@nogataka/smart-edit 0.0.14

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 (186) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +244 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +7 -0
  5. package/dist/devtools/generate_prompt_factory.d.ts +5 -0
  6. package/dist/devtools/generate_prompt_factory.js +114 -0
  7. package/dist/index.d.ts +34 -0
  8. package/dist/index.js +34 -0
  9. package/dist/interprompt/index.d.ts +2 -0
  10. package/dist/interprompt/index.js +1 -0
  11. package/dist/interprompt/jinja_template.d.ts +10 -0
  12. package/dist/interprompt/jinja_template.js +174 -0
  13. package/dist/interprompt/multilang_prompt.d.ts +54 -0
  14. package/dist/interprompt/multilang_prompt.js +302 -0
  15. package/dist/interprompt/prompt_factory.d.ts +16 -0
  16. package/dist/interprompt/prompt_factory.js +189 -0
  17. package/dist/interprompt/util/class_decorators.d.ts +1 -0
  18. package/dist/interprompt/util/class_decorators.js +1 -0
  19. package/dist/interprompt/util/index.d.ts +1 -0
  20. package/dist/interprompt/util/index.js +1 -0
  21. package/dist/serena/agent.d.ts +118 -0
  22. package/dist/serena/agent.js +675 -0
  23. package/dist/serena/agno.d.ts +111 -0
  24. package/dist/serena/agno.js +278 -0
  25. package/dist/serena/analytics.d.ts +24 -0
  26. package/dist/serena/analytics.js +119 -0
  27. package/dist/serena/cli.d.ts +9 -0
  28. package/dist/serena/cli.js +731 -0
  29. package/dist/serena/code_editor.d.ts +42 -0
  30. package/dist/serena/code_editor.js +239 -0
  31. package/dist/serena/config/context_mode.d.ts +41 -0
  32. package/dist/serena/config/context_mode.js +239 -0
  33. package/dist/serena/config/serena_config.d.ts +134 -0
  34. package/dist/serena/config/serena_config.js +718 -0
  35. package/dist/serena/constants.d.ts +18 -0
  36. package/dist/serena/constants.js +27 -0
  37. package/dist/serena/dashboard.d.ts +55 -0
  38. package/dist/serena/dashboard.js +472 -0
  39. package/dist/serena/generated/generated_prompt_factory.d.ts +27 -0
  40. package/dist/serena/generated/generated_prompt_factory.js +42 -0
  41. package/dist/serena/gui_log_viewer.d.ts +41 -0
  42. package/dist/serena/gui_log_viewer.js +436 -0
  43. package/dist/serena/mcp.d.ts +118 -0
  44. package/dist/serena/mcp.js +904 -0
  45. package/dist/serena/project.d.ts +62 -0
  46. package/dist/serena/project.js +321 -0
  47. package/dist/serena/prompt_factory.d.ts +20 -0
  48. package/dist/serena/prompt_factory.js +42 -0
  49. package/dist/serena/resources/config/contexts/agent.yml +8 -0
  50. package/dist/serena/resources/config/contexts/chatgpt.yml +28 -0
  51. package/dist/serena/resources/config/contexts/codex.yml +27 -0
  52. package/dist/serena/resources/config/contexts/context.template.yml +11 -0
  53. package/dist/serena/resources/config/contexts/desktop-app.yml +17 -0
  54. package/dist/serena/resources/config/contexts/ide-assistant.yml +26 -0
  55. package/dist/serena/resources/config/contexts/oaicompat-agent.yml +8 -0
  56. package/dist/serena/resources/config/internal_modes/jetbrains.yml +15 -0
  57. package/dist/serena/resources/config/modes/editing.yml +112 -0
  58. package/dist/serena/resources/config/modes/interactive.yml +11 -0
  59. package/dist/serena/resources/config/modes/mode.template.yml +7 -0
  60. package/dist/serena/resources/config/modes/no-onboarding.yml +8 -0
  61. package/dist/serena/resources/config/modes/onboarding.yml +16 -0
  62. package/dist/serena/resources/config/modes/one-shot.yml +15 -0
  63. package/dist/serena/resources/config/modes/planning.yml +15 -0
  64. package/dist/serena/resources/config/prompt_templates/simple_tool_outputs.yml +75 -0
  65. package/dist/serena/resources/config/prompt_templates/system_prompt.yml +66 -0
  66. package/dist/serena/resources/dashboard/dashboard.js +815 -0
  67. package/dist/serena/resources/dashboard/index.html +314 -0
  68. package/dist/serena/resources/dashboard/jquery.min.js +3 -0
  69. package/dist/serena/resources/dashboard/serena-icon-16.png +0 -0
  70. package/dist/serena/resources/dashboard/serena-icon-32.png +0 -0
  71. package/dist/serena/resources/dashboard/serena-icon-48.png +0 -0
  72. package/dist/serena/resources/dashboard/serena-logs-dark-mode.png +0 -0
  73. package/dist/serena/resources/dashboard/serena-logs.png +0 -0
  74. package/dist/serena/resources/project.template.yml +67 -0
  75. package/dist/serena/resources/serena_config.template.yml +85 -0
  76. package/dist/serena/symbol.d.ts +199 -0
  77. package/dist/serena/symbol.js +616 -0
  78. package/dist/serena/text_utils.d.ts +51 -0
  79. package/dist/serena/text_utils.js +267 -0
  80. package/dist/serena/tools/cmd_tools.d.ts +31 -0
  81. package/dist/serena/tools/cmd_tools.js +48 -0
  82. package/dist/serena/tools/config_tools.d.ts +53 -0
  83. package/dist/serena/tools/config_tools.js +176 -0
  84. package/dist/serena/tools/file_tools.d.ts +231 -0
  85. package/dist/serena/tools/file_tools.js +511 -0
  86. package/dist/serena/tools/index.d.ts +7 -0
  87. package/dist/serena/tools/index.js +7 -0
  88. package/dist/serena/tools/memory_tools.d.ts +60 -0
  89. package/dist/serena/tools/memory_tools.js +135 -0
  90. package/dist/serena/tools/symbol_tools.d.ts +165 -0
  91. package/dist/serena/tools/symbol_tools.js +362 -0
  92. package/dist/serena/tools/tools_base.d.ts +162 -0
  93. package/dist/serena/tools/tools_base.js +378 -0
  94. package/dist/serena/tools/workflow_tools.d.ts +35 -0
  95. package/dist/serena/tools/workflow_tools.js +161 -0
  96. package/dist/serena/util/class_decorators.d.ts +7 -0
  97. package/dist/serena/util/class_decorators.js +37 -0
  98. package/dist/serena/util/exception.d.ts +8 -0
  99. package/dist/serena/util/exception.js +53 -0
  100. package/dist/serena/util/file_system.d.ts +30 -0
  101. package/dist/serena/util/file_system.js +352 -0
  102. package/dist/serena/util/general.d.ts +11 -0
  103. package/dist/serena/util/general.js +42 -0
  104. package/dist/serena/util/git.d.ts +11 -0
  105. package/dist/serena/util/git.js +37 -0
  106. package/dist/serena/util/inspection.d.ts +45 -0
  107. package/dist/serena/util/inspection.js +221 -0
  108. package/dist/serena/util/logging.d.ts +46 -0
  109. package/dist/serena/util/logging.js +205 -0
  110. package/dist/serena/util/shell.d.ts +21 -0
  111. package/dist/serena/util/shell.js +95 -0
  112. package/dist/serena/util/thread.d.ts +23 -0
  113. package/dist/serena/util/thread.js +88 -0
  114. package/dist/serena/version.d.ts +1 -0
  115. package/dist/serena/version.js +23 -0
  116. package/dist/solidlsp/language_servers/autoload.d.ts +23 -0
  117. package/dist/solidlsp/language_servers/autoload.js +25 -0
  118. package/dist/solidlsp/language_servers/bash_language_server.d.ts +10 -0
  119. package/dist/solidlsp/language_servers/bash_language_server.js +64 -0
  120. package/dist/solidlsp/language_servers/clangd_language_server.d.ts +13 -0
  121. package/dist/solidlsp/language_servers/clangd_language_server.js +110 -0
  122. package/dist/solidlsp/language_servers/clojure_lsp.d.ts +13 -0
  123. package/dist/solidlsp/language_servers/clojure_lsp.js +137 -0
  124. package/dist/solidlsp/language_servers/common.d.ts +41 -0
  125. package/dist/solidlsp/language_servers/common.js +365 -0
  126. package/dist/solidlsp/language_servers/csharp_language_server.d.ts +21 -0
  127. package/dist/solidlsp/language_servers/csharp_language_server.js +694 -0
  128. package/dist/solidlsp/language_servers/dart_language_server.d.ts +10 -0
  129. package/dist/solidlsp/language_servers/dart_language_server.js +122 -0
  130. package/dist/solidlsp/language_servers/eclipse_jdtls.d.ts +24 -0
  131. package/dist/solidlsp/language_servers/eclipse_jdtls.js +671 -0
  132. package/dist/solidlsp/language_servers/erlang_language_server.d.ts +22 -0
  133. package/dist/solidlsp/language_servers/erlang_language_server.js +327 -0
  134. package/dist/solidlsp/language_servers/gopls.d.ts +12 -0
  135. package/dist/solidlsp/language_servers/gopls.js +59 -0
  136. package/dist/solidlsp/language_servers/intelephense.d.ts +13 -0
  137. package/dist/solidlsp/language_servers/intelephense.js +121 -0
  138. package/dist/solidlsp/language_servers/jedi_server.d.ts +18 -0
  139. package/dist/solidlsp/language_servers/jedi_server.js +234 -0
  140. package/dist/solidlsp/language_servers/kotlin_language_server.d.ts +19 -0
  141. package/dist/solidlsp/language_servers/kotlin_language_server.js +474 -0
  142. package/dist/solidlsp/language_servers/lua_ls.d.ts +18 -0
  143. package/dist/solidlsp/language_servers/lua_ls.js +319 -0
  144. package/dist/solidlsp/language_servers/nixd_language_server.d.ts +17 -0
  145. package/dist/solidlsp/language_servers/nixd_language_server.js +341 -0
  146. package/dist/solidlsp/language_servers/pyright_server.d.ts +19 -0
  147. package/dist/solidlsp/language_servers/pyright_server.js +180 -0
  148. package/dist/solidlsp/language_servers/r_language_server.d.ts +19 -0
  149. package/dist/solidlsp/language_servers/r_language_server.js +184 -0
  150. package/dist/solidlsp/language_servers/ruby_common.d.ts +10 -0
  151. package/dist/solidlsp/language_servers/ruby_common.js +136 -0
  152. package/dist/solidlsp/language_servers/ruby_lsp.d.ts +18 -0
  153. package/dist/solidlsp/language_servers/ruby_lsp.js +230 -0
  154. package/dist/solidlsp/language_servers/rust_analyzer.d.ts +13 -0
  155. package/dist/solidlsp/language_servers/rust_analyzer.js +96 -0
  156. package/dist/solidlsp/language_servers/solargraph.d.ts +18 -0
  157. package/dist/solidlsp/language_servers/solargraph.js +208 -0
  158. package/dist/solidlsp/language_servers/sourcekit_lsp.d.ts +24 -0
  159. package/dist/solidlsp/language_servers/sourcekit_lsp.js +449 -0
  160. package/dist/solidlsp/language_servers/terraform_ls.d.ts +13 -0
  161. package/dist/solidlsp/language_servers/terraform_ls.js +139 -0
  162. package/dist/solidlsp/language_servers/typescript_language_server.d.ts +20 -0
  163. package/dist/solidlsp/language_servers/typescript_language_server.js +237 -0
  164. package/dist/solidlsp/language_servers/vts_language_server.d.ts +13 -0
  165. package/dist/solidlsp/language_servers/vts_language_server.js +121 -0
  166. package/dist/solidlsp/language_servers/zls.d.ts +20 -0
  167. package/dist/solidlsp/language_servers/zls.js +254 -0
  168. package/dist/solidlsp/ls.d.ts +197 -0
  169. package/dist/solidlsp/ls.js +507 -0
  170. package/dist/solidlsp/ls_config.d.ts +43 -0
  171. package/dist/solidlsp/ls_config.js +157 -0
  172. package/dist/solidlsp/ls_exceptions.d.ts +5 -0
  173. package/dist/solidlsp/ls_exceptions.js +14 -0
  174. package/dist/solidlsp/ls_handler.d.ts +54 -0
  175. package/dist/solidlsp/ls_handler.js +406 -0
  176. package/dist/solidlsp/ls_request.d.ts +31 -0
  177. package/dist/solidlsp/ls_request.js +42 -0
  178. package/dist/solidlsp/ls_types.d.ts +7 -0
  179. package/dist/solidlsp/ls_types.js +8 -0
  180. package/dist/solidlsp/lsp_protocol_handler/server.d.ts +61 -0
  181. package/dist/solidlsp/lsp_protocol_handler/server.js +68 -0
  182. package/dist/solidlsp/util/subprocess_util.d.ts +6 -0
  183. package/dist/solidlsp/util/subprocess_util.js +11 -0
  184. package/dist/solidlsp/util/zip.d.ts +25 -0
  185. package/dist/solidlsp/util/zip.js +188 -0
  186. package/package.json +65 -0
@@ -0,0 +1,449 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import path from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { ensureDefaultSubprocessOptions } from '../util/subprocess_util.js';
5
+ import { SolidLanguageServer, registerLanguageServer } from '../ls.js';
6
+ import { Language } from '../ls_config.js';
7
+ import { NodeLanguageServerHandler } from '../ls_handler.js';
8
+ const SOURCEKIT_ASSUME_ENV = 'SERENA_ASSUME_SOURCEKIT';
9
+ const SOURCEKIT_PATH_ENV = 'SERENA_SOURCEKIT_PATH';
10
+ const SOURCEKIT_INITIAL_DELAY_ENV = 'SERENA_SOURCEKIT_REFERENCE_INITIAL_DELAY_MS';
11
+ const SOURCEKIT_RETRY_DELAY_ENV = 'SERENA_SOURCEKIT_REFERENCE_RETRY_DELAY_MS';
12
+ const SOURCEKIT_IGNORED_DIRECTORIES = ['.build', '.swiftpm', 'node_modules', 'dist', 'build'];
13
+ const CAPABILITIES_TEMPLATE = Object.freeze({
14
+ general: {
15
+ markdown: { parser: 'marked', version: '1.1.0' },
16
+ positionEncodings: ['utf-16'],
17
+ regularExpressions: { engine: 'ECMAScript', version: 'ES2020' },
18
+ staleRequestSupport: {
19
+ cancel: true,
20
+ retryOnContentModified: [
21
+ 'textDocument/semanticTokens/full',
22
+ 'textDocument/semanticTokens/range',
23
+ 'textDocument/semanticTokens/full/delta'
24
+ ]
25
+ }
26
+ },
27
+ notebookDocument: {
28
+ synchronization: { dynamicRegistration: true, executionSummarySupport: true }
29
+ },
30
+ textDocument: {
31
+ callHierarchy: { dynamicRegistration: true },
32
+ codeAction: {
33
+ codeActionLiteralSupport: {
34
+ codeActionKind: {
35
+ valueSet: [
36
+ '',
37
+ 'quickfix',
38
+ 'refactor',
39
+ 'refactor.extract',
40
+ 'refactor.inline',
41
+ 'refactor.rewrite',
42
+ 'source',
43
+ 'source.organizeImports'
44
+ ]
45
+ }
46
+ },
47
+ dataSupport: true,
48
+ disabledSupport: true,
49
+ dynamicRegistration: true,
50
+ honorsChangeAnnotations: true,
51
+ isPreferredSupport: true,
52
+ resolveSupport: { properties: ['edit'] }
53
+ },
54
+ codeLens: { dynamicRegistration: true },
55
+ colorProvider: { dynamicRegistration: true },
56
+ completion: {
57
+ completionItem: {
58
+ commitCharactersSupport: true,
59
+ deprecatedSupport: true,
60
+ documentationFormat: ['markdown', 'plaintext'],
61
+ insertReplaceSupport: true,
62
+ insertTextModeSupport: { valueSet: [1, 2] },
63
+ labelDetailsSupport: true,
64
+ preselectSupport: true,
65
+ resolveSupport: { properties: ['documentation', 'detail', 'additionalTextEdits'] },
66
+ snippetSupport: true,
67
+ tagSupport: { valueSet: [1] }
68
+ },
69
+ completionItemKind: {
70
+ valueSet: Array.from({ length: 25 }, (_, index) => index + 1)
71
+ },
72
+ completionList: {
73
+ itemDefaults: ['commitCharacters', 'editRange', 'insertTextFormat', 'insertTextMode', 'data']
74
+ },
75
+ contextSupport: true,
76
+ dynamicRegistration: true,
77
+ insertTextMode: 2
78
+ },
79
+ declaration: { dynamicRegistration: true, linkSupport: true },
80
+ definition: { dynamicRegistration: true, linkSupport: true },
81
+ diagnostic: { dynamicRegistration: true, relatedDocumentSupport: false },
82
+ documentHighlight: { dynamicRegistration: true },
83
+ documentLink: { dynamicRegistration: true, tooltipSupport: true },
84
+ documentSymbol: {
85
+ dynamicRegistration: true,
86
+ hierarchicalDocumentSymbolSupport: true,
87
+ labelSupport: true,
88
+ symbolKind: { valueSet: Array.from({ length: 26 }, (_, index) => index + 1) },
89
+ tagSupport: { valueSet: [1] }
90
+ },
91
+ foldingRange: {
92
+ dynamicRegistration: true,
93
+ foldingRange: { collapsedText: false },
94
+ foldingRangeKind: { valueSet: ['comment', 'imports', 'region'] },
95
+ lineFoldingOnly: true,
96
+ rangeLimit: 5000
97
+ },
98
+ formatting: { dynamicRegistration: true },
99
+ hover: { contentFormat: ['markdown', 'plaintext'], dynamicRegistration: true },
100
+ implementation: { dynamicRegistration: true, linkSupport: true },
101
+ inlayHint: {
102
+ dynamicRegistration: true,
103
+ resolveSupport: { properties: ['tooltip', 'textEdits', 'label.tooltip', 'label.location', 'label.command'] }
104
+ },
105
+ inlineValue: { dynamicRegistration: true },
106
+ linkedEditingRange: { dynamicRegistration: true },
107
+ onTypeFormatting: { dynamicRegistration: true },
108
+ publishDiagnostics: {
109
+ codeDescriptionSupport: true,
110
+ dataSupport: true,
111
+ relatedInformation: true,
112
+ tagSupport: { valueSet: [1, 2] },
113
+ versionSupport: false
114
+ },
115
+ rangeFormatting: { dynamicRegistration: true, rangesSupport: true },
116
+ references: { dynamicRegistration: true },
117
+ rename: {
118
+ dynamicRegistration: true,
119
+ honorsChangeAnnotations: true,
120
+ prepareSupport: true,
121
+ prepareSupportDefaultBehavior: 1
122
+ },
123
+ selectionRange: { dynamicRegistration: true },
124
+ semanticTokens: {
125
+ augmentsSyntaxTokens: true,
126
+ dynamicRegistration: true,
127
+ formats: ['relative'],
128
+ multilineTokenSupport: false,
129
+ overlappingTokenSupport: false,
130
+ requests: { full: { delta: true }, range: true },
131
+ serverCancelSupport: true,
132
+ tokenModifiers: [
133
+ 'declaration',
134
+ 'definition',
135
+ 'readonly',
136
+ 'static',
137
+ 'deprecated',
138
+ 'abstract',
139
+ 'async',
140
+ 'modification',
141
+ 'documentation',
142
+ 'defaultLibrary'
143
+ ],
144
+ tokenTypes: [
145
+ 'namespace',
146
+ 'type',
147
+ 'class',
148
+ 'enum',
149
+ 'interface',
150
+ 'struct',
151
+ 'typeParameter',
152
+ 'parameter',
153
+ 'variable',
154
+ 'property',
155
+ 'enumMember',
156
+ 'event',
157
+ 'function',
158
+ 'method',
159
+ 'macro',
160
+ 'keyword',
161
+ 'modifier',
162
+ 'comment',
163
+ 'string',
164
+ 'number',
165
+ 'regexp',
166
+ 'operator',
167
+ 'decorator'
168
+ ]
169
+ },
170
+ signatureHelp: {
171
+ contextSupport: true,
172
+ dynamicRegistration: true,
173
+ signatureInformation: {
174
+ activeParameterSupport: true,
175
+ documentationFormat: ['markdown', 'plaintext'],
176
+ parameterInformation: { labelOffsetSupport: true }
177
+ }
178
+ },
179
+ synchronization: {
180
+ didSave: true,
181
+ dynamicRegistration: true,
182
+ willSave: true,
183
+ willSaveWaitUntil: true
184
+ },
185
+ typeDefinition: { dynamicRegistration: true, linkSupport: true },
186
+ typeHierarchy: { dynamicRegistration: true }
187
+ },
188
+ window: {
189
+ showDocument: { support: true },
190
+ showMessage: { messageActionItem: { additionalPropertiesSupport: true } },
191
+ workDoneProgress: true
192
+ },
193
+ workspace: {
194
+ applyEdit: true,
195
+ codeLens: { refreshSupport: true },
196
+ configuration: true,
197
+ diagnostics: { refreshSupport: true },
198
+ didChangeConfiguration: { dynamicRegistration: true },
199
+ didChangeWatchedFiles: { dynamicRegistration: true, relativePatternSupport: true },
200
+ executeCommand: { dynamicRegistration: true },
201
+ fileOperations: {
202
+ didCreate: true,
203
+ didDelete: true,
204
+ didRename: true,
205
+ dynamicRegistration: true,
206
+ willCreate: true,
207
+ willDelete: true,
208
+ willRename: true
209
+ },
210
+ foldingRange: { refreshSupport: true },
211
+ inlayHint: { refreshSupport: true },
212
+ inlineValue: { refreshSupport: true },
213
+ semanticTokens: { refreshSupport: false },
214
+ symbol: {
215
+ dynamicRegistration: true,
216
+ resolveSupport: { properties: ['location.range'] },
217
+ symbolKind: { valueSet: Array.from({ length: 26 }, (_, index) => index + 1) },
218
+ tagSupport: { valueSet: [1] }
219
+ },
220
+ workspaceEdit: {
221
+ changeAnnotationSupport: { groupsOnLabel: true },
222
+ documentChanges: true,
223
+ failureHandling: 'textOnlyTransactional',
224
+ normalizesLineEndings: true,
225
+ resourceOperations: ['create', 'rename', 'delete']
226
+ },
227
+ workspaceFolders: true
228
+ }
229
+ });
230
+ const INITIALIZATION_OPTIONS_TEMPLATE = Object.freeze({
231
+ backgroundIndexing: true,
232
+ backgroundPreparationMode: 'enabled',
233
+ 'textDocument/codeLens': {
234
+ supportedCommands: { 'swift.debug': 'swift.debug', 'swift.run': 'swift.run' }
235
+ },
236
+ 'window/didChangeActiveDocument': true,
237
+ 'workspace/getReferenceDocument': true,
238
+ 'workspace/peekDocuments': true
239
+ });
240
+ export class SourceKitLanguageServer extends SolidLanguageServer {
241
+ handler;
242
+ versionDescription;
243
+ initialized = false;
244
+ firstReferenceDelayApplied = false;
245
+ initializationTimestamp = null;
246
+ constructor(config, loggerLike, repositoryRootPath, options = {}) {
247
+ const augmentedConfig = {
248
+ ...config,
249
+ ignoredPaths: mergeIgnoredPaths(config.ignoredPaths, SOURCEKIT_IGNORED_DIRECTORIES)
250
+ };
251
+ const { command, version, assumed } = resolveSourcekitBinary();
252
+ const handler = new NodeLanguageServerHandler({
253
+ cmd: command,
254
+ cwd: repositoryRootPath
255
+ }, {
256
+ requestTimeoutSeconds: options?.timeout ?? null
257
+ });
258
+ super(augmentedConfig, loggerLike, repositoryRootPath, {
259
+ ...options,
260
+ handler,
261
+ solidlspSettings: options?.solidlspSettings
262
+ });
263
+ this.handler = handler;
264
+ this.versionDescription = assumed ? `${version} (assumed)` : version;
265
+ this.registerHandlers();
266
+ if (this.versionDescription && this.versionDescription.trim().length > 0) {
267
+ this.logger.info(`Starting sourcekit-lsp with version: ${this.versionDescription}`);
268
+ }
269
+ else {
270
+ this.logger.info('Starting sourcekit-lsp (version unknown)');
271
+ }
272
+ }
273
+ start() {
274
+ const shouldInitialize = !this.initialized;
275
+ super.start();
276
+ if (shouldInitialize) {
277
+ this.initializeLanguageServer();
278
+ this.initialized = true;
279
+ }
280
+ return this;
281
+ }
282
+ stop(shutdownTimeout = 2.0) {
283
+ super.stop(shutdownTimeout);
284
+ this.initialized = false;
285
+ this.firstReferenceDelayApplied = false;
286
+ this.initializationTimestamp = null;
287
+ }
288
+ requestReferencingSymbols(options) {
289
+ this.applyInitialReferenceDelay();
290
+ let references = super.requestReferencingSymbols(options);
291
+ if (process.env.CI && references.length === 0) {
292
+ const retryDelay = resolveDelayFromEnv(SOURCEKIT_RETRY_DELAY_ENV, 5000);
293
+ if (retryDelay > 0) {
294
+ this.logger.info(`No references found in CI - retrying after additional ${(retryDelay / 1000).toFixed(1)}s delay`);
295
+ sleepMilliseconds(retryDelay);
296
+ }
297
+ references = super.requestReferencingSymbols(options);
298
+ }
299
+ return references;
300
+ }
301
+ registerHandlers() {
302
+ const noop = () => undefined;
303
+ this.handler.onRequest('client/registerCapability', noop);
304
+ this.handler.onNotification('window/logMessage', (payload) => {
305
+ const message = extractWindowMessage(payload);
306
+ if (message) {
307
+ this.logger.info(`SourceKit LSP message: ${message}`);
308
+ }
309
+ });
310
+ this.handler.onNotification('$/progress', noop);
311
+ this.handler.onNotification('textDocument/publishDiagnostics', noop);
312
+ }
313
+ initializeLanguageServer() {
314
+ const params = this.buildInitializeParams();
315
+ const response = this.handler.sendRequest('initialize', params);
316
+ if (!response || typeof response !== 'object') {
317
+ throw new Error('sourcekit-lsp returned an invalid initialize response.');
318
+ }
319
+ const capabilities = response.capabilities;
320
+ if (!capabilities || typeof capabilities !== 'object') {
321
+ throw new Error('sourcekit-lsp did not return capabilities during initialization.');
322
+ }
323
+ const capabilityKeys = Object.keys(capabilities);
324
+ this.logger.info(`SourceKit LSP capabilities: ${capabilityKeys.join(', ')}`);
325
+ if (!('textDocumentSync' in capabilities)) {
326
+ throw new Error('sourcekit-lsp initialize response missing textDocumentSync capability.');
327
+ }
328
+ if (!('definitionProvider' in capabilities)) {
329
+ throw new Error('sourcekit-lsp initialize response missing definitionProvider capability.');
330
+ }
331
+ this.handler.notify.initialized({});
332
+ this.firstReferenceDelayApplied = false;
333
+ this.initializationTimestamp = Date.now();
334
+ }
335
+ buildInitializeParams() {
336
+ const repositoryAbsolutePath = path.resolve(this.repositoryRootPath);
337
+ const rootUri = pathToFileURL(repositoryAbsolutePath).href;
338
+ return {
339
+ capabilities: deepClone(CAPABILITIES_TEMPLATE),
340
+ clientInfo: { name: 'Visual Studio Code', version: '1.102.2' },
341
+ initializationOptions: deepClone(INITIALIZATION_OPTIONS_TEMPLATE),
342
+ locale: 'en',
343
+ processId: process.pid,
344
+ rootPath: repositoryAbsolutePath,
345
+ rootUri,
346
+ workspaceFolders: [
347
+ {
348
+ uri: rootUri,
349
+ name: path.basename(repositoryAbsolutePath)
350
+ }
351
+ ]
352
+ };
353
+ }
354
+ applyInitialReferenceDelay() {
355
+ if (this.firstReferenceDelayApplied) {
356
+ return;
357
+ }
358
+ const delayMs = this.computeInitialReferenceDelayMs();
359
+ if (delayMs > 0) {
360
+ this.logger.info(`Sleeping ${(delayMs / 1000).toFixed(1)}s before requesting references for the first time (CI needs extra indexing time)`);
361
+ sleepMilliseconds(delayMs);
362
+ }
363
+ this.firstReferenceDelayApplied = true;
364
+ }
365
+ computeInitialReferenceDelayMs() {
366
+ const override = resolveDelayFromEnv(SOURCEKIT_INITIAL_DELAY_ENV, null);
367
+ if (override !== null) {
368
+ return override;
369
+ }
370
+ const baseDelaySeconds = process.env.CI ? 15 : 5;
371
+ if (this.initializationTimestamp) {
372
+ const elapsedSeconds = (Date.now() - this.initializationTimestamp) / 1000;
373
+ const remainingSeconds = Math.max(2, baseDelaySeconds - elapsedSeconds);
374
+ return Math.max(0, Math.round(remainingSeconds * 1000));
375
+ }
376
+ return baseDelaySeconds * 1000;
377
+ }
378
+ }
379
+ function mergeIgnoredPaths(existing, additions) {
380
+ const merged = new Set(existing ?? []);
381
+ for (const entry of additions) {
382
+ merged.add(entry);
383
+ }
384
+ return Array.from(merged);
385
+ }
386
+ function resolveSourcekitBinary() {
387
+ const command = (process.env[SOURCEKIT_PATH_ENV] ?? 'sourcekit-lsp').trim() || 'sourcekit-lsp';
388
+ const assumed = process.env[SOURCEKIT_ASSUME_ENV] === '1';
389
+ if (assumed) {
390
+ return { command, version: 'assumed', assumed: true };
391
+ }
392
+ try {
393
+ const result = spawnSync(command, ['-h'], ensureDefaultSubprocessOptions({ encoding: 'utf-8' }));
394
+ if (result.error) {
395
+ throw result.error;
396
+ }
397
+ if (result.status !== 0) {
398
+ const stderr = (result.stderr ?? '').toString().trim();
399
+ throw new Error(`sourcekit-lsp '-h' exited with status ${result.status}. ${stderr || 'Install sourcekit-lsp and ensure it is on PATH.'}`);
400
+ }
401
+ const stdout = (result.stdout ?? '').toString().trim();
402
+ const stderr = (result.stderr ?? '').toString().trim();
403
+ const version = stdout || stderr || 'unknown';
404
+ return { command, version, assumed: false };
405
+ }
406
+ catch (error) {
407
+ const message = error instanceof Error
408
+ ? error.message
409
+ : 'Unknown error while probing sourcekit-lsp. Install sourcekit-lsp and make sure it is on your PATH.';
410
+ throw new Error(`${message} See https://github.com/apple/sourcekit-lsp#installation for installation instructions.`);
411
+ }
412
+ }
413
+ function resolveDelayFromEnv(envName, fallbackMs) {
414
+ const raw = process.env[envName];
415
+ if (raw === undefined) {
416
+ return fallbackMs ?? 0;
417
+ }
418
+ const value = Number(raw);
419
+ if (!Number.isFinite(value) || value < 0) {
420
+ return fallbackMs ?? 0;
421
+ }
422
+ return value;
423
+ }
424
+ function extractWindowMessage(payload) {
425
+ if (!payload || typeof payload !== 'object') {
426
+ return null;
427
+ }
428
+ const message = payload.message;
429
+ return typeof message === 'string' ? message : null;
430
+ }
431
+ function sleepMilliseconds(durationMs) {
432
+ if (durationMs <= 0) {
433
+ return;
434
+ }
435
+ if (typeof SharedArrayBuffer !== 'undefined' && typeof Atomics?.wait === 'function') {
436
+ const shared = new SharedArrayBuffer(4);
437
+ const view = new Int32Array(shared);
438
+ Atomics.wait(view, 0, 0, durationMs);
439
+ return;
440
+ }
441
+ const end = Date.now() + durationMs;
442
+ while (Date.now() < end) {
443
+ // busy-wait fallback if Atomics.wait is unavailable
444
+ }
445
+ }
446
+ function deepClone(value) {
447
+ return JSON.parse(JSON.stringify(value));
448
+ }
449
+ registerLanguageServer(Language.SWIFT, SourceKitLanguageServer);
@@ -0,0 +1,13 @@
1
+ import { type LogLevel } from '../../serena/util/logging.js';
2
+ import { SolidLanguageServer, type LanguageServerConfigLike, type SolidLspSettingsInit } from '../ls.js';
3
+ import { NodeLanguageServerHandler } from '../ls_handler.js';
4
+ export declare class TerraformLanguageServer extends SolidLanguageServer {
5
+ protected readonly handler: NodeLanguageServerHandler;
6
+ constructor(config: LanguageServerConfigLike, loggerLike: {
7
+ level?: number | LogLevel;
8
+ } | null, repositoryRootPath: string, options?: {
9
+ timeout?: number | null;
10
+ solidlspSettings?: SolidLspSettingsInit;
11
+ });
12
+ private registerHandlers;
13
+ }
@@ -0,0 +1,139 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { createSerenaLogger } from '../../serena/util/logging.js';
5
+ import { Language } from '../ls_config.js';
6
+ import { ensureDefaultSubprocessOptions } from '../util/subprocess_util.js';
7
+ import { SolidLanguageServer, SolidLspSettings, registerLanguageServer, coerceLogLevel } from '../ls.js';
8
+ import { NodeLanguageServerHandler } from '../ls_handler.js';
9
+ import { RuntimeDependencyCollection, quoteWindowsPath } from './common.js';
10
+ const TERRAFORM_DEPENDENCIES = [
11
+ {
12
+ id: 'terraform-ls',
13
+ description: 'terraform-ls for macOS (ARM64)',
14
+ url: 'https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_darwin_arm64.zip',
15
+ platformId: 'osx-arm64',
16
+ archiveType: 'zip',
17
+ binaryName: 'terraform-ls'
18
+ },
19
+ {
20
+ id: 'terraform-ls',
21
+ description: 'terraform-ls for macOS (x64)',
22
+ url: 'https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_darwin_amd64.zip',
23
+ platformId: 'osx-x64',
24
+ archiveType: 'zip',
25
+ binaryName: 'terraform-ls'
26
+ },
27
+ {
28
+ id: 'terraform-ls',
29
+ description: 'terraform-ls for Linux (ARM64)',
30
+ url: 'https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_linux_arm64.zip',
31
+ platformId: 'linux-arm64',
32
+ archiveType: 'zip',
33
+ binaryName: 'terraform-ls'
34
+ },
35
+ {
36
+ id: 'terraform-ls',
37
+ description: 'terraform-ls for Linux (x64)',
38
+ url: 'https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_linux_amd64.zip',
39
+ platformId: 'linux-x64',
40
+ archiveType: 'zip',
41
+ binaryName: 'terraform-ls'
42
+ },
43
+ {
44
+ id: 'terraform-ls',
45
+ description: 'terraform-ls for Windows (x64)',
46
+ url: 'https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_windows_amd64.zip',
47
+ platformId: 'win-x64',
48
+ archiveType: 'zip',
49
+ binaryName: 'terraform-ls.exe'
50
+ }
51
+ ];
52
+ function mergeIgnoredPaths(existing) {
53
+ const merged = new Set(existing ?? []);
54
+ ['.terraform', 'terraform.tfstate.d'].forEach((entry) => merged.add(entry));
55
+ return Array.from(merged);
56
+ }
57
+ function commandExists(command) {
58
+ const locator = process.platform === 'win32' ? 'where' : 'which';
59
+ return spawnSync(locator, [command], ensureDefaultSubprocessOptions({ stdio: 'ignore' })).status === 0;
60
+ }
61
+ function ensureTerraformCli() {
62
+ if (process.env.SERENA_ASSUME_TERRAFORM === '1') {
63
+ return;
64
+ }
65
+ if (!commandExists('terraform')) {
66
+ throw new Error('Terraform CLI not found. Install it from https://developer.hashicorp.com/terraform/install and ensure it is available in PATH.');
67
+ }
68
+ }
69
+ function resolveRuntimeDirectory(settings) {
70
+ const dir = path.join(settings.languageServersStaticDir, 'terraform-ls');
71
+ fs.mkdirSync(dir, { recursive: true });
72
+ return dir;
73
+ }
74
+ function ensureTerraformLanguageServer(runtimeDir, dependencies, loggerLevel) {
75
+ const { logger } = createSerenaLogger({
76
+ name: 'solidlsp.language_servers.terraform',
77
+ emitToConsole: false,
78
+ level: loggerLevel === undefined ? undefined : coerceLogLevel(loggerLevel)
79
+ });
80
+ const binaryPath = dependencies.binaryPath(runtimeDir);
81
+ if (fs.existsSync(binaryPath)) {
82
+ return binaryPath;
83
+ }
84
+ if (process.env.SERENA_SKIP_RUNTIME_INSTALL === '1') {
85
+ throw new Error(`terraform-ls executable not found at ${binaryPath}. Allow downloads or install terraform-ls manually.`);
86
+ }
87
+ logger.info('Downloading terraform-ls runtime dependency.');
88
+ dependencies.install(logger, runtimeDir);
89
+ if (!fs.existsSync(binaryPath)) {
90
+ throw new Error(`Failed to install terraform-ls (expected binary at ${binaryPath}).`);
91
+ }
92
+ if (process.platform !== 'win32') {
93
+ try {
94
+ fs.chmodSync(binaryPath, 0o755);
95
+ }
96
+ catch {
97
+ // ignore chmod failures
98
+ }
99
+ }
100
+ return binaryPath;
101
+ }
102
+ export class TerraformLanguageServer extends SolidLanguageServer {
103
+ handler;
104
+ constructor(config, loggerLike, repositoryRootPath, options = {}) {
105
+ const augmentedConfig = {
106
+ ...config,
107
+ ignoredPaths: mergeIgnoredPaths(config.ignoredPaths)
108
+ };
109
+ ensureTerraformCli();
110
+ const solidSettings = new SolidLspSettings(options?.solidlspSettings);
111
+ const runtimeDir = resolveRuntimeDirectory(solidSettings);
112
+ const dependencies = new RuntimeDependencyCollection(TERRAFORM_DEPENDENCIES);
113
+ const binaryPath = ensureTerraformLanguageServer(runtimeDir, dependencies, loggerLike?.level);
114
+ const handler = new NodeLanguageServerHandler({
115
+ cmd: `${quoteWindowsPath(binaryPath)} serve`,
116
+ cwd: repositoryRootPath
117
+ });
118
+ super(augmentedConfig, loggerLike, repositoryRootPath, {
119
+ ...options,
120
+ handler,
121
+ solidlspSettings: options?.solidlspSettings
122
+ });
123
+ this.handler = handler;
124
+ this.registerHandlers();
125
+ }
126
+ registerHandlers() {
127
+ const noop = () => undefined;
128
+ this.handler.onNotification('window/logMessage', (payload) => {
129
+ if (payload && typeof payload === 'object' && 'message' in payload) {
130
+ this.logger.info(`terraform-ls: ${payload.message ?? ''}`);
131
+ }
132
+ });
133
+ this.handler.onNotification('$/progress', noop);
134
+ this.handler.onNotification('textDocument/publishDiagnostics', noop);
135
+ this.handler.onRequest('client/registerCapability', noop);
136
+ this.handler.onRequest('workspace/executeClientCommand', () => []);
137
+ }
138
+ }
139
+ registerLanguageServer(Language.TERRAFORM, TerraformLanguageServer);
@@ -0,0 +1,20 @@
1
+ import { type LogLevel } from '../../serena/util/logging.js';
2
+ import { SolidLanguageServer, type LanguageServerConfigLike, type SolidLspSettingsInit } from '../ls.js';
3
+ export declare class TypeScriptLanguageServer extends SolidLanguageServer {
4
+ private readonly nodeHandler;
5
+ private initialized;
6
+ private serverReady;
7
+ private initializeCommandRegistered;
8
+ constructor(config: LanguageServerConfigLike, loggerLike: {
9
+ level?: number | LogLevel;
10
+ } | null, repositoryRootPath: string, options?: {
11
+ timeout?: number | null;
12
+ solidlspSettings?: SolidLspSettingsInit;
13
+ });
14
+ start(): this;
15
+ stop(shutdownTimeout?: number): void;
16
+ private registerHandlers;
17
+ private initializeLanguageServer;
18
+ private buildInitializeParams;
19
+ private verifyCapabilities;
20
+ }