@safeskill/cli 0.2.0 → 0.2.1
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/CHANGELOG.md +6 -0
- package/README.md +46 -43
- package/dist/cli.mjs +32 -13
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
- Added Flocks agent support with `.flocks/plugins/skills` install paths.
|
|
6
|
+
- Added hub resolve fallback for new or unsupported agent-specific resolve requests.
|
|
7
|
+
- Fixed zip artifact extraction when packages contain explicit directory entries.
|
|
8
|
+
|
|
3
9
|
## 0.0.1
|
|
4
10
|
|
|
5
11
|
- Renamed the published package and CLI command from `skills` to `safeskill`.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ The SafeSkill CLI for the open agent skills ecosystem.
|
|
|
6
6
|
|
|
7
7
|
<!-- agent-list:start -->
|
|
8
8
|
|
|
9
|
-
Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [
|
|
9
|
+
Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [41 more](#available-agents).
|
|
10
10
|
|
|
11
11
|
<!-- agent-list:end -->
|
|
12
12
|
|
|
@@ -238,48 +238,49 @@ Skills can be installed to any of these agents:
|
|
|
238
238
|
|
|
239
239
|
<!-- supported-agents:start -->
|
|
240
240
|
|
|
241
|
-
| Agent | `--agent` | Project Path
|
|
242
|
-
| ------------------------------------- | ---------------------------------------- |
|
|
243
|
-
| Amp, Kimi Code CLI, Replit, Universal | `amp`, `kimi-cli`, `replit`, `universal` | `.agents/skills/`
|
|
244
|
-
| Antigravity | `antigravity` | `.agents/skills/`
|
|
245
|
-
| Augment | `augment` | `.augment/skills/`
|
|
246
|
-
| Claude Code | `claude-code` | `.claude/skills/`
|
|
247
|
-
| OpenClaw | `openclaw` | `skills/`
|
|
248
|
-
| Cline, Warp | `cline`, `warp` | `.agents/skills/`
|
|
249
|
-
| CodeBuddy | `codebuddy` | `.codebuddy/skills/`
|
|
250
|
-
| Codex | `codex` | `.agents/skills/`
|
|
251
|
-
| Command Code | `command-code` | `.commandcode/skills/`
|
|
252
|
-
| Continue | `continue` | `.continue/skills/`
|
|
253
|
-
| Cortex Code | `cortex` | `.cortex/skills/`
|
|
254
|
-
| Crush | `crush` | `.crush/skills/`
|
|
255
|
-
| Cursor | `cursor` | `.agents/skills/`
|
|
256
|
-
| Deep Agents | `deepagents` | `.agents/skills/`
|
|
257
|
-
| Droid | `droid` | `.factory/skills/`
|
|
258
|
-
| Firebender | `firebender` | `.agents/skills/`
|
|
259
|
-
|
|
|
260
|
-
|
|
|
261
|
-
|
|
|
262
|
-
|
|
|
263
|
-
|
|
|
264
|
-
|
|
|
265
|
-
|
|
|
266
|
-
|
|
|
267
|
-
|
|
|
268
|
-
|
|
|
269
|
-
|
|
|
270
|
-
|
|
|
271
|
-
|
|
|
272
|
-
|
|
|
273
|
-
|
|
|
274
|
-
|
|
|
275
|
-
|
|
|
276
|
-
|
|
|
277
|
-
| Trae
|
|
278
|
-
|
|
|
279
|
-
|
|
|
280
|
-
|
|
|
281
|
-
|
|
|
282
|
-
|
|
|
241
|
+
| Agent | `--agent` | Project Path | Global Path |
|
|
242
|
+
| ------------------------------------- | ---------------------------------------- | ------------------------- | ---------------------------------- |
|
|
243
|
+
| Amp, Kimi Code CLI, Replit, Universal | `amp`, `kimi-cli`, `replit`, `universal` | `.agents/skills/` | `~/.config/agents/skills/` |
|
|
244
|
+
| Antigravity | `antigravity` | `.agents/skills/` | `~/.gemini/antigravity/skills/` |
|
|
245
|
+
| Augment | `augment` | `.augment/skills/` | `~/.augment/skills/` |
|
|
246
|
+
| Claude Code | `claude-code` | `.claude/skills/` | `~/.claude/skills/` |
|
|
247
|
+
| OpenClaw | `openclaw` | `skills/` | `~/.openclaw/skills/` |
|
|
248
|
+
| Cline, Warp | `cline`, `warp` | `.agents/skills/` | `~/.agents/skills/` |
|
|
249
|
+
| CodeBuddy | `codebuddy` | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
|
|
250
|
+
| Codex | `codex` | `.agents/skills/` | `~/.codex/skills/` |
|
|
251
|
+
| Command Code | `command-code` | `.commandcode/skills/` | `~/.commandcode/skills/` |
|
|
252
|
+
| Continue | `continue` | `.continue/skills/` | `~/.continue/skills/` |
|
|
253
|
+
| Cortex Code | `cortex` | `.cortex/skills/` | `~/.snowflake/cortex/skills/` |
|
|
254
|
+
| Crush | `crush` | `.crush/skills/` | `~/.config/crush/skills/` |
|
|
255
|
+
| Cursor | `cursor` | `.agents/skills/` | `~/.cursor/skills/` |
|
|
256
|
+
| Deep Agents | `deepagents` | `.agents/skills/` | `~/.deepagents/agent/skills/` |
|
|
257
|
+
| Droid | `droid` | `.factory/skills/` | `~/.factory/skills/` |
|
|
258
|
+
| Firebender | `firebender` | `.agents/skills/` | `~/.firebender/skills/` |
|
|
259
|
+
| Flocks | `flocks` | `.flocks/plugins/skills/` | `~/.flocks/plugins/skills/` |
|
|
260
|
+
| Gemini CLI | `gemini-cli` | `.agents/skills/` | `~/.gemini/skills/` |
|
|
261
|
+
| GitHub Copilot | `github-copilot` | `.agents/skills/` | `~/.copilot/skills/` |
|
|
262
|
+
| Goose | `goose` | `.goose/skills/` | `~/.config/goose/skills/` |
|
|
263
|
+
| Junie | `junie` | `.junie/skills/` | `~/.junie/skills/` |
|
|
264
|
+
| iFlow CLI | `iflow-cli` | `.iflow/skills/` | `~/.iflow/skills/` |
|
|
265
|
+
| Kilo Code | `kilo` | `.kilocode/skills/` | `~/.kilocode/skills/` |
|
|
266
|
+
| Kiro CLI | `kiro-cli` | `.kiro/skills/` | `~/.kiro/skills/` |
|
|
267
|
+
| Kode | `kode` | `.kode/skills/` | `~/.kode/skills/` |
|
|
268
|
+
| MCPJam | `mcpjam` | `.mcpjam/skills/` | `~/.mcpjam/skills/` |
|
|
269
|
+
| Mistral Vibe | `mistral-vibe` | `.vibe/skills/` | `~/.vibe/skills/` |
|
|
270
|
+
| Mux | `mux` | `.mux/skills/` | `~/.mux/skills/` |
|
|
271
|
+
| OpenCode | `opencode` | `.agents/skills/` | `~/.config/opencode/skills/` |
|
|
272
|
+
| OpenHands | `openhands` | `.openhands/skills/` | `~/.openhands/skills/` |
|
|
273
|
+
| Pi | `pi` | `.pi/skills/` | `~/.pi/agent/skills/` |
|
|
274
|
+
| Qoder | `qoder` | `.qoder/skills/` | `~/.qoder/skills/` |
|
|
275
|
+
| Qwen Code | `qwen-code` | `.qwen/skills/` | `~/.qwen/skills/` |
|
|
276
|
+
| Roo Code | `roo` | `.roo/skills/` | `~/.roo/skills/` |
|
|
277
|
+
| Trae | `trae` | `.trae/skills/` | `~/.trae/skills/` |
|
|
278
|
+
| Trae CN | `trae-cn` | `.trae/skills/` | `~/.trae-cn/skills/` |
|
|
279
|
+
| Windsurf | `windsurf` | `.windsurf/skills/` | `~/.codeium/windsurf/skills/` |
|
|
280
|
+
| Zencoder | `zencoder` | `.zencoder/skills/` | `~/.zencoder/skills/` |
|
|
281
|
+
| Neovate | `neovate` | `.neovate/skills/` | `~/.neovate/skills/` |
|
|
282
|
+
| Pochi | `pochi` | `.pochi/skills/` | `~/.pochi/skills/` |
|
|
283
|
+
| AdaL | `adal` | `.adal/skills/` | `~/.adal/skills/` |
|
|
283
284
|
|
|
284
285
|
<!-- supported-agents:end -->
|
|
285
286
|
|
|
@@ -361,6 +362,7 @@ The CLI searches for skills in these locations within a repository:
|
|
|
361
362
|
- `.cortex/skills/`
|
|
362
363
|
- `.crush/skills/`
|
|
363
364
|
- `.factory/skills/`
|
|
365
|
+
- `.flocks/plugins/skills/`
|
|
364
366
|
- `.goose/skills/`
|
|
365
367
|
- `.junie/skills/`
|
|
366
368
|
- `.iflow/skills/`
|
|
@@ -381,6 +383,7 @@ The CLI searches for skills in these locations within a repository:
|
|
|
381
383
|
- `.neovate/skills/`
|
|
382
384
|
- `.pochi/skills/`
|
|
383
385
|
- `.adal/skills/`
|
|
386
|
+
|
|
384
387
|
<!-- skill-discovery:end -->
|
|
385
388
|
|
|
386
389
|
### Plugin Manifest Discovery
|
package/dist/cli.mjs
CHANGED
|
@@ -607,9 +607,7 @@ async function extractDownloadedArtifact(destination, fileName, bytes) {
|
|
|
607
607
|
import_yauzl.open(tempZipPath, {
|
|
608
608
|
lazyEntries: true,
|
|
609
609
|
strictFileNames: false,
|
|
610
|
-
decodeStrings: true
|
|
611
|
-
encoding,
|
|
612
|
-
validateEntryNames: false
|
|
610
|
+
decodeStrings: true
|
|
613
611
|
}, (err, zipfile) => {
|
|
614
612
|
if (err) {
|
|
615
613
|
reject(err);
|
|
@@ -617,16 +615,22 @@ async function extractDownloadedArtifact(destination, fileName, bytes) {
|
|
|
617
615
|
}
|
|
618
616
|
const processedFiles = /* @__PURE__ */ new Set();
|
|
619
617
|
zipfile.on("entry", (entry) => {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
}
|
|
624
|
-
let fileName = entry.fileName;
|
|
625
|
-
fileName = fileName.replace(/[^\w\-._/\\]/g, (char) => {
|
|
618
|
+
let fileName = entry.fileName.replace(/\\/g, "/");
|
|
619
|
+
const isDirectoryEntry = fileName.endsWith("/");
|
|
620
|
+
fileName = fileName.replace(/[^\w\-._/]/g, (char) => {
|
|
626
621
|
const code = char.charCodeAt(0);
|
|
627
622
|
if (code < 32 || code > 126) return "_";
|
|
628
623
|
return char;
|
|
629
624
|
});
|
|
625
|
+
if (isDirectoryEntry) {
|
|
626
|
+
const directoryName = fileName.replace(/\/+$/, "");
|
|
627
|
+
if (!directoryName) {
|
|
628
|
+
zipfile.readEntry();
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
mkdir(join(destination, directoryName), { recursive: true }).then(() => zipfile.readEntry()).catch(reject);
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
630
634
|
if (processedFiles.has(fileName)) {
|
|
631
635
|
zipfile.readEntry();
|
|
632
636
|
return;
|
|
@@ -720,14 +724,19 @@ async function searchSkillsCatalog(query, limit = 10) {
|
|
|
720
724
|
}
|
|
721
725
|
}
|
|
722
726
|
async function resolveHubSkill(source, agent) {
|
|
723
|
-
const
|
|
724
|
-
const
|
|
727
|
+
const resolveUrl = buildApiUrl(await getSafeSkillHubBaseUrl(), "/resolve");
|
|
728
|
+
const resolveWithAgent = agent ? await fetch(resolveUrl, {
|
|
725
729
|
method: "POST",
|
|
726
730
|
headers: getHeaders({ "content-type": "application/json" }),
|
|
727
731
|
body: JSON.stringify({
|
|
728
732
|
source,
|
|
729
|
-
|
|
733
|
+
agent
|
|
730
734
|
})
|
|
735
|
+
}) : null;
|
|
736
|
+
const response = resolveWithAgent && resolveWithAgent.ok ? resolveWithAgent : await fetch(resolveUrl, {
|
|
737
|
+
method: "POST",
|
|
738
|
+
headers: getHeaders({ "content-type": "application/json" }),
|
|
739
|
+
body: JSON.stringify({ source })
|
|
731
740
|
});
|
|
732
741
|
if (!response.ok) throw new Error(`hub resolve failed: ${response.status}`);
|
|
733
742
|
return readEnvelope(response);
|
|
@@ -1167,6 +1176,15 @@ const agents = {
|
|
|
1167
1176
|
return existsSync(join(home, ".firebender"));
|
|
1168
1177
|
}
|
|
1169
1178
|
},
|
|
1179
|
+
flocks: {
|
|
1180
|
+
name: "flocks",
|
|
1181
|
+
displayName: "Flocks",
|
|
1182
|
+
skillsDir: ".flocks/plugins/skills",
|
|
1183
|
+
globalSkillsDir: join(home, ".flocks/plugins/skills"),
|
|
1184
|
+
detectInstalled: async () => {
|
|
1185
|
+
return existsSync(join(home, ".flocks"));
|
|
1186
|
+
}
|
|
1187
|
+
},
|
|
1170
1188
|
"gemini-cli": {
|
|
1171
1189
|
name: "gemini-cli",
|
|
1172
1190
|
displayName: "Gemini CLI",
|
|
@@ -1440,6 +1458,7 @@ const SKILLS_SUBDIR = "skills";
|
|
|
1440
1458
|
function sanitizeName(name) {
|
|
1441
1459
|
const asciiName = name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "");
|
|
1442
1460
|
if (asciiName.length === 0) {
|
|
1461
|
+
if (!/[\p{L}\p{N}]/u.test(name)) return "unnamed-skill";
|
|
1443
1462
|
let hash = 0;
|
|
1444
1463
|
for (let i = 0; i < name.length; i++) {
|
|
1445
1464
|
const char = name.charCodeAt(i);
|
|
@@ -2259,7 +2278,7 @@ function createEmptyLocalLock() {
|
|
|
2259
2278
|
skills: {}
|
|
2260
2279
|
};
|
|
2261
2280
|
}
|
|
2262
|
-
var version$1 = "0.2.
|
|
2281
|
+
var version$1 = "0.2.1";
|
|
2263
2282
|
const isCancelled$1 = (value) => typeof value === "symbol";
|
|
2264
2283
|
async function isSourcePrivate(source) {
|
|
2265
2284
|
const ownerRepo = parseOwnerRepo(source);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@safeskill/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "SafeSkill CLI, for safe your skills",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"deepagents",
|
|
52
52
|
"droid",
|
|
53
53
|
"firebender",
|
|
54
|
+
"flocks",
|
|
54
55
|
"gemini-cli",
|
|
55
56
|
"github-copilot",
|
|
56
57
|
"goose",
|