pi-smart-compact 9.5.0 → 9.6.1
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/ARCHITECTURE.md +7 -5
- package/CHANGELOG.md +40 -0
- package/README.md +35 -19
- package/dist/app/global-settings-runtime.d.ts +7 -0
- package/dist/app/global-settings-runtime.d.ts.map +1 -0
- package/dist/app/register-context-tools.d.ts +4 -1
- package/dist/app/register-context-tools.d.ts.map +1 -1
- package/dist/app/register-smart-compact-command.d.ts +3 -1
- package/dist/app/register-smart-compact-command.d.ts.map +1 -1
- package/dist/app/run-context.d.ts +3 -3
- package/dist/app/run-context.d.ts.map +1 -1
- package/dist/app/smart-compact-policy.d.ts +4 -1
- package/dist/app/smart-compact-policy.d.ts.map +1 -1
- package/dist/app/steps/tier.d.ts +5 -4
- package/dist/app/steps/tier.d.ts.map +1 -1
- package/dist/constants.d.ts +43 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/domain/tool-semantics.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1830 -560
- package/dist/infra/ai-messages.d.ts.map +1 -1
- package/dist/infra/fs.d.ts +2 -1
- package/dist/infra/fs.d.ts.map +1 -1
- package/dist/phases/explore.d.ts.map +1 -1
- package/dist/phases/synthesize.d.ts +5 -0
- package/dist/phases/synthesize.d.ts.map +1 -1
- package/dist/phases/verify.d.ts.map +1 -1
- package/dist/provider-eval.js +157 -54
- package/dist/provider-scenario-eval.js +162 -57
- package/dist/telemetry-report.js +125 -22
- package/dist/ui/overlays.d.ts.map +1 -1
- package/dist/ui/settings-complex.d.ts +9 -0
- package/dist/ui/settings-complex.d.ts.map +1 -0
- package/dist/ui/settings-overlay.d.ts +43 -3
- package/dist/ui/settings-overlay.d.ts.map +1 -1
- package/dist/utils/config.d.ts +14 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/file-needles.d.ts +24 -0
- package/dist/utils/file-needles.d.ts.map +1 -1
- package/dist/utils/file-ref-detect.d.ts +6 -1
- package/dist/utils/file-ref-detect.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts +1 -0
- package/dist/utils/helpers.d.ts.map +1 -1
- package/package.json +5 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-messages.d.ts","sourceRoot":"","sources":["../../src/infra/ai-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ai-messages.d.ts","sourceRoot":"","sources":["../../src/infra/ai-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAIpE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,cAAc,GAAG,UAAU,EAAE,CAE3F"}
|
package/dist/infra/fs.d.ts
CHANGED
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
* `atomicWriteFile` for new async-friendly callers (background metrics).
|
|
26
26
|
*
|
|
27
27
|
* Lock acquisition is fail-closed: callers never continue an append/trim
|
|
28
|
-
* without ownership. Locks
|
|
28
|
+
* without ownership. Locks are never stolen on elapsed time because a live,
|
|
29
|
+
* slow owner must not overlap a successor.
|
|
29
30
|
*/
|
|
30
31
|
/** Ensure a private directory exists and normalize an existing target. */
|
|
31
32
|
export declare function ensureDir(dir: string): void;
|
package/dist/infra/fs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/infra/fs.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/infra/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAWH,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAG3C;AAWD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAYnF;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAW9F;AA2CD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAI1D;AAYD,+EAA+E;AAC/E,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CASrE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAoCtF;AAED,+EAA+E;AAC/E,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC1G;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAa,GAAG,CAAC,EAAE,CAoB1F;AAED,oEAAoE;AACpE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBxF;AAGD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CASxD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,IAAI,CAElF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/phases/explore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,KAAK,EACL,GAAG,EAKH,eAAe,EAChB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EAElB,MAAM,aAAa,CAAC;AAcrB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAIjE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAuBpD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAqBvE;
|
|
1
|
+
{"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/phases/explore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,KAAK,EACL,GAAG,EAKH,eAAe,EAChB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EAElB,MAAM,aAAa,CAAC;AAcrB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAIjE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAuBpD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAqBvE;AAsHD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAC1D,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,iBAAuB,GAC9B,MAAM,CA6MR;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,UAAU,EAAE,GACxB,iBAAiB,CAkDnB;AA6DD,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,UAAU,EAAE,GACxB,iBAAiB,CAgCnB;AAED,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,UAAU,EAAE,GACxB,iBAAiB,CAWnB;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,UAAU,EAAE,EACzB,UAAU,EAAE,oBAAoB,EAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,CAAC,EAAE,WAAW,EACpB,SAAS,SAAyB,EAClC,MAAM,CAAC,EAAE,CACP,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,KAC5C,IAAI,EACT,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC;IACT,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAkTD"}
|
|
@@ -5,6 +5,11 @@ import type { Model, Api, ProviderHeaders } from "@earendil-works/pi-ai";
|
|
|
5
5
|
import type { LlmMessage, LlmChunk, ChunkSummary, StructuredExtraction, ExplorationReport, ProfileConfig, CompactionState } from "../types.ts";
|
|
6
6
|
import { type TokenEstimator } from "../utils/tokens.ts";
|
|
7
7
|
import type { SmartCompactServices } from "../infra/services.ts";
|
|
8
|
+
/** A provider response completed, but did not satisfy the batch-output contract. */
|
|
9
|
+
export declare class BatchSummaryFormatError extends Error {
|
|
10
|
+
readonly name = "BatchSummaryFormatError";
|
|
11
|
+
constructor(reason: string);
|
|
12
|
+
}
|
|
8
13
|
export declare function chunkLlmMessages(msgs: LlmMessage[], boundaries: import("../types.ts").TopicBoundary[], pc: ProfileConfig, estimator?: TokenEstimator, focus?: string): LlmChunk[];
|
|
9
14
|
export declare function singlePassCompact(convText: string, extraction: StructuredExtraction, report: ExplorationReport | null, prevContext: string, model: Model<Api>, auth: {
|
|
10
15
|
apiKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../src/phases/synthesize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,MAAM,aAAa,CAAC;AAYrB,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAU5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"synthesize.d.ts","sourceRoot":"","sources":["../../src/phases/synthesize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,KAAK,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,MAAM,aAAa,CAAC;AAYrB,OAAO,EAGN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAU5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AA0BjE,oFAAoF;AACpF,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,6BAA6B;IAE1C,YAAY,MAAM,EAAE,MAAM,EAEzB;CACD;AAoRD,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,UAAU,EAAE,EAClB,UAAU,EAAE,OAAO,aAAa,EAAE,aAAa,EAAE,EACjD,EAAE,EAAE,aAAa,EACjB,SAAS,GAAE,cAAqC,EAChD,KAAK,CAAC,EAAE,MAAM,GACZ,QAAQ,EAAE,CAwGZ;AAED,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAA;CAAE,CAAC,CA2D3C;AAED,wBAAsB,cAAc,CACnC,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,EAAE,oBAAoB,EAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,eAAe,CAAC,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAyKzB;AA6BD,wBAAsB,WAAW,CAChC,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,EAC/B,KAAK,CAAC,EAAE,MAAM,EACd,UAAU,GAAE,eAAe,GAAG,IAAW,GACvC,OAAO,CAAC,MAAM,CAAC,CAmDjB;AAED,wBAAgB,gBAAgB,CAC/B,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,oBAAoB,EAChC,QAAQ,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,EAChD,YAAY,GAAE,MAAc,EAC5B,UAAU,GAAE,eAAe,GAAG,IAAW,GACvC,MAAM,CAwIR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,CAiB7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/phases/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACX,KAAK,EACL,GAAG,EACH,eAAe,EAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,UAAU,EACV,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/phases/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACX,KAAK,EACL,GAAG,EACH,eAAe,EAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,UAAU,EACV,MAAM,aAAa,CAAC;AAoCrB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,MAAM,WAAW,oBAAoB;IACpC,cAAc,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AA8SD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAkClE;AAED,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,kBAAkB,GACxB,MAAM,GAAG,IAAI,CAcf;AAED,wFAAwF;AACxF,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YACC,MAAM,EAAE,kBAAkB,EAC1B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,qBAAqB,EAW5B;CACD;AAwUD,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAK1E;AAED,qGAAqG;AACrG,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,QAAQ,GAAE,oBAAyB,EACnC,SAAS,SAAI,GACX;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAyB7E;AAiYD,wBAAgB,aAAa,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,QAAQ,GAAE,oBAAyB,GACjC,kBAAkB,CA2CpB;AAED,iHAAiH;AACjH,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EAAE,EACvB,UAAU,EAAE,oBAAoB,EAChC,UAAU,GAAE,eAAe,GAAG,IAAW,EACzC,QAAQ,GAAE,oBAAyB,GACjC,MAAM,CA4MR;AA2CD,wBAAsB,YAAY,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EAAE,EACvB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,eAAe,CAAA;CAAE,EACnD,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,CA2DjB"}
|
package/dist/provider-eval.js
CHANGED
|
@@ -156,7 +156,7 @@ function formatProviderEvaluation(report) {
|
|
|
156
156
|
import fs2 from "fs";
|
|
157
157
|
|
|
158
158
|
// src/constants.ts
|
|
159
|
-
var VERSION = "9.
|
|
159
|
+
var VERSION = "9.6.1";
|
|
160
160
|
var SETTLED_TRIGGER_COOLDOWN_MS = 10 * 60000;
|
|
161
161
|
var COMPACT_SYSTEM_PREFIX = "You are an expert conversation summarizer for a coding agent. " + "Produce structured markdown summaries. " + "Follow output format exactly. " + "Use EXACT names \u2014 never paraphrase code identifiers. " + "Trust deterministic extraction data over intuition.";
|
|
162
162
|
var PROFILES = {
|
|
@@ -667,38 +667,117 @@ function buildPathNeedles(filePath) {
|
|
|
667
667
|
}
|
|
668
668
|
return needles;
|
|
669
669
|
}
|
|
670
|
-
|
|
671
|
-
|
|
670
|
+
var MAX_INDEXED_SUFFIX_CHARS = 1024;
|
|
671
|
+
function buildPathNeedleOwnershipIndex(allPaths) {
|
|
672
|
+
const owners = new Map;
|
|
673
|
+
const normalizedPaths = allPaths.map(normalizePath);
|
|
674
|
+
let hasUnindexedSuffixes = false;
|
|
675
|
+
for (const normalized of normalizedPaths) {
|
|
676
|
+
const suffixes = new Set([normalized]);
|
|
677
|
+
for (let index = 0;index < normalized.length; index++) {
|
|
678
|
+
if (normalized[index] !== "/")
|
|
679
|
+
continue;
|
|
680
|
+
if (normalized.length - index - 1 <= MAX_INDEXED_SUFFIX_CHARS) {
|
|
681
|
+
suffixes.add(normalized.slice(index + 1));
|
|
682
|
+
} else {
|
|
683
|
+
hasUnindexedSuffixes = true;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
for (const suffix of suffixes) {
|
|
687
|
+
owners.set(suffix, (owners.get(suffix) ?? 0) + 1);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
return { counts: owners, normalizedPaths, hasUnindexedSuffixes };
|
|
691
|
+
}
|
|
692
|
+
function buildUniquePathNeedlesFromIndex(filePath, owners) {
|
|
672
693
|
return buildPathNeedles(filePath).filter((needle) => {
|
|
673
|
-
|
|
674
|
-
|
|
694
|
+
if (!owners.hasUnindexedSuffixes)
|
|
695
|
+
return owners.counts.get(needle) === 1;
|
|
696
|
+
let count = 0;
|
|
697
|
+
for (const candidate of owners.normalizedPaths) {
|
|
675
698
|
if (candidate === needle || candidate.endsWith("/" + needle))
|
|
676
|
-
|
|
677
|
-
if (
|
|
699
|
+
count++;
|
|
700
|
+
if (count > 1)
|
|
678
701
|
return false;
|
|
679
702
|
}
|
|
680
|
-
return
|
|
703
|
+
return count === 1;
|
|
681
704
|
});
|
|
682
705
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
const
|
|
688
|
-
|
|
706
|
+
var PATH_CANDIDATE_CHAR_RE = /[\w./-]/;
|
|
707
|
+
function buildKnownPathReferenceIndex(knownPaths) {
|
|
708
|
+
const segmentSuffixes = new Set;
|
|
709
|
+
const boundarySuffixes = new Set;
|
|
710
|
+
const normalizedPaths = [];
|
|
711
|
+
let hasUnindexedSuffixes = false;
|
|
712
|
+
for (const path of knownPaths) {
|
|
689
713
|
const normalizedPath = normalizePath(path).replace(/^\/+/, "");
|
|
714
|
+
if (!normalizedPath)
|
|
715
|
+
continue;
|
|
716
|
+
normalizedPaths.push(normalizedPath);
|
|
717
|
+
segmentSuffixes.add(normalizedPath);
|
|
718
|
+
for (let index = 0;index < normalizedPath.length; index++) {
|
|
719
|
+
if (normalizedPath[index] === "/") {
|
|
720
|
+
if (normalizedPath.length - index - 1 <= MAX_INDEXED_SUFFIX_CHARS) {
|
|
721
|
+
segmentSuffixes.add(normalizedPath.slice(index + 1));
|
|
722
|
+
} else {
|
|
723
|
+
hasUnindexedSuffixes = true;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
if (index > 0 && !PATH_CANDIDATE_CHAR_RE.test(normalizedPath[index - 1])) {
|
|
727
|
+
if (normalizedPath.length - index <= MAX_INDEXED_SUFFIX_CHARS) {
|
|
728
|
+
boundarySuffixes.add(normalizedPath.slice(index));
|
|
729
|
+
} else {
|
|
730
|
+
hasUnindexedSuffixes = true;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return {
|
|
736
|
+
segmentSuffixes,
|
|
737
|
+
sortedSegmentSuffixes: [...segmentSuffixes].sort(),
|
|
738
|
+
boundarySuffixes,
|
|
739
|
+
normalizedPaths,
|
|
740
|
+
hasUnindexedSuffixes
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
function matchesKnownPathReference(normalizedRef, normalizedPaths) {
|
|
744
|
+
const pathShaped = normalizedRef.includes("/");
|
|
745
|
+
return normalizedPaths.some((normalizedPath) => {
|
|
690
746
|
if (normalizedPath === normalizedRef || normalizedPath.endsWith("/" + normalizedRef))
|
|
691
747
|
return true;
|
|
692
748
|
if (normalizedPath.endsWith(normalizedRef)) {
|
|
693
749
|
const boundary = normalizedPath[normalizedPath.length - normalizedRef.length - 1];
|
|
694
|
-
if (boundary &&
|
|
750
|
+
if (boundary && !PATH_CANDIDATE_CHAR_RE.test(boundary))
|
|
695
751
|
return true;
|
|
696
752
|
}
|
|
697
753
|
if (!pathShaped)
|
|
698
754
|
return false;
|
|
699
|
-
return normalizedPath.
|
|
755
|
+
return normalizedPath.startsWith(normalizedRef + "/") || normalizedPath.includes("/" + normalizedRef + "/");
|
|
700
756
|
});
|
|
701
757
|
}
|
|
758
|
+
function sortedHasPrefix(values, prefix) {
|
|
759
|
+
let low = 0;
|
|
760
|
+
let high = values.length;
|
|
761
|
+
while (low < high) {
|
|
762
|
+
const middle = low + high >>> 1;
|
|
763
|
+
if (values[middle] < prefix)
|
|
764
|
+
low = middle + 1;
|
|
765
|
+
else
|
|
766
|
+
high = middle;
|
|
767
|
+
}
|
|
768
|
+
return values[low]?.startsWith(prefix) ?? false;
|
|
769
|
+
}
|
|
770
|
+
function isKnownPathReferenceInIndex(ref, index) {
|
|
771
|
+
const normalizedRef = normalizePath(ref).replace(/^\/+/, "");
|
|
772
|
+
if (!normalizedRef)
|
|
773
|
+
return false;
|
|
774
|
+
if (index.segmentSuffixes.has(normalizedRef) || index.boundarySuffixes.has(normalizedRef)) {
|
|
775
|
+
return true;
|
|
776
|
+
}
|
|
777
|
+
if (normalizedRef.includes("/") && sortedHasPrefix(index.sortedSegmentSuffixes, normalizedRef + "/"))
|
|
778
|
+
return true;
|
|
779
|
+
return index.hasUnindexedSuffixes ? matchesKnownPathReference(normalizedRef, index.normalizedPaths) : false;
|
|
780
|
+
}
|
|
702
781
|
|
|
703
782
|
// src/domain/tool-semantics.ts
|
|
704
783
|
var PATH_KEYS = [
|
|
@@ -775,6 +854,38 @@ function warn(msg, err) {
|
|
|
775
854
|
console.error(LOG_PREFIX + " " + msg + (detail ? ": " + detail : ""));
|
|
776
855
|
}
|
|
777
856
|
|
|
857
|
+
// src/infra/fs.ts
|
|
858
|
+
import fs from "fs";
|
|
859
|
+
function readJsonlTail(target, limit, maxBytes = 512 * 1024) {
|
|
860
|
+
if (limit <= 0 || !fs.existsSync(target))
|
|
861
|
+
return [];
|
|
862
|
+
const stat = fs.statSync(target);
|
|
863
|
+
const length = Math.min(stat.size, maxBytes);
|
|
864
|
+
const buffer = Buffer.alloc(length);
|
|
865
|
+
const fd = fs.openSync(target, "r");
|
|
866
|
+
try {
|
|
867
|
+
fs.readSync(fd, buffer, 0, length, stat.size - length);
|
|
868
|
+
} finally {
|
|
869
|
+
fs.closeSync(fd);
|
|
870
|
+
}
|
|
871
|
+
let text = buffer.toString("utf8");
|
|
872
|
+
if (stat.size > length) {
|
|
873
|
+
const newline = text.indexOf(`
|
|
874
|
+
`);
|
|
875
|
+
text = newline >= 0 ? text.slice(newline + 1) : "";
|
|
876
|
+
}
|
|
877
|
+
const values = [];
|
|
878
|
+
for (const line of text.split(`
|
|
879
|
+
`)) {
|
|
880
|
+
if (!line)
|
|
881
|
+
continue;
|
|
882
|
+
try {
|
|
883
|
+
values.push(JSON.parse(line));
|
|
884
|
+
} catch {}
|
|
885
|
+
}
|
|
886
|
+
return values.slice(-limit);
|
|
887
|
+
}
|
|
888
|
+
|
|
778
889
|
// src/infra/paths.ts
|
|
779
890
|
import path from "path";
|
|
780
891
|
import os from "os";
|
|
@@ -800,7 +911,12 @@ function damageReportsFile() {
|
|
|
800
911
|
// src/utils/file-ref-detect.ts
|
|
801
912
|
var CODE_EXT_RE = /\.(ts|tsx|js|jsx|mjs|cjs|rs|py|go|java|rb|cs|cpp|c|h|hpp|swift|kt|scala|php|css|scss|html|json|yaml|yml|toml|md|mdx|sh|sql|tf|ini|env|lock|gradle|xml)$/i;
|
|
802
913
|
var VERSION_RE = /^v?\d+(?:\.\d+)+(?:[-+][\w.-]+)?$/i;
|
|
803
|
-
|
|
914
|
+
function isAsciiWordCode(code) {
|
|
915
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code === 95 || code >= 97 && code <= 122;
|
|
916
|
+
}
|
|
917
|
+
function isCandidateCode(code) {
|
|
918
|
+
return isAsciiWordCode(code) || code === 45 || code === 46 || code === 47;
|
|
919
|
+
}
|
|
804
920
|
function isLikelyFileRef(candidate) {
|
|
805
921
|
if (candidate.startsWith("//") || VERSION_RE.test(candidate))
|
|
806
922
|
return false;
|
|
@@ -811,13 +927,32 @@ function isLikelyFileRef(candidate) {
|
|
|
811
927
|
return CODE_EXT_RE.test(candidate);
|
|
812
928
|
}
|
|
813
929
|
function extractFileRefs(summary) {
|
|
814
|
-
const matcher = new RegExp(FILE_REF_CANDIDATE_RE.source, FILE_REF_CANDIDATE_RE.flags);
|
|
815
930
|
const refs = [];
|
|
816
|
-
|
|
817
|
-
|
|
931
|
+
let cursor = 0;
|
|
932
|
+
while (cursor < summary.length) {
|
|
933
|
+
while (cursor < summary.length && !isCandidateCode(summary.charCodeAt(cursor)))
|
|
934
|
+
cursor++;
|
|
935
|
+
const runStart = cursor;
|
|
936
|
+
while (cursor < summary.length && isCandidateCode(summary.charCodeAt(cursor)))
|
|
937
|
+
cursor++;
|
|
938
|
+
const runEnd = cursor;
|
|
939
|
+
let extensionDot = -1;
|
|
940
|
+
for (let index = runStart + 1;index + 1 < runEnd; index++) {
|
|
941
|
+
if (summary.charCodeAt(index) === 46 && isAsciiWordCode(summary.charCodeAt(index + 1))) {
|
|
942
|
+
extensionDot = index;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
if (extensionDot < 0)
|
|
946
|
+
continue;
|
|
947
|
+
let matchEnd = extensionDot + 2;
|
|
948
|
+
while (matchEnd < runEnd && isAsciiWordCode(summary.charCodeAt(matchEnd))) {
|
|
949
|
+
matchEnd++;
|
|
950
|
+
}
|
|
951
|
+
const candidate = summary.slice(runStart, matchEnd);
|
|
952
|
+
if (/[\\/]/.test(summary[matchEnd] ?? ""))
|
|
818
953
|
continue;
|
|
819
|
-
if (isLikelyFileRef(
|
|
820
|
-
refs.push(
|
|
954
|
+
if (isLikelyFileRef(candidate))
|
|
955
|
+
refs.push(candidate);
|
|
821
956
|
}
|
|
822
957
|
return refs;
|
|
823
958
|
}
|
|
@@ -1083,38 +1218,6 @@ function isDiagnosticConstraintText(text) {
|
|
|
1083
1218
|
return /^(?:\[[^\]]+\]\s*)?(?:npm\s+(?:error|warn|notice|audit|verbose|info)\b|(?:rg|grep):|command exited\b)/i.test(candidate);
|
|
1084
1219
|
}
|
|
1085
1220
|
|
|
1086
|
-
// src/infra/fs.ts
|
|
1087
|
-
import fs from "fs";
|
|
1088
|
-
function readJsonlTail(target, limit, maxBytes = 512 * 1024) {
|
|
1089
|
-
if (limit <= 0 || !fs.existsSync(target))
|
|
1090
|
-
return [];
|
|
1091
|
-
const stat = fs.statSync(target);
|
|
1092
|
-
const length = Math.min(stat.size, maxBytes);
|
|
1093
|
-
const buffer = Buffer.alloc(length);
|
|
1094
|
-
const fd = fs.openSync(target, "r");
|
|
1095
|
-
try {
|
|
1096
|
-
fs.readSync(fd, buffer, 0, length, stat.size - length);
|
|
1097
|
-
} finally {
|
|
1098
|
-
fs.closeSync(fd);
|
|
1099
|
-
}
|
|
1100
|
-
let text = buffer.toString("utf8");
|
|
1101
|
-
if (stat.size > length) {
|
|
1102
|
-
const newline = text.indexOf(`
|
|
1103
|
-
`);
|
|
1104
|
-
text = newline >= 0 ? text.slice(newline + 1) : "";
|
|
1105
|
-
}
|
|
1106
|
-
const values = [];
|
|
1107
|
-
for (const line of text.split(`
|
|
1108
|
-
`)) {
|
|
1109
|
-
if (!line)
|
|
1110
|
-
continue;
|
|
1111
|
-
try {
|
|
1112
|
-
values.push(JSON.parse(line));
|
|
1113
|
-
} catch {}
|
|
1114
|
-
}
|
|
1115
|
-
return values.slice(-limit);
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
1221
|
// src/infra/clock.ts
|
|
1119
1222
|
var systemClock = {
|
|
1120
1223
|
now: () => Date.now()
|
|
@@ -5,7 +5,7 @@ var __require = import.meta.require;
|
|
|
5
5
|
import { ModelRegistry, ModelRuntime } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
|
-
var VERSION = "9.
|
|
8
|
+
var VERSION = "9.6.1";
|
|
9
9
|
var SETTLED_TRIGGER_COOLDOWN_MS = 10 * 60000;
|
|
10
10
|
var COMPACT_SYSTEM_PREFIX = "You are an expert conversation summarizer for a coding agent. " + "Produce structured markdown summaries. " + "Follow output format exactly. " + "Use EXACT names \u2014 never paraphrase code identifiers. " + "Trust deterministic extraction data over intuition.";
|
|
11
11
|
var PROFILES = {
|
|
@@ -690,38 +690,117 @@ function buildPathNeedles(filePath) {
|
|
|
690
690
|
}
|
|
691
691
|
return needles;
|
|
692
692
|
}
|
|
693
|
-
|
|
694
|
-
|
|
693
|
+
var MAX_INDEXED_SUFFIX_CHARS = 1024;
|
|
694
|
+
function buildPathNeedleOwnershipIndex(allPaths) {
|
|
695
|
+
const owners = new Map;
|
|
696
|
+
const normalizedPaths = allPaths.map(normalizePath);
|
|
697
|
+
let hasUnindexedSuffixes = false;
|
|
698
|
+
for (const normalized of normalizedPaths) {
|
|
699
|
+
const suffixes = new Set([normalized]);
|
|
700
|
+
for (let index = 0;index < normalized.length; index++) {
|
|
701
|
+
if (normalized[index] !== "/")
|
|
702
|
+
continue;
|
|
703
|
+
if (normalized.length - index - 1 <= MAX_INDEXED_SUFFIX_CHARS) {
|
|
704
|
+
suffixes.add(normalized.slice(index + 1));
|
|
705
|
+
} else {
|
|
706
|
+
hasUnindexedSuffixes = true;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
for (const suffix of suffixes) {
|
|
710
|
+
owners.set(suffix, (owners.get(suffix) ?? 0) + 1);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return { counts: owners, normalizedPaths, hasUnindexedSuffixes };
|
|
714
|
+
}
|
|
715
|
+
function buildUniquePathNeedlesFromIndex(filePath, owners) {
|
|
695
716
|
return buildPathNeedles(filePath).filter((needle) => {
|
|
696
|
-
|
|
697
|
-
|
|
717
|
+
if (!owners.hasUnindexedSuffixes)
|
|
718
|
+
return owners.counts.get(needle) === 1;
|
|
719
|
+
let count = 0;
|
|
720
|
+
for (const candidate of owners.normalizedPaths) {
|
|
698
721
|
if (candidate === needle || candidate.endsWith("/" + needle))
|
|
699
|
-
|
|
700
|
-
if (
|
|
722
|
+
count++;
|
|
723
|
+
if (count > 1)
|
|
701
724
|
return false;
|
|
702
725
|
}
|
|
703
|
-
return
|
|
726
|
+
return count === 1;
|
|
704
727
|
});
|
|
705
728
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
const
|
|
711
|
-
|
|
729
|
+
var PATH_CANDIDATE_CHAR_RE = /[\w./-]/;
|
|
730
|
+
function buildKnownPathReferenceIndex(knownPaths) {
|
|
731
|
+
const segmentSuffixes = new Set;
|
|
732
|
+
const boundarySuffixes = new Set;
|
|
733
|
+
const normalizedPaths = [];
|
|
734
|
+
let hasUnindexedSuffixes = false;
|
|
735
|
+
for (const path of knownPaths) {
|
|
712
736
|
const normalizedPath = normalizePath(path).replace(/^\/+/, "");
|
|
737
|
+
if (!normalizedPath)
|
|
738
|
+
continue;
|
|
739
|
+
normalizedPaths.push(normalizedPath);
|
|
740
|
+
segmentSuffixes.add(normalizedPath);
|
|
741
|
+
for (let index = 0;index < normalizedPath.length; index++) {
|
|
742
|
+
if (normalizedPath[index] === "/") {
|
|
743
|
+
if (normalizedPath.length - index - 1 <= MAX_INDEXED_SUFFIX_CHARS) {
|
|
744
|
+
segmentSuffixes.add(normalizedPath.slice(index + 1));
|
|
745
|
+
} else {
|
|
746
|
+
hasUnindexedSuffixes = true;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
if (index > 0 && !PATH_CANDIDATE_CHAR_RE.test(normalizedPath[index - 1])) {
|
|
750
|
+
if (normalizedPath.length - index <= MAX_INDEXED_SUFFIX_CHARS) {
|
|
751
|
+
boundarySuffixes.add(normalizedPath.slice(index));
|
|
752
|
+
} else {
|
|
753
|
+
hasUnindexedSuffixes = true;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return {
|
|
759
|
+
segmentSuffixes,
|
|
760
|
+
sortedSegmentSuffixes: [...segmentSuffixes].sort(),
|
|
761
|
+
boundarySuffixes,
|
|
762
|
+
normalizedPaths,
|
|
763
|
+
hasUnindexedSuffixes
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
function matchesKnownPathReference(normalizedRef, normalizedPaths) {
|
|
767
|
+
const pathShaped = normalizedRef.includes("/");
|
|
768
|
+
return normalizedPaths.some((normalizedPath) => {
|
|
713
769
|
if (normalizedPath === normalizedRef || normalizedPath.endsWith("/" + normalizedRef))
|
|
714
770
|
return true;
|
|
715
771
|
if (normalizedPath.endsWith(normalizedRef)) {
|
|
716
772
|
const boundary = normalizedPath[normalizedPath.length - normalizedRef.length - 1];
|
|
717
|
-
if (boundary &&
|
|
773
|
+
if (boundary && !PATH_CANDIDATE_CHAR_RE.test(boundary))
|
|
718
774
|
return true;
|
|
719
775
|
}
|
|
720
776
|
if (!pathShaped)
|
|
721
777
|
return false;
|
|
722
|
-
return normalizedPath.
|
|
778
|
+
return normalizedPath.startsWith(normalizedRef + "/") || normalizedPath.includes("/" + normalizedRef + "/");
|
|
723
779
|
});
|
|
724
780
|
}
|
|
781
|
+
function sortedHasPrefix(values, prefix) {
|
|
782
|
+
let low = 0;
|
|
783
|
+
let high = values.length;
|
|
784
|
+
while (low < high) {
|
|
785
|
+
const middle = low + high >>> 1;
|
|
786
|
+
if (values[middle] < prefix)
|
|
787
|
+
low = middle + 1;
|
|
788
|
+
else
|
|
789
|
+
high = middle;
|
|
790
|
+
}
|
|
791
|
+
return values[low]?.startsWith(prefix) ?? false;
|
|
792
|
+
}
|
|
793
|
+
function isKnownPathReferenceInIndex(ref, index) {
|
|
794
|
+
const normalizedRef = normalizePath(ref).replace(/^\/+/, "");
|
|
795
|
+
if (!normalizedRef)
|
|
796
|
+
return false;
|
|
797
|
+
if (index.segmentSuffixes.has(normalizedRef) || index.boundarySuffixes.has(normalizedRef)) {
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
if (normalizedRef.includes("/") && sortedHasPrefix(index.sortedSegmentSuffixes, normalizedRef + "/"))
|
|
801
|
+
return true;
|
|
802
|
+
return index.hasUnindexedSuffixes ? matchesKnownPathReference(normalizedRef, index.normalizedPaths) : false;
|
|
803
|
+
}
|
|
725
804
|
|
|
726
805
|
// src/domain/tool-semantics.ts
|
|
727
806
|
var PATH_KEYS = [
|
|
@@ -798,6 +877,38 @@ function warn(msg, err) {
|
|
|
798
877
|
console.error(LOG_PREFIX + " " + msg + (detail ? ": " + detail : ""));
|
|
799
878
|
}
|
|
800
879
|
|
|
880
|
+
// src/infra/fs.ts
|
|
881
|
+
import fs from "fs";
|
|
882
|
+
function readJsonlTail(target, limit, maxBytes = 512 * 1024) {
|
|
883
|
+
if (limit <= 0 || !fs.existsSync(target))
|
|
884
|
+
return [];
|
|
885
|
+
const stat = fs.statSync(target);
|
|
886
|
+
const length = Math.min(stat.size, maxBytes);
|
|
887
|
+
const buffer = Buffer.alloc(length);
|
|
888
|
+
const fd = fs.openSync(target, "r");
|
|
889
|
+
try {
|
|
890
|
+
fs.readSync(fd, buffer, 0, length, stat.size - length);
|
|
891
|
+
} finally {
|
|
892
|
+
fs.closeSync(fd);
|
|
893
|
+
}
|
|
894
|
+
let text = buffer.toString("utf8");
|
|
895
|
+
if (stat.size > length) {
|
|
896
|
+
const newline = text.indexOf(`
|
|
897
|
+
`);
|
|
898
|
+
text = newline >= 0 ? text.slice(newline + 1) : "";
|
|
899
|
+
}
|
|
900
|
+
const values = [];
|
|
901
|
+
for (const line of text.split(`
|
|
902
|
+
`)) {
|
|
903
|
+
if (!line)
|
|
904
|
+
continue;
|
|
905
|
+
try {
|
|
906
|
+
values.push(JSON.parse(line));
|
|
907
|
+
} catch {}
|
|
908
|
+
}
|
|
909
|
+
return values.slice(-limit);
|
|
910
|
+
}
|
|
911
|
+
|
|
801
912
|
// src/infra/paths.ts
|
|
802
913
|
import path from "path";
|
|
803
914
|
import os from "os";
|
|
@@ -823,7 +934,12 @@ function damageReportsFile() {
|
|
|
823
934
|
// src/utils/file-ref-detect.ts
|
|
824
935
|
var CODE_EXT_RE = /\.(ts|tsx|js|jsx|mjs|cjs|rs|py|go|java|rb|cs|cpp|c|h|hpp|swift|kt|scala|php|css|scss|html|json|yaml|yml|toml|md|mdx|sh|sql|tf|ini|env|lock|gradle|xml)$/i;
|
|
825
936
|
var VERSION_RE = /^v?\d+(?:\.\d+)+(?:[-+][\w.-]+)?$/i;
|
|
826
|
-
|
|
937
|
+
function isAsciiWordCode(code) {
|
|
938
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code === 95 || code >= 97 && code <= 122;
|
|
939
|
+
}
|
|
940
|
+
function isCandidateCode(code) {
|
|
941
|
+
return isAsciiWordCode(code) || code === 45 || code === 46 || code === 47;
|
|
942
|
+
}
|
|
827
943
|
function isLikelyFileRef(candidate) {
|
|
828
944
|
if (candidate.startsWith("//") || VERSION_RE.test(candidate))
|
|
829
945
|
return false;
|
|
@@ -834,13 +950,32 @@ function isLikelyFileRef(candidate) {
|
|
|
834
950
|
return CODE_EXT_RE.test(candidate);
|
|
835
951
|
}
|
|
836
952
|
function extractFileRefs(summary) {
|
|
837
|
-
const matcher = new RegExp(FILE_REF_CANDIDATE_RE.source, FILE_REF_CANDIDATE_RE.flags);
|
|
838
953
|
const refs = [];
|
|
839
|
-
|
|
840
|
-
|
|
954
|
+
let cursor = 0;
|
|
955
|
+
while (cursor < summary.length) {
|
|
956
|
+
while (cursor < summary.length && !isCandidateCode(summary.charCodeAt(cursor)))
|
|
957
|
+
cursor++;
|
|
958
|
+
const runStart = cursor;
|
|
959
|
+
while (cursor < summary.length && isCandidateCode(summary.charCodeAt(cursor)))
|
|
960
|
+
cursor++;
|
|
961
|
+
const runEnd = cursor;
|
|
962
|
+
let extensionDot = -1;
|
|
963
|
+
for (let index = runStart + 1;index + 1 < runEnd; index++) {
|
|
964
|
+
if (summary.charCodeAt(index) === 46 && isAsciiWordCode(summary.charCodeAt(index + 1))) {
|
|
965
|
+
extensionDot = index;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
if (extensionDot < 0)
|
|
969
|
+
continue;
|
|
970
|
+
let matchEnd = extensionDot + 2;
|
|
971
|
+
while (matchEnd < runEnd && isAsciiWordCode(summary.charCodeAt(matchEnd))) {
|
|
972
|
+
matchEnd++;
|
|
973
|
+
}
|
|
974
|
+
const candidate = summary.slice(runStart, matchEnd);
|
|
975
|
+
if (/[\\/]/.test(summary[matchEnd] ?? ""))
|
|
841
976
|
continue;
|
|
842
|
-
if (isLikelyFileRef(
|
|
843
|
-
refs.push(
|
|
977
|
+
if (isLikelyFileRef(candidate))
|
|
978
|
+
refs.push(candidate);
|
|
844
979
|
}
|
|
845
980
|
return refs;
|
|
846
981
|
}
|
|
@@ -1106,38 +1241,6 @@ function isDiagnosticConstraintText(text) {
|
|
|
1106
1241
|
return /^(?:\[[^\]]+\]\s*)?(?:npm\s+(?:error|warn|notice|audit|verbose|info)\b|(?:rg|grep):|command exited\b)/i.test(candidate);
|
|
1107
1242
|
}
|
|
1108
1243
|
|
|
1109
|
-
// src/infra/fs.ts
|
|
1110
|
-
import fs from "fs";
|
|
1111
|
-
function readJsonlTail(target, limit, maxBytes = 512 * 1024) {
|
|
1112
|
-
if (limit <= 0 || !fs.existsSync(target))
|
|
1113
|
-
return [];
|
|
1114
|
-
const stat = fs.statSync(target);
|
|
1115
|
-
const length = Math.min(stat.size, maxBytes);
|
|
1116
|
-
const buffer = Buffer.alloc(length);
|
|
1117
|
-
const fd = fs.openSync(target, "r");
|
|
1118
|
-
try {
|
|
1119
|
-
fs.readSync(fd, buffer, 0, length, stat.size - length);
|
|
1120
|
-
} finally {
|
|
1121
|
-
fs.closeSync(fd);
|
|
1122
|
-
}
|
|
1123
|
-
let text = buffer.toString("utf8");
|
|
1124
|
-
if (stat.size > length) {
|
|
1125
|
-
const newline = text.indexOf(`
|
|
1126
|
-
`);
|
|
1127
|
-
text = newline >= 0 ? text.slice(newline + 1) : "";
|
|
1128
|
-
}
|
|
1129
|
-
const values = [];
|
|
1130
|
-
for (const line of text.split(`
|
|
1131
|
-
`)) {
|
|
1132
|
-
if (!line)
|
|
1133
|
-
continue;
|
|
1134
|
-
try {
|
|
1135
|
-
values.push(JSON.parse(line));
|
|
1136
|
-
} catch {}
|
|
1137
|
-
}
|
|
1138
|
-
return values.slice(-limit);
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
1244
|
// src/infra/clock.ts
|
|
1142
1245
|
var systemClock = {
|
|
1143
1246
|
now: () => Date.now()
|
|
@@ -2220,8 +2323,9 @@ function verifyFileReferences(summary, extraction, continuity, evidence, collect
|
|
|
2220
2323
|
...(continuity?.unresolvedErrors ?? []).flatMap((error) => error.files),
|
|
2221
2324
|
...(continuity?.openLoops ?? []).flatMap((loop) => loop.files)
|
|
2222
2325
|
]));
|
|
2326
|
+
const knownFileIndex = buildKnownPathReferenceIndex(knownFiles);
|
|
2223
2327
|
for (const ref of new Set(extractFileRefs(summary))) {
|
|
2224
|
-
const grounded =
|
|
2328
|
+
const grounded = isKnownPathReferenceInIndex(ref, knownFileIndex) || Boolean(evidence.sourceMessages && sourceSupportsFileReference(ref, evidence.sourceMessages));
|
|
2225
2329
|
if (!grounded)
|
|
2226
2330
|
addGap(accumulator, { kind: "fabricated-file", ref }, 4);
|
|
2227
2331
|
}
|
|
@@ -2239,9 +2343,10 @@ function verifyProgressConsistency(parsed, extraction, collected, paths, accumul
|
|
|
2239
2343
|
}, 12);
|
|
2240
2344
|
}
|
|
2241
2345
|
const doneRefs = new Set(extractFileRefs(done).map(normalizePath));
|
|
2346
|
+
const modifiedPathOwners = buildPathNeedleOwnershipIndex(paths.modified);
|
|
2242
2347
|
for (const file of extraction.modifiedFiles) {
|
|
2243
|
-
const needles =
|
|
2244
|
-
if (!needles.some((needle) => doneRefs.has(
|
|
2348
|
+
const needles = buildUniquePathNeedlesFromIndex(file.path, modifiedPathOwners);
|
|
2349
|
+
if (!needles.some((needle) => doneRefs.has(needle)))
|
|
2245
2350
|
continue;
|
|
2246
2351
|
const unresolved = collected.unresolved.find((error) => {
|
|
2247
2352
|
const firstLine = error.message.split(/\r?\n/, 1)[0] ?? "";
|