Commit Graph

66 Commits

Author SHA1 Message Date
kashorin 68f1693645 refactor: publish video-domain packages independently for 0.3.1 2026-10-09 18:13:50 +08:00
kashorin d7b38b7094 refactor: make caption cues authored content 2026-10-09 00:34:14 +08:00
kashorin a4c25ea76b refactor: make narrative projection an explicit author relation 2026-10-08 15:42:44 +08:00
kashorin 682b221c81 refactor: require named temporal values at component boundaries 2026-10-08 14:38:26 +08:00
kashorin 9559574f74 refactor: make caption timing a complete unit table 2026-10-08 14:13:14 +08:00
kashorin 836349e8e8 refactor: separate temporal anchors from audiovisual composition 2026-10-07 20:44:29 +08:00
kashorin 205bfeb98d refactor: establish the adaptive composition model 2026-10-07 20:44:28 +08:00
rpone fe44981a19 fix(caption): give each Caption unit one owner at projection time
An aligner reports each word ending where the next one begins, and
`tokenFrameSpan` keeps the frame that instant falls in, so adjacent Word
windows overlap by one frame. Cue boundaries inherited that overlap, and a
renderer that draws Cues at a single position drew two of them on the same
frame.

`exclusiveActivationFrames` in `@hypit/caption-fine` already states the rule
for Atoms: as soon as the next authored unit starts, the previous one stops.
Apply it once where unit timings are built. A Cue envelope ends at its last
unit, so exclusive Cue boundaries follow. The Timeline keeps the raw Token
measurements.

Closes #297.
2026-09-18 16:45:17 +08:00
kashorin bd728d05b9 feat(script)!: delimit semantic markers and preserve caption spacing 2026-09-17 06:58:25 +08:00
kashorin 395775536d feat(script): support shared display and speech alignment units 2026-09-14 23:29:11 +08:00
kashorin b679e32192 refactor: unify adaptive timeline and presentation composition
Place prepared Takes on an independent Timeline with gaps and overlaps. Present picture, sound and captions through explicit Use rules while preserving source timing and project-authored styles.

Unify Companion bands, parameter ownership and source writeback in Studio. Migrate components, examples and authoring guidance, remove retired Speech/Semantic Track interfaces, and retain protocol identifiers at @1.

Validation: repository suite (786 tests; six sandbox-blocked tests passed on permitted rerun), 43 Studio tests after audit fixes, TypeScript, public declarations, four example-package builds, chat Source check and npm file inventory.
2026-09-13 01:01:47 +08:00
kashorin 87ac1a5b92 fix(speech): preserve Chinese word timing through alignment and captions 2026-09-10 20:59:13 +08:00
kashorin bb1af2996f feat(distribution): publish under @hypit/hypit and unify studio command 2026-09-10 04:30:13 +08:00
kashorin e90b070c33 feat(composition): support authored clocks alongside semantic timelines 2026-09-09 23:38:46 +08:00
kashorin 6d5a56c043 feat: complete public extension and transparent media paths 2026-09-07 04:34:42 +08:00
kashorin e933cc2e43 docs(video): align examples with the authoring model 2026-09-07 04:25:49 +08:00
kashorin fcc11e8ce0 fix(caption): style non-contiguous role cues 2026-08-29 18:58:22 +08:00
kashorin a4c290b032 refactor: preserve semantic identity through video time 2026-08-26 03:05:55 +08:00
kashorin a12d5fa709 feat: complete fine caption where how when protocol 2026-08-24 14:54:43 +08:00
kashorin 490fe1125a refactor: externalize temporal windows and simplify studio adapters 2026-08-23 04:11:52 +08:00
rpone 03d0257b0b Rename the Playground to Studio wherever a reader is sent
`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.
2026-08-21 00:40:42 +08:00
rpone 7485fbf24b Merge main, taking main's caption outline fix
Four conflicts. Two were mechanical: `align-transcript.ts` and
`svml-playground/src/pipeline/placeholder.ts` are modify/delete, and the
deletion is this branch's intent — local alignment removes the need to
fabricate a program-audio digest, and Studio has no stand-ins to draw.

The other two are the same bug fixed twice. Both sides found that CSS
`-webkit-text-stroke` is centred on the glyph edge, so half the stroke eats
the letterform, and both moved to `VisualTextPaintLayer` with
`placement: "outside"` — which already existed at the merge base on
`VisualTextFlowElement`. That shared starting point is why they converged an
hour apart.

`packages/caption-fine/src/render.ts` and its test take main's version. Main
extends `VisualTextElement` and the HyperFrames renderer rather than moving
Caption Fine onto text-flow, and it carries two fixes this branch does not:
CSS blur is a radius covering about two deviations while the filter takes a
deviation, so passing the authored number through doubles every shadow and
glow in the repository, and its filter-definition dedup takes 80 defs to 16.
Neither file is touched by `a4f2b31f`, so taking main's reverts `d5ee32c7`
exactly and nothing else. `renderFineCaption` works on `ProgramSpace`, which
survives here as a projection of `SemanticTrack`, so the semantic API change
does not reach it.

The Pill-as-paint-layer and structured-typography work in `d5ee32c7` is a
real gain and is not preserved here; it belongs on top of main's
implementation as its own change.

`pnpm check` clean; `pnpm test` 510 pass, 0 fail, 15 skipped.
2026-08-21 00:40:21 +08:00
kashorin f3d319db22 refactor: make SemanticTrack the program skeleton 2026-08-21 00:11:28 +08:00
rpone db3058f24a fix: an Atom measured inside one frame is drawn for that frame
A word shorter than a frame measures to the same frame at both ends once samples
are rounded to the frame grid, and the projection refused the empty span it
produced, taking the whole Caption Track with it.

The map is right to report what it measured: alignment states, and tests, that
deciding what a degenerate window means belongs to whoever renders it. So it is
decided here, where an Atom becomes a Cue that has to be drawn.
2026-08-20 21:29:18 +08:00
kashorin d91482f112 feat: introduce per-segment semantic takes 2026-08-20 16:35:21 +08:00
rpone f11f6bf8d5 feat: publish Hypit element declarations 2026-08-19 17:35:00 +08:00
rpone df23c73d97 refactor: rebrand Narratage as Hypit 2026-08-19 15:51:58 +08:00
kashorin 7683e38c0e refactor: remove defensive execution scaffolding 2026-08-17 14:03:53 +08:00
kashorin 3a7c60f8cb refactor: simplify package loading and runtime execution 2026-08-17 14:03:52 +08:00
kashorin 281d98fbba refactor(speech): make timing frame and sample exact 2026-08-13 22:04:30 +08:00
kashorin 2abc991691 refactor: slim authoring graph values 2026-08-13 20:20:05 +08:00
kashorin a4c5532f68 refactor: keep type identity on graph edges 2026-08-13 20:15:48 +08:00
kashorin b758a947dd refactor: strip redundant value contract tags 2026-08-13 20:07:38 +08:00
kashorin 849ac2a76f refactor: simplify modular compilation and runtime state 2026-08-13 18:53:05 +08:00
rpone 108b9ae0a6 Merge remote-tracking branch 'origin/main'
The three example package locks conflicted: both sides had regenerated
them. Neither side's digests were still correct, since the merged tree
combines their source refactor with the license field added to every
manifest, so the locks were rebuilt from the merged bytes rather than
resolved by picking a side.
2026-08-13 00:34:10 +08:00
rpone c4216c4b4c chore: declare licensing accurately before the public release
Every workspace manifest omitted a license field, so a scanner reading
the published repository would resolve all 90 of them as unknown. Both
Python services went further and declared plain Apache-2.0, which is
looser than the LICENSE they actually ship under.

Package bytes feed the example package locks, so adding the field
invalidated all three; refreshed them. Only closureDigest and artifacts
move — same 31 selected packages, nothing added or removed.

Also record what the READMEs never said: ffmpeg is a real prerequisite
for a Build and had zero mentions, and the media Lambda layer is a GPL
FFmpeg build. That build is deliberate — libx264 is GPL-only and the
encode path requires it — and it stays lawful only because the operator
builds and deploys it into their own account. Publishing a prebuilt
layer would break that, so the boundary is now written down.
2026-08-13 00:21:27 +08:00
kashorin 9e7aa9f4d7 refactor: remove redundant repository scaffolding 2026-08-13 00:17:36 +08:00
kashorin 39ff01aeca refactor: simplify graph realization and local workflow 2026-08-12 15:38:06 +08:00
kashorin 29c031b28c refactor(video): normalize media at track boundaries 2026-08-11 17:18:11 +08:00
kashorin 76cae8eaab refactor: separate markup text and typography
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.
2026-08-10 10:55:46 +08:00
kashorin 81aeb2d169 Normalize logical identities and migration docs 2026-08-10 03:58:39 +08:00
kashorin 21c7b8fd8e feat: freeze the visual ir compatibility waist 2026-08-09 23:01:12 +08:00
kashorin 56e3e8f6db feat: complete unified media track 2026-08-09 17:19:10 +08:00
kashorin ee2c8b5f5a feat: add exact audio and screen overlay tracks 2026-08-09 14:31:24 +08:00
kashorin 4d714877aa feat: establish shared track authoring foundations 2026-08-09 13:36:28 +08:00
kashorin a3114f992b refactor: make caption planning atom-safe 2026-08-09 07:14:59 +08:00
kashorin f3d47a43c2 refactor: separate caption planning from style rendering 2026-08-09 05:22:35 +08:00
kashorin b06b6b9442 test: remove redundant pre-release coverage 2026-08-09 03:26:59 +08:00
kashorin 359d199b13 refactor: remove client branding and freeze pre-release identities 2026-08-09 03:16:57 +08:00
kashorin 52c0ada02a refactor: report located time instead of tidying it
Three places quantised or paired a measurement and then forced the result
forwards when it came out backwards, and one assertion required exactly the
order those corrections manufactured. Together they meant a backwards
measurement either vanished silently or killed the Build, and a consumer could
never see that the evidence disagreed with itself.

Locating now reports what it measured. Selection occurrences are located
independently and returned in Script order: never sorted, merged or clipped
against one another, because reconciling them is a decision about the caller's
own material. Two tests hold that line, one at each level.

The map also stops being a structure consumers read. Caption asked it for token
windows by reaching into the array; it now calls tokenSpanSeconds, a boundary
test keeps every other package out of the fields, and the segments array, which
no longer had a reader, is gone.

The envelope in groupWindow and the interpolation bound in fillEstimated stay:
one aggregates a run of evidence, the other shapes a value for tokens that were
never measured. Neither edits a measurement.
2026-08-08 06:08:43 +08:00