@xevy/cli 0.1.7 → 0.1.8

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 (3) hide show
  1. package/README.md +34 -10
  2. package/bin/xevy.mjs +98 -33
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -45,7 +45,8 @@ This walks you through everything:
45
45
 
46
46
  1. Installs the **pi agent** if it isn't already on your PATH.
47
47
  2. Installs the Xevy extensions (see [`xevy setup`](#xevy-setup) for details).
48
- 3. Asks for your **API key**. When prompted, open the link it prints it takes you
48
+ 3. Installs the Xevy **SDLC skills** for Claude Code / Cursor / Codex (via `@xevy/skills`).
49
+ 4. Asks for your **API key**. When prompted, open the link it prints — it takes you
49
50
  straight to **Settings → Profile → API keys** at
50
51
  <https://xevy.ai/settings?section=profile&tab=api> — click **Create key**, copy the
51
52
  key, and paste it back into the terminal. Your key is saved to
@@ -62,6 +63,15 @@ That's it — you're set up. The sections below are reference for when you need
62
63
 
63
64
  ## Upgrading
64
65
 
66
+ Keep the Xevy extensions and SDLC skills current (run after Xevy releases):
67
+
68
+ ```bash
69
+ xevy check # is a newer skills version available?
70
+ xevy update # refresh the pi extensions + the SDLC skills
71
+ ```
72
+
73
+ To upgrade the CLI binary itself:
74
+
65
75
  ```bash
66
76
  npm update -g @xevy/cli # or re-run: npm install -g @xevy/cli
67
77
  ```
@@ -77,10 +87,24 @@ npm update -g @xevy/cli # or re-run: npm install -g @xevy/cli
77
87
  3. Asks for your **API key** (reuses an already-saved one if present) and prints a
78
88
  **direct link to the API-keys tab** to generate one, then stores it in
79
89
  `~/.config/xevy/credentials` (mode `600`, never printed).
90
+ 4. Installs the Xevy **SDLC skills** into `.claude/skills`, `.cursor/skills`, etc.
91
+ (delegates to `@xevy/skills` — skills only; the MCP tools for pi are already
92
+ wired through the extensions above). A skills hiccup only warns; it never aborts
93
+ the setup that already succeeded.
80
94
 
81
95
  The API-keys link opens **Settings → Profile → API keys** directly:
82
96
  `https://xevy.ai/settings?section=profile&tab=api`.
83
97
 
98
+ ## `xevy update` / `xevy check`
99
+
100
+ ```bash
101
+ xevy update # re-download the pi extensions + update the SDLC skills
102
+ xevy check # report whether newer SDLC skills are available (exit 2 = update available)
103
+ ```
104
+
105
+ `update` refreshes the extensions from the server and the skills via `@xevy/skills`;
106
+ your saved API key is left untouched. Both accept `--base <url>` for self-hosted hosts.
107
+
84
108
  ## `xevy`
85
109
 
86
110
  Opens pi, loading `~/.xevy/extensions` via `pi -e …` (pi also auto-loads the
@@ -101,18 +125,18 @@ xevy "summarise this repo" # forwards the prompt to pi
101
125
 
102
126
  ## Skills & MCP for other agents
103
127
 
104
- `@xevy/cli` sets up the [pi](https://github.com/badlogic/pi-mono) agent. If you'd
105
- rather use **Cursor, Claude Code, or one of [50+ other agents](https://github.com/vercel-labs/skills#supported-agents)**,
106
- install the Xevy **SDLC skills** and the **Xevy MCP server** with the sibling
107
- package instead:
128
+ `xevy setup` already installs the Xevy **SDLC skills** for **Cursor, Claude Code, and
129
+ [50+ other agents](https://github.com/vercel-labs/skills#supported-agents)**. To also
130
+ register the **Xevy MCP server** in those clients (pi gets it via the extensions), add
131
+ it over OAuth (Cursor: Settings → MCP → `xevy`; Claude Code: browser sign-in on first
132
+ use) or run the sibling package's MCP step:
108
133
 
109
134
  ```bash
110
- npx @xevy/skills # skills + MCP, global by default
111
- npx @xevy/skills --project # into the current repo instead
135
+ npx @xevy/skills mcp # register the Xevy MCP server, global by default
136
+ npx @xevy/skills # or: skills + MCP together
112
137
  ```
113
138
 
114
- Then connect MCP over OAuth (Cursor: Settings MCP `xevy`; Claude Code: browser
115
- sign-in on first use). See the [`@xevy/skills` README](../xevy-skills/README.md) for
116
- the full command list, per-agent flags, and manual install steps.
139
+ See the [`@xevy/skills` README](../xevy-skills/README.md) for the full command list,
140
+ per-agent flags, and manual install steps.
117
141
 
118
142
  Docs: <https://xevy.ai/docs/mcp>
package/bin/xevy.mjs CHANGED
@@ -4,7 +4,10 @@
4
4
  *
5
5
  * xevy setup Install the pi agent (if missing); install the Xevy extensions
6
6
  * (core + model + MCP globally, xevy.ts into ~/.xevy/extensions);
7
- * and store your API key.
7
+ * install the Xevy SDLC skills (via @xevy/skills); and store your
8
+ * API key.
9
+ * xevy update Refresh the pi extensions + the Xevy SDLC skills.
10
+ * xevy check Report whether newer Xevy SDLC skills are available.
8
11
  * xevy Open pi with the Xevy extensions.
9
12
  *
10
13
  * `xevy setup` fetches the extensions from the server and asks for an API key
@@ -67,7 +70,9 @@ function usage() {
67
70
  console.log(`Xevy CLI
68
71
 
69
72
  xevy Open pi with the Xevy extensions in ~/.xevy/extensions
70
- xevy setup [--base u] Install pi (if missing) + the Xevy extensions, store your API key
73
+ xevy setup [--base u] Install pi (if missing) + the Xevy extensions + SDLC skills, store your API key
74
+ xevy update [--base u] Refresh the pi extensions + the Xevy SDLC skills
75
+ xevy check [--base u] Report whether newer Xevy SDLC skills are available
71
76
 
72
77
  Options:
73
78
  --base <url> Xevy host (default: XEVY_BASE or ${DEFAULT_BASE})
@@ -76,6 +81,7 @@ Options:
76
81
 
77
82
  Examples:
78
83
  npx @xevy/cli setup
84
+ npx @xevy/cli update
79
85
  npx @xevy/cli
80
86
 
81
87
  Install globally to drop the npx prefix:
@@ -94,9 +100,9 @@ function parseArgv(argv) {
94
100
  if (first === "-h" || first === "--help" || first === "help") return { command: "help", base };
95
101
  if (first === "-v" || first === "--version") return { command: "version", base };
96
102
 
97
- if (first === "setup") {
98
- args.shift();
99
- const opts = { command: "setup", base, piArgs: [] };
103
+ if (first === "setup" || first === "update" || first === "check") {
104
+ const command = args.shift();
105
+ const opts = { command, base, piArgs: [] };
100
106
  while (args.length > 0) {
101
107
  const a = args.shift();
102
108
  if (a === "--base") {
@@ -105,7 +111,7 @@ function parseArgv(argv) {
105
111
  opts.base = v.replace(/\/$/, "");
106
112
  continue;
107
113
  }
108
- die(`Unknown option for \`xevy setup\`: ${a}. Try \`xevy --help\`.`);
114
+ die(`Unknown option for \`xevy ${command}\`: ${a}. Try \`xevy --help\`.`);
109
115
  }
110
116
  return opts;
111
117
  }
@@ -141,6 +147,26 @@ function ensurePi() {
141
147
  }
142
148
  }
143
149
 
150
+ // Install the Xevy SDLC skills (into .claude/skills, .cursor/skills, etc.) via
151
+ // the published @xevy/skills package. Skills only — the pi tools + MCP are
152
+ // already wired through the extensions above and the stored credentials, so we
153
+ // skip add-mcp here. Non-fatal: the core pi setup has already succeeded, so a
154
+ // skills hiccup warns with the manual command instead of aborting.
155
+ function installSkills(base) {
156
+ const args = ["--yes", "@xevy/skills", "skills", "-y"];
157
+ if (base !== DEFAULT_BASE) args.push("--base", base);
158
+ const label = "npx @xevy/skills skills (Xevy SDLC skills)";
159
+ console.log(`→ ${label}`);
160
+ const command = isWindows ? "npx.cmd" : "npx";
161
+ const r = spawnSync(command, args, { stdio: "inherit", shell: isWindows, env: process.env });
162
+ if (r.error || r.status !== 0) {
163
+ console.warn(`⚠ Could not install Xevy skills (${r.error ? r.error.message : `exit ${r.status}`}).`);
164
+ console.warn(" Install them later with: npx @xevy/skills skills -y");
165
+ return false;
166
+ }
167
+ return true;
168
+ }
169
+
144
170
  async function downloadExtension(base, file, destDir, markers) {
145
171
  const url = `${base}/${file}`;
146
172
  console.log(`→ Downloading ${url}`);
@@ -232,39 +258,33 @@ async function promptNewApiKey(base) {
232
258
  return token;
233
259
  }
234
260
 
261
+ // Download all four Xevy pi extensions to their install dirs. Shared by `setup`
262
+ // and `update` so the two never drift.
263
+ // • xevy-core.ts → pi's GLOBAL extensions dir (shared base: ask_question
264
+ // tool + setup/context). Global so it loads in EVERY pi session and is
265
+ // always present for xevy.ts (which requires it). Global-only avoids a
266
+ // double-load: if it were also in ~/.xevy it'd register ask_question twice.
267
+ // • xevy-model.ts → GLOBAL too, so the xevy/* models are available in every
268
+ // pi session (plain `pi` included), not just via `xevy`.
269
+ // • xevy-mcp.ts → GLOBAL too — the MCP→pi tool bridge (auth reused from
270
+ // the model login), available in every pi session.
271
+ // • xevy.ts → ~/.xevy/extensions (tools/workflow; loaded by `xevy`,
272
+ // which also auto-loads the global dir → core + model + MCP come along).
273
+ async function downloadAllExtensions(base) {
274
+ await downloadExtension(base, "xevy-core.ts", PI_EXTENSION_DIR, ["xevyCoreExtension", "registerCommand"]);
275
+ await downloadExtension(base, "xevy-model.ts", PI_EXTENSION_DIR, ["xevyModelExtension", "registerCommand"]);
276
+ await downloadExtension(base, "xevy-mcp.ts", PI_EXTENSION_DIR, ["xevyMcpExtension", "registerCommand"]);
277
+ await downloadExtension(base, XEVY_EXTENSION_FILE, XEVY_EXTENSIONS_DIR, ["EXTENSION_VERSION", "registerCommand"]);
278
+ }
279
+
235
280
  async function setup(opts) {
236
281
  console.log("Setting up Xevy for pi\n");
237
282
 
238
283
  // 1. Ensure pi is installed (installs it if missing).
239
284
  ensurePi();
240
285
 
241
- // 2. Extensions:
242
- // • xevy-core.ts → pi's GLOBAL extensions dir (shared base: ask_question
243
- // tool + setup/context). Global so it loads in EVERY pi session and is
244
- // always present for xevy.ts (which requires it). Global-only avoids a
245
- // double-load: if it were also in ~/.xevy it'd register ask_question twice.
246
- // • xevy-model.ts → GLOBAL too, so the xevy/* models are available in every
247
- // pi session (plain `pi` included), not just via `xevy`.
248
- // • xevy-mcp.ts → GLOBAL too — the MCP→pi tool bridge (auth reused from
249
- // the model login), available in every pi session.
250
- // • xevy.ts → ~/.xevy/extensions (tools/workflow; loaded by `xevy`,
251
- // which also auto-loads the global dir → core + model + MCP come along).
252
- await downloadExtension(opts.base, "xevy-core.ts", PI_EXTENSION_DIR, [
253
- "xevyCoreExtension",
254
- "registerCommand",
255
- ]);
256
- await downloadExtension(opts.base, "xevy-model.ts", PI_EXTENSION_DIR, [
257
- "xevyModelExtension",
258
- "registerCommand",
259
- ]);
260
- await downloadExtension(opts.base, "xevy-mcp.ts", PI_EXTENSION_DIR, [
261
- "xevyMcpExtension",
262
- "registerCommand",
263
- ]);
264
- await downloadExtension(opts.base, XEVY_EXTENSION_FILE, XEVY_EXTENSIONS_DIR, [
265
- "EXTENSION_VERSION",
266
- "registerCommand",
267
- ]);
286
+ // 2. Extensions (core + model + MCP globally, xevy.ts into ~/.xevy).
287
+ await downloadAllExtensions(opts.base);
268
288
 
269
289
  // 3. API key — reuse the saved one if present, otherwise ask for a new one.
270
290
  const existing = readStoredToken();
@@ -279,12 +299,55 @@ async function setup(opts) {
279
299
  writeCredentials(opts.base, token);
280
300
  console.log(`✓ API key stored at ${CREDENTIALS_FILE} (key not shown).`);
281
301
 
302
+ // 4. SDLC skills — install the Xevy agent skills so Claude Code / Cursor /
303
+ // Codex pick them up alongside pi.
304
+ const skillsOk = installSkills(opts.base);
305
+
282
306
  console.log("\n✓ Setup complete.");
283
307
  console.log(" • Xevy models (xevy/auto, xevy/fast, …) + MCP tools are available in any pi session — no /login needed.");
308
+ console.log(
309
+ skillsOk
310
+ ? " • Xevy SDLC skills installed for Claude Code / Cursor / Codex — refresh later with `xevy update`."
311
+ : " • Xevy SDLC skills NOT installed — run `xevy update` to add them.",
312
+ );
284
313
  console.log(" • Run `xevy` to open pi with the Xevy tools + models loaded.");
314
+ console.log(" • Keep current with `xevy check` / `xevy update`.");
315
+ if (opts.base !== DEFAULT_BASE) console.log(` • Host: ${opts.base}`);
316
+ }
317
+
318
+ // `xevy update` — refresh the pi extensions from the server AND update the SDLC
319
+ // skills. This is the "update everything the CLI installed" command. Skills are
320
+ // delegated to @xevy/skills (the source of truth); the API key is left as-is.
321
+ async function update(opts) {
322
+ console.log("Updating Xevy\n");
323
+
324
+ // 1. Re-download the pi extensions (they carry the date-stamped versions).
325
+ await downloadAllExtensions(opts.base);
326
+
327
+ // 2. Skills via @xevy/skills (single source of truth for SDLC skills).
328
+ const skillsOk = installSkills(opts.base);
329
+
330
+ console.log("\n✓ Update complete.");
331
+ console.log(" • Xevy pi extensions refreshed.");
332
+ console.log(
333
+ skillsOk
334
+ ? " • Xevy SDLC skills updated."
335
+ : " • Xevy SDLC skills NOT updated — run `npx @xevy/skills update -y` manually.",
336
+ );
285
337
  if (opts.base !== DEFAULT_BASE) console.log(` • Host: ${opts.base}`);
286
338
  }
287
339
 
340
+ // `xevy check` — is a newer SDLC-skills version available? Delegates to the
341
+ // @xevy/skills version check (which reads the install stamp + npm/manifest).
342
+ function check(opts) {
343
+ const args = ["--yes", "@xevy/skills", "check"];
344
+ if (opts.base !== DEFAULT_BASE) args.push("--base", opts.base);
345
+ const command = isWindows ? "npx.cmd" : "npx";
346
+ const r = spawnSync(command, args, { stdio: "inherit", shell: isWindows, env: process.env });
347
+ // Preserve @xevy/skills' exit code (0 = current, 2 = update available, …).
348
+ process.exit(r.status ?? (r.error ? 1 : 0));
349
+ }
350
+
288
351
  function open(opts) {
289
352
  if (!hasPi()) {
290
353
  die("pi is not installed. Run `xevy setup` first.");
@@ -315,6 +378,8 @@ async function main() {
315
378
  if (opts.command === "help") return usage();
316
379
  if (opts.command === "version") return console.log(readCliVersion());
317
380
  if (opts.command === "setup") return setup(opts);
381
+ if (opts.command === "update") return update(opts);
382
+ if (opts.command === "check") return check(opts);
318
383
  if (opts.command === "open") return open(opts);
319
384
  }
320
385
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xevy/cli",
3
- "version": "0.1.7",
4
- "description": "Xevy CLI — `xevy setup` installs the pi agent + the Xevy pi extension and stores your API key; `xevy` opens pi with it.",
3
+ "version": "0.1.8",
4
+ "description": "Xevy CLI — `xevy setup` installs the pi agent, the Xevy pi extensions, and the SDLC skills, and stores your API key; `xevy update`/`xevy check` keep them current; `xevy` opens pi with it.",
5
5
  "type": "module",
6
6
  "keywords": [
7
7
  "xevy",