@zqagent/core 0.3.16 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +161 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +161 -51
- package/dist/index.js.map +1 -1
- package/dist/internal/update/controller.cjs +1 -1
- package/dist/internal/update/controller.js +1 -1
- package/dist/internal/update/platform.cjs +1 -1
- package/dist/internal/update/platform.js +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -8861,6 +8861,9 @@ function nameOf(node) {
|
|
|
8861
8861
|
if (typeNode?.text) return typeNode.text.split("<")[0].trim();
|
|
8862
8862
|
return null;
|
|
8863
8863
|
}
|
|
8864
|
+
function spanOf(node) {
|
|
8865
|
+
return { line: node.startPosition.row + 1, endLine: node.endPosition.row + 1 };
|
|
8866
|
+
}
|
|
8864
8867
|
var MAX_COLLECT = 200;
|
|
8865
8868
|
var VARIABLE_DECLARATIONS = /* @__PURE__ */ new Set(["lexical_declaration", "variable_declaration"]);
|
|
8866
8869
|
var MODULE_CONTAINERS = /* @__PURE__ */ new Set([
|
|
@@ -8898,7 +8901,12 @@ function collectVariables(node, out, exported) {
|
|
|
8898
8901
|
if (!nameNode || nameNode.type !== "identifier") continue;
|
|
8899
8902
|
const isFn = isFunctionValue(decl);
|
|
8900
8903
|
if (!isFn && !exported) continue;
|
|
8901
|
-
out.push({
|
|
8904
|
+
out.push({
|
|
8905
|
+
name: nameNode.text,
|
|
8906
|
+
kind: isFn ? "function" : "const",
|
|
8907
|
+
exported,
|
|
8908
|
+
...spanOf(decl)
|
|
8909
|
+
});
|
|
8902
8910
|
}
|
|
8903
8911
|
}
|
|
8904
8912
|
function collect(node, ruleTypes, out, max, depth, exported = false, lang = "", inModule = false) {
|
|
@@ -8914,7 +8922,12 @@ function collect(node, ruleTypes, out, max, depth, exported = false, lang = "",
|
|
|
8914
8922
|
const name = nameOf(child);
|
|
8915
8923
|
const usable = name && !name.includes("\n") && name.length <= 80;
|
|
8916
8924
|
if (usable) {
|
|
8917
|
-
out.push({
|
|
8925
|
+
out.push({
|
|
8926
|
+
name,
|
|
8927
|
+
kind,
|
|
8928
|
+
exported: isExport || isPublicDeclaration(child, lang, name),
|
|
8929
|
+
...spanOf(child)
|
|
8930
|
+
});
|
|
8918
8931
|
if (RECORD_AND_DESCEND.has(child.type) && depth < MAX_DEPTH) {
|
|
8919
8932
|
collect(child, ruleTypes, out, max, depth + 1, isExport, lang, MODULE_CONTAINERS.has(child.type));
|
|
8920
8933
|
}
|
|
@@ -8929,7 +8942,8 @@ function collect(node, ruleTypes, out, max, depth, exported = false, lang = "",
|
|
|
8929
8942
|
out.push({
|
|
8930
8943
|
name: nameNode.text,
|
|
8931
8944
|
kind: "type",
|
|
8932
|
-
exported: isPublicDeclaration(spec, lang, nameNode.text)
|
|
8945
|
+
exported: isPublicDeclaration(spec, lang, nameNode.text),
|
|
8946
|
+
...spanOf(spec)
|
|
8933
8947
|
});
|
|
8934
8948
|
}
|
|
8935
8949
|
continue;
|
|
@@ -8958,10 +8972,13 @@ function prioritizeSymbols(symbols, maxSymbols) {
|
|
|
8958
8972
|
seen.add(s.name);
|
|
8959
8973
|
return true;
|
|
8960
8974
|
});
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
8975
|
+
const trimmed = unique.length <= maxSymbols ? unique : [...unique.filter((s) => s.exported), ...unique.filter((s) => !s.exported)].slice(
|
|
8976
|
+
0,
|
|
8977
|
+
maxSymbols
|
|
8978
|
+
);
|
|
8979
|
+
return trimmed.map(
|
|
8980
|
+
(s) => s.line === void 0 ? { name: s.name, kind: s.kind } : { name: s.name, kind: s.kind, line: s.line, endLine: s.endLine }
|
|
8981
|
+
);
|
|
8965
8982
|
}
|
|
8966
8983
|
function packageOf(tree, packageNode) {
|
|
8967
8984
|
if (!packageNode) return void 0;
|
|
@@ -8972,6 +8989,14 @@ function packageOf(tree, packageNode) {
|
|
|
8972
8989
|
}
|
|
8973
8990
|
return void 0;
|
|
8974
8991
|
}
|
|
8992
|
+
function countReexports(tree) {
|
|
8993
|
+
let n = 0;
|
|
8994
|
+
for (const child of tree.rootNode.children) {
|
|
8995
|
+
if (child.type !== "export_statement") continue;
|
|
8996
|
+
if (child.childForFieldName("source")) n += 1;
|
|
8997
|
+
}
|
|
8998
|
+
return n;
|
|
8999
|
+
}
|
|
8975
9000
|
async function extractWithTreeSitter(langId, bytes, source, maxSymbols) {
|
|
8976
9001
|
const rule = TS_RULES[langId];
|
|
8977
9002
|
if (!rule) return null;
|
|
@@ -8995,7 +9020,8 @@ async function extractWithTreeSitter(langId, bytes, source, maxSymbols) {
|
|
|
8995
9020
|
}
|
|
8996
9021
|
return {
|
|
8997
9022
|
symbols: prioritizeSymbols(symbols, maxSymbols),
|
|
8998
|
-
pkg: packageOf(tree, rule.packageNode)
|
|
9023
|
+
pkg: packageOf(tree, rule.packageNode),
|
|
9024
|
+
reexports: countReexports(tree)
|
|
8999
9025
|
};
|
|
9000
9026
|
} catch {
|
|
9001
9027
|
return null;
|
|
@@ -9008,6 +9034,13 @@ async function extractWithTreeSitter(langId, bytes, source, maxSymbols) {
|
|
|
9008
9034
|
// src/repomap/extract/regex.ts
|
|
9009
9035
|
init_cjs_shims();
|
|
9010
9036
|
var MAX_LINE_CHARS = 500;
|
|
9037
|
+
var REEXPORT_RE = /^export\s+(?:\*\s*(?:as\s+[\w$]+\s*)?|type\s*(?:\*\s*|\{[^}]*\}\s*)|\{[^}]*\}\s*)from\s+['"]/gm;
|
|
9038
|
+
var BLOCK_COMMENT_RE = /\/\*[\s\S]*?\*\//g;
|
|
9039
|
+
function countReexports2(source, langId) {
|
|
9040
|
+
if (langId !== "typescript" && langId !== "tsx" && langId !== "javascript") return 0;
|
|
9041
|
+
const text = source.includes("/*") ? source.replace(BLOCK_COMMENT_RE, "") : source;
|
|
9042
|
+
return text.match(REEXPORT_RE)?.length ?? 0;
|
|
9043
|
+
}
|
|
9011
9044
|
function stripBlockComments(line, state) {
|
|
9012
9045
|
let out = "";
|
|
9013
9046
|
let i = 0;
|
|
@@ -9041,7 +9074,8 @@ function extractWithRegex(langId, source, maxSymbols) {
|
|
|
9041
9074
|
let pkg;
|
|
9042
9075
|
const state = { inBlock: false };
|
|
9043
9076
|
const lines = source.split("\n");
|
|
9044
|
-
for (
|
|
9077
|
+
for (let i = 0; i < lines.length; i++) {
|
|
9078
|
+
const raw = lines[i];
|
|
9045
9079
|
if (symbols.length >= maxSymbols) break;
|
|
9046
9080
|
const stripped = stripBlockComments(raw, state);
|
|
9047
9081
|
const line = /^\s/.test(raw) ? stripped : stripped.replace(/^\s+/, "");
|
|
@@ -9054,9 +9088,9 @@ function extractWithRegex(langId, source, maxSymbols) {
|
|
|
9054
9088
|
if (!name) continue;
|
|
9055
9089
|
if (seen.has(name)) continue;
|
|
9056
9090
|
seen.add(name);
|
|
9057
|
-
symbols.push({ name, kind: rule.kind });
|
|
9091
|
+
symbols.push({ name, kind: rule.kind, line: i + 1 });
|
|
9058
9092
|
}
|
|
9059
|
-
return { symbols, pkg };
|
|
9093
|
+
return { symbols, pkg, reexports: countReexports2(source, langId) };
|
|
9060
9094
|
}
|
|
9061
9095
|
|
|
9062
9096
|
// src/repomap/grammar.ts
|
|
@@ -9114,6 +9148,7 @@ function markLoaded(langId) {
|
|
|
9114
9148
|
failedAt.delete(langId);
|
|
9115
9149
|
}
|
|
9116
9150
|
var inflight = /* @__PURE__ */ new Map();
|
|
9151
|
+
var readyCache = /* @__PURE__ */ new Map();
|
|
9117
9152
|
function grammarDir() {
|
|
9118
9153
|
const explicit = process.env.ZQAGENT_REPOMAP_GRAMMAR_DIR?.trim();
|
|
9119
9154
|
if (explicit) return explicit;
|
|
@@ -9137,10 +9172,7 @@ function verify(spec, buf) {
|
|
|
9137
9172
|
return sha256Hex(buf) === spec.sha256;
|
|
9138
9173
|
}
|
|
9139
9174
|
function readLocal(spec) {
|
|
9140
|
-
const
|
|
9141
|
-
const explicit = process.env.ZQAGENT_REPOMAP_GRAMMAR_DIR?.trim();
|
|
9142
|
-
if (explicit) candidates.push(path13.join(explicit, `${spec.id}.wasm`));
|
|
9143
|
-
for (const file of candidates) {
|
|
9175
|
+
for (const file of localCandidates(spec)) {
|
|
9144
9176
|
try {
|
|
9145
9177
|
const buf = fs11.readFileSync(file);
|
|
9146
9178
|
if (verify(spec, buf)) return new Uint8Array(buf);
|
|
@@ -9149,6 +9181,24 @@ function readLocal(spec) {
|
|
|
9149
9181
|
}
|
|
9150
9182
|
return null;
|
|
9151
9183
|
}
|
|
9184
|
+
function localCandidates(spec) {
|
|
9185
|
+
const candidates = [cachePath(spec)];
|
|
9186
|
+
const explicit = process.env.ZQAGENT_REPOMAP_GRAMMAR_DIR?.trim();
|
|
9187
|
+
if (explicit) candidates.push(path13.join(explicit, `${spec.id}.wasm`));
|
|
9188
|
+
return candidates;
|
|
9189
|
+
}
|
|
9190
|
+
function localSignature(spec) {
|
|
9191
|
+
const parts = [];
|
|
9192
|
+
for (const file of localCandidates(spec)) {
|
|
9193
|
+
try {
|
|
9194
|
+
const st = fs11.statSync(file);
|
|
9195
|
+
parts.push(`${st.mtimeMs}:${st.size}`);
|
|
9196
|
+
} catch {
|
|
9197
|
+
parts.push("-");
|
|
9198
|
+
}
|
|
9199
|
+
}
|
|
9200
|
+
return parts.join("|");
|
|
9201
|
+
}
|
|
9152
9202
|
async function download(spec) {
|
|
9153
9203
|
if (offline()) return null;
|
|
9154
9204
|
for (const build of CDN_TEMPLATES) {
|
|
@@ -9207,7 +9257,13 @@ async function loadGrammar(langId) {
|
|
|
9207
9257
|
function grammarReady(langId) {
|
|
9208
9258
|
if (resolved.get(langId)) return true;
|
|
9209
9259
|
const spec = GRAMMARS[langId];
|
|
9210
|
-
|
|
9260
|
+
if (!spec) return false;
|
|
9261
|
+
const sig = localSignature(spec);
|
|
9262
|
+
const hit = readyCache.get(langId);
|
|
9263
|
+
if (hit && hit.sig === sig) return hit.ready;
|
|
9264
|
+
const ready = readLocal(spec) !== null;
|
|
9265
|
+
readyCache.set(langId, { sig, ready });
|
|
9266
|
+
return ready;
|
|
9211
9267
|
}
|
|
9212
9268
|
|
|
9213
9269
|
// src/repomap/extract/index.ts
|
|
@@ -9226,10 +9282,10 @@ async function extractFile(relPath, source) {
|
|
|
9226
9282
|
const bytes = await loadGrammar(lang);
|
|
9227
9283
|
if (bytes) {
|
|
9228
9284
|
const ts = await extractWithTreeSitter(lang, bytes, source, MAX_SYMBOLS_PER_FILE);
|
|
9229
|
-
if (ts) return { symbols: ts.symbols, pkg: ts.pkg, via: "tree-sitter" };
|
|
9285
|
+
if (ts) return { symbols: ts.symbols, pkg: ts.pkg, reexports: ts.reexports, via: "tree-sitter" };
|
|
9230
9286
|
}
|
|
9231
9287
|
const re = extractWithRegex(lang, source, MAX_SYMBOLS_PER_FILE);
|
|
9232
|
-
return { symbols: re.symbols, pkg: re.pkg, via: "regex" };
|
|
9288
|
+
return { symbols: re.symbols, pkg: re.pkg, reexports: re.reexports, via: "regex" };
|
|
9233
9289
|
}
|
|
9234
9290
|
function wantsContent(relPath) {
|
|
9235
9291
|
if (!langOf(relPath)) return false;
|
|
@@ -9416,6 +9472,10 @@ function hasLayerWord(name) {
|
|
|
9416
9472
|
}
|
|
9417
9473
|
var ENTRY_RE = /(^|\/)(main|index|program|startup|app|application|bootstrap|mod|__init__)(\.|\/)/i;
|
|
9418
9474
|
var ENTRY_SUFFIX_RE = /(application|program|startup)\.(java|kt|cs|scala)$/i;
|
|
9475
|
+
function isEntryFile(relPath, sourceRoots = []) {
|
|
9476
|
+
if (ENTRY_SUFFIX_RE.test(relPath)) return true;
|
|
9477
|
+
return ENTRY_RE.test(relPath) && depthFromSourceRoot(relPath, sourceRoots) <= 1;
|
|
9478
|
+
}
|
|
9419
9479
|
var TEST_RE = /(^|\/)(test|tests|__tests__|__mocks__|spec|specs|e2e)(\/|$)|\.(test|spec)\.[a-z]+$|test\.(java|kt|cs)$|_test\.(go|py|rb)$/i;
|
|
9420
9480
|
var DOC_RE = /(^|\/)(docs?|examples?|samples?|demo|benchmarks?|bench|fixtures?)(\/|$)|\.(md|mdx|rst|txt|adoc)$/i;
|
|
9421
9481
|
var GENERATED_RE = /\.(min|generated|designer)\.|_pb2?\.|\.g\.(cs|java)$|(^|\/)gen\//i;
|
|
@@ -9451,7 +9511,7 @@ function scorePath(relPath, sourceRoots) {
|
|
|
9451
9511
|
score += W.sourceRoot;
|
|
9452
9512
|
}
|
|
9453
9513
|
const depth = depthFromSourceRoot(relPath, sourceRoots);
|
|
9454
|
-
if (
|
|
9514
|
+
if (isEntryFile(relPath, sourceRoots)) {
|
|
9455
9515
|
score += W.entry;
|
|
9456
9516
|
}
|
|
9457
9517
|
const base = relPath.slice(relPath.lastIndexOf("/") + 1).replace(/\.[^.]+$/, "");
|
|
@@ -9479,7 +9539,7 @@ function rankFiles(paths, sourceRoots, hasSymbols) {
|
|
|
9479
9539
|
|
|
9480
9540
|
// src/repomap/types.ts
|
|
9481
9541
|
init_cjs_shims();
|
|
9482
|
-
var REPOMAP_CACHE_VERSION =
|
|
9542
|
+
var REPOMAP_CACHE_VERSION = 5;
|
|
9483
9543
|
|
|
9484
9544
|
// src/repomap/indexer.ts
|
|
9485
9545
|
var import_node_crypto2 = require("crypto");
|
|
@@ -9687,6 +9747,7 @@ async function buildRepoMap(root, opts = {}) {
|
|
|
9687
9747
|
size: stat.size,
|
|
9688
9748
|
symbols: ex.symbols,
|
|
9689
9749
|
pkg: ex.pkg,
|
|
9750
|
+
reexports: ex.reexports,
|
|
9690
9751
|
via: ex.via
|
|
9691
9752
|
};
|
|
9692
9753
|
} catch {
|
|
@@ -9694,15 +9755,18 @@ async function buildRepoMap(root, opts = {}) {
|
|
|
9694
9755
|
}
|
|
9695
9756
|
await yieldToLoop();
|
|
9696
9757
|
}
|
|
9697
|
-
const
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9758
|
+
const retained = {};
|
|
9759
|
+
for (const [rel, v] of Object.entries(result)) {
|
|
9760
|
+
if (v.symbols.length > 0 || (v.reexports ?? 0) > 0 || isEntryFile(rel, shape.sourceRoots)) {
|
|
9761
|
+
retained[rel] = v;
|
|
9762
|
+
}
|
|
9763
|
+
}
|
|
9764
|
+
const ranked = rankFiles(Object.keys(retained), shape.sourceRoots);
|
|
9701
9765
|
const scan = {
|
|
9702
9766
|
files: files.length,
|
|
9703
9767
|
// 报「地图里有多少文件」而不是「本次新提取了多少」:命中缓存时
|
|
9704
|
-
//
|
|
9705
|
-
indexed: Object.keys(
|
|
9768
|
+
// 后者为 0,模型会误判结构图为空(实测曾把 1324 个文件报成 0)
|
|
9769
|
+
indexed: Object.keys(retained).length,
|
|
9706
9770
|
truncated: enumTruncated || limit < rankedAll.length,
|
|
9707
9771
|
elapsedMs: Date.now() - started
|
|
9708
9772
|
};
|
|
@@ -9719,7 +9783,7 @@ async function buildRepoMap(root, opts = {}) {
|
|
|
9719
9783
|
shape
|
|
9720
9784
|
});
|
|
9721
9785
|
}
|
|
9722
|
-
return { root: absRoot, scale, scan, ranked, files:
|
|
9786
|
+
return { root: absRoot, scale, scan, ranked, files: retained, shape };
|
|
9723
9787
|
} catch {
|
|
9724
9788
|
return empty;
|
|
9725
9789
|
}
|
|
@@ -9760,6 +9824,11 @@ var GENERIC_SYMBOLS = /* @__PURE__ */ new Set([
|
|
|
9760
9824
|
function meaningful(symbols) {
|
|
9761
9825
|
return symbols.filter((s) => s.name.length > 3 && !GENERIC_SYMBOLS.has(s.name));
|
|
9762
9826
|
}
|
|
9827
|
+
function symbolRef(s, withRange = false) {
|
|
9828
|
+
if (s.line === void 0 || s.name.includes(":")) return s.name;
|
|
9829
|
+
const end = withRange && s.endLine !== void 0 && s.endLine > s.line ? `-${s.endLine}` : "";
|
|
9830
|
+
return `${s.name}:${s.line}${end}`;
|
|
9831
|
+
}
|
|
9763
9832
|
var GROUP_FILE_LIMIT = { small: 5, medium: 4, large: 1 };
|
|
9764
9833
|
var BREADTH_SHARE = 0.5;
|
|
9765
9834
|
var TAIL_RESERVE = 64;
|
|
@@ -9783,7 +9852,7 @@ function baseName(relPath) {
|
|
|
9783
9852
|
function symbolsInline(symbols) {
|
|
9784
9853
|
const kept = meaningful(symbols);
|
|
9785
9854
|
if (kept.length === 0) return "";
|
|
9786
|
-
const names = kept.slice(0, MAX_SYMBOLS_PER_LINE).map((s) => s
|
|
9855
|
+
const names = kept.slice(0, MAX_SYMBOLS_PER_LINE).map((s) => symbolRef(s));
|
|
9787
9856
|
const more = kept.length > MAX_SYMBOLS_PER_LINE ? ", \u2026" : "";
|
|
9788
9857
|
return names.join(", ") + more;
|
|
9789
9858
|
}
|
|
@@ -9791,14 +9860,14 @@ function buildGroups(map) {
|
|
|
9791
9860
|
const groups = /* @__PURE__ */ new Map();
|
|
9792
9861
|
for (const { path: rel } of map.ranked) {
|
|
9793
9862
|
const entry = map.files[rel];
|
|
9794
|
-
if (!entry
|
|
9863
|
+
if (!entry) continue;
|
|
9795
9864
|
const label = groupLabelOf(rel, entry.pkg);
|
|
9796
9865
|
let g = groups.get(label);
|
|
9797
9866
|
if (!g) {
|
|
9798
9867
|
g = { label, files: [] };
|
|
9799
9868
|
groups.set(label, g);
|
|
9800
9869
|
}
|
|
9801
|
-
g.files.push({ path: rel, symbols: entry.symbols });
|
|
9870
|
+
g.files.push({ path: rel, symbols: entry.symbols, reexports: entry.reexports });
|
|
9802
9871
|
}
|
|
9803
9872
|
return [...groups.values()];
|
|
9804
9873
|
}
|
|
@@ -9809,12 +9878,20 @@ function moduleLine(mod, info) {
|
|
|
9809
9878
|
return ` ${label} (${info.files} \u6587\u4EF6)${layers ? ` ${layers}` : ""}${entry}`;
|
|
9810
9879
|
}
|
|
9811
9880
|
function renderLarge(map, budget) {
|
|
9881
|
+
const bestOfModule = /* @__PURE__ */ new Map();
|
|
9882
|
+
for (const r of map.ranked) {
|
|
9883
|
+
const slash = r.path.indexOf("/");
|
|
9884
|
+
const mod = slash < 0 ? "." : r.path.slice(0, slash);
|
|
9885
|
+
const prev = bestOfModule.get(mod);
|
|
9886
|
+
if (prev === void 0 || r.score > prev) bestOfModule.set(mod, r.score);
|
|
9887
|
+
}
|
|
9812
9888
|
const perModule = /* @__PURE__ */ new Map();
|
|
9813
9889
|
for (const rel of Object.keys(map.files)) {
|
|
9814
9890
|
const slash = rel.indexOf("/");
|
|
9815
9891
|
const first = slash < 0 ? "." : rel.slice(0, slash);
|
|
9816
9892
|
const bucket = perModule.get(first) ?? {
|
|
9817
9893
|
files: 0,
|
|
9894
|
+
best: bestOfModule.get(first) ?? Number.NEGATIVE_INFINITY,
|
|
9818
9895
|
layers: /* @__PURE__ */ new Set(),
|
|
9819
9896
|
entryDepth: Number.POSITIVE_INFINITY
|
|
9820
9897
|
};
|
|
@@ -9834,7 +9911,9 @@ function renderLarge(map, budget) {
|
|
|
9834
9911
|
}
|
|
9835
9912
|
perModule.set(first, bucket);
|
|
9836
9913
|
}
|
|
9837
|
-
const sorted = [...perModule.entries()].sort(
|
|
9914
|
+
const sorted = [...perModule.entries()].sort(
|
|
9915
|
+
(a, b) => b[1].best - a[1].best || b[1].files - a[1].files || a[0].localeCompare(b[0])
|
|
9916
|
+
);
|
|
9838
9917
|
const lines = [];
|
|
9839
9918
|
const lineBudget = Math.max(200, budget - TAIL_RESERVE);
|
|
9840
9919
|
let used = 0;
|
|
@@ -9856,8 +9935,13 @@ function renderLarge(map, budget) {
|
|
|
9856
9935
|
return lines.join("\n");
|
|
9857
9936
|
}
|
|
9858
9937
|
function fileLine(f) {
|
|
9859
|
-
const
|
|
9860
|
-
|
|
9938
|
+
const name = baseName(f.path);
|
|
9939
|
+
if (f.symbols.length > 0) {
|
|
9940
|
+
const sym = symbolsInline(f.symbols);
|
|
9941
|
+
return ` ${name}${sym ? `: ${sym}` : ""}`;
|
|
9942
|
+
}
|
|
9943
|
+
if (f.reexports) return ` ${name}: (\u518D\u5BFC\u51FA ${f.reexports})`;
|
|
9944
|
+
return ` ${name}: (\u5165\u53E3)`;
|
|
9861
9945
|
}
|
|
9862
9946
|
function renderDetailed(map, budget) {
|
|
9863
9947
|
const limit = GROUP_FILE_LIMIT[map.scale === "medium" ? "medium" : "small"];
|
|
@@ -9892,23 +9976,36 @@ function renderDetailed(map, budget) {
|
|
|
9892
9976
|
const out = [];
|
|
9893
9977
|
for (const b of blocks) out.push(b.header, ...b.lines);
|
|
9894
9978
|
const omitted = map.ranked.length - shownFiles;
|
|
9895
|
-
if (omitted > 0) out.push(`\u2026 \u53E6\u6709 ${omitted} \u4E2A\u6587\u4EF6\u672A\u5217\u51FA\uFF0C\u7528 repo_map \u5DE5\u5177\u67E5\u770B`);
|
|
9979
|
+
if (omitted > 0) out.push(`\u2026 \u53E6\u6709 ${omitted} \u4E2A\u6587\u4EF6\u672A\u5217\u51FA\uFF0C\u7528 repo_map \u5DE5\u5177\u6309\u76EE\u5F55\u67E5\u770B`);
|
|
9896
9980
|
return out.join("\n");
|
|
9897
9981
|
}
|
|
9982
|
+
function shapeLine(shape) {
|
|
9983
|
+
if (!shape) return "";
|
|
9984
|
+
const parts = [];
|
|
9985
|
+
const kinds = shape.kinds.filter((k) => k !== "npm" || !shape.kinds.includes("npm-workspace"));
|
|
9986
|
+
if (kinds.length) parts.push(kinds.slice(0, 3).join(" \xB7 "));
|
|
9987
|
+
if (shape.modules.length > 1) parts.push(`${shape.modules.length} \u6A21\u5757`);
|
|
9988
|
+
const roots = [...new Set(shape.sourceRoots)].sort((a, b) => a.split("/").length - b.split("/").length || a.localeCompare(b)).slice(0, 3);
|
|
9989
|
+
if (roots.length) parts.push(`\u6E90\u7801\u6839 ${roots.join(", ")}`);
|
|
9990
|
+
return parts.length ? `\u9879\u76EE\u5F62\u6001: ${parts.join(" \xB7 ")}` : "";
|
|
9991
|
+
}
|
|
9898
9992
|
function renderRepoMap(map) {
|
|
9899
9993
|
if (map.ranked.length === 0 && !map.shape) return "";
|
|
9900
9994
|
const budget = renderBudget(map.scale);
|
|
9901
|
-
const
|
|
9995
|
+
const title = map.scale === "large" ? "\u4EE3\u7801\u7ED3\u6784\uFF08\u81EA\u52A8\u6458\u8981 \xB7 \u5927\u578B\u9879\u76EE\uFF1B\u6309\u6A21\u5757\u4E0B\u94BB\u7528 repo_map \u5DE5\u5177\uFF09" : "\u4EE3\u7801\u7ED3\u6784\uFF08\u81EA\u52A8\u751F\u6210\uFF1B\u7B26\u53F7\u540E\u7684\u6570\u5B57\u662F\u884C\u53F7\uFF1B\u66F4\u7EC6\u7684\u89C6\u56FE\u7528 repo_map \u5DE5\u5177\uFF09";
|
|
9996
|
+
const shape = shapeLine(map.shape);
|
|
9997
|
+
const head = shape ? `${title}
|
|
9998
|
+
${shape}` : title;
|
|
9902
9999
|
const bodyBudget = Math.max(200, budget - head.length - 1);
|
|
9903
10000
|
const body = map.scale === "large" ? renderLarge(map, bodyBudget) : renderDetailed(map, bodyBudget);
|
|
9904
|
-
if (!body.trim()) return
|
|
10001
|
+
if (!body.trim()) return shape;
|
|
9905
10002
|
const text = `${head}
|
|
9906
10003
|
${body}`;
|
|
9907
10004
|
if (text.length <= budget) return text;
|
|
9908
10005
|
return cutAtLine(text, budget);
|
|
9909
10006
|
}
|
|
9910
10007
|
function cutAtLine(text, budget) {
|
|
9911
|
-
const marker = "\n\u2026\uFF08\u7ED3\u6784\u56FE\u5DF2\u622A\u65AD\uFF0C\u7528 repo_map \u5DE5\u5177\u67E5\u770B\uFF09";
|
|
10008
|
+
const marker = "\n\u2026\uFF08\u7ED3\u6784\u56FE\u5DF2\u622A\u65AD\uFF0C\u7528 repo_map \u5DE5\u5177\u6309\u76EE\u5F55\u67E5\u770B\uFF09";
|
|
9912
10009
|
const room = budget - marker.length;
|
|
9913
10010
|
if (room <= 0) return marker.slice(1);
|
|
9914
10011
|
const cut = text.slice(0, room);
|
|
@@ -10018,10 +10115,12 @@ function attachRepoMap(engine, opts) {
|
|
|
10018
10115
|
const original = spec.func;
|
|
10019
10116
|
engine.registry.register(
|
|
10020
10117
|
async (args, ctx) => {
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10118
|
+
try {
|
|
10119
|
+
return await original(args, ctx);
|
|
10120
|
+
} finally {
|
|
10121
|
+
invalidateRepoMap(workspace);
|
|
10122
|
+
schedule();
|
|
10123
|
+
}
|
|
10025
10124
|
},
|
|
10026
10125
|
spec.metadata,
|
|
10027
10126
|
spec.schema,
|
|
@@ -13213,17 +13312,26 @@ function registerSearchTool(registry, workspace) {
|
|
|
13213
13312
|
// src/tools/repoMap.ts
|
|
13214
13313
|
init_cjs_shims();
|
|
13215
13314
|
var MAX_CHARS = 16e3;
|
|
13315
|
+
function filesUnder(map, prefix) {
|
|
13316
|
+
const keys = Object.keys(map.files);
|
|
13317
|
+
if (!prefix) return keys;
|
|
13318
|
+
if (prefix === ".") return keys.filter((rel) => !rel.includes("/"));
|
|
13319
|
+
return keys.filter((rel) => rel === prefix || rel.startsWith(`${prefix}/`));
|
|
13320
|
+
}
|
|
13216
13321
|
function renderSubset(map, prefix, maxFiles) {
|
|
13217
13322
|
const order = new Map(map.ranked.map((r, i) => [r.path, i]));
|
|
13218
|
-
const under =
|
|
13323
|
+
const under = filesUnder(map, prefix).sort(
|
|
13324
|
+
(a, b) => (order.get(a) ?? Infinity) - (order.get(b) ?? Infinity)
|
|
13325
|
+
);
|
|
13219
13326
|
const matched = under.slice(0, maxFiles);
|
|
13220
13327
|
if (matched.length === 0) return null;
|
|
13221
13328
|
const entries = [];
|
|
13222
13329
|
let used = 0;
|
|
13223
13330
|
for (const rel of matched) {
|
|
13224
13331
|
const f = map.files[rel];
|
|
13225
|
-
const sym = f.symbols.slice(0, 8).map((s) => s
|
|
13226
|
-
const
|
|
13332
|
+
const sym = f.symbols.slice(0, 8).map((s) => symbolRef(s, true)).join(", ");
|
|
13333
|
+
const body = f.symbols.length > 0 ? sym : f.reexports ? `(\u518D\u5BFC\u51FA ${f.reexports})` : "(\u5165\u53E3)";
|
|
13334
|
+
const line = `${rel}: ${body}`;
|
|
13227
13335
|
if (used + line.length + 1 > MAX_CHARS) break;
|
|
13228
13336
|
entries.push(line);
|
|
13229
13337
|
used += line.length + 1;
|
|
@@ -13255,18 +13363,20 @@ function registerRepoMapTool(registry, workspace) {
|
|
|
13255
13363
|
if (sub) return sub;
|
|
13256
13364
|
return { error: `\u6CA1\u6709\u5339\u914D\u7684\u76EE\u5F55\uFF1A${path30}` };
|
|
13257
13365
|
}
|
|
13258
|
-
const groups = buildGroups(map).slice(0, 40).map((g) =>
|
|
13259
|
-
|
|
13260
|
-
|
|
13261
|
-
|
|
13262
|
-
|
|
13366
|
+
const groups = buildGroups(map).slice(0, 40).map((g) => {
|
|
13367
|
+
const dir = g.files[0]?.path.split("/").slice(0, -1).join("/") || ".";
|
|
13368
|
+
return {
|
|
13369
|
+
label: g.label,
|
|
13370
|
+
files: filesUnder(map, dir).length,
|
|
13371
|
+
...dir === g.label ? {} : { path: dir }
|
|
13372
|
+
};
|
|
13373
|
+
});
|
|
13263
13374
|
return {
|
|
13264
13375
|
scale: map.scale,
|
|
13265
13376
|
files: map.scan.files,
|
|
13266
13377
|
indexed: map.scan.indexed,
|
|
13267
13378
|
groups,
|
|
13268
|
-
|
|
13269
|
-
hint: '\u7528 path \u53C2\u6570\u53EF\u53EA\u770B\u67D0\u4E2A\u6A21\u5757/\u76EE\u5F55\uFF08\u53D6 groups[].path\uFF09\uFF0C\u4F8B\u5982 path="packages/core/src"'
|
|
13379
|
+
hint: '\u7ED3\u6784\u56FE\u5DF2\u5728\u7CFB\u7EDF\u63D0\u793A\u8BCD\u91CC\uFF0C\u8FD9\u91CC\u53EA\u7ED9\u5168\u5C40\u5206\u7EC4\uFF08files \u542B\u5B50\u76EE\u5F55\uFF09\u3002\u7528 path \u53C2\u6570\u6309\u76EE\u5F55\u4E0B\u94BB\uFF1A\u5206\u7EC4\u6807\u9898\u662F\u5305\u540D\u65F6\u7528 groups[].path\uFF0C\u5426\u5219\u76F4\u63A5\u7528 label\uFF0C\u4F8B\u5982 path="packages/core/src"'
|
|
13270
13380
|
};
|
|
13271
13381
|
},
|
|
13272
13382
|
{ category: "search", riskLevel: "low", capabilities: ["repo_map"], requiresApproval: false },
|