docbridge 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -337,7 +337,7 @@ var require_typescript = __commonJS((exports, module) => {
337
337
  compareDiagnostics: () => compareDiagnostics,
338
338
  compareEmitHelpers: () => compareEmitHelpers,
339
339
  compareNumberOfDirectorySeparators: () => compareNumberOfDirectorySeparators,
340
- comparePaths: () => comparePaths,
340
+ comparePaths: () => comparePaths2,
341
341
  comparePathsCaseInsensitive: () => comparePathsCaseInsensitive,
342
342
  comparePathsCaseSensitive: () => comparePathsCaseSensitive,
343
343
  comparePatternKeys: () => comparePatternKeys,
@@ -8840,7 +8840,7 @@ ${lanes.join(`
8840
8840
  function comparePathsCaseInsensitive(a, b) {
8841
8841
  return comparePathsWorker(a, b, compareStringsCaseInsensitive);
8842
8842
  }
8843
- function comparePaths(a, b, currentDirectory, ignoreCase) {
8843
+ function comparePaths2(a, b, currentDirectory, ignoreCase) {
8844
8844
  if (typeof currentDirectory === "string") {
8845
8845
  a = combinePaths(currentDirectory, a);
8846
8846
  b = combinePaths(currentDirectory, b);
@@ -19607,7 +19607,7 @@ ${lanes.join(`
19607
19607
  if (options.rootDir || options.composite && options.configFilePath) {
19608
19608
  const commonDir = getNormalizedAbsolutePath(getCommonSourceDirectory(options, () => [], host.getCurrentDirectory(), host.getCanonicalFileName), host.getCurrentDirectory());
19609
19609
  const outputPath = getSourceFilePathInNewDirWorker(sourceFile.fileName, options.outDir, host.getCurrentDirectory(), commonDir, host.getCanonicalFileName);
19610
- if (comparePaths(sourceFile.fileName, outputPath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0)
19610
+ if (comparePaths2(sourceFile.fileName, outputPath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0)
19611
19611
  return false;
19612
19612
  }
19613
19613
  return true;
@@ -41023,7 +41023,7 @@ ${lanes.join(`
41023
41023
  var nodeModulesAtTypes = combinePaths("node_modules", "@types");
41024
41024
  function arePathsEqual(path1, path2, host) {
41025
41025
  const useCaseSensitiveFileNames2 = typeof host.useCaseSensitiveFileNames === "function" ? host.useCaseSensitiveFileNames() : host.useCaseSensitiveFileNames;
41026
- return comparePaths(path1, path2, !useCaseSensitiveFileNames2) === 0;
41026
+ return comparePaths2(path1, path2, !useCaseSensitiveFileNames2) === 0;
41027
41027
  }
41028
41028
  function getOriginalAndResolvedFileName(fileName, host, traceEnabled) {
41029
41029
  const resolvedFileName = realPath(fileName, host, traceEnabled);
@@ -46147,7 +46147,7 @@ ${lanes.join(`
46147
46147
  return true;
46148
46148
  if (a === undefined || b === undefined)
46149
46149
  return false;
46150
- return comparePaths(a, b, ignoreCase) === 0;
46150
+ return comparePaths2(a, b, ignoreCase) === 0;
46151
46151
  }
46152
46152
  function countPathComponents(path) {
46153
46153
  let count = 0;
@@ -46363,7 +46363,7 @@ ${lanes.join(`
46363
46363
  const canTryTsExtension = preferTsExtension && hasImplementationTSFileExtension(targetFilePath);
46364
46364
  switch (mode) {
46365
46365
  case 0:
46366
- if (extensionSwappedTarget && comparePaths(extensionSwappedTarget, pathOrPattern, ignoreCase) === 0 || comparePaths(targetFilePath, pathOrPattern, ignoreCase) === 0 || outputFile && comparePaths(outputFile, pathOrPattern, ignoreCase) === 0 || declarationFile && comparePaths(declarationFile, pathOrPattern, ignoreCase) === 0) {
46366
+ if (extensionSwappedTarget && comparePaths2(extensionSwappedTarget, pathOrPattern, ignoreCase) === 0 || comparePaths2(targetFilePath, pathOrPattern, ignoreCase) === 0 || outputFile && comparePaths2(outputFile, pathOrPattern, ignoreCase) === 0 || declarationFile && comparePaths2(declarationFile, pathOrPattern, ignoreCase) === 0) {
46367
46367
  return { moduleFileToTry: packageName };
46368
46368
  }
46369
46369
  break;
@@ -47927,7 +47927,7 @@ ${lanes.join(`
47927
47927
  const isTargetPlainJs = isPlainJsFile(targetSymbolFile, compilerOptions.checkJs);
47928
47928
  const symbolName2 = symbolToString(source2);
47929
47929
  if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) {
47930
- const firstFile = comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === -1 ? sourceSymbolFile : targetSymbolFile;
47930
+ const firstFile = comparePaths2(sourceSymbolFile.path, targetSymbolFile.path) === -1 ? sourceSymbolFile : targetSymbolFile;
47931
47931
  const secondFile = firstFile === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile;
47932
47932
  const filesDuplicates = getOrUpdate(amalgamatedDuplicates, `${firstFile.path}|${secondFile.path}`, () => ({ firstFile, secondFile, conflictingSymbols: /* @__PURE__ */ new Map }));
47933
47933
  const conflictingSymbolInfo = getOrUpdate(filesDuplicates.conflictingSymbols, symbolName2, () => ({ isBlockScoped: isEitherBlockScoped, firstFileLocations: [], secondFileLocations: [] }));
@@ -102037,7 +102037,7 @@ ${lanes.join(`
102037
102037
  } else {
102038
102038
  const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile.fileName, options));
102039
102039
  const isJsonFile = isJsonSourceFile(sourceFile);
102040
- const isJsonEmittedToSameLocation = isJsonFile && comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0;
102040
+ const isJsonEmittedToSameLocation = isJsonFile && comparePaths2(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0;
102041
102041
  const jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath;
102042
102042
  const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
102043
102043
  const declarationFilePath = forceDtsPaths || getEmitDeclarations(options) && !isJsonFile ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
@@ -102065,7 +102065,7 @@ ${lanes.join(`
102065
102065
  return;
102066
102066
  const isJsonFile = fileExtensionIs(inputFileName, ".json");
102067
102067
  const outputFileName = getOutputJSFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory2);
102068
- return !isJsonFile || comparePaths(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== 0 ? outputFileName : undefined;
102068
+ return !isJsonFile || comparePaths2(inputFileName, outputFileName, Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== 0 ? outputFileName : undefined;
102069
102069
  }
102070
102070
  function getOutputJSFileNameWorker(inputFileName, options, ignoreCase, getCommonSourceDirectory2) {
102071
102071
  return changeExtension(getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.outDir, getCommonSourceDirectory2), getOutputExtension(inputFileName, options));
@@ -109855,7 +109855,7 @@ ${lanes.join(`
109855
109855
  return false;
109856
109856
  }
109857
109857
  function isSameFile(file1, file2) {
109858
- return comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0;
109858
+ return comparePaths2(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0;
109859
109859
  }
109860
109860
  function getSymlinkCache() {
109861
109861
  if (host.getSymlinkCache) {
@@ -145523,7 +145523,7 @@ ${newComment.split(`
145523
145523
  if (files) {
145524
145524
  for (let filePath of files) {
145525
145525
  filePath = normalizePath(filePath);
145526
- if (exclude && comparePaths(filePath, exclude, scriptDirectory, ignoreCase) === 0) {
145526
+ if (exclude && comparePaths2(filePath, exclude, scriptDirectory, ignoreCase) === 0) {
145527
145527
  continue;
145528
145528
  }
145529
145529
  const { name, extension } = getFilenameWithExtensionOption(getBaseFileName(filePath), program, extensionOptions, false);
@@ -145568,16 +145568,16 @@ ${newComment.split(`
145568
145568
  }
145569
145569
  function addCompletionEntriesFromPaths(result, fragment, baseDirectory, extensionOptions, program, host, moduleSpecifierResolutionHost, paths) {
145570
145570
  const getPatternsForKey = (key) => paths[key];
145571
- const comparePaths2 = (a, b) => {
145571
+ const comparePaths22 = (a, b) => {
145572
145572
  const patternA = tryParsePattern(a);
145573
145573
  const patternB = tryParsePattern(b);
145574
145574
  const lengthA = typeof patternA === "object" ? patternA.prefix.length : a.length;
145575
145575
  const lengthB = typeof patternB === "object" ? patternB.prefix.length : b.length;
145576
145576
  return compareValues(lengthB, lengthA);
145577
145577
  };
145578
- return addCompletionEntriesFromPathsOrExportsOrImports(result, false, false, fragment, baseDirectory, extensionOptions, program, host, moduleSpecifierResolutionHost, getOwnKeys(paths), getPatternsForKey, comparePaths2);
145578
+ return addCompletionEntriesFromPathsOrExportsOrImports(result, false, false, fragment, baseDirectory, extensionOptions, program, host, moduleSpecifierResolutionHost, getOwnKeys(paths), getPatternsForKey, comparePaths22);
145579
145579
  }
145580
- function addCompletionEntriesFromPathsOrExportsOrImports(result, isExports, isImports, fragment, baseDirectory, extensionOptions, program, host, moduleSpecifierResolutionHost, keys, getPatternsForKey, comparePaths2) {
145580
+ function addCompletionEntriesFromPathsOrExportsOrImports(result, isExports, isImports, fragment, baseDirectory, extensionOptions, program, host, moduleSpecifierResolutionHost, keys, getPatternsForKey, comparePaths22) {
145581
145581
  let pathResults = [];
145582
145582
  let matchedPath;
145583
145583
  for (const key of keys) {
@@ -145590,12 +145590,12 @@ ${newComment.split(`
145590
145590
  if (!pathPattern)
145591
145591
  continue;
145592
145592
  const isMatch = typeof pathPattern === "object" && isPatternMatch(pathPattern, fragment);
145593
- const isLongestMatch = isMatch && (matchedPath === undefined || comparePaths2(keyWithoutLeadingDotSlash, matchedPath) === -1);
145593
+ const isLongestMatch = isMatch && (matchedPath === undefined || comparePaths22(keyWithoutLeadingDotSlash, matchedPath) === -1);
145594
145594
  if (isLongestMatch) {
145595
145595
  matchedPath = keyWithoutLeadingDotSlash;
145596
145596
  pathResults = pathResults.filter((r) => !r.matchedPattern);
145597
145597
  }
145598
- if (typeof pathPattern === "string" || matchedPath === undefined || comparePaths2(keyWithoutLeadingDotSlash, matchedPath) !== 1) {
145598
+ if (typeof pathPattern === "string" || matchedPath === undefined || comparePaths22(keyWithoutLeadingDotSlash, matchedPath) !== 1) {
145599
145599
  pathResults.push({
145600
145600
  matchedPattern: isMatch,
145601
145601
  results: getCompletionsForPathMapping(keyWithoutLeadingDotSlash, patterns, fragment, baseDirectory, extensionOptions, isExports, isImports, program, host, moduleSpecifierResolutionHost).map(({ name, kind, extension }) => nameAndKind(name, kind, extension))
@@ -156337,7 +156337,7 @@ ${options.prefix}` : `
156337
156337
  compareDiagnostics: () => compareDiagnostics,
156338
156338
  compareEmitHelpers: () => compareEmitHelpers,
156339
156339
  compareNumberOfDirectorySeparators: () => compareNumberOfDirectorySeparators,
156340
- comparePaths: () => comparePaths,
156340
+ comparePaths: () => comparePaths2,
156341
156341
  comparePathsCaseInsensitive: () => comparePathsCaseInsensitive,
156342
156342
  comparePathsCaseSensitive: () => comparePathsCaseSensitive,
156343
156343
  comparePatternKeys: () => comparePatternKeys,
@@ -160561,7 +160561,7 @@ ${options.prefix}` : `
160561
160561
  return this.writeLog(`TypingWatchers already invoked`);
160562
160562
  if (!fileExtensionIs(f, ".json"))
160563
160563
  return this.writeLog(`Ignoring files that are not *.json`);
160564
- if (comparePaths(f, combinePaths(this.projectService.typingsInstaller.globalTypingsCacheLocation, "package.json"), !this.useCaseSensitiveFileNames()))
160564
+ if (comparePaths2(f, combinePaths(this.projectService.typingsInstaller.globalTypingsCacheLocation, "package.json"), !this.useCaseSensitiveFileNames()))
160565
160565
  return this.writeLog(`Ignoring package.json change at global typings location`);
160566
160566
  this.onTypingInstallerWatchInvoke();
160567
160567
  }, 1, this.projectService.getWatchOptions(this), watchType, this) : (this.writeLog(`Skipping watcher creation at ${path}:: ${getDetailWatchInfo(watchType, this)}`), noopFileWatcher));
@@ -168755,38 +168755,33 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
168755
168755
  });
168756
168756
 
168757
168757
  // src/cli/index.ts
168758
- import { readFileSync as readFileSync5, statSync as statSync4 } from "node:fs";
168758
+ import { readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
168759
168759
  import { resolve as resolve4 } from "node:path";
168760
168760
  // package.json
168761
168761
  var package_default = {
168762
168762
  name: "docbridge",
168763
- version: "0.6.0",
168763
+ version: "0.6.1",
168764
168764
  description: "A CLI that links Markdown specifications and code declarations. Runs on Node.js and Bun.",
168765
- license: "MIT",
168766
- type: "module",
168767
- bin: {
168768
- docbridge: "./dist/index.js"
168769
- },
168770
- repository: {
168771
- type: "git",
168772
- url: "git+https://github.com/salan70/docbridge.git"
168773
- },
168774
- bugs: {
168775
- url: "https://github.com/salan70/docbridge/issues"
168776
- },
168777
- homepage: "https://github.com/salan70/docbridge#readme",
168778
168765
  keywords: [
168766
+ "bun",
168767
+ "cli",
168779
168768
  "documentation",
168769
+ "lsp",
168780
168770
  "markdown",
168781
- "specification",
168782
- "cli",
168783
168771
  "node",
168784
- "bun",
168785
- "lsp"
168772
+ "specification"
168786
168773
  ],
168787
- engines: {
168788
- node: ">=22",
168789
- bun: ">=1.1.31"
168774
+ homepage: "https://github.com/salan70/docbridge#readme",
168775
+ bugs: {
168776
+ url: "https://github.com/salan70/docbridge/issues"
168777
+ },
168778
+ license: "MIT",
168779
+ repository: {
168780
+ type: "git",
168781
+ url: "git+https://github.com/salan70/docbridge.git"
168782
+ },
168783
+ bin: {
168784
+ docbridge: "./dist/index.js"
168790
168785
  },
168791
168786
  files: [
168792
168787
  "dist",
@@ -168796,6 +168791,7 @@ var package_default = {
168796
168791
  "CHANGELOG.md",
168797
168792
  "LICENSE"
168798
168793
  ],
168794
+ type: "module",
168799
168795
  scripts: {
168800
168796
  docbridge: "bun run src/cli/index.ts",
168801
168797
  check: "bun run src/cli/index.ts check",
@@ -168805,13 +168801,19 @@ var package_default = {
168805
168801
  },
168806
168802
  devDependencies: {
168807
168803
  "@types/bun": "^1.3.14",
168804
+ oxfmt: "0.57.0",
168805
+ oxlint: "1.73.0",
168808
168806
  typescript: "^5.9.0"
168807
+ },
168808
+ engines: {
168809
+ bun: ">=1.1.31",
168810
+ node: ">=22"
168809
168811
  }
168810
168812
  };
168811
168813
 
168812
168814
  // src/core/code-language.ts
168813
- import { existsSync, realpathSync } from "node:fs";
168814
- import { dirname, join as join3, resolve } from "node:path";
168815
+ import { accessSync, chmodSync, constants, existsSync, realpathSync, statSync } from "node:fs";
168816
+ import { dirname as dirname2, join as join3, resolve } from "node:path";
168815
168817
  import { fileURLToPath } from "node:url";
168816
168818
 
168817
168819
  // src/core/glob.ts
@@ -168899,7 +168901,16 @@ function collectFiles(projectRoot, patterns) {
168899
168901
  }
168900
168902
  };
168901
168903
  walk("");
168902
- return [...matched].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
168904
+ return [...matched].toSorted(comparePaths);
168905
+ }
168906
+ function comparePaths(left, right) {
168907
+ if (left < right) {
168908
+ return -1;
168909
+ }
168910
+ if (left > right) {
168911
+ return 1;
168912
+ }
168913
+ return 0;
168903
168914
  }
168904
168915
  function readManagedFile(projectRoot, relativePath) {
168905
168916
  try {
@@ -168956,7 +168967,7 @@ function escapeRegExpChar(char) {
168956
168967
  import { spawnSync } from "node:child_process";
168957
168968
  import { mkdirSync } from "node:fs";
168958
168969
  import { tmpdir } from "node:os";
168959
- import { join as join2 } from "node:path";
168970
+ import { dirname, join as join2 } from "node:path";
168960
168971
  function invokeScannerWorker(request, command, run = runScannerWorkerProcess) {
168961
168972
  const processResult = run({
168962
168973
  command,
@@ -168965,7 +168976,7 @@ function invokeScannerWorker(request, command, run = runScannerWorkerProcess) {
168965
168976
  if (!processResult.ok) {
168966
168977
  return {
168967
168978
  ok: false,
168968
- diagnostic: scannerUnavailableDiagnostic(request.language, processResult.error),
168979
+ diagnostic: scannerUnavailableDiagnostic(request.language, processResult.error, command[0]),
168969
168980
  stderr: processResult.stderr
168970
168981
  };
168971
168982
  }
@@ -169089,16 +169100,30 @@ function isResponseFile(value) {
169089
169100
  function isRecord(value) {
169090
169101
  return typeof value === "object" && value !== null && !Array.isArray(value);
169091
169102
  }
169092
- function scannerUnavailableDiagnostic(language, error) {
169103
+ function scannerUnavailableDiagnostic(language, error, executable) {
169093
169104
  const label = languageLabel(language);
169094
169105
  return {
169095
169106
  severity: "error",
169096
169107
  code: "code_scanner_unavailable",
169097
169108
  language,
169098
169109
  target: language,
169099
- message: `${label} scanner worker is unavailable: ${reasonOf(error)}`
169110
+ message: `${label} scanner worker is unavailable: ${spawnFailureReason(error, executable)}`
169100
169111
  };
169101
169112
  }
169113
+ function spawnFailureReason(error, executable) {
169114
+ const reason = reasonOf(error);
169115
+ if (!isExecDenied(error) || executable === undefined) {
169116
+ return reason;
169117
+ }
169118
+ return `${reason}; the scanner is executable but ${dirname(executable)} refuses to ` + `execute it, which a \`noexec\` mount does. Install DocBridge as a project ` + `dependency, or point the installer cache at an exec-capable directory, ` + `instead of running through \`bunx\``;
169119
+ }
169120
+ function isExecDenied(error) {
169121
+ if (!(error instanceof Error)) {
169122
+ return false;
169123
+ }
169124
+ const code = error.code;
169125
+ return code === "EACCES" || code === "EPERM";
169126
+ }
169102
169127
  function scannerFailedDiagnostic(language, reason) {
169103
169128
  const label = languageLabel(language);
169104
169129
  return {
@@ -169531,11 +169556,7 @@ function duplicateLinkDiagnostic(source, target, location, range) {
169531
169556
  }
169532
169557
 
169533
169558
  // src/core/code-language.ts
169534
- var KNOWN_CODE_LANGUAGES = [
169535
- "typescript",
169536
- "swift",
169537
- "dart"
169538
- ];
169559
+ var KNOWN_CODE_LANGUAGES = ["typescript", "swift", "dart"];
169539
169560
  function isCodeLanguage(value) {
169540
169561
  return KNOWN_CODE_LANGUAGES.includes(value);
169541
169562
  }
@@ -169554,6 +169575,10 @@ function resolveScannerWorkerCommand(language, options = {}) {
169554
169575
  const candidates = scannerExecutableCandidates(language, platformKey, platformSupported, options);
169555
169576
  const found = candidates.find((candidate) => existsSync(candidate));
169556
169577
  if (found !== undefined) {
169578
+ const repair = ensureExecutable(found, options.chmod ?? chmodSync);
169579
+ if (!repair.ok) {
169580
+ return { ok: false, diagnostic: scannerUnavailableDiagnostic2(language, repair.reason) };
169581
+ }
169557
169582
  return { ok: true, command: [found] };
169558
169583
  }
169559
169584
  if (!platformSupported) {
@@ -169578,9 +169603,7 @@ function createScannerWorkerAdapter(language, command, adapterOptions = {}) {
169578
169603
  if (!commandResolution.ok) {
169579
169604
  return {
169580
169605
  ...emptyScan(language, filePath),
169581
- diagnostics: [
169582
- fileScopedScannerDiagnostic(commandResolution.diagnostic, filePath)
169583
- ]
169606
+ diagnostics: [fileScopedScannerDiagnostic(commandResolution.diagnostic, filePath)]
169584
169607
  };
169585
169608
  }
169586
169609
  const result = invokeScannerWorker({
@@ -169618,9 +169641,18 @@ function collectCodeFiles(projectRoot, codeInclude) {
169618
169641
  collected.push({ language, relPath });
169619
169642
  }
169620
169643
  }
169621
- collected.sort((left, right) => left.relPath < right.relPath ? -1 : left.relPath > right.relPath ? 1 : 0);
169644
+ collected.sort((left, right) => comparePaths2(left.relPath, right.relPath));
169622
169645
  return collected;
169623
169646
  }
169647
+ function comparePaths2(left, right) {
169648
+ if (left < right) {
169649
+ return -1;
169650
+ }
169651
+ if (left > right) {
169652
+ return 1;
169653
+ }
169654
+ return 0;
169655
+ }
169624
169656
  function scanCodeFiles(projectRoot, files, codeInclude, read, onContent) {
169625
169657
  const codeFiles = [];
169626
169658
  const diagnostics = [];
@@ -169695,6 +169727,40 @@ function scannerExecutableCandidates(language, platformKey, platformSupported, o
169695
169727
  ...platformSupported ? [join3(distRoot, "bin", platformKey, executable)] : []
169696
169728
  ];
169697
169729
  }
169730
+ function ensureExecutable(path, chmod) {
169731
+ let mode;
169732
+ try {
169733
+ mode = statSync(path).mode;
169734
+ } catch (error) {
169735
+ return { ok: false, reason: `cannot stat ${path}: ${reasonOf2(error)}` };
169736
+ }
169737
+ if (isExecutableByThisProcess(path)) {
169738
+ return { ok: true };
169739
+ }
169740
+ try {
169741
+ chmod(path, mode | 73);
169742
+ } catch (error) {
169743
+ return {
169744
+ ok: false,
169745
+ reason: `${path} is not executable (mode ${formatMode(mode)}) and the executable ` + `bit could not be restored: ${reasonOf2(error)}; run \`chmod +x ${path}\` ` + `or reinstall DocBridge into a writable location`
169746
+ };
169747
+ }
169748
+ return { ok: true };
169749
+ }
169750
+ function isExecutableByThisProcess(path) {
169751
+ try {
169752
+ accessSync(path, constants.X_OK);
169753
+ return true;
169754
+ } catch {
169755
+ return false;
169756
+ }
169757
+ }
169758
+ function formatMode(mode) {
169759
+ return `0${(mode & 4095).toString(8).padStart(3, "0")}`;
169760
+ }
169761
+ function reasonOf2(error) {
169762
+ return error instanceof Error ? error.message : String(error);
169763
+ }
169698
169764
  function isSupportedScannerPlatformKey(platformKey) {
169699
169765
  return SUPPORTED_SCANNER_PLATFORM_KEYS.includes(platformKey);
169700
169766
  }
@@ -169706,7 +169772,7 @@ function scannerRootsFromModuleUrl(moduleUrl) {
169706
169772
  } catch {
169707
169773
  resolved = modulePath;
169708
169774
  }
169709
- const moduleDir = dirname(resolved);
169775
+ const moduleDir = dirname2(resolved);
169710
169776
  return { distRoot: moduleDir, sourceRoot: resolve(moduleDir, "..", "..") };
169711
169777
  }
169712
169778
  function sourceRootPath() {
@@ -169716,7 +169782,7 @@ function distRootPath() {
169716
169782
  return scannerRootsFromModuleUrl(import.meta.url).distRoot;
169717
169783
  }
169718
169784
  function scannerExecutableName(language) {
169719
- return language === "swift" ? "speclink-swift-scanner" : "speclink_dart_scanner";
169785
+ return language === "swift" ? "docbridge-swift-scanner" : "docbridge_dart_scanner";
169720
169786
  }
169721
169787
  function scannerUnavailableDiagnostic2(language, reason) {
169722
169788
  const label = language.charAt(0).toUpperCase() + language.slice(1);
@@ -169946,24 +170012,18 @@ function isStringArray(value) {
169946
170012
 
169947
170013
  // src/core/diagnostics.ts
169948
170014
  function sortDiagnostics(diagnostics) {
169949
- return [...diagnostics].sort(compareDiagnostics);
170015
+ return [...diagnostics].toSorted(compareDiagnostics);
169950
170016
  }
169951
170017
  function summarizeDiagnostics(diagnostics) {
169952
- return diagnostics.reduce((summary, diagnostic) => {
170018
+ const summary = { errors: 0, warnings: 0 };
170019
+ for (const diagnostic of diagnostics) {
169953
170020
  if (diagnostic.severity === "error") {
169954
- return {
169955
- ...summary,
169956
- errors: summary.errors + 1
169957
- };
170021
+ summary.errors += 1;
170022
+ } else {
170023
+ summary.warnings += 1;
169958
170024
  }
169959
- return {
169960
- ...summary,
169961
- warnings: summary.warnings + 1
169962
- };
169963
- }, {
169964
- errors: 0,
169965
- warnings: 0
169966
- });
170025
+ }
170026
+ return summary;
169967
170027
  }
169968
170028
  function formatDiagnostic(diagnostic) {
169969
170029
  const location = diagnostic.location;
@@ -170056,7 +170116,7 @@ function counterpartsOf(graph, endpoint) {
170056
170116
  resolved.push(doc);
170057
170117
  }
170058
170118
  }
170059
- return resolved.sort(compareEndpoints);
170119
+ return resolved.toSorted(compareEndpoints);
170060
170120
  }
170061
170121
  function addTo(map, key, value) {
170062
170122
  const existing = map.get(key);
@@ -170328,7 +170388,7 @@ function normalizeChangedPaths(projectRoot, paths) {
170328
170388
  }
170329
170389
  function computeRelated(graph, changedFiles) {
170330
170390
  const changedSet = new Set(changedFiles);
170331
- const sortedPaths = [...changedSet].sort((left, right) => left.localeCompare(right));
170391
+ const sortedPaths = [...changedSet].toSorted((left, right) => left.localeCompare(right));
170332
170392
  const endpointsByFile = indexEndpointsByFile(graph);
170333
170393
  const files = [];
170334
170394
  for (const filePath of sortedPaths) {
@@ -170717,9 +170777,9 @@ function computeContext(graph, contentByFile, inputFiles) {
170717
170777
  linkedFromByEndpoint.get(counterpart.endpoint)?.add(endpoint.endpoint);
170718
170778
  }
170719
170779
  }
170720
- const contexts = [...blockByEndpoint.values()].sort(compareBlocks);
170780
+ const contexts = [...blockByEndpoint.values()].toSorted(compareBlocks);
170721
170781
  for (const block of contexts) {
170722
- block.linkedFrom = [...linkedFromByEndpoint.get(block.endpoint) ?? []].sort((left, right) => left.localeCompare(right));
170782
+ block.linkedFrom = [...linkedFromByEndpoint.get(block.endpoint) ?? []].toSorted((left, right) => left.localeCompare(right));
170723
170783
  }
170724
170784
  return {
170725
170785
  contexts,
@@ -170947,8 +171007,8 @@ function computeGraphResult(options) {
170947
171007
  return docNode(doc, options.contentByFile, options.includeContent);
170948
171008
  }
170949
171009
  return;
170950
- }).filter((node) => node !== undefined).sort(compareNodes);
170951
- const pairs = computePairs(includedEdges).sort(comparePairs);
171010
+ }).filter((node) => node !== undefined).toSorted(compareNodes);
171011
+ const pairs = computePairs(includedEdges).toSorted(comparePairs);
170952
171012
  const diagnostics = filterDiagnostics(options.diagnostics, nodes, options.inputFiles);
170953
171013
  const bidirectionalPairs = pairs.filter((pair) => pair.hasDocEdge && pair.hasCodeEdge).length;
170954
171014
  const oneWayEdges = pairs.filter((pair) => pair.hasDocEdge !== pair.hasCodeEdge).length;
@@ -171155,7 +171215,7 @@ function computePairs(edges) {
171155
171215
  return [...byKey.values()];
171156
171216
  }
171157
171217
  function appendDocsOrientedLines(lines, result) {
171158
- const docs = result.nodes.filter((node) => node.kind === "doc").sort(compareNodes);
171218
+ const docs = result.nodes.filter((node) => node.kind === "doc").toSorted(compareNodes);
171159
171219
  for (const doc of docs) {
171160
171220
  const pairs = result.pairs.filter((pair) => pair.docEndpoint === doc.endpoint);
171161
171221
  if (pairs.length === 0) {
@@ -171168,21 +171228,21 @@ function appendDocsOrientedLines(lines, result) {
171168
171228
  lines.push("");
171169
171229
  }
171170
171230
  lines.push(doc.filePath);
171171
- for (const pair of pairs.sort(comparePairs)) {
171231
+ for (const pair of pairs.toSorted(comparePairs)) {
171172
171232
  lines.push(` ${fragmentOf2(pair.docEndpoint)} -> ${pair.codeEndpoint} (${pairStatus(pair)})`);
171173
171233
  }
171174
171234
  }
171175
171235
  }
171176
171236
  function appendScopedLines(lines, result, inputFiles) {
171177
171237
  const inputSet = new Set(inputFiles);
171178
- const nodes = result.nodes.filter((node) => inputSet.has(node.filePath)).sort(compareNodes);
171238
+ const nodes = result.nodes.filter((node) => inputSet.has(node.filePath)).toSorted(compareNodes);
171179
171239
  for (const node of nodes) {
171180
171240
  if (lines.length > 0) {
171181
171241
  lines.push("");
171182
171242
  }
171183
171243
  lines.push(node.filePath);
171184
171244
  const pairs = result.pairs.filter((pair) => pair.codeEndpoint === node.endpoint || pair.docEndpoint === node.endpoint);
171185
- for (const pair of pairs.sort(comparePairs)) {
171245
+ for (const pair of pairs.toSorted(comparePairs)) {
171186
171246
  if (node.kind === "doc") {
171187
171247
  lines.push(` ${fragmentOf2(pair.docEndpoint)} -> ${pair.codeEndpoint} (${pairStatus(pair)})`);
171188
171248
  } else {
@@ -171230,72 +171290,6 @@ function comparePairs(left, right) {
171230
171290
  // src/lsp/server.ts
171231
171291
  import { fileURLToPath as fileURLToPath3 } from "node:url";
171232
171292
 
171233
- // src/lsp/transport.ts
171234
- var HEADER_SEPARATOR = `\r
171235
- \r
171236
- `;
171237
- var CONTENT_LENGTH_HEADER = "content-length";
171238
- function encodeMessage(message) {
171239
- const body = Buffer.from(JSON.stringify(message), "utf8");
171240
- const header = Buffer.from(`Content-Length: ${body.byteLength}${HEADER_SEPARATOR}`, "utf8");
171241
- return Buffer.concat([header, body]);
171242
- }
171243
-
171244
- class MessageReader {
171245
- buffer = Buffer.alloc(0);
171246
- append(chunk) {
171247
- this.buffer = Buffer.concat([this.buffer, Buffer.from(chunk)]);
171248
- }
171249
- read() {
171250
- const messages = [];
171251
- for (;; ) {
171252
- const message = this.readOne();
171253
- if (message === null) {
171254
- break;
171255
- }
171256
- messages.push(message.value);
171257
- }
171258
- return messages;
171259
- }
171260
- readOne() {
171261
- const separatorText = HEADER_SEPARATOR;
171262
- const headerEnd = this.buffer.indexOf(separatorText, 0, "utf8");
171263
- if (headerEnd === -1) {
171264
- return null;
171265
- }
171266
- const headerText = this.buffer.toString("utf8", 0, headerEnd);
171267
- const contentLength = parseContentLength(headerText);
171268
- const bodyStart = headerEnd + separatorText.length;
171269
- if (this.buffer.byteLength - bodyStart < contentLength) {
171270
- return null;
171271
- }
171272
- const bodyEnd = bodyStart + contentLength;
171273
- const bodyText = this.buffer.toString("utf8", bodyStart, bodyEnd);
171274
- this.buffer = this.buffer.subarray(bodyEnd);
171275
- return { value: JSON.parse(bodyText) };
171276
- }
171277
- }
171278
- function parseContentLength(headerText) {
171279
- const lines = headerText.split(`\r
171280
- `);
171281
- for (const line of lines) {
171282
- const colonIndex = line.indexOf(":");
171283
- if (colonIndex === -1) {
171284
- continue;
171285
- }
171286
- const name = line.slice(0, colonIndex).trim().toLowerCase();
171287
- if (name !== CONTENT_LENGTH_HEADER) {
171288
- continue;
171289
- }
171290
- const value = Number.parseInt(line.slice(colonIndex + 1).trim(), 10);
171291
- if (Number.isNaN(value) || value < 0) {
171292
- throw new Error(`Invalid Content-Length header: ${line}`);
171293
- }
171294
- return value;
171295
- }
171296
- throw new Error("Malformed LSP message: missing Content-Length header.");
171297
- }
171298
-
171299
171293
  // src/lsp/position.ts
171300
171294
  function toLspPosition(position) {
171301
171295
  return { line: position.line - 1, character: position.column - 1 };
@@ -171319,70 +171313,6 @@ function rangeContains(range, position) {
171319
171313
  return true;
171320
171314
  }
171321
171315
 
171322
- // src/lsp/index-lookup.ts
171323
- function buildPositionIndex(graph2) {
171324
- const byFile = new Map;
171325
- const add = (range, endpoint) => {
171326
- if (range === undefined) {
171327
- return;
171328
- }
171329
- addTo2(byFile, endpoint.filePath, { range, endpoint });
171330
- };
171331
- for (const symbol of graph2.codeByEndpoint.values()) {
171332
- add(symbol.nameRange, symbol);
171333
- }
171334
- for (const anchor of graph2.docByEndpoint.values()) {
171335
- add(anchor.headingTextRange, anchor);
171336
- }
171337
- return { byFile };
171338
- }
171339
- function endpointAt(index, filePath, position) {
171340
- const entries = index.byFile.get(filePath);
171341
- if (entries === undefined) {
171342
- return;
171343
- }
171344
- for (const entry of entries) {
171345
- if (rangeContains(entry.range, position)) {
171346
- return entry.endpoint;
171347
- }
171348
- }
171349
- return;
171350
- }
171351
- function addTo2(map, key, value) {
171352
- const existing = map.get(key);
171353
- if (existing === undefined) {
171354
- map.set(key, [value]);
171355
- return;
171356
- }
171357
- existing.push(value);
171358
- }
171359
-
171360
- // src/lsp/navigation.ts
171361
- function definition(state, filePath, position) {
171362
- return counterpartLocators(state, filePath, position);
171363
- }
171364
- function references(state, filePath, position) {
171365
- return counterpartLocators(state, filePath, position);
171366
- }
171367
- function counterpartLocators(state, filePath, position) {
171368
- const element = endpointAt(state.index, filePath, position);
171369
- if (element === undefined) {
171370
- return [];
171371
- }
171372
- return counterpartsOf(state.graph, element.endpoint).map((counterpart) => ({
171373
- filePath: counterpart.filePath,
171374
- range: elementRange(counterpart)
171375
- }));
171376
- }
171377
- function elementRange(element) {
171378
- const range = element.kind === "code" ? element.nameRange : element.headingTextRange;
171379
- if (range !== undefined) {
171380
- return range;
171381
- }
171382
- const { line, column } = element.location;
171383
- return { start: { line, column }, end: { line, column } };
171384
- }
171385
-
171386
171316
  // src/lsp/diagnostics.ts
171387
171317
  var SOURCE = "docbridge";
171388
171318
  function toLspDiagnostic(diagnostic, lineLengths) {
@@ -171421,6 +171351,44 @@ function rangeFor(diagnostic, lineLengths) {
171421
171351
  return { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };
171422
171352
  }
171423
171353
 
171354
+ // src/lsp/index-lookup.ts
171355
+ function buildPositionIndex(graph2) {
171356
+ const byFile = new Map;
171357
+ const add = (range, endpoint) => {
171358
+ if (range === undefined) {
171359
+ return;
171360
+ }
171361
+ addTo2(byFile, endpoint.filePath, { range, endpoint });
171362
+ };
171363
+ for (const symbol of graph2.codeByEndpoint.values()) {
171364
+ add(symbol.nameRange, symbol);
171365
+ }
171366
+ for (const anchor of graph2.docByEndpoint.values()) {
171367
+ add(anchor.headingTextRange, anchor);
171368
+ }
171369
+ return { byFile };
171370
+ }
171371
+ function endpointAt(index, filePath, position) {
171372
+ const entries = index.byFile.get(filePath);
171373
+ if (entries === undefined) {
171374
+ return;
171375
+ }
171376
+ for (const entry of entries) {
171377
+ if (rangeContains(entry.range, position)) {
171378
+ return entry.endpoint;
171379
+ }
171380
+ }
171381
+ return;
171382
+ }
171383
+ function addTo2(map, key, value) {
171384
+ const existing = map.get(key);
171385
+ if (existing === undefined) {
171386
+ map.set(key, [value]);
171387
+ return;
171388
+ }
171389
+ existing.push(value);
171390
+ }
171391
+
171424
171392
  // src/lsp/hover.ts
171425
171393
  var DIVIDER = `
171426
171394
 
@@ -171486,6 +171454,52 @@ function lineAt(content, line) {
171486
171454
  `)[line - 1] ?? "";
171487
171455
  }
171488
171456
 
171457
+ // src/lsp/navigation.ts
171458
+ function definition(state, filePath, position) {
171459
+ return counterpartLocators(state, filePath, position);
171460
+ }
171461
+ function references(state, filePath, position) {
171462
+ return counterpartLocators(state, filePath, position);
171463
+ }
171464
+ function counterpartLocators(state, filePath, position) {
171465
+ const element = endpointAt(state.index, filePath, position);
171466
+ if (element === undefined) {
171467
+ return [];
171468
+ }
171469
+ return counterpartsOf(state.graph, element.endpoint).map((counterpart) => ({
171470
+ filePath: counterpart.filePath,
171471
+ range: elementRange(counterpart)
171472
+ }));
171473
+ }
171474
+ function elementRange(element) {
171475
+ const range = element.kind === "code" ? element.nameRange : element.headingTextRange;
171476
+ if (range !== undefined) {
171477
+ return range;
171478
+ }
171479
+ const { line, column } = element.location;
171480
+ return { start: { line, column }, end: { line, column } };
171481
+ }
171482
+
171483
+ // src/lsp/paths.ts
171484
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep } from "node:path";
171485
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
171486
+ function uriToRelativePath(projectRoot, uri) {
171487
+ let absolute;
171488
+ try {
171489
+ absolute = fileURLToPath2(uri);
171490
+ } catch {
171491
+ return;
171492
+ }
171493
+ const rel = relative2(projectRoot, absolute);
171494
+ if (rel === "" || rel.startsWith("..") || isAbsolute2(rel)) {
171495
+ return;
171496
+ }
171497
+ return rel.split(sep).join("/");
171498
+ }
171499
+ function relativePathToUri(projectRoot, relPath) {
171500
+ return pathToFileURL(resolve2(projectRoot, relPath)).href;
171501
+ }
171502
+
171489
171503
  // src/lsp/project.ts
171490
171504
  class Project {
171491
171505
  projectRoot;
@@ -171570,7 +171584,7 @@ class Project {
171570
171584
  }
171571
171585
  }
171572
171586
  }
171573
- return all.sort((left, right) => left.relPath < right.relPath ? -1 : left.relPath > right.relPath ? 1 : 0);
171587
+ return all.toSorted((left, right) => comparePaths3(left.relPath, right.relPath));
171574
171588
  }
171575
171589
  readContent(relPath) {
171576
171590
  const overlaid = this.overlay.get(relPath);
@@ -171592,7 +171606,7 @@ class Project {
171592
171606
  paths.add(relPath);
171593
171607
  }
171594
171608
  }
171595
- return [...paths].sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
171609
+ return [...paths].toSorted(comparePaths3);
171596
171610
  }
171597
171611
  contentFor(relPath, scanDiagnostics) {
171598
171612
  const overlaid = this.overlay.get(relPath);
@@ -171607,6 +171621,15 @@ class Project {
171607
171621
  return read.content;
171608
171622
  }
171609
171623
  }
171624
+ function comparePaths3(left, right) {
171625
+ if (left < right) {
171626
+ return -1;
171627
+ }
171628
+ if (left > right) {
171629
+ return 1;
171630
+ }
171631
+ return 0;
171632
+ }
171610
171633
  function emptyState() {
171611
171634
  const graph2 = buildLinkGraph([], []);
171612
171635
  return {
@@ -171617,24 +171640,70 @@ function emptyState() {
171617
171640
  };
171618
171641
  }
171619
171642
 
171620
- // src/lsp/paths.ts
171621
- import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep } from "node:path";
171622
- import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
171623
- function uriToRelativePath(projectRoot, uri) {
171624
- let absolute;
171625
- try {
171626
- absolute = fileURLToPath2(uri);
171627
- } catch {
171628
- return;
171643
+ // src/lsp/transport.ts
171644
+ var HEADER_SEPARATOR = `\r
171645
+ \r
171646
+ `;
171647
+ var CONTENT_LENGTH_HEADER = "content-length";
171648
+ function encodeMessage(message) {
171649
+ const body = Buffer.from(JSON.stringify(message), "utf8");
171650
+ const header = Buffer.from(`Content-Length: ${body.byteLength}${HEADER_SEPARATOR}`, "utf8");
171651
+ return Buffer.concat([header, body]);
171652
+ }
171653
+
171654
+ class MessageReader {
171655
+ buffer = Buffer.alloc(0);
171656
+ append(chunk) {
171657
+ this.buffer = Buffer.concat([this.buffer, Buffer.from(chunk)]);
171629
171658
  }
171630
- const rel = relative2(projectRoot, absolute);
171631
- if (rel === "" || rel.startsWith("..") || isAbsolute2(rel)) {
171632
- return;
171659
+ read() {
171660
+ const messages = [];
171661
+ for (;; ) {
171662
+ const message = this.readOne();
171663
+ if (message === null) {
171664
+ break;
171665
+ }
171666
+ messages.push(message.value);
171667
+ }
171668
+ return messages;
171669
+ }
171670
+ readOne() {
171671
+ const separatorText = HEADER_SEPARATOR;
171672
+ const headerEnd = this.buffer.indexOf(separatorText, 0, "utf8");
171673
+ if (headerEnd === -1) {
171674
+ return null;
171675
+ }
171676
+ const headerText = this.buffer.toString("utf8", 0, headerEnd);
171677
+ const contentLength = parseContentLength(headerText);
171678
+ const bodyStart = headerEnd + separatorText.length;
171679
+ if (this.buffer.byteLength - bodyStart < contentLength) {
171680
+ return null;
171681
+ }
171682
+ const bodyEnd = bodyStart + contentLength;
171683
+ const bodyText = this.buffer.toString("utf8", bodyStart, bodyEnd);
171684
+ this.buffer = this.buffer.subarray(bodyEnd);
171685
+ return { value: JSON.parse(bodyText) };
171633
171686
  }
171634
- return rel.split(sep).join("/");
171635
171687
  }
171636
- function relativePathToUri(projectRoot, relPath) {
171637
- return pathToFileURL(resolve2(projectRoot, relPath)).href;
171688
+ function parseContentLength(headerText) {
171689
+ const lines = headerText.split(`\r
171690
+ `);
171691
+ for (const line of lines) {
171692
+ const colonIndex = line.indexOf(":");
171693
+ if (colonIndex === -1) {
171694
+ continue;
171695
+ }
171696
+ const name = line.slice(0, colonIndex).trim().toLowerCase();
171697
+ if (name !== CONTENT_LENGTH_HEADER) {
171698
+ continue;
171699
+ }
171700
+ const value = Number.parseInt(line.slice(colonIndex + 1).trim(), 10);
171701
+ if (Number.isNaN(value) || value < 0) {
171702
+ throw new Error(`Invalid Content-Length header: ${line}`);
171703
+ }
171704
+ return value;
171705
+ }
171706
+ throw new Error("Malformed LSP message: missing Content-Length header.");
171638
171707
  }
171639
171708
 
171640
171709
  // src/lsp/server.ts
@@ -171901,18 +171970,12 @@ function fullChangeText(changes) {
171901
171970
  }
171902
171971
 
171903
171972
  // src/cli/init.ts
171904
- import {
171905
- cpSync,
171906
- mkdirSync as mkdirSync2,
171907
- readFileSync as readFileSync4,
171908
- statSync as statSync3,
171909
- writeFileSync
171910
- } from "node:fs";
171973
+ import { cpSync, mkdirSync as mkdirSync2, readFileSync as readFileSync4, statSync as statSync4, writeFileSync } from "node:fs";
171911
171974
  import { join as join7, resolve as resolve3 } from "node:path";
171912
171975
 
171913
171976
  // src/core/init-discovery.ts
171914
- import { existsSync as existsSync2, readdirSync as readdirSync2, statSync } from "node:fs";
171915
- import { basename, dirname as dirname2, join as join5 } from "node:path";
171977
+ import { existsSync as existsSync2, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
171978
+ import { basename, dirname as dirname3, join as join5 } from "node:path";
171916
171979
  var HIGH_CONFIDENCE_DIR_NAMES = new Set([
171917
171980
  "docs/specs",
171918
171981
  "specs",
@@ -171975,7 +172038,7 @@ function discoverDocsScope(projectRoot) {
171975
172038
  }
171976
172039
  const grouped = new Map;
171977
172040
  for (const filePath of eligible) {
171978
- const directory = dirname2(filePath);
172041
+ const directory = dirname3(filePath);
171979
172042
  const existing = grouped.get(directory) ?? [];
171980
172043
  existing.push(filePath);
171981
172044
  grouped.set(directory, existing);
@@ -171985,7 +172048,7 @@ function discoverDocsScope(projectRoot) {
171985
172048
  pattern: `${directory}/**/*.md`,
171986
172049
  score: scoreDocsDirectory(directory),
171987
172050
  fileCount: files.length
171988
- })).sort((left, right) => right.score !== left.score ? right.score - left.score : left.directory.localeCompare(right.directory));
172051
+ })).toSorted((left, right) => right.score !== left.score ? right.score - left.score : left.directory.localeCompare(right.directory));
171989
172052
  const topScore = candidates[0]?.score ?? 0;
171990
172053
  if (topScore === 0) {
171991
172054
  return {
@@ -172082,7 +172145,7 @@ function collectMarkdownFiles(projectRoot, currentDir = ".") {
172082
172145
  const absolutePath = join5(projectRoot, relPath);
172083
172146
  let stats;
172084
172147
  try {
172085
- stats = statSync(absolutePath);
172148
+ stats = statSync2(absolutePath);
172086
172149
  } catch {
172087
172150
  continue;
172088
172151
  }
@@ -172094,7 +172157,7 @@ function collectMarkdownFiles(projectRoot, currentDir = ".") {
172094
172157
  files.push(relPath);
172095
172158
  }
172096
172159
  }
172097
- return files.sort();
172160
+ return files.toSorted();
172098
172161
  }
172099
172162
  function isEligibleDocsFile(filePath) {
172100
172163
  if (EXCLUDED_PROSE_BASENAMES.has(basename(filePath).toLowerCase())) {
@@ -172162,14 +172225,8 @@ function isExcludedCodeFile(filePath, language) {
172162
172225
  }
172163
172226
 
172164
172227
  // src/core/init-plan.ts
172165
- import {
172166
- existsSync as existsSync3,
172167
- readdirSync as readdirSync3,
172168
- readFileSync as readFileSync3,
172169
- realpathSync as realpathSync2,
172170
- statSync as statSync2
172171
- } from "node:fs";
172172
- import { dirname as dirname3, join as join6, relative as relative4 } from "node:path";
172228
+ import { existsSync as existsSync3, readdirSync as readdirSync3, readFileSync as readFileSync3, realpathSync as realpathSync2, statSync as statSync3 } from "node:fs";
172229
+ import { dirname as dirname4, join as join6, relative as relative3 } from "node:path";
172173
172230
  import { fileURLToPath as fileURLToPath4 } from "node:url";
172174
172231
  var CONFIG_FILE_NAME2 = "docbridge.config.json";
172175
172232
  var INIT_SKILL_NAMES = [
@@ -172267,12 +172324,12 @@ function resolvePackageRoot(moduleUrl = import.meta.url) {
172267
172324
  } catch {
172268
172325
  resolved = modulePath;
172269
172326
  }
172270
- let dir = dirname3(resolved);
172327
+ let dir = dirname4(resolved);
172271
172328
  for (;; ) {
172272
172329
  if (existsSync3(join6(dir, "templates", "skills"))) {
172273
172330
  return dir;
172274
172331
  }
172275
- const parent = dirname3(dir);
172332
+ const parent = dirname4(dir);
172276
172333
  if (parent === dir) {
172277
172334
  return dir;
172278
172335
  }
@@ -172287,7 +172344,7 @@ function listDistributableSkills(packageRoot) {
172287
172344
  } catch {
172288
172345
  return [];
172289
172346
  }
172290
- return entries.filter((entry) => entry.startsWith("docbridge-")).filter((entry) => existsSync3(join6(skillsRoot, entry, "SKILL.md"))).sort();
172347
+ return entries.filter((entry) => entry.startsWith("docbridge-")).filter((entry) => existsSync3(join6(skillsRoot, entry, "SKILL.md"))).toSorted();
172291
172348
  }
172292
172349
  function formatInitPlan(plan) {
172293
172350
  const lines = [];
@@ -172409,7 +172466,7 @@ function planSkillOperations(input) {
172409
172466
  }
172410
172467
  operations.push({
172411
172468
  action,
172412
- path: relative4(input.projectRoot, destinationDir),
172469
+ path: relative3(input.projectRoot, destinationDir),
172413
172470
  reason
172414
172471
  });
172415
172472
  }
@@ -172507,7 +172564,12 @@ function agentDestinations(agentTarget) {
172507
172564
  }
172508
172565
  }
172509
172566
  function formatFileOp(operation) {
172510
- const label = operation.action === "would-create" ? "would create" : operation.action === "would-overwrite" ? "would overwrite" : operation.action;
172567
+ let label = operation.action;
172568
+ if (operation.action === "would-create") {
172569
+ label = "would create";
172570
+ } else if (operation.action === "would-overwrite") {
172571
+ label = "would overwrite";
172572
+ }
172511
172573
  const reason = operation.reason ? ` (${operation.reason})` : "";
172512
172574
  return `- ${label} ${operation.path}${reason}`;
172513
172575
  }
@@ -172745,7 +172807,7 @@ function resolveProjectRoot(root) {
172745
172807
  const projectRoot = resolve3(root);
172746
172808
  let stats;
172747
172809
  try {
172748
- stats = statSync3(projectRoot);
172810
+ stats = statSync4(projectRoot);
172749
172811
  } catch {
172750
172812
  throw new InitCliError(`Root path does not exist: ${root}`);
172751
172813
  }
@@ -172968,7 +173030,7 @@ function resolveProjectRoot2(root) {
172968
173030
  const projectRoot = resolve4(root);
172969
173031
  let stats;
172970
173032
  try {
172971
- stats = statSync4(projectRoot);
173033
+ stats = statSync5(projectRoot);
172972
173034
  } catch {
172973
173035
  throw new CliError(`Root path does not exist: ${root}`);
172974
173036
  }