m0saic 0.2.2 → 0.3.1

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 (441) hide show
  1. package/LICENSE +22 -7
  2. package/README.md +23 -5
  3. package/dist/browseE2e.js +1 -1
  4. package/dist/connectionsFromEnv.js +1 -1
  5. package/dist/e2eTemplateVariants.js +1 -1
  6. package/dist/frontDoor.js +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/inlineDsl.js +1 -1
  9. package/dist/mcp/bridgeClient.js +1 -0
  10. package/dist/mcp/server.js +1 -0
  11. package/dist/mcp/tools.js +1 -0
  12. package/dist/mosaicxRunner.js +1 -1
  13. package/dist/outputPattern.js +1 -1
  14. package/dist/showcaseFeed.js +1 -1
  15. package/dist/templateDoctor.js +1 -1
  16. package/dist/utils/checkFeasibility.js +1 -1
  17. package/dist/utils/collectRenderErrors.js +1 -1
  18. package/dist/utils/enrichImageAlphaFromDoc.js +1 -1
  19. package/dist/utils/ensureFfmpeg.js +1 -1
  20. package/dist/utils/extractLayoutMeta.js +1 -1
  21. package/dist/utils/failureHints.js +1 -1
  22. package/dist/utils/ffmpegProbe.js +1 -1
  23. package/dist/utils/formatM0saicForCli.js +1 -1
  24. package/dist/utils/hashFile.js +1 -1
  25. package/dist/utils/helpGroups.js +1 -1
  26. package/dist/utils/installContext.js +1 -0
  27. package/dist/utils/invocation.js +1 -1
  28. package/dist/utils/licenseActivation.js +1 -0
  29. package/dist/utils/licenseActivationWorker.js +1 -0
  30. package/dist/utils/mosaicSpinner.js +1 -1
  31. package/dist/utils/parseDimensions.js +1 -1
  32. package/dist/utils/pathInfo.js +1 -1
  33. package/dist/utils/readJsonArg.js +1 -1
  34. package/dist/utils/renderOutcome.js +1 -1
  35. package/dist/utils/renderReport.js +1 -1
  36. package/dist/utils/renderSignals.js +1 -1
  37. package/dist/utils/renderWorkspace.js +1 -1
  38. package/dist/utils/reportOutputFormat.js +1 -0
  39. package/dist/utils/setupFfmpeg.js +1 -1
  40. package/dist/utils/telemetry.js +1 -1
  41. package/dist/utils/telemetryFlushWorker.js +1 -1
  42. package/dist/utils/telemetryUpstream.js +1 -1
  43. package/dist/utils/telemetryUsage.js +1 -1
  44. package/dist/utils/toolchainConfig.js +1 -1
  45. package/dist/utils/tutorialDuration.js +1 -1
  46. package/dist/utils/updateCheck.js +1 -1
  47. package/dist/utils/updateCheckWorker.js +1 -1
  48. package/dist/utils/validateSourceCounts.js +1 -1
  49. package/dist/utils/versions.js +1 -1
  50. package/dist/webCustomizeLink.js +1 -1
  51. package/node_modules/@m0saic/community-m/NOTICE +9 -0
  52. package/node_modules/@m0saic/community-m/release.json +2 -2
  53. package/node_modules/@m0saic/core/dist/core/buildChildMosaicSource.js +1 -1
  54. package/node_modules/@m0saic/core/dist/core/buildChunkCommands.js +1 -1
  55. package/node_modules/@m0saic/core/dist/core/buildEncodeCommands.js +1 -1
  56. package/node_modules/@m0saic/core/dist/core/buildLavfiSource.js +1 -1
  57. package/node_modules/@m0saic/core/dist/core/buildMediaSource.js +1 -1
  58. package/node_modules/@m0saic/core/dist/core/buildMosaicNode.js +1 -1
  59. package/node_modules/@m0saic/core/dist/core/buildMosaicPlanFromFile.js +1 -1
  60. package/node_modules/@m0saic/core/dist/core/buildSvgTextSource.js +1 -1
  61. package/node_modules/@m0saic/core/dist/core/buildTextRenderCommand.js +1 -1
  62. package/node_modules/@m0saic/core/dist/core/collectRefTargets.js +1 -1
  63. package/node_modules/@m0saic/core/dist/core/index.js +1 -1
  64. package/node_modules/@m0saic/core/dist/core/maskCacheDir.js +1 -1
  65. package/node_modules/@m0saic/core/dist/core/maskWorkerBridge.js +1 -1
  66. package/node_modules/@m0saic/core/dist/core/playbackPlaySpeed.js +1 -1
  67. package/node_modules/@m0saic/core/dist/core/prepareProps.js +1 -1
  68. package/node_modules/@m0saic/core/dist/core/primaryOutput.js +1 -1
  69. package/node_modules/@m0saic/core/dist/core/rasterizeMaskPng.js +1 -1
  70. package/node_modules/@m0saic/core/dist/core/rasterizeSvgMediaPng.js +1 -1
  71. package/node_modules/@m0saic/core/dist/core/refTargetTap.js +1 -1
  72. package/node_modules/@m0saic/core/dist/core/resolveMasks.js +1 -1
  73. package/node_modules/@m0saic/core/dist/core/resolveMasksSync.js +1 -1
  74. package/node_modules/@m0saic/core/dist/core/resolveStrokeRingsSync.js +1 -1
  75. package/node_modules/@m0saic/core/dist/core/roundedRectMask.js +1 -1
  76. package/node_modules/@m0saic/core/dist/core/strokeRing.js +1 -1
  77. package/node_modules/@m0saic/core/dist/core/svgRaster.js +1 -1
  78. package/node_modules/@m0saic/core/dist/defaults.js +1 -1
  79. package/node_modules/@m0saic/core/dist/ffmpeg/backgroundImageInput.js +1 -1
  80. package/node_modules/@m0saic/core/dist/ffmpeg/bufferGuard.js +1 -1
  81. package/node_modules/@m0saic/core/dist/ffmpeg/ffmpegCommands.js +1 -1
  82. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBackdropBlur.js +1 -1
  83. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBlur.js +1 -1
  84. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBorderRadius.js +1 -1
  85. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyCamera.js +1 -1
  86. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyChromaKey.js +1 -1
  87. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyFade.js +1 -1
  88. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyGrade.js +1 -1
  89. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyMask.js +1 -1
  90. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyNoise.js +1 -1
  91. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyPixelize.js +1 -1
  92. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyRotate.js +1 -1
  93. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyStroke.js +1 -1
  94. package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyTileEffects.js +1 -1
  95. package/node_modules/@m0saic/core/dist/ffmpeg/filters/coverCrop.js +1 -1
  96. package/node_modules/@m0saic/core/dist/ffmpeg/filters/index.js +1 -1
  97. package/node_modules/@m0saic/core/dist/ffmpeg/filters/sourceRectCrop.js +1 -1
  98. package/node_modules/@m0saic/core/dist/ffmpeg/gridLowering.js +1 -1
  99. package/node_modules/@m0saic/core/dist/ffmpeg/index.js +1 -1
  100. package/node_modules/@m0saic/core/dist/ffmpeg/splitAvMux.js +1 -1
  101. package/node_modules/@m0saic/core/dist/ffmpeg/threadGuard.js +1 -1
  102. package/node_modules/@m0saic/core/dist/flatten/index.js +1 -1
  103. package/node_modules/@m0saic/core/dist/fs/index.js +1 -1
  104. package/node_modules/@m0saic/core/dist/fs/tempWorkspace.js +1 -1
  105. package/node_modules/@m0saic/core/dist/index.js +1 -1
  106. package/node_modules/@m0saic/core/dist/media/buildAssetManifestFromInputs.js +1 -1
  107. package/node_modules/@m0saic/core/dist/media/buildMediaRegistryFromInput.js +1 -1
  108. package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromInvocationProps.js +1 -1
  109. package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromMosaicRenderableFile.js +1 -1
  110. package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromProps.js +1 -1
  111. package/node_modules/@m0saic/core/dist/media/index.js +1 -1
  112. package/node_modules/@m0saic/core/dist/media/internalMintAsset.js +1 -1
  113. package/node_modules/@m0saic/core/dist/media/remoteUrl.js +1 -1
  114. package/node_modules/@m0saic/core/dist/media/stageUnsafeFilenames.js +1 -1
  115. package/node_modules/@m0saic/core/dist/media/types.js +1 -1
  116. package/node_modules/@m0saic/core/dist/output/index.js +1 -1
  117. package/node_modules/@m0saic/core/dist/output/resolveOutputFormat.js +1 -1
  118. package/node_modules/@m0saic/core/dist/output/types.js +1 -1
  119. package/node_modules/@m0saic/core/dist/probe/cellLuminanceProbe.js +1 -1
  120. package/node_modules/@m0saic/core/dist/probe/extractSubtitleCues.js +1 -1
  121. package/node_modules/@m0saic/core/dist/probe/helpers.js +1 -1
  122. package/node_modules/@m0saic/core/dist/probe/index.js +1 -1
  123. package/node_modules/@m0saic/core/dist/probe/luminanceProbe.js +1 -1
  124. package/node_modules/@m0saic/core/dist/probe/probeMedia.js +1 -1
  125. package/node_modules/@m0saic/core/dist/probe/runFFprobe.js +1 -1
  126. package/node_modules/@m0saic/core/dist/probe/types.js +1 -1
  127. package/node_modules/@m0saic/core/dist/runtime/engineRedaction.js +1 -1
  128. package/node_modules/@m0saic/core/dist/runtime/ffmpegFailure.js +1 -1
  129. package/node_modules/@m0saic/core/dist/runtime/filterPreflight.js +1 -1
  130. package/node_modules/@m0saic/core/dist/runtime/hashFile.js +1 -1
  131. package/node_modules/@m0saic/core/dist/runtime/index.js +1 -1
  132. package/node_modules/@m0saic/core/dist/runtime/pathInfo.js +1 -1
  133. package/node_modules/@m0saic/core/dist/runtime/perfHeatmap.js +1 -1
  134. package/node_modules/@m0saic/core/dist/runtime/perfReport.js +1 -1
  135. package/node_modules/@m0saic/core/dist/runtime/pipelineM0p.js +1 -1
  136. package/node_modules/@m0saic/core/dist/runtime/renderCostModel.constants.js +1 -1
  137. package/node_modules/@m0saic/core/dist/runtime/renderCostModel.js +1 -1
  138. package/node_modules/@m0saic/core/dist/runtime/renderReport.js +1 -1
  139. package/node_modules/@m0saic/core/dist/runtime/renderSidecars.js +1 -1
  140. package/node_modules/@m0saic/core/dist/runtime/resolveMosaicx.js +1 -1
  141. package/node_modules/@m0saic/core/dist/runtime/runPlan.js +1 -1
  142. package/node_modules/@m0saic/core/dist/runtime/types.js +1 -1
  143. package/node_modules/@m0saic/core/dist/runtime/upstream.js +1 -1
  144. package/node_modules/@m0saic/core/dist/runtime/writeSidecars.js +1 -1
  145. package/node_modules/@m0saic/core/dist/types/chunk.js +1 -1
  146. package/node_modules/@m0saic/core/dist/types/index.js +1 -1
  147. package/node_modules/@m0saic/core/dist/types/mosaic-plan.js +1 -1
  148. package/node_modules/@m0saic/core/dist/utils/assertTiming.js +1 -1
  149. package/node_modules/@m0saic/core/dist/utils/command.js +1 -1
  150. package/node_modules/@m0saic/core/dist/utils/createEngineContext.js +1 -1
  151. package/node_modules/@m0saic/core/dist/utils/createTemplateRenderCache.js +1 -1
  152. package/node_modules/@m0saic/core/dist/utils/ffmpegColor.js +1 -1
  153. package/node_modules/@m0saic/core/dist/utils/formatDuration.js +1 -1
  154. package/node_modules/@m0saic/core/dist/utils/fsSafeId.js +1 -1
  155. package/node_modules/@m0saic/core/dist/utils/index.js +1 -1
  156. package/node_modules/@m0saic/core/dist/utils/lowerRenderableToMosaicDocument.js +1 -1
  157. package/node_modules/@m0saic/core/dist/utils/movSafeCodec.js +1 -1
  158. package/node_modules/@m0saic/core/dist/utils/resolveBoxFrac.js +1 -1
  159. package/node_modules/@m0saic/core/dist/validate/index.js +1 -1
  160. package/node_modules/@m0saic/core/scripts/mask-rasterize-core.js +1 -1
  161. package/node_modules/@m0saic/core/scripts/mask-rasterize-worker.js +1 -1
  162. package/node_modules/@m0saic/core/scripts/mask-worker-thread.js +1 -1
  163. package/node_modules/@m0saic/dictionary/NOTICE +9 -0
  164. package/node_modules/@m0saic/dictionary/README.md +315 -0
  165. package/node_modules/@m0saic/dictionary/package.json +1 -1
  166. package/node_modules/@m0saic/dsl/package.json +1 -1
  167. package/node_modules/@m0saic/dsl-file-formats/dist/cjs/agent.js +6 -0
  168. package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0/parseM0File.js +1 -1
  169. package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0/serializeM0File.js +2 -2
  170. package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0c/m0cFile.js +3 -3
  171. package/node_modules/@m0saic/dsl-file-formats/dist/cjs/types.js +1 -1
  172. package/node_modules/@m0saic/dsl-file-formats/package.json +1 -1
  173. package/node_modules/@m0saic/dsl-stdlib/dist/cjs/builders/bakeM0cInsets.js +1 -0
  174. package/node_modules/@m0saic/dsl-stdlib/dist/cjs/builders/index.js +1 -1
  175. package/node_modules/@m0saic/dsl-stdlib/package.json +1 -1
  176. package/node_modules/@m0saic/knowledge/LICENSE +21 -0
  177. package/node_modules/@m0saic/knowledge/README.md +71 -0
  178. package/node_modules/@m0saic/knowledge/dist/index.js +1 -0
  179. package/node_modules/@m0saic/knowledge/docs/README.md +60 -0
  180. package/node_modules/@m0saic/knowledge/docs/file-formats/m0-iteration-protocol.md +120 -0
  181. package/node_modules/@m0saic/knowledge/docs/file-formats/m0p-and-custom-field.md +195 -0
  182. package/node_modules/@m0saic/knowledge/docs/handbook/README.md +27 -0
  183. package/node_modules/@m0saic/knowledge/docs/handbook/composition-arithmetic.md +278 -0
  184. package/node_modules/@m0saic/knowledge/docs/handbook/dsl-complexity.md +75 -0
  185. package/node_modules/@m0saic/knowledge/docs/handbook/dsl-rules.md +367 -0
  186. package/node_modules/@m0saic/knowledge/docs/handbook/feasibility-precision-quantization.md +591 -0
  187. package/node_modules/@m0saic/knowledge/docs/handbook/m0-construction-methods.md +201 -0
  188. package/node_modules/@m0saic/knowledge/docs/handbook/precision-tiers.md +84 -0
  189. package/node_modules/@m0saic/knowledge/docs/m0saic-thesis.md +95 -0
  190. package/node_modules/@m0saic/knowledge/docs/runtime/README.md +24 -0
  191. package/node_modules/@m0saic/knowledge/docs/runtime/agent-at-the-canvas.md +108 -0
  192. package/node_modules/@m0saic/knowledge/docs/runtime/cli-usage.md +475 -0
  193. package/node_modules/@m0saic/knowledge/docs/runtime/ffmpeg-expression-limits.md +117 -0
  194. package/node_modules/@m0saic/knowledge/docs/runtime/reduce-to-one.md +96 -0
  195. package/node_modules/@m0saic/knowledge/docs/skills/README.md +40 -0
  196. package/node_modules/@m0saic/knowledge/docs/skills/axis-and-geometry.md +103 -0
  197. package/node_modules/@m0saic/knowledge/docs/skills/dsl-stdlib-method-catalog.md +7 -0
  198. package/node_modules/@m0saic/knowledge/docs/skills/identity.md +123 -0
  199. package/node_modules/@m0saic/knowledge/docs/skills/labels-and-masks.md +170 -0
  200. package/node_modules/@m0saic/knowledge/docs/skills/m0saic-string-generation.md +251 -0
  201. package/node_modules/@m0saic/knowledge/docs/skills/more-atoms-not-bigger-atoms.md +77 -0
  202. package/node_modules/@m0saic/knowledge/docs/skills/overlay-semantics.md +194 -0
  203. package/node_modules/@m0saic/knowledge/docs/skills/parse-apis.md +79 -0
  204. package/node_modules/@m0saic/knowledge/docs/skills/passthrough-semantics.md +136 -0
  205. package/node_modules/@m0saic/knowledge/docs/skills/structural-construction.md +86 -0
  206. package/node_modules/@m0saic/knowledge/docs/skills/text-in-templates.md +126 -0
  207. package/node_modules/@m0saic/knowledge/docs/skills/zero-overlay-analysis.md +87 -0
  208. package/node_modules/@m0saic/knowledge/docs/templates/README.md +65 -0
  209. package/node_modules/@m0saic/knowledge/docs/templates/capability-templates.md +72 -0
  210. package/node_modules/@m0saic/knowledge/docs/templates/construction-strategy.md +329 -0
  211. package/node_modules/@m0saic/knowledge/docs/templates/data-pipeline.md +324 -0
  212. package/node_modules/@m0saic/knowledge/docs/templates/emission-patterns.md +130 -0
  213. package/node_modules/@m0saic/knowledge/docs/templates/geometry-recipes.md +248 -0
  214. package/node_modules/@m0saic/knowledge/docs/templates/layout-contract.md +168 -0
  215. package/node_modules/@m0saic/knowledge/docs/templates/output-resolution-tree.md +210 -0
  216. package/node_modules/@m0saic/knowledge/docs/templates/patterns/case-study-lessons.md +69 -0
  217. package/node_modules/@m0saic/knowledge/docs/templates/patterns/perf-authoring-rules.md +100 -0
  218. package/node_modules/@m0saic/knowledge/docs/templates/patterns/primitive-extraction-pattern.md +103 -0
  219. package/node_modules/@m0saic/knowledge/docs/templates/philosophy-and-contract.md +310 -0
  220. package/node_modules/@m0saic/knowledge/docs/templates/recursion-nested-rendering.md +154 -0
  221. package/node_modules/@m0saic/knowledge/docs/templates/reference/grid.md +104 -0
  222. package/node_modules/@m0saic/knowledge/docs/templates/reference/json-prop-type.md +169 -0
  223. package/node_modules/@m0saic/knowledge/docs/templates/reference/mosaic-color.md +81 -0
  224. package/node_modules/@m0saic/knowledge/docs/templates/reference/mosaic-placement-props.md +103 -0
  225. package/node_modules/@m0saic/knowledge/docs/templates/reference/prop-bindings.md +338 -0
  226. package/node_modules/@m0saic/knowledge/docs/templates/reference/template-flags.md +236 -0
  227. package/node_modules/@m0saic/knowledge/docs/templates/render-lifecycle.md +117 -0
  228. package/node_modules/@m0saic/knowledge/docs/templates/rendering-model-contract.md +392 -0
  229. package/node_modules/@m0saic/knowledge/docs/templates/standalone-pack-authoring.md +309 -0
  230. package/node_modules/@m0saic/knowledge/docs/templates/theming.md +81 -0
  231. package/node_modules/@m0saic/knowledge/docs/templates/ui-controls.md +150 -0
  232. package/node_modules/@m0saic/knowledge/package.json +6 -0
  233. package/node_modules/@m0saic/momo-types/README.md +109 -0
  234. package/node_modules/@m0saic/momo-types/dist/agent.js +1 -6
  235. package/node_modules/@m0saic/momo-types/dist/context.js +1 -1
  236. package/node_modules/@m0saic/momo-types/package.json +1 -1
  237. package/node_modules/@m0saic/platform/README.md +3 -0
  238. package/node_modules/@m0saic/platform/dist/cjs/index.js +1 -1
  239. package/node_modules/@m0saic/platform/dist/cjs/mosaic/outputKind/outputKind.js +1 -1
  240. package/node_modules/@m0saic/platform/dist/cjs/mosaic/propBindings/index.js +1 -1
  241. package/node_modules/@m0saic/platform/dist/cjs/mosaic/propBindings/propBindings.js +1 -1
  242. package/node_modules/@m0saic/platform/dist/cjs/mosaic/validate/validateSources.js +1 -1
  243. package/node_modules/@m0saic/platform/dist/cjs/packages/mosaicPackages.js +1 -0
  244. package/node_modules/@m0saic/platform/dist/cjs/paths/m0saicRoot.js +1 -1
  245. package/node_modules/@m0saic/platform/dist/cjs/telemetry/lifecycle.js +1 -1
  246. package/node_modules/@m0saic/platform/dist/cjs/telemetry/preview.js +1 -1
  247. package/node_modules/@m0saic/platform/dist/cjs/telemetry/sender.js +1 -1
  248. package/node_modules/@m0saic/platform/dist/cjs/telemetry/usageRecorder.js +1 -1
  249. package/node_modules/@m0saic/platform/dist/cjs/telemetry/usageStore.js +3 -3
  250. package/node_modules/@m0saic/platform/dist/cjs/template-repos/index.js +1 -1
  251. package/node_modules/@m0saic/platform/dist/cjs/template-repos/loadTemplateRepoFromPath.js +4 -4
  252. package/node_modules/@m0saic/platform/dist/cjs/template-repos/templateCatalogSidecars.js +2 -0
  253. package/node_modules/@m0saic/platform/dist/cjs/templateCatalog/index.js +1 -0
  254. package/node_modules/@m0saic/platform/dist/cjs/templateCatalog/templateCatalog.js +1 -0
  255. package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/baseline.json +25 -97
  256. package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/index.js +1 -1
  257. package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/install.js +2 -2
  258. package/node_modules/@m0saic/platform/dist/cjs/toolchain/goldenFfmpeg.js +6 -6
  259. package/node_modules/@m0saic/platform/package.json +1 -1
  260. package/node_modules/@m0saic/product/dist/communityRelease.js +1 -1
  261. package/node_modules/@m0saic/product/dist/freeTierLicense.js +1 -1
  262. package/node_modules/@m0saic/product/dist/index.js +1 -1
  263. package/node_modules/@m0saic/product/dist/licenseActivationNotice.js +1 -0
  264. package/node_modules/@m0saic/product/dist/licenseFile.js +1 -0
  265. package/node_modules/@m0saic/product/dist/licenseToken.js +1 -1
  266. package/node_modules/@m0saic/product/dist/makeScratchPath.js +1 -0
  267. package/node_modules/@m0saic/product/dist/postRenderWrapper.js +1 -1
  268. package/node_modules/@m0saic/product/dist/publicKeys.js +1 -1
  269. package/node_modules/@m0saic/product/dist/revokedKeys.js +1 -1
  270. package/node_modules/@m0saic/product/dist/upstreamDefaults.js +1 -1
  271. package/node_modules/@m0saic/product/dist/workspaceScaffold.js +1 -0
  272. package/node_modules/@m0saic/template-utils/dist/brand/hello-world/helloWorld.js +1 -1
  273. package/node_modules/@m0saic/template-utils/dist/geometry-contract/frameResolution.js +1 -1
  274. package/node_modules/@m0saic/template-utils/dist/geometry-contract/index.js +1 -1
  275. package/node_modules/@m0saic/template-utils/dist/geometry-contract/layoutConstraint.js +2 -2
  276. package/node_modules/@m0saic/template-utils/dist/m0saic/loadSession.js +1 -1
  277. package/node_modules/@m0saic/template-utils/dist/render/createDesignContext.js +1 -1
  278. package/node_modules/@m0saic/template-utils/dist/sources/makeErrorMosaic.js +2 -2
  279. package/node_modules/@m0saic/template-utils/dist/sources/svgTextSource.js +1 -1
  280. package/node_modules/@m0saic/template-utils/dist/template/auditRenderedTemplate.js +5 -5
  281. package/node_modules/@m0saic/template-utils/dist/template/auditSchemaConventions.js +1 -1
  282. package/node_modules/@m0saic/template-utils/dist/template/defineMosaicTemplate.js +1 -1
  283. package/node_modules/@m0saic/template-utils/dist/template/resolveTemplateOutputHints.js +1 -1
  284. package/node_modules/@m0saic/template-utils/dist/template/templateCatalogStore.js +1 -0
  285. package/node_modules/@m0saic/template-utils/dist/template/templateConventions.js +4 -4
  286. package/node_modules/@m0saic/template-utils/dist/template/templateRegistry.js +3 -3
  287. package/node_modules/@m0saic/template-utils/dist/template/validateTemplateProps.js +1 -1
  288. package/node_modules/@m0saic/template-utils/dist/text/fitText.js +6 -6
  289. package/node_modules/@m0saic/template-utils/package.json +1 -1
  290. package/node_modules/@m0saic/templates/NOTICE +9 -0
  291. package/node_modules/@m0saic/templates/dist/catalog.js +1 -0
  292. package/node_modules/@m0saic/templates/dist/freeze.js +8 -8
  293. package/node_modules/@m0saic/templates/dist/index.js +1 -1
  294. package/node_modules/@m0saic/templates/dist/m0saic/_shared/canvas-handles.js +1 -0
  295. package/node_modules/@m0saic/templates/dist/m0saic/_shared/stand-in.js +1 -0
  296. package/node_modules/@m0saic/templates/dist/m0saic/agents/commit-feed/index.js +1 -1
  297. package/node_modules/@m0saic/templates/dist/m0saic/agents/commit-feed/v2/commit-feed.js +1 -0
  298. package/node_modules/@m0saic/templates/dist/m0saic/agents/commit-feed/v2/index.js +1 -0
  299. package/node_modules/@m0saic/templates/dist/m0saic/agents/trace-timeline/index.js +1 -1
  300. package/node_modules/@m0saic/templates/dist/m0saic/agents/trace-timeline/v2/index.js +1 -0
  301. package/node_modules/@m0saic/templates/dist/m0saic/agents/trace-timeline/v2/trace-timeline.js +1 -0
  302. package/node_modules/@m0saic/templates/dist/m0saic/alpine/_shared/alpine-conventions.js +1 -0
  303. package/node_modules/@m0saic/templates/dist/m0saic/alpine/bar-graph/v2/bar-graph.js +1 -0
  304. package/node_modules/@m0saic/templates/dist/m0saic/alpine/bar-graph/v2/index.js +1 -0
  305. package/node_modules/@m0saic/templates/dist/m0saic/alpine/commit-feed/v3/commit-feed.js +1 -0
  306. package/node_modules/@m0saic/templates/dist/m0saic/alpine/commit-feed/v3/index.js +1 -0
  307. package/node_modules/@m0saic/templates/dist/m0saic/alpine/contributor-table/v2/contributor-table.js +1 -0
  308. package/node_modules/@m0saic/templates/dist/m0saic/alpine/contributor-table/v2/index.js +1 -0
  309. package/node_modules/@m0saic/templates/dist/m0saic/alpine/donut/v4/donut.js +1 -0
  310. package/node_modules/@m0saic/templates/dist/m0saic/alpine/donut/v4/index.js +1 -0
  311. package/node_modules/@m0saic/templates/dist/m0saic/alpine/heatmap/v3/heatmap.js +1 -0
  312. package/node_modules/@m0saic/templates/dist/m0saic/alpine/heatmap/v3/index.js +1 -0
  313. package/node_modules/@m0saic/templates/dist/m0saic/alpine/index.js +1 -1
  314. package/node_modules/@m0saic/templates/dist/m0saic/alpine/kpi-card/v3/index.js +1 -0
  315. package/node_modules/@m0saic/templates/dist/m0saic/alpine/kpi-card/v3/kpi-card.js +1 -0
  316. package/node_modules/@m0saic/templates/dist/m0saic/alpine/leaderboard/v2/index.js +1 -0
  317. package/node_modules/@m0saic/templates/dist/m0saic/alpine/leaderboard/v2/leaderboard.js +1 -0
  318. package/node_modules/@m0saic/templates/dist/m0saic/alpine/line-chart/v3/index.js +1 -0
  319. package/node_modules/@m0saic/templates/dist/m0saic/alpine/line-chart/v3/line-chart.js +1 -0
  320. package/node_modules/@m0saic/templates/dist/m0saic/alpine/progress-card/v2/index.js +1 -0
  321. package/node_modules/@m0saic/templates/dist/m0saic/alpine/progress-card/v2/progress-card.js +1 -0
  322. package/node_modules/@m0saic/templates/dist/m0saic/alpine/stat-card/v2/index.js +1 -0
  323. package/node_modules/@m0saic/templates/dist/m0saic/alpine/stat-card/v2/stat-card.js +1 -0
  324. package/node_modules/@m0saic/templates/dist/m0saic/alpine/timeline/v3/index.js +1 -0
  325. package/node_modules/@m0saic/templates/dist/m0saic/alpine/timeline/v3/timeline.js +4 -0
  326. package/node_modules/@m0saic/templates/dist/m0saic/alpine/treemap/v3/index.js +1 -0
  327. package/node_modules/@m0saic/templates/dist/m0saic/alpine/treemap/v3/treemap.js +1 -0
  328. package/node_modules/@m0saic/templates/dist/m0saic/benchmark/index.js +1 -1
  329. package/node_modules/@m0saic/templates/dist/m0saic/benchmark/report/v2/index.js +1 -0
  330. package/node_modules/@m0saic/templates/dist/m0saic/benchmark/report/v2/report.js +1 -0
  331. package/node_modules/@m0saic/templates/dist/m0saic/brand/business-card/v2/business-card.js +1 -0
  332. package/node_modules/@m0saic/templates/dist/m0saic/brand/business-card/v2/index.js +1 -0
  333. package/node_modules/@m0saic/templates/dist/m0saic/brand/index.js +1 -1
  334. package/node_modules/@m0saic/templates/dist/m0saic/brand/logo/v4/index.js +1 -0
  335. package/node_modules/@m0saic/templates/dist/m0saic/brand/logo/v4/logo_runner.js +1 -0
  336. package/node_modules/@m0saic/templates/dist/m0saic/charts/bar-graph/v3/bar-graph.js +1 -0
  337. package/node_modules/@m0saic/templates/dist/m0saic/charts/bar-graph/v3/index.js +1 -0
  338. package/node_modules/@m0saic/templates/dist/m0saic/charts/donut/v5/donut.js +1 -0
  339. package/node_modules/@m0saic/templates/dist/m0saic/charts/donut/v5/index.js +1 -0
  340. package/node_modules/@m0saic/templates/dist/m0saic/charts/index.js +1 -1
  341. package/node_modules/@m0saic/templates/dist/m0saic/charts/line-chart/v2/index.js +1 -0
  342. package/node_modules/@m0saic/templates/dist/m0saic/charts/line-chart/v2/line-chart.js +1 -0
  343. package/node_modules/@m0saic/templates/dist/m0saic/charts/stat-card/v2/index.js +1 -0
  344. package/node_modules/@m0saic/templates/dist/m0saic/charts/stat-card/v2/stat-card.js +1 -0
  345. package/node_modules/@m0saic/templates/dist/m0saic/code/index.js +1 -1
  346. package/node_modules/@m0saic/templates/dist/m0saic/code/snippet-morph/v2/snippet-morph.js +3 -0
  347. package/node_modules/@m0saic/templates/dist/m0saic/collage/image-collage/v2/image-collage.js +1 -0
  348. package/node_modules/@m0saic/templates/dist/m0saic/collage/image-collage/v2/index.js +1 -0
  349. package/node_modules/@m0saic/templates/dist/m0saic/collage/index.js +1 -1
  350. package/node_modules/@m0saic/templates/dist/m0saic/dsl-tutorial/index.js +1 -1
  351. package/node_modules/@m0saic/templates/dist/m0saic/dsl-tutorial/v2/dsl-tutorial.js +1 -0
  352. package/node_modules/@m0saic/templates/dist/m0saic/dsl-tutorial/v2/index.js +1 -0
  353. package/node_modules/@m0saic/templates/dist/m0saic/github/year-card/index.js +1 -1
  354. package/node_modules/@m0saic/templates/dist/m0saic/github/year-card/v2/index.js +1 -0
  355. package/node_modules/@m0saic/templates/dist/m0saic/github/year-card/v2/year-card.js +1 -0
  356. package/node_modules/@m0saic/templates/dist/m0saic/hero/ffmpeg-pulse/index.js +1 -1
  357. package/node_modules/@m0saic/templates/dist/m0saic/hero/ffmpeg-pulse/runner/v2/index.js +1 -0
  358. package/node_modules/@m0saic/templates/dist/m0saic/hero/ffmpeg-pulse/runner/v2/runner.js +1 -0
  359. package/node_modules/@m0saic/templates/dist/m0saic/media/barcode/v2/barcode.js +1 -0
  360. package/node_modules/@m0saic/templates/dist/m0saic/media/barcode/v2/index.js +1 -0
  361. package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/index.js +1 -1
  362. package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v1/tutorial.js +1 -1
  363. package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v2/blur-regions.js +1 -0
  364. package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v2/index.js +1 -0
  365. package/node_modules/@m0saic/templates/dist/m0saic/media/highlights/index.js +1 -1
  366. package/node_modules/@m0saic/templates/dist/m0saic/media/highlights/v2/highlights.js +1 -0
  367. package/node_modules/@m0saic/templates/dist/m0saic/media/highlights/v2/index.js +1 -0
  368. package/node_modules/@m0saic/templates/dist/m0saic/media/index.js +1 -1
  369. package/node_modules/@m0saic/templates/dist/m0saic/media/logo-animate/index.js +1 -1
  370. package/node_modules/@m0saic/templates/dist/m0saic/media/logo-animate/v2/index.js +1 -0
  371. package/node_modules/@m0saic/templates/dist/m0saic/media/logo-animate/v2/logo-animate.js +1 -0
  372. package/node_modules/@m0saic/templates/dist/m0saic/media/metadata-stamp/index.js +1 -1
  373. package/node_modules/@m0saic/templates/dist/m0saic/media/metadata-stamp/v2/index.js +1 -0
  374. package/node_modules/@m0saic/templates/dist/m0saic/media/metadata-stamp/v2/metadata-stamp.js +1 -0
  375. package/node_modules/@m0saic/templates/dist/m0saic/media/qr/code/v2/index.js +1 -0
  376. package/node_modules/@m0saic/templates/dist/m0saic/media/qr/code/v2/qr-code.js +1 -0
  377. package/node_modules/@m0saic/templates/dist/m0saic/media/qr/index.js +1 -1
  378. package/node_modules/@m0saic/templates/dist/m0saic/media/qr/stamp/v2/qr-stamp-custom.js +1 -0
  379. package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid/index.js +1 -1
  380. package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid/v3/index.js +1 -0
  381. package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid/v3/screencap-grid.js +4 -0
  382. package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid_aspect_safe/index.js +1 -1
  383. package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid_aspect_safe/v2/index.js +1 -0
  384. package/node_modules/@m0saic/templates/dist/m0saic/media/screencap_grid_aspect_safe/v2/screencap-grid-aspect-safe.js +3 -0
  385. package/node_modules/@m0saic/templates/dist/m0saic/media/scroll_wall/index.js +1 -1
  386. package/node_modules/@m0saic/templates/dist/m0saic/media/scroll_wall/v2/index.js +1 -0
  387. package/node_modules/@m0saic/templates/dist/m0saic/media/scroll_wall/v2/scroll-wall.js +1 -0
  388. package/node_modules/@m0saic/templates/dist/m0saic/media/subtitle-burn/index.js +1 -1
  389. package/node_modules/@m0saic/templates/dist/m0saic/media/subtitle-burn/v2/index.js +1 -0
  390. package/node_modules/@m0saic/templates/dist/m0saic/media/subtitle-burn/v2/subtitle-burn.js +4 -0
  391. package/node_modules/@m0saic/templates/dist/m0saic/media/trickplay/index.js +1 -1
  392. package/node_modules/@m0saic/templates/dist/m0saic/media/trickplay/v2/index.js +1 -0
  393. package/node_modules/@m0saic/templates/dist/m0saic/media/trickplay/v2/trickplay.js +1 -0
  394. package/node_modules/@m0saic/templates/dist/m0saic/media/video_to_png_sequence/index.js +1 -1
  395. package/node_modules/@m0saic/templates/dist/m0saic/media/video_to_png_sequence/v2/index.js +1 -0
  396. package/node_modules/@m0saic/templates/dist/m0saic/media/video_to_png_sequence/v2/video-to-png-sequence.js +1 -0
  397. package/node_modules/@m0saic/templates/dist/m0saic/media/watermark/index.js +1 -1
  398. package/node_modules/@m0saic/templates/dist/m0saic/media/watermark/v2/index.js +1 -0
  399. package/node_modules/@m0saic/templates/dist/m0saic/media/watermark/v2/watermark.js +1 -0
  400. package/node_modules/@m0saic/templates/dist/m0saic/primitives/grid/index.js +1 -1
  401. package/node_modules/@m0saic/templates/dist/m0saic/primitives/grid/v3/grid.js +1 -0
  402. package/node_modules/@m0saic/templates/dist/m0saic/social/quote-card/index.js +1 -1
  403. package/node_modules/@m0saic/templates/dist/m0saic/social/quote-card/v2/index.js +1 -0
  404. package/node_modules/@m0saic/templates/dist/m0saic/social/quote-card/v2/quote-card.js +1 -0
  405. package/node_modules/@m0saic/templates/dist/m0saic/story/index.js +1 -1
  406. package/node_modules/@m0saic/templates/dist/m0saic/story/narrated-chapters/index.js +1 -1
  407. package/node_modules/@m0saic/templates/dist/m0saic/story/narrated-chapters/v2/index.js +1 -0
  408. package/node_modules/@m0saic/templates/dist/m0saic/story/narrated-chapters/v2/narrated-chapters.js +4 -0
  409. package/node_modules/@m0saic/templates/dist/m0saic/story/scrapbook/v2/index.js +1 -0
  410. package/node_modules/@m0saic/templates/dist/m0saic/story/scrapbook/v2/props.js +1 -0
  411. package/node_modules/@m0saic/templates/dist/m0saic/story/scrapbook/v2/scrapbook.js +1 -0
  412. package/node_modules/@m0saic/templates/dist/m0saic/theming/index.js +1 -1
  413. package/node_modules/@m0saic/templates/dist/m0saic/theming/v2/index.js +1 -0
  414. package/node_modules/@m0saic/templates/dist/m0saic/theming/v2/theming.js +1 -0
  415. package/node_modules/@m0saic/templates/dist/m0saic/web/index.js +1 -1
  416. package/node_modules/@m0saic/templates/dist/m0saic/web/page-skeleton/v2/index.js +1 -0
  417. package/node_modules/@m0saic/templates/dist/m0saic/web/page-skeleton/v2/page-skeleton.js +1 -0
  418. package/node_modules/@m0saic/templates/dist/m0saic/wireframe/base/v3/index.js +1 -0
  419. package/node_modules/@m0saic/templates/dist/m0saic/wireframe/base/v3/wireframe.js +1 -0
  420. package/node_modules/@m0saic/templates/dist/m0saic/wireframe/index.js +1 -1
  421. package/node_modules/@m0saic/templates/dist/repo.js +1 -1
  422. package/node_modules/@m0saic/templates/dist/template-catalog.json +5429 -0
  423. package/node_modules/@m0saic/templates/dist/template-registry.js +1 -1
  424. package/node_modules/@m0saic/templates/dist/web.js +1 -1
  425. package/node_modules/@m0saic/templates/package.json +1 -1
  426. package/node_modules/@m0saic/templates/template-catalog.json +5429 -0
  427. package/node_modules/@m0saic/templates/template-manifest.json +1030 -286
  428. package/node_modules/@m0saic/templates/web-template-ids.json +38 -0
  429. package/node_modules/@m0saic/templates-advanced/NOTICE +9 -0
  430. package/node_modules/@m0saic/text/package.json +1 -1
  431. package/node_modules/@m0saic/types/dist/analytics/consent.js +1 -1
  432. package/node_modules/@m0saic/types/dist/analytics/event.js +1 -1
  433. package/node_modules/@m0saic/types/dist/analytics/usageMetrics.js +1 -1
  434. package/node_modules/@m0saic/types/dist/identifiers/identifiers.js +1 -1
  435. package/node_modules/@m0saic/types/dist/telemetry/ffmpegFailure.js +1 -1
  436. package/node_modules/@m0saic/types/dist/template/template.js +1 -1
  437. package/node_modules/@m0saic/types/package.json +1 -1
  438. package/node_modules/@m0saic/types-internal/dist/analytics/featureKeys.js +1 -1
  439. package/package.json +13 -11
  440. package/resources/starter-base/starter-base.json +10 -0
  441. package/resources/starter-base/starter-base.tgz +0 -0
@@ -0,0 +1,251 @@
1
+ # m0 Generator Guidelines
2
+
3
+ Practical algorithm outline for generating valid m0 strings programmatically. **Prefer official helpers over hand-emitting tokens.**
4
+
5
+ > **Source of truth:**
6
+ > - Builders: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/builders](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/builders)
7
+ > - Unified transforms: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/unified](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/unified)
8
+ > - Validation: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate)
9
+ > - Feasibility: [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/feasibility](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/feasibility)
10
+
11
+ ---
12
+
13
+ ## 0. Prime directives
14
+
15
+ ### 0.1 Prefer library ops over hand-writing strings
16
+
17
+ If an official op/helper exists for the transformation you want, **use it** instead of emitting raw m0 tokens.
18
+
19
+ Three primary sources of safe generation:
20
+
21
+ - **`@m0saic/dsl-stdlib/builders`** — high-level builders (`grid`, `weightedSplit`, `strip`, `container`, `aspectFit`, `placeRect`/`placeRects`, `rectsToM0`, `safeCanvas`, `snapGridFit`, `spotlight`, `comparison`, `rankedList`, `goldenSplit`, `goldenSpiral`, etc.). Full surface: see [`dsl-stdlib-method-catalog.md`](./dsl-stdlib-method-catalog.md).
22
+ - **`@m0saic/dsl-stdlib/transforms`** — unified ops (`split`, `replace`, `addOverlay`, `removeOverlay`, `setTileType`, `measureSplit`, `swapFrames`).
23
+ - **`@m0saic/dsl`** — low-level parsing + validation; never the right tool for *generation*.
24
+
25
+ Raw string emission is a **last resort.**
26
+
27
+ ### 0.2 Use `grid` for grids
28
+
29
+ For row/column grids (equal cells, weighted cells, gutters, outer gutters), call:
30
+
31
+ ```ts
32
+ import { grid } from "@m0saic/dsl-stdlib";
33
+
34
+ const result = grid({ rows: 3, cols: 4, gutter: 0.05 });
35
+ // result.m0 — canonical m0 string
36
+ // result.totalX, result.totalY — split factors
37
+ // result.cellW, result.gutterW — resolved weights
38
+ ```
39
+
40
+ The builder handles weighted-split expansion via `0` carry runs, gutter `-` slots, the illegal `1(...)` / `1[...]` rule, exact classifier-count = child-slot count, and canonical output. **Don't hand-author split trees.**
41
+
42
+ Workflow: build the base layout with a builder, apply targeted edits with unified transforms, validate.
43
+
44
+ ---
45
+
46
+ ## 1. Validation and feasibility
47
+
48
+ ### 1.1 Always validate
49
+
50
+ ```ts
51
+ import { validateM0String } from "@m0saic/dsl";
52
+
53
+ const v = validateM0String(m0);
54
+ if (!v.ok) {
55
+ // v.error is a single structured violation: { code, kind, message, ... }
56
+ // (singular — https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts M0ValidationResult)
57
+ }
58
+ ```
59
+
60
+ Boolean shortcut: `isValidM0String(m0)`.
61
+
62
+ The validator enforces grammar, token rules, overlay correctness, child-count exactness, the trailing-passthrough rule (trailing `0` is always invalid, even with overlay), and the no-sources rule (≥1 leaf `1` required somewhere in the layout). Overlay bodies do NOT need their own source — sourceless bodies like `1{-}` are legal (relaxed 2026-06-03; see [`overlay-semantics.md`](overlay-semantics.md)). See [`handbook/dsl-rules.md`](../handbook/dsl-rules.md) for the full grammar.
63
+
64
+ ### 1.2 Check feasibility when dimensions are known
65
+
66
+ ```ts
67
+ import { computeFeasibility } from "@m0saic/dsl";
68
+
69
+ const f = computeFeasibility(m0);
70
+ if (targetWidth < f.minWidthPx || targetHeight < f.minHeightPx) {
71
+ // Layout cannot render at this resolution — would produce 0-size frames.
72
+ throw new Error(`Below feasible: ${f.minWidthPx}×${f.minHeightPx}`);
73
+ }
74
+ ```
75
+
76
+ If you parse anyway, `parseM0StringComplete` emits `SPLIT_EXCEEDS_AXIS` at parse time:
77
+
78
+ ```ts
79
+ import { parseM0StringComplete } from "@m0saic/dsl";
80
+
81
+ const parsed = parseM0StringComplete(m0, width, height);
82
+ // parsed.precision, parsed.warnings, optional parsed.error
83
+ ```
84
+
85
+ ### 1.3 Feasibility vs. precision (important distinction)
86
+
87
+ - **`computeFeasibility`** — exact `{ minWidthPx, minHeightPx }`. Accounts for nested same-axis splits, passthrough carry chains, overlays. Use for all feasibility decisions.
88
+ - **Precision** is a separate, independent floor (neither bounds the other). For a combined verdict use `evaluateM0` from `@m0saic/dsl-stdlib` — it returns `feasible`, `meetsPrecision`, and `recommendedMin` (the per-axis max of both floors). (`computePrecisionFromString` is an internal dsl helper, not public API.)
89
+
90
+ See [`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md) (canonical) for the two-floor model.
91
+
92
+ ---
93
+
94
+ ## 2. Unified transforms — the canonical API for structural changes
95
+
96
+ When you mutate an existing string, use the unified transforms exported from `@m0saic/dsl-stdlib`. Every transform takes `(m0, target, options) → m0` where `target: TransformTarget` is a discriminated union.
97
+
98
+ ### TransformTarget
99
+
100
+ ```ts
101
+ type TransformTarget =
102
+ | { by: "logicalIndex"; index: number } // 0-based index of rendered frames (1/F only)
103
+ | { by: "span"; span: { start: number; end: number } } // exact char span
104
+ | { by: "stableKey"; key: string }; // structural identity path
105
+ ```
106
+
107
+ Pick the addressing mode that matches your invariant — `logicalIndex` for "the Nth rendered tile," `stableKey` for "this specific node, even after edits," `span` for parser-visible ranges. See [`../file-formats/m0p-and-custom-field.md`](../file-formats/m0p-and-custom-field.md) and [`identity.md`](identity.md) for identity semantics.
108
+
109
+ ### 2.1 Split
110
+
111
+ ```ts
112
+ import { split } from "@m0saic/dsl-stdlib";
113
+
114
+ // Uniform 3-way column split on the 0th tile
115
+ split(m0, { by: "logicalIndex", index: 0 }, { axis: "col", count: 3 });
116
+
117
+ // Weighted split: weights.length must equal count
118
+ split(m0, { by: "logicalIndex", index: 0 }, { axis: "col", count: 2, weights: [60, 40] });
119
+ ```
120
+
121
+ GCD-reduces emitted DSL by default. Pass `weightMode: "literal"` to preserve exact slot count.
122
+
123
+ ### 2.2 Measure-mode split
124
+
125
+ ```ts
126
+ import { measureSplit } from "@m0saic/dsl-stdlib";
127
+
128
+ // axis "col" or "row"; count = granularity; ranges are {a, b} objects (inclusive)
129
+ // (MeasureSplitOptions — https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/unified/measureSplit.ts#L9)
130
+ measureSplit(m0, { by: "logicalIndex", index: 1 }, { axis: "row", count: 12, ranges: [{ a: 2, b: 8 }] });
131
+ ```
132
+
133
+ ### 2.3 Set leaf type
134
+
135
+ ```ts
136
+ import { setTileType } from "@m0saic/dsl-stdlib";
137
+
138
+ // Change a leaf to "-" (null), ">" (passthrough), "F" (frame), or "1"
139
+ setTileType(m0, { by: "logicalIndex", index: 0 }, "-");
140
+ setTileType(m0, { by: "stableKey", key: "r/growc0/fc1" }, ">");
141
+ ```
142
+
143
+ ### 2.4 Add / remove overlay
144
+
145
+ ```ts
146
+ import { addOverlay, removeOverlay } from "@m0saic/dsl-stdlib";
147
+
148
+ addOverlay(m0, { by: "logicalIndex", index: 2 }); // visual overlay
149
+ removeOverlay(m0, { by: "stableKey", key: "r/fc2" });
150
+ ```
151
+
152
+ ### 2.5 Replace / swap
153
+
154
+ ```ts
155
+ import { replace, swapFrames } from "@m0saic/dsl-stdlib";
156
+
157
+ replace(m0, { by: "logicalIndex", index: 0 }, "2(F,F)"); // replace subtree at target
158
+ swapFrames(m0, 0, 1); // swap rendered tiles — takes two logicalIndex numbers
159
+ // directly, NOT a TransformTarget (the one exception to §2)
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 3. Repair-loop strategy
165
+
166
+ When validation fails, apply targeted repairs instead of regenerating from scratch.
167
+
168
+ ### 3.1 ILLEGAL_ONE_SPLIT
169
+
170
+ Problem: `1(...)` or `1[...]` — wrapping a single child as a pseudo-container is illegal.
171
+
172
+ Fix: drop the `1(...)` wrapper or use `0`-runs instead.
173
+
174
+ ### 3.2 Trailing passthrough
175
+
176
+ Problem: last child in a split is `0` (even with overlay — `0{...}` trailing is always invalid).
177
+
178
+ Fix:
179
+ - Replace trailing `0` with `-`: `2(1,0)` → `2(1,-)`
180
+ - Or replace trailing `0` with `1`: `2(1,0)` → `2(1,1)`
181
+
182
+ Don't use `2(1,0{1})` — trailing passthrough with overlay is still invalid.
183
+
184
+ ### 3.3 TOKEN_COUNT mismatch
185
+
186
+ Problem: classifier `N` doesn't match the number of children.
187
+
188
+ Fix: adjust `N` to match children, or add/remove children to match `N`.
189
+
190
+ ### 3.4 SPLIT_EXCEEDS_AXIS
191
+
192
+ Problem: classifier count exceeds available pixels on an axis.
193
+
194
+ Fixes (in order):
195
+ 1. Reduce split count.
196
+ 2. Collapse subtree to `1`.
197
+ 3. Replace with fewer parts.
198
+
199
+ ### 3.5 NO_SOURCES
200
+
201
+ Problem: the layout as a whole contains no leaf `1` (overlay bodies are allowed to be
202
+ sourceless — `ZERO_SOURCE_OVERLAY` is no longer raised).
203
+
204
+ Fix: ensure at least one `1` / `F` exists somewhere (a source inside an overlay counts:
205
+ `2(-,-){1}` is valid). See [`overlay-semantics.md`](overlay-semantics.md).
206
+
207
+ ### 3.6 INVALID_CHAR / TOKEN_RULE
208
+
209
+ Problem: malformed output. **Generator bug** — fix the generation logic, don't band-aid the output.
210
+
211
+ ---
212
+
213
+ ## 4. Overlay body constraints
214
+
215
+ Bodies are parsed as complete m0 sub-expressions: non-empty, not a bare `0`
216
+ (`INVALID_EMPTY`), no trailing passthrough — but they do **NOT** need a leaf `1`
217
+ (sourceless `{-}` / `{2(-,-)}` are legal; relaxed 2026-06-03). Full rules:
218
+ [`overlay-semantics.md`](overlay-semantics.md) and
219
+ [`structural-construction.md`](structural-construction.md) §7.
220
+
221
+ ---
222
+
223
+ ## 5. Output format options
224
+
225
+ Most ops accept output options:
226
+
227
+ ```ts
228
+ { output: "canonical" } // 1, 0
229
+ { output: "pretty" } // F, >
230
+ ```
231
+
232
+ Agents should prefer canonical output for machine use unless pretty is explicitly required.
233
+
234
+ ---
235
+
236
+ ## 6. Precision warnings
237
+
238
+ High classifier counts emit `PRECISION_EXCEEDS_NORM` warnings (informational, never
239
+ blocking; raise the threshold via `parseM0StringComplete(s, w, h, { precisionNorm: 256 })`).
240
+ The two-floor feasibility/precision model:
241
+ [`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md).
242
+
243
+ ---
244
+
245
+ ## See also
246
+
247
+ - [`../handbook/dsl-rules.md`](../handbook/dsl-rules.md) — full grammar.
248
+ - [`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md) — feasibility rules (canonical).
249
+ - [`structural-construction.md`](structural-construction.md) — structural-build patterns.
250
+ - [`overlay-semantics.md`](overlay-semantics.md) — overlay rules.
251
+ - [`parse-apis.md`](parse-apis.md) — parser entry points.
@@ -0,0 +1,77 @@
1
+ # More atoms, never bigger atoms — the scaling contract with ffmpeg
2
+
3
+ > The measured cliffs behind atom 1 (and the "graph-size OOM" debunk) live in
4
+ > [`../runtime/ffmpeg-expression-limits.md`](../runtime/ffmpeg-expression-limits.md).
5
+ > This is the general principle; that is the case study.
6
+
7
+ m0saic renders arbitrarily complex templates by splitting work into pieces.
8
+ That works because ffmpeg capacity scales with the NUMBER of things it is
9
+ given (commands, inputs, filters, files). It breaks when a feature grows a
10
+ single UNPARTITIONABLE ATOM with content. Chunking cannot rescue a bigger
11
+ atom — the atom is smaller than a command.
12
+
13
+ ## The four atoms (with measured walls)
14
+
15
+ 1. **One expression string.** `av_expr_parse` has a ~100 recursion budget:
16
+ ~98 flat `+` terms or ~100 nesting levels, independent of char length.
17
+ Failure is a phantom `Cannot allocate memory` (−12) or `Invalid
18
+ argument` (−22) at graph init, in <80 ms. Applies to EVERY expression:
19
+ `enable`, `geq`, crop/scale/drawtext params, `%{eif}`.
20
+ 2. **One filter's per-frame work.** `geq` interprets its expression per
21
+ pixel per plane per frame (nodes × W × H × fps). No crash — render time
22
+ explodes. Chunking does not reduce it: same pixels either way.
23
+ 3. **One frame's memory.** frames-in-flight × W × H × 4 B. Buffering
24
+ filters (`loop=size=N`, `split`, framesync queues, `tpad`) and
25
+ resolution multiply it; filter COUNT does not (12,000 chained filters /
26
+ 1.19 MB single graph verified fine).
27
+ 4. **One process's argv.** Windows caps ~32 K → `ENAMETOOLONG`.
28
+
29
+ ## The classification test (apply to any content-scaled feature)
30
+
31
+ When something scales with content (N tiles, steps, keyframes, data
32
+ points), ask: **which quantity grows?**
33
+
34
+ - Count of commands / inputs / filters / workspace files grows → MORE
35
+ ATOMS → fine; capacity, chunkable.
36
+ - A single expression, a single filter's per-pixel cost, a single frame's
37
+ resident bytes, or argv grows → BIGGER ATOM → redesign before shipping.
38
+
39
+ ## Bigger-atom anti-patterns → more-atoms replacements
40
+
41
+ | anti-pattern (bigger atom) | replacement (more atoms / bounded atom) |
42
+ |---|---|
43
+ | nested `if(cond,…,else)` per keyframe (`expr = if(...,${expr})` builders) | flat gated sum: `lt(t,t0)*(v0)+(gte·lt)*seg+…+gte(t,tN)*(vN)` |
44
+ | `.join("+")` on a content-scaled window list, emitted raw | route through the funnels (below) or `rebalanceAdditiveChains` |
45
+ | `geq` on a canvas/panel-sized stream | static SVG/PNG mask + `alphamerge`; keep geq on small intermediates |
46
+ | animated values as ever-larger exprs | pre-render to a small intermediate (value `.mov`s, text renders) |
47
+ | content-scaled string inline in argv (`-i lavfi`, drawtext text) | workspace file (`-filter_complex_script`, `-graph_file`, `textfile=`) |
48
+ | full-res lossless-alpha (qtrle/argb) intermediates on opaque nodes | alpha intermediates only where alpha flows |
49
+
50
+ ## Existing enforcement (route new work through these; do not bypass)
51
+
52
+ - `rebalanceAdditiveChains` (`@m0saic/platform` ffexpr) auto-applied at the
53
+ funnels: `quoteEnableArg` (all `:enable=`), `buildOverlayAlphaFilter`
54
+ (enable→geq alpha fold), `buildCameraFilters` (zoom/focus). >32 flat
55
+ terms → balanced tree (O(log n) depth, verified past 1024 terms); ≤32
56
+ passes byte-identical. It CANNOT fix nesting — builders must emit flat
57
+ shapes.
58
+ - Input-count split (`maxInputsPerCommand`) — more commands per node.
59
+ - Graph/text file lowering — argv atom stays constant.
60
+ - SVG rounding rasterizer (default) — rounding is a mask input, not geq.
61
+
62
+ Known bypasses to watch: hand-rolled lavfi `enable=` strings (dsl-string
63
+ caret track, dsl-canvas drawbox — currently ≤3 terms) and nested-if
64
+ builders in other templates (e.g. line-chart anim) that will hit atom 1 if
65
+ their datasets grow.
66
+
67
+ ## Review greps
68
+
69
+ `join("+")` on generated arrays; recursive expr accumulation
70
+ (`= \`if(…,${expr})\``); `geq` fed by canvas-sized labels; content
71
+ interpolation into `-i`/argv rather than a workspace file.
72
+
73
+ ---
74
+
75
+ *Per-pixel eval cost (atom 2) is the next practical wall at denser grids — a
76
+ perf ceiling, not a crash; fix it representationally (masks, pre-rendered
77
+ intermediates), not by chunking.*
@@ -0,0 +1,194 @@
1
+ ## Overlay Semantics & Paint Order
2
+
3
+ Overlays are recursive layout subtrees rendered inside an owner's rect — a first-class
4
+ compositional primitive, not just "layers". This doc covers attachment, paint order,
5
+ deferred zero-overlay paint, the overlay-body validity rule, and composition at scale.
6
+
7
+ > **Source of truth:** overlay parsing in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts);
8
+ > overlay-body validation in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate/m0StringValidator.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate/m0StringValidator.ts)
9
+ > (relaxation comment at lines 479–486); error codes in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts).
10
+ > Every accept/reject example below was runtime-verified against https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/dist
11
+ > via `validateM0String` on 2026-07-27.
12
+
13
+ ## Attachment: any node can own an overlay
14
+
15
+ Form:
16
+
17
+ node{ overlay_body }
18
+
19
+ `node` may be ANY node kind — not just `1`:
20
+
21
+ - `1` (tile), `0` (passthrough), `-` (null — child position only; see Logical Owner)
22
+ - `N(...)` / `N[...]` (splits)
23
+ - a node that is itself an overlay owner (chains)
24
+
25
+ No base `1` is required for an overlay to exist. A chain of full layouts is legal:
26
+
27
+ 2(1,1){3(1,1,1){2(1,1)}} — base 2-col, overlay 3-col, overlay-on-overlay 2-col
28
+
29
+ Rules:
30
+
31
+ - At most ONE immediate overlay object per node — `1{1}{1}` rejects
32
+ (`OVERLAY_CHAIN`). Stack by nesting instead: `1{1{1}}`.
33
+ - The overlay body must validate independently as a full m0 string, recursively.
34
+ - Nesting depth is structurally unbounded — but see the render-cost caveat below.
35
+
36
+ Valid: `1{1}` · `2(1,1){1}` · `1{1{1}}` · `2(1,1){3(1,1,1){2(1,1)}}`
37
+
38
+ ## Overlay rect = owner rect
39
+
40
+ The overlay subtree is parsed against owner.x / owner.y / owner.width / owner.height.
41
+
42
+ - It does NOT inherit sibling geometry.
43
+ - It does NOT escape its parent rect.
44
+
45
+ Applies to tile, group, null, and zero overlays alike.
46
+
47
+ ## Overlays never mutate geometry
48
+
49
+ Overlay stacking, at any depth:
50
+
51
+ - does NOT change splitEven results or sibling sizes
52
+ - does NOT change structuralDepth
53
+ - does NOT alter stableKeys of the base structure
54
+
55
+ It only increments `overlayDepth` and adds paint layers. The base layout defines
56
+ geometry; overlay chains define drawing.
57
+
58
+ ## Paint order
59
+
60
+ Deterministic, defined by engine traversal.
61
+
62
+ ### Tile overlay
63
+
64
+ 1{1}
65
+
66
+ 1. Base tile
67
+ 2. Overlay subtree (immediately after owner)
68
+
69
+ ### Group overlay
70
+
71
+ 2(1,1){1}
72
+
73
+ 1. Child 0
74
+ 2. Child 1
75
+ 3. Group overlay — group overlays paint AFTER all base children.
76
+
77
+ ### Zero overlay (deferred paint)
78
+
79
+ 3(0{1},1,1)
80
+
81
+ Zero overlays do NOT paint immediately; they defer until the claimant renders:
82
+
83
+ 1. Claimant tile
84
+ 2. Deferred zero overlay
85
+
86
+ Multiple zero overlays in one run:
87
+
88
+ 3(0{1},0{1},1)
89
+
90
+ 1. Claimant
91
+ 2. Larger-area zero overlay
92
+ 3. Smaller-area zero overlay (top-most)
93
+
94
+ Deferred zero overlays are sorted by area DESCENDING → smaller overlays paint on top.
95
+
96
+ ### Claimant with its own overlay
97
+
98
+ 3(0{1},1{1},1)
99
+
100
+ 1. Claimant tile
101
+ 2. Claimant's own overlay
102
+ 3. Deferred zero overlay — always after the claimant AND the claimant's overlay.
103
+
104
+ ### Nested overlays
105
+
106
+ 1{1{1}}
107
+
108
+ 1. Base tile
109
+ 2. First overlay
110
+ 3. Nested overlay
111
+
112
+ ## Logical owner `-`
113
+
114
+ `-{X}` marks `isLogicalOwner = true`: the base does not render, but the overlay rect
115
+ exists and carry is still absorbed if it is a claimant. Use for editor semantics and
116
+ labeling containers.
117
+
118
+ Position matters: `-{...}` is valid in a child slot or inside an overlay body, NOT as
119
+ the whole-string root — `2(-{1},1)` and `1{-{1}}` accept; bare `-{1}` rejects
120
+ (`TOKEN_RULE`), as does a bare `-` root (`INVALID_EMPTY`).
121
+
122
+ ## Overlay depth vs structural depth
123
+
124
+ Two independent counters:
125
+
126
+ - `structuralDepth` — increases entering numeric containers; root = 0.
127
+ - `overlayDepth` — increases entering `{...}`; base layout = 0, first overlay = 1.
128
+
129
+ Overlay frames inherit the structuralDepth of their context and use a separate frame
130
+ namespace.
131
+
132
+ ## Overlay body node rule (`INVALID_EMPTY`)
133
+
134
+ An overlay body `{...}` must contribute at least ONE node to the graph, but does not
135
+ have to paint. Logical-owner anchors (`-{X}`) are the common shape.
136
+
137
+ Rejected — zero nodes, or a single root with nothing to act on:
138
+
139
+ 1{} — empty body; no nodes at all
140
+ 1{0} — bare passthrough at the overlay root; nothing to donate to
141
+ 1{-{}} — recursive: the inner `{}` is rejected (deepest offender reported)
142
+
143
+ Accepted — at least one node, even if nothing paints:
144
+
145
+ 1{-} — single null node; logical-owner anchor
146
+ 1{2(-,-)} — all-null split; structural nodes, no paint
147
+ 1{2(0,-)} — passthrough with a sibling to donate space to
148
+ 1{-{-}} — nested logical owners
149
+ 1{-{2(0,-)}} — nested with structural content
150
+ 1{2(-,1)} — overlay body has a source (always valid)
151
+ 1{2[1,1]{1}} — nested overlay body has a source
152
+
153
+ The legacy `ZERO_SOURCE_OVERLAY` rule (body must contain at least one leaf `1`) was
154
+ relaxed 2026-06-03 — overlay bodies no longer have to paint, only exist as nodes
155
+ ([`m0StringValidator.ts`](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/validate/m0StringValidator.ts):479–486).
156
+ The whole-string `NO_SOURCES` check still requires the OUTER (root) layout to produce
157
+ at least one source tile, so the renderer is never asked to draw a fully empty canvas.
158
+
159
+ Error code when rejected: `INVALID_EMPTY` (kind `SYNTAX`).
160
+
161
+ ## Composition at scale: deep overlay stacks
162
+
163
+ Overlay chains are how large rect sets are composed: each `{}` wraps a full valid
164
+ subtree, and each layer paints inside the owner's rect. A 109-overlay brand mark —
165
+ each overlay an independently calculated m0saic drawing one precise rectangle — is a
166
+ measured working example; its serialized string ran to tens of thousands of
167
+ characters, which parse/validate/walk handle without issue.
168
+
169
+ Deep stacks are editor-clean: each overlay is its own layer, filterable by
170
+ `overlayDepth`, structurally independent, with no geometry coupling.
171
+
172
+ Use deep overlays for programmatic rect emission — dictionary-based layouts, glyphs,
173
+ masks, strict layering control. Prefer a single split when it expresses intent more
174
+ clearly or raw-string readability matters.
175
+
176
+ > ⚠️ **Render-cost caveat** (measured 2026-07-02): depth is free structurally, NOT at
177
+ > render time. Each overlay level is one sequential blend pass on ffmpeg's single
178
+ > graph thread, and past ~25 nested overlay layers inline-masks silently degrade
179
+ > (circles→squares, text→tofu) — engine wall W3. Deep stacks are cheap to WRITE
180
+ > and inspect, not cheap to RENDER — collapse time-disjoint line geometry into
181
+ > lavfi tracks first. Author-facing rules:
182
+ > [`../templates/patterns/perf-authoring-rules.md`](../templates/patterns/perf-authoring-rules.md)
183
+ > (R6). Deep dives are engine-internal: `.ai/moat/runtime/ffmpeg-limitations.md`,
184
+ > `.ai/moat/runtime/render-cost-model.md` — absent in the shipped copy.
185
+
186
+ ## Invalid constructions (verified, with codes)
187
+
188
+ 1{} — INVALID_EMPTY (empty body)
189
+ 1{0} — INVALID_EMPTY (bare passthrough body)
190
+ 1{-{}} — INVALID_EMPTY (recursive)
191
+ 1{1}{1} — OVERLAY_CHAIN (two immediate overlays; nest instead)
192
+ 1{{1}} — TOKEN_RULE (no owner token for the inner overlay)
193
+ 1{2(1,0)} — PASSTHROUGH_TO_NOTHING (trailing `0` inside overlay body)
194
+ -{1} — TOKEN_RULE (`-{...}` cannot be the whole-string root)
@@ -0,0 +1,79 @@
1
+ # Choosing the right parse API (and mapping frames → sources)
2
+
3
+ > **Source of truth:** [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts).
4
+ > All four parse exports re-exported from `@m0saic/dsl`. (A fifth,
5
+ > `parseM0StringToFullGraphWithTraversal`, was removed in the public-API prune —
6
+ > use `parseM0StringComplete` with `opts.trace`.)
7
+
8
+ ## The canonical entry point: `parseM0StringComplete`
9
+
10
+ `parseM0StringComplete(input, width, height, opts?)` returns (on success):
11
+
12
+ - `ok: true`
13
+ - `ir.renderFrames` — RenderFrame[] in **paint order**
14
+ - `ir.editorFrames` — EditorFrame[] (full structural graph, always present)
15
+ - `ir.traversal` — optional DFS event stream if `opts.trace`
16
+ - `precision`, `resolutionDiagnostics`, `warnings`
17
+
18
+ Frames are one level deep under **`ir`**, not top-level. On failure:
19
+ `{ ok: false, error, precision, warnings }`. Other options:
20
+ `opts.materialize: "renderOnly"` (the cheap mode `parseM0StringToLogicalFrames`
21
+ rides on) and `opts.precisionNorm` (default 100; gates `PRECISION_EXCEEDS_NORM`
22
+ warnings). Prefer Complete for tooling, editor logic, anything non-trivial.
23
+
24
+ ## The three cheaper tiers
25
+
26
+ | Tier | API | Returns | Use for |
27
+ |---|---|---|---|
28
+ | 1 | `parseM0StringToLogicalFrames(s, w, h)` | rendered leaves only, **logical order**; each has `rect`, `logicalIndex` (array index === logicalIndex), `meta` | template tile mapping — `cell-<logicalIndex>`, labels indexing, "Nth tile" logic |
29
+ | 2 | `parseM0StringToRenderFrames(s, w, h)` | renderable frames in **paint order**; each has `rect`, `paintOrder`, `logicalIndex` | engine paint plan / ffmpeg stacking |
30
+ | 3 | `parseM0StringToFullGraph(s, w, h)` | EVERYTHING as EditorFrame[] — roots, groups, leaves, passthroughs, nulls, overlay subtrees | editor UIs, structural analysis |
31
+
32
+ Key invariant (Tier 2): `paintOrder` is the compositing order; `logicalIndex` is
33
+ the logical tile index. There is **no `sourceIndex` field** — build sources by
34
+ `logicalIndex`, paint by `paintOrder`.
35
+
36
+ Common mistakes the wrong tier causes: confusing paint order with logical order,
37
+ attaching sources to the wrong index, losing overlays/group nodes in a UI.
38
+
39
+ ## Identity on every frame
40
+
41
+ All frame views carry `meta` identity: deterministic StableKey, structuralDepth,
42
+ overlayDepth (separate axes; overlay keys live in the `/ov{depth}c{k}` namespace and
43
+ never shift structural keys). The full contract: [`identity.md`](identity.md).
44
+
45
+ ## Frames → sources → children (the template bridge)
46
+
47
+ The standard pattern for turning geometry into a `MosaicDocument`:
48
+
49
+ 1. Parse the layout — `parseM0StringToLogicalFrames` for leaf mapping. The public
50
+ frames APIs already exclude null-render nodes (the parser filters
51
+ `nullRender` internally — you do NOT hand-filter holes/containers).
52
+ 2. For each frame: create a child renderable (often
53
+ `renderNestedTemplate(cellTemplateId, props, ctx)` —
54
+ https://github.com/m0saic-project/m0saic-packages/blob/main/packages/template-utils/src/render/renderNestedTemplate.ts#L35), attach it under
55
+ `children[id]`, push a `sources[]` entry referencing it.
56
+ 3. Return `{ m0: <same layout>, config.sources, children }` (the document's layout
57
+ field is `m0` — https://github.com/m0saic-project/m0saic-packages/blob/main/packages/types/src/document/document.ts#L132).
58
+
59
+ Rules that keep the bridge deterministic:
60
+
61
+ - **Child IDs come from `frame.logicalIndex`** (e.g. `cell-${logicalIndex}`) — or
62
+ `frame.stableKey` when identity must survive structural edits. Never bare loop
63
+ order. ([`identity.md`](identity.md) owns the when-to-use-which.)
64
+ - **Size and time from `ctx.target`, never `ctx.output`** — `ctx.output` is
65
+ format/codec/alpha only ([`../templates/rendering-model-contract.md`](../templates/rendering-model-contract.md) Rule 5b).
66
+ - **Internal cell templates** (`internal: true`, id `…/cell/v1`) are the reusable
67
+ building block for per-tile content — wireframe-style label/debug tiles are the
68
+ canonical example.
69
+ - Props schemas: use `definePropsSchema` with typed defaults. (There is no
70
+ `constraints.isM0saicLayout` — an older revision of this guidance invented it;
71
+ the real constraint set is `MosaicPropConstraints`,
72
+ https://github.com/m0saic-project/m0saic-packages/blob/main/packages/types/src/template/template.ts#L108-146`.)
73
+
74
+ ## Quick decision table
75
+
76
+ - Engine paint plan / ffmpeg stacking → `parseM0StringToRenderFrames`
77
+ - Template tile mapping / "Nth tile" logic → `parseM0StringToLogicalFrames`
78
+ - Full structural tree / editor UI → `parseM0StringToFullGraph`
79
+ - Traversal events, or anything multi-view → `parseM0StringComplete` (+ `opts.trace`)