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,96 @@
|
|
|
1
|
+
# "Push complexity down" — reduce to 1, then bake the constant
|
|
2
|
+
|
|
3
|
+
Two moves, applied in order. Move 1 is structural (isolate complexity); move 2
|
|
4
|
+
is temporal (stop recomputing a constant). They compose: nest, prove the knobs,
|
|
5
|
+
then bake. The user's vocabulary for this is literally **"reduce to 1"**, **"push
|
|
6
|
+
complexity down"**, and **"bake that result to a flat video file."**
|
|
7
|
+
|
|
8
|
+
## Move 1 — Reduce to 1 (nested source)
|
|
9
|
+
|
|
10
|
+
When a subtree is too complex or too precise, render it as its own **nested
|
|
11
|
+
source** (child mosaic document). In the parent it collapses to a single `F` —
|
|
12
|
+
one cell, one source ref. High-level layout stays simple; the complexity is
|
|
13
|
+
isolated one level down. It still renders every frame; you've only separated
|
|
14
|
+
concerns by precision tier (e.g. a px-baked, quantization-sensitive scatter vs.
|
|
15
|
+
resolution-independent chrome).
|
|
16
|
+
|
|
17
|
+
Mechanism: wrap the subtree as a child doc (`children[...]` + a
|
|
18
|
+
`{type:"mosaic", ref}` source) so the engine renders it into its own
|
|
19
|
+
framebuffer and the parent sees one `F`. Same primitive as nested-mosaic
|
|
20
|
+
clipping.
|
|
21
|
+
|
|
22
|
+
## Move 2 — Bake the constant (flat asset)
|
|
23
|
+
|
|
24
|
+
When a subtree is **identical on every render** — a fixed background, a
|
|
25
|
+
decorative field, a logo sting with no data dependency — don't render it at
|
|
26
|
+
runtime at all. Pre-render it **once** and reference the result as a flat asset.
|
|
27
|
+
|
|
28
|
+
How:
|
|
29
|
+
1. Author a one-off **`internal: true`** bake template whose only job is to
|
|
30
|
+
render that subtree full-canvas, opaque, at each target aspect (e.g.
|
|
31
|
+
`hero/ffmpeg-pulse/scatter-bake/v1`).
|
|
32
|
+
2. `m0saic make` it once per aspect → small `.mp4` / `.png` into the pack's
|
|
33
|
+
`_shared/assets/` (mirror to `dist` via `build:templates`).
|
|
34
|
+
3. In the real template, replace the nested subtree with one
|
|
35
|
+
`{type:"media", mediaType:"video"|"image", assetId, placement:{fit:"cover"}}`
|
|
36
|
+
source, picking the asset by aspect (`scatter-${variantKey}.mp4`).
|
|
37
|
+
4. Update the unit test: assert the `assets.<name>` ref + the `mediaType`, and
|
|
38
|
+
DROP the now-stale "child carries N tiles / animates" assertions.
|
|
39
|
+
|
|
40
|
+
Determinism still holds: a baked asset is a committed fixture, byte-identical
|
|
41
|
+
every run. Animation is fine to bake — the reveal/motion lives in the video.
|
|
42
|
+
|
|
43
|
+
## When to bake (the trigger)
|
|
44
|
+
|
|
45
|
+
> "When you notice DSL count is high **and** render is long, and the result is
|
|
46
|
+
> intended to be the same every time — bake it to a flat file."
|
|
47
|
+
|
|
48
|
+
All three must hold:
|
|
49
|
+
- **High DSL / long render** — the subtree dominates `dsl-complexity.md` metrics
|
|
50
|
+
or wall-clock.
|
|
51
|
+
- **Constant across renders** — no prop/data dependency; same pixels every time.
|
|
52
|
+
(If it varies with data, you cannot bake it — keep it live or reduce to 1.)
|
|
53
|
+
- **Knobs are locked** — bake LAST, after the look is signed off. Baking freezes
|
|
54
|
+
the subtree; re-tuning means re-baking.
|
|
55
|
+
|
|
56
|
+
## When NOT to bake
|
|
57
|
+
|
|
58
|
+
- The subtree depends on props/data (varies per render) → it's not constant.
|
|
59
|
+
- The look isn't locked yet → premature; you'll re-bake every iteration.
|
|
60
|
+
- The subtree is cheap → baking adds an asset + a build step for no win.
|
|
61
|
+
|
|
62
|
+
## Measured payoff (FFmpeg-pulse title beat, 2026-06-23)
|
|
63
|
+
|
|
64
|
+
The title beat's signature background is a ~225-rect scatter with an L→R reveal —
|
|
65
|
+
the same on every render. Baking it to a flat per-aspect `.mp4`:
|
|
66
|
+
|
|
67
|
+
| Metric | Live scatter (inlined) | Baked scatter (1 video src) | Change |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| Wall-clock render (1920×1080, 9 s) | ~5 min | 66 s | ~4.5× faster, ~78% less |
|
|
70
|
+
| Flattened `.mosaic` size | ~163 K chars | 3,838 chars | ~98% smaller |
|
|
71
|
+
| Flattened source count | 238 | 14 | ~94% fewer |
|
|
72
|
+
| Baked asset size | — | ~98–155 KB / aspect | one-time, reused |
|
|
73
|
+
|
|
74
|
+
One-time bake cost ~3 m 21 s/aspect, amortized over every future render (it pays
|
|
75
|
+
for itself after ~1 render). The residual 66 s is the **chrome-overlay floor** —
|
|
76
|
+
the variable, prop-driven work that legitimately stays live. The bake removed the
|
|
77
|
+
*constant* cost and left only the *variable* cost; that's the whole point.
|
|
78
|
+
|
|
79
|
+
## Trade-offs
|
|
80
|
+
|
|
81
|
+
- **Inline:** one flat doc, simplest pipeline; fat parent m0, mixed precision
|
|
82
|
+
tiers, depth accrues toward the ~25-layer overlay mask ceiling (see
|
|
83
|
+
`feasibility-precision-quantization.md` and the overlay-depth limit), full cost
|
|
84
|
+
every render.
|
|
85
|
+
- **Reduced to 1 (nested):** clean parent, isolated complexity, dodges the mask
|
|
86
|
+
ceiling; still full render cost (the subtree still renders).
|
|
87
|
+
- **Baked (flat asset):** near-zero per-render cost for that subtree, tiny
|
|
88
|
+
parent; but adds a committed asset + a one-off bake template + a build step, and
|
|
89
|
+
the subtree is frozen (re-tune ⇒ re-bake).
|
|
90
|
+
|
|
91
|
+
## Adjacent
|
|
92
|
+
|
|
93
|
+
`dsl-complexity.md` (metrics → *when*), `feasibility-precision-quantization.md`
|
|
94
|
+
(precision tiers + the mask ceiling), nested-mosaic clipping (the move-1
|
|
95
|
+
mechanism). The shipped reference for a constant-subtree bake is
|
|
96
|
+
https://github.com/m0saic-project/m0saic-packages/blob/main/packages/templates/src/m0saic/hero/ffmpeg-pulse/scatter-bake/v1.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# skills/ — DSL & engine mental models
|
|
2
|
+
|
|
3
|
+
Operational skills layered on the handbook. **The handbook is canonical** — a doc
|
|
4
|
+
here that restates grammar is a checklist form of the same rules, and on any
|
|
5
|
+
conflict [`../handbook/`](../handbook/README.md) wins.
|
|
6
|
+
|
|
7
|
+
## Grammar & construction (emitting valid m0)
|
|
8
|
+
|
|
9
|
+
- [`structural-construction.md`](structural-construction.md) — the build-time
|
|
10
|
+
rule checklist (count-exactness, overlay discipline, trailing-passthrough).
|
|
11
|
+
- [`m0saic-string-generation.md`](m0saic-string-generation.md) — programmatic
|
|
12
|
+
generation: builders first, unified transforms, validate, repair loop.
|
|
13
|
+
- [`dsl-stdlib-method-catalog.md`](dsl-stdlib-method-catalog.md) — pointer to
|
|
14
|
+
the full stdlib catalog (colocated with the package).
|
|
15
|
+
|
|
16
|
+
## Geometry & semantics (what the parser does)
|
|
17
|
+
|
|
18
|
+
- [`axis-and-geometry.md`](axis-and-geometry.md) — split axes, `splitEven`
|
|
19
|
+
remainders, rect propagation.
|
|
20
|
+
- [`passthrough-semantics.md`](passthrough-semantics.md) — `0` donation runs,
|
|
21
|
+
claimants, carry scoping.
|
|
22
|
+
- [`overlay-semantics.md`](overlay-semantics.md) — **the overlay anchor**:
|
|
23
|
+
attachment, bodies, deferred paint order.
|
|
24
|
+
- [`zero-overlay-analysis.md`](zero-overlay-analysis.md) — the `0{}` phantom
|
|
25
|
+
operator (rarely needed; read overlay-semantics first).
|
|
26
|
+
|
|
27
|
+
## Identity & parsing
|
|
28
|
+
|
|
29
|
+
- [`identity.md`](identity.md) — StableKey, the five axes, selection policies.
|
|
30
|
+
- [`parse-apis.md`](parse-apis.md) — which parse API to use + the
|
|
31
|
+
frames→sources bridge.
|
|
32
|
+
|
|
33
|
+
## Authoring surfaces
|
|
34
|
+
|
|
35
|
+
- [`labels-and-masks.md`](labels-and-masks.md) — labels/masks across
|
|
36
|
+
dictionary → generator → editor → disk.
|
|
37
|
+
- [`text-in-templates.md`](text-in-templates.md) — text sources, rasterizer
|
|
38
|
+
choice, sizing traps.
|
|
39
|
+
- [`more-atoms-not-bigger-atoms.md`](more-atoms-not-bigger-atoms.md) — the
|
|
40
|
+
ffmpeg scaling contract (capacity grows with atom COUNT).
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
## Axis & Geometry (Splits, Pixels, Remainders)
|
|
2
|
+
|
|
3
|
+
The math layer of the walk: exact rectangle geometry from `()` and `[]`,
|
|
4
|
+
deterministic pixel-remainder distribution (`splitEven`), and how `0`-runs and `-`
|
|
5
|
+
holes shape final rects.
|
|
6
|
+
|
|
7
|
+
> **Source of truth:** `splitEven` in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts)
|
|
8
|
+
> (line 478 as of 2026-07-27). Locked behavior: outside-in remainder distribution.
|
|
9
|
+
> Test fixtures in [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/outside-in-remainder.test.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/outside-in-remainder.test.ts).
|
|
10
|
+
|
|
11
|
+
## Axis semantics
|
|
12
|
+
|
|
13
|
+
- Column split `N( ... )` — splits **width** into N segments; height stays the
|
|
14
|
+
container's height.
|
|
15
|
+
- Row split `N[ ... ]` — splits **height** into N segments; width stays the
|
|
16
|
+
container's width.
|
|
17
|
+
|
|
18
|
+
Children are laid out in order:
|
|
19
|
+
|
|
20
|
+
- Columns advance **x** (left → right)
|
|
21
|
+
- Rows advance **y** (top → bottom)
|
|
22
|
+
|
|
23
|
+
## splitEven pixel distribution (deterministic)
|
|
24
|
+
|
|
25
|
+
When splitting an integer pixel length (`total`) into `parts`:
|
|
26
|
+
|
|
27
|
+
- `base = floor(total / parts)`
|
|
28
|
+
- `remainder = total - base * parts`
|
|
29
|
+
- The `remainder` extra pixels are distributed **outside-in**: indices
|
|
30
|
+
0, P-1, 1, P-2, 2, P-3, ...
|
|
31
|
+
- The remaining segments get `base`
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
|
|
35
|
+
- `total = 1080`, `parts = 7`
|
|
36
|
+
- `base = 154`, `remainder = 2`
|
|
37
|
+
- Outside-in order: index 0 gets +1, then index 6 gets +1
|
|
38
|
+
- Sizes: `[155, 154, 154, 154, 154, 154, 155]`
|
|
39
|
+
|
|
40
|
+
Key consequence: remainders distribute symmetrically from the edges inward, keeping
|
|
41
|
+
layouts visually balanced.
|
|
42
|
+
|
|
43
|
+
## Coordinate propagation (rects)
|
|
44
|
+
|
|
45
|
+
Every node owns a rectangle `(x, y, width, height)`. Splits carve that rect into
|
|
46
|
+
child rects:
|
|
47
|
+
|
|
48
|
+
- Column split: child width from `splitEven(width, N)`; child x = cumulative sum of
|
|
49
|
+
prior child widths; y/height unchanged.
|
|
50
|
+
- Row split: child height from `splitEven(height, N)`; child y = cumulative sum of
|
|
51
|
+
prior child heights; x/width unchanged.
|
|
52
|
+
|
|
53
|
+
Overlays always reuse the **owner rect** (same x/y/width/height) and never escape it.
|
|
54
|
+
|
|
55
|
+
## How `0` and `-` affect geometry
|
|
56
|
+
|
|
57
|
+
### `0` (passthrough)
|
|
58
|
+
|
|
59
|
+
- Consumes a split slot; adds its slot size into "carry"
|
|
60
|
+
- The claimant absorbs carry + its own slot, and snaps back to the run start position
|
|
61
|
+
|
|
62
|
+
Geometry impact: `0` changes the eventual claimant rect size and origin. `0` itself
|
|
63
|
+
creates no visible rect (but may create overlay rects via `0{...}`).
|
|
64
|
+
|
|
65
|
+
### `-` (null)
|
|
66
|
+
|
|
67
|
+
- Consumes a split slot; does NOT donate forward
|
|
68
|
+
- Creates a hole / gutter region; can still host overlays (`-{...}`)
|
|
69
|
+
|
|
70
|
+
Geometry impact: a stable region that does not affect siblings beyond consuming its
|
|
71
|
+
share of split space. Useful for isolating sub-layouts and masks.
|
|
72
|
+
|
|
73
|
+
## Why resolution matters (integer pixels)
|
|
74
|
+
|
|
75
|
+
All geometry is integer-pixel based. Two implications:
|
|
76
|
+
|
|
77
|
+
1. A layout can look "perfect" at one size and slightly biased at another, because
|
|
78
|
+
remainder pixels distribute outside-in (edges first).
|
|
79
|
+
2. Bitmap-like layouts (e.g. 64×64 encodings) require compatible output sizes,
|
|
80
|
+
otherwise meaning drifts due to integer rounding distribution.
|
|
81
|
+
|
|
82
|
+
Guidance: if a layout encodes literal grid art, render at sizes aligned to that grid
|
|
83
|
+
(multiples of the grid resolution). For feasibility guards, quantization strategy,
|
|
84
|
+
and quantization-free construction, see
|
|
85
|
+
[`../handbook/feasibility-precision-quantization.md`](../handbook/feasibility-precision-quantization.md).
|
|
86
|
+
|
|
87
|
+
## Minimal examples
|
|
88
|
+
|
|
89
|
+
Even-ish columns — `3(1,1,1)` at width=10:
|
|
90
|
+
|
|
91
|
+
- sizes = `[4,3,3]` (1 remainder pixel goes to the first edge)
|
|
92
|
+
|
|
93
|
+
Rows — `2[1,1]` at height=5:
|
|
94
|
+
|
|
95
|
+
- sizes = `[3,2]`
|
|
96
|
+
|
|
97
|
+
Donation changes claimant geometry — `3(0,1,1)`:
|
|
98
|
+
|
|
99
|
+
- first tile claims 2 slots (`0` + its own)
|
|
100
|
+
|
|
101
|
+
Hole creates gutter — `3(1,-,1)`:
|
|
102
|
+
|
|
103
|
+
- middle region is an explicit empty gutter
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# dsl-stdlib method catalog → see the package
|
|
2
|
+
|
|
3
|
+
The full `@m0saic/dsl-stdlib` method catalog (builders, transforms, queries, masks, SVG import, specialized generators) is **colocated with the package** so it can't drift from the code:
|
|
4
|
+
|
|
5
|
+
➡️ [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/.ai/method-catalog.md](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-stdlib/.ai/method-catalog.md)
|
|
6
|
+
|
|
7
|
+
That doc is regenerated/reviewed in the same change that alters the API. This file is only a pointer — don't duplicate the catalog here.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Identity — StableKey, depth axes, and selection
|
|
2
|
+
|
|
3
|
+
Merged 2026-07-27 from four overlapping docs (stablekey-and-overlay-identity,
|
|
4
|
+
identity-model, structural-vs-overlay-depth, structural-identity_visual-identity —
|
|
5
|
+
deleted; git history has the long forms). One doc, one owner: everything about
|
|
6
|
+
*referring to the same node* across parses, edits, and renders.
|
|
7
|
+
|
|
8
|
+
> **Source of truth:** `StableKey` + `M0NodeIdentity` in
|
|
9
|
+
> [https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/types.ts](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/types.ts); identity
|
|
10
|
+
> construction in [`parse/m0StringParser.ts`](https://github.com/m0saic-dsl/m0/blob/main/packages/dsl/src/parse/m0StringParser.ts)
|
|
11
|
+
> (search `buildIdentity`, `makeStableKeySegment`).
|
|
12
|
+
|
|
13
|
+
## 1. The identity contract
|
|
14
|
+
|
|
15
|
+
Every parsed node receives a deterministic `stableKey` — the address of the parser's
|
|
16
|
+
walk through **structure**. Segments encode node kind + split axis + childIndex among
|
|
17
|
+
structural siblings. Segment grammar (verified at runtime): `r` (root) ·
|
|
18
|
+
`g{row|col}c{n}` (group) · `fc{n}` (frame) · `pc{n}` (passthrough) · `nc{n}` (null) ·
|
|
19
|
+
`/ov{d}c{k}` (overlay namespace).
|
|
20
|
+
|
|
21
|
+
Same canonical string → same StableKeys, same structuralDepth, same overlay
|
|
22
|
+
namespace. If the string changes, the tree changes and some keys change — that is
|
|
23
|
+
correct, not a bug.
|
|
24
|
+
|
|
25
|
+
**StableKey is NOT:** `paintOrder` / `stackOrder` (paint depends on overlay-deferral
|
|
26
|
+
rules), display/label numbering, or geometry. Geometry is *derived* —
|
|
27
|
+
`rect = f(m0, width, height)` — and shifts with resolution and `splitEven`
|
|
28
|
+
remainders while keys stay put. The DSL guarantees **structural** identity, never
|
|
29
|
+
**visual** identity.
|
|
30
|
+
|
|
31
|
+
## 2. The five axes — keep them separate
|
|
32
|
+
|
|
33
|
+
| Axis | Increments when | Use it for |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `structuralDepth` (`meta.structuralDepth`) | entering `N(...)` / `N[...]` | tree indentation, containment reasoning |
|
|
36
|
+
| `overlayDepth` | entering `{...}` | layer filtering |
|
|
37
|
+
| `paintOrder` / `stackOrder` | derived from traversal + overlay deferral | paint simulation ONLY |
|
|
38
|
+
| `logicalIndex` | per rendered leaf, logical order | source assignment (`sources[i]`) |
|
|
39
|
+
| `stableKey` | — (structural address) | persistent identity across edits |
|
|
40
|
+
|
|
41
|
+
Worked example — `2(2(1,1),1)` (verified at runtime): the outermost split **IS the
|
|
42
|
+
root** (`stableKey: r`, structuralDepth 0); the inner group is depth **1**
|
|
43
|
+
(`r/gcolc0`); its tiles are depth **2** (`r/gcolc0/fc0`, `fc1`); the outer `1` is
|
|
44
|
+
depth **1** (`r/fc1`). There is no extra root node above the outermost split.
|
|
45
|
+
|
|
46
|
+
`1{1{1}}` has structuralDepth 0 on all three nodes and overlayDepth 0/1/2 — the two
|
|
47
|
+
depth systems are orthogonal: deep structure with zero overlays, flat structure with
|
|
48
|
+
100 overlays, or both.
|
|
49
|
+
|
|
50
|
+
Never assume `deeper == painted later` — overlay deferral (and area-descending
|
|
51
|
+
zero-overlay stacking) controls paint timing, not depth. See
|
|
52
|
+
[`overlay-semantics.md`](overlay-semantics.md).
|
|
53
|
+
|
|
54
|
+
> ⚠️ overlayDepth is structurally free but NOT render-free: each level is a
|
|
55
|
+
> sequential blend pass, and inline-masks silently drop past ~25 nested layers
|
|
56
|
+
> (engine wall W3 — internal: `.ai/moat/runtime/ffmpeg-limitations.md`).
|
|
57
|
+
|
|
58
|
+
## 3. The overlay invariant
|
|
59
|
+
|
|
60
|
+
Overlay subtrees do NOT affect structural childIndex assignment:
|
|
61
|
+
|
|
62
|
+
- Adding/removing overlays never renumbers the base tree.
|
|
63
|
+
- Overlay frames live in a separate namespace — `<ownerStableKey>/ov<depth>c<k>`
|
|
64
|
+
(`r/fc0` → `r/fc0/ov1c0` → `r/fc0/ov1c0/ov2c0`) — so overlay keys cannot collide
|
|
65
|
+
with or shift structural keys.
|
|
66
|
+
|
|
67
|
+
This is why overlays can be used freely (debug layers, labels, reveals) without
|
|
68
|
+
destabilizing the base layout or any tool keyed on it.
|
|
69
|
+
|
|
70
|
+
## 4. logicalIndex vs paintOrder
|
|
71
|
+
|
|
72
|
+
RenderFrames carry both `paintOrder` (stacking order) and `logicalIndex` (logical
|
|
73
|
+
tile index — same as `LogicalFrame.logicalIndex`; there is **no `sourceIndex`
|
|
74
|
+
field** in https://github.com/m0saic-dsl/m0/blob/main/packages/dsl). Build sources in logical order, paint in stack order —
|
|
75
|
+
the split keeps the source array clean of paint semantics. See
|
|
76
|
+
[`parse-apis.md`](parse-apis.md) for which parse API returns which.
|
|
77
|
+
|
|
78
|
+
## 5. Stability limits — what edits do to keys
|
|
79
|
+
|
|
80
|
+
Keys **WILL change** when you: change split counts, insert/remove siblings in the
|
|
81
|
+
base tree, change axis/group nesting. Keys will **NOT change** when you: add/remove
|
|
82
|
+
overlays, deepen overlay nesting, reorder overlay-only layers.
|
|
83
|
+
|
|
84
|
+
Overlay data attaches to `ownerStableKey`, so across edits: split *inside* the owner
|
|
85
|
+
→ owner survives → overlay stays valid; edit a sibling → unaffected; delete/replace
|
|
86
|
+
the owner → the overlay has no owner and cannot reattach. That last case is correct
|
|
87
|
+
behavior, not data loss to be papered over.
|
|
88
|
+
|
|
89
|
+
**Never reattach by geometry.** Preserving overlays via nearest-rect / similar-size /
|
|
90
|
+
pixel-overlap heuristics introduces non-determinism and unfixable edge cases. If the
|
|
91
|
+
owner is gone, the overlay is gone. Determinism > convenience.
|
|
92
|
+
|
|
93
|
+
## 6. Selection policies (agent workflows)
|
|
94
|
+
|
|
95
|
+
When you need to "pick a tile" — recursive growth, demos, batch transforms — pick by
|
|
96
|
+
StableKey, not geometry or paint order. Deterministic policies:
|
|
97
|
+
|
|
98
|
+
- **Smallest StableKey lexicographically** — stable across edits, cheap.
|
|
99
|
+
- **Earliest leaf in StableKey-sorted order** — a "top-left-most" that survives
|
|
100
|
+
structural change.
|
|
101
|
+
- **`(seed + step) mod leafCount`** over a StableKey-sorted leaf list — round-robin
|
|
102
|
+
demos where each step targets a different tile.
|
|
103
|
+
|
|
104
|
+
Anti-patterns: selecting by pixel position (resolution change → different
|
|
105
|
+
selection), by paint order (adding overlays shifts it), or by unsorted traversal
|
|
106
|
+
order.
|
|
107
|
+
|
|
108
|
+
## 7. Labeling
|
|
109
|
+
|
|
110
|
+
Label tiles by StableKey (`.m0c` labels are StableKey-keyed); use the label `text`
|
|
111
|
+
as the human-meaningful join key (`.m0p` regions reference labels by text). If a
|
|
112
|
+
label's key no longer exists in the current parse, `validateLabels`
|
|
113
|
+
(`@m0saic/dsl-file-formats`) flags it — see
|
|
114
|
+
[`../file-formats/m0p-and-custom-field.md`](../file-formats/m0p-and-custom-field.md) §5.
|
|
115
|
+
|
|
116
|
+
## 8. Common mistakes
|
|
117
|
+
|
|
118
|
+
- Treating overlay tiles as structural leaves — scope "leaves" iterations to the
|
|
119
|
+
base namespace; overlays live under `/ov…`.
|
|
120
|
+
- Confusing overlayDepth for structuralDepth (UI tree depth ≠ "inside another split").
|
|
121
|
+
- Hardcoding StableKey strings — they're stable across *layout* edits but computed
|
|
122
|
+
from structure; always derive them from a parse, never string-match literals.
|
|
123
|
+
- Assuming paintOrder reflects structure — it's derived, overlay rules own it.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Labels and Masks
|
|
2
|
+
|
|
3
|
+
How per-leaf **labels** and **masks** travel from a dictionary entry, through a
|
|
4
|
+
generator, into the editor, and back to disk. The surface spans four packages; this is
|
|
5
|
+
the single map.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. What lives where
|
|
10
|
+
|
|
11
|
+
| Layer | Shape | Home |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| **On disk** | `M0cFile` — `m0` + `labels` (`Record<StableKey, M0Label>`) + `masks` (`Record<StableKey, M0cMaskEntry \| null>`) + `fill` + `size` | https://github.com/m0saic-dsl/m0/blob/main/packages/dsl-file-formats/src/types.ts |
|
|
14
|
+
| **Dictionary entry** | `MosaicDictionaryEntry.labels` / `.masks` — same maps at runtime | https://github.com/m0saic-project/m0saic-packages/blob/main/packages/types/src/dictionary/dictionary.ts |
|
|
15
|
+
| **Editor (live)** | `m0cExtrasRef` — `{ labels, masks, derive, custom }` for the open canvas | the Mosaic Desktop / Web app source (not published) |
|
|
16
|
+
| **Generator output** | `GeneratorResult.m0c?: string` — optional serialized blob | https://github.com/m0saic-project/m0saic-packages/blob/main/packages/dictionary/src/generators |
|
|
17
|
+
|
|
18
|
+
> **`labels[k].color` ≠ the rect fill.** `labels[k].color` tints the *badge*; `fill[k]`
|
|
19
|
+
> paints the *rect*. The inspector once conflated them — don't re-conflate.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Dictionary entry convention
|
|
24
|
+
|
|
25
|
+
- An entry MAY ship **`m0saic.m0c`** instead of `m0saic.m0`. The `.m0c` is
|
|
26
|
+
authoritative; `loadEntryM0()` auto-detects by filename and **throws if both exist**.
|
|
27
|
+
- **`m0saic_src.m0`** is a read-only sibling auto-regenerated by `validate.js`, carrying
|
|
28
|
+
a `# note:` header. It exists for grep-by-DSL and human inspection. **No runtime reads
|
|
29
|
+
it** — never edit it, never treat it as a source.
|
|
30
|
+
- **`entry.masks`** (StableKey-keyed) is the canonical mask path. `entry.maskSets` /
|
|
31
|
+
`getMaskSet()` is reserved for future *named alternate* sets — no current entry uses
|
|
32
|
+
it. Don't reach for it.
|
|
33
|
+
- Positional lookup goes through `getSourceOrderStableKeys(entry)`
|
|
34
|
+
(https://github.com/m0saic-project/m0saic-packages/blob/main/packages/dictionary/src/sourceOrder.ts#L50, memoized per `(entry.id, m0.length)`).
|
|
35
|
+
See logo v2/v3 and qr-animate.
|
|
36
|
+
⚠️ **It throws when `entry.m0` isn't inlined.** Heavy entries carry a lazy
|
|
37
|
+
`entry.m0File` instead. For those, call `resolveM0saic(entry)` first and pass the
|
|
38
|
+
resolved string to the companion **`getSourceOrderStableKeysForM0(id, m0, w, h)`**.
|
|
39
|
+
The error message says this, but only after you've already hit it.
|
|
40
|
+
- One-shot migrations live in **https://github.com/m0saic-project/m0saic-packages/blob/main/packages/dictionary/tools** (not repo-root `tools/`):
|
|
41
|
+
`migrate-masks-to-m0c.mjs` converts legacy `masks.json` + `.m0` → `.m0c`;
|
|
42
|
+
`normalize-mask-paths.mjs` runs the drop-rect-shaped + snap-to-bounds cleanup. Both
|
|
43
|
+
route through `parseM0StringComplete` to turn positional masks into per-StableKey
|
|
44
|
+
entries.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 3. Generator label tiers
|
|
49
|
+
|
|
50
|
+
Every label-emitting generator exposes `labels: LabelTier`
|
|
51
|
+
(`"silent" | "signposts" | "atlas"`) built via `labelTierParam({ defaultTier })`
|
|
52
|
+
(https://github.com/m0saic-project/m0saic-packages/blob/main/packages/dictionary/src/generators/labelTier.ts).
|
|
53
|
+
|
|
54
|
+
| Tier | Emits |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `silent` | plain m0, no labels |
|
|
57
|
+
| `signposts` | named structural regions only ("hero", "feature") |
|
|
58
|
+
| `atlas` | signposts + per-cell / per-level enumeration |
|
|
59
|
+
|
|
60
|
+
`off` is accepted as a spelling alias for `silent`; **`silent` is the canonical wire
|
|
61
|
+
value**. Resolve untrusted input with `resolveLabelTier(raw, fallback)`.
|
|
62
|
+
|
|
63
|
+
### Per-generator defaults and emission path
|
|
64
|
+
|
|
65
|
+
Two emission paths, and which one a generator uses is not arbitrary:
|
|
66
|
+
|
|
67
|
+
- **`emitLabeledM0c({ m0, size, app, tier, labelsBySourceIndex, keyedLabels })`** —
|
|
68
|
+
use when labels map **positionally** to logical source order. Handles
|
|
69
|
+
source-index → stableKey translation, including a feasibility-fallback probe
|
|
70
|
+
scale-up for high-precision layouts.
|
|
71
|
+
- **Direct `serializeM0cFile`** — use when the generator must **classify nulls by
|
|
72
|
+
position** or carries masks. Parse the m0, compute the placed-content bbox, classify
|
|
73
|
+
each `kind: "null"` editorFrame by centroid offset into `padding-top` /
|
|
74
|
+
`padding-right` / `padding-bottom` / `padding-left`. The same algorithm appears in
|
|
75
|
+
every padding-classifying generator — copy it, don't re-derive it.
|
|
76
|
+
|
|
77
|
+
| Generator | Default tier | Path |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `qrCodeGenerator` | **`signposts`** | direct |
|
|
80
|
+
| `barcodeGenerator` | **`signposts`** | direct |
|
|
81
|
+
| `aspectFit` | `silent` | direct (padding classification) |
|
|
82
|
+
| `placeRect` | `silent` | direct (padding classification) |
|
|
83
|
+
| `snapGrid` | `silent` | direct (padding classification) |
|
|
84
|
+
| `aspectSafeGrid` | `silent` | direct (padding classification) |
|
|
85
|
+
| `grid` | `silent` | `emitLabeledM0c` |
|
|
86
|
+
| `spotlightGenerator` | `silent` | `emitLabeledM0c` |
|
|
87
|
+
| `magazineGenerator` | `silent` | `emitLabeledM0c` |
|
|
88
|
+
| `comparisonGenerator` | `silent` | `emitLabeledM0c` |
|
|
89
|
+
| `rankedListGenerator` | `silent` | `emitLabeledM0c` |
|
|
90
|
+
| `goldenLayout` | `silent` | `emitLabeledM0c` |
|
|
91
|
+
| `goldenSpiralGenerator` | `silent` | `emitLabeledM0c` |
|
|
92
|
+
| `safeCanvas` | `silent` | `emitLabeledM0c` |
|
|
93
|
+
|
|
94
|
+
**`silent` is the default everywhere except the two code generators** (QR, barcode),
|
|
95
|
+
which default to `signposts` to preserve their always-on label channel.
|
|
96
|
+
|
|
97
|
+
*Keep this table in sync when adding a generator — verify with
|
|
98
|
+
`grep -A3 "labelTierParam(" https://github.com/m0saic-project/m0saic-packages/blob/main/packages/dictionary/src/generators/*.ts.*
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 4. Editor rendering and drop rules
|
|
103
|
+
|
|
104
|
+
**Chip render gate** — `Frame.tsx`: `canShowLabel = hasLabel && minPx >= 70`. There is
|
|
105
|
+
**no kind filter here**: frames, plain nulls, and passthroughs all wear chips once
|
|
106
|
+
mounted. Visibility moved upstream to the `showNullFrames` toggle, which controls
|
|
107
|
+
whether nulls reach `displayFrames` at all.
|
|
108
|
+
|
|
109
|
+
**Drop-label remap** — `ViewFrame.tsx` `buildDropZone`:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const isLabelable = (f) => f.kind === "frame" || f.kind === "null";
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
⚠️ **The root node is deliberately excluded.** Including it shifts every
|
|
116
|
+
position-slice mapping by one — the off-by-one that mislabeled aspectFit's `content`.
|
|
117
|
+
Bare-`F` drops (canvas was `"r"`) take a separate path: the new canvas *is* the dropped
|
|
118
|
+
m0, so labels apply with their original keys.
|
|
119
|
+
|
|
120
|
+
> **Name collision — two different `isLabelable`.** `ViewFrame`'s is **node-kind**
|
|
121
|
+
> based (above). `App.tsx`'s is **format** based
|
|
122
|
+
> (`loadedFormat === "m0c" || loadedFormat === "m0p"` — can this file carry labels at
|
|
123
|
+
> all). Same identifier, unrelated meanings, different files. Check which one you're
|
|
124
|
+
> reading.
|
|
125
|
+
|
|
126
|
+
**Why no `isLogicalOwner` requirement.** aspectFit-style generators label plain `-`
|
|
127
|
+
nulls (border padding). Requiring `-{...}` overlay anchors would force every
|
|
128
|
+
padding-labeling generator to wrap each null in an overlay purely to make it visible.
|
|
129
|
+
The relaxed rule lets any structural node carry a label, matching the `.m0c` format's
|
|
130
|
+
own permissiveness.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 5. Undo participation
|
|
135
|
+
|
|
136
|
+
`useUndoRedoText(initial, { onCommit, onUndo, onRedo })` exposes side-channel
|
|
137
|
+
callbacks. `App.tsx` snapshots `{ labels, masks }` from `m0cExtrasRef` into a parallel
|
|
138
|
+
stack on every text commit, and restores on undo/redo.
|
|
139
|
+
|
|
140
|
+
- Manual `setFrameLabel` edits **between** commits don't push their own entry — they're
|
|
141
|
+
absorbed into the *next* commit's snapshot. So manual label → text edit → Ctrl-Z
|
|
142
|
+
restores the manual label too.
|
|
143
|
+
- Drop-derived labels vanish cleanly on Ctrl-Z because the snapshot at the drop's commit
|
|
144
|
+
is taken **before** the handler merges drop labels (`setProfileText` calls `onCommit`
|
|
145
|
+
synchronously, ahead of the `m0cExtrasRef` mutation). This ordering is load-bearing.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 6. UI affordances
|
|
150
|
+
|
|
151
|
+
- **The dictionary panel's drag chip is the sole apply path.** Click-drag splices into a
|
|
152
|
+
frame; double-click replaces the canvas (confirm modal when the canvas has structure;
|
|
153
|
+
bare-`F` skips the prompt). The standalone "Use Layout" button was **removed** — it
|
|
154
|
+
duplicated the pipeline and kept drifting.
|
|
155
|
+
- **Save-As gates `.m0`** whenever labels or masks exist (`m0SaveBlocked` in `App.tsx`).
|
|
156
|
+
Both the Cmd/Ctrl+S guard and the format chooser respect it — a `.m0` save would
|
|
157
|
+
silently drop the sidecar maps.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 7. Settled items (don't re-debate)
|
|
162
|
+
|
|
163
|
+
- `aspectSafeGrid` carries m0c only on the **landscape primary** variant; portrait
|
|
164
|
+
alternates don't support m0c yet. Noted in its labels-param description.
|
|
165
|
+
- `LabelTier` naming is **settled**. Renaming touches ~14 generators plus the panel UI.
|
|
166
|
+
- Outer-gutter nulls in `safeCanvas` are **not** labeled — canvas margin, not
|
|
167
|
+
addressable cells.
|
|
168
|
+
|
|
169
|
+
**Related:** `file-formats/m0p-and-custom-field.md` covers `.m0c`'s sibling format but
|
|
170
|
+
predates this convention — read this doc for the entry convention and tier param.
|