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.
Files changed (2) hide show
  1. package/bin/install.mjs +49 -30
  2. 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
- note(`OMP ${ver}`, "OMP detected");
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(`Installing supipowers (${scope})...`);
148
- const result = run(omp, installArgs);
149
- if (result.status !== 0) {
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(result.stderr?.trim() || "omp install failed.");
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: LSP_SERVERS.map((srv) => {
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "supipowers",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "OMP-native workflow extension inspired by Superpowers.",
5
5
  "type": "module",
6
6
  "scripts": {