rrskill 0.1.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/dist/index.js ADDED
@@ -0,0 +1,1264 @@
1
+ import * as c from "node:path";
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) {
11
+ const s = [];
12
+ for (let e = 0; e < t.length; e += 1) {
13
+ const r = t[e];
14
+ if (r) {
15
+ if (St.has(r)) {
16
+ const i = t[e + 1];
17
+ i && !i.startsWith("--") && !Z.has(i) && (e += 1);
18
+ continue;
19
+ }
20
+ Dt.has(r) || r.startsWith("--") || s.push(r);
21
+ }
22
+ }
23
+ return s;
24
+ }
25
+ function Et(t) {
26
+ const s = Q(t)[0] ?? "";
27
+ return s ? Z.has(s) ? { command: s } : { command: "install", slug: s } : { command: "help" };
28
+ }
29
+ async function b(t) {
30
+ const s = t.fsImpl ?? u;
31
+ try {
32
+ return (await s.stat(t.path)).isFile();
33
+ } catch {
34
+ return !1;
35
+ }
36
+ }
37
+ async function Ct(t) {
38
+ const s = t.fsImpl ?? u;
39
+ let e;
40
+ try {
41
+ e = await s.readFile(t.path, "utf8");
42
+ } catch {
43
+ return { ok: !1, issue: { code: "missing_host_config", path: t.path } };
44
+ }
45
+ try {
46
+ const r = JSON.parse(e);
47
+ return r && typeof r == "object" && !Array.isArray(r) ? { ok: !0, value: r } : {
48
+ ok: !1,
49
+ issue: { code: "invalid_host_config_json", path: t.path, error: "root is not a JSON object" }
50
+ };
51
+ } catch (r) {
52
+ return {
53
+ ok: !1,
54
+ issue: { code: "invalid_host_config_json", path: t.path, error: r instanceof Error ? r.message : String(r) }
55
+ };
56
+ }
57
+ }
58
+ function z(t, s) {
59
+ let e = t;
60
+ for (const r of s) {
61
+ if (!e || typeof e != "object")
62
+ return;
63
+ e = e[r];
64
+ }
65
+ return e;
66
+ }
67
+ async function X(t, s = {}) {
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 });
72
+ }
73
+ if (t.host !== "openclaw")
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");
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"]);
81
+ if (!a || typeof a != "object")
82
+ r.push({ code: "missing_host_plugin_entry", path: t.hostConfigPath });
83
+ else {
84
+ const d = [
85
+ { key: ["plugins", "entries", "rrskill", "enabled"], expected: !0 },
86
+ { key: ["plugins", "entries", "rrskill", "config", "primaryCli"], expected: "rrskill" },
87
+ { key: ["plugins", "entries", "rrskill", "config", "primaryLabel"], expected: "official-registry" }
88
+ ];
89
+ for (const f of d) {
90
+ const m = z(l.value, f.key);
91
+ m !== f.expected && r.push({
92
+ code: "host_plugin_policy_mismatch",
93
+ path: t.hostConfigPath,
94
+ key: f.key.join("."),
95
+ expected: f.expected,
96
+ actual: m
97
+ });
98
+ }
99
+ }
100
+ return { ok: r.length === 0, issues: r };
101
+ }
102
+ function P(t, s) {
103
+ const e = c.dirname(x(t));
104
+ return [
105
+ c.resolve(e, "..", "builtins", s),
106
+ c.resolve(e, "..", "src", "builtins", s),
107
+ c.resolve(e, "..", "..", "src", "builtins", s)
108
+ ];
109
+ }
110
+ async function U(t) {
111
+ const s = t.fsImpl ?? u;
112
+ let e;
113
+ for (const r of t.candidates)
114
+ try {
115
+ return await s.readFile(r, "utf8");
116
+ } catch (i) {
117
+ e = i;
118
+ }
119
+ throw new Error(`Failed to load ${t.assetLabel} from candidates: ${t.candidates.join(", ")} (${String(e)})`);
120
+ }
121
+ async function $(t) {
122
+ const s = t.fsImpl ?? u, e = t.content.endsWith(`
123
+ `) ? t.content : `${t.content}
124
+ `;
125
+ try {
126
+ if (await s.readFile(t.path, "utf8") === e)
127
+ return !1;
128
+ } catch {
129
+ }
130
+ return await s.mkdir(c.dirname(t.path), { recursive: !0 }), await s.writeFile(t.path, e, "utf8"), !0;
131
+ }
132
+ const J = ["find-skills", "rrskill-preference"];
133
+ function _t(t) {
134
+ return t === "find-skills" ? "skills/find-skills.md" : "skills/rrskill-preference.md";
135
+ }
136
+ async function Lt(t, s = {}) {
137
+ const e = s.fs ?? u;
138
+ let r = !1;
139
+ for (const i of J) {
140
+ const o = await U({
141
+ candidates: P(import.meta.url, _t(i)),
142
+ fsImpl: e,
143
+ 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;
146
+ }
147
+ return { installed: [...J], changed: r };
148
+ }
149
+ async function xt(t, s = {}) {
150
+ const e = s.fs ?? u;
151
+ if (t.host !== "openclaw")
152
+ return { installed: !1, changed: !1 };
153
+ const r = await U({
154
+ candidates: P(import.meta.url, "plugins/openclaw/index.ts"),
155
+ fsImpl: e,
156
+ assetLabel: "built-in plugin asset"
157
+ }), i = await U({
158
+ candidates: P(import.meta.url, "plugins/openclaw/openclaw.plugin.json"),
159
+ fsImpl: e,
160
+ 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 };
163
+ }
164
+ function Y(t) {
165
+ return !!t && typeof t == "object" && !Array.isArray(t);
166
+ }
167
+ function E(t, s) {
168
+ const e = t[s];
169
+ if (Y(e))
170
+ return e;
171
+ const r = {};
172
+ return t[s] = r, r;
173
+ }
174
+ async function jt(t) {
175
+ const s = t.fsImpl ?? u;
176
+ try {
177
+ const e = await s.readFile(t.path, "utf8");
178
+ try {
179
+ 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" };
181
+ } catch (r) {
182
+ return {
183
+ object: {},
184
+ exists: !0,
185
+ parseOk: !1,
186
+ rawText: e,
187
+ parseError: r instanceof Error ? r.message : String(r)
188
+ };
189
+ }
190
+ } catch {
191
+ return { object: {}, exists: !1, parseOk: !1 };
192
+ }
193
+ }
194
+ async function bt(t) {
195
+ const s = t.fsImpl ?? u, e = `${JSON.stringify(t.value, null, 2)}
196
+ `;
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);
198
+ }
199
+ async function Ot(t) {
200
+ const s = t.fsImpl ?? u, e = await jt({ fsImpl: s, path: t.hostConfigPath });
201
+ if (e.exists && !e.parseOk)
202
+ throw new Error(
203
+ `Invalid OpenClaw config JSON at ${t.hostConfigPath}: ${e.parseError ?? "unknown parse error"}`
204
+ );
205
+ const r = e.object, i = E(r, "plugins"), o = E(i, "entries"), n = E(o, "rrskill"), l = E(n, "config");
206
+ 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({
208
+ fsImpl: s,
209
+ path: t.hostConfigPath,
210
+ value: r,
211
+ prevRawText: e.rawText
212
+ }) : !1;
213
+ }
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 });
216
+ let o = !1;
217
+ return t.host === "openclaw" && (o = await Ot({ fsImpl: e, hostConfigPath: t.hostConfigPath })), {
218
+ builtinsInstalled: r.installed,
219
+ pluginInstalled: i.installed,
220
+ hostConfigRepaired: o
221
+ };
222
+ }
223
+ async function tt(t, s = {}) {
224
+ const e = s.fs ?? u, r = await It(
225
+ {
226
+ host: t.host,
227
+ skillsDir: t.skillsDir,
228
+ pluginDir: t.pluginDir,
229
+ hostConfigPath: t.hostConfigPath
230
+ },
231
+ { fs: e }
232
+ ), i = await X(
233
+ {
234
+ host: t.host,
235
+ skillsDir: t.skillsDir,
236
+ pluginDir: t.pluginDir,
237
+ hostConfigPath: t.hostConfigPath
238
+ },
239
+ { fs: e }
240
+ );
241
+ return {
242
+ builtinsInstalled: r.builtinsInstalled,
243
+ pluginInstalled: r.pluginInstalled,
244
+ hostConfigRepaired: r.hostConfigRepaired,
245
+ verification: i
246
+ };
247
+ }
248
+ function C(t, s) {
249
+ const e = new Set(s.map((n) => n.code)), r = new Set(
250
+ s.filter((n) => n.code === "missing_builtin_skill").map((n) => n.slug)
251
+ ), i = new Set(
252
+ s.filter((n) => n.code === "missing_plugin_file").map((n) => n.path)
253
+ ), o = s.some(
254
+ (n) => [
255
+ "missing_host_config",
256
+ "invalid_host_config_json",
257
+ "missing_host_plugin_entry",
258
+ "host_plugin_policy_mismatch"
259
+ ].includes(n.code)
260
+ );
261
+ return [
262
+ {
263
+ name: "builtin_find-skills",
264
+ ok: !r.has("find-skills"),
265
+ message: r.has("find-skills") ? "missing built-in skill" : "built-in skill installed",
266
+ path: c.join(t.skillsDir, "find-skills", "SKILL.md")
267
+ },
268
+ {
269
+ name: "builtin_rrskill-preference",
270
+ ok: !r.has("rrskill-preference"),
271
+ message: r.has("rrskill-preference") ? "missing built-in skill" : "built-in skill installed",
272
+ path: c.join(t.skillsDir, "rrskill-preference", "SKILL.md")
273
+ },
274
+ {
275
+ 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")
279
+ },
280
+ {
281
+ 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")
285
+ },
286
+ {
287
+ name: "host_config",
288
+ ok: !o,
289
+ message: o ? "OpenClaw host config is missing or does not match rrskill policy" : "OpenClaw host config matches rrskill policy",
290
+ path: t.hostConfigPath
291
+ },
292
+ {
293
+ name: "bootstrap_supported",
294
+ ok: !e.has("unsupported_host_bootstrap"),
295
+ message: "bootstrap integration is supported for openclaw"
296
+ }
297
+ ];
298
+ }
299
+ async function Pt(t, s = {}, e = {}) {
300
+ const r = e.fs ?? u, i = {
301
+ skillsDir: t.skillsDir,
302
+ pluginDir: t.pluginDir,
303
+ hostConfigPath: t.hostConfigPath
304
+ };
305
+ if (t.host !== "openclaw")
306
+ return {
307
+ ok: !0,
308
+ host: t.host,
309
+ bootstrapSupported: !1,
310
+ fixed: !1,
311
+ dryRun: s.dryRun ?? !1,
312
+ checks: [
313
+ {
314
+ name: "cli_available",
315
+ ok: !0,
316
+ message: "rrskill CLI is running"
317
+ },
318
+ {
319
+ name: "bootstrap_supported",
320
+ ok: !0,
321
+ message: `${t.host} currently uses CLI-only initialization; bootstrap repair is not implemented`
322
+ }
323
+ ],
324
+ issues: [],
325
+ nextCommands: ["rrskill search <query>", "rrskill install <slug>"],
326
+ paths: i
327
+ };
328
+ const o = await X(t, {
329
+ fs: r
330
+ });
331
+ if (o.ok)
332
+ return {
333
+ ok: !0,
334
+ host: t.host,
335
+ bootstrapSupported: !0,
336
+ fixed: !1,
337
+ dryRun: s.dryRun ?? !1,
338
+ checks: C(t, []),
339
+ issues: [],
340
+ nextCommands: [],
341
+ paths: i,
342
+ verification: o
343
+ };
344
+ if (s.dryRun)
345
+ return {
346
+ ok: !1,
347
+ host: t.host,
348
+ bootstrapSupported: !0,
349
+ fixed: !1,
350
+ dryRun: !0,
351
+ checks: C(t, o.issues),
352
+ issues: o.issues,
353
+ nextCommands: ["rrskill bootstrap --host openclaw"],
354
+ paths: i,
355
+ verification: o
356
+ };
357
+ if (s.fix) {
358
+ const n = await tt(t, {
359
+ fs: r
360
+ });
361
+ return {
362
+ ok: n.verification.ok,
363
+ host: t.host,
364
+ bootstrapSupported: !0,
365
+ fixed: !0,
366
+ dryRun: !1,
367
+ checks: C(
368
+ t,
369
+ n.verification.ok ? [] : n.verification.issues
370
+ ),
371
+ issues: n.verification.ok ? [] : n.verification.issues,
372
+ nextCommands: n.verification.ok ? [] : ["rrskill bootstrap --host openclaw"],
373
+ paths: i,
374
+ verification: n.verification
375
+ };
376
+ }
377
+ return {
378
+ ok: !1,
379
+ host: t.host,
380
+ bootstrapSupported: !0,
381
+ fixed: !1,
382
+ dryRun: !1,
383
+ checks: C(t, o.issues),
384
+ issues: o.issues,
385
+ nextCommands: ["rrskill bootstrap --host openclaw"],
386
+ paths: i,
387
+ verification: o
388
+ };
389
+ }
390
+ function Ut(t) {
391
+ return t.HOME ?? t.USERPROFILE ?? process.env.HOME ?? process.env.USERPROFILE ?? process.cwd();
392
+ }
393
+ function M(t, s) {
394
+ const e = t?.trim();
395
+ if (e)
396
+ return e === "~" ? s : e.startsWith("~/") ? c.resolve(s, e.slice(2)) : c.resolve(e);
397
+ }
398
+ function O(t, s) {
399
+ for (const e of s) {
400
+ const r = t[e];
401
+ if (typeof r == "string" && r.trim())
402
+ return r.trim();
403
+ }
404
+ }
405
+ function $t(t, s) {
406
+ if (typeof t != "object" || t === null || Array.isArray(t))
407
+ throw new Error(
408
+ `Invalid rrskill config at ${s}: root must be a JSON object`
409
+ );
410
+ return t;
411
+ }
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");
414
+ try {
415
+ const r = await u.readFile(e, "utf8"), i = $t(JSON.parse(r), e);
416
+ return {
417
+ configPath: e,
418
+ host: O(i, ["host"]),
419
+ stateDir: M(
420
+ O(i, ["stateDir", "state_dir"]),
421
+ s
422
+ ),
423
+ skillsSearchUrl: O(i, [
424
+ "skillsSearchUrl",
425
+ "skills_search_url"
426
+ ])
427
+ };
428
+ } catch (r) {
429
+ if ((typeof r == "object" && r !== null && "code" in r ? String(r.code) : void 0) === "ENOENT")
430
+ return { configPath: e };
431
+ throw r instanceof SyntaxError ? new Error(
432
+ `Invalid rrskill config JSON at ${e}: ${r.message}`
433
+ ) : r;
434
+ }
435
+ }
436
+ const Rt = "openclaw", Ft = "--host", q = {
437
+ "--openclaw": "openclaw",
438
+ "--codex": "codex",
439
+ "--claude-code": "claude-code"
440
+ }, st = [
441
+ "openclaw",
442
+ "codex",
443
+ "claude-code"
444
+ ], Ht = new Set(st), Nt = new Set(V);
445
+ function Tt(t) {
446
+ if (!t)
447
+ return;
448
+ const s = t.trim().toLowerCase();
449
+ if (s && Ht.has(s))
450
+ return s;
451
+ }
452
+ function I(t, s) {
453
+ if (t === void 0)
454
+ return;
455
+ const e = Tt(t);
456
+ if (e)
457
+ return e;
458
+ const r = t.trim();
459
+ if (r)
460
+ throw new Error(
461
+ `Unsupported host "${r}" from ${s}. Supported hosts: ${st.join(", ")}`
462
+ );
463
+ }
464
+ function zt(t) {
465
+ const s = t.indexOf(Ft);
466
+ if (s < 0)
467
+ return;
468
+ const e = t[s + 1];
469
+ if (!(!e || e.startsWith("--") || Nt.has(e)))
470
+ return e;
471
+ }
472
+ function Jt(t) {
473
+ const s = t.filter((r) => r in q).map((r) => q[r]);
474
+ if (s.length === 0)
475
+ return;
476
+ const e = Array.from(new Set(s));
477
+ if (e.length > 1)
478
+ throw new Error(`Conflicting host flags: ${e.join(", ")}`);
479
+ return e[0];
480
+ }
481
+ function Mt(t) {
482
+ const s = Jt(t.argv), e = I(
483
+ zt(t.argv),
484
+ "--host"
485
+ );
486
+ if (s && e && s !== e)
487
+ throw new Error(
488
+ `Conflicting host flags: ${s} vs ${e}`
489
+ );
490
+ const r = e ?? s;
491
+ if (r)
492
+ return r;
493
+ const i = I(t.env.RRSKILL_HOST, "RRSKILL_HOST");
494
+ if (i)
495
+ return i;
496
+ const o = t.config.configPath ? `config ${t.config.configPath}` : "config", n = I(t.config.host, o);
497
+ return n || Rt;
498
+ }
499
+ function qt(t) {
500
+ const s = t.env.HOME ?? t.env.USERPROFILE ?? process.env.HOME ?? process.env.USERPROFILE ?? process.cwd(), e = t.config.stateDir ?? `${s}/.rrskill`;
501
+ return { homeDir: s, stateDir: e };
502
+ }
503
+ const Kt = {
504
+ name: "openclaw",
505
+ getDefaultPaths({ homeDir: t }) {
506
+ return {
507
+ skillsDir: `${t}/.openclaw/workspace/skills`,
508
+ pluginDir: `${t}/.openclaw/extensions/rrskill`,
509
+ hostConfigPath: `${t}/.openclaw/openclaw.json`
510
+ };
511
+ }
512
+ }, Wt = {
513
+ name: "codex",
514
+ getDefaultPaths({ homeDir: t, stateDir: s }) {
515
+ const e = s ?? `${t}/.rrskill`;
516
+ return {
517
+ skillsDir: `${e}/hosts/codex/skills`,
518
+ pluginDir: `${e}/hosts/codex/plugin`,
519
+ hostConfigPath: `${t}/.codex/config.toml`
520
+ };
521
+ }
522
+ }, Bt = {
523
+ name: "claude-code",
524
+ getDefaultPaths({ homeDir: t, stateDir: s }) {
525
+ const e = s ?? `${t}/.rrskill`;
526
+ return {
527
+ skillsDir: `${e}/hosts/claude-code/skills`,
528
+ pluginDir: `${e}/hosts/claude-code/plugin`,
529
+ hostConfigPath: `${t}/.claude/settings.json`
530
+ };
531
+ }
532
+ };
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 });
535
+ return {
536
+ argv: t.argv,
537
+ env: t.env,
538
+ host: e,
539
+ distribution: "npm",
540
+ stateDir: r.stateDir,
541
+ skillsDir: i.skillsDir,
542
+ pluginDir: i.pluginDir,
543
+ hostConfigPath: i.hostConfigPath,
544
+ paths: r,
545
+ config: s
546
+ };
547
+ }
548
+ const Gt = ".rrskill_lock.json";
549
+ function A() {
550
+ return { version: 1, skills: {} };
551
+ }
552
+ function et(t) {
553
+ return c.join(t, Gt);
554
+ }
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}`;
557
+ if (!r.startsWith(i))
558
+ throw new Error(`Refusing to write outside skillsDir: slug="${s}"`);
559
+ return r;
560
+ }
561
+ function k(t) {
562
+ return typeof t == "object" && t !== null;
563
+ }
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 ? {
567
+ type: "registry",
568
+ version: (k(s.source) && typeof s.source.version == "string" ? s.source.version : void 0) ?? i
569
+ } : void 0;
570
+ return { slug: e, installedAt: r, source: o };
571
+ }
572
+ function Vt(t) {
573
+ if (!k(t)) return A();
574
+ if (t.version === 1 && k(t.skills)) {
575
+ const i = {};
576
+ for (const [o, n] of Object.entries(t.skills)) {
577
+ const l = W(o, n);
578
+ l && (i[o] = l);
579
+ }
580
+ return { version: 1, skills: i };
581
+ }
582
+ const s = Object.hasOwn(t, "version"), e = Object.hasOwn(t, "skills");
583
+ if (s || e)
584
+ return A();
585
+ const r = {};
586
+ for (const [i, o] of Object.entries(t)) {
587
+ const n = W(i, o);
588
+ n && (r[i] = n);
589
+ }
590
+ return { version: 1, skills: r };
591
+ }
592
+ async function F(t) {
593
+ const s = et(t.skillsDir);
594
+ try {
595
+ const e = await t.fs.readFile(s, "utf8"), r = JSON.parse(e);
596
+ return Vt(r);
597
+ } catch (e) {
598
+ if ((k(e) && typeof e.code == "string" ? e.code : void 0) === "ENOENT") return A();
599
+ throw e;
600
+ }
601
+ }
602
+ async function it(t) {
603
+ const s = et(t.skillsDir);
604
+ await t.fs.mkdir(t.skillsDir, { recursive: !0 });
605
+ const e = `${s}.tmp`, r = `${JSON.stringify(t.lockfile, null, 2)}
606
+ `;
607
+ await t.fs.writeFile(e, r, "utf8"), await t.fs.rename(e, s);
608
+ }
609
+ function nt(t, s) {
610
+ return {
611
+ version: 1,
612
+ skills: {
613
+ ...t.skills,
614
+ [s.slug]: s
615
+ }
616
+ };
617
+ }
618
+ function Zt() {
619
+ return /* @__PURE__ */ new Date();
620
+ }
621
+ async function Qt(t) {
622
+ const s = t.fsImpl ?? u;
623
+ await s.mkdir(t.targetDir, { recursive: !0 });
624
+ const e = c.join(t.targetDir, "rrskill.json");
625
+ await s.writeFile(
626
+ e,
627
+ `${JSON.stringify({ slug: t.slug, installedBy: "rrskill-cli", schema: 1 }, null, 2)}
628
+ `,
629
+ "utf8"
630
+ );
631
+ }
632
+ async function Xt(t, s, e = {}) {
633
+ const r = e.fs ?? u, i = e.now ?? Zt;
634
+ let o;
635
+ if (e.searchSkills && (o = (await e.searchSkills({ query: s })).results.find((m) => m.slug === s), !o))
636
+ 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, {
641
+ slug: s,
642
+ installedAt: i().toISOString(),
643
+ source: { type: "registry", version: l }
644
+ });
645
+ return await it({ skillsDir: t.skillsDir, fs: r, lockfile: d }), {
646
+ slug: s,
647
+ targetDir: n,
648
+ registryMatch: o
649
+ };
650
+ }
651
+ async function Yt(t, s = {}) {
652
+ const e = s.fs ?? u, r = await F({ skillsDir: t.skillsDir, fs: e });
653
+ return Object.keys(r.skills).sort();
654
+ }
655
+ async function ts(t, s, e) {
656
+ return e.searchSkills({ query: s });
657
+ }
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();
660
+ if (!s.downloadSkill)
661
+ return { upgraded: [] };
662
+ const n = [];
663
+ let l = i;
664
+ 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 });
668
+ n.push(a);
669
+ const m = l.skills[a];
670
+ l = nt(l, {
671
+ slug: a,
672
+ installedAt: r().toISOString(),
673
+ source: {
674
+ type: "registry",
675
+ version: f.version ?? m?.source?.version
676
+ }
677
+ }), await it({ skillsDir: t.skillsDir, fs: e, lockfile: l });
678
+ }
679
+ return { upgraded: n };
680
+ }
681
+ function es(t) {
682
+ let s = c.dirname(x(t));
683
+ for (; ; ) {
684
+ const e = c.join(s, "package.json");
685
+ try {
686
+ return JSON.parse(mt(e, "utf8"));
687
+ } catch {
688
+ const r = c.dirname(s);
689
+ if (r === s)
690
+ return {};
691
+ s = r;
692
+ }
693
+ }
694
+ }
695
+ function rs(t = {}) {
696
+ const s = es(import.meta.url);
697
+ return {
698
+ packageName: t.packageName ?? s.name ?? "rrskill",
699
+ version: t.version ?? s.version ?? "0.0.0-dev",
700
+ updateVia: "npm",
701
+ instructions: ["npm install -g rrskill@latest", "npm install -g @rrskill/cli@latest"]
702
+ };
703
+ }
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) {
706
+ return typeof t == "object" && t !== null && !Array.isArray(t);
707
+ }
708
+ function p(t, s) {
709
+ for (const e of s) {
710
+ const r = t[e];
711
+ if (typeof r == "string" && r.trim())
712
+ return r.trim();
713
+ }
714
+ }
715
+ function j(t) {
716
+ try {
717
+ return new URL(t);
718
+ } catch {
719
+ return;
720
+ }
721
+ }
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);
724
+ 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;
727
+ }
728
+ async function ls(t) {
729
+ const s = j(t);
730
+ if (s?.protocol === "http:" || s?.protocol === "https:") {
731
+ const r = await fetch(t, {
732
+ headers: {
733
+ accept: "application/json"
734
+ }
735
+ });
736
+ if (!r.ok)
737
+ throw new Error(
738
+ `Search request failed: ${r.status} ${r.statusText}`
739
+ );
740
+ return {
741
+ payload: await r.text(),
742
+ reference: r.url || t
743
+ };
744
+ }
745
+ if (s?.protocol === "file:") {
746
+ const r = x(s);
747
+ return {
748
+ payload: await u.readFile(r, "utf8"),
749
+ reference: s.toString()
750
+ };
751
+ }
752
+ const e = c.resolve(t);
753
+ return {
754
+ payload: await u.readFile(e, "utf8"),
755
+ reference: ht(e).toString()
756
+ };
757
+ }
758
+ function cs(t, s) {
759
+ if (t)
760
+ try {
761
+ return new URL(t, s).toString();
762
+ } catch {
763
+ return;
764
+ }
765
+ }
766
+ function ot(t, s, e) {
767
+ const r = s?.trim().toLowerCase();
768
+ if (!r)
769
+ return;
770
+ const i = gt("sha256").update(t).digest("hex").toLowerCase();
771
+ if (i !== r)
772
+ throw new Error(
773
+ `SHA256 mismatch for ${e}: expected ${r}, got ${i}`
774
+ );
775
+ }
776
+ function us(t, s) {
777
+ const e = p(t, ["slug"]);
778
+ if (!e)
779
+ return;
780
+ const r = _(t.currentVersion) ? t.currentVersion : {}, i = cs(
781
+ p(r, [
782
+ "skillUrl",
783
+ "downloadUrl",
784
+ "packageUrl",
785
+ "url"
786
+ ]) ?? p(t, ["skillUrl", "downloadUrl", "packageUrl", "url"]),
787
+ s
788
+ );
789
+ return {
790
+ slug: e,
791
+ title: p(t, ["displayName", "name", "title"]) ?? e,
792
+ description: p(t, ["summary", "description"]),
793
+ version: p(r, ["version"]) ?? p(t, ["version"]),
794
+ skillUrl: i,
795
+ sha256: p(r, ["sha256"]) ?? p(t, ["sha256", "checksum"]),
796
+ source: p(t, ["source", "platform"])
797
+ };
798
+ }
799
+ function fs(t, s, e) {
800
+ let r;
801
+ try {
802
+ r = JSON.parse(t);
803
+ } catch (a) {
804
+ throw new Error(
805
+ `Search response is not valid JSON: ${a instanceof Error ? a.message : String(a)}`
806
+ );
807
+ }
808
+ if (!_(r))
809
+ throw new Error("Search API response must be a JSON object.");
810
+ let i = r.results;
811
+ if (!Array.isArray(i)) {
812
+ const a = _(r.data) ? r.data : void 0;
813
+ a && Array.isArray(a.records) && (i = a.records);
814
+ }
815
+ if (!Array.isArray(i))
816
+ throw new Error(
817
+ 'Search API response must include "results" or "data.records" array.'
818
+ );
819
+ 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
823
+ ).some(
824
+ (f) => f.toLowerCase().includes(o)
825
+ ) : !0);
826
+ return { query: e, results: l };
827
+ }
828
+ function ds(t) {
829
+ return async ({ query: s }) => {
830
+ const e = as(
831
+ t.config,
832
+ t.env,
833
+ s,
834
+ os
835
+ ), { payload: r, reference: i } = await ls(e);
836
+ return fs(r, i, s);
837
+ };
838
+ }
839
+ async function at(t, s) {
840
+ const e = [];
841
+ 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;
845
+ break;
846
+ }
847
+ if (n < 0)
848
+ throw new Error("Downloaded skill package is not a valid zip archive.");
849
+ const l = t.readUInt16LE(n + 10);
850
+ let a = t.readUInt32LE(n + 16);
851
+ await u.mkdir(s, { recursive: !0 });
852
+ for (let d = 0; d < l; d += 1) {
853
+ if (t.readUInt32LE(a) !== 33639248)
854
+ throw new Error(
855
+ "Downloaded skill package has an invalid zip central directory."
856
+ );
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(
858
+ "utf8",
859
+ a + 46,
860
+ a + 46 + H
861
+ );
862
+ a += 46 + H + ct + ut;
863
+ const g = S.replaceAll("\\", "/");
864
+ if (!g || g.startsWith("/") || g.includes("../"))
865
+ 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))
868
+ throw new Error(`Unsafe zip path entry detected: ${S}`);
869
+ if (t.readUInt32LE(v) !== 67324752)
870
+ throw new Error(
871
+ "Downloaded skill package has an invalid zip local header."
872
+ );
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
876
+ );
877
+ if (g.endsWith("/")) {
878
+ await u.mkdir(y, { recursive: !0 });
879
+ continue;
880
+ }
881
+ let D;
882
+ if (f === 0)
883
+ D = Buffer.from(T);
884
+ else if (f === 8)
885
+ D = Buffer.from(await is(T));
886
+ else
887
+ throw new Error(
888
+ `Unsupported zip compression method: ${f}`
889
+ );
890
+ if (D.length !== lt)
891
+ 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);
893
+ }
894
+ return e;
895
+ }
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 });
898
+ }
899
+ async function ps(t, s, e) {
900
+ if ((await u.stat(t)).isDirectory())
901
+ return await R(t, s), [];
902
+ const i = await u.readFile(t);
903
+ ot(i, e, t);
904
+ const o = await u.mkdtemp(
905
+ c.join(G.tmpdir(), "rrskill-registry-stage-")
906
+ );
907
+ try {
908
+ const n = await at(i, o);
909
+ return await R(o, s), n;
910
+ } finally {
911
+ await u.rm(o, { recursive: !0, force: !0 });
912
+ }
913
+ }
914
+ async function hs(t, s, e) {
915
+ const r = await fetch(t, {
916
+ headers: {
917
+ accept: "application/zip,application/octet-stream,*/*"
918
+ }
919
+ });
920
+ if (!r.ok)
921
+ throw new Error(
922
+ `Skill download failed: ${r.status} ${r.statusText}`
923
+ );
924
+ const i = Buffer.from(await r.arrayBuffer());
925
+ ot(i, e, t);
926
+ const o = await u.mkdtemp(
927
+ c.join(G.tmpdir(), "rrskill-registry-stage-")
928
+ );
929
+ try {
930
+ const n = await at(i, o);
931
+ return await R(o, s), n;
932
+ } finally {
933
+ await u.rm(o, { recursive: !0, force: !0 });
934
+ }
935
+ }
936
+ async function ms(t, s) {
937
+ const r = (await t({ query: s })).results.find((i) => i.slug === s);
938
+ if (!r)
939
+ throw new Error(`No exact registry match for slug "${s}"`);
940
+ return r;
941
+ }
942
+ async function gs(t, s) {
943
+ const e = s.registrySkill?.slug === s.slug ? s.registrySkill : await ms(t, s.slug), r = e.skillUrl;
944
+ if (!r)
945
+ throw new Error(
946
+ `Registry skill "${s.slug}" does not define a skillUrl/packageUrl`
947
+ );
948
+ const i = j(r), o = e.sha256, n = i?.protocol === "http:" || i?.protocol === "https:" ? await hs(
949
+ r,
950
+ s.targetDir,
951
+ o
952
+ ) : await ps(
953
+ i?.protocol === "file:" ? x(i) : c.resolve(r),
954
+ s.targetDir,
955
+ o
956
+ );
957
+ return {
958
+ slug: s.slug,
959
+ targetDir: s.targetDir,
960
+ writtenFiles: n,
961
+ version: e.version
962
+ };
963
+ }
964
+ function ks(t) {
965
+ return async (s) => gs(t, s);
966
+ }
967
+ class w extends Error {
968
+ code;
969
+ hint;
970
+ nextCommands;
971
+ constructor(s) {
972
+ super(s.message), this.code = s.code, this.hint = s.hint, this.nextCommands = s.nextCommands ?? [];
973
+ }
974
+ }
975
+ function ws() {
976
+ const t = process.argv[1] ?? "";
977
+ return t ? c.basename(t) === "rrskill.js" ? !0 : import.meta.url === `file://${t}` : !1;
978
+ }
979
+ function ys() {
980
+ return [
981
+ "rrskill CLI",
982
+ "",
983
+ "Usage:",
984
+ " rrskill <slug>",
985
+ " rrskill <command> [options]",
986
+ "",
987
+ "Commands:",
988
+ " rrskill <slug>",
989
+ " rrskill install <slug>",
990
+ " rrskill search <query>",
991
+ " rrskill list",
992
+ " rrskill upgrade",
993
+ " rrskill bootstrap --host <openclaw|codex|claude-code>",
994
+ " rrskill doctor --host <openclaw|codex|claude-code>",
995
+ " rrskill version",
996
+ "",
997
+ "Global options:",
998
+ " --host <name>",
999
+ " --openclaw",
1000
+ " --codex",
1001
+ " --claude-code",
1002
+ " --output <json|text>",
1003
+ " --json",
1004
+ " -h, --help",
1005
+ "",
1006
+ "Examples:",
1007
+ " rrskill doctor --host openclaw",
1008
+ " rrskill doctor --host openclaw --fix",
1009
+ " rrskill bootstrap --host openclaw",
1010
+ " rrskill search react",
1011
+ " rrskill install web-search --host codex"
1012
+ ].join(`
1013
+ `);
1014
+ }
1015
+ function vs(t) {
1016
+ const s = [
1017
+ "",
1018
+ "Global options:",
1019
+ " --host <name>",
1020
+ " --openclaw",
1021
+ " --codex",
1022
+ " --claude-code",
1023
+ " --output <json|text>",
1024
+ " --json"
1025
+ ];
1026
+ return t === "search" ? [
1027
+ "rrskill search",
1028
+ "",
1029
+ "Usage:",
1030
+ " rrskill search <query>",
1031
+ "",
1032
+ "Examples:",
1033
+ " rrskill search react",
1034
+ " rrskill search browser automation --host codex",
1035
+ ...s
1036
+ ].join(`
1037
+ `) : t === "install" ? [
1038
+ "rrskill install",
1039
+ "",
1040
+ "Usage:",
1041
+ " rrskill install <slug>",
1042
+ " rrskill <slug>",
1043
+ "",
1044
+ "Examples:",
1045
+ " rrskill install web-search",
1046
+ " rrskill web-search --host codex",
1047
+ ...s
1048
+ ].join(`
1049
+ `) : t === "list" ? [
1050
+ "rrskill list",
1051
+ "",
1052
+ "Usage:",
1053
+ " rrskill list",
1054
+ "",
1055
+ "Examples:",
1056
+ " rrskill list",
1057
+ " rrskill list --host claude-code",
1058
+ ...s
1059
+ ].join(`
1060
+ `) : t === "upgrade" ? [
1061
+ "rrskill upgrade",
1062
+ "",
1063
+ "Usage:",
1064
+ " rrskill upgrade",
1065
+ "",
1066
+ "Examples:",
1067
+ " rrskill upgrade",
1068
+ " rrskill upgrade --host codex",
1069
+ ...s
1070
+ ].join(`
1071
+ `) : t === "bootstrap" ? [
1072
+ "rrskill bootstrap",
1073
+ "",
1074
+ "Usage:",
1075
+ " rrskill bootstrap --host <openclaw|codex|claude-code>",
1076
+ "",
1077
+ "Examples:",
1078
+ " rrskill bootstrap --host openclaw",
1079
+ " rrskill bootstrap --openclaw",
1080
+ ...s
1081
+ ].join(`
1082
+ `) : t === "doctor" ? [
1083
+ "rrskill doctor",
1084
+ "",
1085
+ "Usage:",
1086
+ " rrskill doctor --host <openclaw|codex|claude-code> [--fix] [--dry-run]",
1087
+ "",
1088
+ "Options:",
1089
+ " --fix Attempt host repair when bootstrap support exists",
1090
+ " --dry-run Show the verification plan without making changes",
1091
+ "",
1092
+ "Examples:",
1093
+ " rrskill doctor --host openclaw",
1094
+ " rrskill doctor --host openclaw --fix",
1095
+ " rrskill doctor --host openclaw --dry-run --output json",
1096
+ ...s
1097
+ ].join(`
1098
+ `) : [
1099
+ "rrskill version",
1100
+ "",
1101
+ "Usage:",
1102
+ " rrskill version",
1103
+ "",
1104
+ "Examples:",
1105
+ " rrskill version",
1106
+ " rrskill version --output json",
1107
+ ...s
1108
+ ].join(`
1109
+ `);
1110
+ }
1111
+ function h(t) {
1112
+ process.stdout.write(`${JSON.stringify(t, null, 2)}
1113
+ `);
1114
+ }
1115
+ function L(t, ...s) {
1116
+ return t.some((e) => s.includes(e));
1117
+ }
1118
+ function Ss(t, s) {
1119
+ const e = t.indexOf(s);
1120
+ if (e < 0)
1121
+ return;
1122
+ const r = t[e + 1];
1123
+ if (!(!r || r.startsWith("--")))
1124
+ return r;
1125
+ }
1126
+ function Ds(t) {
1127
+ if (L(t, "--json"))
1128
+ return "json";
1129
+ const s = Ss(t, "--output");
1130
+ if (!s) {
1131
+ if (t.includes("--output"))
1132
+ throw new w({
1133
+ code: "missing_output_mode",
1134
+ message: "--output requires a value.",
1135
+ hint: "rrskill --output <json|text>",
1136
+ nextCommands: ["rrskill --help"]
1137
+ });
1138
+ return "text";
1139
+ }
1140
+ if (s === "json" || s === "text")
1141
+ return s;
1142
+ throw new w({
1143
+ code: "invalid_output_mode",
1144
+ message: `Unsupported output mode "${s}".`,
1145
+ hint: "rrskill --output <json|text>",
1146
+ nextCommands: ["rrskill --help"]
1147
+ });
1148
+ }
1149
+ function B(t, s) {
1150
+ if (t instanceof w && s === "json") {
1151
+ h({
1152
+ ok: !1,
1153
+ error: {
1154
+ code: t.code,
1155
+ message: t.message,
1156
+ hint: t.hint
1157
+ },
1158
+ next_commands: t.nextCommands
1159
+ });
1160
+ return;
1161
+ }
1162
+ if (t instanceof w) {
1163
+ const r = [`Error: ${t.message}`];
1164
+ if (t.hint && r.push(` ${t.hint}`), t.nextCommands.length > 0) {
1165
+ r.push("Next commands:");
1166
+ for (const i of t.nextCommands)
1167
+ r.push(` ${i}`);
1168
+ }
1169
+ process.stderr.write(`${r.join(`
1170
+ `)}
1171
+ `);
1172
+ return;
1173
+ }
1174
+ const e = t instanceof Error ? t.message : String(t);
1175
+ if (s === "json") {
1176
+ h({
1177
+ ok: !1,
1178
+ error: {
1179
+ code: "unexpected_error",
1180
+ message: e
1181
+ },
1182
+ next_commands: ["rrskill --help"]
1183
+ });
1184
+ return;
1185
+ }
1186
+ process.stderr.write(`${e}
1187
+ `);
1188
+ }
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,
1198
+ {
1199
+ fix: L(t, "--fix"),
1200
+ dryRun: L(t, "--dry-run")
1201
+ }
1202
+ );
1203
+ return h(a), a.ok ? 0 : 1;
1204
+ }
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;
1211
+ }
1212
+ if (s.command === "search") {
1213
+ const l = e.slice(1).join(" ").trim();
1214
+ if (!l)
1215
+ throw new w({
1216
+ code: "missing_search_query",
1217
+ message: "Search query is required.",
1218
+ hint: "rrskill search <query>",
1219
+ nextCommands: ["rrskill search react"]
1220
+ });
1221
+ const a = await ts(i, l, { searchSkills: o });
1222
+ return h(a), 0;
1223
+ }
1224
+ if (s.command === "install") {
1225
+ const l = "slug" in s ? s.slug : e[1]?.trim();
1226
+ if (!l)
1227
+ throw new w({
1228
+ code: "missing_skill_slug",
1229
+ message: "Skill slug is required.",
1230
+ hint: "rrskill install <slug>",
1231
+ nextCommands: ["rrskill install web-search"]
1232
+ });
1233
+ const a = await Xt(i, l, { searchSkills: o, downloadSkill: n });
1234
+ return h(a), 0;
1235
+ }
1236
+ if (s.command === "list") {
1237
+ const l = await Yt(i);
1238
+ return h(l), 0;
1239
+ }
1240
+ if (s.command === "upgrade") {
1241
+ const l = await ss(i, { downloadSkill: n });
1242
+ return h(l), 0;
1243
+ }
1244
+ return process.stderr.write(`Command "${s.command}" is not implemented yet.
1245
+ `), 1;
1246
+ }
1247
+ if (ws()) {
1248
+ const t = process.argv.slice(2);
1249
+ Es(t).then((s) => {
1250
+ process.exitCode = s;
1251
+ }).catch((s) => {
1252
+ let e = "text";
1253
+ try {
1254
+ e = Ds(t);
1255
+ } catch (r) {
1256
+ B(r, "text"), process.exitCode = 1;
1257
+ return;
1258
+ }
1259
+ B(s, e), process.exitCode = 1;
1260
+ });
1261
+ }
1262
+ export {
1263
+ Et as buildCliArgv
1264
+ };