@memnexus-ai/cli 1.7.234 → 1.7.236
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/memories.d.ts.map +1 -1
- package/dist/commands/memories.js +63 -11
- package/dist/commands/memories.js.map +1 -1
- package/dist/lib/renderable-retrieval.d.ts +54 -0
- package/dist/lib/renderable-retrieval.d.ts.map +1 -1
- package/dist/lib/renderable-retrieval.js +117 -4
- package/dist/lib/renderable-retrieval.js.map +1 -1
- package/hooks/capture-precompact.sh +258 -0
- package/hooks/capture-session-end.sh +256 -0
- package/package.json +3 -2
- package/hooks/capture-hooks.test.sh +0 -465
|
@@ -42,6 +42,17 @@
|
|
|
42
42
|
* stdout, and only when degraded — matching the server convention that a
|
|
43
43
|
* healthy response gains no new fields (search.schema.ts).
|
|
44
44
|
*
|
|
45
|
+
* ANCHOR-GATE SUPPRESSION (#5450) — A SECOND, DISTINCT CONDITION
|
|
46
|
+
*
|
|
47
|
+
* The fulltext-anchor gate can discard a non-empty candidate set and return `[]`
|
|
48
|
+
* while every branch reports healthy, so `degraded` is false. The server already
|
|
49
|
+
* discloses it (`meta.anchorGateSuppressed`, `meta.anchorGateDiscardedCount`);
|
|
50
|
+
* the CLI dropped it, and the human surfaces printed "Found 0 results". It is
|
|
51
|
+
* carried as `AnchorSuppressionState`, kept apart from `DegradationState`
|
|
52
|
+
* because a suppressed empty is not a branch failure. JSON/YAML stdout is
|
|
53
|
+
* UNCHANGED for this condition: the markers already ride through `meta`
|
|
54
|
+
* untouched, and machine callers may depend on the current shape.
|
|
55
|
+
*
|
|
45
56
|
* This module deliberately has no imports: colouring is the caller's job, and a
|
|
46
57
|
* dependency-free module keeps the type-level enforcement test cheap to run.
|
|
47
58
|
*/
|
|
@@ -62,6 +73,22 @@ export interface DegradationState {
|
|
|
62
73
|
readonly degraded: boolean;
|
|
63
74
|
readonly failures: readonly BranchFailure[];
|
|
64
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether the fulltext-anchor gate threw candidates away on this response
|
|
78
|
+
* (GH #5450), and how many.
|
|
79
|
+
*
|
|
80
|
+
* SEPARATE from `DegradationState` on purpose. The gate can null a candidate set
|
|
81
|
+
* while every retrieval branch reports ok, so `degraded` is FALSE on this path
|
|
82
|
+
* and the CLI's degraded warning never fires. Folding the two together would
|
|
83
|
+
* mislabel a healthy-but-suppressed response as a branch failure and lose the
|
|
84
|
+
* discarded count. `suppressed` is never optional and `discardedCount` is always
|
|
85
|
+
* a number, for the same reason `failures` is always an array: there is no
|
|
86
|
+
* `undefined` for a renderer to read as "fine".
|
|
87
|
+
*/
|
|
88
|
+
export interface AnchorSuppressionState {
|
|
89
|
+
readonly suppressed: boolean;
|
|
90
|
+
readonly discardedCount: number;
|
|
91
|
+
}
|
|
65
92
|
/** A normalised search hit: `{ memory, score, matchedVia }`. */
|
|
66
93
|
export interface SearchResultItem {
|
|
67
94
|
readonly memory: Record<string, any>;
|
|
@@ -72,6 +99,11 @@ export interface SearchResultItem {
|
|
|
72
99
|
export declare const DEGRADED_MARKER = "\u26A0 Degraded retrieval";
|
|
73
100
|
/** Suffix appended to a command's headline when the response is degraded. */
|
|
74
101
|
export declare const DEGRADED_HEADLINE_SUFFIX = " \u2014 INCOMPLETE (degraded retrieval)";
|
|
102
|
+
/**
|
|
103
|
+
* Shared marker text for a suppressed result set. Distinct string from
|
|
104
|
+
* `DEGRADED_MARKER` so the two conditions stay greppable apart in agent logs.
|
|
105
|
+
*/
|
|
106
|
+
export declare const SUPPRESSED_MARKER = "\u26A0 Results DISCARDED (anchor gate)";
|
|
75
107
|
/**
|
|
76
108
|
* The stderr warning line for a response, or null when the response is healthy.
|
|
77
109
|
* Plain text — the caller applies colour.
|
|
@@ -84,6 +116,23 @@ export declare function degradationWarningLine(health: DegradationState): string
|
|
|
84
116
|
export declare function degradationSummaryLine(health: DegradationState): string | null;
|
|
85
117
|
/** Headline suffix for spinners; empty string when healthy. */
|
|
86
118
|
export declare function degradationHeadlineSuffix(health: DegradationState): string;
|
|
119
|
+
/**
|
|
120
|
+
* The stderr warning line for a suppressed result set, or null when nothing was
|
|
121
|
+
* discarded. Plain text — the caller applies colour.
|
|
122
|
+
*
|
|
123
|
+
* The wording has one job: an agent skimming this output must not conclude that
|
|
124
|
+
* nothing exists. That conclusion is the actual harm in #5450 — every roleguide
|
|
125
|
+
* in this repo gates work on a memory search, and a cheerful "Found 0 results"
|
|
126
|
+
* passes that gate with a wrong answer.
|
|
127
|
+
*/
|
|
128
|
+
export declare function suppressionWarningLine(suppression: AnchorSuppressionState): string | null;
|
|
129
|
+
/**
|
|
130
|
+
* A one-line marker for human stdout renderers (table footer, llm/compact
|
|
131
|
+
* header). Null when nothing was discarded.
|
|
132
|
+
*/
|
|
133
|
+
export declare function suppressionSummaryLine(suppression: AnchorSuppressionState): string | null;
|
|
134
|
+
/** Headline suffix for spinners; empty string when nothing was discarded. */
|
|
135
|
+
export declare function suppressionHeadlineSuffix(suppression: AnchorSuppressionState): string;
|
|
87
136
|
/**
|
|
88
137
|
* A search response that has been through the health mapping.
|
|
89
138
|
*
|
|
@@ -101,6 +150,11 @@ export declare class RenderableSearchResult {
|
|
|
101
150
|
readonly temporalMetadata: any;
|
|
102
151
|
/** Retrieval health. Always populated. */
|
|
103
152
|
readonly health: DegradationState;
|
|
153
|
+
/**
|
|
154
|
+
* Anchor-gate suppression (#5450). Always populated, and deliberately NOT
|
|
155
|
+
* folded into `health`: a suppressed empty is not a branch failure.
|
|
156
|
+
*/
|
|
157
|
+
readonly suppression: AnchorSuppressionState;
|
|
104
158
|
private readonly body;
|
|
105
159
|
private constructor();
|
|
106
160
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderable-retrieval.d.ts","sourceRoot":"","sources":["../../src/lib/renderable-retrieval.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"renderable-retrieval.d.ts","sourceRoot":"","sources":["../../src/lib/renderable-retrieval.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,22 +43,45 @@
|
|
|
43
43
|
* stdout, and only when degraded — matching the server convention that a
|
|
44
44
|
* healthy response gains no new fields (search.schema.ts).
|
|
45
45
|
*
|
|
46
|
+
* ANCHOR-GATE SUPPRESSION (#5450) — A SECOND, DISTINCT CONDITION
|
|
47
|
+
*
|
|
48
|
+
* The fulltext-anchor gate can discard a non-empty candidate set and return `[]`
|
|
49
|
+
* while every branch reports healthy, so `degraded` is false. The server already
|
|
50
|
+
* discloses it (`meta.anchorGateSuppressed`, `meta.anchorGateDiscardedCount`);
|
|
51
|
+
* the CLI dropped it, and the human surfaces printed "Found 0 results". It is
|
|
52
|
+
* carried as `AnchorSuppressionState`, kept apart from `DegradationState`
|
|
53
|
+
* because a suppressed empty is not a branch failure. JSON/YAML stdout is
|
|
54
|
+
* UNCHANGED for this condition: the markers already ride through `meta`
|
|
55
|
+
* untouched, and machine callers may depend on the current shape.
|
|
56
|
+
*
|
|
46
57
|
* This module deliberately has no imports: colouring is the caller's job, and a
|
|
47
58
|
* dependency-free module keeps the type-level enforcement test cheap to run.
|
|
48
59
|
*/
|
|
49
60
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
-
exports.RenderableContextBriefing = exports.RenderableDigestResult = exports.RenderableSearchResult = exports.DEGRADED_HEADLINE_SUFFIX = exports.DEGRADED_MARKER = void 0;
|
|
61
|
+
exports.RenderableContextBriefing = exports.RenderableDigestResult = exports.RenderableSearchResult = exports.SUPPRESSED_MARKER = exports.DEGRADED_HEADLINE_SUFFIX = exports.DEGRADED_MARKER = void 0;
|
|
51
62
|
exports.degradationWarningLine = degradationWarningLine;
|
|
52
63
|
exports.degradationSummaryLine = degradationSummaryLine;
|
|
53
64
|
exports.degradationHeadlineSuffix = degradationHeadlineSuffix;
|
|
65
|
+
exports.suppressionWarningLine = suppressionWarningLine;
|
|
66
|
+
exports.suppressionSummaryLine = suppressionSummaryLine;
|
|
67
|
+
exports.suppressionHeadlineSuffix = suppressionHeadlineSuffix;
|
|
54
68
|
/** Shared marker text. Every surface uses this string so it is greppable. */
|
|
55
69
|
exports.DEGRADED_MARKER = '⚠ Degraded retrieval';
|
|
56
70
|
/** Suffix appended to a command's headline when the response is degraded. */
|
|
57
71
|
exports.DEGRADED_HEADLINE_SUFFIX = ' — INCOMPLETE (degraded retrieval)';
|
|
72
|
+
/**
|
|
73
|
+
* Shared marker text for a suppressed result set. Distinct string from
|
|
74
|
+
* `DEGRADED_MARKER` so the two conditions stay greppable apart in agent logs.
|
|
75
|
+
*/
|
|
76
|
+
exports.SUPPRESSED_MARKER = '⚠ Results DISCARDED (anchor gate)';
|
|
58
77
|
const HEALTHY = Object.freeze({
|
|
59
78
|
degraded: false,
|
|
60
79
|
failures: Object.freeze([]),
|
|
61
80
|
});
|
|
81
|
+
const NOT_SUPPRESSED = Object.freeze({
|
|
82
|
+
suppressed: false,
|
|
83
|
+
discardedCount: 0,
|
|
84
|
+
});
|
|
62
85
|
/**
|
|
63
86
|
* Branch names are server-supplied and land on stderr, which agents read.
|
|
64
87
|
* Constrain them to an identifier shape and cap the count rather than echoing
|
|
@@ -103,6 +126,29 @@ function readDegradation(container) {
|
|
|
103
126
|
return HEALTHY;
|
|
104
127
|
return Object.freeze({ degraded: true, failures: readBranchFailures(c.branchFailures) });
|
|
105
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Read the fulltext-anchor-gate disclosure from a wire `meta` container
|
|
131
|
+
* (`meta.anchorGateSuppressed` + `meta.anchorGateDiscardedCount`, attached by
|
|
132
|
+
* the SearchHealth class in core-api/src/routes/memories.routes.ts).
|
|
133
|
+
*
|
|
134
|
+
* The server was already correct: it discloses both fields. The CLI dropped them
|
|
135
|
+
* because `readDegradation` is keyed on `degraded`, which is false here (#5450).
|
|
136
|
+
* This is the single place those two field names are read.
|
|
137
|
+
*
|
|
138
|
+
* Tolerant of either field arriving alone: the count is authoritative when it is
|
|
139
|
+
* a positive number, and a bare `anchorGateSuppressed: true` still counts as
|
|
140
|
+
* suppressed (with an unknown count) rather than being silently dropped.
|
|
141
|
+
*/
|
|
142
|
+
function readAnchorSuppression(container) {
|
|
143
|
+
const c = container;
|
|
144
|
+
if (!c || typeof c !== 'object')
|
|
145
|
+
return NOT_SUPPRESSED;
|
|
146
|
+
const raw = c.anchorGateDiscardedCount;
|
|
147
|
+
const count = typeof raw === 'number' && Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 0;
|
|
148
|
+
if (c.anchorGateSuppressed !== true && count === 0)
|
|
149
|
+
return NOT_SUPPRESSED;
|
|
150
|
+
return Object.freeze({ suppressed: true, discardedCount: count });
|
|
151
|
+
}
|
|
106
152
|
/**
|
|
107
153
|
* build-context reports failure per SECTION rather than per search branch
|
|
108
154
|
* (`meta.timedOutSections` / `meta.failedSections`, memories.routes.ts). Map
|
|
@@ -206,6 +252,66 @@ function degradationSummaryLine(health) {
|
|
|
206
252
|
function degradationHeadlineSuffix(health) {
|
|
207
253
|
return health.degraded ? exports.DEGRADED_HEADLINE_SUFFIX : '';
|
|
208
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* How the discarded count reads when the server sent the flag but no number.
|
|
257
|
+
*
|
|
258
|
+
* "CANDIDATE result", not "matching result" (#5450 review): the count is
|
|
259
|
+
* `anchorGateDiscardedCount`, which counts candidates the gate REJECTED, and
|
|
260
|
+
* rejecting weak candidates is what the gate is for — some fraction of them are
|
|
261
|
+
* genuinely irrelevant. Claiming N *matching* memories were withheld would send
|
|
262
|
+
* an agent re-querying for memories that are not there, and reporting to its own
|
|
263
|
+
* caller that the store holds matches it could not retrieve.
|
|
264
|
+
*
|
|
265
|
+
* The subject AND its verb are returned together ("1 candidate result was" /
|
|
266
|
+
* "28 candidate results were"): the verb has to agree with the singularised
|
|
267
|
+
* noun, so a call site that supplies its own hard-coded "were" produces
|
|
268
|
+
* "1 candidate result were". These lines exist to be believed by an agent
|
|
269
|
+
* skimming them — a visible grammar error in a warning whose whole job is to
|
|
270
|
+
* carry authority undermines it. Call sites must not add a verb.
|
|
271
|
+
*/
|
|
272
|
+
function discardedPhrase(suppression) {
|
|
273
|
+
if (suppression.discardedCount === 1)
|
|
274
|
+
return '1 candidate result was';
|
|
275
|
+
return suppression.discardedCount > 0
|
|
276
|
+
? `${suppression.discardedCount} candidate results were`
|
|
277
|
+
: 'candidate results were';
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* The stderr warning line for a suppressed result set, or null when nothing was
|
|
281
|
+
* discarded. Plain text — the caller applies colour.
|
|
282
|
+
*
|
|
283
|
+
* The wording has one job: an agent skimming this output must not conclude that
|
|
284
|
+
* nothing exists. That conclusion is the actual harm in #5450 — every roleguide
|
|
285
|
+
* in this repo gates work on a memory search, and a cheerful "Found 0 results"
|
|
286
|
+
* passes that gate with a wrong answer.
|
|
287
|
+
*/
|
|
288
|
+
function suppressionWarningLine(suppression) {
|
|
289
|
+
if (!suppression.suppressed)
|
|
290
|
+
return null;
|
|
291
|
+
return (`${exports.SUPPRESSED_MARKER} — ${discardedPhrase(suppression)} retrieved and then DISCARDED ` +
|
|
292
|
+
'by the fulltext-anchor gate before output. This result set is short or empty because ' +
|
|
293
|
+
'results were THROWN AWAY, not because nothing matched. It is NOT evidence that nothing ' +
|
|
294
|
+
'exists — re-run with different wording, or use --format json to read ' +
|
|
295
|
+
'meta.anchorGateDiscardedCount.');
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* A one-line marker for human stdout renderers (table footer, llm/compact
|
|
299
|
+
* header). Null when nothing was discarded.
|
|
300
|
+
*/
|
|
301
|
+
function suppressionSummaryLine(suppression) {
|
|
302
|
+
if (!suppression.suppressed)
|
|
303
|
+
return null;
|
|
304
|
+
return (`${exports.SUPPRESSED_MARKER} — ${discardedPhrase(suppression)} DISCARDED before output. ` +
|
|
305
|
+
'An empty or short result set here is NOT evidence that nothing exists.');
|
|
306
|
+
}
|
|
307
|
+
/** Headline suffix for spinners; empty string when nothing was discarded. */
|
|
308
|
+
function suppressionHeadlineSuffix(suppression) {
|
|
309
|
+
if (!suppression.suppressed)
|
|
310
|
+
return '';
|
|
311
|
+
return suppression.discardedCount > 0
|
|
312
|
+
? ` — ${suppression.discardedCount} DISCARDED, not proof of absence`
|
|
313
|
+
: ' — results DISCARDED, not proof of absence';
|
|
314
|
+
}
|
|
209
315
|
function normaliseResults(raw) {
|
|
210
316
|
if (!Array.isArray(raw))
|
|
211
317
|
return Object.freeze([]);
|
|
@@ -223,6 +329,7 @@ class RenderableSearchResult {
|
|
|
223
329
|
searchMethod;
|
|
224
330
|
temporalMetadata;
|
|
225
331
|
health;
|
|
332
|
+
suppression;
|
|
226
333
|
body;
|
|
227
334
|
constructor(
|
|
228
335
|
/** Normalised `{ memory, score, matchedVia }` hits. */
|
|
@@ -234,12 +341,18 @@ class RenderableSearchResult {
|
|
|
234
341
|
/** `meta.temporalMetadata`, when present. */
|
|
235
342
|
temporalMetadata,
|
|
236
343
|
/** Retrieval health. Always populated. */
|
|
237
|
-
health,
|
|
344
|
+
health,
|
|
345
|
+
/**
|
|
346
|
+
* Anchor-gate suppression (#5450). Always populated, and deliberately NOT
|
|
347
|
+
* folded into `health`: a suppressed empty is not a branch failure.
|
|
348
|
+
*/
|
|
349
|
+
suppression, body) {
|
|
238
350
|
this.results = results;
|
|
239
351
|
this.total = total;
|
|
240
352
|
this.searchMethod = searchMethod;
|
|
241
353
|
this.temporalMetadata = temporalMetadata;
|
|
242
354
|
this.health = health;
|
|
355
|
+
this.suppression = suppression;
|
|
243
356
|
this.body = body;
|
|
244
357
|
}
|
|
245
358
|
/**
|
|
@@ -255,7 +368,7 @@ class RenderableSearchResult {
|
|
|
255
368
|
const b = (body ?? {});
|
|
256
369
|
const results = normaliseResults(b.data);
|
|
257
370
|
const meta = b.meta;
|
|
258
|
-
return new RenderableSearchResult(results, typeof meta?.total === 'number' ? meta.total : results.length, typeof meta?.searchMethod === 'string' ? meta.searchMethod : undefined, meta?.temporalMetadata, readDegradation(meta), b);
|
|
371
|
+
return new RenderableSearchResult(results, typeof meta?.total === 'number' ? meta.total : results.length, typeof meta?.searchMethod === 'string' ? meta.searchMethod : undefined, meta?.temporalMetadata, readDegradation(meta), readAnchorSuppression(meta), b);
|
|
259
372
|
}
|
|
260
373
|
/**
|
|
261
374
|
* Map a `/api/memories` list body (recap's no-query path). The list endpoint
|
|
@@ -265,7 +378,7 @@ class RenderableSearchResult {
|
|
|
265
378
|
static fromListResponse(body) {
|
|
266
379
|
const b = (body ?? {});
|
|
267
380
|
const results = Object.freeze((Array.isArray(b.data) ? b.data : []).map((m) => ({ memory: m })));
|
|
268
|
-
return new RenderableSearchResult(results, results.length, undefined, undefined, HEALTHY, b);
|
|
381
|
+
return new RenderableSearchResult(results, results.length, undefined, undefined, HEALTHY, NOT_SUPPRESSED, b);
|
|
269
382
|
}
|
|
270
383
|
/**
|
|
271
384
|
* The JSON/YAML payload: the response body with results normalised, plus a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderable-retrieval.js","sourceRoot":"","sources":["../../src/lib/renderable-retrieval.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderable-retrieval.js","sourceRoot":"","sources":["../../src/lib/renderable-retrieval.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;;;AA+NH,wDAUC;AAMD,wDAKC;AAGD,8DAEC;AAmCD,wDASC;AAMD,wDAMC;AAGD,8DAKC;AA3QD,6EAA6E;AAChE,QAAA,eAAe,GAAG,sBAAsB,CAAC;AAEtD,6EAA6E;AAChE,QAAA,wBAAwB,GAAG,oCAAoC,CAAC;AAE7E;;;GAGG;AACU,QAAA,iBAAiB,GAAG,mCAAmC,CAAC;AAErE,MAAM,OAAO,GAAqB,MAAM,CAAC,MAAM,CAAC;IAC9C,QAAQ,EAAE,KAAK;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAA6B;CACxD,CAAC,CAAC;AAEH,MAAM,cAAc,GAA2B,MAAM,CAAC,MAAM,CAAC;IAC3D,UAAU,EAAE,KAAK;IACjB,cAAc,EAAE,CAAC;CAClB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AACpD,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,SAAS,QAAQ,CAAC,GAAY;IAC5B,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,GAAY;IACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC;IACjD,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,MAAM,IAAI,GACR,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAa,EAAE,IAAI,IAAK,KAAa,EAAE,MAAM,CAAC,CAAC;QACvF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC1E,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAE,KAAa,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,GAAG,CAAC,MAAM,IAAI,gBAAgB;YAAE,MAAM;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,SAAkB;IACzC,MAAM,CAAC,GAAG,SAAgF,CAAC;IAC3F,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IACvE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,qBAAqB,CAAC,SAAkB;IAC/C,MAAM,CAAC,GAAG,SAGG,CAAC;IACd,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,cAAc,CAAC;IACvD,MAAM,GAAG,GAAG,CAAC,CAAC,wBAAwB,CAAC;IACvC,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,IAAI,CAAC,CAAC,oBAAoB,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC;IAC1E,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,SAAkB;IAChD,MAAM,CAAC,GAAG,SAGG,CAAC;IACd,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IACvE,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,CAAC,GAAY,EAAE,MAA2B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,OAAO;QAChC,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;YACvB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC1E,IAAI,QAAQ,CAAC,MAAM,IAAI,gBAAgB;gBAAE,OAAO;YAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC;IACF,OAAO,CAAC,CAAC,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IACvC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,iFAAiF;AACjF,SAAS,aAAa,CAAC,MAAwB;IAC7C,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,qBAAqB,CAC5B,SAAkB,EAClB,MAAwB;IAExB,MAAM,CAAC,GAAG,SAAoC,CAAC;IAC/C,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IACvC,OAAO,EAAE,GAAG,CAAC,EAAE,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,SAAkB,EAClB,MAAwB;IAExB,MAAM,CAAC,GAAG,SAAoC,CAAC;IAC/C,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,MAA2B,EAAE,EAAE,CAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxE,OAAO;QACL,GAAG,CAAC;QACJ,GAAG,CAAC,kBAAkB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,MAAwB;IAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;QACzB,CAAC,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACxC,CAAC,CAAC,uCAAuC,CAAC;IAC5C,OAAO,CACL,GAAG,uBAAe,MAAM,MAAM,gDAAgD;QAC9E,iCAAiC,CAClC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,MAAwB;IAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,OAAO,GAAG,uBAAe,GAAG,MAAM,kCAAkC,CAAC;AACvE,CAAC;AAED,+DAA+D;AAC/D,SAAgB,yBAAyB,CAAC,MAAwB;IAChE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,gCAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,eAAe,CAAC,WAAmC;IAC1D,IAAI,WAAW,CAAC,cAAc,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACtE,OAAO,WAAW,CAAC,cAAc,GAAG,CAAC;QACnC,CAAC,CAAC,GAAG,WAAW,CAAC,cAAc,yBAAyB;QACxD,CAAC,CAAC,wBAAwB,CAAC;AAC/B,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,sBAAsB,CAAC,WAAmC;IACxE,IAAI,CAAC,WAAW,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,CACL,GAAG,yBAAiB,MAAM,eAAe,CAAC,WAAW,CAAC,gCAAgC;QACtF,uFAAuF;QACvF,yFAAyF;QACzF,uEAAuE;QACvE,gCAAgC,CACjC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,WAAmC;IACxE,IAAI,CAAC,WAAW,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,CACL,GAAG,yBAAiB,MAAM,eAAe,CAAC,WAAW,CAAC,4BAA4B;QAClF,wEAAwE,CACzE,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAgB,yBAAyB,CAAC,WAAmC;IAC3E,IAAI,CAAC,WAAW,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IACvC,OAAO,WAAW,CAAC,cAAc,GAAG,CAAC;QACnC,CAAC,CAAC,MAAM,WAAW,CAAC,cAAc,kCAAkC;QACpE,CAAC,CAAC,4CAA4C,CAAC;AACnD,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY;IACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAgC,CAAC;IACjF,OAAO,MAAM,CAAC,MAAM,CAClB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CACjB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAC9E,CACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAa,sBAAsB;IAGtB;IAEA;IAEA;IAEA;IAEA;IAKA;IACQ;IAhBnB;IACE,uDAAuD;IAC9C,OAAoC;IAC7C,oEAAoE;IAC3D,KAAa;IACtB,yCAAyC;IAChC,YAAgC;IACzC,6CAA6C;IACpC,gBAAqB;IAC9B,0CAA0C;IACjC,MAAwB;IACjC;;;OAGG;IACM,WAAmC,EAC3B,IAA6B;QAdrC,YAAO,GAAP,OAAO,CAA6B;QAEpC,UAAK,GAAL,KAAK,CAAQ;QAEb,iBAAY,GAAZ,YAAY,CAAoB;QAEhC,qBAAgB,GAAhB,gBAAgB,CAAK;QAErB,WAAM,GAAN,MAAM,CAAkB;QAKxB,gBAAW,GAAX,WAAW,CAAwB;QAC3B,SAAI,GAAJ,IAAI,CAAyB;IAC7C,CAAC;IAEJ;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,IAAa;QAClC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAwB,CAAC;QAC9C,MAAM,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAuC,CAAC;QACvD,OAAO,IAAI,sBAAsB,CAC/B,OAAO,EACP,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAC7D,OAAO,IAAI,EAAE,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EACtE,IAAI,EAAE,gBAAgB,EACtB,eAAe,CAAC,IAAI,CAAC,EACrB,qBAAqB,CAAC,IAAI,CAAC,EAC3B,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAa;QACnC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAwB,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAC3B,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CACxC,CAAC;QACjC,OAAO,IAAI,sBAAsB,CAC/B,OAAO,EACP,OAAO,CAAC,MAAM,EACd,SAAS,EACT,SAAS,EACT,OAAO,EACP,cAAc,EACd,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,cAAc;QACZ,sEAAsE;QACtE,qEAAqE;QACrE,gBAAgB;QAChB,OAAO;YACL,GAAG,IAAI,CAAC,IAAI;YACZ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;gBAC9B,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;gBAC9D,CAAC,CAAC,EAAE,CAAC;YACP,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC;CACF;AAlFD,wDAkFC;AAED;;;;;;GAMG;AACH,MAAa,sBAAsB;IAEtB;IAEA;IACA;IACA;IACA;IACA;IACA;IACQ;IATnB,YACW,MAAc;IACvB,2EAA2E;IAClE,QAA6B,EAC7B,OAAc,EACd,QAA2B,EAC3B,QAA2B,EAC3B,uBAA4B,EAC5B,MAAwB,EAChB,IAA6B;QARrC,WAAM,GAAN,MAAM,CAAQ;QAEd,aAAQ,GAAR,QAAQ,CAAqB;QAC7B,YAAO,GAAP,OAAO,CAAO;QACd,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,4BAAuB,GAAvB,uBAAuB,CAAK;QAC5B,WAAM,GAAN,MAAM,CAAkB;QAChB,SAAI,GAAJ,IAAI,CAAyB;IAC7C,CAAC;IAEJ,iFAAiF;IACjF,MAAM,CAAC,eAAe,CAAC,IAAa;QAClC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAwB,CAAC;QAC9C,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAwB,CAAC;QAC3D,OAAO,IAAI,sBAAsB,CAC/B,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAC5C,QAAQ,EACR,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EACzC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAClD,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAClD,CAAC,CAAC,uBAAuB,EACzB,eAAe,CAAC,QAAQ,CAAC,EACzB,CAAC,CACF,CAAC;IACJ,CAAC;IAED,cAAc;QACZ,OAAO;YACL,GAAG,IAAI,CAAC,IAAI;YACZ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAClC,CAAC,CAAC,EAAE,QAAQ,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;gBACtE,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC;CACF;AAtCD,wDAsCC;AAED;;;;;GAKG;AACH,MAAa,yBAAyB;IAGzB;IACA;IAHX;IACE,+DAA+D;IACtD,IAAyB,EACzB,MAAwB;QADxB,SAAI,GAAJ,IAAI,CAAqB;QACzB,WAAM,GAAN,MAAM,CAAkB;IAChC,CAAC;IAEJ,MAAM,CAAC,eAAe,CAAC,IAAa;QAClC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAwB,CAAC;QAC9C,OAAO,IAAI,yBAAyB,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,cAAc;QACZ,OAAO;YACL,GAAG,IAAI,CAAC,IAAI;YACZ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;gBAC9B,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;gBAC9D,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC;CACF;AArBD,8DAqBC"}
|
|
@@ -201,6 +201,263 @@ $(echo "$RECENT_RESULTS" | head -c 1500)"
|
|
|
201
201
|
# Truncate total content to ~5000 chars
|
|
202
202
|
CONTENT=$(echo "$CONTENT" | head -c 5000)
|
|
203
203
|
|
|
204
|
+
# ── 6b. Resolve project scope (codeContext) ──────────────────────────────
|
|
205
|
+
# Auto-captured memories carried no scope at all, so they leaked into every
|
|
206
|
+
# team's scoped searches and polluted build_context (#5158, #4957). PR #3281
|
|
207
|
+
# fixed that for the commit path only; this is the same resolution for the
|
|
208
|
+
# capture hooks, using the same sources and the same precedence.
|
|
209
|
+
#
|
|
210
|
+
# Mirrors resolveCommitCodeContext() in cli/src/lib/commit-context/code-context.ts:
|
|
211
|
+
# 1. MX_CODE_CONTEXT env var — operator-controlled, higher trust. It wins over
|
|
212
|
+
# the file (CWE-345): a checked-in file from an untrusted clone must not
|
|
213
|
+
# override the scope the operator set explicitly.
|
|
214
|
+
# 2. <projectRoot>/.mx-code-context.json — repo-controlled, lower trust.
|
|
215
|
+
# 3. Neither present or neither usable -> NO scope. The memory is created
|
|
216
|
+
# unlabeled, exactly as it was before this block existed. No default is
|
|
217
|
+
# invented: a guessed label is invisible to the scope that should see it
|
|
218
|
+
# and visible to one that should not, which is worse than no label.
|
|
219
|
+
#
|
|
220
|
+
# Every command in this block must end up returning 0. The EXIT/ERR trap set in
|
|
221
|
+
# section 4 exits the hook, so a non-zero status here would discard the
|
|
222
|
+
# pre-compaction context over a missing config file — a far worse regression
|
|
223
|
+
# than the unlabeled memories this fixes. The absent-config path is the common
|
|
224
|
+
# one today.
|
|
225
|
+
CODE_CONTEXT_MAX_BYTES=65536
|
|
226
|
+
|
|
227
|
+
# Walk up for the git project root, mirroring findProjectRoot() in
|
|
228
|
+
# cli/src/lib/commit-context/local-cache.ts. `-e`, not `-d`: inside a git
|
|
229
|
+
# worktree `.git` is a FILE, and the worktree root — not the main repo — is the
|
|
230
|
+
# project root (the TS uses fs.existsSync, which makes no such distinction).
|
|
231
|
+
find_project_root() { # <start-dir> -> project root on stdout, or nothing
|
|
232
|
+
local dir
|
|
233
|
+
dir=$(cd "$1" 2>/dev/null && pwd -P) || return 0
|
|
234
|
+
while [[ -n "$dir" && "$dir" != "/" ]]; do
|
|
235
|
+
if [[ -e "$dir/.git" ]]; then
|
|
236
|
+
printf '%s' "$dir"
|
|
237
|
+
return 0
|
|
238
|
+
fi
|
|
239
|
+
dir=$(dirname "$dir" 2>/dev/null) || return 0
|
|
240
|
+
done
|
|
241
|
+
return 0
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# Keep only the six known keys whose values are non-empty strings, cap each,
|
|
245
|
+
# and emit NOTHING when nothing usable remains — so an empty or scope-free
|
|
246
|
+
# object is never passed as if it were a label. Malformed JSON makes jq exit
|
|
247
|
+
# non-zero with no output, which lands in the same "no scope" branch.
|
|
248
|
+
#
|
|
249
|
+
# `-s` (slurp) is load-bearing, not a style choice. jq accepts a STREAM of JSON
|
|
250
|
+
# documents: without `-s` the filter runs once per document and `jq -c` prints
|
|
251
|
+
# one line each, so a config holding two concatenated or newline-separated
|
|
252
|
+
# objects produced a MULTI-LINE string that was passed verbatim as one
|
|
253
|
+
# --code-context argument. parseCodeContextFlag() (cli/src/commands/memories.ts)
|
|
254
|
+
# JSON.parse()s it and process.exit(1)s before any network call. In THIS hook
|
|
255
|
+
# that loss is unrecoverable: the transcript the capture would have summarized
|
|
256
|
+
# is compacted away immediately afterwards. The `!= "{}"` guard below did not
|
|
257
|
+
# catch it either: `{"zzz":1}{"team":"b"}` normalizes to the two lines
|
|
258
|
+
# `{}` + `{"team":"b"}`, and that whole string is not `{}`. Slurping into an
|
|
259
|
+
# array and taking the first element means exactly one line can ever be emitted.
|
|
260
|
+
#
|
|
261
|
+
# The cap is 100 CODEPOINTS, deliberately below the server's 200. The server's
|
|
262
|
+
# CodeContextSchema uses Zod `.max(200)`, which counts UTF-16 code units, while
|
|
263
|
+
# jq's `[0:N]` slices by codepoint. Every astral-plane character (emoji, CJK
|
|
264
|
+
# extensions, mathematical alphanumerics) is 1 codepoint but 2 UTF-16 units, so
|
|
265
|
+
# a `[0:200]` cap emitted values of up to 400 units — over the server maximum,
|
|
266
|
+
# a 400 from the API, and the same silent capture loss. Since no codepoint
|
|
267
|
+
# exceeds 2 UTF-16 units, 100 codepoints can never exceed 200 units. Scope
|
|
268
|
+
# labels are short names (product/team/service); the extra truncation is
|
|
269
|
+
# unreachable in practice, and truncating is recoverable where a rejected
|
|
270
|
+
# request is not.
|
|
271
|
+
normalize_code_context() { # JSON on stdin -> normalized JSON object, or nothing
|
|
272
|
+
local out
|
|
273
|
+
out=$(jq -s -c '
|
|
274
|
+
(.[0] // {}) as $raw
|
|
275
|
+
| if ($raw | type) == "object" then
|
|
276
|
+
reduce ("product","repo","service","component","team","role") as $k ({};
|
|
277
|
+
if ($raw[$k] | type) == "string" and ($raw[$k] | length) > 0
|
|
278
|
+
then .[$k] = ($raw[$k][0:100])
|
|
279
|
+
else . end)
|
|
280
|
+
else {} end
|
|
281
|
+
' 2>/dev/null) || return 0
|
|
282
|
+
# The newline test is belt-and-braces: `-s` already guarantees one document,
|
|
283
|
+
# and jq -c escapes newlines inside string values. Nothing multi-line may ever
|
|
284
|
+
# reach --code-context again, whatever the filter above does.
|
|
285
|
+
if [[ -n "$out" && "$out" != "{}" && "$out" != "null" && "$out" != *$'\n'* ]]; then
|
|
286
|
+
printf '%s' "$out"
|
|
287
|
+
fi
|
|
288
|
+
return 0
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
CODE_CONTEXT_JSON=""
|
|
292
|
+
|
|
293
|
+
# 1. Env var. Tested for presence only — the value is never echoed or logged.
|
|
294
|
+
if [[ -n "${MX_CODE_CONTEXT:-}" ]]; then
|
|
295
|
+
CODE_CONTEXT_JSON=$(printf '%s' "$MX_CODE_CONTEXT" | normalize_code_context) || CODE_CONTEXT_JSON=""
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
# 2. Repo file — consulted only when the env var yielded nothing usable.
|
|
299
|
+
if [[ -z "$CODE_CONTEXT_JSON" ]]; then
|
|
300
|
+
# ORDER IS LOAD-BEARING: harness-provided project dir, then the worktree path,
|
|
301
|
+
# then the cwd. Each source is TRIED IN TURN, and the transcript's directory
|
|
302
|
+
# is not a source at all. Both properties are corrections to earlier forms and
|
|
303
|
+
# both are pinned by the suite; read this before rewriting the expression.
|
|
304
|
+
#
|
|
305
|
+
# WHY EACH SOURCE IS TRIED SEPARATELY. The earlier form collapsed all three
|
|
306
|
+
# into ONE call: `find_project_root "${CLAUDE_PROJECT_DIR:-${CLAUDE_WORKTREE_PATH:-$(pwd)}}"`.
|
|
307
|
+
# `:-` substitutes only when a variable is UNSET or EMPTY — never when it is
|
|
308
|
+
# set to something useless. So a CLAUDE_PROJECT_DIR that is set but resolves
|
|
309
|
+
# to no repository (a stale path, a deleted directory, a path outside any
|
|
310
|
+
# checkout) consumed the single attempt and the cwd was NEVER consulted.
|
|
311
|
+
# Measured: CLAUDE_PROJECT_DIR=/proc and =/nonexistent/zz each produced
|
|
312
|
+
# {"product":"home","team":"DOTFILES-WRONG-SCOPE"} from the $HOME config.
|
|
313
|
+
# The loop below consults the next source instead, which `:-` cannot express.
|
|
314
|
+
#
|
|
315
|
+
# WHAT IS ACTUALLY KNOWN ABOUT CLAUDE_PROJECT_DIR IN THE CUSTOMER CONTEXT.
|
|
316
|
+
# It is the documented hook variable, and it is the right first source when it
|
|
317
|
+
# is present. This repo does NOT evidence that it is set for hooks installed
|
|
318
|
+
# by `mx mcp install`: every other reference to it is fleet code, and it was
|
|
319
|
+
# measured UNSET in a live Claude Code tool process (a tool process is not a
|
|
320
|
+
# hook process, so that is not disproof — but it is not confirmation either).
|
|
321
|
+
# The expression below is therefore designed to be CORRECT WHEN IT IS ABSENT:
|
|
322
|
+
# an unset or empty value is skipped by the loop and the cwd carries the case.
|
|
323
|
+
# Do not restructure this so that a present CLAUDE_PROJECT_DIR is required.
|
|
324
|
+
# WHY THE TRANSCRIPT DIRECTORY IS NOT A SOURCE. It has no legitimate resolving
|
|
325
|
+
# power, and the reason is DEPTH-INDEPENDENT — do not restate it as a claim
|
|
326
|
+
# about the transcript's nesting. An earlier version of this comment argued
|
|
327
|
+
# from a flat ~/.claude/projects/<slug>/<id>.jsonl layout and enumerated the
|
|
328
|
+
# three directories a walk could reach. That premise is false here. Measured
|
|
329
|
+
# on this machine: transcripts sit at BOTH depth 2 and depth 4 under
|
|
330
|
+
# ~/.claude/projects — 310 at depth 2, 5621 deeper — so any argument of the
|
|
331
|
+
# form "the walk can only ever reach these three named directories" does not
|
|
332
|
+
# hold. The premise that does hold, and that does not depend on depth:
|
|
333
|
+
#
|
|
334
|
+
# .git anywhere under ~/.claude, any depth: 0 (also no .hg, no .svn)
|
|
335
|
+
#
|
|
336
|
+
# An upward walk from any transcript directory traverses only directories
|
|
337
|
+
# inside ~/.claude, none of which carries a repository marker, so it cannot
|
|
338
|
+
# terminate inside that subtree at any depth. That leaves $HOME as its ONLY
|
|
339
|
+
# reachable non-empty outcome, which is precisely the defect this block exists
|
|
340
|
+
# to prevent: keeping dotfiles in git is common, so $HOME/.git exists on many
|
|
341
|
+
# machines, and with $HOME/.mx-code-context.json present every capture from
|
|
342
|
+
# every worktree on the machine was labelled from the home config. A
|
|
343
|
+
# confidently wrong label is worse than no label — invisible to the scope that
|
|
344
|
+
# should see it, visible to one that must not. Do not reintroduce it.
|
|
345
|
+
#
|
|
346
|
+
# CAVEAT, stated because this is a claim about a directory OUTSIDE this
|
|
347
|
+
# repository: it could stop being true, and nothing in this codebase would
|
|
348
|
+
# notice if a repository ever appeared under ~/.claude. Removing the leg does
|
|
349
|
+
# not depend on the caveat holding — the leg is simply gone — but any future
|
|
350
|
+
# argument to reinstate it must re-measure rather than cite this line.
|
|
351
|
+
#
|
|
352
|
+
# WHY $HOME IS REFUSED OUTRIGHT, AND WHY BOTH SIDES ARE CANONICALIZED. Belt
|
|
353
|
+
# and braces for the residual where the cwd itself is $HOME or a directory
|
|
354
|
+
# beneath it whose nearest .git is $HOME's. It also closes a consequence that
|
|
355
|
+
# is easy to miss: CC_ROOT is the basis of the symlink containment test below,
|
|
356
|
+
# so a CC_ROOT of $HOME silently widens "contained in the project" to
|
|
357
|
+
# "anywhere in the home directory", and $HOME/.mx-code-context.json symlinked
|
|
358
|
+
# to any other file under $HOME would resolve and be used. The cost is not
|
|
359
|
+
# supporting a user whose real project IS their home directory; that is the
|
|
360
|
+
# same confusion we want rejected.
|
|
361
|
+
#
|
|
362
|
+
# The comparison MUST canonicalize $HOME. CC_ROOT always arrives canonical —
|
|
363
|
+
# find_project_root builds it with `cd … && pwd -P` — while $HOME arrives
|
|
364
|
+
# verbatim from the environment, so a literal `==` against "$HOME" misses on
|
|
365
|
+
# every spelling that is not byte-identical. Four spellings were measured
|
|
366
|
+
# leaking the home label through a symlinked $HOME/.mx-code-context.json: a
|
|
367
|
+
# trailing slash ("/home/x/"), a "/." suffix ("/home/x/."), $HOME set to a
|
|
368
|
+
# SYMLINK to the real home, and a cwd reached through that same symlink.
|
|
369
|
+
# Symlinked home directories are routine — macOS firmlinks, NFS corporate
|
|
370
|
+
# homes, container images mapping /home/user onto another volume — so the
|
|
371
|
+
# trigger is a normal configuration and the miss is silent: the refusal does
|
|
372
|
+
# not fire, and the containment widening above returns with it. `cd … && pwd -P`
|
|
373
|
+
# is the same primitive find_project_root uses and handles all four in one step.
|
|
374
|
+
#
|
|
375
|
+
# HOME unset, or pointing at nothing, leaves _home_real empty and no refusal
|
|
376
|
+
# fires. That is unchanged from the previous `-n "${HOME:-}"` guard, not a
|
|
377
|
+
# regression. The `|| _home_real=""` is REQUIRED, not decorative: without it a
|
|
378
|
+
# failing `cd` leaves the assignment non-zero and last on its path, which fires
|
|
379
|
+
# the ERR trap and abandons the capture.
|
|
380
|
+
#
|
|
381
|
+
# ERR-TRAP SAFETY — verified, not assumed, because a regression here fires
|
|
382
|
+
# `trap 'exit 0' ERR` and silently abandons the capture. The loop body's only
|
|
383
|
+
# status-bearing statement is a `$(...)` assignment of find_project_root, which
|
|
384
|
+
# returns 0 on every path including the `cd` failure. The break is written as
|
|
385
|
+
# an `if` block for the same reason the $HOME refusal is. The earlier one-line
|
|
386
|
+
# form `[[ -n "$CC_ROOT" ]] && break` returns 1 whenever the loop CONTINUES —
|
|
387
|
+
# an earlier version of this comment claimed it returned 0, which was wrong. It
|
|
388
|
+
# was safe only POSITIONALLY: as a non-final command of an `&&` list it is
|
|
389
|
+
# exempt under the errexit rules, so nothing fired. That safety depends on
|
|
390
|
+
# where the statement sits and would evaporate the moment this loop became the
|
|
391
|
+
# last statement of a function: the function would return 1 and any `$(...)`
|
|
392
|
+
# call of it would fire the trap. The `if` form returns 0 and removes the
|
|
393
|
+
# positional dependence.
|
|
394
|
+
#
|
|
395
|
+
# The same reasoning is why the $HOME refusal is an `if` block ON PURPOSE: the
|
|
396
|
+
# one-line `[[ "$CC_ROOT" == "$_home_real" ]] && CC_ROOT=""` returns 1 when the
|
|
397
|
+
# test is false, and was measured firing the ERR trap when it landed last in an
|
|
398
|
+
# enclosing block. `pwd 2>/dev/null` keeps a deleted cwd from printing "error
|
|
399
|
+
# retrieving current directory" onto the hook's real stderr. This safety comes
|
|
400
|
+
# from find_project_root always returning 0, not from this hook omitting
|
|
401
|
+
# `set -E`, so it survives someone adding `set -E` later. Do not introduce a
|
|
402
|
+
# bare command on this path.
|
|
403
|
+
CC_ROOT=""
|
|
404
|
+
for _cand in "${CLAUDE_PROJECT_DIR:-}" "${CLAUDE_WORKTREE_PATH:-}" "$(pwd 2>/dev/null)"; do
|
|
405
|
+
[[ -n "$_cand" ]] || continue
|
|
406
|
+
CC_ROOT=$(find_project_root "$_cand")
|
|
407
|
+
if [[ -n "$CC_ROOT" ]]; then break; fi
|
|
408
|
+
done
|
|
409
|
+
_home_real=$(cd "${HOME:-/nonexistent}" 2>/dev/null && pwd -P) || _home_real=""
|
|
410
|
+
if [[ -n "$_home_real" && "$CC_ROOT" == "$_home_real" ]]; then
|
|
411
|
+
CC_ROOT=""
|
|
412
|
+
fi
|
|
413
|
+
CC_FILE="${CC_ROOT}/.mx-code-context.json"
|
|
414
|
+
if [[ -n "$CC_ROOT" ]]; then
|
|
415
|
+
# CWE-59. `-f`, `-r` and the read all follow symlinks, so a repo could check
|
|
416
|
+
# in `.mx-code-context.json` as a symlink to any file on the user's machine
|
|
417
|
+
# and the six allowlisted keys of it would be uploaded to the user's own
|
|
418
|
+
# MemNexus account. Resolve the path and require the result to stay inside
|
|
419
|
+
# the project root — the containment this same hook already applies to the
|
|
420
|
+
# transcript path earlier. Read through the RESOLVED path, so the link is
|
|
421
|
+
# not traversed a second time.
|
|
422
|
+
CC_REAL=$(realpath "$CC_FILE" 2>/dev/null || printf '')
|
|
423
|
+
if [[ -n "$CC_REAL" && "$CC_REAL" == "$CC_ROOT"/* && -f "$CC_REAL" && -r "$CC_REAL" ]]; then
|
|
424
|
+
# One open, bounded at the source (same 64KB bound as the TS resolver).
|
|
425
|
+
# The previous form size-checked with `wc -c` and then re-opened for jq:
|
|
426
|
+
# two opens on a path an untrusted repo controls, so a concurrent writer
|
|
427
|
+
# could present a small file to `wc` and a huge one to `jq` (TOCTOU) on a
|
|
428
|
+
# hot path. `head -c` bounds the read itself, which changes >64KB from
|
|
429
|
+
# "skipped" to "truncated, then rejected as invalid JSON" — the same
|
|
430
|
+
# observable outcome, no scope.
|
|
431
|
+
#
|
|
432
|
+
# `2>/dev/null` precedes the input redirect ON PURPOSE. Redirections apply
|
|
433
|
+
# left to right, so with `<"$CC_REAL" 2>/dev/null` a file that turned
|
|
434
|
+
# unreadable between the `-r` test and the open makes bash print the full
|
|
435
|
+
# path and "Permission denied" to the hook's REAL stderr, before the
|
|
436
|
+
# discard takes effect. Verified: reversing these two words reintroduces
|
|
437
|
+
# that leak. Do not reorder.
|
|
438
|
+
#
|
|
439
|
+
# The bytes are PIPED into jq, never routed through a variable. Bash
|
|
440
|
+
# strips NUL bytes out of command-substitution output and warns while
|
|
441
|
+
# doing it — from the parent shell reading the substitution, so the
|
|
442
|
+
# `2>/dev/null` above does not suppress that warning. Via a variable,
|
|
443
|
+
# `{"team":"a<NUL>b"}` printed a warning naming this script and line to
|
|
444
|
+
# the hook's real stderr, and then RESOLVED to team "ab": input the file
|
|
445
|
+
# does not contain, silently repaired before validation instead of
|
|
446
|
+
# rejected by it. Piping keeps the NUL inside jq, which rejects the
|
|
447
|
+
# document as malformed. Do not reintroduce an intermediate variable.
|
|
448
|
+
CODE_CONTEXT_JSON=$(head -c "$CODE_CONTEXT_MAX_BYTES" 2>/dev/null <"$CC_REAL" | normalize_code_context) || CODE_CONTEXT_JSON=""
|
|
449
|
+
fi
|
|
450
|
+
fi
|
|
451
|
+
fi
|
|
452
|
+
|
|
453
|
+
# Nothing resolved -> pass nothing at all, so the create command line is
|
|
454
|
+
# byte-identical to the pre-scope version. The `[@]+` guard keeps an empty array
|
|
455
|
+
# safe to expand under `set -u` on bash < 4.4.
|
|
456
|
+
CODE_CONTEXT_ARGS=()
|
|
457
|
+
if [[ -n "$CODE_CONTEXT_JSON" ]]; then
|
|
458
|
+
CODE_CONTEXT_ARGS=(--code-context "$CODE_CONTEXT_JSON")
|
|
459
|
+
fi
|
|
460
|
+
|
|
204
461
|
# ── 7. Save memory (with timeout — never block compaction) ───────────────
|
|
205
462
|
TIMEOUT_CMD=""
|
|
206
463
|
if command -v timeout >/dev/null 2>&1; then
|
|
@@ -219,6 +476,7 @@ $TIMEOUT_CMD mx memories create \
|
|
|
219
476
|
--conversation-id "NEW" \
|
|
220
477
|
--content "$CONTENT" \
|
|
221
478
|
--topics "auto-captured,precompact" \
|
|
479
|
+
"${CODE_CONTEXT_ARGS[@]+"${CODE_CONTEXT_ARGS[@]}"}" \
|
|
222
480
|
>/dev/null 2>&1 || CREATE_STATUS=$?
|
|
223
481
|
|
|
224
482
|
if [[ "$CREATE_STATUS" -ne 0 ]]; then
|