@lzehrung/codegraph 2.2.2 → 2.3.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.
- package/README.md +2 -2
- package/codegraph-skill/codegraph/SKILL.md +16 -8
- package/dist/agent/followUps.d.ts +1 -0
- package/dist/agent/followUps.d.ts.map +1 -1
- package/dist/agent/followUps.js +11 -0
- package/dist/agent/followUps.js.map +1 -1
- package/dist/agent/orient.d.ts.map +1 -1
- package/dist/agent/orient.js +3 -3
- package/dist/agent/orient.js.map +1 -1
- package/dist/bin/cli.js +1764 -1247
- package/dist/cli/affected.js +2 -2
- package/dist/cli/affected.js.map +1 -1
- package/dist/cli/chunk.d.ts.map +1 -1
- package/dist/cli/chunk.js +16 -6
- package/dist/cli/chunk.js.map +1 -1
- package/dist/cli/commandCatalog.d.ts +1 -1
- package/dist/cli/commandCatalog.d.ts.map +1 -1
- package/dist/cli/commandCatalog.js +15 -3
- package/dist/cli/commandCatalog.js.map +1 -1
- package/dist/cli/compileCache.d.ts +2 -2
- package/dist/cli/compileCache.js +2 -2
- package/dist/cli/context.d.ts.map +1 -1
- package/dist/cli/context.js +1 -0
- package/dist/cli/context.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +6 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explain.d.ts.map +1 -1
- package/dist/cli/explain.js +3 -0
- package/dist/cli/explain.js.map +1 -1
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +1 -1
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/graphQueries.d.ts.map +1 -1
- package/dist/cli/graphQueries.js +22 -14
- package/dist/cli/graphQueries.js.map +1 -1
- package/dist/cli/grep.js +2 -2
- package/dist/cli/grep.js.map +1 -1
- package/dist/cli/help.d.ts +6 -5
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +21 -10
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/lifecycle.js +1 -1
- package/dist/cli/lifecycle.js.map +1 -1
- package/dist/cli/navigation.d.ts.map +1 -1
- package/dist/cli/navigation.js +19 -6
- package/dist/cli/navigation.js.map +1 -1
- package/dist/cli/options.d.ts +8 -0
- package/dist/cli/options.d.ts.map +1 -1
- package/dist/cli/options.js +43 -11
- package/dist/cli/options.js.map +1 -1
- package/dist/cli/progress.d.ts +1 -0
- package/dist/cli/progress.d.ts.map +1 -1
- package/dist/cli/progress.js +103 -30
- package/dist/cli/progress.js.map +1 -1
- package/dist/cli/rootPolicy.d.ts.map +1 -1
- package/dist/cli/rootPolicy.js +2 -4
- package/dist/cli/rootPolicy.js.map +1 -1
- package/dist/cli/server.d.ts.map +1 -1
- package/dist/cli/server.js +3 -2
- package/dist/cli/server.js.map +1 -1
- package/dist/cli/sql.d.ts.map +1 -1
- package/dist/cli/sql.js +2 -1
- package/dist/cli/sql.js.map +1 -1
- package/dist/cli/typeHierarchy.d.ts.map +1 -1
- package/dist/cli/typeHierarchy.js +12 -3
- package/dist/cli/typeHierarchy.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/graphs.d.ts +0 -1
- package/dist/graphs.d.ts.map +1 -1
- package/dist/graphs.js +0 -1
- package/dist/graphs.js.map +1 -1
- package/dist/indexer/build-cache/location.d.ts +4 -2
- package/dist/indexer/build-cache/location.d.ts.map +1 -1
- package/dist/indexer/build-cache/location.js +63 -15
- package/dist/indexer/build-cache/location.js.map +1 -1
- package/dist/indexer/build-cache/project-snapshot.js +26 -25
- package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
- package/dist/indexer.d.ts +3 -6
- package/dist/indexer.d.ts.map +1 -1
- package/dist/indexer.js +2 -9
- package/dist/indexer.js.map +1 -1
- package/dist/lifecycle/gitignore.d.ts +1 -1
- package/dist/lifecycle/gitignore.d.ts.map +1 -1
- package/dist/lifecycle/gitignore.js +7 -12
- package/dist/lifecycle/gitignore.js.map +1 -1
- package/dist/lifecycle/manifest.d.ts.map +1 -1
- package/dist/lifecycle/manifest.js +10 -4
- package/dist/lifecycle/manifest.js.map +1 -1
- package/dist/mcp/handlers.js +1 -1
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/protocol.d.ts.map +1 -1
- package/dist/mcp/protocol.js +79 -1
- package/dist/mcp/protocol.js.map +1 -1
- package/dist/mcp/tools.js +1 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/util/git.d.ts +66 -1
- package/dist/util/git.d.ts.map +1 -1
- package/dist/util/git.js +173 -1
- package/dist/util/git.js.map +1 -1
- package/dist/util/projectFiles.d.ts +7 -6
- package/dist/util/projectFiles.d.ts.map +1 -1
- package/dist/util/projectFiles.js +268 -59
- package/dist/util/projectFiles.js.map +1 -1
- package/docs/mcp.md +13 -11
- package/package.json +3 -3
package/dist/bin/cli.js
CHANGED
|
@@ -432,6 +432,13 @@ function graphCommandSchema(positionals) {
|
|
|
432
432
|
"--symbols-detailed-scope"
|
|
433
433
|
], positionals);
|
|
434
434
|
}
|
|
435
|
+
function getCliCommandUsage(command) {
|
|
436
|
+
const usage = CLI_COMMAND_SCHEMAS.get(command)?.positionals.usage;
|
|
437
|
+
if (!usage) {
|
|
438
|
+
throw new Error(`No validation usage is defined for ${command}.`);
|
|
439
|
+
}
|
|
440
|
+
return usage;
|
|
441
|
+
}
|
|
435
442
|
function allowedFlagsForSchema(schema) {
|
|
436
443
|
return /* @__PURE__ */ new Set(["--help", "-h", "--version", "-v", "--debug", ...schema.flags ?? []]);
|
|
437
444
|
}
|
|
@@ -692,7 +699,8 @@ var init_options = __esm({
|
|
|
692
699
|
[
|
|
693
700
|
"affected",
|
|
694
701
|
commandSchema([...SHARED_BUILD_FLAGS, "--json", "--quiet", "--stdin"], [...SHARED_BUILD_OPTIONS, "--base", "--depth", "--filter", "--head"], {
|
|
695
|
-
kind: "any"
|
|
702
|
+
kind: "any",
|
|
703
|
+
usage: "Usage: codegraph affected <file...> [--stdin] [--base <ref> --head <ref>] [--root <path>] [--depth <n>] [--filter <glob>] [--json | --quiet]"
|
|
696
704
|
})
|
|
697
705
|
],
|
|
698
706
|
[
|
|
@@ -716,7 +724,7 @@ var init_options = __esm({
|
|
|
716
724
|
commandSchema([...JSON_OUTPUT_FLAGS, "--text"], ["--language", "--max-tokens", "--min-tokens"], {
|
|
717
725
|
kind: "max",
|
|
718
726
|
max: 1,
|
|
719
|
-
usage: "Usage: codegraph chunk <file-path> [
|
|
727
|
+
usage: "Usage: codegraph chunk <file-path> [--language <language>] [--min-tokens <n>] [--max-tokens <n>] [--text] [--json | --pretty]"
|
|
720
728
|
})
|
|
721
729
|
],
|
|
722
730
|
[
|
|
@@ -727,10 +735,10 @@ var init_options = __esm({
|
|
|
727
735
|
],
|
|
728
736
|
[
|
|
729
737
|
"deps",
|
|
730
|
-
commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], [...SHARED_BUILD_OPTIONS, "--depth"], {
|
|
738
|
+
commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS, "--all"], [...SHARED_BUILD_OPTIONS, "--depth"], {
|
|
731
739
|
kind: "max",
|
|
732
740
|
max: 1,
|
|
733
|
-
usage: "Usage: codegraph deps <file
|
|
741
|
+
usage: "Usage: codegraph deps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]"
|
|
734
742
|
})
|
|
735
743
|
],
|
|
736
744
|
[
|
|
@@ -813,7 +821,7 @@ var init_options = __esm({
|
|
|
813
821
|
commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], SHARED_BUILD_OPTIONS, {
|
|
814
822
|
kind: "max",
|
|
815
823
|
max: 3,
|
|
816
|
-
usage: "Usage: codegraph goto <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]"
|
|
824
|
+
usage: "Usage: codegraph goto <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]\n codegraph goto <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]"
|
|
817
825
|
})
|
|
818
826
|
],
|
|
819
827
|
["graph", graphCommandSchema({ kind: "any" })],
|
|
@@ -832,7 +840,16 @@ var init_options = __esm({
|
|
|
832
840
|
[
|
|
833
841
|
"grep",
|
|
834
842
|
commandSchema(["--ignore-case", "--json", "--pretty", "-i", "--no-gitignore"], ["--glob", "--ignore-glob", "--include-glob", "--max-hits", "--pattern", "--query", "--regex", "--root"], {
|
|
835
|
-
kind: "
|
|
843
|
+
kind: "max",
|
|
844
|
+
max: 1,
|
|
845
|
+
// `handleGrepCommand` takes the pattern from --pattern, then --regex, then the
|
|
846
|
+
// positional, and --query is a separate syntax-tree mode. Present all three forms
|
|
847
|
+
// so a parse failure does not imply the positional regex is mandatory.
|
|
848
|
+
usage: [
|
|
849
|
+
"Usage: codegraph grep <regex> [--root <dir>] [--glob|--include-glob|--ignore-glob <glob>] [--ignore-case|-i] [--no-gitignore] [--max-hits <n>] [--json | --pretty]",
|
|
850
|
+
" codegraph grep --pattern|--regex <expr> [--root <dir>] [--glob|--include-glob|--ignore-glob <glob>] [--ignore-case|-i] [--no-gitignore] [--max-hits <n>] [--json | --pretty]",
|
|
851
|
+
" codegraph grep --query <tree-sitter-query> [--root <dir>] [--json | --pretty]"
|
|
852
|
+
].join("\n")
|
|
836
853
|
})
|
|
837
854
|
],
|
|
838
855
|
[
|
|
@@ -872,7 +889,7 @@ var init_options = __esm({
|
|
|
872
889
|
], {
|
|
873
890
|
kind: "max",
|
|
874
891
|
max: 1,
|
|
875
|
-
usage: "Usage: codegraph impact [project-root] [--provider git|github|raw] [options]"
|
|
892
|
+
usage: "Usage: codegraph impact [project-root] [--provider git|github|raw] [--depth <n>] [options] [--json | --pretty]"
|
|
876
893
|
})
|
|
877
894
|
],
|
|
878
895
|
[
|
|
@@ -947,7 +964,7 @@ var init_options = __esm({
|
|
|
947
964
|
], {
|
|
948
965
|
kind: "max",
|
|
949
966
|
max: 1,
|
|
950
|
-
usage: "Usage: codegraph server <start|status|stop> [--root <path>]"
|
|
967
|
+
usage: "Usage: codegraph server <start|status|stop> [--root <path>] [--json | --pretty]"
|
|
951
968
|
})
|
|
952
969
|
],
|
|
953
970
|
[
|
|
@@ -974,10 +991,10 @@ var init_options = __esm({
|
|
|
974
991
|
],
|
|
975
992
|
[
|
|
976
993
|
"rdeps",
|
|
977
|
-
commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], [...SHARED_BUILD_OPTIONS, "--depth"], {
|
|
994
|
+
commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS, "--all"], [...SHARED_BUILD_OPTIONS, "--depth"], {
|
|
978
995
|
kind: "max",
|
|
979
996
|
max: 1,
|
|
980
|
-
usage: "Usage: codegraph rdeps <file
|
|
997
|
+
usage: "Usage: codegraph rdeps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]"
|
|
981
998
|
})
|
|
982
999
|
],
|
|
983
1000
|
[
|
|
@@ -985,7 +1002,7 @@ var init_options = __esm({
|
|
|
985
1002
|
commandSchema([...SHARED_BUILD_FLAGS, ...JSON_OUTPUT_FLAGS], [...SHARED_BUILD_OPTIONS, "--col", "--column", "--file", "--line"], {
|
|
986
1003
|
kind: "max",
|
|
987
1004
|
max: 3,
|
|
988
|
-
usage: "Usage: codegraph refs <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]"
|
|
1005
|
+
usage: "Usage: codegraph refs <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]\n codegraph refs <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]\n codegraph refs --file <file> [--line <line> --col <column>] [--root <path>] [--json | --pretty]"
|
|
989
1006
|
})
|
|
990
1007
|
],
|
|
991
1008
|
[
|
|
@@ -1095,7 +1112,7 @@ var init_options = __esm({
|
|
|
1095
1112
|
commandSchema(["--json", "--pretty"], ["--db", "--query", "--sqlite"], {
|
|
1096
1113
|
kind: "max",
|
|
1097
1114
|
max: 2,
|
|
1098
|
-
usage: 'Usage: codegraph sql <sqlite-path> "SELECT ..." [--json | --pretty] OR codegraph sql --db <sqlite
|
|
1115
|
+
usage: 'Usage: codegraph sql <sqlite-path> "SELECT ..." [--json | --pretty] OR codegraph sql --db <sqlite-path> --query "SELECT ..." [--json | --pretty]'
|
|
1099
1116
|
})
|
|
1100
1117
|
],
|
|
1101
1118
|
[
|
|
@@ -1148,16 +1165,14 @@ function resolveCliProgressPresentation(input) {
|
|
|
1148
1165
|
if (input.stderrIsTTY) {
|
|
1149
1166
|
return input.terminalSupportsControlSequences ? "interactive" : "log";
|
|
1150
1167
|
}
|
|
1151
|
-
|
|
1152
|
-
return "log";
|
|
1153
|
-
return "off";
|
|
1168
|
+
return "log";
|
|
1154
1169
|
}
|
|
1155
1170
|
function createCliProgressDisplay(options) {
|
|
1156
1171
|
if (options.presentation === "log")
|
|
1157
|
-
return createLogProgressDisplay(options.write);
|
|
1158
|
-
return createInteractiveProgressDisplay(options.write);
|
|
1172
|
+
return createLogProgressDisplay(options.write, options.delayMs);
|
|
1173
|
+
return createInteractiveProgressDisplay(options.write, options.delayMs);
|
|
1159
1174
|
}
|
|
1160
|
-
function createInteractiveProgressDisplay(write) {
|
|
1175
|
+
function createInteractiveProgressDisplay(write, delayMs = 0) {
|
|
1161
1176
|
let active = false;
|
|
1162
1177
|
let rendered = false;
|
|
1163
1178
|
let frameIndex = 0;
|
|
@@ -1165,6 +1180,7 @@ function createInteractiveProgressDisplay(write) {
|
|
|
1165
1180
|
let total = 0;
|
|
1166
1181
|
let mode = "build";
|
|
1167
1182
|
let interval;
|
|
1183
|
+
let delay;
|
|
1168
1184
|
const clear = () => {
|
|
1169
1185
|
if (!rendered)
|
|
1170
1186
|
return;
|
|
@@ -1177,39 +1193,55 @@ function createInteractiveProgressDisplay(write) {
|
|
|
1177
1193
|
const action = progressAction(mode);
|
|
1178
1194
|
const frame = SPINNER_FRAMES[frameIndex % SPINNER_FRAMES.length];
|
|
1179
1195
|
frameIndex += 1;
|
|
1180
|
-
const count =
|
|
1196
|
+
const count = formatProgressCount(current, total);
|
|
1181
1197
|
write(`${CLEAR_LINE}${action} project index... ${frame}${count}`);
|
|
1182
1198
|
rendered = true;
|
|
1183
1199
|
};
|
|
1184
1200
|
const stopInterval = () => {
|
|
1185
|
-
if (interval
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1201
|
+
if (interval !== void 0) {
|
|
1202
|
+
clearInterval(interval);
|
|
1203
|
+
interval = void 0;
|
|
1204
|
+
}
|
|
1205
|
+
if (delay !== void 0) {
|
|
1206
|
+
clearTimeout(delay);
|
|
1207
|
+
delay = void 0;
|
|
1208
|
+
}
|
|
1189
1209
|
};
|
|
1190
1210
|
const start = (update) => {
|
|
1191
1211
|
stopInterval();
|
|
1192
1212
|
clear();
|
|
1193
1213
|
active = true;
|
|
1214
|
+
rendered = false;
|
|
1194
1215
|
frameIndex = 0;
|
|
1195
1216
|
current = update.current;
|
|
1196
1217
|
total = update.total;
|
|
1197
1218
|
mode = update.mode ?? "build";
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1219
|
+
const beginRendering = () => {
|
|
1220
|
+
if (!active)
|
|
1221
|
+
return;
|
|
1222
|
+
render();
|
|
1223
|
+
interval = setInterval(render, REFRESH_INTERVAL_MS);
|
|
1224
|
+
interval.unref();
|
|
1225
|
+
};
|
|
1226
|
+
if (delayMs) {
|
|
1227
|
+
delay = setTimeout(beginRendering, delayMs);
|
|
1228
|
+
delay.unref();
|
|
1229
|
+
} else {
|
|
1230
|
+
beginRendering();
|
|
1231
|
+
}
|
|
1201
1232
|
};
|
|
1202
1233
|
const complete = (update) => {
|
|
1203
1234
|
if (!active)
|
|
1204
1235
|
return;
|
|
1205
1236
|
active = false;
|
|
1206
1237
|
stopInterval();
|
|
1238
|
+
if (!rendered)
|
|
1239
|
+
return;
|
|
1207
1240
|
clear();
|
|
1208
1241
|
const verb = progressCompleteVerb(mode);
|
|
1209
|
-
const fileCount = update.total;
|
|
1210
|
-
const files = fileCount === 1 ? "file" : "files";
|
|
1242
|
+
const fileCount = formatFileCount(update.total, "words");
|
|
1211
1243
|
const elapsed = update.elapsedMs === void 0 ? "" : ` in ${formatDuration(update.elapsedMs)}`;
|
|
1212
|
-
write(`${verb} project index: ${fileCount}
|
|
1244
|
+
write(`${verb} project index: ${fileCount}${elapsed}.
|
|
1213
1245
|
`);
|
|
1214
1246
|
};
|
|
1215
1247
|
return {
|
|
@@ -1239,37 +1271,92 @@ function createInteractiveProgressDisplay(write) {
|
|
|
1239
1271
|
}
|
|
1240
1272
|
};
|
|
1241
1273
|
}
|
|
1242
|
-
function
|
|
1274
|
+
function formatFileCount(count, zeroFormat = "numeric") {
|
|
1275
|
+
if (!count && zeroFormat === "words")
|
|
1276
|
+
return "no files";
|
|
1277
|
+
return `${count} file${count === 1 ? "" : "s"}`;
|
|
1278
|
+
}
|
|
1279
|
+
function formatProgressCount(current, total) {
|
|
1280
|
+
if (total > 0)
|
|
1281
|
+
return ` ${current}/${formatFileCount(total)}`;
|
|
1282
|
+
return ` ${formatFileCount(current)} processed`;
|
|
1283
|
+
}
|
|
1284
|
+
function createLogProgressDisplay(write, delayMs = 0) {
|
|
1243
1285
|
let active = false;
|
|
1286
|
+
let rendered = false;
|
|
1287
|
+
let current = 0;
|
|
1288
|
+
let total = 0;
|
|
1244
1289
|
let mode = "build";
|
|
1290
|
+
let delay;
|
|
1291
|
+
let heartbeat;
|
|
1292
|
+
const stopTimers = () => {
|
|
1293
|
+
if (delay !== void 0) {
|
|
1294
|
+
clearTimeout(delay);
|
|
1295
|
+
delay = void 0;
|
|
1296
|
+
}
|
|
1297
|
+
if (heartbeat !== void 0) {
|
|
1298
|
+
clearInterval(heartbeat);
|
|
1299
|
+
heartbeat = void 0;
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
const renderStart = () => {
|
|
1303
|
+
if (!active || rendered)
|
|
1304
|
+
return;
|
|
1305
|
+
rendered = true;
|
|
1306
|
+
write(`[Progress] ${progressAction(mode)} project index.
|
|
1307
|
+
`);
|
|
1308
|
+
heartbeat = setInterval(() => {
|
|
1309
|
+
if (!active)
|
|
1310
|
+
return;
|
|
1311
|
+
write(`[Progress] ${progressAction(mode)} project index:${formatProgressCount(current, total)}.
|
|
1312
|
+
`);
|
|
1313
|
+
}, 1e3);
|
|
1314
|
+
heartbeat.unref();
|
|
1315
|
+
};
|
|
1316
|
+
const start = (update) => {
|
|
1317
|
+
stopTimers();
|
|
1318
|
+
active = true;
|
|
1319
|
+
rendered = false;
|
|
1320
|
+
current = update.current;
|
|
1321
|
+
total = update.total;
|
|
1322
|
+
mode = update.mode ?? "build";
|
|
1323
|
+
if (delayMs) {
|
|
1324
|
+
delay = setTimeout(renderStart, delayMs);
|
|
1325
|
+
delay.unref();
|
|
1326
|
+
} else {
|
|
1327
|
+
renderStart();
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1245
1330
|
return {
|
|
1246
1331
|
update: (update) => {
|
|
1247
1332
|
if (update.phase === "start") {
|
|
1248
|
-
|
|
1249
|
-
mode = update.mode ?? "build";
|
|
1250
|
-
const action = progressAction(mode);
|
|
1251
|
-
write(`[Progress] ${action} project index.
|
|
1252
|
-
`);
|
|
1333
|
+
start(update);
|
|
1253
1334
|
return;
|
|
1254
1335
|
}
|
|
1255
1336
|
if (update.phase === "complete") {
|
|
1256
1337
|
if (!active)
|
|
1257
1338
|
return;
|
|
1258
1339
|
active = false;
|
|
1340
|
+
stopTimers();
|
|
1341
|
+
if (!rendered)
|
|
1342
|
+
return;
|
|
1259
1343
|
const verb = progressCompleteVerb(mode);
|
|
1260
1344
|
const elapsed = update.elapsedMs === void 0 ? "" : ` in ${formatDuration(update.elapsedMs)}`;
|
|
1261
|
-
write(`[Progress] ${verb} project index: ${update.total}
|
|
1345
|
+
write(`[Progress] ${verb} project index: ${formatFileCount(update.total, "words")}${elapsed}.
|
|
1262
1346
|
`);
|
|
1263
1347
|
return;
|
|
1264
1348
|
}
|
|
1265
1349
|
if (!active) {
|
|
1266
1350
|
if (update.phase === "update")
|
|
1267
1351
|
return;
|
|
1268
|
-
|
|
1352
|
+
start(update);
|
|
1269
1353
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1354
|
+
current = update.current;
|
|
1355
|
+
total = update.total;
|
|
1356
|
+
mode = update.mode ?? mode;
|
|
1357
|
+
const isComplete = update.total > 0 && update.current >= update.total;
|
|
1358
|
+
if (rendered && (update.current === 1 || isComplete || update.current % 100 === 0)) {
|
|
1359
|
+
write(`[Progress] ${formatFileCount(update.current)} processed.
|
|
1273
1360
|
`);
|
|
1274
1361
|
}
|
|
1275
1362
|
},
|
|
@@ -1277,6 +1364,7 @@ function createLogProgressDisplay(write) {
|
|
|
1277
1364
|
},
|
|
1278
1365
|
dispose: () => {
|
|
1279
1366
|
active = false;
|
|
1367
|
+
stopTimers();
|
|
1280
1368
|
}
|
|
1281
1369
|
};
|
|
1282
1370
|
}
|
|
@@ -1295,9 +1383,10 @@ function progressCompleteVerb(mode) {
|
|
|
1295
1383
|
return "Checked";
|
|
1296
1384
|
}
|
|
1297
1385
|
function formatDuration(elapsedMs2) {
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1386
|
+
const durationMs = Math.max(0, elapsedMs2);
|
|
1387
|
+
if (durationMs < 1e3)
|
|
1388
|
+
return `${Math.round(durationMs)}ms`;
|
|
1389
|
+
return `${(durationMs / 1e3).toFixed(1)}s`;
|
|
1301
1390
|
}
|
|
1302
1391
|
var REFRESH_INTERVAL_MS, CLEAR_LINE, SPINNER_FRAMES;
|
|
1303
1392
|
var init_progress = __esm({
|
|
@@ -1519,7 +1608,8 @@ function createCliProgressHandler(policy) {
|
|
|
1519
1608
|
context.progressDisplay?.dispose();
|
|
1520
1609
|
const display = createCliProgressDisplay({
|
|
1521
1610
|
presentation,
|
|
1522
|
-
write: context.runtime.stderr
|
|
1611
|
+
write: context.runtime.stderr,
|
|
1612
|
+
...policy === "auto" ? { delayMs: 1e3 } : {}
|
|
1523
1613
|
});
|
|
1524
1614
|
context.progressDisplay = display;
|
|
1525
1615
|
return display.update;
|
|
@@ -4671,9 +4761,9 @@ var require_path = __commonJS({
|
|
|
4671
4761
|
"use strict";
|
|
4672
4762
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4673
4763
|
exports.convertPosixPathToPattern = exports.convertWindowsPathToPattern = exports.convertPathToPattern = exports.escapePosixPath = exports.escapeWindowsPath = exports.escape = exports.removeLeadingDotSegment = exports.makeAbsolute = exports.unixify = void 0;
|
|
4674
|
-
var
|
|
4764
|
+
var os12 = __require("os");
|
|
4675
4765
|
var path99 = __require("path");
|
|
4676
|
-
var IS_WINDOWS_PLATFORM =
|
|
4766
|
+
var IS_WINDOWS_PLATFORM = os12.platform() === "win32";
|
|
4677
4767
|
var LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2;
|
|
4678
4768
|
var POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
|
|
4679
4769
|
var WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()[\]{}]|^!|[!+@](?=\())/g;
|
|
@@ -10191,8 +10281,8 @@ var require_settings4 = __commonJS({
|
|
|
10191
10281
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10192
10282
|
exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
|
|
10193
10283
|
var fs49 = __require("fs");
|
|
10194
|
-
var
|
|
10195
|
-
var CPU_COUNT = Math.max(
|
|
10284
|
+
var os12 = __require("os");
|
|
10285
|
+
var CPU_COUNT = Math.max(os12.cpus().length, 1);
|
|
10196
10286
|
exports.DEFAULT_FILE_SYSTEM_ADAPTER = {
|
|
10197
10287
|
lstat: fs49.lstat,
|
|
10198
10288
|
lstatSync: fs49.lstatSync,
|
|
@@ -13403,1029 +13493,1256 @@ var init_concurrency = __esm({
|
|
|
13403
13493
|
}
|
|
13404
13494
|
});
|
|
13405
13495
|
|
|
13406
|
-
// dist/util/
|
|
13407
|
-
var
|
|
13408
|
-
__export(
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13496
|
+
// dist/util/git.js
|
|
13497
|
+
var git_exports = {};
|
|
13498
|
+
__export(git_exports, {
|
|
13499
|
+
DEFAULT_GIT_TIMEOUT_MS: () => DEFAULT_GIT_TIMEOUT_MS,
|
|
13500
|
+
assertSafeRevision: () => assertSafeRevision,
|
|
13501
|
+
clearGitDiscoveryCacheForTests: () => clearGitDiscoveryCacheForTests,
|
|
13502
|
+
clearGitRepositoryCheckCacheForTests: () => clearGitRepositoryCheckCacheForTests,
|
|
13503
|
+
decodeGitPath: () => decodeGitPath,
|
|
13504
|
+
getGitBlobHashes: () => getGitBlobHashes,
|
|
13505
|
+
getGitHead: () => getGitHead,
|
|
13506
|
+
getUnifiedDiff: () => getUnifiedDiff,
|
|
13507
|
+
gitDiffArgs: () => gitDiffArgs,
|
|
13508
|
+
isGitIndexSentinel: () => isGitIndexSentinel,
|
|
13509
|
+
isGitPathIgnored: () => isGitPathIgnored,
|
|
13510
|
+
isGitPathTracked: () => isGitPathTracked,
|
|
13511
|
+
isGitProjectRootIgnored: () => isGitProjectRootIgnored,
|
|
13512
|
+
isGitRepo: () => isGitRepo,
|
|
13513
|
+
isGitWorktreeSentinel: () => isGitWorktreeSentinel,
|
|
13514
|
+
listChangedFiles: () => listChangedFiles,
|
|
13515
|
+
listGitExcludeFiles: () => listGitExcludeFiles,
|
|
13516
|
+
listGitSubmoduleDirectories: () => listGitSubmoduleDirectories,
|
|
13517
|
+
listTrackedFiles: () => listTrackedFiles,
|
|
13518
|
+
listUntrackedFiles: () => listUntrackedFiles,
|
|
13519
|
+
runGit: () => runGit,
|
|
13520
|
+
setGitExecutableForTests: () => setGitExecutableForTests
|
|
13419
13521
|
});
|
|
13420
|
-
import
|
|
13522
|
+
import { spawn } from "node:child_process";
|
|
13523
|
+
import { StringDecoder } from "node:string_decoder";
|
|
13421
13524
|
import fsp4 from "node:fs/promises";
|
|
13525
|
+
import os2 from "node:os";
|
|
13422
13526
|
import path8 from "node:path";
|
|
13423
|
-
function
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
function normalizeGlobPattern(globPattern) {
|
|
13427
|
-
return globPattern.trim().replace(/\\/g, "/");
|
|
13428
|
-
}
|
|
13429
|
-
function isIgnoreGlobReopenedByIncludes(ignoreGlob, includeGlobs) {
|
|
13430
|
-
const literalSegments = ignoreGlob.split("/").filter((segment) => segment && !segment.includes("*"));
|
|
13431
|
-
if (!literalSegments.length)
|
|
13432
|
-
return false;
|
|
13433
|
-
return includeGlobs.some((includeGlob) => {
|
|
13434
|
-
const includeSegments = includeGlob.split("/");
|
|
13435
|
-
return literalSegments.every((segment) => includeSegments.includes(segment));
|
|
13436
|
-
});
|
|
13437
|
-
}
|
|
13438
|
-
function isLocationIndependentGlob(globPattern) {
|
|
13439
|
-
return globPattern.startsWith("**/");
|
|
13440
|
-
}
|
|
13441
|
-
function translateGlobRootIgnoreGlobsForScanRoot(scanRoot, globRoot, ignoreGlobs) {
|
|
13442
|
-
const relativeScanRoot = normalizePath(path8.relative(globRoot, scanRoot));
|
|
13443
|
-
if (!relativeScanRoot || !isRelativePathInside(relativeScanRoot)) {
|
|
13444
|
-
return ignoreGlobs.map(normalizeGlobPattern).filter(Boolean);
|
|
13527
|
+
function decodeGitPath(rawPath) {
|
|
13528
|
+
if (!rawPath.startsWith('"') || !rawPath.endsWith('"')) {
|
|
13529
|
+
return rawPath;
|
|
13445
13530
|
}
|
|
13446
|
-
const
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
|
|
13455
|
-
return void 0;
|
|
13456
|
-
}).filter(isPresent);
|
|
13457
|
-
}
|
|
13458
|
-
function stripGitignoreTrailingSpaces(line) {
|
|
13459
|
-
let end = line.length;
|
|
13460
|
-
while (end > 0 && line[end - 1] === " ") {
|
|
13461
|
-
let slashCount = 0;
|
|
13462
|
-
for (let i = end - 2; i >= 0 && line[i] === "\\"; i -= 1) {
|
|
13463
|
-
slashCount += 1;
|
|
13531
|
+
const inner = rawPath.slice(1, -1);
|
|
13532
|
+
const bytes = [];
|
|
13533
|
+
for (let index = 0; index < inner.length; ) {
|
|
13534
|
+
const char = inner[index];
|
|
13535
|
+
if (char !== "\\") {
|
|
13536
|
+
const codePoint = inner.codePointAt(index);
|
|
13537
|
+
bytes.push(...Buffer.from(String.fromCodePoint(codePoint), "utf8"));
|
|
13538
|
+
index += codePoint > 65535 ? 2 : 1;
|
|
13539
|
+
continue;
|
|
13464
13540
|
}
|
|
13465
|
-
|
|
13466
|
-
|
|
13541
|
+
const octal = inner.slice(index + 1, index + 4).match(/^[0-7]{1,3}/);
|
|
13542
|
+
if (octal) {
|
|
13543
|
+
bytes.push(parseInt(octal[0], 8) & 255);
|
|
13544
|
+
index += 1 + octal[0].length;
|
|
13545
|
+
continue;
|
|
13467
13546
|
}
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
function parseGitignoreRule(baseDir, rawLine) {
|
|
13473
|
-
const trimmedLine = stripGitignoreTrailingSpaces(rawLine);
|
|
13474
|
-
if (!trimmedLine)
|
|
13475
|
-
return null;
|
|
13476
|
-
if (trimmedLine.startsWith("#"))
|
|
13477
|
-
return null;
|
|
13478
|
-
const negated = trimmedLine.startsWith("!");
|
|
13479
|
-
let pattern = negated ? trimmedLine.slice(1) : trimmedLine;
|
|
13480
|
-
if (!pattern || pattern === "/")
|
|
13481
|
-
return null;
|
|
13482
|
-
const dirOnly = pattern.endsWith("/");
|
|
13483
|
-
if (dirOnly) {
|
|
13484
|
-
pattern = pattern.slice(0, -1);
|
|
13485
|
-
}
|
|
13486
|
-
if (pattern.startsWith("/")) {
|
|
13487
|
-
pattern = pattern.slice(1);
|
|
13488
|
-
}
|
|
13489
|
-
pattern = pattern.replace(/^\\([#!])/, "$1").replace(/\\/g, "/");
|
|
13490
|
-
if (!pattern)
|
|
13491
|
-
return null;
|
|
13492
|
-
const anchored = trimmedLine.startsWith("/") || negated && trimmedLine.startsWith("!/");
|
|
13493
|
-
const baseMatcherPattern = anchored || pattern.includes("/") ? pattern : `**/${pattern}`;
|
|
13494
|
-
const matcherPattern = dirOnly ? `${baseMatcherPattern}/**` : [baseMatcherPattern, `${baseMatcherPattern}/**`];
|
|
13495
|
-
const matches = (0, import_picomatch.default)(matcherPattern, { dot: true });
|
|
13496
|
-
return {
|
|
13497
|
-
baseDir: normalizePath(baseDir),
|
|
13498
|
-
negated,
|
|
13499
|
-
dirOnly,
|
|
13500
|
-
matches
|
|
13501
|
-
};
|
|
13502
|
-
}
|
|
13503
|
-
async function loadGitignoreRules(projectRoot) {
|
|
13504
|
-
const gitignoreFiles = await (0, import_fast_glob2.default)(["**/.gitignore"], {
|
|
13505
|
-
cwd: projectRoot,
|
|
13506
|
-
absolute: true,
|
|
13507
|
-
dot: true,
|
|
13508
|
-
followSymbolicLinks: false,
|
|
13509
|
-
ignore: DEFAULT_PROJECT_FILE_IGNORES
|
|
13510
|
-
});
|
|
13511
|
-
gitignoreFiles.sort((left, right) => normalizePath(left).localeCompare(normalizePath(right)));
|
|
13512
|
-
const rules = [];
|
|
13513
|
-
for (const gitignoreFile of gitignoreFiles) {
|
|
13514
|
-
if (isIgnoredByGitignore(gitignoreFile, rules)) {
|
|
13547
|
+
const next = inner[index + 1];
|
|
13548
|
+
if (next === "\\" || next === '"') {
|
|
13549
|
+
bytes.push(next.charCodeAt(0));
|
|
13550
|
+
index += 2;
|
|
13515
13551
|
continue;
|
|
13516
13552
|
}
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
} catch {
|
|
13553
|
+
const singleByteEscape = GIT_QUOTED_PATH_SINGLE_BYTE_ESCAPES[next ?? ""];
|
|
13554
|
+
if (singleByteEscape !== void 0) {
|
|
13555
|
+
bytes.push(singleByteEscape);
|
|
13556
|
+
index += 2;
|
|
13522
13557
|
continue;
|
|
13523
13558
|
}
|
|
13559
|
+
bytes.push(92);
|
|
13560
|
+
index += 1;
|
|
13524
13561
|
}
|
|
13525
|
-
return
|
|
13562
|
+
return Buffer.from(bytes).toString("utf8");
|
|
13526
13563
|
}
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13564
|
+
function setGitExecutableForTests(executable) {
|
|
13565
|
+
gitExecutableForTests = executable;
|
|
13566
|
+
}
|
|
13567
|
+
function clearGitRepositoryCheckCacheForTests() {
|
|
13568
|
+
gitRepositoryChecks.clear();
|
|
13569
|
+
}
|
|
13570
|
+
function clearGitDiscoveryCacheForTests() {
|
|
13571
|
+
gitDiscoveryRootIgnoredChecks.clear();
|
|
13572
|
+
gitExcludeFileChecks.clear();
|
|
13573
|
+
}
|
|
13574
|
+
function resolveGitTimeoutMs(timeoutMs) {
|
|
13575
|
+
if (typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0) {
|
|
13576
|
+
return Math.floor(timeoutMs);
|
|
13536
13577
|
}
|
|
13537
|
-
return
|
|
13578
|
+
return DEFAULT_GIT_TIMEOUT_MS;
|
|
13538
13579
|
}
|
|
13539
|
-
function
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13580
|
+
function appendBoundedTail(current, chunk, maxBytes) {
|
|
13581
|
+
function utf8Tail(value, byteLimit) {
|
|
13582
|
+
let start = value.length;
|
|
13583
|
+
let bytes = 0;
|
|
13584
|
+
while (start) {
|
|
13585
|
+
const last = value.charCodeAt(start - 1);
|
|
13586
|
+
const preceding = start > 1 ? value.charCodeAt(start - 2) : void 0;
|
|
13587
|
+
const isSurrogatePair = last >= 56320 && last <= 57343 && preceding !== void 0 && preceding >= 55296 && preceding <= 56319;
|
|
13588
|
+
const codeUnits = isSurrogatePair ? 2 : 1;
|
|
13589
|
+
let codePointBytes = 3;
|
|
13590
|
+
if (isSurrogatePair) {
|
|
13591
|
+
codePointBytes = 4;
|
|
13592
|
+
} else if (last <= 127) {
|
|
13593
|
+
codePointBytes = 1;
|
|
13594
|
+
} else if (last <= 2047) {
|
|
13595
|
+
codePointBytes = 2;
|
|
13596
|
+
}
|
|
13597
|
+
if (bytes + codePointBytes > byteLimit)
|
|
13598
|
+
break;
|
|
13599
|
+
bytes += codePointBytes;
|
|
13600
|
+
start -= codeUnits;
|
|
13552
13601
|
}
|
|
13602
|
+
return value.slice(start);
|
|
13553
13603
|
}
|
|
13554
|
-
|
|
13604
|
+
if (maxBytes <= 0)
|
|
13605
|
+
return "";
|
|
13606
|
+
const retainedChunk = utf8Tail(chunk, maxBytes);
|
|
13607
|
+
const retainedChunkBytes = Buffer.byteLength(retainedChunk, "utf8");
|
|
13608
|
+
if (retainedChunkBytes >= maxBytes)
|
|
13609
|
+
return retainedChunk;
|
|
13610
|
+
return utf8Tail(current, maxBytes - retainedChunkBytes) + retainedChunk;
|
|
13555
13611
|
}
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13612
|
+
function killGitChild(child) {
|
|
13613
|
+
if (child.killed || child.exitCode !== null)
|
|
13614
|
+
return;
|
|
13559
13615
|
try {
|
|
13560
|
-
|
|
13561
|
-
} catch
|
|
13562
|
-
throw new Error(`${label} does not exist or is not readable: ${resolvedPath} (${stringifyUnknown(error51)})`);
|
|
13563
|
-
}
|
|
13564
|
-
if (!stats.isDirectory()) {
|
|
13565
|
-
throw new Error(`${label} is not a directory: ${resolvedPath}`);
|
|
13616
|
+
child.kill("SIGTERM");
|
|
13617
|
+
} catch {
|
|
13566
13618
|
}
|
|
13567
|
-
|
|
13619
|
+
setTimeout(() => {
|
|
13620
|
+
if (child.killed || child.exitCode !== null)
|
|
13621
|
+
return;
|
|
13622
|
+
try {
|
|
13623
|
+
child.kill("SIGKILL");
|
|
13624
|
+
} catch {
|
|
13625
|
+
}
|
|
13626
|
+
}, 1e3).unref?.();
|
|
13568
13627
|
}
|
|
13569
|
-
async function
|
|
13570
|
-
const
|
|
13571
|
-
const
|
|
13572
|
-
const
|
|
13573
|
-
const
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
] : fastGlobIgnoreGlobs;
|
|
13584
|
-
try {
|
|
13585
|
-
const useGitignore = options?.useGitignore ?? true;
|
|
13586
|
-
const realRoot = await fsp4.realpath(root);
|
|
13587
|
-
const gitignoreRules = !useGitignore ? [] : await loadGitignoreRulesForRootAliases(options?.gitignoreRoot ? await ensureDirectoryReadable(options.gitignoreRoot, "Gitignore root") : root);
|
|
13588
|
-
const files = await (0, import_fast_glob2.default)(patterns, {
|
|
13589
|
-
cwd: root,
|
|
13590
|
-
absolute: true,
|
|
13591
|
-
dot: true,
|
|
13592
|
-
followSymbolicLinks: false,
|
|
13593
|
-
ignore: fastGlobIgnoreGlobs
|
|
13628
|
+
async function runGit(projectRoot, args, options) {
|
|
13629
|
+
const timeoutMs = resolveGitTimeoutMs(options?.timeoutMs);
|
|
13630
|
+
const maxBuffer = options?.maxBuffer ?? 64 * 1024 * 1024;
|
|
13631
|
+
const executable = gitExecutableForTests ?? "git";
|
|
13632
|
+
const signal = options?.signal;
|
|
13633
|
+
if (signal?.aborted) {
|
|
13634
|
+
throw createGitError(projectRoot, args, new Error("aborted before start"));
|
|
13635
|
+
}
|
|
13636
|
+
return await new Promise((resolve, reject) => {
|
|
13637
|
+
const child = spawn(executable, args, {
|
|
13638
|
+
cwd: projectRoot,
|
|
13639
|
+
env: process.env,
|
|
13640
|
+
stdio: [options?.input !== void 0 ? "pipe" : "ignore", "pipe", "pipe"],
|
|
13641
|
+
windowsHide: true
|
|
13594
13642
|
});
|
|
13595
|
-
|
|
13596
|
-
|
|
13597
|
-
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13643
|
+
options?.onSpawn?.(child.pid === void 0 ? {} : { pid: child.pid });
|
|
13644
|
+
let stdout = "";
|
|
13645
|
+
let stderr = "";
|
|
13646
|
+
let settled = false;
|
|
13647
|
+
let timedOut = false;
|
|
13648
|
+
let aborted2 = false;
|
|
13649
|
+
let totalBytes = 0;
|
|
13650
|
+
let stderrBytes = 0;
|
|
13651
|
+
let stderrOverflowed = false;
|
|
13652
|
+
const settle = (fn) => {
|
|
13653
|
+
if (settled)
|
|
13654
|
+
return;
|
|
13655
|
+
settled = true;
|
|
13656
|
+
clearTimeout(timer);
|
|
13657
|
+
if (signal)
|
|
13658
|
+
signal.removeEventListener("abort", onAbort);
|
|
13659
|
+
fn();
|
|
13606
13660
|
};
|
|
13607
|
-
const
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13661
|
+
const timer = setTimeout(() => {
|
|
13662
|
+
timedOut = true;
|
|
13663
|
+
killGitChild(child);
|
|
13664
|
+
}, timeoutMs);
|
|
13665
|
+
timer.unref?.();
|
|
13666
|
+
const onAbort = () => {
|
|
13667
|
+
aborted2 = true;
|
|
13668
|
+
killGitChild(child);
|
|
13669
|
+
};
|
|
13670
|
+
if (signal)
|
|
13671
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
13672
|
+
const stdoutStream = child.stdout;
|
|
13673
|
+
const stderrStream = child.stderr;
|
|
13674
|
+
if (!stdoutStream || !stderrStream) {
|
|
13675
|
+
killGitChild(child);
|
|
13676
|
+
settle(() => reject(createGitError(projectRoot, args, new Error("git child missing stdio pipes"))));
|
|
13677
|
+
return;
|
|
13678
|
+
}
|
|
13679
|
+
const stdoutDecoder = new StringDecoder("utf8");
|
|
13680
|
+
const stderrDecoder = new StringDecoder("utf8");
|
|
13681
|
+
stdoutStream.on("data", (chunk) => {
|
|
13682
|
+
const chunkBytes = typeof chunk === "string" ? Buffer.byteLength(chunk, "utf8") : chunk.length;
|
|
13683
|
+
totalBytes += chunkBytes;
|
|
13684
|
+
if (totalBytes > maxBuffer) {
|
|
13685
|
+
killGitChild(child);
|
|
13686
|
+
settle(() => reject(createGitError(projectRoot, args, new Error(`stdout exceeded maxBuffer (${maxBuffer} bytes)`))));
|
|
13687
|
+
return;
|
|
13688
|
+
}
|
|
13689
|
+
stdout += typeof chunk === "string" ? chunk : stdoutDecoder.write(chunk);
|
|
13617
13690
|
});
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
if (
|
|
13626
|
-
|
|
13627
|
-
|
|
13628
|
-
|
|
13629
|
-
const matchesInclude = !includeMatchers.length || includeMatchers.some((matcher) => matchesDiscoveryGlob(filePath, globRoot, matcher));
|
|
13630
|
-
if (!matchesInclude)
|
|
13631
|
-
return false;
|
|
13632
|
-
if (userIgnoreMatchers.some((matcher) => matchesDiscoveryGlob(filePath, globRoot, matcher))) {
|
|
13633
|
-
return false;
|
|
13691
|
+
stderrStream.on("data", (chunk) => {
|
|
13692
|
+
if (stderrOverflowed)
|
|
13693
|
+
return;
|
|
13694
|
+
const chunkBytes = typeof chunk === "string" ? Buffer.byteLength(chunk, "utf8") : chunk.length;
|
|
13695
|
+
stderrBytes += chunkBytes;
|
|
13696
|
+
const decoded = typeof chunk === "string" ? chunk : stderrDecoder.write(chunk);
|
|
13697
|
+
stderr = appendBoundedTail(stderr, decoded, maxBuffer);
|
|
13698
|
+
if (stderrBytes > maxBuffer) {
|
|
13699
|
+
stderrOverflowed = true;
|
|
13700
|
+
killGitChild(child);
|
|
13701
|
+
settle(() => reject(createGitError(projectRoot, args, new Error(`stderr exceeded maxBuffer (${maxBuffer} bytes): ${stderr.trim()}`))));
|
|
13634
13702
|
}
|
|
13635
|
-
|
|
13636
|
-
|
|
13637
|
-
|
|
13703
|
+
});
|
|
13704
|
+
child.on("error", (error51) => {
|
|
13705
|
+
settle(() => reject(createGitError(projectRoot, args, error51)));
|
|
13706
|
+
});
|
|
13707
|
+
child.on("close", (code, signalName) => {
|
|
13708
|
+
stdout += stdoutDecoder.end();
|
|
13709
|
+
stderr = appendBoundedTail(stderr, stderrDecoder.end(), maxBuffer);
|
|
13710
|
+
settle(() => {
|
|
13711
|
+
if (timedOut) {
|
|
13712
|
+
reject(createGitError(projectRoot, args, new Error(`timed out after ${timeoutMs}ms${stderr ? `: ${stderr.trim()}` : ""}`)));
|
|
13713
|
+
return;
|
|
13714
|
+
}
|
|
13715
|
+
if (aborted2) {
|
|
13716
|
+
reject(createGitError(projectRoot, args, new Error(`aborted${stderr ? `: ${stderr.trim()}` : ""}`)));
|
|
13717
|
+
return;
|
|
13718
|
+
}
|
|
13719
|
+
if (code !== 0) {
|
|
13720
|
+
reject(new Error(`git ${args.join(" ")} failed (${code ?? signalName ?? "unknown"}): ${stderr || stdout || "unknown error"}`));
|
|
13721
|
+
return;
|
|
13722
|
+
}
|
|
13723
|
+
resolve({ stdout, stderr });
|
|
13724
|
+
});
|
|
13725
|
+
});
|
|
13726
|
+
if (options?.input !== void 0) {
|
|
13727
|
+
if (!child.stdin) {
|
|
13728
|
+
killGitChild(child);
|
|
13729
|
+
settle(() => reject(createGitError(projectRoot, args, new Error("git child missing stdin pipe"))));
|
|
13730
|
+
return;
|
|
13638
13731
|
}
|
|
13639
|
-
|
|
13640
|
-
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
|
|
13732
|
+
child.stdin.write(options.input);
|
|
13733
|
+
child.stdin.end();
|
|
13734
|
+
}
|
|
13735
|
+
});
|
|
13736
|
+
}
|
|
13737
|
+
async function runGitCollectStdout(projectRoot, args) {
|
|
13738
|
+
const { stdout } = await runGit(projectRoot, args);
|
|
13739
|
+
return stdout;
|
|
13740
|
+
}
|
|
13741
|
+
function isGitWorktreeSentinel(value) {
|
|
13742
|
+
return value.toUpperCase() === "WORKTREE";
|
|
13743
|
+
}
|
|
13744
|
+
function isGitIndexSentinel(value) {
|
|
13745
|
+
const normalized = value.toUpperCase();
|
|
13746
|
+
return normalized === "INDEX" || normalized === "STAGED";
|
|
13747
|
+
}
|
|
13748
|
+
function assertSafeRevision(value, label) {
|
|
13749
|
+
if (UNSAFE_REVISION_CHARACTERS.test(value)) {
|
|
13750
|
+
throw new Error(`Invalid ${label}: revisions must not contain NUL or newline characters.`);
|
|
13751
|
+
}
|
|
13752
|
+
const trimmed = value.trim();
|
|
13753
|
+
if (!trimmed) {
|
|
13754
|
+
throw new Error(`Invalid ${label}: revision must not be empty.`);
|
|
13755
|
+
}
|
|
13756
|
+
if (trimmed.startsWith("-")) {
|
|
13757
|
+
throw new Error(`Invalid ${label} "${trimmed}": revisions must not start with "-".`);
|
|
13644
13758
|
}
|
|
13759
|
+
return trimmed;
|
|
13645
13760
|
}
|
|
13646
|
-
function
|
|
13647
|
-
const
|
|
13648
|
-
const
|
|
13649
|
-
const
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13658
|
-
const matchesInclude = !includeMatchers.length || includeMatchers.some((matcher) => matchesDiscoveryGlob(absolutePath, globRoot, matcher));
|
|
13659
|
-
if (!matchesInclude)
|
|
13660
|
-
return false;
|
|
13661
|
-
if (defaultIgnoreMatchers.some((matcher) => matcher(normalizedRootRelative))) {
|
|
13662
|
-
if (!(includeMatchers.length > 0 && matchesInclude))
|
|
13663
|
-
return false;
|
|
13664
|
-
}
|
|
13665
|
-
return !userIgnoreMatchers.some((matcher) => matchesDiscoveryGlob(absolutePath, globRoot, matcher));
|
|
13666
|
-
};
|
|
13761
|
+
function gitDiffArgs(base, head, extraArgs = []) {
|
|
13762
|
+
const safeBase = assertSafeRevision(base, "base");
|
|
13763
|
+
const diffSafetyArgs = ["--no-ext-diff", "--no-textconv"];
|
|
13764
|
+
const renameArgs = ["--find-renames"];
|
|
13765
|
+
if (isGitWorktreeSentinel(head)) {
|
|
13766
|
+
return ["diff", ...diffSafetyArgs, ...renameArgs, ...extraArgs, "--end-of-options", safeBase];
|
|
13767
|
+
}
|
|
13768
|
+
if (isGitIndexSentinel(head)) {
|
|
13769
|
+
return ["diff", "--cached", ...diffSafetyArgs, ...renameArgs, ...extraArgs, "--end-of-options", safeBase];
|
|
13770
|
+
}
|
|
13771
|
+
const safeHead = assertSafeRevision(head, "head");
|
|
13772
|
+
return ["diff", ...diffSafetyArgs, ...renameArgs, ...extraArgs, "--end-of-options", `${safeBase}..${safeHead}`];
|
|
13667
13773
|
}
|
|
13668
|
-
async function
|
|
13774
|
+
async function getGitHead(projectRoot) {
|
|
13669
13775
|
try {
|
|
13670
|
-
|
|
13671
|
-
|
|
13672
|
-
|
|
13673
|
-
fsp4.lstat(linkPath),
|
|
13674
|
-
fsp4.realpath(linkPath),
|
|
13675
|
-
fsp4.stat(linkPath)
|
|
13676
|
-
]);
|
|
13677
|
-
if (!linkStats.isSymbolicLink())
|
|
13678
|
-
return false;
|
|
13679
|
-
if (!targetStats.isDirectory())
|
|
13680
|
-
return false;
|
|
13681
|
-
if (!isFilePathWithinRoot(realRoot, realPath))
|
|
13682
|
-
return false;
|
|
13683
|
-
return normalizePath(realPath) !== normalizePath(realRoot);
|
|
13776
|
+
const { stdout } = await runGit(projectRoot, ["rev-parse", "HEAD"]);
|
|
13777
|
+
const hash2 = stdout.trim();
|
|
13778
|
+
return hash2 || null;
|
|
13684
13779
|
} catch {
|
|
13685
|
-
return
|
|
13780
|
+
return null;
|
|
13686
13781
|
}
|
|
13687
13782
|
}
|
|
13688
|
-
async function
|
|
13689
|
-
|
|
13690
|
-
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13703
|
-
});
|
|
13704
|
-
const candidates = await mapLimitSemaphore(entries.filter((entry) => entry.dirent.isSymbolicLink()).map((entry) => entry.path), REALPATH_FILTER_CONCURRENCY, async (linkPath) => await isSafeSymlinkDirectory(root, linkPath, realRoot) ? linkPath : null);
|
|
13705
|
-
const discovered = candidates.filter((entry) => entry !== null);
|
|
13706
|
-
options.onSymlinkDirectoriesDiscovered?.(discovered);
|
|
13707
|
-
return discovered;
|
|
13783
|
+
async function isGitRepo(projectRoot) {
|
|
13784
|
+
const resolvedRoot = path8.resolve(projectRoot);
|
|
13785
|
+
const cached2 = gitRepositoryChecks.get(resolvedRoot);
|
|
13786
|
+
if (cached2)
|
|
13787
|
+
return await cached2;
|
|
13788
|
+
const check2 = (async () => {
|
|
13789
|
+
try {
|
|
13790
|
+
const { stdout } = await runGit(resolvedRoot, ["rev-parse", "--is-inside-work-tree"]);
|
|
13791
|
+
return stdout.trim() === "true";
|
|
13792
|
+
} catch {
|
|
13793
|
+
return false;
|
|
13794
|
+
}
|
|
13795
|
+
})();
|
|
13796
|
+
gitRepositoryChecks.set(resolvedRoot, check2);
|
|
13797
|
+
return await check2;
|
|
13708
13798
|
}
|
|
13709
|
-
async function
|
|
13710
|
-
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
|
|
13715
|
-
|
|
13799
|
+
async function isGitPathTracked(projectRoot, file2) {
|
|
13800
|
+
return await runGitPathPredicate(projectRoot, ["ls-files", "--error-unmatch", "--", normalizePath(file2)]);
|
|
13801
|
+
}
|
|
13802
|
+
async function isGitPathIgnored(projectRoot, file2) {
|
|
13803
|
+
return await runGitPathPredicate(projectRoot, ["check-ignore", "--quiet", "--no-index", "--", normalizePath(file2)]);
|
|
13804
|
+
}
|
|
13805
|
+
async function isGitProjectRootIgnored(projectRoot) {
|
|
13806
|
+
const resolvedRoot = path8.resolve(projectRoot);
|
|
13807
|
+
const cached2 = gitDiscoveryRootIgnoredChecks.get(resolvedRoot);
|
|
13808
|
+
if (cached2)
|
|
13809
|
+
return await cached2;
|
|
13810
|
+
const check2 = isGitPathIgnored(resolvedRoot, resolvedRoot);
|
|
13811
|
+
gitDiscoveryRootIgnoredChecks.set(resolvedRoot, check2);
|
|
13812
|
+
return await check2;
|
|
13813
|
+
}
|
|
13814
|
+
async function runGitPathPredicate(projectRoot, args) {
|
|
13815
|
+
try {
|
|
13816
|
+
await runGit(projectRoot, args);
|
|
13817
|
+
return true;
|
|
13818
|
+
} catch (error51) {
|
|
13819
|
+
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
13820
|
+
if (/\bfailed \(1\):/.test(message))
|
|
13821
|
+
return false;
|
|
13822
|
+
if (error51 instanceof Error && message.startsWith(`git ${args.join(" ")} failed in ${projectRoot}:`)) {
|
|
13823
|
+
throw error51;
|
|
13824
|
+
}
|
|
13825
|
+
throw createGitError(projectRoot, args, error51);
|
|
13826
|
+
}
|
|
13827
|
+
}
|
|
13828
|
+
async function getGitBlobHashes(projectRoot, files, opts) {
|
|
13829
|
+
const gitAvailable = opts?.gitAvailable ?? true;
|
|
13830
|
+
if (!gitAvailable)
|
|
13831
|
+
return /* @__PURE__ */ new Map();
|
|
13832
|
+
const relFileSet = new Set(files.map((file2) => normalizePath(path8.relative(projectRoot, file2))).filter((rel) => rel && !rel.startsWith("..") && !path8.isAbsolute(rel) && rel !== "."));
|
|
13833
|
+
if (!relFileSet.size)
|
|
13834
|
+
return /* @__PURE__ */ new Map();
|
|
13835
|
+
try {
|
|
13836
|
+
const { stdout: trackedStdout } = await runGit(projectRoot, ["ls-files", "-z"], {
|
|
13837
|
+
maxBuffer: 64 * 1024 * 1024
|
|
13838
|
+
});
|
|
13839
|
+
const trackedRel = trackedStdout.split("\0").filter((rel) => rel && relFileSet.has(rel));
|
|
13840
|
+
if (!trackedRel.length)
|
|
13841
|
+
return /* @__PURE__ */ new Map();
|
|
13842
|
+
const hashes = await hashGitPaths(projectRoot, trackedRel);
|
|
13843
|
+
if (hashes.length !== trackedRel.length) {
|
|
13844
|
+
logWithLevel(opts?.logLevel, "warn", `Warning: git hash-object returned ${hashes.length} hash(es) for ${trackedRel.length} requested file(s); discarding Git signatures for this build.`);
|
|
13845
|
+
return /* @__PURE__ */ new Map();
|
|
13846
|
+
}
|
|
13847
|
+
const out = /* @__PURE__ */ new Map();
|
|
13848
|
+
for (let i = 0; i < trackedRel.length; i += 1) {
|
|
13849
|
+
const rel = trackedRel[i];
|
|
13850
|
+
const hash2 = hashes[i];
|
|
13851
|
+
if (!hash2)
|
|
13852
|
+
continue;
|
|
13853
|
+
const abs = normalizePath(path8.resolve(projectRoot, rel));
|
|
13854
|
+
out.set(abs, hash2);
|
|
13855
|
+
}
|
|
13856
|
+
return out;
|
|
13857
|
+
} catch (error51) {
|
|
13858
|
+
logWithLevel(opts?.logLevel, "warn", "Warning: Failed to read Git blob hashes; falling back to content hashing.", error51);
|
|
13859
|
+
return /* @__PURE__ */ new Map();
|
|
13860
|
+
}
|
|
13861
|
+
}
|
|
13862
|
+
async function hashGitPaths(projectRoot, trackedRel) {
|
|
13863
|
+
const batches = [];
|
|
13864
|
+
let currentBatch = [];
|
|
13865
|
+
let currentBatchBytes = 0;
|
|
13866
|
+
for (const rel of trackedRel) {
|
|
13867
|
+
const absolutePath = path8.resolve(projectRoot, rel);
|
|
13868
|
+
const pathBytes = Buffer.byteLength(absolutePath, "utf8") + 1;
|
|
13869
|
+
const wouldExceedBatchLimit = currentBatch.length && currentBatchBytes + pathBytes > MAX_GIT_HASH_OBJECT_ARGUMENT_BYTES;
|
|
13870
|
+
if (wouldExceedBatchLimit) {
|
|
13871
|
+
batches.push(currentBatch);
|
|
13872
|
+
currentBatch = [];
|
|
13873
|
+
currentBatchBytes = 0;
|
|
13874
|
+
}
|
|
13875
|
+
currentBatch.push(absolutePath);
|
|
13876
|
+
currentBatchBytes += pathBytes;
|
|
13877
|
+
}
|
|
13878
|
+
if (currentBatch.length)
|
|
13879
|
+
batches.push(currentBatch);
|
|
13880
|
+
const hashes = [];
|
|
13881
|
+
for (const batch of batches) {
|
|
13882
|
+
const { stdout } = await runGit(projectRoot, ["hash-object", "--", ...batch]);
|
|
13883
|
+
hashes.push(...stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
13884
|
+
}
|
|
13885
|
+
return hashes;
|
|
13886
|
+
}
|
|
13887
|
+
async function listChangedFiles(projectRoot, opts) {
|
|
13888
|
+
let args = [
|
|
13889
|
+
"diff",
|
|
13890
|
+
"--no-ext-diff",
|
|
13891
|
+
"--no-textconv",
|
|
13892
|
+
"--find-renames",
|
|
13893
|
+
"--name-only",
|
|
13894
|
+
"-z",
|
|
13895
|
+
"--diff-filter=ACDMRTUXB"
|
|
13896
|
+
];
|
|
13897
|
+
if (opts.base) {
|
|
13898
|
+
const head = opts.head ?? "HEAD";
|
|
13899
|
+
args = gitDiffArgs(opts.base, head, ["--name-only", "-z", "--diff-filter=ACDMRTUXB"]);
|
|
13900
|
+
} else if (opts.changedSince) {
|
|
13901
|
+
args.push("--end-of-options", assertSafeRevision(opts.changedSince, "changedSince"));
|
|
13902
|
+
} else {
|
|
13716
13903
|
return [];
|
|
13717
|
-
|
|
13718
|
-
|
|
13719
|
-
|
|
13720
|
-
|
|
13721
|
-
|
|
13722
|
-
|
|
13723
|
-
|
|
13724
|
-
|
|
13725
|
-
|
|
13726
|
-
|
|
13727
|
-
const cleanPath = filePath.endsWith("/") ? filePath.slice(0, -1) : filePath;
|
|
13728
|
-
return !rootRelativeIgnoreMatchers.some((matcher) => matchesDiscoveryGlob(cleanPath, globRoot, matcher));
|
|
13729
|
-
}));
|
|
13730
|
-
for (const files of filesByDirectory) {
|
|
13731
|
-
for (const file2 of files) {
|
|
13732
|
-
filesByPath.set(normalizePath(file2), file2);
|
|
13904
|
+
}
|
|
13905
|
+
args.push("--");
|
|
13906
|
+
try {
|
|
13907
|
+
const stdout = await runGitCollectStdout(projectRoot, args);
|
|
13908
|
+
const relFiles = stdout.split("\0").filter(Boolean);
|
|
13909
|
+
const out = [];
|
|
13910
|
+
for (const rel of relFiles) {
|
|
13911
|
+
const abs = normalizePath(path8.resolve(projectRoot, rel));
|
|
13912
|
+
if (abs)
|
|
13913
|
+
out.push(abs);
|
|
13733
13914
|
}
|
|
13915
|
+
return Array.from(new Set(out));
|
|
13916
|
+
} catch (error51) {
|
|
13917
|
+
throw createGitError(projectRoot, args, error51);
|
|
13734
13918
|
}
|
|
13735
|
-
return [...filesByPath.values()];
|
|
13736
13919
|
}
|
|
13737
|
-
async function
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
|
|
13920
|
+
async function listTrackedFiles(projectRoot, opts) {
|
|
13921
|
+
if (!(opts?.gitAvailable ?? true))
|
|
13922
|
+
return [];
|
|
13923
|
+
const args = ["ls-files", "-z"];
|
|
13924
|
+
if (opts?.recurseSubmodules)
|
|
13925
|
+
args.push("--recurse-submodules");
|
|
13926
|
+
try {
|
|
13927
|
+
const { stdout } = await runGit(projectRoot, args, { maxBuffer: 64 * 1024 * 1024 });
|
|
13928
|
+
const out = [];
|
|
13929
|
+
for (const rel of stdout.split("\0").filter(Boolean)) {
|
|
13930
|
+
const abs = normalizePath(path8.resolve(projectRoot, rel));
|
|
13931
|
+
if (abs)
|
|
13932
|
+
out.push(abs);
|
|
13744
13933
|
}
|
|
13745
|
-
|
|
13746
|
-
|
|
13934
|
+
return Array.from(new Set(out));
|
|
13935
|
+
} catch (error51) {
|
|
13936
|
+
throw createGitError(projectRoot, args, error51);
|
|
13937
|
+
}
|
|
13747
13938
|
}
|
|
13748
|
-
async function
|
|
13749
|
-
|
|
13750
|
-
|
|
13939
|
+
async function listGitSubmoduleDirectories(projectRoot, opts) {
|
|
13940
|
+
if (!(opts?.gitAvailable ?? true))
|
|
13941
|
+
return [];
|
|
13942
|
+
const args = ["ls-files", "--stage", "-z"];
|
|
13943
|
+
try {
|
|
13944
|
+
const { stdout } = await runGit(projectRoot, args, { maxBuffer: 64 * 1024 * 1024 });
|
|
13945
|
+
const direct = [];
|
|
13946
|
+
for (const record2 of stdout.split("\0").filter(Boolean)) {
|
|
13947
|
+
if (!record2.startsWith("160000 "))
|
|
13948
|
+
continue;
|
|
13949
|
+
const tabIndex = record2.indexOf(" ");
|
|
13950
|
+
if (tabIndex < 0)
|
|
13951
|
+
continue;
|
|
13952
|
+
const rel = record2.slice(tabIndex + 1);
|
|
13953
|
+
if (rel)
|
|
13954
|
+
direct.push(normalizePath(path8.resolve(projectRoot, rel)));
|
|
13955
|
+
}
|
|
13956
|
+
if (!opts?.recurse || !direct.length)
|
|
13957
|
+
return Array.from(new Set(direct));
|
|
13958
|
+
const nested = await Promise.all(direct.map(async (directory) => await listGitSubmoduleDirectories(directory, opts)));
|
|
13959
|
+
return Array.from(/* @__PURE__ */ new Set([...direct, ...nested.flat()]));
|
|
13960
|
+
} catch (error51) {
|
|
13961
|
+
throw createGitError(projectRoot, args, error51);
|
|
13962
|
+
}
|
|
13751
13963
|
}
|
|
13752
|
-
function
|
|
13753
|
-
|
|
13964
|
+
async function listGitExcludeFiles(projectRoot, opts) {
|
|
13965
|
+
if (!(opts?.gitAvailable ?? true))
|
|
13966
|
+
return [];
|
|
13967
|
+
const resolvedRoot = path8.resolve(projectRoot);
|
|
13968
|
+
const cached2 = gitExcludeFileChecks.get(resolvedRoot);
|
|
13969
|
+
if (cached2)
|
|
13970
|
+
return await cached2;
|
|
13971
|
+
const check2 = listGitExcludeFilesUncached(resolvedRoot);
|
|
13972
|
+
gitExcludeFileChecks.set(resolvedRoot, check2);
|
|
13973
|
+
return await check2;
|
|
13754
13974
|
}
|
|
13755
|
-
async function
|
|
13756
|
-
|
|
13757
|
-
|
|
13758
|
-
|
|
13759
|
-
|
|
13975
|
+
async function listGitExcludeFilesUncached(projectRoot) {
|
|
13976
|
+
let baseDir;
|
|
13977
|
+
try {
|
|
13978
|
+
const { stdout } = await runGit(projectRoot, ["rev-parse", "--show-toplevel"]);
|
|
13979
|
+
baseDir = normalizePath(stdout.trim());
|
|
13980
|
+
} catch {
|
|
13981
|
+
return [];
|
|
13982
|
+
}
|
|
13983
|
+
if (!baseDir)
|
|
13984
|
+
return [];
|
|
13985
|
+
const candidates = [];
|
|
13986
|
+
try {
|
|
13987
|
+
const { stdout } = await runGit(projectRoot, ["rev-parse", "--git-path", "info/exclude"]);
|
|
13988
|
+
const resolved = stdout.trim();
|
|
13989
|
+
if (resolved)
|
|
13990
|
+
candidates.push(normalizePath(path8.resolve(projectRoot, resolved)));
|
|
13991
|
+
} catch {
|
|
13992
|
+
}
|
|
13993
|
+
try {
|
|
13994
|
+
const { stdout } = await runGit(projectRoot, ["config", "--get", "core.excludesFile"]);
|
|
13995
|
+
const configured = stdout.trim();
|
|
13996
|
+
if (configured) {
|
|
13997
|
+
const expanded = configured.startsWith("~") ? path8.join(os2.homedir(), configured.slice(1)) : path8.resolve(projectRoot, configured);
|
|
13998
|
+
candidates.push(normalizePath(expanded));
|
|
13999
|
+
}
|
|
14000
|
+
} catch {
|
|
14001
|
+
}
|
|
14002
|
+
const sources = [];
|
|
14003
|
+
for (const file2 of Array.from(new Set(candidates))) {
|
|
13760
14004
|
try {
|
|
13761
|
-
|
|
13762
|
-
|
|
14005
|
+
if ((await fsp4.stat(file2)).isFile())
|
|
14006
|
+
sources.push({ file: file2, baseDir });
|
|
13763
14007
|
} catch {
|
|
13764
|
-
name = null;
|
|
13765
14008
|
}
|
|
13766
14009
|
}
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
|
|
14010
|
+
return sources;
|
|
14011
|
+
}
|
|
14012
|
+
async function listUntrackedFiles(projectRoot, opts) {
|
|
14013
|
+
const gitAvailable = opts?.gitAvailable ?? true;
|
|
14014
|
+
if (!gitAvailable)
|
|
14015
|
+
return [];
|
|
14016
|
+
const args = ["ls-files", "--others", "-z"];
|
|
14017
|
+
if (opts?.respectGitignore ?? true)
|
|
14018
|
+
args.push("--exclude-standard");
|
|
14019
|
+
try {
|
|
14020
|
+
const stdout = await runGitCollectStdout(projectRoot, args);
|
|
14021
|
+
const relFiles = stdout.toString().split("\0").filter(Boolean);
|
|
14022
|
+
const out = [];
|
|
14023
|
+
for (const rel of relFiles) {
|
|
14024
|
+
const abs = normalizePath(path8.resolve(projectRoot, rel));
|
|
14025
|
+
if (abs)
|
|
14026
|
+
out.push(abs);
|
|
13772
14027
|
}
|
|
14028
|
+
return Array.from(new Set(out));
|
|
14029
|
+
} catch (error51) {
|
|
14030
|
+
throw createGitError(projectRoot, args, error51);
|
|
13773
14031
|
}
|
|
13774
|
-
return {
|
|
13775
|
-
path: normalizedPath,
|
|
13776
|
-
kind: def.kind,
|
|
13777
|
-
type: def.type,
|
|
13778
|
-
role: def.role,
|
|
13779
|
-
projectRoot,
|
|
13780
|
-
...name ? { name } : {}
|
|
13781
|
-
};
|
|
13782
14032
|
}
|
|
13783
|
-
async function
|
|
13784
|
-
|
|
14033
|
+
async function getUnifiedDiff(projectRoot, opts) {
|
|
14034
|
+
let args = [
|
|
14035
|
+
"diff",
|
|
14036
|
+
"--no-ext-diff",
|
|
14037
|
+
"--no-textconv",
|
|
14038
|
+
"--find-renames",
|
|
14039
|
+
"--unified=0",
|
|
14040
|
+
"--no-color",
|
|
14041
|
+
"--diff-filter=ACDMRTUXB"
|
|
14042
|
+
];
|
|
14043
|
+
if (opts.base) {
|
|
14044
|
+
const head = opts.head ?? "HEAD";
|
|
14045
|
+
args = gitDiffArgs(opts.base, head, ["--unified=0", "--no-color", "--diff-filter=ACDMRTUXB"]);
|
|
14046
|
+
} else if (opts.changedSince) {
|
|
14047
|
+
args.push("--end-of-options", assertSafeRevision(opts.changedSince, "changedSince"));
|
|
14048
|
+
} else {
|
|
14049
|
+
return "";
|
|
14050
|
+
}
|
|
14051
|
+
args.push("--");
|
|
13785
14052
|
try {
|
|
13786
|
-
|
|
13787
|
-
const allPatterns = PROJECT_FILE_DEFINITIONS.flatMap((def) => def.patterns.map(toProjectGlob));
|
|
13788
|
-
const matches = await (0, import_fast_glob2.default)(allPatterns, {
|
|
13789
|
-
cwd: root,
|
|
13790
|
-
absolute: true,
|
|
13791
|
-
dot: true,
|
|
13792
|
-
followSymbolicLinks: false,
|
|
13793
|
-
ignore: DEFAULT_PROJECT_FILE_IGNORES,
|
|
13794
|
-
markDirectories: true,
|
|
13795
|
-
onlyFiles: false
|
|
13796
|
-
});
|
|
13797
|
-
const linkedMatches = await listEntriesFromSafeSymlinkDirectories(root, realRoot, allPatterns, DEFAULT_PROJECT_FILE_IGNORES, {
|
|
13798
|
-
markDirectories: true,
|
|
13799
|
-
onlyFiles: false,
|
|
13800
|
-
...options?.knownSymlinkDirectories !== void 0 ? { knownSymlinkDirectories: options.knownSymlinkDirectories } : {},
|
|
13801
|
-
...options?.onSymlinkDirectoriesDiscovered ? { onSymlinkDirectoriesDiscovered: options.onSymlinkDirectoriesDiscovered } : {}
|
|
13802
|
-
});
|
|
13803
|
-
const rootSafeMatches = await filterRealPathsWithinRoot([...matches, ...linkedMatches].map((match) => match.endsWith("/") ? match.slice(0, -1) : match), realRoot);
|
|
13804
|
-
const projectFileDefinitionMatchers = PROJECT_FILE_DEFINITIONS.map((definition) => definition.patterns.map((pattern) => pattern.includes("*") || pattern.includes("?") ? new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$") : void 0));
|
|
13805
|
-
const entries = [];
|
|
13806
|
-
const matchTasks = rootSafeMatches.map(async (cleanMatch) => {
|
|
13807
|
-
const stats = await fsp4.stat(cleanMatch);
|
|
13808
|
-
const isDir = stats.isDirectory();
|
|
13809
|
-
const fileName = path8.basename(cleanMatch);
|
|
13810
|
-
for (let definitionIndex = 0; definitionIndex < PROJECT_FILE_DEFINITIONS.length; definitionIndex++) {
|
|
13811
|
-
const def = PROJECT_FILE_DEFINITIONS[definitionIndex];
|
|
13812
|
-
if (isDir && def.kind !== "dir")
|
|
13813
|
-
continue;
|
|
13814
|
-
if (!isDir && def.kind !== "file")
|
|
13815
|
-
continue;
|
|
13816
|
-
const matchesPattern = def.patterns.some((pattern, patternIndex) => {
|
|
13817
|
-
const matcher = projectFileDefinitionMatchers[definitionIndex][patternIndex];
|
|
13818
|
-
return matcher ? matcher.test(fileName) : pattern === fileName;
|
|
13819
|
-
});
|
|
13820
|
-
if (matchesPattern) {
|
|
13821
|
-
entries.push(await buildProjectFileInfo(def, cleanMatch));
|
|
13822
|
-
}
|
|
13823
|
-
}
|
|
13824
|
-
});
|
|
13825
|
-
await Promise.all(matchTasks);
|
|
13826
|
-
const byKey2 = /* @__PURE__ */ new Map();
|
|
13827
|
-
for (const entry of entries) {
|
|
13828
|
-
const key = `${entry.path}::${entry.type}::${entry.role}`;
|
|
13829
|
-
const existing = byKey2.get(key);
|
|
13830
|
-
if (!existing || !existing.name && entry.name) {
|
|
13831
|
-
byKey2.set(key, entry);
|
|
13832
|
-
}
|
|
13833
|
-
}
|
|
13834
|
-
return Array.from(byKey2.values()).sort((a, b) => {
|
|
13835
|
-
if (a.path === b.path)
|
|
13836
|
-
return a.type.localeCompare(b.type);
|
|
13837
|
-
return a.path.localeCompare(b.path);
|
|
13838
|
-
});
|
|
14053
|
+
return await runGitCollectStdout(projectRoot, args);
|
|
13839
14054
|
} catch (error51) {
|
|
13840
|
-
|
|
13841
|
-
throw new Error(`Failed to discover project files in ${root}: ${stringifyUnknown(error51)}`);
|
|
14055
|
+
throw createGitError(projectRoot, args, error51);
|
|
13842
14056
|
}
|
|
13843
14057
|
}
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
"
|
|
14058
|
+
function createGitError(projectRoot, args, error51) {
|
|
14059
|
+
let detail = stringifyUnknown(error51);
|
|
14060
|
+
if (typeof error51 === "object" && error51 !== null && "stderr" in error51 && typeof error51.stderr === "string" && error51.stderr.trim()) {
|
|
14061
|
+
detail = error51.stderr.trim();
|
|
14062
|
+
} else if (error51 instanceof Error && error51.message) {
|
|
14063
|
+
detail = error51.message;
|
|
14064
|
+
}
|
|
14065
|
+
return new Error(`git ${args.join(" ")} failed in ${projectRoot}: ${detail}`);
|
|
14066
|
+
}
|
|
14067
|
+
var DEFAULT_GIT_TIMEOUT_MS, gitRepositoryChecks, gitDiscoveryRootIgnoredChecks, gitExcludeFileChecks, MAX_GIT_HASH_OBJECT_ARGUMENT_BYTES, gitExecutableForTests, GIT_QUOTED_PATH_SINGLE_BYTE_ESCAPES, UNSAFE_REVISION_CHARACTERS;
|
|
14068
|
+
var init_git = __esm({
|
|
14069
|
+
"dist/util/git.js"() {
|
|
13847
14070
|
"use strict";
|
|
13848
|
-
import_fast_glob2 = __toESM(require_out4(), 1);
|
|
13849
|
-
import_picomatch = __toESM(require_picomatch4(), 1);
|
|
13850
|
-
init_logging();
|
|
13851
14071
|
init_ast();
|
|
13852
14072
|
init_paths();
|
|
13853
|
-
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
13857
|
-
|
|
13858
|
-
|
|
13859
|
-
|
|
13860
|
-
|
|
13861
|
-
|
|
13862
|
-
|
|
13863
|
-
|
|
13864
|
-
|
|
13865
|
-
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
|
|
13869
|
-
|
|
13870
|
-
"**/.venv/**",
|
|
13871
|
-
"**/venv/**",
|
|
13872
|
-
"**/site-packages/**",
|
|
13873
|
-
"**/__pycache__/**",
|
|
13874
|
-
"**/vendor/bundle/**",
|
|
13875
|
-
"**/.build/**",
|
|
13876
|
-
"**/Pods/**"
|
|
13877
|
-
];
|
|
13878
|
-
DEFAULT_PROJECT_MANIFESTS = [
|
|
13879
|
-
"package.json",
|
|
13880
|
-
"package-lock.json",
|
|
13881
|
-
"pnpm-lock.yaml",
|
|
13882
|
-
"yarn.lock",
|
|
13883
|
-
"bun.lockb",
|
|
13884
|
-
"pnpm-workspace.yaml",
|
|
13885
|
-
"lerna.json",
|
|
13886
|
-
"nx.json",
|
|
13887
|
-
"turbo.json",
|
|
13888
|
-
"tsconfig.json",
|
|
13889
|
-
"jsconfig.json",
|
|
13890
|
-
"requirements.txt",
|
|
13891
|
-
"requirements.in",
|
|
13892
|
-
"pyproject.toml",
|
|
13893
|
-
"Pipfile",
|
|
13894
|
-
"Pipfile.lock",
|
|
13895
|
-
"poetry.lock",
|
|
13896
|
-
"setup.py",
|
|
13897
|
-
"setup.cfg",
|
|
13898
|
-
"Cargo.toml",
|
|
13899
|
-
"Cargo.lock",
|
|
13900
|
-
"rust-toolchain",
|
|
13901
|
-
"rust-toolchain.toml",
|
|
13902
|
-
"go.mod",
|
|
13903
|
-
"go.sum",
|
|
13904
|
-
"go.work",
|
|
13905
|
-
"Gemfile",
|
|
13906
|
-
"Gemfile.lock",
|
|
13907
|
-
"*.gemspec",
|
|
13908
|
-
"pom.xml",
|
|
13909
|
-
"mvnw",
|
|
13910
|
-
"build.gradle",
|
|
13911
|
-
"build.gradle.kts",
|
|
13912
|
-
"settings.gradle",
|
|
13913
|
-
"settings.gradle.kts",
|
|
13914
|
-
"gradle.properties",
|
|
13915
|
-
"gradlew",
|
|
13916
|
-
"*.csproj",
|
|
13917
|
-
"*.fsproj",
|
|
13918
|
-
"*.vbproj",
|
|
13919
|
-
"*.sln",
|
|
13920
|
-
"Directory.Build.props",
|
|
13921
|
-
"Directory.Build.targets",
|
|
13922
|
-
"global.json",
|
|
13923
|
-
"composer.json",
|
|
13924
|
-
"composer.lock",
|
|
13925
|
-
"Package.swift",
|
|
13926
|
-
"Package.resolved",
|
|
13927
|
-
"CMakeLists.txt",
|
|
13928
|
-
"CMakePresets.json",
|
|
13929
|
-
"CMakeUserPresets.json",
|
|
13930
|
-
"Makefile",
|
|
13931
|
-
"makefile",
|
|
13932
|
-
"GNUmakefile",
|
|
13933
|
-
"configure.ac",
|
|
13934
|
-
"configure.in",
|
|
13935
|
-
"meson.build",
|
|
13936
|
-
"meson_options.txt",
|
|
13937
|
-
"conanfile.txt",
|
|
13938
|
-
"conanfile.py",
|
|
13939
|
-
"vcpkg.json"
|
|
13940
|
-
];
|
|
13941
|
-
DEFAULT_PROJECT_PATTERNS = [
|
|
13942
|
-
"**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,py,pyi,php,vue,svelte,astro,hbs,handlebars,md,mdx,rst,adoc,asciidoc,go,java,cs,rb,rs,html,htm,css,scss,less,kt,kts,swift,zig,c,h,cc,cpp,cxx,c++,hpp,hh,hxx,ipp,tpp,inl,sql}",
|
|
13943
|
-
...DEFAULT_PROJECT_MANIFESTS.map((name) => `**/${name}`)
|
|
13944
|
-
];
|
|
13945
|
-
REALPATH_FILTER_CONCURRENCY = 64;
|
|
14073
|
+
init_logging();
|
|
14074
|
+
DEFAULT_GIT_TIMEOUT_MS = 3e4;
|
|
14075
|
+
gitRepositoryChecks = /* @__PURE__ */ new Map();
|
|
14076
|
+
gitDiscoveryRootIgnoredChecks = /* @__PURE__ */ new Map();
|
|
14077
|
+
gitExcludeFileChecks = /* @__PURE__ */ new Map();
|
|
14078
|
+
MAX_GIT_HASH_OBJECT_ARGUMENT_BYTES = 24 * 1024;
|
|
14079
|
+
gitExecutableForTests = null;
|
|
14080
|
+
GIT_QUOTED_PATH_SINGLE_BYTE_ESCAPES = {
|
|
14081
|
+
a: 7,
|
|
14082
|
+
b: 8,
|
|
14083
|
+
f: 12,
|
|
14084
|
+
n: 10,
|
|
14085
|
+
r: 13,
|
|
14086
|
+
t: 9,
|
|
14087
|
+
v: 11
|
|
14088
|
+
};
|
|
14089
|
+
UNSAFE_REVISION_CHARACTERS = /[\0\r\n]/;
|
|
13946
14090
|
}
|
|
13947
14091
|
});
|
|
13948
14092
|
|
|
13949
|
-
// dist/util/
|
|
13950
|
-
var
|
|
13951
|
-
__export(
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
isGitPathTracked: () => isGitPathTracked,
|
|
13963
|
-
isGitRepo: () => isGitRepo,
|
|
13964
|
-
isGitWorktreeSentinel: () => isGitWorktreeSentinel,
|
|
13965
|
-
listChangedFiles: () => listChangedFiles,
|
|
13966
|
-
listUntrackedFiles: () => listUntrackedFiles,
|
|
13967
|
-
runGit: () => runGit,
|
|
13968
|
-
setGitExecutableForTests: () => setGitExecutableForTests
|
|
14093
|
+
// dist/util/projectFiles.js
|
|
14094
|
+
var projectFiles_exports = {};
|
|
14095
|
+
__export(projectFiles_exports, {
|
|
14096
|
+
DEFAULT_PROJECT_FILE_IGNORES: () => DEFAULT_PROJECT_FILE_IGNORES,
|
|
14097
|
+
DEFAULT_PROJECT_MANIFESTS: () => DEFAULT_PROJECT_MANIFESTS,
|
|
14098
|
+
DEFAULT_PROJECT_PATTERNS: () => DEFAULT_PROJECT_PATTERNS,
|
|
14099
|
+
createDiscoveredFileMatcher: () => createDiscoveredFileMatcher,
|
|
14100
|
+
discoverProjectFiles: () => discoverProjectFiles,
|
|
14101
|
+
filterRealPathsWithinRoot: () => filterRealPathsWithinRoot,
|
|
14102
|
+
isRelativePathInside: () => isRelativePathInside,
|
|
14103
|
+
listProjectFiles: () => listProjectFiles,
|
|
14104
|
+
matchesDiscoveryGlob: () => matchesDiscoveryGlob,
|
|
14105
|
+
translateGlobRootIgnoreGlobsForScanRoot: () => translateGlobRootIgnoreGlobsForScanRoot
|
|
13969
14106
|
});
|
|
13970
|
-
import
|
|
13971
|
-
import
|
|
14107
|
+
import fs6 from "node:fs";
|
|
14108
|
+
import fsp5 from "node:fs/promises";
|
|
13972
14109
|
import path9 from "node:path";
|
|
13973
|
-
function
|
|
13974
|
-
|
|
13975
|
-
|
|
14110
|
+
function isPresent(value) {
|
|
14111
|
+
return value !== void 0;
|
|
14112
|
+
}
|
|
14113
|
+
function normalizeGlobPattern(globPattern) {
|
|
14114
|
+
return globPattern.trim().replace(/\\/g, "/");
|
|
14115
|
+
}
|
|
14116
|
+
function isIgnoreGlobReopenedByIncludes(ignoreGlob, includeGlobs) {
|
|
14117
|
+
const literalSegments = ignoreGlob.split("/").filter((segment) => segment && !segment.includes("*"));
|
|
14118
|
+
if (!literalSegments.length)
|
|
14119
|
+
return false;
|
|
14120
|
+
return includeGlobs.some((includeGlob) => {
|
|
14121
|
+
const includeSegments = includeGlob.split("/");
|
|
14122
|
+
return literalSegments.every((segment) => includeSegments.includes(segment));
|
|
14123
|
+
});
|
|
14124
|
+
}
|
|
14125
|
+
function isLocationIndependentGlob(globPattern) {
|
|
14126
|
+
return globPattern.startsWith("**/");
|
|
14127
|
+
}
|
|
14128
|
+
function translateGlobRootIgnoreGlobsForScanRoot(scanRoot, globRoot, ignoreGlobs) {
|
|
14129
|
+
const relativeScanRoot = normalizePath(path9.relative(globRoot, scanRoot));
|
|
14130
|
+
if (!relativeScanRoot || !isRelativePathInside(relativeScanRoot)) {
|
|
14131
|
+
return ignoreGlobs.map(normalizeGlobPattern).filter(Boolean);
|
|
13976
14132
|
}
|
|
13977
|
-
const
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
14133
|
+
const rootPrefix = `${relativeScanRoot}/`;
|
|
14134
|
+
return ignoreGlobs.map(normalizeGlobPattern).filter(Boolean).map((globPattern) => {
|
|
14135
|
+
const rootRelativePattern = globPattern.startsWith("/") ? globPattern.slice(1) : globPattern;
|
|
14136
|
+
if (isLocationIndependentGlob(rootRelativePattern))
|
|
14137
|
+
return rootRelativePattern;
|
|
14138
|
+
if (rootRelativePattern === relativeScanRoot || rootRelativePattern === `${relativeScanRoot}/**`)
|
|
14139
|
+
return "**";
|
|
14140
|
+
if (rootRelativePattern.startsWith(rootPrefix))
|
|
14141
|
+
return rootRelativePattern.slice(rootPrefix.length) || "**";
|
|
14142
|
+
return void 0;
|
|
14143
|
+
}).filter(isPresent);
|
|
14144
|
+
}
|
|
14145
|
+
function stripGitignoreTrailingSpaces(line) {
|
|
14146
|
+
let end = line.length;
|
|
14147
|
+
while (end > 0 && line[end - 1] === " ") {
|
|
14148
|
+
let slashCount = 0;
|
|
14149
|
+
for (let i = end - 2; i >= 0 && line[i] === "\\"; i -= 1) {
|
|
14150
|
+
slashCount += 1;
|
|
13986
14151
|
}
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
bytes.push(parseInt(octal[0], 8) & 255);
|
|
13990
|
-
index += 1 + octal[0].length;
|
|
13991
|
-
continue;
|
|
14152
|
+
if (slashCount % 2 === 1) {
|
|
14153
|
+
break;
|
|
13992
14154
|
}
|
|
13993
|
-
|
|
13994
|
-
|
|
13995
|
-
|
|
13996
|
-
|
|
14155
|
+
end -= 1;
|
|
14156
|
+
}
|
|
14157
|
+
return line.slice(0, end);
|
|
14158
|
+
}
|
|
14159
|
+
function parseGitignoreRule(baseDir, rawLine) {
|
|
14160
|
+
const trimmedLine = stripGitignoreTrailingSpaces(rawLine);
|
|
14161
|
+
if (!trimmedLine)
|
|
14162
|
+
return null;
|
|
14163
|
+
if (trimmedLine.startsWith("#"))
|
|
14164
|
+
return null;
|
|
14165
|
+
const negated = trimmedLine.startsWith("!");
|
|
14166
|
+
let pattern = negated ? trimmedLine.slice(1) : trimmedLine;
|
|
14167
|
+
if (!pattern || pattern === "/")
|
|
14168
|
+
return null;
|
|
14169
|
+
const dirOnly = pattern.endsWith("/");
|
|
14170
|
+
if (dirOnly) {
|
|
14171
|
+
pattern = pattern.slice(0, -1);
|
|
14172
|
+
}
|
|
14173
|
+
if (pattern.startsWith("/")) {
|
|
14174
|
+
pattern = pattern.slice(1);
|
|
14175
|
+
}
|
|
14176
|
+
pattern = pattern.replace(/^\\([#!])/, "$1").replace(/\\/g, "/");
|
|
14177
|
+
if (!pattern)
|
|
14178
|
+
return null;
|
|
14179
|
+
const anchored = trimmedLine.startsWith("/") || negated && trimmedLine.startsWith("!/");
|
|
14180
|
+
const baseMatcherPattern = anchored || pattern.includes("/") ? pattern : `**/${pattern}`;
|
|
14181
|
+
const matcherPattern = dirOnly ? `${baseMatcherPattern}/**` : [baseMatcherPattern, `${baseMatcherPattern}/**`];
|
|
14182
|
+
const matches = (0, import_picomatch.default)(matcherPattern, { dot: true });
|
|
14183
|
+
return {
|
|
14184
|
+
baseDir: normalizePath(baseDir),
|
|
14185
|
+
negated,
|
|
14186
|
+
dirOnly,
|
|
14187
|
+
matches
|
|
14188
|
+
};
|
|
14189
|
+
}
|
|
14190
|
+
async function buildGitignoreIndex(sources) {
|
|
14191
|
+
const sorted = [...sources].map(({ file: file2, baseDir }) => ({ file: normalizePath(file2), baseDir: normalizePath(baseDir) })).sort((left, right) => {
|
|
14192
|
+
const leftFile = left.file;
|
|
14193
|
+
const rightFile = right.file;
|
|
14194
|
+
const depthDelta = leftFile.split("/").length - rightFile.split("/").length;
|
|
14195
|
+
if (depthDelta !== 0)
|
|
14196
|
+
return depthDelta;
|
|
14197
|
+
if (leftFile < rightFile)
|
|
14198
|
+
return -1;
|
|
14199
|
+
return leftFile > rightFile ? 1 : 0;
|
|
14200
|
+
});
|
|
14201
|
+
const gitignoreIndex = { hasRules: false, byBaseDir: /* @__PURE__ */ new Map() };
|
|
14202
|
+
for (const { file: file2, baseDir } of sorted) {
|
|
14203
|
+
if (isIgnoredByGitignore(file2, gitignoreIndex)) {
|
|
13997
14204
|
continue;
|
|
13998
14205
|
}
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
14206
|
+
let raw;
|
|
14207
|
+
try {
|
|
14208
|
+
raw = await fsp5.readFile(file2, "utf8");
|
|
14209
|
+
} catch {
|
|
14003
14210
|
continue;
|
|
14004
14211
|
}
|
|
14005
|
-
|
|
14006
|
-
|
|
14212
|
+
const baseKey = fileIdentityKey(baseDir);
|
|
14213
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
14214
|
+
const rule = parseGitignoreRule(baseDir, line);
|
|
14215
|
+
if (!rule)
|
|
14216
|
+
continue;
|
|
14217
|
+
const existing = gitignoreIndex.byBaseDir.get(baseKey);
|
|
14218
|
+
if (existing)
|
|
14219
|
+
existing.rules.push(rule);
|
|
14220
|
+
else
|
|
14221
|
+
gitignoreIndex.byBaseDir.set(baseKey, { baseDir, rules: [rule] });
|
|
14222
|
+
gitignoreIndex.hasRules = true;
|
|
14223
|
+
}
|
|
14007
14224
|
}
|
|
14008
|
-
return
|
|
14225
|
+
return gitignoreIndex;
|
|
14009
14226
|
}
|
|
14010
|
-
function
|
|
14011
|
-
|
|
14012
|
-
|
|
14013
|
-
|
|
14014
|
-
|
|
14227
|
+
async function findGitignoreFiles(projectRoot) {
|
|
14228
|
+
return await (0, import_fast_glob2.default)(["**/.gitignore"], {
|
|
14229
|
+
cwd: projectRoot,
|
|
14230
|
+
absolute: true,
|
|
14231
|
+
dot: true,
|
|
14232
|
+
followSymbolicLinks: false,
|
|
14233
|
+
ignore: DEFAULT_PROJECT_FILE_IGNORES
|
|
14234
|
+
});
|
|
14015
14235
|
}
|
|
14016
|
-
function
|
|
14017
|
-
|
|
14018
|
-
|
|
14236
|
+
async function loadGitignoreIndexForRootAliases(projectRoot) {
|
|
14237
|
+
const roots = [projectRoot];
|
|
14238
|
+
const realRoot = await fsp5.realpath(projectRoot);
|
|
14239
|
+
if (normalizePath(realRoot) !== normalizePath(projectRoot)) {
|
|
14240
|
+
roots.push(realRoot);
|
|
14019
14241
|
}
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
|
|
14024
|
-
let start = value.length;
|
|
14025
|
-
let bytes = 0;
|
|
14026
|
-
while (start) {
|
|
14027
|
-
const last = value.charCodeAt(start - 1);
|
|
14028
|
-
const preceding = start > 1 ? value.charCodeAt(start - 2) : void 0;
|
|
14029
|
-
const isSurrogatePair = last >= 56320 && last <= 57343 && preceding !== void 0 && preceding >= 55296 && preceding <= 56319;
|
|
14030
|
-
const codeUnits = isSurrogatePair ? 2 : 1;
|
|
14031
|
-
let codePointBytes = 3;
|
|
14032
|
-
if (isSurrogatePair) {
|
|
14033
|
-
codePointBytes = 4;
|
|
14034
|
-
} else if (last <= 127) {
|
|
14035
|
-
codePointBytes = 1;
|
|
14036
|
-
} else if (last <= 2047) {
|
|
14037
|
-
codePointBytes = 2;
|
|
14038
|
-
}
|
|
14039
|
-
if (bytes + codePointBytes > byteLimit)
|
|
14040
|
-
break;
|
|
14041
|
-
bytes += codePointBytes;
|
|
14042
|
-
start -= codeUnits;
|
|
14242
|
+
const sources = [];
|
|
14243
|
+
for (const root of roots) {
|
|
14244
|
+
for (const file2 of await findGitignoreFiles(root)) {
|
|
14245
|
+
sources.push({ file: file2, baseDir: path9.dirname(file2) });
|
|
14043
14246
|
}
|
|
14044
|
-
return value.slice(start);
|
|
14045
14247
|
}
|
|
14046
|
-
|
|
14047
|
-
return "";
|
|
14048
|
-
const retainedChunk = utf8Tail(chunk, maxBytes);
|
|
14049
|
-
const retainedChunkBytes = Buffer.byteLength(retainedChunk, "utf8");
|
|
14050
|
-
if (retainedChunkBytes >= maxBytes)
|
|
14051
|
-
return retainedChunk;
|
|
14052
|
-
return utf8Tail(current, maxBytes - retainedChunkBytes) + retainedChunk;
|
|
14053
|
-
}
|
|
14054
|
-
function killGitChild(child) {
|
|
14055
|
-
if (child.killed || child.exitCode !== null)
|
|
14056
|
-
return;
|
|
14057
|
-
try {
|
|
14058
|
-
child.kill("SIGTERM");
|
|
14059
|
-
} catch {
|
|
14060
|
-
}
|
|
14061
|
-
setTimeout(() => {
|
|
14062
|
-
if (child.killed || child.exitCode !== null)
|
|
14063
|
-
return;
|
|
14064
|
-
try {
|
|
14065
|
-
child.kill("SIGKILL");
|
|
14066
|
-
} catch {
|
|
14067
|
-
}
|
|
14068
|
-
}, 1e3).unref?.();
|
|
14248
|
+
return await buildGitignoreIndex(sources);
|
|
14069
14249
|
}
|
|
14070
|
-
|
|
14071
|
-
|
|
14072
|
-
|
|
14073
|
-
const
|
|
14074
|
-
|
|
14075
|
-
|
|
14076
|
-
|
|
14250
|
+
function isIgnoredByGitignore(absolutePath, gitignoreIndex) {
|
|
14251
|
+
if (!gitignoreIndex.hasRules)
|
|
14252
|
+
return false;
|
|
14253
|
+
const chain = [];
|
|
14254
|
+
let current = normalizePath(path9.dirname(absolutePath));
|
|
14255
|
+
for (; ; ) {
|
|
14256
|
+
const group = gitignoreIndex.byBaseDir.get(fileIdentityKey(current));
|
|
14257
|
+
if (group)
|
|
14258
|
+
chain.push(group);
|
|
14259
|
+
const parent = normalizePath(path9.dirname(current));
|
|
14260
|
+
if (parent === current)
|
|
14261
|
+
break;
|
|
14262
|
+
current = parent;
|
|
14077
14263
|
}
|
|
14078
|
-
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14082
|
-
|
|
14083
|
-
|
|
14084
|
-
});
|
|
14085
|
-
options?.onSpawn?.(child.pid === void 0 ? {} : { pid: child.pid });
|
|
14086
|
-
let stdout = "";
|
|
14087
|
-
let stderr = "";
|
|
14088
|
-
let settled = false;
|
|
14089
|
-
let timedOut = false;
|
|
14090
|
-
let aborted2 = false;
|
|
14091
|
-
let totalBytes = 0;
|
|
14092
|
-
let stderrBytes = 0;
|
|
14093
|
-
let stderrOverflowed = false;
|
|
14094
|
-
const settle = (fn) => {
|
|
14095
|
-
if (settled)
|
|
14096
|
-
return;
|
|
14097
|
-
settled = true;
|
|
14098
|
-
clearTimeout(timer);
|
|
14099
|
-
if (signal)
|
|
14100
|
-
signal.removeEventListener("abort", onAbort);
|
|
14101
|
-
fn();
|
|
14102
|
-
};
|
|
14103
|
-
const timer = setTimeout(() => {
|
|
14104
|
-
timedOut = true;
|
|
14105
|
-
killGitChild(child);
|
|
14106
|
-
}, timeoutMs);
|
|
14107
|
-
timer.unref?.();
|
|
14108
|
-
const onAbort = () => {
|
|
14109
|
-
aborted2 = true;
|
|
14110
|
-
killGitChild(child);
|
|
14111
|
-
};
|
|
14112
|
-
if (signal)
|
|
14113
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
14114
|
-
const stdoutStream = child.stdout;
|
|
14115
|
-
const stderrStream = child.stderr;
|
|
14116
|
-
if (!stdoutStream || !stderrStream) {
|
|
14117
|
-
killGitChild(child);
|
|
14118
|
-
settle(() => reject(createGitError(projectRoot, args, new Error("git child missing stdio pipes"))));
|
|
14119
|
-
return;
|
|
14264
|
+
let ignored = false;
|
|
14265
|
+
for (let depth = chain.length - 1; depth >= 0; depth -= 1) {
|
|
14266
|
+
const group = chain[depth];
|
|
14267
|
+
const relativePath3 = path9.relative(group.baseDir, absolutePath);
|
|
14268
|
+
if (!isRelativePathInside(relativePath3)) {
|
|
14269
|
+
continue;
|
|
14120
14270
|
}
|
|
14121
|
-
const
|
|
14122
|
-
const
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
if (totalBytes > maxBuffer) {
|
|
14127
|
-
killGitChild(child);
|
|
14128
|
-
settle(() => reject(createGitError(projectRoot, args, new Error(`stdout exceeded maxBuffer (${maxBuffer} bytes)`))));
|
|
14129
|
-
return;
|
|
14130
|
-
}
|
|
14131
|
-
stdout += typeof chunk === "string" ? chunk : stdoutDecoder.write(chunk);
|
|
14132
|
-
});
|
|
14133
|
-
stderrStream.on("data", (chunk) => {
|
|
14134
|
-
if (stderrOverflowed)
|
|
14135
|
-
return;
|
|
14136
|
-
const chunkBytes = typeof chunk === "string" ? Buffer.byteLength(chunk, "utf8") : chunk.length;
|
|
14137
|
-
stderrBytes += chunkBytes;
|
|
14138
|
-
const decoded = typeof chunk === "string" ? chunk : stderrDecoder.write(chunk);
|
|
14139
|
-
stderr = appendBoundedTail(stderr, decoded, maxBuffer);
|
|
14140
|
-
if (stderrBytes > maxBuffer) {
|
|
14141
|
-
stderrOverflowed = true;
|
|
14142
|
-
killGitChild(child);
|
|
14143
|
-
settle(() => reject(createGitError(projectRoot, args, new Error(`stderr exceeded maxBuffer (${maxBuffer} bytes): ${stderr.trim()}`))));
|
|
14271
|
+
const normalizedRelativePath2 = normalizePath(relativePath3);
|
|
14272
|
+
const hasSeparator = normalizedRelativePath2.includes("/");
|
|
14273
|
+
for (const rule of group.rules) {
|
|
14274
|
+
if (rule.dirOnly && !hasSeparator) {
|
|
14275
|
+
continue;
|
|
14144
14276
|
}
|
|
14145
|
-
|
|
14146
|
-
|
|
14147
|
-
settle(() => reject(createGitError(projectRoot, args, error51)));
|
|
14148
|
-
});
|
|
14149
|
-
child.on("close", (code, signalName) => {
|
|
14150
|
-
stdout += stdoutDecoder.end();
|
|
14151
|
-
stderr = appendBoundedTail(stderr, stderrDecoder.end(), maxBuffer);
|
|
14152
|
-
settle(() => {
|
|
14153
|
-
if (timedOut) {
|
|
14154
|
-
reject(createGitError(projectRoot, args, new Error(`timed out after ${timeoutMs}ms${stderr ? `: ${stderr.trim()}` : ""}`)));
|
|
14155
|
-
return;
|
|
14156
|
-
}
|
|
14157
|
-
if (aborted2) {
|
|
14158
|
-
reject(createGitError(projectRoot, args, new Error(`aborted${stderr ? `: ${stderr.trim()}` : ""}`)));
|
|
14159
|
-
return;
|
|
14160
|
-
}
|
|
14161
|
-
if (code !== 0) {
|
|
14162
|
-
reject(new Error(`git ${args.join(" ")} failed (${code ?? signalName ?? "unknown"}): ${stderr || stdout || "unknown error"}`));
|
|
14163
|
-
return;
|
|
14164
|
-
}
|
|
14165
|
-
resolve({ stdout, stderr });
|
|
14166
|
-
});
|
|
14167
|
-
});
|
|
14168
|
-
if (options?.input !== void 0) {
|
|
14169
|
-
if (!child.stdin) {
|
|
14170
|
-
killGitChild(child);
|
|
14171
|
-
settle(() => reject(createGitError(projectRoot, args, new Error("git child missing stdin pipe"))));
|
|
14172
|
-
return;
|
|
14277
|
+
if (rule.matches(normalizedRelativePath2)) {
|
|
14278
|
+
ignored = !rule.negated;
|
|
14173
14279
|
}
|
|
14174
|
-
child.stdin.write(options.input);
|
|
14175
|
-
child.stdin.end();
|
|
14176
14280
|
}
|
|
14177
|
-
});
|
|
14178
|
-
}
|
|
14179
|
-
async function runGitCollectStdout(projectRoot, args) {
|
|
14180
|
-
const { stdout } = await runGit(projectRoot, args);
|
|
14181
|
-
return stdout;
|
|
14182
|
-
}
|
|
14183
|
-
function isGitWorktreeSentinel(value) {
|
|
14184
|
-
return value.toUpperCase() === "WORKTREE";
|
|
14185
|
-
}
|
|
14186
|
-
function isGitIndexSentinel(value) {
|
|
14187
|
-
const normalized = value.toUpperCase();
|
|
14188
|
-
return normalized === "INDEX" || normalized === "STAGED";
|
|
14189
|
-
}
|
|
14190
|
-
function assertSafeRevision(value, label) {
|
|
14191
|
-
if (UNSAFE_REVISION_CHARACTERS.test(value)) {
|
|
14192
|
-
throw new Error(`Invalid ${label}: revisions must not contain NUL or newline characters.`);
|
|
14193
|
-
}
|
|
14194
|
-
const trimmed = value.trim();
|
|
14195
|
-
if (!trimmed) {
|
|
14196
|
-
throw new Error(`Invalid ${label}: revision must not be empty.`);
|
|
14197
|
-
}
|
|
14198
|
-
if (trimmed.startsWith("-")) {
|
|
14199
|
-
throw new Error(`Invalid ${label} "${trimmed}": revisions must not start with "-".`);
|
|
14200
14281
|
}
|
|
14201
|
-
return
|
|
14282
|
+
return ignored;
|
|
14202
14283
|
}
|
|
14203
|
-
function
|
|
14204
|
-
const
|
|
14205
|
-
|
|
14206
|
-
|
|
14207
|
-
|
|
14208
|
-
|
|
14284
|
+
async function ensureDirectoryReadable(directoryPath, label) {
|
|
14285
|
+
const resolvedPath = path9.resolve(directoryPath);
|
|
14286
|
+
let stats;
|
|
14287
|
+
try {
|
|
14288
|
+
stats = await fsp5.stat(resolvedPath);
|
|
14289
|
+
} catch (error51) {
|
|
14290
|
+
throw new Error(`${label} does not exist or is not readable: ${resolvedPath} (${stringifyUnknown(error51)})`);
|
|
14209
14291
|
}
|
|
14210
|
-
if (
|
|
14211
|
-
|
|
14292
|
+
if (!stats.isDirectory()) {
|
|
14293
|
+
throw new Error(`${label} is not a directory: ${resolvedPath}`);
|
|
14212
14294
|
}
|
|
14213
|
-
|
|
14214
|
-
return ["diff", ...diffSafetyArgs, ...renameArgs, ...extraArgs, "--end-of-options", `${safeBase}..${safeHead}`];
|
|
14295
|
+
return resolvedPath;
|
|
14215
14296
|
}
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14297
|
+
function collectCandidateAncestorDirectories(root, files) {
|
|
14298
|
+
const rootKey = fileIdentityKey(root);
|
|
14299
|
+
const seen = /* @__PURE__ */ new Set([rootKey]);
|
|
14300
|
+
const directories = [normalizePath(root)];
|
|
14301
|
+
for (const file2 of files) {
|
|
14302
|
+
let current = normalizePath(path9.dirname(file2));
|
|
14303
|
+
while (fileIdentityKey(current) !== rootKey) {
|
|
14304
|
+
if (seen.has(fileIdentityKey(current)))
|
|
14305
|
+
break;
|
|
14306
|
+
seen.add(fileIdentityKey(current));
|
|
14307
|
+
directories.push(current);
|
|
14308
|
+
const parent = normalizePath(path9.dirname(current));
|
|
14309
|
+
if (parent === current)
|
|
14310
|
+
break;
|
|
14311
|
+
current = parent;
|
|
14312
|
+
}
|
|
14223
14313
|
}
|
|
14314
|
+
return directories;
|
|
14224
14315
|
}
|
|
14225
|
-
async function
|
|
14226
|
-
const
|
|
14227
|
-
const
|
|
14228
|
-
|
|
14229
|
-
return await cached2;
|
|
14230
|
-
const check2 = (async () => {
|
|
14316
|
+
async function findGitIgnoreSources(root, files) {
|
|
14317
|
+
const directories = collectCandidateAncestorDirectories(root, files);
|
|
14318
|
+
const present = await mapLimitSemaphore(directories, REALPATH_FILTER_CONCURRENCY, async (directory) => {
|
|
14319
|
+
const candidate = normalizePath(path9.join(directory, ".gitignore"));
|
|
14231
14320
|
try {
|
|
14232
|
-
|
|
14233
|
-
return stdout.trim() === "true";
|
|
14321
|
+
return (await fsp5.stat(candidate)).isFile() ? { file: candidate, baseDir: directory } : null;
|
|
14234
14322
|
} catch {
|
|
14235
|
-
return
|
|
14323
|
+
return null;
|
|
14236
14324
|
}
|
|
14237
|
-
})
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
async function isGitPathTracked(projectRoot, file2) {
|
|
14242
|
-
return await runGitPathPredicate(projectRoot, ["ls-files", "--error-unmatch", "--", normalizePath(file2)]);
|
|
14325
|
+
});
|
|
14326
|
+
const sources = present.filter((entry) => entry !== null);
|
|
14327
|
+
sources.push(...await listGitExcludeFiles(root));
|
|
14328
|
+
return sources;
|
|
14243
14329
|
}
|
|
14244
|
-
async function
|
|
14245
|
-
|
|
14330
|
+
async function listGitCandidateFiles(root, logLevel) {
|
|
14331
|
+
try {
|
|
14332
|
+
if (!await isGitRepo(root))
|
|
14333
|
+
return null;
|
|
14334
|
+
if (await isGitProjectRootIgnored(root))
|
|
14335
|
+
return null;
|
|
14336
|
+
const [tracked, untracked, submoduleDirectories] = await Promise.all([
|
|
14337
|
+
listTrackedFiles(root, { recurseSubmodules: true, ...logLevel === void 0 ? {} : { logLevel } }),
|
|
14338
|
+
listUntrackedFiles(root, { respectGitignore: true }),
|
|
14339
|
+
listGitSubmoduleDirectories(root, { recurse: true })
|
|
14340
|
+
]);
|
|
14341
|
+
const submoduleUntracked = await Promise.all(submoduleDirectories.map(async (directory) => await listUntrackedFiles(directory, { respectGitignore: true })));
|
|
14342
|
+
const files = Array.from(/* @__PURE__ */ new Set([...tracked, ...untracked, ...submoduleUntracked.flat()])).sort();
|
|
14343
|
+
return { files, gitignoreFiles: await findGitIgnoreSources(root, files) };
|
|
14344
|
+
} catch (error51) {
|
|
14345
|
+
logWithLevel(logLevel, "debug", `Git discovery unavailable for ${root}: ${stringifyUnknown(error51)}`);
|
|
14346
|
+
return null;
|
|
14347
|
+
}
|
|
14246
14348
|
}
|
|
14247
|
-
async function
|
|
14349
|
+
async function listProjectFiles(projectRoot, patterns = DEFAULT_PROJECT_PATTERNS, options) {
|
|
14350
|
+
const root = await ensureDirectoryReadable(projectRoot, "Project root");
|
|
14351
|
+
const globRoot = options?.globRoot ? await ensureDirectoryReadable(options.globRoot, "Glob root") : root;
|
|
14352
|
+
const includeGlobs = (options?.includeGlobs ?? []).map(normalizeGlobPattern).filter(Boolean);
|
|
14353
|
+
const includeMatchers = includeGlobs.map((globPattern) => (0, import_picomatch.default)(globPattern, { dot: true }));
|
|
14354
|
+
const userIgnoreGlobs = (options?.ignoreGlobs ?? []).map(normalizeGlobPattern).filter(Boolean);
|
|
14355
|
+
const userIgnoreMatchers = userIgnoreGlobs.map((globPattern) => (0, import_picomatch.default)(globPattern, { dot: true }));
|
|
14356
|
+
const defaultIgnoreMatchers = DEFAULT_PROJECT_FILE_IGNORES.map((globPattern) => (0, import_picomatch.default)(globPattern, { dot: true }));
|
|
14357
|
+
const patternMatchers = patterns.map((pattern) => (0, import_picomatch.default)(normalizeGlobPattern(pattern), { dot: true }));
|
|
14358
|
+
const translatedUserIgnoreGlobs = translateGlobRootIgnoreGlobsForScanRoot(root, globRoot, userIgnoreGlobs);
|
|
14359
|
+
const fastGlobIgnoreGlobs = [...DEFAULT_PROJECT_FILE_IGNORES, ...translatedUserIgnoreGlobs];
|
|
14360
|
+
const symlinkProbeIgnoreGlobs = includeGlobs.length ? [
|
|
14361
|
+
...translatedUserIgnoreGlobs,
|
|
14362
|
+
...DEFAULT_PROJECT_FILE_IGNORES.filter((ignoreGlob) => !isIgnoreGlobReopenedByIncludes(ignoreGlob, includeGlobs))
|
|
14363
|
+
] : fastGlobIgnoreGlobs;
|
|
14248
14364
|
try {
|
|
14249
|
-
|
|
14250
|
-
|
|
14365
|
+
const useGitignore = options?.useGitignore ?? true;
|
|
14366
|
+
const realRoot = await fsp5.realpath(root);
|
|
14367
|
+
const gitCandidates = useGitignore && options?.gitignoreRoot === void 0 && normalizePath(realRoot) === normalizePath(root) ? await listGitCandidateFiles(root, options?.logLevel) : null;
|
|
14368
|
+
let gitignoreIndex = EMPTY_GITIGNORE_INDEX;
|
|
14369
|
+
if (useGitignore && gitCandidates) {
|
|
14370
|
+
gitignoreIndex = await buildGitignoreIndex(gitCandidates.gitignoreFiles);
|
|
14371
|
+
} else if (useGitignore) {
|
|
14372
|
+
const gitignoreRoot = options?.gitignoreRoot ? await ensureDirectoryReadable(options.gitignoreRoot, "Gitignore root") : root;
|
|
14373
|
+
gitignoreIndex = await loadGitignoreIndexForRootAliases(gitignoreRoot);
|
|
14374
|
+
}
|
|
14375
|
+
const files = gitCandidates ? gitCandidates.files : await (0, import_fast_glob2.default)(patterns, {
|
|
14376
|
+
cwd: root,
|
|
14377
|
+
absolute: true,
|
|
14378
|
+
dot: true,
|
|
14379
|
+
followSymbolicLinks: false,
|
|
14380
|
+
ignore: fastGlobIgnoreGlobs
|
|
14381
|
+
});
|
|
14382
|
+
const includedOverrideFiles = includeGlobs.length && !gitCandidates ? await (0, import_fast_glob2.default)(translateGlobRootIgnoreGlobsForScanRoot(root, globRoot, includeGlobs), {
|
|
14383
|
+
cwd: root,
|
|
14384
|
+
absolute: true,
|
|
14385
|
+
dot: true,
|
|
14386
|
+
followSymbolicLinks: false,
|
|
14387
|
+
ignore: translatedUserIgnoreGlobs
|
|
14388
|
+
}) : [];
|
|
14389
|
+
const symlinkOptions = {
|
|
14390
|
+
globRoot,
|
|
14391
|
+
...gitCandidates ? { candidatePaths: gitCandidates.files } : {},
|
|
14392
|
+
...options?.knownSymlinkDirectories !== void 0 ? { knownSymlinkDirectories: options.knownSymlinkDirectories } : {},
|
|
14393
|
+
...options?.onSymlinkDirectoriesDiscovered ? { onSymlinkDirectoriesDiscovered: options.onSymlinkDirectoriesDiscovered } : {}
|
|
14394
|
+
};
|
|
14395
|
+
const safeSymlinkDirectories = await resolveSafeSymlinkDirectories(root, realRoot, symlinkProbeIgnoreGlobs, symlinkOptions);
|
|
14396
|
+
const linkedFiles = await listEntriesFromSafeSymlinkDirectories(root, realRoot, patterns, fastGlobIgnoreGlobs, {
|
|
14397
|
+
...symlinkOptions,
|
|
14398
|
+
filterIgnoreGlobs: [...DEFAULT_PROJECT_FILE_IGNORES, ...userIgnoreGlobs],
|
|
14399
|
+
resolvedSafeSymlinkDirectories: safeSymlinkDirectories
|
|
14400
|
+
});
|
|
14401
|
+
const linkedOverrideFiles = includeGlobs.length === 0 ? [] : await listEntriesFromSafeSymlinkDirectories(root, realRoot, patterns, translatedUserIgnoreGlobs, {
|
|
14402
|
+
globRoot,
|
|
14403
|
+
filterIgnoreGlobs: userIgnoreGlobs,
|
|
14404
|
+
resolvedSafeSymlinkDirectories: safeSymlinkDirectories
|
|
14405
|
+
});
|
|
14406
|
+
const rootSafeFiles = await filterRealPathsWithinRootEntries([...files, ...includedOverrideFiles, ...linkedFiles, ...linkedOverrideFiles], realRoot);
|
|
14407
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14408
|
+
return rootSafeFiles.map(({ path: filePath, realPath }) => ({ filePath: normalizePath(filePath), realPath })).filter(({ filePath, realPath }) => {
|
|
14409
|
+
if (seen.has(filePath))
|
|
14410
|
+
return false;
|
|
14411
|
+
seen.add(filePath);
|
|
14412
|
+
const rootRelative = normalizePath(path9.relative(root, filePath));
|
|
14413
|
+
if (!isRelativePathInside(rootRelative))
|
|
14414
|
+
return false;
|
|
14415
|
+
if (!patternMatchers.some((matcher) => matcher(rootRelative)))
|
|
14416
|
+
return false;
|
|
14417
|
+
const matchesInclude = !includeMatchers.length || includeMatchers.some((matcher) => matchesDiscoveryGlob(filePath, globRoot, matcher));
|
|
14418
|
+
if (!matchesInclude)
|
|
14419
|
+
return false;
|
|
14420
|
+
if (userIgnoreMatchers.some((matcher) => matchesDiscoveryGlob(filePath, globRoot, matcher))) {
|
|
14421
|
+
return false;
|
|
14422
|
+
}
|
|
14423
|
+
const ignoredByDefault = defaultIgnoreMatchers.some((matcher) => matcher(rootRelative));
|
|
14424
|
+
if (ignoredByDefault && !(includeMatchers.length > 0 && matchesInclude)) {
|
|
14425
|
+
return false;
|
|
14426
|
+
}
|
|
14427
|
+
if (isIgnoredByGitignore(filePath, gitignoreIndex))
|
|
14428
|
+
return false;
|
|
14429
|
+
return normalizePath(realPath) === filePath || !isIgnoredByGitignore(realPath, gitignoreIndex);
|
|
14430
|
+
}).map(({ filePath }) => filePath);
|
|
14251
14431
|
} catch (error51) {
|
|
14252
|
-
|
|
14253
|
-
|
|
14432
|
+
logWithLevel(options?.logLevel, "debug", `listProjectFiles failed for ${root}: ${stringifyUnknown(error51)}`);
|
|
14433
|
+
throw new Error(`Failed to list files in ${root}: ${stringifyUnknown(error51)}`);
|
|
14434
|
+
}
|
|
14435
|
+
}
|
|
14436
|
+
function createDiscoveredFileMatcher(root, globRoot, patterns, options) {
|
|
14437
|
+
const patternMatchers = patterns.map((pattern) => (0, import_picomatch.default)(normalizeGlobPattern(pattern), { dot: true }));
|
|
14438
|
+
const defaultIgnoreMatchers = DEFAULT_PROJECT_FILE_IGNORES.map((pattern) => (0, import_picomatch.default)(normalizeGlobPattern(pattern), { dot: true }));
|
|
14439
|
+
const includeMatchers = (options?.includeGlobs ?? []).map(normalizeGlobPattern).filter(Boolean).map((pattern) => (0, import_picomatch.default)(pattern, { dot: true }));
|
|
14440
|
+
const userIgnoreMatchers = (options?.ignoreGlobs ?? []).map(normalizeGlobPattern).filter(Boolean).map((pattern) => (0, import_picomatch.default)(pattern, { dot: true }));
|
|
14441
|
+
return (absolutePath) => {
|
|
14442
|
+
const rootRelative = path9.relative(root, absolutePath);
|
|
14443
|
+
if (!isRelativePathInside(rootRelative))
|
|
14254
14444
|
return false;
|
|
14255
|
-
|
|
14256
|
-
|
|
14445
|
+
const normalizedRootRelative = normalizePath(rootRelative);
|
|
14446
|
+
if (!patternMatchers.some((matcher) => matcher(normalizedRootRelative)))
|
|
14447
|
+
return false;
|
|
14448
|
+
const matchesInclude = !includeMatchers.length || includeMatchers.some((matcher) => matchesDiscoveryGlob(absolutePath, globRoot, matcher));
|
|
14449
|
+
if (!matchesInclude)
|
|
14450
|
+
return false;
|
|
14451
|
+
if (defaultIgnoreMatchers.some((matcher) => matcher(normalizedRootRelative))) {
|
|
14452
|
+
if (!(includeMatchers.length > 0 && matchesInclude))
|
|
14453
|
+
return false;
|
|
14257
14454
|
}
|
|
14258
|
-
|
|
14259
|
-
}
|
|
14455
|
+
return !userIgnoreMatchers.some((matcher) => matchesDiscoveryGlob(absolutePath, globRoot, matcher));
|
|
14456
|
+
};
|
|
14260
14457
|
}
|
|
14261
|
-
async function
|
|
14262
|
-
const gitAvailable = opts?.gitAvailable ?? true;
|
|
14263
|
-
if (!gitAvailable)
|
|
14264
|
-
return /* @__PURE__ */ new Map();
|
|
14265
|
-
const relFileSet = new Set(files.map((file2) => normalizePath(path9.relative(projectRoot, file2))).filter((rel) => rel && !rel.startsWith("..") && !path9.isAbsolute(rel) && rel !== "."));
|
|
14266
|
-
if (!relFileSet.size)
|
|
14267
|
-
return /* @__PURE__ */ new Map();
|
|
14458
|
+
async function isSafeSymlinkDirectory(root, linkPath, realRoot) {
|
|
14268
14459
|
try {
|
|
14269
|
-
|
|
14270
|
-
|
|
14460
|
+
if (!isRelativePathInside(path9.relative(root, linkPath)))
|
|
14461
|
+
return false;
|
|
14462
|
+
if (!(await fsp5.lstat(linkPath)).isSymbolicLink())
|
|
14463
|
+
return false;
|
|
14464
|
+
const [realPath, targetStats] = await Promise.all([fsp5.realpath(linkPath), fsp5.stat(linkPath)]);
|
|
14465
|
+
if (!targetStats.isDirectory())
|
|
14466
|
+
return false;
|
|
14467
|
+
if (!isFilePathWithinRoot(realRoot, realPath))
|
|
14468
|
+
return false;
|
|
14469
|
+
return normalizePath(realPath) !== normalizePath(realRoot);
|
|
14470
|
+
} catch {
|
|
14471
|
+
return false;
|
|
14472
|
+
}
|
|
14473
|
+
}
|
|
14474
|
+
async function resolveSafeSymlinkDirectories(root, realRoot, ignore, options) {
|
|
14475
|
+
if (options.knownSymlinkDirectories !== void 0) {
|
|
14476
|
+
const verified = await mapLimitSemaphore(Array.from(new Set(options.knownSymlinkDirectories)), REALPATH_FILTER_CONCURRENCY, async (linkPath) => await isSafeSymlinkDirectory(root, linkPath, realRoot) ? linkPath : null);
|
|
14477
|
+
const resolved = verified.filter((entry) => entry !== null);
|
|
14478
|
+
options.onSymlinkDirectoriesDiscovered?.(resolved, "known");
|
|
14479
|
+
return resolved;
|
|
14480
|
+
}
|
|
14481
|
+
if (options.candidatePaths !== void 0) {
|
|
14482
|
+
const ignoreMatchers = ignore.map(normalizeGlobPattern).filter(Boolean).map((pattern) => (0, import_picomatch.default)(pattern, { dot: true }));
|
|
14483
|
+
const candidatePaths = Array.from(new Set(options.candidatePaths)).filter((candidatePath) => {
|
|
14484
|
+
const relativePath3 = normalizePath(path9.relative(root, candidatePath));
|
|
14485
|
+
if (!isRelativePathInside(relativePath3))
|
|
14486
|
+
return false;
|
|
14487
|
+
return !ignoreMatchers.some((matcher) => matcher(relativePath3));
|
|
14271
14488
|
});
|
|
14272
|
-
const
|
|
14273
|
-
|
|
14274
|
-
|
|
14275
|
-
|
|
14276
|
-
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
|
|
14285
|
-
|
|
14286
|
-
|
|
14287
|
-
|
|
14489
|
+
const verified = await mapLimitSemaphore(candidatePaths, REALPATH_FILTER_CONCURRENCY, async (linkPath) => await isSafeSymlinkDirectory(root, linkPath, realRoot) ? linkPath : null);
|
|
14490
|
+
const discovered2 = verified.filter((entry) => entry !== null);
|
|
14491
|
+
options.onSymlinkDirectoriesDiscovered?.(discovered2, "git-candidates");
|
|
14492
|
+
return discovered2;
|
|
14493
|
+
}
|
|
14494
|
+
const entries = await (0, import_fast_glob2.default)(["**/*"], {
|
|
14495
|
+
cwd: root,
|
|
14496
|
+
absolute: true,
|
|
14497
|
+
dot: true,
|
|
14498
|
+
onlyFiles: false,
|
|
14499
|
+
followSymbolicLinks: false,
|
|
14500
|
+
objectMode: true,
|
|
14501
|
+
ignore
|
|
14502
|
+
});
|
|
14503
|
+
const candidates = await mapLimitSemaphore(entries.filter((entry) => entry.dirent.isSymbolicLink()).map((entry) => entry.path), REALPATH_FILTER_CONCURRENCY, async (linkPath) => await isSafeSymlinkDirectory(root, linkPath, realRoot) ? linkPath : null);
|
|
14504
|
+
const discovered = candidates.filter((entry) => entry !== null);
|
|
14505
|
+
options.onSymlinkDirectoriesDiscovered?.(discovered, "filesystem");
|
|
14506
|
+
return discovered;
|
|
14507
|
+
}
|
|
14508
|
+
async function listEntriesFromSafeSymlinkDirectories(root, realRoot, patterns, ignore, options = {}) {
|
|
14509
|
+
const globRoot = options.globRoot ?? root;
|
|
14510
|
+
const filterIgnoreGlobs = options.filterIgnoreGlobs ?? ignore;
|
|
14511
|
+
const rootRelativeIgnoreMatchers = filterIgnoreGlobs.map(normalizeGlobPattern).filter(Boolean).map((globPattern) => (0, import_picomatch.default)(globPattern, { dot: true }));
|
|
14512
|
+
const locationIndependentIgnores = ignore.map(normalizeGlobPattern).filter(isLocationIndependentGlob);
|
|
14513
|
+
const safeSymlinkDirectories = options.resolvedSafeSymlinkDirectories ?? await resolveSafeSymlinkDirectories(root, realRoot, ignore, options);
|
|
14514
|
+
if (!safeSymlinkDirectories.length)
|
|
14515
|
+
return [];
|
|
14516
|
+
const filesByPath = /* @__PURE__ */ new Map();
|
|
14517
|
+
const filesByDirectory = await mapLimitSemaphore(Array.from(safeSymlinkDirectories), REALPATH_FILTER_CONCURRENCY, async (directory) => (await (0, import_fast_glob2.default)(patterns, {
|
|
14518
|
+
cwd: directory,
|
|
14519
|
+
absolute: true,
|
|
14520
|
+
dot: true,
|
|
14521
|
+
followSymbolicLinks: false,
|
|
14522
|
+
ignore: locationIndependentIgnores,
|
|
14523
|
+
...options.onlyFiles !== void 0 ? { onlyFiles: options.onlyFiles } : {},
|
|
14524
|
+
...options.markDirectories !== void 0 ? { markDirectories: options.markDirectories } : {}
|
|
14525
|
+
})).filter((filePath) => {
|
|
14526
|
+
const cleanPath = filePath.endsWith("/") ? filePath.slice(0, -1) : filePath;
|
|
14527
|
+
return !rootRelativeIgnoreMatchers.some((matcher) => matchesDiscoveryGlob(cleanPath, globRoot, matcher));
|
|
14528
|
+
}));
|
|
14529
|
+
for (const files of filesByDirectory) {
|
|
14530
|
+
for (const file2 of files) {
|
|
14531
|
+
filesByPath.set(normalizePath(file2), file2);
|
|
14288
14532
|
}
|
|
14289
|
-
return out;
|
|
14290
|
-
} catch (error51) {
|
|
14291
|
-
logWithLevel(opts?.logLevel, "warn", "Warning: Failed to read Git blob hashes; falling back to content hashing.", error51);
|
|
14292
|
-
return /* @__PURE__ */ new Map();
|
|
14293
14533
|
}
|
|
14534
|
+
return [...filesByPath.values()];
|
|
14294
14535
|
}
|
|
14295
|
-
async function
|
|
14296
|
-
const
|
|
14297
|
-
|
|
14298
|
-
|
|
14299
|
-
|
|
14300
|
-
|
|
14301
|
-
|
|
14302
|
-
const wouldExceedBatchLimit = currentBatch.length && currentBatchBytes + pathBytes > MAX_GIT_HASH_OBJECT_ARGUMENT_BYTES;
|
|
14303
|
-
if (wouldExceedBatchLimit) {
|
|
14304
|
-
batches.push(currentBatch);
|
|
14305
|
-
currentBatch = [];
|
|
14306
|
-
currentBatchBytes = 0;
|
|
14536
|
+
async function filterRealPathsWithinRootEntries(paths, realRoot) {
|
|
14537
|
+
const filtered = await mapLimitSemaphore(paths, REALPATH_FILTER_CONCURRENCY, async (filePath) => {
|
|
14538
|
+
try {
|
|
14539
|
+
const realPath = await fsp5.realpath(filePath);
|
|
14540
|
+
return isFilePathWithinRoot(realRoot, realPath) ? { path: filePath, realPath } : null;
|
|
14541
|
+
} catch {
|
|
14542
|
+
return null;
|
|
14307
14543
|
}
|
|
14308
|
-
|
|
14309
|
-
|
|
14310
|
-
}
|
|
14311
|
-
if (currentBatch.length)
|
|
14312
|
-
batches.push(currentBatch);
|
|
14313
|
-
const hashes = [];
|
|
14314
|
-
for (const batch of batches) {
|
|
14315
|
-
const { stdout } = await runGit(projectRoot, ["hash-object", "--", ...batch]);
|
|
14316
|
-
hashes.push(...stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
14317
|
-
}
|
|
14318
|
-
return hashes;
|
|
14544
|
+
});
|
|
14545
|
+
return filtered.filter((entry) => entry !== null);
|
|
14319
14546
|
}
|
|
14320
|
-
async function
|
|
14321
|
-
|
|
14322
|
-
|
|
14323
|
-
|
|
14324
|
-
|
|
14325
|
-
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
|
|
14329
|
-
|
|
14330
|
-
|
|
14331
|
-
|
|
14332
|
-
|
|
14333
|
-
|
|
14334
|
-
|
|
14335
|
-
|
|
14336
|
-
|
|
14337
|
-
}
|
|
14338
|
-
args.push("--");
|
|
14339
|
-
try {
|
|
14340
|
-
const stdout = await runGitCollectStdout(projectRoot, args);
|
|
14341
|
-
const relFiles = stdout.split("\0").filter(Boolean);
|
|
14342
|
-
const out = [];
|
|
14343
|
-
for (const rel of relFiles) {
|
|
14344
|
-
const abs = normalizePath(path9.resolve(projectRoot, rel));
|
|
14345
|
-
if (abs)
|
|
14346
|
-
out.push(abs);
|
|
14547
|
+
async function filterRealPathsWithinRoot(paths, realRoot) {
|
|
14548
|
+
const entries = await filterRealPathsWithinRootEntries(paths, realRoot);
|
|
14549
|
+
return entries.map((entry) => entry.path);
|
|
14550
|
+
}
|
|
14551
|
+
function toProjectGlob(pattern) {
|
|
14552
|
+
return pattern.startsWith("**/") ? pattern : `**/${pattern}`;
|
|
14553
|
+
}
|
|
14554
|
+
async function buildProjectFileInfo(def, filePath) {
|
|
14555
|
+
const normalizedPath = normalizePath(filePath);
|
|
14556
|
+
const projectRoot = normalizePath(path9.dirname(filePath));
|
|
14557
|
+
let name = null;
|
|
14558
|
+
if (def.parseName && def.kind === "file") {
|
|
14559
|
+
try {
|
|
14560
|
+
const raw = await fsp5.readFile(filePath, "utf8");
|
|
14561
|
+
name = def.parseName(raw, filePath);
|
|
14562
|
+
} catch {
|
|
14563
|
+
name = null;
|
|
14347
14564
|
}
|
|
14348
|
-
return Array.from(new Set(out));
|
|
14349
|
-
} catch (error51) {
|
|
14350
|
-
throw createGitError(projectRoot, args, error51);
|
|
14351
14565
|
}
|
|
14352
|
-
|
|
14353
|
-
|
|
14354
|
-
|
|
14355
|
-
|
|
14356
|
-
|
|
14357
|
-
const args = ["ls-files", "--others", "-z"];
|
|
14358
|
-
if (opts?.respectGitignore ?? true)
|
|
14359
|
-
args.push("--exclude-standard");
|
|
14360
|
-
try {
|
|
14361
|
-
const stdout = await runGitCollectStdout(projectRoot, args);
|
|
14362
|
-
const relFiles = stdout.toString().split("\0").filter(Boolean);
|
|
14363
|
-
const out = [];
|
|
14364
|
-
for (const rel of relFiles) {
|
|
14365
|
-
const abs = normalizePath(path9.resolve(projectRoot, rel));
|
|
14366
|
-
if (abs)
|
|
14367
|
-
out.push(abs);
|
|
14566
|
+
if (!name && def.nameFromPath) {
|
|
14567
|
+
if (def.nameFromPath === "file") {
|
|
14568
|
+
name = trimToNull(path9.basename(filePath, path9.extname(filePath)));
|
|
14569
|
+
} else {
|
|
14570
|
+
name = trimToNull(path9.basename(projectRoot));
|
|
14368
14571
|
}
|
|
14369
|
-
return Array.from(new Set(out));
|
|
14370
|
-
} catch (error51) {
|
|
14371
|
-
throw createGitError(projectRoot, args, error51);
|
|
14372
14572
|
}
|
|
14573
|
+
return {
|
|
14574
|
+
path: normalizedPath,
|
|
14575
|
+
kind: def.kind,
|
|
14576
|
+
type: def.type,
|
|
14577
|
+
role: def.role,
|
|
14578
|
+
projectRoot,
|
|
14579
|
+
...name ? { name } : {}
|
|
14580
|
+
};
|
|
14373
14581
|
}
|
|
14374
|
-
async function
|
|
14375
|
-
|
|
14376
|
-
"diff",
|
|
14377
|
-
"--no-ext-diff",
|
|
14378
|
-
"--no-textconv",
|
|
14379
|
-
"--find-renames",
|
|
14380
|
-
"--unified=0",
|
|
14381
|
-
"--no-color",
|
|
14382
|
-
"--diff-filter=ACDMRTUXB"
|
|
14383
|
-
];
|
|
14384
|
-
if (opts.base) {
|
|
14385
|
-
const head = opts.head ?? "HEAD";
|
|
14386
|
-
args = gitDiffArgs(opts.base, head, ["--unified=0", "--no-color", "--diff-filter=ACDMRTUXB"]);
|
|
14387
|
-
} else if (opts.changedSince) {
|
|
14388
|
-
args.push("--end-of-options", assertSafeRevision(opts.changedSince, "changedSince"));
|
|
14389
|
-
} else {
|
|
14390
|
-
return "";
|
|
14391
|
-
}
|
|
14392
|
-
args.push("--");
|
|
14582
|
+
async function discoverProjectFiles(projectRoot, options) {
|
|
14583
|
+
const root = await ensureDirectoryReadable(projectRoot, "Project root");
|
|
14393
14584
|
try {
|
|
14394
|
-
|
|
14585
|
+
const realRoot = await fsp5.realpath(root);
|
|
14586
|
+
const allPatterns = PROJECT_FILE_DEFINITIONS.flatMap((def) => def.patterns.map(toProjectGlob));
|
|
14587
|
+
const matches = await (0, import_fast_glob2.default)(allPatterns, {
|
|
14588
|
+
cwd: root,
|
|
14589
|
+
absolute: true,
|
|
14590
|
+
dot: true,
|
|
14591
|
+
followSymbolicLinks: false,
|
|
14592
|
+
ignore: DEFAULT_PROJECT_FILE_IGNORES,
|
|
14593
|
+
markDirectories: true,
|
|
14594
|
+
onlyFiles: false
|
|
14595
|
+
});
|
|
14596
|
+
const linkedMatches = await listEntriesFromSafeSymlinkDirectories(root, realRoot, allPatterns, DEFAULT_PROJECT_FILE_IGNORES, {
|
|
14597
|
+
markDirectories: true,
|
|
14598
|
+
onlyFiles: false,
|
|
14599
|
+
...options?.knownSymlinkDirectories !== void 0 ? { knownSymlinkDirectories: options.knownSymlinkDirectories } : {},
|
|
14600
|
+
...options?.onSymlinkDirectoriesDiscovered ? { onSymlinkDirectoriesDiscovered: options.onSymlinkDirectoriesDiscovered } : {}
|
|
14601
|
+
});
|
|
14602
|
+
const rootSafeMatches = await filterRealPathsWithinRoot([...matches, ...linkedMatches].map((match) => match.endsWith("/") ? match.slice(0, -1) : match), realRoot);
|
|
14603
|
+
const projectFileDefinitionMatchers = PROJECT_FILE_DEFINITIONS.map((definition) => definition.patterns.map((pattern) => pattern.includes("*") || pattern.includes("?") ? new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$") : void 0));
|
|
14604
|
+
const entries = [];
|
|
14605
|
+
const matchTasks = rootSafeMatches.map(async (cleanMatch) => {
|
|
14606
|
+
const stats = await fsp5.stat(cleanMatch);
|
|
14607
|
+
const isDir = stats.isDirectory();
|
|
14608
|
+
const fileName = path9.basename(cleanMatch);
|
|
14609
|
+
for (let definitionIndex = 0; definitionIndex < PROJECT_FILE_DEFINITIONS.length; definitionIndex++) {
|
|
14610
|
+
const def = PROJECT_FILE_DEFINITIONS[definitionIndex];
|
|
14611
|
+
if (isDir && def.kind !== "dir")
|
|
14612
|
+
continue;
|
|
14613
|
+
if (!isDir && def.kind !== "file")
|
|
14614
|
+
continue;
|
|
14615
|
+
const matchesPattern = def.patterns.some((pattern, patternIndex) => {
|
|
14616
|
+
const matcher = projectFileDefinitionMatchers[definitionIndex][patternIndex];
|
|
14617
|
+
return matcher ? matcher.test(fileName) : pattern === fileName;
|
|
14618
|
+
});
|
|
14619
|
+
if (matchesPattern) {
|
|
14620
|
+
entries.push(await buildProjectFileInfo(def, cleanMatch));
|
|
14621
|
+
}
|
|
14622
|
+
}
|
|
14623
|
+
});
|
|
14624
|
+
await Promise.all(matchTasks);
|
|
14625
|
+
const byKey2 = /* @__PURE__ */ new Map();
|
|
14626
|
+
for (const entry of entries) {
|
|
14627
|
+
const key = `${entry.path}::${entry.type}::${entry.role}`;
|
|
14628
|
+
const existing = byKey2.get(key);
|
|
14629
|
+
if (!existing || !existing.name && entry.name) {
|
|
14630
|
+
byKey2.set(key, entry);
|
|
14631
|
+
}
|
|
14632
|
+
}
|
|
14633
|
+
return Array.from(byKey2.values()).sort((a, b) => {
|
|
14634
|
+
if (a.path === b.path)
|
|
14635
|
+
return a.type.localeCompare(b.type);
|
|
14636
|
+
return a.path.localeCompare(b.path);
|
|
14637
|
+
});
|
|
14395
14638
|
} catch (error51) {
|
|
14396
|
-
|
|
14397
|
-
|
|
14398
|
-
}
|
|
14399
|
-
function createGitError(projectRoot, args, error51) {
|
|
14400
|
-
let detail = stringifyUnknown(error51);
|
|
14401
|
-
if (typeof error51 === "object" && error51 !== null && "stderr" in error51 && typeof error51.stderr === "string" && error51.stderr.trim()) {
|
|
14402
|
-
detail = error51.stderr.trim();
|
|
14403
|
-
} else if (error51 instanceof Error && error51.message) {
|
|
14404
|
-
detail = error51.message;
|
|
14639
|
+
logWithLevel(options?.logLevel, "debug", `discoverProjectFiles failed for ${root}: ${stringifyUnknown(error51)}`);
|
|
14640
|
+
throw new Error(`Failed to discover project files in ${root}: ${stringifyUnknown(error51)}`);
|
|
14405
14641
|
}
|
|
14406
|
-
return new Error(`git ${args.join(" ")} failed in ${projectRoot}: ${detail}`);
|
|
14407
14642
|
}
|
|
14408
|
-
var
|
|
14409
|
-
var
|
|
14410
|
-
"dist/util/
|
|
14643
|
+
var import_fast_glob2, import_picomatch, DEFAULT_PROJECT_FILE_IGNORES, DEFAULT_PROJECT_MANIFESTS, DEFAULT_PROJECT_PATTERNS, REALPATH_FILTER_CONCURRENCY, EMPTY_GITIGNORE_INDEX;
|
|
14644
|
+
var init_projectFiles = __esm({
|
|
14645
|
+
"dist/util/projectFiles.js"() {
|
|
14411
14646
|
"use strict";
|
|
14647
|
+
import_fast_glob2 = __toESM(require_out4(), 1);
|
|
14648
|
+
import_picomatch = __toESM(require_picomatch4(), 1);
|
|
14649
|
+
init_logging();
|
|
14412
14650
|
init_ast();
|
|
14413
14651
|
init_paths();
|
|
14414
|
-
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
|
|
14420
|
-
|
|
14421
|
-
|
|
14422
|
-
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14427
|
-
|
|
14428
|
-
|
|
14652
|
+
init_discoveryPath();
|
|
14653
|
+
init_discoveryPath();
|
|
14654
|
+
init_definitions();
|
|
14655
|
+
init_parsers();
|
|
14656
|
+
init_concurrency();
|
|
14657
|
+
init_git();
|
|
14658
|
+
DEFAULT_PROJECT_FILE_IGNORES = [
|
|
14659
|
+
"**/node_modules/**",
|
|
14660
|
+
"**/.git/**",
|
|
14661
|
+
// Never treat Codegraph's own on-disk state as project input. `.codegraph/` contains
|
|
14662
|
+
// lifecycle metadata and the indexer disk cache. Keep the legacy cache ignore so
|
|
14663
|
+
// pre-migration checkouts stay excluded from discovery.
|
|
14664
|
+
"**/.codegraph/**",
|
|
14665
|
+
"**/.codegraph-cache/**",
|
|
14666
|
+
"**/dist/**",
|
|
14667
|
+
"**/build/**",
|
|
14668
|
+
"**/target/**",
|
|
14669
|
+
"**/.venv/**",
|
|
14670
|
+
"**/venv/**",
|
|
14671
|
+
"**/site-packages/**",
|
|
14672
|
+
"**/__pycache__/**",
|
|
14673
|
+
"**/vendor/bundle/**",
|
|
14674
|
+
"**/.build/**",
|
|
14675
|
+
"**/Pods/**"
|
|
14676
|
+
];
|
|
14677
|
+
DEFAULT_PROJECT_MANIFESTS = [
|
|
14678
|
+
"package.json",
|
|
14679
|
+
"package-lock.json",
|
|
14680
|
+
"pnpm-lock.yaml",
|
|
14681
|
+
"yarn.lock",
|
|
14682
|
+
"bun.lockb",
|
|
14683
|
+
"pnpm-workspace.yaml",
|
|
14684
|
+
"lerna.json",
|
|
14685
|
+
"nx.json",
|
|
14686
|
+
"turbo.json",
|
|
14687
|
+
"tsconfig.json",
|
|
14688
|
+
"jsconfig.json",
|
|
14689
|
+
"requirements.txt",
|
|
14690
|
+
"requirements.in",
|
|
14691
|
+
"pyproject.toml",
|
|
14692
|
+
"Pipfile",
|
|
14693
|
+
"Pipfile.lock",
|
|
14694
|
+
"poetry.lock",
|
|
14695
|
+
"setup.py",
|
|
14696
|
+
"setup.cfg",
|
|
14697
|
+
"Cargo.toml",
|
|
14698
|
+
"Cargo.lock",
|
|
14699
|
+
"rust-toolchain",
|
|
14700
|
+
"rust-toolchain.toml",
|
|
14701
|
+
"go.mod",
|
|
14702
|
+
"go.sum",
|
|
14703
|
+
"go.work",
|
|
14704
|
+
"Gemfile",
|
|
14705
|
+
"Gemfile.lock",
|
|
14706
|
+
"*.gemspec",
|
|
14707
|
+
"pom.xml",
|
|
14708
|
+
"mvnw",
|
|
14709
|
+
"build.gradle",
|
|
14710
|
+
"build.gradle.kts",
|
|
14711
|
+
"settings.gradle",
|
|
14712
|
+
"settings.gradle.kts",
|
|
14713
|
+
"gradle.properties",
|
|
14714
|
+
"gradlew",
|
|
14715
|
+
"*.csproj",
|
|
14716
|
+
"*.fsproj",
|
|
14717
|
+
"*.vbproj",
|
|
14718
|
+
"*.sln",
|
|
14719
|
+
"Directory.Build.props",
|
|
14720
|
+
"Directory.Build.targets",
|
|
14721
|
+
"global.json",
|
|
14722
|
+
"composer.json",
|
|
14723
|
+
"composer.lock",
|
|
14724
|
+
"Package.swift",
|
|
14725
|
+
"Package.resolved",
|
|
14726
|
+
"CMakeLists.txt",
|
|
14727
|
+
"CMakePresets.json",
|
|
14728
|
+
"CMakeUserPresets.json",
|
|
14729
|
+
"Makefile",
|
|
14730
|
+
"makefile",
|
|
14731
|
+
"GNUmakefile",
|
|
14732
|
+
"configure.ac",
|
|
14733
|
+
"configure.in",
|
|
14734
|
+
"meson.build",
|
|
14735
|
+
"meson_options.txt",
|
|
14736
|
+
"conanfile.txt",
|
|
14737
|
+
"conanfile.py",
|
|
14738
|
+
"vcpkg.json"
|
|
14739
|
+
];
|
|
14740
|
+
DEFAULT_PROJECT_PATTERNS = [
|
|
14741
|
+
"**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,py,pyi,php,vue,svelte,astro,hbs,handlebars,md,mdx,rst,adoc,asciidoc,go,java,cs,rb,rs,html,htm,css,scss,less,kt,kts,swift,zig,c,h,cc,cpp,cxx,c++,hpp,hh,hxx,ipp,tpp,inl,sql}",
|
|
14742
|
+
...DEFAULT_PROJECT_MANIFESTS.map((name) => `**/${name}`)
|
|
14743
|
+
];
|
|
14744
|
+
REALPATH_FILTER_CONCURRENCY = 64;
|
|
14745
|
+
EMPTY_GITIGNORE_INDEX = { hasRules: false, byBaseDir: /* @__PURE__ */ new Map() };
|
|
14429
14746
|
}
|
|
14430
14747
|
});
|
|
14431
14748
|
|
|
@@ -14523,13 +14840,13 @@ var init_projectSymbols = __esm({
|
|
|
14523
14840
|
});
|
|
14524
14841
|
|
|
14525
14842
|
// dist/util/resolution/jvm.js
|
|
14526
|
-
import
|
|
14843
|
+
import fsp6 from "node:fs/promises";
|
|
14527
14844
|
import path10 from "node:path";
|
|
14528
14845
|
async function readJvmSymbolIndex(filePath, cache, options) {
|
|
14529
14846
|
const cached2 = cache.get(filePath);
|
|
14530
14847
|
if (cached2)
|
|
14531
14848
|
return cached2;
|
|
14532
|
-
const source = await
|
|
14849
|
+
const source = await fsp6.readFile(filePath, "utf8");
|
|
14533
14850
|
const packageName = source.match(options.packagePattern)?.[1] ?? null;
|
|
14534
14851
|
const symbols = /* @__PURE__ */ new Set();
|
|
14535
14852
|
for (const match of source.matchAll(options.declarationPattern)) {
|
|
@@ -14684,7 +15001,7 @@ var init_findFirstExisting = __esm({
|
|
|
14684
15001
|
});
|
|
14685
15002
|
|
|
14686
15003
|
// dist/util/resolution/files.js
|
|
14687
|
-
import
|
|
15004
|
+
import fsp7 from "node:fs/promises";
|
|
14688
15005
|
import path12 from "node:path";
|
|
14689
15006
|
async function findNearestFile(startDir, stopDir, fileName) {
|
|
14690
15007
|
let dir = path12.resolve(startDir);
|
|
@@ -14704,7 +15021,7 @@ async function findNearestFile(startDir, stopDir, fileName) {
|
|
|
14704
15021
|
}
|
|
14705
15022
|
async function isDirectory(p) {
|
|
14706
15023
|
try {
|
|
14707
|
-
const st = await
|
|
15024
|
+
const st = await fsp7.stat(p);
|
|
14708
15025
|
return st.isDirectory();
|
|
14709
15026
|
} catch {
|
|
14710
15027
|
return false;
|
|
@@ -14719,7 +15036,7 @@ var init_files = __esm({
|
|
|
14719
15036
|
|
|
14720
15037
|
// dist/util/resolution/go.js
|
|
14721
15038
|
import fs7 from "node:fs";
|
|
14722
|
-
import
|
|
15039
|
+
import fsp8 from "node:fs/promises";
|
|
14723
15040
|
import path13 from "node:path";
|
|
14724
15041
|
function stripInlineComment(line) {
|
|
14725
15042
|
const idx = line.indexOf("//");
|
|
@@ -14729,7 +15046,7 @@ async function parseGoMod(moduleRoot) {
|
|
|
14729
15046
|
const modPath = path13.join(moduleRoot, "go.mod");
|
|
14730
15047
|
if (!await fileExists(modPath))
|
|
14731
15048
|
return null;
|
|
14732
|
-
const raw = await
|
|
15049
|
+
const raw = await fsp8.readFile(modPath, "utf8");
|
|
14733
15050
|
const lines = raw.split(/\r?\n/);
|
|
14734
15051
|
let modulePath = null;
|
|
14735
15052
|
const replacements = /* @__PURE__ */ new Map();
|
|
@@ -14765,7 +15082,7 @@ async function parseGoMod(moduleRoot) {
|
|
|
14765
15082
|
};
|
|
14766
15083
|
}
|
|
14767
15084
|
async function parseGoWork(goWorkPath) {
|
|
14768
|
-
const content = await
|
|
15085
|
+
const content = await fsp8.readFile(goWorkPath, "utf8");
|
|
14769
15086
|
const lines = content.split(/\r?\n/);
|
|
14770
15087
|
const modules = [];
|
|
14771
15088
|
let inUseBlock = false;
|
|
@@ -14794,7 +15111,7 @@ async function parseGoWork(goWorkPath) {
|
|
|
14794
15111
|
}
|
|
14795
15112
|
async function findGoPackageEntry(dirPath) {
|
|
14796
15113
|
try {
|
|
14797
|
-
const stat = await
|
|
15114
|
+
const stat = await fsp8.stat(dirPath);
|
|
14798
15115
|
if (!stat.isDirectory())
|
|
14799
15116
|
return null;
|
|
14800
15117
|
} catch {
|
|
@@ -14802,7 +15119,7 @@ async function findGoPackageEntry(dirPath) {
|
|
|
14802
15119
|
}
|
|
14803
15120
|
let entries = [];
|
|
14804
15121
|
try {
|
|
14805
|
-
entries = await
|
|
15122
|
+
entries = await fsp8.readdir(dirPath, { withFileTypes: true });
|
|
14806
15123
|
} catch {
|
|
14807
15124
|
return null;
|
|
14808
15125
|
}
|
|
@@ -14954,7 +15271,7 @@ var init_node = __esm({
|
|
|
14954
15271
|
});
|
|
14955
15272
|
|
|
14956
15273
|
// dist/util/resolution/phpComposer.js
|
|
14957
|
-
import
|
|
15274
|
+
import fsp9 from "node:fs/promises";
|
|
14958
15275
|
import path15 from "node:path";
|
|
14959
15276
|
function readComposerNamespaceDirs(value, composerDir) {
|
|
14960
15277
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -15004,7 +15321,7 @@ async function loadPhpComposerConfig(composerPath) {
|
|
|
15004
15321
|
return await cached2;
|
|
15005
15322
|
const pending = (async () => {
|
|
15006
15323
|
try {
|
|
15007
|
-
const raw = await
|
|
15324
|
+
const raw = await fsp9.readFile(composerPath, "utf8");
|
|
15008
15325
|
const parsed = JSON.parse(raw);
|
|
15009
15326
|
const composerDir = path15.dirname(composerPath);
|
|
15010
15327
|
const autoload = parsed.autoload && typeof parsed.autoload === "object" ? parsed.autoload : {};
|
|
@@ -15141,7 +15458,7 @@ async function getPhpComposerAutoloadFiles(composerPath, composerConfig) {
|
|
|
15141
15458
|
}
|
|
15142
15459
|
for (const root of roots) {
|
|
15143
15460
|
try {
|
|
15144
|
-
const stat = await
|
|
15461
|
+
const stat = await fsp9.stat(root.path);
|
|
15145
15462
|
if (stat.isDirectory()) {
|
|
15146
15463
|
const files = await listProjectFiles(root.path, ["**/*.php"]);
|
|
15147
15464
|
for (const filePath of files) {
|
|
@@ -15181,7 +15498,7 @@ async function phpFileMatchesNamespacePrefixes(filePath, namespacePrefixes) {
|
|
|
15181
15498
|
}
|
|
15182
15499
|
let source;
|
|
15183
15500
|
try {
|
|
15184
|
-
source = await
|
|
15501
|
+
source = await fsp9.readFile(filePath, "utf8");
|
|
15185
15502
|
} catch {
|
|
15186
15503
|
return false;
|
|
15187
15504
|
}
|
|
@@ -15217,7 +15534,7 @@ var init_phpComposer = __esm({
|
|
|
15217
15534
|
});
|
|
15218
15535
|
|
|
15219
15536
|
// dist/util/resolution/php.js
|
|
15220
|
-
import
|
|
15537
|
+
import fsp10 from "node:fs/promises";
|
|
15221
15538
|
import path16 from "node:path";
|
|
15222
15539
|
async function resolvePhpPathLikeSpecifier(projectRoot, fromFile, spec) {
|
|
15223
15540
|
let base = path16.resolve(path16.dirname(fromFile), spec);
|
|
@@ -15270,7 +15587,7 @@ async function readPhpSymbolIndex(filePath) {
|
|
|
15270
15587
|
const cached2 = phpSymbolIndexCache.get(filePath);
|
|
15271
15588
|
if (cached2)
|
|
15272
15589
|
return cached2;
|
|
15273
|
-
const source = await
|
|
15590
|
+
const source = await fsp10.readFile(filePath, "utf8");
|
|
15274
15591
|
const packageEntries = extractPhpTopLevelPackageEntries(source);
|
|
15275
15592
|
const primaryEntry = packageEntries[0] ?? {
|
|
15276
15593
|
packageName: "",
|
|
@@ -15719,7 +16036,7 @@ var init_php2 = __esm({
|
|
|
15719
16036
|
|
|
15720
16037
|
// dist/util/resolution/python.js
|
|
15721
16038
|
import fs8 from "node:fs";
|
|
15722
|
-
import
|
|
16039
|
+
import fsp11 from "node:fs/promises";
|
|
15723
16040
|
import path17 from "node:path";
|
|
15724
16041
|
function pythonResolutionCacheKey(projectRoot, fromFile, moduleName, importDotCount) {
|
|
15725
16042
|
const normalizedRoot = normalizePath(path17.resolve(projectRoot));
|
|
@@ -15731,7 +16048,7 @@ async function findPythonPackageAnchor(startDir) {
|
|
|
15731
16048
|
let topWithInit = startDir;
|
|
15732
16049
|
while (true) {
|
|
15733
16050
|
try {
|
|
15734
|
-
await
|
|
16051
|
+
await fsp11.access(path17.join(dir, "__init__.py"), fs8.constants.R_OK);
|
|
15735
16052
|
topWithInit = dir;
|
|
15736
16053
|
} catch {
|
|
15737
16054
|
}
|
|
@@ -15777,7 +16094,7 @@ async function resolvePythonModule(projectRoot, fromFile, moduleName, importDotC
|
|
|
15777
16094
|
resolvePythonModuleCache.set(cacheKey3, res);
|
|
15778
16095
|
return res;
|
|
15779
16096
|
}
|
|
15780
|
-
await
|
|
16097
|
+
await fsp11.access(c, fs8.constants.R_OK);
|
|
15781
16098
|
{
|
|
15782
16099
|
const res = normalizePath(path17.resolve(c));
|
|
15783
16100
|
resolvePythonModuleCache.set(cacheKey3, res);
|
|
@@ -15815,7 +16132,7 @@ async function resolvePythonModule(projectRoot, fromFile, moduleName, importDotC
|
|
|
15815
16132
|
resolvePythonModuleCache.set(cacheKey3, res);
|
|
15816
16133
|
return res;
|
|
15817
16134
|
}
|
|
15818
|
-
await
|
|
16135
|
+
await fsp11.access(c, fs8.constants.R_OK);
|
|
15819
16136
|
{
|
|
15820
16137
|
const res = normalizePath(path17.resolve(c));
|
|
15821
16138
|
resolvePythonModuleCache.set(cacheKey3, res);
|
|
@@ -17987,7 +18304,7 @@ var require_lib2 = __commonJS({
|
|
|
17987
18304
|
|
|
17988
18305
|
// dist/util/resolution/tsconfig.js
|
|
17989
18306
|
import fs9 from "node:fs";
|
|
17990
|
-
import
|
|
18307
|
+
import fsp12 from "node:fs/promises";
|
|
17991
18308
|
import { createRequire } from "node:module";
|
|
17992
18309
|
import path19 from "node:path";
|
|
17993
18310
|
async function findNearestTsconfig(startFromFile, projectRoot) {
|
|
@@ -17997,7 +18314,7 @@ async function findNearestTsconfig(startFromFile, projectRoot) {
|
|
|
17997
18314
|
while (isFilePathWithinRoot(resolvedProjectRoot, dir)) {
|
|
17998
18315
|
const candidate = path19.join(dir, "tsconfig.json");
|
|
17999
18316
|
try {
|
|
18000
|
-
await
|
|
18317
|
+
await fsp12.access(candidate, fs9.constants.R_OK);
|
|
18001
18318
|
return candidate;
|
|
18002
18319
|
} catch {
|
|
18003
18320
|
}
|
|
@@ -18058,7 +18375,7 @@ async function loadTsconfigConfig(cfgPath, projectRoot, seen = /* @__PURE__ */ n
|
|
|
18058
18375
|
return { baseUrl: path19.dirname(normalizedCfgPath).replace(/\\/g, "/"), paths: {} };
|
|
18059
18376
|
}
|
|
18060
18377
|
seen.add(cfgKey);
|
|
18061
|
-
const raw = await
|
|
18378
|
+
const raw = await fsp12.readFile(cfgPath, "utf8");
|
|
18062
18379
|
const json3 = parseJsonc(raw);
|
|
18063
18380
|
const cfgDir = path19.dirname(cfgPath);
|
|
18064
18381
|
const compilerOptions = json3.compilerOptions;
|
|
@@ -18181,7 +18498,7 @@ __export(resolution_exports, {
|
|
|
18181
18498
|
resolveSpecifier: () => resolveSpecifier
|
|
18182
18499
|
});
|
|
18183
18500
|
import fs10 from "node:fs";
|
|
18184
|
-
import
|
|
18501
|
+
import fsp13 from "node:fs/promises";
|
|
18185
18502
|
import path20 from "node:path";
|
|
18186
18503
|
function getResolveSpecifierCacheEntry(key) {
|
|
18187
18504
|
return lruMapGet(resolveSpecifierCache, key);
|
|
@@ -18237,7 +18554,7 @@ async function resolvePathLikeModule(projectRoot, spec, resolutionExtensions) {
|
|
|
18237
18554
|
return path20.resolve(path20.join(p, "index" + e));
|
|
18238
18555
|
}
|
|
18239
18556
|
if (await fileExists(p)) {
|
|
18240
|
-
const st = await
|
|
18557
|
+
const st = await fsp13.stat(p);
|
|
18241
18558
|
if (!st.isDirectory())
|
|
18242
18559
|
return path20.resolve(p);
|
|
18243
18560
|
}
|
|
@@ -18584,7 +18901,7 @@ var init_confinedFile = __esm({
|
|
|
18584
18901
|
});
|
|
18585
18902
|
|
|
18586
18903
|
// dist/util/workerThreads.js
|
|
18587
|
-
import
|
|
18904
|
+
import os3 from "node:os";
|
|
18588
18905
|
function resolveWorkerThreadCount(options) {
|
|
18589
18906
|
const max = options?.max ?? 64;
|
|
18590
18907
|
const requested = options?.requested;
|
|
@@ -18595,7 +18912,7 @@ function resolveWorkerThreadCount(options) {
|
|
|
18595
18912
|
if (typeof defaultCount === "number" && Number.isFinite(defaultCount) && defaultCount > 0) {
|
|
18596
18913
|
return Math.min(Math.max(Math.floor(defaultCount), 1), max);
|
|
18597
18914
|
}
|
|
18598
|
-
return Math.min(Math.max(
|
|
18915
|
+
return Math.min(Math.max(os3.availableParallelism() - 1, 1), max);
|
|
18599
18916
|
}
|
|
18600
18917
|
var init_workerThreads = __esm({
|
|
18601
18918
|
"dist/util/workerThreads.js"() {
|
|
@@ -19000,17 +19317,17 @@ var init_sfc = __esm({
|
|
|
19000
19317
|
});
|
|
19001
19318
|
|
|
19002
19319
|
// dist/languages/filePrep.js
|
|
19003
|
-
import
|
|
19320
|
+
import fsp14 from "node:fs/promises";
|
|
19004
19321
|
async function prepareSourceInput(file2, opts) {
|
|
19005
19322
|
const framework = detectSFCFramework(file2);
|
|
19006
19323
|
if (framework) {
|
|
19007
|
-
const rawSource2 = opts?.source ?? await
|
|
19324
|
+
const rawSource2 = opts?.source ?? await fsp14.readFile(file2, "utf8");
|
|
19008
19325
|
return prepareSFCSourceInput(rawSource2, framework);
|
|
19009
19326
|
}
|
|
19010
19327
|
const sup = supportForFile(file2, opts?.languageExtensions);
|
|
19011
19328
|
if (!sup)
|
|
19012
19329
|
throw new UnsupportedParserInputError(file2);
|
|
19013
|
-
const rawSource = opts?.source ?? await
|
|
19330
|
+
const rawSource = opts?.source ?? await fsp14.readFile(file2, "utf8");
|
|
19014
19331
|
return {
|
|
19015
19332
|
source: rawSource,
|
|
19016
19333
|
sup
|
|
@@ -20962,7 +21279,7 @@ var init_angularjs = __esm({
|
|
|
20962
21279
|
});
|
|
20963
21280
|
|
|
20964
21281
|
// dist/graphs/angularjs.js
|
|
20965
|
-
import
|
|
21282
|
+
import fsp15 from "node:fs/promises";
|
|
20966
21283
|
async function collectAngularJsFrameworkEdges(projectRoot, files, workspaceConfig, parsed) {
|
|
20967
21284
|
const jsFiles = files.filter((file2) => file2.toLowerCase().endsWith(".js"));
|
|
20968
21285
|
if (!jsFiles.length)
|
|
@@ -20975,7 +21292,7 @@ async function collectAngularJsFrameworkEdges(projectRoot, files, workspaceConfi
|
|
|
20975
21292
|
continue;
|
|
20976
21293
|
}
|
|
20977
21294
|
try {
|
|
20978
|
-
const source = await
|
|
21295
|
+
const source = await fsp15.readFile(file2, "utf8");
|
|
20979
21296
|
contexts.push({ file: file2, source });
|
|
20980
21297
|
} catch {
|
|
20981
21298
|
continue;
|
|
@@ -24725,7 +25042,7 @@ var init_extractFacts = __esm({
|
|
|
24725
25042
|
|
|
24726
25043
|
// dist/sql/sourceGraph.js
|
|
24727
25044
|
import crypto2 from "node:crypto";
|
|
24728
|
-
import
|
|
25045
|
+
import fsp16 from "node:fs/promises";
|
|
24729
25046
|
function isSqlFile(filePath, languageExtensions) {
|
|
24730
25047
|
return supportForFile(filePath, languageExtensions)?.id === "sql";
|
|
24731
25048
|
}
|
|
@@ -24854,7 +25171,7 @@ function buildSqlModuleIndex(filePath, source) {
|
|
|
24854
25171
|
};
|
|
24855
25172
|
}
|
|
24856
25173
|
async function readSqlFacts(filePath) {
|
|
24857
|
-
return extractSqlFactsFromSource(filePath, await
|
|
25174
|
+
return extractSqlFactsFromSource(filePath, await fsp16.readFile(filePath, "utf8"));
|
|
24858
25175
|
}
|
|
24859
25176
|
async function buildSqlFactCache(allFiles, languageExtensions) {
|
|
24860
25177
|
const sqlFiles2 = Array.from(new Set(allFiles.map(normalizePath).filter((file2) => isSqlFile(file2, languageExtensions)))).sort((left, right) => left.localeCompare(right));
|
|
@@ -25290,7 +25607,7 @@ var init_adjacency = __esm({
|
|
|
25290
25607
|
});
|
|
25291
25608
|
|
|
25292
25609
|
// dist/worker/nativeExtractWorker.js
|
|
25293
|
-
import
|
|
25610
|
+
import fsp17 from "node:fs/promises";
|
|
25294
25611
|
import { createRequire as createRequire3 } from "node:module";
|
|
25295
25612
|
import path32 from "node:path";
|
|
25296
25613
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -25493,9 +25810,9 @@ var init_nativeExtractWorker = __esm({
|
|
|
25493
25810
|
localNativePackageRoot2 = path32.resolve(path32.dirname(fileURLToPath3(import.meta.url)), "../../packages/codegraph-native");
|
|
25494
25811
|
runExtraction = createNativeExtractor({
|
|
25495
25812
|
loadBinding: loadProductionBinding,
|
|
25496
|
-
readFile:
|
|
25813
|
+
readFile: fsp17.readFile,
|
|
25497
25814
|
statFile: async (filePath) => {
|
|
25498
|
-
const stat = await
|
|
25815
|
+
const stat = await fsp17.stat(filePath);
|
|
25499
25816
|
return { size: stat.size };
|
|
25500
25817
|
}
|
|
25501
25818
|
});
|
|
@@ -29805,7 +30122,7 @@ var init_reports = __esm({
|
|
|
29805
30122
|
// dist/indexer/build-cache/location.js
|
|
29806
30123
|
import crypto4 from "node:crypto";
|
|
29807
30124
|
import fs16 from "node:fs";
|
|
29808
|
-
import
|
|
30125
|
+
import os4 from "node:os";
|
|
29809
30126
|
import path35 from "node:path";
|
|
29810
30127
|
function isWritableDirectory(candidate) {
|
|
29811
30128
|
try {
|
|
@@ -29816,7 +30133,7 @@ function isWritableDirectory(candidate) {
|
|
|
29816
30133
|
}
|
|
29817
30134
|
function isForbiddenAnchor(candidate) {
|
|
29818
30135
|
const resolved = path35.resolve(candidate);
|
|
29819
|
-
const home = path35.resolve(
|
|
30136
|
+
const home = path35.resolve(os4.homedir());
|
|
29820
30137
|
const parsed = path35.parse(resolved);
|
|
29821
30138
|
return fileIdentityKey(resolved) === fileIdentityKey(home) || fileIdentityKey(resolved) === fileIdentityKey(parsed.root);
|
|
29822
30139
|
}
|
|
@@ -29840,7 +30157,7 @@ function findRepositoryAnchor(projectRoot) {
|
|
|
29840
30157
|
return { anchor: start, layer: "project" };
|
|
29841
30158
|
}
|
|
29842
30159
|
function resolveCodegraphUserCacheRoot2() {
|
|
29843
|
-
const base = process.platform === "win32" ? process.env.LOCALAPPDATA?.trim() || path35.join(
|
|
30160
|
+
const base = process.platform === "win32" ? process.env.LOCALAPPDATA?.trim() || path35.join(os4.homedir(), "AppData", "Local") : process.env.XDG_CACHE_HOME?.trim() || path35.join(os4.homedir(), ".cache");
|
|
29844
30161
|
return path35.join(base, "codegraph");
|
|
29845
30162
|
}
|
|
29846
30163
|
function projectCacheNamespace(projectRoot, anchor) {
|
|
@@ -29874,7 +30191,33 @@ function assertAnchorNotForbidden(resolution) {
|
|
|
29874
30191
|
return;
|
|
29875
30192
|
if (!isForbiddenAnchor(resolution.anchor))
|
|
29876
30193
|
return;
|
|
29877
|
-
throw new Error(`Cache anchor "${resolution.anchor}" (from ${CONFIGURED_ANCHOR_LAYER_LABELS[resolution.layer]}) is the home directory or a filesystem root. codegraph refuses to use it as a cache root. Use a subdirectory instead, e.g. "${path35.join(resolution.anchor,
|
|
30194
|
+
throw new Error(`Cache anchor "${resolution.anchor}" (from ${CONFIGURED_ANCHOR_LAYER_LABELS[resolution.layer]}) is the home directory or a filesystem root. codegraph refuses to use it as a cache root. Use a subdirectory instead, e.g. "${path35.join(resolution.anchor, PROJECT_CACHE_DIRECTORY)}".`);
|
|
30195
|
+
}
|
|
30196
|
+
function migrateLegacyProjectCache(candidate, legacyCandidates, logLevel) {
|
|
30197
|
+
if (fs16.existsSync(candidate))
|
|
30198
|
+
return;
|
|
30199
|
+
const legacy = legacyCandidates.find(({ path: legacyPath }) => fs16.existsSync(legacyPath));
|
|
30200
|
+
if (!legacy)
|
|
30201
|
+
return;
|
|
30202
|
+
try {
|
|
30203
|
+
fs16.mkdirSync(path35.dirname(candidate), { recursive: true });
|
|
30204
|
+
fs16.renameSync(legacy.path, candidate);
|
|
30205
|
+
} catch (error51) {
|
|
30206
|
+
if (logLevel === "debug")
|
|
30207
|
+
console.debug(`Unable to migrate legacy cache from ${legacy.path}:`, error51);
|
|
30208
|
+
return;
|
|
30209
|
+
}
|
|
30210
|
+
let current = path35.dirname(legacy.path);
|
|
30211
|
+
for (; ; ) {
|
|
30212
|
+
try {
|
|
30213
|
+
fs16.rmdirSync(current);
|
|
30214
|
+
} catch {
|
|
30215
|
+
break;
|
|
30216
|
+
}
|
|
30217
|
+
if (fileIdentityKey(current) === fileIdentityKey(legacy.cleanupBoundary))
|
|
30218
|
+
break;
|
|
30219
|
+
current = path35.dirname(current);
|
|
30220
|
+
}
|
|
29878
30221
|
}
|
|
29879
30222
|
function resolveCacheLocation(projectRoot, opts) {
|
|
29880
30223
|
const root = path35.resolve(projectRoot);
|
|
@@ -29885,34 +30228,57 @@ function resolveCacheLocation(projectRoot, opts) {
|
|
|
29885
30228
|
const anchor = anchorWritable ? resolution.anchor : root;
|
|
29886
30229
|
const effectiveLayer = anchorWritable ? resolution.layer : "project";
|
|
29887
30230
|
const sameRoot2 = fileIdentityKey(anchor) === fileIdentityKey(root);
|
|
29888
|
-
|
|
29889
|
-
|
|
30231
|
+
const explicitBase = opts?.cacheDir?.trim() || process.env.CODEGRAPH_CACHE_DIR?.trim();
|
|
30232
|
+
if (sameRoot2 && !explicitBase && (!opts?.cacheLocation || opts.cacheLocation === "project")) {
|
|
30233
|
+
const candidate2 = path35.join(root, PROJECT_CACHE_RELATIVE_PATH);
|
|
30234
|
+
migrateLegacyProjectCache(candidate2, [
|
|
30235
|
+
{
|
|
30236
|
+
path: path35.join(root, LEGACY_PROJECT_CACHE_RELATIVE_PATH),
|
|
30237
|
+
cleanupBoundary: path35.join(root, ".codegraph-cache")
|
|
30238
|
+
}
|
|
30239
|
+
], opts?.logLevel);
|
|
30240
|
+
return { path: candidate2, anchor, layer: effectiveLayer };
|
|
29890
30241
|
}
|
|
29891
30242
|
const namespace = projectCacheNamespace(root, effectiveLayer === "git" || effectiveLayer === "manifest" ? anchor : void 0);
|
|
29892
|
-
const explicitBase = opts?.cacheDir?.trim() || process.env.CODEGRAPH_CACHE_DIR?.trim();
|
|
29893
30243
|
if (explicitBase) {
|
|
29894
30244
|
const configured = path35.resolve(explicitBase);
|
|
29895
30245
|
const configuredPath = path35.basename(configured) === namespace ? configured : path35.join(configured, namespace);
|
|
29896
30246
|
return { path: configuredPath, anchor, layer: effectiveLayer };
|
|
29897
30247
|
}
|
|
29898
|
-
|
|
29899
|
-
|
|
29900
|
-
|
|
29901
|
-
|
|
29902
|
-
|
|
29903
|
-
|
|
30248
|
+
if (opts?.cacheLocation === "user") {
|
|
30249
|
+
return {
|
|
30250
|
+
path: path35.join(resolveCodegraphUserCacheRoot2(), "index-v1", namespace),
|
|
30251
|
+
anchor,
|
|
30252
|
+
layer: effectiveLayer
|
|
30253
|
+
};
|
|
30254
|
+
}
|
|
30255
|
+
const candidate = path35.join(anchor, PROJECT_CACHE_RELATIVE_PATH, namespace);
|
|
30256
|
+
const legacyCandidates = [
|
|
30257
|
+
{
|
|
30258
|
+
path: path35.join(anchor, LEGACY_PROJECT_CACHE_RELATIVE_PATH, namespace),
|
|
30259
|
+
cleanupBoundary: path35.join(anchor, ".codegraph-cache")
|
|
29904
30260
|
}
|
|
30261
|
+
];
|
|
30262
|
+
if (!sameRoot2 && !opts?.cacheLocation) {
|
|
30263
|
+
legacyCandidates.push({
|
|
30264
|
+
path: path35.join(root, LEGACY_PROJECT_CACHE_RELATIVE_PATH),
|
|
30265
|
+
cleanupBoundary: path35.join(root, ".codegraph-cache")
|
|
30266
|
+
});
|
|
29905
30267
|
}
|
|
30268
|
+
migrateLegacyProjectCache(candidate, legacyCandidates, opts?.logLevel);
|
|
29906
30269
|
return { path: candidate, anchor, layer: effectiveLayer };
|
|
29907
30270
|
}
|
|
29908
30271
|
function cacheRoot(projectRoot, opts) {
|
|
29909
30272
|
return resolveCacheLocation(projectRoot, opts).path;
|
|
29910
30273
|
}
|
|
29911
|
-
var CONFIGURED_ANCHOR_LAYER_LABELS;
|
|
30274
|
+
var PROJECT_CACHE_DIRECTORY, PROJECT_CACHE_RELATIVE_PATH, LEGACY_PROJECT_CACHE_RELATIVE_PATH, CONFIGURED_ANCHOR_LAYER_LABELS;
|
|
29912
30275
|
var init_location = __esm({
|
|
29913
30276
|
"dist/indexer/build-cache/location.js"() {
|
|
29914
30277
|
"use strict";
|
|
29915
30278
|
init_paths();
|
|
30279
|
+
PROJECT_CACHE_DIRECTORY = ".codegraph";
|
|
30280
|
+
PROJECT_CACHE_RELATIVE_PATH = path35.join(PROJECT_CACHE_DIRECTORY, "cache", "index-v1");
|
|
30281
|
+
LEGACY_PROJECT_CACHE_RELATIVE_PATH = path35.join(".codegraph-cache", "index-v1");
|
|
29916
30282
|
CONFIGURED_ANCHOR_LAYER_LABELS = {
|
|
29917
30283
|
explicit: "--cache-dir (or an absolute cache.location)",
|
|
29918
30284
|
environment: "CODEGRAPH_CACHE_DIR",
|
|
@@ -30158,7 +30524,7 @@ var init_options2 = __esm({
|
|
|
30158
30524
|
import { brotliCompressSync, brotliDecompressSync, constants as zlibConstants } from "node:zlib";
|
|
30159
30525
|
import crypto6 from "node:crypto";
|
|
30160
30526
|
import fs17 from "node:fs";
|
|
30161
|
-
import
|
|
30527
|
+
import fsp18 from "node:fs/promises";
|
|
30162
30528
|
import path37 from "node:path";
|
|
30163
30529
|
function memoryCacheKey(projectRoot, file2) {
|
|
30164
30530
|
return `${normalizePath(projectRoot)}::${file2}`;
|
|
@@ -30310,14 +30676,14 @@ function pruneDiskModuleCache(projectRoot, liveFiles, opts) {
|
|
|
30310
30676
|
}
|
|
30311
30677
|
}
|
|
30312
30678
|
async function fileContentHash(file2) {
|
|
30313
|
-
const buffer = await
|
|
30679
|
+
const buffer = await fsp18.readFile(file2);
|
|
30314
30680
|
const hash2 = crypto6.createHash("sha1");
|
|
30315
30681
|
hash2.update(buffer);
|
|
30316
30682
|
return hash2.digest("hex");
|
|
30317
30683
|
}
|
|
30318
30684
|
async function fileStatSignature(file2, strict, opts) {
|
|
30319
30685
|
try {
|
|
30320
|
-
const stat = await
|
|
30686
|
+
const stat = await fsp18.stat(file2);
|
|
30321
30687
|
const useStrict = strict ?? true;
|
|
30322
30688
|
const shouldHash = useStrict || !!opts?.includeContentHash;
|
|
30323
30689
|
const contentHash = shouldHash ? await fileContentHash(file2) : void 0;
|
|
@@ -30375,7 +30741,7 @@ async function cacheSignatureForFile(file2, sigInfo, opts) {
|
|
|
30375
30741
|
}
|
|
30376
30742
|
async function buildBloomFilterForFile(file2, opts) {
|
|
30377
30743
|
try {
|
|
30378
|
-
const source = await
|
|
30744
|
+
const source = await fsp18.readFile(file2, "utf8");
|
|
30379
30745
|
const support = supportForFile(file2, opts?.languageExtensions);
|
|
30380
30746
|
if (!support)
|
|
30381
30747
|
return null;
|
|
@@ -31085,7 +31451,7 @@ __export(units_exports, {
|
|
|
31085
31451
|
shouldKeepUnit: () => shouldKeepUnit
|
|
31086
31452
|
});
|
|
31087
31453
|
import crypto7 from "node:crypto";
|
|
31088
|
-
import
|
|
31454
|
+
import fsp19 from "node:fs/promises";
|
|
31089
31455
|
import path39 from "node:path";
|
|
31090
31456
|
function lineSpan(unit) {
|
|
31091
31457
|
return Math.max(1, unit.endLine - unit.startLine + 1);
|
|
@@ -31474,7 +31840,7 @@ async function buildDuplicateUnitsForFile(index, file2, projectRoot, minTokens,
|
|
|
31474
31840
|
let source = index.parsed?.get(fileIdentityKey(file2))?.source;
|
|
31475
31841
|
if (source === void 0) {
|
|
31476
31842
|
try {
|
|
31477
|
-
source = await
|
|
31843
|
+
source = await fsp19.readFile(file2, "utf8");
|
|
31478
31844
|
} catch {
|
|
31479
31845
|
return [];
|
|
31480
31846
|
}
|
|
@@ -48363,8 +48729,8 @@ __export(config_exports, {
|
|
|
48363
48729
|
mergeDiscoveryOptions: () => mergeDiscoveryOptions,
|
|
48364
48730
|
mergeGraphOptions: () => mergeGraphOptions
|
|
48365
48731
|
});
|
|
48366
|
-
import
|
|
48367
|
-
import
|
|
48732
|
+
import fsp20 from "node:fs/promises";
|
|
48733
|
+
import os5 from "node:os";
|
|
48368
48734
|
import path40 from "node:path";
|
|
48369
48735
|
function uniq(values) {
|
|
48370
48736
|
return Array.from(new Set(values.map((value) => value.trim().replace(/\\/g, "/")).filter(Boolean)));
|
|
@@ -48434,10 +48800,10 @@ function normalizeConfigLanguageExtensions(extensions) {
|
|
|
48434
48800
|
return normalizeLanguageExtensions(extensions);
|
|
48435
48801
|
}
|
|
48436
48802
|
async function loadUserCacheLocation() {
|
|
48437
|
-
const configRoot = process.platform === "win32" ? process.env.APPDATA?.trim() || path40.join(
|
|
48803
|
+
const configRoot = process.platform === "win32" ? process.env.APPDATA?.trim() || path40.join(os5.homedir(), "AppData", "Roaming") : process.env.XDG_CONFIG_HOME?.trim() || path40.join(os5.homedir(), ".config");
|
|
48438
48804
|
const configPath = path40.join(configRoot, "codegraph", "config.json");
|
|
48439
48805
|
try {
|
|
48440
|
-
const parsedJson = JSON.parse(await
|
|
48806
|
+
const parsedJson = JSON.parse(await fsp20.readFile(configPath, "utf8"));
|
|
48441
48807
|
const parsed = codegraphConfigSchema.safeParse(parsedJson);
|
|
48442
48808
|
if (!parsed.success)
|
|
48443
48809
|
throw new Error(external_exports.prettifyError(parsed.error));
|
|
@@ -48453,7 +48819,7 @@ async function loadCodegraphConfig(projectRoot) {
|
|
|
48453
48819
|
const configPath = path40.join(projectRoot, CODEGRAPH_CONFIG_FILE);
|
|
48454
48820
|
let raw;
|
|
48455
48821
|
try {
|
|
48456
|
-
raw = await
|
|
48822
|
+
raw = await fsp20.readFile(configPath, "utf8");
|
|
48457
48823
|
} catch (error51) {
|
|
48458
48824
|
if (error51 instanceof Error && "code" in error51 && error51.code === "ENOENT") {
|
|
48459
48825
|
return userCacheLocation ? { cache: { location: userCacheLocation } } : {};
|
|
@@ -48519,7 +48885,7 @@ var init_config = __esm({
|
|
|
48519
48885
|
// dist/indexer/build-cache/manifest.js
|
|
48520
48886
|
import crypto8 from "node:crypto";
|
|
48521
48887
|
import fs19 from "node:fs";
|
|
48522
|
-
import
|
|
48888
|
+
import fsp21, {} from "node:fs/promises";
|
|
48523
48889
|
import path41 from "node:path";
|
|
48524
48890
|
async function collectWorkspaceManifestDependencyEdges(projectRoot, manifestFiles, discovery, logLevel) {
|
|
48525
48891
|
const manifestPaths = manifestFiles ?? await listProjectFiles(projectRoot, ["**/package.json"], {
|
|
@@ -48532,7 +48898,7 @@ async function collectWorkspaceManifestDependencyEdges(projectRoot, manifestFile
|
|
|
48532
48898
|
const parsedByPath = /* @__PURE__ */ new Map();
|
|
48533
48899
|
for (const manifestPath of manifestPaths) {
|
|
48534
48900
|
try {
|
|
48535
|
-
const raw = await
|
|
48901
|
+
const raw = await fsp21.readFile(manifestPath, "utf8");
|
|
48536
48902
|
const parsed = JSON.parse(raw);
|
|
48537
48903
|
parsedByPath.set(manifestPath, parsed);
|
|
48538
48904
|
if (typeof parsed.name === "string" && parsed.name.trim()) {
|
|
@@ -48605,7 +48971,7 @@ function normalizeIndexedFileInputs(projectRoot, files, label, realProjectRoot)
|
|
|
48605
48971
|
return [...filesByIdentity.values()];
|
|
48606
48972
|
}
|
|
48607
48973
|
async function normalizeIndexedFileInputsWithinRoot(projectRoot, files, label) {
|
|
48608
|
-
const realRoot = await
|
|
48974
|
+
const realRoot = await fsp21.realpath(projectRoot);
|
|
48609
48975
|
const normalized = normalizeIndexedFileInputs(projectRoot, files, label, realRoot);
|
|
48610
48976
|
await Promise.all(normalized.map(async (file2) => {
|
|
48611
48977
|
try {
|
|
@@ -48673,7 +49039,7 @@ async function computeConfigHash(projectRoot, logLevel) {
|
|
|
48673
49039
|
let firstError;
|
|
48674
49040
|
for (const file2 of configFiles) {
|
|
48675
49041
|
try {
|
|
48676
|
-
const content = await
|
|
49042
|
+
const content = await fsp21.readFile(file2, "utf8");
|
|
48677
49043
|
const relative = path41.relative(projectRoot, file2).replace(/\\/g, "/");
|
|
48678
49044
|
hash2.update(relative);
|
|
48679
49045
|
hash2.update(content);
|
|
@@ -48719,7 +49085,7 @@ function isManifestTempName(name, manifestName) {
|
|
|
48719
49085
|
async function cleanupStaleManifestTemps(manifestPath) {
|
|
48720
49086
|
let entries;
|
|
48721
49087
|
try {
|
|
48722
|
-
entries = await
|
|
49088
|
+
entries = await fsp21.readdir(path41.dirname(manifestPath), { withFileTypes: true });
|
|
48723
49089
|
} catch {
|
|
48724
49090
|
return;
|
|
48725
49091
|
}
|
|
@@ -48730,15 +49096,15 @@ async function cleanupStaleManifestTemps(manifestPath) {
|
|
|
48730
49096
|
continue;
|
|
48731
49097
|
const candidate = path41.join(path41.dirname(manifestPath), entry.name);
|
|
48732
49098
|
try {
|
|
48733
|
-
const stat = await
|
|
49099
|
+
const stat = await fsp21.lstat(candidate);
|
|
48734
49100
|
if (stat.mtimeMs <= cutoff)
|
|
48735
|
-
await
|
|
49101
|
+
await fsp21.rm(candidate, { force: true });
|
|
48736
49102
|
} catch {
|
|
48737
49103
|
}
|
|
48738
49104
|
}
|
|
48739
49105
|
}
|
|
48740
49106
|
async function fsyncManifestFile(filePath) {
|
|
48741
|
-
const handle = await
|
|
49107
|
+
const handle = await fsp21.open(filePath, "r+");
|
|
48742
49108
|
try {
|
|
48743
49109
|
await handle.sync();
|
|
48744
49110
|
} finally {
|
|
@@ -48748,7 +49114,7 @@ async function fsyncManifestFile(filePath) {
|
|
|
48748
49114
|
async function syncManifestDirectory(directoryPath) {
|
|
48749
49115
|
let directory;
|
|
48750
49116
|
try {
|
|
48751
|
-
directory = await
|
|
49117
|
+
directory = await fsp21.open(directoryPath, "r");
|
|
48752
49118
|
await directory.sync();
|
|
48753
49119
|
} catch {
|
|
48754
49120
|
} finally {
|
|
@@ -48771,14 +49137,14 @@ async function writeManifestAtomically(manifestPath, payload) {
|
|
|
48771
49137
|
for (let attempt = 0; attempt <= retryDelays.length; attempt += 1) {
|
|
48772
49138
|
const tempPath = manifestTempFilePath(manifestPath);
|
|
48773
49139
|
try {
|
|
48774
|
-
await
|
|
49140
|
+
await fsp21.writeFile(tempPath, payload, "utf8");
|
|
48775
49141
|
await fsyncManifestFile(tempPath);
|
|
48776
|
-
await
|
|
49142
|
+
await fsp21.rename(tempPath, manifestPath);
|
|
48777
49143
|
await syncManifestDirectory(path41.dirname(manifestPath));
|
|
48778
49144
|
return;
|
|
48779
49145
|
} catch (error51) {
|
|
48780
49146
|
try {
|
|
48781
|
-
await
|
|
49147
|
+
await fsp21.rm(tempPath, { force: true });
|
|
48782
49148
|
} catch {
|
|
48783
49149
|
}
|
|
48784
49150
|
const canRetry = attempt < retryDelays.length && isTransientFileContentionError(error51);
|
|
@@ -48801,7 +49167,7 @@ function recordManifestCorruption(report, artifact, reason, logLevel) {
|
|
|
48801
49167
|
async function loadManifest(projectRoot, opts, report) {
|
|
48802
49168
|
const manifestPath = manifestFilePath(projectRoot, opts);
|
|
48803
49169
|
try {
|
|
48804
|
-
const raw = await
|
|
49170
|
+
const raw = await fsp21.readFile(manifestPath, "utf8");
|
|
48805
49171
|
const parsed = JSON.parse(raw);
|
|
48806
49172
|
let invalidReason;
|
|
48807
49173
|
if (parsed.version !== MANIFEST_VERSION && parsed.version !== 4 && parsed.version !== 3) {
|
|
@@ -48837,7 +49203,7 @@ async function loadManifest(projectRoot, opts, report) {
|
|
|
48837
49203
|
async function writeManifest2(projectRoot, opts, manifest) {
|
|
48838
49204
|
try {
|
|
48839
49205
|
const manifestPath = manifestFilePath(projectRoot, opts);
|
|
48840
|
-
await
|
|
49206
|
+
await fsp21.mkdir(path41.dirname(manifestPath), { recursive: true });
|
|
48841
49207
|
await writeManifestAtomically(manifestPath, JSON.stringify(manifest, null, 2));
|
|
48842
49208
|
return true;
|
|
48843
49209
|
} catch (error51) {
|
|
@@ -49612,7 +49978,7 @@ var init_symbol_graph = __esm({
|
|
|
49612
49978
|
});
|
|
49613
49979
|
|
|
49614
49980
|
// dist/indexer/build-cache/project-snapshot.js
|
|
49615
|
-
import
|
|
49981
|
+
import fsp22 from "node:fs/promises";
|
|
49616
49982
|
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
49617
49983
|
import { brotliCompressSync as brotliCompressSync3, brotliDecompressSync as brotliDecompressSync3, constants as zlibConstants3 } from "node:zlib";
|
|
49618
49984
|
import path43 from "node:path";
|
|
@@ -49763,7 +50129,7 @@ function sameSnapshotFileIdentity(left, right) {
|
|
|
49763
50129
|
return left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
|
|
49764
50130
|
}
|
|
49765
50131
|
async function snapshotFileIdentity(snapshotPath) {
|
|
49766
|
-
const stat = await
|
|
50132
|
+
const stat = await fsp22.stat(snapshotPath);
|
|
49767
50133
|
return {
|
|
49768
50134
|
size: stat.size,
|
|
49769
50135
|
mtimeMs: stat.mtimeMs,
|
|
@@ -49771,7 +50137,7 @@ async function snapshotFileIdentity(snapshotPath) {
|
|
|
49771
50137
|
};
|
|
49772
50138
|
}
|
|
49773
50139
|
async function fsyncSnapshotFile(snapshotPath) {
|
|
49774
|
-
const handle = await
|
|
50140
|
+
const handle = await fsp22.open(snapshotPath, "r+");
|
|
49775
50141
|
try {
|
|
49776
50142
|
await handle.sync();
|
|
49777
50143
|
} finally {
|
|
@@ -49788,7 +50154,7 @@ function isSnapshotTempName(name, snapshotName) {
|
|
|
49788
50154
|
async function cleanupStaleSnapshotTemps(snapshotPath) {
|
|
49789
50155
|
let entries;
|
|
49790
50156
|
try {
|
|
49791
|
-
entries = await
|
|
50157
|
+
entries = await fsp22.readdir(path43.dirname(snapshotPath), { withFileTypes: true });
|
|
49792
50158
|
} catch {
|
|
49793
50159
|
return;
|
|
49794
50160
|
}
|
|
@@ -49799,26 +50165,26 @@ async function cleanupStaleSnapshotTemps(snapshotPath) {
|
|
|
49799
50165
|
continue;
|
|
49800
50166
|
const candidate = path43.join(path43.dirname(snapshotPath), entry.name);
|
|
49801
50167
|
try {
|
|
49802
|
-
const stat = await
|
|
50168
|
+
const stat = await fsp22.lstat(candidate);
|
|
49803
50169
|
if (stat.mtimeMs > cutoff)
|
|
49804
50170
|
continue;
|
|
49805
|
-
await
|
|
50171
|
+
await fsp22.rm(candidate, { force: true });
|
|
49806
50172
|
} catch {
|
|
49807
50173
|
}
|
|
49808
50174
|
}
|
|
49809
50175
|
}
|
|
49810
50176
|
async function writeSnapshotAtomically(snapshotPath, data) {
|
|
49811
|
-
await
|
|
50177
|
+
await fsp22.mkdir(path43.dirname(snapshotPath), { recursive: true });
|
|
49812
50178
|
await cleanupStaleSnapshotTemps(snapshotPath);
|
|
49813
50179
|
let tempPath = path43.join(path43.dirname(snapshotPath), `.${path43.basename(snapshotPath)}.${process.pid}.${randomUUID()}${SNAPSHOT_TEMP_SUFFIX}`);
|
|
49814
50180
|
try {
|
|
49815
|
-
await
|
|
50181
|
+
await fsp22.writeFile(tempPath, data, { flag: "wx" });
|
|
49816
50182
|
await fsyncSnapshotFile(tempPath);
|
|
49817
|
-
await
|
|
50183
|
+
await fsp22.rename(tempPath, snapshotPath);
|
|
49818
50184
|
tempPath = void 0;
|
|
49819
50185
|
} finally {
|
|
49820
50186
|
if (tempPath) {
|
|
49821
|
-
await
|
|
50187
|
+
await fsp22.rm(tempPath, { force: true }).catch(() => void 0);
|
|
49822
50188
|
}
|
|
49823
50189
|
}
|
|
49824
50190
|
}
|
|
@@ -49873,7 +50239,7 @@ async function readParsedSnapshot(snapshotPath) {
|
|
|
49873
50239
|
setBoundedSnapshotCache(parsedSnapshotCache, snapshotPath, cached2);
|
|
49874
50240
|
return { identity: cached2.identity, payload: cached2.payload };
|
|
49875
50241
|
}
|
|
49876
|
-
const compressed = Buffer.from(await
|
|
50242
|
+
const compressed = Buffer.from(await fsp22.readFile(snapshotPath));
|
|
49877
50243
|
const payload = decodeSnapshotPayload(compressed);
|
|
49878
50244
|
const after = await snapshotFileIdentity(snapshotPath);
|
|
49879
50245
|
const entry = { identity: before, compressed, payload };
|
|
@@ -50393,11 +50759,11 @@ function sameSymbolEdgeMultiset(expected, actual) {
|
|
|
50393
50759
|
return false;
|
|
50394
50760
|
const counts = /* @__PURE__ */ new Map();
|
|
50395
50761
|
for (const edge of expected) {
|
|
50396
|
-
const key =
|
|
50762
|
+
const key = symbolEdgeKey(edge);
|
|
50397
50763
|
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
50398
50764
|
}
|
|
50399
50765
|
for (const edge of actual) {
|
|
50400
|
-
const key =
|
|
50766
|
+
const key = symbolEdgeKey(edge);
|
|
50401
50767
|
const remaining = counts.get(key);
|
|
50402
50768
|
if (remaining === void 0)
|
|
50403
50769
|
return false;
|
|
@@ -50408,27 +50774,30 @@ function sameSymbolEdgeMultiset(expected, actual) {
|
|
|
50408
50774
|
}
|
|
50409
50775
|
return !counts.size;
|
|
50410
50776
|
}
|
|
50411
|
-
function
|
|
50412
|
-
|
|
50413
|
-
|
|
50414
|
-
|
|
50415
|
-
|
|
50416
|
-
|
|
50417
|
-
|
|
50418
|
-
|
|
50419
|
-
|
|
50420
|
-
|
|
50421
|
-
|
|
50422
|
-
|
|
50423
|
-
|
|
50424
|
-
|
|
50425
|
-
|
|
50426
|
-
|
|
50427
|
-
|
|
50428
|
-
|
|
50429
|
-
|
|
50430
|
-
}
|
|
50431
|
-
|
|
50777
|
+
function symbolEdgeKey(edge) {
|
|
50778
|
+
const from = lengthPrefixedSymbolEdgeField(edge.from);
|
|
50779
|
+
const to = lengthPrefixedSymbolEdgeField(edge.to);
|
|
50780
|
+
const label = edge.label === void 0 ? "u" : `s${lengthPrefixedSymbolEdgeField(edge.label)}`;
|
|
50781
|
+
if (!edge.site)
|
|
50782
|
+
return `f${from}t${to}l${label}s`;
|
|
50783
|
+
const { file: file2, range } = edge.site;
|
|
50784
|
+
const startIndex = range.start.index === void 0 ? "u" : `n${range.start.index}`;
|
|
50785
|
+
const endIndex = range.end.index === void 0 ? "u" : `n${range.end.index}`;
|
|
50786
|
+
return [
|
|
50787
|
+
`f${from}`,
|
|
50788
|
+
`t${to}`,
|
|
50789
|
+
`l${label}`,
|
|
50790
|
+
`s${lengthPrefixedSymbolEdgeField(file2)}`,
|
|
50791
|
+
`sl${range.start.line}`,
|
|
50792
|
+
`sc${range.start.column}`,
|
|
50793
|
+
`si${startIndex}`,
|
|
50794
|
+
`el${range.end.line}`,
|
|
50795
|
+
`ec${range.end.column}`,
|
|
50796
|
+
`ei${endIndex}`
|
|
50797
|
+
].join("");
|
|
50798
|
+
}
|
|
50799
|
+
function lengthPrefixedSymbolEdgeField(value) {
|
|
50800
|
+
return `${value.length}:${value}`;
|
|
50432
50801
|
}
|
|
50433
50802
|
function normalizedSnapshotNativeMode(nativeMode) {
|
|
50434
50803
|
if (nativeMode === void 0 || nativeMode === "auto")
|
|
@@ -50735,21 +51104,21 @@ var init_build_cache = __esm({
|
|
|
50735
51104
|
|
|
50736
51105
|
// dist/indexer/build-cache/resolver-environment.js
|
|
50737
51106
|
import crypto9 from "node:crypto";
|
|
50738
|
-
import
|
|
51107
|
+
import fsp23 from "node:fs/promises";
|
|
50739
51108
|
import path44 from "node:path";
|
|
50740
51109
|
function normalizedRelativePath(projectRoot, target) {
|
|
50741
51110
|
return path44.relative(projectRoot, target).replace(/\\/g, "/");
|
|
50742
51111
|
}
|
|
50743
51112
|
async function statInput(projectRoot, target) {
|
|
50744
51113
|
try {
|
|
50745
|
-
const stat = await
|
|
51114
|
+
const stat = await fsp23.stat(target);
|
|
50746
51115
|
if (!stat.isFile())
|
|
50747
51116
|
return null;
|
|
50748
51117
|
const sampleBytes = Math.min(stat.size, RESOLUTION_INPUT_SAMPLE_BYTES);
|
|
50749
51118
|
const hash2 = crypto9.createHash("sha256");
|
|
50750
51119
|
if (sampleBytes) {
|
|
50751
51120
|
const first = Buffer.allocUnsafe(sampleBytes);
|
|
50752
|
-
const handle = await
|
|
51121
|
+
const handle = await fsp23.open(target, "r");
|
|
50753
51122
|
try {
|
|
50754
51123
|
const firstRead = await handle.read(first, 0, sampleBytes, 0);
|
|
50755
51124
|
hash2.update(first.subarray(0, firstRead.bytesRead));
|
|
@@ -50797,7 +51166,7 @@ async function activeNodeModulesRoots(projectRoot, files) {
|
|
|
50797
51166
|
return null;
|
|
50798
51167
|
const roots = await Promise.all(candidates.map(async (candidate) => {
|
|
50799
51168
|
try {
|
|
50800
|
-
return (await
|
|
51169
|
+
return (await fsp23.stat(candidate)).isDirectory() ? candidate : null;
|
|
50801
51170
|
} catch {
|
|
50802
51171
|
return null;
|
|
50803
51172
|
}
|
|
@@ -50807,7 +51176,7 @@ async function activeNodeModulesRoots(projectRoot, files) {
|
|
|
50807
51176
|
async function installedPackageManifests(projectRoot, root) {
|
|
50808
51177
|
let entries;
|
|
50809
51178
|
try {
|
|
50810
|
-
entries = await
|
|
51179
|
+
entries = await fsp23.readdir(root, { withFileTypes: true });
|
|
50811
51180
|
} catch {
|
|
50812
51181
|
return [];
|
|
50813
51182
|
}
|
|
@@ -50818,7 +51187,7 @@ async function installedPackageManifests(projectRoot, root) {
|
|
|
50818
51187
|
const entryPath = path44.join(root, entry.name);
|
|
50819
51188
|
if (entry.name.startsWith("@")) {
|
|
50820
51189
|
try {
|
|
50821
|
-
const scopedEntries = await
|
|
51190
|
+
const scopedEntries = await fsp23.readdir(entryPath, { withFileTypes: true });
|
|
50822
51191
|
for (const scopedEntry of scopedEntries) {
|
|
50823
51192
|
if (scopedEntry.isDirectory())
|
|
50824
51193
|
packageDirectories.push(path44.join(entryPath, scopedEntry.name));
|
|
@@ -50969,7 +51338,7 @@ var init_finalize = __esm({
|
|
|
50969
51338
|
});
|
|
50970
51339
|
|
|
50971
51340
|
// dist/indexer/build-manifest.js
|
|
50972
|
-
import
|
|
51341
|
+
import fsp24 from "node:fs/promises";
|
|
50973
51342
|
import path45 from "node:path";
|
|
50974
51343
|
import { performance as performance3 } from "node:perf_hooks";
|
|
50975
51344
|
function toManifestFileEntry(entry) {
|
|
@@ -50989,7 +51358,7 @@ async function writeIndexManifestSnapshot(args) {
|
|
|
50989
51358
|
const writeManifestStart = performance3.now();
|
|
50990
51359
|
const lastCommit = await getGitHead(args.projectRoot);
|
|
50991
51360
|
const configHashResult = await computeConfigHash(args.projectRoot, args.opts?.logLevel);
|
|
50992
|
-
const projectRootMtimeMs = args.symlinkDirectories !== void 0 ? (await
|
|
51361
|
+
const projectRootMtimeMs = args.symlinkDirectories !== void 0 ? (await fsp24.stat(args.projectRoot)).mtimeMs : void 0;
|
|
50993
51362
|
const configHash = recordConfigHashResult(args.manifestReport, configHashResult, args.opts?.logLevel);
|
|
50994
51363
|
const manifestData = {
|
|
50995
51364
|
version: MANIFEST_VERSION,
|
|
@@ -52617,10 +52986,10 @@ var init_build_workers = __esm({
|
|
|
52617
52986
|
|
|
52618
52987
|
// dist/indexer/incremental-plan.js
|
|
52619
52988
|
import fs22 from "node:fs";
|
|
52620
|
-
import
|
|
52989
|
+
import fsp25 from "node:fs/promises";
|
|
52621
52990
|
async function pathExists2(filePath) {
|
|
52622
52991
|
try {
|
|
52623
|
-
await
|
|
52992
|
+
await fsp25.access(filePath);
|
|
52624
52993
|
return true;
|
|
52625
52994
|
} catch {
|
|
52626
52995
|
return false;
|
|
@@ -52797,7 +53166,7 @@ __export(build_index_exports, {
|
|
|
52797
53166
|
});
|
|
52798
53167
|
import crypto10 from "node:crypto";
|
|
52799
53168
|
import fs23 from "node:fs";
|
|
52800
|
-
import
|
|
53169
|
+
import fsp26 from "node:fs/promises";
|
|
52801
53170
|
import path47 from "node:path";
|
|
52802
53171
|
import { performance as performance5 } from "node:perf_hooks";
|
|
52803
53172
|
function initParserBackendDegradationReport(report) {
|
|
@@ -53151,7 +53520,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
|
|
|
53151
53520
|
const shouldWriteManifest = manifestMode === "read-write";
|
|
53152
53521
|
const projectFiles = helperOpts?.projectFiles;
|
|
53153
53522
|
initManifestReport(report, useManifest, false);
|
|
53154
|
-
const confinedRoot = helperOpts?.confineReads ? await
|
|
53523
|
+
const confinedRoot = helperOpts?.confineReads ? await fsp26.realpath(projectRoot) : void 0;
|
|
53155
53524
|
const [trustedSources, normalizedFiles] = [
|
|
53156
53525
|
confinedRoot ? /* @__PURE__ */ new Map() : void 0,
|
|
53157
53526
|
Array.from(new Set(normalizeIndexedFileInputs(projectRoot, rawFiles ?? [], "Index file")))
|
|
@@ -53529,7 +53898,7 @@ async function buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpt
|
|
|
53529
53898
|
const useDiskCache = (opts?.cache ?? "off") === "disk";
|
|
53530
53899
|
const wantsMaxSymlinkCorrectness = !!opts?.cacheStrict || !!opts?.cacheVerify;
|
|
53531
53900
|
const symlinkHintManifest = helperOpts?.ignoreExistingManifest || wantsMaxSymlinkCorrectness || !useDiskCache ? null : await loadManifest(projectRoot, opts);
|
|
53532
|
-
const rootMtime = symlinkHintManifest ? (await
|
|
53901
|
+
const rootMtime = symlinkHintManifest ? (await fsp26.stat(projectRoot)).mtimeMs : void 0;
|
|
53533
53902
|
const symlinkHintIsFresh = symlinkHintManifest?.symlinkDirectoriesRootMtimeMs !== void 0 && rootMtime === symlinkHintManifest.symlinkDirectoriesRootMtimeMs;
|
|
53534
53903
|
const knownSymlinkDirectories = symlinkHintIsFresh ? symlinkHintManifest?.symlinkDirectories : void 0;
|
|
53535
53904
|
let discoveredSymlinkDirectories = knownSymlinkDirectories;
|
|
@@ -53886,7 +54255,7 @@ async function buildProjectIndexIncremental(projectRoot, opts) {
|
|
|
53886
54255
|
if (!entry?.sig)
|
|
53887
54256
|
return true;
|
|
53888
54257
|
try {
|
|
53889
|
-
const stat = await
|
|
54258
|
+
const stat = await fsp26.stat(file2);
|
|
53890
54259
|
const prefix = `${stat.mtimeMs}:${stat.size}`;
|
|
53891
54260
|
return !(entry.sig === prefix || entry.sig.startsWith(`${prefix}:`));
|
|
53892
54261
|
} catch {
|
|
@@ -55467,6 +55836,17 @@ function toolFollowUp(tool, arguments_ = {}, label) {
|
|
|
55467
55836
|
...label !== void 0 ? { label } : {}
|
|
55468
55837
|
};
|
|
55469
55838
|
}
|
|
55839
|
+
function dedupeAgentFollowUps(followUps) {
|
|
55840
|
+
const seen = /* @__PURE__ */ new Set();
|
|
55841
|
+
return followUps.filter((followUp) => {
|
|
55842
|
+
const serializedArguments = JSON.stringify(followUp.arguments);
|
|
55843
|
+
const key = `${followUp.tool.length}|${followUp.tool}${serializedArguments}`;
|
|
55844
|
+
if (seen.has(key))
|
|
55845
|
+
return false;
|
|
55846
|
+
seen.add(key);
|
|
55847
|
+
return true;
|
|
55848
|
+
});
|
|
55849
|
+
}
|
|
55470
55850
|
function formatAgentFollowUpAsCli(followUp) {
|
|
55471
55851
|
const args = followUp.arguments;
|
|
55472
55852
|
switch (followUp.tool) {
|
|
@@ -55693,7 +56073,7 @@ var init_sessionLifecycle = __esm({
|
|
|
55693
56073
|
});
|
|
55694
56074
|
|
|
55695
56075
|
// dist/agent/session.js
|
|
55696
|
-
import
|
|
56076
|
+
import fsp27 from "node:fs/promises";
|
|
55697
56077
|
import path49 from "node:path";
|
|
55698
56078
|
function assertNoPrebuiltSessionWithBuildOptions(options, consumer) {
|
|
55699
56079
|
if (options.session && options.buildOptions) {
|
|
@@ -55772,7 +56152,7 @@ async function collectAgentFileSignatures(files) {
|
|
|
55772
56152
|
await mapLimit([...files], FILE_SIGNATURE_STAT_CONCURRENCY, async (file2) => {
|
|
55773
56153
|
const resolvedFile = normalizePath(path49.resolve(file2));
|
|
55774
56154
|
try {
|
|
55775
|
-
const stat = await
|
|
56155
|
+
const stat = await fsp27.stat(resolvedFile);
|
|
55776
56156
|
if (!stat.isFile())
|
|
55777
56157
|
return;
|
|
55778
56158
|
signatures.set(resolvedFile, {
|
|
@@ -56133,13 +56513,13 @@ var init_errors4 = __esm({
|
|
|
56133
56513
|
});
|
|
56134
56514
|
|
|
56135
56515
|
// dist/lifecycle/gitignore.js
|
|
56136
|
-
import
|
|
56516
|
+
import fsp28 from "node:fs/promises";
|
|
56137
56517
|
import path50 from "node:path";
|
|
56138
56518
|
async function readGitignoreFile(gitignorePath) {
|
|
56139
56519
|
let existing = "";
|
|
56140
56520
|
let stats;
|
|
56141
56521
|
try {
|
|
56142
|
-
stats = await
|
|
56522
|
+
stats = await fsp28.lstat(gitignorePath);
|
|
56143
56523
|
} catch (error51) {
|
|
56144
56524
|
if (!(error51 instanceof Error && "code" in error51 && error51.code === "ENOENT")) {
|
|
56145
56525
|
const detail = errorMessage(error51);
|
|
@@ -56156,7 +56536,7 @@ async function readGitignoreFile(gitignorePath) {
|
|
|
56156
56536
|
throw new CodegraphLifecycleUserError(`Cannot update ${gitignorePath}: expected a regular file, but found a ${kind}. Replace it with a regular file or rerun with --no-update-gitignore.`);
|
|
56157
56537
|
}
|
|
56158
56538
|
try {
|
|
56159
|
-
existing = await
|
|
56539
|
+
existing = await fsp28.readFile(gitignorePath, "utf8");
|
|
56160
56540
|
} catch (error51) {
|
|
56161
56541
|
const detail = errorMessage(error51);
|
|
56162
56542
|
throw new CodegraphLifecycleUserError(`Unable to read ${gitignorePath}: ${detail}. Check file permissions or rerun with --no-update-gitignore.`);
|
|
@@ -56178,43 +56558,38 @@ async function prepareCodegraphLifecycleGitignore(root, options = {}) {
|
|
|
56178
56558
|
const manifestTracked = await isGitPathTracked(resolvedRoot, LIFECYCLE_MANIFEST_PATH);
|
|
56179
56559
|
if (manifestTracked)
|
|
56180
56560
|
return { status: "tracked", path: GITIGNORE_PATH };
|
|
56181
|
-
const
|
|
56182
|
-
|
|
56183
|
-
|
|
56184
|
-
]);
|
|
56185
|
-
const missingRules = [
|
|
56186
|
-
...!lifecycleIgnored ? [LIFECYCLE_GITIGNORE_RULE] : [],
|
|
56187
|
-
...!diskCacheIgnored ? [DISK_CACHE_GITIGNORE_RULE] : []
|
|
56188
|
-
];
|
|
56189
|
-
if (!missingRules.length) {
|
|
56561
|
+
const manifestIgnored = await isGitPathIgnored(resolvedRoot, LIFECYCLE_MANIFEST_PATH);
|
|
56562
|
+
const cacheIgnored = await isGitPathIgnored(resolvedRoot, LIFECYCLE_CACHE_PATH);
|
|
56563
|
+
if (manifestIgnored && cacheIgnored) {
|
|
56190
56564
|
return { status: "already-ignored", path: GITIGNORE_PATH, rules: [...CODEGRAPH_GITIGNORE_RULES] };
|
|
56191
56565
|
}
|
|
56566
|
+
const missingRules = [LIFECYCLE_GITIGNORE_RULE];
|
|
56192
56567
|
const gitignorePath = path50.join(resolvedRoot, GITIGNORE_PATH);
|
|
56193
56568
|
const { existing, newline } = await readGitignoreFile(gitignorePath);
|
|
56194
56569
|
let suffix = missingRules.map((rule) => `${rule}${newline}`).join("");
|
|
56195
56570
|
if (existing && !existing.endsWith("\n"))
|
|
56196
56571
|
suffix = `${newline}${suffix}`;
|
|
56197
56572
|
try {
|
|
56198
|
-
await
|
|
56573
|
+
await fsp28.appendFile(gitignorePath, suffix, "utf8");
|
|
56199
56574
|
} catch (error51) {
|
|
56200
56575
|
const detail = errorMessage(error51);
|
|
56201
56576
|
throw new CodegraphLifecycleUserError(`Unable to update ${gitignorePath}: ${detail}. Check file permissions or rerun with --no-update-gitignore.`);
|
|
56202
56577
|
}
|
|
56203
56578
|
return { status: "added", path: GITIGNORE_PATH, rules: missingRules };
|
|
56204
56579
|
}
|
|
56205
|
-
var LIFECYCLE_MANIFEST_PATH,
|
|
56580
|
+
var LIFECYCLE_MANIFEST_PATH, LIFECYCLE_CACHE_PATH, GITIGNORE_PATH, LIFECYCLE_GITIGNORE_RULE, CODEGRAPH_GITIGNORE_RULES;
|
|
56206
56581
|
var init_gitignore = __esm({
|
|
56207
56582
|
"dist/lifecycle/gitignore.js"() {
|
|
56208
56583
|
"use strict";
|
|
56584
|
+
init_location();
|
|
56209
56585
|
init_git();
|
|
56210
56586
|
init_errors();
|
|
56211
56587
|
init_errors4();
|
|
56212
56588
|
LIFECYCLE_MANIFEST_PATH = ".codegraph/manifest.json";
|
|
56213
|
-
|
|
56589
|
+
LIFECYCLE_CACHE_PATH = PROJECT_CACHE_RELATIVE_PATH.replaceAll(path50.sep, "/");
|
|
56214
56590
|
GITIGNORE_PATH = ".gitignore";
|
|
56215
56591
|
LIFECYCLE_GITIGNORE_RULE = ".codegraph/";
|
|
56216
|
-
|
|
56217
|
-
CODEGRAPH_GITIGNORE_RULES = [LIFECYCLE_GITIGNORE_RULE, DISK_CACHE_GITIGNORE_RULE];
|
|
56592
|
+
CODEGRAPH_GITIGNORE_RULES = [LIFECYCLE_GITIGNORE_RULE];
|
|
56218
56593
|
}
|
|
56219
56594
|
});
|
|
56220
56595
|
|
|
@@ -56230,7 +56605,7 @@ __export(manifest_exports, {
|
|
|
56230
56605
|
uninitCodegraphLifecycle: () => uninitCodegraphLifecycle
|
|
56231
56606
|
});
|
|
56232
56607
|
import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
|
|
56233
|
-
import
|
|
56608
|
+
import fsp29 from "node:fs/promises";
|
|
56234
56609
|
import path51 from "node:path";
|
|
56235
56610
|
function codegraphLifecycleManifestPath(root) {
|
|
56236
56611
|
return path51.join(root, CODEGRAPH_DIR, MANIFEST_FILE);
|
|
@@ -56331,11 +56706,11 @@ async function uninitCodegraphLifecycle(root, options = {}) {
|
|
|
56331
56706
|
if (!entries.length) {
|
|
56332
56707
|
return { schemaVersion: MANIFEST_SCHEMA_VERSION, root, removed: false, manifestPath };
|
|
56333
56708
|
}
|
|
56334
|
-
const unknownEntries = entries.filter((entry) => !
|
|
56709
|
+
const unknownEntries = entries.filter((entry) => !Object.hasOwn(KNOWN_CODEGRAPH_FILES, entry));
|
|
56335
56710
|
if (unknownEntries.length && !options.force) {
|
|
56336
56711
|
throw new CodegraphLifecycleUserError(`Refusing to remove .codegraph with unknown entries: ${unknownEntries.join(", ")}. Use --force to remove them.`);
|
|
56337
56712
|
}
|
|
56338
|
-
const removableEntries = entries.filter((entry) => entry !== SERVER_REGISTRY_FILE && entry !== SERVER_LOG_FILE);
|
|
56713
|
+
const removableEntries = entries.filter((entry) => entry !== SERVER_REGISTRY_FILE && entry !== SERVER_LOG_FILE && entry !== CACHE_DIRECTORY);
|
|
56339
56714
|
if (options.force) {
|
|
56340
56715
|
for (const entry of removableEntries) {
|
|
56341
56716
|
await removeCodegraphPath(path51.join(dir, entry), { recursive: true });
|
|
@@ -56375,7 +56750,7 @@ async function readLifecycleManifest(root, options = {}) {
|
|
|
56375
56750
|
const manifestPath = codegraphLifecycleManifestPath(root);
|
|
56376
56751
|
let raw;
|
|
56377
56752
|
try {
|
|
56378
|
-
raw = await
|
|
56753
|
+
raw = await fsp29.readFile(manifestPath, "utf8");
|
|
56379
56754
|
} catch (error51) {
|
|
56380
56755
|
if (error51 instanceof Error && "code" in error51 && error51.code === "ENOENT")
|
|
56381
56756
|
return null;
|
|
@@ -56399,14 +56774,14 @@ function lifecycleManifestTempFilePath(manifestPath) {
|
|
|
56399
56774
|
}
|
|
56400
56775
|
async function writeLifecycleManifest(root, manifest) {
|
|
56401
56776
|
const manifestPath = codegraphLifecycleManifestPath(root);
|
|
56402
|
-
await
|
|
56777
|
+
await fsp29.mkdir(path51.dirname(manifestPath), { recursive: true });
|
|
56403
56778
|
const tempPath = lifecycleManifestTempFilePath(manifestPath);
|
|
56404
56779
|
try {
|
|
56405
|
-
await
|
|
56780
|
+
await fsp29.writeFile(tempPath, `${JSON.stringify(manifest, null, 2)}
|
|
56406
56781
|
`, "utf8");
|
|
56407
|
-
await
|
|
56782
|
+
await fsp29.rename(tempPath, manifestPath);
|
|
56408
56783
|
} catch (error51) {
|
|
56409
|
-
await
|
|
56784
|
+
await fsp29.rm(tempPath, { force: true }).catch(() => {
|
|
56410
56785
|
});
|
|
56411
56786
|
throw new CodegraphLifecycleUserError(`Unable to write Codegraph lifecycle manifest at ${manifestPath}: ${stringifyError(error51)}`);
|
|
56412
56787
|
}
|
|
@@ -56447,7 +56822,7 @@ async function hashDiscoveredFiles(files, root) {
|
|
|
56447
56822
|
const signatures = /* @__PURE__ */ new Map();
|
|
56448
56823
|
await mapLimit(sorted, FILE_SIGNATURE_STAT_CONCURRENCY2, async (file2) => {
|
|
56449
56824
|
try {
|
|
56450
|
-
const stat = await
|
|
56825
|
+
const stat = await fsp29.stat(file2);
|
|
56451
56826
|
signatures.set(file2, { size: stat.size, mtimeMs: stat.mtimeMs });
|
|
56452
56827
|
} catch (error51) {
|
|
56453
56828
|
if (isMissingStatRace2(error51))
|
|
@@ -56506,18 +56881,18 @@ function sha256(value) {
|
|
|
56506
56881
|
}
|
|
56507
56882
|
async function removeCodegraphPath(target, options) {
|
|
56508
56883
|
try {
|
|
56509
|
-
await
|
|
56884
|
+
await fsp29.rm(target, { ...options.recursive ? { recursive: true } : {}, force: true });
|
|
56510
56885
|
} catch (error51) {
|
|
56511
56886
|
throw new CodegraphLifecycleUserError(`Unable to remove ${target}: ${stringifyError(error51)}`);
|
|
56512
56887
|
}
|
|
56513
56888
|
}
|
|
56514
56889
|
async function readCodegraphDirEntries(dir) {
|
|
56515
56890
|
try {
|
|
56516
|
-
const stats = await
|
|
56891
|
+
const stats = await fsp29.lstat(dir);
|
|
56517
56892
|
if (stats.isSymbolicLink()) {
|
|
56518
56893
|
throw new CodegraphLifecycleUserError(`Refusing to traverse symbolic link as .codegraph lifecycle directory: ${dir}`);
|
|
56519
56894
|
}
|
|
56520
|
-
return await
|
|
56895
|
+
return await fsp29.readdir(dir);
|
|
56521
56896
|
} catch (error51) {
|
|
56522
56897
|
if (error51 instanceof CodegraphLifecycleUserError)
|
|
56523
56898
|
throw error51;
|
|
@@ -56528,7 +56903,7 @@ async function readCodegraphDirEntries(dir) {
|
|
|
56528
56903
|
}
|
|
56529
56904
|
async function removeDirIfEmpty(dir) {
|
|
56530
56905
|
try {
|
|
56531
|
-
await
|
|
56906
|
+
await fsp29.rmdir(dir);
|
|
56532
56907
|
} catch (error51) {
|
|
56533
56908
|
if (error51 instanceof Error && "code" in error51 && error51.code === "ENOTEMPTY")
|
|
56534
56909
|
return;
|
|
@@ -56550,7 +56925,7 @@ function isOptionalStringArray(value) {
|
|
|
56550
56925
|
return true;
|
|
56551
56926
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
56552
56927
|
}
|
|
56553
|
-
var MANIFEST_SCHEMA_VERSION, CODEGRAPH_DIR, MANIFEST_FILE, SERVER_REGISTRY_FILE, SERVER_LOG_FILE, KNOWN_CODEGRAPH_FILES, FILE_SIGNATURE_STAT_CONCURRENCY2;
|
|
56928
|
+
var MANIFEST_SCHEMA_VERSION, CODEGRAPH_DIR, MANIFEST_FILE, SERVER_REGISTRY_FILE, SERVER_LOG_FILE, CACHE_DIRECTORY, KNOWN_CODEGRAPH_FILES, FILE_SIGNATURE_STAT_CONCURRENCY2;
|
|
56554
56929
|
var init_manifest2 = __esm({
|
|
56555
56930
|
"dist/lifecycle/manifest.js"() {
|
|
56556
56931
|
"use strict";
|
|
@@ -56567,7 +56942,13 @@ var init_manifest2 = __esm({
|
|
|
56567
56942
|
MANIFEST_FILE = "manifest.json";
|
|
56568
56943
|
SERVER_REGISTRY_FILE = "server.json";
|
|
56569
56944
|
SERVER_LOG_FILE = "server.log";
|
|
56570
|
-
|
|
56945
|
+
CACHE_DIRECTORY = "cache";
|
|
56946
|
+
KNOWN_CODEGRAPH_FILES = {
|
|
56947
|
+
[MANIFEST_FILE]: true,
|
|
56948
|
+
[SERVER_REGISTRY_FILE]: true,
|
|
56949
|
+
[SERVER_LOG_FILE]: true,
|
|
56950
|
+
[CACHE_DIRECTORY]: true
|
|
56951
|
+
};
|
|
56571
56952
|
FILE_SIGNATURE_STAT_CONCURRENCY2 = 64;
|
|
56572
56953
|
}
|
|
56573
56954
|
});
|
|
@@ -56620,7 +57001,7 @@ function formatSyncResult(label, result) {
|
|
|
56620
57001
|
const summary = `${label} Codegraph at ${result.root}: ${result.manifest.fileCount} files${changeLabel}. Manifest: ${result.manifestPath}`;
|
|
56621
57002
|
if (result.gitignore?.status === "added") {
|
|
56622
57003
|
const gitignorePath = path52.join(result.root, result.gitignore.path);
|
|
56623
|
-
const rules = result.gitignore.rules?.length ? result.gitignore.rules.join(", ") : ".codegraph
|
|
57004
|
+
const rules = result.gitignore.rules?.length ? result.gitignore.rules.join(", ") : ".codegraph/";
|
|
56624
57005
|
return `${summary}
|
|
56625
57006
|
Updated Git ignore policy at ${gitignorePath}: added ${rules}.`;
|
|
56626
57007
|
}
|
|
@@ -57413,14 +57794,14 @@ __export(skill_exports, {
|
|
|
57413
57794
|
getSkillTargetDirForAgent: () => getSkillTargetDirForAgent,
|
|
57414
57795
|
handleSkillCommand: () => handleSkillCommand
|
|
57415
57796
|
});
|
|
57416
|
-
import
|
|
57417
|
-
import
|
|
57797
|
+
import fsp30 from "node:fs/promises";
|
|
57798
|
+
import os6 from "node:os";
|
|
57418
57799
|
import path53 from "node:path";
|
|
57419
57800
|
function getBundledSkillDir(packageRoot) {
|
|
57420
57801
|
const candidate = path53.join(packageRoot, "codegraph-skill", "codegraph");
|
|
57421
57802
|
return pathExists(path53.join(candidate, "SKILL.md")) ? candidate : null;
|
|
57422
57803
|
}
|
|
57423
|
-
function getSkillTargetDirForAgent(agent, homeDir =
|
|
57804
|
+
function getSkillTargetDirForAgent(agent, homeDir = os6.homedir(), env = process.env) {
|
|
57424
57805
|
if (agent === "agents") {
|
|
57425
57806
|
return path53.join(homeDir, ".agents", "skills", "codegraph");
|
|
57426
57807
|
}
|
|
@@ -57481,10 +57862,10 @@ function isCommandAvailableOnPath(command) {
|
|
|
57481
57862
|
}
|
|
57482
57863
|
async function copyDirectoryRecursive(sourceDir, targetDir, overwrite) {
|
|
57483
57864
|
if (overwrite && pathExists(targetDir)) {
|
|
57484
|
-
await
|
|
57865
|
+
await fsp30.rm(targetDir, { recursive: true, force: true });
|
|
57485
57866
|
}
|
|
57486
|
-
await
|
|
57487
|
-
const entries = await
|
|
57867
|
+
await fsp30.mkdir(targetDir, { recursive: true });
|
|
57868
|
+
const entries = await fsp30.readdir(sourceDir, { withFileTypes: true });
|
|
57488
57869
|
for (const entry of entries) {
|
|
57489
57870
|
const sourcePath = path53.join(sourceDir, entry.name);
|
|
57490
57871
|
const targetPath = path53.join(targetDir, entry.name);
|
|
@@ -57495,7 +57876,7 @@ async function copyDirectoryRecursive(sourceDir, targetDir, overwrite) {
|
|
|
57495
57876
|
if (!overwrite && pathExists(targetPath)) {
|
|
57496
57877
|
throw new Error(`Target file already exists: ${normalizePathForDisplay(targetPath)}. Re-run with --force to overwrite.`);
|
|
57497
57878
|
}
|
|
57498
|
-
await
|
|
57879
|
+
await fsp30.copyFile(sourcePath, targetPath);
|
|
57499
57880
|
}
|
|
57500
57881
|
}
|
|
57501
57882
|
function normalizePathSegmentForComparison(segment) {
|
|
@@ -57638,8 +58019,8 @@ var init_skill = __esm({
|
|
|
57638
58019
|
|
|
57639
58020
|
// dist/installer/locks.js
|
|
57640
58021
|
import { createHash as createHash5, randomUUID as randomUUID3 } from "node:crypto";
|
|
57641
|
-
import
|
|
57642
|
-
import
|
|
58022
|
+
import fsp31, {} from "node:fs/promises";
|
|
58023
|
+
import os7 from "node:os";
|
|
57643
58024
|
import path54 from "node:path";
|
|
57644
58025
|
function opencodeConfigHome(settings) {
|
|
57645
58026
|
const configHome = settings.env.XDG_CONFIG_HOME?.trim();
|
|
@@ -57675,7 +58056,7 @@ function installerTransactionLockScopes(settings) {
|
|
|
57675
58056
|
}
|
|
57676
58057
|
function installerTransactionLockPath(scope) {
|
|
57677
58058
|
const digest = createHash5("sha256").update(scope).digest("hex");
|
|
57678
|
-
return path54.join(
|
|
58059
|
+
return path54.join(os7.tmpdir(), `codegraph-installer-${digest}.lock`);
|
|
57679
58060
|
}
|
|
57680
58061
|
async function withInstallerLeaseLock(lockPath, resourceName, operation) {
|
|
57681
58062
|
const lock = await acquireInstallerLeaseLock(lockPath, resourceName);
|
|
@@ -57693,14 +58074,14 @@ async function acquireInstallerLeaseLock(lockPath, resourceName) {
|
|
|
57693
58074
|
let file2;
|
|
57694
58075
|
try {
|
|
57695
58076
|
const owner = randomUUID3();
|
|
57696
|
-
file2 = await
|
|
58077
|
+
file2 = await fsp31.open(acquisitionPath, "wx", 384);
|
|
57697
58078
|
await writeInstallerLeaseMetadata(file2, owner);
|
|
57698
58079
|
await file2.close();
|
|
57699
58080
|
file2 = void 0;
|
|
57700
|
-
await
|
|
58081
|
+
await fsp31.link(acquisitionPath, lockPath);
|
|
57701
58082
|
published = true;
|
|
57702
|
-
await
|
|
57703
|
-
file2 = await
|
|
58083
|
+
await fsp31.rm(acquisitionPath, { force: true });
|
|
58084
|
+
file2 = await fsp31.open(lockPath, "r+");
|
|
57704
58085
|
const lockFile = file2;
|
|
57705
58086
|
const renewalTimer = setInterval(() => {
|
|
57706
58087
|
void writeInstallerLeaseMetadata(lockFile, owner).catch(() => void 0);
|
|
@@ -57709,9 +58090,9 @@ async function acquireInstallerLeaseLock(lockPath, resourceName) {
|
|
|
57709
58090
|
return { file: lockFile, lockPath, metadataPath: lockPath, owner, renewalTimer };
|
|
57710
58091
|
} catch (error51) {
|
|
57711
58092
|
await file2?.close().catch(() => void 0);
|
|
57712
|
-
await
|
|
58093
|
+
await fsp31.rm(acquisitionPath, { force: true }).catch(() => void 0);
|
|
57713
58094
|
if (published)
|
|
57714
|
-
await
|
|
58095
|
+
await fsp31.rm(lockPath, { force: true }).catch(() => void 0);
|
|
57715
58096
|
if (!isInstallerLockPublishConflict(error51, lockPath))
|
|
57716
58097
|
throw error51;
|
|
57717
58098
|
const conflict = await resolveInstallerLeaseConflict(lockPath);
|
|
@@ -57729,10 +58110,10 @@ async function acquireInstallerLeaseLock(lockPath, resourceName) {
|
|
|
57729
58110
|
async function resolveInstallerLeaseConflict(lockPath) {
|
|
57730
58111
|
let observed;
|
|
57731
58112
|
try {
|
|
57732
|
-
const stats = await
|
|
58113
|
+
const stats = await fsp31.lstat(lockPath);
|
|
57733
58114
|
if (!stats.isFile())
|
|
57734
58115
|
return "blocked";
|
|
57735
|
-
observed = { content: await
|
|
58116
|
+
observed = { content: await fsp31.readFile(lockPath, "utf8"), mtimeMs: stats.mtimeMs };
|
|
57736
58117
|
} catch (error51) {
|
|
57737
58118
|
if (isFileSystemErrorCode(error51, "ENOENT"))
|
|
57738
58119
|
return "absent";
|
|
@@ -57754,7 +58135,7 @@ async function resolveInstallerLeaseConflict(lockPath) {
|
|
|
57754
58135
|
async function reclaimAbandonedInstallerLease(lockPath, observed) {
|
|
57755
58136
|
const reclaimPath = `${lockPath}.reclaim-${process.pid}-${randomUUID3()}`;
|
|
57756
58137
|
try {
|
|
57757
|
-
await
|
|
58138
|
+
await fsp31.rename(lockPath, reclaimPath);
|
|
57758
58139
|
} catch (error51) {
|
|
57759
58140
|
if (isFileSystemErrorCode(error51, "ENOENT"))
|
|
57760
58141
|
return "absent";
|
|
@@ -57762,20 +58143,20 @@ async function reclaimAbandonedInstallerLease(lockPath, observed) {
|
|
|
57762
58143
|
}
|
|
57763
58144
|
let verified = false;
|
|
57764
58145
|
try {
|
|
57765
|
-
const stats = await
|
|
57766
|
-
verified = stats.isFile() && stats.mtimeMs === observed.mtimeMs && await
|
|
58146
|
+
const stats = await fsp31.lstat(reclaimPath);
|
|
58147
|
+
verified = stats.isFile() && stats.mtimeMs === observed.mtimeMs && await fsp31.readFile(reclaimPath, "utf8") === observed.content;
|
|
57767
58148
|
} catch {
|
|
57768
58149
|
verified = false;
|
|
57769
58150
|
}
|
|
57770
58151
|
if (verified) {
|
|
57771
|
-
await
|
|
58152
|
+
await fsp31.rm(reclaimPath, { force: true });
|
|
57772
58153
|
return "reclaimed";
|
|
57773
58154
|
}
|
|
57774
58155
|
try {
|
|
57775
|
-
await
|
|
58156
|
+
await fsp31.link(reclaimPath, lockPath);
|
|
57776
58157
|
} catch {
|
|
57777
58158
|
}
|
|
57778
|
-
await
|
|
58159
|
+
await fsp31.rm(reclaimPath, { force: true });
|
|
57779
58160
|
return "blocked";
|
|
57780
58161
|
}
|
|
57781
58162
|
function isInstallerLockPublishConflict(error51, lockPath) {
|
|
@@ -57812,9 +58193,9 @@ async function releaseInstallerLeaseLock(lock) {
|
|
|
57812
58193
|
clearInterval(lock.renewalTimer);
|
|
57813
58194
|
await lock.file.close().catch(() => void 0);
|
|
57814
58195
|
try {
|
|
57815
|
-
const metadata = parseInstallerLeaseMetadata(await
|
|
58196
|
+
const metadata = parseInstallerLeaseMetadata(await fsp31.readFile(lock.metadataPath, "utf8"));
|
|
57816
58197
|
if (metadata?.owner === lock.owner)
|
|
57817
|
-
await
|
|
58198
|
+
await fsp31.rm(lock.lockPath, { force: true });
|
|
57818
58199
|
} catch (error51) {
|
|
57819
58200
|
if (!isFileSystemErrorCode(error51, "ENOENT"))
|
|
57820
58201
|
throw error51;
|
|
@@ -57840,8 +58221,8 @@ var init_locks = __esm({
|
|
|
57840
58221
|
|
|
57841
58222
|
// dist/installer/registry.js
|
|
57842
58223
|
import { createHash as createHash6, randomUUID as randomUUID4 } from "node:crypto";
|
|
57843
|
-
import
|
|
57844
|
-
import
|
|
58224
|
+
import fsp32 from "node:fs/promises";
|
|
58225
|
+
import os8 from "node:os";
|
|
57845
58226
|
import path55 from "node:path";
|
|
57846
58227
|
import { applyEdits, modify, parse as parseJsonc2 } from "jsonc-parser";
|
|
57847
58228
|
function listInstallTargets() {
|
|
@@ -57968,7 +58349,7 @@ async function installDefinitions(definitions, options) {
|
|
|
57968
58349
|
return await withInstallerTransactionLocks(settings, install);
|
|
57969
58350
|
}
|
|
57970
58351
|
async function prepareInstallPlan(definitions, settings, dryRun, force) {
|
|
57971
|
-
const bundledSkill = await
|
|
58352
|
+
const bundledSkill = await fsp32.readFile(bundledSkillFilePath());
|
|
57972
58353
|
const files = [];
|
|
57973
58354
|
const conflicts = [];
|
|
57974
58355
|
for (const definition of definitions) {
|
|
@@ -58096,7 +58477,7 @@ async function rollbackInstallPlan(plan) {
|
|
|
58096
58477
|
}
|
|
58097
58478
|
async function removePlannedInstallFile(filePath, root) {
|
|
58098
58479
|
await assertNoSymbolicLinksWithinRoot(filePath, root);
|
|
58099
|
-
await
|
|
58480
|
+
await fsp32.rm(filePath, { force: true });
|
|
58100
58481
|
}
|
|
58101
58482
|
async function verifyInstallPlan(plan, verifyInstalledConfig) {
|
|
58102
58483
|
for (const file2 of plan.files) {
|
|
@@ -58590,7 +58971,7 @@ function installerSettings(options) {
|
|
|
58590
58971
|
if (env === void 0)
|
|
58591
58972
|
env = options.homeDir === void 0 ? process.env : {};
|
|
58592
58973
|
return {
|
|
58593
|
-
homeDir: options.homeDir ??
|
|
58974
|
+
homeDir: options.homeDir ?? os8.homedir(),
|
|
58594
58975
|
env
|
|
58595
58976
|
};
|
|
58596
58977
|
}
|
|
@@ -58607,14 +58988,14 @@ function bundledSkillFilePath() {
|
|
|
58607
58988
|
async function snapshotInstallFile(filePath, root) {
|
|
58608
58989
|
await assertNoSymbolicLinksWithinRoot(filePath, root);
|
|
58609
58990
|
try {
|
|
58610
|
-
const stats = await
|
|
58991
|
+
const stats = await fsp32.lstat(filePath);
|
|
58611
58992
|
if (stats.isSymbolicLink())
|
|
58612
58993
|
throw unsafeSymbolicLinkError(filePath);
|
|
58613
58994
|
if (!stats.isFile()) {
|
|
58614
58995
|
throw new Error(`Expected a regular file at ${normalizePathForDisplay(filePath)} before running the installer.`);
|
|
58615
58996
|
}
|
|
58616
58997
|
return {
|
|
58617
|
-
bytes: await
|
|
58998
|
+
bytes: await fsp32.readFile(filePath),
|
|
58618
58999
|
mode: stats.mode & 4095
|
|
58619
59000
|
};
|
|
58620
59001
|
} catch (error51) {
|
|
@@ -58634,7 +59015,7 @@ async function assertNoSymbolicLinksWithinRoot(filePath, root) {
|
|
|
58634
59015
|
}
|
|
58635
59016
|
for (let current = resolvedFilePath; current !== resolvedRoot; current = path55.dirname(current)) {
|
|
58636
59017
|
try {
|
|
58637
|
-
const stats = await
|
|
59018
|
+
const stats = await fsp32.lstat(current);
|
|
58638
59019
|
if (stats.isSymbolicLink())
|
|
58639
59020
|
throw unsafeSymbolicLinkError(current);
|
|
58640
59021
|
} catch (error51) {
|
|
@@ -58649,7 +59030,7 @@ async function confirmMissingPathHasDirectoryAncestors(filePath) {
|
|
|
58649
59030
|
let current = path55.dirname(filePath);
|
|
58650
59031
|
while (true) {
|
|
58651
59032
|
try {
|
|
58652
|
-
const stats = await
|
|
59033
|
+
const stats = await fsp32.lstat(current);
|
|
58653
59034
|
if (stats.isSymbolicLink())
|
|
58654
59035
|
throw unsafeSymbolicLinkError(current);
|
|
58655
59036
|
if (!stats.isDirectory()) {
|
|
@@ -58688,7 +59069,7 @@ async function writeTextFileAtomic(filePath, content, options = {}) {
|
|
|
58688
59069
|
await assertNoSymbolicLinkAtPath(filePath);
|
|
58689
59070
|
else
|
|
58690
59071
|
await assertNoSymbolicLinksWithinRoot(filePath, options.root);
|
|
58691
|
-
await
|
|
59072
|
+
await fsp32.mkdir(path55.dirname(filePath), { recursive: true });
|
|
58692
59073
|
await withInstallerLeaseLock(`${filePath}.codegraph-lock`, normalizePathForDisplay(filePath), async () => {
|
|
58693
59074
|
if (options.root === void 0)
|
|
58694
59075
|
await assertNoSymbolicLinkAtPath(filePath);
|
|
@@ -58700,7 +59081,7 @@ async function writeTextFileAtomic(filePath, content, options = {}) {
|
|
|
58700
59081
|
let mode = options.mode ?? 384;
|
|
58701
59082
|
if (options.mode === void 0) {
|
|
58702
59083
|
try {
|
|
58703
|
-
const existing = await
|
|
59084
|
+
const existing = await fsp32.lstat(filePath);
|
|
58704
59085
|
if (existing.isSymbolicLink())
|
|
58705
59086
|
throw unsafeSymbolicLinkError(filePath);
|
|
58706
59087
|
mode = existing.mode & 4095;
|
|
@@ -58709,8 +59090,8 @@ async function writeTextFileAtomic(filePath, content, options = {}) {
|
|
|
58709
59090
|
throw error51;
|
|
58710
59091
|
}
|
|
58711
59092
|
}
|
|
58712
|
-
await
|
|
58713
|
-
await
|
|
59093
|
+
await fsp32.writeFile(temporaryPath, content, { encoding: "utf8", flag: "wx", mode });
|
|
59094
|
+
await fsp32.chmod(temporaryPath, mode);
|
|
58714
59095
|
await renameTemporaryFile(temporaryPath, filePath);
|
|
58715
59096
|
} catch (error51) {
|
|
58716
59097
|
if (isFileSystemErrorCode(error51, "EACCES") || isFileSystemErrorCode(error51, "EPERM")) {
|
|
@@ -58718,13 +59099,13 @@ async function writeTextFileAtomic(filePath, content, options = {}) {
|
|
|
58718
59099
|
}
|
|
58719
59100
|
throw error51;
|
|
58720
59101
|
} finally {
|
|
58721
|
-
await
|
|
59102
|
+
await fsp32.rm(temporaryPath, { force: true }).catch(() => void 0);
|
|
58722
59103
|
}
|
|
58723
59104
|
});
|
|
58724
59105
|
}
|
|
58725
59106
|
async function assertNoSymbolicLinkAtPath(filePath) {
|
|
58726
59107
|
try {
|
|
58727
|
-
const stats = await
|
|
59108
|
+
const stats = await fsp32.lstat(filePath);
|
|
58728
59109
|
if (stats.isSymbolicLink())
|
|
58729
59110
|
throw unsafeSymbolicLinkError(filePath);
|
|
58730
59111
|
} catch (error51) {
|
|
@@ -58739,7 +59120,7 @@ function unsafeSymbolicLinkError(filePath) {
|
|
|
58739
59120
|
async function renameTemporaryFile(temporaryPath, filePath) {
|
|
58740
59121
|
for (let attempt = 0; attempt < 5; attempt += 1) {
|
|
58741
59122
|
try {
|
|
58742
|
-
await
|
|
59123
|
+
await fsp32.rename(temporaryPath, filePath);
|
|
58743
59124
|
return;
|
|
58744
59125
|
} catch (error51) {
|
|
58745
59126
|
if (!isFileSystemErrorCode(error51, "EPERM") || attempt === 4)
|
|
@@ -58927,7 +59308,7 @@ __export(doctor_exports, {
|
|
|
58927
59308
|
formatDoctorSummary: () => formatDoctorSummary
|
|
58928
59309
|
});
|
|
58929
59310
|
import fs25 from "node:fs";
|
|
58930
|
-
import
|
|
59311
|
+
import os9 from "node:os";
|
|
58931
59312
|
import path57 from "node:path";
|
|
58932
59313
|
function statIfExists(filePath) {
|
|
58933
59314
|
try {
|
|
@@ -58960,15 +59341,15 @@ function detectIndexedArtifactType(filePath, stats) {
|
|
|
58960
59341
|
return "artifactBundle";
|
|
58961
59342
|
}
|
|
58962
59343
|
const normalized = normalizePathForDisplay(filePath).toLowerCase();
|
|
59344
|
+
if (normalized.endsWith("/.codegraph/cache") || normalized.includes("/.codegraph/cache/") || normalized.endsWith("/.codegraph-cache") || normalized.includes("/.codegraph-cache/")) {
|
|
59345
|
+
return "diskCache";
|
|
59346
|
+
}
|
|
58963
59347
|
if (normalized.endsWith("/codegraph.json") || normalized.endsWith(".json")) {
|
|
58964
59348
|
return "jsonGraph";
|
|
58965
59349
|
}
|
|
58966
59350
|
if (normalized.endsWith("/graph.sqlite") || normalized.endsWith(".sqlite")) {
|
|
58967
59351
|
return "sqliteGraph";
|
|
58968
59352
|
}
|
|
58969
|
-
if (normalized.endsWith("/.codegraph-cache") || normalized.includes("/.codegraph-cache/")) {
|
|
58970
|
-
return "diskCache";
|
|
58971
|
-
}
|
|
58972
59353
|
return "unknown";
|
|
58973
59354
|
}
|
|
58974
59355
|
function buildIndexedArtifactReport(indexPath) {
|
|
@@ -59155,7 +59536,7 @@ function readCacheLocationField(configPath) {
|
|
|
59155
59536
|
}
|
|
59156
59537
|
}
|
|
59157
59538
|
function readUserCacheLocation() {
|
|
59158
|
-
const configRoot = process.platform === "win32" ? process.env.APPDATA?.trim() || path57.join(
|
|
59539
|
+
const configRoot = process.platform === "win32" ? process.env.APPDATA?.trim() || path57.join(os9.homedir(), "AppData", "Roaming") : process.env.XDG_CONFIG_HOME?.trim() || path57.join(os9.homedir(), ".config");
|
|
59159
59540
|
return readCacheLocationField(path57.join(configRoot, "codegraph", "config.json"));
|
|
59160
59541
|
}
|
|
59161
59542
|
function readEffectiveCacheLocation(root) {
|
|
@@ -60485,7 +60866,7 @@ async function handleSqlCommand(context) {
|
|
|
60485
60866
|
const dbOpt = context.getOpt("--db") ?? context.getOpt("--sqlite") ?? context.positionals[0];
|
|
60486
60867
|
const queryText = context.getOpt("--query") ?? context.positionals[1];
|
|
60487
60868
|
if (!dbOpt || !queryText) {
|
|
60488
|
-
context.writeStderrLine(
|
|
60869
|
+
context.writeStderrLine(getCliCommandUsage("sql"));
|
|
60489
60870
|
context.exit(2);
|
|
60490
60871
|
}
|
|
60491
60872
|
const dbPath = path60.isAbsolute(dbOpt) ? normalizePath(dbOpt) : normalizePath(resolveFilePathFromRoot(context.cwd(), dbOpt));
|
|
@@ -60498,6 +60879,7 @@ var init_sql2 = __esm({
|
|
|
60498
60879
|
init_sqlite();
|
|
60499
60880
|
init_paths();
|
|
60500
60881
|
init_pretty();
|
|
60882
|
+
init_options();
|
|
60501
60883
|
}
|
|
60502
60884
|
});
|
|
60503
60885
|
|
|
@@ -60668,7 +61050,7 @@ var chunk_exports = {};
|
|
|
60668
61050
|
__export(chunk_exports, {
|
|
60669
61051
|
handleChunkCommand: () => handleChunkCommand
|
|
60670
61052
|
});
|
|
60671
|
-
import
|
|
61053
|
+
import fsp33 from "node:fs/promises";
|
|
60672
61054
|
import path61 from "node:path";
|
|
60673
61055
|
function normalizeChunkLanguageId(languageId) {
|
|
60674
61056
|
return chunkLanguageAliases2[languageId] ?? languageId;
|
|
@@ -60691,7 +61073,7 @@ function formatChunkSummary(chunks) {
|
|
|
60691
61073
|
async function handleChunkCommand(context) {
|
|
60692
61074
|
const inputFilePath = context.positionals[0];
|
|
60693
61075
|
if (!inputFilePath) {
|
|
60694
|
-
context.writeStderrLine("
|
|
61076
|
+
context.writeStderrLine(getCliCommandUsage("chunk"));
|
|
60695
61077
|
context.writeStderrLine("Options:");
|
|
60696
61078
|
context.writeStderrLine(" --min-tokens N Minimum tokens per chunk (default: 150)");
|
|
60697
61079
|
context.writeStderrLine(" --max-tokens N Maximum tokens per chunk (default: 400)");
|
|
@@ -60699,16 +61081,25 @@ async function handleChunkCommand(context) {
|
|
|
60699
61081
|
context.writeStderrLine(" --text Force text chunking mode");
|
|
60700
61082
|
context.exit(2);
|
|
60701
61083
|
}
|
|
61084
|
+
const languageOverride = context.getOpt("--language");
|
|
61085
|
+
if (languageOverride) {
|
|
61086
|
+
const languageId = normalizeChunkLanguageId(languageOverride);
|
|
61087
|
+
const isSupported = supportedChunkLanguageIds.has(languageId);
|
|
61088
|
+
if (!isSupported) {
|
|
61089
|
+
context.writeStderrLine(`Unsupported --language value "${languageId}". Supported languages: ${chunkLanguageHelp}.`);
|
|
61090
|
+
context.exit(2);
|
|
61091
|
+
}
|
|
61092
|
+
}
|
|
60702
61093
|
try {
|
|
60703
61094
|
const filePath = path61.resolve(context.cwd(), parseSourceLocationInput(inputFilePath).file);
|
|
60704
|
-
const source = await
|
|
61095
|
+
const source = await fsp33.readFile(filePath, "utf8");
|
|
60705
61096
|
const ext = path61.extname(filePath).toLowerCase();
|
|
60706
|
-
let languageId
|
|
60707
|
-
if (!
|
|
61097
|
+
let languageId;
|
|
61098
|
+
if (!languageOverride) {
|
|
60708
61099
|
const support = supportForFile(filePath);
|
|
60709
61100
|
languageId = support ? normalizeChunkLanguageId(support.id) : chunkTextLanguageByExtension[ext] || "text";
|
|
60710
61101
|
} else {
|
|
60711
|
-
languageId = normalizeChunkLanguageId(
|
|
61102
|
+
languageId = normalizeChunkLanguageId(languageOverride);
|
|
60712
61103
|
}
|
|
60713
61104
|
const forceText = context.hasFlag("--text");
|
|
60714
61105
|
const minTokensRaw = context.getOpt("--min-tokens");
|
|
@@ -60755,7 +61146,7 @@ async function handleChunkCommand(context) {
|
|
|
60755
61146
|
exitWithError(context, error51, 1, "Chunking failed");
|
|
60756
61147
|
}
|
|
60757
61148
|
}
|
|
60758
|
-
var chunkLanguageAliases2, chunkTextLanguageByExtension, chunkLanguageHelp;
|
|
61149
|
+
var chunkLanguageAliases2, chunkTextLanguageByExtension, supportedChunkLanguageIds, chunkLanguageHelp;
|
|
60759
61150
|
var init_chunk = __esm({
|
|
60760
61151
|
"dist/cli/chunk.js"() {
|
|
60761
61152
|
"use strict";
|
|
@@ -60777,7 +61168,8 @@ var init_chunk = __esm({
|
|
|
60777
61168
|
".yaml": "yaml",
|
|
60778
61169
|
".yml": "yaml"
|
|
60779
61170
|
};
|
|
60780
|
-
|
|
61171
|
+
supportedChunkLanguageIds = /* @__PURE__ */ new Set([...Object.keys(LANG_CONFIGS), "vue", "svelte", "json", "yaml", "text"]);
|
|
61172
|
+
chunkLanguageHelp = [...supportedChunkLanguageIds].sort().join(", ");
|
|
60781
61173
|
}
|
|
60782
61174
|
});
|
|
60783
61175
|
|
|
@@ -61791,7 +62183,7 @@ var init_fileView = __esm({
|
|
|
61791
62183
|
});
|
|
61792
62184
|
|
|
61793
62185
|
// dist/documentLinks/check.js
|
|
61794
|
-
import
|
|
62186
|
+
import fsp34 from "node:fs/promises";
|
|
61795
62187
|
import path64 from "node:path";
|
|
61796
62188
|
async function checkMarkdownLinks(projectRoot, discovery) {
|
|
61797
62189
|
const root = path64.resolve(projectRoot);
|
|
@@ -61799,14 +62191,14 @@ async function checkMarkdownLinks(projectRoot, discovery) {
|
|
|
61799
62191
|
}
|
|
61800
62192
|
async function checkMarkdownLinksInFiles(projectRoot, files) {
|
|
61801
62193
|
const root = path64.resolve(projectRoot);
|
|
61802
|
-
const realRoot = await
|
|
62194
|
+
const realRoot = await fsp34.realpath(root);
|
|
61803
62195
|
const markdownFileCandidates = await Promise.all(Array.from(files, async (file2) => {
|
|
61804
62196
|
const absoluteFile = path64.resolve(root, file2);
|
|
61805
62197
|
const relativeFile = toProjectRelativePath(root, absoluteFile);
|
|
61806
62198
|
if (relativeFile !== null)
|
|
61807
62199
|
return path64.resolve(realRoot, relativeFile);
|
|
61808
62200
|
try {
|
|
61809
|
-
return await
|
|
62201
|
+
return await fsp34.realpath(absoluteFile);
|
|
61810
62202
|
} catch {
|
|
61811
62203
|
return absoluteFile;
|
|
61812
62204
|
}
|
|
@@ -61875,7 +62267,7 @@ async function recoverDisplayFileCasing(file2) {
|
|
|
61875
62267
|
const dir = path64.dirname(file2);
|
|
61876
62268
|
const base = path64.basename(file2);
|
|
61877
62269
|
try {
|
|
61878
|
-
const entries = await
|
|
62270
|
+
const entries = await fsp34.readdir(dir);
|
|
61879
62271
|
const match = entries.find((entry) => entry.toLowerCase() === base.toLowerCase());
|
|
61880
62272
|
return match ? path64.join(dir, match) : file2;
|
|
61881
62273
|
} catch {
|
|
@@ -61949,8 +62341,8 @@ async function cachedTargetStatus(target, targetStatusByPath) {
|
|
|
61949
62341
|
}
|
|
61950
62342
|
async function readTargetStatus(target) {
|
|
61951
62343
|
try {
|
|
61952
|
-
const realPath = await
|
|
61953
|
-
const stats = await
|
|
62344
|
+
const realPath = await fsp34.realpath(target);
|
|
62345
|
+
const stats = await fsp34.stat(realPath);
|
|
61954
62346
|
return { status: "found", isDirectory: stats.isDirectory(), realPath };
|
|
61955
62347
|
} catch (error51) {
|
|
61956
62348
|
if (isMissingPathError3(error51))
|
|
@@ -61971,7 +62363,7 @@ async function cachedMarkdownAnchors(target, anchorsByPath) {
|
|
|
61971
62363
|
}
|
|
61972
62364
|
async function readMarkdownFile(file2) {
|
|
61973
62365
|
try {
|
|
61974
|
-
return await
|
|
62366
|
+
return await fsp34.readFile(file2, "utf8");
|
|
61975
62367
|
} catch (error51) {
|
|
61976
62368
|
if (error51 instanceof Error) {
|
|
61977
62369
|
throw new Error(`Failed to read Markdown file ${normalizePath(file2)}: ${error51.message}`);
|
|
@@ -63352,7 +63744,7 @@ var init_navigation_references = __esm({
|
|
|
63352
63744
|
});
|
|
63353
63745
|
|
|
63354
63746
|
// dist/sql/navigation.js
|
|
63355
|
-
import
|
|
63747
|
+
import fsp35 from "node:fs/promises";
|
|
63356
63748
|
import path65 from "node:path";
|
|
63357
63749
|
function isSqlFile2(filePath) {
|
|
63358
63750
|
return path65.extname(filePath).toLowerCase() === ".sql";
|
|
@@ -63638,7 +64030,7 @@ async function sourceForFile(filePath, index) {
|
|
|
63638
64030
|
if (cached2 !== void 0)
|
|
63639
64031
|
return cached2;
|
|
63640
64032
|
const parsed = index.parsed?.get(key);
|
|
63641
|
-
const source = parsed ? parsed.source : await
|
|
64033
|
+
const source = parsed ? parsed.source : await fsp35.readFile(filePath, "utf8");
|
|
63642
64034
|
cache.sourceByFile.set(key, source);
|
|
63643
64035
|
return source;
|
|
63644
64036
|
}
|
|
@@ -65342,7 +65734,7 @@ var init_changes = __esm({
|
|
|
65342
65734
|
});
|
|
65343
65735
|
|
|
65344
65736
|
// dist/sql/review.js
|
|
65345
|
-
import
|
|
65737
|
+
import fsp36 from "node:fs/promises";
|
|
65346
65738
|
import path67 from "node:path";
|
|
65347
65739
|
function isSqlFile3(filePath) {
|
|
65348
65740
|
return path67.extname(filePath).toLowerCase() === ".sql";
|
|
@@ -65357,7 +65749,7 @@ function sortEntries(left, right) {
|
|
|
65357
65749
|
}
|
|
65358
65750
|
async function readExistingFile(filePath) {
|
|
65359
65751
|
try {
|
|
65360
|
-
return await
|
|
65752
|
+
return await fsp36.readFile(filePath, "utf8");
|
|
65361
65753
|
} catch {
|
|
65362
65754
|
return null;
|
|
65363
65755
|
}
|
|
@@ -68720,7 +69112,7 @@ var init_referenceCache = __esm({
|
|
|
68720
69112
|
});
|
|
68721
69113
|
|
|
68722
69114
|
// dist/review/summaries.js
|
|
68723
|
-
import
|
|
69115
|
+
import fsp37 from "node:fs/promises";
|
|
68724
69116
|
import path70 from "node:path";
|
|
68725
69117
|
import { performance as performance9 } from "node:perf_hooks";
|
|
68726
69118
|
function relativePath2(root, file2) {
|
|
@@ -68982,7 +69374,7 @@ function sameRange(left, right) {
|
|
|
68982
69374
|
}
|
|
68983
69375
|
async function summarizeChangedFiles2(input) {
|
|
68984
69376
|
const { projectRoot, index, changedFileList, diffHunksByFile, diffKindsByFile, diffChangesByFile, explicitFiles, existenceByFile, deletedSnapshots, loadSource: suppliedLoadSource, includeSymbolDetails, includeDiffContext, diffContextLines, maxCallsites, referenceConcurrency, diagnostics, reviewTimings } = input;
|
|
68985
|
-
const readSource = suppliedLoadSource ?? (async (file2) => await
|
|
69377
|
+
const readSource = suppliedLoadSource ?? (async (file2) => await fsp37.readFile(file2, "utf8"));
|
|
68986
69378
|
const sourceCache = /* @__PURE__ */ new Map();
|
|
68987
69379
|
const loadSource = (file2) => {
|
|
68988
69380
|
const key = fileIdentityKey(file2);
|
|
@@ -74587,11 +74979,12 @@ function suggestCliCommands(input, limit = 3) {
|
|
|
74587
74979
|
function routeForCliIntent(input) {
|
|
74588
74980
|
return INTENT_ROUTES.find((route) => route.pattern.test(input))?.command;
|
|
74589
74981
|
}
|
|
74590
|
-
function renderCliCommandList() {
|
|
74591
|
-
const
|
|
74592
|
-
|
|
74982
|
+
function renderCliCommandList(advanced = false) {
|
|
74983
|
+
const commands = advanced ? CLI_COMMAND_CATALOG : CLI_COMMAND_CATALOG.filter((command) => CORE_COMMAND_NAMES[command.name]);
|
|
74984
|
+
const width = Math.max(...commands.map((command) => command.name.length));
|
|
74985
|
+
return commands.map((command) => ` ${command.name.padEnd(width)} ${command.summary}`).join("\n");
|
|
74593
74986
|
}
|
|
74594
|
-
var CLI_COMMAND_CATALOG, commandByName, aliasToCommand, INTENT_ROUTES;
|
|
74987
|
+
var CLI_COMMAND_CATALOG, commandByName, aliasToCommand, INTENT_ROUTES, CORE_COMMAND_NAMES;
|
|
74595
74988
|
var init_commandCatalog = __esm({
|
|
74596
74989
|
"dist/cli/commandCatalog.js"() {
|
|
74597
74990
|
"use strict";
|
|
@@ -74663,6 +75056,15 @@ var init_commandCatalog = __esm({
|
|
|
74663
75056
|
{ pattern: /^(configure|setup|agent)$/i, command: "codegraph install" },
|
|
74664
75057
|
{ pattern: /^(health|diagnose|check)$/i, command: "codegraph doctor" }
|
|
74665
75058
|
];
|
|
75059
|
+
CORE_COMMAND_NAMES = {
|
|
75060
|
+
doctor: true,
|
|
75061
|
+
orient: true,
|
|
75062
|
+
explore: true,
|
|
75063
|
+
search: true,
|
|
75064
|
+
file: true,
|
|
75065
|
+
deps: true,
|
|
75066
|
+
review: true
|
|
75067
|
+
};
|
|
74666
75068
|
}
|
|
74667
75069
|
});
|
|
74668
75070
|
|
|
@@ -74765,7 +75167,7 @@ function helpTextForCommand(command, positionals) {
|
|
|
74765
75167
|
}
|
|
74766
75168
|
return void 0;
|
|
74767
75169
|
}
|
|
74768
|
-
var CLI_TASK_HELP_TEXT, CLI_HELP_TEXT, LIFECYCLE_HELP_TEXT, AFFECTED_HELP_TEXT, INSTALL_HELP_TEXT, UNINSTALL_HELP_TEXT, SHARED_INDEX_OPTIONS_HELP, EXPLORE_HELP_TEXT, FILE_HELP_TEXT, SEARCH_HELP_TEXT, GOTO_HELP_TEXT, REFS_HELP_TEXT, GREP_HELP_TEXT, SQL_HELP_TEXT, SYMBOLS_HELP_TEXT, CALLERS_HELP_TEXT, CALLEES_HELP_TEXT, SUPERTYPES_HELP_TEXT, SUBTYPES_HELP_TEXT, IMPLEMENTATIONS_HELP_TEXT, RENAME_PREVIEW_HELP_TEXT, REFACTOR_PLAN_HELP_TEXT, ORIENT_HELP_TEXT, PACKET_HELP_TEXT, EXPLAIN_HELP_TEXT, ARTIFACT_HELP_TEXT, SERVER_HELP_TEXT, MCP_HELP_TEXT, MCP_SERVE_HELP_TEXT, DUPLICATES_HELP_TEXT, DRIFT_HELP_TEXT, VIEWER_HELP_TEXT, INDEX_HELP_TEXT, GRAPH_HELP_TEXT, REVIEW_HELP_TEXT, IMPACT_HELP_TEXT, INSPECT_HELP_TEXT, DEPS_HELP_TEXT, RDEPS_HELP_TEXT, PATH_HELP_TEXT, CYCLES_HELP_TEXT, HOTSPOTS_HELP_TEXT, UNRESOLVED_HELP_TEXT, LINKS_HELP_TEXT, APISURFACE_HELP_TEXT, GRAPH_DELTA_HELP_TEXT, DOCTOR_HELP_TEXT, CHUNK_HELP_TEXT, SKILL_HELP_TEXT, DUMPMOD_HELP_TEXT, VERSION_HELP_TEXT;
|
|
75170
|
+
var CLI_TASK_HELP_TEXT, CLI_HELP_TEXT, ADVANCED_HELP_TEXT, LIFECYCLE_HELP_TEXT, AFFECTED_HELP_TEXT, INSTALL_HELP_TEXT, UNINSTALL_HELP_TEXT, SHARED_INDEX_OPTIONS_HELP, EXPLORE_HELP_TEXT, FILE_HELP_TEXT, SEARCH_HELP_TEXT, GOTO_HELP_TEXT, REFS_HELP_TEXT, GREP_HELP_TEXT, SQL_HELP_TEXT, SYMBOLS_HELP_TEXT, CALLERS_HELP_TEXT, CALLEES_HELP_TEXT, SUPERTYPES_HELP_TEXT, SUBTYPES_HELP_TEXT, IMPLEMENTATIONS_HELP_TEXT, RENAME_PREVIEW_HELP_TEXT, REFACTOR_PLAN_HELP_TEXT, ORIENT_HELP_TEXT, PACKET_HELP_TEXT, EXPLAIN_HELP_TEXT, ARTIFACT_HELP_TEXT, SERVER_HELP_TEXT, MCP_HELP_TEXT, MCP_SERVE_HELP_TEXT, DUPLICATES_HELP_TEXT, DRIFT_HELP_TEXT, VIEWER_HELP_TEXT, INDEX_HELP_TEXT, GRAPH_HELP_TEXT, REVIEW_HELP_TEXT, IMPACT_HELP_TEXT, INSPECT_HELP_TEXT, DEPS_HELP_TEXT, RDEPS_HELP_TEXT, PATH_HELP_TEXT, CYCLES_HELP_TEXT, HOTSPOTS_HELP_TEXT, UNRESOLVED_HELP_TEXT, LINKS_HELP_TEXT, APISURFACE_HELP_TEXT, GRAPH_DELTA_HELP_TEXT, DOCTOR_HELP_TEXT, CHUNK_HELP_TEXT, SKILL_HELP_TEXT, DUMPMOD_HELP_TEXT, VERSION_HELP_TEXT;
|
|
74769
75171
|
var init_help = __esm({
|
|
74770
75172
|
"dist/cli/help.js"() {
|
|
74771
75173
|
"use strict";
|
|
@@ -74792,9 +75194,11 @@ Start here:
|
|
|
74792
75194
|
|
|
74793
75195
|
Usage: codegraph <command> [options] [path]
|
|
74794
75196
|
|
|
74795
|
-
|
|
75197
|
+
Core commands:
|
|
74796
75198
|
${renderCliCommandList()}
|
|
74797
75199
|
|
|
75200
|
+
For the complete catalog, run: codegraph help advanced
|
|
75201
|
+
|
|
74798
75202
|
Graph Options:
|
|
74799
75203
|
--fast-graph Use text import extraction for plain .js and .ts
|
|
74800
75204
|
files. May miss multiline or complex patterns;
|
|
@@ -74893,6 +75297,11 @@ Examples:
|
|
|
74893
75297
|
codegraph refactor-plan Service --rename RenamedService
|
|
74894
75298
|
codegraph version
|
|
74895
75299
|
codegraph -v
|
|
75300
|
+
`;
|
|
75301
|
+
ADVANCED_HELP_TEXT = `codegraph - Complete command catalog
|
|
75302
|
+
|
|
75303
|
+
Commands:
|
|
75304
|
+
${renderCliCommandList(true)}
|
|
74896
75305
|
`;
|
|
74897
75306
|
LIFECYCLE_HELP_TEXT = `codegraph init/status/sync/uninit - Initialize, inspect, refresh, or remove project-local Codegraph state
|
|
74898
75307
|
|
|
@@ -74907,9 +75316,9 @@ Usage:
|
|
|
74907
75316
|
codegraph uninit --root <path> [--force] [--json | --pretty]
|
|
74908
75317
|
|
|
74909
75318
|
State:
|
|
74910
|
-
Lifecycle commands own
|
|
74911
|
-
A tracked manifest is left tracked with a warning. Uninit preserves server.json
|
|
74912
|
-
Init and sync may warm or update the disk cache under .codegraph
|
|
75319
|
+
Lifecycle commands own .codegraph/manifest.json metadata; a shared MCP server owns .codegraph/server.json and .codegraph/server.log. In a Git worktree, init and sync --init ensure the .codegraph/ directory is effectively ignored, appending .codegraph/ to the resolved root's .gitignore only when needed; opt out with --no-update-gitignore.
|
|
75320
|
+
A tracked manifest is left tracked with a warning. Uninit preserves server.json, server.log, and cache even with --force, so stop a shared server explicitly; it leaves the root .gitignore rule, and ordinary sync never changes ignore policy.
|
|
75321
|
+
Init and sync may warm or update the disk cache under .codegraph/cache/index-v1/. Existing .codegraph-cache/ directories migrate automatically on the next run. Other commands do not depend on the manifest.
|
|
74913
75322
|
Positional paths and --root are alternatives for lifecycle commands; do not combine them.
|
|
74914
75323
|
`;
|
|
74915
75324
|
AFFECTED_HELP_TEXT = `codegraph affected - List tests likely affected by changed files
|
|
@@ -74989,20 +75398,20 @@ ${SHARED_INDEX_OPTIONS_HELP}
|
|
|
74989
75398
|
`;
|
|
74990
75399
|
GOTO_HELP_TEXT = `codegraph goto - Go to a definition
|
|
74991
75400
|
|
|
74992
|
-
Usage: codegraph goto <file
|
|
75401
|
+
Usage: codegraph goto <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]
|
|
74993
75402
|
codegraph goto <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]
|
|
74994
75403
|
|
|
74995
|
-
A qualified symbol path resolves one definition without a location. A file-only target succeeds when the file defines one symbol; otherwise JSON returns bounded candidates. Search-result locations and portable symbol handles can be pasted directly.
|
|
75404
|
+
A qualified symbol path or portable symbol handle resolves one definition without a location. A file-only target succeeds when the file defines one symbol; otherwise JSON returns bounded candidates. Search-result locations and portable symbol handles can be pasted directly.
|
|
74996
75405
|
|
|
74997
75406
|
${SHARED_INDEX_OPTIONS_HELP}
|
|
74998
75407
|
`;
|
|
74999
75408
|
REFS_HELP_TEXT = `codegraph refs - Find semantic references
|
|
75000
75409
|
|
|
75001
|
-
Usage: codegraph refs <file
|
|
75410
|
+
Usage: codegraph refs <file|file::symbol|symbol:...> [--root <path>] [--json | --pretty]
|
|
75002
75411
|
codegraph refs <file>[:line[:column]] [line] [column] [--root <path>] [--json | --pretty]
|
|
75003
75412
|
codegraph refs --file <file> [--line <line> --col <column>] [--root <path>] [--json | --pretty]
|
|
75004
75413
|
|
|
75005
|
-
A qualified symbol path
|
|
75414
|
+
A qualified symbol path or portable symbol handle resolves one definition and reports references to it without a location. A file-only target finds references for every definition in the file.
|
|
75006
75415
|
|
|
75007
75416
|
${SHARED_INDEX_OPTIONS_HELP}
|
|
75008
75417
|
`;
|
|
@@ -75358,7 +75767,9 @@ ${SHARED_INDEX_OPTIONS_HELP}
|
|
|
75358
75767
|
`;
|
|
75359
75768
|
DEPS_HELP_TEXT = `codegraph deps - List file dependencies
|
|
75360
75769
|
|
|
75361
|
-
Usage: codegraph deps <file|file::symbol|symbol:...> [--root <path>] [--depth <n>] [--json | --pretty]
|
|
75770
|
+
Usage: codegraph deps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]
|
|
75771
|
+
|
|
75772
|
+
By default, outputs dependencies through depth 1. Use --depth for another finite output depth, or --all to include every depth.
|
|
75362
75773
|
|
|
75363
75774
|
A qualified symbol path or portable symbol handle uses its declaring file for file-graph traversal. Use callees for symbol-level call relationships.
|
|
75364
75775
|
|
|
@@ -75366,7 +75777,9 @@ ${SHARED_INDEX_OPTIONS_HELP}
|
|
|
75366
75777
|
`;
|
|
75367
75778
|
RDEPS_HELP_TEXT = `codegraph rdeps - List reverse file dependencies
|
|
75368
75779
|
|
|
75369
|
-
Usage: codegraph rdeps <file|file::symbol|symbol:...> [--root <path>] [--depth <n>] [--json | --pretty]
|
|
75780
|
+
Usage: codegraph rdeps <file|file::symbol|symbol:...> [--root <path>] [--depth <n> | --all] [--json | --pretty]
|
|
75781
|
+
|
|
75782
|
+
By default, outputs reverse dependencies through depth 1. Use --depth for another finite output depth, or --all to include every depth.
|
|
75370
75783
|
|
|
75371
75784
|
A qualified symbol path or portable symbol handle uses its declaring file for file-graph traversal. Use callers for symbol-level call relationships.
|
|
75372
75785
|
|
|
@@ -81458,8 +81871,17 @@ async function handleTypeHierarchyCommand(command, context) {
|
|
|
81458
81871
|
context.writeStderrLine(helpText2(command).trimEnd());
|
|
81459
81872
|
context.exit(2);
|
|
81460
81873
|
}
|
|
81874
|
+
let limit;
|
|
81875
|
+
let depth;
|
|
81876
|
+
try {
|
|
81877
|
+
limit = parseBoundedIntegerOption(context.getOpt("--limit"), "--limit", DEFAULT_HIERARCHY_LIMIT2, 0, MAX_HIERARCHY_LIMIT2);
|
|
81878
|
+
if (command !== "implementations") {
|
|
81879
|
+
depth = parseBoundedIntegerOption(context.getOpt("--depth"), "--depth", DEFAULT_HIERARCHY_DEPTH, 1, MAX_HIERARCHY_DEPTH2);
|
|
81880
|
+
}
|
|
81881
|
+
} catch (error51) {
|
|
81882
|
+
exitWithError(context, error51, 2);
|
|
81883
|
+
}
|
|
81461
81884
|
try {
|
|
81462
|
-
const limit = parseBoundedIntegerOption(context.getOpt("--limit"), "--limit", DEFAULT_HIERARCHY_LIMIT2, 0, MAX_HIERARCHY_LIMIT2);
|
|
81463
81885
|
if (command === "implementations") {
|
|
81464
81886
|
const response2 = await findImplementations2({
|
|
81465
81887
|
root: context.root,
|
|
@@ -81470,7 +81892,6 @@ async function handleTypeHierarchyCommand(command, context) {
|
|
|
81470
81892
|
writeResponse(context, response2, formatImplementationsResponse);
|
|
81471
81893
|
return;
|
|
81472
81894
|
}
|
|
81473
|
-
const depth = parseBoundedIntegerOption(context.getOpt("--depth"), "--depth", DEFAULT_HIERARCHY_DEPTH, 1, MAX_HIERARCHY_DEPTH2);
|
|
81474
81895
|
const request = {
|
|
81475
81896
|
root: context.root,
|
|
81476
81897
|
handle,
|
|
@@ -81576,6 +81997,9 @@ async function handleExplainCommand(context) {
|
|
|
81576
81997
|
} else {
|
|
81577
81998
|
context.writeStdoutLine(formatAgentExplanation(response));
|
|
81578
81999
|
}
|
|
82000
|
+
if (response.target.kind === "not_found") {
|
|
82001
|
+
context.exit(1);
|
|
82002
|
+
}
|
|
81579
82003
|
}
|
|
81580
82004
|
var init_explain2 = __esm({
|
|
81581
82005
|
"dist/cli/explain.js"() {
|
|
@@ -81863,10 +82287,10 @@ function buildFocusTargets(modules, packets, review) {
|
|
|
81863
82287
|
kind: "hotspot",
|
|
81864
82288
|
file: module2.file,
|
|
81865
82289
|
why: `graph-central module: fan-in ${module2.fanIn}, fan-out ${module2.fanOut}, score ${module2.score}`,
|
|
81866
|
-
followUps: [
|
|
82290
|
+
followUps: dedupeAgentFollowUps([
|
|
81867
82291
|
toolFollowUp("packet_get", { target: packet.file }),
|
|
81868
82292
|
toolFollowUp("packet_get", { target: module2.file })
|
|
81869
|
-
]
|
|
82293
|
+
])
|
|
81870
82294
|
});
|
|
81871
82295
|
continue;
|
|
81872
82296
|
}
|
|
@@ -98215,7 +98639,7 @@ var init_tools = __esm({
|
|
|
98215
98639
|
limit: { type: "integer", minimum: 0, maximum: 50, default: 5 },
|
|
98216
98640
|
maxPackets: { type: "integer", minimum: 0, maximum: 10, default: 3 },
|
|
98217
98641
|
maxPaths: { type: "integer", minimum: 0, maximum: 10, default: 3 },
|
|
98218
|
-
includeSource: { type: "boolean", default:
|
|
98642
|
+
includeSource: { type: "boolean", default: false }
|
|
98219
98643
|
}, ["query"]),
|
|
98220
98644
|
dispatch: { handler: "explore" }
|
|
98221
98645
|
},
|
|
@@ -98830,7 +99254,7 @@ function createCodegraphMcpHandlersForSession(options, session) {
|
|
|
98830
99254
|
...request.limit !== void 0 ? { limit: request.limit } : {},
|
|
98831
99255
|
...request.maxPackets !== void 0 ? { maxPackets: request.maxPackets } : {},
|
|
98832
99256
|
...request.maxPaths !== void 0 ? { maxPaths: request.maxPaths } : {},
|
|
98833
|
-
|
|
99257
|
+
includeSource: request.includeSource ?? false
|
|
98834
99258
|
})),
|
|
98835
99259
|
orient: async (request) => await withFreshness(async () => await orientCodegraphWithSession(session, {
|
|
98836
99260
|
root,
|
|
@@ -101603,7 +102027,7 @@ var init_dist4 = __esm({
|
|
|
101603
102027
|
});
|
|
101604
102028
|
|
|
101605
102029
|
// dist/mcp/http.js
|
|
101606
|
-
import
|
|
102030
|
+
import os10 from "node:os";
|
|
101607
102031
|
function getRequestPath(request) {
|
|
101608
102032
|
return new URL(request.url ?? "/", "http://127.0.0.1").pathname;
|
|
101609
102033
|
}
|
|
@@ -101806,11 +102230,11 @@ function isWildcardBindHost(host) {
|
|
|
101806
102230
|
}
|
|
101807
102231
|
function localInterfaceHostnames() {
|
|
101808
102232
|
const hosts = /* @__PURE__ */ new Set();
|
|
101809
|
-
const hostname3 =
|
|
102233
|
+
const hostname3 = os10.hostname().trim().toLowerCase();
|
|
101810
102234
|
if (hostname3) {
|
|
101811
102235
|
hosts.add(hostname3);
|
|
101812
102236
|
}
|
|
101813
|
-
const interfaces =
|
|
102237
|
+
const interfaces = os10.networkInterfaces();
|
|
101814
102238
|
for (const entries of Object.values(interfaces)) {
|
|
101815
102239
|
for (const entry of entries ?? []) {
|
|
101816
102240
|
if (entry.internal)
|
|
@@ -102399,11 +102823,82 @@ function toToolResult(value) {
|
|
|
102399
102823
|
content: [
|
|
102400
102824
|
{
|
|
102401
102825
|
type: "text",
|
|
102402
|
-
text: JSON.stringify(value
|
|
102826
|
+
text: JSON.stringify(translateMcpFollowUps(value))
|
|
102403
102827
|
}
|
|
102404
102828
|
]
|
|
102405
102829
|
};
|
|
102406
102830
|
}
|
|
102831
|
+
function translateMcpFollowUps(value) {
|
|
102832
|
+
if (Array.isArray(value))
|
|
102833
|
+
return translateFollowUpCollection(value);
|
|
102834
|
+
if (typeof value !== "object" || value === null)
|
|
102835
|
+
return value;
|
|
102836
|
+
const source = value;
|
|
102837
|
+
let translated;
|
|
102838
|
+
for (const [key, nestedValue] of Object.entries(source)) {
|
|
102839
|
+
const nestedTranslation = translateMcpFollowUps(nestedValue);
|
|
102840
|
+
if (nestedTranslation === nestedValue)
|
|
102841
|
+
continue;
|
|
102842
|
+
translated ??= { ...source };
|
|
102843
|
+
translated[key] = nestedTranslation;
|
|
102844
|
+
}
|
|
102845
|
+
return translateFollowUps(translated ?? source);
|
|
102846
|
+
}
|
|
102847
|
+
function translateFollowUpCollection(value) {
|
|
102848
|
+
let translated;
|
|
102849
|
+
for (const [index, entry] of value.entries()) {
|
|
102850
|
+
const entryTranslation = translateMcpFollowUps(entry);
|
|
102851
|
+
if (entryTranslation === entry) {
|
|
102852
|
+
if (translated !== void 0)
|
|
102853
|
+
translated.push(entry);
|
|
102854
|
+
continue;
|
|
102855
|
+
}
|
|
102856
|
+
translated ??= [...value.slice(0, index)];
|
|
102857
|
+
translated.push(entryTranslation);
|
|
102858
|
+
}
|
|
102859
|
+
return translated ?? value;
|
|
102860
|
+
}
|
|
102861
|
+
function translateFollowUps(value) {
|
|
102862
|
+
const followUps = value.followUps;
|
|
102863
|
+
if (!Array.isArray(followUps) || !followUps.every(isAgentFollowUp))
|
|
102864
|
+
return value;
|
|
102865
|
+
const translatedFollowUps = followUps.map(translateMcpFollowUp);
|
|
102866
|
+
if (translatedFollowUps.every((followUp, index) => followUp === followUps[index]))
|
|
102867
|
+
return value;
|
|
102868
|
+
return { ...value, followUps: translatedFollowUps };
|
|
102869
|
+
}
|
|
102870
|
+
function isAgentFollowUp(value) {
|
|
102871
|
+
return typeof value === "object" && value !== null && "tool" in value && typeof value.tool === "string" && "arguments" in value && typeof value.arguments === "object" && value.arguments !== null && !Array.isArray(value.arguments);
|
|
102872
|
+
}
|
|
102873
|
+
function translateMcpFollowUp(followUp) {
|
|
102874
|
+
if (followUp.tool === "chunk")
|
|
102875
|
+
return { ...followUp, tool: "get_file" };
|
|
102876
|
+
if (followUp.tool === "duplicates") {
|
|
102877
|
+
return {
|
|
102878
|
+
...followUp,
|
|
102879
|
+
tool: "packet_get",
|
|
102880
|
+
arguments: { target: firstDuplicateFile(followUp.arguments) }
|
|
102881
|
+
};
|
|
102882
|
+
}
|
|
102883
|
+
if (followUp.tool === "explore" && followUp.arguments.includeSource === void 0) {
|
|
102884
|
+
return {
|
|
102885
|
+
...followUp,
|
|
102886
|
+
arguments: { ...followUp.arguments, includeSource: true }
|
|
102887
|
+
};
|
|
102888
|
+
}
|
|
102889
|
+
if (followUp.tool === "impact" && followUp.arguments.provider === "git") {
|
|
102890
|
+
const arguments_ = { ...followUp.arguments };
|
|
102891
|
+
delete arguments_.provider;
|
|
102892
|
+
return { ...followUp, arguments: arguments_ };
|
|
102893
|
+
}
|
|
102894
|
+
return followUp;
|
|
102895
|
+
}
|
|
102896
|
+
function firstDuplicateFile(arguments_) {
|
|
102897
|
+
const files = arguments_.files;
|
|
102898
|
+
if (!Array.isArray(files))
|
|
102899
|
+
return ".";
|
|
102900
|
+
return files.find((file2) => typeof file2 === "string") ?? ".";
|
|
102901
|
+
}
|
|
102407
102902
|
function toToolErrorResult(error51) {
|
|
102408
102903
|
const message = errorMessage(error51).replace(/(?:[A-Za-z]:)?[/\\][^'"\n]*?(?=(?:[/\\][^'"\n]*)?['"]|$)/g, "<path>");
|
|
102409
102904
|
return { isError: true, content: [{ type: "text", text: message }] };
|
|
@@ -103067,7 +103562,7 @@ import path86 from "node:path";
|
|
|
103067
103562
|
async function handleServerCommand(context) {
|
|
103068
103563
|
const command = context.positionals[0];
|
|
103069
103564
|
if (!isServerCommand(command)) {
|
|
103070
|
-
context.writeStderrLine("
|
|
103565
|
+
context.writeStderrLine(getCliCommandUsage("server"));
|
|
103071
103566
|
context.exit(2);
|
|
103072
103567
|
}
|
|
103073
103568
|
try {
|
|
@@ -103897,7 +104392,8 @@ var init_server2 = __esm({
|
|
|
103897
104392
|
"--warmup",
|
|
103898
104393
|
"--warmup-symbols",
|
|
103899
104394
|
"--workers",
|
|
103900
|
-
"--json"
|
|
104395
|
+
"--json",
|
|
104396
|
+
"--pretty"
|
|
103901
104397
|
],
|
|
103902
104398
|
status: ["--json", "--pretty"],
|
|
103903
104399
|
stop: []
|
|
@@ -103929,7 +104425,7 @@ var graphDelta_exports = {};
|
|
|
103929
104425
|
__export(graphDelta_exports, {
|
|
103930
104426
|
handleGraphDeltaCommand: () => handleGraphDeltaCommand
|
|
103931
104427
|
});
|
|
103932
|
-
import
|
|
104428
|
+
import fsp38 from "node:fs/promises";
|
|
103933
104429
|
function formatGraphDeltaReport(delta) {
|
|
103934
104430
|
const lines = [];
|
|
103935
104431
|
lines.push("Graph delta");
|
|
@@ -103996,7 +104492,7 @@ async function handleGraphDeltaCommand(context) {
|
|
|
103996
104492
|
const outputFile = outputArg ? normalizePath(resolveFilePathFromRoot(context.cwd(), outputArg)) : void 0;
|
|
103997
104493
|
if (outputFile) {
|
|
103998
104494
|
const output = context.hasFlag("--json") ? JSON.stringify(delta, null, 2) : formatGraphDeltaReport(delta);
|
|
103999
|
-
await
|
|
104495
|
+
await fsp38.writeFile(outputFile, `${output}
|
|
104000
104496
|
`, "utf8");
|
|
104001
104497
|
} else {
|
|
104002
104498
|
writeCliOutput(context, delta, formatGraphDeltaReport);
|
|
@@ -104296,7 +104792,7 @@ var init_symbol_render = __esm({
|
|
|
104296
104792
|
});
|
|
104297
104793
|
|
|
104298
104794
|
// dist/sql/graph.js
|
|
104299
|
-
import
|
|
104795
|
+
import fsp39 from "node:fs/promises";
|
|
104300
104796
|
function statementNodeId(fact) {
|
|
104301
104797
|
return `sql:statement:${fact.filePath}:${fact.startLine}-${fact.endLine}`;
|
|
104302
104798
|
}
|
|
@@ -104451,7 +104947,7 @@ function projectSqlFactsToGraph(facts) {
|
|
|
104451
104947
|
};
|
|
104452
104948
|
}
|
|
104453
104949
|
async function buildSqlArtifactGraphFromFiles(files) {
|
|
104454
|
-
const factGroups = await Promise.all(files.map(async (filePath) => extractSqlFactsFromSource(filePath, await
|
|
104950
|
+
const factGroups = await Promise.all(files.map(async (filePath) => extractSqlFactsFromSource(filePath, await fsp39.readFile(filePath, "utf8"))));
|
|
104455
104951
|
return projectSqlFactsToGraph(factGroups.flat());
|
|
104456
104952
|
}
|
|
104457
104953
|
var init_graph = __esm({
|
|
@@ -104482,7 +104978,7 @@ __export(graph_exports, {
|
|
|
104482
104978
|
handleGraphCommand: () => handleGraphCommand
|
|
104483
104979
|
});
|
|
104484
104980
|
import fs42 from "node:fs";
|
|
104485
|
-
import
|
|
104981
|
+
import fsp40 from "node:fs/promises";
|
|
104486
104982
|
import path88 from "node:path";
|
|
104487
104983
|
import { performance as performance12 } from "node:perf_hooks";
|
|
104488
104984
|
function resolveGraphCacheMode(cache) {
|
|
@@ -104645,7 +105141,7 @@ async function handleGraphCommand(context) {
|
|
|
104645
105141
|
...cacheDir ? { cacheDir } : {},
|
|
104646
105142
|
...context.cacheLocation ? { cacheLocation: context.cacheLocation } : {}
|
|
104647
105143
|
};
|
|
104648
|
-
const stable =
|
|
105144
|
+
const stable = true;
|
|
104649
105145
|
let format = "mermaid";
|
|
104650
105146
|
if (context.hasFlag("--json")) {
|
|
104651
105147
|
format = "json";
|
|
@@ -104676,7 +105172,7 @@ async function handleGraphCommand(context) {
|
|
|
104676
105172
|
};
|
|
104677
105173
|
const writeOut = async (text) => {
|
|
104678
105174
|
if (outputFile) {
|
|
104679
|
-
await
|
|
105175
|
+
await fsp40.writeFile(outputFile, `${text}
|
|
104680
105176
|
`, "utf8");
|
|
104681
105177
|
} else {
|
|
104682
105178
|
context.writeStdoutLine(text);
|
|
@@ -105619,7 +106115,7 @@ var init_report3 = __esm({
|
|
|
105619
106115
|
});
|
|
105620
106116
|
|
|
105621
106117
|
// dist/drift/artifact.js
|
|
105622
|
-
import
|
|
106118
|
+
import fsp41 from "node:fs/promises";
|
|
105623
106119
|
import path90 from "node:path";
|
|
105624
106120
|
function readStringRecord2(value) {
|
|
105625
106121
|
if (!isPlainRecord(value))
|
|
@@ -105643,7 +106139,7 @@ function parseManifest(value) {
|
|
|
105643
106139
|
}
|
|
105644
106140
|
async function readJson(filePath, label) {
|
|
105645
106141
|
try {
|
|
105646
|
-
return JSON.parse(await
|
|
106142
|
+
return JSON.parse(await fsp41.readFile(filePath, "utf8"));
|
|
105647
106143
|
} catch (error51) {
|
|
105648
106144
|
if (error51 instanceof Error && "code" in error51 && error51.code === "ENOENT") {
|
|
105649
106145
|
throw new Error(`Codegraph artifact ${label} is missing.`);
|
|
@@ -105777,8 +106273,8 @@ var init_artifact3 = __esm({
|
|
|
105777
106273
|
|
|
105778
106274
|
// dist/drift/git.js
|
|
105779
106275
|
import { execFile } from "node:child_process";
|
|
105780
|
-
import
|
|
105781
|
-
import
|
|
106276
|
+
import fsp42 from "node:fs/promises";
|
|
106277
|
+
import os11 from "node:os";
|
|
105782
106278
|
import path91 from "node:path";
|
|
105783
106279
|
import { promisify } from "node:util";
|
|
105784
106280
|
function snapshotOptions(options) {
|
|
@@ -105798,7 +106294,7 @@ async function cleanupTempDir(dir) {
|
|
|
105798
106294
|
if (!dir)
|
|
105799
106295
|
return;
|
|
105800
106296
|
try {
|
|
105801
|
-
await
|
|
106297
|
+
await fsp42.rm(dir, { recursive: true, force: true });
|
|
105802
106298
|
} catch {
|
|
105803
106299
|
}
|
|
105804
106300
|
}
|
|
@@ -105817,7 +106313,7 @@ async function materializeGitRef(root, ref, prefix) {
|
|
|
105817
106313
|
}
|
|
105818
106314
|
if (checkoutRef === void 0 || checkoutRef === "." || isGitWorktreeSentinel(checkoutRef))
|
|
105819
106315
|
return { root };
|
|
105820
|
-
const tempRoot = await
|
|
106316
|
+
const tempRoot = await fsp42.mkdtemp(path91.join(os11.tmpdir(), prefix));
|
|
105821
106317
|
try {
|
|
105822
106318
|
await execFileAsync("git", ["clone", "--quiet", "--no-checkout", root, tempRoot], { env: process.env });
|
|
105823
106319
|
const checkoutCommit = await resolveGitCommit(root, checkoutRef);
|
|
@@ -106567,7 +107063,7 @@ function formatGotoOutput(projectRootFs, output) {
|
|
|
106567
107063
|
async function handleDumpmodCommand(context) {
|
|
106568
107064
|
const [fileArg] = context.positionals;
|
|
106569
107065
|
if (!fileArg) {
|
|
106570
|
-
context.writeStderrLine("
|
|
107066
|
+
context.writeStderrLine(getCliCommandUsage("dumpmod"));
|
|
106571
107067
|
context.exit(2);
|
|
106572
107068
|
}
|
|
106573
107069
|
const resolvedFile = resolveCliProjectFile(context.projectRootFs, fileArg, "File");
|
|
@@ -106689,9 +107185,14 @@ function writePrettyReferences(context, result) {
|
|
|
106689
107185
|
}
|
|
106690
107186
|
}
|
|
106691
107187
|
async function handleGotoCommand(context) {
|
|
106692
|
-
|
|
107188
|
+
let input;
|
|
107189
|
+
try {
|
|
107190
|
+
input = parseNavigationInput(context, false);
|
|
107191
|
+
} catch (error51) {
|
|
107192
|
+
exitWithError(context, error51, 2);
|
|
107193
|
+
}
|
|
106693
107194
|
if (!input) {
|
|
106694
|
-
context.writeStderrLine("
|
|
107195
|
+
context.writeStderrLine(getCliCommandUsage("goto"));
|
|
106695
107196
|
context.exit(2);
|
|
106696
107197
|
}
|
|
106697
107198
|
const resolvedFile = resolveCliProjectFile(context.projectRootFs, input.file, "File");
|
|
@@ -106744,9 +107245,14 @@ async function handleGotoCommand(context) {
|
|
|
106744
107245
|
context.exit(1);
|
|
106745
107246
|
}
|
|
106746
107247
|
async function handleRefsCommand(context) {
|
|
106747
|
-
|
|
107248
|
+
let input;
|
|
107249
|
+
try {
|
|
107250
|
+
input = parseNavigationInput(context, true);
|
|
107251
|
+
} catch (error51) {
|
|
107252
|
+
exitWithError(context, error51, 2);
|
|
107253
|
+
}
|
|
106748
107254
|
if (!input) {
|
|
106749
|
-
context.writeStderrLine("
|
|
107255
|
+
context.writeStderrLine(getCliCommandUsage("refs"));
|
|
106750
107256
|
context.exit(2);
|
|
106751
107257
|
}
|
|
106752
107258
|
const pretty = !context.hasFlag("--json");
|
|
@@ -106832,11 +107338,12 @@ var init_navigation3 = __esm({
|
|
|
106832
107338
|
init_location2();
|
|
106833
107339
|
init_projectFile();
|
|
106834
107340
|
init_pretty();
|
|
107341
|
+
init_context();
|
|
106835
107342
|
}
|
|
106836
107343
|
});
|
|
106837
107344
|
|
|
106838
107345
|
// dist/graphs/grep.js
|
|
106839
|
-
import
|
|
107346
|
+
import fsp43 from "node:fs/promises";
|
|
106840
107347
|
async function* streamAstGrep(projectRoot, querySource, patterns = [
|
|
106841
107348
|
"**/*.{ts,tsx,js,jsx,mts,cts,mjs,cjs,py,vue,svelte,go,java,cs,rb,rs,html,htm,css,scss,less,kt,kts,swift,zig,c,h,cc,cpp,cxx,c++,hpp,hh,hxx,ipp,tpp,inl}"
|
|
106842
107349
|
], opts) {
|
|
@@ -106894,7 +107401,7 @@ async function* streamTextGrep(projectRoot, patternSource, patterns = [
|
|
|
106894
107401
|
break;
|
|
106895
107402
|
let source;
|
|
106896
107403
|
try {
|
|
106897
|
-
source = await
|
|
107404
|
+
source = await fsp43.readFile(file2, "utf8");
|
|
106898
107405
|
} catch {
|
|
106899
107406
|
continue;
|
|
106900
107407
|
}
|
|
@@ -106983,7 +107490,7 @@ async function handleGrepCommand(context) {
|
|
|
106983
107490
|
exitWithError(context, error51, 2);
|
|
106984
107491
|
}
|
|
106985
107492
|
if ((querySource ? 1 : 0) + (patternSource ? 1 : 0) !== 1) {
|
|
106986
|
-
context.writeStderrLine("
|
|
107493
|
+
context.writeStderrLine(getCliCommandUsage("grep"));
|
|
106987
107494
|
context.exit(2);
|
|
106988
107495
|
}
|
|
106989
107496
|
if (querySource && maxHits !== void 0) {
|
|
@@ -107895,7 +108402,7 @@ function deletedPathsForChange2(change2) {
|
|
|
107895
108402
|
async function buildAffectedReportFromContext(context) {
|
|
107896
108403
|
const inputs = await collectChangedFileInputs(context);
|
|
107897
108404
|
if (!inputs.files.length) {
|
|
107898
|
-
throw new Error("
|
|
108405
|
+
throw new Error(getCliCommandUsage("affected"));
|
|
107899
108406
|
}
|
|
107900
108407
|
const normalizedChangedFiles = Array.from(new Set(inputs.files.map((input) => normalizeChangedFileInput(context.projectRootFs, input)))).sort();
|
|
107901
108408
|
const normalizedDeletedFiles = Array.from(new Set(inputs.deletedFiles.map((input) => normalizeChangedFileInput(context.projectRootFs, input)))).sort();
|
|
@@ -108291,10 +108798,15 @@ async function loadGraph(context) {
|
|
|
108291
108798
|
async function handleDepsCommand(context) {
|
|
108292
108799
|
const [fileArg] = context.positionals;
|
|
108293
108800
|
if (!fileArg) {
|
|
108294
|
-
context.writeStderrLine(
|
|
108801
|
+
context.writeStderrLine(getCliCommandUsage(context.command));
|
|
108295
108802
|
context.exit(2);
|
|
108296
108803
|
}
|
|
108297
108804
|
const depthRaw = context.getOpt("--depth");
|
|
108805
|
+
const all = context.hasFlag("--all");
|
|
108806
|
+
if (all && depthRaw !== void 0) {
|
|
108807
|
+
context.writeStderrLine("--all cannot be combined with --depth.");
|
|
108808
|
+
context.exit(2);
|
|
108809
|
+
}
|
|
108298
108810
|
let depth;
|
|
108299
108811
|
try {
|
|
108300
108812
|
depth = parseOptionalNonNegativeIntegerOption(depthRaw, "--depth");
|
|
@@ -108371,18 +108883,21 @@ async function handleDepsCommand(context) {
|
|
|
108371
108883
|
context.exit(1);
|
|
108372
108884
|
}
|
|
108373
108885
|
targetFile = matchedGraphNode;
|
|
108374
|
-
const
|
|
108375
|
-
|
|
108376
|
-
...loaded.adjacency ? { adjacency: loaded.adjacency } : {}
|
|
108377
|
-
|
|
108378
|
-
|
|
108379
|
-
|
|
108380
|
-
|
|
108886
|
+
const effectiveDepth = depth ?? 1;
|
|
108887
|
+
const traversalOptions = {
|
|
108888
|
+
...loaded.adjacency ? { adjacency: loaded.adjacency } : {},
|
|
108889
|
+
...json3 && !all ? { depth: effectiveDepth + 1 } : {}
|
|
108890
|
+
};
|
|
108891
|
+
const allResults = context.command === "deps" ? getDependencies(loaded.graph, targetFile, traversalOptions) : getReverseDependencies(loaded.graph, targetFile, traversalOptions);
|
|
108892
|
+
const results = all ? allResults : allResults.filter((result) => result.depth <= effectiveDepth);
|
|
108893
|
+
const truncated = results.length !== allResults.length;
|
|
108894
|
+
const omittedCount = allResults.length - results.length;
|
|
108381
108895
|
if (json3) {
|
|
108382
|
-
context.writeJSONLine(results);
|
|
108896
|
+
context.writeJSONLine({ items: results, truncated });
|
|
108383
108897
|
return;
|
|
108384
108898
|
}
|
|
108385
|
-
|
|
108899
|
+
const depthDescription = all ? "all depths" : `depth ${effectiveDepth}`;
|
|
108900
|
+
context.writeStdoutLine(`${context.command === "deps" ? "Dependencies" : "Reverse dependencies"} for ${fileArg} (${depthDescription}; ${omittedCount} omitted):`);
|
|
108386
108901
|
for (const result of results) {
|
|
108387
108902
|
const rel = toProjectDisplayPath(context.projectRootFs, result.file);
|
|
108388
108903
|
context.writeStdoutLine(`${" ".repeat(result.depth)} ${rel} (depth ${result.depth})`);
|
|
@@ -108391,7 +108906,7 @@ async function handleDepsCommand(context) {
|
|
|
108391
108906
|
async function handlePathCommand(context) {
|
|
108392
108907
|
const [fromArg, toArg] = context.positionals;
|
|
108393
108908
|
if (!fromArg || !toArg) {
|
|
108394
|
-
context.writeStderrLine("
|
|
108909
|
+
context.writeStderrLine(getCliCommandUsage("path"));
|
|
108395
108910
|
context.exit(2);
|
|
108396
108911
|
}
|
|
108397
108912
|
const json3 = context.hasFlag("--json");
|
|
@@ -109655,10 +110170,7 @@ function resolveCliRootPolicy(input) {
|
|
|
109655
110170
|
if (!isLegacyImpactRoot) {
|
|
109656
110171
|
return {
|
|
109657
110172
|
status: "error",
|
|
109658
|
-
messages: [
|
|
109659
|
-
`Unexpected positional argument for impact: ${impactRootArg}`,
|
|
109660
|
-
"Usage: codegraph impact [project-root] [--provider git|github|raw] [options]"
|
|
109661
|
-
]
|
|
110173
|
+
messages: [`Unexpected positional argument for impact: ${impactRootArg}`, getCliCommandUsage("impact")]
|
|
109662
110174
|
};
|
|
109663
110175
|
}
|
|
109664
110176
|
}
|
|
@@ -109751,6 +110263,7 @@ var init_rootPolicy = __esm({
|
|
|
109751
110263
|
"dist/cli/rootPolicy.js"() {
|
|
109752
110264
|
"use strict";
|
|
109753
110265
|
init_paths();
|
|
110266
|
+
init_options();
|
|
109754
110267
|
WINDOWS_DRIVE_QUALIFIED_PATTERN = /^[A-Za-z]:[\\/]/;
|
|
109755
110268
|
WINDOWS_DRIVE_RELATIVE_ROOT_PATTERN = /^[\\/](?![\\/])/;
|
|
109756
110269
|
}
|
|
@@ -110527,6 +111040,10 @@ async function runCliWithActiveRuntime(rawArgs) {
|
|
|
110527
111040
|
writeStdoutLine(CLI_HELP_TEXT.trimEnd());
|
|
110528
111041
|
return;
|
|
110529
111042
|
}
|
|
111043
|
+
if (command === "advanced") {
|
|
111044
|
+
writeStdoutLine(ADVANCED_HELP_TEXT.trimEnd());
|
|
111045
|
+
return;
|
|
111046
|
+
}
|
|
110530
111047
|
if (!isKnownCliCommand(command)) {
|
|
110531
111048
|
writeStderrLine(`Unknown command "${command}".`);
|
|
110532
111049
|
const suggestions = suggestCliCommands(command);
|