@hugpy/video-intelligence-ui 0.3.5 → 0.3.6

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/dist/index.html CHANGED
@@ -49,7 +49,7 @@
49
49
  overflow-x: hidden;
50
50
  }
51
51
  </style>
52
- <script type="module" crossorigin src="/video/assets/index-C_av7KDW.js"></script>
52
+ <script type="module" crossorigin src="/video/assets/index--is_kWXv.js"></script>
53
53
  <link rel="stylesheet" crossorigin href="/video/assets/index-DMoT8G1q.css">
54
54
  </head>
55
55
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hugpy/video-intelligence-ui",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "type": "module",
6
6
  "description": "Hugpy video-intelligence console: image crop, audio crop, frames/models and generate stations over the hugpy-video job bus; a standalone Vite + Tailwind v4 arm served at /video",
@@ -728,6 +728,18 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
728
728
  // the warning is worth the one extra click. Session-persisted like every other authored
729
729
  // field here.
730
730
  const [movieTitle, setMovieTitle] = useSessionState("studio.movie.title", "");
731
+ const autoTitleRef = useSessionRef<string>("studio.movie.autoTitle", "");
732
+ const applyGeneratedTitle = useCallback((prompt: string, title?: string) => {
733
+ const derived = title?.trim() || prompt.split(/[.,;\n]/)[0].trim()
734
+ .split(/\s+/).slice(0, 7).join(" ").slice(0, 48);
735
+ if (!derived) return;
736
+ const previousAutoTitle = autoTitleRef.current;
737
+ setMovieTitle((current) => {
738
+ if (current.trim() && current.trim() !== previousAutoTitle) return current;
739
+ autoTitleRef.current = derived;
740
+ return derived;
741
+ });
742
+ }, [setMovieTitle, autoTitleRef]);
731
743
  // Movie-level MODEL PIN + sampler overrides (operator ask 2026-07-13: the Settings tab
732
744
  // wants "the model selection" + a wider range of options). All BLANK-first ⇒ router
733
745
  // default: modelId "" = the capability router picks by budget/resolution (an unroutable
@@ -1361,9 +1373,10 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
1361
1373
  if (first.height != null && !manualSettings.current.includes("height")) setHeight(first.height);
1362
1374
  if (first.fps != null && !manualSettings.current.includes("fps")) setFps(first.fps);
1363
1375
  }
1376
+ applyGeneratedTitle(plan.segments[0]?.prompt || p, plan.title);
1364
1377
  setProducerNote([plan.title, plan.logline].filter(Boolean).join(" — "));
1365
1378
  }, [premise, movieQuery, producing, goals, fps, assist.assistModel, startImage,
1366
- setWidth, setHeight, setFps]);
1379
+ setWidth, setHeight, setFps, applyGeneratedTitle]);
1367
1380
 
1368
1381
  const setSegmentCount = useCallback(
1369
1382
  (n: number) => {
@@ -1477,7 +1490,6 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
1477
1490
  // The last AUTO-derived movie title. A name the operator typed is sacred; a
1478
1491
  // name this ref minted may be replaced by the next Generate (operator
1479
1492
  // 2026-08-13: "purely a product of the same generation method").
1480
- const autoTitleRef = useRef("");
1481
1493
  const planGoalPrompt = useCallback(async (
1482
1494
  i: number, text: string,
1483
1495
  coordinated?: { seed?: number; frames?: number; joint_mode?: string },
@@ -1540,29 +1552,14 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
1540
1552
  setGoalField(i, { negative: cur ? `${cur}, ${neg}` : neg });
1541
1553
  },
1542
1554
  );
1543
- // NAME RIDES ALONG: derive a title from the generated prompt when the
1544
- // movie has none — or when the current one was itself auto-derived.
1545
- const t = movieTitle.trim();
1546
- if (t === "" || t === autoTitleRef.current) {
1547
- const derived = fresh
1548
- .split(/[.,;\n]/)[0]
1549
- .trim()
1550
- .split(/\s+/)
1551
- .slice(0, 7)
1552
- .join(" ")
1553
- .slice(0, 48);
1554
- if (derived) {
1555
- autoTitleRef.current = derived;
1556
- setMovieTitle(derived);
1557
- }
1558
- }
1555
+ applyGeneratedTitle(fresh);
1559
1556
  })();
1560
1557
  // The text is about to change, so the old classification no longer describes it.
1561
1558
  intentText.current[g.key] = "";
1562
1559
  setIntents((prev) => ({ ...prev, [g.key]: null }));
1563
1560
  },
1564
1561
  [assist, goals, rowContext, setGoalField, movieTitle, setMovieTitle,
1565
- settingsMode, planGoalPrompt],
1562
+ settingsMode, planGoalPrompt, applyGeneratedTitle],
1566
1563
  );
1567
1564
 
1568
1565
  // ── negative generation (§1b) — an exclusion list for THIS shot ──
@@ -1598,7 +1595,7 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
1598
1595
  });
1599
1596
  if (!body) return;
1600
1597
  setSpreadNotice(null);
1601
- const res = await assist.runSpread(body);
1598
+ const res = await assist.runSpread({ ...body, fps });
1602
1599
  if (!res) return;
1603
1600
 
1604
1601
  const bySeg = new Map(res.segments.map((s) => [s.segment_id, s]));
@@ -1635,6 +1632,8 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
1635
1632
  };
1636
1633
  }),
1637
1634
  );
1635
+ const firstGenerated = applied.length ? bySeg.get(applied[0]) : undefined;
1636
+ if (firstGenerated) applyGeneratedTitle(firstGenerated.prompt);
1638
1637
  let oracleNotice: string | null = null;
1639
1638
  if (settingsMode === "oracle") {
1640
1639
  for (const key of applied) {
@@ -1685,6 +1684,8 @@ export function StudioMovieComposer({ settingsHost }: StudioMovieComposerProps =
1685
1684
  steeringSeed,
1686
1685
  settingsMode,
1687
1686
  planGoalPrompt,
1687
+ applyGeneratedTitle,
1688
+ fps,
1688
1689
  ]);
1689
1690
 
1690
1691
  // ── GROUP ACTION: negatives for the selected rows ──
@@ -71,6 +71,7 @@ export interface AssistContextWire {
71
71
  /** The `mode:"spread"` request body (§1a), minus `model` (the hook adds that). */
72
72
  export interface SpreadRequestWire {
73
73
  mode: "spread";
74
+ fps?: number;
74
75
  movie_query?: string;
75
76
  style_bible?: Record<string, string>;
76
77
  fixed_segments: SegmentRefWire[];