@prestyj/cli 4.14.0 → 5.0.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.
Files changed (100) hide show
  1. package/dist/app-sidecar.js +63 -7
  2. package/dist/app-sidecar.js.map +1 -1
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +47 -5
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/cache-warm-benchmark.d.ts +22 -0
  8. package/dist/core/cache-warm-benchmark.d.ts.map +1 -0
  9. package/dist/core/cache-warm-benchmark.js +170 -0
  10. package/dist/core/cache-warm-benchmark.js.map +1 -0
  11. package/dist/core/code-retrieval.d.ts +13 -0
  12. package/dist/core/code-retrieval.d.ts.map +1 -0
  13. package/dist/core/code-retrieval.js +87 -0
  14. package/dist/core/code-retrieval.js.map +1 -0
  15. package/dist/core/fast-apply-benchmark.d.ts +26 -0
  16. package/dist/core/fast-apply-benchmark.d.ts.map +1 -0
  17. package/dist/core/fast-apply-benchmark.js +284 -0
  18. package/dist/core/fast-apply-benchmark.js.map +1 -0
  19. package/dist/core/hashline-edit-benchmark.d.ts +55 -0
  20. package/dist/core/hashline-edit-benchmark.d.ts.map +1 -0
  21. package/dist/core/hashline-edit-benchmark.js +342 -0
  22. package/dist/core/hashline-edit-benchmark.js.map +1 -0
  23. package/dist/core/hashline-edit-benchmark.test.d.ts +2 -0
  24. package/dist/core/hashline-edit-benchmark.test.d.ts.map +1 -0
  25. package/dist/core/hashline-edit-benchmark.test.js +141 -0
  26. package/dist/core/hashline-edit-benchmark.test.js.map +1 -0
  27. package/dist/core/hashline.d.ts +50 -0
  28. package/dist/core/hashline.d.ts.map +1 -0
  29. package/dist/core/hashline.js +76 -0
  30. package/dist/core/hashline.js.map +1 -0
  31. package/dist/core/ideal-review.d.ts +12 -1
  32. package/dist/core/ideal-review.d.ts.map +1 -1
  33. package/dist/core/ideal-review.js +52 -2
  34. package/dist/core/ideal-review.js.map +1 -1
  35. package/dist/core/ideal-review.test.js +41 -1
  36. package/dist/core/ideal-review.test.js.map +1 -1
  37. package/dist/core/language-detector.d.ts +11 -0
  38. package/dist/core/language-detector.d.ts.map +1 -1
  39. package/dist/core/language-detector.js +102 -0
  40. package/dist/core/language-detector.js.map +1 -1
  41. package/dist/core/semantic-search-benchmark.d.ts +37 -0
  42. package/dist/core/semantic-search-benchmark.d.ts.map +1 -0
  43. package/dist/core/semantic-search-benchmark.js +211 -0
  44. package/dist/core/semantic-search-benchmark.js.map +1 -0
  45. package/dist/core/semantic-search-benchmark.test.d.ts +2 -0
  46. package/dist/core/semantic-search-benchmark.test.d.ts.map +1 -0
  47. package/dist/core/semantic-search-benchmark.test.js +89 -0
  48. package/dist/core/semantic-search-benchmark.test.js.map +1 -0
  49. package/dist/core/steering.d.ts +25 -0
  50. package/dist/core/steering.d.ts.map +1 -0
  51. package/dist/core/steering.js +29 -0
  52. package/dist/core/steering.js.map +1 -0
  53. package/dist/system-prompt.d.ts.map +1 -1
  54. package/dist/system-prompt.js +2 -1
  55. package/dist/system-prompt.js.map +1 -1
  56. package/dist/system-prompt.test.js +10 -8
  57. package/dist/system-prompt.test.js.map +1 -1
  58. package/dist/tools/edit.d.ts +6 -0
  59. package/dist/tools/edit.d.ts.map +1 -1
  60. package/dist/tools/edit.js +34 -2
  61. package/dist/tools/edit.js.map +1 -1
  62. package/dist/tools/edit.test.js +112 -0
  63. package/dist/tools/edit.test.js.map +1 -1
  64. package/dist/tools/index.d.ts +1 -0
  65. package/dist/tools/index.d.ts.map +1 -1
  66. package/dist/tools/index.js +3 -0
  67. package/dist/tools/index.js.map +1 -1
  68. package/dist/tools/prompt-hints.d.ts.map +1 -1
  69. package/dist/tools/prompt-hints.js +8 -0
  70. package/dist/tools/prompt-hints.js.map +1 -1
  71. package/dist/tools/read.d.ts +1 -0
  72. package/dist/tools/read.d.ts.map +1 -1
  73. package/dist/tools/read.js +14 -3
  74. package/dist/tools/read.js.map +1 -1
  75. package/dist/tools/read.test.js +40 -0
  76. package/dist/tools/read.test.js.map +1 -1
  77. package/dist/tools/search-code.d.ts +11 -0
  78. package/dist/tools/search-code.d.ts.map +1 -0
  79. package/dist/tools/search-code.js +95 -0
  80. package/dist/tools/search-code.js.map +1 -0
  81. package/dist/tools/search-code.test.d.ts +2 -0
  82. package/dist/tools/search-code.test.d.ts.map +1 -0
  83. package/dist/tools/search-code.test.js +77 -0
  84. package/dist/tools/search-code.test.js.map +1 -0
  85. package/dist/ui/App.d.ts.map +1 -1
  86. package/dist/ui/App.js +8 -4
  87. package/dist/ui/App.js.map +1 -1
  88. package/dist/ui/hooks/useAgentLoop.d.ts +1 -1
  89. package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
  90. package/dist/ui/hooks/useAgentLoop.js +6 -4
  91. package/dist/ui/hooks/useAgentLoop.js.map +1 -1
  92. package/dist/utils/image.d.ts +17 -0
  93. package/dist/utils/image.d.ts.map +1 -1
  94. package/dist/utils/image.js +57 -2
  95. package/dist/utils/image.js.map +1 -1
  96. package/dist/utils/prompt-enhancer.d.ts +50 -0
  97. package/dist/utils/prompt-enhancer.d.ts.map +1 -0
  98. package/dist/utils/prompt-enhancer.js +127 -0
  99. package/dist/utils/prompt-enhancer.js.map +1 -0
  100. package/package.json +6 -4
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Hash-anchored line addressing — the pure, UI-free core shared by the hashline
3
+ * benchmark and the opt-in anchor guard in the read/edit tools.
4
+ *
5
+ * Every line gets a short content+position hash. Anchors are UNIQUE by
6
+ * construction (the line's index is folded into the hash, so blank/repeated
7
+ * lines never collide), which is what lets an edit either resolve to exactly one
8
+ * location or be rejected — never silently corrupt a file that drifted since the
9
+ * model last read it.
10
+ */
11
+ import { createHash } from "node:crypto";
12
+ /**
13
+ * 4-hex-char anchor for a line. Position is folded into the hash so anchors are
14
+ * UNIQUE by construction (blank lines and repeated lines no longer collide).
15
+ * Resolution stays O(1) via a lookup map. `index` is the 0-based line index.
16
+ */
17
+ export function lineHash(line, index) {
18
+ return createHash("sha1").update(`${index}:${line.trim()}`).digest("hex").slice(0, 4);
19
+ }
20
+ /** File rendered with `anchor│line` prefixes for the model to read. */
21
+ export function renderWithAnchors(file) {
22
+ return file
23
+ .split("\n")
24
+ .map((l, i) => `${lineHash(l, i)}│${l}`)
25
+ .join("\n");
26
+ }
27
+ export function anchorFile(file) {
28
+ const lines = file.split("\n");
29
+ const counts = new Map();
30
+ lines.forEach((l, i) => {
31
+ const h = lineHash(l, i);
32
+ const arr = counts.get(h) ?? [];
33
+ arr.push(i);
34
+ counts.set(h, arr);
35
+ });
36
+ const anchorToIndex = new Map();
37
+ const ambiguous = new Set();
38
+ for (const [h, idxs] of counts) {
39
+ // Position-folded anchors are unique unless sha1 itself collides in 16 bits.
40
+ if (idxs.length === 1)
41
+ anchorToIndex.set(h, idxs[0]);
42
+ else
43
+ ambiguous.add(h);
44
+ }
45
+ return { rendered: renderWithAnchors(file), anchorToIndex, ambiguous, lines };
46
+ }
47
+ /**
48
+ * True when the line at `index` (0-based) still hashes to `hash`. Out-of-range
49
+ * indices return false. This is the staleness gate the edit tool uses.
50
+ */
51
+ export function verifyAnchor(lines, index, hash) {
52
+ if (index < 0 || index >= lines.length)
53
+ return false;
54
+ return lineHash(lines[index], index) === hash;
55
+ }
56
+ /**
57
+ * Resolve an anchor against the current file lines (0-based). Rejects the edit
58
+ * if either endpoint is out of range, the range is reversed, or either hash no
59
+ * longer matches — the corruption-avoidance property.
60
+ */
61
+ export function resolveAnchoredEdit(lines, anchor) {
62
+ const startIndex = anchor.start_line - 1;
63
+ const endIndex = anchor.end_line - 1;
64
+ if (startIndex < 0 || endIndex < 0 || startIndex >= lines.length || endIndex >= lines.length) {
65
+ return { ok: false, reason: "out_of_range" };
66
+ }
67
+ if (startIndex > endIndex) {
68
+ return { ok: false, reason: "reversed" };
69
+ }
70
+ if (!verifyAnchor(lines, startIndex, anchor.start_hash) ||
71
+ !verifyAnchor(lines, endIndex, anchor.end_hash)) {
72
+ return { ok: false, reason: "hash_mismatch" };
73
+ }
74
+ return { ok: true, startIndex, endIndex };
75
+ }
76
+ //# sourceMappingURL=hashline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hashline.js","sourceRoot":"","sources":["../../src/core/hashline.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,17 @@ export interface IdealReviewDecision {
15
15
  }
16
16
  export declare const IDEAL_REVIEW_PROMPT: string;
17
17
  export declare function evaluateIdealReview(stats: IdealReviewStats): IdealReviewDecision;
18
- export declare function buildIdealReviewMessage(reasons: readonly string[]): Message;
18
+ export declare function buildIdealReviewMessage(reasons: readonly string[], driftedFiles?: readonly string[]): Message;
19
+ /**
20
+ * Test-drift detector \u2014 the one stranding signal a typechecker is blind to.
21
+ * Given the set of files the run mutated, return the source files whose sibling
22
+ * test exists on disk but was NOT touched this run (a green-but-stale test).
23
+ *
24
+ * Pure structural check: no sibling test on disk \u2192 no signal, so it stays
25
+ * silent on projects (or files) without co-located tests. `fileExists` is
26
+ * injectable for tests; paths are resolved against `cwd` so relative tool paths
27
+ * and absolute ones compare consistently.
28
+ */
29
+ export declare function detectTestDrift(touchedFiles: Iterable<string>, cwd: string, fileExists?: (p: string) => boolean): string[];
19
30
  export declare function shouldCountAsRiskyTool(toolName: string): boolean;
20
31
  //# sourceMappingURL=ideal-review.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ideal-review.d.ts","sourceRoot":"","sources":["../../src/core/ideal-review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,QAM6C,CAAC;AAI9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,mBAAmB,CAyChF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAM3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhE"}
1
+ {"version":3,"file":"ideal-review.d.ts","sourceRoot":"","sources":["../../src/core/ideal-review.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,QAM6C,CAAC;AAI9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,mBAAmB,CAyChF;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,YAAY,GAAE,SAAS,MAAM,EAAO,GACnC,OAAO,CAYT;AAOD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC9B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAoB,GAC9C,MAAM,EAAE,CAwBV;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhE"}
@@ -1,3 +1,5 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
1
3
  export const IDEAL_REVIEW_PROMPT = "Ideal? Review the actual work against the user's request before the final response. " +
2
4
  "Is it simple, focused, correct, and aligned? Did you over-edit, leave TODOs, miss an obvious " +
3
5
  "case the request called for, or introduce risk? Judge this by reading the code you changed \u2014 " +
@@ -42,13 +44,61 @@ export function evaluateIdealReview(stats) {
42
44
  }
43
45
  return { shouldReview: score >= 4, score, reasons };
44
46
  }
45
- export function buildIdealReviewMessage(reasons) {
47
+ export function buildIdealReviewMessage(reasons, driftedFiles = []) {
46
48
  const reasonText = reasons.length > 0 ? ` Triggered because: ${reasons.join(", ")}.` : "";
49
+ const driftText = driftedFiles.length > 0
50
+ ? ` Also: you changed ${driftedFiles.join(", ")} but the matching test file was not updated. ` +
51
+ `Update the test to match the new behavior, or state plainly why the existing test is still valid. ` +
52
+ `Edit the test only \u2014 do not run the suite now.`
53
+ : "";
47
54
  return {
48
55
  role: "user",
49
- content: `${IDEAL_REVIEW_PROMPT}${reasonText}`,
56
+ content: `${IDEAL_REVIEW_PROMPT}${reasonText}${driftText}`,
50
57
  };
51
58
  }
59
+ // A test file: foo.test.ts, foo.spec.tsx, foo.test.mjs, etc.
60
+ const TEST_FILE_RE = /\.(test|spec)\.[cm]?[jt]sx?$/;
61
+ // A source code file we can pair with a sibling test.
62
+ const CODE_EXT_RE = /\.([cm]?[jt]sx?)$/;
63
+ /**
64
+ * Test-drift detector \u2014 the one stranding signal a typechecker is blind to.
65
+ * Given the set of files the run mutated, return the source files whose sibling
66
+ * test exists on disk but was NOT touched this run (a green-but-stale test).
67
+ *
68
+ * Pure structural check: no sibling test on disk \u2192 no signal, so it stays
69
+ * silent on projects (or files) without co-located tests. `fileExists` is
70
+ * injectable for tests; paths are resolved against `cwd` so relative tool paths
71
+ * and absolute ones compare consistently.
72
+ */
73
+ export function detectTestDrift(touchedFiles, cwd, fileExists = existsSync) {
74
+ const resolved = new Map(); // absolute -> original (as the model wrote it)
75
+ for (const f of touchedFiles)
76
+ resolved.set(path.resolve(cwd, f), f);
77
+ const touchedSet = new Set(resolved.keys());
78
+ const drifted = [];
79
+ for (const [abs, original] of resolved) {
80
+ const base = path.basename(abs);
81
+ if (TEST_FILE_RE.test(base))
82
+ continue; // the file itself is a test
83
+ const match = base.match(CODE_EXT_RE);
84
+ if (!match)
85
+ continue; // not a code file
86
+ const ext = match[1];
87
+ const dir = path.dirname(abs);
88
+ const stem = base.slice(0, base.length - ext.length - 1);
89
+ // Tests commonly drop the JSX `x` (Button.tsx -> Button.test.ts), so try the
90
+ // source ext and its non-JSX variant against both .test and .spec.
91
+ const testExts = ext.endsWith("x") ? [ext, ext.slice(0, -1)] : [ext];
92
+ const candidates = testExts
93
+ .flatMap((e) => [`${stem}.test.${e}`, `${stem}.spec.${e}`])
94
+ .map((c) => path.join(dir, c));
95
+ if (candidates.some((c) => touchedSet.has(c)))
96
+ continue; // sibling test was updated
97
+ if (candidates.some((c) => fileExists(c)))
98
+ drifted.push(original);
99
+ }
100
+ return drifted;
101
+ }
52
102
  export function shouldCountAsRiskyTool(toolName) {
53
103
  return RISKY_TOOL_NAMES.has(toolName);
54
104
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ideal-review.js","sourceRoot":"","sources":["../../src/core/ideal-review.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,mBAAmB,GAC9B,sFAAsF;IACtF,+FAA+F;IAC/F,oGAAoG;IACpG,8FAA8F;IAC9F,2FAA2F;IAC3F,2EAA2E,CAAC;AAE9E,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,MAAM,UAAU,mBAAmB,CAAC,KAAuB;IACzD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,IAAI,KAAK,CAAC,YAAY,IAAI,GAAG,EAAE,CAAC;QAC9B,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,YAAY,gBAAgB,CAAC,CAAC;IACtD,CAAC;SAAM,IAAI,KAAK,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,YAAY,gBAAgB,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,aAAa,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;QAC5C,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,sBAAsB,CAAC,CAAC;IAC5E,CAAC;SAAM,IAAI,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC;QACnD,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,sBAAsB,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QAClE,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,YAAY,oBAAoB,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,cAAc,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAA0B;IAChE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,uBAAuB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,GAAG,mBAAmB,GAAG,UAAU,EAAE;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"ideal-review.js","sourceRoot":"","sources":["../../src/core/ideal-review.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { buildIdealReviewMessage, evaluateIdealReview } from "./ideal-review.js";
2
+ import { buildIdealReviewMessage, detectTestDrift, evaluateIdealReview } from "./ideal-review.js";
3
3
  describe("evaluateIdealReview", () => {
4
4
  it("skips tiny text-only changes", () => {
5
5
  const decision = evaluateIdealReview({
@@ -55,5 +55,45 @@ describe("buildIdealReviewMessage", () => {
55
55
  expect(message.content).toContain("do NOT run builds, typechecks, linters, or test suites now");
56
56
  expect(message.content).toContain("/commit");
57
57
  });
58
+ it("calls out drifted files and their stale tests", () => {
59
+ const message = buildIdealReviewMessage([], ["src/foo.ts"]);
60
+ expect(message.content).toContain("src/foo.ts");
61
+ expect(message.content).toContain("matching test file was not updated");
62
+ });
63
+ });
64
+ describe("detectTestDrift", () => {
65
+ const cwd = "/proj";
66
+ const exists = (files) => {
67
+ const set = new Set(files);
68
+ return (p) => set.has(p);
69
+ };
70
+ it("flags a changed source whose sibling test exists but was not touched", () => {
71
+ const drift = detectTestDrift(["src/foo.ts"], cwd, exists(["/proj/src/foo.test.ts"]));
72
+ expect(drift).toEqual(["src/foo.ts"]);
73
+ });
74
+ it("stays silent when the sibling test was updated in the same run", () => {
75
+ const drift = detectTestDrift(["src/foo.ts", "src/foo.test.ts"], cwd, exists(["/proj/src/foo.test.ts"]));
76
+ expect(drift).toEqual([]);
77
+ });
78
+ it("stays silent when no sibling test exists on disk", () => {
79
+ const drift = detectTestDrift(["src/foo.ts"], cwd, exists([]));
80
+ expect(drift).toEqual([]);
81
+ });
82
+ it("ignores test files that are themselves the change", () => {
83
+ const drift = detectTestDrift(["src/foo.test.ts"], cwd, exists(["/proj/src/foo.test.ts"]));
84
+ expect(drift).toEqual([]);
85
+ });
86
+ it("ignores non-code files", () => {
87
+ const drift = detectTestDrift(["README.md"], cwd, exists(["/proj/README.test.md"]));
88
+ expect(drift).toEqual([]);
89
+ });
90
+ it("matches .spec siblings and resolves absolute paths", () => {
91
+ const drift = detectTestDrift(["/proj/src/bar.tsx"], cwd, exists(["/proj/src/bar.spec.tsx"]));
92
+ expect(drift).toEqual(["/proj/src/bar.tsx"]);
93
+ });
94
+ it("matches a .test.ts sibling for a .tsx source (test drops the x)", () => {
95
+ const drift = detectTestDrift(["src/Button.tsx"], cwd, exists(["/proj/src/Button.test.ts"]));
96
+ expect(drift).toEqual(["src/Button.tsx"]);
97
+ });
58
98
  });
59
99
  //# sourceMappingURL=ideal-review.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ideal-review.test.js","sourceRoot":"","sources":["../../src/core/ideal-review.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ideal-review.test.js","sourceRoot":"","sources":["../../src/core/ideal-review.test.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,17 @@ export declare function languagesToSortedArray(set: Set<LanguageId>): LanguageId
23
23
  * `typescript`. Keep these short — they're rendered inline.
24
24
  */
25
25
  export declare const LANGUAGE_DISPLAY_NAMES: Readonly<Record<LanguageId, string>>;
26
+ /**
27
+ * Detect a project's tech stack as a short, human-readable string
28
+ * (e.g. "Next.js, TypeScript, Tailwind CSS" or "Rust" or "Python, Django").
29
+ *
30
+ * Cheap + best-effort: reuses `detectLanguages` for the language base and adds a
31
+ * light framework sniff from package.json deps (JS/TS) plus a few manifest
32
+ * content checks (Rails, Django/Flask/FastAPI, Laravel). Returns "" when nothing
33
+ * recognizable is found. Used by the prompt enhancer to bias terminology toward
34
+ * the stack the user actually works in — facts only, never invented scope.
35
+ */
36
+ export declare function detectProjectStack(cwd: string): string;
26
37
  /**
27
38
  * Returns true iff `next` contains every member of `prev` plus at least one
28
39
  * additional language. Used to gate system-prompt rebuilds: we only re-inject
@@ -1 +1 @@
1
- {"version":3,"file":"language-detector.d.ts","sourceRoot":"","sources":["../../src/core/language-detector.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,GAAG,GACH,MAAM,GACN,KAAK,GACL,OAAO,GACP,OAAO,GACP,QAAQ,GACR,SAAS,GACT,OAAO,GACP,QAAQ,GACR,SAAS,GACT,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,WAAW,CAAC;AAkEhB;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,CA8D5D;AAsBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,UAAU,EAAE,CAIzE;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CA0BvE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,CAMtF"}
1
+ {"version":3,"file":"language-detector.d.ts","sourceRoot":"","sources":["../../src/core/language-detector.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,GAAG,GACH,MAAM,GACN,KAAK,GACL,OAAO,GACP,OAAO,GACP,QAAQ,GACR,SAAS,GACT,OAAO,GACP,QAAQ,GACR,SAAS,GACT,MAAM,GACN,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,WAAW,CAAC;AAkEhB;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,CA8D5D;AAsBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,UAAU,EAAE,CAIzE;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CA0BvE,CAAC;AAqEF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA8BtD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,CAMtF"}
@@ -174,6 +174,108 @@ export const LANGUAGE_DISPLAY_NAMES = {
174
174
  bash: "Bash",
175
175
  terraform: "Terraform",
176
176
  };
177
+ // ── Framework detection (for the prompt enhancer's terminology hint) ─────────
178
+ // High-signal framework markers keyed by the dependency name (JS/TS) found in
179
+ // package.json. Mapped to a human display name. Order matters: more specific
180
+ // meta-frameworks are listed first so e.g. Next.js wins over bare React.
181
+ const JS_FRAMEWORK_DEPS = [
182
+ ["next", "Next.js"],
183
+ ["nuxt", "Nuxt"],
184
+ ["@remix-run/react", "Remix"],
185
+ ["@sveltejs/kit", "SvelteKit"],
186
+ ["astro", "Astro"],
187
+ ["expo", "React Native (Expo)"],
188
+ ["react-native", "React Native"],
189
+ ["@angular/core", "Angular"],
190
+ ["solid-js", "SolidJS"],
191
+ ["svelte", "Svelte"],
192
+ ["vue", "Vue"],
193
+ ["react", "React"],
194
+ ["@nestjs/core", "NestJS"],
195
+ ["@tauri-apps/api", "Tauri"],
196
+ ["electron", "Electron"],
197
+ ["hono", "Hono"],
198
+ ["fastify", "Fastify"],
199
+ ["express", "Express"],
200
+ ["tailwindcss", "Tailwind CSS"],
201
+ ];
202
+ // Group meta-framework → the base lib it implies, so we don't list both
203
+ // (e.g. "Next.js, React" → just "Next.js").
204
+ const IMPLIES = {
205
+ "Next.js": "React",
206
+ Remix: "React",
207
+ "React Native": "React",
208
+ "React Native (Expo)": "React",
209
+ Nuxt: "Vue",
210
+ SvelteKit: "Svelte",
211
+ };
212
+ /** Read package.json deps once (best-effort) and return the matched frameworks. */
213
+ function detectJsFrameworks(cwd) {
214
+ let pkg;
215
+ try {
216
+ pkg = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf-8"));
217
+ }
218
+ catch {
219
+ return [];
220
+ }
221
+ const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
222
+ const found = JS_FRAMEWORK_DEPS.filter(([dep]) => dep in deps).map(([, display]) => display);
223
+ // Drop a base lib when a meta-framework that implies it is also present.
224
+ const implied = new Set(found.map((f) => IMPLIES[f]).filter(Boolean));
225
+ return found.filter((f) => !implied.has(f));
226
+ }
227
+ /** Match a non-JS framework by scanning a manifest file's contents for a marker. */
228
+ function detectFromManifest(cwd, file, markers) {
229
+ let content;
230
+ try {
231
+ content = fs.readFileSync(path.join(cwd, file), "utf-8").toLowerCase();
232
+ }
233
+ catch {
234
+ return [];
235
+ }
236
+ return markers.filter(([needle]) => content.includes(needle)).map(([, display]) => display);
237
+ }
238
+ /**
239
+ * Detect a project's tech stack as a short, human-readable string
240
+ * (e.g. "Next.js, TypeScript, Tailwind CSS" or "Rust" or "Python, Django").
241
+ *
242
+ * Cheap + best-effort: reuses `detectLanguages` for the language base and adds a
243
+ * light framework sniff from package.json deps (JS/TS) plus a few manifest
244
+ * content checks (Rails, Django/Flask/FastAPI, Laravel). Returns "" when nothing
245
+ * recognizable is found. Used by the prompt enhancer to bias terminology toward
246
+ * the stack the user actually works in — facts only, never invented scope.
247
+ */
248
+ export function detectProjectStack(cwd) {
249
+ const langs = languagesToSortedArray(detectLanguages(cwd)).map((l) => LANGUAGE_DISPLAY_NAMES[l]);
250
+ const frameworks = [
251
+ ...detectJsFrameworks(cwd),
252
+ ...detectFromManifest(cwd, "Gemfile", [
253
+ ["rails", "Ruby on Rails"],
254
+ ["sinatra", "Sinatra"],
255
+ ]),
256
+ ...detectFromManifest(cwd, "requirements.txt", [
257
+ ["django", "Django"],
258
+ ["flask", "Flask"],
259
+ ["fastapi", "FastAPI"],
260
+ ]),
261
+ ...detectFromManifest(cwd, "pyproject.toml", [
262
+ ["django", "Django"],
263
+ ["flask", "Flask"],
264
+ ["fastapi", "FastAPI"],
265
+ ]),
266
+ ...detectFromManifest(cwd, "composer.json", [["laravel/framework", "Laravel"]]),
267
+ ];
268
+ // Frameworks first (most informative), then languages; de-dupe + cap length.
269
+ const seen = new Set();
270
+ const parts = [];
271
+ for (const item of [...frameworks, ...langs]) {
272
+ if (item && !seen.has(item)) {
273
+ seen.add(item);
274
+ parts.push(item);
275
+ }
276
+ }
277
+ return parts.slice(0, 6).join(", ");
278
+ }
177
279
  /**
178
280
  * Returns true iff `next` contains every member of `prev` plus at least one
179
281
  * additional language. Used to gate system-prompt rebuilds: we only re-inject
@@ -1 +1 @@
1
- {"version":3,"file":"language-detector.js","sourceRoot":"","sources":["../../src/core/language-detector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"language-detector.js","sourceRoot":"","sources":["../../src/core/language-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Semantic AST-chunk retrieval vs whole-file reads — real-API measurement of
3
+ * whether Feature #3 is worth building.
4
+ *
5
+ * The claim (cocoindex-code / oh-my-pi): replacing "grep then read whole files"
6
+ * with "retrieve only the relevant AST chunks" cuts ~70% of the tokens an agent
7
+ * spends locating code, with no loss of answer quality. We test that directly on
8
+ * OUR OWN repo against a live model.
9
+ *
10
+ * For a set of natural-language questions about real files in this repo, we build
11
+ * three context strategies and ask the model the same question with each:
12
+ *
13
+ * BASELINE (whole-file): deliver the FULL text of the top files a lexical
14
+ * grep would surface — this is what the agent reads today (read + grep).
15
+ *
16
+ * SEMANTIC (AST chunks): parse every file into top-level declarations
17
+ * (functions / classes / interfaces / consts), rank chunks with a real BM25
18
+ * retriever, and deliver only the top-k chunks. No embedding model needed; a
19
+ * learned embedding retriever would land between BM25 and ORACLE.
20
+ *
21
+ * ORACLE (upper bound): deliver only the hand-labelled answer chunk(s) — the
22
+ * best case any retriever could achieve.
23
+ *
24
+ * We measure, per question and strategy: INPUT tokens delivered (the headline
25
+ * cost) and whether the model's answer was correct (deterministic keyword grade).
26
+ * The verdict: does SEMANTIC reach BASELINE-level correctness at a fraction of
27
+ * the input tokens?
28
+ *
29
+ * Usage:
30
+ * npx tsx src/core/semantic-search-benchmark.ts
31
+ *
32
+ * Env overrides:
33
+ * GG_SS_PROVIDER / GG_SS_MODEL (default openai / gpt-5.5)
34
+ * GG_SS_TOPK (chunks/files delivered, default 3)
35
+ */
36
+ export declare function grade(answer: string, mustInclude: string[]): boolean;
37
+ //# sourceMappingURL=semantic-search-benchmark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-search-benchmark.d.ts","sourceRoot":"","sources":["../../src/core/semantic-search-benchmark.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAwHH,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAGpE"}