@event4u/agent-config 12.1.0 → 13.0.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 (105) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +151 -0
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/cost/report.md +23 -0
  5. package/dist/agent-src/contexts/execution/subagent-routing.md +148 -33
  6. package/dist/agent-src/contexts/subagent-configuration.md +69 -7
  7. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  8. package/dist/agent-src/rules/design-fidelity.md +1 -1
  9. package/dist/agent-src/rules/design-review-after-ui-write.md +10 -5
  10. package/dist/agent-src/rules/evaluator-independence.md +27 -5
  11. package/dist/agent-src/rules/git-history-discipline.md +5 -1
  12. package/dist/agent-src/rules/missing-skill-recovery.md +89 -0
  13. package/dist/agent-src/rules/ui-audit-gate.md +9 -4
  14. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
  15. package/dist/agent-src/scripts/update_roadmap_progress.ts +17 -2
  16. package/dist/agent-src/skills/authz-review/SKILL.md +4 -0
  17. package/dist/agent-src/skills/design-system-capture/SKILL.md +4 -0
  18. package/dist/agent-src/skills/design-system-capture/references/snapshot-preference-order.md +77 -0
  19. package/dist/agent-src/skills/merge-conflicts/SKILL.md +4 -0
  20. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +17 -1
  21. package/dist/agent-src/skills/roadmap-writing/SKILL.md +4 -4
  22. package/dist/agent-src/skills/systematic-debugging/SKILL.md +4 -0
  23. package/dist/agent-src/skills/threat-modeling/SKILL.md +3 -0
  24. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  25. package/dist/cli-delegate/{chunk-O52B4F5S.js → chunk-3B72LSZL.js} +1 -1
  26. package/dist/cli-delegate/{chunk-55WZN5VF.js → chunk-EVTY7ISR.js} +2 -2
  27. package/dist/cli-delegate/{chunk-K34QTSD5.js → chunk-N7FEST6D.js} +17 -17
  28. package/dist/cli-delegate/{chunk-LKZ5DOYW.js → chunk-XURJ4AQC.js} +11 -3
  29. package/dist/cli-delegate/cmd_conformance.js +2 -2
  30. package/dist/cli-delegate/cmd_doctor.js +2 -2
  31. package/dist/cli-delegate/cmd_export.js +2 -2
  32. package/dist/cli-delegate/cmd_handoff.js +1 -1
  33. package/dist/cli-delegate/cmd_prune.js +2 -2
  34. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  35. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  36. package/dist/cli-delegate/cmd_sync.js +2 -2
  37. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  38. package/dist/cli-delegate/cmd_validate.js +2 -2
  39. package/dist/discovery/deprecation-report.md +1 -1
  40. package/dist/discovery/discovery-manifest.json +43 -22
  41. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  42. package/dist/discovery/discovery-manifest.summary.md +3 -3
  43. package/dist/discovery/dormancy-report.md +1 -1
  44. package/dist/discovery/orphan-report.md +1 -1
  45. package/dist/discovery/packs.json +6 -5
  46. package/dist/discovery/trust-report.md +2 -2
  47. package/dist/discovery/workspaces.json +5 -4
  48. package/dist/hooks/dispatch.js +936 -346
  49. package/dist/install/install.mjs +12 -4
  50. package/dist/mcp/registry-manifest.json +3 -3
  51. package/dist/mcp/server.json +2 -2
  52. package/dist/mcp/server.mjs +1192 -160
  53. package/dist/router.json +1 -1
  54. package/dist/server/schemas/settings.js +2 -2
  55. package/dist/server/schemas/settings.js.map +1 -1
  56. package/docs/guidelines/design-fidelity-mechanics.md +21 -0
  57. package/docs/guidelines/design-handover-extraction.md +87 -0
  58. package/docs/guidelines/prompt-templates.md +24 -1
  59. package/package.json +1 -1
  60. package/src/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
  61. package/src/agent-src/scripts/update_roadmap_progress.ts +17 -2
  62. package/src/config/evaluator-budgets.json +5 -4
  63. package/src/config/gate-coverage.yml +33 -11
  64. package/src/config/gate-violation-baselines.json +9 -3
  65. package/src/config/hook-token-budget.json +8 -1
  66. package/src/scripts/_lib/bench_ab_complexity.ts +439 -0
  67. package/src/scripts/_lib/bench_ab_safety_tier.ts +142 -0
  68. package/src/scripts/_lib/bench_ab_scoring_v2.ts +28 -3
  69. package/src/scripts/_lib/bench_ab_search_adherence.ts +423 -0
  70. package/src/scripts/_lib/bench_ab_size_claim.ts +206 -0
  71. package/src/scripts/_lib/bench_ab_workspace.ts +111 -0
  72. package/src/scripts/_lib/skill_catalogue.ts +258 -5
  73. package/src/scripts/_lib/tier_budget_routing.ts +31 -331
  74. package/src/scripts/ai_council/clients.ts +21 -21
  75. package/src/scripts/bench_ab_v2_complexity.ts +252 -0
  76. package/src/scripts/bench_ab_v2_run.ts +3 -42
  77. package/src/scripts/bench_ab_v2_safety.ts +296 -0
  78. package/src/scripts/bench_ab_v2_search.ts +343 -0
  79. package/src/scripts/bench_ab_v2_stats.ts +191 -0
  80. package/src/scripts/build_archive_index.ts +383 -0
  81. package/src/scripts/capture_skill_catalogue.ts +107 -2
  82. package/src/scripts/check_source_size_budget.ts +428 -0
  83. package/src/scripts/check_suppression_hygiene.ts +5 -1
  84. package/src/scripts/cost/backfill_rates.mjs +298 -0
  85. package/src/scripts/cost/budget.mjs +12 -32
  86. package/src/scripts/cost_summary.ts +25 -0
  87. package/src/scripts/external_sources_denylist.json +1 -0
  88. package/src/scripts/hook_manifest.yaml +28 -2
  89. package/src/scripts/hooks/concern_registry.ts +2 -0
  90. package/src/scripts/hooks/skill_route_hook.ts +226 -0
  91. package/src/scripts/hooks/ui_route_nudge_hook.ts +6 -3
  92. package/src/scripts/lint_design_antipattern_parity.ts +40 -6
  93. package/src/scripts/lint_harvest_provenance.ts +35 -1
  94. package/src/scripts/lint_rule_skill_pack_reach.ts +43 -0
  95. package/src/scripts/lint_skill_router_head.ts +21 -0
  96. package/src/scripts/mcp_server/consumer_tool_catalog.json +26 -3
  97. package/src/scripts/mcp_server/tool_catalog_source.ts +6 -24
  98. package/src/scripts/mcp_server/tools.ts +87 -0
  99. package/src/scripts/release.ts +5 -5
  100. package/src/scripts/routing_doctor.ts +50 -13
  101. package/src/scripts/schemas/command.schema.json +1 -1
  102. package/src/scripts/schemas/skill.schema.json +18 -1
  103. package/src/scripts/trigger_coverage.ts +224 -3
  104. package/src/server/schemas/settings.ts +2 -2
  105. package/src/config/budget-routing.json +0 -7
@@ -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, path74) {
116
- const ctrl = callVisitor(key, node, visitor, path74);
115
+ function visit_(key, node, visitor, path77) {
116
+ const ctrl = callVisitor(key, node, visitor, path77);
117
117
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
118
- replaceNode(key, path74, ctrl);
119
- return visit_(key, ctrl, visitor, path74);
118
+ replaceNode(key, path77, ctrl);
119
+ return visit_(key, ctrl, visitor, path77);
120
120
  }
121
121
  if (typeof ctrl !== "symbol") {
122
122
  if (identity.isCollection(node)) {
123
- path74 = Object.freeze(path74.concat(node));
123
+ path77 = Object.freeze(path77.concat(node));
124
124
  for (let i = 0; i < node.items.length; ++i) {
125
- const ci = visit_(i, node.items[i], visitor, path74);
125
+ const ci = visit_(i, node.items[i], visitor, path77);
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
- path74 = Object.freeze(path74.concat(node));
137
- const ck = visit_("key", node.key, visitor, path74);
136
+ path77 = Object.freeze(path77.concat(node));
137
+ const ck = visit_("key", node.key, visitor, path77);
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, path74);
142
+ const cv = visit_("value", node.value, visitor, path77);
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, path74) {
164
- const ctrl = await callVisitor(key, node, visitor, path74);
163
+ async function visitAsync_(key, node, visitor, path77) {
164
+ const ctrl = await callVisitor(key, node, visitor, path77);
165
165
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
166
- replaceNode(key, path74, ctrl);
167
- return visitAsync_(key, ctrl, visitor, path74);
166
+ replaceNode(key, path77, ctrl);
167
+ return visitAsync_(key, ctrl, visitor, path77);
168
168
  }
169
169
  if (typeof ctrl !== "symbol") {
170
170
  if (identity.isCollection(node)) {
171
- path74 = Object.freeze(path74.concat(node));
171
+ path77 = Object.freeze(path77.concat(node));
172
172
  for (let i = 0; i < node.items.length; ++i) {
173
- const ci = await visitAsync_(i, node.items[i], visitor, path74);
173
+ const ci = await visitAsync_(i, node.items[i], visitor, path77);
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
- path74 = Object.freeze(path74.concat(node));
185
- const ck = await visitAsync_("key", node.key, visitor, path74);
184
+ path77 = Object.freeze(path77.concat(node));
185
+ const ck = await visitAsync_("key", node.key, visitor, path77);
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, path74);
190
+ const cv = await visitAsync_("value", node.value, visitor, path77);
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, path74) {
217
+ function callVisitor(key, node, visitor, path77) {
218
218
  if (typeof visitor === "function")
219
- return visitor(key, node, path74);
219
+ return visitor(key, node, path77);
220
220
  if (identity.isMap(node))
221
- return visitor.Map?.(key, node, path74);
221
+ return visitor.Map?.(key, node, path77);
222
222
  if (identity.isSeq(node))
223
- return visitor.Seq?.(key, node, path74);
223
+ return visitor.Seq?.(key, node, path77);
224
224
  if (identity.isPair(node))
225
- return visitor.Pair?.(key, node, path74);
225
+ return visitor.Pair?.(key, node, path77);
226
226
  if (identity.isScalar(node))
227
- return visitor.Scalar?.(key, node, path74);
227
+ return visitor.Scalar?.(key, node, path77);
228
228
  if (identity.isAlias(node))
229
- return visitor.Alias?.(key, node, path74);
229
+ return visitor.Alias?.(key, node, path77);
230
230
  return void 0;
231
231
  }
232
- function replaceNode(key, path74, node) {
233
- const parent = path74[path74.length - 1];
232
+ function replaceNode(key, path77, node) {
233
+ const parent = path77[path77.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, path74, value) {
843
+ function collectionFromPath(schema, path77, value) {
844
844
  let v = value;
845
- for (let i = path74.length - 1; i >= 0; --i) {
846
- const k = path74[i];
845
+ for (let i = path77.length - 1; i >= 0; --i) {
846
+ const k = path77[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 = (path74) => path74 == null || typeof path74 === "object" && !!path74[Symbol.iterator]().next().done;
865
+ var isEmptyPath = (path77) => path77 == null || typeof path77 === "object" && !!path77[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(path74, value) {
896
- if (isEmptyPath(path74))
895
+ addIn(path77, value) {
896
+ if (isEmptyPath(path77))
897
897
  this.add(value);
898
898
  else {
899
- const [key, ...rest] = path74;
899
+ const [key, ...rest] = path77;
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(path74) {
914
- const [key, ...rest] = path74;
913
+ deleteIn(path77) {
914
+ const [key, ...rest] = path77;
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(path74, keepScalar) {
929
- const [key, ...rest] = path74;
928
+ getIn(path77, keepScalar) {
929
+ const [key, ...rest] = path77;
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(path74) {
948
- const [key, ...rest] = path74;
947
+ hasIn(path77) {
948
+ const [key, ...rest] = path77;
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(path74, value) {
959
- const [key, ...rest] = path74;
958
+ setIn(path77, value) {
959
+ const [key, ...rest] = path77;
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(path74, value) {
3474
+ addIn(path77, value) {
3475
3475
  if (assertCollection(this.contents))
3476
- this.contents.addIn(path74, value);
3476
+ this.contents.addIn(path77, 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(path74) {
3552
- if (Collection.isEmptyPath(path74)) {
3551
+ deleteIn(path77) {
3552
+ if (Collection.isEmptyPath(path77)) {
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(path74) : false;
3558
+ return assertCollection(this.contents) ? this.contents.deleteIn(path77) : 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(path74, keepScalar) {
3574
- if (Collection.isEmptyPath(path74))
3573
+ getIn(path77, keepScalar) {
3574
+ if (Collection.isEmptyPath(path77))
3575
3575
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3576
- return identity.isCollection(this.contents) ? this.contents.getIn(path74, keepScalar) : void 0;
3576
+ return identity.isCollection(this.contents) ? this.contents.getIn(path77, 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(path74) {
3588
- if (Collection.isEmptyPath(path74))
3587
+ hasIn(path77) {
3588
+ if (Collection.isEmptyPath(path77))
3589
3589
  return this.contents !== void 0;
3590
- return identity.isCollection(this.contents) ? this.contents.hasIn(path74) : false;
3590
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path77) : 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(path74, value) {
3608
- if (Collection.isEmptyPath(path74)) {
3607
+ setIn(path77, value) {
3608
+ if (Collection.isEmptyPath(path77)) {
3609
3609
  this.contents = value;
3610
3610
  } else if (this.contents == null) {
3611
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path74), value);
3611
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path77), value);
3612
3612
  } else if (assertCollection(this.contents)) {
3613
- this.contents.setIn(path74, value);
3613
+ this.contents.setIn(path77, value);
3614
3614
  }
3615
3615
  }
3616
3616
  /**
@@ -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, path74) => {
5573
+ visit.itemAtPath = (cst, path77) => {
5574
5574
  let item = cst;
5575
- for (const [field, index] of path74) {
5575
+ for (const [field, index] of path77) {
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, path74) => {
5585
- const parent = visit.itemAtPath(cst, path74.slice(0, -1));
5586
- const field = path74[path74.length - 1][0];
5584
+ visit.parentCollection = (cst, path77) => {
5585
+ const parent = visit.itemAtPath(cst, path77.slice(0, -1));
5586
+ const field = path77[path77.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(path74, item, visitor) {
5593
- let ctrl = visitor(item, path74);
5592
+ function _visit(path77, item, visitor) {
5593
+ let ctrl = visitor(item, path77);
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(path74.concat([[field, i]])), token.items[i], visitor);
5600
+ const ci = _visit(Object.freeze(path77.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, path74);
5611
+ ctrl = ctrl(item, path77);
5612
5612
  }
5613
5613
  }
5614
- return typeof ctrl === "function" ? ctrl(item, path74) : ctrl;
5614
+ return typeof ctrl === "function" ? ctrl(item, path77) : ctrl;
5615
5615
  }
5616
5616
  exports.visit = visit;
5617
5617
  }
@@ -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 fs71 = this.flowScalar(this.type);
6916
+ const fs74 = this.flowScalar(this.type);
6917
6917
  if (atNextItem || it.value) {
6918
- map.items.push({ start, key: fs71, sep: [] });
6918
+ map.items.push({ start, key: fs74, sep: [] });
6919
6919
  this.onKeyLine = true;
6920
6920
  } else if (it.sep) {
6921
- this.stack.push(fs71);
6921
+ this.stack.push(fs74);
6922
6922
  } else {
6923
- Object.assign(it, { key: fs71, sep: [] });
6923
+ Object.assign(it, { key: fs74, 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 fs71 = this.flowScalar(this.type);
7051
+ const fs74 = this.flowScalar(this.type);
7052
7052
  if (!it || it.value)
7053
- fc.items.push({ start: [], key: fs71, sep: [] });
7053
+ fc.items.push({ start: [], key: fs74, sep: [] });
7054
7054
  else if (it.sep)
7055
- this.stack.push(fs71);
7055
+ this.stack.push(fs74);
7056
7056
  else
7057
- Object.assign(it, { key: fs71, sep: [] });
7057
+ Object.assign(it, { key: fs74, sep: [] });
7058
7058
  return;
7059
7059
  }
7060
7060
  case "flow-map-end":
@@ -7363,15 +7363,15 @@ var require_dist = __commonJS({
7363
7363
  });
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
- import * as path73 from "node:path";
7367
- import { fileURLToPath as fileURLToPath52 } from "node:url";
7366
+ import * as path76 from "node:path";
7367
+ import { fileURLToPath as fileURLToPath54 } 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 spawnSync8 } from "node:child_process";
7372
- import fs70 from "node:fs";
7373
- import path72 from "node:path";
7374
- import { fileURLToPath as fileURLToPath51, pathToFileURL as pathToFileURL44 } from "node:url";
7372
+ import fs73 from "node:fs";
7373
+ import path75 from "node:path";
7374
+ import { fileURLToPath as fileURLToPath53, pathToFileURL as pathToFileURL46 } from "node:url";
7375
7375
 
7376
7376
  // src/scripts/_lib/spawn_env.ts
7377
7377
  var DENY_EXACT = /* @__PURE__ */ new Set([
@@ -14841,7 +14841,7 @@ var OpenAICliClient = class extends CliClient {
14841
14841
  if (measuredOn === void 0) return null;
14842
14842
  return {
14843
14843
  code: "model_unsupported_on_transport",
14844
- detail: `openai member pins model \`${this.model}\`, which the codex CLI (subscription transport) refused when measured on ${measuredOn}: "The '${this.model}' model is not supported when using Codex with a ChatGPT account." The CLI publishes no list of models it DOES accept, so there is no supported set to offer here \u2014 the one configuration measured to work is no pin at all. Fix: remove the \`model:\` line from the openai member (or set it to \`codex-default\`) to use the CLI's own default. A pinned model is only reachable on the API transport (\`api_key_ref:\` without \`mode: cli\`).`
14844
+ detail: `openai member pins model \`${this.model}\`, which the codex CLI (subscription transport) refused when measured on ${measuredOn}: "The '${this.model}' model is not supported when using Codex with a ChatGPT account." The CLI publishes no list of models it DOES accept, so there is no supported set to offer here \u2014 the one configuration measured to work is no pin at all. Fix: set \`model: codex-default\` on the openai member. Do NOT delete the \`model:\` line \u2014 an enabled member with no model fails config load, so that takes EVERY provider to NOT CONFIGURED. A pin is reachable only on the API transport.`
14845
14845
  };
14846
14846
  }
14847
14847
  /**
@@ -14956,7 +14956,7 @@ var OpenAICliClient = class extends CliClient {
14956
14956
  // needs and neither of which the error code carries.
14957
14957
  detail: failure.slice(0, 400),
14958
14958
  ...unsupported ? {
14959
- hint: "the codex subscription transport serves no explicitly pinned model measured so far \u2014 remove the `model:` line from the openai member to use the CLI default"
14959
+ hint: "the codex subscription transport serves no explicitly pinned model measured so far \u2014 set `model: codex-default` on the openai member; deleting the line fails config load"
14960
14960
  } : {}
14961
14961
  }
14962
14962
  });
@@ -23772,15 +23772,15 @@ function targets_kernel_rule(filePath) {
23772
23772
  if (segments.length === 0) {
23773
23773
  return null;
23774
23774
  }
23775
- const basename7 = segments[segments.length - 1];
23776
- if (!is_kernel_rule(basename7)) {
23775
+ const basename8 = segments[segments.length - 1];
23776
+ if (!is_kernel_rule(basename8)) {
23777
23777
  return null;
23778
23778
  }
23779
23779
  const dirSegments = segments.slice(0, -1);
23780
23780
  if (!dirSegments.includes("rules")) {
23781
23781
  return null;
23782
23782
  }
23783
- return basename7.replace(/\.md$/, "");
23783
+ return basename8.replace(/\.md$/, "");
23784
23784
  }
23785
23785
  var _MUTATOR_VERBS = /* @__PURE__ */ new Set([
23786
23786
  "sed",
@@ -26830,13 +26830,602 @@ if (_isCliEntry30()) {
26830
26830
  process.exit(main40());
26831
26831
  }
26832
26832
 
26833
+ // src/scripts/hooks/skill_route_hook.ts
26834
+ import fs63 from "node:fs";
26835
+ import path64 from "node:path";
26836
+ import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL37 } from "node:url";
26837
+
26838
+ // src/scripts/_lib/skill_catalogue.ts
26839
+ import * as fs61 from "node:fs";
26840
+ import * as path62 from "node:path";
26841
+ var DEFAULT_CATALOGUE_ROOTS = [".claude/skills", "src/skills"];
26842
+ function resolveSkillsRoot(workspaceRoot2) {
26843
+ for (const candidate of DEFAULT_CATALOGUE_ROOTS) {
26844
+ const abs = path62.join(workspaceRoot2, candidate);
26845
+ try {
26846
+ if (fs61.existsSync(abs) && fs61.statSync(abs).isDirectory()) return abs;
26847
+ } catch {
26848
+ }
26849
+ }
26850
+ return null;
26851
+ }
26852
+ var OBSERVATION_LOG = path62.join(
26853
+ "agents",
26854
+ "evidence",
26855
+ "metrics",
26856
+ "skill-catalogue.jsonl"
26857
+ );
26858
+
26859
+ // src/scripts/skill_tools/score_skill_relevance.ts
26860
+ import * as fs62 from "node:fs";
26861
+ import * as path63 from "node:path";
26862
+ import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL36 } from "node:url";
26863
+
26864
+ // src/scripts/_lib/value_ladder.ts
26865
+ function pyRound(value, ndigits = 0) {
26866
+ if (!Number.isFinite(value) || value === 0) {
26867
+ return value;
26868
+ }
26869
+ const sign = value < 0 ? -1 : 1;
26870
+ const abs = Math.abs(value);
26871
+ let str9 = abs.toPrecision(17);
26872
+ if (str9.includes("e") || str9.includes("E")) {
26873
+ const factor2 = 10 ** ndigits;
26874
+ return value > 0 ? Math.round(abs * factor2) / factor2 * sign : -Math.round(abs * factor2) / factor2;
26875
+ }
26876
+ let [intPart, fracPart = ""] = str9.split(".");
26877
+ while (fracPart.length <= ndigits) {
26878
+ fracPart += "0";
26879
+ }
26880
+ const keepFrac = fracPart.slice(0, ndigits);
26881
+ const deciderStr = fracPart.slice(ndigits);
26882
+ const scaledIntStr = intPart + keepFrac;
26883
+ let scaledInt = BigInt(scaledIntStr === "" ? "0" : scaledIntStr);
26884
+ const firstDecider = deciderStr.charAt(0);
26885
+ const restNonZero = /[1-9]/u.test(deciderStr.slice(1));
26886
+ let roundUp = false;
26887
+ if (firstDecider > "5" || firstDecider === "5" && restNonZero) {
26888
+ roundUp = true;
26889
+ } else if (firstDecider === "5" && !restNonZero) {
26890
+ roundUp = scaledInt % 2n === 1n;
26891
+ }
26892
+ if (roundUp) {
26893
+ scaledInt += 1n;
26894
+ }
26895
+ const factor = 10 ** ndigits;
26896
+ return Number(scaledInt) / factor * sign;
26897
+ }
26898
+
26899
+ // src/scripts/skill_tools/score_skill_relevance.ts
26900
+ var _HERE7 = fileURLToPath43(import.meta.url);
26901
+ var ROOT2 = path63.resolve(path63.dirname(_HERE7), "..", "..", "..");
26902
+ var DEFAULT_SKILLS_DIR = path63.join(ROOT2, ".agent-src.uncondensed", "skills");
26903
+ var TOKEN_RE2 = /[a-z][a-z0-9]+/g;
26904
+ var STOPWORDS = /* @__PURE__ */ new Set([
26905
+ "the",
26906
+ "a",
26907
+ "an",
26908
+ "and",
26909
+ "or",
26910
+ "but",
26911
+ "of",
26912
+ "for",
26913
+ "with",
26914
+ "to",
26915
+ "in",
26916
+ "on",
26917
+ "at",
26918
+ "by",
26919
+ "from",
26920
+ "as",
26921
+ "is",
26922
+ "are",
26923
+ "was",
26924
+ "were",
26925
+ "be",
26926
+ "been",
26927
+ "this",
26928
+ "that",
26929
+ "these",
26930
+ "those",
26931
+ "it",
26932
+ "its",
26933
+ "use",
26934
+ "when",
26935
+ "even",
26936
+ "via",
26937
+ "via:",
26938
+ "into",
26939
+ "onto",
26940
+ "use:",
26941
+ "skill",
26942
+ "skills",
26943
+ "task",
26944
+ "tasks",
26945
+ "code",
26946
+ "file",
26947
+ "files",
26948
+ "doing",
26949
+ "make",
26950
+ "do",
26951
+ "go",
26952
+ "get",
26953
+ "set",
26954
+ "not",
26955
+ "no",
26956
+ "yes",
26957
+ "any",
26958
+ "some",
26959
+ "all",
26960
+ "one",
26961
+ "two",
26962
+ "new",
26963
+ "old",
26964
+ "user",
26965
+ "users",
26966
+ "our",
26967
+ "your",
26968
+ "their",
26969
+ "they",
26970
+ "we",
26971
+ "you",
26972
+ "i",
26973
+ "me"
26974
+ ]);
26975
+ function pyLen(s) {
26976
+ let n = 0;
26977
+ for (const _ of s) {
26978
+ n++;
26979
+ }
26980
+ return n;
26981
+ }
26982
+ function _tokenize(text) {
26983
+ const out = /* @__PURE__ */ new Set();
26984
+ const matches = text.toLowerCase().match(TOKEN_RE2) ?? [];
26985
+ for (const t of matches) {
26986
+ if (!STOPWORDS.has(t) && pyLen(t) > 2) {
26987
+ out.add(t);
26988
+ }
26989
+ }
26990
+ return out;
26991
+ }
26992
+ function _parse_frontmatter(filePath) {
26993
+ const text = fs62.readFileSync(filePath, "utf-8");
26994
+ if (!text.startsWith("---")) {
26995
+ return {};
26996
+ }
26997
+ const end = text.indexOf("\n---", 3);
26998
+ if (end === -1) {
26999
+ return {};
27000
+ }
27001
+ const block = text.slice(3, end);
27002
+ const out = {};
27003
+ let currentListKey = null;
27004
+ for (const raw of _splitlines3(block)) {
27005
+ const line = _rstrip(raw);
27006
+ if (!line || line.startsWith("#")) {
27007
+ continue;
27008
+ }
27009
+ if (currentListKey !== null && line.startsWith(" - ")) {
27010
+ const existing = out[currentListKey];
27011
+ const list = Array.isArray(existing) ? existing : [];
27012
+ if (!Array.isArray(existing)) {
27013
+ out[currentListKey] = list;
27014
+ }
27015
+ list.push(line.slice(4).trim());
27016
+ continue;
27017
+ }
27018
+ currentListKey = null;
27019
+ const m = /^([a-zA-Z_][\w-]*)[ \t\r\f\v]*:[ \t\r\f\v]*(.*)$/u.exec(line);
27020
+ if (!m) {
27021
+ continue;
27022
+ }
27023
+ const key = m[1];
27024
+ let val = m[2].trim();
27025
+ if (val === "") {
27026
+ currentListKey = key;
27027
+ continue;
27028
+ }
27029
+ if (val.startsWith('"') && val.endsWith('"')) {
27030
+ val = val.slice(1, -1);
27031
+ }
27032
+ out[key] = val;
27033
+ }
27034
+ return out;
27035
+ }
27036
+ function _splitlines3(s) {
27037
+ if (s === "") {
27038
+ return [];
27039
+ }
27040
+ return s.split(/\r\n|\r|\n/u);
27041
+ }
27042
+ function _rstrip(s) {
27043
+ return s.replace(/\s+$/u, "");
27044
+ }
27045
+ function _load_skills(skillsDir) {
27046
+ const skills = [];
27047
+ for (const skillMd of _globSkillMd(skillsDir)) {
27048
+ const fm = _parse_frontmatter(skillMd);
27049
+ const rawName = fm["name"];
27050
+ const name = _truthyStr(rawName) ? String(rawName) : path63.basename(path63.dirname(skillMd));
27051
+ const rawDesc = fm["description"];
27052
+ const desc = _truthyStr(rawDesc) ? String(rawDesc) : "";
27053
+ let personas = fm["personas"] ?? [];
27054
+ if (typeof personas === "string") {
27055
+ personas = [personas];
27056
+ }
27057
+ const personaList = [...personas];
27058
+ skills.push({
27059
+ name,
27060
+ description: desc,
27061
+ personas: personaList,
27062
+ terms: _tokenize(name + " " + desc)
27063
+ });
27064
+ }
27065
+ return skills;
27066
+ }
27067
+ function _truthyStr(v) {
27068
+ if (typeof v === "string") {
27069
+ return v !== "";
27070
+ }
27071
+ return false;
27072
+ }
27073
+ function _globSkillMd(root) {
27074
+ let names;
27075
+ try {
27076
+ names = fs62.readdirSync(root);
27077
+ } catch {
27078
+ return [];
27079
+ }
27080
+ const dirs = [];
27081
+ for (const name of names) {
27082
+ const dir = path63.join(root, name);
27083
+ const skillMd = path63.join(dir, "SKILL.md");
27084
+ try {
27085
+ if (fs62.statSync(dir).isDirectory() && fs62.statSync(skillMd).isFile()) {
27086
+ dirs.push(name);
27087
+ }
27088
+ } catch {
27089
+ }
27090
+ }
27091
+ dirs.sort();
27092
+ return dirs.map((name) => path63.join(root, name, "SKILL.md"));
27093
+ }
27094
+ function _score3(taskTerms, skill) {
27095
+ if (taskTerms.size === 0) {
27096
+ return 0;
27097
+ }
27098
+ const skillTerms = skill.terms;
27099
+ let inter = 0;
27100
+ for (const t of taskTerms) {
27101
+ if (skillTerms.has(t)) {
27102
+ inter++;
27103
+ }
27104
+ }
27105
+ const overlap = inter / Math.max(taskTerms.size, 1);
27106
+ let personaHit = 0;
27107
+ const taskLower = [...taskTerms].join(" ");
27108
+ for (const persona of skill.personas) {
27109
+ const slug = String(persona).toLowerCase();
27110
+ const parts = slug.split("-");
27111
+ if (taskLower.includes(slug) || parts.some((part) => taskTerms.has(part))) {
27112
+ personaHit = 1;
27113
+ break;
27114
+ }
27115
+ }
27116
+ return pyRound(overlap * 70 + personaHit * 30, 0);
27117
+ }
27118
+ function rank(task, skillsDir) {
27119
+ const taskTerms = _tokenize(task);
27120
+ const skills = _load_skills(skillsDir);
27121
+ const rows = [];
27122
+ for (const s of skills) {
27123
+ const score = _score3(taskTerms, s);
27124
+ if (score > 0) {
27125
+ rows.push([s.name, score, [...s.personas]]);
27126
+ }
27127
+ }
27128
+ rows.sort((a, b) => {
27129
+ if (b[1] !== a[1]) {
27130
+ return b[1] - a[1];
27131
+ }
27132
+ if (a[0] < b[0]) {
27133
+ return -1;
27134
+ }
27135
+ if (a[0] > b[0]) {
27136
+ return 1;
27137
+ }
27138
+ return 0;
27139
+ });
27140
+ return rows;
27141
+ }
27142
+ function _ljust2(s, w) {
27143
+ const len = pyLen(s);
27144
+ return len >= w ? s : s + " ".repeat(w - len);
27145
+ }
27146
+ function _rjust3(n) {
27147
+ const s = String(n);
27148
+ return s.length >= 3 ? s : " ".repeat(3 - s.length) + s;
27149
+ }
27150
+ function _print_human(rowsIn, top) {
27151
+ let rows = rowsIn;
27152
+ if (top) {
27153
+ rows = rows.slice(0, top);
27154
+ }
27155
+ if (rows.length === 0) {
27156
+ return ["(no relevant skills found)"];
27157
+ }
27158
+ const width = Math.max(...rows.map((r) => pyLen(r[0])));
27159
+ const lines = [];
27160
+ for (const [name, score, personas] of rows) {
27161
+ const personaStr = personas.length > 0 ? personas.join(", ") : "\u2014";
27162
+ lines.push(` ${_rjust3(score)} ${_ljust2(name, width)} ${personaStr}`);
27163
+ }
27164
+ return lines;
27165
+ }
27166
+ function _pyJsonStr3(s) {
27167
+ let out = '"';
27168
+ for (const ch of s) {
27169
+ const code = ch.codePointAt(0);
27170
+ if (ch === '"') {
27171
+ out += '\\"';
27172
+ } else if (ch === "\\") {
27173
+ out += "\\\\";
27174
+ } else if (ch === "\n") {
27175
+ out += "\\n";
27176
+ } else if (ch === "\r") {
27177
+ out += "\\r";
27178
+ } else if (ch === " ") {
27179
+ out += "\\t";
27180
+ } else if (ch === "\b") {
27181
+ out += "\\b";
27182
+ } else if (ch === "\f") {
27183
+ out += "\\f";
27184
+ } else if (code < 32) {
27185
+ out += `\\u${code.toString(16).padStart(4, "0")}`;
27186
+ } else if (code < 127) {
27187
+ out += ch;
27188
+ } else if (code <= 65535) {
27189
+ out += `\\u${code.toString(16).padStart(4, "0")}`;
27190
+ } else {
27191
+ const c = code - 65536;
27192
+ const hi = 55296 + (c >> 10);
27193
+ const lo = 56320 + (c & 1023);
27194
+ out += `\\u${hi.toString(16).padStart(4, "0")}\\u${lo.toString(16).padStart(4, "0")}`;
27195
+ }
27196
+ }
27197
+ return out + '"';
27198
+ }
27199
+ function pyJsonDumpsIndent2(obj, level = 0) {
27200
+ if (obj === null) {
27201
+ return "null";
27202
+ }
27203
+ if (typeof obj === "number") {
27204
+ return String(obj);
27205
+ }
27206
+ if (typeof obj === "string") {
27207
+ return _pyJsonStr3(obj);
27208
+ }
27209
+ if (obj === true) {
27210
+ return "true";
27211
+ }
27212
+ if (obj === false) {
27213
+ return "false";
27214
+ }
27215
+ if (Array.isArray(obj)) {
27216
+ if (obj.length === 0) {
27217
+ return "[]";
27218
+ }
27219
+ const pad2 = " ".repeat(2 * (level + 1));
27220
+ const closePad2 = " ".repeat(2 * level);
27221
+ return `[
27222
+ ${obj.map((v) => pad2 + pyJsonDumpsIndent2(v, level + 1)).join(",\n")}
27223
+ ${closePad2}]`;
27224
+ }
27225
+ const keys = Object.keys(obj);
27226
+ if (keys.length === 0) {
27227
+ return "{}";
27228
+ }
27229
+ const pad = " ".repeat(2 * (level + 1));
27230
+ const closePad = " ".repeat(2 * level);
27231
+ const parts = keys.map(
27232
+ (k) => `${pad}${_pyJsonStr3(k)}: ${pyJsonDumpsIndent2(obj[k], level + 1)}`
27233
+ );
27234
+ return `{
27235
+ ${parts.join(",\n")}
27236
+ ${closePad}}`;
27237
+ }
27238
+ var PROG3 = "score_skill_relevance.py";
27239
+ function _argError4(message) {
27240
+ process.stderr.write(`${PROG3}: error: ${message}
27241
+ `);
27242
+ process.exit(2);
27243
+ }
27244
+ function _parseInt2(raw) {
27245
+ if (!/^[+-]?\d+$/u.test(raw.trim())) {
27246
+ _argError4(`argument --top: invalid int value: '${raw}'`);
27247
+ }
27248
+ return parseInt(raw, 10);
27249
+ }
27250
+ function parse_args8(argv) {
27251
+ const args = {
27252
+ task: "",
27253
+ skills_dir: DEFAULT_SKILLS_DIR,
27254
+ top: 0,
27255
+ json: false,
27256
+ sample: false
27257
+ };
27258
+ for (let i = 0; i < argv.length; i++) {
27259
+ const a = argv[i];
27260
+ if (a === "--json") {
27261
+ args.json = true;
27262
+ } else if (a === "--sample") {
27263
+ args.sample = true;
27264
+ } else if (a === "--task") {
27265
+ const v = argv[++i];
27266
+ if (v === void 0) {
27267
+ _argError4("argument --task: expected one argument");
27268
+ }
27269
+ args.task = v;
27270
+ } else if (a.startsWith("--task=")) {
27271
+ args.task = a.slice("--task=".length);
27272
+ } else if (a === "--skills-dir") {
27273
+ const v = argv[++i];
27274
+ if (v === void 0) {
27275
+ _argError4("argument --skills-dir: expected one argument");
27276
+ }
27277
+ args.skills_dir = v;
27278
+ } else if (a.startsWith("--skills-dir=")) {
27279
+ args.skills_dir = a.slice("--skills-dir=".length);
27280
+ } else if (a === "--top") {
27281
+ const v = argv[++i];
27282
+ if (v === void 0) {
27283
+ _argError4("argument --top: expected one argument");
27284
+ }
27285
+ args.top = _parseInt2(v);
27286
+ } else if (a.startsWith("--top=")) {
27287
+ args.top = _parseInt2(a.slice("--top=".length));
27288
+ } else {
27289
+ _argError4(`unrecognized arguments: ${a}`);
27290
+ }
27291
+ }
27292
+ return args;
27293
+ }
27294
+ var _SAMPLE = {
27295
+ task: "build a livewire component for the user dashboard with reactive state"
27296
+ };
27297
+ function main41(argv = null) {
27298
+ const args = parse_args8(argv ?? process.argv.slice(2));
27299
+ const task = args.sample ? _SAMPLE.task : args.task;
27300
+ if (!task) {
27301
+ _argError4("--task is required (or pass --sample)");
27302
+ }
27303
+ const rows = rank(task, args.skills_dir);
27304
+ if (args.json) {
27305
+ const sliced = args.top ? rows.slice(0, args.top) : rows;
27306
+ const payload = sliced.map(([n, s, p]) => ({ name: n, score: s, personas: p }));
27307
+ process.stdout.write(pyJsonDumpsIndent2({ task, ranked: payload }));
27308
+ process.stdout.write("\n");
27309
+ } else {
27310
+ const lines = _print_human(rows, args.top || null);
27311
+ process.stdout.write(lines.join("\n") + "\n");
27312
+ }
27313
+ return 0;
27314
+ }
27315
+ function _isCliEntry31() {
27316
+ if (process.argv[1] === void 0) {
27317
+ return false;
27318
+ }
27319
+ const argvUrl = pathToFileURL36(path63.resolve(process.argv[1])).href;
27320
+ if (import.meta.url === argvUrl) {
27321
+ return true;
27322
+ }
27323
+ try {
27324
+ const here = fs62.realpathSync(fileURLToPath43(import.meta.url));
27325
+ const argv = fs62.realpathSync(path63.resolve(process.argv[1]));
27326
+ return here === argv;
27327
+ } catch {
27328
+ return false;
27329
+ }
27330
+ }
27331
+ var _isMain5 = _isCliEntry31();
27332
+ if (_isMain5) {
27333
+ process.exitCode = main41();
27334
+ }
27335
+
27336
+ // src/scripts/hooks/skill_route_hook.ts
27337
+ var EXIT_ALLOW18 = 0;
27338
+ var EXIT_WARN10 = 2;
27339
+ var MIN_TOP_SCORE = 31;
27340
+ var MIN_TASK_TERMS = 3;
27341
+ var TOP_K = 3;
27342
+ function _isObject14(v) {
27343
+ return typeof v === "object" && v !== null && !Array.isArray(v);
27344
+ }
27345
+ function routePointers(prompt, skillsDir) {
27346
+ if (skillsDir === null) return [];
27347
+ try {
27348
+ if (_tokenize(prompt).size < MIN_TASK_TERMS) return [];
27349
+ } catch {
27350
+ return [];
27351
+ }
27352
+ let rows;
27353
+ try {
27354
+ rows = rank(prompt, skillsDir);
27355
+ } catch {
27356
+ return [];
27357
+ }
27358
+ const top = rows[0];
27359
+ if (top === void 0 || top[1] < MIN_TOP_SCORE) return [];
27360
+ return rows.slice(0, TOP_K);
27361
+ }
27362
+ function buildRouteLine(rows) {
27363
+ const pointers = rows.map(([name, score]) => `${name} (${score})`).join(", ");
27364
+ return `<skill-route>ranked skill pointers for this prompt: ${pointers}. Deterministic keyword ranker, top-1 at or above ${MIN_TOP_SCORE}/100 \u2014 pointers only, no bodies loaded. Open one if it fits; ignore the line if it does not.</skill-route>`;
27365
+ }
27366
+ function _extractPrompt3(payload) {
27367
+ for (const key of ["prompt", "userPrompt", "user_prompt", "message", "text"]) {
27368
+ const v = payload[key];
27369
+ if (typeof v === "string" && v.trim()) return v;
27370
+ }
27371
+ return "";
27372
+ }
27373
+ function _workspaceRoot4(envelope) {
27374
+ const v = envelope["workspace_root"];
27375
+ return typeof v === "string" && v ? v : process.cwd();
27376
+ }
27377
+ function main42() {
27378
+ let envelope = {};
27379
+ try {
27380
+ const raw = readHookStdin();
27381
+ envelope = raw.trim() ? JSON.parse(raw) : {};
27382
+ } catch {
27383
+ return EXIT_ALLOW18;
27384
+ }
27385
+ const env = _isObject14(envelope) ? envelope : {};
27386
+ const event = env["event"];
27387
+ const slot = typeof event === "string" && event !== "" ? event : "user_prompt_submit";
27388
+ if (slot !== "user_prompt_submit") return EXIT_ALLOW18;
27389
+ const payload = _isObject14(env["payload"]) ? env["payload"] : env;
27390
+ const prompt = _extractPrompt3(payload);
27391
+ if (!prompt) return EXIT_ALLOW18;
27392
+ if (isSyntheticPrompt(prompt)) return EXIT_ALLOW18;
27393
+ const rows = routePointers(prompt, resolveSkillsRoot(_workspaceRoot4(env)));
27394
+ if (rows.length === 0) return EXIT_ALLOW18;
27395
+ process.stdout.write(
27396
+ `${JSON.stringify({
27397
+ decision: "warn",
27398
+ reason: `skill-route: ${rows.length} pointer(s), top ${rows[0][1]}/100`,
27399
+ additional_context: buildRouteLine(rows)
27400
+ })}
27401
+ `
27402
+ );
27403
+ return EXIT_WARN10;
27404
+ }
27405
+ function _isCliEntry32() {
27406
+ if (true) return false;
27407
+ if (process.argv[1] === void 0) return false;
27408
+ const argvUrl = pathToFileURL37(path64.resolve(process.argv[1])).href;
27409
+ if (import.meta.url === argvUrl) return true;
27410
+ try {
27411
+ const here = fs63.realpathSync(fileURLToPath44(import.meta.url));
27412
+ const argv = fs63.realpathSync(path64.resolve(process.argv[1]));
27413
+ return here === argv;
27414
+ } catch {
27415
+ return false;
27416
+ }
27417
+ }
27418
+ if (_isCliEntry32()) {
27419
+ process.exit(main42());
27420
+ }
27421
+
26833
27422
  // src/scripts/hooks/end_review_nudge_hook.ts
26834
27423
  import { spawnSync as spawnSync6 } from "node:child_process";
26835
27424
  import * as crypto6 from "node:crypto";
26836
- import * as fs61 from "node:fs";
27425
+ import * as fs64 from "node:fs";
26837
27426
  import * as os7 from "node:os";
26838
- import * as path62 from "node:path";
26839
- import { fileURLToPath as fileURLToPath43, pathToFileURL as pathToFileURL36 } from "node:url";
27427
+ import * as path65 from "node:path";
27428
+ import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL38 } from "node:url";
26840
27429
 
26841
27430
  // src/scripts/_lib/review_skipped_record.ts
26842
27431
  function isNonNegInt(n) {
@@ -26883,19 +27472,19 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
26883
27472
  const homeDir = opts.homeDir ?? os7.homedir();
26884
27473
  const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
26885
27474
  try {
26886
- const realHome = fs61.realpathSync(homeDir);
26887
- const realPath = fs61.realpathSync(rawPath);
26888
- const relative9 = path62.relative(realHome, realPath);
26889
- if (relative9 === "" || relative9.startsWith("..") || path62.isAbsolute(relative9)) {
27475
+ const realHome = fs64.realpathSync(homeDir);
27476
+ const realPath = fs64.realpathSync(rawPath);
27477
+ const relative9 = path65.relative(realHome, realPath);
27478
+ if (relative9 === "" || relative9.startsWith("..") || path65.isAbsolute(relative9)) {
26890
27479
  return false;
26891
27480
  }
26892
- const { size } = fs61.statSync(realPath);
27481
+ const { size } = fs64.statSync(realPath);
26893
27482
  return size <= maxBytes;
26894
27483
  } catch {
26895
27484
  return false;
26896
27485
  }
26897
27486
  }
26898
- var EXIT_WARN10 = 2;
27487
+ var EXIT_WARN11 = 2;
26899
27488
  function parseNumstat(raw) {
26900
27489
  const rows = [];
26901
27490
  for (const line of raw.split("\n")) {
@@ -27032,19 +27621,19 @@ function appendReviewSkippedTelemetry(workspaceRoot2, diffLines, mutationMeasure
27032
27621
  });
27033
27622
  if (errors.length || line === null) return;
27034
27623
  try {
27035
- const dir = path62.join(workspaceRoot2, "agents", "runtime", "state", "audit");
27036
- fs61.mkdirSync(dir, { recursive: true });
27037
- const file = path62.join(dir, `${ts.slice(0, 7)}.jsonl`);
27038
- fs61.appendFileSync(file, `${JSON.stringify(line)}
27624
+ const dir = path65.join(workspaceRoot2, "agents", "runtime", "state", "audit");
27625
+ fs64.mkdirSync(dir, { recursive: true });
27626
+ const file = path65.join(dir, `${ts.slice(0, 7)}.jsonl`);
27627
+ fs64.appendFileSync(file, `${JSON.stringify(line)}
27039
27628
  `, "utf8");
27040
27629
  } catch {
27041
27630
  }
27042
27631
  }
27043
27632
  function sessionStateDir(workspaceRoot2) {
27044
- return path62.join(workspaceRoot2, "agents", "runtime", "state", "end-review-nudge");
27633
+ return path65.join(workspaceRoot2, "agents", "runtime", "state", "end-review-nudge");
27045
27634
  }
27046
27635
  function sessionStateFile(workspaceRoot2, sessionKey) {
27047
- return path62.join(sessionStateDir(workspaceRoot2), `${sessionKey}.json`);
27636
+ return path65.join(sessionStateDir(workspaceRoot2), `${sessionKey}.json`);
27048
27637
  }
27049
27638
  function deriveSessionKey(envelope, payload) {
27050
27639
  const raw = str3(envelope["session_id"]) || str3(payload["transcript_path"] ?? payload["transcriptPath"]);
@@ -27053,7 +27642,7 @@ function deriveSessionKey(envelope, payload) {
27053
27642
  }
27054
27643
  function hasFiredThisSession(workspaceRoot2, sessionKey) {
27055
27644
  try {
27056
- return fs61.existsSync(sessionStateFile(workspaceRoot2, sessionKey));
27645
+ return fs64.existsSync(sessionStateFile(workspaceRoot2, sessionKey));
27057
27646
  } catch {
27058
27647
  return false;
27059
27648
  }
@@ -27067,7 +27656,7 @@ function markFiredThisSession(workspaceRoot2, sessionKey, ts) {
27067
27656
  function _read_stdin3() {
27068
27657
  return readHookStdin();
27069
27658
  }
27070
- function main41() {
27659
+ function main43() {
27071
27660
  const [envelope, payload] = unwrap(_read_stdin3(), "claude");
27072
27661
  const event = String(envelope["event"] ?? "");
27073
27662
  if (event !== "" && event !== "stop") {
@@ -27096,7 +27685,7 @@ function main41() {
27096
27685
  let reviewerRan = false;
27097
27686
  if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
27098
27687
  try {
27099
- reviewerRan = scanTranscriptForReviewer(fs61.readFileSync(transcriptPath, "utf-8"));
27688
+ reviewerRan = scanTranscriptForReviewer(fs64.readFileSync(transcriptPath, "utf-8"));
27100
27689
  } catch {
27101
27690
  reviewerRan = false;
27102
27691
  }
@@ -27117,42 +27706,42 @@ function main41() {
27117
27706
  })}
27118
27707
  `
27119
27708
  );
27120
- return EXIT_WARN10;
27709
+ return EXIT_WARN11;
27121
27710
  }
27122
- function _isCliEntry31() {
27711
+ function _isCliEntry33() {
27123
27712
  if (true) {
27124
27713
  return false;
27125
27714
  }
27126
27715
  if (process.argv[1] === void 0) {
27127
27716
  return false;
27128
27717
  }
27129
- const argvUrl = pathToFileURL36(path62.resolve(process.argv[1])).href;
27718
+ const argvUrl = pathToFileURL38(path65.resolve(process.argv[1])).href;
27130
27719
  if (import.meta.url === argvUrl) {
27131
27720
  return true;
27132
27721
  }
27133
27722
  try {
27134
- const here = fs61.realpathSync(fileURLToPath43(import.meta.url));
27135
- const argv = fs61.realpathSync(path62.resolve(process.argv[1]));
27723
+ const here = fs64.realpathSync(fileURLToPath45(import.meta.url));
27724
+ const argv = fs64.realpathSync(path65.resolve(process.argv[1]));
27136
27725
  return here === argv;
27137
27726
  } catch {
27138
27727
  return false;
27139
27728
  }
27140
27729
  }
27141
- if (_isCliEntry31()) {
27142
- process.exit(main41());
27730
+ if (_isCliEntry33()) {
27731
+ process.exit(main43());
27143
27732
  }
27144
27733
 
27145
27734
  // src/scripts/hooks/turn_end_gate_hook.ts
27146
27735
  import * as crypto8 from "node:crypto";
27147
- import * as fs63 from "node:fs";
27148
- import * as path64 from "node:path";
27149
- import { fileURLToPath as fileURLToPath45, pathToFileURL as pathToFileURL38 } from "node:url";
27736
+ import * as fs66 from "node:fs";
27737
+ import * as path67 from "node:path";
27738
+ import { fileURLToPath as fileURLToPath47, pathToFileURL as pathToFileURL40 } from "node:url";
27150
27739
 
27151
27740
  // src/scripts/hooks/subagent_ledger_hook.ts
27152
27741
  import * as crypto7 from "node:crypto";
27153
- import * as fs62 from "node:fs";
27154
- import * as path63 from "node:path";
27155
- import { fileURLToPath as fileURLToPath44, pathToFileURL as pathToFileURL37 } from "node:url";
27742
+ import * as fs65 from "node:fs";
27743
+ import * as path66 from "node:path";
27744
+ import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL39 } from "node:url";
27156
27745
 
27157
27746
  // src/scripts/_lib/subagent_response.ts
27158
27747
  var MAX_SUMMARY_CHARS = 2e3;
@@ -27242,11 +27831,11 @@ function validateResponse(input) {
27242
27831
  }
27243
27832
 
27244
27833
  // src/scripts/hooks/subagent_ledger_hook.ts
27245
- var EXIT_ALLOW18 = 0;
27834
+ var EXIT_ALLOW19 = 0;
27246
27835
  function isObject7(v) {
27247
27836
  return typeof v === "object" && v !== null && !Array.isArray(v);
27248
27837
  }
27249
- var LEDGER_DIR = path63.join("agents", "runtime", "state", "subagent-ledger");
27838
+ var LEDGER_DIR = path66.join("agents", "runtime", "state", "subagent-ledger");
27250
27839
  var OPEN_SUBDIR = "open";
27251
27840
  var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
27252
27841
  function refFor(agentId) {
@@ -27327,10 +27916,10 @@ function _jsonObjectCandidates(message) {
27327
27916
  return out;
27328
27917
  }
27329
27918
  function openDir(root) {
27330
- return path63.join(root, LEDGER_DIR, OPEN_SUBDIR);
27919
+ return path66.join(root, LEDGER_DIR, OPEN_SUBDIR);
27331
27920
  }
27332
27921
  function openFile(root, ref) {
27333
- return path63.join(openDir(root), `${ref}.json`);
27922
+ return path66.join(openDir(root), `${ref}.json`);
27334
27923
  }
27335
27924
  var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
27336
27925
  function _asOpenRecord(value, expectedRef) {
@@ -27357,7 +27946,7 @@ function readOpenRecords(root) {
27357
27946
  const out = /* @__PURE__ */ new Map();
27358
27947
  let names;
27359
27948
  try {
27360
- names = fs62.readdirSync(openDir(root));
27949
+ names = fs65.readdirSync(openDir(root));
27361
27950
  } catch {
27362
27951
  return out;
27363
27952
  }
@@ -27365,7 +27954,7 @@ function readOpenRecords(root) {
27365
27954
  if (!name.endsWith(".json")) continue;
27366
27955
  const expectedRef = name.slice(0, -".json".length);
27367
27956
  try {
27368
- const raw = fs62.readFileSync(path63.join(openDir(root), name), "utf8");
27957
+ const raw = fs65.readFileSync(path66.join(openDir(root), name), "utf8");
27369
27958
  const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
27370
27959
  if (rec) out.set(rec.ref, rec);
27371
27960
  } catch {
@@ -27380,13 +27969,13 @@ function resolveDepth(parentRef, open) {
27380
27969
  return { depth: parent.depth + 1, depth_basis: "observed" };
27381
27970
  }
27382
27971
  function ledgerFileFor(root, ts) {
27383
- return path63.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
27972
+ return path66.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
27384
27973
  }
27385
27974
  function appendLedgerLine(root, ts, line) {
27386
27975
  if (is_replay_mode()) return;
27387
27976
  const file = ledgerFileFor(root, ts);
27388
- fs62.mkdirSync(path63.dirname(file), { recursive: true });
27389
- fs62.appendFileSync(file, `${JSON.stringify(line)}
27977
+ fs65.mkdirSync(path66.dirname(file), { recursive: true });
27978
+ fs65.appendFileSync(file, `${JSON.stringify(line)}
27390
27979
  `, "utf8");
27391
27980
  }
27392
27981
  var WALL_CLOCK_ARMS_MS = [
@@ -27400,7 +27989,7 @@ function armsExceeded(elapsedMs) {
27400
27989
  return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
27401
27990
  }
27402
27991
  function openRecordStats(root, nowMs = Date.now()) {
27403
- const ledgerPresent = fs62.existsSync(path63.join(root, LEDGER_DIR));
27992
+ const ledgerPresent = fs65.existsSync(path66.join(root, LEDGER_DIR));
27404
27993
  const open = readOpenRecords(root);
27405
27994
  let maxDepth = 0;
27406
27995
  let counted = 0;
@@ -27428,13 +28017,13 @@ function writeOpenRecord(root, rec) {
27428
28017
  function removeOpenRecord(root, ref) {
27429
28018
  if (is_replay_mode()) return;
27430
28019
  try {
27431
- fs62.unlinkSync(openFile(root, ref));
28020
+ fs65.unlinkSync(openFile(root, ref));
27432
28021
  } catch {
27433
28022
  }
27434
28023
  }
27435
28024
  function countOpen(root) {
27436
28025
  try {
27437
- return fs62.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
28026
+ return fs65.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
27438
28027
  } catch {
27439
28028
  return 0;
27440
28029
  }
@@ -27558,9 +28147,9 @@ function handleStop(root, payload, nowIso, sessionId2) {
27558
28147
  }
27559
28148
  function processEnvelope2(envelope, consumerRoot) {
27560
28149
  try {
27561
- if (!isObject7(envelope)) return EXIT_ALLOW18;
28150
+ if (!isObject7(envelope)) return EXIT_ALLOW19;
27562
28151
  const event = envelope["event"];
27563
- if (event !== "subagent_start" && event !== "subagent_stop") return EXIT_ALLOW18;
28152
+ if (event !== "subagent_start" && event !== "subagent_stop") return EXIT_ALLOW19;
27564
28153
  const payload = unwrapPayload2(envelope);
27565
28154
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
27566
28155
  const sessionId2 = str4(payload, "session_id", "sessionId") ?? str4(envelope, "session_id", "sessionId");
@@ -27568,9 +28157,9 @@ function processEnvelope2(envelope, consumerRoot) {
27568
28157
  if (event === "subagent_start") handleStart(consumerRoot, payload, nowIso, sessionId2);
27569
28158
  else handleStop(consumerRoot, payload, nowIso, sessionId2);
27570
28159
  } catch {
27571
- return EXIT_ALLOW18;
28160
+ return EXIT_ALLOW19;
27572
28161
  }
27573
- return EXIT_ALLOW18;
28162
+ return EXIT_ALLOW19;
27574
28163
  }
27575
28164
  function resolveConsumerRoot(envelope) {
27576
28165
  if (isObject7(envelope)) {
@@ -27582,34 +28171,34 @@ function resolveConsumerRoot(envelope) {
27582
28171
  }
27583
28172
  return process.cwd();
27584
28173
  }
27585
- function main42() {
28174
+ function main44() {
27586
28175
  const raw = readHookStdin();
27587
28176
  let envelope = {};
27588
28177
  try {
27589
28178
  envelope = raw.trim() ? JSON.parse(raw) : {};
27590
28179
  } catch {
27591
- return EXIT_ALLOW18;
28180
+ return EXIT_ALLOW19;
27592
28181
  }
27593
28182
  return processEnvelope2(envelope, resolveConsumerRoot(envelope));
27594
28183
  }
27595
- function _isCliEntry32() {
28184
+ function _isCliEntry34() {
27596
28185
  if (true) {
27597
28186
  return false;
27598
28187
  }
27599
28188
  if (process.argv[1] === void 0) return false;
27600
- const argvUrl = pathToFileURL37(path63.resolve(process.argv[1])).href;
28189
+ const argvUrl = pathToFileURL39(path66.resolve(process.argv[1])).href;
27601
28190
  if (import.meta.url === argvUrl) return true;
27602
28191
  try {
27603
- return fs62.realpathSync(fileURLToPath44(import.meta.url)) === fs62.realpathSync(path63.resolve(process.argv[1]));
28192
+ return fs65.realpathSync(fileURLToPath46(import.meta.url)) === fs65.realpathSync(path66.resolve(process.argv[1]));
27604
28193
  } catch {
27605
28194
  return false;
27606
28195
  }
27607
28196
  }
27608
- if (_isCliEntry32()) process.exit(main42());
28197
+ if (_isCliEntry34()) process.exit(main44());
27609
28198
 
27610
28199
  // src/scripts/hooks/turn_end_gate_hook.ts
27611
28200
  var EXIT_BLOCK4 = 1;
27612
- var EXIT_ALLOW19 = 0;
28201
+ var EXIT_ALLOW20 = 0;
27613
28202
  var TRANSCRIPT_READ_MAX_BYTES = 8 * 1024 * 1024;
27614
28203
  function stripFencedBlocks(text) {
27615
28204
  const out = [];
@@ -27713,7 +28302,7 @@ function detectPromissory(reply) {
27713
28302
  }
27714
28303
  function readCiSettled(workspaceRoot2) {
27715
28304
  try {
27716
- const raw = fs63.readFileSync(path64.join(workspaceRoot2, STATE_FILE3), "utf-8");
28305
+ const raw = fs66.readFileSync(path67.join(workspaceRoot2, STATE_FILE3), "utf-8");
27717
28306
  const decoded = JSON.parse(raw);
27718
28307
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
27719
28308
  const ci = decoded["ci_last"];
@@ -27747,7 +28336,7 @@ function detectCompletionClaim(reply, ci) {
27747
28336
  }
27748
28337
  function readLanguagePin(workspaceRoot2) {
27749
28338
  try {
27750
- const raw = fs63.readFileSync(path64.join(workspaceRoot2, STATE_FILE5), "utf-8");
28339
+ const raw = fs66.readFileSync(path67.join(workspaceRoot2, STATE_FILE5), "utf-8");
27751
28340
  const decoded = JSON.parse(raw);
27752
28341
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
27753
28342
  const lang = decoded["language"];
@@ -27796,17 +28385,17 @@ function detectUnverifiedEdit(toolCalls) {
27796
28385
  };
27797
28386
  }
27798
28387
  function stateDir(workspaceRoot2) {
27799
- return path64.join(workspaceRoot2, "agents", "runtime", "state", "turn-end-gate");
28388
+ return path67.join(workspaceRoot2, "agents", "runtime", "state", "turn-end-gate");
27800
28389
  }
27801
28390
  function sessionStateFile2(workspaceRoot2, sessionKey) {
27802
- return path64.join(stateDir(workspaceRoot2), `${sessionKey}.json`);
28391
+ return path67.join(stateDir(workspaceRoot2), `${sessionKey}.json`);
27803
28392
  }
27804
28393
  function deriveSessionKey2(sessionId2) {
27805
28394
  return crypto8.createHash("sha256").update(sessionId2).digest("hex").slice(0, 32);
27806
28395
  }
27807
28396
  function alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal) {
27808
28397
  try {
27809
- const raw = fs63.readFileSync(sessionStateFile2(workspaceRoot2, sessionKey), "utf-8");
28398
+ const raw = fs66.readFileSync(sessionStateFile2(workspaceRoot2, sessionKey), "utf-8");
27810
28399
  const decoded = JSON.parse(raw);
27811
28400
  if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
27812
28401
  return decoded["refused_turn"] === turnOrdinal;
@@ -27831,10 +28420,10 @@ function readTranscriptTail(transcriptPath, opts = {}) {
27831
28420
  if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
27832
28421
  let lines;
27833
28422
  try {
27834
- if (opts.maxBytes !== void 0 && fs63.statSync(transcriptPath).size > opts.maxBytes) {
28423
+ if (opts.maxBytes !== void 0 && fs66.statSync(transcriptPath).size > opts.maxBytes) {
27835
28424
  return empty;
27836
28425
  }
27837
- lines = fs63.readFileSync(transcriptPath, "utf-8").split("\n");
28426
+ lines = fs66.readFileSync(transcriptPath, "utf-8").split("\n");
27838
28427
  } catch {
27839
28428
  return empty;
27840
28429
  }
@@ -27910,15 +28499,15 @@ function _messageText(content) {
27910
28499
  function str5(v) {
27911
28500
  return typeof v === "string" ? v : "";
27912
28501
  }
27913
- function main43() {
28502
+ function main45() {
27914
28503
  let envelope;
27915
28504
  let payload;
27916
28505
  try {
27917
28506
  [envelope, payload] = unwrap(readHookStdin(), "claude");
27918
28507
  } catch {
27919
- return EXIT_ALLOW19;
28508
+ return EXIT_ALLOW20;
27920
28509
  }
27921
- if (payload["stop_hook_active"] === true) return EXIT_ALLOW19;
28510
+ if (payload["stop_hook_active"] === true) return EXIT_ALLOW20;
27922
28511
  const workspaceRoot2 = str5(envelope["workspace_root"]) || process.cwd();
27923
28512
  let dispatchOpen = false;
27924
28513
  try {
@@ -27931,11 +28520,11 @@ function main43() {
27931
28520
  const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(transcriptPath, {
27932
28521
  maxBytes: TRANSCRIPT_READ_MAX_BYTES
27933
28522
  });
27934
- if (!lastAssistant) return EXIT_ALLOW19;
28523
+ if (!lastAssistant) return EXIT_ALLOW20;
27935
28524
  const sessionKey = deriveSessionKey2(
27936
28525
  str5(envelope["session_id"]) || "unknown-session"
27937
28526
  );
27938
- if (alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal)) return EXIT_ALLOW19;
28527
+ if (alreadyRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal)) return EXIT_ALLOW20;
27939
28528
  const findings = [];
27940
28529
  for (const f of [
27941
28530
  // A and D are the completion-adjacent pair a pending dispatch excuses
@@ -27955,7 +28544,7 @@ function main43() {
27955
28544
  ]) {
27956
28545
  if (f) findings.push(f);
27957
28546
  }
27958
- if (findings.length === 0) return EXIT_ALLOW19;
28547
+ if (findings.length === 0) return EXIT_ALLOW20;
27959
28548
  markRefusedTurn(workspaceRoot2, sessionKey, turnOrdinal, findings[0].detector);
27960
28549
  const lines = findings.map(
27961
28550
  (f) => ` \xB7 ${f.detector}: ${f.reason}
@@ -27970,37 +28559,37 @@ ${lines.join("\n")}
27970
28559
  );
27971
28560
  return EXIT_BLOCK4;
27972
28561
  }
27973
- function _isCliEntry33() {
28562
+ function _isCliEntry35() {
27974
28563
  if (true) {
27975
28564
  return false;
27976
28565
  }
27977
28566
  if (process.argv[1] === void 0) {
27978
28567
  return false;
27979
28568
  }
27980
- const argvUrl = pathToFileURL38(path64.resolve(process.argv[1])).href;
28569
+ const argvUrl = pathToFileURL40(path67.resolve(process.argv[1])).href;
27981
28570
  if (import.meta.url === argvUrl) {
27982
28571
  return true;
27983
28572
  }
27984
28573
  try {
27985
- const here = fs63.realpathSync(fileURLToPath45(import.meta.url));
27986
- const argv = fs63.realpathSync(path64.resolve(process.argv[1]));
28574
+ const here = fs66.realpathSync(fileURLToPath47(import.meta.url));
28575
+ const argv = fs66.realpathSync(path67.resolve(process.argv[1]));
27987
28576
  return here === argv;
27988
28577
  } catch {
27989
28578
  return false;
27990
28579
  }
27991
28580
  }
27992
- if (_isCliEntry33()) {
27993
- process.exit(main43());
28581
+ if (_isCliEntry35()) {
28582
+ process.exit(main45());
27994
28583
  }
27995
28584
 
27996
28585
  // src/scripts/hooks/edit_shape_hook.ts
27997
28586
  import { spawnSync as spawnSync7 } from "node:child_process";
27998
28587
  import * as crypto9 from "node:crypto";
27999
- import * as fs64 from "node:fs";
28000
- import * as path65 from "node:path";
28001
- import { fileURLToPath as fileURLToPath46, pathToFileURL as pathToFileURL39 } from "node:url";
28002
- var EXIT_ALLOW20 = 0;
28003
- var EXIT_WARN11 = 2;
28588
+ import * as fs67 from "node:fs";
28589
+ import * as path68 from "node:path";
28590
+ import { fileURLToPath as fileURLToPath48, pathToFileURL as pathToFileURL41 } from "node:url";
28591
+ var EXIT_ALLOW21 = 0;
28592
+ var EXIT_WARN12 = 2;
28004
28593
  var MIN_FILE_LINES = 50;
28005
28594
  var MAX_DIFF_RATIO = 0.2;
28006
28595
  var EXEMPT_PATH_PATTERNS = [
@@ -28051,7 +28640,7 @@ function effectiveDiffLines(cwd, relPath) {
28051
28640
  }
28052
28641
  function fileLineCount(absPath) {
28053
28642
  try {
28054
- const text = fs64.readFileSync(absPath, "utf8");
28643
+ const text = fs67.readFileSync(absPath, "utf8");
28055
28644
  if (text.length === 0) return 0;
28056
28645
  return text.split("\n").length - (text.endsWith("\n") ? 1 : 0);
28057
28646
  } catch {
@@ -28068,11 +28657,11 @@ function deriveSessionKey3(envelope, payload) {
28068
28657
  return crypto9.createHash("sha256").update(material).digest("hex");
28069
28658
  }
28070
28659
  function sessionStateFile3(workspaceRoot2, sessionKey) {
28071
- return path65.join(workspaceRoot2, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
28660
+ return path68.join(workspaceRoot2, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
28072
28661
  }
28073
28662
  function hasFiredThisSession2(workspaceRoot2, sessionKey) {
28074
28663
  try {
28075
- return fs64.existsSync(sessionStateFile3(workspaceRoot2, sessionKey));
28664
+ return fs67.existsSync(sessionStateFile3(workspaceRoot2, sessionKey));
28076
28665
  } catch {
28077
28666
  return false;
28078
28667
  }
@@ -28093,26 +28682,26 @@ function extractFilePath(payload) {
28093
28682
  if (!isObject8(ti)) return "";
28094
28683
  return str6(ti["file_path"] ?? ti["path"] ?? ti["filePath"]);
28095
28684
  }
28096
- function main44() {
28685
+ function main46() {
28097
28686
  try {
28098
28687
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
28099
28688
  const event = str6(envelope["event"]);
28100
- if (event !== "" && event !== "post_tool_use") return EXIT_ALLOW20;
28689
+ if (event !== "" && event !== "post_tool_use") return EXIT_ALLOW21;
28101
28690
  const toolName = extractToolName2(payload);
28102
- if (toolName !== "Write") return EXIT_ALLOW20;
28691
+ if (toolName !== "Write") return EXIT_ALLOW21;
28103
28692
  const filePath = extractFilePath(payload);
28104
- if (!filePath) return EXIT_ALLOW20;
28693
+ if (!filePath) return EXIT_ALLOW21;
28105
28694
  const workspaceRoot2 = str6(envelope["workspace_root"]).trim() || process.cwd();
28106
- const absPath = path65.isAbsolute(filePath) ? filePath : path65.resolve(workspaceRoot2, filePath);
28107
- const relPath = path65.relative(workspaceRoot2, absPath);
28108
- if (isExemptPath(relPath) || isExemptPath(absPath)) return EXIT_ALLOW20;
28695
+ const absPath = path68.isAbsolute(filePath) ? filePath : path68.resolve(workspaceRoot2, filePath);
28696
+ const relPath = path68.relative(workspaceRoot2, absPath);
28697
+ if (isExemptPath(relPath) || isExemptPath(absPath)) return EXIT_ALLOW21;
28109
28698
  const fileLines = fileLineCount(absPath);
28110
- if (fileLines < MIN_FILE_LINES) return EXIT_ALLOW20;
28699
+ if (fileLines < MIN_FILE_LINES) return EXIT_ALLOW21;
28111
28700
  const diffLines = effectiveDiffLines(workspaceRoot2, relPath.startsWith("..") ? absPath : relPath);
28112
- if (diffLines === 0) return EXIT_ALLOW20;
28113
- if (diffLines / fileLines > MAX_DIFF_RATIO) return EXIT_ALLOW20;
28701
+ if (diffLines === 0) return EXIT_ALLOW21;
28702
+ if (diffLines / fileLines > MAX_DIFF_RATIO) return EXIT_ALLOW21;
28114
28703
  const sessionKey = deriveSessionKey3(envelope, payload);
28115
- if (hasFiredThisSession2(workspaceRoot2, sessionKey)) return EXIT_ALLOW20;
28704
+ if (hasFiredThisSession2(workspaceRoot2, sessionKey)) return EXIT_ALLOW21;
28116
28705
  markFiredThisSession2(workspaceRoot2, sessionKey);
28117
28706
  process.stdout.write(
28118
28707
  `${JSON.stringify({
@@ -28122,41 +28711,41 @@ function main44() {
28122
28711
  })}
28123
28712
  `
28124
28713
  );
28125
- return EXIT_WARN11;
28714
+ return EXIT_WARN12;
28126
28715
  } catch {
28127
- return EXIT_ALLOW20;
28716
+ return EXIT_ALLOW21;
28128
28717
  }
28129
28718
  }
28130
- function _isCliEntry34() {
28719
+ function _isCliEntry36() {
28131
28720
  if (true) {
28132
28721
  return false;
28133
28722
  }
28134
28723
  if (process.argv[1] === void 0) {
28135
28724
  return false;
28136
28725
  }
28137
- const argvUrl = pathToFileURL39(path65.resolve(process.argv[1])).href;
28726
+ const argvUrl = pathToFileURL41(path68.resolve(process.argv[1])).href;
28138
28727
  if (import.meta.url === argvUrl) {
28139
28728
  return true;
28140
28729
  }
28141
28730
  try {
28142
- const here = fs64.realpathSync(fileURLToPath46(import.meta.url));
28143
- const argv = fs64.realpathSync(path65.resolve(process.argv[1]));
28731
+ const here = fs67.realpathSync(fileURLToPath48(import.meta.url));
28732
+ const argv = fs67.realpathSync(path68.resolve(process.argv[1]));
28144
28733
  return here === argv;
28145
28734
  } catch {
28146
28735
  return false;
28147
28736
  }
28148
28737
  }
28149
- if (_isCliEntry34()) {
28150
- process.exit(main44());
28738
+ if (_isCliEntry36()) {
28739
+ process.exit(main46());
28151
28740
  }
28152
28741
 
28153
28742
  // src/scripts/hooks/reread_guard_hook.ts
28154
28743
  import * as crypto10 from "node:crypto";
28155
- import * as fs65 from "node:fs";
28156
- import * as path66 from "node:path";
28157
- import { fileURLToPath as fileURLToPath47, pathToFileURL as pathToFileURL40 } from "node:url";
28158
- var EXIT_ALLOW21 = 0;
28159
- var EXIT_WARN12 = 2;
28744
+ import * as fs68 from "node:fs";
28745
+ import * as path69 from "node:path";
28746
+ import { fileURLToPath as fileURLToPath49, pathToFileURL as pathToFileURL42 } from "node:url";
28747
+ var EXIT_ALLOW22 = 0;
28748
+ var EXIT_WARN13 = 2;
28160
28749
  var EXEMPT_PATH_PATTERNS2 = [
28161
28750
  /(^|\/)dist\//i,
28162
28751
  // dist/**
@@ -28190,11 +28779,11 @@ function deriveSessionKey4(envelope, payload) {
28190
28779
  return crypto10.createHash("sha256").update(material).digest("hex");
28191
28780
  }
28192
28781
  function ledgerFile(workspaceRoot2, sessionKey) {
28193
- return path66.join(workspaceRoot2, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
28782
+ return path69.join(workspaceRoot2, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
28194
28783
  }
28195
28784
  function readLedger(workspaceRoot2, sessionKey) {
28196
28785
  try {
28197
- const parsed = JSON.parse(fs65.readFileSync(ledgerFile(workspaceRoot2, sessionKey), "utf8"));
28786
+ const parsed = JSON.parse(fs68.readFileSync(ledgerFile(workspaceRoot2, sessionKey), "utf8"));
28198
28787
  if (!isObject9(parsed)) return emptyLedger();
28199
28788
  return {
28200
28789
  reads: isObject9(parsed["reads"]) ? parsed["reads"] : {},
@@ -28235,41 +28824,41 @@ function buildDuplicateReadLine(relPath, earlierTs) {
28235
28824
  function buildPostEditReadLine(relPath) {
28236
28825
  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.`;
28237
28826
  }
28238
- function main45() {
28827
+ function main47() {
28239
28828
  try {
28240
28829
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
28241
28830
  const event = str7(envelope["event"]);
28242
- if (event !== "" && event !== "pre_tool_use") return EXIT_ALLOW21;
28831
+ if (event !== "" && event !== "pre_tool_use") return EXIT_ALLOW22;
28243
28832
  const toolName = extractToolName3(payload);
28244
28833
  const isRead = READ_TOOLS.has(toolName);
28245
28834
  const isWrite = WRITE_TOOLS2.has(toolName);
28246
- if (!isRead && !isWrite) return EXIT_ALLOW21;
28835
+ if (!isRead && !isWrite) return EXIT_ALLOW22;
28247
28836
  const toolInput = extractToolInput2(payload);
28248
28837
  const filePath = extractFilePath2(toolInput);
28249
- if (!filePath) return EXIT_ALLOW21;
28838
+ if (!filePath) return EXIT_ALLOW22;
28250
28839
  const workspaceRoot2 = str7(envelope["workspace_root"]).trim() || process.cwd();
28251
- const absPath = path66.isAbsolute(filePath) ? filePath : path66.resolve(workspaceRoot2, filePath);
28252
- const relPath = path66.relative(workspaceRoot2, absPath);
28253
- if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW21;
28840
+ const absPath = path69.isAbsolute(filePath) ? filePath : path69.resolve(workspaceRoot2, filePath);
28841
+ const relPath = path69.relative(workspaceRoot2, absPath);
28842
+ if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW22;
28254
28843
  const sessionKey = deriveSessionKey4(envelope, payload);
28255
28844
  const ledger = readLedger(workspaceRoot2, sessionKey);
28256
28845
  const key = relPath.startsWith("..") ? absPath : relPath;
28257
28846
  if (isWrite) {
28258
28847
  ledger.writes[key] = Date.now();
28259
28848
  writeLedger(workspaceRoot2, sessionKey, ledger);
28260
- return EXIT_ALLOW21;
28849
+ return EXIT_ALLOW22;
28261
28850
  }
28262
28851
  if (isRangedRead(toolInput)) {
28263
- return EXIT_ALLOW21;
28852
+ return EXIT_ALLOW22;
28264
28853
  }
28265
28854
  let mtime;
28266
28855
  let size;
28267
28856
  try {
28268
- const st = fs65.statSync(absPath);
28857
+ const st = fs68.statSync(absPath);
28269
28858
  mtime = st.mtimeMs;
28270
28859
  size = st.size;
28271
28860
  } catch {
28272
- return EXIT_ALLOW21;
28861
+ return EXIT_ALLOW22;
28273
28862
  }
28274
28863
  const prior = ledger.reads[key];
28275
28864
  const ownWrite = ledger.writes[key];
@@ -28284,7 +28873,7 @@ function main45() {
28284
28873
  if (ownWrite !== void 0) delete ledger.writes[key];
28285
28874
  if (advisory !== null) ledger.fired[key] = true;
28286
28875
  writeLedger(workspaceRoot2, sessionKey, ledger);
28287
- if (advisory === null) return EXIT_ALLOW21;
28876
+ if (advisory === null) return EXIT_ALLOW22;
28288
28877
  process.stdout.write(
28289
28878
  `${JSON.stringify({
28290
28879
  decision: "warn",
@@ -28293,39 +28882,39 @@ function main45() {
28293
28882
  })}
28294
28883
  `
28295
28884
  );
28296
- return EXIT_WARN12;
28885
+ return EXIT_WARN13;
28297
28886
  } catch {
28298
- return EXIT_ALLOW21;
28887
+ return EXIT_ALLOW22;
28299
28888
  }
28300
28889
  }
28301
- function _isCliEntry35() {
28890
+ function _isCliEntry37() {
28302
28891
  if (true) {
28303
28892
  return false;
28304
28893
  }
28305
28894
  if (process.argv[1] === void 0) {
28306
28895
  return false;
28307
28896
  }
28308
- const argvUrl = pathToFileURL40(path66.resolve(process.argv[1])).href;
28897
+ const argvUrl = pathToFileURL42(path69.resolve(process.argv[1])).href;
28309
28898
  if (import.meta.url === argvUrl) {
28310
28899
  return true;
28311
28900
  }
28312
28901
  try {
28313
- const here = fs65.realpathSync(fileURLToPath47(import.meta.url));
28314
- const argv = fs65.realpathSync(path66.resolve(process.argv[1]));
28902
+ const here = fs68.realpathSync(fileURLToPath49(import.meta.url));
28903
+ const argv = fs68.realpathSync(path69.resolve(process.argv[1]));
28315
28904
  return here === argv;
28316
28905
  } catch {
28317
28906
  return false;
28318
28907
  }
28319
28908
  }
28320
- if (_isCliEntry35()) {
28321
- process.exit(main45());
28909
+ if (_isCliEntry37()) {
28910
+ process.exit(main47());
28322
28911
  }
28323
28912
 
28324
28913
  // src/scripts/hooks/session_eol_hook.ts
28325
- import * as fs67 from "node:fs";
28326
- import * as path69 from "node:path";
28914
+ import * as fs70 from "node:fs";
28915
+ import * as path72 from "node:path";
28327
28916
  import process11 from "node:process";
28328
- import { fileURLToPath as fileURLToPath48, pathToFileURL as pathToFileURL41 } from "node:url";
28917
+ import { fileURLToPath as fileURLToPath50, pathToFileURL as pathToFileURL43 } from "node:url";
28329
28918
 
28330
28919
  // src/config/recycle-threshold-budget.json
28331
28920
  var recycle_threshold_budget_default = {
@@ -28343,13 +28932,13 @@ var recycle_threshold_budget_default = {
28343
28932
 
28344
28933
  // src/scripts/_lib/session_eol.ts
28345
28934
  import * as crypto11 from "node:crypto";
28346
- import * as fs66 from "node:fs";
28347
- import * as path68 from "node:path";
28935
+ import * as fs69 from "node:fs";
28936
+ import * as path71 from "node:path";
28348
28937
 
28349
28938
  // src/scripts/_lib/cc_transcript.ts
28350
- import * as path67 from "node:path";
28939
+ import * as path70 from "node:path";
28351
28940
  import { homedir as homedir6 } from "node:os";
28352
- var DEFAULT_PROJECTS_ROOT = path67.join(homedir6(), ".claude", "projects");
28941
+ var DEFAULT_PROJECTS_ROOT = path70.join(homedir6(), ".claude", "projects");
28353
28942
  function billableInputTokens(u) {
28354
28943
  return u.input_tokens + u.cache_read_input_tokens + u.cache_creation_input_tokens;
28355
28944
  }
@@ -28458,17 +29047,17 @@ function scanEolSlice(text, prior) {
28458
29047
  return next;
28459
29048
  }
28460
29049
  function eolStateDir(workspaceRoot2) {
28461
- return path68.join(workspaceRoot2, "agents", "runtime", "state", "session-eol");
29050
+ return path71.join(workspaceRoot2, "agents", "runtime", "state", "session-eol");
28462
29051
  }
28463
29052
  function eolStateFile(workspaceRoot2, sessionKey) {
28464
- return path68.join(eolStateDir(workspaceRoot2), `${sessionKey}.json`);
29053
+ return path71.join(eolStateDir(workspaceRoot2), `${sessionKey}.json`);
28465
29054
  }
28466
29055
  function eolSessionKey(raw) {
28467
29056
  return crypto11.createHash("sha256").update(raw || "unknown-session").digest("hex");
28468
29057
  }
28469
29058
  function readNewCompleteLines(filePath, fromByte) {
28470
29059
  try {
28471
- const { size } = fs66.statSync(filePath);
29060
+ const { size } = fs69.statSync(filePath);
28472
29061
  if (size < fromByte) {
28473
29062
  return { text: "", nextOffset: 0, truncated: true };
28474
29063
  }
@@ -28477,11 +29066,11 @@ function readNewCompleteLines(filePath, fromByte) {
28477
29066
  }
28478
29067
  const length = size - fromByte;
28479
29068
  const buffer = Buffer.alloc(length);
28480
- const fd = fs66.openSync(filePath, "r");
29069
+ const fd = fs69.openSync(filePath, "r");
28481
29070
  try {
28482
- fs66.readSync(fd, buffer, 0, length, fromByte);
29071
+ fs69.readSync(fd, buffer, 0, length, fromByte);
28483
29072
  } finally {
28484
- fs66.closeSync(fd);
29073
+ fs69.closeSync(fd);
28485
29074
  }
28486
29075
  const lastNewline = buffer.lastIndexOf(10);
28487
29076
  if (lastNewline === -1) {
@@ -28498,9 +29087,9 @@ function readNewCompleteLines(filePath, fromByte) {
28498
29087
  }
28499
29088
 
28500
29089
  // src/scripts/hooks/session_eol_hook.ts
28501
- var EXIT_WARN13 = 2;
29090
+ var EXIT_WARN14 = 2;
28502
29091
  var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
28503
- var CONTEXT_FILL_REL = path69.join("agents", "runtime", "state", "context-fill.json");
29092
+ var CONTEXT_FILL_REL = path72.join("agents", "runtime", "state", "context-fill.json");
28504
29093
  function str8(value) {
28505
29094
  return typeof value === "string" ? value : "";
28506
29095
  }
@@ -28512,7 +29101,7 @@ function deriveSessionKey5(envelope, payload) {
28512
29101
  }
28513
29102
  function readState3(file) {
28514
29103
  try {
28515
- const parsed = JSON.parse(fs67.readFileSync(file, "utf-8"));
29104
+ const parsed = JSON.parse(fs70.readFileSync(file, "utf-8"));
28516
29105
  if (parsed && typeof parsed === "object" && parsed.schema_version === 1 && parsed.counters && typeof parsed.counters.scanned_bytes === "number") {
28517
29106
  return {
28518
29107
  schema_version: 1,
@@ -28533,10 +29122,10 @@ function readState3(file) {
28533
29122
  };
28534
29123
  }
28535
29124
  function envelopeExists(workspaceRoot2, since = null) {
28536
- const target = path69.join(workspaceRoot2, RECYCLE_ENVELOPE_REL);
29125
+ const target = path72.join(workspaceRoot2, RECYCLE_ENVELOPE_REL);
28537
29126
  let raw;
28538
29127
  try {
28539
- raw = fs67.readFileSync(target, "utf-8");
29128
+ raw = fs70.readFileSync(target, "utf-8");
28540
29129
  } catch (exc) {
28541
29130
  return exc?.code !== "ENOENT";
28542
29131
  }
@@ -28550,7 +29139,7 @@ function envelopeExists(workspaceRoot2, since = null) {
28550
29139
  }
28551
29140
  }
28552
29141
  function buildMissingEnvelopeLine(workspaceRoot2) {
28553
- return `recycle advised earlier, but no envelope exists at ${path69.join(workspaceRoot2, RECYCLE_ENVELOPE_REL)} \u2014 /clear now starts the successor from nothing. Re-run \`agent-config session:recycle\` and check that it prints the absolute path it wrote before clearing.`;
29142
+ return `recycle advised earlier, but no envelope exists at ${path72.join(workspaceRoot2, RECYCLE_ENVELOPE_REL)} \u2014 /clear now starts the successor from nothing. Re-run \`agent-config session:recycle\` and check that it prints the absolute path it wrote before clearing.`;
28554
29143
  }
28555
29144
  function readThresholdTokens() {
28556
29145
  const override = process11.env[THRESHOLD_OVERRIDE_ENV];
@@ -28566,7 +29155,7 @@ function buildAdvisoryLine3(tokens, threshold) {
28566
29155
  }
28567
29156
  function writeContextFill(workspaceRoot2, tokens, threshold, ts) {
28568
29157
  try {
28569
- atomic_write_json(path69.join(workspaceRoot2, CONTEXT_FILL_REL), {
29158
+ atomic_write_json(path72.join(workspaceRoot2, CONTEXT_FILL_REL), {
28570
29159
  schema_version: 1,
28571
29160
  final_context_tokens: tokens,
28572
29161
  recycle_threshold_tokens: threshold,
@@ -28576,7 +29165,7 @@ function writeContextFill(workspaceRoot2, tokens, threshold, ts) {
28576
29165
  } catch {
28577
29166
  }
28578
29167
  }
28579
- function main46() {
29168
+ function main48() {
28580
29169
  const [envelope, payload] = unwrap(readHookStdin(), "claude");
28581
29170
  const event = String(envelope["event"] ?? "");
28582
29171
  if (event !== "" && event !== "stop") {
@@ -28633,7 +29222,7 @@ function main46() {
28633
29222
  })}
28634
29223
  `
28635
29224
  );
28636
- return EXIT_WARN13;
29225
+ return EXIT_WARN14;
28637
29226
  }
28638
29227
  if (shouldWarnMissing) {
28639
29228
  process11.stdout.write(
@@ -28644,42 +29233,42 @@ function main46() {
28644
29233
  })}
28645
29234
  `
28646
29235
  );
28647
- return EXIT_WARN13;
29236
+ return EXIT_WARN14;
28648
29237
  }
28649
29238
  return 0;
28650
29239
  }
28651
- function _isCliEntry36() {
29240
+ function _isCliEntry38() {
28652
29241
  if (true) {
28653
29242
  return false;
28654
29243
  }
28655
29244
  if (process11.argv[1] === void 0) {
28656
29245
  return false;
28657
29246
  }
28658
- const argvUrl = pathToFileURL41(path69.resolve(process11.argv[1])).href;
29247
+ const argvUrl = pathToFileURL43(path72.resolve(process11.argv[1])).href;
28659
29248
  if (import.meta.url === argvUrl) {
28660
29249
  return true;
28661
29250
  }
28662
29251
  try {
28663
- const here = fs67.realpathSync(fileURLToPath48(import.meta.url));
28664
- const argv = fs67.realpathSync(path69.resolve(process11.argv[1]));
29252
+ const here = fs70.realpathSync(fileURLToPath50(import.meta.url));
29253
+ const argv = fs70.realpathSync(path72.resolve(process11.argv[1]));
28665
29254
  return here === argv;
28666
29255
  } catch {
28667
29256
  return false;
28668
29257
  }
28669
29258
  }
28670
- if (_isCliEntry36()) {
28671
- process11.exit(main46());
29259
+ if (_isCliEntry38()) {
29260
+ process11.exit(main48());
28672
29261
  }
28673
29262
 
28674
29263
  // src/scripts/hooks/tool_result_bytes_hook.ts
28675
- import * as fs68 from "node:fs";
28676
- import * as path70 from "node:path";
28677
- import { fileURLToPath as fileURLToPath49, pathToFileURL as pathToFileURL42 } from "node:url";
28678
- var EXIT_ALLOW22 = 0;
29264
+ import * as fs71 from "node:fs";
29265
+ import * as path73 from "node:path";
29266
+ import { fileURLToPath as fileURLToPath51, pathToFileURL as pathToFileURL44 } from "node:url";
29267
+ var EXIT_ALLOW23 = 0;
28679
29268
  function isObject10(v) {
28680
29269
  return typeof v === "object" && v !== null && !Array.isArray(v);
28681
29270
  }
28682
- var CENSUS_FILE = path70.join("agents", "runtime", "state", "tool-result-census.jsonl");
29271
+ var CENSUS_FILE = path73.join("agents", "runtime", "state", "tool-result-census.jsonl");
28683
29272
  var RESULT_KEYS = ["tool_response", "toolResponse", "tool_result", "toolUseResult"];
28684
29273
  function _resultBytes(payload) {
28685
29274
  for (const key of RESULT_KEYS) {
@@ -28712,19 +29301,19 @@ function unwrapPayload3(envelope) {
28712
29301
  return isObject10(inner) ? inner : envelope;
28713
29302
  }
28714
29303
  function censusFile(consumerRoot) {
28715
- return path70.join(consumerRoot, CENSUS_FILE);
29304
+ return path73.join(consumerRoot, CENSUS_FILE);
28716
29305
  }
28717
29306
  function _appendCensusLine(consumerRoot, line) {
28718
29307
  if (is_replay_mode()) return;
28719
29308
  const file = censusFile(consumerRoot);
28720
- fs68.mkdirSync(path70.dirname(file), { recursive: true });
28721
- fs68.appendFileSync(file, `${JSON.stringify(line)}
29309
+ fs71.mkdirSync(path73.dirname(file), { recursive: true });
29310
+ fs71.appendFileSync(file, `${JSON.stringify(line)}
28722
29311
  `, "utf8");
28723
29312
  }
28724
29313
  function processEnvelope3(envelope, consumerRoot) {
28725
29314
  try {
28726
- if (!isObject10(envelope)) return EXIT_ALLOW22;
28727
- if (envelope["event"] !== "post_tool_use") return EXIT_ALLOW22;
29315
+ if (!isObject10(envelope)) return EXIT_ALLOW23;
29316
+ if (envelope["event"] !== "post_tool_use") return EXIT_ALLOW23;
28728
29317
  const payload = unwrapPayload3(envelope);
28729
29318
  const bytes = _resultBytes(payload);
28730
29319
  _appendCensusLine(consumerRoot, {
@@ -28734,9 +29323,9 @@ function processEnvelope3(envelope, consumerRoot) {
28734
29323
  measurable: bytes !== null
28735
29324
  });
28736
29325
  } catch {
28737
- return EXIT_ALLOW22;
29326
+ return EXIT_ALLOW23;
28738
29327
  }
28739
- return EXIT_ALLOW22;
29328
+ return EXIT_ALLOW23;
28740
29329
  }
28741
29330
  function resolveConsumerRoot2(envelope) {
28742
29331
  if (isObject10(envelope)) {
@@ -28749,36 +29338,36 @@ function resolveConsumerRoot2(envelope) {
28749
29338
  }
28750
29339
  return process.cwd();
28751
29340
  }
28752
- function main47() {
29341
+ function main49() {
28753
29342
  const raw = readHookStdin();
28754
29343
  let envelope = {};
28755
29344
  try {
28756
29345
  envelope = raw.trim() ? JSON.parse(raw) : {};
28757
29346
  } catch {
28758
- return EXIT_ALLOW22;
29347
+ return EXIT_ALLOW23;
28759
29348
  }
28760
29349
  return processEnvelope3(envelope, resolveConsumerRoot2(envelope));
28761
29350
  }
28762
- function _isCliEntry37() {
29351
+ function _isCliEntry39() {
28763
29352
  if (true) {
28764
29353
  return false;
28765
29354
  }
28766
29355
  if (process.argv[1] === void 0) return false;
28767
- const argvUrl = pathToFileURL42(path70.resolve(process.argv[1])).href;
29356
+ const argvUrl = pathToFileURL44(path73.resolve(process.argv[1])).href;
28768
29357
  if (import.meta.url === argvUrl) return true;
28769
29358
  try {
28770
- return fs68.realpathSync(fileURLToPath49(import.meta.url)) === fs68.realpathSync(path70.resolve(process.argv[1]));
29359
+ return fs71.realpathSync(fileURLToPath51(import.meta.url)) === fs71.realpathSync(path73.resolve(process.argv[1]));
28771
29360
  } catch {
28772
29361
  return false;
28773
29362
  }
28774
29363
  }
28775
- if (_isCliEntry37()) process.exit(main47());
29364
+ if (_isCliEntry39()) process.exit(main49());
28776
29365
 
28777
29366
  // src/scripts/hooks/spawn_guard_shadow_hook.ts
28778
- import * as fs69 from "node:fs";
28779
- import * as path71 from "node:path";
28780
- import { fileURLToPath as fileURLToPath50, pathToFileURL as pathToFileURL43 } from "node:url";
28781
- var EXIT_ALLOW23 = 0;
29367
+ import * as fs72 from "node:fs";
29368
+ import * as path74 from "node:path";
29369
+ import { fileURLToPath as fileURLToPath52, pathToFileURL as pathToFileURL45 } from "node:url";
29370
+ var EXIT_ALLOW24 = 0;
28782
29371
  function isObject11(v) {
28783
29372
  return typeof v === "object" && v !== null && !Array.isArray(v);
28784
29373
  }
@@ -28806,10 +29395,10 @@ function extractToolName4(payload) {
28806
29395
  }
28807
29396
  function processEnvelope4(envelope, consumerRoot) {
28808
29397
  try {
28809
- if (!isObject11(envelope)) return EXIT_ALLOW23;
29398
+ if (!isObject11(envelope)) return EXIT_ALLOW24;
28810
29399
  const payload = unwrapPayload4(envelope);
28811
29400
  const toolName = extractToolName4(payload);
28812
- if (toolName === null || !DISPATCH_TOOL_NAMES2.has(toolName)) return EXIT_ALLOW23;
29401
+ if (toolName === null || !DISPATCH_TOOL_NAMES2.has(toolName)) return EXIT_ALLOW24;
28813
29402
  const stats = openRecordStats(consumerRoot);
28814
29403
  const depthEstimate = stats.max_depth + 1;
28815
29404
  const verdicts = evaluateCandidates(depthEstimate, stats.open_count);
@@ -28837,32 +29426,32 @@ function processEnvelope4(envelope, consumerRoot) {
28837
29426
  posture: "shadow"
28838
29427
  });
28839
29428
  } catch {
28840
- return EXIT_ALLOW23;
29429
+ return EXIT_ALLOW24;
28841
29430
  }
28842
- return EXIT_ALLOW23;
29431
+ return EXIT_ALLOW24;
28843
29432
  }
28844
- function main48() {
29433
+ function main50() {
28845
29434
  const raw = readHookStdin();
28846
29435
  let envelope = {};
28847
29436
  try {
28848
29437
  envelope = raw.trim() ? JSON.parse(raw) : {};
28849
29438
  } catch {
28850
- return EXIT_ALLOW23;
29439
+ return EXIT_ALLOW24;
28851
29440
  }
28852
29441
  return processEnvelope4(envelope, resolveConsumerRoot(envelope));
28853
29442
  }
28854
- function _isCliEntry38() {
29443
+ function _isCliEntry40() {
28855
29444
  if (true) return false;
28856
29445
  if (process.argv[1] === void 0) return false;
28857
- const argvUrl = pathToFileURL43(path71.resolve(process.argv[1])).href;
29446
+ const argvUrl = pathToFileURL45(path74.resolve(process.argv[1])).href;
28858
29447
  if (import.meta.url === argvUrl) return true;
28859
29448
  try {
28860
- return fs69.realpathSync(fileURLToPath50(import.meta.url)) === fs69.realpathSync(path71.resolve(process.argv[1]));
29449
+ return fs72.realpathSync(fileURLToPath52(import.meta.url)) === fs72.realpathSync(path74.resolve(process.argv[1]));
28861
29450
  } catch {
28862
29451
  return false;
28863
29452
  }
28864
29453
  }
28865
- if (_isCliEntry38()) process.exit(main48());
29454
+ if (_isCliEntry40()) process.exit(main50());
28866
29455
 
28867
29456
  // src/scripts/hooks/concern_registry.ts
28868
29457
  var CONCERN_REGISTRY = {
@@ -28899,14 +29488,15 @@ var CONCERN_REGISTRY = {
28899
29488
  "src/scripts/hooks/ui_route_nudge_hook.ts": main37,
28900
29489
  "src/scripts/hooks/orchestration_record_hook.ts": main39,
28901
29490
  "src/scripts/hooks/delegation_nudge_hook.ts": main40,
28902
- "src/scripts/hooks/end_review_nudge_hook.ts": main41,
28903
- "src/scripts/hooks/turn_end_gate_hook.ts": main43,
28904
- "src/scripts/hooks/edit_shape_hook.ts": main44,
28905
- "src/scripts/hooks/reread_guard_hook.ts": main45,
28906
- "src/scripts/hooks/session_eol_hook.ts": main46,
28907
- "src/scripts/hooks/subagent_ledger_hook.ts": main42,
28908
- "src/scripts/hooks/tool_result_bytes_hook.ts": main47,
28909
- "src/scripts/hooks/spawn_guard_shadow_hook.ts": main48
29491
+ "src/scripts/hooks/skill_route_hook.ts": main42,
29492
+ "src/scripts/hooks/end_review_nudge_hook.ts": main43,
29493
+ "src/scripts/hooks/turn_end_gate_hook.ts": main45,
29494
+ "src/scripts/hooks/edit_shape_hook.ts": main46,
29495
+ "src/scripts/hooks/reread_guard_hook.ts": main47,
29496
+ "src/scripts/hooks/session_eol_hook.ts": main48,
29497
+ "src/scripts/hooks/subagent_ledger_hook.ts": main44,
29498
+ "src/scripts/hooks/tool_result_bytes_hook.ts": main49,
29499
+ "src/scripts/hooks/spawn_guard_shadow_hook.ts": main50
28910
29500
  };
28911
29501
 
28912
29502
  // src/scripts/hooks/host_semantics.ts
@@ -28962,14 +29552,14 @@ function emitFor(platform, event, severity, reasons, legacyExit) {
28962
29552
 
28963
29553
  // src/scripts/hooks/dispatch_hook.ts
28964
29554
  var _IN_BUNDLE = true;
28965
- var REPO_ROOT = path72.resolve(
28966
- path72.dirname(fileURLToPath51(import.meta.url)),
29555
+ var REPO_ROOT = path75.resolve(
29556
+ path75.dirname(fileURLToPath53(import.meta.url)),
28967
29557
  ..._IN_BUNDLE ? ["..", ".."] : ["..", "..", ".."]
28968
29558
  );
28969
- var MANIFEST_PATH = path72.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
28970
- var EXIT_ALLOW24 = 0;
29559
+ var MANIFEST_PATH = path75.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
29560
+ var EXIT_ALLOW25 = 0;
28971
29561
  var EXIT_BLOCK5 = 1;
28972
- var EXIT_WARN14 = 2;
29562
+ var EXIT_WARN15 = 2;
28973
29563
  var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
28974
29564
  "session_start",
28975
29565
  "session_end",
@@ -28983,11 +29573,11 @@ var EVENT_VOCABULARY = /* @__PURE__ */ new Set([
28983
29573
  "subagent_stop"
28984
29574
  ]);
28985
29575
  var _SEVERITY_BY_EXIT = {
28986
- [EXIT_ALLOW24]: "allow",
29576
+ [EXIT_ALLOW25]: "allow",
28987
29577
  [EXIT_BLOCK5]: "block",
28988
- [EXIT_WARN14]: "warn"
29578
+ [EXIT_WARN15]: "warn"
28989
29579
  };
28990
- function _isObject14(v) {
29580
+ function _isObject15(v) {
28991
29581
  return typeof v === "object" && v !== null && !Array.isArray(v);
28992
29582
  }
28993
29583
  function _severity_for(rc) {
@@ -29017,16 +29607,16 @@ function _parse_concern_stdout(stdout_text) {
29017
29607
  } catch {
29018
29608
  return { _raw_stdout: text.slice(0, 500) };
29019
29609
  }
29020
- return _isObject14(parsed) ? parsed : { _raw: parsed };
29610
+ return _isObject15(parsed) ? parsed : { _raw: parsed };
29021
29611
  }
29022
29612
  function _load_yaml3(p) {
29023
- const text = fs70.readFileSync(p, "utf-8");
29613
+ const text = fs73.readFileSync(p, "utf-8");
29024
29614
  const data = (0, import_yaml6.parse)(text, { version: "1.1" });
29025
- return _isObject14(data) ? data : {};
29615
+ return _isObject15(data) ? data : {};
29026
29616
  }
29027
29617
  function _payload_tool_name(envelope) {
29028
29618
  const payload = envelope["payload"];
29029
- if (!_isObject14(payload)) {
29619
+ if (!_isObject15(payload)) {
29030
29620
  return "";
29031
29621
  }
29032
29622
  const raw = payload["tool_name"];
@@ -29054,8 +29644,8 @@ function _role_drop_set(manifest, role, event) {
29054
29644
  return /* @__PURE__ */ new Set();
29055
29645
  }
29056
29646
  const rolesRaw = manifest["roles"];
29057
- const roleSpec = _isObject14(rolesRaw) ? rolesRaw[role] : void 0;
29058
- if (!_isObject14(roleSpec)) {
29647
+ const roleSpec = _isObject15(rolesRaw) ? rolesRaw[role] : void 0;
29648
+ if (!_isObject15(roleSpec)) {
29059
29649
  return /* @__PURE__ */ new Set();
29060
29650
  }
29061
29651
  const drop = roleSpec["drop"];
@@ -29066,28 +29656,28 @@ function _role_drop_set(manifest, role, event) {
29066
29656
  }
29067
29657
  function _resolve_concerns(manifest, platform, event, role = "orchestrator") {
29068
29658
  const platformsRaw = manifest["platforms"];
29069
- const platforms = _isObject14(platformsRaw) ? platformsRaw : {};
29659
+ const platforms = _isObject15(platformsRaw) ? platformsRaw : {};
29070
29660
  const block = platforms[platform];
29071
29661
  if (!block) {
29072
29662
  return [];
29073
29663
  }
29074
- if (_isObject14(block) && block["fallback_only"]) {
29664
+ if (_isObject15(block) && block["fallback_only"]) {
29075
29665
  return [];
29076
29666
  }
29077
- const names = _isObject14(block) ? block[event] : null;
29667
+ const names = _isObject15(block) ? block[event] : null;
29078
29668
  if (!Array.isArray(names)) {
29079
29669
  return [];
29080
29670
  }
29081
29671
  const dropped = _role_drop_set(manifest, role, event);
29082
29672
  const concernsRaw = manifest["concerns"];
29083
- const concerns_def = _isObject14(concernsRaw) ? concernsRaw : {};
29673
+ const concerns_def = _isObject15(concernsRaw) ? concernsRaw : {};
29084
29674
  const out = [];
29085
29675
  for (const name of names) {
29086
29676
  if (typeof name === "string" && dropped.has(name)) {
29087
29677
  continue;
29088
29678
  }
29089
29679
  const spec = typeof name === "string" ? concerns_def[name] : void 0;
29090
- if (!spec || !_isObject14(spec)) {
29680
+ if (!spec || !_isObject15(spec)) {
29091
29681
  process.stderr.write(
29092
29682
  `dispatch_hook: unknown concern '${String(name)}' in manifest
29093
29683
  `
@@ -29177,7 +29767,7 @@ function _maybe_capture_payload(args, payload_text) {
29177
29767
  }
29178
29768
  try {
29179
29769
  const target = _expanduser3(capture_dir);
29180
- fs70.mkdirSync(target, { recursive: true });
29770
+ fs73.mkdirSync(target, { recursive: true });
29181
29771
  let payload;
29182
29772
  try {
29183
29773
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
@@ -29194,8 +29784,8 @@ function _maybe_capture_payload(args, payload_text) {
29194
29784
  const ts = Date.now();
29195
29785
  const native = (args.native_event || args.event).replace(/\//g, "_");
29196
29786
  const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
29197
- fs70.writeFileSync(
29198
- path72.join(target, fname),
29787
+ fs73.writeFileSync(
29788
+ path75.join(target, fname),
29199
29789
  _py_json_dumps2(record, 2) + "\n",
29200
29790
  { encoding: "utf-8" }
29201
29791
  );
@@ -29206,7 +29796,7 @@ function _maybe_capture_payload(args, payload_text) {
29206
29796
  function _expanduser3(p) {
29207
29797
  if (p === "~" || p.startsWith("~/")) {
29208
29798
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
29209
- return path72.join(home, p.slice(1));
29799
+ return path75.join(home, p.slice(1));
29210
29800
  }
29211
29801
  return p;
29212
29802
  }
@@ -29214,7 +29804,7 @@ function _build_envelope(args, payload_text) {
29214
29804
  let payload;
29215
29805
  try {
29216
29806
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
29217
- if (!_isObject14(payload)) {
29807
+ if (!_isObject15(payload)) {
29218
29808
  payload = { _raw: payload };
29219
29809
  }
29220
29810
  } catch {
@@ -29238,25 +29828,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
29238
29828
  const walkUp = (start) => {
29239
29829
  let dir = start;
29240
29830
  for (; ; ) {
29241
- const candidate = path72.join(dir, "node_modules", ".bin", binName);
29831
+ const candidate = path75.join(dir, "node_modules", ".bin", binName);
29242
29832
  if (_isFile7(candidate)) {
29243
29833
  return candidate;
29244
29834
  }
29245
- const parent = path72.dirname(dir);
29835
+ const parent = path75.dirname(dir);
29246
29836
  if (parent === dir) {
29247
29837
  return null;
29248
29838
  }
29249
29839
  dir = parent;
29250
29840
  }
29251
29841
  };
29252
- const tsx = walkUp(path72.dirname(scriptPath)) ?? walkUp(path72.dirname(fileURLToPath51(import.meta.url)));
29842
+ const tsx = walkUp(path75.dirname(scriptPath)) ?? walkUp(path75.dirname(fileURLToPath53(import.meta.url)));
29253
29843
  if (tsx !== null) {
29254
29844
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
29255
29845
  }
29256
29846
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
29257
29847
  }
29258
29848
  function _run_concern_inproc(main_fn, concern, envelope) {
29259
- const scriptAbs = path72.join(REPO_ROOT, String(concern["script"]));
29849
+ const scriptAbs = path75.join(REPO_ROOT, String(concern["script"]));
29260
29850
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
29261
29851
  argsList.push("--platform", String(envelope["platform"] || "generic"));
29262
29852
  const workspace = String(envelope["workspace_root"] || process.cwd());
@@ -29333,7 +29923,7 @@ function _run_concern(concern, envelope) {
29333
29923
  return _run_concern_inproc(inproc, concern, envelope);
29334
29924
  }
29335
29925
  }
29336
- const script = path72.join(REPO_ROOT, String(concern["script"]));
29926
+ const script = path75.join(REPO_ROOT, String(concern["script"]));
29337
29927
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
29338
29928
  const cmd = [script, ...argsList];
29339
29929
  cmd.push("--platform", String(envelope["platform"] || "generic"));
@@ -29390,7 +29980,7 @@ function _run_concern(concern, envelope) {
29390
29980
  }
29391
29981
  function _isFile7(p) {
29392
29982
  try {
29393
- return fs70.statSync(p).isFile();
29983
+ return fs73.statSync(p).isFile();
29394
29984
  } catch {
29395
29985
  return false;
29396
29986
  }
@@ -29402,20 +29992,20 @@ function _reduce(rcs) {
29402
29992
  if (rcs.some((rc) => rc === EXIT_BLOCK5)) {
29403
29993
  return EXIT_BLOCK5;
29404
29994
  }
29405
- if (rcs.some((rc) => rc === EXIT_WARN14)) {
29406
- return EXIT_WARN14;
29995
+ if (rcs.some((rc) => rc === EXIT_WARN15)) {
29996
+ return EXIT_WARN15;
29407
29997
  }
29408
- return EXIT_ALLOW24;
29998
+ return EXIT_ALLOW25;
29409
29999
  }
29410
30000
  function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
29411
30001
  if (is_replay_mode()) {
29412
30002
  return;
29413
30003
  }
29414
30004
  const workspace = String(envelope["workspace_root"] || process.cwd());
29415
- const state_root = path72.join(workspace, "agents", "runtime", "state");
30005
+ const state_root = path75.join(workspace, "agents", "runtime", "state");
29416
30006
  const fb_dir = feedback_dir(state_root, session_id);
29417
30007
  try {
29418
- fs70.mkdirSync(fb_dir, { recursive: true });
30008
+ fs73.mkdirSync(fb_dir, { recursive: true });
29419
30009
  } catch (exc) {
29420
30010
  const msg = exc instanceof Error ? exc.message : String(exc);
29421
30011
  process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
@@ -29423,7 +30013,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
29423
30013
  return;
29424
30014
  }
29425
30015
  for (const entry of entries) {
29426
- const target = path72.join(fb_dir, `${entry["concern"]}.json`);
30016
+ const target = path75.join(fb_dir, `${entry["concern"]}.json`);
29427
30017
  try {
29428
30018
  atomic_write_json(target, entry);
29429
30019
  } catch (exc) {
@@ -29463,7 +30053,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
29463
30053
  })
29464
30054
  };
29465
30055
  try {
29466
- atomic_write_json(path72.join(fb_dir, "summary.json"), summary);
30056
+ atomic_write_json(path75.join(fb_dir, "summary.json"), summary);
29467
30057
  } catch (exc) {
29468
30058
  const msg = exc instanceof Error ? exc.message : String(exc);
29469
30059
  process.stderr.write(`dispatch_hook: summary write failed: ${msg}
@@ -29473,17 +30063,17 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
29473
30063
  function _record_rule_trips(envelope, entries) {
29474
30064
  if (is_replay_mode()) return;
29475
30065
  const tripped = entries.filter(
29476
- (e) => e["exit_code"] === EXIT_BLOCK5 || e["exit_code"] === EXIT_WARN14
30066
+ (e) => e["exit_code"] === EXIT_BLOCK5 || e["exit_code"] === EXIT_WARN15
29477
30067
  );
29478
30068
  if (tripped.length === 0) return;
29479
30069
  try {
29480
30070
  const workspace = String(envelope["workspace_root"] || process.cwd());
29481
- const state_dir = path72.join(workspace, "agents", "runtime", "state");
29482
- const target = path72.join(state_dir, "rule-trips.json");
29483
- fs70.mkdirSync(state_dir, { recursive: true });
30071
+ const state_dir = path75.join(workspace, "agents", "runtime", "state");
30072
+ const target = path75.join(state_dir, "rule-trips.json");
30073
+ fs73.mkdirSync(state_dir, { recursive: true });
29484
30074
  let doc = { schema_version: 1, concerns: {} };
29485
30075
  try {
29486
- const parsed = JSON.parse(fs70.readFileSync(target, "utf-8"));
30076
+ const parsed = JSON.parse(fs73.readFileSync(target, "utf-8"));
29487
30077
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) doc = parsed;
29488
30078
  } catch {
29489
30079
  }
@@ -29494,7 +30084,7 @@ function _record_rule_trips(envelope, entries) {
29494
30084
  const prev = concerns[name] ?? { block: 0, warn: 0 };
29495
30085
  concerns[name] = {
29496
30086
  block: (Number(prev["block"]) || 0) + (e["exit_code"] === EXIT_BLOCK5 ? 1 : 0),
29497
- warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN14 ? 1 : 0),
30087
+ warn: (Number(prev["warn"]) || 0) + (e["exit_code"] === EXIT_WARN15 ? 1 : 0),
29498
30088
  last_trip: today
29499
30089
  };
29500
30090
  }
@@ -29582,7 +30172,7 @@ function _parse_args(argv) {
29582
30172
  }
29583
30173
  return args;
29584
30174
  }
29585
- function main49(argv) {
30175
+ function main51(argv) {
29586
30176
  const args = _parse_args(argv ?? process.argv.slice(2));
29587
30177
  if (args.project_dir) {
29588
30178
  const project_dir = _expanduser3(args.project_dir);
@@ -29600,13 +30190,13 @@ function main49(argv) {
29600
30190
  `dispatch_hook: unknown event '${args.event}'; allowed: ${_sortedRepr(EVENT_VOCABULARY)}
29601
30191
  `
29602
30192
  );
29603
- return EXIT_ALLOW24;
30193
+ return EXIT_ALLOW25;
29604
30194
  }
29605
30195
  const manifest_path = args.manifest;
29606
- if (!fs70.existsSync(manifest_path)) {
30196
+ if (!fs73.existsSync(manifest_path)) {
29607
30197
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
29608
30198
  `);
29609
- return EXIT_ALLOW24;
30199
+ return EXIT_ALLOW25;
29610
30200
  }
29611
30201
  const manifest = _load_yaml3(manifest_path);
29612
30202
  if (args.min_version) {
@@ -29630,10 +30220,10 @@ function main49(argv) {
29630
30220
  concerns: concerns.map((c) => c["name"])
29631
30221
  };
29632
30222
  process.stdout.write(_py_json_dumps2(plan, 2) + "\n");
29633
- return EXIT_ALLOW24;
30223
+ return EXIT_ALLOW25;
29634
30224
  }
29635
30225
  if (concerns.length === 0) {
29636
- return EXIT_ALLOW24;
30226
+ return EXIT_ALLOW25;
29637
30227
  }
29638
30228
  const envelope = _build_envelope(args, payload_text);
29639
30229
  const session_id = _resolve_session_id(envelope);
@@ -29653,7 +30243,7 @@ function main49(argv) {
29653
30243
  const raw_rc = rc;
29654
30244
  if (rc >= 3) {
29655
30245
  if (!concern["fail_closed"]) {
29656
- rc = EXIT_ALLOW24;
30246
+ rc = EXIT_ALLOW25;
29657
30247
  } else {
29658
30248
  rc = EXIT_BLOCK5;
29659
30249
  }
@@ -29666,7 +30256,7 @@ function main49(argv) {
29666
30256
  `dispatch_hook: concern '${String(concern["name"])}' is declared severity: advisory but returned BLOCK \u2014 downgraded to warn.
29667
30257
  `
29668
30258
  );
29669
- rc = EXIT_WARN14;
30259
+ rc = EXIT_WARN15;
29670
30260
  }
29671
30261
  rcs.push(rc);
29672
30262
  const reply = _parse_concern_stdout(stdout_text);
@@ -29676,7 +30266,7 @@ function main49(argv) {
29676
30266
  if (message) {
29677
30267
  concern_messages.push({ rc, text: message });
29678
30268
  }
29679
- if (args.event === "session_start" && rc === EXIT_ALLOW24 && typeof reply["context"] === "string" && reply["context"].trim()) {
30269
+ if (args.event === "session_start" && rc === EXIT_ALLOW25 && typeof reply["context"] === "string" && reply["context"].trim()) {
29680
30270
  context_blocks.push(reply["context"].trim());
29681
30271
  }
29682
30272
  feedback_entries.push({
@@ -29695,7 +30285,7 @@ function main49(argv) {
29695
30285
  const final_rc = _reduce(rcs);
29696
30286
  _write_feedback(envelope, session_id, feedback_entries, final_rc, started_at);
29697
30287
  _record_rule_trips(envelope, feedback_entries);
29698
- if (context_blocks.length > 0 && final_rc === EXIT_ALLOW24) {
30288
+ if (context_blocks.length > 0 && final_rc === EXIT_ALLOW25) {
29699
30289
  process.stdout.write(context_blocks.join("\n\n") + "\n");
29700
30290
  }
29701
30291
  const decidingReasons = concern_messages.filter((m) => m.rc === final_rc).map((m) => m.text);
@@ -29716,7 +30306,7 @@ function main49(argv) {
29716
30306
  }
29717
30307
  function _isDir4(p) {
29718
30308
  try {
29719
- return fs70.statSync(p).isDirectory();
30309
+ return fs73.statSync(p).isDirectory();
29720
30310
  } catch {
29721
30311
  return false;
29722
30312
  }
@@ -29727,41 +30317,41 @@ function _sortedRepr(s) {
29727
30317
  }
29728
30318
  function _readStdin14() {
29729
30319
  try {
29730
- return fs70.readFileSync(0, "utf-8");
30320
+ return fs73.readFileSync(0, "utf-8");
29731
30321
  } catch {
29732
30322
  return "";
29733
30323
  }
29734
30324
  }
29735
- function _isCliEntry39() {
30325
+ function _isCliEntry41() {
29736
30326
  if (true) {
29737
30327
  return false;
29738
30328
  }
29739
30329
  if (process.argv[1] === void 0) {
29740
30330
  return false;
29741
30331
  }
29742
- const argvUrl = pathToFileURL44(path72.resolve(process.argv[1])).href;
30332
+ const argvUrl = pathToFileURL46(path75.resolve(process.argv[1])).href;
29743
30333
  if (import.meta.url === argvUrl) {
29744
30334
  return true;
29745
30335
  }
29746
30336
  try {
29747
- const here = fs70.realpathSync(fileURLToPath51(import.meta.url));
29748
- const argv = fs70.realpathSync(path72.resolve(process.argv[1]));
30337
+ const here = fs73.realpathSync(fileURLToPath53(import.meta.url));
30338
+ const argv = fs73.realpathSync(path75.resolve(process.argv[1]));
29749
30339
  return here === argv;
29750
30340
  } catch {
29751
30341
  return false;
29752
30342
  }
29753
30343
  }
29754
- var isCliEntry13 = _isCliEntry39();
30344
+ var isCliEntry13 = _isCliEntry41();
29755
30345
  if (isCliEntry13) {
29756
- process.exit(main49(process.argv.slice(2)));
30346
+ process.exit(main51(process.argv.slice(2)));
29757
30347
  }
29758
30348
 
29759
30349
  // src/scripts/hooks/dispatch_entry.ts
29760
- var _selfPath = fileURLToPath52(import.meta.url);
29761
- var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path73.resolve(process.argv[1]) === path73.resolve(_selfPath);
30350
+ var _selfPath = fileURLToPath54(import.meta.url);
30351
+ var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path76.resolve(process.argv[1]) === path76.resolve(_selfPath);
29762
30352
  if (_invokedDirectly2) {
29763
- process.exitCode = main49(process.argv.slice(2));
30353
+ process.exitCode = main51(process.argv.slice(2));
29764
30354
  }
29765
30355
  export {
29766
- main49 as main
30356
+ main51 as main
29767
30357
  };