From 7efebb4a8c267637a4da73a87ddb2a8af745c9d9 Mon Sep 17 00:00:00 2001 From: archipelago Date: Mon, 22 Jun 2026 16:45:26 -0400 Subject: [PATCH] feat(demo): per-folder media merge + AIUI seed-chats bootstrap - Curated files loader now MERGES per top-level folder: dropping real files into demo/files/Music/ swaps only Music and keeps the sample Documents/Photos/Videos (verified). Media plays with the Range support already in place. - AIUI index.html: a ?seed bootstrap pre-loads the example "Content Showcase" conversation into AIUI's IndexedDB by calling the bundle's own seedPromptsToConversation() (identical to its /seed command), so the chat history isn't empty when the demo points users to "previous chats". Guarded by try/catch + an existence check; no-op without ?seed. Co-Authored-By: Claude Opus 4.8 (1M context) --- demo/aiui/index.html | 25 +++++++++++++++++++++++++ neode-ui/mock-backend.js | 18 ++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/demo/aiui/index.html b/demo/aiui/index.html index bb1a78b2..241e7854 100644 --- a/demo/aiui/index.html +++ b/demo/aiui/index.html @@ -14,6 +14,31 @@ AIUI + + diff --git a/neode-ui/mock-backend.js b/neode-ui/mock-backend.js index a71b7301..2831631a 100755 --- a/neode-ui/mock-backend.js +++ b/neode-ui/mock-backend.js @@ -3626,11 +3626,21 @@ function loadDemoDiskFiles() { } walk(root, '/') if (!tree['/'].length) return // empty folder → keep the hardcoded seeds - for (const k of Object.keys(SEED_FILES)) delete SEED_FILES[k] - Object.assign(SEED_FILES, tree) - for (const k of Object.keys(SEED_FILE_CONTENTS)) delete SEED_FILE_CONTENTS[k] + // Per-folder MERGE: a top-level folder present in demo/files replaces that + // seed folder; seed folders the curator didn't provide (e.g. sample Documents) + // are kept. So dropping real Music/ doesn't wipe the sample Documents. + const provided = new Set(tree['/'].map(e => e.name)) + for (const k of Object.keys(SEED_FILES)) { + if (k !== '/' && provided.has(k.split('/')[1])) delete SEED_FILES[k] + } + for (const k of Object.keys(SEED_FILE_CONTENTS)) { + if (provided.has(k.split('/')[1])) delete SEED_FILE_CONTENTS[k] + } + const keptRoot = (SEED_FILES['/'] || []).filter(e => !provided.has(e.name)) + for (const [k, v] of Object.entries(tree)) { if (k !== '/') SEED_FILES[k] = v } + SEED_FILES['/'] = [...keptRoot, ...tree['/']] Object.assign(SEED_FILE_CONTENTS, contents) - console.log(`[Demo] Loaded curated files from demo/files (${Object.keys(diskFilePaths).length} binary, ${Object.keys(contents).length} text)`) + console.log(`[Demo] Merged curated files from demo/files (${Object.keys(diskFilePaths).length} binary, ${Object.keys(contents).length} text; folders: ${[...provided].join(', ')})`) } loadDemoDiskFiles()