@nanocollective/nanocoder 1.16.5 → 1.17.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.
Files changed (162) hide show
  1. package/README.md +53 -19
  2. package/assets/nanocoder-vscode.vsix +0 -0
  3. package/dist/app.d.ts +6 -1
  4. package/dist/app.d.ts.map +1 -1
  5. package/dist/app.js +54 -18
  6. package/dist/app.js.map +1 -1
  7. package/dist/cli.js +13 -1
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/mcp.d.ts +6 -0
  10. package/dist/commands/mcp.d.ts.map +1 -1
  11. package/dist/commands/mcp.js +25 -3
  12. package/dist/commands/mcp.js.map +1 -1
  13. package/dist/components/vscode-extension-prompt.d.ts +12 -0
  14. package/dist/components/vscode-extension-prompt.d.ts.map +1 -0
  15. package/dist/components/vscode-extension-prompt.js +115 -0
  16. package/dist/components/vscode-extension-prompt.js.map +1 -0
  17. package/dist/hooks/useAppInitialization.d.ts +2 -0
  18. package/dist/hooks/useAppInitialization.d.ts.map +1 -1
  19. package/dist/hooks/useAppInitialization.js +55 -1
  20. package/dist/hooks/useAppInitialization.js.map +1 -1
  21. package/dist/hooks/useModeHandlers.d.ts +2 -1
  22. package/dist/hooks/useModeHandlers.d.ts.map +1 -1
  23. package/dist/hooks/useModeHandlers.js +13 -1
  24. package/dist/hooks/useModeHandlers.js.map +1 -1
  25. package/dist/hooks/useToolHandler.d.ts.map +1 -1
  26. package/dist/hooks/useToolHandler.js +11 -0
  27. package/dist/hooks/useToolHandler.js.map +1 -1
  28. package/dist/hooks/useVSCodeServer.d.ts +45 -0
  29. package/dist/hooks/useVSCodeServer.d.ts.map +1 -0
  30. package/dist/hooks/useVSCodeServer.js +144 -0
  31. package/dist/hooks/useVSCodeServer.js.map +1 -0
  32. package/dist/lsp/index.d.ts +12 -0
  33. package/dist/lsp/index.d.ts.map +1 -0
  34. package/dist/lsp/index.js +11 -0
  35. package/dist/lsp/index.js.map +1 -0
  36. package/dist/lsp/lsp-client.d.ts +78 -0
  37. package/dist/lsp/lsp-client.d.ts.map +1 -0
  38. package/dist/lsp/lsp-client.js +378 -0
  39. package/dist/lsp/lsp-client.js.map +1 -0
  40. package/dist/lsp/lsp-client.spec.d.ts +2 -0
  41. package/dist/lsp/lsp-client.spec.d.ts.map +1 -0
  42. package/dist/lsp/lsp-client.spec.js +395 -0
  43. package/dist/lsp/lsp-client.spec.js.map +1 -0
  44. package/dist/lsp/lsp-manager.d.ts +124 -0
  45. package/dist/lsp/lsp-manager.d.ts.map +1 -0
  46. package/dist/lsp/lsp-manager.js +313 -0
  47. package/dist/lsp/lsp-manager.js.map +1 -0
  48. package/dist/lsp/lsp-manager.spec.d.ts +2 -0
  49. package/dist/lsp/lsp-manager.spec.d.ts.map +1 -0
  50. package/dist/lsp/lsp-manager.spec.js +388 -0
  51. package/dist/lsp/lsp-manager.spec.js.map +1 -0
  52. package/dist/lsp/protocol.d.ts +313 -0
  53. package/dist/lsp/protocol.d.ts.map +1 -0
  54. package/dist/lsp/protocol.js +70 -0
  55. package/dist/lsp/protocol.js.map +1 -0
  56. package/dist/lsp/protocol.spec.d.ts +2 -0
  57. package/dist/lsp/protocol.spec.d.ts.map +1 -0
  58. package/dist/lsp/protocol.spec.js +406 -0
  59. package/dist/lsp/protocol.spec.js.map +1 -0
  60. package/dist/lsp/server-discovery.d.ts +35 -0
  61. package/dist/lsp/server-discovery.d.ts.map +1 -0
  62. package/dist/lsp/server-discovery.js +291 -0
  63. package/dist/lsp/server-discovery.js.map +1 -0
  64. package/dist/lsp/server-discovery.spec.d.ts +2 -0
  65. package/dist/lsp/server-discovery.spec.d.ts.map +1 -0
  66. package/dist/lsp/server-discovery.spec.js +375 -0
  67. package/dist/lsp/server-discovery.spec.js.map +1 -0
  68. package/dist/mcp/mcp-client.d.ts +18 -0
  69. package/dist/mcp/mcp-client.d.ts.map +1 -1
  70. package/dist/mcp/mcp-client.js +59 -23
  71. package/dist/mcp/mcp-client.js.map +1 -1
  72. package/dist/mcp/mcp-client.spec.d.ts +2 -0
  73. package/dist/mcp/mcp-client.spec.d.ts.map +1 -0
  74. package/dist/mcp/mcp-client.spec.js +64 -0
  75. package/dist/mcp/mcp-client.spec.js.map +1 -0
  76. package/dist/mcp/transport-factory.d.ts +39 -0
  77. package/dist/mcp/transport-factory.d.ts.map +1 -0
  78. package/dist/mcp/transport-factory.js +176 -0
  79. package/dist/mcp/transport-factory.js.map +1 -0
  80. package/dist/mcp/transport-factory.spec.d.ts +2 -0
  81. package/dist/mcp/transport-factory.spec.d.ts.map +1 -0
  82. package/dist/mcp/transport-factory.spec.js +303 -0
  83. package/dist/mcp/transport-factory.spec.js.map +1 -0
  84. package/dist/tools/create-file.d.ts.map +1 -1
  85. package/dist/tools/create-file.js +37 -3
  86. package/dist/tools/create-file.js.map +1 -1
  87. package/dist/tools/delete-lines.d.ts.map +1 -1
  88. package/dist/tools/delete-lines.js +41 -1
  89. package/dist/tools/delete-lines.js.map +1 -1
  90. package/dist/tools/index.d.ts.map +1 -1
  91. package/dist/tools/index.js +2 -0
  92. package/dist/tools/index.js.map +1 -1
  93. package/dist/tools/insert-lines.d.ts.map +1 -1
  94. package/dist/tools/insert-lines.js +40 -1
  95. package/dist/tools/insert-lines.js.map +1 -1
  96. package/dist/tools/lsp-get-diagnostics.d.ts +3 -0
  97. package/dist/tools/lsp-get-diagnostics.d.ts.map +1 -0
  98. package/dist/tools/lsp-get-diagnostics.js +182 -0
  99. package/dist/tools/lsp-get-diagnostics.js.map +1 -0
  100. package/dist/tools/replace-lines.d.ts.map +1 -1
  101. package/dist/tools/replace-lines.js +44 -1
  102. package/dist/tools/replace-lines.js.map +1 -1
  103. package/dist/tools/tool-manager.d.ts +17 -0
  104. package/dist/tools/tool-manager.d.ts.map +1 -1
  105. package/dist/tools/tool-manager.js +12 -0
  106. package/dist/tools/tool-manager.js.map +1 -1
  107. package/dist/types/config.d.ts +27 -0
  108. package/dist/types/config.d.ts.map +1 -1
  109. package/dist/types/mcp.d.ts +23 -1
  110. package/dist/types/mcp.d.ts.map +1 -1
  111. package/dist/vscode/extension-installer.d.ts +24 -0
  112. package/dist/vscode/extension-installer.d.ts.map +1 -0
  113. package/dist/vscode/extension-installer.js +110 -0
  114. package/dist/vscode/extension-installer.js.map +1 -0
  115. package/dist/vscode/extension-installer.spec.d.ts +2 -0
  116. package/dist/vscode/extension-installer.spec.d.ts.map +1 -0
  117. package/dist/vscode/extension-installer.spec.js +132 -0
  118. package/dist/vscode/extension-installer.spec.js.map +1 -0
  119. package/dist/vscode/index.d.ts +14 -0
  120. package/dist/vscode/index.d.ts.map +1 -0
  121. package/dist/vscode/index.js +14 -0
  122. package/dist/vscode/index.js.map +1 -0
  123. package/dist/vscode/protocol.d.ts +101 -0
  124. package/dist/vscode/protocol.d.ts.map +1 -0
  125. package/dist/vscode/protocol.js +7 -0
  126. package/dist/vscode/protocol.js.map +1 -0
  127. package/dist/vscode/protocol.spec.d.ts +2 -0
  128. package/dist/vscode/protocol.spec.d.ts.map +1 -0
  129. package/dist/vscode/protocol.spec.js +354 -0
  130. package/dist/vscode/protocol.spec.js.map +1 -0
  131. package/dist/vscode/vscode-server.d.ts +118 -0
  132. package/dist/vscode/vscode-server.d.ts.map +1 -0
  133. package/dist/vscode/vscode-server.js +303 -0
  134. package/dist/vscode/vscode-server.js.map +1 -0
  135. package/dist/vscode/vscode-server.spec.d.ts +2 -0
  136. package/dist/vscode/vscode-server.spec.d.ts.map +1 -0
  137. package/dist/vscode/vscode-server.spec.js +487 -0
  138. package/dist/vscode/vscode-server.spec.js.map +1 -0
  139. package/dist/wizard/steps/mcp-step.d.ts.map +1 -1
  140. package/dist/wizard/steps/mcp-step.js +139 -72
  141. package/dist/wizard/steps/mcp-step.js.map +1 -1
  142. package/dist/wizard/steps/summary-step.d.ts.map +1 -1
  143. package/dist/wizard/steps/summary-step.js +58 -2
  144. package/dist/wizard/steps/summary-step.js.map +1 -1
  145. package/dist/wizard/templates/mcp-templates.d.ts +20 -2
  146. package/dist/wizard/templates/mcp-templates.d.ts.map +1 -1
  147. package/dist/wizard/templates/mcp-templates.js +351 -7
  148. package/dist/wizard/templates/mcp-templates.js.map +1 -1
  149. package/dist/wizard/templates/mcp-templates.spec.js +257 -0
  150. package/dist/wizard/templates/mcp-templates.spec.js.map +1 -1
  151. package/dist/wizard/validation-array.spec.d.ts +2 -0
  152. package/dist/wizard/validation-array.spec.d.ts.map +1 -0
  153. package/dist/wizard/validation-array.spec.js +221 -0
  154. package/dist/wizard/validation-array.spec.js.map +1 -0
  155. package/dist/wizard/validation.d.ts +26 -1
  156. package/dist/wizard/validation.d.ts.map +1 -1
  157. package/dist/wizard/validation.js +15 -2
  158. package/dist/wizard/validation.js.map +1 -1
  159. package/dist/wizard/validation.spec.js +13 -5
  160. package/dist/wizard/validation.spec.js.map +1 -1
  161. package/package.json +7 -3
  162. package/source/app/prompts/main-prompt.md +6 -0
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Language Server Auto-Discovery
3
+ * Detects installed language servers on the system
4
+ */
5
+ import { execSync } from 'child_process';
6
+ import { existsSync } from 'fs';
7
+ import { join } from 'path';
8
+ /**
9
+ * Known language servers and their configurations
10
+ */
11
+ const KNOWN_SERVERS = [
12
+ // TypeScript/JavaScript
13
+ {
14
+ name: 'typescript-language-server',
15
+ command: 'typescript-language-server',
16
+ args: ['--stdio'],
17
+ languages: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'],
18
+ checkCommand: 'typescript-language-server --version',
19
+ installHint: 'npm install -g typescript-language-server typescript',
20
+ },
21
+ // Python - Pyright (preferred)
22
+ {
23
+ name: 'pyright',
24
+ command: 'pyright-langserver',
25
+ args: ['--stdio'],
26
+ languages: ['py', 'pyi'],
27
+ checkCommand: 'pyright-langserver --version',
28
+ installHint: 'npm install -g pyright',
29
+ },
30
+ // Python - pylsp (alternative)
31
+ {
32
+ name: 'pylsp',
33
+ command: 'pylsp',
34
+ args: [],
35
+ languages: ['py', 'pyi'],
36
+ checkCommand: 'pylsp --version',
37
+ installHint: 'pip install python-lsp-server',
38
+ },
39
+ // Rust
40
+ {
41
+ name: 'rust-analyzer',
42
+ command: 'rust-analyzer',
43
+ args: [],
44
+ languages: ['rs'],
45
+ checkCommand: 'rust-analyzer --version',
46
+ installHint: 'rustup component add rust-analyzer',
47
+ },
48
+ // Go
49
+ {
50
+ name: 'gopls',
51
+ command: 'gopls',
52
+ args: ['serve'],
53
+ languages: ['go'],
54
+ checkCommand: 'gopls version',
55
+ installHint: 'go install golang.org/x/tools/gopls@latest',
56
+ },
57
+ // C/C++
58
+ {
59
+ name: 'clangd',
60
+ command: 'clangd',
61
+ args: ['--background-index'],
62
+ languages: ['c', 'cpp', 'cc', 'cxx', 'h', 'hpp', 'hxx'],
63
+ checkCommand: 'clangd --version',
64
+ installHint: 'Install via system package manager (apt, brew, etc.)',
65
+ },
66
+ // JSON
67
+ {
68
+ name: 'vscode-json-languageserver',
69
+ command: 'vscode-json-language-server',
70
+ args: ['--stdio'],
71
+ languages: ['json', 'jsonc'],
72
+ checkCommand: 'vscode-json-language-server --version',
73
+ installHint: 'npm install -g vscode-langservers-extracted',
74
+ },
75
+ // HTML
76
+ {
77
+ name: 'vscode-html-languageserver',
78
+ command: 'vscode-html-language-server',
79
+ args: ['--stdio'],
80
+ languages: ['html', 'htm'],
81
+ checkCommand: 'vscode-html-language-server --version',
82
+ installHint: 'npm install -g vscode-langservers-extracted',
83
+ },
84
+ // CSS
85
+ {
86
+ name: 'vscode-css-languageserver',
87
+ command: 'vscode-css-language-server',
88
+ args: ['--stdio'],
89
+ languages: ['css', 'scss', 'less'],
90
+ checkCommand: 'vscode-css-language-server --version',
91
+ installHint: 'npm install -g vscode-langservers-extracted',
92
+ },
93
+ // YAML
94
+ {
95
+ name: 'yaml-language-server',
96
+ command: 'yaml-language-server',
97
+ args: ['--stdio'],
98
+ languages: ['yaml', 'yml'],
99
+ checkCommand: 'yaml-language-server --version',
100
+ installHint: 'npm install -g yaml-language-server',
101
+ },
102
+ // Bash/Shell
103
+ {
104
+ name: 'bash-language-server',
105
+ command: 'bash-language-server',
106
+ args: ['start'],
107
+ languages: ['sh', 'bash', 'zsh'],
108
+ checkCommand: 'bash-language-server --version',
109
+ installHint: 'npm install -g bash-language-server',
110
+ },
111
+ // Lua
112
+ {
113
+ name: 'lua-language-server',
114
+ command: 'lua-language-server',
115
+ args: [],
116
+ languages: ['lua'],
117
+ checkCommand: 'lua-language-server --version',
118
+ installHint: 'Install from https://github.com/LuaLS/lua-language-server',
119
+ },
120
+ ];
121
+ /**
122
+ * Check if a command is available in PATH or locally in node_modules
123
+ * Returns the path to use, or null if not found
124
+ */
125
+ function findCommand(command) {
126
+ // First check PATH
127
+ try {
128
+ execSync(`which ${command}`, { stdio: 'ignore' });
129
+ return command;
130
+ }
131
+ catch {
132
+ // Not in PATH
133
+ }
134
+ // Check local node_modules/.bin
135
+ const localBinPath = join(process.cwd(), 'node_modules', '.bin', command);
136
+ if (existsSync(localBinPath)) {
137
+ return localBinPath;
138
+ }
139
+ return null;
140
+ }
141
+ /**
142
+ * Check if a command works by running a check command
143
+ */
144
+ function verifyServer(checkCommand) {
145
+ try {
146
+ execSync(checkCommand, { stdio: 'ignore', timeout: 5000 });
147
+ return true;
148
+ }
149
+ catch {
150
+ return false;
151
+ }
152
+ }
153
+ /**
154
+ * Discover all installed language servers
155
+ */
156
+ export function discoverLanguageServers() {
157
+ const discovered = [];
158
+ const coveredLanguages = new Set();
159
+ for (const server of KNOWN_SERVERS) {
160
+ // Skip if we already have a server for all of this server's languages
161
+ const hasNewLanguages = server.languages.some(lang => !coveredLanguages.has(lang));
162
+ if (!hasNewLanguages)
163
+ continue;
164
+ // Check if command exists (in PATH or local node_modules)
165
+ const commandPath = findCommand(server.command);
166
+ if (!commandPath)
167
+ continue;
168
+ // Verify server works if check command provided
169
+ // Use the resolved command path for verification
170
+ if (server.checkCommand) {
171
+ const checkCmd = server.checkCommand.replace(server.command, commandPath);
172
+ if (!verifyServer(checkCmd))
173
+ continue;
174
+ }
175
+ // Add to discovered servers with resolved command path
176
+ discovered.push({
177
+ name: server.name,
178
+ command: commandPath,
179
+ args: server.args,
180
+ languages: server.languages,
181
+ });
182
+ // Mark languages as covered
183
+ for (const lang of server.languages) {
184
+ coveredLanguages.add(lang);
185
+ }
186
+ }
187
+ return discovered;
188
+ }
189
+ /**
190
+ * Get language server config for a specific file extension
191
+ */
192
+ export function getServerForLanguage(servers, extension) {
193
+ const ext = extension.startsWith('.') ? extension.slice(1) : extension;
194
+ return servers.find(server => server.languages.includes(ext));
195
+ }
196
+ /**
197
+ * Get the file extension to LSP language ID mapping
198
+ */
199
+ export function getLanguageId(extension) {
200
+ const ext = extension.startsWith('.') ? extension.slice(1) : extension;
201
+ const languageMap = {
202
+ ts: 'typescript',
203
+ tsx: 'typescriptreact',
204
+ js: 'javascript',
205
+ jsx: 'javascriptreact',
206
+ mjs: 'javascript',
207
+ cjs: 'javascript',
208
+ py: 'python',
209
+ pyi: 'python',
210
+ rs: 'rust',
211
+ go: 'go',
212
+ c: 'c',
213
+ cpp: 'cpp',
214
+ cc: 'cpp',
215
+ cxx: 'cpp',
216
+ h: 'c',
217
+ hpp: 'cpp',
218
+ hxx: 'cpp',
219
+ json: 'json',
220
+ jsonc: 'jsonc',
221
+ html: 'html',
222
+ htm: 'html',
223
+ css: 'css',
224
+ scss: 'scss',
225
+ less: 'less',
226
+ yaml: 'yaml',
227
+ yml: 'yaml',
228
+ sh: 'shellscript',
229
+ bash: 'shellscript',
230
+ zsh: 'shellscript',
231
+ lua: 'lua',
232
+ md: 'markdown',
233
+ toml: 'toml',
234
+ xml: 'xml',
235
+ sql: 'sql',
236
+ java: 'java',
237
+ kt: 'kotlin',
238
+ swift: 'swift',
239
+ rb: 'ruby',
240
+ php: 'php',
241
+ };
242
+ return languageMap[ext] || ext;
243
+ }
244
+ /**
245
+ * Get install hints for missing language servers
246
+ */
247
+ export function getMissingServerHints(extensions) {
248
+ const hints = [];
249
+ const checkedServers = new Set();
250
+ for (const ext of extensions) {
251
+ const e = ext.startsWith('.') ? ext.slice(1) : ext;
252
+ for (const server of KNOWN_SERVERS) {
253
+ if (checkedServers.has(server.name))
254
+ continue;
255
+ if (!server.languages.includes(e))
256
+ continue;
257
+ checkedServers.add(server.name);
258
+ if (!findCommand(server.command) && server.installHint) {
259
+ hints.push(`${server.name}: ${server.installHint}`);
260
+ }
261
+ }
262
+ }
263
+ return hints;
264
+ }
265
+ /**
266
+ * Try to find language server from node_modules (project-local)
267
+ */
268
+ export function findLocalServer(projectRoot, serverName) {
269
+ const localPaths = [
270
+ join(projectRoot, 'node_modules', '.bin', serverName),
271
+ join(projectRoot, 'node_modules', serverName, 'bin', serverName),
272
+ ];
273
+ for (const path of localPaths) {
274
+ if (existsSync(path)) {
275
+ return path;
276
+ }
277
+ }
278
+ return null;
279
+ }
280
+ /**
281
+ * Get all known language servers with their availability status
282
+ */
283
+ export function getKnownServersStatus() {
284
+ return KNOWN_SERVERS.map(server => ({
285
+ name: server.name,
286
+ available: findCommand(server.command) !== null,
287
+ languages: server.languages,
288
+ installHint: server.installHint,
289
+ }));
290
+ }
291
+ //# sourceMappingURL=server-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-discovery.js","sourceRoot":"","sources":["../../source/lsp/server-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server-discovery.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-discovery.spec.d.ts","sourceRoot":"","sources":["../../source/lsp/server-discovery.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,375 @@
1
+ import test from 'ava';
2
+ import { getServerForLanguage, getLanguageId, getMissingServerHints, findLocalServer, getKnownServersStatus, } from './server-discovery.js';
3
+ console.log(`\nserver-discovery.spec.ts`);
4
+ // getLanguageId tests
5
+ test('getLanguageId - returns typescript for ts extension', t => {
6
+ t.is(getLanguageId('ts'), 'typescript');
7
+ });
8
+ test('getLanguageId - returns typescriptreact for tsx extension', t => {
9
+ t.is(getLanguageId('tsx'), 'typescriptreact');
10
+ });
11
+ test('getLanguageId - returns javascript for js extension', t => {
12
+ t.is(getLanguageId('js'), 'javascript');
13
+ });
14
+ test('getLanguageId - returns javascriptreact for jsx extension', t => {
15
+ t.is(getLanguageId('jsx'), 'javascriptreact');
16
+ });
17
+ test('getLanguageId - returns javascript for mjs extension', t => {
18
+ t.is(getLanguageId('mjs'), 'javascript');
19
+ });
20
+ test('getLanguageId - returns javascript for cjs extension', t => {
21
+ t.is(getLanguageId('cjs'), 'javascript');
22
+ });
23
+ test('getLanguageId - returns python for py extension', t => {
24
+ t.is(getLanguageId('py'), 'python');
25
+ });
26
+ test('getLanguageId - returns python for pyi extension', t => {
27
+ t.is(getLanguageId('pyi'), 'python');
28
+ });
29
+ test('getLanguageId - returns rust for rs extension', t => {
30
+ t.is(getLanguageId('rs'), 'rust');
31
+ });
32
+ test('getLanguageId - returns go for go extension', t => {
33
+ t.is(getLanguageId('go'), 'go');
34
+ });
35
+ test('getLanguageId - returns c for c extension', t => {
36
+ t.is(getLanguageId('c'), 'c');
37
+ });
38
+ test('getLanguageId - returns cpp for cpp extension', t => {
39
+ t.is(getLanguageId('cpp'), 'cpp');
40
+ });
41
+ test('getLanguageId - returns cpp for cc extension', t => {
42
+ t.is(getLanguageId('cc'), 'cpp');
43
+ });
44
+ test('getLanguageId - returns cpp for cxx extension', t => {
45
+ t.is(getLanguageId('cxx'), 'cpp');
46
+ });
47
+ test('getLanguageId - returns c for h extension', t => {
48
+ t.is(getLanguageId('h'), 'c');
49
+ });
50
+ test('getLanguageId - returns cpp for hpp extension', t => {
51
+ t.is(getLanguageId('hpp'), 'cpp');
52
+ });
53
+ test('getLanguageId - returns cpp for hxx extension', t => {
54
+ t.is(getLanguageId('hxx'), 'cpp');
55
+ });
56
+ test('getLanguageId - returns json for json extension', t => {
57
+ t.is(getLanguageId('json'), 'json');
58
+ });
59
+ test('getLanguageId - returns jsonc for jsonc extension', t => {
60
+ t.is(getLanguageId('jsonc'), 'jsonc');
61
+ });
62
+ test('getLanguageId - returns html for html extension', t => {
63
+ t.is(getLanguageId('html'), 'html');
64
+ });
65
+ test('getLanguageId - returns html for htm extension', t => {
66
+ t.is(getLanguageId('htm'), 'html');
67
+ });
68
+ test('getLanguageId - returns css for css extension', t => {
69
+ t.is(getLanguageId('css'), 'css');
70
+ });
71
+ test('getLanguageId - returns scss for scss extension', t => {
72
+ t.is(getLanguageId('scss'), 'scss');
73
+ });
74
+ test('getLanguageId - returns less for less extension', t => {
75
+ t.is(getLanguageId('less'), 'less');
76
+ });
77
+ test('getLanguageId - returns yaml for yaml extension', t => {
78
+ t.is(getLanguageId('yaml'), 'yaml');
79
+ });
80
+ test('getLanguageId - returns yaml for yml extension', t => {
81
+ t.is(getLanguageId('yml'), 'yaml');
82
+ });
83
+ test('getLanguageId - returns shellscript for sh extension', t => {
84
+ t.is(getLanguageId('sh'), 'shellscript');
85
+ });
86
+ test('getLanguageId - returns shellscript for bash extension', t => {
87
+ t.is(getLanguageId('bash'), 'shellscript');
88
+ });
89
+ test('getLanguageId - returns shellscript for zsh extension', t => {
90
+ t.is(getLanguageId('zsh'), 'shellscript');
91
+ });
92
+ test('getLanguageId - returns lua for lua extension', t => {
93
+ t.is(getLanguageId('lua'), 'lua');
94
+ });
95
+ test('getLanguageId - returns markdown for md extension', t => {
96
+ t.is(getLanguageId('md'), 'markdown');
97
+ });
98
+ test('getLanguageId - returns toml for toml extension', t => {
99
+ t.is(getLanguageId('toml'), 'toml');
100
+ });
101
+ test('getLanguageId - returns xml for xml extension', t => {
102
+ t.is(getLanguageId('xml'), 'xml');
103
+ });
104
+ test('getLanguageId - returns sql for sql extension', t => {
105
+ t.is(getLanguageId('sql'), 'sql');
106
+ });
107
+ test('getLanguageId - returns java for java extension', t => {
108
+ t.is(getLanguageId('java'), 'java');
109
+ });
110
+ test('getLanguageId - returns kotlin for kt extension', t => {
111
+ t.is(getLanguageId('kt'), 'kotlin');
112
+ });
113
+ test('getLanguageId - returns swift for swift extension', t => {
114
+ t.is(getLanguageId('swift'), 'swift');
115
+ });
116
+ test('getLanguageId - returns ruby for rb extension', t => {
117
+ t.is(getLanguageId('rb'), 'ruby');
118
+ });
119
+ test('getLanguageId - returns php for php extension', t => {
120
+ t.is(getLanguageId('php'), 'php');
121
+ });
122
+ test('getLanguageId - handles extension with leading dot', t => {
123
+ t.is(getLanguageId('.ts'), 'typescript');
124
+ });
125
+ test('getLanguageId - handles extension with leading dot for py', t => {
126
+ t.is(getLanguageId('.py'), 'python');
127
+ });
128
+ test('getLanguageId - returns extension as fallback for unknown type', t => {
129
+ t.is(getLanguageId('xyz'), 'xyz');
130
+ });
131
+ test('getLanguageId - returns extension as fallback for unknown with dot', t => {
132
+ t.is(getLanguageId('.unknown'), 'unknown');
133
+ });
134
+ // getServerForLanguage tests
135
+ test('getServerForLanguage - finds server for matching extension', t => {
136
+ const servers = [
137
+ {
138
+ name: 'typescript-language-server',
139
+ command: 'typescript-language-server',
140
+ args: ['--stdio'],
141
+ languages: ['ts', 'tsx', 'js', 'jsx'],
142
+ },
143
+ {
144
+ name: 'pyright',
145
+ command: 'pyright-langserver',
146
+ args: ['--stdio'],
147
+ languages: ['py', 'pyi'],
148
+ },
149
+ ];
150
+ const result = getServerForLanguage(servers, 'ts');
151
+ t.truthy(result);
152
+ t.is(result?.name, 'typescript-language-server');
153
+ });
154
+ test('getServerForLanguage - finds python server for py extension', t => {
155
+ const servers = [
156
+ {
157
+ name: 'typescript-language-server',
158
+ command: 'typescript-language-server',
159
+ args: ['--stdio'],
160
+ languages: ['ts', 'tsx'],
161
+ },
162
+ {
163
+ name: 'pyright',
164
+ command: 'pyright-langserver',
165
+ args: ['--stdio'],
166
+ languages: ['py', 'pyi'],
167
+ },
168
+ ];
169
+ const result = getServerForLanguage(servers, 'py');
170
+ t.truthy(result);
171
+ t.is(result?.name, 'pyright');
172
+ });
173
+ test('getServerForLanguage - returns undefined for no matching server', t => {
174
+ const servers = [
175
+ {
176
+ name: 'typescript-language-server',
177
+ command: 'typescript-language-server',
178
+ args: ['--stdio'],
179
+ languages: ['ts', 'tsx'],
180
+ },
181
+ ];
182
+ const result = getServerForLanguage(servers, 'py');
183
+ t.is(result, undefined);
184
+ });
185
+ test('getServerForLanguage - handles extension with leading dot', t => {
186
+ const servers = [
187
+ {
188
+ name: 'rust-analyzer',
189
+ command: 'rust-analyzer',
190
+ args: [],
191
+ languages: ['rs'],
192
+ },
193
+ ];
194
+ const result = getServerForLanguage(servers, '.rs');
195
+ t.truthy(result);
196
+ t.is(result?.name, 'rust-analyzer');
197
+ });
198
+ test('getServerForLanguage - returns first matching server when multiple match', t => {
199
+ const servers = [
200
+ {
201
+ name: 'pyright',
202
+ command: 'pyright-langserver',
203
+ args: ['--stdio'],
204
+ languages: ['py', 'pyi'],
205
+ },
206
+ {
207
+ name: 'pylsp',
208
+ command: 'pylsp',
209
+ args: [],
210
+ languages: ['py', 'pyi'],
211
+ },
212
+ ];
213
+ const result = getServerForLanguage(servers, 'py');
214
+ t.truthy(result);
215
+ t.is(result?.name, 'pyright');
216
+ });
217
+ test('getServerForLanguage - handles empty servers array', t => {
218
+ const servers = [];
219
+ const result = getServerForLanguage(servers, 'ts');
220
+ t.is(result, undefined);
221
+ });
222
+ // getMissingServerHints tests
223
+ test('getMissingServerHints - returns array', t => {
224
+ const result = getMissingServerHints(['ts']);
225
+ t.true(Array.isArray(result));
226
+ });
227
+ test('getMissingServerHints - handles extension with leading dot', t => {
228
+ const result = getMissingServerHints(['.ts', '.py']);
229
+ t.true(Array.isArray(result));
230
+ });
231
+ test('getMissingServerHints - handles empty extensions array', t => {
232
+ const result = getMissingServerHints([]);
233
+ t.deepEqual(result, []);
234
+ });
235
+ test('getMissingServerHints - returns hints for unknown extensions only if server exists', t => {
236
+ // Unknown extensions won't have hints because there's no known server
237
+ const result = getMissingServerHints(['xyz']);
238
+ t.true(Array.isArray(result));
239
+ });
240
+ test('getMissingServerHints - does not duplicate hints for same server', t => {
241
+ // ts and tsx are handled by the same server
242
+ const result = getMissingServerHints(['ts', 'tsx', 'js', 'jsx']);
243
+ // Should have at most one hint for typescript-language-server
244
+ const tsHints = result.filter(h => h.includes('typescript-language-server'));
245
+ t.true(tsHints.length <= 1);
246
+ });
247
+ // findLocalServer tests
248
+ test('findLocalServer - returns null for non-existent server', t => {
249
+ const result = findLocalServer('/non-existent-path', 'some-server');
250
+ t.is(result, null);
251
+ });
252
+ test('findLocalServer - returns null for non-existent project root', t => {
253
+ const result = findLocalServer('/does/not/exist', 'typescript-language-server');
254
+ t.is(result, null);
255
+ });
256
+ test('findLocalServer - searches in node_modules/.bin', t => {
257
+ // This test verifies the function behavior - it should check specific paths
258
+ const result = findLocalServer(process.cwd(), 'non-existent-binary-xyz');
259
+ t.is(result, null);
260
+ });
261
+ // getKnownServersStatus tests
262
+ test('getKnownServersStatus - returns array of server status', t => {
263
+ const result = getKnownServersStatus();
264
+ t.true(Array.isArray(result));
265
+ t.true(result.length > 0);
266
+ });
267
+ test('getKnownServersStatus - each item has required properties', t => {
268
+ const result = getKnownServersStatus();
269
+ for (const server of result) {
270
+ t.truthy(server.name);
271
+ t.true(typeof server.available === 'boolean');
272
+ t.true(Array.isArray(server.languages));
273
+ t.true(server.languages.length > 0);
274
+ }
275
+ });
276
+ test('getKnownServersStatus - includes typescript server', t => {
277
+ const result = getKnownServersStatus();
278
+ const tsServer = result.find(s => s.name === 'typescript-language-server');
279
+ t.truthy(tsServer);
280
+ t.true(tsServer.languages.includes('ts'));
281
+ t.true(tsServer.languages.includes('tsx'));
282
+ });
283
+ test('getKnownServersStatus - includes pyright server', t => {
284
+ const result = getKnownServersStatus();
285
+ const pyServer = result.find(s => s.name === 'pyright');
286
+ t.truthy(pyServer);
287
+ t.true(pyServer.languages.includes('py'));
288
+ });
289
+ test('getKnownServersStatus - includes rust-analyzer', t => {
290
+ const result = getKnownServersStatus();
291
+ const rustServer = result.find(s => s.name === 'rust-analyzer');
292
+ t.truthy(rustServer);
293
+ t.true(rustServer.languages.includes('rs'));
294
+ });
295
+ test('getKnownServersStatus - includes gopls', t => {
296
+ const result = getKnownServersStatus();
297
+ const goServer = result.find(s => s.name === 'gopls');
298
+ t.truthy(goServer);
299
+ t.true(goServer.languages.includes('go'));
300
+ });
301
+ test('getKnownServersStatus - includes clangd', t => {
302
+ const result = getKnownServersStatus();
303
+ const cppServer = result.find(s => s.name === 'clangd');
304
+ t.truthy(cppServer);
305
+ t.true(cppServer.languages.includes('c'));
306
+ t.true(cppServer.languages.includes('cpp'));
307
+ });
308
+ test('getKnownServersStatus - has install hints', t => {
309
+ const result = getKnownServersStatus();
310
+ // At least some servers should have install hints
311
+ const withHints = result.filter(s => s.installHint);
312
+ t.true(withHints.length > 0);
313
+ });
314
+ test('getKnownServersStatus - install hint contains useful info', t => {
315
+ const result = getKnownServersStatus();
316
+ const tsServer = result.find(s => s.name === 'typescript-language-server');
317
+ t.truthy(tsServer?.installHint);
318
+ t.true(tsServer.installHint.includes('npm'));
319
+ });
320
+ // discoverLanguageServers is harder to test as it depends on system state
321
+ // We can test the structure of what it returns
322
+ test('getKnownServersStatus - includes all major language servers', t => {
323
+ const result = getKnownServersStatus();
324
+ const serverNames = result.map(s => s.name);
325
+ // Check for presence of major servers
326
+ t.true(serverNames.includes('typescript-language-server'));
327
+ t.true(serverNames.includes('pyright') || serverNames.includes('pylsp'));
328
+ t.true(serverNames.includes('rust-analyzer'));
329
+ t.true(serverNames.includes('gopls'));
330
+ t.true(serverNames.includes('clangd'));
331
+ });
332
+ test('getKnownServersStatus - includes web servers', t => {
333
+ const result = getKnownServersStatus();
334
+ const serverNames = result.map(s => s.name);
335
+ t.true(serverNames.includes('vscode-json-languageserver'));
336
+ t.true(serverNames.includes('vscode-html-languageserver'));
337
+ t.true(serverNames.includes('vscode-css-languageserver'));
338
+ });
339
+ test('getKnownServersStatus - includes yaml server', t => {
340
+ const result = getKnownServersStatus();
341
+ const yamlServer = result.find(s => s.name === 'yaml-language-server');
342
+ t.truthy(yamlServer);
343
+ t.true(yamlServer.languages.includes('yaml'));
344
+ t.true(yamlServer.languages.includes('yml'));
345
+ });
346
+ test('getKnownServersStatus - includes bash server', t => {
347
+ const result = getKnownServersStatus();
348
+ const bashServer = result.find(s => s.name === 'bash-language-server');
349
+ t.truthy(bashServer);
350
+ t.true(bashServer.languages.includes('sh'));
351
+ t.true(bashServer.languages.includes('bash'));
352
+ });
353
+ test('getKnownServersStatus - includes lua server', t => {
354
+ const result = getKnownServersStatus();
355
+ const luaServer = result.find(s => s.name === 'lua-language-server');
356
+ t.truthy(luaServer);
357
+ t.true(luaServer.languages.includes('lua'));
358
+ });
359
+ // Edge cases
360
+ test('getLanguageId - handles empty string', t => {
361
+ const result = getLanguageId('');
362
+ t.is(result, '');
363
+ });
364
+ test('getServerForLanguage - handles empty extension', t => {
365
+ const servers = [
366
+ {
367
+ name: 'test',
368
+ command: 'test',
369
+ languages: ['ts'],
370
+ },
371
+ ];
372
+ const result = getServerForLanguage(servers, '');
373
+ t.is(result, undefined);
374
+ });
375
+ //# sourceMappingURL=server-discovery.spec.js.map