@agent-native/core 0.51.6 → 0.51.8
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/pr-visual-recap-workflow.d.ts +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +1 -1
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/skills.d.ts +13 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +255 -24
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/assistant-ui-recovery.d.ts.map +1 -1
- package/dist/client/assistant-ui-recovery.js +15 -12
- package/dist/client/assistant-ui-recovery.js.map +1 -1
- package/dist/provider-api/corpus-jobs-store.d.ts +95 -0
- package/dist/provider-api/corpus-jobs-store.d.ts.map +1 -0
- package/dist/provider-api/corpus-jobs-store.js +394 -0
- package/dist/provider-api/corpus-jobs-store.js.map +1 -0
- package/dist/provider-api/corpus-jobs.d.ts +146 -0
- package/dist/provider-api/corpus-jobs.d.ts.map +1 -0
- package/dist/provider-api/corpus-jobs.js +1192 -0
- package/dist/provider-api/corpus-jobs.js.map +1 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +9 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/docs/content/template-analytics.md +0 -8
- package/docs/content/template-assets.md +0 -6
- package/docs/content/template-brain.md +0 -8
- package/docs/content/template-calendar.md +0 -8
- package/docs/content/template-clips.md +0 -8
- package/docs/content/template-content.md +0 -14
- package/docs/content/template-design.md +0 -6
- package/docs/content/template-forms.md +0 -10
- package/docs/content/template-mail.md +0 -8
- package/docs/content/template-plan.md +180 -0
- package/docs/content/template-slides.md +0 -8
- package/docs/content/template-videos.md +0 -8
- package/package.json +3 -1
package/dist/cli/skills.js
CHANGED
|
@@ -21,7 +21,7 @@ Usage:
|
|
|
21
21
|
npx @agent-native/core@latest skills list
|
|
22
22
|
npx @agent-native/core@latest skills status [assets|design-exploration|visual-plan|visual-recap|context-xray] [--client codex|claude-code|all] [--scope user|project] [--json]
|
|
23
23
|
npx @agent-native/core@latest skills update [assets|design-exploration|visual-plan|visual-recap|context-xray] [--client codex|claude-code|all] [--scope user|project] [--dry-run] [--json]
|
|
24
|
-
npx @agent-native/core@latest skills add assets|design-exploration|visual-plan|visual-recap|context-xray [--client codex|claude-code|claude-code-cli|cowork|all] [--scope user|project] [--mcp-url <url>] [--no-connect] [--with-github-action] [--yes] [--dry-run] [--json]
|
|
24
|
+
npx @agent-native/core@latest skills add assets|design-exploration|visual-plan|visual-recap|context-xray [--client codex|claude-code|claude-code-cli|cowork|all] [--scope user|project] [--mode hosted|local-files|self-hosted] [--mcp-url <url>] [--no-connect] [--with-github-action] [--yes] [--dry-run] [--json]
|
|
25
25
|
npx @agent-native/core@latest skills add <manifest-or-app-dir|skill-repo> [--skill <name>] [--client ...] [--yes]
|
|
26
26
|
|
|
27
27
|
Examples:
|
|
@@ -30,6 +30,8 @@ Examples:
|
|
|
30
30
|
npx @agent-native/core@latest skills add visual-plan
|
|
31
31
|
npx @agent-native/core@latest skills add visual-recap
|
|
32
32
|
npx @agent-native/core@latest skills add visual-recap --with-github-action
|
|
33
|
+
npx @agent-native/core@latest skills add visual-plan --mode local-files
|
|
34
|
+
npx @agent-native/core@latest skills add visual-plan --mode self-hosted --mcp-url https://my-plan-app.example.com
|
|
33
35
|
npx @agent-native/core@latest skills status visual-plan
|
|
34
36
|
npx @agent-native/core@latest skills update visual-plan
|
|
35
37
|
npx @agent-native/core@latest skills add visual-plan --no-connect
|
|
@@ -59,6 +61,12 @@ deployment) instead of the built-in hosted default — a bare origin gets the
|
|
|
59
61
|
standard /_agent-native/mcp path appended. Use app-skill pack for marketplace
|
|
60
62
|
bundles and custom adapter output.
|
|
61
63
|
|
|
64
|
+
When installing visual-plan or visual-recap interactively, the CLI asks where
|
|
65
|
+
plans and recaps should live: hosted Plans for shareable links/comments, local
|
|
66
|
+
files for "No sharing, all local.", or a self-hosted/custom Plan app URL.
|
|
67
|
+
Pass --mode to choose directly. Local-files mode skips MCP registration and
|
|
68
|
+
auth and installs instructions that default to MDX folders plus local preview.
|
|
69
|
+
|
|
62
70
|
When installing visual-recap interactively, the CLI offers to add the optional PR
|
|
63
71
|
Visual Recap GitHub Action. Pass --with-github-action to write it directly, then
|
|
64
72
|
run "npx @agent-native/core@latest recap setup" / "npx @agent-native/core@latest recap doctor" to configure and
|
|
@@ -2244,12 +2252,60 @@ function stableSkillHash(files) {
|
|
|
2244
2252
|
}
|
|
2245
2253
|
return hash.digest("hex").slice(0, 16);
|
|
2246
2254
|
}
|
|
2247
|
-
function
|
|
2255
|
+
function insertAfterFrontmatter(markdown, block) {
|
|
2256
|
+
if (!block.trim())
|
|
2257
|
+
return markdown;
|
|
2258
|
+
const match = markdown.match(/^---\n[\s\S]*?\n---\n/);
|
|
2259
|
+
if (!match)
|
|
2260
|
+
return `${block}\n\n${markdown}`;
|
|
2261
|
+
return `${match[0]}\n${block.trim()}\n\n${markdown.slice(match[0].length)}`;
|
|
2262
|
+
}
|
|
2263
|
+
function planModeInstructionBlock(input) {
|
|
2264
|
+
if (input.mode === "local-files") {
|
|
2265
|
+
return `## Installed Mode
|
|
2266
|
+
|
|
2267
|
+
Default storage for this installation: local files. Create and update plans and
|
|
2268
|
+
recaps as MDX folders under \`plans/<slug>/\`, run
|
|
2269
|
+
\`npx @agent-native/core@latest plan local preview --dir plans/<slug> --kind plan|recap\`,
|
|
2270
|
+
and report the local preview URL or path. No sharing, all local. Use a hosted
|
|
2271
|
+
or self-hosted Plan MCP connector only if the user explicitly asks to publish or
|
|
2272
|
+
share.`;
|
|
2273
|
+
}
|
|
2274
|
+
if (input.mode === "self-hosted") {
|
|
2275
|
+
return `## Installed Mode
|
|
2276
|
+
|
|
2277
|
+
Default storage for this installation: the configured self-hosted/custom Plan
|
|
2278
|
+
app${input.mcpUrl ? ` at \`${input.mcpUrl}\`` : ""}. Use that Plan MCP connector
|
|
2279
|
+
for plans and recaps instead of assuming \`https://plan.agent-native.com\`.`;
|
|
2280
|
+
}
|
|
2281
|
+
return "";
|
|
2282
|
+
}
|
|
2283
|
+
function applyPlanModeToSkillMarkdown(markdown, input) {
|
|
2284
|
+
if (input.appSkillId !== "visual-plans")
|
|
2285
|
+
return markdown;
|
|
2286
|
+
const block = planModeInstructionBlock({
|
|
2287
|
+
mode: input.mode,
|
|
2288
|
+
mcpUrl: input.mcpUrl,
|
|
2289
|
+
});
|
|
2290
|
+
return insertAfterFrontmatter(markdown, block);
|
|
2291
|
+
}
|
|
2292
|
+
function skillFilesForBuiltIn(appSkillId, options = {}) {
|
|
2248
2293
|
const entry = BUILT_IN_APP_SKILLS[appSkillId];
|
|
2249
2294
|
const skills = {
|
|
2250
|
-
[entry.skillName]: entry.skillMarkdown,
|
|
2295
|
+
[entry.skillName]: applyPlanModeToSkillMarkdown(entry.skillMarkdown, {
|
|
2296
|
+
appSkillId,
|
|
2297
|
+
mode: options.planMode,
|
|
2298
|
+
mcpUrl: options.mcpUrl,
|
|
2299
|
+
}),
|
|
2251
2300
|
...builtInExtraSkills(entry),
|
|
2252
2301
|
};
|
|
2302
|
+
for (const [skillName, skillMarkdown] of Object.entries(builtInExtraSkills(entry))) {
|
|
2303
|
+
skills[skillName] = applyPlanModeToSkillMarkdown(skillMarkdown, {
|
|
2304
|
+
appSkillId,
|
|
2305
|
+
mode: options.planMode,
|
|
2306
|
+
mcpUrl: options.mcpUrl,
|
|
2307
|
+
});
|
|
2308
|
+
}
|
|
2253
2309
|
const extraFiles = builtInExtraFiles(entry);
|
|
2254
2310
|
const out = {};
|
|
2255
2311
|
for (const [skillName, skillMarkdown] of Object.entries(skills)) {
|
|
@@ -2261,11 +2317,12 @@ function skillFilesForBuiltIn(appSkillId) {
|
|
|
2261
2317
|
appSkillId,
|
|
2262
2318
|
displayName: entry.manifest.displayName,
|
|
2263
2319
|
skillName,
|
|
2264
|
-
mcpUrl: isLocalOnlyBuiltInSkill(entry)
|
|
2320
|
+
mcpUrl: isLocalOnlyBuiltInSkill(entry) || options.planMode === "local-files"
|
|
2265
2321
|
? ""
|
|
2266
|
-
: entry.manifest.hosted.mcpUrl,
|
|
2322
|
+
: (options.mcpUrl ?? entry.manifest.hosted.mcpUrl),
|
|
2267
2323
|
files,
|
|
2268
2324
|
contentHash: stableSkillHash(files),
|
|
2325
|
+
planMode: options.planMode,
|
|
2269
2326
|
};
|
|
2270
2327
|
}
|
|
2271
2328
|
return out;
|
|
@@ -2295,6 +2352,7 @@ function writeSkillFolder(dir, bundle, installedAt = new Date().toISOString()) {
|
|
|
2295
2352
|
mcpUrl: bundle.mcpUrl,
|
|
2296
2353
|
installedAt,
|
|
2297
2354
|
updateCommand: `npx @agent-native/core@latest skills update ${bundle.skillName}`,
|
|
2355
|
+
...(bundle.planMode ? { planMode: bundle.planMode } : {}),
|
|
2298
2356
|
};
|
|
2299
2357
|
fs.writeFileSync(path.join(dir, AGENT_NATIVE_SKILL_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\n`, "utf-8");
|
|
2300
2358
|
}
|
|
@@ -2324,7 +2382,10 @@ function builtInSkillsRootForAgent(agent, scope, baseDir) {
|
|
|
2324
2382
|
* (which would have to be published to npm first). Returns the written folders.
|
|
2325
2383
|
*/
|
|
2326
2384
|
function installBuiltInInstructions(input) {
|
|
2327
|
-
const bundles = Object.values(skillFilesForBuiltIn(input.appSkillId
|
|
2385
|
+
const bundles = Object.values(skillFilesForBuiltIn(input.appSkillId, {
|
|
2386
|
+
planMode: input.planMode,
|
|
2387
|
+
mcpUrl: input.mcpUrl,
|
|
2388
|
+
})).filter((bundle) => !input.onlySkillNames || input.onlySkillNames.includes(bundle.skillName));
|
|
2328
2389
|
const written = [];
|
|
2329
2390
|
for (const agent of input.skillsAgents) {
|
|
2330
2391
|
const root = builtInSkillsRootForAgent(agent, input.scope, input.baseDir);
|
|
@@ -2438,7 +2499,7 @@ function clientFilterForStatus(parsed) {
|
|
|
2438
2499
|
}
|
|
2439
2500
|
function collectSkillInstallStates(parsed, options) {
|
|
2440
2501
|
const appSkillIds = targetIdsForStatus(parsed);
|
|
2441
|
-
const
|
|
2502
|
+
const defaultLatest = latestSkillBundlesForTargets(appSkillIds);
|
|
2442
2503
|
const roots = skillSearchRoots({
|
|
2443
2504
|
baseDir: options.baseDir ?? process.cwd(),
|
|
2444
2505
|
clients: clientFilterForStatus(parsed),
|
|
@@ -2447,7 +2508,7 @@ function collectSkillInstallStates(parsed, options) {
|
|
|
2447
2508
|
const states = [];
|
|
2448
2509
|
const seenDirs = new Set();
|
|
2449
2510
|
for (const root of roots) {
|
|
2450
|
-
for (const bundle of Object.values(
|
|
2511
|
+
for (const bundle of Object.values(defaultLatest)) {
|
|
2451
2512
|
const dir = path.join(root.root, bundle.skillName);
|
|
2452
2513
|
const resolvedDir = path.resolve(dir);
|
|
2453
2514
|
if (seenDirs.has(resolvedDir) || !fs.existsSync(dir))
|
|
@@ -2456,35 +2517,41 @@ function collectSkillInstallStates(parsed, options) {
|
|
|
2456
2517
|
continue;
|
|
2457
2518
|
seenDirs.add(resolvedDir);
|
|
2458
2519
|
const files = listSkillFolderFiles(dir);
|
|
2459
|
-
const installedHash = Object.keys(files).length > 0 ? stableSkillHash(files) : null;
|
|
2460
2520
|
const metadata = readSkillInstallMetadata(dir);
|
|
2521
|
+
const stateBundle = skillFilesForBuiltIn(bundle.appSkillId, {
|
|
2522
|
+
planMode: metadata?.planMode,
|
|
2523
|
+
mcpUrl: metadata?.mcpUrl,
|
|
2524
|
+
})[bundle.skillName] ?? bundle;
|
|
2525
|
+
const installedHash = Object.keys(files).length > 0 ? stableSkillHash(files) : null;
|
|
2461
2526
|
states.push({
|
|
2462
|
-
appSkillId:
|
|
2463
|
-
displayName:
|
|
2464
|
-
skillName:
|
|
2527
|
+
appSkillId: stateBundle.appSkillId,
|
|
2528
|
+
displayName: stateBundle.displayName,
|
|
2529
|
+
skillName: stateBundle.skillName,
|
|
2465
2530
|
path: dir,
|
|
2466
2531
|
root: root.root,
|
|
2467
2532
|
scope: root.scope,
|
|
2468
2533
|
client: root.client,
|
|
2469
|
-
latestHash:
|
|
2534
|
+
latestHash: stateBundle.contentHash,
|
|
2470
2535
|
installedHash,
|
|
2471
2536
|
metadataHash: metadata?.contentHash,
|
|
2472
|
-
current: installedHash ===
|
|
2537
|
+
current: installedHash === stateBundle.contentHash,
|
|
2473
2538
|
managed: metadata?.source === "agent-native",
|
|
2539
|
+
planMode: metadata?.planMode,
|
|
2540
|
+
mcpUrl: metadata?.mcpUrl,
|
|
2474
2541
|
});
|
|
2475
2542
|
}
|
|
2476
2543
|
}
|
|
2477
2544
|
return states.sort((a, b) => `${a.skillName}:${a.path}`.localeCompare(`${b.skillName}:${b.path}`));
|
|
2478
2545
|
}
|
|
2479
2546
|
function updateSkillInstallStates(states, dryRun) {
|
|
2480
|
-
const latest = latestSkillBundlesForTargets([
|
|
2481
|
-
...new Set(states.map((state) => state.appSkillId)),
|
|
2482
|
-
]);
|
|
2483
2547
|
const updated = [];
|
|
2484
2548
|
for (const state of states) {
|
|
2485
2549
|
if (state.current && state.managed)
|
|
2486
2550
|
continue;
|
|
2487
|
-
const bundle =
|
|
2551
|
+
const bundle = skillFilesForBuiltIn(state.appSkillId, {
|
|
2552
|
+
planMode: state.planMode,
|
|
2553
|
+
mcpUrl: state.mcpUrl,
|
|
2554
|
+
})[state.skillName];
|
|
2488
2555
|
if (!bundle)
|
|
2489
2556
|
continue;
|
|
2490
2557
|
if (!dryRun)
|
|
@@ -2622,6 +2689,56 @@ async function promptForScope(context) {
|
|
|
2622
2689
|
}
|
|
2623
2690
|
return result === "project" ? "project" : "user";
|
|
2624
2691
|
}
|
|
2692
|
+
async function promptForPlanMode(context) {
|
|
2693
|
+
const clack = await import("@clack/prompts");
|
|
2694
|
+
const result = await clack.select({
|
|
2695
|
+
message: "Where should visual plans and recaps live?",
|
|
2696
|
+
options: [
|
|
2697
|
+
{
|
|
2698
|
+
value: "hosted",
|
|
2699
|
+
label: "Hosted Plans, shareable links",
|
|
2700
|
+
hint: "Stores plans at plan.agent-native.com. Enables sharing, comments, browser editor. Requires one-time browser sign-in.",
|
|
2701
|
+
},
|
|
2702
|
+
{
|
|
2703
|
+
value: "local-files",
|
|
2704
|
+
label: "Local files only",
|
|
2705
|
+
hint: "Writes plans/<name>/plan.mdx in this repo and opens a local preview. No sharing, all local.",
|
|
2706
|
+
},
|
|
2707
|
+
{
|
|
2708
|
+
value: "self-hosted",
|
|
2709
|
+
label: "Self-hosted/custom URL",
|
|
2710
|
+
hint: "Connect to your own Plan app or local dev tunnel.",
|
|
2711
|
+
},
|
|
2712
|
+
],
|
|
2713
|
+
initialValue: context.initialMode,
|
|
2714
|
+
});
|
|
2715
|
+
if (clack.isCancel(result)) {
|
|
2716
|
+
clack.cancel("Cancelled.");
|
|
2717
|
+
return null;
|
|
2718
|
+
}
|
|
2719
|
+
return normalizePlanInstallMode(String(result));
|
|
2720
|
+
}
|
|
2721
|
+
async function promptForPlanMcpUrl() {
|
|
2722
|
+
const clack = await import("@clack/prompts");
|
|
2723
|
+
const result = await clack.text({
|
|
2724
|
+
message: "Plan app URL or MCP URL",
|
|
2725
|
+
placeholder: "https://my-plan-app.example.com",
|
|
2726
|
+
validate(value) {
|
|
2727
|
+
try {
|
|
2728
|
+
resolveMcpUrlOverride(value);
|
|
2729
|
+
return undefined;
|
|
2730
|
+
}
|
|
2731
|
+
catch (err) {
|
|
2732
|
+
return err?.message ?? "Enter a valid http:// or https:// URL.";
|
|
2733
|
+
}
|
|
2734
|
+
},
|
|
2735
|
+
});
|
|
2736
|
+
if (clack.isCancel(result)) {
|
|
2737
|
+
clack.cancel("Cancelled.");
|
|
2738
|
+
return null;
|
|
2739
|
+
}
|
|
2740
|
+
return String(result).trim();
|
|
2741
|
+
}
|
|
2625
2742
|
async function promptForSkills(context) {
|
|
2626
2743
|
const clack = await import("@clack/prompts");
|
|
2627
2744
|
const result = await clack.multiselect({
|
|
@@ -2659,6 +2776,30 @@ async function resolveSkillsClients(parsed, options) {
|
|
|
2659
2776
|
}
|
|
2660
2777
|
return selected;
|
|
2661
2778
|
}
|
|
2779
|
+
function normalizePlanInstallMode(value) {
|
|
2780
|
+
const normalized = value?.trim().toLowerCase();
|
|
2781
|
+
if (!normalized || normalized === "hosted")
|
|
2782
|
+
return "hosted";
|
|
2783
|
+
if (normalized === "local" ||
|
|
2784
|
+
normalized === "local-file" ||
|
|
2785
|
+
normalized === "local-files" ||
|
|
2786
|
+
normalized === "files") {
|
|
2787
|
+
return "local-files";
|
|
2788
|
+
}
|
|
2789
|
+
if (normalized === "self-hosted" ||
|
|
2790
|
+
normalized === "selfhosted" ||
|
|
2791
|
+
normalized === "custom" ||
|
|
2792
|
+
normalized === "custom-url") {
|
|
2793
|
+
return "self-hosted";
|
|
2794
|
+
}
|
|
2795
|
+
throw new Error('--mode must be one of "hosted", "local-files", or "self-hosted".');
|
|
2796
|
+
}
|
|
2797
|
+
function targetIncludesPlans(target) {
|
|
2798
|
+
return normalizeKnownSkillTarget(target) === "visual-plans";
|
|
2799
|
+
}
|
|
2800
|
+
function targetsIncludePlans(targets) {
|
|
2801
|
+
return targets.some(targetIncludesPlans);
|
|
2802
|
+
}
|
|
2662
2803
|
async function resolveSkillTargets(parsed, options) {
|
|
2663
2804
|
if (parsed.target || !shouldPrompt(parsed, options)) {
|
|
2664
2805
|
return [parsed.target ?? "assets"];
|
|
@@ -2755,6 +2896,14 @@ export function parseSkillsArgs(argv) {
|
|
|
2755
2896
|
}
|
|
2756
2897
|
else if ((value = eat("--mcp-url")) !== undefined)
|
|
2757
2898
|
out.mcpUrl = value;
|
|
2899
|
+
else if ((value = eat("--mode")) !== undefined)
|
|
2900
|
+
out.planMode = normalizePlanInstallMode(value);
|
|
2901
|
+
else if (arg === "--hosted")
|
|
2902
|
+
out.planMode = "hosted";
|
|
2903
|
+
else if (arg === "--local" || arg === "--local-files")
|
|
2904
|
+
out.planMode = "local-files";
|
|
2905
|
+
else if (arg === "--self-hosted" || arg === "--custom-url")
|
|
2906
|
+
out.planMode = "self-hosted";
|
|
2758
2907
|
else if (arg === "--yes" || arg === "-y")
|
|
2759
2908
|
out.yes = true;
|
|
2760
2909
|
else if (arg === "--dry-run")
|
|
@@ -2785,6 +2934,9 @@ export function parseSkillsArgs(argv) {
|
|
|
2785
2934
|
if (out.scope !== "user" && out.scope !== "project") {
|
|
2786
2935
|
throw new Error("--scope must be either user or project.");
|
|
2787
2936
|
}
|
|
2937
|
+
if (out.planMode === "local-files" && out.mcpUrl) {
|
|
2938
|
+
throw new Error("--mode local-files cannot be combined with --mcp-url.");
|
|
2939
|
+
}
|
|
2788
2940
|
return out;
|
|
2789
2941
|
}
|
|
2790
2942
|
function loadSkillTarget(target, onlySkillNames) {
|
|
@@ -2898,6 +3050,8 @@ function dryRunInstallCommand(parsed, target) {
|
|
|
2898
3050
|
"--scope",
|
|
2899
3051
|
parsed.scope,
|
|
2900
3052
|
];
|
|
3053
|
+
if (parsed.planMode)
|
|
3054
|
+
args.push("--mode", parsed.planMode);
|
|
2901
3055
|
if (parsed.mcpUrl)
|
|
2902
3056
|
args.push("--mcp-url", parsed.mcpUrl);
|
|
2903
3057
|
if (parsed.instructions && !parsed.mcp)
|
|
@@ -3159,6 +3313,20 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
|
|
|
3159
3313
|
export async function addAgentNativeSkill(parsed, options = {}) {
|
|
3160
3314
|
const target = parsed.target ?? "assets";
|
|
3161
3315
|
const knownTarget = normalizeKnownSkillTarget(target);
|
|
3316
|
+
const planMode = knownTarget === "visual-plans"
|
|
3317
|
+
? (parsed.planMode ?? (parsed.mcpUrl ? "self-hosted" : "hosted"))
|
|
3318
|
+
: undefined;
|
|
3319
|
+
if (parsed.planMode && knownTarget !== "visual-plans") {
|
|
3320
|
+
throw new Error("--mode only applies to visual-plan / visual-recap.");
|
|
3321
|
+
}
|
|
3322
|
+
if (planMode === "local-files" && parsed.mcpUrl) {
|
|
3323
|
+
throw new Error("--mode local-files cannot be combined with --mcp-url.");
|
|
3324
|
+
}
|
|
3325
|
+
if (planMode === "self-hosted" && !parsed.mcpUrl) {
|
|
3326
|
+
throw new Error("--mode self-hosted requires --mcp-url <url>.");
|
|
3327
|
+
}
|
|
3328
|
+
const shouldRegisterMcp = parsed.mcp &&
|
|
3329
|
+
!(knownTarget === "visual-plans" && planMode === "local-files");
|
|
3162
3330
|
// For multi-skill bundles (the plan bundle), a single-skill target installs
|
|
3163
3331
|
// only that skill. `installsRecap` controls the PR Visual Recap github-action
|
|
3164
3332
|
// offer, which is only relevant when the recap skill is part of the install.
|
|
@@ -3258,12 +3426,15 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3258
3426
|
displayName: installTarget.displayName,
|
|
3259
3427
|
skillNames: installTarget.skillNames,
|
|
3260
3428
|
skillsAgents,
|
|
3261
|
-
mcpUrl:
|
|
3262
|
-
|
|
3429
|
+
mcpUrl: knownTarget === "visual-plans" && planMode === "local-files"
|
|
3430
|
+
? ""
|
|
3431
|
+
: installTarget.loaded.manifest.hosted.mcpUrl,
|
|
3432
|
+
mcpClients: shouldRegisterMcp ? clients : [],
|
|
3263
3433
|
dryRun: true,
|
|
3264
3434
|
commands: [dryRunInstallCommand(parsed, target)],
|
|
3265
3435
|
githubActionPath,
|
|
3266
3436
|
githubActionSuggestedCommand,
|
|
3437
|
+
planMode,
|
|
3267
3438
|
};
|
|
3268
3439
|
}
|
|
3269
3440
|
finally {
|
|
@@ -3279,7 +3450,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3279
3450
|
try {
|
|
3280
3451
|
if (parsed.instructions) {
|
|
3281
3452
|
if (skillsAgents.length === 0) {
|
|
3282
|
-
if (!
|
|
3453
|
+
if (!shouldRegisterMcp) {
|
|
3283
3454
|
throw new Error("Skill instructions can only be installed for Codex or Claude Code clients. Use an MCP-capable client or omit --instructions-only.");
|
|
3284
3455
|
}
|
|
3285
3456
|
}
|
|
@@ -3295,6 +3466,8 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3295
3466
|
scope: parsed.scope,
|
|
3296
3467
|
baseDir: options.baseDir ?? process.cwd(),
|
|
3297
3468
|
dryRun: parsed.dryRun,
|
|
3469
|
+
planMode,
|
|
3470
|
+
mcpUrl: installTarget.loaded.manifest.hosted.mcpUrl,
|
|
3298
3471
|
});
|
|
3299
3472
|
instructionSource = instructionsWritten[0];
|
|
3300
3473
|
commands.push(...instructionsWritten.map((dir) => `write ${dir}`));
|
|
@@ -3333,7 +3506,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3333
3506
|
scope: parsed.scope,
|
|
3334
3507
|
dryRun: Boolean(parsed.dryRun),
|
|
3335
3508
|
});
|
|
3336
|
-
if (
|
|
3509
|
+
if (shouldRegisterMcp) {
|
|
3337
3510
|
commands.push(`npx @agent-native/core@latest app-skill ensure --manifest ${installTarget.loaded.file} --client ${parsed.client} --scope ${parsed.scope} --yes`);
|
|
3338
3511
|
if (!parsed.dryRun) {
|
|
3339
3512
|
await ensureAppSkill(installTarget.loaded, {
|
|
@@ -3414,13 +3587,16 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3414
3587
|
instructionSource,
|
|
3415
3588
|
skillNames: installTarget.skillNames,
|
|
3416
3589
|
skillsAgents,
|
|
3417
|
-
mcpUrl:
|
|
3418
|
-
|
|
3590
|
+
mcpUrl: knownTarget === "visual-plans" && planMode === "local-files"
|
|
3591
|
+
? ""
|
|
3592
|
+
: installTarget.loaded.manifest.hosted.mcpUrl,
|
|
3593
|
+
mcpClients: shouldRegisterMcp ? clients : [],
|
|
3419
3594
|
dryRun: parsed.dryRun,
|
|
3420
3595
|
commands,
|
|
3421
3596
|
written: instructionsWritten,
|
|
3422
3597
|
connected,
|
|
3423
3598
|
connectCommand,
|
|
3599
|
+
planMode,
|
|
3424
3600
|
githubActionPath,
|
|
3425
3601
|
githubActionExisted,
|
|
3426
3602
|
githubActionSuggestedCommand,
|
|
@@ -3454,6 +3630,7 @@ function skillStateJson(state) {
|
|
|
3454
3630
|
installedHash: state.installedHash,
|
|
3455
3631
|
latestHash: state.latestHash,
|
|
3456
3632
|
metadataHash: state.metadataHash,
|
|
3633
|
+
planMode: state.planMode,
|
|
3457
3634
|
};
|
|
3458
3635
|
}
|
|
3459
3636
|
function formatSkillState(state) {
|
|
@@ -3464,6 +3641,13 @@ function formatSkillState(state) {
|
|
|
3464
3641
|
: "";
|
|
3465
3642
|
return `${state.skillName.padEnd(22)} ${status.padEnd(7)} ${state.scope}/${state.client} ${managed}${hashes}\n ${state.path}`;
|
|
3466
3643
|
}
|
|
3644
|
+
function planModeSummary(mode) {
|
|
3645
|
+
if (mode === "local-files")
|
|
3646
|
+
return "Local files - No sharing, all local.";
|
|
3647
|
+
if (mode === "self-hosted")
|
|
3648
|
+
return "Self-hosted/custom Plan app";
|
|
3649
|
+
return "Hosted Plans - shareable links and comments";
|
|
3650
|
+
}
|
|
3467
3651
|
function runSkillsStatusOrUpdate(parsed, options, update) {
|
|
3468
3652
|
const before = collectSkillInstallStates(parsed, options);
|
|
3469
3653
|
const changed = update ? updateSkillInstallStates(before, parsed.dryRun) : [];
|
|
@@ -3586,6 +3770,45 @@ export async function runSkills(argv, options = {}) {
|
|
|
3586
3770
|
selectedAll: targets.length === skillPromptOptions().length,
|
|
3587
3771
|
preselected,
|
|
3588
3772
|
});
|
|
3773
|
+
const includesPlans = targetsIncludePlans(targets);
|
|
3774
|
+
if (parsed.planMode && !includesPlans) {
|
|
3775
|
+
throw new Error("--mode only applies to visual-plan / visual-recap.");
|
|
3776
|
+
}
|
|
3777
|
+
if (includesPlans) {
|
|
3778
|
+
if (!parsed.planMode && parsed.mcpUrl) {
|
|
3779
|
+
parsed.planMode = "self-hosted";
|
|
3780
|
+
}
|
|
3781
|
+
if (!parsed.planMode && shouldPrompt(parsed, options)) {
|
|
3782
|
+
const prompt = options.promptPlanMode ?? promptForPlanMode;
|
|
3783
|
+
const mode = await prompt({ initialMode: "hosted" });
|
|
3784
|
+
if (!mode) {
|
|
3785
|
+
telemetry.track("skills_cli cancelled", { step: "plan-mode" });
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
parsed.planMode = mode;
|
|
3789
|
+
}
|
|
3790
|
+
if (!parsed.planMode)
|
|
3791
|
+
parsed.planMode = "hosted";
|
|
3792
|
+
if (parsed.planMode === "self-hosted" && !parsed.mcpUrl) {
|
|
3793
|
+
if (shouldPrompt(parsed, options)) {
|
|
3794
|
+
const prompt = options.promptPlanMcpUrl ?? promptForPlanMcpUrl;
|
|
3795
|
+
const mcpUrl = await prompt();
|
|
3796
|
+
if (!mcpUrl) {
|
|
3797
|
+
telemetry.track("skills_cli cancelled", {
|
|
3798
|
+
step: "plan-mcp-url",
|
|
3799
|
+
});
|
|
3800
|
+
return;
|
|
3801
|
+
}
|
|
3802
|
+
parsed.mcpUrl = mcpUrl;
|
|
3803
|
+
}
|
|
3804
|
+
else {
|
|
3805
|
+
throw new Error("--mode self-hosted requires --mcp-url <url> in non-interactive mode.");
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
telemetry.track("skills_cli plan mode selected", {
|
|
3809
|
+
mode: parsed.planMode,
|
|
3810
|
+
});
|
|
3811
|
+
}
|
|
3589
3812
|
const clients = await resolveSkillsClients(parsed, optionsWithTelemetry);
|
|
3590
3813
|
if (!clients) {
|
|
3591
3814
|
telemetry.track("skills_cli cancelled", { step: "clients" });
|
|
@@ -3684,6 +3907,11 @@ export async function runSkills(argv, options = {}) {
|
|
|
3684
3907
|
.filter((result) => result.local)
|
|
3685
3908
|
.flatMap((result) => result.commands)),
|
|
3686
3909
|
];
|
|
3910
|
+
const planModes = [
|
|
3911
|
+
...new Set(results
|
|
3912
|
+
.map((result) => result.planMode)
|
|
3913
|
+
.filter((mode) => Boolean(mode))),
|
|
3914
|
+
];
|
|
3687
3915
|
const authConnected = results.some((result) => result.connected);
|
|
3688
3916
|
const pendingConnectCommands = [
|
|
3689
3917
|
...new Set(results
|
|
@@ -3720,6 +3948,9 @@ export async function runSkills(argv, options = {}) {
|
|
|
3720
3948
|
? `MCP config ${mcpClients.join(", ")}`
|
|
3721
3949
|
: "MCP config not required",
|
|
3722
3950
|
mcpUrls.length ? `MCP URL ${mcpUrls.join(", ")}` : "",
|
|
3951
|
+
planModes.length
|
|
3952
|
+
? `Plan mode ${planModes.map(planModeSummary).join(", ")}`
|
|
3953
|
+
: "",
|
|
3723
3954
|
authConnected
|
|
3724
3955
|
? "Authentication completed"
|
|
3725
3956
|
: pendingConnectCommands.length
|