@agent-native/core 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/action.d.ts +8 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +20 -10
- package/dist/action.js.map +1 -1
- package/dist/cli/app-skill.d.ts +3 -1
- package/dist/cli/app-skill.d.ts.map +1 -1
- package/dist/cli/app-skill.js +50 -8
- package/dist/cli/app-skill.js.map +1 -1
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +39 -5
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +9 -7
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +42 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts +10 -0
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +60 -6
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +4 -6
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +15 -2
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/plan-publish-store.d.ts +17 -7
- package/dist/cli/plan-publish-store.d.ts.map +1 -1
- package/dist/cli/plan-publish-store.js +33 -8
- package/dist/cli/plan-publish-store.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.js +1 -1
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
- package/dist/cli/recap.d.ts +63 -5
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +641 -48
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +26 -11
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +644 -972
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +3 -2
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +37 -9
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
- package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
- package/dist/client/blocks/library/DiffBlock.js +44 -12
- package/dist/client/blocks/library/DiffBlock.js.map +1 -1
- package/dist/client/blocks/library/annotation-rail.d.ts +12 -3
- package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
- package/dist/client/blocks/library/annotation-rail.js +29 -3
- package/dist/client/blocks/library/annotation-rail.js.map +1 -1
- package/dist/client/blocks/library/html.d.ts.map +1 -1
- package/dist/client/blocks/library/html.js +3 -1
- package/dist/client/blocks/library/html.js.map +1 -1
- package/dist/client/blocks/library/question-form.d.ts.map +1 -1
- package/dist/client/blocks/library/question-form.js +4 -1
- package/dist/client/blocks/library/question-form.js.map +1 -1
- package/dist/client/components/LiveCursorOverlay.d.ts +46 -0
- package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -0
- package/dist/client/components/LiveCursorOverlay.js +137 -0
- package/dist/client/components/LiveCursorOverlay.js.map +1 -0
- package/dist/client/components/PresenceBar.d.ts +11 -1
- package/dist/client/components/PresenceBar.d.ts.map +1 -1
- package/dist/client/components/PresenceBar.js +39 -7
- package/dist/client/components/PresenceBar.js.map +1 -1
- package/dist/client/components/RemoteSelectionRings.d.ts +43 -0
- package/dist/client/components/RemoteSelectionRings.d.ts.map +1 -0
- package/dist/client/components/RemoteSelectionRings.js +116 -0
- package/dist/client/components/RemoteSelectionRings.js.map +1 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -1
- package/dist/collab/awareness.d.ts +25 -0
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +42 -5
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client.d.ts +19 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +362 -57
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/follow-mode.d.ts +56 -0
- package/dist/collab/follow-mode.d.ts.map +1 -0
- package/dist/collab/follow-mode.js +54 -0
- package/dist/collab/follow-mode.js.map +1 -0
- package/dist/collab/index.d.ts +3 -1
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +5 -1
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/presence.d.ts +56 -0
- package/dist/collab/presence.d.ts.map +1 -0
- package/dist/collab/presence.js +98 -0
- package/dist/collab/presence.js.map +1 -0
- package/dist/collab/routes.d.ts.map +1 -1
- package/dist/collab/routes.js +33 -6
- package/dist/collab/routes.js.map +1 -1
- package/dist/collab/struct-routes.d.ts.map +1 -1
- package/dist/collab/struct-routes.js +24 -4
- package/dist/collab/struct-routes.js.map +1 -1
- package/dist/collab/ydoc-manager.d.ts +13 -0
- package/dist/collab/ydoc-manager.d.ts.map +1 -1
- package/dist/collab/ydoc-manager.js +51 -15
- package/dist/collab/ydoc-manager.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +2 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/extensions/routes.d.ts +18 -0
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +30 -8
- package/dist/extensions/routes.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +42 -5
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/scripts/db/index.d.ts.map +1 -1
- package/dist/scripts/db/index.js +1 -0
- package/dist/scripts/db/index.js.map +1 -1
- package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts +28 -0
- package/dist/scripts/db/migrate-encrypt-oauth-tokens.d.ts.map +1 -0
- package/dist/scripts/db/migrate-encrypt-oauth-tokens.js +164 -0
- package/dist/scripts/db/migrate-encrypt-oauth-tokens.js.map +1 -0
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +7 -5
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/secrets/index.d.ts +1 -0
- package/dist/secrets/index.d.ts.map +1 -1
- package/dist/secrets/index.js +4 -0
- package/dist/secrets/index.js.map +1 -1
- package/dist/server/collab-plugin.d.ts +6 -0
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +105 -5
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/poll-events.d.ts +5 -0
- package/dist/server/poll-events.d.ts.map +1 -1
- package/dist/server/poll-events.js +27 -4
- package/dist/server/poll-events.js.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +4 -1
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +185 -37
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +12 -2
- package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +185 -37
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +12 -2
- package/docs/content/plan-plugin.md +21 -6
- package/docs/content/pr-visual-recap.md +52 -3
- package/docs/content/real-time-collaboration.md +481 -97
- package/docs/content/skills-guide.md +13 -0
- package/docs/content/template-plan.md +18 -7
- package/package.json +5 -1
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +185 -37
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +12 -2
- package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +185 -37
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +12 -2
package/dist/cli/skills.js
CHANGED
|
@@ -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
|
|
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\`
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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,
|
|
253
|
-
// CANVAS_SURFACE_CORE — visual-plan
|
|
254
|
-
// DOCUMENT_QUALITY_CORE — visual-plan
|
|
255
|
-
// EXEMPLAR_CORE — visual-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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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
|
|
758
|
-
when the work is primarily product UI and review
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
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
|
|
943
|
-
|
|
944
|
-
|
|
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
|
|
1046
|
+
## Wireframe quality — read \`references/wireframe.md\`
|
|
952
1047
|
|
|
953
|
-
|
|
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
|
-
|
|
1050
|
+
## Canvas — read \`references/canvas.md\`
|
|
960
1051
|
|
|
961
|
-
${
|
|
1052
|
+
${CANVAS_REFERENCE_POINTER}
|
|
962
1053
|
|
|
963
|
-
## Document
|
|
1054
|
+
## Document quality — read \`references/document-quality.md\`
|
|
964
1055
|
|
|
965
|
-
|
|
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
|
-
|
|
1058
|
+
## Good vs. bad exemplar — read \`references/exemplar.md\`
|
|
970
1059
|
|
|
971
|
-
|
|
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
|
|
988
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
1171
|
-
|
|
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\`
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
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
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
not a
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
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
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
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
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
2008
|
-
the
|
|
2009
|
-
|
|
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\`
|
|
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.
|
|
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
|
|
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.
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
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
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
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
|
|
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" ||
|
|
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
|
|
2808
|
-
|
|
2809
|
-
|
|
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
|
-
|
|
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(
|
|
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(", ")}.\
|
|
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
|