
这是什么
一个开源、本地优先的视频剪辑器,剪辑的入口是对话。agent 读工程、再通过界面自己用的那套命令层去改它,所以每一处编辑都落在一条专业多轨时间线上,是片段、转场、字幕、特效或音频条目,仍然可拖、可撤销、可存版本、可导出。内置 agent 跑在你自己填的 API Key 上,或者通过厂商自家的命令行工具跑在你已有的 ChatGPT、Claude、Copilot、Grok 订阅上;外部的 Codex、Claude Code、Qoder 与千问办公客户端通过本机 Streamable HTTP MCP 端点接到同一批工具,走的是先审阅、再落到真实时间线的草稿会话。工程、聊天记录、版本与素材都在用户数据目录下的存储里,云端只有可选的 Cloudflare R2 桶用于纯云端素材。预览与无头渲染都走 Remotion,导出背后是 FFmpeg 与一条 WebGL 特效管线,本机 H.264 编码优先用 macOS 的 VideoToolbox 与 Windows 的 NVENC,都不行才落回软件编码。TypeScript、React、Electron,AGPL。
谁做的几乎由一个人写完:仓库 1,029 次提交里有 827 次来自同一个账号,第二大贡献者 73 次,另有二十四人的提交都只有个位数。103 次提交带共同作者尾注,其中最大的一群——45 次——署名 Claude Opus 5.5,Cursor 与 Copilot 各出现七次。
它是怎么搭起来的
组成 · 6一个 React 编辑器和一套 agent 运行时共用一个命令层,分布在三个进程里,而这三个进程也可能就是同一个。时间线是不可变状态加一层命令层,既独立于界面、也独立于任何模型;agent 在这批命令之上组装工具,于是内置 agent、外部 MCP 客户端和命令行做的是同一批操作,而被否掉的提案可以在没碰过真实工程的情况下丢掉。local-first 是照字面做的:工程、聊天、版本与素材都在用户数据目录下的存储里,IndexedDB 是浏览器侧缓存并带迁移路径,素材目录是一个设置项,默认架构里唯一的云存储是可选项。预览和无头渲染是同一批 Remotion 合成,这也是为什么导出相关的工作里有那么大一部分是在让浏览器引擎、本机渲染器和 FFmpeg 编码器显示同一批帧。验证是架构的一部分而不是它之后的一道工序:2,772 个文件里有 640 个是检查,另有一个脚本只跑被改动影响到的那些;而 pull request 的验证,是在项目已经发了十四个版本之后才接上的。
- src/agent/
- 代码量最大的一块,503 个文件、约 3.2 MB:组装、工具定义、技能、进度与设置。
src/agent/skills/下 30 个技能目录共 85 个文件,从一份 62 KB 的口播指南到只做路由的短技能;生成出来的工具目录assets/agent/openchatcut-tool-schemas.json自己就有 266 KB。 - src/editor/
- 124 个文件,装着 README 所说「独立于 UI 与 LLM」的那条时间线:23 KB 的命令构造器,片段、轨道、工程与文字稿四组 reducer,以及关键帧、滑移、波纹、磁吸、序列图、多机位切换与时间码。agent 能要求的每一个操作,都先在这里存在。
- server/plugins/、server/agent-runs/ 与 server/external-agent/
- 服务端,分别 183、42、56 个文件:生成、转写、素材探测、导出规划与存储;服务端自己的模型循环,连同运行存储、事件窗口与工具策略;以及 MCP 桥、编辑会话归属,和那个让外部 agent 在应用关着时也能干活的离线运行时。
- remotion/、src/export/ 与 src/gl/
- 渲染与画面管线,分别 15、71、164 个文件。Remotion 那边是渲染入口、一份渲染契约、两个视频解码器和导出并发的基准;导出那边负责素材规划、成片质检与任务恢复;GL 那边装着特效与转场,每个 shader 都是一个
.frag文件配一个生成出来的模块。 - desktop/、cli/ 与 config/
- 打包与自动化层,分别 88、13、5 个文件:Electron 主进程连同它内嵌的服务与原生推理 worker,用 esbuild 构建的
occ命令行,以及产出网页端、AppImage、NSIS 与两个 macOS 目标的那套 Vite 与 electron-builder 配置。 - assets/ 与 src/i18n/
- 不是代码的那部分重量:115 个字体文件 21 MB、236 张缩略图、39 个音效、35 条人声样本、两个 LUT,以及 13 MB 随包分发的模型文件。旁边是四种界面语言,其中俄语词典本身就是单独一个 246 KB 的模块。
取舍,以及它替代了什么
编辑器、内置 agent 与所有外部客户端共用同一层剪辑命令 替代 给 agent 单独一套工程格式或第二套编辑 API
README 里写明了:外部 agent 调用的就是编辑器自己的内部剪辑工具与
EditorCore命令,不存在会彼此跑偏的第二套工程格式,而且外部草稿准备期间真实时间线不会被改动。也正是这条边界让 agent 的编辑天然可撤销、可审阅。预览和最终渲染共用 Remotion 合成 替代 看到的用一个渲染器、拿到的用另一个
README 把 Remotion 列为预览、合成与服务端渲染的核心基础,而这个项目为这个选择付的账是拿两个解码器互相校验:一个跑在 macOS 上的 CI 任务断言服务端的两个视频解码器显示的帧与播放器一致。当 Chrome 的解码器在 Windows 上出问题时,它的答案是把这个平台挪到 Remotion 的 FFmpeg 合成器上,而不是再补第三条路。
服务端拥有 agent 循环,编辑器留住时间线 替代 让服务端自己直接改工程
服务端执行先是 0.2.1 的可选项,到 0.2.2 变成唯一路径——这个反转很快,而它之所以能安全地做,是因为边界还在:编辑器仍然把每一处改动当作普通的可撤销命令来应用,外部会话绑定到工程与编辑器版本,并且只暴露对草稿安全的工具,因为被否掉的提案没法把一次生成或一次导出回滚掉。
工程 schema 只做加法,不做破坏性变更 替代 直接升版本号、把一切向前迁移
0.2.0 加入的内容寻址素材身份被留在公开的 v3 schema 里,好让 v0.1.9 仍能读新版保存的工程;周围那几个存储也一并改成保留自己解析不了的记录,而不是在下次写入时把它们丢掉。
不设工具轮次上限,改用一批有名字的保护机制 替代 每轮固定一个工具调用上限
changelog 里写着循环不再限制工具轮次、由模型自行决定任务何时结束,顶替上限的是一串机制:重试、只读并行而写操作走独占屏障、按压力压缩上下文、恢复闭合事件与滚动事件窗口。issue #186 则证明旧上限确实存在且暴露得很糟:一次运行正好停在 100 条被接受的工具请求上,报出来的却是 404 而不是上限。
依据README.md(31,696 字符)及其架构表、目录表与技术基础清单,从 0.1.0 读到 0.2.15 的 CHANGELOG.md(951 行、149 KB),package.json,.github/workflows/ci.yml,src/agent/skills/NOTICE.md,skills/openchatcut/SKILL.md,以及 recon 报告的两层目录汇总与完整的 2,772 个文件树及体积。
制作过程
6 个阶段- 01
十周、一千次提交与二十六个版本
仓库创建于 2026-07-15,第一次提交是 2026-07-20,第 1,029 次提交落在 2026-09-30。共 1,029 次提交,光八月就有 676 次,九月 229 次,而七月剩下的那十天只有 124 次。中英双语的 changelog 记下了二十六个版本,从 2026-07-20 的
0.1.0到 2026-09-28 的0.2.15;已发布的 release 列表里能看到其中二十个,v0.1.6到v0.2.15,其中 2026-08-17 前后三天连发五个。对十周来说这是一个很大的程序:2,772 个文件、156 个目录、约 119 MB,而其中有 640 个文件是以检查命名的,不是功能。周围是 2,061 个星、314 个 fork、8 个 watcher 与 16 个未关的 issue。贡献者列了二十六人;虽然 1,029 次提交里有 1,016 次能对到关联账号,形状仍然是一个人:账号本人 827 次,第二人 73 次,另有二十四人各只有个位数。103 次提交带共同作者尾注,最大的一群是 45 次署名 Claude Opus 5.5 的,Cursor 与 Copilot 各七次。 - 02
渲染路径:两个引擎都发了,以及这件事的账单
最难的选择都发生在导出,而它们是被「两边都做」解决的。0.1.2 一次性加了基于 WebCodecs 的浏览器导出(带实时进度与取消,不兼容时自动回退到服务端渲染),加了硬件感知的本机 H.264——先去探测 FFmpeg 在 macOS 上有没有 VideoToolbox、在 Windows 上有没有 NVENC,都没有就用软件编码;同一个版本还让 Remotion 的渲染并发量看 CPU 与内存,给重型导出加了一条可配置的全局队列,并在播放前先把可变帧率素材归一化。代价全写在后来的修复里。Windows 上的本机渲染现在改用 Remotion 的 FFmpeg 合成器解码,不再用 Chrome 的 WebCodecs——后者的 D3D11 硬件解码器可能一声不响地停止出帧,让导出卡在 10% 左右直到超时;macOS 与 Linux 保留原来的解码方式,排查时可以用
CC_RENDER_VIDEO_DECODER=webcodecs|offthread手动指定。GLSL 转场导出的是几帧之前的画面,因为每路输入都在自己的视频跳转完成前就被画了出来;现在两路都取自导出自身的解码器。浏览器快导沿用了 Remotion 的单帧 30 秒默认值,而本机渲染器允许的宽得多,于是同一个工程可能在一个引擎失败、在另一个引擎正常;现在两条路径共用 10 分钟的单帧预算。4K 的自动硬件码率此前停在 30 Mbps,而导出对话框承诺 60,现在按 4K30 给 40 Mbps、4K60 给 60 Mbps。 - 03
时间线几何只算一遍,工程格式拒绝把旧版本扔下
时间线是另一处必须被决定、而不能靠长出来的架构。0.1.8 把它统一到感知播放速度的源时间与源窗口计算上,并让移动、重定时、切分、裁剪、波纹与覆盖共用同一遍转场校正——这也是为什么同一个版本能一次加上滑移与比率拉伸模式、插入与覆盖落轨、嵌套序列、源时间码与同步锁定组。0.2.0 加了内容寻址的素材身份:一条流式 SHA-256 贯穿浏览器、分片上传、Agent 与桌面导入四条链路,并且刻意把新元数据留在公开的 v3 工程 schema 里,好让 v0.1.9 仍能读新版保存的工程。这个承诺在反方向也成立:版本历史、导出历史、模板与任务注册表在回写时会保留本版解析不了的记录,而不是丢掉;本版读不懂的工程不再被下一次保存覆盖;只被某个更新格式的快照引用的素材会被保护起来、不被清理。缺陷是同一个故事的倒放:滑移编辑即使面对带显式素材 id 的片段也按 URL 去找源时长,于是同一个 URL 在素材池里有两份条目时,600 帧的源被按第一份 300 帧条目钳制,本该是 540 的入点变成了 240。
- 04
把 agent 循环搬到服务端,编辑器留下了什么
0.2.1 把 agent 循环的服务端执行做成可选;同一天发布的 0.2.2 把它变成唯一路径,并移除了浏览器端的模型循环,聊天、草稿、结算与提案都通过一条单写者账本存在服务端,能跨页面刷新与本机服务重启恢复。这在结构上就是一个「权柄分裂」问题,而代码的答案是拒绝把时间线交给服务端:服务端拥有模型循环,编辑器仍然通过人类编辑用的同一批经过校验、可撤销的
EditorCore命令去执行每一处改动,外部 MCP 会话则绑定到工程版本与编辑器版本,让过期草稿赢不了。同一个版本还取消了工具轮次上限,由模型自己判断什么时候做完,并用一串机制保护长运行:瞬时厂商错误重试、只读工具并行执行而写工具走独占屏障、按压力触发的上下文压缩、被中断工具调用的恢复闭合事件,以及滚动事件窗口。issue #186 说明了固定上限的代价:一次长运行正好攒到 100 条被接受的工具请求(84 条放行、16 条拒绝),最后报出的却是一个误导性的 HTTP 404 而不是上限提示;修法是取消上限,并把它之后马上会撞到的另外两道天花板一起抬高。 - 05
issue 区被当成开发日志用
这个仓库的 issue 区读起来像日志,因为维护者会在里面回话。2026-09-28,一位用 Linux 源码部署的 reporter 连开六个编号 issue:锁定的
onnxruntime-nodeCUDA 安装脚本让npm ci失败;用普通 HTTP 打开时编辑器一片空白并报crypto.randomUUID is not a function;激活另一帧率的序列后素材池时长会变;本机素材浏览其实是桌面端专有;以及工具调用上限。回复里会点名原因、也会交代修到哪一步:404 那条第二天就答了,因为有了 store 层的复现,定位很快;浏览那条没有被敷衍地关掉,而是把理由写明——要在网页版编辑器里开放它,需要一个显式的服务端根目录白名单,因为AGENT_IMPORT_ROOTS为空就等于不受限,而且它不在这版 v0.2.15 里。一位新用户遇到厂商把工具调用的类型流成空值,作者照着他贴出的响应体在当天就把修复放上main,并把 issue 留到发版再关。除了 bug 报告,贡献者还带来了整块集成:GitHub Copilot 与 Claude Code 两个 Agent 后端,Requesty、OFox、Fal.ai 三个厂商,三个混剪工作流,以及 Qoder 的一键 MCP 接入。有一个厂商接入的 pull request 被拒了,理由是商业而不是技术:把厂商网关加成内置预设属于商业合作位,这类事按合作谈。 - 06
作者亲手写下的、没做成的事
这个仓库值得读,是因为它把失败留在了记录里。持续集成文件在自己的注释里写着这段历史:直到 2026-08-31 才把 pull request 纳入检查,而后果很快就出现了——有一个 pull request 一直挂着构建失败,却没有任何东西告诉它的作者;所以那条注释现在写着,一个构建不过的 pull request,必须在 pull request 上说出来。后来一个 pull request 的正文承认,本机完整构建在准备原生 Whisper 时被本地编译器与 SDK 的组合挡住了,完整构建交给 CI 去验。另一个做性能基准的 pull request 报告:在 16 核 M4 Max 上,四个 worker 渲染两个短的 4K60 用例,比预热后的自动 13 worker 基线快约 26–28%;它不改任何运行时默认值,并且明说还需要在更长时间线、更复杂的合成和别的 Mac 上继续测,才能谈要不要改成自动策略。0.2.13 的变更记录里写着一次只在 Windows 出现的崩溃,它之所以逃过验证,恰恰因为那段恢复逻辑是按平台门禁、只在 Windows 生效;0.2.12 的记录则写着 Windows 本地转写此前从未真正运行过——打包把可执行文件和它的动态库分开放了,于是任何模型档位都直接以一个裸退出码死掉。
相关档案
全部档案 →第 061 号
Reticle
一个 MCP 服务器加一个只在开发期生效的 SDK:让编码 agent 从应用内部去读、去操作一个正在运行的 web 或桌面应用,然后给出判词和该改的文件与行号,而不是一张截图。
第 077 号
Lody
一个让团队共用他们本来就在跑的编码 agent 的工作台:连上一台机器,把 Claude Code、Codex、Kimi 或任何其他说同一套协议的 agent 接进来,然后从桌面端、手机、网页或终端派活;会话之间可以互相派活,而代码始终留在机器主人自己连上来的那台机器上。
第 073 号
Zeron
一个 Rust 桌面程序,把你在用的编码 agent——Claude Code、Codex、Cursor、Devin、Grok、Hermes、Pi、Antigravity——装进同一个控制台,默认只在本机跑、不需要账号;只有你主动登录,它才会把这些会话同步到你其它的设备上。