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,30 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Any
5
+
6
+
7
+ @dataclass
8
+ class Builder:
9
+ chart_mode: str = "image"
10
+ parts: list[str] = field(default_factory=list)
11
+ offset: int = 0
12
+ inline_styles: list[dict[str, Any]] = field(default_factory=list)
13
+ headings: list[dict[str, Any]] = field(default_factory=list)
14
+ blocks: list[dict[str, Any]] = field(default_factory=list)
15
+ lists: list[dict[str, Any]] = field(default_factory=list)
16
+ placeholders: list[dict[str, Any]] = field(default_factory=list)
17
+ tables: list[dict[str, Any]] = field(default_factory=list)
18
+ chart_images: list[dict[str, Any]] = field(default_factory=list)
19
+ two_col_text_blocks: int = 0
20
+ table_counter: int = 0
21
+ chart_counter: int = 0
22
+
23
+ def add(self, text: str) -> tuple[int, int]:
24
+ start = self.offset
25
+ self.parts.append(text)
26
+ self.offset += len(text)
27
+ return start, self.offset
28
+
29
+ def text(self) -> str:
30
+ return "".join(self.parts)
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from .constants import DEFAULT_RENDER_WORKERS, DOC_CONTENT_WIDTH_PT
8
+ from .docx_writer import write_docx
9
+ from .html_parser import parse_html
10
+ from .quality import build_preflight_checks
11
+ from .rendering import render_chart_images
12
+
13
+
14
+ def build_docx_upload_plan(
15
+ manifest: dict[str, Any],
16
+ docx_path: Path,
17
+ preflight: dict[str, Any],
18
+ ) -> dict[str, Any]:
19
+ return {
20
+ "title": manifest["title"],
21
+ "source_html": manifest["source_html"],
22
+ "docx_file": str(docx_path),
23
+ "preflight_status": preflight["status"],
24
+ "doc_content_width_pt": DOC_CONTENT_WIDTH_PT,
25
+ "sequence": [
26
+ {
27
+ "tool": "mcp__codex_apps__google_drive._upload_file",
28
+ "file_uri": str(docx_path),
29
+ "file_name": docx_path.name,
30
+ "mime_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
31
+ }
32
+ ],
33
+ "expected_drive_result": (
34
+ "A Drive-hosted DOCX file is acceptable. The file does not need to be "
35
+ "converted to the native Google Docs MIME type."
36
+ ),
37
+ "verification": [
38
+ "fetch or open the uploaded Drive file and confirm it is readable",
39
+ "compare extracted text against manifest.json headings, lists, source notes, and links",
40
+ "inspect local report.docx structure for expected headings, tables, lists, and image relationships",
41
+ "compare generated chart_images/*.png against the HTML report visuals when visual fidelity matters",
42
+ ],
43
+ }
44
+
45
+
46
+ def write_json(path: Path, obj: Any) -> None:
47
+ path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
48
+
49
+
50
+ def write_docx_upload_readme(
51
+ html: Path,
52
+ manifest: dict[str, Any],
53
+ preflight: dict[str, Any],
54
+ docx_path: Path,
55
+ ) -> str:
56
+ return f"""# Report-to-Google-Doc DOCX Upload Plan
57
+
58
+ Source: `{html}`
59
+
60
+ Local DOCX: `{docx_path}`
61
+
62
+ Inventory:
63
+ - headings: {manifest["counts"]["headings"]}
64
+ - native tables/cards: {manifest["counts"]["tables"]}
65
+ - chart images: {manifest["counts"].get("chart_images", 0)}
66
+ - source two-column blocks: {manifest["counts"].get("two_col_source_blocks", 0)}
67
+ - rendered two-column blocks: {manifest["counts"].get("two_col_image_blocks", 0)}
68
+ - inline style spans: {manifest["counts"]["inline_styles"]}
69
+ - lists: {manifest["counts"]["lists"]}
70
+ - preflight: {preflight["status"]} ({preflight["summary"]["errors"]} errors,
71
+ {preflight["summary"]["warnings"]} warnings)
72
+
73
+ Expected connector sequence:
74
+
75
+ 1. Inspect `preflight_checks.json`. Do not upload until preflight passes.
76
+ 2. Upload `{docx_path}` with `mcp__codex_apps__google_drive._upload_file`.
77
+ 3. Treat the Drive-hosted DOCX as the deliverable; it does not need native
78
+ Google Docs MIME conversion.
79
+ 4. Fetch/open the uploaded file and compare it against `manifest.json` and the
80
+ source HTML report.
81
+
82
+ This helper intentionally writes only DOCX-upload artifacts. It does not write
83
+ Google Docs batch-update request files such as `seed_requests.json`,
84
+ `table_requests.json`, `content_replacement_requests_template.json`,
85
+ `chart_image_requests_template.json`, `remote_write_plan.json`, or
86
+ `all_requests*.json`.
87
+ """
88
+
89
+
90
+ def write_outputs(
91
+ html: Path,
92
+ out_dir: Path,
93
+ chart_mode: str = "image",
94
+ render_workers: int = DEFAULT_RENDER_WORKERS,
95
+ strict_preflight: bool = True,
96
+ ) -> None:
97
+ out_dir.mkdir(parents=True, exist_ok=True)
98
+ manifest = parse_html(html, chart_mode=chart_mode)
99
+ if manifest.get("chart_images"):
100
+ render_chart_images(manifest, out_dir, render_workers=render_workers)
101
+ preflight = build_preflight_checks(
102
+ manifest,
103
+ out_dir,
104
+ )
105
+
106
+ (out_dir / "skeleton.txt").write_text(manifest["skeleton_text"], encoding="utf-8")
107
+ write_json(out_dir / "manifest.json", manifest)
108
+ write_json(out_dir / "preflight_checks.json", preflight)
109
+ write_json(out_dir / "placeholder_queries.json", manifest["placeholders"])
110
+
111
+ docx_path = write_docx(manifest, out_dir)
112
+ docx_upload_plan = build_docx_upload_plan(
113
+ manifest,
114
+ docx_path,
115
+ preflight,
116
+ )
117
+ write_json(out_dir / "docx_upload_plan.json", docx_upload_plan)
118
+ readme = write_docx_upload_readme(
119
+ html,
120
+ manifest,
121
+ preflight,
122
+ docx_path,
123
+ )
124
+ (out_dir / "README.md").write_text(readme, encoding="utf-8")
125
+ if strict_preflight and preflight["status"] != "passed":
126
+ raise SystemExit(
127
+ f"Preflight failed with {preflight['summary']['errors']} error(s). "
128
+ f"Inspect {out_dir / 'preflight_checks.json'}."
129
+ )
@@ -0,0 +1,374 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from .constants import BAR_CHART_HEX_COLORS, DOC_CONTENT_WIDTH_PT, NEUTRAL_SVG_COLORS
8
+ from .table_utils import table_column_widths
9
+
10
+
11
+ def add_preflight_check(
12
+ checks: list[dict[str, Any]],
13
+ *,
14
+ name: str,
15
+ passed: bool,
16
+ severity: str,
17
+ message: str,
18
+ details: dict[str, Any] | None = None,
19
+ ) -> None:
20
+ checks.append(
21
+ {
22
+ "name": name,
23
+ "status": "passed" if passed else "failed",
24
+ "severity": severity,
25
+ "message": message,
26
+ "details": details or {},
27
+ }
28
+ )
29
+
30
+
31
+ def hex_to_rgb_tuple(value: str) -> tuple[int, int, int]:
32
+ raw = value.strip().lstrip("#")
33
+ return (int(raw[0:2], 16), int(raw[2:4], 16), int(raw[4:6], 16))
34
+
35
+
36
+ def is_expected_svg_mark_color(color: str) -> bool:
37
+ normalized = color.lower()
38
+ if normalized in BAR_CHART_HEX_COLORS:
39
+ return True
40
+ if normalized in NEUTRAL_SVG_COLORS:
41
+ return False
42
+ red, green, blue = hex_to_rgb_tuple(normalized)
43
+ return max(red, green, blue) - min(red, green, blue) >= 45 and max(red, green, blue) < 245
44
+
45
+
46
+ def expected_chart_colors(chart: dict[str, Any]) -> list[tuple[int, int, int]]:
47
+ """Return colors that prove the rendered PNG kept the source visual marks.
48
+
49
+ This is intentionally conservative: it checks report-specific bar and
50
+ positive/negative table colors, plus saturated SVG colors, but ignores text,
51
+ gridline, and background colors that would let a broken chart pass.
52
+ """
53
+ kind = chart.get("kind")
54
+ if kind == "bar_chart":
55
+ return [hex_to_rgb_tuple("#1d4ed8" if chart.get("bar_color") == "blue" else "#0f766e")]
56
+ if kind == "two_col_table_grid":
57
+ has_positive = any(
58
+ "positive" in cell_styles
59
+ for panel in chart.get("panels", [])
60
+ for row_styles in panel.get("cell_styles", [])
61
+ for cell_styles in row_styles
62
+ )
63
+ has_negative = any(
64
+ "negative" in cell_styles
65
+ for panel in chart.get("panels", [])
66
+ for row_styles in panel.get("cell_styles", [])
67
+ for cell_styles in row_styles
68
+ )
69
+ colors: list[str] = []
70
+ if has_positive:
71
+ colors.append("#26845f")
72
+ if has_negative:
73
+ colors.append("#c75146")
74
+ return [hex_to_rgb_tuple(color) for color in colors]
75
+ if kind == "svg":
76
+ markup = str(chart.get("svg_markup", "")).lower()
77
+ return [
78
+ hex_to_rgb_tuple(color)
79
+ for color in sorted(set(re.findall(r"#[0-9a-f]{6}", markup)))
80
+ if is_expected_svg_mark_color(color)
81
+ ]
82
+ return []
83
+
84
+
85
+ def image_pixels(image: Any) -> list[tuple[int, int, int]]:
86
+ if hasattr(image, "get_flattened_data"):
87
+ return list(image.get_flattened_data())
88
+ return list(image.getdata())
89
+
90
+
91
+ def count_expected_color_hits(
92
+ image: Any,
93
+ expected_colors: list[tuple[int, int, int]],
94
+ tolerance: int = 40,
95
+ ) -> dict[str, int]:
96
+ if not expected_colors:
97
+ return {}
98
+
99
+ color_hits = {"#%02x%02x%02x" % color: 0 for color in expected_colors}
100
+ color_table = image.getcolors(maxcolors=image.size[0] * image.size[1])
101
+ if color_table is None:
102
+ pixel_iter = (
103
+ image.get_flattened_data() if hasattr(image, "get_flattened_data") else image.getdata()
104
+ )
105
+ color_table = [(1, pixel) for pixel in pixel_iter]
106
+ for count, pixel in color_table:
107
+ for expected in expected_colors:
108
+ if sum(abs(pixel[channel] - expected[channel]) for channel in range(3)) <= tolerance:
109
+ color_hits["#%02x%02x%02x" % expected] += count
110
+ return color_hits
111
+
112
+
113
+ def inspect_image_object(
114
+ image: Any,
115
+ expected_colors: list[tuple[int, int, int]],
116
+ exact_color_scan: bool = False,
117
+ ) -> dict[str, Any]:
118
+ """Return cheap local evidence that a rendered image is usable in Docs."""
119
+ from PIL import Image
120
+
121
+ rgb_image = image.convert("RGB")
122
+ width, height = rgb_image.size
123
+ sample = rgb_image.resize((min(width, 160), min(height, 160)))
124
+ pixels = image_pixels(sample)
125
+ # Full-image color scans are expensive on large chart screenshots. Use
126
+ # exact scans only for rendered table grids, where tiny red/green text is
127
+ # easy to miss after downsampling.
128
+ if exact_color_scan:
129
+ color_image = rgb_image
130
+ else:
131
+ color_image = rgb_image.resize(
132
+ (min(width, 160), min(height, 160)),
133
+ getattr(Image, "Resampling", Image).NEAREST,
134
+ )
135
+ color_hits = count_expected_color_hits(color_image, expected_colors)
136
+
137
+ total = max(1, len(pixels))
138
+ extrema = sample.getextrema()
139
+ uniform = all(channel_min == channel_max for channel_min, channel_max in extrema)
140
+ non_white = sum(1 for r, g, b in pixels if min(r, g, b) < 245)
141
+ non_white_ratio = non_white / total
142
+
143
+ return {
144
+ "width_px": width,
145
+ "height_px": height,
146
+ "uniform": uniform,
147
+ "non_white_ratio": round(non_white_ratio, 4),
148
+ "expected_color_hits": color_hits,
149
+ }
150
+
151
+
152
+ def inspect_png(
153
+ path: Path, expected_colors: list[tuple[int, int, int]], exact_color_scan: bool = False
154
+ ) -> dict[str, Any]:
155
+ try:
156
+ from PIL import Image
157
+ except ImportError as exc: # pragma: no cover - dependency check path
158
+ raise RuntimeError("PNG preflight requires pillow") from exc
159
+
160
+ with Image.open(path) as image:
161
+ return inspect_image_object(image, expected_colors, exact_color_scan=exact_color_scan)
162
+
163
+
164
+ def build_preflight_checks(
165
+ manifest: dict[str, Any],
166
+ out_dir: Path,
167
+ ) -> dict[str, Any]:
168
+ """Build the local quality gate that must pass before Google Docs writes."""
169
+ checks: list[dict[str, Any]] = []
170
+ doc_width = DOC_CONTENT_WIDTH_PT
171
+
172
+ add_preflight_check(
173
+ checks,
174
+ name="source_is_report_html",
175
+ passed=not manifest.get("source_flags", {}).get("auth_page_detected", False),
176
+ severity="error",
177
+ message="Source HTML must be the report, not an auth/login page.",
178
+ )
179
+
180
+ source_two_col = manifest["counts"].get("two_col_source_blocks", 0)
181
+ rendered_two_col = manifest["counts"].get("two_col_image_blocks", 0)
182
+ text_two_col = manifest["counts"].get("two_col_text_blocks", 0)
183
+ add_preflight_check(
184
+ checks,
185
+ name="two_col_blocks_preserved",
186
+ passed=source_two_col == rendered_two_col + text_two_col,
187
+ severity="error",
188
+ message="Every source .two-col block should map to either one rendered multi-column block or preserved native text blocks.",
189
+ details={
190
+ "source_two_col_blocks": source_two_col,
191
+ "rendered_two_col_blocks": rendered_two_col,
192
+ "native_text_two_col_blocks": text_two_col,
193
+ },
194
+ )
195
+
196
+ source_svgs = manifest["counts"].get("svgs", 0)
197
+ rendered_svgs = manifest["counts"].get("svg_image_blocks", 0)
198
+ add_preflight_check(
199
+ checks,
200
+ name="svg_blocks_preserved",
201
+ passed=source_svgs == rendered_svgs,
202
+ severity="error",
203
+ message="Every source SVG visual should map to one rendered DOCX image.",
204
+ details={"source_svgs": source_svgs, "rendered_svg_images": rendered_svgs},
205
+ )
206
+
207
+ source_bars = manifest["counts"].get("bar_source_blocks", 0)
208
+ rendered_bars = manifest["counts"].get("bar_image_blocks", 0)
209
+ table_bars = manifest["counts"].get("bar_table_blocks", 0)
210
+ add_preflight_check(
211
+ checks,
212
+ name="bar_chart_blocks_preserved",
213
+ passed=source_bars == rendered_bars + table_bars,
214
+ severity="error",
215
+ message="Every source bar-chart block should map to one rendered DOCX image or native table fallback.",
216
+ details={
217
+ "source_bar_blocks": source_bars,
218
+ "rendered_bar_images": rendered_bars,
219
+ "native_bar_tables": table_bars,
220
+ },
221
+ )
222
+
223
+ for chart in manifest.get("chart_images", []):
224
+ width = float(chart.get("docs_width_pt", doc_width))
225
+ add_preflight_check(
226
+ checks,
227
+ name=f"{chart['id']}_width_cap",
228
+ passed=width <= doc_width,
229
+ severity="error",
230
+ message="Rendered image width is capped to the report text column.",
231
+ details={"docs_width_pt": width, "doc_width_pt": doc_width},
232
+ )
233
+ if chart.get("kind") == "two_col_table_grid":
234
+ missing_titles = [
235
+ idx
236
+ for idx, panel in enumerate(chart.get("panels", []), start=1)
237
+ if not str(panel.get("title", "")).strip()
238
+ ]
239
+ add_preflight_check(
240
+ checks,
241
+ name=f"{chart['id']}_panel_titles",
242
+ passed=not missing_titles,
243
+ severity="error",
244
+ message="Rendered multi-column table panels preserve visible source titles.",
245
+ details={"missing_title_panel_indices": missing_titles},
246
+ )
247
+
248
+ image_path = out_dir / chart["image_file"]
249
+ add_preflight_check(
250
+ checks,
251
+ name=f"{chart['id']}_png_exists",
252
+ passed=image_path.exists(),
253
+ severity="error",
254
+ message="Every chart placeholder has a rendered local PNG.",
255
+ details={"image_file": chart["image_file"]},
256
+ )
257
+ if image_path.exists():
258
+ try:
259
+ stats = chart.get("render_preflight_stats") or inspect_png(
260
+ image_path,
261
+ expected_chart_colors(chart),
262
+ exact_color_scan=chart.get("kind") == "two_col_table_grid",
263
+ )
264
+ color_hits = stats.get("expected_color_hits", {})
265
+ expected_colors_present = not color_hits or any(
266
+ count > 0 for count in color_hits.values()
267
+ )
268
+ add_preflight_check(
269
+ checks,
270
+ name=f"{chart['id']}_png_not_blank",
271
+ passed=not stats["uniform"] and stats["non_white_ratio"] > 0.002,
272
+ severity="error",
273
+ message="Rendered image is not blank or near-empty.",
274
+ details=stats,
275
+ )
276
+ add_preflight_check(
277
+ checks,
278
+ name=f"{chart['id']}_expected_colors_visible",
279
+ passed=expected_colors_present,
280
+ severity="error",
281
+ message="Expected chart/table colors are visible in the rendered PNG.",
282
+ details=stats,
283
+ )
284
+ except Exception as exc:
285
+ add_preflight_check(
286
+ checks,
287
+ name=f"{chart['id']}_png_inspection",
288
+ passed=False,
289
+ severity="error",
290
+ message=f"Could not inspect rendered PNG: {exc}",
291
+ details={"image_file": chart["image_file"]},
292
+ )
293
+
294
+ table_width_failures: list[dict[str, Any]] = []
295
+ for table in manifest.get("tables", []):
296
+ rows = table.get("rows", [])
297
+ if not rows:
298
+ continue
299
+ widths = table_column_widths(table, len(rows[0]))
300
+ total = round(sum(widths), 1)
301
+ if total > doc_width:
302
+ table_width_failures.append(
303
+ {"id": table["id"], "total_width_pt": total, "column_widths_pt": widths}
304
+ )
305
+ add_preflight_check(
306
+ checks,
307
+ name="native_table_width_cap",
308
+ passed=not table_width_failures,
309
+ severity="error",
310
+ message="Native table column widths do not exceed the report text column.",
311
+ details={"failures": table_width_failures},
312
+ )
313
+
314
+ image_size_failures = []
315
+ for chart in manifest.get("chart_images", []):
316
+ width = chart.get("docs_width_pt")
317
+ height = chart.get("docs_height_pt")
318
+ if width is None or height is None or float(width) > doc_width:
319
+ image_size_failures.append({"id": chart.get("id"), "width": width, "height": height})
320
+ add_preflight_check(
321
+ checks,
322
+ name="docx_images_have_explicit_sizes",
323
+ passed=not image_size_failures,
324
+ severity="error",
325
+ message="DOCX image entries carry explicit text-width object sizes.",
326
+ details={"failures": image_size_failures},
327
+ )
328
+
329
+ chart_count = len(manifest.get("chart_images", []))
330
+ add_preflight_check(
331
+ checks,
332
+ name="docx_image_count_matches_manifest",
333
+ passed=chart_count
334
+ == len(
335
+ [
336
+ chart
337
+ for chart in manifest.get("chart_images", [])
338
+ if chart.get("image_file") and chart.get("docs_width_pt")
339
+ ]
340
+ ),
341
+ severity="error",
342
+ message="Every rendered image has the metadata needed for one DOCX image.",
343
+ details={
344
+ "manifest_chart_images": chart_count,
345
+ "docx_image_entries": len(
346
+ [
347
+ chart
348
+ for chart in manifest.get("chart_images", [])
349
+ if chart.get("image_file") and chart.get("docs_width_pt")
350
+ ]
351
+ ),
352
+ },
353
+ )
354
+
355
+ errors = [
356
+ check for check in checks if check["severity"] == "error" and check["status"] == "failed"
357
+ ]
358
+ warnings = [
359
+ check for check in checks if check["severity"] == "warning" and check["status"] == "failed"
360
+ ]
361
+ return {
362
+ "status": "failed" if errors else "passed",
363
+ "doc_content_width_pt": doc_width,
364
+ "summary": {
365
+ "checks": len(checks),
366
+ "errors": len(errors),
367
+ "warnings": len(warnings),
368
+ "tables": len(manifest.get("tables", [])),
369
+ "chart_images": chart_count,
370
+ },
371
+ "errors": errors,
372
+ "warnings": warnings,
373
+ "checks": checks,
374
+ }