@agent-native/core 0.84.53 → 0.84.54
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +7 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/skills.ts +34 -16
- package/corpus/core/src/client/AssistantChat.tsx +140 -114
- package/corpus/core/src/client/blocks/library/diagram.config.ts +13 -2
- package/corpus/core/src/client/blocks/library/diagram.tsx +27 -3
- package/corpus/core/src/client/blocks/library/server-specs.ts +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.config.ts +7 -1
- package/corpus/core/src/client/blocks/library/wireframe.tsx +42 -3
- package/corpus/core/src/client/blocks/types.ts +9 -0
- package/corpus/core/src/client/chat/message-components.tsx +1 -1
- package/corpus/core/src/styles/agent-native.css +44 -0
- package/corpus/core/src/styles/blocks.css +18 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/references/document-quality.md +10 -6
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +20 -9
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +4 -1
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +20 -9
- package/corpus/templates/plan/actions/create-ui-plan.ts +1 -1
- package/corpus/templates/plan/actions/create-visual-plan.ts +1 -1
- package/corpus/templates/plan/actions/create-visual-recap.ts +1 -1
- package/corpus/templates/plan/actions/get-plan-blocks.ts +2 -0
- package/corpus/templates/plan/app/components/plan/planBlocks.tsx +2 -0
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +38 -4
- package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +18 -0
- package/corpus/templates/plan/app/global.css +1 -2
- package/corpus/templates/plan/changelog/2026-07-02-plan-chat-keeps-the-composer-anchored-when-connect-ai-appears.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-02-wireframe-and-diagram-blocks-can-now-show-or-hide-their-outer-frame.md +6 -0
- package/corpus/templates/plan/server/plan-mdx.ts +3 -0
- package/corpus/templates/plan/shared/plan-content.ts +8 -0
- package/dist/cli/skills.d.ts +3 -3
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +34 -16
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +32 -25
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/blocks/library/diagram.config.d.ts +3 -1
- package/dist/client/blocks/library/diagram.config.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.config.js +10 -1
- package/dist/client/blocks/library/diagram.config.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +13 -7
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/server-specs.js +2 -2
- package/dist/client/blocks/library/server-specs.js.map +1 -1
- package/dist/client/blocks/library/wireframe.config.d.ts +3 -1
- package/dist/client/blocks/library/wireframe.config.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.config.js +4 -0
- package/dist/client/blocks/library/wireframe.config.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +20 -9
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/blocks/types.d.ts +8 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-native.css +44 -0
- package/dist/styles/blocks.css +18 -0
- package/package.json +1 -1
|
@@ -113,6 +113,7 @@ function ArtboardFrame({
|
|
|
113
113
|
skeleton,
|
|
114
114
|
renderMode,
|
|
115
115
|
roughOverlay = true,
|
|
116
|
+
showFrame = true,
|
|
116
117
|
selector,
|
|
117
118
|
caption,
|
|
118
119
|
render,
|
|
@@ -129,6 +130,7 @@ function ArtboardFrame({
|
|
|
129
130
|
skeleton?: boolean;
|
|
130
131
|
renderMode?: "wireframe" | "design";
|
|
131
132
|
roughOverlay?: boolean;
|
|
133
|
+
showFrame?: boolean;
|
|
132
134
|
selector: string;
|
|
133
135
|
caption?: string;
|
|
134
136
|
render: (ctx: {
|
|
@@ -164,6 +166,9 @@ function ArtboardFrame({
|
|
|
164
166
|
const designMode = renderMode === "design";
|
|
165
167
|
const sketchy = !designMode && style === "sketchy" && !skeleton;
|
|
166
168
|
const roughEnabled = sketchy && roughOverlay;
|
|
169
|
+
const frameBorder = skeleton
|
|
170
|
+
? "var(--plan-placeholder-line, var(--plan-line, hsl(var(--border))))"
|
|
171
|
+
: "var(--plan-line, hsl(var(--border)))";
|
|
167
172
|
|
|
168
173
|
useEffect(() => {
|
|
169
174
|
const element = fitRef.current;
|
|
@@ -231,6 +236,7 @@ function ArtboardFrame({
|
|
|
231
236
|
ref={ref}
|
|
232
237
|
className="plan-kit-artboard relative"
|
|
233
238
|
data-rough-scope="wireframe"
|
|
239
|
+
data-frame={showFrame ? "show" : "hide"}
|
|
234
240
|
style={{
|
|
235
241
|
width,
|
|
236
242
|
// Auto-height by default (content-driven, floored at `minHeight`);
|
|
@@ -259,10 +265,19 @@ function ArtboardFrame({
|
|
|
259
265
|
>
|
|
260
266
|
{render({ theme, style })}
|
|
261
267
|
</div>
|
|
268
|
+
{!roughEnabled && showFrame && (
|
|
269
|
+
<div
|
|
270
|
+
className="pointer-events-none absolute inset-0"
|
|
271
|
+
style={{
|
|
272
|
+
borderRadius: preset.radius,
|
|
273
|
+
border: `1.5px solid ${frameBorder}`,
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
)}
|
|
262
277
|
<RoughOverlay
|
|
263
278
|
scopeRef={ref}
|
|
264
279
|
enabled={roughEnabled}
|
|
265
|
-
drawFrame={
|
|
280
|
+
drawFrame={showFrame}
|
|
266
281
|
frameRadius={preset.radius}
|
|
267
282
|
selector={selector}
|
|
268
283
|
/>
|
|
@@ -313,10 +328,12 @@ function WireframeStyleToggleButton() {
|
|
|
313
328
|
function HtmlArtboard({
|
|
314
329
|
data,
|
|
315
330
|
ctx: _ctx,
|
|
331
|
+
showFrame,
|
|
316
332
|
compact,
|
|
317
333
|
}: {
|
|
318
334
|
data: WireframeData;
|
|
319
335
|
ctx: BlockRenderContext;
|
|
336
|
+
showFrame: boolean;
|
|
320
337
|
compact?: boolean;
|
|
321
338
|
}) {
|
|
322
339
|
const renderMode = data.renderMode ?? "wireframe";
|
|
@@ -350,6 +367,7 @@ function HtmlArtboard({
|
|
|
350
367
|
compact={compact}
|
|
351
368
|
skeleton={data.skeleton}
|
|
352
369
|
renderMode={renderMode}
|
|
370
|
+
showFrame={showFrame}
|
|
353
371
|
selector={HTML_ROUGH_SELECTOR}
|
|
354
372
|
caption={data.caption}
|
|
355
373
|
render={({ theme, style }) => (
|
|
@@ -357,6 +375,7 @@ function HtmlArtboard({
|
|
|
357
375
|
className="plan-html-frame"
|
|
358
376
|
data-theme={theme}
|
|
359
377
|
data-style={style}
|
|
378
|
+
data-frame={showFrame ? "show" : "hide"}
|
|
360
379
|
data-render-mode={renderMode}
|
|
361
380
|
data-plan-design-scope={scopeId}
|
|
362
381
|
data-skeleton={data.skeleton ? "true" : undefined}
|
|
@@ -378,9 +397,11 @@ function HtmlArtboard({
|
|
|
378
397
|
|
|
379
398
|
function KitArtboard({
|
|
380
399
|
data,
|
|
400
|
+
showFrame,
|
|
381
401
|
compact,
|
|
382
402
|
}: {
|
|
383
403
|
data: WireframeData;
|
|
404
|
+
showFrame: boolean;
|
|
384
405
|
compact?: boolean;
|
|
385
406
|
}) {
|
|
386
407
|
return (
|
|
@@ -388,6 +409,7 @@ function KitArtboard({
|
|
|
388
409
|
surface={data.surface}
|
|
389
410
|
compact={compact}
|
|
390
411
|
skeleton={data.skeleton}
|
|
412
|
+
showFrame={showFrame}
|
|
391
413
|
selector="[data-rough]"
|
|
392
414
|
caption={data.caption}
|
|
393
415
|
render={({ theme, style }) => (
|
|
@@ -430,10 +452,27 @@ function WireframeSurfaceView({
|
|
|
430
452
|
ctx: BlockRenderContext;
|
|
431
453
|
compact?: boolean;
|
|
432
454
|
}) {
|
|
455
|
+
const showFrame = resolveVisualFrame(data.frame, ctx);
|
|
433
456
|
if (isHtmlData(data)) {
|
|
434
|
-
return
|
|
457
|
+
return (
|
|
458
|
+
<HtmlArtboard
|
|
459
|
+
data={data}
|
|
460
|
+
ctx={ctx}
|
|
461
|
+
showFrame={showFrame}
|
|
462
|
+
compact={compact}
|
|
463
|
+
/>
|
|
464
|
+
);
|
|
435
465
|
}
|
|
436
|
-
return <KitArtboard data={data} compact={compact} />;
|
|
466
|
+
return <KitArtboard data={data} showFrame={showFrame} compact={compact} />;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function resolveVisualFrame(
|
|
470
|
+
frame: WireframeData["frame"],
|
|
471
|
+
ctx: BlockRenderContext,
|
|
472
|
+
): boolean {
|
|
473
|
+
const resolved =
|
|
474
|
+
frame && frame !== "auto" ? frame : (ctx.visualFrame ?? "show");
|
|
475
|
+
return resolved !== "hide";
|
|
437
476
|
}
|
|
438
477
|
|
|
439
478
|
/* -------------------------------------------------------------------------- */
|
|
@@ -19,6 +19,9 @@ import type { ZodType } from "zod";
|
|
|
19
19
|
/** Where a block can be placed in a document. */
|
|
20
20
|
export type BlockPlacement = "block" | "inline";
|
|
21
21
|
|
|
22
|
+
/** How visual blocks decide whether to draw an outer surface frame. */
|
|
23
|
+
export type BlockVisualFrame = "auto" | "show" | "hide";
|
|
24
|
+
|
|
22
25
|
/**
|
|
23
26
|
* A serialized MDX/NFM attribute value before the shared `prop()` encoder runs.
|
|
24
27
|
* `prop()` decides string-vs-JSON encoding; this is just the value domain.
|
|
@@ -96,6 +99,12 @@ export interface BlockRenderContext {
|
|
|
96
99
|
dialect?: "gfm" | "nfm";
|
|
97
100
|
/** Document text direction inferred by the host app. */
|
|
98
101
|
textDirection?: "ltr" | "rtl";
|
|
102
|
+
/**
|
|
103
|
+
* Host default for visual wireframe/diagram frames when block data leaves
|
|
104
|
+
* `frame` unset or set to `auto`. Plans/recaps usually show a frame; docs can
|
|
105
|
+
* hide it by default and let individual blocks opt back in.
|
|
106
|
+
*/
|
|
107
|
+
visualFrame?: Exclude<BlockVisualFrame, "auto">;
|
|
99
108
|
/** Resolve an asset id → displayable URL. */
|
|
100
109
|
resolveAssetSrc?: (assetId: string) => string | undefined;
|
|
101
110
|
/** Open the shared asset picker (returns the chosen asset). */
|
|
@@ -214,7 +214,7 @@ export function SelectionAttachedPill() {
|
|
|
214
214
|
if (length === null || length === 0) return null;
|
|
215
215
|
|
|
216
216
|
return (
|
|
217
|
-
<div className="shrink-0 px-3 pt-1.5 -mb-1">
|
|
217
|
+
<div className="agent-selection-attached-pill shrink-0 px-3 pt-1.5 -mb-1">
|
|
218
218
|
<div className="inline-flex items-center gap-1.5 rounded-full border border-border bg-muted/50 px-2 py-0.5 text-[11px] text-muted-foreground">
|
|
219
219
|
<IconQuote size={11} />
|
|
220
220
|
<span>{length.toLocaleString()} chars of selection attached</span>
|
|
@@ -682,6 +682,23 @@
|
|
|
682
682
|
line-height: 1.75rem;
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
+
.agent-composer-stack {
|
|
686
|
+
position: relative;
|
|
687
|
+
flex-shrink: 0;
|
|
688
|
+
width: 100%;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
.agent-composer-stack[data-agent-composer-adjacent-ui="true"],
|
|
692
|
+
.agent-composer-stack:has(.agent-selection-attached-pill) {
|
|
693
|
+
display: flex;
|
|
694
|
+
flex-direction: column;
|
|
695
|
+
gap: 0.5rem;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.agent-composer-setup-card {
|
|
699
|
+
width: 100%;
|
|
700
|
+
}
|
|
701
|
+
|
|
685
702
|
[data-agent-empty-state="centered"] {
|
|
686
703
|
justify-content: center;
|
|
687
704
|
}
|
|
@@ -691,6 +708,33 @@
|
|
|
691
708
|
overflow: visible;
|
|
692
709
|
}
|
|
693
710
|
|
|
711
|
+
[data-agent-empty-state="centered"]
|
|
712
|
+
> .agent-composer-stack:not([data-agent-composer-adjacent-ui="true"]):not(
|
|
713
|
+
:has(.agent-selection-attached-pill)
|
|
714
|
+
)
|
|
715
|
+
> .agent-composer-setup-card {
|
|
716
|
+
position: absolute;
|
|
717
|
+
left: 0;
|
|
718
|
+
right: 0;
|
|
719
|
+
z-index: 3;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
[data-agent-empty-state="centered"]
|
|
723
|
+
> .agent-composer-stack:not([data-agent-composer-adjacent-ui="true"]):not(
|
|
724
|
+
:has(.agent-selection-attached-pill)
|
|
725
|
+
)
|
|
726
|
+
> .agent-composer-setup-card[data-agent-composer-setup-position="above"] {
|
|
727
|
+
bottom: calc(100% + 0.5rem);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
[data-agent-empty-state="centered"]
|
|
731
|
+
> .agent-composer-stack:not([data-agent-composer-adjacent-ui="true"]):not(
|
|
732
|
+
:has(.agent-selection-attached-pill)
|
|
733
|
+
)
|
|
734
|
+
> .agent-composer-setup-card[data-agent-composer-setup-position="below"] {
|
|
735
|
+
top: calc(100% + 0.5rem);
|
|
736
|
+
}
|
|
737
|
+
|
|
694
738
|
[data-agent-empty-state="compact-setup"] > .agent-chat-scroll {
|
|
695
739
|
flex: 0 0 auto;
|
|
696
740
|
overflow: visible;
|
|
@@ -1290,6 +1290,20 @@
|
|
|
1290
1290
|
line-height: 1.4;
|
|
1291
1291
|
}
|
|
1292
1292
|
|
|
1293
|
+
.plan-diagram-frame[data-frame="show"] {
|
|
1294
|
+
border: 1px solid var(--wf-diagram-line);
|
|
1295
|
+
padding: 10px;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
.plan-diagram-frame[data-frame="show"][data-rough-ready] {
|
|
1299
|
+
border-color: transparent;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
.plan-diagram-frame[data-frame="hide"] {
|
|
1303
|
+
border: 0;
|
|
1304
|
+
background: transparent;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1293
1307
|
.plan-diagram-frame[data-theme="dark"] {
|
|
1294
1308
|
--wf-diagram-line: color-mix(in srgb, var(--wf-sketch) 72%, var(--wf-line));
|
|
1295
1309
|
}
|
|
@@ -1312,6 +1326,10 @@
|
|
|
1312
1326
|
direction: inherit;
|
|
1313
1327
|
}
|
|
1314
1328
|
|
|
1329
|
+
.plan-diagram-frame[data-frame="show"] .plan-diagram-frame-content {
|
|
1330
|
+
padding: 0;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1315
1333
|
.plan-diagram-frame-content
|
|
1316
1334
|
> .diagram-panel:not([data-rough]):not([data-diagram-frame]) {
|
|
1317
1335
|
--rough-skip: 1;
|
|
@@ -109,12 +109,16 @@ so you never emit a block the editor cannot render or round-trip:
|
|
|
109
109
|
`--wf-paper`, `--wf-card`, `--wf-accent`, `--wf-accent-soft`, `--wf-warn`, and
|
|
110
110
|
`--wf-ok`, and switch to Excalifont plus rough.js outlines in sketchy mode. Do not
|
|
111
111
|
set `font-family` and do not hard-code hex, rgb, or hsl colors in diagram HTML
|
|
112
|
-
or CSS.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
or CSS. Choose the outer `frame` intentionally: use `show` when the diagram
|
|
113
|
+
stands alone in a recap, comparison, or prose section; use `hide` when the
|
|
114
|
+
diagram sits inside docs chrome, columns, tabs, cards, a canvas surface, or
|
|
115
|
+
already has visible `.diagram-panel` / `.diagram-box` structure. Leave room
|
|
116
|
+
for the sketch font: keep labels short, give nodes generous width, and place
|
|
117
|
+
boundary/annotation labels in unused space instead of over nodes; labels must
|
|
118
|
+
not overlap nodes, connectors, or each other. For small text/SVG changes to an
|
|
119
|
+
existing HTML diagram, use `patch-diagram-html` with a unique
|
|
120
|
+
`find`/`replace` snippet instead of resending the whole `data.html` string.
|
|
121
|
+
Use legacy `nodes` / `edges` only for small previews or truly
|
|
118
122
|
sequential flows. In architecture/code plans, prefer a repeated section rhythm:
|
|
119
123
|
recommendation title, confidence and category badges, code-path evidence, a
|
|
120
124
|
local before/after or current/target spatial diagram, then concise
|
|
@@ -171,15 +171,26 @@ occurrence. The result is re-sanitized. In local-files privacy mode, do not call
|
|
|
171
171
|
hosted Plan tools; edit the local MDX source directly and rerun the local
|
|
172
172
|
check/serve or verify command for `<plan-dir>`.
|
|
173
173
|
|
|
174
|
-
**
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
`
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
174
|
+
**Choose the outer frame deliberately.** Wireframe and diagram data accept
|
|
175
|
+
`frame: "auto" | "show" | "hide"` in block data (`<Screen frame="hide">` in
|
|
176
|
+
MDX wireframes, `<Diagram frame="hide">` for MDX diagrams). Leave it unset or
|
|
177
|
+
`auto` when the host context should decide: Plan and recap surfaces default to a
|
|
178
|
+
drawn outer frame; docs surfaces default to no outer frame. Use `show` for
|
|
179
|
+
standalone product screens, before/after recap comparisons, screenshot-like
|
|
180
|
+
artifacts, and visuals that need containment from surrounding prose. Use `hide`
|
|
181
|
+
when a docs page, tab, column, card, canvas artboard, or the visual's own
|
|
182
|
+
internal chrome already supplies the boundary. Do not use `hide` to compensate
|
|
183
|
+
for cramped content; fix the layout instead.
|
|
184
|
+
|
|
185
|
+
**Inner padding and borders still matter.** Always wrap HTML wireframe content
|
|
186
|
+
in a root container with real inner padding before drawing cards, fields, pills,
|
|
187
|
+
labels, or controls. Use at least 14-16px of padding, `box-sizing: border-box`,
|
|
188
|
+
`height: 100%`, and `gap` between child rows on the root node itself so the
|
|
189
|
+
first row never sits flush against the screen edge. Do not rely on padding on a
|
|
190
|
+
nested page section as the first visible inset; the outermost element must
|
|
191
|
+
create the breathing room. Keep text away from borders: every container, field,
|
|
192
|
+
button, menu item, and annotation needs enough padding and line-height to read
|
|
193
|
+
cleanly in the rendered Plan view.
|
|
183
194
|
|
|
184
195
|
**For feature-cloud or abundance visuals, optimize the composition over line-by-line
|
|
185
196
|
reading.** Some marketing/product sections need to feel like a large surface area
|
|
@@ -377,7 +377,10 @@ tags — resolve every conceptual name to its exact tag + prop schema with the
|
|
|
377
377
|
Author diagram HTML/CSS with the renderer-owned `.diagram-*` primitives
|
|
378
378
|
(`.diagram-panel`, `.diagram-node`, `.diagram-pill`, `[data-rough]`, …) and
|
|
379
379
|
the same `--wf-*` theme tokens `references/wireframe.md` defines — never
|
|
380
|
-
`font-family`, hex, rgb/hsl literals, or one-off dark/light palettes.
|
|
380
|
+
`font-family`, hex, rgb/hsl literals, or one-off dark/light palettes. Choose
|
|
381
|
+
the outer `frame` intentionally: recap diagrams usually benefit from
|
|
382
|
+
`frame: "show"` when they stand alone, but use `frame: "hide"` when columns,
|
|
383
|
+
tabs, a card, or the diagram's own panels already provide the boundary.
|
|
381
384
|
- **Outcome-first narrative** → `rich-text` for the "what changed and why" prose:
|
|
382
385
|
the objective the diff served, the key decisions visible in it, and the risks a
|
|
383
386
|
reviewer should weigh. This is the only place the model writes freely.
|
|
@@ -171,15 +171,26 @@ occurrence. The result is re-sanitized. In local-files privacy mode, do not call
|
|
|
171
171
|
hosted Plan tools; edit the local MDX source directly and rerun the local
|
|
172
172
|
check/serve or verify command for `<plan-dir>`.
|
|
173
173
|
|
|
174
|
-
**
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
`
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
174
|
+
**Choose the outer frame deliberately.** Wireframe and diagram data accept
|
|
175
|
+
`frame: "auto" | "show" | "hide"` in block data (`<Screen frame="hide">` in
|
|
176
|
+
MDX wireframes, `<Diagram frame="hide">` for MDX diagrams). Leave it unset or
|
|
177
|
+
`auto` when the host context should decide: Plan and recap surfaces default to a
|
|
178
|
+
drawn outer frame; docs surfaces default to no outer frame. Use `show` for
|
|
179
|
+
standalone product screens, before/after recap comparisons, screenshot-like
|
|
180
|
+
artifacts, and visuals that need containment from surrounding prose. Use `hide`
|
|
181
|
+
when a docs page, tab, column, card, canvas artboard, or the visual's own
|
|
182
|
+
internal chrome already supplies the boundary. Do not use `hide` to compensate
|
|
183
|
+
for cramped content; fix the layout instead.
|
|
184
|
+
|
|
185
|
+
**Inner padding and borders still matter.** Always wrap HTML wireframe content
|
|
186
|
+
in a root container with real inner padding before drawing cards, fields, pills,
|
|
187
|
+
labels, or controls. Use at least 14-16px of padding, `box-sizing: border-box`,
|
|
188
|
+
`height: 100%`, and `gap` between child rows on the root node itself so the
|
|
189
|
+
first row never sits flush against the screen edge. Do not rely on padding on a
|
|
190
|
+
nested page section as the first visible inset; the outermost element must
|
|
191
|
+
create the breathing room. Keep text away from borders: every container, field,
|
|
192
|
+
button, menu item, and annotation needs enough padding and line-height to read
|
|
193
|
+
cleanly in the rendered Plan view.
|
|
183
194
|
|
|
184
195
|
**For feature-cloud or abundance visuals, optimize the composition over line-by-line
|
|
185
196
|
reading.** Some marketing/product sections need to feel like a large surface area
|
|
@@ -72,7 +72,7 @@ export default defineAction({
|
|
|
72
72
|
content: planContentSchema
|
|
73
73
|
.optional()
|
|
74
74
|
.describe(
|
|
75
|
-
|
|
75
|
+
'Structured editable UI plan content. Prefer this for app-owned top canvas wireframes (HTML mockups: set the wireframe\'s data.html to a semantic HTML fragment of the screen and pick a surface — the renderer owns the theme, footprint/aspect, hand-drawn font, and sketch overlay; use --wf-* CSS tokens for any custom color, never hex). Call get-plan-blocks first for visual frame guidance before choosing frame: "show" or frame: "hide". Do not use legacy kit-tree screen arrays or nested FrameScreen/Card/Row/Btn-style children for new canvas artboards. Use sketch diagrams, rich text, code blocks (grouped in a vertical tabs block for a file map), annotated code for key files, validation checklists, and bounded custom HTML fragments. Diagram data.html/data.css should use renderer-owned .diagram-* primitives plus --wf-* tokens, not custom fonts or hard-coded hex/rgb/hsl colors, so light/dark and sketchy Excalifont/rough.js modes remain correct. The canvas should carry Claude-style flex/grid wireframe artboards and designer annotations; the document should add implementation substance instead of duplicating the same wireframes. The renderer owns all visual styling; emit lean content, not pixels.',
|
|
76
76
|
),
|
|
77
77
|
markdown: z
|
|
78
78
|
.string()
|
|
@@ -84,7 +84,7 @@ export default defineAction({
|
|
|
84
84
|
content: planContentSchema
|
|
85
85
|
.optional()
|
|
86
86
|
.describe(
|
|
87
|
-
"Structured editable plan content. Prefer this for rich text, inline diagrams, annotated code, question-form open questions, and optional canvas/prototype UI surfaces. Call the get-plan-blocks tool FIRST for the authoritative block catalog, authoring rules, and style tokens — do not author from memory. Key rules: canvas frames use wireframe data.html/html semantic HTML, not legacy kit-tree screen arrays; use diagram blocks with .diagram-* primitives and --wf-* tokens (no hex/rgb/hsl, no custom fonts); for file maps use annotated-code blocks in a vertical tabs block; put unresolved decisions in a bottom question-form block.",
|
|
87
|
+
"Structured editable plan content. Prefer this for rich text, inline diagrams, annotated code, question-form open questions, and optional canvas/prototype UI surfaces. Call the get-plan-blocks tool FIRST for the authoritative block catalog, visual frame guidance, authoring rules, and style tokens — do not author from memory. Key rules: canvas frames use wireframe data.html/html semantic HTML, not legacy kit-tree screen arrays; use diagram blocks with .diagram-* primitives and --wf-* tokens (no hex/rgb/hsl, no custom fonts); for file maps use annotated-code blocks in a vertical tabs block; put unresolved decisions in a bottom question-form block.",
|
|
88
88
|
),
|
|
89
89
|
markdown: z
|
|
90
90
|
.string()
|
|
@@ -245,7 +245,7 @@ export default defineAction({
|
|
|
245
245
|
.describe("Current focus for the review surface."),
|
|
246
246
|
status: planStatusSchema.optional().default("review"),
|
|
247
247
|
mdx: planMdxFileSchema.describe(
|
|
248
|
-
"Recap source files. Call the get-plan-blocks tool FIRST for the authoritative block catalog, authoring rules, and style tokens — do not author from memory. Key rules: derive all blocks from the real diff only; use diff blocks with line-anchored annotations on key hunks; for UI changes include realistic, non-empty WireframeBlock before/after in a Columns block (labels: Before / After) with visible product text/controls; if canvas.mdx is present, DesignBoard artboards must use Screen html/data.html wireframes, never fresh nested kit-tree children such as FrameScreen/Card/Row/Btn; use .diagram-* primitives and --wf-* tokens in diagrams (no hex/rgb/hsl, no custom fonts); keep API endpoint blocks in single-column flow unless it is an explicit before/after contract comparison.",
|
|
248
|
+
"Recap source files. Call the get-plan-blocks tool FIRST for the authoritative block catalog, visual frame guidance, authoring rules, and style tokens — do not author from memory. Key rules: derive all blocks from the real diff only; use diff blocks with line-anchored annotations on key hunks; for UI changes include realistic, non-empty WireframeBlock before/after in a Columns block (labels: Before / After) with visible product text/controls; if canvas.mdx is present, DesignBoard artboards must use Screen html/data.html wireframes, never fresh nested kit-tree children such as FrameScreen/Card/Row/Btn; use .diagram-* primitives and --wf-* tokens in diagrams (no hex/rgb/hsl, no custom fonts); keep API endpoint blocks in single-column flow unless it is an explicit before/after contract comparison.",
|
|
249
249
|
),
|
|
250
250
|
}),
|
|
251
251
|
publicAgent: {
|
|
@@ -33,6 +33,8 @@ const AUTHORING_RULES_NOTE = `
|
|
|
33
33
|
|
|
34
34
|
**Wireframes**: set \`data.html\` to a semantic HTML fragment; pick a surface (desktop/mobile/popover/panel/browser). The renderer owns theme, footprint/aspect, Excalifont, and rough.js sketch overlay. Use \`--wf-*\` CSS tokens for any custom color (never hex). Prototype screens use semantic HTML with \`data-goto\` attributes for navigation.
|
|
35
35
|
|
|
36
|
+
**Visual frames**: \`wireframe\` and \`diagram\` data accept \`frame: "auto" | "show" | "hide"\`. Leave it unset/\`auto\` when the host context should decide: Plan and recap surfaces default to framed; docs default to unframed. Use \`frame: "show"\` for standalone product screens, before/after recap comparisons, screenshot-like artifacts, and visuals that need containment from surrounding prose. Use \`frame: "hide"\` when a docs page, tab, column, card, canvas artboard, or the visual's own internal chrome already supplies the boundary. Hiding the outer frame must not remove inner padding, meaningful card/field/button borders, or the visual's readable structure.
|
|
37
|
+
|
|
36
38
|
**Canvas storyboards**: if the user asks for a canvas, storyboard, wireframe, light storyboard, UI flow, screen flow, product flow, mockup, or visual comparison, the primary artifact must be \`content.canvas\` / \`canvas.mdx\` with \`DesignBoard\` artboards containing \`Screen\` HTML wireframes. Each canvas \`Screen\` must carry \`html\` / \`data.html\`; never author fresh nested kit-tree children such as \`<FrameScreen>\`, \`<Card>\`, \`<Row>\`, or \`<Btn>\` inside canvas \`<Screen>\` tags. Kit trees are old-plan compatibility only and often render worse on the pan/zoom canvas than HTML wireframes. Do not use document-body \`diagram\` blocks for the primary UI story. Use \`diagram\` only for architecture, data flow, or implementation mechanics below the canvas, and only after the UI storyboard exists.
|
|
37
39
|
|
|
38
40
|
**Before/After columns**: compose a \`columns\` block from \`<Column>\` CHILDREN — never a \`columns=\` attribute or inline JSON array. Author it as \`<Columns><Column label="Before">…child block(s)…</Column><Column label="After">…child block(s)…</Column></Columns>\`. Each \`<Column>\` wraps real nested blocks (e.g. a \`Wireframe\`); the parser fills in column ids and child-block \`data\` from that markup, whereas a \`columns=\` attribute array leaves them missing and FAILS schema validation. For UI state comparisons put one \`wireframe\` block in each side and label the columns \`Before\` and \`After\`; the renderer draws labels as headings and lays narrow surfaces side by side. Never bake Before/After labels inside the wireframe HTML or hand-stack the pair.
|
|
@@ -165,10 +165,12 @@ export function createPlanBlockRenderContext(options: {
|
|
|
165
165
|
editingDisabled?: boolean;
|
|
166
166
|
showCodeAnnotationOverlays?: boolean;
|
|
167
167
|
codeAnnotationLayout?: BlockRenderContext["codeAnnotationLayout"];
|
|
168
|
+
visualFrame?: BlockRenderContext["visualFrame"];
|
|
168
169
|
}): BlockRenderContext {
|
|
169
170
|
const ctx: BlockRenderContext & PlanBlockRenderContextExtras = {
|
|
170
171
|
dialect: "gfm",
|
|
171
172
|
textDirection: options.textDirection,
|
|
173
|
+
visualFrame: options.visualFrame ?? "show",
|
|
172
174
|
showCodeAnnotationOverlays: options.showCodeAnnotationOverlays,
|
|
173
175
|
codeAnnotationLayout: options.codeAnnotationLayout,
|
|
174
176
|
onQuestionFormSubmit: options.onVisualQuestionsSubmit,
|
|
@@ -121,10 +121,12 @@ export function Wireframe({
|
|
|
121
121
|
selectedDesignElementKey?: string | null;
|
|
122
122
|
onDesignElementSelect?: (selection: DesignElementSelection) => void;
|
|
123
123
|
}) {
|
|
124
|
+
const showFrame = "frame" in data && data.frame === "hide" ? false : true;
|
|
124
125
|
if (isHtmlData(data)) {
|
|
125
126
|
return (
|
|
126
127
|
<HtmlArtboard
|
|
127
128
|
data={data}
|
|
129
|
+
showFrame={showFrame}
|
|
128
130
|
compact={compact}
|
|
129
131
|
canvasSize={canvasSize}
|
|
130
132
|
canvasWidth={canvasWidth}
|
|
@@ -140,6 +142,7 @@ export function Wireframe({
|
|
|
140
142
|
return (
|
|
141
143
|
<KitWireframe
|
|
142
144
|
data={data}
|
|
145
|
+
showFrame={showFrame}
|
|
143
146
|
compact={compact}
|
|
144
147
|
canvasSize={canvasSize}
|
|
145
148
|
canvasWidth={canvasWidth}
|
|
@@ -167,6 +170,7 @@ function ArtboardFrame({
|
|
|
167
170
|
skeleton,
|
|
168
171
|
renderMode,
|
|
169
172
|
roughOverlay = true,
|
|
173
|
+
showFrame = true,
|
|
170
174
|
selector,
|
|
171
175
|
caption,
|
|
172
176
|
render,
|
|
@@ -178,6 +182,7 @@ function ArtboardFrame({
|
|
|
178
182
|
skeleton?: boolean;
|
|
179
183
|
renderMode?: "wireframe" | "design";
|
|
180
184
|
roughOverlay?: boolean;
|
|
185
|
+
showFrame?: boolean;
|
|
181
186
|
selector: string;
|
|
182
187
|
caption?: string;
|
|
183
188
|
render: (ctx: {
|
|
@@ -250,6 +255,7 @@ function ArtboardFrame({
|
|
|
250
255
|
ref={ref}
|
|
251
256
|
className="plan-kit-artboard relative"
|
|
252
257
|
data-rough-scope="wireframe"
|
|
258
|
+
data-frame={showFrame ? "show" : "hide"}
|
|
253
259
|
style={{
|
|
254
260
|
width,
|
|
255
261
|
height,
|
|
@@ -273,7 +279,7 @@ function ArtboardFrame({
|
|
|
273
279
|
are never cut, and a skeleton frame still reads as a frame). Sketchy
|
|
274
280
|
mode gets its frame from the rough overlay unless the caller needs
|
|
275
281
|
all borders to stay in the normal scrolling DOM. */}
|
|
276
|
-
{!roughEnabled && (
|
|
282
|
+
{!roughEnabled && showFrame && (
|
|
277
283
|
<div
|
|
278
284
|
className="pointer-events-none absolute inset-0"
|
|
279
285
|
style={{
|
|
@@ -285,6 +291,7 @@ function ArtboardFrame({
|
|
|
285
291
|
<RoughOverlay
|
|
286
292
|
scopeRef={ref}
|
|
287
293
|
enabled={roughEnabled}
|
|
294
|
+
drawFrame={showFrame}
|
|
288
295
|
frameRadius={preset.radius}
|
|
289
296
|
selector={selector}
|
|
290
297
|
/>
|
|
@@ -330,6 +337,7 @@ function WireframeStyleToggleButton() {
|
|
|
330
337
|
|
|
331
338
|
function HtmlArtboard({
|
|
332
339
|
data,
|
|
340
|
+
showFrame,
|
|
333
341
|
compact,
|
|
334
342
|
canvasSize,
|
|
335
343
|
canvasWidth,
|
|
@@ -340,6 +348,7 @@ function HtmlArtboard({
|
|
|
340
348
|
onDesignElementSelect,
|
|
341
349
|
}: {
|
|
342
350
|
data: PlanWireframeBlock["data"];
|
|
351
|
+
showFrame: boolean;
|
|
343
352
|
compact?: boolean;
|
|
344
353
|
canvasSize?: number;
|
|
345
354
|
canvasWidth?: number;
|
|
@@ -478,6 +487,7 @@ function HtmlArtboard({
|
|
|
478
487
|
skeleton={data.skeleton}
|
|
479
488
|
renderMode={renderMode}
|
|
480
489
|
roughOverlay={!interactive}
|
|
490
|
+
showFrame={showFrame}
|
|
481
491
|
selector={HTML_ROUGH_SELECTOR}
|
|
482
492
|
caption={data.caption}
|
|
483
493
|
render={({ theme, style }) => (
|
|
@@ -486,6 +496,7 @@ function HtmlArtboard({
|
|
|
486
496
|
className="plan-html-frame"
|
|
487
497
|
data-theme={theme}
|
|
488
498
|
data-style={style}
|
|
499
|
+
data-frame={showFrame ? "show" : "hide"}
|
|
489
500
|
data-render-mode={renderMode}
|
|
490
501
|
data-plan-design-scope={scopeId}
|
|
491
502
|
data-skeleton={data.skeleton ? "true" : undefined}
|
|
@@ -531,11 +542,13 @@ export function KitWireframePreview({
|
|
|
531
542
|
|
|
532
543
|
function KitWireframe({
|
|
533
544
|
data,
|
|
545
|
+
showFrame = data.frame !== "hide",
|
|
534
546
|
compact,
|
|
535
547
|
canvasSize,
|
|
536
548
|
canvasWidth,
|
|
537
549
|
}: {
|
|
538
550
|
data: PlanWireframeBlock["data"];
|
|
551
|
+
showFrame?: boolean;
|
|
539
552
|
compact?: boolean;
|
|
540
553
|
canvasSize?: number;
|
|
541
554
|
canvasWidth?: number;
|
|
@@ -547,6 +560,7 @@ function KitWireframe({
|
|
|
547
560
|
canvasSize={canvasSize}
|
|
548
561
|
canvasWidth={canvasWidth}
|
|
549
562
|
skeleton={data.skeleton}
|
|
563
|
+
showFrame={showFrame}
|
|
550
564
|
selector="[data-rough]"
|
|
551
565
|
caption={data.caption}
|
|
552
566
|
render={({ theme, style }) => (
|
|
@@ -588,6 +602,7 @@ export function SketchDiagram({
|
|
|
588
602
|
compact?: boolean;
|
|
589
603
|
}) {
|
|
590
604
|
const t = useT();
|
|
605
|
+
const showFrame = data.frame !== "hide";
|
|
591
606
|
if (data.html?.trim()) {
|
|
592
607
|
return <HtmlDiagram data={data} compact={compact} />;
|
|
593
608
|
}
|
|
@@ -599,6 +614,7 @@ export function SketchDiagram({
|
|
|
599
614
|
data={data}
|
|
600
615
|
compact={compact}
|
|
601
616
|
markerId={markerId}
|
|
617
|
+
showFrame={showFrame}
|
|
602
618
|
/>
|
|
603
619
|
);
|
|
604
620
|
}
|
|
@@ -613,7 +629,14 @@ export function SketchDiagram({
|
|
|
613
629
|
);
|
|
614
630
|
}
|
|
615
631
|
return (
|
|
616
|
-
<div
|
|
632
|
+
<div
|
|
633
|
+
className={cn(
|
|
634
|
+
"plan-sketch",
|
|
635
|
+
showFrame
|
|
636
|
+
? "rounded-[16px] border border-plan-line bg-plan-wireframe p-5"
|
|
637
|
+
: "p-0",
|
|
638
|
+
)}
|
|
639
|
+
>
|
|
617
640
|
<div
|
|
618
641
|
className={cn(
|
|
619
642
|
"flex gap-3 overflow-x-auto pb-2",
|
|
@@ -684,6 +707,7 @@ function HtmlDiagram({
|
|
|
684
707
|
const { resolvedTheme } = useTheme();
|
|
685
708
|
const theme: "light" | "dark" = resolvedTheme === "dark" ? "dark" : "light";
|
|
686
709
|
const style = useWireframeStyle();
|
|
710
|
+
const showFrame = data.frame !== "hide";
|
|
687
711
|
const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
688
712
|
const scopeSelector = `[data-plan-diagram-scope="${scopeId}"]`;
|
|
689
713
|
const safeHtml = useMemo(() => sanitizeDiagramHtml(data.html), [data.html]);
|
|
@@ -701,6 +725,7 @@ function HtmlDiagram({
|
|
|
701
725
|
className="plan-diagram-frame"
|
|
702
726
|
data-theme={theme}
|
|
703
727
|
data-style={style}
|
|
728
|
+
data-frame={showFrame ? "show" : "hide"}
|
|
704
729
|
data-plan-diagram-scope={scopeId}
|
|
705
730
|
>
|
|
706
731
|
{scopedCss && <style>{scopedCss}</style>}
|
|
@@ -712,7 +737,7 @@ function HtmlDiagram({
|
|
|
712
737
|
<RoughOverlay
|
|
713
738
|
scopeRef={ref}
|
|
714
739
|
enabled={style === "sketchy"}
|
|
715
|
-
drawFrame={
|
|
740
|
+
drawFrame={showFrame}
|
|
716
741
|
selector={DIAGRAM_ROUGH_SELECTOR}
|
|
717
742
|
/>
|
|
718
743
|
{data.caption && !compact && (
|
|
@@ -726,10 +751,12 @@ function PositionedSketchDiagram({
|
|
|
726
751
|
data,
|
|
727
752
|
compact,
|
|
728
753
|
markerId,
|
|
754
|
+
showFrame,
|
|
729
755
|
}: {
|
|
730
756
|
data: PlanDiagramBlock["data"];
|
|
731
757
|
compact?: boolean;
|
|
732
758
|
markerId: string;
|
|
759
|
+
showFrame: boolean;
|
|
733
760
|
}) {
|
|
734
761
|
const nodes = (data.nodes ?? []).map((node) => ({
|
|
735
762
|
...node,
|
|
@@ -743,7 +770,14 @@ function PositionedSketchDiagram({
|
|
|
743
770
|
const canvasHeight = compact ? 280 : 430;
|
|
744
771
|
|
|
745
772
|
return (
|
|
746
|
-
<div
|
|
773
|
+
<div
|
|
774
|
+
className={cn(
|
|
775
|
+
"plan-sketch",
|
|
776
|
+
showFrame
|
|
777
|
+
? "rounded-[16px] border border-plan-line bg-plan-wireframe p-5"
|
|
778
|
+
: "p-0",
|
|
779
|
+
)}
|
|
780
|
+
>
|
|
747
781
|
<div
|
|
748
782
|
className="relative overflow-hidden rounded-xl border border-plan-line bg-plan-document"
|
|
749
783
|
style={{ minHeight: canvasHeight }}
|