@deftai/directive 0.119.13 → 0.121.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/dist/authz.js CHANGED
@@ -27,6 +27,7 @@ import { existsSync } from "node:fs";
27
27
  import { isAbsolute, resolve } from "node:path";
28
28
  import { onePrUnit } from "@deftai/directive-core";
29
29
  import { AFK_TEMPLATE_NAMES, AUTHZ_OPERATIONS, CLOSED_VERB_TEMPLATE_NAMES, FINISH_LOOP_TEMPLATE_NAME, formatDecomposeStructuralMintCommand, isAfkTemplateName, isClosedVerbTemplateName, isFinishLoopTemplateName, mintAfkTemplateGrant, mintDecomposeStructuralApplyGrant, mintHumanOriginGrant, revokeGrant, showAuthzSnapshot, startUatLease, suspendUatLease, toProjectRelativePosix, } from "@deftai/directive-core/authz";
30
+ import { uatCampaignEndSeal } from "@deftai/directive-core/authz/campaign-end-seal";
30
31
  import { refuseMintWhileUatActive, refuseNonInteractiveMint, resolveHumanPresenceMintSeams, } from "./human-presence-mint.js";
31
32
  export { AUTHZ_AGENT_SHELL_ENV_MARKERS, AUTHZ_INTERACTIVE_CONFIRM_PHRASE, } from "./human-presence-mint.js";
32
33
  function parseOps(raw) {
@@ -328,13 +329,18 @@ export function main(argv = process.argv.slice(2), seams = {}) {
328
329
  const blocked = gateConfirm();
329
330
  if (blocked !== null)
330
331
  return blocked;
331
- const { lease } = startUatLease({
332
+ // Result narrowing; pinActive mint wiring stays parked (class 4).
333
+ const started = startUatLease({
332
334
  projectRoot: args.projectRoot,
333
335
  campaignId: args.campaign,
334
336
  actor: args.actor,
335
337
  note: args.note,
336
338
  });
337
- process.stdout.write(`✓ UAT lease ACTIVE campaign=${lease.campaignId} (human-origin operator-cli)\n`);
339
+ if (!started.ok) {
340
+ process.stderr.write(`authz:uat-start: ${started.reason}\n`);
341
+ return 2;
342
+ }
343
+ process.stdout.write(`✓ UAT lease ACTIVE campaign=${started.lease.campaignId} (human-origin operator-cli)\n`);
338
344
  process.stdout.write(" Product edit/push/PR/merge denied until a named fix cohort grant is minted.\n");
339
345
  process.stdout.write(" Tests, evidence capture, and issue filing remain allowed.\n");
340
346
  return 0;
@@ -343,10 +349,18 @@ export function main(argv = process.argv.slice(2), seams = {}) {
343
349
  const blocked = gateConfirm();
344
350
  if (blocked !== null)
345
351
  return blocked;
346
- const state = suspendUatLease({
352
+ // Sealed campaign-end only after CLI human-presence gateConfirm (#4233).
353
+ // pinActive mint wiring stays parked (class 4 follow-up).
354
+ const suspended = suspendUatLease({
347
355
  projectRoot: args.projectRoot,
348
356
  actor: args.actor,
357
+ campaignEndSeal: uatCampaignEndSeal(),
349
358
  });
359
+ if (!suspended.ok) {
360
+ process.stderr.write(`authz:uat-suspend: ${suspended.reason}\n`);
361
+ return 2;
362
+ }
363
+ const state = suspended.state;
350
364
  if (state.uat === null) {
351
365
  process.stdout.write("UAT lease was already inactive.\n");
352
366
  }
@@ -400,7 +414,7 @@ export function main(argv = process.argv.slice(2), seams = {}) {
400
414
  const blocked = gateConfirm();
401
415
  if (blocked !== null)
402
416
  return blocked;
403
- const grant = mintDecomposeStructuralApplyGrant({
417
+ const minted = mintDecomposeStructuralApplyGrant({
404
418
  projectRoot: root,
405
419
  parentPath: parentAbs,
406
420
  draftPath: draftAbs,
@@ -409,6 +423,11 @@ export function main(argv = process.argv.slice(2), seams = {}) {
409
423
  expiresAt: args.expiresAt,
410
424
  singleUse: args.singleUse,
411
425
  });
426
+ if (!minted.ok) {
427
+ process.stderr.write(`authz:grant: ${minted.reason}\n`);
428
+ return 2;
429
+ }
430
+ const grant = minted.grant;
412
431
  // mintDecomposeStructuralApplyGrant always sets contentDigest + worktree.
413
432
  const digest = grant.scope.contentDigest || "";
414
433
  process.stdout.write(`✓ human-origin structural grant minted id=${grant.id} origin=${grant.origin.kind}\n`);
@@ -474,7 +493,7 @@ export function main(argv = process.argv.slice(2), seams = {}) {
474
493
  const blocked = gateConfirm();
475
494
  if (blocked !== null)
476
495
  return blocked;
477
- const grant = mintAfkTemplateGrant({
496
+ const minted = mintAfkTemplateGrant({
478
497
  projectRoot: args.projectRoot,
479
498
  template: args.template,
480
499
  target: args.target,
@@ -489,6 +508,11 @@ export function main(argv = process.argv.slice(2), seams = {}) {
489
508
  issueIds: args.issueIds,
490
509
  cohortId: args.cohort,
491
510
  });
511
+ if (!minted.ok) {
512
+ process.stderr.write(`authz:grant: ${minted.reason}\n`);
513
+ return 2;
514
+ }
515
+ const grant = minted.grant;
492
516
  process.stdout.write(`✓ human-origin grant minted id=${grant.id} origin=${grant.origin.kind} ` +
493
517
  `template=${args.template}\n`);
494
518
  if (isFinishLoopTemplateName(args.template)) {
@@ -511,7 +535,7 @@ export function main(argv = process.argv.slice(2), seams = {}) {
511
535
  if (blocked !== null)
512
536
  return blocked;
513
537
  }
514
- const grant = mintHumanOriginGrant({
538
+ const minted = mintHumanOriginGrant({
515
539
  projectRoot: args.projectRoot,
516
540
  actor: args.actor,
517
541
  operations: args.operations,
@@ -525,6 +549,11 @@ export function main(argv = process.argv.slice(2), seams = {}) {
525
549
  expiresAt: args.expiresAt,
526
550
  singleUse: args.singleUse,
527
551
  });
552
+ if (!minted.ok) {
553
+ process.stderr.write(`authz:grant: ${minted.reason}\n`);
554
+ return 2;
555
+ }
556
+ const grant = minted.grant;
528
557
  process.stdout.write(`✓ human-origin grant minted id=${grant.id} origin=${grant.origin.kind}\n`);
529
558
  process.stdout.write(` ops=[${grant.scope.operations.join(",")}] cohort=${grant.scope.cohortId ?? "-"}\n`);
530
559
  if (grant.scope.surfaces.length > 0) {
@@ -542,10 +571,15 @@ export function main(argv = process.argv.slice(2), seams = {}) {
542
571
  if (blocked !== null)
543
572
  return blocked;
544
573
  }
545
- const revoked = revokeGrant({
574
+ const revokedResult = revokeGrant({
546
575
  projectRoot: args.projectRoot,
547
576
  grantId: args.grantId,
548
577
  });
578
+ if (!revokedResult.ok) {
579
+ process.stderr.write(`authz:revoke: ${revokedResult.reason}\n`);
580
+ return 2;
581
+ }
582
+ const revoked = revokedResult.grant;
549
583
  if (revoked === null) {
550
584
  process.stderr.write(`authz: grant not found: ${args.grantId}\n`);
551
585
  return 1;
@@ -2,14 +2,19 @@
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { runChangelogCheck } from "@deftai/directive-core/task-surface";
5
- function parseProjectRoot(argv) {
5
+ function parseChangelogCheckArgs(argv) {
6
6
  let projectRoot = ".";
7
+ let againstMergeBase = false;
7
8
  for (let i = 0; i < argv.length; i += 1) {
8
9
  const arg = argv[i] ?? "";
9
10
  if (arg === "--project-root") {
10
11
  const value = argv[i + 1];
11
12
  if (value === undefined) {
12
- return { projectRoot, error: "argument --project-root: expected one argument" };
13
+ return {
14
+ projectRoot,
15
+ againstMergeBase,
16
+ error: "argument --project-root: expected one argument",
17
+ };
13
18
  }
14
19
  projectRoot = value;
15
20
  i += 1;
@@ -17,14 +22,17 @@ function parseProjectRoot(argv) {
17
22
  else if (arg.startsWith("--project-root=")) {
18
23
  projectRoot = arg.slice("--project-root=".length);
19
24
  }
25
+ else if (arg === "--against-merge-base") {
26
+ againstMergeBase = true;
27
+ }
20
28
  else {
21
- return { projectRoot, error: `unrecognized argument: ${arg}` };
29
+ return { projectRoot, againstMergeBase, error: `unrecognized argument: ${arg}` };
22
30
  }
23
31
  }
24
- return { projectRoot };
32
+ return { projectRoot, againstMergeBase };
25
33
  }
26
34
  export function run(argv) {
27
- const args = parseProjectRoot(argv);
35
+ const args = parseChangelogCheckArgs(argv);
28
36
  if (args.error !== undefined) {
29
37
  process.stderr.write(`changelog-check: ${args.error}\n`);
30
38
  return 2;
@@ -36,7 +44,7 @@ export function run(argv) {
36
44
  writeErr: (text) => {
37
45
  process.stderr.write(text);
38
46
  },
39
- });
47
+ }, { againstMergeBase: args.againstMergeBase });
40
48
  }
41
49
  if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
42
50
  process.exit(run(process.argv.slice(2)));
@@ -10,9 +10,9 @@ export interface DispatchIo {
10
10
  writeErr: (text: string) => void;
11
11
  }
12
12
  /** CLI modules in packages/cli/src (excluding parity harnesses and bin/index). */
13
- export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "ownership-doctor", "ownership-fix", "verify-ownership", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "xbrief-adopt-stored-plan-id", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-class-checks", "verify-presentation-coverage", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-consumer-header-placeholder", "verify-agents-md-advisory", "verify-persisted-planning-narratives", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-operator-scope-limit", "verify-presentation-ceiling", "verify-intent-constraint", "verify-durable-effect-acquisition", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
13
+ export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "ownership-doctor", "ownership-fix", "verify-ownership", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "pre-pr-run", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "xbrief-adopt-stored-plan-id", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-class-checks", "verify-presentation-coverage", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "verify-spec-drift", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-cohort-review-monitors", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "subagent-pre-cancel", "subagent-steer-write", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-consumer-header-placeholder", "verify-agents-md-advisory", "verify-persisted-planning-narratives", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-operator-scope-limit", "verify-presentation-ceiling", "verify-intent-constraint", "verify-durable-effect-acquisition", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
14
14
  /** Core-only CLI entrypoints without a packages/cli wrapper. */
15
- export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact", "migrate-clause-ids"];
15
+ export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-reconstruct", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact", "migrate-clause-ids"];
16
16
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
17
17
  export declare const TRIAGE_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
18
18
  /** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
package/dist/dispatch.js CHANGED
@@ -64,6 +64,7 @@ export const CLI_MODULE_VERBS = [
64
64
  "pr-watch",
65
65
  "pr-finish-loop",
66
66
  "directive-finish-loop",
67
+ "pre-pr-run",
67
68
  "preflight-cache",
68
69
  "preflight-gh",
69
70
  "probe-session",
@@ -150,12 +151,16 @@ export const CLI_MODULE_VERBS = [
150
151
  "verify-stubs",
151
152
  "verify-xbrief-drift",
152
153
  "verify-spec-prd-fresh",
154
+ "verify-spec-drift",
153
155
  "rule-ownership-lint",
154
156
  "verify-story-ready",
155
157
  "verify-review-monitor",
158
+ "verify-cohort-review-monitors",
156
159
  "verify-l4-owner",
157
160
  "verify-subagent-alive",
158
161
  "verify-subagent-steer",
162
+ "subagent-pre-cancel",
163
+ "subagent-steer-write",
159
164
  "review-monitor-register",
160
165
  "review-monitor-release",
161
166
  "verify-tools",
@@ -215,6 +220,7 @@ export const CORE_MODULE_VERBS = [
215
220
  "roadmap-render",
216
221
  "rule-map",
217
222
  "spec-render",
223
+ "spec-reconstruct",
218
224
  "spec-validate",
219
225
  "code-structure-validate",
220
226
  "pack-migrate-skills",
@@ -310,6 +316,7 @@ export const FRESHNESS_ALIAS_SUBCOMMANDS = {
310
316
  const FRESHNESS_COLON_ALIASES = Object.fromEntries(Object.keys(FRESHNESS_ALIAS_SUBCOMMANDS).map((alias) => [alias, "freshness-report"]));
311
317
  /** Task-style aliases (framework_commands / Taskfile names). */
312
318
  export const VERB_ALIASES = {
319
+ "pre-pr:run": "pre-pr-run",
313
320
  "hook:dispatch": "hook-dispatch",
314
321
  "verify:encoding": "verify-encoding",
315
322
  "verify:forward-coverage": "verify-forward-coverage",
@@ -363,9 +370,12 @@ export const VERB_ALIASES = {
363
370
  "vbrief:activate": "vbrief-activate",
364
371
  "verify:story-ready": "verify-story-ready",
365
372
  "verify:review-monitor": "verify-review-monitor",
373
+ "verify:cohort-review-monitors": "verify-cohort-review-monitors",
366
374
  "verify:l4-owner": "verify-l4-owner",
367
375
  "verify:subagent-alive": "verify-subagent-alive",
368
376
  "verify:subagent-steer": "verify-subagent-steer",
377
+ "subagent:pre-cancel": "subagent-pre-cancel",
378
+ "subagent:steer": "subagent-steer-write",
369
379
  "agent:monitor": "subagent-monitor",
370
380
  "review-monitor:register": "review-monitor-register",
371
381
  "review-monitor:release": "review-monitor-release",
@@ -395,6 +405,7 @@ export const VERB_ALIASES = {
395
405
  "verify:scm-boundary": "verify-scm-boundary",
396
406
  "verify:xbrief-drift": "verify-xbrief-drift",
397
407
  "verify:spec-prd-fresh": "verify-spec-prd-fresh",
408
+ "verify:spec-drift": "verify-spec-drift",
398
409
  "verify:capacity": "verify-capacity",
399
410
  "verify:session-ritual": "verify-session-ritual",
400
411
  "verify:plan-sequence": "verify-plan-sequence",
@@ -437,6 +448,7 @@ export const VERB_ALIASES = {
437
448
  "ts:check-lane": "ts-check-lane",
438
449
  "spec:validate": "spec-validate",
439
450
  "spec:render": "spec-render",
451
+ "spec:reconstruct": "spec-reconstruct",
440
452
  "prd:render": "prd-render",
441
453
  "project:render": "project-render",
442
454
  "project:write-narratives": "project-write-narratives",
@@ -487,6 +499,7 @@ const SUBDIR_CLI_STEMS = {
487
499
  "verify-scm-boundary": "verify-source-cli/verify-scm-boundary",
488
500
  "verify-xbrief-drift": "verify-source-cli/verify-xbrief-drift",
489
501
  "verify-spec-prd-fresh": "verify-source-cli/verify-spec-prd-fresh",
502
+ "verify-spec-drift": "verify-source-cli/verify-spec-drift",
490
503
  "verify-go-freeze": "gates-cli/verify-go-freeze",
491
504
  "verify-bridge-drift": "gates-cli/verify-bridge-drift",
492
505
  "validate-links": "content-validate-cli/validate-links",
@@ -2527,6 +2540,10 @@ async function loadCoreModuleHandler(verb, io) {
2527
2540
  const { runSpecValidateCli } = await import("./render-cli/spec-validate-cli.js");
2528
2541
  return (argv) => runSpecValidateCli(argv);
2529
2542
  }
2543
+ case "spec-reconstruct": {
2544
+ const { runSpecReconstructCliEntry } = await import("./render-cli/spec-reconstruct-cli.js");
2545
+ return (argv) => runSpecReconstructCliEntry(argv);
2546
+ }
2530
2547
  case "spec-render": {
2531
2548
  const { runSpecRenderCli } = await import("./render-cli/spec-render-cli.js");
2532
2549
  return (argv) => runSpecRenderCli(argv);
@@ -156,6 +156,10 @@ export function run(argv, seams = {}) {
156
156
  const rendered = renderHostDecision(args.host, decision);
157
157
  if (rendered.length > 0)
158
158
  writeOut(`${rendered}\n`);
159
+ // Force-kill allow must print the non-empty reason even when host allow wire is empty (#5281).
160
+ if (decision.code === "kill-force-ready" && decision.message.trim().length > 0) {
161
+ writeErr(`${decision.message}\n`);
162
+ }
159
163
  if ((decision.code === "invalid-input" || decision.code === "stdin-empty") &&
160
164
  args.host === "cursor") {
161
165
  // Keys are already embedded in decision.message; stderr helps operators tailing logs.
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ interface ParsedArgs {
3
+ repo: string;
4
+ baseSha: string;
5
+ headSha: string;
6
+ treeHash: string;
7
+ prBodyHash: string;
8
+ prNodeId: string | null;
9
+ approvedRevision: string;
10
+ scope: string[];
11
+ acceptance: string;
12
+ generation: number;
13
+ skillVersion: string;
14
+ policyVersion: string;
15
+ runId: string | null;
16
+ complete: boolean;
17
+ observeCommand: boolean;
18
+ observeSemantic: boolean;
19
+ phase: string | null;
20
+ command: string;
21
+ exitCode: number | null;
22
+ inputHash: string | null;
23
+ skipReason: string | null;
24
+ suppliedContentsHash: string;
25
+ controllerObservedHash: string;
26
+ criteriaDigest: string | null;
27
+ reviewedFiles: string[];
28
+ reviewerReportRef: string | null;
29
+ markComplete: boolean;
30
+ skillOpen: boolean;
31
+ evaluate: boolean;
32
+ json: boolean;
33
+ help: boolean;
34
+ error?: string;
35
+ }
36
+ export declare function parseArgs(argv: string[]): ParsedArgs;
37
+ export declare function run(argv: string[]): number;
38
+ export {};
39
+ //# sourceMappingURL=pre-pr-run.d.ts.map