grepmax 0.26.69 → 0.26.71
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/.claude-plugin/marketplace.json +1 -1
- package/DOCUMENT-SEARCH.md +113 -0
- package/README.md +24 -0
- package/dist/bin.js +11 -2
- package/dist/commands/audit.js +9 -1
- package/dist/commands/mcp.js +16 -3
- package/dist/commands/project.js +7 -1
- package/dist/commands/skeleton.js +13 -10
- package/dist/commands/surprises.js +2 -0
- package/dist/lib/analysis/surprising-connections.js +16 -2
- package/dist/lib/daemon/daemon.js +50 -0
- package/dist/lib/daemon/document-search-handler.js +194 -0
- package/dist/lib/daemon/graph-handler.js +23 -8
- package/dist/lib/daemon/ipc-handler.js +29 -2
- package/dist/lib/daemon/rows-handler.js +48 -4
- package/dist/lib/mcp/document-contract.js +281 -0
- package/dist/lib/mcp/document-search.js +274 -0
- package/dist/lib/output/agent-budget.js +39 -0
- package/dist/lib/output/project-coverage.js +16 -0
- package/dist/lib/store/vector-db.js +13 -0
- package/dist/lib/utils/resource-budget.js +29 -1
- package/dist/lib/workers/embeddings/granite.js +8 -3
- package/dist/lib/workers/embeddings/mlx-client.js +27 -0
- package/dist/lib/workers/orchestrator.js +47 -9
- package/dist/lib/workers/pool.js +85 -3
- package/dist/lib/workers/process-child.js +22 -5
- package/dist/lib/workers/worker.js +4 -1
- package/package.json +5 -3
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.documentFilter = documentFilter;
|
|
46
|
+
exports.handleDocumentSearch = handleDocumentSearch;
|
|
47
|
+
const path = __importStar(require("node:path"));
|
|
48
|
+
const document_contract_1 = require("../mcp/document-contract");
|
|
49
|
+
function sqlString(input) {
|
|
50
|
+
return `'${input.replace(/'/g, "''")}'`;
|
|
51
|
+
}
|
|
52
|
+
function documentFilter(prefixes) {
|
|
53
|
+
return `(${prefixes
|
|
54
|
+
.map((prefix) => {
|
|
55
|
+
const dir = prefix.endsWith(path.sep) ? prefix : prefix + path.sep;
|
|
56
|
+
return `(path = ${sqlString(prefix)} OR (path >= ${sqlString(dir)} AND path < ${sqlString(`${dir}\uffff`)}))`;
|
|
57
|
+
})
|
|
58
|
+
.join(" OR ")}) AND lower(path) LIKE '%.md'`;
|
|
59
|
+
}
|
|
60
|
+
function handleDocumentSearch(deps, cmd, signal) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
var _c, _d;
|
|
64
|
+
try {
|
|
65
|
+
const deadline = performance.now() + document_contract_1.DOCUMENT_LIMITS.deadlineMs;
|
|
66
|
+
signal = AbortSignal.any([
|
|
67
|
+
signal,
|
|
68
|
+
AbortSignal.timeout(document_contract_1.DOCUMENT_LIMITS.deadlineMs),
|
|
69
|
+
]);
|
|
70
|
+
signal.throwIfAborted();
|
|
71
|
+
if (cmd.contractVersion !== document_contract_1.DOCUMENT_CONTRACT_VERSION)
|
|
72
|
+
return (0, document_contract_1.documentFailure)("unsupported_tool");
|
|
73
|
+
if (deps.state() !== "ready")
|
|
74
|
+
return (0, document_contract_1.documentFailure)(deps.state());
|
|
75
|
+
if (typeof cmd.checkout !== "string")
|
|
76
|
+
return (0, document_contract_1.documentFailure)("no_index");
|
|
77
|
+
const context = (0, document_contract_1.selectDocumentContext)(deps.home, cmd.checkout);
|
|
78
|
+
if (cmd.projectRoot !== context.wireRoot || cmd.store !== context.store)
|
|
79
|
+
return (0, document_contract_1.documentFailure)("store_unavailable");
|
|
80
|
+
const embeddingState = deps.embeddingState(context.wireRoot);
|
|
81
|
+
if (embeddingState !== "ready")
|
|
82
|
+
return (0, document_contract_1.documentFailure)(embeddingState);
|
|
83
|
+
const generation = deps.generation();
|
|
84
|
+
if (!(0, document_contract_1.documentGeneration)(generation))
|
|
85
|
+
return (0, document_contract_1.documentFailure)("index_unavailable");
|
|
86
|
+
if (!(0, document_contract_1.documentGeneration)(cmd.generation) || cmd.generation !== generation)
|
|
87
|
+
return (0, document_contract_1.documentFailure)("embedding_mismatch");
|
|
88
|
+
const recheck = () => {
|
|
89
|
+
signal.throwIfAborted();
|
|
90
|
+
if (performance.now() >= deadline)
|
|
91
|
+
throw new Error("timeout");
|
|
92
|
+
if (deps.state() !== "ready")
|
|
93
|
+
throw new Error(deps.state());
|
|
94
|
+
if (deps.generation() !== generation ||
|
|
95
|
+
deps.embeddingState(context.wireRoot) !== "ready")
|
|
96
|
+
throw new Error("embedding_mismatch");
|
|
97
|
+
};
|
|
98
|
+
const base = {
|
|
99
|
+
ok: true,
|
|
100
|
+
root: context.root,
|
|
101
|
+
store: context.store,
|
|
102
|
+
generation,
|
|
103
|
+
};
|
|
104
|
+
if (cmd.cmd === "documents.status") {
|
|
105
|
+
const { paths, requested } = (0, document_contract_1.documentCoveragePaths)(cmd.paths, context);
|
|
106
|
+
const covered = paths.flatMap((file) => {
|
|
107
|
+
const entry = deps.meta(file);
|
|
108
|
+
return (entry === null || entry === void 0 ? void 0 : entry.hasVectors) === true
|
|
109
|
+
? [
|
|
110
|
+
Object.assign(Object.assign({ path: file }, (entry.hashVersion === 1 && /^[a-f0-9]{64}$/.test(entry.hash)
|
|
111
|
+
? { hash: entry.hash, hashAlgorithm: "sha256-bytes" }
|
|
112
|
+
: {})), ((0, document_contract_1.documentMtime)(entry.mtimeMs) !== null
|
|
113
|
+
? { indexedMtimeMs: entry.mtimeMs }
|
|
114
|
+
: {})),
|
|
115
|
+
]
|
|
116
|
+
: [];
|
|
117
|
+
});
|
|
118
|
+
recheck();
|
|
119
|
+
const state = (0, document_contract_1.documentQueryState)(deps.queryState());
|
|
120
|
+
return Object.assign(Object.assign({}, base), { embeddingReady: state === "ready", queryState: state, lastIndexed: (_c = (0, document_contract_1.documentIndexedAt)((_a = deps.lastIndexed) === null || _a === void 0 ? void 0 : _a.call(deps, context.wireRoot))) !== null && _c !== void 0 ? _c : context.lastIndexed, indexState: (0, document_contract_1.documentIndexState)(deps.indexState(context.wireRoot)), covered, coverage: {
|
|
121
|
+
requested,
|
|
122
|
+
indexed: covered.length,
|
|
123
|
+
partial: covered.length !== requested,
|
|
124
|
+
} });
|
|
125
|
+
}
|
|
126
|
+
if (cmd.cmd !== "documents.search")
|
|
127
|
+
return (0, document_contract_1.documentFailure)("unsupported_tool");
|
|
128
|
+
if (typeof cmd.query !== "string" ||
|
|
129
|
+
!cmd.query.trim() ||
|
|
130
|
+
cmd.query.length > document_contract_1.DOCUMENT_LIMITS.query)
|
|
131
|
+
return (0, document_contract_1.documentFailure)("search_unavailable");
|
|
132
|
+
const prefixes = (0, document_contract_1.documentPaths)(cmd.prefixes, context, "prefixes");
|
|
133
|
+
const state = deps.queryState();
|
|
134
|
+
if (state !== "ready")
|
|
135
|
+
return (0, document_contract_1.documentFailure)(state);
|
|
136
|
+
recheck();
|
|
137
|
+
const encoded = yield deps.encode(cmd.query, signal);
|
|
138
|
+
recheck();
|
|
139
|
+
if (!encoded.dense.length || !encoded.dense.every(Number.isFinite))
|
|
140
|
+
return (0, document_contract_1.documentFailure)("embedding_unavailable");
|
|
141
|
+
const table = yield deps.table();
|
|
142
|
+
recheck();
|
|
143
|
+
const remainingMs = Math.floor(deadline - performance.now());
|
|
144
|
+
if (remainingMs <= 0)
|
|
145
|
+
throw new Error("timeout");
|
|
146
|
+
// Await the actual native promise, not a JS timeout race. The caller's
|
|
147
|
+
// bridge/signal has its own deadline; shared ownership must remain until
|
|
148
|
+
// native completion, even if the SDK fails to honor its native timeout.
|
|
149
|
+
const rows = (yield table
|
|
150
|
+
.vectorSearch(encoded.dense)
|
|
151
|
+
.distanceType("cosine")
|
|
152
|
+
.where(documentFilter(prefixes))
|
|
153
|
+
.select(["path", "hash", "start_line", "end_line", "_distance"])
|
|
154
|
+
.limit(document_contract_1.DOCUMENT_LIMITS.candidates)
|
|
155
|
+
.toArray({ timeoutMs: remainingMs }));
|
|
156
|
+
recheck();
|
|
157
|
+
const matches = rows.slice(0, document_contract_1.DOCUMENT_LIMITS.candidates).flatMap((row) => {
|
|
158
|
+
if (typeof row.path !== "string" ||
|
|
159
|
+
!prefixes.some((prefix) => row.path === prefix || row.path.startsWith(prefix + path.sep)))
|
|
160
|
+
return [];
|
|
161
|
+
const file = (0, document_contract_1.canonicalPointer)(row.path, context);
|
|
162
|
+
if (!file ||
|
|
163
|
+
!Number.isInteger(row.start_line) ||
|
|
164
|
+
row.start_line < 0 ||
|
|
165
|
+
!Number.isInteger(row.end_line) ||
|
|
166
|
+
row.end_line < row.start_line ||
|
|
167
|
+
!Number.isFinite(row._distance))
|
|
168
|
+
return [];
|
|
169
|
+
const entry = deps.meta(row.path);
|
|
170
|
+
// Only a matching current metadata revision proves this row's digest is bytes.
|
|
171
|
+
const hash = (entry === null || entry === void 0 ? void 0 : entry.hashVersion) === 1 &&
|
|
172
|
+
entry.hasVectors === true &&
|
|
173
|
+
row.hash === entry.hash &&
|
|
174
|
+
/^[a-f0-9]{64}$/.test(row.hash)
|
|
175
|
+
? { hash: row.hash, hashAlgorithm: "sha256-bytes" }
|
|
176
|
+
: {};
|
|
177
|
+
return [
|
|
178
|
+
Object.assign({ path: file, startLine: row.start_line + 1, endLine: row.end_line + 1, score: 1 / (1 + Math.max(0, row._distance)) }, hash),
|
|
179
|
+
];
|
|
180
|
+
});
|
|
181
|
+
return Object.assign(Object.assign({}, base), { indexState: (0, document_contract_1.documentIndexState)(deps.indexState(context.wireRoot)), matches, retrieval: "dense", candidateLimit: document_contract_1.DOCUMENT_LIMITS.candidates });
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const e = error;
|
|
185
|
+
return (0, document_contract_1.documentFailure)(signal.aborted
|
|
186
|
+
? ((_b = signal.reason) === null || _b === void 0 ? void 0 : _b.name) === "TimeoutError"
|
|
187
|
+
? "timeout"
|
|
188
|
+
: "cancelled"
|
|
189
|
+
: e.name === "QueryTimeoutError"
|
|
190
|
+
? "timeout"
|
|
191
|
+
: ((_d = e.code) !== null && _d !== void 0 ? _d : e.message));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
@@ -537,13 +537,15 @@ function findFileCycles(deps, prefix, top) {
|
|
|
537
537
|
* `top` caps each list; `deadTotal` reports the full pre-cap dead count.
|
|
538
538
|
*/
|
|
539
539
|
function computeAudit(rows, prefix, top) {
|
|
540
|
-
var _a;
|
|
541
|
-
var
|
|
542
|
-
|
|
540
|
+
var _a, _b, _c, _d, _e, _f;
|
|
541
|
+
var _g;
|
|
542
|
+
var _h;
|
|
543
|
+
// Only a uniquely defined name can establish an architectural edge.
|
|
543
544
|
const defs = new Map();
|
|
544
545
|
// Distinct files defining each name — name-based edges can't tell same-name
|
|
545
546
|
// symbols apart, so multi-file definitions get flagged in the output.
|
|
546
547
|
const defFileCounts = new Map();
|
|
548
|
+
const defLocations = new Map();
|
|
547
549
|
// Distinct files that reference a symbol (cross-file inbound edges).
|
|
548
550
|
const inboundFiles = new Map();
|
|
549
551
|
const inboundTotal = new Map();
|
|
@@ -562,9 +564,15 @@ function computeAudit(rows, prefix, top) {
|
|
|
562
564
|
if (!defs.has(s)) {
|
|
563
565
|
defs.set(s, { file, line, exported, complexity: 0 });
|
|
564
566
|
}
|
|
567
|
+
else {
|
|
568
|
+
(_h = defs.get(s)).exported || (_h.exported = exported);
|
|
569
|
+
}
|
|
565
570
|
if (!defFileCounts.has(s))
|
|
566
571
|
defFileCounts.set(s, new Set());
|
|
567
572
|
defFileCounts.get(s).add(file);
|
|
573
|
+
if (!defLocations.has(s))
|
|
574
|
+
defLocations.set(s, new Set());
|
|
575
|
+
defLocations.get(s).add(`${file}:${line}`);
|
|
568
576
|
if (!fileDefs.has(file))
|
|
569
577
|
fileDefs.set(file, new Set());
|
|
570
578
|
fileDefs.get(file).add(s);
|
|
@@ -586,7 +594,7 @@ function computeAudit(rows, prefix, top) {
|
|
|
586
594
|
continue;
|
|
587
595
|
// Builtin method names (get, set, push, …) leak in via prototype/member
|
|
588
596
|
// definitions and their inbound counts are meaningless name collisions.
|
|
589
|
-
if ((0, callsites_1.isBuiltinCallee)(symbol))
|
|
597
|
+
if ((0, callsites_1.isBuiltinCallee)(symbol) || ((_a = defLocations.get(symbol)) === null || _a === void 0 ? void 0 : _a.size) !== 1)
|
|
590
598
|
continue;
|
|
591
599
|
const refFiles = inboundFiles.get(symbol);
|
|
592
600
|
if (!refFiles)
|
|
@@ -603,7 +611,7 @@ function computeAudit(rows, prefix, top) {
|
|
|
603
611
|
line: info.line,
|
|
604
612
|
inboundFiles: external,
|
|
605
613
|
totalRefs: inboundTotal.get(symbol) || 0,
|
|
606
|
-
defFiles: (
|
|
614
|
+
defFiles: (_g = (_b = defFileCounts.get(symbol)) === null || _b === void 0 ? void 0 : _b.size) !== null && _g !== void 0 ? _g : 1,
|
|
607
615
|
});
|
|
608
616
|
}
|
|
609
617
|
godNodes.sort((a, b) => b.inboundFiles - a.inboundFiles || b.totalRefs - a.totalRefs);
|
|
@@ -613,6 +621,8 @@ function computeAudit(rows, prefix, top) {
|
|
|
613
621
|
for (const [file, syms] of fileDefs) {
|
|
614
622
|
const dependents = new Set();
|
|
615
623
|
for (const s of syms) {
|
|
624
|
+
if ((0, callsites_1.isBuiltinCallee)(s) || ((_c = defLocations.get(s)) === null || _c === void 0 ? void 0 : _c.size) !== 1)
|
|
625
|
+
continue;
|
|
616
626
|
const refFiles = inboundFiles.get(s);
|
|
617
627
|
if (!refFiles)
|
|
618
628
|
continue;
|
|
@@ -626,7 +636,9 @@ function computeAudit(rows, prefix, top) {
|
|
|
626
636
|
const out = fileOutRefs.get(file);
|
|
627
637
|
if (out)
|
|
628
638
|
for (const s of out)
|
|
629
|
-
if (defs.has(s)
|
|
639
|
+
if (defs.has(s) &&
|
|
640
|
+
!(0, callsites_1.isBuiltinCallee)(s) &&
|
|
641
|
+
((_d = defLocations.get(s)) === null || _d === void 0 ? void 0 : _d.size) === 1)
|
|
630
642
|
fanOut++;
|
|
631
643
|
hubFiles.push({
|
|
632
644
|
file: rel(file, prefix),
|
|
@@ -639,7 +651,7 @@ function computeAudit(rows, prefix, top) {
|
|
|
639
651
|
const fileDeps = new Map();
|
|
640
652
|
for (const [file, refs] of fileOutRefs) {
|
|
641
653
|
for (const s of refs) {
|
|
642
|
-
if ((0, callsites_1.isBuiltinCallee)(s))
|
|
654
|
+
if ((0, callsites_1.isBuiltinCallee)(s) || ((_e = defLocations.get(s)) === null || _e === void 0 ? void 0 : _e.size) !== 1)
|
|
643
655
|
continue;
|
|
644
656
|
const defFiles = defFileCounts.get(s);
|
|
645
657
|
if (!defFiles || defFiles.size !== 1)
|
|
@@ -657,7 +669,9 @@ function computeAudit(rows, prefix, top) {
|
|
|
657
669
|
// references anywhere (including their own file).
|
|
658
670
|
const deadAll = [];
|
|
659
671
|
for (const [symbol, info] of defs) {
|
|
660
|
-
if (info.exported
|
|
672
|
+
if (info.exported ||
|
|
673
|
+
((_f = defLocations.get(symbol)) === null || _f === void 0 ? void 0 : _f.size) !== 1 ||
|
|
674
|
+
(0, callsites_1.isBuiltinCallee)(symbol))
|
|
661
675
|
continue;
|
|
662
676
|
if ((inboundTotal.get(symbol) || 0) > 0)
|
|
663
677
|
continue;
|
|
@@ -665,6 +679,7 @@ function computeAudit(rows, prefix, top) {
|
|
|
665
679
|
}
|
|
666
680
|
deadAll.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
667
681
|
return {
|
|
682
|
+
ambiguousSymbols: [...defLocations.values()].filter((locations) => locations.size > 1).length,
|
|
668
683
|
scannedChunks: rows.length,
|
|
669
684
|
scannedFiles: files.size,
|
|
670
685
|
godNodes: godNodes.slice(0, top),
|
|
@@ -133,13 +133,17 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
133
133
|
cmd.cmd !== "shutdown" &&
|
|
134
134
|
(daemon.operationStatus() === "closing" ||
|
|
135
135
|
daemon.operationStatus() === "closed")) {
|
|
136
|
-
return
|
|
136
|
+
return cmd.cmd === "documents.status" || cmd.cmd === "documents.search"
|
|
137
|
+
? { ok: false, state: "busy" }
|
|
138
|
+
: errorResponse(new operation_coordinator_1.OperationClosedError());
|
|
137
139
|
}
|
|
138
140
|
// The socket listens before LanceDB/MetaCache are open so liveness probes
|
|
139
141
|
// succeed during slow startup. Gate resource-dependent commands until those
|
|
140
142
|
// stores exist; ping/shutdown must always work (probes + restart).
|
|
141
143
|
if (cmd.cmd !== "ping" && cmd.cmd !== "shutdown" && !daemon.isReady()) {
|
|
142
|
-
return
|
|
144
|
+
return cmd.cmd === "documents.status" || cmd.cmd === "documents.search"
|
|
145
|
+
? { ok: false, state: "index_unavailable" }
|
|
146
|
+
: { ok: false, error: "daemon initializing" };
|
|
143
147
|
}
|
|
144
148
|
switch (cmd.cmd) {
|
|
145
149
|
case "ping":
|
|
@@ -157,6 +161,7 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
157
161
|
exclusiveGenerationRebuild: exports.EXCLUSIVE_GENERATION_REBUILD_PROTOCOL,
|
|
158
162
|
readVerbs: read_verbs_1.READ_VERBS_PROTOCOL,
|
|
159
163
|
searchDiagnostics: 1,
|
|
164
|
+
existingIndexOnlySearch: 1,
|
|
160
165
|
perFileSearch: 1,
|
|
161
166
|
// `watch`/`unwatch` accept holder/pid/ttlMs. A daemon without this
|
|
162
167
|
// treats `unwatch` as unwatch-for-everyone, so clients releasing a
|
|
@@ -225,6 +230,28 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
225
230
|
setImmediate(() => daemon.shutdown());
|
|
226
231
|
return { ok: true };
|
|
227
232
|
}
|
|
233
|
+
case "documents.status":
|
|
234
|
+
case "documents.search": {
|
|
235
|
+
const ac = new AbortController();
|
|
236
|
+
const close = () => ac.abort();
|
|
237
|
+
conn.once("close", close);
|
|
238
|
+
try {
|
|
239
|
+
return yield daemon.documentSearch(cmd, ac.signal);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
return {
|
|
243
|
+
ok: false,
|
|
244
|
+
state: ac.signal.aborted
|
|
245
|
+
? "cancelled"
|
|
246
|
+
: error instanceof operation_coordinator_1.OperationBusyError
|
|
247
|
+
? "busy"
|
|
248
|
+
: "index_unavailable",
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
conn.off("close", close);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
228
255
|
case "search":
|
|
229
256
|
case "search-v2": {
|
|
230
257
|
const isV2 = cmd.cmd === "search-v2";
|
|
@@ -41,8 +41,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
41
41
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
45
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
46
|
+
var m = o[Symbol.asyncIterator], i;
|
|
47
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
48
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
49
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
50
|
+
};
|
|
44
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.MAX_LOCATE_ROWS = exports.ReadVerbError = void 0;
|
|
52
|
+
exports.MAX_LOCATE_ROWS = exports.MAX_PROJECT_ROWS = exports.ReadVerbError = void 0;
|
|
46
53
|
exports.withLocalStore = withLocalStore;
|
|
47
54
|
exports.scopeToWire = scopeToWire;
|
|
48
55
|
exports.assertReadableProject = assertReadableProject;
|
|
@@ -51,6 +58,7 @@ exports.clampInt = clampInt;
|
|
|
51
58
|
exports.asReadVerbResponse = asReadVerbResponse;
|
|
52
59
|
exports.runSymbols = runSymbols;
|
|
53
60
|
exports.handleRowsSymbols = handleRowsSymbols;
|
|
61
|
+
exports.countProjectRows = countProjectRows;
|
|
54
62
|
exports.runProject = runProject;
|
|
55
63
|
exports.handleRowsProject = handleRowsProject;
|
|
56
64
|
exports.runLocate = runLocate;
|
|
@@ -270,15 +278,42 @@ function handleRowsSymbols(deps, payload) {
|
|
|
270
278
|
}));
|
|
271
279
|
});
|
|
272
280
|
}
|
|
281
|
+
// --- rows.project -----------------------------------------------------------
|
|
282
|
+
exports.MAX_PROJECT_ROWS = 200000;
|
|
283
|
+
/** Count a path-only stream in bounded Arrow batches with a native deadline.
|
|
284
|
+
* The SDK's countRows API has no execution timeout. */
|
|
285
|
+
function countProjectRows(query, timeoutMs) {
|
|
286
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
287
|
+
var _a, e_1, _b, _c;
|
|
288
|
+
let count = 0;
|
|
289
|
+
try {
|
|
290
|
+
for (var _d = true, _e = __asyncValues((0, query_timeout_1.streamQueryRows)(query, "project inventory count", timeoutMs)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
|
291
|
+
_c = _f.value;
|
|
292
|
+
_d = false;
|
|
293
|
+
const _row = _c;
|
|
294
|
+
count++;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
298
|
+
finally {
|
|
299
|
+
try {
|
|
300
|
+
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
|
|
301
|
+
}
|
|
302
|
+
finally { if (e_1) throw e_1.error; }
|
|
303
|
+
}
|
|
304
|
+
return count;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
273
307
|
/**
|
|
274
308
|
* The `project` scan and its aggregation. Returns the finished overview rather
|
|
275
309
|
* than the (up to 200 000) rows it was computed from — see the file header.
|
|
276
310
|
*/
|
|
277
311
|
function runProject(deps, projectRoot) {
|
|
278
312
|
return __awaiter(this, void 0, void 0, function* () {
|
|
313
|
+
var _a;
|
|
279
314
|
const table = yield tableOf(deps);
|
|
280
315
|
const prefix = projectRoot.endsWith("/") ? projectRoot : `${projectRoot}/`;
|
|
281
|
-
const
|
|
316
|
+
const scanned = yield table
|
|
282
317
|
.query()
|
|
283
318
|
.select([
|
|
284
319
|
"path",
|
|
@@ -289,8 +324,15 @@ function runProject(deps, projectRoot) {
|
|
|
289
324
|
"referenced_symbols",
|
|
290
325
|
])
|
|
291
326
|
.where((0, filter_builder_1.pathStartsWith)(prefix))
|
|
292
|
-
.limit(
|
|
293
|
-
.toArray(
|
|
327
|
+
.limit(exports.MAX_PROJECT_ROWS + 1)
|
|
328
|
+
.toArray({
|
|
329
|
+
timeoutMs: (_a = deps.queryTimeoutMs) !== null && _a !== void 0 ? _a : query_timeout_1.QUERY_EXECUTION_OPTIONS.timeoutMs,
|
|
330
|
+
});
|
|
331
|
+
const sampled = scanned.length > exports.MAX_PROJECT_ROWS;
|
|
332
|
+
const rows = sampled ? scanned.slice(0, exports.MAX_PROJECT_ROWS) : scanned;
|
|
333
|
+
const totalChunks = sampled
|
|
334
|
+
? yield countProjectRows(table.query().select(["path"]).where((0, filter_builder_1.pathStartsWith)(prefix)), deps.queryTimeoutMs)
|
|
335
|
+
: rows.length;
|
|
294
336
|
const nodePath = yield Promise.resolve().then(() => __importStar(require("node:path")));
|
|
295
337
|
const files = new Set();
|
|
296
338
|
const extCounts = new Map();
|
|
@@ -343,6 +385,8 @@ function runProject(deps, projectRoot) {
|
|
|
343
385
|
}
|
|
344
386
|
}
|
|
345
387
|
return {
|
|
388
|
+
sampled,
|
|
389
|
+
totalChunks,
|
|
346
390
|
chunks: rows.length,
|
|
347
391
|
files: files.size,
|
|
348
392
|
extEntries: Array.from(extCounts.entries())
|