Skip to content

feat(native): wireframe the proposed dashboard, move library paths under .holistics/ - #33

Merged
datbth merged 5 commits into
mainfrom
native-skills/dashboard-skills-wireframe-and-paths
Aug 12, 2026
Merged

feat(native): wireframe the proposed dashboard, move library paths under .holistics/#33
datbth merged 5 commits into
mainfrom
native-skills/dashboard-skills-wireframe-and-paths

Conversation

@thinhnguyentruong

Copy link
Copy Markdown
Contributor

Two independent changes to the dashboard-authoring skills. Happy to split them if you'd rather review separately — the second is a self-contained path rename.

1. build-dashboard — the plan is drawn, not described

Why

Step 2 asked the user to approve a layout described in prose ("the sections top-to-bottom by importance") plus a bullet list of blocks. The user was approving a sentence about an arrangement, not the arrangement — nothing in the plan committed the build to a shape, and nothing at verification time checked that the canvas matched what was agreed.

What changed

The proposal now ends with a block-beta wireframe on the same 12-column grid as the canvas, so column spans are the build widths (¼ 3 · ⅓ 4 · ½ 6 · full 12 → 280 / 380 / 580 / 1180 px):

```mermaid
---
config:
  fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
  htmlLabels: false
---
block-beta
columns 1
block:frame
  columns 12
  b_title["Sales Overview"]:12
  f_date["Date Range"]:3 f_country["Office Country"]:3 c_pop["Compare To"]:3 space:3
  k_sales["Total Sales · KPI"]:3 k_orders["Orders · KPI"]:3 k_cust["Customers · KPI"]:3 space:3
  h_trend["How sales are moving"]:12
  v_trend["Monthly Sales Trend · Line"]:12
  h_where["Where it comes from"]:12
  v_country["Sales by Country · Bar"]:6 v_detail["Order Detail · Table"]:6
end
classDef board fill:none,stroke:#e3e7ed
classDef sect fill:#ffffff,fill-opacity:0.6,stroke:none
classDef ctrl fill:#f5f8fa,stroke:#cbd0d7
classDef viz fill:#d1e5fa,stroke:#1b7ce4
class frame board
class b_title,h_trend,h_where sect
class f_date,f_country,c_pop ctrl
class k_sales,k_orders,k_cust,v_trend,v_country,v_detail viz
```

The wireframe is binding, not decorative: step 3 builds to it via the span→px conversion, and verify step 5 checks the canvas matches — same blocks, same rows, same spans — and requires any deviation to be named at handoff.

To pay for it, the text plan loses its per-block bullets and its **Layout** line. Both restated what the diagram now shows; block name and viz type live in the box labels.

Box fill encodes what kind of block it is — data / control / section heading — using design-system values rather than picked colours, so the diagram reads as part of the product rather than as generic mermaid.

Constraints worth knowing (all found by rendering, not by reading docs)

These are in the skill because none is guessable, and each one produced a visible defect first:

  • htmlLabels: false is required. With mermaid's default HTML labels, every label is truncated by a character or two in chat — a label is a div sized to a width measured in one font and then rendered in another, and the overflow is cut. Switching to SVG text measures the real text node and fixes it. The key must be top-level: block: { htmlLabels: false } looks equivalent and silently does nothing.
  • The cost of that: SVG text ignores the label styling a classDef carries, so label colour, size and weight always fall back to mermaid's defaults. The dead properties are deliberately not in the template — clipping was a functional defect, label typography was polish.
  • space is a keyword, not a block id. A live run emitted space1:9 and drew an empty lavender box labelled "space1" in the middle of the control row. The skill now says to write it bare however often it is needed and never number it. Styling the stray block does not help — the box disappears but the text remains.
  • Every row must total exactly 12, padded with space:<n>; boxes fill left-to-right and wrap on their own, so a short row shifts every block after it.
  • Shapes were rejected. Distinguishing headings with a stadium/rounded shape shrinks the box to fit its text instead of spanning its declared columns — which destroys true relative width, the one property the wireframe exists to convey. Fills leave the geometry untouched.

block-beta requires mermaid 11.

2. build-custom-chart, build-dashboard-theme — library paths move under .holistics/

Both skills prescribe where a new file goes. They now point at:

.holistics/library/custom_charts/<chart_name>.chart.aml
.holistics/library/themes/<slug>.theme.aml

This covers the frontmatter descriptions, the workflow steps that write the file, and the "look for something to start from" steps that read the folder. Applied to both the native-skills/ and plugins/ copy of each skill so the linked directories stay in sync.

Path strings only — the two prose references to the public chart library are untouched, since they name a catalogue rather than a folder.

Caveats

  • The wireframe was iterated against the live chat renderer over several rounds; the version here is the one that came back clean. It has not been re-run through an eval, and the eval as built grades wiring rather than presentation, so it could not grade this anyway.
  • The diagram never fills the message width. Mermaid pins an inline max-width equal to the natural content width, and block.useMaxWidth:false only replaces that with a hard pixel width — there is no setting that stretches it. Fixing it means relaxing the SVG max-width on the rendering side, which is out of scope here.
  • Section headings render as a translucent white band rather than one hugging the words, because a label's own background cannot be styled — the white has to be the box fill. Its opacity is set by contrast, not taste: at 0.6 the heading clears WCAG AA against the dark chat background; lowering it further does not.
  • Reviewers should confirm .holistics/library/ matches the project layout they expect before this lands — it is a prescribed output path, so getting it wrong sends new files somewhere that is not loaded.

Test plan

  • pnpm validate-links — all links valid
  • pnpm validate-frontmatter — all 30 files pass
  • Template parses and renders, verified on both the light and dark chat background
  • Labels render in full (no truncation) with htmlLabels: false
  • space:<n> produces no box and no label
  • A full propose → approve → build round in chat, checking the built canvas matches the confirmed wireframe

🤖 Generated with Claude Code

thinhnguyentruong and others added 2 commits August 12, 2026 16:41
build-dashboard's propose-and-confirm step now draws the proposed
dashboard as a mermaid block-beta wireframe on the same 12-column
grid as the canvas, so the user approves the real arrangement rather
than a prose description of it. Column spans are the build widths
(1/4 3, 1/3 4, 1/2 6, full 12), step 3 builds to the confirmed
wireframe, and verify step 5 checks the canvas matches it.

The text plan loses its per-block bullets and its Layout line, both
of which the diagram now carries.

Box colour encodes the kind of block -- data, control, section
heading -- using design-system values, and everything sits inside a
frame so the diagram reads as separate from the message text. The
diagram declares htmlLabels:false, without which long labels are
truncated in chat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
build-custom-chart and build-dashboard-theme each prescribe where a
new file goes. Both now point at .holistics/library/ instead of a
bare library/ at the project root:

  .holistics/library/custom_charts/<chart_name>.chart.aml
  .holistics/library/themes/<slug>.theme.aml

This covers the frontmatter descriptions, the workflow steps that
write the file, and the "look for something to start from" steps
that read the folder. Applied to both the native-skills copy and the
plugins copy of each skill so the linked directories stay in sync.

The two prose references to the public chart library are left alone;
they do not name a folder.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thinhnguyentruong and others added 3 commits August 12, 2026 17:12
…gin source

Follows the shared-content model in DEVELOPMENT.md: a skill is defined
once in a source plugin, and every consumer holds a full copy with a
.link file pointing back at it.

build-custom-chart sat at native-skills/system/build-custom-chart --
the only skill directory not under a plugin group folder, so it was
not reachable as part of a plugin. Its native copy moves to
native-skills/system/holistics-development/ and now links to the
existing plugins/holistics-development/skills/build-custom-chart. The
two directories were previously independent copies with nothing
enforcing that they matched.

build-dashboard had no plugin copy at all. Its content becomes the
source at plugins/holistics-development/skills/build-dashboard, and
the native copy keeps its path at native-skills/system/
holistics-common/build-dashboard, now carrying a .link.

build-dashboard-theme was already correct and is untouched.

Copies were produced with `pnpm sync-links`, so edits from here go to
the source under plugins/ and propagate outward.

Side effect: build-dashboard and build-custom-chart are now covered by
`pnpm validate-frontmatter`, which globs plugins/**/SKILL.md only --
31 files validated, up from 30.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@datbth
datbth merged commit 8f44a8b into main Aug 12, 2026
4 checks passed
@datbth
datbth deleted the native-skills/dashboard-skills-wireframe-and-paths branch August 12, 2026 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants