Every page carried a frontmatter `title` and repeated it as a body `# `, which
the site renders as two headings with two permalinks. The heading text matched
the frontmatter on 41 of the 43 pages; on the two quickstarts it did not, so
"Make a video with your Agent" and "和 Agent 一起制作视频" give way to the
titles already in their frontmatter.
Each step's video now sits directly under that step's heading rather than after
its prose, and the avatars link keeps a blank line beneath it.
Speech publishes semantic timing and original audio. Media Performance and project components consume the prepared material, preserving source offsets across Takes while controlling their own framing and motion.
Add explicit renderer programs for coordinated HTML/CSS/JavaScript scenes, with typed media children, backdrop filtering and blending. Remove stand-in and estimated-take preview paths, migrate Sources and documentation, and demonstrate a Moment-driven video-to-diagram handoff.
Replace the vague MiMo TTS surface with explicit Voice Design, Voice Reference and Voice Clone capabilities. Keep model semantics in mimo-speech, provider transport in Xiaomi MiMo and HypiHub, and update examples to reuse the same accepted voice reference.
estimate:Speech leaves the Author Surface and the Build graph. A duration
is the author's decision, written as a literal on the element that needs
it; the graph computes none, so a Build plan is complete before it starts.
- @hypit/estimate keeps only the measurement library and the
SpeechEstimatePolicy type; its Surface, Producer and fragment are gone.
Policies can be read from an SVS Recipe or from attributes.
- hypit measure joins the creation tools: it counts a Segment's
pronunciation units from the compiled author source (or --text) at the
chosen delivery policy and prints the seconds to write as the literal.
- seedance: duration is a literal only; the DurationProgram deferral, its
type, producers, fragment and schema are removed.
- media:StillVideo: duration is a literal in seconds, published as an
ordinary SpeechDuration Record for its plan step.
- estimated:SemanticTake owns its policy, inline or as policy={recipe},
and publishes it as <id>.policy.
- preview-mock reads program duration from SpeechDuration Records and the
duration port of generation requests; compiler-node's plan-time
pre-evaluation of estimate is removed.
- The 13 example sources and the media-track preview carry the seconds
hypit measure produced for each Segment; the quickstart, styles and
packages guides and the Skill's twelve passages describe the literal.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`b32e8253` replaced both Playgrounds with `packages/studio`, but the rename
stopped at `examples/`. The skill and the docs still named the tool, the
command and the recipe sheet that no longer exist.
`studio.svs` becomes `recipes.svs` with its import alias, in the 39 files the
examples rename had left behind — docs, the `docs/zh` mirrors, the skill
references and the package manifests whose authoring snippets show the alias.
The old name was already loose, since an `.svs` file is a parameter-recipe
sheet rather than anything Studio reads; once `studio` names the application
it reads as Studio's own config file, which it is not. Two test fixtures keyed
the alias as a plain string rather than inside `{}`, so they moved with it —
`packages/text` had a real reference to `recipes.shot` resolving against a
`studio.shot` fixture.
`pnpm svml:playground -- --source main.svml` becomes `pnpm studio -- --run
build.svrun` throughout. The Run Source is not an optional extra any more:
Studio's unit of work is the Run, and it reads the Author SVML back out of it.
`preview-check.mjs` imported `svml-playground/src/pipeline/preview.js`, which
this branch deleted, so the skill's own build gate had been dead since
`b32e8253`. It is rebuilt on Studio's real entry path — `loadStudioDomain`,
`loadStudioRun`, `inspectStudioRun`, `readStudioSession` — and reports
`provenance.errors` and unresolved Candidates instead of the `waiting` and
`stand-in` fields Studio no longer has. It stays in URL space for Windows, as
`e0ecccb9` established, and closes the archive before exiting rather than
leaving it open behind a `process.exit` in a `try`.
The preview pages are rewritten rather than renamed, because what they
describe is gone. Studio has no stand-ins, no black frames and no estimated
timing; it refuses to open and names what is missing. So the pages document
the five refusals verbatim, and say plainly that a Source still declaring
ungenerated shots will not open — including the warning that no example in
this repository currently does. Running the ported check over all nine
committed Run Sources: six refuse on unresolved capabilities or a target that
is not a Film, and three on footage under the gitignored `examples/**/assets/`.
Claiming otherwise would have shipped a quickstart whose first command fails.
`pnpm check` clean; `pnpm test` 510 pass, 0 fail; `pnpm test:release` 8 pass.
TierBoard, Column and TopThree remain. The Typewriter variant's Types,
Producers, Surface, schedule, render, fragment and Style paths are gone, along
with the helpers that only it used: grapheme splitting, its stage fit, the
package's only text-flow element, and the prefix and defaults generality of the
typography decoder.
Three chains had the Typewriter branch as their terminal else. Each one now
ends on a surviving variant with an explicit failure for an unknown one, rather
than relying on a fall-through. The browser visual test's canvas shrinks to the
content that remains.
Drop the playbook section that told the agent when to start the
playground, the package README, and the Layer 7 listing line in both
language editions. The package and its pnpm script stay in place.
The Playgrounds were already workspace packages: each has a manifest, sits in
the workspace, and depends on other packages through `workspace:*`. Only their
directory said otherwise, and it said so at a cost.
`packages/` is where the seven architectural layers live, and Layer 7 is
Applications: `cli` and `video-cli` already sat there. The Playgrounds are
Applications too, so they belong beside them. The repository layout guide
already described this arrangement, naming `tools/` as "boundary tests and
build scripts" and the workspace as a single `packages/*` glob; the layout had
drifted from the documentation rather than the reverse.
Moving them collapses three globs into one and lets the per-package import
boundary reach 36 files it could not see, because that check is scoped to
`packages/*/(src|test)/`. It immediately found one: svml-playground read
`@narratage/runtime-local/config` without declaring the dependency, which
resolved only by walking up to the root install. Declared now.
Update 30 doc files (EN+ZH) to match the visual layer rewrite:
- broll → media-track with SpatialFrame positioning and appearance/motion split
- caption:Style/Track → caption-fine:Style/Track with cue bounds and font binding
- text position props removed, text:Style/text:Area with explicit font bytes
- Film Recipe loses canvas dimensions → space:Canvas graph value
- speech:Spine gains canvas= attribute
- prompt-kit → @narratage/text, run-text → run-markup, compiler-text-node → compiler-markup-node
- SemanticMap simplified: final word windows only, no quality labels
- Four layers → five layers (Application became Layer 5)
Rename the author frontend around Markup, replace PromptKit with graph-native Text templates, and keep video typography in its own package. Wire ordinary Text through explicit graph edges into model and visible consumers, refresh examples, locks, tests, and architecture documentation.
Nothing here was unfinished. Everything removed was surplus: names kept
after a rename, helpers nobody called, a package nothing could use, and
two documentation entries describing code that does not exist.
Four aliases recorded three renamings and one duplicate class name, and
not one of them had a caller: bindingForOutput, selectedCandidate,
deriveBuildPlan, RuntimeConfigRegistry. A second name for one thing is
the failure this repository names first, and these had reached the point
where the alias was used internally while the real name was used
everywhere else.
sameProducerRef and sameProducer answered the same question two ways,
both uncalled. reference.ts holds a consistent family — sameModule,
sameType, sameCapability, sameProducer — so the odd implementation in
graph.ts went. resolveCapability and assertKnownType went with them.
transport-process is deleted. Its README expected a WhisperX or
HyperFrames Endpoint to wrap it; WhisperX became a warm HTTP service
because model loading cannot be paid per call, and the others drive
binaries that write files. The contract is one JSON document in and one
out, and every local media operation moves bytes too large or too binary
for that. Remotely the same limit is productive — it forced the media
Lambda to pass S3 locations — but locally a child process can simply open
the file, so the transport buys nothing. It can return from git history
when something actually speaks JSON.
architecture.md listed CommandDispatcher as a port with no code behind
it, and credited BuildScheduler with retry and cancellation, which live
in the execution driver. A second Scheduler implementation would have
been written against that sentence.
The new boundary test is what stops this growing back: a package must be
imported, activatable from a lock, or a declared entry point. Verified
against a planted dead package.
One process had two names. The directory, the Python package, its executable
and the repository script all said service; the wire protocol and the prose
said sidecar. Nothing distinguished them, so a reader had to learn that both
meant the same running program.
The protocol is svml.whisperx-service@1 and the Provider's implementation
locator follows it, which changes that Provider's Runtime identity — a Build
started against the old identity does not resume. Both package locks are
regenerated because the rename reached two locked READMEs as well.