create-yss-spec 1.1.2 → 1.1.4

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 (278) hide show
  1. package/package.json +1 -1
  2. package/template/.agents/skills/excalidraw-diagram-generator/SKILL.md +3 -3
  3. package/template/.agents/skills/grill-me/SKILL.md +7 -0
  4. package/template/.agents/skills/grilling/SKILL.md +12 -0
  5. package/template/.agents/skills/handoff/SKILL.md +16 -0
  6. package/template/.agents/skills/to-issues/SKILL.md +2 -2
  7. package/template/.claude/skills/grill-me/SKILL.md +7 -0
  8. package/template/.claude/skills/grilling/SKILL.md +12 -0
  9. package/template/.claude/skills/handoff/SKILL.md +16 -0
  10. package/template/.claude/skills/to-issues/SKILL.md +2 -2
  11. package/template/.codex/skills/cross-repo-implementation-routing/SKILL.md +1 -1
  12. package/template/.codex/skills/data-analytics/.app.json +84 -0
  13. package/template/.codex/skills/data-analytics/.codex-plugin/plugin.json +66 -0
  14. package/template/.codex/skills/data-analytics/.mcp.json +30 -0
  15. package/template/.codex/skills/data-analytics/AGENTS.md +20 -0
  16. package/template/.codex/skills/data-analytics/DEPENDENCIES.MD +27 -0
  17. package/template/.codex/skills/data-analytics/README.md +60 -0
  18. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html +16 -0
  19. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part001 +1 -0
  20. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part002 +1 -0
  21. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part003 +1 -0
  22. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part004 +1 -0
  23. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part005 +1 -0
  24. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part006 +1 -0
  25. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html +16 -0
  26. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part001 +1 -0
  27. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part002 +1 -0
  28. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part003 +1 -0
  29. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part004 +1 -0
  30. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part005 +1 -0
  31. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part006 +1 -0
  32. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part007 +1 -0
  33. package/template/.codex/skills/data-analytics/assets/datascience-small.svg +5 -0
  34. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html +16 -0
  35. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part001 +1 -0
  36. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part002 +1 -0
  37. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part003 +1 -0
  38. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part004 +1 -0
  39. package/template/.codex/skills/data-analytics/assets/datascience.png +0 -0
  40. package/template/.codex/skills/data-analytics/assets/datascience.svg +10 -0
  41. package/template/.codex/skills/data-analytics/mcp/server.cjs +2963 -0
  42. package/template/.codex/skills/data-analytics/package-lock.json +3048 -0
  43. package/template/.codex/skills/data-analytics/package.json +43 -0
  44. package/template/.codex/skills/data-analytics/scripts/normalize-widget-assets.mjs +75 -0
  45. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +160 -0
  46. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/agents/openai.yaml +6 -0
  47. package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +148 -0
  48. package/template/.codex/skills/data-analytics/skills/build-dashboard/agents/openai.yaml +6 -0
  49. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/bi-platform-dashboard.md +18 -0
  50. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/html-dashboard.md +24 -0
  51. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/mcp-artifact-dashboard.md +71 -0
  52. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/streamlit-dashboard.md +85 -0
  53. package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +207 -0
  54. package/template/.codex/skills/data-analytics/skills/build-report/agents/openai.yaml +6 -0
  55. package/template/.codex/skills/data-analytics/skills/build-report/assets/executive-report-shell.html +70 -0
  56. package/template/.codex/skills/data-analytics/skills/build-report/assets/technical-report-shell.html +66 -0
  57. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +118 -0
  58. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/agents/openai.yaml +6 -0
  59. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/__init__.py +1 -0
  60. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +57 -0
  61. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/constants.py +61 -0
  62. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/docx_writer.py +362 -0
  63. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/html_parser.py +829 -0
  64. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/model.py +30 -0
  65. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +129 -0
  66. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/quality.py +374 -0
  67. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/rendering.py +613 -0
  68. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/table_utils.py +54 -0
  69. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/utils.py +16 -0
  70. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc_plan.py +9 -0
  71. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +78 -0
  72. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/agents/openai.yaml +6 -0
  73. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/scripts/report_to_google_slides.py +2379 -0
  74. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +88 -0
  75. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/agents/openai.yaml +6 -0
  76. package/template/.codex/skills/data-analytics/skills/build-report/specifications/executive-report.md +97 -0
  77. package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +59 -0
  78. package/template/.codex/skills/data-analytics/skills/build-report/specifications/technical-report.md +75 -0
  79. package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +103 -0
  80. package/template/.codex/skills/data-analytics/skills/design-kpis/agents/openai.yaml +6 -0
  81. package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +68 -0
  82. package/template/.codex/skills/data-analytics/skills/gather-business-context/agents/openai.yaml +6 -0
  83. package/template/.codex/skills/data-analytics/skills/index/SKILL.md +251 -0
  84. package/template/.codex/skills/data-analytics/skills/index/agents/openai.yaml +6 -0
  85. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +131 -0
  86. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/agents/openai.yaml +6 -0
  87. package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +141 -0
  88. package/template/.codex/skills/data-analytics/skills/kpi-reporting/agents/openai.yaml +6 -0
  89. package/template/.codex/skills/data-analytics/skills/kpi-reporting/references/report-templates.md +32 -0
  90. package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +106 -0
  91. package/template/.codex/skills/data-analytics/skills/market-sizing/agents/openai.yaml +6 -0
  92. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +130 -0
  93. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/agents/openai.yaml +6 -0
  94. package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +141 -0
  95. package/template/.codex/skills/data-analytics/skills/product-business-analysis/agents/openai.yaml +6 -0
  96. package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +178 -0
  97. package/template/.codex/skills/data-analytics/skills/spreadsheets/agents/openai.yaml +9 -0
  98. package/template/.codex/skills/data-analytics/skills/spreadsheets/assets/file-spreadsheet.png +0 -0
  99. package/template/.codex/skills/data-analytics/skills/spreadsheets/charts.md +31 -0
  100. package/template/.codex/skills/data-analytics/skills/spreadsheets/references/artifact_tool_api.md +466 -0
  101. package/template/.codex/skills/data-analytics/skills/spreadsheets/style_guidelines.md +99 -0
  102. package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +195 -0
  103. package/template/.codex/skills/data-analytics/skills/user-context/agents/openai.yaml +6 -0
  104. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +26 -0
  105. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/source-category-config.json +51 -0
  106. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/user-context-config.md +66 -0
  107. package/template/.codex/skills/data-analytics/skills/user-context/references/automation.md +69 -0
  108. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +204 -0
  109. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-state-template.json +87 -0
  110. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +497 -0
  111. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/connector-playbook.md +74 -0
  112. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/setup.md +65 -0
  113. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/skill-template.md +160 -0
  114. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/source-intake.md +75 -0
  115. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/weekly-polling-automation.md +96 -0
  116. package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +263 -0
  117. package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +1460 -0
  118. package/template/.codex/skills/data-analytics/skills/user-context/scripts/init_user_context_state.py +128 -0
  119. package/template/.codex/skills/data-analytics/skills/user-context/scripts/reset_user_context_state.py +101 -0
  120. package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +499 -0
  121. package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +978 -0
  122. package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +190 -0
  123. package/template/.codex/skills/data-analytics/skills/validate-data/agents/openai.yaml +6 -0
  124. package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +157 -0
  125. package/template/.codex/skills/data-analytics/skills/visualize-data/agents/openai.yaml +6 -0
  126. package/template/.codex/skills/data-analytics/skills/visualize-data/references/seaborn-templates.md +774 -0
  127. package/template/.codex/skills/data-analytics/src/DESIGN.md +222 -0
  128. package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +3666 -0
  129. package/template/.codex/skills/data-analytics/src/analytics-app/analytics-layout.test.mjs +136 -0
  130. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartFrame.tsx +54 -0
  131. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartLegend.tsx +96 -0
  132. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartRenderer.tsx +1647 -0
  133. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartTooltip.tsx +245 -0
  134. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-app-helpers.tsx +462 -0
  135. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-capabilities.ts +107 -0
  136. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-compatibility.ts +164 -0
  137. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-contract.ts +192 -0
  138. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-theme.ts +203 -0
  139. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-tokens.css +619 -0
  140. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-transforms.ts +402 -0
  141. package/template/.codex/skills/data-analytics/src/analytics-app/fonts/SystemSansVariableVF.woff2 +0 -0
  142. package/template/.codex/skills/data-analytics/src/analytics-app/imageExport.ts +370 -0
  143. package/template/.codex/skills/data-analytics/src/analytics-app/layout/AnalyticsLayoutCanvas.tsx +536 -0
  144. package/template/.codex/skills/data-analytics/src/analytics-app/layout/RichMarkdown.tsx +681 -0
  145. package/template/.codex/skills/data-analytics/src/analytics-app/layout/analyticsLayoutCore.ts +164 -0
  146. package/template/.codex/skills/data-analytics/src/analytics-app/main.tsx +21 -0
  147. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/chart_contract.py +472 -0
  148. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/check_analytics_app_runtime_links.py +75 -0
  149. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/design_contract.py +142 -0
  150. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/package_utils.py +142 -0
  151. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/tests/test_package_utils.py +377 -0
  152. package/template/.codex/skills/data-analytics/src/analytics-app/styles.css +3468 -0
  153. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.d.ts +44 -0
  154. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.jsx +639 -0
  155. package/template/.codex/skills/data-analytics/src/analytics-app/tables/data-table.css +327 -0
  156. package/template/.codex/skills/data-analytics/src/analytics-app/tokens.css +225 -0
  157. package/template/.codex/skills/data-analytics/src/analytics-app/types.ts +204 -0
  158. package/template/.codex/skills/data-analytics/src/analytics-app-core.md +85 -0
  159. package/template/.codex/skills/data-analytics/src/codex-style-contract.md +30 -0
  160. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.html +12 -0
  161. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.jsx +1008 -0
  162. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.css +2117 -0
  163. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.html +122 -0
  164. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.js +3588 -0
  165. package/template/.codex/skills/data-analytics/src/datascience-table-widget.css +483 -0
  166. package/template/.codex/skills/data-analytics/src/datascience-table-widget.html +32 -0
  167. package/template/.codex/skills/data-analytics/src/datascience-table-widget.js +333 -0
  168. package/template/.codex/skills/data-analytics/src/mcp-host.js +153 -0
  169. package/template/.codex/skills/data-analytics/src/recharts-config.js +315 -0
  170. package/template/.codex/skills/data-analytics/src/recharts-renderer.jsx +294 -0
  171. package/template/.codex/skills/data-analytics/src/sql-source-view.css +33 -0
  172. package/template/.codex/skills/data-analytics/src/sql-source-view.js +157 -0
  173. package/template/.codex/skills/data-analytics/src/styles/codex-theme.css +121 -0
  174. package/template/.codex/skills/data-analytics/src/table-renderer.jsx +28 -0
  175. package/template/.codex/skills/data-analytics/tests/chart-transforms.test.mjs +87 -0
  176. package/template/.codex/skills/data-analytics/tests/funnel-smoke.html +105 -0
  177. package/template/.codex/skills/data-analytics/tests/inline-widget-compare.html +233 -0
  178. package/template/.codex/skills/data-analytics/tests/mcp-server.test.mjs +1500 -0
  179. package/template/.codex/skills/data-analytics/tests/native-style-contract.test.mjs +219 -0
  180. package/template/.codex/skills/data-analytics/tests/recharts-config.test.mjs +144 -0
  181. package/template/.codex/skills/data-analytics/tests/recharts-renderer.test.mjs +11 -0
  182. package/template/.codex/skills/data-analytics/tests/rich-markdown.test.mjs +54 -0
  183. package/template/.codex/skills/data-analytics/tests/widget-render-harness.html +321 -0
  184. package/template/.codex/skills/data-analytics/tsconfig.json +19 -0
  185. package/template/.codex/skills/data-analytics/vite.config.ts +46 -0
  186. package/template/.codex/skills/product-design/.app.json +7 -0
  187. package/template/.codex/skills/product-design/.codex-plugin/plugin.json +50 -0
  188. package/template/.codex/skills/product-design/README.md +50 -0
  189. package/template/.codex/skills/product-design/agents/openai.yaml +4 -0
  190. package/template/.codex/skills/product-design/assets/composerIcon.svg +9 -0
  191. package/template/.codex/skills/product-design/assets/logo.png +0 -0
  192. package/template/.codex/skills/product-design/package.json +11 -0
  193. package/template/.codex/skills/product-design/references/browser-order.md +9 -0
  194. package/template/.codex/skills/product-design/references/communication-protocol.md +45 -0
  195. package/template/.codex/skills/product-design/references/critical-overrides.md +58 -0
  196. package/template/.codex/skills/product-design/references/local-prototype-preflight.md +16 -0
  197. package/template/.codex/skills/product-design/scripts/bootstrap-prototype.mjs +147 -0
  198. package/template/.codex/skills/product-design/skills/audit/SKILL.md +159 -0
  199. package/template/.codex/skills/product-design/skills/audit/agents/openai.yaml +6 -0
  200. package/template/.codex/skills/product-design/skills/audit/references/design-audit-framework.md +73 -0
  201. package/template/.codex/skills/product-design/skills/design-qa/SKILL.md +133 -0
  202. package/template/.codex/skills/product-design/skills/design-qa/agents/openai.yaml +6 -0
  203. package/template/.codex/skills/product-design/skills/design-qa/references/qa-rubric.md +61 -0
  204. package/template/.codex/skills/product-design/skills/get-context/SKILL.md +81 -0
  205. package/template/.codex/skills/product-design/skills/get-context/agents/openai.yaml +6 -0
  206. package/template/.codex/skills/product-design/skills/ideate/SKILL.md +179 -0
  207. package/template/.codex/skills/product-design/skills/ideate/agents/openai.yaml +6 -0
  208. package/template/.codex/skills/product-design/skills/image-to-code/SKILL.md +105 -0
  209. package/template/.codex/skills/product-design/skills/image-to-code/agents/openai.yaml +6 -0
  210. package/template/.codex/skills/product-design/skills/index/SKILL.md +126 -0
  211. package/template/.codex/skills/product-design/skills/index/agents/openai.yaml +6 -0
  212. package/template/.codex/skills/product-design/skills/prototype/SKILL.md +128 -0
  213. package/template/.codex/skills/product-design/skills/prototype/agents/openai.yaml +6 -0
  214. package/template/.codex/skills/product-design/skills/prototype/references/existing-codebase-edits.md +18 -0
  215. package/template/.codex/skills/product-design/skills/research/SKILL.md +92 -0
  216. package/template/.codex/skills/product-design/skills/research/agents/openai.yaml +6 -0
  217. package/template/.codex/skills/product-design/skills/share/SKILL.md +41 -0
  218. package/template/.codex/skills/product-design/skills/share/agents/openai.yaml +6 -0
  219. package/template/.codex/skills/product-design/skills/url-to-code/SKILL.md +124 -0
  220. package/template/.codex/skills/product-design/skills/url-to-code/agents/openai.yaml +6 -0
  221. package/template/.codex/skills/product-design/skills/user-context/SKILL.md +147 -0
  222. package/template/.codex/skills/product-design/skills/user-context/agents/openai.yaml +6 -0
  223. package/template/.codex/skills/product-design/skills/user-context/plugin-author-config/user-context-template.md +63 -0
  224. package/template/.codex/skills/product-design/skills/user-context/references/onboarding.md +66 -0
  225. package/template/.codex/skills/product-design/skills/user-context/scripts/init_user_context.py +86 -0
  226. package/template/.codex/skills/product-design/skills/user-context/scripts/user_context_preflight.py +204 -0
  227. package/template/.codex/skills/product-design/templates/prototype/AGENTS.md +7 -0
  228. package/template/.codex/skills/product-design/templates/prototype/index.html +12 -0
  229. package/template/.codex/skills/product-design/templates/prototype/package.json +18 -0
  230. package/template/.codex/skills/product-design/templates/prototype/src/App.jsx +5 -0
  231. package/template/.codex/skills/product-design/templates/prototype/src/main.jsx +10 -0
  232. package/template/.codex/skills/product-design/templates/prototype/src/styles.css +13 -0
  233. package/template/.codex/skills/product-design/templates/prototype/vite.config.mjs +14 -0
  234. package/template/.codex/skills/product-design-prototype/SKILL.md +1 -1
  235. package/template/.codex/skills/yss-api-integration/SKILL.md +1 -1
  236. package/template/.codex/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
  237. package/template/.codex/skills/yss-filerunner/SKILL.md +1 -1
  238. package/template/.codex/skills/yss-openapi/SKILL.md +1 -1
  239. package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +1 -1
  240. package/template/.codex/skills/yss-openapi-governance/SKILL.md +3 -3
  241. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +23 -7
  242. package/template/.codex/skills/yss-router/SKILL.md +1 -2
  243. package/template/.codex/skills/yss-router/references/boundaries.md +0 -1
  244. package/template/.codex/skills/yss-source-index/references/source-map-config.md +0 -1
  245. package/template/.codex/skills/yss-source-index/scripts/refresh-yss-skill-index.py +0 -3
  246. package/template/.hermes/skills/grill-me/SKILL.md +7 -0
  247. package/template/.hermes/skills/grilling/SKILL.md +12 -0
  248. package/template/.hermes/skills/handoff/SKILL.md +16 -0
  249. package/template/.hermes/skills/to-issues/SKILL.md +2 -2
  250. package/template/.pi/skills/grill-me/SKILL.md +7 -0
  251. package/template/.pi/skills/grilling/SKILL.md +12 -0
  252. package/template/.pi/skills/handoff/SKILL.md +16 -0
  253. package/template/.pi/skills/to-issues/SKILL.md +2 -2
  254. package/template/.trae/skills/grill-me/SKILL.md +7 -0
  255. package/template/.trae/skills/grilling/SKILL.md +12 -0
  256. package/template/.trae/skills/handoff/SKILL.md +16 -0
  257. package/template/.trae/skills/to-issues/SKILL.md +2 -2
  258. package/template/AGENTS.md +11 -3
  259. package/template/docs/adr/adr-product-design-prototype-entrypoint.md +54 -0
  260. package/template/docs/api/templates/openapi-draft-review-checklist.md +4 -2
  261. package/template/docs/design/README.md +8 -4
  262. package/template/docs/design/templates/interaction-spec-template.md +4 -1
  263. package/template/docs/design/templates/prototype-confirmation-template.md +57 -0
  264. package/template/docs/design/templates/prototype-review-checklist.md +6 -2
  265. package/template/docs/design/templates/state-matrix-template.md +1 -1
  266. package/template/docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md +22 -3
  267. package/template/docs/process/harness-executive-blueprint.md +2 -1
  268. package/template/docs/process/harness-process-tailoring.md +8 -1
  269. package/template/docs/process/harness-work-unit-map.md +1 -1
  270. package/template/docs/process/lifecycle-artifact-map.md +17 -8
  271. package/template/docs/process/product-prototype-workflow.md +82 -0
  272. package/template/docs/user-guide/product-lifecycle-workflow.md +2 -2
  273. package/template/docs/user-guide/product-rd-lifecycle-best-practices.md +15 -10
  274. package/template/scripts/verify-template +0 -14
  275. package/template/skills-lock.json +70 -27
  276. package/template/.codex/skills/yss-anti-scheduler/SKILL.md +0 -53
  277. package/template/.codex/skills/yss-anti-scheduler/agents/openai.yaml +0 -4
  278. package/template/.codex/skills/yss-anti-scheduler/references/source-index.md +0 -157
@@ -0,0 +1,315 @@
1
+ export const CANONICAL_CHART_TYPES = [
2
+ "line",
3
+ "area",
4
+ "stackedArea",
5
+ "bar",
6
+ "histogram",
7
+ "scatter",
8
+ "heatmap",
9
+ "pie",
10
+ "leaderboard",
11
+ "sparkline",
12
+ "funnel",
13
+ "waterfall",
14
+ "boxPlot",
15
+ ];
16
+
17
+ export const chartPickerSections = [
18
+ {
19
+ title: "Trends",
20
+ options: [
21
+ { type: "line", label: "Line", preview: "line" },
22
+ { type: "area", label: "Area", preview: "area" },
23
+ { type: "stackedArea", label: "Stacked area", preview: "stacked-area" },
24
+ { type: "sparkline", label: "Sparkline", preview: "sparkline" },
25
+ ],
26
+ },
27
+ {
28
+ title: "Comparison",
29
+ options: [
30
+ { type: "bar", label: "Bar", preview: "bar" },
31
+ { type: "leaderboard", label: "Leaderboard", preview: "leaderboard" },
32
+ ],
33
+ },
34
+ {
35
+ title: "Distribution",
36
+ options: [
37
+ { type: "histogram", label: "Histogram", preview: "histogram" },
38
+ { type: "boxPlot", label: "Box plot", preview: "box-plot" },
39
+ ],
40
+ },
41
+ {
42
+ title: "Relationships",
43
+ options: [
44
+ { type: "scatter", label: "Scatter", preview: "scatter" },
45
+ { type: "heatmap", label: "Heatmap", preview: "heatmap" },
46
+ ],
47
+ },
48
+ {
49
+ title: "Composition",
50
+ options: [
51
+ { type: "pie", label: "Pie", preview: "pie" },
52
+ ],
53
+ },
54
+ {
55
+ title: "Progression",
56
+ options: [
57
+ { type: "funnel", label: "Funnel", preview: "funnel" },
58
+ { type: "waterfall", label: "Waterfall", preview: "waterfall" },
59
+ ],
60
+ },
61
+ ];
62
+
63
+ const DEFAULT_COLORS = [
64
+ "var(--ds-chart-stack-1, #003f7a)",
65
+ "var(--ds-chart-stack-2, #0169cc)",
66
+ "var(--ds-chart-stack-3, #8046d9)",
67
+ "var(--ds-chart-stack-4, #339cff)",
68
+ "var(--ds-chart-stack-5, #ad7bf9)",
69
+ "var(--ds-chart-series-green, #00692a)",
70
+ "var(--ds-chart-series-orange, #923b0f)",
71
+ "var(--ds-chart-series-neutral, #8f8f8f)",
72
+ ];
73
+ const COMPACT_VALUE_THRESHOLD = 100_000;
74
+
75
+ export function asArray(value) {
76
+ return Array.isArray(value) ? value : [];
77
+ }
78
+
79
+ export function text(value) {
80
+ return value == null ? "" : String(value);
81
+ }
82
+
83
+ export function number(value) {
84
+ const parsed = Number(value);
85
+ return Number.isFinite(parsed) ? parsed : null;
86
+ }
87
+
88
+ export function unique(values) {
89
+ const seen = new Set();
90
+ const output = [];
91
+ for (const value of values) {
92
+ const key = text(value);
93
+ if (seen.has(key)) continue;
94
+ seen.add(key);
95
+ output.push(key);
96
+ }
97
+ return output;
98
+ }
99
+
100
+ export function isCanonicalChartType(value) {
101
+ return CANONICAL_CHART_TYPES.includes(value);
102
+ }
103
+
104
+ export function canonicalVisualizationType(value) {
105
+ return isCanonicalChartType(value) ? value : "bar";
106
+ }
107
+
108
+ export function groupData(data) {
109
+ const groups = new Map();
110
+ for (const point of asArray(data)) {
111
+ const y = number(point && point.y);
112
+ if (y == null) continue;
113
+ const series = text((point && point.series) || "Value");
114
+ if (!groups.has(series)) groups.set(series, []);
115
+ groups.get(series).push({ x: point && point.x, y, label: point && point.label, raw: point });
116
+ }
117
+ return groups;
118
+ }
119
+
120
+ export function rechartsLegendNames(data, chartType) {
121
+ if (chartType === "histogram" || chartType === "heatmap" || chartType === "boxPlot") return [];
122
+ return [...groupData(data).keys()];
123
+ }
124
+
125
+ export function hasNumericX(data) {
126
+ return asArray(data).some((point) => number(point && point.x) != null);
127
+ }
128
+
129
+ export function emptyChartMessage(data, chartType, visibleSeries = new Set()) {
130
+ const rows = asArray(data);
131
+ if (!rows.length) return "No chart data to render.";
132
+ const legendNames = rechartsLegendNames(rows, chartType);
133
+ const seriesNames = [...groupData(rows).keys()];
134
+ if (legendNames.length && visibleSeries instanceof Set && visibleSeries.size && !legendNames.some((name) => visibleSeries.has(name))) {
135
+ return "No visible series selected.";
136
+ }
137
+ if (chartType === "scatter" && !hasNumericX(rows)) return "Scatter plots need numeric x and y values.";
138
+ if (chartType === "histogram" && !rows.some((point) => number(point && (point.y != null ? point.y : point.x)) != null)) {
139
+ return "Histogram needs numeric values.";
140
+ }
141
+ if (chartType === "heatmap" && seriesNames.length <= 1) return "Heatmaps need a grouping field with at least two series.";
142
+ if (chartType === "pie") {
143
+ const total = rows.reduce((sum, point) => sum + Math.max(0, number(point && point.y) ?? 0), 0);
144
+ if (!total) return "Pie charts need positive values.";
145
+ if (seriesNames.length <= 1) return "Pie charts need a grouping field with at least two slices.";
146
+ }
147
+ if ((chartType === "line" || chartType === "area" || chartType === "stackedArea" || chartType === "sparkline") && unique(rows.map((point) => point && point.x)).length < 2) {
148
+ return `${chartType === "stackedArea" ? "Stacked area" : "Trend"} charts need at least two x values.`;
149
+ }
150
+ if (chartType === "stackedArea" && seriesNames.length <= 1) return "Stacked area charts need a grouping field with at least two series.";
151
+ if (chartType === "funnel") {
152
+ const xCount = unique(rows.map((point) => point && point.x)).length;
153
+ if (seriesNames.length > 1) return "Funnel charts need a single series.";
154
+ if (xCount < 2 || xCount > 8) return "Funnel charts need between two and eight stages.";
155
+ if (rows.some((point) => (number(point && point.y) ?? 0) < 0)) return "Funnel charts need non-negative values.";
156
+ }
157
+ if (chartType === "waterfall") {
158
+ const xCount = unique(rows.map((point) => point && point.x)).length;
159
+ if (seriesNames.length > 1) return "Waterfall charts need a single series.";
160
+ if (xCount < 2 || xCount > 12) return "Waterfall charts need between two and twelve steps.";
161
+ }
162
+ if (chartType === "leaderboard") {
163
+ const xCount = unique(rows.map((point) => point && point.x)).length;
164
+ if (seriesNames.length > 1) return "Leaderboards need a single series.";
165
+ if (xCount < 2) return "Leaderboards need at least two ranked categories.";
166
+ }
167
+ if (chartType === "boxPlot") {
168
+ const numericRows = rows.filter((point) => number(point && point.y) != null);
169
+ const valuesByCategory = new Map();
170
+ for (const point of numericRows) {
171
+ const key = text(point && point.x);
172
+ valuesByCategory.set(key, (valuesByCategory.get(key) || 0) + 1);
173
+ }
174
+ if (numericRows.length < 10 || Math.max(0, ...valuesByCategory.values()) < 5) {
175
+ return "Box plots need at least ten numeric values and five values in one category.";
176
+ }
177
+ }
178
+ return "";
179
+ }
180
+
181
+ export function isDateLikeValue(value) {
182
+ if (value instanceof Date && Number.isFinite(value.getTime())) return true;
183
+ if (typeof value !== "string") return false;
184
+ const raw = value.trim();
185
+ if (!raw) return false;
186
+ if (!/^\d{4}[-/]\d{1,2}(?:[-/]\d{1,2})?(?:[T\s]\d{1,2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)?$/.test(raw)) {
187
+ return false;
188
+ }
189
+ return Number.isFinite(new Date(raw).getTime());
190
+ }
191
+
192
+ export function resolveCssColor(value, root = document.documentElement) {
193
+ const raw = text(value).trim();
194
+ if (!raw.startsWith("var(")) return raw;
195
+ const match = raw.match(/^var\((--[^,\s)]+)(?:,\s*([^)]+))?\)$/);
196
+ if (!match) return raw;
197
+ const resolved = getComputedStyle(root).getPropertyValue(match[1]).trim();
198
+ return resolved || text(match[2]).trim();
199
+ }
200
+
201
+ export function resolveCssColors(values, root) {
202
+ return asArray(values).map((value) => resolveCssColor(value, root)).filter(Boolean);
203
+ }
204
+
205
+ export function colorAt(colors, index) {
206
+ return colors[index % colors.length] || DEFAULT_COLORS[index % DEFAULT_COLORS.length];
207
+ }
208
+
209
+ function compactDigits(value) {
210
+ const absolute = Math.abs(value);
211
+ if (absolute >= COMPACT_VALUE_THRESHOLD) return 1;
212
+ return 2;
213
+ }
214
+
215
+ function formatNumber(value, compact = false) {
216
+ const absolute = Math.abs(value);
217
+ return new Intl.NumberFormat(undefined, {
218
+ maximumFractionDigits: compactDigits(value),
219
+ notation: compact && absolute >= COMPACT_VALUE_THRESHOLD ? "compact" : "standard",
220
+ }).format(value);
221
+ }
222
+
223
+ function isUsdUnit(unit) {
224
+ return unit === "$" || text(unit).toUpperCase() === "USD";
225
+ }
226
+
227
+ function unitScaleSuffix(unit) {
228
+ const normalized = text(unit).toLowerCase();
229
+ if (normalized === "usd millions" || normalized === "usd million") return "M";
230
+ if (normalized === "usd billions" || normalized === "usd billion") return "B";
231
+ if (normalized === "usd thousands" || normalized === "usd thousand") return "K";
232
+ if (/^\$[kmbt]$/i.test(text(unit))) return text(unit).slice(1).toUpperCase();
233
+ return null;
234
+ }
235
+
236
+ function formatCurrency(value) {
237
+ const absolute = Math.abs(value);
238
+ return new Intl.NumberFormat(undefined, {
239
+ currency: "USD",
240
+ maximumFractionDigits: compactDigits(value),
241
+ notation: absolute >= COMPACT_VALUE_THRESHOLD ? "compact" : "standard",
242
+ style: "currency",
243
+ }).format(value).replace(/\.0([KMBT])$/i, "$1");
244
+ }
245
+
246
+ function isPercentWordUnit(unit) {
247
+ const normalized = text(unit).toLowerCase();
248
+ return normalized === "percent" || normalized === "percentage";
249
+ }
250
+
251
+ function formatPercent(value) {
252
+ return new Intl.NumberFormat(undefined, {
253
+ maximumFractionDigits: 1,
254
+ style: "percent",
255
+ }).format(value);
256
+ }
257
+
258
+ export function formatValue(value, unit = "") {
259
+ const numeric = number(value);
260
+ if (numeric == null) return text(value);
261
+ const cleanUnit = text(unit);
262
+ if (!cleanUnit) return formatNumber(numeric, true);
263
+ if (isPercentWordUnit(cleanUnit)) return formatPercent(numeric);
264
+ if (cleanUnit === "%" || cleanUnit.startsWith("%")) return `${formatNumber(numeric)}%`;
265
+ if (isUsdUnit(cleanUnit)) return formatCurrency(numeric);
266
+ const scaleSuffix = unitScaleSuffix(cleanUnit);
267
+ if (scaleSuffix) return `$${formatNumber(numeric)}${scaleSuffix}`;
268
+ if (cleanUnit.startsWith("$")) return `$${formatNumber(numeric)}${cleanUnit.slice(1)}`;
269
+ return `${formatNumber(numeric, true)} ${cleanUnit}`;
270
+ }
271
+
272
+ export function buildCategoryRows(data) {
273
+ const groups = groupData(data);
274
+ const xValues = unique(asArray(data).map((point) => point && point.x));
275
+ return xValues.map((x) => {
276
+ const row = { x: text(x) };
277
+ for (const [series, points] of groups.entries()) {
278
+ const point = points.find((item) => text(item.x) === text(x));
279
+ row[series] = point ? point.y : null;
280
+ }
281
+ return row;
282
+ });
283
+ }
284
+
285
+ export function histogramBins(data, requestedBinCount) {
286
+ const values = asArray(data)
287
+ .map((point) => number(point && (point.y != null ? point.y : point.x)))
288
+ .filter((value) => value != null);
289
+ if (!values.length) return [];
290
+ const min = Math.min(...values);
291
+ const max = Math.max(...values);
292
+ const binCount = Math.max(1, requestedBinCount || Math.min(12, Math.max(5, Math.ceil(Math.sqrt(values.length)))));
293
+ const binWidth = (max - min || 1) / binCount;
294
+ const bins = Array.from({ length: binCount }, (_, index) => ({
295
+ x: `${formatValue(min + index * binWidth)}-${formatValue(min + (index + 1) * binWidth)}`,
296
+ count: 0,
297
+ start: min + index * binWidth,
298
+ end: min + (index + 1) * binWidth,
299
+ }));
300
+ for (const value of values) {
301
+ const index = Math.min(binCount - 1, Math.max(0, Math.floor((value - min) / binWidth)));
302
+ bins[index].count += 1;
303
+ }
304
+ return bins;
305
+ }
306
+
307
+ export function pieRows(data) {
308
+ const groups = groupData(data);
309
+ return [...groups.entries()]
310
+ .map(([name, points]) => ({
311
+ name,
312
+ value: points.reduce((sum, point) => sum + Math.max(0, point.y), 0),
313
+ }))
314
+ .filter((row) => row.value > 0);
315
+ }
@@ -0,0 +1,294 @@
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+
4
+ import { ChartRenderer } from "./analytics-app/charting/ChartRenderer";
5
+ import "./analytics-app/charting/chart-tokens.css";
6
+ import { asArray, number, text } from "./recharts-config.js";
7
+
8
+ const DEFAULT_COMPACT_HEIGHT = 280;
9
+ const DEFAULT_EXPLORER_HEIGHT = 520;
10
+ const DEFAULT_CHART_WIDTH = 760;
11
+ const MIN_CHART_WIDTH = 280;
12
+ const MIN_COMPACT_CHART_HEIGHT = 280;
13
+ const MIN_EXPLORER_CHART_HEIGHT = 320;
14
+
15
+ function formatBinValue(value) {
16
+ return new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(value);
17
+ }
18
+
19
+ function buildHistogramRows(data) {
20
+ const values = asArray(data)
21
+ .map((point) => number(point && (point.y != null ? point.y : point.x)))
22
+ .filter((value) => value != null);
23
+ if (!values.length) return [];
24
+ const min = Math.min(...values);
25
+ const max = Math.max(...values);
26
+ const binCount = Math.max(1, Math.min(12, Math.max(5, Math.ceil(Math.sqrt(values.length)))));
27
+ const binWidth = (max - min || 1) / binCount;
28
+ const rows = Array.from({ length: binCount }, (_, index) => {
29
+ const start = min + index * binWidth;
30
+ const end = min + (index + 1) * binWidth;
31
+ return {
32
+ count: 0,
33
+ x: `${formatBinValue(start)}-${formatBinValue(end)}`,
34
+ };
35
+ });
36
+ for (const value of values) {
37
+ const index = Math.min(binCount - 1, Math.max(0, Math.floor((value - min) / binWidth)));
38
+ rows[index].count += 1;
39
+ }
40
+ return rows;
41
+ }
42
+
43
+ function quantile(sortedValues, percentile) {
44
+ if (!sortedValues.length) return 0;
45
+ const index = (sortedValues.length - 1) * percentile;
46
+ const lower = Math.floor(index);
47
+ const upper = Math.ceil(index);
48
+ if (lower === upper) return sortedValues[lower] ?? 0;
49
+ const weight = index - lower;
50
+ return (sortedValues[lower] ?? 0) * (1 - weight) + (sortedValues[upper] ?? 0) * weight;
51
+ }
52
+
53
+ function buildBoxPlotRows(data) {
54
+ const grouped = new Map();
55
+ for (const point of asArray(data)) {
56
+ const value = number(point && point.y);
57
+ if (value == null) continue;
58
+ const key = text(point && point.x);
59
+ if (!grouped.has(key)) grouped.set(key, []);
60
+ grouped.get(key).push(value);
61
+ }
62
+ return [...grouped.entries()].map(([x, values]) => {
63
+ const sorted = [...values].sort((a, b) => a - b);
64
+ return {
65
+ x,
66
+ min: sorted[0] ?? 0,
67
+ q1: quantile(sorted, 0.25),
68
+ median: quantile(sorted, 0.5),
69
+ q3: quantile(sorted, 0.75),
70
+ max: sorted[sorted.length - 1] ?? 0,
71
+ };
72
+ });
73
+ }
74
+
75
+ function resultRows(dataset) {
76
+ const table = dataset?.table && typeof dataset.table === "object"
77
+ ? dataset.table
78
+ : dataset?.result_table && typeof dataset.result_table === "object"
79
+ ? dataset.result_table
80
+ : null;
81
+ if (Array.isArray(table?.rows)) return table.rows;
82
+ return asArray(dataset?.data);
83
+ }
84
+
85
+ function rowsForType(dataset, type) {
86
+ const rows = resultRows(dataset);
87
+ if (type === "histogram") return buildHistogramRows(rows);
88
+ if (type === "boxPlot") return buildBoxPlotRows(rows);
89
+ return rows;
90
+ }
91
+
92
+ function chartSettingsForDataset(dataset, existing, overrides = {}) {
93
+ const visualizationSettings = dataset?.visualization_spec?.settings;
94
+ const source =
95
+ existing?.settings && typeof existing.settings === "object"
96
+ ? existing.settings
97
+ : visualizationSettings && typeof visualizationSettings === "object"
98
+ ? visualizationSettings
99
+ : {};
100
+ const merged = {
101
+ ...source,
102
+ ...(overrides && typeof overrides === "object" ? overrides : {}),
103
+ };
104
+ return {
105
+ ...merged,
106
+ groupMode: merged.groupMode ?? merged.group_mode,
107
+ orientation: merged.orientation,
108
+ showPoints: merged.showPoints ?? merged.show_points,
109
+ };
110
+ }
111
+
112
+ function isPercentWordUnit(unit) {
113
+ const normalized = text(unit).toLowerCase();
114
+ return normalized === "percent" || normalized === "percentage";
115
+ }
116
+
117
+ function chartSpecForDataset(dataset, type, options) {
118
+ const existing = dataset.chart_spec && typeof dataset.chart_spec === "object" ? dataset.chart_spec : {};
119
+ const { series: _legacySeries, xField: _legacyXField, ...encodedExisting } = existing;
120
+ const rawUnit = options.unit || existing.unit || "";
121
+ const percentWordUnit = isPercentWordUnit(rawUnit);
122
+ const unit = percentWordUnit ? "" : rawUnit;
123
+ const settings = chartSettingsForDataset(dataset, existing, options.settings);
124
+ const existingEncodings = existing.encodings && typeof existing.encodings === "object" && !Array.isArray(existing.encodings) ? existing.encodings : {};
125
+ const hasScatterSize = type === "scatter" && asArray(dataset.data).some((point) => number(point && point.size) != null);
126
+ const encodings = {
127
+ ...existingEncodings,
128
+ ...(hasScatterSize && !existingEncodings.size ? { size: { field: "size", label: "Size", type: "quantitative" } } : {}),
129
+ };
130
+ const referenceLines = Array.isArray(existing.referenceLines) ? [...existing.referenceLines] : [];
131
+ const baseline = number(options.baseline);
132
+ if (baseline != null && !referenceLines.some((line) => number(line && line.value) === baseline)) {
133
+ referenceLines.push({
134
+ axis:
135
+ type === "horizontalBar" ||
136
+ type === "horizontalStackedBar" ||
137
+ type === "horizontalStackedBar100" ||
138
+ (type === "bar" && settings.orientation === "horizontal")
139
+ ? "x"
140
+ : "y",
141
+ value: baseline,
142
+ });
143
+ }
144
+ return {
145
+ ...encodedExisting,
146
+ dataset: existing.dataset || dataset.id || "inline",
147
+ id: existing.id || dataset.id || "inline-chart",
148
+ referenceLines,
149
+ settings,
150
+ surface: {
151
+ ...(existing.surface || {}),
152
+ interactiveLegend: Boolean(options.onVisibleSeriesChange),
153
+ surface: options.surface || "compact",
154
+ },
155
+ title: existing.title || dataset.title || options.title || "Data Analytics chart",
156
+ type,
157
+ unit,
158
+ valueFormat: existing.valueFormat || (percentWordUnit ? "percent" : unit === "$" ? "currency" : "compact"),
159
+ encodings:
160
+ type === "histogram"
161
+ ? {
162
+ x: { field: "x", label: existing.xAxisTitle || "Bucket", type: "ordinal" },
163
+ y: { field: "count", label: "Count", type: "quantitative" },
164
+ }
165
+ : type === "boxPlot"
166
+ ? {
167
+ x: { field: "x", label: existing.xAxisTitle || "Category", type: "ordinal" },
168
+ y: { fields: ["min", "q1", "median", "q3", "max"], label: existing.yAxisTitle || "Distribution", type: "quantitative" },
169
+ }
170
+ : encodings,
171
+ };
172
+ }
173
+
174
+ function positiveNumber(value) {
175
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
176
+ if (typeof value === "string") {
177
+ const parsed = Number(value);
178
+ if (Number.isFinite(parsed) && parsed > 0) return parsed;
179
+ }
180
+ return null;
181
+ }
182
+
183
+ function measuredRect(element) {
184
+ if (!element || typeof element.getBoundingClientRect !== "function") {
185
+ return { height: 0, width: 0 };
186
+ }
187
+ const rect = element.getBoundingClientRect();
188
+ return {
189
+ height: Number.isFinite(rect.height) ? rect.height : 0,
190
+ width: Number.isFinite(rect.width) ? rect.width : 0,
191
+ };
192
+ }
193
+
194
+ function chartDimensionsForMount(mount, options = {}) {
195
+ const surface = options.surface === "explorer" ? "explorer" : "compact";
196
+ const mountRect = measuredRect(mount);
197
+ const containerRect = measuredRect(mount && mount.parentElement);
198
+ const shellRect = measuredRect(mount && mount.parentElement && mount.parentElement.parentElement);
199
+ const width = Math.max(
200
+ MIN_CHART_WIDTH,
201
+ Math.floor(positiveNumber(options.width) || mountRect.width || containerRect.width || shellRect.width || DEFAULT_CHART_WIDTH),
202
+ );
203
+ const fallbackHeight = surface === "explorer" ? DEFAULT_EXPLORER_HEIGHT : DEFAULT_COMPACT_HEIGHT;
204
+ const minHeight = surface === "explorer" ? MIN_EXPLORER_CHART_HEIGHT : MIN_COMPACT_CHART_HEIGHT;
205
+ const measuredHeight = surface === "explorer" ? mountRect.height || containerRect.height || shellRect.height : 0;
206
+ const height = Math.max(
207
+ minHeight,
208
+ Math.floor(positiveNumber(options.height) || measuredHeight || fallbackHeight),
209
+ );
210
+ return { height, width };
211
+ }
212
+
213
+ function MeasuredChartRenderer({
214
+ chart,
215
+ dataset,
216
+ mount,
217
+ options,
218
+ type,
219
+ }) {
220
+ const [dimensions, setDimensions] = React.useState(() => chartDimensionsForMount(mount, options));
221
+
222
+ React.useLayoutEffect(() => {
223
+ let frame = 0;
224
+ const update = () => {
225
+ window.cancelAnimationFrame(frame);
226
+ frame = window.requestAnimationFrame(() => {
227
+ setDimensions((current) => {
228
+ const next = chartDimensionsForMount(mount, options);
229
+ return current.width === next.width && current.height === next.height ? current : next;
230
+ });
231
+ });
232
+ };
233
+
234
+ update();
235
+ const observer = typeof ResizeObserver === "function" ? new ResizeObserver(update) : null;
236
+ if (observer) {
237
+ observer.observe(mount);
238
+ if (mount.parentElement) observer.observe(mount.parentElement);
239
+ if (mount.parentElement && mount.parentElement.parentElement) {
240
+ observer.observe(mount.parentElement.parentElement);
241
+ }
242
+ }
243
+ window.addEventListener("resize", update);
244
+ if (document.fonts && typeof document.fonts.ready?.then === "function") {
245
+ document.fonts.ready.then(update).catch(() => {});
246
+ }
247
+ return () => {
248
+ window.cancelAnimationFrame(frame);
249
+ observer?.disconnect();
250
+ window.removeEventListener("resize", update);
251
+ };
252
+ }, [mount, options.height, options.surface, options.width]);
253
+
254
+ return (
255
+ <ChartRenderer
256
+ chart={chart}
257
+ height={dimensions.height}
258
+ onVisibleSeriesChange={options.onVisibleSeriesChange}
259
+ responsive={false}
260
+ rows={rowsForType(dataset, type)}
261
+ showLegend={true}
262
+ surface={options.surface === "explorer" ? "explorer" : "compact"}
263
+ visibleSeries={options.visibleSeries}
264
+ width={dimensions.width}
265
+ />
266
+ );
267
+ }
268
+
269
+ export function destroyRechartsChart(container) {
270
+ if (!container || !container.__datascienceRechartsRoot) return;
271
+ container.__datascienceRechartsRoot.unmount();
272
+ container.__datascienceRechartsRoot = null;
273
+ }
274
+
275
+ export function renderRechartsChart(container, dataset, type, options = {}) {
276
+ destroyRechartsChart(container);
277
+ const mount = document.createElement("div");
278
+ mount.className = "chart-canvas-wrap recharts-chart-wrap";
279
+ mount.setAttribute("role", "img");
280
+ mount.setAttribute("aria-label", text(dataset.title || options.title || "Data Analytics chart"));
281
+ container.appendChild(mount);
282
+ const root = createRoot(mount);
283
+ const chart = chartSpecForDataset(dataset, type, options);
284
+ container.__datascienceRechartsRoot = root;
285
+ root.render(
286
+ <MeasuredChartRenderer
287
+ chart={chart}
288
+ dataset={dataset}
289
+ mount={mount}
290
+ options={options}
291
+ type={type}
292
+ />,
293
+ );
294
+ }
@@ -0,0 +1,33 @@
1
+ .source-code {
2
+ overflow: auto;
3
+ margin: 0;
4
+ border: 1px solid var(--ds-border-subtle);
5
+ border-radius: var(--ds-radius-panel);
6
+ background: var(--ds-code-container-bg);
7
+ color: var(--ds-text);
8
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
9
+ white-space: pre-wrap;
10
+ word-break: break-word;
11
+ }
12
+
13
+ .code-token {
14
+ color: inherit;
15
+ }
16
+
17
+ .code-keyword {
18
+ color: var(--ds-blue-bright);
19
+ font-weight: 600;
20
+ }
21
+
22
+ .code-string {
23
+ color: var(--positive);
24
+ }
25
+
26
+ .code-number {
27
+ color: var(--stack-secondary);
28
+ }
29
+
30
+ .code-comment {
31
+ color: var(--ds-text-muted);
32
+ font-style: italic;
33
+ }