@agent-native/skills 0.2.11 → 0.2.13
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/README.md +5 -4
- package/dist/connect.d.ts +5 -6
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +52 -12
- package/dist/connect.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +125 -27
- package/dist/index.js.map +1 -1
- package/dist/mcp-config-writers.d.ts +32 -21
- package/dist/mcp-config-writers.d.ts.map +1 -1
- package/dist/mcp-config-writers.js +166 -23
- package/dist/mcp-config-writers.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -15,7 +15,8 @@ Usage:
|
|
|
15
15
|
|
|
16
16
|
Options:
|
|
17
17
|
--skill <name> Install only this skill (repeatable)
|
|
18
|
-
--client, -a <client> codex, claude-code,
|
|
18
|
+
--client, -a <client> codex, claude-code, cowork, pi, cursor, opencode, github-copilot, or all
|
|
19
|
+
(default: all; repeatable or comma-separated)
|
|
19
20
|
--scope <user|project> Install globally or into the current project (default: user)
|
|
20
21
|
-g, --global Alias for --scope user
|
|
21
22
|
--project Alias for --scope project
|
|
@@ -32,9 +33,9 @@ Options:
|
|
|
32
33
|
--dry-run Print intended writes without changing files
|
|
33
34
|
--json Print the result as JSON
|
|
34
35
|
|
|
35
|
-
App-backed skills (visual-plan, visual-recap
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
App-backed skills (visual-plan, visual-recap) register their hosted MCP server
|
|
37
|
+
in your agent config by default so the agent can actually use them. Use
|
|
38
|
+
--no-mcp to skip that and copy the files only.
|
|
38
39
|
For visual-plan/visual-recap, choose --mode local-files for no sharing and all
|
|
39
40
|
local files, or --mode self-hosted --mcp-url <url> for your own Plan app.
|
|
40
41
|
|
|
@@ -43,7 +44,15 @@ Examples:
|
|
|
43
44
|
npx @agent-native/skills@latest add --skill quick-recap
|
|
44
45
|
npx @agent-native/skills@latest add --skill visual-recap --with-github-action
|
|
45
46
|
`;
|
|
46
|
-
const CLIENTS = [
|
|
47
|
+
const CLIENTS = [
|
|
48
|
+
"codex",
|
|
49
|
+
"claude-code",
|
|
50
|
+
"cowork",
|
|
51
|
+
"pi",
|
|
52
|
+
"cursor",
|
|
53
|
+
"opencode",
|
|
54
|
+
"github-copilot",
|
|
55
|
+
];
|
|
47
56
|
const DEFAULT_SKILLS_SOURCE = "BuilderIO/skills";
|
|
48
57
|
const MANAGED_INSTRUCTIONS_START = "<!-- BEGIN @agent-native/skills -->";
|
|
49
58
|
const MANAGED_INSTRUCTIONS_END = "<!-- END @agent-native/skills -->";
|
|
@@ -110,6 +119,8 @@ export function parseSkillsCliArgs(argv) {
|
|
|
110
119
|
out.dryRun = true;
|
|
111
120
|
else if (arg === "--json")
|
|
112
121
|
out.printJson = true;
|
|
122
|
+
else if (arg === "--quiet")
|
|
123
|
+
out.quiet = true;
|
|
113
124
|
else if (arg === "--update-instructions")
|
|
114
125
|
out.updateInstructions = true;
|
|
115
126
|
else if (arg === "--no-update-instructions")
|
|
@@ -227,6 +238,11 @@ function shouldLoadPublicCatalog(parsed) {
|
|
|
227
238
|
return true;
|
|
228
239
|
return parsed.skillNames.some((name) => !resolveAppForSkill(name));
|
|
229
240
|
}
|
|
241
|
+
const HIDDEN_STANDALONE_BUILT_INS = [
|
|
242
|
+
"assets",
|
|
243
|
+
"design-exploration",
|
|
244
|
+
"context-xray",
|
|
245
|
+
];
|
|
230
246
|
export async function runSkillsCli(argv, options = {}) {
|
|
231
247
|
const parsed = parseSkillsCliArgs(argv);
|
|
232
248
|
// `@agent-native/skills` normally uses the exact same core flow as
|
|
@@ -255,6 +271,7 @@ export async function runSkillsCli(argv, options = {}) {
|
|
|
255
271
|
isInteractive: options.isInteractive,
|
|
256
272
|
baseDir: parsed.baseDir ?? options.baseDir,
|
|
257
273
|
catalogMode: "all",
|
|
274
|
+
hiddenBuiltInSkillTargets: HIDDEN_STANDALONE_BUILT_INS,
|
|
258
275
|
publicSkillSource: loadedSource?.root ?? parsed.source ?? DEFAULT_SKILLS_SOURCE,
|
|
259
276
|
publicSkillEntries,
|
|
260
277
|
promptSkills: options.promptSkills
|
|
@@ -268,6 +285,8 @@ export async function runSkillsCli(argv, options = {}) {
|
|
|
268
285
|
promptGithubAction: options.promptGithubAction
|
|
269
286
|
? async (context) => options.promptGithubAction?.({
|
|
270
287
|
workflowPath: context.workflowPath,
|
|
288
|
+
setupCommand: context.setupCommand,
|
|
289
|
+
docsUrl: context.docsUrl,
|
|
271
290
|
}) ?? null
|
|
272
291
|
: undefined,
|
|
273
292
|
promptPlanMode: options.promptPlanMode,
|
|
@@ -333,8 +352,8 @@ export async function runSkillsCli(argv, options = {}) {
|
|
|
333
352
|
withGithubAction: parsed.withGithubAction,
|
|
334
353
|
force: parsed.force,
|
|
335
354
|
connect: parsed.connect,
|
|
336
|
-
quiet: parsed.printJson,
|
|
337
|
-
log: parsed.printJson ? undefined : stdoutLog,
|
|
355
|
+
quiet: parsed.printJson || parsed.quiet,
|
|
356
|
+
log: parsed.printJson || parsed.quiet ? undefined : stdoutLog,
|
|
338
357
|
isInteractive: options.isInteractive,
|
|
339
358
|
promptSkills: options.promptSkills,
|
|
340
359
|
promptClients: options.promptClients,
|
|
@@ -359,6 +378,8 @@ export async function runSkillsCli(argv, options = {}) {
|
|
|
359
378
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
360
379
|
return;
|
|
361
380
|
}
|
|
381
|
+
if (parsed.quiet)
|
|
382
|
+
return;
|
|
362
383
|
await printInstallResult(result, {
|
|
363
384
|
baseDir: parsed.baseDir ?? options.baseDir ?? process.cwd(),
|
|
364
385
|
dryRun: parsed.dryRun,
|
|
@@ -426,11 +447,14 @@ export async function installSkills(options) {
|
|
|
426
447
|
options.telemetry?.track("skills_cli scope selected", { scope });
|
|
427
448
|
const instructionBlocks = managedInstructionBlocksForSkills(skillNames);
|
|
428
449
|
const shouldUpdateInstructions = await shouldUpdateManagedInstructions(instructionBlocks, options);
|
|
429
|
-
const shouldWriteGithubAction = selected.some((skill) => skill.name === "visual-recap")
|
|
430
|
-
shouldWritePrVisualRecapWorkflow(options, baseDir);
|
|
450
|
+
const shouldWriteGithubAction = await shouldWritePrVisualRecapWorkflow(selected.some((skill) => skill.name === "visual-recap"), options, baseDir);
|
|
431
451
|
const mcpApps = options.mcp === false || planMode === "local-files"
|
|
432
452
|
? []
|
|
433
453
|
: mcpAppsForSkills(skillNames, planMcpOverride);
|
|
454
|
+
const skillFileClients = clients.filter(supportsSkillFiles);
|
|
455
|
+
if (skillFileClients.length === 0 && mcpApps.length === 0) {
|
|
456
|
+
throw new Error("Claude Cowork is MCP-only for Agent Native skills. Choose Codex, Claude Code, Pi, Cursor, OpenCode, or GitHub Copilot for local skill files, or install an app-backed skill with MCP enabled.");
|
|
457
|
+
}
|
|
434
458
|
const progress = await createInstallProgress(options, 1 +
|
|
435
459
|
(shouldUpdateInstructions ? 1 : 0) +
|
|
436
460
|
(shouldWriteGithubAction ? 1 : 0) +
|
|
@@ -441,8 +465,7 @@ export async function installSkills(options) {
|
|
|
441
465
|
const mcpServers = [];
|
|
442
466
|
try {
|
|
443
467
|
progress?.start("Installing skill files...");
|
|
444
|
-
for (const
|
|
445
|
-
const root = installRootForClient(client, scope, baseDir);
|
|
468
|
+
for (const root of unique(skillFileClients.map((client) => installRootForClient(client, scope, baseDir)))) {
|
|
446
469
|
for (const skill of selected) {
|
|
447
470
|
const destination = path.join(root, skill.name);
|
|
448
471
|
written.push(destination);
|
|
@@ -463,7 +486,7 @@ export async function installSkills(options) {
|
|
|
463
486
|
});
|
|
464
487
|
if (shouldUpdateInstructions) {
|
|
465
488
|
progress?.message("Updating managed instructions...");
|
|
466
|
-
instructionFiles = writeManagedInstructions(instructionBlocks, baseDir,
|
|
489
|
+
instructionFiles = writeManagedInstructions(instructionBlocks, baseDir, skillFileClients, scope, options);
|
|
467
490
|
progress?.advance("Managed instructions updated");
|
|
468
491
|
if (instructionFiles.length) {
|
|
469
492
|
options.telemetry?.track("skills_cli instructions updated", {
|
|
@@ -480,12 +503,17 @@ export async function installSkills(options) {
|
|
|
480
503
|
}
|
|
481
504
|
}
|
|
482
505
|
// Register the hosted MCP server for app-backed skills (visual-plan /
|
|
483
|
-
// visual-recap → Agent-Native Plan
|
|
484
|
-
//
|
|
485
|
-
//
|
|
486
|
-
//
|
|
506
|
+
// visual-recap → Agent-Native Plan) so the agent can actually call them,
|
|
507
|
+
// not just read the SKILL.md. On by default; `--no-mcp` installs the
|
|
508
|
+
// skill files only. One registration per app, so visual-plan +
|
|
509
|
+
// visual-recap share a single "plan" server.
|
|
487
510
|
if (mcpApps.length > 0) {
|
|
488
|
-
const mcpClients = clients
|
|
511
|
+
const mcpClients = clients
|
|
512
|
+
.map(skillClientToMcpClient)
|
|
513
|
+
.filter((client) => Boolean(client));
|
|
514
|
+
if (mcpClients.length === 0) {
|
|
515
|
+
throw new Error("MCP setup supports Claude Code, Codex, Cursor, OpenCode, GitHub Copilot / VS Code, or Claude Cowork. Use --mode local-files or --no-mcp for Pi.");
|
|
516
|
+
}
|
|
489
517
|
for (const app of mcpApps) {
|
|
490
518
|
progress?.message(`Registering ${app.displayName} MCP server...`);
|
|
491
519
|
if (!options.dryRun) {
|
|
@@ -574,6 +602,7 @@ function defaultArgs(command) {
|
|
|
574
602
|
force: false,
|
|
575
603
|
connect: true,
|
|
576
604
|
mcp: true,
|
|
605
|
+
quiet: false,
|
|
577
606
|
};
|
|
578
607
|
}
|
|
579
608
|
function selectedPlanApp(skillNames) {
|
|
@@ -651,14 +680,40 @@ function normalizeClients(value) {
|
|
|
651
680
|
return CLIENTS;
|
|
652
681
|
if (client === "codex")
|
|
653
682
|
return ["codex"];
|
|
683
|
+
if (client === "cowork" || client === "claude-cowork") {
|
|
684
|
+
return ["cowork"];
|
|
685
|
+
}
|
|
686
|
+
if (client === "pi")
|
|
687
|
+
return ["pi"];
|
|
688
|
+
if (client === "cursor")
|
|
689
|
+
return ["cursor"];
|
|
690
|
+
if (client === "opencode" || client === "open-code") {
|
|
691
|
+
return ["opencode"];
|
|
692
|
+
}
|
|
693
|
+
if (client === "github-copilot" ||
|
|
694
|
+
client === "copilot" ||
|
|
695
|
+
client === "vscode" ||
|
|
696
|
+
client === "vs-code") {
|
|
697
|
+
return ["github-copilot"];
|
|
698
|
+
}
|
|
654
699
|
if (client === "claude" ||
|
|
655
700
|
client === "claude-code" ||
|
|
656
701
|
client === "claude-code-cli") {
|
|
657
702
|
return ["claude-code"];
|
|
658
703
|
}
|
|
659
|
-
throw new Error(`Unsupported client "${raw}". Use codex, claude-code, or all.`);
|
|
704
|
+
throw new Error(`Unsupported client "${raw}". Use codex, claude-code, cowork, pi, cursor, opencode, github-copilot, or all.`);
|
|
660
705
|
});
|
|
661
706
|
}
|
|
707
|
+
function skillClientToMcpClient(client) {
|
|
708
|
+
if (client === "pi")
|
|
709
|
+
return null;
|
|
710
|
+
if (client === "claude-code")
|
|
711
|
+
return "claude-code";
|
|
712
|
+
return client;
|
|
713
|
+
}
|
|
714
|
+
function supportsSkillFiles(client) {
|
|
715
|
+
return client !== "cowork";
|
|
716
|
+
}
|
|
662
717
|
function normalizeSkillName(value) {
|
|
663
718
|
const normalized = value.trim().toLowerCase();
|
|
664
719
|
if (!/^[a-z0-9][a-z0-9._-]*$/.test(normalized)) {
|
|
@@ -840,15 +895,24 @@ function isInteractive(options) {
|
|
|
840
895
|
function installRootForClient(client, scope, baseDir) {
|
|
841
896
|
const home = process.env.HOME || os.homedir();
|
|
842
897
|
if (scope === "project") {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
898
|
+
if (client !== "claude-code") {
|
|
899
|
+
return path.join(baseDir, ".agents", "skills");
|
|
900
|
+
}
|
|
901
|
+
return path.join(baseDir, ".claude", "skills");
|
|
846
902
|
}
|
|
847
903
|
if (client === "codex") {
|
|
848
904
|
return process.env.CODEX_HOME
|
|
849
905
|
? path.join(process.env.CODEX_HOME, "skills")
|
|
850
906
|
: path.join(home, ".codex", "skills");
|
|
851
907
|
}
|
|
908
|
+
if (client === "pi") {
|
|
909
|
+
return path.join(home, ".agents", "skills");
|
|
910
|
+
}
|
|
911
|
+
if (client === "cursor" ||
|
|
912
|
+
client === "opencode" ||
|
|
913
|
+
client === "github-copilot") {
|
|
914
|
+
return path.join(home, ".agents", "skills");
|
|
915
|
+
}
|
|
852
916
|
return path.join(home, ".claude", "skills");
|
|
853
917
|
}
|
|
854
918
|
function discoverSkills(root) {
|
|
@@ -1055,14 +1119,17 @@ function resolveInstructionFiles(baseDir, explicit, clients, scope) {
|
|
|
1055
1119
|
if (explicit && explicit.length > 0) {
|
|
1056
1120
|
return explicit.map((file) => path.resolve(baseDir, file));
|
|
1057
1121
|
}
|
|
1122
|
+
const instructionClients = clients.filter(supportsSkillFiles);
|
|
1123
|
+
if (instructionClients.length === 0)
|
|
1124
|
+
return [];
|
|
1058
1125
|
if (scope === "user") {
|
|
1059
1126
|
const home = process.env.HOME || os.homedir();
|
|
1060
1127
|
const files = [];
|
|
1061
|
-
if (
|
|
1128
|
+
if (instructionClients.includes("codex")) {
|
|
1062
1129
|
const codexHome = process.env.CODEX_HOME || path.join(home, ".codex");
|
|
1063
1130
|
files.push(path.join(codexHome, "AGENTS.md"));
|
|
1064
1131
|
}
|
|
1065
|
-
if (
|
|
1132
|
+
if (instructionClients.includes("claude-code")) {
|
|
1066
1133
|
files.push(path.join(home, ".claude", "CLAUDE.md"));
|
|
1067
1134
|
}
|
|
1068
1135
|
return unique(files);
|
|
@@ -1083,13 +1150,44 @@ function upsertManagedBlock(file, block) {
|
|
|
1083
1150
|
function escapeRegExp(value) {
|
|
1084
1151
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1085
1152
|
}
|
|
1086
|
-
|
|
1153
|
+
const PR_VISUAL_RECAP_DOCS_URL = "https://www.agent-native.com/docs/pr-visual-recap";
|
|
1154
|
+
function prVisualRecapWorkflowPath(baseDir) {
|
|
1155
|
+
return path.join(baseDir, ".github", "workflows", "pr-visual-recap.yml");
|
|
1156
|
+
}
|
|
1157
|
+
function prVisualRecapSetupCommand() {
|
|
1158
|
+
return "npx @agent-native/core@latest recap setup";
|
|
1159
|
+
}
|
|
1160
|
+
async function promptForGithubAction(context) {
|
|
1161
|
+
const clack = await import("@clack/prompts");
|
|
1162
|
+
const result = await clack.confirm({
|
|
1163
|
+
message: "Optional: add automatic PR Visual Recaps? (GitHub Action)\n" +
|
|
1164
|
+
" Posts a human-friendly recap on every pull request.\n" +
|
|
1165
|
+
` Learn more: ${context.docsUrl}\n` +
|
|
1166
|
+
` Writes ${context.workflowPath}; ${context.setupCommand} finishes the GitHub secrets.`,
|
|
1167
|
+
initialValue: false,
|
|
1168
|
+
});
|
|
1169
|
+
if (clack.isCancel(result)) {
|
|
1170
|
+
clack.cancel("Skipped PR Visual Recap workflow.");
|
|
1171
|
+
return null;
|
|
1172
|
+
}
|
|
1173
|
+
return Boolean(result);
|
|
1174
|
+
}
|
|
1175
|
+
async function shouldWritePrVisualRecapWorkflow(hasVisualRecap, options, baseDir) {
|
|
1176
|
+
if (!hasVisualRecap)
|
|
1177
|
+
return false;
|
|
1087
1178
|
if (options.withGithubAction)
|
|
1088
1179
|
return true;
|
|
1089
|
-
if (fs.existsSync(
|
|
1180
|
+
if (fs.existsSync(prVisualRecapWorkflowPath(baseDir)))
|
|
1090
1181
|
return false;
|
|
1091
|
-
|
|
1092
|
-
|
|
1182
|
+
if (options.yes || !isInteractive(options))
|
|
1183
|
+
return false;
|
|
1184
|
+
const prompt = options.promptGithubAction ?? promptForGithubAction;
|
|
1185
|
+
const choice = await prompt({
|
|
1186
|
+
workflowPath: path.join(".github", "workflows", "pr-visual-recap.yml"),
|
|
1187
|
+
setupCommand: prVisualRecapSetupCommand(),
|
|
1188
|
+
docsUrl: PR_VISUAL_RECAP_DOCS_URL,
|
|
1189
|
+
});
|
|
1190
|
+
return choice === true;
|
|
1093
1191
|
}
|
|
1094
1192
|
const PR_VISUAL_RECAP_REUSABLE_WORKFLOW = `name: PR Visual Recap
|
|
1095
1193
|
|