@ammduncan/easel 0.2.24 → 0.2.26

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/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  All notable changes to easel. This project adheres to [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## 0.2.26 — 2026-05-23
6
+
7
+ ### Changed
8
+ - **The "open on another session" push hint now nudges agents to use their interactive question tool.** When a push lands but easel is showing a *different* session, the hint returned to the agent previously just said "ASK the user…", which agents (including Claude Code) tended to render as a passive one-line note. It now explicitly says: if your client has an interactive question/prompt tool (e.g. `AskUserQuestion`), use it to offer the choice as clickable options — (a) switch the open tab via the topbar dropdown, or (b) call `open` for a fresh tab — rather than burying it in prose. Stays client-agnostic (text-only clients still read a clear instruction; capable clients self-upgrade to a structured prompt) — no UI is forced at the MCP layer.
9
+
10
+ ## 0.2.25 — 2026-05-23
11
+
12
+ ### Docs
13
+ - **Documented the `.window` primitive and the "build mockups fluid" rule.** Added the `.window` / `.window.desktop` chrome to the skill's helpers section (it shipped in 0.2.24 with CSS but wasn't written up), and a guidance rule: lay desktop mockups out with flex/`%`/`fr` widths, not hardcoded `width: 1440px` columns. 1440 is a *max*, not a target — a fluid mockup reflows to fit when the viewer's window is narrowed, so there's no horizontal scroll, nothing clipped, and PNG/PDF exports stay complete. (Answers "should desktop mockups scroll horizontally when squeezed?" — no; build fluid so they reflow.) Also corrected the now-stale `.full-bleed` description to match 0.2.24 (fills the content column from the shared left edge, doesn't bleed to the card's physical edge). Skill + inline `push` tool description.
14
+
5
15
  ## 0.2.24 — 2026-05-23
6
16
 
7
17
  ### Added
package/dist/mcp.js CHANGED
@@ -139,7 +139,9 @@ export async function main() {
139
139
  "═══ LAYOUT ═══\n" +
140
140
  "• Stack desktop mockups VERTICALLY with labels ('Now', 'Proposed') — don't squeeze them side-by-side. The iframe is ~900px wide; two desktop screens at half-width crush columns, wrap headings to 3 lines, and turn tables unreadable.\n" +
141
141
  "• Side-by-side is fine only for narrow mobile mockups, small cards, or short text columns that genuinely fit in half-width.\n" +
142
- "• Mockup embedded mid-explanation? Prose has a ~880px reading-width cap, but a mockup section should fill the full card. Wrap JUST the mockup in <div class=\"full-bleed\">…</div> it breaks out of the body padding + prose cap to span the full card width, while surrounding prose stays in the reading column. (If the WHOLE push is a UI recreation, use kind:'mockup'/'app' instead — that strips the entire frame.)\n" +
142
+ "• Mockup embedded mid-explanation? Prose is left-aligned and capped ~880px; wrap JUST the mockup in <div class=\"full-bleed\">…</div> and it fills the content column from the SAME left edge (wider than the prose, sharing one left margin; the body padding stays as a gutter so nothing touches the card edge). (If the WHOLE push is a UI recreation, use kind:'mockup'/'app' instead.)\n" +
143
+ "• Window chrome: wrap a mockup in <div class=\"window\" data-title=\"App name\">…</div> for a macOS window frame (title bar + red/yellow/green traffic-light dots + centred title). Add the `desktop` class (class=\"window desktop\") for the 1440x900 (16:10) desktop canvas via min-height:900px; omit it so dialogs/components size to content. Combine with .full-bleed to fill the column.\n" +
144
+ "• BUILD MOCKUPS FLUID, not fixed-width. Lay the inside out with flex / % / fr widths, not hardcoded width:1440px columns. 1440 is a MAX, not a target. A fluid mockup reflows to fit when the viewer's window is squeezed — no horizontal scroll, nothing clipped, exports stay complete. A fixed-pixel-width mockup gets cut off or needs an awkward horizontal scrollbar when narrowed.\n" +
143
145
  "• MATCH THE SOURCE'S REAL FRAME — faithful height, not minimal, in both directions. Mocking a COMPONENT (card, modal, row, toolbar)? Size to content — do NOT pad with min-height:560px / height:100vh to feel 'desktop-y'; that floats content in dead whitespace. Mocking a FULL DESKTOP SCREEN (login page, dashboard)? Give it realistic viewport proportions (e.g. height:760px or 16:10) and lay content out inside as the real screen does (centred form, top nav) — cropping a real screen down to just its content height misrepresents it just as much. Either way copy the source's exact height if it has one. Test: cropped the same way, would your mock look like a screenshot of the real thing? Empty bands = over-padded; a screen squashed to a strip = under-sized.\n" +
144
146
  "• When recreating real app UI, hug the source — pull exact colors, spacing, sizing, radii, fonts from the component/theme/Figma/DevTools. A close-but-wrong recreation misleads more than no recreation. If you can't reach the actuals, say so in chat and don't pass the mock off as accurate.\n" +
145
147
  "• One accent color, 3–4 instances max per card. Status colors (red/amber/green) only when state genuinely maps to status.\n\n" +
@@ -294,7 +296,7 @@ export async function main() {
294
296
  }
295
297
  else if (openResult.kind === "other-session") {
296
298
  tabHint =
297
- " · easel is open in another tab on a different session — ASK the user whether to switch via the topbar 'switch ▾' dropdown to this session, or call `open` to launch a new tab/window for it";
299
+ " · easel is open in another tab, but on a DIFFERENT session — so this push isn't visible yet. ASK THE USER how to surface it, and if your client has an interactive question/prompt tool (e.g. AskUserQuestion), USE IT to offer the choice as clickable options rather than burying it in prose: (a) switch the open tab to this session via the topbar 'switch ▾' dropdown, or (b) have you call the `open` tool to launch a fresh tab. Do not auto-open or pick for them.";
298
300
  }
299
301
  else if (result.sessionTabs === 0) {
300
302
  tabHint =
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ammduncan/easel",
3
- "version": "0.2.24",
3
+ "version": "0.2.26",
4
4
  "description": "A live browser tab for every Claude Code (and MCP) session. The push MCP tool appends HTML cards to a scrolling feed you keep open in split-screen.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -293,12 +293,29 @@ Most mockups appear *inside* an explanation push — prose intro, embedded UI mo
293
293
  <p>The left panel uses the existing brand assets…</p>
294
294
  ```
295
295
 
296
- `.full-bleed` is injected into every presentation push. It breaks the wrapped element out of the body padding + 1400px prose cap to span the full card width, then everything outside it stays in the reading column. This is the right tool when a mockup is one section of a longer push.
296
+ `.full-bleed` is injected into every presentation push. Prose is left-aligned and capped at ~880px; `.full-bleed` fills the **content column's full width from the same left edge** wider than the prose, sharing one left margin down the card. It does *not* bleed to the card's physical edge: the body padding stays as a gutter, so neither the mockup nor the text ever touches the card border.
297
297
 
298
298
  Two cases, two tools:
299
299
  - **Whole push is a mockup / app recreation** → `kind: "mockup"` (or `"app"`) on the push. Strips the entire presentation frame; content owns the canvas.
300
300
  - **Mockup embedded in an explanation** → leave the push as-is and wrap the mockup section in `<div class="full-bleed">`.
301
301
 
302
+ ### Window chrome for UI mockups
303
+
304
+ Wrap a mockup in `.window` to give it a macOS window frame — a title bar with the three traffic-light dots and a centred title:
305
+
306
+ ```html
307
+ <div class="full-bleed">
308
+ <div class="window desktop" data-title="DVLA Self Service — Login">
309
+ <!-- mockup content fills the window body, below the 40px title bar -->
310
+ </div>
311
+ </div>
312
+ ```
313
+
314
+ - `data-title` sets the centred title text (omit for a blank bar).
315
+ - Add the **`desktop`** class for a full desktop-screen canvas — `min-height: 900px`, the standard 1440×900 (16:10) design canvas — so a screen mockup looks like a real window with viewport breathing room. **Omit `desktop`** for a dialog or small component so the chrome sizes to its content (don't pad a small thing to screen height).
316
+
317
+ **Build the mockup fluid, not fixed-width.** Lay the inside out with flex / `%` / `fr` widths, not hardcoded `width: 1440px` columns. The content column caps at a desktop-realistic width, but when the viewer's window is narrower (a "squeezed" screen) a fluid mockup simply **reflows to fit** — no horizontal scroll, nothing clipped, and PNG/PDF export still captures the whole thing. A fixed-pixel-width mockup gets cut off or needs an awkward horizontal scrollbar when squeezed; a fluid one never does. The 1440 is a *max*, not a target.
318
+
302
319
  ### Semantic chips
303
320
 
304
321
  ```html