@agent-native/core 0.48.4 → 0.49.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.
Files changed (126) hide show
  1. package/dist/agent/context-xray/actions/context-evict.d.ts +1 -1
  2. package/dist/agent/context-xray/actions/context-pin.d.ts +1 -1
  3. package/dist/agent/context-xray/actions/context-report.d.ts +4 -4
  4. package/dist/agent/context-xray/actions/context-restore.d.ts +1 -1
  5. package/dist/application-state/handlers.d.ts +2 -2
  6. package/dist/application-state/handlers.d.ts.map +1 -1
  7. package/dist/cli/app-skill.d.ts +157 -0
  8. package/dist/cli/app-skill.d.ts.map +1 -0
  9. package/dist/cli/app-skill.js +17 -7
  10. package/dist/cli/app-skill.js.map +1 -1
  11. package/dist/cli/audit-agent-web.d.ts +2 -0
  12. package/dist/cli/audit-agent-web.d.ts.map +1 -0
  13. package/dist/cli/code-agent-connector.d.ts +17 -0
  14. package/dist/cli/code-agent-connector.d.ts.map +1 -0
  15. package/dist/cli/code.d.ts +66 -0
  16. package/dist/cli/code.d.ts.map +1 -0
  17. package/dist/cli/connect.d.ts +168 -0
  18. package/dist/cli/connect.d.ts.map +1 -0
  19. package/dist/cli/connect.js +118 -30
  20. package/dist/cli/connect.js.map +1 -1
  21. package/dist/cli/context-xray-local.d.ts +16 -0
  22. package/dist/cli/context-xray-local.d.ts.map +1 -0
  23. package/dist/cli/create-workspace.d.ts +8 -0
  24. package/dist/cli/create-workspace.d.ts.map +1 -0
  25. package/dist/cli/index.d.ts +3 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/info.d.ts +2 -0
  28. package/dist/cli/info.d.ts.map +1 -0
  29. package/dist/cli/mcp-config-writers.d.ts +108 -0
  30. package/dist/cli/mcp-config-writers.d.ts.map +1 -0
  31. package/dist/cli/mcp-config-writers.js +143 -0
  32. package/dist/cli/mcp-config-writers.js.map +1 -1
  33. package/dist/cli/mcp.d.ts +16 -0
  34. package/dist/cli/mcp.d.ts.map +1 -0
  35. package/dist/cli/mcp.js +10 -10
  36. package/dist/cli/mcp.js.map +1 -1
  37. package/dist/cli/migrate.d.ts +38 -0
  38. package/dist/cli/migrate.d.ts.map +1 -0
  39. package/dist/cli/plan-local.d.ts +43 -0
  40. package/dist/cli/plan-local.d.ts.map +1 -0
  41. package/dist/cli/plan-publish-store.d.ts +62 -0
  42. package/dist/cli/plan-publish-store.d.ts.map +1 -0
  43. package/dist/cli/pr-visual-recap-workflow.d.ts +11 -0
  44. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -0
  45. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  46. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  47. package/dist/cli/recap.d.ts +453 -0
  48. package/dist/cli/recap.d.ts.map +1 -0
  49. package/dist/cli/recap.js +228 -95
  50. package/dist/cli/recap.js.map +1 -1
  51. package/dist/cli/skills.d.ts +193 -0
  52. package/dist/cli/skills.d.ts.map +1 -0
  53. package/dist/cli/skills.js +369 -171
  54. package/dist/cli/skills.js.map +1 -1
  55. package/dist/cli/telemetry.d.ts +13 -0
  56. package/dist/cli/telemetry.d.ts.map +1 -0
  57. package/dist/cli/telemetry.js +115 -0
  58. package/dist/cli/telemetry.js.map +1 -0
  59. package/dist/cli/workspace-dev.d.ts +96 -0
  60. package/dist/cli/workspace-dev.d.ts.map +1 -0
  61. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  62. package/dist/client/blocks/library/AnnotatedCodeBlock.js +15 -7
  63. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  64. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  65. package/dist/client/blocks/library/DiffBlock.js +17 -10
  66. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  67. package/dist/client/blocks/library/annotation-rail.d.ts +5 -0
  68. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  69. package/dist/client/blocks/library/annotation-rail.js +6 -0
  70. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  71. package/dist/client/blocks/types.d.ts +5 -0
  72. package/dist/client/blocks/types.d.ts.map +1 -1
  73. package/dist/client/blocks/types.js.map +1 -1
  74. package/dist/extensions/schema.d.ts +54 -54
  75. package/dist/extensions/slots/schema.d.ts +13 -13
  76. package/dist/file-upload/actions/upload-image.d.ts +4 -4
  77. package/dist/mcp/actions/create-org-service-token.d.ts +1 -1
  78. package/dist/mcp/actions/list-org-service-tokens.d.ts +7 -7
  79. package/dist/mcp/build-server.d.ts +12 -12
  80. package/dist/mcp/build-server.d.ts.map +1 -1
  81. package/dist/mcp/build-server.js.map +1 -1
  82. package/dist/mcp/connect-route.js +1 -1
  83. package/dist/mcp/connect-route.js.map +1 -1
  84. package/dist/mcp/oauth-route.d.ts +10 -0
  85. package/dist/mcp/oauth-route.d.ts.map +1 -1
  86. package/dist/mcp/oauth-route.js +34 -3
  87. package/dist/mcp/oauth-route.js.map +1 -1
  88. package/dist/mcp/oauth-store.d.ts +15 -1
  89. package/dist/mcp/oauth-store.d.ts.map +1 -1
  90. package/dist/mcp/oauth-store.js +60 -4
  91. package/dist/mcp/oauth-store.js.map +1 -1
  92. package/dist/mcp/oauth-token.d.ts +3 -1
  93. package/dist/mcp/oauth-token.d.ts.map +1 -1
  94. package/dist/mcp/oauth-token.js +78 -6
  95. package/dist/mcp/oauth-token.js.map +1 -1
  96. package/dist/mcp/server.d.ts.map +1 -1
  97. package/dist/mcp/server.js +8 -6
  98. package/dist/mcp/server.js.map +1 -1
  99. package/dist/observability/routes.d.ts +11 -11
  100. package/dist/org/handlers.d.ts +7 -11
  101. package/dist/org/handlers.d.ts.map +1 -1
  102. package/dist/secrets/schema.d.ts +7 -7
  103. package/dist/server/csrf.d.ts +1 -1
  104. package/dist/server/csrf.d.ts.map +1 -1
  105. package/dist/server/poll-events.d.ts +1 -1
  106. package/dist/server/security-headers.d.ts +1 -1
  107. package/dist/server/security-headers.d.ts.map +1 -1
  108. package/dist/sharing/actions/list-resource-shares.d.ts +3 -3
  109. package/dist/sharing/actions/set-resource-visibility.d.ts +2 -2
  110. package/dist/sharing/actions/share-resource.d.ts +4 -4
  111. package/dist/sharing/actions/unshare-resource.d.ts +1 -1
  112. package/dist/sharing/schema.d.ts +12 -12
  113. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +2 -2
  114. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +6 -6
  115. package/dist/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +2 -2
  116. package/dist/workspace-files/schema.d.ts +8 -8
  117. package/docs/content/deployment.md +32 -8
  118. package/docs/content/drop-in-agent.md +24 -17
  119. package/docs/content/external-agents.md +14 -0
  120. package/docs/content/plan-plugin.md +22 -7
  121. package/docs/content/template-content.md +36 -0
  122. package/docs/content/template-plan.md +22 -0
  123. package/package.json +5 -1
  124. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +2 -2
  125. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +6 -6
  126. package/src/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +2 -2
@@ -8,48 +8,50 @@ import os from "node:os";
8
8
  import path from "node:path";
9
9
  import { spawn } from "node:child_process";
10
10
  import { createHash } from "node:crypto";
11
+ import { fileURLToPath } from "node:url";
12
+ import { createCliTelemetry } from "./telemetry.js";
11
13
  import { buildAppSkillPack, ensureAppSkill, loadAppSkillManifest, normalizeAppSkillManifest, } from "./app-skill.js";
12
14
  import { readConnectClientPreferences, resolveClients, runConnect, writeConnectClientPreferences, } from "./connect.js";
13
15
  import { CONTEXT_XRAY_SKILL_MD, installLocalContextXray, } from "./context-xray-local.js";
14
16
  import { CLIENTS } from "./mcp-config-writers.js";
15
17
  import { PR_VISUAL_RECAP_SETUP, writePrVisualRecapWorkflow } from "./recap.js";
16
- const HELP = `agent-native skills
18
+ const HELP = `npx @agent-native/core@latest skills
17
19
 
18
20
  Usage:
19
- agent-native skills list
20
- agent-native skills status [assets|design-exploration|visual-plan|visual-recap|context-xray] [--client codex|claude-code|all] [--scope user|project] [--json]
21
- agent-native skills update [assets|design-exploration|visual-plan|visual-recap|context-xray] [--client codex|claude-code|all] [--scope user|project] [--dry-run] [--json]
22
- agent-native 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]
23
- agent-native skills add <manifest-or-app-dir|skill-repo> [--skill <name>] [--client ...] [--yes]
21
+ npx @agent-native/core@latest skills list
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
+ 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]
25
+ npx @agent-native/core@latest skills add <manifest-or-app-dir|skill-repo> [--skill <name>] [--client ...] [--yes]
24
26
 
25
27
  Examples:
26
- agent-native skills add assets
27
- agent-native skills add design-exploration
28
- agent-native skills add visual-plan
29
- agent-native skills add visual-recap
30
- agent-native skills add visual-recap --with-github-action
31
- agent-native skills status visual-plan
32
- agent-native skills update visual-plan
33
- agent-native skills add visual-plan --no-connect
34
- agent-native skills add context-xray --client all
35
- agent-native skills add assets --client claude-code
36
- agent-native skills add assets --mcp-url https://my-app.ngrok-free.dev
37
- agent-native skills add ./dist/assets-skill --client codex
38
- agent-native skills add BuilderIO/skills --client codex --scope project
39
- agent-native skills add BuilderIO/skills --with-github-action
28
+ npx @agent-native/core@latest skills add assets
29
+ npx @agent-native/core@latest skills add design-exploration
30
+ npx @agent-native/core@latest skills add visual-plan
31
+ npx @agent-native/core@latest skills add visual-recap
32
+ npx @agent-native/core@latest skills add visual-recap --with-github-action
33
+ npx @agent-native/core@latest skills status visual-plan
34
+ npx @agent-native/core@latest skills update visual-plan
35
+ npx @agent-native/core@latest skills add visual-plan --no-connect
36
+ npx @agent-native/core@latest skills add context-xray --client all
37
+ npx @agent-native/core@latest skills add assets --client claude-code
38
+ npx @agent-native/core@latest skills add assets --mcp-url https://my-app.ngrok-free.dev
39
+ npx @agent-native/core@latest skills add ./dist/assets-skill --client codex
40
+ npx @agent-native/core@latest skills add BuilderIO/skills --client codex --scope project
41
+ npx @agent-native/core@latest skills add BuilderIO/skills --with-github-action
40
42
 
41
43
  The add command installs the SKILL.md instructions, registers the app-backed
42
44
  MCP connector, and then authenticates it in one step so you do not hit an OAuth
43
- wall on the first tool call. Authentication reuses "agent-native connect":
45
+ wall on the first tool call. Authentication reuses "npx @agent-native/core@latest connect":
44
46
  OAuth-capable clients (Claude Code) get a URL-only entry and a /mcp authenticate
45
47
  prompt, while Codex / Cowork run the browser device-code flow. In a
46
48
  non-interactive shell or CI the auth step is skipped and the exact
47
- "agent-native connect <url>" command is printed instead.
49
+ "npx @agent-native/core@latest connect <url>" command is printed instead.
48
50
 
49
51
  Running "npx @agent-native/skills add ..." directly installs instructions only;
50
52
  use this Agent Native CLI path when you want MCP setup and auth too. Pass --no-connect to
51
53
  register the connector without authenticating (leave auth to the host or run
52
- "agent-native connect" later). Pass --mcp-url to register that connector against
54
+ "npx @agent-native/core@latest connect" later). Pass --mcp-url to register that connector against
53
55
  a custom origin (an ngrok tunnel, a local dev server, or a self-hosted
54
56
  deployment) instead of the built-in hosted default — a bare origin gets the
55
57
  standard /_agent-native/mcp path appended. Use app-skill pack for marketplace
@@ -57,7 +59,7 @@ bundles and custom adapter output.
57
59
 
58
60
  When installing visual-recap interactively, the CLI offers to add the optional PR
59
61
  Visual Recap GitHub Action. Pass --with-github-action to write it directly, then
60
- run "agent-native recap setup" / "agent-native recap doctor" to configure and
62
+ run "npx @agent-native/core@latest recap setup" / "npx @agent-native/core@latest recap doctor" to configure and
61
63
  verify GitHub Actions.
62
64
 
63
65
  The status/update commands inspect copied Agent Native skill folders and refresh
@@ -121,7 +123,7 @@ of using a generic image generator.
121
123
 
122
124
  - Hosted default: connect \`https://assets.agent-native.com/_agent-native/mcp\`.
123
125
  Do not put shared secrets in skill files.
124
- - For CLI/code-editor clients, keep any \`agent-native connect\` command
126
+ - For CLI/code-editor clients, keep any \`npx @agent-native/core@latest connect\` command
125
127
  running until browser authorization finishes. Stopping it early can leave the
126
128
  browser approved but the local MCP config unwritten. Restart or reload the
127
129
  agent client after installing or connecting if Assets tools do not appear in
@@ -131,9 +133,12 @@ of using a generic image generator.
131
133
  - Do not call image/video providers directly from another app. Assets owns
132
134
  generation, picker UI, search/list/export, and asset context.
133
135
  - If an Assets tool call returns \`Session terminated\`, \`needs auth\`, or
134
- another connector/session error, do not keep retrying the tool. Tell the user
135
- to reconnect or authenticate the Assets MCP connector, then continue after it
136
- is available.
136
+ another connector/session error, do not keep retrying the tool. Stop and give
137
+ the user the reconnect step: in Claude Code run \`/mcp\` and choose
138
+ Authenticate/Reconnect for the Assets connector; from any terminal run
139
+ \`npx @agent-native/core@latest reconnect https://assets.agent-native.com\` — this
140
+ re-authenticates WITHOUT reinstalling. Never reinstall from scratch just to fix
141
+ auth. Continue once the connector is available.
137
142
  - Do not hand-roll MCP HTTP requests with curl from the agent session. Use the
138
143
  host-exposed Assets tools after restart/reload, or use the returned
139
144
  browser/deep-link fallback.
@@ -193,7 +198,7 @@ iteration, or a human-in-the-loop choice among design directions.
193
198
 
194
199
  - Hosted default: connect \`https://design.agent-native.com/_agent-native/mcp\`.
195
200
  Do not put shared secrets in skill files.
196
- - For CLI/code-editor clients, keep any \`agent-native connect\` command
201
+ - For CLI/code-editor clients, keep any \`npx @agent-native/core@latest connect\` command
197
202
  running until browser authorization finishes. Stopping it early can leave the
198
203
  browser approved but the local MCP config unwritten. Restart or reload the
199
204
  agent client after installing or connecting if Design tools do not appear in
@@ -203,9 +208,12 @@ iteration, or a human-in-the-loop choice among design directions.
203
208
  - Keep the loop visual: surface the inline MCP App or the returned "Open
204
209
  design" link instead of pasting large HTML blobs into chat.
205
210
  - If a Design tool call returns \`Session terminated\`, \`needs auth\`, or
206
- another connector/session error, do not keep retrying the tool. Tell the user
207
- to reconnect or authenticate the Design MCP connector, then continue after it
208
- is available.
211
+ another connector/session error, do not keep retrying the tool. Stop and give
212
+ the user the reconnect step: in Claude Code run \`/mcp\` and choose
213
+ Authenticate/Reconnect for the Design connector; from any terminal run
214
+ \`npx @agent-native/core@latest reconnect https://design.agent-native.com\` — this
215
+ re-authenticates WITHOUT reinstalling. Never reinstall from scratch just to fix
216
+ auth. Continue once the connector is available.
209
217
  - Do not hand-roll MCP HTTP requests with curl from the agent session. Use the
210
218
  host-exposed Design tools after restart/reload, or use the returned
211
219
  browser/deep-link fallback.
@@ -251,10 +259,13 @@ your repo as MDX. This local mode is a separate advanced path, not the default
251
259
  hosted flow.
252
260
 
253
261
  If a Plans tool returns \`needs auth\`, \`Unauthorized\`, or \`Session terminated\`,
254
- do not keep retrying the tool. Authenticate the connector with
255
- \`npx @agent-native/core@latest connect https://plan.agent-native.com\` (OAuth-capable hosts can
256
- instead re-run /mcp and choose Authenticate), then continue once the connector
257
- is available.
262
+ do not keep retrying the tool. Stop and give the user the reconnect step: in
263
+ Claude Code run \`/mcp\` and choose Authenticate/Reconnect for the plan
264
+ connector; from any terminal run
265
+ \`npx @agent-native/core@latest reconnect https://plan.agent-native.com\` — this
266
+ re-authenticates WITHOUT reinstalling and finds the entry by URL regardless of
267
+ connector name. Never reinstall from scratch just to fix auth. Continue once
268
+ the connector is available.
258
269
 
259
270
  Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
260
271
  not put shared secrets in skill files.`;
@@ -916,11 +927,12 @@ plan over as inline chat content — no Markdown prose, ASCII sketch, table, or
916
927
  fenced wireframe. If the connector's tools are missing, do NOT fall back to
917
928
  inline output: the usual cause is a connector that did not finish connecting
918
929
  this session (it registers zero tools), not auth. Stop and give the user the
919
- exact restore step — reconnect via \`/mcp\` (or restart the session); only if
920
- genuinely unauthenticated, run
921
- \`npx @agent-native/core@latest connect https://plan.agent-native.com\`. Publish once the tool is
922
- reachable. Local-files privacy mode (after Tool Guidance) is the only
923
- exception.
930
+ exact restore step — in Claude Code run \`/mcp\` and choose
931
+ Authenticate/Reconnect (or restart the session); if genuinely unauthenticated,
932
+ run \`npx @agent-native/core@latest reconnect https://plan.agent-native.com\` this
933
+ re-authenticates WITHOUT reinstalling. Never reinstall from scratch just to fix
934
+ auth. Publish once the tool is reachable. Local-files privacy mode (after Tool
935
+ Guidance) is the only exception.
924
936
 
925
937
  ## Core Workflow
926
938
 
@@ -1224,10 +1236,13 @@ because it is named \`agent-native-plans\` instead of \`plan\`. The usual cause
1224
1236
  connector that did not finish connecting this session (it registers zero tools),
1225
1237
  NOT necessarily an auth problem — so do not assume the user must authenticate.
1226
1238
  Stop and tell the user how to restore it: reconnect the Plan MCP connector (in
1227
- Claude Code, run \`/mcp\` and reconnect, or restart the session); only if it is
1228
- genuinely unauthenticated, run \`npx @agent-native/core@latest connect <plan-app-url>\` or
1229
- re-authenticate via \`/mcp\`. Then publish once the tool is reachable. Falling
1230
- back to inline content is a defect, not a degraded mode.
1239
+ Claude Code, run \`/mcp\` and choose Authenticate/Reconnect, or restart the
1240
+ session); if it is genuinely unauthenticated, run
1241
+ \`npx @agent-native/core@latest reconnect https://plan.agent-native.com\` this
1242
+ re-authenticates WITHOUT reinstalling and finds the entry by URL regardless of
1243
+ connector name. Never reinstall from scratch just to fix auth. Then publish once
1244
+ the tool is reachable. Falling back to inline content is a defect, not a
1245
+ degraded mode.
1231
1246
 
1232
1247
  ## When To Use
1233
1248
 
@@ -2025,7 +2040,7 @@ function writeSkillFolder(dir, bundle, installedAt = new Date().toISOString()) {
2025
2040
  contentHash: bundle.contentHash,
2026
2041
  mcpUrl: bundle.mcpUrl,
2027
2042
  installedAt,
2028
- updateCommand: `agent-native skills update ${bundle.skillName}`,
2043
+ updateCommand: `npx @agent-native/core@latest skills update ${bundle.skillName}`,
2029
2044
  };
2030
2045
  fs.writeFileSync(path.join(dir, AGENT_NATIVE_SKILL_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\n`, "utf-8");
2031
2046
  }
@@ -2152,7 +2167,7 @@ function targetIdsForStatus(parsed) {
2152
2167
  }
2153
2168
  const known = normalizeKnownSkillTarget(parsed.target);
2154
2169
  if (!known) {
2155
- throw new Error(`Unknown built-in skill: ${parsed.target}. Run "agent-native skills list".`);
2170
+ throw new Error(`Unknown built-in skill: ${parsed.target}. Run "npx @agent-native/core@latest skills list".`);
2156
2171
  }
2157
2172
  if (isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[known])) {
2158
2173
  throw new Error(`${BUILT_IN_APP_SKILLS[known].manifest.displayName} is installed as a local command and cannot be refreshed with skills update yet.`);
@@ -2290,8 +2305,11 @@ function prVisualRecapSetupCommand() {
2290
2305
  async function promptForGithubAction(context) {
2291
2306
  const clack = await import("@clack/prompts");
2292
2307
  const result = await clack.confirm({
2293
- message: "Optional: add automatic PR Visual Recaps?\n" +
2294
- ` This writes ${context.workflowPath}; ${context.setupCommand} can finish GitHub secrets.`,
2308
+ message: "Optional: add automatic PR Visual Recaps? (GitHub Action)\n" +
2309
+ " Posts a human-friendly recap on every pull request — a high-altitude\n" +
2310
+ " overview of what the PR does, with annotated code, diagrams, and\n" +
2311
+ " before/after notes instead of a raw diff.\n" +
2312
+ ` Writes ${context.workflowPath}; ${context.setupCommand} finishes the GitHub secrets.`,
2295
2313
  initialValue: false,
2296
2314
  });
2297
2315
  if (clack.isCancel(result)) {
@@ -2392,9 +2410,16 @@ async function resolveSkillTargets(parsed, options) {
2392
2410
  return [parsed.target ?? "assets"];
2393
2411
  }
2394
2412
  const prompt = options.promptSkills ?? promptForSkills;
2413
+ const promptOptions = skillPromptOptions();
2414
+ // The interactive multiselect skill picker is about to be shown (no --skill /
2415
+ // target passed and we are interactive) — record the funnel "prompted" step.
2416
+ options.telemetry?.track("skills_cli skills prompted", {
2417
+ availableCount: promptOptions.length,
2418
+ available: promptOptions.map((option) => option.value).join(","),
2419
+ });
2395
2420
  const selected = await prompt({
2396
2421
  initialTargets: ["visual-plan", "visual-recap"],
2397
- options: skillPromptOptions(),
2422
+ options: promptOptions,
2398
2423
  });
2399
2424
  if (!selected || selected.length === 0)
2400
2425
  return null;
@@ -2610,6 +2635,7 @@ function preserveMcpUrlAppPathOverride(target, input) {
2610
2635
  function dryRunInstallCommand(parsed, target) {
2611
2636
  const clients = parsed.clients ?? resolveClients(parsed.client);
2612
2637
  const args = [
2638
+ "@agent-native/core@latest",
2613
2639
  "skills",
2614
2640
  "add",
2615
2641
  target,
@@ -2634,7 +2660,7 @@ function dryRunInstallCommand(parsed, target) {
2634
2660
  args.push("--no-update-instructions");
2635
2661
  if (parsed.yes || isKnownSkill(target))
2636
2662
  args.push("--yes");
2637
- return commandString("agent-native", args);
2663
+ return commandString("npx", args);
2638
2664
  }
2639
2665
  async function runCommand(cmd, args, options = {}) {
2640
2666
  return new Promise((resolve, reject) => {
@@ -2784,6 +2810,12 @@ async function addPlainSkillRepo(parsed, options) {
2784
2810
  if (code !== 0)
2785
2811
  throw new Error(`npx @agent-native/skills add exited with ${code}.`);
2786
2812
  }
2813
+ options.telemetry?.track("skills_cli install completed", {
2814
+ skills: target,
2815
+ clients: clients.join(","),
2816
+ scope: parsed.scope,
2817
+ dryRun: Boolean(parsed.dryRun),
2818
+ });
2787
2819
  return {
2788
2820
  id: target,
2789
2821
  displayName: target,
@@ -2813,6 +2845,7 @@ function canRunInteractiveConnect(options) {
2813
2845
  /** Build the `npx @agent-native/core@latest connect <url> --client … --scope …` command. */
2814
2846
  function connectCommandFor(hostedUrl, clients, scope) {
2815
2847
  const args = [
2848
+ "@agent-native/core@latest",
2816
2849
  "connect",
2817
2850
  hostedUrl,
2818
2851
  "--client",
@@ -2820,7 +2853,7 @@ function connectCommandFor(hostedUrl, clients, scope) {
2820
2853
  "--scope",
2821
2854
  scope,
2822
2855
  ];
2823
- return commandString("agent-native", args);
2856
+ return commandString("npx", args);
2824
2857
  }
2825
2858
  /**
2826
2859
  * Authenticate the freshly-registered hosted MCP connector so the user does not
@@ -2845,6 +2878,7 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
2845
2878
  return { connected: false, connectCommand };
2846
2879
  }
2847
2880
  options.log?.(`Authenticating ${installTarget.displayName}…`);
2881
+ options.telemetry?.track("skills_cli connect started");
2848
2882
  try {
2849
2883
  await (options.runConnect ?? runConnect)([
2850
2884
  hostedUrl,
@@ -2853,10 +2887,14 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
2853
2887
  "--scope",
2854
2888
  parsed.scope,
2855
2889
  ]);
2890
+ options.telemetry?.track("skills_cli connect completed");
2856
2891
  return { connected: true, connectCommand: "" };
2857
2892
  }
2858
2893
  catch (err) {
2859
2894
  // Non-fatal: the MCP connector is registered. Surface the manual command.
2895
+ options.telemetry?.track("skills_cli connect failed", {
2896
+ error: err?.message ?? String(err),
2897
+ });
2860
2898
  options.log?.(`Could not finish authentication automatically (${err?.message ?? err}). ` +
2861
2899
  `Run it later with: ${connectCommand}`);
2862
2900
  return { connected: false, connectCommand };
@@ -2877,7 +2915,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
2877
2915
  return addPlainSkillRepo({ ...parsed, target }, options);
2878
2916
  }
2879
2917
  if (!knownTarget && !fs.existsSync(path.resolve(target))) {
2880
- throw new Error(`Unknown skill or manifest path: ${target}. Run "agent-native skills list".`);
2918
+ throw new Error(`Unknown skill or manifest path: ${target}. Run "npx @agent-native/core@latest skills list".`);
2881
2919
  }
2882
2920
  const knownBuiltIn = knownTarget ? BUILT_IN_APP_SKILLS[knownTarget] : null;
2883
2921
  if (isLocalOnlyBuiltInSkill(knownBuiltIn)) {
@@ -2893,6 +2931,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
2893
2931
  const githubActionPath = parsed.withGithubAction && knownTarget === "visual-plans"
2894
2932
  ? prVisualRecapWorkflowDisplayPath()
2895
2933
  : undefined;
2934
+ options.telemetry?.track("skills_cli install completed", {
2935
+ skills: knownBuiltIn.skillName,
2936
+ clients: clients.join(","),
2937
+ scope: parsed.scope,
2938
+ dryRun: true,
2939
+ });
2896
2940
  return {
2897
2941
  id: knownBuiltIn.manifest.id,
2898
2942
  displayName: knownBuiltIn.manifest.displayName,
@@ -2911,6 +2955,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
2911
2955
  clients,
2912
2956
  scope: parsed.scope,
2913
2957
  });
2958
+ options.telemetry?.track("skills_cli install completed", {
2959
+ skills: knownBuiltIn.skillName,
2960
+ clients: clients.join(","),
2961
+ scope: parsed.scope,
2962
+ dryRun: false,
2963
+ });
2914
2964
  return {
2915
2965
  id: knownBuiltIn.manifest.id,
2916
2966
  displayName: knownBuiltIn.manifest.displayName,
@@ -2941,6 +2991,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
2941
2991
  const githubActionSuggestedCommand = installsRecap && !parsed.withGithubAction
2942
2992
  ? prVisualRecapInstallCommand()
2943
2993
  : undefined;
2994
+ options.telemetry?.track("skills_cli install completed", {
2995
+ skills: installTarget.skillNames.join(","),
2996
+ clients: clients.join(","),
2997
+ scope: parsed.scope,
2998
+ dryRun: true,
2999
+ });
2944
3000
  return {
2945
3001
  id: installTarget.id,
2946
3002
  displayName: installTarget.displayName,
@@ -3013,6 +3069,14 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3013
3069
  }
3014
3070
  }
3015
3071
  }
3072
+ // Skill instructions are now on disk (built-in folders copied or external
3073
+ // pack materialized) — record the install before MCP registration/connect.
3074
+ options.telemetry?.track("skills_cli install completed", {
3075
+ skills: installTarget.skillNames.join(","),
3076
+ clients: clients.join(","),
3077
+ scope: parsed.scope,
3078
+ dryRun: Boolean(parsed.dryRun),
3079
+ });
3016
3080
  if (parsed.mcp) {
3017
3081
  commands.push(`npx @agent-native/core@latest app-skill ensure --manifest ${installTarget.loaded.file} --client ${parsed.client} --scope ${parsed.scope} --yes`);
3018
3082
  if (!parsed.dryRun) {
@@ -3024,6 +3088,9 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3024
3088
  confirm: true,
3025
3089
  log: options.log,
3026
3090
  });
3091
+ options.telemetry?.track("skills_cli mcp registered", {
3092
+ skills: installTarget.skillNames.join(","),
3093
+ });
3027
3094
  // One-step install + authenticate: after registering a hosted MCP
3028
3095
  // connector, kick off the existing connect/device-code flow so the user
3029
3096
  // does not hit an OAuth wall on the first tool call. `--no-connect`
@@ -3047,13 +3114,21 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3047
3114
  if (installsRecap &&
3048
3115
  !withGithubAction &&
3049
3116
  !fs.existsSync(prVisualRecapWorkflowPath(baseDir))) {
3050
- if (shouldPrompt(parsed, options)) {
3117
+ // Normally the recap decision is made up front in `runSkills` (so it's
3118
+ // resolved here). Only prompt inline when a direct caller invoked
3119
+ // addAgentNativeSkill without going through that up-front step.
3120
+ if (!parsed.githubActionResolved && shouldPrompt(parsed, options)) {
3051
3121
  const prompt = options.promptGithubAction ?? promptForGithubAction;
3052
- withGithubAction =
3053
- (await prompt({
3054
- workflowPath: prVisualRecapWorkflowDisplayPath(),
3055
- setupCommand: prVisualRecapSetupCommand(),
3056
- })) === true;
3122
+ const choice = await prompt({
3123
+ workflowPath: prVisualRecapWorkflowDisplayPath(),
3124
+ setupCommand: prVisualRecapSetupCommand(),
3125
+ });
3126
+ if (choice === null) {
3127
+ options.telemetry?.track("skills_cli cancelled", {
3128
+ step: "github-action",
3129
+ });
3130
+ }
3131
+ withGithubAction = choice === true;
3057
3132
  }
3058
3133
  if (!withGithubAction) {
3059
3134
  githubActionSuggestedCommand = prVisualRecapInstallCommand();
@@ -3074,6 +3149,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3074
3149
  githubActionExisted =
3075
3150
  writeResult.status === "written" ? writeResult.existed : false;
3076
3151
  commands.push(`write ${writeResult.path}`);
3152
+ options.telemetry?.track("skills_cli github action added");
3077
3153
  }
3078
3154
  }
3079
3155
  return {
@@ -3153,7 +3229,7 @@ function runSkillsStatusOrUpdate(parsed, options, update) {
3153
3229
  }
3154
3230
  if (before.length === 0) {
3155
3231
  const target = parsed.target ? ` for ${parsed.target}` : "";
3156
- process.stdout.write(`No installed Agent Native skill copies found${target}.\nRun "agent-native skills add ${parsed.target ?? "visual-plan"}" to install one.\n`);
3232
+ process.stdout.write(`No installed Agent Native skill copies found${target}.\nRun "npx @agent-native/core@latest skills add ${parsed.target ?? "visual-plan"}" to install one.\n`);
3157
3233
  return;
3158
3234
  }
3159
3235
  if (update) {
@@ -3171,6 +3247,21 @@ function runSkillsStatusOrUpdate(parsed, options, update) {
3171
3247
  const rows = (update && parsed.dryRun ? before : after).map(formatSkillState);
3172
3248
  process.stdout.write(`${rows.join("\n")}\n`);
3173
3249
  }
3250
+ /**
3251
+ * Resolve the CLI version the same way `index.ts` does — read it from the
3252
+ * package.json two levels up from the compiled module (dist/cli/skills.js →
3253
+ * ../../package.json). Best-effort: falls back to "unknown".
3254
+ */
3255
+ function readCliVersion() {
3256
+ try {
3257
+ const here = path.dirname(fileURLToPath(import.meta.url));
3258
+ const pkg = JSON.parse(fs.readFileSync(path.resolve(here, "../../package.json"), "utf8"));
3259
+ return typeof pkg.version === "string" ? pkg.version : "unknown";
3260
+ }
3261
+ catch {
3262
+ return "unknown";
3263
+ }
3264
+ }
3174
3265
  export async function runSkills(argv, options = {}) {
3175
3266
  const parsed = parseSkillsArgs(argv);
3176
3267
  const log = parsed.printJson
@@ -3180,124 +3271,231 @@ export async function runSkills(argv, options = {}) {
3180
3271
  process.stdout.write(`${HELP}\n`);
3181
3272
  return;
3182
3273
  }
3183
- if (parsed.command === "list") {
3184
- const skills = listSkills();
3274
+ // `@agent-native/skills` now delegates its interactive install to this
3275
+ // function. For plain skill repos we still shell out to
3276
+ // `npx @agent-native/skills add …`; this env guard tells that child process
3277
+ // to run its OWN headless installer instead of bouncing back into core,
3278
+ // which would otherwise be an infinite skills → core → skills loop.
3279
+ process.env.AGENT_NATIVE_SKILLS_DIRECT = "1";
3280
+ // Best-effort install-funnel telemetry. Created once per run and flushed in a
3281
+ // finally so events send on success, error, and cancellation — the CLI is
3282
+ // short-lived, so flushing before exit is essential or the events never send.
3283
+ const startedAt = Date.now();
3284
+ const telemetry = options.telemetry ??
3285
+ createCliTelemetry({
3286
+ cli: "core",
3287
+ cliVersion: readCliVersion(),
3288
+ command: parsed.command,
3289
+ interactive: shouldPrompt(parsed, options),
3290
+ });
3291
+ const optionsWithTelemetry = { ...options, telemetry };
3292
+ try {
3293
+ telemetry.track("skills_cli started");
3294
+ if (parsed.command === "list") {
3295
+ const skills = listSkills();
3296
+ telemetry.track("skills_cli skills listed", {
3297
+ availableCount: skills.length,
3298
+ available: skills.map((skill) => skill.id).join(","),
3299
+ });
3300
+ if (parsed.printJson) {
3301
+ process.stdout.write(`${JSON.stringify(skills, null, 2)}\n`);
3302
+ return;
3303
+ }
3304
+ for (const skill of skills) {
3305
+ const description = skill.description.replace(/[.?!]?$/, ".");
3306
+ const aliases = skill.aliases.length
3307
+ ? ` Aliases: ${skill.aliases.join(", ")}.`
3308
+ : "";
3309
+ const target = skill.local ? "local command" : skill.mcpUrl;
3310
+ process.stdout.write(`${skill.id.padEnd(12)} ${description}${aliases} (${target})\n`);
3311
+ }
3312
+ return;
3313
+ }
3314
+ if (parsed.command === "status" || parsed.command === "update") {
3315
+ runSkillsStatusOrUpdate(parsed, options, parsed.command === "update");
3316
+ return;
3317
+ }
3318
+ const targets = await resolveSkillTargets(parsed, optionsWithTelemetry);
3319
+ if (!targets) {
3320
+ telemetry.track("skills_cli cancelled", { step: "skills" });
3321
+ return;
3322
+ }
3323
+ const preselected = Boolean(parsed.target);
3324
+ telemetry.track("skills_cli skills selected", {
3325
+ selected: targets.join(","),
3326
+ selectedCount: targets.length,
3327
+ // Best-effort "took everything offered" signal: compare against the
3328
+ // interactive picker's option count (the plan sub-skills collapse into a
3329
+ // single bundle target, so this is approximate, like the standalone CLI).
3330
+ selectedAll: targets.length === skillPromptOptions().length,
3331
+ preselected,
3332
+ });
3333
+ const clients = await resolveSkillsClients(parsed, optionsWithTelemetry);
3334
+ if (!clients) {
3335
+ telemetry.track("skills_cli cancelled", { step: "clients" });
3336
+ return;
3337
+ }
3338
+ telemetry.track("skills_cli clients selected", {
3339
+ clients: clients.join(","),
3340
+ clientCount: clients.length,
3341
+ });
3342
+ // Ask where to install (project vs user) unless an explicit --scope was
3343
+ // passed or we are running non-interactively.
3344
+ if (!parsed.scopeExplicit && shouldPrompt(parsed, options)) {
3345
+ const promptScope = options.promptScope ?? promptForScope;
3346
+ const scope = await promptScope({ initialScope: "project" });
3347
+ if (!scope) {
3348
+ telemetry.track("skills_cli cancelled", { step: "scope" });
3349
+ return;
3350
+ }
3351
+ parsed.scope = scope;
3352
+ }
3353
+ telemetry.track("skills_cli scope selected", { scope: parsed.scope });
3354
+ // Decide the optional PR Visual Recap GitHub Action UP FRONT — before any
3355
+ // install or MCP registration — so every prompt is answered before we touch
3356
+ // disk. The choice is threaded into each install via `withGithubAction` +
3357
+ // `githubActionResolved` (so addAgentNativeSkill doesn't re-prompt mid-flow).
3358
+ const recapBaseDir = options.baseDir ?? process.cwd();
3359
+ const anyRecapTarget = targets.some((target) => {
3360
+ if (normalizeKnownSkillTarget(target) !== "visual-plans")
3361
+ return false;
3362
+ const only = builtInOnlySkillNames(target);
3363
+ return !only || only.includes("visual-recap");
3364
+ });
3365
+ if (anyRecapTarget &&
3366
+ !parsed.withGithubAction &&
3367
+ !fs.existsSync(prVisualRecapWorkflowPath(recapBaseDir)) &&
3368
+ shouldPrompt(parsed, options)) {
3369
+ const prompt = options.promptGithubAction ?? promptForGithubAction;
3370
+ const choice = await prompt({
3371
+ workflowPath: prVisualRecapWorkflowDisplayPath(),
3372
+ setupCommand: prVisualRecapSetupCommand(),
3373
+ });
3374
+ if (choice === null) {
3375
+ telemetry.track("skills_cli cancelled", { step: "github-action" });
3376
+ }
3377
+ parsed.withGithubAction = choice === true;
3378
+ parsed.githubActionResolved = true;
3379
+ }
3380
+ const results = [];
3381
+ for (const target of targets) {
3382
+ results.push(await addAgentNativeSkill({
3383
+ ...parsed,
3384
+ target,
3385
+ client: clientArgForClients(clients),
3386
+ clients,
3387
+ }, {
3388
+ ...optionsWithTelemetry,
3389
+ log,
3390
+ }));
3391
+ }
3392
+ // The add flow succeeded for every target — record the funnel completion
3393
+ // before printing output (output below cannot fail the install).
3394
+ const completedSkills = [
3395
+ ...new Set(results.flatMap((result) => result.skillNames)),
3396
+ ];
3397
+ const completedClients = [
3398
+ ...new Set(results.flatMap((result) => result.mcpClients)),
3399
+ ];
3400
+ telemetry.track("skills_cli completed", {
3401
+ skills: completedSkills.join(","),
3402
+ clients: completedClients.join(","),
3403
+ scope: parsed.scope,
3404
+ durationMs: Date.now() - startedAt,
3405
+ });
3185
3406
  if (parsed.printJson) {
3186
- process.stdout.write(`${JSON.stringify(skills, null, 2)}\n`);
3407
+ process.stdout.write(`${JSON.stringify(results.length === 1 ? results[0] : results, null, 2)}\n`);
3187
3408
  return;
3188
3409
  }
3189
- for (const skill of skills) {
3190
- const description = skill.description.replace(/[.?!]?$/, ".");
3191
- const aliases = skill.aliases.length
3192
- ? ` Aliases: ${skill.aliases.join(", ")}.`
3410
+ if (parsed.dryRun) {
3411
+ process.stdout.write(`${results.flatMap((result) => result.commands).join("\n")}\n`);
3412
+ return;
3413
+ }
3414
+ const installedNames = results
3415
+ .map((result) => result.displayName)
3416
+ .join(", ");
3417
+ const skillsAgents = [
3418
+ ...new Set(results.flatMap((result) => result.skillsAgents)),
3419
+ ];
3420
+ const mcpClients = [
3421
+ ...new Set(results.flatMap((result) => result.mcpClients)),
3422
+ ];
3423
+ const mcpUrls = [
3424
+ ...new Set(results.map((result) => result.mcpUrl).filter(Boolean)),
3425
+ ];
3426
+ const localCommands = [
3427
+ ...new Set(results
3428
+ .filter((result) => result.local)
3429
+ .flatMap((result) => result.commands)),
3430
+ ];
3431
+ const authConnected = results.some((result) => result.connected);
3432
+ const pendingConnectCommands = [
3433
+ ...new Set(results
3434
+ .map((result) => result.connectCommand)
3435
+ .filter((command) => Boolean(command))),
3436
+ ];
3437
+ const authLine = authConnected
3438
+ ? "Authentication: completed."
3439
+ : pendingConnectCommands.length
3440
+ ? `Authentication: pending — run ${pendingConnectCommands.join(" && ")}`
3193
3441
  : "";
3194
- const target = skill.local ? "local command" : skill.mcpUrl;
3195
- process.stdout.write(`${skill.id.padEnd(12)} ${description}${aliases} (${target})\n`);
3442
+ const githubActions = [
3443
+ ...new Set(results
3444
+ .map((result) => result.githubActionPath)
3445
+ .filter((p) => Boolean(p))),
3446
+ ];
3447
+ const githubActionLine = githubActions.length
3448
+ ? `PR Visual Recap workflow: wrote ${githubActions.join(", ")}.\nNext: run ${prVisualRecapSetupCommand()} to configure GitHub secrets/variables, or set them manually:\n ${PR_VISUAL_RECAP_SETUP.join("\n ")}`
3449
+ : "";
3450
+ const githubActionSuggestions = [
3451
+ ...new Set(results
3452
+ .map((result) => result.githubActionSuggestedCommand)
3453
+ .filter((command) => Boolean(command))),
3454
+ ];
3455
+ const githubActionSuggestionLine = githubActionSuggestions.length
3456
+ ? `Optional PR Visual Recap workflow: run ${githubActionSuggestions.join(" && ")} to add automatic recap comments on pull requests.`
3457
+ : "";
3458
+ const clack = await import("@clack/prompts");
3459
+ const summary = [
3460
+ skillsAgents.length
3461
+ ? `Skill instructions ${skillsAgents.join(", ")}`
3462
+ : "Skill instructions skipped",
3463
+ mcpClients.length
3464
+ ? `MCP config ${mcpClients.join(", ")}`
3465
+ : "MCP config not required",
3466
+ mcpUrls.length ? `MCP URL ${mcpUrls.join(", ")}` : "",
3467
+ authConnected
3468
+ ? "Authentication completed"
3469
+ : pendingConnectCommands.length
3470
+ ? `Authentication pending — run ${pendingConnectCommands.join(" && ")}`
3471
+ : "",
3472
+ localCommands.length
3473
+ ? `Local command ${localCommands.join(", ")}`
3474
+ : "",
3475
+ ].filter(Boolean);
3476
+ clack.note(summary.join("\n"), `Installed ${installedNames} skill${results.length === 1 ? "" : "s"}`);
3477
+ // GitHub Action follow-ups — kept as exact, copy-pasteable command lines.
3478
+ for (const line of [githubActionLine, githubActionSuggestionLine].filter(Boolean)) {
3479
+ process.stdout.write(`${line}\n`);
3196
3480
  }
3197
- return;
3198
- }
3199
- if (parsed.command === "status" || parsed.command === "update") {
3200
- runSkillsStatusOrUpdate(parsed, options, parsed.command === "update");
3201
- return;
3202
- }
3203
- const targets = await resolveSkillTargets(parsed, options);
3204
- if (!targets)
3205
- return;
3206
- const clients = await resolveSkillsClients(parsed, options);
3207
- if (!clients)
3208
- return;
3209
- // Ask where to install (project vs user) unless an explicit --scope was
3210
- // passed or we are running non-interactively.
3211
- if (!parsed.scopeExplicit && shouldPrompt(parsed, options)) {
3212
- const promptScope = options.promptScope ?? promptForScope;
3213
- const scope = await promptScope({ initialScope: "project" });
3214
- if (!scope)
3215
- return;
3216
- parsed.scope = scope;
3217
- }
3218
- const results = [];
3219
- for (const target of targets) {
3220
- results.push(await addAgentNativeSkill({
3221
- ...parsed,
3222
- target,
3223
- client: clientArgForClients(clients),
3224
- clients,
3225
- }, {
3226
- ...options,
3227
- log,
3228
- }));
3481
+ const slashCommands = completedSkills.map((name) => `/${name}`).join(" ");
3482
+ const clientHint = parsed.clientExplicit
3483
+ ? ""
3484
+ : "\n Add another client later with --client <client> (e.g. --client claude-code).";
3485
+ clack.outro(`✅ All set! Start using ${slashCommands || "your new skills"} in your agent client.` +
3486
+ `\n You may need to reload the client for the skill + MCP server to appear.` +
3487
+ clientHint);
3229
3488
  }
3230
- if (parsed.printJson) {
3231
- process.stdout.write(`${JSON.stringify(results.length === 1 ? results[0] : results, null, 2)}\n`);
3232
- return;
3489
+ catch (error) {
3490
+ telemetry.track("skills_cli failed", {
3491
+ command: parsed.command,
3492
+ error: error instanceof Error ? error.message : String(error),
3493
+ durationMs: Date.now() - startedAt,
3494
+ });
3495
+ throw error;
3233
3496
  }
3234
- if (parsed.dryRun) {
3235
- process.stdout.write(`${results.flatMap((result) => result.commands).join("\n")}\n`);
3236
- return;
3497
+ finally {
3498
+ await telemetry.flush();
3237
3499
  }
3238
- const installedNames = results.map((result) => result.displayName).join(", ");
3239
- const skillsAgents = [
3240
- ...new Set(results.flatMap((result) => result.skillsAgents)),
3241
- ];
3242
- const mcpClients = [
3243
- ...new Set(results.flatMap((result) => result.mcpClients)),
3244
- ];
3245
- const mcpUrls = [
3246
- ...new Set(results.map((result) => result.mcpUrl).filter(Boolean)),
3247
- ];
3248
- const localCommands = [
3249
- ...new Set(results
3250
- .filter((result) => result.local)
3251
- .flatMap((result) => result.commands)),
3252
- ];
3253
- const authConnected = results.some((result) => result.connected);
3254
- const pendingConnectCommands = [
3255
- ...new Set(results
3256
- .map((result) => result.connectCommand)
3257
- .filter((command) => Boolean(command))),
3258
- ];
3259
- const authLine = authConnected
3260
- ? "Authentication: completed."
3261
- : pendingConnectCommands.length
3262
- ? `Authentication: pending — run ${pendingConnectCommands.join(" && ")}`
3263
- : "";
3264
- const githubActions = [
3265
- ...new Set(results
3266
- .map((result) => result.githubActionPath)
3267
- .filter((p) => Boolean(p))),
3268
- ];
3269
- const githubActionLine = githubActions.length
3270
- ? `PR Visual Recap workflow: wrote ${githubActions.join(", ")}.\nNext: run ${prVisualRecapSetupCommand()} to configure GitHub secrets/variables, or set them manually:\n ${PR_VISUAL_RECAP_SETUP.join("\n ")}`
3271
- : "";
3272
- const githubActionSuggestions = [
3273
- ...new Set(results
3274
- .map((result) => result.githubActionSuggestedCommand)
3275
- .filter((command) => Boolean(command))),
3276
- ];
3277
- const githubActionSuggestionLine = githubActionSuggestions.length
3278
- ? `Optional PR Visual Recap workflow: run ${githubActionSuggestions.join(" && ")} to add automatic recap comments on pull requests.`
3279
- : "";
3280
- process.stdout.write([
3281
- `Installed ${installedNames} skill${results.length === 1 ? "" : "s"}.`,
3282
- skillsAgents.length
3283
- ? `Skill instructions: ${skillsAgents.join(", ")}.`
3284
- : "Skill instructions: skipped.",
3285
- mcpClients.length
3286
- ? `MCP config: ${mcpClients.join(", ")}.`
3287
- : "MCP config: not required.",
3288
- mcpUrls.length
3289
- ? `MCP URL${mcpUrls.length === 1 ? "" : "s"}: ${mcpUrls.join(", ")}.`
3290
- : "",
3291
- authLine,
3292
- githubActionLine,
3293
- githubActionSuggestionLine,
3294
- localCommands.length ? `Local command: ${localCommands.join(", ")}.` : "",
3295
- "Restart or reload selected agent clients if the skill is not visible yet.",
3296
- parsed.clientExplicit
3297
- ? ""
3298
- : `To add another client later, rerun with --client <client> (for example: --client claude-code).`,
3299
- ]
3300
- .filter(Boolean)
3301
- .join("\n") + "\n");
3302
3500
  }
3303
3501
  //# sourceMappingURL=skills.js.map