@agent-native/core 0.48.3 → 0.49.0
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/agent/context-xray/actions/context-evict.d.ts +1 -1
- package/dist/agent/context-xray/actions/context-pin.d.ts +1 -1
- package/dist/agent/context-xray/actions/context-report.d.ts +4 -4
- package/dist/agent/context-xray/actions/context-restore.d.ts +1 -1
- package/dist/application-state/handlers.d.ts +2 -2
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/cli/app-skill.d.ts +157 -0
- package/dist/cli/app-skill.d.ts.map +1 -0
- package/dist/cli/app-skill.js +17 -7
- package/dist/cli/app-skill.js.map +1 -1
- package/dist/cli/audit-agent-web.d.ts +2 -0
- package/dist/cli/audit-agent-web.d.ts.map +1 -0
- package/dist/cli/code-agent-connector.d.ts +17 -0
- package/dist/cli/code-agent-connector.d.ts.map +1 -0
- package/dist/cli/code.d.ts +66 -0
- package/dist/cli/code.d.ts.map +1 -0
- package/dist/cli/connect.d.ts +168 -0
- package/dist/cli/connect.d.ts.map +1 -0
- package/dist/cli/connect.js +118 -30
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/context-xray-local.d.ts +16 -0
- package/dist/cli/context-xray-local.d.ts.map +1 -0
- package/dist/cli/create-workspace.d.ts +8 -0
- package/dist/cli/create-workspace.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/info.d.ts +2 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/mcp-config-writers.d.ts +108 -0
- package/dist/cli/mcp-config-writers.d.ts.map +1 -0
- package/dist/cli/mcp-config-writers.js +143 -0
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/mcp.d.ts +16 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +10 -10
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/migrate.d.ts +38 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/plan-local.d.ts +43 -0
- package/dist/cli/plan-local.d.ts.map +1 -0
- package/dist/cli/plan-publish-store.d.ts +62 -0
- package/dist/cli/plan-publish-store.d.ts.map +1 -0
- package/dist/cli/pr-visual-recap-workflow.d.ts +11 -0
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -0
- package/dist/cli/pr-visual-recap-workflow.js +1 -1
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +453 -0
- package/dist/cli/recap.d.ts.map +1 -0
- package/dist/cli/recap.js +228 -95
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +193 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +518 -177
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/telemetry.d.ts +13 -0
- package/dist/cli/telemetry.d.ts.map +1 -0
- package/dist/cli/telemetry.js +115 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/workspace-dev.d.ts +96 -0
- package/dist/cli/workspace-dev.d.ts.map +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +10 -19
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ErrorBoundary.d.ts.map +1 -1
- package/dist/client/ErrorBoundary.js +34 -1
- package/dist/client/ErrorBoundary.js.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +15 -7
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
- package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/DiffBlock.js +17 -10
- package/dist/client/blocks/library/DiffBlock.js.map +1 -1
- package/dist/client/blocks/library/annotation-rail.d.ts +5 -0
- package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
- package/dist/client/blocks/library/annotation-rail.js +6 -0
- package/dist/client/blocks/library/annotation-rail.js.map +1 -1
- package/dist/client/blocks/types.d.ts +5 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts +17 -0
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +67 -0
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +15 -71
- package/dist/deploy/build.js.map +1 -1
- package/dist/extensions/schema.d.ts +54 -54
- package/dist/extensions/slots/schema.d.ts +13 -13
- package/dist/file-upload/actions/upload-image.d.ts +4 -4
- package/dist/mcp/actions/create-org-service-token.d.ts +1 -1
- package/dist/mcp/actions/list-org-service-tokens.d.ts +7 -7
- package/dist/mcp/build-server.d.ts +12 -12
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/connect-route.js +1 -1
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/mcp/oauth-route.d.ts +10 -0
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +34 -3
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/mcp/oauth-store.d.ts +15 -1
- package/dist/mcp/oauth-store.d.ts.map +1 -1
- package/dist/mcp/oauth-store.js +60 -4
- package/dist/mcp/oauth-store.js.map +1 -1
- package/dist/mcp/oauth-token.d.ts +3 -1
- package/dist/mcp/oauth-token.d.ts.map +1 -1
- package/dist/mcp/oauth-token.js +78 -6
- package/dist/mcp/oauth-token.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +8 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/observability/routes.d.ts +11 -11
- package/dist/org/handlers.d.ts +7 -11
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/secrets/schema.d.ts +7 -7
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +8 -5
- package/dist/server/auth.js.map +1 -1
- package/dist/server/csrf.d.ts +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +12 -11
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll-events.d.ts +1 -1
- package/dist/server/security-headers.d.ts +1 -1
- package/dist/server/security-headers.d.ts.map +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +42 -130
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/sharing/actions/list-resource-shares.d.ts +3 -3
- package/dist/sharing/actions/set-resource-visibility.d.ts +2 -2
- package/dist/sharing/actions/share-resource.d.ts +4 -4
- package/dist/sharing/actions/unshare-resource.d.ts +1 -1
- package/dist/sharing/schema.d.ts +12 -12
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +2 -2
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +6 -6
- package/dist/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +2 -2
- package/dist/workspace-files/schema.d.ts +8 -8
- package/docs/content/external-agents.md +14 -0
- package/docs/content/plan-plugin.md +16 -7
- package/package.json +5 -1
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +2 -2
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +6 -6
- package/src/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +2 -2
package/dist/cli/skills.js
CHANGED
|
@@ -8,55 +8,58 @@ 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-
|
|
30
|
-
agent-native skills
|
|
31
|
-
agent-native skills
|
|
32
|
-
agent-native skills
|
|
33
|
-
agent-native skills add
|
|
34
|
-
agent-native skills add
|
|
35
|
-
agent-native skills add assets --
|
|
36
|
-
agent-native skills add
|
|
37
|
-
agent-native skills add
|
|
38
|
-
agent-native skills add BuilderIO/skills --
|
|
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
|
|
39
42
|
|
|
40
43
|
The add command installs the SKILL.md instructions, registers the app-backed
|
|
41
44
|
MCP connector, and then authenticates it in one step so you do not hit an OAuth
|
|
42
|
-
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":
|
|
43
46
|
OAuth-capable clients (Claude Code) get a URL-only entry and a /mcp authenticate
|
|
44
47
|
prompt, while Codex / Cowork run the browser device-code flow. In a
|
|
45
48
|
non-interactive shell or CI the auth step is skipped and the exact
|
|
46
|
-
"agent-native connect <url>" command is printed instead.
|
|
49
|
+
"npx @agent-native/core@latest connect <url>" command is printed instead.
|
|
47
50
|
|
|
48
51
|
Running "npx @agent-native/skills add ..." directly installs instructions only;
|
|
49
52
|
use this Agent Native CLI path when you want MCP setup and auth too. Pass --no-connect to
|
|
50
53
|
register the connector without authenticating (leave auth to the host or run
|
|
51
|
-
"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
|
|
52
55
|
a custom origin (an ngrok tunnel, a local dev server, or a self-hosted
|
|
53
56
|
deployment) instead of the built-in hosted default — a bare origin gets the
|
|
54
57
|
standard /_agent-native/mcp path appended. Use app-skill pack for marketplace
|
|
55
58
|
bundles and custom adapter output.
|
|
56
59
|
|
|
57
|
-
When installing visual-
|
|
60
|
+
When installing visual-recap interactively, the CLI offers to add the optional PR
|
|
58
61
|
Visual Recap GitHub Action. Pass --with-github-action to write it directly, then
|
|
59
|
-
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
|
|
60
63
|
verify GitHub Actions.
|
|
61
64
|
|
|
62
65
|
The status/update commands inspect copied Agent Native skill folders and refresh
|
|
@@ -120,7 +123,7 @@ of using a generic image generator.
|
|
|
120
123
|
|
|
121
124
|
- Hosted default: connect \`https://assets.agent-native.com/_agent-native/mcp\`.
|
|
122
125
|
Do not put shared secrets in skill files.
|
|
123
|
-
- 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
|
|
124
127
|
running until browser authorization finishes. Stopping it early can leave the
|
|
125
128
|
browser approved but the local MCP config unwritten. Restart or reload the
|
|
126
129
|
agent client after installing or connecting if Assets tools do not appear in
|
|
@@ -130,9 +133,12 @@ of using a generic image generator.
|
|
|
130
133
|
- Do not call image/video providers directly from another app. Assets owns
|
|
131
134
|
generation, picker UI, search/list/export, and asset context.
|
|
132
135
|
- If an Assets tool call returns \`Session terminated\`, \`needs auth\`, or
|
|
133
|
-
another connector/session error, do not keep retrying the tool.
|
|
134
|
-
|
|
135
|
-
|
|
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.
|
|
136
142
|
- Do not hand-roll MCP HTTP requests with curl from the agent session. Use the
|
|
137
143
|
host-exposed Assets tools after restart/reload, or use the returned
|
|
138
144
|
browser/deep-link fallback.
|
|
@@ -192,7 +198,7 @@ iteration, or a human-in-the-loop choice among design directions.
|
|
|
192
198
|
|
|
193
199
|
- Hosted default: connect \`https://design.agent-native.com/_agent-native/mcp\`.
|
|
194
200
|
Do not put shared secrets in skill files.
|
|
195
|
-
- 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
|
|
196
202
|
running until browser authorization finishes. Stopping it early can leave the
|
|
197
203
|
browser approved but the local MCP config unwritten. Restart or reload the
|
|
198
204
|
agent client after installing or connecting if Design tools do not appear in
|
|
@@ -202,9 +208,12 @@ iteration, or a human-in-the-loop choice among design directions.
|
|
|
202
208
|
- Keep the loop visual: surface the inline MCP App or the returned "Open
|
|
203
209
|
design" link instead of pasting large HTML blobs into chat.
|
|
204
210
|
- If a Design tool call returns \`Session terminated\`, \`needs auth\`, or
|
|
205
|
-
another connector/session error, do not keep retrying the tool.
|
|
206
|
-
|
|
207
|
-
|
|
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.
|
|
208
217
|
- Do not hand-roll MCP HTTP requests with curl from the agent session. Use the
|
|
209
218
|
host-exposed Design tools after restart/reload, or use the returned
|
|
210
219
|
browser/deep-link fallback.
|
|
@@ -250,10 +259,13 @@ your repo as MDX. This local mode is a separate advanced path, not the default
|
|
|
250
259
|
hosted flow.
|
|
251
260
|
|
|
252
261
|
If a Plans tool returns \`needs auth\`, \`Unauthorized\`, or \`Session terminated\`,
|
|
253
|
-
do not keep retrying the tool.
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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.
|
|
257
269
|
|
|
258
270
|
Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
|
|
259
271
|
not put shared secrets in skill files.`;
|
|
@@ -915,11 +927,12 @@ plan over as inline chat content — no Markdown prose, ASCII sketch, table, or
|
|
|
915
927
|
fenced wireframe. If the connector's tools are missing, do NOT fall back to
|
|
916
928
|
inline output: the usual cause is a connector that did not finish connecting
|
|
917
929
|
this session (it registers zero tools), not auth. Stop and give the user the
|
|
918
|
-
exact restore step —
|
|
919
|
-
genuinely unauthenticated,
|
|
920
|
-
\`npx @agent-native/core@latest
|
|
921
|
-
|
|
922
|
-
|
|
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.
|
|
923
936
|
|
|
924
937
|
## Core Workflow
|
|
925
938
|
|
|
@@ -1223,10 +1236,13 @@ because it is named \`agent-native-plans\` instead of \`plan\`. The usual cause
|
|
|
1223
1236
|
connector that did not finish connecting this session (it registers zero tools),
|
|
1224
1237
|
NOT necessarily an auth problem — so do not assume the user must authenticate.
|
|
1225
1238
|
Stop and tell the user how to restore it: reconnect the Plan MCP connector (in
|
|
1226
|
-
Claude Code, run \`/mcp\` and
|
|
1227
|
-
genuinely unauthenticated, run
|
|
1228
|
-
|
|
1229
|
-
|
|
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.
|
|
1230
1246
|
|
|
1231
1247
|
## When To Use
|
|
1232
1248
|
|
|
@@ -1947,6 +1963,21 @@ function builtInExtraFiles(entry) {
|
|
|
1947
1963
|
function builtInSkillNames(entry) {
|
|
1948
1964
|
return [entry.skillName, ...Object.keys(builtInExtraSkills(entry))];
|
|
1949
1965
|
}
|
|
1966
|
+
/**
|
|
1967
|
+
* When a target names a single skill that lives inside a multi-skill bundle
|
|
1968
|
+
* (the plan bundle ships both `visual-plan` and `visual-recap`), restrict the
|
|
1969
|
+
* install to just that skill. The bundle aliases (`visual-plans`, `plannotate`,
|
|
1970
|
+
* …) return undefined so they install every skill in the bundle.
|
|
1971
|
+
*/
|
|
1972
|
+
function builtInOnlySkillNames(target) {
|
|
1973
|
+
const normalized = target.trim().toLowerCase();
|
|
1974
|
+
if (normalized === "visual-plan")
|
|
1975
|
+
return ["visual-plan"];
|
|
1976
|
+
if (normalized === "visual-recap" || normalized === "visual-recaps") {
|
|
1977
|
+
return ["visual-recap"];
|
|
1978
|
+
}
|
|
1979
|
+
return undefined;
|
|
1980
|
+
}
|
|
1950
1981
|
function stableSkillHash(files) {
|
|
1951
1982
|
const hash = createHash("sha256");
|
|
1952
1983
|
for (const rel of Object.keys(files).sort()) {
|
|
@@ -2009,10 +2040,49 @@ function writeSkillFolder(dir, bundle, installedAt = new Date().toISOString()) {
|
|
|
2009
2040
|
contentHash: bundle.contentHash,
|
|
2010
2041
|
mcpUrl: bundle.mcpUrl,
|
|
2011
2042
|
installedAt,
|
|
2012
|
-
updateCommand: `agent-native skills update ${bundle.skillName}`,
|
|
2043
|
+
updateCommand: `npx @agent-native/core@latest skills update ${bundle.skillName}`,
|
|
2013
2044
|
};
|
|
2014
2045
|
fs.writeFileSync(path.join(dir, AGENT_NATIVE_SKILL_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\n`, "utf-8");
|
|
2015
2046
|
}
|
|
2047
|
+
/**
|
|
2048
|
+
* The skills directory a built-in skill's instructions are copied into for a
|
|
2049
|
+
* given agent + scope. Mirrors the layout the skills installer uses so
|
|
2050
|
+
* `skills status` / `skills update` find the folders again.
|
|
2051
|
+
*/
|
|
2052
|
+
function builtInSkillsRootForAgent(agent, scope, baseDir) {
|
|
2053
|
+
const home = homeDir() ?? baseDir;
|
|
2054
|
+
if (scope === "project") {
|
|
2055
|
+
return agent === "codex"
|
|
2056
|
+
? path.join(baseDir, ".agents", "skills")
|
|
2057
|
+
: path.join(baseDir, ".claude", "skills");
|
|
2058
|
+
}
|
|
2059
|
+
if (agent === "codex") {
|
|
2060
|
+
return process.env.CODEX_HOME
|
|
2061
|
+
? path.join(process.env.CODEX_HOME, "skills")
|
|
2062
|
+
: path.join(home, ".codex", "skills");
|
|
2063
|
+
}
|
|
2064
|
+
return path.join(home, ".claude", "skills");
|
|
2065
|
+
}
|
|
2066
|
+
/**
|
|
2067
|
+
* Write a built-in skill's instruction folders straight into each client's
|
|
2068
|
+
* skills directory. Built-in skills ship their SKILL.md inside this package, so
|
|
2069
|
+
* there is no need to shell out to the separate @agent-native/skills installer
|
|
2070
|
+
* (which would have to be published to npm first). Returns the written folders.
|
|
2071
|
+
*/
|
|
2072
|
+
function installBuiltInInstructions(input) {
|
|
2073
|
+
const bundles = Object.values(skillFilesForBuiltIn(input.appSkillId)).filter((bundle) => !input.onlySkillNames || input.onlySkillNames.includes(bundle.skillName));
|
|
2074
|
+
const written = [];
|
|
2075
|
+
for (const agent of input.skillsAgents) {
|
|
2076
|
+
const root = builtInSkillsRootForAgent(agent, input.scope, input.baseDir);
|
|
2077
|
+
for (const bundle of bundles) {
|
|
2078
|
+
const dir = path.join(root, bundle.skillName);
|
|
2079
|
+
if (!input.dryRun)
|
|
2080
|
+
writeSkillFolder(dir, bundle);
|
|
2081
|
+
written.push(dir);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
return written;
|
|
2085
|
+
}
|
|
2016
2086
|
function listSkillFolderFiles(dir) {
|
|
2017
2087
|
const out = {};
|
|
2018
2088
|
const walk = (current, prefix = "") => {
|
|
@@ -2097,7 +2167,7 @@ function targetIdsForStatus(parsed) {
|
|
|
2097
2167
|
}
|
|
2098
2168
|
const known = normalizeKnownSkillTarget(parsed.target);
|
|
2099
2169
|
if (!known) {
|
|
2100
|
-
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".`);
|
|
2101
2171
|
}
|
|
2102
2172
|
if (isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[known])) {
|
|
2103
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.`);
|
|
@@ -2200,12 +2270,25 @@ function clientPromptOptions() {
|
|
|
2200
2270
|
hint: CLIENT_HINTS[client],
|
|
2201
2271
|
}));
|
|
2202
2272
|
}
|
|
2273
|
+
// For now the interactive installer offers only the two plan skills, each as
|
|
2274
|
+
// an independently selectable entry (uncheck one to install just the other).
|
|
2275
|
+
// The other built-in skills stay installable via `agent-native skills add
|
|
2276
|
+
// <name>` but are hidden from the default checklist. The values are the real
|
|
2277
|
+
// slash-command names so users see exactly what they are installing.
|
|
2278
|
+
const PLAN_SKILL_PROMPT_OPTIONS = [
|
|
2279
|
+
{
|
|
2280
|
+
value: "visual-plan",
|
|
2281
|
+
label: "visual-plan",
|
|
2282
|
+
hint: "Reviewable coding-agent plan: diagrams, annotated code, file trees, open questions.",
|
|
2283
|
+
},
|
|
2284
|
+
{
|
|
2285
|
+
value: "visual-recap",
|
|
2286
|
+
label: "visual-recap",
|
|
2287
|
+
hint: "Turn a PR, commit, branch, or git diff into a high-altitude visual recap.",
|
|
2288
|
+
},
|
|
2289
|
+
];
|
|
2203
2290
|
function skillPromptOptions() {
|
|
2204
|
-
return
|
|
2205
|
-
value: entry.skillName,
|
|
2206
|
-
label: entry.manifest.displayName,
|
|
2207
|
-
hint: entry.manifest.description,
|
|
2208
|
-
}));
|
|
2291
|
+
return PLAN_SKILL_PROMPT_OPTIONS;
|
|
2209
2292
|
}
|
|
2210
2293
|
function prVisualRecapWorkflowPath(baseDir) {
|
|
2211
2294
|
return path.join(baseDir, ".github", "workflows", "pr-visual-recap.yml");
|
|
@@ -2214,7 +2297,7 @@ function prVisualRecapWorkflowDisplayPath() {
|
|
|
2214
2297
|
return path.join(".github", "workflows", "pr-visual-recap.yml");
|
|
2215
2298
|
}
|
|
2216
2299
|
function prVisualRecapInstallCommand() {
|
|
2217
|
-
return "npx @agent-native/core@latest skills add visual-
|
|
2300
|
+
return "npx @agent-native/core@latest skills add visual-recap --with-github-action";
|
|
2218
2301
|
}
|
|
2219
2302
|
function prVisualRecapSetupCommand() {
|
|
2220
2303
|
return "npx @agent-native/core@latest recap setup";
|
|
@@ -2222,8 +2305,11 @@ function prVisualRecapSetupCommand() {
|
|
|
2222
2305
|
async function promptForGithubAction(context) {
|
|
2223
2306
|
const clack = await import("@clack/prompts");
|
|
2224
2307
|
const result = await clack.confirm({
|
|
2225
|
-
message: "Optional: add automatic PR Visual Recaps
|
|
2226
|
-
|
|
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.`,
|
|
2227
2313
|
initialValue: false,
|
|
2228
2314
|
});
|
|
2229
2315
|
if (clack.isCancel(result)) {
|
|
@@ -2258,6 +2344,30 @@ async function promptForClients(context) {
|
|
|
2258
2344
|
}
|
|
2259
2345
|
return normalizeClientIds(result);
|
|
2260
2346
|
}
|
|
2347
|
+
async function promptForScope(context) {
|
|
2348
|
+
const clack = await import("@clack/prompts");
|
|
2349
|
+
const result = await clack.select({
|
|
2350
|
+
message: "Where do you want to install these skills?",
|
|
2351
|
+
options: [
|
|
2352
|
+
{
|
|
2353
|
+
value: "project",
|
|
2354
|
+
label: "Project",
|
|
2355
|
+
hint: "This repo only (.agents / .claude in the current directory) — committed with your project",
|
|
2356
|
+
},
|
|
2357
|
+
{
|
|
2358
|
+
value: "user",
|
|
2359
|
+
label: "User",
|
|
2360
|
+
hint: "Your home directory (~/.codex, ~/.claude) — available across all projects",
|
|
2361
|
+
},
|
|
2362
|
+
],
|
|
2363
|
+
initialValue: context.initialScope,
|
|
2364
|
+
});
|
|
2365
|
+
if (clack.isCancel(result)) {
|
|
2366
|
+
clack.cancel("Cancelled.");
|
|
2367
|
+
return null;
|
|
2368
|
+
}
|
|
2369
|
+
return result === "project" ? "project" : "user";
|
|
2370
|
+
}
|
|
2261
2371
|
async function promptForSkills(context) {
|
|
2262
2372
|
const clack = await import("@clack/prompts");
|
|
2263
2373
|
const result = await clack.multiselect({
|
|
@@ -2300,12 +2410,29 @@ async function resolveSkillTargets(parsed, options) {
|
|
|
2300
2410
|
return [parsed.target ?? "assets"];
|
|
2301
2411
|
}
|
|
2302
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
|
+
});
|
|
2303
2420
|
const selected = await prompt({
|
|
2304
|
-
initialTargets: ["
|
|
2305
|
-
options:
|
|
2421
|
+
initialTargets: ["visual-plan", "visual-recap"],
|
|
2422
|
+
options: promptOptions,
|
|
2306
2423
|
});
|
|
2307
2424
|
if (!selected || selected.length === 0)
|
|
2308
2425
|
return null;
|
|
2426
|
+
// Both plan skills share one MCP connector, so when both are selected install
|
|
2427
|
+
// them through the bundle target — that registers/authenticates the connector
|
|
2428
|
+
// once instead of twice.
|
|
2429
|
+
const planSubskills = ["visual-plan", "visual-recap"];
|
|
2430
|
+
if (planSubskills.every((skill) => selected.includes(skill))) {
|
|
2431
|
+
return [
|
|
2432
|
+
"visual-plans",
|
|
2433
|
+
...selected.filter((s) => !planSubskills.includes(s)),
|
|
2434
|
+
];
|
|
2435
|
+
}
|
|
2309
2436
|
return selected;
|
|
2310
2437
|
}
|
|
2311
2438
|
export function parseSkillsArgs(argv) {
|
|
@@ -2406,11 +2533,11 @@ export function parseSkillsArgs(argv) {
|
|
|
2406
2533
|
}
|
|
2407
2534
|
return out;
|
|
2408
2535
|
}
|
|
2409
|
-
function loadSkillTarget(target) {
|
|
2536
|
+
function loadSkillTarget(target, onlySkillNames) {
|
|
2410
2537
|
const knownTarget = normalizeKnownSkillTarget(target);
|
|
2411
2538
|
if (knownTarget) {
|
|
2412
2539
|
const builtIn = BUILT_IN_APP_SKILLS[knownTarget];
|
|
2413
|
-
const skillNames = builtInSkillNames(builtIn);
|
|
2540
|
+
const skillNames = builtInSkillNames(builtIn).filter((name) => !onlySkillNames || onlySkillNames.includes(name));
|
|
2414
2541
|
return {
|
|
2415
2542
|
id: builtIn.manifest.id,
|
|
2416
2543
|
displayName: builtIn.manifest.displayName,
|
|
@@ -2423,6 +2550,9 @@ function loadSkillTarget(target) {
|
|
|
2423
2550
|
materializeInstructions(outDir) {
|
|
2424
2551
|
const bundles = skillFilesForBuiltIn(knownTarget);
|
|
2425
2552
|
for (const bundle of Object.values(bundles)) {
|
|
2553
|
+
if (onlySkillNames && !onlySkillNames.includes(bundle.skillName)) {
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2426
2556
|
writeSkillFolder(path.join(outDir, "skills", bundle.skillName), bundle);
|
|
2427
2557
|
}
|
|
2428
2558
|
return outDir;
|
|
@@ -2505,6 +2635,7 @@ function preserveMcpUrlAppPathOverride(target, input) {
|
|
|
2505
2635
|
function dryRunInstallCommand(parsed, target) {
|
|
2506
2636
|
const clients = parsed.clients ?? resolveClients(parsed.client);
|
|
2507
2637
|
const args = [
|
|
2638
|
+
"@agent-native/core@latest",
|
|
2508
2639
|
"skills",
|
|
2509
2640
|
"add",
|
|
2510
2641
|
target,
|
|
@@ -2529,7 +2660,7 @@ function dryRunInstallCommand(parsed, target) {
|
|
|
2529
2660
|
args.push("--no-update-instructions");
|
|
2530
2661
|
if (parsed.yes || isKnownSkill(target))
|
|
2531
2662
|
args.push("--yes");
|
|
2532
|
-
return commandString("
|
|
2663
|
+
return commandString("npx", args);
|
|
2533
2664
|
}
|
|
2534
2665
|
async function runCommand(cmd, args, options = {}) {
|
|
2535
2666
|
return new Promise((resolve, reject) => {
|
|
@@ -2679,6 +2810,12 @@ async function addPlainSkillRepo(parsed, options) {
|
|
|
2679
2810
|
if (code !== 0)
|
|
2680
2811
|
throw new Error(`npx @agent-native/skills add exited with ${code}.`);
|
|
2681
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
|
+
});
|
|
2682
2819
|
return {
|
|
2683
2820
|
id: target,
|
|
2684
2821
|
displayName: target,
|
|
@@ -2708,6 +2845,7 @@ function canRunInteractiveConnect(options) {
|
|
|
2708
2845
|
/** Build the `npx @agent-native/core@latest connect <url> --client … --scope …` command. */
|
|
2709
2846
|
function connectCommandFor(hostedUrl, clients, scope) {
|
|
2710
2847
|
const args = [
|
|
2848
|
+
"@agent-native/core@latest",
|
|
2711
2849
|
"connect",
|
|
2712
2850
|
hostedUrl,
|
|
2713
2851
|
"--client",
|
|
@@ -2715,7 +2853,7 @@ function connectCommandFor(hostedUrl, clients, scope) {
|
|
|
2715
2853
|
"--scope",
|
|
2716
2854
|
scope,
|
|
2717
2855
|
];
|
|
2718
|
-
return commandString("
|
|
2856
|
+
return commandString("npx", args);
|
|
2719
2857
|
}
|
|
2720
2858
|
/**
|
|
2721
2859
|
* Authenticate the freshly-registered hosted MCP connector so the user does not
|
|
@@ -2740,6 +2878,7 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
|
|
|
2740
2878
|
return { connected: false, connectCommand };
|
|
2741
2879
|
}
|
|
2742
2880
|
options.log?.(`Authenticating ${installTarget.displayName}…`);
|
|
2881
|
+
options.telemetry?.track("skills_cli connect started");
|
|
2743
2882
|
try {
|
|
2744
2883
|
await (options.runConnect ?? runConnect)([
|
|
2745
2884
|
hostedUrl,
|
|
@@ -2748,10 +2887,14 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
|
|
|
2748
2887
|
"--scope",
|
|
2749
2888
|
parsed.scope,
|
|
2750
2889
|
]);
|
|
2890
|
+
options.telemetry?.track("skills_cli connect completed");
|
|
2751
2891
|
return { connected: true, connectCommand: "" };
|
|
2752
2892
|
}
|
|
2753
2893
|
catch (err) {
|
|
2754
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
|
+
});
|
|
2755
2898
|
options.log?.(`Could not finish authentication automatically (${err?.message ?? err}). ` +
|
|
2756
2899
|
`Run it later with: ${connectCommand}`);
|
|
2757
2900
|
return { connected: false, connectCommand };
|
|
@@ -2760,11 +2903,19 @@ async function connectAfterEnsure(installTarget, clients, parsed, options) {
|
|
|
2760
2903
|
export async function addAgentNativeSkill(parsed, options = {}) {
|
|
2761
2904
|
const target = parsed.target ?? "assets";
|
|
2762
2905
|
const knownTarget = normalizeKnownSkillTarget(target);
|
|
2906
|
+
// For multi-skill bundles (the plan bundle), a single-skill target installs
|
|
2907
|
+
// only that skill. `installsRecap` controls the PR Visual Recap github-action
|
|
2908
|
+
// offer, which is only relevant when the recap skill is part of the install.
|
|
2909
|
+
const onlySkillNames = knownTarget
|
|
2910
|
+
? builtInOnlySkillNames(target)
|
|
2911
|
+
: undefined;
|
|
2912
|
+
const installsRecap = knownTarget === "visual-plans" &&
|
|
2913
|
+
(!onlySkillNames || onlySkillNames.includes("visual-recap"));
|
|
2763
2914
|
if (!knownTarget && isPlainSkillRepoTarget(target)) {
|
|
2764
2915
|
return addPlainSkillRepo({ ...parsed, target }, options);
|
|
2765
2916
|
}
|
|
2766
2917
|
if (!knownTarget && !fs.existsSync(path.resolve(target))) {
|
|
2767
|
-
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".`);
|
|
2768
2919
|
}
|
|
2769
2920
|
const knownBuiltIn = knownTarget ? BUILT_IN_APP_SKILLS[knownTarget] : null;
|
|
2770
2921
|
if (isLocalOnlyBuiltInSkill(knownBuiltIn)) {
|
|
@@ -2780,6 +2931,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2780
2931
|
const githubActionPath = parsed.withGithubAction && knownTarget === "visual-plans"
|
|
2781
2932
|
? prVisualRecapWorkflowDisplayPath()
|
|
2782
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
|
+
});
|
|
2783
2940
|
return {
|
|
2784
2941
|
id: knownBuiltIn.manifest.id,
|
|
2785
2942
|
displayName: knownBuiltIn.manifest.displayName,
|
|
@@ -2798,6 +2955,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2798
2955
|
clients,
|
|
2799
2956
|
scope: parsed.scope,
|
|
2800
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
|
+
});
|
|
2801
2964
|
return {
|
|
2802
2965
|
id: knownBuiltIn.manifest.id,
|
|
2803
2966
|
displayName: knownBuiltIn.manifest.displayName,
|
|
@@ -2813,7 +2976,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2813
2976
|
commands: localInstall.commands,
|
|
2814
2977
|
};
|
|
2815
2978
|
}
|
|
2816
|
-
let installTarget = loadSkillTarget(target);
|
|
2979
|
+
let installTarget = loadSkillTarget(target, onlySkillNames);
|
|
2817
2980
|
if (parsed.mcpUrl) {
|
|
2818
2981
|
installTarget = withMcpUrlOverride(installTarget, parsed.mcpUrl);
|
|
2819
2982
|
}
|
|
@@ -2822,12 +2985,18 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2822
2985
|
const skillsAgents = skillsAgentsForClients(clients);
|
|
2823
2986
|
if (parsed.dryRun) {
|
|
2824
2987
|
try {
|
|
2825
|
-
const githubActionPath = parsed.withGithubAction &&
|
|
2988
|
+
const githubActionPath = parsed.withGithubAction && installsRecap
|
|
2826
2989
|
? prVisualRecapWorkflowDisplayPath()
|
|
2827
2990
|
: undefined;
|
|
2828
|
-
const githubActionSuggestedCommand =
|
|
2991
|
+
const githubActionSuggestedCommand = installsRecap && !parsed.withGithubAction
|
|
2829
2992
|
? prVisualRecapInstallCommand()
|
|
2830
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
|
+
});
|
|
2831
3000
|
return {
|
|
2832
3001
|
id: installTarget.id,
|
|
2833
3002
|
displayName: installTarget.displayName,
|
|
@@ -2848,6 +3017,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2848
3017
|
const commands = [];
|
|
2849
3018
|
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "an-skills-add-"));
|
|
2850
3019
|
let instructionSource;
|
|
3020
|
+
let instructionsWritten;
|
|
2851
3021
|
let connected = false;
|
|
2852
3022
|
let connectCommand;
|
|
2853
3023
|
try {
|
|
@@ -2857,7 +3027,26 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2857
3027
|
throw new Error("Skill instructions can only be installed for Codex or Claude Code clients. Use an MCP-capable client or omit --instructions-only.");
|
|
2858
3028
|
}
|
|
2859
3029
|
}
|
|
3030
|
+
else if (knownTarget) {
|
|
3031
|
+
// Built-in skills ship their instructions inside this package, so copy
|
|
3032
|
+
// the skill folders straight into each client's skills directory. This
|
|
3033
|
+
// avoids shelling out to the separate @agent-native/skills installer
|
|
3034
|
+
// (which would need to be published to npm to run via npx).
|
|
3035
|
+
instructionsWritten = installBuiltInInstructions({
|
|
3036
|
+
appSkillId: knownTarget,
|
|
3037
|
+
onlySkillNames,
|
|
3038
|
+
skillsAgents,
|
|
3039
|
+
scope: parsed.scope,
|
|
3040
|
+
baseDir: options.baseDir ?? process.cwd(),
|
|
3041
|
+
dryRun: parsed.dryRun,
|
|
3042
|
+
});
|
|
3043
|
+
instructionSource = instructionsWritten[0];
|
|
3044
|
+
commands.push(...instructionsWritten.map((dir) => `write ${dir}`));
|
|
3045
|
+
}
|
|
2860
3046
|
else {
|
|
3047
|
+
// External app-skill manifests / plain skill repos still go through the
|
|
3048
|
+
// standalone installer, which knows how to pack adapters and fetch
|
|
3049
|
+
// remote skill collections.
|
|
2861
3050
|
instructionSource = installTarget.materializeInstructions(tmpRoot);
|
|
2862
3051
|
const args = [
|
|
2863
3052
|
"--yes",
|
|
@@ -2880,6 +3069,14 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2880
3069
|
}
|
|
2881
3070
|
}
|
|
2882
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
|
+
});
|
|
2883
3080
|
if (parsed.mcp) {
|
|
2884
3081
|
commands.push(`npx @agent-native/core@latest app-skill ensure --manifest ${installTarget.loaded.file} --client ${parsed.client} --scope ${parsed.scope} --yes`);
|
|
2885
3082
|
if (!parsed.dryRun) {
|
|
@@ -2891,6 +3088,9 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2891
3088
|
confirm: true,
|
|
2892
3089
|
log: options.log,
|
|
2893
3090
|
});
|
|
3091
|
+
options.telemetry?.track("skills_cli mcp registered", {
|
|
3092
|
+
skills: installTarget.skillNames.join(","),
|
|
3093
|
+
});
|
|
2894
3094
|
// One-step install + authenticate: after registering a hosted MCP
|
|
2895
3095
|
// connector, kick off the existing connect/device-code flow so the user
|
|
2896
3096
|
// does not hit an OAuth wall on the first tool call. `--no-connect`
|
|
@@ -2911,24 +3111,32 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2911
3111
|
let githubActionPath;
|
|
2912
3112
|
let githubActionExisted;
|
|
2913
3113
|
let githubActionSuggestedCommand;
|
|
2914
|
-
if (
|
|
3114
|
+
if (installsRecap &&
|
|
2915
3115
|
!withGithubAction &&
|
|
2916
3116
|
!fs.existsSync(prVisualRecapWorkflowPath(baseDir))) {
|
|
2917
|
-
|
|
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)) {
|
|
2918
3121
|
const prompt = options.promptGithubAction ?? promptForGithubAction;
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
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;
|
|
2924
3132
|
}
|
|
2925
3133
|
if (!withGithubAction) {
|
|
2926
3134
|
githubActionSuggestedCommand = prVisualRecapInstallCommand();
|
|
2927
3135
|
}
|
|
2928
3136
|
}
|
|
2929
3137
|
if (withGithubAction) {
|
|
2930
|
-
if (
|
|
2931
|
-
options.log?.("--with-github-action only applies to the visual-
|
|
3138
|
+
if (!installsRecap) {
|
|
3139
|
+
options.log?.("--with-github-action only applies to the visual-recap skill; skipping the workflow.");
|
|
2932
3140
|
}
|
|
2933
3141
|
else {
|
|
2934
3142
|
const writeResult = writePrVisualRecapWorkflow(baseDir, {
|
|
@@ -2941,6 +3149,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2941
3149
|
githubActionExisted =
|
|
2942
3150
|
writeResult.status === "written" ? writeResult.existed : false;
|
|
2943
3151
|
commands.push(`write ${writeResult.path}`);
|
|
3152
|
+
options.telemetry?.track("skills_cli github action added");
|
|
2944
3153
|
}
|
|
2945
3154
|
}
|
|
2946
3155
|
return {
|
|
@@ -2953,6 +3162,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
2953
3162
|
mcpClients: clients,
|
|
2954
3163
|
dryRun: parsed.dryRun,
|
|
2955
3164
|
commands,
|
|
3165
|
+
written: instructionsWritten,
|
|
2956
3166
|
connected,
|
|
2957
3167
|
connectCommand,
|
|
2958
3168
|
githubActionPath,
|
|
@@ -3019,7 +3229,7 @@ function runSkillsStatusOrUpdate(parsed, options, update) {
|
|
|
3019
3229
|
}
|
|
3020
3230
|
if (before.length === 0) {
|
|
3021
3231
|
const target = parsed.target ? ` for ${parsed.target}` : "";
|
|
3022
|
-
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`);
|
|
3023
3233
|
return;
|
|
3024
3234
|
}
|
|
3025
3235
|
if (update) {
|
|
@@ -3037,6 +3247,21 @@ function runSkillsStatusOrUpdate(parsed, options, update) {
|
|
|
3037
3247
|
const rows = (update && parsed.dryRun ? before : after).map(formatSkillState);
|
|
3038
3248
|
process.stdout.write(`${rows.join("\n")}\n`);
|
|
3039
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
|
+
}
|
|
3040
3265
|
export async function runSkills(argv, options = {}) {
|
|
3041
3266
|
const parsed = parseSkillsArgs(argv);
|
|
3042
3267
|
const log = parsed.printJson
|
|
@@ -3046,115 +3271,231 @@ export async function runSkills(argv, options = {}) {
|
|
|
3046
3271
|
process.stdout.write(`${HELP}\n`);
|
|
3047
3272
|
return;
|
|
3048
3273
|
}
|
|
3049
|
-
|
|
3050
|
-
|
|
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
|
+
});
|
|
3051
3406
|
if (parsed.printJson) {
|
|
3052
|
-
process.stdout.write(`${JSON.stringify(
|
|
3407
|
+
process.stdout.write(`${JSON.stringify(results.length === 1 ? results[0] : results, null, 2)}\n`);
|
|
3408
|
+
return;
|
|
3409
|
+
}
|
|
3410
|
+
if (parsed.dryRun) {
|
|
3411
|
+
process.stdout.write(`${results.flatMap((result) => result.commands).join("\n")}\n`);
|
|
3053
3412
|
return;
|
|
3054
3413
|
}
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
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(" && ")}`
|
|
3059
3441
|
: "";
|
|
3060
|
-
|
|
3061
|
-
|
|
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`);
|
|
3062
3480
|
}
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
if (!targets)
|
|
3071
|
-
return;
|
|
3072
|
-
const clients = await resolveSkillsClients(parsed, options);
|
|
3073
|
-
if (!clients)
|
|
3074
|
-
return;
|
|
3075
|
-
const results = [];
|
|
3076
|
-
for (const target of targets) {
|
|
3077
|
-
results.push(await addAgentNativeSkill({
|
|
3078
|
-
...parsed,
|
|
3079
|
-
target,
|
|
3080
|
-
client: clientArgForClients(clients),
|
|
3081
|
-
clients,
|
|
3082
|
-
}, {
|
|
3083
|
-
...options,
|
|
3084
|
-
log,
|
|
3085
|
-
}));
|
|
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);
|
|
3086
3488
|
}
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
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;
|
|
3090
3496
|
}
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
return;
|
|
3497
|
+
finally {
|
|
3498
|
+
await telemetry.flush();
|
|
3094
3499
|
}
|
|
3095
|
-
const installedNames = results.map((result) => result.displayName).join(", ");
|
|
3096
|
-
const skillsAgents = [
|
|
3097
|
-
...new Set(results.flatMap((result) => result.skillsAgents)),
|
|
3098
|
-
];
|
|
3099
|
-
const mcpClients = [
|
|
3100
|
-
...new Set(results.flatMap((result) => result.mcpClients)),
|
|
3101
|
-
];
|
|
3102
|
-
const mcpUrls = [
|
|
3103
|
-
...new Set(results.map((result) => result.mcpUrl).filter(Boolean)),
|
|
3104
|
-
];
|
|
3105
|
-
const localCommands = [
|
|
3106
|
-
...new Set(results
|
|
3107
|
-
.filter((result) => result.local)
|
|
3108
|
-
.flatMap((result) => result.commands)),
|
|
3109
|
-
];
|
|
3110
|
-
const authConnected = results.some((result) => result.connected);
|
|
3111
|
-
const pendingConnectCommands = [
|
|
3112
|
-
...new Set(results
|
|
3113
|
-
.map((result) => result.connectCommand)
|
|
3114
|
-
.filter((command) => Boolean(command))),
|
|
3115
|
-
];
|
|
3116
|
-
const authLine = authConnected
|
|
3117
|
-
? "Authentication: completed."
|
|
3118
|
-
: pendingConnectCommands.length
|
|
3119
|
-
? `Authentication: pending — run ${pendingConnectCommands.join(" && ")}`
|
|
3120
|
-
: "";
|
|
3121
|
-
const githubActions = [
|
|
3122
|
-
...new Set(results
|
|
3123
|
-
.map((result) => result.githubActionPath)
|
|
3124
|
-
.filter((p) => Boolean(p))),
|
|
3125
|
-
];
|
|
3126
|
-
const githubActionLine = githubActions.length
|
|
3127
|
-
? `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 ")}`
|
|
3128
|
-
: "";
|
|
3129
|
-
const githubActionSuggestions = [
|
|
3130
|
-
...new Set(results
|
|
3131
|
-
.map((result) => result.githubActionSuggestedCommand)
|
|
3132
|
-
.filter((command) => Boolean(command))),
|
|
3133
|
-
];
|
|
3134
|
-
const githubActionSuggestionLine = githubActionSuggestions.length
|
|
3135
|
-
? `Optional PR Visual Recap workflow: run ${githubActionSuggestions.join(" && ")} to add automatic recap comments on pull requests.`
|
|
3136
|
-
: "";
|
|
3137
|
-
process.stdout.write([
|
|
3138
|
-
`Installed ${installedNames} skill${results.length === 1 ? "" : "s"}.`,
|
|
3139
|
-
skillsAgents.length
|
|
3140
|
-
? `Skill instructions: ${skillsAgents.join(", ")}.`
|
|
3141
|
-
: "Skill instructions: skipped.",
|
|
3142
|
-
mcpClients.length
|
|
3143
|
-
? `MCP config: ${mcpClients.join(", ")}.`
|
|
3144
|
-
: "MCP config: not required.",
|
|
3145
|
-
mcpUrls.length
|
|
3146
|
-
? `MCP URL${mcpUrls.length === 1 ? "" : "s"}: ${mcpUrls.join(", ")}.`
|
|
3147
|
-
: "",
|
|
3148
|
-
authLine,
|
|
3149
|
-
githubActionLine,
|
|
3150
|
-
githubActionSuggestionLine,
|
|
3151
|
-
localCommands.length ? `Local command: ${localCommands.join(", ")}.` : "",
|
|
3152
|
-
"Restart or reload selected agent clients if the skill is not visible yet.",
|
|
3153
|
-
parsed.clientExplicit
|
|
3154
|
-
? ""
|
|
3155
|
-
: `To add another client later, rerun with --client <client> (for example: --client claude-code).`,
|
|
3156
|
-
]
|
|
3157
|
-
.filter(Boolean)
|
|
3158
|
-
.join("\n") + "\n");
|
|
3159
3500
|
}
|
|
3160
3501
|
//# sourceMappingURL=skills.js.map
|