supipowers 0.1.0 → 0.1.3
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/bin/install.mjs +29 -53
- package/package.json +1 -1
- package/src/commands/config.ts +1 -1
- package/src/config/defaults.ts +0 -1
- package/src/config/schema.ts +0 -1
- package/src/lsp/detector.ts +17 -22
- package/src/lsp/setup-guide.ts +10 -41
- package/src/types.ts +0 -1
package/bin/install.mjs
CHANGED
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
note,
|
|
13
13
|
} from "@clack/prompts";
|
|
14
14
|
import { spawnSync } from "node:child_process";
|
|
15
|
-
import {
|
|
16
|
-
import { resolve,
|
|
15
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
16
|
+
import { resolve, dirname, join } from "node:path";
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
import { homedir } from "node:os";
|
|
19
19
|
|
|
@@ -59,53 +59,29 @@ function findOmpBinary() {
|
|
|
59
59
|
const LSP_SERVERS = [
|
|
60
60
|
{
|
|
61
61
|
language: "TypeScript / JavaScript",
|
|
62
|
-
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
|
|
63
62
|
server: "typescript-language-server",
|
|
64
63
|
installCmd: "bun add -g typescript-language-server typescript",
|
|
65
64
|
},
|
|
66
65
|
{
|
|
67
66
|
language: "Python",
|
|
68
|
-
extensions: [".py"],
|
|
69
67
|
server: "pyright",
|
|
70
68
|
installCmd: "pip install pyright",
|
|
71
69
|
},
|
|
72
70
|
{
|
|
73
71
|
language: "Rust",
|
|
74
|
-
extensions: [".rs"],
|
|
75
72
|
server: "rust-analyzer",
|
|
76
73
|
installCmd: "rustup component add rust-analyzer",
|
|
77
74
|
},
|
|
78
75
|
{
|
|
79
76
|
language: "Go",
|
|
80
|
-
extensions: [".go"],
|
|
81
77
|
server: "gopls",
|
|
82
78
|
installCmd: "go install golang.org/x/tools/gopls@latest",
|
|
83
79
|
},
|
|
84
80
|
];
|
|
85
81
|
|
|
86
|
-
function
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
const entries = readdirSync(dir, { withFileTypes: true });
|
|
90
|
-
for (const entry of entries) {
|
|
91
|
-
if (entry.isFile()) {
|
|
92
|
-
detected.add(extname(entry.name));
|
|
93
|
-
} else if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
94
|
-
// One level deep
|
|
95
|
-
try {
|
|
96
|
-
const subEntries = readdirSync(join(dir, entry.name), { withFileTypes: true });
|
|
97
|
-
for (const sub of subEntries) {
|
|
98
|
-
if (sub.isFile()) detected.add(extname(sub.name));
|
|
99
|
-
}
|
|
100
|
-
} catch {
|
|
101
|
-
// skip unreadable dirs
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
} catch {
|
|
106
|
-
// skip
|
|
107
|
-
}
|
|
108
|
-
return detected;
|
|
82
|
+
function isInstalled(binary) {
|
|
83
|
+
const result = run("which", [binary]);
|
|
84
|
+
return result.status === 0;
|
|
109
85
|
}
|
|
110
86
|
|
|
111
87
|
// ── Main ─────────────────────────────────────────────────────
|
|
@@ -178,33 +154,33 @@ async function main() {
|
|
|
178
154
|
|
|
179
155
|
// ── Step 3: LSP setup (optional) ──────────────────────────
|
|
180
156
|
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (matchingServers.length > 0) {
|
|
187
|
-
const selected = await multiselect({
|
|
188
|
-
message: "Detected project languages. Install LSP servers for better code intelligence?",
|
|
189
|
-
options: matchingServers.map((srv) => ({
|
|
157
|
+
const selected = await multiselect({
|
|
158
|
+
message: "Install LSP servers for better code intelligence?",
|
|
159
|
+
options: LSP_SERVERS.map((srv) => {
|
|
160
|
+
const installed = isInstalled(srv.server);
|
|
161
|
+
return {
|
|
190
162
|
value: srv,
|
|
191
163
|
label: srv.language,
|
|
192
|
-
hint: srv.server,
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
164
|
+
hint: installed ? `${srv.server} (installed)` : srv.server,
|
|
165
|
+
};
|
|
166
|
+
}),
|
|
167
|
+
required: false,
|
|
168
|
+
});
|
|
196
169
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
170
|
+
if (!isCancel(selected) && selected.length > 0) {
|
|
171
|
+
for (const srv of selected) {
|
|
172
|
+
if (isInstalled(srv.server)) {
|
|
173
|
+
note(`${srv.server} is already installed, skipping.`, srv.language);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const ls = spinner();
|
|
177
|
+
ls.start(`Installing ${srv.server}...`);
|
|
178
|
+
const [cmd, ...args] = srv.installCmd.split(" ");
|
|
179
|
+
const r = run(cmd, args);
|
|
180
|
+
if (r.status !== 0) {
|
|
181
|
+
ls.stop(`Failed to install ${srv.server} — you can install manually: ${srv.installCmd}`);
|
|
182
|
+
} else {
|
|
183
|
+
ls.stop(`${srv.server} installed`);
|
|
208
184
|
}
|
|
209
185
|
}
|
|
210
186
|
}
|
package/package.json
CHANGED
package/src/commands/config.ts
CHANGED
|
@@ -21,7 +21,7 @@ export function registerConfigCommand(pi: ExtensionAPI): void {
|
|
|
21
21
|
`Max fix retries: ${config.orchestration.maxFixRetries}`,
|
|
22
22
|
`Max nesting depth: ${config.orchestration.maxNestingDepth}`,
|
|
23
23
|
`Model preference: ${config.orchestration.modelPreference}`,
|
|
24
|
-
`LSP
|
|
24
|
+
`LSP setup guide: ${config.lsp.setupGuide}`,
|
|
25
25
|
`Notification verbosity: ${config.notifications.verbosity}`,
|
|
26
26
|
`QA framework: ${config.qa.framework ?? "not detected"}`,
|
|
27
27
|
`Release pipeline: ${config.release.pipeline ?? "not configured"}`,
|
package/src/config/defaults.ts
CHANGED
package/src/config/schema.ts
CHANGED
package/src/lsp/detector.ts
CHANGED
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
// src/lsp/detector.ts
|
|
2
|
-
import type
|
|
2
|
+
import { LSP_SERVERS, type LspServerEntry } from "./setup-guide.js";
|
|
3
3
|
|
|
4
|
-
export interface
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface LspServerInfo {
|
|
10
|
-
name: string;
|
|
11
|
-
status: "running" | "stopped" | "error";
|
|
12
|
-
fileTypes: string[];
|
|
13
|
-
error?: string;
|
|
4
|
+
export interface LspServerStatus {
|
|
5
|
+
server: LspServerEntry;
|
|
6
|
+
installed: boolean;
|
|
14
7
|
}
|
|
15
8
|
|
|
16
9
|
/**
|
|
17
|
-
* Check LSP
|
|
18
|
-
* Uses pi.exec to call the lsp tool programmatically.
|
|
10
|
+
* Check which LSP servers are installed by looking for their binaries.
|
|
19
11
|
*/
|
|
20
|
-
export async function
|
|
12
|
+
export async function checkInstalledServers(
|
|
21
13
|
exec: (cmd: string, args: string[]) => Promise<{ stdout: string; exitCode: number }>
|
|
22
|
-
): Promise<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
): Promise<LspServerStatus[]> {
|
|
15
|
+
const results: LspServerStatus[] = [];
|
|
16
|
+
for (const server of LSP_SERVERS) {
|
|
17
|
+
try {
|
|
18
|
+
const result = await exec("which", [server.server]);
|
|
19
|
+
results.push({ server, installed: result.exitCode === 0 });
|
|
20
|
+
} catch {
|
|
21
|
+
results.push({ server, installed: false });
|
|
22
|
+
}
|
|
29
23
|
}
|
|
24
|
+
return results;
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
/**
|
|
33
|
-
* Check if LSP is available from the extension context.
|
|
28
|
+
* Check if LSP is available from the OMP extension context at runtime.
|
|
34
29
|
* Reads the active tools list to see if "lsp" is registered.
|
|
35
30
|
*/
|
|
36
31
|
export function isLspAvailable(activeTools: string[]): boolean {
|
package/src/lsp/setup-guide.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/lsp/setup-guide.ts
|
|
2
2
|
|
|
3
|
-
export interface
|
|
3
|
+
export interface LspServerEntry {
|
|
4
4
|
language: string;
|
|
5
5
|
server: string;
|
|
6
6
|
installCommand: string;
|
|
7
7
|
notes: string;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
export const LSP_SERVERS: LspServerEntry[] = [
|
|
11
11
|
{
|
|
12
12
|
language: "TypeScript/JavaScript",
|
|
13
13
|
server: "typescript-language-server",
|
|
@@ -34,47 +34,16 @@ const COMMON_LSP_SERVERS: SetupInstruction[] = [
|
|
|
34
34
|
},
|
|
35
35
|
];
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
export function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
s.language.toLowerCase().includes(lang.toLowerCase())
|
|
42
|
-
)
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Detect project languages from file extensions */
|
|
47
|
-
export function detectProjectLanguages(files: string[]): string[] {
|
|
48
|
-
const extMap: Record<string, string> = {
|
|
49
|
-
".ts": "typescript",
|
|
50
|
-
".tsx": "typescript",
|
|
51
|
-
".js": "javascript",
|
|
52
|
-
".jsx": "javascript",
|
|
53
|
-
".py": "python",
|
|
54
|
-
".rs": "rust",
|
|
55
|
-
".go": "go",
|
|
56
|
-
".java": "java",
|
|
57
|
-
".rb": "ruby",
|
|
58
|
-
".php": "php",
|
|
59
|
-
};
|
|
60
|
-
const languages = new Set<string>();
|
|
61
|
-
for (const file of files) {
|
|
62
|
-
const ext = file.slice(file.lastIndexOf("."));
|
|
63
|
-
if (extMap[ext]) languages.add(extMap[ext]);
|
|
64
|
-
}
|
|
65
|
-
return [...languages];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** Format setup instructions as readable text */
|
|
69
|
-
export function formatSetupGuide(instructions: SetupInstruction[]): string {
|
|
70
|
-
if (instructions.length === 0) {
|
|
71
|
-
return "No LSP setup instructions available for your project languages.";
|
|
37
|
+
/** Format all LSP servers as readable text */
|
|
38
|
+
export function formatSetupGuide(servers: LspServerEntry[] = LSP_SERVERS): string {
|
|
39
|
+
if (servers.length === 0) {
|
|
40
|
+
return "No LSP servers available.";
|
|
72
41
|
}
|
|
73
42
|
const lines = ["LSP Setup Guide:", ""];
|
|
74
|
-
for (const
|
|
75
|
-
lines.push(`## ${
|
|
76
|
-
lines.push(`Install: ${
|
|
77
|
-
lines.push(`Note: ${
|
|
43
|
+
for (const srv of servers) {
|
|
44
|
+
lines.push(`## ${srv.language} — ${srv.server}`);
|
|
45
|
+
lines.push(`Install: ${srv.installCommand}`);
|
|
46
|
+
lines.push(`Note: ${srv.notes}`);
|
|
78
47
|
lines.push("");
|
|
79
48
|
}
|
|
80
49
|
return lines.join("\n");
|