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,475 @@
1
+ # m0saic CLI usage
2
+
3
+ > Regenerated 2026-07-29 from the CLI source (not published) — re-verify with
4
+ > `m0saic --help` / `grep -c '.command(' the CLI source (not published) (14 as of
5
+ > 2026-07-29, **2 of them dev-gated** — `browse-templates` and `momo`; a 15th
6
+ > command, `telemetry`, registers via a helper — see below). So: 12 public
7
+ > commands + 2 dev-gated + `telemetry`.
8
+ >
9
+ > **2026-09-16:** `doctor` (added after this snapshot, dev-gated at 0.1.0) is now
10
+ > **public** — see its row; `browse-templates` and `momo` remain the only two
11
+ > `if (DEV_MODE)` commands. Public set is locked by `PUBLIC_COMMANDS` in
12
+ > the CLI source (not published) (15 incl. `doctor`, `hello-world`).
13
+
14
+ Source of truth: [the CLI source (not published)](the CLI source (not published))
15
+ (~5,866 lines). Inline-DSL arg parsing: [the CLI source (not published)](the CLI source (not published)).
16
+ Root `COMMANDS.md` (monorepo document, not published) documents the inline-DSL shorthand + test tiers.
17
+
18
+ ## Entry routing — inline-DSL mode is first-class
19
+
20
+ Before commander ever runs, `index.ts:~7279-7285` inspects `process.argv[2]`:
21
+ `isInlineM0()` (`inlineDsl.ts:36-41`) treats ANY first arg that is not a flag and
22
+ not in `KNOWN_SUBCOMMANDS` as an inline m0 string and dispatches to
23
+ `handleInlineDsl` instead of `program.parseAsync`.
24
+
25
+ ```bash
26
+ m0saic "2(1,1)" # static wireframe → output.png (default mode "wire")
27
+ m0saic "2(1,1)" --anim # animated wireframe → output.mp4
28
+ m0saic "2(1,1)" --wire # explicit static (same as default)
29
+ m0saic layout.m0 # .m0 / .m0c paths also accepted (index.ts:~7184-7270)
30
+ ```
31
+
32
+ - Args after the string parse via `parseInlineArgs` (`inlineDsl.ts:123`): `-w/-h`
33
+ (default 1920×1080), `-o`, `--fps`, `--durationMs`, `--props`, `--save-mosaic`,
34
+ `--save-m0`, `--prefer-pretty-m0`/`--prefer-canonical-m0`, `--disable-ui`,
35
+ `--format`, `--alpha`, `--validate-only`, `--report`, `--toolchain`, plus the
36
+ dev-gated dump flags (below).
37
+ - The string is validated with `validateM0String` before render (index.ts:~7222);
38
+ whitespace is stripped. Always shell-quote the DSL (parens/brackets).
39
+ - Output extension is coerced to match mode (`resolveInlineOutput`,
40
+ `inlineDsl.ts:86` — `--anim -o out.png` → `out.mp4`).
41
+ - Mode maps onto the wireframe handlers: `wire` → `handleWireframe`, `anim` →
42
+ `handleAnimatedWireframe` (index.ts:~7264-7266).
43
+
44
+ ## Command table
45
+
46
+ 18 `.command(` registrations in `index.ts` + `telemetry` registered by
47
+ `registerTelemetryCommand(program)` (index.ts:~7138 → `utils/telemetry.ts:~372`).
48
+ Two of the 18 sit inside `if (DEV_MODE) { … }` and are absent from the public
49
+ help — see the DEV-GATED rows below.
50
+
51
+ > **Line numbers are loose signposts, written `~NNNN`** (founder ruling
52
+ > 2026-09-25). `index.ts` is ~7,200 lines and every number in this doc had drifted
53
+ > within weeks. **The greppable symbol is the anchor; the number only says
54
+ > roughly where to look.** A number that has moved is not a defect and does not
55
+ > earn a fix pass — correct one when you are editing that row anyway, and
56
+ > otherwise leave it.
57
+
58
+ | Command (index.ts line) | What it does |
59
+ |---|---|
60
+ | `make <input>` (~5095) | Primary render: template id / `.mosaic` / `.mosaicx` → video or image. Full flag surface below. |
61
+ | `hello-world` | The first render — a thin alias for `make @m0saic/hello-world/v1` (the brand card; output defaults to `hello-world.mp4`). With `--template-repo <path...>` / `--community-repo <path>` it renders the loaded repo's **front door** instead: the first repo (load order) whose `repo.helloWorld` names a template that registered, announced as `Front door: <id> — <repo>'s hello-world`; no repos, or none that name one → the core card with a one-line why. Takes `-o -w -h --fps --durationMs --props --quiet --verbose` (no engine surface). Picker: the CLI source (not published). |
62
+ | `make-wireframe` (~5462) | Static wireframe PNG from `--m0 <string>` or `--mfile <path>`. |
63
+ | `make-wireframe-animated` (~5568) | Animated wireframe MP4 from `--m0`/`--mfile`; extra `--disable-ui`. |
64
+ | `flatten <input>` (~5680) | Inline all `type:mosaic` children of a `.mosaic`/template into one flat JSON doc — no render. |
65
+ | `resolve <input>` (~5800) | `.mosaicx` recipe → resolved `.mosaic` provenance doc, no ffmpeg; `--flatten` also inlines children. |
66
+ | `list-templates` (~5946) | Print registered template ids (`--json`); annotates primitive/internal/deprecated. |
67
+ | `doctor <repoDir>` | **Public since 0.2.0** (dev-gated at 0.1.0; founder ruling 2026-09-16, BURN-DOWN D5 → publish). Run the template conventions over a template repo folder — the same checks its build gate (`tools/check-registry.mjs`) runs, from outside (agents, reviewers, forks, CI on a fork): definition-time + render-time conventions (the 13 throw-posture ones incl. `latticeSmooth`) and, when the repo commits `layout-fingerprints/` or `.layout.m0` sidecars, the fingerprint diff. `--json` (one object: `ok, repo, mode, loadDiagnostics, rendered, skipped, errors, warnings, notes, fingerprints, conventions`), `--sweep` (also render on the standard 1080p canvases → `canvasEnvelope`), `--entry <path>`, `--src <dir>`. Loads through `loadTemplateRepoFromPath` under the external origin scope, so conventions RECORD rather than throw and one bad template never hides the rest. **Runs the repo's template module bodies in-process** — prints a trust warning to stderr (not under `--json`). Exit 1 on any error-severity finding or a fatal load diagnostic. It is the pack-publishing contract for community/starter authors ("the publish requirement for packs"). Impl: the CLI source (not published); locked public by `__tests__/cli.surface.test.js`. |
68
+ | `browse-templates` (~6033) | **DEV-GATED** (whole command inside `if (DEV_MODE)`, 4792): interactive TTY picker (template → variant → confirm → delegates to `make`). It drives the E2E variant matrix and writes to `test-output/` — a development harness, not a user surface. |
69
+ | `momo <message…>` (~6282) | **DEV-GATED** (whole command inside `if (DEV_MODE)`, 5040): relay English geometry instruction to Momo in a running Mosaic Desktop over the loopback bridge; exit 0 applied / 2 not-applied / 1 couldn't-run. |
70
+ | `init <name>` (~6464) | Scaffold a template workspace — the compact starter twin, renamed to the user's handle. `--dir`, `--handle`, `--display-name`. Shares ONE scaffold with Desktop's Start pane (`scaffoldTemplateWorkspace` in `@m0saic/product`), so the two cannot drift. Deliberately does NOT write the trust store: loading an external repo is the user's consent, recorded by the app in `~/m0saic/template-trust.json`. Prints the install / build / fingerprint line and the Add-source hint. |
71
+ | `mcp` (~6538) | Run the CLI as an **MCP server** over stdio — the agent-facing surface. See below. |
72
+ | `open [file]` (~6608) | Open a file in Mosaic Desktop, or `--template` / `--make` to open the Make page via the bridge. See below. |
73
+ | `setup` (~6830) | Download + install the pinned ffmpeg toolchain (`--gpl` default / `--lgpl` / `--yes` / `--platform-key`). Idempotent: detects installed golden slot or a PATH ffmpeg with libx264. **The only path that downloads** — renders never do. TTY asks `Download the pinned GPL ffmpeg build now?`; non-TTY / `CI` need explicit approval — `--yes` (or the `--gpl` / `--lgpl` repair flags), otherwise `No terminal to ask for approval on.` + exit 1, nothing downloaded. Ends `✓ ffmpeg is ready. Now run your m0saic command again.` |
74
+ | `activate <key>` (~7000) | Validate + store a license key at `~/m0saic/license.json` (`M0SAIC_PRODUCT_KEY` env wins over the file). **A VERIFIED key — valid, in grace, expired or revoked — also sends ONE notice to m0saic.io from a detached worker (`utils/licenseActivation.ts` → `licenseActivationWorker.js`): the key's `keyId`, the outcome, `surface: "cli"`, the CLI's major.minor. Never the token, the email or the install id. Sent in EVERY telemetry mode — the one signal outside them (founder ruling 2026-09-26); honours `M0SAIC_TELEMETRY_ENDPOINT=off`, `CI` (unless the endpoint came from env) and dormancy (a dev checkout never sends); ignores the mode and `DO_NOT_TRACK`. The command prints "Told m0saic.io this key was used …" after the verdict, and `--help` says so. An unverified key sends nothing.** `TELEMETRY.md` §1.16. |
75
+ | `license` (~6991) | Show tier/holder/expiry; `--remove` returns to free tier. |
76
+ | `update` (~7050) | Check npm for a newer release; offers `npm i -g m0saic@latest`. |
77
+ | `versions` (~7116) | Print **every bundled `@m0saic/*` package**, grouped by tier (language / substrate / product — the CLI bundles no community package) + ffmpeg baseline/runtime + resolved toolchain. `--json`: `packages` holds ALL bundled packages (a superset of the old `templates`/`types` pair, so scripts keep working). Classification comes from `@m0saic/platform` `describeMosaicPackage`, shared with Desktop's Tools → About this build (2026-09-26). |
78
+ | `telemetry` (via helper) | Subcommands `status` (default) · `set-mode <standard\|local-only\|ghost>` · `list` · `preview` · `flush` · `clear`. Since 0.2.0 PUBLISHED builds transmit (Standard mode): day summary + today-so-far rollups after renders via a detached worker, to `https://m0saic.io/api/telemetry`. Workspace builds are dormant. Gates for harnesses: `M0SAIC_TELEMETRY=ghost` (nothing recorded), `M0SAIC_TELEMETRY_ENDPOINT=off` (nothing sent), `CI` (no send unless the endpoint is set by env). **Modes govern usage telemetry only: `activate` is in `CLI_USAGE_SKIPPED_COMMANDS`** — its notice is identity-less, and the rollup deliberately carries no `cli.command.activate` counter beside it (the pairing would link an install id to a key id). `status` / `preview` cannot list the notice: it is never queued. Full reference: `TELEMETRY.md` at the repo root (§1.16 for the notice). |
79
+
80
+ > **`decode-watermark` is GONE** (removed 2026-07-28). Recovering a forensic
81
+ > watermark is now an ordinary template — `@m0saic/forensic/watermark/verify/v1`,
82
+ > run through `make` — because a CLI can't grow a bespoke command per template
83
+ > family. The old `--ffmpeg <path>` override it carried is now the template's
84
+ > `ffmpegPath` prop.
85
+
86
+ ## `make` input routing (index.ts:~5340-5372)
87
+
88
+ 1. Extension `.mosaic` → `handleMosaicFile` — parse JSON renderable, resolve
89
+ relative media against the file's dir, plan + render.
90
+ 2. Extension `.mosaicx` → `handleMosaicxFile` (~4214) — the **resolve-then-render
91
+ branch**: absolutize asset paths → apply the doc's `runner` block as option
92
+ defaults (explicit flags win) → sibling `.m0v` auto-discovery → route
93
+ `--inputs`/`--input-dir` into the single `template_invocation`'s
94
+ `props.sourceIds` (ambiguous multi-invocation → error; zero inputs on an
95
+ input-requiring template → renders a usage-card and exits non-zero) →
96
+ `resolveMosaicx` → write resolved doc to a tmp `.mosaic` → delegate to
97
+ `handleMosaicFile` (~4460, defined ~4475) so the post-resolve render path is shared.
98
+ **Two roots accepted** (2026-08-14): `mosaicx_document` and
99
+ `mosaicx_pipeline` (a root-level template chain — see
100
+ `templates/data-pipeline.md`). The header echoes which one it read
101
+ (`kind: mosaicx_pipeline`). A chain root has no top-level `sources`, so the
102
+ `--inputs` routing and the usage-card gap detection above are inert for it;
103
+ `runner` applies to both. Same for `resolve <input>`.
104
+ **Duration is an ASK on this path** (2026-09-05): `--durationMs ??
105
+ wrapper.durationMs` reaches the template as `userIntent.durationMs` via
106
+ `mosaicxUserIntent` (`mosaicxRunner.ts:405`) on both `make` and `resolve`, so a
107
+ self-timing template FITS its walk to the length (as Make does) instead of
108
+ being trimmed to it. Mint ledger wrappers mirroring the template's natural
109
+ length unless the variant is deliberately pinned.
110
+ 3. No extension + starts with `@` → `handleTemplateMake` — template id, merge
111
+ `--props` over `defaultProps`, render.
112
+ 4. Anything else → error, exit 1.
113
+
114
+ ## Exit codes (2026-09-15)
115
+
116
+ | Code | Meaning | File at `-o`? |
117
+ |---|---|---|
118
+ | `0` | Success — the output is the render asked for. | Yes |
119
+ | `1` | Failure — plan build threw, ffmpeg exited non-zero, validation failed, zero commands. | No / unusable |
120
+ | `2` | `momo` ran but did not apply a change. | n/a |
121
+ | `3` | **RENDER DEGRADED** — the renderable carried `engine.renderStatus: "error"`, so the output is an **error mosaic**. | **Yes**, valid media |
122
+
123
+ **Why 3 exists.** A template that hits bad input does not crash: it returns
124
+ `makeErrorMosaic(...)`, a readable card stamped `engine.renderStatus: "error"`.
125
+ That card renders, so the CLI used to write it and exit 0 — a caller whose only
126
+ success test was "did a file appear at the expected path?" reported success on a
127
+ picture of an error. 3 is deliberately not 1: exit 1 means "there is no output,
128
+ retry or clean up", which is false here. The engine still never aborts on the
129
+ marker — it renders, writes the file, and *then* the CLI reports.
130
+
131
+ **Detection** (`src/utils/collectRenderErrors.ts`) walks the WHOLE renderable
132
+ tree for the marker: document level, source level, nested `children`
133
+ (recursively), and pipeline `steps` (dispatching per step, so a nested pipeline
134
+ is walked too). **One error mosaic anywhere in the tree degrades the whole run** —
135
+ a batch where 4 of 5 steps are fine still exits 3, because one deliverable is an
136
+ error card. `errors[].path` in the sidecar (`children.hero.sources[0]`,
137
+ `steps[1].sources[0]`) says which.
138
+
139
+ > ⚠️ Historical: the walker read `doc.config?.sources`, but
140
+ > `MosaicDocument.sources` was hoisted out of `config` long ago — so every
141
+ > source-level marker (exactly where `makeErrorMosaic` puts it) was invisible and
142
+ > every error-mosaic render exited 0. `mosaicxRunner` hand-promoted its error to
143
+ > doc level to work around it; both the bug and the workaround are gone.
144
+
145
+ **Classification** (`src/utils/renderOutcome.ts` — the single decision point; all
146
+ 12 report call sites in `index.ts` route through it):
147
+
148
+ - **Hard errors beat engine errors.** A run with both is 1, not 3.
149
+ - A **zero-command plan** counts its engine errors as hard — there is no output
150
+ to call degraded — so that path stays 1.
151
+ - Free vs paid tier is **orthogonal**. The marker is read off the document, not
152
+ the file; the free-tier QR wrap runs before classification, so on free tier the
153
+ error card ships stamped and still exits 3. A stamp failure is swallowed as a
154
+ warning and never changes the exit code.
155
+
156
+ With `--report` the same verdict is machine-readable, so a caller that parses the
157
+ sidecar never needs the exit code and a caller that reads exit codes never needs
158
+ the JSON:
159
+
160
+ ```json
161
+ { "ok": false, "exitCode": 3, "renderStatus": "degraded",
162
+ "renderErrorCodes": ["ENGINE_ERROR"],
163
+ "errors": [{ "code": "ENGINE_ERROR", "message": "Quote Card: quote must not be empty", "path": "sources[0]" }] }
164
+ ```
165
+
166
+ ## `make` flags
167
+
168
+ **Core** — `-w/--width` and `-h/--height` are `requiredOption`s. Then:
169
+ `-o/--output` (defaults `out.mp4` / `out.png`, index.ts:~172-173), `--fps` (1–120),
170
+ `--durationMs` (>0), `--format`/`--output-kind` (`video|image`),
171
+ `--alpha`/`--no-alpha`, `--props <jsonOrPath>` (inline JSON **or** `@path/to/json`
172
+ — `utils/readJsonArg.ts:18` strips the `@` and reads the file),
173
+ `--validate-only` (exit 0/1/3, no render — 3 = the renderable IS an error
174
+ mosaic; prints `Validation DEGRADED`), `--report` (`.output.json` /
175
+ `.validate.json` sidecars, both carrying `renderStatus` + `renderErrorCodes`),
176
+ `--save-mosaic [path]`, `--save-m0 [path]`,
177
+ `--keep-temp`, `--quiet`, `--verbose`, `--prefer-pretty-m0` /
178
+ `--prefer-canonical-m0` (printed-m0 form only; note: NOT `--prefer-*-m0saic`),
179
+ `--background-color <color>`, `--template-repo <path...>` +
180
+ `--template-repo-entry <file>` (external template repos), `--community-repo <path>`
181
+ (ONE checkout of the official community repo — see the community gate below).
182
+
183
+ **Encode surface** (index.ts:~4231-4338, mirrors the Make page's Advanced panel;
184
+ precedence: flags > `.m0v` preset > doc-on-disk > engine default):
185
+ `--target <preset>` (`web-mp4|web-webm|alpha-mov|image-png|image-jpeg|animated-gif|audio-mp3|audio-wav`),
186
+ `--container`, `--video-codec`, `--audio-codec`, `--pixel-format`, `--bitrate`
187
+ (CRF wins on conflict), `--crf`, `--encoder-preset`, `--encoder-profile`,
188
+ `--encoder-level`, `--encoder-options <k=v,…>`, `--gop-size`, `--audio-bitrate`,
189
+ `--audio-sample-rate`, `--audio-channel-layout`, `--no-audio` (`-an`),
190
+ `--color-space`/`--color-range`/`--color-primaries`/`--color-transfer`
191
+ (metadata-only), `--metadata-title`/`-description`/`-author`/`-copyright`/`-comment`.
192
+
193
+ **Batching / multi-output**: `--inputs <files...>` (populates `sourceIds`; wins
194
+ over `--input-dir`), `--input-dir <path>` (+ `--recursive` for depth-first walk),
195
+ `--output-pattern <pattern>` (tokens `{{base}} {{ext}} {{stepName}} {{index}}
196
+ {{i}} {{date}} {{batch}} {{label}}`; collisions get `-1,-2,…`), `--batch <name>`.
197
+
198
+ **`.m0v`**: `--m0v <path>` loads a Mosaic Vocabulary file two ways — named
199
+ outputs onto `ctx.userIntent.outputs` (template-consultative) AND a post-render
200
+ merge onto the renderable **by index** when entry counts match
201
+ (index.ts:~4218-4221; `BaseRenderOptions` docstring ~541-557).
202
+
203
+ **Toolchain**: `--toolchain <name>` is a **global program option**
204
+ (index.ts:~526), not make-specific — a named entry from `m0saic.local.json`, with
205
+ implicit `gpl`/`lgpl` golden slots merged in. Resolution precedence: `--toolchain`
206
+ flag > `M0SAIC_TOOLCHAIN` env > config `defaultToolchain` > PATH/golden fallback
207
+ (`utils/toolchainConfig.ts:129`). There is **no** `--ffmpeg` anywhere on the CLI
208
+ any more (it left with `decode-watermark`) — the equivalent is the verify
209
+ template's `ffmpegPath` prop; `--platform-key` only on `setup`.
210
+
211
+ **No-ffmpeg gate** (`utils/ensureFfmpeg.ts` via `ensureRenderToolchain()`, index.ts
212
+ ~404, first thing in every render handler): resolved ffmpeg fails to probe → the
213
+ 4-line `ffmpeg isn't detected.` message (points at `setup`) and **exit 1** — TTY,
214
+ piped and CI alike; no prompt, no inline download, no auto-install (founder
215
+ ruling 2026-09-16; supersedes cli-v1-publish.md Phase 2). `setup` is the only
216
+ downloader, and it too never fetches without approval (TTY prompt, or `--yes`).
217
+ Spell every `setup` hint with `cliSetupCommand()` (`utils/invocation.ts`):
218
+ `npx m0saic setup` under npx, `m0saic setup` installed.
219
+
220
+ **Perf**: `--perf [path]` writes a `.perf.json` sidecar — per-ffmpeg-command
221
+ timing rolled up by mosaic node (names the bottleneck panel/template).
222
+
223
+ **DEV-GATED** (each wrapped in `.hideHelp(!DEV_MODE)`; `DEV_MODE =
224
+ process.env.M0SAIC_DEV === "1"` at index.ts:~71, compile-stripped to `false` in
225
+ the published artifact): `--dev` (commands + timings), `--print-commands`,
226
+ `--save-plan [path]`, `--save-commands [path]`. Same gating inside inline-DSL
227
+ mode (`inlineDsl.ts:148-154`). Also dev-gated: the whole `momo` command, the
228
+ whole `browse-templates` command, and `open`'s
229
+ `--agent-note`/`--agent-question`. `--save-mosaic` and `--save-m0` are NOT gated,
230
+ and neither is `doctor` (public since 0.2.0).
231
+
232
+ > Note: a dev-gated command's NAME still appears in `KNOWN_SUBCOMMANDS`
233
+ > (`inlineDsl.ts:11-29`), outside the gate — the inline-DSL router has to know
234
+ > `momo` is a subcommand and not an m0 string. So grepping a shipped tarball for
235
+ > `momo` / `browse-templates` finds hits; that is the router table, not the
236
+ > gated implementation.
237
+
238
+ ## External template repos and the community gate (2026-09-16)
239
+
240
+ **Three reserved identities, exact-match, nothing else is checked:** template
241
+ namespaces `@m0saic/` and `@m0saic-dev/`, repo id `@m0saic-community`
242
+ (`index.ts:~907-909`; registry compare is case-insensitive, `templateRegistry.ts:~112`).
243
+ Every other namespace / repo id is open. `--template-repo` never grants anything.
244
+
245
+ **The grant.** `--community-repo <path>` says "this IS the official repo"; the
246
+ `@m0saic-dev/` grant comes only from `verifyCommunityRelease()` (`@m0saic/product`
247
+ `communityRelease.ts`) passing on the checkout's `release.json` against
248
+ `LICENSE_PUBLIC_KEYS` (`publicKeys.ts` — the licence k1 family; rotation = append
249
+ `k2`, ship, sign with `M0SAIC_SIGNING_KID=k2`; older CLIs report `unknown-kid`).
250
+ The gate runs BEFORE the entry module is imported. All gate/notice lines go to
251
+ stderr (survive `--quiet`, keep `--json` stdout clean):
252
+
253
+ - ok → `✓ community repo verified: <tag> (signed, <kid>)`
254
+ - else → `⚠ <path> is not a verified release of the official community repo
255
+ (<reason>). Loaded as an ordinary template repo — its @m0saic-dev/ ids are
256
+ refused. Get the official checkout: the link on m0saic.io/community` → the
257
+ reserved ids are refused in ONE collapsed line, `⚠ [template-repo]
258
+ TEMPLATE_ID_RESERVED_NAMESPACE: refused <N> ids in reserved namespace
259
+ (@m0saic-dev/…): <id1>, <id2>, <id3>, …` (other rejection codes stay one line
260
+ each) → the existing `❌ Refusing to use template repo` block → **exit 1**.
261
+
262
+ **`release.json` v1:** `{ schemaVersion: 1, tag, publishedAt, treeSha256,
263
+ signature: { kid, alg: "ed25519", sig: <base64url> } }` (`--unsigned` omits
264
+ `signature`; the legacy `{ tag, publishedAt }` reads as `missing-signature`).
265
+ Tree = every file under `dist/**` + `template-manifest.json` + `package.json`,
266
+ sorted POSIX paths, one `"<path>\0<sha256>\n"` line each; `*.json` hashed on
267
+ `JSON.stringify(JSON.parse(text))` (BOM stripped; CRLF / re-indent survive, a
268
+ key reorder does not), other files raw bytes; no symlink is ever followed.
269
+ Payload `"m0saic-community-release/v1\n<tag>\n<publishedAt>\n<treeSha256>\n"`
270
+ (`publishedAt` must be ISO 8601, else `malformed`). Ladder:
271
+ `missing-release → malformed → missing-signature → unknown-kid → bad-signature
272
+ → symlink-in-tree / foreign-modules → tree-mismatch → ok` — signature before
273
+ tree, so `tree-mismatch` = authentic release with edited dist/manifests,
274
+ `bad-signature` = forged `release.json`; the two structural refusals
275
+ (`symlink-in-tree`: ANY symlink under `dist/**`, `dist` itself or a signed
276
+ root file; `foreign-modules`: a `node_modules` dir at the root or under
277
+ `dist/`) sit between them and carry the offending path in the notice —
278
+ `(symlink-in-tree: dist/node_modules)`, `(foreign-modules: node_modules)`.
279
+ `publishedAt` is signed but there is still no anti-rollback (an older
280
+ authentic release verifies).
281
+
282
+ **A checkout never supplies `@m0saic/*` to itself.** The loader
283
+ (`@m0saic/platform` `template-repos/hostFirstResolution.ts`, installed by
284
+ `loadTemplateRepoFromPath` before the entry import) resolves every
285
+ `@m0saic/<pkg>[/<subpath>]` require whose parent file lies under a loaded
286
+ repo root from the HOST's own `node_modules` walk — the CLI's vendored copies,
287
+ the desktop's bundle, the workspace under dev — never from the checkout. So a
288
+ clone with nothing installed loads anywhere (0.2.0 is the first CLI that
289
+ can), and a `node_modules/@m0saic/template-utils` planted beside a tree is
290
+ never evaluated, via `--community-repo` or `--template-repo` alike. Every
291
+ other specifier (`sharp`, `@twemoji/svg`, relative paths) resolves as before,
292
+ from the checkout. CommonJS only — an `.mjs` entry's static `import`s use the
293
+ ESM resolver, which has no hook.
294
+
295
+ **Minting:** `scripts/sync-community-templates.mjs --tag <tag> --out <dir>` signs
296
+ with `M0SAIC_SIGNING_KEY_FILE` (REQUIRED — no default path; production laptop
297
+ only) under `M0SAIC_SIGNING_KID` (default `k1`), self-verifies against the
298
+ embedded keys, writes `.gitattributes` (`* -text`). Unset or missing key =
299
+ refused, never a silent unsigned release; `--unsigned` = loud banner, a snapshot
300
+ no shipped CLI trusts.
301
+
302
+ **DEV seam (workspace builds only, inside `if (DEV_MODE)`):** reasons
303
+ `missing-release` / `missing-signature` are still granted — `✓ community repo:
304
+ <path> (dev build: unsigned community checkout trusted)` (the in-repo
305
+ https://github.com/m0saic-project/m0saic-community-templates/blob/main has no `release.json`) — and
306
+ `M0SAIC_COMMUNITY_TRUST_KEY_PEM` (+ `M0SAIC_COMMUNITY_TRUST_KEY_KID`, default `k1`)
307
+ adds a public key for tests. Tampered tree, forged release or unknown kid are
308
+ refused even in dev. The tarball folds `process.env.M0SAIC_DEV` to `"0"` and the
309
+ audit bans the token, so none of this ships.
310
+
311
+ **Lookalikes are a display concern** — one stderr line for UNSIGNED repos, never a
312
+ refusal: `⚠ [template-repo] <subject> is not an official m0saic namespace — only
313
+ @m0saic/ and @m0saic-dev/ are, and they are signed.` Subject: loaded publisher
314
+ namespaces starting with `@m0saic` that are not exactly the two reserved ones →
315
+ else a repoId matching `/m0saic|mosaic/i` → else `"<displayName>" (<repoId>)`.
316
+ Never for repoId exactly `@m0saic-community`: via `--template-repo` that gets
317
+ `⚠ [template-repo] repo id "@m0saic-community" is reserved for the official
318
+ community repo and this checkout is unverified — loading it under ordinary
319
+ rules.` A `--community-repo` checkout that fails the gate gets ONLY the
320
+ not-verified notice.
321
+
322
+ **Desktop:** `installVersion()` runs `validateCommunityTree` → `verifyCommunityTree`
323
+ (inline-requires `@m0saic/product`) → refuses `tag-mismatch`; failure =
324
+ `{ ok:false, error: "downloaded tree rejected: release signature not verified
325
+ (<reason>): <detail>", reason }` on the existing IPC path; `installed.json` gains
326
+ `signedBy` + `treeSha256`; seam `installVersion({ releasePublicKeys })`. The
327
+ seed/installed load path (`loadCommunityRepo`) does not re-verify; consent gate
328
+ unchanged.
329
+
330
+ Help wording for `make` / `hello-world` / `list-templates` is ONE string,
331
+ test-locked (`__tests__/cli.flags.test.js`): "…Grants the @m0saic-dev/ namespace
332
+ when its release signature verifies (unsigned or modified checkouts load as
333
+ ordinary repos); the community checkout loads only this way".
334
+
335
+ ### Hardening (rounds 2 + 3, 2026-09-16)
336
+
337
+ **Host-first `@m0saic/*` resolution.** https://github.com/m0saic-project/m0saic-packages/blob/main/packages/platform/src/template-repos/hostFirstResolution.ts (wired in `loadTemplateRepoFromPath.ts` via `registerHostFirstRepoRoot(repoRoot)` before the native `import(file://…)` of the entry): ONE wrapper around Node's real `Module._resolveFilename` (found by walking the prototype chain — under Jest `node:module` exports a subclass copy), installed once per process, persistent so render-time lazy requires are covered. A request matching `/^@m0saic\/[^/\\]+(?:\/.*)?$/` whose requesting module lies under a registered root (realpath'd) is resolved from the HOST's own `node_modules` walk — never the checkout's. Everything else (relative paths, non-`@m0saic` deps, host code) is untouched. CJS only. Consequences: a community clone loads from ANY directory with no `node_modules` (before this, `--community-repo` only worked inside the monorepo); a planted `node_modules/@m0saic/*` beside a verified tree is never evaluated, via either flag; a starter's `file:` link to `@m0saic/template-utils` resolves to the same physical package — no drift.
338
+
339
+ **Fail-closed tree verification** (`inspectReleaseTree` in `communityRelease.ts`; desktop mirror `inspectCommunityTree` in the Mosaic Desktop / Web app source (not published), run by `installVersion`). A release tree is plain files and directories, nothing else. Refused, in this order after the signature check and before the hash compare: `symlink-in-tree` (ANY symlink — file or dir — under `dist/**`, `dist` itself, a signed root file, or ANY entry at the checkout root); `special-file-in-tree` (FIFO / socket / device anywhere in the same places — a FIFO named `dist/publishers.js` shadows the signed `dist/publishers/` dir and blocks or executes whoever opens it); `foreign-modules` (a `node_modules` dir at the root or under `dist/`, matched case-insensitively). `verifyCommunityRelease` lstats `release.json` before opening it (a FIFO planted there used to hang the verifier). The hasher THROWS `ReleaseTreeError` on a special entry rather than skipping it; `signCommunityRelease` refuses to sign such a tree. The signed payload is `"m0saic-community-release/v1\n<tag>\n<publishedAt>\n<treeSha256>\n"`. The CLI notice carries the detail for these reasons — `(foreign-modules: node_modules)`; for `special-file-in-tree` the CLI does NOT load the folder at all (an ordinary load provably hangs): notice + `❌ Refusing to use template repo` + exit 1.
340
+
341
+ **Community deps.** The `@m0saic-dev/community-m` pack (the only `sharp` / `@twemoji/svg` user) was deleted as defunct on 2026-09-16; both left the community `package.json` and BOTH allowlists (`dep-allowlist.json` ↔ `TEMPLATE_REPO_DEP_ALLOWLIST`, lockstep-tested). Community templates may import only what the hosts ship: `@m0saic/{types,template-utils,dsl-stdlib,platform,dsl}` + `node:path`. A native or third-party runtime dep is a founder decision. `sharp` survives only as a root devDependency for core/templates tests.
342
+
343
+ **Accepted residual.** A third-party `--template-repo` checkout with its own `node_modules` runs its own copies of non-`@m0saic` deps — third-party code, with the notice printed; it cannot obtain a reserved identity that way (adversary-verified). DEV builds (`M0SAIC_DEV=1`, compile-stripped from the tarball) still trust an unsigned checkout for `missing-release` / `missing-signature` only; a tampered or forged tree is refused even in dev.
344
+
345
+ ## Wireframe commands
346
+
347
+ `make-wireframe` / `make-wireframe-animated` take the layout as `--m0 <string>`
348
+ (inline DSL — the flag is `--m0`, not `--m0saic`) or `--mfile <path>`, plus the
349
+ same core/save/report/`--m0v`/`--output-pattern` surface as `make` (no encode
350
+ surface, no `--inputs`). Animated adds `--disable-ui` (index.ts:~4504).
351
+
352
+ ## `m0saic open` — pointer only
353
+
354
+ The canonical protocol (candidate file naming, agent block, iteration ritual,
355
+ `--template` hot-reload loop) lives in
356
+ [https://github.com/m0saic-project/m0saic-sandbox/blob/main/packages/sandbox/agent.md](https://github.com/m0saic-project/m0saic-sandbox/blob/main/packages/sandbox/agent.md) — read that,
357
+ not this. Shape only: `open <file>` accepts `.m0 .m0c .m0p .m0v .mosaic
358
+ .mosaicx` and routes to Mosaic Desktop (auto-detects a running dev electron on
359
+ macOS; `--app <path>` override); `open --template <id> [--props/--props-file]`
360
+ opens the Make page via the loopback bridge, hot-reloading fresh
361
+ https://github.com/m0saic-project/m0saic-packages/blob/main/packages/templates/dist first (`--no-reload` to skip); `open --make
362
+ <file.mosaicx>` opens an authored `.mosaicx` in Make and adopts it for the
363
+ agent loop.
364
+
365
+ ## `m0saic mcp` — the agent surface (2026-09-25)
366
+
367
+ MCP has three primitives; this server implements **tools** only (model-invoked).
368
+ Transport is newline-delimited JSON-RPC 2.0 over stdio, hand-rolled in
369
+ `src/mcp/server.ts` (~230 lines, **zero runtime deps**: the official SDK carries
370
+ 17, including express, hono, cors, jose and ajv, and the CLI vendors its whole
371
+ closure into the published tarball). `initialize` echoes the client's
372
+ `protocolVersion`; a tool that throws returns `isError: true` rather than a
373
+ JSON-RPC error, so the model sees the failure instead of the transport eating it.
374
+
375
+ The 21 tools (`src/mcp/tools.ts`; the list is locked in `tools.test.ts`), in four groups:
376
+
377
+ - **Knowledge** — `knowledge_list`, `knowledge_read`, `knowledge_search`. The
378
+ `@m0saic/knowledge` docs, so an agent reads the handbook instead of guessing.
379
+ - **Local, no app needed** — `list_templates`, `template_props`, `validate_m0`,
380
+ `workspace_scaffold`, `render_still`, `doctor`.
381
+ - **Through the loopback bridge into a running Desktop — the authoring loop** —
382
+ `desktop_status` (also says which flow you are in: `in-the-room`, a shell
383
+ Desktop's Agent panel opened, or `ecosystem`), `desktop_open_in_make` (open a
384
+ template for review — this resets the person's session on it),
385
+ `desktop_reload_sources`, `desktop_read_verdict` (takes a template id, or the
386
+ path of a forked `.mosaic`; surfaces `srcMosaic` + `geometryEdits`).
387
+ - **The live canvas (0.3.1)** — see it: `desktop_layout` (the template, every
388
+ tile's bound prop and shown value, the current bag with `changedKeys`, the
389
+ modes; `detail`, `tileId`, `prop`), `desktop_snapshot` (a PNG on disk); act
390
+ through Make's own handlers: `desktop_set_props` (THE way to change a prop —
391
+ one undoable write, "Agent changed …"), `desktop_select_tile`,
392
+ `desktop_make_control` (reveal, camera, undo/redo, view, preview mode, canvas,
393
+ tile card, studio, cover, hover, tile override); branch when the template has
394
+ no knob: `desktop_fork_to_document` (a plain `.mosaic` + its m0),
395
+ `desktop_open_file`, `desktop_edit_geometry` (a pending ghost the person
396
+ applies). Behaviour and etiquette: [`agent-at-the-canvas.md`](agent-at-the-canvas.md);
397
+ the wire: `docs/compat-bridges.md` (0.3.1 routes).
398
+
399
+ Three rules the implementation enforces:
400
+
401
+ - **`render_still` pins `M0SAIC_CLI=/usr/bin/false`.** `@m0saic/benchmark/run/v1`
402
+ re-invokes `argv[1]`; without the pin a render from inside the CLI fork-bombs.
403
+ - **Failures return a HINT, never raw stderr** (`findFailureHint`). Engine text is
404
+ moat: the argv and the filtergraph never cross to a model.
405
+ - **The act routes never focus or restore the window**, and every live-canvas verb
406
+ runs the handler a click would — Desktop's main process sanitises the verb and
407
+ its args inbound and rebuilds every result from an allow-list outbound
408
+ (`electron/makeAgent.js`), so nothing an agent polls can carry a plan, an argv
409
+ or a filtergraph.
410
+
411
+ `src/mcp/bridgeClient.ts` is the transport for the desktop tools. A 404 means
412
+ `route-missing` — "this Desktop is too old for that route" — not "the app is
413
+ down"; the compat warning prints once per process. The full route table is
414
+ `docs/compat-bridges.md`.
415
+
416
+ **`--agent-note` / `--agent-question` are PUBLIC** as of this line (the DEV_MODE
417
+ strip is gone and `__tests__/cli.surface.test.js` asserts they appear in the
418
+ published help — the lock was inverted, not removed). With `--template` they seed
419
+ a note / question into Make's File tab for the reviewer to answer.
420
+
421
+ ## `m0saic doctor` answers a VERSIONED question (2026-09-25)
422
+
423
+ Conventions change, so "does this repo pass?" is the wrong question — the right one is **which line
424
+ does it pass at.** `report.conventions` carries it:
425
+
426
+ ```
427
+ conventions: meets 0.2.0 (shipped at 0.2.0).
428
+ behind 0.3.0: bindingsDeclared, canvasFill
429
+ 9 of 96 template(s) behind — a vN+1 on each clears it.
430
+ ```
431
+
432
+ - **`meets`** — the newest m0saic line every template in the repo satisfies (error severity only; a
433
+ `record` warning is advice, not a failure to meet a line).
434
+ - **`behind`** — the lines it does not meet, with the rules that fail, oldest first.
435
+ - **`shippedAt`** — the repo's own `frozen.manifest.json` `release`.
436
+ - **`target`** — the repo's `repo.conventions` (e.g. `"0.3.1"`, 0.3.1): the line whose rules it has
437
+ adopted. Each template is held to the LOWER of its shipped line and the target; rules introduced after
438
+ that are lag ("behind"), never errors. A repo moves its target when its templates have adopted the
439
+ newer rules — like a crate's edition. Absent: held to every rule this CLI knows. A malformed target is
440
+ a load warning (`CONVENTIONS_TARGET`); one newer than the CLI knows is a note. The summary line reads
441
+ `conventions: meets 0.3.0 (targets 0.3.0).` and a lagging template says *"the repo targets 0.3.0:
442
+ behind on catalogSidecar — not a defect, adopt them, then move repo.conventions."*
443
+ - **`lagOnly`** — true when EVERY failure comes from a line newer than `shippedAt`. The footer then
444
+ says so explicitly: *"Not a defect: these templates met the conventions of their day. Fix at the
445
+ next vN."*
446
+
447
+ **A template is allowed to lag.** It met the conventions of its day; the rules moved; the fix is its
448
+ next `vN`. **A repo is allowed to target an older line too** (`repo.conventions`): a new m0saic release
449
+ never turns its build red — the freeze protects what shipped, the target protects a repo with no freeze
450
+ (every third-party repo). What the rules guarantee is that **NEW** templates meet the CURRENT line — which is why the
451
+ postures throw (founder: "we need to be greedy about adding conventions because agents, especially
452
+ non-frontier ones, won't"). The exit code is still 1 on any error, because the status is informational
453
+ and the message carries the meaning.
454
+
455
+ `TEMPLATE_CONVENTION_SINCE` in `@m0saic/template-utils` is the map of rule → line. Everything
456
+ pre-0.3.0 reads `0.2.0`: at that freeze the whole shipped fleet passed every rule then in force, so it
457
+ is a true lower bound rather than a guessed date.
458
+
459
+ ## Failure modes
460
+
461
+ - `spawnSync m0saic EACCES` — the CLI isn't built/linked on this machine:
462
+ `cd the CLI source (not published) && npm run build && npm link`.
463
+ - No ffmpeg at all → `ffmpeg isn't detected.` (4 lines), exit 1, nothing
464
+ downloaded (`ensureRenderToolchain()`, index.ts ~404); run `m0saic setup`
465
+ (`npx m0saic setup` under npx), then re-run. A broken golden slot prints
466
+ `❌ Toolchain "gpl" (golden) is broken … Re-install it: m0saic setup --gpl`.
467
+ - Free tier re-encodes every deliverable (QR stamp wrap) — codecs/durations
468
+ change, breaking probe-based assertions. Check `npm run tier:status` first;
469
+ full rule in the maintainers' agent contract §7.7 (not published).
470
+ - Non-zero ffmpeg exits print a core-computed failure classification after the
471
+ exit-code line (`printFfmpegFailure`, index.ts:~113) — read it before rerunning
472
+ with `--verbose`.
473
+ - Invalid m0 strings fail fast at validation (`validateM0String`), not inside
474
+ ffmpeg; `SPLIT_EXCEEDS_AXIS` means the split count exceeds the pixel axis —
475
+ see `docs/handbook/feasibility-precision-quantization.md`.
@@ -0,0 +1,117 @@
1
+ # FFmpeg Expression Limits — the parse-depth cliff (a phantom "OOM")
2
+
3
+ **Source of truth:** `rebalanceAdditiveChains` in
4
+ [https://github.com/m0saic-project/m0saic-packages/blob/main/packages/platform/src/ffexpr/balance.ts](https://github.com/m0saic-project/m0saic-packages/blob/main/packages/platform/src/ffexpr/balance.ts)
5
+ (`DEFAULT_MAX_FLAT_ADDITIVE_TERMS = 32`); the funnels that apply it —
6
+ `quoteEnableArg` in [https://github.com/m0saic-project/m0saic-packages/blob/main/packages/platform/src/ffexpr/ffmpeg.ts](https://github.com/m0saic-project/m0saic-packages/blob/main/packages/platform/src/ffexpr/ffmpeg.ts),
7
+ `buildOverlayAlphaFilter` + `buildCameraFilters` in `@m0saic/core`.
8
+ Verified against BtbN ffmpeg `N-124278-gcc3ca17127-20260430` (the pinned GPL build).
9
+
10
+ > Companion mental model: [`../skills/more-atoms-not-bigger-atoms.md`](../skills/more-atoms-not-bigger-atoms.md).
11
+ > This doc is the measured case study; that one is the general principle.
12
+
13
+ ---
14
+
15
+ ## The symptom (and why it lies)
16
+
17
+ FFmpeg's expression parser (`av_expr_parse`, `libavutil/eval.c`) has a **fixed
18
+ recursion budget (~100)**. When an emitted expression exceeds it, filtergraph
19
+ init fails with:
20
+
21
+ - **`Error initializing filters / Error : Cannot allocate memory` (−12)** — a
22
+ **phantom OOM**: deterministic, ~60 ms, completely independent of free RAM.
23
+ This is the additive-chain shape.
24
+ - or **`Missing ')' or too many args` → `Invalid argument` (−22) /
25
+ `Error reinitializing filters`** — the deeply-nested shape (e.g. a `crop`
26
+ focus expr).
27
+
28
+ The word "memory" is a lie. It is NOT commit pressure, graph size, filter
29
+ count, or a platform difference — all of which this failure repeatedly (and
30
+ expensively) misled debugging toward. It is one expression too deep.
31
+
32
+ ## The cliff (measured, term-count-driven — NOT chars)
33
+
34
+ - A **flat `a+b+c+…` chain fails at exactly 99 terms** (98 parses, 99 fails).
35
+ Character length is irrelevant: a 3.8 K-char / 98-term expr parses; a
36
+ 2.3 K-char / 99-term expr fails.
37
+ - **Genuine nesting** (nested `if(cond,…,else)` chains) fails at ~100 levels.
38
+ - Because ffmpeg spends one recursion level **per additive term at the same
39
+ nesting level**, both shapes share the same ~100 budget.
40
+
41
+ ## The two shapes → the two fixes
42
+
43
+ 1. **Flat additive chains** (`enable` window sums, the `overlay.enable`→`geq`
44
+ alpha fold, camera zoom/focus). Fixable by REGROUPING the same terms into a
45
+ **balanced binary tree** — `((a+b)+(c+d))…` — which keeps parse depth
46
+ O(log N) and is safe past 1024 terms. This is `rebalanceAdditiveChains`.
47
+ 2. **Deep nesting** (one nested `if()` level per keyframe). Rebalancing CANNOT
48
+ help — the builder must **emit a flat shape instead**. dsl-tutorial's camera
49
+ `focusExpr` was rewritten from nested `if(lt(t,…),…, else)` (depth 109 at
50
+ 10×10) to a **flat sum of disjoint window-gated smoothstep segments**
51
+ (`lt` head + `gte·lt` segments + `gte` tail).
52
+
53
+ ## Authoring rule
54
+
55
+ **No flat additive chain longer than ~32 terms, and no piecewise-over-time
56
+ expression built as a nested if-else chain, should ever reach a filtergraph.**
57
+ Build piecewise-in-time values as **flat gated sums**; long chains are
58
+ auto-rebalanced at the engine funnels below.
59
+
60
+ ## Engine enforcement (shipped 2026-07-02 — route new work through these)
61
+
62
+ `rebalanceAdditiveChains` (`@m0saic/platform` `ffexpr/balance.ts`, threshold
63
+ `DEFAULT_MAX_FLAT_ADDITIVE_TERMS = 32`) is applied automatically at every
64
+ expression funnel:
65
+
66
+ - `quoteEnableArg` — ALL `:enable='…'` sites (overlay, drawtext,
67
+ `compileEnableArg`).
68
+ - `buildOverlayAlphaFilter` — the `overlay.enable` → `geq` alpha fold.
69
+ - `buildCameraFilters` — zoom/focus chains.
70
+
71
+ Chains **≤ 32 terms pass through byte-identical** (goldens unaffected); only
72
+ longer chains are regrouped. Rebalancing fixes PARSE; it does not change eval
73
+ cost (see below).
74
+
75
+ **Known bypasses to watch:** hand-rolled lavfi strings that build `enable=`
76
+ outside the funnels — dsl-string caret-track `drawbox`, dsl-canvas `drawbox`
77
+ (both currently ≤3-term chains, safe) — and any template that still builds a
78
+ nested-`if` expression (e.g. a line-chart animation) which will hit the cliff
79
+ if its dataset grows. Keep per-filter chains small, or call
80
+ `rebalanceAdditiveChains` before joining.
81
+
82
+ ## The "graph-SIZE OOM" was this cliff wearing a trench coat (debunked)
83
+
84
+ A separate ≈130 K-chars / 9 000-filters "graph-size OOM" mode was once believed
85
+ to exist, and a `splitByGraphBudget` chunker was calibrated against it. **It does
86
+ not reproduce.** Direct verification:
87
+
88
+ - The exact 142 K canvas part it was calibrated on renders standalone at full
89
+ duration; so do a **12 000-chained-drawbox / 1.19 MB single graph** and a
90
+ 9 000-filter graph.
91
+ - Every recorded failure sidecar in `smokebatch/` (smoke9–29) is a command
92
+ whose EXPRESSIONS cross the parse cliff (flat ≥99 or nesting ≥109), failing in
93
+ <80 ms with −12/−22. **No sidecar ever names a size-heavy command.**
94
+
95
+ Graph chars merely *correlated* with expression bulk in that era's graphs. The
96
+ graph-size chunker was reverted. **Do not re-add a filtergraph-size split
97
+ chasing a "size OOM" — it is the parse cliff.** (The input-count split,
98
+ `maxInputsPerCommand`, is a separate and real argv/process-arg constraint and
99
+ stays.)
100
+
101
+ ## Note: the macOS "grind" is a different wall
102
+
103
+ The same dense graphs that fail fast on Windows (parse cliff) instead ran for
104
+ 20+ min on macOS. That was NOT the parse cliff (Mac's ffmpeg parses flat chains
105
+ fine) — it was **per-pixel `geq` eval cost** (O(terms) per pixel per plane per
106
+ frame). Rebalancing does not reduce it; density caps like `PULSE_TERM_CAP` and
107
+ representational fixes (SVG masks, pre-rendered intermediates) do. That's a
108
+ perf ceiling, not a crash — see the "more atoms" skill, atom 2.
109
+
110
+ There is also a *third*, mechanically distinct macOS wall on
111
+ conversion-/input-dense graphs (many `scale`/`format` nodes + many still
112
+ inputs, e.g. dsl-tutorial grids): **swscale thread-cap exhaustion**, where
113
+ per-conversion thread pools blow past `kern.num_taskthreads` and frames freeze
114
+ at t=0 or grind at ~1 fps. That one is neither parse depth nor `geq` eval cost —
115
+ that wall is engine-internal: `.ai/moat/runtime/macos-swscale-thread-cap.md`
116
+ (absent in the shipped copy; symptom summary: dense still-image canvases freeze
117
+ at t=0 / grind ~1 fps on macOS — the engine's threadGuard mitigates it).