@event4u/agent-config 14.22.0 → 14.23.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 (111) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +159 -380
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/pr/merge.md +47 -38
  7. package/dist/agent-src/commands/roadmap/next.md +8 -0
  8. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +12 -0
  9. package/dist/agent-src/rules/notes-first-reasoning.md +36 -25
  10. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  11. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -1
  12. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +9 -0
  13. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +52 -2
  14. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  15. package/dist/cli/registry.js +1 -1
  16. package/dist/cli-delegate/archive_completed_roadmaps.js +52 -4
  17. package/dist/cli-delegate/{chunk-TGIPZBCW.js → chunk-2KKXJW25.js} +22 -8
  18. package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-IAI3XL43.js} +15 -3
  19. package/dist/cli-delegate/{chunk-BIXEDQPZ.js → chunk-KCNTUSPI.js} +1 -1
  20. package/dist/cli-delegate/cmd_export.js +2 -2
  21. package/dist/cli-delegate/cmd_handoff.js +20 -12
  22. package/dist/cli-delegate/cmd_prune.js +2 -2
  23. package/dist/cli-delegate/cmd_session_recycle.js +3 -13
  24. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  25. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  26. package/dist/cli-delegate/cmd_sync.js +2 -2
  27. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  28. package/dist/cli-delegate/cmd_validate.js +2 -2
  29. package/dist/discovery/deprecation-report.md +1 -1
  30. package/dist/discovery/discovery-manifest.json +8 -8
  31. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  32. package/dist/discovery/discovery-manifest.summary.md +1 -1
  33. package/dist/discovery/dormancy-report.md +1 -1
  34. package/dist/discovery/orphan-report.md +1 -1
  35. package/dist/discovery/packs.json +2 -2
  36. package/dist/discovery/trust-report.md +1 -1
  37. package/dist/discovery/workspaces.json +2 -2
  38. package/dist/hooks/dispatch.js +880 -289
  39. package/dist/install/install.mjs +15 -3
  40. package/dist/mcp/registry-manifest.json +2 -2
  41. package/dist/mcp/server.json +2 -2
  42. package/dist/mcp/server.mjs +5458 -2453
  43. package/dist/scripts/_lib/lean_projection_mode.js +108 -0
  44. package/dist/scripts/_lib/router_match.js +243 -0
  45. package/dist/scripts/_lib/rule_injection.js +216 -0
  46. package/dist/scripts/condense.js +20 -20
  47. package/dist/scripts/project_thin_rules.js +139 -19
  48. package/dist/server/schemas/settings.js +16 -3
  49. package/docs/MIGRATION.md +56 -0
  50. package/docs/contracts/settings-classes.md +39 -7
  51. package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  52. package/llms.txt +1 -1
  53. package/package.json +1 -1
  54. package/src/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  55. package/src/config/agent-settings.template.yml +47 -1
  56. package/src/config/continuity-surface.json +7 -0
  57. package/src/config/evaluator-budgets.json +4 -4
  58. package/src/config/gate-violation-baselines.json +2 -2
  59. package/src/config/hook-token-budget.json +7 -6
  60. package/src/config/packed-binary-manifest.json +1 -1
  61. package/src/config/routing-coverage-seed.json +9 -2
  62. package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
  63. package/src/scripts/_cli/handoff_sessions.ts +14 -44
  64. package/src/scripts/_lib/continuity_slot.ts +295 -0
  65. package/src/scripts/_lib/continuity_writer.ts +253 -0
  66. package/src/scripts/_lib/hook_settings.ts +85 -0
  67. package/src/scripts/_lib/lean_projection_mode.ts +127 -0
  68. package/src/scripts/_lib/packed_binary_predicate.ts +37 -0
  69. package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
  70. package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
  71. package/src/scripts/_lib/session_eol.ts +44 -0
  72. package/src/scripts/_lib/session_index_trust.ts +346 -0
  73. package/src/scripts/_lib/standing_bound_ratchet.ts +154 -0
  74. package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
  75. package/src/scripts/audit_mcp_tools.ts +69 -25
  76. package/src/scripts/build_mcp_catalog.ts +24 -1
  77. package/src/scripts/check_host_tree_parity.ts +291 -0
  78. package/src/scripts/check_preamble_payload_budget.ts +136 -7
  79. package/src/scripts/check_rule_projection_integrity.ts +102 -2
  80. package/src/scripts/ci_settle.ts +205 -5
  81. package/src/scripts/code_graph/build.ts +79 -0
  82. package/src/scripts/code_graph/cli.ts +258 -7
  83. package/src/scripts/code_graph/detect.ts +38 -0
  84. package/src/scripts/code_graph/query.ts +25 -2
  85. package/src/scripts/code_graph/sqlite_store.ts +16 -1
  86. package/src/scripts/code_graph/types.ts +52 -3
  87. package/src/scripts/code_graph/validate.ts +3 -1
  88. package/src/scripts/code_graph/verbs.ts +590 -0
  89. package/src/scripts/condense.ts +20 -20
  90. package/src/scripts/handoff_context_hook.ts +39 -1
  91. package/src/scripts/hook_manifest.json +1 -1
  92. package/src/scripts/hook_manifest.yaml +24 -1
  93. package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
  94. package/src/scripts/hooks/code_graph_context_hook.ts +7 -18
  95. package/src/scripts/hooks/push_settle_hook.ts +3 -2
  96. package/src/scripts/hooks/rule_inject_hook.ts +107 -20
  97. package/src/scripts/hooks/session_eol_hook.ts +120 -2
  98. package/src/scripts/hot_context_hook.ts +62 -7
  99. package/src/scripts/lint_roadmap_blockers.ts +164 -1
  100. package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
  101. package/src/scripts/mcp_server/graph_tools.ts +294 -0
  102. package/src/scripts/mcp_server/path_util.ts +31 -0
  103. package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
  104. package/src/scripts/mcp_server/tools.ts +3 -13
  105. package/src/scripts/model_rule_injection.ts +61 -4
  106. package/src/scripts/project_thin_rules.ts +149 -16
  107. package/src/scripts/report_standing_payload_by_host.ts +650 -0
  108. package/src/scripts/schemas/agent-settings.schema.json +7 -1
  109. package/src/scripts/session_memory_index.ts +81 -8
  110. package/src/server/schemas/settings.ts +23 -4
  111. package/src/vendor/grammars/README.md +27 -2
@@ -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, path110) {
116
- const ctrl = callVisitor(key, node, visitor, path110);
115
+ function visit_(key, node, visitor, path111) {
116
+ const ctrl = callVisitor(key, node, visitor, path111);
117
117
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
118
- replaceNode(key, path110, ctrl);
119
- return visit_(key, ctrl, visitor, path110);
118
+ replaceNode(key, path111, ctrl);
119
+ return visit_(key, ctrl, visitor, path111);
120
120
  }
121
121
  if (typeof ctrl !== "symbol") {
122
122
  if (identity.isCollection(node)) {
123
- path110 = Object.freeze(path110.concat(node));
123
+ path111 = Object.freeze(path111.concat(node));
124
124
  for (let i = 0; i < node.items.length; ++i) {
125
- const ci = visit_(i, node.items[i], visitor, path110);
125
+ const ci = visit_(i, node.items[i], visitor, path111);
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
- path110 = Object.freeze(path110.concat(node));
137
- const ck = visit_("key", node.key, visitor, path110);
136
+ path111 = Object.freeze(path111.concat(node));
137
+ const ck = visit_("key", node.key, visitor, path111);
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, path110);
142
+ const cv = visit_("value", node.value, visitor, path111);
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, path110) {
164
- const ctrl = await callVisitor(key, node, visitor, path110);
163
+ async function visitAsync_(key, node, visitor, path111) {
164
+ const ctrl = await callVisitor(key, node, visitor, path111);
165
165
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
166
- replaceNode(key, path110, ctrl);
167
- return visitAsync_(key, ctrl, visitor, path110);
166
+ replaceNode(key, path111, ctrl);
167
+ return visitAsync_(key, ctrl, visitor, path111);
168
168
  }
169
169
  if (typeof ctrl !== "symbol") {
170
170
  if (identity.isCollection(node)) {
171
- path110 = Object.freeze(path110.concat(node));
171
+ path111 = Object.freeze(path111.concat(node));
172
172
  for (let i = 0; i < node.items.length; ++i) {
173
- const ci = await visitAsync_(i, node.items[i], visitor, path110);
173
+ const ci = await visitAsync_(i, node.items[i], visitor, path111);
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
- path110 = Object.freeze(path110.concat(node));
185
- const ck = await visitAsync_("key", node.key, visitor, path110);
184
+ path111 = Object.freeze(path111.concat(node));
185
+ const ck = await visitAsync_("key", node.key, visitor, path111);
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, path110);
190
+ const cv = await visitAsync_("value", node.value, visitor, path111);
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, path110) {
217
+ function callVisitor(key, node, visitor, path111) {
218
218
  if (typeof visitor === "function")
219
- return visitor(key, node, path110);
219
+ return visitor(key, node, path111);
220
220
  if (identity.isMap(node))
221
- return visitor.Map?.(key, node, path110);
221
+ return visitor.Map?.(key, node, path111);
222
222
  if (identity.isSeq(node))
223
- return visitor.Seq?.(key, node, path110);
223
+ return visitor.Seq?.(key, node, path111);
224
224
  if (identity.isPair(node))
225
- return visitor.Pair?.(key, node, path110);
225
+ return visitor.Pair?.(key, node, path111);
226
226
  if (identity.isScalar(node))
227
- return visitor.Scalar?.(key, node, path110);
227
+ return visitor.Scalar?.(key, node, path111);
228
228
  if (identity.isAlias(node))
229
- return visitor.Alias?.(key, node, path110);
229
+ return visitor.Alias?.(key, node, path111);
230
230
  return void 0;
231
231
  }
232
- function replaceNode(key, path110, node) {
233
- const parent = path110[path110.length - 1];
232
+ function replaceNode(key, path111, node) {
233
+ const parent = path111[path111.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, path110, value) {
843
+ function collectionFromPath(schema, path111, value) {
844
844
  let v = value;
845
- for (let i = path110.length - 1; i >= 0; --i) {
846
- const k = path110[i];
845
+ for (let i = path111.length - 1; i >= 0; --i) {
846
+ const k = path111[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 = (path110) => path110 == null || typeof path110 === "object" && !!path110[Symbol.iterator]().next().done;
865
+ var isEmptyPath = (path111) => path111 == null || typeof path111 === "object" && !!path111[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(path110, value) {
896
- if (isEmptyPath(path110))
895
+ addIn(path111, value) {
896
+ if (isEmptyPath(path111))
897
897
  this.add(value);
898
898
  else {
899
- const [key, ...rest] = path110;
899
+ const [key, ...rest] = path111;
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(path110) {
914
- const [key, ...rest] = path110;
913
+ deleteIn(path111) {
914
+ const [key, ...rest] = path111;
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(path110, keepScalar) {
929
- const [key, ...rest] = path110;
928
+ getIn(path111, keepScalar) {
929
+ const [key, ...rest] = path111;
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(path110) {
948
- const [key, ...rest] = path110;
947
+ hasIn(path111) {
948
+ const [key, ...rest] = path111;
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(path110, value) {
959
- const [key, ...rest] = path110;
958
+ setIn(path111, value) {
959
+ const [key, ...rest] = path111;
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(path110, value) {
3474
+ addIn(path111, value) {
3475
3475
  if (assertCollection(this.contents))
3476
- this.contents.addIn(path110, value);
3476
+ this.contents.addIn(path111, 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(path110) {
3552
- if (Collection.isEmptyPath(path110)) {
3551
+ deleteIn(path111) {
3552
+ if (Collection.isEmptyPath(path111)) {
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(path110) : false;
3558
+ return assertCollection(this.contents) ? this.contents.deleteIn(path111) : 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(path110, keepScalar) {
3574
- if (Collection.isEmptyPath(path110))
3573
+ getIn(path111, keepScalar) {
3574
+ if (Collection.isEmptyPath(path111))
3575
3575
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
3576
- return identity.isCollection(this.contents) ? this.contents.getIn(path110, keepScalar) : void 0;
3576
+ return identity.isCollection(this.contents) ? this.contents.getIn(path111, 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(path110) {
3588
- if (Collection.isEmptyPath(path110))
3587
+ hasIn(path111) {
3588
+ if (Collection.isEmptyPath(path111))
3589
3589
  return this.contents !== void 0;
3590
- return identity.isCollection(this.contents) ? this.contents.hasIn(path110) : false;
3590
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path111) : 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(path110, value) {
3608
- if (Collection.isEmptyPath(path110)) {
3607
+ setIn(path111, value) {
3608
+ if (Collection.isEmptyPath(path111)) {
3609
3609
  this.contents = value;
3610
3610
  } else if (this.contents == null) {
3611
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path110), value);
3611
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path111), value);
3612
3612
  } else if (assertCollection(this.contents)) {
3613
- this.contents.setIn(path110, value);
3613
+ this.contents.setIn(path111, 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, path110) => {
5573
+ visit.itemAtPath = (cst, path111) => {
5574
5574
  let item = cst;
5575
- for (const [field, index] of path110) {
5575
+ for (const [field, index] of path111) {
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, path110) => {
5585
- const parent = visit.itemAtPath(cst, path110.slice(0, -1));
5586
- const field = path110[path110.length - 1][0];
5584
+ visit.parentCollection = (cst, path111) => {
5585
+ const parent = visit.itemAtPath(cst, path111.slice(0, -1));
5586
+ const field = path111[path111.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(path110, item, visitor) {
5593
- let ctrl = visitor(item, path110);
5592
+ function _visit(path111, item, visitor) {
5593
+ let ctrl = visitor(item, path111);
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(path110.concat([[field, i]])), token.items[i], visitor);
5600
+ const ci = _visit(Object.freeze(path111.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, path110);
5611
+ ctrl = ctrl(item, path111);
5612
5612
  }
5613
5613
  }
5614
- return typeof ctrl === "function" ? ctrl(item, path110) : ctrl;
5614
+ return typeof ctrl === "function" ? ctrl(item, path111) : 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 fs107 = this.flowScalar(this.type);
6916
+ const fs109 = this.flowScalar(this.type);
6917
6917
  if (atNextItem || it.value) {
6918
- map.items.push({ start, key: fs107, sep: [] });
6918
+ map.items.push({ start, key: fs109, sep: [] });
6919
6919
  this.onKeyLine = true;
6920
6920
  } else if (it.sep) {
6921
- this.stack.push(fs107);
6921
+ this.stack.push(fs109);
6922
6922
  } else {
6923
- Object.assign(it, { key: fs107, sep: [] });
6923
+ Object.assign(it, { key: fs109, 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 fs107 = this.flowScalar(this.type);
7051
+ const fs109 = this.flowScalar(this.type);
7052
7052
  if (!it || it.value)
7053
- fc.items.push({ start: [], key: fs107, sep: [] });
7053
+ fc.items.push({ start: [], key: fs109, sep: [] });
7054
7054
  else if (it.sep)
7055
- this.stack.push(fs107);
7055
+ this.stack.push(fs109);
7056
7056
  else
7057
- Object.assign(it, { key: fs107, sep: [] });
7057
+ Object.assign(it, { key: fs109, sep: [] });
7058
7058
  return;
7059
7059
  }
7060
7060
  case "flow-map-end":
@@ -7363,14 +7363,14 @@ var require_dist = __commonJS({
7363
7363
  });
7364
7364
 
7365
7365
  // src/scripts/hooks/dispatch_entry.ts
7366
- import * as path109 from "node:path";
7366
+ import * as path110 from "node:path";
7367
7367
  import { fileURLToPath as fileURLToPath71 } from "node:url";
7368
7368
 
7369
7369
  // src/scripts/hooks/dispatch_hook.ts
7370
7370
  var import_yaml7 = __toESM(require_dist(), 1);
7371
7371
  import { spawnSync as spawnSync11 } from "node:child_process";
7372
- import fs106 from "node:fs";
7373
- import path108 from "node:path";
7372
+ import fs108 from "node:fs";
7373
+ import path109 from "node:path";
7374
7374
  import * as tty2 from "node:tty";
7375
7375
  import { fileURLToPath as fileURLToPath70, pathToFileURL as pathToFileURL61 } from "node:url";
7376
7376
 
@@ -18580,18 +18580,34 @@ function restore_hot_context(root, source, now = /* @__PURE__ */ new Date()) {
18580
18580
  ].join("\n");
18581
18581
  return { action: "inject", reason: `restored (source=${source || "startup"})`, context: block };
18582
18582
  }
18583
- function _session_index_block_or_null(root) {
18583
+ function _session_index_block_or_null(root, sessionId3) {
18584
18584
  try {
18585
18585
  const req = createRequire4(import.meta.url);
18586
18586
  const mod = req("./session_memory_index.js");
18587
18587
  if (!mod.session_index_enabled(root)) return null;
18588
+ const verdict2 = mod.session_index_trust(root);
18589
+ if (!verdict2.ok) {
18590
+ process7.stderr.write(`hot-context-hook: session index refused [${String(verdict2.code)}]: ${String(verdict2.detail)}
18591
+ `);
18592
+ return null;
18593
+ }
18588
18594
  const prev = process7.cwd();
18595
+ let block;
18589
18596
  try {
18590
18597
  process7.chdir(root);
18591
- return mod.build_session_index_block();
18598
+ block = mod.serve_session_index_block(verdict2);
18592
18599
  } finally {
18593
18600
  process7.chdir(prev);
18594
18601
  }
18602
+ if (block === null) return null;
18603
+ const trust = req("./_lib/session_index_trust.js");
18604
+ const claim = trust.claimSessionOnce(root, sessionId3);
18605
+ if (!claim.ok) {
18606
+ process7.stderr.write(`hot-context-hook: session index already served [${String(claim.code)}]
18607
+ `);
18608
+ return null;
18609
+ }
18610
+ return block;
18595
18611
  } catch (exc) {
18596
18612
  process7.stderr.write(`hot-context-hook: session index skipped: ${String(exc)}
18597
18613
  `);
@@ -18630,7 +18646,10 @@ function main7() {
18630
18646
  if (decision.action === "inject" && decision.context) {
18631
18647
  blocks.push(decision.context);
18632
18648
  }
18633
- const indexBlock = _session_index_block_or_null(root);
18649
+ const sessionId3 = String(
18650
+ envelope.session_id ?? payload.session_id ?? payload.sessionId ?? ""
18651
+ );
18652
+ const indexBlock = _session_index_block_or_null(root, sessionId3);
18634
18653
  if (indexBlock !== null) {
18635
18654
  blocks.push(indexBlock);
18636
18655
  }
@@ -19399,6 +19418,7 @@ var RECYCLE_CONSUMED_REL = path24.join(
19399
19418
  "recycle-envelope.consumed.json"
19400
19419
  );
19401
19420
  var RECYCLE_MAX_AGE_HOURS = 48;
19421
+ var RECYCLE_ENVELOPE_MAX_BYTES = 6144;
19402
19422
  var _STATE_REL = path24.join("agents", "runtime", "state");
19403
19423
  function recycle_envelope_rel(session_id) {
19404
19424
  return _sessionKeyed(session_id, RECYCLE_ENVELOPE_REL, "recycle-envelope", ".json");
@@ -19406,6 +19426,14 @@ function recycle_envelope_rel(session_id) {
19406
19426
  function recycle_consumed_rel(session_id) {
19407
19427
  return _sessionKeyed(session_id, RECYCLE_CONSUMED_REL, "recycle-envelope", ".consumed.json");
19408
19428
  }
19429
+ function recycle_quarantine_rel(session_id) {
19430
+ return _sessionKeyed(
19431
+ session_id,
19432
+ path24.join(_STATE_REL, "recycle-envelope.quarantined.json"),
19433
+ "recycle-envelope",
19434
+ ".quarantined.json"
19435
+ );
19436
+ }
19409
19437
  function _sessionKeyed(session_id, legacy, stem, suffix) {
19410
19438
  const id = String(session_id ?? "").trim();
19411
19439
  if (id === "") {
@@ -19432,22 +19460,35 @@ function listContinuityRecords(workspace_root) {
19432
19460
  }
19433
19461
  function resolveContinuityRecord(workspace_root, session_id) {
19434
19462
  const id = String(session_id ?? "").trim();
19435
- if (id !== "") {
19436
- const own = path24.join(workspace_root, recycle_envelope_rel(id));
19437
- return fs26.existsSync(own) ? { file: own, reason: `continuity record for this session (${safe_stem(id)})` } : { file: null, reason: `no continuity record for this session (${safe_stem(id)})` };
19438
- }
19439
- const candidates = listContinuityRecords(workspace_root);
19463
+ const own = id === "" ? null : path24.join(workspace_root, recycle_envelope_rel(id));
19464
+ const candidates = listContinuityRecords(workspace_root).filter((f) => f !== own);
19440
19465
  if (candidates.length === 0) {
19441
- return { file: null, reason: "no continuity record present" };
19466
+ return {
19467
+ file: null,
19468
+ reason: id === "" ? "no continuity record present" : `no predecessor record in this workspace (own: ${safe_stem(id)})`
19469
+ };
19442
19470
  }
19443
19471
  if (candidates.length === 1) {
19444
- return { file: candidates[0], reason: "one continuity record, no session id to key on" };
19472
+ return {
19473
+ file: candidates[0],
19474
+ reason: id === "" ? "one continuity record, no session id to key on" : `predecessor record, one candidate (own: ${safe_stem(id)})`
19475
+ };
19445
19476
  }
19446
19477
  return {
19447
19478
  file: null,
19448
- reason: `starting clean: ${candidates.length} continuity records in this workspace and no session id to tell them apart \u2014 resuming from the newest would resume a peer session, not this one`
19479
+ reason: `starting clean: ${candidates.length} continuity records in this workspace and no way to tell which is the predecessor \u2014 resuming from the newest would resume a peer session, not this one`
19449
19480
  };
19450
19481
  }
19482
+ function resolvePredecessor(projectRoot, sessionId3) {
19483
+ try {
19484
+ const consumed = path24.join(projectRoot, recycle_consumed_rel(sessionId3));
19485
+ const raw = JSON.parse(fs26.readFileSync(consumed, "utf-8"));
19486
+ const prior = String(raw.session_id ?? "").trim();
19487
+ return prior === "" ? "none" : prior;
19488
+ } catch {
19489
+ return "none";
19490
+ }
19491
+ }
19451
19492
  function predecessorTracePresent(workspace_root, predecessor) {
19452
19493
  const id = String(predecessor ?? "").trim();
19453
19494
  if (id === "" || id === "none") {
@@ -19530,8 +19571,8 @@ function lockfile_path(env) {
19530
19571
  }
19531
19572
  return write_target("installed.lock", { env: env ?? null });
19532
19573
  }
19533
- function read_lockfile(path110) {
19534
- const target = path110 ?? lockfile_path();
19574
+ function read_lockfile(path111) {
19575
+ const target = path111 ?? lockfile_path();
19535
19576
  let text;
19536
19577
  try {
19537
19578
  text = fs27.readFileSync(target, { encoding: "utf-8" });
@@ -20657,6 +20698,7 @@ var EPISTEMIC = new Set(EPISTEMIC_STATES);
20657
20698
  var MAX_REF_CHARS = 200;
20658
20699
  var MAX_LINE_CHARS = 240;
20659
20700
  var MAX_ENTRIES = 40;
20701
+ var CAPSULE_SCHEMA_VERSION = 4;
20660
20702
  var ACCEPTED_CAPSULE_VERSIONS = [3, 4];
20661
20703
  var CAPSULE_VARIANTS = ["worker", "main_session", "continuity_record"];
20662
20704
  var CONTINUITY_RECORD_FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
@@ -21121,7 +21163,15 @@ function consume_recycle_envelope(root, now = /* @__PURE__ */ new Date(), sessio
21121
21163
  reason: `recycle envelope names predecessor "${predecessor}", which has no trace in this workspace`
21122
21164
  };
21123
21165
  }
21124
- const drift = describeDrift(envelope, collectRepoAnchor(root));
21166
+ const anchor = collectRepoAnchor(root);
21167
+ const envelopeBranch = String(envelope["branch"] ?? "").trim();
21168
+ if (envelopeBranch !== "" && anchor.branch !== null && envelopeBranch !== anchor.branch) {
21169
+ return {
21170
+ action: "absent",
21171
+ reason: `recycle envelope is for branch "${envelopeBranch}" and this tree is on "${anchor.branch}" \u2014 left unclaimed for a session on that branch rather than consumed`
21172
+ };
21173
+ }
21174
+ const drift = describeDrift(envelope, anchor);
21125
21175
  const warnings = scanEnvelopeDirectives(envelope);
21126
21176
  const focus = (process10.env.AGENT_RESUME_FOCUS ?? "").trim();
21127
21177
  const block = wrapAsPriorSessionData(JSON.stringify(envelope, null, 2), {
@@ -24487,7 +24537,7 @@ A push is not a delivery. Per verify-before-complete, a completion claim needs f
24487
24537
  Before this turn ends:
24488
24538
  1. Settle it:
24489
24539
  ${settle}
24490
- Exit 0 = settled green \xB7 1 = settled, something failed \xB7 2 = NOT a verdict (timed out or unreadable \u2014 never report 2 as green).
24540
+ Exit 0 = settled green, and the line names the head it is about \xB7 1 = settled, something failed \xB7 2 = NOT a verdict (timed out, unreadable, or the PR is merged / closed / head-diverged \u2014 never report 2 as green).
24491
24541
  2. Red? Read only the failing part:
24492
24542
  gh run view --job <id> --log-failed | grep -E '\xD7|FAIL|Error'
24493
24543
  then fix it and push again (fix-what-you-see: the author is irrelevant).
@@ -28107,6 +28157,83 @@ var COMMAND_OPS = [
28107
28157
  { op: "commit", re: new RegExp(`${P}git\\s+${G}commit\\b`, "i") },
28108
28158
  { op: "branch", re: new RegExp(`${P}git\\s+${G}(checkout\\s+-b|switch\\s+-c)\\b`, "i") }
28109
28159
  ];
28160
+ function splitOutsideQuotes(command) {
28161
+ const parts = [];
28162
+ let cur = "";
28163
+ let quote = null;
28164
+ for (let i = 0; i < command.length; i += 1) {
28165
+ const ch = command[i];
28166
+ if (quote !== null) {
28167
+ if (quote === "$'" && ch === "\\" && i + 1 < command.length) {
28168
+ cur += ch + command[i + 1];
28169
+ i += 1;
28170
+ continue;
28171
+ }
28172
+ cur += ch;
28173
+ if (ch === (quote === "$'" ? "'" : quote)) {
28174
+ quote = null;
28175
+ } else if (ch === "\\" && quote === '"' && i + 1 < command.length) {
28176
+ cur += command[i + 1];
28177
+ i += 1;
28178
+ }
28179
+ continue;
28180
+ }
28181
+ if (ch === "$" && (command[i + 1] === "'" || command[i + 1] === '"')) {
28182
+ quote = command[i + 1] === "'" ? "$'" : '"';
28183
+ cur += ch + command[i + 1];
28184
+ i += 1;
28185
+ continue;
28186
+ }
28187
+ if (ch === '"' || ch === "'") {
28188
+ quote = ch;
28189
+ cur += ch;
28190
+ continue;
28191
+ }
28192
+ if (ch === "\\" && i + 1 < command.length) {
28193
+ cur += ch + command[i + 1];
28194
+ i += 1;
28195
+ continue;
28196
+ }
28197
+ if (ch === "\n" || ch === ";" || ch === "|" || ch === "&") {
28198
+ if ((ch === "|" || ch === "&") && command[i + 1] === ch) {
28199
+ i += 1;
28200
+ }
28201
+ parts.push(cur);
28202
+ cur = "";
28203
+ continue;
28204
+ }
28205
+ cur += ch;
28206
+ }
28207
+ if (quote !== null) {
28208
+ parts.push(...splitIgnoringQuotes(cur));
28209
+ return parts;
28210
+ }
28211
+ parts.push(cur);
28212
+ return parts;
28213
+ }
28214
+ function splitIgnoringQuotes(fragment) {
28215
+ const parts = [];
28216
+ let cur = "";
28217
+ for (let i = 0; i < fragment.length; i += 1) {
28218
+ const ch = fragment[i];
28219
+ if (ch === "\\" && i + 1 < fragment.length) {
28220
+ cur += ch + fragment[i + 1];
28221
+ i += 1;
28222
+ continue;
28223
+ }
28224
+ if (ch === "\n" || ch === ";" || ch === "|" || ch === "&") {
28225
+ if ((ch === "|" || ch === "&") && fragment[i + 1] === ch) {
28226
+ i += 1;
28227
+ }
28228
+ parts.push(cur);
28229
+ cur = "";
28230
+ continue;
28231
+ }
28232
+ cur += ch;
28233
+ }
28234
+ parts.push(cur);
28235
+ return parts;
28236
+ }
28110
28237
  function substitutionPayloads(segment) {
28111
28238
  const out = [];
28112
28239
  for (let i = 0; i < segment.length; i += 1) {
@@ -28141,6 +28268,38 @@ function substitutionPayloads(segment) {
28141
28268
  }
28142
28269
  return out;
28143
28270
  }
28271
+ function invokedSegments(command, depth = 0) {
28272
+ if (depth > 3) {
28273
+ return [];
28274
+ }
28275
+ const out = [];
28276
+ const withoutHeredocs = command.replace(
28277
+ /<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1[\s\S]*?^\s*\2\s*$/gm,
28278
+ "<<HEREDOC"
28279
+ );
28280
+ for (const raw of splitOutsideQuotes(withoutHeredocs)) {
28281
+ let seg = raw.trim();
28282
+ if (!seg) {
28283
+ continue;
28284
+ }
28285
+ seg = seg.replace(/^(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|\S*)\s+)+/, "");
28286
+ for (const payload of substitutionPayloads(seg)) {
28287
+ out.push(...invokedSegments(payload, depth + 1));
28288
+ }
28289
+ const wrapped = /^(?:\S*\/)?(?:ba|z|k)?sh\s+-[a-z]*c\s+(?:"([^"]*)"|'([^']*)'|(\S+))/.exec(seg);
28290
+ if (wrapped) {
28291
+ out.push(...invokedSegments(wrapped[1] ?? wrapped[2] ?? wrapped[3] ?? "", depth + 1));
28292
+ continue;
28293
+ }
28294
+ const evaled = /^eval\s+(?:"([^"]*)"|'([^']*)'|(.+))$/.exec(seg);
28295
+ if (evaled) {
28296
+ out.push(...invokedSegments(evaled[1] ?? evaled[2] ?? evaled[3] ?? "", depth + 1));
28297
+ continue;
28298
+ }
28299
+ out.push(seg.replace(/^(\S+)/, (w) => w.replace(/['"]/g, "")));
28300
+ }
28301
+ return out;
28302
+ }
28144
28303
 
28145
28304
  // src/scripts/hooks/block_no_verify.ts
28146
28305
  var _HERE4 = fileURLToPath38(import.meta.url);
@@ -29049,9 +29208,62 @@ var _PATH_KEYS3 = [
29049
29208
  "filePath",
29050
29209
  "notebook_path"
29051
29210
  ];
29211
+ var _READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
29212
+ "read",
29213
+ "grep",
29214
+ "glob",
29215
+ "notebookread",
29216
+ "ls",
29217
+ "view",
29218
+ "search",
29219
+ "codebase-retrieval",
29220
+ "codebase_retrieval",
29221
+ "file_search",
29222
+ "grep_search",
29223
+ "read_file",
29224
+ "list_dir",
29225
+ "semantic_search"
29226
+ ]);
29052
29227
  function _isObject12(v) {
29053
29228
  return v !== null && v !== void 0 && typeof v === "object" && !Array.isArray(v);
29054
29229
  }
29230
+ function isGlobOverAcceptableInboxDir(name) {
29231
+ if (!/[*?[\]]/.test(name)) {
29232
+ return false;
29233
+ }
29234
+ const literal = name.replace(/[*?]|\[[^\]]*\]/g, "");
29235
+ const trimmed = literal.replace(/-+$/, "");
29236
+ return trimmed !== "" && isAcceptableInboxDir(trimmed);
29237
+ }
29238
+ function _redirectTargets(segment) {
29239
+ const out = [];
29240
+ const re = /(?:^|[^0-9<>&])[0-9]*>>?\s*([^\s|&;<>]+)/g;
29241
+ let m = re.exec(segment);
29242
+ while (m !== null) {
29243
+ const target = (m[1] ?? "").replace(/^['"`]+|['"`]+$/g, "");
29244
+ if (target) {
29245
+ out.push(target);
29246
+ }
29247
+ m = re.exec(segment);
29248
+ }
29249
+ return out;
29250
+ }
29251
+ function creatableTokens(command) {
29252
+ const out = [];
29253
+ const segments = invokedSegments(command);
29254
+ for (const seg of segments) {
29255
+ out.push(..._redirectTargets(seg));
29256
+ }
29257
+ out.push(..._redirectTargets(command));
29258
+ for (const text of [...segments, command]) {
29259
+ for (const tok of text.split(/[\s"'`(){};|&<>]+/)) {
29260
+ if (tok) {
29261
+ out.push(tok);
29262
+ }
29263
+ }
29264
+ }
29265
+ return out;
29266
+ }
29055
29267
  var INBOX_RE = /(?:^|\/)agents\/tmp(?:\.old)?\/([^/]+)\/./;
29056
29268
  var INBOX_DIR_TERMINAL_RE = /(?:^|\/)agents\/tmp(?:\.old)?\/([^/.]+)\/?$/;
29057
29269
  function inboxDirName(filePath) {
@@ -29077,13 +29289,16 @@ function verdictFor(filePath, exists, repoRoot = "") {
29077
29289
  if (isAcceptableInboxDir(dir)) {
29078
29290
  return { block: false, dir, reason: "opaque round identifier or named working set" };
29079
29291
  }
29292
+ if (isGlobOverAcceptableInboxDir(dir)) {
29293
+ return { block: false, dir, reason: "glob over an acceptable name \u2014 not a creatable literal" };
29294
+ }
29080
29295
  const normalized = filePath.replace(/\\/g, "/").replace(/^(\.\/)+/, "");
29081
- const m = /(?:^|\/)(agents\/tmp(?:\.old)?\/[^/]+)\//.exec(normalized) ?? /(?:^|\/)(agents\/tmp(?:\.old)?\/[^/.]+)\/?$/.exec(normalized);
29296
+ const m = /^((?:.*?\/)??agents\/tmp(?:\.old)?\/[^/]+)\//.exec(normalized) ?? /^((?:.*?\/)??agents\/tmp(?:\.old)?\/[^/.]+)\/?$/.exec(normalized);
29082
29297
  if (m === null) {
29083
29298
  return { block: true, dir, reason: "new inbox directory with a speaking name (path not re-anchorable)" };
29084
29299
  }
29085
29300
  const upto = m[1];
29086
- const probe = repoRoot === "" ? upto : path63.join(repoRoot, upto);
29301
+ const probe = repoRoot === "" || path63.isAbsolute(upto) ? upto : path63.join(repoRoot, upto);
29087
29302
  if (exists(probe)) {
29088
29303
  return { block: false, dir, reason: "directory already exists \u2014 rename, do not re-refuse" };
29089
29304
  }
@@ -29128,20 +29343,20 @@ function main37() {
29128
29343
  return 0;
29129
29344
  }
29130
29345
  const repoRoot = typeof envelope["project_dir"] === "string" ? envelope["project_dir"] : "";
29346
+ const rawTool = payload["tool_name"] ?? envelope["tool_name"];
29347
+ const toolName2 = typeof rawTool === "string" ? rawTool.trim().toLowerCase() : "";
29131
29348
  const candidates = [];
29132
- for (const key of _PATH_KEYS3) {
29133
- const v = ti[key];
29134
- if (typeof v === "string" && v) {
29135
- candidates.push(v);
29349
+ if (!_READ_ONLY_TOOLS.has(toolName2)) {
29350
+ for (const key of _PATH_KEYS3) {
29351
+ const v = ti[key];
29352
+ if (typeof v === "string" && v) {
29353
+ candidates.push(v);
29354
+ }
29136
29355
  }
29137
29356
  }
29138
29357
  const cmd = ti["command"] ?? (_isObject12(envelope["payload"]) ? envelope["payload"]["command"] : void 0);
29139
29358
  if (typeof cmd === "string" && cmd) {
29140
- for (const tok of cmd.split(/[\s"'`(){};|&<>]+/)) {
29141
- if (tok) {
29142
- candidates.push(tok);
29143
- }
29144
- }
29359
+ candidates.push(...creatableTokens(cmd));
29145
29360
  }
29146
29361
  for (const v of candidates) {
29147
29362
  const verdict2 = verdictFor(v, (p) => fs64.existsSync(p), repoRoot);
@@ -30778,7 +30993,7 @@ import * as fs69 from "node:fs";
30778
30993
  import * as path68 from "node:path";
30779
30994
 
30780
30995
  // src/scripts/code_graph/validate.ts
30781
- var RELATIONS = /* @__PURE__ */ new Set(["calls", "imports", "uses", "inherits", "member"]);
30996
+ var RELATIONS = /* @__PURE__ */ new Set(["calls", "imports", "uses", "inherits", "member", "tests"]);
30782
30997
  var CONFIDENCES = /* @__PURE__ */ new Set(["EXTRACTED", "INFERRED", "AMBIGUOUS"]);
30783
30998
  var RESOLVED_VIA = /* @__PURE__ */ new Set([
30784
30999
  "same-file",
@@ -30929,6 +31144,14 @@ function pickSource(verdicts) {
30929
31144
  if (native) return native;
30930
31145
  return verdicts.find((v) => v.kind === "consumer") ?? null;
30931
31146
  }
31147
+ var NATIVE_CACHE_REL = path68.join("agents", "runtime", "state", "code-graph-v1.json");
31148
+ function graphState(root, nativeCache) {
31149
+ const picked = pickSource(detectSources(root, nativeCache ?? path68.join(root, NATIVE_CACHE_REL)));
31150
+ if (!picked) return "absent";
31151
+ if (picked.stale !== true) return "fresh";
31152
+ const behind = picked.commits_behind;
31153
+ return `behind:${typeof behind === "number" ? behind : 0}`;
31154
+ }
30932
31155
 
30933
31156
  // src/scripts/hooks/code_graph_context_hook.ts
30934
31157
  var EXIT_ALLOW17 = 0;
@@ -30979,14 +31202,6 @@ function latch(root, session) {
30979
31202
  } catch {
30980
31203
  }
30981
31204
  }
30982
- var NATIVE_CACHE = path69.join("agents", "runtime", "state", "code-graph-v1.json");
30983
- function graphState(root) {
30984
- const picked = pickSource(detectSources(root, path69.join(root, NATIVE_CACHE)));
30985
- if (!picked) return "absent";
30986
- if (picked.stale !== true) return "fresh";
30987
- const behind = picked.commits_behind;
30988
- return `behind:${typeof behind === "number" ? behind : 0}`;
30989
- }
30990
31205
  function contextLine(state) {
30991
31206
  if (state === "fresh") {
30992
31207
  return "code-graph: fresh. For structure questions (who calls / where used / impact) `agent-config code-graph query|affected <symbol>` answers from the index; grep is the other path \u2014 say which one answered.";
@@ -31489,6 +31704,54 @@ function leanProjectionModeRaw(root) {
31489
31704
  }
31490
31705
  return "";
31491
31706
  }
31707
+ function leanProjectionHostsRaw(root) {
31708
+ const file = path72.join(root, SETTINGS_FILE11);
31709
+ let text;
31710
+ try {
31711
+ if (!fs73.statSync(file).isFile()) return [];
31712
+ text = fs73.readFileSync(file, "utf-8");
31713
+ } catch {
31714
+ return [];
31715
+ }
31716
+ const strip = (s) => s.trim().replace(/^["']|["']$/g, "");
31717
+ let inSection = false;
31718
+ let inBlock = false;
31719
+ let blockIndent = -1;
31720
+ const out = [];
31721
+ for (const raw of text.split(/\r\n|\r|\n/)) {
31722
+ const line = raw.replace(/\s+$/, "");
31723
+ if (!line || line.replace(/^\s+/, "").startsWith("#")) continue;
31724
+ if (!(line.startsWith(" ") || line.startsWith(" "))) {
31725
+ inSection = /^lean_projection\s*:\s*$/.test(line);
31726
+ inBlock = false;
31727
+ continue;
31728
+ }
31729
+ if (!inSection) continue;
31730
+ const indent = /^\s*/.exec(line)[0].length;
31731
+ if (inBlock) {
31732
+ const item = /^\s*-\s*(\S.*)$/.exec(line);
31733
+ if (item !== null && indent >= blockIndent) {
31734
+ const v = strip(item[1] ?? "");
31735
+ if (v !== "") out.push(v);
31736
+ continue;
31737
+ }
31738
+ inBlock = false;
31739
+ }
31740
+ const inline = /^\s+hosts\s*:\s*\[([^\]]*)\]\s*$/.exec(line);
31741
+ if (inline !== null) {
31742
+ for (const part of (inline[1] ?? "").split(",")) {
31743
+ const v = strip(part);
31744
+ if (v !== "") out.push(v);
31745
+ }
31746
+ continue;
31747
+ }
31748
+ if (/^\s+hosts\s*:\s*$/.test(line)) {
31749
+ inBlock = true;
31750
+ blockIndent = indent;
31751
+ }
31752
+ }
31753
+ return out;
31754
+ }
31492
31755
 
31493
31756
  // src/scripts/hooks/ui_route_nudge_hook.ts
31494
31757
  var EXIT_ALLOW20 = 0;
@@ -33579,6 +33842,39 @@ function normalizeLeanProjectionMode(raw) {
33579
33842
  function deliversBodies(mode) {
33580
33843
  return mode === "delivery";
33581
33844
  }
33845
+ var THINNABLE_HOSTS = ["claude-code", "cursor", "cline"];
33846
+ var DEFAULT_LEAN_PROJECTION_HOSTS = ["claude-code"];
33847
+ function resolveLeanProjectionHosts(raw) {
33848
+ const known = new Set(THINNABLE_HOSTS);
33849
+ if (!Array.isArray(raw) || raw.length === 0) {
33850
+ return { hosts: [...DEFAULT_LEAN_PROJECTION_HOSTS], dropped: [], usedDefault: true };
33851
+ }
33852
+ const hosts = [];
33853
+ const dropped = [];
33854
+ for (const entry of raw) {
33855
+ const id = typeof entry === "string" ? entry.trim().toLowerCase() : "";
33856
+ if (id === "") {
33857
+ dropped.push({ id: String(entry), reason: "unknown" });
33858
+ continue;
33859
+ }
33860
+ if (!known.has(id)) {
33861
+ dropped.push({ id, reason: KNOWN_NON_THINNABLE_HOSTS.has(id) ? "not-thinnable" : "unknown" });
33862
+ continue;
33863
+ }
33864
+ if (!hosts.includes(id)) hosts.push(id);
33865
+ }
33866
+ hosts.sort();
33867
+ return { hosts, dropped, usedDefault: false };
33868
+ }
33869
+ var KNOWN_NON_THINNABLE_HOSTS = /* @__PURE__ */ new Set([
33870
+ "claude-desktop",
33871
+ "augment",
33872
+ "copilot",
33873
+ "windsurf",
33874
+ "gemini",
33875
+ "codex",
33876
+ "cowork"
33877
+ ]);
33582
33878
 
33583
33879
  // src/scripts/_lib/rule_injection.ts
33584
33880
  import * as fs82 from "node:fs";
@@ -33850,7 +34146,7 @@ function selectForInjection(repoRoot, matches, capBytes, shortlist) {
33850
34146
  // src/scripts/hooks/rule_inject_hook.ts
33851
34147
  var EXIT_ALLOW25 = 0;
33852
34148
  var EXIT_WARN14 = 2;
33853
- var CAP_BYTES = 20480;
34149
+ var CAP_BYTES = 16384;
33854
34150
  var FILE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "NotebookEdit", "Read", "MultiEdit"]);
33855
34151
  function isObject11(v) {
33856
34152
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -33928,8 +34224,11 @@ ${body.trim()}
33928
34224
  if (ids.length === 0) return null;
33929
34225
  return { rules: ids, bytes: sel.bytes, body: parts.join("\n\n") };
33930
34226
  }
34227
+ var DELIVERY_HOST = "claude-code";
33931
34228
  function gateOpen(root, cliEntry) {
33932
- if (deliversBodies(normalizeLeanProjectionMode(leanProjectionModeRaw(root)))) return true;
34229
+ const mode = normalizeLeanProjectionMode(leanProjectionModeRaw(root));
34230
+ const hosts = resolveLeanProjectionHosts(leanProjectionHostsRaw(root)).hosts;
34231
+ if (deliversBodies(mode) && hosts.includes(DELIVERY_HOST)) return true;
33933
34232
  if (hookSectionEnabled(root, "rule_inject")) return true;
33934
34233
  return cliEntry && process13.env["AGENT_CONFIG_REPLAY"] !== "1";
33935
34234
  }
@@ -34070,8 +34369,8 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
34070
34369
  try {
34071
34370
  const realHome = fs84.realpathSync(homeDir);
34072
34371
  const realPath = fs84.realpathSync(rawPath);
34073
- const relative13 = path83.relative(realHome, realPath);
34074
- if (relative13 === "" || relative13.startsWith("..") || path83.isAbsolute(relative13)) {
34372
+ const relative14 = path83.relative(realHome, realPath);
34373
+ if (relative14 === "" || relative14.startsWith("..") || path83.isAbsolute(relative14)) {
34075
34374
  return false;
34076
34375
  }
34077
34376
  const { size } = fs84.statSync(realPath);
@@ -36300,8 +36599,8 @@ if (_isCliEntry43()) {
36300
36599
  }
36301
36600
 
36302
36601
  // src/scripts/hooks/session_eol_hook.ts
36303
- import * as fs95 from "node:fs";
36304
- import * as path96 from "node:path";
36602
+ import * as fs97 from "node:fs";
36603
+ import * as path97 from "node:path";
36305
36604
  import process16 from "node:process";
36306
36605
  import { fileURLToPath as fileURLToPath63, pathToFileURL as pathToFileURL54 } from "node:url";
36307
36606
 
@@ -36444,6 +36743,16 @@ function eolStateFile(workspaceRoot3, sessionKey) {
36444
36743
  function eolSessionKey(raw) {
36445
36744
  return crypto13.createHash("sha256").update(raw || "unknown-session").digest("hex");
36446
36745
  }
36746
+ var SUBSTANTIVE_TOKEN_FLOOR = 1e4;
36747
+ function is_substantive(counters) {
36748
+ if (counters === null) return true;
36749
+ if (!Number.isFinite(counters.assistant_records)) return true;
36750
+ if (counters.assistant_records < 1) return false;
36751
+ if (!Number.isFinite(counters.tool_calls)) return true;
36752
+ if (counters.tool_calls >= 1) return true;
36753
+ if (!Number.isFinite(counters.final_context_tokens)) return true;
36754
+ return counters.final_context_tokens >= SUBSTANTIVE_TOKEN_FLOOR;
36755
+ }
36447
36756
  function readNewCompleteLines(filePath, fromByte) {
36448
36757
  try {
36449
36758
  const { size } = fs91.statSync(filePath);
@@ -36705,10 +37014,273 @@ function writeCheckpoint(repoRoot, cp) {
36705
37014
  }
36706
37015
  }
36707
37016
 
37017
+ // src/scripts/_lib/continuity_writer.ts
37018
+ import * as fs95 from "node:fs";
37019
+ function auto_record_enabled(root) {
37020
+ try {
37021
+ const settings = load_agent_settings({ cwd: root });
37022
+ const section = settings["continuity"];
37023
+ if (section && typeof section === "object" && !Array.isArray(section)) {
37024
+ const v = section["auto_record"];
37025
+ return v === "on" || v === true;
37026
+ }
37027
+ } catch {
37028
+ }
37029
+ return false;
37030
+ }
37031
+ function run_checkpoints_enabled(root) {
37032
+ try {
37033
+ const settings = load_agent_settings({ cwd: root });
37034
+ const section = settings["continuity"];
37035
+ if (section && typeof section === "object" && !Array.isArray(section)) {
37036
+ const v = section["run_checkpoints"];
37037
+ if (v === "off" || v === false) return false;
37038
+ }
37039
+ } catch {
37040
+ }
37041
+ return true;
37042
+ }
37043
+ var LIST_CAP = 12;
37044
+ function _clip(line) {
37045
+ const one = line.replace(/\s+/g, " ").trim();
37046
+ return one.length <= MAX_LINE_CHARS ? one : `${one.slice(0, MAX_LINE_CHARS - 1)}\u2026`;
37047
+ }
37048
+ function roadmapShape(text) {
37049
+ let done = 0;
37050
+ let total = 0;
37051
+ const open = [];
37052
+ for (const raw of phaseLines(text)) {
37053
+ const m = CHECKBOX_LINE.exec(raw);
37054
+ if (m === null) continue;
37055
+ total += 1;
37056
+ const mark = m[1];
37057
+ if (mark === "x" || mark === "X") {
37058
+ done += 1;
37059
+ continue;
37060
+ }
37061
+ if (mark === "~" || mark === "-") continue;
37062
+ if (open.length < LIST_CAP) {
37063
+ open.push(_clip((m[2] ?? "").replace(/\*\*/g, "")));
37064
+ }
37065
+ }
37066
+ return { done, total, open };
37067
+ }
37068
+ function acceptanceCriteria(text) {
37069
+ const lines = text.split("\n");
37070
+ const out = [];
37071
+ let inside = false;
37072
+ for (const raw of lines) {
37073
+ const heading = /^(#{2,3})[ \t]+(.*?)[ \t]*$/.exec(raw);
37074
+ if (heading !== null) {
37075
+ inside = /^Acceptance[ \t]+Criteria\b/i.test(heading[2] ?? "");
37076
+ continue;
37077
+ }
37078
+ if (!inside) continue;
37079
+ const m = CHECKBOX_LINE.exec(raw);
37080
+ if (m === null) continue;
37081
+ if (out.length < LIST_CAP) {
37082
+ out.push(_clip((m[2] ?? "").replace(/\*\*/g, "")));
37083
+ }
37084
+ }
37085
+ return out;
37086
+ }
37087
+ function buildContinuityRecord(input) {
37088
+ const { root, sessionId: sessionId3, slug, counters } = input;
37089
+ const now = input.now ?? /* @__PURE__ */ new Date();
37090
+ if (!is_substantive(counters)) {
37091
+ return {
37092
+ record: null,
37093
+ reason: "no record \u2014 the session is not substantive by the committed floor"
37094
+ };
37095
+ }
37096
+ if (slug === null || slug.trim() === "") {
37097
+ return {
37098
+ record: null,
37099
+ reason: "no record \u2014 no claimed roadmap, so no deterministic acceptance criterion exists"
37100
+ };
37101
+ }
37102
+ let text;
37103
+ try {
37104
+ text = fs95.readFileSync(roadmapPath(root, slug), "utf-8");
37105
+ } catch {
37106
+ return { record: null, reason: `no record \u2014 the claimed roadmap ${slug} is not readable` };
37107
+ }
37108
+ const shape = roadmapShape(text);
37109
+ if (shape.total === 0) {
37110
+ return { record: null, reason: `no record \u2014 ${slug} carries no phase checkboxes to count` };
37111
+ }
37112
+ const declared = acceptanceCriteria(text);
37113
+ const criteria = declared.length > 0 ? declared : (
37114
+ // A roadmap with no declared criteria still has one definitional
37115
+ // completion condition, and it is derived from the artefact class
37116
+ // rather than judged: every step closed. Anything richer would be
37117
+ // a definition of done nobody wrote.
37118
+ [`every phase step in agents/roadmaps/${slug}.md is closed`]
37119
+ );
37120
+ const record = {
37121
+ capsule_version: CAPSULE_SCHEMA_VERSION,
37122
+ variant: "continuity_record",
37123
+ summary: _clip(`${slug}: ${shape.done} of ${shape.total} steps closed`),
37124
+ task: _clip(slug),
37125
+ workspace: root,
37126
+ written_at: now.toISOString(),
37127
+ acceptance_criteria: criteria.slice(0, MAX_ENTRIES),
37128
+ remaining: shape.open.slice(0, MAX_ENTRIES),
37129
+ predecessor: resolvePredecessor(root, sessionId3),
37130
+ artifact_paths: [`agents/roadmaps/${slug}.md`]
37131
+ };
37132
+ if (sessionId3.trim() !== "") {
37133
+ record["session_id"] = sessionId3.trim();
37134
+ }
37135
+ const head = readHead(root);
37136
+ if (head !== null) {
37137
+ record["head"] = head;
37138
+ }
37139
+ return { record, reason: `record built for ${slug} (${shape.done}/${shape.total} closed)` };
37140
+ }
37141
+
37142
+ // src/scripts/_lib/continuity_slot.ts
37143
+ import * as fs96 from "node:fs";
37144
+ import * as path96 from "node:path";
37145
+ var MAX_AGE_MS = RECYCLE_MAX_AGE_HOURS * 3600 * 1e3;
37146
+ function _parse2(file) {
37147
+ try {
37148
+ const decoded = JSON.parse(fs96.readFileSync(file, "utf-8"));
37149
+ if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
37150
+ return decoded;
37151
+ }
37152
+ return null;
37153
+ } catch {
37154
+ return null;
37155
+ }
37156
+ }
37157
+ function _ageMs(record, now) {
37158
+ const raw = record["written_at"];
37159
+ if (typeof raw !== "string") return null;
37160
+ const at = Date.parse(raw);
37161
+ if (Number.isNaN(at)) return null;
37162
+ return now.getTime() - at;
37163
+ }
37164
+ function inspectSlot(workspace_root, session_id, now = /* @__PURE__ */ new Date()) {
37165
+ const target = path96.join(workspace_root, recycle_envelope_rel(session_id));
37166
+ if (!fs96.existsSync(target)) {
37167
+ const consumed = path96.join(workspace_root, recycle_consumed_rel(session_id));
37168
+ if (fs96.existsSync(consumed)) {
37169
+ return { state: "consumed", reason: "the record for this session was consumed", target };
37170
+ }
37171
+ const quarantined = path96.join(workspace_root, recycle_quarantine_rel(session_id));
37172
+ if (fs96.existsSync(quarantined)) {
37173
+ return {
37174
+ state: "quarantined",
37175
+ reason: "the slot is free; an unusable record sits in quarantine",
37176
+ target
37177
+ };
37178
+ }
37179
+ return { state: "absent", reason: "no record in this slot", target };
37180
+ }
37181
+ const resident = _parse2(target);
37182
+ if (resident === null) {
37183
+ return { state: "quarantined", reason: "the resident record does not parse as an object", target };
37184
+ }
37185
+ const violations = validateRecycleEnvelope(resident);
37186
+ if (violations.length > 0) {
37187
+ return {
37188
+ state: "quarantined",
37189
+ reason: `the resident record fails validation (${violations.length} violation(s))`,
37190
+ target,
37191
+ resident
37192
+ };
37193
+ }
37194
+ const age = _ageMs(resident, now);
37195
+ if (age === null || age > MAX_AGE_MS) {
37196
+ return {
37197
+ state: "quarantined",
37198
+ reason: age === null ? "the resident record carries no parseable written_at" : `the resident record is older than ${RECYCLE_MAX_AGE_HOURS} h`,
37199
+ target,
37200
+ resident
37201
+ };
37202
+ }
37203
+ const owner = String(resident["session_id"] ?? "").trim();
37204
+ const mine = String(session_id ?? "").trim();
37205
+ if (owner !== "" && mine !== "" && owner !== mine) {
37206
+ return {
37207
+ state: "conflicting",
37208
+ reason: `the slot holds an unconsumed record belonging to session ${owner}`,
37209
+ target,
37210
+ resident
37211
+ };
37212
+ }
37213
+ return { state: "published", reason: "this session has an unconsumed record", target, resident };
37214
+ }
37215
+ function publishContinuityRecord(workspace_root, session_id, record, now = /* @__PURE__ */ new Date()) {
37216
+ const violations = validateRecycleEnvelope(record);
37217
+ if (violations.length > 0) {
37218
+ return {
37219
+ state: "absent",
37220
+ wrote: false,
37221
+ reason: `refused \u2014 the record to publish fails validation: ${violations[0]}`
37222
+ };
37223
+ }
37224
+ const bytes = Buffer.byteLength(JSON.stringify(record, null, 2), "utf-8");
37225
+ if (bytes > RECYCLE_ENVELOPE_MAX_BYTES) {
37226
+ return {
37227
+ state: "absent",
37228
+ wrote: false,
37229
+ reason: `refused \u2014 ${bytes} bytes exceeds the ${RECYCLE_ENVELOPE_MAX_BYTES} byte slot cap`
37230
+ };
37231
+ }
37232
+ const target = path96.join(workspace_root, recycle_envelope_rel(session_id));
37233
+ const before = inspectSlot(workspace_root, session_id, now);
37234
+ if (before.state === "conflicting") {
37235
+ return { state: "conflicting", wrote: false, reason: `refused \u2014 ${before.reason}` };
37236
+ }
37237
+ if (before.state === "published" && before.resident !== void 0) {
37238
+ const residentAt = Date.parse(String(before.resident["written_at"] ?? ""));
37239
+ const incomingAt = Date.parse(String(record["written_at"] ?? ""));
37240
+ if (!Number.isNaN(residentAt) && !Number.isNaN(incomingAt) && incomingAt < residentAt) {
37241
+ return {
37242
+ state: "published",
37243
+ wrote: false,
37244
+ reason: "refused \u2014 the resident record is newer than the one offered"
37245
+ };
37246
+ }
37247
+ }
37248
+ let quarantined;
37249
+ if (before.state === "quarantined" && fs96.existsSync(target)) {
37250
+ const dest = path96.join(workspace_root, recycle_quarantine_rel(session_id));
37251
+ try {
37252
+ fs96.mkdirSync(path96.dirname(dest), { recursive: true });
37253
+ fs96.renameSync(target, dest);
37254
+ quarantined = dest;
37255
+ } catch (exc) {
37256
+ return {
37257
+ state: "quarantined",
37258
+ wrote: false,
37259
+ reason: `refused \u2014 could not quarantine the unusable resident: ${String(exc)}`
37260
+ };
37261
+ }
37262
+ }
37263
+ const result = update_json_under_lock(target, () => record);
37264
+ if (result !== "written") {
37265
+ return {
37266
+ state: before.state,
37267
+ wrote: false,
37268
+ reason: `refused \u2014 the slot write did not complete (${result})`,
37269
+ ...quarantined !== void 0 ? { quarantined } : {}
37270
+ };
37271
+ }
37272
+ return {
37273
+ state: "published",
37274
+ wrote: true,
37275
+ reason: before.state === "published" ? "superseded this session\u2019s earlier record" : `published into a ${before.state} slot`,
37276
+ ...quarantined !== void 0 ? { quarantined } : {}
37277
+ };
37278
+ }
37279
+
36708
37280
  // src/scripts/hooks/session_eol_hook.ts
36709
37281
  var EXIT_WARN19 = 2;
36710
37282
  var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
36711
- var CONTEXT_FILL_REL = path96.join("agents", "runtime", "state", "context-fill.json");
37283
+ var CONTEXT_FILL_REL = path97.join("agents", "runtime", "state", "context-fill.json");
36712
37284
  function str12(value) {
36713
37285
  return typeof value === "string" ? value : "";
36714
37286
  }
@@ -36723,7 +37295,7 @@ function payloadSessionId(payload, envelope) {
36723
37295
  }
36724
37296
  function readState4(file) {
36725
37297
  try {
36726
- const parsed = JSON.parse(fs95.readFileSync(file, "utf-8"));
37298
+ const parsed = JSON.parse(fs97.readFileSync(file, "utf-8"));
36727
37299
  if (parsed && typeof parsed === "object" && parsed.schema_version === 1 && parsed.counters && typeof parsed.counters.scanned_bytes === "number") {
36728
37300
  return {
36729
37301
  schema_version: 1,
@@ -36744,10 +37316,10 @@ function readState4(file) {
36744
37316
  };
36745
37317
  }
36746
37318
  function envelopeExists(workspaceRoot3, since = null, sessionId3 = null) {
36747
- const target = path96.join(workspaceRoot3, recycle_envelope_rel(sessionId3));
37319
+ const target = path97.join(workspaceRoot3, recycle_envelope_rel(sessionId3));
36748
37320
  let raw;
36749
37321
  try {
36750
- raw = fs95.readFileSync(target, "utf-8");
37322
+ raw = fs97.readFileSync(target, "utf-8");
36751
37323
  } catch (exc) {
36752
37324
  return exc?.code !== "ENOENT";
36753
37325
  }
@@ -36761,7 +37333,7 @@ function envelopeExists(workspaceRoot3, since = null, sessionId3 = null) {
36761
37333
  }
36762
37334
  }
36763
37335
  function buildMissingEnvelopeLine(workspaceRoot3, sessionId3 = null) {
36764
- return `recycle advised earlier, but no envelope exists at ${path96.join(workspaceRoot3, recycle_envelope_rel(sessionId3))} \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.`;
37336
+ return `recycle advised earlier, but no envelope exists at ${path97.join(workspaceRoot3, recycle_envelope_rel(sessionId3))} \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.`;
36765
37337
  }
36766
37338
  function readThresholdTokens() {
36767
37339
  const override = process16.env[THRESHOLD_OVERRIDE_ENV];
@@ -36777,7 +37349,7 @@ function buildAdvisoryLine4(tokens, threshold) {
36777
37349
  }
36778
37350
  function writeContextFill(workspaceRoot3, tokens, threshold, ts) {
36779
37351
  try {
36780
- atomic_write_json(path96.join(workspaceRoot3, CONTEXT_FILL_REL), {
37352
+ atomic_write_json(path97.join(workspaceRoot3, CONTEXT_FILL_REL), {
36781
37353
  schema_version: 1,
36782
37354
  final_context_tokens: tokens,
36783
37355
  recycle_threshold_tokens: threshold,
@@ -36837,7 +37409,7 @@ function main61() {
36837
37409
  }
36838
37410
  writeContextFill(workspaceRoot3, tokens, threshold, now);
36839
37411
  const checkpointRunId = payloadSessionId(payload, envelope);
36840
- if (shouldAdvise && checkpointRunId !== "") {
37412
+ if (shouldAdvise && checkpointRunId !== "" && run_checkpoints_enabled(workspaceRoot3)) {
36841
37413
  try {
36842
37414
  const slug = read_claimed_slug(workspaceRoot3, checkpointRunId);
36843
37415
  if (slug !== null) {
@@ -36850,6 +37422,7 @@ function main61() {
36850
37422
  } catch {
36851
37423
  }
36852
37424
  }
37425
+ writeContinuityRecord(workspaceRoot3, rawSessionId, counters, threshold, tokens);
36853
37426
  if (shouldAdvise && threshold !== null && tokens !== null) {
36854
37427
  process16.stdout.write(
36855
37428
  `${JSON.stringify({
@@ -36874,6 +37447,24 @@ function main61() {
36874
37447
  }
36875
37448
  return 0;
36876
37449
  }
37450
+ function writeContinuityRecord(workspaceRoot3, rawSessionId, counters, threshold, tokens) {
37451
+ if (threshold === null || tokens === null || tokens < threshold) return;
37452
+ const sessionId3 = String(rawSessionId ?? "").trim();
37453
+ if (sessionId3 === "") return;
37454
+ try {
37455
+ if (!auto_record_enabled(workspaceRoot3)) return;
37456
+ const slug = read_claimed_slug(workspaceRoot3, sessionId3);
37457
+ const decision = buildContinuityRecord({
37458
+ root: workspaceRoot3,
37459
+ sessionId: sessionId3,
37460
+ slug,
37461
+ counters
37462
+ });
37463
+ if (decision.record === null) return;
37464
+ publishContinuityRecord(workspaceRoot3, sessionId3, decision.record);
37465
+ } catch {
37466
+ }
37467
+ }
36877
37468
  function _isCliEntry44() {
36878
37469
  if (true) {
36879
37470
  return false;
@@ -36881,13 +37472,13 @@ function _isCliEntry44() {
36881
37472
  if (process16.argv[1] === void 0) {
36882
37473
  return false;
36883
37474
  }
36884
- const argvUrl = pathToFileURL54(path96.resolve(process16.argv[1])).href;
37475
+ const argvUrl = pathToFileURL54(path97.resolve(process16.argv[1])).href;
36885
37476
  if (import.meta.url === argvUrl) {
36886
37477
  return true;
36887
37478
  }
36888
37479
  try {
36889
- const here = fs95.realpathSync(fileURLToPath63(import.meta.url));
36890
- const argv = fs95.realpathSync(path96.resolve(process16.argv[1]));
37480
+ const here = fs97.realpathSync(fileURLToPath63(import.meta.url));
37481
+ const argv = fs97.realpathSync(path97.resolve(process16.argv[1]));
36891
37482
  return here === argv;
36892
37483
  } catch {
36893
37484
  return false;
@@ -36898,14 +37489,14 @@ if (_isCliEntry44()) {
36898
37489
  }
36899
37490
 
36900
37491
  // src/scripts/hooks/tool_result_bytes_hook.ts
36901
- import * as fs96 from "node:fs";
36902
- import * as path97 from "node:path";
37492
+ import * as fs98 from "node:fs";
37493
+ import * as path98 from "node:path";
36903
37494
  import { fileURLToPath as fileURLToPath64, pathToFileURL as pathToFileURL55 } from "node:url";
36904
37495
  var EXIT_ALLOW31 = 0;
36905
37496
  function isObject17(v) {
36906
37497
  return typeof v === "object" && v !== null && !Array.isArray(v);
36907
37498
  }
36908
- var CENSUS_FILE = path97.join("agents", "runtime", "state", "tool-result-census.jsonl");
37499
+ var CENSUS_FILE = path98.join("agents", "runtime", "state", "tool-result-census.jsonl");
36909
37500
  var RESULT_KEYS = ["tool_response", "toolResponse", "tool_result", "toolUseResult"];
36910
37501
  function _resultBytes(payload) {
36911
37502
  for (const key of RESULT_KEYS) {
@@ -36940,13 +37531,13 @@ function unwrapPayload4(envelope) {
36940
37531
  return isObject17(inner) ? inner : envelope;
36941
37532
  }
36942
37533
  function censusFile(consumerRoot) {
36943
- return path97.join(consumerRoot, CENSUS_FILE);
37534
+ return path98.join(consumerRoot, CENSUS_FILE);
36944
37535
  }
36945
37536
  function _appendCensusLine(consumerRoot, line) {
36946
37537
  if (is_replay_mode()) return;
36947
37538
  const file = censusFile(consumerRoot);
36948
- fs96.mkdirSync(path97.dirname(file), { recursive: true });
36949
- fs96.appendFileSync(file, `${JSON.stringify(line)}
37539
+ fs98.mkdirSync(path98.dirname(file), { recursive: true });
37540
+ fs98.appendFileSync(file, `${JSON.stringify(line)}
36950
37541
  `, "utf8");
36951
37542
  }
36952
37543
  function processEnvelope4(envelope, consumerRoot) {
@@ -36992,10 +37583,10 @@ function _isCliEntry45() {
36992
37583
  return false;
36993
37584
  }
36994
37585
  if (process.argv[1] === void 0) return false;
36995
- const argvUrl = pathToFileURL55(path97.resolve(process.argv[1])).href;
37586
+ const argvUrl = pathToFileURL55(path98.resolve(process.argv[1])).href;
36996
37587
  if (import.meta.url === argvUrl) return true;
36997
37588
  try {
36998
- return fs96.realpathSync(fileURLToPath64(import.meta.url)) === fs96.realpathSync(path97.resolve(process.argv[1]));
37589
+ return fs98.realpathSync(fileURLToPath64(import.meta.url)) === fs98.realpathSync(path98.resolve(process.argv[1]));
36999
37590
  } catch {
37000
37591
  return false;
37001
37592
  }
@@ -37003,8 +37594,8 @@ function _isCliEntry45() {
37003
37594
  if (_isCliEntry45()) process.exit(main62());
37004
37595
 
37005
37596
  // src/scripts/hooks/spawn_guard_shadow_hook.ts
37006
- import * as fs97 from "node:fs";
37007
- import * as path98 from "node:path";
37597
+ import * as fs99 from "node:fs";
37598
+ import * as path99 from "node:path";
37008
37599
  import { fileURLToPath as fileURLToPath65, pathToFileURL as pathToFileURL56 } from "node:url";
37009
37600
  var EXIT_ALLOW32 = 0;
37010
37601
  function isObject18(v) {
@@ -37082,10 +37673,10 @@ function main63() {
37082
37673
  function _isCliEntry46() {
37083
37674
  if (true) return false;
37084
37675
  if (process.argv[1] === void 0) return false;
37085
- const argvUrl = pathToFileURL56(path98.resolve(process.argv[1])).href;
37676
+ const argvUrl = pathToFileURL56(path99.resolve(process.argv[1])).href;
37086
37677
  if (import.meta.url === argvUrl) return true;
37087
37678
  try {
37088
- return fs97.realpathSync(fileURLToPath65(import.meta.url)) === fs97.realpathSync(path98.resolve(process.argv[1]));
37679
+ return fs99.realpathSync(fileURLToPath65(import.meta.url)) === fs99.realpathSync(path99.resolve(process.argv[1]));
37089
37680
  } catch {
37090
37681
  return false;
37091
37682
  }
@@ -37093,13 +37684,13 @@ function _isCliEntry46() {
37093
37684
  if (_isCliEntry46()) process.exit(main63());
37094
37685
 
37095
37686
  // src/scripts/hooks/source_first_gate_hook.ts
37096
- import * as fs98 from "node:fs";
37097
- import * as path99 from "node:path";
37687
+ import * as fs100 from "node:fs";
37688
+ import * as path100 from "node:path";
37098
37689
  import { fileURLToPath as fileURLToPath66, pathToFileURL as pathToFileURL57 } from "node:url";
37099
37690
  var EXIT_ALLOW33 = 0;
37100
37691
  var MAX_SHADOW_WARNS = 2;
37101
- var SHADOW_LOG = path99.join("agents", "runtime", "state", "source-first-gate.jsonl");
37102
- var STATE_FILE9 = path99.join("agents", "runtime", "state", "source-first-gate.json");
37692
+ var SHADOW_LOG = path100.join("agents", "runtime", "state", "source-first-gate.jsonl");
37693
+ var STATE_FILE9 = path100.join("agents", "runtime", "state", "source-first-gate.json");
37103
37694
  function isObject19(v) {
37104
37695
  return typeof v === "object" && v !== null && !Array.isArray(v);
37105
37696
  }
@@ -37173,7 +37764,7 @@ var EMPTY_STATE = { handoverSeen: false, sourceRead: false, wouldWarn: 0 };
37173
37764
  var MAX_SESSIONS2 = 50;
37174
37765
  function readState5(root, session) {
37175
37766
  try {
37176
- const all = JSON.parse(fs98.readFileSync(path99.join(root, STATE_FILE9), "utf-8"));
37767
+ const all = JSON.parse(fs100.readFileSync(path100.join(root, STATE_FILE9), "utf-8"));
37177
37768
  const entry = all[session];
37178
37769
  if (entry && typeof entry.handoverSeen === "boolean" && typeof entry.sourceRead === "boolean" && typeof entry.wouldWarn === "number") {
37179
37770
  return entry;
@@ -37185,10 +37776,10 @@ function readState5(root, session) {
37185
37776
  function writeState4(root, session, state) {
37186
37777
  if (is_replay_mode()) return;
37187
37778
  try {
37188
- const file = path99.join(root, STATE_FILE9);
37779
+ const file = path100.join(root, STATE_FILE9);
37189
37780
  let all = {};
37190
37781
  try {
37191
- all = JSON.parse(fs98.readFileSync(file, "utf-8"));
37782
+ all = JSON.parse(fs100.readFileSync(file, "utf-8"));
37192
37783
  } catch {
37193
37784
  }
37194
37785
  if (!isObject19(all)) all = {};
@@ -37199,8 +37790,8 @@ function writeState4(root, session, state) {
37199
37790
  for (const key of keys.slice(keys.length - MAX_SESSIONS2)) pruned[key] = all[key];
37200
37791
  all = pruned;
37201
37792
  }
37202
- fs98.mkdirSync(path99.dirname(file), { recursive: true });
37203
- fs98.writeFileSync(file, JSON.stringify(all));
37793
+ fs100.mkdirSync(path100.dirname(file), { recursive: true });
37794
+ fs100.writeFileSync(file, JSON.stringify(all));
37204
37795
  } catch {
37205
37796
  }
37206
37797
  }
@@ -37221,7 +37812,7 @@ function evaluateCandidates2(handoverSeen, handoverOnDisk, sourceRead) {
37221
37812
  }
37222
37813
  function handoverPresentOnDisk(root) {
37223
37814
  try {
37224
- return fs98.statSync(path99.join(root, ".claude", "design-system")).isDirectory();
37815
+ return fs100.statSync(path100.join(root, ".claude", "design-system")).isDirectory();
37225
37816
  } catch {
37226
37817
  return false;
37227
37818
  }
@@ -37229,9 +37820,9 @@ function handoverPresentOnDisk(root) {
37229
37820
  function appendShadowLine(root, line) {
37230
37821
  if (is_replay_mode()) return;
37231
37822
  try {
37232
- const file = path99.join(root, SHADOW_LOG);
37233
- fs98.mkdirSync(path99.dirname(file), { recursive: true });
37234
- fs98.appendFileSync(file, `${JSON.stringify(line)}
37823
+ const file = path100.join(root, SHADOW_LOG);
37824
+ fs100.mkdirSync(path100.dirname(file), { recursive: true });
37825
+ fs100.appendFileSync(file, `${JSON.stringify(line)}
37235
37826
  `, "utf8");
37236
37827
  } catch {
37237
37828
  }
@@ -37307,10 +37898,10 @@ function main64() {
37307
37898
  function _isCliEntry47() {
37308
37899
  if (true) return false;
37309
37900
  if (process.argv[1] === void 0) return false;
37310
- const argvUrl = pathToFileURL57(path99.resolve(process.argv[1])).href;
37901
+ const argvUrl = pathToFileURL57(path100.resolve(process.argv[1])).href;
37311
37902
  if (import.meta.url === argvUrl) return true;
37312
37903
  try {
37313
- return fs98.realpathSync(fileURLToPath66(import.meta.url)) === fs98.realpathSync(path99.resolve(process.argv[1]));
37904
+ return fs100.realpathSync(fileURLToPath66(import.meta.url)) === fs100.realpathSync(path100.resolve(process.argv[1]));
37314
37905
  } catch {
37315
37906
  return false;
37316
37907
  }
@@ -37318,12 +37909,12 @@ function _isCliEntry47() {
37318
37909
  if (_isCliEntry47()) process.exit(main64());
37319
37910
 
37320
37911
  // src/scripts/hooks/interruption_ledger_hook.ts
37321
- import * as fs99 from "node:fs";
37322
- import * as path100 from "node:path";
37912
+ import * as fs101 from "node:fs";
37913
+ import * as path101 from "node:path";
37323
37914
  import { fileURLToPath as fileURLToPath67, pathToFileURL as pathToFileURL58 } from "node:url";
37324
37915
  var EXIT_OK2 = 0;
37325
37916
  var TRANSCRIPT_READ_MAX_BYTES2 = 2 * 1024 * 1024;
37326
- var LEDGER_RELPATH = path100.join("agents", "runtime", "state", "interruptions.jsonl");
37917
+ var LEDGER_RELPATH = path101.join("agents", "runtime", "state", "interruptions.jsonl");
37327
37918
  function hasNumberedOptions(reply) {
37328
37919
  let count = 0;
37329
37920
  for (const line of reply.split("\n")) {
@@ -37347,14 +37938,14 @@ function classifyReply(reply) {
37347
37938
  function readClaimedRoadmap(workspaceRoot3, sessionId3) {
37348
37939
  if (!sessionId3) return null;
37349
37940
  try {
37350
- const file = path100.join(
37941
+ const file = path101.join(
37351
37942
  workspaceRoot3,
37352
37943
  "agents",
37353
37944
  "runtime",
37354
37945
  "state",
37355
37946
  `roadmap-claim-${sessionId3}.json`
37356
37947
  );
37357
- const parsed = JSON.parse(fs99.readFileSync(file, "utf8"));
37948
+ const parsed = JSON.parse(fs101.readFileSync(file, "utf8"));
37358
37949
  if (parsed === null || typeof parsed !== "object") return null;
37359
37950
  const slug = parsed["slug"];
37360
37951
  return typeof slug === "string" && slug.length > 0 ? slug : null;
@@ -37365,7 +37956,7 @@ function readClaimedRoadmap(workspaceRoot3, sessionId3) {
37365
37956
  function alreadyRecorded(ledgerPath, runId, turn) {
37366
37957
  let raw;
37367
37958
  try {
37368
- raw = fs99.readFileSync(ledgerPath, "utf8");
37959
+ raw = fs101.readFileSync(ledgerPath, "utf8");
37369
37960
  } catch {
37370
37961
  return false;
37371
37962
  }
@@ -37409,7 +38000,7 @@ function main65() {
37409
38000
  if (!lastAssistant) return EXIT_OK2;
37410
38001
  const sessionId3 = str14(payload["session_id"]) || str14(envelope["session_id"]);
37411
38002
  const runId = sessionId3 ? derive_session_tag(sessionId3) : "unknown";
37412
- const ledgerPath = path100.join(workspaceRoot3, LEDGER_RELPATH);
38003
+ const ledgerPath = path101.join(workspaceRoot3, LEDGER_RELPATH);
37413
38004
  if (alreadyRecorded(ledgerPath, runId, turnOrdinal)) return EXIT_OK2;
37414
38005
  const verdict2 = classifyReply(lastAssistant);
37415
38006
  const record = {
@@ -37421,8 +38012,8 @@ function main65() {
37421
38012
  at: (/* @__PURE__ */ new Date()).toISOString()
37422
38013
  };
37423
38014
  try {
37424
- fs99.mkdirSync(path100.dirname(ledgerPath), { recursive: true });
37425
- fs99.appendFileSync(ledgerPath, `${JSON.stringify(record)}
38015
+ fs101.mkdirSync(path101.dirname(ledgerPath), { recursive: true });
38016
+ fs101.appendFileSync(ledgerPath, `${JSON.stringify(record)}
37426
38017
  `, "utf8");
37427
38018
  } catch {
37428
38019
  }
@@ -37432,13 +38023,13 @@ function _isCliEntry48() {
37432
38023
  if (process.argv[1] === void 0) {
37433
38024
  return false;
37434
38025
  }
37435
- const argvUrl = pathToFileURL58(path100.resolve(process.argv[1])).href;
38026
+ const argvUrl = pathToFileURL58(path101.resolve(process.argv[1])).href;
37436
38027
  if (import.meta.url === argvUrl) {
37437
38028
  return true;
37438
38029
  }
37439
38030
  try {
37440
- const here = fs99.realpathSync(fileURLToPath67(import.meta.url));
37441
- const argv = fs99.realpathSync(path100.resolve(process.argv[1]));
38031
+ const here = fs101.realpathSync(fileURLToPath67(import.meta.url));
38032
+ const argv = fs101.realpathSync(path101.resolve(process.argv[1]));
37442
38033
  return here === argv;
37443
38034
  } catch {
37444
38035
  return false;
@@ -37449,15 +38040,15 @@ if (_isCliEntry48()) {
37449
38040
  }
37450
38041
 
37451
38042
  // src/scripts/hooks/run_continuation_hook.ts
37452
- import * as fs101 from "node:fs";
38043
+ import * as fs103 from "node:fs";
37453
38044
 
37454
38045
  // src/scripts/_lib/billing_grant.ts
37455
- import * as fs100 from "node:fs";
37456
- import * as path101 from "node:path";
37457
- var BILLING_GRANT_DIR_REL = path101.join("agents", "runtime", "billing-grants");
38046
+ import * as fs102 from "node:fs";
38047
+ import * as path102 from "node:path";
38048
+ var BILLING_GRANT_DIR_REL = path102.join("agents", "runtime", "billing-grants");
37458
38049
  var BILLING_GRANT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
37459
38050
  function grantFile(repoRoot, runId) {
37460
- return path101.join(
38051
+ return path102.join(
37461
38052
  repoRoot,
37462
38053
  BILLING_GRANT_DIR_REL,
37463
38054
  `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`
@@ -37465,13 +38056,13 @@ function grantFile(repoRoot, runId) {
37465
38056
  }
37466
38057
  function revokeBillingGrant(repoRoot, runId) {
37467
38058
  try {
37468
- fs100.unlinkSync(grantFile(repoRoot, runId));
38059
+ fs102.unlinkSync(grantFile(repoRoot, runId));
37469
38060
  } catch {
37470
38061
  }
37471
38062
  }
37472
38063
 
37473
38064
  // src/scripts/hooks/run_continuation_hook.ts
37474
- import * as path102 from "node:path";
38065
+ import * as path103 from "node:path";
37475
38066
  import { fileURLToPath as fileURLToPath68, pathToFileURL as pathToFileURL59 } from "node:url";
37476
38067
 
37477
38068
  // src/scripts/_lib/outcome_vocabularies.ts
@@ -37562,13 +38153,13 @@ var EXIT_ALLOW34 = 0;
37562
38153
  var EXIT_BLOCK4 = 1;
37563
38154
  var BLOCKED_BY_MARKER = /<!--\s*blocked-by:\s*\S[^>]*-->/;
37564
38155
  var LEDGER_TAIL_MAX_BYTES = 512 * 1024;
37565
- var EVENTS_RELPATH = path102.join(
38156
+ var EVENTS_RELPATH = path103.join(
37566
38157
  "agents",
37567
38158
  "runtime",
37568
38159
  "state",
37569
38160
  "run-continuation.jsonl"
37570
38161
  );
37571
- var STATE_DIR_REL = path102.join("agents", "runtime", "state");
38162
+ var STATE_DIR_REL = path103.join("agents", "runtime", "state");
37572
38163
  var ABSENT_CONFIRM_FIRES = 2;
37573
38164
  var DUPLICATE_WINDOW_MS = 60 * 1e3;
37574
38165
  function isDuplicateFire(state, turnOrdinal, openCount, nowMs, roadmapSource) {
@@ -37640,20 +38231,20 @@ function extractVerify(stepText) {
37640
38231
  function stateRelPath(runId, slug) {
37641
38232
  const safeRun = runId.replace(/[^A-Za-z0-9_-]/g, "_");
37642
38233
  const safeSlug = slug.replace(/[^A-Za-z0-9_-]/g, "_");
37643
- return path102.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
38234
+ return path103.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
37644
38235
  }
37645
38236
  function legacyStateRelPath(runId) {
37646
38237
  const safe = runId.replace(/[^A-Za-z0-9_-]/g, "_");
37647
- return path102.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
38238
+ return path103.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
37648
38239
  }
37649
38240
  function readRunState(workspaceRoot3, runId, slug) {
37650
- const keyedFile = path102.join(workspaceRoot3, stateRelPath(runId, slug));
38241
+ const keyedFile = path103.join(workspaceRoot3, stateRelPath(runId, slug));
37651
38242
  const keyed = readState6(keyedFile);
37652
38243
  if (keyed !== null) return { state: keyed, from: "keyed", keyedFile };
37653
38244
  if (fileExists(keyedFile)) {
37654
38245
  return { state: null, from: "keyed", keyedFile };
37655
38246
  }
37656
- const legacy = readState6(path102.join(workspaceRoot3, legacyStateRelPath(runId)));
38247
+ const legacy = readState6(path103.join(workspaceRoot3, legacyStateRelPath(runId)));
37657
38248
  if (legacy === null) return { state: null, from: "none", keyedFile };
37658
38249
  if (legacy.roadmap !== void 0 && legacy.roadmap !== slug) {
37659
38250
  return { state: null, from: "none", keyedFile };
@@ -37666,25 +38257,25 @@ function writeState5(file, state) {
37666
38257
  function clearRunState(workspaceRoot3, runId, keyedFile, adoptedLegacy) {
37667
38258
  revokeBillingGrant(workspaceRoot3, runId);
37668
38259
  try {
37669
- fs101.rmSync(keyedFile, { force: true });
38260
+ fs103.rmSync(keyedFile, { force: true });
37670
38261
  } catch {
37671
38262
  }
37672
38263
  if (!adoptedLegacy) return;
37673
38264
  try {
37674
- fs101.rmSync(path102.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
38265
+ fs103.rmSync(path103.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
37675
38266
  } catch {
37676
38267
  }
37677
38268
  }
37678
38269
  function fileExists(p) {
37679
38270
  try {
37680
- return fs101.statSync(p).isFile();
38271
+ return fs103.statSync(p).isFile();
37681
38272
  } catch {
37682
38273
  return false;
37683
38274
  }
37684
38275
  }
37685
38276
  function readState6(file) {
37686
38277
  try {
37687
- const parsed = JSON.parse(fs101.readFileSync(file, "utf8"));
38278
+ const parsed = JSON.parse(fs103.readFileSync(file, "utf8"));
37688
38279
  if (parsed === null || typeof parsed !== "object") return null;
37689
38280
  const o = parsed;
37690
38281
  if (typeof o["started_at"] !== "string") return null;
@@ -37725,16 +38316,16 @@ function readState6(file) {
37725
38316
  }
37726
38317
  }
37727
38318
  function normalizeDir(p) {
37728
- const abs = path102.resolve(p);
38319
+ const abs = path103.resolve(p);
37729
38320
  try {
37730
- return fs101.realpathSync(abs);
38321
+ return fs103.realpathSync(abs);
37731
38322
  } catch {
37732
38323
  return abs;
37733
38324
  }
37734
38325
  }
37735
38326
  function normalizeFile(p) {
37736
- const abs = path102.resolve(p);
37737
- return path102.join(normalizeDir(path102.dirname(abs)), path102.basename(abs));
38327
+ const abs = path103.resolve(p);
38328
+ return path103.join(normalizeDir(path103.dirname(abs)), path103.basename(abs));
37738
38329
  }
37739
38330
  function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
37740
38331
  const reader = normalizeDir(workspaceRoot3);
@@ -37761,36 +38352,36 @@ function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
37761
38352
  };
37762
38353
  }
37763
38354
  function resolveRoadmap(sessionRoot, workspaceRoot3, slug) {
37764
- const dirRel = path102.join("agents", "roadmaps");
38355
+ const dirRel = path103.join("agents", "roadmaps");
37765
38356
  const stem = slug.trim().replace(/\.md$/, "");
37766
- const rel = path102.join(dirRel, `${stem}.md`);
37767
- const norm = path102.normalize(rel);
37768
- if (path102.dirname(norm) !== dirRel) return null;
37769
- if (sessionRoot !== workspaceRoot3 && isDirectory(path102.join(sessionRoot, dirRel))) {
37770
- return path102.join(sessionRoot, norm);
38357
+ const rel = path103.join(dirRel, `${stem}.md`);
38358
+ const norm = path103.normalize(rel);
38359
+ if (path103.dirname(norm) !== dirRel) return null;
38360
+ if (sessionRoot !== workspaceRoot3 && isDirectory(path103.join(sessionRoot, dirRel))) {
38361
+ return path103.join(sessionRoot, norm);
37771
38362
  }
37772
- return path102.join(normalizeDir(workspaceRoot3), norm);
38363
+ return path103.join(normalizeDir(workspaceRoot3), norm);
37773
38364
  }
37774
38365
  function isDirectory(p) {
37775
38366
  try {
37776
- return fs101.statSync(p).isDirectory();
38367
+ return fs103.statSync(p).isDirectory();
37777
38368
  } catch {
37778
38369
  return false;
37779
38370
  }
37780
38371
  }
37781
38372
  function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
37782
38373
  try {
37783
- const file = path102.join(workspaceRoot3, EVENTS_RELPATH);
37784
- const size = fs101.statSync(file).size;
38374
+ const file = path103.join(workspaceRoot3, EVENTS_RELPATH);
38375
+ const size = fs103.statSync(file).size;
37785
38376
  const start = Math.max(0, size - LEDGER_TAIL_MAX_BYTES);
37786
- const fd = fs101.openSync(file, "r");
38377
+ const fd = fs103.openSync(file, "r");
37787
38378
  let text;
37788
38379
  try {
37789
38380
  const buf = Buffer.alloc(size - start);
37790
- const read = fs101.readSync(fd, buf, 0, buf.length, start);
38381
+ const read = fs103.readSync(fd, buf, 0, buf.length, start);
37791
38382
  text = buf.subarray(0, read).toString("utf8");
37792
38383
  } finally {
37793
- fs101.closeSync(fd);
38384
+ fs103.closeSync(fd);
37794
38385
  }
37795
38386
  for (const line of text.split("\n")) {
37796
38387
  if (line === "") continue;
@@ -37813,9 +38404,9 @@ function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
37813
38404
  }
37814
38405
  function appendEvent2(workspaceRoot3, record) {
37815
38406
  try {
37816
- const file = path102.join(workspaceRoot3, EVENTS_RELPATH);
37817
- fs101.mkdirSync(path102.dirname(file), { recursive: true });
37818
- fs101.appendFileSync(file, `${JSON.stringify(record)}
38407
+ const file = path103.join(workspaceRoot3, EVENTS_RELPATH);
38408
+ fs103.mkdirSync(path103.dirname(file), { recursive: true });
38409
+ fs103.appendFileSync(file, `${JSON.stringify(record)}
37819
38410
  `, "utf8");
37820
38411
  } catch {
37821
38412
  }
@@ -37823,7 +38414,7 @@ function appendEvent2(workspaceRoot3, record) {
37823
38414
  function refusedThisTurn(workspaceRoot3, sessionId3, turnOrdinal) {
37824
38415
  try {
37825
38416
  const file = sessionRefusalFile(workspaceRoot3, deriveSessionKey(sessionId3 || "unknown-session"));
37826
- const rec = parseRecord(fs101.readFileSync(file, "utf-8"));
38417
+ const rec = parseRecord(fs103.readFileSync(file, "utf-8"));
37827
38418
  return rec !== null && rec.refused_turn === turnOrdinal;
37828
38419
  } catch {
37829
38420
  return false;
@@ -37857,7 +38448,7 @@ function main66() {
37857
38448
  let roadmapText = null;
37858
38449
  if (roadmapPath2 !== null) {
37859
38450
  try {
37860
- roadmapText = fs101.readFileSync(roadmapPath2, "utf8");
38451
+ roadmapText = fs103.readFileSync(roadmapPath2, "utf8");
37861
38452
  roadmapFile = roadmapPath2;
37862
38453
  } catch {
37863
38454
  roadmapText = null;
@@ -37906,7 +38497,7 @@ function main66() {
37906
38497
  );
37907
38498
  if (!transcriptPath) return EXIT_ALLOW34;
37908
38499
  try {
37909
- if (fs101.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
38500
+ if (fs103.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
37910
38501
  const inert = readRunState(workspaceRoot3, runId, slug);
37911
38502
  if (inert.state !== null && inert.state.inert_reported !== true) {
37912
38503
  const inertRoots = provenance(
@@ -38065,11 +38656,11 @@ function _isCliEntry49() {
38065
38656
  return false;
38066
38657
  }
38067
38658
  if (process.argv[1] === void 0) return false;
38068
- const argvUrl = pathToFileURL59(path102.resolve(process.argv[1])).href;
38659
+ const argvUrl = pathToFileURL59(path103.resolve(process.argv[1])).href;
38069
38660
  if (import.meta.url === argvUrl) return true;
38070
38661
  try {
38071
- const here = fs101.realpathSync(fileURLToPath68(import.meta.url));
38072
- const argv = fs101.realpathSync(path102.resolve(process.argv[1]));
38662
+ const here = fs103.realpathSync(fileURLToPath68(import.meta.url));
38663
+ const argv = fs103.realpathSync(path103.resolve(process.argv[1]));
38073
38664
  return here === argv;
38074
38665
  } catch {
38075
38666
  return false;
@@ -38080,8 +38671,8 @@ if (_isCliEntry49()) {
38080
38671
  }
38081
38672
 
38082
38673
  // src/scripts/hooks/journal_record_hook.ts
38083
- import * as fs103 from "node:fs";
38084
- import * as path104 from "node:path";
38674
+ import * as fs105 from "node:fs";
38675
+ import * as path105 from "node:path";
38085
38676
  import { fileURLToPath as fileURLToPath69, pathToFileURL as pathToFileURL60 } from "node:url";
38086
38677
 
38087
38678
  // src/scripts/_lib/surface.ts
@@ -38112,8 +38703,8 @@ function readSurface(v) {
38112
38703
 
38113
38704
  // src/scripts/_lib/runtime_journal.ts
38114
38705
  import * as crypto14 from "node:crypto";
38115
- import * as fs102 from "node:fs";
38116
- import * as path103 from "node:path";
38706
+ import * as fs104 from "node:fs";
38707
+ import * as path104 from "node:path";
38117
38708
 
38118
38709
  // src/scripts/_lib/sqlite_schema.ts
38119
38710
  function addColumnIfMissing(db, table, column, decl) {
@@ -38215,7 +38806,7 @@ function requireId(name, id, optional) {
38215
38806
  }
38216
38807
  var JOURNAL_DIR_NAME = "agent-journal";
38217
38808
  var JOURNAL_FILE_NAME = "journal.sqlite";
38218
- var JOURNAL_FALLBACK_REL = path103.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
38809
+ var JOURNAL_FALLBACK_REL = path104.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
38219
38810
  function digest(domain, input) {
38220
38811
  return crypto14.createHash("sha256").update(`${domain}\0${input}`).digest("hex").slice(0, 12);
38221
38812
  }
@@ -38226,20 +38817,20 @@ function resolveJournal(root) {
38226
38817
  if (common !== null) {
38227
38818
  const own = git_dir(root) ?? common;
38228
38819
  return {
38229
- path: path103.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
38820
+ path: path104.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
38230
38821
  scope: "repo-shared",
38231
38822
  reason: "common git dir resolved \u2014 every worktree of this repo writes one database",
38232
38823
  repository_id: digest(REPO_DOMAIN, common),
38233
38824
  worktree_id: digest(WORKTREE_DOMAIN, own)
38234
38825
  };
38235
38826
  }
38236
- let real = path103.resolve(root);
38827
+ let real = path104.resolve(root);
38237
38828
  try {
38238
- real = fs102.realpathSync(real);
38829
+ real = fs104.realpathSync(real);
38239
38830
  } catch {
38240
38831
  }
38241
38832
  return {
38242
- path: path103.join(real, JOURNAL_FALLBACK_REL),
38833
+ path: path104.join(real, JOURNAL_FALLBACK_REL),
38243
38834
  scope: "worktree-local",
38244
38835
  reason: "no common git dir \u2014 not inside a git repository; falling back to the tree-local path",
38245
38836
  repository_id: digest(REPO_DOMAIN, real),
@@ -38327,7 +38918,7 @@ function ensureWal(db) {
38327
38918
  function discard(dbPath) {
38328
38919
  for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
38329
38920
  try {
38330
- fs102.rmSync(p, { force: true });
38921
+ fs104.rmSync(p, { force: true });
38331
38922
  } catch {
38332
38923
  }
38333
38924
  }
@@ -38339,9 +38930,9 @@ function openJournal(root) {
38339
38930
  );
38340
38931
  }
38341
38932
  const location = resolveJournal(root);
38342
- fs102.mkdirSync(path103.dirname(location.path), { recursive: true });
38933
+ fs104.mkdirSync(path104.dirname(location.path), { recursive: true });
38343
38934
  const { DatabaseSync } = loadSqliteSync("runtime_journal");
38344
- if (fs102.existsSync(location.path)) {
38935
+ if (fs104.existsSync(location.path)) {
38345
38936
  let drift = false;
38346
38937
  let probe = null;
38347
38938
  try {
@@ -38595,10 +39186,10 @@ function _isCliEntry50() {
38595
39186
  return false;
38596
39187
  }
38597
39188
  if (process.argv[1] === void 0) return false;
38598
- const argvUrl = pathToFileURL60(path104.resolve(process.argv[1])).href;
39189
+ const argvUrl = pathToFileURL60(path105.resolve(process.argv[1])).href;
38599
39190
  if (import.meta.url === argvUrl) return true;
38600
39191
  try {
38601
- return fs103.realpathSync(fileURLToPath69(import.meta.url)) === fs103.realpathSync(path104.resolve(process.argv[1]));
39192
+ return fs105.realpathSync(fileURLToPath69(import.meta.url)) === fs105.realpathSync(path105.resolve(process.argv[1]));
38602
39193
  } catch {
38603
39194
  return false;
38604
39195
  }
@@ -38667,7 +39258,7 @@ var CONCERN_REGISTRY = {
38667
39258
  };
38668
39259
 
38669
39260
  // src/scripts/hooks/category_a.ts
38670
- import * as path105 from "node:path";
39261
+ import * as path106 from "node:path";
38671
39262
  var READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
38672
39263
  "Read",
38673
39264
  "Glob",
@@ -38846,10 +39437,10 @@ var SCRIPT_TAKING_SUBCOMMANDS = /* @__PURE__ */ new Set([
38846
39437
  ]);
38847
39438
  function isInsideWorkingTree(candidate, root) {
38848
39439
  if (!candidate.trim() || !root.trim()) return false;
38849
- const abs = path105.resolve(root, candidate);
38850
- const rel = path105.relative(path105.resolve(root), abs);
39440
+ const abs = path106.resolve(root, candidate);
39441
+ const rel = path106.relative(path106.resolve(root), abs);
38851
39442
  if (rel === "") return true;
38852
- return !rel.startsWith("..") && !path105.isAbsolute(rel);
39443
+ return !rel.startsWith("..") && !path106.isAbsolute(rel);
38853
39444
  }
38854
39445
  function _argv(command) {
38855
39446
  return command.trim().split(/\s+/).filter((t) => t.length > 0);
@@ -38877,7 +39468,7 @@ function _gitSubcommand(argv) {
38877
39468
  if (!_isFlag(token)) return token;
38878
39469
  const [flag, inlineValue] = token.includes("=") ? [token.slice(0, token.indexOf("=")), token.slice(token.indexOf("=") + 1)] : [token, null];
38879
39470
  const value = inlineValue ?? (GIT_VALUE_FLAGS.has(flag) ? argv[++i] : void 0);
38880
- if (value !== void 0 && (path105.isAbsolute(value) || value.split("/").includes(".."))) {
39471
+ if (value !== void 0 && (path106.isAbsolute(value) || value.split("/").includes(".."))) {
38881
39472
  return "";
38882
39473
  }
38883
39474
  }
@@ -39080,8 +39671,8 @@ function _py_json_dumps2(value, indent) {
39080
39671
 
39081
39672
  // src/scripts/_lib/collector_denominator.ts
39082
39673
  import crypto15 from "node:crypto";
39083
- import fs105 from "node:fs";
39084
- import path107 from "node:path";
39674
+ import fs107 from "node:fs";
39675
+ import path108 from "node:path";
39085
39676
 
39086
39677
  // src/scripts/_lib/collector_record.ts
39087
39678
  var COLLECTOR_EVENTS = [
@@ -39158,30 +39749,30 @@ var FIELD_PURPOSE = {
39158
39749
  var ALLOWED_FIELDS = new Set(Object.keys(FIELD_PURPOSE));
39159
39750
 
39160
39751
  // src/scripts/_lib/collector_store.ts
39161
- import * as fs104 from "node:fs";
39752
+ import * as fs106 from "node:fs";
39162
39753
  import * as os13 from "node:os";
39163
- import * as path106 from "node:path";
39754
+ import * as path107 from "node:path";
39164
39755
  var COLLECTOR_DIR_NAME = "agent-collector";
39165
39756
  var COLLECTOR_FILE_NAME = "collector.sqlite";
39166
39757
  var OPT_OUT_MARKER_NAME = "OPT-OUT";
39167
39758
  var MIGRATION_MARKER_NAME = "MIGRATION-IN-FLIGHT";
39168
39759
  var QUARANTINE_DIR_NAME = "quarantine";
39169
39760
  function defaultUserRoot() {
39170
- return path106.join(os13.homedir(), ".event4u", "agent-config");
39761
+ return path107.join(os13.homedir(), ".event4u", "agent-config");
39171
39762
  }
39172
39763
  function resolveCollectorStore(userRoot = defaultUserRoot()) {
39173
- const dir = path106.join(userRoot, COLLECTOR_DIR_NAME);
39764
+ const dir = path107.join(userRoot, COLLECTOR_DIR_NAME);
39174
39765
  return {
39175
39766
  userRoot,
39176
39767
  root: dir,
39177
- path: path106.join(dir, COLLECTOR_FILE_NAME),
39178
- optOutMarker: path106.join(dir, OPT_OUT_MARKER_NAME),
39179
- migrationMarker: path106.join(dir, MIGRATION_MARKER_NAME),
39180
- quarantineDir: path106.join(dir, QUARANTINE_DIR_NAME)
39768
+ path: path107.join(dir, COLLECTOR_FILE_NAME),
39769
+ optOutMarker: path107.join(dir, OPT_OUT_MARKER_NAME),
39770
+ migrationMarker: path107.join(dir, MIGRATION_MARKER_NAME),
39771
+ quarantineDir: path107.join(dir, QUARANTINE_DIR_NAME)
39181
39772
  };
39182
39773
  }
39183
39774
  function isOptedOut(userRoot = defaultUserRoot()) {
39184
- return fs104.existsSync(resolveCollectorStore(userRoot).optOutMarker);
39775
+ return fs106.existsSync(resolveCollectorStore(userRoot).optOutMarker);
39185
39776
  }
39186
39777
  var MIGRATIONS = Object.freeze({
39187
39778
  // 0 → 1. No DDL: `user_version` 0 is the default SQLite assigns, and a
@@ -39198,24 +39789,24 @@ var SPOOL_DIR_NAME = "spool";
39198
39789
  var SPOOL_PENDING_NAME = "pending.jsonl";
39199
39790
  var ENABLED_MARKER_NAME = "ENABLED";
39200
39791
  function denominatorPath(userRoot) {
39201
- return path107.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
39792
+ return path108.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
39202
39793
  }
39203
39794
  function spoolDir(userRoot) {
39204
- return path107.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
39795
+ return path108.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
39205
39796
  }
39206
39797
  function spoolPendingPath(userRoot) {
39207
- return path107.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
39798
+ return path108.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
39208
39799
  }
39209
39800
  function enabledMarkerPath(userRoot) {
39210
- return path107.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
39801
+ return path108.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
39211
39802
  }
39212
39803
  function isCollectorEnabled(userRoot) {
39213
39804
  if (isOptedOut(userRoot)) return false;
39214
- if (fs105.existsSync(killSwitchPathLocal(userRoot))) return false;
39215
- return fs105.existsSync(enabledMarkerPath(userRoot));
39805
+ if (fs107.existsSync(killSwitchPathLocal(userRoot))) return false;
39806
+ return fs107.existsSync(enabledMarkerPath(userRoot));
39216
39807
  }
39217
39808
  function killSwitchPathLocal(userRoot) {
39218
- return path107.join(resolveCollectorStore(userRoot).root, "STOP");
39809
+ return path108.join(resolveCollectorStore(userRoot).root, "STOP");
39219
39810
  }
39220
39811
  function utcDate(at = Date.now()) {
39221
39812
  return new Date(at).toISOString().slice(0, 10);
@@ -39227,8 +39818,8 @@ function recordOpportunity(event, platform, userRoot, at = Date.now(), opts = {}
39227
39818
  if (!COLLECTOR_EVENTS.includes(event)) return false;
39228
39819
  if (!COLLECTOR_PLATFORMS.includes(platform)) return false;
39229
39820
  const target = denominatorPath(userRoot);
39230
- fs105.mkdirSync(path107.dirname(target), { recursive: true });
39231
- fs105.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
39821
+ fs107.mkdirSync(path108.dirname(target), { recursive: true });
39822
+ fs107.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
39232
39823
  `);
39233
39824
  return true;
39234
39825
  } catch {
@@ -39242,19 +39833,19 @@ var MACHINE_ID_NAME = "machine-id";
39242
39833
  var EPISODE_DIR_NAME = "episodes";
39243
39834
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
39244
39835
  function machineIdPath(userRoot) {
39245
- return path107.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
39836
+ return path108.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
39246
39837
  }
39247
39838
  function machineId(userRoot) {
39248
39839
  const target = machineIdPath(userRoot);
39249
39840
  try {
39250
- const existing = fs105.readFileSync(target, "utf8").trim();
39841
+ const existing = fs107.readFileSync(target, "utf8").trim();
39251
39842
  if (UUID_RE.test(existing)) return existing;
39252
39843
  } catch {
39253
39844
  }
39254
39845
  try {
39255
39846
  const minted = crypto15.randomUUID();
39256
- fs105.mkdirSync(path107.dirname(target), { recursive: true });
39257
- fs105.writeFileSync(target, `${minted}
39847
+ fs107.mkdirSync(path108.dirname(target), { recursive: true });
39848
+ fs107.writeFileSync(target, `${minted}
39258
39849
  `);
39259
39850
  return minted;
39260
39851
  } catch {
@@ -39278,17 +39869,17 @@ function episodeId(env = process.env) {
39278
39869
  ].join("-");
39279
39870
  }
39280
39871
  function nextSequence(episode, userRoot) {
39281
- const dir = path107.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
39282
- const target = path107.join(dir, `${episode}.seq`);
39872
+ const dir = path108.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
39873
+ const target = path108.join(dir, `${episode}.seq`);
39283
39874
  try {
39284
- fs105.mkdirSync(dir, { recursive: true });
39875
+ fs107.mkdirSync(dir, { recursive: true });
39285
39876
  let current = 0;
39286
39877
  try {
39287
- const raw = Number.parseInt(fs105.readFileSync(target, "utf8").trim(), 10);
39878
+ const raw = Number.parseInt(fs107.readFileSync(target, "utf8").trim(), 10);
39288
39879
  if (Number.isInteger(raw) && raw >= 0) current = raw + 1;
39289
39880
  } catch {
39290
39881
  }
39291
- fs105.writeFileSync(target, `${current}
39882
+ fs107.writeFileSync(target, `${current}
39292
39883
  `);
39293
39884
  return current;
39294
39885
  } catch {
@@ -39327,12 +39918,12 @@ function spoolRecord(record, userRoot) {
39327
39918
  try {
39328
39919
  if (!isCollectorEnabled(userRoot)) return false;
39329
39920
  const target = spoolPendingPath(userRoot);
39330
- fs105.mkdirSync(path107.dirname(target), { recursive: true });
39921
+ fs107.mkdirSync(path108.dirname(target), { recursive: true });
39331
39922
  try {
39332
- if (fs105.statSync(target).size >= SPOOL_MAX_BYTES) return false;
39923
+ if (fs107.statSync(target).size >= SPOOL_MAX_BYTES) return false;
39333
39924
  } catch {
39334
39925
  }
39335
- fs105.appendFileSync(target, `${JSON.stringify(record)}
39926
+ fs107.appendFileSync(target, `${JSON.stringify(record)}
39336
39927
  `);
39337
39928
  return true;
39338
39929
  } catch {
@@ -39342,11 +39933,11 @@ function spoolRecord(record, userRoot) {
39342
39933
 
39343
39934
  // src/scripts/hooks/dispatch_hook.ts
39344
39935
  var _IN_BUNDLE2 = true;
39345
- var REPO_ROOT = path108.resolve(
39346
- path108.dirname(fileURLToPath70(import.meta.url)),
39936
+ var REPO_ROOT = path109.resolve(
39937
+ path109.dirname(fileURLToPath70(import.meta.url)),
39347
39938
  ..._IN_BUNDLE2 ? ["..", ".."] : ["..", "..", ".."]
39348
39939
  );
39349
- var MANIFEST_PATH = path108.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
39940
+ var MANIFEST_PATH = path109.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
39350
39941
  var EXIT_ALLOW37 = 0;
39351
39942
  var EXIT_BLOCK6 = 1;
39352
39943
  var EXIT_WARN20 = 2;
@@ -39408,11 +39999,11 @@ function _manifest_fingerprint(text) {
39408
39999
  return `${h.toString(16)}:${String(text.length)}`;
39409
40000
  }
39410
40001
  function _load_yaml3(p) {
39411
- const text = fs106.readFileSync(p, "utf-8");
40002
+ const text = fs108.readFileSync(p, "utf-8");
39412
40003
  const compiled = p.replace(/\.ya?ml$/u, ".json");
39413
40004
  if (compiled !== p) {
39414
40005
  try {
39415
- const raw = JSON.parse(fs106.readFileSync(compiled, "utf-8"));
40006
+ const raw = JSON.parse(fs108.readFileSync(compiled, "utf-8"));
39416
40007
  if (_isObject18(raw) && raw["fingerprint"] === _manifest_fingerprint(text) && _isObject18(raw["manifest"])) {
39417
40008
  return raw["manifest"];
39418
40009
  }
@@ -39510,7 +40101,7 @@ function _maybe_capture_payload(args, payload_text) {
39510
40101
  }
39511
40102
  try {
39512
40103
  const target = _expanduser3(capture_dir);
39513
- fs106.mkdirSync(target, { recursive: true });
40104
+ fs108.mkdirSync(target, { recursive: true });
39514
40105
  let payload;
39515
40106
  try {
39516
40107
  payload = payload_text.trim() ? JSON.parse(payload_text) : {};
@@ -39527,8 +40118,8 @@ function _maybe_capture_payload(args, payload_text) {
39527
40118
  const ts = Date.now();
39528
40119
  const native = (args.native_event || args.event).replace(/\//g, "_");
39529
40120
  const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
39530
- fs106.writeFileSync(
39531
- path108.join(target, fname),
40121
+ fs108.writeFileSync(
40122
+ path109.join(target, fname),
39532
40123
  _py_json_dumps2(record, 2) + "\n",
39533
40124
  { encoding: "utf-8" }
39534
40125
  );
@@ -39539,7 +40130,7 @@ function _maybe_capture_payload(args, payload_text) {
39539
40130
  function _expanduser3(p) {
39540
40131
  if (p === "~" || p.startsWith("~/")) {
39541
40132
  const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
39542
- return path108.join(home, p.slice(1));
40133
+ return path109.join(home, p.slice(1));
39543
40134
  }
39544
40135
  return p;
39545
40136
  }
@@ -39572,25 +40163,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
39572
40163
  const walkUp = (start) => {
39573
40164
  let dir = start;
39574
40165
  for (; ; ) {
39575
- const candidate = path108.join(dir, "node_modules", ".bin", binName);
40166
+ const candidate = path109.join(dir, "node_modules", ".bin", binName);
39576
40167
  if (_isFile8(candidate)) {
39577
40168
  return candidate;
39578
40169
  }
39579
- const parent = path108.dirname(dir);
40170
+ const parent = path109.dirname(dir);
39580
40171
  if (parent === dir) {
39581
40172
  return null;
39582
40173
  }
39583
40174
  dir = parent;
39584
40175
  }
39585
40176
  };
39586
- const tsx = walkUp(path108.dirname(scriptPath)) ?? walkUp(path108.dirname(fileURLToPath70(import.meta.url)));
40177
+ const tsx = walkUp(path109.dirname(scriptPath)) ?? walkUp(path109.dirname(fileURLToPath70(import.meta.url)));
39587
40178
  if (tsx !== null) {
39588
40179
  return { command: tsx, args: [scriptPath, ...scriptArgs] };
39589
40180
  }
39590
40181
  return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
39591
40182
  }
39592
40183
  function _run_concern_inproc(main_fn, concern, envelope) {
39593
- const scriptAbs = path108.join(REPO_ROOT, String(concern["script"]));
40184
+ const scriptAbs = path109.join(REPO_ROOT, String(concern["script"]));
39594
40185
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
39595
40186
  argsList.push("--platform", String(envelope["platform"] || "generic"));
39596
40187
  const workspace = String(envelope["workspace_root"] || process.cwd());
@@ -39667,7 +40258,7 @@ function _run_concern(concern, envelope) {
39667
40258
  return _run_concern_inproc(inproc, concern, envelope);
39668
40259
  }
39669
40260
  }
39670
- const script = path108.join(REPO_ROOT, String(concern["script"]));
40261
+ const script = path109.join(REPO_ROOT, String(concern["script"]));
39671
40262
  const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
39672
40263
  const cmd = [script, ...argsList];
39673
40264
  cmd.push("--platform", String(envelope["platform"] || "generic"));
@@ -39724,7 +40315,7 @@ function _run_concern(concern, envelope) {
39724
40315
  }
39725
40316
  function _isFile8(p) {
39726
40317
  try {
39727
- return fs106.statSync(p).isFile();
40318
+ return fs108.statSync(p).isFile();
39728
40319
  } catch {
39729
40320
  return false;
39730
40321
  }
@@ -39746,10 +40337,10 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
39746
40337
  return;
39747
40338
  }
39748
40339
  const workspace = String(envelope["workspace_root"] || process.cwd());
39749
- const state_root = path108.join(workspace, "agents", "runtime", "state");
40340
+ const state_root = path109.join(workspace, "agents", "runtime", "state");
39750
40341
  const fb_dir = feedback_dir(state_root, session_id);
39751
40342
  try {
39752
- fs106.mkdirSync(fb_dir, { recursive: true });
40343
+ fs108.mkdirSync(fb_dir, { recursive: true });
39753
40344
  } catch (exc) {
39754
40345
  const msg = exc instanceof Error ? exc.message : String(exc);
39755
40346
  process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
@@ -39757,7 +40348,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
39757
40348
  return;
39758
40349
  }
39759
40350
  for (const entry of entries) {
39760
- const target = path108.join(fb_dir, `${entry["concern"]}.json`);
40351
+ const target = path109.join(fb_dir, `${entry["concern"]}.json`);
39761
40352
  try {
39762
40353
  atomic_write_json(target, entry);
39763
40354
  } catch (exc) {
@@ -39806,7 +40397,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
39806
40397
  };
39807
40398
  try {
39808
40399
  const invocation = `${String(process.pid)}-${process.hrtime.bigint().toString()}`;
39809
- update_json_under_lock(path108.join(fb_dir, "summary.json"), (loaded) => {
40400
+ update_json_under_lock(path109.join(fb_dir, "summary.json"), (loaded) => {
39810
40401
  const priorRaw = loaded["invocations"];
39811
40402
  const prior = Array.isArray(priorRaw) ? priorRaw : [];
39812
40403
  const next = [...prior, { invocation, ...summary }];
@@ -39833,8 +40424,8 @@ function _record_rule_trips(envelope, entries) {
39833
40424
  if (tripped.length === 0) return;
39834
40425
  try {
39835
40426
  const workspace = String(envelope["workspace_root"] || process.cwd());
39836
- const state_dir = path108.join(workspace, "agents", "runtime", "state");
39837
- const target = path108.join(state_dir, "rule-trips.json");
40427
+ const state_dir = path109.join(workspace, "agents", "runtime", "state");
40428
+ const target = path109.join(state_dir, "rule-trips.json");
39838
40429
  const today = _now_iso3().slice(0, 10);
39839
40430
  update_json_under_lock(target, (loaded) => {
39840
40431
  const doc = { schema_version: 1, concerns: {}, ...loaded };
@@ -39976,7 +40567,7 @@ function main68(argv) {
39976
40567
  recordOpportunity(args.event, args.platform);
39977
40568
  recordCapture(args.event, args.platform);
39978
40569
  const manifest_path = args.manifest;
39979
- if (!fs106.existsSync(manifest_path)) {
40570
+ if (!fs108.existsSync(manifest_path)) {
39980
40571
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
39981
40572
  `);
39982
40573
  return EXIT_ALLOW37;
@@ -40146,7 +40737,7 @@ function main68(argv) {
40146
40737
  }
40147
40738
  function _isDir4(p) {
40148
40739
  try {
40149
- return fs106.statSync(p).isDirectory();
40740
+ return fs108.statSync(p).isDirectory();
40150
40741
  } catch {
40151
40742
  return false;
40152
40743
  }
@@ -40163,13 +40754,13 @@ function _isCliEntry51() {
40163
40754
  if (process.argv[1] === void 0) {
40164
40755
  return false;
40165
40756
  }
40166
- const argvUrl = pathToFileURL61(path108.resolve(process.argv[1])).href;
40757
+ const argvUrl = pathToFileURL61(path109.resolve(process.argv[1])).href;
40167
40758
  if (import.meta.url === argvUrl) {
40168
40759
  return true;
40169
40760
  }
40170
40761
  try {
40171
- const here = fs106.realpathSync(fileURLToPath70(import.meta.url));
40172
- const argv = fs106.realpathSync(path108.resolve(process.argv[1]));
40762
+ const here = fs108.realpathSync(fileURLToPath70(import.meta.url));
40763
+ const argv = fs108.realpathSync(path109.resolve(process.argv[1]));
40173
40764
  return here === argv;
40174
40765
  } catch {
40175
40766
  return false;
@@ -40182,7 +40773,7 @@ if (isCliEntry16) {
40182
40773
 
40183
40774
  // src/scripts/hooks/dispatch_entry.ts
40184
40775
  var _selfPath = fileURLToPath71(import.meta.url);
40185
- var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path109.resolve(process.argv[1]) === path109.resolve(_selfPath);
40776
+ var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path110.resolve(process.argv[1]) === path110.resolve(_selfPath);
40186
40777
  if (_invokedDirectly2) {
40187
40778
  process.exitCode = main68(process.argv.slice(2));
40188
40779
  }