@nodaro/shared 2.14.0 → 2.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodaro/shared",
3
- "version": "2.14.0",
3
+ "version": "2.15.0",
4
4
  "description": "Shared types, model catalog, wire contracts, and structural vocabularies for the Nodaro platform and SDK.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -287,6 +287,17 @@ describe("cinematography fields (angle / speed / onScreenText / look)", () => {
287
287
  expect(windowAnalysisSchema.safeParse({ slots: [slot], scenes: [{ ...baseScene }] }).success).toBe(true)
288
288
  })
289
289
 
290
+ it("round 4: a scene carries a free-text `transition` beside the legacy enum", () => {
291
+ // F.8: the analyser describes the edit in its own words; the enum is legacy.
292
+ const ok = windowAnalysisSchema.safeParse({ slots: [slot], scenes: [{ ...baseScene, transition: "fast blurred pan left" }] })
293
+ expect(ok.success).toBe(true)
294
+ expect(ok.success && ok.data.scenes[0]!.transition).toBe("fast blurred pan left")
295
+ expect(windowAnalysisSchema.safeParse({ slots: [slot], scenes: [{ ...baseScene, transition: "" }] }).success).toBe(false)
296
+ expect(windowAnalysisSchema.safeParse({ slots: [slot], scenes: [{ ...baseScene, transition: "x".repeat(121) }] }).success).toBe(false)
297
+ // legacy blueprints still parse
298
+ expect(windowAnalysisSchema.safeParse({ slots: [slot], scenes: [{ ...baseScene, transitionOut: "whip" }] }).success).toBe(true)
299
+ })
300
+
290
301
  it("marks the viewpoints where no face is visible — auto-cast reads this", () => {
291
302
  // A reference frame shot from behind cannot cast a face, however well framed.
292
303
  expect([...VIDEO_ANALYSIS_FACELESS_ANGLES].sort()).toEqual(["from-behind", "over-the-shoulder"])
@@ -334,6 +334,15 @@ const windowSceneBase = z.object({
334
334
  /** Effects on this shot's PICTURE. Absent ⇒ a clean image. */
335
335
  effects: z.array(z.enum(VIDEO_ANALYSIS_VISUAL_EFFECTS)).optional(),
336
336
  transitionOut: z.enum(VIDEO_ANALYSIS_TRANSITIONS).optional(),
337
+ // Round 4 (2026-08-30, recast shot craft rev 1.5 Appendix F.8): the edit into
338
+ // the next scene in the analyser's OWN WORDS — a few words of what it saw
339
+ // ("fast blurred pan left", "fade to black", "zoom-blur warp into the tunnel")
340
+ // — or absent when the take continues through the change or no edit is seen
341
+ // (nothing asserted: the video model decides from story and refs). The closed
342
+ // `transitionOut` vocabulary above is LEGACY from here on: kept so stored
343
+ // blueprints still parse, never emitted again. Readers take
344
+ // `transition ?? transitionOut`.
345
+ transition: z.string().trim().min(1).max(120).optional(),
337
346
  // Array of concurrent layers (music + speech + sfx together); [] = silence.
338
347
  audio: z.array(audioLayerSchema),
339
348
  /** slotId → variationId for slots wearing a NON-default look in this scene