gsd-pi 2.8.2 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cli.js +5 -0
- package/dist/loader.js +1 -1
- package/dist/update-check.d.ts +24 -0
- package/dist/update-check.js +93 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.d.ts +4 -2
- package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.d.ts +46 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.js +758 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/client.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.d.ts +23 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.js +267 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/config.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.d.ts +17 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.js +101 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/edits.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.d.ts +15 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.js +46 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/helpers.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.d.ts +35 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.js +709 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/index.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts +2 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +308 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.d.ts +34 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.js +136 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.d.ts +262 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.js +64 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/types.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.d.ts +50 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.js +574 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/lsp/utils.js.map +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.d.ts +13 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.js +4 -0
- package/node_modules/@gsd/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +10 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +2 -2
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.js +80 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +5 -0
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/node_modules/@gsd/pi-coding-agent/src/core/extensions/types.ts +4 -2
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/client.ts +880 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/config.ts +325 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/defaults.json +456 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/edits.ts +109 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/helpers.ts +54 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/index.ts +943 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +407 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lsp.md +33 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/lspmux.ts +199 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/types.ts +421 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/lsp/utils.ts +682 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/node_modules/@gsd/pi-coding-agent/src/core/tools/index.ts +10 -0
- package/node_modules/@gsd/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +2 -2
- package/node_modules/@gsd/pi-coding-agent/src/modes/interactive/interactive-mode.ts +94 -2
- package/node_modules/@gsd/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
- package/node_modules/@gsd/pi-coding-agent/src/modes/rpc/rpc-types.ts +2 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +4 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +46 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js +758 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +23 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.js +267 -0
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +17 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.js +101 -0
- package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.js +46 -0
- package/packages/pi-coding-agent/dist/core/lsp/helpers.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts +35 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js +709 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +308 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +34 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +136 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +262 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.js +64 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +50 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.js +574 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +13 -0
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +4 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +10 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +80 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +4 -2
- package/packages/pi-coding-agent/src/core/lsp/client.ts +880 -0
- package/packages/pi-coding-agent/src/core/lsp/config.ts +325 -0
- package/packages/pi-coding-agent/src/core/lsp/defaults.json +456 -0
- package/packages/pi-coding-agent/src/core/lsp/edits.ts +109 -0
- package/packages/pi-coding-agent/src/core/lsp/helpers.ts +54 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +943 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +407 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp.md +33 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +199 -0
- package/packages/pi-coding-agent/src/core/lsp/types.ts +421 -0
- package/packages/pi-coding-agent/src/core/lsp/utils.ts +682 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/tools/index.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +2 -2
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +94 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +2 -1
- package/src/resources/extensions/ask-user-questions.ts +42 -2
- package/src/resources/extensions/bg-shell/index.ts +34 -37
- package/src/resources/extensions/browser-tools/core.d.ts +205 -0
- package/src/resources/extensions/browser-tools/index.ts +2 -2
- package/src/resources/extensions/browser-tools/refs.ts +1 -1
- package/src/resources/extensions/browser-tools/tools/session.ts +1 -1
- package/src/resources/extensions/context7/index.ts +2 -2
- package/src/resources/extensions/get-secrets-from-user.ts +3 -2
- package/src/resources/extensions/google-search/index.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +126 -12
- package/src/resources/extensions/gsd/commands.ts +218 -3
- package/src/resources/extensions/gsd/doctor.ts +1 -1
- package/src/resources/extensions/gsd/git-service.ts +163 -13
- package/src/resources/extensions/gsd/guided-flow.ts +19 -9
- package/src/resources/extensions/gsd/index.ts +17 -7
- package/src/resources/extensions/gsd/preferences.ts +1 -1
- package/src/resources/extensions/gsd/tests/git-service.test.ts +226 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/next-milestone-id.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +352 -0
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/worktree.ts +20 -1
- package/src/resources/extensions/mac-tools/index.ts +1 -1
- package/src/resources/extensions/search-the-web/command-search-provider.ts +1 -1
- package/src/resources/extensions/search-the-web/format.ts +1 -1
- package/src/resources/extensions/search-the-web/index.ts +5 -5
- package/src/resources/extensions/search-the-web/native-search.ts +5 -6
- package/src/resources/extensions/search-the-web/tool-fetch-page.ts +7 -7
- package/src/resources/extensions/search-the-web/tool-llm-context.ts +11 -11
- package/src/resources/extensions/search-the-web/tool-search.ts +10 -10
- package/src/resources/extensions/shared/interview-ui.ts +2 -2
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
import * as fsPromises from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { glob } from "glob";
|
|
4
|
+
import { isEnoent } from "./helpers.js";
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Language Detection
|
|
7
|
+
// =============================================================================
|
|
8
|
+
const LANGUAGE_MAP = {
|
|
9
|
+
// TypeScript/JavaScript
|
|
10
|
+
".ts": "typescript",
|
|
11
|
+
".tsx": "typescriptreact",
|
|
12
|
+
".js": "javascript",
|
|
13
|
+
".jsx": "javascriptreact",
|
|
14
|
+
".mjs": "javascript",
|
|
15
|
+
".cjs": "javascript",
|
|
16
|
+
".mts": "typescript",
|
|
17
|
+
".cts": "typescript",
|
|
18
|
+
// Systems languages
|
|
19
|
+
".rs": "rust",
|
|
20
|
+
".go": "go",
|
|
21
|
+
".c": "c",
|
|
22
|
+
".h": "c",
|
|
23
|
+
".cpp": "cpp",
|
|
24
|
+
".cc": "cpp",
|
|
25
|
+
".cxx": "cpp",
|
|
26
|
+
".hpp": "cpp",
|
|
27
|
+
".hxx": "cpp",
|
|
28
|
+
".zig": "zig",
|
|
29
|
+
// Scripting languages
|
|
30
|
+
".py": "python",
|
|
31
|
+
".rb": "ruby",
|
|
32
|
+
".lua": "lua",
|
|
33
|
+
".sh": "shellscript",
|
|
34
|
+
".bash": "shellscript",
|
|
35
|
+
".zsh": "shellscript",
|
|
36
|
+
".fish": "fish",
|
|
37
|
+
".pl": "perl",
|
|
38
|
+
".php": "php",
|
|
39
|
+
// JVM languages
|
|
40
|
+
".java": "java",
|
|
41
|
+
".kt": "kotlin",
|
|
42
|
+
".kts": "kotlin",
|
|
43
|
+
".scala": "scala",
|
|
44
|
+
".groovy": "groovy",
|
|
45
|
+
".clj": "clojure",
|
|
46
|
+
// .NET languages
|
|
47
|
+
".cs": "csharp",
|
|
48
|
+
".fs": "fsharp",
|
|
49
|
+
".vb": "vb",
|
|
50
|
+
// Web
|
|
51
|
+
".html": "html",
|
|
52
|
+
".htm": "html",
|
|
53
|
+
".css": "css",
|
|
54
|
+
".scss": "scss",
|
|
55
|
+
".sass": "sass",
|
|
56
|
+
".less": "less",
|
|
57
|
+
".vue": "vue",
|
|
58
|
+
".svelte": "svelte",
|
|
59
|
+
// Data formats
|
|
60
|
+
".json": "json",
|
|
61
|
+
".jsonc": "jsonc",
|
|
62
|
+
".yaml": "yaml",
|
|
63
|
+
".yml": "yaml",
|
|
64
|
+
".toml": "toml",
|
|
65
|
+
".xml": "xml",
|
|
66
|
+
".ini": "ini",
|
|
67
|
+
// Documentation
|
|
68
|
+
".md": "markdown",
|
|
69
|
+
".markdown": "markdown",
|
|
70
|
+
".rst": "restructuredtext",
|
|
71
|
+
".adoc": "asciidoc",
|
|
72
|
+
".tex": "latex",
|
|
73
|
+
// Other
|
|
74
|
+
".sql": "sql",
|
|
75
|
+
".graphql": "graphql",
|
|
76
|
+
".gql": "graphql",
|
|
77
|
+
".proto": "protobuf",
|
|
78
|
+
".dockerfile": "dockerfile",
|
|
79
|
+
".tf": "terraform",
|
|
80
|
+
".hcl": "hcl",
|
|
81
|
+
".nix": "nix",
|
|
82
|
+
".ex": "elixir",
|
|
83
|
+
".exs": "elixir",
|
|
84
|
+
".erl": "erlang",
|
|
85
|
+
".hrl": "erlang",
|
|
86
|
+
".hs": "haskell",
|
|
87
|
+
".ml": "ocaml",
|
|
88
|
+
".mli": "ocaml",
|
|
89
|
+
".swift": "swift",
|
|
90
|
+
".r": "r",
|
|
91
|
+
".R": "r",
|
|
92
|
+
".jl": "julia",
|
|
93
|
+
".dart": "dart",
|
|
94
|
+
".elm": "elm",
|
|
95
|
+
".v": "v",
|
|
96
|
+
".nim": "nim",
|
|
97
|
+
".cr": "crystal",
|
|
98
|
+
".d": "d",
|
|
99
|
+
".pas": "pascal",
|
|
100
|
+
".pp": "pascal",
|
|
101
|
+
".lisp": "lisp",
|
|
102
|
+
".lsp": "lisp",
|
|
103
|
+
".rkt": "racket",
|
|
104
|
+
".scm": "scheme",
|
|
105
|
+
".ps1": "powershell",
|
|
106
|
+
".psm1": "powershell",
|
|
107
|
+
".bat": "bat",
|
|
108
|
+
".cmd": "bat",
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Detect language ID from file path.
|
|
112
|
+
*/
|
|
113
|
+
export function detectLanguageId(filePath) {
|
|
114
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
115
|
+
const basename = path.basename(filePath).toLowerCase();
|
|
116
|
+
if (basename === "dockerfile" || basename.startsWith("dockerfile.")) {
|
|
117
|
+
return "dockerfile";
|
|
118
|
+
}
|
|
119
|
+
if (basename === "makefile" || basename === "gnumakefile") {
|
|
120
|
+
return "makefile";
|
|
121
|
+
}
|
|
122
|
+
if (basename === "cmakelists.txt" || ext === ".cmake") {
|
|
123
|
+
return "cmake";
|
|
124
|
+
}
|
|
125
|
+
return LANGUAGE_MAP[ext] ?? "plaintext";
|
|
126
|
+
}
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// URI Handling (Cross-Platform)
|
|
129
|
+
// =============================================================================
|
|
130
|
+
export function fileToUri(filePath) {
|
|
131
|
+
const resolved = path.resolve(filePath);
|
|
132
|
+
if (process.platform === "win32") {
|
|
133
|
+
return `file:///${resolved.replace(/\\/g, "/")}`;
|
|
134
|
+
}
|
|
135
|
+
return `file://${resolved}`;
|
|
136
|
+
}
|
|
137
|
+
export function uriToFile(uri) {
|
|
138
|
+
if (!uri.startsWith("file://")) {
|
|
139
|
+
return uri;
|
|
140
|
+
}
|
|
141
|
+
let filePath = decodeURIComponent(uri.slice(7));
|
|
142
|
+
if (process.platform === "win32" && filePath.startsWith("/") && /^[A-Za-z]:/.test(filePath.slice(1))) {
|
|
143
|
+
filePath = filePath.slice(1);
|
|
144
|
+
}
|
|
145
|
+
return filePath;
|
|
146
|
+
}
|
|
147
|
+
// =============================================================================
|
|
148
|
+
// Diagnostic Formatting
|
|
149
|
+
// =============================================================================
|
|
150
|
+
const SEVERITY_NAMES = {
|
|
151
|
+
1: "error",
|
|
152
|
+
2: "warning",
|
|
153
|
+
3: "info",
|
|
154
|
+
4: "hint",
|
|
155
|
+
};
|
|
156
|
+
export function severityToString(severity) {
|
|
157
|
+
return SEVERITY_NAMES[severity ?? 1] ?? "unknown";
|
|
158
|
+
}
|
|
159
|
+
export function sortDiagnostics(diagnostics) {
|
|
160
|
+
return diagnostics.sort((a, b) => {
|
|
161
|
+
const aSeverity = a.severity ?? 1;
|
|
162
|
+
const bSeverity = b.severity ?? 1;
|
|
163
|
+
if (aSeverity !== bSeverity)
|
|
164
|
+
return aSeverity - bSeverity;
|
|
165
|
+
const aLine = a.range.start.line;
|
|
166
|
+
const bLine = b.range.start.line;
|
|
167
|
+
if (aLine !== bLine)
|
|
168
|
+
return aLine - bLine;
|
|
169
|
+
const aCol = a.range.start.character;
|
|
170
|
+
const bCol = b.range.start.character;
|
|
171
|
+
if (aCol !== bCol)
|
|
172
|
+
return aCol - bCol;
|
|
173
|
+
return a.message.localeCompare(b.message);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
export function severityToIcon(severity) {
|
|
177
|
+
switch (severity ?? 1) {
|
|
178
|
+
case 1:
|
|
179
|
+
return "[E]";
|
|
180
|
+
case 2:
|
|
181
|
+
return "[W]";
|
|
182
|
+
case 3:
|
|
183
|
+
return "[I]";
|
|
184
|
+
case 4:
|
|
185
|
+
return "[H]";
|
|
186
|
+
default:
|
|
187
|
+
return "[E]";
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function stripDiagnosticNoise(message) {
|
|
191
|
+
return message
|
|
192
|
+
.split("\n")
|
|
193
|
+
.filter(line => {
|
|
194
|
+
const trimmed = line.trim();
|
|
195
|
+
if (trimmed.startsWith("for further information visit"))
|
|
196
|
+
return false;
|
|
197
|
+
if (/^https?:\/\//.test(trimmed))
|
|
198
|
+
return false;
|
|
199
|
+
return true;
|
|
200
|
+
})
|
|
201
|
+
.join("\n")
|
|
202
|
+
.trim();
|
|
203
|
+
}
|
|
204
|
+
export function formatDiagnostic(diagnostic, filePath) {
|
|
205
|
+
const severity = severityToString(diagnostic.severity);
|
|
206
|
+
const line = diagnostic.range.start.line + 1;
|
|
207
|
+
const col = diagnostic.range.start.character + 1;
|
|
208
|
+
const source = diagnostic.source ? `[${diagnostic.source}] ` : "";
|
|
209
|
+
const code = diagnostic.code !== undefined ? ` (${diagnostic.code})` : "";
|
|
210
|
+
const message = stripDiagnosticNoise(diagnostic.message);
|
|
211
|
+
return `${filePath}:${line}:${col} [${severity}] ${source}${message}${code}`;
|
|
212
|
+
}
|
|
213
|
+
const DIAG_PATH_RE = /^(.+?):(\d+:\d+\s+.*)$/;
|
|
214
|
+
export function formatGroupedDiagnosticMessages(messages) {
|
|
215
|
+
const diagnosticsByFile = new Map();
|
|
216
|
+
const fileOrder = [];
|
|
217
|
+
const ungrouped = [];
|
|
218
|
+
for (const msg of messages) {
|
|
219
|
+
const match = DIAG_PATH_RE.exec(msg);
|
|
220
|
+
if (!match) {
|
|
221
|
+
ungrouped.push(msg);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const [, rawFilePath, rest] = match;
|
|
225
|
+
const filePath = rawFilePath.replace(/\\/g, "/");
|
|
226
|
+
if (!diagnosticsByFile.has(filePath)) {
|
|
227
|
+
diagnosticsByFile.set(filePath, []);
|
|
228
|
+
fileOrder.push(filePath);
|
|
229
|
+
}
|
|
230
|
+
diagnosticsByFile.get(filePath)?.push(rest);
|
|
231
|
+
}
|
|
232
|
+
if (diagnosticsByFile.size === 0) {
|
|
233
|
+
return ungrouped.join("\n");
|
|
234
|
+
}
|
|
235
|
+
const filesByDirectory = new Map();
|
|
236
|
+
for (const filePath of fileOrder) {
|
|
237
|
+
const directory = path.dirname(filePath).replace(/\\/g, "/");
|
|
238
|
+
if (!filesByDirectory.has(directory)) {
|
|
239
|
+
filesByDirectory.set(directory, []);
|
|
240
|
+
}
|
|
241
|
+
filesByDirectory.get(directory)?.push(filePath);
|
|
242
|
+
}
|
|
243
|
+
const lines = [];
|
|
244
|
+
for (const [directory, directoryFiles] of filesByDirectory) {
|
|
245
|
+
if (directory === ".") {
|
|
246
|
+
for (const filePath of directoryFiles) {
|
|
247
|
+
if (lines.length > 0) {
|
|
248
|
+
lines.push("");
|
|
249
|
+
}
|
|
250
|
+
lines.push(`# ${path.basename(filePath)}`);
|
|
251
|
+
for (const diagnostic of diagnosticsByFile.get(filePath) ?? []) {
|
|
252
|
+
lines.push(` ${diagnostic}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (lines.length > 0) {
|
|
258
|
+
lines.push("");
|
|
259
|
+
}
|
|
260
|
+
lines.push(`# ${directory}`);
|
|
261
|
+
for (const filePath of directoryFiles) {
|
|
262
|
+
lines.push(`## └─ ${path.basename(filePath)}`);
|
|
263
|
+
for (const diagnostic of diagnosticsByFile.get(filePath) ?? []) {
|
|
264
|
+
lines.push(` ${diagnostic}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (ungrouped.length > 0) {
|
|
269
|
+
lines.push("");
|
|
270
|
+
for (const msg of ungrouped) {
|
|
271
|
+
lines.push(msg);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return lines.join("\n");
|
|
275
|
+
}
|
|
276
|
+
export function formatDiagnosticsSummary(diagnostics) {
|
|
277
|
+
const counts = { error: 0, warning: 0, info: 0, hint: 0 };
|
|
278
|
+
for (const d of diagnostics) {
|
|
279
|
+
const sev = severityToString(d.severity);
|
|
280
|
+
if (sev in counts) {
|
|
281
|
+
counts[sev]++;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const parts = [];
|
|
285
|
+
if (counts.error > 0)
|
|
286
|
+
parts.push(`${counts.error} error(s)`);
|
|
287
|
+
if (counts.warning > 0)
|
|
288
|
+
parts.push(`${counts.warning} warning(s)`);
|
|
289
|
+
if (counts.info > 0)
|
|
290
|
+
parts.push(`${counts.info} info(s)`);
|
|
291
|
+
if (counts.hint > 0)
|
|
292
|
+
parts.push(`${counts.hint} hint(s)`);
|
|
293
|
+
return parts.length > 0 ? parts.join(", ") : "no issues";
|
|
294
|
+
}
|
|
295
|
+
// =============================================================================
|
|
296
|
+
// Location Formatting
|
|
297
|
+
// =============================================================================
|
|
298
|
+
export function formatLocation(location, cwd) {
|
|
299
|
+
const file = path.relative(cwd, uriToFile(location.uri));
|
|
300
|
+
const line = location.range.start.line + 1;
|
|
301
|
+
const col = location.range.start.character + 1;
|
|
302
|
+
return `${file}:${line}:${col}`;
|
|
303
|
+
}
|
|
304
|
+
export function formatPosition(line, col) {
|
|
305
|
+
return `${line}:${col}`;
|
|
306
|
+
}
|
|
307
|
+
// =============================================================================
|
|
308
|
+
// WorkspaceEdit Formatting
|
|
309
|
+
// =============================================================================
|
|
310
|
+
export function formatWorkspaceEdit(edit, cwd) {
|
|
311
|
+
const results = [];
|
|
312
|
+
if (edit.changes) {
|
|
313
|
+
for (const [uri, textEdits] of Object.entries(edit.changes)) {
|
|
314
|
+
const file = path.relative(cwd, uriToFile(uri));
|
|
315
|
+
results.push(`${file}: ${textEdits.length} edit${textEdits.length > 1 ? "s" : ""}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (edit.documentChanges) {
|
|
319
|
+
for (const change of edit.documentChanges) {
|
|
320
|
+
if ("edits" in change && change.textDocument) {
|
|
321
|
+
const file = path.relative(cwd, uriToFile(change.textDocument.uri));
|
|
322
|
+
results.push(`${file}: ${change.edits.length} edit${change.edits.length > 1 ? "s" : ""}`);
|
|
323
|
+
}
|
|
324
|
+
else if ("kind" in change) {
|
|
325
|
+
switch (change.kind) {
|
|
326
|
+
case "create":
|
|
327
|
+
results.push(`CREATE: ${path.relative(cwd, uriToFile(change.uri))}`);
|
|
328
|
+
break;
|
|
329
|
+
case "rename":
|
|
330
|
+
results.push(`RENAME: ${path.relative(cwd, uriToFile(change.oldUri))} -> ${path.relative(cwd, uriToFile(change.newUri))}`);
|
|
331
|
+
break;
|
|
332
|
+
case "delete":
|
|
333
|
+
results.push(`DELETE: ${path.relative(cwd, uriToFile(change.uri))}`);
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return results;
|
|
340
|
+
}
|
|
341
|
+
export function formatTextEdit(edit, maxLength = 50) {
|
|
342
|
+
const range = `${edit.range.start.line + 1}:${edit.range.start.character + 1}`;
|
|
343
|
+
const preview = edit.newText.length > maxLength
|
|
344
|
+
? `${edit.newText.slice(0, maxLength).replace(/\n/g, "\\n")}…`
|
|
345
|
+
: edit.newText.replace(/\n/g, "\\n");
|
|
346
|
+
return `line ${range} -> "${preview}"`;
|
|
347
|
+
}
|
|
348
|
+
// =============================================================================
|
|
349
|
+
// Symbol Formatting
|
|
350
|
+
// =============================================================================
|
|
351
|
+
const SYMBOL_KIND_LABELS = {
|
|
352
|
+
1: "File",
|
|
353
|
+
2: "Module",
|
|
354
|
+
3: "Namespace",
|
|
355
|
+
4: "Package",
|
|
356
|
+
5: "Class",
|
|
357
|
+
6: "Method",
|
|
358
|
+
7: "Property",
|
|
359
|
+
8: "Field",
|
|
360
|
+
9: "Constructor",
|
|
361
|
+
10: "Enum",
|
|
362
|
+
11: "Interface",
|
|
363
|
+
12: "Function",
|
|
364
|
+
13: "Variable",
|
|
365
|
+
14: "Constant",
|
|
366
|
+
15: "String",
|
|
367
|
+
16: "Number",
|
|
368
|
+
17: "Boolean",
|
|
369
|
+
18: "Array",
|
|
370
|
+
19: "Object",
|
|
371
|
+
20: "Key",
|
|
372
|
+
21: "Null",
|
|
373
|
+
22: "EnumMember",
|
|
374
|
+
23: "Struct",
|
|
375
|
+
24: "Event",
|
|
376
|
+
25: "Operator",
|
|
377
|
+
26: "TypeParameter",
|
|
378
|
+
};
|
|
379
|
+
export function symbolKindToIcon(kind) {
|
|
380
|
+
return `[${SYMBOL_KIND_LABELS[kind] ?? "?"}]`;
|
|
381
|
+
}
|
|
382
|
+
export function symbolKindToName(kind) {
|
|
383
|
+
return SYMBOL_KIND_LABELS[kind] ?? "Unknown";
|
|
384
|
+
}
|
|
385
|
+
export function formatDocumentSymbol(symbol, indent = 0) {
|
|
386
|
+
const prefix = " ".repeat(indent);
|
|
387
|
+
const icon = symbolKindToIcon(symbol.kind);
|
|
388
|
+
const line = symbol.range.start.line + 1;
|
|
389
|
+
const detail = symbol.detail ? ` ${symbol.detail}` : "";
|
|
390
|
+
const results = [`${prefix}${icon} ${symbol.name}${detail} @ line ${line}`];
|
|
391
|
+
if (symbol.children) {
|
|
392
|
+
for (const child of symbol.children) {
|
|
393
|
+
results.push(...formatDocumentSymbol(child, indent + 1));
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return results;
|
|
397
|
+
}
|
|
398
|
+
export function formatSymbolInformation(symbol, cwd) {
|
|
399
|
+
const icon = symbolKindToIcon(symbol.kind);
|
|
400
|
+
const location = formatLocation(symbol.location, cwd);
|
|
401
|
+
const container = symbol.containerName ? ` (${symbol.containerName})` : "";
|
|
402
|
+
return `${icon} ${symbol.name}${container} @ ${location}`;
|
|
403
|
+
}
|
|
404
|
+
export function filterWorkspaceSymbols(symbols, query) {
|
|
405
|
+
const needle = query.trim().toLowerCase();
|
|
406
|
+
if (!needle)
|
|
407
|
+
return symbols;
|
|
408
|
+
return symbols.filter(symbol => {
|
|
409
|
+
const fields = [symbol.name, symbol.containerName ?? "", uriToFile(symbol.location.uri)];
|
|
410
|
+
return fields.some(field => field.toLowerCase().includes(needle));
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
export function dedupeWorkspaceSymbols(symbols) {
|
|
414
|
+
const seen = new Set();
|
|
415
|
+
const unique = [];
|
|
416
|
+
for (const symbol of symbols) {
|
|
417
|
+
const key = [
|
|
418
|
+
symbol.name,
|
|
419
|
+
symbol.containerName ?? "",
|
|
420
|
+
symbol.kind,
|
|
421
|
+
symbol.location.uri,
|
|
422
|
+
symbol.location.range.start.line,
|
|
423
|
+
symbol.location.range.start.character,
|
|
424
|
+
].join(":");
|
|
425
|
+
if (seen.has(key))
|
|
426
|
+
continue;
|
|
427
|
+
seen.add(key);
|
|
428
|
+
unique.push(symbol);
|
|
429
|
+
}
|
|
430
|
+
return unique;
|
|
431
|
+
}
|
|
432
|
+
export function formatCodeAction(action, index) {
|
|
433
|
+
const kind = "kind" in action && action.kind ? action.kind : "action";
|
|
434
|
+
const preferred = "isPreferred" in action && action.isPreferred ? " (preferred)" : "";
|
|
435
|
+
const disabled = "disabled" in action && action.disabled ? ` (disabled: ${action.disabled.reason})` : "";
|
|
436
|
+
return `${index}: [${kind}] ${action.title}${preferred}${disabled}`;
|
|
437
|
+
}
|
|
438
|
+
function isCommandItem(action) {
|
|
439
|
+
return typeof action.command === "string";
|
|
440
|
+
}
|
|
441
|
+
export async function applyCodeAction(action, dependencies) {
|
|
442
|
+
if (isCommandItem(action)) {
|
|
443
|
+
await dependencies.executeCommand(action);
|
|
444
|
+
return { title: action.title, edits: [], executedCommands: [action.command] };
|
|
445
|
+
}
|
|
446
|
+
let resolvedAction = action;
|
|
447
|
+
if (!resolvedAction.edit && dependencies.resolveCodeAction) {
|
|
448
|
+
try {
|
|
449
|
+
resolvedAction = await dependencies.resolveCodeAction(resolvedAction);
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
// Resolve is optional; continue with unresolved action.
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const edits = resolvedAction.edit ? await dependencies.applyWorkspaceEdit(resolvedAction.edit) : [];
|
|
456
|
+
const executedCommands = [];
|
|
457
|
+
if (resolvedAction.command) {
|
|
458
|
+
await dependencies.executeCommand(resolvedAction.command);
|
|
459
|
+
executedCommands.push(resolvedAction.command.command);
|
|
460
|
+
}
|
|
461
|
+
if (edits.length === 0 && executedCommands.length === 0) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
return { title: resolvedAction.title, edits, executedCommands };
|
|
465
|
+
}
|
|
466
|
+
const GLOB_PATTERN_CHARS = /[*?[{]/;
|
|
467
|
+
export function hasGlobPattern(value) {
|
|
468
|
+
return GLOB_PATTERN_CHARS.test(value);
|
|
469
|
+
}
|
|
470
|
+
export async function collectGlobMatches(pattern, cwd, maxMatches) {
|
|
471
|
+
const normalizedLimit = Number.isFinite(maxMatches) ? Math.max(1, Math.trunc(maxMatches)) : 1;
|
|
472
|
+
const allMatches = await glob(pattern, { cwd });
|
|
473
|
+
if (allMatches.length > normalizedLimit) {
|
|
474
|
+
return { matches: allMatches.slice(0, normalizedLimit), truncated: true };
|
|
475
|
+
}
|
|
476
|
+
return { matches: allMatches, truncated: false };
|
|
477
|
+
}
|
|
478
|
+
// =============================================================================
|
|
479
|
+
// Hover Content Extraction
|
|
480
|
+
// =============================================================================
|
|
481
|
+
export function extractHoverText(contents) {
|
|
482
|
+
if (typeof contents === "string") {
|
|
483
|
+
return contents;
|
|
484
|
+
}
|
|
485
|
+
if (Array.isArray(contents)) {
|
|
486
|
+
return contents.map(c => extractHoverText(c)).join("\n\n");
|
|
487
|
+
}
|
|
488
|
+
if (typeof contents === "object" && contents !== null) {
|
|
489
|
+
if ("value" in contents && typeof contents.value === "string") {
|
|
490
|
+
return contents.value;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return String(contents);
|
|
494
|
+
}
|
|
495
|
+
// =============================================================================
|
|
496
|
+
// General Utilities
|
|
497
|
+
// =============================================================================
|
|
498
|
+
function firstNonWhitespaceColumn(lineText) {
|
|
499
|
+
const match = lineText.match(/\S/);
|
|
500
|
+
return match ? (match.index ?? 0) : 0;
|
|
501
|
+
}
|
|
502
|
+
function findSymbolMatchIndexes(lineText, symbol, caseInsensitive = false) {
|
|
503
|
+
if (symbol.length === 0)
|
|
504
|
+
return [];
|
|
505
|
+
const haystack = caseInsensitive ? lineText.toLowerCase() : lineText;
|
|
506
|
+
const needle = caseInsensitive ? symbol.toLowerCase() : symbol;
|
|
507
|
+
const indexes = [];
|
|
508
|
+
let fromIndex = 0;
|
|
509
|
+
while (fromIndex <= haystack.length - needle.length) {
|
|
510
|
+
const matchIndex = haystack.indexOf(needle, fromIndex);
|
|
511
|
+
if (matchIndex === -1)
|
|
512
|
+
break;
|
|
513
|
+
indexes.push(matchIndex);
|
|
514
|
+
fromIndex = matchIndex + needle.length;
|
|
515
|
+
}
|
|
516
|
+
return indexes;
|
|
517
|
+
}
|
|
518
|
+
function normalizeOccurrence(occurrence) {
|
|
519
|
+
if (occurrence === undefined || !Number.isFinite(occurrence))
|
|
520
|
+
return 1;
|
|
521
|
+
return Math.max(1, Math.trunc(occurrence));
|
|
522
|
+
}
|
|
523
|
+
export async function resolveSymbolColumn(filePath, line, symbol, occurrence) {
|
|
524
|
+
const lineNumber = Math.max(1, line);
|
|
525
|
+
const matchOccurrence = normalizeOccurrence(occurrence);
|
|
526
|
+
try {
|
|
527
|
+
const fileText = await fsPromises.readFile(filePath, "utf-8");
|
|
528
|
+
const lines = fileText.split("\n");
|
|
529
|
+
const targetLine = lines[lineNumber - 1] ?? "";
|
|
530
|
+
if (!symbol) {
|
|
531
|
+
return firstNonWhitespaceColumn(targetLine);
|
|
532
|
+
}
|
|
533
|
+
const exactIndexes = findSymbolMatchIndexes(targetLine, symbol);
|
|
534
|
+
const fallbackIndexes = exactIndexes.length > 0 ? exactIndexes : findSymbolMatchIndexes(targetLine, symbol, true);
|
|
535
|
+
if (fallbackIndexes.length === 0) {
|
|
536
|
+
throw new Error(`Symbol "${symbol}" not found on line ${lineNumber}`);
|
|
537
|
+
}
|
|
538
|
+
if (matchOccurrence > fallbackIndexes.length) {
|
|
539
|
+
throw new Error(`Symbol "${symbol}" occurrence ${matchOccurrence} is out of bounds on line ${lineNumber} (found ${fallbackIndexes.length})`);
|
|
540
|
+
}
|
|
541
|
+
return fallbackIndexes[matchOccurrence - 1];
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
if (isEnoent(error)) {
|
|
545
|
+
throw new Error(`File not found: ${filePath}`);
|
|
546
|
+
}
|
|
547
|
+
throw error;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
export async function readLocationContext(filePath, line, contextLines = 1) {
|
|
551
|
+
const targetLine = Math.max(1, line);
|
|
552
|
+
const surrounding = Math.max(0, contextLines);
|
|
553
|
+
try {
|
|
554
|
+
const fileText = await fsPromises.readFile(filePath, "utf-8");
|
|
555
|
+
const lines = fileText.split("\n");
|
|
556
|
+
if (lines.length === 0)
|
|
557
|
+
return [];
|
|
558
|
+
const startLine = Math.max(1, targetLine - surrounding);
|
|
559
|
+
const endLine = Math.min(lines.length, targetLine + surrounding);
|
|
560
|
+
const context = [];
|
|
561
|
+
for (let currentLine = startLine; currentLine <= endLine; currentLine++) {
|
|
562
|
+
const content = lines[currentLine - 1] ?? "";
|
|
563
|
+
context.push(`${currentLine}: ${content}`);
|
|
564
|
+
}
|
|
565
|
+
return context;
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
if (isEnoent(error)) {
|
|
569
|
+
return [];
|
|
570
|
+
}
|
|
571
|
+
throw error;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/core/lsp/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fsPromises from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { glob } from \"glob\";\nimport { isEnoent } from \"./helpers.js\";\nimport type {\n\tCodeAction,\n\tCommand,\n\tDiagnostic,\n\tDiagnosticSeverity,\n\tDocumentSymbol,\n\tLocation,\n\tSymbolInformation,\n\tSymbolKind,\n\tTextEdit,\n\tWorkspaceEdit,\n} from \"./types.js\";\n\n// =============================================================================\n// Language Detection\n// =============================================================================\n\nconst LANGUAGE_MAP: Record<string, string> = {\n\t// TypeScript/JavaScript\n\t\".ts\": \"typescript\",\n\t\".tsx\": \"typescriptreact\",\n\t\".js\": \"javascript\",\n\t\".jsx\": \"javascriptreact\",\n\t\".mjs\": \"javascript\",\n\t\".cjs\": \"javascript\",\n\t\".mts\": \"typescript\",\n\t\".cts\": \"typescript\",\n\n\t// Systems languages\n\t\".rs\": \"rust\",\n\t\".go\": \"go\",\n\t\".c\": \"c\",\n\t\".h\": \"c\",\n\t\".cpp\": \"cpp\",\n\t\".cc\": \"cpp\",\n\t\".cxx\": \"cpp\",\n\t\".hpp\": \"cpp\",\n\t\".hxx\": \"cpp\",\n\t\".zig\": \"zig\",\n\n\t// Scripting languages\n\t\".py\": \"python\",\n\t\".rb\": \"ruby\",\n\t\".lua\": \"lua\",\n\t\".sh\": \"shellscript\",\n\t\".bash\": \"shellscript\",\n\t\".zsh\": \"shellscript\",\n\t\".fish\": \"fish\",\n\t\".pl\": \"perl\",\n\t\".php\": \"php\",\n\n\t// JVM languages\n\t\".java\": \"java\",\n\t\".kt\": \"kotlin\",\n\t\".kts\": \"kotlin\",\n\t\".scala\": \"scala\",\n\t\".groovy\": \"groovy\",\n\t\".clj\": \"clojure\",\n\n\t// .NET languages\n\t\".cs\": \"csharp\",\n\t\".fs\": \"fsharp\",\n\t\".vb\": \"vb\",\n\n\t// Web\n\t\".html\": \"html\",\n\t\".htm\": \"html\",\n\t\".css\": \"css\",\n\t\".scss\": \"scss\",\n\t\".sass\": \"sass\",\n\t\".less\": \"less\",\n\t\".vue\": \"vue\",\n\t\".svelte\": \"svelte\",\n\n\t// Data formats\n\t\".json\": \"json\",\n\t\".jsonc\": \"jsonc\",\n\t\".yaml\": \"yaml\",\n\t\".yml\": \"yaml\",\n\t\".toml\": \"toml\",\n\t\".xml\": \"xml\",\n\t\".ini\": \"ini\",\n\n\t// Documentation\n\t\".md\": \"markdown\",\n\t\".markdown\": \"markdown\",\n\t\".rst\": \"restructuredtext\",\n\t\".adoc\": \"asciidoc\",\n\t\".tex\": \"latex\",\n\n\t// Other\n\t\".sql\": \"sql\",\n\t\".graphql\": \"graphql\",\n\t\".gql\": \"graphql\",\n\t\".proto\": \"protobuf\",\n\t\".dockerfile\": \"dockerfile\",\n\t\".tf\": \"terraform\",\n\t\".hcl\": \"hcl\",\n\t\".nix\": \"nix\",\n\t\".ex\": \"elixir\",\n\t\".exs\": \"elixir\",\n\t\".erl\": \"erlang\",\n\t\".hrl\": \"erlang\",\n\t\".hs\": \"haskell\",\n\t\".ml\": \"ocaml\",\n\t\".mli\": \"ocaml\",\n\t\".swift\": \"swift\",\n\t\".r\": \"r\",\n\t\".R\": \"r\",\n\t\".jl\": \"julia\",\n\t\".dart\": \"dart\",\n\t\".elm\": \"elm\",\n\t\".v\": \"v\",\n\t\".nim\": \"nim\",\n\t\".cr\": \"crystal\",\n\t\".d\": \"d\",\n\t\".pas\": \"pascal\",\n\t\".pp\": \"pascal\",\n\t\".lisp\": \"lisp\",\n\t\".lsp\": \"lisp\",\n\t\".rkt\": \"racket\",\n\t\".scm\": \"scheme\",\n\t\".ps1\": \"powershell\",\n\t\".psm1\": \"powershell\",\n\t\".bat\": \"bat\",\n\t\".cmd\": \"bat\",\n};\n\n/**\n * Detect language ID from file path.\n */\nexport function detectLanguageId(filePath: string): string {\n\tconst ext = path.extname(filePath).toLowerCase();\n\tconst basename = path.basename(filePath).toLowerCase();\n\n\tif (basename === \"dockerfile\" || basename.startsWith(\"dockerfile.\")) {\n\t\treturn \"dockerfile\";\n\t}\n\tif (basename === \"makefile\" || basename === \"gnumakefile\") {\n\t\treturn \"makefile\";\n\t}\n\tif (basename === \"cmakelists.txt\" || ext === \".cmake\") {\n\t\treturn \"cmake\";\n\t}\n\n\treturn LANGUAGE_MAP[ext] ?? \"plaintext\";\n}\n\n// =============================================================================\n// URI Handling (Cross-Platform)\n// =============================================================================\n\nexport function fileToUri(filePath: string): string {\n\tconst resolved = path.resolve(filePath);\n\n\tif (process.platform === \"win32\") {\n\t\treturn `file:///${resolved.replace(/\\\\/g, \"/\")}`;\n\t}\n\n\treturn `file://${resolved}`;\n}\n\nexport function uriToFile(uri: string): string {\n\tif (!uri.startsWith(\"file://\")) {\n\t\treturn uri;\n\t}\n\n\tlet filePath = decodeURIComponent(uri.slice(7));\n\n\tif (process.platform === \"win32\" && filePath.startsWith(\"/\") && /^[A-Za-z]:/.test(filePath.slice(1))) {\n\t\tfilePath = filePath.slice(1);\n\t}\n\n\treturn filePath;\n}\n\n// =============================================================================\n// Diagnostic Formatting\n// =============================================================================\n\nconst SEVERITY_NAMES: Record<DiagnosticSeverity, string> = {\n\t1: \"error\",\n\t2: \"warning\",\n\t3: \"info\",\n\t4: \"hint\",\n};\n\nexport function severityToString(severity?: DiagnosticSeverity): string {\n\treturn SEVERITY_NAMES[severity ?? 1] ?? \"unknown\";\n}\n\nexport function sortDiagnostics(diagnostics: Diagnostic[]): Diagnostic[] {\n\treturn diagnostics.sort((a, b) => {\n\t\tconst aSeverity = a.severity ?? 1;\n\t\tconst bSeverity = b.severity ?? 1;\n\t\tif (aSeverity !== bSeverity) return aSeverity - bSeverity;\n\t\tconst aLine = a.range.start.line;\n\t\tconst bLine = b.range.start.line;\n\t\tif (aLine !== bLine) return aLine - bLine;\n\t\tconst aCol = a.range.start.character;\n\t\tconst bCol = b.range.start.character;\n\t\tif (aCol !== bCol) return aCol - bCol;\n\t\treturn a.message.localeCompare(b.message);\n\t});\n}\n\nexport function severityToIcon(severity?: DiagnosticSeverity): string {\n\tswitch (severity ?? 1) {\n\t\tcase 1:\n\t\t\treturn \"[E]\";\n\t\tcase 2:\n\t\t\treturn \"[W]\";\n\t\tcase 3:\n\t\t\treturn \"[I]\";\n\t\tcase 4:\n\t\t\treturn \"[H]\";\n\t\tdefault:\n\t\t\treturn \"[E]\";\n\t}\n}\n\nfunction stripDiagnosticNoise(message: string): string {\n\treturn message\n\t\t.split(\"\\n\")\n\t\t.filter(line => {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.startsWith(\"for further information visit\")) return false;\n\t\t\tif (/^https?:\\/\\//.test(trimmed)) return false;\n\t\t\treturn true;\n\t\t})\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nexport function formatDiagnostic(diagnostic: Diagnostic, filePath: string): string {\n\tconst severity = severityToString(diagnostic.severity);\n\tconst line = diagnostic.range.start.line + 1;\n\tconst col = diagnostic.range.start.character + 1;\n\tconst source = diagnostic.source ? `[${diagnostic.source}] ` : \"\";\n\tconst code = diagnostic.code !== undefined ? ` (${diagnostic.code})` : \"\";\n\tconst message = stripDiagnosticNoise(diagnostic.message);\n\n\treturn `${filePath}:${line}:${col} [${severity}] ${source}${message}${code}`;\n}\n\nconst DIAG_PATH_RE = /^(.+?):(\\d+:\\d+\\s+.*)$/;\n\nexport function formatGroupedDiagnosticMessages(messages: string[]): string {\n\tconst diagnosticsByFile = new Map<string, string[]>();\n\tconst fileOrder: string[] = [];\n\tconst ungrouped: string[] = [];\n\n\tfor (const msg of messages) {\n\t\tconst match = DIAG_PATH_RE.exec(msg);\n\t\tif (!match) {\n\t\t\tungrouped.push(msg);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst [, rawFilePath, rest] = match;\n\t\tconst filePath = rawFilePath.replace(/\\\\/g, \"/\");\n\t\tif (!diagnosticsByFile.has(filePath)) {\n\t\t\tdiagnosticsByFile.set(filePath, []);\n\t\t\tfileOrder.push(filePath);\n\t\t}\n\t\tdiagnosticsByFile.get(filePath)?.push(rest);\n\t}\n\n\tif (diagnosticsByFile.size === 0) {\n\t\treturn ungrouped.join(\"\\n\");\n\t}\n\n\tconst filesByDirectory = new Map<string, string[]>();\n\tfor (const filePath of fileOrder) {\n\t\tconst directory = path.dirname(filePath).replace(/\\\\/g, \"/\");\n\t\tif (!filesByDirectory.has(directory)) {\n\t\t\tfilesByDirectory.set(directory, []);\n\t\t}\n\t\tfilesByDirectory.get(directory)?.push(filePath);\n\t}\n\n\tconst lines: string[] = [];\n\tfor (const [directory, directoryFiles] of filesByDirectory) {\n\t\tif (directory === \".\") {\n\t\t\tfor (const filePath of directoryFiles) {\n\t\t\t\tif (lines.length > 0) {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\n\t\t\t\tlines.push(`# ${path.basename(filePath)}`);\n\t\t\t\tfor (const diagnostic of diagnosticsByFile.get(filePath) ?? []) {\n\t\t\t\t\tlines.push(` ${diagnostic}`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (lines.length > 0) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(`# ${directory}`);\n\t\tfor (const filePath of directoryFiles) {\n\t\t\tlines.push(`## └─ ${path.basename(filePath)}`);\n\t\t\tfor (const diagnostic of diagnosticsByFile.get(filePath) ?? []) {\n\t\t\t\tlines.push(` ${diagnostic}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (ungrouped.length > 0) {\n\t\tlines.push(\"\");\n\t\tfor (const msg of ungrouped) {\n\t\t\tlines.push(msg);\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function formatDiagnosticsSummary(diagnostics: Diagnostic[]): string {\n\tconst counts = { error: 0, warning: 0, info: 0, hint: 0 };\n\n\tfor (const d of diagnostics) {\n\t\tconst sev = severityToString(d.severity);\n\t\tif (sev in counts) {\n\t\t\tcounts[sev as keyof typeof counts]++;\n\t\t}\n\t}\n\n\tconst parts: string[] = [];\n\tif (counts.error > 0) parts.push(`${counts.error} error(s)`);\n\tif (counts.warning > 0) parts.push(`${counts.warning} warning(s)`);\n\tif (counts.info > 0) parts.push(`${counts.info} info(s)`);\n\tif (counts.hint > 0) parts.push(`${counts.hint} hint(s)`);\n\n\treturn parts.length > 0 ? parts.join(\", \") : \"no issues\";\n}\n\n// =============================================================================\n// Location Formatting\n// =============================================================================\n\nexport function formatLocation(location: Location, cwd: string): string {\n\tconst file = path.relative(cwd, uriToFile(location.uri));\n\tconst line = location.range.start.line + 1;\n\tconst col = location.range.start.character + 1;\n\treturn `${file}:${line}:${col}`;\n}\n\nexport function formatPosition(line: number, col: number): string {\n\treturn `${line}:${col}`;\n}\n\n// =============================================================================\n// WorkspaceEdit Formatting\n// =============================================================================\n\nexport function formatWorkspaceEdit(edit: WorkspaceEdit, cwd: string): string[] {\n\tconst results: string[] = [];\n\n\tif (edit.changes) {\n\t\tfor (const [uri, textEdits] of Object.entries(edit.changes)) {\n\t\t\tconst file = path.relative(cwd, uriToFile(uri));\n\t\t\tresults.push(`${file}: ${textEdits.length} edit${textEdits.length > 1 ? \"s\" : \"\"}`);\n\t\t}\n\t}\n\n\tif (edit.documentChanges) {\n\t\tfor (const change of edit.documentChanges) {\n\t\t\tif (\"edits\" in change && change.textDocument) {\n\t\t\t\tconst file = path.relative(cwd, uriToFile(change.textDocument.uri));\n\t\t\t\tresults.push(`${file}: ${change.edits.length} edit${change.edits.length > 1 ? \"s\" : \"\"}`);\n\t\t\t} else if (\"kind\" in change) {\n\t\t\t\tswitch (change.kind) {\n\t\t\t\t\tcase \"create\":\n\t\t\t\t\t\tresults.push(`CREATE: ${path.relative(cwd, uriToFile(change.uri))}`);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"rename\":\n\t\t\t\t\t\tresults.push(\n\t\t\t\t\t\t\t`RENAME: ${path.relative(cwd, uriToFile(change.oldUri))} -> ${path.relative(cwd, uriToFile(change.newUri))}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"delete\":\n\t\t\t\t\t\tresults.push(`DELETE: ${path.relative(cwd, uriToFile(change.uri))}`);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results;\n}\n\nexport function formatTextEdit(edit: TextEdit, maxLength = 50): string {\n\tconst range = `${edit.range.start.line + 1}:${edit.range.start.character + 1}`;\n\tconst preview =\n\t\tedit.newText.length > maxLength\n\t\t\t? `${edit.newText.slice(0, maxLength).replace(/\\n/g, \"\\\\n\")}…`\n\t\t\t: edit.newText.replace(/\\n/g, \"\\\\n\");\n\treturn `line ${range} -> \"${preview}\"`;\n}\n\n// =============================================================================\n// Symbol Formatting\n// =============================================================================\n\nconst SYMBOL_KIND_LABELS: Record<number, string> = {\n\t1: \"File\",\n\t2: \"Module\",\n\t3: \"Namespace\",\n\t4: \"Package\",\n\t5: \"Class\",\n\t6: \"Method\",\n\t7: \"Property\",\n\t8: \"Field\",\n\t9: \"Constructor\",\n\t10: \"Enum\",\n\t11: \"Interface\",\n\t12: \"Function\",\n\t13: \"Variable\",\n\t14: \"Constant\",\n\t15: \"String\",\n\t16: \"Number\",\n\t17: \"Boolean\",\n\t18: \"Array\",\n\t19: \"Object\",\n\t20: \"Key\",\n\t21: \"Null\",\n\t22: \"EnumMember\",\n\t23: \"Struct\",\n\t24: \"Event\",\n\t25: \"Operator\",\n\t26: \"TypeParameter\",\n};\n\nexport function symbolKindToIcon(kind: SymbolKind): string {\n\treturn `[${SYMBOL_KIND_LABELS[kind] ?? \"?\"}]`;\n}\n\nexport function symbolKindToName(kind: SymbolKind): string {\n\treturn SYMBOL_KIND_LABELS[kind] ?? \"Unknown\";\n}\n\nexport function formatDocumentSymbol(symbol: DocumentSymbol, indent = 0): string[] {\n\tconst prefix = \" \".repeat(indent);\n\tconst icon = symbolKindToIcon(symbol.kind);\n\tconst line = symbol.range.start.line + 1;\n\tconst detail = symbol.detail ? ` ${symbol.detail}` : \"\";\n\tconst results = [`${prefix}${icon} ${symbol.name}${detail} @ line ${line}`];\n\n\tif (symbol.children) {\n\t\tfor (const child of symbol.children) {\n\t\t\tresults.push(...formatDocumentSymbol(child, indent + 1));\n\t\t}\n\t}\n\n\treturn results;\n}\n\nexport function formatSymbolInformation(symbol: SymbolInformation, cwd: string): string {\n\tconst icon = symbolKindToIcon(symbol.kind);\n\tconst location = formatLocation(symbol.location, cwd);\n\tconst container = symbol.containerName ? ` (${symbol.containerName})` : \"\";\n\treturn `${icon} ${symbol.name}${container} @ ${location}`;\n}\n\nexport function filterWorkspaceSymbols(symbols: SymbolInformation[], query: string): SymbolInformation[] {\n\tconst needle = query.trim().toLowerCase();\n\tif (!needle) return symbols;\n\treturn symbols.filter(symbol => {\n\t\tconst fields = [symbol.name, symbol.containerName ?? \"\", uriToFile(symbol.location.uri)];\n\t\treturn fields.some(field => field.toLowerCase().includes(needle));\n\t});\n}\n\nexport function dedupeWorkspaceSymbols(symbols: SymbolInformation[]): SymbolInformation[] {\n\tconst seen = new Set<string>();\n\tconst unique: SymbolInformation[] = [];\n\tfor (const symbol of symbols) {\n\t\tconst key = [\n\t\t\tsymbol.name,\n\t\t\tsymbol.containerName ?? \"\",\n\t\t\tsymbol.kind,\n\t\t\tsymbol.location.uri,\n\t\t\tsymbol.location.range.start.line,\n\t\t\tsymbol.location.range.start.character,\n\t\t].join(\":\");\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tunique.push(symbol);\n\t}\n\treturn unique;\n}\n\nexport function formatCodeAction(action: CodeAction | Command, index: number): string {\n\tconst kind = \"kind\" in action && action.kind ? action.kind : \"action\";\n\tconst preferred = \"isPreferred\" in action && action.isPreferred ? \" (preferred)\" : \"\";\n\tconst disabled = \"disabled\" in action && action.disabled ? ` (disabled: ${action.disabled.reason})` : \"\";\n\treturn `${index}: [${kind}] ${action.title}${preferred}${disabled}`;\n}\n\nexport interface CodeActionApplyDependencies {\n\tresolveCodeAction?: (action: CodeAction) => Promise<CodeAction>;\n\tapplyWorkspaceEdit: (edit: WorkspaceEdit) => Promise<string[]>;\n\texecuteCommand: (command: Command) => Promise<void>;\n}\n\nexport interface AppliedCodeActionResult {\n\ttitle: string;\n\tedits: string[];\n\texecutedCommands: string[];\n}\n\nfunction isCommandItem(action: CodeAction | Command): action is Command {\n\treturn typeof action.command === \"string\";\n}\n\nexport async function applyCodeAction(\n\taction: CodeAction | Command,\n\tdependencies: CodeActionApplyDependencies,\n): Promise<AppliedCodeActionResult | null> {\n\tif (isCommandItem(action)) {\n\t\tawait dependencies.executeCommand(action);\n\t\treturn { title: action.title, edits: [], executedCommands: [action.command] };\n\t}\n\n\tlet resolvedAction = action;\n\tif (!resolvedAction.edit && dependencies.resolveCodeAction) {\n\t\ttry {\n\t\t\tresolvedAction = await dependencies.resolveCodeAction(resolvedAction);\n\t\t} catch {\n\t\t\t// Resolve is optional; continue with unresolved action.\n\t\t}\n\t}\n\n\tconst edits = resolvedAction.edit ? await dependencies.applyWorkspaceEdit(resolvedAction.edit) : [];\n\tconst executedCommands: string[] = [];\n\tif (resolvedAction.command) {\n\t\tawait dependencies.executeCommand(resolvedAction.command);\n\t\texecutedCommands.push(resolvedAction.command.command);\n\t}\n\n\tif (edits.length === 0 && executedCommands.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn { title: resolvedAction.title, edits, executedCommands };\n}\n\nconst GLOB_PATTERN_CHARS = /[*?[{]/;\n\nexport function hasGlobPattern(value: string): boolean {\n\treturn GLOB_PATTERN_CHARS.test(value);\n}\n\nexport async function collectGlobMatches(\n\tpattern: string,\n\tcwd: string,\n\tmaxMatches: number,\n): Promise<{ matches: string[]; truncated: boolean }> {\n\tconst normalizedLimit = Number.isFinite(maxMatches) ? Math.max(1, Math.trunc(maxMatches)) : 1;\n\tconst allMatches = await glob(pattern, { cwd });\n\tif (allMatches.length > normalizedLimit) {\n\t\treturn { matches: allMatches.slice(0, normalizedLimit), truncated: true };\n\t}\n\treturn { matches: allMatches, truncated: false };\n}\n\n// =============================================================================\n// Hover Content Extraction\n// =============================================================================\n\nexport function extractHoverText(\n\tcontents: string | { kind: string; value: string } | { language: string; value: string } | unknown[],\n): string {\n\tif (typeof contents === \"string\") {\n\t\treturn contents;\n\t}\n\n\tif (Array.isArray(contents)) {\n\t\treturn contents.map(c => extractHoverText(c as string | { kind: string; value: string })).join(\"\\n\\n\");\n\t}\n\n\tif (typeof contents === \"object\" && contents !== null) {\n\t\tif (\"value\" in contents && typeof contents.value === \"string\") {\n\t\t\treturn contents.value;\n\t\t}\n\t}\n\n\treturn String(contents);\n}\n\n// =============================================================================\n// General Utilities\n// =============================================================================\n\nfunction firstNonWhitespaceColumn(lineText: string): number {\n\tconst match = lineText.match(/\\S/);\n\treturn match ? (match.index ?? 0) : 0;\n}\n\nfunction findSymbolMatchIndexes(lineText: string, symbol: string, caseInsensitive = false): number[] {\n\tif (symbol.length === 0) return [];\n\tconst haystack = caseInsensitive ? lineText.toLowerCase() : lineText;\n\tconst needle = caseInsensitive ? symbol.toLowerCase() : symbol;\n\tconst indexes: number[] = [];\n\tlet fromIndex = 0;\n\twhile (fromIndex <= haystack.length - needle.length) {\n\t\tconst matchIndex = haystack.indexOf(needle, fromIndex);\n\t\tif (matchIndex === -1) break;\n\t\tindexes.push(matchIndex);\n\t\tfromIndex = matchIndex + needle.length;\n\t}\n\treturn indexes;\n}\n\nfunction normalizeOccurrence(occurrence?: number): number {\n\tif (occurrence === undefined || !Number.isFinite(occurrence)) return 1;\n\treturn Math.max(1, Math.trunc(occurrence));\n}\n\nexport async function resolveSymbolColumn(\n\tfilePath: string,\n\tline: number,\n\tsymbol?: string,\n\toccurrence?: number,\n): Promise<number> {\n\tconst lineNumber = Math.max(1, line);\n\tconst matchOccurrence = normalizeOccurrence(occurrence);\n\ttry {\n\t\tconst fileText = await fsPromises.readFile(filePath, \"utf-8\");\n\t\tconst lines = fileText.split(\"\\n\");\n\t\tconst targetLine = lines[lineNumber - 1] ?? \"\";\n\t\tif (!symbol) {\n\t\t\treturn firstNonWhitespaceColumn(targetLine);\n\t\t}\n\n\t\tconst exactIndexes = findSymbolMatchIndexes(targetLine, symbol);\n\t\tconst fallbackIndexes = exactIndexes.length > 0 ? exactIndexes : findSymbolMatchIndexes(targetLine, symbol, true);\n\t\tif (fallbackIndexes.length === 0) {\n\t\t\tthrow new Error(`Symbol \"${symbol}\" not found on line ${lineNumber}`);\n\t\t}\n\t\tif (matchOccurrence > fallbackIndexes.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`Symbol \"${symbol}\" occurrence ${matchOccurrence} is out of bounds on line ${lineNumber} (found ${fallbackIndexes.length})`,\n\t\t\t);\n\t\t}\n\t\treturn fallbackIndexes[matchOccurrence - 1];\n\t} catch (error: unknown) {\n\t\tif (isEnoent(error)) {\n\t\t\tthrow new Error(`File not found: ${filePath}`);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nexport async function readLocationContext(filePath: string, line: number, contextLines = 1): Promise<string[]> {\n\tconst targetLine = Math.max(1, line);\n\tconst surrounding = Math.max(0, contextLines);\n\ttry {\n\t\tconst fileText = await fsPromises.readFile(filePath, \"utf-8\");\n\t\tconst lines = fileText.split(\"\\n\");\n\t\tif (lines.length === 0) return [];\n\n\t\tconst startLine = Math.max(1, targetLine - surrounding);\n\t\tconst endLine = Math.min(lines.length, targetLine + surrounding);\n\t\tconst context: string[] = [];\n\t\tfor (let currentLine = startLine; currentLine <= endLine; currentLine++) {\n\t\t\tconst content = lines[currentLine - 1] ?? \"\";\n\t\t\tcontext.push(`${currentLine}: ${content}`);\n\t\t}\n\t\treturn context;\n\t} catch (error: unknown) {\n\t\tif (isEnoent(error)) {\n\t\t\treturn [];\n\t\t}\n\t\tthrow error;\n\t}\n}\n"]}
|