plotleaf 0.1.0 → 0.3.0

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.
@@ -0,0 +1,78 @@
1
+ [
2
+ {
3
+ "product": "Linen tote",
4
+ "image": "./assets/linen-tote.png",
5
+ "image_alt": "Illustration of a sand-coloured linen tote",
6
+ "weekly_orders": [
7
+ 42,
8
+ 47,
9
+ 44,
10
+ 56,
11
+ 59,
12
+ 63,
13
+ 68,
14
+ 74
15
+ ],
16
+ "orders": 453,
17
+ "revenue": 18120,
18
+ "change": 0.182,
19
+ "last_week": 74
20
+ },
21
+ {
22
+ "product": "Desk lamp",
23
+ "image": "./assets/desk-lamp.jpg",
24
+ "image_alt": "Illustration of a blue desk lamp",
25
+ "weekly_orders": [
26
+ 38,
27
+ 35,
28
+ 39,
29
+ null,
30
+ 46,
31
+ 44,
32
+ 49,
33
+ 53
34
+ ],
35
+ "orders": 304,
36
+ "revenue": 27360,
37
+ "change": 0.124,
38
+ "last_week": 53
39
+ },
40
+ {
41
+ "product": "Field notebook",
42
+ "image": "./assets/field-notebook.png",
43
+ "image_alt": "Illustration of a green field notebook",
44
+ "weekly_orders": [
45
+ 60,
46
+ 63,
47
+ 59,
48
+ 64,
49
+ 62,
50
+ 69,
51
+ 72,
52
+ 78
53
+ ],
54
+ "orders": 527,
55
+ "revenue": 10540,
56
+ "change": 0.068,
57
+ "last_week": 78
58
+ },
59
+ {
60
+ "product": "Linen tote \u2014 natural",
61
+ "image": "./assets/linen-tote.png",
62
+ "image_alt": "Illustration of the same sand-coloured linen tote in a second product row",
63
+ "weekly_orders": [
64
+ 18,
65
+ 21,
66
+ 20,
67
+ 24,
68
+ 23,
69
+ 27,
70
+ 29,
71
+ 31
72
+ ],
73
+ "orders": 193,
74
+ "revenue": 7720,
75
+ "change": 0.094,
76
+ "last_week": 31
77
+ }
78
+ ]
@@ -0,0 +1,39 @@
1
+ ---
2
+ title: Product Performance
3
+ description: A fictional catalogue with embedded product images and weekly order sparklines.
4
+ ---
5
+
6
+ # Product Performance
7
+
8
+ A fictional store's product performance over **eight weeks ending 1 November 2026**. All data, comparisons and product illustrations are synthetic and prepared for this example.
9
+
10
+ :::grid{columns="3"}
11
+ ::metric{label="Orders" value="1477" comparison="18.2% vs previous eight weeks" direction="up" sentiment="positive"}
12
+ ::metric{label="Revenue" value="63740" format="currency:USD" comparison="20% vs previous eight weeks" direction="up" sentiment="positive"}
13
+ ::metric{label="Products" value="4" comparison="1 more than previous period" direction="up" sentiment="positive"}
14
+ :::
15
+
16
+ The fictional comparison period contains **1,250 orders**, **US$53,120 revenue** and **three products**. Changes above are prepared and rounded by the example author.
17
+
18
+ ## Product detail
19
+
20
+ Weekly order lines share the same vertical scale, so their heights are comparable. The lamp has one missing week, shown as a gap; its prepared total covers recorded weeks only. Expand **View values** to inspect the original samples.
21
+
22
+ :::table{data="./products.json" title="Performance by product"}
23
+ ::column{field="image" label="Preview" kind="image" alt="image_alt"}
24
+ ::column{field="product" label="Product"}
25
+ ::column{field="weekly_orders" label="Weekly orders" kind="sparkline" sortBy="last_week"}
26
+ ::column{field="orders" label="Orders" format="number"}
27
+ ::column{field="revenue" label="Revenue" format="currency:USD"}
28
+ ::column{field="change" label="Δ period" format="percent" sign="always" semantics="higher-is-better"}
29
+ :::
30
+
31
+ ### Reading this table
32
+
33
+ - **Linen tote leads relative growth.** Comparisons are prepared by the author, not calculated from the sparkline.
34
+ - **Notebooks lead order volume.** They also have the highest final-week value in this fictional set.
35
+ - **The natural tote reuses its image.** The portable report embeds each unique illustration once.
36
+
37
+ :::callout{title="Coverage"}
38
+ Every value and illustration is fictional. Sorting Weekly orders uses the declared final-week key; it does not compare arrays or recompute totals. No live filters or subtotal calculations are implied.
39
+ :::
@@ -0,0 +1,78 @@
1
+ [
2
+ {
3
+ "product": "Linen tote",
4
+ "image": "./catalog/assets/linen-tote.png",
5
+ "image_alt": "Illustration of a sand-coloured linen tote",
6
+ "weekly_orders": [
7
+ 42,
8
+ 47,
9
+ 44,
10
+ 56,
11
+ 59,
12
+ 63,
13
+ 68,
14
+ 74
15
+ ],
16
+ "orders": 453,
17
+ "revenue": 18120,
18
+ "change": 0.182,
19
+ "last_week": 74
20
+ },
21
+ {
22
+ "product": "Desk lamp",
23
+ "image": "./catalog/assets/desk-lamp.jpg",
24
+ "image_alt": "Illustration of a blue desk lamp",
25
+ "weekly_orders": [
26
+ 38,
27
+ 35,
28
+ 39,
29
+ null,
30
+ 46,
31
+ 44,
32
+ 49,
33
+ 53
34
+ ],
35
+ "orders": 304,
36
+ "revenue": 27360,
37
+ "change": 0.124,
38
+ "last_week": 53
39
+ },
40
+ {
41
+ "product": "Field notebook",
42
+ "image": "./catalog/assets/field-notebook.png",
43
+ "image_alt": "Illustration of a green field notebook",
44
+ "weekly_orders": [
45
+ 60,
46
+ 63,
47
+ 59,
48
+ 64,
49
+ 62,
50
+ 69,
51
+ 72,
52
+ 78
53
+ ],
54
+ "orders": 527,
55
+ "revenue": 10540,
56
+ "change": 0.068,
57
+ "last_week": 78
58
+ },
59
+ {
60
+ "product": "Linen tote — natural",
61
+ "image": "./catalog/assets/linen-tote.png",
62
+ "image_alt": "Illustration of the same sand-coloured linen tote in a second product row",
63
+ "weekly_orders": [
64
+ 18,
65
+ 21,
66
+ 20,
67
+ 24,
68
+ 23,
69
+ 27,
70
+ 29,
71
+ 31
72
+ ],
73
+ "orders": 193,
74
+ "revenue": 7720,
75
+ "change": 0.094,
76
+ "last_week": 31
77
+ }
78
+ ]
@@ -0,0 +1,30 @@
1
+ [
2
+ {
3
+ "stage": "Visited",
4
+ "teams": 41200,
5
+ "baseline": 41200,
6
+ "share": 1.0,
7
+ "status": "on-target"
8
+ },
9
+ {
10
+ "stage": "Signed up",
11
+ "teams": 12480,
12
+ "baseline": 41200,
13
+ "share": 0.3029126213592233,
14
+ "status": "on-target"
15
+ },
16
+ {
17
+ "stage": "Activated",
18
+ "teams": 7612,
19
+ "baseline": 41200,
20
+ "share": 0.18475728155339805,
21
+ "status": "below-target"
22
+ },
23
+ {
24
+ "stage": "Converted",
25
+ "teams": 1284,
26
+ "baseline": 41200,
27
+ "share": 0.03116504854368932,
28
+ "status": "at-risk"
29
+ }
30
+ ]
@@ -0,0 +1,14 @@
1
+ [
2
+ {
3
+ "plan": "Pro",
4
+ "teams": 5100
5
+ },
6
+ {
7
+ "plan": "Team",
8
+ "teams": 1900
9
+ },
10
+ {
11
+ "plan": "Free",
12
+ "teams": 612
13
+ }
14
+ ]
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: PLG Onboarding
3
+ description: A fictional product onboarding report with prepared funnel and plan data.
4
+ ---
5
+
6
+ # PLG Onboarding
7
+
8
+ A fictional product's onboarding performance, **6 April–28 June 2026**. All values and comparisons are synthetic, prepared by the example author.
9
+
10
+ :::grid{columns="4"}
11
+ ::metric{label="Signups" value="12480" comparison="18.2% vs previous quarter" direction="up" sentiment="positive"}
12
+ ::metric{label="Activated teams" value="7612" comparison="24.1% vs previous quarter" direction="up" sentiment="positive"}
13
+ ::metric{label="Converted" value="1284" comparison="11.4% vs previous quarter" direction="up" sentiment="positive"}
14
+ ::metric{label="Conversion rate" value="0.10288461538461538" format="percent" comparison="0.8 pt vs previous quarter" direction="up" sentiment="positive"}
15
+ :::
16
+
17
+ :::grid{columns="2"}
18
+ ::area{data="./signups.json" x="week" y="signups" xType="date" title="Signups by week"}
19
+ ::funnel{data="./funnel.json" stage="stage" value="teams" total="baseline" share="share" status="status" title="Funnel by stage"}
20
+ :::
21
+
22
+ ## Activation mix
23
+
24
+ **7,612 teams** activated. Pro accounts for the largest share; each category below is mutually exclusive. Funnel percentages use **41,200 visitors** as the explicit denominator. The KPI conversion rate uses **12,480 signups**, so it answers a different question.
25
+
26
+ ::::grid{columns="2"}
27
+ ::donut{data="./plans.json" category="plan" value="teams" title="Activated teams by plan"}
28
+ :::table{data="./plans.json" title="Activated teams"}
29
+ ::column{field="plan" label="Plan"}
30
+ ::column{field="teams" label="Teams" format="number"}
31
+ :::
32
+ ::::
33
+
34
+ ### Key findings
35
+
36
+ - **Activation is the next opportunity.** Its below-target status is supplied by the author; the renderer does not infer it from the rate.
37
+ - **Conversion needs attention.** The author marked this stage at risk against the fictional team's own operating targets.
38
+ - **Pro leads the mix.** Plan counts add to the same 7,612 activated teams shown in the KPI and funnel.
39
+
40
+ :::callout{title="About this example"}
41
+ All data, comparisons, statuses and findings are fictional. This report has no live filters or data connections. The funnel preserves the prepared stage order and never guesses a denominator or business status.
42
+ :::
@@ -0,0 +1,50 @@
1
+ [
2
+ {
3
+ "week": "2026-04-06",
4
+ "signups": 700
5
+ },
6
+ {
7
+ "week": "2026-04-13",
8
+ "signups": 800
9
+ },
10
+ {
11
+ "week": "2026-04-20",
12
+ "signups": 770
13
+ },
14
+ {
15
+ "week": "2026-04-27",
16
+ "signups": 850
17
+ },
18
+ {
19
+ "week": "2026-05-04",
20
+ "signups": 980
21
+ },
22
+ {
23
+ "week": "2026-05-11",
24
+ "signups": 1050
25
+ },
26
+ {
27
+ "week": "2026-05-18",
28
+ "signups": 1040
29
+ },
30
+ {
31
+ "week": "2026-05-25",
32
+ "signups": 1120
33
+ },
34
+ {
35
+ "week": "2026-06-01",
36
+ "signups": 1180
37
+ },
38
+ {
39
+ "week": "2026-06-08",
40
+ "signups": 1160
41
+ },
42
+ {
43
+ "week": "2026-06-15",
44
+ "signups": 1230
45
+ },
46
+ {
47
+ "week": "2026-06-22",
48
+ "signups": 1600
49
+ }
50
+ ]
@@ -0,0 +1,96 @@
1
+ ---
2
+ title: Storefront Overview
3
+ description: A cumulative plotleaf showcase with fictional metrics, charts, tables, images and sparklines.
4
+ ---
5
+
6
+ # Storefront Overview
7
+
8
+ A fictional store's weekly performance, using synthetic data for demonstration. Orders grew **18.2%**, while returns fell **12%** from the previous period.
9
+
10
+ :::grid{columns="4"}
11
+ ::metric{label="Orders" value="12480" comparison="18.2% vs previous week" direction="up" sentiment="positive"}
12
+ ::metric{label="Revenue" value="824160" format="currency:USD" comparison="24.1% vs previous week" direction="up" sentiment="positive"}
13
+ ::metric{label="Returns" value="384" comparison="12% vs previous week" direction="down" sentiment="positive"}
14
+ ::metric{label="Return rate" value="0.03076923076923077" format="percent" comparison="0.4 pt vs previous week" direction="down" sentiment="positive"}
15
+ :::
16
+
17
+ ## Sales and returns
18
+
19
+ The store received **12,480 orders** over seven days. Size-related returns made up most of the **384 returns**, suggesting a useful area for clearer product guidance.
20
+
21
+ :::grid{columns="2"}
22
+ ::area{data="./storefront/orders.json" x="date" y="orders" xType="date" title="Orders by day" target="2000" targetLabel="Daily target"}
23
+ ::bar{data="./storefront/returns.json" x="reason" y="count" title="Returns by reason"}
24
+ :::
25
+
26
+ ## Sales by category
27
+
28
+ Apparel accounts for the largest share of this fictional week's **12,480 orders**. Each order belongs to one category.
29
+
30
+ ::::grid{columns="2"}
31
+ ::donut{data="./storefront/categories.json" category="category" value="orders" title="Order mix"}
32
+ :::table{data="./storefront/categories.json" title="Category performance"}
33
+ ::column{field="category" label="Category"}
34
+ ::column{field="orders" label="Orders" format="number"}
35
+ ::column{field="revenue" label="Revenue" format="currency:USD"}
36
+ ::column{field="change" label="Δ week" format="percent" sign="always" semantics="higher-is-better"}
37
+ :::
38
+ ::::
39
+
40
+ ### Key findings
41
+
42
+ - **Growth spans every category.** All four categories increased orders over the previous week.
43
+ - **Returns declined.** The return count and rate both improved.
44
+ - **Size guidance is the next opportunity.** Review fit descriptions before changing the return policy.
45
+
46
+ ---
47
+
48
+ ## Product onboarding
49
+
50
+ A separate fictional product example covers **6 April–28 June 2026**. Its prepared funnel uses **41,200 visitors** as the denominator for every stage; its statuses reflect the example author's operating targets. These team counts are independent of the store's orders above.
51
+
52
+ :::grid{columns="2"}
53
+ ::line{data="./onboarding/signups.json" x="week" y="signups" xType="date" title="Signups by week" target="1600" targetLabel="Weekly target"}
54
+ ::funnel{data="./onboarding/funnel.json" stage="stage" value="teams" total="baseline" share="share" status="status" title="Funnel by stage"}
55
+ :::
56
+
57
+ ### Onboarding findings
58
+
59
+ Activation needs attention against the prepared target, and conversion is marked at risk. Expand the chart and funnel data disclosures to inspect the original values and denominators.
60
+
61
+ ---
62
+
63
+ ## Product catalogue
64
+
65
+ A fictional store's product performance over **eight weeks ending 1 November 2026**. All data, comparisons and product illustrations are synthetic and prepared for this example.
66
+
67
+ :::grid{columns="3"}
68
+ ::metric{label="Orders" value="1477" comparison="18.2% vs previous eight weeks" direction="up" sentiment="positive"}
69
+ ::metric{label="Revenue" value="63740" format="currency:USD" comparison="20% vs previous eight weeks" direction="up" sentiment="positive"}
70
+ ::metric{label="Products" value="4" comparison="1 more than previous period" direction="up" sentiment="positive"}
71
+ :::
72
+
73
+ The fictional comparison period contains **1,250 orders**, **US$53,120 revenue** and **three products**. Changes above are prepared and rounded by the example author.
74
+
75
+ ### Product detail
76
+
77
+ Weekly order lines share the same vertical scale, so their heights are comparable. The lamp has one missing week, shown as a gap; its prepared total covers recorded weeks only. Expand **View values** to inspect the original samples.
78
+
79
+ :::table{data="./catalog/showcase-products.json" title="Performance by product"}
80
+ ::column{field="image" label="Preview" kind="image" alt="image_alt"}
81
+ ::column{field="product" label="Product"}
82
+ ::column{field="weekly_orders" label="Weekly orders" kind="sparkline" sortBy="last_week"}
83
+ ::column{field="orders" label="Orders" format="number"}
84
+ ::column{field="revenue" label="Revenue" format="currency:USD"}
85
+ ::column{field="change" label="Δ period" format="percent" sign="always" semantics="higher-is-better"}
86
+ :::
87
+
88
+ ### Reading this table
89
+
90
+ - **Linen tote leads relative growth.** Comparisons are prepared by the author, not calculated from the sparkline.
91
+ - **Notebooks lead order volume.** They also have the highest final-week value in this fictional set.
92
+ - **The natural tote reuses its image.** The portable report embeds each unique illustration once.
93
+
94
+ :::callout{title="About these examples"}
95
+ All datasets, comparisons, statuses, findings and product illustrations are fictional. Store totals cover 1–7 November 2026; the onboarding and catalogue sections identify their separate periods and populations. Comparisons are prepared by the author, not inferred by the renderer. No live filters, data connections or subtotal calculations are implied.
96
+ :::
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "plotleaf",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Beautiful, interactive reports from Markdown and JSON. Built for agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/LoueeD/plotleaf.git"
10
+ },
11
+ "homepage": "https://github.com/LoueeD/plotleaf#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/LoueeD/plotleaf/issues"
14
+ },
7
15
  "bin": {
8
16
  "plotleaf": "./dist/cli.js"
9
17
  },
@@ -18,10 +26,17 @@
18
26
  "dist/assets/styles.css",
19
27
  "dist/assets/notices.txt",
20
28
  "schema/components.json",
29
+ "examples/report.md",
21
30
  "examples/storefront/*.md",
22
31
  "examples/storefront/*.json",
23
32
  "examples/adoption/*.md",
24
33
  "examples/adoption/*.json",
34
+ "examples/onboarding/*.md",
35
+ "examples/onboarding/*.json",
36
+ "examples/catalog/*.md",
37
+ "examples/catalog/*.json",
38
+ "examples/catalog/assets/*.png",
39
+ "examples/catalog/assets/*.jpg",
25
40
  "skills/plotleaf/SKILL.md",
26
41
  "README.md",
27
42
  "LICENSE",
@@ -36,10 +51,12 @@
36
51
  "test:browser": "node node_modules/@playwright/test/cli.js test",
37
52
  "test:consumer": "node tests/consumer/smoke.mjs",
38
53
  "check": "bun run typecheck && bun run build && bun run test && bun run test:consumer",
39
- "audit:package": "node scripts/audit-package.mjs"
54
+ "audit:package": "node scripts/audit-package.mjs",
55
+ "dev": "bun run build && node dist/cli.js dev examples/report.md"
40
56
  },
41
57
  "dependencies": {
42
58
  "chokidar": "6.0.0",
59
+ "image-size": "2.1.0",
43
60
  "open": "11.0.4",
44
61
  "rehype-sanitize": "6.0.0",
45
62
  "rehype-stringify": "10.0.1",