@event4u/agent-config 15.0.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +142 -348
- package/dist/agent-src/commands/roadmap/create.md +3 -2
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +50 -0
- package/dist/agent-src/rules/user-interaction.md +31 -30
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli-delegate/{chunk-HZ52BRGG.js → chunk-H32DGUJH.js} +14 -89
- package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
- package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
- package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
- package/dist/cli-delegate/cmd_conformance.js +831 -272
- package/dist/cli-delegate/cmd_explain.js +4 -2
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +13 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +5 -5
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1274 -571
- package/dist/install/install.mjs +1 -0
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1218 -632
- package/dist/scripts/_lib/installed_lock.js +1 -1
- package/dist/server/io/yamlIO.js +50 -0
- package/package.json +1 -1
- package/src/config/continuity-surface.json +7 -0
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/config/host-injection-effect.json +1 -1
- package/src/config/preamble-payload-budget.json +12 -7
- package/src/config/preamble-payload-exceptions.json +28 -0
- package/src/scripts/_dispatch.bash +3 -1
- package/src/scripts/_lib/base_ref_payload.ts +315 -0
- package/src/scripts/_lib/dropped_decision.ts +142 -0
- package/src/scripts/_lib/installed_lock.ts +1 -1
- package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
- package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
- package/src/scripts/_lib/release_findings_ingest.ts +324 -0
- package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
- package/src/scripts/_lib/review_baseline.ts +254 -0
- package/src/scripts/_lib/review_skipped_record.ts +61 -1
- package/src/scripts/_lib/standing_bound_ratchet.ts +216 -103
- package/src/scripts/_lib/turn_end_refusals.ts +51 -4
- package/src/scripts/check_beta_review_markers.ts +35 -4
- package/src/scripts/check_finding_dispositions.ts +167 -16
- package/src/scripts/check_held_object_arrivals.ts +381 -0
- package/src/scripts/check_preamble_payload_budget.ts +399 -122
- package/src/scripts/check_release_published.ts +1 -1
- package/src/scripts/check_reply_consistency.ts +86 -17
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +39 -3
- package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
- package/src/scripts/hooks/review_baseline_hook.ts +130 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
- package/src/scripts/hooks_doctor.ts +4 -1
- package/src/scripts/install.ts +1 -1
- package/src/scripts/interruption_report.ts +8 -2
- package/src/scripts/janitor.ts +8 -1
- package/src/scripts/measure_turn_end_gate.ts +302 -5
- package/src/scripts/release.ts +52 -64
- package/src/scripts/release_drill.ts +193 -14
- package/src/scripts/release_env.ts +1 -1
- package/src/scripts/release_publication.ts +1 -1
- package/src/scripts/report_held_object_arrivals.ts +456 -0
- package/src/scripts/sync_agent_settings.ts +140 -18
- package/src/server/io/yamlIO.ts +48 -0
package/dist/hooks/dispatch.js
CHANGED
|
@@ -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,
|
|
116
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
115
|
+
function visit_(key, node, visitor, path116) {
|
|
116
|
+
const ctrl = callVisitor(key, node, visitor, path116);
|
|
117
117
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
118
|
-
replaceNode(key,
|
|
119
|
-
return visit_(key, ctrl, visitor,
|
|
118
|
+
replaceNode(key, path116, ctrl);
|
|
119
|
+
return visit_(key, ctrl, visitor, path116);
|
|
120
120
|
}
|
|
121
121
|
if (typeof ctrl !== "symbol") {
|
|
122
122
|
if (identity.isCollection(node)) {
|
|
123
|
-
|
|
123
|
+
path116 = Object.freeze(path116.concat(node));
|
|
124
124
|
for (let i = 0; i < node.items.length; ++i) {
|
|
125
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
125
|
+
const ci = visit_(i, node.items[i], visitor, path116);
|
|
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
|
-
|
|
137
|
-
const ck = visit_("key", node.key, visitor,
|
|
136
|
+
path116 = Object.freeze(path116.concat(node));
|
|
137
|
+
const ck = visit_("key", node.key, visitor, path116);
|
|
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,
|
|
142
|
+
const cv = visit_("value", node.value, visitor, path116);
|
|
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,
|
|
164
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
163
|
+
async function visitAsync_(key, node, visitor, path116) {
|
|
164
|
+
const ctrl = await callVisitor(key, node, visitor, path116);
|
|
165
165
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
166
|
-
replaceNode(key,
|
|
167
|
-
return visitAsync_(key, ctrl, visitor,
|
|
166
|
+
replaceNode(key, path116, ctrl);
|
|
167
|
+
return visitAsync_(key, ctrl, visitor, path116);
|
|
168
168
|
}
|
|
169
169
|
if (typeof ctrl !== "symbol") {
|
|
170
170
|
if (identity.isCollection(node)) {
|
|
171
|
-
|
|
171
|
+
path116 = Object.freeze(path116.concat(node));
|
|
172
172
|
for (let i = 0; i < node.items.length; ++i) {
|
|
173
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
173
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path116);
|
|
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
|
-
|
|
185
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
184
|
+
path116 = Object.freeze(path116.concat(node));
|
|
185
|
+
const ck = await visitAsync_("key", node.key, visitor, path116);
|
|
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,
|
|
190
|
+
const cv = await visitAsync_("value", node.value, visitor, path116);
|
|
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,
|
|
217
|
+
function callVisitor(key, node, visitor, path116) {
|
|
218
218
|
if (typeof visitor === "function")
|
|
219
|
-
return visitor(key, node,
|
|
219
|
+
return visitor(key, node, path116);
|
|
220
220
|
if (identity.isMap(node))
|
|
221
|
-
return visitor.Map?.(key, node,
|
|
221
|
+
return visitor.Map?.(key, node, path116);
|
|
222
222
|
if (identity.isSeq(node))
|
|
223
|
-
return visitor.Seq?.(key, node,
|
|
223
|
+
return visitor.Seq?.(key, node, path116);
|
|
224
224
|
if (identity.isPair(node))
|
|
225
|
-
return visitor.Pair?.(key, node,
|
|
225
|
+
return visitor.Pair?.(key, node, path116);
|
|
226
226
|
if (identity.isScalar(node))
|
|
227
|
-
return visitor.Scalar?.(key, node,
|
|
227
|
+
return visitor.Scalar?.(key, node, path116);
|
|
228
228
|
if (identity.isAlias(node))
|
|
229
|
-
return visitor.Alias?.(key, node,
|
|
229
|
+
return visitor.Alias?.(key, node, path116);
|
|
230
230
|
return void 0;
|
|
231
231
|
}
|
|
232
|
-
function replaceNode(key,
|
|
233
|
-
const parent =
|
|
232
|
+
function replaceNode(key, path116, node) {
|
|
233
|
+
const parent = path116[path116.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,
|
|
843
|
+
function collectionFromPath(schema, path116, value) {
|
|
844
844
|
let v = value;
|
|
845
|
-
for (let i =
|
|
846
|
-
const k =
|
|
845
|
+
for (let i = path116.length - 1; i >= 0; --i) {
|
|
846
|
+
const k = path116[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 = (
|
|
865
|
+
var isEmptyPath = (path116) => path116 == null || typeof path116 === "object" && !!path116[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(
|
|
896
|
-
if (isEmptyPath(
|
|
895
|
+
addIn(path116, value) {
|
|
896
|
+
if (isEmptyPath(path116))
|
|
897
897
|
this.add(value);
|
|
898
898
|
else {
|
|
899
|
-
const [key, ...rest] =
|
|
899
|
+
const [key, ...rest] = path116;
|
|
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(
|
|
914
|
-
const [key, ...rest] =
|
|
913
|
+
deleteIn(path116) {
|
|
914
|
+
const [key, ...rest] = path116;
|
|
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(
|
|
929
|
-
const [key, ...rest] =
|
|
928
|
+
getIn(path116, keepScalar) {
|
|
929
|
+
const [key, ...rest] = path116;
|
|
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(
|
|
948
|
-
const [key, ...rest] =
|
|
947
|
+
hasIn(path116) {
|
|
948
|
+
const [key, ...rest] = path116;
|
|
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(
|
|
959
|
-
const [key, ...rest] =
|
|
958
|
+
setIn(path116, value) {
|
|
959
|
+
const [key, ...rest] = path116;
|
|
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(
|
|
3474
|
+
addIn(path116, value) {
|
|
3475
3475
|
if (assertCollection(this.contents))
|
|
3476
|
-
this.contents.addIn(
|
|
3476
|
+
this.contents.addIn(path116, 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(
|
|
3552
|
-
if (Collection.isEmptyPath(
|
|
3551
|
+
deleteIn(path116) {
|
|
3552
|
+
if (Collection.isEmptyPath(path116)) {
|
|
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(
|
|
3558
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path116) : 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(
|
|
3574
|
-
if (Collection.isEmptyPath(
|
|
3573
|
+
getIn(path116, keepScalar) {
|
|
3574
|
+
if (Collection.isEmptyPath(path116))
|
|
3575
3575
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3576
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3576
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path116, 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(
|
|
3588
|
-
if (Collection.isEmptyPath(
|
|
3587
|
+
hasIn(path116) {
|
|
3588
|
+
if (Collection.isEmptyPath(path116))
|
|
3589
3589
|
return this.contents !== void 0;
|
|
3590
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3590
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path116) : 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(
|
|
3608
|
-
if (Collection.isEmptyPath(
|
|
3607
|
+
setIn(path116, value) {
|
|
3608
|
+
if (Collection.isEmptyPath(path116)) {
|
|
3609
3609
|
this.contents = value;
|
|
3610
3610
|
} else if (this.contents == null) {
|
|
3611
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3611
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path116), value);
|
|
3612
3612
|
} else if (assertCollection(this.contents)) {
|
|
3613
|
-
this.contents.setIn(
|
|
3613
|
+
this.contents.setIn(path116, value);
|
|
3614
3614
|
}
|
|
3615
3615
|
}
|
|
3616
3616
|
/**
|
|
@@ -3996,10 +3996,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
3996
3996
|
let offset = bm.offset;
|
|
3997
3997
|
let commentEnd = null;
|
|
3998
3998
|
for (const collItem of bm.items) {
|
|
3999
|
-
const { start, key, sep:
|
|
3999
|
+
const { start, key, sep: sep12, value } = collItem;
|
|
4000
4000
|
const keyProps = resolveProps.resolveProps(start, {
|
|
4001
4001
|
indicator: "explicit-key-ind",
|
|
4002
|
-
next: key ??
|
|
4002
|
+
next: key ?? sep12?.[0],
|
|
4003
4003
|
offset,
|
|
4004
4004
|
onError,
|
|
4005
4005
|
parentIndent: bm.indent,
|
|
@@ -4013,7 +4013,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
4013
4013
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
4014
4014
|
onError(offset, "BAD_INDENT", startColMsg);
|
|
4015
4015
|
}
|
|
4016
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
4016
|
+
if (!keyProps.anchor && !keyProps.tag && !sep12) {
|
|
4017
4017
|
commentEnd = keyProps.end;
|
|
4018
4018
|
if (keyProps.comment) {
|
|
4019
4019
|
if (map.comment)
|
|
@@ -4037,7 +4037,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
4037
4037
|
ctx.atKey = false;
|
|
4038
4038
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
4039
4039
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
4040
|
-
const valueProps = resolveProps.resolveProps(
|
|
4040
|
+
const valueProps = resolveProps.resolveProps(sep12 ?? [], {
|
|
4041
4041
|
indicator: "map-value-ind",
|
|
4042
4042
|
next: value,
|
|
4043
4043
|
offset: keyNode.range[2],
|
|
@@ -4053,7 +4053,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
4053
4053
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
4054
4054
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
4055
4055
|
}
|
|
4056
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset,
|
|
4056
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep12, null, valueProps, onError);
|
|
4057
4057
|
if (ctx.schema.compat)
|
|
4058
4058
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
4059
4059
|
offset = valueNode.range[2];
|
|
@@ -4144,7 +4144,7 @@ var require_resolve_end = __commonJS({
|
|
|
4144
4144
|
let comment = "";
|
|
4145
4145
|
if (end) {
|
|
4146
4146
|
let hasSpace = false;
|
|
4147
|
-
let
|
|
4147
|
+
let sep12 = "";
|
|
4148
4148
|
for (const token of end) {
|
|
4149
4149
|
const { source, type } = token;
|
|
4150
4150
|
switch (type) {
|
|
@@ -4158,13 +4158,13 @@ var require_resolve_end = __commonJS({
|
|
|
4158
4158
|
if (!comment)
|
|
4159
4159
|
comment = cb;
|
|
4160
4160
|
else
|
|
4161
|
-
comment +=
|
|
4162
|
-
|
|
4161
|
+
comment += sep12 + cb;
|
|
4162
|
+
sep12 = "";
|
|
4163
4163
|
break;
|
|
4164
4164
|
}
|
|
4165
4165
|
case "newline":
|
|
4166
4166
|
if (comment)
|
|
4167
|
-
|
|
4167
|
+
sep12 += source;
|
|
4168
4168
|
hasSpace = true;
|
|
4169
4169
|
break;
|
|
4170
4170
|
default:
|
|
@@ -4207,18 +4207,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4207
4207
|
let offset = fc.offset + fc.start.source.length;
|
|
4208
4208
|
for (let i = 0; i < fc.items.length; ++i) {
|
|
4209
4209
|
const collItem = fc.items[i];
|
|
4210
|
-
const { start, key, sep:
|
|
4210
|
+
const { start, key, sep: sep12, value } = collItem;
|
|
4211
4211
|
const props = resolveProps.resolveProps(start, {
|
|
4212
4212
|
flow: fcName,
|
|
4213
4213
|
indicator: "explicit-key-ind",
|
|
4214
|
-
next: key ??
|
|
4214
|
+
next: key ?? sep12?.[0],
|
|
4215
4215
|
offset,
|
|
4216
4216
|
onError,
|
|
4217
4217
|
parentIndent: fc.indent,
|
|
4218
4218
|
startOnNewline: false
|
|
4219
4219
|
});
|
|
4220
4220
|
if (!props.found) {
|
|
4221
|
-
if (!props.anchor && !props.tag && !
|
|
4221
|
+
if (!props.anchor && !props.tag && !sep12 && !value) {
|
|
4222
4222
|
if (i === 0 && props.comma)
|
|
4223
4223
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
4224
4224
|
else if (i < fc.items.length - 1)
|
|
@@ -4272,8 +4272,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4272
4272
|
}
|
|
4273
4273
|
}
|
|
4274
4274
|
}
|
|
4275
|
-
if (!isMap && !
|
|
4276
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
4275
|
+
if (!isMap && !sep12 && !props.found) {
|
|
4276
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep12, null, props, onError);
|
|
4277
4277
|
coll.items.push(valueNode);
|
|
4278
4278
|
offset = valueNode.range[2];
|
|
4279
4279
|
if (isBlock(value))
|
|
@@ -4285,7 +4285,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4285
4285
|
if (isBlock(key))
|
|
4286
4286
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
4287
4287
|
ctx.atKey = false;
|
|
4288
|
-
const valueProps = resolveProps.resolveProps(
|
|
4288
|
+
const valueProps = resolveProps.resolveProps(sep12 ?? [], {
|
|
4289
4289
|
flow: fcName,
|
|
4290
4290
|
indicator: "map-value-ind",
|
|
4291
4291
|
next: value,
|
|
@@ -4296,8 +4296,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4296
4296
|
});
|
|
4297
4297
|
if (valueProps.found) {
|
|
4298
4298
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
4299
|
-
if (
|
|
4300
|
-
for (const st of
|
|
4299
|
+
if (sep12)
|
|
4300
|
+
for (const st of sep12) {
|
|
4301
4301
|
if (st === valueProps.found)
|
|
4302
4302
|
break;
|
|
4303
4303
|
if (st.type === "newline") {
|
|
@@ -4314,7 +4314,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
4314
4314
|
else
|
|
4315
4315
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
4316
4316
|
}
|
|
4317
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
4317
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep12, null, valueProps, onError) : null;
|
|
4318
4318
|
if (valueNode) {
|
|
4319
4319
|
if (isBlock(value))
|
|
4320
4320
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -4494,7 +4494,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
4494
4494
|
chompStart = i + 1;
|
|
4495
4495
|
}
|
|
4496
4496
|
let value = "";
|
|
4497
|
-
let
|
|
4497
|
+
let sep12 = "";
|
|
4498
4498
|
let prevMoreIndented = false;
|
|
4499
4499
|
for (let i = 0; i < contentStart; ++i)
|
|
4500
4500
|
value += lines[i][0].slice(trimIndent) + "\n";
|
|
@@ -4511,24 +4511,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
4511
4511
|
indent = "";
|
|
4512
4512
|
}
|
|
4513
4513
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
4514
|
-
value +=
|
|
4515
|
-
|
|
4514
|
+
value += sep12 + indent.slice(trimIndent) + content;
|
|
4515
|
+
sep12 = "\n";
|
|
4516
4516
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
4517
|
-
if (
|
|
4518
|
-
|
|
4519
|
-
else if (!prevMoreIndented &&
|
|
4520
|
-
|
|
4521
|
-
value +=
|
|
4522
|
-
|
|
4517
|
+
if (sep12 === " ")
|
|
4518
|
+
sep12 = "\n";
|
|
4519
|
+
else if (!prevMoreIndented && sep12 === "\n")
|
|
4520
|
+
sep12 = "\n\n";
|
|
4521
|
+
value += sep12 + indent.slice(trimIndent) + content;
|
|
4522
|
+
sep12 = "\n";
|
|
4523
4523
|
prevMoreIndented = true;
|
|
4524
4524
|
} else if (content === "") {
|
|
4525
|
-
if (
|
|
4525
|
+
if (sep12 === "\n")
|
|
4526
4526
|
value += "\n";
|
|
4527
4527
|
else
|
|
4528
|
-
|
|
4528
|
+
sep12 = "\n";
|
|
4529
4529
|
} else {
|
|
4530
|
-
value +=
|
|
4531
|
-
|
|
4530
|
+
value += sep12 + content;
|
|
4531
|
+
sep12 = " ";
|
|
4532
4532
|
prevMoreIndented = false;
|
|
4533
4533
|
}
|
|
4534
4534
|
}
|
|
@@ -4710,25 +4710,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
4710
4710
|
if (!match)
|
|
4711
4711
|
return source;
|
|
4712
4712
|
let res = match[1];
|
|
4713
|
-
let
|
|
4713
|
+
let sep12 = " ";
|
|
4714
4714
|
let pos = first.lastIndex;
|
|
4715
4715
|
line.lastIndex = pos;
|
|
4716
4716
|
while (match = line.exec(source)) {
|
|
4717
4717
|
if (match[1] === "") {
|
|
4718
|
-
if (
|
|
4719
|
-
res +=
|
|
4718
|
+
if (sep12 === "\n")
|
|
4719
|
+
res += sep12;
|
|
4720
4720
|
else
|
|
4721
|
-
|
|
4721
|
+
sep12 = "\n";
|
|
4722
4722
|
} else {
|
|
4723
|
-
res +=
|
|
4724
|
-
|
|
4723
|
+
res += sep12 + match[1];
|
|
4724
|
+
sep12 = " ";
|
|
4725
4725
|
}
|
|
4726
4726
|
pos = line.lastIndex;
|
|
4727
4727
|
}
|
|
4728
4728
|
const last = /[ \t]*(.*)/sy;
|
|
4729
4729
|
last.lastIndex = pos;
|
|
4730
4730
|
match = last.exec(source);
|
|
4731
|
-
return res +
|
|
4731
|
+
return res + sep12 + (match?.[1] ?? "");
|
|
4732
4732
|
}
|
|
4733
4733
|
function doubleQuotedValue(source, onError) {
|
|
4734
4734
|
let res = "";
|
|
@@ -5538,14 +5538,14 @@ var require_cst_stringify = __commonJS({
|
|
|
5538
5538
|
}
|
|
5539
5539
|
}
|
|
5540
5540
|
}
|
|
5541
|
-
function stringifyItem({ start, key, sep:
|
|
5541
|
+
function stringifyItem({ start, key, sep: sep12, value }) {
|
|
5542
5542
|
let res = "";
|
|
5543
5543
|
for (const st of start)
|
|
5544
5544
|
res += st.source;
|
|
5545
5545
|
if (key)
|
|
5546
5546
|
res += stringifyToken(key);
|
|
5547
|
-
if (
|
|
5548
|
-
for (const st of
|
|
5547
|
+
if (sep12)
|
|
5548
|
+
for (const st of sep12)
|
|
5549
5549
|
res += st.source;
|
|
5550
5550
|
if (value)
|
|
5551
5551
|
res += stringifyToken(value);
|
|
@@ -5570,9 +5570,9 @@ var require_cst_visit = __commonJS({
|
|
|
5570
5570
|
visit.BREAK = BREAK;
|
|
5571
5571
|
visit.SKIP = SKIP;
|
|
5572
5572
|
visit.REMOVE = REMOVE;
|
|
5573
|
-
visit.itemAtPath = (cst,
|
|
5573
|
+
visit.itemAtPath = (cst, path116) => {
|
|
5574
5574
|
let item = cst;
|
|
5575
|
-
for (const [field, index] of
|
|
5575
|
+
for (const [field, index] of path116) {
|
|
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,
|
|
5585
|
-
const parent = visit.itemAtPath(cst,
|
|
5586
|
-
const field =
|
|
5584
|
+
visit.parentCollection = (cst, path116) => {
|
|
5585
|
+
const parent = visit.itemAtPath(cst, path116.slice(0, -1));
|
|
5586
|
+
const field = path116[path116.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(
|
|
5593
|
-
let ctrl = visitor(item,
|
|
5592
|
+
function _visit(path116, item, visitor) {
|
|
5593
|
+
let ctrl = visitor(item, path116);
|
|
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(
|
|
5600
|
+
const ci = _visit(Object.freeze(path116.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,
|
|
5611
|
+
ctrl = ctrl(item, path116);
|
|
5612
5612
|
}
|
|
5613
5613
|
}
|
|
5614
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5614
|
+
return typeof ctrl === "function" ? ctrl(item, path116) : ctrl;
|
|
5615
5615
|
}
|
|
5616
5616
|
exports.visit = visit;
|
|
5617
5617
|
}
|
|
@@ -6712,18 +6712,18 @@ var require_parser = __commonJS({
|
|
|
6712
6712
|
if (this.type === "map-value-ind") {
|
|
6713
6713
|
const prev = getPrevProps(this.peek(2));
|
|
6714
6714
|
const start = getFirstKeyStartProps(prev);
|
|
6715
|
-
let
|
|
6715
|
+
let sep12;
|
|
6716
6716
|
if (scalar.end) {
|
|
6717
|
-
|
|
6718
|
-
|
|
6717
|
+
sep12 = scalar.end;
|
|
6718
|
+
sep12.push(this.sourceToken);
|
|
6719
6719
|
delete scalar.end;
|
|
6720
6720
|
} else
|
|
6721
|
-
|
|
6721
|
+
sep12 = [this.sourceToken];
|
|
6722
6722
|
const map = {
|
|
6723
6723
|
type: "block-map",
|
|
6724
6724
|
offset: scalar.offset,
|
|
6725
6725
|
indent: scalar.indent,
|
|
6726
|
-
items: [{ start, key: scalar, sep:
|
|
6726
|
+
items: [{ start, key: scalar, sep: sep12 }]
|
|
6727
6727
|
};
|
|
6728
6728
|
this.onKeyLine = true;
|
|
6729
6729
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -6876,15 +6876,15 @@ var require_parser = __commonJS({
|
|
|
6876
6876
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
6877
6877
|
const start2 = getFirstKeyStartProps(it.start);
|
|
6878
6878
|
const key = it.key;
|
|
6879
|
-
const
|
|
6880
|
-
|
|
6879
|
+
const sep12 = it.sep;
|
|
6880
|
+
sep12.push(this.sourceToken);
|
|
6881
6881
|
delete it.key;
|
|
6882
6882
|
delete it.sep;
|
|
6883
6883
|
this.stack.push({
|
|
6884
6884
|
type: "block-map",
|
|
6885
6885
|
offset: this.offset,
|
|
6886
6886
|
indent: this.indent,
|
|
6887
|
-
items: [{ start: start2, key, sep:
|
|
6887
|
+
items: [{ start: start2, key, sep: sep12 }]
|
|
6888
6888
|
});
|
|
6889
6889
|
} else if (start.length > 0) {
|
|
6890
6890
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -6913,14 +6913,14 @@ var require_parser = __commonJS({
|
|
|
6913
6913
|
case "scalar":
|
|
6914
6914
|
case "single-quoted-scalar":
|
|
6915
6915
|
case "double-quoted-scalar": {
|
|
6916
|
-
const
|
|
6916
|
+
const fs111 = this.flowScalar(this.type);
|
|
6917
6917
|
if (atNextItem || it.value) {
|
|
6918
|
-
map.items.push({ start, key:
|
|
6918
|
+
map.items.push({ start, key: fs111, sep: [] });
|
|
6919
6919
|
this.onKeyLine = true;
|
|
6920
6920
|
} else if (it.sep) {
|
|
6921
|
-
this.stack.push(
|
|
6921
|
+
this.stack.push(fs111);
|
|
6922
6922
|
} else {
|
|
6923
|
-
Object.assign(it, { key:
|
|
6923
|
+
Object.assign(it, { key: fs111, 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
|
|
7051
|
+
const fs111 = this.flowScalar(this.type);
|
|
7052
7052
|
if (!it || it.value)
|
|
7053
|
-
fc.items.push({ start: [], key:
|
|
7053
|
+
fc.items.push({ start: [], key: fs111, sep: [] });
|
|
7054
7054
|
else if (it.sep)
|
|
7055
|
-
this.stack.push(
|
|
7055
|
+
this.stack.push(fs111);
|
|
7056
7056
|
else
|
|
7057
|
-
Object.assign(it, { key:
|
|
7057
|
+
Object.assign(it, { key: fs111, sep: [] });
|
|
7058
7058
|
return;
|
|
7059
7059
|
}
|
|
7060
7060
|
case "flow-map-end":
|
|
@@ -7078,13 +7078,13 @@ var require_parser = __commonJS({
|
|
|
7078
7078
|
const prev = getPrevProps(parent);
|
|
7079
7079
|
const start = getFirstKeyStartProps(prev);
|
|
7080
7080
|
fixFlowSeqItems(fc);
|
|
7081
|
-
const
|
|
7082
|
-
|
|
7081
|
+
const sep12 = fc.end.splice(1, fc.end.length);
|
|
7082
|
+
sep12.push(this.sourceToken);
|
|
7083
7083
|
const map = {
|
|
7084
7084
|
type: "block-map",
|
|
7085
7085
|
offset: fc.offset,
|
|
7086
7086
|
indent: fc.indent,
|
|
7087
|
-
items: [{ start, key: fc, sep:
|
|
7087
|
+
items: [{ start, key: fc, sep: sep12 }]
|
|
7088
7088
|
};
|
|
7089
7089
|
this.onKeyLine = true;
|
|
7090
7090
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -7363,16 +7363,16 @@ var require_dist = __commonJS({
|
|
|
7363
7363
|
});
|
|
7364
7364
|
|
|
7365
7365
|
// src/scripts/hooks/dispatch_entry.ts
|
|
7366
|
-
import * as
|
|
7367
|
-
import { fileURLToPath as
|
|
7366
|
+
import * as path115 from "node:path";
|
|
7367
|
+
import { fileURLToPath as fileURLToPath74 } from "node:url";
|
|
7368
7368
|
|
|
7369
7369
|
// src/scripts/hooks/dispatch_hook.ts
|
|
7370
7370
|
var import_yaml7 = __toESM(require_dist(), 1);
|
|
7371
|
-
import { spawnSync as
|
|
7372
|
-
import
|
|
7373
|
-
import
|
|
7371
|
+
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
7372
|
+
import fs110 from "node:fs";
|
|
7373
|
+
import path114 from "node:path";
|
|
7374
7374
|
import * as tty2 from "node:tty";
|
|
7375
|
-
import { fileURLToPath as
|
|
7375
|
+
import { fileURLToPath as fileURLToPath73, pathToFileURL as pathToFileURL63 } from "node:url";
|
|
7376
7376
|
|
|
7377
7377
|
// src/scripts/_lib/spawn_env.ts
|
|
7378
7378
|
var DENY_EXACT = /* @__PURE__ */ new Set([
|
|
@@ -16091,8 +16091,8 @@ function lockfile_path(env) {
|
|
|
16091
16091
|
}
|
|
16092
16092
|
return write_target("installed.lock", { env: env ?? null });
|
|
16093
16093
|
}
|
|
16094
|
-
function read_lockfile(
|
|
16095
|
-
const target =
|
|
16094
|
+
function read_lockfile(path116) {
|
|
16095
|
+
const target = path116 ?? lockfile_path();
|
|
16096
16096
|
let text;
|
|
16097
16097
|
try {
|
|
16098
16098
|
text = fs21.readFileSync(target, { encoding: "utf-8" });
|
|
@@ -16160,7 +16160,9 @@ var DETECTOR_IDS = [
|
|
|
16160
16160
|
"promissory",
|
|
16161
16161
|
"language",
|
|
16162
16162
|
"verification",
|
|
16163
|
-
"completion"
|
|
16163
|
+
"completion",
|
|
16164
|
+
"pending-decision",
|
|
16165
|
+
"untested"
|
|
16164
16166
|
];
|
|
16165
16167
|
var REFUSAL_STATE_REL = path22.join("agents", "runtime", "state", "turn-end-gate");
|
|
16166
16168
|
function refusalStateDir(workspaceRoot3) {
|
|
@@ -16185,7 +16187,9 @@ function readSessionCounts(workspaceRoot3, sessionId3) {
|
|
|
16185
16187
|
}
|
|
16186
16188
|
}
|
|
16187
16189
|
function emptyCounts() {
|
|
16188
|
-
|
|
16190
|
+
const out = {};
|
|
16191
|
+
for (const id of DETECTOR_IDS) out[id] = 0;
|
|
16192
|
+
return out;
|
|
16189
16193
|
}
|
|
16190
16194
|
function isDetector(v) {
|
|
16191
16195
|
return typeof v === "string" && DETECTOR_IDS.includes(v);
|
|
@@ -16211,6 +16215,9 @@ function parseRecord(raw) {
|
|
|
16211
16215
|
if (typeof o["agent_config_version"] === "string") {
|
|
16212
16216
|
rec.agent_config_version = o["agent_config_version"];
|
|
16213
16217
|
}
|
|
16218
|
+
if (typeof o["refused_prompt_id"] === "string") {
|
|
16219
|
+
rec.refused_prompt_id = o["refused_prompt_id"];
|
|
16220
|
+
}
|
|
16214
16221
|
const counts = o["counts"];
|
|
16215
16222
|
if (typeof counts === "object" && counts !== null && !Array.isArray(counts)) {
|
|
16216
16223
|
const parsed = {};
|
|
@@ -16254,6 +16261,9 @@ function foldRefusal(prev, input) {
|
|
|
16254
16261
|
else if (prev?.agent_config_version !== void 0) {
|
|
16255
16262
|
rec.agent_config_version = prev.agent_config_version;
|
|
16256
16263
|
}
|
|
16264
|
+
if (input.promptId !== void 0 && input.promptId !== "") {
|
|
16265
|
+
rec.refused_prompt_id = input.promptId;
|
|
16266
|
+
}
|
|
16257
16267
|
return rec;
|
|
16258
16268
|
}
|
|
16259
16269
|
function readInstallBoundary() {
|
|
@@ -34016,14 +34026,92 @@ if (_isCliEntry37()) {
|
|
|
34016
34026
|
}
|
|
34017
34027
|
|
|
34018
34028
|
// src/scripts/hooks/end_review_nudge_hook.ts
|
|
34019
|
-
import { spawnSync as
|
|
34029
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
34020
34030
|
import * as crypto9 from "node:crypto";
|
|
34021
|
-
import * as
|
|
34031
|
+
import * as fs83 from "node:fs";
|
|
34022
34032
|
import * as os11 from "node:os";
|
|
34023
|
-
import * as
|
|
34033
|
+
import * as path84 from "node:path";
|
|
34024
34034
|
import { fileURLToPath as fileURLToPath56, pathToFileURL as pathToFileURL48 } from "node:url";
|
|
34025
34035
|
|
|
34036
|
+
// src/scripts/_lib/review_baseline.ts
|
|
34037
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
34038
|
+
import * as fs82 from "node:fs";
|
|
34039
|
+
import * as path83 from "node:path";
|
|
34040
|
+
function currentHeadSha(cwd) {
|
|
34041
|
+
try {
|
|
34042
|
+
const r = spawnSync6("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" });
|
|
34043
|
+
if (r.status !== 0) return null;
|
|
34044
|
+
const out = (r.stdout ?? "").trim();
|
|
34045
|
+
return out === "" ? null : out;
|
|
34046
|
+
} catch {
|
|
34047
|
+
return null;
|
|
34048
|
+
}
|
|
34049
|
+
}
|
|
34050
|
+
var BASELINE_STATE_REL = path83.join("agents", "runtime", "state", "review-baseline");
|
|
34051
|
+
function baselineStateDir(workspaceRoot3) {
|
|
34052
|
+
return path83.join(workspaceRoot3, BASELINE_STATE_REL);
|
|
34053
|
+
}
|
|
34054
|
+
function baselineStateFile(workspaceRoot3, sessionKey) {
|
|
34055
|
+
return path83.join(baselineStateDir(workspaceRoot3), `${sessionKey}.json`);
|
|
34056
|
+
}
|
|
34057
|
+
function parseBaseline(raw) {
|
|
34058
|
+
let decoded;
|
|
34059
|
+
try {
|
|
34060
|
+
decoded = JSON.parse(raw);
|
|
34061
|
+
} catch {
|
|
34062
|
+
return null;
|
|
34063
|
+
}
|
|
34064
|
+
if (typeof decoded !== "object" || decoded === null || Array.isArray(decoded)) return null;
|
|
34065
|
+
const o = decoded;
|
|
34066
|
+
const lines = o["baseline_lines"];
|
|
34067
|
+
if (typeof lines !== "number" || !Number.isFinite(lines) || lines < 0) return null;
|
|
34068
|
+
const written = o["written_at"];
|
|
34069
|
+
if (typeof written !== "string") return null;
|
|
34070
|
+
const head = o["head_sha"];
|
|
34071
|
+
const measure = o["measure"];
|
|
34072
|
+
return {
|
|
34073
|
+
head_sha: typeof head === "string" && head !== "" ? head : null,
|
|
34074
|
+
baseline_lines: lines,
|
|
34075
|
+
...measure === "exact" || measure === "capped_approximation" ? { measure } : {},
|
|
34076
|
+
written_at: written
|
|
34077
|
+
};
|
|
34078
|
+
}
|
|
34079
|
+
function readBaseline(workspaceRoot3, sessionKey) {
|
|
34080
|
+
const file = baselineStateFile(workspaceRoot3, sessionKey);
|
|
34081
|
+
let raw;
|
|
34082
|
+
try {
|
|
34083
|
+
raw = fs82.readFileSync(file, "utf-8");
|
|
34084
|
+
} catch (exc) {
|
|
34085
|
+
const code = exc?.code;
|
|
34086
|
+
return code === "ENOENT" ? "absent" : "unreadable";
|
|
34087
|
+
}
|
|
34088
|
+
return parseBaseline(raw) ?? "unreadable";
|
|
34089
|
+
}
|
|
34090
|
+
function applyBaseline(measuredLines, baseline, headSha, measuredMeasure = "exact") {
|
|
34091
|
+
if (baseline === "absent" || baseline === "unreadable") {
|
|
34092
|
+
return { applied: false, fallback: baseline, lines: measuredLines };
|
|
34093
|
+
}
|
|
34094
|
+
if (baseline.measure !== "exact" || measuredMeasure !== "exact") {
|
|
34095
|
+
return { applied: false, fallback: "mixed-measure", lines: measuredLines };
|
|
34096
|
+
}
|
|
34097
|
+
if (baseline.head_sha !== headSha()) {
|
|
34098
|
+
return { applied: false, fallback: "head-moved", lines: measuredLines };
|
|
34099
|
+
}
|
|
34100
|
+
return {
|
|
34101
|
+
applied: true,
|
|
34102
|
+
baseline,
|
|
34103
|
+
lines: Math.max(0, measuredLines - baseline.baseline_lines)
|
|
34104
|
+
};
|
|
34105
|
+
}
|
|
34106
|
+
|
|
34026
34107
|
// src/scripts/_lib/review_skipped_record.ts
|
|
34108
|
+
var BASELINE_APPLICATIONS = [
|
|
34109
|
+
"applied",
|
|
34110
|
+
"absent",
|
|
34111
|
+
"unreadable",
|
|
34112
|
+
"head_moved",
|
|
34113
|
+
"mixed_measure"
|
|
34114
|
+
];
|
|
34027
34115
|
var PRODUCER_PRIVACY_CLASS2 = "ids-only";
|
|
34028
34116
|
function isNonNegInt(n) {
|
|
34029
34117
|
return typeof n === "number" && Number.isFinite(n) && Number.isInteger(n) && n >= 0;
|
|
@@ -34039,6 +34127,9 @@ function buildReviewSkippedLine(input) {
|
|
|
34039
34127
|
}
|
|
34040
34128
|
if (!input.ts) errors.push("ts (ISO-8601 UTC) is required");
|
|
34041
34129
|
if (!input.id) errors.push("id (ULID, UUID, or content hash) is required");
|
|
34130
|
+
if (input.baseline !== void 0 && !BASELINE_APPLICATIONS.includes(input.baseline)) {
|
|
34131
|
+
errors.push(`baseline must be one of ${BASELINE_APPLICATIONS.join(", ")}`);
|
|
34132
|
+
}
|
|
34042
34133
|
if (errors.length) return { line: null, errors };
|
|
34043
34134
|
const line = {
|
|
34044
34135
|
schema_version: 1,
|
|
@@ -34065,7 +34156,14 @@ function buildReviewSkippedLine(input) {
|
|
|
34065
34156
|
persona: null,
|
|
34066
34157
|
input_kind: "prompt",
|
|
34067
34158
|
type: "note",
|
|
34068
|
-
review_skipped: {
|
|
34159
|
+
review_skipped: {
|
|
34160
|
+
diff_lines: input.diff_lines,
|
|
34161
|
+
mutation_measure: input.mutation_measure,
|
|
34162
|
+
// Omitted, not defaulted, when the producer recorded nothing —
|
|
34163
|
+
// audit-log-v1's absent-versus-present split is the same one
|
|
34164
|
+
// `skills_applied` uses above, for the same reason.
|
|
34165
|
+
...input.baseline === void 0 ? {} : { baseline: input.baseline }
|
|
34166
|
+
}
|
|
34069
34167
|
};
|
|
34070
34168
|
return { line, errors: [] };
|
|
34071
34169
|
}
|
|
@@ -34079,13 +34177,13 @@ function isSafeTranscriptPath(rawPath, opts = {}) {
|
|
|
34079
34177
|
const homeDir = opts.homeDir ?? os11.homedir();
|
|
34080
34178
|
const maxBytes = opts.maxBytes ?? TRANSCRIPT_SCAN_MAX_BYTES;
|
|
34081
34179
|
try {
|
|
34082
|
-
const realHome =
|
|
34083
|
-
const realPath =
|
|
34084
|
-
const
|
|
34085
|
-
if (
|
|
34180
|
+
const realHome = fs83.realpathSync(homeDir);
|
|
34181
|
+
const realPath = fs83.realpathSync(rawPath);
|
|
34182
|
+
const relative16 = path84.relative(realHome, realPath);
|
|
34183
|
+
if (relative16 === "" || relative16.startsWith("..") || path84.isAbsolute(relative16)) {
|
|
34086
34184
|
return false;
|
|
34087
34185
|
}
|
|
34088
|
-
const { size } =
|
|
34186
|
+
const { size } = fs83.statSync(realPath);
|
|
34089
34187
|
return size <= maxBytes;
|
|
34090
34188
|
} catch {
|
|
34091
34189
|
return false;
|
|
@@ -34116,7 +34214,7 @@ function nonDocMutatedLines(rows) {
|
|
|
34116
34214
|
}
|
|
34117
34215
|
function gitNumstatRows(cwd) {
|
|
34118
34216
|
try {
|
|
34119
|
-
const r =
|
|
34217
|
+
const r = spawnSync7("git", ["diff", "--numstat", "HEAD"], {
|
|
34120
34218
|
cwd,
|
|
34121
34219
|
encoding: "utf8",
|
|
34122
34220
|
maxBuffer: 16 * 1024 * 1024
|
|
@@ -34129,7 +34227,7 @@ function gitNumstatRows(cwd) {
|
|
|
34129
34227
|
}
|
|
34130
34228
|
function untrackedNonDocFiles(cwd) {
|
|
34131
34229
|
try {
|
|
34132
|
-
const r =
|
|
34230
|
+
const r = spawnSync7("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
34133
34231
|
cwd,
|
|
34134
34232
|
encoding: "utf8",
|
|
34135
34233
|
maxBuffer: 16 * 1024 * 1024
|
|
@@ -34144,13 +34242,13 @@ var BINARY_PROBE_BYTES = 8e3;
|
|
|
34144
34242
|
var UNTRACKED_FILE_READ_CAP_BYTES = 8 * 1024 * 1024;
|
|
34145
34243
|
function untrackedFileLineCount(cwd, relPath) {
|
|
34146
34244
|
try {
|
|
34147
|
-
const abs =
|
|
34148
|
-
const size =
|
|
34245
|
+
const abs = path84.resolve(cwd, relPath);
|
|
34246
|
+
const size = fs83.statSync(abs).size;
|
|
34149
34247
|
if (size === 0) return 0;
|
|
34150
34248
|
if (size > UNTRACKED_FILE_READ_CAP_BYTES) {
|
|
34151
34249
|
return MUTATION_LINE_THRESHOLD + 1;
|
|
34152
34250
|
}
|
|
34153
|
-
const buf =
|
|
34251
|
+
const buf = fs83.readFileSync(abs);
|
|
34154
34252
|
if (buf.length === 0) return 0;
|
|
34155
34253
|
const probe = buf.subarray(0, Math.min(buf.length, BINARY_PROBE_BYTES));
|
|
34156
34254
|
if (probe.includes(0)) return 0;
|
|
@@ -34229,30 +34327,31 @@ function scanTranscriptForReviewer(transcriptText) {
|
|
|
34229
34327
|
function buildAdvisoryLine(diffLines) {
|
|
34230
34328
|
return `this session mutated ${diffLines} lines without a neutral review; spawn a cross-model reviewer before claiming done (delegation-policy / verify-budget)`;
|
|
34231
34329
|
}
|
|
34232
|
-
function appendReviewSkippedTelemetry(workspaceRoot3, diffLines, mutationMeasure) {
|
|
34330
|
+
function appendReviewSkippedTelemetry(workspaceRoot3, diffLines, mutationMeasure, baseline) {
|
|
34233
34331
|
if (is_replay_mode()) return;
|
|
34234
34332
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
34235
34333
|
const { line, errors } = buildReviewSkippedLine({
|
|
34236
34334
|
diff_lines: diffLines,
|
|
34237
34335
|
mutation_measure: mutationMeasure,
|
|
34238
34336
|
ts,
|
|
34239
|
-
id: crypto9.randomUUID()
|
|
34337
|
+
id: crypto9.randomUUID(),
|
|
34338
|
+
baseline
|
|
34240
34339
|
});
|
|
34241
34340
|
if (errors.length || line === null) return;
|
|
34242
34341
|
try {
|
|
34243
|
-
const dir =
|
|
34244
|
-
|
|
34245
|
-
const file =
|
|
34246
|
-
|
|
34342
|
+
const dir = path84.join(workspaceRoot3, "agents", "runtime", "state", "audit");
|
|
34343
|
+
fs83.mkdirSync(dir, { recursive: true });
|
|
34344
|
+
const file = path84.join(dir, `${ts.slice(0, 7)}.jsonl`);
|
|
34345
|
+
fs83.appendFileSync(file, `${JSON.stringify(line)}
|
|
34247
34346
|
`, "utf8");
|
|
34248
34347
|
} catch {
|
|
34249
34348
|
}
|
|
34250
34349
|
}
|
|
34251
34350
|
function sessionStateDir(workspaceRoot3) {
|
|
34252
|
-
return
|
|
34351
|
+
return path84.join(workspaceRoot3, "agents", "runtime", "state", "end-review-nudge");
|
|
34253
34352
|
}
|
|
34254
34353
|
function sessionStateFile(workspaceRoot3, sessionKey) {
|
|
34255
|
-
return
|
|
34354
|
+
return path84.join(sessionStateDir(workspaceRoot3), `${sessionKey}.json`);
|
|
34256
34355
|
}
|
|
34257
34356
|
function deriveSessionKey2(envelope, payload) {
|
|
34258
34357
|
const raw = str6(envelope["session_id"]) || str6(payload["transcript_path"] ?? payload["transcriptPath"]);
|
|
@@ -34261,7 +34360,7 @@ function deriveSessionKey2(envelope, payload) {
|
|
|
34261
34360
|
}
|
|
34262
34361
|
function hasFiredThisSession(workspaceRoot3, sessionKey) {
|
|
34263
34362
|
try {
|
|
34264
|
-
return
|
|
34363
|
+
return fs83.existsSync(sessionStateFile(workspaceRoot3, sessionKey));
|
|
34265
34364
|
} catch {
|
|
34266
34365
|
return false;
|
|
34267
34366
|
}
|
|
@@ -34275,6 +34374,12 @@ function markFiredThisSession(workspaceRoot3, sessionKey, ts) {
|
|
|
34275
34374
|
function _read_stdin3() {
|
|
34276
34375
|
return readHookStdin();
|
|
34277
34376
|
}
|
|
34377
|
+
var FALLBACK_TO_TELEMETRY = {
|
|
34378
|
+
absent: "absent",
|
|
34379
|
+
unreadable: "unreadable",
|
|
34380
|
+
"head-moved": "head_moved",
|
|
34381
|
+
"mixed-measure": "mixed_measure"
|
|
34382
|
+
};
|
|
34278
34383
|
function main54() {
|
|
34279
34384
|
const [envelope, payload] = unwrap(_read_stdin3(), "claude");
|
|
34280
34385
|
const event = String(envelope["event"] ?? "");
|
|
@@ -34282,19 +34387,32 @@ function main54() {
|
|
|
34282
34387
|
return 0;
|
|
34283
34388
|
}
|
|
34284
34389
|
const workspace_root = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
|
|
34285
|
-
let
|
|
34390
|
+
let measuredLines;
|
|
34286
34391
|
let mutationMeasure;
|
|
34287
34392
|
try {
|
|
34288
34393
|
const measured = totalNonDocMutatedLinesWithMeasure(workspace_root);
|
|
34289
|
-
|
|
34394
|
+
measuredLines = measured.lines;
|
|
34290
34395
|
mutationMeasure = measured.measure;
|
|
34291
34396
|
} catch {
|
|
34292
34397
|
return 0;
|
|
34293
34398
|
}
|
|
34399
|
+
const sessionKey = deriveSessionKey2(envelope, payload);
|
|
34400
|
+
const baselineOutcome = applyBaseline(
|
|
34401
|
+
measuredLines,
|
|
34402
|
+
readBaseline(workspace_root, sessionKey),
|
|
34403
|
+
// A THUNK, not a value: on the `absent` and `unreadable` branches the
|
|
34404
|
+
// result is discarded, and those two are the steady state on every host
|
|
34405
|
+
// without this nudge and on every session before its first baseline
|
|
34406
|
+
// write. Passing the value eagerly spent an 11-14 ms `git rev-parse` on
|
|
34407
|
+
// each of those stops for nothing.
|
|
34408
|
+
() => currentHeadSha(workspace_root),
|
|
34409
|
+
mutationMeasure
|
|
34410
|
+
);
|
|
34411
|
+
const diffLines = baselineOutcome.lines;
|
|
34412
|
+
const baselineApplication = baselineOutcome.applied ? "applied" : FALLBACK_TO_TELEMETRY[baselineOutcome.fallback];
|
|
34294
34413
|
if (diffLines <= MUTATION_LINE_THRESHOLD) {
|
|
34295
34414
|
return 0;
|
|
34296
34415
|
}
|
|
34297
|
-
const sessionKey = deriveSessionKey2(envelope, payload);
|
|
34298
34416
|
if (hasFiredThisSession(workspace_root, sessionKey)) {
|
|
34299
34417
|
return 0;
|
|
34300
34418
|
}
|
|
@@ -34304,7 +34422,7 @@ function main54() {
|
|
|
34304
34422
|
let reviewerRan = false;
|
|
34305
34423
|
if (transcriptPath && isSafeTranscriptPath(transcriptPath)) {
|
|
34306
34424
|
try {
|
|
34307
|
-
reviewerRan = scanTranscriptForReviewer(
|
|
34425
|
+
reviewerRan = scanTranscriptForReviewer(fs83.readFileSync(transcriptPath, "utf-8"));
|
|
34308
34426
|
} catch {
|
|
34309
34427
|
reviewerRan = false;
|
|
34310
34428
|
}
|
|
@@ -34314,7 +34432,12 @@ function main54() {
|
|
|
34314
34432
|
}
|
|
34315
34433
|
markFiredThisSession(workspace_root, sessionKey, (/* @__PURE__ */ new Date()).toISOString());
|
|
34316
34434
|
try {
|
|
34317
|
-
appendReviewSkippedTelemetry(
|
|
34435
|
+
appendReviewSkippedTelemetry(
|
|
34436
|
+
workspace_root,
|
|
34437
|
+
diffLines,
|
|
34438
|
+
mutationMeasure,
|
|
34439
|
+
baselineApplication
|
|
34440
|
+
);
|
|
34318
34441
|
} catch {
|
|
34319
34442
|
}
|
|
34320
34443
|
process.stdout.write(
|
|
@@ -34334,13 +34457,13 @@ function _isCliEntry38() {
|
|
|
34334
34457
|
if (process.argv[1] === void 0) {
|
|
34335
34458
|
return false;
|
|
34336
34459
|
}
|
|
34337
|
-
const argvUrl = pathToFileURL48(
|
|
34460
|
+
const argvUrl = pathToFileURL48(path84.resolve(process.argv[1])).href;
|
|
34338
34461
|
if (import.meta.url === argvUrl) {
|
|
34339
34462
|
return true;
|
|
34340
34463
|
}
|
|
34341
34464
|
try {
|
|
34342
|
-
const here =
|
|
34343
|
-
const argv =
|
|
34465
|
+
const here = fs83.realpathSync(fileURLToPath56(import.meta.url));
|
|
34466
|
+
const argv = fs83.realpathSync(path84.resolve(process.argv[1]));
|
|
34344
34467
|
return here === argv;
|
|
34345
34468
|
} catch {
|
|
34346
34469
|
return false;
|
|
@@ -34350,16 +34473,530 @@ if (_isCliEntry38()) {
|
|
|
34350
34473
|
process.exit(main54());
|
|
34351
34474
|
}
|
|
34352
34475
|
|
|
34353
|
-
// src/scripts/hooks/
|
|
34476
|
+
// src/scripts/hooks/review_baseline_hook.ts
|
|
34354
34477
|
import * as fs84 from "node:fs";
|
|
34355
34478
|
import * as path85 from "node:path";
|
|
34356
|
-
import { fileURLToPath as
|
|
34479
|
+
import { fileURLToPath as fileURLToPath57, pathToFileURL as pathToFileURL49 } from "node:url";
|
|
34480
|
+
var EXIT_OK2 = 0;
|
|
34481
|
+
function buildBaseline(workspaceRoot3, now = /* @__PURE__ */ new Date()) {
|
|
34482
|
+
const measured = totalNonDocMutatedLinesWithMeasure(workspaceRoot3);
|
|
34483
|
+
return {
|
|
34484
|
+
head_sha: currentHeadSha(workspaceRoot3),
|
|
34485
|
+
baseline_lines: measured.lines,
|
|
34486
|
+
// Carried, not discarded. Past `UNTRACKED_FILE_CAP` the count is a
|
|
34487
|
+
// synthetic `THRESHOLD + 1 + tracked` chosen to be over the bar rather
|
|
34488
|
+
// than to be true, and subtracting that from a later exact count is
|
|
34489
|
+
// arithmetic over two different quantities. The consumer refuses the
|
|
34490
|
+
// subtraction when the two measures disagree; it can only do that if the
|
|
34491
|
+
// writer says which one it took.
|
|
34492
|
+
measure: measured.measure,
|
|
34493
|
+
written_at: now.toISOString()
|
|
34494
|
+
};
|
|
34495
|
+
}
|
|
34496
|
+
function main55() {
|
|
34497
|
+
let envelope;
|
|
34498
|
+
let payload;
|
|
34499
|
+
try {
|
|
34500
|
+
[envelope, payload] = unwrap(readHookStdin(), "claude");
|
|
34501
|
+
} catch {
|
|
34502
|
+
return EXIT_OK2;
|
|
34503
|
+
}
|
|
34504
|
+
const event = String(envelope["event"] ?? "");
|
|
34505
|
+
if (event !== "" && event !== "session_start") return EXIT_OK2;
|
|
34506
|
+
const workspaceRoot3 = String(envelope["workspace_root"] ?? "").trim() || process.cwd();
|
|
34507
|
+
const sessionKey = deriveSessionKey2(envelope, payload);
|
|
34508
|
+
const file = baselineStateFile(workspaceRoot3, sessionKey);
|
|
34509
|
+
try {
|
|
34510
|
+
if (fs84.existsSync(file)) return EXIT_OK2;
|
|
34511
|
+
} catch {
|
|
34512
|
+
return EXIT_OK2;
|
|
34513
|
+
}
|
|
34514
|
+
try {
|
|
34515
|
+
atomic_write_json(file, buildBaseline(workspaceRoot3));
|
|
34516
|
+
} catch {
|
|
34517
|
+
}
|
|
34518
|
+
return EXIT_OK2;
|
|
34519
|
+
}
|
|
34520
|
+
function _isCliEntry39() {
|
|
34521
|
+
if (true) return false;
|
|
34522
|
+
if (process.argv[1] === void 0) return false;
|
|
34523
|
+
const argvUrl = pathToFileURL49(path85.resolve(process.argv[1])).href;
|
|
34524
|
+
if (import.meta.url === argvUrl) return true;
|
|
34525
|
+
try {
|
|
34526
|
+
const here = fs84.realpathSync(fileURLToPath57(import.meta.url));
|
|
34527
|
+
const argv = fs84.realpathSync(path85.resolve(process.argv[1]));
|
|
34528
|
+
return here === argv;
|
|
34529
|
+
} catch {
|
|
34530
|
+
return false;
|
|
34531
|
+
}
|
|
34532
|
+
}
|
|
34533
|
+
if (_isCliEntry39()) {
|
|
34534
|
+
process.exit(main55());
|
|
34535
|
+
}
|
|
34536
|
+
|
|
34537
|
+
// src/scripts/hooks/turn_end_gate_hook.ts
|
|
34538
|
+
import * as fs88 from "node:fs";
|
|
34539
|
+
import * as path90 from "node:path";
|
|
34540
|
+
import { fileURLToPath as fileURLToPath61, pathToFileURL as pathToFileURL52 } from "node:url";
|
|
34541
|
+
|
|
34542
|
+
// src/scripts/check_reply_consistency.ts
|
|
34543
|
+
import * as fs86 from "node:fs";
|
|
34544
|
+
import * as path88 from "node:path";
|
|
34545
|
+
import { fileURLToPath as fileURLToPath59, pathToFileURL as pathToFileURL50 } from "node:url";
|
|
34546
|
+
|
|
34547
|
+
// src/scripts/_lib/agent_src.ts
|
|
34548
|
+
import * as fs85 from "node:fs";
|
|
34549
|
+
import * as path87 from "node:path";
|
|
34550
|
+
import { fileURLToPath as fileURLToPath58 } from "node:url";
|
|
34551
|
+
|
|
34552
|
+
// src/scripts/_lib/guidelines_lane.ts
|
|
34553
|
+
import * as path86 from "node:path";
|
|
34554
|
+
var GUIDELINES_SOURCE_REL = path86.join("docs", "guidelines");
|
|
34555
|
+
|
|
34556
|
+
// src/scripts/_lib/agent_src.ts
|
|
34557
|
+
var _HERE11 = path87.dirname(fileURLToPath58(import.meta.url));
|
|
34558
|
+
var _DEFAULT_ROOT = path87.resolve(_HERE11, "..", "..", "..");
|
|
34559
|
+
function _deriveRoots(root) {
|
|
34560
|
+
const packages = path87.join(root, "packages");
|
|
34561
|
+
const src = path87.join(root, "src");
|
|
34562
|
+
return {
|
|
34563
|
+
ROOT: root,
|
|
34564
|
+
LEGACY_SRC: path87.join(root, ".agent-src.uncondensed"),
|
|
34565
|
+
PACKAGES: packages,
|
|
34566
|
+
PACKAGE_CORE: path87.join(packages, "core"),
|
|
34567
|
+
SRC: src,
|
|
34568
|
+
SRC_SKILLS: path87.join(src, "skills"),
|
|
34569
|
+
SRC_RULES: path87.join(src, "rules"),
|
|
34570
|
+
SRC_AGENT: path87.join(src, "agent-src"),
|
|
34571
|
+
SRC_DOMAINS: path87.join(src, "domains")
|
|
34572
|
+
};
|
|
34573
|
+
}
|
|
34574
|
+
var _roots = _deriveRoots(_DEFAULT_ROOT);
|
|
34575
|
+
function _isDir4(p) {
|
|
34576
|
+
try {
|
|
34577
|
+
return fs85.statSync(p).isDirectory();
|
|
34578
|
+
} catch {
|
|
34579
|
+
return false;
|
|
34580
|
+
}
|
|
34581
|
+
}
|
|
34582
|
+
function _exists5(p) {
|
|
34583
|
+
try {
|
|
34584
|
+
fs85.statSync(p);
|
|
34585
|
+
return true;
|
|
34586
|
+
} catch {
|
|
34587
|
+
return false;
|
|
34588
|
+
}
|
|
34589
|
+
}
|
|
34590
|
+
function _iterdirSorted2(p) {
|
|
34591
|
+
let names;
|
|
34592
|
+
try {
|
|
34593
|
+
names = fs85.readdirSync(p);
|
|
34594
|
+
} catch {
|
|
34595
|
+
return [];
|
|
34596
|
+
}
|
|
34597
|
+
names.sort();
|
|
34598
|
+
return names.map((name) => path87.join(p, name));
|
|
34599
|
+
}
|
|
34600
|
+
function artefact_roots() {
|
|
34601
|
+
const roots = [];
|
|
34602
|
+
if (_exists5(_roots.LEGACY_SRC)) {
|
|
34603
|
+
roots.push(_roots.LEGACY_SRC);
|
|
34604
|
+
}
|
|
34605
|
+
if (_exists5(_roots.PACKAGES)) {
|
|
34606
|
+
for (const pkg of _iterdirSorted2(_roots.PACKAGES)) {
|
|
34607
|
+
const sub = path87.join(pkg, ".agent-src.uncondensed");
|
|
34608
|
+
if (_isDir4(sub)) {
|
|
34609
|
+
roots.push(sub);
|
|
34610
|
+
}
|
|
34611
|
+
}
|
|
34612
|
+
}
|
|
34613
|
+
if (_isDir4(_roots.SRC_AGENT)) {
|
|
34614
|
+
roots.push(_roots.SRC_AGENT);
|
|
34615
|
+
}
|
|
34616
|
+
if (_isDir4(_roots.SRC_SKILLS) || _isDir4(_roots.SRC_RULES)) {
|
|
34617
|
+
roots.push(_roots.SRC);
|
|
34618
|
+
}
|
|
34619
|
+
return roots;
|
|
34620
|
+
}
|
|
34621
|
+
|
|
34622
|
+
// src/scripts/check_reply_consistency.ts
|
|
34623
|
+
var _HERE12 = fileURLToPath59(import.meta.url);
|
|
34624
|
+
var ROOT3 = path88.resolve(path88.dirname(_HERE12), "..", "..");
|
|
34625
|
+
var QUIET = process.argv.slice(2).includes("--quiet");
|
|
34626
|
+
var OPTION_LINE_RE = /^\s*>?\s*(\d+)\.\s+\S/;
|
|
34627
|
+
var REC_LINE_RE = /(?:Recommendation|Empfehlung)\s*:\s*(\d+)\b/i;
|
|
34628
|
+
var TAG_RE = /\((?:recommended|rec|empfohlen)\)/i;
|
|
34629
|
+
var CODESPAN_RE = /`[^`\n]*`/g;
|
|
34630
|
+
var HEADING_RE = /^#{1,6}\s/;
|
|
34631
|
+
var FENCE_RE = /^\s*(```|~~~)/;
|
|
34632
|
+
var REC_ADJACENCY_WINDOW = 2;
|
|
34633
|
+
function _strip_codespans(line) {
|
|
34634
|
+
return line.replace(CODESPAN_RE, "``");
|
|
34635
|
+
}
|
|
34636
|
+
function splitAndMask(text) {
|
|
34637
|
+
return mask_fences(_splitlines4(text));
|
|
34638
|
+
}
|
|
34639
|
+
function _splitlines4(text) {
|
|
34640
|
+
if (text === "") return [];
|
|
34641
|
+
const parts = text.split(/\r\n|\r|\n/);
|
|
34642
|
+
if (parts.length > 0 && parts[parts.length - 1] === "") {
|
|
34643
|
+
parts.pop();
|
|
34644
|
+
}
|
|
34645
|
+
return parts;
|
|
34646
|
+
}
|
|
34647
|
+
function mask_fences(lines) {
|
|
34648
|
+
const out = [];
|
|
34649
|
+
let fence = null;
|
|
34650
|
+
for (const raw of lines) {
|
|
34651
|
+
const m = FENCE_RE.exec(raw);
|
|
34652
|
+
if (m) {
|
|
34653
|
+
const marker = m[1];
|
|
34654
|
+
if (fence === null) {
|
|
34655
|
+
fence = marker;
|
|
34656
|
+
} else if (fence === marker) {
|
|
34657
|
+
fence = null;
|
|
34658
|
+
}
|
|
34659
|
+
out.push("");
|
|
34660
|
+
continue;
|
|
34661
|
+
}
|
|
34662
|
+
out.push(fence === null ? raw : "");
|
|
34663
|
+
}
|
|
34664
|
+
return out;
|
|
34665
|
+
}
|
|
34666
|
+
function find_option_blocks(text) {
|
|
34667
|
+
const lines = mask_fences(_splitlines4(text));
|
|
34668
|
+
const blocks = [];
|
|
34669
|
+
let current = null;
|
|
34670
|
+
for (let idx = 0; idx < lines.length; idx++) {
|
|
34671
|
+
const m = OPTION_LINE_RE.exec(lines[idx]);
|
|
34672
|
+
if (m) {
|
|
34673
|
+
const num = parseInt(m[1], 10);
|
|
34674
|
+
if (current === null) {
|
|
34675
|
+
current = { startLine: idx + 1, endLine: idx + 1, numbers: [num] };
|
|
34676
|
+
} else {
|
|
34677
|
+
current.endLine = idx + 1;
|
|
34678
|
+
current.numbers.push(num);
|
|
34679
|
+
}
|
|
34680
|
+
} else {
|
|
34681
|
+
if (current !== null && current.numbers.length >= 2) {
|
|
34682
|
+
blocks.push(current);
|
|
34683
|
+
}
|
|
34684
|
+
current = null;
|
|
34685
|
+
}
|
|
34686
|
+
}
|
|
34687
|
+
if (current !== null && current.numbers.length >= 2) {
|
|
34688
|
+
blocks.push(current);
|
|
34689
|
+
}
|
|
34690
|
+
return blocks;
|
|
34691
|
+
}
|
|
34692
|
+
function recommendationsUnder(text, block, maskedLines) {
|
|
34693
|
+
const lines = maskedLines ?? mask_fences(_splitlines4(text));
|
|
34694
|
+
const recs = [];
|
|
34695
|
+
let inspected = 0;
|
|
34696
|
+
for (let idx = block.endLine; idx < lines.length && inspected < REC_ADJACENCY_WINDOW; idx++) {
|
|
34697
|
+
const line = lines[idx];
|
|
34698
|
+
if (line.trim() === "") {
|
|
34699
|
+
continue;
|
|
34700
|
+
}
|
|
34701
|
+
if (HEADING_RE.test(line) || OPTION_LINE_RE.test(line)) {
|
|
34702
|
+
break;
|
|
34703
|
+
}
|
|
34704
|
+
inspected += 1;
|
|
34705
|
+
const m = REC_LINE_RE.exec(line);
|
|
34706
|
+
if (m) {
|
|
34707
|
+
recs.push({ line: idx + 1, num: parseInt(m[1], 10) });
|
|
34708
|
+
}
|
|
34709
|
+
}
|
|
34710
|
+
return recs;
|
|
34711
|
+
}
|
|
34712
|
+
function check_reply(text) {
|
|
34713
|
+
const rawLines = _splitlines4(text);
|
|
34714
|
+
const lines = mask_fences(rawLines);
|
|
34715
|
+
const findings = [];
|
|
34716
|
+
for (let idx = 0; idx < lines.length; idx++) {
|
|
34717
|
+
const stripped = _strip_codespans(lines[idx]);
|
|
34718
|
+
if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
|
|
34719
|
+
findings.push({
|
|
34720
|
+
line: idx + 1,
|
|
34721
|
+
message: `inline tag on numbered option \u2014 ${rawLines[idx].trim()}`
|
|
34722
|
+
});
|
|
34723
|
+
}
|
|
34724
|
+
}
|
|
34725
|
+
const blocks = find_option_blocks(text);
|
|
34726
|
+
for (const block of blocks) {
|
|
34727
|
+
const recs = recommendationsUnder(text, block);
|
|
34728
|
+
if (recs.length === 0) {
|
|
34729
|
+
findings.push({
|
|
34730
|
+
line: block.startLine,
|
|
34731
|
+
message: "numbered options block without a Recommendation:/Empfehlung: line directly under it"
|
|
34732
|
+
});
|
|
34733
|
+
continue;
|
|
34734
|
+
}
|
|
34735
|
+
if (recs.length > 1) {
|
|
34736
|
+
findings.push({
|
|
34737
|
+
line: recs[1].line,
|
|
34738
|
+
message: `multiple recommendation lines under one options block: [${recs.map((r) => r.num).join(", ")}]`
|
|
34739
|
+
});
|
|
34740
|
+
continue;
|
|
34741
|
+
}
|
|
34742
|
+
const rec = recs[0];
|
|
34743
|
+
if (!block.numbers.includes(rec.num)) {
|
|
34744
|
+
findings.push({
|
|
34745
|
+
line: rec.line,
|
|
34746
|
+
message: `recommendation ${String(rec.num)} not present in the options block above it (options: [${block.numbers.join(", ")}])`
|
|
34747
|
+
});
|
|
34748
|
+
}
|
|
34749
|
+
}
|
|
34750
|
+
findings.sort((a, b) => a.line - b.line);
|
|
34751
|
+
return findings;
|
|
34752
|
+
}
|
|
34753
|
+
function _isDir5(p) {
|
|
34754
|
+
try {
|
|
34755
|
+
return fs86.statSync(p).isDirectory();
|
|
34756
|
+
} catch {
|
|
34757
|
+
return false;
|
|
34758
|
+
}
|
|
34759
|
+
}
|
|
34760
|
+
function _rglobMdSorted(dir) {
|
|
34761
|
+
const out = [];
|
|
34762
|
+
const walk = (current) => {
|
|
34763
|
+
let entries;
|
|
34764
|
+
try {
|
|
34765
|
+
entries = fs86.readdirSync(current, { withFileTypes: true });
|
|
34766
|
+
} catch {
|
|
34767
|
+
return;
|
|
34768
|
+
}
|
|
34769
|
+
for (const ent of entries) {
|
|
34770
|
+
const full = path88.join(current, ent.name);
|
|
34771
|
+
if (ent.isDirectory() || ent.isSymbolicLink() && _isDir5(full)) {
|
|
34772
|
+
walk(full);
|
|
34773
|
+
} else if (ent.name.endsWith(".md")) {
|
|
34774
|
+
out.push(full);
|
|
34775
|
+
}
|
|
34776
|
+
}
|
|
34777
|
+
};
|
|
34778
|
+
walk(dir);
|
|
34779
|
+
out.sort();
|
|
34780
|
+
return out;
|
|
34781
|
+
}
|
|
34782
|
+
function _relToPosixOrAbs(child, root) {
|
|
34783
|
+
const rel = path88.relative(root, child);
|
|
34784
|
+
if (rel === "" || rel.startsWith("..") || path88.isAbsolute(rel)) {
|
|
34785
|
+
return child.split(path88.sep).join("/");
|
|
34786
|
+
}
|
|
34787
|
+
return rel.split(path88.sep).join("/");
|
|
34788
|
+
}
|
|
34789
|
+
function cmd_scan_dir(root) {
|
|
34790
|
+
let roots;
|
|
34791
|
+
if (!_isDir5(root)) {
|
|
34792
|
+
const legacy = path88.join(ROOT3, ".agent-src.uncondensed");
|
|
34793
|
+
if (path88.resolve(root) === path88.resolve(legacy)) {
|
|
34794
|
+
roots = artefact_roots();
|
|
34795
|
+
if (roots.length === 0) {
|
|
34796
|
+
process.stderr.write("error: no artefact roots found (legacy or packages/*)\n");
|
|
34797
|
+
return 1;
|
|
34798
|
+
}
|
|
34799
|
+
} else {
|
|
34800
|
+
process.stderr.write(`error: not a directory: ${root}
|
|
34801
|
+
`);
|
|
34802
|
+
return 1;
|
|
34803
|
+
}
|
|
34804
|
+
} else {
|
|
34805
|
+
roots = [root];
|
|
34806
|
+
}
|
|
34807
|
+
const violations = [];
|
|
34808
|
+
let scanned = 0;
|
|
34809
|
+
for (const r of roots) {
|
|
34810
|
+
for (const md of _rglobMdSorted(r)) {
|
|
34811
|
+
scanned += 1;
|
|
34812
|
+
const text = fs86.readFileSync(md, "utf-8");
|
|
34813
|
+
const lines = _splitlines4(text);
|
|
34814
|
+
for (let idx = 0; idx < lines.length; idx++) {
|
|
34815
|
+
const raw = lines[idx];
|
|
34816
|
+
const stripped = _strip_codespans(raw);
|
|
34817
|
+
if (OPTION_LINE_RE.test(stripped) && TAG_RE.test(stripped)) {
|
|
34818
|
+
violations.push([md, idx + 1, raw.trim()]);
|
|
34819
|
+
}
|
|
34820
|
+
}
|
|
34821
|
+
}
|
|
34822
|
+
}
|
|
34823
|
+
try {
|
|
34824
|
+
assertScanned({
|
|
34825
|
+
gate: "check_reply_consistency",
|
|
34826
|
+
scanned,
|
|
34827
|
+
units: "markdown file(s)",
|
|
34828
|
+
roots: roots.map((r) => _relToPosixOrAbs(r, ROOT3))
|
|
34829
|
+
});
|
|
34830
|
+
} catch (exc) {
|
|
34831
|
+
if (exc instanceof DeadScopeError) {
|
|
34832
|
+
process.stderr.write(`\u274C ${exc.message}
|
|
34833
|
+
`);
|
|
34834
|
+
return 1;
|
|
34835
|
+
}
|
|
34836
|
+
throw exc;
|
|
34837
|
+
}
|
|
34838
|
+
if (violations.length > 0) {
|
|
34839
|
+
for (const [p, line, snippet] of violations) {
|
|
34840
|
+
process.stderr.write(` \u{1F534} ${p}:${String(line)} \u2014 inline-tag \u2014 ${snippet}
|
|
34841
|
+
`);
|
|
34842
|
+
}
|
|
34843
|
+
process.stderr.write(`
|
|
34844
|
+
\u274C ${String(violations.length)} legacy-pattern violation(s)
|
|
34845
|
+
`);
|
|
34846
|
+
return 2;
|
|
34847
|
+
}
|
|
34848
|
+
if (!QUIET) {
|
|
34849
|
+
const scanned2 = roots.map((r) => _relToPosixOrAbs(r, ROOT3)).join(", ");
|
|
34850
|
+
process.stdout.write(`\u2705 No legacy (recommended) tags found under ${scanned2}
|
|
34851
|
+
`);
|
|
34852
|
+
}
|
|
34853
|
+
return 0;
|
|
34854
|
+
}
|
|
34855
|
+
var USAGE = "usage: check_reply_consistency [-h] (--stdin | --file FILE | --scan-dir SCAN_DIR)\n [-v] [--quiet]\n";
|
|
34856
|
+
function _usage_error(message) {
|
|
34857
|
+
process.stderr.write(USAGE);
|
|
34858
|
+
process.stderr.write(`check_reply_consistency: error: ${message}
|
|
34859
|
+
`);
|
|
34860
|
+
process.exit(1);
|
|
34861
|
+
}
|
|
34862
|
+
function _readStdin14() {
|
|
34863
|
+
try {
|
|
34864
|
+
return fs86.readFileSync(0, "utf-8");
|
|
34865
|
+
} catch {
|
|
34866
|
+
return "";
|
|
34867
|
+
}
|
|
34868
|
+
}
|
|
34869
|
+
function parse_args9(argv) {
|
|
34870
|
+
let stdin = false;
|
|
34871
|
+
let file = null;
|
|
34872
|
+
let scan_dir = null;
|
|
34873
|
+
let verbose = false;
|
|
34874
|
+
const groupSeen = [];
|
|
34875
|
+
const need = (i, name) => {
|
|
34876
|
+
const v = argv[i];
|
|
34877
|
+
if (v === void 0) {
|
|
34878
|
+
_usage_error(`argument ${name}: expected one argument`);
|
|
34879
|
+
}
|
|
34880
|
+
return v;
|
|
34881
|
+
};
|
|
34882
|
+
for (let i = 0; i < argv.length; i++) {
|
|
34883
|
+
const arg = argv[i];
|
|
34884
|
+
if (arg === "--stdin") {
|
|
34885
|
+
stdin = true;
|
|
34886
|
+
groupSeen.push("--stdin");
|
|
34887
|
+
} else if (arg === "--file") {
|
|
34888
|
+
file = need(++i, "--file");
|
|
34889
|
+
groupSeen.push("--file");
|
|
34890
|
+
} else if (arg.startsWith("--file=")) {
|
|
34891
|
+
file = arg.slice("--file=".length);
|
|
34892
|
+
groupSeen.push("--file");
|
|
34893
|
+
} else if (arg === "--scan-dir") {
|
|
34894
|
+
scan_dir = need(++i, "--scan-dir");
|
|
34895
|
+
groupSeen.push("--scan-dir");
|
|
34896
|
+
} else if (arg.startsWith("--scan-dir=")) {
|
|
34897
|
+
scan_dir = arg.slice("--scan-dir=".length);
|
|
34898
|
+
groupSeen.push("--scan-dir");
|
|
34899
|
+
} else if (arg === "-v" || arg === "--verbose") {
|
|
34900
|
+
verbose = true;
|
|
34901
|
+
} else if (arg === "--quiet") {
|
|
34902
|
+
} else if (arg === "-h" || arg === "--help") {
|
|
34903
|
+
process.stdout.write(USAGE);
|
|
34904
|
+
process.exit(0);
|
|
34905
|
+
} else {
|
|
34906
|
+
_usage_error(`unrecognized arguments: ${arg}`);
|
|
34907
|
+
}
|
|
34908
|
+
}
|
|
34909
|
+
if (groupSeen.length === 0) {
|
|
34910
|
+
_usage_error("one of the arguments --stdin --file --scan-dir is required");
|
|
34911
|
+
}
|
|
34912
|
+
if (groupSeen.length > 1) {
|
|
34913
|
+
_usage_error(`argument ${groupSeen[1]}: not allowed with argument ${groupSeen[0]}`);
|
|
34914
|
+
}
|
|
34915
|
+
return { stdin, file, scan_dir, verbose };
|
|
34916
|
+
}
|
|
34917
|
+
function main56(argv = process.argv.slice(2)) {
|
|
34918
|
+
const args = parse_args9(argv);
|
|
34919
|
+
if (args.scan_dir !== null) {
|
|
34920
|
+
return cmd_scan_dir(args.scan_dir);
|
|
34921
|
+
}
|
|
34922
|
+
let text;
|
|
34923
|
+
try {
|
|
34924
|
+
text = args.stdin ? _readStdin14() : fs86.readFileSync(args.file, "utf-8");
|
|
34925
|
+
} catch (e) {
|
|
34926
|
+
process.stderr.write(`error: ${String(e)}
|
|
34927
|
+
`);
|
|
34928
|
+
return 1;
|
|
34929
|
+
}
|
|
34930
|
+
const findings = check_reply(text);
|
|
34931
|
+
if (findings.length === 0) {
|
|
34932
|
+
if (args.verbose && !QUIET) {
|
|
34933
|
+
process.stdout.write("\u2705 reply consistent (every options block carries one adjacent recommendation)\n");
|
|
34934
|
+
}
|
|
34935
|
+
return 0;
|
|
34936
|
+
}
|
|
34937
|
+
for (const f of findings) {
|
|
34938
|
+
process.stderr.write(`\u274C line ${String(f.line)}: ${f.message}
|
|
34939
|
+
`);
|
|
34940
|
+
}
|
|
34941
|
+
return 2;
|
|
34942
|
+
}
|
|
34943
|
+
function _isCliEntry40() {
|
|
34944
|
+
if (true) {
|
|
34945
|
+
return false;
|
|
34946
|
+
}
|
|
34947
|
+
if (process.argv[1] === void 0) {
|
|
34948
|
+
return false;
|
|
34949
|
+
}
|
|
34950
|
+
const argvUrl = pathToFileURL50(path88.resolve(process.argv[1])).href;
|
|
34951
|
+
if (import.meta.url === argvUrl) {
|
|
34952
|
+
return true;
|
|
34953
|
+
}
|
|
34954
|
+
try {
|
|
34955
|
+
const here = fs86.realpathSync(fileURLToPath59(import.meta.url));
|
|
34956
|
+
const argv = fs86.realpathSync(path88.resolve(process.argv[1]));
|
|
34957
|
+
return here === argv;
|
|
34958
|
+
} catch {
|
|
34959
|
+
return false;
|
|
34960
|
+
}
|
|
34961
|
+
}
|
|
34962
|
+
var _IN_BUNDLE2 = true;
|
|
34963
|
+
if (!_IN_BUNDLE2 && (_isCliEntry40() || process.argv[1] === _HERE12)) {
|
|
34964
|
+
process.exit(main56());
|
|
34965
|
+
}
|
|
34966
|
+
|
|
34967
|
+
// src/scripts/_lib/dropped_decision.ts
|
|
34968
|
+
function detectDroppedDecision(assistantTurnTexts, closingFromPayload = false) {
|
|
34969
|
+
if (assistantTurnTexts.length < 2) return null;
|
|
34970
|
+
const asksIn = (text) => {
|
|
34971
|
+
const blocks = find_option_blocks(text);
|
|
34972
|
+
if (blocks.length === 0) return blocks;
|
|
34973
|
+
const masked = splitAndMask(text);
|
|
34974
|
+
return blocks.filter((b) => recommendationsUnder(text, b, masked).length > 0);
|
|
34975
|
+
};
|
|
34976
|
+
const closing = assistantTurnTexts[assistantTurnTexts.length - 1];
|
|
34977
|
+
if (asksIn(closing).length > 0) return null;
|
|
34978
|
+
for (let i = assistantTurnTexts.length - 2; i >= 0; i -= 1) {
|
|
34979
|
+
const earlier = assistantTurnTexts[i];
|
|
34980
|
+
const blocks = asksIn(earlier);
|
|
34981
|
+
if (blocks.length === 0) continue;
|
|
34982
|
+
const block = blocks[blocks.length - 1];
|
|
34983
|
+
return {
|
|
34984
|
+
detector: "pending-decision",
|
|
34985
|
+
// The option NUMBERS and the line span, never the option text: the
|
|
34986
|
+
// evidence is quoted into a refusal that reaches the transcript, and
|
|
34987
|
+
// an options block can carry anything the reply carried.
|
|
34988
|
+
evidence: `options ${block.numbers.join("/")} at lines ${block.startLine}-${block.endLine} of an earlier reply this turn (closing reply read from ${closingFromPayload ? "the stop payload" : "the transcript"})`,
|
|
34989
|
+
reason: "an earlier reply in THIS turn put numbered options to the user and no user answer followed \u2014 this closing reply carries no options block, so the decision disappeared without being answered, cancelled or superseded. A hook nudge, a reviewer result or a task notification may ADD to a turn; it may not displace a question already asked (user-interaction Iron Law 3: a decision handed to the user outlives the turn). Re-present the block and its recommendation line at the end of this reply"
|
|
34990
|
+
};
|
|
34991
|
+
}
|
|
34992
|
+
return null;
|
|
34993
|
+
}
|
|
34357
34994
|
|
|
34358
34995
|
// src/scripts/hooks/subagent_ledger_hook.ts
|
|
34359
34996
|
import * as crypto10 from "node:crypto";
|
|
34360
|
-
import * as
|
|
34361
|
-
import * as
|
|
34362
|
-
import { fileURLToPath as
|
|
34997
|
+
import * as fs87 from "node:fs";
|
|
34998
|
+
import * as path89 from "node:path";
|
|
34999
|
+
import { fileURLToPath as fileURLToPath60, pathToFileURL as pathToFileURL51 } from "node:url";
|
|
34363
35000
|
|
|
34364
35001
|
// src/scripts/_lib/subagent_response.ts
|
|
34365
35002
|
var MAX_SUMMARY_CHARS = 2e3;
|
|
@@ -34465,7 +35102,7 @@ var EXIT_ALLOW26 = 0;
|
|
|
34465
35102
|
function isObject13(v) {
|
|
34466
35103
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
34467
35104
|
}
|
|
34468
|
-
var LEDGER_DIR =
|
|
35105
|
+
var LEDGER_DIR = path89.join("agents", "runtime", "state", "subagent-ledger");
|
|
34469
35106
|
var OPEN_SUBDIR = "open";
|
|
34470
35107
|
var OPEN_RECORD_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
34471
35108
|
function refFor(agentId) {
|
|
@@ -34555,10 +35192,10 @@ function _jsonObjectCandidates(message) {
|
|
|
34555
35192
|
return out;
|
|
34556
35193
|
}
|
|
34557
35194
|
function openDir(root) {
|
|
34558
|
-
return
|
|
35195
|
+
return path89.join(root, LEDGER_DIR, OPEN_SUBDIR);
|
|
34559
35196
|
}
|
|
34560
35197
|
function openFile(root, ref) {
|
|
34561
|
-
return
|
|
35198
|
+
return path89.join(openDir(root), `${ref}.json`);
|
|
34562
35199
|
}
|
|
34563
35200
|
var DEPTH_BASES = /* @__PURE__ */ new Set(["observed", "asserted-parent", "assumed-root"]);
|
|
34564
35201
|
function _asOpenRecord(value, expectedRef) {
|
|
@@ -34585,7 +35222,7 @@ function readOpenRecords(root) {
|
|
|
34585
35222
|
const out = /* @__PURE__ */ new Map();
|
|
34586
35223
|
let names;
|
|
34587
35224
|
try {
|
|
34588
|
-
names =
|
|
35225
|
+
names = fs87.readdirSync(openDir(root));
|
|
34589
35226
|
} catch {
|
|
34590
35227
|
return out;
|
|
34591
35228
|
}
|
|
@@ -34593,7 +35230,7 @@ function readOpenRecords(root) {
|
|
|
34593
35230
|
if (!name.endsWith(".json")) continue;
|
|
34594
35231
|
const expectedRef = name.slice(0, -".json".length);
|
|
34595
35232
|
try {
|
|
34596
|
-
const raw =
|
|
35233
|
+
const raw = fs87.readFileSync(path89.join(openDir(root), name), "utf8");
|
|
34597
35234
|
const rec = _asOpenRecord(JSON.parse(raw), expectedRef);
|
|
34598
35235
|
if (rec) out.set(rec.ref, rec);
|
|
34599
35236
|
} catch {
|
|
@@ -34608,13 +35245,13 @@ function resolveDepth(parentRef, open) {
|
|
|
34608
35245
|
return { depth: parent.depth + 1, depth_basis: "observed" };
|
|
34609
35246
|
}
|
|
34610
35247
|
function ledgerFileFor2(root, ts) {
|
|
34611
|
-
return
|
|
35248
|
+
return path89.join(root, LEDGER_DIR, `${ts.slice(0, 7)}.jsonl`);
|
|
34612
35249
|
}
|
|
34613
35250
|
function appendLedgerLine(root, ts, line) {
|
|
34614
35251
|
if (is_replay_mode()) return;
|
|
34615
35252
|
const file = ledgerFileFor2(root, ts);
|
|
34616
|
-
|
|
34617
|
-
|
|
35253
|
+
fs87.mkdirSync(path89.dirname(file), { recursive: true });
|
|
35254
|
+
fs87.appendFileSync(file, `${JSON.stringify(line)}
|
|
34618
35255
|
`, "utf8");
|
|
34619
35256
|
}
|
|
34620
35257
|
var WALL_CLOCK_ARMS_MS = [
|
|
@@ -34628,7 +35265,7 @@ function armsExceeded(elapsedMs) {
|
|
|
34628
35265
|
return WALL_CLOCK_ARMS_MS.filter((a) => elapsedMs >= a.ms).map((a) => a.label);
|
|
34629
35266
|
}
|
|
34630
35267
|
function openRecordStats(root, nowMs = Date.now()) {
|
|
34631
|
-
const ledgerPresent =
|
|
35268
|
+
const ledgerPresent = fs87.existsSync(path89.join(root, LEDGER_DIR));
|
|
34632
35269
|
const open = readOpenRecords(root);
|
|
34633
35270
|
let maxDepth = 0;
|
|
34634
35271
|
let counted = 0;
|
|
@@ -34656,13 +35293,13 @@ function writeOpenRecord(root, rec) {
|
|
|
34656
35293
|
function removeOpenRecord(root, ref) {
|
|
34657
35294
|
if (is_replay_mode()) return;
|
|
34658
35295
|
try {
|
|
34659
|
-
|
|
35296
|
+
fs87.unlinkSync(openFile(root, ref));
|
|
34660
35297
|
} catch {
|
|
34661
35298
|
}
|
|
34662
35299
|
}
|
|
34663
35300
|
function countOpen(root) {
|
|
34664
35301
|
try {
|
|
34665
|
-
return
|
|
35302
|
+
return fs87.readdirSync(openDir(root)).filter((n) => n.endsWith(".json")).length;
|
|
34666
35303
|
} catch {
|
|
34667
35304
|
return 0;
|
|
34668
35305
|
}
|
|
@@ -34813,7 +35450,7 @@ function resolveConsumerRoot(envelope) {
|
|
|
34813
35450
|
}
|
|
34814
35451
|
return process.cwd();
|
|
34815
35452
|
}
|
|
34816
|
-
function
|
|
35453
|
+
function main57() {
|
|
34817
35454
|
const raw = readHookStdin();
|
|
34818
35455
|
let envelope = {};
|
|
34819
35456
|
try {
|
|
@@ -34823,20 +35460,20 @@ function main55() {
|
|
|
34823
35460
|
}
|
|
34824
35461
|
return processEnvelope3(envelope, resolveConsumerRoot(envelope));
|
|
34825
35462
|
}
|
|
34826
|
-
function
|
|
35463
|
+
function _isCliEntry41() {
|
|
34827
35464
|
if (true) {
|
|
34828
35465
|
return false;
|
|
34829
35466
|
}
|
|
34830
35467
|
if (process.argv[1] === void 0) return false;
|
|
34831
|
-
const argvUrl =
|
|
35468
|
+
const argvUrl = pathToFileURL51(path89.resolve(process.argv[1])).href;
|
|
34832
35469
|
if (import.meta.url === argvUrl) return true;
|
|
34833
35470
|
try {
|
|
34834
|
-
return
|
|
35471
|
+
return fs87.realpathSync(fileURLToPath60(import.meta.url)) === fs87.realpathSync(path89.resolve(process.argv[1]));
|
|
34835
35472
|
} catch {
|
|
34836
35473
|
return false;
|
|
34837
35474
|
}
|
|
34838
35475
|
}
|
|
34839
|
-
if (
|
|
35476
|
+
if (_isCliEntry41()) process.exit(main57());
|
|
34840
35477
|
|
|
34841
35478
|
// src/scripts/hooks/turn_end_gate_hook.ts
|
|
34842
35479
|
var EXIT_BLOCK3 = 1;
|
|
@@ -34945,7 +35582,7 @@ function detectPromissory(reply) {
|
|
|
34945
35582
|
function readCiSettled(workspaceRoot3, session_id) {
|
|
34946
35583
|
if (!hasStableSessionId(session_id)) return { seen: false, settled: false };
|
|
34947
35584
|
try {
|
|
34948
|
-
const raw =
|
|
35585
|
+
const raw = fs88.readFileSync(path90.join(workspaceRoot3, statePathFor(session_id)), "utf-8");
|
|
34949
35586
|
const decoded = JSON.parse(raw);
|
|
34950
35587
|
if (!owns_session_state(decoded, session_id)) return { seen: false, settled: false };
|
|
34951
35588
|
if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
|
|
@@ -34981,8 +35618,8 @@ function detectCompletionClaim(reply, ci) {
|
|
|
34981
35618
|
function readLanguagePin(workspaceRoot3, session_id) {
|
|
34982
35619
|
if (!hasStableSessionId(session_id)) return "und";
|
|
34983
35620
|
try {
|
|
34984
|
-
const raw =
|
|
34985
|
-
|
|
35621
|
+
const raw = fs88.readFileSync(
|
|
35622
|
+
path90.join(workspaceRoot3, statePathFor2(session_id)),
|
|
34986
35623
|
"utf-8"
|
|
34987
35624
|
);
|
|
34988
35625
|
const decoded = JSON.parse(raw);
|
|
@@ -35033,12 +35670,37 @@ function detectUnverifiedEdit(toolCalls) {
|
|
|
35033
35670
|
reason: "this turn changed a file and then ran no verification command \u2014 no test, type-check, lint or build call follows the last edit (verify-before-complete: a claim without a fresh run is unverified)"
|
|
35034
35671
|
};
|
|
35035
35672
|
}
|
|
35673
|
+
var _SOURCE_RE = /\.(?:ts|tsx|js|jsx|mjs|cjs|vue|svelte|php|py|rb|go|rs|java|kt|swift|cs|scala|ex|exs)$/i;
|
|
35674
|
+
var _TEST_PATH_RE = /(?:^|\/)(?:tests?|specs?|__tests__|__specs__|e2e|cypress|playwright|features)\//i;
|
|
35675
|
+
var _TEST_FILE_RE = /(?:\.(?:test|spec)\.[a-z]+$)|(?:_test\.[a-z]+$)|(?:(?:^|\/)test_[^/]+$)|(?:Test\.php$)|(?:Spec\.php$)|(?:\.feature$)/i;
|
|
35676
|
+
function _isTestPath(p) {
|
|
35677
|
+
return _TEST_PATH_RE.test(p) || _TEST_FILE_RE.test(p);
|
|
35678
|
+
}
|
|
35679
|
+
function _isProductionSource(p) {
|
|
35680
|
+
return _SOURCE_RE.test(p) && !_isTestPath(p);
|
|
35681
|
+
}
|
|
35682
|
+
function detectUntestedChange(reply, toolCalls) {
|
|
35683
|
+
const edited = toolCalls.filter((c) => _EDIT_TOOLS.has(c.name) && c.path !== void 0).map((c) => c.path);
|
|
35684
|
+
const source = edited.filter(_isProductionSource);
|
|
35685
|
+
if (source.length === 0) return null;
|
|
35686
|
+
if (edited.some(_isTestPath)) return null;
|
|
35687
|
+
const prose = visibleProse(reply);
|
|
35688
|
+
const m = _COMPLETION_RE.exec(prose);
|
|
35689
|
+
if (!m) return null;
|
|
35690
|
+
if (_NEGATED_CLAIM_RE.test(_lineAround(prose, m.index))) return null;
|
|
35691
|
+
const shown = source.slice(0, 3).join(", ");
|
|
35692
|
+
return {
|
|
35693
|
+
detector: "untested",
|
|
35694
|
+
evidence: shown + (source.length > 3 ? ` (+${String(source.length - 3)} more)` : ""),
|
|
35695
|
+
reason: "a completion claim over production code this turn changed, with NO test file touched anywhere in the turn \u2014 running a linter is not evidence the change works. Write the test that would have caught the failure, and enumerate the states the change actually has (every view, every CRUD path, the empty and error states) rather than the happy one. If a test genuinely does not belong here, say which file carries the coverage instead"
|
|
35696
|
+
};
|
|
35697
|
+
}
|
|
35036
35698
|
function sessionStateFile2(workspaceRoot3, sessionKey) {
|
|
35037
35699
|
return sessionRefusalFile(workspaceRoot3, sessionKey);
|
|
35038
35700
|
}
|
|
35039
35701
|
function alreadyRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal) {
|
|
35040
35702
|
try {
|
|
35041
|
-
const raw =
|
|
35703
|
+
const raw = fs88.readFileSync(sessionStateFile2(workspaceRoot3, sessionKey), "utf-8");
|
|
35042
35704
|
const decoded = JSON.parse(raw);
|
|
35043
35705
|
if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
|
|
35044
35706
|
return decoded["refused_turn"] === turnOrdinal;
|
|
@@ -35047,12 +35709,12 @@ function alreadyRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal) {
|
|
|
35047
35709
|
}
|
|
35048
35710
|
return false;
|
|
35049
35711
|
}
|
|
35050
|
-
function markRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal, detectors) {
|
|
35712
|
+
function markRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal, detectors, promptId) {
|
|
35051
35713
|
if (is_replay_mode()) return;
|
|
35052
35714
|
const file = sessionStateFile2(workspaceRoot3, sessionKey);
|
|
35053
35715
|
let prev = null;
|
|
35054
35716
|
try {
|
|
35055
|
-
prev = parseRecord(
|
|
35717
|
+
prev = parseRecord(fs88.readFileSync(file, "utf-8"));
|
|
35056
35718
|
} catch {
|
|
35057
35719
|
}
|
|
35058
35720
|
let version;
|
|
@@ -35068,27 +35730,34 @@ function markRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal, detectors) {
|
|
|
35068
35730
|
detectors,
|
|
35069
35731
|
turnOrdinal,
|
|
35070
35732
|
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35071
|
-
version
|
|
35733
|
+
version,
|
|
35734
|
+
promptId
|
|
35072
35735
|
})
|
|
35073
35736
|
);
|
|
35074
35737
|
} catch {
|
|
35075
35738
|
}
|
|
35076
35739
|
}
|
|
35077
35740
|
function readTranscriptTail(transcriptPath, opts = {}) {
|
|
35078
|
-
const empty = {
|
|
35741
|
+
const empty = {
|
|
35742
|
+
lastAssistant: "",
|
|
35743
|
+
turnOrdinal: 0,
|
|
35744
|
+
toolCalls: [],
|
|
35745
|
+
assistantTurnTexts: []
|
|
35746
|
+
};
|
|
35079
35747
|
if (!transcriptPath || !isSafeTranscriptPath(transcriptPath, opts)) return empty;
|
|
35080
35748
|
let lines;
|
|
35081
35749
|
try {
|
|
35082
|
-
if (opts.maxBytes !== void 0 &&
|
|
35750
|
+
if (opts.maxBytes !== void 0 && fs88.statSync(transcriptPath).size > opts.maxBytes) {
|
|
35083
35751
|
return empty;
|
|
35084
35752
|
}
|
|
35085
|
-
lines =
|
|
35753
|
+
lines = fs88.readFileSync(transcriptPath, "utf-8").split("\n");
|
|
35086
35754
|
} catch {
|
|
35087
35755
|
return empty;
|
|
35088
35756
|
}
|
|
35089
35757
|
let lastAssistant = "";
|
|
35090
35758
|
let turnOrdinal = 0;
|
|
35091
35759
|
let toolCalls = [];
|
|
35760
|
+
let assistantTurnTexts = [];
|
|
35092
35761
|
for (const rawLine of lines) {
|
|
35093
35762
|
const line = rawLine.trim();
|
|
35094
35763
|
if (!line) continue;
|
|
@@ -35107,20 +35776,27 @@ function readTranscriptTail(transcriptPath, opts = {}) {
|
|
|
35107
35776
|
if (typeof msg !== "object" || msg === null || Array.isArray(msg)) continue;
|
|
35108
35777
|
const content = msg["content"];
|
|
35109
35778
|
if (role === "assistant") {
|
|
35110
|
-
toolCalls.push(...
|
|
35779
|
+
toolCalls.push(...extractToolCalls(content));
|
|
35111
35780
|
}
|
|
35112
35781
|
const text = _messageText(content);
|
|
35113
35782
|
if (text === null) continue;
|
|
35114
35783
|
if (role === "assistant") {
|
|
35115
35784
|
lastAssistant = text;
|
|
35785
|
+
assistantTurnTexts.push(text);
|
|
35116
35786
|
} else if (!isSyntheticPrompt(text)) {
|
|
35117
35787
|
turnOrdinal += 1;
|
|
35118
35788
|
toolCalls = [];
|
|
35789
|
+
assistantTurnTexts = [];
|
|
35119
35790
|
}
|
|
35120
35791
|
}
|
|
35121
|
-
return {
|
|
35792
|
+
return {
|
|
35793
|
+
lastAssistant: lastAssistant.trim(),
|
|
35794
|
+
turnOrdinal,
|
|
35795
|
+
toolCalls,
|
|
35796
|
+
assistantTurnTexts
|
|
35797
|
+
};
|
|
35122
35798
|
}
|
|
35123
|
-
function
|
|
35799
|
+
function extractToolCalls(content) {
|
|
35124
35800
|
if (!Array.isArray(content)) return [];
|
|
35125
35801
|
const out = [];
|
|
35126
35802
|
for (const blk of content) {
|
|
@@ -35158,7 +35834,7 @@ function _messageText(content) {
|
|
|
35158
35834
|
function str8(v) {
|
|
35159
35835
|
return typeof v === "string" ? v : "";
|
|
35160
35836
|
}
|
|
35161
|
-
function
|
|
35837
|
+
function main58() {
|
|
35162
35838
|
let envelope;
|
|
35163
35839
|
let payload;
|
|
35164
35840
|
try {
|
|
@@ -35176,10 +35852,19 @@ function main56() {
|
|
|
35176
35852
|
const transcriptPath = str8(
|
|
35177
35853
|
payload["transcript_path"] ?? payload["transcriptPath"]
|
|
35178
35854
|
);
|
|
35179
|
-
const { lastAssistant, turnOrdinal, toolCalls } = readTranscriptTail(
|
|
35180
|
-
|
|
35181
|
-
|
|
35855
|
+
const { lastAssistant, turnOrdinal, toolCalls, assistantTurnTexts } = readTranscriptTail(
|
|
35856
|
+
transcriptPath,
|
|
35857
|
+
{ maxBytes: TRANSCRIPT_READ_MAX_BYTES }
|
|
35858
|
+
);
|
|
35182
35859
|
if (!lastAssistant) return EXIT_ALLOW27;
|
|
35860
|
+
const payloadClosing = str8(
|
|
35861
|
+
payload["last_assistant_message"] ?? payload["lastAssistantMessage"]
|
|
35862
|
+
);
|
|
35863
|
+
const closingFromPayload = payloadClosing !== "" && !assistantTurnTexts.includes(payloadClosing);
|
|
35864
|
+
const turnTexts = closingFromPayload ? [...assistantTurnTexts, payloadClosing] : assistantTurnTexts;
|
|
35865
|
+
const promptId = str8(
|
|
35866
|
+
payload["prompt_id"] ?? payload["promptId"]
|
|
35867
|
+
);
|
|
35183
35868
|
const rawSessionId = str8(envelope["session_id"]) || "";
|
|
35184
35869
|
const sessionKey = deriveSessionKey(rawSessionId || "unknown-session");
|
|
35185
35870
|
if (alreadyRefusedTurn(workspaceRoot3, sessionKey, turnOrdinal)) return EXIT_ALLOW27;
|
|
@@ -35201,7 +35886,23 @@ function main56() {
|
|
|
35201
35886
|
// gating is where the comment above says gating belongs — inside the
|
|
35202
35887
|
// detector: no CI observed, or a settled read, or no completion claim
|
|
35203
35888
|
// ⇒ no finding.
|
|
35204
|
-
dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot3, rawSessionId))
|
|
35889
|
+
dispatchOpen ? null : detectCompletionClaim(lastAssistant, readCiSettled(workspaceRoot3, rawSessionId)),
|
|
35890
|
+
// Detector E is UNCONDITIONAL, and that is the opposite choice from A
|
|
35891
|
+
// and D one line above rather than an oversight. An open dispatch
|
|
35892
|
+
// excuses a promissory closing because the work is genuinely still
|
|
35893
|
+
// running; it excuses nothing about a question the user was already
|
|
35894
|
+
// asked. Worse: a dispatch — or the `end-review-nudge` stop concern
|
|
35895
|
+
// that produced the measured failure — IS the continuation that drops
|
|
35896
|
+
// the decision, so narrowing E the same way would silence it in exactly
|
|
35897
|
+
// the case it exists for.
|
|
35898
|
+
detectDroppedDecision(turnTexts, closingFromPayload),
|
|
35899
|
+
// Detector F takes the OTHER side of that same question, and the two
|
|
35900
|
+
// sitting adjacent is the clearest place to say why. E fires on a
|
|
35901
|
+
// question already asked, which an open dispatch cannot excuse. F fires
|
|
35902
|
+
// on a completion CLAIM, and a turn waiting on a subagent has not
|
|
35903
|
+
// finished — so its closing is not the claim F is about. Same slot,
|
|
35904
|
+
// opposite trigger, opposite treatment of `dispatchOpen`.
|
|
35905
|
+
dispatchOpen ? null : detectUntestedChange(lastAssistant, toolCalls)
|
|
35205
35906
|
]) {
|
|
35206
35907
|
if (f) findings.push(f);
|
|
35207
35908
|
}
|
|
@@ -35210,7 +35911,8 @@ function main56() {
|
|
|
35210
35911
|
workspaceRoot3,
|
|
35211
35912
|
sessionKey,
|
|
35212
35913
|
turnOrdinal,
|
|
35213
|
-
findings.map((f) => f.detector)
|
|
35914
|
+
findings.map((f) => f.detector),
|
|
35915
|
+
promptId
|
|
35214
35916
|
);
|
|
35215
35917
|
const lines = findings.map(
|
|
35216
35918
|
(f) => ` \xB7 ${f.detector}: ${f.reason}
|
|
@@ -35219,41 +35921,41 @@ function main56() {
|
|
|
35219
35921
|
process.stderr.write(
|
|
35220
35922
|
`turn-end-gate: REFUSED \u2014 this turn is not finished.
|
|
35221
35923
|
${lines.join("\n")}
|
|
35222
|
-
Do the promised work now, correct the language, run the verification the edit needs,
|
|
35924
|
+
Do the promised work now, correct the language, run the verification the edit needs, read the CI verdict before claiming it, or re-present the options block this turn dropped \u2014 then end the turn.
|
|
35223
35925
|
This turn will not be refused a second time.
|
|
35224
35926
|
`
|
|
35225
35927
|
);
|
|
35226
35928
|
return EXIT_BLOCK3;
|
|
35227
35929
|
}
|
|
35228
|
-
function
|
|
35930
|
+
function _isCliEntry42() {
|
|
35229
35931
|
if (true) {
|
|
35230
35932
|
return false;
|
|
35231
35933
|
}
|
|
35232
35934
|
if (process.argv[1] === void 0) {
|
|
35233
35935
|
return false;
|
|
35234
35936
|
}
|
|
35235
|
-
const argvUrl =
|
|
35937
|
+
const argvUrl = pathToFileURL52(path90.resolve(process.argv[1])).href;
|
|
35236
35938
|
if (import.meta.url === argvUrl) {
|
|
35237
35939
|
return true;
|
|
35238
35940
|
}
|
|
35239
35941
|
try {
|
|
35240
|
-
const here =
|
|
35241
|
-
const argv =
|
|
35942
|
+
const here = fs88.realpathSync(fileURLToPath61(import.meta.url));
|
|
35943
|
+
const argv = fs88.realpathSync(path90.resolve(process.argv[1]));
|
|
35242
35944
|
return here === argv;
|
|
35243
35945
|
} catch {
|
|
35244
35946
|
return false;
|
|
35245
35947
|
}
|
|
35246
35948
|
}
|
|
35247
|
-
if (
|
|
35248
|
-
process.exit(
|
|
35949
|
+
if (_isCliEntry42()) {
|
|
35950
|
+
process.exit(main58());
|
|
35249
35951
|
}
|
|
35250
35952
|
|
|
35251
35953
|
// src/scripts/hooks/edit_shape_hook.ts
|
|
35252
|
-
import { spawnSync as
|
|
35954
|
+
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
35253
35955
|
import * as crypto11 from "node:crypto";
|
|
35254
|
-
import * as
|
|
35255
|
-
import * as
|
|
35256
|
-
import { fileURLToPath as
|
|
35956
|
+
import * as fs89 from "node:fs";
|
|
35957
|
+
import * as path91 from "node:path";
|
|
35958
|
+
import { fileURLToPath as fileURLToPath62, pathToFileURL as pathToFileURL53 } from "node:url";
|
|
35257
35959
|
var EXIT_ALLOW28 = 0;
|
|
35258
35960
|
var EXIT_WARN16 = 2;
|
|
35259
35961
|
var MIN_FILE_LINES = 50;
|
|
@@ -35293,7 +35995,7 @@ function parseNumstatLines(raw) {
|
|
|
35293
35995
|
}
|
|
35294
35996
|
function effectiveDiffLines(cwd, relPath) {
|
|
35295
35997
|
try {
|
|
35296
|
-
const r =
|
|
35998
|
+
const r = spawnSync8("git", ["diff", "HEAD", "--numstat", "--", relPath], {
|
|
35297
35999
|
cwd,
|
|
35298
36000
|
encoding: "utf8",
|
|
35299
36001
|
maxBuffer: 16 * 1024 * 1024
|
|
@@ -35306,7 +36008,7 @@ function effectiveDiffLines(cwd, relPath) {
|
|
|
35306
36008
|
}
|
|
35307
36009
|
function fileLineCount(absPath) {
|
|
35308
36010
|
try {
|
|
35309
|
-
const text =
|
|
36011
|
+
const text = fs89.readFileSync(absPath, "utf8");
|
|
35310
36012
|
if (text.length === 0) return 0;
|
|
35311
36013
|
return text.split("\n").length - (text.endsWith("\n") ? 1 : 0);
|
|
35312
36014
|
} catch {
|
|
@@ -35323,11 +36025,11 @@ function deriveSessionKey3(envelope, payload) {
|
|
|
35323
36025
|
return crypto11.createHash("sha256").update(material).digest("hex");
|
|
35324
36026
|
}
|
|
35325
36027
|
function sessionStateFile3(workspaceRoot3, sessionKey) {
|
|
35326
|
-
return
|
|
36028
|
+
return path91.join(workspaceRoot3, "agents", "runtime", "state", "edit-shape", `${sessionKey}.json`);
|
|
35327
36029
|
}
|
|
35328
36030
|
function hasFiredThisSession2(workspaceRoot3, sessionKey) {
|
|
35329
36031
|
try {
|
|
35330
|
-
return
|
|
36032
|
+
return fs89.existsSync(sessionStateFile3(workspaceRoot3, sessionKey));
|
|
35331
36033
|
} catch {
|
|
35332
36034
|
return false;
|
|
35333
36035
|
}
|
|
@@ -35348,7 +36050,7 @@ function extractFilePath2(payload) {
|
|
|
35348
36050
|
if (!isObject14(ti)) return "";
|
|
35349
36051
|
return str9(ti["file_path"] ?? ti["path"] ?? ti["filePath"]);
|
|
35350
36052
|
}
|
|
35351
|
-
function
|
|
36053
|
+
function main59() {
|
|
35352
36054
|
try {
|
|
35353
36055
|
const [envelope, payload] = unwrap(readHookStdin(), "claude");
|
|
35354
36056
|
const event = str9(envelope["event"]);
|
|
@@ -35358,8 +36060,8 @@ function main57() {
|
|
|
35358
36060
|
const filePath = extractFilePath2(payload);
|
|
35359
36061
|
if (!filePath) return EXIT_ALLOW28;
|
|
35360
36062
|
const workspaceRoot3 = str9(envelope["workspace_root"]).trim() || process.cwd();
|
|
35361
|
-
const absPath =
|
|
35362
|
-
const relPath =
|
|
36063
|
+
const absPath = path91.isAbsolute(filePath) ? filePath : path91.resolve(workspaceRoot3, filePath);
|
|
36064
|
+
const relPath = path91.relative(workspaceRoot3, absPath);
|
|
35363
36065
|
if (isExemptPath(relPath) || isExemptPath(absPath)) return EXIT_ALLOW28;
|
|
35364
36066
|
const fileLines = fileLineCount(absPath);
|
|
35365
36067
|
if (fileLines < MIN_FILE_LINES) return EXIT_ALLOW28;
|
|
@@ -35382,54 +36084,54 @@ function main57() {
|
|
|
35382
36084
|
return EXIT_ALLOW28;
|
|
35383
36085
|
}
|
|
35384
36086
|
}
|
|
35385
|
-
function
|
|
36087
|
+
function _isCliEntry43() {
|
|
35386
36088
|
if (true) {
|
|
35387
36089
|
return false;
|
|
35388
36090
|
}
|
|
35389
36091
|
if (process.argv[1] === void 0) {
|
|
35390
36092
|
return false;
|
|
35391
36093
|
}
|
|
35392
|
-
const argvUrl =
|
|
36094
|
+
const argvUrl = pathToFileURL53(path91.resolve(process.argv[1])).href;
|
|
35393
36095
|
if (import.meta.url === argvUrl) {
|
|
35394
36096
|
return true;
|
|
35395
36097
|
}
|
|
35396
36098
|
try {
|
|
35397
|
-
const here =
|
|
35398
|
-
const argv =
|
|
36099
|
+
const here = fs89.realpathSync(fileURLToPath62(import.meta.url));
|
|
36100
|
+
const argv = fs89.realpathSync(path91.resolve(process.argv[1]));
|
|
35399
36101
|
return here === argv;
|
|
35400
36102
|
} catch {
|
|
35401
36103
|
return false;
|
|
35402
36104
|
}
|
|
35403
36105
|
}
|
|
35404
|
-
if (
|
|
35405
|
-
process.exit(
|
|
36106
|
+
if (_isCliEntry43()) {
|
|
36107
|
+
process.exit(main59());
|
|
35406
36108
|
}
|
|
35407
36109
|
|
|
35408
36110
|
// src/scripts/hooks/comment_discipline_hook.ts
|
|
35409
|
-
import * as
|
|
35410
|
-
import * as
|
|
35411
|
-
import { fileURLToPath as
|
|
36111
|
+
import * as fs91 from "node:fs";
|
|
36112
|
+
import * as path94 from "node:path";
|
|
36113
|
+
import { fileURLToPath as fileURLToPath64, pathToFileURL as pathToFileURL54 } from "node:url";
|
|
35412
36114
|
|
|
35413
36115
|
// src/scripts/lint_code_comments.ts
|
|
35414
|
-
import { spawnSync as
|
|
35415
|
-
import * as
|
|
36116
|
+
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
36117
|
+
import * as fs90 from "node:fs";
|
|
35416
36118
|
import * as os12 from "node:os";
|
|
35417
|
-
import * as
|
|
36119
|
+
import * as path93 from "node:path";
|
|
35418
36120
|
import process15 from "node:process";
|
|
35419
|
-
import { fileURLToPath as
|
|
36121
|
+
import { fileURLToPath as fileURLToPath63 } from "node:url";
|
|
35420
36122
|
|
|
35421
36123
|
// src/scripts/_lib/gate_self_test.ts
|
|
35422
|
-
import { spawnSync as
|
|
35423
|
-
import * as
|
|
36124
|
+
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
36125
|
+
import * as path92 from "node:path";
|
|
35424
36126
|
import process14 from "node:process";
|
|
35425
36127
|
function runGateCli(repoRoot, scriptRelPath, args, cwd) {
|
|
35426
|
-
const tsx =
|
|
36128
|
+
const tsx = path92.join(
|
|
35427
36129
|
repoRoot,
|
|
35428
36130
|
"node_modules",
|
|
35429
36131
|
".bin",
|
|
35430
36132
|
process14.platform === "win32" ? "tsx.cmd" : "tsx"
|
|
35431
36133
|
);
|
|
35432
|
-
const res =
|
|
36134
|
+
const res = spawnSync9(tsx, [path92.join(repoRoot, scriptRelPath), ...args], {
|
|
35433
36135
|
cwd,
|
|
35434
36136
|
encoding: "utf-8",
|
|
35435
36137
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -35481,7 +36183,7 @@ ${opts.gate} --self-test: ${String(opts.cases.length - failed)}/${String(opts.ca
|
|
|
35481
36183
|
}
|
|
35482
36184
|
|
|
35483
36185
|
// src/scripts/lint_code_comments.ts
|
|
35484
|
-
var
|
|
36186
|
+
var _HERE13 = fileURLToPath63(import.meta.url);
|
|
35485
36187
|
var SCANNED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
35486
36188
|
".ts",
|
|
35487
36189
|
".tsx",
|
|
@@ -35741,20 +36443,20 @@ function scanText2(file, text) {
|
|
|
35741
36443
|
function isScannable(rel) {
|
|
35742
36444
|
if (SKIP_SEGMENTS.some((s) => rel.includes(s))) return false;
|
|
35743
36445
|
if (rel.endsWith(".d.ts")) return false;
|
|
35744
|
-
return SCANNED_EXTENSIONS.has(
|
|
36446
|
+
return SCANNED_EXTENSIONS.has(path93.extname(rel));
|
|
35745
36447
|
}
|
|
35746
36448
|
function changedFiles(root, base) {
|
|
35747
|
-
const r =
|
|
36449
|
+
const r = spawnSync10("git", ["diff", "--name-only", "--diff-filter=ACMR", `${base}...HEAD`], {
|
|
35748
36450
|
cwd: root,
|
|
35749
36451
|
encoding: "utf-8"
|
|
35750
36452
|
});
|
|
35751
36453
|
const tracked = r.status === 0 ? r.stdout.split("\n") : [];
|
|
35752
|
-
const u =
|
|
36454
|
+
const u = spawnSync10("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
35753
36455
|
cwd: root,
|
|
35754
36456
|
encoding: "utf-8"
|
|
35755
36457
|
});
|
|
35756
36458
|
const untracked = u.status === 0 ? u.stdout.split("\n") : [];
|
|
35757
|
-
const m =
|
|
36459
|
+
const m = spawnSync10("git", ["diff", "--name-only", "--diff-filter=ACMR"], {
|
|
35758
36460
|
cwd: root,
|
|
35759
36461
|
encoding: "utf-8"
|
|
35760
36462
|
});
|
|
@@ -35763,7 +36465,7 @@ function changedFiles(root, base) {
|
|
|
35763
36465
|
}
|
|
35764
36466
|
function addedLineMap(root, base) {
|
|
35765
36467
|
const out = /* @__PURE__ */ new Map();
|
|
35766
|
-
const u =
|
|
36468
|
+
const u = spawnSync10("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
35767
36469
|
cwd: root,
|
|
35768
36470
|
encoding: "utf-8"
|
|
35769
36471
|
});
|
|
@@ -35776,7 +36478,7 @@ function addedLineMap(root, base) {
|
|
|
35776
36478
|
["diff", "--unified=0", "--diff-filter=ACMR", `${base}...HEAD`],
|
|
35777
36479
|
["diff", "--unified=0", "--diff-filter=ACMR"]
|
|
35778
36480
|
]) {
|
|
35779
|
-
const r =
|
|
36481
|
+
const r = spawnSync10("git", argv, { cwd: root, encoding: "utf-8" });
|
|
35780
36482
|
if (r.status !== 0) continue;
|
|
35781
36483
|
mergeAddedLines(out, parseAddedLines(r.stdout));
|
|
35782
36484
|
}
|
|
@@ -35919,11 +36621,11 @@ var COMMENT_CASES = [
|
|
|
35919
36621
|
}
|
|
35920
36622
|
];
|
|
35921
36623
|
function selfTest2() {
|
|
35922
|
-
const repoRoot =
|
|
35923
|
-
const dir =
|
|
36624
|
+
const repoRoot = path93.resolve(path93.dirname(_HERE13), "..", "..");
|
|
36625
|
+
const dir = fs90.mkdtempSync(path93.join(os12.tmpdir(), "lcc-selftest-"));
|
|
35924
36626
|
const exercise = (testCase, index) => {
|
|
35925
|
-
const file =
|
|
35926
|
-
|
|
36627
|
+
const file = path93.join(dir, `case-${String(index)}.ts`);
|
|
36628
|
+
fs90.writeFileSync(file, testCase.source, "utf-8");
|
|
35927
36629
|
return runGateCli(repoRoot, "src/scripts/lint_code_comments.ts", ["--paths", file], dir);
|
|
35928
36630
|
};
|
|
35929
36631
|
try {
|
|
@@ -35938,7 +36640,7 @@ function selfTest2() {
|
|
|
35938
36640
|
}))
|
|
35939
36641
|
});
|
|
35940
36642
|
} finally {
|
|
35941
|
-
|
|
36643
|
+
fs90.rmSync(dir, { recursive: true, force: true });
|
|
35942
36644
|
}
|
|
35943
36645
|
}
|
|
35944
36646
|
var HELP = `usage: lint_code_comments [--base <ref>] [--root <dir>] [--paths <f> \u2026] [--report]
|
|
@@ -35953,7 +36655,7 @@ Classes: de-comment \xB7 report-comment \xB7 provenance-comment
|
|
|
35953
36655
|
Escape: code-comment-allow <class|*> -- <reason> (per line)
|
|
35954
36656
|
code-comment-allow-file -- <reason> (first 2000 chars)
|
|
35955
36657
|
`;
|
|
35956
|
-
function
|
|
36658
|
+
function main60(argv) {
|
|
35957
36659
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
35958
36660
|
process15.stdout.write(HELP);
|
|
35959
36661
|
return 0;
|
|
@@ -35966,7 +36668,7 @@ function main58(argv) {
|
|
|
35966
36668
|
return selfTest2();
|
|
35967
36669
|
}
|
|
35968
36670
|
let base = "origin/main";
|
|
35969
|
-
let root =
|
|
36671
|
+
let root = path93.resolve(path93.dirname(_HERE13), "..", "..");
|
|
35970
36672
|
let reportOnly = false;
|
|
35971
36673
|
const explicit = [];
|
|
35972
36674
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -35977,7 +36679,7 @@ function main58(argv) {
|
|
|
35977
36679
|
} else if (a === "--base") {
|
|
35978
36680
|
base = argv[++i] ?? "";
|
|
35979
36681
|
} else if (a === "--root") {
|
|
35980
|
-
root =
|
|
36682
|
+
root = path93.resolve(argv[++i] ?? ".");
|
|
35981
36683
|
} else if (a === "--report") {
|
|
35982
36684
|
reportOnly = true;
|
|
35983
36685
|
} else if (a === "--paths") {
|
|
@@ -35996,10 +36698,10 @@ ${HELP}`);
|
|
|
35996
36698
|
const added = explicit.length > 0 ? null : addedLineMap(root, base);
|
|
35997
36699
|
const findings = [];
|
|
35998
36700
|
for (const rel of candidates) {
|
|
35999
|
-
const abs =
|
|
36701
|
+
const abs = path93.isAbsolute(rel) ? rel : path93.join(root, rel);
|
|
36000
36702
|
let text;
|
|
36001
36703
|
try {
|
|
36002
|
-
text =
|
|
36704
|
+
text = fs90.readFileSync(abs, "utf-8");
|
|
36003
36705
|
} catch {
|
|
36004
36706
|
continue;
|
|
36005
36707
|
}
|
|
@@ -36060,12 +36762,12 @@ var _isMain6 = (() => {
|
|
|
36060
36762
|
const entry = process15.argv[1];
|
|
36061
36763
|
if (!entry) return false;
|
|
36062
36764
|
try {
|
|
36063
|
-
return
|
|
36765
|
+
return fs90.realpathSync(entry) === fs90.realpathSync(_HERE13);
|
|
36064
36766
|
} catch {
|
|
36065
36767
|
return false;
|
|
36066
36768
|
}
|
|
36067
36769
|
})();
|
|
36068
|
-
if (_isMain6) process15.exit(
|
|
36770
|
+
if (_isMain6) process15.exit(main60(process15.argv.slice(2)));
|
|
36069
36771
|
|
|
36070
36772
|
// src/scripts/hooks/comment_discipline_hook.ts
|
|
36071
36773
|
var EXIT_ALLOW29 = 0;
|
|
@@ -36092,7 +36794,7 @@ function buildAdvisoryLine3(file, findings) {
|
|
|
36092
36794
|
const more = findings.length > MAX_REPORTED ? `, +${findings.length - MAX_REPORTED} more` : "";
|
|
36093
36795
|
return `comment-discipline: the text just written to ${file} carries ${summary} \u2014 ${named}${more}. A comment states a WHY or a constraint the code cannot show, in English; evidence for a roadmap step belongs in that roadmap, not in a second copy in the source. Rewrite or delete those lines now, before the next write \u2014 \`lint_code_comments\` refuses them at the gate.`;
|
|
36094
36796
|
}
|
|
36095
|
-
function
|
|
36797
|
+
function main61() {
|
|
36096
36798
|
try {
|
|
36097
36799
|
const [envelope, payload] = unwrap(readHookStdin(), "claude");
|
|
36098
36800
|
const event = str10(envelope["event"]);
|
|
@@ -36108,9 +36810,9 @@ function main59() {
|
|
|
36108
36810
|
const text = writtenText(toolName2, ti);
|
|
36109
36811
|
if (!text) return EXIT_ALLOW29;
|
|
36110
36812
|
const workspaceRoot3 = str10(envelope["workspace_root"]).trim() || process.cwd();
|
|
36111
|
-
const abs =
|
|
36112
|
-
const rel =
|
|
36113
|
-
const shown = rel.startsWith("..") ?
|
|
36813
|
+
const abs = path94.isAbsolute(filePath) ? filePath : path94.resolve(workspaceRoot3, filePath);
|
|
36814
|
+
const rel = path94.relative(workspaceRoot3, abs);
|
|
36815
|
+
const shown = rel.startsWith("..") ? path94.basename(abs) : rel;
|
|
36114
36816
|
const findings = scanText2(shown, text);
|
|
36115
36817
|
if (findings.length === 0) return EXIT_ALLOW29;
|
|
36116
36818
|
process.stdout.write(
|
|
@@ -36126,24 +36828,24 @@ function main59() {
|
|
|
36126
36828
|
return EXIT_ALLOW29;
|
|
36127
36829
|
}
|
|
36128
36830
|
}
|
|
36129
|
-
function
|
|
36831
|
+
function _isCliEntry44() {
|
|
36130
36832
|
if (true) return false;
|
|
36131
36833
|
if (process.argv[1] === void 0) return false;
|
|
36132
|
-
const argvUrl =
|
|
36834
|
+
const argvUrl = pathToFileURL54(path94.resolve(process.argv[1])).href;
|
|
36133
36835
|
if (import.meta.url === argvUrl) return true;
|
|
36134
36836
|
try {
|
|
36135
|
-
return
|
|
36837
|
+
return fs91.realpathSync(fileURLToPath64(import.meta.url)) === fs91.realpathSync(path94.resolve(process.argv[1]));
|
|
36136
36838
|
} catch {
|
|
36137
36839
|
return false;
|
|
36138
36840
|
}
|
|
36139
36841
|
}
|
|
36140
|
-
if (
|
|
36842
|
+
if (_isCliEntry44()) process.exit(main61());
|
|
36141
36843
|
|
|
36142
36844
|
// src/scripts/hooks/reread_guard_hook.ts
|
|
36143
36845
|
import * as crypto12 from "node:crypto";
|
|
36144
|
-
import * as
|
|
36145
|
-
import * as
|
|
36146
|
-
import { fileURLToPath as
|
|
36846
|
+
import * as fs92 from "node:fs";
|
|
36847
|
+
import * as path95 from "node:path";
|
|
36848
|
+
import { fileURLToPath as fileURLToPath65, pathToFileURL as pathToFileURL55 } from "node:url";
|
|
36147
36849
|
var EXIT_ALLOW30 = 0;
|
|
36148
36850
|
var EXIT_WARN18 = 2;
|
|
36149
36851
|
var EXEMPT_PATH_PATTERNS2 = [
|
|
@@ -36179,11 +36881,11 @@ function deriveSessionKey4(envelope, payload) {
|
|
|
36179
36881
|
return crypto12.createHash("sha256").update(material).digest("hex");
|
|
36180
36882
|
}
|
|
36181
36883
|
function ledgerFile(workspaceRoot3, sessionKey) {
|
|
36182
|
-
return
|
|
36884
|
+
return path95.join(workspaceRoot3, "agents", "runtime", "state", "reread-guard", `${sessionKey}.json`);
|
|
36183
36885
|
}
|
|
36184
36886
|
function readLedger(workspaceRoot3, sessionKey) {
|
|
36185
36887
|
try {
|
|
36186
|
-
const parsed = JSON.parse(
|
|
36888
|
+
const parsed = JSON.parse(fs92.readFileSync(ledgerFile(workspaceRoot3, sessionKey), "utf8"));
|
|
36187
36889
|
if (!isObject16(parsed)) return emptyLedger();
|
|
36188
36890
|
return {
|
|
36189
36891
|
reads: isObject16(parsed["reads"]) ? parsed["reads"] : {},
|
|
@@ -36224,7 +36926,7 @@ function buildDuplicateReadLine(relPath, earlierTs) {
|
|
|
36224
36926
|
function buildPostEditReadLine(relPath) {
|
|
36225
36927
|
return `re-read guard: this session just edited ${relPath} \u2014 a full-file re-read re-pays for content you already have; a ranged Read (offset/limit) over the edited hunk is enough to verify the change.`;
|
|
36226
36928
|
}
|
|
36227
|
-
function
|
|
36929
|
+
function main62() {
|
|
36228
36930
|
try {
|
|
36229
36931
|
const [envelope, payload] = unwrap(readHookStdin(), "claude");
|
|
36230
36932
|
const event = str11(envelope["event"]);
|
|
@@ -36237,8 +36939,8 @@ function main60() {
|
|
|
36237
36939
|
const filePath = extractFilePath3(toolInput);
|
|
36238
36940
|
if (!filePath) return EXIT_ALLOW30;
|
|
36239
36941
|
const workspaceRoot3 = str11(envelope["workspace_root"]).trim() || process.cwd();
|
|
36240
|
-
const absPath =
|
|
36241
|
-
const relPath =
|
|
36942
|
+
const absPath = path95.isAbsolute(filePath) ? filePath : path95.resolve(workspaceRoot3, filePath);
|
|
36943
|
+
const relPath = path95.relative(workspaceRoot3, absPath);
|
|
36242
36944
|
if (isExemptPath2(relPath) || isExemptPath2(absPath)) return EXIT_ALLOW30;
|
|
36243
36945
|
const sessionKey = deriveSessionKey4(envelope, payload);
|
|
36244
36946
|
const ledger = readLedger(workspaceRoot3, sessionKey);
|
|
@@ -36254,7 +36956,7 @@ function main60() {
|
|
|
36254
36956
|
let mtime;
|
|
36255
36957
|
let size;
|
|
36256
36958
|
try {
|
|
36257
|
-
const st =
|
|
36959
|
+
const st = fs92.statSync(absPath);
|
|
36258
36960
|
mtime = st.mtimeMs;
|
|
36259
36961
|
size = st.size;
|
|
36260
36962
|
} catch {
|
|
@@ -36287,34 +36989,34 @@ function main60() {
|
|
|
36287
36989
|
return EXIT_ALLOW30;
|
|
36288
36990
|
}
|
|
36289
36991
|
}
|
|
36290
|
-
function
|
|
36992
|
+
function _isCliEntry45() {
|
|
36291
36993
|
if (true) {
|
|
36292
36994
|
return false;
|
|
36293
36995
|
}
|
|
36294
36996
|
if (process.argv[1] === void 0) {
|
|
36295
36997
|
return false;
|
|
36296
36998
|
}
|
|
36297
|
-
const argvUrl =
|
|
36999
|
+
const argvUrl = pathToFileURL55(path95.resolve(process.argv[1])).href;
|
|
36298
37000
|
if (import.meta.url === argvUrl) {
|
|
36299
37001
|
return true;
|
|
36300
37002
|
}
|
|
36301
37003
|
try {
|
|
36302
|
-
const here =
|
|
36303
|
-
const argv =
|
|
37004
|
+
const here = fs92.realpathSync(fileURLToPath65(import.meta.url));
|
|
37005
|
+
const argv = fs92.realpathSync(path95.resolve(process.argv[1]));
|
|
36304
37006
|
return here === argv;
|
|
36305
37007
|
} catch {
|
|
36306
37008
|
return false;
|
|
36307
37009
|
}
|
|
36308
37010
|
}
|
|
36309
|
-
if (
|
|
36310
|
-
process.exit(
|
|
37011
|
+
if (_isCliEntry45()) {
|
|
37012
|
+
process.exit(main62());
|
|
36311
37013
|
}
|
|
36312
37014
|
|
|
36313
37015
|
// src/scripts/hooks/session_eol_hook.ts
|
|
36314
|
-
import * as
|
|
36315
|
-
import * as
|
|
37016
|
+
import * as fs99 from "node:fs";
|
|
37017
|
+
import * as path102 from "node:path";
|
|
36316
37018
|
import process16 from "node:process";
|
|
36317
|
-
import { fileURLToPath as
|
|
37019
|
+
import { fileURLToPath as fileURLToPath66, pathToFileURL as pathToFileURL56 } from "node:url";
|
|
36318
37020
|
|
|
36319
37021
|
// src/config/recycle-threshold-budget.json
|
|
36320
37022
|
var recycle_threshold_budget_default = {
|
|
@@ -36332,13 +37034,13 @@ var recycle_threshold_budget_default = {
|
|
|
36332
37034
|
|
|
36333
37035
|
// src/scripts/_lib/session_eol.ts
|
|
36334
37036
|
import * as crypto13 from "node:crypto";
|
|
36335
|
-
import * as
|
|
36336
|
-
import * as
|
|
37037
|
+
import * as fs93 from "node:fs";
|
|
37038
|
+
import * as path97 from "node:path";
|
|
36337
37039
|
|
|
36338
37040
|
// src/scripts/_lib/cc_transcript.ts
|
|
36339
|
-
import * as
|
|
37041
|
+
import * as path96 from "node:path";
|
|
36340
37042
|
import { homedir as homedir8 } from "node:os";
|
|
36341
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
37043
|
+
var DEFAULT_PROJECTS_ROOT = path96.join(homedir8(), ".claude", "projects");
|
|
36342
37044
|
function billableInputTokens(u) {
|
|
36343
37045
|
return u.input_tokens + u.cache_read_input_tokens + u.cache_creation_input_tokens;
|
|
36344
37046
|
}
|
|
@@ -36447,10 +37149,10 @@ function scanEolSlice(text, prior) {
|
|
|
36447
37149
|
return next;
|
|
36448
37150
|
}
|
|
36449
37151
|
function eolStateDir(workspaceRoot3) {
|
|
36450
|
-
return
|
|
37152
|
+
return path97.join(workspaceRoot3, "agents", "runtime", "state", "session-eol");
|
|
36451
37153
|
}
|
|
36452
37154
|
function eolStateFile(workspaceRoot3, sessionKey) {
|
|
36453
|
-
return
|
|
37155
|
+
return path97.join(eolStateDir(workspaceRoot3), `${sessionKey}.json`);
|
|
36454
37156
|
}
|
|
36455
37157
|
function eolSessionKey(raw) {
|
|
36456
37158
|
return crypto13.createHash("sha256").update(raw || "unknown-session").digest("hex");
|
|
@@ -36467,7 +37169,7 @@ function is_substantive(counters) {
|
|
|
36467
37169
|
}
|
|
36468
37170
|
function readNewCompleteLines(filePath, fromByte) {
|
|
36469
37171
|
try {
|
|
36470
|
-
const { size } =
|
|
37172
|
+
const { size } = fs93.statSync(filePath);
|
|
36471
37173
|
if (size < fromByte) {
|
|
36472
37174
|
return { text: "", nextOffset: 0, truncated: true };
|
|
36473
37175
|
}
|
|
@@ -36476,11 +37178,11 @@ function readNewCompleteLines(filePath, fromByte) {
|
|
|
36476
37178
|
}
|
|
36477
37179
|
const length = size - fromByte;
|
|
36478
37180
|
const buffer = Buffer.alloc(length);
|
|
36479
|
-
const fd =
|
|
37181
|
+
const fd = fs93.openSync(filePath, "r");
|
|
36480
37182
|
try {
|
|
36481
|
-
|
|
37183
|
+
fs93.readSync(fd, buffer, 0, length, fromByte);
|
|
36482
37184
|
} finally {
|
|
36483
|
-
|
|
37185
|
+
fs93.closeSync(fd);
|
|
36484
37186
|
}
|
|
36485
37187
|
const lastNewline = buffer.lastIndexOf(10);
|
|
36486
37188
|
if (lastNewline === -1) {
|
|
@@ -36497,23 +37199,23 @@ function readNewCompleteLines(filePath, fromByte) {
|
|
|
36497
37199
|
}
|
|
36498
37200
|
|
|
36499
37201
|
// src/scripts/_lib/context_observation.ts
|
|
36500
|
-
import * as
|
|
36501
|
-
import * as
|
|
37202
|
+
import * as fs95 from "node:fs";
|
|
37203
|
+
import * as path99 from "node:path";
|
|
36502
37204
|
|
|
36503
37205
|
// src/scripts/_lib/loop_guards.ts
|
|
36504
|
-
import * as
|
|
36505
|
-
import * as
|
|
37206
|
+
import * as fs94 from "node:fs";
|
|
37207
|
+
import * as path98 from "node:path";
|
|
36506
37208
|
function atomicWriteJson(file, value) {
|
|
36507
37209
|
const tmp = `${file}.${String(process.pid)}.tmp`;
|
|
36508
37210
|
try {
|
|
36509
|
-
|
|
36510
|
-
|
|
37211
|
+
fs94.mkdirSync(path98.dirname(file), { recursive: true });
|
|
37212
|
+
fs94.writeFileSync(tmp, `${JSON.stringify(value)}
|
|
36511
37213
|
`, "utf8");
|
|
36512
|
-
|
|
37214
|
+
fs94.renameSync(tmp, file);
|
|
36513
37215
|
return true;
|
|
36514
37216
|
} catch {
|
|
36515
37217
|
try {
|
|
36516
|
-
|
|
37218
|
+
fs94.unlinkSync(tmp);
|
|
36517
37219
|
} catch {
|
|
36518
37220
|
}
|
|
36519
37221
|
return false;
|
|
@@ -36559,7 +37261,7 @@ function stallSignal(history, window = 3) {
|
|
|
36559
37261
|
}
|
|
36560
37262
|
function readUnavailableDependency(transcriptPath) {
|
|
36561
37263
|
try {
|
|
36562
|
-
const raw =
|
|
37264
|
+
const raw = fs94.readFileSync(transcriptPath, "utf8");
|
|
36563
37265
|
return detectUnavailableDependency(raw.slice(-DEPENDENCY_SCAN_BYTES));
|
|
36564
37266
|
} catch {
|
|
36565
37267
|
return null;
|
|
@@ -36567,18 +37269,18 @@ function readUnavailableDependency(transcriptPath) {
|
|
|
36567
37269
|
}
|
|
36568
37270
|
|
|
36569
37271
|
// src/scripts/_lib/context_observation.ts
|
|
36570
|
-
var CONTEXT_OBSERVATION_REL =
|
|
37272
|
+
var CONTEXT_OBSERVATION_REL = path99.join(
|
|
36571
37273
|
"agents",
|
|
36572
37274
|
"runtime",
|
|
36573
37275
|
"state",
|
|
36574
37276
|
"context-observation.json"
|
|
36575
37277
|
);
|
|
36576
37278
|
function observationFile(repoRoot) {
|
|
36577
|
-
return
|
|
37279
|
+
return path99.join(repoRoot, CONTEXT_OBSERVATION_REL);
|
|
36578
37280
|
}
|
|
36579
37281
|
function readContextObservation(repoRoot) {
|
|
36580
37282
|
try {
|
|
36581
|
-
const parsed = JSON.parse(
|
|
37283
|
+
const parsed = JSON.parse(fs95.readFileSync(observationFile(repoRoot), "utf-8"));
|
|
36582
37284
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
36583
37285
|
const o = parsed;
|
|
36584
37286
|
if (typeof o["fingerprint"] !== "string" || o["fingerprint"] === "") return null;
|
|
@@ -36600,8 +37302,8 @@ function premiseMoved(claimed, observed) {
|
|
|
36600
37302
|
}
|
|
36601
37303
|
|
|
36602
37304
|
// src/scripts/_lib/run_checkpoint.ts
|
|
36603
|
-
import * as
|
|
36604
|
-
import * as
|
|
37305
|
+
import * as fs96 from "node:fs";
|
|
37306
|
+
import * as path100 from "node:path";
|
|
36605
37307
|
|
|
36606
37308
|
// src/scripts/_lib/roadmap_checkboxes.ts
|
|
36607
37309
|
var CHECKBOX_LINE = /^[ \t]*[-*][ \t]+\[([ xX~-])\][ \t]+(.*)$/;
|
|
@@ -36631,7 +37333,7 @@ function phaseLines(text) {
|
|
|
36631
37333
|
}
|
|
36632
37334
|
|
|
36633
37335
|
// src/scripts/_lib/run_checkpoint.ts
|
|
36634
|
-
var CHECKPOINT_DIR_REL =
|
|
37336
|
+
var CHECKPOINT_DIR_REL = path100.join("agents", "runtime", "state", "checkpoints");
|
|
36635
37337
|
function countRoadmap(text) {
|
|
36636
37338
|
const counts = { open: 0, done: 0, parked: 0, next: null };
|
|
36637
37339
|
for (const raw of phaseLines(text)) {
|
|
@@ -36652,34 +37354,34 @@ function countRoadmap(text) {
|
|
|
36652
37354
|
return counts;
|
|
36653
37355
|
}
|
|
36654
37356
|
function checkpointFile(repoRoot, runId) {
|
|
36655
|
-
return
|
|
37357
|
+
return path100.join(repoRoot, CHECKPOINT_DIR_REL, `${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
|
|
36656
37358
|
}
|
|
36657
37359
|
function roadmapPath(repoRoot, slug) {
|
|
36658
|
-
return
|
|
37360
|
+
return path100.join(repoRoot, "agents", "roadmaps", `${slug}.md`);
|
|
36659
37361
|
}
|
|
36660
37362
|
function readHead(repoRoot) {
|
|
36661
37363
|
try {
|
|
36662
|
-
let gitDir =
|
|
36663
|
-
if (
|
|
36664
|
-
const m = /^gitdir:\s*(.+)$/m.exec(
|
|
37364
|
+
let gitDir = path100.join(repoRoot, ".git");
|
|
37365
|
+
if (fs96.statSync(gitDir).isFile()) {
|
|
37366
|
+
const m = /^gitdir:\s*(.+)$/m.exec(fs96.readFileSync(gitDir, "utf-8").trim());
|
|
36665
37367
|
if (m === null) return null;
|
|
36666
|
-
gitDir =
|
|
37368
|
+
gitDir = path100.resolve(repoRoot, m[1]);
|
|
36667
37369
|
}
|
|
36668
37370
|
let refRoot = gitDir;
|
|
36669
37371
|
try {
|
|
36670
|
-
const common =
|
|
36671
|
-
if (common !== "") refRoot =
|
|
37372
|
+
const common = fs96.readFileSync(path100.join(gitDir, "commondir"), "utf-8").trim();
|
|
37373
|
+
if (common !== "") refRoot = path100.resolve(gitDir, common);
|
|
36672
37374
|
} catch {
|
|
36673
37375
|
}
|
|
36674
|
-
const head =
|
|
37376
|
+
const head = fs96.readFileSync(path100.join(gitDir, "HEAD"), "utf-8").trim();
|
|
36675
37377
|
if (/^[0-9a-f]{40}$/.test(head)) return head;
|
|
36676
37378
|
const ref = /^ref:\s*(.+)$/.exec(head);
|
|
36677
37379
|
if (ref === null) return null;
|
|
36678
37380
|
const refName = ref[1];
|
|
36679
37381
|
try {
|
|
36680
|
-
return
|
|
37382
|
+
return fs96.readFileSync(path100.join(refRoot, refName), "utf-8").trim() || null;
|
|
36681
37383
|
} catch {
|
|
36682
|
-
const packed =
|
|
37384
|
+
const packed = fs96.readFileSync(path100.join(refRoot, "packed-refs"), "utf-8");
|
|
36683
37385
|
for (const line of packed.split("\n")) {
|
|
36684
37386
|
const pm = /^([0-9a-f]{40})\s+(.+)$/.exec(line.trim());
|
|
36685
37387
|
if (pm !== null && pm[2] === refName) return pm[1];
|
|
@@ -36693,7 +37395,7 @@ function readHead(repoRoot) {
|
|
|
36693
37395
|
function buildCheckpoint(repoRoot, runId, slug, opts = {}) {
|
|
36694
37396
|
let text;
|
|
36695
37397
|
try {
|
|
36696
|
-
text =
|
|
37398
|
+
text = fs96.readFileSync(roadmapPath(repoRoot, slug), "utf-8");
|
|
36697
37399
|
} catch {
|
|
36698
37400
|
return null;
|
|
36699
37401
|
}
|
|
@@ -36717,8 +37419,8 @@ function buildCheckpoint(repoRoot, runId, slug, opts = {}) {
|
|
|
36717
37419
|
function writeCheckpoint(repoRoot, cp) {
|
|
36718
37420
|
const file = checkpointFile(repoRoot, cp.run_id);
|
|
36719
37421
|
try {
|
|
36720
|
-
|
|
36721
|
-
|
|
37422
|
+
fs96.mkdirSync(path100.dirname(file), { recursive: true });
|
|
37423
|
+
fs96.writeFileSync(file, `${JSON.stringify(cp, null, 2)}
|
|
36722
37424
|
`, "utf-8");
|
|
36723
37425
|
return file;
|
|
36724
37426
|
} catch {
|
|
@@ -36727,7 +37429,7 @@ function writeCheckpoint(repoRoot, cp) {
|
|
|
36727
37429
|
}
|
|
36728
37430
|
|
|
36729
37431
|
// src/scripts/_lib/continuity_writer.ts
|
|
36730
|
-
import * as
|
|
37432
|
+
import * as fs97 from "node:fs";
|
|
36731
37433
|
var AUTO_RECORD_KEY = "continuity.auto_record";
|
|
36732
37434
|
function auto_record_enabled(root) {
|
|
36733
37435
|
try {
|
|
@@ -36825,7 +37527,7 @@ function buildContinuityRecord(input) {
|
|
|
36825
37527
|
}
|
|
36826
37528
|
let text;
|
|
36827
37529
|
try {
|
|
36828
|
-
text =
|
|
37530
|
+
text = fs97.readFileSync(roadmapPath(root, slug), "utf-8");
|
|
36829
37531
|
} catch {
|
|
36830
37532
|
return { record: null, reason: `no record \u2014 the claimed roadmap ${slug} is not readable` };
|
|
36831
37533
|
}
|
|
@@ -36864,12 +37566,12 @@ function buildContinuityRecord(input) {
|
|
|
36864
37566
|
}
|
|
36865
37567
|
|
|
36866
37568
|
// src/scripts/_lib/continuity_slot.ts
|
|
36867
|
-
import * as
|
|
36868
|
-
import * as
|
|
37569
|
+
import * as fs98 from "node:fs";
|
|
37570
|
+
import * as path101 from "node:path";
|
|
36869
37571
|
var MAX_AGE_MS = RECYCLE_MAX_AGE_HOURS * 3600 * 1e3;
|
|
36870
37572
|
function _parse2(file) {
|
|
36871
37573
|
try {
|
|
36872
|
-
const decoded = JSON.parse(
|
|
37574
|
+
const decoded = JSON.parse(fs98.readFileSync(file, "utf-8"));
|
|
36873
37575
|
if (typeof decoded === "object" && decoded !== null && !Array.isArray(decoded)) {
|
|
36874
37576
|
return decoded;
|
|
36875
37577
|
}
|
|
@@ -36886,14 +37588,14 @@ function _ageMs(record, now) {
|
|
|
36886
37588
|
return now.getTime() - at;
|
|
36887
37589
|
}
|
|
36888
37590
|
function inspectSlot(workspace_root, session_id, now = /* @__PURE__ */ new Date()) {
|
|
36889
|
-
const target =
|
|
36890
|
-
if (!
|
|
36891
|
-
const consumed =
|
|
36892
|
-
if (
|
|
37591
|
+
const target = path101.join(workspace_root, recycle_envelope_rel(session_id));
|
|
37592
|
+
if (!fs98.existsSync(target)) {
|
|
37593
|
+
const consumed = path101.join(workspace_root, recycle_consumed_rel(session_id));
|
|
37594
|
+
if (fs98.existsSync(consumed)) {
|
|
36893
37595
|
return { state: "consumed", reason: "the record for this session was consumed", target };
|
|
36894
37596
|
}
|
|
36895
|
-
const quarantined =
|
|
36896
|
-
if (
|
|
37597
|
+
const quarantined = path101.join(workspace_root, recycle_quarantine_rel(session_id));
|
|
37598
|
+
if (fs98.existsSync(quarantined)) {
|
|
36897
37599
|
return {
|
|
36898
37600
|
state: "quarantined",
|
|
36899
37601
|
reason: "the slot is free; an unusable record sits in quarantine",
|
|
@@ -36953,7 +37655,7 @@ function publishContinuityRecord(workspace_root, session_id, record, now = /* @_
|
|
|
36953
37655
|
reason: `refused \u2014 ${bytes} bytes exceeds the ${RECYCLE_ENVELOPE_MAX_BYTES} byte slot cap`
|
|
36954
37656
|
};
|
|
36955
37657
|
}
|
|
36956
|
-
const target =
|
|
37658
|
+
const target = path101.join(workspace_root, recycle_envelope_rel(session_id));
|
|
36957
37659
|
const before = inspectSlot(workspace_root, session_id, now);
|
|
36958
37660
|
if (before.state === "conflicting") {
|
|
36959
37661
|
return { state: "conflicting", wrote: false, reason: `refused \u2014 ${before.reason}` };
|
|
@@ -36970,11 +37672,11 @@ function publishContinuityRecord(workspace_root, session_id, record, now = /* @_
|
|
|
36970
37672
|
}
|
|
36971
37673
|
}
|
|
36972
37674
|
let quarantined;
|
|
36973
|
-
if (before.state === "quarantined" &&
|
|
36974
|
-
const dest =
|
|
37675
|
+
if (before.state === "quarantined" && fs98.existsSync(target)) {
|
|
37676
|
+
const dest = path101.join(workspace_root, recycle_quarantine_rel(session_id));
|
|
36975
37677
|
try {
|
|
36976
|
-
|
|
36977
|
-
|
|
37678
|
+
fs98.mkdirSync(path101.dirname(dest), { recursive: true });
|
|
37679
|
+
fs98.renameSync(target, dest);
|
|
36978
37680
|
quarantined = dest;
|
|
36979
37681
|
} catch (exc) {
|
|
36980
37682
|
return {
|
|
@@ -37003,7 +37705,7 @@ function publishContinuityRecord(workspace_root, session_id, record, now = /* @_
|
|
|
37003
37705
|
|
|
37004
37706
|
// src/scripts/hooks/session_eol_hook.ts
|
|
37005
37707
|
var THRESHOLD_OVERRIDE_ENV = "AGENT_RECYCLE_THRESHOLD_TOKENS";
|
|
37006
|
-
var CONTEXT_FILL_REL =
|
|
37708
|
+
var CONTEXT_FILL_REL = path102.join("agents", "runtime", "state", "context-fill.json");
|
|
37007
37709
|
function str12(value) {
|
|
37008
37710
|
return typeof value === "string" ? value : "";
|
|
37009
37711
|
}
|
|
@@ -37018,7 +37720,7 @@ function payloadSessionId(payload, envelope) {
|
|
|
37018
37720
|
}
|
|
37019
37721
|
function readState4(file) {
|
|
37020
37722
|
try {
|
|
37021
|
-
const parsed = JSON.parse(
|
|
37723
|
+
const parsed = JSON.parse(fs99.readFileSync(file, "utf-8"));
|
|
37022
37724
|
if (parsed && typeof parsed === "object" && parsed.schema_version === 1 && parsed.counters && typeof parsed.counters.scanned_bytes === "number") {
|
|
37023
37725
|
return {
|
|
37024
37726
|
schema_version: 1,
|
|
@@ -37049,7 +37751,7 @@ function readThresholdTokens() {
|
|
|
37049
37751
|
}
|
|
37050
37752
|
function writeContextFill(workspaceRoot3, tokens, threshold, ts) {
|
|
37051
37753
|
try {
|
|
37052
|
-
atomic_write_json(
|
|
37754
|
+
atomic_write_json(path102.join(workspaceRoot3, CONTEXT_FILL_REL), {
|
|
37053
37755
|
schema_version: 1,
|
|
37054
37756
|
final_context_tokens: tokens,
|
|
37055
37757
|
recycle_threshold_tokens: threshold,
|
|
@@ -37059,7 +37761,7 @@ function writeContextFill(workspaceRoot3, tokens, threshold, ts) {
|
|
|
37059
37761
|
} catch {
|
|
37060
37762
|
}
|
|
37061
37763
|
}
|
|
37062
|
-
function
|
|
37764
|
+
function main63() {
|
|
37063
37765
|
const [envelope, payload] = unwrap(readHookStdin(), "claude");
|
|
37064
37766
|
const event = String(envelope["event"] ?? "");
|
|
37065
37767
|
if (event !== "" && event !== "stop") {
|
|
@@ -37142,38 +37844,38 @@ function writeContinuityRecord(workspaceRoot3, rawSessionId, counters, threshold
|
|
|
37142
37844
|
} catch {
|
|
37143
37845
|
}
|
|
37144
37846
|
}
|
|
37145
|
-
function
|
|
37847
|
+
function _isCliEntry46() {
|
|
37146
37848
|
if (true) {
|
|
37147
37849
|
return false;
|
|
37148
37850
|
}
|
|
37149
37851
|
if (process16.argv[1] === void 0) {
|
|
37150
37852
|
return false;
|
|
37151
37853
|
}
|
|
37152
|
-
const argvUrl =
|
|
37854
|
+
const argvUrl = pathToFileURL56(path102.resolve(process16.argv[1])).href;
|
|
37153
37855
|
if (import.meta.url === argvUrl) {
|
|
37154
37856
|
return true;
|
|
37155
37857
|
}
|
|
37156
37858
|
try {
|
|
37157
|
-
const here =
|
|
37158
|
-
const argv =
|
|
37859
|
+
const here = fs99.realpathSync(fileURLToPath66(import.meta.url));
|
|
37860
|
+
const argv = fs99.realpathSync(path102.resolve(process16.argv[1]));
|
|
37159
37861
|
return here === argv;
|
|
37160
37862
|
} catch {
|
|
37161
37863
|
return false;
|
|
37162
37864
|
}
|
|
37163
37865
|
}
|
|
37164
|
-
if (
|
|
37165
|
-
process16.exit(
|
|
37866
|
+
if (_isCliEntry46()) {
|
|
37867
|
+
process16.exit(main63());
|
|
37166
37868
|
}
|
|
37167
37869
|
|
|
37168
37870
|
// src/scripts/hooks/tool_result_bytes_hook.ts
|
|
37169
|
-
import * as
|
|
37170
|
-
import * as
|
|
37171
|
-
import { fileURLToPath as
|
|
37871
|
+
import * as fs100 from "node:fs";
|
|
37872
|
+
import * as path103 from "node:path";
|
|
37873
|
+
import { fileURLToPath as fileURLToPath67, pathToFileURL as pathToFileURL57 } from "node:url";
|
|
37172
37874
|
var EXIT_ALLOW31 = 0;
|
|
37173
37875
|
function isObject17(v) {
|
|
37174
37876
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
37175
37877
|
}
|
|
37176
|
-
var CENSUS_FILE =
|
|
37878
|
+
var CENSUS_FILE = path103.join("agents", "runtime", "state", "tool-result-census.jsonl");
|
|
37177
37879
|
var RESULT_KEYS = ["tool_response", "toolResponse", "tool_result", "toolUseResult"];
|
|
37178
37880
|
function _resultBytes(payload) {
|
|
37179
37881
|
for (const key of RESULT_KEYS) {
|
|
@@ -37208,13 +37910,13 @@ function unwrapPayload4(envelope) {
|
|
|
37208
37910
|
return isObject17(inner) ? inner : envelope;
|
|
37209
37911
|
}
|
|
37210
37912
|
function censusFile(consumerRoot) {
|
|
37211
|
-
return
|
|
37913
|
+
return path103.join(consumerRoot, CENSUS_FILE);
|
|
37212
37914
|
}
|
|
37213
37915
|
function _appendCensusLine(consumerRoot, line) {
|
|
37214
37916
|
if (is_replay_mode()) return;
|
|
37215
37917
|
const file = censusFile(consumerRoot);
|
|
37216
|
-
|
|
37217
|
-
|
|
37918
|
+
fs100.mkdirSync(path103.dirname(file), { recursive: true });
|
|
37919
|
+
fs100.appendFileSync(file, `${JSON.stringify(line)}
|
|
37218
37920
|
`, "utf8");
|
|
37219
37921
|
}
|
|
37220
37922
|
function processEnvelope4(envelope, consumerRoot) {
|
|
@@ -37245,7 +37947,7 @@ function resolveConsumerRoot2(envelope) {
|
|
|
37245
37947
|
}
|
|
37246
37948
|
return process.cwd();
|
|
37247
37949
|
}
|
|
37248
|
-
function
|
|
37950
|
+
function main64() {
|
|
37249
37951
|
const raw = readHookStdin();
|
|
37250
37952
|
let envelope = {};
|
|
37251
37953
|
try {
|
|
@@ -37255,25 +37957,25 @@ function main62() {
|
|
|
37255
37957
|
}
|
|
37256
37958
|
return processEnvelope4(envelope, resolveConsumerRoot2(envelope));
|
|
37257
37959
|
}
|
|
37258
|
-
function
|
|
37960
|
+
function _isCliEntry47() {
|
|
37259
37961
|
if (true) {
|
|
37260
37962
|
return false;
|
|
37261
37963
|
}
|
|
37262
37964
|
if (process.argv[1] === void 0) return false;
|
|
37263
|
-
const argvUrl =
|
|
37965
|
+
const argvUrl = pathToFileURL57(path103.resolve(process.argv[1])).href;
|
|
37264
37966
|
if (import.meta.url === argvUrl) return true;
|
|
37265
37967
|
try {
|
|
37266
|
-
return
|
|
37968
|
+
return fs100.realpathSync(fileURLToPath67(import.meta.url)) === fs100.realpathSync(path103.resolve(process.argv[1]));
|
|
37267
37969
|
} catch {
|
|
37268
37970
|
return false;
|
|
37269
37971
|
}
|
|
37270
37972
|
}
|
|
37271
|
-
if (
|
|
37973
|
+
if (_isCliEntry47()) process.exit(main64());
|
|
37272
37974
|
|
|
37273
37975
|
// src/scripts/hooks/spawn_guard_shadow_hook.ts
|
|
37274
|
-
import * as
|
|
37275
|
-
import * as
|
|
37276
|
-
import { fileURLToPath as
|
|
37976
|
+
import * as fs101 from "node:fs";
|
|
37977
|
+
import * as path104 from "node:path";
|
|
37978
|
+
import { fileURLToPath as fileURLToPath68, pathToFileURL as pathToFileURL58 } from "node:url";
|
|
37277
37979
|
var EXIT_ALLOW32 = 0;
|
|
37278
37980
|
function isObject18(v) {
|
|
37279
37981
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
@@ -37337,7 +38039,7 @@ function processEnvelope5(envelope, consumerRoot) {
|
|
|
37337
38039
|
}
|
|
37338
38040
|
return EXIT_ALLOW32;
|
|
37339
38041
|
}
|
|
37340
|
-
function
|
|
38042
|
+
function main65() {
|
|
37341
38043
|
const raw = readHookStdin();
|
|
37342
38044
|
let envelope = {};
|
|
37343
38045
|
try {
|
|
@@ -37347,27 +38049,27 @@ function main63() {
|
|
|
37347
38049
|
}
|
|
37348
38050
|
return processEnvelope5(envelope, resolveConsumerRoot(envelope));
|
|
37349
38051
|
}
|
|
37350
|
-
function
|
|
38052
|
+
function _isCliEntry48() {
|
|
37351
38053
|
if (true) return false;
|
|
37352
38054
|
if (process.argv[1] === void 0) return false;
|
|
37353
|
-
const argvUrl =
|
|
38055
|
+
const argvUrl = pathToFileURL58(path104.resolve(process.argv[1])).href;
|
|
37354
38056
|
if (import.meta.url === argvUrl) return true;
|
|
37355
38057
|
try {
|
|
37356
|
-
return
|
|
38058
|
+
return fs101.realpathSync(fileURLToPath68(import.meta.url)) === fs101.realpathSync(path104.resolve(process.argv[1]));
|
|
37357
38059
|
} catch {
|
|
37358
38060
|
return false;
|
|
37359
38061
|
}
|
|
37360
38062
|
}
|
|
37361
|
-
if (
|
|
38063
|
+
if (_isCliEntry48()) process.exit(main65());
|
|
37362
38064
|
|
|
37363
38065
|
// src/scripts/hooks/source_first_gate_hook.ts
|
|
37364
|
-
import * as
|
|
37365
|
-
import * as
|
|
37366
|
-
import { fileURLToPath as
|
|
38066
|
+
import * as fs102 from "node:fs";
|
|
38067
|
+
import * as path105 from "node:path";
|
|
38068
|
+
import { fileURLToPath as fileURLToPath69, pathToFileURL as pathToFileURL59 } from "node:url";
|
|
37367
38069
|
var EXIT_ALLOW33 = 0;
|
|
37368
38070
|
var MAX_SHADOW_WARNS = 2;
|
|
37369
|
-
var SHADOW_LOG =
|
|
37370
|
-
var STATE_FILE9 =
|
|
38071
|
+
var SHADOW_LOG = path105.join("agents", "runtime", "state", "source-first-gate.jsonl");
|
|
38072
|
+
var STATE_FILE9 = path105.join("agents", "runtime", "state", "source-first-gate.json");
|
|
37371
38073
|
function isObject19(v) {
|
|
37372
38074
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
37373
38075
|
}
|
|
@@ -37441,7 +38143,7 @@ var EMPTY_STATE = { handoverSeen: false, sourceRead: false, wouldWarn: 0 };
|
|
|
37441
38143
|
var MAX_SESSIONS2 = 50;
|
|
37442
38144
|
function readState5(root, session) {
|
|
37443
38145
|
try {
|
|
37444
|
-
const all = JSON.parse(
|
|
38146
|
+
const all = JSON.parse(fs102.readFileSync(path105.join(root, STATE_FILE9), "utf-8"));
|
|
37445
38147
|
const entry = all[session];
|
|
37446
38148
|
if (entry && typeof entry.handoverSeen === "boolean" && typeof entry.sourceRead === "boolean" && typeof entry.wouldWarn === "number") {
|
|
37447
38149
|
return entry;
|
|
@@ -37453,10 +38155,10 @@ function readState5(root, session) {
|
|
|
37453
38155
|
function writeState4(root, session, state) {
|
|
37454
38156
|
if (is_replay_mode()) return;
|
|
37455
38157
|
try {
|
|
37456
|
-
const file =
|
|
38158
|
+
const file = path105.join(root, STATE_FILE9);
|
|
37457
38159
|
let all = {};
|
|
37458
38160
|
try {
|
|
37459
|
-
all = JSON.parse(
|
|
38161
|
+
all = JSON.parse(fs102.readFileSync(file, "utf-8"));
|
|
37460
38162
|
} catch {
|
|
37461
38163
|
}
|
|
37462
38164
|
if (!isObject19(all)) all = {};
|
|
@@ -37467,8 +38169,8 @@ function writeState4(root, session, state) {
|
|
|
37467
38169
|
for (const key of keys.slice(keys.length - MAX_SESSIONS2)) pruned[key] = all[key];
|
|
37468
38170
|
all = pruned;
|
|
37469
38171
|
}
|
|
37470
|
-
|
|
37471
|
-
|
|
38172
|
+
fs102.mkdirSync(path105.dirname(file), { recursive: true });
|
|
38173
|
+
fs102.writeFileSync(file, JSON.stringify(all));
|
|
37472
38174
|
} catch {
|
|
37473
38175
|
}
|
|
37474
38176
|
}
|
|
@@ -37489,7 +38191,7 @@ function evaluateCandidates2(handoverSeen, handoverOnDisk, sourceRead) {
|
|
|
37489
38191
|
}
|
|
37490
38192
|
function handoverPresentOnDisk(root) {
|
|
37491
38193
|
try {
|
|
37492
|
-
return
|
|
38194
|
+
return fs102.statSync(path105.join(root, ".claude", "design-system")).isDirectory();
|
|
37493
38195
|
} catch {
|
|
37494
38196
|
return false;
|
|
37495
38197
|
}
|
|
@@ -37497,9 +38199,9 @@ function handoverPresentOnDisk(root) {
|
|
|
37497
38199
|
function appendShadowLine(root, line) {
|
|
37498
38200
|
if (is_replay_mode()) return;
|
|
37499
38201
|
try {
|
|
37500
|
-
const file =
|
|
37501
|
-
|
|
37502
|
-
|
|
38202
|
+
const file = path105.join(root, SHADOW_LOG);
|
|
38203
|
+
fs102.mkdirSync(path105.dirname(file), { recursive: true });
|
|
38204
|
+
fs102.appendFileSync(file, `${JSON.stringify(line)}
|
|
37503
38205
|
`, "utf8");
|
|
37504
38206
|
} catch {
|
|
37505
38207
|
}
|
|
@@ -37560,7 +38262,7 @@ function processEnvelope6(envelope, consumerRoot, session) {
|
|
|
37560
38262
|
}
|
|
37561
38263
|
return EXIT_ALLOW33;
|
|
37562
38264
|
}
|
|
37563
|
-
function
|
|
38265
|
+
function main66() {
|
|
37564
38266
|
const raw = readHookStdin();
|
|
37565
38267
|
let envelope = {};
|
|
37566
38268
|
try {
|
|
@@ -37572,26 +38274,26 @@ function main64() {
|
|
|
37572
38274
|
const session = typeof sessionVal === "string" && sessionVal ? sessionVal : "unknown";
|
|
37573
38275
|
return processEnvelope6(envelope, resolveConsumerRoot(envelope), session);
|
|
37574
38276
|
}
|
|
37575
|
-
function
|
|
38277
|
+
function _isCliEntry49() {
|
|
37576
38278
|
if (true) return false;
|
|
37577
38279
|
if (process.argv[1] === void 0) return false;
|
|
37578
|
-
const argvUrl =
|
|
38280
|
+
const argvUrl = pathToFileURL59(path105.resolve(process.argv[1])).href;
|
|
37579
38281
|
if (import.meta.url === argvUrl) return true;
|
|
37580
38282
|
try {
|
|
37581
|
-
return
|
|
38283
|
+
return fs102.realpathSync(fileURLToPath69(import.meta.url)) === fs102.realpathSync(path105.resolve(process.argv[1]));
|
|
37582
38284
|
} catch {
|
|
37583
38285
|
return false;
|
|
37584
38286
|
}
|
|
37585
38287
|
}
|
|
37586
|
-
if (
|
|
38288
|
+
if (_isCliEntry49()) process.exit(main66());
|
|
37587
38289
|
|
|
37588
38290
|
// src/scripts/hooks/interruption_ledger_hook.ts
|
|
37589
|
-
import * as
|
|
37590
|
-
import * as
|
|
37591
|
-
import { fileURLToPath as
|
|
37592
|
-
var
|
|
38291
|
+
import * as fs103 from "node:fs";
|
|
38292
|
+
import * as path106 from "node:path";
|
|
38293
|
+
import { fileURLToPath as fileURLToPath70, pathToFileURL as pathToFileURL60 } from "node:url";
|
|
38294
|
+
var EXIT_OK3 = 0;
|
|
37593
38295
|
var TRANSCRIPT_READ_MAX_BYTES2 = 2 * 1024 * 1024;
|
|
37594
|
-
var LEDGER_RELPATH =
|
|
38296
|
+
var LEDGER_RELPATH = path106.join("agents", "runtime", "state", "interruptions.jsonl");
|
|
37595
38297
|
function hasNumberedOptions(reply) {
|
|
37596
38298
|
let count = 0;
|
|
37597
38299
|
for (const line of reply.split("\n")) {
|
|
@@ -37615,14 +38317,14 @@ function classifyReply(reply) {
|
|
|
37615
38317
|
function readClaimedRoadmap(workspaceRoot3, sessionId3) {
|
|
37616
38318
|
if (!sessionId3) return null;
|
|
37617
38319
|
try {
|
|
37618
|
-
const file =
|
|
38320
|
+
const file = path106.join(
|
|
37619
38321
|
workspaceRoot3,
|
|
37620
38322
|
"agents",
|
|
37621
38323
|
"runtime",
|
|
37622
38324
|
"state",
|
|
37623
38325
|
`roadmap-claim-${sessionId3}.json`
|
|
37624
38326
|
);
|
|
37625
|
-
const parsed = JSON.parse(
|
|
38327
|
+
const parsed = JSON.parse(fs103.readFileSync(file, "utf8"));
|
|
37626
38328
|
if (parsed === null || typeof parsed !== "object") return null;
|
|
37627
38329
|
const slug = parsed["slug"];
|
|
37628
38330
|
return typeof slug === "string" && slug.length > 0 ? slug : null;
|
|
@@ -37633,7 +38335,7 @@ function readClaimedRoadmap(workspaceRoot3, sessionId3) {
|
|
|
37633
38335
|
function alreadyRecorded(ledgerPath, runId, turn) {
|
|
37634
38336
|
let raw;
|
|
37635
38337
|
try {
|
|
37636
|
-
raw =
|
|
38338
|
+
raw = fs103.readFileSync(ledgerPath, "utf8");
|
|
37637
38339
|
} catch {
|
|
37638
38340
|
return false;
|
|
37639
38341
|
}
|
|
@@ -37652,19 +38354,19 @@ function alreadyRecorded(ledgerPath, runId, turn) {
|
|
|
37652
38354
|
function str14(v) {
|
|
37653
38355
|
return typeof v === "string" ? v : "";
|
|
37654
38356
|
}
|
|
37655
|
-
function
|
|
38357
|
+
function main67() {
|
|
37656
38358
|
let envelope;
|
|
37657
38359
|
let payload;
|
|
37658
38360
|
try {
|
|
37659
38361
|
[envelope, payload] = unwrap(readHookStdin(), "claude");
|
|
37660
38362
|
} catch {
|
|
37661
|
-
return
|
|
38363
|
+
return EXIT_OK3;
|
|
37662
38364
|
}
|
|
37663
38365
|
const workspaceRoot3 = str14(envelope["workspace_root"]) || process.cwd();
|
|
37664
38366
|
const transcriptPath = str14(
|
|
37665
38367
|
payload["transcript_path"] ?? payload["transcriptPath"]
|
|
37666
38368
|
);
|
|
37667
|
-
if (!transcriptPath) return
|
|
38369
|
+
if (!transcriptPath) return EXIT_OK3;
|
|
37668
38370
|
let lastAssistant = "";
|
|
37669
38371
|
let turnOrdinal = 0;
|
|
37670
38372
|
try {
|
|
@@ -37672,13 +38374,13 @@ function main65() {
|
|
|
37672
38374
|
lastAssistant = tail.lastAssistant;
|
|
37673
38375
|
turnOrdinal = tail.turnOrdinal;
|
|
37674
38376
|
} catch {
|
|
37675
|
-
return
|
|
38377
|
+
return EXIT_OK3;
|
|
37676
38378
|
}
|
|
37677
|
-
if (!lastAssistant) return
|
|
38379
|
+
if (!lastAssistant) return EXIT_OK3;
|
|
37678
38380
|
const sessionId3 = str14(payload["session_id"]) || str14(envelope["session_id"]);
|
|
37679
38381
|
const runId = sessionId3 ? derive_session_tag(sessionId3) : "unknown";
|
|
37680
|
-
const ledgerPath =
|
|
37681
|
-
if (alreadyRecorded(ledgerPath, runId, turnOrdinal)) return
|
|
38382
|
+
const ledgerPath = path106.join(workspaceRoot3, LEDGER_RELPATH);
|
|
38383
|
+
if (alreadyRecorded(ledgerPath, runId, turnOrdinal)) return EXIT_OK3;
|
|
37682
38384
|
const verdict2 = classifyReply(lastAssistant);
|
|
37683
38385
|
const record = {
|
|
37684
38386
|
run_id: runId,
|
|
@@ -37689,43 +38391,43 @@ function main65() {
|
|
|
37689
38391
|
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
37690
38392
|
};
|
|
37691
38393
|
try {
|
|
37692
|
-
|
|
37693
|
-
|
|
38394
|
+
fs103.mkdirSync(path106.dirname(ledgerPath), { recursive: true });
|
|
38395
|
+
fs103.appendFileSync(ledgerPath, `${JSON.stringify(record)}
|
|
37694
38396
|
`, "utf8");
|
|
37695
38397
|
} catch {
|
|
37696
38398
|
}
|
|
37697
|
-
return
|
|
38399
|
+
return EXIT_OK3;
|
|
37698
38400
|
}
|
|
37699
|
-
function
|
|
38401
|
+
function _isCliEntry50() {
|
|
37700
38402
|
if (process.argv[1] === void 0) {
|
|
37701
38403
|
return false;
|
|
37702
38404
|
}
|
|
37703
|
-
const argvUrl =
|
|
38405
|
+
const argvUrl = pathToFileURL60(path106.resolve(process.argv[1])).href;
|
|
37704
38406
|
if (import.meta.url === argvUrl) {
|
|
37705
38407
|
return true;
|
|
37706
38408
|
}
|
|
37707
38409
|
try {
|
|
37708
|
-
const here =
|
|
37709
|
-
const argv =
|
|
38410
|
+
const here = fs103.realpathSync(fileURLToPath70(import.meta.url));
|
|
38411
|
+
const argv = fs103.realpathSync(path106.resolve(process.argv[1]));
|
|
37710
38412
|
return here === argv;
|
|
37711
38413
|
} catch {
|
|
37712
38414
|
return false;
|
|
37713
38415
|
}
|
|
37714
38416
|
}
|
|
37715
|
-
if (
|
|
37716
|
-
process.exit(
|
|
38417
|
+
if (_isCliEntry50()) {
|
|
38418
|
+
process.exit(main67());
|
|
37717
38419
|
}
|
|
37718
38420
|
|
|
37719
38421
|
// src/scripts/hooks/run_continuation_hook.ts
|
|
37720
|
-
import * as
|
|
38422
|
+
import * as fs105 from "node:fs";
|
|
37721
38423
|
|
|
37722
38424
|
// src/scripts/_lib/billing_grant.ts
|
|
37723
|
-
import * as
|
|
37724
|
-
import * as
|
|
37725
|
-
var BILLING_GRANT_DIR_REL =
|
|
38425
|
+
import * as fs104 from "node:fs";
|
|
38426
|
+
import * as path107 from "node:path";
|
|
38427
|
+
var BILLING_GRANT_DIR_REL = path107.join("agents", "runtime", "billing-grants");
|
|
37726
38428
|
var BILLING_GRANT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
37727
38429
|
function grantFile(repoRoot, runId) {
|
|
37728
|
-
return
|
|
38430
|
+
return path107.join(
|
|
37729
38431
|
repoRoot,
|
|
37730
38432
|
BILLING_GRANT_DIR_REL,
|
|
37731
38433
|
`${runId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`
|
|
@@ -37733,14 +38435,14 @@ function grantFile(repoRoot, runId) {
|
|
|
37733
38435
|
}
|
|
37734
38436
|
function revokeBillingGrant(repoRoot, runId) {
|
|
37735
38437
|
try {
|
|
37736
|
-
|
|
38438
|
+
fs104.unlinkSync(grantFile(repoRoot, runId));
|
|
37737
38439
|
} catch {
|
|
37738
38440
|
}
|
|
37739
38441
|
}
|
|
37740
38442
|
|
|
37741
38443
|
// src/scripts/hooks/run_continuation_hook.ts
|
|
37742
|
-
import * as
|
|
37743
|
-
import { fileURLToPath as
|
|
38444
|
+
import * as path108 from "node:path";
|
|
38445
|
+
import { fileURLToPath as fileURLToPath71, pathToFileURL as pathToFileURL61 } from "node:url";
|
|
37744
38446
|
|
|
37745
38447
|
// src/scripts/_lib/outcome_vocabularies.ts
|
|
37746
38448
|
var RUN_TERMINAL_STATES = [
|
|
@@ -37830,13 +38532,13 @@ var EXIT_ALLOW34 = 0;
|
|
|
37830
38532
|
var EXIT_BLOCK4 = 1;
|
|
37831
38533
|
var BLOCKED_BY_MARKER = /<!--\s*blocked-by:\s*\S[^>]*-->/;
|
|
37832
38534
|
var LEDGER_TAIL_MAX_BYTES = 512 * 1024;
|
|
37833
|
-
var EVENTS_RELPATH =
|
|
38535
|
+
var EVENTS_RELPATH = path108.join(
|
|
37834
38536
|
"agents",
|
|
37835
38537
|
"runtime",
|
|
37836
38538
|
"state",
|
|
37837
38539
|
"run-continuation.jsonl"
|
|
37838
38540
|
);
|
|
37839
|
-
var STATE_DIR_REL =
|
|
38541
|
+
var STATE_DIR_REL = path108.join("agents", "runtime", "state");
|
|
37840
38542
|
var ABSENT_CONFIRM_FIRES = 2;
|
|
37841
38543
|
var DUPLICATE_WINDOW_MS = 60 * 1e3;
|
|
37842
38544
|
function isDuplicateFire(state, turnOrdinal, openCount, nowMs, roadmapSource) {
|
|
@@ -37908,20 +38610,20 @@ function extractVerify(stepText) {
|
|
|
37908
38610
|
function stateRelPath(runId, slug) {
|
|
37909
38611
|
const safeRun = runId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
37910
38612
|
const safeSlug = slug.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
37911
|
-
return
|
|
38613
|
+
return path108.join(STATE_DIR_REL, `run-continuation-${safeRun}-${safeSlug}.json`);
|
|
37912
38614
|
}
|
|
37913
38615
|
function legacyStateRelPath(runId) {
|
|
37914
38616
|
const safe = runId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
37915
|
-
return
|
|
38617
|
+
return path108.join(STATE_DIR_REL, `run-continuation-${safe}.json`);
|
|
37916
38618
|
}
|
|
37917
38619
|
function readRunState(workspaceRoot3, runId, slug) {
|
|
37918
|
-
const keyedFile =
|
|
38620
|
+
const keyedFile = path108.join(workspaceRoot3, stateRelPath(runId, slug));
|
|
37919
38621
|
const keyed = readState6(keyedFile);
|
|
37920
38622
|
if (keyed !== null) return { state: keyed, from: "keyed", keyedFile };
|
|
37921
38623
|
if (fileExists(keyedFile)) {
|
|
37922
38624
|
return { state: null, from: "keyed", keyedFile };
|
|
37923
38625
|
}
|
|
37924
|
-
const legacy = readState6(
|
|
38626
|
+
const legacy = readState6(path108.join(workspaceRoot3, legacyStateRelPath(runId)));
|
|
37925
38627
|
if (legacy === null) return { state: null, from: "none", keyedFile };
|
|
37926
38628
|
if (legacy.roadmap !== void 0 && legacy.roadmap !== slug) {
|
|
37927
38629
|
return { state: null, from: "none", keyedFile };
|
|
@@ -37934,25 +38636,25 @@ function writeState5(file, state) {
|
|
|
37934
38636
|
function clearRunState(workspaceRoot3, runId, keyedFile, adoptedLegacy) {
|
|
37935
38637
|
revokeBillingGrant(workspaceRoot3, runId);
|
|
37936
38638
|
try {
|
|
37937
|
-
|
|
38639
|
+
fs105.rmSync(keyedFile, { force: true });
|
|
37938
38640
|
} catch {
|
|
37939
38641
|
}
|
|
37940
38642
|
if (!adoptedLegacy) return;
|
|
37941
38643
|
try {
|
|
37942
|
-
|
|
38644
|
+
fs105.rmSync(path108.join(workspaceRoot3, legacyStateRelPath(runId)), { force: true });
|
|
37943
38645
|
} catch {
|
|
37944
38646
|
}
|
|
37945
38647
|
}
|
|
37946
38648
|
function fileExists(p) {
|
|
37947
38649
|
try {
|
|
37948
|
-
return
|
|
38650
|
+
return fs105.statSync(p).isFile();
|
|
37949
38651
|
} catch {
|
|
37950
38652
|
return false;
|
|
37951
38653
|
}
|
|
37952
38654
|
}
|
|
37953
38655
|
function readState6(file) {
|
|
37954
38656
|
try {
|
|
37955
|
-
const parsed = JSON.parse(
|
|
38657
|
+
const parsed = JSON.parse(fs105.readFileSync(file, "utf8"));
|
|
37956
38658
|
if (parsed === null || typeof parsed !== "object") return null;
|
|
37957
38659
|
const o = parsed;
|
|
37958
38660
|
if (typeof o["started_at"] !== "string") return null;
|
|
@@ -37993,16 +38695,16 @@ function readState6(file) {
|
|
|
37993
38695
|
}
|
|
37994
38696
|
}
|
|
37995
38697
|
function normalizeDir(p) {
|
|
37996
|
-
const abs =
|
|
38698
|
+
const abs = path108.resolve(p);
|
|
37997
38699
|
try {
|
|
37998
|
-
return
|
|
38700
|
+
return fs105.realpathSync(abs);
|
|
37999
38701
|
} catch {
|
|
38000
38702
|
return abs;
|
|
38001
38703
|
}
|
|
38002
38704
|
}
|
|
38003
38705
|
function normalizeFile(p) {
|
|
38004
|
-
const abs =
|
|
38005
|
-
return
|
|
38706
|
+
const abs = path108.resolve(p);
|
|
38707
|
+
return path108.join(normalizeDir(path108.dirname(abs)), path108.basename(abs));
|
|
38006
38708
|
}
|
|
38007
38709
|
function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
|
|
38008
38710
|
const reader = normalizeDir(workspaceRoot3);
|
|
@@ -38029,36 +38731,36 @@ function provenance(workspaceRoot3, claimPath, sessionRoot, sessionCwd) {
|
|
|
38029
38731
|
};
|
|
38030
38732
|
}
|
|
38031
38733
|
function resolveRoadmap(sessionRoot, workspaceRoot3, slug) {
|
|
38032
|
-
const dirRel =
|
|
38734
|
+
const dirRel = path108.join("agents", "roadmaps");
|
|
38033
38735
|
const stem = slug.trim().replace(/\.md$/, "");
|
|
38034
|
-
const rel =
|
|
38035
|
-
const norm =
|
|
38036
|
-
if (
|
|
38037
|
-
if (sessionRoot !== workspaceRoot3 && isDirectory(
|
|
38038
|
-
return
|
|
38736
|
+
const rel = path108.join(dirRel, `${stem}.md`);
|
|
38737
|
+
const norm = path108.normalize(rel);
|
|
38738
|
+
if (path108.dirname(norm) !== dirRel) return null;
|
|
38739
|
+
if (sessionRoot !== workspaceRoot3 && isDirectory(path108.join(sessionRoot, dirRel))) {
|
|
38740
|
+
return path108.join(sessionRoot, norm);
|
|
38039
38741
|
}
|
|
38040
|
-
return
|
|
38742
|
+
return path108.join(normalizeDir(workspaceRoot3), norm);
|
|
38041
38743
|
}
|
|
38042
38744
|
function isDirectory(p) {
|
|
38043
38745
|
try {
|
|
38044
|
-
return
|
|
38746
|
+
return fs105.statSync(p).isDirectory();
|
|
38045
38747
|
} catch {
|
|
38046
38748
|
return false;
|
|
38047
38749
|
}
|
|
38048
38750
|
}
|
|
38049
38751
|
function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
|
|
38050
38752
|
try {
|
|
38051
|
-
const file =
|
|
38052
|
-
const size =
|
|
38753
|
+
const file = path108.join(workspaceRoot3, EVENTS_RELPATH);
|
|
38754
|
+
const size = fs105.statSync(file).size;
|
|
38053
38755
|
const start = Math.max(0, size - LEDGER_TAIL_MAX_BYTES);
|
|
38054
|
-
const fd =
|
|
38756
|
+
const fd = fs105.openSync(file, "r");
|
|
38055
38757
|
let text;
|
|
38056
38758
|
try {
|
|
38057
38759
|
const buf = Buffer.alloc(size - start);
|
|
38058
|
-
const read =
|
|
38760
|
+
const read = fs105.readSync(fd, buf, 0, buf.length, start);
|
|
38059
38761
|
text = buf.subarray(0, read).toString("utf8");
|
|
38060
38762
|
} finally {
|
|
38061
|
-
|
|
38763
|
+
fs105.closeSync(fd);
|
|
38062
38764
|
}
|
|
38063
38765
|
for (const line of text.split("\n")) {
|
|
38064
38766
|
if (line === "") continue;
|
|
@@ -38081,9 +38783,9 @@ function eventAlreadyLogged(workspaceRoot3, runId, slug, event) {
|
|
|
38081
38783
|
}
|
|
38082
38784
|
function appendEvent2(workspaceRoot3, record) {
|
|
38083
38785
|
try {
|
|
38084
|
-
const file =
|
|
38085
|
-
|
|
38086
|
-
|
|
38786
|
+
const file = path108.join(workspaceRoot3, EVENTS_RELPATH);
|
|
38787
|
+
fs105.mkdirSync(path108.dirname(file), { recursive: true });
|
|
38788
|
+
fs105.appendFileSync(file, `${JSON.stringify(record)}
|
|
38087
38789
|
`, "utf8");
|
|
38088
38790
|
} catch {
|
|
38089
38791
|
}
|
|
@@ -38091,7 +38793,7 @@ function appendEvent2(workspaceRoot3, record) {
|
|
|
38091
38793
|
function refusedThisTurn(workspaceRoot3, sessionId3, turnOrdinal) {
|
|
38092
38794
|
try {
|
|
38093
38795
|
const file = sessionRefusalFile(workspaceRoot3, deriveSessionKey(sessionId3 || "unknown-session"));
|
|
38094
|
-
const rec = parseRecord(
|
|
38796
|
+
const rec = parseRecord(fs105.readFileSync(file, "utf-8"));
|
|
38095
38797
|
return rec !== null && rec.refused_turn === turnOrdinal;
|
|
38096
38798
|
} catch {
|
|
38097
38799
|
return false;
|
|
@@ -38100,7 +38802,7 @@ function refusedThisTurn(workspaceRoot3, sessionId3, turnOrdinal) {
|
|
|
38100
38802
|
function str15(v) {
|
|
38101
38803
|
return typeof v === "string" ? v : "";
|
|
38102
38804
|
}
|
|
38103
|
-
function
|
|
38805
|
+
function main68() {
|
|
38104
38806
|
if (is_replay_mode()) return EXIT_ALLOW34;
|
|
38105
38807
|
if (process.env["AGENT_CONFIG_NO_RUN_CONTINUATION"] === "1") return EXIT_ALLOW34;
|
|
38106
38808
|
let envelope;
|
|
@@ -38125,7 +38827,7 @@ function main66() {
|
|
|
38125
38827
|
let roadmapText = null;
|
|
38126
38828
|
if (roadmapPath2 !== null) {
|
|
38127
38829
|
try {
|
|
38128
|
-
roadmapText =
|
|
38830
|
+
roadmapText = fs105.readFileSync(roadmapPath2, "utf8");
|
|
38129
38831
|
roadmapFile = roadmapPath2;
|
|
38130
38832
|
} catch {
|
|
38131
38833
|
roadmapText = null;
|
|
@@ -38174,7 +38876,7 @@ function main66() {
|
|
|
38174
38876
|
);
|
|
38175
38877
|
if (!transcriptPath) return EXIT_ALLOW34;
|
|
38176
38878
|
try {
|
|
38177
|
-
if (
|
|
38879
|
+
if (fs105.statSync(transcriptPath).size > TRANSCRIPT_READ_MAX_BYTES) {
|
|
38178
38880
|
const inert = readRunState(workspaceRoot3, runId, slug);
|
|
38179
38881
|
if (inert.state !== null && inert.state.inert_reported !== true) {
|
|
38180
38882
|
const inertRoots = provenance(
|
|
@@ -38328,29 +39030,29 @@ ${stepLine}
|
|
|
38328
39030
|
Continue with this step now: do the work, run its verify line, flip the box, then end the turn. Escalate instead of continuing ONLY for a locked decision class (high_impact / user_required) or a halt your contract names.
|
|
38329
39031
|
`;
|
|
38330
39032
|
}
|
|
38331
|
-
function
|
|
39033
|
+
function _isCliEntry51() {
|
|
38332
39034
|
if (true) {
|
|
38333
39035
|
return false;
|
|
38334
39036
|
}
|
|
38335
39037
|
if (process.argv[1] === void 0) return false;
|
|
38336
|
-
const argvUrl =
|
|
39038
|
+
const argvUrl = pathToFileURL61(path108.resolve(process.argv[1])).href;
|
|
38337
39039
|
if (import.meta.url === argvUrl) return true;
|
|
38338
39040
|
try {
|
|
38339
|
-
const here =
|
|
38340
|
-
const argv =
|
|
39041
|
+
const here = fs105.realpathSync(fileURLToPath71(import.meta.url));
|
|
39042
|
+
const argv = fs105.realpathSync(path108.resolve(process.argv[1]));
|
|
38341
39043
|
return here === argv;
|
|
38342
39044
|
} catch {
|
|
38343
39045
|
return false;
|
|
38344
39046
|
}
|
|
38345
39047
|
}
|
|
38346
|
-
if (
|
|
38347
|
-
process.exit(
|
|
39048
|
+
if (_isCliEntry51()) {
|
|
39049
|
+
process.exit(main68());
|
|
38348
39050
|
}
|
|
38349
39051
|
|
|
38350
39052
|
// src/scripts/hooks/journal_record_hook.ts
|
|
38351
|
-
import * as
|
|
38352
|
-
import * as
|
|
38353
|
-
import { fileURLToPath as
|
|
39053
|
+
import * as fs107 from "node:fs";
|
|
39054
|
+
import * as path110 from "node:path";
|
|
39055
|
+
import { fileURLToPath as fileURLToPath72, pathToFileURL as pathToFileURL62 } from "node:url";
|
|
38354
39056
|
|
|
38355
39057
|
// src/scripts/_lib/surface.ts
|
|
38356
39058
|
var SURFACES = ["ide", "cli", "cloud", "unknown"];
|
|
@@ -38380,8 +39082,8 @@ function readSurface(v) {
|
|
|
38380
39082
|
|
|
38381
39083
|
// src/scripts/_lib/runtime_journal.ts
|
|
38382
39084
|
import * as crypto14 from "node:crypto";
|
|
38383
|
-
import * as
|
|
38384
|
-
import * as
|
|
39085
|
+
import * as fs106 from "node:fs";
|
|
39086
|
+
import * as path109 from "node:path";
|
|
38385
39087
|
|
|
38386
39088
|
// src/scripts/_lib/sqlite_schema.ts
|
|
38387
39089
|
function addColumnIfMissing(db, table, column, decl) {
|
|
@@ -38483,7 +39185,7 @@ function requireId(name, id, optional) {
|
|
|
38483
39185
|
}
|
|
38484
39186
|
var JOURNAL_DIR_NAME = "agent-journal";
|
|
38485
39187
|
var JOURNAL_FILE_NAME = "journal.sqlite";
|
|
38486
|
-
var JOURNAL_FALLBACK_REL =
|
|
39188
|
+
var JOURNAL_FALLBACK_REL = path109.join("agents", "runtime", "state", JOURNAL_FILE_NAME);
|
|
38487
39189
|
function digest(domain, input) {
|
|
38488
39190
|
return crypto14.createHash("sha256").update(`${domain}\0${input}`).digest("hex").slice(0, 12);
|
|
38489
39191
|
}
|
|
@@ -38494,20 +39196,20 @@ function resolveJournal(root) {
|
|
|
38494
39196
|
if (common !== null) {
|
|
38495
39197
|
const own = git_dir(root) ?? common;
|
|
38496
39198
|
return {
|
|
38497
|
-
path:
|
|
39199
|
+
path: path109.join(common, JOURNAL_DIR_NAME, JOURNAL_FILE_NAME),
|
|
38498
39200
|
scope: "repo-shared",
|
|
38499
39201
|
reason: "common git dir resolved \u2014 every worktree of this repo writes one database",
|
|
38500
39202
|
repository_id: digest(REPO_DOMAIN, common),
|
|
38501
39203
|
worktree_id: digest(WORKTREE_DOMAIN, own)
|
|
38502
39204
|
};
|
|
38503
39205
|
}
|
|
38504
|
-
let real =
|
|
39206
|
+
let real = path109.resolve(root);
|
|
38505
39207
|
try {
|
|
38506
|
-
real =
|
|
39208
|
+
real = fs106.realpathSync(real);
|
|
38507
39209
|
} catch {
|
|
38508
39210
|
}
|
|
38509
39211
|
return {
|
|
38510
|
-
path:
|
|
39212
|
+
path: path109.join(real, JOURNAL_FALLBACK_REL),
|
|
38511
39213
|
scope: "worktree-local",
|
|
38512
39214
|
reason: "no common git dir \u2014 not inside a git repository; falling back to the tree-local path",
|
|
38513
39215
|
repository_id: digest(REPO_DOMAIN, real),
|
|
@@ -38595,7 +39297,7 @@ function ensureWal(db) {
|
|
|
38595
39297
|
function discard(dbPath) {
|
|
38596
39298
|
for (const p of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
|
|
38597
39299
|
try {
|
|
38598
|
-
|
|
39300
|
+
fs106.rmSync(p, { force: true });
|
|
38599
39301
|
} catch {
|
|
38600
39302
|
}
|
|
38601
39303
|
}
|
|
@@ -38607,9 +39309,9 @@ function openJournal(root) {
|
|
|
38607
39309
|
);
|
|
38608
39310
|
}
|
|
38609
39311
|
const location = resolveJournal(root);
|
|
38610
|
-
|
|
39312
|
+
fs106.mkdirSync(path109.dirname(location.path), { recursive: true });
|
|
38611
39313
|
const { DatabaseSync } = loadSqliteSync("runtime_journal");
|
|
38612
|
-
if (
|
|
39314
|
+
if (fs106.existsSync(location.path)) {
|
|
38613
39315
|
let drift = false;
|
|
38614
39316
|
let probe = null;
|
|
38615
39317
|
try {
|
|
@@ -38848,7 +39550,7 @@ function processEnvelope7(envelope, consumerRoot) {
|
|
|
38848
39550
|
}
|
|
38849
39551
|
return EXIT_ALLOW35;
|
|
38850
39552
|
}
|
|
38851
|
-
function
|
|
39553
|
+
function main69() {
|
|
38852
39554
|
const raw = readHookStdin();
|
|
38853
39555
|
let envelope = {};
|
|
38854
39556
|
try {
|
|
@@ -38858,20 +39560,20 @@ function main67() {
|
|
|
38858
39560
|
}
|
|
38859
39561
|
return processEnvelope7(envelope, resolveConsumerRoot3(envelope));
|
|
38860
39562
|
}
|
|
38861
|
-
function
|
|
39563
|
+
function _isCliEntry52() {
|
|
38862
39564
|
if (true) {
|
|
38863
39565
|
return false;
|
|
38864
39566
|
}
|
|
38865
39567
|
if (process.argv[1] === void 0) return false;
|
|
38866
|
-
const argvUrl =
|
|
39568
|
+
const argvUrl = pathToFileURL62(path110.resolve(process.argv[1])).href;
|
|
38867
39569
|
if (import.meta.url === argvUrl) return true;
|
|
38868
39570
|
try {
|
|
38869
|
-
return
|
|
39571
|
+
return fs107.realpathSync(fileURLToPath72(import.meta.url)) === fs107.realpathSync(path110.resolve(process.argv[1]));
|
|
38870
39572
|
} catch {
|
|
38871
39573
|
return false;
|
|
38872
39574
|
}
|
|
38873
39575
|
}
|
|
38874
|
-
if (
|
|
39576
|
+
if (_isCliEntry52()) process.exit(main69());
|
|
38875
39577
|
|
|
38876
39578
|
// src/scripts/hooks/concern_registry.ts
|
|
38877
39579
|
var CONCERN_REGISTRY = {
|
|
@@ -38920,22 +39622,23 @@ var CONCERN_REGISTRY = {
|
|
|
38920
39622
|
"src/scripts/hooks/skill_route_hook.ts": main52,
|
|
38921
39623
|
"src/scripts/hooks/rule_inject_hook.ts": main53,
|
|
38922
39624
|
"src/scripts/hooks/end_review_nudge_hook.ts": main54,
|
|
38923
|
-
"src/scripts/hooks/
|
|
38924
|
-
"src/scripts/hooks/
|
|
38925
|
-
"src/scripts/hooks/
|
|
38926
|
-
"src/scripts/hooks/
|
|
38927
|
-
"src/scripts/hooks/
|
|
38928
|
-
"src/scripts/hooks/
|
|
38929
|
-
"src/scripts/hooks/
|
|
38930
|
-
"src/scripts/hooks/
|
|
38931
|
-
"src/scripts/hooks/
|
|
38932
|
-
"src/scripts/hooks/
|
|
38933
|
-
"src/scripts/hooks/
|
|
38934
|
-
"src/scripts/hooks/
|
|
39625
|
+
"src/scripts/hooks/review_baseline_hook.ts": main55,
|
|
39626
|
+
"src/scripts/hooks/turn_end_gate_hook.ts": main58,
|
|
39627
|
+
"src/scripts/hooks/edit_shape_hook.ts": main59,
|
|
39628
|
+
"src/scripts/hooks/comment_discipline_hook.ts": main61,
|
|
39629
|
+
"src/scripts/hooks/reread_guard_hook.ts": main62,
|
|
39630
|
+
"src/scripts/hooks/session_eol_hook.ts": main63,
|
|
39631
|
+
"src/scripts/hooks/subagent_ledger_hook.ts": main57,
|
|
39632
|
+
"src/scripts/hooks/tool_result_bytes_hook.ts": main64,
|
|
39633
|
+
"src/scripts/hooks/spawn_guard_shadow_hook.ts": main65,
|
|
39634
|
+
"src/scripts/hooks/source_first_gate_hook.ts": main66,
|
|
39635
|
+
"src/scripts/hooks/interruption_ledger_hook.ts": main67,
|
|
39636
|
+
"src/scripts/hooks/run_continuation_hook.ts": main68,
|
|
39637
|
+
"src/scripts/hooks/journal_record_hook.ts": main69
|
|
38935
39638
|
};
|
|
38936
39639
|
|
|
38937
39640
|
// src/scripts/hooks/category_a.ts
|
|
38938
|
-
import * as
|
|
39641
|
+
import * as path111 from "node:path";
|
|
38939
39642
|
var READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
|
|
38940
39643
|
"Read",
|
|
38941
39644
|
"Glob",
|
|
@@ -39114,10 +39817,10 @@ var SCRIPT_TAKING_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
39114
39817
|
]);
|
|
39115
39818
|
function isInsideWorkingTree(candidate, root) {
|
|
39116
39819
|
if (!candidate.trim() || !root.trim()) return false;
|
|
39117
|
-
const abs =
|
|
39118
|
-
const rel =
|
|
39820
|
+
const abs = path111.resolve(root, candidate);
|
|
39821
|
+
const rel = path111.relative(path111.resolve(root), abs);
|
|
39119
39822
|
if (rel === "") return true;
|
|
39120
|
-
return !rel.startsWith("..") && !
|
|
39823
|
+
return !rel.startsWith("..") && !path111.isAbsolute(rel);
|
|
39121
39824
|
}
|
|
39122
39825
|
function _argv(command) {
|
|
39123
39826
|
return command.trim().split(/\s+/).filter((t) => t.length > 0);
|
|
@@ -39145,7 +39848,7 @@ function _gitSubcommand(argv) {
|
|
|
39145
39848
|
if (!_isFlag(token)) return token;
|
|
39146
39849
|
const [flag, inlineValue] = token.includes("=") ? [token.slice(0, token.indexOf("=")), token.slice(token.indexOf("=") + 1)] : [token, null];
|
|
39147
39850
|
const value = inlineValue ?? (GIT_VALUE_FLAGS.has(flag) ? argv[++i] : void 0);
|
|
39148
|
-
if (value !== void 0 && (
|
|
39851
|
+
if (value !== void 0 && (path111.isAbsolute(value) || value.split("/").includes(".."))) {
|
|
39149
39852
|
return "";
|
|
39150
39853
|
}
|
|
39151
39854
|
}
|
|
@@ -39348,8 +40051,8 @@ function _py_json_dumps2(value, indent) {
|
|
|
39348
40051
|
|
|
39349
40052
|
// src/scripts/_lib/collector_denominator.ts
|
|
39350
40053
|
import crypto15 from "node:crypto";
|
|
39351
|
-
import
|
|
39352
|
-
import
|
|
40054
|
+
import fs109 from "node:fs";
|
|
40055
|
+
import path113 from "node:path";
|
|
39353
40056
|
|
|
39354
40057
|
// src/scripts/_lib/collector_record.ts
|
|
39355
40058
|
var COLLECTOR_EVENTS = [
|
|
@@ -39426,30 +40129,30 @@ var FIELD_PURPOSE = {
|
|
|
39426
40129
|
var ALLOWED_FIELDS = new Set(Object.keys(FIELD_PURPOSE));
|
|
39427
40130
|
|
|
39428
40131
|
// src/scripts/_lib/collector_store.ts
|
|
39429
|
-
import * as
|
|
40132
|
+
import * as fs108 from "node:fs";
|
|
39430
40133
|
import * as os13 from "node:os";
|
|
39431
|
-
import * as
|
|
40134
|
+
import * as path112 from "node:path";
|
|
39432
40135
|
var COLLECTOR_DIR_NAME = "agent-collector";
|
|
39433
40136
|
var COLLECTOR_FILE_NAME = "collector.sqlite";
|
|
39434
40137
|
var OPT_OUT_MARKER_NAME = "OPT-OUT";
|
|
39435
40138
|
var MIGRATION_MARKER_NAME = "MIGRATION-IN-FLIGHT";
|
|
39436
40139
|
var QUARANTINE_DIR_NAME = "quarantine";
|
|
39437
40140
|
function defaultUserRoot() {
|
|
39438
|
-
return
|
|
40141
|
+
return path112.join(os13.homedir(), ".event4u", "agent-config");
|
|
39439
40142
|
}
|
|
39440
40143
|
function resolveCollectorStore(userRoot = defaultUserRoot()) {
|
|
39441
|
-
const dir =
|
|
40144
|
+
const dir = path112.join(userRoot, COLLECTOR_DIR_NAME);
|
|
39442
40145
|
return {
|
|
39443
40146
|
userRoot,
|
|
39444
40147
|
root: dir,
|
|
39445
|
-
path:
|
|
39446
|
-
optOutMarker:
|
|
39447
|
-
migrationMarker:
|
|
39448
|
-
quarantineDir:
|
|
40148
|
+
path: path112.join(dir, COLLECTOR_FILE_NAME),
|
|
40149
|
+
optOutMarker: path112.join(dir, OPT_OUT_MARKER_NAME),
|
|
40150
|
+
migrationMarker: path112.join(dir, MIGRATION_MARKER_NAME),
|
|
40151
|
+
quarantineDir: path112.join(dir, QUARANTINE_DIR_NAME)
|
|
39449
40152
|
};
|
|
39450
40153
|
}
|
|
39451
40154
|
function isOptedOut(userRoot = defaultUserRoot()) {
|
|
39452
|
-
return
|
|
40155
|
+
return fs108.existsSync(resolveCollectorStore(userRoot).optOutMarker);
|
|
39453
40156
|
}
|
|
39454
40157
|
var MIGRATIONS = Object.freeze({
|
|
39455
40158
|
// 0 → 1. No DDL: `user_version` 0 is the default SQLite assigns, and a
|
|
@@ -39466,24 +40169,24 @@ var SPOOL_DIR_NAME = "spool";
|
|
|
39466
40169
|
var SPOOL_PENDING_NAME = "pending.jsonl";
|
|
39467
40170
|
var ENABLED_MARKER_NAME = "ENABLED";
|
|
39468
40171
|
function denominatorPath(userRoot) {
|
|
39469
|
-
return
|
|
40172
|
+
return path113.join(resolveCollectorStore(userRoot).root, DENOMINATOR_FILE_NAME);
|
|
39470
40173
|
}
|
|
39471
40174
|
function spoolDir(userRoot) {
|
|
39472
|
-
return
|
|
40175
|
+
return path113.join(resolveCollectorStore(userRoot).root, SPOOL_DIR_NAME);
|
|
39473
40176
|
}
|
|
39474
40177
|
function spoolPendingPath(userRoot) {
|
|
39475
|
-
return
|
|
40178
|
+
return path113.join(spoolDir(userRoot), SPOOL_PENDING_NAME);
|
|
39476
40179
|
}
|
|
39477
40180
|
function enabledMarkerPath(userRoot) {
|
|
39478
|
-
return
|
|
40181
|
+
return path113.join(resolveCollectorStore(userRoot).root, ENABLED_MARKER_NAME);
|
|
39479
40182
|
}
|
|
39480
40183
|
function isCollectorEnabled(userRoot) {
|
|
39481
40184
|
if (isOptedOut(userRoot)) return false;
|
|
39482
|
-
if (
|
|
39483
|
-
return
|
|
40185
|
+
if (fs109.existsSync(killSwitchPathLocal(userRoot))) return false;
|
|
40186
|
+
return fs109.existsSync(enabledMarkerPath(userRoot));
|
|
39484
40187
|
}
|
|
39485
40188
|
function killSwitchPathLocal(userRoot) {
|
|
39486
|
-
return
|
|
40189
|
+
return path113.join(resolveCollectorStore(userRoot).root, "STOP");
|
|
39487
40190
|
}
|
|
39488
40191
|
function utcDate(at = Date.now()) {
|
|
39489
40192
|
return new Date(at).toISOString().slice(0, 10);
|
|
@@ -39495,8 +40198,8 @@ function recordOpportunity(event, platform, userRoot, at = Date.now(), opts = {}
|
|
|
39495
40198
|
if (!COLLECTOR_EVENTS.includes(event)) return false;
|
|
39496
40199
|
if (!COLLECTOR_PLATFORMS.includes(platform)) return false;
|
|
39497
40200
|
const target = denominatorPath(userRoot);
|
|
39498
|
-
|
|
39499
|
-
|
|
40201
|
+
fs109.mkdirSync(path113.dirname(target), { recursive: true });
|
|
40202
|
+
fs109.appendFileSync(target, `${utcDate(at)} ${event} ${platform}
|
|
39500
40203
|
`);
|
|
39501
40204
|
return true;
|
|
39502
40205
|
} catch {
|
|
@@ -39510,19 +40213,19 @@ var MACHINE_ID_NAME = "machine-id";
|
|
|
39510
40213
|
var EPISODE_DIR_NAME = "episodes";
|
|
39511
40214
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
39512
40215
|
function machineIdPath(userRoot) {
|
|
39513
|
-
return
|
|
40216
|
+
return path113.join(resolveCollectorStore(userRoot).root, MACHINE_ID_NAME);
|
|
39514
40217
|
}
|
|
39515
40218
|
function machineId(userRoot) {
|
|
39516
40219
|
const target = machineIdPath(userRoot);
|
|
39517
40220
|
try {
|
|
39518
|
-
const existing =
|
|
40221
|
+
const existing = fs109.readFileSync(target, "utf8").trim();
|
|
39519
40222
|
if (UUID_RE.test(existing)) return existing;
|
|
39520
40223
|
} catch {
|
|
39521
40224
|
}
|
|
39522
40225
|
try {
|
|
39523
40226
|
const minted = crypto15.randomUUID();
|
|
39524
|
-
|
|
39525
|
-
|
|
40227
|
+
fs109.mkdirSync(path113.dirname(target), { recursive: true });
|
|
40228
|
+
fs109.writeFileSync(target, `${minted}
|
|
39526
40229
|
`);
|
|
39527
40230
|
return minted;
|
|
39528
40231
|
} catch {
|
|
@@ -39546,17 +40249,17 @@ function episodeId(env = process.env) {
|
|
|
39546
40249
|
].join("-");
|
|
39547
40250
|
}
|
|
39548
40251
|
function nextSequence(episode, userRoot) {
|
|
39549
|
-
const dir =
|
|
39550
|
-
const target =
|
|
40252
|
+
const dir = path113.join(resolveCollectorStore(userRoot).root, EPISODE_DIR_NAME);
|
|
40253
|
+
const target = path113.join(dir, `${episode}.seq`);
|
|
39551
40254
|
try {
|
|
39552
|
-
|
|
40255
|
+
fs109.mkdirSync(dir, { recursive: true });
|
|
39553
40256
|
let current = 0;
|
|
39554
40257
|
try {
|
|
39555
|
-
const raw = Number.parseInt(
|
|
40258
|
+
const raw = Number.parseInt(fs109.readFileSync(target, "utf8").trim(), 10);
|
|
39556
40259
|
if (Number.isInteger(raw) && raw >= 0) current = raw + 1;
|
|
39557
40260
|
} catch {
|
|
39558
40261
|
}
|
|
39559
|
-
|
|
40262
|
+
fs109.writeFileSync(target, `${current}
|
|
39560
40263
|
`);
|
|
39561
40264
|
return current;
|
|
39562
40265
|
} catch {
|
|
@@ -39595,12 +40298,12 @@ function spoolRecord(record, userRoot) {
|
|
|
39595
40298
|
try {
|
|
39596
40299
|
if (!isCollectorEnabled(userRoot)) return false;
|
|
39597
40300
|
const target = spoolPendingPath(userRoot);
|
|
39598
|
-
|
|
40301
|
+
fs109.mkdirSync(path113.dirname(target), { recursive: true });
|
|
39599
40302
|
try {
|
|
39600
|
-
if (
|
|
40303
|
+
if (fs109.statSync(target).size >= SPOOL_MAX_BYTES) return false;
|
|
39601
40304
|
} catch {
|
|
39602
40305
|
}
|
|
39603
|
-
|
|
40306
|
+
fs109.appendFileSync(target, `${JSON.stringify(record)}
|
|
39604
40307
|
`);
|
|
39605
40308
|
return true;
|
|
39606
40309
|
} catch {
|
|
@@ -39609,12 +40312,12 @@ function spoolRecord(record, userRoot) {
|
|
|
39609
40312
|
}
|
|
39610
40313
|
|
|
39611
40314
|
// src/scripts/hooks/dispatch_hook.ts
|
|
39612
|
-
var
|
|
39613
|
-
var REPO_ROOT =
|
|
39614
|
-
|
|
39615
|
-
...
|
|
40315
|
+
var _IN_BUNDLE3 = true;
|
|
40316
|
+
var REPO_ROOT = path114.resolve(
|
|
40317
|
+
path114.dirname(fileURLToPath73(import.meta.url)),
|
|
40318
|
+
..._IN_BUNDLE3 ? ["..", ".."] : ["..", "..", ".."]
|
|
39616
40319
|
);
|
|
39617
|
-
var MANIFEST_PATH =
|
|
40320
|
+
var MANIFEST_PATH = path114.join(REPO_ROOT, "src", "scripts", "hook_manifest.yaml");
|
|
39618
40321
|
var EXIT_ALLOW37 = 0;
|
|
39619
40322
|
var EXIT_BLOCK6 = 1;
|
|
39620
40323
|
var EXIT_WARN19 = 2;
|
|
@@ -39676,11 +40379,11 @@ function _manifest_fingerprint(text) {
|
|
|
39676
40379
|
return `${h.toString(16)}:${String(text.length)}`;
|
|
39677
40380
|
}
|
|
39678
40381
|
function _load_yaml3(p) {
|
|
39679
|
-
const text =
|
|
40382
|
+
const text = fs110.readFileSync(p, "utf-8");
|
|
39680
40383
|
const compiled = p.replace(/\.ya?ml$/u, ".json");
|
|
39681
40384
|
if (compiled !== p) {
|
|
39682
40385
|
try {
|
|
39683
|
-
const raw = JSON.parse(
|
|
40386
|
+
const raw = JSON.parse(fs110.readFileSync(compiled, "utf-8"));
|
|
39684
40387
|
if (_isObject18(raw) && raw["fingerprint"] === _manifest_fingerprint(text) && _isObject18(raw["manifest"])) {
|
|
39685
40388
|
return raw["manifest"];
|
|
39686
40389
|
}
|
|
@@ -39778,7 +40481,7 @@ function _maybe_capture_payload(args, payload_text) {
|
|
|
39778
40481
|
}
|
|
39779
40482
|
try {
|
|
39780
40483
|
const target = _expanduser3(capture_dir);
|
|
39781
|
-
|
|
40484
|
+
fs110.mkdirSync(target, { recursive: true });
|
|
39782
40485
|
let payload;
|
|
39783
40486
|
try {
|
|
39784
40487
|
payload = payload_text.trim() ? JSON.parse(payload_text) : {};
|
|
@@ -39795,8 +40498,8 @@ function _maybe_capture_payload(args, payload_text) {
|
|
|
39795
40498
|
const ts = Date.now();
|
|
39796
40499
|
const native = (args.native_event || args.event).replace(/\//g, "_");
|
|
39797
40500
|
const fname = `${args.platform}__${native}__${ts}__${process.pid}.json`;
|
|
39798
|
-
|
|
39799
|
-
|
|
40501
|
+
fs110.writeFileSync(
|
|
40502
|
+
path114.join(target, fname),
|
|
39800
40503
|
_py_json_dumps2(record, 2) + "\n",
|
|
39801
40504
|
{ encoding: "utf-8" }
|
|
39802
40505
|
);
|
|
@@ -39807,7 +40510,7 @@ function _maybe_capture_payload(args, payload_text) {
|
|
|
39807
40510
|
function _expanduser3(p) {
|
|
39808
40511
|
if (p === "~" || p.startsWith("~/")) {
|
|
39809
40512
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "";
|
|
39810
|
-
return
|
|
40513
|
+
return path114.join(home, p.slice(1));
|
|
39811
40514
|
}
|
|
39812
40515
|
return p;
|
|
39813
40516
|
}
|
|
@@ -39840,25 +40543,25 @@ function _resolve_tsx_invocation2(scriptPath, scriptArgs) {
|
|
|
39840
40543
|
const walkUp = (start) => {
|
|
39841
40544
|
let dir = start;
|
|
39842
40545
|
for (; ; ) {
|
|
39843
|
-
const candidate =
|
|
40546
|
+
const candidate = path114.join(dir, "node_modules", ".bin", binName);
|
|
39844
40547
|
if (_isFile8(candidate)) {
|
|
39845
40548
|
return candidate;
|
|
39846
40549
|
}
|
|
39847
|
-
const parent =
|
|
40550
|
+
const parent = path114.dirname(dir);
|
|
39848
40551
|
if (parent === dir) {
|
|
39849
40552
|
return null;
|
|
39850
40553
|
}
|
|
39851
40554
|
dir = parent;
|
|
39852
40555
|
}
|
|
39853
40556
|
};
|
|
39854
|
-
const tsx = walkUp(
|
|
40557
|
+
const tsx = walkUp(path114.dirname(scriptPath)) ?? walkUp(path114.dirname(fileURLToPath73(import.meta.url)));
|
|
39855
40558
|
if (tsx !== null) {
|
|
39856
40559
|
return { command: tsx, args: [scriptPath, ...scriptArgs] };
|
|
39857
40560
|
}
|
|
39858
40561
|
return { command: "npx", args: ["tsx", scriptPath, ...scriptArgs] };
|
|
39859
40562
|
}
|
|
39860
40563
|
function _run_concern_inproc(main_fn, concern, envelope) {
|
|
39861
|
-
const scriptAbs =
|
|
40564
|
+
const scriptAbs = path114.join(REPO_ROOT, String(concern["script"]));
|
|
39862
40565
|
const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
|
|
39863
40566
|
argsList.push("--platform", String(envelope["platform"] || "generic"));
|
|
39864
40567
|
const workspace = String(envelope["workspace_root"] || process.cwd());
|
|
@@ -39894,7 +40597,7 @@ function _run_concern_inproc(main_fn, concern, envelope) {
|
|
|
39894
40597
|
if (!(k in hardened)) delete process.env[k];
|
|
39895
40598
|
}
|
|
39896
40599
|
Object.assign(process.env, hardened);
|
|
39897
|
-
if (workspace !== prevCwd &&
|
|
40600
|
+
if (workspace !== prevCwd && _isDir6(workspace)) {
|
|
39898
40601
|
process.chdir(workspace);
|
|
39899
40602
|
}
|
|
39900
40603
|
const result = main_fn(argsList);
|
|
@@ -39935,7 +40638,7 @@ function _run_concern(concern, envelope) {
|
|
|
39935
40638
|
return _run_concern_inproc(inproc, concern, envelope);
|
|
39936
40639
|
}
|
|
39937
40640
|
}
|
|
39938
|
-
const script =
|
|
40641
|
+
const script = path114.join(REPO_ROOT, String(concern["script"]));
|
|
39939
40642
|
const argsList = Array.isArray(concern["args"]) ? concern["args"].map((a) => String(a)) : [];
|
|
39940
40643
|
const cmd = [script, ...argsList];
|
|
39941
40644
|
cmd.push("--platform", String(envelope["platform"] || "generic"));
|
|
@@ -39958,7 +40661,7 @@ function _run_concern(concern, envelope) {
|
|
|
39958
40661
|
const concern_env = hardenedSpawnEnv({ AGENT_CONFIG_PACKAGE_ROOT: REPO_ROOT });
|
|
39959
40662
|
const started = performance.now();
|
|
39960
40663
|
const { command, args: spawnArgs } = _resolve_tsx_invocation2(script, cmd.slice(1));
|
|
39961
|
-
const proc =
|
|
40664
|
+
const proc = spawnSync11(command, spawnArgs, {
|
|
39962
40665
|
input: _compactJsonDumps(envelope),
|
|
39963
40666
|
encoding: "utf-8",
|
|
39964
40667
|
cwd: workspace,
|
|
@@ -39992,7 +40695,7 @@ function _run_concern(concern, envelope) {
|
|
|
39992
40695
|
}
|
|
39993
40696
|
function _isFile8(p) {
|
|
39994
40697
|
try {
|
|
39995
|
-
return
|
|
40698
|
+
return fs110.statSync(p).isFile();
|
|
39996
40699
|
} catch {
|
|
39997
40700
|
return false;
|
|
39998
40701
|
}
|
|
@@ -40014,10 +40717,10 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
|
|
|
40014
40717
|
return;
|
|
40015
40718
|
}
|
|
40016
40719
|
const workspace = String(envelope["workspace_root"] || process.cwd());
|
|
40017
|
-
const state_root =
|
|
40720
|
+
const state_root = path114.join(workspace, "agents", "runtime", "state");
|
|
40018
40721
|
const fb_dir = feedback_dir(state_root, session_id);
|
|
40019
40722
|
try {
|
|
40020
|
-
|
|
40723
|
+
fs110.mkdirSync(fb_dir, { recursive: true });
|
|
40021
40724
|
} catch (exc) {
|
|
40022
40725
|
const msg = exc instanceof Error ? exc.message : String(exc);
|
|
40023
40726
|
process.stderr.write(`dispatch_hook: feedback dir unavailable: ${msg}
|
|
@@ -40025,7 +40728,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
|
|
|
40025
40728
|
return;
|
|
40026
40729
|
}
|
|
40027
40730
|
for (const entry of entries) {
|
|
40028
|
-
const target =
|
|
40731
|
+
const target = path114.join(fb_dir, `${entry["concern"]}.json`);
|
|
40029
40732
|
try {
|
|
40030
40733
|
atomic_write_json(target, entry);
|
|
40031
40734
|
} catch (exc) {
|
|
@@ -40074,7 +40777,7 @@ function _write_feedback(envelope, session_id, entries, final_rc, started_at) {
|
|
|
40074
40777
|
};
|
|
40075
40778
|
try {
|
|
40076
40779
|
const invocation = `${String(process.pid)}-${process.hrtime.bigint().toString()}`;
|
|
40077
|
-
update_json_under_lock(
|
|
40780
|
+
update_json_under_lock(path114.join(fb_dir, "summary.json"), (loaded) => {
|
|
40078
40781
|
const priorRaw = loaded["invocations"];
|
|
40079
40782
|
const prior = Array.isArray(priorRaw) ? priorRaw : [];
|
|
40080
40783
|
const next = [...prior, { invocation, ...summary }];
|
|
@@ -40101,8 +40804,8 @@ function _record_rule_trips(envelope, entries) {
|
|
|
40101
40804
|
if (tripped.length === 0) return;
|
|
40102
40805
|
try {
|
|
40103
40806
|
const workspace = String(envelope["workspace_root"] || process.cwd());
|
|
40104
|
-
const state_dir =
|
|
40105
|
-
const target =
|
|
40807
|
+
const state_dir = path114.join(workspace, "agents", "runtime", "state");
|
|
40808
|
+
const target = path114.join(state_dir, "rule-trips.json");
|
|
40106
40809
|
const today = _now_iso3().slice(0, 10);
|
|
40107
40810
|
update_json_under_lock(target, (loaded) => {
|
|
40108
40811
|
const doc = { schema_version: 1, concerns: {}, ...loaded };
|
|
@@ -40207,11 +40910,11 @@ function _parse_args(argv) {
|
|
|
40207
40910
|
}
|
|
40208
40911
|
return args;
|
|
40209
40912
|
}
|
|
40210
|
-
function
|
|
40913
|
+
function main70(argv) {
|
|
40211
40914
|
const args = _parse_args(argv ?? process.argv.slice(2));
|
|
40212
40915
|
if (args.project_dir) {
|
|
40213
40916
|
const project_dir = _expanduser3(args.project_dir);
|
|
40214
|
-
if (
|
|
40917
|
+
if (_isDir6(project_dir)) {
|
|
40215
40918
|
process.chdir(project_dir);
|
|
40216
40919
|
} else {
|
|
40217
40920
|
process.stderr.write(
|
|
@@ -40244,7 +40947,7 @@ function main68(argv) {
|
|
|
40244
40947
|
recordOpportunity(args.event, args.platform);
|
|
40245
40948
|
recordCapture(args.event, args.platform);
|
|
40246
40949
|
const manifest_path = args.manifest;
|
|
40247
|
-
if (!
|
|
40950
|
+
if (!fs110.existsSync(manifest_path)) {
|
|
40248
40951
|
process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}
|
|
40249
40952
|
`);
|
|
40250
40953
|
return EXIT_ALLOW37;
|
|
@@ -40412,9 +41115,9 @@ function main68(argv) {
|
|
|
40412
41115
|
}
|
|
40413
41116
|
return emission.exit;
|
|
40414
41117
|
}
|
|
40415
|
-
function
|
|
41118
|
+
function _isDir6(p) {
|
|
40416
41119
|
try {
|
|
40417
|
-
return
|
|
41120
|
+
return fs110.statSync(p).isDirectory();
|
|
40418
41121
|
} catch {
|
|
40419
41122
|
return false;
|
|
40420
41123
|
}
|
|
@@ -40424,36 +41127,36 @@ function _sortedRepr(s) {
|
|
|
40424
41127
|
return `[${items.map((x) => `'${x}'`).join(", ")}]`;
|
|
40425
41128
|
}
|
|
40426
41129
|
var _stdin_read_failed = null;
|
|
40427
|
-
function
|
|
41130
|
+
function _isCliEntry53() {
|
|
40428
41131
|
if (true) {
|
|
40429
41132
|
return false;
|
|
40430
41133
|
}
|
|
40431
41134
|
if (process.argv[1] === void 0) {
|
|
40432
41135
|
return false;
|
|
40433
41136
|
}
|
|
40434
|
-
const argvUrl =
|
|
41137
|
+
const argvUrl = pathToFileURL63(path114.resolve(process.argv[1])).href;
|
|
40435
41138
|
if (import.meta.url === argvUrl) {
|
|
40436
41139
|
return true;
|
|
40437
41140
|
}
|
|
40438
41141
|
try {
|
|
40439
|
-
const here =
|
|
40440
|
-
const argv =
|
|
41142
|
+
const here = fs110.realpathSync(fileURLToPath73(import.meta.url));
|
|
41143
|
+
const argv = fs110.realpathSync(path114.resolve(process.argv[1]));
|
|
40441
41144
|
return here === argv;
|
|
40442
41145
|
} catch {
|
|
40443
41146
|
return false;
|
|
40444
41147
|
}
|
|
40445
41148
|
}
|
|
40446
|
-
var isCliEntry16 =
|
|
41149
|
+
var isCliEntry16 = _isCliEntry53();
|
|
40447
41150
|
if (isCliEntry16) {
|
|
40448
|
-
process.exit(
|
|
41151
|
+
process.exit(main70(process.argv.slice(2)));
|
|
40449
41152
|
}
|
|
40450
41153
|
|
|
40451
41154
|
// src/scripts/hooks/dispatch_entry.ts
|
|
40452
|
-
var _selfPath =
|
|
40453
|
-
var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 &&
|
|
41155
|
+
var _selfPath = fileURLToPath74(import.meta.url);
|
|
41156
|
+
var _invokedDirectly2 = globalThis.__AC_HOOKS_BUNDLE_DIRECT === true || process.argv[1] !== void 0 && path115.resolve(process.argv[1]) === path115.resolve(_selfPath);
|
|
40454
41157
|
if (_invokedDirectly2) {
|
|
40455
|
-
process.exitCode =
|
|
41158
|
+
process.exitCode = main70(process.argv.slice(2));
|
|
40456
41159
|
}
|
|
40457
41160
|
export {
|
|
40458
|
-
|
|
41161
|
+
main70 as main
|
|
40459
41162
|
};
|