2026-05-13 · 新增独立源码解析与协作地图
+ docs +目的:把产品功能区、源码位置、接口、数据模型、需求描述方式固定下来,减少“描述不准导致改偏”。
+影响:新增 docs/source-analysis.html,不接入 Next 应用,不影响工作台运行。
以后描述:可以直接引用本页的功能区名称、节点职责和源码文件名。
+diff --git a/.memory/worklog.json b/.memory/worklog.json index a7e49b3..dddc022 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -2142,6 +2142,19 @@ "type": "session-heartbeat", "message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-13 18:46 (~1)", "files_changed": 1 + }, + { + "ts": "2026-05-13T18:52:04+08:00", + "type": "commit", + "message": "auto-save 2026-05-13 18:51 (~1)", + "hash": "417cbe1", + "files_changed": 1 + }, + { + "ts": "2026-05-13T10:59:29Z", + "type": "session-heartbeat", + "message": "Codex 会话活跃 · 最近命令:codex · 3 项未提交变更 · 最近提交:auto-save 2026-05-13 18:51 (~1)", + "files_changed": 3 } ] } diff --git a/AGENTS.md b/AGENTS.md index e9eaebd..959b6cd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,3 +19,11 @@ - 部署完成后,不允许在 `.project.json` 缺少最新公网链接的状态下结束任务 - 部署完成后,必须同步更新 `RULES.md` 的部署事实 - 如果只更新了代码但没回写部署元数据,这个任务不算完成 + +## Source Analysis Contract + +- 项目内源码解析页固定为 `docs/source-analysis.html` +- 该页面用于帮助用户把产品需求准确描述到源码位置:功能区、节点职责、数据模型、接口、变更影响都要能查到 +- 任何改动只要影响产品理解、节点职责、界面行为、数据模型、API、运行方式或用户操作路径,必须在同一次任务里更新 `docs/source-analysis.html` +- 更新时至少补充“变更记录”,必要时同步更新源码结构地图、界面区域到源码、数据模型、接口地图、节点职责边界 +- 不要把源码解析页接入主应用路由,除非用户明确要求;它默认是项目内独立 HTML 文档 diff --git a/RULES.md b/RULES.md index e3968e3..35dd224 100644 --- a/RULES.md +++ b/RULES.md @@ -40,4 +40,6 @@ - 任何部署或域名变化,都要先改元数据,再视为任务完成 ## 注意事项 -- 待补充 +- 项目内源码解析页:`docs/source-analysis.html` +- 源码解析页是给产品协作和需求描述用的独立 HTML,不接入 Next 应用路由 +- 后续任何功能、节点职责、接口、数据模型或用户操作路径变更,都要同步更新 `docs/source-analysis.html` 的对应章节和变更记录 diff --git a/docs/source-analysis.html b/docs/source-analysis.html new file mode 100644 index 0000000..14c0fda --- /dev/null +++ b/docs/source-analysis.html @@ -0,0 +1,924 @@ + + +
+ + ++ 它把“你看到的界面、你想改的功能、实际要动的源码、可能影响的数据和接口”放在同一个地方。 + 后续描述需求时,可以直接说“改源码地图里的某个区域 / 某个节点职责 / 某个接口行为”,这样改动范围会更准,也更容易追踪每次变更带来的影响。 +
+ +例如“镜头拆解 / 元素提取面板”、“元素改造 Storyboard 节点”、“分镜头编排工作台 4 图槽”。不要只说“这里乱”,要指向页面里的功能区。
+例如“Vision 只给候选元素,用户必须能编辑、删除、重新提取”,这会直接落到 FrameLightbox 和元素接口。
例如“点击元素不要跳页面”、“不要直接进入编排打断思路”、“不要把参考视频复刻成一样的东西”。这能约束交互和文案。
+建议表达格式:我要改「功能区」;当前问题是「行为」;正确职责是「业务目的」;不要影响「已有流程」。
+| 项目 | 命令 / 入口 | 说明 |
|---|---|---|
| 前端开发服务 | +cd web && pnpm dev |
+ Next.js App Router,主页面是 web/app/page.tsx,默认端口 4290。 |
+
| 后端开发服务 | +cd api && source .venv/bin/activate && uvicorn main:app --port 4291 --reload |
+ FastAPI,所有任务状态、视频、关键帧、清洗、元素、分镜保存都在 api/main.py。 |
+
| 测试页面 | +http://localhost:4290/?job=c6767f3a166b |
+ URL 里可放多个 job id:?job=id1,id2,id3,前端会恢复多个任务并激活最后一个。 |
+
| 源码解析页 | +open docs/source-analysis.html |
+ 独立静态 HTML,不被 Next 构建、不影响产品工作台。 | +
当前产品不是“复制别人的视频”,而是拆解参考视频,提取可借鉴的镜头元素,再改造成 SKG 产品语境的视频素材。
+TK 链接或本地上传,后端下载/保存源视频。
拆轨、抽关键帧、手动加帧,形成参考分镜池。
对关键帧做全图或区域清洗,必要时应用为当前参考图。
识别场景和候选元素,只是候选,不应锁死。
编辑/新增/删除元素,对元素反复生成提取图。
把参考主体、场景、动作和 SKG 产品放入分镜结构。
用分镜结构生成首帧和视频片段。当前未实现。
片段、字幕、配音、转场合成最终 mp4。当前未实现。
web/app/page.tsx | 产品工作台主状态:jobs、activeJobId、selectedFrames、clipboard、ReactFlow 节点和边。 |
web/components/nodes/index.tsx | DAG 节点定义:Input、Keyframe、ASR、Translate、Rewrite、Storyboard、VideoGen、Compose。 |
web/components/lightbox.tsx | 镜头拆解和元素提取的主工作面板:清洗、识别、元素编辑、区域提取、抠图。 |
web/components/storyboard-bar.tsx | 顶部已选分镜条:展示选入编排的关键帧,点击进入工作台。 |
web/components/storyboard-workbench.tsx | 全屏分镜编排工作台:4 图槽、改造目标、时长、自动保存。 |
web/lib/api.ts | 前端类型和 API client,是前后端数据契约镜像。 |
api/main.py | FastAPI 单文件后端:状态模型、任务恢复、下载、抽帧、Vision、清洗、元素、分镜、文件返回。 |
jobs/<jobId>/state.json | 运行时状态文件,不在源码列表里,但刷新恢复依赖它。 |
jobs/<jobId>/frames | 关键帧 jpg。注意 frame.index 是稳定 ID,不等于数组下标。 |
jobs/<jobId>/cleaned | 清洗后待应用图片。 |
jobs/<jobId>/elements | 元素提取图,多版本命名:idx_elementId_cutoutId.jpg。 |
jobs/<jobId>/gen | 关键帧生图结果。 |
前端主链路: +web/app/page.tsx + -> ReactFlow 节点:web/components/nodes/index.tsx + -> 镜头拆解面板:web/components/lightbox.tsx + -> 顶部分镜条:web/components/storyboard-bar.tsx + -> 分镜工作台:web/components/storyboard-workbench.tsx + -> API 契约:web/lib/api.ts + +后端主链路: +api/main.py + -> Job / KeyFrame / KeyElement / StoryboardScene + -> 下载 / 上传 / 抽帧 / Vision / 清洗 / 元素提取 / 分镜保存 + -> jobs/<jobId>/state.json + 图片文件落盘+
InputNode in web/components/nodes/index.tsx;状态处理在 page.tsx。KeyframeNode 和 FrameLightbox;后端 /frames、/describe、/cleanup。FrameLightbox;类型 KeyElement;接口 addElement/updateElement/deleteElement/cutoutElement/deleteCutout。StoryboardNode;上方元素缩略图来自所有已提取 cutouts。StoryboardBar;只展示 selectedFrames,不负责提取元素。StoryboardWorkbench;保存到 frame.storyboard;接口 PUT /storyboard。一个视频任务。前端维护多个 jobs[],当前激活的是 activeJobId。URL 查询参数会持久化多个 job。
Job {
+ id, url, status, progress, message,
+ video_url, duration, width, height,
+ frames: KeyFrame[],
+ transcript: TranscriptSegment[],
+ storyboard_images?: StoryboardImage[]
+}
+ 关键帧是整个产品的核心单位。index 是稳定 ID,手动加帧后不连续,不能用数组下标代替。
KeyFrame {
+ index, timestamp, url,
+ description,
+ cleaned_url, cleaned_applied,
+ elements: KeyElement[],
+ storyboard: StoryboardScene,
+ generated_images: GeneratedImage[]
+}
+ 从关键帧里识别或手动添加的可借鉴元素。Vision 给的是候选,用户可编辑,并可多次生成提取图。
+KeyElement {
+ id,
+ name_zh, name_en, position,
+ source: auto | manual | region,
+ region,
+ cutouts: string[],
+ cutout_id
+}
+ 分镜编排结果,不是复刻说明。它把参考图和 SKG 改造方向绑定到一个分镜上。
+StoryboardScene {
+ duration,
+ subject_image,
+ scene_image,
+ product_image,
+ action_image,
+ subject,
+ product,
+ scene,
+ action
+}
+ | 功能 | 接口 | 前端调用 | 说明 |
|---|---|---|---|
| 创建任务 | POST /jobs | createJob | 提交 TK 链接,后台开始下载,停在 downloaded 等用户点解析。 |
| 上传视频 | POST /jobs/upload | uploadJob | 保存 source.mp4,然后同样进入下载完成状态。 |
| 解析视频 | POST /jobs/{id}/analyze | analyzeJob | 拆轨 + 抽关键帧。当前不自动跑 ASR,避免 audio 阻塞视觉管线。 |
| 手动加帧 | POST /jobs/{id}/frames?t= | addManualFrame | 按视频时间戳抽一帧,index 递增但 frames 按 timestamp 排序。 |
| Vision 识别 | POST /frames/{idx}/describe | describeFrame | 写入 frame.description,后续可从 objects 加候选元素。 |
| 清洗水印 | POST /frames/{idx}/cleanup | cleanupFrame | 支持全图和区域清洗,生成 cleaned 待应用版本。 |
| 应用清洗 | POST /cleanup/apply | applyCleanedFrame | 物理覆盖 frames/{idx}.jpg,并备份原图。 |
| 元素增改删 | POST/PATCH/DELETE /elements | addElement/updateElement/deleteElement | 让用户修正 Vision 错误,避免候选结果锁死。 |
| 元素提取 | POST /elements/{element_id}/cutout | cutoutElement | 调用图像模型生成独立白底素材图,每次累积一张 cutout。 |
| 分镜保存 | PUT /frames/{idx}/storyboard | updateStoryboard | 保存 4 图槽、时长和改造说明。 |
| 生图 | POST /frames/{idx}/generate | generateImage | 基于关键帧或已选生成图做 image-to-image,目前可用。 |
| 节点 | 当前职责 | 不该承担 | 改动主要文件 |
|---|---|---|---|
| 输入 Input | +创建/上传任务,显示视频就绪,触发解析。 | +不要自动一路跑到 ASR 或生图;用户需要控制解析节奏。 | +page.tsx、InputNode、api/main.py |
+
| 镜头拆解 / 元素提取 | +关键帧选择、清洗、Vision 候选、元素编辑、区域提取、元素 cutout。 | +不要把 Vision 结果当最终结论;不要点击元素就跳走。 | +KeyframeNode、FrameLightbox、元素接口 |
+
| 元素改造 Storyboard | +展示可用元素素材,承接“参考元素 → SKG 画面”的入口。 | +不要等同于最终视频生成;不要暗示复刻原视频。 | +StoryboardNode、StoryboardBar |
+
| 分镜工作台 | +每个分镜填 4 图槽和改造 brief,为后续生成首帧/视频片段做准备。 | +当前不负责真实调用视频模型。 | +StoryboardWorkbench、updateStoryboard |
+
| ASR / Translate / Rewrite | +未来的文案轨,目前部分占位或受 audio 阻塞。 | +不要阻断视觉素材管线。 | +ASRNode、TranslateNode、RewriteNode、ASR 接口 |
+
| Video Gen / Compose | +未来生成视频和合成成品。 | +当前只是占位,不要描述成已打通。 | +VideoGenNode、ComposeNode、未来模型接口 |
+
最重要的产品判断:当前视觉素材管线已经能继续推进,文案/音频/视频生成不要再反过来卡住镜头拆解和元素改造。
+“我在关键帧 lightbox 里,Vision 识别后的元素列表应该怎么编辑/重提取/删除;点击元素不要跳转;提取图怎么预览和复制。”
+“我在 DAG 的元素改造节点,它上方缩略图展示什么、hover 预览什么、点击后是否进入工作台、是否自动选中对应分镜。”
+“我在全屏分镜编排工作台,每个分镜需要哪些槽位、字段如何命名、保存后如何传给后续生成视频。”
+“这个动作需要持久化到 state.json,字段加在 Job/KeyFrame/KeyElement/StoryboardScene 哪一层,刷新后要恢复。”
+“这个节点的业务职责要改,不只是 UI 文案;请同步更新节点标题、subtitle、说明、可点击行为、状态推导和本源码解析页。”
+这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。
+目的:把产品功能区、源码位置、接口、数据模型、需求描述方式固定下来,减少“描述不准导致改偏”。
+影响:新增 docs/source-analysis.html,不接入 Next 应用,不影响工作台运行。
以后描述:可以直接引用本页的功能区名称、节点职责和源码文件名。
+问题:元素改造节点上方小图 hover 没有像镜头拆解节点一样显示原图预览,并且首次修复时出现运行时错误。
+原因:节点内部 overflow 裁剪了预览;随后 portal 预览里把变量写成了不存在的 aspectRatio。
影响:web/components/nodes/index.tsx。现在 hover 展示来源原帧和提取元素,运行时异常已验证为 0。
问题:Vision 识别可能错,但元素列表像最终结果;点击提取图会跳页面,打断用户思路。
+改动:支持元素改名、改英文提示、改位置、删除元素、重复提取、删除单张提取图;提取图不再用链接跳新页。
+影响:FrameLightbox、web/lib/api.ts、PATCH /jobs/{job_id}/frames/{idx}/elements/{element_id}。
问题:从 Storyboard 或顶部分镜条进入编排时,没有明确定位到用户正在看的那一帧。
+改动:工作台接受 focusedFrame,点击缩略图会打开工作台并聚焦对应分镜。
影响:page.tsx、StoryboardBar、StoryboardWorkbench、StoryboardNode。
问题:SKG 网关 audio 不通时,视觉解析也容易被标记失败。
+改动:analyze 主流程强调拆轨和关键帧,声音文案轨独立处理。
影响:api/main.py、page.tsx、节点语义说明。
以后任何改动只要影响产品理解、节点职责、界面行为、数据模型、API、运行方式或用户操作路径,都要同步更新本页的对应章节和“变更记录”。
+| 改动类型 | 必须更新本页哪里 | 原因 |
|---|---|---|
| 节点文案 / 节点功能 | 业务管线、节点职责边界、界面区域到源码、变更记录 | 避免用户按旧节点理解描述需求。 |
| 新增 / 修改接口 | 接口地图、数据模型、变更记录 | 避免前后端契约不清。 |
| 新增数据字段 | 数据模型、源码结构地图、变更记录 | 刷新恢复和 state.json 依赖字段一致。 |
| 改交互路径 | 界面区域到源码、需求描述模板、变更记录 | 用户描述“点击哪里”时必须和真实路径一致。 |
| 修 bug | 变更记录;如果暴露新坑,也更新当前已通与阻塞 | 让后续同类问题能快速定位。 |