@agent-native/core 0.45.0 → 0.45.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 (93) hide show
  1. package/dist/action.d.ts +8 -1
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +20 -10
  4. package/dist/action.js.map +1 -1
  5. package/dist/cli/app-skill.d.ts +3 -1
  6. package/dist/cli/app-skill.d.ts.map +1 -1
  7. package/dist/cli/app-skill.js +50 -8
  8. package/dist/cli/app-skill.js.map +1 -1
  9. package/dist/cli/connect.d.ts.map +1 -1
  10. package/dist/cli/connect.js +39 -5
  11. package/dist/cli/connect.js.map +1 -1
  12. package/dist/cli/create.d.ts.map +1 -1
  13. package/dist/cli/create.js +9 -7
  14. package/dist/cli/create.js.map +1 -1
  15. package/dist/cli/index.js +42 -10
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/mcp-config-writers.d.ts +10 -0
  18. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  19. package/dist/cli/mcp-config-writers.js +60 -6
  20. package/dist/cli/mcp-config-writers.js.map +1 -1
  21. package/dist/cli/mcp.d.ts.map +1 -1
  22. package/dist/cli/mcp.js +4 -6
  23. package/dist/cli/mcp.js.map +1 -1
  24. package/dist/cli/plan-local.d.ts.map +1 -1
  25. package/dist/cli/plan-local.js +15 -2
  26. package/dist/cli/plan-local.js.map +1 -1
  27. package/dist/cli/plan-publish-store.d.ts +17 -7
  28. package/dist/cli/plan-publish-store.d.ts.map +1 -1
  29. package/dist/cli/plan-publish-store.js +33 -8
  30. package/dist/cli/plan-publish-store.js.map +1 -1
  31. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  32. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  33. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  34. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  35. package/dist/cli/recap.d.ts +63 -5
  36. package/dist/cli/recap.d.ts.map +1 -1
  37. package/dist/cli/recap.js +641 -48
  38. package/dist/cli/recap.js.map +1 -1
  39. package/dist/cli/skills.d.ts +26 -11
  40. package/dist/cli/skills.d.ts.map +1 -1
  41. package/dist/cli/skills.js +644 -972
  42. package/dist/cli/skills.js.map +1 -1
  43. package/dist/cli/templates-meta.d.ts.map +1 -1
  44. package/dist/cli/templates-meta.js +3 -2
  45. package/dist/cli/templates-meta.js.map +1 -1
  46. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  47. package/dist/client/blocks/library/AnnotatedCodeBlock.js +37 -9
  48. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  49. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  50. package/dist/client/blocks/library/DiffBlock.js +44 -12
  51. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  52. package/dist/client/blocks/library/annotation-rail.d.ts +12 -3
  53. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  54. package/dist/client/blocks/library/annotation-rail.js +29 -3
  55. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  56. package/dist/client/blocks/library/html.d.ts.map +1 -1
  57. package/dist/client/blocks/library/html.js +3 -1
  58. package/dist/client/blocks/library/html.js.map +1 -1
  59. package/dist/client/blocks/library/question-form.d.ts.map +1 -1
  60. package/dist/client/blocks/library/question-form.js +4 -1
  61. package/dist/client/blocks/library/question-form.js.map +1 -1
  62. package/dist/db/migrations.d.ts.map +1 -1
  63. package/dist/db/migrations.js +2 -1
  64. package/dist/db/migrations.js.map +1 -1
  65. package/dist/extensions/routes.d.ts +18 -0
  66. package/dist/extensions/routes.d.ts.map +1 -1
  67. package/dist/extensions/routes.js +30 -8
  68. package/dist/extensions/routes.js.map +1 -1
  69. package/dist/oauth-tokens/store.d.ts.map +1 -1
  70. package/dist/oauth-tokens/store.js +42 -5
  71. package/dist/oauth-tokens/store.js.map +1 -1
  72. package/dist/scripts/db/index.d.ts.map +1 -1
  73. package/dist/scripts/db/index.js +1 -0
  74. package/dist/scripts/db/index.js.map +1 -1
  75. package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts +28 -0
  76. package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts.map +1 -0
  77. package/dist/scripts/db/migrate-encrypt-oauth-tokens.js +164 -0
  78. package/dist/scripts/db/migrate-encrypt-oauth-tokens.js.map +1 -0
  79. package/dist/scripts/db/scoping.d.ts.map +1 -1
  80. package/dist/scripts/db/scoping.js +7 -5
  81. package/dist/scripts/db/scoping.js.map +1 -1
  82. package/dist/secrets/index.d.ts +1 -0
  83. package/dist/secrets/index.d.ts.map +1 -1
  84. package/dist/secrets/index.js +4 -0
  85. package/dist/secrets/index.js.map +1 -1
  86. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  87. package/dist/sharing/actions/set-resource-visibility.js +4 -1
  88. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  89. package/docs/content/plan-plugin.md +21 -6
  90. package/docs/content/pr-visual-recap.md +52 -3
  91. package/docs/content/skills-guide.md +13 -0
  92. package/docs/content/template-plan.md +18 -7
  93. package/package.json +5 -1
@@ -7,6 +7,7 @@ import fs from "node:fs";
7
7
  import os from "node:os";
8
8
  import path from "node:path";
9
9
  import { spawn } from "node:child_process";
10
+ import { createHash } from "node:crypto";
10
11
  import { buildAppSkillPack, ensureAppSkill, loadAppSkillManifest, normalizeAppSkillManifest, } from "./app-skill.js";
11
12
  import { readConnectClientPreferences, resolveClients, runConnect, writeConnectClientPreferences, } from "./connect.js";
12
13
  import { CONTEXT_XRAY_SKILL_MD, installLocalContextXray, } from "./context-xray-local.js";
@@ -16,6 +17,8 @@ const HELP = `agent-native skills
16
17
 
17
18
  Usage:
18
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]
19
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]
20
23
  agent-native skills add <manifest-or-app-dir> [--client ...] [--yes]
21
24
 
@@ -24,6 +27,8 @@ Examples:
24
27
  agent-native skills add design-exploration
25
28
  agent-native skills add visual-plan
26
29
  agent-native skills add visual-plan --with-github-action
30
+ agent-native skills status visual-plan
31
+ agent-native skills update visual-plan
27
32
  agent-native skills add visual-plan --no-connect
28
33
  agent-native skills add context-xray --client all
29
34
  agent-native skills add assets --client claude-code
@@ -45,7 +50,15 @@ register the connector without authenticating (leave auth to the host or run
45
50
  a custom origin (an ngrok tunnel, a local dev server, or a self-hosted
46
51
  deployment) instead of the built-in hosted default — a bare origin gets the
47
52
  standard /_agent-native/mcp path appended. Use app-skill pack for marketplace
48
- bundles and custom adapter output.`;
53
+ bundles and custom adapter output.
54
+
55
+ When installing visual-plan interactively, the CLI offers to add the optional PR
56
+ Visual Recap GitHub Action. Pass --with-github-action to write it directly, then
57
+ run "agent-native recap setup" / "agent-native recap doctor" to configure and
58
+ verify GitHub Actions.
59
+
60
+ The status/update commands inspect copied Agent Native skill folders and refresh
61
+ their instruction files from the current @agent-native/core package.`;
49
62
  const ASSETS_SKILL_MD = `---
50
63
  name: assets
51
64
  description: >-
@@ -198,8 +211,7 @@ iteration, or a human-in-the-loop choice among design directions.
198
211
  `;
199
212
  /**
200
213
  * Shared setup/auth block for every Plans skill (`/visual-plan`,
201
- * `/visual-recap`, `/ui-plan`, `/prototype-plan`, `/plan-design`,
202
- * `/visual-questions`). Interpolated into each skill markdown
214
+ * `/visual-recap`). Interpolated into each skill markdown
203
215
  * so the install + one-step authenticate instructions never drift between them.
204
216
  * Keep this in sync with the copies under `templates/plan/.agents/skills/*` and
205
217
  * top-level `skills/*` (this skill's SKILL.md is triplicated with no sync test).
@@ -217,10 +229,12 @@ intended), so the first tool call does not hit an OAuth wall:
217
229
  agent-native skills add visual-plan
218
230
  \`\`\`
219
231
 
220
- After that, \`/visual-plan\` (and \`/visual-recap\`, \`/ui-plan\`,
221
- \`/prototype-plan\`, \`/plan-design\`, \`/visual-questions\`) generate a plan and open
222
- the editor. Pass \`--no-connect\` to
223
- register the connector without authenticating, then run
232
+ After that, \`/visual-plan\` and \`/visual-recap\` are the two installed slash
233
+ commands. Other planning modes — UI-first (\`create-ui-plan\`), prototype-first
234
+ (\`create-prototype-plan\`), design-first (\`create-plan-design\`), and visual
235
+ intake (\`create-visual-questions\`) are MCP tools reachable from \`/visual-plan\`,
236
+ not separate slash commands. Pass \`--no-connect\` to register the connector
237
+ without authenticating, then run
224
238
  \`agent-native connect https://plan.agent-native.com\` whenever you are ready.
225
239
 
226
240
  **Browser (people you share with).** Open the Plans editor and create & edit
@@ -249,13 +263,13 @@ not put shared secrets in skill files.`;
249
263
  // distributed artifact stays a flat string, so distribution is unchanged.
250
264
  //
251
265
  // Consumers:
252
- // WIREFRAME_QUALITY_CORE — visual-plan, ui-plan, visual-recap (surface-agnostic)
253
- // CANVAS_SURFACE_CORE — visual-plan, ui-plan (canvas/artboard mechanics)
254
- // DOCUMENT_QUALITY_CORE — visual-plan, ui-plan
255
- // EXEMPLAR_CORE — visual-plan, ui-plan
266
+ // WIREFRAME_QUALITY_CORE — visual-plan, visual-recap (surface-agnostic)
267
+ // CANVAS_SURFACE_CORE — visual-plan modes (canvas/artboard mechanics)
268
+ // DOCUMENT_QUALITY_CORE — visual-plan
269
+ // EXEMPLAR_CORE — visual-plan
256
270
  // Surface-agnostic HTML wireframe quality rules. Applies equally to a standalone
257
- // WireframeBlock/<Screen> (visual-recap) and to a canvas artboard (visual-plan /
258
- // ui-plan). Do not put canvas/artboard placement mechanics here.
271
+ // WireframeBlock/<Screen> (visual-recap) and to a canvas artboard (visual-plan).
272
+ // Do not put canvas/artboard placement mechanics here.
259
273
  const WIREFRAME_QUALITY_CORE = `<!-- SHARED-CORE:wireframe-quality START -->
260
274
 
261
275
  **A wireframe is an HTML mockup. The renderer owns the look; you write the
@@ -476,7 +490,34 @@ hex colors:
476
490
  \`\`\`
477
491
 
478
492
  <!-- SHARED-CORE:wireframe-quality END -->`;
479
- // Canvas/artboard placement mechanics. Used only by visual-plan and ui-plan
493
+ // Progressive-disclosure reference file. `WIREFRAME_QUALITY_CORE` is the single
494
+ // source of truth for HTML wireframe quality; it is materialized verbatim into a
495
+ // sibling `references/wireframe.md` in EVERY plan skill dir (visual-plan and
496
+ // visual-recap), instead of being interpolated inline into each SKILL.md body.
497
+ // The SKILL.md bodies carry only `WIREFRAME_REFERENCE_POINTER`, which tells the
498
+ // agent to read this file before authoring any wireframe. Keeping the reference
499
+ // body byte-identical to the core (markers included) lets the sync guard assert
500
+ // the on-disk copies never drift from the canonical constant.
501
+ export const WIREFRAME_REFERENCE_MD = `# HTML wireframe quality — single source of truth
502
+
503
+ This file is the canonical quality bar for HTML wireframes / \`<Screen>\` /
504
+ \`WireframeBlock\` content, shared word for word by \`/visual-plan\` and
505
+ \`/visual-recap\`. Read it in full before authoring ANY wireframe; do not
506
+ author wireframes from memory or paraphrase these rules per command.
507
+
508
+ ${WIREFRAME_QUALITY_CORE}
509
+ `;
510
+ // Short pointer that replaces the inline wireframe-quality core in each SKILL.md
511
+ // body. Authoring quality lives in the sibling reference file so the SKILL.md
512
+ // stays lean (progressive disclosure); the agent loads the detail on demand.
513
+ const WIREFRAME_REFERENCE_POINTER = `UI recap/plan wireframes must meet a strict quality bar — full-width chrome,
514
+ pinned bottom bars, real product content, before/after comparability, the right
515
+ \`surface\` preset, \`--wf-*\` tokens instead of hex, and no \`<html>\`/\`<style>\`/font
516
+ tags. Before authoring ANY wireframe / \`<Screen>\` / \`WireframeBlock\`, READ
517
+ \`references/wireframe.md\` in this skill directory — it is the single source of
518
+ truth for HTML wireframe quality, shared word for word with \`/visual-plan\`
519
+ and \`/visual-recap\`. Do not author wireframes from memory.`;
520
+ // Canvas/artboard placement mechanics. Used only by visual-plan modes
480
521
  // (visual-recap renders standalone wireframes, not a canvas).
481
522
  const CANVAS_SURFACE_CORE = `<!-- SHARED-CORE:canvas-surface START -->
482
523
 
@@ -693,7 +734,7 @@ unreadable diagrams before asking for approval.
693
734
  <!-- SHARED-CORE:document-quality END -->`;
694
735
  const EXEMPLAR_CORE = `<!-- SHARED-CORE:exemplar START -->
695
736
 
696
- **GOOD.** A \`/ui-plan\` for a todo app: a canvas with a \`desktop\` artboard whose
737
+ **GOOD.** A UI-first plan for a todo app: a canvas with a \`desktop\` artboard whose
697
738
  \`data.html\` is a real flex layout — a sidebar of links (\`Inbox 12\`, \`Today 4\`,
698
739
  \`Done\`), a main column with an \`<h1>Today</h1>\`, accent \`.wf-pill\`s for the
699
740
  filters, a muted section label \`OVERDUE\`, and \`.wf-card\` task rows carrying real
@@ -733,6 +774,60 @@ labeled boxes with overlapping text, where the actual code evidence and
733
774
  recommendations live elsewhere. Never produce this.
734
775
 
735
776
  <!-- SHARED-CORE:exemplar END -->`;
777
+ // Progressive-disclosure reference files. Like `WIREFRAME_REFERENCE_MD`, each of
778
+ // the canvas / document-quality / exemplar cores is the single source of truth
779
+ // for its topic and is materialized verbatim into a sibling `references/*.md`
780
+ // file in the visual-plan skill dir instead of being interpolated inline into
781
+ // the SKILL.md body. The body carries only the matching `*_REFERENCE_POINTER`.
782
+ // Keeping each reference body byte-identical to its core (markers included) lets
783
+ // the sync guard assert the on-disk copies never drift from the constant.
784
+ export const CANVAS_REFERENCE_MD = `# Canvas & artboard placement — single source of truth
785
+
786
+ This file is the canonical guide for how the visual-plan canvas works: artboard
787
+ placement, lane layout, annotations, patching, and the legacy kit tree. Read it
788
+ in full before authoring or editing any canvas/artboard content; do not author
789
+ canvas layouts from memory or paraphrase these rules per mode.
790
+
791
+ ${CANVAS_SURFACE_CORE}
792
+ `;
793
+ export const DOCUMENT_QUALITY_REFERENCE_MD = `# Plan document quality — single source of truth
794
+
795
+ This file is the canonical quality bar for the plan document below the canvas:
796
+ how it reads, which blocks to use, how open questions are surfaced, and the
797
+ pre-handoff check. Read it in full before authoring the plan document; it is the
798
+ quality bar. Do not write the document from memory or paraphrase these rules per
799
+ mode.
800
+
801
+ ${DOCUMENT_QUALITY_CORE}
802
+ `;
803
+ export const EXEMPLAR_REFERENCE_MD = `# Good vs. bad exemplar — single source of truth
804
+
805
+ This file is the canonical worked example of a great plan (and the anti-patterns
806
+ to avoid). Read it alongside the document-quality and canvas references before
807
+ authoring a plan; it is the bar these plans must clear.
808
+
809
+ ${EXEMPLAR_CORE}
810
+ `;
811
+ // Short pointers that replace the inline canvas / document-quality / exemplar
812
+ // cores in the SKILL.md body. Authoring detail lives in the sibling reference
813
+ // files so the SKILL.md stays lean (progressive disclosure); the agent loads the
814
+ // detail on demand.
815
+ const CANVAS_REFERENCE_POINTER = `The canvas is the single source of truth for static UI mockups: artboard
816
+ placement is locked by the \`surface\` (never coordinates), mixed surfaces lay out
817
+ in lanes, annotations are plain-text designer notes anchored by
818
+ \`targetId\`/\`placement\`, and edits are surgical \`contentPatches\`. Before
819
+ authoring or editing ANY canvas, artboard, or annotation, READ
820
+ \`references/canvas.md\` in this skill directory — it is the single source of truth
821
+ for canvas/artboard mechanics. Do not author canvas layouts from memory.`;
822
+ const DOCUMENT_QUALITY_REFERENCE_POINTER = `The document is a serious technical plan, not marketing: outcome-first,
823
+ prose-first, self-contained, built from the right native blocks, with open
824
+ questions in a single bottom \`question-form\` and a pre-handoff visual check.
825
+ Before authoring the plan document, READ \`references/document-quality.md\` in this
826
+ skill directory — it is the single source of truth for the document quality bar.
827
+ Do not write the document from memory.`;
828
+ const EXEMPLAR_REFERENCE_POINTER = `For a worked example of the bar — a great UI-first plan and \`/visual-plan\`, plus
829
+ the anti-patterns to avoid — READ \`references/exemplar.md\` in this skill
830
+ directory before authoring a plan.`;
736
831
  export const VISUAL_PLANS_SKILL_MD = `---
737
832
  name: visual-plan
738
833
  description: >-
@@ -754,14 +849,14 @@ usually start in the document with local diagrams near each claim. UI and produc
754
849
  plans should still start with the top canvas/prototype when screens or behavior
755
850
  are what the user needs to review.
756
851
 
757
- \`/visual-plan\` is the canonical command and the main entry point. Use \`/ui-plan\`
758
- when the work is primarily product UI and review should start with the screens.
759
- Use \`/prototype-plan\` when review should start with a functional live prototype.
760
- Use \`/plan-design\` when review should start with full-fidelity branded design.
761
- Use \`/visual-questions\` only when the user explicitly wants a visual intake form
762
- before planning. When a Codex, Claude Code, Markdown, or pasted plan already
763
- exists, \`/visual-plan\` uses that source plan as the starting point and builds
764
- the review surface from it instead of starting over.
852
+ \`/visual-plan\` is the packaged command and main entry point. Choose the review
853
+ mode from the task: UI-first when the work is primarily product UI and review
854
+ should start with screens, prototype-first when review should start with a
855
+ functional live prototype, design-first when review needs full-fidelity branded
856
+ screens, or visual-intake when the user explicitly wants a questionnaire before
857
+ planning. When a Codex, Claude Code, Markdown, or pasted plan already exists,
858
+ \`/visual-plan\` uses that source plan as the starting point and builds the review
859
+ surface from it instead of starting over.
765
860
 
766
861
  ## When To Use
767
862
 
@@ -939,38 +1034,30 @@ not add visual chrome by default:
939
1034
  needs to operate the behavior. Keep the static wireframes in
940
1035
  \`content.canvas\`, add the aligned functional prototype in
941
1036
  \`content.prototype\`, and rely on the top visual tabs to switch between them.
942
- - **Prototype-first** when the user explicitly asks for \`/prototype-plan\`, asks
943
- to operate the UI, or when interaction is the main question. Use
944
- \`create-prototype-plan\`, which still preserves static mocks where useful.
1037
+ - **Prototype-first** when the user asks to operate the UI or when interaction is
1038
+ the main question. Use \`create-prototype-plan\`, which still preserves static
1039
+ mocks where useful.
945
1040
 
946
1041
  For mixed canvas + prototype plans, reuse the same real labels, app statuses,
947
1042
  and screen ids across both surfaces. The canvas is the inspectable static reference;
948
1043
  the prototype is the interactive version of that same flow, not a separate
949
1044
  design direction.
950
1045
 
951
- ## Wireframe & Canvas Core
1046
+ ## Wireframe quality read \`references/wireframe.md\`
952
1047
 
953
- This section is shared by \`/visual-plan\` and \`/ui-plan\`, and is the single
954
- source of truth for how wireframes and the canvas work. The wireframe-quality
955
- rules below are additionally shared, word for word, with \`/visual-recap\`; the
956
- canvas/artboard mechanics apply only to \`/visual-plan\` and \`/ui-plan\`. Do not
957
- paraphrase any of it per command.
1048
+ ${WIREFRAME_REFERENCE_POINTER}
958
1049
 
959
- ${WIREFRAME_QUALITY_CORE}
1050
+ ## Canvas — read \`references/canvas.md\`
960
1051
 
961
- ${CANVAS_SURFACE_CORE}
1052
+ ${CANVAS_REFERENCE_POINTER}
962
1053
 
963
- ## Document Quality Core
1054
+ ## Document quality — read \`references/document-quality.md\`
964
1055
 
965
- This section is shared, word for word, by \`/visual-plan\` and \`/ui-plan\`. It is
966
- the single source of truth for the document below the canvas. Do not paraphrase
967
- it per command.
1056
+ ${DOCUMENT_QUALITY_REFERENCE_POINTER}
968
1057
 
969
- ${DOCUMENT_QUALITY_CORE}
1058
+ ## Good vs. bad exemplar — read \`references/exemplar.md\`
970
1059
 
971
- ## Good vs. Bad Exemplar
972
-
973
- ${EXEMPLAR_CORE}
1060
+ ${EXEMPLAR_REFERENCE_POINTER}
974
1061
 
975
1062
  ## Tool Guidance
976
1063
 
@@ -984,8 +1071,8 @@ ${EXEMPLAR_CORE}
984
1071
  optional matching Prototype tab.
985
1072
  - \`convert-visual-plan-to-prototype\`: convert an existing HTML wireframe canvas
986
1073
  into a prototype plan.
987
- - \`create-visual-questions\`: use only for the explicit \`/visual-questions\`
988
- command, not as \`/visual-plan\` preflight.
1074
+ - \`create-visual-questions\`: use only when the user explicitly asks for a visual
1075
+ intake questionnaire, not as \`/visual-plan\` preflight.
989
1076
  - \`update-visual-plan\`: revise content, status, or comments; prefer
990
1077
  \`contentPatches\` over regenerating the whole plan.
991
1078
  - \`read-visual-plan-source\`: read the normalized plan as \`plan.mdx\`,
@@ -998,177 +1085,22 @@ ${EXEMPLAR_CORE}
998
1085
  - \`get-plan-feedback\`: read unconsumed human feedback. Use it frequently; it
999
1086
  returns grouped threads, exact anchor details, expected resolver, and recent
1000
1087
  review-event payloads so agents can act only on the comments meant for them.
1088
+ - \`get-plan-blocks\`: resolve block tags before authoring — do not memorize tags;
1089
+ call this first to get the authoritative tag names, required fields, and prop
1090
+ shapes from the live block registry.
1001
1091
  - \`export-visual-plan\`: export HTML, Markdown fallback, structured JSON, and MDX
1002
1092
  files for repo check-in.
1003
1093
 
1004
1094
  When the user critiques a plan's look or structure, fix the renderer or this
1005
1095
  skill — never hand-edit one stored plan. Turn feedback into better guidance.
1006
1096
 
1007
- ## Setup & Authentication
1008
-
1009
- There are two ways into Plans.
1010
-
1011
- **Coding agent (CLI).** Install once with the Agent-Native CLI. The command
1012
- installs the Plans skills, registers the hosted Plans MCP connector, and
1013
- authenticates it in the same step (a one-time browser sign-in at setup — this is
1014
- intended), so the first tool call does not hit an OAuth wall:
1015
-
1016
- \`\`\`bash
1017
- agent-native skills add visual-plan
1018
- \`\`\`
1019
-
1020
- After that, \`/visual-plan\` (and \`/visual-recap\`, \`/ui-plan\`,
1021
- \`/prototype-plan\`, \`/plan-design\`, \`/visual-questions\`) generate a plan and open
1022
- the editor. Pass \`--no-connect\` to
1023
- register the connector without authenticating, then run
1024
- \`agent-native connect https://plan.agent-native.com\` whenever you are ready.
1025
-
1026
- **Browser (people you share with).** Open the Plans editor and create & edit
1027
- with no sign-up — you work as a guest. Sign in only when you want to save or
1028
- share; signing in claims the plans you made as a guest into your account.
1029
-
1030
- Sharing and commenting require an account: public/shared plans are viewable by
1031
- anyone with the link, but commenting on them needs an agent-native account.
1032
-
1033
- For fully offline, no-account use, run the Plans app locally and sync plans to
1034
- your repo as MDX. This local mode is a separate advanced path, not the default
1035
- hosted flow.
1036
-
1037
- If a Plans tool returns \`needs auth\`, \`Unauthorized\`, or \`Session terminated\`,
1038
- do not keep retrying the tool. Authenticate the connector with
1039
- \`agent-native connect https://plan.agent-native.com\` (OAuth-capable hosts can
1040
- instead re-run /mcp and choose Authenticate), then continue once the connector
1041
- is available.
1042
-
1043
- Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
1044
- not put shared secrets in skill files.
1045
- `;
1046
- export const UI_PLAN_SKILL_MD = `---
1047
- name: ui-plan
1048
- description: >-
1049
- Use Agent-Native Plans for UI-first planning with an optional top pan/zoom
1050
- wireframe canvas, a refined Notion-like document, rich tabs, diagrams,
1051
- comments, drawing, and agent handoff.
1052
- metadata:
1053
- visibility: exported
1054
- ---
1055
-
1056
- # UI Plan
1057
-
1058
- Use \`/ui-plan\` when the task is primarily about product UI, user flows,
1059
- interaction details, component layout, or visual direction. The reviewable UI
1060
- comes first; implementation detail comes after the user has something concrete to
1061
- react to.
1062
-
1063
- \`/visual-plan\` remains the general command for architecture, backend, refactors,
1064
- and mixed work. Use \`/prototype-plan\` when the UI review needs a functional live
1065
- prototype instead of static screens. Use \`/plan-design\` when polish, brand, or
1066
- visual fidelity are material to the decision. Use \`/visual-questions\` only when
1067
- the user explicitly wants visual intake before planning. Use \`/visual-plan\` when
1068
- a text plan already exists and should become the source material for the review.
1069
-
1070
- ## Plan Discipline
1071
-
1072
- - **Gate hard.** Use a UI plan when the surface is new, ambiguous, spans several
1073
- screens or states, or the direction needs agreement before coding. Skip it for
1074
- cosmetic one-liners — a color, a label, a spacing tweak — and just make the
1075
- change. Never ship a single-step or filler plan.
1076
- - **Research before you draft.** Read the real components, routes, and design
1077
- tokens first; ground every mockup and the file map in actual files and symbols.
1078
- Delegate wide exploration to a sub-agent when the surface is large.
1079
- - **Planning is read-only.** Make no source edits while building or reviewing.
1080
- Start editing only after the user approves the UI direction.
1081
- - **Clarify vs. assume.** Do not ask how to build the UI — present the direction
1082
- and options as mockups and tabs. Ask a clarifying question only when an
1083
- ambiguity would change the design; use the host agent's normal
1084
- ask-user-question flow and batch 2-4 before finalizing. Do not call
1085
- \`create-visual-questions\` from \`/ui-plan\`; keep answerable follow-up inside
1086
- the same plan as a bottom \`question-form\` Open Questions block. Otherwise
1087
- state the assumption in the plan and proceed.
1088
- - **The plan is the approval gate.** Ask the user to review and approve the UI
1089
- direction before you write code, and name the files/areas the work touches.
1090
-
1091
- ## UI-First Workflow
1092
-
1093
- 1. Follow the host agent's normal planning flow: inspect the codebase, gather
1094
- the UI/component context needed, and ask native clarifying questions as needed
1095
- before generating the plan.
1096
- 2. Call \`create-ui-plan\` with a UI-specific title, brief, source, repo path, and
1097
- structured \`content\`. The canvas comes first, the document second.
1098
- 3. Compose the top canvas from the kit (see the cores below): the key artboards
1099
- with real product content, designer notes, and connectors only for real
1100
- sequences. Skip the canvas when wireframes would not clarify the work.
1101
- 4. Continue below as a concise technical document that stays close to the
1102
- Markdown plan the agent would normally output — not a second copy of the
1103
- canvas — covering concrete files, contracts, phases, risks, and validation.
1104
- 5. Call \`get-plan-feedback\` before implementation, after review, after a long
1105
- pause, and before the final response. Treat \`anchorDetails\`, resolver intent,
1106
- recent review events, and any focused screenshots from browser handoff as the
1107
- source of truth for exactly what changed and exactly what each UI comment
1108
- points at. Apply changes with \`update-visual-plan\`, preferring
1109
- \`contentPatches\` for one frame, annotation, node, tab, or block. When the
1110
- user wants source-control friendly edits, use \`patch-visual-plan-source\`
1111
- against the MDX files instead of regenerating the plan.
1112
-
1113
- ## Agent Handoff
1114
-
1115
- After the canvas and document, add a short handoff that names the chosen UI
1116
- direction, unresolved visual questions, and feedback that must be read before
1117
- code changes. Never claim feedback has been applied until \`get-plan-feedback\` or
1118
- the user has supplied it.
1119
-
1120
- ## Wireframe & Canvas Core
1121
-
1122
- This section is shared by \`/visual-plan\` and \`/ui-plan\`, and is the single
1123
- source of truth for how wireframes and the canvas work. The wireframe-quality
1124
- rules below are additionally shared, word for word, with \`/visual-recap\`; the
1125
- canvas/artboard mechanics apply only to \`/visual-plan\` and \`/ui-plan\`. Do not
1126
- paraphrase any of it per command.
1127
-
1128
- ${WIREFRAME_QUALITY_CORE}
1129
-
1130
- ${CANVAS_SURFACE_CORE}
1131
-
1132
- ## Document Quality Core
1133
-
1134
- This section is shared, word for word, by \`/visual-plan\` and \`/ui-plan\`. It is
1135
- the single source of truth for the document below the canvas. Do not paraphrase
1136
- it per command.
1137
-
1138
- ${DOCUMENT_QUALITY_CORE}
1139
-
1140
- ## Good vs. Bad Exemplar
1141
-
1142
- ${EXEMPLAR_CORE}
1143
-
1144
- ## Tool Guidance
1145
-
1146
- - \`create-ui-plan\`: create the UI-first structured visual plan.
1147
- - \`create-prototype-plan\`: create a prototype-first plan when UI review needs a
1148
- functional live prototype.
1149
- - \`create-plan-design\`: create a full-fidelity branded design plan when polish,
1150
- brand, and detailed visual direction are primary review inputs.
1151
- - \`convert-visual-plan-to-prototype\`: convert an existing HTML wireframe canvas
1152
- into a prototype plan.
1153
- - \`create-visual-questions\`: use only for the explicit \`/visual-questions\`
1154
- command, not as \`/ui-plan\` preflight.
1155
- - \`update-visual-plan\`: revise content, mockups, comments, or handoff notes;
1156
- prefer targeted \`contentPatches\`.
1157
- - \`read-visual-plan-source\`: read the normalized plan as \`plan.mdx\`,
1158
- optional \`canvas.mdx\`, optional \`.plan-state.json\`, and JSON.
1159
- - \`patch-visual-plan-source\`: apply granular MDX AST patches by stable block,
1160
- artboard, annotation, component, or wireframe-node id.
1161
- - \`import-visual-plan-source\`: create or replace a plan from an MDX folder.
1162
- - \`get-visual-plan\`: inspect the current structured plan, exported HTML, and
1163
- annotations; it also returns the MDX folder for source workflows.
1164
- - \`get-plan-feedback\`: read unconsumed reviewer comments before coding; it
1165
- returns grouped threads, exact anchor details, expected resolver, and recent
1166
- review-event payloads so agents can act only on the comments meant for them.
1167
- - \`export-visual-plan\`: export HTML, Markdown fallback, structured JSON, and MDX
1168
- files for repo check-in.
1097
+ ## Visibility & Sharing
1169
1098
 
1170
- When the user critiques a plan's look or structure, fix the renderer or this
1171
- skill never hand-edit one stored plan. Turn feedback into better guidance.
1099
+ Use \`set-resource-visibility\` to change who can see a plan (e.g. public, login,
1100
+ or org-scoped). Use \`share-resource\` to grant specific users or roles access
1101
+ by email or role. Gate visibility before sharing any plan that covers
1102
+ unreleased or private work — default to the narrowest scope that meets the
1103
+ review need.
1172
1104
 
1173
1105
  ## Setup & Authentication
1174
1106
 
@@ -1183,10 +1115,12 @@ intended), so the first tool call does not hit an OAuth wall:
1183
1115
  agent-native skills add visual-plan
1184
1116
  \`\`\`
1185
1117
 
1186
- After that, \`/visual-plan\` (and \`/visual-recap\`, \`/ui-plan\`,
1187
- \`/prototype-plan\`, \`/plan-design\`, \`/visual-questions\`) generate a plan and open
1188
- the editor. Pass \`--no-connect\` to
1189
- register the connector without authenticating, then run
1118
+ After that, \`/visual-plan\` and \`/visual-recap\` are the two installed slash
1119
+ commands. Other planning modes — UI-first (\`create-ui-plan\`), prototype-first
1120
+ (\`create-prototype-plan\`), design-first (\`create-plan-design\`), and visual
1121
+ intake (\`create-visual-questions\`) are MCP tools reachable from \`/visual-plan\`,
1122
+ not separate slash commands. Pass \`--no-connect\` to register the connector
1123
+ without authenticating, then run
1190
1124
  \`agent-native connect https://plan.agent-native.com\` whenever you are ready.
1191
1125
 
1192
1126
  **Browser (people you share with).** Open the Plans editor and create & edit
@@ -1209,273 +1143,6 @@ is available.
1209
1143
  Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
1210
1144
  not put shared secrets in skill files.
1211
1145
  `;
1212
- export const PROTOTYPE_PLAN_SKILL_MD = `---
1213
- name: prototype-plan
1214
- description: >-
1215
- Use Agent-Native Plans for /prototype-plan when work needs a functional
1216
- prototype-first plan, static mocks, comments, review toggles, or conversion
1217
- from a visual plan.
1218
- metadata:
1219
- visibility: exported
1220
- ---
1221
-
1222
- # Prototype Plan
1223
-
1224
- \`/prototype-plan\` creates a plan whose primary review surface is a live,
1225
- functional prototype above the document. Use it when the user needs to feel a
1226
- flow, operate basic UI state, or comment on interaction before implementation
1227
- hardens the decision.
1228
-
1229
- ## Rule
1230
-
1231
- Make the prototype answer a concrete question. The plan should say what is being
1232
- tested, show the functional prototype first, then keep static mocks and implementation
1233
- notes in the document below.
1234
-
1235
- ## When To Use
1236
-
1237
- Use \`/prototype-plan\` when the user asks for a prototype, wants to click through
1238
- and operate UI states, needs design review before code, wants comments pinned to
1239
- live screens, or asks to move a visual plan into a prototype.
1240
-
1241
- Prefer \`/visual-plan\` for architecture, data flow, or non-interactive planning.
1242
- Prefer \`/ui-plan\` when static screen review is enough. Use \`/visual-plan\` first
1243
- when the user hands you an existing Markdown/Codex/Claude plan that needs a
1244
- visual companion before becoming interactive.
1245
-
1246
- ## Core Workflow
1247
-
1248
- 1. Inspect the real codebase and decide the question the prototype should
1249
- answer. Good examples: "Does this onboarding flow feel short enough?" or
1250
- "Which dashboard density should we implement?"
1251
- 2. Call \`create-prototype-plan\` with a title, brief, and screen HTML. Default to
1252
- one functional prototype screen when local UI behavior is enough; use 2-4
1253
- screens only for true routes, steps, or materially different contexts. The
1254
- returned plan opens with the prototype viewer on top and static mocks, flow
1255
- diagram, implementation map, and verification below.
1256
- 3. Make controls actually work. Use the renderer's safe Alpine-like directives:
1257
- \`x-data\`, \`x-model\`, \`x-for\`, \`x-text\`, \`x-show\`, \`:class\`, \`@click\`, and
1258
- \`@keydown.enter\`. Use safe helper verbs such as \`remove(list, item)\`,
1259
- \`setAll(list, 'done', true)\`, \`removeWhere(list, 'done', true)\`, and counters
1260
- such as \`count(list)\`, \`countWhere(list, 'done', true)\`, and
1261
- \`remaining(list, 'done')\` when they help. Use \`data-goto="screen-id"\` only
1262
- for true screen/route changes, not for every button press.
1263
- 4. Show important app feedback inside the prototype itself: selected filters,
1264
- checked rows, typed drafts, validation messages, permissions, progress, or
1265
- empty states.
1266
- 5. Surface the returned Plans link and ask the user to click through, comment on
1267
- the prototype or static mocks, and approve the direction before code changes.
1268
- 6. Before implementing or revising, call \`get-plan-feedback\`. Treat prototype
1269
- anchors, screenshots, and resolver intent as the source of truth.
1270
- 7. Update with \`update-visual-plan\` content patches. Use
1271
- \`patch-prototype-html\`, \`update-prototype-screen\`, or \`set-prototype\` for
1272
- targeted prototype edits instead of regenerating the whole plan.
1273
-
1274
- ## Converting A Visual Plan
1275
-
1276
- When a visual plan already has HTML canvas wireframes, call
1277
- \`convert-visual-plan-to-prototype\` with the plan id. This derives prototype
1278
- screens from the canvas frames, preserves the canvas/static mocks by default,
1279
- and changes the top review surface to the prototype viewer.
1280
-
1281
- Use \`removeCanvas: true\` only when the user explicitly wants the old canvas
1282
- gone. Otherwise keep static mocks available for source export and detailed
1283
- review.
1284
-
1285
- ## Prototype Screen HTML
1286
-
1287
- Write bounded semantic HTML fragments only:
1288
-
1289
- \`\`\`html
1290
- <div style="display:flex;flex-direction:column;gap:14px;padding:18px;height:100%">
1291
- <header style="display:flex;justify-content:space-between;gap:12px">
1292
- <div>
1293
- <h1>Launch checklist</h1>
1294
- <p class="wf-muted">Reviewer can add, complete, filter, and remove tasks.</p>
1295
- </div>
1296
- <span class="wf-pill accent">Live prototype</span>
1297
- </header>
1298
- <section
1299
- class="wf-card"
1300
- x-data="{ draft: '', filter: 'all', todos: [{ text: 'Check copy', done: false }, { text: 'Confirm owner', done: true }] }"
1301
- style="display:flex;flex-direction:column;gap:10px"
1302
- >
1303
- <div style="display:flex;gap:8px">
1304
- <input x-model="draft" @keydown.enter="draft && todos.push({ text: draft, done: false }); draft = ''" placeholder="Add task" />
1305
- <button class="primary" @click="draft && todos.push({ text: draft, done: false }); draft = ''">Add</button>
1306
- </div>
1307
- <div style="display:flex;gap:8px">
1308
- <button @click="filter = 'all'" :class="{ primary: filter === 'all' }">All</button>
1309
- <button @click="filter = 'done'" :class="{ primary: filter === 'done' }">Done</button>
1310
- <button @click="setAll(todos, 'done', true)">Mark all done</button>
1311
- </div>
1312
- <p class="wf-muted"><span x-text="remaining(todos, 'done')"></span> open / <span x-text="count(todos)"></span> total</p>
1313
- <div
1314
- class="wf-box"
1315
- x-for="todo in todos"
1316
- x-show="filter === 'all' || (filter === 'done' && todo.done)"
1317
- :class="{ 'is-done': todo.done }"
1318
- style="display:flex;justify-content:space-between;gap:10px"
1319
- >
1320
- <label style="display:flex;gap:8px"><input type="checkbox" x-model="todo.done" /><span x-text="todo.text"></span></label>
1321
- <button @click="remove(todos, todo)">Remove</button>
1322
- </div>
1323
- <button @click="removeWhere(todos, 'done', true)">Clear completed</button>
1324
- </section>
1325
- </div>
1326
- \`\`\`
1327
-
1328
- Use real labels, counts, dates, and controls grounded in the target app. Keep
1329
- surfaces honest: \`browser\` for web pages, \`desktop\` for app shells, \`mobile\`
1330
- only for real mobile work, \`panel\` for side panels, and \`popover\` for menus.
1331
-
1332
- Do not include \`<html>\`, \`<body>\`, \`<script>\`, \`<style>\`, browser \`on*\`
1333
- handler attributes such as \`onclick\`, fake APIs, raw secrets, or customer data.
1334
- The renderer owns sketchy/clean mode, theme, surface sizing, rough outlines, and
1335
- comment overlays.
1336
-
1337
- ## Review Surface
1338
-
1339
- Prototype plans support:
1340
-
1341
- - real local controls through safe prototype directives
1342
- - optional screen/route transitions from \`data-goto\`
1343
- - rough vs clean mode through the shared wireframe toggle
1344
- - dark vs light mode through the shared theme toggle
1345
- - comment visibility from the prototype toolbar
1346
- - Figma-style comments pinned directly on live prototype screens
1347
- - a popout URL with \`?prototype=1\` for focused browser review
1348
- - static wireframe mocks in the document body where they help implementation
1349
-
1350
- ## Source Files
1351
-
1352
- Runtime JSON is canonical. Source export uses:
1353
-
1354
- - \`plan.mdx\` for document blocks
1355
- - \`prototype.mdx\` for \`<Prototype>\`, \`<PrototypeScreen>\`, and
1356
- \`<PrototypeTransition>\`
1357
- - \`canvas.mdx\` for static mocks when a canvas is present
1358
- - \`.plan-state.json\` for persisted viewport state
1359
-
1360
- Patch source with \`patch-visual-plan-source\` only when the user wants
1361
- source-control friendly edits. Patch runtime content when the user is simply
1362
- reviewing and iterating.
1363
-
1364
- ## Related Skills
1365
-
1366
- - \`visual-plan\`
1367
- - \`ui-plan\`
1368
- - \`visual-questions\`
1369
- `;
1370
- export const PLAN_DESIGN_SKILL_MD = `---
1371
- name: plan-design
1372
- description: >-
1373
- Use Agent-Native Plans for full-fidelity UI design planning with a Design
1374
- canvas tab and optional interactive Prototype tab before implementation.
1375
- metadata:
1376
- visibility: exported
1377
- ---
1378
-
1379
- # Plan Design
1380
-
1381
- Use \`/plan-design\` when the user needs a high-fidelity product design before
1382
- implementation: polished branded screens, realistic content, visual direction,
1383
- and interaction review. It is the full-fidelity companion to \`/visual-plan\` and
1384
- \`/prototype-plan\`: the top review surface should show \`Design\` and, when the
1385
- flow needs interaction, \`Prototype\`.
1386
-
1387
- ## When To Use
1388
-
1389
- Use this for UI-heavy work where brand, visual hierarchy, polished layout, or
1390
- interaction feel are material to the decision. Skip it for small copy, spacing,
1391
- or obvious component changes.
1392
-
1393
- ## Research First
1394
-
1395
- Before creating the plan:
1396
-
1397
- 1. Inspect the real app shell, routes, components, CSS variables, Tailwind
1398
- tokens, theme files, and any relevant screenshots.
1399
- 2. If \`design.md\` exists, treat it as the primary design brief and pass its
1400
- important content into \`create-plan-design.designMd\`.
1401
- 3. If a \`.fig\` local-copy file or parsed brand kit is available, use the
1402
- Design/brand-kit parsing actions from the app or shared tooling first, then
1403
- pass the extracted token summary into \`brandKit\`.
1404
- 4. Parse existing codebase style info when possible: CSS custom properties,
1405
- Tailwind config, global CSS, font declarations, spacing/radius tokens, and
1406
- component conventions. Pass the compact evidence into \`codebaseStyles\`.
1407
- 5. Ground every screen in actual product content. Avoid lorem ipsum, generic
1408
- marketing filler, and placeholder gray boxes unless designing an explicit
1409
- loading state.
1410
-
1411
- ## Create The Plan
1412
-
1413
- Call \`create-plan-design\` with:
1414
-
1415
- - \`title\`, \`brief\`, \`repoPath\`, and any \`implementationNotes\`.
1416
- - \`designMd\`, \`brandKit\`, \`codebaseStyles\`, or \`designNotes\` when available.
1417
- - \`screens\`: one to six full-fidelity HTML/CSS screen fragments. Each screen
1418
- must include a bounded \`html\` fragment, optional scoped \`css\`, a \`surface\`,
1419
- and stable \`data-design-id\` attributes on elements a reviewer might edit.
1420
- - \`transitions\` only when the Prototype tab should support true screen/step
1421
- navigation. Use \`data-goto="screen-id"\` in the screen HTML for those controls.
1422
-
1423
- The Design tab is the visual source of truth. The Prototype tab is for behavior
1424
- and should reuse the same visual styling where practical. Do not create a
1425
- separate design direction in the prototype.
1426
-
1427
- ## Full-Fidelity HTML Rules
1428
-
1429
- - Write bounded fragments only: no \`<html>\`, \`<head>\`, \`<body>\`, \`<script>\`,
1430
- \`<style>\`, external imports, iframes, SVG, or executable URLs.
1431
- - Put CSS in the screen \`css\` field. The renderer scopes it to the artboard.
1432
- - Use real CSS and CSS variables. Tailwind-like class names are fine only when
1433
- the provided \`css\` defines them or the classes are harmless semantic hooks.
1434
- - Use \`renderMode: "design"\` on design screen data when authoring full
1435
- structured content directly.
1436
- - Add \`data-design-id="meaningful-name"\` to editable elements such as hero
1437
- panels, key buttons, cards, nav items, pricing rows, chart panels, and state
1438
- chips. Keep ids stable and descriptive.
1439
- - Keep the design responsive within the selected surface. Text must not clip,
1440
- overlap, or rely on viewport-sized type.
1441
-
1442
- ## Targeted Style Edits
1443
-
1444
- When a reviewer selects an element in the Design tab or asks for a specific
1445
- style change, avoid regenerating the whole plan. Use:
1446
-
1447
- \`\`\`json
1448
- {
1449
- "op": "update-design-element-style",
1450
- "frameId": "frame-overview",
1451
- "elementId": "primary-cta",
1452
- "styles": {
1453
- "background-color": "#0f766e",
1454
- "border-radius": "10px"
1455
- }
1456
- }
1457
- \`\`\`
1458
-
1459
- Use \`frameId\` for inline canvas designs or \`blockId\` for a referenced wireframe
1460
- block. Set a style value to \`null\` to remove it. Use \`patch-wireframe-html\` or
1461
- \`patch-prototype-html\` for text/content changes inside a fragment.
1462
-
1463
- ## Document Handoff
1464
-
1465
- Below the visual surface, keep the document concise and implementation-oriented:
1466
- actual files and symbols, state/actions/contracts, open questions, risks, and
1467
- verification. The document should not repeat the same screens in prose.
1468
-
1469
- Before implementation, call \`get-plan-feedback\` and treat comments, selected
1470
- element details, and recent review events as the source of truth.
1471
-
1472
- ## Related Skills
1473
-
1474
- - \`visual-plan\`
1475
- - \`ui-plan\`
1476
- - \`prototype-plan\`
1477
- - \`frontend-design\`
1478
- `;
1479
1146
  export const VISUAL_RECAP_SKILL_MD = `---
1480
1147
  name: visual-recap
1481
1148
  description: >-
@@ -1535,23 +1202,26 @@ otherwise approved by the user.
1535
1202
  ## Always Publish As An Agent-Native Plan — Never Inline
1536
1203
 
1537
1204
  The deliverable is ALWAYS a published Agent-Native Plan, created with the
1538
- \`create-visual-recap\` tool on the \`plan\` MCP server. NEVER hand the recap to the
1539
- user as inline chat content not Markdown prose, not an ASCII sketch, not a
1540
- table, not a fenced "wireframe", not a "here's the recap" summary. A recap's
1541
- entire value is the hosted, interactive, annotatable plan; an inline summary is
1542
- not a recap, it is the thing a recap replaces. The only supported output is to
1543
- publish the plan and return its absolute URL.
1544
-
1545
- Except for the explicit local-files privacy mode above, if the \`plan\` MCP
1546
- server's tools are not available, do NOT improvise an inline
1547
- recap as a fallback. The usual cause is a connector that did not finish
1548
- connecting this session (it registers zero tools), NOT necessarily an auth
1549
- problem so do not assume the user must authenticate. Stop and tell the user
1550
- how to restore it: reconnect the plan MCP server (in Claude Code, run \`/mcp\` and
1551
- reconnect, or restart the session); only if it is genuinely unauthenticated, run
1552
- \`agent-native connect <plan-app-url>\` or re-authenticate via \`/mcp\`. Then publish
1553
- once the tool is reachable. Falling back to inline content is a defect, not a
1554
- degraded mode.
1205
+ \`create-visual-recap\` tool on the Plan MCP connector. The connector is usually
1206
+ exposed as the \`plan\` server, but older installed agents may expose the same
1207
+ hosted connector as \`agent-native-plans\`; both names are valid. NEVER hand the
1208
+ recap to the user as inline chat content not Markdown prose, not an ASCII
1209
+ sketch, not a table, not a fenced "wireframe", not a "here's the recap" summary.
1210
+ A recap's entire value is the hosted, interactive, annotatable plan; an inline
1211
+ summary is not a recap, it is the thing a recap replaces. The only supported
1212
+ output is to publish the plan and return its absolute URL.
1213
+
1214
+ Except for the explicit local-files privacy mode above, if neither the \`plan\`
1215
+ nor legacy \`agent-native-plans\` Plan MCP tools are available, do NOT improvise an
1216
+ inline recap as a fallback. Do not report the connector as disconnected just
1217
+ because it is named \`agent-native-plans\` instead of \`plan\`. The usual cause is a
1218
+ connector that did not finish connecting this session (it registers zero tools),
1219
+ NOT necessarily an auth problem so do not assume the user must authenticate.
1220
+ Stop and tell the user how to restore it: reconnect the Plan MCP connector (in
1221
+ Claude Code, run \`/mcp\` and reconnect, or restart the session); only if it is
1222
+ genuinely unauthenticated, run \`agent-native connect <plan-app-url>\` or
1223
+ re-authenticate via \`/mcp\`. Then publish once the tool is reachable. Falling
1224
+ back to inline content is a defect, not a degraded mode.
1555
1225
 
1556
1226
  ## When To Use
1557
1227
 
@@ -1602,6 +1272,11 @@ them. Alongside the visual/structural headline (wireframes, \`data-model\`,
1602
1272
  \`api-endpoint\`, \`diagram\`), a substantial recap also carries the implementation
1603
1273
  evidence:
1604
1274
 
1275
+ - A short surface/state inventory before authoring: list the changed routes,
1276
+ components, popovers/dialogs, role/access states, empty/error states, and
1277
+ shared abstractions visible in the diff. The final recap must either represent
1278
+ each meaningful item with a block or intentionally omit it because it is tiny,
1279
+ redundant, or not user-visible.
1605
1280
  - A \`file-tree\` of the changed files with each entry's \`change\` flag, so the
1606
1281
  reviewer sees the footprint of the work at a glance.
1607
1282
  - The split \`diff\` of the KEY changed files, grouped under a \`## Key changes\`
@@ -1615,269 +1290,69 @@ Skip the diff appendix only for a genuinely tiny change that reviews faster as
1615
1290
  plain diff (see "When To Use"); for any change worth recapping, the file-tree and
1616
1291
  key-change diffs belong in the plan.
1617
1292
 
1618
- ## UI Impact Needs Wireframes
1619
-
1620
- When the diff changes rendered UI, layout, density, visual state, interaction
1621
- affordances, navigation, controls, menus, dialogs, or design tokens, the recap
1622
- MUST include one or more wireframes. Prose and file diffs are not a substitute
1623
- for showing what changed visually.
1624
-
1625
- Choose the smallest visual surface that makes the review clear:
1626
-
1627
- - Use a \`Before\` / \`After\` wireframe pair when the reviewer benefits from direct
1628
- comparison, such as a removed or added control, a changed state, layout
1629
- density, ordering, navigation, or a visible component replacement. The
1630
- Wireframe Quality core below owns how to lay that pair out (columns vs.
1631
- vertical stack by geometry).
1632
- - Use an after-only wireframe when the change is purely additive or the "before"
1633
- state would only show absence without adding review value.
1634
- - Use more than two wireframes when the UI change is flow-dependent, responsive,
1635
- or stateful; show the meaningful states in order instead of forcing a single
1636
- before/after pair.
1637
- - For tiny surfaces like menus, popovers, dialogs, toasts, or panels, use the
1638
- matching \`surface\` (\`popover\`, \`panel\`, etc.) and show the focused sub-surface.
1639
- Do not redraw a full page unless placement in the page is itself part of the
1640
- change.
1641
-
1642
- Ground each wireframe in the changed UI behavior, component names, file paths,
1643
- and diff-visible labels/states. If exact pixels are inferred rather than
1644
- captured, say so in the wireframe caption or a concise annotation. For
1645
- local/manual recaps, import or update the plan source that holds the wireframes
1646
- so the rendered recap opens with the UI visual available.
1647
-
1648
- ## Wireframe Quality
1649
-
1650
- UI recap wireframes must look like the UI surface that changed, not like generic
1651
- architecture boxes. The following bar is shared, word for word, with
1652
- \`/visual-plan\` and \`/ui-plan\`: it is the single source of truth for HTML
1653
- wireframe quality, and applies to a recap's standalone \`wireframe\` /
1654
- \`WireframeBlock\` / \`<Screen>\` exactly as it applies to a plan's canvas artboard.
1655
-
1656
- <!-- SHARED-CORE:wireframe-quality START -->
1657
-
1658
- **A wireframe is an HTML mockup. The renderer owns the look; you write the
1659
- content.** Set \`data.html\` to a self-contained, semantic HTML fragment of the
1660
- screen and set \`data.surface\`. The renderer owns the surface footprint/aspect,
1661
- the dark/light theme, the hand-drawn font, and the rough.js sketch overlay — you
1662
- never write \`<html>\`/\`<body>\`/\`<script>\`/\`<style>\` tags, font-family, hex colors,
1663
- or any width/height/coordinates. You write real HTML layout and real product
1664
- content; the renderer styles and roughens it.
1665
-
1666
- **A wireframe block's data is an HTML screen plus a surface:**
1667
-
1668
- \`\`\`json
1669
- {
1670
- "surface": "browser",
1671
- "html": "<div style=\\"display:flex;flex-direction:column;gap:10px;padding:16px;height:100%\\"><h1>Sign in</h1><p class=\\"wf-muted\\">Use your work email to continue.</p><div class=\\"wf-card\\" style=\\"display:flex;flex-direction:column;gap:10px\\"><label>Email<input value=\\"jane@acme.co\\" /></label><label>Password<input value=\\"••••••••\\" /></label><label style=\\"display:flex;align-items:center;gap:8px\\"><input type=\\"checkbox\\" checked /> Remember me</label><button class=\\"primary\\">Sign in</button></div><a href=\\"#\\">Forgot password?</a></div>"
1672
- }
1673
- \`\`\`
1674
-
1675
- **Write PLAIN semantic HTML and let the renderer style it.** Bare elements
1676
- (\`h1\`/\`h2\`/\`h3\`, \`p\`, \`button\`, \`input\`, \`<input type="checkbox">\`, \`a\`, \`hr\`)
1677
- are auto-themed — no classes needed. Helper classes carry the rest:
1678
-
1679
- - \`.wf-card\` / \`.wf-box\` — a bordered, padded container (a panel, a list item).
1680
- - \`.wf-pill\` / \`.wf-chip\` — a rounded tag or filter; add \`.accent\`
1681
- (\`<span class="wf-pill accent">\`) for the accent-filled variant.
1682
- - \`.wf-muted\` — secondary/muted text (or use \`<small>\`).
1683
- - \`button.primary\` or any element with \`[data-primary]\` — the accent-filled
1684
- primary button.
1685
-
1686
- **Use the \`--wf-*\` tokens for any custom color, never hex.** The renderer flips
1687
- these on light/dark, so reading them is what keeps a mockup correct in both
1688
- themes. For any inline border, background, or text color, reference a token:
1689
- \`style="border:1.4px solid var(--wf-line)"\`. The tokens are \`--wf-ink\` (text),
1690
- \`--wf-muted\` (secondary text), \`--wf-line\` (borders/dividers), \`--wf-paper\`
1691
- (page background), \`--wf-card\` (raised surface), \`--wf-accent\` /
1692
- \`--wf-accent-fg\` / \`--wf-accent-soft\` (brand action), \`--wf-warn\`, \`--wf-ok\`,
1693
- and \`--wf-radius\`. Never hard-code a hex color and never set \`font-family\` — the
1694
- renderer owns the sketch/clean font.
1695
-
1696
- **Lay out with inline \`style\` flex/grid.** You write the real layout —
1697
- \`display:flex; flex-direction:column; gap:10px; padding:16px\` and so on — and the
1698
- renderer never repositions anything. Compose the actual product: reproduce the
1699
- current screen, then show the modification. Real labels, real counts, real dates,
1700
- real button text grounded in the screen you read; not lorem or gray bars.
1701
-
1702
- **Surface presets — match the real footprint, never default to desktop+mobile.**
1703
- Pick the \`surface\` that matches what the user will actually see:
1704
-
1705
- - \`browser\`: a web page that needs a browser chrome frame around it.
1706
- - \`desktop\`: a full desktop app page or app shell.
1707
- - \`mobile\`: a phone screen, only when the work is genuinely mobile.
1708
- - \`popover\`: a small floating menu, dropdown, or inline popover.
1709
- - \`panel\`: a side panel, inspector, or sidebar widget.
1710
-
1711
- A sidebar popover renders as a small surface, not a desktop page and a phone
1712
- frame. Do not emit \`desktop\` + \`mobile\` variants unless responsive behavior
1713
- actually changes the layout. For a component or widget, show one broader
1714
- app-context frame only when placement affects understanding, then the focused
1715
- component states.
1716
-
1717
- **Model the actual component shell for small surfaces.** A rendered UI change
1718
- belongs in a wireframe; reserve \`diagram\` for architecture, dependency, state,
1719
- or data-flow relationships. Popovers, dropdown menus, command palettes, and
1720
- context menus use \`surface: "popover"\` unless the surrounding page placement is
1721
- the point of the change. Dialogs, sheets, inspectors, sidebars, and long
1722
- property panels use the matching \`panel\` / \`desktop\` surface as appropriate.
1723
- Show the real chrome: trigger or anchor when it matters, title/header row,
1724
- top-right actions, separators, fields, options, selected states, body content,
1725
- and footer actions that are visible in the workflow.
1726
-
1727
- **Modify, don't redesign.** When the task changes an existing screen, reproduce
1728
- the current screen's real layout and footprint FIRST, then change only the delta
1729
- and call it out with a single annotation. Do not restack the page into a new
1730
- layout. For net-new surfaces, compose from the real app shell.
1731
-
1732
- **Classify mockup scope before implementation.** Before turning a plan mockup
1733
- into source code, decide whether each artboard represents the whole page/app
1734
- shell, a route body inside an existing shell, or a component/sub-surface. If an
1735
- artboard includes navigation, sidebars, auth banners, or a signup/login form,
1736
- map those pieces to the real shared shell/auth components instead of nesting the
1737
- entire mockup inside the current page. When a mockup references the product's
1738
- standard signup/login page, find and reuse that existing implementation; do not
1739
- approximate it from the wireframe.
1740
-
1741
- **Zoom in on sub-surfaces, don't redraw the page.** For a small sub-surface (a
1742
- popover, menu, dialog, toast), show the full screen once, then add a small
1743
- separate artboard whose \`html\` contains ONLY that sub-surface — do not re-draw
1744
- the whole page around it, and do not scale a duplicate up. Pick the matching
1745
- \`surface\` (e.g. \`popover\`) so the footprint is right; never widen a popover to
1746
- page width.
1747
-
1748
- **Loading / skeleton states.** Set \`data.skeleton: true\` on the wireframe and
1749
- fill the \`html\` with neutral, textless placeholder geometry — boxes and bars
1750
- built as \`<div>\`s with \`background:var(--wf-line)\` and explicit heights/widths,
1751
- no labels or copy. The renderer drops borders, sketch, and color into the
1752
- skeleton register automatically. Never escape to a \`custom-html\` document block
1753
- to fake a loader.
1754
-
1755
- **Editing an existing mockup.** To change one element, text, or color in an
1756
- existing html mockup, do NOT regenerate the frame — call \`update-visual-plan\`
1757
- with \`contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
1758
- replace }] }]\`. Each \`find\` is a unique snippet of the current html (read it
1759
- first with \`get-visual-plan\`); set \`all: true\` on an edit to replace every
1760
- occurrence. The result is re-sanitized.
1761
-
1762
- **Treat the wireframe border as part of the visible design.** Always wrap HTML
1763
- wireframe content in a root container with real inner padding before drawing
1764
- cards, fields, pills, labels, or controls. Use at least 14-16px of padding,
1765
- \`box-sizing: border-box\`, \`height: 100%\`, and \`gap\` between child rows so the
1766
- first row never sits flush against the screen border. Keep text away from
1767
- borders: every container, field, button, menu item, and annotation needs enough
1768
- padding and line-height to read cleanly in the rendered Plan view.
1769
-
1770
- **Lay out children safely so they never collide.** Use HTML flex/grid with
1771
- \`gap\`, \`min-width: 0\`, and sensible overflow. Avoid negative margins, absolute
1772
- positioning, or fixed child widths that can collide when the renderer switches
1773
- between light/dark, sketch/clean, or different zoom levels.
1774
-
1775
- **Do not wrap intentionally single-line labels.** For toolbars, tab rails,
1776
- breadcrumbs, chip/filter rows, branch and file names, file chips, and code
1777
- filenames — any deliberately single-line row — do not let long text wrap. Put
1778
- \`white-space: nowrap\` on the row (and \`overflow: hidden; text-overflow: ellipsis\`
1779
- on the individual labels that can grow), so the wireframe demonstrates the actual
1780
- layout behavior instead of producing ugly stacked or vertical text. Use
1781
- horizontally scrollable or clipped rails for overflow.
1782
-
1783
- **Fill the frame; keep labels short.** Each artboard is a fixed-size surface — compose enough realistic HTML to fill it top to bottom with even vertical rhythm; never leave a large empty band. On desktop/app-shell sidebars, let the nav stack flex to fill (\`flex:1\`) and add any persistent bottom action/status after it so the rail reads complete in taller frames. On mobile especially, flow real rows down the whole screen (status bar, header, then list/detail content) rather than a header floating above a gap. Keep every label short enough to sit on one line within its column — shorten the copy rather than relying on the frame to absorb it (long labels wrap or clip).
1784
-
1785
- **Persistent chrome bars span the full frame width.** Top bars, app headers,
1786
- toolbars, and bottom tab/nav bars are full-width chrome, not centered content.
1787
- Lay each one out as a single flex row that fills the frame
1788
- (\`style="display:flex;align-items:center;width:100%"\`) and push trailing actions
1789
- to the right edge with a flex spacer (\`<div style="flex:1"></div>\`) between the
1790
- leading group and the trailing group — never center a bar inside a narrow,
1791
- centered block, and never let it collapse to the width of its contents. In a
1792
- Before/After pair the bar stays full-width in BOTH states even when one state has
1793
- fewer controls; the spacer absorbs the difference so the remaining controls hold
1794
- their edge alignment instead of sliding to the center.
1795
-
1796
- **Pin bottom bars to the bottom of the frame.** For mobile tab bars, footers, and
1797
- any persistent bottom action row, make the frame itself a flex column at
1798
- \`height:100%\` (\`style="display:flex;flex-direction:column;height:100%"\`), give the
1799
- scrolling body \`flex:1\` so it absorbs the slack, and place the bar as the LAST
1800
- child of the frame (or set \`margin-top:auto\` on it). The bar then sits flush at
1801
- the bottom of the surface instead of floating directly under the content with an
1802
- empty band beneath it.
1803
-
1804
- **Before / after must be comparable.** When showing a state change, preserve the
1805
- unchanged controls in both states so the reviewer can see exactly what moved or
1806
- appeared; do not show an added control as a generic box floating elsewhere in
1807
- the surface. Place the new/changed affordance where the implementation puts it —
1808
- for example, a new \`Edit with AI\` action in a popover header belongs in the
1809
- top-right header slot, aligned with the title, not in the body or footer. Use
1810
- the same frame size, scale, outer padding, border radius, and visual density on
1811
- both sides unless the change itself alters those properties, and let the frame
1812
- height fit the content rather than leaving a tall empty lower half.
1293
+ ## UI Impact Needs Wireframes
1813
1294
 
1814
- **Name the states with the column header, never inside the frame.** Put the two
1815
- states in a \`columns\` block and set each column's \`label\` to \`Before\` and
1816
- \`After\` the renderer draws that label as an \`h4\` heading above each frame. Do
1817
- NOT bake a \`Before\`/\`After\` pill, title, or heading into the wireframe \`html\`: a
1818
- label placed inside reads as part of the product UI, lands in a random corner,
1819
- and clutters the comparison. The column header is the one and only place the
1820
- state name belongs.
1295
+ When the diff changes rendered UI, layout, density, visual state, interaction
1296
+ affordances, navigation, controls, menus, dialogs, or design tokens, the recap
1297
+ MUST include one or more wireframes. Prose and file diffs are not a substitute
1298
+ for showing what changed visually.
1821
1299
 
1822
- **Let the surface choose side-by-side vs. stacked.** The \`columns\` renderer lays
1823
- narrow surfaces (\`mobile\`, \`popover\`, \`panel\`) out side by side, and
1824
- automatically stacks wide surfaces (\`desktop\`, \`browser\`) vertically at full
1825
- document width so a large frame is never crushed into a half-width column and
1826
- cropped. Author both wireframes with the real \`surface\` and the matching
1827
- \`Before\`/\`After\` column labels; do not hand-stack the pair into separate
1828
- top-level wireframes or duplicate the state name as body content.
1300
+ Before choosing wireframes, make a UI coverage pass from the diff:
1301
+
1302
+ - Identify the entry surface where the change appears, such as a page header,
1303
+ list row, toolbar, route shell, or menu trigger.
1304
+ - Identify the interaction surface that opens or changes, such as a popover,
1305
+ dialog, tab, sheet, dropdown, inline editor, or toast.
1306
+ - Identify the resulting destination or persistent state, such as a public page,
1307
+ read-only view, empty state, error state, loading state, permission-denied
1308
+ state, or saved/shared state.
1309
+ - Identify access or role variants when permissions change. Owner/admin/editor
1310
+ versus viewer/non-manager differences are visual behavior and need a compact
1311
+ matrix, paired wireframes, or clearly labeled state sequence.
1312
+
1313
+ For UI-heavy PRs, a single before/after of the entry surface is not enough.
1314
+ Show the changed entry point, the main changed interaction surface, and the
1315
+ resulting/destination state. Add more states when the diff adds tabs, role-based
1316
+ controls, public/private visibility, invite/manage flows, destructive controls,
1317
+ or empty/error branches.
1829
1318
 
1830
- **Good example a contacts list, surface \`browser\`.** A small, real screen
1831
- composed from the helper classes and tokens, layout in inline flex, no fonts or
1832
- hex colors:
1319
+ Choose the smallest visual surface that makes the review clear:
1833
1320
 
1834
- \`\`\`html
1835
- <div
1836
- style="display:flex;flex-direction:column;gap:12px;padding:16px;height:100%"
1837
- >
1838
- <div style="display:flex;align-items:center;justify-content:space-between">
1839
- <h1>Contacts</h1>
1840
- <button class="primary">New contact</button>
1841
- </div>
1842
- <div style="display:flex;gap:6px">
1843
- <span class="wf-pill accent">All 128</span>
1844
- <span class="wf-pill">Favorites</span>
1845
- <span class="wf-pill">Archived</span>
1846
- </div>
1847
- <div
1848
- class="wf-card"
1849
- style="display:flex;flex-direction:column;gap:0;padding:0"
1850
- >
1851
- <div
1852
- style="display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1.4px solid var(--wf-line)"
1853
- >
1854
- <div
1855
- style="width:32px;height:32px;border-radius:999px;background:var(--wf-accent-soft)"
1856
- ></div>
1857
- <div style="flex:1">
1858
- <strong>Jane Cooper</strong><br /><small>jane@acme.co</small>
1859
- </div>
1860
- <span class="wf-pill">Lead</span>
1861
- </div>
1862
- <div style="display:flex;align-items:center;gap:10px;padding:10px 12px">
1863
- <div
1864
- style="width:32px;height:32px;border-radius:999px;background:var(--wf-accent-soft)"
1865
- ></div>
1866
- <div style="flex:1">
1867
- <strong>Marcus Lee</strong><br /><small>marcus@globex.io</small>
1868
- </div>
1869
- <span class="wf-pill">Customer</span>
1870
- </div>
1871
- </div>
1872
- </div>
1873
- \`\`\`
1321
+ - Use a \`Before\` / \`After\` wireframe pair when the reviewer benefits from direct
1322
+ comparison, such as a removed or added control, a changed state, layout
1323
+ density, ordering, navigation, or a visible component replacement. The
1324
+ Wireframe Quality core below owns how to lay that pair out (columns vs.
1325
+ vertical stack by geometry).
1326
+ - Use an after-only wireframe when the change is purely additive or the "before"
1327
+ state would only show absence without adding review value.
1328
+ - Use more than two wireframes when the UI change is flow-dependent, responsive,
1329
+ or stateful; show the meaningful states in order instead of forcing a single
1330
+ before/after pair.
1331
+ - For tiny surfaces like menus, popovers, dialogs, toasts, or panels, use the
1332
+ matching \`surface\` (\`popover\`, \`panel\`, etc.) and show the focused sub-surface.
1333
+ Do not redraw a full page unless placement in the page is itself part of the
1334
+ change.
1335
+
1336
+ Ground each wireframe in the changed UI behavior, component names, file paths,
1337
+ and diff-visible labels/states. If exact pixels are inferred rather than
1338
+ captured, say so in the wireframe caption or a concise annotation. For
1339
+ local/manual recaps, import or update the plan source that holds the wireframes
1340
+ so the rendered recap opens with the UI visual available.
1874
1341
 
1875
- <!-- SHARED-CORE:wireframe-quality END -->
1342
+ ## Wireframe Quality — read \`references/wireframe.md\`
1343
+
1344
+ UI recap/plan wireframes must meet a strict quality bar — full-width chrome,
1345
+ pinned bottom bars, real product content, before/after comparability, the right
1346
+ \`surface\` preset, \`--wf-*\` tokens instead of hex, and no \`<html>\`/\`<style>\`/font
1347
+ tags. Before authoring ANY wireframe / \`<Screen>\` / \`WireframeBlock\`, READ
1348
+ \`references/wireframe.md\` in this skill directory — it is the single source of
1349
+ truth for HTML wireframe quality, shared word for word with \`/visual-plan\`
1350
+ and \`/visual-recap\`. Do not author wireframes from memory.
1876
1351
 
1877
1352
  Use the standard \`WireframeBlock\` / \`<Screen>\` format so the Plan viewer owns the
1878
1353
  surface frame, theme, and sketchy/clean toggle. HTML wireframes are appropriate
1879
1354
  when placement precision matters, especially popovers, menus, dialogs, and dense
1880
- forms; kit-tree wireframes are appropriate for simpler layouts. For HTML
1355
+ forms. For HTML
1881
1356
  wireframes, keep \`renderMode\` unset or \`wireframe\` unless a design-only editable
1882
1357
  mockup is explicitly required, because \`renderMode="design"\` disables the
1883
1358
  sketchy rough overlay.
@@ -2004,9 +1479,12 @@ tags — resolve every conceptual name to its exact tag + prop schema with the
2004
1479
  wireframes when the comparison clarifies the change; otherwise use after-only
2005
1480
  or a short state/flow sequence. Use realistic UI surfaces: for a popover
2006
1481
  change, show a popover with its title row, top-right actions, options/fields,
2007
- and any opened prompt/menu anchored to the correct trigger. Keep the body lean:
2008
- the wireframe carries the UI story, while the file tree and \`diff\`
2009
- blocks carry implementation evidence.
1482
+ tabs, selected/disabled states, people/lists/rows, and any opened prompt/menu
1483
+ anchored to the correct trigger. If a route was added, show the route body and
1484
+ the unavailable/empty state when the diff implements one. If permissions
1485
+ changed, show what managers can do and what viewers/non-managers see instead.
1486
+ Keep the body lean: the wireframe carries the UI story, while the file tree
1487
+ and \`diff\` blocks carry implementation evidence.
2010
1488
  - **Architecture or data-flow shift** → \`diagram\` with \`data.html\` / \`data.css\`
2011
1489
  as a two-panel before/after, layered, or swimlane layout, or \`mermaid\` for a
2012
1490
  quick graph. Use two-dimensional layouts; do not reduce a structural change to
@@ -2033,8 +1511,9 @@ memorized tags — they drift and silently produce a wrong tag (\`ApiEndpoint\`
2033
1511
  instead of \`Endpoint\`, \`JsonExplorer\` instead of \`Json\`, \`Tabs\` instead of
2034
1512
  \`TabsBlock\`) that errors on import.
2035
1513
 
2036
- **Before writing any structured plan content, call \`get-plan-blocks\` on the
2037
- \`plan\` MCP server.** It returns the authoritative, always-current block
1514
+ **Before writing any structured plan content, call \`get-plan-blocks\` on the Plan
1515
+ MCP connector (\`plan\` or legacy \`agent-native-plans\`).** It returns the
1516
+ authoritative, always-current block
2038
1517
  vocabulary generated live from the app's own block registry — the same config
2039
1518
  the renderer and MDX round-trip use — so it can never be stale even if this
2040
1519
  SKILL.md is an old installed copy:
@@ -2095,7 +1574,10 @@ For UI diffs, wireframes are the visual comparison primitive. Use before/after
2095
1574
  wireframes when the comparison clarifies the change; use after-only or a state
2096
1575
  sequence when that better matches the change. The visual headline must show
2097
1576
  exact placement, realistic chrome, and adequate padding before any abstract
2098
- explanation. The Wireframe Quality core owns the before/after layout choice —
1577
+ explanation. Do not stop at the first visible affordance when the diff adds a
1578
+ flow; show the entry point, the opened surface, and the resulting state or page
1579
+ so the reviewer can trace the actual user path. The Wireframe Quality core owns
1580
+ the before/after layout choice —
2099
1581
  the \`columns\` renderer keeps narrow surfaces side by side and auto-stacks wide
2100
1582
  \`desktop\`/\`browser\` frames vertically; never hand-build a side-by-side
2101
1583
  wireframe layout in \`custom-html\`. For document-body
@@ -2129,15 +1611,19 @@ inferred (not extracted) as inferred in prose.
2129
1611
  hardcoded-secret rule: obviously fake placeholders only, never the real value,
2130
1612
  in any block, caption, or note.
2131
1613
 
2132
- ## Bidirectional Loop (Fast-Follow)
1614
+ ## Bidirectional Loop
2133
1615
 
2134
1616
  Because a recap is a real, editable plan, the same review loop as forward plans
2135
1617
  applies: a reviewer can annotate any block, and the coding agent reads
2136
1618
  \`get-plan-feedback\` to drive fixes back into the code — annotation → agent →
2137
- diff, the same close-the-loop flow forward plans use. In v1, recaps are
2138
- **read-only**: they summarize a merged or proposed change for review, and the
2139
- annotate-to-fix loop is a fast-follow, not yet wired. Build the recap so the
2140
- blocks are anchorable and the loop drops in later without restructuring.
1619
+ diff, the same close-the-loop flow forward plans use. After a reviewer annotates
1620
+ a block, call \`get-plan-feedback\` to read the structured feedback, then either
1621
+ update the recap with \`create-visual-recap\` (passing the existing \`planId\` to
1622
+ replace it in place) or apply targeted changes with \`update-visual-plan\`. The
1623
+ loop is live and wired. The one thing not yet automatic is PR-comment-triggered
1624
+ re-runs: the GitHub Action creates an initial recap per PR, but it does not yet
1625
+ re-run automatically when new review feedback is posted in GitHub — that
1626
+ auto-re-run is the remaining fast-follow.
2141
1627
 
2142
1628
  ## Related Skills
2143
1629
 
@@ -2148,143 +1634,6 @@ blocks are anchorable and the loop drops in later without restructuring.
2148
1634
  recap's redaction and visibility gating mirror.
2149
1635
  - **sharing** — org/login-gated visibility for the plan that holds the recap.
2150
1636
  `;
2151
- export const VISUAL_QUESTIONS_SKILL_MD = `---
2152
- name: visual-questions
2153
- description: >-
2154
- Use Agent-Native Plans to ask rich visual intake questions when
2155
- /visual-questions is explicitly requested before creating a UI plan or visual
2156
- plan.
2157
- metadata:
2158
- visibility: both
2159
- ---
2160
-
2161
- # Visual Questions
2162
-
2163
- Use \`/visual-questions\` when the next best step is not a plan yet, but a
2164
- reviewable visual intake: single-choice option rows, multi-select option rows,
2165
- freeform notes, mockup choices, sketch diagrams, and a generated answer summary
2166
- that feeds the next planning prompt. It composes with \`/visual-plan\`, \`/ui-plan\`,
2167
- \`/prototype-plan\`, and \`/plan-design\`.
2168
-
2169
- ## When To Use
2170
-
2171
- - The user asks to be shown options before the agent writes a plan.
2172
- - UI direction, form factor, layout model, feature set, or visual style is fuzzy
2173
- enough that 2-6 answers would materially change the plan.
2174
- - The user would benefit from choosing between visual mockups or diagrams rather
2175
- than answering text-only prompts.
2176
-
2177
- Gate hard: skip this for tiny, unambiguous changes. If the agent can reasonably
2178
- infer the answer, prefer \`/ui-plan\`, \`/prototype-plan\`, \`/plan-design\`, or
2179
- \`/visual-plan\` directly and put assumptions in the plan.
2180
-
2181
- Visual questions are an explicit intake command, not an automatic preflight for
2182
- \`/visual-plan\`, \`/ui-plan\`, \`/prototype-plan\`, or \`/plan-design\`.
2183
-
2184
- ## Workflow
2185
-
2186
- 1. Call \`create-visual-questions\` with a clear title, brief, source, and repo
2187
- path when known.
2188
- 2. Omit \`questions\` for the default UI intake. Provide a custom \`questions\` array
2189
- only when the task has domain-specific choices.
2190
- 3. Surface the returned Plans link and ask the user to answer visually.
2191
- 4. The generated summary drives the next step: \`create-ui-plan\` for static UI
2192
- review, \`create-prototype-plan\` for click-through UI flows,
2193
- \`create-plan-design\` for high-fidelity branded UI review,
2194
- \`create-visual-plan\` for general plans or when a text plan already exists,
2195
- or \`update-visual-plan\` with targeted \`contentPatches\` to fold answers into
2196
- an active plan.
2197
- 5. If the user leaves comments, call \`get-plan-feedback\` before using the answers.
2198
-
2199
- ## Question Types
2200
-
2201
- Supported \`questions\` entries:
2202
-
2203
- - \`single\`: chip group where one option wins.
2204
- - \`multi\`: chip group where multiple options can be selected.
2205
- - \`freeform\`: textarea for constraints, inspirations, or things to avoid.
2206
- - \`visual\`: visual options with sketch previews — use for layout direction, flow
2207
- depth, surface choice, or diagram choices.
2208
-
2209
- Each option can include \`label\`, \`value\`, \`description\`, \`recommended\`,
2210
- \`preview\`, and \`bullets\`. Valid \`preview\` values match the wireframe surfaces:
2211
- \`desktop\`, \`mobile\`, \`popover\`, \`panel\`, \`component\`, \`split\`, \`flow\`, and
2212
- \`diagram\`. Pick the preview that matches the real footprint — do not offer a
2213
- desktop/mobile pair for a popover, panel, or component.
2214
-
2215
- \`single\`, \`multi\`, and \`visual\` questions always render a write-in field, so a
2216
- reviewer can answer with their own option instead of the listed choices. Do not
2217
- add an explicit "Other" or "Something else" option yourself; set
2218
- \`allowOther: false\` only on the rare question where a free-text answer makes no
2219
- sense.
2220
-
2221
- ## Quality Bar
2222
-
2223
- - Ask only decision-changing questions. A beautiful form with low-value questions
2224
- is still friction.
2225
- - Prefer visible, answerable options over abstract prose.
2226
- - Use visual tabs when users need to compare layout or flow shapes.
2227
- - Keep the output calm and document-like, not a landing page.
2228
- - The generated answer summary is not the final plan; it is the intake prompt for
2229
- the next agent step.
2230
-
2231
- ## Tool Guidance
2232
-
2233
- - \`create-visual-questions\`: create the interactive intake plan.
2234
- - \`get-visual-plan\`: inspect the current visual question plan.
2235
- - \`get-plan-feedback\`: read comments before creating or updating the next plan.
2236
- - \`create-ui-plan\`: create a UI-first plan from the answers.
2237
- - \`create-prototype-plan\`: create a prototype-first plan from the answers when
2238
- interaction feel matters.
2239
- - \`create-plan-design\`: create a high-fidelity branded design plan from the
2240
- answers when visual polish is the primary review input.
2241
- - \`create-visual-plan\`: create a general visual plan from the answers, or pass
2242
- existing plan text as \`planText\` when the answers should shape an imported
2243
- plan.
2244
- - \`export-visual-plan\`: export answer plans as HTML, Markdown fallback,
2245
- structured JSON, and MDX files when the intake needs to be checked into a repo.
2246
- - \`read-visual-plan-source\` / \`patch-visual-plan-source\`: inspect or patch the
2247
- MDX source if another agent is operating from checked-in plan files.
2248
-
2249
- ## Setup & Authentication
2250
-
2251
- There are two ways into Plans.
2252
-
2253
- **Coding agent (CLI).** Install once with the Agent-Native CLI. The command
2254
- installs the Plans skills, registers the hosted Plans MCP connector, and
2255
- authenticates it in the same step (a one-time browser sign-in at setup — this is
2256
- intended), so the first tool call does not hit an OAuth wall:
2257
-
2258
- \`\`\`bash
2259
- agent-native skills add visual-plan
2260
- \`\`\`
2261
-
2262
- After that, \`/visual-plan\` (and \`/visual-recap\`, \`/ui-plan\`,
2263
- \`/prototype-plan\`, \`/plan-design\`, \`/visual-questions\`) generate a plan and open
2264
- the editor. Pass \`--no-connect\` to
2265
- register the connector without authenticating, then run
2266
- \`agent-native connect https://plan.agent-native.com\` whenever you are ready.
2267
-
2268
- **Browser (people you share with).** Open the Plans editor and create & edit
2269
- with no sign-up — you work as a guest. Sign in only when you want to save or
2270
- share; signing in claims the plans you made as a guest into your account.
2271
-
2272
- Sharing and commenting require an account: public/shared plans are viewable by
2273
- anyone with the link, but commenting on them needs an agent-native account.
2274
-
2275
- For fully offline, no-account use, run the Plans app locally and sync plans to
2276
- your repo as MDX. This local mode is a separate advanced path, not the default
2277
- hosted flow.
2278
-
2279
- If a Plans tool returns \`needs auth\`, \`Unauthorized\`, or \`Session terminated\`,
2280
- do not keep retrying the tool. Authenticate the connector with
2281
- \`agent-native connect https://plan.agent-native.com\` (OAuth-capable hosts can
2282
- instead re-run /mcp and choose Authenticate), then continue once the connector
2283
- is available.
2284
-
2285
- Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
2286
- not put shared secrets in skill files.
2287
- `;
2288
1637
  export const BUILT_IN_APP_SKILLS = {
2289
1638
  assets: {
2290
1639
  skillName: "assets",
@@ -2376,10 +1725,19 @@ export const BUILT_IN_APP_SKILLS = {
2376
1725
  skillName: "visual-plan",
2377
1726
  extraSkills: {
2378
1727
  "visual-recap": VISUAL_RECAP_SKILL_MD,
2379
- "visual-questions": VISUAL_QUESTIONS_SKILL_MD,
2380
- "ui-plan": UI_PLAN_SKILL_MD,
2381
- "prototype-plan": PROTOTYPE_PLAN_SKILL_MD,
2382
- "plan-design": PLAN_DESIGN_SKILL_MD,
1728
+ },
1729
+ // Sibling reference files materialized alongside each skill's SKILL.md
1730
+ // (progressive disclosure). Keyed by skill name -> relative path -> content.
1731
+ // Both plan skills ship the same canonical wireframe-quality reference; the
1732
+ // canvas / document-quality / exemplar references are visual-plan only.
1733
+ extraFiles: {
1734
+ "visual-plan": {
1735
+ "references/wireframe.md": WIREFRAME_REFERENCE_MD,
1736
+ "references/canvas.md": CANVAS_REFERENCE_MD,
1737
+ "references/document-quality.md": DOCUMENT_QUALITY_REFERENCE_MD,
1738
+ "references/exemplar.md": EXEMPLAR_REFERENCE_MD,
1739
+ },
1740
+ "visual-recap": { "references/wireframe.md": WIREFRAME_REFERENCE_MD },
2383
1741
  },
2384
1742
  manifest: normalizeAppSkillManifest({
2385
1743
  schemaVersion: 1,
@@ -2390,10 +1748,10 @@ export const BUILT_IN_APP_SKILLS = {
2390
1748
  url: "https://plan.agent-native.com",
2391
1749
  mcpUrl: "https://plan.agent-native.com/_agent-native/mcp",
2392
1750
  },
2393
- mcp: { serverName: "agent-native-plans" },
1751
+ mcp: { serverName: "plan", aliases: ["agent-native-plans"] },
2394
1752
  auth: {
2395
1753
  mode: "oauth",
2396
- setup: "Install with the Agent-Native CLI to add the /visual-plan, /visual-recap, /ui-plan, /prototype-plan, /plan-design, and /visual-questions skills plus the Plan MCP connector. Authenticate only for hosted/account-backed sharing.",
1754
+ setup: "Install with the Agent-Native CLI to add the /visual-plan and /visual-recap skills plus the Plan MCP connector. Authenticate only for hosted/account-backed sharing.",
2397
1755
  },
2398
1756
  surfaces: [
2399
1757
  {
@@ -2408,30 +1766,6 @@ export const BUILT_IN_APP_SKILLS = {
2408
1766
  path: "/plans",
2409
1767
  description: "Create a visual recap plan from a PR, commit, branch, or git diff for high-altitude review.",
2410
1768
  },
2411
- {
2412
- id: "ui-plan",
2413
- action: "create-ui-plan",
2414
- path: "/plans",
2415
- description: "Create a UI-first Agent-Native plan with an optional top pan/zoom wireframe canvas and a refined rich document below.",
2416
- },
2417
- {
2418
- id: "prototype-plan",
2419
- action: "create-prototype-plan",
2420
- path: "/plans",
2421
- description: "Create a prototype-first Agent-Native plan with a functional live prototype above the document.",
2422
- },
2423
- {
2424
- id: "plan-design",
2425
- action: "create-plan-design",
2426
- path: "/plans",
2427
- description: "Create a full-fidelity Agent-Native design plan with a Design canvas tab and optional matching Prototype tab.",
2428
- },
2429
- {
2430
- id: "visual-questions",
2431
- action: "create-visual-questions",
2432
- path: "/plans",
2433
- description: "Create a rich visual intake questionnaire for explicit /visual-questions workflows.",
2434
- },
2435
1769
  ],
2436
1770
  skills: [
2437
1771
  {
@@ -2444,26 +1778,6 @@ export const BUILT_IN_APP_SKILLS = {
2444
1778
  visibility: "exported",
2445
1779
  exportAs: "visual-recap",
2446
1780
  },
2447
- {
2448
- path: "skills/visual-questions",
2449
- visibility: "exported",
2450
- exportAs: "visual-questions",
2451
- },
2452
- {
2453
- path: "skills/ui-plan",
2454
- visibility: "exported",
2455
- exportAs: "ui-plan",
2456
- },
2457
- {
2458
- path: "skills/prototype-plan",
2459
- visibility: "exported",
2460
- exportAs: "prototype-plan",
2461
- },
2462
- {
2463
- path: "skills/plan-design",
2464
- visibility: "exported",
2465
- exportAs: "plan-design",
2466
- },
2467
1781
  ],
2468
1782
  hostAdapters: [
2469
1783
  "codex-plugin",
@@ -2509,6 +1823,7 @@ export const BUILT_IN_APP_SKILLS = {
2509
1823
  skillMarkdown: CONTEXT_XRAY_SKILL_MD,
2510
1824
  },
2511
1825
  };
1826
+ export const AGENT_NATIVE_SKILL_METADATA_FILE = "agent-native-skill.json";
2512
1827
  const BUILT_IN_APP_SKILL_ALIASES = {
2513
1828
  assets: "assets",
2514
1829
  asset: "assets",
@@ -2531,13 +1846,6 @@ const BUILT_IN_APP_SKILL_ALIASES = {
2531
1846
  "visual-recaps": "visual-plans",
2532
1847
  "code-review-recap": "visual-plans",
2533
1848
  "code-review-recaps": "visual-plans",
2534
- "ui-plan": "visual-plans",
2535
- "prototype-plan": "visual-plans",
2536
- "plan-design": "visual-plans",
2537
- "plan-designs": "visual-plans",
2538
- "design-plan": "visual-plans",
2539
- "design-plans": "visual-plans",
2540
- "visual-questions": "visual-plans",
2541
1849
  "html-plan": "visual-plans",
2542
1850
  "plan-mode": "visual-plans",
2543
1851
  plannotate: "visual-plans",
@@ -2561,10 +1869,6 @@ const BUILT_IN_APP_SKILL_DISPLAY_ALIASES = {
2561
1869
  "visual-plan",
2562
1870
  "visual-recap",
2563
1871
  "code-review-recap",
2564
- "ui-plan",
2565
- "prototype-plan",
2566
- "plan-design",
2567
- "visual-questions",
2568
1872
  "html-plan",
2569
1873
  "plannotate",
2570
1874
  ],
@@ -2597,9 +1901,243 @@ function isLocalOnlyBuiltInSkill(entry) {
2597
1901
  function builtInExtraSkills(entry) {
2598
1902
  return "extraSkills" in entry && entry.extraSkills ? entry.extraSkills : {};
2599
1903
  }
1904
+ /**
1905
+ * Sibling reference files for a skill (skill name -> relative path -> content),
1906
+ * materialized alongside its SKILL.md for progressive disclosure.
1907
+ */
1908
+ function builtInExtraFiles(entry) {
1909
+ return "extraFiles" in entry && entry.extraFiles ? entry.extraFiles : {};
1910
+ }
2600
1911
  function builtInSkillNames(entry) {
2601
1912
  return [entry.skillName, ...Object.keys(builtInExtraSkills(entry))];
2602
1913
  }
1914
+ function stableSkillHash(files) {
1915
+ const hash = createHash("sha256");
1916
+ for (const rel of Object.keys(files).sort()) {
1917
+ if (rel === AGENT_NATIVE_SKILL_METADATA_FILE)
1918
+ continue;
1919
+ hash.update(rel);
1920
+ hash.update("\0");
1921
+ hash.update(files[rel]);
1922
+ hash.update("\0");
1923
+ }
1924
+ return hash.digest("hex").slice(0, 16);
1925
+ }
1926
+ function skillFilesForBuiltIn(appSkillId) {
1927
+ const entry = BUILT_IN_APP_SKILLS[appSkillId];
1928
+ const skills = {
1929
+ [entry.skillName]: entry.skillMarkdown,
1930
+ ...builtInExtraSkills(entry),
1931
+ };
1932
+ const extraFiles = builtInExtraFiles(entry);
1933
+ const out = {};
1934
+ for (const [skillName, skillMarkdown] of Object.entries(skills)) {
1935
+ const files = {
1936
+ "SKILL.md": skillMarkdown,
1937
+ ...(extraFiles[skillName] ?? {}),
1938
+ };
1939
+ out[skillName] = {
1940
+ appSkillId,
1941
+ displayName: entry.manifest.displayName,
1942
+ skillName,
1943
+ mcpUrl: isLocalOnlyBuiltInSkill(entry)
1944
+ ? ""
1945
+ : entry.manifest.hosted.mcpUrl,
1946
+ files,
1947
+ contentHash: stableSkillHash(files),
1948
+ };
1949
+ }
1950
+ return out;
1951
+ }
1952
+ function latestSkillBundlesForTargets(appSkillIds) {
1953
+ const out = {};
1954
+ for (const appSkillId of appSkillIds) {
1955
+ Object.assign(out, skillFilesForBuiltIn(appSkillId));
1956
+ }
1957
+ return out;
1958
+ }
1959
+ function writeSkillFolder(dir, bundle, installedAt = new Date().toISOString()) {
1960
+ fs.rmSync(dir, { recursive: true, force: true });
1961
+ fs.mkdirSync(dir, { recursive: true });
1962
+ for (const [rel, content] of Object.entries(bundle.files)) {
1963
+ const target = path.join(dir, rel);
1964
+ fs.mkdirSync(path.dirname(target), { recursive: true });
1965
+ fs.writeFileSync(target, content, "utf-8");
1966
+ }
1967
+ const metadata = {
1968
+ schemaVersion: 1,
1969
+ source: "agent-native",
1970
+ appSkillId: bundle.appSkillId,
1971
+ displayName: bundle.displayName,
1972
+ skillName: bundle.skillName,
1973
+ contentHash: bundle.contentHash,
1974
+ mcpUrl: bundle.mcpUrl,
1975
+ installedAt,
1976
+ updateCommand: `agent-native skills update ${bundle.skillName}`,
1977
+ };
1978
+ fs.writeFileSync(path.join(dir, AGENT_NATIVE_SKILL_METADATA_FILE), `${JSON.stringify(metadata, null, 2)}\n`, "utf-8");
1979
+ }
1980
+ function listSkillFolderFiles(dir) {
1981
+ const out = {};
1982
+ const walk = (current, prefix = "") => {
1983
+ for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
1984
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
1985
+ const abs = path.join(current, entry.name);
1986
+ if (entry.isDirectory()) {
1987
+ walk(abs, rel);
1988
+ continue;
1989
+ }
1990
+ if (!entry.isFile() || rel === AGENT_NATIVE_SKILL_METADATA_FILE)
1991
+ continue;
1992
+ out[rel] = fs.readFileSync(abs, "utf-8");
1993
+ }
1994
+ };
1995
+ if (fs.existsSync(dir))
1996
+ walk(dir);
1997
+ return out;
1998
+ }
1999
+ function readSkillInstallMetadata(dir) {
2000
+ const file = path.join(dir, AGENT_NATIVE_SKILL_METADATA_FILE);
2001
+ if (!fs.existsSync(file))
2002
+ return undefined;
2003
+ try {
2004
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
2005
+ if (parsed &&
2006
+ parsed.source === "agent-native" &&
2007
+ typeof parsed.skillName === "string" &&
2008
+ typeof parsed.contentHash === "string") {
2009
+ return parsed;
2010
+ }
2011
+ }
2012
+ catch { }
2013
+ return undefined;
2014
+ }
2015
+ function homeDir() {
2016
+ return process.env.HOME || os.homedir();
2017
+ }
2018
+ function skillSearchRoots(input) {
2019
+ const roots = [];
2020
+ const clientSet = new Set(input.clients);
2021
+ const includeAll = input.clients.length === 0;
2022
+ const hasClient = (client) => includeAll || clientSet.has(client);
2023
+ const add = (root, scope, client) => {
2024
+ if (root)
2025
+ roots.push({ root, scope, client });
2026
+ };
2027
+ if (input.scopes.includes("project")) {
2028
+ if (hasClient("codex")) {
2029
+ add(path.join(input.baseDir, ".agents", "skills"), "project", "codex");
2030
+ }
2031
+ if (hasClient("claude-code") || hasClient("claude-code-cli")) {
2032
+ add(path.join(input.baseDir, ".claude", "skills"), "project", "claude-code");
2033
+ }
2034
+ if (includeAll)
2035
+ add(path.join(input.baseDir, "skills"), "project", "repo");
2036
+ }
2037
+ if (input.scopes.includes("user")) {
2038
+ const home = homeDir();
2039
+ if (hasClient("codex")) {
2040
+ add(process.env.CODEX_HOME
2041
+ ? path.join(process.env.CODEX_HOME, "skills")
2042
+ : undefined, "user", "codex");
2043
+ add(home ? path.join(home, ".codex", "skills") : undefined, "user", "codex");
2044
+ }
2045
+ if (hasClient("claude-code") || hasClient("claude-code-cli")) {
2046
+ add(home ? path.join(home, ".claude", "skills") : undefined, "user", "claude-code");
2047
+ }
2048
+ }
2049
+ const seen = new Set();
2050
+ return roots.filter((entry) => {
2051
+ const key = `${entry.scope}:${entry.client}:${path.resolve(entry.root)}`;
2052
+ if (seen.has(key))
2053
+ return false;
2054
+ seen.add(key);
2055
+ return true;
2056
+ });
2057
+ }
2058
+ function targetIdsForStatus(parsed) {
2059
+ if (!parsed.target) {
2060
+ return Object.keys(BUILT_IN_APP_SKILLS).filter((id) => !isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[id]));
2061
+ }
2062
+ const known = normalizeKnownSkillTarget(parsed.target);
2063
+ if (!known) {
2064
+ throw new Error(`Unknown built-in skill: ${parsed.target}. Run "agent-native skills list".`);
2065
+ }
2066
+ if (isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[known])) {
2067
+ throw new Error(`${BUILT_IN_APP_SKILLS[known].manifest.displayName} is installed as a local command and cannot be refreshed with skills update yet.`);
2068
+ }
2069
+ return [known];
2070
+ }
2071
+ function scopeFilterForStatus(parsed) {
2072
+ return parsed.scopeExplicit
2073
+ ? [parsed.scope]
2074
+ : ["project", "user"];
2075
+ }
2076
+ function clientFilterForStatus(parsed) {
2077
+ return parsed.clientExplicit ? resolveClients(parsed.client) : [];
2078
+ }
2079
+ function collectSkillInstallStates(parsed, options) {
2080
+ const appSkillIds = targetIdsForStatus(parsed);
2081
+ const latest = latestSkillBundlesForTargets(appSkillIds);
2082
+ const roots = skillSearchRoots({
2083
+ baseDir: options.baseDir ?? process.cwd(),
2084
+ clients: clientFilterForStatus(parsed),
2085
+ scopes: scopeFilterForStatus(parsed),
2086
+ });
2087
+ const states = [];
2088
+ const seenDirs = new Set();
2089
+ for (const root of roots) {
2090
+ for (const bundle of Object.values(latest)) {
2091
+ const dir = path.join(root.root, bundle.skillName);
2092
+ const resolvedDir = path.resolve(dir);
2093
+ if (seenDirs.has(resolvedDir) || !fs.existsSync(dir))
2094
+ continue;
2095
+ if (!fs.existsSync(path.join(dir, "SKILL.md")))
2096
+ continue;
2097
+ seenDirs.add(resolvedDir);
2098
+ const files = listSkillFolderFiles(dir);
2099
+ const installedHash = Object.keys(files).length > 0 ? stableSkillHash(files) : null;
2100
+ const metadata = readSkillInstallMetadata(dir);
2101
+ states.push({
2102
+ appSkillId: bundle.appSkillId,
2103
+ displayName: bundle.displayName,
2104
+ skillName: bundle.skillName,
2105
+ path: dir,
2106
+ root: root.root,
2107
+ scope: root.scope,
2108
+ client: root.client,
2109
+ latestHash: bundle.contentHash,
2110
+ installedHash,
2111
+ metadataHash: metadata?.contentHash,
2112
+ current: installedHash === bundle.contentHash,
2113
+ managed: metadata?.source === "agent-native",
2114
+ });
2115
+ }
2116
+ }
2117
+ return states.sort((a, b) => `${a.skillName}:${a.path}`.localeCompare(`${b.skillName}:${b.path}`));
2118
+ }
2119
+ function updateSkillInstallStates(states, dryRun) {
2120
+ const latest = latestSkillBundlesForTargets([
2121
+ ...new Set(states.map((state) => state.appSkillId)),
2122
+ ]);
2123
+ const updated = [];
2124
+ for (const state of states) {
2125
+ if (state.current && state.managed)
2126
+ continue;
2127
+ const bundle = latest[state.skillName];
2128
+ if (!bundle)
2129
+ continue;
2130
+ if (!dryRun)
2131
+ writeSkillFolder(state.path, bundle);
2132
+ updated.push({
2133
+ ...state,
2134
+ current: !dryRun,
2135
+ installedHash: dryRun ? state.installedHash : bundle.contentHash,
2136
+ metadataHash: dryRun ? state.metadataHash : bundle.contentHash,
2137
+ });
2138
+ }
2139
+ return updated;
2140
+ }
2603
2141
  function normalizeClientIds(values) {
2604
2142
  if (!Array.isArray(values))
2605
2143
  return [];
@@ -2633,6 +2171,31 @@ function skillPromptOptions() {
2633
2171
  hint: entry.manifest.description,
2634
2172
  }));
2635
2173
  }
2174
+ function prVisualRecapWorkflowPath(baseDir) {
2175
+ return path.join(baseDir, ".github", "workflows", "pr-visual-recap.yml");
2176
+ }
2177
+ function prVisualRecapWorkflowDisplayPath() {
2178
+ return path.join(".github", "workflows", "pr-visual-recap.yml");
2179
+ }
2180
+ function prVisualRecapInstallCommand() {
2181
+ return "agent-native skills add visual-plan --with-github-action";
2182
+ }
2183
+ function prVisualRecapSetupCommand() {
2184
+ return "agent-native recap setup";
2185
+ }
2186
+ async function promptForGithubAction(context) {
2187
+ const clack = await import("@clack/prompts");
2188
+ const result = await clack.confirm({
2189
+ message: "Optional: add automatic PR Visual Recaps?\n" +
2190
+ ` This writes ${context.workflowPath}; ${context.setupCommand} can finish GitHub secrets.`,
2191
+ initialValue: false,
2192
+ });
2193
+ if (clack.isCancel(result)) {
2194
+ clack.cancel("Skipped PR Visual Recap workflow.");
2195
+ return null;
2196
+ }
2197
+ return Boolean(result);
2198
+ }
2636
2199
  function shouldPrompt(parsed, options) {
2637
2200
  if (parsed.yes || parsed.printJson)
2638
2201
  return false;
@@ -2717,7 +2280,10 @@ export function parseSkillsArgs(argv) {
2717
2280
  command = "help";
2718
2281
  args = argv.slice(1);
2719
2282
  }
2720
- else if (first === "list" || first === "add") {
2283
+ else if (first === "list" ||
2284
+ first === "add" ||
2285
+ first === "status" ||
2286
+ first === "update") {
2721
2287
  command = first;
2722
2288
  args = argv.slice(1);
2723
2289
  }
@@ -2729,6 +2295,7 @@ export function parseSkillsArgs(argv) {
2729
2295
  client: "codex",
2730
2296
  clientExplicit: false,
2731
2297
  scope: "user",
2298
+ scopeExplicit: false,
2732
2299
  yes: false,
2733
2300
  dryRun: false,
2734
2301
  printJson: false,
@@ -2759,8 +2326,10 @@ export function parseSkillsArgs(argv) {
2759
2326
  out.client = value;
2760
2327
  out.clientExplicit = true;
2761
2328
  }
2762
- else if ((value = eat("--scope")) !== undefined)
2329
+ else if ((value = eat("--scope")) !== undefined) {
2763
2330
  out.scope = value;
2331
+ out.scopeExplicit = true;
2332
+ }
2764
2333
  else if ((value = eat("--mcp-url")) !== undefined)
2765
2334
  out.mcpUrl = value;
2766
2335
  else if (arg === "--yes" || arg === "-y")
@@ -2804,14 +2373,9 @@ function loadSkillTarget(target) {
2804
2373
  },
2805
2374
  skillNames,
2806
2375
  materializeInstructions(outDir) {
2807
- const skills = {
2808
- [builtIn.skillName]: builtIn.skillMarkdown,
2809
- ...builtInExtraSkills(builtIn),
2810
- };
2811
- for (const [skillName, skillMarkdown] of Object.entries(skills)) {
2812
- const skillDir = path.join(outDir, "skills", skillName);
2813
- fs.mkdirSync(skillDir, { recursive: true });
2814
- fs.writeFileSync(path.join(skillDir, "SKILL.md"), skillMarkdown, "utf-8");
2376
+ const bundles = skillFilesForBuiltIn(knownTarget);
2377
+ for (const bundle of Object.values(bundles)) {
2378
+ writeSkillFolder(path.join(outDir, "skills", bundle.skillName), bundle);
2815
2379
  }
2816
2380
  return outDir;
2817
2381
  },
@@ -2909,6 +2473,8 @@ function dryRunInstallCommand(parsed, target) {
2909
2473
  args.push("--mcp-only");
2910
2474
  if (!parsed.connect)
2911
2475
  args.push("--no-connect");
2476
+ if (parsed.withGithubAction)
2477
+ args.push("--with-github-action");
2912
2478
  if (parsed.yes || isKnownSkill(target))
2913
2479
  args.push("--yes");
2914
2480
  return commandString("agent-native", args);
@@ -3065,6 +2631,9 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3065
2631
  const clients = parsed.clients ?? resolveClients(parsed.client);
3066
2632
  const skillsAgents = skillsAgentsForClients(clients);
3067
2633
  if (parsed.dryRun) {
2634
+ const githubActionPath = parsed.withGithubAction && knownTarget === "visual-plans"
2635
+ ? prVisualRecapWorkflowDisplayPath()
2636
+ : undefined;
3068
2637
  return {
3069
2638
  id: knownBuiltIn.manifest.id,
3070
2639
  displayName: knownBuiltIn.manifest.displayName,
@@ -3075,6 +2644,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3075
2644
  dryRun: true,
3076
2645
  local: true,
3077
2646
  commands: [dryRunInstallCommand(parsed, target)],
2647
+ githubActionPath,
3078
2648
  };
3079
2649
  }
3080
2650
  const localInstall = installLocalContextXray({
@@ -3106,6 +2676,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3106
2676
  const skillsAgents = skillsAgentsForClients(clients);
3107
2677
  if (parsed.dryRun) {
3108
2678
  try {
2679
+ const githubActionPath = parsed.withGithubAction && knownTarget === "visual-plans"
2680
+ ? prVisualRecapWorkflowDisplayPath()
2681
+ : undefined;
2682
+ const githubActionSuggestedCommand = knownTarget === "visual-plans" && !parsed.withGithubAction
2683
+ ? prVisualRecapInstallCommand()
2684
+ : undefined;
3109
2685
  return {
3110
2686
  id: installTarget.id,
3111
2687
  displayName: installTarget.displayName,
@@ -3115,6 +2691,8 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3115
2691
  mcpClients: clients,
3116
2692
  dryRun: true,
3117
2693
  commands: [dryRunInstallCommand(parsed, target)],
2694
+ githubActionPath,
2695
+ githubActionSuggestedCommand,
3118
2696
  };
3119
2697
  }
3120
2698
  finally {
@@ -3182,14 +2760,32 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3182
2760
  }
3183
2761
  // `--with-github-action`: also drop the PR Visual Recap workflow into the
3184
2762
  // repo so PRs get automatic recaps. Only meaningful for the plan family.
2763
+ const baseDir = options.baseDir ?? process.cwd();
2764
+ let withGithubAction = Boolean(parsed.withGithubAction);
3185
2765
  let githubActionPath;
3186
2766
  let githubActionExisted;
3187
- if (parsed.withGithubAction) {
2767
+ let githubActionSuggestedCommand;
2768
+ if (knownTarget === "visual-plans" &&
2769
+ !withGithubAction &&
2770
+ !fs.existsSync(prVisualRecapWorkflowPath(baseDir))) {
2771
+ if (shouldPrompt(parsed, options)) {
2772
+ const prompt = options.promptGithubAction ?? promptForGithubAction;
2773
+ withGithubAction =
2774
+ (await prompt({
2775
+ workflowPath: prVisualRecapWorkflowDisplayPath(),
2776
+ setupCommand: prVisualRecapSetupCommand(),
2777
+ })) === true;
2778
+ }
2779
+ if (!withGithubAction) {
2780
+ githubActionSuggestedCommand = prVisualRecapInstallCommand();
2781
+ }
2782
+ }
2783
+ if (withGithubAction) {
3188
2784
  if (knownTarget !== "visual-plans") {
3189
2785
  options.log?.("--with-github-action only applies to the visual-plan skill; skipping the workflow.");
3190
2786
  }
3191
2787
  else {
3192
- const written = writePrVisualRecapWorkflow(options.baseDir ?? process.cwd());
2788
+ const written = writePrVisualRecapWorkflow(baseDir);
3193
2789
  githubActionPath = written.path;
3194
2790
  githubActionExisted = written.existed;
3195
2791
  commands.push(`write ${written.path}`);
@@ -3209,6 +2805,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
3209
2805
  connectCommand,
3210
2806
  githubActionPath,
3211
2807
  githubActionExisted,
2808
+ githubActionSuggestedCommand,
3212
2809
  };
3213
2810
  }
3214
2811
  finally {
@@ -3226,6 +2823,68 @@ function listSkills() {
3226
2823
  local: isLocalOnlyBuiltInSkill(entry),
3227
2824
  }));
3228
2825
  }
2826
+ function skillStateJson(state) {
2827
+ return {
2828
+ appSkillId: state.appSkillId,
2829
+ displayName: state.displayName,
2830
+ skillName: state.skillName,
2831
+ path: state.path,
2832
+ scope: state.scope,
2833
+ client: state.client,
2834
+ status: state.current ? "current" : "stale",
2835
+ managed: state.managed,
2836
+ installedHash: state.installedHash,
2837
+ latestHash: state.latestHash,
2838
+ metadataHash: state.metadataHash,
2839
+ };
2840
+ }
2841
+ function formatSkillState(state) {
2842
+ const status = state.current ? "current" : "stale";
2843
+ const managed = state.managed ? "managed" : "unmarked";
2844
+ const hashes = state.installedHash && !state.current
2845
+ ? ` (${state.installedHash} -> ${state.latestHash})`
2846
+ : "";
2847
+ return `${state.skillName.padEnd(22)} ${status.padEnd(7)} ${state.scope}/${state.client} ${managed}${hashes}\n ${state.path}`;
2848
+ }
2849
+ function runSkillsStatusOrUpdate(parsed, options, update) {
2850
+ const before = collectSkillInstallStates(parsed, options);
2851
+ const changed = update ? updateSkillInstallStates(before, parsed.dryRun) : [];
2852
+ const after = update && !parsed.dryRun
2853
+ ? collectSkillInstallStates(parsed, options)
2854
+ : before;
2855
+ if (parsed.printJson) {
2856
+ const outputStates = update && !parsed.dryRun ? after : before;
2857
+ process.stdout.write(`${JSON.stringify({
2858
+ ok: true,
2859
+ command: parsed.command,
2860
+ dryRun: parsed.dryRun,
2861
+ found: before.length,
2862
+ stale: outputStates.filter((state) => !state.current).length,
2863
+ updated: changed.length,
2864
+ skills: outputStates.map(skillStateJson),
2865
+ }, null, 2)}\n`);
2866
+ return;
2867
+ }
2868
+ if (before.length === 0) {
2869
+ const target = parsed.target ? ` for ${parsed.target}` : "";
2870
+ process.stdout.write(`No installed Agent Native skill copies found${target}.\nRun "agent-native skills add ${parsed.target ?? "visual-plan"}" to install one.\n`);
2871
+ return;
2872
+ }
2873
+ if (update) {
2874
+ if (parsed.dryRun) {
2875
+ process.stdout.write(changed.length
2876
+ ? `Would update ${changed.length} skill folder${changed.length === 1 ? "" : "s"}:\n`
2877
+ : "All discovered skill folders are already current.\n");
2878
+ }
2879
+ else {
2880
+ process.stdout.write(changed.length
2881
+ ? `Updated ${changed.length} skill folder${changed.length === 1 ? "" : "s"}.\n`
2882
+ : "All discovered skill folders are already current.\n");
2883
+ }
2884
+ }
2885
+ const rows = (update && parsed.dryRun ? before : after).map(formatSkillState);
2886
+ process.stdout.write(`${rows.join("\n")}\n`);
2887
+ }
3229
2888
  export async function runSkills(argv, options = {}) {
3230
2889
  const parsed = parseSkillsArgs(argv);
3231
2890
  const log = parsed.printJson
@@ -3251,6 +2910,10 @@ export async function runSkills(argv, options = {}) {
3251
2910
  }
3252
2911
  return;
3253
2912
  }
2913
+ if (parsed.command === "status" || parsed.command === "update") {
2914
+ runSkillsStatusOrUpdate(parsed, options, parsed.command === "update");
2915
+ return;
2916
+ }
3254
2917
  const targets = await resolveSkillTargets(parsed, options);
3255
2918
  if (!targets)
3256
2919
  return;
@@ -3309,7 +2972,15 @@ export async function runSkills(argv, options = {}) {
3309
2972
  .filter((p) => Boolean(p))),
3310
2973
  ];
3311
2974
  const githubActionLine = githubActions.length
3312
- ? `PR Visual Recap workflow: wrote ${githubActions.join(", ")}.\nSet these GitHub repo secrets/variables for it to run:\n ${PR_VISUAL_RECAP_SETUP.join("\n ")}`
2975
+ ? `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 ")}`
2976
+ : "";
2977
+ const githubActionSuggestions = [
2978
+ ...new Set(results
2979
+ .map((result) => result.githubActionSuggestedCommand)
2980
+ .filter((command) => Boolean(command))),
2981
+ ];
2982
+ const githubActionSuggestionLine = githubActionSuggestions.length
2983
+ ? `Optional PR Visual Recap workflow: run ${githubActionSuggestions.join(" && ")} to add automatic recap comments on pull requests.`
3313
2984
  : "";
3314
2985
  process.stdout.write([
3315
2986
  `Installed ${installedNames} skill${results.length === 1 ? "" : "s"}.`,
@@ -3324,6 +2995,7 @@ export async function runSkills(argv, options = {}) {
3324
2995
  : "",
3325
2996
  authLine,
3326
2997
  githubActionLine,
2998
+ githubActionSuggestionLine,
3327
2999
  localCommands.length ? `Local command: ${localCommands.join(", ")}.` : "",
3328
3000
  "Restart or reload selected agent clients if the skill is not visible yet.",
3329
3001
  parsed.clientExplicit