@agent-native/core 0.44.4 → 0.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +2 -1
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +224 -10
- 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 +69 -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 +43 -0
- package/dist/cli/plan-local.d.ts.map +1 -0
- package/dist/cli/plan-local.js +490 -0
- package/dist/cli/plan-local.js.map +1 -0
- 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 +225 -3
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +1267 -27
- 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 +810 -1365
- 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 +41 -10
- 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 +54 -23
- package/dist/client/blocks/library/DiffBlock.js.map +1 -1
- package/dist/client/blocks/library/annotation-rail.d.ts +27 -8
- package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
- package/dist/client/blocks/library/annotation-rail.js +64 -27
- package/dist/client/blocks/library/annotation-rail.js.map +1 -1
- package/dist/client/blocks/library/code-filename-label.d.ts +8 -0
- package/dist/client/blocks/library/code-filename-label.d.ts.map +1 -0
- package/dist/client/blocks/library/code-filename-label.js +15 -0
- package/dist/client/blocks/library/code-filename-label.js.map +1 -0
- package/dist/client/blocks/library/code.d.ts.map +1 -1
- package/dist/client/blocks/library/code.js +3 -2
- package/dist/client/blocks/library/code.js.map +1 -1
- package/dist/client/blocks/library/diff.config.d.ts +1 -1
- package/dist/client/blocks/library/diff.config.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/narrow-container.d.ts +4 -4
- package/dist/client/blocks/library/narrow-container.d.ts.map +1 -1
- package/dist/client/blocks/library/narrow-container.js +10 -10
- package/dist/client/blocks/library/narrow-container.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/blocks/library/tabs.d.ts.map +1 -1
- package/dist/client/blocks/library/tabs.js +7 -2
- package/dist/client/blocks/library/tabs.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +4 -1
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
- package/dist/client/db-admin/TableEditor.js +3 -1
- package/dist/client/db-admin/TableEditor.js.map +1 -1
- package/dist/db/client.d.ts +8 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +23 -2
- package/dist/db/client.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/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +8 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/extensions/html-shell.js +1 -1
- package/dist/extensions/html-shell.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/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +5 -1
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/mcp/build-server.d.ts +1 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +7 -3
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +56 -19
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/mcp/oauth-store.d.ts +1 -0
- package/dist/mcp/oauth-store.d.ts.map +1 -1
- package/dist/mcp/oauth-store.js +9 -0
- package/dist/mcp/oauth-store.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +9 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp-client/errors.js +3 -3
- package/dist/mcp-client/errors.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/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +3 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +10 -2
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +7 -3
- package/dist/server/auth.js.map +1 -1
- package/dist/server/recap-image-route.d.ts.map +1 -1
- package/dist/server/recap-image-route.js +3 -6
- package/dist/server/recap-image-route.js.map +1 -1
- package/dist/server/sentry.d.ts.map +1 -1
- package/dist/server/sentry.js +12 -5
- package/dist/server/sentry.js.map +1 -1
- package/dist/server/social-og-image.d.ts.map +1 -1
- package/dist/server/social-og-image.js +3 -1
- package/dist/server/social-og-image.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/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
- package/docs/content/plan-plugin.md +39 -7
- package/docs/content/pr-visual-recap.md +89 -13
- package/docs/content/skills-guide.md +13 -0
- package/docs/content/template-plan.md +62 -7
- package/package.json +5 -1
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
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
|
|
|
@@ -814,6 +909,37 @@ plan needs a richer review surface.
|
|
|
814
909
|
update the plan with \`update-visual-plan\` rather than only changing course in
|
|
815
910
|
chat, and re-read the approved plan before major steps.
|
|
816
911
|
|
|
912
|
+
## Local-Files Privacy Mode
|
|
913
|
+
|
|
914
|
+
Use local-files privacy mode when the user explicitly asks for no DB writes,
|
|
915
|
+
no hosted Plan app, no Plan MCP publish, fully local files, offline/private
|
|
916
|
+
planning, or when \`AGENT_NATIVE_PLANS_MODE=local-files\` is set. In this mode the
|
|
917
|
+
plan data must never be sent to the Plan MCP server or Plan app action surface.
|
|
918
|
+
|
|
919
|
+
The local-files contract is:
|
|
920
|
+
|
|
921
|
+
- Read source context from local files and shell commands only.
|
|
922
|
+
- Write the plan as a local MDX folder under \`plans/<slug>/\`: \`plan.mdx\`,
|
|
923
|
+
optional \`canvas.mdx\`, optional \`prototype.mdx\`, and optional
|
|
924
|
+
\`.plan-state.json\`.
|
|
925
|
+
- Run \`agent-native plan local preview --dir plans/<slug> --kind plan\` after
|
|
926
|
+
writing or updating the folder. Report the returned local URL or the
|
|
927
|
+
\`/local-plans/<slug>\` route if the local Plan app is running with the same
|
|
928
|
+
\`PLAN_LOCAL_DIR\`.
|
|
929
|
+
- Do **not** call \`create-visual-plan\`, \`create-ui-plan\`,
|
|
930
|
+
\`create-prototype-plan\`, \`create-plan-design\`, \`import-visual-plan-source\`,
|
|
931
|
+
\`update-visual-plan\`, \`patch-visual-plan-source\`, \`get-plan-feedback\`,
|
|
932
|
+
\`export-visual-plan\`, or any hosted Plan tool for that plan.
|
|
933
|
+
- Treat feedback as file or chat feedback: update the MDX files directly, rerun
|
|
934
|
+
the local preview command, and summarize the new local URL/path. Hosted
|
|
935
|
+
comments, sharing, history, and publish/export receipts are unavailable until
|
|
936
|
+
the user explicitly opts into publishing.
|
|
937
|
+
|
|
938
|
+
Local-files mode prevents plan content from going to the Agent-Native Plan
|
|
939
|
+
database. It does not by itself make the coding agent's language model local;
|
|
940
|
+
for that stronger privacy boundary, the host agent/model must also be local or
|
|
941
|
+
otherwise approved by the user.
|
|
942
|
+
|
|
817
943
|
## Core Workflow
|
|
818
944
|
|
|
819
945
|
1. Follow the host agent's normal planning flow: inspect the codebase, delegate
|
|
@@ -908,38 +1034,30 @@ not add visual chrome by default:
|
|
|
908
1034
|
needs to operate the behavior. Keep the static wireframes in
|
|
909
1035
|
\`content.canvas\`, add the aligned functional prototype in
|
|
910
1036
|
\`content.prototype\`, and rely on the top visual tabs to switch between them.
|
|
911
|
-
- **Prototype-first** when the user
|
|
912
|
-
|
|
913
|
-
|
|
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.
|
|
914
1040
|
|
|
915
1041
|
For mixed canvas + prototype plans, reuse the same real labels, app statuses,
|
|
916
1042
|
and screen ids across both surfaces. The canvas is the inspectable static reference;
|
|
917
1043
|
the prototype is the interactive version of that same flow, not a separate
|
|
918
1044
|
design direction.
|
|
919
1045
|
|
|
920
|
-
## Wireframe
|
|
1046
|
+
## Wireframe quality — read \`references/wireframe.md\`
|
|
921
1047
|
|
|
922
|
-
|
|
923
|
-
source of truth for how wireframes and the canvas work. The wireframe-quality
|
|
924
|
-
rules below are additionally shared, word for word, with \`/visual-recap\`; the
|
|
925
|
-
canvas/artboard mechanics apply only to \`/visual-plan\` and \`/ui-plan\`. Do not
|
|
926
|
-
paraphrase any of it per command.
|
|
1048
|
+
${WIREFRAME_REFERENCE_POINTER}
|
|
927
1049
|
|
|
928
|
-
|
|
1050
|
+
## Canvas — read \`references/canvas.md\`
|
|
929
1051
|
|
|
930
|
-
${
|
|
1052
|
+
${CANVAS_REFERENCE_POINTER}
|
|
931
1053
|
|
|
932
|
-
## Document
|
|
1054
|
+
## Document quality — read \`references/document-quality.md\`
|
|
933
1055
|
|
|
934
|
-
|
|
935
|
-
the single source of truth for the document below the canvas. Do not paraphrase
|
|
936
|
-
it per command.
|
|
1056
|
+
${DOCUMENT_QUALITY_REFERENCE_POINTER}
|
|
937
1057
|
|
|
938
|
-
|
|
1058
|
+
## Good vs. bad exemplar — read \`references/exemplar.md\`
|
|
939
1059
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
${EXEMPLAR_CORE}
|
|
1060
|
+
${EXEMPLAR_REFERENCE_POINTER}
|
|
943
1061
|
|
|
944
1062
|
## Tool Guidance
|
|
945
1063
|
|
|
@@ -953,8 +1071,8 @@ ${EXEMPLAR_CORE}
|
|
|
953
1071
|
optional matching Prototype tab.
|
|
954
1072
|
- \`convert-visual-plan-to-prototype\`: convert an existing HTML wireframe canvas
|
|
955
1073
|
into a prototype plan.
|
|
956
|
-
- \`create-visual-questions\`: use only
|
|
957
|
-
|
|
1074
|
+
- \`create-visual-questions\`: use only when the user explicitly asks for a visual
|
|
1075
|
+
intake questionnaire, not as \`/visual-plan\` preflight.
|
|
958
1076
|
- \`update-visual-plan\`: revise content, status, or comments; prefer
|
|
959
1077
|
\`contentPatches\` over regenerating the whole plan.
|
|
960
1078
|
- \`read-visual-plan-source\`: read the normalized plan as \`plan.mdx\`,
|
|
@@ -967,177 +1085,22 @@ ${EXEMPLAR_CORE}
|
|
|
967
1085
|
- \`get-plan-feedback\`: read unconsumed human feedback. Use it frequently; it
|
|
968
1086
|
returns grouped threads, exact anchor details, expected resolver, and recent
|
|
969
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.
|
|
970
1091
|
- \`export-visual-plan\`: export HTML, Markdown fallback, structured JSON, and MDX
|
|
971
1092
|
files for repo check-in.
|
|
972
1093
|
|
|
973
1094
|
When the user critiques a plan's look or structure, fix the renderer or this
|
|
974
1095
|
skill — never hand-edit one stored plan. Turn feedback into better guidance.
|
|
975
1096
|
|
|
976
|
-
##
|
|
977
|
-
|
|
978
|
-
There are two ways into Plans.
|
|
979
|
-
|
|
980
|
-
**Coding agent (CLI).** Install once with the Agent-Native CLI. The command
|
|
981
|
-
installs the Plans skills, registers the hosted Plans MCP connector, and
|
|
982
|
-
authenticates it in the same step (a one-time browser sign-in at setup — this is
|
|
983
|
-
intended), so the first tool call does not hit an OAuth wall:
|
|
984
|
-
|
|
985
|
-
\`\`\`bash
|
|
986
|
-
agent-native skills add visual-plan
|
|
987
|
-
\`\`\`
|
|
988
|
-
|
|
989
|
-
After that, \`/visual-plan\` (and \`/visual-recap\`, \`/ui-plan\`,
|
|
990
|
-
\`/prototype-plan\`, \`/plan-design\`, \`/visual-questions\`) generate a plan and open
|
|
991
|
-
the editor. Pass \`--no-connect\` to
|
|
992
|
-
register the connector without authenticating, then run
|
|
993
|
-
\`agent-native connect https://plan.agent-native.com\` whenever you are ready.
|
|
994
|
-
|
|
995
|
-
**Browser (people you share with).** Open the Plans editor and create & edit
|
|
996
|
-
with no sign-up — you work as a guest. Sign in only when you want to save or
|
|
997
|
-
share; signing in claims the plans you made as a guest into your account.
|
|
998
|
-
|
|
999
|
-
Sharing and commenting require an account: public/shared plans are viewable by
|
|
1000
|
-
anyone with the link, but commenting on them needs an agent-native account.
|
|
1001
|
-
|
|
1002
|
-
For fully offline, no-account use, run the Plans app locally and sync plans to
|
|
1003
|
-
your repo as MDX. This local mode is a separate advanced path, not the default
|
|
1004
|
-
hosted flow.
|
|
1005
|
-
|
|
1006
|
-
If a Plans tool returns \`needs auth\`, \`Unauthorized\`, or \`Session terminated\`,
|
|
1007
|
-
do not keep retrying the tool. Authenticate the connector with
|
|
1008
|
-
\`agent-native connect https://plan.agent-native.com\` (OAuth-capable hosts can
|
|
1009
|
-
instead re-run /mcp and choose Authenticate), then continue once the connector
|
|
1010
|
-
is available.
|
|
1011
|
-
|
|
1012
|
-
Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
|
|
1013
|
-
not put shared secrets in skill files.
|
|
1014
|
-
`;
|
|
1015
|
-
export const UI_PLAN_SKILL_MD = `---
|
|
1016
|
-
name: ui-plan
|
|
1017
|
-
description: >-
|
|
1018
|
-
Use Agent-Native Plans for UI-first planning with an optional top pan/zoom
|
|
1019
|
-
wireframe canvas, a refined Notion-like document, rich tabs, diagrams,
|
|
1020
|
-
comments, drawing, and agent handoff.
|
|
1021
|
-
metadata:
|
|
1022
|
-
visibility: exported
|
|
1023
|
-
---
|
|
1024
|
-
|
|
1025
|
-
# UI Plan
|
|
1026
|
-
|
|
1027
|
-
Use \`/ui-plan\` when the task is primarily about product UI, user flows,
|
|
1028
|
-
interaction details, component layout, or visual direction. The reviewable UI
|
|
1029
|
-
comes first; implementation detail comes after the user has something concrete to
|
|
1030
|
-
react to.
|
|
1031
|
-
|
|
1032
|
-
\`/visual-plan\` remains the general command for architecture, backend, refactors,
|
|
1033
|
-
and mixed work. Use \`/prototype-plan\` when the UI review needs a functional live
|
|
1034
|
-
prototype instead of static screens. Use \`/plan-design\` when polish, brand, or
|
|
1035
|
-
visual fidelity are material to the decision. Use \`/visual-questions\` only when
|
|
1036
|
-
the user explicitly wants visual intake before planning. Use \`/visual-plan\` when
|
|
1037
|
-
a text plan already exists and should become the source material for the review.
|
|
1038
|
-
|
|
1039
|
-
## Plan Discipline
|
|
1040
|
-
|
|
1041
|
-
- **Gate hard.** Use a UI plan when the surface is new, ambiguous, spans several
|
|
1042
|
-
screens or states, or the direction needs agreement before coding. Skip it for
|
|
1043
|
-
cosmetic one-liners — a color, a label, a spacing tweak — and just make the
|
|
1044
|
-
change. Never ship a single-step or filler plan.
|
|
1045
|
-
- **Research before you draft.** Read the real components, routes, and design
|
|
1046
|
-
tokens first; ground every mockup and the file map in actual files and symbols.
|
|
1047
|
-
Delegate wide exploration to a sub-agent when the surface is large.
|
|
1048
|
-
- **Planning is read-only.** Make no source edits while building or reviewing.
|
|
1049
|
-
Start editing only after the user approves the UI direction.
|
|
1050
|
-
- **Clarify vs. assume.** Do not ask how to build the UI — present the direction
|
|
1051
|
-
and options as mockups and tabs. Ask a clarifying question only when an
|
|
1052
|
-
ambiguity would change the design; use the host agent's normal
|
|
1053
|
-
ask-user-question flow and batch 2-4 before finalizing. Do not call
|
|
1054
|
-
\`create-visual-questions\` from \`/ui-plan\`; keep answerable follow-up inside
|
|
1055
|
-
the same plan as a bottom \`question-form\` Open Questions block. Otherwise
|
|
1056
|
-
state the assumption in the plan and proceed.
|
|
1057
|
-
- **The plan is the approval gate.** Ask the user to review and approve the UI
|
|
1058
|
-
direction before you write code, and name the files/areas the work touches.
|
|
1059
|
-
|
|
1060
|
-
## UI-First Workflow
|
|
1061
|
-
|
|
1062
|
-
1. Follow the host agent's normal planning flow: inspect the codebase, gather
|
|
1063
|
-
the UI/component context needed, and ask native clarifying questions as needed
|
|
1064
|
-
before generating the plan.
|
|
1065
|
-
2. Call \`create-ui-plan\` with a UI-specific title, brief, source, repo path, and
|
|
1066
|
-
structured \`content\`. The canvas comes first, the document second.
|
|
1067
|
-
3. Compose the top canvas from the kit (see the cores below): the key artboards
|
|
1068
|
-
with real product content, designer notes, and connectors only for real
|
|
1069
|
-
sequences. Skip the canvas when wireframes would not clarify the work.
|
|
1070
|
-
4. Continue below as a concise technical document that stays close to the
|
|
1071
|
-
Markdown plan the agent would normally output — not a second copy of the
|
|
1072
|
-
canvas — covering concrete files, contracts, phases, risks, and validation.
|
|
1073
|
-
5. Call \`get-plan-feedback\` before implementation, after review, after a long
|
|
1074
|
-
pause, and before the final response. Treat \`anchorDetails\`, resolver intent,
|
|
1075
|
-
recent review events, and any focused screenshots from browser handoff as the
|
|
1076
|
-
source of truth for exactly what changed and exactly what each UI comment
|
|
1077
|
-
points at. Apply changes with \`update-visual-plan\`, preferring
|
|
1078
|
-
\`contentPatches\` for one frame, annotation, node, tab, or block. When the
|
|
1079
|
-
user wants source-control friendly edits, use \`patch-visual-plan-source\`
|
|
1080
|
-
against the MDX files instead of regenerating the plan.
|
|
1081
|
-
|
|
1082
|
-
## Agent Handoff
|
|
1083
|
-
|
|
1084
|
-
After the canvas and document, add a short handoff that names the chosen UI
|
|
1085
|
-
direction, unresolved visual questions, and feedback that must be read before
|
|
1086
|
-
code changes. Never claim feedback has been applied until \`get-plan-feedback\` or
|
|
1087
|
-
the user has supplied it.
|
|
1088
|
-
|
|
1089
|
-
## Wireframe & Canvas Core
|
|
1090
|
-
|
|
1091
|
-
This section is shared by \`/visual-plan\` and \`/ui-plan\`, and is the single
|
|
1092
|
-
source of truth for how wireframes and the canvas work. The wireframe-quality
|
|
1093
|
-
rules below are additionally shared, word for word, with \`/visual-recap\`; the
|
|
1094
|
-
canvas/artboard mechanics apply only to \`/visual-plan\` and \`/ui-plan\`. Do not
|
|
1095
|
-
paraphrase any of it per command.
|
|
1096
|
-
|
|
1097
|
-
${WIREFRAME_QUALITY_CORE}
|
|
1098
|
-
|
|
1099
|
-
${CANVAS_SURFACE_CORE}
|
|
1100
|
-
|
|
1101
|
-
## Document Quality Core
|
|
1102
|
-
|
|
1103
|
-
This section is shared, word for word, by \`/visual-plan\` and \`/ui-plan\`. It is
|
|
1104
|
-
the single source of truth for the document below the canvas. Do not paraphrase
|
|
1105
|
-
it per command.
|
|
1106
|
-
|
|
1107
|
-
${DOCUMENT_QUALITY_CORE}
|
|
1108
|
-
|
|
1109
|
-
## Good vs. Bad Exemplar
|
|
1110
|
-
|
|
1111
|
-
${EXEMPLAR_CORE}
|
|
1112
|
-
|
|
1113
|
-
## Tool Guidance
|
|
1114
|
-
|
|
1115
|
-
- \`create-ui-plan\`: create the UI-first structured visual plan.
|
|
1116
|
-
- \`create-prototype-plan\`: create a prototype-first plan when UI review needs a
|
|
1117
|
-
functional live prototype.
|
|
1118
|
-
- \`create-plan-design\`: create a full-fidelity branded design plan when polish,
|
|
1119
|
-
brand, and detailed visual direction are primary review inputs.
|
|
1120
|
-
- \`convert-visual-plan-to-prototype\`: convert an existing HTML wireframe canvas
|
|
1121
|
-
into a prototype plan.
|
|
1122
|
-
- \`create-visual-questions\`: use only for the explicit \`/visual-questions\`
|
|
1123
|
-
command, not as \`/ui-plan\` preflight.
|
|
1124
|
-
- \`update-visual-plan\`: revise content, mockups, comments, or handoff notes;
|
|
1125
|
-
prefer targeted \`contentPatches\`.
|
|
1126
|
-
- \`read-visual-plan-source\`: read the normalized plan as \`plan.mdx\`,
|
|
1127
|
-
optional \`canvas.mdx\`, optional \`.plan-state.json\`, and JSON.
|
|
1128
|
-
- \`patch-visual-plan-source\`: apply granular MDX AST patches by stable block,
|
|
1129
|
-
artboard, annotation, component, or wireframe-node id.
|
|
1130
|
-
- \`import-visual-plan-source\`: create or replace a plan from an MDX folder.
|
|
1131
|
-
- \`get-visual-plan\`: inspect the current structured plan, exported HTML, and
|
|
1132
|
-
annotations; it also returns the MDX folder for source workflows.
|
|
1133
|
-
- \`get-plan-feedback\`: read unconsumed reviewer comments before coding; it
|
|
1134
|
-
returns grouped threads, exact anchor details, expected resolver, and recent
|
|
1135
|
-
review-event payloads so agents can act only on the comments meant for them.
|
|
1136
|
-
- \`export-visual-plan\`: export HTML, Markdown fallback, structured JSON, and MDX
|
|
1137
|
-
files for repo check-in.
|
|
1097
|
+
## Visibility & Sharing
|
|
1138
1098
|
|
|
1139
|
-
|
|
1140
|
-
|
|
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.
|
|
1141
1104
|
|
|
1142
1105
|
## Setup & Authentication
|
|
1143
1106
|
|
|
@@ -1152,10 +1115,12 @@ intended), so the first tool call does not hit an OAuth wall:
|
|
|
1152
1115
|
agent-native skills add visual-plan
|
|
1153
1116
|
\`\`\`
|
|
1154
1117
|
|
|
1155
|
-
After that, \`/visual-plan\`
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
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
|
|
1159
1124
|
\`agent-native connect https://plan.agent-native.com\` whenever you are ready.
|
|
1160
1125
|
|
|
1161
1126
|
**Browser (people you share with).** Open the Plans editor and create & edit
|
|
@@ -1178,273 +1143,6 @@ is available.
|
|
|
1178
1143
|
Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
|
|
1179
1144
|
not put shared secrets in skill files.
|
|
1180
1145
|
`;
|
|
1181
|
-
export const PROTOTYPE_PLAN_SKILL_MD = `---
|
|
1182
|
-
name: prototype-plan
|
|
1183
|
-
description: >-
|
|
1184
|
-
Use Agent-Native Plans for /prototype-plan when work needs a functional
|
|
1185
|
-
prototype-first plan, static mocks, comments, review toggles, or conversion
|
|
1186
|
-
from a visual plan.
|
|
1187
|
-
metadata:
|
|
1188
|
-
visibility: exported
|
|
1189
|
-
---
|
|
1190
|
-
|
|
1191
|
-
# Prototype Plan
|
|
1192
|
-
|
|
1193
|
-
\`/prototype-plan\` creates a plan whose primary review surface is a live,
|
|
1194
|
-
functional prototype above the document. Use it when the user needs to feel a
|
|
1195
|
-
flow, operate basic UI state, or comment on interaction before implementation
|
|
1196
|
-
hardens the decision.
|
|
1197
|
-
|
|
1198
|
-
## Rule
|
|
1199
|
-
|
|
1200
|
-
Make the prototype answer a concrete question. The plan should say what is being
|
|
1201
|
-
tested, show the functional prototype first, then keep static mocks and implementation
|
|
1202
|
-
notes in the document below.
|
|
1203
|
-
|
|
1204
|
-
## When To Use
|
|
1205
|
-
|
|
1206
|
-
Use \`/prototype-plan\` when the user asks for a prototype, wants to click through
|
|
1207
|
-
and operate UI states, needs design review before code, wants comments pinned to
|
|
1208
|
-
live screens, or asks to move a visual plan into a prototype.
|
|
1209
|
-
|
|
1210
|
-
Prefer \`/visual-plan\` for architecture, data flow, or non-interactive planning.
|
|
1211
|
-
Prefer \`/ui-plan\` when static screen review is enough. Use \`/visual-plan\` first
|
|
1212
|
-
when the user hands you an existing Markdown/Codex/Claude plan that needs a
|
|
1213
|
-
visual companion before becoming interactive.
|
|
1214
|
-
|
|
1215
|
-
## Core Workflow
|
|
1216
|
-
|
|
1217
|
-
1. Inspect the real codebase and decide the question the prototype should
|
|
1218
|
-
answer. Good examples: "Does this onboarding flow feel short enough?" or
|
|
1219
|
-
"Which dashboard density should we implement?"
|
|
1220
|
-
2. Call \`create-prototype-plan\` with a title, brief, and screen HTML. Default to
|
|
1221
|
-
one functional prototype screen when local UI behavior is enough; use 2-4
|
|
1222
|
-
screens only for true routes, steps, or materially different contexts. The
|
|
1223
|
-
returned plan opens with the prototype viewer on top and static mocks, flow
|
|
1224
|
-
diagram, implementation map, and verification below.
|
|
1225
|
-
3. Make controls actually work. Use the renderer's safe Alpine-like directives:
|
|
1226
|
-
\`x-data\`, \`x-model\`, \`x-for\`, \`x-text\`, \`x-show\`, \`:class\`, \`@click\`, and
|
|
1227
|
-
\`@keydown.enter\`. Use safe helper verbs such as \`remove(list, item)\`,
|
|
1228
|
-
\`setAll(list, 'done', true)\`, \`removeWhere(list, 'done', true)\`, and counters
|
|
1229
|
-
such as \`count(list)\`, \`countWhere(list, 'done', true)\`, and
|
|
1230
|
-
\`remaining(list, 'done')\` when they help. Use \`data-goto="screen-id"\` only
|
|
1231
|
-
for true screen/route changes, not for every button press.
|
|
1232
|
-
4. Show important app feedback inside the prototype itself: selected filters,
|
|
1233
|
-
checked rows, typed drafts, validation messages, permissions, progress, or
|
|
1234
|
-
empty states.
|
|
1235
|
-
5. Surface the returned Plans link and ask the user to click through, comment on
|
|
1236
|
-
the prototype or static mocks, and approve the direction before code changes.
|
|
1237
|
-
6. Before implementing or revising, call \`get-plan-feedback\`. Treat prototype
|
|
1238
|
-
anchors, screenshots, and resolver intent as the source of truth.
|
|
1239
|
-
7. Update with \`update-visual-plan\` content patches. Use
|
|
1240
|
-
\`patch-prototype-html\`, \`update-prototype-screen\`, or \`set-prototype\` for
|
|
1241
|
-
targeted prototype edits instead of regenerating the whole plan.
|
|
1242
|
-
|
|
1243
|
-
## Converting A Visual Plan
|
|
1244
|
-
|
|
1245
|
-
When a visual plan already has HTML canvas wireframes, call
|
|
1246
|
-
\`convert-visual-plan-to-prototype\` with the plan id. This derives prototype
|
|
1247
|
-
screens from the canvas frames, preserves the canvas/static mocks by default,
|
|
1248
|
-
and changes the top review surface to the prototype viewer.
|
|
1249
|
-
|
|
1250
|
-
Use \`removeCanvas: true\` only when the user explicitly wants the old canvas
|
|
1251
|
-
gone. Otherwise keep static mocks available for source export and detailed
|
|
1252
|
-
review.
|
|
1253
|
-
|
|
1254
|
-
## Prototype Screen HTML
|
|
1255
|
-
|
|
1256
|
-
Write bounded semantic HTML fragments only:
|
|
1257
|
-
|
|
1258
|
-
\`\`\`html
|
|
1259
|
-
<div style="display:flex;flex-direction:column;gap:14px;padding:18px;height:100%">
|
|
1260
|
-
<header style="display:flex;justify-content:space-between;gap:12px">
|
|
1261
|
-
<div>
|
|
1262
|
-
<h1>Launch checklist</h1>
|
|
1263
|
-
<p class="wf-muted">Reviewer can add, complete, filter, and remove tasks.</p>
|
|
1264
|
-
</div>
|
|
1265
|
-
<span class="wf-pill accent">Live prototype</span>
|
|
1266
|
-
</header>
|
|
1267
|
-
<section
|
|
1268
|
-
class="wf-card"
|
|
1269
|
-
x-data="{ draft: '', filter: 'all', todos: [{ text: 'Check copy', done: false }, { text: 'Confirm owner', done: true }] }"
|
|
1270
|
-
style="display:flex;flex-direction:column;gap:10px"
|
|
1271
|
-
>
|
|
1272
|
-
<div style="display:flex;gap:8px">
|
|
1273
|
-
<input x-model="draft" @keydown.enter="draft && todos.push({ text: draft, done: false }); draft = ''" placeholder="Add task" />
|
|
1274
|
-
<button class="primary" @click="draft && todos.push({ text: draft, done: false }); draft = ''">Add</button>
|
|
1275
|
-
</div>
|
|
1276
|
-
<div style="display:flex;gap:8px">
|
|
1277
|
-
<button @click="filter = 'all'" :class="{ primary: filter === 'all' }">All</button>
|
|
1278
|
-
<button @click="filter = 'done'" :class="{ primary: filter === 'done' }">Done</button>
|
|
1279
|
-
<button @click="setAll(todos, 'done', true)">Mark all done</button>
|
|
1280
|
-
</div>
|
|
1281
|
-
<p class="wf-muted"><span x-text="remaining(todos, 'done')"></span> open / <span x-text="count(todos)"></span> total</p>
|
|
1282
|
-
<div
|
|
1283
|
-
class="wf-box"
|
|
1284
|
-
x-for="todo in todos"
|
|
1285
|
-
x-show="filter === 'all' || (filter === 'done' && todo.done)"
|
|
1286
|
-
:class="{ 'is-done': todo.done }"
|
|
1287
|
-
style="display:flex;justify-content:space-between;gap:10px"
|
|
1288
|
-
>
|
|
1289
|
-
<label style="display:flex;gap:8px"><input type="checkbox" x-model="todo.done" /><span x-text="todo.text"></span></label>
|
|
1290
|
-
<button @click="remove(todos, todo)">Remove</button>
|
|
1291
|
-
</div>
|
|
1292
|
-
<button @click="removeWhere(todos, 'done', true)">Clear completed</button>
|
|
1293
|
-
</section>
|
|
1294
|
-
</div>
|
|
1295
|
-
\`\`\`
|
|
1296
|
-
|
|
1297
|
-
Use real labels, counts, dates, and controls grounded in the target app. Keep
|
|
1298
|
-
surfaces honest: \`browser\` for web pages, \`desktop\` for app shells, \`mobile\`
|
|
1299
|
-
only for real mobile work, \`panel\` for side panels, and \`popover\` for menus.
|
|
1300
|
-
|
|
1301
|
-
Do not include \`<html>\`, \`<body>\`, \`<script>\`, \`<style>\`, browser \`on*\`
|
|
1302
|
-
handler attributes such as \`onclick\`, fake APIs, raw secrets, or customer data.
|
|
1303
|
-
The renderer owns sketchy/clean mode, theme, surface sizing, rough outlines, and
|
|
1304
|
-
comment overlays.
|
|
1305
|
-
|
|
1306
|
-
## Review Surface
|
|
1307
|
-
|
|
1308
|
-
Prototype plans support:
|
|
1309
|
-
|
|
1310
|
-
- real local controls through safe prototype directives
|
|
1311
|
-
- optional screen/route transitions from \`data-goto\`
|
|
1312
|
-
- rough vs clean mode through the shared wireframe toggle
|
|
1313
|
-
- dark vs light mode through the shared theme toggle
|
|
1314
|
-
- comment visibility from the prototype toolbar
|
|
1315
|
-
- Figma-style comments pinned directly on live prototype screens
|
|
1316
|
-
- a popout URL with \`?prototype=1\` for focused browser review
|
|
1317
|
-
- static wireframe mocks in the document body where they help implementation
|
|
1318
|
-
|
|
1319
|
-
## Source Files
|
|
1320
|
-
|
|
1321
|
-
Runtime JSON is canonical. Source export uses:
|
|
1322
|
-
|
|
1323
|
-
- \`plan.mdx\` for document blocks
|
|
1324
|
-
- \`prototype.mdx\` for \`<Prototype>\`, \`<PrototypeScreen>\`, and
|
|
1325
|
-
\`<PrototypeTransition>\`
|
|
1326
|
-
- \`canvas.mdx\` for static mocks when a canvas is present
|
|
1327
|
-
- \`.plan-state.json\` for persisted viewport state
|
|
1328
|
-
|
|
1329
|
-
Patch source with \`patch-visual-plan-source\` only when the user wants
|
|
1330
|
-
source-control friendly edits. Patch runtime content when the user is simply
|
|
1331
|
-
reviewing and iterating.
|
|
1332
|
-
|
|
1333
|
-
## Related Skills
|
|
1334
|
-
|
|
1335
|
-
- \`visual-plan\`
|
|
1336
|
-
- \`ui-plan\`
|
|
1337
|
-
- \`visual-questions\`
|
|
1338
|
-
`;
|
|
1339
|
-
export const PLAN_DESIGN_SKILL_MD = `---
|
|
1340
|
-
name: plan-design
|
|
1341
|
-
description: >-
|
|
1342
|
-
Use Agent-Native Plans for full-fidelity UI design planning with a Design
|
|
1343
|
-
canvas tab and optional interactive Prototype tab before implementation.
|
|
1344
|
-
metadata:
|
|
1345
|
-
visibility: exported
|
|
1346
|
-
---
|
|
1347
|
-
|
|
1348
|
-
# Plan Design
|
|
1349
|
-
|
|
1350
|
-
Use \`/plan-design\` when the user needs a high-fidelity product design before
|
|
1351
|
-
implementation: polished branded screens, realistic content, visual direction,
|
|
1352
|
-
and interaction review. It is the full-fidelity companion to \`/visual-plan\` and
|
|
1353
|
-
\`/prototype-plan\`: the top review surface should show \`Design\` and, when the
|
|
1354
|
-
flow needs interaction, \`Prototype\`.
|
|
1355
|
-
|
|
1356
|
-
## When To Use
|
|
1357
|
-
|
|
1358
|
-
Use this for UI-heavy work where brand, visual hierarchy, polished layout, or
|
|
1359
|
-
interaction feel are material to the decision. Skip it for small copy, spacing,
|
|
1360
|
-
or obvious component changes.
|
|
1361
|
-
|
|
1362
|
-
## Research First
|
|
1363
|
-
|
|
1364
|
-
Before creating the plan:
|
|
1365
|
-
|
|
1366
|
-
1. Inspect the real app shell, routes, components, CSS variables, Tailwind
|
|
1367
|
-
tokens, theme files, and any relevant screenshots.
|
|
1368
|
-
2. If \`design.md\` exists, treat it as the primary design brief and pass its
|
|
1369
|
-
important content into \`create-plan-design.designMd\`.
|
|
1370
|
-
3. If a \`.fig\` local-copy file or parsed brand kit is available, use the
|
|
1371
|
-
Design/brand-kit parsing actions from the app or shared tooling first, then
|
|
1372
|
-
pass the extracted token summary into \`brandKit\`.
|
|
1373
|
-
4. Parse existing codebase style info when possible: CSS custom properties,
|
|
1374
|
-
Tailwind config, global CSS, font declarations, spacing/radius tokens, and
|
|
1375
|
-
component conventions. Pass the compact evidence into \`codebaseStyles\`.
|
|
1376
|
-
5. Ground every screen in actual product content. Avoid lorem ipsum, generic
|
|
1377
|
-
marketing filler, and placeholder gray boxes unless designing an explicit
|
|
1378
|
-
loading state.
|
|
1379
|
-
|
|
1380
|
-
## Create The Plan
|
|
1381
|
-
|
|
1382
|
-
Call \`create-plan-design\` with:
|
|
1383
|
-
|
|
1384
|
-
- \`title\`, \`brief\`, \`repoPath\`, and any \`implementationNotes\`.
|
|
1385
|
-
- \`designMd\`, \`brandKit\`, \`codebaseStyles\`, or \`designNotes\` when available.
|
|
1386
|
-
- \`screens\`: one to six full-fidelity HTML/CSS screen fragments. Each screen
|
|
1387
|
-
must include a bounded \`html\` fragment, optional scoped \`css\`, a \`surface\`,
|
|
1388
|
-
and stable \`data-design-id\` attributes on elements a reviewer might edit.
|
|
1389
|
-
- \`transitions\` only when the Prototype tab should support true screen/step
|
|
1390
|
-
navigation. Use \`data-goto="screen-id"\` in the screen HTML for those controls.
|
|
1391
|
-
|
|
1392
|
-
The Design tab is the visual source of truth. The Prototype tab is for behavior
|
|
1393
|
-
and should reuse the same visual styling where practical. Do not create a
|
|
1394
|
-
separate design direction in the prototype.
|
|
1395
|
-
|
|
1396
|
-
## Full-Fidelity HTML Rules
|
|
1397
|
-
|
|
1398
|
-
- Write bounded fragments only: no \`<html>\`, \`<head>\`, \`<body>\`, \`<script>\`,
|
|
1399
|
-
\`<style>\`, external imports, iframes, SVG, or executable URLs.
|
|
1400
|
-
- Put CSS in the screen \`css\` field. The renderer scopes it to the artboard.
|
|
1401
|
-
- Use real CSS and CSS variables. Tailwind-like class names are fine only when
|
|
1402
|
-
the provided \`css\` defines them or the classes are harmless semantic hooks.
|
|
1403
|
-
- Use \`renderMode: "design"\` on design screen data when authoring full
|
|
1404
|
-
structured content directly.
|
|
1405
|
-
- Add \`data-design-id="meaningful-name"\` to editable elements such as hero
|
|
1406
|
-
panels, key buttons, cards, nav items, pricing rows, chart panels, and state
|
|
1407
|
-
chips. Keep ids stable and descriptive.
|
|
1408
|
-
- Keep the design responsive within the selected surface. Text must not clip,
|
|
1409
|
-
overlap, or rely on viewport-sized type.
|
|
1410
|
-
|
|
1411
|
-
## Targeted Style Edits
|
|
1412
|
-
|
|
1413
|
-
When a reviewer selects an element in the Design tab or asks for a specific
|
|
1414
|
-
style change, avoid regenerating the whole plan. Use:
|
|
1415
|
-
|
|
1416
|
-
\`\`\`json
|
|
1417
|
-
{
|
|
1418
|
-
"op": "update-design-element-style",
|
|
1419
|
-
"frameId": "frame-overview",
|
|
1420
|
-
"elementId": "primary-cta",
|
|
1421
|
-
"styles": {
|
|
1422
|
-
"background-color": "#0f766e",
|
|
1423
|
-
"border-radius": "10px"
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
\`\`\`
|
|
1427
|
-
|
|
1428
|
-
Use \`frameId\` for inline canvas designs or \`blockId\` for a referenced wireframe
|
|
1429
|
-
block. Set a style value to \`null\` to remove it. Use \`patch-wireframe-html\` or
|
|
1430
|
-
\`patch-prototype-html\` for text/content changes inside a fragment.
|
|
1431
|
-
|
|
1432
|
-
## Document Handoff
|
|
1433
|
-
|
|
1434
|
-
Below the visual surface, keep the document concise and implementation-oriented:
|
|
1435
|
-
actual files and symbols, state/actions/contracts, open questions, risks, and
|
|
1436
|
-
verification. The document should not repeat the same screens in prose.
|
|
1437
|
-
|
|
1438
|
-
Before implementation, call \`get-plan-feedback\` and treat comments, selected
|
|
1439
|
-
element details, and recent review events as the source of truth.
|
|
1440
|
-
|
|
1441
|
-
## Related Skills
|
|
1442
|
-
|
|
1443
|
-
- \`visual-plan\`
|
|
1444
|
-
- \`ui-plan\`
|
|
1445
|
-
- \`prototype-plan\`
|
|
1446
|
-
- \`frontend-design\`
|
|
1447
|
-
`;
|
|
1448
1146
|
export const VISUAL_RECAP_SKILL_MD = `---
|
|
1449
1147
|
name: visual-recap
|
|
1450
1148
|
description: >-
|
|
@@ -1466,25 +1164,64 @@ schema, API, file, and architecture changes become the same \`data-model\`,
|
|
|
1466
1164
|
now they summarize work that exists. A reviewer scans the shape of the change
|
|
1467
1165
|
before spending attention on the literal lines.
|
|
1468
1166
|
|
|
1167
|
+
## Local-Files Privacy Mode Exception
|
|
1168
|
+
|
|
1169
|
+
Use local-files privacy mode when the user explicitly asks for no DB writes,
|
|
1170
|
+
no hosted Plan app, no Plan MCP publish, fully local files, offline/private
|
|
1171
|
+
recaps, or when \`AGENT_NATIVE_PLANS_MODE=local-files\` is set. This is the only
|
|
1172
|
+
exception to the hosted publish rule below.
|
|
1173
|
+
|
|
1174
|
+
In local-files mode:
|
|
1175
|
+
|
|
1176
|
+
- Read the diff/stat/source context from local files and shell commands only.
|
|
1177
|
+
The existing \`agent-native recap collect-diff\`, \`scan\`, and
|
|
1178
|
+
\`build-prompt --local-files\` helpers are safe to use because they operate on
|
|
1179
|
+
local files and do not write to the Plan database.
|
|
1180
|
+
- Write the recap as a local MDX folder under \`plans/<slug>/\`: \`plan.mdx\`,
|
|
1181
|
+
optional \`canvas.mdx\`, optional \`prototype.mdx\`, and optional
|
|
1182
|
+
\`.plan-state.json\`. Set \`kind: "recap"\` and \`localOnly: true\` in
|
|
1183
|
+
frontmatter/state when authoring the source.
|
|
1184
|
+
- Run \`agent-native plan local preview --dir plans/<slug> --kind recap\` after
|
|
1185
|
+
writing or updating the folder. Report the returned local URL or the
|
|
1186
|
+
\`/local-plans/<slug>\` route if the local Plan app is running with the same
|
|
1187
|
+
\`PLAN_LOCAL_DIR\`.
|
|
1188
|
+
- Do **not** call \`create-visual-recap\`, \`create-visual-plan\`,
|
|
1189
|
+
\`import-visual-plan-source\`, \`update-visual-plan\`,
|
|
1190
|
+
\`patch-visual-plan-source\`, \`get-plan-feedback\`, \`export-visual-plan\`,
|
|
1191
|
+
\`set-resource-visibility\`, or any hosted Plan tool for that recap.
|
|
1192
|
+
- Treat review feedback as file or chat feedback: update the MDX files directly,
|
|
1193
|
+
rerun the local preview command, and summarize the new local URL/path.
|
|
1194
|
+
Hosted comments, sharing, screenshots, usage attachment, and PR sticky comment
|
|
1195
|
+
publishing are unavailable until the user explicitly opts into publishing.
|
|
1196
|
+
|
|
1197
|
+
Local-files mode prevents recap content from going to the Agent-Native Plan
|
|
1198
|
+
database. It does not by itself make the coding agent's language model local;
|
|
1199
|
+
for that stronger privacy boundary, the host agent/model must also be local or
|
|
1200
|
+
otherwise approved by the user.
|
|
1201
|
+
|
|
1469
1202
|
## Always Publish As An Agent-Native Plan — Never Inline
|
|
1470
1203
|
|
|
1471
1204
|
The deliverable is ALWAYS a published Agent-Native Plan, created with the
|
|
1472
|
-
\`create-visual-recap\` tool on the
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
not a
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
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.
|
|
1488
1225
|
|
|
1489
1226
|
## When To Use
|
|
1490
1227
|
|
|
@@ -1535,282 +1272,87 @@ them. Alongside the visual/structural headline (wireframes, \`data-model\`,
|
|
|
1535
1272
|
\`api-endpoint\`, \`diagram\`), a substantial recap also carries the implementation
|
|
1536
1273
|
evidence:
|
|
1537
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.
|
|
1538
1280
|
- A \`file-tree\` of the changed files with each entry's \`change\` flag, so the
|
|
1539
|
-
reviewer sees the footprint of the work at a glance.
|
|
1540
|
-
- The \`diff\` of the KEY changed files, grouped under a \`## Key changes\`
|
|
1541
|
-
\`rich-text\` heading in a single
|
|
1542
|
-
|
|
1543
|
-
reviewer can drop from the high-altitude shape
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
Skip the diff appendix only for a genuinely tiny change that reviews faster as
|
|
1548
|
-
plain diff (see "When To Use"); for any change worth recapping, the file-tree and
|
|
1549
|
-
key-change diffs belong in the plan.
|
|
1550
|
-
|
|
1551
|
-
## UI Impact Needs Wireframes
|
|
1552
|
-
|
|
1553
|
-
When the diff changes rendered UI, layout, density, visual state, interaction
|
|
1554
|
-
affordances, navigation, controls, menus, dialogs, or design tokens, the recap
|
|
1555
|
-
MUST include one or more wireframes. Prose and file diffs are not a substitute
|
|
1556
|
-
for showing what changed visually.
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
-
|
|
1566
|
-
state
|
|
1567
|
-
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
**A wireframe block's data is an HTML screen plus a surface:**
|
|
1600
|
-
|
|
1601
|
-
\`\`\`json
|
|
1602
|
-
{
|
|
1603
|
-
"surface": "browser",
|
|
1604
|
-
"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>"
|
|
1605
|
-
}
|
|
1606
|
-
\`\`\`
|
|
1607
|
-
|
|
1608
|
-
**Write PLAIN semantic HTML and let the renderer style it.** Bare elements
|
|
1609
|
-
(\`h1\`/\`h2\`/\`h3\`, \`p\`, \`button\`, \`input\`, \`<input type="checkbox">\`, \`a\`, \`hr\`)
|
|
1610
|
-
are auto-themed — no classes needed. Helper classes carry the rest:
|
|
1611
|
-
|
|
1612
|
-
- \`.wf-card\` / \`.wf-box\` — a bordered, padded container (a panel, a list item).
|
|
1613
|
-
- \`.wf-pill\` / \`.wf-chip\` — a rounded tag or filter; add \`.accent\`
|
|
1614
|
-
(\`<span class="wf-pill accent">\`) for the accent-filled variant.
|
|
1615
|
-
- \`.wf-muted\` — secondary/muted text (or use \`<small>\`).
|
|
1616
|
-
- \`button.primary\` or any element with \`[data-primary]\` — the accent-filled
|
|
1617
|
-
primary button.
|
|
1618
|
-
|
|
1619
|
-
**Use the \`--wf-*\` tokens for any custom color, never hex.** The renderer flips
|
|
1620
|
-
these on light/dark, so reading them is what keeps a mockup correct in both
|
|
1621
|
-
themes. For any inline border, background, or text color, reference a token:
|
|
1622
|
-
\`style="border:1.4px solid var(--wf-line)"\`. The tokens are \`--wf-ink\` (text),
|
|
1623
|
-
\`--wf-muted\` (secondary text), \`--wf-line\` (borders/dividers), \`--wf-paper\`
|
|
1624
|
-
(page background), \`--wf-card\` (raised surface), \`--wf-accent\` /
|
|
1625
|
-
\`--wf-accent-fg\` / \`--wf-accent-soft\` (brand action), \`--wf-warn\`, \`--wf-ok\`,
|
|
1626
|
-
and \`--wf-radius\`. Never hard-code a hex color and never set \`font-family\` — the
|
|
1627
|
-
renderer owns the sketch/clean font.
|
|
1628
|
-
|
|
1629
|
-
**Lay out with inline \`style\` flex/grid.** You write the real layout —
|
|
1630
|
-
\`display:flex; flex-direction:column; gap:10px; padding:16px\` and so on — and the
|
|
1631
|
-
renderer never repositions anything. Compose the actual product: reproduce the
|
|
1632
|
-
current screen, then show the modification. Real labels, real counts, real dates,
|
|
1633
|
-
real button text grounded in the screen you read; not lorem or gray bars.
|
|
1634
|
-
|
|
1635
|
-
**Surface presets — match the real footprint, never default to desktop+mobile.**
|
|
1636
|
-
Pick the \`surface\` that matches what the user will actually see:
|
|
1637
|
-
|
|
1638
|
-
- \`browser\`: a web page that needs a browser chrome frame around it.
|
|
1639
|
-
- \`desktop\`: a full desktop app page or app shell.
|
|
1640
|
-
- \`mobile\`: a phone screen, only when the work is genuinely mobile.
|
|
1641
|
-
- \`popover\`: a small floating menu, dropdown, or inline popover.
|
|
1642
|
-
- \`panel\`: a side panel, inspector, or sidebar widget.
|
|
1643
|
-
|
|
1644
|
-
A sidebar popover renders as a small surface, not a desktop page and a phone
|
|
1645
|
-
frame. Do not emit \`desktop\` + \`mobile\` variants unless responsive behavior
|
|
1646
|
-
actually changes the layout. For a component or widget, show one broader
|
|
1647
|
-
app-context frame only when placement affects understanding, then the focused
|
|
1648
|
-
component states.
|
|
1649
|
-
|
|
1650
|
-
**Model the actual component shell for small surfaces.** A rendered UI change
|
|
1651
|
-
belongs in a wireframe; reserve \`diagram\` for architecture, dependency, state,
|
|
1652
|
-
or data-flow relationships. Popovers, dropdown menus, command palettes, and
|
|
1653
|
-
context menus use \`surface: "popover"\` unless the surrounding page placement is
|
|
1654
|
-
the point of the change. Dialogs, sheets, inspectors, sidebars, and long
|
|
1655
|
-
property panels use the matching \`panel\` / \`desktop\` surface as appropriate.
|
|
1656
|
-
Show the real chrome: trigger or anchor when it matters, title/header row,
|
|
1657
|
-
top-right actions, separators, fields, options, selected states, body content,
|
|
1658
|
-
and footer actions that are visible in the workflow.
|
|
1659
|
-
|
|
1660
|
-
**Modify, don't redesign.** When the task changes an existing screen, reproduce
|
|
1661
|
-
the current screen's real layout and footprint FIRST, then change only the delta
|
|
1662
|
-
and call it out with a single annotation. Do not restack the page into a new
|
|
1663
|
-
layout. For net-new surfaces, compose from the real app shell.
|
|
1664
|
-
|
|
1665
|
-
**Classify mockup scope before implementation.** Before turning a plan mockup
|
|
1666
|
-
into source code, decide whether each artboard represents the whole page/app
|
|
1667
|
-
shell, a route body inside an existing shell, or a component/sub-surface. If an
|
|
1668
|
-
artboard includes navigation, sidebars, auth banners, or a signup/login form,
|
|
1669
|
-
map those pieces to the real shared shell/auth components instead of nesting the
|
|
1670
|
-
entire mockup inside the current page. When a mockup references the product's
|
|
1671
|
-
standard signup/login page, find and reuse that existing implementation; do not
|
|
1672
|
-
approximate it from the wireframe.
|
|
1673
|
-
|
|
1674
|
-
**Zoom in on sub-surfaces, don't redraw the page.** For a small sub-surface (a
|
|
1675
|
-
popover, menu, dialog, toast), show the full screen once, then add a small
|
|
1676
|
-
separate artboard whose \`html\` contains ONLY that sub-surface — do not re-draw
|
|
1677
|
-
the whole page around it, and do not scale a duplicate up. Pick the matching
|
|
1678
|
-
\`surface\` (e.g. \`popover\`) so the footprint is right; never widen a popover to
|
|
1679
|
-
page width.
|
|
1680
|
-
|
|
1681
|
-
**Loading / skeleton states.** Set \`data.skeleton: true\` on the wireframe and
|
|
1682
|
-
fill the \`html\` with neutral, textless placeholder geometry — boxes and bars
|
|
1683
|
-
built as \`<div>\`s with \`background:var(--wf-line)\` and explicit heights/widths,
|
|
1684
|
-
no labels or copy. The renderer drops borders, sketch, and color into the
|
|
1685
|
-
skeleton register automatically. Never escape to a \`custom-html\` document block
|
|
1686
|
-
to fake a loader.
|
|
1687
|
-
|
|
1688
|
-
**Editing an existing mockup.** To change one element, text, or color in an
|
|
1689
|
-
existing html mockup, do NOT regenerate the frame — call \`update-visual-plan\`
|
|
1690
|
-
with \`contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
|
|
1691
|
-
replace }] }]\`. Each \`find\` is a unique snippet of the current html (read it
|
|
1692
|
-
first with \`get-visual-plan\`); set \`all: true\` on an edit to replace every
|
|
1693
|
-
occurrence. The result is re-sanitized.
|
|
1694
|
-
|
|
1695
|
-
**Treat the wireframe border as part of the visible design.** Always wrap HTML
|
|
1696
|
-
wireframe content in a root container with real inner padding before drawing
|
|
1697
|
-
cards, fields, pills, labels, or controls. Use at least 14-16px of padding,
|
|
1698
|
-
\`box-sizing: border-box\`, \`height: 100%\`, and \`gap\` between child rows so the
|
|
1699
|
-
first row never sits flush against the screen border. Keep text away from
|
|
1700
|
-
borders: every container, field, button, menu item, and annotation needs enough
|
|
1701
|
-
padding and line-height to read cleanly in the rendered Plan view.
|
|
1702
|
-
|
|
1703
|
-
**Lay out children safely so they never collide.** Use HTML flex/grid with
|
|
1704
|
-
\`gap\`, \`min-width: 0\`, and sensible overflow. Avoid negative margins, absolute
|
|
1705
|
-
positioning, or fixed child widths that can collide when the renderer switches
|
|
1706
|
-
between light/dark, sketch/clean, or different zoom levels.
|
|
1707
|
-
|
|
1708
|
-
**Do not wrap intentionally single-line labels.** For toolbars, tab rails,
|
|
1709
|
-
breadcrumbs, chip/filter rows, branch and file names, file chips, and code
|
|
1710
|
-
filenames — any deliberately single-line row — do not let long text wrap. Put
|
|
1711
|
-
\`white-space: nowrap\` on the row (and \`overflow: hidden; text-overflow: ellipsis\`
|
|
1712
|
-
on the individual labels that can grow), so the wireframe demonstrates the actual
|
|
1713
|
-
layout behavior instead of producing ugly stacked or vertical text. Use
|
|
1714
|
-
horizontally scrollable or clipped rails for overflow.
|
|
1715
|
-
|
|
1716
|
-
**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).
|
|
1717
|
-
|
|
1718
|
-
**Persistent chrome bars span the full frame width.** Top bars, app headers,
|
|
1719
|
-
toolbars, and bottom tab/nav bars are full-width chrome, not centered content.
|
|
1720
|
-
Lay each one out as a single flex row that fills the frame
|
|
1721
|
-
(\`style="display:flex;align-items:center;width:100%"\`) and push trailing actions
|
|
1722
|
-
to the right edge with a flex spacer (\`<div style="flex:1"></div>\`) between the
|
|
1723
|
-
leading group and the trailing group — never center a bar inside a narrow,
|
|
1724
|
-
centered block, and never let it collapse to the width of its contents. In a
|
|
1725
|
-
Before/After pair the bar stays full-width in BOTH states even when one state has
|
|
1726
|
-
fewer controls; the spacer absorbs the difference so the remaining controls hold
|
|
1727
|
-
their edge alignment instead of sliding to the center.
|
|
1728
|
-
|
|
1729
|
-
**Pin bottom bars to the bottom of the frame.** For mobile tab bars, footers, and
|
|
1730
|
-
any persistent bottom action row, make the frame itself a flex column at
|
|
1731
|
-
\`height:100%\` (\`style="display:flex;flex-direction:column;height:100%"\`), give the
|
|
1732
|
-
scrolling body \`flex:1\` so it absorbs the slack, and place the bar as the LAST
|
|
1733
|
-
child of the frame (or set \`margin-top:auto\` on it). The bar then sits flush at
|
|
1734
|
-
the bottom of the surface instead of floating directly under the content with an
|
|
1735
|
-
empty band beneath it.
|
|
1736
|
-
|
|
1737
|
-
**Before / after must be comparable.** When showing a state change, preserve the
|
|
1738
|
-
unchanged controls in both states so the reviewer can see exactly what moved or
|
|
1739
|
-
appeared; do not show an added control as a generic box floating elsewhere in
|
|
1740
|
-
the surface. Place the new/changed affordance where the implementation puts it —
|
|
1741
|
-
for example, a new \`Edit with AI\` action in a popover header belongs in the
|
|
1742
|
-
top-right header slot, aligned with the title, not in the body or footer. Use
|
|
1743
|
-
the same frame size, scale, outer padding, border radius, and visual density on
|
|
1744
|
-
both sides unless the change itself alters those properties, and let the frame
|
|
1745
|
-
height fit the content rather than leaving a tall empty lower half.
|
|
1746
|
-
|
|
1747
|
-
**Name the states with the column header, never inside the frame.** Put the two
|
|
1748
|
-
states in a \`columns\` block and set each column's \`label\` to \`Before\` and
|
|
1749
|
-
\`After\` — the renderer draws that label as an \`h4\` heading above each frame. Do
|
|
1750
|
-
NOT bake a \`Before\`/\`After\` pill, title, or heading into the wireframe \`html\`: a
|
|
1751
|
-
label placed inside reads as part of the product UI, lands in a random corner,
|
|
1752
|
-
and clutters the comparison. The column header is the one and only place the
|
|
1753
|
-
state name belongs.
|
|
1754
|
-
|
|
1755
|
-
**Let the surface choose side-by-side vs. stacked.** The \`columns\` renderer lays
|
|
1756
|
-
narrow surfaces (\`mobile\`, \`popover\`, \`panel\`) out side by side, and
|
|
1757
|
-
automatically stacks wide surfaces (\`desktop\`, \`browser\`) vertically at full
|
|
1758
|
-
document width so a large frame is never crushed into a half-width column and
|
|
1759
|
-
cropped. Author both wireframes with the real \`surface\` and the matching
|
|
1760
|
-
\`Before\`/\`After\` column labels; do not hand-stack the pair into separate
|
|
1761
|
-
top-level wireframes or duplicate the state name as body content.
|
|
1762
|
-
|
|
1763
|
-
**Good example — a contacts list, surface \`browser\`.** A small, real screen
|
|
1764
|
-
composed from the helper classes and tokens, layout in inline flex, no fonts or
|
|
1765
|
-
hex colors:
|
|
1766
|
-
|
|
1767
|
-
\`\`\`html
|
|
1768
|
-
<div
|
|
1769
|
-
style="display:flex;flex-direction:column;gap:12px;padding:16px;height:100%"
|
|
1770
|
-
>
|
|
1771
|
-
<div style="display:flex;align-items:center;justify-content:space-between">
|
|
1772
|
-
<h1>Contacts</h1>
|
|
1773
|
-
<button class="primary">New contact</button>
|
|
1774
|
-
</div>
|
|
1775
|
-
<div style="display:flex;gap:6px">
|
|
1776
|
-
<span class="wf-pill accent">All 128</span>
|
|
1777
|
-
<span class="wf-pill">Favorites</span>
|
|
1778
|
-
<span class="wf-pill">Archived</span>
|
|
1779
|
-
</div>
|
|
1780
|
-
<div
|
|
1781
|
-
class="wf-card"
|
|
1782
|
-
style="display:flex;flex-direction:column;gap:0;padding:0"
|
|
1783
|
-
>
|
|
1784
|
-
<div
|
|
1785
|
-
style="display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1.4px solid var(--wf-line)"
|
|
1786
|
-
>
|
|
1787
|
-
<div
|
|
1788
|
-
style="width:32px;height:32px;border-radius:999px;background:var(--wf-accent-soft)"
|
|
1789
|
-
></div>
|
|
1790
|
-
<div style="flex:1">
|
|
1791
|
-
<strong>Jane Cooper</strong><br /><small>jane@acme.co</small>
|
|
1792
|
-
</div>
|
|
1793
|
-
<span class="wf-pill">Lead</span>
|
|
1794
|
-
</div>
|
|
1795
|
-
<div style="display:flex;align-items:center;gap:10px;padding:10px 12px">
|
|
1796
|
-
<div
|
|
1797
|
-
style="width:32px;height:32px;border-radius:999px;background:var(--wf-accent-soft)"
|
|
1798
|
-
></div>
|
|
1799
|
-
<div style="flex:1">
|
|
1800
|
-
<strong>Marcus Lee</strong><br /><small>marcus@globex.io</small>
|
|
1801
|
-
</div>
|
|
1802
|
-
<span class="wf-pill">Customer</span>
|
|
1803
|
-
</div>
|
|
1804
|
-
</div>
|
|
1805
|
-
</div>
|
|
1806
|
-
\`\`\`
|
|
1281
|
+
reviewer sees the footprint of the work at a glance.
|
|
1282
|
+
- The split \`diff\` of the KEY changed files, grouped under a \`## Key changes\`
|
|
1283
|
+
\`rich-text\` heading in a single horizontal \`tabs\` block (the default
|
|
1284
|
+
orientation, one file per tab), with a one-line \`summary\` and a few
|
|
1285
|
+
\`annotations\` on each — so the reviewer can drop from the high-altitude shape
|
|
1286
|
+
straight into the load-bearing code. Use horizontal file tabs, not a vertical
|
|
1287
|
+
side rail, so the selected file has enough width for the side-by-side diff.
|
|
1288
|
+
|
|
1289
|
+
Skip the diff appendix only for a genuinely tiny change that reviews faster as
|
|
1290
|
+
plain diff (see "When To Use"); for any change worth recapping, the file-tree and
|
|
1291
|
+
key-change diffs belong in the plan.
|
|
1292
|
+
|
|
1293
|
+
## UI Impact Needs Wireframes
|
|
1294
|
+
|
|
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.
|
|
1299
|
+
|
|
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.
|
|
1318
|
+
|
|
1319
|
+
Choose the smallest visual surface that makes the review clear:
|
|
1320
|
+
|
|
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.
|
|
1807
1341
|
|
|
1808
|
-
|
|
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.
|
|
1809
1351
|
|
|
1810
1352
|
Use the standard \`WireframeBlock\` / \`<Screen>\` format so the Plan viewer owns the
|
|
1811
1353
|
surface frame, theme, and sketchy/clean toggle. HTML wireframes are appropriate
|
|
1812
1354
|
when placement precision matters, especially popovers, menus, dialogs, and dense
|
|
1813
|
-
forms
|
|
1355
|
+
forms. For HTML
|
|
1814
1356
|
wireframes, keep \`renderMode\` unset or \`wireframe\` unless a design-only editable
|
|
1815
1357
|
mockup is explicitly required, because \`renderMode="design"\` disables the
|
|
1816
1358
|
sketchy rough overlay.
|
|
@@ -1822,6 +1364,11 @@ text-match screenshot is not enough; visually inspect the captured image.
|
|
|
1822
1364
|
|
|
1823
1365
|
## Open And Report The Recap
|
|
1824
1366
|
|
|
1367
|
+
In local-files privacy mode, report the local preview URL/path from
|
|
1368
|
+
\`agent-native plan local preview\` or the \`/local-plans/<slug>\` route for a local
|
|
1369
|
+
Plan app using the same \`PLAN_LOCAL_DIR\`. Do not invent a hosted URL and do not
|
|
1370
|
+
publish just to get an absolute Plan link.
|
|
1371
|
+
|
|
1825
1372
|
After creating the recap, link the reviewer to the rendered plan with an
|
|
1826
1373
|
**absolute URL on the origin whose database actually holds the plan**. That
|
|
1827
1374
|
origin is the Plan MCP server you just created the recap through — NOT whatever
|
|
@@ -1865,7 +1412,9 @@ artifacts, not as the main way to open the recap.
|
|
|
1865
1412
|
## Diff → Block Mapping
|
|
1866
1413
|
|
|
1867
1414
|
Map each kind of change to the block that carries it, derived mechanically from
|
|
1868
|
-
the actual diff
|
|
1415
|
+
the actual diff. The names below are the CONCEPTUAL block types, not the JSX
|
|
1416
|
+
tags — resolve every conceptual name to its exact tag + prop schema with the
|
|
1417
|
+
\`get-plan-blocks\` tool (see "Block reference" below) before authoring.
|
|
1869
1418
|
|
|
1870
1419
|
- **Schema / migration change** → \`data-model\` for the resulting entities,
|
|
1871
1420
|
fields, and relations. Flag what moved per field/entity with
|
|
@@ -1892,42 +1441,36 @@ the actual diff:
|
|
|
1892
1441
|
- **Compatibility-sensitive change** → short \`rich-text\` notes beside the
|
|
1893
1442
|
relevant \`data-model\` / \`api-endpoint\` block. Name the changed field,
|
|
1894
1443
|
endpoint, or behavior and mark whether it is breaking, risky, or non-breaking;
|
|
1895
|
-
pair that note with a \`diff\` for the literal lines.
|
|
1896
|
-
- **Any meaningful code hunk** → \`diff\` carrying the real
|
|
1897
|
-
and the \`filename\` / \`language\`.
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
changes and why; it renders as a description above the code so the reviewer
|
|
1904
|
-
reads intent first. Never leave a diff unlabeled.
|
|
1444
|
+
pair that note with a split \`diff\` for the literal lines.
|
|
1445
|
+
- **Any meaningful code hunk** → \`diff\` with \`mode: "split"\`, carrying the real
|
|
1446
|
+
\`before\` / \`after\` text and the \`filename\` / \`language\`. Split mode is the
|
|
1447
|
+
default for recap code review because before/after legibility is the point;
|
|
1448
|
+
use \`mode: "unified"\` only for a genuinely narrow standalone hunk where
|
|
1449
|
+
side-by-side would hide the code. Give every \`diff\` a one-line \`summary\`
|
|
1450
|
+
saying what the hunk changes and why; it renders as a description above the
|
|
1451
|
+
code so the reviewer reads intent first. Never leave a diff unlabeled.
|
|
1905
1452
|
For the KEY changed files, attach \`annotations\` to the \`diff\` so the recap
|
|
1906
1453
|
calls out what each important hunk does — this is the headline affordance for
|
|
1907
|
-
annotating the key files updated. Each annotation
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
point at removed lines). Keep it to a few high-signal notes per file, not one
|
|
1911
|
-
per line.
|
|
1454
|
+
annotating the key files updated. Each annotation anchors to the AFTER-side
|
|
1455
|
+
line numbers by default (set \`side: "before"\` to point at removed lines). Keep
|
|
1456
|
+
it to a few high-signal notes per file, not one per line.
|
|
1912
1457
|
When several key files each need a substantial diff, introduce the group with a
|
|
1913
1458
|
\`rich-text\` heading block whose markdown is \`## Key changes\`, then place the
|
|
1914
|
-
\`diff\` blocks under it in a reusable \`tabs\` block with
|
|
1915
|
-
\`orientation
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
Keep each tab label to the file path or a short basename plus directory hint.
|
|
1459
|
+
\`diff\` blocks under it in a reusable \`tabs\` block with horizontal orientation
|
|
1460
|
+
(the default — omit \`orientation\`) so the selected file's split diff gets the
|
|
1461
|
+
full document width. Let that heading label the section — do NOT also set a
|
|
1462
|
+
\`title\` on the \`tabs\` block. Keep each tab label to the file path or a short
|
|
1463
|
+
basename plus directory hint.
|
|
1920
1464
|
If the recap ends with more than one supporting diff, that trailing diff
|
|
1921
|
-
appendix should be one
|
|
1465
|
+
appendix should be one horizontal \`tabs\` block under its own \`## Key changes\`
|
|
1922
1466
|
heading, not a stack of separate \`diff\` blocks.
|
|
1923
1467
|
- **Brand-new file or a substantial added block with no meaningful "before"** →
|
|
1924
|
-
\`annotated-code\` rather than a one-sided \`diff\`. Carry the real new code
|
|
1468
|
+
\`annotated-code\` rather than a one-sided split \`diff\`. Carry the real new code
|
|
1925
1469
|
with its \`filename\` / \`language\` and anchor a few high-signal notes to the lines
|
|
1926
|
-
that matter
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
grouped.
|
|
1470
|
+
that matter so the reviewer reads what the new code does, not code for code's
|
|
1471
|
+
sake. Keep split \`diff\` for true before/after hunks where the removed lines
|
|
1472
|
+
still carry meaning, and group several annotated walkthroughs in a horizontal
|
|
1473
|
+
\`tabs\` block the same way diffs are grouped.
|
|
1931
1474
|
- **Files added / removed / renamed** → \`file-tree\` with each entry's \`change\`
|
|
1932
1475
|
flag (\`added\`, \`removed\`, \`modified\`, \`renamed\`) and a short \`note\`; attach a
|
|
1933
1476
|
\`snippet\` only when one tells the reviewer something the path does not.
|
|
@@ -1936,15 +1479,17 @@ the actual diff:
|
|
|
1936
1479
|
wireframes when the comparison clarifies the change; otherwise use after-only
|
|
1937
1480
|
or a short state/flow sequence. Use realistic UI surfaces: for a popover
|
|
1938
1481
|
change, show a popover with its title row, top-right actions, options/fields,
|
|
1939
|
-
and any opened prompt/menu
|
|
1940
|
-
the
|
|
1941
|
-
|
|
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.
|
|
1942
1488
|
- **Architecture or data-flow shift** → \`diagram\` with \`data.html\` / \`data.css\`
|
|
1943
1489
|
as a two-panel before/after, layered, or swimlane layout, or \`mermaid\` for a
|
|
1944
|
-
quick graph. Use
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
\`wireframe\` blocks.
|
|
1490
|
+
quick graph. Use two-dimensional layouts; do not reduce a structural change to
|
|
1491
|
+
a left-to-right chain. Do not use \`diagram\` as a stand-in for rendered UI
|
|
1492
|
+
controls; UI changes need \`wireframe\` blocks.
|
|
1948
1493
|
Diagram HTML/CSS should use renderer-owned primitives such as
|
|
1949
1494
|
\`.diagram-panel\`, \`.diagram-card\`, \`.diagram-node\`, \`.diagram-box\`,
|
|
1950
1495
|
\`.diagram-pill\`, \`.diagram-muted\`, and \`[data-rough]\`; these map to the plan's
|
|
@@ -1957,349 +1502,56 @@ the actual diff:
|
|
|
1957
1502
|
the objective the diff served, the key decisions visible in it, and the risks a
|
|
1958
1503
|
reviewer should weigh. This is the only place the model writes freely.
|
|
1959
1504
|
|
|
1960
|
-
## Block
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
\`
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
the block level are validated.
|
|
2011
|
-
|
|
2012
|
-
### \`Endpoint\` (API / route)
|
|
2013
|
-
|
|
2014
|
-
Tag is \`Endpoint\` — NOT \`ApiEndpoint\`. Required attrs: \`method\`, \`path\`. Optional
|
|
2015
|
-
attrs: \`summary\` (the short title — NOT \`title\`), \`auth\`, \`deprecated\` (bool),
|
|
2016
|
-
\`change\`, \`params\`, \`request\`, \`responses\`. The prose \`description\` is the MDX
|
|
2017
|
-
**children** (body between the tags), NOT an attribute.
|
|
2018
|
-
|
|
2019
|
-
- \`method\` ∈ \`GET | POST | PUT | PATCH | DELETE | HEAD | OPTIONS\`. For a
|
|
2020
|
-
WebSocket upgrade use \`GET\`.
|
|
2021
|
-
- \`change\` (and per-param/per-response \`change\`) ∈ \`added | modified | removed | renamed\`.
|
|
2022
|
-
- \`params={[{ name, in, type?, required?, description?, change?, was? }]}\` where
|
|
2023
|
-
\`in\` ∈ \`path | query | header | body\`.
|
|
2024
|
-
- \`request={{ contentType?, example? }}\` — \`example\` is a JSON **string**, not a
|
|
2025
|
-
nested object.
|
|
2026
|
-
- \`responses={[{ status, description?, example?, change? }]}\` — each \`example\` is
|
|
2027
|
-
a JSON **string** (the renderer parses it into the collapsible JsonExplorer).
|
|
2028
|
-
Give each distinct message shape (e.g. success vs error, or separate WS frame
|
|
2029
|
-
types) its OWN response entry, not one merged body.
|
|
2030
|
-
|
|
2031
|
-
\`\`\`mdx
|
|
2032
|
-
<Endpoint
|
|
2033
|
-
id="ep-create-task"
|
|
2034
|
-
method="POST"
|
|
2035
|
-
path="/api/tasks"
|
|
2036
|
-
summary="Create a task"
|
|
2037
|
-
request={{ contentType: "application/json", example: '{"title":"Ship recap"}' }}
|
|
2038
|
-
responses={[{ status: "201", description: "Created", example: '{"id":"t_1","title":"Ship recap"}' }]}
|
|
2039
|
-
>
|
|
2040
|
-
|
|
2041
|
-
Creates a task scoped to the caller's org.
|
|
2042
|
-
|
|
2043
|
-
</Endpoint>
|
|
2044
|
-
\`\`\`
|
|
2045
|
-
|
|
2046
|
-
### \`DataModel\` (schema / ER)
|
|
2047
|
-
|
|
2048
|
-
Tag is \`DataModel\`. Required attr: \`entities\` (>= 1). Optional attr: \`relations\`.
|
|
2049
|
-
There is NO top-level \`fields=\` attribute — fields live inside each entity. There
|
|
2050
|
-
is NO per-field \`required\` or \`description\` key; fold either into \`note\`.
|
|
2051
|
-
|
|
2052
|
-
- \`entities={[{ id, name, note?, change?, fields: [...] }]}\` — \`id\` is referenced
|
|
2053
|
-
by relations.
|
|
2054
|
-
- each field: \`{ name, type?, pk?, fk?, nullable?, default?, note?, change?, was? }\`.
|
|
2055
|
-
\`pk\`/\`nullable\` are booleans; \`fk\` is a string target like \`"User.id"\`;
|
|
2056
|
-
\`change\` ∈ \`added | modified | removed | renamed\`; \`was\` is the prior value
|
|
2057
|
-
when \`change\` is \`modified\`.
|
|
2058
|
-
- \`relations={[{ from, to, kind?, label? }]}\` (optional — the renderer infers
|
|
2059
|
-
simple \`1-n\` from \`fk\` when omitted); \`kind\` ∈ \`1-1 | 1-n | n-n\`.
|
|
2060
|
-
|
|
2061
|
-
\`\`\`mdx
|
|
2062
|
-
<DataModel
|
|
2063
|
-
id="dm-tasks"
|
|
2064
|
-
entities={[
|
|
2065
|
-
{
|
|
2066
|
-
id: "task",
|
|
2067
|
-
name: "Task",
|
|
2068
|
-
fields: [
|
|
2069
|
-
{ name: "id", type: "uuid", pk: true },
|
|
2070
|
-
{ name: "title", type: "text" },
|
|
2071
|
-
{ name: "status", type: "text", change: "added", note: "open|done" }
|
|
2072
|
-
]
|
|
2073
|
-
}
|
|
2074
|
-
]}
|
|
2075
|
-
/>
|
|
2076
|
-
\`\`\`
|
|
2077
|
-
|
|
2078
|
-
### \`FileTree\` (changed files)
|
|
2079
|
-
|
|
2080
|
-
Tag is \`FileTree\`. Required attr: \`entries\` (>= 1). Optional attr: \`title\`. The
|
|
2081
|
-
tree is built from the leaf \`path\`s — do NOT pass an ASCII tree in children; the
|
|
2082
|
-
block is self-closing.
|
|
2083
|
-
|
|
2084
|
-
- \`entries={[{ path, change?, note?, snippet?, language? }]}\` — \`path\` is
|
|
2085
|
-
slash-delimited; \`change\` ∈ \`added | modified | removed | renamed\`. Add a
|
|
2086
|
-
\`snippet\` (with optional \`language\`) only when it says something the path does
|
|
2087
|
-
not.
|
|
2088
|
-
|
|
2089
|
-
\`\`\`mdx
|
|
2090
|
-
<FileTree
|
|
2091
|
-
id="ft-changed"
|
|
2092
|
-
title="Files touched"
|
|
2093
|
-
entries={[
|
|
2094
|
-
{ path: "server/routes/tasks.ts", change: "modified", note: "add POST handler" },
|
|
2095
|
-
{ path: "server/db/schema.ts", change: "modified" },
|
|
2096
|
-
{ path: "tests/tasks.test.ts", change: "added" }
|
|
2097
|
-
]}
|
|
2098
|
-
/>
|
|
2099
|
-
\`\`\`
|
|
2100
|
-
|
|
2101
|
-
### \`Mermaid\` (graph)
|
|
2102
|
-
|
|
2103
|
-
Tag is \`Mermaid\` — this is its OWN block, separate from \`Diagram\`. Required attr:
|
|
2104
|
-
\`source\` (the diagram text). Optional attr: \`caption\`. Do NOT put mermaid text
|
|
2105
|
-
inside a \`Diagram\` block, and do NOT use \`<Diagram mermaid={...}>\` — that is not a
|
|
2106
|
-
real prop and will not render.
|
|
2107
|
-
|
|
2108
|
-
\`\`\`mdx
|
|
2109
|
-
<Mermaid
|
|
2110
|
-
id="mm-flow"
|
|
2111
|
-
source={\`flowchart LR
|
|
2112
|
-
Client --> API
|
|
2113
|
-
API --> DB\`}
|
|
2114
|
-
caption="Request path"
|
|
2115
|
-
/>
|
|
2116
|
-
\`\`\`
|
|
2117
|
-
|
|
2118
|
-
### \`Diagram\` (HTML/SVG or node graph)
|
|
2119
|
-
|
|
2120
|
-
Tag is \`Diagram\`. The whole payload is ONE \`data\` attribute:
|
|
2121
|
-
\`data={{ html?, css?, caption?, nodes?, edges?, notes? }}\`. It requires either
|
|
2122
|
-
\`html\` (an inert HTML/SVG fragment) OR at least one node — a \`Diagram\` with
|
|
2123
|
-
neither fails validation. This is for architecture / data-flow / dependency
|
|
2124
|
-
relationships, NOT rendered UI (use a wireframe for UI) and NOT mermaid (use
|
|
2125
|
-
\`Mermaid\`). Use \`.diagram-*\` primitives + \`--wf-*\` tokens in \`html\`/\`css\`; never
|
|
2126
|
-
hex colors or \`font-family\`.
|
|
2127
|
-
|
|
2128
|
-
\`\`\`mdx
|
|
2129
|
-
<Diagram
|
|
2130
|
-
id="dg-arch"
|
|
2131
|
-
data={{
|
|
2132
|
-
nodes: [
|
|
2133
|
-
{ id: "ui", label: "UI" },
|
|
2134
|
-
{ id: "api", label: "API" },
|
|
2135
|
-
{ id: "db", label: "DB" }
|
|
2136
|
-
],
|
|
2137
|
-
edges: [
|
|
2138
|
-
{ from: "ui", to: "api" },
|
|
2139
|
-
{ from: "api", to: "db" }
|
|
2140
|
-
]
|
|
2141
|
-
}}
|
|
2142
|
-
/>
|
|
2143
|
-
\`\`\`
|
|
2144
|
-
|
|
2145
|
-
### \`Json\` (JSON explorer)
|
|
2146
|
-
|
|
2147
|
-
Tag is \`Json\`. Required attr: \`json\` — a **string** containing the JSON.
|
|
2148
|
-
Optional attrs: \`title\`, \`collapsedDepth\` (number, default 2).
|
|
2149
|
-
|
|
2150
|
-
\`\`\`mdx
|
|
2151
|
-
<Json
|
|
2152
|
-
id="json-config"
|
|
2153
|
-
title="Resolved config"
|
|
2154
|
-
json={'{"flags":{"recap":true},"limit":50}'}
|
|
2155
|
-
/>
|
|
2156
|
-
\`\`\`
|
|
2157
|
-
|
|
2158
|
-
### \`Diff\` (before/after)
|
|
2159
|
-
|
|
2160
|
-
Tag is \`Diff\`. Required attrs: \`before\`, \`after\` (multiline source strings).
|
|
2161
|
-
Optional attrs: \`filename\`, \`language\`, \`mode\` (\`unified | split\`), \`annotations\`.
|
|
2162
|
-
Leave \`mode\` unset: it defaults to **unified**, which reads cleanly at any width
|
|
2163
|
-
and is what recap diffs want — they almost always live inside a width-constrained
|
|
2164
|
-
container (a vertical-tabs panel or a comparison column) where split's two
|
|
2165
|
-
line-number gutters cut the code off. Only set \`mode: "split"\` for a standalone,
|
|
2166
|
-
full-document-width diff where side-by-side genuinely helps. The reader always
|
|
2167
|
-
exposes a Unified/Split toggle (when there is room), so a viewer can switch
|
|
2168
|
-
either way regardless of the authored default. Give every diff a \`summary\` (the
|
|
2169
|
-
shared envelope attr) so the reviewer reads intent first.
|
|
2170
|
-
|
|
2171
|
-
- \`annotations={[{ side?, lines, label?, note }]}\` — \`side\` ∈ \`before | after\`
|
|
2172
|
-
(default \`after\`); \`lines\` is a 1-based ref like \`"13"\` or \`"13-15"\`.
|
|
2173
|
-
|
|
2174
|
-
\`\`\`mdx
|
|
2175
|
-
<Diff
|
|
2176
|
-
id="diff-handler"
|
|
2177
|
-
filename="server/routes/tasks.ts"
|
|
2178
|
-
language="ts"
|
|
2179
|
-
summary="Add the POST /api/tasks handler"
|
|
2180
|
-
before={\`router.get("/api/tasks", list);\`}
|
|
2181
|
-
after={\`router.get("/api/tasks", list);\\nrouter.post("/api/tasks", create);\`}
|
|
2182
|
-
annotations={[{ side: "after", lines: "2", label: "New route", note: "Creates a task" }]}
|
|
2183
|
-
/>
|
|
2184
|
-
\`\`\`
|
|
2185
|
-
|
|
2186
|
-
### \`AnnotatedCode\` (new-file walkthrough)
|
|
2187
|
-
|
|
2188
|
-
Tag is \`AnnotatedCode\`. Required attr: \`code\` (multiline string). Optional attrs:
|
|
2189
|
-
\`filename\`, \`language\`, \`annotations\`. Use this for a brand-new file with no
|
|
2190
|
-
meaningful "before".
|
|
2191
|
-
|
|
2192
|
-
- \`annotations={[{ lines, label?, note }]}\` — 1-based \`lines\` ref (no \`side\`,
|
|
2193
|
-
unlike \`Diff\`).
|
|
2194
|
-
|
|
2195
|
-
\`\`\`mdx
|
|
2196
|
-
<AnnotatedCode
|
|
2197
|
-
id="ac-create"
|
|
2198
|
-
filename="server/tasks/create.ts"
|
|
2199
|
-
language="ts"
|
|
2200
|
-
code={\`export async function create(input: NewTask) {\\n return db.tasks.insert(input);\\n}\`}
|
|
2201
|
-
annotations={[{ lines: "1-3", label: "Handler", note: "Inserts and returns the row" }]}
|
|
2202
|
-
/>
|
|
2203
|
-
\`\`\`
|
|
2204
|
-
|
|
2205
|
-
### \`RichText\` (prose)
|
|
2206
|
-
|
|
2207
|
-
Tag is \`RichText\`. The markdown is the MDX **children** (body between the tags),
|
|
2208
|
-
NOT an attribute. Use \`## Key changes\` here as the heading above a grouped diff
|
|
2209
|
-
\`TabsBlock\`.
|
|
2210
|
-
|
|
2211
|
-
\`\`\`mdx
|
|
2212
|
-
<RichText id="rt-why">
|
|
2213
|
-
|
|
2214
|
-
## Why
|
|
2215
|
-
|
|
2216
|
-
Adds a create endpoint so the agent can author tasks directly.
|
|
2217
|
-
|
|
2218
|
-
</RichText>
|
|
2219
|
-
\`\`\`
|
|
2220
|
-
|
|
2221
|
-
### \`Callout\` (tone note)
|
|
2222
|
-
|
|
2223
|
-
Tag is \`Callout\`. Optional attr: \`tone\` ∈ \`info | decision | risk | warning | success\`.
|
|
2224
|
-
The body markdown is the MDX **children**, NOT an attribute.
|
|
2225
|
-
|
|
2226
|
-
\`\`\`mdx
|
|
2227
|
-
<Callout id="co-risk" tone="risk">
|
|
2228
|
-
|
|
2229
|
-
The new column is non-nullable with no default — existing rows need a backfill.
|
|
2230
|
-
|
|
2231
|
-
</Callout>
|
|
2232
|
-
\`\`\`
|
|
2233
|
-
|
|
2234
|
-
### \`Columns\` (side-by-side)
|
|
2235
|
-
|
|
2236
|
-
Tag is \`Columns\`; each column is a nested \`<Column label="...">\` whose body is
|
|
2237
|
-
markdown and/or block components. 1–4 columns. Use labels \`Before\` / \`After\` for
|
|
2238
|
-
structured comparisons.
|
|
2239
|
-
|
|
2240
|
-
\`\`\`mdx
|
|
2241
|
-
<Columns id="cols-schema">
|
|
2242
|
-
<Column label="Before">
|
|
2243
|
-
|
|
2244
|
-
\`status\` did not exist.
|
|
2245
|
-
|
|
2246
|
-
</Column>
|
|
2247
|
-
<Column label="After">
|
|
2248
|
-
|
|
2249
|
-
<DataModel id="dm-after" entities={[{ id: "task", name: "Task", fields: [{ name: "status", type: "text", change: "added" }] }]} />
|
|
2250
|
-
|
|
2251
|
-
</Column>
|
|
2252
|
-
</Columns>
|
|
2253
|
-
\`\`\`
|
|
2254
|
-
|
|
2255
|
-
### \`TabsBlock\` (tab rail)
|
|
2256
|
-
|
|
2257
|
-
Tag is \`TabsBlock\` — NOT \`Tabs\`, and there is NO nested \`<Tab>\` element. Required
|
|
2258
|
-
attr: \`tabs\` (1–12). Optional attr: \`orientation\` (\`horizontal | vertical\`; use
|
|
2259
|
-
\`vertical\` for a file rail). The whole \`tabs\` array (including nested child
|
|
2260
|
-
blocks) is ONE JSON prop; do NOT nest the tabs or their child blocks as MDX
|
|
2261
|
-
elements. Label the section with a preceding \`## Key changes\` \`RichText\` heading
|
|
2262
|
-
rather than a \`title\` on the block.
|
|
2263
|
-
|
|
2264
|
-
\`\`\`mdx
|
|
2265
|
-
<TabsBlock
|
|
2266
|
-
id="tabs-key"
|
|
2267
|
-
orientation="vertical"
|
|
2268
|
-
tabs={[
|
|
2269
|
-
{ id: "t-route", label: "routes/tasks.ts", blocks: [ /* Diff block objects */ ] },
|
|
2270
|
-
{ id: "t-schema", label: "db/schema.ts", blocks: [ /* Diff block objects */ ] }
|
|
2271
|
-
]}
|
|
2272
|
-
/>
|
|
2273
|
-
\`\`\`
|
|
2274
|
-
|
|
2275
|
-
### \`WireframeBlock\` + \`<Screen>\` (UI)
|
|
2276
|
-
|
|
2277
|
-
Tag is \`WireframeBlock\`; its body is a single \`<Screen surface ... >\` subtree
|
|
2278
|
-
(this is nested MDX, not a flat prop). On \`<Screen>\`, \`html\` must be a
|
|
2279
|
-
single-quoted string or a static template literal — NEVER a dynamic expression
|
|
2280
|
-
(\`html={someVar}\` throws on import). \`surface\` ∈
|
|
2281
|
-
\`desktop | mobile | popover | panel | browser\`. Optional \`<Screen>\` attrs:
|
|
2282
|
-
\`renderMode\` (\`wireframe | design\`), \`caption\`, \`css\`, \`skeleton\`. See the
|
|
2283
|
-
Wireframe Quality core above for the HTML rules.
|
|
2284
|
-
|
|
2285
|
-
\`\`\`mdx
|
|
2286
|
-
<WireframeBlock id="wf-tasks">
|
|
2287
|
-
<Screen surface="browser" html={'<div style="display:flex;flex-direction:column;gap:12px;padding:16px;height:100%"><h1>Tasks</h1><button class="primary">New task</button></div>'} />
|
|
2288
|
-
</WireframeBlock>
|
|
2289
|
-
\`\`\`
|
|
2290
|
-
|
|
2291
|
-
### Other blocks
|
|
2292
|
-
|
|
2293
|
-
- \`HtmlBlock\` (custom-html) — flat attrs \`html\` (required, bounded fragment),
|
|
2294
|
-
\`css?\`, \`caption?\`. Prefer a wireframe for UI; this is an escape hatch.
|
|
2295
|
-
- \`Table\` — flat attrs \`columns={["A","B"]}\` and \`rows={[["1","2"]]}\` (both arrays
|
|
2296
|
-
of strings), optional \`density\` (\`compact | normal | relaxed\`).
|
|
2297
|
-
- \`Checklist\` — flat attr \`items={[{ id, label, checked?, note? }]}\`.
|
|
2298
|
-
- \`Code\` — flat attrs \`code\` (required string), \`language?\`, \`filename?\`,
|
|
2299
|
-
\`caption?\`, \`maxLines?\`. For a multi-file rail use a \`TabsBlock\` of \`Code\`
|
|
2300
|
-
blocks.
|
|
2301
|
-
- \`OpenApi\` — flat attrs \`spec\` (required JSON string of a whole OpenAPI/Swagger
|
|
2302
|
-
doc), \`title?\`. The whole-document counterpart to \`Endpoint\`.
|
|
1505
|
+
## Block reference — call \`get-plan-blocks\`, do not memorize tags
|
|
1506
|
+
|
|
1507
|
+
The conceptual block names above (\`api-endpoint\`, \`data-model\`, \`json-explorer\`,
|
|
1508
|
+
\`tabs\`, …) are NOT the JSX tags you author with, and the exact tags, required
|
|
1509
|
+
fields, and prop shapes change as the block library evolves. Do not author from
|
|
1510
|
+
memorized tags — they drift and silently produce a wrong tag (\`ApiEndpoint\`
|
|
1511
|
+
instead of \`Endpoint\`, \`JsonExplorer\` instead of \`Json\`, \`Tabs\` instead of
|
|
1512
|
+
\`TabsBlock\`) that errors on import.
|
|
1513
|
+
|
|
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
|
|
1517
|
+
vocabulary generated live from the app's own block registry — the same config
|
|
1518
|
+
the renderer and MDX round-trip use — so it can never be stale even if this
|
|
1519
|
+
SKILL.md is an old installed copy:
|
|
1520
|
+
|
|
1521
|
+
- \`get-plan-blocks\` (default \`format: "reference"\`) → a compact table of every
|
|
1522
|
+
block's runtime \`type\`, exact MDX \`<Tag>\`, placement, and key data fields.
|
|
1523
|
+
This is your map from each conceptual name above to its real tag and props.
|
|
1524
|
+
- \`get-plan-blocks\` with \`format: "schema"\` → the full per-block JSON Schema
|
|
1525
|
+
plus a worked example for each block, when you need exact field types,
|
|
1526
|
+
enums, or nesting (e.g. \`Diff.annotations\`, \`Endpoint.params[].in\`,
|
|
1527
|
+
\`DataModel.entities[].fields[]\`).
|
|
1528
|
+
|
|
1529
|
+
Author the recap source against the tags and schemas that call returns. The
|
|
1530
|
+
complete set of valid block-level tags is whatever \`get-plan-blocks\` lists;
|
|
1531
|
+
any other capitalized tag at the block level is rejected on import with an
|
|
1532
|
+
"Unknown plan block" / "did you mean" error. Lowercase HTML tags inside
|
|
1533
|
+
\`rich-text\`/markdown prose (\`<div>\`, \`<span>\`, \`<code>\`, \`<br>\`, …) are always
|
|
1534
|
+
fine — only capitalized component-style block tags are validated.
|
|
1535
|
+
|
|
1536
|
+
A few recap-specific authoring rules the registry table cannot encode:
|
|
1537
|
+
|
|
1538
|
+
- Every block takes a REQUIRED \`id\` (unique across the whole plan) plus the
|
|
1539
|
+
shared optional \`summary\` / \`editable\` envelope; give a block a heading by
|
|
1540
|
+
placing a \`rich-text\` block with a Markdown \`###\` heading directly above it
|
|
1541
|
+
(blocks no longer take a \`title\`).
|
|
1542
|
+
- \`Endpoint\`: prose \`description\` is the MDX **children** (body between the
|
|
1543
|
+
tags), not an attribute; for a WebSocket upgrade use \`method="GET"\`. Each
|
|
1544
|
+
request/response \`example\` is a JSON **string** (the renderer parses it into
|
|
1545
|
+
the JSON explorer), so keep it a single parseable JSON value.
|
|
1546
|
+
- \`TabsBlock\`: the whole \`tabs\` array (including nested child blocks) is ONE
|
|
1547
|
+
JSON \`tabs={[…]}\` prop — there is NO nested \`<Tab>\` element.
|
|
1548
|
+
- \`WireframeBlock\`: its body is a single \`<Screen surface ... html=… />\` subtree
|
|
1549
|
+
(nested MDX, not a flat prop); \`html\` must be a single-quoted string or static
|
|
1550
|
+
template literal, never a dynamic \`html={someVar}\` expression. See the
|
|
1551
|
+
Wireframe Quality core above for the HTML rules.
|
|
1552
|
+
- \`Diagram\`: the whole payload is one \`data={{ html?, css?, nodes?, edges?, … }}\`
|
|
1553
|
+
attribute and requires either \`html\` or at least one node; \`Mermaid\` is its
|
|
1554
|
+
own separate block (\`source\` text), not a \`Diagram\` prop.
|
|
2303
1555
|
|
|
2304
1556
|
## Before / After Is The Headline
|
|
2305
1557
|
|
|
@@ -2313,16 +1565,19 @@ comparisons there are two primitives, and they cover the whole need together:
|
|
|
2313
1565
|
"the schema went from X to Y" or "the endpoint contract changed like this."
|
|
2314
1566
|
Do not use \`columns\` simply to compact or group a list of API endpoints.
|
|
2315
1567
|
- **\`diff\`** — for **code**. It renders the literal removed and added lines. Use
|
|
2316
|
-
it for the actual hunks.
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
split
|
|
1568
|
+
it for the actual hunks. Use split mode by default for recap code review;
|
|
1569
|
+
reserve \`mode: "unified"\` for genuinely narrow standalone hunks where
|
|
1570
|
+
side-by-side would hide the code. Key-file diff groups should use horizontal
|
|
1571
|
+
tabs so split diffs get the full document width.
|
|
2320
1572
|
|
|
2321
1573
|
For UI diffs, wireframes are the visual comparison primitive. Use before/after
|
|
2322
1574
|
wireframes when the comparison clarifies the change; use after-only or a state
|
|
2323
1575
|
sequence when that better matches the change. The visual headline must show
|
|
2324
1576
|
exact placement, realistic chrome, and adequate padding before any abstract
|
|
2325
|
-
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 —
|
|
2326
1581
|
the \`columns\` renderer keeps narrow surfaces side by side and auto-stacks wide
|
|
2327
1582
|
\`desktop\`/\`browser\` frames vertically; never hand-build a side-by-side
|
|
2328
1583
|
wireframe layout in \`custom-html\`. For document-body
|
|
@@ -2356,15 +1611,19 @@ inferred (not extracted) as inferred in prose.
|
|
|
2356
1611
|
hardcoded-secret rule: obviously fake placeholders only, never the real value,
|
|
2357
1612
|
in any block, caption, or note.
|
|
2358
1613
|
|
|
2359
|
-
## Bidirectional Loop
|
|
1614
|
+
## Bidirectional Loop
|
|
2360
1615
|
|
|
2361
1616
|
Because a recap is a real, editable plan, the same review loop as forward plans
|
|
2362
1617
|
applies: a reviewer can annotate any block, and the coding agent reads
|
|
2363
1618
|
\`get-plan-feedback\` to drive fixes back into the code — annotation → agent →
|
|
2364
|
-
diff, the same close-the-loop flow forward plans use.
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
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.
|
|
2368
1627
|
|
|
2369
1628
|
## Related Skills
|
|
2370
1629
|
|
|
@@ -2375,143 +1634,6 @@ blocks are anchorable and the loop drops in later without restructuring.
|
|
|
2375
1634
|
recap's redaction and visibility gating mirror.
|
|
2376
1635
|
- **sharing** — org/login-gated visibility for the plan that holds the recap.
|
|
2377
1636
|
`;
|
|
2378
|
-
export const VISUAL_QUESTIONS_SKILL_MD = `---
|
|
2379
|
-
name: visual-questions
|
|
2380
|
-
description: >-
|
|
2381
|
-
Use Agent-Native Plans to ask rich visual intake questions when
|
|
2382
|
-
/visual-questions is explicitly requested before creating a UI plan or visual
|
|
2383
|
-
plan.
|
|
2384
|
-
metadata:
|
|
2385
|
-
visibility: both
|
|
2386
|
-
---
|
|
2387
|
-
|
|
2388
|
-
# Visual Questions
|
|
2389
|
-
|
|
2390
|
-
Use \`/visual-questions\` when the next best step is not a plan yet, but a
|
|
2391
|
-
reviewable visual intake: single-choice option rows, multi-select option rows,
|
|
2392
|
-
freeform notes, mockup choices, sketch diagrams, and a generated answer summary
|
|
2393
|
-
that feeds the next planning prompt. It composes with \`/visual-plan\`, \`/ui-plan\`,
|
|
2394
|
-
\`/prototype-plan\`, and \`/plan-design\`.
|
|
2395
|
-
|
|
2396
|
-
## When To Use
|
|
2397
|
-
|
|
2398
|
-
- The user asks to be shown options before the agent writes a plan.
|
|
2399
|
-
- UI direction, form factor, layout model, feature set, or visual style is fuzzy
|
|
2400
|
-
enough that 2-6 answers would materially change the plan.
|
|
2401
|
-
- The user would benefit from choosing between visual mockups or diagrams rather
|
|
2402
|
-
than answering text-only prompts.
|
|
2403
|
-
|
|
2404
|
-
Gate hard: skip this for tiny, unambiguous changes. If the agent can reasonably
|
|
2405
|
-
infer the answer, prefer \`/ui-plan\`, \`/prototype-plan\`, \`/plan-design\`, or
|
|
2406
|
-
\`/visual-plan\` directly and put assumptions in the plan.
|
|
2407
|
-
|
|
2408
|
-
Visual questions are an explicit intake command, not an automatic preflight for
|
|
2409
|
-
\`/visual-plan\`, \`/ui-plan\`, \`/prototype-plan\`, or \`/plan-design\`.
|
|
2410
|
-
|
|
2411
|
-
## Workflow
|
|
2412
|
-
|
|
2413
|
-
1. Call \`create-visual-questions\` with a clear title, brief, source, and repo
|
|
2414
|
-
path when known.
|
|
2415
|
-
2. Omit \`questions\` for the default UI intake. Provide a custom \`questions\` array
|
|
2416
|
-
only when the task has domain-specific choices.
|
|
2417
|
-
3. Surface the returned Plans link and ask the user to answer visually.
|
|
2418
|
-
4. The generated summary drives the next step: \`create-ui-plan\` for static UI
|
|
2419
|
-
review, \`create-prototype-plan\` for click-through UI flows,
|
|
2420
|
-
\`create-plan-design\` for high-fidelity branded UI review,
|
|
2421
|
-
\`create-visual-plan\` for general plans or when a text plan already exists,
|
|
2422
|
-
or \`update-visual-plan\` with targeted \`contentPatches\` to fold answers into
|
|
2423
|
-
an active plan.
|
|
2424
|
-
5. If the user leaves comments, call \`get-plan-feedback\` before using the answers.
|
|
2425
|
-
|
|
2426
|
-
## Question Types
|
|
2427
|
-
|
|
2428
|
-
Supported \`questions\` entries:
|
|
2429
|
-
|
|
2430
|
-
- \`single\`: chip group where one option wins.
|
|
2431
|
-
- \`multi\`: chip group where multiple options can be selected.
|
|
2432
|
-
- \`freeform\`: textarea for constraints, inspirations, or things to avoid.
|
|
2433
|
-
- \`visual\`: visual options with sketch previews — use for layout direction, flow
|
|
2434
|
-
depth, surface choice, or diagram choices.
|
|
2435
|
-
|
|
2436
|
-
Each option can include \`label\`, \`value\`, \`description\`, \`recommended\`,
|
|
2437
|
-
\`preview\`, and \`bullets\`. Valid \`preview\` values match the wireframe surfaces:
|
|
2438
|
-
\`desktop\`, \`mobile\`, \`popover\`, \`panel\`, \`component\`, \`split\`, \`flow\`, and
|
|
2439
|
-
\`diagram\`. Pick the preview that matches the real footprint — do not offer a
|
|
2440
|
-
desktop/mobile pair for a popover, panel, or component.
|
|
2441
|
-
|
|
2442
|
-
\`single\`, \`multi\`, and \`visual\` questions always render a write-in field, so a
|
|
2443
|
-
reviewer can answer with their own option instead of the listed choices. Do not
|
|
2444
|
-
add an explicit "Other" or "Something else" option yourself; set
|
|
2445
|
-
\`allowOther: false\` only on the rare question where a free-text answer makes no
|
|
2446
|
-
sense.
|
|
2447
|
-
|
|
2448
|
-
## Quality Bar
|
|
2449
|
-
|
|
2450
|
-
- Ask only decision-changing questions. A beautiful form with low-value questions
|
|
2451
|
-
is still friction.
|
|
2452
|
-
- Prefer visible, answerable options over abstract prose.
|
|
2453
|
-
- Use visual tabs when users need to compare layout or flow shapes.
|
|
2454
|
-
- Keep the output calm and document-like, not a landing page.
|
|
2455
|
-
- The generated answer summary is not the final plan; it is the intake prompt for
|
|
2456
|
-
the next agent step.
|
|
2457
|
-
|
|
2458
|
-
## Tool Guidance
|
|
2459
|
-
|
|
2460
|
-
- \`create-visual-questions\`: create the interactive intake plan.
|
|
2461
|
-
- \`get-visual-plan\`: inspect the current visual question plan.
|
|
2462
|
-
- \`get-plan-feedback\`: read comments before creating or updating the next plan.
|
|
2463
|
-
- \`create-ui-plan\`: create a UI-first plan from the answers.
|
|
2464
|
-
- \`create-prototype-plan\`: create a prototype-first plan from the answers when
|
|
2465
|
-
interaction feel matters.
|
|
2466
|
-
- \`create-plan-design\`: create a high-fidelity branded design plan from the
|
|
2467
|
-
answers when visual polish is the primary review input.
|
|
2468
|
-
- \`create-visual-plan\`: create a general visual plan from the answers, or pass
|
|
2469
|
-
existing plan text as \`planText\` when the answers should shape an imported
|
|
2470
|
-
plan.
|
|
2471
|
-
- \`export-visual-plan\`: export answer plans as HTML, Markdown fallback,
|
|
2472
|
-
structured JSON, and MDX files when the intake needs to be checked into a repo.
|
|
2473
|
-
- \`read-visual-plan-source\` / \`patch-visual-plan-source\`: inspect or patch the
|
|
2474
|
-
MDX source if another agent is operating from checked-in plan files.
|
|
2475
|
-
|
|
2476
|
-
## Setup & Authentication
|
|
2477
|
-
|
|
2478
|
-
There are two ways into Plans.
|
|
2479
|
-
|
|
2480
|
-
**Coding agent (CLI).** Install once with the Agent-Native CLI. The command
|
|
2481
|
-
installs the Plans skills, registers the hosted Plans MCP connector, and
|
|
2482
|
-
authenticates it in the same step (a one-time browser sign-in at setup — this is
|
|
2483
|
-
intended), so the first tool call does not hit an OAuth wall:
|
|
2484
|
-
|
|
2485
|
-
\`\`\`bash
|
|
2486
|
-
agent-native skills add visual-plan
|
|
2487
|
-
\`\`\`
|
|
2488
|
-
|
|
2489
|
-
After that, \`/visual-plan\` (and \`/visual-recap\`, \`/ui-plan\`,
|
|
2490
|
-
\`/prototype-plan\`, \`/plan-design\`, \`/visual-questions\`) generate a plan and open
|
|
2491
|
-
the editor. Pass \`--no-connect\` to
|
|
2492
|
-
register the connector without authenticating, then run
|
|
2493
|
-
\`agent-native connect https://plan.agent-native.com\` whenever you are ready.
|
|
2494
|
-
|
|
2495
|
-
**Browser (people you share with).** Open the Plans editor and create & edit
|
|
2496
|
-
with no sign-up — you work as a guest. Sign in only when you want to save or
|
|
2497
|
-
share; signing in claims the plans you made as a guest into your account.
|
|
2498
|
-
|
|
2499
|
-
Sharing and commenting require an account: public/shared plans are viewable by
|
|
2500
|
-
anyone with the link, but commenting on them needs an agent-native account.
|
|
2501
|
-
|
|
2502
|
-
For fully offline, no-account use, run the Plans app locally and sync plans to
|
|
2503
|
-
your repo as MDX. This local mode is a separate advanced path, not the default
|
|
2504
|
-
hosted flow.
|
|
2505
|
-
|
|
2506
|
-
If a Plans tool returns \`needs auth\`, \`Unauthorized\`, or \`Session terminated\`,
|
|
2507
|
-
do not keep retrying the tool. Authenticate the connector with
|
|
2508
|
-
\`agent-native connect https://plan.agent-native.com\` (OAuth-capable hosts can
|
|
2509
|
-
instead re-run /mcp and choose Authenticate), then continue once the connector
|
|
2510
|
-
is available.
|
|
2511
|
-
|
|
2512
|
-
Hosted default: connect \`https://plan.agent-native.com/_agent-native/mcp\`. Do
|
|
2513
|
-
not put shared secrets in skill files.
|
|
2514
|
-
`;
|
|
2515
1637
|
export const BUILT_IN_APP_SKILLS = {
|
|
2516
1638
|
assets: {
|
|
2517
1639
|
skillName: "assets",
|
|
@@ -2603,10 +1725,19 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
2603
1725
|
skillName: "visual-plan",
|
|
2604
1726
|
extraSkills: {
|
|
2605
1727
|
"visual-recap": VISUAL_RECAP_SKILL_MD,
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
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 },
|
|
2610
1741
|
},
|
|
2611
1742
|
manifest: normalizeAppSkillManifest({
|
|
2612
1743
|
schemaVersion: 1,
|
|
@@ -2617,10 +1748,10 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
2617
1748
|
url: "https://plan.agent-native.com",
|
|
2618
1749
|
mcpUrl: "https://plan.agent-native.com/_agent-native/mcp",
|
|
2619
1750
|
},
|
|
2620
|
-
mcp: { serverName: "agent-native-plans" },
|
|
1751
|
+
mcp: { serverName: "plan", aliases: ["agent-native-plans"] },
|
|
2621
1752
|
auth: {
|
|
2622
1753
|
mode: "oauth",
|
|
2623
|
-
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.",
|
|
2624
1755
|
},
|
|
2625
1756
|
surfaces: [
|
|
2626
1757
|
{
|
|
@@ -2635,30 +1766,6 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
2635
1766
|
path: "/plans",
|
|
2636
1767
|
description: "Create a visual recap plan from a PR, commit, branch, or git diff for high-altitude review.",
|
|
2637
1768
|
},
|
|
2638
|
-
{
|
|
2639
|
-
id: "ui-plan",
|
|
2640
|
-
action: "create-ui-plan",
|
|
2641
|
-
path: "/plans",
|
|
2642
|
-
description: "Create a UI-first Agent-Native plan with an optional top pan/zoom wireframe canvas and a refined rich document below.",
|
|
2643
|
-
},
|
|
2644
|
-
{
|
|
2645
|
-
id: "prototype-plan",
|
|
2646
|
-
action: "create-prototype-plan",
|
|
2647
|
-
path: "/plans",
|
|
2648
|
-
description: "Create a prototype-first Agent-Native plan with a functional live prototype above the document.",
|
|
2649
|
-
},
|
|
2650
|
-
{
|
|
2651
|
-
id: "plan-design",
|
|
2652
|
-
action: "create-plan-design",
|
|
2653
|
-
path: "/plans",
|
|
2654
|
-
description: "Create a full-fidelity Agent-Native design plan with a Design canvas tab and optional matching Prototype tab.",
|
|
2655
|
-
},
|
|
2656
|
-
{
|
|
2657
|
-
id: "visual-questions",
|
|
2658
|
-
action: "create-visual-questions",
|
|
2659
|
-
path: "/plans",
|
|
2660
|
-
description: "Create a rich visual intake questionnaire for explicit /visual-questions workflows.",
|
|
2661
|
-
},
|
|
2662
1769
|
],
|
|
2663
1770
|
skills: [
|
|
2664
1771
|
{
|
|
@@ -2671,26 +1778,6 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
2671
1778
|
visibility: "exported",
|
|
2672
1779
|
exportAs: "visual-recap",
|
|
2673
1780
|
},
|
|
2674
|
-
{
|
|
2675
|
-
path: "skills/visual-questions",
|
|
2676
|
-
visibility: "exported",
|
|
2677
|
-
exportAs: "visual-questions",
|
|
2678
|
-
},
|
|
2679
|
-
{
|
|
2680
|
-
path: "skills/ui-plan",
|
|
2681
|
-
visibility: "exported",
|
|
2682
|
-
exportAs: "ui-plan",
|
|
2683
|
-
},
|
|
2684
|
-
{
|
|
2685
|
-
path: "skills/prototype-plan",
|
|
2686
|
-
visibility: "exported",
|
|
2687
|
-
exportAs: "prototype-plan",
|
|
2688
|
-
},
|
|
2689
|
-
{
|
|
2690
|
-
path: "skills/plan-design",
|
|
2691
|
-
visibility: "exported",
|
|
2692
|
-
exportAs: "plan-design",
|
|
2693
|
-
},
|
|
2694
1781
|
],
|
|
2695
1782
|
hostAdapters: [
|
|
2696
1783
|
"codex-plugin",
|
|
@@ -2736,6 +1823,7 @@ export const BUILT_IN_APP_SKILLS = {
|
|
|
2736
1823
|
skillMarkdown: CONTEXT_XRAY_SKILL_MD,
|
|
2737
1824
|
},
|
|
2738
1825
|
};
|
|
1826
|
+
export const AGENT_NATIVE_SKILL_METADATA_FILE = "agent-native-skill.json";
|
|
2739
1827
|
const BUILT_IN_APP_SKILL_ALIASES = {
|
|
2740
1828
|
assets: "assets",
|
|
2741
1829
|
asset: "assets",
|
|
@@ -2758,13 +1846,6 @@ const BUILT_IN_APP_SKILL_ALIASES = {
|
|
|
2758
1846
|
"visual-recaps": "visual-plans",
|
|
2759
1847
|
"code-review-recap": "visual-plans",
|
|
2760
1848
|
"code-review-recaps": "visual-plans",
|
|
2761
|
-
"ui-plan": "visual-plans",
|
|
2762
|
-
"prototype-plan": "visual-plans",
|
|
2763
|
-
"plan-design": "visual-plans",
|
|
2764
|
-
"plan-designs": "visual-plans",
|
|
2765
|
-
"design-plan": "visual-plans",
|
|
2766
|
-
"design-plans": "visual-plans",
|
|
2767
|
-
"visual-questions": "visual-plans",
|
|
2768
1849
|
"html-plan": "visual-plans",
|
|
2769
1850
|
"plan-mode": "visual-plans",
|
|
2770
1851
|
plannotate: "visual-plans",
|
|
@@ -2788,10 +1869,6 @@ const BUILT_IN_APP_SKILL_DISPLAY_ALIASES = {
|
|
|
2788
1869
|
"visual-plan",
|
|
2789
1870
|
"visual-recap",
|
|
2790
1871
|
"code-review-recap",
|
|
2791
|
-
"ui-plan",
|
|
2792
|
-
"prototype-plan",
|
|
2793
|
-
"plan-design",
|
|
2794
|
-
"visual-questions",
|
|
2795
1872
|
"html-plan",
|
|
2796
1873
|
"plannotate",
|
|
2797
1874
|
],
|
|
@@ -2824,9 +1901,243 @@ function isLocalOnlyBuiltInSkill(entry) {
|
|
|
2824
1901
|
function builtInExtraSkills(entry) {
|
|
2825
1902
|
return "extraSkills" in entry && entry.extraSkills ? entry.extraSkills : {};
|
|
2826
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
|
+
}
|
|
2827
1911
|
function builtInSkillNames(entry) {
|
|
2828
1912
|
return [entry.skillName, ...Object.keys(builtInExtraSkills(entry))];
|
|
2829
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
|
+
}
|
|
2830
2141
|
function normalizeClientIds(values) {
|
|
2831
2142
|
if (!Array.isArray(values))
|
|
2832
2143
|
return [];
|
|
@@ -2860,6 +2171,31 @@ function skillPromptOptions() {
|
|
|
2860
2171
|
hint: entry.manifest.description,
|
|
2861
2172
|
}));
|
|
2862
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
|
+
}
|
|
2863
2199
|
function shouldPrompt(parsed, options) {
|
|
2864
2200
|
if (parsed.yes || parsed.printJson)
|
|
2865
2201
|
return false;
|
|
@@ -2944,7 +2280,10 @@ export function parseSkillsArgs(argv) {
|
|
|
2944
2280
|
command = "help";
|
|
2945
2281
|
args = argv.slice(1);
|
|
2946
2282
|
}
|
|
2947
|
-
else if (first === "list" ||
|
|
2283
|
+
else if (first === "list" ||
|
|
2284
|
+
first === "add" ||
|
|
2285
|
+
first === "status" ||
|
|
2286
|
+
first === "update") {
|
|
2948
2287
|
command = first;
|
|
2949
2288
|
args = argv.slice(1);
|
|
2950
2289
|
}
|
|
@@ -2956,6 +2295,7 @@ export function parseSkillsArgs(argv) {
|
|
|
2956
2295
|
client: "codex",
|
|
2957
2296
|
clientExplicit: false,
|
|
2958
2297
|
scope: "user",
|
|
2298
|
+
scopeExplicit: false,
|
|
2959
2299
|
yes: false,
|
|
2960
2300
|
dryRun: false,
|
|
2961
2301
|
printJson: false,
|
|
@@ -2986,8 +2326,10 @@ export function parseSkillsArgs(argv) {
|
|
|
2986
2326
|
out.client = value;
|
|
2987
2327
|
out.clientExplicit = true;
|
|
2988
2328
|
}
|
|
2989
|
-
else if ((value = eat("--scope")) !== undefined)
|
|
2329
|
+
else if ((value = eat("--scope")) !== undefined) {
|
|
2990
2330
|
out.scope = value;
|
|
2331
|
+
out.scopeExplicit = true;
|
|
2332
|
+
}
|
|
2991
2333
|
else if ((value = eat("--mcp-url")) !== undefined)
|
|
2992
2334
|
out.mcpUrl = value;
|
|
2993
2335
|
else if (arg === "--yes" || arg === "-y")
|
|
@@ -3031,14 +2373,9 @@ function loadSkillTarget(target) {
|
|
|
3031
2373
|
},
|
|
3032
2374
|
skillNames,
|
|
3033
2375
|
materializeInstructions(outDir) {
|
|
3034
|
-
const
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
};
|
|
3038
|
-
for (const [skillName, skillMarkdown] of Object.entries(skills)) {
|
|
3039
|
-
const skillDir = path.join(outDir, "skills", skillName);
|
|
3040
|
-
fs.mkdirSync(skillDir, { recursive: true });
|
|
3041
|
-
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);
|
|
3042
2379
|
}
|
|
3043
2380
|
return outDir;
|
|
3044
2381
|
},
|
|
@@ -3136,6 +2473,8 @@ function dryRunInstallCommand(parsed, target) {
|
|
|
3136
2473
|
args.push("--mcp-only");
|
|
3137
2474
|
if (!parsed.connect)
|
|
3138
2475
|
args.push("--no-connect");
|
|
2476
|
+
if (parsed.withGithubAction)
|
|
2477
|
+
args.push("--with-github-action");
|
|
3139
2478
|
if (parsed.yes || isKnownSkill(target))
|
|
3140
2479
|
args.push("--yes");
|
|
3141
2480
|
return commandString("agent-native", args);
|
|
@@ -3292,6 +2631,9 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3292
2631
|
const clients = parsed.clients ?? resolveClients(parsed.client);
|
|
3293
2632
|
const skillsAgents = skillsAgentsForClients(clients);
|
|
3294
2633
|
if (parsed.dryRun) {
|
|
2634
|
+
const githubActionPath = parsed.withGithubAction && knownTarget === "visual-plans"
|
|
2635
|
+
? prVisualRecapWorkflowDisplayPath()
|
|
2636
|
+
: undefined;
|
|
3295
2637
|
return {
|
|
3296
2638
|
id: knownBuiltIn.manifest.id,
|
|
3297
2639
|
displayName: knownBuiltIn.manifest.displayName,
|
|
@@ -3302,6 +2644,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3302
2644
|
dryRun: true,
|
|
3303
2645
|
local: true,
|
|
3304
2646
|
commands: [dryRunInstallCommand(parsed, target)],
|
|
2647
|
+
githubActionPath,
|
|
3305
2648
|
};
|
|
3306
2649
|
}
|
|
3307
2650
|
const localInstall = installLocalContextXray({
|
|
@@ -3333,6 +2676,12 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3333
2676
|
const skillsAgents = skillsAgentsForClients(clients);
|
|
3334
2677
|
if (parsed.dryRun) {
|
|
3335
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;
|
|
3336
2685
|
return {
|
|
3337
2686
|
id: installTarget.id,
|
|
3338
2687
|
displayName: installTarget.displayName,
|
|
@@ -3342,6 +2691,8 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3342
2691
|
mcpClients: clients,
|
|
3343
2692
|
dryRun: true,
|
|
3344
2693
|
commands: [dryRunInstallCommand(parsed, target)],
|
|
2694
|
+
githubActionPath,
|
|
2695
|
+
githubActionSuggestedCommand,
|
|
3345
2696
|
};
|
|
3346
2697
|
}
|
|
3347
2698
|
finally {
|
|
@@ -3409,14 +2760,32 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3409
2760
|
}
|
|
3410
2761
|
// `--with-github-action`: also drop the PR Visual Recap workflow into the
|
|
3411
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);
|
|
3412
2765
|
let githubActionPath;
|
|
3413
2766
|
let githubActionExisted;
|
|
3414
|
-
|
|
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) {
|
|
3415
2784
|
if (knownTarget !== "visual-plans") {
|
|
3416
2785
|
options.log?.("--with-github-action only applies to the visual-plan skill; skipping the workflow.");
|
|
3417
2786
|
}
|
|
3418
2787
|
else {
|
|
3419
|
-
const written = writePrVisualRecapWorkflow(
|
|
2788
|
+
const written = writePrVisualRecapWorkflow(baseDir);
|
|
3420
2789
|
githubActionPath = written.path;
|
|
3421
2790
|
githubActionExisted = written.existed;
|
|
3422
2791
|
commands.push(`write ${written.path}`);
|
|
@@ -3436,6 +2805,7 @@ export async function addAgentNativeSkill(parsed, options = {}) {
|
|
|
3436
2805
|
connectCommand,
|
|
3437
2806
|
githubActionPath,
|
|
3438
2807
|
githubActionExisted,
|
|
2808
|
+
githubActionSuggestedCommand,
|
|
3439
2809
|
};
|
|
3440
2810
|
}
|
|
3441
2811
|
finally {
|
|
@@ -3453,6 +2823,68 @@ function listSkills() {
|
|
|
3453
2823
|
local: isLocalOnlyBuiltInSkill(entry),
|
|
3454
2824
|
}));
|
|
3455
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
|
+
}
|
|
3456
2888
|
export async function runSkills(argv, options = {}) {
|
|
3457
2889
|
const parsed = parseSkillsArgs(argv);
|
|
3458
2890
|
const log = parsed.printJson
|
|
@@ -3478,6 +2910,10 @@ export async function runSkills(argv, options = {}) {
|
|
|
3478
2910
|
}
|
|
3479
2911
|
return;
|
|
3480
2912
|
}
|
|
2913
|
+
if (parsed.command === "status" || parsed.command === "update") {
|
|
2914
|
+
runSkillsStatusOrUpdate(parsed, options, parsed.command === "update");
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
3481
2917
|
const targets = await resolveSkillTargets(parsed, options);
|
|
3482
2918
|
if (!targets)
|
|
3483
2919
|
return;
|
|
@@ -3536,7 +2972,15 @@ export async function runSkills(argv, options = {}) {
|
|
|
3536
2972
|
.filter((p) => Boolean(p))),
|
|
3537
2973
|
];
|
|
3538
2974
|
const githubActionLine = githubActions.length
|
|
3539
|
-
? `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.`
|
|
3540
2984
|
: "";
|
|
3541
2985
|
process.stdout.write([
|
|
3542
2986
|
`Installed ${installedNames} skill${results.length === 1 ? "" : "s"}.`,
|
|
@@ -3551,6 +2995,7 @@ export async function runSkills(argv, options = {}) {
|
|
|
3551
2995
|
: "",
|
|
3552
2996
|
authLine,
|
|
3553
2997
|
githubActionLine,
|
|
2998
|
+
githubActionSuggestionLine,
|
|
3554
2999
|
localCommands.length ? `Local command: ${localCommands.join(", ")}.` : "",
|
|
3555
3000
|
"Restart or reload selected agent clients if the skill is not visible yet.",
|
|
3556
3001
|
parsed.clientExplicit
|