comark-ui 0.10.0 → 0.10.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/client.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as typesetStylesheet, t as typesetCss } from "./typeset-css-BOtdXbMg.mjs";
1
+ import { n as typesetStylesheet, t as typesetCss } from "./typeset-css-BqBoCTMG.mjs";
2
2
  import { i as startMermaid, n as mermaidBar, r as mermaidCss, t as addMermaidStyles } from "./client-zWY8yhUx.mjs";
3
3
  export { addMermaidStyles, mermaidBar, mermaidCss, startMermaid, typesetCss, typesetStylesheet };
package/dist/html.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as commentsCss, n as Preset, o as criticCss, r as PresetOptions } from "./index-CNYr62nX.mjs";
1
+ import { a as commentsCss, n as Preset, o as criticCss, r as PresetOptions } from "./index-7SBL13EQ.mjs";
2
2
  import { NodeHandler } from "comark";
3
3
  //#region src/html.d.ts
4
4
  /**
package/dist/html.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as criticCss, r as preset, t as commentsCss } from "./src-C3nMECXA.mjs";
2
- import { t as typesetCss } from "./typeset-css-BOtdXbMg.mjs";
2
+ import { t as typesetCss } from "./typeset-css-BqBoCTMG.mjs";
3
3
  import { a as start, n as mermaidBar, r as mermaidCss } from "./client-zWY8yhUx.mjs";
4
4
  import { t as rawText } from "./text-D8j9clg3.mjs";
5
5
  import { escapeHtml } from "comark/utils";
@@ -67,7 +67,7 @@ const mermaid = (zooms) => ({
67
67
  const width = /^<div[^>]*><svg[^>]* width="([\d.]+)"/.exec(card)?.[1];
68
68
  const wide = width ? ` data-wide style="--cmm-svg:${Math.ceil(Number(width))}px"` : "";
69
69
  const zoomed = zooms && width ? card.replace(/^<div/, "<div data-zoom tabindex=\"0\"") : card;
70
- return (first ? `<style data-comark-mermaid>${mermaidCss}</style>` : "") + `<div class="cmm"${wide} data-source="${attr(source)}">${zoomed}<div class="cmm-bar">${mermaidBar()}</div>${first ? `<script>${mermaidScript}<\/script>` : ""}${zooms && width ? zoom.runtime(state) : ""}</div>`;
70
+ return (first ? `<style data-comark-mermaid>${mermaidCss}</style>` : "") + `<div class="cmm" data-comark-frame${wide} data-source="${attr(source)}">${zoomed}<div class="cmm-bar">${mermaidBar()}</div>${first ? `<script>${mermaidScript}<\/script>` : ""}${zooms && width ? zoom.runtime(state) : ""}</div>`;
71
71
  }) }
72
72
  });
73
73
  const typeset = () => `<style data-comark-typeset>${typesetCss}</style>`;
@@ -63,7 +63,7 @@ type ShikiOptions = {
63
63
  * and report a limit issue without checking whether the language is supported.
64
64
  */
65
65
  highlighter: (language: string) => ShikiHighlighter | undefined | Promise<ShikiHighlighter | undefined>;
66
- /** Theme names your highlighter has loaded. The dark one goes in `--shiki-dark`, which the typeset styles follow. */
66
+ /** Theme names your highlighter has loaded. The dark one goes in `--shiki-dark`, which typeset and comark-code's styles follow. */
67
67
  themes: {
68
68
  light: string;
69
69
  dark?: string;
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { n as typesetStylesheet, t as typesetCss } from "./typeset-css-DtOLAa1Z.mjs";
2
- import { a as commentsCss, c as TYPESET_TAG, d as ShikiOptions, f as MermaidOptions, i as Renderer, l as typeset, n as Preset, o as criticCss, r as PresetOptions, s as preset, t as AnyPlugin, u as ShikiHighlighter } from "./index-CNYr62nX.mjs";
2
+ import { a as commentsCss, c as TYPESET_TAG, d as ShikiOptions, f as MermaidOptions, i as Renderer, l as typeset, n as Preset, o as criticCss, r as PresetOptions, s as preset, t as AnyPlugin, u as ShikiHighlighter } from "./index-7SBL13EQ.mjs";
3
3
  export { AnyPlugin, type MermaidOptions, Preset, PresetOptions, Renderer, type ShikiHighlighter, type ShikiOptions, TYPESET_TAG, commentsCss, criticCss, preset, typeset, typesetCss, typesetStylesheet };
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
1
  import { a as typeset, i as TYPESET_TAG, n as criticCss, r as preset, t as commentsCss } from "./src-C3nMECXA.mjs";
2
- import { n as typesetStylesheet, t as typesetCss } from "./typeset-css-BOtdXbMg.mjs";
2
+ import { n as typesetStylesheet, t as typesetCss } from "./typeset-css-BqBoCTMG.mjs";
3
3
  export { TYPESET_TAG, commentsCss, criticCss, preset, typeset, typesetCss, typesetStylesheet };
package/dist/react.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as commentsCss, n as Preset, o as criticCss, r as PresetOptions } from "./index-CNYr62nX.mjs";
1
+ import { a as commentsCss, n as Preset, o as criticCss, r as PresetOptions } from "./index-7SBL13EQ.mjs";
2
2
  import { ComponentType } from "react";
3
3
  //#region src/react.d.ts
4
4
  type AnyComponent = ComponentType<any>;
package/dist/react.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as criticCss, r as preset, t as commentsCss } from "./src-C3nMECXA.mjs";
2
- import { t as typesetCss } from "./typeset-css-BOtdXbMg.mjs";
2
+ import { t as typesetCss } from "./typeset-css-BqBoCTMG.mjs";
3
3
  import { i as startMermaid, n as mermaidBar, t as addMermaidStyles } from "./client-zWY8yhUx.mjs";
4
4
  import { createElement, useEffect } from "react";
5
5
  import * as badge from "comark-badge/react";
@@ -44,6 +44,7 @@ function Mermaid(props) {
44
44
  useEffect(() => startMermaid(), []);
45
45
  return createElement("div", {
46
46
  className: "cmm",
47
+ "data-comark-frame": "",
47
48
  "data-source": props.content
48
49
  }, createElement(Pele, props), createElement("div", {
49
50
  className: "cmm-bar",
@@ -53,7 +53,7 @@ Problems land in `meta.issues` after `parseMarkdown`, one sentence each, and a h
53
53
 
54
54
  ## Shape the document
55
55
 
56
- This skill teaches the blocks. Four sibling skills teach a whole document, what goes in it and in what order: `before-after-evidence`, `review-document`, `visual-explanation`, and `teach-lesson`. When the user asks for one of those and it isn't installed, suggest `vp dlx skills add onmax/comark-ui` and picking it from the list.
56
+ This skill teaches the blocks. Five sibling skills teach a whole document, what goes in it and in what order: `before-after-evidence`, `review-document`, `report`, `visual-explanation`, and `teach-lesson`. When the user asks for one of those and it isn't installed, suggest `vp dlx skills add onmax/comark-ui` and picking it from the list.
57
57
 
58
58
  ## Pick the blocks
59
59
 
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: report
3
+ description: Writes research, a ranked shortlist, a comparison, or a plan as one Markdown page someone decides from, with the answer and decisions first, the numbers in charts, and the detail folded. Use when the reader has to choose between options or approve a plan.
4
+ license: MIT
5
+ ---
6
+
7
+ # Report
8
+
9
+ The reader scans a report before reading it. They want the answer, the decisions they have to make, and the numbers behind both, and they check the rest only when they doubt something. So the page has a fixed shape: the answer on top, one picture per section, short table cells, and detail folded underneath.
10
+
11
+ For findings about something that already exists, such as a code review or an audit, use `review-document`. For how something works, use `visual-explanation`. This skill shapes a report you already have the material for; gathering the material is the research itself.
12
+
13
+ ## 1. Write the answer and the decisions
14
+
15
+ Write the answer in two sentences: what you recommend and the main reason. For a plan, that's the first step and the goal it serves. Under it, write each decision the reader has to make as a question they can answer yes or no. Up to three go in the callout as a numbered list. Past three, ask one question ("Take my recommendation on all seven?") and give the decisions their own table right after the answer.
16
+
17
+ Done when someone who reads only the answer and the callout knows what you recommend and what they have to decide.
18
+
19
+ ## 2. Give every fact one home
20
+
21
+ List what the report holds: the items, their numbers, any order, the blockers, the findings, what you left out, how you checked. Give each one exactly one section. When the items have both a rank and an order to do them in, keep the order the reader acts on and put the rank's inputs, if it has any, in the picture. Another section refers to a fact by its name or number ("change 3", "D2") and leaves its value where it lives. Reuse the source's numbering; when you have to add IDs, give each kind a prefix no other kind starts with. A chart's table is already under it in a Data fold, so it gets no second copy.
22
+
23
+ Done when no value, list, or order is written out in two sections.
24
+
25
+ ## 3. Pick one picture per section
26
+
27
+ A section opens with one sentence that says what to look at, then its picture. A second picture fits only when it answers the question the first one raises, such as the table of steps under the flowchart of their order. Numbers live in charts and table columns, and a sentence names only the number that matters.
28
+
29
+ | The section answers | Picture |
30
+ | --- | --- |
31
+ | Which items are worth it, by two scores and a size | Bubble chart: `::chart` with a `vega-lite` spec |
32
+ | How big each item is, or what each blocker would unlock | `::chart{type="bar" horizontal labels}` |
33
+ | How each item's size splits into parts | `::chart{type="stacked" horizontal}` |
34
+ | In what order, and what has to land first | `mermaid` flowchart, blockers as `{{hexagons}}` |
35
+ | How a mechanism moves between states | `mermaid` `stateDiagram-v2` |
36
+ | A number before and after | `::stats` or `:delta` |
37
+ | A share of a whole | `:progress` |
38
+ | Findings, options, or decisions compared across the same columns | Table of at most five columns, `:badge` for categories and verdicts |
39
+ | Detail per item | `::accordion`, one item per row, the same parts inside every item |
40
+ | What you left out | Bar chart of the largest, then `::accordion` grouped by reason |
41
+ | How you checked | `> [!CAUTION]` for what you didn't verify, kept open; sources in `::details` |
42
+
43
+ A table cell holds a value, a badge, or a few words. The reasoning behind a cell goes in that item's accordion. A column whose cells are all the same says one thing, so say it in the section's sentence and drop the column. Two charts that compare the same unit share one scale, so draw them as one chart, or fix the axis domain in both.
44
+
45
+ [references/blocks.md](references/blocks.md) has the syntax for each, with the gotchas the renderer doesn't report. The `comark-ui` skill documents every block in full.
46
+
47
+ Done when every section opens with its sentence and its picture, every number the answer rests on sits in a chart or a table column, and no table cell runs past a line or two at reading width.
48
+
49
+ ## 4. Assemble the page
50
+
51
+ The two ends are fixed, and the middle holds the sections your material has, in the order the reader acts on them:
52
+
53
+ ```text
54
+ Frontmatter title = the answer in under 70 characters; status, date, tags
55
+ The answer two sentences, the decisions in > [!IMPORTANT], at most one > [!WARNING]
56
+ Decisions the decision table, only when there are more than three
57
+ middle from step 3, such as: the picture the answer rests on, findings,
58
+ the order, blockers, before and after, each item, left out
59
+ How I checked > [!CAUTION] open, sources folded
60
+ ```
61
+
62
+ Keep open what the reader decides on, and fold what they would only check: each decision and your recommendation stay open in the callout or the decision table, and the arguments behind them fold. When each item fits one table row, the table is the item list and needs no accordion. Past about a dozen items, the table is the list, and only the items that need reasoning get an accordion item. Lists stay one level deep; a second level becomes a table. Cards are for links to the next pages only.
63
+
64
+ [references/example.md](references/example.md) is a full report in this shape: the answer and decision on top, a bubble chart, one order shown as a flowchart and a table, blockers sized by what they unlock, one accordion item per module with the same parts, the left-out chart with its groups, and the open "Not verified" callout.
65
+
66
+ Done when the page follows this order and nothing the reader decides on is folded.
67
+
68
+ ## 5. Check the render
69
+
70
+ 1. Lint it, and fix until it reports no problems:
71
+
72
+ ```sh
73
+ vp dlx --package comark-linter --package comark-ui comark-lint report.md
74
+ ```
75
+
76
+ These commands use the [global Vite+ CLI](https://viteplus.dev/guide/global-cli). Without it, `pnpm dlx` takes the same arguments.
77
+
78
+ 2. Render it as [references/blocks.md](references/blocks.md#render-it-locally) shows, and read every screenshot, closed and open. Labels must not overlap, each chart must say what its sentence says, table cells must stay short, and diagram text must read at the size of the body text. A wide flowchart renders small: switch it to `TB`, shorten its labels, or split it past about ten nodes.
79
+ 3. Hand it over where the task says. When it goes to a host such as Drop, publish it as the host's skill describes and give the link.
80
+
81
+ Done when lint reports no problems and you've read every screenshot of the render.
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Report"
3
+ short_description: "Answer and decisions first, numbers in charts, detail folded"
@@ -0,0 +1,199 @@
1
+ # Blocks for a report
2
+
3
+ Each block below renders with the full `comark-ui` preset. The `comark-ui` skill documents every block in full; read its reference for a block before you change more than the values here.
4
+
5
+ ## The answer: callouts
6
+
7
+ ```md
8
+ > [!IMPORTANT]
9
+ > **Your calls:**
10
+ >
11
+ > 1. Hold `@nuxtjs/i18n` until #3564 has URL routing?
12
+ > 2. Ship the Env and Resend codemods before Auth's SSR gap closes?
13
+
14
+ > [!WARNING]
15
+ > Every row needs Nuxt 5, and the codemods don't upgrade Nuxt.
16
+ ```
17
+
18
+ Frontmatter `status`, `date`, and `tags` render as a properties box at the top with no extra markup.
19
+
20
+ ## Bubble chart: two scores and a size
21
+
22
+ ````md
23
+ ::chart{title="Shortlist: value and difficulty (1 to 5), bubble size = npm downloads a week"}
24
+ | module | difficulty | value | downloads |
25
+ | --- | --: | --: | --: |
26
+ | nuxt-auth-utils | 4 | 5 | 177926 |
27
+ | Resend | 2 | 4 | 1251 |
28
+ | t3-env | 2 | 3 | 6072 |
29
+ | nuxt-cron | 2 | 3 | 3123 |
30
+
31
+ ```vega-lite
32
+ {
33
+ "width": 620,
34
+ "height": 320,
35
+ "encoding": {
36
+ "x": { "field": "difficulty", "type": "quantitative", "scale": { "domain": [1.5, 5] }, "title": "Difficulty (5 = hardest)" },
37
+ "y": { "field": "value", "type": "quantitative", "scale": { "domain": [2.5, 5.5] }, "title": "Value (5 = most)" }
38
+ },
39
+ "layer": [
40
+ {
41
+ "mark": { "type": "circle", "opacity": 0.55 },
42
+ "encoding": { "size": { "field": "downloads", "type": "quantitative", "scale": { "range": [80, 3000] }, "legend": null } }
43
+ },
44
+ {
45
+ "transform": [{ "filter": "indexof(['Resend', 't3-env', 'nuxt-cron'], datum.module) < 0" }],
46
+ "mark": { "type": "text", "dy": -26, "fontSize": 12 },
47
+ "encoding": { "text": { "field": "module" } }
48
+ },
49
+ {
50
+ "transform": [{ "filter": "indexof(['Resend', 't3-env'], datum.module) >= 0" }],
51
+ "mark": { "type": "text", "align": "right", "dx": -12, "fontSize": 12 },
52
+ "encoding": { "text": { "field": "module" } }
53
+ },
54
+ {
55
+ "transform": [{ "filter": "datum.module === 'nuxt-cron'" }],
56
+ "mark": { "type": "text", "dy": 16, "fontSize": 12 },
57
+ "encoding": { "text": { "field": "module" } }
58
+ }
59
+ ]
60
+ }
61
+ ```
62
+ ::
63
+ ````
64
+
65
+ - With a `vega-lite` spec, `::chart` takes only `title`; `type`, `x`, and `y` are lint errors. Name the columns in `encoding`.
66
+ - Set `width` in pixels. `"container"` renders about 230px wide.
67
+ - Labels overlap when two points share a spot or sit close. Give each label layer a `filter` and move those points' labels left (`align: right`, `dx: -12`) or below (`dy: 16`). Look at the render; the lint can't see overlap.
68
+ - Write a range such as 4–5 as its middle, 4.5, and say so in the item's detail.
69
+
70
+ ## Bar chart: sizes, with one mark
71
+
72
+ ```md
73
+ ::chart{type="bar" horizontal labels title="Left out: npm downloads a week (10k and up)"}
74
+ | module | downloads |
75
+ | --- | --: |
76
+ | @nuxtjs/i18n | 977490 |
77
+ | nuxt-csurf | 223523 |
78
+ :::annotation{at="@nuxtjs/i18n" mark="box" color="amber" side="right"}
79
+ Your call: hold until #3564 has URL routing.
80
+ :::
81
+ ::
82
+ ```
83
+
84
+ Rows draw in table order, so sort them largest first. Mark the bar a decision is about, at most one; a chart no decision points at gets no mark.
85
+
86
+ For sizes that split into parts, use `type="stacked"`, one column per part:
87
+
88
+ ```md
89
+ ::chart{type="stacked" horizontal title="Description characters per skill"}
90
+ | skill | sentence | trigger list |
91
+ | --- | --: | --: |
92
+ | emil-mobile-native | 760 | 551 |
93
+ | emil-prep-for-prod | 865 | 386 |
94
+ ::
95
+ ```
96
+
97
+ Each chart scales its own axis. When two charts compare the same unit, put the rows in one chart, or write both in `vega-lite` with the same `"scale": { "domain": [0, 1400] }` on the value axis, so equal values draw equal bars.
98
+
99
+ ## Order and blockers: a flowchart
100
+
101
+ ````md
102
+ ```mermaid
103
+ flowchart LR
104
+ shell["1 · Wizard shell + Env"]
105
+ shell --> resend["2 · Resend"]
106
+ shell --> auth["3 · Auth"]
107
+ ssr{{"SSR session + page middleware"}} --> auth
108
+ upstash{{"Upstash driver"}} -.-> rl["5 · Rate limit"]
109
+ ```
110
+ ````
111
+
112
+ Use `LR` for up to about five steps side by side and `TB` for a longer chain or long labels; the diagram scales down to fit the page width, so a wide one renders small. Boxes are steps, numbered in the order the reader acts. Hexagons are work that has to land first; a dashed arrow means it should land first but doesn't have to. Say both in the sentence above the diagram.
113
+
114
+ ## The decision table: past three decisions
115
+
116
+ ```md
117
+ | # | Decision | Opus | Sol | Recommend |
118
+ | --- | --- | --- | --- | --- |
119
+ | D1 | Import family for apps | `vite-hub/*` | `@vite-hub/*` | :badge[vite-hub/*]{color="success"} |
120
+ | D2 | Sandbox Task option key | `sandboxTask` | `sandbox.tasks` | :badge[sandboxTask]{color="success"} |
121
+ ```
122
+
123
+ Each cell is the position, not the argument. The arguments go in the decision's accordion item, labeled with its number.
124
+
125
+ ## The table: at most five columns
126
+
127
+ ```md
128
+ | Step | Module → primitive | npm/week | Fit |
129
+ | --- | --- | --: | --- |
130
+ | 1 | `@t3-oss/env-nuxt` → Env | 6,072 | :badge[High]{color="success"} |
131
+ | 3 | `nuxt-auth-utils` → Auth | 177,926 | :badge[Partial]{color="warning"} |
132
+ ```
133
+
134
+ Badge colors: `success` good, `warning` partial or at risk, `error` blocked, `neutral` unknown. Scores that are already in a chart stay out of the table. A cell holds a value, a badge, or a few words; a column of sentences turns the table into a wall of text, so move it into the accordion.
135
+
136
+ Write file names and domains in backticks, such as `AGENTS.md` and `devtools.fm`. Bare, they render as link chips with an icon.
137
+
138
+ ## Each item: an accordion
139
+
140
+ ````md
141
+ ::accordion
142
+ :::accordion-item{label="2 · Resend → Email"}
143
+ | Resend | ViteHub Email |
144
+ | --- | --- |
145
+ | `new Resend(key).emails.send(msg)` | `email.send(msg)` |
146
+
147
+ - **Manual:** batch, contacts, audiences, broadcasts.
148
+ - **First:** nothing.
149
+ - **Gain:** a dev outbox and Console preview.
150
+ :::
151
+ ::
152
+ ````
153
+
154
+ Every item has the same parts in the same order, with bold labels, a line or two each. A part that needs more becomes a table inside the item. The label starts with the item's step number from the table. Icons come from `lucide:`; pick one per kind of item.
155
+
156
+ ## Before and after: stats and delta
157
+
158
+ ```md
159
+ ::stats{better="lower"}
160
+ | Measure | Before | After |
161
+ | --- | --: | --: |
162
+ | Description characters loaded | 23,515 | 10,981 |
163
+ | Model-invoked skills | 49 | 41 |
164
+ ::
165
+
166
+ Trimming the lists saves :delta{from=23515 to=10981 unit="chars" better="lower"} every session.
167
+ ```
168
+
169
+ `::stats` holds one table of exactly three columns: a name, before, after. Each cell is a number with an optional unit, the same unit in both cells, and the block adds the percent itself. A value with a qualifier, such as "about 65" or "6 of 11", belongs in a plain table, or keeps its number in the cell and moves the qualifier into the row's name. `better` applies to every row, so rows that are better higher go in a second block.
170
+
171
+ ## A share: progress
172
+
173
+ ```md
174
+ :progress{value=293 max=785 label="nuxt-security configs that mention rateLimiter"}
175
+ ```
176
+
177
+ ## How I checked
178
+
179
+ ````md
180
+ > [!CAUTION]
181
+ > **Not verified:** any source module on Nuxt 5; the Docus count (one npm call).
182
+
183
+ ::details{summary="Sources and method"}
184
+ - **Downloads:** `api.npmjs.org/downloads/point/last-week`, 2026-10-30 to 2026-11-05.
185
+ ::
186
+ ````
187
+
188
+ ## Render it locally
189
+
190
+ A host renders the report only after you publish it, and a private page may need the user's sign-in, so check the render before you hand it over. Copy this skill's [scripts/render.mjs](../scripts/render.mjs) next to the report, then:
191
+
192
+ ```sh
193
+ mkdir -p tmp/report-render && cd tmp/report-render
194
+ echo '{ "private": true, "type": "module" }' > package.json
195
+ pnpm add --ignore-workspace comark @comark/html comark-ui playwright
196
+ node ../../render.mjs ../../report.md out
197
+ ```
198
+
199
+ Without its own `package.json`, pnpm walks up to the repository's and can fail on its catalog. The script writes `out/report.html` and screenshots at 900px wide, 1600px tall each: `report-closed-*.png` as the reader first sees it, and `report-open-*.png` with every fold open. When Playwright has no browser downloaded, it uses the newest Chromium in `~/.cache/ms-playwright`.