Merge branch 'master' into feat/design_agent_simple
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Repository checks (push) Successful in 2m48s
Project CI / Frontend tests (push) Successful in 3m26s
Project CI / Backend tests (push) Successful in 7m17s
Project CI / Native shell tests (push) Successful in 19m27s

This commit was merged in pull request #305.
This commit is contained in:
2026-09-09 16:34:16 +08:00
17 changed files with 201 additions and 58 deletions
@@ -8052,6 +8052,13 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 新建/恢复 ephemeral Codex thread 时,replay 使用 `contextWindowTokens`、`autoCompactTokenLimit`、本次 `maxOutputTokens` 与 4096 安全余量计算预算,从最新记录向前选择连续完整的 `user` / `assistant` / `tool` 行;超预算旧前缀被省略,单条记录不截断,当前 user request 始终保留。
- 发生省略时在 prompt 开头加入普通 `system: Earlier conversation history was omitted due to context budget.` 提示;当前请求本身超过硬上下文预算则直接失败。该策略是 Direct 专用滑动窗口,不复用 Runtime Agent 的摘要、tail 或 session compaction 生命周期。
## 2026-09-05 共享 CanvasWorld 统一超采样与资源页迁移
- 背景:资源总览页曾在业务层重复实现 world 的渲染与尺寸逻辑,需与网站 / Tauri 共用的 `@genarrative/image-canvas-react` 统一。
- 决策:`CanvasWorld` 的公开契约为逻辑 `viewport`,最终视觉比例由 `viewport.scale` 定义。渲染细节由共享包封装,调用方不得自行换算。所有调用方继续使用共享默认正方形 `CANVAS_WORLD_SIZE = 12000`,不引入 `worldWidth/worldHeight` 等矩形 API。资源页 `navigationBounds` 只保留布局、fit、依赖线 geometry 和 data 属性用途,不再驱动 world DOM 尺寸。非缩放描边只应用于资源依赖关系线等几何 overlay,静态卡片图标不继承统一 SVG 描边规则;位图维持浏览器默认插值,不全局启用 `pixelated`。
- 影响范围:资源总览迁移为直接渲染共享 `CanvasWorld`,卡片控件通过共享 inverse-scale CSS 变量保持屏幕级尺寸;Asset Canvas、UI Editor 和依赖线继续消费相同 viewport 坐标与事件换算,不改变业务状态或持久化合同。
- 验证方式:调用方测试以预期逻辑 `{ x, y, scale }` 调用公开 helper `canvasViewportToWorldTransform`,再与实际 world 的 `style.transform` 比较;不手写渲染换算,不以缩放按钮文案替代 viewport 断言。运行共享包与 AGC 定向类型 / 测试、资源页集成测试、`npm run check:encoding` 和 `git diff --check`,覆盖 SVG 描边、拖拽坐标、关系线端点和默认 world 尺寸。
## 2026-09-07 DirectProject 用户消息由 AGC 预写并过滤 Codex 回显
- `.agent/conversations/project.jsonl` 中的 DirectProject 用户消息由 AGC 在 `turn/start` 前以 `direct-codex:{clientTurnId}:user` 幂等追加;写入失败时禁止发起 Codex turn,失败或中断也保留该 user item。
@@ -5023,3 +5023,11 @@
- 外层 `start-tauri-dev.mjs` 应在启动 Tauri 前完成配套开发服务准备,并统一收束自有服务进程树;不要让冷编译和数据库发布挤占 Tauri 的前端就绪等待。自动发布必须保留数据库,不能靠清库解决启动问题。
- CLI 与 standalone 可能是两个独立软链接。必须同时核对 `spacetime --version` 和 `spacetimedb-standalone --version`,不能把 CLI 的版本记录当作宿主版本证明;PATH 中存在宿主时启动器检查两者一致。更换宿主前停机备份数据,按原目录启动,不通过清库处理版本错配。
- Router 配置缺失不应只在首次请求时报错。API/All 启动必须先校验官方地址、固定模型、provisioning secret、管理员 Token 和凭据加密密钥;否则服务看似 healthy,但登录后的 provisioning/模型调用才延迟失败。
## 共享画布框选需要识别 world 的真实后代命中
- 现象:共享 `CanvasWorld` 在 world 外层增加 `.genarrative-image-canvas__world-content` 后,点击或拖拽空白画布时事件 `target` 是内层 div;框选逻辑若只检查外层 world 本身,就会只清除焦点而不创建选框。
- 原因:viewport 上的 pointer 事件通过冒泡接收,`event.currentTarget` 是 viewport,空白区域的 `event.target` 可能是 world 的任意后代,不保证命中外层元素。
- 处理:框选命中判断使用 `Element.closest('.genarrative-image-canvas__world')`,并保留 viewport 自身命中路径;回归测试通过真实 `CanvasWorld` DOM 的 `pointerdown` 冒泡覆盖内层 world content。
- 验证:`src/components/image-editor/useImageCanvasStageInteractions.test.tsx` 覆盖内层 world content 命中,定向交互测试通过。
- 关联:`packages/image-canvas-react/src/useImageCanvasStageInteractions.ts`、`packages/image-canvas-react/src/CanvasWorld.tsx`。