Repository navigation
fix(plugins): deliver browser exports from the downloads folder - #21
Conversation
The published export skills still told agents to return a cloud downloadUrl and said Codex could not ask the editor to export, so agents picked cloud rendering for files the browser had already rendered. A completed browser export is only delivered once the file is found on disk: Chrome holds the second automatic download until the user allows multiple downloads, and the Claude Browser pane waits on a save dialog. - Codex and Claude export: render locally by default, find the file by expectedFilename (or the entry name) in the downloads folder, ask the user for the one browser-specific step when it is missing, then cloud with the user's agreement, and ChatCut Desktop only when cloud cannot. - Basics: drop the download-URL requirement and the claim that the editor cannot export. - Known errors (all hosts): a failed local export is not by itself a reason to switch to cloud. - Verification: self-check with preview_timeline, audio, or a local 480p range instead of a full-resolution export. - Send x-chatcut-plugin-version from every host so export behavior can be compared across plugin releases; bump Codex 1.10.18, Claude 1.10.20, Grok 1.10.17, Kimi 1.10.17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@leowio 麻烦帮忙 review 一下这个 PR,补充说明它解决什么问题、预期收益多少。 解决的问题 已发布插件的导出 skill 还是旧写法,和服务端已上线的规则(#4998 等,10/21 12:43 上线)矛盾:
浏览器本地导出没有链接,agent 照旧 skill 做就只能改走云。这个 PR 把插件说法和服务端对齐:本地导出后按文件名在下载目录确认文件真的在了才算交付,找不到就按浏览器请用户补一步,用户做不到才在同意后走云。顺带三件事:自检不再导出全片;下载被浏览器拦住时如实告诉用户,不再说“已触发下载”;请求带上 为什么现在需要 服务端改动上线后的监控(最近 24 小时,剔除批量号):云渲染分钟比上周同时段少约 42%。但两个客户端差别很大:
今天上午 Claude Code 的选云比例回升,主要来自 3 个高频用户(几小时内各导出 60–80 次),全部是旧版插件(请求不带版本号)。旧 Claude skill 要求“下载到本地路径”,正是这个 PR 改掉的地方。 预期收益(推算) 如果 Claude Code 的选云比例降到接近 Codex 的水平,它的云渲染分钟约少一半到三分之二,也就是每周约 2.5–3.5k 分钟,约 $0.3–0.7k/周,相当于目前剩余云渲染的 10–15%。Codex 侧服务端规则已经起作用,增量较小。实际效果要等用户升级插件后,按 验证:生产上用隔离 Codex 对比新旧插件 13 轮,新版在 Chrome 挂起第二次下载时引导用户点“允许”、找到文件后交付,旧版会假交付;兜底链路先征得同意才走云。仓库测试 82/82。详情见 PR 描述。 |
Problem
Hosted MCP agents send a large share of ChatCut exports to cloud (Lambda) rendering, even though a connected editor tab can render them locally. The published plugin skills push them there:
exporttold agents to "return itsdownloadUrl", and in Claude Code to download that URL to a local path. A browser export has no URL, so the only way to follow the skill was cloud rendering.known-errorsdescribed export failures in cloud-render terms.A browser export reaching "complete" also does not mean the file is on disk. On production Chrome holds the second and later automatic downloads until the user allows "Download multiple files". The Claude desktop Browser pane opens a save dialog for every export. In both cases the server and the editor still report the file as downloaded.
The monorepo's 10/11 local-delivery rewrite (
9e97ab445b) never reached this repository, andplugins/has since been removed from the monorepo, so the published skills must be fixed here.Approach
A browser export is delivered when the agent finds the file on disk, not when the job completes. Order:
renderMode).expectedFilenamefrom the server.track_exportentry'sname, taking the newest match modified after submission.(1)suffix.deliveryGuidancewhen present.renderMode:"cloud"and deliver itsdownloadUrl. Cloud is never offered before the user has had that chance, and never used just to get a link or for a self-check.Self-checks use
preview_timeline, aformat:"audio"export, or a local 480p range, never a full-resolution export.Changes
skills/export,skills/chatcut-plugin-basics,skills/known-errors,skills/verification,.mcp.json,.codex-plugin/plugin.jsonchatcut-plugin-basics-claude),.claude-plugin/plugin.json,README.mdskills/known-errors,mcp.json,.cursor-plugin/plugin.jsonskills/known-errors,.mcp.json,kimi.plugin.json,README.mdchatcut-export-guideis unchanged, as the Kimi README requires. Version header in both MCP definitions. Version bump.tests/export-delivery.test.mjs,tests/plugin-version-header.test.mjsVersions and header
x-chatcut-plugin-version: 1.10.18(http_headers)x-chatcut-plugin-version: 1.10.20(headers)x-chatcut-plugin-version: 1.10.17(headers)x-chatcut-plugin-version: 1.10.17(.mcp.jsonandkimi.plugin.json)Existing
x-chatcut-mcp-surfaceandx-chatcut-mcp-clientheaders are kept. The backend telemetry change records this header aschatcut_plugin_versiononexternal_mcp_tool_call, so cloud-render share can be compared between old and new plugin users.Expected impact
Together with the server-side wording change, the projected reduction is about 15–30% of weekly cloud render minutes. This is an estimate from the source mix of the 10/13–19 baseline, not a measurement. The plugin part only takes effect as users update, and the version header is what will measure it.
Verification
node --test tests/*.test.mjs: 82/82 pass.claude plugin validate ./claudeandclaude plugin validate .(marketplace): pass.CODEX_HOME/CLAUDE_CONFIG_DIR:x-chatcut-mcp-surface: codexandx-chatcut-plugin-version: 1.10.18on every request, including OAuth discovery.x-chatcut-mcp-client,x-chatcut-mcp-surface, andx-chatcut-plugin-version: 1.10.20.Production, real path: new 1.10.18 vs old 1.10.17
Setup:
codex execwith an isolatedCODEX_HOMEand each plugin installed from a local marketplace; productionapi.chatcut.io; an internal test project; first 5 seconds (frames 0–150), 1080p. The editor ran in a fresh-profile Chrome 155, driven only through the debugging protocol, and the owner signed in themselves.~/Downloads/<name>.mp4by exact name, delivers the path; file is 5.08 s H.264/AAC with the size matchingtrack_exportAcross these 10 turns neither version chose cloud on its own. The production error text already says not to retry in the cloud, so the plugin's visible difference here is honest delivery when the download is held. Claude Code, where the old skill demanded a local download of a URL, could not be run end-to-end in this environment.
Fallback chain (final text, no editor available)
renderMode:"cloud", 5 s 1080p, done in 16.5 s, deliversdownloadUrl(the only cloud render in testing)An earlier draft offered cloud in the same message as the first "open the editor" request. The final text adds "Do not offer cloud before the user has had that chance", and the re-run confirmed it.
Found on production, outside this PR
track_exportlooked up by the short render ID thatsubmit_exportreturns always reports a browser-compute export asunavailablesince the 10/20 production deploy; fix in ChatCut-Inc/chatcut#4994.track_exportbriefly reported a just-completed browser export asunavailable("every connected editor tab answered without it"). It read correctly a few minutes later, and the tab had not reloaded.track_exportwithtimelineIdreturned no entries even though the browser entries had thattimelineId.No compatible browser executor has capacity.without the "open the editor with get_editor_url" guidance. The new skill still leads the agent to ask the user to open the editor.Not covered
expectedFilenameanddeliveryGuidance, which are not on production yet. Testing used thenamefallback.(1)duplicate-name case.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.