@proxysoul/soulforge 2.9.3 → 2.10.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.
@@ -17293,6 +17293,60 @@ var init_dist7 = __esm(() => {
17293
17293
  __reExport(src_exports, bundle_full_exports);
17294
17294
  });
17295
17295
 
17296
+ // src/core/utils/ensure-soulforge-dir.ts
17297
+ import { execSync } from "child_process";
17298
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
17299
+ import { join } from "path";
17300
+ function ensureSoulforgeDir(cwd) {
17301
+ const dir = join(cwd, ENTRY);
17302
+ if (!existsSync(dir))
17303
+ mkdirSync(dir, {
17304
+ recursive: true
17305
+ });
17306
+ if (!patched.has(cwd)) {
17307
+ patched.add(cwd);
17308
+ try {
17309
+ ensureGitignore(cwd);
17310
+ } catch {}
17311
+ }
17312
+ return dir;
17313
+ }
17314
+ function ensureGitignore(cwd) {
17315
+ const status = gitCheckIgnoreStatus(cwd);
17316
+ if (status !== 1)
17317
+ return;
17318
+ const gitignorePath = join(cwd, ".gitignore");
17319
+ if (existsSync(gitignorePath)) {
17320
+ const content = readFileSync(gitignorePath, "utf-8");
17321
+ const eol = content.includes(`\r
17322
+ `) ? `\r
17323
+ ` : `
17324
+ `;
17325
+ const prefix = content.length > 0 && !content.endsWith(`
17326
+ `) ? eol : "";
17327
+ appendFileSync(gitignorePath, `${prefix}.soulforge${eol}`);
17328
+ } else {
17329
+ writeFileSync(gitignorePath, `.soulforge
17330
+ `);
17331
+ }
17332
+ }
17333
+ function gitCheckIgnoreStatus(cwd) {
17334
+ try {
17335
+ execSync("git check-ignore -q .soulforge", {
17336
+ cwd,
17337
+ stdio: "pipe",
17338
+ timeout: 3000
17339
+ });
17340
+ return 0;
17341
+ } catch (err2) {
17342
+ return err2.status ?? 128;
17343
+ }
17344
+ }
17345
+ var ENTRY = ".soulforge", patched;
17346
+ var init_ensure_soulforge_dir = __esm(() => {
17347
+ patched = new Set;
17348
+ });
17349
+
17296
17350
  // src/core/security/forbidden.ts
17297
17351
  var exports_forbidden = {};
17298
17352
  __export(exports_forbidden, {
@@ -17306,9 +17360,9 @@ __export(exports_forbidden, {
17306
17360
  addSessionPattern: () => addSessionPattern,
17307
17361
  addProjectPattern: () => addProjectPattern
17308
17362
  });
17309
- import { existsSync, readFileSync, realpathSync, watch, writeFileSync } from "fs";
17363
+ import { existsSync as existsSync2, readFileSync as readFileSync2, realpathSync, watch, writeFileSync as writeFileSync2 } from "fs";
17310
17364
  import { homedir } from "os";
17311
- import { basename as basename2, join, resolve } from "path";
17365
+ import { basename as basename2, join as join2, resolve } from "path";
17312
17366
  function globToRegex(pattern) {
17313
17367
  const cached = regexCache.get(pattern);
17314
17368
  if (cached)
@@ -17320,9 +17374,9 @@ function globToRegex(pattern) {
17320
17374
  }
17321
17375
  function loadPatternsFromFile(filePath) {
17322
17376
  try {
17323
- if (!existsSync(filePath))
17377
+ if (!existsSync2(filePath))
17324
17378
  return [];
17325
- const raw2 = readFileSync(filePath, "utf-8");
17379
+ const raw2 = readFileSync2(filePath, "utf-8");
17326
17380
  const parsed = JSON.parse(raw2);
17327
17381
  return Array.isArray(parsed.patterns) ? parsed.patterns : [];
17328
17382
  } catch {
@@ -17331,9 +17385,9 @@ function loadPatternsFromFile(filePath) {
17331
17385
  }
17332
17386
  function parseIgnoreFile(filePath) {
17333
17387
  try {
17334
- if (!existsSync(filePath))
17388
+ if (!existsSync2(filePath))
17335
17389
  return [];
17336
- const content = readFileSync(filePath, "utf-8");
17390
+ const content = readFileSync2(filePath, "utf-8");
17337
17391
  return content.split(`
17338
17392
  `).map((l3) => l3.trim()).filter((l3) => l3.length > 0 && !l3.startsWith("#"));
17339
17393
  } catch {
@@ -17341,18 +17395,18 @@ function parseIgnoreFile(filePath) {
17341
17395
  }
17342
17396
  }
17343
17397
  function initForbidden(cwd) {
17344
- const globalFile = join(homedir(), ".soulforge", "forbidden.json");
17345
- const projectFile = join(cwd, ".soulforge", "forbidden.json");
17398
+ const globalFile = join2(homedir(), ".soulforge", "forbidden.json");
17399
+ const projectFile = join2(cwd, ".soulforge", "forbidden.json");
17346
17400
  globalPatterns = loadPatternsFromFile(globalFile);
17347
17401
  projectPatterns = loadPatternsFromFile(projectFile);
17348
17402
  sessionPatternsMap.clear();
17349
- const aiIgnorePath = join(cwd, ".aiignore");
17403
+ const aiIgnorePath = join2(cwd, ".aiignore");
17350
17404
  aiIgnorePatterns = parseIgnoreFile(aiIgnorePath);
17351
17405
  if (aiIgnoreWatcher) {
17352
17406
  aiIgnoreWatcher.close();
17353
17407
  aiIgnoreWatcher = null;
17354
17408
  }
17355
- if (existsSync(aiIgnorePath)) {
17409
+ if (existsSync2(aiIgnorePath)) {
17356
17410
  try {
17357
17411
  aiIgnoreWatcher = watch(aiIgnorePath, () => {
17358
17412
  aiIgnorePatterns = parseIgnoreFile(aiIgnorePath);
@@ -17385,28 +17439,23 @@ function clearTabSessionPatterns(tabId) {
17385
17439
  sessionPatternsMap.delete(tabId);
17386
17440
  }
17387
17441
  function addProjectPattern(cwd, pattern) {
17388
- const filePath = join(cwd, ".soulforge", "forbidden.json");
17442
+ const filePath = join2(cwd, ".soulforge", "forbidden.json");
17389
17443
  const existing = loadPatternsFromFile(filePath);
17390
17444
  if (!existing.includes(pattern)) {
17391
17445
  existing.push(pattern);
17392
- const {
17393
- mkdirSync
17394
- } = __require("fs");
17395
- mkdirSync(join(cwd, ".soulforge"), {
17396
- recursive: true
17397
- });
17398
- writeFileSync(filePath, JSON.stringify({
17446
+ ensureSoulforgeDir(cwd);
17447
+ writeFileSync2(filePath, JSON.stringify({
17399
17448
  patterns: existing
17400
17449
  }, null, 2));
17401
17450
  projectPatterns = existing;
17402
17451
  }
17403
17452
  }
17404
17453
  function removeProjectPattern(cwd, pattern) {
17405
- const filePath = join(cwd, ".soulforge", "forbidden.json");
17454
+ const filePath = join2(cwd, ".soulforge", "forbidden.json");
17406
17455
  const existing = loadPatternsFromFile(filePath);
17407
17456
  const updated = existing.filter((p2) => p2 !== pattern);
17408
17457
  if (updated.length !== existing.length) {
17409
- writeFileSync(filePath, JSON.stringify({
17458
+ writeFileSync2(filePath, JSON.stringify({
17410
17459
  patterns: updated
17411
17460
  }, null, 2));
17412
17461
  projectPatterns = updated;
@@ -17462,6 +17511,7 @@ function buildForbiddenContext(tabId) {
17462
17511
  }
17463
17512
  var BUILTIN_PATTERNS, globalPatterns, projectPatterns, sessionPatternsMap, aiIgnorePatterns, initialized = false, aiIgnoreWatcher = null, regexCache;
17464
17513
  var init_forbidden = __esm(() => {
17514
+ init_ensure_soulforge_dir();
17465
17515
  BUILTIN_PATTERNS = [
17466
17516
  ".env",
17467
17517
  ".env.*",
@@ -18553,7 +18603,7 @@ __export(exports_file_tree, {
18553
18603
  IGNORED_DIRS: () => IGNORED_DIRS
18554
18604
  });
18555
18605
  import { readdirSync } from "fs";
18556
- import { join as join2 } from "path";
18606
+ import { join as join3 } from "path";
18557
18607
  function walkDir(dir, prefix, depth, lines) {
18558
18608
  if (depth <= 0)
18559
18609
  return;
@@ -18573,7 +18623,7 @@ function walkDir(dir, prefix, depth, lines) {
18573
18623
  const childPrefix = isLast ? " " : "\u2502 ";
18574
18624
  lines.push(`${prefix}${connector}${entry.name}${entry.isDirectory() ? "/" : ""}`);
18575
18625
  if (entry.isDirectory()) {
18576
- walkDir(join2(dir, entry.name), prefix + childPrefix, depth - 1, lines);
18626
+ walkDir(join3(dir, entry.name), prefix + childPrefix, depth - 1, lines);
18577
18627
  }
18578
18628
  }
18579
18629
  } catch {}
@@ -18586,7 +18636,7 @@ var init_file_tree = __esm(() => {
18586
18636
  // src/core/intelligence/repo-map-utils.ts
18587
18637
  import { readdir, stat } from "fs/promises";
18588
18638
  import { homedir as homedir2 } from "os";
18589
- import { extname, join as join3, resolve as resolve2 } from "path";
18639
+ import { extname, join as join4, resolve as resolve2 } from "path";
18590
18640
  function barrelToDir(barrelPath) {
18591
18641
  return barrelPath.replace(BARREL_RE, "");
18592
18642
  }
@@ -18801,7 +18851,7 @@ async function collectFilesViaGit(dir) {
18801
18851
  const ext = extname(line).toLowerCase();
18802
18852
  if (!(ext in INDEXABLE_EXTENSIONS))
18803
18853
  continue;
18804
- const fullPath = join3(dir, line);
18854
+ const fullPath = join4(dir, line);
18805
18855
  if (isForbidden(fullPath))
18806
18856
  continue;
18807
18857
  try {
@@ -18835,7 +18885,7 @@ async function collectFilesWalk(dir, depth, counter, out2) {
18835
18885
  break;
18836
18886
  if (entry.name.startsWith(".") && entry.name !== ".")
18837
18887
  continue;
18838
- const fullPath = join3(dir, entry.name);
18888
+ const fullPath = join4(dir, entry.name);
18839
18889
  if (entry.isDirectory()) {
18840
18890
  if (!IGNORED_DIRS.has(entry.name)) {
18841
18891
  await collectFilesWalk(fullPath, depth + 1, ctx, files);
@@ -22241,10 +22291,10 @@ var exports_tree_sitter2 = {};
22241
22291
  __export(exports_tree_sitter2, {
22242
22292
  TreeSitterBackend: () => TreeSitterBackend
22243
22293
  });
22244
- import { existsSync as existsSync2 } from "fs";
22294
+ import { existsSync as existsSync3 } from "fs";
22245
22295
  import { readFile } from "fs/promises";
22246
22296
  import { homedir as homedir3 } from "os";
22247
- import { dirname, join as join4, resolve as resolve3 } from "path";
22297
+ import { dirname, join as join5, resolve as resolve3 } from "path";
22248
22298
  function extractImportSpecifiers(node, language) {
22249
22299
  const specifiers = [];
22250
22300
  collectSpecifiers(node, language, specifiers);
@@ -22483,7 +22533,7 @@ function createQuery(lang254, source) {
22483
22533
  var BUNDLED_WASM_DIR, QUERIES, GRAMMAR_FILES, HEADER_EXTS, TSQueryClass = null, TreeSitterBackend;
22484
22534
  var init_tree_sitter2 = __esm(() => {
22485
22535
  init_types2();
22486
- BUNDLED_WASM_DIR = join4(homedir3(), ".soulforge", "wasm");
22536
+ BUNDLED_WASM_DIR = join5(homedir3(), ".soulforge", "wasm");
22487
22537
  QUERIES = {
22488
22538
  typescript: `
22489
22539
  (function_declaration name: (identifier) @name) @func
@@ -23388,13 +23438,13 @@ var init_tree_sitter2 = __esm(() => {
23388
23438
  resolveWasm(filename) {
23389
23439
  const basename3 = filename.split("/").pop() ?? filename;
23390
23440
  if (TreeSitterBackend.IS_BUNDLED) {
23391
- return join4(BUNDLED_WASM_DIR, basename3);
23441
+ return join5(BUNDLED_WASM_DIR, basename3);
23392
23442
  }
23393
23443
  let dir = import.meta.dir;
23394
23444
  for (let i4 = 0;i4 < 5; i4++) {
23395
23445
  for (const sub of ["node_modules/web-tree-sitter", "node_modules/tree-sitter-wasms/out"]) {
23396
- const p2 = join4(dir, sub, basename3);
23397
- if (existsSync2(p2))
23446
+ const p2 = join5(dir, sub, basename3);
23447
+ if (existsSync3(p2))
23398
23448
  return p2;
23399
23449
  }
23400
23450
  const parent = dirname(dir);
@@ -23402,14 +23452,14 @@ var init_tree_sitter2 = __esm(() => {
23402
23452
  break;
23403
23453
  dir = parent;
23404
23454
  }
23405
- return join4(BUNDLED_WASM_DIR, basename3);
23455
+ return join5(BUNDLED_WASM_DIR, basename3);
23406
23456
  }
23407
23457
  async doInit() {
23408
23458
  let wasmPath = this.resolveWasm("tree-sitter.wasm");
23409
- if (!existsSync2(wasmPath)) {
23459
+ if (!existsSync3(wasmPath)) {
23410
23460
  wasmPath = this.resolveWasm("web-tree-sitter.wasm");
23411
23461
  }
23412
- if (!existsSync2(wasmPath)) {
23462
+ if (!existsSync3(wasmPath)) {
23413
23463
  throw new Error(`tree-sitter.wasm not found in ${BUNDLED_WASM_DIR} or node_modules`);
23414
23464
  }
23415
23465
  const mod = await Promise.resolve().then(() => (init_tree_sitter(), exports_tree_sitter));
@@ -24138,10 +24188,10 @@ __export(exports_repo_map, {
24138
24188
  RepoMap: () => RepoMap
24139
24189
  });
24140
24190
  import { Database } from "bun:sqlite";
24141
- import { execSync } from "child_process";
24142
- import { chmodSync, existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, statSync } from "fs";
24191
+ import { execSync as execSync2 } from "child_process";
24192
+ import { chmodSync, existsSync as existsSync4, readFileSync as readFileSync3, statSync } from "fs";
24143
24193
  import { stat as statAsync } from "fs/promises";
24144
- import { dirname as dirname2, extname as extname2, join as join5, relative, resolve as resolve4 } from "path";
24194
+ import { dirname as dirname2, extname as extname2, join as join6, relative, resolve as resolve4 } from "path";
24145
24195
 
24146
24196
  class RepoMap {
24147
24197
  db;
@@ -24167,12 +24217,8 @@ class RepoMap {
24167
24217
  lastRenderedPaths = [];
24168
24218
  constructor(cwd) {
24169
24219
  this.cwd = cwd;
24170
- const dbDir = join5(cwd, ".soulforge");
24171
- if (!existsSync3(dbDir))
24172
- mkdirSync(dbDir, {
24173
- recursive: true
24174
- });
24175
- const dbPath = join5(dbDir, "repomap.db");
24220
+ const dbDir = ensureSoulforgeDir(cwd);
24221
+ const dbPath = join6(dbDir, "repomap.db");
24176
24222
  this.db = new Database(dbPath);
24177
24223
  this.db.run("PRAGMA journal_mode = WAL");
24178
24224
  this.db.run("PRAGMA busy_timeout = 5000");
@@ -24601,7 +24647,7 @@ class RepoMap {
24601
24647
  let lineCount = 0;
24602
24648
  let content;
24603
24649
  try {
24604
- content = readFileSync2(absPath, "utf-8");
24650
+ content = readFileSync3(absPath, "utf-8");
24605
24651
  lineCount = content.split(`
24606
24652
  `).length;
24607
24653
  } catch {
@@ -24857,7 +24903,7 @@ class RepoMap {
24857
24903
  if (this.goModulePrefix !== undefined)
24858
24904
  return this.goModulePrefix;
24859
24905
  try {
24860
- const goMod = readFileSync2(join5(this.cwd, "go.mod"), "utf-8");
24906
+ const goMod = readFileSync3(join6(this.cwd, "go.mod"), "utf-8");
24861
24907
  const match = goMod.match(/^module\s+(\S+)/m);
24862
24908
  this.goModulePrefix = match?.[1] ?? null;
24863
24909
  } catch {
@@ -24871,7 +24917,7 @@ class RepoMap {
24871
24917
  this.tsconfigPaths = null;
24872
24918
  for (const name2 of ["tsconfig.json", "jsconfig.json"]) {
24873
24919
  try {
24874
- const raw2 = readFileSync2(join5(this.cwd, name2), "utf-8");
24920
+ const raw2 = readFileSync3(join6(this.cwd, name2), "utf-8");
24875
24921
  const config = JSON.parse(raw2);
24876
24922
  const paths = config?.compilerOptions?.paths;
24877
24923
  if (paths && typeof paths === "object") {
@@ -24965,21 +25011,21 @@ class RepoMap {
24965
25011
  }
24966
25012
  resolveRelPath(relBase) {
24967
25013
  const stripped = relBase.replace(/\.(m?js|cjs|jsx)$/, "");
24968
- const base = join5(this.cwd, stripped);
25014
+ const base = join6(this.cwd, stripped);
24969
25015
  const candidates = [base];
24970
25016
  if (stripped !== relBase)
24971
- candidates.push(join5(this.cwd, relBase));
25017
+ candidates.push(join6(this.cwd, relBase));
24972
25018
  const ext = extname2(stripped);
24973
25019
  if (!ext) {
24974
25020
  for (const tryExt of Object.keys(INDEXABLE_EXTENSIONS)) {
24975
25021
  candidates.push(base + tryExt);
24976
25022
  }
24977
25023
  for (const tryExt of [".ts", ".tsx", ".js", ".jsx", ".py", ".rb", ".php"]) {
24978
- candidates.push(join5(base, `index${tryExt}`));
25024
+ candidates.push(join6(base, `index${tryExt}`));
24979
25025
  }
24980
- candidates.push(join5(base, "__init__.py"));
24981
- candidates.push(join5(base, "mod.rs"));
24982
- candidates.push(join5(base, "lib.rs"));
25026
+ candidates.push(join6(base, "__init__.py"));
25027
+ candidates.push(join6(base, "mod.rs"));
25028
+ candidates.push(join6(base, "lib.rs"));
24983
25029
  candidates.push(`${base}.go`);
24984
25030
  }
24985
25031
  for (const candidate of candidates) {
@@ -25050,7 +25096,7 @@ class RepoMap {
25050
25096
  const fileRow = getFilePath.get(ref.file_id);
25051
25097
  if (!fileRow)
25052
25098
  continue;
25053
- const absPath = join5(this.cwd, fileRow.path);
25099
+ const absPath = join6(this.cwd, fileRow.path);
25054
25100
  const resolved = this.resolveImportSource(ref.import_source, absPath);
25055
25101
  if (resolved !== null) {
25056
25102
  update.run(resolved, ref.rowid);
@@ -25270,7 +25316,7 @@ class RepoMap {
25270
25316
  const update = this.db.prepare("UPDATE symbols SET qualified_name = ? WHERE id = ?");
25271
25317
  let enriched = 0;
25272
25318
  for (const file of files) {
25273
- const absPath = join5(this.cwd, file.path);
25319
+ const absPath = join6(this.cwd, file.path);
25274
25320
  let raw2;
25275
25321
  try {
25276
25322
  raw2 = await documentSymbols2(absPath);
@@ -25563,7 +25609,7 @@ class RepoMap {
25563
25609
  if (this.hasGit !== null)
25564
25610
  return this.hasGit;
25565
25611
  try {
25566
- execSync("git rev-parse --git-dir", {
25612
+ execSync2("git rev-parse --git-dir", {
25567
25613
  cwd: this.cwd,
25568
25614
  stdio: "pipe",
25569
25615
  timeout: 3000
@@ -25679,8 +25725,8 @@ class RepoMap {
25679
25725
  return this.entryPointsCache;
25680
25726
  this.entryPointsCache = [];
25681
25727
  try {
25682
- const pkgPath = join5(this.cwd, "package.json");
25683
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
25728
+ const pkgPath = join6(this.cwd, "package.json");
25729
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
25684
25730
  for (const field of ["module", "main", "source"]) {
25685
25731
  if (typeof pkg[field] === "string") {
25686
25732
  this.entryPointsCache.push(pkg[field].replace(/^\.\//, ""));
@@ -25716,7 +25762,7 @@ class RepoMap {
25716
25762
  "config.ru"
25717
25763
  ];
25718
25764
  for (const p2 of commonEntryPoints) {
25719
- if (existsSync3(join5(this.cwd, p2)))
25765
+ if (existsSync4(join6(this.cwd, p2)))
25720
25766
  this.entryPointsCache.push(p2);
25721
25767
  }
25722
25768
  return this.entryPointsCache;
@@ -25791,7 +25837,7 @@ class RepoMap {
25791
25837
  let lines = fileCache.get(row.path);
25792
25838
  if (!lines) {
25793
25839
  try {
25794
- const content = readFileSync2(join5(this.cwd, row.path), "utf-8");
25840
+ const content = readFileSync3(join6(this.cwd, row.path), "utf-8");
25795
25841
  lines = content.split(`
25796
25842
  `);
25797
25843
  fileCache.set(row.path, lines);
@@ -25874,11 +25920,11 @@ class RepoMap {
25874
25920
  const cachedMtime = existingById.get(sym.sym_id) ?? existingByKey.get(`${sym.file_path}\x00${sym.name}`);
25875
25921
  if (cachedMtime === sym.file_mtime)
25876
25922
  continue;
25877
- const absPath = join5(this.cwd, sym.file_path);
25923
+ const absPath = join6(this.cwd, sym.file_path);
25878
25924
  let code = "";
25879
25925
  let lineSpan = sym.end_line - sym.line;
25880
25926
  try {
25881
- const content = readFileSync2(absPath, "utf-8");
25927
+ const content = readFileSync3(absPath, "utf-8");
25882
25928
  const lines = content.split(`
25883
25929
  `);
25884
25930
  const startLine = Math.max(0, sym.line - 1);
@@ -26057,7 +26103,7 @@ class RepoMap {
26057
26103
  return;
26058
26104
  const files = this.db.query("SELECT path, mtime_ms FROM files").all();
26059
26105
  for (const f3 of files) {
26060
- const absPath = join5(this.cwd, f3.path);
26106
+ const absPath = join6(this.cwd, f3.path);
26061
26107
  try {
26062
26108
  const st = statSync(absPath);
26063
26109
  if (st.mtimeMs !== f3.mtime_ms) {
@@ -26079,7 +26125,7 @@ class RepoMap {
26079
26125
  for (let i4 = 0;i4 < filesWithImports.length; i4++) {
26080
26126
  const file = filesWithImports[i4];
26081
26127
  try {
26082
- const content = readFileSync2(join5(this.cwd, file.path), "utf-8");
26128
+ const content = readFileSync3(join6(this.cwd, file.path), "utf-8");
26083
26129
  fileContents.set(file.id, content.split(`
26084
26130
  `));
26085
26131
  } catch {}
@@ -26526,7 +26572,7 @@ class RepoMap {
26526
26572
  const results = [];
26527
26573
  const seenPaths = new Set;
26528
26574
  for (const row of rows) {
26529
- const absPath = join5(this.cwd, row.path);
26575
+ const absPath = join6(this.cwd, row.path);
26530
26576
  if (seenPaths.has(absPath))
26531
26577
  continue;
26532
26578
  seenPaths.add(absPath);
@@ -26620,7 +26666,7 @@ class RepoMap {
26620
26666
  if (seen.has(key2))
26621
26667
  continue;
26622
26668
  seen.add(key2);
26623
- const absPath = join5(this.cwd, row.path);
26669
+ const absPath = join6(this.cwd, row.path);
26624
26670
  try {
26625
26671
  const stat2 = statSync(absPath);
26626
26672
  if (Math.abs(stat2.mtimeMs - row.mtime_ms) > 1000)
@@ -26674,7 +26720,7 @@ class RepoMap {
26674
26720
  const rows = this.db.query("SELECT path, mtime_ms FROM files WHERE path LIKE ? ESCAPE '\\' ORDER BY pagerank DESC LIMIT ?").all(likePattern, limit);
26675
26721
  const results = [];
26676
26722
  for (const row of rows) {
26677
- const absPath = join5(this.cwd, row.path);
26723
+ const absPath = join6(this.cwd, row.path);
26678
26724
  try {
26679
26725
  const stat2 = statSync(absPath);
26680
26726
  if (Math.abs(stat2.mtimeMs - row.mtime_ms) > 1000)
@@ -26755,7 +26801,7 @@ class RepoMap {
26755
26801
  return trackable.map((row) => {
26756
26802
  let usedInternally = false;
26757
26803
  try {
26758
- const raw2 = readFileSync2(join5(this.cwd, row.path), "utf-8");
26804
+ const raw2 = readFileSync3(join6(this.cwd, row.path), "utf-8");
26759
26805
  const content = raw2.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/(["'`])(?:(?!\1|\\).|\\.)*\1/g, "").replace(/^\s*export\s+(type\s+)?\{[^}]*\}/gm, "");
26760
26806
  const re3 = new RegExp(`\\b${escaped(row.name)}\\b`, "g");
26761
26807
  const matches2 = content.match(re3);
@@ -26842,7 +26888,7 @@ class RepoMap {
26842
26888
  const importerDir = ref.file_path.substring(0, ref.file_path.lastIndexOf("/")) || ".";
26843
26889
  let resolved = ref.import_source;
26844
26890
  if (resolved.startsWith(".")) {
26845
- resolved = join5(importerDir, resolved).replace(/\\/g, "/");
26891
+ resolved = join6(importerDir, resolved).replace(/\\/g, "/");
26846
26892
  } else {
26847
26893
  const segments = resolved.replace(/^crate::/, "").split(/[:./]/);
26848
26894
  for (const seg of segments) {
@@ -27430,6 +27476,7 @@ class RepoMap {
27430
27476
  }
27431
27477
  }
27432
27478
  var init_repo_map = __esm(() => {
27479
+ init_ensure_soulforge_dir();
27433
27480
  init_clone_detection();
27434
27481
  init_repo_map_constants();
27435
27482
  init_repo_map_utils();
@@ -27487,8 +27534,8 @@ var exports_router = {};
27487
27534
  __export(exports_router, {
27488
27535
  CodeIntelligenceRouter: () => CodeIntelligenceRouter
27489
27536
  });
27490
- import { existsSync as existsSync4, readdirSync as readdirSync2 } from "fs";
27491
- import { extname as extname3, join as join6 } from "path";
27537
+ import { existsSync as existsSync5, readdirSync as readdirSync2 } from "fs";
27538
+ import { extname as extname3, join as join7 } from "path";
27492
27539
 
27493
27540
  class CodeIntelligenceRouter {
27494
27541
  backends = [];
@@ -27521,7 +27568,7 @@ class CodeIntelligenceRouter {
27521
27568
  if (this.detectedLanguage)
27522
27569
  return this.detectedLanguage;
27523
27570
  for (const [configFile, lang254] of Object.entries(PROJECT_FILE_TO_LANGUAGE)) {
27524
- if (existsSync4(join6(this.cwd, configFile))) {
27571
+ if (existsSync5(join7(this.cwd, configFile))) {
27525
27572
  this.detectedLanguage = lang254;
27526
27573
  return lang254;
27527
27574
  }
@@ -27646,7 +27693,7 @@ class CodeIntelligenceRouter {
27646
27693
  if (this.config.language)
27647
27694
  add(this.config.language);
27648
27695
  for (const [configFile, lang254] of Object.entries(PROJECT_FILE_TO_LANGUAGE)) {
27649
- if (existsSync4(join6(this.cwd, configFile)))
27696
+ if (existsSync5(join7(this.cwd, configFile)))
27650
27697
  add(lang254);
27651
27698
  }
27652
27699
  const SKIP = new Set(["node_modules", ".git", "dist", "build", "out", "vendor", "__pycache__", ".venv", "venv", "target", ".next", ".nuxt", ".output", "coverage", ".turbo", ".cache"]);
@@ -27682,7 +27729,7 @@ class CodeIntelligenceRouter {
27682
27729
  for (const entry of entries) {
27683
27730
  if (entry.isDirectory() && !SKIP.has(entry.name) && !entry.name.startsWith(".")) {
27684
27731
  queue.push({
27685
- dir: join6(item.dir, entry.name),
27732
+ dir: join7(item.dir, entry.name),
27686
27733
  depth: item.depth + 1
27687
27734
  });
27688
27735
  }
@@ -27719,14 +27766,14 @@ class CodeIntelligenceRouter {
27719
27766
  });
27720
27767
  for (const entry of entries) {
27721
27768
  if (entry.isFile() && exts.some((ext) => entry.name.endsWith(ext))) {
27722
- return join6(item.dir, entry.name);
27769
+ return join7(item.dir, entry.name);
27723
27770
  }
27724
27771
  }
27725
27772
  if (item.depth < MAX_DEPTH2) {
27726
27773
  for (const entry of entries) {
27727
27774
  if (entry.isDirectory() && !SKIP.has(entry.name) && !entry.name.startsWith(".")) {
27728
27775
  queue.push({
27729
- dir: join6(item.dir, entry.name),
27776
+ dir: join7(item.dir, entry.name),
27730
27777
  depth: item.depth + 1
27731
27778
  });
27732
27779
  }
@@ -28174,22 +28221,22 @@ var init_protocol = __esm(() => {
28174
28221
  });
28175
28222
 
28176
28223
  // src/config/index.ts
28177
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
28224
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
28178
28225
  import { homedir as homedir4 } from "os";
28179
- import { join as join7 } from "path";
28226
+ import { join as join8 } from "path";
28180
28227
  function loadConfig() {
28181
- if (!existsSync5(CONFIG_DIR)) {
28228
+ if (!existsSync6(CONFIG_DIR)) {
28182
28229
  mkdirSync2(CONFIG_DIR, {
28183
28230
  recursive: true,
28184
28231
  mode: 448
28185
28232
  });
28186
28233
  }
28187
- if (!existsSync5(CONFIG_FILE)) {
28188
- writeFileSync2(CONFIG_FILE, JSON.stringify(DEFAULT_CONFIG, null, 2));
28234
+ if (!existsSync6(CONFIG_FILE)) {
28235
+ writeFileSync3(CONFIG_FILE, JSON.stringify(DEFAULT_CONFIG, null, 2));
28189
28236
  return DEFAULT_CONFIG;
28190
28237
  }
28191
28238
  try {
28192
- const raw2 = readFileSync3(CONFIG_FILE, "utf-8");
28239
+ const raw2 = readFileSync4(CONFIG_FILE, "utf-8");
28193
28240
  return {
28194
28241
  ...DEFAULT_CONFIG,
28195
28242
  ...JSON.parse(raw2)
@@ -28201,11 +28248,11 @@ function loadConfig() {
28201
28248
  }
28202
28249
  }
28203
28250
  function loadProjectConfig(cwd) {
28204
- const projectFile = join7(cwd, ".soulforge", "config.json");
28205
- if (!existsSync5(projectFile))
28251
+ const projectFile = join8(cwd, ".soulforge", "config.json");
28252
+ if (!existsSync6(projectFile))
28206
28253
  return null;
28207
28254
  try {
28208
- const raw2 = readFileSync3(projectFile, "utf-8");
28255
+ const raw2 = readFileSync4(projectFile, "utf-8");
28209
28256
  return JSON.parse(raw2);
28210
28257
  } catch (err2) {
28211
28258
  process.stderr.write(`[soulforge] Failed to parse ${projectFile}: ${err2 instanceof Error ? err2.message : String(err2)} \u2014 ignoring project config
@@ -28215,8 +28262,9 @@ function loadProjectConfig(cwd) {
28215
28262
  }
28216
28263
  var CONFIG_DIR, CONFIG_FILE, DEFAULT_CONFIG;
28217
28264
  var init_config = __esm(() => {
28218
- CONFIG_DIR = join7(homedir4(), ".soulforge");
28219
- CONFIG_FILE = join7(CONFIG_DIR, "config.json");
28265
+ init_ensure_soulforge_dir();
28266
+ CONFIG_DIR = join8(homedir4(), ".soulforge");
28267
+ CONFIG_FILE = join8(CONFIG_DIR, "config.json");
28220
28268
  DEFAULT_CONFIG = {
28221
28269
  defaultModel: "none",
28222
28270
  routerRules: [],
@@ -28256,13 +28304,13 @@ var init_config = __esm(() => {
28256
28304
  });
28257
28305
 
28258
28306
  // src/core/intelligence/backends/lsp/server-registry.ts
28259
- import { execSync as execSync2 } from "child_process";
28260
- import { existsSync as existsSync6 } from "fs";
28307
+ import { execSync as execSync3 } from "child_process";
28308
+ import { existsSync as existsSync7 } from "fs";
28261
28309
  import { homedir as homedir5 } from "os";
28262
- import { join as join8 } from "path";
28310
+ import { join as join9 } from "path";
28263
28311
  function commandExists(cmd) {
28264
28312
  try {
28265
- execSync2(`command -v ${cmd}`, {
28313
+ execSync3(`command -v ${cmd}`, {
28266
28314
  stdio: "ignore"
28267
28315
  });
28268
28316
  return true;
@@ -28271,15 +28319,15 @@ function commandExists(cmd) {
28271
28319
  }
28272
28320
  }
28273
28321
  function commandExistsInMason(cmd) {
28274
- const fullPath = join8(MASON_BIN_DIR, cmd);
28275
- return existsSync6(fullPath) ? fullPath : null;
28322
+ const fullPath = join9(MASON_BIN_DIR, cmd);
28323
+ return existsSync7(fullPath) ? fullPath : null;
28276
28324
  }
28277
28325
  function findInSoulforge(cmd) {
28278
- const npmBin = join8(SOULFORGE_BIN_DIR, "node_modules", ".bin", cmd);
28279
- if (existsSync6(npmBin))
28326
+ const npmBin = join9(SOULFORGE_BIN_DIR, "node_modules", ".bin", cmd);
28327
+ if (existsSync7(npmBin))
28280
28328
  return npmBin;
28281
- const directBin = join8(SOULFORGE_BIN_DIR, "bin", cmd);
28282
- if (existsSync6(directBin))
28329
+ const directBin = join9(SOULFORGE_BIN_DIR, "bin", cmd);
28330
+ if (existsSync7(directBin))
28283
28331
  return directBin;
28284
28332
  return null;
28285
28333
  }
@@ -28482,8 +28530,8 @@ var init_server_registry = __esm(() => {
28482
28530
  args: ["--stdio"]
28483
28531
  }]
28484
28532
  };
28485
- MASON_BIN_DIR = join8(homedir5(), ".local", "share", "soulforge", "mason", "bin");
28486
- SOULFORGE_BIN_DIR = join8(homedir5(), ".soulforge", "lsp-servers");
28533
+ MASON_BIN_DIR = join9(homedir5(), ".local", "share", "soulforge", "mason", "bin");
28534
+ SOULFORGE_BIN_DIR = join9(homedir5(), ".soulforge", "lsp-servers");
28487
28535
  probeCache = new Map;
28488
28536
  });
28489
28537
 
@@ -29329,7 +29377,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
29329
29377
  exports.useTransition = function() {
29330
29378
  return resolveDispatcher().useTransition();
29331
29379
  };
29332
- exports.version = "19.2.4";
29380
+ exports.version = "19.2.5";
29333
29381
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
29334
29382
  })();
29335
29383
  });
@@ -29426,9 +29474,10 @@ function trackProcess(proc) {
29426
29474
  tracked.add(proc);
29427
29475
  proc.on("exit", () => tracked.delete(proc));
29428
29476
  }
29429
- var tracked;
29477
+ var tracked, trackedBun;
29430
29478
  var init_process_tracker = __esm(() => {
29431
29479
  tracked = new Set;
29480
+ trackedBun = new Set;
29432
29481
  });
29433
29482
 
29434
29483
  // src/core/intelligence/backends/lsp/standalone-client.ts
@@ -30038,9 +30087,9 @@ var exports_lsp = {};
30038
30087
  __export(exports_lsp, {
30039
30088
  LspBackend: () => LspBackend
30040
30089
  });
30041
- import { existsSync as existsSync7, readdirSync as readdirSync3 } from "fs";
30090
+ import { existsSync as existsSync8, readdirSync as readdirSync3 } from "fs";
30042
30091
  import { readdir as readdir2, readFile as readFile4 } from "fs/promises";
30043
- import { dirname as dirname3, join as join9, resolve as resolve5 } from "path";
30092
+ import { dirname as dirname3, join as join10, resolve as resolve5 } from "path";
30044
30093
  function getNvimBridge() {
30045
30094
  if (_nvimBridge === null) {
30046
30095
  try {
@@ -30067,18 +30116,18 @@ class LspBackend {
30067
30116
  async findAnchorFile() {
30068
30117
  const candidates = ["src/index.ts", "src/main.ts", "src/app.ts", "index.ts", "main.ts", "src/index.js", "src/main.js", "index.js", "main.py", "src/main.py", "main.go", "src/main.go", "src/lib.rs", "src/main.rs"];
30069
30118
  for (const candidate of candidates) {
30070
- const full = join9(this.cwd, candidate);
30071
- if (existsSync7(full))
30119
+ const full = join10(this.cwd, candidate);
30120
+ if (existsSync8(full))
30072
30121
  return full;
30073
30122
  }
30074
- for (const dir of [join9(this.cwd, "src"), this.cwd]) {
30075
- if (!existsSync7(dir))
30123
+ for (const dir of [join10(this.cwd, "src"), this.cwd]) {
30124
+ if (!existsSync8(dir))
30076
30125
  continue;
30077
30126
  try {
30078
30127
  const files = await readdir2(dir);
30079
30128
  const source = files.find((f3) => f3.endsWith(".ts") || f3.endsWith(".js") || f3.endsWith(".py") || f3.endsWith(".go") || f3.endsWith(".rs"));
30080
30129
  if (source)
30081
- return join9(dir, source);
30130
+ return join10(dir, source);
30082
30131
  } catch {}
30083
30132
  }
30084
30133
  return null;
@@ -31229,7 +31278,7 @@ function findProjectRootForLanguage(file, language) {
31229
31278
  } catch {}
31230
31279
  }
31231
31280
  for (const marker of nameMarkers) {
31232
- if (existsSync7(join9(dir, marker)))
31281
+ if (existsSync8(join10(dir, marker)))
31233
31282
  return dir;
31234
31283
  }
31235
31284
  dir = dirname3(dir);
@@ -201865,7 +201914,7 @@ var require_path_browserify = __commonJS((exports, module2) => {
201865
201914
  assertPath(path);
201866
201915
  return path.length > 0 && path.charCodeAt(0) === 47;
201867
201916
  },
201868
- join: function join10() {
201917
+ join: function join11() {
201869
201918
  if (arguments.length === 0)
201870
201919
  return ".";
201871
201920
  var joined;
@@ -204389,6 +204438,7 @@ var require_dist = __commonJS((exports) => {
204389
204438
 
204390
204439
  // node_modules/tinyglobby/dist/index.cjs
204391
204440
  var require_dist2 = __commonJS((exports) => {
204441
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
204392
204442
  var __create2 = Object.create;
204393
204443
  var __defProp5 = Object.defineProperty;
204394
204444
  var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
@@ -204412,29 +204462,26 @@ var require_dist2 = __commonJS((exports) => {
204412
204462
  enumerable: true
204413
204463
  }) : target, mod));
204414
204464
  var fs2 = __require("fs");
204415
- fs2 = __toESM2(fs2);
204416
204465
  var path = __require("path");
204417
- path = __toESM2(path);
204418
204466
  var url = __require("url");
204419
- url = __toESM2(url);
204420
204467
  var fdir = require_dist();
204421
- fdir = __toESM2(fdir);
204422
204468
  var picomatch = require_picomatch2();
204423
204469
  picomatch = __toESM2(picomatch);
204424
204470
  var isReadonlyArray = Array.isArray;
204471
+ var BACKSLASHES = /\\/g;
204425
204472
  var isWin = process.platform === "win32";
204426
204473
  var ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/;
204427
204474
  function getPartialMatcher(patterns, options = {}) {
204428
204475
  const patternsCount = patterns.length;
204429
204476
  const patternsParts = Array(patternsCount);
204430
204477
  const matchers = Array(patternsCount);
204431
- const globstarEnabled = !options.noglobstar;
204432
- for (let i4 = 0;i4 < patternsCount; i4++) {
204478
+ let i4, j2;
204479
+ for (i4 = 0;i4 < patternsCount; i4++) {
204433
204480
  const parts2 = splitPattern(patterns[i4]);
204434
204481
  patternsParts[i4] = parts2;
204435
204482
  const partsCount = parts2.length;
204436
204483
  const partMatchers = Array(partsCount);
204437
- for (let j2 = 0;j2 < partsCount; j2++)
204484
+ for (j2 = 0;j2 < partsCount; j2++)
204438
204485
  partMatchers[j2] = (0, picomatch.default)(parts2[j2], options);
204439
204486
  matchers[i4] = partMatchers;
204440
204487
  }
@@ -204442,20 +204489,19 @@ var require_dist2 = __commonJS((exports) => {
204442
204489
  const inputParts = input.split("/");
204443
204490
  if (inputParts[0] === ".." && ONLY_PARENT_DIRECTORIES.test(input))
204444
204491
  return true;
204445
- for (let i4 = 0;i4 < patterns.length; i4++) {
204492
+ for (i4 = 0;i4 < patternsCount; i4++) {
204446
204493
  const patternParts = patternsParts[i4];
204447
204494
  const matcher = matchers[i4];
204448
204495
  const inputPatternCount = inputParts.length;
204449
204496
  const minParts = Math.min(inputPatternCount, patternParts.length);
204450
- let j2 = 0;
204497
+ j2 = 0;
204451
204498
  while (j2 < minParts) {
204452
204499
  const part = patternParts[j2];
204453
204500
  if (part.includes("/"))
204454
204501
  return true;
204455
- const match = matcher[j2](inputParts[j2]);
204456
- if (!match)
204502
+ if (!matcher[j2](inputParts[j2]))
204457
204503
  break;
204458
- if (globstarEnabled && part === "**")
204504
+ if (!options.noglobstar && part === "**")
204459
204505
  return true;
204460
204506
  j2++;
204461
204507
  }
@@ -204470,7 +204516,7 @@ var require_dist2 = __commonJS((exports) => {
204470
204516
  function buildFormat(cwd, root2, absolute) {
204471
204517
  if (cwd === root2 || root2.startsWith(`${cwd}/`)) {
204472
204518
  if (absolute) {
204473
- const start2 = isRoot(cwd) ? cwd.length : cwd.length + 1;
204519
+ const start2 = cwd.length + +!isRoot(cwd);
204474
204520
  return (p2, isDir) => p2.slice(start2, isDir ? -1 : undefined) || ".";
204475
204521
  }
204476
204522
  const prefix = root2.slice(cwd.length + 1);
@@ -204494,29 +204540,27 @@ var require_dist2 = __commonJS((exports) => {
204494
204540
  }
204495
204541
  return (p2) => {
204496
204542
  const result = path.posix.relative(cwd, `${root2}/${p2}`);
204497
- if (p2.endsWith("/") && result !== "")
204498
- return `${result}/`;
204499
- return result || ".";
204543
+ return p2[p2.length - 1] === "/" && result !== "" ? `${result}/` : result || ".";
204500
204544
  };
204501
204545
  }
204502
204546
  var splitPatternOptions = { parts: true };
204503
- function splitPattern(path$2) {
204547
+ function splitPattern(path$1) {
204504
204548
  var _result$parts;
204505
- const result = picomatch.default.scan(path$2, splitPatternOptions);
204506
- return ((_result$parts = result.parts) === null || _result$parts === undefined ? undefined : _result$parts.length) ? result.parts : [path$2];
204549
+ const result = picomatch.default.scan(path$1, splitPatternOptions);
204550
+ return ((_result$parts = result.parts) === null || _result$parts === undefined ? undefined : _result$parts.length) ? result.parts : [path$1];
204507
204551
  }
204508
204552
  var ESCAPED_WIN32_BACKSLASHES = /\\(?![()[\]{}!+@])/g;
204509
204553
  function convertPosixPathToPattern(path$2) {
204510
204554
  return escapePosixPath(path$2);
204511
204555
  }
204512
- function convertWin32PathToPattern(path$2) {
204513
- return escapeWin32Path(path$2).replace(ESCAPED_WIN32_BACKSLASHES, "/");
204556
+ function convertWin32PathToPattern(path$3) {
204557
+ return escapeWin32Path(path$3).replace(ESCAPED_WIN32_BACKSLASHES, "/");
204514
204558
  }
204515
204559
  var convertPathToPattern = isWin ? convertWin32PathToPattern : convertPosixPathToPattern;
204516
204560
  var POSIX_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}*?|]|^!|[!+@](?=\()|\\(?![()[\]{}!*+?@|]))/g;
204517
204561
  var WIN32_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}]|^!|[!+@](?=\())/g;
204518
- var escapePosixPath = (path$2) => path$2.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&");
204519
- var escapeWin32Path = (path$2) => path$2.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&");
204562
+ var escapePosixPath = (path$4) => path$4.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&");
204563
+ var escapeWin32Path = (path$5) => path$5.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&");
204520
204564
  var escapePath = isWin ? escapeWin32Path : escapePosixPath;
204521
204565
  function isDynamicPattern(pattern, options) {
204522
204566
  if ((options === null || options === undefined ? undefined : options.caseSensitiveMatch) === false)
@@ -204527,32 +204571,33 @@ var require_dist2 = __commonJS((exports) => {
204527
204571
  function log(...tasks) {
204528
204572
  console.log(`[tinyglobby ${(/* @__PURE__ */ new Date()).toLocaleTimeString("es")}]`, ...tasks);
204529
204573
  }
204574
+ function ensureStringArray(value) {
204575
+ return typeof value === "string" ? [value] : value !== null && value !== undefined ? value : [];
204576
+ }
204530
204577
  var PARENT_DIRECTORY = /^(\/?\.\.)+/;
204531
204578
  var ESCAPING_BACKSLASHES = /\\(?=[()[\]{}!*+?@|])/g;
204532
- var BACKSLASHES = /\\/g;
204533
- function normalizePattern(pattern, expandDirectories, cwd, props, isIgnore) {
204579
+ function normalizePattern(pattern, opts, props, isIgnore) {
204580
+ var _PARENT_DIRECTORY$exe;
204581
+ const cwd = opts.cwd;
204534
204582
  let result = pattern;
204535
- if (pattern.endsWith("/"))
204583
+ if (pattern[pattern.length - 1] === "/")
204536
204584
  result = pattern.slice(0, -1);
204537
- if (!result.endsWith("*") && expandDirectories)
204585
+ if (result[result.length - 1] !== "*" && opts.expandDirectories)
204538
204586
  result += "/**";
204539
204587
  const escapedCwd = escapePath(cwd);
204540
- if (path.default.isAbsolute(result.replace(ESCAPING_BACKSLASHES, "")))
204541
- result = path.posix.relative(escapedCwd, result);
204542
- else
204543
- result = path.posix.normalize(result);
204544
- const parentDirectoryMatch = PARENT_DIRECTORY.exec(result);
204588
+ result = (0, path.isAbsolute)(result.replace(ESCAPING_BACKSLASHES, "")) ? path.posix.relative(escapedCwd, result) : path.posix.normalize(result);
204589
+ const parentDir = (_PARENT_DIRECTORY$exe = PARENT_DIRECTORY.exec(result)) === null || _PARENT_DIRECTORY$exe === undefined ? undefined : _PARENT_DIRECTORY$exe[0];
204545
204590
  const parts2 = splitPattern(result);
204546
- if (parentDirectoryMatch === null || parentDirectoryMatch === undefined ? undefined : parentDirectoryMatch[0]) {
204547
- const n = (parentDirectoryMatch[0].length + 1) / 3;
204591
+ if (parentDir) {
204592
+ const n = (parentDir.length + 1) / 3;
204548
204593
  let i4 = 0;
204549
204594
  const cwdParts = escapedCwd.split("/");
204550
204595
  while (i4 < n && parts2[i4 + n] === cwdParts[cwdParts.length + i4 - n]) {
204551
204596
  result = result.slice(0, (n - i4 - 1) * 3) + result.slice((n - i4) * 3 + parts2[i4 + n].length + 1) || ".";
204552
204597
  i4++;
204553
204598
  }
204554
- const potentialRoot = path.posix.join(cwd, parentDirectoryMatch[0].slice(i4 * 3));
204555
- if (!potentialRoot.startsWith(".") && props.root.length > potentialRoot.length) {
204599
+ const potentialRoot = path.posix.join(cwd, parentDir.slice(i4 * 3));
204600
+ if (potentialRoot[0] !== "." && props.root.length > potentialRoot.length) {
204556
204601
  props.root = potentialRoot;
204557
204602
  props.depthOffset = -n + i4;
204558
204603
  }
@@ -204568,7 +204613,7 @@ var require_dist2 = __commonJS((exports) => {
204568
204613
  newCommonPath.pop();
204569
204614
  break;
204570
204615
  }
204571
- if (part !== props.commonPath[i4] || isDynamicPattern(part) || i4 === parts2.length - 1)
204616
+ if (i4 === parts2.length - 1 || part !== props.commonPath[i4] || isDynamicPattern(part))
204572
204617
  break;
204573
204618
  newCommonPath.push(part);
204574
204619
  }
@@ -204578,167 +204623,143 @@ var require_dist2 = __commonJS((exports) => {
204578
204623
  }
204579
204624
  return result;
204580
204625
  }
204581
- function processPatterns({ patterns = ["**/*"], ignore = [], expandDirectories = true }, cwd, props) {
204582
- if (typeof patterns === "string")
204583
- patterns = [patterns];
204584
- if (typeof ignore === "string")
204585
- ignore = [ignore];
204626
+ function processPatterns(options, patterns, props) {
204586
204627
  const matchPatterns = [];
204587
204628
  const ignorePatterns = [];
204588
- for (const pattern of ignore) {
204629
+ for (const pattern of options.ignore) {
204589
204630
  if (!pattern)
204590
204631
  continue;
204591
204632
  if (pattern[0] !== "!" || pattern[1] === "(")
204592
- ignorePatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, true));
204633
+ ignorePatterns.push(normalizePattern(pattern, options, props, true));
204593
204634
  }
204594
204635
  for (const pattern of patterns) {
204595
204636
  if (!pattern)
204596
204637
  continue;
204597
204638
  if (pattern[0] !== "!" || pattern[1] === "(")
204598
- matchPatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, false));
204639
+ matchPatterns.push(normalizePattern(pattern, options, props, false));
204599
204640
  else if (pattern[1] !== "!" || pattern[2] === "(")
204600
- ignorePatterns.push(normalizePattern(pattern.slice(1), expandDirectories, cwd, props, true));
204641
+ ignorePatterns.push(normalizePattern(pattern.slice(1), options, props, true));
204601
204642
  }
204602
204643
  return {
204603
204644
  match: matchPatterns,
204604
204645
  ignore: ignorePatterns
204605
204646
  };
204606
204647
  }
204607
- function formatPaths(paths, relative2) {
204608
- for (let i4 = paths.length - 1;i4 >= 0; i4--) {
204609
- const path$2 = paths[i4];
204610
- paths[i4] = relative2(path$2);
204611
- }
204612
- return paths;
204613
- }
204614
- function normalizeCwd(cwd) {
204615
- if (!cwd)
204616
- return process.cwd().replace(BACKSLASHES, "/");
204617
- if (cwd instanceof URL)
204618
- return (0, url.fileURLToPath)(cwd).replace(BACKSLASHES, "/");
204619
- return path.default.resolve(cwd).replace(BACKSLASHES, "/");
204620
- }
204621
- function getCrawler(patterns, inputOptions = {}) {
204622
- const options = process.env.TINYGLOBBY_DEBUG ? {
204623
- ...inputOptions,
204624
- debug: true
204625
- } : inputOptions;
204626
- const cwd = normalizeCwd(options.cwd);
204627
- if (options.debug)
204628
- log("globbing with:", {
204629
- patterns,
204630
- options,
204631
- cwd
204632
- });
204633
- if (Array.isArray(patterns) && patterns.length === 0)
204634
- return [{
204635
- sync: () => [],
204636
- withPromise: async () => []
204637
- }, false];
204648
+ function buildCrawler(options, patterns) {
204649
+ const cwd = options.cwd;
204638
204650
  const props = {
204639
204651
  root: cwd,
204640
- commonPath: null,
204641
204652
  depthOffset: 0
204642
204653
  };
204643
- const processed = processPatterns({
204644
- ...options,
204645
- patterns
204646
- }, cwd, props);
204654
+ const processed = processPatterns(options, patterns, props);
204647
204655
  if (options.debug)
204648
204656
  log("internal processing patterns:", processed);
204657
+ const { absolute, caseSensitiveMatch, debug, dot, followSymbolicLinks, onlyDirectories } = options;
204658
+ const root2 = props.root.replace(BACKSLASHES, "");
204649
204659
  const matchOptions = {
204650
- dot: options.dot,
204660
+ dot,
204651
204661
  nobrace: options.braceExpansion === false,
204652
- nocase: options.caseSensitiveMatch === false,
204662
+ nocase: !caseSensitiveMatch,
204653
204663
  noextglob: options.extglob === false,
204654
204664
  noglobstar: options.globstar === false,
204655
204665
  posix: true
204656
204666
  };
204657
- const matcher = (0, picomatch.default)(processed.match, {
204658
- ...matchOptions,
204659
- ignore: processed.ignore
204660
- });
204667
+ const matcher = (0, picomatch.default)(processed.match, matchOptions);
204661
204668
  const ignore = (0, picomatch.default)(processed.ignore, matchOptions);
204662
204669
  const partialMatcher = getPartialMatcher(processed.match, matchOptions);
204663
- const format = buildFormat(cwd, props.root, options.absolute);
204664
- const formatExclude = options.absolute ? format : buildFormat(cwd, props.root, true);
204665
- const fdirOptions = {
204666
- filters: [options.debug ? (p2, isDirectory) => {
204667
- const path$2 = format(p2, isDirectory);
204668
- const matches2 = matcher(path$2);
204670
+ const format = buildFormat(cwd, root2, absolute);
204671
+ const excludeFormatter = absolute ? format : buildFormat(cwd, root2, true);
204672
+ const excludePredicate = (_3, p2) => {
204673
+ const relativePath = excludeFormatter(p2, true);
204674
+ return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
204675
+ };
204676
+ let maxDepth;
204677
+ if (options.deep !== undefined)
204678
+ maxDepth = Math.round(options.deep - props.depthOffset);
204679
+ const crawler = new fdir.fdir({
204680
+ filters: [debug ? (p2, isDirectory) => {
204681
+ const path2 = format(p2, isDirectory);
204682
+ const matches2 = matcher(path2) && !ignore(path2);
204669
204683
  if (matches2)
204670
- log(`matched ${path$2}`);
204684
+ log(`matched ${path2}`);
204671
204685
  return matches2;
204672
- } : (p2, isDirectory) => matcher(format(p2, isDirectory))],
204673
- exclude: options.debug ? (_3, p2) => {
204674
- const relativePath = formatExclude(p2, true);
204675
- const skipped = relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
204676
- if (skipped)
204677
- log(`skipped ${p2}`);
204678
- else
204679
- log(`crawling ${p2}`);
204686
+ } : (p2, isDirectory) => {
204687
+ const path2 = format(p2, isDirectory);
204688
+ return matcher(path2) && !ignore(path2);
204689
+ }],
204690
+ exclude: debug ? (_3, p2) => {
204691
+ const skipped = excludePredicate(_3, p2);
204692
+ log(`${skipped ? "skipped" : "crawling"} ${p2}`);
204680
204693
  return skipped;
204681
- } : (_3, p2) => {
204682
- const relativePath = formatExclude(p2, true);
204683
- return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
204684
- },
204685
- fs: options.fs ? {
204686
- readdir: options.fs.readdir || fs2.default.readdir,
204687
- readdirSync: options.fs.readdirSync || fs2.default.readdirSync,
204688
- realpath: options.fs.realpath || fs2.default.realpath,
204689
- realpathSync: options.fs.realpathSync || fs2.default.realpathSync,
204690
- stat: options.fs.stat || fs2.default.stat,
204691
- statSync: options.fs.statSync || fs2.default.statSync
204692
- } : undefined,
204694
+ } : excludePredicate,
204695
+ fs: options.fs,
204693
204696
  pathSeparator: "/",
204694
- relativePaths: true,
204695
- resolveSymlinks: true,
204697
+ relativePaths: !absolute,
204698
+ resolvePaths: absolute,
204699
+ includeBasePath: absolute,
204700
+ resolveSymlinks: followSymbolicLinks,
204701
+ excludeSymlinks: !followSymbolicLinks,
204702
+ excludeFiles: onlyDirectories,
204703
+ includeDirs: onlyDirectories || !options.onlyFiles,
204704
+ maxDepth,
204696
204705
  signal: options.signal
204697
- };
204698
- if (options.deep !== undefined)
204699
- fdirOptions.maxDepth = Math.round(options.deep - props.depthOffset);
204700
- if (options.absolute) {
204701
- fdirOptions.relativePaths = false;
204702
- fdirOptions.resolvePaths = true;
204703
- fdirOptions.includeBasePath = true;
204704
- }
204705
- if (options.followSymbolicLinks === false) {
204706
- fdirOptions.resolveSymlinks = false;
204707
- fdirOptions.excludeSymlinks = true;
204708
- }
204709
- if (options.onlyDirectories) {
204710
- fdirOptions.excludeFiles = true;
204711
- fdirOptions.includeDirs = true;
204712
- } else if (options.onlyFiles === false)
204713
- fdirOptions.includeDirs = true;
204714
- props.root = props.root.replace(BACKSLASHES, "");
204715
- const root2 = props.root;
204706
+ }).crawl(root2);
204716
204707
  if (options.debug)
204717
- log("internal properties:", props);
204718
- const relative2 = cwd !== root2 && !options.absolute && buildRelative(cwd, props.root);
204719
- return [new fdir.fdir(fdirOptions).crawl(root2), relative2];
204708
+ log("internal properties:", {
204709
+ ...props,
204710
+ root: root2
204711
+ });
204712
+ return [crawler, cwd !== root2 && !absolute && buildRelative(cwd, root2)];
204720
204713
  }
204721
- async function glob(patternsOrOptions, options) {
204722
- if (patternsOrOptions && (options === null || options === undefined ? undefined : options.patterns))
204723
- throw new Error("Cannot pass patterns as both an argument and an option");
204724
- const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string";
204725
- const opts = isModern ? options : patternsOrOptions;
204726
- const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns;
204727
- const [crawler, relative2] = getCrawler(patterns, opts);
204728
- if (!relative2)
204729
- return crawler.withPromise();
204730
- return formatPaths(await crawler.withPromise(), relative2);
204731
- }
204732
- function globSync(patternsOrOptions, options) {
204733
- if (patternsOrOptions && (options === null || options === undefined ? undefined : options.patterns))
204714
+ function formatPaths(paths, mapper) {
204715
+ if (mapper)
204716
+ for (let i4 = paths.length - 1;i4 >= 0; i4--)
204717
+ paths[i4] = mapper(paths[i4]);
204718
+ return paths;
204719
+ }
204720
+ var defaultOptions = {
204721
+ caseSensitiveMatch: true,
204722
+ cwd: process.cwd(),
204723
+ debug: !!process.env.TINYGLOBBY_DEBUG,
204724
+ expandDirectories: true,
204725
+ followSymbolicLinks: true,
204726
+ onlyFiles: true
204727
+ };
204728
+ function getOptions2(options) {
204729
+ const opts = {
204730
+ ...defaultOptions,
204731
+ ...options
204732
+ };
204733
+ opts.cwd = (opts.cwd instanceof URL ? (0, url.fileURLToPath)(opts.cwd) : (0, path.resolve)(opts.cwd)).replace(BACKSLASHES, "/");
204734
+ opts.ignore = ensureStringArray(opts.ignore);
204735
+ opts.fs && (opts.fs = {
204736
+ readdir: opts.fs.readdir || fs2.readdir,
204737
+ readdirSync: opts.fs.readdirSync || fs2.readdirSync,
204738
+ realpath: opts.fs.realpath || fs2.realpath,
204739
+ realpathSync: opts.fs.realpathSync || fs2.realpathSync,
204740
+ stat: opts.fs.stat || fs2.stat,
204741
+ statSync: opts.fs.statSync || fs2.statSync
204742
+ });
204743
+ if (opts.debug)
204744
+ log("globbing with options:", opts);
204745
+ return opts;
204746
+ }
204747
+ function getCrawler(globInput, inputOptions = {}) {
204748
+ var _ref;
204749
+ if (globInput && (inputOptions === null || inputOptions === undefined ? undefined : inputOptions.patterns))
204734
204750
  throw new Error("Cannot pass patterns as both an argument and an option");
204735
- const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string";
204736
- const opts = isModern ? options : patternsOrOptions;
204737
- const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns;
204738
- const [crawler, relative2] = getCrawler(patterns, opts);
204739
- if (!relative2)
204740
- return crawler.sync();
204741
- return formatPaths(crawler.sync(), relative2);
204751
+ const isModern = isReadonlyArray(globInput) || typeof globInput === "string";
204752
+ const patterns = ensureStringArray((_ref = isModern ? globInput : globInput.patterns) !== null && _ref !== undefined ? _ref : "**/*");
204753
+ const options = getOptions2(isModern ? inputOptions : globInput);
204754
+ return patterns.length > 0 ? buildCrawler(options, patterns) : [];
204755
+ }
204756
+ async function glob(globInput, options) {
204757
+ const [crawler, relative2] = getCrawler(globInput, options);
204758
+ return crawler ? formatPaths(await crawler.withPromise(), relative2) : [];
204759
+ }
204760
+ function globSync(globInput, options) {
204761
+ const [crawler, relative2] = getCrawler(globInput, options);
204762
+ return crawler ? formatPaths(crawler.sync(), relative2) : [];
204742
204763
  }
204743
204764
  exports.convertPathToPattern = convertPathToPattern;
204744
204765
  exports.escapePath = escapePath;