m0saic 0.2.1 → 0.3.0
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.
- package/LICENSE +22 -7
- package/README.md +23 -5
- package/dist/browseE2e.js +1 -1
- package/dist/connectionsFromEnv.js +1 -1
- package/dist/e2eTemplateVariants.js +1 -1
- package/dist/frontDoor.js +1 -1
- package/dist/index.js +1 -1
- package/dist/inlineDsl.js +1 -1
- package/dist/mcp/bridgeClient.js +1 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +1 -0
- package/dist/mosaicxRunner.js +1 -1
- package/dist/outputPattern.js +1 -1
- package/dist/showcaseFeed.js +1 -1
- package/dist/templateDoctor.js +1 -1
- package/dist/utils/checkFeasibility.js +1 -1
- package/dist/utils/collectRenderErrors.js +1 -1
- package/dist/utils/enrichImageAlphaFromDoc.js +1 -1
- package/dist/utils/ensureFfmpeg.js +1 -1
- package/dist/utils/extractLayoutMeta.js +1 -1
- package/dist/utils/failureHints.js +1 -1
- package/dist/utils/ffmpegProbe.js +1 -1
- package/dist/utils/formatM0saicForCli.js +1 -1
- package/dist/utils/hashFile.js +1 -1
- package/dist/utils/helpGroups.js +1 -1
- package/dist/utils/installContext.js +1 -0
- package/dist/utils/invocation.js +1 -1
- package/dist/utils/licenseActivation.js +1 -0
- package/dist/utils/licenseActivationWorker.js +1 -0
- package/dist/utils/mosaicSpinner.js +1 -1
- package/dist/utils/parseDimensions.js +1 -1
- package/dist/utils/pathInfo.js +1 -1
- package/dist/utils/readJsonArg.js +1 -1
- package/dist/utils/renderOutcome.js +1 -1
- package/dist/utils/renderReport.js +1 -1
- package/dist/utils/renderSignals.js +1 -1
- package/dist/utils/renderWorkspace.js +1 -1
- package/dist/utils/reportOutputFormat.js +1 -0
- package/dist/utils/setupFfmpeg.js +1 -1
- package/dist/utils/telemetry.js +1 -1
- package/dist/utils/telemetryFlushWorker.js +1 -1
- package/dist/utils/telemetryUpstream.js +1 -1
- package/dist/utils/telemetryUsage.js +1 -1
- package/dist/utils/toolchainConfig.js +1 -1
- package/dist/utils/tutorialDuration.js +1 -1
- package/dist/utils/updateCheck.js +1 -1
- package/dist/utils/updateCheckWorker.js +1 -1
- package/dist/utils/validateSourceCounts.js +1 -1
- package/dist/utils/versions.js +1 -1
- package/dist/webCustomizeLink.js +1 -1
- package/node_modules/@m0saic/community-m/NOTICE +9 -0
- package/node_modules/@m0saic/community-m/release.json +2 -2
- package/node_modules/@m0saic/core/dist/core/buildChildMosaicSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildChunkCommands.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildEncodeCommands.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildLavfiSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildMediaSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildMosaicNode.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildMosaicPlanFromFile.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildSvgTextSource.js +1 -1
- package/node_modules/@m0saic/core/dist/core/buildTextRenderCommand.js +1 -1
- package/node_modules/@m0saic/core/dist/core/collectRefTargets.js +1 -1
- package/node_modules/@m0saic/core/dist/core/index.js +1 -1
- package/node_modules/@m0saic/core/dist/core/maskCacheDir.js +1 -1
- package/node_modules/@m0saic/core/dist/core/maskWorkerBridge.js +1 -1
- package/node_modules/@m0saic/core/dist/core/playbackPlaySpeed.js +1 -1
- package/node_modules/@m0saic/core/dist/core/prepareProps.js +1 -1
- package/node_modules/@m0saic/core/dist/core/primaryOutput.js +1 -1
- package/node_modules/@m0saic/core/dist/core/rasterizeMaskPng.js +1 -1
- package/node_modules/@m0saic/core/dist/core/rasterizeSvgMediaPng.js +1 -1
- package/node_modules/@m0saic/core/dist/core/refTargetTap.js +1 -1
- package/node_modules/@m0saic/core/dist/core/resolveMasks.js +1 -1
- package/node_modules/@m0saic/core/dist/core/resolveMasksSync.js +1 -1
- package/node_modules/@m0saic/core/dist/core/resolveStrokeRingsSync.js +1 -1
- package/node_modules/@m0saic/core/dist/core/roundedRectMask.js +1 -1
- package/node_modules/@m0saic/core/dist/core/strokeRing.js +1 -1
- package/node_modules/@m0saic/core/dist/core/svgRaster.js +1 -1
- package/node_modules/@m0saic/core/dist/defaults.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/backgroundImageInput.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/bufferGuard.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/ffmpegCommands.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBackdropBlur.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBlur.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyBorderRadius.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyCamera.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyChromaKey.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyFade.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyGrade.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyMask.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyNoise.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyPixelize.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyRotate.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyStroke.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/applyTileEffects.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/coverCrop.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/index.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/filters/sourceRectCrop.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/gridLowering.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/index.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/splitAvMux.js +1 -1
- package/node_modules/@m0saic/core/dist/ffmpeg/threadGuard.js +1 -1
- package/node_modules/@m0saic/core/dist/flatten/index.js +1 -1
- package/node_modules/@m0saic/core/dist/fs/index.js +1 -1
- package/node_modules/@m0saic/core/dist/fs/tempWorkspace.js +1 -1
- package/node_modules/@m0saic/core/dist/index.js +1 -1
- package/node_modules/@m0saic/core/dist/media/buildAssetManifestFromInputs.js +1 -1
- package/node_modules/@m0saic/core/dist/media/buildMediaRegistryFromInput.js +1 -1
- package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromInvocationProps.js +1 -1
- package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromMosaicRenderableFile.js +1 -1
- package/node_modules/@m0saic/core/dist/media/collectMediaInputsFromProps.js +1 -1
- package/node_modules/@m0saic/core/dist/media/index.js +1 -1
- package/node_modules/@m0saic/core/dist/media/internalMintAsset.js +1 -1
- package/node_modules/@m0saic/core/dist/media/remoteUrl.js +1 -1
- package/node_modules/@m0saic/core/dist/media/stageUnsafeFilenames.js +1 -1
- package/node_modules/@m0saic/core/dist/media/types.js +1 -1
- package/node_modules/@m0saic/core/dist/output/index.js +1 -1
- package/node_modules/@m0saic/core/dist/output/resolveOutputFormat.js +1 -1
- package/node_modules/@m0saic/core/dist/output/types.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/cellLuminanceProbe.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/extractSubtitleCues.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/helpers.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/index.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/luminanceProbe.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/probeMedia.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/runFFprobe.js +1 -1
- package/node_modules/@m0saic/core/dist/probe/types.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/engineRedaction.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/ffmpegFailure.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/filterPreflight.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/hashFile.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/index.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/pathInfo.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/perfHeatmap.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/perfReport.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/pipelineM0p.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderCostModel.constants.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderCostModel.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderReport.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/renderSidecars.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/resolveMosaicx.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/runPlan.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/types.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/upstream.js +1 -1
- package/node_modules/@m0saic/core/dist/runtime/writeSidecars.js +1 -1
- package/node_modules/@m0saic/core/dist/types/chunk.js +1 -1
- package/node_modules/@m0saic/core/dist/types/index.js +1 -1
- package/node_modules/@m0saic/core/dist/types/mosaic-plan.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/assertTiming.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/command.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/createEngineContext.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/createTemplateRenderCache.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/ffmpegColor.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/formatDuration.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/fsSafeId.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/index.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/lowerRenderableToMosaicDocument.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/movSafeCodec.js +1 -1
- package/node_modules/@m0saic/core/dist/utils/resolveBoxFrac.js +1 -1
- package/node_modules/@m0saic/core/dist/validate/index.js +1 -1
- package/node_modules/@m0saic/core/scripts/mask-rasterize-core.js +1 -1
- package/node_modules/@m0saic/core/scripts/mask-rasterize-worker.js +1 -1
- package/node_modules/@m0saic/core/scripts/mask-worker-thread.js +1 -1
- package/node_modules/@m0saic/dictionary/NOTICE +9 -0
- package/node_modules/@m0saic/dictionary/README.md +315 -0
- package/node_modules/@m0saic/dictionary/package.json +1 -1
- package/node_modules/@m0saic/dsl/package.json +1 -1
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/agent.js +6 -0
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0/parseM0File.js +1 -1
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0/serializeM0File.js +2 -2
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/m0c/m0cFile.js +3 -3
- package/node_modules/@m0saic/dsl-file-formats/dist/cjs/types.js +1 -1
- package/node_modules/@m0saic/dsl-file-formats/package.json +1 -1
- package/node_modules/@m0saic/dsl-stdlib/dist/cjs/builders/bakeM0cInsets.js +1 -0
- package/node_modules/@m0saic/dsl-stdlib/dist/cjs/builders/index.js +1 -1
- package/node_modules/@m0saic/dsl-stdlib/package.json +1 -1
- package/node_modules/@m0saic/knowledge/LICENSE +21 -0
- package/node_modules/@m0saic/knowledge/README.md +71 -0
- package/node_modules/@m0saic/knowledge/dist/index.js +1 -0
- package/node_modules/@m0saic/knowledge/docs/README.md +60 -0
- package/node_modules/@m0saic/knowledge/docs/file-formats/m0-iteration-protocol.md +120 -0
- package/node_modules/@m0saic/knowledge/docs/file-formats/m0p-and-custom-field.md +195 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/README.md +27 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/composition-arithmetic.md +278 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/dsl-complexity.md +75 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/dsl-rules.md +367 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/feasibility-precision-quantization.md +591 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/m0-construction-methods.md +201 -0
- package/node_modules/@m0saic/knowledge/docs/handbook/precision-tiers.md +84 -0
- package/node_modules/@m0saic/knowledge/docs/m0saic-thesis.md +95 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/README.md +17 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/cli-usage.md +447 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/ffmpeg-expression-limits.md +117 -0
- package/node_modules/@m0saic/knowledge/docs/runtime/reduce-to-one.md +96 -0
- package/node_modules/@m0saic/knowledge/docs/skills/README.md +40 -0
- package/node_modules/@m0saic/knowledge/docs/skills/axis-and-geometry.md +103 -0
- package/node_modules/@m0saic/knowledge/docs/skills/dsl-stdlib-method-catalog.md +7 -0
- package/node_modules/@m0saic/knowledge/docs/skills/identity.md +123 -0
- package/node_modules/@m0saic/knowledge/docs/skills/labels-and-masks.md +170 -0
- package/node_modules/@m0saic/knowledge/docs/skills/m0saic-string-generation.md +251 -0
- package/node_modules/@m0saic/knowledge/docs/skills/more-atoms-not-bigger-atoms.md +77 -0
- package/node_modules/@m0saic/knowledge/docs/skills/overlay-semantics.md +194 -0
- package/node_modules/@m0saic/knowledge/docs/skills/parse-apis.md +79 -0
- package/node_modules/@m0saic/knowledge/docs/skills/passthrough-semantics.md +136 -0
- package/node_modules/@m0saic/knowledge/docs/skills/structural-construction.md +86 -0
- package/node_modules/@m0saic/knowledge/docs/skills/text-in-templates.md +126 -0
- package/node_modules/@m0saic/knowledge/docs/skills/zero-overlay-analysis.md +87 -0
- package/node_modules/@m0saic/knowledge/docs/templates/README.md +65 -0
- package/node_modules/@m0saic/knowledge/docs/templates/capability-templates.md +72 -0
- package/node_modules/@m0saic/knowledge/docs/templates/construction-strategy.md +329 -0
- package/node_modules/@m0saic/knowledge/docs/templates/data-pipeline.md +324 -0
- package/node_modules/@m0saic/knowledge/docs/templates/emission-patterns.md +130 -0
- package/node_modules/@m0saic/knowledge/docs/templates/geometry-recipes.md +248 -0
- package/node_modules/@m0saic/knowledge/docs/templates/layout-contract.md +168 -0
- package/node_modules/@m0saic/knowledge/docs/templates/output-resolution-tree.md +202 -0
- package/node_modules/@m0saic/knowledge/docs/templates/patterns/case-study-lessons.md +69 -0
- package/node_modules/@m0saic/knowledge/docs/templates/patterns/perf-authoring-rules.md +100 -0
- package/node_modules/@m0saic/knowledge/docs/templates/patterns/primitive-extraction-pattern.md +103 -0
- package/node_modules/@m0saic/knowledge/docs/templates/philosophy-and-contract.md +310 -0
- package/node_modules/@m0saic/knowledge/docs/templates/recursion-nested-rendering.md +154 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/grid.md +104 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/json-prop-type.md +169 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/mosaic-color.md +81 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/mosaic-placement-props.md +103 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/prop-bindings.md +324 -0
- package/node_modules/@m0saic/knowledge/docs/templates/reference/template-flags.md +224 -0
- package/node_modules/@m0saic/knowledge/docs/templates/render-lifecycle.md +117 -0
- package/node_modules/@m0saic/knowledge/docs/templates/rendering-model-contract.md +392 -0
- package/node_modules/@m0saic/knowledge/docs/templates/standalone-pack-authoring.md +299 -0
- package/node_modules/@m0saic/knowledge/docs/templates/theming.md +81 -0
- package/node_modules/@m0saic/knowledge/docs/templates/ui-controls.md +150 -0
- package/node_modules/@m0saic/knowledge/package.json +6 -0
- package/node_modules/@m0saic/momo-types/README.md +109 -0
- package/node_modules/@m0saic/momo-types/dist/agent.js +1 -6
- package/node_modules/@m0saic/momo-types/dist/context.js +1 -1
- package/node_modules/@m0saic/momo-types/package.json +1 -1
- package/node_modules/@m0saic/platform/README.md +3 -0
- package/node_modules/@m0saic/platform/dist/cjs/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/outputKind/outputKind.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/propBindings/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/propBindings/propBindings.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/mosaic/validate/validateSources.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/packages/mosaicPackages.js +1 -0
- package/node_modules/@m0saic/platform/dist/cjs/paths/m0saicRoot.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/lifecycle.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/preview.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/sender.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/usageRecorder.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/telemetry/usageStore.js +3 -3
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/baseline.json +25 -97
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/index.js +1 -1
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/ffmpeg/install.js +2 -2
- package/node_modules/@m0saic/platform/dist/cjs/toolchain/goldenFfmpeg.js +6 -6
- package/node_modules/@m0saic/platform/package.json +1 -1
- package/node_modules/@m0saic/product/dist/communityRelease.js +1 -1
- package/node_modules/@m0saic/product/dist/freeTierLicense.js +1 -1
- package/node_modules/@m0saic/product/dist/index.js +1 -1
- package/node_modules/@m0saic/product/dist/licenseActivationNotice.js +1 -0
- package/node_modules/@m0saic/product/dist/licenseFile.js +1 -0
- package/node_modules/@m0saic/product/dist/licenseToken.js +1 -1
- package/node_modules/@m0saic/product/dist/makeScratchPath.js +1 -0
- package/node_modules/@m0saic/product/dist/postRenderWrapper.js +1 -1
- package/node_modules/@m0saic/product/dist/publicKeys.js +1 -1
- package/node_modules/@m0saic/product/dist/revokedKeys.js +1 -1
- package/node_modules/@m0saic/product/dist/upstreamDefaults.js +1 -1
- package/node_modules/@m0saic/product/dist/workspaceScaffold.js +1 -0
- package/node_modules/@m0saic/template-utils/dist/brand/hello-world/helloWorld.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/geometry-contract/index.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/geometry-contract/layoutConstraint.js +2 -2
- package/node_modules/@m0saic/template-utils/dist/m0saic/loadSession.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/render/createDesignContext.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/sources/makeErrorMosaic.js +2 -2
- package/node_modules/@m0saic/template-utils/dist/sources/svgTextSource.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/template/auditRenderedTemplate.js +5 -5
- package/node_modules/@m0saic/template-utils/dist/template/templateConventions.js +3 -3
- package/node_modules/@m0saic/template-utils/dist/template/validateTemplateProps.js +1 -1
- package/node_modules/@m0saic/template-utils/dist/text/fitText.js +6 -6
- package/node_modules/@m0saic/template-utils/package.json +1 -1
- package/node_modules/@m0saic/templates/NOTICE +9 -0
- package/node_modules/@m0saic/templates/dist/m0saic/media/blur-regions/v1/tutorial.js +1 -1
- package/node_modules/@m0saic/templates/package.json +1 -1
- package/node_modules/@m0saic/templates-advanced/NOTICE +9 -0
- package/node_modules/@m0saic/text/package.json +1 -1
- package/node_modules/@m0saic/types/dist/analytics/consent.js +1 -1
- package/node_modules/@m0saic/types/dist/analytics/event.js +1 -1
- package/node_modules/@m0saic/types/dist/analytics/usageMetrics.js +1 -1
- package/node_modules/@m0saic/types/dist/identifiers/identifiers.js +1 -1
- package/node_modules/@m0saic/types/dist/telemetry/ffmpegFailure.js +1 -1
- package/node_modules/@m0saic/types/package.json +1 -1
- package/node_modules/@m0saic/types-internal/dist/analytics/featureKeys.js +1 -1
- package/package.json +13 -11
- package/resources/starter-base/starter-base.json +10 -0
- package/resources/starter-base/starter-base.tgz +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
## Passthrough & Carry Semantics
|
|
2
|
+
|
|
3
|
+
`0` (passthrough) is the zero-frame donation primitive. Misused, a layout is either
|
|
4
|
+
invalid (`PASSTHROUGH_TO_NOTHING`) or geometrically wrong. This doc covers donation
|
|
5
|
+
mechanics, claimant/carry scoping, overlay behavior on zero-runs, the trailing rule,
|
|
6
|
+
and the weighted-split encoding.
|
|
7
|
+
|
|
8
|
+
> **Source of truth:** passthrough handling 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)
|
|
9
|
+
> and validator rules 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).
|
|
10
|
+
> Trailing-passthrough error code `PASSTHROUGH_TO_NOTHING` in [`errors/errors.ts`](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/errors/errors.ts).
|
|
11
|
+
> Validity examples below runtime-verified against https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/dist on 2026-07-27.
|
|
12
|
+
|
|
13
|
+
## What `0` means
|
|
14
|
+
|
|
15
|
+
`0`:
|
|
16
|
+
|
|
17
|
+
- Consumes a split slot
|
|
18
|
+
- Produces no rendered frame
|
|
19
|
+
- Donates its space forward to the next claimant
|
|
20
|
+
|
|
21
|
+
It does NOT render. It only contributes geometry.
|
|
22
|
+
|
|
23
|
+
> Design intent: `0` exists primarily to encode weighted / percentage splits in a
|
|
24
|
+
> deterministic integer-only way.
|
|
25
|
+
|
|
26
|
+
## What is a claimant?
|
|
27
|
+
|
|
28
|
+
A claimant is the first non-zero node after a run of `0`s:
|
|
29
|
+
|
|
30
|
+
- `1` (tile)
|
|
31
|
+
- `-` (null)
|
|
32
|
+
- `N(...)` / `N[...]` (group)
|
|
33
|
+
|
|
34
|
+
When a claimant appears:
|
|
35
|
+
|
|
36
|
+
- It absorbs ALL donated space from the run
|
|
37
|
+
- It absorbs its own slot
|
|
38
|
+
- Its position snaps back to the start of the run
|
|
39
|
+
|
|
40
|
+
## Donation run example
|
|
41
|
+
|
|
42
|
+
3(0,0,1)
|
|
43
|
+
|
|
44
|
+
- First `0` → carry = 1 slot
|
|
45
|
+
- Second `0` → carry = 2 slots
|
|
46
|
+
- `1` appears → absorbs carry + own slot = 3 slots
|
|
47
|
+
|
|
48
|
+
Result: the tile spans the entire width of the classifier.
|
|
49
|
+
|
|
50
|
+
## Carry is scoped per classifier
|
|
51
|
+
|
|
52
|
+
Carry does NOT leak outside the classifier body, and resets after each claimant:
|
|
53
|
+
|
|
54
|
+
7(0{1},1,0{1},1,1,1,1)
|
|
55
|
+
|
|
56
|
+
Two separate runs:
|
|
57
|
+
|
|
58
|
+
- Run 1: `0{1}` starts carry → first `1` absorbs the run
|
|
59
|
+
- Run 2: new `0{1}` → fresh carry → next `1` absorbs it
|
|
60
|
+
|
|
61
|
+
## Overlay behavior on `0`
|
|
62
|
+
|
|
63
|
+
### `0{...}` targets the merged region so far
|
|
64
|
+
|
|
65
|
+
4(0,0{2(1,1)},0,1)
|
|
66
|
+
|
|
67
|
+
1. First `0` — carry = 1 slot
|
|
68
|
+
2. Second `0{2(1,1)}` — carry = 2 slots; overlay canvas = merged 2-slot region
|
|
69
|
+
3. Third `0` — carry = 3 slots
|
|
70
|
+
4. `1` — absorbs 4 slots total
|
|
71
|
+
|
|
72
|
+
Overlay size is fixed at the moment it appears. Later carry growth does NOT resize
|
|
73
|
+
earlier overlays.
|
|
74
|
+
|
|
75
|
+
### Multiple zero overlays grow monotonically
|
|
76
|
+
|
|
77
|
+
5(0{1},0{1},0,0,1)
|
|
78
|
+
|
|
79
|
+
- First `0{1}` → overlay spans 1 slot
|
|
80
|
+
- Second `0{1}` → overlay spans 2 slots
|
|
81
|
+
- Remaining `0`s → carry grows
|
|
82
|
+
- `1` absorbs all 5
|
|
83
|
+
|
|
84
|
+
Each overlay anchors to the region size at its creation time. Zero-overlay prefix
|
|
85
|
+
geometry as a deliberate technique (progressive region staging, area-ordered
|
|
86
|
+
layering) has its own doc: [`zero-overlay-analysis.md`](zero-overlay-analysis.md).
|
|
87
|
+
|
|
88
|
+
## Trailing passthrough rule (`PASSTHROUGH_TO_NOTHING`)
|
|
89
|
+
|
|
90
|
+
A trailing `0` inside a classifier is **always** invalid — even if it carries an
|
|
91
|
+
overlay. No claimant absorbs the donation; an overlay on `0` does not change that.
|
|
92
|
+
|
|
93
|
+
Invalid:
|
|
94
|
+
|
|
95
|
+
2(1,0) — bare trailing passthrough
|
|
96
|
+
2(1,0{1}) — trailing passthrough with overlay (still invalid)
|
|
97
|
+
3(1,1,0{1}) — trailing passthrough with overlay
|
|
98
|
+
0{1} — whole-string passthrough: no sibling exists to claim
|
|
99
|
+
|
|
100
|
+
Valid:
|
|
101
|
+
|
|
102
|
+
2(0,1) — passthrough donates to claimant
|
|
103
|
+
2(0{1},1) — passthrough with overlay, not trailing
|
|
104
|
+
3(1,0,1) — passthrough in middle position
|
|
105
|
+
|
|
106
|
+
The rule applies recursively inside nested classifiers AND overlay bodies:
|
|
107
|
+
`1{2(1,0)}` rejects with `PASSTHROUGH_TO_NOTHING`.
|
|
108
|
+
|
|
109
|
+
## Weighted split encoding
|
|
110
|
+
|
|
111
|
+
Zero-runs are how weighted splits are encoded. To encode a 60/40 split:
|
|
112
|
+
|
|
113
|
+
[60% region][40% region]
|
|
114
|
+
|
|
115
|
+
DSL representation (conceptual pattern):
|
|
116
|
+
|
|
117
|
+
100( 59 zeros, 1, 39 zeros, 1 )
|
|
118
|
+
|
|
119
|
+
The zero-run before each `1` encodes how much space that tile absorbs. Mechanical
|
|
120
|
+
and deterministic.
|
|
121
|
+
|
|
122
|
+
### The stdlib GCD-reduces this for you
|
|
123
|
+
|
|
124
|
+
Never hand-roll the 100-slot form. `weightedSplit` (and the unified `split`
|
|
125
|
+
transform's `weights` option) default to `mode: "optimized"`, which divides all
|
|
126
|
+
weights by their GCD before emitting slots:
|
|
127
|
+
|
|
128
|
+
weightedSplit([60, 40], "col") → 5(0,0,1,0,1) — not 100(...)
|
|
129
|
+
weightedSplit([50, 25, 25], "col") → 4(0,1,1,1)
|
|
130
|
+
|
|
131
|
+
Verified 2026-07-27: GCD reduction in
|
|
132
|
+
[https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/builders/weightedSplit.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/builders/weightedSplit.ts):119–122;
|
|
133
|
+
the `split` transform routes through the same reduction in
|
|
134
|
+
[`buildSplitFragment.ts`](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/src/transforms/primitives/split/_internal/buildSplitFragment.ts)
|
|
135
|
+
(default `mode = "optimized"`). `mode: "literal"` keeps raw weights (legacy);
|
|
136
|
+
`precision` rescales weights to an exact slot budget first (largest-remainder).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Structural construction — emitting valid canonical m0
|
|
2
|
+
|
|
3
|
+
Operational construction rules. The Handbook is canonical for grammar
|
|
4
|
+
([`../handbook/dsl-rules.md`](../handbook/dsl-rules.md)) — this doc is the build-time
|
|
5
|
+
checklist form of the same rules; on any conflict, the handbook wins.
|
|
6
|
+
|
|
7
|
+
> **Source of truth:** [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)
|
|
8
|
+
> and [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).
|
|
9
|
+
|
|
10
|
+
## 1. Canonical output only
|
|
11
|
+
|
|
12
|
+
Emit `1` not `F`, `0` not `>`, no whitespace; allowed characters: `0–9 ( ) [ ] { } , -`.
|
|
13
|
+
Never emit pretty aliases.
|
|
14
|
+
|
|
15
|
+
## 2. Numeric containers must match exactly
|
|
16
|
+
|
|
17
|
+
`N(child1, …, childK)` requires `K === N`. No compression, no implicit slots, no
|
|
18
|
+
empty classifiers (`2()`, `3[]` invalid). Build children first, count them, then
|
|
19
|
+
prefix with N.
|
|
20
|
+
|
|
21
|
+
Valid: `2(1,1)` · `3[1,0,1]` Invalid: `2(1)` · `3(1,1)` · `2(1,1,1)` · `3()`
|
|
22
|
+
|
|
23
|
+
## 3. First token rule
|
|
24
|
+
|
|
25
|
+
A valid string starts with `1`, or a NUMBER > 1 followed immediately by `(` or `[`.
|
|
26
|
+
`0`, `-`, `,1`, `{1}` are invalid openers. `1(...)` / `1[...]` is
|
|
27
|
+
`ILLEGAL_ONE_SPLIT` — never wrap a single child in a pseudo-container.
|
|
28
|
+
|
|
29
|
+
## 4. NUMBER must be followed by a classifier
|
|
30
|
+
|
|
31
|
+
`2,1` and `2{1}` are invalid; `2(1,1)` and `2[1,1]` are valid.
|
|
32
|
+
|
|
33
|
+
## 5. Overlay discipline — objects vs nesting
|
|
34
|
+
|
|
35
|
+
- **At most one immediate overlay object per node**: `1{1}`, `2(1,1){1}`, `0{1}`,
|
|
36
|
+
`-{1}` valid; `1{1}{1}` invalid.
|
|
37
|
+
- **Layer via nesting**: `1{1{1}}` — base tile, overlay subtree, overlay on the
|
|
38
|
+
overlay.
|
|
39
|
+
- **Multiple overlay layers/regions via structure inside the body**:
|
|
40
|
+
`1{2(1,-){2(-,1)}}` — the overlay body is a container that owns its own overlay;
|
|
41
|
+
holes (`-`) isolate which regions show tiles. "One overlay object per node" does
|
|
42
|
+
not limit overlay depth.
|
|
43
|
+
|
|
44
|
+
## 6. No trailing passthrough
|
|
45
|
+
|
|
46
|
+
A trailing `0` inside a classifier is always invalid — **even with an overlay**
|
|
47
|
+
(`PASSTHROUGH_TO_NOTHING`): `2(1,0)` and `2(1,0{1})` invalid; `2(0,1)` and
|
|
48
|
+
`2(0{1},1)` valid. A passthrough must donate to a claimant; an overlay does not
|
|
49
|
+
exempt it.
|
|
50
|
+
|
|
51
|
+
## 7. Overlay bodies — valid, but sourceless is LEGAL
|
|
52
|
+
|
|
53
|
+
Bodies validate recursively as full m0 sub-expressions. A body must contain at
|
|
54
|
+
least one node, but it does NOT need a leaf `1` — the legacy `ZERO_SOURCE_OVERLAY`
|
|
55
|
+
rule was **relaxed 2026-06-03** and is no longer raised
|
|
56
|
+
(`m0StringValidator.ts:485`). Canonical overlay rules:
|
|
57
|
+
[`overlay-semantics.md`](overlay-semantics.md).
|
|
58
|
+
|
|
59
|
+
Invalid: `1{}` (INVALID_EMPTY) · `1{0}` (INVALID_EMPTY) · `1{2(1,0)}` (trailing
|
|
60
|
+
passthrough in body)
|
|
61
|
+
Valid: `1{1}` · `1{2(1,1)}` · `1{1{1}}` · `1{2(-,1)}` · `1{-}` · `1{2(-,-)}`
|
|
62
|
+
|
|
63
|
+
## 8. No-sources rule
|
|
64
|
+
|
|
65
|
+
The layout as a whole needs ≥1 leaf `1` (`NO_SOURCES`) — a source inside an
|
|
66
|
+
overlay counts: `2(-,-)` invalid, `2(-,-){1}` valid.
|
|
67
|
+
|
|
68
|
+
## Quick reference
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
VALID: 1 · 2(1,1) · 2(1{1},1) · 3[1,0{1},1] · 1{1{1}} · 1{2(1,-){2(-,1)}} · 1{-}
|
|
72
|
+
INVALID: 0 · - · 2(1) · 2(1,1,1) · 1{{1}} · 1{1}{1} · 2(1,0) · 2(1,0{1}) · 1{} · 1{0} · 2(-,-)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Construction procedure
|
|
76
|
+
|
|
77
|
+
1. Decide the structure shape (tree of splits + leaves).
|
|
78
|
+
2. Build child arrays per split; count them; prefix the exact numeric classifier.
|
|
79
|
+
3. Attach at most one overlay object per node; get extra layers via nesting or
|
|
80
|
+
split/hole structure inside the body.
|
|
81
|
+
4. Canonicalize.
|
|
82
|
+
5. Validate with `isValidM0String` / `validateM0String` from `@m0saic/dsl`
|
|
83
|
+
(returns `{ok: true} | {ok: false, error}` — singular `error`).
|
|
84
|
+
6. On failure: discard and rebuild. Never patch a broken string by hand — fix the
|
|
85
|
+
generator ([`m0saic-string-generation.md`](m0saic-string-generation.md) §3 has
|
|
86
|
+
the per-code repair moves).
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Text in templates
|
|
2
|
+
|
|
3
|
+
How to put text into a template without it silently clipping.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ⚠️ The rule that bites: nothing soft-wraps
|
|
8
|
+
|
|
9
|
+
**No rasterizer in m0saic wraps text.** A long string in a single `MosaicTextLayer`
|
|
10
|
+
renders as **one line and clips off the cell** — no error, no warning, no visual cue
|
|
11
|
+
in the plan. It just disappears past the edge.
|
|
12
|
+
|
|
13
|
+
This is true for **both** rasterizers:
|
|
14
|
+
|
|
15
|
+
- `drawtext` (ffmpeg) has no soft-wrap.
|
|
16
|
+
- `rasterizer: "svg"` converts glyphs to outlines via `@m0saic/text` — there is no
|
|
17
|
+
wrapping logic in that path either.
|
|
18
|
+
|
|
19
|
+
**Any template that puts user-typed or composed strings into text MUST pre-break
|
|
20
|
+
them.** Use `multilineTextLayers` (below); don't hand-roll.
|
|
21
|
+
|
|
22
|
+
The failure is worst with user data — a title that fits every fixture and clips on the
|
|
23
|
+
one real input nobody tested.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## The source shape
|
|
28
|
+
|
|
29
|
+
A text tile is one `MosaicTextSource` per leaf cell:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
style: { fontSize, fontColor, fontFamily }, // source-level, applies to all layers
|
|
35
|
+
layers: [ /* MosaicTextLayer[] — one per LINE */ ],
|
|
36
|
+
placement: { hAlign, vAlign }, // optional if layers carry their own
|
|
37
|
+
visual: { backgroundColor }, // solid fill behind the text
|
|
38
|
+
renderMode: { kind: "image" }, // see below
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A `MosaicTextLayer` is
|
|
43
|
+
`{ content: { kind: "literal", text } | { kind: "expr", expr }, style?, placement? }`.
|
|
44
|
+
Layers stack within one source; each may carry its own `placement` (including a
|
|
45
|
+
`yExpr`) to position itself in the cell.
|
|
46
|
+
|
|
47
|
+
### Two orthogonal knobs — don't confuse them
|
|
48
|
+
|
|
49
|
+
| Knob | Values | Question it answers |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `renderMode` | `{ kind: "image" }` \| `{ kind: "video" }` | single RGBA frame, or an RGBA video for `ctx.target.durationMs`? |
|
|
52
|
+
| `rasterizer` | `"drawtext"` \| `"svg"` | which mechanism turns glyphs into pixels? |
|
|
53
|
+
|
|
54
|
+
**Choose the rasterizer on dynamism**, per `templates/patterns/perf-authoring-rules.md`
|
|
55
|
+
**R9**: `svg` for static text (a mask + colour tile — no drawtext, no per-frame
|
|
56
|
+
shaping), `drawtext` only when the text is genuinely per-frame dynamic. `svg` does
|
|
57
|
+
**not** support expressions; the fallback to drawtext for those is correct. Read R9
|
|
58
|
+
before scaling up — it carries the density budgets (hundreds of glyph masks in one
|
|
59
|
+
panel approach the argv wall) and the note that **the app fits text wider than the
|
|
60
|
+
CLI**, so leave generous fixed-font margins.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Helpers — use these, don't hand-roll
|
|
65
|
+
|
|
66
|
+
All from `@m0saic/template-utils`:
|
|
67
|
+
|
|
68
|
+
| Helper | Signature | Use |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `multilineTextLayers` | `({ text, maxCharsPerLine, fontSize, lineHeightRatio?, hAlign? }) => MosaicTextLayer[]` | **The one you usually want.** Wraps and returns one centred layer per line, vertically stacked via `yExpr`. Feed straight into `layers`. |
|
|
71
|
+
| `wrapText` | `(text, maxCharsPerLine) => string[]` | Greedy word-wrap by character count. Never splits a word. Use when you need the lines themselves. |
|
|
72
|
+
| `makeErrorMosaic` | `(message, { width, height, title?, errorCode?, … })` | Fail-fast card that **also sets `engine.renderStatus = "error"`** — the UI disables Make, and the CLI exits **3** (RENDER DEGRADED) after writing the card. Use for invalid input, and **pass `errorCode`**: it is what lands in the `--report` sidecar's `renderErrorCodes` (omit it and the caller only sees `ENGINE_ERROR`). See `runtime/cli-usage.md` → "Exit codes". |
|
|
73
|
+
| `makeStubMosaic` | `(label, { width, height, backgroundColor?, textColor?, note? })` | "STUB" placeholder. Auto-sizes the font. Does **not** mark an error — validate-only still passes. |
|
|
74
|
+
| `animateNumbersInText` | `(text, { startSec, durationSec, ease }) => string` | Returns an `expr` that counts numbers up on intro (KPI / stat cards). |
|
|
75
|
+
| `fadeInExpr` | `(startSec, durSec, ease?) => string` | Overlay-alpha expression for a timed fade-in. |
|
|
76
|
+
|
|
77
|
+
> `multilineTextLayers` returns `[]` for empty input — **check and omit the source**
|
|
78
|
+
> rather than emitting a text tile with no layers.
|
|
79
|
+
|
|
80
|
+
> `makeErrorMosaic` vs `makeStubMosaic` is a real distinction, not a style choice:
|
|
81
|
+
> error blocks the render path, stub does not. Reach for stub only when "not
|
|
82
|
+
> implemented yet" is a legitimate state.
|
|
83
|
+
|
|
84
|
+
Both size their cards from dimensions **you** pass — pass `ctx.target.{width,height}`,
|
|
85
|
+
never `ctx.output` (see `rendering-model-contract.md` Rule 5b).
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Sizing
|
|
90
|
+
|
|
91
|
+
`maxCharsPerLine` is coarse — glyph widths vary by font. Start from:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
maxCharsPerLine = floor(cellWidthPx / (fontSize * 0.55))
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
and tune per font. **Scale `fontSize` to the cell** — `clamp(width / N, lo, hi)` —
|
|
98
|
+
rather than hard-coding pixels, so the template survives a resolution change.
|
|
99
|
+
|
|
100
|
+
### Canonical wrapped, centred text tile
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { multilineTextLayers } from "@m0saic/template-utils";
|
|
104
|
+
|
|
105
|
+
function textTile(text: string, fontSize: number, bg: string, cellWidth: number) {
|
|
106
|
+
const maxChars = Math.max(8, Math.floor(cellWidth / (fontSize * 0.55)));
|
|
107
|
+
return {
|
|
108
|
+
type: "text" as const,
|
|
109
|
+
style: { fontSize, fontColor: "#ffffff", fontFamily: "Arial" },
|
|
110
|
+
layers: multilineTextLayers({ text, maxCharsPerLine: maxChars, fontSize }),
|
|
111
|
+
visual: { backgroundColor: bg },
|
|
112
|
+
renderMode: { kind: "image" as const },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Related
|
|
120
|
+
|
|
121
|
+
- **`templates/patterns/perf-authoring-rules.md` R9** — rasterizer choice + density budgets.
|
|
122
|
+
- **`templates/construction-strategy.md`** — "Drawing shapes: SVG inline-mask on a
|
|
123
|
+
color source". Text is for *words*; never draw a shape with a glyph — ffmpeg drops
|
|
124
|
+
`▲`/`▼`/emoji as tofu.
|
|
125
|
+
- **`templates/rendering-model-contract.md` Rule 5b** — size error/stub cards off
|
|
126
|
+
`ctx.target`.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# The `0{}` operator — phantom geometry, deferred paint
|
|
2
|
+
|
|
3
|
+
`0` is a passthrough: it donates its space to the next claimant and renders nothing.
|
|
4
|
+
`0{...}` is a passthrough whose overlay still renders: the base donates space as
|
|
5
|
+
usual, but the body receives the accumulated carry rect and **paints on top of the
|
|
6
|
+
claimant, deferred**. An element that gives its space away, then draws over the
|
|
7
|
+
sibling that absorbed it. Trimmed 2026-07-27 from a longer essay (git history).
|
|
8
|
+
|
|
9
|
+
> **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)
|
|
10
|
+
> (+ `parse/sortDeferredOverlays.ts`). Basics: [`passthrough-semantics.md`](passthrough-semantics.md),
|
|
11
|
+
> [`overlay-semantics.md`](overlay-semantics.md).
|
|
12
|
+
|
|
13
|
+
## The four quadrants
|
|
14
|
+
|
|
15
|
+
| | Owns space | Doesn't own space |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| **Paints** | `1` (tile) | `0{}` (phantom overlay) |
|
|
18
|
+
| **Doesn't paint** | `-` (null gap) | `0` (passthrough) |
|
|
19
|
+
|
|
20
|
+
`0{}` is the fourth quadrant: spatial accounting and visual presence, fully
|
|
21
|
+
decoupled.
|
|
22
|
+
|
|
23
|
+
## The mechanism (verified at runtime)
|
|
24
|
+
|
|
25
|
+
`3(1, 0{1}, 1)` @ 1080×720 — three 360px slots; the `0` donates, the last tile
|
|
26
|
+
claims 720px; the overlay body gets the merged carry rect and paints LAST:
|
|
27
|
+
|
|
28
|
+
| Paint order | What | Rect | `logicalIndex` |
|
|
29
|
+
|---|---|---|---|
|
|
30
|
+
| 0 | first tile | `{x:0, w:360}` | 0 |
|
|
31
|
+
| 1 | claimant (expanded) | `{x:360, w:720}` | 2 |
|
|
32
|
+
| 2 | deferred zero-overlay | `{x:360, w:360}` | 1 |
|
|
33
|
+
|
|
34
|
+
Note the split between orders: the overlay is `logicalIndex` **1** (encountered
|
|
35
|
+
before the claimant in DFS) but paints **after** it. Build sources in logical
|
|
36
|
+
order; paint order is derived.
|
|
37
|
+
|
|
38
|
+
**Multiple `0{...}` before one claimant sort area-DESCENDING at flush** — widest
|
|
39
|
+
paints first (background), narrowest last (top). `5(0{1},0{1},0{1},0,1)` @1000px:
|
|
40
|
+
claimant 1000px paints first, then 600 → 400 → 200 on top. Free z-ordering from
|
|
41
|
+
coverage, no z-index.
|
|
42
|
+
|
|
43
|
+
**Rects grow monotonically:** each `0{...}` in a run captures the prefix sum of
|
|
44
|
+
slot widths, anchored at the run start — `4(0{1},0{1},0{1},1)` @800px yields
|
|
45
|
+
overlays at `{x:0, w:200/400/600}` under a full-width claimant. Concentric framing
|
|
46
|
+
from pure geometry.
|
|
47
|
+
|
|
48
|
+
**Trailing `0{}` is always invalid** — `PASSTHROUGH_TO_NOTHING`; an overlay does
|
|
49
|
+
not exempt the donation from needing a claimant. `2(1,0{1})` invalid;
|
|
50
|
+
`2(0{1},1)` valid.
|
|
51
|
+
|
|
52
|
+
## The body is a full m0 sub-expression
|
|
53
|
+
|
|
54
|
+
Splits, nulls, passthroughs, nested overlays — all legal inside `0{...}`, parsed
|
|
55
|
+
into the merged rect like an independent document. So a phantom can carry an entire
|
|
56
|
+
sub-layout: holes that let the claimant show through (`0{4(1,-,-,1)}`), stacked
|
|
57
|
+
rows (`0{3[1,1,1]}`), thin gridline rules at precise offsets
|
|
58
|
+
(`0{100[0,…,1,…,0,1,…]}`), even nested overlay depth (`0{2(1{1},1{1})}` — four
|
|
59
|
+
sources from one zero-space element). Source count = whatever the body demands.
|
|
60
|
+
|
|
61
|
+
## Patterns (one line each)
|
|
62
|
+
|
|
63
|
+
- **Floating annotation** — grid-positioned callout over an expanded tile's region.
|
|
64
|
+
- **Progressive reveal** — monotone widths + per-source `startAtSec`: layers peel
|
|
65
|
+
front-to-back.
|
|
66
|
+
- **Gradient banding** — N phantoms at fractional widths, solid colors at
|
|
67
|
+
decreasing opacity.
|
|
68
|
+
- **Watermark/badge** — a tiny phantom deep in a 100-split places a corner stamp;
|
|
69
|
+
content and stamp stay structurally independent.
|
|
70
|
+
- **Conditional layer** — phantom sources honor `overlay.enable` windows: a flash
|
|
71
|
+
highlight with zero structural change.
|
|
72
|
+
- **Debug overlay** — inject `0{1}` tints/labels during development; removing `{1}`
|
|
73
|
+
restores the bare `0` with geometry untouched.
|
|
74
|
+
|
|
75
|
+
## When `0{}` is wrong
|
|
76
|
+
|
|
77
|
+
- The layer should CLAIM space (push siblings) → use `1` or `-`.
|
|
78
|
+
- The template has many sources and non-expert consumers → the logical/paint order
|
|
79
|
+
split confuses source mapping; keep `0{}` inside internal primitives.
|
|
80
|
+
|
|
81
|
+
## For agents
|
|
82
|
+
|
|
83
|
+
You will almost never need `0{}` — `1`, `-`, `0`, and `1{1}` cover ~99% of
|
|
84
|
+
layouts. Reach for it only when all three hold: (1) a visual layer at a specific
|
|
85
|
+
grid position, (2) painting on top of whatever fills that region, (3) claiming no
|
|
86
|
+
layout space. When all three hold, `0{}` is the correct expression, not a
|
|
87
|
+
workaround.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# templates/ — the authoring surface
|
|
2
|
+
|
|
3
|
+
Read as a path: **contract → build → verify → publish**. The required authoring
|
|
4
|
+
process (add / deprecate / tests / registry) is the agent contract §10 — not
|
|
5
|
+
duplicated here.
|
|
6
|
+
|
|
7
|
+
## The path
|
|
8
|
+
|
|
9
|
+
1. [`philosophy-and-contract.md`](philosophy-and-contract.md) — what a template
|
|
10
|
+
IS: the typed contract, ctx.target vs ctx.output, tiers, props-as-schema.
|
|
11
|
+
- **Defaults are part of the contract**: every optional boolean / closed-set
|
|
12
|
+
knob carries a `defaultProps` value, every plain string/number a default or
|
|
13
|
+
a placeholder — enforced inside `defineMosaicTemplate` (throws first-party).
|
|
14
|
+
2. [`construction-strategy.md`](construction-strategy.md) — how to build one:
|
|
15
|
+
the Rect Thesis, styles, smell tests.
|
|
16
|
+
- **Constraints first.** Declare the props contract and the layout
|
|
17
|
+
constraints, THEN build, THEN check in a loop across canvases × prop
|
|
18
|
+
combinations; the build itself is the first gate —
|
|
19
|
+
[`standalone-pack-authoring.md`](standalone-pack-authoring.md) §0.
|
|
20
|
+
3. [`geometry-recipes.md`](geometry-recipes.md) — the four placement recipes
|
|
21
|
+
(SNAP_PX · placeInsetPieces · placeOptimizedPieces · lattice ratio-grid).
|
|
22
|
+
4. [`rendering-model-contract.md`](rendering-model-contract.md) — the 12-rule
|
|
23
|
+
output contract the engine holds you to.
|
|
24
|
+
- [`output-resolution-tree.md`](output-resolution-tree.md) — how top-level
|
|
25
|
+
duration / size / fps / format / audio resolve (user > template intent >
|
|
26
|
+
host hints > engine defaults); read before touching any of them.
|
|
27
|
+
5. [`layout-contract.md`](layout-contract.md) — verify layout intent
|
|
28
|
+
(withLayoutContract / checkLayout / assertLayout). **Before the first
|
|
29
|
+
candidate** for anything that paints text: tag fitted text, declare
|
|
30
|
+
`textFits`, sweep `assertLayout` at the 7-canvas set in the gate test.
|
|
31
|
+
|
|
32
|
+
## By topic
|
|
33
|
+
|
|
34
|
+
- [`recursion-nested-rendering.md`](recursion-nested-rendering.md) — children,
|
|
35
|
+
bottom-up eval, nested-mosaic-as-clip-region.
|
|
36
|
+
- [`data-pipeline.md`](data-pipeline.md) — fetcher / adapter / handle patterns +
|
|
37
|
+
the operational how-to.
|
|
38
|
+
- [`render-lifecycle.md`](render-lifecycle.md) — the four entry points
|
|
39
|
+
(`render` required; `renderLite` / `renderCover` / `renderTutorial` opt-in),
|
|
40
|
+
the null-on-absent dispatch rule, and the onboarding-surface checklist.
|
|
41
|
+
- [`capability-templates.md`](capability-templates.md) — self-fetch app-runnable
|
|
42
|
+
templates; renderLite rules.
|
|
43
|
+
- [`emission-patterns.md`](emission-patterns.md) — non-pixel outputs (data /
|
|
44
|
+
sidecars / telemetry).
|
|
45
|
+
- [`theming.md`](theming.md) — design tokens over the upstream channel.
|
|
46
|
+
- [`ui-controls.md`](ui-controls.md) — the `picker` taxonomy + prop controls.
|
|
47
|
+
- [`standalone-pack-authoring.md`](standalone-pack-authoring.md) — branded pack
|
|
48
|
+
playbook (alpine is the reference).
|
|
49
|
+
|
|
50
|
+
## reference/ — lookup specs (types & builders)
|
|
51
|
+
|
|
52
|
+
[`placement-props`](reference/mosaic-placement-props.md) ·
|
|
53
|
+
[`prop type: json`](reference/json-prop-type.md) ·
|
|
54
|
+
[`template flags`](reference/template-flags.md) ·
|
|
55
|
+
[`grid builder`](reference/grid.md) · [`MosaicColor`](reference/mosaic-color.md) ·
|
|
56
|
+
[`prop bindings`](reference/prop-bindings.md)
|
|
57
|
+
|
|
58
|
+
## patterns/ — distilled experience
|
|
59
|
+
|
|
60
|
+
- [`perf-authoring-rules.md`](patterns/perf-authoring-rules.md) — R1–R11, each
|
|
61
|
+
paid for by a measured incident. Read before shipping any template.
|
|
62
|
+
- [`case-study-lessons.md`](patterns/case-study-lessons.md) — L1–L9 from the
|
|
63
|
+
early template generation.
|
|
64
|
+
- [`primitive-extraction-pattern.md`](patterns/primitive-extraction-pattern.md)
|
|
65
|
+
— when/how to extract primitives (incl. Rule 7: verify NESTED).
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Capability-tier templates
|
|
2
|
+
|
|
3
|
+
The tier contract itself (what `{ tier: "capability", caps }` unlocks, default-deny
|
|
4
|
+
caps, when to stay core) lives in [`philosophy-and-contract.md`](philosophy-and-contract.md).
|
|
5
|
+
This doc carries the two shipped patterns that go beyond the contract: app-runnable
|
|
6
|
+
self-fetch templates, and the `renderLite` preview rule.
|
|
7
|
+
|
|
8
|
+
> **Source of truth:** capability declaration shape in
|
|
9
|
+
> https://github.com/m0saic-project/m0saic-packages/blob/main/packages/template-utils/src/template/defineMosaicTemplate.ts; the shipped exemplar
|
|
10
|
+
> `@m0saic/github/weekly-pulse/v1` (https://github.com/m0saic-project/m0saic-packages/blob/main/packages/templates/src/m0saic/github/weekly-pulse/v1).
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## App-runnable capability templates (self-fetch)
|
|
15
|
+
|
|
16
|
+
The `.mosaicx`/cron chain (fetcher → adapter → runner) can't run from the Templates
|
|
17
|
+
UI — the core runner is core-tier (mock/upstream only) and the live chain only exists
|
|
18
|
+
as a `.mosaicx`. The shipped pattern: a single **capability-tier** template that IS the
|
|
19
|
+
whole chain in one pickable unit — `@m0saic/github/weekly-pulse/v1`. It
|
|
20
|
+
`fetch → derive → render`s itself when flipped to `source: "live"` (+ repo + token),
|
|
21
|
+
and replays a frozen sample by default (network-free).
|
|
22
|
+
|
|
23
|
+
- It's a **plain-object** `MosaicTemplate` (not `defineMosaicTemplate`) because it
|
|
24
|
+
returns a duration-follows-timings pipeline, so it skips the wrapper's
|
|
25
|
+
`assertTiming` (the CLI `make` path still applies assertTiming — a plain object
|
|
26
|
+
does NOT escape it there).
|
|
27
|
+
- It reuses the runner's extracted `buildPulsePipeline`, so the app-runnable version
|
|
28
|
+
and the cron runner emit the identical beat pipeline.
|
|
29
|
+
- A template can't be "core sometimes, capability sometimes" — the app-runnable live
|
|
30
|
+
version is a SEPARATE capability template, leaving the runner core-tier for the
|
|
31
|
+
cron path.
|
|
32
|
+
|
|
33
|
+
### Live-mode clock exception
|
|
34
|
+
|
|
35
|
+
An app-runnable capability template MAY read the wall clock for ONE thing: a
|
|
36
|
+
live-mode default window (`props.window ?? lastFullWeek(now)`), documented as a
|
|
37
|
+
deliberate exception to the clock rule (this template is non-deterministic in live
|
|
38
|
+
mode by design). Pinning `window` or using the cron `{{lastFullWeek*}}` tokens keeps
|
|
39
|
+
it deterministic. Replay mode never reads the clock. A `livePreview: true` escape
|
|
40
|
+
hatch lets power users fetch real data into the geometric preview on demand.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## renderLite is PREVIEW-ONLY (RenderHero uses the real render geometry)
|
|
45
|
+
|
|
46
|
+
> `renderLite` is one of FOUR render entry points, and it is not a capability-tier
|
|
47
|
+
> feature — a core template may declare it too. The lifecycle contract for all
|
|
48
|
+
> four (including the opt-in `renderCover` / `renderTutorial` onboarding
|
|
49
|
+
> surfaces) is [`render-lifecycle.md`](render-lifecycle.md). This section keeps
|
|
50
|
+
> the part that IS capability-specific: why a self-fetching template's stand-in
|
|
51
|
+
> must never reach RenderHero, and the `renderable_ready` wiring that avoids it.
|
|
52
|
+
|
|
53
|
+
`renderLite()` returns a stand-in (a themed "ready" card) so selecting a
|
|
54
|
+
side-effecting template never runs its real work. It must feed ONLY the idle-state
|
|
55
|
+
GeometricPreview — NEVER the render-progress hero (RenderHero), which would otherwise
|
|
56
|
+
show the card while ffmpeg renders the real beats. Shipped wiring:
|
|
57
|
+
|
|
58
|
+
- `templates:get` returns `hasRenderLite: typeof tmpl.renderLite === "function"` so
|
|
59
|
+
the host/UI knows a preview is a stand-in.
|
|
60
|
+
- `templates:renderToFile`: right after the real `render()` (BEFORE ffmpeg's
|
|
61
|
+
`render_start`), for renderLite templates the host forwards the resolved renderable
|
|
62
|
+
via a `renderable_ready` renderEvent.
|
|
63
|
+
- MakePage captures it as `liveRenderable` and flattens THAT into the hero filmstrip;
|
|
64
|
+
a stand-in preview never drives the hero. Until `renderable_ready` lands (a few ms)
|
|
65
|
+
or if it can't be flattened, the hero shows the neutral loader — never the card.
|
|
66
|
+
Core templates (no renderLite) are unchanged: their preview already IS the render
|
|
67
|
+
geometry.
|
|
68
|
+
|
|
69
|
+
**Rule for authors/hosts:** if `render()` returns geometry structurally different
|
|
70
|
+
from `renderLite()` (as any self-fetching capability template does), the host must
|
|
71
|
+
not reuse the renderLite doc for render-progress; it must hook the real `render()`
|
|
72
|
+
output.
|