@event4u/agent-config 9.34.0 → 9.36.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.
Files changed (112) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +64 -77
  3. package/CONTRIBUTING.md +23 -14
  4. package/dist/agent-src/commands/analyze/reference-repo.md +135 -42
  5. package/dist/agent-src/commands/roadmap/next.md +37 -5
  6. package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
  7. package/dist/agent-src/rules/design-review-after-ui-write.md +53 -6
  8. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  9. package/dist/agent-src/rules/ui-audit-gate.md +35 -0
  10. package/dist/agent-src/scripts/roadmap_gates.ts +119 -4
  11. package/dist/agent-src/skills/design-system-capture/SKILL.md +2 -2
  12. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
  13. package/dist/agent-src/skills/fe-design/SKILL.md +84 -12
  14. package/dist/agent-src/skills/fe-design/evals/triggers.json +11 -3
  15. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +5 -5
  16. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  17. package/dist/agent-src/skills/skill-writing/SKILL.md +24 -0
  18. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +29 -0
  19. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +25 -0
  20. package/dist/agent-src/templates/AGENTS.md +1 -1
  21. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  22. package/dist/agent-src/templates/scripts/memory_lookup.ts +1 -2
  23. package/dist/agent-src/templates/scripts/memory_signal.ts +2 -4
  24. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.ts +35 -5
  25. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation.ts +252 -0
  26. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.ts +307 -0
  27. package/dist/cli/registry.js +2 -2
  28. package/dist/cli/registry.js.map +1 -1
  29. package/dist/cli-delegate/{chunk-YPAWXXXR.js → chunk-55RI5UXK.js} +17 -0
  30. package/dist/cli-delegate/{chunk-UVKNIJH2.js → chunk-JP53LNVT.js} +12 -0
  31. package/dist/cli-delegate/{chunk-736JCWLM.js → chunk-M2DPGFZ4.js} +10 -0
  32. package/dist/cli-delegate/{chunk-MA4GFWDY.js → chunk-NR7HSN3P.js} +2 -2
  33. package/dist/cli-delegate/{chunk-REMEZSVP.js → chunk-SFGARMAB.js} +13 -3
  34. package/dist/cli-delegate/{chunk-DS6BLDMG.js → chunk-U7CMAIOC.js} +7 -2
  35. package/dist/cli-delegate/cmd_conformance.js +4 -4
  36. package/dist/cli-delegate/cmd_doctor.js +3 -3
  37. package/dist/cli-delegate/cmd_export.js +3 -3
  38. package/dist/cli-delegate/cmd_handoff.js +1 -1
  39. package/dist/cli-delegate/cmd_migrate.js +1 -1
  40. package/dist/cli-delegate/cmd_prune.js +3 -3
  41. package/dist/cli-delegate/cmd_refresh.js +1 -1
  42. package/dist/cli-delegate/cmd_session_recycle.js +8 -1
  43. package/dist/cli-delegate/cmd_settings_migrate.js +3 -3
  44. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  45. package/dist/cli-delegate/cmd_sync.js +3 -3
  46. package/dist/cli-delegate/cmd_uninstall.js +3 -3
  47. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  48. package/dist/cli-delegate/cmd_validate.js +3 -3
  49. package/dist/discovery/deprecation-report.md +1 -1
  50. package/dist/discovery/discovery-manifest.json +14 -14
  51. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  52. package/dist/discovery/discovery-manifest.summary.md +1 -1
  53. package/dist/discovery/dormancy-report.md +1 -1
  54. package/dist/discovery/orphan-report.md +1 -1
  55. package/dist/discovery/packs.json +2 -2
  56. package/dist/discovery/trust-report.md +1 -1
  57. package/dist/discovery/workspaces.json +2 -2
  58. package/dist/hooks/dispatch.js +789 -401
  59. package/dist/install/install.mjs +21 -4
  60. package/dist/mcp/registry-manifest.json +2 -2
  61. package/dist/mcp/server.json +2 -2
  62. package/dist/mcp/server.mjs +99 -7
  63. package/dist/router.json +1 -1
  64. package/dist/server/schemas/settings.js +6 -0
  65. package/dist/server/schemas/settings.js.map +1 -1
  66. package/docs/contracts/settings-classes.md +5 -2
  67. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +46 -4
  68. package/package.json +2 -2
  69. package/src/agent-src/scripts/roadmap_gates.ts +119 -4
  70. package/src/agent-src/templates/AGENTS.md +1 -1
  71. package/src/agent-src/templates/scripts/memory_lookup.ts +1 -2
  72. package/src/agent-src/templates/scripts/memory_signal.ts +2 -4
  73. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_gate.ts +35 -5
  74. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation.ts +252 -0
  75. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/staged_confirmation_store.ts +307 -0
  76. package/src/config/agent-settings.template.yml +43 -2
  77. package/src/config/gate-coverage.yml +12 -0
  78. package/src/config/quorum-attendance-budget.json +10 -2
  79. package/src/scripts/_cli/cmd_doctor.ts +32 -0
  80. package/src/scripts/_cli/cmd_migrate.ts +26 -3
  81. package/src/scripts/_cli/cmd_refresh.ts +29 -0
  82. package/src/scripts/_cli/cmd_session_recycle.ts +40 -2
  83. package/src/scripts/_dispatch.bash +6 -2
  84. package/src/scripts/_lib/hook_settings.ts +79 -0
  85. package/src/scripts/_lib/session_register.ts +67 -1
  86. package/src/scripts/_lib/ui_surface.ts +97 -0
  87. package/src/scripts/ai_council/config.ts +60 -0
  88. package/src/scripts/ai_council/events_log.ts +103 -4
  89. package/src/scripts/ai_council/quorum.ts +83 -6
  90. package/src/scripts/capture_skill_catalogue.ts +483 -0
  91. package/src/scripts/council_cli.ts +36 -1
  92. package/src/scripts/hook_manifest.yaml +18 -3
  93. package/src/scripts/hooks/concern_registry.ts +2 -0
  94. package/src/scripts/hooks/design_slop_hook.ts +1 -1
  95. package/src/scripts/hooks/turn_end_gate_hook.ts +172 -11
  96. package/src/scripts/hooks/ui_route_nudge_hook.ts +250 -0
  97. package/src/scripts/lint_framework_leakage.ts +195 -28
  98. package/src/scripts/lint_framework_leakage_allowlist.json +94 -86
  99. package/src/scripts/lint_roadmap_complexity.ts +60 -0
  100. package/src/scripts/lint_rule_skill_pack_reach.ts +263 -0
  101. package/src/scripts/memory_lookup.ts +1 -2
  102. package/src/scripts/report_consultation_rate.ts +358 -0
  103. package/src/scripts/report_skill_activation.ts +5 -1
  104. package/src/scripts/schemas/command.schema.json +4 -0
  105. package/src/scripts/schemas/skill.schema.json +4 -0
  106. package/src/scripts/session_register_hook.ts +238 -18
  107. package/src/scripts/sessions_cli.ts +377 -12
  108. package/src/server/schemas/settings.ts +12 -0
  109. /package/dist/agent-src/skills/design-system-capture/{reference → references}/design-system-json.md +0 -0
  110. /package/dist/agent-src/skills/prediction-pool-optimizer/{reference → references}/ev-fixtures.md +0 -0
  111. /package/dist/agent-src/skills/prediction-pool-optimizer/{reference → references}/odds-and-bonus.md +0 -0
  112. /package/dist/agent-src/skills/react-shadcn-ui/{reference → references}/registry.md +0 -0
@@ -112,17 +112,17 @@ var require_visit = __commonJS({
112
112
  visit.BREAK = BREAK;
113
113
  visit.SKIP = SKIP;
114
114
  visit.REMOVE = REMOVE;
115
- function visit_(key, node, visitor, path67) {
116
- const ctrl = callVisitor(key, node, visitor, path67);
115
+ function visit_(key, node, visitor, path69) {
116
+ const ctrl = callVisitor(key, node, visitor, path69);
117
117
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
118
- replaceNode(key, path67, ctrl);
119
- return visit_(key, ctrl, visitor, path67);
118
+ replaceNode(key, path69, ctrl);
119
+ return visit_(key, ctrl, visitor, path69);
120
120
  }
121
121
  if (typeof ctrl !== "symbol") {
122
122
  if (identity.isCollection(node)) {
123
- path67 = Object.freeze(path67.concat(node));
123
+ path69 = Object.freeze(path69.concat(node));
124
124
  for (let i = 0; i < node.items.length; ++i) {
125
- const ci = visit_(i, node.items[i], visitor, path67);
125
+ const ci = visit_(i, node.items[i], visitor, path69);
126
126
  if (typeof ci === "number")
127
127
  i = ci - 1;
128
128
  else if (ci === BREAK)
@@ -133,13 +133,13 @@ var require_visit = __commonJS({
133
133
  }
134
134
  }
135
135
  } else if (identity.isPair(node)) {
136
- path67 = Object.freeze(path67.concat(node));
137
- const ck = visit_("key", node.key, visitor, path67);
136
+ path69 = Object.freeze(path69.concat(node));
137
+ const ck = visit_("key", node.key, visitor, path69);
138
138
  if (ck === BREAK)
139
139
  return BREAK;
140
140
  else if (ck === REMOVE)
141
141
  node.key = null;
142
- const cv = visit_("value", node.value, visitor, path67);
142
+ const cv = visit_("value", node.value, visitor, path69);
143
143
  if (cv === BREAK)
144
144
  return BREAK;
145
145
  else if (cv === REMOVE)
@@ -160,17 +160,17 @@ var require_visit = __commonJS({
160
160
  visitAsync.BREAK = BREAK;
161
161
  visitAsync.SKIP = SKIP;
162
162
  visitAsync.REMOVE = REMOVE;
163
- async function visitAsync_(key, node, visitor, path67) {
164
- const ctrl = await callVisitor(key, node, visitor, path67);
163
+ async function visitAsync_(key, node, visitor, path69) {
164
+ const ctrl = await callVisitor(key, node, visitor, path69);
165
165
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
166
- replaceNode(key, path67, ctrl);
167
- return visitAsync_(key, ctrl, visitor, path67);
166
+ replaceNode(key, path69, ctrl);
167
+ return visitAsync_(key, ctrl, visitor, path69);
168
168
  }
169
169
  if (typeof ctrl !== "symbol") {
170
170
  if (identity.isCollection(node)) {
171
- path67 = Object.freeze(path67.concat(node));
171
+ path69 = Object.freeze(path69.concat(node));
172
172
  for (let i = 0; i < node.items.length; ++i) {
173
- const ci = await visitAsync_(i, node.items[i], visitor, path67);
173
+ const ci = await visitAsync_(i, node.items[i], visitor, path69);
174
174
  if (typeof ci === "number")
175
175
  i = ci - 1;
176
176
  else if (ci === BREAK)
@@ -181,13 +181,13 @@ var require_visit = __commonJS({
181
181
  }
182
182
  }
183
183
  } else if (identity.isPair(node)) {
184
- path67 = Object.freeze(path67.concat(node));
185
- const ck = await visitAsync_("key", node.key, visitor, path67);
184
+ path69 = Object.freeze(path69.concat(node));
185
+ const ck = await visitAsync_("key", node.key, visitor, path69);
186
186
  if (ck === BREAK)
187
187
  return BREAK;
188
188
  else if (ck === REMOVE)
189
189
  node.key = null;
190
- const cv = await visitAsync_("value", node.value, visitor, path67);
190
+ const cv = await visitAsync_("value", node.value, visitor, path69);
191
191
  if (cv === BREAK)
192
192
  return BREAK;
193
193
  else if (cv === REMOVE)
@@ -214,23 +214,23 @@ var require_visit = __commonJS({
214
214
  }
215
215
  return visitor;
216
216
  }
217
- function callVisitor(key, node, visitor, path67) {
217
+ function callVisitor(key, node, visitor, path69) {
218
218
  if (typeof visitor === "function")
219
- return visitor(key, node, path67);
219
+ return visitor(key, node, path69);
220
220
  if (identity.isMap(node))
221
- return visitor.Map?.(key, node, path67);
221
+ return visitor.Map?.(key, node, path69);
222
222
  if (identity.isSeq(node))
223
- return visitor.Seq?.(key, node, path67);
223
+ return visitor.Seq?.(key, node, path69);
224
224
  if (identity.isPair(node))
225
- return visitor.Pair?.(key, node, path67);
225
+ return visitor.Pair?.(key, node, path69);
226
226
  if (identity.isScalar(node))
227
- return visitor.Scalar?.(key, node, path67);
227
+ return visitor.Scalar?.(key, node, path69);
228
228
  if (identity.isAlias(node))
229
- return visitor.Alias?.(key, node, path67);
229
+ return visitor.Alias?.(key, node, path69);
230
230
  return void 0;
231
231
  }
232
- function replaceNode(key, path67, node) {
233
- const parent = path67[path67.length - 1];
232
+ function replaceNode(key, path69, node) {
233
+ const parent = path69[path69.length - 1];
234
234
  if (identity.isCollection(parent)) {
235
235
  parent.items[key] = node;
236
236
  } else if (identity.isPair(parent)) {
@@ -840,10 +840,10 @@ var require_Collection = __commonJS({
840
840
  var createNode = require_createNode();
841
841
  var identity = require_identity();
842
842
  var Node = require_Node();
843
- function collectionFromPath(schema, path67, value) {
843
+ function collectionFromPath(schema, path69, value) {
844
844
  let v = value;
845
- for (let i = path67.length - 1; i >= 0; --i) {
846
- const k = path67[i];
845
+ for (let i = path69.length - 1; i >= 0; --i) {
846
+ const k = path69[i];
847
847
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
848
848
  const a = [];
849
849
  a[k] = v;
@@ -862,7 +862,7 @@ var require_Collection = __commonJS({
862
862
  sourceObjects: /* @__PURE__ */ new Map()
863
863
  });
864
864
  }
865
- var isEmptyPath = (path67) => path67 == null || typeof path67 === "object" && !!path67[Symbol.iterator]().next().done;
865
+ var isEmptyPath = (path69) => path69 == null || typeof path69 === "object" && !!path69[Symbol.iterator]().next().done;
866
866
  var Collection = class extends Node.NodeBase {
867
867
  constructor(type, schema) {
868
868
  super(type);
@@ -892,11 +892,11 @@ var require_Collection = __commonJS({
892
892
  * be a Pair instance or a `{ key, value }` object, which may not have a key
893
893
  * that already exists in the map.
894
894
  */
895
- addIn(path67, value) {
896
- if (isEmptyPath(path67))
895
+ addIn(path69, value) {
896
+ if (isEmptyPath(path69))
897
897
  this.add(value);
898
898
  else {
899
- const [key, ...rest] = path67;
899
+ const [key, ...rest] = path69;
900
900
  const node = this.get(key, true);
901
901
  if (identity.isCollection(node))
902
902
  node.addIn(rest, value);
@@ -910,8 +910,8 @@ var require_Collection = __commonJS({
910
910
  * Removes a value from the collection.
911
911
  * @returns `true` if the item was found and removed.
912
912
  */
913
- deleteIn(path67) {
914
- const [key, ...rest] = path67;
913
+ deleteIn(path69) {
914
+ const [key, ...rest] = path69;
915
915
  if (rest.length === 0)
916
916
  return this.delete(key);
917
917
  const node = this.get(key, true);
@@ -925,8 +925,8 @@ var require_Collection = __commonJS({
925
925
  * scalar values from their surrounding node; to disable set `keepScalar` to
926
926
  * `true` (collections are always returned intact).
927
927
  */
928
- getIn(path67, keepScalar) {
929
- const [key, ...rest] = path67;
928
+ getIn(path69, keepScalar) {
929
+ const [key, ...rest] = path69;
930
930
  const node = this.get(key, true);
931
931
  if (rest.length === 0)
932
932
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -944,8 +944,8 @@ var require_Collection = __commonJS({
944
944
  /**
945
945
  * Checks if the collection includes a value with the key `key`.
946
946
  */
947
- hasIn(path67) {
948
- const [key, ...rest] = path67;
947
+ hasIn(path69) {
948
+ const [key, ...rest] = path69;
949
949
  if (rest.length === 0)
950
950
  return this.has(key);
951
951
  const node = this.get(key, true);
@@ -955,8 +955,8 @@ var require_Collection = __commonJS({
955
955
  * Sets a value in this collection. For `!!set`, `value` needs to be a
956
956
  * boolean to add/remove the item from the set.
957
957
  */
958
- setIn(path67, value) {
959
- const [key, ...rest] = path67;
958
+ setIn(path69, value) {
959
+ const [key, ...rest] = path69;
960
960
  if (rest.length === 0) {
961
961
  this.set(key, value);
962
962
  } else {
@@ -3471,9 +3471,9 @@ var require_Document = __commonJS({
3471
3471
  this.contents.add(value);
3472
3472
  }
3473
3473
  /** Adds a value to the document. */
3474
- addIn(path67, value) {
3474
+ addIn(path69, value) {
3475
3475
  if (assertCollection(this.contents))
3476
- this.contents.addIn(path67, value);
3476
+ this.contents.addIn(path69, value);
3477
3477
  }
3478
3478
  /**
3479
3479
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3548,14 +3548,14 @@ var require_Document = __commonJS({
3548
3548
  * Removes a value from the document.
3549
3549
  * @returns `true` if the item was found and removed.
3550
3550
  */
3551
- deleteIn(path67) {
3552
- if (Collection.isEmptyPath(path67)) {
3551
+ deleteIn(path69) {
3552
+ if (Collection.isEmptyPath(path69)) {
3553
3553
  if (this.contents == null)
3554
3554
  return false;
3555
3555
  this.contents = null;
3556
3556
  return true;
3557
3557
  }
3558
- return assertCollection(this.contents) ? this.contents.deleteIn(path67) : false;
3558
+ return assertCollection(this.contents) ? this.contents.deleteIn(path69) : false;
3559
3559
  }
3560
3560
  /**
3561
3561
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3570,10 +3570,10 @@ var require_Document = __commonJS({
3570
3570
  * scalar values from their surrounding node; to disable set `keepScalar` to
3571
3571
  * `true` (collections are always returned intact).
3572
3572
  */
3573
- getIn(path67, keepScalar) {
3574
- if (Collection.isEmptyPath(path67))
3573
+ getIn(path69, keepScalar) {
3574
+ if (Collection.isEmptyPath(path69))
3575
3575
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3576
- return identity.isCollection(this.contents) ? this.contents.getIn(path67, keepScalar) : void 0;
3576
+ return identity.isCollection(this.contents) ? this.contents.getIn(path69, keepScalar) : void 0;
3577
3577
  }
3578
3578
  /**
3579
3579
  * Checks if the document includes a value with the key `key`.
@@ -3584,10 +3584,10 @@ var require_Document = __commonJS({
3584
3584
  /**
3585
3585
  * Checks if the document includes a value at `path`.
3586
3586
  */
3587
- hasIn(path67) {
3588
- if (Collection.isEmptyPath(path67))
3587
+ hasIn(path69) {
3588
+ if (Collection.isEmptyPath(path69))
3589
3589
  return this.contents !== void 0;
3590
- return identity.isCollection(this.contents) ? this.contents.hasIn(path67) : false;
3590
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path69) : false;
3591
3591
  }
3592
3592
  /**
3593
3593
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3604,13 +3604,13 @@ var require_Document = __commonJS({
3604
3604
  * Sets a value in this document. For `!!set`, `value` needs to be a
3605
3605
  * boolean to add/remove the item from the set.
3606
3606
  */
3607
- setIn(path67, value) {
3608
- if (Collection.isEmptyPath(path67)) {
3607
+ setIn(path69, value) {
3608
+ if (Collection.isEmptyPath(path69)) {
3609
3609
  this.contents = value;
3610
3610
  } else if (this.contents == null) {
3611
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path67), value);
3611
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path69), value);
3612
3612
  } else if (assertCollection(this.contents)) {
3613
- this.contents.setIn(path67, value);
3613
+ this.contents.setIn(path69, value);
3614
3614
  }
3615
3615
  }
3616
3616
  /**
@@ -3996,10 +3996,10 @@ var require_resolve_block_map = __commonJS({
3996
3996
  let offset = bm.offset;
3997
3997
  let commentEnd = null;
3998
3998
  for (const collItem of bm.items) {
3999
- const { start, key, sep: sep6, value } = collItem;
3999
+ const { start, key, sep: sep7, value } = collItem;
4000
4000
  const keyProps = resolveProps.resolveProps(start, {
4001
4001
  indicator: "explicit-key-ind",
4002
- next: key ?? sep6?.[0],
4002
+ next: key ?? sep7?.[0],
4003
4003
  offset,
4004
4004
  onError,
4005
4005
  parentIndent: bm.indent,
@@ -4013,7 +4013,7 @@ var require_resolve_block_map = __commonJS({
4013
4013
  else if ("indent" in key && key.indent !== bm.indent)
4014
4014
  onError(offset, "BAD_INDENT", startColMsg);
4015
4015
  }
4016
- if (!keyProps.anchor && !keyProps.tag && !sep6) {
4016
+ if (!keyProps.anchor && !keyProps.tag && !sep7) {
4017
4017
  commentEnd = keyProps.end;
4018
4018
  if (keyProps.comment) {
4019
4019
  if (map.comment)
@@ -4037,7 +4037,7 @@ var require_resolve_block_map = __commonJS({
4037
4037
  ctx.atKey = false;
4038
4038
  if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
4039
4039
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
4040
- const valueProps = resolveProps.resolveProps(sep6 ?? [], {
4040
+ const valueProps = resolveProps.resolveProps(sep7 ?? [], {
4041
4041
  indicator: "map-value-ind",
4042
4042
  next: value,
4043
4043
  offset: keyNode.range[2],
@@ -4053,7 +4053,7 @@ var require_resolve_block_map = __commonJS({
4053
4053
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
4054
4054
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
4055
4055
  }
4056
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep6, null, valueProps, onError);
4056
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep7, null, valueProps, onError);
4057
4057
  if (ctx.schema.compat)
4058
4058
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
4059
4059
  offset = valueNode.range[2];
@@ -4144,7 +4144,7 @@ var require_resolve_end = __commonJS({
4144
4144
  let comment = "";
4145
4145
  if (end) {
4146
4146
  let hasSpace = false;
4147
- let sep6 = "";
4147
+ let sep7 = "";
4148
4148
  for (const token of end) {
4149
4149
  const { source, type } = token;
4150
4150
  switch (type) {
@@ -4158,13 +4158,13 @@ var require_resolve_end = __commonJS({
4158
4158
  if (!comment)
4159
4159
  comment = cb;
4160
4160
  else
4161
- comment += sep6 + cb;
4162
- sep6 = "";
4161
+ comment += sep7 + cb;
4162
+ sep7 = "";
4163
4163
  break;
4164
4164
  }
4165
4165
  case "newline":
4166
4166
  if (comment)
4167
- sep6 += source;
4167
+ sep7 += source;
4168
4168
  hasSpace = true;
4169
4169
  break;
4170
4170
  default:
@@ -4207,18 +4207,18 @@ var require_resolve_flow_collection = __commonJS({
4207
4207
  let offset = fc.offset + fc.start.source.length;
4208
4208
  for (let i = 0; i < fc.items.length; ++i) {
4209
4209
  const collItem = fc.items[i];
4210
- const { start, key, sep: sep6, value } = collItem;
4210
+ const { start, key, sep: sep7, value } = collItem;
4211
4211
  const props = resolveProps.resolveProps(start, {
4212
4212
  flow: fcName,
4213
4213
  indicator: "explicit-key-ind",
4214
- next: key ?? sep6?.[0],
4214
+ next: key ?? sep7?.[0],
4215
4215
  offset,
4216
4216
  onError,
4217
4217
  parentIndent: fc.indent,
4218
4218
  startOnNewline: false
4219
4219
  });
4220
4220
  if (!props.found) {
4221
- if (!props.anchor && !props.tag && !sep6 && !value) {
4221
+ if (!props.anchor && !props.tag && !sep7 && !value) {
4222
4222
  if (i === 0 && props.comma)
4223
4223
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
4224
4224
  else if (i < fc.items.length - 1)
@@ -4272,8 +4272,8 @@ var require_resolve_flow_collection = __commonJS({
4272
4272
  }
4273
4273
  }
4274
4274
  }
4275
- if (!isMap && !sep6 && !props.found) {
4276
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep6, null, props, onError);
4275
+ if (!isMap && !sep7 && !props.found) {
4276
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep7, null, props, onError);
4277
4277
  coll.items.push(valueNode);
4278
4278
  offset = valueNode.range[2];
4279
4279
  if (isBlock(value))
@@ -4285,7 +4285,7 @@ var require_resolve_flow_collection = __commonJS({
4285
4285
  if (isBlock(key))
4286
4286
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
4287
4287
  ctx.atKey = false;
4288
- const valueProps = resolveProps.resolveProps(sep6 ?? [], {
4288
+ const valueProps = resolveProps.resolveProps(sep7 ?? [], {
4289
4289
  flow: fcName,
4290
4290
  indicator: "map-value-ind",
4291
4291
  next: value,
@@ -4296,8 +4296,8 @@ var require_resolve_flow_collection = __commonJS({
4296
4296
  });
4297
4297
  if (valueProps.found) {
4298
4298
  if (!isMap && !props.found && ctx.options.strict) {
4299
- if (sep6)
4300
- for (const st of sep6) {
4299
+ if (sep7)
4300
+ for (const st of sep7) {
4301
4301
  if (st === valueProps.found)
4302
4302
  break;
4303
4303
  if (st.type === "newline") {
@@ -4314,7 +4314,7 @@ var require_resolve_flow_collection = __commonJS({
4314
4314
  else
4315
4315
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
4316
4316
  }
4317
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep6, null, valueProps, onError) : null;
4317
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep7, null, valueProps, onError) : null;
4318
4318
  if (valueNode) {
4319
4319
  if (isBlock(value))
4320
4320
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -4494,7 +4494,7 @@ var require_resolve_block_scalar = __commonJS({
4494
4494
  chompStart = i + 1;
4495
4495
  }
4496
4496
  let value = "";
4497
- let sep6 = "";
4497
+ let sep7 = "";
4498
4498
  let prevMoreIndented = false;
4499
4499
  for (let i = 0; i < contentStart; ++i)
4500
4500
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -4511,24 +4511,24 @@ var require_resolve_block_scalar = __commonJS({
4511
4511
  indent = "";
4512
4512
  }
4513
4513
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
4514
- value += sep6 + indent.slice(trimIndent) + content;
4515
- sep6 = "\n";
4514
+ value += sep7 + indent.slice(trimIndent) + content;
4515
+ sep7 = "\n";
4516
4516
  } else if (indent.length > trimIndent || content[0] === " ") {
4517
- if (sep6 === " ")
4518
- sep6 = "\n";
4519
- else if (!prevMoreIndented && sep6 === "\n")
4520
- sep6 = "\n\n";
4521
- value += sep6 + indent.slice(trimIndent) + content;
4522
- sep6 = "\n";
4517
+ if (sep7 === " ")
4518
+ sep7 = "\n";
4519
+ else if (!prevMoreIndented && sep7 === "\n")
4520
+ sep7 = "\n\n";
4521
+ value += sep7 + indent.slice(trimIndent) + content;
4522
+ sep7 = "\n";
4523
4523
  prevMoreIndented = true;
4524
4524
  } else if (content === "") {
4525
- if (sep6 === "\n")
4525
+ if (sep7 === "\n")
4526
4526
  value += "\n";
4527
4527
  else
4528
- sep6 = "\n";
4528
+ sep7 = "\n";
4529
4529
  } else {
4530
- value += sep6 + content;
4531
- sep6 = " ";
4530
+ value += sep7 + content;
4531
+ sep7 = " ";
4532
4532
  prevMoreIndented = false;
4533
4533
  }
4534
4534
  }
@@ -4710,25 +4710,25 @@ var require_resolve_flow_scalar = __commonJS({
4710
4710
  if (!match)
4711
4711
  return source;
4712
4712
  let res = match[1];
4713
- let sep6 = " ";
4713
+ let sep7 = " ";
4714
4714
  let pos = first.lastIndex;
4715
4715
  line.lastIndex = pos;
4716
4716
  while (match = line.exec(source)) {
4717
4717
  if (match[1] === "") {
4718
- if (sep6 === "\n")
4719
- res += sep6;
4718
+ if (sep7 === "\n")
4719
+ res += sep7;
4720
4720
  else
4721
- sep6 = "\n";
4721
+ sep7 = "\n";
4722
4722
  } else {
4723
- res += sep6 + match[1];
4724
- sep6 = " ";
4723
+ res += sep7 + match[1];
4724
+ sep7 = " ";
4725
4725
  }
4726
4726
  pos = line.lastIndex;
4727
4727
  }
4728
4728
  const last = /[ \t]*(.*)/sy;
4729
4729
  last.lastIndex = pos;
4730
4730
  match = last.exec(source);
4731
- return res + sep6 + (match?.[1] ?? "");
4731
+ return res + sep7 + (match?.[1] ?? "");
4732
4732
  }
4733
4733
  function doubleQuotedValue(source, onError) {
4734
4734
  let res = "";
@@ -5538,14 +5538,14 @@ var require_cst_stringify = __commonJS({
5538
5538
  }
5539
5539
  }
5540
5540
  }
5541
- function stringifyItem({ start, key, sep: sep6, value }) {
5541
+ function stringifyItem({ start, key, sep: sep7, value }) {
5542
5542
  let res = "";
5543
5543
  for (const st of start)
5544
5544
  res += st.source;
5545
5545
  if (key)
5546
5546
  res += stringifyToken(key);
5547
- if (sep6)
5548
- for (const st of sep6)
5547
+ if (sep7)
5548
+ for (const st of sep7)
5549
5549
  res += st.source;
5550
5550
  if (value)
5551
5551
  res += stringifyToken(value);
@@ -5570,9 +5570,9 @@ var require_cst_visit = __commonJS({
5570
5570
  visit.BREAK = BREAK;
5571
5571
  visit.SKIP = SKIP;
5572
5572
  visit.REMOVE = REMOVE;
5573
- visit.itemAtPath = (cst, path67) => {
5573
+ visit.itemAtPath = (cst, path69) => {
5574
5574
  let item = cst;
5575
- for (const [field, index] of path67) {
5575
+ for (const [field, index] of path69) {
5576
5576
  const tok = item?.[field];
5577
5577
  if (tok && "items" in tok) {
5578
5578
  item = tok.items[index];
@@ -5581,23 +5581,23 @@ var require_cst_visit = __commonJS({
5581
5581
  }
5582
5582
  return item;
5583
5583
  };
5584
- visit.parentCollection = (cst, path67) => {
5585
- const parent = visit.itemAtPath(cst, path67.slice(0, -1));
5586
- const field = path67[path67.length - 1][0];
5584
+ visit.parentCollection = (cst, path69) => {
5585
+ const parent = visit.itemAtPath(cst, path69.slice(0, -1));
5586
+ const field = path69[path69.length - 1][0];
5587
5587
  const coll = parent?.[field];
5588
5588
  if (coll && "items" in coll)
5589
5589
  return coll;
5590
5590
  throw new Error("Parent collection not found");
5591
5591
  };
5592
- function _visit(path67, item, visitor) {
5593
- let ctrl = visitor(item, path67);
5592
+ function _visit(path69, item, visitor) {
5593
+ let ctrl = visitor(item, path69);
5594
5594
  if (typeof ctrl === "symbol")
5595
5595
  return ctrl;
5596
5596
  for (const field of ["key", "value"]) {
5597
5597
  const token = item[field];
5598
5598
  if (token && "items" in token) {
5599
5599
  for (let i = 0; i < token.items.length; ++i) {
5600
- const ci = _visit(Object.freeze(path67.concat([[field, i]])), token.items[i], visitor);
5600
+ const ci = _visit(Object.freeze(path69.concat([[field, i]])), token.items[i], visitor);
5601
5601
  if (typeof ci === "number")
5602
5602
  i = ci - 1;
5603
5603
  else if (ci === BREAK)
@@ -5608,10 +5608,10 @@ var require_cst_visit = __commonJS({
5608
5608
  }
5609
5609
  }
5610
5610
  if (typeof ctrl === "function" && field === "key")
5611
- ctrl = ctrl(item, path67);
5611
+ ctrl = ctrl(item, path69);
5612
5612
  }
5613
5613
  }
5614
- return typeof ctrl === "function" ? ctrl(item, path67) : ctrl;
5614
+ return typeof ctrl === "function" ? ctrl(item, path69) : ctrl;
5615
5615
  }
5616
5616
  exports.visit = visit;
5617
5617
  }
@@ -6712,18 +6712,18 @@ var require_parser = __commonJS({
6712
6712
  if (this.type === "map-value-ind") {
6713
6713
  const prev = getPrevProps(this.peek(2));
6714
6714
  const start = getFirstKeyStartProps(prev);
6715
- let sep6;
6715
+ let sep7;
6716
6716
  if (scalar.end) {
6717
- sep6 = scalar.end;
6718
- sep6.push(this.sourceToken);
6717
+ sep7 = scalar.end;
6718
+ sep7.push(this.sourceToken);
6719
6719
  delete scalar.end;
6720
6720
  } else
6721
- sep6 = [this.sourceToken];
6721
+ sep7 = [this.sourceToken];
6722
6722
  const map = {
6723
6723
  type: "block-map",
6724
6724
  offset: scalar.offset,
6725
6725
  indent: scalar.indent,
6726
- items: [{ start, key: scalar, sep: sep6 }]
6726
+ items: [{ start, key: scalar, sep: sep7 }]
6727
6727
  };
6728
6728
  this.onKeyLine = true;
6729
6729
  this.stack[this.stack.length - 1] = map;
@@ -6876,15 +6876,15 @@ var require_parser = __commonJS({
6876
6876
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
6877
6877
  const start2 = getFirstKeyStartProps(it.start);
6878
6878
  const key = it.key;
6879
- const sep6 = it.sep;
6880
- sep6.push(this.sourceToken);
6879
+ const sep7 = it.sep;
6880
+ sep7.push(this.sourceToken);
6881
6881
  delete it.key;
6882
6882
  delete it.sep;
6883
6883
  this.stack.push({
6884
6884
  type: "block-map",
6885
6885
  offset: this.offset,
6886
6886
  indent: this.indent,
6887
- items: [{ start: start2, key, sep: sep6 }]
6887
+ items: [{ start: start2, key, sep: sep7 }]
6888
6888
  });
6889
6889
  } else if (start.length > 0) {
6890
6890
  it.sep = it.sep.concat(start, this.sourceToken);
@@ -6913,14 +6913,14 @@ var require_parser = __commonJS({
6913
6913
  case "scalar":
6914
6914
  case "single-quoted-scalar":
6915
6915
  case "double-quoted-scalar": {
6916
- const fs64 = this.flowScalar(this.type);
6916
+ const fs66 = this.flowScalar(this.type);
6917
6917
  if (atNextItem || it.value) {
6918
- map.items.push({ start, key: fs64, sep: [] });
6918
+ map.items.push({ start, key: fs66, sep: [] });
6919
6919
  this.onKeyLine = true;
6920
6920
  } else if (it.sep) {
6921
- this.stack.push(fs64);
6921
+ this.stack.push(fs66);
6922
6922
  } else {
6923
- Object.assign(it, { key: fs64, sep: [] });
6923
+ Object.assign(it, { key: fs66, sep: [] });
6924
6924
  this.onKeyLine = true;
6925
6925
  }
6926
6926
  return;
@@ -7048,13 +7048,13 @@ var require_parser = __commonJS({
7048
7048
  case "scalar":
7049
7049
  case "single-quoted-scalar":
7050
7050
  case "double-quoted-scalar": {
7051
- const fs64 = this.flowScalar(this.type);
7051
+ const fs66 = this.flowScalar(this.type);
7052
7052
  if (!it || it.value)
7053
- fc.items.push({ start: [], key: fs64, sep: [] });
7053
+ fc.items.push({ start: [], key: fs66, sep: [] });
7054
7054
  else if (it.sep)
7055
- this.stack.push(fs64);
7055
+ this.stack.push(fs66);
7056
7056
  else
7057
- Object.assign(it, { key: fs64, sep: [] });
7057
+ Object.assign(it, { key: fs66, sep: [] });
7058
7058
  return;
7059
7059
  }
7060
7060
  case "flow-map-end":
@@ -7078,13 +7078,13 @@ var require_parser = __commonJS({
7078
7078
  const prev = getPrevProps(parent);
7079
7079
  const start = getFirstKeyStartProps(prev);
7080
7080
  fixFlowSeqItems(fc);
7081
- const sep6 = fc.end.splice(1, fc.end.length);
7082
- sep6.push(this.sourceToken);
7081
+ const sep7 = fc.end.splice(1, fc.end.length);
7082
+ sep7.push(this.sourceToken);
7083
7083
  const map = {
7084
7084
  type: "block-map",
7085
7085
  offset: fc.offset,
7086
7086
  indent: fc.indent,
7087
- items: [{ start, key: fc, sep: sep6 }]
7087
+ items: [{ start, key: fc, sep: sep7 }]
7088
7088
  };
7089
7089
  this.onKeyLine = true;
7090
7090
  this.stack[this.stack.length - 1] = map;
@@ -7363,15 +7363,15 @@ var require_dist = __commonJS({
7363
7363
  });
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
- import * as path66 from "node:path";
7367
- import { fileURLToPath as fileURLToPath47 } from "node:url";
7366
+ import * as path68 from "node:path";
7367
+ import { fileURLToPath as fileURLToPath48 } from "node:url";
7368
7368
 
7369
7369
  // src/scripts/hooks/dispatch_hook.ts
7370
7370
  var import_yaml6 = __toESM(require_dist(), 1);
7371
7371
  import { spawnSync as spawnSync7 } from "node:child_process";
7372
- import fs63 from "node:fs";
7373
- import path65 from "node:path";
7374
- import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL40 } from "node:url";
7372
+ import fs65 from "node:fs";
7373
+ import path67 from "node:path";
7374
+ import { fileURLToPath as fileURLToPath47, pathToFileURL as pathToFileURL41 } from "node:url";
7375
7375
 
7376
7376
  // src/scripts/_lib/spawn_env.ts
7377
7377
  var DENY_EXACT = /* @__PURE__ */ new Set([
@@ -14036,6 +14036,11 @@ var import_yaml3 = __toESM(require_dist(), 1);
14036
14036
  import * as fs14 from "node:fs";
14037
14037
  import * as os2 from "node:os";
14038
14038
  import * as path13 from "node:path";
14039
+
14040
+ // src/scripts/ai_council/quorum.ts
14041
+ var SOLO_FLOOR_MIN_PRESENT = 2;
14042
+
14043
+ // src/scripts/ai_council/config.ts
14039
14044
  var _VALID_PROVIDERS = /* @__PURE__ */ new Set([
14040
14045
  "anthropic",
14041
14046
  "openai",
@@ -14342,6 +14347,9 @@ function _build_config(raw, source_path) {
14342
14347
  _asDict(_getOr(raw, "cli_call_budget", {}))
14343
14348
  );
14344
14349
  const quorum = _build_quorum(_get(raw, "quorum", "majority"));
14350
+ const quorum_min_present = _build_quorum_min_present(
14351
+ _get(raw, "quorum_min_present", SOLO_FLOOR_MIN_PRESENT)
14352
+ );
14345
14353
  const necessity_classifier = _build_necessity_classifier(
14346
14354
  _asDict(_getOr(raw, "necessity_classifier", {}))
14347
14355
  );
@@ -14390,6 +14398,7 @@ function _build_config(raw, source_path) {
14390
14398
  consensus_scoring: consensus,
14391
14399
  cli_call_budget,
14392
14400
  quorum,
14401
+ quorum_min_present,
14393
14402
  necessity_classifier,
14394
14403
  model_downgrade,
14395
14404
  debate,
@@ -15217,6 +15226,14 @@ function _build_quorum(raw) {
15217
15226
  `\`quorum\`=${_pyRepr3(raw)} must be 'majority' or an integer >= 1 (got ${_pyTypeName(raw)}).`
15218
15227
  );
15219
15228
  }
15229
+ function _build_quorum_min_present(raw) {
15230
+ if (_isInt(raw) && raw >= 1) {
15231
+ return raw;
15232
+ }
15233
+ throw new CouncilConfigError(
15234
+ `\`quorum_min_present\`=${_pyRepr3(raw)} must be an integer >= 1 (got ${_pyTypeName(raw)}).`
15235
+ );
15236
+ }
15220
15237
  function _build_advisor(name, cfg) {
15221
15238
  if (!_isDict(cfg)) {
15222
15239
  throw new CouncilConfigError(`advisors.${name}: must be a mapping.`);
@@ -20494,35 +20511,109 @@ function foreign_live_records(dir, session_id, options = {}) {
20494
20511
  const own = safe_stem(session_id);
20495
20512
  return read_live_records(dir, options).filter((r) => safe_stem(r.session_id) !== own);
20496
20513
  }
20514
+ function classify_collisions(others, here) {
20515
+ const out = [];
20516
+ for (const r of others) {
20517
+ if (here.roadmap_slug !== null && r.roadmap_slug !== null && r.roadmap_slug === here.roadmap_slug) {
20518
+ out.push({ kind: "roadmap", record: r });
20519
+ }
20520
+ }
20521
+ for (const r of others) {
20522
+ if (here.branch !== null && r.branch === here.branch) {
20523
+ out.push({ kind: "branch", record: r });
20524
+ }
20525
+ }
20526
+ return out;
20527
+ }
20497
20528
 
20498
20529
  // src/scripts/session_register_hook.ts
20499
20530
  var REPLAY_ENV_VAR6 = "AGENT_CONFIG_REPLAY";
20500
- var ROADMAP_CLAIM_REL = path42.join("agents", "runtime", "state", "roadmap-claim.json");
20531
+ var _STATE_REL = path42.join("agents", "runtime", "state");
20532
+ var ROADMAP_CLAIM_REL = path42.join(_STATE_REL, "roadmap-claim.json");
20533
+ function roadmap_claim_rel(session_id) {
20534
+ const id = String(session_id ?? "").trim();
20535
+ if (id === "") {
20536
+ return ROADMAP_CLAIM_REL;
20537
+ }
20538
+ const rel = path42.join(_STATE_REL, `roadmap-claim-${safe_stem(id)}.json`);
20539
+ const norm = path42.normalize(rel);
20540
+ if (!norm.startsWith(`${_STATE_REL}${path42.sep}`) || norm.includes("..")) {
20541
+ return ROADMAP_CLAIM_REL;
20542
+ }
20543
+ return norm;
20544
+ }
20501
20545
  function _is_replay_mode4() {
20502
20546
  return String(process9.env[REPLAY_ENV_VAR6] ?? "").trim() !== "";
20503
20547
  }
20504
- function read_claimed_slug(workspace_root) {
20548
+ function _read_claim_file(file) {
20505
20549
  try {
20506
- const raw = fs41.readFileSync(path42.join(workspace_root, ROADMAP_CLAIM_REL), "utf-8");
20507
- const parsed = JSON.parse(raw);
20508
- if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
20509
- const slug = parsed["slug"];
20510
- if (typeof slug === "string" && slug.trim().length > 0) {
20511
- return slug.trim();
20512
- }
20550
+ const parsed = JSON.parse(fs41.readFileSync(file, "utf-8"));
20551
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
20552
+ return null;
20513
20553
  }
20514
- return null;
20554
+ const rec = parsed;
20555
+ const slug = rec["slug"];
20556
+ if (typeof slug !== "string" || slug.trim().length === 0) {
20557
+ return null;
20558
+ }
20559
+ const sid = rec["session_id"];
20560
+ return {
20561
+ slug: slug.trim(),
20562
+ ...typeof sid === "string" && sid.trim() !== "" ? { session_id: sid.trim() } : {}
20563
+ };
20515
20564
  } catch {
20516
20565
  return null;
20517
20566
  }
20518
20567
  }
20568
+ function read_claimed_slug(workspace_root, session_id) {
20569
+ const own = roadmap_claim_rel(session_id);
20570
+ if (own !== ROADMAP_CLAIM_REL) {
20571
+ const mine = _read_claim_file(path42.join(workspace_root, own));
20572
+ if (mine !== null) {
20573
+ return mine.slug;
20574
+ }
20575
+ }
20576
+ const legacy = _read_claim_file(path42.join(workspace_root, ROADMAP_CLAIM_REL));
20577
+ if (legacy === null) {
20578
+ return null;
20579
+ }
20580
+ const id = String(session_id ?? "").trim();
20581
+ if (id !== "") {
20582
+ return null;
20583
+ }
20584
+ return legacy.slug;
20585
+ }
20586
+ function claim_is_stale(workspace_root, slug, peer_worktree) {
20587
+ if (slug === null || slug.trim() === "") {
20588
+ return false;
20589
+ }
20590
+ const base = slug.trim().replace(/\.md$/, "");
20591
+ const rel = path42.normalize(path42.join("agents", "roadmaps", `${base}.md`));
20592
+ const inside = rel.startsWith(`agents${path42.sep}roadmaps${path42.sep}`) && !rel.includes("..");
20593
+ if (!inside || path42.isAbsolute(base)) {
20594
+ return true;
20595
+ }
20596
+ const roots = [peer_worktree, workspace_root].filter(
20597
+ (r) => typeof r === "string" && r.trim() !== ""
20598
+ );
20599
+ for (const root of roots) {
20600
+ try {
20601
+ if (fs41.existsSync(path42.join(root, rel))) {
20602
+ return false;
20603
+ }
20604
+ } catch {
20605
+ return false;
20606
+ }
20607
+ }
20608
+ return true;
20609
+ }
20519
20610
  function build_record(workspace_root, session_id, platform, started_at, now = /* @__PURE__ */ new Date()) {
20520
20611
  return {
20521
20612
  session_id,
20522
20613
  platform,
20523
20614
  worktree: workspace_root,
20524
20615
  branch: current_branch(workspace_root),
20525
- roadmap_slug: read_claimed_slug(workspace_root),
20616
+ roadmap_slug: read_claimed_slug(workspace_root, session_id),
20526
20617
  started_at,
20527
20618
  last_seen: iso_now(now)
20528
20619
  };
@@ -20540,20 +20631,26 @@ function foreign_sessions_block(workspace_root, session_id, now = /* @__PURE__ *
20540
20631
  const others = foreign_live_records(dir, session_id, { prune: true, now });
20541
20632
  if (others.length === 0) return null;
20542
20633
  const here = current_branch(workspace_root);
20634
+ const my_slug = read_claimed_slug(workspace_root, session_id);
20543
20635
  const lines = [];
20544
- let collision = null;
20636
+ const live_others = [];
20545
20637
  for (const r of others) {
20546
20638
  const age_min = Math.max(0, Math.round((now.getTime() - Date.parse(r.last_seen)) / 6e4));
20547
- const slug = r.roadmap_slug === null ? "no roadmap claimed" : `roadmap: ${r.roadmap_slug}`;
20639
+ const stale = claim_is_stale(workspace_root, r.roadmap_slug, r.worktree);
20640
+ const slug = r.roadmap_slug === null ? "no roadmap claimed" : stale ? `roadmap: ${r.roadmap_slug} (STALE \u2014 no such open roadmap; treat as no claim)` : `roadmap: ${r.roadmap_slug}`;
20548
20641
  const ttl_note = ttl_is_measured(r.platform) ? "" : ` \xB7 unmeasured host, TTL falls back to ${Math.round(ttl_seconds_for(r.platform) / 3600)}h`;
20549
20642
  lines.push(
20550
20643
  `- ${r.platform} \xB7 branch \`${r.branch ?? "detached"}\` \xB7 ${slug} \xB7 last seen ${age_min} min ago${ttl_note}
20551
20644
  worktree: ${r.worktree}`
20552
20645
  );
20553
- if (collision === null && here !== null && r.branch === here) {
20554
- collision = r;
20555
- }
20646
+ live_others.push(stale ? { ...r, roadmap_slug: null } : r);
20556
20647
  }
20648
+ const collisions = classify_collisions(live_others, {
20649
+ branch: here,
20650
+ roadmap_slug: claim_is_stale(workspace_root, my_slug) ? null : my_slug
20651
+ });
20652
+ const roadmap_hits = collisions.filter((c) => c.kind === "roadmap");
20653
+ const branch_hit = collisions.find((c) => c.kind === "branch") ?? null;
20557
20654
  const parts = [
20558
20655
  "<session-register>",
20559
20656
  "The following OTHER agent sessions are live on this repository right now.",
@@ -20561,7 +20658,23 @@ function foreign_sessions_block(workspace_root, session_id, now = /* @__PURE__ *
20561
20658
  "",
20562
20659
  ...lines
20563
20660
  ];
20564
- if (collision !== null) {
20661
+ if (roadmap_hits.length > 0) {
20662
+ parts.push(
20663
+ "",
20664
+ `DUPLICATE WORK: ${roadmap_hits.length} other live session(s) claim the SAME roadmap \`${my_slug}\`.`,
20665
+ ...roadmap_hits.map(
20666
+ (h) => ` \xB7 branch \`${h.record.branch ?? "detached"}\` in ${h.record.worktree}`
20667
+ ),
20668
+ "A different branch name does NOT make this a different task \u2014 measured twice,",
20669
+ "two sessions built one roadmap phase under two branch names and one PR was wasted.",
20670
+ "STOP before writing code. Ask the user ONCE, as numbered options:",
20671
+ " 1. Take a different roadmap (`agent-config sessions:list` shows what is held)",
20672
+ " 2. Split the roadmap explicitly \u2014 name which phases are yours",
20673
+ " 3. Continue anyway, accepting that one of the two results is discarded",
20674
+ "Never decide silently, in either direction."
20675
+ );
20676
+ }
20677
+ if (branch_hit !== null) {
20565
20678
  parts.push(
20566
20679
  "",
20567
20680
  `COLLISION: another live session already holds branch \`${here}\`.`,
@@ -20602,6 +20715,10 @@ function main25() {
20602
20715
  if (event === "session_end" || event === "stop" && stop_means_session_end(platform)) {
20603
20716
  const dir = register_dir(root);
20604
20717
  if (dir !== null) delete_record(dir, session_id);
20718
+ try {
20719
+ fs41.unlinkSync(path42.join(root, roadmap_claim_rel(session_id)));
20720
+ } catch {
20721
+ }
20605
20722
  return 0;
20606
20723
  }
20607
20724
  if (event === "session_start" || event === "user_prompt_submit" || event === "stop") {
@@ -22528,7 +22645,7 @@ import { fileURLToPath as fileURLToPath36, pathToFileURL as pathToFileURL29 } fr
22528
22645
 
22529
22646
  // src/install/rtkDetection.ts
22530
22647
  import { spawnSync as spawnSync4 } from "node:child_process";
22531
- import { existsSync as existsSync8, statSync as statSync9, readFileSync as readFileSync19, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9 } from "node:fs";
22648
+ import { existsSync as existsSync9, statSync as statSync9, readFileSync as readFileSync19, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9 } from "node:fs";
22532
22649
  import { homedir as homedir4 } from "node:os";
22533
22650
  import { delimiter, join as join19, dirname as dirname9 } from "node:path";
22534
22651
  var TOKEN_KILLER_GAIN_SIGNATURE = /RTK Token Savings/;
@@ -22541,7 +22658,7 @@ function resolveBinaryOnPath(name, pathEnv) {
22541
22658
  if (dir.length === 0) continue;
22542
22659
  for (const suffix of suffixes) {
22543
22660
  const candidate = join19(dir, `${name}${suffix}`);
22544
- if (existsSync8(candidate)) return candidate;
22661
+ if (existsSync9(candidate)) return candidate;
22545
22662
  }
22546
22663
  }
22547
22664
  return null;
@@ -22878,6 +22995,44 @@ import fs51 from "node:fs";
22878
22995
  import path52 from "node:path";
22879
22996
  import { fileURLToPath as fileURLToPath37, pathToFileURL as pathToFileURL30 } from "node:url";
22880
22997
 
22998
+ // src/scripts/_lib/ui_surface.ts
22999
+ var UI_EXTENSIONS = [
23000
+ "html",
23001
+ "htm",
23002
+ "css",
23003
+ "scss",
23004
+ "sass",
23005
+ "less",
23006
+ "vue",
23007
+ "svelte",
23008
+ "astro",
23009
+ "jsx",
23010
+ "tsx"
23011
+ ];
23012
+ var UI_COMPOUND_SUFFIXES = [".blade.php"];
23013
+ var UI_EXT = new RegExp(
23014
+ `(\\.(${UI_EXTENSIONS.join("|")})|${UI_COMPOUND_SUFFIXES.map((s) => s.replace(/\./g, "\\.")).join("|")})$`,
23015
+ "i"
23016
+ );
23017
+ function isUiPath(p) {
23018
+ return UI_EXT.test(p);
23019
+ }
23020
+ var UI_PATH_FRAGMENTS = [
23021
+ "resources/views/",
23022
+ "resources/js/",
23023
+ // `components/` already subsumes `src/components/` under substring
23024
+ // matching — listing both here would be dead weight. The rules' own
23025
+ // `path_prefix` list keeps both because matching there is anchored.
23026
+ "components/",
23027
+ "pages/"
23028
+ ];
23029
+ var UI_TREE_EXCLUSIONS = ["pages/api/"];
23030
+ function isUiTreePath(p) {
23031
+ const normalized = p.replace(/\\/g, "/").toLowerCase();
23032
+ if (UI_TREE_EXCLUSIONS.some((fragment) => normalized.includes(fragment))) return false;
23033
+ return UI_PATH_FRAGMENTS.some((fragment) => normalized.includes(fragment));
23034
+ }
23035
+
22881
23036
  // src/scripts/lint_design_slop.ts
22882
23037
  import fs50 from "node:fs";
22883
23038
  import path51 from "node:path";
@@ -23467,7 +23622,6 @@ var SETTINGS_FILE7 = ".agent-settings.yml";
23467
23622
  var EXIT_ALLOW13 = 0;
23468
23623
  var EXIT_WARN6 = 2;
23469
23624
  var DEGRADE_AFTER = 3;
23470
- var UI_EXT = /\.(html|htm|css|scss|sass|less|vue|svelte|astro|jsx|tsx)$/i;
23471
23625
  function isObject2(v) {
23472
23626
  return typeof v === "object" && v !== null && !Array.isArray(v);
23473
23627
  }
@@ -23876,11 +24030,180 @@ function isCliEntry11() {
23876
24030
  }
23877
24031
  if (isCliEntry11()) process.exit(main36());
23878
24032
 
23879
- // src/scripts/hooks/orchestration_record_hook.ts
23880
- import * as crypto4 from "node:crypto";
24033
+ // src/scripts/hooks/ui_route_nudge_hook.ts
23881
24034
  import * as fs55 from "node:fs";
23882
24035
  import * as path56 from "node:path";
23883
- import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL33 } from "node:url";
24036
+ import { fileURLToPath as fileURLToPath39, pathToFileURL as pathToFileURL32 } from "node:url";
24037
+
24038
+ // src/scripts/_lib/hook_settings.ts
24039
+ import * as fs54 from "node:fs";
24040
+ import * as path55 from "node:path";
24041
+ var SETTINGS_FILE9 = ".agent-settings.yml";
24042
+ function hookSectionEnabled(root, section) {
24043
+ const file = path55.join(root, SETTINGS_FILE9);
24044
+ let text;
24045
+ try {
24046
+ if (!fs54.statSync(file).isFile()) return false;
24047
+ text = fs54.readFileSync(file, "utf-8");
24048
+ } catch {
24049
+ return false;
24050
+ }
24051
+ const escaped = section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24052
+ const sectionPattern = new RegExp(`^(\\s+)${escaped}\\s*:\\s*$`);
24053
+ let inHooks = false;
24054
+ let sectionIndent = null;
24055
+ const indentOf = (line) => line.length - line.replace(/^\s+/, "").length;
24056
+ for (const raw of text.split(/\r\n|\r|\n/)) {
24057
+ const line = raw.replace(/\s+$/, "");
24058
+ if (!line || line.replace(/^\s+/, "").startsWith("#")) continue;
24059
+ if (!(line.startsWith(" ") || line.startsWith(" "))) {
24060
+ inHooks = /^hooks\s*:\s*$/.test(line);
24061
+ sectionIndent = null;
24062
+ continue;
24063
+ }
24064
+ if (inHooks) {
24065
+ const opened = sectionPattern.exec(line);
24066
+ if (opened) {
24067
+ sectionIndent = opened[1].length;
24068
+ continue;
24069
+ }
24070
+ if (sectionIndent !== null && indentOf(line) <= sectionIndent) {
24071
+ sectionIndent = null;
24072
+ }
24073
+ }
24074
+ if (sectionIndent !== null && /^\s+enabled\s*:\s*true\b/.test(line)) return true;
24075
+ }
24076
+ return false;
24077
+ }
24078
+
24079
+ // src/scripts/hooks/ui_route_nudge_hook.ts
24080
+ var EXIT_ALLOW15 = 0;
24081
+ var EXIT_WARN8 = 2;
24082
+ var MAX_NUDGES = 2;
24083
+ var DESIGN_SURFACES = [
24084
+ "fe-design",
24085
+ "existing-ui-audit",
24086
+ "design-review",
24087
+ "design-intelligence"
24088
+ ];
24089
+ function isObject4(v) {
24090
+ return typeof v === "object" && v !== null && !Array.isArray(v);
24091
+ }
24092
+ function unwrap2(envelope) {
24093
+ const inner = envelope["payload"];
24094
+ return isObject4(inner) ? inner : envelope;
24095
+ }
24096
+ function extractEvent(outer) {
24097
+ const envelope = unwrap2(outer);
24098
+ const ti = envelope["tool_input"] ?? envelope["toolInput"] ?? envelope["input"];
24099
+ if (!isObject4(ti)) return null;
24100
+ const fileVal = ti["file_path"] ?? ti["path"] ?? ti["filePath"];
24101
+ const file = typeof fileVal === "string" ? fileVal : "";
24102
+ let isWrite = false;
24103
+ for (const key of ["content", "new_string", "new_str", "text", "newText"]) {
24104
+ if (typeof ti[key] === "string" && ti[key].length > 0) isWrite = true;
24105
+ }
24106
+ return { file, isWrite };
24107
+ }
24108
+ function isConsultation(event) {
24109
+ if (event.isWrite || !event.file) return false;
24110
+ const normalized = event.file.replace(/\\/g, "/").toLowerCase();
24111
+ return DESIGN_SURFACES.some((surface) => normalized.includes(`skills/${surface}/`));
24112
+ }
24113
+ function isUiWrite(event) {
24114
+ if (!event.isWrite || !event.file) return false;
24115
+ return isUiPath(event.file) || isUiTreePath(event.file);
24116
+ }
24117
+ function stateFile2(root) {
24118
+ return path56.join(root, "agents", "runtime", "state", "ui-route-nudge.json");
24119
+ }
24120
+ function readState2(root, session) {
24121
+ try {
24122
+ const all = JSON.parse(fs55.readFileSync(stateFile2(root), "utf-8"));
24123
+ const entry = all[session];
24124
+ if (entry && typeof entry.consulted === "boolean" && typeof entry.nudges === "number") {
24125
+ return entry;
24126
+ }
24127
+ } catch {
24128
+ }
24129
+ return { consulted: false, nudges: 0 };
24130
+ }
24131
+ var MAX_SESSIONS = 50;
24132
+ function pruneSessions(all, keep = MAX_SESSIONS) {
24133
+ const keys = Object.keys(all);
24134
+ if (keys.length <= keep) return all;
24135
+ const survivors = keys.slice(keys.length - keep);
24136
+ const pruned = {};
24137
+ for (const key of survivors) pruned[key] = all[key];
24138
+ return pruned;
24139
+ }
24140
+ function writeState2(root, session, state) {
24141
+ try {
24142
+ const file = stateFile2(root);
24143
+ let all = {};
24144
+ try {
24145
+ all = JSON.parse(fs55.readFileSync(file, "utf-8"));
24146
+ } catch {
24147
+ }
24148
+ if (typeof all !== "object" || all === null || Array.isArray(all)) all = {};
24149
+ all[session] = state;
24150
+ fs55.mkdirSync(path56.dirname(file), { recursive: true });
24151
+ fs55.writeFileSync(file, JSON.stringify(pruneSessions(all)));
24152
+ } catch {
24153
+ }
24154
+ }
24155
+ function decide4(event, state) {
24156
+ if (isConsultation(event)) {
24157
+ return { state: { ...state, consulted: true }, warn: false };
24158
+ }
24159
+ if (!isUiWrite(event)) return { state, warn: false };
24160
+ if (state.consulted) return { state, warn: false };
24161
+ if (state.nudges >= MAX_NUDGES) return { state, warn: false };
24162
+ return { state: { ...state, nudges: state.nudges + 1 }, warn: true };
24163
+ }
24164
+ function nudgeReason2(file) {
24165
+ return `Non-trivial UI write to ${file} with no design consultation this session. Run \`existing-ui-audit\` first, then the fe-design loop (brief \u2192 build \u2192 review). Skip only if this is ui-trivial: <=1 file, <=5 lines, no new component, no new state, no new dependency.`;
24166
+ }
24167
+ function main37() {
24168
+ let envelope;
24169
+ try {
24170
+ const raw = readHookStdin();
24171
+ if (!raw.trim()) return EXIT_ALLOW15;
24172
+ envelope = JSON.parse(raw);
24173
+ } catch {
24174
+ return EXIT_ALLOW15;
24175
+ }
24176
+ if (!isObject4(envelope)) return EXIT_ALLOW15;
24177
+ const rootVal = envelope["workspace_root"];
24178
+ const root = typeof rootVal === "string" && rootVal ? rootVal : process.cwd();
24179
+ if (!hookSectionEnabled(root, "ui_route_nudge")) return EXIT_ALLOW15;
24180
+ const sessionVal = envelope["session_id"];
24181
+ const session = typeof sessionVal === "string" && sessionVal ? sessionVal : "unknown";
24182
+ const event = extractEvent(envelope);
24183
+ if (!event) return EXIT_ALLOW15;
24184
+ const before = readState2(root, session);
24185
+ const { state, warn } = decide4(event, before);
24186
+ if (state.consulted !== before.consulted || state.nudges !== before.nudges) {
24187
+ writeState2(root, session, state);
24188
+ }
24189
+ if (!warn) return EXIT_ALLOW15;
24190
+ process.stdout.write(`${JSON.stringify({ reason: nudgeReason2(event.file) })}
24191
+ `);
24192
+ return EXIT_WARN8;
24193
+ }
24194
+ function isCliEntry12() {
24195
+ const entry = process.argv[1];
24196
+ if (!entry) return false;
24197
+ return pathToFileURL32(path56.resolve(entry)).href === import.meta.url;
24198
+ }
24199
+ if (isCliEntry12()) process.exit(main37());
24200
+ var _HOOK_FILE = fileURLToPath39(import.meta.url);
24201
+
24202
+ // src/scripts/hooks/orchestration_record_hook.ts
24203
+ import * as crypto4 from "node:crypto";
24204
+ import * as fs57 from "node:fs";
24205
+ import * as path58 from "node:path";
24206
+ import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL34 } from "node:url";
23884
24207
 
23885
24208
  // src/scripts/_lib/orchestration_record.ts
23886
24209
  var DISPATCH_OUTCOMES = ["DONE", "DONE_WITH_CONCERNS", "NEEDS_CONTEXT", "BLOCKED", "killed"];
@@ -24076,9 +24399,9 @@ function buildOrchestrationLine(input) {
24076
24399
 
24077
24400
  // src/scripts/orchestration_record.ts
24078
24401
  import * as crypto3 from "node:crypto";
24079
- import * as fs54 from "node:fs";
24080
- import * as path55 from "node:path";
24081
- import { pathToFileURL as pathToFileURL32 } from "node:url";
24402
+ import * as fs56 from "node:fs";
24403
+ import * as path57 from "node:path";
24404
+ import { pathToFileURL as pathToFileURL33 } from "node:url";
24082
24405
  var DEFAULT_DIR = "agents/runtime/state/audit";
24083
24406
  function parseFlags(argv) {
24084
24407
  const flags = {};
@@ -24128,7 +24451,7 @@ function contentHashId(input) {
24128
24451
  });
24129
24452
  return crypto3.createHash("sha256").update(canonical).digest("hex").slice(0, 26).toUpperCase();
24130
24453
  }
24131
- function main37(argv = process.argv.slice(2)) {
24454
+ function main38(argv = process.argv.slice(2)) {
24132
24455
  const flags = parseFlags(argv);
24133
24456
  const dir = str2(flags, "dir") ?? DEFAULT_DIR;
24134
24457
  const dryRun = flags["dry-run"] === true;
@@ -24189,27 +24512,27 @@ function main37(argv = process.argv.slice(2)) {
24189
24512
  process.stdout.write(serialized + "\n");
24190
24513
  return 0;
24191
24514
  }
24192
- fs54.mkdirSync(dir, { recursive: true });
24193
- const file = path55.join(dir, `${ts.slice(0, 7)}.jsonl`);
24194
- fs54.appendFileSync(file, serialized + "\n", "utf8");
24515
+ fs56.mkdirSync(dir, { recursive: true });
24516
+ const file = path57.join(dir, `${ts.slice(0, 7)}.jsonl`);
24517
+ fs56.appendFileSync(file, serialized + "\n", "utf8");
24195
24518
  process.stdout.write(`orchestration telemetry recorded \u2192 ${file} (id ${line.id})
24196
24519
  `);
24197
24520
  return 0;
24198
24521
  }
24199
24522
  if (process.argv[1] !== void 0) {
24200
- const invokedUrl = pathToFileURL32(path55.resolve(process.argv[1])).href;
24201
- if (import.meta.url === invokedUrl) process.exit(main37());
24523
+ const invokedUrl = pathToFileURL33(path57.resolve(process.argv[1])).href;
24524
+ if (import.meta.url === invokedUrl) process.exit(main38());
24202
24525
  }
24203
24526
 
24204
24527
  // src/scripts/hooks/orchestration_record_hook.ts
24205
- var EXIT_ALLOW15 = 0;
24206
- function isObject4(v) {
24528
+ var EXIT_ALLOW16 = 0;
24529
+ function isObject5(v) {
24207
24530
  return typeof v === "object" && v !== null && !Array.isArray(v);
24208
24531
  }
24209
24532
  var DISPATCH_TOOL_NAMES = /* @__PURE__ */ new Set(["Agent", "Task"]);
24210
24533
  function unwrapPayload(envelope) {
24211
24534
  const inner = envelope["payload"];
24212
- return isObject4(inner) ? inner : envelope;
24535
+ return isObject5(inner) ? inner : envelope;
24213
24536
  }
24214
24537
  function extractToolName(payload) {
24215
24538
  const v = payload["tool_name"] ?? payload["toolName"] ?? payload["tool"];
@@ -24217,12 +24540,12 @@ function extractToolName(payload) {
24217
24540
  }
24218
24541
  function extractToolInput(payload) {
24219
24542
  const v = payload["tool_input"] ?? payload["toolInput"];
24220
- return isObject4(v) ? v : null;
24543
+ return isObject5(v) ? v : null;
24221
24544
  }
24222
24545
  function extractToolResult(payload) {
24223
24546
  for (const key of ["tool_response", "toolResponse", "tool_result", "toolUseResult"]) {
24224
24547
  const v = payload[key];
24225
- if (isObject4(v)) return v;
24548
+ if (isObject5(v)) return v;
24226
24549
  }
24227
24550
  return null;
24228
24551
  }
@@ -24243,7 +24566,7 @@ function extractDispatchFacts(payload) {
24243
24566
  const result = extractToolResult(payload);
24244
24567
  const resolvedModel = result && typeof result["resolvedModel"] === "string" ? result["resolvedModel"] : null;
24245
24568
  let totalTokens = result ? numOrNull(result["totalTokens"]) : null;
24246
- if (totalTokens === null && result && isObject4(result["usage"])) {
24569
+ if (totalTokens === null && result && isObject5(result["usage"])) {
24247
24570
  const usage = result["usage"];
24248
24571
  const inTok = numOrNull(usage["input_tokens"]);
24249
24572
  const outTok = numOrNull(usage["output_tokens"]);
@@ -24292,35 +24615,35 @@ function buildRecordInput(facts, ts, id) {
24292
24615
  return input;
24293
24616
  }
24294
24617
  function auditFileFor(consumerRoot, ts) {
24295
- return path56.join(consumerRoot, DEFAULT_DIR, `${ts.slice(0, 7)}.jsonl`);
24618
+ return path58.join(consumerRoot, DEFAULT_DIR, `${ts.slice(0, 7)}.jsonl`);
24296
24619
  }
24297
24620
  function appendLine(consumerRoot, ts, line) {
24298
24621
  if (is_replay_mode()) return;
24299
24622
  const file = auditFileFor(consumerRoot, ts);
24300
- fs55.mkdirSync(path56.dirname(file), { recursive: true });
24301
- fs55.appendFileSync(file, `${JSON.stringify(line)}
24623
+ fs57.mkdirSync(path58.dirname(file), { recursive: true });
24624
+ fs57.appendFileSync(file, `${JSON.stringify(line)}
24302
24625
  `, "utf8");
24303
24626
  }
24304
24627
  function processEnvelope(envelope, consumer_root) {
24305
24628
  try {
24306
- if (!isObject4(envelope)) return EXIT_ALLOW15;
24629
+ if (!isObject5(envelope)) return EXIT_ALLOW16;
24307
24630
  const payload = unwrapPayload(envelope);
24308
24631
  const toolName = extractToolName(payload);
24309
- if (toolName === null || !DISPATCH_TOOL_NAMES.has(toolName)) return EXIT_ALLOW15;
24632
+ if (toolName === null || !DISPATCH_TOOL_NAMES.has(toolName)) return EXIT_ALLOW16;
24310
24633
  const facts = extractDispatchFacts(payload);
24311
24634
  const ts = (/* @__PURE__ */ new Date()).toISOString();
24312
24635
  const id = crypto4.randomUUID();
24313
24636
  const input = buildRecordInput(facts, ts, id);
24314
24637
  const { line, errors } = buildOrchestrationLine(input);
24315
- if (errors.length || line === null) return EXIT_ALLOW15;
24638
+ if (errors.length || line === null) return EXIT_ALLOW16;
24316
24639
  appendLine(consumer_root, ts, line);
24317
24640
  } catch {
24318
- return EXIT_ALLOW15;
24641
+ return EXIT_ALLOW16;
24319
24642
  }
24320
- return EXIT_ALLOW15;
24643
+ return EXIT_ALLOW16;
24321
24644
  }
24322
24645
  function _resolveRoot(envelope) {
24323
- if (isObject4(envelope)) {
24646
+ if (isObject5(envelope)) {
24324
24647
  const cwd = envelope["cwd"];
24325
24648
  if (typeof cwd === "string" && cwd) return cwd;
24326
24649
  const pr = envelope["workspace_root"] ?? envelope["project_root"];
@@ -24328,13 +24651,13 @@ function _resolveRoot(envelope) {
24328
24651
  }
24329
24652
  return process.cwd();
24330
24653
  }
24331
- function main38() {
24654
+ function main39() {
24332
24655
  const raw = readHookStdin();
24333
24656
  let envelope = {};
24334
24657
  try {
24335
24658
  envelope = raw.trim() ? JSON.parse(raw) : {};
24336
24659
  } catch {
24337
- return EXIT_ALLOW15;
24660
+ return EXIT_ALLOW16;
24338
24661
  }
24339
24662
  return processEnvelope(envelope, _resolveRoot(envelope));
24340
24663
  }
@@ -24343,20 +24666,20 @@ function _isCliEntry29() {
24343
24666
  return false;
24344
24667
  }
24345
24668
  if (process.argv[1] === void 0) return false;
24346
- const argvUrl = pathToFileURL33(path56.resolve(process.argv[1])).href;
24669
+ const argvUrl = pathToFileURL34(path58.resolve(process.argv[1])).href;
24347
24670
  if (import.meta.url === argvUrl) return true;
24348
24671
  try {
24349
- return fs55.realpathSync(fileURLToPath39(import.meta.url)) === fs55.realpathSync(path56.resolve(process.argv[1]));
24672
+ return fs57.realpathSync(fileURLToPath40(import.meta.url)) === fs57.realpathSync(path58.resolve(process.argv[1]));
24350
24673
  } catch {
24351
24674
  return false;
24352
24675
  }
24353
24676
  }
24354
- if (_isCliEntry29()) process.exit(main38());
24677
+ if (_isCliEntry29()) process.exit(main39());
24355
24678
 
24356
24679
  // src/scripts/hooks/delegation_nudge_hook.ts
24357
- import fs56 from "node:fs";
24358
- import path57 from "node:path";
24359
- import { fileURLToPath as fileURLToPath40, pathToFileURL as pathToFileURL34 } from "node:url";
24680
+ import fs58 from "node:fs";
24681
+ import path59 from "node:path";
24682
+ import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL35 } from "node:url";
24360
24683
 
24361
24684
  // src/scripts/_lib/host_capability.ts
24362
24685
  import process10 from "node:process";
@@ -24691,8 +25014,8 @@ function resolveSubagentRouting(inp) {
24691
25014
  }
24692
25015
 
24693
25016
  // src/scripts/hooks/delegation_nudge_hook.ts
24694
- var EXIT_ALLOW16 = 0;
24695
- var EXIT_WARN8 = 2;
25017
+ var EXIT_ALLOW17 = 0;
25018
+ var EXIT_WARN9 = 2;
24696
25019
  function _isObject13(v) {
24697
25020
  return typeof v === "object" && v !== null && !Array.isArray(v);
24698
25021
  }
@@ -24849,34 +25172,34 @@ function _workspaceRoot3(envelope) {
24849
25172
  }
24850
25173
  return process.cwd();
24851
25174
  }
24852
- function main39() {
25175
+ function main40() {
24853
25176
  let envelope = {};
24854
25177
  try {
24855
25178
  const raw = readHookStdin();
24856
25179
  envelope = raw.trim() ? JSON.parse(raw) : {};
24857
25180
  } catch {
24858
- return EXIT_ALLOW16;
25181
+ return EXIT_ALLOW17;
24859
25182
  }
24860
25183
  const env = _isObject13(envelope) ? envelope : {};
24861
25184
  const event = env["event"];
24862
25185
  const slot = typeof event === "string" && event !== "" ? event : "user_prompt_submit";
24863
25186
  if (slot !== "user_prompt_submit") {
24864
- return EXIT_ALLOW16;
25187
+ return EXIT_ALLOW17;
24865
25188
  }
24866
25189
  const payload = _isObject13(env["payload"]) ? env["payload"] : env;
24867
25190
  const prompt = _extractPrompt2(payload);
24868
25191
  if (!prompt) {
24869
- return EXIT_ALLOW16;
25192
+ return EXIT_ALLOW17;
24870
25193
  }
24871
25194
  if (isSyntheticPrompt(prompt)) {
24872
- return EXIT_ALLOW16;
25195
+ return EXIT_ALLOW17;
24873
25196
  }
24874
25197
  const root = _workspaceRoot3(env);
24875
25198
  const platform = env["platform"];
24876
25199
  const hostId = typeof platform === "string" && platform ? platform : null;
24877
25200
  const result = classifyPrompt(prompt, root, hostId);
24878
25201
  if (!result) {
24879
- return EXIT_ALLOW16;
25202
+ return EXIT_ALLOW17;
24880
25203
  }
24881
25204
  process.stdout.write(
24882
25205
  `${JSON.stringify({
@@ -24886,7 +25209,7 @@ function main39() {
24886
25209
  })}
24887
25210
  `
24888
25211
  );
24889
- return EXIT_WARN8;
25212
+ return EXIT_WARN9;
24890
25213
  }
24891
25214
  function _isCliEntry30() {
24892
25215
  if (true) {
@@ -24895,29 +25218,29 @@ function _isCliEntry30() {
24895
25218
  if (process.argv[1] === void 0) {
24896
25219
  return false;
24897
25220
  }
24898
- const argvUrl = pathToFileURL34(path57.resolve(process.argv[1])).href;
25221
+ const argvUrl = pathToFileURL35(path59.resolve(process.argv[1])).href;
24899
25222
  if (import.meta.url === argvUrl) {
24900
25223
  return true;
24901
25224
  }
24902
25225
  try {
24903
- const here = fs56.realpathSync(fileURLToPath40(import.meta.url));
24904
- const argv = fs56.realpathSync(path57.resolve(process.argv[1]));
25226
+ const here = fs58.realpathSync(fileURLToPath41(import.meta.url));
25227
+ const argv = fs58.realpathSync(path59.resolve(process.argv[1]));
24905
25228
  return here === argv;
24906
25229
  } catch {
24907
25230
  return false;
24908
25231
  }
24909
25232
  }
24910
25233
  if (_isCliEntry30()) {
24911
- process.exit(main39());
25234
+ process.exit(main40());
24912
25235
  }
24913
25236
 
24914
25237
  // src/scripts/hooks/end_review_nudge_hook.ts
24915
25238
  import { spawnSync as spawnSync5 } from "node:child_process";
24916
25239
  import * as crypto5 from "node:crypto";
24917
- import * as fs57 from "node:fs";
25240
+ import * as fs59 from "node:fs";
24918
25241
  import * as os6 from "node:os";
24919
- import * as path58 from "node:path";
24920
- import { fileURLToPath as fileURLToPath41, pathToFileURL as pathToFileURL35 } from "node:url";
25242
+ import * as path60 from "node:path";
25243
+ import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL36 } from "node:url";
24921
25244
 
24922
25245
  // src/scripts/_lib/review_skipped_record.ts
24923
25246
  function isNonNegInt(n) {
@@ -24964,19 +25287,19 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
24964
25287
  const homeDir = opts.homeDir ?? os6.homedir();
24965
25288
  const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
24966
25289
  try {
24967
- const realHome = fs57.realpathSync(homeDir);
24968
- const realPath = fs57.realpathSync(rawPath);
24969
- const relative9 = path58.relative(realHome, realPath);
24970
- if (relative9 === "" || relative9.startsWith("..") || path58.isAbsolute(relative9)) {
25290
+ const realHome = fs59.realpathSync(homeDir);
25291
+ const realPath = fs59.realpathSync(rawPath);
25292
+ const relative9 = path60.relative(realHome, realPath);
25293
+ if (relative9 === "" || relative9.startsWith("..") || path60.isAbsolute(relative9)) {
24971
25294
  return false;
24972
25295
  }
24973
- const { size } = fs57.statSync(realPath);
25296
+ const { size } = fs59.statSync(realPath);
24974
25297
  return size <= maxBytes;
24975
25298
  } catch {
24976
25299
  return false;
24977
25300
  }
24978
25301
  }
24979
- var EXIT_WARN9 = 2;
25302
+ var EXIT_WARN10 = 2;
24980
25303
  function parseNumstat(raw) {
24981
25304
  const rows = [];
24982
25305
  for (const line of raw.split("\n")) {
@@ -25049,7 +25372,7 @@ function totalNonDocMutatedLinesWithMeasure(cwd) {
25049
25372
  );
25050
25373
  return { lines: trackedLines + untrackedLines, measure: "exact" };
25051
25374
  }
25052
- function isObject5(v) {
25375
+ function isObject6(v) {
25053
25376
  return typeof v === "object" && v !== null && !Array.isArray(v);
25054
25377
  }
25055
25378
  function str3(v) {
@@ -25069,16 +25392,16 @@ function scanTranscriptForReviewer(transcriptText) {
25069
25392
  } catch {
25070
25393
  continue;
25071
25394
  }
25072
- if (!isObject5(obj) || obj["type"] !== "assistant") continue;
25395
+ if (!isObject6(obj) || obj["type"] !== "assistant") continue;
25073
25396
  const msg = obj["message"];
25074
- if (!isObject5(msg)) continue;
25397
+ if (!isObject6(msg)) continue;
25075
25398
  const content = msg["content"];
25076
25399
  if (!Array.isArray(content)) continue;
25077
25400
  for (const blk of content) {
25078
- if (!isObject5(blk) || blk["type"] !== "tool_use") continue;
25401
+ if (!isObject6(blk) || blk["type"] !== "tool_use") continue;
25079
25402
  const name = str3(blk["name"]);
25080
25403
  const input = blk["input"];
25081
- const inputObj = isObject5(input) ? input : {};
25404
+ const inputObj = isObject6(input) ? input : {};
25082
25405
  if (DISPATCH_TOOL_RE.test(name)) {
25083
25406
  const label = [
25084
25407
  str3(inputObj["description"]),
@@ -25113,19 +25436,19 @@ function appendReviewSkippedTelemetry(workspaceRoot2, diffLines, mutationMeasure
25113
25436
  });
25114
25437
  if (errors.length || line === null) return;
25115
25438
  try {
25116
- const dir = path58.join(workspaceRoot2, "agents", "runtime", "state", "audit");
25117
- fs57.mkdirSync(dir, { recursive: true });
25118
- const file = path58.join(dir, `${ts.slice(0, 7)}.jsonl`);
25119
- fs57.appendFileSync(file, `${JSON.stringify(line)}
25439
+ const dir = path60.join(workspaceRoot2, "agents", "runtime", "state", "audit");
25440
+ fs59.mkdirSync(dir, { recursive: true });
25441
+ const file = path60.join(dir, `${ts.slice(0, 7)}.jsonl`);
25442
+ fs59.appendFileSync(file, `${JSON.stringify(line)}
25120
25443
  `, "utf8");
25121
25444
  } catch {
25122
25445
  }
25123
25446
  }
25124
25447
  function sessionStateDir(workspaceRoot2) {
25125
- return path58.join(workspaceRoot2, "agents", "runtime", "state", "end-review-nudge");
25448
+ return path60.join(workspaceRoot2, "agents", "runtime", "state", "end-review-nudge");
25126
25449
  }
25127
25450
  function sessionStateFile(workspaceRoot2, sessionKey) {
25128
- return path58.join(sessionStateDir(workspaceRoot2), `${sessionKey}.json`);
25451
+ return path60.join(sessionStateDir(workspaceRoot2), `${sessionKey}.json`);
25129
25452
  }
25130
25453
  function deriveSessionKey(envelope, payload) {
25131
25454
  const raw = str3(envelope["session_id"]) || str3(payload["transcript_path"] ?? payload["transcriptPath"]);
@@ -25134,7 +25457,7 @@ function deriveSessionKey(envelope, payload) {
25134
25457
  }
25135
25458
  function hasFiredThisSession(workspaceRoot2, sessionKey) {
25136
25459
  try {
25137
- return fs57.existsSync(sessionStateFile(workspaceRoot2, sessionKey));
25460
+ return fs59.existsSync(sessionStateFile(workspaceRoot2, sessionKey));
25138
25461
  } catch {
25139
25462
  return false;
25140
25463
  }
@@ -25148,7 +25471,7 @@ function markFiredThisSession(workspaceRoot2, sessionKey, ts) {
25148
25471
  function _read_stdin3() {
25149
25472
  return readHookStdin();
25150
25473
  }
25151
- function main40() {
25474
+ function main41() {
25152
25475
  const [envelope, payload] = unwrap(_read_stdin3(), "claude");
25153
25476
  const event = String(envelope["event"] ?? "");
25154
25477
  if (event !== "" && event !== "stop") {
@@ -25177,7 +25500,7 @@ function main40() {
25177
25500
  let reviewerRan = false;
25178
25501
  if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
25179
25502
  try {
25180
- reviewerRan = scanTranscriptForReviewer(fs57.readFileSync(transcriptPath, "utf-8"));
25503
+ reviewerRan = scanTranscriptForReviewer(fs59.readFileSync(transcriptPath, "utf-8"));
25181
25504
  } catch {
25182
25505
  reviewerRan = false;
25183
25506
  }
@@ -25198,7 +25521,7 @@ function main40() {
25198
25521
  })}
25199
25522
  `
25200
25523
  );
25201
- return EXIT_WARN9;
25524
+ return EXIT_WARN10;
25202
25525
  }
25203
25526
  function _isCliEntry31() {
25204
25527
  if (true) {
@@ -25207,29 +25530,29 @@ function _isCliEntry31() {
25207
25530
  if (process.argv[1] === void 0) {
25208
25531
  return false;
25209
25532
  }
25210
- const argvUrl = pathToFileURL35(path58.resolve(process.argv[1])).href;
25533
+ const argvUrl = pathToFileURL36(path60.resolve(process.argv[1])).href;
25211
25534
  if (import.meta.url === argvUrl) {
25212
25535
  return true;
25213
25536
  }
25214
25537
  try {
25215
- const here = fs57.realpathSync(fileURLToPath41(import.meta.url));
25216
- const argv = fs57.realpathSync(path58.resolve(process.argv[1]));
25538
+ const here = fs59.realpathSync(fileURLToPath42(import.meta.url));
25539
+ const argv = fs59.realpathSync(path60.resolve(process.argv[1]));
25217
25540
  return here === argv;
25218
25541
  } catch {
25219
25542
  return false;
25220
25543
  }
25221
25544
  }
25222
25545
  if (_isCliEntry31()) {
25223
- process.exit(main40());
25546
+ process.exit(main41());
25224
25547
  }
25225
25548
 
25226
25549
  // src/scripts/hooks/turn_end_gate_hook.ts
25227
25550
  import * as crypto6 from "node:crypto";
25228
- import * as fs58 from "node:fs";
25229
- import * as path59 from "node:path";
25230
- import { fileURLToPath as fileURLToPath42, pathToFileURL as pathToFileURL36 } from "node:url";
25551
+ import * as fs60 from "node:fs";
25552
+ import * as path61 from "node:path";
25553
+ import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL37 } from "node:url";
25231
25554
  var EXIT_BLOCK4 = 1;
25232
- var EXIT_ALLOW17 = 0;
25555
+ var EXIT_ALLOW18 = 0;
25233
25556
  var TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024;
25234
25557
  function stripFencedBlocks(text) {
25235
25558
  const out = [];
@@ -25333,7 +25656,7 @@ function detectPromissory(reply) {
25333
25656
  }
25334
25657
  function readLanguagePin(workspaceRoot2) {
25335
25658
  try {
25336
- const raw = fs58.readFileSync(path59.join(workspaceRoot2, STATE_FILE5), "utf-8");
25659
+ const raw = fs60.readFileSync(path61.join(workspaceRoot2, STATE_FILE5), "utf-8");
25337
25660
  const decoded = JSON.parse(raw);
25338
25661
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
25339
25662
  const lang = decoded["language"];
@@ -25355,18 +25678,44 @@ function detectLanguage(reply, pinned) {
25355
25678
  reason: `the pinned reply language is "${pinned}" but the reply classifies as "${verdict.language}" (${verdict.de_markers} de / ${verdict.en_markers} en markers; code, quotes, tables, URLs and paths excluded, then scored lead-first by the same classifier that sets the pin)`
25356
25679
  };
25357
25680
  }
25681
+ var _EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
25682
+ var _VERIFY_RE = /\b(test|tests|vitest|jest|pytest|phpunit|pest|tsc|eslint|ruff|mypy|pyright|clippy|typecheck|lint|build|ci|preflight|smoke[-_:a-z]*|check[-_:a-z]*|validate[-_:a-z]*)\b|\b(task|npm|pnpm|yarn|composer|cargo|go|make|php artisan|bun)\s+(run\s+)?\S*(test|check|lint|build|ci|typecheck)/i;
25683
+ function isVerificationCommand(command) {
25684
+ return _VERIFY_RE.test(command);
25685
+ }
25686
+ function detectUnverifiedEdit(toolCalls) {
25687
+ let lastEdit = -1;
25688
+ for (let i = 0; i < toolCalls.length; i += 1) {
25689
+ if (_EDIT_TOOLS.has(toolCalls[i].name)) lastEdit = i;
25690
+ }
25691
+ if (lastEdit === -1) return null;
25692
+ for (let i = lastEdit + 1; i < toolCalls.length; i += 1) {
25693
+ const c = toolCalls[i];
25694
+ if (c.name === "Bash" && c.command !== void 0 && isVerificationCommand(c.command)) {
25695
+ return null;
25696
+ }
25697
+ }
25698
+ const edited = toolCalls[lastEdit].path;
25699
+ return {
25700
+ detector: "verification",
25701
+ // The path, never the diff: the evidence span is quoted into a refusal,
25702
+ // and `ToolCall` is shaped so a file body cannot reach it.
25703
+ evidence: edited ?? toolCalls[lastEdit].name,
25704
+ reason: "this turn changed a file and then ran no verification command \u2014 no test, type-check, lint or build call follows the last edit (verify-before-complete: a claim without a fresh run is unverified)"
25705
+ };
25706
+ }
25358
25707
  function stateDir(workspaceRoot2) {
25359
- return path59.join(workspaceRoot2, "agents", "runtime", "state", "turn-end-gate");
25708
+ return path61.join(workspaceRoot2, "agents", "runtime", "state", "turn-end-gate");
25360
25709
  }
25361
25710
  function sessionStateFile2(workspaceRoot2, sessionKey) {
25362
- return path59.join(stateDir(workspaceRoot2), `${sessionKey}.json`);
25711
+ return path61.join(stateDir(workspaceRoot2), `${sessionKey}.json`);
25363
25712
  }
25364
25713
  function deriveSessionKey2(sessionId2) {
25365
25714
  return crypto6.createHash("sha256").update(sessionId2).digest("hex").slice(0, 32);
25366
25715
  }
25367
25716
  function alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal) {
25368
25717
  try {
25369
- const raw = fs58.readFileSync(sessionStateFile2(workspaceRoot2, sessionKey), "utf-8");
25718
+ const raw = fs60.readFileSync(sessionStateFile2(workspaceRoot2, sessionKey), "utf-8");
25370
25719
  const decoded = JSON.parse(raw);
25371
25720
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
25372
25721
  return decoded["refused_turn"] === turnOrdinal;
@@ -25387,19 +25736,20 @@ function markRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal, detector) {
25387
25736
  }
25388
25737
  }
25389
25738
  function readTranscriptTail(transcriptPath, opts = {}) {
25390
- const empty = { lastAssistant: "", turnOrdinal: 0 };
25739
+ const empty = { lastAssistant: "", turnOrdinal: 0, toolCalls: [] };
25391
25740
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
25392
25741
  let lines;
25393
25742
  try {
25394
- if (opts.maxBytes !== void 0 && fs58.statSync(transcriptPath).size > opts.maxBytes) {
25743
+ if (opts.maxBytes !== void 0 && fs60.statSync(transcriptPath).size > opts.maxBytes) {
25395
25744
  return empty;
25396
25745
  }
25397
- lines = fs58.readFileSync(transcriptPath, "utf-8").split("\n");
25746
+ lines = fs60.readFileSync(transcriptPath, "utf-8").split("\n");
25398
25747
  } catch {
25399
25748
  return empty;
25400
25749
  }
25401
25750
  let lastAssistant = "";
25402
25751
  let turnOrdinal = 0;
25752
+ let toolCalls = [];
25403
25753
  for (const rawLine of lines) {
25404
25754
  const line = rawLine.trim();
25405
25755
  if (!line) continue;
@@ -25416,15 +25766,42 @@ function readTranscriptTail(transcriptPath, opts = {}) {
25416
25766
  if (role !== "assistant" && role !== "user") continue;
25417
25767
  const msg = entry["message"];
25418
25768
  if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
25419
- const text = _messageText(msg["content"]);
25769
+ const content = msg["content"];
25770
+ if (role === "assistant") {
25771
+ toolCalls.push(..._toolCalls(content));
25772
+ }
25773
+ const text = _messageText(content);
25420
25774
  if (text === null) continue;
25421
25775
  if (role === "assistant") {
25422
25776
  lastAssistant = text;
25423
25777
  } else if (!isSyntheticPrompt(text)) {
25424
25778
  turnOrdinal += 1;
25779
+ toolCalls = [];
25425
25780
  }
25426
25781
  }
25427
- return { lastAssistant: lastAssistant.trim(), turnOrdinal };
25782
+ return { lastAssistant: lastAssistant.trim(), turnOrdinal, toolCalls };
25783
+ }
25784
+ function _toolCalls(content) {
25785
+ if (!Array.isArray(content)) return [];
25786
+ const out = [];
25787
+ for (const blk of content) {
25788
+ if (typeof blk !== "object" || blk === null || Array.isArray(blk)) continue;
25789
+ const b = blk;
25790
+ if (b["type"] !== "tool_use") continue;
25791
+ const name = b["name"];
25792
+ if (typeof name !== "string") continue;
25793
+ const input = b["input"];
25794
+ const call = { name };
25795
+ if (typeof input === "object" && input !== null && !Array.isArray(input)) {
25796
+ const inp = input;
25797
+ const cmd = inp["command"];
25798
+ if (typeof cmd === "string") call.command = cmd;
25799
+ const p = inp["file_path"] ?? inp["path"] ?? inp["notebook_path"];
25800
+ if (typeof p === "string") call.path = p;
25801
+ }
25802
+ out.push(call);
25803
+ }
25804
+ return out;
25428
25805
  }
25429
25806
  function _messageText(content) {
25430
25807
  if (typeof content === "string") return content;
@@ -25448,7 +25825,12 @@ function _isOn(v) {
25448
25825
  return null;
25449
25826
  }
25450
25827
  function readGateSettings(workspaceRoot2) {
25451
- const off = { enabled: false, promissory: true, language: true };
25828
+ const off = {
25829
+ enabled: false,
25830
+ promissory: true,
25831
+ language: true,
25832
+ verification: true
25833
+ };
25452
25834
  let settings;
25453
25835
  try {
25454
25836
  settings = load_agent_settings({ cwd: workspaceRoot2 });
@@ -25467,35 +25849,36 @@ function readGateSettings(workspaceRoot2) {
25467
25849
  return {
25468
25850
  enabled: flag("enabled", false),
25469
25851
  promissory: flag("promissory", true),
25470
- language: flag("language", true)
25852
+ language: flag("language", true),
25853
+ verification: flag("verification", true)
25471
25854
  };
25472
25855
  }
25473
25856
  function str4(v) {
25474
25857
  return typeof v === "string" ? v : "";
25475
25858
  }
25476
- function main41() {
25859
+ function main42() {
25477
25860
  let envelope;
25478
25861
  let payload;
25479
25862
  try {
25480
25863
  [envelope, payload] = unwrap(readHookStdin(), "claude");
25481
25864
  } catch {
25482
- return EXIT_ALLOW17;
25865
+ return EXIT_ALLOW18;
25483
25866
  }
25484
- if (payload["stop_hook_active"] === true) return EXIT_ALLOW17;
25867
+ if (payload["stop_hook_active"] === true) return EXIT_ALLOW18;
25485
25868
  const workspaceRoot2 = str4(envelope["workspace_root"]) || process.cwd();
25486
25869
  const settings = readGateSettings(workspaceRoot2);
25487
- if (!settings.enabled) return EXIT_ALLOW17;
25870
+ if (!settings.enabled) return EXIT_ALLOW18;
25488
25871
  const transcriptPath = str4(
25489
25872
  payload["transcript_path"] ?? payload["transcriptPath"]
25490
25873
  );
25491
- const { lastAssistant, turnOrdinal } = readTranscriptTail(transcriptPath, {
25874
+ const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
25492
25875
  maxBytes: TRANSCRIPT_READ_MAX_BYTES
25493
25876
  });
25494
- if (!lastAssistant) return EXIT_ALLOW17;
25877
+ if (!lastAssistant) return EXIT_ALLOW18;
25495
25878
  const sessionKey = deriveSessionKey2(
25496
25879
  str4(envelope["session_id"]) || "unknown-session"
25497
25880
  );
25498
- if (alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal)) return EXIT_ALLOW17;
25881
+ if (alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal)) return EXIT_ALLOW18;
25499
25882
  const findings = [];
25500
25883
  if (settings.promissory) {
25501
25884
  const f = detectPromissory(lastAssistant);
@@ -25505,7 +25888,11 @@ function main41() {
25505
25888
  const f = detectLanguage(lastAssistant, readLanguagePin(workspaceRoot2));
25506
25889
  if (f) findings.push(f);
25507
25890
  }
25508
- if (findings.length === 0) return EXIT_ALLOW17;
25891
+ if (settings.verification) {
25892
+ const f = detectUnverifiedEdit(toolCalls);
25893
+ if (f) findings.push(f);
25894
+ }
25895
+ if (findings.length === 0) return EXIT_ALLOW18;
25509
25896
  markRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal, findings[0].detector);
25510
25897
  const lines = findings.map(
25511
25898
  (f) => ` \xB7 ${f.detector}: ${f.reason}
@@ -25514,7 +25901,7 @@ function main41() {
25514
25901
  process.stderr.write(
25515
25902
  `turn-end-gate: REFUSED \u2014 this turn is not finished.
25516
25903
  ${lines.join("\n")}
25517
- Do the promised work now, or correct the language, then end the turn.
25904
+ Do the promised work now, correct the language, or run the verification the edit needs, then end the turn.
25518
25905
  This turn will not be refused a second time.
25519
25906
  Disable: hooks.turn_end_gate.enabled: false in .agent-settings.yml
25520
25907
  `
@@ -25528,30 +25915,30 @@ function _isCliEntry32() {
25528
25915
  if (process.argv[1] === void 0) {
25529
25916
  return false;
25530
25917
  }
25531
- const argvUrl = pathToFileURL36(path59.resolve(process.argv[1])).href;
25918
+ const argvUrl = pathToFileURL37(path61.resolve(process.argv[1])).href;
25532
25919
  if (import.meta.url === argvUrl) {
25533
25920
  return true;
25534
25921
  }
25535
25922
  try {
25536
- const here = fs58.realpathSync(fileURLToPath42(import.meta.url));
25537
- const argv = fs58.realpathSync(path59.resolve(process.argv[1]));
25923
+ const here = fs60.realpathSync(fileURLToPath43(import.meta.url));
25924
+ const argv = fs60.realpathSync(path61.resolve(process.argv[1]));
25538
25925
  return here === argv;
25539
25926
  } catch {
25540
25927
  return false;
25541
25928
  }
25542
25929
  }
25543
25930
  if (_isCliEntry32()) {
25544
- process.exit(main41());
25931
+ process.exit(main42());
25545
25932
  }
25546
25933
 
25547
25934
  // src/scripts/hooks/edit_shape_hook.ts
25548
25935
  import { spawnSync as spawnSync6 } from "node:child_process";
25549
25936
  import * as crypto7 from "node:crypto";
25550
- import * as fs59 from "node:fs";
25551
- import * as path60 from "node:path";
25552
- import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL37 } from "node:url";
25553
- var EXIT_ALLOW18 = 0;
25554
- var EXIT_WARN10 = 2;
25937
+ import * as fs61 from "node:fs";
25938
+ import * as path62 from "node:path";
25939
+ import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL38 } from "node:url";
25940
+ var EXIT_ALLOW19 = 0;
25941
+ var EXIT_WARN11 = 2;
25555
25942
  var MIN_FILE_LINES = 50;
25556
25943
  var MAX_DIFF_RATIO = 0.2;
25557
25944
  var EXEMPT_PATH_PATTERNS = [
@@ -25566,7 +25953,7 @@ var EXEMPT_PATH_PATTERNS = [
25566
25953
  /(^|\/)agents\/runtime\//i
25567
25954
  // agents/runtime/**
25568
25955
  ];
25569
- function isObject6(v) {
25956
+ function isObject7(v) {
25570
25957
  return typeof v === "object" && v !== null && !Array.isArray(v);
25571
25958
  }
25572
25959
  function str5(v) {
@@ -25602,7 +25989,7 @@ function effectiveDiffLines(cwd, relPath) {
25602
25989
  }
25603
25990
  function fileLineCount(absPath) {
25604
25991
  try {
25605
- const text = fs59.readFileSync(absPath, "utf8");
25992
+ const text = fs61.readFileSync(absPath, "utf8");
25606
25993
  if (text.length === 0) return 0;
25607
25994
  return text.split("\n").length - (text.endsWith("\n") ? 1 : 0);
25608
25995
  } catch {
@@ -25619,11 +26006,11 @@ function deriveSessionKey3(envelope, payload) {
25619
26006
  return crypto7.createHash("sha256").update(material).digest("hex");
25620
26007
  }
25621
26008
  function sessionStateFile3(workspaceRoot2, sessionKey) {
25622
- return path60.join(workspaceRoot2, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
26009
+ return path62.join(workspaceRoot2, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
25623
26010
  }
25624
26011
  function hasFiredThisSession2(workspaceRoot2, sessionKey) {
25625
26012
  try {
25626
- return fs59.existsSync(sessionStateFile3(workspaceRoot2, sessionKey));
26013
+ return fs61.existsSync(sessionStateFile3(workspaceRoot2, sessionKey));
25627
26014
  } catch {
25628
26015
  return false;
25629
26016
  }
@@ -25641,29 +26028,29 @@ function extractToolName2(payload) {
25641
26028
  }
25642
26029
  function extractFilePath(payload) {
25643
26030
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
25644
- if (!isObject6(ti)) return "";
26031
+ if (!isObject7(ti)) return "";
25645
26032
  return str5(ti["file_path"] ?? ti["path"] ?? ti["filePath"]);
25646
26033
  }
25647
- function main42() {
26034
+ function main43() {
25648
26035
  try {
25649
26036
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
25650
26037
  const event = str5(envelope["event"]);
25651
- if (event !== "" && event !== "post_tool_use") return EXIT_ALLOW18;
26038
+ if (event !== "" && event !== "post_tool_use") return EXIT_ALLOW19;
25652
26039
  const toolName = extractToolName2(payload);
25653
- if (toolName !== "Write") return EXIT_ALLOW18;
26040
+ if (toolName !== "Write") return EXIT_ALLOW19;
25654
26041
  const filePath = extractFilePath(payload);
25655
- if (!filePath) return EXIT_ALLOW18;
26042
+ if (!filePath) return EXIT_ALLOW19;
25656
26043
  const workspaceRoot2 = str5(envelope["workspace_root"]).trim() || process.cwd();
25657
- const absPath = path60.isAbsolute(filePath) ? filePath : path60.resolve(workspaceRoot2, filePath);
25658
- const relPath = path60.relative(workspaceRoot2, absPath);
25659
- if (isExemptPath(relPath) || isExemptPath(absPath)) return EXIT_ALLOW18;
26044
+ const absPath = path62.isAbsolute(filePath) ? filePath : path62.resolve(workspaceRoot2, filePath);
26045
+ const relPath = path62.relative(workspaceRoot2, absPath);
26046
+ if (isExemptPath(relPath) || isExemptPath(absPath)) return EXIT_ALLOW19;
25660
26047
  const fileLines = fileLineCount(absPath);
25661
- if (fileLines < MIN_FILE_LINES) return EXIT_ALLOW18;
26048
+ if (fileLines < MIN_FILE_LINES) return EXIT_ALLOW19;
25662
26049
  const diffLines = effectiveDiffLines(workspaceRoot2, relPath.startsWith("..") ? absPath : relPath);
25663
- if (diffLines === 0) return EXIT_ALLOW18;
25664
- if (diffLines / fileLines > MAX_DIFF_RATIO) return EXIT_ALLOW18;
26050
+ if (diffLines === 0) return EXIT_ALLOW19;
26051
+ if (diffLines / fileLines > MAX_DIFF_RATIO) return EXIT_ALLOW19;
25665
26052
  const sessionKey = deriveSessionKey3(envelope, payload);
25666
- if (hasFiredThisSession2(workspaceRoot2, sessionKey)) return EXIT_ALLOW18;
26053
+ if (hasFiredThisSession2(workspaceRoot2, sessionKey)) return EXIT_ALLOW19;
25667
26054
  markFiredThisSession2(workspaceRoot2, sessionKey);
25668
26055
  process.stdout.write(
25669
26056
  `${JSON.stringify({
@@ -25673,9 +26060,9 @@ function main42() {
25673
26060
  })}
25674
26061
  `
25675
26062
  );
25676
- return EXIT_WARN10;
26063
+ return EXIT_WARN11;
25677
26064
  } catch {
25678
- return EXIT_ALLOW18;
26065
+ return EXIT_ALLOW19;
25679
26066
  }
25680
26067
  }
25681
26068
  function _isCliEntry33() {
@@ -25685,29 +26072,29 @@ function _isCliEntry33() {
25685
26072
  if (process.argv[1] === void 0) {
25686
26073
  return false;
25687
26074
  }
25688
- const argvUrl = pathToFileURL37(path60.resolve(process.argv[1])).href;
26075
+ const argvUrl = pathToFileURL38(path62.resolve(process.argv[1])).href;
25689
26076
  if (import.meta.url === argvUrl) {
25690
26077
  return true;
25691
26078
  }
25692
26079
  try {
25693
- const here = fs59.realpathSync(fileURLToPath43(import.meta.url));
25694
- const argv = fs59.realpathSync(path60.resolve(process.argv[1]));
26080
+ const here = fs61.realpathSync(fileURLToPath44(import.meta.url));
26081
+ const argv = fs61.realpathSync(path62.resolve(process.argv[1]));
25695
26082
  return here === argv;
25696
26083
  } catch {
25697
26084
  return false;
25698
26085
  }
25699
26086
  }
25700
26087
  if (_isCliEntry33()) {
25701
- process.exit(main42());
26088
+ process.exit(main43());
25702
26089
  }
25703
26090
 
25704
26091
  // src/scripts/hooks/reread_guard_hook.ts
25705
26092
  import * as crypto8 from "node:crypto";
25706
- import * as fs60 from "node:fs";
25707
- import * as path61 from "node:path";
25708
- import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL38 } from "node:url";
25709
- var EXIT_ALLOW19 = 0;
25710
- var EXIT_WARN11 = 2;
26093
+ import * as fs62 from "node:fs";
26094
+ import * as path63 from "node:path";
26095
+ import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL39 } from "node:url";
26096
+ var EXIT_ALLOW20 = 0;
26097
+ var EXIT_WARN12 = 2;
25711
26098
  var EXEMPT_PATH_PATTERNS2 = [
25712
26099
  /(^|\/)dist\//i,
25713
26100
  // dist/**
@@ -25722,7 +26109,7 @@ var EXEMPT_PATH_PATTERNS2 = [
25722
26109
  ];
25723
26110
  var READ_TOOLS = /* @__PURE__ */ new Set(["Read"]);
25724
26111
  var WRITE_TOOLS2 = /* @__PURE__ */ new Set(["Edit", "Write"]);
25725
- function isObject7(v) {
26112
+ function isObject8(v) {
25726
26113
  return typeof v === "object" && v !== null && !Array.isArray(v);
25727
26114
  }
25728
26115
  function str6(v) {
@@ -25741,16 +26128,16 @@ function deriveSessionKey4(envelope, payload) {
25741
26128
  return crypto8.createHash("sha256").update(material).digest("hex");
25742
26129
  }
25743
26130
  function ledgerFile(workspaceRoot2, sessionKey) {
25744
- return path61.join(workspaceRoot2, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
26131
+ return path63.join(workspaceRoot2, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
25745
26132
  }
25746
26133
  function readLedger(workspaceRoot2, sessionKey) {
25747
26134
  try {
25748
- const parsed = JSON.parse(fs60.readFileSync(ledgerFile(workspaceRoot2, sessionKey), "utf8"));
25749
- if (!isObject7(parsed)) return emptyLedger();
26135
+ const parsed = JSON.parse(fs62.readFileSync(ledgerFile(workspaceRoot2, sessionKey), "utf8"));
26136
+ if (!isObject8(parsed)) return emptyLedger();
25750
26137
  return {
25751
- reads: isObject7(parsed["reads"]) ? parsed["reads"] : {},
25752
- writes: isObject7(parsed["writes"]) ? parsed["writes"] : {},
25753
- fired: isObject7(parsed["fired"]) ? parsed["fired"] : {}
26138
+ reads: isObject8(parsed["reads"]) ? parsed["reads"] : {},
26139
+ writes: isObject8(parsed["writes"]) ? parsed["writes"] : {},
26140
+ fired: isObject8(parsed["fired"]) ? parsed["fired"] : {}
25754
26141
  };
25755
26142
  } catch {
25756
26143
  return emptyLedger();
@@ -25767,7 +26154,7 @@ function extractToolName3(payload) {
25767
26154
  }
25768
26155
  function extractToolInput2(payload) {
25769
26156
  const ti = payload["tool_input"] ?? payload["toolInput"] ?? payload["input"];
25770
- return isObject7(ti) ? ti : {};
26157
+ return isObject8(ti) ? ti : {};
25771
26158
  }
25772
26159
  function extractFilePath2(toolInput) {
25773
26160
  return str6(toolInput["file_path"] ?? toolInput["path"] ?? toolInput["filePath"]);
@@ -25786,41 +26173,41 @@ function buildDuplicateReadLine(relPath, earlierTs) {
25786
26173
  function buildPostEditReadLine(relPath) {
25787
26174
  return `re-read guard: this session just edited ${relPath} \u2014 a full-file re-read re-pays for content you already have; a ranged Read (offset/limit) over the edited hunk is enough to verify the change.`;
25788
26175
  }
25789
- function main43() {
26176
+ function main44() {
25790
26177
  try {
25791
26178
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
25792
26179
  const event = str6(envelope["event"]);
25793
- if (event !== "" && event !== "pre_tool_use") return EXIT_ALLOW19;
26180
+ if (event !== "" && event !== "pre_tool_use") return EXIT_ALLOW20;
25794
26181
  const toolName = extractToolName3(payload);
25795
26182
  const isRead = READ_TOOLS.has(toolName);
25796
26183
  const isWrite = WRITE_TOOLS2.has(toolName);
25797
- if (!isRead && !isWrite) return EXIT_ALLOW19;
26184
+ if (!isRead && !isWrite) return EXIT_ALLOW20;
25798
26185
  const toolInput = extractToolInput2(payload);
25799
26186
  const filePath = extractFilePath2(toolInput);
25800
- if (!filePath) return EXIT_ALLOW19;
26187
+ if (!filePath) return EXIT_ALLOW20;
25801
26188
  const workspaceRoot2 = str6(envelope["workspace_root"]).trim() || process.cwd();
25802
- const absPath = path61.isAbsolute(filePath) ? filePath : path61.resolve(workspaceRoot2, filePath);
25803
- const relPath = path61.relative(workspaceRoot2, absPath);
25804
- if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW19;
26189
+ const absPath = path63.isAbsolute(filePath) ? filePath : path63.resolve(workspaceRoot2, filePath);
26190
+ const relPath = path63.relative(workspaceRoot2, absPath);
26191
+ if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW20;
25805
26192
  const sessionKey = deriveSessionKey4(envelope, payload);
25806
26193
  const ledger = readLedger(workspaceRoot2, sessionKey);
25807
26194
  const key = relPath.startsWith("..") ? absPath : relPath;
25808
26195
  if (isWrite) {
25809
26196
  ledger.writes[key] = Date.now();
25810
26197
  writeLedger(workspaceRoot2, sessionKey, ledger);
25811
- return EXIT_ALLOW19;
26198
+ return EXIT_ALLOW20;
25812
26199
  }
25813
26200
  if (isRangedRead(toolInput)) {
25814
- return EXIT_ALLOW19;
26201
+ return EXIT_ALLOW20;
25815
26202
  }
25816
26203
  let mtime;
25817
26204
  let size;
25818
26205
  try {
25819
- const st = fs60.statSync(absPath);
26206
+ const st = fs62.statSync(absPath);
25820
26207
  mtime = st.mtimeMs;
25821
26208
  size = st.size;
25822
26209
  } catch {
25823
- return EXIT_ALLOW19;
26210
+ return EXIT_ALLOW20;
25824
26211
  }
25825
26212
  const prior = ledger.reads[key];
25826
26213
  const ownWrite = ledger.writes[key];
@@ -25835,7 +26222,7 @@ function main43() {
25835
26222
  if (ownWrite !== void 0) delete ledger.writes[key];
25836
26223
  if (advisory !== null) ledger.fired[key] = true;
25837
26224
  writeLedger(workspaceRoot2, sessionKey, ledger);
25838
- if (advisory === null) return EXIT_ALLOW19;
26225
+ if (advisory === null) return EXIT_ALLOW20;
25839
26226
  process.stdout.write(
25840
26227
  `${JSON.stringify({
25841
26228
  decision: "warn",
@@ -25844,9 +26231,9 @@ function main43() {
25844
26231
  })}
25845
26232
  `
25846
26233
  );
25847
- return EXIT_WARN11;
26234
+ return EXIT_WARN12;
25848
26235
  } catch {
25849
- return EXIT_ALLOW19;
26236
+ return EXIT_ALLOW20;
25850
26237
  }
25851
26238
  }
25852
26239
  function _isCliEntry34() {
@@ -25856,27 +26243,27 @@ function _isCliEntry34() {
25856
26243
  if (process.argv[1] === void 0) {
25857
26244
  return false;
25858
26245
  }
25859
- const argvUrl = pathToFileURL38(path61.resolve(process.argv[1])).href;
26246
+ const argvUrl = pathToFileURL39(path63.resolve(process.argv[1])).href;
25860
26247
  if (import.meta.url === argvUrl) {
25861
26248
  return true;
25862
26249
  }
25863
26250
  try {
25864
- const here = fs60.realpathSync(fileURLToPath44(import.meta.url));
25865
- const argv = fs60.realpathSync(path61.resolve(process.argv[1]));
26251
+ const here = fs62.realpathSync(fileURLToPath45(import.meta.url));
26252
+ const argv = fs62.realpathSync(path63.resolve(process.argv[1]));
25866
26253
  return here === argv;
25867
26254
  } catch {
25868
26255
  return false;
25869
26256
  }
25870
26257
  }
25871
26258
  if (_isCliEntry34()) {
25872
- process.exit(main43());
26259
+ process.exit(main44());
25873
26260
  }
25874
26261
 
25875
26262
  // src/scripts/hooks/session_eol_hook.ts
25876
- import * as fs62 from "node:fs";
25877
- import * as path64 from "node:path";
26263
+ import * as fs64 from "node:fs";
26264
+ import * as path66 from "node:path";
25878
26265
  import process11 from "node:process";
25879
- import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL39 } from "node:url";
26266
+ import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL40 } from "node:url";
25880
26267
 
25881
26268
  // src/config/recycle-threshold-budget.json
25882
26269
  var recycle_threshold_budget_default = {
@@ -25894,13 +26281,13 @@ var recycle_threshold_budget_default = {
25894
26281
 
25895
26282
  // src/scripts/_lib/session_eol.ts
25896
26283
  import * as crypto9 from "node:crypto";
25897
- import * as fs61 from "node:fs";
25898
- import * as path63 from "node:path";
26284
+ import * as fs63 from "node:fs";
26285
+ import * as path65 from "node:path";
25899
26286
 
25900
26287
  // src/scripts/_lib/cc_transcript.ts
25901
- import * as path62 from "node:path";
26288
+ import * as path64 from "node:path";
25902
26289
  import { homedir as homedir6 } from "node:os";
25903
- var DEFAULT_PROJECTS_ROOT = path62.join(homedir6(), ".claude", "projects");
26290
+ var DEFAULT_PROJECTS_ROOT = path64.join(homedir6(), ".claude", "projects");
25904
26291
  function billableInputTokens(u) {
25905
26292
  return u.input_tokens + u.cache_read_input_tokens + u.cache_creation_input_tokens;
25906
26293
  }
@@ -26009,17 +26396,17 @@ function scanEolSlice(text, prior) {
26009
26396
  return next;
26010
26397
  }
26011
26398
  function eolStateDir(workspaceRoot2) {
26012
- return path63.join(workspaceRoot2, "agents", "runtime", "state", "session-eol");
26399
+ return path65.join(workspaceRoot2, "agents", "runtime", "state", "session-eol");
26013
26400
  }
26014
26401
  function eolStateFile(workspaceRoot2, sessionKey) {
26015
- return path63.join(eolStateDir(workspaceRoot2), `${sessionKey}.json`);
26402
+ return path65.join(eolStateDir(workspaceRoot2), `${sessionKey}.json`);
26016
26403
  }
26017
26404
  function eolSessionKey(raw) {
26018
26405
  return crypto9.createHash("sha256").update(raw || "unknown-session").digest("hex");
26019
26406
  }
26020
26407
  function readNewCompleteLines(filePath, fromByte) {
26021
26408
  try {
26022
- const { size } = fs61.statSync(filePath);
26409
+ const { size } = fs63.statSync(filePath);
26023
26410
  if (size < fromByte) {
26024
26411
  return { text: "", nextOffset: 0, truncated: true };
26025
26412
  }
@@ -26028,11 +26415,11 @@ function readNewCompleteLines(filePath, fromByte) {
26028
26415
  }
26029
26416
  const length = size - fromByte;
26030
26417
  const buffer = Buffer.alloc(length);
26031
- const fd = fs61.openSync(filePath, "r");
26418
+ const fd = fs63.openSync(filePath, "r");
26032
26419
  try {
26033
- fs61.readSync(fd, buffer, 0, length, fromByte);
26420
+ fs63.readSync(fd, buffer, 0, length, fromByte);
26034
26421
  } finally {
26035
- fs61.closeSync(fd);
26422
+ fs63.closeSync(fd);
26036
26423
  }
26037
26424
  const lastNewline = buffer.lastIndexOf(10);
26038
26425
  if (lastNewline === -1) {
@@ -26049,21 +26436,21 @@ function readNewCompleteLines(filePath, fromByte) {
26049
26436
  }
26050
26437
 
26051
26438
  // src/scripts/hooks/session_eol_hook.ts
26052
- var EXIT_WARN12 = 2;
26439
+ var EXIT_WARN13 = 2;
26053
26440
  var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
26054
- var CONTEXT_FILL_REL = path64.join("agents", "runtime", "state", "context-fill.json");
26441
+ var CONTEXT_FILL_REL = path66.join("agents", "runtime", "state", "context-fill.json");
26055
26442
  function str7(value) {
26056
26443
  return typeof value === "string" ? value : "";
26057
26444
  }
26058
- var stateFile2 = eolStateFile;
26445
+ var stateFile3 = eolStateFile;
26059
26446
  function deriveSessionKey5(envelope, payload) {
26060
26447
  return eolSessionKey(
26061
26448
  str7(envelope["session_id"]) || str7(payload["transcript_path"] ?? payload["transcriptPath"])
26062
26449
  );
26063
26450
  }
26064
- function readState2(file) {
26451
+ function readState3(file) {
26065
26452
  try {
26066
- const parsed = JSON.parse(fs62.readFileSync(file, "utf-8"));
26453
+ const parsed = JSON.parse(fs64.readFileSync(file, "utf-8"));
26067
26454
  if (parsed && typeof parsed === "object" && parsed.schema_version === 1 && parsed.counters && typeof parsed.counters.scanned_bytes === "number") {
26068
26455
  return {
26069
26456
  schema_version: 1,
@@ -26095,7 +26482,7 @@ function buildAdvisoryLine3(tokens, threshold) {
26095
26482
  }
26096
26483
  function writeContextFill(workspaceRoot2, tokens, threshold, ts) {
26097
26484
  try {
26098
- atomic_write_json(path64.join(workspaceRoot2, CONTEXT_FILL_REL), {
26485
+ atomic_write_json(path66.join(workspaceRoot2, CONTEXT_FILL_REL), {
26099
26486
  schema_version: 1,
26100
26487
  final_context_tokens: tokens,
26101
26488
  recycle_threshold_tokens: threshold,
@@ -26105,7 +26492,7 @@ function writeContextFill(workspaceRoot2, tokens, threshold, ts) {
26105
26492
  } catch {
26106
26493
  }
26107
26494
  }
26108
- function main44() {
26495
+ function main45() {
26109
26496
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
26110
26497
  const event = String(envelope["event"] ?? "");
26111
26498
  if (event !== "" && event !== "stop") {
@@ -26122,8 +26509,8 @@ function main44() {
26122
26509
  return 0;
26123
26510
  }
26124
26511
  const sessionKey = deriveSessionKey5(envelope, payload);
26125
- const file = stateFile2(workspaceRoot2, sessionKey);
26126
- const state = readState2(file);
26512
+ const file = stateFile3(workspaceRoot2, sessionKey);
26513
+ const state = readState3(file);
26127
26514
  let counters = state.counters;
26128
26515
  const read = readNewCompleteLines(transcriptPath, counters.scanned_bytes);
26129
26516
  if (read.truncated) {
@@ -26160,7 +26547,7 @@ function main44() {
26160
26547
  })}
26161
26548
  `
26162
26549
  );
26163
- return EXIT_WARN12;
26550
+ return EXIT_WARN13;
26164
26551
  }
26165
26552
  return 0;
26166
26553
  }
@@ -26171,20 +26558,20 @@ function _isCliEntry35() {
26171
26558
  if (process11.argv[1] === void 0) {
26172
26559
  return false;
26173
26560
  }
26174
- const argvUrl = pathToFileURL39(path64.resolve(process11.argv[1])).href;
26561
+ const argvUrl = pathToFileURL40(path66.resolve(process11.argv[1])).href;
26175
26562
  if (import.meta.url === argvUrl) {
26176
26563
  return true;
26177
26564
  }
26178
26565
  try {
26179
- const here = fs62.realpathSync(fileURLToPath45(import.meta.url));
26180
- const argv = fs62.realpathSync(path64.resolve(process11.argv[1]));
26566
+ const here = fs64.realpathSync(fileURLToPath46(import.meta.url));
26567
+ const argv = fs64.realpathSync(path66.resolve(process11.argv[1]));
26181
26568
  return here === argv;
26182
26569
  } catch {
26183
26570
  return false;
26184
26571
  }
26185
26572
  }
26186
26573
  if (_isCliEntry35()) {
26187
- process11.exit(main44());
26574
+ process11.exit(main45());
26188
26575
  }
26189
26576
 
26190
26577
  // src/scripts/hooks/concern_registry.ts
@@ -26219,13 +26606,14 @@ var CONCERN_REGISTRY = {
26219
26606
  "src/scripts/hooks/rtk_wrap_hook.ts": main33,
26220
26607
  "src/scripts/hooks/design_slop_hook.ts": main35,
26221
26608
  "src/scripts/hooks/code_graph_nudge_hook.ts": main36,
26222
- "src/scripts/hooks/orchestration_record_hook.ts": main38,
26223
- "src/scripts/hooks/delegation_nudge_hook.ts": main39,
26224
- "src/scripts/hooks/end_review_nudge_hook.ts": main40,
26225
- "src/scripts/hooks/turn_end_gate_hook.ts": main41,
26226
- "src/scripts/hooks/edit_shape_hook.ts": main42,
26227
- "src/scripts/hooks/reread_guard_hook.ts": main43,
26228
- "src/scripts/hooks/session_eol_hook.ts": main44
26609
+ "src/scripts/hooks/ui_route_nudge_hook.ts": main37,
26610
+ "src/scripts/hooks/orchestration_record_hook.ts": main39,
26611
+ "src/scripts/hooks/delegation_nudge_hook.ts": main40,
26612
+ "src/scripts/hooks/end_review_nudge_hook.ts": main41,
26613
+ "src/scripts/hooks/turn_end_gate_hook.ts": main42,
26614
+ "src/scripts/hooks/edit_shape_hook.ts": main43,
26615
+ "src/scripts/hooks/reread_guard_hook.ts": main44,
26616
+ "src/scripts/hooks/session_eol_hook.ts": main45
26229
26617
  };
26230
26618
 
26231
26619
  // src/scripts/hooks/host_semantics.ts
@@ -26279,14 +26667,14 @@ function emitFor(platform, event, severity, reasons, legacyExit) {
26279
26667
 
26280
26668
  // src/scripts/hooks/dispatch_hook.ts
26281
26669
  var _IN_BUNDLE = true;
26282
- var REPO_ROOT = path65.resolve(
26283
- path65.dirname(fileURLToPath46(import.meta.url)),
26670
+ var REPO_ROOT = path67.resolve(
26671
+ path67.dirname(fileURLToPath47(import.meta.url)),
26284
26672
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
26285
26673
  );
26286
- var MANIFEST_PATH = path65.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
26287
- var EXIT_ALLOW20 = 0;
26674
+ var MANIFEST_PATH = path67.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
26675
+ var EXIT_ALLOW21 = 0;
26288
26676
  var EXIT_BLOCK5 = 1;
26289
- var EXIT_WARN13 = 2;
26677
+ var EXIT_WARN14 = 2;
26290
26678
  var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
26291
26679
  "session_start",
26292
26680
  "session_end",
@@ -26298,9 +26686,9 @@ var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
26298
26686
  "agent_error"
26299
26687
  ]);
26300
26688
  var _SEVERITY_BY_EXIT = {
26301
- [EXIT_ALLOW20]: "allow",
26689
+ [EXIT_ALLOW21]: "allow",
26302
26690
  [EXIT_BLOCK5]: "block",
26303
- [EXIT_WARN13]: "warn"
26691
+ [EXIT_WARN14]: "warn"
26304
26692
  };
26305
26693
  function _isObject14(v) {
26306
26694
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -26335,7 +26723,7 @@ function _parse_concern_stdout(stdout_text) {
26335
26723
  return _isObject14(parsed) ? parsed : { _raw: parsed };
26336
26724
  }
26337
26725
  function _load_yaml3(p) {
26338
- const text = fs63.readFileSync(p, "utf-8");
26726
+ const text = fs65.readFileSync(p, "utf-8");
26339
26727
  const data = (0, import_yaml6.parse)(text, { version: "1.1" });
26340
26728
  return _isObject14(data) ? data : {};
26341
26729
  }
@@ -26492,7 +26880,7 @@ function _maybe_capture_payload(args, payload_text) {
26492
26880
  }
26493
26881
  try {
26494
26882
  const target = _expanduser3(capture_dir);
26495
- fs63.mkdirSync(target, { recursive: true });
26883
+ fs65.mkdirSync(target, { recursive: true });
26496
26884
  let payload;
26497
26885
  try {
26498
26886
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
@@ -26509,8 +26897,8 @@ function _maybe_capture_payload(args, payload_text) {
26509
26897
  const ts = Date.now();
26510
26898
  const native = (args.native_event || args.event).replace(/\//g, "_");
26511
26899
  const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
26512
- fs63.writeFileSync(
26513
- path65.join(target, fname),
26900
+ fs65.writeFileSync(
26901
+ path67.join(target, fname),
26514
26902
  _py_json_dumps2(record, 2) + "\n",
26515
26903
  { encoding: "utf-8" }
26516
26904
  );
@@ -26521,7 +26909,7 @@ function _maybe_capture_payload(args, payload_text) {
26521
26909
  function _expanduser3(p) {
26522
26910
  if (p === "~" || p.startsWith("~/")) {
26523
26911
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
26524
- return path65.join(home, p.slice(1));
26912
+ return path67.join(home, p.slice(1));
26525
26913
  }
26526
26914
  return p;
26527
26915
  }
@@ -26553,25 +26941,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
26553
26941
  const walkUp = (start) => {
26554
26942
  let dir = start;
26555
26943
  for (; ; ) {
26556
- const candidate = path65.join(dir, "node_modules", ".bin", binName);
26944
+ const candidate = path67.join(dir, "node_modules", ".bin", binName);
26557
26945
  if (_isFile7(candidate)) {
26558
26946
  return candidate;
26559
26947
  }
26560
- const parent = path65.dirname(dir);
26948
+ const parent = path67.dirname(dir);
26561
26949
  if (parent === dir) {
26562
26950
  return null;
26563
26951
  }
26564
26952
  dir = parent;
26565
26953
  }
26566
26954
  };
26567
- const tsx = walkUp(path65.dirname(scriptPath)) ?? walkUp(path65.dirname(fileURLToPath46(import.meta.url)));
26955
+ const tsx = walkUp(path67.dirname(scriptPath)) ?? walkUp(path67.dirname(fileURLToPath47(import.meta.url)));
26568
26956
  if (tsx !== null) {
26569
26957
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
26570
26958
  }
26571
26959
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
26572
26960
  }
26573
26961
  function _run_concern_inproc(main_fn, concern, envelope) {
26574
- const scriptAbs = path65.join(REPO_ROOT, String(concern["script"]));
26962
+ const scriptAbs = path67.join(REPO_ROOT, String(concern["script"]));
26575
26963
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
26576
26964
  argsList.push("--platform", String(envelope["platform"] || "generic"));
26577
26965
  const workspace = String(envelope["workspace_root"] || process.cwd());
@@ -26648,7 +27036,7 @@ function _run_concern(concern, envelope) {
26648
27036
  return _run_concern_inproc(inproc, concern, envelope);
26649
27037
  }
26650
27038
  }
26651
- const script = path65.join(REPO_ROOT, String(concern["script"]));
27039
+ const script = path67.join(REPO_ROOT, String(concern["script"]));
26652
27040
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
26653
27041
  const cmd = [script, ...argsList];
26654
27042
  cmd.push("--platform", String(envelope["platform"] || "generic"));
@@ -26705,7 +27093,7 @@ function _run_concern(concern, envelope) {
26705
27093
  }
26706
27094
  function _isFile7(p) {
26707
27095
  try {
26708
- return fs63.statSync(p).isFile();
27096
+ return fs65.statSync(p).isFile();
26709
27097
  } catch {
26710
27098
  return false;
26711
27099
  }
@@ -26717,20 +27105,20 @@ function _reduce(rcs) {
26717
27105
  if (rcs.some((rc) => rc === EXIT_BLOCK5)) {
26718
27106
  return EXIT_BLOCK5;
26719
27107
  }
26720
- if (rcs.some((rc) => rc === EXIT_WARN13)) {
26721
- return EXIT_WARN13;
27108
+ if (rcs.some((rc) => rc === EXIT_WARN14)) {
27109
+ return EXIT_WARN14;
26722
27110
  }
26723
- return EXIT_ALLOW20;
27111
+ return EXIT_ALLOW21;
26724
27112
  }
26725
27113
  function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
26726
27114
  if (is_replay_mode()) {
26727
27115
  return;
26728
27116
  }
26729
27117
  const workspace = String(envelope["workspace_root"] || process.cwd());
26730
- const state_root = path65.join(workspace, "agents", "runtime", "state");
27118
+ const state_root = path67.join(workspace, "agents", "runtime", "state");
26731
27119
  const fb_dir = feedback_dir(state_root, session_id);
26732
27120
  try {
26733
- fs63.mkdirSync(fb_dir, { recursive: true });
27121
+ fs65.mkdirSync(fb_dir, { recursive: true });
26734
27122
  } catch (exc) {
26735
27123
  const msg = exc instanceof Error ? exc.message : String(exc);
26736
27124
  process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
@@ -26738,7 +27126,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
26738
27126
  return;
26739
27127
  }
26740
27128
  for (const entry of entries) {
26741
- const target = path65.join(fb_dir, `${entry["concern"]}.json`);
27129
+ const target = path67.join(fb_dir, `${entry["concern"]}.json`);
26742
27130
  try {
26743
27131
  atomic_write_json(target, entry);
26744
27132
  } catch (exc) {
@@ -26778,7 +27166,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
26778
27166
  })
26779
27167
  };
26780
27168
  try {
26781
- atomic_write_json(path65.join(fb_dir, "summary.json"), summary);
27169
+ atomic_write_json(path67.join(fb_dir, "summary.json"), summary);
26782
27170
  } catch (exc) {
26783
27171
  const msg = exc instanceof Error ? exc.message : String(exc);
26784
27172
  process.stderr.write(`dispatch_hook: summary write failed: ${msg}
@@ -26788,17 +27176,17 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
26788
27176
  function _record_rule_trips(envelope, entries) {
26789
27177
  if (is_replay_mode()) return;
26790
27178
  const tripped = entries.filter(
26791
- (e) => e["exit_code"] === EXIT_BLOCK5 || e["exit_code"] === EXIT_WARN13
27179
+ (e) => e["exit_code"] === EXIT_BLOCK5 || e["exit_code"] === EXIT_WARN14
26792
27180
  );
26793
27181
  if (tripped.length === 0) return;
26794
27182
  try {
26795
27183
  const workspace = String(envelope["workspace_root"] || process.cwd());
26796
- const state_dir = path65.join(workspace, "agents", "runtime", "state");
26797
- const target = path65.join(state_dir, "rule-trips.json");
26798
- fs63.mkdirSync(state_dir, { recursive: true });
27184
+ const state_dir = path67.join(workspace, "agents", "runtime", "state");
27185
+ const target = path67.join(state_dir, "rule-trips.json");
27186
+ fs65.mkdirSync(state_dir, { recursive: true });
26799
27187
  let doc = { schema_version: 1, concerns: {} };
26800
27188
  try {
26801
- const parsed = JSON.parse(fs63.readFileSync(target, "utf-8"));
27189
+ const parsed = JSON.parse(fs65.readFileSync(target, "utf-8"));
26802
27190
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) doc = parsed;
26803
27191
  } catch {
26804
27192
  }
@@ -26809,7 +27197,7 @@ function _record_rule_trips(envelope, entries) {
26809
27197
  const prev = concerns[name] ?? { block: 0, warn: 0 };
26810
27198
  concerns[name] = {
26811
27199
  block: (Number(prev["block"]) || 0) + (e["exit_code"] === EXIT_BLOCK5 ? 1 : 0),
26812
- warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN13 ? 1 : 0),
27200
+ warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN14 ? 1 : 0),
26813
27201
  last_trip: today
26814
27202
  };
26815
27203
  }
@@ -26897,7 +27285,7 @@ function _parse_args(argv) {
26897
27285
  }
26898
27286
  return args;
26899
27287
  }
26900
- function main45(argv) {
27288
+ function main46(argv) {
26901
27289
  const args = _parse_args(argv ?? process.argv.slice(2));
26902
27290
  if (args.project_dir) {
26903
27291
  const project_dir = _expanduser3(args.project_dir);
@@ -26915,13 +27303,13 @@ function main45(argv) {
26915
27303
  `dispatch_hook: unknown event '${args.event}'; allowed: ${_sortedRepr(EVENT_VOCABULARY)}
26916
27304
  `
26917
27305
  );
26918
- return EXIT_ALLOW20;
27306
+ return EXIT_ALLOW21;
26919
27307
  }
26920
27308
  const manifest_path = args.manifest;
26921
- if (!fs63.existsSync(manifest_path)) {
27309
+ if (!fs65.existsSync(manifest_path)) {
26922
27310
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
26923
27311
  `);
26924
- return EXIT_ALLOW20;
27312
+ return EXIT_ALLOW21;
26925
27313
  }
26926
27314
  const manifest = _load_yaml3(manifest_path);
26927
27315
  if (args.min_version) {
@@ -26945,10 +27333,10 @@ function main45(argv) {
26945
27333
  concerns: concerns.map((c) => c["name"])
26946
27334
  };
26947
27335
  process.stdout.write(_py_json_dumps2(plan, 2) + "\n");
26948
- return EXIT_ALLOW20;
27336
+ return EXIT_ALLOW21;
26949
27337
  }
26950
27338
  if (concerns.length === 0) {
26951
- return EXIT_ALLOW20;
27339
+ return EXIT_ALLOW21;
26952
27340
  }
26953
27341
  const envelope = _build_envelope(args, payload_text);
26954
27342
  const session_id = _resolve_session_id(envelope);
@@ -26968,7 +27356,7 @@ function main45(argv) {
26968
27356
  const raw_rc = rc;
26969
27357
  if (rc >= 3) {
26970
27358
  if (!concern["fail_closed"]) {
26971
- rc = EXIT_ALLOW20;
27359
+ rc = EXIT_ALLOW21;
26972
27360
  } else {
26973
27361
  rc = EXIT_BLOCK5;
26974
27362
  }
@@ -26981,7 +27369,7 @@ function main45(argv) {
26981
27369
  `dispatch_hook: concern '${String(concern["name"])}' is declared severity: advisory but returned BLOCK \u2014 downgraded to warn.
26982
27370
  `
26983
27371
  );
26984
- rc = EXIT_WARN13;
27372
+ rc = EXIT_WARN14;
26985
27373
  }
26986
27374
  rcs.push(rc);
26987
27375
  const reply = _parse_concern_stdout(stdout_text);
@@ -26991,7 +27379,7 @@ function main45(argv) {
26991
27379
  if (message) {
26992
27380
  concern_messages.push({ rc, text: message });
26993
27381
  }
26994
- if (args.event === "session_start" && rc === EXIT_ALLOW20 && typeof reply["context"] === "string" && reply["context"].trim()) {
27382
+ if (args.event === "session_start" && rc === EXIT_ALLOW21 && typeof reply["context"] === "string" && reply["context"].trim()) {
26995
27383
  context_blocks.push(reply["context"].trim());
26996
27384
  }
26997
27385
  feedback_entries.push({
@@ -27010,7 +27398,7 @@ function main45(argv) {
27010
27398
  const final_rc = _reduce(rcs);
27011
27399
  _write_feedback(envelope, session_id, feedback_entries, final_rc, started_at);
27012
27400
  _record_rule_trips(envelope, feedback_entries);
27013
- if (context_blocks.length > 0 && final_rc === EXIT_ALLOW20) {
27401
+ if (context_blocks.length > 0 && final_rc === EXIT_ALLOW21) {
27014
27402
  process.stdout.write(context_blocks.join("\n\n") + "\n");
27015
27403
  }
27016
27404
  const decidingReasons = concern_messages.filter((m) => m.rc === final_rc).map((m) => m.text);
@@ -27031,7 +27419,7 @@ function main45(argv) {
27031
27419
  }
27032
27420
  function _isDir4(p) {
27033
27421
  try {
27034
- return fs63.statSync(p).isDirectory();
27422
+ return fs65.statSync(p).isDirectory();
27035
27423
  } catch {
27036
27424
  return false;
27037
27425
  }
@@ -27042,7 +27430,7 @@ function _sortedRepr(s) {
27042
27430
  }
27043
27431
  function _readStdin14() {
27044
27432
  try {
27045
- return fs63.readFileSync(0, "utf-8");
27433
+ return fs65.readFileSync(0, "utf-8");
27046
27434
  } catch {
27047
27435
  return "";
27048
27436
  }
@@ -27054,29 +27442,29 @@ function _isCliEntry36() {
27054
27442
  if (process.argv[1] === void 0) {
27055
27443
  return false;
27056
27444
  }
27057
- const argvUrl = pathToFileURL40(path65.resolve(process.argv[1])).href;
27445
+ const argvUrl = pathToFileURL41(path67.resolve(process.argv[1])).href;
27058
27446
  if (import.meta.url === argvUrl) {
27059
27447
  return true;
27060
27448
  }
27061
27449
  try {
27062
- const here = fs63.realpathSync(fileURLToPath46(import.meta.url));
27063
- const argv = fs63.realpathSync(path65.resolve(process.argv[1]));
27450
+ const here = fs65.realpathSync(fileURLToPath47(import.meta.url));
27451
+ const argv = fs65.realpathSync(path67.resolve(process.argv[1]));
27064
27452
  return here === argv;
27065
27453
  } catch {
27066
27454
  return false;
27067
27455
  }
27068
27456
  }
27069
- var isCliEntry12 = _isCliEntry36();
27070
- if (isCliEntry12) {
27071
- process.exit(main45(process.argv.slice(2)));
27457
+ var isCliEntry13 = _isCliEntry36();
27458
+ if (isCliEntry13) {
27459
+ process.exit(main46(process.argv.slice(2)));
27072
27460
  }
27073
27461
 
27074
27462
  // src/scripts/hooks/dispatch_entry.ts
27075
- var _selfPath = fileURLToPath47(import.meta.url);
27076
- var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path66.resolve(process.argv[1]) === path66.resolve(_selfPath);
27463
+ var _selfPath = fileURLToPath48(import.meta.url);
27464
+ var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path68.resolve(process.argv[1]) === path68.resolve(_selfPath);
27077
27465
  if (_invokedDirectly2) {
27078
- process.exitCode = main45(process.argv.slice(2));
27466
+ process.exitCode = main46(process.argv.slice(2));
27079
27467
  }
27080
27468
  export {
27081
- main45 as main
27469
+ main46 as main
27082
27470
  };