decorated-pi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/extensions/extend-model.ts +410 -0
- package/extensions/guidance.ts +21 -0
- package/extensions/index.ts +24 -0
- package/extensions/lsp/client.ts +525 -0
- package/extensions/lsp/env.ts +12 -0
- package/extensions/lsp/format.ts +349 -0
- package/extensions/lsp/index.ts +14 -0
- package/extensions/lsp/prompt.ts +39 -0
- package/extensions/lsp/server-manager.ts +303 -0
- package/extensions/lsp/servers.ts +229 -0
- package/extensions/lsp/tools.ts +530 -0
- package/extensions/lsp/trust.ts +39 -0
- package/extensions/safety.ts +370 -0
- package/extensions/session-title.ts +40 -0
- package/extensions/settings.ts +62 -0
- package/extensions/slash.ts +67 -0
- package/extensions/smart-at.ts +220 -0
- package/extensions/subdir-agents.ts +121 -0
- package/index.ts +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, extname, isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
const EXTENSION_LANGUAGES: Record<string, string> = {
|
|
5
|
+
".ts": "typescript",
|
|
6
|
+
".tsx": "typescript",
|
|
7
|
+
".mts": "typescript",
|
|
8
|
+
".cts": "typescript",
|
|
9
|
+
".js": "typescript",
|
|
10
|
+
".jsx": "typescript",
|
|
11
|
+
".mjs": "typescript",
|
|
12
|
+
".cjs": "typescript",
|
|
13
|
+
".c": "c",
|
|
14
|
+
".h": "cpp",
|
|
15
|
+
".cc": "cpp",
|
|
16
|
+
".cp": "cpp",
|
|
17
|
+
".cpp": "cpp",
|
|
18
|
+
".cxx": "cpp",
|
|
19
|
+
".hh": "cpp",
|
|
20
|
+
".hpp": "cpp",
|
|
21
|
+
".hxx": "cpp",
|
|
22
|
+
".ipp": "cpp",
|
|
23
|
+
".ixx": "cpp",
|
|
24
|
+
".tpp": "cpp",
|
|
25
|
+
".py": "python",
|
|
26
|
+
".rs": "rust",
|
|
27
|
+
".go": "go",
|
|
28
|
+
".rb": "ruby",
|
|
29
|
+
".java": "java",
|
|
30
|
+
".lua": "lua",
|
|
31
|
+
".svelte": "svelte",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type LanguageConfig = {
|
|
35
|
+
language: string;
|
|
36
|
+
command: string;
|
|
37
|
+
args: string[];
|
|
38
|
+
install_hint: string;
|
|
39
|
+
is_project_local?: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const LANGUAGE_SERVERS: Record<string, Omit<LanguageConfig, "is_project_local">> = {
|
|
43
|
+
typescript: {
|
|
44
|
+
language: "typescript",
|
|
45
|
+
command: "typescript-language-server",
|
|
46
|
+
args: ["--stdio"],
|
|
47
|
+
install_hint:
|
|
48
|
+
"Install TypeScript LSP with: pnpm add -D typescript typescript-language-server",
|
|
49
|
+
},
|
|
50
|
+
c: {
|
|
51
|
+
language: "c",
|
|
52
|
+
command: "clangd",
|
|
53
|
+
args: ["--background-index"],
|
|
54
|
+
install_hint: "Install clangd and ensure the clangd binary is on PATH.",
|
|
55
|
+
},
|
|
56
|
+
cpp: {
|
|
57
|
+
language: "cpp",
|
|
58
|
+
command: "clangd",
|
|
59
|
+
args: ["--background-index"],
|
|
60
|
+
install_hint: "Install clangd and ensure the clangd binary is on PATH.",
|
|
61
|
+
},
|
|
62
|
+
python: {
|
|
63
|
+
language: "python",
|
|
64
|
+
command: "pylsp",
|
|
65
|
+
args: [],
|
|
66
|
+
install_hint: "Install Python LSP with: pip install python-lsp-server",
|
|
67
|
+
},
|
|
68
|
+
rust: {
|
|
69
|
+
language: "rust",
|
|
70
|
+
command: "rust-analyzer",
|
|
71
|
+
args: [],
|
|
72
|
+
install_hint:
|
|
73
|
+
"Install Rust Analyzer and ensure the rust-analyzer binary is on PATH.",
|
|
74
|
+
},
|
|
75
|
+
go: {
|
|
76
|
+
language: "go",
|
|
77
|
+
command: "gopls",
|
|
78
|
+
args: ["serve"],
|
|
79
|
+
install_hint:
|
|
80
|
+
"Install Go LSP with: go install golang.org/x/tools/gopls@latest",
|
|
81
|
+
},
|
|
82
|
+
ruby: {
|
|
83
|
+
language: "ruby",
|
|
84
|
+
command: "solargraph",
|
|
85
|
+
args: ["stdio"],
|
|
86
|
+
install_hint: "Install Ruby LSP with: gem install solargraph",
|
|
87
|
+
},
|
|
88
|
+
java: {
|
|
89
|
+
language: "java",
|
|
90
|
+
command: "jdtls",
|
|
91
|
+
args: [],
|
|
92
|
+
install_hint:
|
|
93
|
+
"Install Eclipse JDT Language Server and ensure the jdtls binary is on PATH.",
|
|
94
|
+
},
|
|
95
|
+
lua: {
|
|
96
|
+
language: "lua",
|
|
97
|
+
command: "lua-language-server",
|
|
98
|
+
args: [],
|
|
99
|
+
install_hint:
|
|
100
|
+
"Install Lua LSP and ensure the lua-language-server binary is on PATH.",
|
|
101
|
+
},
|
|
102
|
+
svelte: {
|
|
103
|
+
language: "svelte",
|
|
104
|
+
command: "svelteserver",
|
|
105
|
+
args: ["--stdio"],
|
|
106
|
+
install_hint:
|
|
107
|
+
"Install Svelte LSP with: pnpm add -D svelte-language-server (or volta install svelte-language-server)",
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const WORKSPACE_MARKERS = [
|
|
112
|
+
"svelte.config.js",
|
|
113
|
+
"svelte.config.ts",
|
|
114
|
+
"tsconfig.json",
|
|
115
|
+
"jsconfig.json",
|
|
116
|
+
"package.json",
|
|
117
|
+
"pyproject.toml",
|
|
118
|
+
"Cargo.toml",
|
|
119
|
+
"go.mod",
|
|
120
|
+
"Gemfile",
|
|
121
|
+
"pom.xml",
|
|
122
|
+
"build.gradle",
|
|
123
|
+
"build.gradle.kts",
|
|
124
|
+
".clangd",
|
|
125
|
+
"compile_commands.json",
|
|
126
|
+
"compile_flags.txt",
|
|
127
|
+
"CMakeLists.txt",
|
|
128
|
+
"meson.build",
|
|
129
|
+
"Makefile",
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
const REPOSITORY_MARKERS = [
|
|
133
|
+
"pnpm-workspace.yaml",
|
|
134
|
+
"package-lock.json",
|
|
135
|
+
"yarn.lock",
|
|
136
|
+
"bun.lockb",
|
|
137
|
+
"bun.lock",
|
|
138
|
+
".git",
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
export function detect_language(file_path: string): string | undefined {
|
|
142
|
+
return EXTENSION_LANGUAGES[extname(file_path).toLowerCase()];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function list_supported_languages(): string[] {
|
|
146
|
+
return Object.keys(LANGUAGE_SERVERS).sort();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function resolve_server_command_info(
|
|
150
|
+
command: string,
|
|
151
|
+
cwd: string = process.cwd()
|
|
152
|
+
): { command: string; is_project_local: boolean } {
|
|
153
|
+
if (
|
|
154
|
+
!command ||
|
|
155
|
+
isAbsolute(command) ||
|
|
156
|
+
command.includes("/") ||
|
|
157
|
+
command.includes("\\")
|
|
158
|
+
) {
|
|
159
|
+
return { command, is_project_local: false };
|
|
160
|
+
}
|
|
161
|
+
for (const dir of ancestor_directories(cwd)) {
|
|
162
|
+
const local_bin = resolve_local_binary(dir, command);
|
|
163
|
+
if (local_bin) {
|
|
164
|
+
return { command: local_bin, is_project_local: true };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { command, is_project_local: false };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function get_server_config(
|
|
171
|
+
language: string,
|
|
172
|
+
cwd: string = process.cwd()
|
|
173
|
+
): LanguageConfig | undefined {
|
|
174
|
+
const base = LANGUAGE_SERVERS[language];
|
|
175
|
+
if (!base) return undefined;
|
|
176
|
+
const resolved = resolve_server_command_info(base.command, cwd);
|
|
177
|
+
return { ...base, command: resolved.command, is_project_local: resolved.is_project_local };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function language_id_for_file(file_path: string): string | undefined {
|
|
181
|
+
return detect_language(file_path);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function find_workspace_root(
|
|
185
|
+
file_path: string,
|
|
186
|
+
fallback: string = process.cwd()
|
|
187
|
+
): string {
|
|
188
|
+
const start = resolve(dirname(file_path));
|
|
189
|
+
const project_root = find_nearest_marker_directory(start, WORKSPACE_MARKERS);
|
|
190
|
+
if (project_root) return project_root;
|
|
191
|
+
const repo_root = find_nearest_marker_directory(start, REPOSITORY_MARKERS);
|
|
192
|
+
if (repo_root) return repo_root;
|
|
193
|
+
return resolve(fallback);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function find_nearest_marker_directory(
|
|
197
|
+
start: string,
|
|
198
|
+
markers: string[]
|
|
199
|
+
): string | undefined {
|
|
200
|
+
for (const dir of ancestor_directories(start)) {
|
|
201
|
+
if (markers.some((marker) => existsSync(join(dir, marker)))) {
|
|
202
|
+
return dir;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function ancestor_directories(start: string): string[] {
|
|
209
|
+
const dirs: string[] = [];
|
|
210
|
+
let current = resolve(start);
|
|
211
|
+
while (true) {
|
|
212
|
+
dirs.push(current);
|
|
213
|
+
const parent = dirname(current);
|
|
214
|
+
if (parent === current) break;
|
|
215
|
+
current = parent;
|
|
216
|
+
}
|
|
217
|
+
return dirs;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function resolve_local_binary(
|
|
221
|
+
directory: string,
|
|
222
|
+
command: string
|
|
223
|
+
): string | undefined {
|
|
224
|
+
const candidates = [
|
|
225
|
+
join(directory, "node_modules", ".bin", command),
|
|
226
|
+
join(directory, "node_modules", ".bin", `${command}.cmd`),
|
|
227
|
+
];
|
|
228
|
+
return candidates.find((candidate) => existsSync(candidate));
|
|
229
|
+
}
|