From 33f87eb35dffdf42b0dbb41ba142ea7dfe9aacd2 Mon Sep 17 00:00:00 2001 From: kang Date: Wed, 20 May 2026 22:43:19 +0800 Subject: [PATCH] auto-save 2026-05-20 22:43 (~2) --- .memory/worklog.json | 238 +++++++++++++++++++++++++++++++++++++++ src/lib/packGenerator.ts | 39 +++++-- 2 files changed, 269 insertions(+), 8 deletions(-) diff --git a/.memory/worklog.json b/.memory/worklog.json index 0b83407..4a67e18 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -1601,6 +1601,244 @@ "message": "auto-save 2026-05-20 17:17 (~2)", "hash": "1325a73", "files_changed": 2 + }, + { + "ts": "2026-05-20T17:17:42+08:00", + "type": "commit", + "message": "fix: default replicate previews to portrait ratio", + "hash": "94bca09", + "files_changed": 2 + }, + { + "ts": "2026-05-20T17:38:50+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 17:38 (~2)", + "hash": "30790d2", + "files_changed": 2 + }, + { + "ts": "2026-05-20T17:44:16+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 17:44 (~4)", + "hash": "6ad847f", + "files_changed": 4 + }, + { + "ts": "2026-05-20T17:49:41+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 17:49 (~2)", + "hash": "ef77adb", + "files_changed": 2 + }, + { + "ts": "2026-05-20T18:00:32+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 18:00 (+1, ~1)", + "hash": "9d91086", + "files_changed": 2 + }, + { + "ts": "2026-05-20T18:05:58+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 18:05 (+1, ~1)", + "hash": "9cabc44", + "files_changed": 2 + }, + { + "ts": "2026-05-20T18:22:16+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 18:22 (+2, ~3)", + "hash": "b35c386", + "files_changed": 5 + }, + { + "ts": "2026-05-20T18:27:42+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 18:27 (+3, ~1)", + "hash": "62b322a", + "files_changed": 4 + }, + { + "ts": "2026-05-20T18:33:08+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 18:33 (~5)", + "hash": "e2c288f", + "files_changed": 5 + }, + { + "ts": "2026-05-20T18:40:30+08:00", + "type": "commit", + "message": "fix: merge pack progress into project brief", + "hash": "f0b85dd", + "files_changed": 4 + }, + { + "ts": "2026-05-20T18:49:26+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 18:49 (~3)", + "hash": "f2fe3e9", + "files_changed": 3 + }, + { + "ts": "2026-05-20T19:00:17+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 19:00 (~3)", + "hash": "b49d795", + "files_changed": 3 + }, + { + "ts": "2026-05-20T19:00:44+08:00", + "type": "commit", + "message": "fix: show pack assets as horizontal detail strip", + "hash": "d3d9349", + "files_changed": 2 + }, + { + "ts": "2026-05-20T19:11:08+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 19:11 (~2)", + "hash": "6ee6e36", + "files_changed": 2 + }, + { + "ts": "2026-05-20T19:22:24+08:00", + "type": "commit", + "message": "fix: switch asset tabs as single panel", + "hash": "2e3bc50", + "files_changed": 1 + }, + { + "ts": "2026-05-20T19:27:49+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 19:27 (~3)", + "hash": "a93be9b", + "files_changed": 3 + }, + { + "ts": "2026-05-20T19:36:55+08:00", + "type": "commit", + "message": "fix: render asset tabs as ratio-preserving grid", + "hash": "5a05058", + "files_changed": 2 + }, + { + "ts": "2026-05-20T19:49:32+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 19:49 (~2)", + "hash": "89c3ed7", + "files_changed": 2 + }, + { + "ts": "2026-05-20T19:50:56+08:00", + "type": "commit", + "message": "fix: keep hover previews near pointer", + "hash": "cacb0bd", + "files_changed": 1 + }, + { + "ts": "2026-05-20T20:00:24+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:00 (~5)", + "hash": "40c8bc1", + "files_changed": 5 + }, + { + "ts": "2026-05-20T20:11:16+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:11 (~2)", + "hash": "c002c37", + "files_changed": 2 + }, + { + "ts": "2026-05-20T20:16:29+08:00", + "type": "commit", + "message": "fix: sync side gallery with active asset panel", + "hash": "3f087ed", + "files_changed": 4 + }, + { + "ts": "2026-05-20T20:22:10+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:22 (+1, ~1)", + "hash": "be4e1ad", + "files_changed": 2 + }, + { + "ts": "2026-05-20T20:27:35+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:27 (~5)", + "hash": "cd1a870", + "files_changed": 5 + }, + { + "ts": "2026-05-20T20:33:02+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:32 (~2)", + "hash": "0ebbe2e", + "files_changed": 2 + }, + { + "ts": "2026-05-20T20:42:45+08:00", + "type": "commit", + "message": "feat: add active pack image downloads", + "hash": "0869c74", + "files_changed": 5 + }, + { + "ts": "2026-05-20T20:49:19+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:49 (+2, ~4)", + "hash": "0f389a0", + "files_changed": 6 + }, + { + "ts": "2026-05-20T20:54:46+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 20:54 (~3)", + "hash": "5180db7", + "files_changed": 3 + }, + { + "ts": "2026-05-20T21:05:37+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 21:05 (~2)", + "hash": "96afeee", + "files_changed": 2 + }, + { + "ts": "2026-05-20T21:16:29+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 21:16 (~2)", + "hash": "c12fe00", + "files_changed": 2 + }, + { + "ts": "2026-05-20T21:20:41+08:00", + "type": "commit", + "message": "feat: persist text and video outputs", + "hash": "765744d", + "files_changed": 9 + }, + { + "ts": "2026-05-20T21:27:22+08:00", + "type": "commit", + "message": "auto-save 2026-05-20 21:27 (+1, ~4)", + "hash": "52844b2", + "files_changed": 5 + }, + { + "ts": "2026-05-20T21:29:43+08:00", + "type": "commit", + "message": "fix: archive generated videos locally", + "hash": "5d95e91", + "files_changed": 4 + }, + { + "ts": "2026-05-20T21:38:07+08:00", + "type": "commit", + "message": "fix: make video prompts material adaptive", + "hash": "7106f3a", + "files_changed": 1 } ] } diff --git a/src/lib/packGenerator.ts b/src/lib/packGenerator.ts index 19463eb..6659239 100644 --- a/src/lib/packGenerator.ts +++ b/src/lib/packGenerator.ts @@ -151,6 +151,8 @@ function sortTemplatesByAnchor(); + async function createAsset(template: AssetTemplate): Promise { const assetId = `${opts.kind}_${template.filenamePart}_${randomBytes(3).toString('hex')}`; const anchorAsset = template.anchorTemplateId ? assets.find(asset => asset.templateId === template.anchorTemplateId) @@ -318,7 +322,7 @@ export async function generateAssetPack(opts: { const prompt = renderPrompt(template.promptTemplate, characterSpec, anchorImageUrl); const preFilledSlot = opts.session.preFilledSlots?.find(slot => slot.templateId === template.id); if (preFilledSlot) { - assets.push({ + return { id: assetId, templateId: template.id, kind: opts.kind, @@ -346,9 +350,7 @@ export async function generateAssetPack(opts: { templateFreezeVersion: TEMPLATE_FREEZE_VERSION, anchorTemplateId: template.anchorTemplateId, }, - }); - await opts.onProgress?.(pack); - continue; + }; } const generated = await generateAssetImage({ packId, @@ -357,7 +359,7 @@ export async function generateAssetPack(opts: { anchorImageUrl, aspectRatio: template.aspectRatio, }); - assets.push({ + return { id: assetId, templateId: template.id, kind: opts.kind, @@ -381,10 +383,31 @@ export async function generateAssetPack(opts: { anchorTemplateId: template.anchorTemplateId, raw: generated.raw, }, - }); - await opts.onProgress?.(pack); + }; } + while (remainingTemplates.length > 0) { + const readyTemplates = remainingTemplates + .filter(template => !template.anchorTemplateId || generatedTemplateIds.has(template.anchorTemplateId)) + .slice(0, PACK_ASSET_CONCURRENCY); + if (!readyTemplates.length) { + throw new Error(`template anchor cycle or missing root: ${remainingTemplates.map(template => template.id).join(', ')}`); + } + + for (const template of readyTemplates) { + remainingTemplates.splice(remainingTemplates.indexOf(template), 1); + } + + await Promise.all(readyTemplates.map(async template => { + const asset = await createAsset(template); + assets.push(asset); + generatedTemplateIds.add(template.id); + await opts.onProgress?.(pack); + })); + } + + const templateOrder = new Map(templates.map((template, index) => [template.id, index])); + assets.sort((a, b) => (templateOrder.get(a.templateId) ?? 0) - (templateOrder.get(b.templateId) ?? 0)); pack.status = 'complete'; const manifest: ExportManifest = {