CHANGELOG.md
Rama main · réplica de lectura del repositorio original.
# 变更记录
一句话一条,最新在上面。README 里只留最近几条,全部在这儿。
每条对应的代码改动在 [commit 历史](https://github.com/CatCatUncle/openworkbuddy/commits/main)——
提交信息写的是「为什么改」,不是「改了哪个文件」,翻起来比这份清单细得多。
English: [CHANGELOG.en.md](CHANGELOG.en.md)
## 2026
- **11-10** v0.19.3:修复附件名带中文右括号时被截断:「报告(终版).docx」不再在对话里变成打不开的「报告(终版」,本机引擎也能拿到完整路径。
- **11-06** v0.19.2:修复资料库页签同时高亮:打开笔记时,全部文件、推荐等页签不再一起显示选中,一次只选中一个页签。
- **11-06** 评测新增盲评:两轮成果逐题并排,不显示来源,全部选完才揭晓哪轮赢。自进化提案可先带着候选规则跑一轮评测,对比基线后再决定采纳。
- **11-06** 企业后台新增「成员权限」和「存储」:按连接器和技能控制成员能用什么,可打开组织内任务只读分享,查看各账号磁盘占用并设每人配额。连接器接入增加内置检查,没装 toolward 也能发现下载直接执行、读密钥文件、云元数据地址等写法。
- **11-06** 记忆可以挂在项目上:甲客户的口径不再跟到乙客户的任务里,全局记忆照常到处带。自进化把用户下一句的纠正(不对、重做)算作负反馈,不再只靠很少有人点的 👍👎。
- **11-06** 画布新增 `/` 快捷面板(双击空白处也可打开)、图片切宫格、多选批量做视频和批量生成、把一组卡存为工作流再插回;工作流只留提示词、参数和连线,不带素材和结果。图片加载后量出的卡高不再占一步撤销。
- **11-06** 工程线新增工作目录条和改动面板:输入框上方显示文件夹、分支和改动数,面板逐文件看 diff,可放弃单个文件的修改;有源码的文件夹就地读写,跟命令行一致。应用自己调用的 git 改走沙箱并盖掉仓库里能执行命令的配置,防止 agent 借 .git/config 逃出沙箱。
- **11-06** v0.19.1:多人共用时 Linux 成员的命令改走 bubblewrap 系统沙箱,隔离立不起来就拒绝执行,修复拼接路径绕过文件黑名单读取 Key 文件的漏洞(用测试 Key 本地复现,未发现线上事故)。**升级须知**:Linux 多人部署升级前先装 bubblewrap,Docker 镜像已内置,compose 要保留 SYS_ADMIN 等权限,否则成员命令会被拒绝;确需放开写 `security.allow_member_unsandboxed`。升级前已给成员开过账号的,建议更换 Key。macOS、Windows 本来就有系统沙箱。
- **11-06** 资料库上万文件点击即响应:遍历移到后台线程并缓存,切换视图先画已有内容再刷新,接口约 100ms 降到 5ms;内容区不再被限高。多任务按内存排队,重活单独限流,子进程降优先级,排队不计入任务时限,设置页可调并发。
- **11-06** 命令行写代码档:每轮提示词减少 75%(49,635 → 12,643 字),工具 44 → 23,load_tools 按需加载,有源码的目录就地运行,支持 --profile。
- **11-06** 评测集支持 CSV、Excel、TXT、JSON 上传和页面新建;标准可设权重、必须项和扣分项,按 HealthBench 算法得分,人工与评委对账显示一致率和 Cohen's kappa;新增 PPT、Word、Excel 三道办公题。
- **11-06** 内置方舟下线表,下线型号提前告警并从目录隐藏;生图生视频按顺序回退,已下单或被审核拦下的不重发;新增豆包配音、转写和自定义语音接口(按官方文档实现,线上请先自测)。后台新增成员自带模型开关;超管首次创建输两遍密码并提醒保管。
- **11-06** 对话悬停看时间,回复下方改成图标,只留 tokens 数,点赞点踩放到右边;回复可直达执行追踪,追踪能跳回对应回合,显示 TTFT、TPOT、tok/s;侧栏直接列项目,页签不再被挤走,行数随窗口高度变化。写入面向 AI 助手的授权说明 AGENTS.md。
- **11-04** v0.18.4:云端首次接入不再锁死旧型号,支持按账号查询、刷新和手填模型或方舟 ep- 接入点;模型清单按地址、Key、协议隔离,改目的地不会带出已存 Key。修复 Claude/Gemini/Ollama 发现协议、方舟模态识别与异步回包串渠道;更新方舟/DeepSeek 默认型号和方舟媒体候选。404 不再一概断言型号不存在;Seedance 2.x 使用 JSON 参数并校验时长和分辨率。
- **11-03** v0.18.3:整理中间文件与资料库删除改为可恢复回收,桌面版进入系统废纸篓/回收站,服务端保留原字节和恢复记录;回收失败不回退永久删除。不再按 out/dist/build/target 名称清理整目录,依赖缓存默认不勾,运行中任务和后台命令阻止清理;新界面拒绝向旧服务发送删除请求。
- **11-03** 固定宽网页与 Office 预览首次显示自动适配,栏宽变化、隐藏后显示和内容更新后重新测量;保留手动缩放比例,修复混合纸张 OFD 后续宽页裁切,合并尺寸回调并在关闭时释放监听。
- **11-03** 内置 Agent 在执行中定期核对清单,忽略提醒后暂缓新操作,保留读取核验;手动续做恢复成功的未完成清单。进度显示确认时间,区分当前操作,隔离专家清单,清空与历史回放保持真实;未完成清单不再当作正常结束。补充执行架构与 LLMCompiler 的取舍说明。
- **11-01** v0.18.2:删除任务默认清理其专属文件夹,可取消勾选保留成果;桌面版移入系统废纸篓,服务端移入原工作目录 `.trash/tasks/` 并记录原位置。项目根目录、多个任务共享目录、定时任务共用成果目录保留;跨项目历史目录逐一核对,兼顾 CLI 落盘归属与网页内存归属。
- **11-01** 删除前等待任务停止、附件写入和最终保存完成;按确认快照复核目录身份,拒绝链接、替换目录和过期确认。清理失败保留对话并显示原因,部分回收准确告知;成功后清理记录、备份、归档并刷新资料库和旧预览,避免任务被收尾保存重新创建。
- **10-30** Office 预览增加纸张版式、缩放与展开;DOC/WPS、XLS/ET 内置兼容读取,系统“打开方式”保持可选,不修改默认关联。详见[格式能力与限制](docs/文件预览与转换.md)。
- **10-30** Office、PDF、OFD 可转 Markdown;OFD 上传保留后缀和字节;旧 PPT 提取有效文字,扫描页与截断会提示;CEB 需授权引擎。
- **10-30** 资料库预览接管阅读区域,收紧外框,标题和操作分行;关闭旧对话侧栏,取消过期读取,大表按工作表与每页 100 行显示。
- **10-30** 收件箱改按时间倒序,已读和旧错误不再挤掉最新消息;项目点击只切换选中态,快捷顺序保持稳定。CLI 历史独立保留,按启动目录识别项目,支持 --project。
- **10-30** 临时审批按账号和任务隔离,权限卡明确授权范围;目录外附件可导入工作副本,旧成果仅在路径、大小和时间证据一致时恢复读取。
- **10-29** 资料库分组与显示方式改为本地切换,不再重读目录和任务索引;复用文件行、缩略图及预览,并减少屏外内容排版。
- **10-29** 自动化编辑改用大正文面板,长任务按内容增高并在框内滚动,保存按钮始终可见,适配小窗口。
- **10-29** 项目侧栏展示当前及常用的 5 个项目,支持置顶、最近使用和搜索全部项目;完整列表上移到项目标题旁,编辑、移除收进菜单。
- **10-27** 修复无限画布同名图片串图:缩略图、放大图和右侧预览绑定原文件与项目;文件缺失不换图,切项目后忽略迟到素材。
- **10-27** 手机端应用:输入区适配可视高度,设置改横向导航,文件预览铺满屏幕,侧栏选择后自动收起。
- **10-27** 官网适配手机和微信浏览器:导航自动换行,修复标题、卡片和图片拥挤,中英文文档同步优化。
- **10-27** 推荐技能新增软著模板填写与导出、简历教练与求职辅导,按需从作者公开仓库安装。
- **10-27** 项目与自动化搜索保留输入框和光标,确认组词后再筛选,不重复请求列表;迟到的运行记录不再覆盖已切回的任务页。
- **10-26** 修复跨项目执行追踪遗漏、运行中切换目录导致记录拆分、本机引擎工具步骤未入账,以及父子节点用量重复累计。列表读取失败不再显示成空记录,运行中自动刷新;恢复「专家 · 技能 · 连接器」完整入口名称。
- **10-26** 资料库搜索保留原输入框和光标;输入法确认组词后再搜索,旧请求不会覆盖新输入,修复英文输入乱序。
- **10-26** 修复目录迁移后历史成果仍使用旧目录指纹,按同一会话备份核对后恢复链接;助理页支持独立选择 API 或本机引擎,界面与实际执行保持一致,不更改定时任务引擎。本机飞书发送通过专用应用通道访问钥匙串,保留沙箱限制与每轮回执去重,明确未送达的提醒不再显示已完成。
- **10-25** 飞书机器人支持明确配置主动通知接收目标,由应用发送并核对消息回执,不依赖本机引擎读取系统钥匙串。定时任务分别记录执行与通知结果;通知失败不重跑任务,不更新已送达基线,发送结果不明时不自动重发。
- **10-24** 桌面工作台统一在主窗口切换任务,移除会话菜单的新窗口入口;任务链接和预览跳转复用主窗口,保留成果文件独立预览。
- **10-23** 拆除技能、连接器和账号三处循环依赖;工作区上下文统一到独立模块,连接器读取目录不再加载整个工具执行器。技能和插件共用纯解析器,保留技能管理原导出;授权统计由管理路由传入实时计数器,循环依赖例外清零并锁定。补充并发素材隔离、嵌套上下文恢复、独立加载与账号计数回归。
- **10-23** 文本模型编辑和复制在当前总览内打开表单,旧的未挂渠道模型自动展开总览;保留目录迟到时尚未保存的输入。飞书本人身份新增取消连接,确认后通过官方 CLI 清除本机登录态并停止扫码进程树,失败如实显示,不清机器人凭证;服务端授权撤销范围另行说明。定时任务记录本轮飞书发送状态,内置工具与交回应用执行的 CLI 工具收到成功回执后不再换 profile/机器人重复发送,超时或无回执先核对,下一轮独立计数。
- **10-23** 修复 Agent 读取其他安装目录配置后,把不属于当前窗口的型号写进画布:API 与本机引擎都接收当前应用的媒体清单,新增和更新节点校验型号,不匹配整笔拒绝;无效型号可在卡片一键恢复为当前默认模型,切换本身不触发生成。
- **10-23** 修复多张卡同时长高时重复推挤、残留重叠和过量连线更新;统一计算位置,每张卡最多移动一次,保留人工叠放。已有结果的卡片收起编辑器后仍展示失败与待回收任务;等待报价有持续提示,确认期间切项目不启动生成。
- **10-23** 修复画布「开跑」缺少即时反馈和启动异常后无法重试,报价请求有超时反馈;生成失败原因保留在原卡。镜头结果不再自动复制卡片,旧的无引用副本可合并并撤销。视频首尾帧保留原始字节,火山人像审核拒绝显示中文并停止自动重发;支持填写已审核素材 ID,按参考模式发送并明确不混发本地首尾帧。
- **10-22** 修复本机引擎在画布中误报“未配置视频接口”:系统说明和画布读取工具提供准确媒体型号及生成清单路径,只传能力元数据、不传凭据。视频和配音分别判断,保留确认报价后执行的流程。
- **10-22** 补齐角色定妆照与场景图卡片上的设定输入和图像模型选择;显示实际默认型号,显式选择默认可覆盖剧本旧型号,无效或缺失配置在提交前提示。模型设置保存后卡片立即刷新,补充真实浏览器请求与结果写回回归。
- **10-22** 重整通用画布创作入口与卡片交互:卡内提示词、模型、参考和高级参数,已有素材按选择状态收紧;图片可继续做变体或视频,首尾帧分配明确,版本可并排对比,重命名后保留历史。Agent 默认收起,短剧起步只需写剧本。新增整张/选中画布与素材流式导出;同步增量更新、滚轮合帧、输入和批量操作合并保存,补齐真实浏览器与导出安全回归。
- **10-21** 收件箱打开时不再自动标记全部已读,普通任务通知按账号保留最近 300 条,已读后重新打开和刷新页面仍可查看;所有定时结果(含写回原对话的排期)集中显示,支持全部、未读和定时任务筛选及运行记录入口。对话搜索增加可见入口和可点击匹配片段,保留前后定位与早期消息检索,切换对话时清除旧搜索
- **10-21** 修正 Windows 安装验证调用批处理时的重复引号转义;主分支 CI 提前验证真实 cmd.exe、内置运行时、中文/空格路径和启动目录。候选构建未通过检查时保留原标签,使用新版本号重新发布
- **10-20** 文件链接按原项目定位,外部文件按完整路径打开;修复同名串页、部署串目录和切换预览时的迟到覆盖;新增跨项目同名与资源路径回归。发版只复用 24 小时内同一提交的已通过主分支 CI,无可信记录时仍跑全套
- **10-20** 安装版首次启动注册 CLI,使用内置运行时,保留启动目录与桌面数据根;源码目录移动后可用 `npm link` 修复命令。账号菜单独立宽度与滚动,开关不再挤成竖排,无限画布移至自动化下方
- **10-20** 首页收敛为两组十个常用任务,选择类型提示所需素材、不覆盖草稿;任务行常驻置顶按钮,重命名和停止等操作在菜单内
- **10-20** 关闭本机命令行会话导入与组织内只读分享:移除界面入口、停止自动扫描,新建导入与分享接口、旧分享链接均不可用
- **10-20** 精简账号区和对话工具栏;通知已读持久化,批量清除只刷新一次历史;角标接口只请求状态元数据;本轮结束、已停止和未完成分别显示
- **10-20** 内联网页脚本语法检查独立为工具模块,防止生成页面带语法错误;视频成片排他创建与发布,拒绝覆盖已有文件
- **10-20** Windows 安装版支持显式下载与重启安装更新,源码、免安装版和 macOS 保留各自的更新路径;补齐 Windows 文件缩略图
- **10-20** 源码更新提示说明检查更新只查 GitHub 发布版本,不会同步代码;先检查工作区,仅允许快进更新;本地有改动或分叉时保留旧目录,另建源码副本并沿用原数据根,避免误覆盖会话和成果
- **10-19** 修复发版 CI 漏跑 Goal 步数续跑套件的问题;补齐测试文件版权头,并按实际宿主、运行时、安全闸与交付链路重画技术架构图
- **10-19** 架构图改用中英文 SVG,避免 Mermaid 渲染失败和节点文字截断;README 最新动态压到单条 80 字以内
- **10-19** 任务标题旁显示创建日期并提供直接改名入口;成果预览在文件属于当前任务时使用「任务名 · 日期 / 文件名」,底层目录路径保持稳定,旧文件链接不失效。Goal 模式遇到单轮 100 步上限时先检查验收项,再按有限轮次续跑;Codex CLI 沙箱拦截会明确说明不会产生后台审批卡
- **10-19** 网页隔离预览的临时 `localStorage`、`sessionStorage` 上限各提高到 64 MiB,关闭后清除;本地部署使用浏览器原生存储配额,重要数据仍需网页导出备份
- **10-19** HTML 网页预览默认使用完整面板视口,交互画布和页面滚动不再被整页缩放压小;尺寸上报后可手动切换整页适配,SVG 等静态内容保留原有适配方式
- **10-17** CLI 按终端交互:默认单行进度与最终结果,工具输出、diff 和诊断通过 `/details` 或 `--verbose` 查看,用量保留在 `/usage`;空行不再成为插话,本机引擎未消费的补充要求会在同一会话继续执行;成果清单只列本轮改动,打开最近成果由本机程序执行并报告真实结果,保留审批、错误和管道协议
- **10-16** 修复网页预览中小游戏、按钮无反应:在页面脚本之前提供独立的临时存储,避免读取最高分等记录时中断初始化;工作区与资料库预览统一兼容,保留账号和应用数据隔离
- **10-16** 发布检查修正:打包回归样本统一放进临时目录;安装包提供 SHA-256 清单,发布说明从上一正式版汇总,跳过未发布标签;界面回归显式选择语言,覆盖中英文切换
- **10-16** OAuth 第二期:HTTP 连接器在服务商页面授权,令牌自动刷新,可移除本机授权
- **10-16** 预览支持圈选批注,文件改动能逐块回退、撤销,并按行提出修改要求
- **10-16** 团队任务使用组织共享模型和连接器,费用与个人任务分别记录;浏览器录制可生成技能草稿
- **10-16** 英文界面新增漏翻检查,用户原文不翻译;官网提供中英文用户和开发者指南
- **10-16** 新增组织内只读分享:本人生成和撤回,同组织登录成员查看;只展示对话正文和实际交付文件,排除工具参数、配置凭据、越界文件。分享操作在页面内展开,单人模式隐藏
- **10-16** 中英文 README 把首次成功路径提前:安装、连接模型、复制周报任务、打开实际文件并核对。新增故障排查、双向入口参数、试用计时和聚合漏斗模板;未采集指标明确标记缺失
- **10-15** 执行计划改成对话页面内的折叠清单:默认只显示标题和进度,点击原处展开,随对话滚动;进度更新保留展开状态、键盘焦点和文本选择,暂停原因与继续按钮照常可见
- **10-15** 新增任务收件箱,集中显示待审批、待答复、出错、运行中和未读任务;独立定时任务的完成结果也可从这里打开执行过程。定时任务在对话里创建时把结论写回来源对话,独立创建时放进收件箱;来源会话关联留在服务端,接口只返回是否关联
- **10-15** 任务历史按日期分组并显示文件产出标记;行菜单支持改名、移项目、标未读、置顶、删除和新窗口打开,拖动即可置顶;工作区与资料库文件可固定在侧栏
- **10-15** 审批等待时可按 Esc 拒绝、按主修饰键 + Enter 单次放行;增加新建任务和搜索快捷键,以及输入框下方的核对提醒
- **10-15** 任务历史能置顶了:鼠标停在一条任务上点图钉,它就进最上面的「已置顶」一组,后顶的排在上面;再点一下放回去。置顶记在服务端,换台电脑、清了缓存都还在,再老的任务顶着也不会从侧栏掉出去;置顶不改它的先后。没存上会挪回原处并说原因
- **10-15** 页面更跟手:自进化里点「采纳」「驳回」不再整页刷新,按钮显示「采纳中…」,列表原地更新;进自进化、智能体不用再等几秒——本机 CLI 开机就先探好,几个一起探,过期了先给旧结果、后台再刷新。技能、插件、连接器、账号页切换时不再闪「加载中」,设置页换内容后停在原来的位置
- **10-14** 多人服务器上每个账号都能绑自己的消息渠道:在「助理设置」里扫自己的微信,填自己的飞书、QQ、企业微信应用、公众号、群机器人、通用 Webhook 和邮箱。消息按本人账号跑,用他自己的工作目录、偏好和助理模型,记录只有本人看得到;定时任务和提醒推到他自己绑的渠道,一条都没绑才照旧推服务器那套。密钥读回来是打码的,各人的回调地址带一串随机号,不暴露账号名;成员的通用 Webhook 不设密钥不收任务。账号停用、删除后,他的渠道一分钟内断开。平台管理员那套原样不动
- **10-14** 多人服务器上成员有自己的那份了:平台管理员按渠道勾哪些模型给成员用;成员能填自己的 Key,只有他自己看得到、用得着,花他自己的钱,不扣组织额度(平台管理员可整台关掉)
- **10-14** 成员能建自己的专家,只有自己能委派;平台管理员的专家可以一位一位设「不给成员用」,专家团里成员只看到自己能用的那几位
- **10-14** 每个人能起自己的助理名字、换头像、写「我的偏好」:每次任务都带上,排在组织统一的偏好后面,别人不受影响
- **10-14** 微信扫码、断开和各 IM 通道的「测一下」只有平台管理员能做
- **10-14** 文件名里带顿号的附件不再被拆成两个:「这是一个测、试文件.txt」以前在消息底下显示成两个不存在的文件,本机 Codex / Claude Code 也拿不到它的完整路径
- **10-13** 注册能直接填邮箱:自动取 @ 前面那段当用户名,登录时填邮箱也认;那段当不了用户名或撞名,页面上当场说清。注册失败不再算进限流,同一地址建满 20 个号才歇,先 1 分钟、再撞上 3 分钟(原来 5 个就锁 15 分钟)。
- **10-13** 设置 → 安全 新增「沙箱安全」开关:关掉后 AI 能动工作目录外的文件、连本机和内网,命令不再套系统沙箱;文件黑名单、OpenWorkBuddy 自己的端口照旧拦。多个账号共用时关不掉
- **10-13** 「本机/内网放行」支持通配符:192.168.1.*:* 放一整个网段,*.local:8080 放一类主机名,*:5432 放所有机器的某个端口。OpenWorkBuddy 自己的端口写了也不放
- **10-12** 扫码连的个人微信收得到定时任务和提醒了:任务跑完、让 AI「发我微信」都推到微信上,重启也不丢(前提是你在微信里给它发过一句)。以前只推企业微信、钉钉群机器人,AI 找不到发消息的路,回一句发不出去。从微信来的任务跑完不再重复推一遍
- **10-12** 微信连接更跟手:跑任务期间照样收消息,中途发「停」当场生效,不用等任务跑完;处理时微信里显示「对方正在输入」;网络抖一下 1 秒后就重连,最多等 10 秒,不再干等一分钟
- **10-12** 自动化页的「+ 添加自动化」「从模版添加」和编辑改成弹窗,不再在页面里撑开一大块;Esc 或「取消」关掉,点窗外不关。任务回复里顺口提到「fetch failed」不再被判成连不上上游
- **10-12** 飞书「扫码配应用」也能选已有的应用了:选了已有应用照样算配好;终端里那团二维码乱码不再贴进报错
- **10-12** 本机 Codex / Claude Code 读得到随消息传的文件了:粘贴的大段文字、拖进来的图和文档,发给它时末尾附上每个文件的完整路径。以前只给文件名,它自己去搜,工作目录在 git 仓库里、文件又被 .gitignore 忽略时搜不到,回一句「只收到文件名」
- **10-10** 成员、审计员和分公司账号也能建多个项目(工作空间):不止一个账号时,用自己工作目录的人在侧栏「项目」里新建、切换、改名、移除自己的项目,项目说明、挂的资料库、专家、技能、连接器照常按项目记。每个项目一个文件夹,建在自己工作目录下的 projects/ 里;以前的成果都在「默认项目」,就是原来那个工作目录。不能另选文件夹;项目文件夹被换成指到别处的链接时不跟过去,这一趟退回工作目录本身。各人的项目只有自己看得到,默认组织管理员共用的那份项目列表一个字不动。默认项目就是工作目录本身,不能移除。移除别的项目只从列表拿掉,文件夹和成果都留着;改名不改文件夹,老对话照样打得开。项目改名、移除后,它名下的老对话不再从侧栏消失:改名的跟着新名字走,移除的归到第一个项目,管理员那份项目列表也一样
- **10-10** 画布卡片右边多了连接点(鼠标停在卡上或选中时出现,触屏上一直显示):拖到另一张卡上松手就连线,线跟原来的一样,能断开、能撤销;连不上的卡标红并写明原因(用不上这张卡的内容、已经连着了、会绕成一个圈),松手不连;拖到空白处、拖回自己或按 Esc 都不留半截线,挪卡、框选、平移照旧。点一下连接点弹出「新建并连上」,只列连得上的种类,新卡放在右边空处、已经连好,撤销一下连卡带线一起退回。选中卡后,标题、名字、提示词能直接在卡上改:单行回车保存、多行回车换行,点别处保存,Esc 取消,拼音选字时按的回车和 Esc 不算;检查器当场跟着变,跟在检查器里改是同一步撤销。成员账号的画布里,文件夹下拉不再给「选择其他文件夹」
- **10-10** 渠道能选生图、视频、配音各走哪种接口:渠道表单加了「生图接口」「视频接口」「配音接口」三个下拉,默认「自动」,括号里写着这次会走哪种,中转也能手选;选了的优先于按型号、渠道类型和地址的推断。千问生图点「测」不再误报 400:以前测活拿生图型号去发对话请求,还发到了百炼原生地址后面拼出来的对话路径上,上游只能回 400;现在生图、视频、配音型号只做不花钱的清单核对,标「只验了一半」,对话测活改走兼容地址,报错带状态码和上游原文。百炼生图被上游明确拒绝「不支持同步/异步调用」、又没收单时,自动换另一种方式提交一次,并按渠道和型号记住;5xx、超时、已收单、渠道上选定了接口的都不换
- **10-10** 本回合产出按重要程度排:先把这一回合的文件排好再截前 12 张卡片,网页、PDF、Word / PPT / Excel 这类成品排前面,接着是视频、音频、图片;有成品时,草稿、调试脚本这类过程稿的卡片收起来,名字仍在下面的清单里。任务做完,最后那份成品自动在预览里打开,不用再一个个点。删掉或挪走的文件,服务端当场查实了才标「已删除」沉到最后,同名文件写回来会重新认;点开前先问一句文件还在不在,不再点了才报「不存在」。缩略图、复制图片没成功时只说看到的(「缩略图没显示出来」「图片没取到(HTTP 404)」),不再猜是改名、挪走还是删了
- **10-10** 输入框字多跟着长高:最少两行,最高约窗口三分之一(6~12 行),再多才在框里滚,最底下那行不会被切掉半截;框里上面或下面还有没露出来的字,那一边渐隐一行高,一眼看出还能往哪滚。对话区右下角那两颗滚动按钮跟着输入框往上让,不再压在正在写的字上
- **10-10** 多账号时工作目录、成果和资料库按账号分开:不止一个账号时,默认组织的管理员(含这台服务器的老主人)照旧用原来那份共享的工作目录、项目和资料库,以前建的工作空间都在;其余每人(成员、审计员,分公司的人连管理员在内)分到自己的工作目录(默认组织在数据根下的 accounts/<账号>/,分公司在组织根下一层)和自己的资料库,暂时每人一个工作空间。文件列表、成果页、搜索、下载,AI 读写和搜文件,都只认自己那份;管理员要看成员的文件,从成员的对话里点开。「本地产物」里的文件和文件夹能删了:只删得到自己工作目录里的,有任务在跑时不让删,删了记进安全审计。定时任务在负责人自己的目录里跑,命令行和 IM 进来的任务照旧在共享目录上。只有一个账号时一切照旧;老文件不搬,升级前的成果在「按任务」和老对话里照样打得开
- **10-10** 本机 Claude Code 删文件这类操作改成弹审批卡问你:Claude Code 卡上那项改叫「删文件等操作先问我」(原来叫「要审批的动作交给安全中心判」;设置 → 智能体 → 底层引擎,只有属主看得到,默认关)。勾上后 rm、sudo 这类要人点头的操作不再一律拒,改成弹审批卡,跟内置引擎同一张:网页、终端、手机都看得到,改文件的卡带 diff,批了才跑。名单放行的照跑,不认得的工具、判的时候出错的照拒。「自动改文件」档里 claude 自己会放行的 rm、rmdir,也按安全设置挂成先问(这版 claude 不认那个参数就照旧直接禁)。不用另勾「借给它的工具(生图、资料库等)在这边执行」;卡弹不出来时先说一句,这一趟碰到这类操作直接不做。放行的命令由 Claude Code 自己跑,不套系统沙箱;问答、计划那一趟和 Codex 不挂
- **10-10** 设置页说明改成大白话:每项一句话说清做什么、默认多少、花不花钱。「执行上限」里直接写「一个任务最多做几步」「一个任务最多跑几分钟」「一个工具最多等几秒」;六个先问小模型的开关并进「让小模型把关」一组,花多少钱、还没配小模型只在组头说一遍;安全页两份命令名单写明哪份直接跑、哪份先问你,名单外的那项改叫「名单外的命令先问小模型」。任务停下时、技能说明里、报错里点名的设置项跟设置页一字不差,「去设置里改」能直接点过去;英文界面同步
- **10-09** 换了工作目录不再带出别的对话的文件:自己选的文件夹也给每个对话单开一格放成果;命令行 -C、/cd 点名的和像代码仓库的照旧原地改。设置页和输入框旁的文件夹菜单都摆着这两种放法,选文件夹那一刻记下,按文件夹记住;分格后会告诉 AI 现成的文件在上一层。先传后发的附件记下传在哪、谁传的,换了文件夹或对话再发,搬的只是自己那份
- **10-09** 新对话头一条消息带的附件,点开预览不再报「文件不存在」:附件先放在工作空间根上,发出头一条消息才搬进新建的成果文件夹,现在气泡上的文件条和缩略图跟着改指向。两条对话各传一份同名文件,不再互相指到对方那份;传到一半切去别的对话,附件仍记在上传时那条名下
- **10-09** 答过的选项钉住:你在这个会话里答过的选项、中途补的话,每一步都带给模型,长任务压缩历史也冲不掉,专家子代理问到的主代理也看得见。一字不差再问一遍的直接拦下(以前这道拦截躲在一个默认关的开关后面,基本没生效过)。问句里自己写的前提不算你定的;真做不成先说清卡在哪再问,不许悄悄换一条路
- **10-09** 本机 Codex 有新版会告诉属主:点「重新检测本机」时顺带查一次(npm、bun、Homebrew 装的才查,平时打开设置页不联网),有新版就单列一行,附一键复制的升级命令;原地升级完会重新读型号表,新版才有的型号当场出现。任务里 Codex 报型号不认时,写明本机这份是几版、名字是不是只差写法、现在能用哪些、怎么升,它的原话附在最后,不再替你断定是订阅账号的限制
- **10-09** 本机引擎的型号下拉列出具体型号:分组列出具体型号、别名、其他型号和你用过的;属主多一项「手填别的型号…」,成员只在放行的里挑。本机装了不止一份 claude / codex 时,用版本最新、跑得起来的那份,卡上列出另外几份的路径和版本;要更新版 CLI 才能用的型号不进下拉,只对属主单列一行,附升级命令。「试一下能不能用」报这趟真跑的型号,填的是别名时连它落到的具体型号一起写
- **10-09** 平台管理员把底层引擎切到本机 Claude Code / Codex 直接能用,不用再先勾选;多人共用时只拦别的账号:成员要等管理员勾上「也给其他账号用」才跟着用,卡上写明走谁的订阅、命令在哪跑。设置页、引导、思考档位、对话和目标拆解都按这个账号实际在用的引擎来判断
- **10-09** DeepSeek V4 官方地址一条回复最多给到 64K,思考开关按它的新参数发(thinking.type 管开关,力度只分 low / high / max);回复写太长被截断时提示说人话,回「继续」就接着做
- **10-09** 地图设置:高德报错说人话,填 Key 的提示写明要选「Web服务」那种;新增「国内路线用哪家打开」,高德、Google 二选一
- **10-09** 附件不再卡 30MB:输入框和画布直接传原文件,服务端边收边写盘,不再转成 base64 整份进内存,两三百兆的录屏也拖得进来;老页面、脚本用的 JSON 上传照收
- **10-08** 借给本机引擎的工具可以改在主程序里执行:设置 → 智能体 → 底层引擎,在 Claude Code 或 Codex 卡上勾「借给它的工具(生图、资料库等)在这边执行」(只有属主看得到,默认关)。勾上后生图、配音、资料库这些借出去的工具每次都交回主程序,在这一趟的上下文里跑:账记在发起这一趟的人名下,审批卡在网页、终端、手机上都看得到,组织规矩、权限档位都按这一趟的。一趟一张凭据,跑完就作废(macOS、Linux 上只有本人读得到);名单外的、叫停之后来的一律拒。交不回去时明说这一步没做成,不退回引擎那头自己跑;口子没开成就说一句,这一趟照老样子跑。Codex 的命令沙箱连不了本机套接字,它命令行里的 owb 照旧自己跑,只有 MCP 那条交回来
- **10-08** 本机 Claude Code / Codex 能从资料库取素材:资料库里的 PDF、图片、Word 不是文本,以前引擎够不着,只能叫你拖进对话;现在借给它们 library_import,复制进这一趟的工作目录再用。只取得到你自己那份资料库,项目只挂了一块就只有那一块,按名字、带 ../ 都取不到别人的;问答、计划那一趟要往工作目录写,所以不借
- **10-07** 本机 Claude Code 要审批的动作可以交给安全中心判:设置 → 智能体 → 底层引擎 → Claude Code 卡上勾「要审批的动作交给安全中心判」(只有属主看得到,默认关)。命令、改文件、抓网页照安全中心的规则判,名单放行的直接跑;删除、sudo 这类要人点头的、不认得的工具、判的时候出错的,一律拒。每次现读设置,名单改了下一条就认。放行的命令由 Claude Code 自己跑,不套系统沙箱,跟没勾时一样;问答、计划那一趟和 Codex 不挂
- **10-07** 本机引擎出视频:按了停止、工具时限到了、CLI 先退了,上游已经收下的单照样出片,主程序在后台按任务号接着收,绝不重新下单;片子落回原对话目录、照常计费,结尾说一句有几条、任务号是哪些。你点了停止的,百炼、火山两家先去上游撤单(排队中的撤得掉,已在渲染的照样出片计费)。服务重启后接着收上次没收完的,超过一天还没收回来的不再查
- **10-07** 停本机引擎时连自立门户的子孙进程一起收:脚本拉起的浏览器、中间那层先退了留下的孤儿,以前按进程组杀够不着,现在按跑着时拍的进程树快照逐个停掉,不理 SIGTERM 的 3 秒后强停。pid 被复用的、换了父进程的一概不碰,不按名字杀
- **10-07** 本机引擎收尾照实核一遍交付:回复里点了名的文件不在或者是 0 字节的空壳、说「如图」这一趟却没有新图片,运行页上说一句(只提示,不打回重跑)。桥里的联网、命令、拦截记录逐条追加进审计,命令行跑完马上退也不丢,审计中心按时间并进来,不再整份盖掉主程序那份
- **10-07** 本机引擎的运行页看得懂了:借出去的工具叫回原名,图标、标题跟内置引擎一样,不再是 mcp__openworkbuddy__x;Codex 自带生图出的图半路就放进对话目录、出一张生图卡;好一阵不出声,每 30 秒说一声还在跑、多久没有新输出;工具没挂上、只读停了哪些设置这类提示存进对话,重开还在。本机引擎连着失败单独计数,不再算到云模型头上。这些话英文界面都有英文
- **10-07** 本机引擎也挂上插件带来的连接器,连接器页上关掉、暂停的不挂;走网址的连接器两个 CLI 写法各不相同,这次不转,运行页上点名是哪几台。名字里带点、带双下划线的改成两个 CLI 都认的写法,Claude 不再每次调用都弹权限;写给 Claude 的连接器配置只给本人读写
- **10-07** OWB 拉起的 Codex 不再加载宿主机上给别的工具装的技能和它自带的系统技能(只留 imagegen),描述不再挤掉项目说明和借出去的工具;项目自带的技能照常加载,你在终端里直接用 Codex 不受影响。Codex 报错照原话说:只有它明说没登录才说没登录,光一个 401 说是被上游拒了;说哪项设置「不再支持」的,连同怎么改一起带出来
- **10-07** 本机引擎的用量记准:Codex 续跑不再把整条线程的累计用量重算一遍(以前账本虚高好几倍),起算点找不到就记 0、不拿猜的数充数;Claude 被停、跑超时也记得上,一次调用拆成几条吐的只记一份。用本机订阅跑的只记不扣积分,界面上写明「用本机订阅跑的,不扣积分」
- **10-07** 问答、计划模式走本机 Claude Code / Codex 时一律按只读跑(claude plan、codex read-only),属主手填的放宽设置和附加参数这一趟不认,运行页上说一句哪几样没用;只借读的那几个工具。Codex 命令沙箱里跑不成的工具(要花钱记账的、要写数据目录的、要开 Chrome 的)开跑前就停,不花冤枉钱,提示词点名改走哪个 MCP 工具;「只看不动」档两个引擎都不给 owb 命令
- **10-07** 本机引擎的提示词照实说:借出去的工具逐个列全,技能一个不落、每条带正文文件的路径;看图 Claude 用 Read、Codex 用 view_image;node 脚本能直接 require 自带的 pptxgenjs / docx / exceljs。owb 放在哪都认 --help,打出完整说明和全部参数,敲错工具名给出近似的名字
- **10-07** 本机引擎借 OWB 的工具更靠谱:借出去的名单只留一份,提示词、MCP、owb list 照同一张表,一个不借就真不借;产物落在这一趟任务自己的工作区,资料库只看得见本人那份,项目只挂一块就只看那一块;PATH 先放 owb 那一层、补全的搜索路径接在后面,装在 nvm / homebrew 里的 CLI 不再找不到 node;生图、出视频、配音的回执照引擎的当前目录说路径,不再说成「已显示在上方」;设置文件读不出来时借出去的工具一律不执行,不再当空设置照默认跑
- **10-07** 行程卡「打开路线」:国内一天四站以上改开高德网页版路线规划,站名和坐标一起带过去,一天最多 15 站,扫码在手机上打开同一页(三站以内仍开高德导航链接,三站一律按驾车,不然途经点会丢)。Google 地图每站写「站名, 城市」,不再只给坐标——只给坐标时它会换成旁边商户、雕塑的名字,只写站名又可能跑到别的城市。国内的「打开路线」旁边多了「高德 / Google」两格,换了整天路线和段间导航一起换,记在本机;Google 一次最多 10 站,超了照实说这天几站。链接长的二维码画大一号,好扫
- **10-07** 行程卡:点地图上的钉子,旁边弹出这一站的小卡(照片、评分、类别、钟点、「导航到这」),「上一站」「下一站」一路翻下去,Esc 收起、焦点回到那颗钉子;窄窗口里小卡贴在地图底边。两站之间点「导航 ▾」,展开步行、公交、骑行、驾车四种走法,各开一条高德链接;「发到手机」就地出二维码(本机编的),扫了在手机上接着导航,段间的还能换走法。高德额度按月分开算,Key 出错当天停用、整批只打一次;路线没查成的那段写明原话、能再查一次,时间线上也看得到;每站标出地点信息从哪来;行程 JSON 解不开时说清第几行不对
- **10-07** 画布花钱更稳:画布对话里的 Agent 不再直接生成,改成交一份待生成清单挂在画布顶上,先估价,点「开跑」才扣费;只开跑一部分时,跑过的划掉,没跑的带新报价留着。每一单带单号,服务端同号只跑一次,断线不再重复扣费;没收到结果的格子标「状态未知」,给「看结果」「再生成一次(会再扣费)」「忽略」。生成失败只有上游明说没收单、或者压根没发出去才换备用模型重发,等超时、下载断了这类可能已扣费的照原话报错。镜头检查器能「生成配音」「换一版配音」,同样先报价再扣费。本机引擎跑画布任务也能改节点、交清单
- **10-07** 画布找得回来:删画布挪进项目回收站,画布下拉里一点放回来,备份和快照跟着走;Agent 清空画布或一口气删一串节点前先存快照,顶上给「撤销」一键补回。撤销只撤你自己的改动,提示上的「撤销」只撤它说的那一步;连线能单独断开,删节点不再弹确认。画布没存进项目时顶上挂红条照抄原话、可重试。时间线上拖镜头格子(触屏按住拖)或按 Alt+←/→ 换放映顺序,一键合成照同一个顺序拼;没配音但视频自带声音的镜头用视频原声;服务重启后合成进度问不到就照实说、给重新合成。上传同名文件存成 名字_2,原来那份不动,同一个附件重拖原地换新;素材台账不再把在用的标成没人用
- **10-07** 闲着时更省电:没有任务在跑、也没人在用的时候,服务那边的卡顿计时闲满一分钟就停,每秒醒来的次数从约 40 次降到 2 次左右;任务或请求一进来立刻接着计,界面后台的定时轮询不算「在用」。窗口不在前台时,界面线程也不再一直盯着卡没卡
- **10-07** 行程卡换了个样:地图铺满整张卡片,当天的地点浮在右边一栏,天数胶囊浮在地图左上角,缩放和「回到全览」挪到左下角。地图上的钉子是带白边的照片方块,挂着序号和地名,挤不下的地名先不写;取景躲开右边那栏,收起那栏就照整张地图重新取景。点地点卡片,地图滑到那一站;点钉子,右边滚到那张卡片。卡片照片更大,写评分和类别,具体钟点单列一行;两站之间那一行写怎么走、多远、多久,兼当分隔线。「打开路线」旁边写明开哪个地图:国内三站以内开高德,再多或国内外混着开 Google 地图(十站以内),一天每段都在两公里内就按步行
- **10-06** 系统沙箱:AI 跑的命令(run_shell、后台命令)和 run_node 脚本,在 macOS 上套系统自带的 sandbox-exec,在 Windows 上降到低完整性级别跑。不管命令怎么写,都读不到 Key 和账本、改不了应用本身;macOS 上还连不上 OpenWorkBuddy 自己的端口,Windows 上只写得进工作区和临时目录。开关在 设置 → 安全 → 系统沙箱,四档:默认、自动(立不起来照常跑)、必须(立不起来就不跑)、关闭,设置页看得到现在立没立起来。每条命令多花:macOS 约 7 毫秒,Windows 约 13–16 毫秒(真 Windows 上实测)。被拦下时输出里会说开关在哪。Windows 那层挡不住连本机端口、隔不开同机多个组织的工作区,开关旁边和[安全](docs/安全.md#系统沙箱macoswindows)里都写明了。Linux 上暂时没有这一层
- **10-06** 只用你配过的模型:中转站不再转发没登记的型号,放行任意型号要属主显式打开;判断模型只认配置过的型号;渠道测试只测已登记的型号,存着的 Key 不随改过的地址发出;记忆向量只用设置里选定的嵌入模型,没选就按关键词检索。设了额度时,没价目的型号直接拦下;价目补齐向导带上默认型号,本地免费的模型按渠道地址判断
- **10-06** 额度闸补漏:主渠道挂了换备用渠道前也过价,备用那条没价目就不换,照实说卡在哪、去价目表补;换过道的任务按渠道拆开记账。看图过额度闸,出图出视频先解析出实际型号再估价。只靠前缀对上价目的贵档型号(如 -pro、-realtime、-thinking)在设了上限时按没价目拦下,日期快照和更便宜的小号照常放行。记忆向量被额度拦下时,记忆页如实说原因、改按关键词召回
- **10-06** Key 不进 AI 手里:AI 起的子进程只拿最小环境变量,Key 类变量默认不带,属主可在 设置 → 安全 配透传清单。联网工具默认打不到本机、内网和云元数据:先解析地址逐个判,连接钉住判过的地址,跳转逐跳重判;OpenWorkBuddy 自己的端口始终拦,属主可按 host:端口 放行。多人共用时,命令和代码碰了文件黑名单直接拦下,不出审批卡
- **10-06** 外部引擎(本机 Codex、Claude)必须指定型号:型号要钉死或在属主放行列表里,附加参数不许换型号;组织关了命令行就不启动;多人共用默认关、属主逐个打开,不往引擎传 Key 类变量。Codex 默认不联网、只写工作区。报错指到真找得到的设置位置,老配置升上来时会提示这几条
- **10-06** 行程卡:回答里的行程画成能拖能点的地图,按天切换,地点卡片、时间线、照片都有。右边列表能收起、拖宽窄,地图能拖高,右上角「回到全览」一下回到当天所有地点(焦点在地图上按 0 也行)。不填 Key 也能用;在 设置 → 地图 填了高德 Key,国内地点更准、还有评分。地图服务没给照片就按名字和位置去 Wikidata 补。点「导航」国外开 Google 地图、国内开高德,两站两公里内按步行,再远按开车;国外一天的整条路线带上途经点一起开
- **10-06** README「长这样」放了行程卡的两张截图:北京三日游,地图视图按天标好每个点位、右边是带照片的地点卡片和导航,切到时间线一天从上午排到晚上
- **10-06** 本机 Codex 收到工作目录和产出说明;它自带生图出的图自动放进对话文件夹,成果栏能预览
- **10-06** 授权说明补上授权码作废的三种情形(退款、泄露、冒用)和申诉办法:作废前先通知,泄露、冒用不连累被授权方,作废只提示、不锁功能。写明软件没有统计和遥测,联网只为干活和检查更新
- **10-06** 源码按层搬进 src/:platform、core、domains、agent 与 engines、server / cli / im / desktop、util,各层只准往下引用,层级守护在测试里强制;打包白名单只认 src。二次开发先看[代码架构](docs/代码架构.md)
- **10-05** 新建项目:连接器、专家、技能可全选、清空、筛选,按 Shift 连选,还能照搬已有项目的选择
- **10-05** 评测:评委看得到过程,提示词可改,加人工评测和多维成绩单
- **10-03** README 放了一集一句话做出来的 AI 短剧成片《不烧心》EP01:剧本、定妆、分镜、首帧、镜头视频到成片一路做到底,75 秒,点封面看
- **10-02** 参考模板用起来先弹一张填空表:模板里的 `__名字=默认__` 给默认值,`__名字=A/B/C__` 出选项,逗号或括号后面那段当提示;右边实时预览填好的样子,上次填的记着。没填完也能先填进输入框,按 Tab / Shift+Tab 在剩下的空之间跳。写模板时选中文字点「设为填空」(Mod+E)就包成空,再点一次拆回来,下面列出所有空、能试填。删模板不再二次确认,删完给一个撤销。内置 14 条模板的空都重写成有名字的格子
- **10-02** Windows 安装包改成向导:能选装在哪个盘、哪个文件夹,看得到进度条;装进数据文件夹会被拦下。包里文件从一万多个减到四千个,装得更快;任务栏图标和通知归到同一个应用名下。免安装版解压时有图,重复双击不再删掉正在跑的那份
- **10-02** Windows 起任务不再闪黑窗:子进程一律隐藏,.cmd 垫片、GBK 输出照常读得懂,退出收尾和剪贴板都不再卡界面。中文、空格、长路径统一处理;python3 走 ASCII 垫片,系统自带的 WindowsApps 占位不再抢先。高 DPI 下托盘图标、成果栏按钮、画布和时间线不再糊或错位。拦删除的命令补上二十多种 cmd 写法(`@`、`,`、`;`、`=` 前缀,重定向,`cmd.exe/c`、`%ComSpec%`、`^` 续行、`forfiles /c"…"` 等),PowerShell、start、net 走同一套判定
- **10-02** PPT 预览按每页真实版式画:位置、底色、字号、图片、表格、图表都在,zip64 打包的文件也能打开。无限画布按图片真实比例摆,不再拉变形;时间线预览改成胶片条。成果栏在窄窗口下关闭键不再被挤出屏幕
- **10-02** 模型渠道修一轮:火山方舟上的 GLM 不再被拦成「智谱的型号」;模型挂错渠道时不再乱判乱挪,改挂了会告诉你。多媒体渠道里通义国际站和专属地址、看图协议、按型号点名、万相异步出图都修好了;画布里对话放上去的参考图、首帧、视频不再全挂「找不到」
- **10-01** 对话里说「装这个技能」直接装进技能库:跟技能页「从 GitHub 装」走同一条路,过安全扫描、记来源;会覆盖已有技能、扫描有告警时要你点头。内置技能跟着应用升级换新版,你改过的原样留着。对话里要接 MCP 直接带你进连接器页
- **10-01** 飞书、微信这类消息的回复超过单条上限时,按段落拆成几条依次发,一个字不丢——以前超出的部分直接被截掉。回复里的 SVG 图表以前是把源码原样发过去,现在转成 PNG 当图片发;发不了图的渠道明说一句图没发出去
- **10-01** 分文件夹以前就有的老对话:工作空间根上已有的文件照原地改写,不再在新文件夹里另起一份同名的,成果区「本对话」里也列得出这些文件;换过工作空间目录后,老对话里的图片、文档附件照样有缩略图、点得开
- **10-01** 命令行(owb)也按对话各开一个文件夹,不再全堆在工作空间根上。有任务在跑时点「新任务」,新任务不再落进上一条临时切过的文件夹。消息和代码块上的「复制」在桌面版里点了没反应的毛病修了,复制不成时如实说
- **09-30** 成果按对话分文件夹,不再只限默认工作空间:新建项目没填目录(应用替你建在 ~/OpenWorkBuddy/projects 下)、没指定目录的分公司,每个对话也各有自己的文件夹,两条对话各写一份同名文件不再互相盖掉。飞书、微信这类消息按会话分(`IM_对话/月日_头一句话`),定时任务按任务名分(`定时任务/任务名`),跑完什么都没产出的空文件夹自动收掉。你自己选的文件夹照旧就地读写。对话中途换了文件夹,成果区不再显示「本对话 0」;定时任务点「看执行过程」能看到这一趟的产出
- **09-30** 参考模板库能自己加、改、删了。「我的」谁都能加,只有自己看得见;「公司」只有管理员能加改删,全组织看得见,每次改动记进操作审计;内置模板点「改」是存一份副本、原来那条藏起来,「已藏起」里能放回。个人桌面版只有「我的」
- **09-30** 同时开好几个对话不再卡:所有对话共用一条实时通道,每个对话各用各的浏览器标签页;服务挪出界面线程,存盘、缩略图、截图也不再占主线程;侧栏每一行都能单独停
- **09-30** 首次配置能直接填中转站、自建网关、本机 vLLM 这类 OpenAI 兼容地址,只填域名打回 404 时自动补 /v1 再验;用输入法选词时按回车不再把半截拼音发出去;长对话能连着往上翻
- **09-30** 一台服务器带几家公司能用了:平台超管在「组织管理」建组织,在那一行发这家的第一张邀请码,拿码注册的人就是这家的超管。组织到期后发不起新任务(网页、IM、定时任务、中转 Key 都停),登录、翻历史、下载成果照常;想立刻停一家,把到期时间改到以前
- **09-30** 多人部署的权限补漏:普通成员看不到连接器的地址和启动参数;租户管理员不能自己打开命令行、改记账折扣、抬组织封顶、改付费 API 额度;停用的人重新启用要过席位;邀请码上限按组织各算 200 张;删掉的成员留下的对话只归原组织管,登录名不能再被占用;办离职的交接人必须是本组织在用的人;成员那一行加了「解二次验证」,手机丢了不用再上服务器跑命令;命令行、IM 这类没登录的用量不会再记到分公司名下
- **09-30** 定时任务替负责人本人跑:记负责人的账、用负责人那家组织的目录和规矩;负责人被停用、删除,或组织到期,任务当场停并写明原因。登录成败都进运行日志,锁号和停用账号在试登录进组织审计
- **09-30** 新写[账号与部署运维](docs/账号与部署运维.md):部署方式怎么挑、第一个账号、加人、办离职、密码和二次验证丢了怎么找回(含 Docker 里怎么跑)、去哪查登录记录、备份恢复升级、一台服务器带几家组织、上线前自查。部署和多人协作文档里过时的地方一并改掉
- **09-30** 许可文件从三份并成两份:`LICENSE-ECOSYSTEM.md` 里的 MIT 清单和全文并进 [COMMERCIAL-LICENSE.md](COMMERCIAL-LICENSE.md#按-mit-授权的部分),条款一字没改
- **09-28** 授权写清楚了:个人非商用免费;公司使用(哪怕只在内部)和个人商用(接单、做付费产品)要向作者买商业授权,公司可先免费试用 30 天。登录页、开箱向导第一步、关于页、启动日志都写着;管理后台加「商业授权」页,填授权码本机验证,不联网、不锁任何功能。细则见 [COMMERCIAL-LICENSE.md](COMMERCIAL-LICENSE.md)
- **09-28** Word 文档技能重写:用 docx 库出文件,中文字体、目录、页眉页码、表格一套模板直接能用;改已有 .docx 的做法和容易踩的坑也写上了
- **09-28** 通义渠道算记忆向量不再被误判成「不可用」:以前一次塞 16 条,通义上限是 10 条,整批被拒后退到了本地 Ollama。现在按各家的上限分批发
- **09-28** Excel、PPT 技能里的模板照抄就能跑:以前末尾那句 `await` 在 run_node 里是语法错,Excel 模板还用了一个没定义的变量
- **09-28** 回复说到一半就断、任务却报「完成」的毛病修了:上游半路停(DeepSeek 忙时会这样)或者流断了没收到结束标记,现在都算「没说完」,自动让它从断开的地方接着说,交付的是拼好的整句;连着断 3 次才停,并告诉你是上游没发完。上游内容审核掐掉的,界面上直说被拦了
- **09-28** 渠道能选接口格式了:OpenAI Chat Completions、OpenAI Responses、Anthropic、Google Gemini、Ollama 原生五种。本地部署、自建网关说哪种就选哪种,「测一下」和真跑打的是同一个地址;工具调用在每种格式下都能来回。Ollama 原生口默认把上下文开到 32k,不再被它按几千 token 悄悄截掉系统提示词;Gemini 被安全策略拦下会直说是它拦的
- **09-28** 对话在别处还跑着(另一个标签页、手机上发起的,或者断线后没接回来),这边发一句「继续」不再报「该会话已有任务在运行」:页面当场接上那一趟的直播,这句话按插队 / 排队的开关送进去;点开时那趟已经在跑的,跑着的那一轮只显示一份,不再多一轮「中断了」
- **09-27** 设置 → 模型里换了「主用」,新对话真的换过去:以前开着「新对话沿用上次选的模型」时,输入框里挑过的旧模型一直压着,设置里怎么点都没用;输入框里点「跟随全局默认」也同样会被拽回去。当前对话单独选过模型的,换主用时会说一声它没跟着换;助理页和飞书等消息单独选了模型的,对话卡里标出来,一键改回跟主用
- **09-27** 自动备份:设置 → 数据备份里选「每天」或「每周」,到点自动打一份,只留最近 7 份自动的,手点的、导入的一份不删;默认关(备份里有 API Key)。正在恢复时不打,打包时不许恢复,失败了设置页和审计里都看得见
- **09-27** 能做视频了:配音按段合成(TTS)、动效渲染(`render_motion`)、按时间线合成成片(`compose_video`)。四个现成配方——产品宣传片、产品演示、小红书轮播、多平台分发——开头先弹一张表,时长、画幅、声音、封面挑好再动手,交付页一次列齐成品。**要花钱的那一步(AI 生图、付费配音)默认是「这次不做」**,只标一句「要花钱,没替你选」,你自己勾了才跑;配音扣过费又被你停掉的,照实算已花钱。重名的文件不覆盖,另起名字
- **09-27** 网页演示录屏(`record_web_demo`):打开网页照步骤点一遍录成视频,要公开的先把本机用户名、路径这类信息打上码;录到一半页面跳走了就不交付,不拿半截录像充数。品牌档案一个产品存一份:名字、卖点(带出处)、配色、字体、配音、口吻,出图出片直接套
- **09-27** 资料库加「工作区」页签,像访达一样一层层点进文件夹,工作区里多深的文件都找得到、点得开;「文件夹」视图写明只显示最近一批,旁边「全部 N 个 →」一键跳过去;「未归属」和搜索改成查整个工作区,不再只看最新 500 个、三层以内
- **09-27** 「本回合产出」列得出第四层及更深的文件(以前 AI 写到深层目录里的文件不在清单上),飞书、企微回复里的附件同样带上;删掉的不列
- **09-27** 飞书:mp4 当视频消息发,超过上限先压缩再发,上传失败退回按文件发,手机竖拍的不再被压扁。任务卡片写这次花了多少钱(「已花 ¥0.84」);没有官方单价的写「单价未知」,不按 0 算;Claude Code、Codex 这类引擎花费记不全的,干脆不写金额,免得少报
- **09-27** 企微、QQ、公众号、iLink 发文件出错时,报错里不再带出你电脑上的完整路径
- **09-27** 测试不再碰真实数据:加了一道闸,哪条测试要写真实数据目录就当场报错;几套单独跑会写进去的测试都换成自己的临时目录。一次全量测试新增的临时文件从约 1.5G 降到 6.3M,e2e 跑通后不留临时目录
- **09-27** 配方的英文界面里「没选 / 这次不做 / 没填」三处兜底文字也翻成英文
- **09-25** 项目主页加了「替代对比」:Claude Cowork、Codex、豆包办公、千问办公、DeepSeek 各一页,中英两份,每页都老实写了什么时候还是用对方更合适;README 加「从别家换过来」一节,主页补上 sitemap.xml 和 robots.txt
- **09-25** 命令行 REPL 能好好打多行了:粘进来的多行摆进输入框、回车才发(以前里头的回车直接把半截发出去);自己换行用行尾 `\` 回车、`Ctrl+J` 或 `Option+回车`;`Ctrl+G` 用 `$EDITOR` 写一大段,编辑器没存成原来的字还在;`Ctrl+R` 搜以前问过的话,多行的放回来还是多行;攒着几行时 `Ctrl+C` 只扔这段不退出
- **09-25** 命令行跑着的时候,「思考中…」和正在跑的工具那一行后面走字:`· 12s · 8.4k tokens · Esc 停`,分得清是在干活还是卡住了;按 `Esc` 停这一趟、不退出,停完那行定格成 `· 12s`。你在打字、在回答它的问题时不抢 Esc
- **09-25** 命令行 Plan 模式出完计划,摆两个选项让你挑:「按这份计划开干」(切到 Craft 照计划动手,做完逐条对照计划说哪几步做了、哪几步没做)或「接着改计划」;Esc 不选,接着打字说别的。计划还在跑时你已经开始打字的,不弹
- **09-25** 命令行没人在终端前(管道、`--json`、定时任务)遇到要审批的一步,当场拒掉并告诉你怎么放行,不再干等;新增 `--allow`,出门前预先点头某一类命令、写文件或危险操作。提示里给的那串 `--allow "…"` 原样复制回去就认,写错规则直接退出码 2,不会带着没生效的放行悄悄跑下去。模型那头收到的也改成实话:以前说「已在界面弹出审批请求」,没摆过卡它就会跟你说「你拒了」
- **09-25** 命令行 REPL 里 `!` 开头自己跑一条 shell(`!git status`),输出自动带进下一句话给 agent 看,`/drop` 不要;Ctrl+C 只停这一条命令。真要发一句以 `!` 开头的话,打 `!!`
- **09-25** 项目规范(AGENTS.md,没有就读 CLAUDE.md)从工作目录一路往上读到 git 仓库根,子目录里的规则离得近的优先,共用 6000 字预算;命令行任务现在也会带上,`/status` 里一行「项目规范」列出读了哪几份
- **09-25** 回答里提到的文件名,只要工作目录里真有就能点开预览。以前只认这一轮刚生成的,上一轮画的图在收尾清单表里是一行行死字;打开历史任务时文件清单晚到一步,到了也会补上链接。两个子文件夹里各有一份同名文件、说不清指哪个的,不链
- **09-24** 命令行的审批改成 ↑↓ 挑、回车确定(数字键和 y/n 照样直接选,Esc=不允许);单子刚冒出来那 0.4 秒内的回车不算,免得之前多敲的一下把删库命令放过去。窄终端里一行都不折,重画擦得干净
- **09-24** 命令行里工具调用的样子跟 Claude Code / Codex 对齐:`● Shell(npm test)` 一行写清跑的哪条命令、改的哪个文件,下面 `└` 挂输出头 4 行、剩下的说还有几行;退出码非 0 放第一行;并发或中间插了审批单,结果前把自己那行再印一遍,不会挂错
- **09-24** 画布出视频:上游已经收下的那一单出了错(等结果超时、下载断了)不再自动重跑,免得扣两次钱,提示里给出任务号
- **09-24** 画布出视频带上卡上写的时长、画幅、分辨率,镜头没写时长就用新建短剧定的每镜秒数;新镜头卡的占位字不再混进提示词
- **09-24** 设置里的上下文上限留空=按模型窗口自动算,不再一保存就卡在 12 万字
- **09-24** 在画布里对话,任务历史当场显示「运行中」、置顶、回复边到边进来;历史里只显示你打的那句,不再是一大段操作说明;断流会接着跟到真跑完
- **09-24** 输入框提示 `@` 引用文件、`/` 调用技能与指令
- **09-24** 判断模型(Jev)改成默认不开:只配了 OpenRouter 聊天渠道不再自动用它,要用得自己加一条「TypeSafe Jev」渠道
- **09-23** 命令行 `/cost`(也就是 `/status`):这个会话一共花了多少 token、调了几次、约多少钱;有一轮的模型查不到价就只报 token 不报钱,本机引擎按不花钱算
- **09-23** 等输入的命令(`read`、`input()`、`npm init`)不再空等到超时:`run_shell` / `run_node` 不给 stdin,当场读到结尾,以前白等 120 秒、现在 0.07 秒回来。`read_file` 认 `offset`/`limit`(以前静默丢掉、从头整篇读),二进制文件直说不回乱码;`search_files` 认 `pattern`/`path`,给一个文件就只搜这一个;空命令报错不再假装 exit 0
- **09-23** 改 Windows 换行(CRLF)的文件不再改出一半 `\n` 一半 `\r\n`:`edit_file` / `multi_edit` / `write_file`(含追加)都跟着文件原来的换行走;文件用 Tab、它给的是空格(或反过来)时写回去换成文件的那种,不再留下 Python 报 TabError 的混缩进。本来就混着的文件不动
- **09-23** `openworkbuddy workflow 流程.json`:把「想方案 → 照做 → 审一遍」写成文件按顺序跑,`{{名字}}` 贴前面某步的结论;一步没成后面就停,文件写错一步都不跑
- **09-23** 钩子:`config.json` 的 `agent.hooks` 里写命令——`before_shell` 拦命令、`after_edit` 改完文件自动跑(格式化/lint)、`done` 没过不许收尾(最多打回两次)
- **09-23** 命令行:`/review`(和 `openworkbuddy review [基准]`)把改动取好交给它审,只看不动;`.openworkbuddy/commands/*.md` 自己写斜杠命令,`$ARGUMENTS` `$1` 填参数;新开关 `--model` `--max-steps` `--append-system` 只管这一次
- **09-23** 写代码更顺手:`find_files` 按名找文件、`multi_edit` 一个文件改多处(全成或全不动)、读后被改就拦(改前先重读)、`run_shell` 可放后台(`shell_output` / `shell_kill`)、`todo_write` 进度清单——没打勾就收工会被打回
- **09-23** **开工之前先挑技能:用户点名一分钱不花直接加载,没点名才问判断模型一道单选(默认关,设置 → 智能体设置)。** 用户装了技能是指望干那类活时照着做,可技能在提示词里只是一份名字清单,模型第一步想不起来,整篇就按自己的路子做完了。「/wechat-article」「用 wechat-article 写」现在机械地加载,开关关着也照做(整词匹配,`html-page` 不会被 `html-pages-v2` 蒙混);没点名、开了闸,问一道「该先照哪个技能做」,选项是技能名加「都不对口」,挑中且确定度到 70% 才替它加载。只在顶层任务问、已加载过不再问;只会多加载不会少加载;挑「都不对口」、拿不准、问不成一律照旧并留一行警告。67 条断言,换回旧 agent.js 18 条红
- **09-23** **加载过的技能,历史一压缩就忘了;下一轮续跑更是从头没这回事。** `use_skill` 的全文以前只是一条工具结果躺在历史里,压缩、截短第一个牺牲它,于是同一场对话里第三篇推文又不按技能来了。现在加载好的技能全文挂在系统提示词「已加载技能」一节(最多三份,更早的列名字),每一步都看得见;工具结果只回一句回执;压缩摘要里写一行【已加载技能】,续跑时从历史里的 use_skill 调用和这一行把技能自动带回来。提示词里把「动手前先 use_skill」从建议写成规矩
- **09-23** **历史压缩那一步用的是全局默认模型,不是这场对话选的那个——默认模型填成判断模型时压缩直接 400,报错一行看不懂。** 压缩摘要现在跟着这场对话的模型走;渠道里把判断模型(Jev)当对话模型用,报错直说:它只会在选项里挑一个,不会写字,去 设置 → 模型 换,判断模型在 设置 → 智能体设置 里单独配
- **09-23** **记忆超预算时,「交付别用 open 替我打开」这种规矩被挤掉了——恰恰是任何活都得守的那种。** 装不下时按跟本次任务的相关度挑,对事实是对的(写推文用不着「报销走飞书」),对规矩是错的:「别替我打开文件」跟「写公众号推文」一个词都不沾,相关度零分,比它新的杂事都排在它前面。现在规矩类先进门(按记入时间,稳定),剩下的预算再按相关度挑事实;规矩多到装不下也明说「还有 N 条规矩装不下」,不悄悄丢;命中只记给真进门的。21 条断言,把「规矩先进门」改回去 5 条红
- **09-23** **agent 做完老是 `open` 一下替你把文件打开——用户没要求的话,交付只报路径。** `open` / `xdg-open` / `start` / `explorer` 进了「先问」那张表:全自动档也会弹一次确认,用户明确说「打开」才开;提示词里也写明对话里会自动出预览卡,不必替用户开。cmd-risk 套 141 条,新增 11 条(含 `&&` 串起来的;`echo open the door`、`node open.js` 不误拦)
- **09-23** **对话里的预览卡和右边预览面板打开的不是同一张图。** 同一个路径 agent 改了三版,卡片是改完那一刻抓的,右边面板点开是浏览器缓存里的上一版,用户以为它骗人。现在每张卡、每次预览都带那一版的时间戳(`?v=`),服务端只对带版本号的请求给长缓存,不带的一律不缓存;卡片和面板各自指向自己那一版,点哪张开哪张。前端和 e2e 各补了断言
- **09-23** **v0.9.0 第二次打标签又红了:这回红的是「clone 只占 50.1M,不到普通拷贝的四分之一」——量出来 clone 比普通拷贝还大,这在物理上不可能。** 那条断言量的是 `df` 系统级空闲盘的前后差,流水线那台机器上 e2e 刚跑完 Electron 就把 prefs 这套当子进程再跑一遍,别的进程还在往盘上写,48M 的差里混进了别人的 2M。同一提交在 push 触发的流水线上是绿的,本地也是绿的——**这是量法的噪声,不是 clone 退回了普通拷贝**。改成最多量三次,哪一次量出 clone 不到普通拷贝四分之一就停,三次都不像才算挂,两次之间 `sync` 等 300ms。红话里带上每次量出来的数,一眼能分清是噪声还是真退回。变异对照:在镜像里把 `canClone` 硬掰成 false,三次量出来都是 ≈48M,闸照红——重试救的是噪声,救不了真退回。本地 393 过 0 挂。
- **09-23** **打断你之前先判一句:第二问起,agent 弹给你之前先花一道题问问是不是非问不可。** `ask_user` 是唯一不受循环守卫管的工具——连问四遍也不会被拦,而拦它的理由本来就该是「这一问值不值得打断用户」,不是「问了几次」。现在开了这道闸(设置 → 「打断你之前先判一句」,默认关),头一问白放行;从第二问起,同一轮里字面上问过的直接回上次的答案不再弹;没问过的先交给判断模型归类——「关键信息 / 岔路 / 得你拍板」照旧弹,「汇报进度 / 技术路线 / 自己查得到 / 又问一遍」四类且确定度 ≥ 80% 才拦下,拦下的回给 agent 一段回执:按最合理默认继续、在最终汇报里注明、判错了再问一次这道闸不拦。归类没答上来、判断模型没回应、两道题打架,全都照旧弹——**这道闸只会少弹,不会替你挑答案**(岔路永远弹)。85 条断言,含五组真跑 agent 的对照:开闸配「汇报进度」拦 1 放 2、关闸 3 问全弹、「非得问」全弹、判断模型抛错全弹并留痕、归类说是岔路全弹。
- **09-23** **本地测试全绿,流水线上红了——这套测试悄悄依赖开发机的系统语言。** v0.9.0 的标签推上去,测试那一步就挂了,后面打包和发布整个跳过,Release 页上一个包都没有。差别不在代码在机器:界面语言默认跟系统走(`navigator.language`),开发机是中文,流水线那台是英文,而有两条断言照着中文原文比——「点 + 开的是新建项目那个编辑器」比的是弹窗标题那四个字,在英文界面上量出来是 `New project`。**红的是断言的写法,不是产品**:那个编辑器好好地开着,四栏一栏不少。两处都改成量结构——这一条现在数「名字 / 工作目录 / 项目指令 / 挂哪块资料库」这四栏在不在(这本来就是它那句话承诺的东西),/ 菜单表头那条改成看提示里有没有 `↑↓` 和 `Esc`,键名哪个语言都不翻。另外真页面进门先把语言钉死再整页重载,钉没钉住当场验,验不过直接报错,而不是让后面几十条断言结在一个说不清的前提上(另外四套开真页面的测试早就这么写了,就这一套漏了)。量了三遍:钉中文 68 节 2296 条全绿,钉英文同样 68 节 2296 条全绿——换台机器量出来的数一样;再拿修之前的断言配英文界面,第 66 节当场红,报出来的那句话跟流水线上的一字不差,这才算复现了。
- **09-23** **上一条是「数错了改过来」,这一条是「别再靠人记得」。** 徽章那份数字只有人手动跑 `npm run stats` 才重算,而「记得跑」这件事是靠不住的——上一版就是这么挂了一整版。现在机器每次跑测试都自己数一遍,跟 `docs/stats.json` 里存的那份逐栏对(连版本号一起对,发版抬了号忘了重跑当场红)。**`updated` 那一栏故意不比**:它每天都变,比它等于要求每天重跑一遍,然后所有人第二天早上看到的都是红的——一个天天误报的闸,两周之内就会被人学会忽略。9 条新断言,其中 4 条是反向对照:技能数差一个要抓得到、版本号没跟上要抓得到、只有日期不同不许红、文件整个读不出来要算每一栏都不对(而不是静悄悄放行)。真注进去量过:把存着的技能数减一,闸红在那一条上;把版本号退回 0.8.1,红话里直接写出「文件里写着 0.8.1,现在数出来是 0.9.0」和下一步该跑什么。发版清单里也补上了这一步。
- **09-23** **README 顶上那几个徽章数错了,写着 35 个技能,实际有 36 个。** 徽章读的是 `docs/stats.json`,这份文件得手动跑 `npm run stats` 才重算,上一版之后没人跑过。顺带修了同一个脚本里的日期:`updated` 那一栏用的是 `toISOString()`,那是 UTC——东八区晚上八点之后跑一遍,徽章上写的是昨天,而同一次提交里更新日志的日期是本机算的,**同一天的改动在两个地方写着两个日子**。改成按本机时区取。就地量过:此刻本机 09-23 00:42,旧写法吐 09-22,新写法吐 09-23;两条对照——把时钟搬到 `TZ=UTC`,两种写法必须一模一样;搬到 `TZ=America/Los_Angeles`,本机日期得是更早的那个。不然「修好了」可能只是把偏移硬加了一天,换个时区照样错。
- **09-22** **刚给 `/` 菜单加的上下键,没有一个地方告诉过用户它存在。** 顺手把「回车是填进输入框,不是把话发出去」也写在表头右边——这条规矩刚改过,学过旧行为的人不看一眼不会知道。一行都挑不了的时候(打了个谁也匹配不上的词)这句不出现,免得指一条走不通的路。**同一趟修掉了自己上一版引进的毛病:名单是异步对回来的,对回来就重画,而重画无条件把选中钉回第一行**——人刚按了两下 ↓,名单一落地就被拽回去,上下键等于白按。现在重画会把选中留在原来那一行,只在菜单正开着的时候算:关掉了的那一次挑到哪儿,下一次再打 `/` 不该还认,那是人看不见的旧状态。名单跟刚才一模一样时干脆一次都不重画。3 条新断言(提示在/不在、重画选中不跑、没变不重画),6 处变异注进真代码,另加 2 条等价改写当对照,一条都没误报。其中「选中跨关了又开漏过去」那条,是原来那条反向对照先红了才发现的。
- **09-22** **打 `/` 挑个技能,回车一按,话就发出去了——而人还没写要它做什么。** 认 `/` 的那个监听挂在 capture 阶段,只 `preventDefault()` 就收手了;可管回车发送的那个监听挂在同一个 textarea 上,两个都在「目标元素」这一级,按注册先后挨个跑——前一个拦掉的是浏览器的默认行为(换行),拦不住后一个 JS 监听。**要掐断的是传播,不是默认行为。** 同一处还补了上下键:以前「选中」那一行全靠渲染时给第一行钉个 `.sel`,回车永远只拿得到第一个,想要第二个只能伸手去点——所谓「选择技能」在键盘上根本做不到。现在 ↑↓ 能走、走到头绕回来、跟着滚动。**另一件事:装完技能得刷新一下页面,`/` 里才找得到。** 那份技能名单只在开页面那一下拉过一次,之后再没人管它。只补在「本机点了安装」那一下是不够的——技能进来的路有好几条:技能中心装的、插件一包带进来的、命令行直接往目录里扔的、别人在同一台服务器上装的。所以改成「要用的时候顺手对一遍」:`/` 一打就去核一次名单(节流 3 秒,不然一个词能打十几次接口),哪条路进来的都算;加号菜单里的技能列表走同一份,插件装好 / 更新 / 卸载那几处不重拉技能的地方再显式对一遍。7 条新断言在真页面上跑,临时服务器顺带支起一个 `/api/skills`——往那个数组里加一条就等于「服务器上装了个技能」,然后看页面不重载认不认得。两条**反向对照**:把 `stopImmediatePropagation` 抹平(只动这一句,别的一字不改),同一下回车当场把话发出去;把「顺手对一遍」换成空函数,新装的技能就永远看不见。11 处变异逐条注进真代码(换成 `stopPropagation`、回车不看选中行、上下写反、走到头不绕回、节流拉到半小时、名单拉回来了不重画),另加 2 条等价改写当对照,一条都没误报。
- **09-22** **点侧栏「项目」那一行上的 +,只闪了一下,什么也没有。** 这颗 + 长在「项目」那一整行里面,而整行的动作是「打开项目管理页」。侧栏的点击是委托在 `.side-nav` 上、按 `closest(".item")` 认的,所以点 + 和点整行在它眼里是同一件事:主区切到项目页 → 重新拉一遍项目 → 把 `#proj-list` 整个重画——刚插进去的那个输入框当场被抹掉。**「闪一下」不是动画,是两个动作打架,后一个把前一个的结果盖掉了。** 顺手把新建的入口也换了:原来是在列表顶上插一个只填名字的输入框,工作目录、项目指令、挂哪块资料库当场都配不了,建完还得再进去补一趟;现在点 + 直接开项目页上「新建项目」那同一个编辑器。扫了一遍 `public/index.html`,侧栏里嵌着可点控件的行只有这一处,所以这个坑是独一份的。6 条新断言全在真页面上跑:起一个临时静态服务器加载真的 `index.html`,点真的那颗 +,看弹窗开没开、主区有没有被顺手切走;其中一条是**反向对照**——把拦冒泡那句摘掉、换回旧的就地插输入框,当场复现「闪一下就没了」。不加这条的话,上面几条只能证明「现在好使」,证不了「当初坏在这一句上」,也就拦不住它再坏一次。2 处变异逐条注进真代码(摘掉拦冒泡、退回旧写法),另加 1 条等价改写当对照,一条都没误报。
- **09-22** **手机上那排键,手指得贴着连点两三次才中。** 在 390 宽的屏幕上量了一遍:50 个能点的东西里有 9 颗任一边不到 36px——发送键 32 见方,附件、侧栏、模型选择器、顶栏那几颗全是 30 高。手指的接触面直径大约 8–10mm,落到 390 宽的屏幕上就是 40px 上下,30 见方的键意味着每一次点都在赌。**这不是「小了点」,是同一个动作有时管用有时不管用**——而人分不清是自己没点准还是应用没反应,只会觉得这东西卡。现在按 `pointer` 分档:触屏上两个控件高度令牌一起抬到 44,发送键 44 见方,顶栏「成果文件」「插队」、空屏上那两排(场景页签、下面的建议)都给到 44 高;行里夹着的那几颗(列表行尾的「更多」、分组头那颗 +)行高给不到 44,给到 40;chip 上那颗 × 只有 18 见方,chip 本身才 26 高撑不开,用负外边距把热区从 chip 里溢出来——看着还是 18,点得着 32。**分档按 pointer 而不是按窗口宽度**:桌面浏览器拉窄了仍然是鼠标在点,没必要为它牺牲密度;真正需要大热区的是触屏,而这件事只有 pointer 说得准。几何本来就全挂在那两个令牌上,所以这儿改两行,整套键一起长大,不用一处处追。量完再量:触屏档 0 颗不到 44、0px 横向溢出(键长大最怕的就是把版面撑出横向滚动),鼠标档一颗没动、也没有任何一颗小于 24×24(WCAG 2.5.8 那条底线)。15 条新断言不是读 CSS 文本,是起一个只喂 `public/` 的临时静态服务器、在 390×844 的窗口里加载真的 `index.html` 去量真几何;触屏那一档靠 CDP 打开触摸模拟——`Emulation.setEmulatedMedia` 压根不支持 `pointer` 这个特性,最早那版两档量出来一模一样就是栽在这儿,所以**「这一档真的是 coarse 吗」被钉成了一条先验料断言**:一个假前提能让下面每一条都绿得毫无意义。侧栏收起来、chip 还没出现的时候那几颗量不到,量不到就等于没测(第一轮变异正是从这儿漏掉两条),改成把真选择器要的那层壳搭出来、摆到屏幕外面量。12 处变异逐条注进真样式表(含「整段规则等于没有」「按窗口宽度分档」「发送键只长宽不长高」「常规档那个令牌忘了改」),另加 3 条等价改写当对照,一条都没误报。
- **09-22** **那只桌面宠物,默认是开着的——而桌面上什么都没有。** 后端三处写的都是「没配过就是关」(`server.js` 的 `enabled === true`、`pet.js` 的初始值、`electron-main` 读不到配置时的兜底),只有设置页那张卡画成了 `enabled !== false`:于是一个从没碰过这个开关的人打开设置,看见「显示桌面宠物」勾得好好的,桌面角上却空空如也——他会去查宠物为什么没出来,而不是去查这个勾为什么是勾上的。**界面替状态撒谎,比状态本身错更难查。** 顺手把开关搬出来:原来唯一那个开关埋在 设置 → 助理 那一屏往下滚的一张卡里,想让它出来陪一会儿、或者开会前让它消失,都得翻三层——**开关存在但找不到,等于没有**。现在右上角头像菜单里、紧挨着「语言」那行就是它,「开 / 关」两颗胶囊跟语言那行一个样式,点即切、菜单不关、原地翻;点下去先把界面翻过去再去存,存不下当场翻回来并弹红字——屏幕上停着一个服务端并不认的状态更糟:他以为关掉了,下次开机那只还在桌面上。纯服务端模式(`npm start`)压根没有桌面窗口,这一行整个不画:一个点了没反应的开关比没有更伤人,而设置页那张卡照旧在,那儿写得下为什么。这一行一个新词条都没往字典里加——标签本来就在字典里,「开 / 关」跟着 `data-i18n-skip` 走,英文下自动是 On / Off,i18n 那道 90% 覆盖闸门的分子分母一个没动。头像菜单那组断言从 29 条涨到 47 条(含反向对照:`available:false` 时哪怕 `enabled` 是真也不画、再点同一档不白跑一趟服务端、真开着的时候设置页那格确实勾着)。其中两条是把存盘卡在半路量的——**「请求发出去了、还没回来」那一帧**:少写一句 `p.enabled = next`、或者存完之前压根不重画,只看最后一帧的话照样全绿(存成之后整个 `settingsCache` 会被服务端那份换掉,最后一帧看着一模一样),这两条变异当初就是这么漏过去的。23 处变异逐条注进真源码,另加 3 条等价改写当对照,一条都没误报。
- **09-22** **Release 页不告诉你这一版改了什么。** 上面只有一份安装指南和一条 `Full Changelog` 的 compare 链接——站在下载页前面的人只想知道一件事:值不值得现在更新;而要回答它,得点进去翻二十个 commit。那句话其实早就写好了,就是 README「最新动态」里那几行人话,只是从来没被搬到发版正文上去。现在 `scripts/release-notes.js` 按 **tag 区间**去挖:上一个 tag 到这个 tag 之间,README 里**新增的**那几行,原样摆在正文最上面。按 tag 挖而不是按日期抓,是因为同一天发两个 patch 时,日期口径会把上一版的改动在这一版再印一遍(e2e 里那条断言就是拿两个真 tag 比有没有重复条目——写这条的时候它当场逮住脚本自己的一个 bug:`main()` 收了参数却还在读 `process.argv[2]`,于是两次调用挖出的是同一版)。挖不到就一个字不写:第一个 tag 前面没有可比的东西,CI 上万一是浅克隆也取不到上一个 tag——宁可退回「只有安装指南」,也别在发版正文里印一段来路不明的东西。发版这条链的闸门从 22 种退回加到 26 种,新增的四种全是这段会**悄悄变成空白**的路(脚本没了、算了却没摆进正文、正文那步压根不调它、release job 的 checkout 退回浅克隆);顺带把「checkout 得是全深度」这条按 job 切开各查各的——release.yml 现在有两处 checkout,整份一起 regex 的话,一边退回浅克隆另一边还是深的,那条照样绿。
- **09-22** **会话太长要先压一压,而压的那十几秒屏幕上什么都没有。** 压缩自己也要跟模型说一次话,而这一步正卡在「他按下发送」和「第一个字出来」中间:一声不吭的话,他看到的就是一个不知道在干什么的转圈,只能猜是模型卡了还是网断了(余量条上那句「下一轮开跑前会自动压一次」,反而让这个空白更难解释——说好了要压,然后就没动静了)。现在开跑先报一声:过程区里摆一行「正在把早前 20 条消息压成一份摘要…已等 8 秒(压完这一轮才开跑,原文归档不删)」。没有真进度可报,硬画一根匀速爬的进度条是骗人,所以只报两件能说准的事——在压什么、已经等了多久;秒数由过程区那根本来就在的 1 秒计时器带着走,不另开一个可能漏掉的定时器。**报了开头就必须有收尾**:压成了、模型这一发挂了、模型回了个空,三条路各带一条结果出去,把同一行的字换掉(不是再摞一行——摞一行的话,历史里会永远留着一句停在「正在压…」,看着像卡死在那儿);压崩了如实说是哪一句报错、说清早前的内容一条没动、并指一下去哪调预算,不许假装压成了。后端漏了收尾还有最后一道:这一轮结束时扫一遍,还挂着「正在压」的行一律收掉。`compact_start` 这条是转瞬即逝的,不进存盘清单——进了的话,回放老会话会重演一行「正在压…」,而那一刻根本没人在压。10 条端到端(含反向对照:没到阈值压不着的时候一个字都不许说)+ 25 条前端(其中 11 条在真窗口里量,秒数是量文本真的变了、不是量那个函数被调用过)。
- **09-22** **设置里那个「看图模型」,把本来就会看图的主模型挤掉了。** 这一路以前的判据只有一条——那个槽里填没填东西,填了就一律绕开主模型。真实配置里于是出现了这一幕:主模型和看图槽填的是**同一个型号**,只是走了两条渠道,同一个模型被硬拆成两份,多一把 Key、多一份限流额度;单配的那条一路 429 和超时,主模型这边一次就过。用户的原话是「文本模型我用多模态模型就没有必要用什么看图模型」。现在按设置页上一直写着的那句话走:**单配的看图模型,是给「主模型看不了图」的人预备的**。主模型自己会看图就直接用主模型,并在答案末尾交代一句「没绕到单配的 X」——绕过了他亲手配的东西却一个字不说,那条配置在他眼里就是凭空没了;同一个型号拆两条渠道的,认型号名不认渠道;`look_at_image(model: "…")` 点了名的一律照办。「会不会看图」只认 caps 里那个勾(设置页上他自己勾的),老配置没 caps 才退回按型号名猜,跟设置页下拉分组共用同一份 `capOfModel`——名字是层很薄的伪装,能问就别猜。勾错了也不让这张图白丢:主模型当场回 400「不支持图片」时,单配的那条自动顶上,并告诉他去哪儿把那个勾取消。设置页那格同样照实说是谁在看——主模型会看图时写「主模型自己会看图,直接用它 · N 个备选待命」,不说的话,在这儿挂了个模型的人会一直以为图都归它,而它其实一次请求都没接到过。13 条纯函数断言 + 6 条端到端(含 2 条反向对照:点名了就不许改投、没绕过谁就不许多这句话)。
- **09-22** **你拖进去让它看的那张图,转头出现在「本回合产出」里。** 附件是**先传后发**的,上传接口要拿会话 id 去认领这条对话的成果文件夹;而新开一条对话时,这个 id 要等到**按下发送**那一刻才生成——于是传图那一刻带过去的是 `null`,服务端既没处放,也记不上「待搬进去」那笔账,图就落在任务目录的**上一级**。agent 在自己的工作目录里翻不到,只好 find 一圈再 cp 一份进来;那份副本是这一轮新写的文件,于是他传进去的**输入**,被如实记成了产出。现在 id 在传附件那一刻就取,发送那一步改成按「左边列表里有没有这条对话」判断是不是新会话——取过 id 不等于列过。顺带一笔:任务文件夹名把发送时自动补进正文的素材锚点也当成了用户写的字,于是真实数据里躺着一个「任务_0921_图片1IMG8037JP」——序号和被砍了一半的扩展名占满 12 个格,他真正问的那句「这是什么」一个字都没进去;现在锚点先洗掉,只拖了图一个字没写的,拿文件名(去扩展名)兜底。
- **09-22** **发出去之后,刚才拖进去的是哪张图,界面上只剩一个文件名。** 输入框上面那排 64px 缩略图是发送前的事,按下发送就没了——气泡底下只剩一颗写着 `IMG_8037.JPG` 的回形针 chip,点不动;想看一眼自己发的是哪张,只能去文件库里按名字找。现在图片在气泡**上面**摆成真缩略图(跟气泡右边缘对齐,最长边 220px,一律走 `?thumb=320`,原图有 2800×7032 的,解出来 75MB),非图片的附件仍是气泡里那排带名字的 chip——图看画面、文件看名字。两者点一下都开右边那张预览卡,卡上有「下载」和「打开所在位置」,这才算真的**找得到**那个文件。路径三档兜底:上传那一刻服务端亲口说的那份最准,其次按会话目录拼,再不行按工作空间根目录——会话 id 那个 bug 修好之前传的图,物理上就躺在根目录,所以第二档失手会自动退到第三档再试一次,两档都读不出来才降成一颗写着名字的灰 chip,并把 tooltip 改成「这份素材读不出来了:可能已被改名、移走或删掉」,不给人看一个空灰框。前端 2223 条断言 / 63 组(气泡那组从 28 涨到 50,其中 7 条是在真窗口里量 `getBoundingClientRect()`:缩略图在气泡上面、右边缘对齐、220px 封顶、长宽比没被压扁、灰 chip 真能看见);17 处变异逐条注进真源码。
- **09-21** **按「引用」,输入框里多出 400 字别人的话;拖进来一张图,输入框里多出一行「【图片 1:xxx.png】」。** 这两样都是发给模型看的协议,却一直往人打字的那个框里灌:引完得先翻过自己引的那一坨才能接着写,图片那行删错一个字锚点当场就废。飞书、ChatGPT、Claude 都不是这么做的,现在改成同一套:**引用钉成输入框上的一张卡**(谁说的 · 两行封顶 · × 撤掉 · 点一下跳回原文,原文不在这个对话里了会说一声),在回复里拖选一段还会就地冒出「引用这段」——只引选中的那一截,而且选区得真落在这条回复里,在别处选的字不许记到它头上(界面上看着完全正常,引的却是别人的话);**图片变成输入框上面那排 64px 缩略图**(名字进 tooltip 和无障碍标签,底边一条序号),文件仍是带名字的宽 chip——图看的是画面,文件看的是名字。协议推迟到按下发送那一刻才拼进正文:开头一段 `> `、随后一行一个【图片 N:…】、末尾那句兼容清单,**发给模型的字节一个没变**,老会话回放出来不差一个字;人自己把锚点打进句子里的,位置以他摆的为准,不在开头再补一遍(补了的话同一张图在模型眼里成了两张,它会老实地拼出四格)。气泡里也把这两样折起来:开头的 `> ` 折成一张点得开的引用卡(三行封顶),素材锚点折成气泡底下那排(图片 / 视频 / 音频 / 摘录 / 文件各自的图标,一排全是回形针等于没分类),**写在句子中间的锚点一个字不动**——折掉的话「把【图片 1:a.png】放左边」会变成「把放左边」,而他发出去的原文其实是好的。引用的正文是模型吐出来的,两处都走 textContent,不进 innerHTML。前端测试 2176 条断言 / 63 组(引用 46 条、气泡折叠 28 条):气泡那段长在 createTurnUI 的闭包里,从真源码里整块切出来用 new Function 跑;折叠和两行封顶都是量 `scrollHeight > clientHeight` 的真裁剪——`-webkit-box` 在 flex 子项上计算值是 `flow-root`,直接断言关键字会看走眼。12 处变异逐条注进真源码,12 红,红的都是对应那条断言。
- **09-21** **想知道本机的 Claude Code / Codex 到底能不能用,得先切过去用它一回。** 整个设置页只有一条通道说实话——「测试连接」,可它长在展开区里,而展开区只对**已经选中**的引擎渲染。现在「试一下能不能用」挂在每一张装了的卡上,不选中也能当场试,全卡就一颗钮。徽章那边同样在替人下结论:`--version` 跑通就发一个绿的「已装 ✓」,可它只证明文件在——没登录、订阅过期、被限流,长的全是同一个绿;现在没真跑过只说中性的「本机有 2.1.278」,绿留给真跑通的那一次,测不通当场转红并写清楚下一步敲哪条命令。版本号顺手削成一个形状(`2.1.278 (Claude Code)` 和 `codex-cli 0.154.0` 在徽章上都只剩数字,标题已经写着产品名了,不说第二遍),原样那行连同启动命令行一起挪进展开区——`claude -p --output-format stream-json` 摆在折叠卡上,对着想用订阅的人说不出任何信息。测出来的结论记一份,保存设置重画一次不用再花 token 重测;点钮、点结论都不算「切引擎」,试和用是两件事。前端新增 29 条断言(含 4 条反向对照:钮不在展开区里 / 命令行没被删只是挪了 / 点卡片正文确实切得过去 / 红是量出来的颜色不是数类名),6 条变异按「改之前」的写法塞回去,全被对应那条断言当场拦住。
- **09-21** **「本回合产出」里冒出一堆在别处见过的文件名。** 文件没有串台,是卡片把一包东西拆开摆了:那一轮任务跑了它自己写的导出脚本,把整个仓库拷进任务目录,真落盘 124 个文件、其中 122 个都在同一个目录里;而卡片上只写文件名、不写目录,摆出来就是一排眼熟的名字,连字节数都跟仓库里那几个一模一样(本来就是逐字节的拷贝),真正做出来的那份行动方案反倒被挤到只剩一张卡位。判据两条一起看:这个目录这一回合收了 8 个以上的文件,且里面够格上卡的是少数派——缺第二条的话,一回合出 12 张分镜图的做图任务会被折成一个文件夹图标,而那 12 张恰恰是真产出。够格的整包换一张文件夹卡,只给一个打开文件夹的入口;下面的变更清单一条不少,122 个文件照旧查得到全路径——摊开的是卡片区,不是事实。顺带:文件夹的生死改成「里面还有活着的文件就算它还在」(名字永远不在文件清单里,拿 `alive` 判等于每来一条事件撤它一次),`README.en.md` 这种带语种后缀的也不再当交付物上卡。frontend 15 条断言,3 条是反向对照。
- **09-21** **手机配对的二维码里,那个地址是猜出来的,猜错了扫出来打不开。** 老做法是「翻到第一个私网 IPv4 就用」,而 `os.networkInterfaces()` 的顺序没有任何保证——这台机器上量过:真网卡是 192.168.1.84,代理隧道 198.18.0.1 排在它前面,连 `route -n get default` 指的都是隧道,所以「按默认路由挑」同样错。装了 Docker 或连着公司 VPN 的机器,172.17.x / 10.x 完全可能排在前面,编进二维码就是一个手机永远够不着的地址。现在按网卡排:物理口在前,隧道口、Docker 网桥、虚拟机口一律靠后,同一档按名字排死,免得每次刷新给的地址都不一样;挑法再准也可能挑错,所以一次返回最多 3 个候选、各自带二维码,界面上给一句「打不开?换一个地址」。那一屏也补上了三句人话:这串码干嘛用、这个地址哪来的、它什么时候打不开(换网络、用手机流量都打不开);一个局域网地址都翻不到时不再留白。顺手逮到的另一桩:6 处 `toast(…, "err")` ——第二个参数是图标名,`#i-err` 在 169 个 sprite 符号里查不到,浏览器不报错不警告,画一个 15×15、里面 0 个形状的空框,于是「复制失败」「踢不掉」这几句既没图标也不是红的。`test/icons.js` 新增一道闸,专扫从参数流进 `ic()` 的那一类(102 处字面量逐个对 sprite)。
- **09-21** **快捷键表上有一条,按下去只会弹一句「暂未支持」。** 19 条逐条在真 app 里过了一遍:2 条由输入框自己处理,16 条按下去真有事发生,1 条是死的——⌘D「语音录制开关」,整个函数体就是 `toast("语音录制暂未支持")`,前端压根没有任何录音界面。它在设置里跟其余 18 条排在一起,长得一模一样,用户没法知道哪条是真的。三处一起删(表项、动作、英文词条),那行「共 N 条」读的是表长,自己从 19 变成 18。闸门不靠正则扫源码,而是把两张真表解析出来对账,五种坏法各配一条反向对照:占位动作、空动作、只在表上没动作、只在代码里用户永远按不到、标成系统级却没在主进程注册。
- **09-21** **搜索只认 Jina / Tavily / Brave 三家,国内用户得先翻出去才能搜。** 现在是八家,默认国内优先:博查、智谱、七牛云,海外 Tavily、Serper、Jina、Brave,再加一路「自定义」——填个地址就能接自建的 SearXNG,或者接我没法逐条核实的那几家(阿里云 IQS、秘塔、火山)。配了几家就顺延几家,前面那家挂了自动往后走,最后才落到不要 Key 的免费通道;配额是先扣后退,被免费通道兜住的那次会退回去,账单上记的是真正出结果的那家,不是你在设置里选的那家。返回结果按**形状**认(几种已知的数组位置挨个试),厂商哪天多包一层,最坏是「这次没搜到」,不是整条 agent 断掉。免费兜底那条的超时从 30 秒压到 8 秒——它只是兜底,卡够 30 秒不如早点说没有。价格表里那几个数字照公开资料填的,没逐条核对厂商页面,这句话也写在界面上。
- **09-21** **跑到一半进程没了的那一轮,历史里永远转着「运行中…」,还找不到哪儿能停。** 回放是拿「回答」那条记录来收尾的;一问后面没有回答(服务重启、进程被杀),这一轮就没人给它画终点,标题上的圈一直转——偏偏这时 runningSessions 里根本没有它,界面上一颗能停的钮都找不到,只能重开。现在回放到末尾发现最后一问没人接,就按「断了」收尾:写「中断了 · 1 步」,标题上挂一句「没收到结束,这一轮是断的」。frontend 新增 3 条断言,含一条反向对照——正常收尾的还得是「已完成」。
- **09-21** **答过的岔路,每次打开这条对话都重新问一遍。** 回放历史时先给提问卡加了 `done`——那个类是拿来标「不能再点了」的;可「结论已经画上去了」用的判据也是它,画结论那一步于是被自己人拦住。一条早就选完的岔路,隔天打开还是「有个岔路,想让你定一下 / 这是历史记录里的提问」,看着像卡在那儿等人回答。两件事拆成两个标记之后,同一条对话回放出来是「这个岔路你定过了 · 你选了 投资决策参考」。顺带量了一下最早的猜测(回放动画太慢造成的错觉):整段回放 21 毫秒,跟它没关系。frontend 新增 4 条断言,含一条反向对照——没答过的那张不许编出个答案。
- **09-21** **刚注册一个账号,侧栏里躺着的是前任所有的对话。** 升级上来那批老会话没记归属,而「没记归属」以前一律当「公共的」——本意是别让历史丢了,做出来却是新建一个 demo 账号,一打开满屏都是别人的任务。现在它们认到这台机器上第一个注册的人名下(账号体系还没有那会儿,坐在这台机器前的就是他):他的历史一条不少,新账号的侧栏干干净净。空壳会话照旧放行——前端是先发 id、再发第一句话的,拦了等于谁都开不了新任务。e2e 正反各钉一条 ★。
- **09-21** **资料库是整台机器共用的一份,谁传进去别人都看得见。** 以前只能按「谁的东西」拦:写拦得住(非管理员那儿挂「只读」角标),读拦不住——每个人的 agent 都带着 library_list / library_read,一句「翻一下资料库」照样把别人的合同念出来。现在换成一人一个根:老库原地不动、还归第一个注册的人(一个字节都不搬),其余账号各自一份、用到才建。写闸跟着撤了——根都分开还拦写,等于给成员一个自己的空目录什么也放不进去,比原来更难用;界面上那副「共享资料 · 只读」的面孔也一并拆掉。tenant 498 过 / 0 挂,8 个变异体全拦下。
- **09-21** **换了个账号,宠物和通知渠道还是上一个人的。** 引擎、宠物、快捷键这些本来就该谁用谁的,却一直只有 config.json 一份。现在按账号存,请求进来时跟工作区、配额、策略一起挂上。「个人桌面版」那条短路(一切照旧读 config)从两个条件收紧成三个:Electron 壳 + 只听本机 + **这台机器上只有一个账号**——同一台 Mac 上开了两个号,这话就不成立了,再走短路等于小张能改老板的 Key 和 MCP。
- **09-21** **想改自己的密码,只能去找管理员。** 头像菜单加了「修改密码」:验旧密码,改完把别的设备踢下线。密码要求那句话是服务端按组织策略回的,前端不抄第二份——抄了的下场是管理员改完策略,这儿还写着「至少 6 位」。
- **09-21** **渠道我修好了,AI 还在说「用不了」。** 本地熔断闸原来只有三条自愈的路:配置动了、设置页按了保存、熬过 30 分钟冷却。可用户修的是渠道那头(充值、续费、把网弄通),设置页一个字没动,指纹也就没变——三条全落空,只能干等。现在加第四条:**人重新开口就整个放开一次**。光放开还不够——上一轮那句「别再调这个工具了」还原样躺在对话历史里,模型照着它继续拒绝,用户看见的还是「用不了」;所以刚放开的那几条会写进这一轮的提示词,明说那句过期了、该调就正常调,不许一个请求都没发就先下结论。代价是最多多发一次请求。
- **09-21** **链接后面凭空多出「<strong>」几个字,点下去还跳错地方。** 裸网址转链接这一遍排在加粗前面,于是 `**https://…/abc**` 收尾那两个星号被当成网址吞进了 href,加粗那一遍再往 href 中间插一个 `</strong>`。把裸网址挪到最后转,这条路就断了——那会儿 `**…**` 早成了 `<strong>…</strong>`,网址两边干干净净。顺带两处:标签内部整个跳过(`<img alt="见 https://…">` 这种**属性里**的网址以前会被撑破),末尾的右圆括号成对的留、落单的剃(维基、飞书那类 `.../Foo_(bar)` 少剃一个字符就跳去另一个页面)。
- **09-21** **打不开这个应用的人,看见的是一整页中文。** 跟下面删除确认那条同一个根因,只是更往外一层:右键菜单、启动失败页、两个系统报错框,全是主进程里的 JS 字符串,一秒钟都没进过渲染进程的 DOM,网页那套翻译根本够不着。右键菜单 8 条在英文下条条是中文;更要紧的是启动失败页——看见它的恰恰是应用打不开的那个人(issue #1 那批),最需要看懂上面写的怎么修,给他的却是一整页中文。壳里现在单带一本字典(中英各 29 条):语言先问渲染进程存的那份偏好(`owb-lang`,跟网页同一个键),问不到——或者窗口压根就没建出来——才退回系统语言;启动失败页正是后一种时候要画的东西,它的 `<html lang>` 也跟着走。闸门按**形状**比两本字典(键对齐、英文那本里不许剩汉字、不许两边一模一样),再把右键菜单和六种死法各跑一遍;反过来还扫那四段代码里的字符串,谁再写死一句就报。e2e 新增这一条,5 个变异体全拦下。
- **09-21** **画布上那张「短剧分镜」,在下拉里叫「新笔记」。** 12 种节点里,`canvasDefaultPayload` 漏了 storyboard 那一支,它于是掉进 default 分支,拿到的是笔记的 payload。卡面上看不出来——那句「短剧分镜」是写死的——可「连接到下游节点…」那个下拉里它叫「新笔记」,交给 Agent 的正文也是「记录灵感、任务或需要补充的内容…」;起手模板铺出来的那张就是这样。补上初值,另加一道按**形状**比的闸门:节点类型表和 case 表是两份名单,对不上就报(note 不算,它本身就是 default 分支)。把那一行删掉,e2e 当场红在这条断言上。
- **09-21** **英文界面下,每按一次「删掉」,弹出来的都是中文。** 全站 31 处删除确认走的是原生 `confirm()`,而翻译是照着 DOM 走的——原生框里那句话从头到尾只是个 JS 字符串,一秒钟都没进过 DOM,所以连「扫一遍界面看还剩几个汉字」那道闸门也发现不了。同一个根因还欠着两笔:浏览器那边用户一旦勾上「不再显示对话框」,`confirm()` 从此静默返回 false,每颗删除钮当场变哑巴(跟当初 `prompt()` 那个「点了没反应」是同一种长相);原生模态框离屏点不动,于是这 31 条删除路径一条都没验过。现在全换成自绘的框:词典补 59 条 + 15 组模式句(其中一组按 8 类名词展开),红钮上写的是动词(删掉 / 卸载 / 解散 / 踢掉 / 下架 / 恢复默认),焦点落在「算了」上,要删哪几样一条条列出来——清单封了高度、自带滚动,顶出屏幕的话连「算了」都按不着,那比没有确认框更糟。闸门认的是**选项对象的形状**,不是「写在 askConfirm 的括号里」,就这一下多逮到两处漏网:手填工作区路径那个框,和批量删自动化任务那处转手递进去的选项。这道闸扫的是整个 public/js,企业后台也在里面——它今天用的是自己画的框,但没人拦着它哪天随手写回 confirm()。test/confirm-dialogs.js 25 过 / 0 挂,14 个变异体全拦下。顺带删掉 library-mkdir 里一条被推翻的结论:「confirm 不抛,所以全站确认框不用改」——测量还成立,结论早就不成立了。换完之后,两套老测试自己先露了馅:它们的替身还停在 `window.confirm`,源码里那句 `askConfirm` 于是成了 ReferenceError——而它抛在 async 处理函数里没人接,「点了取消就一条请求都没发」照样绿。补了一条正向对照:同一颗钮点「确定」得真发出去,这条假绿才站不住。
- **09-21** **新建完一个文件夹,找不到地方删。** 删除只在「列表」这一种摆法里活着——图标和画廊两种摆法上写着 `display:none`,搜索那条路压根没画这颗钮。三种摆法现在都有(图标 / 画廊挪到格子右上角),搜出来的那份也删得掉;站在文件夹里面时,「删掉这个文件夹」就摆在「新建文件夹」旁边——建它和删它是同一条操作条,删完退回上一级。本地产物照样不给这颗钮:那是任务在工作目录里写出来的。顺带把非空文件夹那条死路接上——那颗钮原来叫「知道了」(你知道了,然后呢),现在叫「进去清空」,按下去就进到那一层。test/library-mkdir.js 85 过 / 0 挂(原 65),9 个变异体全拦下。
- **09-21** **工作台切成 English,点进企业管理后台还是满屏中文。** 这个后台从头到尾没引过 i18n.js——19 个面板、538 处界面文字一条没翻。词典补 494 条 + 28 条带数字日期的模式句,侧栏底下加了中 / 英切换(跟工作台共用一份偏好,在哪边切另一边也跟着变)。**用户自己起的名字不翻**:组织名、部门名、渠道名、模型名是数据不是界面,翻了等于把人家的渠道给改了名。数字也跟着语言走(1235 万 / 12M),切语言是把当前页整个重画——「万」和千分位是渲染时算出来的,翻 DOM 翻不到。新加一道闸:切成英文把 19 页全走一遍,DOM 里但凡还剩一个汉字就算漏;现在剩 11 条,条条对得上用户起的名字。admin-ui 145 过 / 0 挂(原 134),7 个变异体全拦下。
- **09-21** **手还按在卡上,同步来一趟,卡自己弹回原处。** 跟上一条同一个根因:铺快照是 graph.clear() 整图重来,正在拖的那张当场被拆掉,手里还按着、位置回到了起点。「同步给打字让路」这条现在推广成「手上有活就让路」——打字、拖卡都算,时效从最后一下动作算起(不是从按下去那一刻,有人对位置能磨蹭半分钟),拖出窗外撒了手也不会把同步卡死。test/canvas.js 58 过 / 0 挂(原 52),11 个变异体全拦下。
- **09-21** **正打着字,同步来一趟,刚敲的半句就没了。** 属性面板是整块重画的,重画一次输入框就换了新的一个,光标掉回 body,接着敲的字进了空气,节点里的文字也被对面那份盖了回去。现在同步会给打字让路(手停 10 秒才补上,免得焦点留在框里走开、这个标签页从此再也不同步),面板自己重画时也把光标放回原来那个字上。test/canvas.js 52 过 / 0 挂(原 47),7 个变异体全拦下。顺带修了一条会随机挂的测试:隐藏窗里那个 confirm 的框有时被 Electron 直接收掉,判据从「挂没挂」改成「抛没抛」(prompt 抛、confirm 不抛,同一扇窗里对比)。
- **09-21** **删掉的连线,同步一下、重开一次、按下撤销,都会自己回来。** 两处本来都是护着老画布的:「对面没有连线就沿用我这边的」,和「一个镜头 + 一个起过名的场景就替它补上线」——可「没有连线」也可能是人刚把线删了。现在存盘时标版本 2(连线是照实记的,空就是空),版本 1 的老文件照旧护着、照旧补线,他删一下就升成 2。顺带修了 v0.7.4 发版挂掉的那条画布测试(写死等 2.3 秒,而同步一圈 1.8 秒、撞上正在写盘会整圈跳过),所以 v0.7.4 没出安装包。test/canvas.js 47 过 / 0 挂(原 40),7 个变异体全拦下。
- **09-21** **删掉的画布会借尸还魂,清空的画布自己长东西。** 删画布只删服务器那份,本机副本按画布名留着——再建一张同名的,删掉那些原样长回来,还会被存回服务器。起手那两张卡(一句话概念 + 分镜表)的判据是「现在是空的」,于是用户自己清空的画布每打开一次就长回来两张,换台机器打开也一样。现在删画布、新建画布都把本机那份副本一起清掉;起手卡只给「从来没人动过」的画布——新建出来的 `updatedAt` 留 0,之后任何一次保存(清空也算)都盖上时间戳。test/canvas.js 40 过 / 0 挂(原 30),18 个变异体全拦下;服务端那半边另有 2 个变异体,也全拦下。
- **09-20** **换个项目打开,画布上是上一个项目的东西。** 本机那份副本的键上只有画布名,两个项目的 `main` 共用一格;铺上去之后还会存一次盘,把新项目自己的画布顶掉。切画布同理:存盘攒 240 毫秒再发,发的时候才去读「现在是哪张」,旧内容就落到了新画布名下。现在键上带项目名(老版本存的那份只认领一次)、切之前先把欠的那趟写完、写出去之前再核一次「这份是写给谁的」。test/canvas.js 30 过 / 0 挂,同一份测试放到 v0.7.2 上挂 8 条,11 个变异体全拦下。
- **09-20** **无限画布三处静默丢数据。** 标题叫「开始工作」「开始创作」的节点,加载和同步时一律不铺、连着的线一起扔——可代码里从来没谁造过这两个标题的卡,能撞上的只有用户自己起的名字;删完还顺手存一次盘,本机和服务器那两份一起变瘦(三个节点两条线进去,剩 1 个节点 0 条线)。同步拉回来的快照,铺完又原样发回服务器,而服务端每写一次就把时间戳换成现在,于是两个标签页每 1.8 秒互相顶一轮、各拷一份 .bak,谁都没动过画布。再有一趟同步把多选砍成一个:框选 3 个之后只剩 1 个还选着,下一下 Delete 删掉的就不是你以为的那一片。画布这 2462 行原来一条测试都没有,新写 test/canvas.js:修之前 6 过 / 9 挂,修完 16 过 / 0 挂,6 个变异体全拦下。
- **09-20** **英文界面上,资料库整页是中文——v0.7.0 的安装包也因此一个都没出。** 发版卡在测试那一步:CI 那台机器的系统语言是英文,界面照英文渲染,而断言是照中文文案写的。顺着查下去才是真问题——这一页整页没进词典,英文用户看到 22 段中文正文 + 15 处中文属性,连「新建文件夹到底有什么用」那段说明也是中文。词典补 59 条 + 11 条带数字和文件名的模式句;空状态改成一句话占一个文本节点(`<b>` 把句子劈成两半,英文那边词序接不上)。全站那道覆盖率闸门按百分比算,一页全漏也摊得平,所以另加一道:把页面渲染出来切成英文,数屏幕上还剩几个汉字,用户自己的文件名先抠掉再数;开真页面的测试不钉语言直接不给过。资料库 65 过 / 0 挂(原 57),拆掉钉子在英文机器上当场挂 8 条。
- **09-20** **资料库现在说得清「新建文件夹」是干嘛的,也能删了。** 这一页原来把「你传进来的参考资料」和「任务写出来的产物」混在一起摆,而新建 / 上传两颗钮浮在两段的最上面,人自然以为它们管下面全部。现在两段分开,钮挪进「参考资料」那一段;空状态也直说:项目设置里只挂其中一个文件夹,这个项目的 AI 就只看得见那一块,不会翻到隔壁客户的材料——建文件夹是给 AI 划视野,不是给人归档看着整齐。文件夹和资料各挂一个垃圾桶(产物那段故意没有),确认框焦点落在「算了」上;文件夹里还有东西就不给「删掉」这颗钮,直接说清还剩几样、一条请求都不发。顺带把 Electron 那三个原生框实测了一遍:`prompt()` 一调用就抛(v0.6.12 那个「点了没反应」就死在这儿),`confirm()` / `alert()` 挂在原生模态框上等人点——对用户好使,但离屏测试点不动,所以新写的删除走自绘的框。测试里那条拿 `typeof` 证明 confirm 能用的断言也换成真调一次。57 过 / 0 挂(原 36)。
- **09-20** **企业后台还剩三处回包是按人头长的:678 / 491 / 631 KB → 11 / 12 / 9 KB。** 用量明细每趟捎带一张「按人分组」的汇总(3000 人时 205 KB 的回包有 195 KB 是它,而这一页画的是流水);中转 Key 页捎带「每人单独的 API 上限」那张表(631 KB 里 620 KB 是同一行重复三千遍);数据统计只要「几个人」这一个整数,却把全员的角色、额度、余额都算了一遍,还翻了一趟用量账本。成员用量和每人上限各拆出一条接口,一页 50 个,筛排翻页全在服务端;分组表截到前 20 / 50 并带上真实组数,不然「二十」会被当成「全部」。这两张表**故意不按花名册排**——它们回答的是「钱花在谁身上了」「谁的闸子要动」,按名册排的话相关的人散在六十页中间。「本月花了多少」三处口径钉死:充值不算花销。多租户 485 过 / 0 挂(原 435)、后台界面 134 项、中转站 218 过,15 个变异体全被拦下——第一轮有 4 个活口,也就是那四条断言在骗人(账本里没造过充值、归属校验只判状态码、额度见底只在不筛时比过、十个人正好一页装得下边界没跨过),补完才满。
- **09-20** **企业后台的成员页,是把整份花名册甩给浏览器、让它自己筛。** 一屏看得见十几行,而回包里装的是这家公司的每一个人:角色、部门、状态、余额、最后活跃,一个不少。实测 3000 人的组织,点进成员页那一趟是 **1041 KB**,浏览器里画出 **3002 行、78098 个 DOM 节点**,从点进来到表格出来 **878ms**;而这还只是成员页。同一份整份花名册另外还被捎带在两个地方:管理员角色页每次 **1042 KB**(为了画一张十来行的管理层名单),用量明细页每趟都带一份,于是 `?limit=` 根本缩不小回包——`limit=20` 是 **682 KB**,`limit=1` 还是 **678 KB**。现在筛、排、翻页全挪到服务端,一页 50 个人:3000 人时回包 **1041 → 17 KB**、DOM 节点 **78098 → 1403**、渲染 **878 → 38ms**、后端 18.8 → **12.2ms**;1000 人 346 → 17 KB、259 → 28ms;300 人 104 → 17 KB、90 → 22ms。搜一个字(含一整趟请求)3000 人时 **57ms** 出 52 行。角色页 1042 → **48 KB**(只回管理层名单,加一份**只有名字那五格**的候选人下拉,超过 500 个就截断、并且明说截断了——不然界面上「下拉里找不到那个人」会被当成他不存在);用量明细页的花名册改成按需捎带,682 → **200 KB**。这里头有两条顺序是看不见、但一破就悄悄退回从前的:**排序必须在切页之前**(不然「第一页」取决于人在账本里的物理顺序,今天谁排在前面取决于谁昨天改过资料),**算钱必须在切页之后**(每个人都要算角色额度余额、还要翻用量账本查最后活跃,六百个人算完只显示五十个,前面那些全是白算的);档位下限同理,得在**原始账号**上就把人筛掉,而不是算完再扔。地址栏里手改的 `?limit=99999` 只给 500,`limit=0` / `limit=-5` 当没传回默认一页(原来会被夹成 1,界面上变成「一页一个人、六百页」),翻过头退回最后一页而不是给一张空表(空表跟「这家公司没有人」长得一模一样)。**顺带修了一个只有真去敲键盘才量得出来的坏法**:这三页的搜索框,打完一个字、数据回来之后光标就没了——`route()` 每次都整页重画,搜索框那个 DOM 节点被扔掉,焦点落回 `<body>`,接着打的第二个字直接进了空气。实测重渲染后 `document.activeElement` = BODY、下一个字进 BODY;修完是「光标还在框里、字停在原处、下一个字进搜索框」,成员 / 用量明细 / 操作审计三页都验过。另外量过一次骨架屏闪动(用量明细 1 帧 / 19ms、审计 0 帧),没量出收益,就没动。多租户套件 **435 条断言过 / 0 挂**(原来 367 条),企业后台界面测试 **107 项通过**(原来 88 项),**19 个突变体全被拦下**——包括「排序挪到切页之后」「最后活跃还按整份查」「limit 不夹上限」「翻过头给空表」「首页又捎带整份」「重渲染之后不把光标放回去」。**还没做完的**:「按人」那张用量表还是一人一行(3000 人的组织那一趟仍是 678 KB),用量明细页那个「看谁的」下拉也还是 3000 个 `<option>`(约 197 KB)——那两处要的是搜索框,不是下拉框。
- **09-20** **企业后台的「办离职」按钮,点下去什么都不发生。** 办离职是这套后台里最像「企业功能」的那一个——把权限一次关完、把在跑的排期转给同事、留一条审计。按钮在成员页上摆得好好的,后端那条接口是好的,`lifecycle` 套件全绿,但**点它没有任何反应**:点击处理函数里读了一个只在渲染函数里存在的变量(`shown`),于是点一下就是一句 `Uncaught ReferenceError`,只报在 console 里——界面上一点动静都没有,人只会以为网慢,点第三下之后去别处想办法。19 个面板各渲染一遍抓不到它:渲染是对的,坏的是点下去那一下;后端测试也抓不到:测试打的是接口,没人点过那颗按钮。修法是一行,顺带把语义也修对了——交接人选本来就该从**整份在职名单**里挑,而不是从当前筛出来的那几行里挑。为了让这类坏法不再只能靠人点出来,企业后台的界面测试加了一道闸:19 个面板逐个进去,每一类按钮真点一下,页面里挂着 `error` / `unhandledrejection` 收集器,点完比对有没有新错。**一共点了 42 颗,抓到 1 颗。** 复制类按钮不点——它写的是系统剪贴板,跑一次测试把人正在用的剪贴板冲掉,这个代价不能收;导出类按钮的下载动作被换掉,否则 Electron 里会弹出保存框,没人点就一直挂着。「办离职」另外单独再验一遍:不光是「没报错」,得真把那张对话框弹出来,且交接下拉里列的是**别的在职同事**(不含正在办离职的那个人——把任务交给他等于没交接)。企业后台界面测试 88 项通过 / 0 挂(原来 84 项);把那一行改回去,这道闸立刻变红,报的就是 `members/data-off:Uncaught ReferenceError: shown is not defined`。
- **09-20** **平台那张组织列表,是一家一家去查成员列表拼出来的。** 每家公司只显示两个数字——几个人、几个在用——而背后调的是给成员页用的那个函数:它要算每个人的角色、额度、本月剩余、余额,还要为「最后活跃」翻一遍用量账本。实测:11 家公司 18.7ms,31 家 59.0ms,61 家 **159.0ms、读盘 35.6 MB**(换来一张 38 KB 的表),121 家 **388.4ms、98.3 MB**——读盘量是公司数的平方。守着它的是一句现在已经不成立的注释:「组织数量是个位数,不值得为它做索引」,而这个产品现在是按多租户卖的,这一页正是平台管理员开后台第一眼看的东西。现在整本账数一遍,剩下的都是内存里的加法:61 家 159.0 → **2.8ms**、35.6 → **0.5 MB**;121 家 388.4 → **5.4ms**、98.3 → **0.9 MB**;用量账本**一遍都不用翻**(原来 61 遍)。数人头有两个容易错的地方,各钉了一条断言:停用的人**照样算人头**(席位是按人头卖的,剔掉就是少收钱),没有 `status` 那一格的老账号**当在用算**(跟成员页那边的默认值必须是同一个,否则同一家公司在两个页面上显示两个不同的在用人数,谁也说不清哪个是真的)——最后一条断言干脆拿两处的数直接对。367 条断言过 / 0 挂;29 个突变体全被拦下。
- **09-20** **每条请求的「进门费」:干正事之前先把整个平台的账本翻七遍。** 登录闸 + 租户作用域这段路,每个请求都要走一遍:认人、判登录有效期、强制二次验证、远程设备开关、租户作用域。它把 `users.json` 读 **3 遍**、`orgs.json` 读 **4 遍**——而这两本装的是**整个平台**的账号、所有还活着的登录令牌和全部公司表,跟这条请求要干什么一点关系都没有。实测一条什么都不做的接口:5 人的装机 0.52ms,300 人 / 900 个令牌 / 20 家公司 4.16ms,1000 人 / 3000 个令牌 / 60 家 **13.18ms、读盘 2.36 MB**,3000 人时 **39.12ms、7.1 MB**。聊天页是几秒一次轮询的,于是「公司人多了之后整个产品变慢」跟谁在用没关系。现在一趟请求两本各读一遍,解析好的组织和设置顺手挂在请求上给下游用:13.18ms → **4.84ms**、2359 → **782 KB**;3000 人 39.12ms → **13.93ms**、7115 → **2359 KB**。记活跃那处的 5 分钟节流以前是**先无条件把整本 users.json 读出来再判**——省下的只有写,没省读,而在这条路上读才是贵的那一半;改成拿手上这份判,真要写了才重新读一遍(拿请求开头那份盖回去,会把这中间别处写的东西抹掉)。判据用「翻了几遍」不用「花了几毫秒」:毫秒在慢机器上会飘,次数不会。**一处行为变了**:远程设备开关以前自带 `try/catch → false`,于是「`orgs.json` 读坏了 + 这个人已经开了二次验证」这个组合下,请求会被**静默放行**;现在这种情况直接 500——两本账读不出来的时候,宁可挡住也别放。登录有效期那处照旧:组织表读不出来退回默认 90 天,不会把一次读盘失败变成 500。357 条断言过 / 0 挂;25 个突变体全被拦下,其中 11 条专盯这次改动:三处「又自己去读一遍」、「设置变成空的」、「有效期不认组织设置」、「节流撤掉」、「拿请求开头那份盖回去」、「租户作用域没挂就丢租户」,以及强制二次验证和远程开关这两道闸改从同一份设置读之后还灵不灵(这两条分别拿 `auth-2fa` 和 `remote` 套件判)。
- **09-20** **企业后台的成员页,快慢取决于平台上又开了几家公司。** `publicUser` 给每个人算三格(月额度 / 本月剩余 / 余额),这三格各自去 `org.getOrg()` 读一遍 `orgs.json`——一个人三遍,而 `orgs.json` 里装的是平台上**所有**公司的数据。实测:500 人的成员页把 `orgs.json` 读了 **1500 遍**、搬 1302 KB 进内存,一次 28.69ms。更难受的是自己这边一个字没改的情况——同样 50 个人的页,平台上 2 家公司 5.6ms、21 家 16.8ms、101 家 76.1ms、501 家 **365.6ms**:慢的不是你自己的数据,是隔壁又来了几家。组织设置在这一趟里根本不会变,现在整张表只读一次:500 人 28.69ms → **1.36ms**(读取 1500 遍 → 1 遍),50 人的页在 501 家公司下 365.6ms → **2.7ms**。省掉的只是读取不是判断——传下去的必须是**这个人自己组织**的那份设置(列表已经按组织筛过了),单独给某个人设过的月额度照旧盖得过组织默认值,`publicUser` 单独用在一个人身上时仍然自己去读。判据用「`orgs.json` 被读了几遍」不用「花了几毫秒」:毫秒在慢机器上会飘,次数不会。346 条断言过 / 0 挂;14 个突变体全被拦下,其中两条专盯这次改动最容易踩的错法——「读一遍是读了,读的是别人家那一遍」和「顺手把判断也省了,个人额度被组织默认值盖回去」。
- **09-20** **一个租户的日常操作,能把另一个租户的审计记录整个挤掉——而且看上去像「那阵子本来就没人动过」**。全部组织的审计条目挤在 `orgs.json` 里**同一个数组**,存盘时 `slice(0, 1000)`。实测:乙公司记下 21 条,甲公司之后正常运营记了 1200 条,乙公司那 21 条**一条不剩**,后台显示「0 条」——跟「这个组织从来没发生过事」长得一模一样,而且没有任何提示。乙公司什么都没做错。第二条病跟它是同一条病:审计流水躺在热路径上,`getOrg()` 有 37 处调用,每次都要把整本审计连同组织数据一起 parse 一遍,实测一次 `getOrg()` 在审计 0 条时 0.02ms、1000 条 0.91ms、50000 条 **45.57ms**——封顶只能定在 1000 就是被这个逼出来的,翻译过来是「为了不拖慢每个请求,只好把合规记录删掉」。现在一个组织一本:`data/audit/<组织 id>.jsonl`,一行一条往后追(写一条是 O(1),不再整本读出来改一下再整本写回去),封顶**每个组织 5000 条**,隔离是靠分文件不是靠一句过滤,谁也挤不掉谁。`getOrg()` 从 45.57ms 回到 0.02ms 且跟审计多长完全无关,`orgs.json` 掉到 1730 字节。老装机第一次启动自动搬家,**覆盖式**写,所以上一趟搬到一半崩过、重来一趟也不会把同一批写两遍;文件 0600(这本里是「谁在什么时候放行了哪条命令」,跟 `users.json` 一个待遇);断电断在半行上只坏那一行,不是整本读不出来。界面上两句假话一起改了:副标题原来写死「这个组织建起来到现在的全部管理动作」,而审计明明有保留上限——现在存满了改口说「最近 N 条(已到保留上限,更早的已被挤掉)」,并摆一条写明上限是多少条、现存最早的一条是哪天、下一步该导出存档的提醒;导出按钮原来只导屏幕上这 50 条,合规的人筛完一个月、页脚写着 5000 条,得一页一页导 100 次——现在按当前筛选分批把全量拉下来(实测一次导出 5012 条,导出中按钮禁用,完事自己恢复)。339 条后端断言 + 84 条真浏览器断言过、0 挂;10 个后端突变体和 4 个界面突变体全被拦下(原子写那条留着标成「已知测不出」:原子性要断电才看得见,留着是提醒别以为测全了)。
- **09-20** **读 Office 文档的九个静默错漏:表尾整行丢、公式一片空白、原生图表读回来是空页**。原来的测试只喂过一张密实的矩形表——没有空行、没有公式、没有合并格、没有稀疏列,于是下面这些全是绿的,但凡换成真实报表就错。Excel 那头是 exceljs 的计数陷阱:`actualRowCount` / `actualColumnCount` 是「非空行/列的条数」,不是末行/末列的下标,中间空一行当间隔,写进去 6 行读出来 5 行,丢的正好是「合计」那行;更糟的是 `truncated` 还报 false,数据少了却告诉上层「没截断」,模型当成事实全的用。公式格读回来是空串(exceljs 不算公式也不写缓存值),现在至少给出公式原文 `=SUM(B4:C4)`,是真话。合并格原来把主格的值复制进每个被盖住的格子,A1:D1 的标题横着重复四遍,模型会当成四列数据。PowerPoint 那头,用 `addChart` 做的页读回来整页是空的——而 `skills/ppt-design` 正推荐用 addChart;现在顺着 graphicFrame → 幻灯片 rels → `charts/chartN.xml` 读缓存值,按 `c:pt` 的 idx 对齐(idx 会跳号,按文档顺序推会把分类和数值错位);插图的页同样一个字没有,现在标[图片]并带上替代文字。Word 那头,有序列表和项目符号读回来都是「-」,「第三条写的什么」直接答不了,现在顺 numPr → num → abstractNum → lvl 的 numFmt 真数出 1. 2. 3.;超链接的地址整个丢掉只剩锚文本;页眉页脚从来不读——「内部资料 请勿外传」这类话正好写在那儿。顺带堵一个口子:`.docx` 常常是外面发进来的,里头写一句 `javascript:` 的超链接完全合法,预览面板照单渲染就等于给了它一个可点的入口,现在只认 http/https/mailto。写这头同步改了 `skills/excel-report`:公式必须同时给 `result` 缓存值,否则生成的报表在网页预览、`read_document`、别人手机上点开,合计那一列全是空白。368 过 / 0 挂(office-tools)、45 过 / 0 挂(preview-layout),都带反向对照;13 条变异 13/13 全被抓到。
- **09-20** **本地连绿三轮、流水线上红一次:附件那段测试在等时间,不在等条件**。v0.6.11 打完 tag,CI 挂在一条断言上:「拖进来的文件按原名上传:粘贴文本_0920_070258.txt」——名字里还带着 runner 当时的时间戳,看着像拖拽功能把 `笔记.md` 改了名。一个字节都没改。那一段的前七小节等的是固定的 40ms,而 `uploads` 是一路累加的数组:读文件要过一遍 FileReader,GitHub 的机器比本机慢,40ms 内还没读完,`uploads.at(-1)` 拿到的就还是上一小节粘贴的那份 txt——断言于是拿上一段的附件去比这一段的文件名。这段测试自己的注释里早写着「一律等条件,不等时间」,规矩立了,前七段没照做。现在整段没有固定等待:每一条都等自己那次上传落地;反过来的断言(「短文本不该当附件传」)也留出真实窗口去等那个不该来的请求,等不到才算数——只等一拍就下结论,证明的只是「现在还没传」。50 条断言过、0 挂。对照实验:给 `readAsDataURL` 加 200ms 延迟,修之前那份**原样复现**流水线上那句话(只有时间戳换成了本地时间),修之后照过;只延迟那个 `.md` 文件的读取,连挂在哪一条都一样。
- **09-20** **启动失败页上写着「把这行贴到 issue 里」,而那一页恰恰是右键复制不了的一页**。右键菜单和「外链交给系统浏览器」这两根线挂在 `require("./server.js")` 后面,可启动失败时那句 require 就是抛出点——它一抛,后面一行都不执行。于是页面上写着「把下面这行贴到 GitHub issue 里」「贴 issue 时带上启动日志」,用户选中那串路径按右键,什么都不弹,只能对着屏幕手抄;页面右下角那个「提 issue」也不去他自己的浏览器,而是在应用里另开一个没有地址栏、没有登录态的 Electron 窗口。这是这个文件第三次栽在同一件事上——3 秒兜底亮窗和 20 秒看门狗当初都是为了同一个理由挪到 require 前面去的,注释里写得明明白白,这两根线漏了。现在一起挪到建完窗口就挂。顺带把那条显卡建议改成给出 `config.json` 的**真实路径**:原来写的是「在用户目录的 OpenWorkBuddy/config.json 里」,而一个已经卡在门外的人得自己去猜 Windows 和 macOS 的用户目录分别在哪;算不出路径时退回一句话,不是 `undefined`,更不能连这块最后的告示牌一起炸掉。377 条断言过、0 挂,6 个突变体全被拦下:两根线挪回 require 后面(拿修之前那份原文当突变体)、右键不再给「复制」、链接那条不给「在浏览器里打开」、空菜单也弹、路径又写回「用户目录的…」、算不出路径时不兜底。
- **09-20** **启动失败的那一页,给的建议是「去提 issue」——哪怕闸门已经知道该怎么修**。开机闸门查完 Node 版本和依赖,会给出一句中文人话(比如「跑一次 `npm install`」「到 Releases 重新下载覆盖安装」「去 nodejs.org 下 LTS」);可窗口那边拿到的只是一串错误文本,再拿 `Cannot find module`、`EACCES`、`EADDRINUSE` 这些**英文**关键字去猜该说什么——中文判据一个都对不上,于是三条全落进兜底那句:「服务端启动时崩了。把下面这行贴到 GitHub issue 里。」实测三种死法(源码版缺依赖、装机版缺文件、Node 太老)的大标题一字不差,全是这句。一个下完就打不开的人,屏幕上唯一的指示是去开 issue 等人回——这正是 issue #1 里那批人的处境。现在判据跟着错误走:闸门抛错时把那份判据挂在 `err.bootProblem` 上,窗口直接用它的 `fix`,猜错误文本只留给闸门管不着的崩法(端口被占、权限不够)。红框里也只印判据标题那一行,不再把整串连同修法一起塞进去——修法已经在上面用正文写着了,红框重复一遍只会让人以为那也是要贴走的报错。`dialog.showErrorBox` 那条系统弹窗走同一套。370 条断言过、0 挂,5 个突变体全被拦下:建议绕回去猜、闸门不再挂判据、红框又印整串、系统弹窗那条漏接、窗口大标题绕回去猜。
- **09-20** **开机闸门查依赖,查的是一份手写的三个包的名单**:`express`、`@anthropic-ai/sdk`、`exceljs`,而 `package.json` 里是 13 个。实测过这份名单能拦住什么——把包一个个从解析里抹掉再启动,**只有 `express` 真能把启动拦在门口**,另外 12 个都是跑起来之后才 require 的。所以漏报不会当场炸,只会拖到用户去用某个功能的那一刻才炸,而那时错误长什么样就管不着了。更要命的是这份手写名单**只会越来越旧**:加一个依赖就得记得回来补一笔,忘了不会有任何提示。现在直接读 `package.json` 的 `dependencies`,读不出来(文件坏了 / 被裁过)才退回那三个保底名字——退回空数组等于闸门当场失效,比名单旧得多。报名字也改了:以前只印前三个,于是「整体没装成、13 个全缺」和「真就少了一个包」在屏幕上长得一模一样,可这两种该做的事不一样。现在超过三个就跟上总数。实测四种情形:真实装机放行(退出 0)、只少 `qrcode` 报「找不到 qrcode」、装了一半报「等 12 个」、一个都没装报「等 13 个」,装机版给的是「到 Releases 重新下载」而不是 `npm install`。133 条断言过、0 挂,4 个突变体全被拦下。
- **09-20** **抓网页这件事,模型每次都得先做一道多余的选择题**:工具清单里同时摆着 `fetch_url` 和 `render_page`,而它们在代码里根本是同一个 case——`render_page` 就是 `fetch_url` 带上 `render:"force"`。更糟的是提示词里还专门有一行教它「空壳就用 render_page」,跟 `render` 参数自己的说明互相打架:同一件事给了两套互相矛盾的指令。翻 `git log -S` 才发现 2026-09-14 的注释里就写着「已并进 fetch_url」,可当时只写了字没删定义,那条定义在清单里又多待了六天。这回真删了:工具清单 28 → 27 条,工具表 18294 → 18014 字。`executeTool` 里 `fetch_url`/`render_page` 那条合并的 case **保留**——还活着的会话、外部 MCP 客户端、历史排期任务里都可能还攥着这个名字,落到 default 只会得到一句「未知工具」。**外部 CLI 引擎(Claude Code / Codex)那边是反过来的**:它们手上没有本项目的 `fetch_url`,自带的抓网页工具不跑 JS,动态站点一律空壳——对它们来说这儿根本没有选择题,少借一个就是真少一样能力,所以 `render_page` 单独留在桥的「只借给外部引擎」那一档里(有浏览器时借出 16 个工具、含它,没浏览器 14 个、不含)。五个突变体全被拦下:定义偷偷回到清单、`fetch_url` 的 `render` 参数被改名、提示词里又提这个名字、桥上那份被删掉、`executeTool` 的老名字别名被删掉。
- **09-20** **设置页问完渠道、一个模型都没拿到时,那行字直接消失,什么都不说**。上一秒还写着「正在问渠道有哪些模型…」,下一秒空成一片——问出了什么结果,界面上一个字都没有。对本机 Ollama 尤其要命:它回的是 200 加一份空清单(服务起来了,只是还没 `pull` 过任何东西),不是错,所以连个错误原因都没有,而他真正要做的那件事(去终端 `ollama pull`)没人告诉他。现在分三档说话:本机服务空清单 → 写清楚跑哪句命令、大概多大、拉完回来重开下拉框会再问一次;云端渠道空清单 → 说明不少国产渠道压根没有这个接口,精选和「自己填…」照用;**连请求都没发出去**(服务端没起来 / 网断了)→ 也得说一句,以前它和「问到了、就是没有」在界面上完全一样。另外那趟空清单**不再记进前端缓存**——缓住的话,他照着提示 `pull` 完回来重开下拉框,看到的还是那份空的,等于提示教他做的事做完了界面上什么都不变。对话模型和多媒体两条选型路都改了(`public/js/app-05.js`),5 条断言跑真源码,5 个突变体全被拦下:抹回空字符串、空清单又进缓存、`local` 忘了往下传、不分本机云端一律喊 `ollama pull`、`catch` 又回到抹掉那行字。
- **09-20** **接本机 Ollama 的时候,用哪个模型不给选**,向导上写死的是 `qwen3:14b`——那是个约 9GB 的模型,16G 内存的 Mac 拉都拉不动,而机器上明明装着别的。毛病在于向导拿的是服务商模板里那一行写死的型号,而**装了什么只有你那台机器知道**。现在向导会直接问机器:选中「Ollama 本地」的一瞬间去问 `/v1/models`,把它真装了的那几个列成下拉框;模板里那个默认值**只在你确实装了的时候才选中**(没装还默认选它,点下一步必然 404,而报出来的错看着像 Ollama 坏了)。Ollama 没起来也不留空手——提示里写清楚先 `ollama serve` 再 `ollama pull`,并留一颗「重新问一次」(他照着去终端拉完模型回来,得有地方再问一遍,否则清单缓在那儿,起没起来都一样空);清单里没有想要的就选「自己填…」把名字敲进去,空着不许往下走。挑好的型号会**真被拿去验活**,验过了才落盘——以前是先把配置改掉再去验,验砸了那条改动还留在内存里,下一次任何一次保存都会把它写进盘,等于一次失败的尝试把你本来跑得好好的配置弄坏了。连不上 Ollama 时的兜底型号也从 `qwen3:14b` 换成了 `qwen3:8b`(约 5GB),14B 那条留在候选目录里,想要更聪明的自己点。前端 13 条断言跑的是 `public/js/app-03.js` 里那一段真源码,后端拿一台假 Ollama 从头验到尾:问得到清单、10 分钟内走缓存(上游只打 1 次)、匿名和普通成员都打不到上游(这个接口会带着平台的 Key 出网)、Ollama 没起来和地址没写全各报各的、点名的型号真被拿去 ping、验不过时盘上和内存里那条都不许动、模板新建那条也认这个型号。四个突变体(验活前就改配置 / 模板吞掉型号 / 兜底换回 14b / 拆掉管理员闸)全被拦下。
- **09-20** **装了包的 macOS 用户点「有新版本」,被推回去下一个新 dmg——于是第一次打开又撞上「Apple 无法验证」**。这条路是自己给自己挖的:他手上那份明明已经放行过了,升一次级又得再走一遍系统设置。现在 macOS 的升级提示第一条给的是那句零弹窗的 `curl -fsSL .../install-mac.sh | bash`,而且这条命令**不塞在正文里**——正文是一段话,命令混在里面既选不中也点不动。它单独走一条返回值,界面上画成一行等宽字加一颗「复制这条命令」,复制完提示「粘到终端里回车就行」。命令只在真有新版时露出来(已经是最新还摆一条升级命令,照着跑一趟等于白跑),Windows 和从源码跑的人一个字都看不到。6 条前端断言跑 `public/js/app-06.js` 真源码,另加一组后端对照:正文必须指向那条命令、命令必须是那句 curl、Windows 和源码那两条必须是空。
- **09-20** **往输入框里拖一个文件,界面上要过一会儿才有反应**——而那一会儿里什么都没有:没有卡片、输入框里没有字、连个转圈都没有。因为以前是等上传回来才挂卡片,4MB 的片子实测空窗 124ms,走手机网更久,人会以为没拖进去,再拖一次。现在松手那一瞬间卡片和文字锚点就都在了,上传在后台转圈,传完圈停下、卡片可以点开看。另外七处一起收了:卡片编号原来是按同类现存数量 +1 算的,加两张图删掉第一张再加一张,新的又叫「图片 2」——界面上并排两个「图片 2」,发给模型的也是两个,现在编号只增不复用;同一个文件拖第二次原来是彻底静默(照发一次上传,卡片不变、输入框不变、一个字的提示都没有),现在明说「已经在这条消息里了」并把内容更新成最新那份;拖进来一个文件夹原来当 0 字节文件传上去,工作目录里多一个同名垃圾、卡片还说「加好了」,现在不传、不挂卡片、点名是哪个并说该怎么办;上传失败原来把文字锚点留在输入里,等于告诉模型「这个文件有」,它照着去读只会扑空,现在失败就把锚点撤回、卡片变红留一颗重试键(文件还在手里,不用重新去 Finder 找);还在传的时候点发送原来直接发出去,现在拦住、输入框一个字不清、并说清在等什么;卡片上原来只有一个文件名,1KB 的草稿和 25MB 的片子长得一模一样,现在写着体积,删除和打开都是真按钮(原来的删除键是个挂了 onclick 的 `<b>`,鼠标能点、Tab 过去空无一物、读屏也念不出来),点名字直接打开它在工作目录里的真实路径;缩略图原来是把整份文件 base64 塞进 `img.src`——300KB 的图片实测挂上去是 409,622 个字符,浏览器还按原分辨率解一遍码再缩到 28 像素显示,贴几张手机照片就是几百兆内存,现在先缩再挂。这一段的回归断言从 21 条加到 **49 条**,八条新路(编号不复用 / 松手即时反馈 / 重复文件 / 文件夹 / 传失败加重试 / 传输中拦发送 / 卡片体积与键盘可达 / 缩略图真缩过)跑的都是 `public/js/app-02.js` 里那一段真源码。
- **09-20** **手动下 dmg 的人,第一次打开必然撞上「Apple 无法验证」,而那个框上只有「完成 / 移到废纸篓」**——看上去就是个死胡同,GitHub 上已经有人因为这个打不开。先量清楚是哪一种拦:包是 ad-hoc 签名(`TeamIdentifier=not set`),`spctl -a -t exec` 必然拒绝,和有没有隔离标记无关;但 `codesign --verify --deep --strict` 退出 0,签名是完好的——所以这属于「去设置里点一下就能放行」的那种,不是「已损坏」那种(那种设置里根本没有「仍要打开」那一栏,解法完全不同,两者混在一起写会把人带沟里,现在四处文档都把它俩分开写)。苹果企业开发者账号还在审,证书批下来之前这一步免不掉,于是四层一起补:dmg 窗口自己会讲(新画了 540×420 的背景图和对应的 @2x,上半是「把左边拖到右边」加一支箭头,分隔线以下就写着「点完成 → 系统设置 → 隐私与安全性 → 滚到底 → 点仍要打开」,中英各一行,末尾注明签名批下来就没这步了;在真打出来的 dmg 里验过:`.background.tiff` 两帧 540×420 + 1080×840,`.DS_Store` 里窗口 `{{400,510},{540,420}}`、图标中心正好落在 (140,178) 和 (400,178),两个图标方框内着墨像素为 0,每行居中误差都在 1px 内);README 中英文把这段警告提到了折叠块外面、并且把折叠块改成默认展开(打不开应用的人不会去点开一个折叠块),三条路里不用开终端的那条排第一(绝大多数人不会为了装个软件去开终端,只给一行 `xattr` 命令等于没给);`docs/安装与启动.md` 和 release 正文模板给全了弹窗原文、按钮原名和验证命令;线上已经发出去的 **7 个 release(v0.6.2–v0.6.8)正文也逐条改了**(2169→2971 字符,早几个 1970→2792),原有的「双击了没反应」「boot.log」那几段都还在。新加的发版闸门会盯着:四处安装说明必须都有不开终端的那条路、必须都写了「已损坏」是另一回事、README 那一段必须是展开的、dmg 图标位置不许压到背景图下半的字上(反向对照把图标放大到 200px,当场红)。
- **09-20** 连接器卡片上那句**「为什么连不上」,一直只露中间一截**。死因里带着进程死前喊的最后几行 stderr,两三百字是常事,而它被放在了放工具名的那一排里;那排的胶囊是定高 20px、不换行、内容居中的,于是一句话被截成中间一段——开头没有、结尾没有、连个省略号都不给。现在它有自己的块:红色淡底、正常换行、三行封顶,真裁了才出一颗「展开」(裁没裁是问浏览器要的,不是数字数猜的),全文同时在 `title` 里。还有三处一起收了:命令行那栏夹三行,可 `max-height` 写的是 3.7em、行高是 1.55,乘出来是 2.39 行,**第三行恰好从字中间被横切开**,看着就像被遮住了;夹行数这件事本身也有坑,`-webkit-line-clamp` 只管内容盒的高,盒子自己再带 padding 的话,下边那平会把第四行漏出来半条,所以夹行数改成落在内层;插件卡片右上角那个绝对定位的角标正好压在「已连接 · N 个工具」上,现在有角标就把标题行整体让下来。顺手把状态字和头像的颜色从填色换成配套的文字色(填色是给底色用的,当字色在深色主题下偏糊)。最后让死因本身短一点:filesystem 那类服务器把要开放的目录当参数收,路径写错时它只甩一串 `Warning: Cannot access directory ...` 加一句英文总结,现在直接点名是哪几个目录打不开。布局这几条是在真浏览器里量盒子验的(盒高必须是行高的整数倍),反向对照把旧写法摆回去两次,两次都真挂了。这把尺子后来推到全站量了一遍,又揪出三处同样被拦腰切断的:审批卡收起后的命令原文(封顶 4.8em,扣掉内边距和边框只剩 1.94 行)、画布音频节点的正文、画布里正在跑的那条消息。角标让行那条也从连接器卡推到了所有带角标的卡片——专家卡的「官方」、技能卡的「插件」、目录卡的「已接入」,原来都压着副标题。新加一条前端尺子专盯这类框:拿真浏览器量盒高,不是行高的整数倍就算横切(clientHeight 是取整过的,57.6 拿到手里是 58,恰好把要量的那点误差抹平,得用 getBoundingClientRect);反向对照把四个旧封顶值摆回去,四块当场全红。
- **09-20** 用完真浏览器之后,**它自己不会走**。`chrome_cdp` 拉起的 Chrome 是 detached 起的,pid 记下来就再没人管过——这台开发机上真挂出过一个:跑了十个半小时,GPU 进程常年 160% CPU,load average 上了三位数。现在三条线一起兜:闲置十分钟自己关(`OWB_CDP_IDLE_MS` 可调)、本进程退出时带走、也能显式发一条 `close`。收的时候连整个进程组一起收——只杀主进程的话,真正在烧 CPU 的 GPU 和渲染器还留在那儿。
- **09-20** 内置技能从 25 条加到 **35 条**:竞品监控、市场调研与规模测算、表格数据分析、一稿多投、用户反馈分析、SEO 内容简报、财务测算、播客口播、信息图、销售开发信。都是照着本项目真有的工具写的,不写用不了的花活。
- **09-20** 连接器预设从 39 条加到 **52 条**:Linear、Jira / Confluence、Sentry、Vercel、Figma、Airtable、Asana、Canva、Apify、YouTube 数据、AntV 统计图表、EdgeOne 一键部署、B 站。只认 OAuth 的那几家统一走 `mcp-remote` 转一手,第一次连弹浏览器点个同意就行,不用找 Key。
- **09-20** 推荐技能新增 4 条:交互网页 / 小应用、算法生成艺术、对内沟通文案、Claude API 接入(都是 Apache-2.0)。
- **09-20** `gen_diagram` 画的图**常常只出 SVG、没有 PNG**(飞书文档和 Word 只收 PNG,等于图插不进去)。没在桌面应用里跑的时候,转 PNG 靠调本机 Chrome 无头截图——图其实两秒就写到盘上了,可 Chrome 进程之后还能再挂一分多钟不退(有显示器的 mac 上尤其容易)。原来的写法是等它退,等满 30 秒超时把它杀掉,然后因为「是被超时杀的」把那张已经好端端躺在盘上的图一起丢掉。现在不等退出,盯着文件,写完就把进程收掉,两秒出图。顺手给它单开了一份临时浏览器配置:不给的话它会去开你正开着的那份 Chrome 配置,抢锁、拖慢,还动人家的浏览器。
- **09-20** macOS 上**下载下来的包双击打不开**,有人卡在 0.6.2 一直没用上。毛病不在包里:这个项目没有 Apple 那张 99 美元一年的开发者证书,发出去的是 ad-hoc 签名,而浏览器下载的文件会被打上 `com.apple.quarantine`。macOS 15 起这类包双击弹出来的框上只有「移到废纸篓 / 完成」两个按钮——**没有「打开」那一个**,照着网上「右键→打开」的老教程点也没用,绝大多数人到这儿就认定「这软件是坏的」。现在多一条 `curl -fsSL .../install-mac.sh | bash`:curl 下下来的文件本来就不带那个标记,全程一个弹窗都没有——认芯片挑 arm64/x64、下 zip、解压、放进「应用程序」、顺手再 `xattr -dr` 摘一次、签名坏了就地重签(拷贝、同步盘、解压工具都可能把它弄坏,而 Apple 芯片上签名一坏报的是「已损坏」,看不出真正原因)。顺带堵了一对互相覆盖:`scripts/make-mac-app.sh` 生成的开发壳固定落在 `~/Applications`,而 `/Applications` 写不进去时安装脚本也退到那儿,两边撞同一个名字。闷头覆盖的话,装好的正式版会被换成一个指向本机仓库的开发壳——你的东西仍在 `~/OpenWorkBuddy` 好端端躺着,界面上却一条任务都没有,看着就是数据没了。现在两个脚本各自认得出对方,撞上就停下来告诉你换个地方装。
- **09-20** 无限画布**能一次选一片了**:按住 Shift 或 ⌘ 点节点加选减选,工具条上多了个「框选」开关,拖一个框碰到的都选中,⌘A 全选、Delete 一起删、Escape 退出来。框选本来只有「按住 Shift 拖」一条路,可空白处拖出来的默认动作是平移——试一次以为不支持,就不会有第二次,所以给它一个看得见的开关。真正的毛病在后面:这几个键挂在画布那一页上,而鼠标点完节点、点完空白,焦点一直停在 `<body>`,它是画布的**祖先**,按键根本不经过画布。于是框也框得出来、选中也高亮着,**按 Delete 没反应、⌘A 没反应、Escape 退不出框选**,看着像多选压根没做。现在在画布上点一下就把焦点收过来,点的是输入框或按钮则不抢。另外两处:框选的命中判定从「整个节点都在框里」改成「碰到就算」(圈住大半张画布却一个没选上,没人猜得到是差了半个边),Shift 在空白处点一下没拖动的,当成「取消选中」。25 条断言钉住,包括「正在输入框里打字时 Delete 只删字」。
- **09-20** 短剧进度带**展开之后把画布压住了**。视口高度写死在 `calc(100vh - 278px)` 里,那个 278 是这条进度带还不存在时算出来的;它一出现(展开还会长出卡点清单和镜头表)就把画布连同下面的对话区一起顶下去,而浮在画布顶上的工具条 `top: 42px` 同样是那会儿量的,原地不动正好盖在进度带脸上——剧本、定妆那两格永远露不出来。现在把进度带的实际高度量出来喂进 `--cp-h`,视口和工具条一起让位;进度带自己也封了顶(最高 40vh,再长就自己滚),不然三十个镜头的表能长到一屏还多。
- **09-20** 「**N 个角色的定妆照在画布上写着,盘上已经没有了**」这句话经常是**冤枉的**。判「文件在不在」靠的是一份工作目录清单,而那份清单是截断过的——最深只走 3 层、最多 500 条。工作目录一攒多,或者素材落在深一层,满画布的节点就一起挂出这句话,文件其实好端端躺着。现在改成两步:清单里有的直接算在,没有的挨个去问一次盘(一张画布封顶 400 条),**判死刑只有盘说了算**;路径解析不出来的一律算「不敢说」,宁可不喊也不冤枉一个还在的文件。同一条带子上还有一处重复:收起时那句「下一步做什么」和展开后的第一条卡点本来就是同一句话,两处一起摆着看上去像出了两个故障——展开时只留那一条。
- **09-20** 「整理文件夹 · 腾出空间」这个入口从**空状态里撤掉了**。刚进来什么都还没做的人,第一眼看到的不该是一个劝他删东西的按钮——那是在替他操心一件他还没有的烦恼。能力本身没动,任务跑完照样会问你要不要清中间文件。
- **09-19** 跑自动评测**不再动你的真记忆、真偏好、真额度账本**,题库也补上了单轮题考不出来的三种题形。先说那个真会伤人的毛病:评测跑批以前跟正常使用共用一个数据目录,于是题目里 agent 顺手 `remember` 一句「用户喜欢用 Firefox」就真进了你的长期记忆,下一轮评测又被上一轮记下的东西影响——成绩从此不可复现,而你的记忆库里多了一堆不知道哪来的话。现在开跑前先把数据目录指到 `eval/runs/<时间戳>/data/`,跑完那一轮的所有痕迹都锁在那个文件夹里。题库 15 → 18 题:**长任务题**(12 个订单文件,规范藏在其中一个文件里,要跑 40 步以上)考的是「跑到三十步之后,第三步读到的那条规矩还守不守」——规范必须放文件里,写进题面就考不到了,题面坐在历史最前面,裁历史时最不容易被裁掉,中间那段工具输出才是先被丢的;**多轮题**三轮连着问,口径只在第一轮说一次,后面两轮一个字不重提;**记忆召回题**把规矩提前种进长期记忆、题面里一个字不提,另外故意种两条不相干的(换浏览器、换办公群),考它会不会把无关记忆硬塞进产物。配套还有一道**不花钱的离线闸门**(`node test/eval.js`,100 条断言,一次模型都不调):把每道题的判分喂给一个空目录,要求**一条都不许绿**——智能体什么都没干的时候这题就该零分,哪条 check 这时候还亮绿,它就不是在判对错,是在白送分。这条闸门写完当天就抓出两道老题的送分项:一条纯否定断言在模型崩了一个字没输出时照样绿,另一条在模型把两个源文件直接删掉时判「副本已删干净」。最后把「改了提示词或工具描述必须跑一遍评测」写进 CONTRIBUTING,列清了哪些改动算触发条件(agent.js 系统提示词、工具 description、技能提示词、裁剪与记忆注入逻辑)。
- **09-19** 两条任务同时改一个代码仓库时,**后到的那条进自己的 git worktree**(`worktree.js`)。原来的隔离是「每条对话一个成果文件夹」,对写文档的活儿够用;工作目录一指到自己的代码仓库上就失效了——两条任务读的是同一份 `src/`,A 刚把函数改成三个参数,B 手里还是两个参数的旧文本,写回去就把 A 的改动抹了。谁也不报错,测试可能还是绿的,坏的是中间那一版。现在做法跟 Codex 一样:同一个 `.git`、独立工作区、改动进 `owb/<会话>` 分支。三条界限都是故意的:**只有撞上才隔离**(一个人一条任务是绝大多数情况,凭空把人扔进陌生目录只会让他找不着文件);**先到的那条不动**(它在你眼皮底下那份工作区里改,这是你的预期,后到的才是「多出来的」);**绝不自动合回来**。另外几件事不做就是骗人:你手上没提交的改动要**带过去**(被 `.gitignore` 忽略的不带,不然一个 800MB 的 `build/` 也跟着走),不带的话第二条任务看到的是一个「退回上次 commit」的仓库,它会以为同事的活没干,把你改好的地方再改一遍;跑完**自动提交**到那根分支,没提交的改动是合不回来的,你照着提示敲 `git merge` 会发现这分支跟自己一模一样;白跑的那趟(agent 一个字没写)**就地收掉**,目录和分支都不留,不然每撞一次车就多一根删不掉的分支;有改动的**一个都不许删**,放满 14 天也只删目录、分支一直留着。撞车名单把终端里那趟也算上(网页一条 + 终端一条是最常见的撞法,而它俩是两个进程,靠 `data/cli-live` 那本账互相看见)。提示词里明说了不许自己 merge / rebase / push。开不出来的情况(没装 git、还没有第一次提交、裸仓库、补丁打不上……)一律退回老样子在原工作区跑,日志写一句,任务不会因为这个起不来。`openworkbuddy worktree` 看分身、`openworkbuddy worktree 清理` 收白跑的
- **09-19** **超级管理员**这一档补上了,权限按 RBAC 重做。以前**任何一个管理员都能把另一个管理员降成成员、停用、删号、重置密码**,也能随手再造一个管理员出来。两个人吵一架,谁先点谁赢,那不是权限模型,是先手优势。而且更糟的在分公司:`owner` 这个保护位以前**只给全站第一个注册的人**,后建的组织一个受保护的人都没有,那儿的管理员完全是互相赤膊。现在四档——超级管理员 / 管理员 / 审计员(这一档本来就有,只是没排进序列:进得去后台、看得见全组织的账,一个字也改不了)/ 成员,整套规矩只有两条:**只能管比自己低的那一档**(同档互相动不了),**授角色要同时够得着人和角色**(于是管理员能提审计员,永远造不出第二个管理员)。发管理员有四条路——改角色、直接建号、发邀请码、部门模板——四条全堵在同一道闸上,少堵一条这条规矩绕一步就没了。超管每个组织只有一个,**只能转让不能增发**:两个超管等于把第一条规矩在最高那一档上重新打开,要么互相罢免(先手优势原样回来),要么谁也罢免不了谁(点错一次永远拿不下来)。锁死了有两条出口:平台超管(默认组织那一个)能跨组织救场,他自己出事就在服务器上跑 `openworkbuddy owner <用户名>`——理由跟 `passwd` 那条一样,能读到 `users.json` 的人本来就是机主了,**同样绝不接到 HTTP 上**。升级自动搬家一次:老账本的 `owner` 布尔抬成角色,以前没有超管的分公司按建号顺序补上最早的那个在职管理员。整套判断收在一个 `rbac.js` 里,一屏读得完——权限这种东西读不完就没人敢信。后台那几个角色下拉也照着**你自己发得出去的角色**画——管理员的下拉里不再挂着「管理员」,看得见的按钮不能是点下去才告诉你没权限的按钮;改人的时候他现在那一档先摆在下拉里,哪怕你改不动,不然默认落在第一项上,看着像「他是成员」。新加一套 103 条断言的测试,每条「该拒」后面压一条「该放」。
- **09-19** 短剧分镜**能退回上一版了**。以前改一句台词重跑一下,上一版的首帧就被同名文件盖掉,找不回来——光记路径没用,路径还是那个路径,里头的字节已经换人了。所以留底存的是**字节本身**:首帧 / 尾帧 / 视频 / 配音按 sha256 进对象库,同一份内容只占一份(重跑十次退十次,中间态多半是重复的)。每一镜点「版本」翻它有过哪些样子,缩略图直接从留底里取;退回去是**整镜换回那一版**,不是只换图——合并会留下「上一版的视频配这一版的首帧」那种四不像,而它在界面上跟成功长得一模一样。退之前先给现在这一版拍一张,所以退错了还能再退回来。清掉的那一版是真回不来:按钮直接点不动,旁边写明是哪一种回不来,不给一颗点了没反应的按钮。账本躺在工作目录里、模型写得到,所以从不信账本里的路径——一律 resolve 回根目录再校验,出去的一律拒。
- **09-19** 欠费的渠道**撞一次就断**,不再天天去撞。阿里云百炼把欠费报成 **HTTP 400**,正文里一个「余额」「quota」「overdue」都没有,只有一句 `Access denied, please make sure your account is in good standing` 和一个 `code: Arrearage`。400 不在硬错表里,那串词熔断器也一个都接不住,于是欠费被当成「这次不巧」——下一次照发,再白等一个超时,充值之前天天如此。而这条渠道底下挂的是出厂那条**默认视频模型**,等于生视频这一路一直在撞一堵不会动的墙。现在认 `Arrearage` 和那句 `in good standing`,一次就断,拦住时说的是「这条渠道没余额了」并让人去 设置 → 模型,而不是「等几分钟自动再试」——方向错了,等多久都没用。反向对照压了两条:同样是 400 的参数填错、以及 429 限流,一条都不许断(限流会过去,断了等于把能用的渠道关掉)。
- **09-19** 火山方舟上**转售的别家型号,不再被当成挂错了渠道**。方舟给自己上架的每个型号都盖一个 `-YYMMDD` 的日期尾巴,而它又是个转售平台——精选目录里 `deepseek-v3-250324`、`kimi-k2-250711` 挂的都是方舟。老判据只看牌子前缀,于是用户填在方舟渠道上的 `glm-5-3-flash-260828` 被认成智谱家的,保存一次就被自动挪到智谱那条渠道上;而那个型号在方舟上是真能调通的(实测 200),挪走之后反倒必然报「型号不存在」。这类失败长得跟成功一模一样:设置页上显示的还是他填的那个名字,人只会以为是模型坏了。现在日期尾巴比前缀可信,尾巴还得是真日期——99 月、0 日、4 位数都不算,Anthropic 的 8 位写法 `claude-sonnet-4-20250514` 和 OpenAI 的 `gpt-4o-2024-08-06` 也都不许被吃掉。这一路补了 46 条断言,每条「该判挂错」后面都压一条「该放行」。
- **09-19** 卡住的任务**自己会停下来了**,不再转到天亮。以前只有两档,都是「劝」:同一个调用连着三次拿到同样的结果就往历史里塞一句「换条路走」,连着五次拦一次不执行。模型不听就一路转到最大步数或最大运行时间——用户看到的是一句「已达最大运行时间,任务强制收尾」,还以为是活儿太多,回过头去把上限调大,下一趟转得更久、烧得更多。现在补上第三档**硬停**,五种卡法各认各的:同参同结果 6 次、一字不差的同一句报错 6 次(换参数也没用,说明参数根本不是变量)、连续失败 12 次、渠道都熔断了还连着调 4 次、以及 `A→B→A→B` 这种两步或三步一圈、每圈入参和结果都一样转满 4 圈——最后这种单看每个工具都不重复,只有连起来看才看得见。**这种停不自动续跑**(续跑第一件事就是把同样的圈再转一遍),停下来那句话也不再劝你去调大上限(上限再大它也只是多转几圈),而是点名让你去修它撞墙的那条路:渠道、文件还是命令。36 条断言里每一档都配一条**差一次就到的反向对照**——判据松一格,正在干活的任务就会被拦腰砍断,而误停比不停更伤人。
- **09-19** 资料库里的三处毛病一起修了。**音频和视频点开就能听能看**:一个 1006 KB 的 mp3 被判「文件太大,预览不动,请下载后本地打开」,因为它走的是读文本那条路,而文本上限是 512 KB。根子还在服务端:取文件那个接口**一律当附件发**,带着 `Content-Disposition: attachment`,`<audio>`/`<video>`/`<iframe>` 全都渲染不出来。现在默认内联发并带对 MIME,真要存盘的走 `?dl=1` 才加附件头。**二进制文件不再整包拉回来**:`.psd`/`.heic`/`.sqlite`/`.zip` 这些只发一个 HEAD 探它还在不在,直接说「二进制文件,下载后本地打开」;没后缀的看头几个字节认。**「出自任务」不再张冠李戴**:`任务_0915_对话_2/BGM_纯配乐.mp3` 被算到了 9-17 那个小红书任务头上,因为老写法认的是「第一个列出过这个文件的任务」,而后面那个任务确实也碰过它。现在先按文件自己所在的那个任务目录认,认不出来才退回去扫;两边都认不出就交白卷,不猜一个回去。**多了「所在位置」和「复制文件」两颗按钮**:前者在访达里把那个文件选中,后者把文件本身放进剪贴板,粘到微信或 PPT 里是文件不是一条本机路径。这两颗只有本机那位(平台管理员)画得出来。
- **09-19** 「用真浏览器打开这个网页看一眼」这条路**修通了**。以前只有一个动作能用(列出有哪些标签页),导航、截图、跑 JS 全挂,还得你自己先开一个带 `--remote-debugging-port` 的 Chrome。挂的原因是四个毛病叠在一起:**9222 端口上蹲着一个不提供调试口的 Chrome**(端口通 ≠ 调试口开着,连接当场被拒);握手里带了 `Origin` 头,而 **Chrome 111 起不再接受**,一律 403;**成功的那次也被当成失败**——校验的是「Switching Protocols」这个原因短语,而 Chrome 153 回的是「WebSocket Protocol Handshake」,状态码同样是 101;`evaluate` 的返回值**多剥了一层**,所以每次取回来的都是 `undefined`。现在它自己拉一个 Chrome:独立的用户数据目录、端口交给系统挑(`--remote-debugging-port=0` 再读 `DevToolsActivePort`),碰不到你正开着的那个窗口和登录态;已经有一个活着的就直接接管,不重复拉。无头档位下 WebGL 也真画得出来(`--use-angle=swiftshader`——老写法里那个 `--disable-gpu` 正是把 WebGL 弄死的元凶)。连不上的时候先跑 `action: "status"`,它只探不碰,直接告诉你是没装 Chrome、端口上是别的进程,还是被 `OWB_CDP_NO_LAUNCH` 按住了。新加 20 条断言,测试里那个假 Chrome 会对带 `Origin` 的握手回 403,这条回归以后跑不掉。
- **09-19** 它反问你的时候,**题面里点名的那个文件自己摊到右边**。三版封面对比摆在一个 HTML 里,问题里也写了文件名,可你得自己去成果文件面板里把它翻出来。现在题面和选项说明里出现的文件名都认(《》里的、带路径的都算),**只认这一趟真写出来的那些**,所以不会弹一个「文件不存在」;问题下面还挂着这几份文件的按钮,随时点回去。跑完了才出产物那条路一个字没改——产出仍然不抢版面,只有「不看就答不上来」的提问才动右边那条。回放历史、别人的会话、窄窗都不开。
- **09-19** 成果文件面板顶上多了个**按名字找**。分组能解决「翻」,解决不了「我就要那一个」:一个任务跑下来几十个文件,得先展开对的文件夹再一行行扫。搜的是整条相对路径,所以文件夹名也算线索(打「0918」就把那天那个任务夹里的都捞出来);空格分词、全都命中才算(「封面 html」= 名字里有封面、而且是 html);结果不分组、直接摊平,每行标着它在哪个文件夹(同名的 `index.html` 一个任务能有好几份)。文件不到 8 个不摆这个框——一眼扫得完的时候它纯占地方。
- **09-19** 公众号封面**改成真生图**,不再拿 HTML 排版截个图充数。根子在技能里:`wechat-article` 原来只写了尺寸(900×383、1:1),一个字没说画面该长什么样,于是每次都退回去拿排版糊一张。现在多了一步专门的封面,提示词按主体 / 风格 / 光与色 / 构图四行拼,三条硬规矩写死:**别让模型往图上写标题**(中文字必糊)、两个尺寸都交、一次出三个方向摆一个对比页让你挑——问的时候点名那个对比文件,网页端自己就摊开了。
- **09-19** 改文件那几步**能退回去了**:`write_file` / `edit_file` 落盘前先把改前那份留底(工作目录 `.history/`,按内容寻址,同一份内容只存一次),过程卡上点开就是这一步的 diff(加的绿、删的红),旁边一颗「回退到这步之前」——那一步和它之后动过的文件一起退回去,新建的删掉、改过的恢复;回退本身也留底,退错了再按一下「撤销回退」就回来。命令行是 `/rewind`,不带序号先列出能退的步。**「每步都问」档位下审批条上直接是这几行 diff**,批的是改动本身,不再是一个文件名——终端、网页、手机三处同一份。回退只认本会话的检查点,账本被手改塞进 `../../` 也写不出工作目录;30 天前的底自动清。
- **09-19** 修好了一条**把发版整个挡住**的红:v0.5.1 打了 tag,却一个安装包都没出来。CI 上挂的是前端那条「从资料库跳回那一轮,高亮得真画出来」——runner 上量出 `animation-name: "none"`。不是代码的事:GitHub 的 macOS runner **系统默认开着「减弱动态效果」**,而这一档下那条高亮动画本来就该是 none。于是同一份文件同一个 Chromium,开发机全绿、runner 全红,看着还像 CI 自己坏了。现在每个测试窗口都明说自己要哪一档(默认 no-preference,要测 reduce 的那两屏自己改成 reduce),结果不再跟着跑测试那台机器的辅助功能设置飘;两遍各加一条夹具自检,下次谁把这层摘了,报的是「这一遍不是 reduce 档」而不是一句莫名其妙的 `"none"`。本机拿 `--force-prefers-reduced-motion` 把 runner 的状态复现了一遍:改之前照样红,改之后 54 屏全过。
- **09-19** 被掐掉时那半句「任务强制收尾」现在**说得出下一步**。老措辞只有一句「如需继续,可提高设置中的上限」:上限在哪一页没说,默认就是 30 分钟也没说,更没提还有「自动续跑轮数」这个开关(默认 0,所以撞了墙什么都不会自己接着跑)。现在这句点名「设置 → 执行上限」、点名「自动续跑轮数」,并把进度档的位置(工作目录的 `PROGRESS.md`)一起给出来,看到的人不用再回过头来问。**手动停止不再被当成撞上限**:人自己按的停,还劝他去调大上限就是答非所问,那一条只说怎么接着做——Web 过程条和命令行里那句 `▲ …,任务强制收尾` 同样不再跟在「已手动停止」后面。措辞也从两份收成一份:内置循环和本机 CLI 引擎以前各拼各的,一边改一边不改就会在 Web 和 IM 上说出两种话,现在都叫 `stopNotice()`,谁再手抄一遍测试当场红。
- **09-19** 定时任务的每一趟执行,现在都留下**一整段能点开回放的会话**。自动化页每条任务底下是「运行记录」,每条记录后面挂着「看执行过程」——点进去就是那一趟调了哪些工具、每一步返回了什么、最后为什么是这个结论,跟手动对话完全同构,走的也是同一个 `openSession`,没有第二套回放。以前这儿是光秃秃一句 `runTask({ history })`:不给 emit 就没有事件,不给 sessionId 就没有会话,一整趟执行只在记录上留下一句**被截到 500 字**的结果,想知道它卡在哪一步一点痕迹都查不到。三处细节都是照着「背着人跑」这件事定的:**定时会话不进侧栏**(一天几十条 cron 会把真正的对话整个挤下去,它们的正经入口是运行记录那一栏);**宠物不为 cron 动表情**(背着人跑的任务让桌面宠物手舞足蹈,会盖掉用户手头正在看的那件事);**记录删了会话跟着删**(记录 300 条封顶、任务删了记录也跟着删,可盘上的会话文件没人碰——用得越久越多,而且全是没有入口的孤儿)。录像不许影响执行:起录像失败就当没这回事继续跑,会话 id 先落盘再开跑,任务跑一半崩了那半段过程也还找得回来。
- **09-19** 能排**「只跑一次」**的定时任务了。用户说「五分钟后叫我去准备面试」,以前排出来的是一条**每天 14:00** 的 cron。根因不在模型:cron 五个字段里压根没有「一次」这个概念,模型手上只有这一个工具,只能拿「每天这个点」去近似「这个点」,于是一条提醒变成了一条每天都要响的闹钟。现在认三种写法:`+5m` / `+2h` / `+1d`(**这条是主力**——系统提示词里的当前时间只精确到「几点左右」,模型算不出「五分钟后」的绝对时刻,硬让它算只会算歪,不如让它照抄用户说的那个量)、`14:05`(今天这个钟点,过了就顺延到明天)、`2026-09-19 14:05` 或完整 ISO。**认不出来一律抛错,绝不猜一个时刻回去**:排期是要弹给用户点头的,猜错的那一下他点的是「同意」。响过之后状态是「已完成」不是「已暂停」(暂停的言下之意是「还会再跑,等你开」),记录留着——人还要回头看「那条提醒到底响没响」。关机错过了照样补,这正是一次性提醒最该补的场合(合上笔记本去开会,回来该看见它响过),但隔了一天的「五分钟后叫我」再响就是骚扰,超过补跑窗口就只记一句「错过了,晚了 N 分钟」。关掉自己这一下是**同步**做在放行之前的:fire 是异步的,等任务跑完再关,中间每一分钟的 tick 都会看见它还开着、时刻还是过去时——一条五分钟的提醒会连着响到你手动关掉。
- **09-19** 资料库里**点一个文件真的能看见内容了**。内容确确实实渲染进了右栏,只是那块板子还挂着 `display:none`(右栏是按需出现的,没选东西时 `data-prev=off`),于是屏幕上什么都不发生。之所以一直没人发现:随便点一下筛选器就会走整页重画,那一路是照选中项重算这个属性的,于是又能看了——看起来像「偶尔抽风」,其实是每次进这一页的**第一下必挂**。顺手把预览格式补齐:Word / Excel / PPT / CSV / TSV / zip 在这一页也能直接看了,画法和样式跟对话页共用同一套,不抄第二份;`.xlsx` 多张表的标签点得动(一个表格文件常常好几张表,点不动就只看得见第一张);CSV 按 RFC4180 认引号、自己判分隔符是逗号分号还是制表符(欧洲导出的表用分号,按逗号拆会拆成一整列)。Office 97-2003 那三种是 OLE 二进制不是压缩包,拆不开就明说是格式的事、并给一条能走通的路(另存为新格式),比让它掉进「这个文件不是文本」强得多。
- **09-19** 输入框左边那个 **+,现在一个入口装下六件常干的事**:添加文件、切模式、挑专家、挑技能、看**模型此刻手上到底有哪些工具**、开关已经配好的连接器。在这之前这六件事散在六个地方:上传是一枚回形针,模式在快捷栏最右,专家和技能要跳到另一页(回来时对话已经翻页了),而「有哪些工具」——**界面上根本没有**,只能问它一次、等它答「我没配发信通道」。一级只有六行字,二级从右边飞出来一块 300px 的板子摆清单,所以一级不会被二级撑变形、来回切也不跳宽度。连接器那一栏能**直接关掉某一台**:关 ≠ 删,配置密钥参数全留着,只是这一轮不去连它、工具表里也不出现——留着定义模型就会先想一个用它的方案、调一次、吃一条「连不上」、再重想,白烧一轮。关掉的那几台在界面上跟「连不上」分得清(少一个字段,用户关掉一台看到的是一张灰卡片,跟连接失败长得一模一样),「授权没了」也和「连不上」分开说(前者要你现在就去换 Key,后者多半过会儿自己就好)。连接器是整台机器一份的,开关归平台管理员,跟权限档位同一个判据。
- **09-19** **撞不通的模型不再一趟一趟去撞**。五路媒体工具(看图 / 生图 / 生视频 / 配音 / 转文字)现在统一穿过同一层派发:401 / 402 / 403 / 404 这种「不换东西就永远不会好」的错一次就停 30 分钟,超时连不上这种攒够 3 次停 5 分钟,400 / 422 是参数的事不算渠道的账。为什么记在派发这一层而不是五个函数各自的开头:那五个函数里散着三十多个 `return {isError:true}`,一个一个去记账早晚漏掉一条,而漏掉的那条恰好就是撞得最凶的那条。指纹按「这一路 + 地址 + 型号 + Key 的哈希前 8 位」算,所以换把 Key、换个型号立刻重新可用,不用等冷却。光有这道闸还不够:模型该转的圈还是照转,用户看到的是 trace 里四十条一模一样的「看图 · 失败」——所以同一个工具被熔断闸拦到**第二次**,本轮就不再执行它了(第一次拦下时模型还没读到那句话,它有权换个型号点名另一条渠道再试一次;读过一次还撞就不是判断问题了)。熔断在后台默默生效就行,但「为什么它突然不给我看图了」必须能看见:设置 → 模型 页顶上一条黄条摊开说是哪一路、还剩多久、为什么。**在设置里动过渠道配置就立刻清空熔断记录**——你改完还得干等半小时,然后来问「我都改好了怎么还不动」。
- **09-19** 看图模型的下拉**按渠道自己报的模态分组**,不再按名字猜。拿 OpenRouter 当天那 446 个型号实测:真能接图的有 263 个,按名字只认得出 134 个——用户自己配的 `z-ai/glm-5.3-flash` 名字里一个 vl / vision 都没有,于是被扔进了「其它模型」;另一头 `gpt-5-image`、`gemini-3-pro-image` 这些**出图**的名字里带 image,照样在看图的下拉里排着队等人选。选中一个出图的拿去看图,上游要么报一串看不懂的参数错,要么真去画了一张图再超时,界面上只剩「卡住」。好在 `/models` 这一层越来越多家会报 `architecture.input_modalities` / `output_modalities`(OpenRouter、new-api、one-api 都透传),那是渠道自己说的,比猜准、也比我们维护一张永远追不上的型号表准:报了就信它并标成「确定」,没报才退回按名字猜并标成「不确定」。前端拿这一格决定**敢不敢把一条拦在「看图」那一组外面**——猜出来的不敢拦,人家自己说的才敢。进出都只有文字的那批是**确定**哪一路都不是,说死了才拦得住 `gpt-5.x-codex` 混进看图那一组;既能接图又能出图的一律先认「产出」那一路(把 `gemini-3-pro-image` 配在看图上是纯纯的浪费和卡顿,它的正业是画图)。
- **09-19** 同名渠道会**自己编号**。同一家配两条(一条自己的 Key 一条公司的、或者一条正式一条备用)是常事,可下拉里两行字一模一样,选哪个全靠猜;改错了那条还以为改的是另一条。现在重名的按配置顺序标上「①②③」,只有重名才标——没重名的不该凭空多个符号出来。
- **09-19** 「添加模型」那张表单**不再被异步重画冲没**。精选目录是现拉的,拉回来会把这一屏再画一遍:人点了「添加看图模型」、正在下拉里翻型号,目录恰好这时到了——整张卡重画,表单连同刚选好的那一行一起没了,按钮看着还在,点下去又是空的。现在表单开着就不重画:重画本来只为了「把目录补上」这点好处,不值得拿人填了一半的东西去换。同一句话还有另一半:保存失败时那行提示**穿着成功的衣服**——绿色、13px、挂在一整屏表单的最底下、上面还压着五张折叠卡,用户看到的是一行绿色小字,跟「已保存」长得一模一样。其实每次都报了错,只是那个错藏在屏幕外面。现在失败一律另外再喊一嗓子,不指望那行小字。
- **09-19** 换过的**桌面宠物重开还在**。开机时那份配置是手抄五个字段传过去的,**偏偏漏掉了 sprite**:于是选了精灵图宠物的人,`character` 传成了 `"sprite"`、`sprite` 却是空字符串,拿空 id 去查自然找不着,最后那行兜底静静地落回 `"cat"`。同一份名单还漏了「跑完通知」和「四处走动」,缩放的兜底值也跟宠物自己的默认值对不上(那边是 2,这里写死 1)——三处都是同一个病:手抄一份字段清单,以后加字段的人不会想到回来改它。现在整份摊过去,只把「启用」单独钉死成必须显式为 true(没配过就不该有宠物),其余交给宠物自己的默认值,以后加字段不用再动这里。
- **09-19** **粘进输入框的图不再算成上一轮的产出**。根子在上传那一步把文件直接落进了这条会话的成果文件夹——那一步是对的,素材和成果待在一起,否则工作目录根下越堆越乱(真实数据里躺过 22 个)。可「本回合产出」的判据是「在我的文件夹里 + 修改时间在开跑之后」,这张图两条全占:它确实是刚出现的新文件,只是写它的人是用户不是 agent。**谁写的这件事只有落盘那一刻知道**,事后从盘上看一个文件是看不出来的,所以只能在那一刻记一笔。记的是「名字 + 那一刻的修改时间」而不是只记名字:agent 后来真把这张图改写了(抠图、压缩、换格式),时间一变就不再算输入——那时候它确实变成了产出,本来就该出现在卡片里。
- **09-19** 安全档位**真的落到本机 CLI 的命令行上**了。这两个 CLI 自带工具、自带循环,它们写文件、跑命令**不经过**本项目的安全中心(只有从 MCP 桥回流的那批才走那道闸)。以前 claude 这条路硬写死 `acceptEdits`、codex 这条路硬写死 `workspace-write`,于是用户在设置页把档位调到「只看不动」、切到本机引擎照样随便改文件——界面上那颗开关是个摆设,而且是最不能当摆设的那一颗。现在四个档位一路翻译下去:只看不动 → claude `plan` / codex `read-only`,问一下 → `default` / `read-only`,全自动 → `acceptEdits` / `workspace-write`,不拦 → `bypassPermissions` / `workspace-write`。「这类命令要问我一下」那张名单在这条路上**问不着**(`-p` 非交互,没有审批通道),所以只剩不给用:名单上每条取第一个词收成 `--disallowed-tools Bash(sudo:*)` 这种(名单写的是前缀如 `diskutil erase`,而 CLI 那边的匹配单位是可执行文件名),删除保护是另一颗开关,也跟着收 `Bash(rm:*)`。「只看不动」还额外**不把借出去的命令行入口放进白名单**——那是条后门,模型从那儿照样能写文件。手填的 `engine_options` 仍然最大,不配 guard 时老行为一字节不变。档位收紧了会在运行页明说一句:不说的话,用户看到的是「它怎么什么都不肯干」,而真正的原因在另一个页面上的一颗开关里,隔着两层根本联系不起来。
- **09-19** `@` 提到文件的那张菜单,**一屏十二行终于认得出哪行是哪个文件**了。以前名字显示的是完整相对路径,可任务目录名本身就有二十几个字,于是十二行全叫「任务_0918_帮我做一个『openwor…」;而右边那句说明十二行一模一样(「工作空间文件」),等于白占一行。现在名字只显示最后一段、目录名让给说明那一行,插进正文的仍然是完整相对路径。名字自己包一层元素才拿得到省略号(裸文本节点在网格里是匿名盒子,长文件名只能硬折),图标一律给(取不到就用通用那个,否则有的行有图标有的没有,名字的左边缘会错开一截)。
- **09-18** 资料库里点一份产出,**直接落到写出它的那段对话上**,不是把整条对话从头摆出来。文件行后面多了个小气泡图标(鼠标扫过那一行才亮),出自哪次任务那一行也标着「第 N 轮」。原来点过去只是打开对话、一脚滚到最底下——一次跑了十几轮的任务,人还得自己往回翻,等于这一跳什么忙都没帮上。回合号是数**对话记录里的 user 条目**算出来的,不是拿数组下标充数(回放时一条 user 起一个回合,下标里还夹着 assistant,差着将近一倍,跳过去正好落在一段跟这份文件毫无关系的话上)。同一份文件改过好几轮就认头一轮——你点它是想看「这东西怎么来的」,那句话在第一次写出它的那一段里。**跳不过去就认输**:老会话根本没记过回合、记录也可能被裁过,这时候服务端一个字都不编,界面干脆不画这个按钮,照旧把对话滚到底。落点会亮一下再退(开了「减弱动态效果」就不淡入淡出,底色直接摆上)——不标记的话人只知道「页面动了一下」,不知道该看哪儿。
- **09-18** **能引用某一条回复来追问了**。回复底下的操作条多了个「引用」:按下去那条回复的正文以 `>` 引用块的形式落进输入框,你接着在下面写自己的话。**先选中一段就只引那一段**——一条回复常常好几屏,整段引过去等于什么都没指。为什么是塞进输入框而不是挂一枚标签:引用的内容**要能改**,真实用法几乎都是「它这段里有一句不对」,人会把那句留下、其余删掉。只取渲染后的正文,过程卡片、按钮条、token 统计一个字不带;输入框里写了一半的话不会被冲掉,空一行接在后面;同一段连按两下不会引进来两遍(会说一声「已经在输入框里了」);超过 400 字截断并打省略号——再长就不是引用而是复述,模型也会被那一大坨带偏。
- **09-18** 补上三个**一直在画空框框的图标**:自动化列表的「上次跑」、安全设置页的「技能与连接器体检」、画布的「最近一次生成」。`<use href="#i-打错的名字">` 不报错也不警告,浏览器安安静静画一个跟正常图标一样大的空格子,只有盯着那一格看的人才发现里头没东西。顺手加了道闸:界面上 379 处写死的图标名,每一处都对着雪碧图核一遍(两个页面各有各的一张,分别核),核不了的那 78 处变量名如实报个数,不假装全覆盖了。
- **09-18** 接上了 **Jev 判断模型**(TypeSafe System One),它不写字,只回选项 / 分数 / 概率,外加一个「有多确定」。它没挂进「模型」那个下拉——对话模型吃一段话吐一段话,它吃一段材料加一道**有类型的**题,挂上去每一趟都是 400,所以走的是单独一条路:命令行 `openworkbuddy jev`、接口 `/api/decide`、设置页里加一条渠道点「测一下」(那个按钮认得出它,不会拿对话接口去 ping 一个必然的 400)。**配过 OpenRouter 的人什么都不用填**,原来那把 Key 直接能用。第一处真用上它的地方是**目标模式的验收**:原来让对话模型对着几条标准吐一段 `{"results":[…]}`,那是拿会写字的东西模拟一张表格,它偶尔就不按格式回话、整轮打勾原地不动;现在每条标准是一道是非题,格式在类型上就跑不掉。更要紧的是多了一格确定度——**过 70% 才打勾,没过线的留着不打并在卡上写清是「拿不准」而不是「没干」**,因为这张卡最骗人的地方就是打了勾的人就不再看了。没配这个模型的机器上安静退回原来那条路,行为一个字节不差。额度按**题数**记不按请求数记(一次能塞 32 道题,按请求记那道闸等于没有),输出 token 不要钱,一趟三道题约两万分之一美金。
- **09-18** 侧栏的**任务历史能搜正文了**,还能按意思搜。原来那个放大镜只筛标题,可标题是任务跑完自动起的,用户从没读过一眼——他记得的是自己当时打的那句话(「把这个 csv 里重复的行挑出来」),或者最后拿到的那个文件名(「清洗结果.xlsx」)。按标题筛这两种记法一条都找不着,只能一条条点开看,点到第五条就放弃了。现在按三种命中找,**每条都标清楚是靠哪一种找到的**:标题 / 产出文件 / 对话里 / 词面接近 / 意思相近。不标的话,语义命中那几条看起来就是凭空冒出来的不相干任务,人只会觉得搜索坏了。打字时本地立刻筛标题、不等网络(等的话列表会空一下,而空列表看起来跟「没搜到」一模一样),300ms 后服务端那一路跟上并接管;搜挂了就退回本地筛标题**并说明是挂了**,不拿「没搜到」糊过去——那是两件事。没配嵌入渠道时结果里明说「意思相近这一路这次没走」,不悄悄降级。命令行的 `/resume` 同样吃这一套:`/resume 重复的行` 接得上标题里没这几个字的那条,选单里只靠正文对上的行会标一句「对话里」。搜索照样过归属过滤——**侧栏看不见的会话也搜不到,搜索不是绕过归属的后门**。
- **09-18** 选择器顶上补了个**搜索框**,而且一直摆着。原来是打了字才在标题后面回显一句「搜「周报」」——于是没打字的人根本不知道这儿能搜;「打字搜」那三个字是写在脚注里的,夹在一串按键提示中间,没人会去读一行提示。现在框在第一眼就杵在那儿,空着的时候写明筛的是什么(`/resume` 是标题 / 会话 id / 来源,`/model` 是型号名和厂商),打进去的字原样回显、光标跟着走。**搜空了框里也留着刚打的词**——一清空人就不知道该退格删什么。脚注顺手把「打字搜」删了:框已经在眼前,同一句话说两遍只是把按键提示挤长。
- **09-18** 终端里接回之前那段对话,从「数序号」变成「挑」。`/resume` 不带参数弹一个选择器:↑↓ 挑、打字实时搜(标题、会话 id、来源都在搜索范围里)、回车接上、Esc 算了,桌面端开的那些也在同一张单子里,每行标着来源、聊了几轮、多久以前。原来是印一张带序号的表让人对着敲——序号得用眼睛数,数错一位接的就是**另一条会话**,而且这种错要到下一句话答非所问才发现;会话一多还会翻屏,第 13 条根本不在表上。`/model` 走的是同一个选择器,两条命令共用一套交互,省得长出两种。列表比屏幕长就自己滚,选中的那条始终留在窗口里——露不出来的话人按着按着就不知道按到哪儿了。**管道里跑、或者这台终端画不了覆盖式界面,两条都自动退回老样子**(印一张表、敲序号),跟 `/` 菜单共用同一个「这台终端不认」的开关:画花过一次,两边一起退,少一半交互也比把人的终端搅烂强。
- **09-18** 命令行补上三条一直缺的命令。`/compact` 手动把前面聊过的压成一段摘要腾地方——**手动敲的这一下不看阈值、也不看「关了自动压缩」那个设置**,那个设置管的是「别自作主张」,不是「不许我自己压」;原文照样归档,压完报一句「12 条并成 1 条,上下文 100k → 40k,省了 60%」,没压成就直说没压,不拿「还没到阈值」当交代。`/diff` 列这个会话动过哪些文件,**以工具调用为准、不听模型自述**——它说改了而没真调 `write_file` 的情况是存在的,听自述等于替它圆谎;文件后来被删了也照列并标「没了」,悄悄不显示是另一种圆谎。工作目录是 git 仓库的话顺带出 `git diff --stat`,不是的话明说「给不了逐行 diff」,免得人以为 diff 坏了。`/mcp` 报连接器接上了没有、各自带了几个工具,**没接上的要说清楚卡在哪儿**(token 过期就写 token 过期)——只打个叉的话,人只会反复重启,重启一百次也还是 token 过期。
- **09-18** `/init` 让它把当前工作目录摸一遍,写一份 `AGENTS.md` 放在根下:项目是干什么的、怎么跑怎么测、哪几个目录是主干、有哪些既定规矩。这份文件桌面端和命令行每趟活儿开跑前都会读,所以它准不准直接决定后面几十趟顺不顺。**它不是自己动手写文件,是把这句话交回去当一趟正常的活儿跑**——权限档、改文件前的确认、`/diff` 里的记录一个都不少;按一下命令盘上就凭空多个文件、中间什么都没问过,是这类命令最容易犯的错。措辞上也拧了两处:命令照抄真在 `package.json` / 文档里看到的那几条(不然它会顺手编一条 `npm test` 出来,而这个项目可能根本没有),规矩只写找得到依据的、找不到就不写,别拿通用建议凑满十条。目录里已经有 `AGENTS.md` 或 `CLAUDE.md` 的话先读完再增补,**不整篇覆盖**——那份八成是人手写的。
- **09-18** 两个键位,省得为了换个档去敲命令。`Shift+Tab` 循环切这一趟的权限档(只看不动 → 每步都问 → 自动改文件 → 转回来),每按一下当场把切到哪档、那档意味着什么打出来,而且**只管这一趟,配置文件一个字不动**。**这个圈里没有「全自动」**:那个键就挨着 Tab,误碰一下就把命令确认也关了,而人正盯着自己那半行字,根本不会去读屏幕上多出来的一行——要全自动得明着敲 `/perm full`。`Esc` 连按两下,把这个会话里问过的话摆出来挑一条,原样放回输入行改了重问。它**只管放回去,不回卷历史**:真把已经跑过的那几轮删掉,等于把模型做过的事悄悄抹了,而人看不见抹了什么;要重来开 `/new`,要接回去用 `/resume`,两条路都在明面上。顺带治好一处:`/d` 不再是谁的简写——`/diff` 和 `/drop` 都以 d 开头,收成简写就等于替人在两条里挑了一条,而他只打了一个字母。
- **09-17** 任务跑完,顺手问一句要不要把中间文件清掉。一趟短片任务拆出几百张帧图、一段配乐分出四条音轨、一次打包吐出一个 `node_modules`——成片交出去之后这些还躺在工作区里,一个月下来能占掉几个 G,而没人会专门去翻。现在任务收尾时多一张卡片:「这一趟顺手造了 N 个中间文件,占 XX」,按来路分成五组(抽出来的帧、分离出来的音轨、打包产物、草稿和临时件、一次性脚本),每组写清楚**为什么敢删**(成片还在、原音频还在、`package.json` 还在、这是跑一次就没用的脚本),勾好按一下就清,「先留着」什么都不做。首页「把事情交给我」那一屏也钉了同一个入口,上面直接写着此刻能腾出多少——这么高频的事得放在手边,藏在设置里的清理功能等于没有。**面板分两半是故意的**:上半是我敢说它是中间物的(可删,每条带理由),下半是「地方到底花在哪了」——按任务列出占用,只报数不评判。真正压着盘的往往是三周前那个视频任务的成片,规则永远不会去动它,但你得先看得见它才谈得上自己决定;那半边每行都能「只整理这个任务」或者直接在访达里打开。**红线**:`apply()` 只认这一轮 `plan()` 自己提出来的那份名单,名单外的路径一律拒——就算有人把 `../../users.json`、`/etc/hosts` 直接塞进请求也一样,因为这是个能删文件的接口,白名单之外根本不该存在第二条路。交付物(成片、报告、`交付说明.md`)在任何一条规则里都不参与;`package.json` 还在的目录才算打包产物;源码树里的 `.py` 不算一次性脚本;同一批 wav 只报一次,不会同一个文件被两条规则各算一遍。删就是真删、不进回收站——挪进 `.trash` 只是把同样的字节换个地方占着,而用户要的是空间回来;删掉的每一条都写进审计日志,事后查得到是谁在什么时候清的
- **09-17** 资料库不再拿一屏「点开告诉你文件不存在」的行糊弄人,而且两种原因分开治。**升级那次被挪走的,跟着搬家找回来**:`migrate.js` 会把工作区根目录下躺过一天的散文件收进 `以前的文件_日期/`,搬完之后资料库还拿当初记下的裸文件名去查,一整批好端端躺在盘上的文件被判成「已经不在」——它只是往下挪了一层。现在按新地址报出去,点开真能打开,顺手认领掉,免得同一个文件在「未归属」里再出现一遍。不做全盘按文件名搜是故意的:两个任务目录里各有一个 `cover.png`,搜回来很可能是另一份,而「打开的不是我要的那张图」比「说它不在了」更难发现;`at` 只在当前工作目录下认,因为它是要拿去当地址用的,在别的根里找到一个同名文件却给不出能打开的地址,比说它不在了还糟。**真删掉的那批,默认不摆出来**:一次视频任务拆出几百张帧图、分析完自己清掉,这些行摆在那儿,每一行都是一句「这儿有个文件」,点开却说没有,那一趟点击是纯亏的;整组都没了的任务整组不露面,留个只能点出「文件不存在」的空壳没有任何用处。但不是悄悄吞掉——底下写着还有几个没显示,一点就全回来(划掉并标「已不在」),这个选择记在 localStorage 里,不用每次重按
- **09-17** 公司买的各家 API 收到一个口子上,员工和别的程序都不再碰真 Key。上游 Key 在后台填一次,发出去的是一把 `sk-` 开头的虚拟 Key,对外是标准 OpenAI 协议——别人的代码一行不用改,`base_url` 换成你的地址就能跑。**不只是对话**:`/v1/chat/completions`、`/v1/embeddings`、`/v1/images/generations`、`/v1/videos/generations`、`/v1/audio/speech`、`/v1/audio/transcriptions`、`/v1/search` 七条路都在同一道闸子下面——公司买的从来不只是对话那一份,而漏在闸子外面的那几份恰好最贵(视频是按秒算的)。每把 Key 单独勾能力:只给生图的那把去调语音当场 401,而且 `/v1/models` 里根本不列对话型号——列出来的每个 id 都是一句「你可以叫它」的承诺,让它叫过去只拿到 401,对面的程序员会先去翻自己的代码,翻半天才发现问题出在一个能力开关上。生图生视频的产物落在 `/v1/files/<id>/content`:24 小时过期、过期即删,别的公司拿这个 id 去取返回 **404 而不是 403**——403 等于承认「这个 id 是存在的」。真 Key 只在服务器内存里拼进上游请求,日志和回包里都不出现;虚拟 Key 存的是哈希,界面上只看得到后四位,丢了只能重发一把,找不回来
- **09-17** 中转站的账按「这家怎么卖」算,额度是硬闸不是报表。对话按 token 计(元 / 百万 token,内置一份截到 2026-09-17 的价目,美元按 7.1 折),其余四种各按各的单位:生图按张、生视频按秒、语音合成按千字符、转写按分钟——统统折成 token 记的话账面会好看得离谱,而月底的账单不会跟着好看。单价三层覆盖:内置 → 后台改的 → 某条渠道单独改的;后台那张表按「能力 + 型号」改一条,存下去立刻生效,每一行标着这个价是内置的还是你改的,审计员看得见、改不动(能改就等于这一页上所有的账都能被改成 0 元)。算不出价的(比如刚上线的型号)单独记成「不知道多少钱」一列,**不记 0**——记成 0 的那一刻这笔钱就永远找不回来了。额度是先扣后结:发出去之前按预估扣住,回来之后按实际结算,超了当场返 402 `insufficient_quota`。三级上限:组织 / 部门模板 / 单把 Key,填 0 是不限。**员工在界面上自己点的、定时任务跑的,花的是同一笔预算**——以前只有对外那条路过闸,漏的恰好是能一直点「重试」的那半边。超额的提示说清是谁的额度满了:「整个组织这个月的预算用完了,不是你一个人的:上限 2.00 元,已用 2.10 元」——不说清楚的话,人会以为是自己手气不好,回去再点第二次、第三次
- **09-17** 工作区里点开 `.mjs`、`.py` 这类源码,现在按代码画:左边一栏行号(横着拉的时候钉在原地)、关键字/字符串/数字/注释分五色,而且**不折行**。原来它走的是给日志和纯文本调的那条兜底 `<pre>`——`white-space: pre-wrap` 加 `overflow-wrap: anywhere`,长 URL 不把面板撑宽是对的,可同一条规矩落到代码上就是从**任意位置**断字:`fun` 留在上一行、`ction` 掉到下一行,看着「像乱码」——字都是对的,断点全是错的。前端打包产物更惨:rolldown / esbuild 吐出来的 `.mjs` 常常整份文件就一行几万字符,糊成一坨。所以认出压缩产物(最长一行超过 400 字符)的时候默认先替你排好版——按 `{` `}` `;` 断行、跟着括号深度缩进,横幅上写着最长一行有多少字符,旁边一个「看原文」随时切回去。排版只加换行和缩进,一个字符都不改,也不回写文件。断行这件事**故意没用 AST**:打包器的产物什么怪语法都有,解析器一遇到不认识的就整份罢工,而一个只认字符串、注释、正则的字符扫描器最差也就是断得难看,不会丢内容。这三样是必须认的——`var q="}}}"` 里的花括号不是结构,`/[/{};]+/g` 里的斜杠不是注释,`for(let i=0;i<3;i++)` 里的分号不是句末,每一样都有单独的测试盯着。着色按语言分六档(C 系 / `#` 注释系 / JSON / CSS / 标签系 / SQL),颜色是照深色底 `#16181f` 量过对比度的(注释那档从 3.1 提到 5.2——注释是拿来读的,不是拿来隐身的)。超过 5000 行只画前 5000 行,横幅上直说(文件本身没被动过,下载下来是完整的)
- **09-17** 装别人的技能之前先体检一遍。技能正文本身就是写给 agent 看的指令,而 agent 手里有 shell——一个链接装进来,它下一次干活就照着做。现在装之前扫一遍:目录、GitHub 上单个 `.md`、界面上自己粘一段,三条路都过同一道闸。分三档:**能过**照装;**有话说**(外网地址、装依赖、读环境变量)把原文摘出来给你看,再点一次确认;**别装**(`curl | bash`、读 `id_rsa`、翻 `~/.aws`、`rm -rf ~`、反弹 shell 之类共 10 条)直接拦下,只有平台管理员能强行放行,放行这一下会记进日志、也写进技能目录里的 `.install.json`——从哪个仓库哪个 commit 装的、谁放的行、当时扫出什么,都在里面。不算分:34 条规则里只有 10 条会拦,剩下 24 条一律只提醒,因为「7.5 分要不要装」没人答得上来。看的是组合不是关键词:`printenv` 单独出现不算什么,跟一个往外发的地址凑在一起才算;一句话前面有「不要 / 别 / 禁止 / 严禁」就不当回事——「不要用 `curl | bash`」是正经的安全提示,不是攻击。技能开头那段 frontmatter 里的提醒会升成拦下,因为 `description` 会被塞进**每一条**任务的系统提示词里,藏在那儿的一句话是全天候生效的。**它拦不住的那部分也说清楚**:同类静态扫描在公开数据集上只抓到约四分之三,四条里放过一条;而在本仓库自带的 34 个技能上,误拦率实测 5.9%(2 个,都是真命中的字面,不是假警报)——这个数字钉进了测试,以后改规则一旦误拦变多,CI 当场红
- **09-17** 技能和连接器体检可外挂 [toolward](https://github.com/CatCatUncle/toolward) 当第二把尺子:两份结论合并,只会更严不会更松;不进依赖、不走 `npx`,递过去的连接器配置已脱敏。开关 `OPENWORKBUDDY_TOOLWARD=off / advisory / auto`
- **09-17** 成片能垫配乐了:画布上摆一个「声音」节点、素材用途写「配乐」,合成面板里就多一个「垫上配乐」的勾,用的是哪一首也写在勾旁边(画布上摆着好几段音乐时,混错了只能整条重跑)。一说话音乐自动压低(本机 ffmpeg 带 sidechaincompress 才有这一路,没有就固定音量垫着——开跑前就说,不是拼到最后一步才报错);音乐比片子短就循环,比片子长也不会把片尾拉出几秒黑屏;台词一分贝都不会小:ffmpeg 的 `amix` 默认把每一路都除以 2,这是最容易悄没声把整条片子的对白弄小一半的地方,所以人声先乘回来、混完还过一道限幅
- **09-17** `wb` 这个简写在仓库里彻底退休了——上次改名只动了命令名,剩下的都还挂着。环境变量 `WB_*` → `OPENWORKBUDDY_*`(`WB_HOME` 是宿主机目录,跟容器里的 `OPENWORKBUDDY_HOME` 不是一回事,另起名叫 `OPENWORKBUDDY_DATA`),Docker 数据目录 `wb-data/` → `openworkbuddy-data/`,备份文件名 `wb-backup-*.tar.gz` → `openworkbuddy-backup-*.tar.gz`,登录 Cookie `wb_token` → `openworkbuddy_token`,浏览器本地的那些键和 CSS 变量 `wb-*` / `--wb-*` → `owb-*` / `--owb-*`。顺带治好一处对不上:交互模式的帮助里还印着 `wb>`,真提示符早就是 `openworkbuddy>` 了。**升级要做两件事**:Docker 部署的把目录改名 `mv wb-data openworkbuddy-data`、`.env` 里的变量名照 `deploy/env.example` 重抄一遍;所有人重新登录一次(Cookie 换名了)。不用手动搬的:侧边栏的任务历史会自己迁过去,老备份包照旧认得出来、还在列表里
- **09-17** 切换对话时输入框上头那根「上下文 87%」不再赖着不走。这根条全界面只有一根,而且只在任务跑起来、后端播事件的时候才重画;换到一条还没开跑的新对话既没有事件可等,也没人去收它,于是上一条那句「下一轮开跑前会自动压一次,想留全文就另开会话」原样挂着,指的却是别人家的数——新对话明明是空的,看上去却像一上来就快满了。现在三条换对话的路(点历史记录、跟一趟终端里起的任务、开新任务)都先把它收回去,本会话自己的数回放到了再填回来;顺带堵上另一半:后台并行跑着的那条会话,不再把它的余量画到你眼前这条对话上
- **09-17** 补上一道分公司之间的墙。按相对路径找文件时,兜底那一遍会把**所有记得住的工作目录**挨个扫一遍——包括别的分公司的,于是分公司的人光凭一个文件名、或者把别人那个目录的指纹抄进地址栏,就能把总部的文件读出来。现在候选目录先过一道租户过滤,租户外的一律不认;同一个租户内部跨子项目照旧找得回来,个人版(没有登录态,比如飞书回调和定时任务)一字不差走老路
- **09-17** 执行追踪里那一串一模一样的名字治好了。名字原来取的是**整段对话的第一句**,可一轮对话开一条追踪、传进来的又是整段历史——同一个会话聊十轮,列表上就是十行「OpenWorkBuddy日志技术选型」,点进去才知道是哪趟。现在取的是**最近那句有内容的话**,「继续」「好的」「嗯」「ok」这种接不上的短句自动往前找一句(「继续把日志接上」是正经需求,不算);再给每条标上「第 N 轮」,名字撞车也分得开。**已经写进账本的老记录也一起分开了**:磁盘上的字不改,但每条都存着当时的完整输入,读的时候照新规矩重算一遍——只认「名字正好以这段历史第一句结尾、而后面还有别的话」这个旧规矩留下的指纹,自己起的名字碰不着,不会被乱改
- **09-17** 忘了密码、手机也丢了,不用等管理员了:在服务器本机敲 `openworkbuddy passwd <用户名>` 随机发一串新密码(也可以直接把新密码写在后面),`openworkbuddy 2fa <用户名>` 看二次验证开没开、`--off` 关掉。改完当场把这个人所有登录状态作废。**这两条只认本机命令行、绝不接到 HTTP 上**——凭的是「你能读到服务器上的 users.json」,本来就已经是最高权限,再开一个网络接口才是真送分
- **09-17** 入职和离职各收成一步,办完出一张回执。离职一次关完:账号停用、所有登录令牌作废、扫码配过的手机平板踢下线、他发出去还没用完的邀请码作废、二次验证解绑、名下的定时任务停掉并可以指名转给交接人(**转过去仍然是关着的**,让接手的人自己看过再开);对话记录、产出的文件、用量流水和历史审计原样留着——人走了账还得能对。两道防手滑:不能给自己办,也不能把组织里最后一个在职管理员办掉(办完谁都进不了后台)。入职:按部门模板套好角色和月额度,一个部门招第三个人时不用再去回忆前两个是怎么配的
- **09-17** 出了事能看见了:运行日志按天落盘、自动轮转不撑爆磁盘(敏感字段照样脱敏,Key 不会顺着日志漏出去),关键指标每分钟滚一份快照(请求量、耗时分位、失败率、各渠道花了多少),设置 → 运行状况一页看完,越线自动推到企业微信 / 钉钉。同一条规则 30 分钟内只报一次,**恢复了也说一声**——只报警不报恢复的系统,用不了两周大家就开始无视它。分位数改成了「最近邻」算法——样本少的时候,插值法算出来的 P95 是一个**从来没真实发生过**的数,看着比实际好
- **09-17** 用量账本拆成按月分片,顺带修掉一处**会让账悄悄少算**的老设计:原来整本账是一个 `usage.json`,每记一笔要整本读出来、插一条、再整本写回去,而且只留最新 2000 条——50 个人每天各用 10 次,**四天就撞顶**,后台的「本月用量」「谁在用」从此少算,还一个错都不报。现在一笔一行直接追加到 `data/usage/2026-09.jsonl`,追加耗时跟历史多长完全无关(老写法 10 万条要 262ms,每趟任务结束都付这笔钱),查「本月」只读一个分片,也不再封顶——被封顶丢掉的正是计费和审计数据。老的 `usage.json` 第一次用到账本时自动拆开,**不删**,改名成 `.migrated` 留在原地好对账。执行追踪那本也一起接上了轮转(最多留 6 本,约 144 MB 封顶)
- **09-17** 远程那两条路各给了一个开关,**默认都是关的**:「允许扫码接入远程设备」(手机、另一台电脑)和「允许从网页/手机操控终端里正在跑的任务」。装完就默默开着的话,人不一定知道自己刚把什么暴露到了局域网上。开关在企业设置里,**关掉的同时已经配过的设备下一次请求就被踢下线**——不踢的话这个开关就是假的:你以为手机断了,其实没断
- **09-17** 预览里的图能复制了:预览面板、无限画布的大图、资料库里点开的图,`Ctrl/⌘+C` 直接进剪贴板,粘到微信、PPT、飞书里都是图本身而不是一条本机路径;桌面版右键也多了「复制图片」「复制图片地址」「另存为」
- **09-17** 企业设置那条路由是把请求体里的 `settings` 整个交进来的,所以新加的表结构设置(部门模板、额度表)落盘前一律先拍干净:只认清单里的字段、角色只认 admin/auditor/member、数字夹进范围。不拍的话,认了这个键就等于认了请求体能往组织设置里写一张任意结构的表——里头塞个越权的角色,办入职时就照着建号了;顺带修掉一处会把整张表存成 `"[object Object]"` 的老写法
- **09-17** 命令行改名 `wb` → **`openworkbuddy`**。理由不是好听,是防混淆:`wb` 太短,容易被读成别家产品的缩写。`npm link` / 全局安装过的重装一次(`npm unlink && npm link`),补全脚本重新生成一份(`openworkbuddy completion zsh > ~/.zsh/completions/_openworkbuddy`),老的 `_wb`、`~/.wb-completion.bash` 删掉。选项和子命令一个没动,只是命令名换了
- **09-17** 密码这块补齐了三样:**密码策略**(企业设置里改最短位数 6-64、可选复杂度要求;注册、自己改密码、管理员重置三个入口一起管,系统生成的随机密码也跟着变长)、**二次验证**(TOTP,Google Authenticator / 1Password 都能扫,可全组织强制)、**忘记密码自助**(在跑着服务的那台机器上敲一句 `openworkbuddy passwd <用户名>` 就改回来了,不依赖邮件服务器;手机丢了进不去二次验证的还有 `openworkbuddy 2fa <用户名> --off`。登录页上就写着这两句话该去哪儿敲,不用翻文档)
- **09-17** 授权这件事说清楚了:**买商业授权不解锁任何功能**——只有一份代码,装的这份就是全部。买到的是三样:一张允许你拿它赚钱的许可证、商标与白标的口子、能找到人的支持。以前文档把「SSO、审计外送、内网部署」写得像现货,其实一个都还没写,现在明确标成路线图
- **09-17** 开了一个口子:部署配置、CI 流水线、`scripts/`、评测任务集与基线、技能模板 `skills/skill-creator/`、文档里的示例代码与格式规范,**额外按 MIT 发布**,商用也随便拿([清单](COMMERCIAL-LICENSE.md#按-mit-授权的部分))。同时写明:你自己写的技能、插件、连接器配置是你自己的作品,不是本项目的衍生作品
- **09-17** 把仓库整个盘了一遍「还有哪些能开源」:代码这侧已经没有可放的了,没公开的只剩第三方技能包(别人的授权)、来源不明的技能、用户数据三类,每类的理由写进了[边界文档](docs/开源与商业版边界.md)第 3 节;管理后台侧栏那个「企业版」徽章改成「管理后台」——它是页面名字,不该被读成档位
- **09-17** 资料库里的预览修好了:图片、Markdown、HTML、PDF 点开就能看;「名字还在、东西不在」会直说是哪一种(被挪走了还是读不出来),不再是一个碎图标、一片空白或者一句「读取失败」;清单里查不到体积的写「—」,不再撞下限撞出一个「1 KB」的假数
- **09-17** 桌面版点「新窗口打开」不再甩 `{"error":"未登录","setup":false}`:站内地址留在应用里开一个子窗口,登录 cookie 跟着走;只有真外链才交给系统浏览器——「本地部署预览」那条不在此列,它是另一个进程另一个端口、链接自带令牌,本来就该去浏览器(手机扫码也靠它)
- **09-17** 终端里它也会反问你一句了:岔路口(报告交 Word 还是 PDF)摆一道选择题,每个选项底下写清楚选它意味着什么;序号、选项名、名字的一小段都认,也可以不选、直接把想法打进去。**只有真有人坐在终端前才会问**——管道、`--json`、cron 里跑的那些,agent 收到的是「没人在线,按最合理的默认继续做」,不会挂在那儿等一个永远不来的回答
- **09-17** `openworkbuddy` 大修:`sessions` / `resume` / `engines` / `doctor` / `completion` 五个子命令(老选项一个没动),`-f` 带文件图片一起问、`--raw` 出原始 Markdown、`-V` 看版本;退出码分得开(`2` 是参数写错、`130` 是 Ctrl+C),认 `NO_COLOR` / `FORCE_COLOR`;三种 shell 的 Tab 补全跟 `--help` 长在同一张表上,加一个选项三处同时就有
- **09-17** 交互模式里打一个 `/` 就把命令菜单弹出来——记不住命令的人第一反应是打个 `/` 等着看有什么,不会去按 Tab;只弹不选,没按过 ↑↓ 或 Tab 就按你原样发走,终端不认那些控制序列就整场关掉菜单退回 Tab 补全,绝不把输入行搅成一团
- **09-17** 粘 Key 时多框进来的空格、换行、中文引号,保存那一刻就指出是第几个字符不对,不用等发出去收一个看不懂的 401;对话和生图 / 配音 / 生视频两路现在过的是同一道闸
- **09-17** `config.json` 落盘权限收成 0600:以前是 umask 给的 0644,同一台 VPS、同一台办公电脑上任何一个别的账号一句 `cat` 就把所有 Key 拿走;开机先收一次,把装了半年的老机器一并修好,`.bak` 跟正本一样收
- **09-17** 权限这一圈收完了:账号库 `users.json`、组织库 `orgs.json` 跟 `config.json` 一样 0600(里头是密码哈希、二次验证的种子和还没用掉的邀请码——同一台机器上别的账号 `cat` 一下,拿到的是一份能直接拿去登录的材料),`data/` 和 `logs/` 两个目录收成 0700。日志这条尤其值得单说:一行一条 JSON,带着谁在什么时候登录了、会话 id、报错原文和出错时的那几个参数,默认 0755 的话它就是一份**不留痕迹**的「谁在干什么」流水。目录是出生时就带着 0700 的,不是建完再改——中间那一瞬的 0755 也不留。Windows 上 chmod 基本是空操作,这条只在 macOS / Linux 上算数
- **09-17** 换 Key 进审计流水了:多管理员的组织里,谁把哪条渠道从哪把换成了哪把,事后查得到(两头都只记「前三位…末四位」,明文不进审计表)
- **09-17** 生视频认五家协议(通义万相 / 火山方舟 Seedance / 智谱 CogVideoX / MiniMax 海螺 / 硅基流动):先看渠道类型、再看地址域名、还能在 `config.json` 上逐条写 `protocol`,三条都认不出**就不发那一趟**——按条计费的异步任务白跑一趟要等好几分钟才看见错;不收尾帧的渠道传了 `last_frame` 也在发请求前拦下;手写的 `protocol` 不会再被设置页保存时抹掉;只做视频的渠道不再出现在对话模型的选单里
- **09-17** 回答正文里 `[调研报告](报告.md)` 这类指向工作区文件的链接点得开了(以前只认 `https:`,屏幕上原样印出一串方括号圆括号),键盘回车也认;认不准的一律不给链接,`javascript:` 和往地址里塞引号都进不了属性
- **09-17** 首页场景按「你要交出什么」重排,最后收成**三类**(文档与汇报 / 数据与内容 / 代码与设计)——分到五类以上,人就得先在脑子里给自己的活归个类才敢点,那一步本来就是多余的;同一件事不再两个入口、也不再有「金融服务」这种没法交办的行业名;无限画布挪到侧栏「项目」上面——项目底下挂着一列会长的子项,排在它后面的看着像「项目的最后一条」
- **09-17** 自进化修了一处会把规则吞掉的顺序错:超字数预算时砍掉的原来永远是**最新**那几条——人刚在评审页点了「采纳」、界面写着「已生效」,模型一个字都没收到,还不吭声。现在保新砍旧、点名砍了哪几条,尾巴那句「另有 N 条」也算进预算里
- **09-17** 提示词把「什么该问、什么自己定」收成三类(白做的关键信息 / 成品形态岔路 / 花钱不可逆和只有你知道的事),技术路线永远算自己定;音频视频一律先 `transcribe_audio` 转文字再动手,不许 `read_file` 读二进制瞎猜
- **09-17** 换电脑搬家闭环:设置 → 数据里能「立即备份」「下载」「导入备份文件」「恢复」,备份覆盖账号、组织、会话、IM 会话、记忆、个人偏好、用量账本、审计、`config.json`、定时任务、专家和自己写的技能;导入的包落盘前整个拆开校验,绝对路径、`..`、软硬链接、非 gzip 和顶层多余目录一律拒掉,恢复前自动再备一份 `before-restore`
- **09-17** 任务执行中再发消息可以自己选插队还是排队:插队打断当前步骤当场改,排队等这轮跑完再按顺序开;排队里的那条能撤回,这个选择记在本机、不跟着账号走
- **09-17** 按次收费的接口(搜索、生图、视频、语音、转写)加了额度闸门:超额前先问、记下谁花的和走的哪个渠道,企业后台按天、按月、按人翻账;默认不限额,自己带 Key 的个人用户不受影响
- **09-17** 企业管理后台的用量可以按时间范围、按成员、按模型筛选并翻页,不再只有最近 25 条
- **09-16** 飞书渠道补齐群聊与云文档评论闭环:群聊中 @ 机器人可执行任务并回传文字/文件;飞书云文档评论区 @ 机器人会识别目标文档、读取正文上下文,并在原评论线程回复;修正评论回复接口参数位置,避免 `field validation failed`;文档正文与用户评论分离传给 Agent,避免长文档被原样回显;去重状态跨重启保留
- **09-15** README 改成“先看到真实交付、再用一句话上手”的项目首页:首屏讲清本机文件交付,紧跟可复制的第一次任务和 Star/贡献入口;补齐英语用户的本地办公、自托管与 Agent 学习定位,新增 `llms.txt` 让搜索和 AI 摘要更易正确理解项目;同时补齐 DAG 排版依赖的 MIT 署名,完整测试重新全绿
- **09-15** 无限画布交互收口:空白处左拖平移、`Shift`+拖拽框选、框选后拖任一节点整体移动;节点正文只选中不弹属性,只有齿轮才打开设置,避免操作时遮住画布;顶部间距收紧,把更多高度还给画布
- **09-15** README 首屏改为脱敏的真实任务演示(输入 → 执行 → 文件预览),AI 短剧无限画布移到功能介绍之后,新增脱敏 DAG 效果图和独立录屏;录制脚本不会再把画布录屏覆盖到 README 首屏
- **09-14** AI 短剧无限画布进入可用版:画布 Agent、DAG 连线与紧凑排版、框选/撤销/右键操作、节点属性与素材预览、图片放大、视频/音频播放、工作区切换、@ 引用、模型选择和本地 Trace 全部收进同一个短剧工程;README 新增真实运行、完全脱敏的无限画布录屏 GIF,方便贡献者快速理解产品
- **09-14** 增加 AI 短剧无限画布模式:剧本、角色、场景、分镜、素材、生成结果和本项目 Agent 在同一张可执行画布内协作,支持多张短剧工程、素材拖入、框选批量操作、自动排版和画布内对话
- **09-14** 优化无限画布短剧创作 UI:参考图/视频/音频可预览,图片支持放大查看,画布对话支持附件、`@` 引用节点与素材、执行模式和模型选择
- **09-14** 飞书消息去重跨重启持久化:已处理的消息 ID 写入本地数据文件,重启后不再重复执行旧任务;文件只保存消息 ID,不保存消息正文或联系人信息
- **09-13** 讲故事的片子能拍了:先把分镜表摆出来给你点头,再角色定妆照 → 每镜首帧 → 生视频 → 配音 → 拼成带字幕的竖版片;改哪一镜就只有那一镜再花钱
- **09-13** 同一格重跑不再花第二次钱:生图 / 生视频 / 配音的参数跟上一次逐字一样时,直接复用上次的产物,连模型都不调(确实要换一版,工具参数加 `no_cache: true`);另开了一条不过模型的直调口 `POST /api/tool/run`,「同样的参数原样再跑一遍」这种确定性动作不用再烧一轮主模型的 token 去把提示词复述给它听,它也没机会顺手改写你那句话——能这么直调的只有生图 / 生视频 / 配音 / 网页截图这四个
- **09-13** 企业后台的渠道表能自己加、能改、能删了:自建网关、公司内网代理、换了域名的私有部署这些预置目录里没有的,点「新渠道」当场填;同一个地址挂了两条会标出来而不是并成一条(各是一个账号一把 Key、各花各的额度),删渠道之前先把连坐的数报清楚——底下挂着几个对话模型、几个媒体模型、默认模型在不在里面
- **09-13** 命令跑不起来时不再只甩一句 `command not found`:认得出的外部工具会直接说清缺的是哪个、它管什么、这台机器上(mac / Windows / Linux 各不一样)该敲哪一句装;`ffprobe`、`libreoffice` 这类别名会折回它所属的那个包,不会让人去搜一个根本不存在的东西,认不出的命令则一个字都不加
- **09-13** 「任务最大运行时间」的默认值四处对不上——配置模板写 10 分钟、代码按 30 分钟跑、设置页文案又写「默认 10」——现在统一成 30 分钟,并把「自动续跑轮数」补进配置模板(默认仍是 0,因为每一轮都真花钱);图文成片技能也多了一条前置提醒:分镜超过 6 段先去把步数和时长调上去,别让片子断在最后一步拼装之前——那时候图和配音的钱都已经花完了
- **09-13** 出图、出片、配音现在能在同一轮里一起跑,默认同时 2 条(设置里 1-4 可调):一集短剧十二个镜头不用再一条条排,但每条都花钱所以给得比搜索那档保守;顺带修掉没起名的产出在同一毫秒里会写成同一个文件名、后一张盖掉前一张还两张都报成功的坑
- **09-13** 生图能喂参考图(最多 4 张),生视频能定首帧、尾帧:同一个人同一件商品跨镜头不再长变样;文生/图生型号选反了在发请求之前就拦下来,渠道真不认也明确报错,不偷偷退回纯文生
- **09-13** 会议纪要师、合同审阅员、邮件沟通师、项目经理、产品经理、招聘专员、客服话术师这七位现在各带一本写死的作业规范,交出来的东西有固定结构、有红线,不再是每次一个样
- **09-13** 配一条 SMTP,AI 就能把写好的报告、做好的文件直接发到对方邮箱;收件人白名单是硬闸,每封信出门前还要你看全文点头
- **09-13** AI 能自己排定时任务了:「每周一早九点把上周数据整理成表」说一句就定下,到点自己跑
- **09-13** 录音、会议视频、语音留言直接转文字,转完接着往下写纪要,不用自己再听一遍
- **09-13** 甲方发来的 Word / Excel / PPT / PDF 直接读,资料库里的素材随手取,做完的东西一句话推到群里
- **09-13** 终端里也看得到产出的图了:`/open` 交给系统程序打开,认得出的终端直接画在对话里
- **09-13** 发版这条链补齐:PR 有红绿灯、版本号对不上当场红、单平台挂了不拖垮整次发版
- **09-13** 做网页不再千篇一律:动笔前先挑视觉方向,同一个需求两次做出来不一样
- **09-13** 每一步花了多久直接写在卡上,收尾再记一笔账:工具占了多久、剩下多少是模型在想
- **09-13** 接 Langfuse 就能翻每次模型调用的原始输入输出,一层层点开看
- **09-13** API Key 五连坑一起修:填了不认、每次弹向导、渠道重名、没地方填、模型不齐
- **09-13** 企业管理后台补「模型与 Key」页,管理员在后台就能配,不用回首页
- **09-11** 侧栏分「办公 / 工程」两条线;终端里 `openworkbuddy` 起的活儿,手机上看得见、插得上话
- **09-11** 生图 / 生视频 / 配音 / 视觉都能配多个模型,同一家的 Key 只填一次
- **09-11** 「下载了打不开」修了六种,每种都有窗口说清原因,另附一份启动日志
- **09-11** 装机包瘦了 139 MB:source map 和类型声明运行时一个字节都不读
- **09-11** 「检查更新」不再劝装了包的人去 `git pull`
- **09-11** 补三处高危:改一个字母绕过门禁、文件名能执行命令、预览站点对全网敞开
- **09-11** 多人服务器上,普通成员不再看见一排点了必然 403 的按钮
- **09-11** UI 精致化:三级表面层级、统一投影、修掉不可见的滚动条
- **09-10** 任务历史不是丢了,是被一个凭空编出来的项目名滤没了——已修
- **09-10** 一条命令部署到服务器:`bash deploy.sh`,加 `--domain` 直接带 HTTPS
- **09-10** 多租户 + 企业管理后台:16 个面板,管理员、审计员、成员各看各的
- **09-10** 不许「没做完就收摊」:收尾前对一遍进度档,还有没打勾的就打回去
- **09-10** 执行过程一行流:每步一行,原始入参和完整返回收在卡里点开就是
- **09-10** 长回复不卡了:十万字流式,DOM 重建 19.7 秒 → 0.7 秒
- **09-10** Goal 目标卡:拆验收、判分都走你本机 CLI,不偷偷烧 API 额度
- **09-10** 微信 / 企微 / 公众号 / QQ 也能收文件、图片、语音、表情了
- **09-10** 飞书扫码新建应用,App ID 自动填回
- **09-09** 任务完成不再弹面板抢版面,产出收成一排 chip
- **09-09** 连接器 39 个预设一键接入;专家加到 15 位 + 4 支专家团
- **09-09** 中英文一键切换;外观页给了主题、六套皮肤、字号和密度
- **09-08** 首次开箱五步向导,打开就带你配好模型、引擎、IM
- **09-08** 本机 Claude Code / Codex 当引擎,记忆、技能、读文件、生图配音全接上
- **09-08** 带 reasoning 的模型可以关掉思考或调强度
- **09-07** 定时任务加「假绿」裁定:没抛异常不等于干成了
- **09-05** 命令行 `openworkbuddy`:单发 / 交互 / 管道 / `--json`,退出码说实话
- **09-03** 应用内直接预览 docx / xlsx / pptx / zip / csv
- **08-31** 粘贴、拖拽文件和图片进对话,agent 真能看懂图
---
[← README](README.md)