@prismer/runtime 2.2.55 → 2.2.64

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 (563) hide show
  1. package/CHANGELOG.md +574 -0
  2. package/apc/skills/releasing-test/SKILL.md +9 -0
  3. package/built-in-skills/agent-coordination/SKILL.md +21 -4
  4. package/built-in-skills/agent-meta/SKILL.md +11 -0
  5. package/built-in-skills/assets/SKILL.md +1 -1
  6. package/built-in-skills/canvas-design/SKILL.md +3 -3
  7. package/built-in-skills/canvas-design/canvas-fonts/IBMPlexSerif-OFL.txt +93 -0
  8. package/built-in-skills/canvas-design/canvas-fonts/InstrumentSerif-OFL.txt +93 -0
  9. package/built-in-skills/canvas-design/canvas-fonts/LICENSE-SOURCES.md +16 -0
  10. package/built-in-skills/claim-agent-ownership/SKILL.md +7 -3
  11. package/built-in-skills/claude-api/SKILL.md +1 -1
  12. package/built-in-skills/claude-api/python/claude-api/README.md +2 -2
  13. package/built-in-skills/claude-api/python/claude-api/tool-use.md +9 -5
  14. package/built-in-skills/claude-api/python/managed-agents/README.md +11 -1
  15. package/built-in-skills/claude-api/shared/error-codes.md +4 -4
  16. package/built-in-skills/claude-api/shared/managed-agents-client-patterns.md +4 -2
  17. package/built-in-skills/claude-api/shared/managed-agents-core.md +1 -2
  18. package/built-in-skills/claude-api/shared/managed-agents-events.md +41 -22
  19. package/built-in-skills/claude-api/shared/managed-agents-multiagent.md +5 -3
  20. package/built-in-skills/claude-api/shared/managed-agents-self-hosted-sandboxes.md +1 -1
  21. package/built-in-skills/claude-api/shared/managed-agents-tools.md +2 -3
  22. package/built-in-skills/claude-api/shared/model-migration.md +3 -3
  23. package/built-in-skills/claude-api/shared/models.md +1 -1
  24. package/built-in-skills/claude-api/typescript/claude-api/batches.md +1 -1
  25. package/built-in-skills/claude-api/typescript/claude-api/files-api.md +3 -1
  26. package/built-in-skills/claude-api/typescript/claude-api/tool-use.md +8 -2
  27. package/built-in-skills/claude-api/typescript/managed-agents/README.md +8 -2
  28. package/built-in-skills/codebase-design/SKILL.md +15 -1
  29. package/built-in-skills/codebase-design/references/requesting-code-review/GUIDE.md +291 -0
  30. package/built-in-skills/codebase-design/references/requesting-code-review/LICENSE +21 -0
  31. package/built-in-skills/codebase-design/references/requesting-code-review/LICENSE.superpowers +21 -0
  32. package/built-in-skills/codebase-design/references/requesting-code-review/NOTICE.md +37 -0
  33. package/built-in-skills/codebase-design/references/sdlc-review/GUIDE.md +130 -0
  34. package/built-in-skills/codebase-design/references/sdlc-review/LICENSE +21 -0
  35. package/built-in-skills/codebase-design/references/sdlc-review/NOTICE.md +17 -0
  36. package/built-in-skills/codebase-design/references/simplify-code/GUIDE.md +269 -0
  37. package/built-in-skills/codebase-design/references/simplify-code/LICENSE +21 -0
  38. package/built-in-skills/codebase-design/references/simplify-code/NOTICE.md +37 -0
  39. package/built-in-skills/competitor-intelligence/LICENSE +21 -0
  40. package/built-in-skills/competitor-intelligence/NOTICE.md +6 -0
  41. package/built-in-skills/competitor-intelligence/SKILL.md +125 -0
  42. package/built-in-skills/competitor-intelligence/scripts/watch_state.py +160 -0
  43. package/built-in-skills/conversation-compaction/SKILL.md +3 -0
  44. package/built-in-skills/council-creator/SKILL.md +4 -3
  45. package/built-in-skills/diagnosing-bugs/SKILL.md +12 -0
  46. package/built-in-skills/diagnosing-bugs/references/desktop-dom/GUIDE.md +64 -0
  47. package/built-in-skills/diagnosing-bugs/references/desktop-dom/LICENSE +21 -0
  48. package/built-in-skills/diagnosing-bugs/references/desktop-dom/NOTICE.md +17 -0
  49. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/GUIDE.md +410 -0
  50. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/LICENSE +21 -0
  51. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/LICENSE.superpowers +21 -0
  52. package/built-in-skills/diagnosing-bugs/references/systematic-debugging/NOTICE.md +37 -0
  53. package/built-in-skills/doc-coauthoring/SKILL.md +6 -0
  54. package/built-in-skills/doc-coauthoring/references/humanizer/GUIDE.md +647 -0
  55. package/built-in-skills/doc-coauthoring/references/humanizer/LICENSE +21 -0
  56. package/built-in-skills/doc-coauthoring/references/humanizer/LICENSE.hermes +21 -0
  57. package/built-in-skills/doc-coauthoring/references/humanizer/PROVENANCE.md +7 -0
  58. package/built-in-skills/document-actions/LICENSE +21 -0
  59. package/built-in-skills/document-actions/NOTICE.md +21 -0
  60. package/built-in-skills/document-actions/SKILL.md +46 -0
  61. package/built-in-skills/evidence-citations/LICENSE +21 -0
  62. package/built-in-skills/evidence-citations/NOTICE.md +21 -0
  63. package/built-in-skills/evidence-citations/SKILL.md +46 -0
  64. package/built-in-skills/evidence-citations/references/citation-formats.md +68 -0
  65. package/built-in-skills/evidence-citations/references/grounding-rationale.md +64 -0
  66. package/built-in-skills/evidence-citations/scripts/sources.py +720 -0
  67. package/built-in-skills/frontend-design/SKILL.md +6 -0
  68. package/built-in-skills/frontend-design/references/claude-design/GUIDE.md +650 -0
  69. package/built-in-skills/frontend-design/references/claude-design/LICENSE +21 -0
  70. package/built-in-skills/frontend-design/references/claude-design/LICENSE.hermes +21 -0
  71. package/built-in-skills/frontend-design/references/claude-design/PROVENANCE.md +7 -0
  72. package/built-in-skills/image-generate/SKILL.md +5 -0
  73. package/built-in-skills/image-generate/scripts/generate-and-deliver.mjs +24 -3
  74. package/built-in-skills/mcp-builder/reference/evaluation.md +11 -2
  75. package/built-in-skills/mcp-builder/reference/node_mcp_server.md +34 -5
  76. package/built-in-skills/mcp-builder/reference/python_mcp_server.md +6 -2
  77. package/built-in-skills/mcp-builder/scripts/connections.py +1 -1
  78. package/built-in-skills/mcp-builder/scripts/evaluation.py +52 -34
  79. package/built-in-skills/mcp-builder/scripts/requirements.txt +2 -2
  80. package/built-in-skills/meeting-actions/LICENSE +21 -0
  81. package/built-in-skills/meeting-actions/NOTICE.md +21 -0
  82. package/built-in-skills/meeting-actions/SKILL.md +48 -0
  83. package/built-in-skills/memory/SKILL.md +27 -3
  84. package/built-in-skills/memory/references/llm-wiki/GUIDE.md +468 -0
  85. package/built-in-skills/memory/references/llm-wiki/LICENSE +21 -0
  86. package/built-in-skills/memory/references/llm-wiki/NOTICE.md +4 -0
  87. package/built-in-skills/memory/references/llm-wiki/scripts/lint_wiki.py +84 -0
  88. package/built-in-skills/memory/references/llm-wiki/scripts/requirements.txt +1 -0
  89. package/built-in-skills/memory/references/llm-wiki/templates/SCHEMA.md +19 -0
  90. package/built-in-skills/memory/references/llm-wiki/templates/index.md +9 -0
  91. package/built-in-skills/memory/references/llm-wiki/templates/log.md +4 -0
  92. package/built-in-skills/memory-dream/SKILL.md +8 -15
  93. package/built-in-skills/memory-import/SKILL.md +51 -0
  94. package/built-in-skills/office-artifacts/NOTICE.md +15 -0
  95. package/built-in-skills/office-artifacts/SKILL.md +20 -0
  96. package/built-in-skills/office-artifacts/references/RESOURCE-LIMITS.md +44 -0
  97. package/built-in-skills/office-artifacts/references/docx/GUIDE.md +196 -0
  98. package/built-in-skills/office-artifacts/references/docx/LICENSE +21 -0
  99. package/built-in-skills/office-artifacts/references/docx/NOTICE.md +21 -0
  100. package/built-in-skills/office-artifacts/references/docx/references/revisions-and-comments.md +88 -0
  101. package/built-in-skills/office-artifacts/references/docx/scripts/docx_comments.py +292 -0
  102. package/built-in-skills/office-artifacts/references/docx/scripts/docx_common.py +93 -0
  103. package/built-in-skills/office-artifacts/references/docx/scripts/docx_create.py +177 -0
  104. package/built-in-skills/office-artifacts/references/docx/scripts/docx_edit.py +250 -0
  105. package/built-in-skills/office-artifacts/references/docx/scripts/docx_read.py +169 -0
  106. package/built-in-skills/office-artifacts/references/docx/scripts/docx_revisions.py +149 -0
  107. package/built-in-skills/office-artifacts/references/docx/scripts/docx_template.py +70 -0
  108. package/built-in-skills/office-artifacts/references/docx/scripts/docx_validate.py +155 -0
  109. package/built-in-skills/office-artifacts/references/docx/tests/test_docx_skill.py +525 -0
  110. package/built-in-skills/office-artifacts/references/pdf/GUIDE.md +125 -0
  111. package/built-in-skills/office-artifacts/references/pdf/LICENSE +21 -0
  112. package/built-in-skills/office-artifacts/references/pdf/NOTICE.md +21 -0
  113. package/built-in-skills/office-artifacts/references/pdf/references/forms.md +99 -0
  114. package/built-in-skills/office-artifacts/references/pdf/references/nano-pdf-editing.md +40 -0
  115. package/built-in-skills/office-artifacts/references/pdf/references/ocr-extraction.md +165 -0
  116. package/built-in-skills/office-artifacts/references/pdf/scripts/_raster.py +87 -0
  117. package/built-in-skills/office-artifacts/references/pdf/scripts/extract_marker.py +95 -0
  118. package/built-in-skills/office-artifacts/references/pdf/scripts/extract_pymupdf.py +107 -0
  119. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_create.py +153 -0
  120. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_fill_form.py +97 -0
  121. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_form_layout.py +168 -0
  122. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_make_form.py +145 -0
  123. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_merge.py +50 -0
  124. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_meta.py +123 -0
  125. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_page_image.py +101 -0
  126. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_read.py +153 -0
  127. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_secure.py +71 -0
  128. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_split.py +86 -0
  129. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_stamp.py +145 -0
  130. package/built-in-skills/office-artifacts/references/pdf/scripts/pdf_watermark.py +51 -0
  131. package/built-in-skills/office-artifacts/references/pdf/tests/test_pdf_skill.py +414 -0
  132. package/built-in-skills/office-artifacts/references/powerpoint/GUIDE.md +220 -0
  133. package/built-in-skills/office-artifacts/references/powerpoint/LICENSE +21 -0
  134. package/built-in-skills/office-artifacts/references/powerpoint/NOTICE.md +21 -0
  135. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_create.py +214 -0
  136. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_edit.py +442 -0
  137. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_from_template.py +88 -0
  138. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_read.py +131 -0
  139. package/built-in-skills/office-artifacts/references/powerpoint/scripts/pptx_render.py +104 -0
  140. package/built-in-skills/office-artifacts/references/powerpoint/tests/test_powerpoint_skill.py +478 -0
  141. package/built-in-skills/office-artifacts/references/xlsx/GUIDE.md +196 -0
  142. package/built-in-skills/office-artifacts/references/xlsx/LICENSE +21 -0
  143. package/built-in-skills/office-artifacts/references/xlsx/NOTICE.md +21 -0
  144. package/built-in-skills/office-artifacts/references/xlsx/references/restructuring.md +74 -0
  145. package/built-in-skills/office-artifacts/references/xlsx/scripts/csv_to_xlsx.py +108 -0
  146. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_create.py +259 -0
  147. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_edit.py +269 -0
  148. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_read.py +160 -0
  149. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_recalc.py +111 -0
  150. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_restructure.py +418 -0
  151. package/built-in-skills/office-artifacts/references/xlsx/scripts/xlsx_to_csv.py +69 -0
  152. package/built-in-skills/office-artifacts/references/xlsx/tests/test_xlsx_skill.py +542 -0
  153. package/built-in-skills/office-artifacts/tests/test_resource_regressions.py +272 -0
  154. package/built-in-skills/persona-generator/SKILL.md +9 -9
  155. package/built-in-skills/pkf-svg/SKILL.md +5 -0
  156. package/built-in-skills/pkf-svg/references/architecture-diagram/GUIDE.md +148 -0
  157. package/built-in-skills/pkf-svg/references/architecture-diagram/LICENSE +21 -0
  158. package/built-in-skills/pkf-svg/references/architecture-diagram/LICENSE.hermes +21 -0
  159. package/built-in-skills/pkf-svg/references/architecture-diagram/PROVENANCE.md +7 -0
  160. package/built-in-skills/pkf-svg/references/architecture-diagram/templates/template.html +345 -0
  161. package/built-in-skills/pkf-writing/SKILL.md +36 -14
  162. package/built-in-skills/prismer-airtable/LICENSE +21 -0
  163. package/built-in-skills/prismer-airtable/NOTICE.md +11 -0
  164. package/built-in-skills/prismer-airtable/SKILL.md +248 -0
  165. package/built-in-skills/prismer-airtable/scripts/airtable_client.py +76 -0
  166. package/built-in-skills/prismer-apple-notes/LICENSE +21 -0
  167. package/built-in-skills/prismer-apple-notes/NOTICE.md +17 -0
  168. package/built-in-skills/prismer-apple-notes/SKILL.md +118 -0
  169. package/built-in-skills/prismer-apple-notes/scripts/readiness.py +47 -0
  170. package/built-in-skills/prismer-apple-reminders/LICENSE +21 -0
  171. package/built-in-skills/prismer-apple-reminders/NOTICE.md +17 -0
  172. package/built-in-skills/prismer-apple-reminders/SKILL.md +155 -0
  173. package/built-in-skills/prismer-apple-reminders/scripts/readiness.py +47 -0
  174. package/built-in-skills/prismer-ascii-video/LICENSE +21 -0
  175. package/built-in-skills/prismer-ascii-video/LICENSE.hermes +21 -0
  176. package/built-in-skills/prismer-ascii-video/PROVENANCE.md +7 -0
  177. package/built-in-skills/prismer-ascii-video/README.md +290 -0
  178. package/built-in-skills/prismer-ascii-video/SKILL.md +252 -0
  179. package/built-in-skills/prismer-ascii-video/provenance/category-DESCRIPTION.md +3 -0
  180. package/built-in-skills/prismer-ascii-video/references/architecture.md +807 -0
  181. package/built-in-skills/prismer-ascii-video/references/composition.md +900 -0
  182. package/built-in-skills/prismer-ascii-video/references/effects.md +1877 -0
  183. package/built-in-skills/prismer-ascii-video/references/inputs.md +693 -0
  184. package/built-in-skills/prismer-ascii-video/references/optimization.md +688 -0
  185. package/built-in-skills/prismer-ascii-video/references/scenes.md +1018 -0
  186. package/built-in-skills/prismer-ascii-video/references/shaders.md +1408 -0
  187. package/built-in-skills/prismer-ascii-video/references/troubleshooting.md +360 -0
  188. package/built-in-skills/prismer-baoyu-infographic/LICENSE +21 -0
  189. package/built-in-skills/prismer-baoyu-infographic/LICENSE.hermes +21 -0
  190. package/built-in-skills/prismer-baoyu-infographic/LICENSE.origin +21 -0
  191. package/built-in-skills/prismer-baoyu-infographic/PORT_NOTES.md +37 -0
  192. package/built-in-skills/prismer-baoyu-infographic/PROVENANCE.md +7 -0
  193. package/built-in-skills/prismer-baoyu-infographic/SKILL.md +240 -0
  194. package/built-in-skills/prismer-baoyu-infographic/references/analysis-framework.md +182 -0
  195. package/built-in-skills/prismer-baoyu-infographic/references/base-prompt.md +43 -0
  196. package/built-in-skills/prismer-baoyu-infographic/references/layouts/bento-grid.md +41 -0
  197. package/built-in-skills/prismer-baoyu-infographic/references/layouts/binary-comparison.md +48 -0
  198. package/built-in-skills/prismer-baoyu-infographic/references/layouts/bridge.md +41 -0
  199. package/built-in-skills/prismer-baoyu-infographic/references/layouts/circular-flow.md +41 -0
  200. package/built-in-skills/prismer-baoyu-infographic/references/layouts/comic-strip.md +41 -0
  201. package/built-in-skills/prismer-baoyu-infographic/references/layouts/comparison-matrix.md +41 -0
  202. package/built-in-skills/prismer-baoyu-infographic/references/layouts/dashboard.md +41 -0
  203. package/built-in-skills/prismer-baoyu-infographic/references/layouts/dense-modules.md +72 -0
  204. package/built-in-skills/prismer-baoyu-infographic/references/layouts/funnel.md +41 -0
  205. package/built-in-skills/prismer-baoyu-infographic/references/layouts/hierarchical-layers.md +48 -0
  206. package/built-in-skills/prismer-baoyu-infographic/references/layouts/hub-spoke.md +41 -0
  207. package/built-in-skills/prismer-baoyu-infographic/references/layouts/iceberg.md +41 -0
  208. package/built-in-skills/prismer-baoyu-infographic/references/layouts/isometric-map.md +41 -0
  209. package/built-in-skills/prismer-baoyu-infographic/references/layouts/jigsaw.md +41 -0
  210. package/built-in-skills/prismer-baoyu-infographic/references/layouts/linear-progression.md +48 -0
  211. package/built-in-skills/prismer-baoyu-infographic/references/layouts/periodic-table.md +41 -0
  212. package/built-in-skills/prismer-baoyu-infographic/references/layouts/story-mountain.md +41 -0
  213. package/built-in-skills/prismer-baoyu-infographic/references/layouts/structural-breakdown.md +48 -0
  214. package/built-in-skills/prismer-baoyu-infographic/references/layouts/tree-branching.md +41 -0
  215. package/built-in-skills/prismer-baoyu-infographic/references/layouts/venn-diagram.md +41 -0
  216. package/built-in-skills/prismer-baoyu-infographic/references/layouts/winding-roadmap.md +41 -0
  217. package/built-in-skills/prismer-baoyu-infographic/references/structured-content-template.md +244 -0
  218. package/built-in-skills/prismer-baoyu-infographic/references/styles/aged-academia.md +36 -0
  219. package/built-in-skills/prismer-baoyu-infographic/references/styles/bold-graphic.md +36 -0
  220. package/built-in-skills/prismer-baoyu-infographic/references/styles/chalkboard.md +61 -0
  221. package/built-in-skills/prismer-baoyu-infographic/references/styles/claymation.md +29 -0
  222. package/built-in-skills/prismer-baoyu-infographic/references/styles/corporate-memphis.md +29 -0
  223. package/built-in-skills/prismer-baoyu-infographic/references/styles/craft-handmade.md +44 -0
  224. package/built-in-skills/prismer-baoyu-infographic/references/styles/cyberpunk-neon.md +29 -0
  225. package/built-in-skills/prismer-baoyu-infographic/references/styles/hand-drawn-edu.md +63 -0
  226. package/built-in-skills/prismer-baoyu-infographic/references/styles/ikea-manual.md +29 -0
  227. package/built-in-skills/prismer-baoyu-infographic/references/styles/kawaii.md +29 -0
  228. package/built-in-skills/prismer-baoyu-infographic/references/styles/knolling.md +29 -0
  229. package/built-in-skills/prismer-baoyu-infographic/references/styles/lego-brick.md +29 -0
  230. package/built-in-skills/prismer-baoyu-infographic/references/styles/morandi-journal.md +60 -0
  231. package/built-in-skills/prismer-baoyu-infographic/references/styles/origami.md +29 -0
  232. package/built-in-skills/prismer-baoyu-infographic/references/styles/pixel-art.md +29 -0
  233. package/built-in-skills/prismer-baoyu-infographic/references/styles/pop-laboratory.md +48 -0
  234. package/built-in-skills/prismer-baoyu-infographic/references/styles/retro-pop-grid.md +47 -0
  235. package/built-in-skills/prismer-baoyu-infographic/references/styles/storybook-watercolor.md +29 -0
  236. package/built-in-skills/prismer-baoyu-infographic/references/styles/subway-map.md +29 -0
  237. package/built-in-skills/prismer-baoyu-infographic/references/styles/technical-schematic.md +36 -0
  238. package/built-in-skills/prismer-baoyu-infographic/references/styles/ui-wireframe.md +29 -0
  239. package/built-in-skills/prismer-blocked-page-recovery/LICENSE +21 -0
  240. package/built-in-skills/prismer-blocked-page-recovery/NOTICE.md +17 -0
  241. package/built-in-skills/prismer-blocked-page-recovery/SKILL.md +158 -0
  242. package/built-in-skills/prismer-blocked-page-recovery/scripts/recover_page.py +311 -0
  243. package/built-in-skills/prismer-box/LICENSE +21 -0
  244. package/built-in-skills/prismer-box/NOTICE.md +11 -0
  245. package/built-in-skills/prismer-box/SKILL.md +147 -0
  246. package/built-in-skills/prismer-box/references/bulk-operations.md +43 -0
  247. package/built-in-skills/prismer-box/references/cli-guide.md +133 -0
  248. package/built-in-skills/prismer-box/references/content-workflows.md +86 -0
  249. package/built-in-skills/prismer-box/references/hubs.md +77 -0
  250. package/built-in-skills/prismer-box/references/oauth-setup.md +92 -0
  251. package/built-in-skills/prismer-box/references/rest-api.md +37 -0
  252. package/built-in-skills/prismer-box/references/sdk-development.md +85 -0
  253. package/built-in-skills/prismer-box/references/search-and-ai.md +147 -0
  254. package/built-in-skills/prismer-box/references/troubleshooting.md +33 -0
  255. package/built-in-skills/prismer-box/references/webhooks-and-events.md +43 -0
  256. package/built-in-skills/prismer-codebase-inspection/LICENSE +21 -0
  257. package/built-in-skills/prismer-codebase-inspection/NOTICE.md +17 -0
  258. package/built-in-skills/prismer-codebase-inspection/SKILL.md +141 -0
  259. package/built-in-skills/prismer-computer-use/LICENSE +21 -0
  260. package/built-in-skills/prismer-computer-use/NOTICE.md +17 -0
  261. package/built-in-skills/prismer-computer-use/SKILL.md +372 -0
  262. package/built-in-skills/prismer-design-md/LICENSE +21 -0
  263. package/built-in-skills/prismer-design-md/LICENSE.hermes +21 -0
  264. package/built-in-skills/prismer-design-md/PROVENANCE.md +7 -0
  265. package/built-in-skills/prismer-design-md/SKILL.md +227 -0
  266. package/built-in-skills/prismer-design-md/templates/starter.md +99 -0
  267. package/built-in-skills/prismer-email-inbox-triage/LICENSE +21 -0
  268. package/built-in-skills/prismer-email-inbox-triage/NOTICE.md +11 -0
  269. package/built-in-skills/prismer-email-inbox-triage/SKILL.md +116 -0
  270. package/built-in-skills/prismer-findmy/LICENSE +21 -0
  271. package/built-in-skills/prismer-findmy/NOTICE.md +17 -0
  272. package/built-in-skills/prismer-findmy/SKILL.md +150 -0
  273. package/built-in-skills/prismer-findmy/scripts/readiness.py +47 -0
  274. package/built-in-skills/prismer-gif-search/LICENSE +21 -0
  275. package/built-in-skills/prismer-gif-search/LICENSE.hermes +21 -0
  276. package/built-in-skills/prismer-gif-search/PROVENANCE.md +7 -0
  277. package/built-in-skills/prismer-gif-search/SKILL.md +97 -0
  278. package/built-in-skills/prismer-gif-search/scripts/tenor.py +81 -0
  279. package/built-in-skills/prismer-github/LICENSE +21 -0
  280. package/built-in-skills/prismer-github/NOTICE.md +17 -0
  281. package/built-in-skills/prismer-github/SKILL.md +74 -0
  282. package/built-in-skills/prismer-github/references/auth.md +91 -0
  283. package/built-in-skills/prismer-github/references/ci-troubleshooting.md +193 -0
  284. package/built-in-skills/prismer-github/references/code-review.md +465 -0
  285. package/built-in-skills/prismer-github/references/conventional-commits.md +81 -0
  286. package/built-in-skills/prismer-github/references/github-api-cheatsheet.md +177 -0
  287. package/built-in-skills/prismer-github/references/issue-to-pr.md +74 -0
  288. package/built-in-skills/prismer-github/references/issues.md +336 -0
  289. package/built-in-skills/prismer-github/references/pr-workflow.md +346 -0
  290. package/built-in-skills/prismer-github/references/repo-management.md +484 -0
  291. package/built-in-skills/prismer-github/references/review-output-template.md +84 -0
  292. package/built-in-skills/prismer-github/scripts/ensure-gh.py +132 -0
  293. package/built-in-skills/prismer-github/scripts/gh-env.sh +25 -0
  294. package/built-in-skills/prismer-github/scripts/git-credential-token.py +68 -0
  295. package/built-in-skills/prismer-github/scripts/github-api.py +71 -0
  296. package/built-in-skills/prismer-github/scripts/github-context.py +28 -0
  297. package/built-in-skills/prismer-github/templates/bug-report.md +35 -0
  298. package/built-in-skills/prismer-github/templates/feature-request.md +31 -0
  299. package/built-in-skills/prismer-github/templates/pr-body-bugfix.md +35 -0
  300. package/built-in-skills/prismer-github/templates/pr-body-feature.md +33 -0
  301. package/built-in-skills/prismer-google-workspace/LICENSE +21 -0
  302. package/built-in-skills/prismer-google-workspace/NOTICE.md +11 -0
  303. package/built-in-skills/prismer-google-workspace/SKILL.md +369 -0
  304. package/built-in-skills/prismer-google-workspace/references/daily-brief.md +65 -0
  305. package/built-in-skills/prismer-google-workspace/references/gmail-search-syntax.md +63 -0
  306. package/built-in-skills/prismer-google-workspace/scripts/_hermes_home.py +17 -0
  307. package/built-in-skills/prismer-google-workspace/scripts/_private_state.py +39 -0
  308. package/built-in-skills/prismer-google-workspace/scripts/google_api.py +1339 -0
  309. package/built-in-skills/prismer-google-workspace/scripts/gws_bridge.py +121 -0
  310. package/built-in-skills/prismer-google-workspace/scripts/setup.py +563 -0
  311. package/built-in-skills/prismer-google-workspace/tests/test_productivity_regressions.py +214 -0
  312. package/built-in-skills/prismer-hermes-agent/LICENSE +21 -0
  313. package/built-in-skills/prismer-hermes-agent/NOTICE.md +17 -0
  314. package/built-in-skills/prismer-hermes-agent/SKILL.md +247 -0
  315. package/built-in-skills/prismer-hermes-agent/references/background-systems.md +108 -0
  316. package/built-in-skills/prismer-hermes-agent/references/cli-reference.md +158 -0
  317. package/built-in-skills/prismer-hermes-agent/references/configuration.md +96 -0
  318. package/built-in-skills/prismer-hermes-agent/references/contributor-guide.md +151 -0
  319. package/built-in-skills/prismer-hermes-agent/references/delegate-task-concurrency-diagnosis.md +47 -0
  320. package/built-in-skills/prismer-hermes-agent/references/desktop-plugins.md +215 -0
  321. package/built-in-skills/prismer-hermes-agent/references/native-mcp.md +351 -0
  322. package/built-in-skills/prismer-hermes-agent/references/petdex.md +82 -0
  323. package/built-in-skills/prismer-hermes-agent/references/portal-auth-for-third-party-apps.md +135 -0
  324. package/built-in-skills/prismer-hermes-agent/references/project-context-files.md +55 -0
  325. package/built-in-skills/prismer-hermes-agent/references/providers-and-models.md +81 -0
  326. package/built-in-skills/prismer-hermes-agent/references/security-privacy.md +73 -0
  327. package/built-in-skills/prismer-hermes-agent/references/slash-commands.md +119 -0
  328. package/built-in-skills/prismer-hermes-agent/references/themes.md +134 -0
  329. package/built-in-skills/prismer-hermes-agent/references/troubleshooting.md +87 -0
  330. package/built-in-skills/prismer-hermes-agent/references/tui-widgets.md +144 -0
  331. package/built-in-skills/prismer-hermes-agent/references/webhooks.md +219 -0
  332. package/built-in-skills/prismer-hermes-agent/references/windows-quirks.md +64 -0
  333. package/built-in-skills/prismer-hermes-agent/templates/clock.mjs +51 -0
  334. package/built-in-skills/prismer-hermes-agent/templates/plugin.js +97 -0
  335. package/built-in-skills/prismer-hermes-agent/templates/skin.yaml +49 -0
  336. package/built-in-skills/prismer-himalaya/LICENSE +21 -0
  337. package/built-in-skills/prismer-himalaya/NOTICE.md +11 -0
  338. package/built-in-skills/prismer-himalaya/SKILL.md +340 -0
  339. package/built-in-skills/prismer-himalaya/references/configuration.md +227 -0
  340. package/built-in-skills/prismer-himalaya/references/message-composition.md +206 -0
  341. package/built-in-skills/prismer-himalaya/scripts/compose_draft.py +48 -0
  342. package/built-in-skills/prismer-im-collab/SKILL.md +1 -1
  343. package/built-in-skills/prismer-imessage/LICENSE +21 -0
  344. package/built-in-skills/prismer-imessage/NOTICE.md +17 -0
  345. package/built-in-skills/prismer-imessage/SKILL.md +128 -0
  346. package/built-in-skills/prismer-imessage/scripts/readiness.py +47 -0
  347. package/built-in-skills/prismer-manim-video/LICENSE +21 -0
  348. package/built-in-skills/prismer-manim-video/LICENSE.hermes +21 -0
  349. package/built-in-skills/prismer-manim-video/PROVENANCE.md +7 -0
  350. package/built-in-skills/prismer-manim-video/README.md +23 -0
  351. package/built-in-skills/prismer-manim-video/SKILL.md +279 -0
  352. package/built-in-skills/prismer-manim-video/references/animation-design-thinking.md +161 -0
  353. package/built-in-skills/prismer-manim-video/references/animations.md +282 -0
  354. package/built-in-skills/prismer-manim-video/references/camera-and-3d.md +135 -0
  355. package/built-in-skills/prismer-manim-video/references/decorations.md +202 -0
  356. package/built-in-skills/prismer-manim-video/references/equations.md +216 -0
  357. package/built-in-skills/prismer-manim-video/references/graphs-and-data.md +163 -0
  358. package/built-in-skills/prismer-manim-video/references/mobjects.md +333 -0
  359. package/built-in-skills/prismer-manim-video/references/paper-explainer.md +255 -0
  360. package/built-in-skills/prismer-manim-video/references/production-quality.md +190 -0
  361. package/built-in-skills/prismer-manim-video/references/rendering.md +187 -0
  362. package/built-in-skills/prismer-manim-video/references/scene-planning.md +118 -0
  363. package/built-in-skills/prismer-manim-video/references/troubleshooting.md +135 -0
  364. package/built-in-skills/prismer-manim-video/references/updaters-and-trackers.md +260 -0
  365. package/built-in-skills/prismer-manim-video/references/visual-design.md +124 -0
  366. package/built-in-skills/prismer-manim-video/scripts/setup.sh +15 -0
  367. package/built-in-skills/prismer-maps/LICENSE +21 -0
  368. package/built-in-skills/prismer-maps/NOTICE.md +11 -0
  369. package/built-in-skills/prismer-maps/SKILL.md +240 -0
  370. package/built-in-skills/prismer-maps/scripts/maps_client.py +1324 -0
  371. package/built-in-skills/prismer-node-inspect-debugger/LICENSE +21 -0
  372. package/built-in-skills/prismer-node-inspect-debugger/NOTICE.md +17 -0
  373. package/built-in-skills/prismer-node-inspect-debugger/SKILL.md +347 -0
  374. package/built-in-skills/prismer-notion/LICENSE +21 -0
  375. package/built-in-skills/prismer-notion/NOTICE.md +11 -0
  376. package/built-in-skills/prismer-notion/SKILL.md +495 -0
  377. package/built-in-skills/prismer-notion/references/block-types.md +112 -0
  378. package/built-in-skills/prismer-obsidian/LICENSE +21 -0
  379. package/built-in-skills/prismer-obsidian/LICENSE.hermes +21 -0
  380. package/built-in-skills/prismer-obsidian/PROVENANCE.md +7 -0
  381. package/built-in-skills/prismer-obsidian/SKILL.md +80 -0
  382. package/built-in-skills/prismer-obsidian/provenance/category-DESCRIPTION.md +3 -0
  383. package/built-in-skills/prismer-obsidian/scripts/write_note.py +84 -0
  384. package/built-in-skills/prismer-p5js/LICENSE +21 -0
  385. package/built-in-skills/prismer-p5js/LICENSE.hermes +21 -0
  386. package/built-in-skills/prismer-p5js/PROVENANCE.md +7 -0
  387. package/built-in-skills/prismer-p5js/README.md +64 -0
  388. package/built-in-skills/prismer-p5js/SKILL.md +574 -0
  389. package/built-in-skills/prismer-p5js/references/animation.md +439 -0
  390. package/built-in-skills/prismer-p5js/references/color-systems.md +355 -0
  391. package/built-in-skills/prismer-p5js/references/core-api.md +410 -0
  392. package/built-in-skills/prismer-p5js/references/export-pipeline.md +534 -0
  393. package/built-in-skills/prismer-p5js/references/interaction.md +398 -0
  394. package/built-in-skills/prismer-p5js/references/shapes-and-geometry.md +300 -0
  395. package/built-in-skills/prismer-p5js/references/troubleshooting.md +532 -0
  396. package/built-in-skills/prismer-p5js/references/typography.md +302 -0
  397. package/built-in-skills/prismer-p5js/references/visual-effects.md +905 -0
  398. package/built-in-skills/prismer-p5js/references/webgl-and-3d.md +423 -0
  399. package/built-in-skills/prismer-p5js/scripts/export-frames.js +91 -0
  400. package/built-in-skills/prismer-p5js/scripts/render.sh +113 -0
  401. package/built-in-skills/prismer-p5js/scripts/serve.sh +25 -0
  402. package/built-in-skills/prismer-p5js/scripts/setup.sh +87 -0
  403. package/built-in-skills/prismer-p5js/templates/viewer.html +401 -0
  404. package/built-in-skills/prismer-popular-web-designs/LICENSE +21 -0
  405. package/built-in-skills/prismer-popular-web-designs/LICENSE.hermes +21 -0
  406. package/built-in-skills/prismer-popular-web-designs/LICENSE.origin +21 -0
  407. package/built-in-skills/prismer-popular-web-designs/PROVENANCE.md +7 -0
  408. package/built-in-skills/prismer-popular-web-designs/SKILL.md +218 -0
  409. package/built-in-skills/prismer-popular-web-designs/templates/airbnb.md +259 -0
  410. package/built-in-skills/prismer-popular-web-designs/templates/airtable.md +102 -0
  411. package/built-in-skills/prismer-popular-web-designs/templates/apple.md +326 -0
  412. package/built-in-skills/prismer-popular-web-designs/templates/bmw.md +193 -0
  413. package/built-in-skills/prismer-popular-web-designs/templates/cal.md +272 -0
  414. package/built-in-skills/prismer-popular-web-designs/templates/claude.md +325 -0
  415. package/built-in-skills/prismer-popular-web-designs/templates/clay.md +317 -0
  416. package/built-in-skills/prismer-popular-web-designs/templates/clickhouse.md +294 -0
  417. package/built-in-skills/prismer-popular-web-designs/templates/cohere.md +279 -0
  418. package/built-in-skills/prismer-popular-web-designs/templates/coinbase.md +142 -0
  419. package/built-in-skills/prismer-popular-web-designs/templates/composio.md +320 -0
  420. package/built-in-skills/prismer-popular-web-designs/templates/cursor.md +322 -0
  421. package/built-in-skills/prismer-popular-web-designs/templates/elevenlabs.md +278 -0
  422. package/built-in-skills/prismer-popular-web-designs/templates/expo.md +294 -0
  423. package/built-in-skills/prismer-popular-web-designs/templates/figma.md +233 -0
  424. package/built-in-skills/prismer-popular-web-designs/templates/framer.md +259 -0
  425. package/built-in-skills/prismer-popular-web-designs/templates/hashicorp.md +291 -0
  426. package/built-in-skills/prismer-popular-web-designs/templates/ibm.md +345 -0
  427. package/built-in-skills/prismer-popular-web-designs/templates/intercom.md +159 -0
  428. package/built-in-skills/prismer-popular-web-designs/templates/kraken.md +138 -0
  429. package/built-in-skills/prismer-popular-web-designs/templates/linear.app.md +380 -0
  430. package/built-in-skills/prismer-popular-web-designs/templates/lovable.md +311 -0
  431. package/built-in-skills/prismer-popular-web-designs/templates/minimax.md +270 -0
  432. package/built-in-skills/prismer-popular-web-designs/templates/mintlify.md +339 -0
  433. package/built-in-skills/prismer-popular-web-designs/templates/miro.md +121 -0
  434. package/built-in-skills/prismer-popular-web-designs/templates/mistral.ai.md +274 -0
  435. package/built-in-skills/prismer-popular-web-designs/templates/mongodb.md +279 -0
  436. package/built-in-skills/prismer-popular-web-designs/templates/notion.md +322 -0
  437. package/built-in-skills/prismer-popular-web-designs/templates/nvidia.md +306 -0
  438. package/built-in-skills/prismer-popular-web-designs/templates/ollama.md +280 -0
  439. package/built-in-skills/prismer-popular-web-designs/templates/opencode.ai.md +294 -0
  440. package/built-in-skills/prismer-popular-web-designs/templates/pinterest.md +243 -0
  441. package/built-in-skills/prismer-popular-web-designs/templates/posthog.md +269 -0
  442. package/built-in-skills/prismer-popular-web-designs/templates/raycast.md +281 -0
  443. package/built-in-skills/prismer-popular-web-designs/templates/replicate.md +274 -0
  444. package/built-in-skills/prismer-popular-web-designs/templates/resend.md +316 -0
  445. package/built-in-skills/prismer-popular-web-designs/templates/revolut.md +198 -0
  446. package/built-in-skills/prismer-popular-web-designs/templates/runwayml.md +257 -0
  447. package/built-in-skills/prismer-popular-web-designs/templates/sanity.md +370 -0
  448. package/built-in-skills/prismer-popular-web-designs/templates/sentry.md +275 -0
  449. package/built-in-skills/prismer-popular-web-designs/templates/spacex.md +207 -0
  450. package/built-in-skills/prismer-popular-web-designs/templates/spotify.md +259 -0
  451. package/built-in-skills/prismer-popular-web-designs/templates/stripe.md +335 -0
  452. package/built-in-skills/prismer-popular-web-designs/templates/supabase.md +268 -0
  453. package/built-in-skills/prismer-popular-web-designs/templates/superhuman.md +265 -0
  454. package/built-in-skills/prismer-popular-web-designs/templates/together.ai.md +276 -0
  455. package/built-in-skills/prismer-popular-web-designs/templates/uber.md +308 -0
  456. package/built-in-skills/prismer-popular-web-designs/templates/vercel.md +323 -0
  457. package/built-in-skills/prismer-popular-web-designs/templates/voltagent.md +336 -0
  458. package/built-in-skills/prismer-popular-web-designs/templates/warp.md +266 -0
  459. package/built-in-skills/prismer-popular-web-designs/templates/webflow.md +105 -0
  460. package/built-in-skills/prismer-popular-web-designs/templates/wise.md +186 -0
  461. package/built-in-skills/prismer-popular-web-designs/templates/x.ai.md +270 -0
  462. package/built-in-skills/prismer-popular-web-designs/templates/zapier.md +341 -0
  463. package/built-in-skills/prismer-product-price-monitor/LICENSE +21 -0
  464. package/built-in-skills/prismer-product-price-monitor/NOTICE.md +11 -0
  465. package/built-in-skills/prismer-product-price-monitor/SKILL.md +97 -0
  466. package/built-in-skills/prismer-product-price-monitor/scripts/watch_state.py +116 -0
  467. package/built-in-skills/prismer-python-debugpy/LICENSE +21 -0
  468. package/built-in-skills/prismer-python-debugpy/NOTICE.md +17 -0
  469. package/built-in-skills/prismer-python-debugpy/SKILL.md +377 -0
  470. package/built-in-skills/prismer-python-debugpy/scripts/dap_client.py +68 -0
  471. package/built-in-skills/prismer-songsee/LICENSE +21 -0
  472. package/built-in-skills/prismer-songsee/LICENSE.hermes +21 -0
  473. package/built-in-skills/prismer-songsee/PROVENANCE.md +7 -0
  474. package/built-in-skills/prismer-songsee/SKILL.md +91 -0
  475. package/built-in-skills/prismer-songwriting-and-ai-music/LICENSE +21 -0
  476. package/built-in-skills/prismer-songwriting-and-ai-music/LICENSE.hermes +21 -0
  477. package/built-in-skills/prismer-songwriting-and-ai-music/PROVENANCE.md +7 -0
  478. package/built-in-skills/prismer-songwriting-and-ai-music/SKILL.md +317 -0
  479. package/built-in-skills/prismer-spike/LICENSE +21 -0
  480. package/built-in-skills/prismer-spike/LICENSE.gsd +21 -0
  481. package/built-in-skills/prismer-spike/NOTICE.md +17 -0
  482. package/built-in-skills/prismer-spike/SKILL.md +212 -0
  483. package/built-in-skills/prismer-teams-meeting-pipeline/LICENSE +21 -0
  484. package/built-in-skills/prismer-teams-meeting-pipeline/NOTICE.md +11 -0
  485. package/built-in-skills/prismer-teams-meeting-pipeline/SKILL.md +156 -0
  486. package/built-in-skills/prismer-xurl/LICENSE +21 -0
  487. package/built-in-skills/prismer-xurl/LICENSE.hermes +21 -0
  488. package/built-in-skills/prismer-xurl/PROVENANCE.md +7 -0
  489. package/built-in-skills/prismer-xurl/SKILL.md +444 -0
  490. package/built-in-skills/prismer-xurl/provenance/category-DESCRIPTION.md +3 -0
  491. package/built-in-skills/prismer-youtube-content/LICENSE +21 -0
  492. package/built-in-skills/prismer-youtube-content/LICENSE.hermes +21 -0
  493. package/built-in-skills/prismer-youtube-content/PROVENANCE.md +7 -0
  494. package/built-in-skills/prismer-youtube-content/SKILL.md +86 -0
  495. package/built-in-skills/prismer-youtube-content/provenance/category-DESCRIPTION.md +3 -0
  496. package/built-in-skills/prismer-youtube-content/references/output-formats.md +56 -0
  497. package/built-in-skills/prismer-youtube-content/scripts/fetch_transcript.py +146 -0
  498. package/built-in-skills/research-arxiv/LICENSE +21 -0
  499. package/built-in-skills/research-arxiv/NOTICE.md +4 -0
  500. package/built-in-skills/research-arxiv/SKILL.md +263 -0
  501. package/built-in-skills/research-arxiv/scripts/search_arxiv.py +111 -0
  502. package/built-in-skills/role-builder/SKILL.md +7 -1
  503. package/built-in-skills/role-builder/scripts/author-role.mjs +23 -7
  504. package/built-in-skills/role-builder/scripts/ingest-role.mjs +15 -117
  505. package/built-in-skills/role-builder/scripts/instantiate-and-run.mjs +15 -1
  506. package/built-in-skills/role-builder/scripts/operation-harness.mjs +6 -4
  507. package/built-in-skills/skill-creator/LICENSE.prismer +21 -0
  508. package/built-in-skills/skill-creator/NOTICE.md +18 -0
  509. package/built-in-skills/skill-creator/SKILL.md +20 -1
  510. package/built-in-skills/skill-creator/eval-viewer/generate_review.py +20 -31
  511. package/built-in-skills/skill-creator/eval-viewer/viewer.html +35 -23
  512. package/built-in-skills/skill-creator/references/hermes-agent-skill-authoring/GUIDE.md +220 -0
  513. package/built-in-skills/skill-creator/references/hermes-agent-skill-authoring/LICENSE +21 -0
  514. package/built-in-skills/{skill-authoring/SKILL.md → skill-creator/references/skill-authoring/GUIDE.md} +1 -1
  515. package/built-in-skills/{skill-builder/SKILL.md → skill-creator/references/skill-builder/GUIDE.md} +8 -12
  516. package/built-in-skills/skill-creator/references/skill-builder/scripts/ingest.mjs +93 -0
  517. package/built-in-skills/skill-creator/scripts/aggregate_benchmark.py +3 -2
  518. package/built-in-skills/skill-creator/scripts/import-library.mjs +30 -7
  519. package/built-in-skills/skill-creator/scripts/improve_description.py +14 -16
  520. package/built-in-skills/skill-creator/scripts/package_skill.py +16 -9
  521. package/built-in-skills/skill-creator/scripts/quick_validate.py +22 -5
  522. package/built-in-skills/skill-creator/scripts/run_eval.py +63 -144
  523. package/built-in-skills/skill-creator/scripts/run_loop.py +24 -16
  524. package/built-in-skills/slack-gif-creator/core/gif_builder.py +13 -2
  525. package/built-in-skills/slack-gif-creator/core/validators.py +17 -7
  526. package/built-in-skills/tasks/SKILL.md +2 -2
  527. package/built-in-skills/tdd/SKILL.md +7 -0
  528. package/built-in-skills/tdd/references/test-driven-development/GUIDE.md +356 -0
  529. package/built-in-skills/tdd/references/test-driven-development/LICENSE +21 -0
  530. package/built-in-skills/tdd/references/test-driven-development/LICENSE.superpowers +21 -0
  531. package/built-in-skills/tdd/references/test-driven-development/NOTICE.md +37 -0
  532. package/built-in-skills/team/SKILL.md +1 -1
  533. package/built-in-skills/web-artifacts-builder/SKILL.md +3 -3
  534. package/built-in-skills/web-artifacts-builder/scripts/bundle-artifact.sh +9 -7
  535. package/built-in-skills/web-artifacts-builder/scripts/init-artifact.sh +28 -55
  536. package/built-in-skills/webapp-qa/LICENSE +21 -0
  537. package/built-in-skills/webapp-qa/NOTICE.md +37 -0
  538. package/built-in-skills/webapp-qa/SKILL.md +41 -0
  539. package/built-in-skills/webapp-qa/references/dogfood/GUIDE.md +161 -0
  540. package/built-in-skills/webapp-qa/references/issue-taxonomy.md +109 -0
  541. package/built-in-skills/webapp-qa/templates/dogfood-report-template.md +86 -0
  542. package/built-in-skills/webapp-testing/SKILL.md +9 -2
  543. package/built-in-skills/webapp-testing/examples/console_logging.py +10 -4
  544. package/built-in-skills/webapp-testing/examples/element_discovery.py +11 -4
  545. package/built-in-skills/webapp-testing/examples/static_html_automation.py +14 -9
  546. package/built-in-skills/webapp-testing/scripts/with_server.py +34 -10
  547. package/built-in-skills/weekly-review/LICENSE +21 -0
  548. package/built-in-skills/weekly-review/NOTICE.md +21 -0
  549. package/built-in-skills/weekly-review/SKILL.md +49 -0
  550. package/components/eaas-pi-components.manifest.json +37 -0
  551. package/dist/cli.cjs +7079 -3327
  552. package/dist/cli.js +6706 -2936
  553. package/dist/index.cjs +7930 -3822
  554. package/dist/index.d.cts +484 -5
  555. package/dist/index.d.ts +484 -5
  556. package/dist/index.js +7181 -3064
  557. package/package.json +7 -2
  558. package/plugins/memory/prismer/__init__.py +4 -0
  559. package/plugins/memory/prismer/tool-schemas.generated.json +8 -0
  560. package/built-in-skills/skill-builder/scripts/ingest.mjs +0 -265
  561. package/built-in-skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  562. /package/built-in-skills/{document-generation/SKILL.md → office-artifacts/references/document-generation/GUIDE.md} +0 -0
  563. /package/built-in-skills/{skill-authoring/skill.json → skill-creator/references/skill-authoring/draft-contract.json} +0 -0
@@ -0,0 +1,1018 @@
1
+ # Scene System & Creative Composition
2
+
3
+ > **See also:** architecture.md · composition.md · effects.md · shaders.md
4
+
5
+ ## Scene Design Philosophy
6
+
7
+ Scenes are storytelling units, not effect demos. Every scene needs:
8
+ - A **concept** — what is happening visually? Not "plasma + rings" but "emergence from void" or "crystallization"
9
+ - An **arc** — how does it change over its duration? Build, decay, transform, reveal?
10
+ - A **role** — how does it serve the larger video narrative? Opening tension, peak energy, resolution?
11
+
12
+ The design patterns below provide compositional techniques. The scene examples show them in practice at increasing complexity. The protocol section covers the technical contract.
13
+
14
+ Good scene design starts with the concept, then selects effects and parameters that serve it. The design patterns section shows *how* to compose layers intentionally. The examples section shows complete working scenes at every complexity level. The protocol section covers the technical contract that all scenes must follow.
15
+
16
+ ---
17
+
18
+ ## Scene Design Patterns
19
+
20
+ Higher-order patterns for composing scenes that feel intentional rather than random. These patterns use the existing building blocks (value fields, blend modes, shaders, feedback) but organize them with compositional intent.
21
+
22
+ ## Layer Hierarchy
23
+
24
+ Every scene should have clear visual layers with distinct roles:
25
+
26
+ | Layer | Grid | Brightness | Purpose |
27
+ |-------|------|-----------|---------|
28
+ | **Background** | xs or sm (dense) | 0.1–0.25 | Atmosphere, texture. Never competes with content. |
29
+ | **Content** | md (balanced) | 0.4–0.8 | The main visual idea. Carries the scene's concept. |
30
+ | **Accent** | lg or sm (sparse) | 0.5–1.0 (sparse coverage) | Highlights, punctuation, sparse bright points. |
31
+
32
+ The background sets mood. The content layer is what the scene *is about*. The accent adds visual interest without overwhelming.
33
+
34
+ ```python
35
+ def fx_example(r, f, t, S):
36
+ local = t
37
+ progress = min(local / 5.0, 1.0)
38
+
39
+ g_bg = r.get_grid("sm")
40
+ g_main = r.get_grid("md")
41
+ g_accent = r.get_grid("lg")
42
+
43
+ # --- Background: dim atmosphere ---
44
+ bg_val = vf_smooth_noise(g_bg, f, t * 0.3, S, octaves=2, bri=0.15)
45
+ # ... render bg to canvas
46
+
47
+ # --- Content: the main visual idea ---
48
+ content_val = vf_spiral(g_main, f, t, S, n_arms=n_arms, tightness=tightness)
49
+ # ... render content on top of canvas
50
+
51
+ # --- Accent: sparse highlights ---
52
+ accent_val = vf_noise_static(g_accent, f, t, S, density=0.05)
53
+ # ... render accent on top
54
+
55
+ return canvas
56
+ ```
57
+
58
+ ## Directional Parameter Arcs
59
+
60
+ Parameters should *go somewhere* over the scene's duration — not oscillate aimlessly with `sin(t * N)`.
61
+
62
+ **Bad:** `twist = 3.0 + 2.0 * math.sin(t * 0.6)` — wobbles back and forth, feels aimless.
63
+
64
+ **Good:** `twist = 2.0 + progress * 5.0` — starts gentle, ends intense. The scene *builds*.
65
+
66
+ Use `progress = min(local / duration, 1.0)` (0→1 over the scene) to drive directional change:
67
+
68
+ | Pattern | Formula | Feel |
69
+ |---------|---------|------|
70
+ | Linear ramp | `progress * range` | Steady buildup |
71
+ | Ease-out | `1 - (1 - progress) ** 2` | Fast start, gentle finish |
72
+ | Ease-in | `progress ** 2` | Slow start, accelerating |
73
+ | Step reveal | `np.clip((progress - 0.5) / 0.25, 0, 1)` | Nothing until 50%, then fades in |
74
+ | Build + plateau | `min(1.0, progress * 1.5)` | Reaches full at 67%, holds |
75
+
76
+ Oscillation is fine for *secondary* parameters (saturation shimmer, hue drift). But the *defining* parameter of the scene should have a direction.
77
+
78
+ ### Examples of Directional Arcs
79
+
80
+ | Scene concept | Parameter | Arc |
81
+ |--------------|-----------|-----|
82
+ | Emergence | Ring radius | 0 → max (ease-out) |
83
+ | Shatter | Voronoi cell count | 8 → 38 (linear) |
84
+ | Descent | Tunnel speed | 2.0 → 10.0 (linear) |
85
+ | Mandala | Shape complexity | ring → +polygon → +star → +rosette (step reveals) |
86
+ | Crescendo | Layer count | 1 → 7 (staggered entry) |
87
+ | Entropy | Geometry visibility | 1.0 → 0.0 (consumed) |
88
+
89
+ ## Scene Concepts
90
+
91
+ Each scene should be built around a *visual idea*, not an effect name.
92
+
93
+ **Bad:** "fx_plasma_cascade" — named after the effect. No concept.
94
+ **Good:** "fx_emergence" — a point of light expands into a field. The name tells you *what happens*.
95
+
96
+ Good scene concepts have:
97
+ 1. A **visual metaphor** (emergence, descent, collision, entropy)
98
+ 2. A **directional arc** (things change from A to B, not oscillate)
99
+ 3. **Motivated layer choices** (each layer serves the concept)
100
+ 4. **Motivated feedback** (transform direction matches the metaphor)
101
+
102
+ | Concept | Metaphor | Feedback transform | Why |
103
+ |---------|----------|-------------------|-----|
104
+ | Emergence | Birth, expansion | zoom-out | Past frames expand outward |
105
+ | Descent | Falling, acceleration | zoom-in | Past frames rush toward center |
106
+ | Inferno | Rising fire | shift-up | Past frames rise with the flames |
107
+ | Entropy | Decay, dissolution | none | Clean, no persistence — things disappear |
108
+ | Crescendo | Accumulation | zoom + hue_shift | Everything compounds and shifts |
109
+
110
+ ## Compositional Techniques
111
+
112
+ ### Counter-Rotating Dual Systems
113
+
114
+ Two instances of the same effect rotating in opposite directions create visual interference:
115
+
116
+ ```python
117
+ # Primary spiral (clockwise)
118
+ s1_val = vf_spiral(g_main, f, t * 1.5, S, n_arms=n_arms_1, tightness=tightness_1)
119
+
120
+ # Counter-rotating spiral (counter-clockwise via negative time)
121
+ s2_val = vf_spiral(g_accent, f, -t * 1.2, S, n_arms=n_arms_2, tightness=tightness_2)
122
+
123
+ # Screen blend creates bright interference at crossing points
124
+ canvas = blend_canvas(canvas_with_s1, c2, "screen", 0.7)
125
+ ```
126
+
127
+ Works with spirals, vortexes, rings. The counter-rotation creates constantly shifting interference patterns.
128
+
129
+ ### Wave Collision
130
+
131
+ Two wave fronts converging from opposite sides, meeting at a collision point:
132
+
133
+ ```python
134
+ collision_phase = abs(progress - 0.5) * 2 # 1→0→1 (0 at collision)
135
+
136
+ # Wave A approaches from left
137
+ offset_a = (1 - progress) * g.cols * 0.4
138
+ wave_a = np.sin((g.cc + offset_a) * 0.08 + t * 2) * 0.5 + 0.5
139
+
140
+ # Wave B approaches from right
141
+ offset_b = -(1 - progress) * g.cols * 0.4
142
+ wave_b = np.sin((g.cc + offset_b) * 0.08 - t * 2) * 0.5 + 0.5
143
+
144
+ # Interference peaks at collision
145
+ combined = wave_a * 0.5 + wave_b * 0.5 + np.abs(wave_a - wave_b) * (1 - collision_phase) * 0.5
146
+ ```
147
+
148
+ ### Progressive Fragmentation
149
+
150
+ Voronoi with cell count increasing over time — visual shattering:
151
+
152
+ ```python
153
+ n_pts = int(8 + progress * 30) # 8 cells → 38 cells
154
+ # Pre-generate enough points, slice to n_pts
155
+ px = base_x[:n_pts] + np.sin(t * 0.3 + np.arange(n_pts) * 0.7) * (3 + progress * 3)
156
+ ```
157
+
158
+ The edge glow width can also increase with progress to emphasize the cracks.
159
+
160
+ ### Entropy / Consumption
161
+
162
+ A clean geometric pattern being overtaken by an organic process:
163
+
164
+ ```python
165
+ # Geometry fades out
166
+ geo_val = clean_pattern * max(0.05, 1.0 - progress * 0.9)
167
+
168
+ # Organic process grows in
169
+ rd_val = vf_reaction_diffusion(g, f, t, S) * min(1.0, progress * 1.5)
170
+
171
+ # Render geometry first, organic on top — organic consumes geometry
172
+ ```
173
+
174
+ ### Staggered Layer Entry (Crescendo)
175
+
176
+ Layers enter one at a time, building to overwhelming density:
177
+
178
+ ```python
179
+ def layer_strength(enter_t, ramp=1.5):
180
+ """0.0 until enter_t, ramps to 1.0 over ramp seconds."""
181
+ return max(0.0, min(1.0, (local - enter_t) / ramp))
182
+
183
+ # Layer 1: always present
184
+ s1 = layer_strength(0.0)
185
+ # Layer 2: enters at 2s
186
+ s2 = layer_strength(2.0)
187
+ # Layer 3: enters at 4s
188
+ s3 = layer_strength(4.0)
189
+ # ... etc
190
+
191
+ # Each layer uses a different effect, grid, palette, and blend mode
192
+ # Screen blend between layers so they accumulate light
193
+ ```
194
+
195
+ For a 15-second crescendo, 7 layers entering every 2 seconds works well. Use different blend modes (screen for most, add for energy, colordodge for the final wash).
196
+
197
+ ## Scene Ordering
198
+
199
+ For a multi-scene reel or video:
200
+ - **Vary mood between adjacent scenes** — don't put two calm scenes next to each other
201
+ - **Randomize order** rather than grouping by type — prevents "effect demo" feel
202
+ - **End on the strongest scene** — crescendo or something with a clear payoff
203
+ - **Open with energy** — grab attention in the first 2 seconds
204
+
205
+ ---
206
+
207
+ ## Scene Protocol
208
+
209
+ Scenes are the top-level creative unit. Each scene is a time-bounded segment with its own effect function, shader chain, feedback configuration, and tone-mapping gamma.
210
+
211
+ ### Scene Protocol (v2)
212
+
213
+ ### Function Signature
214
+
215
+ ```python
216
+ def fx_scene_name(r, f, t, S) -> canvas:
217
+ """
218
+ Args:
219
+ r: Renderer instance — access multiple grids via r.get_grid("sm")
220
+ f: dict of audio/video features, all values normalized to [0, 1]
221
+ t: time in seconds — local to scene (0.0 at scene start)
222
+ S: dict for persistent state (particles, rain columns, etc.)
223
+
224
+ Returns:
225
+ canvas: numpy uint8 array, shape (VH, VW, 3) — full pixel frame
226
+ """
227
+ ```
228
+
229
+ **Local time convention:** Scene functions receive `t` starting at 0.0 for the first frame of the scene, regardless of where the scene appears in the timeline. The render loop subtracts the scene's start time before calling the function:
230
+
231
+ ```python
232
+ # In render_clip:
233
+ t_local = fi / FPS - scene_start
234
+ canvas = fx_fn(r, feat, t_local, S)
235
+ ```
236
+
237
+ This makes scenes reorderable without modifying their code. Compute scene progress as:
238
+
239
+ ```python
240
+ progress = min(t / scene_duration, 1.0) # 0→1 over the scene
241
+ ```
242
+
243
+ This replaces the v1 protocol where scenes returned `(chars, colors)` tuples. The v2 protocol gives scenes full control over multi-grid rendering and pixel-level composition internally.
244
+
245
+ ### The Renderer Class
246
+
247
+ ```python
248
+ class Renderer:
249
+ def __init__(self):
250
+ self.grids = {} # lazy-initialized grid cache
251
+ self.g = None # "active" grid (for backward compat)
252
+ self.S = {} # persistent state dict
253
+
254
+ def get_grid(self, key):
255
+ """Get or create a GridLayer by size key."""
256
+ if key not in self.grids:
257
+ sizes = {"xs": 8, "sm": 10, "md": 16, "lg": 20, "xl": 24, "xxl": 40}
258
+ self.grids[key] = GridLayer(FONT_PATH, sizes[key])
259
+ return self.grids[key]
260
+
261
+ def set_grid(self, key):
262
+ """Set active grid (legacy). Prefer get_grid() for multi-grid scenes."""
263
+ self.g = self.get_grid(key)
264
+ return self.g
265
+ ```
266
+
267
+ **Key difference from v1**: scenes call `r.get_grid("sm")`, `r.get_grid("lg")`, etc. to access multiple grids. Each grid is lazy-initialized and cached. The `set_grid()` method still works for single-grid scenes.
268
+
269
+ ### Minimal Scene (Single Grid)
270
+
271
+ ```python
272
+ def fx_simple_rings(r, f, t, S):
273
+ """Single-grid scene: rings with distance-mapped hue."""
274
+ canvas = _render_vf(r, "md",
275
+ lambda g, f, t, S: vf_rings(g, f, t, S, n_base=8, spacing_base=3),
276
+ hf_distance(0.3, 0.02), PAL_STARS, f, t, S, sat=0.85)
277
+ return canvas
278
+ ```
279
+
280
+ ### Standard Scene (Two Grids + Blend)
281
+
282
+ ```python
283
+ def fx_tunnel_ripple(r, f, t, S):
284
+ """Two-grid scene: tunnel depth exclusion-blended with ripple."""
285
+ canvas_a = _render_vf(r, "md",
286
+ lambda g, f, t, S: vf_tunnel(g, f, t, S, speed=5.0, complexity=10) * 1.3,
287
+ hf_distance(0.55, 0.02), PAL_GREEK, f, t, S, sat=0.7)
288
+
289
+ canvas_b = _render_vf(r, "sm",
290
+ lambda g, f, t, S: vf_ripple(g, f, t, S,
291
+ sources=[(0.3,0.3), (0.7,0.7), (0.5,0.2)], freq=0.5, damping=0.012) * 1.4,
292
+ hf_angle(0.1), PAL_STARS, f, t, S, sat=0.8)
293
+
294
+ return blend_canvas(canvas_a, canvas_b, "exclusion", 0.8)
295
+ ```
296
+
297
+ ### Complex Scene (Three Grids + Conditional + Custom Rendering)
298
+
299
+ ```python
300
+ def fx_rings_explosion(r, f, t, S):
301
+ """Three-grid scene with particles and conditional kaleidoscope."""
302
+ # Layer 1: rings
303
+ canvas_a = _render_vf(r, "sm",
304
+ lambda g, f, t, S: vf_rings(g, f, t, S, n_base=10, spacing_base=2) * 1.4,
305
+ lambda g, f, t, S: (g.angle / (2*np.pi) + t * 0.15) % 1.0,
306
+ PAL_STARS, f, t, S, sat=0.9)
307
+
308
+ # Layer 2: vortex on different grid
309
+ canvas_b = _render_vf(r, "md",
310
+ lambda g, f, t, S: vf_vortex(g, f, t, S, twist=6.0) * 1.2,
311
+ hf_time_cycle(0.15), PAL_BLOCKS, f, t, S, sat=0.8)
312
+
313
+ result = blend_canvas(canvas_b, canvas_a, "screen", 0.7)
314
+
315
+ # Layer 3: particles (custom rendering, not _render_vf)
316
+ g = r.get_grid("sm")
317
+ if "px" not in S:
318
+ S["px"], S["py"], S["vx"], S["vy"], S["life"], S["pch"] = (
319
+ [], [], [], [], [], [])
320
+ if f.get("beat", 0) > 0.5:
321
+ chars = list("\u2605\u2736\u2733\u2738\u2726\u2728*+")
322
+ for _ in range(int(80 + f.get("rms", 0.3) * 120)):
323
+ ang = random.uniform(0, 2 * math.pi)
324
+ sp = random.uniform(1, 10) * (0.5 + f.get("sub_r", 0.3) * 2)
325
+ S["px"].append(float(g.cols // 2))
326
+ S["py"].append(float(g.rows // 2))
327
+ S["vx"].append(math.cos(ang) * sp * 2.5)
328
+ S["vy"].append(math.sin(ang) * sp)
329
+ S["life"].append(1.0)
330
+ S["pch"].append(random.choice(chars))
331
+
332
+ # Update + draw particles
333
+ ch_p = np.full((g.rows, g.cols), " ", dtype="U1")
334
+ co_p = np.zeros((g.rows, g.cols, 3), dtype=np.uint8)
335
+ i = 0
336
+ while i < len(S["px"]):
337
+ S["px"][i] += S["vx"][i]; S["py"][i] += S["vy"][i]
338
+ S["vy"][i] += 0.03; S["life"][i] -= 0.02
339
+ if S["life"][i] <= 0:
340
+ for k in ("px","py","vx","vy","life","pch"): S[k].pop(i)
341
+ else:
342
+ pr, pc = int(S["py"][i]), int(S["px"][i])
343
+ if 0 <= pr < g.rows and 0 <= pc < g.cols:
344
+ ch_p[pr, pc] = S["pch"][i]
345
+ co_p[pr, pc] = hsv2rgb_scalar(
346
+ 0.08 + (1-S["life"][i])*0.15, 0.95, S["life"][i])
347
+ i += 1
348
+
349
+ canvas_p = g.render(ch_p, co_p)
350
+ result = blend_canvas(result, canvas_p, "add", 0.8)
351
+
352
+ # Conditional kaleidoscope on strong beats
353
+ if f.get("bdecay", 0) > 0.4:
354
+ result = sh_kaleidoscope(result.copy(), folds=6)
355
+
356
+ return result
357
+ ```
358
+
359
+ ### Scene with Custom Character Rendering (Matrix Rain)
360
+
361
+ When you need per-cell control beyond what `_render_vf()` provides:
362
+
363
+ ```python
364
+ def fx_matrix_layered(r, f, t, S):
365
+ """Matrix rain blended with tunnel — two grids, screen blend."""
366
+ # Layer 1: Matrix rain (custom per-column rendering)
367
+ g = r.get_grid("md")
368
+ rows, cols = g.rows, g.cols
369
+ pal = PAL_KATA
370
+
371
+ if "ry" not in S or len(S["ry"]) != cols:
372
+ S["ry"] = np.random.uniform(-rows, rows, cols).astype(np.float32)
373
+ S["rsp"] = np.random.uniform(0.3, 2.0, cols).astype(np.float32)
374
+ S["rln"] = np.random.randint(8, 35, cols)
375
+ S["rch"] = np.random.randint(1, len(pal), (rows, cols))
376
+
377
+ speed = 0.6 + f.get("bass", 0.3) * 3
378
+ if f.get("beat", 0) > 0.5: speed *= 2.5
379
+ S["ry"] += S["rsp"] * speed
380
+
381
+ ch = np.full((rows, cols), " ", dtype="U1")
382
+ co = np.zeros((rows, cols, 3), dtype=np.uint8)
383
+ heads = S["ry"].astype(int)
384
+ for c in range(cols):
385
+ head = heads[c]
386
+ for i in range(S["rln"][c]):
387
+ row = head - i
388
+ if 0 <= row < rows:
389
+ fade = 1.0 - i / S["rln"][c]
390
+ ch[row, c] = pal[S["rch"][row, c] % len(pal)]
391
+ if i == 0:
392
+ v = int(min(255, fade * 300))
393
+ co[row, c] = (int(v*0.9), v, int(v*0.9))
394
+ else:
395
+ v = int(fade * 240)
396
+ co[row, c] = (int(v*0.1), v, int(v*0.4))
397
+ canvas_a = g.render(ch, co)
398
+
399
+ # Layer 2: Tunnel on sm grid for depth texture
400
+ canvas_b = _render_vf(r, "sm",
401
+ lambda g, f, t, S: vf_tunnel(g, f, t, S, speed=5.0, complexity=10),
402
+ hf_distance(0.3, 0.02), PAL_BLOCKS, f, t, S, sat=0.6)
403
+
404
+ return blend_canvas(canvas_a, canvas_b, "screen", 0.5)
405
+ ```
406
+
407
+ ---
408
+
409
+ ## Scene Table
410
+
411
+ The scene table defines the timeline: which scene plays when, with what configuration.
412
+
413
+ ### Structure
414
+
415
+ ```python
416
+ SCENES = [
417
+ {
418
+ "start": 0.0, # start time in seconds
419
+ "end": 3.96, # end time in seconds
420
+ "name": "starfield", # identifier (used for clip filenames)
421
+ "grid": "sm", # default grid (for render_clip setup)
422
+ "fx": fx_starfield, # scene function reference (must be module-level)
423
+ "gamma": 0.75, # tonemap gamma override (default 0.75)
424
+ "shaders": [ # shader chain (applied after tonemap + feedback)
425
+ ("bloom", {"thr": 120}),
426
+ ("vignette", {"s": 0.2}),
427
+ ("grain", {"amt": 8}),
428
+ ],
429
+ "feedback": None, # feedback buffer config (None = disabled)
430
+ # "feedback": {"decay": 0.8, "blend": "screen", "opacity": 0.3,
431
+ # "transform": "zoom", "transform_amt": 0.02, "hue_shift": 0.02},
432
+ },
433
+ {
434
+ "start": 3.96,
435
+ "end": 6.58,
436
+ "name": "matrix_layered",
437
+ "grid": "md",
438
+ "fx": fx_matrix_layered,
439
+ "shaders": [
440
+ ("crt", {"strength": 0.05}),
441
+ ("scanlines", {"intensity": 0.12}),
442
+ ("color_grade", {"tint": (0.7, 1.2, 0.7)}),
443
+ ("bloom", {"thr": 100}),
444
+ ],
445
+ "feedback": {"decay": 0.5, "blend": "add", "opacity": 0.2},
446
+ },
447
+ # ... more scenes ...
448
+ ]
449
+ ```
450
+
451
+ ### Beat-Synced Scene Cutting
452
+
453
+ Derive cut points from audio analysis:
454
+
455
+ ```python
456
+ # Get beat timestamps
457
+ beats = [fi / FPS for fi in range(N_FRAMES) if features["beat"][fi] > 0.5]
458
+
459
+ # Group beats into phrase boundaries (every 4-8 beats)
460
+ cuts = [0.0]
461
+ for i in range(0, len(beats), 4): # cut every 4 beats
462
+ cuts.append(beats[i])
463
+ cuts.append(DURATION)
464
+
465
+ # Or use the music's structure: silence gaps, energy changes
466
+ energy = features["rms"]
467
+ # Find timestamps where energy drops significantly -> natural break points
468
+ ```
469
+
470
+ ### `render_clip()` — The Render Loop
471
+
472
+ This function renders one scene to a clip file:
473
+
474
+ ```python
475
+ def render_clip(seg, features, clip_path):
476
+ r = Renderer()
477
+ r.set_grid(seg["grid"])
478
+ S = r.S
479
+ import hashlib
480
+ seed = int.from_bytes(hashlib.sha256(str(seg["id"]).encode()).digest()[:4], "big")
481
+ random.seed(seed)
482
+ np.random.seed(seed)
483
+
484
+ # Build shader chain from config
485
+ chain = ShaderChain()
486
+ for shader_name, kwargs in seg.get("shaders", []):
487
+ chain.add(shader_name, **kwargs)
488
+
489
+ # Setup feedback buffer
490
+ fb = None
491
+ fb_cfg = seg.get("feedback", None)
492
+ if fb_cfg:
493
+ fb = FeedbackBuffer()
494
+
495
+ fx_fn = seg["fx"]
496
+
497
+ # Open ffmpeg pipe
498
+ cmd = ["ffmpeg", "-y", "-f", "rawvideo", "-pix_fmt", "rgb24",
499
+ "-s", f"{VW}x{VH}", "-r", str(FPS), "-i", "pipe:0",
500
+ "-c:v", "libx264", "-preset", "fast", "-crf", "20",
501
+ "-pix_fmt", "yuv420p", clip_path]
502
+ stderr_fh = open(clip_path.replace(".mp4", ".log"), "w")
503
+ pipe = subprocess.Popen(cmd, stdin=subprocess.PIPE,
504
+ stdout=subprocess.DEVNULL, stderr=stderr_fh)
505
+
506
+ for fi in range(seg["frame_start"], seg["frame_end"]):
507
+ t = (fi - seg["frame_start"]) / FPS
508
+ feat = {k: float(features[k][fi]) for k in features}
509
+
510
+ # 1. Scene renders canvas
511
+ canvas = fx_fn(r, feat, t, S)
512
+
513
+ # 2. Tonemap normalizes brightness
514
+ canvas = tonemap(canvas, gamma=seg.get("gamma", 0.75))
515
+
516
+ # 3. Feedback adds temporal recursion
517
+ if fb and fb_cfg:
518
+ canvas = fb.apply(canvas, **{k: fb_cfg[k] for k in fb_cfg})
519
+
520
+ # 4. Shader chain adds post-processing
521
+ canvas = chain.apply(canvas, f=feat, t=t)
522
+
523
+ pipe.stdin.write(canvas.tobytes())
524
+
525
+ pipe.stdin.close()
526
+ status = pipe.wait()
527
+ stderr_fh.close()
528
+ if status != 0:
529
+ raise RuntimeError(f"ffmpeg failed: {status}")
530
+ ```
531
+
532
+ ### Building Segments from Scene Table
533
+
534
+ ```python
535
+ segments = []
536
+ for i, scene in enumerate(SCENES):
537
+ segments.append({
538
+ "id": f"s{i:02d}_{scene['name']}",
539
+ "name": scene["name"],
540
+ "grid": scene["grid"],
541
+ "fx": scene["fx"],
542
+ "shaders": scene.get("shaders", []),
543
+ "feedback": scene.get("feedback", None),
544
+ "gamma": scene.get("gamma", 0.75),
545
+ "frame_start": int(scene["start"] * FPS),
546
+ "frame_end": int(scene["end"] * FPS),
547
+ })
548
+ ```
549
+
550
+ ### Parallel Rendering
551
+
552
+ Scenes are independent units dispatched to a process pool:
553
+
554
+ ```python
555
+ from concurrent.futures import ProcessPoolExecutor, as_completed
556
+
557
+ with ProcessPoolExecutor(max_workers=N_WORKERS) as pool:
558
+ futures = {
559
+ pool.submit(render_clip, seg, features, clip_path): seg["id"]
560
+ for seg, clip_path in zip(segments, clip_paths)
561
+ }
562
+ for fut in as_completed(futures):
563
+ try:
564
+ fut.result()
565
+ except Exception as e:
566
+ log(f"ERROR {futures[fut]}: {e}")
567
+ ```
568
+
569
+ **Pickling constraint**: `ProcessPoolExecutor` serializes arguments via pickle. Module-level functions can be pickled; lambdas and closures cannot. All `fx_*` scene functions MUST be defined at module level, not as closures or class methods.
570
+
571
+ ### Test-Frame Mode
572
+
573
+ Render a single frame at a specific timestamp to verify visuals without a full render:
574
+
575
+ ```python
576
+ if args.test_frame >= 0:
577
+ fi = min(int(args.test_frame * FPS), N_FRAMES - 1)
578
+ t = fi / FPS
579
+ feat = {k: float(features[k][fi]) for k in features}
580
+ scene = next(sc for sc in reversed(SCENES) if t >= sc["start"])
581
+ r = Renderer()
582
+ r.set_grid(scene["grid"])
583
+ canvas = scene["fx"](r, feat, t, r.S)
584
+ canvas = tonemap(canvas, gamma=scene.get("gamma", 0.75))
585
+ chain = ShaderChain()
586
+ for sn, kw in scene.get("shaders", []):
587
+ chain.add(sn, **kw)
588
+ canvas = chain.apply(canvas, f=feat, t=t)
589
+ Image.fromarray(canvas).save(f"test_{args.test_frame:.1f}s.png")
590
+ print(f"Mean brightness: {canvas.astype(float).mean():.1f}")
591
+ ```
592
+
593
+ CLI: `python reel.py --test-frame 10.0`
594
+
595
+ ---
596
+
597
+ ## Scene Design Checklist
598
+
599
+ For each scene:
600
+
601
+ 1. **Choose 2-3 grid sizes** — different scales create interference
602
+ 2. **Choose different value fields** per layer — don't use the same effect on every grid
603
+ 3. **Choose different hue fields** per layer — or at minimum different hue offsets
604
+ 4. **Choose different palettes** per layer — mixing PAL_RUNE with PAL_BLOCKS looks different from PAL_RUNE with PAL_DENSE
605
+ 5. **Choose a blend mode** that matches the energy — screen for bright, difference for psychedelic, exclusion for subtle
606
+ 6. **Add conditional effects** on beat — kaleidoscope, mirror, glitch
607
+ 7. **Configure feedback** for trailing/recursive looks — or None for clean cuts
608
+ 8. **Set gamma** if using destructive shaders (solarize, posterize)
609
+ 9. **Test with --test-frame** at the scene's midpoint before full render
610
+
611
+ ---
612
+
613
+ ## Scene Examples
614
+
615
+ Copy-paste-ready scene functions at increasing complexity. Each is a complete, working v2 scene function that returns a pixel canvas. See the Scene Protocol section above for the scene protocol and `composition.md` for blend modes and tonemap.
616
+
617
+ ---
618
+
619
+ ### Minimal — Single Grid, Single Effect
620
+
621
+ ### Breathing Plasma
622
+
623
+ One grid, one value field, one hue field. The simplest possible scene.
624
+
625
+ ```python
626
+ def fx_breathing_plasma(r, f, t, S):
627
+ """Plasma field with time-cycling hue. Audio modulates brightness."""
628
+ canvas = _render_vf(r, "md",
629
+ lambda g, f, t, S: vf_plasma(g, f, t, S) * 1.3,
630
+ hf_time_cycle(0.08), PAL_DENSE, f, t, S, sat=0.8)
631
+ return canvas
632
+ ```
633
+
634
+ ### Reaction-Diffusion Coral
635
+
636
+ Single grid, simulation-based field. Evolves organically over time.
637
+
638
+ ```python
639
+ def fx_coral(r, f, t, S):
640
+ """Gray-Scott reaction-diffusion — coral branching pattern.
641
+ Slow-evolving, organic. Best for ambient/chill sections."""
642
+ canvas = _render_vf(r, "sm",
643
+ lambda g, f, t, S: vf_reaction_diffusion(g, f, t, S,
644
+ feed=0.037, kill=0.060, steps_per_frame=6, init_mode="center"),
645
+ hf_distance(0.55, 0.015), PAL_DOTS, f, t, S, sat=0.7)
646
+ return canvas
647
+ ```
648
+
649
+ ### SDF Geometry
650
+
651
+ Geometric shapes from SDFs. Clean, precise, graphic.
652
+
653
+ ```python
654
+ def fx_sdf_rings(r, f, t, S):
655
+ """Concentric SDF rings with smooth pulsing."""
656
+ def val_fn(g, f, t, S):
657
+ d1 = sdf_ring(g, radius=0.15 + f.get("bass", 0.3) * 0.05, thickness=0.015)
658
+ d2 = sdf_ring(g, radius=0.25 + f.get("mid", 0.3) * 0.05, thickness=0.012)
659
+ d3 = sdf_ring(g, radius=0.35 + f.get("hi", 0.3) * 0.04, thickness=0.010)
660
+ combined = sdf_smooth_union(sdf_smooth_union(d1, d2, 0.05), d3, 0.05)
661
+ return sdf_glow(combined, falloff=0.08) * (0.5 + f.get("rms", 0.3) * 0.8)
662
+ canvas = _render_vf(r, "md", val_fn, hf_angle(0.0), PAL_STARS, f, t, S, sat=0.85)
663
+ return canvas
664
+ ```
665
+
666
+ ---
667
+
668
+ ### Standard — Two Grids + Blend
669
+
670
+ ### Tunnel Through Noise
671
+
672
+ Two grids at different densities, screen blended. The fine noise texture shows through the coarser tunnel characters.
673
+
674
+ ```python
675
+ def fx_tunnel_noise(r, f, t, S):
676
+ """Tunnel depth on md grid + fBM noise on sm grid, screen blended."""
677
+ canvas_a = _render_vf(r, "md",
678
+ lambda g, f, t, S: vf_tunnel(g, f, t, S, speed=4.0, complexity=8) * 1.2,
679
+ hf_distance(0.5, 0.02), PAL_BLOCKS, f, t, S, sat=0.7)
680
+
681
+ canvas_b = _render_vf(r, "sm",
682
+ lambda g, f, t, S: vf_fbm(g, f, t, S, octaves=4, freq=0.05, speed=0.15) * 1.3,
683
+ hf_time_cycle(0.06), PAL_RUNE, f, t, S, sat=0.6)
684
+
685
+ return blend_canvas(canvas_a, canvas_b, "screen", 0.7)
686
+ ```
687
+
688
+ ### Voronoi Cells + Spiral Overlay
689
+
690
+ Voronoi cell edges with a spiral arm pattern overlaid.
691
+
692
+ ```python
693
+ def fx_voronoi_spiral(r, f, t, S):
694
+ """Voronoi edge detection on md + logarithmic spiral on lg."""
695
+ canvas_a = _render_vf(r, "md",
696
+ lambda g, f, t, S: vf_voronoi(g, f, t, S,
697
+ n_cells=15, mode="edge", edge_width=2.0, speed=0.4),
698
+ hf_angle(0.2), PAL_CIRCUIT, f, t, S, sat=0.75)
699
+
700
+ canvas_b = _render_vf(r, "lg",
701
+ lambda g, f, t, S: vf_spiral(g, f, t, S, n_arms=4, tightness=3.0) * 1.2,
702
+ hf_distance(0.1, 0.03), PAL_BLOCKS, f, t, S, sat=0.9)
703
+
704
+ return blend_canvas(canvas_a, canvas_b, "exclusion", 0.6)
705
+ ```
706
+
707
+ ### Domain-Warped fBM
708
+
709
+ Two layers of the same fBM, one domain-warped, difference-blended for psychedelic organic texture.
710
+
711
+ ```python
712
+ def fx_organic_warp(r, f, t, S):
713
+ """Clean fBM vs domain-warped fBM, difference blended."""
714
+ canvas_a = _render_vf(r, "sm",
715
+ lambda g, f, t, S: vf_fbm(g, f, t, S, octaves=5, freq=0.04, speed=0.1),
716
+ hf_plasma(0.2), PAL_DENSE, f, t, S, sat=0.6)
717
+
718
+ canvas_b = _render_vf(r, "md",
719
+ lambda g, f, t, S: vf_domain_warp(g, f, t, S,
720
+ warp_strength=20.0, freq=0.05, speed=0.15),
721
+ hf_time_cycle(0.05), PAL_BRAILLE, f, t, S, sat=0.7)
722
+
723
+ return blend_canvas(canvas_a, canvas_b, "difference", 0.7)
724
+ ```
725
+
726
+ ---
727
+
728
+ ### Complex — Three Grids + Conditional + Feedback
729
+
730
+ ### Psychedelic Cathedral
731
+
732
+ Three-grid composition with beat-triggered kaleidoscope and feedback zoom tunnel. The most visually complex pattern.
733
+
734
+ ```python
735
+ def fx_cathedral(r, f, t, S):
736
+ """Three-layer cathedral: interference + rings + noise, kaleidoscope on beat,
737
+ feedback zoom tunnel."""
738
+ # Layer 1: interference pattern on sm grid
739
+ canvas_a = _render_vf(r, "sm",
740
+ lambda g, f, t, S: vf_interference(g, f, t, S, n_waves=7) * 1.3,
741
+ hf_angle(0.0), PAL_MATH, f, t, S, sat=0.8)
742
+
743
+ # Layer 2: pulsing rings on md grid
744
+ canvas_b = _render_vf(r, "md",
745
+ lambda g, f, t, S: vf_rings(g, f, t, S, n_base=10, spacing_base=3) * 1.4,
746
+ hf_distance(0.3, 0.02), PAL_STARS, f, t, S, sat=0.9)
747
+
748
+ # Layer 3: temporal noise on lg grid (slow morph)
749
+ canvas_c = _render_vf(r, "lg",
750
+ lambda g, f, t, S: vf_temporal_noise(g, f, t, S,
751
+ freq=0.04, t_freq=0.2, octaves=3),
752
+ hf_time_cycle(0.12), PAL_BLOCKS, f, t, S, sat=0.7)
753
+
754
+ # Blend: A screen B, then difference with C
755
+ result = blend_canvas(canvas_a, canvas_b, "screen", 0.8)
756
+ result = blend_canvas(result, canvas_c, "difference", 0.5)
757
+
758
+ # Beat-triggered kaleidoscope
759
+ if f.get("bdecay", 0) > 0.3:
760
+ folds = 6 if f.get("sub_r", 0.3) > 0.4 else 8
761
+ result = sh_kaleidoscope(result.copy(), folds=folds)
762
+
763
+ return result
764
+
765
+ # Scene table entry with feedback:
766
+ # {"start": 30.0, "end": 50.0, "name": "cathedral", "fx": fx_cathedral,
767
+ # "gamma": 0.65, "shaders": [("bloom", {"thr": 110}), ("chromatic", {"amt": 4}),
768
+ # ("vignette", {"s": 0.2}), ("grain", {"amt": 8})],
769
+ # "feedback": {"decay": 0.75, "blend": "screen", "opacity": 0.35,
770
+ # "transform": "zoom", "transform_amt": 0.012, "hue_shift": 0.015}}
771
+ ```
772
+
773
+ ### Masked Reaction-Diffusion with Attractor Overlay
774
+
775
+ Reaction-diffusion visible only through an animated iris mask, with a strange attractor density field underneath.
776
+
777
+ ```python
778
+ def fx_masked_life(r, f, t, S):
779
+ """Attractor base + reaction-diffusion visible through iris mask + particles."""
780
+ g_sm = r.get_grid("sm")
781
+ g_md = r.get_grid("md")
782
+
783
+ # Layer 1: strange attractor density field (background)
784
+ canvas_bg = _render_vf(r, "sm",
785
+ lambda g, f, t, S: vf_strange_attractor(g, f, t, S,
786
+ attractor="clifford", n_points=30000),
787
+ hf_time_cycle(0.04), PAL_DOTS, f, t, S, sat=0.5)
788
+
789
+ # Layer 2: reaction-diffusion (foreground, will be masked)
790
+ canvas_rd = _render_vf(r, "md",
791
+ lambda g, f, t, S: vf_reaction_diffusion(g, f, t, S,
792
+ feed=0.046, kill=0.063, steps_per_frame=4, init_mode="ring"),
793
+ hf_angle(0.15), PAL_HALFFILL, f, t, S, sat=0.85)
794
+
795
+ # Animated iris mask — opens over first 5 seconds of scene
796
+ scene_start = S.get("_scene_start", t)
797
+ if "_scene_start" not in S:
798
+ S["_scene_start"] = t
799
+ mask = mask_iris(g_md, t, scene_start, scene_start + 5.0,
800
+ max_radius=0.6)
801
+ canvas_rd = apply_mask_canvas(canvas_rd, mask, bg_canvas=canvas_bg)
802
+
803
+ # Layer 3: flow-field particles following the R-D gradient
804
+ rd_field = vf_reaction_diffusion(g_sm, f, t, S,
805
+ feed=0.046, kill=0.063, steps_per_frame=0) # read without stepping
806
+ ch_p, co_p = update_flow_particles(S, g_sm, f, rd_field,
807
+ n=300, speed=0.8, char_set=list("·•◦∘°"))
808
+ canvas_p = g_sm.render(ch_p, co_p)
809
+
810
+ result = blend_canvas(canvas_rd, canvas_p, "add", 0.7)
811
+ return result
812
+ ```
813
+
814
+ ### Morphing Field Sequence with Eased Keyframes
815
+
816
+ Demonstrates temporal coherence: smooth morphing between effects with keyframed parameters.
817
+
818
+ ```python
819
+ def fx_morphing_journey(r, f, t, S):
820
+ """Morphs through 4 value fields over 20 seconds with eased transitions.
821
+ Parameters (twist, arm count) also keyframed."""
822
+ # Keyframed twist parameter
823
+ twist = keyframe(t, [(0, 1.0), (5, 5.0), (10, 2.0), (15, 8.0), (20, 1.0)],
824
+ ease_fn=ease_in_out_cubic, loop=True)
825
+
826
+ # Sequence of value fields with 2s crossfade
827
+ fields = [
828
+ lambda g, f, t, S: vf_plasma(g, f, t, S),
829
+ lambda g, f, t, S: vf_vortex(g, f, t, S, twist=twist),
830
+ lambda g, f, t, S: vf_fbm(g, f, t, S, octaves=5, freq=0.04),
831
+ lambda g, f, t, S: vf_domain_warp(g, f, t, S, warp_strength=15),
832
+ ]
833
+ durations = [5.0, 5.0, 5.0, 5.0]
834
+
835
+ val_fn = lambda g, f, t, S: vf_sequence(g, f, t, S, fields, durations,
836
+ crossfade=2.0)
837
+
838
+ # Render with slowly rotating hue
839
+ canvas = _render_vf(r, "md", val_fn, hf_time_cycle(0.06),
840
+ PAL_DENSE, f, t, S, sat=0.8)
841
+
842
+ # Second layer: tiled version of same sequence at smaller grid
843
+ tiled_fn = lambda g, f, t, S: vf_sequence(
844
+ make_tgrid(g, *uv_tile(g, 3, 3, mirror=True)),
845
+ f, t, S, fields, durations, crossfade=2.0)
846
+ canvas_b = _render_vf(r, "sm", tiled_fn, hf_angle(0.1),
847
+ PAL_RUNE, f, t, S, sat=0.6)
848
+
849
+ return blend_canvas(canvas, canvas_b, "screen", 0.5)
850
+ ```
851
+
852
+ ---
853
+
854
+ ### Specialized — Unique State Patterns
855
+
856
+ ### Game of Life with Ghost Trails
857
+
858
+ Cellular automaton with analog fade trails. Beat injects random cells.
859
+
860
+ ```python
861
+ def fx_life(r, f, t, S):
862
+ """Conway's Game of Life with fading ghost trails.
863
+ Beat events inject random live cells for disruption."""
864
+ canvas = _render_vf(r, "sm",
865
+ lambda g, f, t, S: vf_game_of_life(g, f, t, S,
866
+ rule="life", steps_per_frame=1, fade=0.92, density=0.25),
867
+ hf_fixed(0.33), PAL_BLOCKS, f, t, S, sat=0.8)
868
+
869
+ # Overlay: coral automaton on lg grid for chunky texture
870
+ canvas_b = _render_vf(r, "lg",
871
+ lambda g, f, t, S: vf_game_of_life(g, f, t, S,
872
+ rule="coral", steps_per_frame=1, fade=0.85, density=0.15, seed=99),
873
+ hf_time_cycle(0.1), PAL_HATCH, f, t, S, sat=0.6)
874
+
875
+ return blend_canvas(canvas, canvas_b, "screen", 0.5)
876
+ ```
877
+
878
+ ### Boids Flock Over Voronoi
879
+
880
+ Emergent swarm movement over a cellular background.
881
+
882
+ ```python
883
+ def fx_boid_swarm(r, f, t, S):
884
+ """Flocking boids over animated voronoi cells."""
885
+ # Background: voronoi cells
886
+ canvas_bg = _render_vf(r, "md",
887
+ lambda g, f, t, S: vf_voronoi(g, f, t, S,
888
+ n_cells=20, mode="distance", speed=0.2),
889
+ hf_distance(0.4, 0.02), PAL_CIRCUIT, f, t, S, sat=0.5)
890
+
891
+ # Foreground: boids
892
+ g = r.get_grid("md")
893
+ ch_b, co_b = update_boids(S, g, f, n_boids=150, perception=6.0,
894
+ max_speed=1.5, char_set=list("▸▹►▻→⟶"))
895
+ canvas_boids = g.render(ch_b, co_b)
896
+
897
+ # Trails for the boids
898
+ # (boid positions are stored in S["boid_x"], S["boid_y"])
899
+ S["px"] = list(S.get("boid_x", []))
900
+ S["py"] = list(S.get("boid_y", []))
901
+ ch_t, co_t = draw_particle_trails(S, g, max_trail=6, fade=0.6)
902
+ canvas_trails = g.render(ch_t, co_t)
903
+
904
+ result = blend_canvas(canvas_bg, canvas_trails, "add", 0.3)
905
+ result = blend_canvas(result, canvas_boids, "add", 0.9)
906
+ return result
907
+ ```
908
+
909
+ ### Fire Rising Through SDF Text Stencil
910
+
911
+ Fire effect visible only through text letterforms.
912
+
913
+ ```python
914
+ def fx_fire_text(r, f, t, S):
915
+ """Fire columns visible through text stencil. Text acts as window."""
916
+ g = r.get_grid("lg")
917
+
918
+ # Full-screen fire (will be masked)
919
+ canvas_fire = _render_vf(r, "sm",
920
+ lambda g, f, t, S: np.clip(
921
+ vf_fbm(g, f, t, S, octaves=4, freq=0.08, speed=0.8) *
922
+ (1.0 - g.rr / g.rows) * # fade toward top
923
+ (0.6 + f.get("bass", 0.3) * 0.8), 0, 1),
924
+ hf_fixed(0.05), PAL_BLOCKS, f, t, S, sat=0.9) # fire hue
925
+
926
+ # Background: dark domain warp
927
+ canvas_bg = _render_vf(r, "md",
928
+ lambda g, f, t, S: vf_domain_warp(g, f, t, S,
929
+ warp_strength=8, freq=0.03, speed=0.05) * 0.3,
930
+ hf_fixed(0.6), PAL_DENSE, f, t, S, sat=0.4)
931
+
932
+ # Text stencil mask
933
+ mask = mask_text(g, "FIRE", row_frac=0.45)
934
+ # Expand vertically for multi-row coverage
935
+ for offset in range(-2, 3):
936
+ shifted = mask_text(g, "FIRE", row_frac=0.45 + offset / g.rows)
937
+ mask = mask_union(mask, shifted)
938
+
939
+ canvas_masked = apply_mask_canvas(canvas_fire, mask, bg_canvas=canvas_bg)
940
+ return canvas_masked
941
+ ```
942
+
943
+ ### Portrait Mode: Vertical Rain + Quote
944
+
945
+ Optimized for 9:16. Uses vertical space for long rain trails and stacked text.
946
+
947
+ ```python
948
+ def fx_portrait_rain_quote(r, f, t, S):
949
+ """Portrait-optimized: matrix rain (long vertical trails) with stacked quote.
950
+ Designed for 1080x1920 (9:16)."""
951
+ g = r.get_grid("md") # ~112x100 in portrait
952
+
953
+ # Matrix rain — long trails benefit from portrait's extra rows
954
+ ch, co, S = eff_matrix_rain(g, f, t, S,
955
+ hue=0.33, bri=0.6, pal=PAL_KATA, speed_base=0.4, speed_beat=2.5)
956
+ canvas_rain = g.render(ch, co)
957
+
958
+ # Tunnel depth underneath for texture
959
+ canvas_tunnel = _render_vf(r, "sm",
960
+ lambda g, f, t, S: vf_tunnel(g, f, t, S, speed=3.0, complexity=6) * 0.8,
961
+ hf_fixed(0.33), PAL_BLOCKS, f, t, S, sat=0.5)
962
+
963
+ result = blend_canvas(canvas_tunnel, canvas_rain, "screen", 0.8)
964
+
965
+ # Quote text — portrait layout: short lines, many of them
966
+ g_text = r.get_grid("lg") # ~90x80 in portrait
967
+ quote_lines = layout_text_portrait(
968
+ "The code is the art and the art is the code",
969
+ max_chars_per_line=20)
970
+ # Center vertically
971
+ block_start = (g_text.rows - len(quote_lines)) // 2
972
+ ch_t = np.full((g_text.rows, g_text.cols), " ", dtype="U1")
973
+ co_t = np.zeros((g_text.rows, g_text.cols, 3), dtype=np.uint8)
974
+ total_chars = sum(len(l) for l in quote_lines)
975
+ progress = min(1.0, (t - S.get("_scene_start", t)) / 3.0)
976
+ if "_scene_start" not in S: S["_scene_start"] = t
977
+ render_typewriter(ch_t, co_t, quote_lines, block_start, g_text.cols,
978
+ progress, total_chars, (200, 255, 220), t)
979
+ canvas_text = g_text.render(ch_t, co_t)
980
+
981
+ result = blend_canvas(result, canvas_text, "add", 0.9)
982
+ return result
983
+ ```
984
+
985
+ ---
986
+
987
+ ### Scene Table Template
988
+
989
+ Wire scenes into a complete video:
990
+
991
+ ```python
992
+ SCENES = [
993
+ {"start": 0.0, "end": 5.0, "name": "coral",
994
+ "fx": fx_coral, "grid": "sm", "gamma": 0.70,
995
+ "shaders": [("bloom", {"thr": 110}), ("vignette", {"s": 0.2})],
996
+ "feedback": {"decay": 0.8, "blend": "screen", "opacity": 0.3,
997
+ "transform": "zoom", "transform_amt": 0.01}},
998
+
999
+ {"start": 5.0, "end": 15.0, "name": "tunnel_noise",
1000
+ "fx": fx_tunnel_noise, "grid": "md", "gamma": 0.75,
1001
+ "shaders": [("chromatic", {"amt": 3}), ("bloom", {"thr": 120}),
1002
+ ("scanlines", {"intensity": 0.06}), ("grain", {"amt": 8})],
1003
+ "feedback": None},
1004
+
1005
+ {"start": 15.0, "end": 35.0, "name": "cathedral",
1006
+ "fx": fx_cathedral, "grid": "sm", "gamma": 0.65,
1007
+ "shaders": [("bloom", {"thr": 100}), ("chromatic", {"amt": 5}),
1008
+ ("color_wobble", {"amt": 0.2}), ("vignette", {"s": 0.18})],
1009
+ "feedback": {"decay": 0.75, "blend": "screen", "opacity": 0.35,
1010
+ "transform": "zoom", "transform_amt": 0.012, "hue_shift": 0.015}},
1011
+
1012
+ {"start": 35.0, "end": 50.0, "name": "morphing",
1013
+ "fx": fx_morphing_journey, "grid": "md", "gamma": 0.70,
1014
+ "shaders": [("bloom", {"thr": 110}), ("grain", {"amt": 6})],
1015
+ "feedback": {"decay": 0.7, "blend": "screen", "opacity": 0.25,
1016
+ "transform": "rotate_cw", "transform_amt": 0.003}},
1017
+ ]
1018
+ ```