@agent-native/core 0.51.10 → 0.51.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/dist/cli/connect.d.ts +3 -0
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +17 -7
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/skills.d.ts +25 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +397 -69
- package/dist/cli/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/skills.js
CHANGED
|
@@ -45,16 +45,16 @@ Examples:
|
|
|
45
45
|
The add command installs the SKILL.md instructions, registers the app-backed
|
|
46
46
|
MCP connector, and then authenticates it in one step so you do not hit an OAuth
|
|
47
47
|
wall on the first tool call. By default, add targets every supported local
|
|
48
|
-
client this CLI can configure (Claude Code,
|
|
48
|
+
client this CLI can configure (Claude Code, Codex, and Cowork);
|
|
49
49
|
pass --client to narrow it. Authentication reuses "npx @agent-native/core@latest connect":
|
|
50
50
|
OAuth-capable clients (Claude Code) get a URL-only entry and a /mcp authenticate
|
|
51
51
|
prompt, while Codex / Cowork run the browser device-code flow. In a
|
|
52
52
|
non-interactive shell or CI the auth step is skipped and the exact
|
|
53
53
|
"npx @agent-native/core@latest connect <url> --client all" command is printed instead.
|
|
54
54
|
|
|
55
|
-
Running "npx @agent-native/skills@latest add ..."
|
|
56
|
-
|
|
57
|
-
register
|
|
55
|
+
Running "npx @agent-native/skills@latest add ..." uses this same shared install
|
|
56
|
+
flow with the broader BuilderIO skills catalog enabled. Pass --no-connect to
|
|
57
|
+
register MCP where possible without authenticating (leave auth to the host or run
|
|
58
58
|
"npx @agent-native/core@latest connect" later). Pass --mcp-url to register that connector against
|
|
59
59
|
a custom origin (an ngrok tunnel, a local dev server, or a self-hosted
|
|
60
60
|
deployment) instead of the built-in hosted default — a bare origin gets the
|
|
@@ -2246,6 +2246,14 @@ const CLIENT_HINTS = {
|
|
|
2246
2246
|
codex: "$CODEX_HOME/config.toml or ~/.codex/config.toml",
|
|
2247
2247
|
cowork: "~/.cowork/mcp.json",
|
|
2248
2248
|
};
|
|
2249
|
+
const SKILLS_CLIENTS = ["claude-code", "codex", "cowork"];
|
|
2250
|
+
const SKILL_INSTRUCTION_CLIENTS = ["claude-code", "codex"];
|
|
2251
|
+
const SKILL_INSTRUCTION_CLIENT_HINTS = {
|
|
2252
|
+
"claude-code": ".claude/skills or .claude/commands",
|
|
2253
|
+
"claude-code-cli": ".claude/skills or .claude/commands",
|
|
2254
|
+
codex: ".agents/skills or ~/.codex/skills",
|
|
2255
|
+
cowork: "MCP only",
|
|
2256
|
+
};
|
|
2249
2257
|
function normalizeKnownSkillTarget(value) {
|
|
2250
2258
|
const key = value?.trim().toLowerCase();
|
|
2251
2259
|
if (!key)
|
|
@@ -2632,19 +2640,51 @@ function normalizeClientIds(values) {
|
|
|
2632
2640
|
}
|
|
2633
2641
|
return out;
|
|
2634
2642
|
}
|
|
2635
|
-
function
|
|
2636
|
-
|
|
2643
|
+
function normalizeSkillsClientIds(values) {
|
|
2644
|
+
const seen = new Set();
|
|
2645
|
+
const out = [];
|
|
2646
|
+
for (const client of normalizeClientIds(values)) {
|
|
2647
|
+
const normalized = client === "claude-code-cli" ? "claude-code" : client;
|
|
2648
|
+
if (seen.has(normalized))
|
|
2649
|
+
continue;
|
|
2650
|
+
seen.add(normalized);
|
|
2651
|
+
out.push(normalized);
|
|
2652
|
+
}
|
|
2653
|
+
return out;
|
|
2654
|
+
}
|
|
2655
|
+
function resolveSkillsClientArg(client) {
|
|
2656
|
+
return normalizeSkillsClientIds(resolveClients(client));
|
|
2657
|
+
}
|
|
2658
|
+
function skillsClients(installsMcp) {
|
|
2659
|
+
return installsMcp ? SKILLS_CLIENTS : SKILL_INSTRUCTION_CLIENTS;
|
|
2660
|
+
}
|
|
2661
|
+
function filterSkillsClients(clients, installsMcp) {
|
|
2662
|
+
if (installsMcp)
|
|
2663
|
+
return clients;
|
|
2664
|
+
return clients.filter((client) => SKILL_INSTRUCTION_CLIENTS.includes(client));
|
|
2665
|
+
}
|
|
2666
|
+
function clientPromptOptions(installsMcp) {
|
|
2667
|
+
return skillsClients(installsMcp).map((client) => ({
|
|
2637
2668
|
value: client,
|
|
2638
2669
|
label: CLIENT_LABELS[client],
|
|
2639
|
-
hint:
|
|
2670
|
+
hint: installsMcp
|
|
2671
|
+
? CLIENT_HINTS[client]
|
|
2672
|
+
: SKILL_INSTRUCTION_CLIENT_HINTS[client],
|
|
2640
2673
|
}));
|
|
2641
2674
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2675
|
+
const DEFAULT_PUBLIC_SKILLS_SOURCE = "BuilderIO/skills";
|
|
2676
|
+
const PUBLIC_SKILL_TARGET_PREFIX = "public-skills:";
|
|
2677
|
+
const BUILT_IN_SKILL_PROMPT_OPTIONS = [
|
|
2678
|
+
{
|
|
2679
|
+
value: "assets",
|
|
2680
|
+
label: "assets",
|
|
2681
|
+
hint: BUILT_IN_APP_SKILLS.assets.manifest.description,
|
|
2682
|
+
},
|
|
2683
|
+
{
|
|
2684
|
+
value: "design-exploration",
|
|
2685
|
+
label: "design-exploration",
|
|
2686
|
+
hint: BUILT_IN_APP_SKILLS.design.manifest.description,
|
|
2687
|
+
},
|
|
2648
2688
|
{
|
|
2649
2689
|
value: "visual-plan",
|
|
2650
2690
|
label: "visual-plan",
|
|
@@ -2655,9 +2695,64 @@ const PLAN_SKILL_PROMPT_OPTIONS = [
|
|
|
2655
2695
|
label: "visual-recap",
|
|
2656
2696
|
hint: "Interactive visual recap that maps PRs/diffs with diagrams, annotated diffs, API/schema summaries, and review notes.",
|
|
2657
2697
|
},
|
|
2698
|
+
{
|
|
2699
|
+
value: "context-xray",
|
|
2700
|
+
label: "context-xray",
|
|
2701
|
+
hint: BUILT_IN_APP_SKILLS["context-xray"].manifest.description,
|
|
2702
|
+
},
|
|
2658
2703
|
];
|
|
2659
|
-
|
|
2660
|
-
|
|
2704
|
+
const DEFAULT_SKILL_PROMPT_TARGETS = ["visual-plan", "visual-recap"];
|
|
2705
|
+
function publicSkillEntries(options) {
|
|
2706
|
+
if (options.catalogMode !== "all")
|
|
2707
|
+
return [];
|
|
2708
|
+
const seen = new Set();
|
|
2709
|
+
return (options.publicSkillEntries ?? [])
|
|
2710
|
+
.map((entry) => ({
|
|
2711
|
+
name: entry.name.trim().toLowerCase(),
|
|
2712
|
+
description: entry.description,
|
|
2713
|
+
}))
|
|
2714
|
+
.filter((entry) => {
|
|
2715
|
+
if (!entry.name || isKnownSkill(entry.name) || seen.has(entry.name)) {
|
|
2716
|
+
return false;
|
|
2717
|
+
}
|
|
2718
|
+
seen.add(entry.name);
|
|
2719
|
+
return true;
|
|
2720
|
+
})
|
|
2721
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
2722
|
+
}
|
|
2723
|
+
function publicSkillNames(options) {
|
|
2724
|
+
return new Set(publicSkillEntries(options).map((entry) => entry.name));
|
|
2725
|
+
}
|
|
2726
|
+
function publicSkillPromptOptions(options) {
|
|
2727
|
+
return publicSkillEntries(options).map((entry) => ({
|
|
2728
|
+
value: entry.name,
|
|
2729
|
+
label: entry.name,
|
|
2730
|
+
hint: entry.description ?? "Public skill from the BuilderIO skills catalog.",
|
|
2731
|
+
}));
|
|
2732
|
+
}
|
|
2733
|
+
function skillPromptOptions(options = {}) {
|
|
2734
|
+
return [
|
|
2735
|
+
...BUILT_IN_SKILL_PROMPT_OPTIONS,
|
|
2736
|
+
...publicSkillPromptOptions(options),
|
|
2737
|
+
];
|
|
2738
|
+
}
|
|
2739
|
+
function defaultSkillPromptTargets(options) {
|
|
2740
|
+
return [
|
|
2741
|
+
...DEFAULT_SKILL_PROMPT_TARGETS,
|
|
2742
|
+
...publicSkillEntries(options).map((entry) => entry.name),
|
|
2743
|
+
];
|
|
2744
|
+
}
|
|
2745
|
+
function publicSkillSelectionTarget(skillNames) {
|
|
2746
|
+
return `${PUBLIC_SKILL_TARGET_PREFIX}${skillNames.join(",")}`;
|
|
2747
|
+
}
|
|
2748
|
+
function publicSkillSelectionNames(target) {
|
|
2749
|
+
if (!target.startsWith(PUBLIC_SKILL_TARGET_PREFIX))
|
|
2750
|
+
return null;
|
|
2751
|
+
return target
|
|
2752
|
+
.slice(PUBLIC_SKILL_TARGET_PREFIX.length)
|
|
2753
|
+
.split(",")
|
|
2754
|
+
.map((name) => name.trim().toLowerCase())
|
|
2755
|
+
.filter(Boolean);
|
|
2661
2756
|
}
|
|
2662
2757
|
function prVisualRecapWorkflowPath(baseDir) {
|
|
2663
2758
|
return path.join(baseDir, ".github", "workflows", "pr-visual-recap.yml");
|
|
@@ -2700,9 +2795,13 @@ function shouldPrompt(parsed, options) {
|
|
|
2700
2795
|
}
|
|
2701
2796
|
async function promptForClients(context) {
|
|
2702
2797
|
const clack = await import("@clack/prompts");
|
|
2798
|
+
const message = context.installsMcp
|
|
2799
|
+
? "Install the MCP connector and skills for which local agents?\n" +
|
|
2800
|
+
" (space toggles, enter confirms; saved for next time)"
|
|
2801
|
+
: "Install skill instructions for which local agents?\n" +
|
|
2802
|
+
" (space toggles, enter confirms; saved for next time)";
|
|
2703
2803
|
const result = await clack.multiselect({
|
|
2704
|
-
message
|
|
2705
|
-
" (space toggles, enter confirms; saved for next time)",
|
|
2804
|
+
message,
|
|
2706
2805
|
options: context.options,
|
|
2707
2806
|
initialValues: context.initialClients,
|
|
2708
2807
|
required: true,
|
|
@@ -2745,7 +2844,7 @@ async function promptForPlanMode(context) {
|
|
|
2745
2844
|
{
|
|
2746
2845
|
value: "hosted",
|
|
2747
2846
|
label: "Hosted Plans, shareable links",
|
|
2748
|
-
hint: "Stores plans at plan.agent-native.com
|
|
2847
|
+
hint: "100% free and open source. Stores plans at plan.agent-native.com with sharing, comments, and browser editor. Requires one-time browser sign-in.",
|
|
2749
2848
|
},
|
|
2750
2849
|
{
|
|
2751
2850
|
value: "local-files",
|
|
@@ -2787,6 +2886,18 @@ async function promptForPlanMcpUrl() {
|
|
|
2787
2886
|
}
|
|
2788
2887
|
return String(result).trim();
|
|
2789
2888
|
}
|
|
2889
|
+
async function promptForUpdateInstructions() {
|
|
2890
|
+
const clack = await import("@clack/prompts");
|
|
2891
|
+
const result = await clack.confirm({
|
|
2892
|
+
message: "Add managed AGENTS.md / CLAUDE.md instructions for always-on skill behavior?",
|
|
2893
|
+
initialValue: true,
|
|
2894
|
+
});
|
|
2895
|
+
if (clack.isCancel(result)) {
|
|
2896
|
+
clack.cancel("Skipped managed instruction updates.");
|
|
2897
|
+
return null;
|
|
2898
|
+
}
|
|
2899
|
+
return Boolean(result);
|
|
2900
|
+
}
|
|
2790
2901
|
async function promptForSkills(context) {
|
|
2791
2902
|
const clack = await import("@clack/prompts");
|
|
2792
2903
|
const result = await clack.multiselect({
|
|
@@ -2804,15 +2915,20 @@ async function promptForSkills(context) {
|
|
|
2804
2915
|
return [];
|
|
2805
2916
|
return result.filter((value) => typeof value === "string");
|
|
2806
2917
|
}
|
|
2807
|
-
async function resolveSkillsClients(parsed, options) {
|
|
2918
|
+
async function resolveSkillsClients(parsed, options, installsMcp) {
|
|
2808
2919
|
if (parsed.clientExplicit || !shouldPrompt(parsed, options)) {
|
|
2809
|
-
|
|
2920
|
+
const clients = filterSkillsClients(resolveSkillsClientArg(parsed.client), installsMcp);
|
|
2921
|
+
if (clients.length === 0) {
|
|
2922
|
+
throw new Error("Local-file skill instructions only support Codex or Claude Code clients.");
|
|
2923
|
+
}
|
|
2924
|
+
return clients;
|
|
2810
2925
|
}
|
|
2811
|
-
const initialClients =
|
|
2926
|
+
const initialClients = skillsClients(installsMcp);
|
|
2812
2927
|
const prompt = options.promptClients ?? promptForClients;
|
|
2813
|
-
const selected =
|
|
2928
|
+
const selected = normalizeSkillsClientIds(await prompt({
|
|
2814
2929
|
initialClients,
|
|
2815
|
-
options: clientPromptOptions(),
|
|
2930
|
+
options: clientPromptOptions(installsMcp),
|
|
2931
|
+
installsMcp,
|
|
2816
2932
|
}));
|
|
2817
2933
|
if (selected.length === 0)
|
|
2818
2934
|
return null;
|
|
@@ -2848,12 +2964,66 @@ function targetIncludesPlans(target) {
|
|
|
2848
2964
|
function targetsIncludePlans(targets) {
|
|
2849
2965
|
return targets.some(targetIncludesPlans);
|
|
2850
2966
|
}
|
|
2967
|
+
function planSkillNamesSelected(skillNames) {
|
|
2968
|
+
return Boolean(skillNames?.some((name) => normalizeKnownSkillTarget(name) === "visual-plans"));
|
|
2969
|
+
}
|
|
2970
|
+
function recapSkillNamesSelected(skillNames) {
|
|
2971
|
+
return Boolean(skillNames?.some((name) => {
|
|
2972
|
+
const normalized = name.trim().toLowerCase();
|
|
2973
|
+
return (normalized === "visual-recap" ||
|
|
2974
|
+
normalized === "visual-recaps" ||
|
|
2975
|
+
normalizeKnownSkillTarget(normalized) === "visual-plans");
|
|
2976
|
+
}));
|
|
2977
|
+
}
|
|
2978
|
+
function resolveSelectedSkillTargets(selected, options) {
|
|
2979
|
+
const publicNames = publicSkillNames(options);
|
|
2980
|
+
const builtInSelections = [];
|
|
2981
|
+
const publicSelections = [];
|
|
2982
|
+
for (const raw of selected) {
|
|
2983
|
+
const skill = raw.trim().toLowerCase();
|
|
2984
|
+
if (!skill)
|
|
2985
|
+
continue;
|
|
2986
|
+
if (isKnownSkill(skill)) {
|
|
2987
|
+
builtInSelections.push(skill);
|
|
2988
|
+
continue;
|
|
2989
|
+
}
|
|
2990
|
+
if (publicNames.has(skill)) {
|
|
2991
|
+
publicSelections.push(skill);
|
|
2992
|
+
continue;
|
|
2993
|
+
}
|
|
2994
|
+
throw new Error(`Unknown skill: ${raw}. Run "npx @agent-native/core@latest skills list".`);
|
|
2995
|
+
}
|
|
2996
|
+
const out = [];
|
|
2997
|
+
const planSubskills = ["visual-plan", "visual-recap"];
|
|
2998
|
+
const selectedPlanSubskills = planSubskills.filter((skill) => builtInSelections.includes(skill));
|
|
2999
|
+
if (selectedPlanSubskills.length === planSubskills.length) {
|
|
3000
|
+
out.push("visual-plans");
|
|
3001
|
+
}
|
|
3002
|
+
else {
|
|
3003
|
+
out.push(...selectedPlanSubskills);
|
|
3004
|
+
}
|
|
3005
|
+
out.push(...builtInSelections.filter((skill) => !planSubskills.includes(skill) && !out.includes(skill)));
|
|
3006
|
+
if (publicSelections.length > 0) {
|
|
3007
|
+
out.push(publicSkillSelectionTarget([...new Set(publicSelections)]));
|
|
3008
|
+
}
|
|
3009
|
+
return out;
|
|
3010
|
+
}
|
|
2851
3011
|
async function resolveSkillTargets(parsed, options) {
|
|
3012
|
+
if (!parsed.target && parsed.plainSkillNames?.length) {
|
|
3013
|
+
return resolveSelectedSkillTargets(parsed.plainSkillNames, options);
|
|
3014
|
+
}
|
|
2852
3015
|
if (parsed.target || !shouldPrompt(parsed, options)) {
|
|
2853
|
-
|
|
3016
|
+
const target = parsed.target ?? "assets";
|
|
3017
|
+
if (!parsed.target)
|
|
3018
|
+
return [target];
|
|
3019
|
+
const normalizedTarget = target.trim().toLowerCase();
|
|
3020
|
+
if (publicSkillNames(options).has(normalizedTarget)) {
|
|
3021
|
+
return [publicSkillSelectionTarget([normalizedTarget])];
|
|
3022
|
+
}
|
|
3023
|
+
return [target];
|
|
2854
3024
|
}
|
|
2855
3025
|
const prompt = options.promptSkills ?? promptForSkills;
|
|
2856
|
-
const promptOptions = skillPromptOptions();
|
|
3026
|
+
const promptOptions = skillPromptOptions(options);
|
|
2857
3027
|
// The interactive multiselect skill picker is about to be shown (no --skill /
|
|
2858
3028
|
// target passed and we are interactive) — record the funnel "prompted" step.
|
|
2859
3029
|
options.telemetry?.track("skills_cli skills prompted", {
|
|
@@ -2861,22 +3031,12 @@ async function resolveSkillTargets(parsed, options) {
|
|
|
2861
3031
|
available: promptOptions.map((option) => option.value).join(","),
|
|
2862
3032
|
});
|
|
2863
3033
|
const selected = await prompt({
|
|
2864
|
-
initialTargets:
|
|
3034
|
+
initialTargets: defaultSkillPromptTargets(options),
|
|
2865
3035
|
options: promptOptions,
|
|
2866
3036
|
});
|
|
2867
3037
|
if (!selected || selected.length === 0)
|
|
2868
3038
|
return null;
|
|
2869
|
-
|
|
2870
|
-
// them through the bundle target — that registers/authenticates the connector
|
|
2871
|
-
// once instead of twice.
|
|
2872
|
-
const planSubskills = ["visual-plan", "visual-recap"];
|
|
2873
|
-
if (planSubskills.every((skill) => selected.includes(skill))) {
|
|
2874
|
-
return [
|
|
2875
|
-
"visual-plans",
|
|
2876
|
-
...selected.filter((s) => !planSubskills.includes(s)),
|
|
2877
|
-
];
|
|
2878
|
-
}
|
|
2879
|
-
return selected;
|
|
3039
|
+
return resolveSelectedSkillTargets(selected, options);
|
|
2880
3040
|
}
|
|
2881
3041
|
export function parseSkillsArgs(argv) {
|
|
2882
3042
|
const first = argv[0];
|
|
@@ -2932,6 +3092,14 @@ export function parseSkillsArgs(argv) {
|
|
|
2932
3092
|
out.client = value;
|
|
2933
3093
|
out.clientExplicit = true;
|
|
2934
3094
|
}
|
|
3095
|
+
else if ((value = eat("--agent")) !== undefined) {
|
|
3096
|
+
out.client = value;
|
|
3097
|
+
out.clientExplicit = true;
|
|
3098
|
+
}
|
|
3099
|
+
else if ((value = eat("-a")) !== undefined) {
|
|
3100
|
+
out.client = value;
|
|
3101
|
+
out.clientExplicit = true;
|
|
3102
|
+
}
|
|
2935
3103
|
else if ((value = eat("--skill")) !== undefined) {
|
|
2936
3104
|
out.plainSkillNames = [...(out.plainSkillNames ?? []), value];
|
|
2937
3105
|
}
|
|
@@ -2942,6 +3110,8 @@ export function parseSkillsArgs(argv) {
|
|
|
2942
3110
|
out.scope = value;
|
|
2943
3111
|
out.scopeExplicit = true;
|
|
2944
3112
|
}
|
|
3113
|
+
else if ((value = eat("--cwd")) !== undefined)
|
|
3114
|
+
out.baseDir = value;
|
|
2945
3115
|
else if ((value = eat("--mcp-url")) !== undefined)
|
|
2946
3116
|
out.mcpUrl = value;
|
|
2947
3117
|
else if ((value = eat("--mode")) !== undefined)
|
|
@@ -2958,6 +3128,18 @@ export function parseSkillsArgs(argv) {
|
|
|
2958
3128
|
out.dryRun = true;
|
|
2959
3129
|
else if (arg === "--json")
|
|
2960
3130
|
out.printJson = true;
|
|
3131
|
+
else if (arg === "-g" || arg === "--global") {
|
|
3132
|
+
out.scope = "user";
|
|
3133
|
+
out.scopeExplicit = true;
|
|
3134
|
+
}
|
|
3135
|
+
else if (arg === "--project") {
|
|
3136
|
+
out.scope = "project";
|
|
3137
|
+
out.scopeExplicit = true;
|
|
3138
|
+
}
|
|
3139
|
+
else if (arg === "--copy") {
|
|
3140
|
+
// Compatibility with @agent-native/skills. Core always copies skill
|
|
3141
|
+
// instructions instead of linking to the source repo.
|
|
3142
|
+
}
|
|
2961
3143
|
else if (arg === "--mcp-only")
|
|
2962
3144
|
out.instructions = false;
|
|
2963
3145
|
else if (arg === "--instructions-only" || arg === "--no-mcp")
|
|
@@ -3087,7 +3269,7 @@ function preserveMcpUrlAppPathOverride(target, input) {
|
|
|
3087
3269
|
};
|
|
3088
3270
|
}
|
|
3089
3271
|
function dryRunInstallCommand(parsed, target) {
|
|
3090
|
-
const clients = parsed.clients ??
|
|
3272
|
+
const clients = parsed.clients ?? resolveSkillsClientArg(parsed.client);
|
|
3091
3273
|
const args = [
|
|
3092
3274
|
"@agent-native/core@latest",
|
|
3093
3275
|
"skills",
|
|
@@ -3219,21 +3401,30 @@ function isGithubSkillRepoTarget(target) {
|
|
|
3219
3401
|
function isPlainSkillRepoTarget(target) {
|
|
3220
3402
|
return isPlainSkillRepoPath(target) || isGithubSkillRepoTarget(target);
|
|
3221
3403
|
}
|
|
3222
|
-
function agentNativeSkillsInstallArgs(parsed, target, clients) {
|
|
3404
|
+
function agentNativeSkillsInstallArgs(parsed, target, clients, baseDir) {
|
|
3223
3405
|
const args = [
|
|
3224
3406
|
"--yes",
|
|
3225
3407
|
"@agent-native/skills@latest",
|
|
3226
3408
|
"add",
|
|
3409
|
+
"--copy",
|
|
3227
3410
|
target,
|
|
3228
3411
|
"--client",
|
|
3229
3412
|
clientArgForClients(clients),
|
|
3230
3413
|
"--scope",
|
|
3231
3414
|
parsed.scope,
|
|
3232
3415
|
];
|
|
3416
|
+
if (baseDir)
|
|
3417
|
+
args.push("--cwd", baseDir);
|
|
3233
3418
|
if (parsed.withGithubAction)
|
|
3234
3419
|
args.push("--with-github-action");
|
|
3235
3420
|
if (parsed.force)
|
|
3236
3421
|
args.push("--force");
|
|
3422
|
+
if (parsed.planMode)
|
|
3423
|
+
args.push("--mode", parsed.planMode);
|
|
3424
|
+
if (parsed.mcpUrl)
|
|
3425
|
+
args.push("--mcp-url", parsed.mcpUrl);
|
|
3426
|
+
if (!parsed.mcp)
|
|
3427
|
+
args.push("--no-mcp");
|
|
3237
3428
|
if (!parsed.connect)
|
|
3238
3429
|
args.push("--no-connect");
|
|
3239
3430
|
for (const skill of parsed.plainSkillNames ?? []) {
|
|
@@ -3245,6 +3436,8 @@ function agentNativeSkillsInstallArgs(parsed, target, clients) {
|
|
|
3245
3436
|
args.push("--no-update-instructions");
|
|
3246
3437
|
if (parsed.yes)
|
|
3247
3438
|
args.push("--yes");
|
|
3439
|
+
if (parsed.dryRun)
|
|
3440
|
+
args.push("--dry-run");
|
|
3248
3441
|
return args;
|
|
3249
3442
|
}
|
|
3250
3443
|
async function addPlainSkillRepo(parsed, options) {
|
|
@@ -3252,15 +3445,16 @@ async function addPlainSkillRepo(parsed, options) {
|
|
|
3252
3445
|
if (!parsed.instructions && parsed.mcp) {
|
|
3253
3446
|
throw new Error("Plain skill repositories only install skill instructions. Run without --mcp-only.");
|
|
3254
3447
|
}
|
|
3255
|
-
if (parsed.mcpUrl) {
|
|
3448
|
+
if (parsed.mcpUrl && !planSkillNamesSelected(parsed.plainSkillNames)) {
|
|
3256
3449
|
throw new Error("--mcp-url only applies to app-backed Agent Native skills.");
|
|
3257
3450
|
}
|
|
3258
|
-
const clients = parsed.clients ??
|
|
3451
|
+
const clients = parsed.clients ?? resolveSkillsClientArg(parsed.client);
|
|
3259
3452
|
const skillsAgents = skillsAgentsForClients(clients);
|
|
3453
|
+
const selectedSkillNames = parsed.plainSkillNames ?? [];
|
|
3260
3454
|
if (skillsAgents.length === 0) {
|
|
3261
3455
|
throw new Error("Plain skill repositories can only install instructions for Codex or Claude Code clients.");
|
|
3262
3456
|
}
|
|
3263
|
-
const args = agentNativeSkillsInstallArgs(parsed, target, clients);
|
|
3457
|
+
const args = agentNativeSkillsInstallArgs(parsed, target, clients, options.baseDir);
|
|
3264
3458
|
if (!parsed.dryRun) {
|
|
3265
3459
|
const code = await (options.runCommand ?? runCommand)("npx", args, {
|
|
3266
3460
|
stdio: parsed.yes ? "silent" : "inherit",
|
|
@@ -3269,15 +3463,17 @@ async function addPlainSkillRepo(parsed, options) {
|
|
|
3269
3463
|
throw new Error(`npx @agent-native/skills@latest add exited with ${code}.`);
|
|
3270
3464
|
}
|
|
3271
3465
|
options.telemetry?.track("skills_cli install completed", {
|
|
3272
|
-
skills: target,
|
|
3466
|
+
skills: selectedSkillNames.length ? selectedSkillNames.join(",") : target,
|
|
3273
3467
|
clients: clients.join(","),
|
|
3274
3468
|
scope: parsed.scope,
|
|
3275
3469
|
dryRun: Boolean(parsed.dryRun),
|
|
3276
3470
|
});
|
|
3277
3471
|
return {
|
|
3278
3472
|
id: target,
|
|
3279
|
-
displayName:
|
|
3280
|
-
|
|
3473
|
+
displayName: selectedSkillNames.length
|
|
3474
|
+
? selectedSkillNames.join(", ")
|
|
3475
|
+
: target,
|
|
3476
|
+
skillNames: selectedSkillNames,
|
|
3281
3477
|
skillsAgents,
|
|
3282
3478
|
mcpUrl: "",
|
|
3283
3479
|
mcpClients: [],
|
|
@@ -3338,13 +3534,29 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
|
|
|
3338
3534
|
options.log?.(`Authenticating ${installTarget.displayName}…`);
|
|
3339
3535
|
options.telemetry?.track("skills_cli connect started");
|
|
3340
3536
|
try {
|
|
3341
|
-
|
|
3537
|
+
const connectArgs = [
|
|
3342
3538
|
hostedUrl,
|
|
3343
3539
|
"--client",
|
|
3344
3540
|
clientArgForClients(clients),
|
|
3345
3541
|
"--scope",
|
|
3346
3542
|
parsed.scope,
|
|
3347
|
-
]
|
|
3543
|
+
];
|
|
3544
|
+
if (options.runConnect) {
|
|
3545
|
+
await options.runConnect(connectArgs);
|
|
3546
|
+
}
|
|
3547
|
+
else {
|
|
3548
|
+
await runConnect(connectArgs, {
|
|
3549
|
+
isInteractive: options.isInteractive,
|
|
3550
|
+
logOut: (message) => {
|
|
3551
|
+
if (message.trim())
|
|
3552
|
+
options.log?.(message);
|
|
3553
|
+
},
|
|
3554
|
+
logErr: (message) => {
|
|
3555
|
+
if (message.trim())
|
|
3556
|
+
options.log?.(message);
|
|
3557
|
+
},
|
|
3558
|
+
});
|
|
3559
|
+
}
|
|
3348
3560
|
options.telemetry?.track("skills_cli connect completed");
|
|
3349
3561
|
return { connected: true, connectCommand: "" };
|
|
3350
3562
|
}
|
|
@@ -3360,6 +3572,14 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
|
|
|
3360
3572
|
}
|
|
3361
3573
|
export async function addAgentNativeSkill(parsed, options = {}) {
|
|
3362
3574
|
const target = parsed.target ?? "assets";
|
|
3575
|
+
const publicSelection = publicSkillSelectionNames(target);
|
|
3576
|
+
if (publicSelection) {
|
|
3577
|
+
return addPlainSkillRepo({
|
|
3578
|
+
...parsed,
|
|
3579
|
+
target: options.publicSkillSource ?? DEFAULT_PUBLIC_SKILLS_SOURCE,
|
|
3580
|
+
plainSkillNames: publicSelection,
|
|
3581
|
+
}, options);
|
|
3582
|
+
}
|
|
3363
3583
|
const knownTarget = normalizeKnownSkillTarget(target);
|
|
3364
3584
|
const planMode = knownTarget === "visual-plans"
|
|
3365
3585
|
? (parsed.planMode ?? (parsed.mcpUrl ? "self-hosted" : "hosted"))
|
|
@@ -3397,7 +3617,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3397
3617
|
if (!parsed.instructions && parsed.mcp) {
|
|
3398
3618
|
throw new Error("Context X-Ray does not need MCP config yet. Run without --mcp-only.");
|
|
3399
3619
|
}
|
|
3400
|
-
const clients = parsed.clients ??
|
|
3620
|
+
const clients = parsed.clients ?? resolveSkillsClientArg(parsed.client);
|
|
3401
3621
|
const skillsAgents = skillsAgentsForClients(clients);
|
|
3402
3622
|
if (parsed.dryRun) {
|
|
3403
3623
|
const githubActionPath = parsed.withGithubAction && knownTarget === "visual-plans"
|
|
@@ -3452,7 +3672,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3452
3672
|
if (parsed.mcpUrl) {
|
|
3453
3673
|
installTarget = withMcpUrlOverride(installTarget, parsed.mcpUrl);
|
|
3454
3674
|
}
|
|
3455
|
-
const clients = parsed.clients ??
|
|
3675
|
+
const clients = parsed.clients ?? resolveSkillsClientArg(parsed.client);
|
|
3456
3676
|
installTarget = preserveMcpUrlAppPathOverride(installTarget, parsed.mcpUrl);
|
|
3457
3677
|
const skillsAgents = skillsAgentsForClients(clients);
|
|
3458
3678
|
if (parsed.dryRun) {
|
|
@@ -3495,6 +3715,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3495
3715
|
let instructionsWritten;
|
|
3496
3716
|
let connected = false;
|
|
3497
3717
|
let connectCommand;
|
|
3718
|
+
let registeredMcpClients = shouldRegisterMcp ? clients : [];
|
|
3498
3719
|
try {
|
|
3499
3720
|
if (parsed.instructions) {
|
|
3500
3721
|
if (skillsAgents.length === 0) {
|
|
@@ -3557,7 +3778,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3557
3778
|
if (shouldRegisterMcp) {
|
|
3558
3779
|
commands.push(`npx @agent-native/core@latest app-skill ensure --manifest ${installTarget.loaded.file} --client ${parsed.client} --scope ${parsed.scope} --yes`);
|
|
3559
3780
|
if (!parsed.dryRun) {
|
|
3560
|
-
await ensureAppSkill(installTarget.loaded, {
|
|
3781
|
+
const ensureResult = await ensureAppSkill(installTarget.loaded, {
|
|
3561
3782
|
clients,
|
|
3562
3783
|
scope: parsed.scope,
|
|
3563
3784
|
baseDir: options.baseDir,
|
|
@@ -3565,6 +3786,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3565
3786
|
confirm: true,
|
|
3566
3787
|
log: options.log,
|
|
3567
3788
|
});
|
|
3789
|
+
registeredMcpClients = ensureResult.written.map((written) => written.client);
|
|
3568
3790
|
options.telemetry?.track("skills_cli mcp registered", {
|
|
3569
3791
|
skills: installTarget.skillNames.join(","),
|
|
3570
3792
|
});
|
|
@@ -3576,9 +3798,18 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3576
3798
|
const result = await connectAfterEnsure(installTarget, clients, parsed, options);
|
|
3577
3799
|
connected = result.connected;
|
|
3578
3800
|
connectCommand = result.connectCommand || undefined;
|
|
3801
|
+
if (connected)
|
|
3802
|
+
registeredMcpClients = clients;
|
|
3579
3803
|
if (connectCommand)
|
|
3580
3804
|
commands.push(connectCommand);
|
|
3581
3805
|
}
|
|
3806
|
+
else {
|
|
3807
|
+
const pendingClients = clients.filter((client) => !registeredMcpClients.includes(client));
|
|
3808
|
+
if (pendingClients.length > 0) {
|
|
3809
|
+
connectCommand = connectCommandFor(installTarget.loaded.manifest.hosted.url, pendingClients, parsed.scope);
|
|
3810
|
+
commands.push(connectCommand);
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3582
3813
|
}
|
|
3583
3814
|
}
|
|
3584
3815
|
// `--with-github-action`: also drop the PR Visual Recap workflow into the
|
|
@@ -3638,7 +3869,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3638
3869
|
mcpUrl: knownTarget === "visual-plans" && planMode === "local-files"
|
|
3639
3870
|
? ""
|
|
3640
3871
|
: installTarget.loaded.manifest.hosted.mcpUrl,
|
|
3641
|
-
mcpClients:
|
|
3872
|
+
mcpClients: registeredMcpClients,
|
|
3642
3873
|
dryRun: parsed.dryRun,
|
|
3643
3874
|
commands,
|
|
3644
3875
|
written: instructionsWritten,
|
|
@@ -3655,15 +3886,29 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3655
3886
|
installTarget.cleanup?.();
|
|
3656
3887
|
}
|
|
3657
3888
|
}
|
|
3658
|
-
function listSkills() {
|
|
3659
|
-
return
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3889
|
+
function listSkills(options = {}) {
|
|
3890
|
+
return [
|
|
3891
|
+
...Object.values(BUILT_IN_APP_SKILLS).map((entry) => ({
|
|
3892
|
+
id: entry.manifest.id,
|
|
3893
|
+
aliases: BUILT_IN_APP_SKILL_DISPLAY_ALIASES[entry.manifest.id] ?? [],
|
|
3894
|
+
name: entry.manifest.displayName,
|
|
3895
|
+
description: entry.manifest.description,
|
|
3896
|
+
mcpUrl: isLocalOnlyBuiltInSkill(entry)
|
|
3897
|
+
? ""
|
|
3898
|
+
: entry.manifest.hosted.mcpUrl,
|
|
3899
|
+
local: isLocalOnlyBuiltInSkill(entry),
|
|
3900
|
+
source: "agent-native",
|
|
3901
|
+
})),
|
|
3902
|
+
...publicSkillEntries(options).map((entry) => ({
|
|
3903
|
+
id: entry.name,
|
|
3904
|
+
aliases: [],
|
|
3905
|
+
name: entry.name,
|
|
3906
|
+
description: entry.description ?? "Public skill from the BuilderIO skills catalog.",
|
|
3907
|
+
mcpUrl: "",
|
|
3908
|
+
local: true,
|
|
3909
|
+
source: options.publicSkillSource ?? DEFAULT_PUBLIC_SKILLS_SOURCE,
|
|
3910
|
+
})),
|
|
3911
|
+
];
|
|
3667
3912
|
}
|
|
3668
3913
|
function skillStateJson(state) {
|
|
3669
3914
|
return {
|
|
@@ -3696,6 +3941,55 @@ function planModeSummary(mode) {
|
|
|
3696
3941
|
return "Self-hosted/custom Plan app";
|
|
3697
3942
|
return "Hosted Plans - shareable links and comments";
|
|
3698
3943
|
}
|
|
3944
|
+
function targetInstallsMcp(target, parsed) {
|
|
3945
|
+
if (!parsed.mcp)
|
|
3946
|
+
return false;
|
|
3947
|
+
if (publicSkillSelectionNames(target))
|
|
3948
|
+
return false;
|
|
3949
|
+
const knownTarget = normalizeKnownSkillTarget(target);
|
|
3950
|
+
if (knownTarget === "visual-plans")
|
|
3951
|
+
return parsed.planMode !== "local-files";
|
|
3952
|
+
if (knownTarget) {
|
|
3953
|
+
return !isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[knownTarget]);
|
|
3954
|
+
}
|
|
3955
|
+
return true;
|
|
3956
|
+
}
|
|
3957
|
+
function targetsInstallMcp(targets, parsed) {
|
|
3958
|
+
return targets.some((target) => targetInstallsMcp(target, parsed));
|
|
3959
|
+
}
|
|
3960
|
+
function instructionContentForSkill(skillName) {
|
|
3961
|
+
if (skillName === "quick-recap") {
|
|
3962
|
+
return "When writing final response status indicators, use the /quick-recap skill always.";
|
|
3963
|
+
}
|
|
3964
|
+
if (skillName === "efficient-fable") {
|
|
3965
|
+
return "When operating as Claude Fable, use the /efficient-fable skill always.";
|
|
3966
|
+
}
|
|
3967
|
+
if (skillName === "efficient-frontier") {
|
|
3968
|
+
return "When using a high-cost frontier model for codebase-heavy work, use the /efficient-frontier skill always.";
|
|
3969
|
+
}
|
|
3970
|
+
if (skillName === "stay-within-limits") {
|
|
3971
|
+
return "When long-running or parallel work needs usage-limit checks, use the /stay-within-limits skill always.";
|
|
3972
|
+
}
|
|
3973
|
+
if (skillName === "visual-plan") {
|
|
3974
|
+
return "When work needs an interactive visual plan before implementation, use the /visual-plan skill always.";
|
|
3975
|
+
}
|
|
3976
|
+
if (skillName === "visual-recap") {
|
|
3977
|
+
return "When a PR, branch, commit, or diff needs an interactive visual recap, use the /visual-recap skill always.";
|
|
3978
|
+
}
|
|
3979
|
+
return null;
|
|
3980
|
+
}
|
|
3981
|
+
function selectedPlainSkillNamesForInstructionPrompt(targets, parsed) {
|
|
3982
|
+
const names = new Set(parsed.plainSkillNames ?? []);
|
|
3983
|
+
for (const target of targets) {
|
|
3984
|
+
for (const name of publicSkillSelectionNames(target) ?? []) {
|
|
3985
|
+
names.add(name);
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
return [...names];
|
|
3989
|
+
}
|
|
3990
|
+
function hasManagedInstructionBlock(skillNames) {
|
|
3991
|
+
return skillNames.some((name) => Boolean(instructionContentForSkill(name)));
|
|
3992
|
+
}
|
|
3699
3993
|
function runSkillsStatusOrUpdate(parsed, options, update) {
|
|
3700
3994
|
const before = collectSkillInstallStates(parsed, options);
|
|
3701
3995
|
const changed = update ? updateSkillInstallStates(before, parsed.dryRun) : [];
|
|
@@ -3752,9 +4046,19 @@ function readCliVersion() {
|
|
|
3752
4046
|
}
|
|
3753
4047
|
export async function runSkills(argv, options = {}) {
|
|
3754
4048
|
const parsed = parseSkillsArgs(argv);
|
|
4049
|
+
if (parsed.baseDir) {
|
|
4050
|
+
options = { ...options, baseDir: path.resolve(parsed.baseDir) };
|
|
4051
|
+
}
|
|
4052
|
+
const clackForLog = parsed.printJson
|
|
4053
|
+
? undefined
|
|
4054
|
+
: await import("@clack/prompts");
|
|
3755
4055
|
const log = parsed.printJson
|
|
3756
4056
|
? undefined
|
|
3757
|
-
: (message) =>
|
|
4057
|
+
: (message) => {
|
|
4058
|
+
if (!message.trim())
|
|
4059
|
+
return;
|
|
4060
|
+
clackForLog?.log.info(message);
|
|
4061
|
+
};
|
|
3758
4062
|
if (parsed.command === "help") {
|
|
3759
4063
|
process.stdout.write(`${HELP}\n`);
|
|
3760
4064
|
return;
|
|
@@ -3764,6 +4068,7 @@ export async function runSkills(argv, options = {}) {
|
|
|
3764
4068
|
// `npx @agent-native/skills@latest add …`; this env guard tells that child process
|
|
3765
4069
|
// to run its OWN headless installer instead of bouncing back into core,
|
|
3766
4070
|
// which would otherwise be an infinite skills → core → skills loop.
|
|
4071
|
+
const previousDirect = process.env.AGENT_NATIVE_SKILLS_DIRECT;
|
|
3767
4072
|
process.env.AGENT_NATIVE_SKILLS_DIRECT = "1";
|
|
3768
4073
|
// Best-effort install-funnel telemetry. Created once per run and flushed in a
|
|
3769
4074
|
// finally so events send on success, error, and cancellation — the CLI is
|
|
@@ -3780,7 +4085,7 @@ export async function runSkills(argv, options = {}) {
|
|
|
3780
4085
|
try {
|
|
3781
4086
|
telemetry.track("skills_cli started");
|
|
3782
4087
|
if (parsed.command === "list") {
|
|
3783
|
-
const skills = listSkills();
|
|
4088
|
+
const skills = listSkills(optionsWithTelemetry);
|
|
3784
4089
|
telemetry.track("skills_cli skills listed", {
|
|
3785
4090
|
availableCount: skills.length,
|
|
3786
4091
|
available: skills.map((skill) => skill.id).join(","),
|
|
@@ -3815,10 +4120,11 @@ export async function runSkills(argv, options = {}) {
|
|
|
3815
4120
|
// Best-effort "took everything offered" signal: compare against the
|
|
3816
4121
|
// interactive picker's option count (the plan sub-skills collapse into a
|
|
3817
4122
|
// single bundle target, so this is approximate, like the standalone CLI).
|
|
3818
|
-
selectedAll: targets.length === skillPromptOptions().length,
|
|
4123
|
+
selectedAll: targets.length === skillPromptOptions(options).length,
|
|
3819
4124
|
preselected,
|
|
3820
4125
|
});
|
|
3821
|
-
const includesPlans = targetsIncludePlans(targets)
|
|
4126
|
+
const includesPlans = targetsIncludePlans(targets) ||
|
|
4127
|
+
planSkillNamesSelected(parsed.plainSkillNames);
|
|
3822
4128
|
if (parsed.planMode && !includesPlans) {
|
|
3823
4129
|
throw new Error("--mode only applies to visual-plan / visual-recap.");
|
|
3824
4130
|
}
|
|
@@ -3857,7 +4163,8 @@ export async function runSkills(argv, options = {}) {
|
|
|
3857
4163
|
mode: parsed.planMode,
|
|
3858
4164
|
});
|
|
3859
4165
|
}
|
|
3860
|
-
const
|
|
4166
|
+
const installsMcp = targetsInstallMcp(targets, parsed);
|
|
4167
|
+
const clients = await resolveSkillsClients(parsed, optionsWithTelemetry, installsMcp);
|
|
3861
4168
|
if (!clients) {
|
|
3862
4169
|
telemetry.track("skills_cli cancelled", { step: "clients" });
|
|
3863
4170
|
return;
|
|
@@ -3878,6 +4185,20 @@ export async function runSkills(argv, options = {}) {
|
|
|
3878
4185
|
parsed.scope = scope;
|
|
3879
4186
|
}
|
|
3880
4187
|
telemetry.track("skills_cli scope selected", { scope: parsed.scope });
|
|
4188
|
+
const instructionSkillNames = selectedPlainSkillNamesForInstructionPrompt(targets, parsed);
|
|
4189
|
+
if (parsed.updateInstructions === undefined &&
|
|
4190
|
+
hasManagedInstructionBlock(instructionSkillNames) &&
|
|
4191
|
+
shouldPrompt(parsed, options)) {
|
|
4192
|
+
const prompt = options.promptUpdateInstructions ?? promptForUpdateInstructions;
|
|
4193
|
+
const choice = await prompt();
|
|
4194
|
+
if (choice === null) {
|
|
4195
|
+
telemetry.track("skills_cli cancelled", {
|
|
4196
|
+
step: "managed-instructions",
|
|
4197
|
+
});
|
|
4198
|
+
return;
|
|
4199
|
+
}
|
|
4200
|
+
parsed.updateInstructions = choice === true;
|
|
4201
|
+
}
|
|
3881
4202
|
// Decide the optional PR Visual Recap GitHub Action UP FRONT — before any
|
|
3882
4203
|
// install or MCP registration — so every prompt is answered before we touch
|
|
3883
4204
|
// disk. The choice is threaded into each install via `withGithubAction` +
|
|
@@ -3888,7 +4209,7 @@ export async function runSkills(argv, options = {}) {
|
|
|
3888
4209
|
return false;
|
|
3889
4210
|
const only = builtInOnlySkillNames(target);
|
|
3890
4211
|
return !only || only.includes("visual-recap");
|
|
3891
|
-
});
|
|
4212
|
+
}) || recapSkillNamesSelected(parsed.plainSkillNames);
|
|
3892
4213
|
if (anyRecapTarget &&
|
|
3893
4214
|
!parsed.withGithubAction &&
|
|
3894
4215
|
!fs.existsSync(prVisualRecapWorkflowPath(recapBaseDir)) &&
|
|
@@ -4011,15 +4332,16 @@ export async function runSkills(argv, options = {}) {
|
|
|
4011
4332
|
clack.note(summary.join("\n"), `Installed ${installedNames} skill${results.length === 1 ? "" : "s"}`);
|
|
4012
4333
|
// GitHub Action follow-ups — kept as exact, copy-pasteable command lines.
|
|
4013
4334
|
for (const line of [githubActionLine, githubActionSuggestionLine].filter(Boolean)) {
|
|
4014
|
-
|
|
4335
|
+
clack.log.info(line);
|
|
4015
4336
|
}
|
|
4016
4337
|
const slashCommands = completedSkills.map((name) => `/${name}`).join(" ");
|
|
4017
|
-
const configuredEveryClient =
|
|
4338
|
+
const configuredEveryClient = SKILLS_CLIENTS.every((client) => clients.includes(client));
|
|
4018
4339
|
const clientHint = configuredEveryClient
|
|
4019
4340
|
? ""
|
|
4020
4341
|
: "\n Add another client later with --client <client> (e.g. --client claude-code).";
|
|
4342
|
+
const reloadTarget = mcpClients.length > 0 ? "skill + MCP server" : "skill";
|
|
4021
4343
|
clack.outro(`✅ All set! Start using ${slashCommands || "your new skills"} in your agent client.` +
|
|
4022
|
-
`\n You may need to reload the client for the
|
|
4344
|
+
`\n You may need to reload the client for the ${reloadTarget} to appear.` +
|
|
4023
4345
|
clientHint);
|
|
4024
4346
|
}
|
|
4025
4347
|
catch (error) {
|
|
@@ -4032,6 +4354,12 @@ export async function runSkills(argv, options = {}) {
|
|
|
4032
4354
|
}
|
|
4033
4355
|
finally {
|
|
4034
4356
|
await telemetry.flush();
|
|
4357
|
+
if (previousDirect === undefined) {
|
|
4358
|
+
delete process.env.AGENT_NATIVE_SKILLS_DIRECT;
|
|
4359
|
+
}
|
|
4360
|
+
else {
|
|
4361
|
+
process.env.AGENT_NATIVE_SKILLS_DIRECT = previousDirect;
|
|
4362
|
+
}
|
|
4035
4363
|
}
|
|
4036
4364
|
}
|
|
4037
4365
|
//# sourceMappingURL=skills.js.map
|