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