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/CHANGELOG.md +30 -1
- package/README.md +7 -104
- package/dist/bin/darwin-arm64/SHA256SUMS +2 -2
- package/dist/bin/darwin-arm64/{speclink-swift-scanner → docbridge-swift-scanner} +0 -0
- package/dist/bin/darwin-arm64/{speclink_dart_scanner → docbridge_dart_scanner} +0 -0
- package/dist/bin/linux-x64/SHA256SUMS +2 -2
- package/dist/bin/linux-x64/{speclink-swift-scanner → docbridge-swift-scanner} +0 -0
- package/dist/bin/linux-x64/{speclink_dart_scanner → docbridge_dart_scanner} +0 -0
- package/dist/index.js +319 -257
- package/package.json +23 -21
- package/schemas/context-output.schema.json +9 -1
- package/templates/skills/docbridge-adopt/SKILL.md +5 -5
- package/templates/skills/docbridge-annotate/SKILL.md +9 -8
- package/templates/skills/docbridge-sync/SKILL.md +2 -2
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: () =>
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 &&
|
|
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 =
|
|
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 &&
|
|
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 ||
|
|
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
|
|
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 &&
|
|
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
|
|
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,
|
|
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,
|
|
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 ||
|
|
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 ||
|
|
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: () =>
|
|
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 (
|
|
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
|
|
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.
|
|
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
|
-
"
|
|
168785
|
-
"lsp"
|
|
168772
|
+
"specification"
|
|
168786
168773
|
],
|
|
168787
|
-
|
|
168788
|
-
|
|
168789
|
-
|
|
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].
|
|
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: ${
|
|
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
|
|
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 =
|
|
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" ? "
|
|
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].
|
|
170015
|
+
return [...diagnostics].toSorted(compareDiagnostics);
|
|
169950
170016
|
}
|
|
169951
170017
|
function summarizeDiagnostics(diagnostics) {
|
|
169952
|
-
|
|
170018
|
+
const summary = { errors: 0, warnings: 0 };
|
|
170019
|
+
for (const diagnostic of diagnostics) {
|
|
169953
170020
|
if (diagnostic.severity === "error") {
|
|
169954
|
-
|
|
169955
|
-
|
|
169956
|
-
|
|
169957
|
-
};
|
|
170021
|
+
summary.errors += 1;
|
|
170022
|
+
} else {
|
|
170023
|
+
summary.warnings += 1;
|
|
169958
170024
|
}
|
|
169959
|
-
|
|
169960
|
-
|
|
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.
|
|
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].
|
|
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()].
|
|
170780
|
+
const contexts = [...blockByEndpoint.values()].toSorted(compareBlocks);
|
|
170721
170781
|
for (const block of contexts) {
|
|
170722
|
-
block.linkedFrom = [...linkedFromByEndpoint.get(block.endpoint) ?? []].
|
|
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).
|
|
170951
|
-
const pairs = computePairs(includedEdges).
|
|
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").
|
|
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.
|
|
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)).
|
|
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.
|
|
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.
|
|
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].
|
|
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/
|
|
171621
|
-
|
|
171622
|
-
|
|
171623
|
-
|
|
171624
|
-
|
|
171625
|
-
|
|
171626
|
-
|
|
171627
|
-
|
|
171628
|
-
|
|
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
|
-
|
|
171631
|
-
|
|
171632
|
-
|
|
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
|
|
171637
|
-
|
|
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
|
|
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 =
|
|
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
|
-
})).
|
|
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 =
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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"))).
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
173033
|
+
stats = statSync5(projectRoot);
|
|
172972
173034
|
} catch {
|
|
172973
173035
|
throw new CliError(`Root path does not exist: ${root}`);
|
|
172974
173036
|
}
|