ggaction 0.0.21 → 0.0.23

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.
Files changed (265) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +83 -90
  3. package/knowledge/action-card.schema.json +1 -1
  4. package/knowledge/action-cards.json +1 -1
  5. package/knowledge/intent-taxonomy.json +1 -1
  6. package/knowledge/mcp-resources.json +1 -1
  7. package/package.json +11 -4
  8. package/src/BasicChartProgram.js +1 -1
  9. package/src/accessibility.js +1 -0
  10. package/src/actions/boxPlots/components.js +1 -96
  11. package/src/actions/boxPlots/create.js +6 -1
  12. package/src/actions/boxPlots/edit.js +8 -0
  13. package/src/actions/boxPlots/materialize.js +3 -0
  14. package/src/actions/boxPlots/options.js +1 -1
  15. package/src/actions/canvas/actions.js +2 -1
  16. package/src/actions/canvas/index.js +3 -0
  17. package/src/actions/canvas/plotBorder.js +2 -1
  18. package/src/actions/canvas/plotOrder.js +14 -0
  19. package/src/actions/charts/area.js +1 -1
  20. package/src/actions/charts/bar.js +4 -4
  21. package/src/actions/charts/density.js +1 -1
  22. package/src/actions/charts/ecdf.js +1 -1
  23. package/src/actions/charts/endpoints.js +54 -5
  24. package/src/actions/charts/heatmap.js +1 -1
  25. package/src/actions/charts/histogram.js +1 -1
  26. package/src/actions/charts/horizon.js +1 -1
  27. package/src/actions/charts/index.js +2 -1
  28. package/src/actions/charts/interval-regression.js +3 -3
  29. package/src/actions/charts/line.js +1 -1
  30. package/src/actions/charts/radar.js +63 -3
  31. package/src/actions/charts/raincloud.js +37 -6
  32. package/src/actions/charts/rug-strip.js +2 -2
  33. package/src/actions/charts/scatter.js +3 -3
  34. package/src/actions/charts/text.js +1 -1
  35. package/src/actions/composition/actions.js +10 -3
  36. package/src/actions/coordinates/actions.js +2 -0
  37. package/src/actions/data/basic.js +6 -0
  38. package/src/actions/data/derived.js +6 -2
  39. package/src/actions/data/edit.js +22 -36
  40. package/src/actions/data/filter.js +1 -376
  41. package/src/actions/data/flatten.js +19 -0
  42. package/src/actions/data/index.js +6 -0
  43. package/src/actions/data/lookup.js +50 -0
  44. package/src/actions/data/raincloudFilter.js +56 -0
  45. package/src/actions/data/shared.js +10 -0
  46. package/src/actions/data/timeUnit.js +1 -1
  47. package/src/actions/distributions/revision.js +3 -1
  48. package/src/actions/encodings/angle.js +2 -1
  49. package/src/actions/encodings/appearance.js +38 -13
  50. package/src/actions/encodings/channels.js +14 -3
  51. package/src/actions/encodings/color/continuous.js +26 -10
  52. package/src/actions/encodings/color/index.js +50 -20
  53. package/src/actions/encodings/color/policy.js +57 -4
  54. package/src/actions/encodings/parallel.js +4 -0
  55. package/src/actions/encodings/position/policies/bar.js +10 -6
  56. package/src/actions/encodings/position/policies/line.js +1 -152
  57. package/src/actions/encodings/position/resolve.js +4 -1
  58. package/src/actions/encodings/ranged.js +46 -0
  59. package/src/actions/encodings/remove.js +1 -1
  60. package/src/actions/encodings/ruleAppearance.js +7 -6
  61. package/src/actions/encodings/shared.js +14 -2
  62. package/src/actions/encodings/stroke.js +20 -14
  63. package/src/actions/encodings/strokeDash.js +9 -11
  64. package/src/actions/encodings/text.js +30 -2
  65. package/src/actions/errorBars/edit.js +24 -4
  66. package/src/actions/facets/actions.js +1 -793
  67. package/src/actions/facets/derive.js +34 -5
  68. package/src/actions/facets/replay.js +1 -38
  69. package/src/actions/gradientPlots/components.js +21 -9
  70. package/src/actions/gradientPlots/create.js +4 -2
  71. package/src/actions/gradientPlots/edit.js +18 -1
  72. package/src/actions/gradientPlots/materialize.js +35 -36
  73. package/src/actions/gradientPlots/options.js +1 -1
  74. package/src/actions/gradientPlots/paint.js +13 -7
  75. package/src/actions/guides/applicability.js +2 -0
  76. package/src/actions/guides/axes/axes.js +39 -0
  77. package/src/actions/guides/axes/axis.js +9 -5
  78. package/src/actions/guides/axes/edit.js +11 -8
  79. package/src/actions/guides/axes/labels.js +24 -8
  80. package/src/actions/guides/axes/parallel/policy.js +3 -5
  81. package/src/actions/guides/axes/parallel/resolve.js +4 -3
  82. package/src/actions/guides/axes/policy.js +22 -0
  83. package/src/actions/guides/axes/tickGroups.js +4 -2
  84. package/src/actions/guides/axes/ticks.js +22 -4
  85. package/src/actions/guides/axes/titles.js +19 -6
  86. package/src/actions/guides/facadeAxes.js +3 -0
  87. package/src/actions/guides/grids/grid.js +3 -1
  88. package/src/actions/guides/grids/resolve.js +7 -11
  89. package/src/actions/guides/guides.js +21 -1
  90. package/src/actions/guides/legends/categorical/actions.js +1 -515
  91. package/src/actions/guides/legends/categorical/components.js +1 -4
  92. package/src/actions/guides/legends/categorical/layout.js +5 -2
  93. package/src/actions/guides/legends/categorical/options.js +4 -0
  94. package/src/actions/guides/legends/categorical/resolve.js +8 -3
  95. package/src/actions/guides/legends/categorical/symbols.js +3 -3
  96. package/src/actions/guides/legends/colorSize.js +2 -0
  97. package/src/actions/guides/legends/continuous/common.js +1 -1
  98. package/src/actions/guides/legends/continuous/gradient.js +1 -360
  99. package/src/actions/guides/legends/continuous/interval.js +1 -1
  100. package/src/actions/guides/legends/continuous/opacity.js +15 -1
  101. package/src/actions/guides/legends/edit.js +1 -1
  102. package/src/actions/guides/legends/focused.js +1 -1
  103. package/src/actions/guides/legends/lane.js +1 -1
  104. package/src/actions/guides/legends/sampling.js +1 -140
  105. package/src/actions/guides/legends/strokeWidth.js +3 -2
  106. package/src/actions/guides/legends/transition.js +19 -2
  107. package/src/actions/guides/polar/axes/facade.js +5 -4
  108. package/src/actions/guides/polar/axes/labels.js +5 -4
  109. package/src/actions/guides/polar/axes/titles.js +5 -4
  110. package/src/actions/guides/polar/resolve.js +2 -1
  111. package/src/actions/guides/tickValues.js +7 -7
  112. package/src/actions/marks/arc/actions.js +5 -7
  113. package/src/actions/marks/area/actions.js +9 -3
  114. package/src/actions/marks/bar/create.js +4 -2
  115. package/src/actions/marks/bar/edit.js +9 -6
  116. package/src/actions/marks/bar/materialize.js +5 -3
  117. package/src/actions/marks/dependentReferences.js +87 -0
  118. package/src/actions/marks/index.js +2 -0
  119. package/src/actions/marks/lifecycle.js +2 -1
  120. package/src/actions/marks/line/actions.js +24 -6
  121. package/src/actions/marks/line/materialize.js +7 -3
  122. package/src/actions/marks/point/create.js +5 -4
  123. package/src/actions/marks/point/edit.js +6 -3
  124. package/src/actions/marks/point/jitter.js +6 -6
  125. package/src/actions/marks/point/materialize.js +36 -39
  126. package/src/actions/marks/rect/actions.js +16 -4
  127. package/src/actions/marks/references.js +183 -35
  128. package/src/actions/marks/rule/actions.js +20 -9
  129. package/src/actions/marks/shared.js +2 -1
  130. package/src/actions/marks/text/actions.js +10 -3
  131. package/src/actions/marks/tick/actions.js +11 -2
  132. package/src/actions/primitives/editGraphics.js +28 -3
  133. package/src/actions/primitives/index.js +9 -0
  134. package/src/actions/primitives/semanticAction.js +13 -7
  135. package/src/actions/primitives/semanticValidation/layer.js +20 -0
  136. package/src/actions/primitives/semanticValidation/scale.js +8 -1
  137. package/src/actions/regression/create.js +6 -1
  138. package/src/actions/regression/edit.js +10 -1
  139. package/src/actions/scales/channels.js +1 -1
  140. package/src/actions/scales/consumers/common.js +19 -1
  141. package/src/actions/scales/consumers/families.js +2 -2
  142. package/src/actions/scales/consumers/seriesLayout.js +4 -3
  143. package/src/actions/scales/edit.js +11 -0
  144. package/src/actions/scales/editPolicy.js +5 -3
  145. package/src/actions/scales/preview.js +2 -1
  146. package/src/actions/scales/quantitativeColor.js +2 -4
  147. package/src/actions/selection/actions.js +10 -1
  148. package/src/actions/theme/reconcile.js +37 -9
  149. package/src/core/compositionState.js +26 -7
  150. package/src/core/datasetReferences.js +17 -0
  151. package/src/core/facetAxisPolicy.js +30 -0
  152. package/src/core/immutable.js +1 -0
  153. package/src/core/resourceReferences.js +5 -3
  154. package/src/core/validation.js +4 -0
  155. package/src/core/vocabulary.js +24 -2
  156. package/src/grammar/aggregate.js +1 -0
  157. package/src/grammar/arcs.js +1 -1
  158. package/src/grammar/areaSeries.js +1 -1
  159. package/src/grammar/axisTextPlacement.js +1 -1
  160. package/src/grammar/bars/policy.js +2 -2
  161. package/src/grammar/curveCommands.js +35 -2
  162. package/src/grammar/datasetDependencies.js +97 -0
  163. package/src/grammar/datasetSchema.js +32 -2
  164. package/src/grammar/facetHeaders.js +1 -0
  165. package/src/grammar/facets/dependencies.js +6 -2
  166. package/src/grammar/facets/guides.js +7 -5
  167. package/src/grammar/facets/legendIntent.js +6 -2
  168. package/src/grammar/facets/scales.js +27 -7
  169. package/src/grammar/flatten.js +85 -0
  170. package/src/grammar/histogram.js +13 -1
  171. package/src/grammar/horizon.js +1 -494
  172. package/src/grammar/jitter.js +2 -2
  173. package/src/grammar/legendSpacing.js +45 -0
  174. package/src/grammar/lineMissing.js +90 -0
  175. package/src/grammar/lineSeries.js +1 -376
  176. package/src/grammar/lookup.js +97 -0
  177. package/src/grammar/markFilter.js +4 -2
  178. package/src/grammar/markLabels.js +8 -3
  179. package/src/grammar/numeric.js +1 -1
  180. package/src/grammar/pathCommands.js +1 -1
  181. package/src/grammar/pathSeries.js +1 -109
  182. package/src/grammar/pointPolygon.js +81 -0
  183. package/src/grammar/pointShapes.js +15 -15
  184. package/src/grammar/rects.js +1 -1
  185. package/src/grammar/regression/derive.js +1 -195
  186. package/src/grammar/regression/parameters.js +7 -0
  187. package/src/grammar/scales/appearance.js +1 -1
  188. package/src/grammar/scales/color.js +1 -1
  189. package/src/grammar/scales/colorConsumers.js +1 -63
  190. package/src/grammar/scales/continuous.js +58 -1
  191. package/src/grammar/scales/definition.js +1 -1
  192. package/src/grammar/scales/ordinal.js +5 -2
  193. package/src/grammar/scales/policies.js +3 -3
  194. package/src/grammar/schemas/graphicBounds.js +40 -12
  195. package/src/grammar/schemas/graphicClip.js +23 -0
  196. package/src/grammar/schemas/graphicTree.js +16 -0
  197. package/src/grammar/statisticalReference.js +22 -0
  198. package/src/grammar/text.js +65 -1
  199. package/src/grammar/ticks.js +92 -1
  200. package/src/grammar/timeUnit.js +9 -3
  201. package/src/grammar/transformTopology.js +3 -1
  202. package/src/grammar/transforms.js +24 -0
  203. package/src/inspection.js +1 -495
  204. package/src/inspectionDescriptors.js +1 -1
  205. package/src/layout/canvas.js +1 -1
  206. package/src/layout/facetContentFlow.js +101 -0
  207. package/src/layout/facetHeaderTitles.js +1 -0
  208. package/src/layout/facetTopLane.js +29 -0
  209. package/src/layout/facets.js +1 -1
  210. package/src/layout/guideCollisions.js +9 -3
  211. package/src/layout/legendGroup.js +1 -1
  212. package/src/layout/legendItems.js +26 -10
  213. package/src/layout/legendSpacing.js +66 -0
  214. package/src/layout/plotDrawOrder.js +17 -0
  215. package/src/materialization/bars/histogram.js +8 -2
  216. package/src/materialization/bars/resolve.js +1 -1
  217. package/src/materialization/composition.js +1 -0
  218. package/src/materialization/compositionSnapshot.js +22 -2
  219. package/src/materialization/dataProvenance.js +1 -1
  220. package/src/materialization/facetContentBounds.js +96 -0
  221. package/src/materialization/facetGuides/layout.js +1 -1
  222. package/src/materialization/facetGuides/placement.js +39 -11
  223. package/src/materialization/facetGuides/preparation.js +43 -24
  224. package/src/materialization/facetHeaders.js +1 -1
  225. package/src/materialization/facetTopLane.js +25 -0
  226. package/src/materialization/facets.js +1 -1
  227. package/src/materialization/graphicHierarchy.js +30 -1
  228. package/src/materialization/graphicTranslation.js +2 -0
  229. package/src/materialization/guides/layout.js +1 -1
  230. package/src/materialization/guides/resources.js +1 -1
  231. package/src/materialization/legends.js +1 -1
  232. package/src/materialization/markClip.js +26 -0
  233. package/src/materialization/marks/capabilities.js +3 -2
  234. package/src/materialization/marks/grouping.js +7 -5
  235. package/src/materialization/marks/index.js +4 -2
  236. package/src/materialization/marks/policies.js +4 -0
  237. package/src/materialization/plotDrawOrder.js +44 -0
  238. package/src/materialization/rect.js +11 -3
  239. package/src/materialization/scaleGuideDependencies.js +13 -5
  240. package/src/materialization/selection/items/common.js +1 -1
  241. package/src/materialization/selection/items/path.js +1 -0
  242. package/src/materialization/selection/policies/index.js +2 -1
  243. package/src/materialization/text.js +10 -5
  244. package/src/mcp/cli.js +0 -0
  245. package/src/persistence/validation.js +114 -18
  246. package/src/persistence.js +4 -2
  247. package/src/renderers/canvas/index.js +16 -0
  248. package/src/renderers/canvas/isolated.js +11 -1
  249. package/src/renderers/canvas/native.js +7 -0
  250. package/src/renderers/canvas/scene.js +66 -0
  251. package/src/renderers/canvas/text.js +3 -2
  252. package/src/renderers/svg.js +1 -617
  253. package/src/renderers/svgSerialization.js +643 -0
  254. package/src/renderers/transitionScene.js +67 -0
  255. package/src/scene.js +89 -0
  256. package/src/selectors/axes.js +1 -1
  257. package/src/selectors/datasets.js +1 -0
  258. package/src/selectors/grids.js +9 -0
  259. package/src/selectors/markClip.js +28 -0
  260. package/src/selectors/raincloud.js +7 -0
  261. package/src/version.js +1 -1
  262. package/types/basic.d.ts +7 -0
  263. package/types/index.d.ts +8 -0
  264. package/types/program.d.ts +286 -70
  265. package/types/scene.d.ts +35 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,96 @@ All notable changes to `ggaction` are recorded in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## [0.0.23] - 2026-10-23
8
+
9
+ - Add independent full-content facet packing, view-aware headers and per-channel Cartesian axis policies with unclipped shared footer axes.
10
+ - Avoid false title/legend collisions from floating-point roundoff at touching edges.
11
+
12
+ - Add opt-in `placement: "plot-last"` for regression fits and bands, preserving source attachment by default and retaining placement through edits and restoration.
13
+
14
+ - Add explicit `monotone-steffen` interpolation for lines, areas and interval boundaries while preserving existing monotone output.
15
+
16
+ - Preserve null or absent calendar inputs as null buckets with opt-in `missing: "null"`, including immutable edits and saved programs.
17
+ - Preserve locally moved legend title alignment and reserve four-edge facet parent title lanes.
18
+ - Strengthen test oracles, execution receipts, consumer qualification, source coverage, browser evidence and bounded CI runners.
19
+
20
+ - Correct documentation examples, recovery ordering, conditional defaults, data-refresh guidance, and action-card prerequisites; execute additional examples and pin contextual exceptions.
21
+ - Publish the complete declaration dependency graph, all runtime entry references, and selective LLM page/action/type artifacts with shared identity and hashes.
22
+ - Improve task search, navigation affordances, source editing links, and first-run documentation; replace the README animation with the paper's Nightingale rose sequence.
23
+
24
+ ## [0.0.22] - 2026-10-23
25
+
26
+ - Add opt-in plot clipping to supported Cartesian mark layers, with native/SVG/PNG/PDF parity and immutable owner replay.
27
+ - Add validated simple polygon point shapes, retaining area/radius normalization in marks, shape scales, legends and persistence.
28
+ - Support explicit fold-produced facet partition keys and rotated facet headers without changing original input rows.
29
+ - Allow explicit Cartesian axis-title overlap with labels; preserve strict collision checks when omitted.
30
+ - Preserve exact continuous-legend sampling endpoints, avoiding rounded-domain extrapolation.
31
+ - Keep opacity/stroke-width `nice` declarations boolean-only and restrict categorical dash fallback declarations to Cartesian consumers, matching the existing runtime role checks.
32
+
33
+ - Add native Canvas transition scenes and drawing through `ggaction/scene`, preserving explicit owner/nested clips, fractional viewport coverage, immutable scene identity and the existing SVG scene contract.
34
+
35
+ - Update locked Hono to 4.13.13, Vite to 6.4.5 and ip-address to 10.7.4; preserve native platform metadata and verify the existing browser/MCP consumers.
36
+
37
+ - Add opt-in facet header `anchor: "content"` for plot spacing, following concrete mark overflow while preserving along-edge plot alignment, clipping, role overrides and editable replay.
38
+
39
+ - Add explicit axis `format: "ticks"` for per-axis numeric tick precision, including independent facets, while preserving existing automatic formatting.
40
+
41
+ - Add opt-in `missing: "break"` for direct Cartesian quantitative/temporal lines, preserving raw observations, independent axis domains and curve restarts across gaps, including filtering, immutable edits and saved programs. Strict defaults remain unchanged.
42
+
43
+ - Add opt-in `nice: { count }` rounding for automatic linear position domains, preserving existing boolean behavior, independent facet ranges, immutable edits and saved programs.
44
+ - Add opt-in nearest-step linear Cartesian ticks with matching labels, inferred grids, named owners, independent facets and editable saved programs.
45
+ - Fix editable version-1 lookup schema migration while retaining strict references, typed keys, raw rows and final schema validation.
46
+
47
+ - Add independent role-scoped facet field titles through existing header creation and editing, with rotated placement, immutable partial edits, removal and collision-checked replay.
48
+
49
+ - Add `createLookupData` / `editLookupData` for typed lookup between named datasets, preserving primary rows and both raw inputs.
50
+ - Support immutable lookup edits, revisions from either input, typed lineage, persistence,
51
+ facet/grid composition and encoding repeats over direct lookup results.
52
+
53
+ - Support finite zero and negative Cubehelix lightness gamma, including explicit zero-position RGB boundaries, shared color/stroke legends and immutable replay.
54
+
55
+ - Add `encodeDx` and `encodeDy` for direct numeric independent Text offsets, including atomic channel assignment, immutable data replay and saved programs. Basic retains its Text-family exclusion.
56
+
57
+ - Support quantitative/temporal Tick color mappings and their filled gradient, interval and sampled-color legends, preserving geometry, raw data, existing stroke-only behavior and explicit channel switching.
58
+
59
+ - Support exact continuous color/stroke gradient tick values through existing legend creation and editing, with mapped positions, explicit reset, retained representation sampling and atomic domain validation.
60
+
61
+ - Raise the bounded per-path capacity to 30,000 commands, preserving interpolation/area expansion checks, immutable native edits and independent allocation limits.
62
+
63
+ - Add `createFlattenData` / `editFlattenData` for aligned parallel-array data expansion with null padding, immutable raw ancestors, typed lineage, Full derived editing/replay and Basic creation.
64
+
65
+ - Inherit fixed line colors in categorical dash legends while preserving mapped colors, explicit sample overrides and independent sample opacity.
66
+
67
+ - Place inferred external side legends beyond occupied same-edge axes, preserving family gaps, plot-top alignment, explicit offsets and immutable guide replay.
68
+
69
+ - Fix categorical symbol recipe edits from rounded bar samples to plain swatches, including restoration to automatic samples and facet/data replay.
70
+
71
+ - Support explicit ordinal stroke-dash fields in existing line/rule, facade and bulk encodings, preserving categorical domain order and immutable rematerialization.
72
+
73
+ - Add explicit Cartesian-axis and plot-border underlays, with strict existing-container child-order editing.
74
+ - Add opt-in facet `topLane: "shared"` with plot spacing, fixed child sizes, collision validation and editable persistence. Render blank mapped text consistently.
75
+ - Add opt-in content-aware legend `rowPadding` and independent `titlePadding`, with focused editing, explicit reset and retained replay intent.
76
+ - Fix HCL and HCL-long hue handling at exact neutral RGB endpoints for D50 and D65.
77
+ - Support finite numeric datum bounds in Rect/Rule range encoders, with final-pair validation and unchanged source data.
78
+ - Align continuous color and stroke TypeScript palette descriptors with existing runtime count, extent and nested range forms.
79
+ - Reuse validated immutable composition state and namespaced child graphics during layout edits, preserving validation of changed state and caller-owned inputs.
80
+ - Report measured minimum facet header spacing through existing structured error diagnostics so clients can retry without repeated gap searches.
81
+ - Add `editRadarPlot` to atomically edit the selected dimensions and order of a wide Radar chart while preserving its closed paths, groups, appearance and guides.
82
+ - Accept color in Box and Gradient plot creation, support continuous Arc color, and preserve compound-chart color and filtering through edits and facets.
83
+ - Compute distribution and endpoint statistical references from their source observations; retain and recompute independently authored reference layers through owner edits.
84
+ - Resolve compatible facet color/stroke policies and combined legend domains consistently. Automatic `createGuides` accepts a chart with no applicable guides.
85
+ - Reserve Polar and Parallel axis text in facet header and shared-legend placement; inferred outside legends also clear Polar labels after typography changes.
86
+ - Apply Histogram missing-value policy consistently to marks, scales, guides, labels and selections, and expose actual bin intervals as category labels.
87
+
88
+ - Add `createStatisticalReference` for a native mean/median/extreme/quantile line or exact percentile interval, with dark solid line defaults and existing statistical reference replay and ownership.
89
+
90
+ - Preserve aggregate bar positions and widths when categorical color repeats the category-axis field and no group or layout was already specified.
91
+
92
+ - Infer left/right legend clearance from occupied axis guides and reflow it after axis edits or removal; exact-inner Canvas sizing also fits inferred edge legend groups.
93
+ - Detect chart title position and typography changes in `comparePrograms` when the title text is unchanged.
94
+ - Add `editAxes` to edit selected Cartesian, Polar, or Parallel axes through one atomic public action, with existing channel-editor options and explicit named-axis selection.
95
+ - Forward native `missing: "error" | "skip"` through `createScatterPlot` and `createBarPlot` without changing source rows.
96
+
7
97
  ## [0.0.21] - 2026-10-18
8
98
 
9
99
  - Fix precision loss and collapsed bounds in bootstrap interval data and charts.
package/README.md CHANGED
@@ -9,77 +9,10 @@ Most visualization grammars describe a finished chart. **ggaction** represents c
9
9
  Build, inspect, select, and revise charts one meaningful action at a time.
10
10
 
11
11
  <p align="left">
12
- <img src="./docs/assets/images/readme-authoring-sequence.gif" width="960" height="540" loading="eager" alt="A ggaction program progressively creates a scatterplot, adds grouped regression fits and confidence bands, highlights the Japan group across chart layers, and finishes with an R-squared annotation.">
12
+ <img src="./docs/assets/images/readme-authoring-sequence.gif" width="960" height="540" loading="eager" alt="The paper Nightingale rose plot is built progressively, then its radial mapping, cause colors, sector spacing, title, and palette are revised.">
13
13
  </p>
14
14
 
15
- Every frame is rendered from an immutable `ChartProgram`. The final R² label is a traceable action built from public extension primitives.
16
-
17
- ## A grammar of graphical action
18
-
19
- An action expresses a design operation on a chart element. In
20
- `editLineMark({ strokeWidth: 4 })`, `edit` is the operation, `LineMark` names
21
- the target concept, and the option supplies the design choice.
22
-
23
- The grammar has two units: **graphical actions** and **chart programs**.
24
- A program composes action calls in authoring order and retains their resulting
25
- immutable state. Authors read a linear sequence of decisions; an action may
26
- delegate to smaller actions recorded in its nested execution trace.
27
-
28
- The following fragment assumes `cars` is an array of row objects:
29
-
30
- ```javascript
31
- import { chart } from "ggaction";
32
-
33
- const program = chart()
34
- .createCanvas({
35
- width: 760,
36
- height: 480,
37
- margin: { top: 40, right: 190, bottom: 70, left: 80 }
38
- })
39
- .createData({ values: cars })
40
- .createScatterPlot({
41
- id: "points",
42
- x: "Displacement",
43
- y: "Acceleration",
44
- color: "Origin",
45
- guides: false
46
- })
47
- .createRegression()
48
- .createGuides();
49
- ```
50
-
51
- Here `createRegression()` infers groups from the point layer, uses a linear
52
- model, and includes a 95% mean-response interval band. The right margin reserves
53
- space for the resulting legend. The [regression recipe](https://ggaction.github.io/ggaction/recipes/regression-scatterplot/)
54
- provides data and rendering setup; [regression options](https://ggaction.github.io/ggaction/api/regression/)
55
- control grouping, model, interval, and whether a band is drawn.
56
-
57
- ## Why actions?
58
-
59
- - **Progressive** — build and revise a chart one meaningful operation at a time.
60
- - **Traceable** — retain high-level actions and the wrapped actions they invoke.
61
- - **Materialized** — actions create concrete backend-neutral graphics; rendering does not perform hidden semantic compilation.
62
-
63
- ## MCP server for LLM
64
-
65
- ggaction includes a local, read-only MCP server that gives coding assistants
66
- current action names, syntax-valid call templates, explicit placeholders, and
67
- task-specific authoring steps
68
- without loading the complete documentation.
69
-
70
- <p align="left">
71
- <img src="./docs/assets/images/readme-mcp-benefits.svg" width="960" loading="lazy" alt="Across 576 fixed task runs, MCP with bounded fallback improved strict success and reduced tokens and model calls compared with public-documentation browsing for Terra, Luna, and Nano.">
72
- </p>
73
-
74
- Across a fixed 576-run evaluation, MCP-first authoring with bounded fallback
75
- improved strict task success while using fewer tokens and model calls for all
76
- three model sizes. The server runs locally over stdio and does not execute chart
77
- code, access arbitrary files, make network requests, require an account, or
78
- collect telemetry.
79
-
80
- [Set up the local MCP server](https://ggaction.github.io/ggaction/mcp/) ·
81
- [Inspect the benchmark record](./benchmarks/llm-authoring-v1/) ·
82
- [Read the complete evaluation report](./agent_docs/impl/roadmap5.4/phase6/ATTEMPT11.md)
15
+ Every frame is rendered from an immutable `ChartProgram`. This is the paper’s Nightingale rose-plot authoring sequence: create the chart, encode mortality and cause, adjust sector spacing, add the title, and change the palette.
83
16
 
84
17
  ## Quick start
85
18
 
@@ -170,28 +103,86 @@ automatic undo stack; the application chooses which to retain or render.
170
103
 
171
104
  Use `createLinePlot`, `createBarPlot`, `createHistogram`, and `createHeatmap` for
172
105
  the other basic Cartesian charts. The `ggaction/basic` entry keeps this common
173
- creation path at or below the current 205,000-byte gzip regression ceiling while
106
+ creation path at or below the current 231,000-byte gzip regression ceiling while
174
107
  each facade still records its mark, encoding, and guide actions as trace
175
108
  children. Import from
176
109
  `ggaction` when you need editing, selection, composition, alternative
177
110
  coordinates, or statistical layers. See the
178
111
  [Basic Charts API](https://ggaction.github.io/ggaction/api/basic-charts/).
179
112
 
180
- Use `createParallelCoordinates({ dimensions })` to connect each source row
181
- across ordered, dimension-local scales and axes. See the
182
- [Parallel Coordinates API](https://ggaction.github.io/ggaction/api/parallel-coordinates/)
183
- or the [runnable Cars example](./examples/cars-parallel-coordinates/).
184
-
185
- For an advanced layered example, follow the [regression recipe](https://ggaction.github.io/ggaction/recipes/regression-scatterplot/)
186
- or open the [runnable regression example](./examples/cars-regression-scatterplot/).
187
- To compare category distributions with density-filled strips, read the
188
- [gradient-plot guide](https://ggaction.github.io/ggaction/api/gradient-plots/)
189
- or open the [runnable example](./examples/cars-gradient-plot/).
190
- For symmetric or split density shapes centered on categories, use the
191
- [violin-plot API](https://ggaction.github.io/ggaction/api/violin-plots/) or the
192
- [runnable Cars example](./examples/cars-acceleration-violins/).
193
- For compact signed time-series bands, use `encodeHorizon` on an area mark and
194
- open the [runnable Gapminder example](./examples/gapminder-horizon/).
113
+ Explore [parallel coordinates](https://ggaction.github.io/ggaction/api/parallel-coordinates/),
114
+ [gradient plots](https://ggaction.github.io/ggaction/api/gradient-plots/),
115
+ [violin plots](https://ggaction.github.io/ggaction/api/violin-plots/), and
116
+ [Horizon charts](./examples/gapminder-horizon/) in the [runnable examples](./examples/README.md).
117
+
118
+ ## A grammar of graphical action
119
+
120
+ An action expresses a design operation on a chart element. In
121
+ `editLineMark({ strokeWidth: 4 })`, `edit` is the operation, `LineMark` names
122
+ the target concept, and the option supplies the design choice.
123
+
124
+ The grammar has two units: **graphical actions** and **chart programs**.
125
+ A program composes action calls in authoring order and retains their resulting
126
+ immutable state. Authors read a linear sequence of decisions; an action may
127
+ delegate to smaller actions recorded in its nested execution trace.
128
+
129
+ The following fragment assumes `cars` is an array of row objects:
130
+
131
+ ```javascript
132
+ import { chart } from "ggaction";
133
+
134
+ const program = chart()
135
+ .createCanvas({
136
+ width: 760,
137
+ height: 480,
138
+ margin: { top: 40, right: 190, bottom: 70, left: 80 }
139
+ })
140
+ .createData({ values: cars })
141
+ .createScatterPlot({
142
+ id: "points",
143
+ x: "Displacement",
144
+ y: "Acceleration",
145
+ color: "Origin",
146
+ guides: false
147
+ })
148
+ .createRegression()
149
+ .createGuides();
150
+ ```
151
+
152
+ Here `createRegression()` infers groups from the point layer, uses a linear
153
+ model, and includes a 95% mean-response interval band. The right margin reserves
154
+ space for the resulting legend. The [regression recipe](https://ggaction.github.io/ggaction/recipes/regression-scatterplot/)
155
+ provides data and rendering setup ([source](./examples/cars-regression-scatterplot/)); [regression options](https://ggaction.github.io/ggaction/api/regression/)
156
+ control grouping, model, interval, and whether a band is drawn.
157
+
158
+ ## Why actions?
159
+
160
+ - **Progressive** — build and revise a chart one meaningful operation at a time.
161
+ - **Traceable** — retain high-level actions and the wrapped actions they invoke.
162
+ - **Materialized** — actions create concrete backend-neutral graphics; rendering does not perform hidden semantic compilation.
163
+
164
+ ## MCP server for LLM
165
+
166
+ ggaction includes a local, read-only MCP server that gives coding assistants
167
+ current action names, syntax-valid call templates, explicit placeholders, and
168
+ task-specific authoring steps
169
+ without loading the complete documentation.
170
+
171
+ <p align="left">
172
+ <img src="./docs/assets/images/readme-mcp-benefits.svg" width="960" loading="lazy" alt="Across 576 fixed task runs, MCP with bounded fallback improved strict success and reduced tokens and model calls compared with public-documentation browsing for Terra, Luna, and Nano.">
173
+ </p>
174
+
175
+ In the fixed 576-run evaluation completed on 2026-08-10 (24 tasks × 2 repetitions ×
176
+ `gpt-5.6-terra`, `gpt-5.6-luna`, and `gpt-5.4-nano` × 4 conditions;
177
+ product candidate `4e211ba418cd437d7c66c4fb986fcc714cf579ea`), MCP-first authoring with bounded fallback
178
+ improved strict task success while using fewer tokens and model calls for all
179
+ three model sizes. The server runs locally over stdio and does not execute chart
180
+ code, access arbitrary files, make network requests, require an account, or
181
+ collect telemetry.
182
+
183
+ [Set up the local MCP server](https://ggaction.github.io/ggaction/mcp/) ·
184
+ [Inspect the benchmark record](./benchmarks/llm-authoring-v1/) ·
185
+ [Read the complete evaluation report](./agent_docs/impl/roadmap5.4/phase6/ATTEMPT11.md)
195
186
 
196
187
  ## What it supports
197
188
 
@@ -220,15 +211,13 @@ The package is ESM-only and requires Node.js 20 or later.
220
211
  | `ggaction/inspection` | Inspect dataset schemas, action applicability, program changes, and concrete results without mutation |
221
212
  | `ggaction/diagnostics` | Read structured error codes and resource details in Browser or Node |
222
213
  | `ggaction/svg` | Serialize a completed program to browser-safe SVG |
214
+ | `ggaction/scene` | Read-only structured transition scenes and native Canvas scene drawing |
223
215
  | `ggaction-mcp` | Run the local read-only MCP authoring server over stdio in Node.js |
224
216
 
225
217
  All module entries include TypeScript declarations. The default, basic,
226
218
  extension, diagnostics, accessibility, and SVG entries are browser-safe; the PNG and PDF adapters are
227
219
  Node-only.
228
220
 
229
- The installed package also includes the Node-only `ggaction-mcp` executable. It
230
- provides one local, read-only chart-authoring search tool and stays outside every
231
- browser entry. See the [local MCP guide](https://ggaction.github.io/ggaction/mcp/).
232
221
 
233
222
  ## Documentation
234
223
 
@@ -248,7 +237,7 @@ the extra discussion required before public API or architecture changes.
248
237
 
249
238
  ## Status and development
250
239
 
251
- > **Status:** `0.0.21` is the current experimental public release. APIs may change before `1.0.0`; changes are recorded in the [changelog](./CHANGELOG.md).
240
+ > **Status:** `0.0.23` is the current experimental public release. APIs may change before `1.0.0`; changes are recorded in the [changelog](./CHANGELOG.md).
252
241
 
253
242
  ```bash
254
243
  npm install
@@ -262,6 +251,9 @@ The renderer development suite also needs Poppler's `pdftoppm` on `PATH` for
262
251
  independent PDF pixel checks. The CI and protected release jobs install
263
252
  `poppler-utils` explicitly; this is not a runtime package dependency.
264
253
 
254
+
255
+ For extension authors, the installed package includes `node_modules/ggaction/knowledge/extension-authoring.md`. Read that file alongside the installed declarations; it is a guide file, not an importable package entry.
256
+
265
257
  ## Related Links
266
258
 
267
259
  - Action-trace demo: [Link](https://ggactionbot.github.io/action-trace-demo/)
@@ -269,7 +261,8 @@ independent PDF pixel checks. The CI and protected release jobs install
269
261
  ### Prepare a release
270
262
 
271
263
  Record changes under `Unreleased` in `CHANGELOG.md` and commit the reviewed work.
272
- Run `npm run release:prepare -- 0.0.16 --dry-run` to preview version updates.
264
+ Set `NEXT_VERSION` to the agreed next release version (at least the current package version).
265
+ Run `npm run release:prepare -- "$NEXT_VERSION" --dry-run` to preview version updates.
273
266
  Omit `--dry-run` to update versions, promote notes, and generate the release
274
267
  contract, documentation, and local notes. Review the Git diff. After committing
275
268
  runtime changes, rerun the command to refresh source provenance; existing notes
@@ -1 +1 @@
1
- {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://ggaction.github.io/ggaction/schemas/action-card.schema.json","title":"ggaction compact action card","type":"object","additionalProperties":false,"required":["schemaVersion","name","layer","domain","summary","signature","intents","lifecycle","resources","authoringRoles","wraps","editableVia","supports","units","inference","completionRequirements","options","callPatterns","snippet","errors","route"],"properties":{"schemaVersion":{"const":3},"name":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"},"layer":{"enum":["user-facing","advanced","primitive"]},"domain":{"type":"string","minLength":1},"summary":{"type":"string","minLength":20,"maxLength":420},"signature":{"type":"string","minLength":10},"intents":{"type":"array","minItems":3,"maxItems":7,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":80}},"lifecycle":{"type":"string","minLength":3},"resources":{"type":"object","additionalProperties":false,"required":["prerequisites","owns","idOptions"],"properties":{"prerequisites":{"type":"array","maxItems":4,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":100}},"owns":{"type":"array","maxItems":3,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":80}},"idOptions":{"type":"array","maxItems":10,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":30}}}},"authoringRoles":{"type":"array","minItems":1,"maxItems":5,"uniqueItems":true,"items":{"enum":["H0","H1","H2","H3","H4"]}},"wraps":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"}},"editableVia":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"}},"supports":{"type":"object","additionalProperties":false,"required":["entryPoints"],"properties":{"entryPoints":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"enum":["default","basic"]}}}},"units":{"type":"array","maxItems":16,"items":{"type":"object","additionalProperties":false,"required":["path","unit"],"properties":{"path":{"type":"string","minLength":1,"maxLength":80},"unit":{"enum":["logical-pixel","degree","angle","ratio","probability","count","calendar-unit","temporal-input","data-value","band-fraction"]}}}},"inference":{"type":"array","maxItems":20,"items":{"type":"object","additionalProperties":false,"required":["input","strategy"],"properties":{"input":{"type":"string","minLength":1,"maxLength":80},"strategy":{"enum":["explicit","explicit-or-current","explicit-current-unique-or-error","documented-auto","documented-default"]}}}},"completionRequirements":{"type":"object","additionalProperties":false,"required":["state","requires","allowsEmpty"],"properties":{"state":{"enum":["complete","deferred","contextual","not-applicable"]},"requires":{"type":"array","maxItems":4,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":100}},"allowsEmpty":{"type":"boolean"}}},"options":{"type":"array","maxItems":40,"items":{"type":"object","additionalProperties":false,"required":["name","required","type"],"properties":{"name":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"},"required":{"type":"boolean"},"type":{"type":"string","minLength":1,"maxLength":500}}}},"callPatterns":{"type":"array","minItems":1,"maxItems":3,"uniqueItems":true,"items":{"type":"string","minLength":3,"maxLength":260}},"snippet":{"type":"string","minLength":3,"maxLength":700},"errors":{"type":"array","maxItems":2,"items":{"type":"object","additionalProperties":false,"required":["error","fix"],"properties":{"error":{"type":"string","minLength":5,"maxLength":220},"fix":{"type":"string","minLength":5,"maxLength":220}}}},"route":{"type":"string","pattern":"^/reference/"}}}
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://ggaction.github.io/ggaction/schemas/action-card.schema.json","title":"ggaction compact action card","type":"object","additionalProperties":false,"required":["schemaVersion","name","layer","domain","summary","signature","intents","lifecycle","resources","authoringRoles","wraps","editableVia","supports","units","inference","completionRequirements","options","callPatterns","snippet","errors","route"],"properties":{"schemaVersion":{"const":3},"name":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"},"layer":{"enum":["user-facing","advanced","primitive"]},"domain":{"type":"string","minLength":1},"summary":{"type":"string","minLength":20,"maxLength":420},"signature":{"type":"string","minLength":10},"intents":{"type":"array","minItems":3,"maxItems":7,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":80}},"lifecycle":{"type":"string","minLength":3},"resources":{"type":"object","additionalProperties":false,"required":["prerequisites","owns","idOptions"],"properties":{"prerequisites":{"type":"array","maxItems":4,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":100}},"owns":{"type":"array","maxItems":3,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":80}},"idOptions":{"type":"array","maxItems":10,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":30}}}},"authoringRoles":{"type":"array","minItems":1,"maxItems":5,"uniqueItems":true,"items":{"enum":["H0","H1","H2","H3","H4"]}},"wraps":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"}},"editableVia":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"}},"supports":{"type":"object","additionalProperties":false,"required":["entryPoints"],"properties":{"entryPoints":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"enum":["default","basic"]}}}},"units":{"type":"array","maxItems":16,"items":{"type":"object","additionalProperties":false,"required":["path","unit"],"properties":{"path":{"type":"string","minLength":1,"maxLength":80},"unit":{"enum":["logical-pixel","degree","angle","ratio","probability","count","calendar-unit","temporal-input","data-value","band-fraction"]}}}},"inference":{"type":"array","maxItems":20,"items":{"type":"object","additionalProperties":false,"required":["input","strategy"],"properties":{"input":{"type":"string","minLength":1,"maxLength":80},"strategy":{"enum":["explicit","explicit-or-current","explicit-current-unique-or-error","documented-auto","documented-default"]}}}},"completionRequirements":{"type":"object","additionalProperties":false,"required":["state","requires","allowsEmpty"],"properties":{"state":{"enum":["complete","deferred","contextual","not-applicable"]},"requires":{"type":"array","maxItems":4,"uniqueItems":true,"items":{"type":"string","minLength":2,"maxLength":100}},"allowsEmpty":{"type":"boolean","description":"Whether this action permits an empty result. This does not promise that subsequent actions can infer domains from empty data or that geometry is complete."}}},"options":{"type":"array","maxItems":40,"items":{"type":"object","additionalProperties":false,"required":["name","required","type"],"properties":{"name":{"type":"string","pattern":"^[A-Za-z][A-Za-z0-9]*$"},"required":{"type":"boolean"},"type":{"type":"string","minLength":1,"maxLength":500}}}},"callPatterns":{"type":"array","minItems":1,"maxItems":3,"uniqueItems":true,"items":{"type":"string","minLength":3,"maxLength":260}},"snippet":{"type":"string","minLength":3,"maxLength":700},"errors":{"type":"array","maxItems":2,"items":{"type":"object","additionalProperties":false,"required":["error","fix"],"properties":{"error":{"type":"string","minLength":5,"maxLength":220},"fix":{"type":"string","minLength":5,"maxLength":220}}}},"route":{"type":"string","pattern":"^/reference/"}}}