@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.
- package/LICENSE +22 -0
- package/README.md +244 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +7 -0
- package/dist/devtools/generate_prompt_factory.d.ts +5 -0
- package/dist/devtools/generate_prompt_factory.js +114 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +34 -0
- package/dist/interprompt/index.d.ts +2 -0
- package/dist/interprompt/index.js +1 -0
- package/dist/interprompt/jinja_template.d.ts +10 -0
- package/dist/interprompt/jinja_template.js +174 -0
- package/dist/interprompt/multilang_prompt.d.ts +54 -0
- package/dist/interprompt/multilang_prompt.js +302 -0
- package/dist/interprompt/prompt_factory.d.ts +16 -0
- package/dist/interprompt/prompt_factory.js +189 -0
- package/dist/interprompt/util/class_decorators.d.ts +1 -0
- package/dist/interprompt/util/class_decorators.js +1 -0
- package/dist/interprompt/util/index.d.ts +1 -0
- package/dist/interprompt/util/index.js +1 -0
- package/dist/serena/agent.d.ts +118 -0
- package/dist/serena/agent.js +675 -0
- package/dist/serena/agno.d.ts +111 -0
- package/dist/serena/agno.js +278 -0
- package/dist/serena/analytics.d.ts +24 -0
- package/dist/serena/analytics.js +119 -0
- package/dist/serena/cli.d.ts +9 -0
- package/dist/serena/cli.js +731 -0
- package/dist/serena/code_editor.d.ts +42 -0
- package/dist/serena/code_editor.js +239 -0
- package/dist/serena/config/context_mode.d.ts +41 -0
- package/dist/serena/config/context_mode.js +239 -0
- package/dist/serena/config/serena_config.d.ts +134 -0
- package/dist/serena/config/serena_config.js +718 -0
- package/dist/serena/constants.d.ts +18 -0
- package/dist/serena/constants.js +27 -0
- package/dist/serena/dashboard.d.ts +55 -0
- package/dist/serena/dashboard.js +472 -0
- package/dist/serena/generated/generated_prompt_factory.d.ts +27 -0
- package/dist/serena/generated/generated_prompt_factory.js +42 -0
- package/dist/serena/gui_log_viewer.d.ts +41 -0
- package/dist/serena/gui_log_viewer.js +436 -0
- package/dist/serena/mcp.d.ts +118 -0
- package/dist/serena/mcp.js +904 -0
- package/dist/serena/project.d.ts +62 -0
- package/dist/serena/project.js +321 -0
- package/dist/serena/prompt_factory.d.ts +20 -0
- package/dist/serena/prompt_factory.js +42 -0
- package/dist/serena/resources/config/contexts/agent.yml +8 -0
- package/dist/serena/resources/config/contexts/chatgpt.yml +28 -0
- package/dist/serena/resources/config/contexts/codex.yml +27 -0
- package/dist/serena/resources/config/contexts/context.template.yml +11 -0
- package/dist/serena/resources/config/contexts/desktop-app.yml +17 -0
- package/dist/serena/resources/config/contexts/ide-assistant.yml +26 -0
- package/dist/serena/resources/config/contexts/oaicompat-agent.yml +8 -0
- package/dist/serena/resources/config/internal_modes/jetbrains.yml +15 -0
- package/dist/serena/resources/config/modes/editing.yml +112 -0
- package/dist/serena/resources/config/modes/interactive.yml +11 -0
- package/dist/serena/resources/config/modes/mode.template.yml +7 -0
- package/dist/serena/resources/config/modes/no-onboarding.yml +8 -0
- package/dist/serena/resources/config/modes/onboarding.yml +16 -0
- package/dist/serena/resources/config/modes/one-shot.yml +15 -0
- package/dist/serena/resources/config/modes/planning.yml +15 -0
- package/dist/serena/resources/config/prompt_templates/simple_tool_outputs.yml +75 -0
- package/dist/serena/resources/config/prompt_templates/system_prompt.yml +66 -0
- package/dist/serena/resources/dashboard/dashboard.js +815 -0
- package/dist/serena/resources/dashboard/index.html +314 -0
- package/dist/serena/resources/dashboard/jquery.min.js +3 -0
- package/dist/serena/resources/dashboard/serena-icon-16.png +0 -0
- package/dist/serena/resources/dashboard/serena-icon-32.png +0 -0
- package/dist/serena/resources/dashboard/serena-icon-48.png +0 -0
- package/dist/serena/resources/dashboard/serena-logs-dark-mode.png +0 -0
- package/dist/serena/resources/dashboard/serena-logs.png +0 -0
- package/dist/serena/resources/project.template.yml +67 -0
- package/dist/serena/resources/serena_config.template.yml +85 -0
- package/dist/serena/symbol.d.ts +199 -0
- package/dist/serena/symbol.js +616 -0
- package/dist/serena/text_utils.d.ts +51 -0
- package/dist/serena/text_utils.js +267 -0
- package/dist/serena/tools/cmd_tools.d.ts +31 -0
- package/dist/serena/tools/cmd_tools.js +48 -0
- package/dist/serena/tools/config_tools.d.ts +53 -0
- package/dist/serena/tools/config_tools.js +176 -0
- package/dist/serena/tools/file_tools.d.ts +231 -0
- package/dist/serena/tools/file_tools.js +511 -0
- package/dist/serena/tools/index.d.ts +7 -0
- package/dist/serena/tools/index.js +7 -0
- package/dist/serena/tools/memory_tools.d.ts +60 -0
- package/dist/serena/tools/memory_tools.js +135 -0
- package/dist/serena/tools/symbol_tools.d.ts +165 -0
- package/dist/serena/tools/symbol_tools.js +362 -0
- package/dist/serena/tools/tools_base.d.ts +162 -0
- package/dist/serena/tools/tools_base.js +378 -0
- package/dist/serena/tools/workflow_tools.d.ts +35 -0
- package/dist/serena/tools/workflow_tools.js +161 -0
- package/dist/serena/util/class_decorators.d.ts +7 -0
- package/dist/serena/util/class_decorators.js +37 -0
- package/dist/serena/util/exception.d.ts +8 -0
- package/dist/serena/util/exception.js +53 -0
- package/dist/serena/util/file_system.d.ts +30 -0
- package/dist/serena/util/file_system.js +352 -0
- package/dist/serena/util/general.d.ts +11 -0
- package/dist/serena/util/general.js +42 -0
- package/dist/serena/util/git.d.ts +11 -0
- package/dist/serena/util/git.js +37 -0
- package/dist/serena/util/inspection.d.ts +45 -0
- package/dist/serena/util/inspection.js +221 -0
- package/dist/serena/util/logging.d.ts +46 -0
- package/dist/serena/util/logging.js +205 -0
- package/dist/serena/util/shell.d.ts +21 -0
- package/dist/serena/util/shell.js +95 -0
- package/dist/serena/util/thread.d.ts +23 -0
- package/dist/serena/util/thread.js +88 -0
- package/dist/serena/version.d.ts +1 -0
- package/dist/serena/version.js +23 -0
- package/dist/solidlsp/language_servers/autoload.d.ts +23 -0
- package/dist/solidlsp/language_servers/autoload.js +25 -0
- package/dist/solidlsp/language_servers/bash_language_server.d.ts +10 -0
- package/dist/solidlsp/language_servers/bash_language_server.js +64 -0
- package/dist/solidlsp/language_servers/clangd_language_server.d.ts +13 -0
- package/dist/solidlsp/language_servers/clangd_language_server.js +110 -0
- package/dist/solidlsp/language_servers/clojure_lsp.d.ts +13 -0
- package/dist/solidlsp/language_servers/clojure_lsp.js +137 -0
- package/dist/solidlsp/language_servers/common.d.ts +41 -0
- package/dist/solidlsp/language_servers/common.js +365 -0
- package/dist/solidlsp/language_servers/csharp_language_server.d.ts +21 -0
- package/dist/solidlsp/language_servers/csharp_language_server.js +694 -0
- package/dist/solidlsp/language_servers/dart_language_server.d.ts +10 -0
- package/dist/solidlsp/language_servers/dart_language_server.js +122 -0
- package/dist/solidlsp/language_servers/eclipse_jdtls.d.ts +24 -0
- package/dist/solidlsp/language_servers/eclipse_jdtls.js +671 -0
- package/dist/solidlsp/language_servers/erlang_language_server.d.ts +22 -0
- package/dist/solidlsp/language_servers/erlang_language_server.js +327 -0
- package/dist/solidlsp/language_servers/gopls.d.ts +12 -0
- package/dist/solidlsp/language_servers/gopls.js +59 -0
- package/dist/solidlsp/language_servers/intelephense.d.ts +13 -0
- package/dist/solidlsp/language_servers/intelephense.js +121 -0
- package/dist/solidlsp/language_servers/jedi_server.d.ts +18 -0
- package/dist/solidlsp/language_servers/jedi_server.js +234 -0
- package/dist/solidlsp/language_servers/kotlin_language_server.d.ts +19 -0
- package/dist/solidlsp/language_servers/kotlin_language_server.js +474 -0
- package/dist/solidlsp/language_servers/lua_ls.d.ts +18 -0
- package/dist/solidlsp/language_servers/lua_ls.js +319 -0
- package/dist/solidlsp/language_servers/nixd_language_server.d.ts +17 -0
- package/dist/solidlsp/language_servers/nixd_language_server.js +341 -0
- package/dist/solidlsp/language_servers/pyright_server.d.ts +19 -0
- package/dist/solidlsp/language_servers/pyright_server.js +180 -0
- package/dist/solidlsp/language_servers/r_language_server.d.ts +19 -0
- package/dist/solidlsp/language_servers/r_language_server.js +184 -0
- package/dist/solidlsp/language_servers/ruby_common.d.ts +10 -0
- package/dist/solidlsp/language_servers/ruby_common.js +136 -0
- package/dist/solidlsp/language_servers/ruby_lsp.d.ts +18 -0
- package/dist/solidlsp/language_servers/ruby_lsp.js +230 -0
- package/dist/solidlsp/language_servers/rust_analyzer.d.ts +13 -0
- package/dist/solidlsp/language_servers/rust_analyzer.js +96 -0
- package/dist/solidlsp/language_servers/solargraph.d.ts +18 -0
- package/dist/solidlsp/language_servers/solargraph.js +208 -0
- package/dist/solidlsp/language_servers/sourcekit_lsp.d.ts +24 -0
- package/dist/solidlsp/language_servers/sourcekit_lsp.js +449 -0
- package/dist/solidlsp/language_servers/terraform_ls.d.ts +13 -0
- package/dist/solidlsp/language_servers/terraform_ls.js +139 -0
- package/dist/solidlsp/language_servers/typescript_language_server.d.ts +20 -0
- package/dist/solidlsp/language_servers/typescript_language_server.js +237 -0
- package/dist/solidlsp/language_servers/vts_language_server.d.ts +13 -0
- package/dist/solidlsp/language_servers/vts_language_server.js +121 -0
- package/dist/solidlsp/language_servers/zls.d.ts +20 -0
- package/dist/solidlsp/language_servers/zls.js +254 -0
- package/dist/solidlsp/ls.d.ts +197 -0
- package/dist/solidlsp/ls.js +507 -0
- package/dist/solidlsp/ls_config.d.ts +43 -0
- package/dist/solidlsp/ls_config.js +157 -0
- package/dist/solidlsp/ls_exceptions.d.ts +5 -0
- package/dist/solidlsp/ls_exceptions.js +14 -0
- package/dist/solidlsp/ls_handler.d.ts +54 -0
- package/dist/solidlsp/ls_handler.js +406 -0
- package/dist/solidlsp/ls_request.d.ts +31 -0
- package/dist/solidlsp/ls_request.js +42 -0
- package/dist/solidlsp/ls_types.d.ts +7 -0
- package/dist/solidlsp/ls_types.js +8 -0
- package/dist/solidlsp/lsp_protocol_handler/server.d.ts +61 -0
- package/dist/solidlsp/lsp_protocol_handler/server.js +68 -0
- package/dist/solidlsp/util/subprocess_util.d.ts +6 -0
- package/dist/solidlsp/util/subprocess_util.js +11 -0
- package/dist/solidlsp/util/zip.d.ts +25 -0
- package/dist/solidlsp/util/zip.js +188 -0
- package/package.json +65 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Buffer } from 'node:buffer';
|
|
2
|
+
import { type SpawnSyncOptions, type SpawnSyncReturns } from 'node:child_process';
|
|
3
|
+
import type { SerenaLogger } from '../../serena/util/logging.js';
|
|
4
|
+
export interface RuntimeDependency {
|
|
5
|
+
id: string;
|
|
6
|
+
platformId?: PlatformId | 'any' | 'platform-agnostic' | null;
|
|
7
|
+
url?: string | null;
|
|
8
|
+
archiveType?: string | null;
|
|
9
|
+
binaryName?: string | null;
|
|
10
|
+
command?: string | string[] | null;
|
|
11
|
+
packageName?: string | null;
|
|
12
|
+
packageVersion?: string | null;
|
|
13
|
+
extractPath?: string | null;
|
|
14
|
+
description?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export type RuntimeDependencyOverride = RuntimeDependency;
|
|
17
|
+
export type PlatformId = 'win-x86' | 'win-x64' | 'win-arm64' | 'osx' | 'osx-x64' | 'osx-arm64' | 'linux-x86' | 'linux-x64' | 'linux-arm64' | 'linux-musl-x64' | 'linux-musl-arm64';
|
|
18
|
+
export type CommandRunner = (command: string, args: string[], options: SpawnSyncOptions) => SpawnSyncReturns<string | Buffer>;
|
|
19
|
+
export declare class RuntimeDependencyCollection {
|
|
20
|
+
private readonly byKey;
|
|
21
|
+
private readonly commandRunner;
|
|
22
|
+
constructor(dependencies: RuntimeDependency[], overrides?: RuntimeDependencyOverride[], options?: {
|
|
23
|
+
runCommand?: CommandRunner;
|
|
24
|
+
});
|
|
25
|
+
getDependenciesForPlatform(platformId: PlatformId): RuntimeDependency[];
|
|
26
|
+
getDependenciesForCurrentPlatform(): RuntimeDependency[];
|
|
27
|
+
getSingleDepForCurrentPlatform(dependencyId?: string | null): RuntimeDependency;
|
|
28
|
+
binaryPath(targetDir: string): string;
|
|
29
|
+
install(logger: SerenaLogger, targetDir: string): Record<string, string>;
|
|
30
|
+
private runCommand;
|
|
31
|
+
private makeKey;
|
|
32
|
+
private installFromUrl;
|
|
33
|
+
private downloadArchive;
|
|
34
|
+
private extractArchive;
|
|
35
|
+
private extractGz;
|
|
36
|
+
}
|
|
37
|
+
export declare function quoteWindowsPath(inputPath: string): string;
|
|
38
|
+
export declare const Platform: {
|
|
39
|
+
readonly current: () => PlatformId;
|
|
40
|
+
readonly isWindows: () => boolean;
|
|
41
|
+
};
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { URL } from 'node:url';
|
|
6
|
+
import { gunzipSync } from 'node:zlib';
|
|
7
|
+
import AdmZip from 'adm-zip';
|
|
8
|
+
import * as tar from 'tar';
|
|
9
|
+
import { ensureDefaultSubprocessOptions } from '../util/subprocess_util.js';
|
|
10
|
+
function determinePlatformId() {
|
|
11
|
+
const platform = process.platform;
|
|
12
|
+
const arch = process.arch;
|
|
13
|
+
if (platform === 'win32') {
|
|
14
|
+
if (arch === 'x64' || arch === 'arm64') {
|
|
15
|
+
return arch === 'x64' ? 'win-x64' : 'win-arm64';
|
|
16
|
+
}
|
|
17
|
+
return 'win-x86';
|
|
18
|
+
}
|
|
19
|
+
if (platform === 'darwin') {
|
|
20
|
+
return arch === 'arm64' ? 'osx-arm64' : 'osx-x64';
|
|
21
|
+
}
|
|
22
|
+
if (platform === 'linux') {
|
|
23
|
+
const libc = os.type().toLowerCase().includes('musl') ? 'musl' : 'glibc';
|
|
24
|
+
if (arch === 'arm64') {
|
|
25
|
+
return libc === 'musl' ? 'linux-musl-arm64' : 'linux-arm64';
|
|
26
|
+
}
|
|
27
|
+
if (arch === 'x64') {
|
|
28
|
+
return libc === 'musl' ? 'linux-musl-x64' : 'linux-x64';
|
|
29
|
+
}
|
|
30
|
+
return 'linux-x86';
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Unsupported platform: platform=${platform}, arch=${arch}`);
|
|
33
|
+
}
|
|
34
|
+
function currentPlatformId() {
|
|
35
|
+
return determinePlatformId();
|
|
36
|
+
}
|
|
37
|
+
function normalizeCommand(command) {
|
|
38
|
+
if (Array.isArray(command)) {
|
|
39
|
+
const [cmd, ...args] = command;
|
|
40
|
+
if (!cmd) {
|
|
41
|
+
throw new Error('Runtime dependency command must not be empty.');
|
|
42
|
+
}
|
|
43
|
+
return { cmd, args, shell: false };
|
|
44
|
+
}
|
|
45
|
+
return { cmd: command, args: [], shell: true };
|
|
46
|
+
}
|
|
47
|
+
export class RuntimeDependencyCollection {
|
|
48
|
+
byKey = new Map();
|
|
49
|
+
commandRunner;
|
|
50
|
+
constructor(dependencies, overrides = [], options = {}) {
|
|
51
|
+
for (const dep of dependencies) {
|
|
52
|
+
const key = this.makeKey(dep.id, dep.platformId ?? null);
|
|
53
|
+
if (this.byKey.has(key)) {
|
|
54
|
+
throw new Error(`Duplicate runtime dependency: id=${dep.id}, platform=${dep.platformId ?? 'default'}`);
|
|
55
|
+
}
|
|
56
|
+
this.byKey.set(key, dep);
|
|
57
|
+
}
|
|
58
|
+
for (const override of overrides) {
|
|
59
|
+
const key = this.makeKey(override.id, override.platformId ?? null);
|
|
60
|
+
const existing = this.byKey.get(key);
|
|
61
|
+
if (existing) {
|
|
62
|
+
this.byKey.set(key, { ...existing, ...override });
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.byKey.set(key, override);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
this.commandRunner =
|
|
69
|
+
options.runCommand ??
|
|
70
|
+
((command, args, opt) => {
|
|
71
|
+
const baseOptions = opt ? { ...opt } : {};
|
|
72
|
+
const spawnOptions = ensureDefaultSubprocessOptions(baseOptions);
|
|
73
|
+
return spawnSync(command, args, spawnOptions);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
getDependenciesForPlatform(platformId) {
|
|
77
|
+
return Array.from(this.byKey.values()).filter((dep) => {
|
|
78
|
+
const target = dep.platformId ?? null;
|
|
79
|
+
return target === null || target === 'any' || target === 'platform-agnostic' || target === platformId;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
getDependenciesForCurrentPlatform() {
|
|
83
|
+
return this.getDependenciesForPlatform(currentPlatformId());
|
|
84
|
+
}
|
|
85
|
+
getSingleDepForCurrentPlatform(dependencyId) {
|
|
86
|
+
let deps = this.getDependenciesForCurrentPlatform();
|
|
87
|
+
if (dependencyId) {
|
|
88
|
+
deps = deps.filter((dep) => dep.id === dependencyId);
|
|
89
|
+
}
|
|
90
|
+
if (deps.length !== 1) {
|
|
91
|
+
throw new Error(`Expected exactly one runtime dependency (platform=${currentPlatformId()}, dependencyId=${dependencyId ?? 'any'}), found ${deps.length}.`);
|
|
92
|
+
}
|
|
93
|
+
return deps[0];
|
|
94
|
+
}
|
|
95
|
+
binaryPath(targetDir) {
|
|
96
|
+
const dep = this.getSingleDepForCurrentPlatform();
|
|
97
|
+
if (!dep.binaryName) {
|
|
98
|
+
return targetDir;
|
|
99
|
+
}
|
|
100
|
+
return path.join(targetDir, dep.binaryName);
|
|
101
|
+
}
|
|
102
|
+
install(logger, targetDir) {
|
|
103
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
104
|
+
const results = {};
|
|
105
|
+
for (const dep of this.getDependenciesForCurrentPlatform()) {
|
|
106
|
+
if (dep.url) {
|
|
107
|
+
this.installFromUrl(dep, logger, targetDir);
|
|
108
|
+
}
|
|
109
|
+
if (dep.command) {
|
|
110
|
+
this.runCommand(dep, targetDir, logger);
|
|
111
|
+
}
|
|
112
|
+
const key = dep.id;
|
|
113
|
+
const binaryPath = dep.binaryName ? path.join(targetDir, dep.binaryName) : targetDir;
|
|
114
|
+
results[key] = binaryPath;
|
|
115
|
+
}
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
118
|
+
runCommand(dep, cwd, logger) {
|
|
119
|
+
const command = dep.command;
|
|
120
|
+
if (!command) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const { cmd, args, shell } = normalizeCommand(command);
|
|
124
|
+
const options = ensureDefaultSubprocessOptions({
|
|
125
|
+
cwd,
|
|
126
|
+
shell,
|
|
127
|
+
stdio: 'inherit'
|
|
128
|
+
});
|
|
129
|
+
logger.info(`Installing dependency ${dep.id} via ${Array.isArray(command) ? command.join(' ') : command}`);
|
|
130
|
+
const result = this.commandRunner(cmd, args, options);
|
|
131
|
+
if (result.error) {
|
|
132
|
+
throw result.error;
|
|
133
|
+
}
|
|
134
|
+
if (result.status !== 0) {
|
|
135
|
+
throw new Error(`Command for dependency ${dep.id} exited with status ${result.status ?? 'unknown'}.`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
makeKey(id, platformId) {
|
|
139
|
+
return `${id}::${platformId ?? 'default'}`;
|
|
140
|
+
}
|
|
141
|
+
installFromUrl(dep, logger, targetDir) {
|
|
142
|
+
if (!dep.url) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'serena-runtime-'));
|
|
146
|
+
const downloadPath = path.join(tempRoot, inferFilenameFromUrl(dep));
|
|
147
|
+
try {
|
|
148
|
+
this.downloadArchive(dep, downloadPath, logger);
|
|
149
|
+
this.extractArchive(dep, downloadPath, targetDir, logger);
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
try {
|
|
153
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// best effort cleanup
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
downloadArchive(dep, destination, logger) {
|
|
161
|
+
logger.info(`Downloading runtime dependency ${dep.id} from ${dep.url}`);
|
|
162
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
163
|
+
const commonOptions = {
|
|
164
|
+
cwd: path.dirname(destination),
|
|
165
|
+
stdio: 'inherit'
|
|
166
|
+
};
|
|
167
|
+
const run = (command, args) => this.commandRunner(command, args, commonOptions);
|
|
168
|
+
const url = dep.url;
|
|
169
|
+
const curlArgs = ['-L', url, '-o', destination];
|
|
170
|
+
const curlResult = run('curl', curlArgs);
|
|
171
|
+
if (curlResult.status === 0) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (process.platform !== 'win32') {
|
|
175
|
+
const wgetResult = run('wget', ['-O', destination, url]);
|
|
176
|
+
if (wgetResult.status === 0) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
const psArgs = [
|
|
182
|
+
'-NoLogo',
|
|
183
|
+
'-NoProfile',
|
|
184
|
+
'-ExecutionPolicy',
|
|
185
|
+
'Bypass',
|
|
186
|
+
'-Command',
|
|
187
|
+
`Invoke-WebRequest -Uri ${JSON.stringify(url)} -OutFile ${JSON.stringify(destination)} -UseBasicParsing`
|
|
188
|
+
];
|
|
189
|
+
const psResult = run('powershell', psArgs);
|
|
190
|
+
if (psResult.status === 0) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
throw new Error(`Failed to download runtime dependency ${dep.id}. Ensure curl, wget, or PowerShell is available in PATH.`);
|
|
195
|
+
}
|
|
196
|
+
extractArchive(dep, archivePath, targetDir, logger) {
|
|
197
|
+
const archiveType = normalizeArchiveType(dep.archiveType, archivePath);
|
|
198
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
199
|
+
switch (archiveType) {
|
|
200
|
+
case null:
|
|
201
|
+
copyFileToTarget(archivePath, targetDir, dep.binaryName);
|
|
202
|
+
break;
|
|
203
|
+
case 'gz':
|
|
204
|
+
this.extractGz(archivePath, targetDir, dep);
|
|
205
|
+
break;
|
|
206
|
+
case 'zip':
|
|
207
|
+
extractZipArchive(archivePath, targetDir, logger);
|
|
208
|
+
break;
|
|
209
|
+
case 'tar':
|
|
210
|
+
extractTarArchive(archivePath, targetDir, logger);
|
|
211
|
+
break;
|
|
212
|
+
case 'zip.gz': {
|
|
213
|
+
const buffer = gunzipSync(fs.readFileSync(archivePath));
|
|
214
|
+
const tmpZipPath = `${archivePath}.unzipped.zip`;
|
|
215
|
+
fs.writeFileSync(tmpZipPath, buffer);
|
|
216
|
+
try {
|
|
217
|
+
extractZipArchive(tmpZipPath, targetDir, logger);
|
|
218
|
+
}
|
|
219
|
+
finally {
|
|
220
|
+
fs.rmSync(tmpZipPath, { force: true });
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
default: {
|
|
225
|
+
const rawType = dep.archiveType ?? 'unknown';
|
|
226
|
+
throw new Error(`Unsupported archive type '${rawType}' for dependency ${dep.id}.`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
extractGz(archivePath, targetDir, dep) {
|
|
231
|
+
if (!dep.binaryName) {
|
|
232
|
+
throw new Error(`Dependency ${dep.id} with archiveType=gz must set binaryName.`);
|
|
233
|
+
}
|
|
234
|
+
const outputPath = path.join(targetDir, dep.binaryName);
|
|
235
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
236
|
+
const data = gunzipSync(fs.readFileSync(archivePath));
|
|
237
|
+
fs.writeFileSync(outputPath, data);
|
|
238
|
+
trySetExecutable(outputPath);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function inferFilenameFromUrl(dep) {
|
|
242
|
+
if (!dep.url) {
|
|
243
|
+
return `${dep.id}.download`;
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const parsed = new URL(dep.url);
|
|
247
|
+
const segments = parsed.pathname.split('/').filter(Boolean);
|
|
248
|
+
if (segments.length > 0) {
|
|
249
|
+
return segments[segments.length - 1];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// ignore invalid URLs
|
|
254
|
+
}
|
|
255
|
+
return `${dep.id}.download`;
|
|
256
|
+
}
|
|
257
|
+
function normalizeArchiveType(rawType, archivePath) {
|
|
258
|
+
if (rawType) {
|
|
259
|
+
const lowered = rawType.toLowerCase();
|
|
260
|
+
if (['zip', 'vsix', 'nupkg'].includes(lowered)) {
|
|
261
|
+
return 'zip';
|
|
262
|
+
}
|
|
263
|
+
if (['gz'].includes(lowered)) {
|
|
264
|
+
return 'gz';
|
|
265
|
+
}
|
|
266
|
+
if (['zip.gz'].includes(lowered)) {
|
|
267
|
+
return 'zip.gz';
|
|
268
|
+
}
|
|
269
|
+
if (['tar', 'gztar', 'bztar', 'xztar', 'tar.gz', 'tar.bz2', 'tar.xz', 'tgz'].includes(lowered)) {
|
|
270
|
+
return 'tar';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const loweredPath = archivePath.toLowerCase();
|
|
274
|
+
if (loweredPath.endsWith('.zip')) {
|
|
275
|
+
return 'zip';
|
|
276
|
+
}
|
|
277
|
+
if (loweredPath.endsWith('.tar.gz') || loweredPath.endsWith('.tgz') || loweredPath.endsWith('.tar.bz2') || loweredPath.endsWith('.tar.xz') || loweredPath.endsWith('.tar')) {
|
|
278
|
+
return 'tar';
|
|
279
|
+
}
|
|
280
|
+
if (loweredPath.endsWith('.zip.gz')) {
|
|
281
|
+
return 'zip.gz';
|
|
282
|
+
}
|
|
283
|
+
if (loweredPath.endsWith('.gz')) {
|
|
284
|
+
return 'gz';
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
function extractZipArchive(archivePath, targetDir, logger) {
|
|
289
|
+
logger.info(`Extracting ZIP archive ${archivePath} into ${targetDir}`);
|
|
290
|
+
const zip = new AdmZip(archivePath);
|
|
291
|
+
const entries = zip.getEntries();
|
|
292
|
+
for (const entry of entries) {
|
|
293
|
+
const entryPath = path.join(targetDir, entry.entryName);
|
|
294
|
+
if (entry.isDirectory) {
|
|
295
|
+
fs.mkdirSync(entryPath, { recursive: true });
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
fs.mkdirSync(path.dirname(entryPath), { recursive: true });
|
|
299
|
+
fs.writeFileSync(entryPath, entry.getData());
|
|
300
|
+
trySetExecutable(entryPath, entry);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function extractTarArchive(archivePath, targetDir, logger) {
|
|
304
|
+
logger.info(`Extracting TAR archive ${archivePath} into ${targetDir}`);
|
|
305
|
+
try {
|
|
306
|
+
tar.x({ file: archivePath, cwd: targetDir, sync: true, strict: true });
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
logger.warn(`tar.x failed for ${archivePath}: ${String(error)}. Falling back to system tar command.`);
|
|
310
|
+
const result = spawnSync('tar', ['-xf', archivePath, '-C', targetDir], ensureDefaultSubprocessOptions({ stdio: 'inherit' }));
|
|
311
|
+
if (result.error || result.status !== 0) {
|
|
312
|
+
throw new Error(`Failed to extract TAR archive ${archivePath}: ${result.error ?? `exit code ${result.status}`}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function copyFileToTarget(sourcePath, targetDir, binaryName) {
|
|
317
|
+
const destination = binaryName ? path.join(targetDir, binaryName) : path.join(targetDir, path.basename(sourcePath));
|
|
318
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
319
|
+
fs.copyFileSync(sourcePath, destination);
|
|
320
|
+
trySetExecutable(destination);
|
|
321
|
+
}
|
|
322
|
+
function trySetExecutable(filePath, zipEntry) {
|
|
323
|
+
if (process.platform === 'win32') {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const attr = zipEntry?.header?.attr;
|
|
327
|
+
if (attr != null) {
|
|
328
|
+
const mode = (attr >>> 16) & 0o777;
|
|
329
|
+
if (mode) {
|
|
330
|
+
try {
|
|
331
|
+
fs.chmodSync(filePath, mode);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// ignore chmod errors
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
const stats = fs.statSync(filePath);
|
|
341
|
+
if ((stats.mode & 0o111) === 0) {
|
|
342
|
+
fs.chmodSync(filePath, stats.mode | 0o555);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
// ignore chmod errors
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
export function quoteWindowsPath(inputPath) {
|
|
350
|
+
if (process.platform !== 'win32') {
|
|
351
|
+
return inputPath;
|
|
352
|
+
}
|
|
353
|
+
if (inputPath.startsWith('"') && inputPath.endsWith('"')) {
|
|
354
|
+
return inputPath;
|
|
355
|
+
}
|
|
356
|
+
return `"${inputPath}"`;
|
|
357
|
+
}
|
|
358
|
+
export const Platform = {
|
|
359
|
+
current() {
|
|
360
|
+
return currentPlatformId();
|
|
361
|
+
},
|
|
362
|
+
isWindows() {
|
|
363
|
+
return process.platform === 'win32';
|
|
364
|
+
}
|
|
365
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
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 CSharpLanguageServer extends SolidLanguageServer {
|
|
5
|
+
protected readonly handler: NodeLanguageServerHandler;
|
|
6
|
+
private initialized;
|
|
7
|
+
constructor(config: LanguageServerConfigLike, loggerLike: {
|
|
8
|
+
level?: number | LogLevel;
|
|
9
|
+
} | null, repositoryRootPath: string, options?: {
|
|
10
|
+
timeout?: number | null;
|
|
11
|
+
solidlspSettings?: SolidLspSettingsInit;
|
|
12
|
+
});
|
|
13
|
+
start(): this;
|
|
14
|
+
stop(shutdownTimeout?: number): void;
|
|
15
|
+
private registerHandlers;
|
|
16
|
+
private initializeLanguageServer;
|
|
17
|
+
private buildInitializeParams;
|
|
18
|
+
private applyDiagnosticCapabilities;
|
|
19
|
+
private verifyCapabilities;
|
|
20
|
+
private openSolutionAndProjects;
|
|
21
|
+
}
|