@rslsp1/fa-app-tools 2.0.81 → 2.0.83

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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SzenenView,
3
3
  createFlowSzenenViewPort
4
- } from "./chunk-GEGJD43Y.mjs";
4
+ } from "./chunk-JTGC5PXJ.mjs";
5
5
  import "./chunk-FUY2OCVC.mjs";
6
6
  import {
7
7
  exportProjectToZip,
@@ -30,7 +30,7 @@ import {
30
30
  } from "./chunk-VBWQP7PO.mjs";
31
31
 
32
32
  // package.json
33
- var version = "2.0.81";
33
+ var version = "2.0.83";
34
34
 
35
35
  // src/hooks/useOnClickOutside.ts
36
36
  import { useEffect } from "react";
@@ -2922,6 +2922,21 @@ function validateTagBaseSelection(base, userId, contextId) {
2922
2922
  // src/hooks/useTagBase.ts
2923
2923
  var USER_ID_KEY = "aa-user-id";
2924
2924
  var CONTEXT_ID_KEY = "aa-context-id";
2925
+ var IDENTITY_NAMESPACE_KEY = "aa-identity-namespace";
2926
+ function readStoredNamespace() {
2927
+ try {
2928
+ return localStorage.getItem(IDENTITY_NAMESPACE_KEY);
2929
+ } catch {
2930
+ return null;
2931
+ }
2932
+ }
2933
+ function writeStoredNamespace(namespace) {
2934
+ try {
2935
+ if (namespace === null) localStorage.removeItem(IDENTITY_NAMESPACE_KEY);
2936
+ else localStorage.setItem(IDENTITY_NAMESPACE_KEY, namespace);
2937
+ } catch {
2938
+ }
2939
+ }
2925
2940
  function readStoredId(key) {
2926
2941
  try {
2927
2942
  const v = localStorage.getItem(key);
@@ -2958,6 +2973,16 @@ function useTagBase(token, namespace) {
2958
2973
  }, [selectedContextId]);
2959
2974
  const load = useCallback2(async () => {
2960
2975
  if (!token || !namespace) return;
2976
+ if (readStoredNamespace() !== namespace) {
2977
+ selectedUserIdRef.current = null;
2978
+ selectedContextIdRef.current = null;
2979
+ setSelectedUserId(null);
2980
+ setSelectedContextId(null);
2981
+ writeStoredId(USER_ID_KEY, null);
2982
+ writeStoredId(CONTEXT_ID_KEY, null);
2983
+ writeStoredNamespace(namespace);
2984
+ setPickerMessage(null);
2985
+ }
2961
2986
  setIsLoading(true);
2962
2987
  setError(null);
2963
2988
  try {
@@ -2996,16 +3021,19 @@ function useTagBase(token, namespace) {
2996
3021
  setSelectedContextId(null);
2997
3022
  writeStoredId(USER_ID_KEY, userId);
2998
3023
  writeStoredId(CONTEXT_ID_KEY, null);
2999
- }, []);
3024
+ writeStoredNamespace(namespace);
3025
+ }, [namespace]);
3000
3026
  const selectContext = useCallback2((contextId) => {
3001
3027
  setSelectedContextId(contextId);
3002
3028
  writeStoredId(CONTEXT_ID_KEY, contextId);
3003
- }, []);
3029
+ writeStoredNamespace(namespace);
3030
+ }, [namespace]);
3004
3031
  const resetSelection = useCallback2(() => {
3005
3032
  setSelectedUserId(null);
3006
3033
  setSelectedContextId(null);
3007
3034
  writeStoredId(USER_ID_KEY, null);
3008
3035
  writeStoredId(CONTEXT_ID_KEY, null);
3036
+ writeStoredNamespace(null);
3009
3037
  setPickerMessage(null);
3010
3038
  }, []);
3011
3039
  const validation = tagBase ? validateTagBaseSelection(tagBase, selectedUserId, selectedContextId) : { valid: false, reason: null };
@@ -5712,6 +5740,57 @@ function FlowWorkspacePicker({
5712
5740
  ] }) });
5713
5741
  }
5714
5742
 
5743
+ // src/lib/flowBootstrapTarget.ts
5744
+ var PROD_NAMESPACE = "app.art-by-rolands.de/";
5745
+ var DEV_NAMESPACE = "dev-app.art-by-rolands.de/";
5746
+ var SELECTABLE_NAMESPACES = [PROD_NAMESPACE, DEV_NAMESPACE];
5747
+ var DEFAULT_NAMESPACE = PROD_NAMESPACE;
5748
+ function environmentForNamespace(namespace) {
5749
+ if (!namespace) return null;
5750
+ if (namespace === DEV_NAMESPACE) return "dev";
5751
+ if (namespace === PROD_NAMESPACE) return "prod";
5752
+ return null;
5753
+ }
5754
+ function normalizeSelectableNamespace(namespace) {
5755
+ return namespace && SELECTABLE_NAMESPACES.includes(namespace) ? namespace : DEFAULT_NAMESPACE;
5756
+ }
5757
+ function resolveBootstrapTarget(input) {
5758
+ const { hostNamespace, serverNamespace, isProbingServer = false } = input;
5759
+ if (hostNamespace) {
5760
+ return {
5761
+ source: "host",
5762
+ phase: "ready",
5763
+ ready: true,
5764
+ namespace: hostNamespace,
5765
+ environment: environmentForNamespace(hostNamespace)
5766
+ };
5767
+ }
5768
+ if (serverNamespace) {
5769
+ return {
5770
+ source: "server",
5771
+ phase: "ready",
5772
+ ready: true,
5773
+ namespace: serverNamespace,
5774
+ environment: environmentForNamespace(serverNamespace)
5775
+ };
5776
+ }
5777
+ if (isProbingServer) {
5778
+ return { source: "server", phase: "probing", ready: false, namespace: null, environment: null };
5779
+ }
5780
+ const { selectedNamespace, isStartDialogOpen = false } = input;
5781
+ if (isStartDialogOpen) {
5782
+ return { source: "dialog", phase: "awaiting-choice", ready: false, namespace: null, environment: null };
5783
+ }
5784
+ const namespace = normalizeSelectableNamespace(selectedNamespace);
5785
+ return {
5786
+ source: "dialog",
5787
+ phase: "ready",
5788
+ ready: true,
5789
+ namespace,
5790
+ environment: environmentForNamespace(namespace)
5791
+ };
5792
+ }
5793
+
5715
5794
  // src/components/AvatarArchitectApp.tsx
5716
5795
  import { Fragment as Fragment11, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
5717
5796
  function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, requireWorkspaceSelection = false, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
@@ -5738,31 +5817,38 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5738
5817
  const [hfTokenInput, setHfTokenInput] = useState25(initialHfToken || "");
5739
5818
  const [isLoadingFromHF, setIsLoadingFromHF] = useState25(false);
5740
5819
  const [hfNamespaceLocal, setHfNamespaceLocal] = useState25(() => {
5741
- const KNOWN = ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"];
5742
- const DEFAULT = "app.art-by-rolands.de/";
5743
5820
  try {
5744
- const stored = localStorage.getItem("aa-hf-namespace");
5745
- if (stored && KNOWN.includes(stored)) return stored;
5746
- localStorage.setItem("aa-hf-namespace", DEFAULT);
5747
- return DEFAULT;
5821
+ return normalizeSelectableNamespace(localStorage.getItem("aa-hf-namespace"));
5748
5822
  } catch {
5749
- return DEFAULT;
5823
+ return DEFAULT_NAMESPACE;
5750
5824
  }
5751
5825
  });
5752
5826
  const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState25(null);
5827
+ const [serverProbeFailed, setServerProbeFailed] = useState25(false);
5753
5828
  useEffect10(() => {
5754
5829
  if (hfNamespace !== void 0 || !serverBaseUrl) return;
5755
5830
  fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
5756
5831
  if (typeof d.hfNamespace === "string" && d.hfNamespace) setHfNamespaceFromServer(d.hfNamespace);
5757
- }).catch(() => {
5758
- });
5832
+ else setServerProbeFailed(true);
5833
+ }).catch(() => setServerProbeFailed(true));
5759
5834
  }, [hfNamespace, serverBaseUrl]);
5760
- const effectiveNamespace = hfNamespace ?? hfNamespaceFromServer ?? hfNamespaceLocal;
5761
- const szenenPort = useMemo6(() => hfToken ? createFlowSzenenViewPort({
5835
+ const [targetConfirmed, setTargetConfirmed] = useState25(false);
5836
+ const isDialogTarget = hfNamespace === void 0 && hfNamespaceFromServer === null && (!serverBaseUrl || serverProbeFailed);
5837
+ const isProbingServer = hfNamespace === void 0 && !!serverBaseUrl && hfNamespaceFromServer === null && !serverProbeFailed;
5838
+ const bootstrapTarget = resolveBootstrapTarget({
5839
+ hostNamespace: hfNamespace,
5840
+ serverNamespace: hfNamespaceFromServer,
5841
+ isProbingServer,
5842
+ selectedNamespace: hfNamespaceLocal,
5843
+ isStartDialogOpen: isDialogTarget && !targetConfirmed
5844
+ });
5845
+ const effectiveNamespace = bootstrapTarget.namespace ?? "";
5846
+ const szenenPort = useMemo6(() => hfToken && effectiveNamespace ? createFlowSzenenViewPort({
5762
5847
  generateText: onGeneratePrompt,
5763
5848
  token: hfToken,
5764
- namespace: effectiveNamespace
5765
- }) : null, [hfToken, effectiveNamespace, onGeneratePrompt]);
5849
+ namespace: effectiveNamespace,
5850
+ generateImage: onGenerateImage
5851
+ }) : null, [hfToken, effectiveNamespace, onGeneratePrompt, onGenerateImage]);
5766
5852
  const {
5767
5853
  state: hfState,
5768
5854
  isLoading: isHfRefreshing,
@@ -5836,6 +5922,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
5836
5922
  } catch {
5837
5923
  }
5838
5924
  setLayoutChoice(choice);
5925
+ setTargetConfirmed(true);
5839
5926
  setShowStart(false);
5840
5927
  };
5841
5928
  const [nodes, setNodes] = useState25([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
@@ -6597,45 +6684,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6597
6684
  const all = Object.entries(merged).flatMap(([cat, tags]) => tags.map((t) => ({ ...t, category: cat })));
6598
6685
  return { by_category: merged, all };
6599
6686
  };
6600
- if (requireWorkspaceSelection) {
6601
- if (!hfToken) {
6602
- return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx29("section", { className: "flow-workspace-picker__card", role: "alert", children: "HF-Token fehlt \u2014 User und Context koennen nicht aus der Tag-Base geladen werden." }) });
6603
- }
6604
- if (tagBaseResult.isLoading) {
6605
- return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs27("section", { className: "flow-workspace-picker__card", children: [
6606
- "Lade User und Contexts aus ",
6607
- effectiveNamespace,
6608
- "\u2026"
6609
- ] }) });
6610
- }
6611
- if (tagBaseResult.error) {
6612
- return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs27("section", { className: "flow-workspace-picker__card", role: "alert", children: [
6613
- "Tag-Base ",
6614
- effectiveNamespace,
6615
- " konnte nicht geladen werden: ",
6616
- tagBaseResult.error
6617
- ] }) });
6618
- }
6619
- if (!tagBaseResult.tagBase) {
6620
- return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs27("section", { className: "flow-workspace-picker__card", role: "alert", children: [
6621
- "Im Namespace ",
6622
- effectiveNamespace,
6623
- " fehlt tags-state-*.zip. Der Server muss zuerst die Tag-Base erzeugen."
6624
- ] }) });
6625
- }
6626
- if (tagBaseResult.needsPicker) {
6627
- return /* @__PURE__ */ jsx29(
6628
- FlowWorkspacePicker,
6629
- {
6630
- tagBase: tagBaseResult.tagBase,
6631
- selectedUserId: tagBaseResult.selectedUserId,
6632
- message: tagBaseResult.pickerMessage,
6633
- onSelectUser: tagBaseResult.selectUser,
6634
- onSelectContext: tagBaseResult.selectContext
6635
- }
6636
- );
6637
- }
6638
- }
6639
6687
  if (isFullscreen && currentResult?.base64) {
6640
6688
  const fsRaw = currentResult.fullBase64 || currentResult.base64;
6641
6689
  const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
@@ -6779,7 +6827,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6779
6827
  }
6780
6828
  )
6781
6829
  ] }),
6782
- !hfNamespace && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-3 w-full", children: [
6830
+ isDialogTarget && /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-3 w-full", children: [
6783
6831
  /* @__PURE__ */ jsx29("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold flex-shrink-0", children: "State:" }),
6784
6832
  ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ jsx29(
6785
6833
  "button",
@@ -6864,7 +6912,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6864
6912
  "button",
6865
6913
  {
6866
6914
  type: "button",
6867
- disabled: !szenenPort,
6915
+ disabled: !szenenPort || !bootstrapTarget.ready,
6868
6916
  onClick: () => setShowSzenen(true),
6869
6917
  children: [
6870
6918
  /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined", children: "movie" }),
@@ -6899,6 +6947,48 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
6899
6947
  ] })
6900
6948
  ] });
6901
6949
  }
6950
+ if (requireWorkspaceSelection) {
6951
+ if (!bootstrapTarget.ready) {
6952
+ return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx29("section", { className: "flow-workspace-picker__card", children: "Zielraum wird bestimmt\u2026" }) });
6953
+ }
6954
+ if (!hfToken) {
6955
+ return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsx29("section", { className: "flow-workspace-picker__card", role: "alert", children: "HF-Token fehlt \u2014 User und Context koennen nicht aus der Tag-Base geladen werden." }) });
6956
+ }
6957
+ if (tagBaseResult.isLoading) {
6958
+ return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs27("section", { className: "flow-workspace-picker__card", children: [
6959
+ "Lade User und Contexts aus ",
6960
+ effectiveNamespace,
6961
+ "\u2026"
6962
+ ] }) });
6963
+ }
6964
+ if (tagBaseResult.error) {
6965
+ return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs27("section", { className: "flow-workspace-picker__card", role: "alert", children: [
6966
+ "Tag-Base ",
6967
+ effectiveNamespace,
6968
+ " konnte nicht geladen werden: ",
6969
+ tagBaseResult.error
6970
+ ] }) });
6971
+ }
6972
+ if (!tagBaseResult.tagBase) {
6973
+ return /* @__PURE__ */ jsx29("main", { className: "flow-workspace-picker", children: /* @__PURE__ */ jsxs27("section", { className: "flow-workspace-picker__card", role: "alert", children: [
6974
+ "Im Namespace ",
6975
+ effectiveNamespace,
6976
+ " fehlt tags-state-*.zip. Der Server muss zuerst die Tag-Base erzeugen."
6977
+ ] }) });
6978
+ }
6979
+ if (tagBaseResult.needsPicker) {
6980
+ return /* @__PURE__ */ jsx29(
6981
+ FlowWorkspacePicker,
6982
+ {
6983
+ tagBase: tagBaseResult.tagBase,
6984
+ selectedUserId: tagBaseResult.selectedUserId,
6985
+ message: tagBaseResult.pickerMessage,
6986
+ onSelectUser: tagBaseResult.selectUser,
6987
+ onSelectContext: tagBaseResult.selectContext
6988
+ }
6989
+ );
6990
+ }
6991
+ }
6902
6992
  if (layoutChoice === "mobile" || layoutChoice === "mobile-desktop") {
6903
6993
  const mdMode = layoutChoice === "mobile-desktop";
6904
6994
  const mdScale = mdMode ? window.innerWidth / 430 : 1;
package/dist/szenen.d.mts CHANGED
@@ -631,7 +631,53 @@ declare const SZENEN_EVENT_TYPES: {
631
631
  * falls eine entstand.
632
632
  */
633
633
  readonly imageGenerationFinished: "szenen.image_generation_finished";
634
+ /**
635
+ * Ein Bild-Batch ist kanonisch gespeichert — Stufe 6.9.2, Gate D
636
+ * (D-6.9.2-6).
637
+ *
638
+ * Erscheint erst, **nachdem** jedes Bild des Batches im Bildbestand liegt
639
+ * (`hfUploadImage` + `image_added`, dieselbe Reihenfolge wie
640
+ * `hfImageLibrary.putImage`) — kein Bild gilt als vorhanden, bevor sein
641
+ * Upload bestätigt ist (R3). Trägt bewusst **keine Bilddaten**, nur den
642
+ * vollständigen Metadatennachweis, den `listBatchesForPromptRun()` /
643
+ * `getBatch()` ohne MySQL rekonstruieren können müssen: `item_id`,
644
+ * `prompt_run_id`, `generation_batch_id`, `source_kind`, je Bild
645
+ * `position`, `media_ref`, `asset_id`, `model`, `seed`, `width`/`height`.
646
+ *
647
+ * Additiv wie jedes Ereignis dieser Domain: ein zweiter Batch desselben
648
+ * Laufs ist ein **weiteres** Ereignis mit derselben `item_id`, nicht eine
649
+ * Änderung am ersten (D-113/D-121 — ein Lauf bleibt ein Item). Gilt für
650
+ * `generated_in_app` **und** `external_import` — nur `source_kind`
651
+ * unterscheidet die beiden Schreiber (D-116/D-117/D-120).
652
+ *
653
+ * Der Elementreducer ignoriert auch diesen Typ (`default:`-Zweig); gelesen
654
+ * wird mit `collectImageBatches` (`imageBatchStore.ts`).
655
+ */
656
+ readonly imageBatchPersisted: "szenen.image_batch_persisted";
634
657
  };
658
+ /** Ein einzelnes Bild innerhalb von `ImageBatchPersistedPayload` (D-6.9.2-6). */
659
+ interface ImageBatchPersistedImage {
660
+ position: number;
661
+ /** Im aktuellen Host auflösbarer Locator — hier die HF-Bildkennung (D-93). */
662
+ media_ref: string;
663
+ /** Fachlich stabile Identität, soweit bekannt — hier identisch mit `media_ref` (D-118). */
664
+ asset_id?: string;
665
+ model?: string | null;
666
+ /** Nur gesetzt, wenn der Provider ihn tatsächlich zurückliefert (D-107). */
667
+ seed?: number | null;
668
+ width?: number | null;
669
+ height?: number | null;
670
+ }
671
+ /** Nutzlast von `imageBatchPersisted` — geschrieben nach bestätigtem Bild-Upload. */
672
+ interface ImageBatchPersistedPayload {
673
+ item_id: string;
674
+ prompt_run_id: string;
675
+ generation_batch_id: string;
676
+ source_kind: 'generated_in_app' | 'external_import';
677
+ title: string;
678
+ images: readonly ImageBatchPersistedImage[];
679
+ created_at: string;
680
+ }
635
681
  /**
636
682
  * Ein Event, wie der Reducer es sieht.
637
683
  *
@@ -2263,17 +2309,41 @@ interface SzenenViewPort {
2263
2309
  context: ContextChainPort;
2264
2310
  /** Prompt-Läufe — Stufe 3/4. */
2265
2311
  runs: SzenenRunPort;
2266
- /** Runde als Item — fehlt in Flow-Pure. */
2312
+ /**
2313
+ * Runde als Item — fehlt, solange ein Host keinen Item-Persistenzweg hat.
2314
+ *
2315
+ * Für Flow ist das **keine** MySQL-Grenze mehr (Stufe 6.9.2 hat die alte
2316
+ * Kurzschlussbegründung "kein MySQL → kann nicht" für Batch-Historie und
2317
+ * -Schreiben widerlegt, D-6.9.2-1): Items fehlen hier ausschließlich, weil
2318
+ * Gate H (D-6.9.2-9) einen eigenen Item-Persistenzvertrag über HF erst
2319
+ * nach einer Inventur des bestehenden Library-Modells bekommen soll — ein
2320
+ * offener Architekturpunkt, keine Plattformgrenze.
2321
+ */
2267
2322
  items?: SzenenItemPort;
2268
- /** Medien — fehlt, solange ein Host Stufe 5 nicht anbietet. */
2323
+ /** Medien — fehlt, solange kein hostneutraler Version/Item↔Asset-Zuordnungsvertrag existiert (Gate I, D-6.9.2-10). */
2269
2324
  media?: SzenenMediaPort;
2270
2325
  /** Bildbestand — fehlt, wenn ein Host keinen hat (D-94). */
2271
2326
  imageLibrary?: SzenenImageLibraryPort;
2272
2327
  /** Rekonstruktion — fehlt ohne Textgenerierungs-Port (Stufe 6.5). */
2273
2328
  derivation?: SzenenDerivationPort;
2274
- /** Bild-Batch-Historie — fehlt, solange ein Host keinen MySQL-Zugriff hat (D-122). */
2329
+ /**
2330
+ * Bild-Batch-Historie — fehlt, wenn ein Host den autoritativen
2331
+ * Ereigniskanal selbst nicht lesen kann.
2332
+ *
2333
+ * **Kein** MySQL-Erfordernis (Korrektur Stufe 6.9.2, D-6.9.2-7): Sie
2334
+ * rekonstruiert Batches und Bildaufträge ausschließlich aus dem
2335
+ * Ereignislog. Flow liefert sie deshalb unabhängig von Bildprovider und
2336
+ * Batch-Schreibweg — React liefert sie zusätzlich über MySQL als Index.
2337
+ */
2275
2338
  imageBatchHistory?: SzenenImageBatchHistoryPort;
2276
- /** Bild-Batch-Schreiben — fehlt ohne sicheren Batch-Schreibpfad (D-122). */
2339
+ /**
2340
+ * Bild-Batch-Schreiben — fehlt ohne sicheren, hostübergreifenden
2341
+ * Batch-Schreibpfad.
2342
+ *
2343
+ * Für Flow ist der Schreibpfad HF (`hfUploadImage` + `image_batch_persisted`,
2344
+ * D-6.9.2-4/6), nicht MySQL — auch hier gilt seit Stufe 6.9.2 nicht mehr
2345
+ * "kein MySQL → kann nicht" (D-6.9.2-1).
2346
+ */
2277
2347
  imageBatchWrite?: SzenenImageBatchWritePort;
2278
2348
  /**
2279
2349
  * Bildgenerierung aus einem Prompt-Lauf — fehlt, wenn Providerzugang
@@ -2373,8 +2443,10 @@ interface CreateMemoryViewPortOptions {
2373
2443
  /**
2374
2444
  * Ob der Port Bild-Batch-Historie anbietet (Stufe 6.7, D-122).
2375
2445
  *
2376
- * `false` bildet einen Host ohne MySQL-Zugriff ab (Flow-Pure): der
2377
- * Bereich zeigt dann keine Batch-Historie, statt leer zu erscheinen (R11).
2446
+ * `false` bildet einen Host ohne lesbaren autoritativen Kanal ab — **nicht**
2447
+ * mehr pauschal "kein MySQL" (Korrektur Stufe 6.9.2, D-6.9.2-7/D-6.9.2-1):
2448
+ * Flow liest diese Historie seit 6.9.2 direkt aus HF. Der Bereich zeigt bei
2449
+ * `false` keine Batch-Historie, statt leer zu erscheinen (R11).
2378
2450
  */
2379
2451
  imageBatchHistory?: boolean;
2380
2452
  /** Vorbelegte Batches, aus denen `listBatchesForPromptRun`/`getBatch` lesen. */
@@ -2400,6 +2472,44 @@ interface CreateMemoryViewPortOptions {
2400
2472
  }
2401
2473
  declare function createMemoryViewPort(options?: CreateMemoryViewPortOptions): SzenenViewPort;
2402
2474
 
2475
+ interface FlowGenerateImageParams {
2476
+ prompt: string;
2477
+ modelDisplayName: string;
2478
+ aspectRatio?: string;
2479
+ referenceImageMediaIds?: readonly string[];
2480
+ }
2481
+ /** Die nackte Flow-SDK-Funktion, wie `AppFa.tsx` sie hereinreicht. */
2482
+ type FlowGenerateImage = (params: FlowGenerateImageParams) => Promise<{
2483
+ base64: string;
2484
+ mediaId?: string;
2485
+ }>;
2486
+ /**
2487
+ * Katalogisierte Bildmodelle (`imageGenerationCapability.ts`) auf
2488
+ * Flow-Display-Namen (`howto-flow-sdk.md` — bekannt sind "🍌 Nano Banana Pro",
2489
+ * "🍌 Nano Banana 2", "Imagen 4").
2490
+ *
2491
+ * Nur `imagen-4.0-generate-001` hat einen dokumentierten Flow-Display-Namen.
2492
+ * `imagen-3.0-generate-001` bleibt bewusst draußen: Ein stiller Griff zu
2493
+ * "Imagen 4" wäre genau der Modell-Fallback, den D-115 verbietet.
2494
+ */
2495
+ declare const FLOW_MODEL_DISPLAY_NAMES: Readonly<Record<string, string>>;
2496
+ /**
2497
+ * Ob dieser Host tatsächlich Zugang zu einem katalogisierten Bildmodell hat
2498
+ * (D-115) — die Vorgabe für `hasAccess` in `createFlowSzenenViewPort()`.
2499
+ */
2500
+ declare function flowImageProviderHasAccess(model: {
2501
+ callable_model_id: string;
2502
+ }): boolean;
2503
+ /**
2504
+ * Ein Provideraufruf je Bild — dieselbe Begründung wie beim React-Adapter
2505
+ * (`reactImageProvider.ts`): Das SDK kennt keinen Mehrbild-Parameter
2506
+ * (`howto-flow-sdk.md`, CONVERGE-Fundstelle „4 Varianten gleichzeitig").
2507
+ * Teilfehler verwerfen nichts: Bricht der k-te Aufruf ab, werden die ersten
2508
+ * k-1 Bilder zurückgegeben; nur wenn **kein** Bild zustande kam, wirft der
2509
+ * Adapter.
2510
+ */
2511
+ declare function createFlowImageProvider(generateImage: FlowGenerateImage): ImageGenerationProviderPort;
2512
+
2403
2513
  interface CreateFlowSzenenViewPortOptions {
2404
2514
  /**
2405
2515
  * Der Textzugang des Flow-SDK. Entfaellt, wenn `textPort` gesetzt ist — ein
@@ -2428,10 +2538,29 @@ interface CreateFlowSzenenViewPortOptions {
2428
2538
  imageLibrary?: SzenenImageLibraryPort;
2429
2539
  newRunId?: () => string;
2430
2540
  now?: () => Date;
2541
+ /**
2542
+ * Der Bildzugang des Flow-SDK — Stufe 6.9.2, Gate B (D-6.9.2-3). Entfällt,
2543
+ * wenn `imageProvider` gesetzt ist oder gar kein Bildzugang vorliegt: dann
2544
+ * bleibt `imageGeneration` am Port weg, exakt wie bei `generateText`.
2545
+ */
2546
+ generateImage?: FlowGenerateImage;
2547
+ /** Ein fertiger Bildprovider statt des Flow-SDK — für Tests. */
2548
+ imageProvider?: ImageGenerationProviderPort;
2549
+ /**
2550
+ * Ob dieser Host Zugang zu einem katalogisierten Bildmodell hat (D-115).
2551
+ * Vorgabe: die bekannten Flow-Display-Namen (`flowImageProviderHasAccess`).
2552
+ */
2553
+ imageProviderHasAccess?: ImageProviderAccessCheck;
2554
+ /** Kennung je abgelegtem Batch-Bild. Ersetzbar, damit ein Test nicht würfelt. */
2555
+ newBatchImageId?: (generationBatchId: string, position: number) => string;
2431
2556
  }
2432
2557
  /**
2433
2558
  * Complete Flow adapter for the shared SzenenView: authoritative HF elements
2434
- * and runs plus Flow.generate.text. Server-only item commands stay absent.
2559
+ * and runs, Flow.generate.text, and — Stufe 6.9.2 — HF-backed image-batch
2560
+ * history/write plus Flow.generate.image-based image generation (Gates
2561
+ * B–G, D-6.9.2-3…7). Item persistence stays absent: Gate H (D-6.9.2-9)
2562
+ * needs an inventory pass on the existing HF library model first, so this
2563
+ * is a real, documented gap — not a leftover "Flow has no MySQL" assumption.
2435
2564
  */
2436
2565
  declare function createFlowSzenenViewPort(options: CreateFlowSzenenViewPortOptions): SzenenViewPort;
2437
2566
 
@@ -2690,6 +2819,52 @@ interface CreateClientDerivationPortOptions {
2690
2819
  }
2691
2820
  declare function createClientDerivationPort(options: CreateClientDerivationPortOptions): SzenenDerivationPort;
2692
2821
 
2822
+ interface CreateHfImageBatchPersistenceOptions {
2823
+ namespace: string;
2824
+ token: string;
2825
+ channel: ElementEventChannel;
2826
+ /** Kennung je abgelegtem Bild. Ersetzbar, damit ein Test nicht würfelt. */
2827
+ newImageId?: (generationBatchId: string, position: number) => string;
2828
+ now?: () => Date;
2829
+ }
2830
+ /**
2831
+ * `ImageGenerationBatchPersistence` für Flow — derselbe kanonische Weg wie
2832
+ * `SzenenImageBatchWritePort.importBatch`, nur mit `source_kind:
2833
+ * 'generated_in_app'` (D-116/D-120).
2834
+ */
2835
+ declare function createHfImageGenerationBatchPersistence(options: CreateHfImageBatchPersistenceOptions): ImageGenerationBatchPersistence;
2836
+ /**
2837
+ * `SzenenImageBatchWritePort` für Flow — Gate G (D-117).
2838
+ *
2839
+ * `importBatch` ruft **keinen** Provider; er legt bereits vorhandene Bilder
2840
+ * über denselben kanonischen Weg ab wie ein in-App erzeugter Batch, nur mit
2841
+ * `source_kind: 'external_import'`.
2842
+ *
2843
+ * `attachLibraryItem` schreibt nichts — die Item-Kennung ist deterministisch
2844
+ * an den Lauf gebunden (`itemIdForRun`), es gibt in diesem Modell keine
2845
+ * Umhängung, nur eine Prüfung: gehört das genannte Item bereits zu einem
2846
+ * anderen Lauf, ist das ein Konflikt (D-117 Punkt 6/7), kein stiller Erfolg.
2847
+ */
2848
+ declare function createHfImageBatchWrite(options: CreateHfImageBatchPersistenceOptions): SzenenImageBatchWritePort;
2849
+
2850
+ interface CreateHfImageBatchHistoryOptions {
2851
+ channel: ElementEventChannel;
2852
+ }
2853
+ declare function createHfImageBatchHistory(options: CreateHfImageBatchHistoryOptions): SzenenImageBatchHistoryPort;
2854
+
2855
+ /**
2856
+ * Faltet alle `image_batch_persisted`-Ereignisse zu einem Batch je `item_id`.
2857
+ *
2858
+ * Ein zweites Ereignis mit derselben `generation_batch_id` wird ignoriert —
2859
+ * ein Wiederholungsversuch nach einem Schreibfehler darf dieselben Bilder
2860
+ * nicht doppelt zählen.
2861
+ */
2862
+ declare function collectImageBatches(events: readonly ElementEvent[]): readonly PromptImageBatch[];
2863
+ /** Alle Batches eines Prompt-Laufs — normalerweise höchstens einer (D-113). */
2864
+ declare function batchesForPromptRun(events: readonly ElementEvent[], runId: string): readonly PromptImageBatch[];
2865
+ /** Ein einzelner Batch über eine seiner `generation_batch_id`s, oder `null`. */
2866
+ declare function findImageBatch(events: readonly ElementEvent[], batchId: string): PromptImageBatch | null;
2867
+
2693
2868
  type SzenenAreaId = 'derive' | 'elements' | 'scene' | 'setup' | 'shot' | 'media';
2694
2869
  interface SzenenArea {
2695
2870
  id: SzenenAreaId;
@@ -2744,4 +2919,4 @@ interface SzenenViewProps {
2744
2919
  }
2745
2920
  declare const SzenenView: React__default.FC<SzenenViewProps>;
2746
2921
 
2747
- export { AuthoritativeSzenenStore, CATALOGUE_TYPES, type CallableImageModel, CapabilityAnchorError, type CapabilityFlag, type CapabilityReason, type CapabilityReport, type CapabilityReportInput, type CapabilityScope, type CapabilityState, type ChainQueries, type ClientDerivationChannel, type ClientDerivationStore, ContextChainPort, type CreateBrowserTextGenerationPortOptions, type CreateClientDerivationPortOptions, type CreateClientRunPortOptions, type CreateFlowSzenenViewPortOptions, type CreateHfElementStoreOptions, type CreateHfEventChannelOptions, type CreateImageGenerationPortOptions, type CreateMemoryViewPortOptions, DerivableType, DerivationAssessment, DerivationConflict, DerivationDiagnostic, DerivationFailure, DerivationImage, DerivationInputMode, type DeriveItemInput, type DerivedItem, type DerivedLineage, type DerivedRelationship, type DerivedSzenenReference, type DifferentialResult, type DifferentialStep, type Divergence, DraftChainMeta, ELEMENT_VERSION_SCHEMA_FILE, type ElementEvent, type ElementEventChannel, ElementSnapshot, type ElementStoreState, type ExistingSzenenItem, FlowGenerateText, type FreezeDraftChainInput, type FreezeFailure, type FreezeResult, type FreezeSuccess, type FrozenChainNode, type GeneratedImage, type IdFactory, type ImageGenerationBatchPersistence, type ImageGenerationCapability, type ImageGenerationEventChannel, type ImageGenerationFinishedPayload, type ImageGenerationOrder, type ImageGenerationProviderPort, type ImageGenerationResult, type ImageGenerationRunReader, type ImageGenerationStartedPayload, ImageProvenance, type ImageProviderAccessCheck, type ImageProviderInput, type InMemoryEventChannel, type InputError, type IntegrityVerdict, type ItemDerivationFailure, type ItemDerivationFailureClass, type ItemDerivationResult, type ItemMedium, type LibraryImage, type NodeContribution, NotDerivable, type Notice, type NoticeTone, type PromptRunOutcome, type PromptRunOutput, type PromptRunPersistencePort, type PromptRunRecord, type PromptRunRecordedPayload, type ProviderCheckRecord, type ProviderCheckRecordedPayload, type ProviderCheckResult, PublishCheckResult, PublishFinding, RULES_WITHOUT_CAPABILITY_EFFECT, RULE_SCOPES, type RawSchema, type RecordedDerivationInput, type RecordedProposal, type RecoveryStatus, type ReducerFinding, ReferenceResolver, type RendererInput, type ResolveFailure, type ResolveResult, type ResolveShotInput, type ResolveShotPayloadInput, ResolveTechnicalError, type ResolvedCamera, type ResolvedNode, type ResolvedPlacement, type RunEventChannel, type RunFailure, type RunFailureClass, type RunItemReference, SZENEN_EVENT_PREFIX, SZENEN_EVENT_TYPES, SZENEN_ITEM_PREFIX, SZENEN_SCHEMAS, type SaveRunAsItemInput, type SceneDerivationPersistencePort, type SceneDerivationRecord, type SceneDerivationRecordedPayload, type SceneDerivationRecoveryRecord, type SceneDerivationRecoveryRecordedPayload, SchemaError, type StartImageGenerationInput, type StartRunInput, type StepState, type SzenenArea, type SzenenAreaId, type SzenenBatchOrigin, type SzenenBatchOriginFailure, type SzenenBatchOriginVerdict, SzenenCommands, SzenenElementStore, SzenenElementType, type SzenenImageGenerationPort as SzenenImageGenerationPortContract, type SzenenImageLibraryPort, type SzenenItemPort, type SzenenMediaPort, SzenenQueries, type SzenenRunPort, SzenenView, type SzenenViewCapabilities, type SzenenViewPort, type SzenenViewProps, TargetModelResolution, TextGenerationPort, UNCHECKED_PUBLISH_RULES, UnusableProposal, type VersionMedium, type VisibilityNode, areasFor, buildSystemInstruction, buildUserPrompt, callOptional, callableImageModelFor, capabilitiesOf, capabilityForTargetModel, capabilityGate, capabilityReport, catalogueFor, checkCreateElementInput, checkElementType, checkOptionalId, checkParents, checkPayloadPresent, checkPromptRunRecord, checkPublishVersionInput, checkRequiredId, checkReviseMetadataInput, checkRevision, checkRunResponse, checkSceneDerivationRecord, checkSceneDerivationRecoveryRecord, checkSetPreferredHeadInput, checkSzenenBatchOrigin, checkTitle, checkWriteDraftInput, collectImageGenerationOrders, collectPromptRuns, collectProviderChecks, collectSceneDerivationRecoveries, collectSceneDerivations, createBrowserTextGenerationPort, createClientDerivationPort, createClientRunPort, createEventLogDerivationPersistence, createEventLogRunPersistence, createFlowSzenenViewPort, createHfElementStore, createHfEventChannel, createHfImageLibrary, createImageGenerationPort, createInMemoryEventChannel, createMemoryViewPort, derivationPoliciesOf, deriveItemFromRun, deriveLineage, differentialSteps, draftRevisionOf, findImageGenerationOrder, findPromptRun, findProviderCheck, findSceneDerivation, findSceneDerivationRecovery, firstError, freezeDraftChain, hasPlacementCapability, isKnownElementType, isSzenenItemId, itemIdForRun, logRevisionOf, mergeSzenenBatchOrigin, noticeFor, ordersForPromptRun, parseRunResponse, preferredHeadRevisionOf, publishedHeadsOf, recoveriesForRun, recoveryStatusOf, reduceElementEvents, resolveArea, resolveShot, resolveShotPayload, roundOfRun, runPromptDerivation, runStoreDifferential, scopeOfPath, totalModelCalls, unclassifiedPublishRules, unsupportedReason };
2922
+ export { type AttachLibraryItemInput, type AttachLibraryItemResult, AuthoritativeSzenenStore, CATALOGUE_TYPES, type CallableImageModel, CapabilityAnchorError, type CapabilityFlag, type CapabilityReason, type CapabilityReport, type CapabilityReportInput, type CapabilityScope, type CapabilityState, type ChainQueries, type ClientDerivationChannel, type ClientDerivationStore, ContextChainPort, type CreateBrowserTextGenerationPortOptions, type CreateClientDerivationPortOptions, type CreateClientRunPortOptions, type CreateFlowSzenenViewPortOptions, type CreateHfElementStoreOptions, type CreateHfEventChannelOptions, type CreateHfImageBatchHistoryOptions, type CreateHfImageBatchPersistenceOptions, type CreateImageGenerationPortOptions, type CreateMemoryViewPortOptions, DerivableType, DerivationAssessment, DerivationConflict, DerivationDiagnostic, DerivationFailure, DerivationImage, DerivationInputMode, type DeriveItemInput, type DerivedItem, type DerivedLineage, type DerivedRelationship, type DerivedSzenenReference, type DifferentialResult, type DifferentialStep, type Divergence, DraftChainMeta, ELEMENT_VERSION_SCHEMA_FILE, type ElementEvent, type ElementEventChannel, ElementSnapshot, type ElementStoreState, type ExistingSzenenItem, FLOW_MODEL_DISPLAY_NAMES, type FlowGenerateImage, type FlowGenerateImageParams, FlowGenerateText, type FreezeDraftChainInput, type FreezeFailure, type FreezeResult, type FreezeSuccess, type FrozenChainNode, type GeneratedImage, type IdFactory, type ImageBatchPersistedImage, type ImageBatchPersistedPayload, type ImageGenerationBatchPersistence, type ImageGenerationCapability, type ImageGenerationEventChannel, type ImageGenerationFinishedPayload, type ImageGenerationOrder, type ImageGenerationProviderPort, type ImageGenerationResult, type ImageGenerationRunReader, type ImageGenerationStartedPayload, ImageProvenance, type ImageProviderAccessCheck, type ImageProviderInput, type ImportBatchImageInput, type ImportBatchInput, type InMemoryEventChannel, type InputError, type IntegrityVerdict, type ItemDerivationFailure, type ItemDerivationFailureClass, type ItemDerivationResult, type ItemMedium, type LibraryImage, type NodeContribution, NotDerivable, type Notice, type NoticeTone, type PromptBatchImageRef, type PromptImageBatch, type PromptRunOutcome, type PromptRunOutput, type PromptRunPersistencePort, type PromptRunRecord, type PromptRunRecordedPayload, type ProviderCheckRecord, type ProviderCheckRecordedPayload, type ProviderCheckResult, PublishCheckResult, PublishFinding, RULES_WITHOUT_CAPABILITY_EFFECT, RULE_SCOPES, type RawSchema, type RecordedDerivationInput, type RecordedProposal, type RecoveryStatus, type ReducerFinding, ReferenceResolver, type RendererInput, type ResolveFailure, type ResolveResult, type ResolveShotInput, type ResolveShotPayloadInput, ResolveTechnicalError, type ResolvedCamera, type ResolvedNode, type ResolvedPlacement, type RunEventChannel, type RunFailure, type RunFailureClass, type RunItemReference, SZENEN_EVENT_PREFIX, SZENEN_EVENT_TYPES, SZENEN_ITEM_PREFIX, SZENEN_SCHEMAS, type SaveRunAsItemInput, type SceneDerivationPersistencePort, type SceneDerivationRecord, type SceneDerivationRecordedPayload, type SceneDerivationRecoveryRecord, type SceneDerivationRecoveryRecordedPayload, SchemaError, type StartImageGenerationInput, type StartRunInput, type StepState, type SzenenArea, type SzenenAreaId, type SzenenBatchOrigin, type SzenenBatchOriginFailure, type SzenenBatchOriginVerdict, SzenenCommands, SzenenElementStore, SzenenElementType, type SzenenImageBatchHistoryPort, type SzenenImageBatchWritePort, type SzenenImageGenerationPort as SzenenImageGenerationPortContract, type SzenenImageLibraryPort, type SzenenItemPort, type SzenenMediaPort, SzenenQueries, type SzenenRunPort, SzenenView, type SzenenViewCapabilities, type SzenenViewPort, type SzenenViewProps, TargetModelResolution, TextGenerationPort, UNCHECKED_PUBLISH_RULES, UnusableProposal, type VersionMedium, type VisibilityNode, areasFor, batchesForPromptRun, buildSystemInstruction, buildUserPrompt, callOptional, callableImageModelFor, capabilitiesOf, capabilityForTargetModel, capabilityGate, capabilityReport, catalogueFor, checkCreateElementInput, checkElementType, checkOptionalId, checkParents, checkPayloadPresent, checkPromptRunRecord, checkPublishVersionInput, checkRequiredId, checkReviseMetadataInput, checkRevision, checkRunResponse, checkSceneDerivationRecord, checkSceneDerivationRecoveryRecord, checkSetPreferredHeadInput, checkSzenenBatchOrigin, checkTitle, checkWriteDraftInput, collectImageBatches, collectImageGenerationOrders, collectPromptRuns, collectProviderChecks, collectSceneDerivationRecoveries, collectSceneDerivations, createBrowserTextGenerationPort, createClientDerivationPort, createClientRunPort, createEventLogDerivationPersistence, createEventLogRunPersistence, createFlowImageProvider, createFlowSzenenViewPort, createHfElementStore, createHfEventChannel, createHfImageBatchHistory, createHfImageBatchWrite, createHfImageGenerationBatchPersistence, createHfImageLibrary, createImageGenerationPort, createInMemoryEventChannel, createMemoryViewPort, derivationPoliciesOf, deriveItemFromRun, deriveLineage, differentialSteps, draftRevisionOf, findImageBatch, findImageGenerationOrder, findPromptRun, findProviderCheck, findSceneDerivation, findSceneDerivationRecovery, firstError, flowImageProviderHasAccess, freezeDraftChain, hasPlacementCapability, isKnownElementType, isSzenenItemId, itemIdForRun, logRevisionOf, mergeSzenenBatchOrigin, noticeFor, ordersForPromptRun, parseRunResponse, preferredHeadRevisionOf, publishedHeadsOf, recoveriesForRun, recoveryStatusOf, reduceElementEvents, resolveArea, resolveShot, resolveShotPayload, roundOfRun, runPromptDerivation, runStoreDifferential, scopeOfPath, totalModelCalls, unclassifiedPublishRules, unsupportedReason };