@wrongstack/tools 0.7.7 → 0.8.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.
@@ -1,11 +1,12 @@
1
1
  import * as fs2 from 'node:fs/promises';
2
- import * as path3 from 'node:path';
2
+ import * as path4 from 'node:path';
3
3
  import { compileGlob } from '@wrongstack/core';
4
+ import { createRequire } from 'node:module';
4
5
  import * as fs from 'node:fs';
5
- import { mkdirSync, writeFileSync, unlinkSync } from 'node:fs';
6
- import { DatabaseSync } from 'node:sqlite';
6
+ import { mkdirSync, writeFileSync } from 'node:fs';
7
7
  import * as ts from 'typescript';
8
8
  import { execSync, spawnSync } from 'node:child_process';
9
+ import * as os from 'node:os';
9
10
 
10
11
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
12
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -82,12 +83,39 @@ function internalKindToLspKind(k) {
82
83
  // src/codebase-index/writer.ts
83
84
  var INDEX_DIR = ".codebase-index";
84
85
  var DB_FILE = "index.db";
86
+ var warningSilenced = false;
87
+ function silenceSqliteExperimentalWarning() {
88
+ if (warningSilenced) return;
89
+ warningSilenced = true;
90
+ const original = process.emitWarning.bind(process);
91
+ process.emitWarning = ((warning, ...rest) => {
92
+ const msg = typeof warning === "string" ? warning : warning?.message ?? "";
93
+ const name = typeof warning === "string" ? String(rest[0] ?? "") : warning?.name ?? "";
94
+ if (/sqlite/i.test(msg) && /experimental/i.test(`${name} ${msg}`)) return;
95
+ original(warning, ...rest);
96
+ });
97
+ }
98
+ var DatabaseSyncCtor;
99
+ function loadDatabaseSync() {
100
+ if (DatabaseSyncCtor) return DatabaseSyncCtor;
101
+ silenceSqliteExperimentalWarning();
102
+ try {
103
+ const req = createRequire(import.meta.url);
104
+ DatabaseSyncCtor = req("node:sqlite").DatabaseSync;
105
+ } catch (err) {
106
+ throw new Error(
107
+ `The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. This runtime doesn't provide it: ${err instanceof Error ? err.message : String(err)}`
108
+ );
109
+ }
110
+ return DatabaseSyncCtor;
111
+ }
85
112
  var IndexStore = class {
86
113
  constructor(projectRoot) {
87
114
  this.projectRoot = projectRoot;
88
- const dir = path3.join(projectRoot, INDEX_DIR);
115
+ const dir = path4.join(projectRoot, INDEX_DIR);
89
116
  fs.mkdirSync(dir, { recursive: true });
90
- this.db = new DatabaseSync(path3.join(dir, DB_FILE));
117
+ const Database = loadDatabaseSync();
118
+ this.db = new Database(path4.join(dir, DB_FILE));
91
119
  this.initSchema();
92
120
  }
93
121
  projectRoot;
@@ -282,7 +310,7 @@ var IndexStore = class {
282
310
  totalFiles,
283
311
  byLang,
284
312
  byKind,
285
- indexPath: path3.join(this.projectRoot, INDEX_DIR),
313
+ indexPath: path4.join(this.projectRoot, INDEX_DIR),
286
314
  lastIndexed,
287
315
  sizeBytes,
288
316
  version: SCHEMA_VERSION
@@ -375,7 +403,7 @@ var IndexStore = class {
375
403
  }));
376
404
  }
377
405
  sizeBytes() {
378
- const dbPath = path3.join(this.projectRoot, INDEX_DIR, DB_FILE);
406
+ const dbPath = path4.join(this.projectRoot, INDEX_DIR, DB_FILE);
379
407
  try {
380
408
  return fs.statSync(dbPath).size;
381
409
  } catch {
@@ -590,6 +618,7 @@ import (
590
618
  "go/ast"
591
619
  "go/parser"
592
620
  "go/token"
621
+ "io"
593
622
  "os"
594
623
  "strings"
595
624
  )
@@ -604,17 +633,13 @@ type Sym struct {
604
633
  }
605
634
 
606
635
  func main() {
607
- if len(os.Args) < 2 {
608
- fmt.Print("[]")
609
- return
610
- }
611
- src, err := os.ReadFile(os.Args[1])
636
+ src, err := io.ReadAll(os.Stdin)
612
637
  if err != nil {
613
638
  fmt.Print("[]")
614
639
  return
615
640
  }
616
641
  fset := token.NewFileSet()
617
- node, err := parser.ParseFile(fset, os.Args[1], src, 0)
642
+ node, err := parser.ParseFile(fset, "src.go", src, 0)
618
643
  if err != nil {
619
644
  fmt.Print("[]")
620
645
  return
@@ -758,7 +783,7 @@ func formatMethods(fields []*ast.Field) string {
758
783
  return formatFields(fields)
759
784
  }
760
785
 
761
- func formatTypeParams(tp *ast.TypeParams) string {
786
+ func formatTypeParams(tp *ast.FieldList) string {
762
787
  if tp == nil || len(tp.List) == 0 {
763
788
  return ""
764
789
  }
@@ -801,30 +826,33 @@ func formatType(t ast.Expr) string {
801
826
  return "chan " + formatType(v.Value)
802
827
  case *ast.BasicLit:
803
828
  return v.Value
829
+ case *ast.IndexExpr:
830
+ // Generic instantiation with one type arg, e.g. Logger[int].
831
+ return formatType(v.X) + "[" + formatType(v.Index) + "]"
832
+ case *ast.IndexListExpr:
833
+ // Generic instantiation with multiple type args, e.g. Map[K, V].
834
+ args := make([]string, len(v.Indices))
835
+ for i, idx := range v.Indices {
836
+ args[i] = formatType(idx)
837
+ }
838
+ return formatType(v.X) + "[" + strings.Join(args, ", ") + "]"
804
839
  default:
805
840
  return "?"
806
841
  }
807
842
  }
808
843
  `;
809
- function syncGoParse(filePath, _content, lang) {
810
- const tmpDir = path3.join(process.env.TEMP ?? "/tmp", "ws-go-parse");
844
+ function syncGoParse(filePath, content, lang) {
845
+ const tmpDir = path4.join(os.tmpdir(), "ws-go-parse");
811
846
  try {
812
847
  mkdirSync(tmpDir, { recursive: true });
813
- const scriptPath = path3.join(tmpDir, "parse.go");
848
+ const scriptPath = path4.join(tmpDir, "parse.go");
814
849
  writeFileSync(scriptPath, GO_PARSE_SCRIPT, "utf8");
815
- let stdout;
816
- try {
817
- stdout = execSync(`go run "${scriptPath}" "${filePath}"`, {
818
- timeout: 15e3,
819
- encoding: "utf8",
820
- windowsHide: true
821
- });
822
- } finally {
823
- try {
824
- unlinkSync(scriptPath);
825
- } catch {
826
- }
827
- }
850
+ const stdout = execSync(`go run "${scriptPath}"`, {
851
+ input: content,
852
+ timeout: 15e3,
853
+ encoding: "utf8",
854
+ windowsHide: true
855
+ });
828
856
  if (!stdout.trim()) {
829
857
  return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
830
858
  }
@@ -1061,7 +1089,11 @@ print(json.dumps([s.to_dict() for s in syms]))
1061
1089
  `;
1062
1090
  function syncPyParse(filePath, lang) {
1063
1091
  try {
1064
- const stdout = execSync(`python -c "${PY_PARSE_SCRIPT.replace(/"/g, '\\"')}" "${filePath}"`, {
1092
+ const tmpDir = path4.join(os.tmpdir(), "ws-py-parse");
1093
+ mkdirSync(tmpDir, { recursive: true });
1094
+ const scriptPath = path4.join(tmpDir, "parse.py");
1095
+ writeFileSync(scriptPath, PY_PARSE_SCRIPT, "utf8");
1096
+ const stdout = execSync(`python "${scriptPath}" "${filePath}"`, {
1065
1097
  timeout: 15e3,
1066
1098
  encoding: "utf8",
1067
1099
  windowsHide: true
@@ -1100,9 +1132,12 @@ function parseSymbols4(opts) {
1100
1132
  function checkNativeParser() {
1101
1133
  try {
1102
1134
  execSync("rustc --version", { stdio: "pipe" });
1103
- const toolsDir = path3.join(process.cwd(), "tools");
1135
+ const toolsDir = path4.join(process.cwd(), "tools");
1104
1136
  try {
1105
- execSync("cargo metadata --no-deps --format-version 1 --manifest-path " + path3.join(toolsDir, "Cargo.toml"), { stdio: "pipe" });
1137
+ execSync(
1138
+ "cargo metadata --no-deps --format-version 1 --manifest-path " + path4.join(toolsDir, "Cargo.toml"),
1139
+ { stdio: "pipe" }
1140
+ );
1106
1141
  return true;
1107
1142
  } catch {
1108
1143
  return false;
@@ -1113,17 +1148,21 @@ function checkNativeParser() {
1113
1148
  }
1114
1149
  function tryNativeParse(file, content) {
1115
1150
  try {
1116
- const toolsDir = path3.join(process.cwd(), "tools");
1117
- const crateDir = path3.join(toolsDir, "syn-parser");
1118
- const tmpFile = path3.join(crateDir, "src", "input.rs");
1119
- const { writeFileSync: writeFileSync2 } = __require("node:fs");
1120
- writeFileSync2(tmpFile, content, "utf8");
1121
- const result = spawnSync("cargo", ["run", "--manifest-path", path3.join(toolsDir, "Cargo.toml")], {
1122
- cwd: process.cwd(),
1123
- encoding: "utf8",
1124
- timeout: 15e3,
1125
- stdio: ["pipe", "pipe", "pipe"]
1126
- });
1151
+ const toolsDir = path4.join(process.cwd(), "tools");
1152
+ const crateDir = path4.join(toolsDir, "syn-parser");
1153
+ const tmpFile = path4.join(crateDir, "src", "input.rs");
1154
+ const { writeFileSync: writeFileSync3 } = __require("node:fs");
1155
+ writeFileSync3(tmpFile, content, "utf8");
1156
+ const result = spawnSync(
1157
+ "cargo",
1158
+ ["run", "--manifest-path", path4.join(toolsDir, "Cargo.toml")],
1159
+ {
1160
+ cwd: process.cwd(),
1161
+ encoding: "utf8",
1162
+ timeout: 15e3,
1163
+ stdio: ["pipe", "pipe", "pipe"]
1164
+ }
1165
+ );
1127
1166
  if (result.status === 0 && result.stdout) {
1128
1167
  const symbols = JSON.parse(result.stdout);
1129
1168
  return {
@@ -1157,7 +1196,8 @@ function regexParse(opts) {
1157
1196
  lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
1158
1197
  }
1159
1198
  function lineFromOffset(offset) {
1160
- let lo = 0, hi = lineOffsets.length - 1;
1199
+ let lo = 0;
1200
+ let hi = lineOffsets.length - 1;
1161
1201
  while (lo < hi) {
1162
1202
  const mid = lo + hi + 1 >>> 1;
1163
1203
  if (lineOffsets[mid] <= offset) lo = mid;
@@ -1171,8 +1211,7 @@ function regexParse(opts) {
1171
1211
  }
1172
1212
  for (const pattern of RS_PATTERNS) {
1173
1213
  pattern.regex.lastIndex = 0;
1174
- let match;
1175
- while ((match = pattern.regex.exec(content)) !== null) {
1214
+ for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
1176
1215
  const name = match[1];
1177
1216
  const offset = match.index;
1178
1217
  const line = lineFromOffset(offset);
@@ -1214,7 +1253,7 @@ function parseSymbols5(opts) {
1214
1253
  function regexParse2(opts) {
1215
1254
  const { file, content, lang } = opts;
1216
1255
  const symbols = [];
1217
- const basename2 = path3.basename(file).toLowerCase();
1256
+ const basename2 = path4.basename(file).toLowerCase();
1218
1257
  const isPackageJson = basename2 === "package.json";
1219
1258
  const isTsconfig = basename2 === "tsconfig.json" || basename2 === "tsconfig.build.json";
1220
1259
  const isJsonSchema = content.includes("$schema") || content.includes("$id") || content.includes("$ref");
@@ -1225,7 +1264,8 @@ function regexParse2(opts) {
1225
1264
  lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
1226
1265
  }
1227
1266
  function lineFromOffset(offset) {
1228
- let lo = 0, hi = lineOffsets.length - 1;
1267
+ let lo = 0;
1268
+ let hi = lineOffsets.length - 1;
1229
1269
  while (lo < hi) {
1230
1270
  const mid = lo + hi + 1 >>> 1;
1231
1271
  if (lineOffsets[mid] <= offset) lo = mid;
@@ -1237,19 +1277,20 @@ function regexParse2(opts) {
1237
1277
  if (rootMatch) {
1238
1278
  const offset = rootMatch.index;
1239
1279
  const line = lineFromOffset(offset);
1240
- symbols.push(makeSymbol({
1241
- name: path3.basename(file),
1242
- kind: "object",
1243
- line,
1244
- col: 0,
1245
- signature: `"${path3.basename(file)}" = { ... }`,
1246
- file,
1247
- lang
1248
- }));
1280
+ symbols.push(
1281
+ makeSymbol({
1282
+ name: path4.basename(file),
1283
+ kind: "object",
1284
+ line,
1285
+ col: 0,
1286
+ signature: `"${path4.basename(file)}" = { ... }`,
1287
+ file,
1288
+ lang
1289
+ })
1290
+ );
1249
1291
  }
1250
1292
  const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
1251
- let match;
1252
- while ((match = topLevelKeyRegex.exec(content)) !== null) {
1293
+ for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
1253
1294
  const key = match[1];
1254
1295
  const offset = match.index;
1255
1296
  const line = lineFromOffset(offset);
@@ -1276,15 +1317,17 @@ function regexParse2(opts) {
1276
1317
  signature = `"$ref": "..."`;
1277
1318
  }
1278
1319
  }
1279
- symbols.push(makeSymbol({
1280
- name: key,
1281
- kind,
1282
- line,
1283
- col,
1284
- signature,
1285
- file,
1286
- lang
1287
- }));
1320
+ symbols.push(
1321
+ makeSymbol({
1322
+ name: key,
1323
+ kind,
1324
+ line,
1325
+ col,
1326
+ signature,
1327
+ file,
1328
+ lang
1329
+ })
1330
+ );
1288
1331
  if (isPackageJson && key === "scripts") {
1289
1332
  extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset);
1290
1333
  }
@@ -1293,20 +1336,21 @@ function regexParse2(opts) {
1293
1336
  }
1294
1337
  }
1295
1338
  const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
1296
- let defsMatch;
1297
- while ((defsMatch = defsRegex.exec(content)) !== null) {
1339
+ const defsMatch = defsRegex.exec(content);
1340
+ if (defsMatch !== null) {
1298
1341
  const offset = defsMatch.index;
1299
1342
  const line = lineFromOffset(offset);
1300
- symbols.push(makeSymbol({
1301
- name: "$defs",
1302
- kind: "property",
1303
- line,
1304
- col: offset - (lineOffsets[line - 1] ?? 0),
1305
- signature: '"$defs": { ... }',
1306
- file,
1307
- lang
1308
- }));
1309
- break;
1343
+ symbols.push(
1344
+ makeSymbol({
1345
+ name: "$defs",
1346
+ kind: "property",
1347
+ line,
1348
+ col: offset - (lineOffsets[line - 1] ?? 0),
1349
+ signature: '"$defs": { ... }',
1350
+ file,
1351
+ lang
1352
+ })
1353
+ );
1310
1354
  }
1311
1355
  const defsPatterns = [
1312
1356
  /"\$defs"\s*:/g,
@@ -1316,69 +1360,71 @@ function regexParse2(opts) {
1316
1360
  ];
1317
1361
  for (const pat of defsPatterns) {
1318
1362
  pat.lastIndex = 0;
1319
- while ((match = pat.exec(content)) !== null) {
1363
+ for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
1320
1364
  const offset = match.index;
1321
1365
  const line = lineFromOffset(offset);
1322
1366
  const key = match[0].match(/"([^"]+)"/)?.[1] ?? match[0];
1323
- symbols.push(makeSymbol({
1324
- name: key,
1325
- kind: "property",
1326
- line,
1327
- col: offset - (lineOffsets[line - 1] ?? 0),
1328
- signature: `"${key}": { ... }`,
1329
- file,
1330
- lang
1331
- }));
1367
+ symbols.push(
1368
+ makeSymbol({
1369
+ name: key,
1370
+ kind: "property",
1371
+ line,
1372
+ col: offset - (lineOffsets[line - 1] ?? 0),
1373
+ signature: `"${key}": { ... }`,
1374
+ file,
1375
+ lang
1376
+ })
1377
+ );
1332
1378
  }
1333
1379
  }
1334
1380
  return { file, lang, symbols, mtimeMs: Date.now() };
1335
1381
  }
1336
1382
  function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
1337
1383
  const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
1338
- let match;
1339
- while ((match = scriptsBlockRegex.exec(content)) !== null) {
1384
+ for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
1340
1385
  const blockContent = match[0];
1341
1386
  const blockOffset = match.index;
1342
1387
  const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
1343
- let scriptMatch;
1344
- while ((scriptMatch = scriptKeyRegex.exec(blockContent)) !== null) {
1388
+ for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
1345
1389
  const key = scriptMatch[1];
1346
1390
  const keyOffset = blockOffset + scriptMatch.index;
1347
1391
  const line = lineFromOffset(keyOffset);
1348
- symbols.push(makeSymbol({
1349
- name: key,
1350
- kind: "function",
1351
- line,
1352
- col: keyOffset - (lineOffsets[line - 1] ?? 0),
1353
- signature: `"${key}": "..."`,
1354
- file,
1355
- lang
1356
- }));
1392
+ symbols.push(
1393
+ makeSymbol({
1394
+ name: key,
1395
+ kind: "function",
1396
+ line,
1397
+ col: keyOffset - (lineOffsets[line - 1] ?? 0),
1398
+ signature: `"${key}": "..."`,
1399
+ file,
1400
+ lang
1401
+ })
1402
+ );
1357
1403
  }
1358
1404
  }
1359
1405
  }
1360
1406
  function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
1361
1407
  const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
1362
- let match;
1363
- while ((match = optsBlockRegex.exec(content)) !== null) {
1408
+ for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
1364
1409
  const blockContent = match[0];
1365
1410
  const blockOffset = match.index;
1366
1411
  const optKeyRegex = /"(\w[\w]*)"\s*:/g;
1367
- let optMatch;
1368
- while ((optMatch = optKeyRegex.exec(blockContent)) !== null) {
1412
+ for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
1369
1413
  const key = optMatch[1];
1370
1414
  const keyOffset = blockOffset + optMatch.index;
1371
1415
  const line = lineFromOffset(keyOffset);
1372
1416
  if (line <= parentLine) continue;
1373
- symbols.push(makeSymbol({
1374
- name: key,
1375
- kind: "property",
1376
- line,
1377
- col: keyOffset - (lineOffsets[line - 1] ?? 0),
1378
- signature: `"${key}": ...`,
1379
- file,
1380
- lang
1381
- }));
1417
+ symbols.push(
1418
+ makeSymbol({
1419
+ name: key,
1420
+ kind: "property",
1421
+ line,
1422
+ col: keyOffset - (lineOffsets[line - 1] ?? 0),
1423
+ signature: `"${key}": ...`,
1424
+ file,
1425
+ lang
1426
+ })
1427
+ );
1382
1428
  }
1383
1429
  }
1384
1430
  }
@@ -1416,7 +1462,8 @@ function regexParse3(opts) {
1416
1462
  lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
1417
1463
  }
1418
1464
  function lineFromOffset(offset) {
1419
- let lo = 0, hi = lineOffsets.length - 1;
1465
+ let lo = 0;
1466
+ let hi = lineOffsets.length - 1;
1420
1467
  while (lo < hi) {
1421
1468
  const mid = lo + hi + 1 >>> 1;
1422
1469
  if (lineOffsets[mid] <= offset) lo = mid;
@@ -1425,40 +1472,43 @@ function regexParse3(opts) {
1425
1472
  return lo + 1;
1426
1473
  }
1427
1474
  const anchorRegex = /&(\w[\w-]*)/g;
1428
- let match;
1429
- while ((match = anchorRegex.exec(content)) !== null) {
1475
+ for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
1430
1476
  const name = match[1];
1431
1477
  const offset = match.index;
1432
1478
  const line = lineFromOffset(offset);
1433
1479
  const col = offset - (lineOffsets[line - 1] ?? 0);
1434
- symbols.push(makeSymbol2({
1435
- name,
1436
- kind: "const",
1437
- line,
1438
- col,
1439
- signature: `&${name}`,
1440
- file,
1441
- lang
1442
- }));
1480
+ symbols.push(
1481
+ makeSymbol2({
1482
+ name,
1483
+ kind: "const",
1484
+ line,
1485
+ col,
1486
+ signature: `&${name}`,
1487
+ file,
1488
+ lang
1489
+ })
1490
+ );
1443
1491
  }
1444
1492
  const aliasRegex = /\*(\w[\w-]*)/g;
1445
- while ((match = aliasRegex.exec(content)) !== null) {
1493
+ for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
1446
1494
  const name = match[1];
1447
1495
  const offset = match.index;
1448
1496
  const line = lineFromOffset(offset);
1449
1497
  const col = offset - (lineOffsets[line - 1] ?? 0);
1450
- symbols.push(makeSymbol2({
1451
- name,
1452
- kind: "const",
1453
- line,
1454
- col,
1455
- signature: `*${name}`,
1456
- file,
1457
- lang
1458
- }));
1498
+ symbols.push(
1499
+ makeSymbol2({
1500
+ name,
1501
+ kind: "const",
1502
+ line,
1503
+ col,
1504
+ signature: `*${name}`,
1505
+ file,
1506
+ lang
1507
+ })
1508
+ );
1459
1509
  }
1460
1510
  const kvRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:/gm;
1461
- while ((match = kvRegex.exec(content)) !== null) {
1511
+ for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {
1462
1512
  const indent = match[1].length;
1463
1513
  const key = match[2];
1464
1514
  const offset = match.index;
@@ -1474,38 +1524,42 @@ function regexParse3(opts) {
1474
1524
  symbols.push(makeSymbol2({ name: key, kind, line, col, signature, file, lang }));
1475
1525
  }
1476
1526
  const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
1477
- while ((match = listItemRegex.exec(content)) !== null) {
1527
+ for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
1478
1528
  const key = match[2];
1479
1529
  const offset = match.index;
1480
1530
  const line = lineFromOffset(offset);
1481
1531
  const col = offset - (lineOffsets[line - 1] ?? 0);
1482
1532
  const value = extractValue(content, offset + match[0].length);
1483
1533
  const kind = isScalar(value) ? "literal" : "property";
1484
- symbols.push(makeSymbol2({
1485
- name: key,
1486
- kind,
1487
- line,
1488
- col,
1489
- signature: `- ${key}: ${truncate(value, 60)}`,
1490
- file,
1491
- lang
1492
- }));
1534
+ symbols.push(
1535
+ makeSymbol2({
1536
+ name: key,
1537
+ kind,
1538
+ line,
1539
+ col,
1540
+ signature: `- ${key}: ${truncate(value, 60)}`,
1541
+ file,
1542
+ lang
1543
+ })
1544
+ );
1493
1545
  }
1494
1546
  const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
1495
- while ((match = blockScalarRegex.exec(content)) !== null) {
1547
+ for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
1496
1548
  const key = match[2];
1497
1549
  const offset = match.index;
1498
1550
  const line = lineFromOffset(offset);
1499
1551
  const col = offset - (lineOffsets[line - 1] ?? 0);
1500
- symbols.push(makeSymbol2({
1501
- name: key,
1502
- kind: "property",
1503
- line,
1504
- col,
1505
- signature: `${key}: | ...`,
1506
- file,
1507
- lang
1508
- }));
1552
+ symbols.push(
1553
+ makeSymbol2({
1554
+ name: key,
1555
+ kind: "property",
1556
+ line,
1557
+ col,
1558
+ signature: `${key}: | ...`,
1559
+ file,
1560
+ lang
1561
+ })
1562
+ );
1509
1563
  }
1510
1564
  return { file, lang, symbols, mtimeMs: Date.now() };
1511
1565
  }
@@ -1577,12 +1631,12 @@ async function findSourceFiles(projectRoot, ignore) {
1577
1631
  }
1578
1632
  for (const e of entries) {
1579
1633
  if (ignoreSet.has(e.name)) continue;
1580
- const full = path3.join(dir, e.name);
1634
+ const full = path4.join(dir, e.name);
1581
1635
  if (e.isDirectory()) {
1582
1636
  await walk(full);
1583
1637
  } else if (e.isFile()) {
1584
- const rel = path3.relative(projectRoot, full).replace(/\\/g, "/");
1585
- const ext = path3.extname(e.name);
1638
+ const rel = path4.relative(projectRoot, full).replace(/\\/g, "/");
1639
+ const ext = path4.extname(e.name);
1586
1640
  for (const { ext: extName, pat } of globs) {
1587
1641
  if (ext === extName && (pat.test(rel) || pat.test(e.name))) {
1588
1642
  results.push(full);
@@ -1626,7 +1680,7 @@ async function runIndexer(ctx, opts) {
1626
1680
  let symbolsIndexed = 0;
1627
1681
  let files;
1628
1682
  if (opts.files && opts.files.length > 0) {
1629
- files = opts.files.map((f) => path3.resolve(projectRoot, f));
1683
+ files = opts.files.map((f) => path4.resolve(projectRoot, f));
1630
1684
  } else {
1631
1685
  files = await findSourceFiles(projectRoot, ignore);
1632
1686
  }