@rslsp1/fa-app-tools 1.1.2 → 1.1.4
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.d.mts +15 -4
- package/dist/index.d.ts +15 -4
- package/dist/index.js +97 -8
- package/dist/index.mjs +97 -8
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -93,13 +93,21 @@ declare function parsePromptResponse(raw: string): {
|
|
|
93
93
|
prompt: string;
|
|
94
94
|
feedback: string | null;
|
|
95
95
|
};
|
|
96
|
+
interface FlowSdkImage {
|
|
97
|
+
base64: string;
|
|
98
|
+
mimeType: string;
|
|
99
|
+
}
|
|
96
100
|
interface FlowSdk {
|
|
97
101
|
generate: {
|
|
98
102
|
image: (options: Record<string, any>) => Promise<{
|
|
99
103
|
base64: string;
|
|
100
104
|
mediaId: string;
|
|
101
105
|
}>;
|
|
102
|
-
text: (prompt: string, options?:
|
|
106
|
+
text: (prompt: string, options?: {
|
|
107
|
+
systemInstruction?: string;
|
|
108
|
+
thinkingLevel?: string;
|
|
109
|
+
images?: FlowSdkImage[];
|
|
110
|
+
}) => Promise<{
|
|
103
111
|
text: string;
|
|
104
112
|
}>;
|
|
105
113
|
};
|
|
@@ -119,7 +127,7 @@ declare function createFlowServices(Flow: FlowSdk): {
|
|
|
119
127
|
base64: string;
|
|
120
128
|
mediaId: string;
|
|
121
129
|
}>;
|
|
122
|
-
generateText: (hierarchyText: string, mode?: "literal" | "creative") => Promise<string>;
|
|
130
|
+
generateText: (hierarchyText: string, mode?: "literal" | "creative" | "scan", images?: FlowSdkImage[]) => Promise<string>;
|
|
123
131
|
};
|
|
124
132
|
declare function interpretSdkError(err: any): Error;
|
|
125
133
|
|
|
@@ -233,7 +241,10 @@ interface AvatarArchitectAppProps {
|
|
|
233
241
|
base64: string;
|
|
234
242
|
mediaId?: string;
|
|
235
243
|
}>;
|
|
236
|
-
onGeneratePrompt: (text: string
|
|
244
|
+
onGeneratePrompt: (text: string, mode?: string, images?: {
|
|
245
|
+
base64: string;
|
|
246
|
+
mimeType: string;
|
|
247
|
+
}[]) => Promise<string>;
|
|
237
248
|
onDownload: (base64: string, mimeType: string, filename: string) => Promise<void>;
|
|
238
249
|
onSelectMedia: () => Promise<MediaItem[]>;
|
|
239
250
|
buildInfo?: string;
|
|
@@ -297,6 +308,6 @@ interface ProjectSyncTabProps {
|
|
|
297
308
|
}
|
|
298
309
|
declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
|
|
299
310
|
|
|
300
|
-
declare const LIB_VERSION = "1.1.
|
|
311
|
+
declare const LIB_VERSION = "1.1.4";
|
|
301
312
|
|
|
302
313
|
export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedTag, SetupPanel, type SyncDiff, type TagOption, type WorkspaceTags, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildPromptTabPayload, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, getFormattedTimestamp, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
|
package/dist/index.d.ts
CHANGED
|
@@ -93,13 +93,21 @@ declare function parsePromptResponse(raw: string): {
|
|
|
93
93
|
prompt: string;
|
|
94
94
|
feedback: string | null;
|
|
95
95
|
};
|
|
96
|
+
interface FlowSdkImage {
|
|
97
|
+
base64: string;
|
|
98
|
+
mimeType: string;
|
|
99
|
+
}
|
|
96
100
|
interface FlowSdk {
|
|
97
101
|
generate: {
|
|
98
102
|
image: (options: Record<string, any>) => Promise<{
|
|
99
103
|
base64: string;
|
|
100
104
|
mediaId: string;
|
|
101
105
|
}>;
|
|
102
|
-
text: (prompt: string, options?:
|
|
106
|
+
text: (prompt: string, options?: {
|
|
107
|
+
systemInstruction?: string;
|
|
108
|
+
thinkingLevel?: string;
|
|
109
|
+
images?: FlowSdkImage[];
|
|
110
|
+
}) => Promise<{
|
|
103
111
|
text: string;
|
|
104
112
|
}>;
|
|
105
113
|
};
|
|
@@ -119,7 +127,7 @@ declare function createFlowServices(Flow: FlowSdk): {
|
|
|
119
127
|
base64: string;
|
|
120
128
|
mediaId: string;
|
|
121
129
|
}>;
|
|
122
|
-
generateText: (hierarchyText: string, mode?: "literal" | "creative") => Promise<string>;
|
|
130
|
+
generateText: (hierarchyText: string, mode?: "literal" | "creative" | "scan", images?: FlowSdkImage[]) => Promise<string>;
|
|
123
131
|
};
|
|
124
132
|
declare function interpretSdkError(err: any): Error;
|
|
125
133
|
|
|
@@ -233,7 +241,10 @@ interface AvatarArchitectAppProps {
|
|
|
233
241
|
base64: string;
|
|
234
242
|
mediaId?: string;
|
|
235
243
|
}>;
|
|
236
|
-
onGeneratePrompt: (text: string
|
|
244
|
+
onGeneratePrompt: (text: string, mode?: string, images?: {
|
|
245
|
+
base64: string;
|
|
246
|
+
mimeType: string;
|
|
247
|
+
}[]) => Promise<string>;
|
|
237
248
|
onDownload: (base64: string, mimeType: string, filename: string) => Promise<void>;
|
|
238
249
|
onSelectMedia: () => Promise<MediaItem[]>;
|
|
239
250
|
buildInfo?: string;
|
|
@@ -297,6 +308,6 @@ interface ProjectSyncTabProps {
|
|
|
297
308
|
}
|
|
298
309
|
declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
|
|
299
310
|
|
|
300
|
-
declare const LIB_VERSION = "1.1.
|
|
311
|
+
declare const LIB_VERSION = "1.1.4";
|
|
301
312
|
|
|
302
313
|
export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedTag, SetupPanel, type SyncDiff, type TagOption, type WorkspaceTags, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildPromptTabPayload, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, getFormattedTimestamp, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
|
package/dist/index.js
CHANGED
|
@@ -428,7 +428,24 @@ function createFlowServices(Flow) {
|
|
|
428
428
|
throw interpretSdkError(err);
|
|
429
429
|
}
|
|
430
430
|
},
|
|
431
|
-
generateText: async (hierarchyText, mode = "creative") => {
|
|
431
|
+
generateText: async (hierarchyText, mode = "creative", images) => {
|
|
432
|
+
if (mode === "scan" && images?.length) {
|
|
433
|
+
try {
|
|
434
|
+
const response = await Flow.generate.text(
|
|
435
|
+
"Analyze this image and create a detailed image generation prompt that would recreate it. Focus on: subject, style, lighting, composition, color palette, mood, and technical quality. Output ONLY the prompt string, no explanations.",
|
|
436
|
+
{
|
|
437
|
+
thinkingLevel: "low",
|
|
438
|
+
systemInstruction: "You are an expert image analyst and prompt engineer. Always return ONLY the generation prompt, no headers, no quotes, no conversational filler.",
|
|
439
|
+
images
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
const result = response?.text?.trim() || "";
|
|
443
|
+
if (!result) throw new Error("Empty AI response");
|
|
444
|
+
return cleanAiResponse(result);
|
|
445
|
+
} catch (err) {
|
|
446
|
+
throw interpretSdkError(err);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
432
449
|
const prompt = buildGenerationPrompt(hierarchyText, mode);
|
|
433
450
|
try {
|
|
434
451
|
const response = await Flow.generate.text(prompt, {
|
|
@@ -1704,6 +1721,20 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
1704
1721
|
const [seedMode, setSeedMode] = (0, import_react14.useState)("random");
|
|
1705
1722
|
const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react14.useState)(false);
|
|
1706
1723
|
const [isRightCollapsed, setIsRightCollapsed] = (0, import_react14.useState)(false);
|
|
1724
|
+
const [leftPanelWidth, setLeftPanelWidth] = (0, import_react14.useState)(() => {
|
|
1725
|
+
try {
|
|
1726
|
+
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
1727
|
+
} catch {
|
|
1728
|
+
return 260;
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
const [rightPanelWidth, setRightPanelWidth] = (0, import_react14.useState)(() => {
|
|
1732
|
+
try {
|
|
1733
|
+
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
1734
|
+
} catch {
|
|
1735
|
+
return 320;
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1707
1738
|
const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react14.useState)(false);
|
|
1708
1739
|
const [projectActionState, setProjectActionState] = (0, import_react14.useState)("idle");
|
|
1709
1740
|
const syncServerDataRef = (0, import_react14.useRef)(null);
|
|
@@ -1719,6 +1750,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
1719
1750
|
});
|
|
1720
1751
|
const [activeReferenceId, setActiveReferenceId] = (0, import_react14.useState)(null);
|
|
1721
1752
|
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react14.useState)(null);
|
|
1753
|
+
const [isScanningImage, setIsScanningImage] = (0, import_react14.useState)(false);
|
|
1722
1754
|
const [touchStartX, setTouchStartX] = (0, import_react14.useState)(null);
|
|
1723
1755
|
const [isFullscreen, setIsFullscreen] = (0, import_react14.useState)(false);
|
|
1724
1756
|
const [zoomScale, setZoomScale] = (0, import_react14.useState)(1);
|
|
@@ -1788,6 +1820,61 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
1788
1820
|
setActiveReferenceId(null);
|
|
1789
1821
|
setActiveReferenceThumbnail(null);
|
|
1790
1822
|
};
|
|
1823
|
+
const startLeftResize = (e) => {
|
|
1824
|
+
e.preventDefault();
|
|
1825
|
+
const startX = e.clientX;
|
|
1826
|
+
const startW = leftPanelWidth;
|
|
1827
|
+
const onMove = (ev) => {
|
|
1828
|
+
const w = Math.max(180, Math.min(520, startW + ev.clientX - startX));
|
|
1829
|
+
setLeftPanelWidth(w);
|
|
1830
|
+
try {
|
|
1831
|
+
localStorage.setItem("aa-left-width", String(w));
|
|
1832
|
+
} catch {
|
|
1833
|
+
}
|
|
1834
|
+
};
|
|
1835
|
+
const onUp = () => {
|
|
1836
|
+
document.removeEventListener("mousemove", onMove);
|
|
1837
|
+
document.removeEventListener("mouseup", onUp);
|
|
1838
|
+
};
|
|
1839
|
+
document.addEventListener("mousemove", onMove);
|
|
1840
|
+
document.addEventListener("mouseup", onUp);
|
|
1841
|
+
};
|
|
1842
|
+
const startRightResize = (e) => {
|
|
1843
|
+
e.preventDefault();
|
|
1844
|
+
const startX = e.clientX;
|
|
1845
|
+
const startW = rightPanelWidth;
|
|
1846
|
+
const onMove = (ev) => {
|
|
1847
|
+
const w = Math.max(180, Math.min(520, startW - (ev.clientX - startX)));
|
|
1848
|
+
setRightPanelWidth(w);
|
|
1849
|
+
try {
|
|
1850
|
+
localStorage.setItem("aa-right-width", String(w));
|
|
1851
|
+
} catch {
|
|
1852
|
+
}
|
|
1853
|
+
};
|
|
1854
|
+
const onUp = () => {
|
|
1855
|
+
document.removeEventListener("mousemove", onMove);
|
|
1856
|
+
document.removeEventListener("mouseup", onUp);
|
|
1857
|
+
};
|
|
1858
|
+
document.addEventListener("mousemove", onMove);
|
|
1859
|
+
document.addEventListener("mouseup", onUp);
|
|
1860
|
+
};
|
|
1861
|
+
const handleScanImage = async (file) => {
|
|
1862
|
+
setIsScanningImage(true);
|
|
1863
|
+
try {
|
|
1864
|
+
const base64 = await new Promise((resolve, reject) => {
|
|
1865
|
+
const reader = new FileReader();
|
|
1866
|
+
reader.onloadend = () => resolve(reader.result.split(",")[1]);
|
|
1867
|
+
reader.onerror = reject;
|
|
1868
|
+
reader.readAsDataURL(file);
|
|
1869
|
+
});
|
|
1870
|
+
const prompt = await onGeneratePrompt("", "scan", [{ base64, mimeType: file.type || "image/png" }]);
|
|
1871
|
+
setActivePrompt(prompt);
|
|
1872
|
+
} catch (err) {
|
|
1873
|
+
console.error("Scan fehlgeschlagen:", err);
|
|
1874
|
+
} finally {
|
|
1875
|
+
setIsScanningImage(false);
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1791
1878
|
const currentIndex = (0, import_react14.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
1792
1879
|
const goToPrev = (0, import_react14.useCallback)(() => {
|
|
1793
1880
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
@@ -2347,7 +2434,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2347
2434
|
} })
|
|
2348
2435
|
] })
|
|
2349
2436
|
] }),
|
|
2350
|
-
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
|
|
2351
2438
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
|
|
2352
2439
|
workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { onClick: () => {
|
|
2353
2440
|
setLeftTab("prompt");
|
|
@@ -2404,10 +2491,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2404
2491
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
2405
2492
|
}
|
|
2406
2493
|
) }),
|
|
2407
|
-
leftTab === "prompt" &&
|
|
2494
|
+
workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
|
|
2408
2495
|
handleGenerateImage(prompt);
|
|
2409
2496
|
setMobileTab("stage");
|
|
2410
|
-
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete }),
|
|
2497
|
+
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
|
|
2411
2498
|
activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
|
|
2412
2499
|
activeTab === "sync" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2413
2500
|
ProjectSyncTab,
|
|
@@ -2543,7 +2630,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2543
2630
|
}
|
|
2544
2631
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
|
|
2545
2632
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
|
|
2546
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 :
|
|
2633
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 : leftPanelWidth, transition: "none" }, children: [
|
|
2547
2634
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
|
|
2548
2635
|
!isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-1 gap-1", children: [
|
|
2549
2636
|
workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { onClick: () => setLeftTab("prompt"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
|
|
@@ -2583,9 +2670,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2583
2670
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
2584
2671
|
}
|
|
2585
2672
|
) }),
|
|
2586
|
-
leftTab === "prompt" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete })
|
|
2673
|
+
leftTab === "prompt" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
|
|
2587
2674
|
] })
|
|
2588
2675
|
] }),
|
|
2676
|
+
!isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
2589
2677
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
|
|
2590
2678
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
|
|
2591
2679
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -2639,7 +2727,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2639
2727
|
] }) })
|
|
2640
2728
|
] })
|
|
2641
2729
|
] }),
|
|
2642
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
2730
|
+
!isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
2731
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
|
|
2643
2732
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
|
|
2644
2733
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: () => {
|
|
2645
2734
|
setActiveTab(tab);
|
|
@@ -2687,7 +2776,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2687
2776
|
}
|
|
2688
2777
|
|
|
2689
2778
|
// src/index.ts
|
|
2690
|
-
var LIB_VERSION = "1.1.
|
|
2779
|
+
var LIB_VERSION = "1.1.4";
|
|
2691
2780
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2692
2781
|
0 && (module.exports = {
|
|
2693
2782
|
AvatarArchitectApp,
|
package/dist/index.mjs
CHANGED
|
@@ -362,7 +362,24 @@ function createFlowServices(Flow) {
|
|
|
362
362
|
throw interpretSdkError(err);
|
|
363
363
|
}
|
|
364
364
|
},
|
|
365
|
-
generateText: async (hierarchyText, mode = "creative") => {
|
|
365
|
+
generateText: async (hierarchyText, mode = "creative", images) => {
|
|
366
|
+
if (mode === "scan" && images?.length) {
|
|
367
|
+
try {
|
|
368
|
+
const response = await Flow.generate.text(
|
|
369
|
+
"Analyze this image and create a detailed image generation prompt that would recreate it. Focus on: subject, style, lighting, composition, color palette, mood, and technical quality. Output ONLY the prompt string, no explanations.",
|
|
370
|
+
{
|
|
371
|
+
thinkingLevel: "low",
|
|
372
|
+
systemInstruction: "You are an expert image analyst and prompt engineer. Always return ONLY the generation prompt, no headers, no quotes, no conversational filler.",
|
|
373
|
+
images
|
|
374
|
+
}
|
|
375
|
+
);
|
|
376
|
+
const result = response?.text?.trim() || "";
|
|
377
|
+
if (!result) throw new Error("Empty AI response");
|
|
378
|
+
return cleanAiResponse(result);
|
|
379
|
+
} catch (err) {
|
|
380
|
+
throw interpretSdkError(err);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
366
383
|
const prompt = buildGenerationPrompt(hierarchyText, mode);
|
|
367
384
|
try {
|
|
368
385
|
const response = await Flow.generate.text(prompt, {
|
|
@@ -1638,6 +1655,20 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
1638
1655
|
const [seedMode, setSeedMode] = useState6("random");
|
|
1639
1656
|
const [isLeftCollapsed, setIsLeftCollapsed] = useState6(false);
|
|
1640
1657
|
const [isRightCollapsed, setIsRightCollapsed] = useState6(false);
|
|
1658
|
+
const [leftPanelWidth, setLeftPanelWidth] = useState6(() => {
|
|
1659
|
+
try {
|
|
1660
|
+
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
1661
|
+
} catch {
|
|
1662
|
+
return 260;
|
|
1663
|
+
}
|
|
1664
|
+
});
|
|
1665
|
+
const [rightPanelWidth, setRightPanelWidth] = useState6(() => {
|
|
1666
|
+
try {
|
|
1667
|
+
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
1668
|
+
} catch {
|
|
1669
|
+
return 320;
|
|
1670
|
+
}
|
|
1671
|
+
});
|
|
1641
1672
|
const [isPromptCollapsed, setIsPromptCollapsed] = useState6(false);
|
|
1642
1673
|
const [projectActionState, setProjectActionState] = useState6("idle");
|
|
1643
1674
|
const syncServerDataRef = useRef6(null);
|
|
@@ -1653,6 +1684,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
1653
1684
|
});
|
|
1654
1685
|
const [activeReferenceId, setActiveReferenceId] = useState6(null);
|
|
1655
1686
|
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState6(null);
|
|
1687
|
+
const [isScanningImage, setIsScanningImage] = useState6(false);
|
|
1656
1688
|
const [touchStartX, setTouchStartX] = useState6(null);
|
|
1657
1689
|
const [isFullscreen, setIsFullscreen] = useState6(false);
|
|
1658
1690
|
const [zoomScale, setZoomScale] = useState6(1);
|
|
@@ -1722,6 +1754,61 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
1722
1754
|
setActiveReferenceId(null);
|
|
1723
1755
|
setActiveReferenceThumbnail(null);
|
|
1724
1756
|
};
|
|
1757
|
+
const startLeftResize = (e) => {
|
|
1758
|
+
e.preventDefault();
|
|
1759
|
+
const startX = e.clientX;
|
|
1760
|
+
const startW = leftPanelWidth;
|
|
1761
|
+
const onMove = (ev) => {
|
|
1762
|
+
const w = Math.max(180, Math.min(520, startW + ev.clientX - startX));
|
|
1763
|
+
setLeftPanelWidth(w);
|
|
1764
|
+
try {
|
|
1765
|
+
localStorage.setItem("aa-left-width", String(w));
|
|
1766
|
+
} catch {
|
|
1767
|
+
}
|
|
1768
|
+
};
|
|
1769
|
+
const onUp = () => {
|
|
1770
|
+
document.removeEventListener("mousemove", onMove);
|
|
1771
|
+
document.removeEventListener("mouseup", onUp);
|
|
1772
|
+
};
|
|
1773
|
+
document.addEventListener("mousemove", onMove);
|
|
1774
|
+
document.addEventListener("mouseup", onUp);
|
|
1775
|
+
};
|
|
1776
|
+
const startRightResize = (e) => {
|
|
1777
|
+
e.preventDefault();
|
|
1778
|
+
const startX = e.clientX;
|
|
1779
|
+
const startW = rightPanelWidth;
|
|
1780
|
+
const onMove = (ev) => {
|
|
1781
|
+
const w = Math.max(180, Math.min(520, startW - (ev.clientX - startX)));
|
|
1782
|
+
setRightPanelWidth(w);
|
|
1783
|
+
try {
|
|
1784
|
+
localStorage.setItem("aa-right-width", String(w));
|
|
1785
|
+
} catch {
|
|
1786
|
+
}
|
|
1787
|
+
};
|
|
1788
|
+
const onUp = () => {
|
|
1789
|
+
document.removeEventListener("mousemove", onMove);
|
|
1790
|
+
document.removeEventListener("mouseup", onUp);
|
|
1791
|
+
};
|
|
1792
|
+
document.addEventListener("mousemove", onMove);
|
|
1793
|
+
document.addEventListener("mouseup", onUp);
|
|
1794
|
+
};
|
|
1795
|
+
const handleScanImage = async (file) => {
|
|
1796
|
+
setIsScanningImage(true);
|
|
1797
|
+
try {
|
|
1798
|
+
const base64 = await new Promise((resolve, reject) => {
|
|
1799
|
+
const reader = new FileReader();
|
|
1800
|
+
reader.onloadend = () => resolve(reader.result.split(",")[1]);
|
|
1801
|
+
reader.onerror = reject;
|
|
1802
|
+
reader.readAsDataURL(file);
|
|
1803
|
+
});
|
|
1804
|
+
const prompt = await onGeneratePrompt("", "scan", [{ base64, mimeType: file.type || "image/png" }]);
|
|
1805
|
+
setActivePrompt(prompt);
|
|
1806
|
+
} catch (err) {
|
|
1807
|
+
console.error("Scan fehlgeschlagen:", err);
|
|
1808
|
+
} finally {
|
|
1809
|
+
setIsScanningImage(false);
|
|
1810
|
+
}
|
|
1811
|
+
};
|
|
1725
1812
|
const currentIndex = useMemo2(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
1726
1813
|
const goToPrev = useCallback(() => {
|
|
1727
1814
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
@@ -2281,7 +2368,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2281
2368
|
} })
|
|
2282
2369
|
] })
|
|
2283
2370
|
] }),
|
|
2284
|
-
|
|
2371
|
+
/* @__PURE__ */ jsxs11("div", { style: { display: mobileTab === "tools" ? "flex" : "none" }, className: "flex flex-col flex-1 min-h-0", children: [
|
|
2285
2372
|
/* @__PURE__ */ jsxs11("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
|
|
2286
2373
|
workspaceTags && /* @__PURE__ */ jsxs11("button", { onClick: () => {
|
|
2287
2374
|
setLeftTab("prompt");
|
|
@@ -2338,10 +2425,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2338
2425
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
2339
2426
|
}
|
|
2340
2427
|
) }),
|
|
2341
|
-
leftTab === "prompt" &&
|
|
2428
|
+
workspaceTags && /* @__PURE__ */ jsx13("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ jsx13(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
|
|
2342
2429
|
handleGenerateImage(prompt);
|
|
2343
2430
|
setMobileTab("stage");
|
|
2344
|
-
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete }),
|
|
2431
|
+
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
|
|
2345
2432
|
activeTab === "setup" && /* @__PURE__ */ jsx13(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
|
|
2346
2433
|
activeTab === "sync" && /* @__PURE__ */ jsx13(
|
|
2347
2434
|
ProjectSyncTab,
|
|
@@ -2477,7 +2564,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2477
2564
|
}
|
|
2478
2565
|
return /* @__PURE__ */ jsxs11("div", { className: "flex h-screen w-screen bg-[#0e0e0e] text-white overflow-hidden", style: hcStyle, children: [
|
|
2479
2566
|
/* @__PURE__ */ jsx13("div", { className: "absolute top-2 right-2 z-50", children: /* @__PURE__ */ jsx13("button", { onClick: () => setShowStart(true), className: "text-white/10 hover:text-white/30 transition-colors text-[10px]", children: "\u21C4" }) }),
|
|
2480
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 :
|
|
2567
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col border-r border-white/5 overflow-hidden relative bg-black/10 shrink-0", style: { width: isLeftCollapsed ? 48 : leftPanelWidth, transition: "none" }, children: [
|
|
2481
2568
|
/* @__PURE__ */ jsxs11("div", { className: "h-14 border-b border-white/5 flex items-center justify-between shrink-0 px-1", children: [
|
|
2482
2569
|
!isLeftCollapsed && /* @__PURE__ */ jsxs11("div", { className: "flex flex-1 gap-1", children: [
|
|
2483
2570
|
workspaceTags && /* @__PURE__ */ jsxs11("button", { onClick: () => setLeftTab("prompt"), className: `flex-1 flex items-center justify-center gap-1 h-8 rounded-lg text-[8px] font-bold uppercase tracking-wide transition-colors ${leftTab === "prompt" ? "bg-white/10 text-white" : "text-white/30 hover:text-white/60"}`, children: [
|
|
@@ -2517,9 +2604,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2517
2604
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
2518
2605
|
}
|
|
2519
2606
|
) }),
|
|
2520
|
-
leftTab === "prompt" && workspaceTags && /* @__PURE__ */ jsx13(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete })
|
|
2607
|
+
leftTab === "prompt" && workspaceTags && /* @__PURE__ */ jsx13(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateImage(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
|
|
2521
2608
|
] })
|
|
2522
2609
|
] }),
|
|
2610
|
+
!isLeftCollapsed && /* @__PURE__ */ jsx13("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
2523
2611
|
/* @__PURE__ */ jsxs11("div", { className: "flex-1 flex flex-col bg-[#0b0b0b] overflow-hidden", children: [
|
|
2524
2612
|
/* @__PURE__ */ jsxs11("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
|
|
2525
2613
|
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5", children: [
|
|
@@ -2573,7 +2661,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2573
2661
|
] }) })
|
|
2574
2662
|
] })
|
|
2575
2663
|
] }),
|
|
2576
|
-
/* @__PURE__ */
|
|
2664
|
+
!isRightCollapsed && /* @__PURE__ */ jsx13("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
2665
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col border-l border-white/5 bg-[#0e0e0e] shrink-0", style: { width: isRightCollapsed ? 60 : rightPanelWidth, transition: "none" }, children: [
|
|
2577
2666
|
/* @__PURE__ */ jsxs11("div", { className: "flex border-b border-white/5 h-14 shrink-0 overflow-hidden", children: [
|
|
2578
2667
|
/* @__PURE__ */ jsx13("div", { className: "flex flex-1", children: ["history", "gallery", "inspect", "setup", "sync"].map((tab) => /* @__PURE__ */ jsx13("button", { onClick: () => {
|
|
2579
2668
|
setActiveTab(tab);
|
|
@@ -2621,7 +2710,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2621
2710
|
}
|
|
2622
2711
|
|
|
2623
2712
|
// src/index.ts
|
|
2624
|
-
var LIB_VERSION = "1.1.
|
|
2713
|
+
var LIB_VERSION = "1.1.4";
|
|
2625
2714
|
export {
|
|
2626
2715
|
AvatarArchitectApp,
|
|
2627
2716
|
CollapsibleCard,
|