@rrskill/cli 0.1.1 → 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/dist/index.js CHANGED
@@ -1,30 +1,30 @@
1
- import * as c from "node:path";
1
+ import * as l from "node:path";
2
2
  import * as u from "node:fs/promises";
3
- import { fileURLToPath as x, pathToFileURL as ht } from "node:url";
4
- import { readFileSync as mt } from "node:fs";
5
- import { createHash as gt } from "node:crypto";
6
- import * as G from "node:os";
7
- import * as kt from "node:zlib";
8
- import { promisify as wt } from "node:util";
9
- const V = ["search", "install", "list", "upgrade", "bootstrap", "doctor", "version"], Z = new Set(V), yt = "--host", vt = "--output", St = /* @__PURE__ */ new Set([yt, vt]), Dt = /* @__PURE__ */ new Set(["--openclaw", "--codex", "--claude-code"]);
10
- function Q(t) {
3
+ import { fileURLToPath as _, pathToFileURL as kt } from "node:url";
4
+ import { readFileSync as wt } from "node:fs";
5
+ import { createHash as yt } from "node:crypto";
6
+ import * as Z from "node:os";
7
+ import * as vt from "node:zlib";
8
+ import { promisify as St } from "node:util";
9
+ const Q = ["search", "install", "list", "upgrade", "bootstrap", "doctor", "version"], X = new Set(Q), Dt = "--host", xt = "--output", jt = /* @__PURE__ */ new Set([Dt, xt]), Ct = /* @__PURE__ */ new Set(["--openclaw", "--codex", "--claude-code"]);
10
+ function Y(t) {
11
11
  const s = [];
12
12
  for (let e = 0; e < t.length; e += 1) {
13
13
  const r = t[e];
14
14
  if (r) {
15
- if (St.has(r)) {
15
+ if (jt.has(r)) {
16
16
  const i = t[e + 1];
17
- i && !i.startsWith("--") && !Z.has(i) && (e += 1);
17
+ i && !i.startsWith("--") && !X.has(i) && (e += 1);
18
18
  continue;
19
19
  }
20
- Dt.has(r) || r.startsWith("--") || s.push(r);
20
+ Ct.has(r) || r.startsWith("--") || s.push(r);
21
21
  }
22
22
  }
23
23
  return s;
24
24
  }
25
25
  function Et(t) {
26
- const s = Q(t)[0] ?? "";
27
- return s ? Z.has(s) ? { command: s } : { command: "install", slug: s } : { command: "help" };
26
+ const s = Y(t), e = s[0] ?? "";
27
+ return e ? e === "help" ? { command: "help" } : X.has(e) ? { command: e } : s.length === 1 ? { command: "install", slug: e } : { command: "unknown", input: e } : { command: "help" };
28
28
  }
29
29
  async function b(t) {
30
30
  const s = t.fsImpl ?? u;
@@ -34,7 +34,7 @@ async function b(t) {
34
34
  return !1;
35
35
  }
36
36
  }
37
- async function Ct(t) {
37
+ async function _t(t) {
38
38
  const s = t.fsImpl ?? u;
39
39
  let e;
40
40
  try {
@@ -55,7 +55,7 @@ async function Ct(t) {
55
55
  };
56
56
  }
57
57
  }
58
- function z(t, s) {
58
+ function J(t, s) {
59
59
  let e = t;
60
60
  for (const r of s) {
61
61
  if (!e || typeof e != "object")
@@ -64,50 +64,49 @@ function z(t, s) {
64
64
  }
65
65
  return e;
66
66
  }
67
- async function X(t, s = {}) {
67
+ async function tt(t, s = {}) {
68
68
  const e = s.fs ?? u, r = [], i = ["find-skills", "rrskill-preference"];
69
- for (const d of i) {
70
- const f = c.join(t.skillsDir, d, "SKILL.md");
71
- await b({ fsImpl: e, path: f }) || r.push({ code: "missing_builtin_skill", slug: d, path: f });
69
+ for (const f of i) {
70
+ const d = l.join(t.skillsDir, f, "SKILL.md");
71
+ await b({ fsImpl: e, path: d }) || r.push({ code: "missing_builtin_skill", slug: f, path: d });
72
72
  }
73
73
  if (t.host !== "openclaw")
74
74
  return r.push({ code: "unsupported_host_bootstrap", host: t.host }), { ok: !1, issues: r };
75
- const o = c.join(t.pluginDir, "index.ts"), n = c.join(t.pluginDir, "openclaw.plugin.json");
75
+ const o = l.join(t.pluginDir, "index.ts"), n = l.join(t.pluginDir, "openclaw.plugin.json");
76
76
  await b({ fsImpl: e, path: o }) || r.push({ code: "missing_plugin_file", path: o }), await b({ fsImpl: e, path: n }) || r.push({ code: "missing_plugin_file", path: n });
77
- const l = await Ct({ fsImpl: e, path: t.hostConfigPath });
78
- if (!l.ok)
79
- return r.push(l.issue), { ok: !1, issues: r };
80
- const a = z(l.value, ["plugins", "entries", "rrskill"]);
77
+ const c = await _t({ fsImpl: e, path: t.hostConfigPath });
78
+ if (!c.ok)
79
+ return r.push(c.issue), { ok: !1, issues: r };
80
+ const a = J(c.value, ["plugins", "entries", "rrskill"]);
81
81
  if (!a || typeof a != "object")
82
82
  r.push({ code: "missing_host_plugin_entry", path: t.hostConfigPath });
83
83
  else {
84
- const d = [
84
+ const f = [
85
85
  { key: ["plugins", "entries", "rrskill", "enabled"], expected: !0 },
86
86
  { key: ["plugins", "entries", "rrskill", "config", "primaryCli"], expected: "rrskill" },
87
87
  { key: ["plugins", "entries", "rrskill", "config", "primaryLabel"], expected: "official-registry" }
88
88
  ];
89
- for (const f of d) {
90
- const m = z(l.value, f.key);
91
- m !== f.expected && r.push({
89
+ for (const d of f) {
90
+ const h = J(c.value, d.key);
91
+ h !== d.expected && r.push({
92
92
  code: "host_plugin_policy_mismatch",
93
93
  path: t.hostConfigPath,
94
- key: f.key.join("."),
95
- expected: f.expected,
96
- actual: m
94
+ key: d.key.join("."),
95
+ expected: d.expected,
96
+ actual: h
97
97
  });
98
98
  }
99
99
  }
100
100
  return { ok: r.length === 0, issues: r };
101
101
  }
102
- function P(t, s) {
103
- const e = c.dirname(x(t));
102
+ function O(t, s) {
103
+ const e = l.dirname(_(t));
104
104
  return [
105
- c.resolve(e, "..", "builtins", s),
106
- c.resolve(e, "..", "src", "builtins", s),
107
- c.resolve(e, "..", "..", "src", "builtins", s)
105
+ l.resolve(e, "..", "assets", "builtins", s),
106
+ l.resolve(e, "..", "..", "assets", "builtins", s)
108
107
  ];
109
108
  }
110
- async function U(t) {
109
+ async function P(t) {
111
110
  const s = t.fsImpl ?? u;
112
111
  let e;
113
112
  for (const r of t.candidates)
@@ -118,7 +117,7 @@ async function U(t) {
118
117
  }
119
118
  throw new Error(`Failed to load ${t.assetLabel} from candidates: ${t.candidates.join(", ")} (${String(e)})`);
120
119
  }
121
- async function $(t) {
120
+ async function U(t) {
122
121
  const s = t.fsImpl ?? u, e = t.content.endsWith(`
123
122
  `) ? t.content : `${t.content}
124
123
  `;
@@ -127,57 +126,57 @@ async function $(t) {
127
126
  return !1;
128
127
  } catch {
129
128
  }
130
- return await s.mkdir(c.dirname(t.path), { recursive: !0 }), await s.writeFile(t.path, e, "utf8"), !0;
129
+ return await s.mkdir(l.dirname(t.path), { recursive: !0 }), await s.writeFile(t.path, e, "utf8"), !0;
131
130
  }
132
- const J = ["find-skills", "rrskill-preference"];
133
- function _t(t) {
131
+ const B = ["find-skills", "rrskill-preference"];
132
+ function Lt(t) {
134
133
  return t === "find-skills" ? "skills/find-skills.md" : "skills/rrskill-preference.md";
135
134
  }
136
- async function Lt(t, s = {}) {
135
+ async function bt(t, s = {}) {
137
136
  const e = s.fs ?? u;
138
137
  let r = !1;
139
- for (const i of J) {
140
- const o = await U({
141
- candidates: P(import.meta.url, _t(i)),
138
+ for (const i of B) {
139
+ const o = await P({
140
+ candidates: O(import.meta.url, Lt(i)),
142
141
  fsImpl: e,
143
142
  assetLabel: "built-in skill asset"
144
- }), n = c.join(t.skillsDir, i, "SKILL.md"), l = await $({ path: n, content: o, fsImpl: e });
145
- r = r || l;
143
+ }), n = l.join(t.skillsDir, i, "SKILL.md"), c = await U({ path: n, content: o, fsImpl: e });
144
+ r = r || c;
146
145
  }
147
- return { installed: [...J], changed: r };
146
+ return { installed: [...B], changed: r };
148
147
  }
149
- async function xt(t, s = {}) {
148
+ async function $t(t, s = {}) {
150
149
  const e = s.fs ?? u;
151
150
  if (t.host !== "openclaw")
152
151
  return { installed: !1, changed: !1 };
153
- const r = await U({
154
- candidates: P(import.meta.url, "plugins/openclaw/index.ts"),
152
+ const r = await P({
153
+ candidates: O(import.meta.url, "plugins/openclaw/index.ts"),
155
154
  fsImpl: e,
156
155
  assetLabel: "built-in plugin asset"
157
- }), i = await U({
158
- candidates: P(import.meta.url, "plugins/openclaw/openclaw.plugin.json"),
156
+ }), i = await P({
157
+ candidates: O(import.meta.url, "plugins/openclaw/openclaw.plugin.json"),
159
158
  fsImpl: e,
160
159
  assetLabel: "built-in plugin asset"
161
- }), o = c.join(t.pluginDir, "index.ts"), n = c.join(t.pluginDir, "openclaw.plugin.json"), l = await $({ path: o, content: r, fsImpl: e }), a = await $({ path: n, content: i, fsImpl: e });
162
- return { installed: !0, changed: l || a };
160
+ }), o = l.join(t.pluginDir, "index.ts"), n = l.join(t.pluginDir, "openclaw.plugin.json"), c = await U({ path: o, content: r, fsImpl: e }), a = await U({ path: n, content: i, fsImpl: e });
161
+ return { installed: !0, changed: c || a };
163
162
  }
164
- function Y(t) {
163
+ function st(t) {
165
164
  return !!t && typeof t == "object" && !Array.isArray(t);
166
165
  }
167
- function E(t, s) {
166
+ function x(t, s) {
168
167
  const e = t[s];
169
- if (Y(e))
168
+ if (st(e))
170
169
  return e;
171
170
  const r = {};
172
171
  return t[s] = r, r;
173
172
  }
174
- async function jt(t) {
173
+ async function It(t) {
175
174
  const s = t.fsImpl ?? u;
176
175
  try {
177
176
  const e = await s.readFile(t.path, "utf8");
178
177
  try {
179
178
  const r = JSON.parse(e);
180
- return Y(r) ? { object: r, exists: !0, parseOk: !0, rawText: e } : { object: {}, exists: !0, parseOk: !1, rawText: e, parseError: "root is not a JSON object" };
179
+ return st(r) ? { object: r, exists: !0, parseOk: !0, rawText: e } : { object: {}, exists: !0, parseOk: !1, rawText: e, parseError: "root is not a JSON object" };
181
180
  } catch (r) {
182
181
  return {
183
182
  object: {},
@@ -191,37 +190,47 @@ async function jt(t) {
191
190
  return { object: {}, exists: !1, parseOk: !1 };
192
191
  }
193
192
  }
194
- async function bt(t) {
193
+ async function Ot(t) {
195
194
  const s = t.fsImpl ?? u, e = `${JSON.stringify(t.value, null, 2)}
196
195
  `;
197
- return t.prevRawText !== void 0 && t.prevRawText === e ? !1 : (await s.mkdir(c.dirname(t.path), { recursive: !0 }), await s.writeFile(t.path, e, "utf8"), !0);
196
+ return t.prevRawText !== void 0 && t.prevRawText === e ? !1 : (await s.mkdir(l.dirname(t.path), { recursive: !0 }), await s.writeFile(t.path, e, "utf8"), !0);
198
197
  }
199
- async function Ot(t) {
200
- const s = t.fsImpl ?? u, e = await jt({ fsImpl: s, path: t.hostConfigPath });
198
+ async function Pt(t) {
199
+ const s = t.fsImpl ?? u, e = await It({ fsImpl: s, path: t.hostConfigPath });
201
200
  if (e.exists && !e.parseOk)
202
201
  throw new Error(
203
202
  `Invalid OpenClaw config JSON at ${t.hostConfigPath}: ${e.parseError ?? "unknown parse error"}`
204
203
  );
205
- const r = e.object, i = E(r, "plugins"), o = E(i, "entries"), n = E(o, "rrskill"), l = E(n, "config");
204
+ const r = e.object, i = x(r, "plugins"), o = x(i, "entries"), n = x(o, "rrskill"), c = x(n, "config");
206
205
  let a = !e.exists || !e.parseOk;
207
- return n.enabled !== !0 && (n.enabled = !0, a = !0), l.primaryCli !== "rrskill" && (l.primaryCli = "rrskill", a = !0), l.primaryLabel !== "official-registry" && (l.primaryLabel = "official-registry", a = !0), a ? bt({
206
+ return n.enabled !== !0 && (n.enabled = !0, a = !0), c.primaryCli !== "rrskill" && (c.primaryCli = "rrskill", a = !0), c.primaryLabel !== "official-registry" && (c.primaryLabel = "official-registry", a = !0), a ? Ot({
208
207
  fsImpl: s,
209
208
  path: t.hostConfigPath,
210
209
  value: r,
211
210
  prevRawText: e.rawText
212
211
  }) : !1;
213
212
  }
214
- async function It(t, s = {}) {
215
- const e = s.fs ?? u, r = await Lt({ skillsDir: t.skillsDir }, { fs: e }), i = await xt({ host: t.host, pluginDir: t.pluginDir }, { fs: e });
213
+ async function Ut(t, s = {}) {
214
+ const e = s.fs ?? u, r = await bt({ skillsDir: t.skillsDir }, { fs: e }), i = await $t({ host: t.host, pluginDir: t.pluginDir }, { fs: e });
216
215
  let o = !1;
217
- return t.host === "openclaw" && (o = await Ot({ fsImpl: e, hostConfigPath: t.hostConfigPath })), {
216
+ return t.host === "openclaw" && (o = await Pt({ fsImpl: e, hostConfigPath: t.hostConfigPath })), {
218
217
  builtinsInstalled: r.installed,
219
218
  pluginInstalled: i.installed,
220
219
  hostConfigRepaired: o
221
220
  };
222
221
  }
223
- async function tt(t, s = {}) {
224
- const e = s.fs ?? u, r = await It(
222
+ async function et(t, s = {}) {
223
+ if (t.host !== "openclaw")
224
+ return {
225
+ builtinsInstalled: [],
226
+ pluginInstalled: !1,
227
+ hostConfigRepaired: !1,
228
+ verification: {
229
+ ok: !1,
230
+ issues: [{ code: "unsupported_host_bootstrap", host: t.host }]
231
+ }
232
+ };
233
+ const e = s.fs ?? u, r = await Ut(
225
234
  {
226
235
  host: t.host,
227
236
  skillsDir: t.skillsDir,
@@ -229,7 +238,7 @@ async function tt(t, s = {}) {
229
238
  hostConfigPath: t.hostConfigPath
230
239
  },
231
240
  { fs: e }
232
- ), i = await X(
241
+ ), i = await tt(
233
242
  {
234
243
  host: t.host,
235
244
  skillsDir: t.skillsDir,
@@ -245,7 +254,7 @@ async function tt(t, s = {}) {
245
254
  verification: i
246
255
  };
247
256
  }
248
- function C(t, s) {
257
+ function j(t, s) {
249
258
  const e = new Set(s.map((n) => n.code)), r = new Set(
250
259
  s.filter((n) => n.code === "missing_builtin_skill").map((n) => n.slug)
251
260
  ), i = new Set(
@@ -263,25 +272,25 @@ function C(t, s) {
263
272
  name: "builtin_find-skills",
264
273
  ok: !r.has("find-skills"),
265
274
  message: r.has("find-skills") ? "missing built-in skill" : "built-in skill installed",
266
- path: c.join(t.skillsDir, "find-skills", "SKILL.md")
275
+ path: l.join(t.skillsDir, "find-skills", "SKILL.md")
267
276
  },
268
277
  {
269
278
  name: "builtin_rrskill-preference",
270
279
  ok: !r.has("rrskill-preference"),
271
280
  message: r.has("rrskill-preference") ? "missing built-in skill" : "built-in skill installed",
272
- path: c.join(t.skillsDir, "rrskill-preference", "SKILL.md")
281
+ path: l.join(t.skillsDir, "rrskill-preference", "SKILL.md")
273
282
  },
274
283
  {
275
284
  name: "plugin_index",
276
- ok: !i.has(c.join(t.pluginDir, "index.ts")),
277
- message: i.has(c.join(t.pluginDir, "index.ts")) ? "missing OpenClaw plugin entry file" : "OpenClaw plugin entry file present",
278
- path: c.join(t.pluginDir, "index.ts")
285
+ ok: !i.has(l.join(t.pluginDir, "index.ts")),
286
+ message: i.has(l.join(t.pluginDir, "index.ts")) ? "missing OpenClaw plugin entry file" : "OpenClaw plugin entry file present",
287
+ path: l.join(t.pluginDir, "index.ts")
279
288
  },
280
289
  {
281
290
  name: "plugin_manifest",
282
- ok: !i.has(c.join(t.pluginDir, "openclaw.plugin.json")),
283
- message: i.has(c.join(t.pluginDir, "openclaw.plugin.json")) ? "missing OpenClaw plugin manifest" : "OpenClaw plugin manifest present",
284
- path: c.join(t.pluginDir, "openclaw.plugin.json")
291
+ ok: !i.has(l.join(t.pluginDir, "openclaw.plugin.json")),
292
+ message: i.has(l.join(t.pluginDir, "openclaw.plugin.json")) ? "missing OpenClaw plugin manifest" : "OpenClaw plugin manifest present",
293
+ path: l.join(t.pluginDir, "openclaw.plugin.json")
285
294
  },
286
295
  {
287
296
  name: "host_config",
@@ -296,7 +305,7 @@ function C(t, s) {
296
305
  }
297
306
  ];
298
307
  }
299
- async function Pt(t, s = {}, e = {}) {
308
+ async function Rt(t, s = {}, e = {}) {
300
309
  const r = e.fs ?? u, i = {
301
310
  skillsDir: t.skillsDir,
302
311
  pluginDir: t.pluginDir,
@@ -325,7 +334,7 @@ async function Pt(t, s = {}, e = {}) {
325
334
  nextCommands: ["rrskill search <query>", "rrskill install <slug>"],
326
335
  paths: i
327
336
  };
328
- const o = await X(t, {
337
+ const o = await tt(t, {
329
338
  fs: r
330
339
  });
331
340
  if (o.ok)
@@ -335,7 +344,7 @@ async function Pt(t, s = {}, e = {}) {
335
344
  bootstrapSupported: !0,
336
345
  fixed: !1,
337
346
  dryRun: s.dryRun ?? !1,
338
- checks: C(t, []),
347
+ checks: j(t, []),
339
348
  issues: [],
340
349
  nextCommands: [],
341
350
  paths: i,
@@ -348,14 +357,14 @@ async function Pt(t, s = {}, e = {}) {
348
357
  bootstrapSupported: !0,
349
358
  fixed: !1,
350
359
  dryRun: !0,
351
- checks: C(t, o.issues),
360
+ checks: j(t, o.issues),
352
361
  issues: o.issues,
353
362
  nextCommands: ["rrskill bootstrap --host openclaw"],
354
363
  paths: i,
355
364
  verification: o
356
365
  };
357
366
  if (s.fix) {
358
- const n = await tt(t, {
367
+ const n = await et(t, {
359
368
  fs: r
360
369
  });
361
370
  return {
@@ -364,7 +373,7 @@ async function Pt(t, s = {}, e = {}) {
364
373
  bootstrapSupported: !0,
365
374
  fixed: !0,
366
375
  dryRun: !1,
367
- checks: C(
376
+ checks: j(
368
377
  t,
369
378
  n.verification.ok ? [] : n.verification.issues
370
379
  ),
@@ -380,47 +389,47 @@ async function Pt(t, s = {}, e = {}) {
380
389
  bootstrapSupported: !0,
381
390
  fixed: !1,
382
391
  dryRun: !1,
383
- checks: C(t, o.issues),
392
+ checks: j(t, o.issues),
384
393
  issues: o.issues,
385
394
  nextCommands: ["rrskill bootstrap --host openclaw"],
386
395
  paths: i,
387
396
  verification: o
388
397
  };
389
398
  }
390
- function Ut(t) {
399
+ function At(t) {
391
400
  return t.HOME ?? t.USERPROFILE ?? process.env.HOME ?? process.env.USERPROFILE ?? process.cwd();
392
401
  }
393
- function M(t, s) {
402
+ function q(t, s) {
394
403
  const e = t?.trim();
395
404
  if (e)
396
- return e === "~" ? s : e.startsWith("~/") ? c.resolve(s, e.slice(2)) : c.resolve(e);
405
+ return e === "~" ? s : e.startsWith("~/") ? l.resolve(s, e.slice(2)) : l.resolve(e);
397
406
  }
398
- function O(t, s) {
407
+ function $(t, s) {
399
408
  for (const e of s) {
400
409
  const r = t[e];
401
410
  if (typeof r == "string" && r.trim())
402
411
  return r.trim();
403
412
  }
404
413
  }
405
- function $t(t, s) {
414
+ function Tt(t, s) {
406
415
  if (typeof t != "object" || t === null || Array.isArray(t))
407
416
  throw new Error(
408
417
  `Invalid rrskill config at ${s}: root must be a JSON object`
409
418
  );
410
419
  return t;
411
420
  }
412
- async function At(t) {
413
- const s = Ut(t.env), e = M(t.env.RRSKILL_CONFIG_PATH, s) ?? c.resolve(s, ".rrskill", "config.json");
421
+ async function Ft(t) {
422
+ const s = At(t.env), e = q(t.env.RRSKILL_CONFIG_PATH, s) ?? l.resolve(s, ".rrskill", "config.json");
414
423
  try {
415
- const r = await u.readFile(e, "utf8"), i = $t(JSON.parse(r), e);
424
+ const r = await u.readFile(e, "utf8"), i = Tt(JSON.parse(r), e);
416
425
  return {
417
426
  configPath: e,
418
- host: O(i, ["host"]),
419
- stateDir: M(
420
- O(i, ["stateDir", "state_dir"]),
427
+ host: $(i, ["host"]),
428
+ stateDir: q(
429
+ $(i, ["stateDir", "state_dir"]),
421
430
  s
422
431
  ),
423
- skillsSearchUrl: O(i, [
432
+ skillsSearchUrl: $(i, [
424
433
  "skillsSearchUrl",
425
434
  "skills_search_url"
426
435
  ])
@@ -433,44 +442,44 @@ async function At(t) {
433
442
  ) : r;
434
443
  }
435
444
  }
436
- const Rt = "openclaw", Ft = "--host", q = {
445
+ const Nt = "openclaw", Ht = "--host", K = {
437
446
  "--openclaw": "openclaw",
438
447
  "--codex": "codex",
439
448
  "--claude-code": "claude-code"
440
- }, st = [
449
+ }, rt = [
441
450
  "openclaw",
442
451
  "codex",
443
452
  "claude-code"
444
- ], Ht = new Set(st), Nt = new Set(V);
445
- function Tt(t) {
453
+ ], zt = new Set(rt), Mt = new Set(Q);
454
+ function Jt(t) {
446
455
  if (!t)
447
456
  return;
448
457
  const s = t.trim().toLowerCase();
449
- if (s && Ht.has(s))
458
+ if (s && zt.has(s))
450
459
  return s;
451
460
  }
452
461
  function I(t, s) {
453
462
  if (t === void 0)
454
463
  return;
455
- const e = Tt(t);
464
+ const e = Jt(t);
456
465
  if (e)
457
466
  return e;
458
467
  const r = t.trim();
459
468
  if (r)
460
469
  throw new Error(
461
- `Unsupported host "${r}" from ${s}. Supported hosts: ${st.join(", ")}`
470
+ `Unsupported host "${r}" from ${s}. Supported hosts: ${rt.join(", ")}`
462
471
  );
463
472
  }
464
- function zt(t) {
465
- const s = t.indexOf(Ft);
473
+ function Bt(t) {
474
+ const s = t.indexOf(Ht);
466
475
  if (s < 0)
467
476
  return;
468
477
  const e = t[s + 1];
469
- if (!(!e || e.startsWith("--") || Nt.has(e)))
478
+ if (!(!e || e.startsWith("--") || Mt.has(e)))
470
479
  return e;
471
480
  }
472
- function Jt(t) {
473
- const s = t.filter((r) => r in q).map((r) => q[r]);
481
+ function qt(t) {
482
+ const s = t.filter((r) => r in K).map((r) => K[r]);
474
483
  if (s.length === 0)
475
484
  return;
476
485
  const e = Array.from(new Set(s));
@@ -478,9 +487,9 @@ function Jt(t) {
478
487
  throw new Error(`Conflicting host flags: ${e.join(", ")}`);
479
488
  return e[0];
480
489
  }
481
- function Mt(t) {
482
- const s = Jt(t.argv), e = I(
483
- zt(t.argv),
490
+ function Kt(t) {
491
+ const s = qt(t.argv), e = I(
492
+ Bt(t.argv),
484
493
  "--host"
485
494
  );
486
495
  if (s && e && s !== e)
@@ -494,13 +503,13 @@ function Mt(t) {
494
503
  if (i)
495
504
  return i;
496
505
  const o = t.config.configPath ? `config ${t.config.configPath}` : "config", n = I(t.config.host, o);
497
- return n || Rt;
506
+ return n || Nt;
498
507
  }
499
- function qt(t) {
508
+ function Wt(t) {
500
509
  const s = t.env.HOME ?? t.env.USERPROFILE ?? process.env.HOME ?? process.env.USERPROFILE ?? process.cwd(), e = t.config.stateDir ?? `${s}/.rrskill`;
501
510
  return { homeDir: s, stateDir: e };
502
511
  }
503
- const Kt = {
512
+ const Vt = {
504
513
  name: "openclaw",
505
514
  getDefaultPaths({ homeDir: t }) {
506
515
  return {
@@ -509,7 +518,7 @@ const Kt = {
509
518
  hostConfigPath: `${t}/.openclaw/openclaw.json`
510
519
  };
511
520
  }
512
- }, Wt = {
521
+ }, Gt = {
513
522
  name: "codex",
514
523
  getDefaultPaths({ homeDir: t, stateDir: s }) {
515
524
  const e = s ?? `${t}/.rrskill`;
@@ -519,7 +528,7 @@ const Kt = {
519
528
  hostConfigPath: `${t}/.codex/config.toml`
520
529
  };
521
530
  }
522
- }, Bt = {
531
+ }, Zt = {
523
532
  name: "claude-code",
524
533
  getDefaultPaths({ homeDir: t, stateDir: s }) {
525
534
  const e = s ?? `${t}/.rrskill`;
@@ -530,8 +539,8 @@ const Kt = {
530
539
  };
531
540
  }
532
541
  };
533
- async function K(t) {
534
- const s = await At({ env: t.env }), e = Mt({ argv: t.argv, env: t.env, config: s }), r = qt({ env: t.env, config: s }), i = e === "openclaw" ? Kt.getDefaultPaths({ homeDir: r.homeDir, stateDir: r.stateDir }) : e === "codex" ? Wt.getDefaultPaths({ homeDir: r.homeDir, stateDir: r.stateDir }) : Bt.getDefaultPaths({ homeDir: r.homeDir, stateDir: r.stateDir });
542
+ async function W(t) {
543
+ const s = await Ft({ env: t.env }), e = Kt({ argv: t.argv, env: t.env, config: s }), r = Wt({ env: t.env, config: s }), i = e === "openclaw" ? Vt.getDefaultPaths({ homeDir: r.homeDir, stateDir: r.stateDir }) : e === "codex" ? Gt.getDefaultPaths({ homeDir: r.homeDir, stateDir: r.stateDir }) : Zt.getDefaultPaths({ homeDir: r.homeDir, stateDir: r.stateDir });
535
544
  return {
536
545
  argv: t.argv,
537
546
  env: t.env,
@@ -545,68 +554,68 @@ async function K(t) {
545
554
  config: s
546
555
  };
547
556
  }
548
- const Gt = ".rrskill_lock.json";
549
- function A() {
557
+ const Qt = ".rrskill_lock.json";
558
+ function R() {
550
559
  return { version: 1, skills: {} };
551
560
  }
552
- function et(t) {
553
- return c.join(t, Gt);
561
+ function it(t) {
562
+ return l.join(t, Qt);
554
563
  }
555
- function rt(t, s) {
556
- const e = c.resolve(t), r = c.resolve(e, s), i = e.endsWith(c.sep) ? e : `${e}${c.sep}`;
564
+ function nt(t, s) {
565
+ const e = l.resolve(t), r = l.resolve(e, s), i = e.endsWith(l.sep) ? e : `${e}${l.sep}`;
557
566
  if (!r.startsWith(i))
558
567
  throw new Error(`Refusing to write outside skillsDir: slug="${s}"`);
559
568
  return r;
560
569
  }
561
- function k(t) {
570
+ function w(t) {
562
571
  return typeof t == "object" && t !== null;
563
572
  }
564
- function W(t, s) {
565
- if (!k(s)) return;
566
- const e = typeof s.slug == "string" ? s.slug : t, r = typeof s.installedAt == "string" ? s.installedAt : void 0, i = typeof s.version == "string" ? s.version : void 0, o = k(s.source) || i ? {
573
+ function V(t, s) {
574
+ if (!w(s)) return;
575
+ const e = typeof s.slug == "string" ? s.slug : t, r = typeof s.installedAt == "string" ? s.installedAt : void 0, i = typeof s.version == "string" ? s.version : void 0, o = w(s.source) || i ? {
567
576
  type: "registry",
568
- version: (k(s.source) && typeof s.source.version == "string" ? s.source.version : void 0) ?? i
577
+ version: (w(s.source) && typeof s.source.version == "string" ? s.source.version : void 0) ?? i
569
578
  } : void 0;
570
579
  return { slug: e, installedAt: r, source: o };
571
580
  }
572
- function Vt(t) {
573
- if (!k(t)) return A();
574
- if (t.version === 1 && k(t.skills)) {
581
+ function Xt(t) {
582
+ if (!w(t)) return R();
583
+ if (t.version === 1 && w(t.skills)) {
575
584
  const i = {};
576
585
  for (const [o, n] of Object.entries(t.skills)) {
577
- const l = W(o, n);
578
- l && (i[o] = l);
586
+ const c = V(o, n);
587
+ c && (i[o] = c);
579
588
  }
580
589
  return { version: 1, skills: i };
581
590
  }
582
591
  const s = Object.hasOwn(t, "version"), e = Object.hasOwn(t, "skills");
583
592
  if (s || e)
584
- return A();
593
+ return R();
585
594
  const r = {};
586
595
  for (const [i, o] of Object.entries(t)) {
587
- const n = W(i, o);
596
+ const n = V(i, o);
588
597
  n && (r[i] = n);
589
598
  }
590
599
  return { version: 1, skills: r };
591
600
  }
592
- async function F(t) {
593
- const s = et(t.skillsDir);
601
+ async function N(t) {
602
+ const s = it(t.skillsDir);
594
603
  try {
595
604
  const e = await t.fs.readFile(s, "utf8"), r = JSON.parse(e);
596
- return Vt(r);
605
+ return Xt(r);
597
606
  } catch (e) {
598
- if ((k(e) && typeof e.code == "string" ? e.code : void 0) === "ENOENT") return A();
607
+ if ((w(e) && typeof e.code == "string" ? e.code : void 0) === "ENOENT") return R();
599
608
  throw e;
600
609
  }
601
610
  }
602
- async function it(t) {
603
- const s = et(t.skillsDir);
611
+ async function ot(t) {
612
+ const s = it(t.skillsDir);
604
613
  await t.fs.mkdir(t.skillsDir, { recursive: !0 });
605
614
  const e = `${s}.tmp`, r = `${JSON.stringify(t.lockfile, null, 2)}
606
615
  `;
607
616
  await t.fs.writeFile(e, r, "utf8"), await t.fs.rename(e, s);
608
617
  }
609
- function nt(t, s) {
618
+ function at(t, s) {
610
619
  return {
611
620
  version: 1,
612
621
  skills: {
@@ -615,13 +624,13 @@ function nt(t, s) {
615
624
  }
616
625
  };
617
626
  }
618
- function Zt() {
627
+ function Yt() {
619
628
  return /* @__PURE__ */ new Date();
620
629
  }
621
- async function Qt(t) {
630
+ async function ts(t) {
622
631
  const s = t.fsImpl ?? u;
623
632
  await s.mkdir(t.targetDir, { recursive: !0 });
624
- const e = c.join(t.targetDir, "rrskill.json");
633
+ const e = l.join(t.targetDir, "rrskill.json");
625
634
  await s.writeFile(
626
635
  e,
627
636
  `${JSON.stringify({ slug: t.slug, installedBy: "rrskill-cli", schema: 1 }, null, 2)}
@@ -629,71 +638,71 @@ async function Qt(t) {
629
638
  "utf8"
630
639
  );
631
640
  }
632
- async function Xt(t, s, e = {}) {
633
- const r = e.fs ?? u, i = e.now ?? Zt;
641
+ async function ss(t, s, e = {}) {
642
+ const r = e.fs ?? u, i = e.now ?? Yt;
634
643
  let o;
635
- if (e.searchSkills && (o = (await e.searchSkills({ query: s })).results.find((m) => m.slug === s), !o))
644
+ if (e.searchSkills && (o = (await e.searchSkills({ query: s })).results.find((h) => h.slug === s), !o))
636
645
  throw new Error(`No exact registry match for slug "${s}"`);
637
- const n = rt(t.skillsDir, s);
638
- let l = o?.version;
639
- e.downloadSkill ? (await r.mkdir(n, { recursive: !0 }), l = (await e.downloadSkill({ slug: s, targetDir: n, registrySkill: o })).version ?? l) : await Qt({ slug: s, targetDir: n, fsImpl: r });
640
- const a = await F({ skillsDir: t.skillsDir, fs: r }), d = nt(a, {
646
+ const n = nt(t.skillsDir, s);
647
+ let c = o?.version;
648
+ e.downloadSkill ? (await r.mkdir(n, { recursive: !0 }), c = (await e.downloadSkill({ slug: s, targetDir: n, registrySkill: o })).version ?? c) : await ts({ slug: s, targetDir: n, fsImpl: r });
649
+ const a = await N({ skillsDir: t.skillsDir, fs: r }), f = at(a, {
641
650
  slug: s,
642
651
  installedAt: i().toISOString(),
643
- source: { type: "registry", version: l }
652
+ source: { type: "registry", version: c }
644
653
  });
645
- return await it({ skillsDir: t.skillsDir, fs: r, lockfile: d }), {
654
+ return await ot({ skillsDir: t.skillsDir, fs: r, lockfile: f }), {
646
655
  slug: s,
647
656
  targetDir: n,
648
657
  registryMatch: o
649
658
  };
650
659
  }
651
- async function Yt(t, s = {}) {
652
- const e = s.fs ?? u, r = await F({ skillsDir: t.skillsDir, fs: e });
660
+ async function es(t, s = {}) {
661
+ const e = s.fs ?? u, r = await N({ skillsDir: t.skillsDir, fs: e });
653
662
  return Object.keys(r.skills).sort();
654
663
  }
655
- async function ts(t, s, e) {
664
+ async function rs(t, s, e) {
656
665
  return e.searchSkills({ query: s });
657
666
  }
658
- async function ss(t, s = {}) {
659
- const e = s.fs ?? u, r = s.now ?? (() => /* @__PURE__ */ new Date()), i = await F({ skillsDir: t.skillsDir, fs: e }), o = Object.keys(i.skills).sort();
667
+ async function is(t, s = {}) {
668
+ const e = s.fs ?? u, r = s.now ?? (() => /* @__PURE__ */ new Date()), i = await N({ skillsDir: t.skillsDir, fs: e }), o = Object.keys(i.skills).sort();
660
669
  if (!s.downloadSkill)
661
670
  return { upgraded: [] };
662
671
  const n = [];
663
- let l = i;
672
+ let c = i;
664
673
  for (const a of o) {
665
- const d = rt(t.skillsDir, a);
666
- await e.mkdir(d, { recursive: !0 });
667
- const f = await s.downloadSkill({ slug: a, targetDir: d });
674
+ const f = nt(t.skillsDir, a);
675
+ await e.mkdir(f, { recursive: !0 });
676
+ const d = await s.downloadSkill({ slug: a, targetDir: f });
668
677
  n.push(a);
669
- const m = l.skills[a];
670
- l = nt(l, {
678
+ const h = c.skills[a];
679
+ c = at(c, {
671
680
  slug: a,
672
681
  installedAt: r().toISOString(),
673
682
  source: {
674
683
  type: "registry",
675
- version: f.version ?? m?.source?.version
684
+ version: d.version ?? h?.source?.version
676
685
  }
677
- }), await it({ skillsDir: t.skillsDir, fs: e, lockfile: l });
686
+ }), await ot({ skillsDir: t.skillsDir, fs: e, lockfile: c });
678
687
  }
679
688
  return { upgraded: n };
680
689
  }
681
- function es(t) {
682
- let s = c.dirname(x(t));
690
+ function ns(t) {
691
+ let s = l.dirname(_(t));
683
692
  for (; ; ) {
684
- const e = c.join(s, "package.json");
693
+ const e = l.join(s, "package.json");
685
694
  try {
686
- return JSON.parse(mt(e, "utf8"));
695
+ return JSON.parse(wt(e, "utf8"));
687
696
  } catch {
688
- const r = c.dirname(s);
697
+ const r = l.dirname(s);
689
698
  if (r === s)
690
699
  return {};
691
700
  s = r;
692
701
  }
693
702
  }
694
703
  }
695
- function rs(t = {}) {
696
- const s = es(import.meta.url);
704
+ function os(t = {}) {
705
+ const s = ns(import.meta.url);
697
706
  return {
698
707
  packageName: t.packageName ?? s.name ?? "rrskill",
699
708
  version: t.version ?? s.version ?? "0.0.0-dev",
@@ -701,8 +710,8 @@ function rs(t = {}) {
701
710
  instructions: ["npm install -g rrskill@latest", "npm install -g @rrskill/cli@latest"]
702
711
  };
703
712
  }
704
- const is = wt(kt.inflateRaw), ns = "https://api.rrskill.ai/skills?page=1&size={limit}&search={query}&orderBy=downloadCount&order=desc", os = 20;
705
- function _(t) {
713
+ const as = St(vt.inflateRaw), ls = "https://api.rrskill.ai/skills?page=1&size={limit}&search={query}&orderBy=downloadCount&order=desc", cs = 20;
714
+ function C(t) {
706
715
  return typeof t == "object" && t !== null && !Array.isArray(t);
707
716
  }
708
717
  function p(t, s) {
@@ -712,21 +721,21 @@ function p(t, s) {
712
721
  return r.trim();
713
722
  }
714
723
  }
715
- function j(t) {
724
+ function L(t) {
716
725
  try {
717
726
  return new URL(t);
718
727
  } catch {
719
728
  return;
720
729
  }
721
730
  }
722
- function as(t, s, e, r) {
723
- const i = s.RRSKILL_SKILLS_SEARCH_URL?.trim() || s.RRSKILL_SEARCH_URL?.trim() || t.skillsSearchUrl?.trim() || ns, o = i.replaceAll("{query}", encodeURIComponent(e)).replaceAll("{limit}", String(r)), n = j(o);
731
+ function us(t, s, e, r) {
732
+ const i = s.RRSKILL_SKILLS_SEARCH_URL?.trim() || s.RRSKILL_SEARCH_URL?.trim() || t.skillsSearchUrl?.trim() || ls, o = i.replaceAll("{query}", encodeURIComponent(e)).replaceAll("{limit}", String(r)), n = L(o);
724
733
  return n && ["http:", "https:"].includes(n.protocol) ? (i.includes("{query}") || ["search", "q", "keyword", "slug"].some(
725
- (l) => n.searchParams.has(l)
726
- ) || n.searchParams.set("search", e), i.includes("{limit}") || ["limit", "size"].some((l) => n.searchParams.has(l)) || n.searchParams.set("limit", String(r)), n.toString()) : o;
734
+ (c) => n.searchParams.has(c)
735
+ ) || n.searchParams.set("search", e), i.includes("{limit}") || ["limit", "size"].some((c) => n.searchParams.has(c)) || n.searchParams.set("limit", String(r)), n.toString()) : o;
727
736
  }
728
- async function ls(t) {
729
- const s = j(t);
737
+ async function fs(t) {
738
+ const s = L(t);
730
739
  if (s?.protocol === "http:" || s?.protocol === "https:") {
731
740
  const r = await fetch(t, {
732
741
  headers: {
@@ -743,19 +752,19 @@ async function ls(t) {
743
752
  };
744
753
  }
745
754
  if (s?.protocol === "file:") {
746
- const r = x(s);
755
+ const r = _(s);
747
756
  return {
748
757
  payload: await u.readFile(r, "utf8"),
749
758
  reference: s.toString()
750
759
  };
751
760
  }
752
- const e = c.resolve(t);
761
+ const e = l.resolve(t);
753
762
  return {
754
763
  payload: await u.readFile(e, "utf8"),
755
- reference: ht(e).toString()
764
+ reference: kt(e).toString()
756
765
  };
757
766
  }
758
- function cs(t, s) {
767
+ function ds(t, s) {
759
768
  if (t)
760
769
  try {
761
770
  return new URL(t, s).toString();
@@ -763,21 +772,21 @@ function cs(t, s) {
763
772
  return;
764
773
  }
765
774
  }
766
- function ot(t, s, e) {
775
+ function lt(t, s, e) {
767
776
  const r = s?.trim().toLowerCase();
768
777
  if (!r)
769
778
  return;
770
- const i = gt("sha256").update(t).digest("hex").toLowerCase();
779
+ const i = yt("sha256").update(t).digest("hex").toLowerCase();
771
780
  if (i !== r)
772
781
  throw new Error(
773
782
  `SHA256 mismatch for ${e}: expected ${r}, got ${i}`
774
783
  );
775
784
  }
776
- function us(t, s) {
785
+ function ps(t, s) {
777
786
  const e = p(t, ["slug"]);
778
787
  if (!e)
779
788
  return;
780
- const r = _(t.currentVersion) ? t.currentVersion : {}, i = cs(
789
+ const r = C(t.currentVersion) ? t.currentVersion : {}, i = ds(
781
790
  p(r, [
782
791
  "skillUrl",
783
792
  "downloadUrl",
@@ -796,7 +805,7 @@ function us(t, s) {
796
805
  source: p(t, ["source", "platform"])
797
806
  };
798
807
  }
799
- function fs(t, s, e) {
808
+ function hs(t, s, e) {
800
809
  let r;
801
810
  try {
802
811
  r = JSON.parse(t);
@@ -805,11 +814,11 @@ function fs(t, s, e) {
805
814
  `Search response is not valid JSON: ${a instanceof Error ? a.message : String(a)}`
806
815
  );
807
816
  }
808
- if (!_(r))
817
+ if (!C(r))
809
818
  throw new Error("Search API response must be a JSON object.");
810
819
  let i = r.results;
811
820
  if (!Array.isArray(i)) {
812
- const a = _(r.data) ? r.data : void 0;
821
+ const a = C(r.data) ? r.data : void 0;
813
822
  a && Array.isArray(a.records) && (i = a.records);
814
823
  }
815
824
  if (!Array.isArray(i))
@@ -817,101 +826,101 @@ function fs(t, s, e) {
817
826
  'Search API response must include "results" or "data.records" array.'
818
827
  );
819
828
  const o = e.trim().toLowerCase(), n = !["http:", "https:"].includes(
820
- j(s)?.protocol ?? ""
821
- ), l = i.filter(_).map((a) => us(a, s)).filter((a) => a !== void 0).filter((a) => n && o ? [a.slug, a.title, a.description].filter(
822
- (f) => !!f
829
+ L(s)?.protocol ?? ""
830
+ ), c = i.filter(C).map((a) => ps(a, s)).filter((a) => a !== void 0).filter((a) => n && o ? [a.slug, a.title, a.description].filter(
831
+ (d) => !!d
823
832
  ).some(
824
- (f) => f.toLowerCase().includes(o)
833
+ (d) => d.toLowerCase().includes(o)
825
834
  ) : !0);
826
- return { query: e, results: l };
835
+ return { query: e, results: c };
827
836
  }
828
- function ds(t) {
837
+ function ms(t) {
829
838
  return async ({ query: s }) => {
830
- const e = as(
839
+ const e = us(
831
840
  t.config,
832
841
  t.env,
833
842
  s,
834
- os
835
- ), { payload: r, reference: i } = await ls(e);
836
- return fs(r, i, s);
843
+ cs
844
+ ), { payload: r, reference: i } = await fs(e);
845
+ return hs(r, i, s);
837
846
  };
838
847
  }
839
- async function at(t, s) {
848
+ async function ct(t, s) {
840
849
  const e = [];
841
850
  let n = -1;
842
- for (let d = t.length - 22; d >= Math.max(0, t.length - 65557); d -= 1)
843
- if (t.readUInt32LE(d) === 101010256) {
844
- n = d;
851
+ for (let f = t.length - 22; f >= Math.max(0, t.length - 65557); f -= 1)
852
+ if (t.readUInt32LE(f) === 101010256) {
853
+ n = f;
845
854
  break;
846
855
  }
847
856
  if (n < 0)
848
857
  throw new Error("Downloaded skill package is not a valid zip archive.");
849
- const l = t.readUInt16LE(n + 10);
858
+ const c = t.readUInt16LE(n + 10);
850
859
  let a = t.readUInt32LE(n + 16);
851
860
  await u.mkdir(s, { recursive: !0 });
852
- for (let d = 0; d < l; d += 1) {
861
+ for (let f = 0; f < c; f += 1) {
853
862
  if (t.readUInt32LE(a) !== 33639248)
854
863
  throw new Error(
855
864
  "Downloaded skill package has an invalid zip central directory."
856
865
  );
857
- const f = t.readUInt16LE(a + 10), m = t.readUInt32LE(a + 20), lt = t.readUInt32LE(a + 24), H = t.readUInt16LE(a + 28), ct = t.readUInt16LE(a + 30), ut = t.readUInt16LE(a + 32), v = t.readUInt32LE(a + 42), S = t.toString(
866
+ const d = t.readUInt16LE(a + 10), h = t.readUInt32LE(a + 20), ft = t.readUInt32LE(a + 24), H = t.readUInt16LE(a + 28), dt = t.readUInt16LE(a + 30), pt = t.readUInt16LE(a + 32), v = t.readUInt32LE(a + 42), S = t.toString(
858
867
  "utf8",
859
868
  a + 46,
860
869
  a + 46 + H
861
870
  );
862
- a += 46 + H + ct + ut;
863
- const g = S.replaceAll("\\", "/");
864
- if (!g || g.startsWith("/") || g.includes("../"))
871
+ a += 46 + H + dt + pt;
872
+ const k = S.replaceAll("\\", "/");
873
+ if (!k || k.startsWith("/") || k.includes("../"))
865
874
  throw new Error(`Unsafe zip path entry detected: ${S}`);
866
- const y = c.resolve(s, g), ft = s.endsWith(c.sep) ? s : `${s}${c.sep}`;
867
- if (y !== s && !y.startsWith(ft))
875
+ const y = l.resolve(s, k), ht = s.endsWith(l.sep) ? s : `${s}${l.sep}`;
876
+ if (y !== s && !y.startsWith(ht))
868
877
  throw new Error(`Unsafe zip path entry detected: ${S}`);
869
878
  if (t.readUInt32LE(v) !== 67324752)
870
879
  throw new Error(
871
880
  "Downloaded skill package has an invalid zip local header."
872
881
  );
873
- const dt = t.readUInt16LE(v + 26), pt = t.readUInt16LE(v + 28), N = v + 30 + dt + pt, T = t.subarray(
874
- N,
875
- N + m
882
+ const mt = t.readUInt16LE(v + 26), gt = t.readUInt16LE(v + 28), z = v + 30 + mt + gt, M = t.subarray(
883
+ z,
884
+ z + h
876
885
  );
877
- if (g.endsWith("/")) {
886
+ if (k.endsWith("/")) {
878
887
  await u.mkdir(y, { recursive: !0 });
879
888
  continue;
880
889
  }
881
890
  let D;
882
- if (f === 0)
883
- D = Buffer.from(T);
884
- else if (f === 8)
885
- D = Buffer.from(await is(T));
891
+ if (d === 0)
892
+ D = Buffer.from(M);
893
+ else if (d === 8)
894
+ D = Buffer.from(await as(M));
886
895
  else
887
896
  throw new Error(
888
- `Unsupported zip compression method: ${f}`
897
+ `Unsupported zip compression method: ${d}`
889
898
  );
890
- if (D.length !== lt)
899
+ if (D.length !== ft)
891
900
  throw new Error(`Zip entry size mismatch for ${S}`);
892
- await u.mkdir(c.dirname(y), { recursive: !0 }), await u.writeFile(y, D), e.push(g);
901
+ await u.mkdir(l.dirname(y), { recursive: !0 }), await u.writeFile(y, D), e.push(k);
893
902
  }
894
903
  return e;
895
904
  }
896
- async function R(t, s) {
897
- await u.rm(s, { recursive: !0, force: !0 }), await u.mkdir(c.dirname(s), { recursive: !0 }), await u.cp(t, s, { recursive: !0 });
905
+ async function A(t, s) {
906
+ await u.rm(s, { recursive: !0, force: !0 }), await u.mkdir(l.dirname(s), { recursive: !0 }), await u.cp(t, s, { recursive: !0 });
898
907
  }
899
- async function ps(t, s, e) {
908
+ async function gs(t, s, e) {
900
909
  if ((await u.stat(t)).isDirectory())
901
- return await R(t, s), [];
910
+ return await A(t, s), [];
902
911
  const i = await u.readFile(t);
903
- ot(i, e, t);
912
+ lt(i, e, t);
904
913
  const o = await u.mkdtemp(
905
- c.join(G.tmpdir(), "rrskill-registry-stage-")
914
+ l.join(Z.tmpdir(), "rrskill-registry-stage-")
906
915
  );
907
916
  try {
908
- const n = await at(i, o);
909
- return await R(o, s), n;
917
+ const n = await ct(i, o);
918
+ return await A(o, s), n;
910
919
  } finally {
911
920
  await u.rm(o, { recursive: !0, force: !0 });
912
921
  }
913
922
  }
914
- async function hs(t, s, e) {
923
+ async function ks(t, s, e) {
915
924
  const r = await fetch(t, {
916
925
  headers: {
917
926
  accept: "application/zip,application/octet-stream,*/*"
@@ -922,35 +931,35 @@ async function hs(t, s, e) {
922
931
  `Skill download failed: ${r.status} ${r.statusText}`
923
932
  );
924
933
  const i = Buffer.from(await r.arrayBuffer());
925
- ot(i, e, t);
934
+ lt(i, e, t);
926
935
  const o = await u.mkdtemp(
927
- c.join(G.tmpdir(), "rrskill-registry-stage-")
936
+ l.join(Z.tmpdir(), "rrskill-registry-stage-")
928
937
  );
929
938
  try {
930
- const n = await at(i, o);
931
- return await R(o, s), n;
939
+ const n = await ct(i, o);
940
+ return await A(o, s), n;
932
941
  } finally {
933
942
  await u.rm(o, { recursive: !0, force: !0 });
934
943
  }
935
944
  }
936
- async function ms(t, s) {
945
+ async function ws(t, s) {
937
946
  const r = (await t({ query: s })).results.find((i) => i.slug === s);
938
947
  if (!r)
939
948
  throw new Error(`No exact registry match for slug "${s}"`);
940
949
  return r;
941
950
  }
942
- async function gs(t, s) {
943
- const e = s.registrySkill?.slug === s.slug ? s.registrySkill : await ms(t, s.slug), r = e.skillUrl;
951
+ async function ys(t, s) {
952
+ const e = s.registrySkill?.slug === s.slug ? s.registrySkill : await ws(t, s.slug), r = e.skillUrl;
944
953
  if (!r)
945
954
  throw new Error(
946
955
  `Registry skill "${s.slug}" does not define a skillUrl/packageUrl`
947
956
  );
948
- const i = j(r), o = e.sha256, n = i?.protocol === "http:" || i?.protocol === "https:" ? await hs(
957
+ const i = L(r), o = e.sha256, n = i?.protocol === "http:" || i?.protocol === "https:" ? await ks(
949
958
  r,
950
959
  s.targetDir,
951
960
  o
952
- ) : await ps(
953
- i?.protocol === "file:" ? x(i) : c.resolve(r),
961
+ ) : await gs(
962
+ i?.protocol === "file:" ? _(i) : l.resolve(r),
954
963
  s.targetDir,
955
964
  o
956
965
  );
@@ -961,10 +970,10 @@ async function gs(t, s) {
961
970
  version: e.version
962
971
  };
963
972
  }
964
- function ks(t) {
965
- return async (s) => gs(t, s);
973
+ function vs(t) {
974
+ return async (s) => ys(t, s);
966
975
  }
967
- class w extends Error {
976
+ class g extends Error {
968
977
  code;
969
978
  hint;
970
979
  nextCommands;
@@ -972,11 +981,11 @@ class w extends Error {
972
981
  super(s.message), this.code = s.code, this.hint = s.hint, this.nextCommands = s.nextCommands ?? [];
973
982
  }
974
983
  }
975
- function ws() {
984
+ function Ss() {
976
985
  const t = process.argv[1] ?? "";
977
- return t ? ["rrskill.js", "rrskill"].includes(c.basename(t)) ? !0 : import.meta.url === `file://${t}` : !1;
986
+ return t ? ["rrskill.js", "rrskill"].includes(l.basename(t)) ? !0 : import.meta.url === `file://${t}` : !1;
978
987
  }
979
- function ys() {
988
+ function Ds() {
980
989
  return [
981
990
  "rrskill CLI",
982
991
  "",
@@ -1012,7 +1021,7 @@ function ys() {
1012
1021
  ].join(`
1013
1022
  `);
1014
1023
  }
1015
- function vs(t) {
1024
+ function xs(t) {
1016
1025
  const s = [
1017
1026
  "",
1018
1027
  "Global options:",
@@ -1108,14 +1117,77 @@ function vs(t) {
1108
1117
  ].join(`
1109
1118
  `);
1110
1119
  }
1111
- function h(t) {
1120
+ function T(t) {
1112
1121
  process.stdout.write(`${JSON.stringify(t, null, 2)}
1113
1122
  `);
1114
1123
  }
1115
- function L(t, ...s) {
1124
+ function F(t) {
1125
+ process.stdout.write(t.endsWith(`
1126
+ `) ? t : `${t}
1127
+ `);
1128
+ }
1129
+ function m(t, s, e) {
1130
+ if (s === "json") {
1131
+ T(t);
1132
+ return;
1133
+ }
1134
+ F(e(t));
1135
+ }
1136
+ function js(t) {
1137
+ return [
1138
+ `${t.packageName} ${t.version}`,
1139
+ `Update via ${t.updateVia}:`,
1140
+ ...t.instructions.map((s) => ` ${s}`)
1141
+ ].join(`
1142
+ `);
1143
+ }
1144
+ function Cs(t) {
1145
+ return t.results.length === 0 ? `No skills found for "${t.query}".` : t.results.map((s) => {
1146
+ const e = s.version ? `@${s.version}` : "", r = s.title && s.title !== s.slug ? ` - ${s.title}` : "";
1147
+ return `${s.slug}${e}${r}`;
1148
+ }).join(`
1149
+ `);
1150
+ }
1151
+ function Es(t) {
1152
+ const s = [`Installed ${t.slug}`, `Target: ${t.targetDir}`];
1153
+ return t.registryMatch?.version && s.push(`Version: ${t.registryMatch.version}`), s.join(`
1154
+ `);
1155
+ }
1156
+ function _s(t) {
1157
+ return t.length === 0 ? "No skills installed." : t.join(`
1158
+ `);
1159
+ }
1160
+ function Ls(t) {
1161
+ return t.upgraded.length === 0 ? "No skills upgraded." : ["Upgraded skills:", ...t.upgraded.map((s) => ` ${s}`)].join(`
1162
+ `);
1163
+ }
1164
+ function bs(t) {
1165
+ const s = [
1166
+ t.verification.ok ? "Bootstrap succeeded." : "Bootstrap failed.",
1167
+ `Builtins installed: ${t.builtinsInstalled.length === 0 ? "none" : t.builtinsInstalled.join(", ")}`,
1168
+ `Plugin installed: ${t.pluginInstalled ? "yes" : "no"}`,
1169
+ `Host config repaired: ${t.hostConfigRepaired ? "yes" : "no"}`
1170
+ ];
1171
+ return t.verification.ok || s.push(
1172
+ ...t.verification.issues.map(
1173
+ (e) => "code" in e ? `Issue: ${e.code}` : `Issue: ${JSON.stringify(e)}`
1174
+ )
1175
+ ), s.join(`
1176
+ `);
1177
+ }
1178
+ function $s(t) {
1179
+ const s = [
1180
+ t.ok ? `Doctor OK for ${t.host}.` : `Doctor found issues for ${t.host}.`,
1181
+ `Bootstrap supported: ${t.bootstrapSupported ? "yes" : "no"}`,
1182
+ `Fixed: ${t.fixed ? "yes" : "no"}`
1183
+ ];
1184
+ return t.checks.length > 0 && s.push(...t.checks.map((e) => `[${e.ok ? "ok" : "fail"}] ${e.name}: ${e.message}`)), t.nextCommands.length > 0 && s.push("Next commands:", ...t.nextCommands.map((e) => ` ${e}`)), s.join(`
1185
+ `);
1186
+ }
1187
+ function E(t, ...s) {
1116
1188
  return t.some((e) => s.includes(e));
1117
1189
  }
1118
- function Ss(t, s) {
1190
+ function Is(t, s) {
1119
1191
  const e = t.indexOf(s);
1120
1192
  if (e < 0)
1121
1193
  return;
@@ -1123,32 +1195,32 @@ function Ss(t, s) {
1123
1195
  if (!(!r || r.startsWith("--")))
1124
1196
  return r;
1125
1197
  }
1126
- function Ds(t) {
1127
- if (L(t, "--json"))
1198
+ function ut(t, s = "json") {
1199
+ if (E(t, "--json"))
1128
1200
  return "json";
1129
- const s = Ss(t, "--output");
1130
- if (!s) {
1201
+ const e = Is(t, "--output");
1202
+ if (!e) {
1131
1203
  if (t.includes("--output"))
1132
- throw new w({
1204
+ throw new g({
1133
1205
  code: "missing_output_mode",
1134
1206
  message: "--output requires a value.",
1135
1207
  hint: "rrskill --output <json|text>",
1136
1208
  nextCommands: ["rrskill --help"]
1137
1209
  });
1138
- return "text";
1139
- }
1140
- if (s === "json" || s === "text")
1141
1210
  return s;
1142
- throw new w({
1211
+ }
1212
+ if (e === "json" || e === "text")
1213
+ return e;
1214
+ throw new g({
1143
1215
  code: "invalid_output_mode",
1144
- message: `Unsupported output mode "${s}".`,
1216
+ message: `Unsupported output mode "${e}".`,
1145
1217
  hint: "rrskill --output <json|text>",
1146
1218
  nextCommands: ["rrskill --help"]
1147
1219
  });
1148
1220
  }
1149
- function B(t, s) {
1150
- if (t instanceof w && s === "json") {
1151
- h({
1221
+ function G(t, s) {
1222
+ if (t instanceof g && s === "json") {
1223
+ T({
1152
1224
  ok: !1,
1153
1225
  error: {
1154
1226
  code: t.code,
@@ -1159,7 +1231,7 @@ function B(t, s) {
1159
1231
  });
1160
1232
  return;
1161
1233
  }
1162
- if (t instanceof w) {
1234
+ if (t instanceof g) {
1163
1235
  const r = [`Error: ${t.message}`];
1164
1236
  if (t.hint && r.push(` ${t.hint}`), t.nextCommands.length > 0) {
1165
1237
  r.push("Next commands:");
@@ -1173,7 +1245,7 @@ function B(t, s) {
1173
1245
  }
1174
1246
  const e = t instanceof Error ? t.message : String(t);
1175
1247
  if (s === "json") {
1176
- h({
1248
+ T({
1177
1249
  ok: !1,
1178
1250
  error: {
1179
1251
  code: "unexpected_error",
@@ -1186,77 +1258,84 @@ function B(t, s) {
1186
1258
  process.stderr.write(`${e}
1187
1259
  `);
1188
1260
  }
1189
- async function Es(t) {
1190
- const s = Et(t), e = Q(t), r = L(t, "--help", "-h");
1191
- if (s.command === "help" || r)
1192
- return s.command !== "help" && s.command !== "install" ? (process.stdout.write(`${vs(s.command)}
1193
- `), 0) : (process.stdout.write(`${ys()}
1194
- `), 0);
1195
- if (s.command === "doctor") {
1196
- const l = await K({ argv: t, env: process.env }), a = await Pt(
1197
- l,
1261
+ async function Os(t) {
1262
+ const s = ut(t, "json"), e = Et(t), r = Y(t), i = E(t, "--help", "-h");
1263
+ if (e.command === "unknown")
1264
+ throw new g({
1265
+ code: "unknown_command",
1266
+ message: `Unknown command "${e.input}".`,
1267
+ hint: "rrskill --help",
1268
+ nextCommands: ["rrskill --help"]
1269
+ });
1270
+ if (e.command === "help" || i) {
1271
+ const a = e.command === "help" ? r[1] : e.command !== "install" ? e.command : void 0;
1272
+ return a && ["search", "install", "list", "upgrade", "bootstrap", "doctor", "version"].includes(a) ? (F(xs(a)), 0) : (F(Ds()), 0);
1273
+ }
1274
+ if (e.command === "doctor") {
1275
+ const a = await W({ argv: t, env: process.env }), f = await Rt(
1276
+ a,
1198
1277
  {
1199
- fix: L(t, "--fix"),
1200
- dryRun: L(t, "--dry-run")
1278
+ fix: E(t, "--fix"),
1279
+ dryRun: E(t, "--dry-run")
1201
1280
  }
1202
1281
  );
1203
- return h(a), a.ok ? 0 : 1;
1282
+ return m(f, s, $s), f.ok ? 0 : 1;
1204
1283
  }
1205
- if (s.command === "version")
1206
- return h(rs()), 0;
1207
- const i = await K({ argv: t, env: process.env }), o = ds({ config: i.config, env: i.env }), n = ks(o);
1208
- if (s.command === "bootstrap") {
1209
- const l = await tt(i);
1210
- return h(l), l.verification.ok ? 0 : 1;
1284
+ if (e.command === "version")
1285
+ return m(os(), s, js), 0;
1286
+ const o = await W({ argv: t, env: process.env }), n = ms({ config: o.config, env: o.env }), c = vs(n);
1287
+ if (e.command === "bootstrap") {
1288
+ const a = await et(o);
1289
+ return m(a, s, bs), a.verification.ok ? 0 : 1;
1211
1290
  }
1212
- if (s.command === "search") {
1213
- const l = e.slice(1).join(" ").trim();
1214
- if (!l)
1215
- throw new w({
1291
+ if (e.command === "search") {
1292
+ const a = r.slice(1).join(" ").trim();
1293
+ if (!a)
1294
+ throw new g({
1216
1295
  code: "missing_search_query",
1217
1296
  message: "Search query is required.",
1218
1297
  hint: "rrskill search <query>",
1219
1298
  nextCommands: ["rrskill search react"]
1220
1299
  });
1221
- const a = await ts(i, l, { searchSkills: o });
1222
- return h(a), 0;
1300
+ const f = await rs(o, a, { searchSkills: n });
1301
+ return m(f, s, Cs), 0;
1223
1302
  }
1224
- if (s.command === "install") {
1225
- const l = "slug" in s ? s.slug : e[1]?.trim();
1226
- if (!l)
1227
- throw new w({
1303
+ if (e.command === "install") {
1304
+ const a = "slug" in e ? e.slug : r[1]?.trim();
1305
+ if (!a)
1306
+ throw new g({
1228
1307
  code: "missing_skill_slug",
1229
1308
  message: "Skill slug is required.",
1230
1309
  hint: "rrskill install <slug>",
1231
1310
  nextCommands: ["rrskill install web-search"]
1232
1311
  });
1233
- const a = await Xt(i, l, { searchSkills: o, downloadSkill: n });
1234
- return h(a), 0;
1312
+ const f = await ss(o, a, { searchSkills: n, downloadSkill: c });
1313
+ return m(f, s, Es), 0;
1235
1314
  }
1236
- if (s.command === "list") {
1237
- const l = await Yt(i);
1238
- return h(l), 0;
1315
+ if (e.command === "list") {
1316
+ const a = await es(o);
1317
+ return m(a, s, _s), 0;
1239
1318
  }
1240
- if (s.command === "upgrade") {
1241
- const l = await ss(i, { downloadSkill: n });
1242
- return h(l), 0;
1319
+ if (e.command === "upgrade") {
1320
+ const a = await is(o, { downloadSkill: c });
1321
+ return m(a, s, Ls), 0;
1243
1322
  }
1244
- return process.stderr.write(`Command "${s.command}" is not implemented yet.
1323
+ return process.stderr.write(`Command "${e.command}" is not implemented yet.
1245
1324
  `), 1;
1246
1325
  }
1247
- if (ws()) {
1326
+ if (Ss()) {
1248
1327
  const t = process.argv.slice(2);
1249
- Es(t).then((s) => {
1328
+ Os(t).then((s) => {
1250
1329
  process.exitCode = s;
1251
1330
  }).catch((s) => {
1252
1331
  let e = "text";
1253
1332
  try {
1254
- e = Ds(t);
1333
+ e = ut(t, "text");
1255
1334
  } catch (r) {
1256
- B(r, "text"), process.exitCode = 1;
1335
+ G(r, "text"), process.exitCode = 1;
1257
1336
  return;
1258
1337
  }
1259
- B(s, e), process.exitCode = 1;
1338
+ G(s, e), process.exitCode = 1;
1260
1339
  });
1261
1340
  }
1262
1341
  export {