grepmax 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * Measure-first prototype for Graphify Phase 3 "surprising connections".
4
+ *
5
+ * It samples indexed code chunks, asks LanceDB for each chunk's nearest vector
6
+ * neighbors, then filters out pairs that are already obvious. Output is grouped
7
+ * by file pair and scored for actionability. This is deliberately an eval
8
+ * harness; the product surface is `gmax surprises --experimental`.
9
+ *
10
+ * Run:
11
+ * pnpm bench:surprises
12
+ * pnpm bench:surprises -- --sample 300 --neighbors 25 --top 30
13
+ * pnpm bench:surprises:json
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
49
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
50
+ return new (P || (P = Promise))(function (resolve, reject) {
51
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
52
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
53
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
54
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
55
+ });
56
+ };
57
+ Object.defineProperty(exports, "__esModule", { value: true });
58
+ const path = __importStar(require("node:path"));
59
+ const surprising_connections_1 = require("./lib/analysis/surprising-connections");
60
+ const vector_db_1 = require("./lib/store/vector-db");
61
+ const exit_1 = require("./lib/utils/exit");
62
+ const project_root_1 = require("./lib/utils/project-root");
63
+ function argValue(name) {
64
+ const prefix = `${name}=`;
65
+ for (let i = 2; i < process.argv.length; i++) {
66
+ const arg = process.argv[i];
67
+ if (arg === name)
68
+ return process.argv[i + 1];
69
+ if (arg.startsWith(prefix))
70
+ return arg.slice(prefix.length);
71
+ }
72
+ return undefined;
73
+ }
74
+ function argValues(name) {
75
+ const values = [];
76
+ const prefix = `${name}=`;
77
+ for (let i = 2; i < process.argv.length; i++) {
78
+ const arg = process.argv[i];
79
+ if (arg === name && process.argv[i + 1]) {
80
+ values.push(process.argv[i + 1]);
81
+ i++;
82
+ }
83
+ else if (arg.startsWith(prefix)) {
84
+ values.push(arg.slice(prefix.length));
85
+ }
86
+ }
87
+ return values.length > 0 ? values : undefined;
88
+ }
89
+ function hasFlag(name) {
90
+ return process.argv.includes(name);
91
+ }
92
+ function intOpt(name, envName, fallback) {
93
+ var _a;
94
+ const raw = (_a = argValue(name)) !== null && _a !== void 0 ? _a : process.env[envName];
95
+ const parsed = Number.parseInt(raw !== null && raw !== void 0 ? raw : "", 10);
96
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
97
+ }
98
+ function floatOpt(name, envName, fallback) {
99
+ var _a;
100
+ const raw = (_a = argValue(name)) !== null && _a !== void 0 ? _a : process.env[envName];
101
+ const parsed = Number.parseFloat(raw !== null && raw !== void 0 ? raw : "");
102
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
103
+ }
104
+ function run() {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ var _a, _b;
107
+ const root = path.resolve((_a = argValue("--root")) !== null && _a !== void 0 ? _a : process.cwd());
108
+ const projectRoot = (_b = (0, project_root_1.findProjectRoot)(root)) !== null && _b !== void 0 ? _b : root;
109
+ const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
110
+ const vectorDb = new vector_db_1.VectorDB(paths.lancedbDir);
111
+ const table = yield vectorDb.ensureTable();
112
+ const top = intOpt("--top", "GMAX_SURPRISE_TOP", 25);
113
+ const json = hasFlag("--json") || process.env.GMAX_EVAL_JSON === "1";
114
+ const log = json ? console.error : console.log;
115
+ const result = yield (0, surprising_connections_1.analyzeSurprisingConnections)(table, projectRoot, {
116
+ sample: intOpt("--sample", "GMAX_SURPRISE_SAMPLE", surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.sample),
117
+ neighbors: intOpt("--neighbors", "GMAX_SURPRISE_NEIGHBORS", surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.neighbors),
118
+ dirDepth: intOpt("--dir-depth", "GMAX_SURPRISE_DIR_DEPTH", surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.dirDepth),
119
+ minSimilarity: floatOpt("--min-sim", "GMAX_SURPRISE_MIN_SIM", surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.minSimilarity),
120
+ maxRows: intOpt("--max-rows", "GMAX_SURPRISE_MAX_ROWS", surprising_connections_1.DEFAULT_SURPRISE_OPTIONS.maxRows),
121
+ includeTests: hasFlag("--include-tests"),
122
+ includeEval: hasFlag("--include-eval"),
123
+ in: argValues("--in"),
124
+ exclude: argValues("--exclude"),
125
+ });
126
+ const { summary, findings } = result;
127
+ const topFindings = findings.slice(0, top);
128
+ log(`Surprising-connections prototype: ${summary.sampledAnchors} sampled chunks from ${summary.codeRows} code chunks (${summary.rows} indexed rows)`);
129
+ if (json) {
130
+ process.stdout.write(`${JSON.stringify({
131
+ summary,
132
+ findings: topFindings.map((finding) => ({
133
+ score: finding.score,
134
+ maxSimilarity: finding.maxSimilarity,
135
+ medianSimilarity: finding.medianSimilarity,
136
+ pairCount: finding.pairCount,
137
+ files: [finding.fileA, finding.fileB],
138
+ reasons: finding.reasons,
139
+ topSimilarities: finding.topSimilarities,
140
+ representative: {
141
+ similarity: Number(finding.representative.similarity.toFixed(3)),
142
+ distance: Number(finding.representative.distance.toFixed(3)),
143
+ scoreParts: finding.representative.scoreParts,
144
+ source: {
145
+ file: finding.representative.source.relPath,
146
+ line: finding.representative.source.startLine + 1,
147
+ symbols: finding.representative.source.definedSymbols.slice(0, 4),
148
+ role: finding.representative.source.role,
149
+ },
150
+ target: {
151
+ file: finding.representative.target.relPath,
152
+ line: finding.representative.target.startLine + 1,
153
+ symbols: finding.representative.target.definedSymbols.slice(0, 4),
154
+ role: finding.representative.target.role,
155
+ },
156
+ },
157
+ })),
158
+ }, null, 2)}\n`);
159
+ }
160
+ else {
161
+ console.log("\nSummary");
162
+ console.log(` project: ${projectRoot}`);
163
+ console.log(` rows/code rows: ${summary.rows}/${summary.codeRows}`);
164
+ console.log(` sampled anchors: ${summary.sampledAnchors}`);
165
+ console.log(` graph file edges: ${summary.graphFileEdges}`);
166
+ console.log(` accepted pairs/file-pairs: ${summary.acceptedPairs}/${summary.acceptedFilePairs}`);
167
+ console.log(` similarity p50/p90/max: ${summary.similarity.p50}/${summary.similarity.p90}/${summary.similarity.max}`);
168
+ console.log(` score p50/p90/max: ${summary.actionabilityScore.p50}/${summary.actionabilityScore.p90}/${summary.actionabilityScore.max}`);
169
+ console.log(` filtered: same-file ${summary.filters.sameFile}, same-dir ${summary.filters.sameDirBucket}, graph-edge ${summary.filters.graphEdge}, tests ${summary.filters.tests}`);
170
+ console.log("\nTop grouped surprising connections");
171
+ if (topFindings.length === 0) {
172
+ console.log(" none");
173
+ }
174
+ else {
175
+ for (const finding of topFindings) {
176
+ const pair = finding.representative;
177
+ console.log(` score=${finding.score.toFixed(3)} sim=${finding.maxSimilarity.toFixed(3)} pairs=${finding.pairCount} ${finding.fileA}`);
178
+ console.log(` <-> ${finding.fileB}`);
179
+ console.log(` best: ${(0, surprising_connections_1.lineLabel)(pair.source)} <-> ${(0, surprising_connections_1.lineLabel)(pair.target)}`);
180
+ console.log(` reasons: ${finding.reasons.join(", ") || "none"}`);
181
+ }
182
+ }
183
+ }
184
+ yield vectorDb.close();
185
+ yield (0, exit_1.gracefulExit)(0);
186
+ });
187
+ }
188
+ run().catch((error) => __awaiter(void 0, void 0, void 0, function* () {
189
+ console.error(error instanceof Error ? error.stack || error.message : error);
190
+ yield (0, exit_1.gracefulExit)(1);
191
+ }));
package/dist/index.js CHANGED
@@ -73,6 +73,7 @@ const similar_1 = require("./commands/similar");
73
73
  const skeleton_1 = require("./commands/skeleton");
74
74
  const status_1 = require("./commands/status");
75
75
  const summarize_1 = require("./commands/summarize");
76
+ const surprises_1 = require("./commands/surprises");
76
77
  const symbols_1 = require("./commands/symbols");
77
78
  const test_find_1 = require("./commands/test-find");
78
79
  const trace_1 = require("./commands/trace");
@@ -129,6 +130,7 @@ commander_1.program.addCommand(diff_1.diff);
129
130
  commander_1.program.addCommand(test_find_1.testFind);
130
131
  commander_1.program.addCommand(impact_1.impact);
131
132
  commander_1.program.addCommand(similar_1.similar);
133
+ commander_1.program.addCommand(surprises_1.surprises);
132
134
  commander_1.program.addCommand(context_1.context);
133
135
  // Services
134
136
  commander_1.program.addCommand(serve_1.serve);