supipowers 0.1.3 → 0.2.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/bin/install.mjs +49 -30
- package/package.json +1 -1
package/bin/install.mjs
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
intro,
|
|
5
5
|
outro,
|
|
6
6
|
confirm,
|
|
7
|
-
select,
|
|
8
7
|
multiselect,
|
|
9
8
|
spinner,
|
|
10
9
|
isCancel,
|
|
@@ -12,7 +11,7 @@ import {
|
|
|
12
11
|
note,
|
|
13
12
|
} from "@clack/prompts";
|
|
14
13
|
import { spawnSync } from "node:child_process";
|
|
15
|
-
import { readFileSync, existsSync } from "node:fs";
|
|
14
|
+
import { readFileSync, existsSync, mkdirSync, cpSync, readdirSync } from "node:fs";
|
|
16
15
|
import { resolve, dirname, join } from "node:path";
|
|
17
16
|
import { fileURLToPath } from "node:url";
|
|
18
17
|
import { homedir } from "node:os";
|
|
@@ -91,9 +90,12 @@ async function main() {
|
|
|
91
90
|
|
|
92
91
|
// ── Step 1: OMP check ──────────────────────────────────────
|
|
93
92
|
|
|
93
|
+
const ompSpinner = spinner();
|
|
94
|
+
ompSpinner.start("Looking for OMP...");
|
|
94
95
|
let omp = findOmpBinary();
|
|
95
96
|
|
|
96
97
|
if (!omp) {
|
|
98
|
+
ompSpinner.stop("OMP not found");
|
|
97
99
|
note(
|
|
98
100
|
"OMP (oh-my-pi) is an AI coding agent that supipowers extends.\n" +
|
|
99
101
|
"It adds sub-agents, LSP integration, and plugin support to pi.\n" +
|
|
@@ -125,45 +127,62 @@ async function main() {
|
|
|
125
127
|
} else {
|
|
126
128
|
const version = run(omp, ["--version"]);
|
|
127
129
|
const ver = version.stdout?.trim() || "unknown";
|
|
128
|
-
|
|
130
|
+
ompSpinner.stop(`OMP ${ver} detected`);
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
// ── Step 2: Install supipowers
|
|
132
|
-
|
|
133
|
-
const scope = await select({
|
|
134
|
-
message: "Where should supipowers be installed?",
|
|
135
|
-
options: [
|
|
136
|
-
{ value: "global", label: "Global", hint: "available in all projects" },
|
|
137
|
-
{ value: "local", label: "Project-local", hint: "only this directory" },
|
|
138
|
-
],
|
|
139
|
-
});
|
|
140
|
-
if (isCancel(scope)) bail("Cancelled.");
|
|
141
|
-
|
|
142
|
-
const packageSpec = `npm:supipowers@${VERSION}`;
|
|
143
|
-
const installArgs = ["install", packageSpec];
|
|
144
|
-
if (scope === "local") installArgs.push("-l");
|
|
133
|
+
// ── Step 2: Install supipowers into ~/.omp/agent/ ───────────
|
|
145
134
|
|
|
146
135
|
const s = spinner();
|
|
147
|
-
s.start(
|
|
148
|
-
|
|
149
|
-
|
|
136
|
+
s.start("Installing supipowers...");
|
|
137
|
+
|
|
138
|
+
const packageRoot = resolve(__dirname, "..");
|
|
139
|
+
const ompAgent = join(homedir(), ".omp", "agent");
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
// Copy extension (src/ + package.json) → ~/.omp/agent/extensions/supipowers/
|
|
143
|
+
const extDir = join(ompAgent, "extensions", "supipowers");
|
|
144
|
+
mkdirSync(extDir, { recursive: true });
|
|
145
|
+
cpSync(join(packageRoot, "src"), join(extDir, "src"), { recursive: true });
|
|
146
|
+
cpSync(join(packageRoot, "package.json"), join(extDir, "package.json"));
|
|
147
|
+
|
|
148
|
+
// Copy skills → ~/.omp/agent/skills/<skillname>/SKILL.md
|
|
149
|
+
const skillsSource = join(packageRoot, "skills");
|
|
150
|
+
if (existsSync(skillsSource)) {
|
|
151
|
+
const skillDirs = readdirSync(skillsSource, { withFileTypes: true });
|
|
152
|
+
for (const entry of skillDirs) {
|
|
153
|
+
if (!entry.isDirectory()) continue;
|
|
154
|
+
const skillFile = join(skillsSource, entry.name, "SKILL.md");
|
|
155
|
+
if (!existsSync(skillFile)) continue;
|
|
156
|
+
const destDir = join(ompAgent, "skills", entry.name);
|
|
157
|
+
mkdirSync(destDir, { recursive: true });
|
|
158
|
+
cpSync(skillFile, join(destDir, "SKILL.md"));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
s.stop("supipowers installed");
|
|
163
|
+
} catch (err) {
|
|
150
164
|
s.stop("Installation failed");
|
|
151
|
-
bail(
|
|
165
|
+
bail(err.message || "Failed to copy files to ~/.omp/agent/");
|
|
152
166
|
}
|
|
153
|
-
s.stop("supipowers installed");
|
|
154
167
|
|
|
155
168
|
// ── Step 3: LSP setup (optional) ──────────────────────────
|
|
156
169
|
|
|
170
|
+
const lspSpinner = spinner();
|
|
171
|
+
lspSpinner.start("Checking installed LSP servers...");
|
|
172
|
+
const lspOptions = LSP_SERVERS.map((srv) => {
|
|
173
|
+
const installed = isInstalled(srv.server);
|
|
174
|
+
return {
|
|
175
|
+
value: srv,
|
|
176
|
+
label: srv.language,
|
|
177
|
+
hint: installed ? `${srv.server} (installed)` : srv.server,
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
const installedCount = lspOptions.filter((o) => o.hint.includes("(installed)")).length;
|
|
181
|
+
lspSpinner.stop(`Found ${installedCount}/${LSP_SERVERS.length} LSP servers installed`);
|
|
182
|
+
|
|
157
183
|
const selected = await multiselect({
|
|
158
184
|
message: "Install LSP servers for better code intelligence?",
|
|
159
|
-
options:
|
|
160
|
-
const installed = isInstalled(srv.server);
|
|
161
|
-
return {
|
|
162
|
-
value: srv,
|
|
163
|
-
label: srv.language,
|
|
164
|
-
hint: installed ? `${srv.server} (installed)` : srv.server,
|
|
165
|
-
};
|
|
166
|
-
}),
|
|
185
|
+
options: lspOptions,
|
|
167
186
|
required: false,
|
|
168
187
|
});
|
|
169
188
|
|