4148 Commits

Author SHA1 Message Date
k88936 551fb6609a 为 Raw 编辑建立独立字节类型
恢复旧图片链路的 Vec 字节契约

让新增 raw_edit 输入和结果类型独立于既有 ReferenceImage
2026-09-12 11:15:15 +08:00
k88936 d05440dcca 为 Raw 编辑建立独立字节类型
恢复旧图片链路的 Vec 字节契约

让新增 raw_edit 输入和结果类型独立于既有 ReferenceImage
2026-09-12 11:13:27 +08:00
k88936 7edf4a8f8b 恢复旧图片链路字节类型
Project CI / Repository checks (pull_request) Failing after 13s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Frontend tests (pull_request) Successful in 2m43s
Project CI / Native shell tests (pull_request) Failing after 14m6s
撤回非 raw_edit 的全局 Bytes 迁移

保留既有 VectorEngine 与编辑器路径的 Vec 字节契约
2026-09-12 11:06:05 +08:00
k88936 727794bc95 Merge branch 'master' into boot-time-diagnosis
Project CI / Repository checks (pull_request) Successful in 2m43s
Project CI / Frontend tests (pull_request) Successful in 3m12s
Project CI / Backend tests (pull_request) Successful in 7m13s
Project CI / Native shell tests (pull_request) Successful in 20m20s
2026-09-12 10:58:33 +08:00
k88936 cc9b95ddef 优化调试配置:提升SHA-256计算性能,避免调试构建阻塞
Project CI / Repository checks (pull_request) Failing after 14s
Project CI / Backend tests (pull_request) Failing after 14s
Project CI / Frontend tests (pull_request) Successful in 3m5s
Project CI / Native shell tests (pull_request) Successful in 20m20s
2026-09-12 10:54:51 +08:00
k88936 afc9ecbd51 补充 WebP 源图转码测试
验证 WebP 输入可转换为 PNG 上传格式
2026-09-12 10:42:15 +08:00
k88936 fc2f4b71ce 支持分离流程转换非 PNG 源图
在上传图片编辑请求前将 JPEG 和 WebP 转码为 PNG

新增 JPEG 转 PNG 单元测试并将转码放入阻塞任务
2026-09-12 10:38:00 +08:00
k88936 545f64cf9e 补齐原图编辑失败追踪事件
provider 失败时记录 external_generation_run 失败状态

保留现有外部 API 失败审计与错误映射
2026-09-12 10:37:04 +08:00
k88936 2a50614c11 将分离恢复阻塞 I/O 移出异步线程
新增 spawn_blocking 状态读取封装

sidecar 目录创建改用阻塞任务执行
2026-09-12 10:23:32 +08:00
k88936 915006c98f 适配绑定区域类型错误调用方
在区域归一化边界转换 typed error 为展示文案
2026-09-12 10:23:21 +08:00
k88936 69ce232a74 为绑定区域校验引入类型错误
用 ZeroDimension 和 OutOfBounds 区分边界校验失败

补充 typed error 单元测试并保留展示层中文文案
2026-09-12 10:20:17 +08:00
lhk229 22c4807612 删除策划对话栏未接通的文件浏览死接线
Project CI / Repository checks (pull_request) Successful in 2m21s
Project CI / Frontend tests (pull_request) Successful in 2m56s
Project CI / Backend tests (pull_request) Successful in 5m52s
Project CI / Native shell tests (pull_request) Successful in 17m55s
DesignAgentSurface 移除从未消费的 files 与预览 props

ProjectSupervisorView 同步移除死 props 声明与透传

App 移除 designWorkspaceFiles 等状态与 refreshDesignWorkspace,每轮策划事件不再多打一次 list_design_workspace
2026-09-12 09:44:09 +08:00
suzmii 3f7e41e466 「所有资源」展开态改回平铺画布:不再为每个栏目渲染标题栏
Project CI / Repository checks (pull_request) Successful in 2m50s
Project CI / Frontend tests (pull_request) Successful in 3m19s
Project CI / Backend tests (pull_request) Successful in 7m23s
Project CI / Native shell tests (pull_request) Successful in 19m4s
展开态真实栏目不再渲染栏目标题栏,整个场景只留 all 那一条钉在视口上、带「资源总览」收起入口的标题栏

原因是分带只为有可见资源的栏目生成,空栏目拿不到标题栏矩形后全部回落到世界原点叠成一摞(空项目必现,现场是 7 条)

ResourceBookSceneCategoryPlan 新增 titlebar 字段,渲染层按它决定是否产出标题栏节点

分带去掉标题栏横带的高度预留与矩形换算,删除 RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT 与 resourceBookAllTitlebarRects

拖动写回口径不变(resourceBookAllBandLocalPoint 一行未改),零 CSS 变更

resourceBookLayout.test 与 appSurface 两条「所有资源」用例加反向守卫;变异验证改回旧行为时两条同时红(got 7)

decision-log 与 pitfalls 记这次倒因为「缺一路坐标输入时不要静默回落到原点」
2026-09-12 09:38:03 +08:00
suzmii 5b62d1e4ef 修复资源登记把任意图片写成 ui 类型
Project CI / Repository checks (pull_request) Successful in 3m17s
Project CI / Frontend tests (pull_request) Successful in 3m55s
Project CI / Backend tests (pull_request) Successful in 6m29s
Project CI / Native shell tests (pull_request) Successful in 17m16s
停用本地导入图片的 ui 默认 kind:agent_local_project_file_type 的图片扩展名分支改写 canonical image(派生 unclassified,落「待归类」),并注明不许把 ui 当图片默认值及其不可恢复原因——读时自愈只在落盘 category 为 unclassified 时触发,kind 本身写错时自愈只会把错值放大成 ui-interaction
账户素材导入改用平台真实类型:新增 imported_platform_asset_kind,账户素材库记录自带的 assetKind 不再被常量 ui 顶掉,缺失才退回中性 image
平台素材导入改用响应里的 assetKind:网页项目画布与平台素材导入同样走 imported_platform_asset_kind,不再写死 ui
上传素材按内容证据推导 kind:upload_local_asset_at 不再把来源词 uploaded 当类型,改由 uploaded_asset_kind 按 mediaType 与扩展名推导 audio/video/image/document/code,判不出才用中性 asset;同一命令也收 .wav 与 .md,因此不能一刀切成 image
补 4 处回归与反查用例:本地导入与上传断言落盘 kind 与 category 且不得出现 ui、ui-interaction、uploaded;两处平台导入的 kind 解析加纯函数单测与调用点反查门禁;变异把错值改回来必须变红(M1/M2/M3 实测 4 个用例全红,还原后 diff 与基线逐字节一致)
覆盖边界:账户素材库与平台素材导入是异步 HTTP 路径,仓库内没有可复用的端到端夹具,这两条覆盖是纯函数单测加调用点反查门禁,不是端到端断言;本地导入与上传是读落盘 manifest 的行为级断言
后续事项:ImportedAsset.asset_kind 仍返回平台原始值(缺失为 none),与已落盘 kind 可能不一致,本次未改动
2026-09-12 02:30:31 +08:00
k88936 319aa69d6e 统一分离树根节点坐标空间
子节点收集复用根节点实际解析矩形
2026-09-12 02:24:01 +08:00
k88936 bec468bdc9 统一分离终止节点判定
批次选择与提取提示复用同一终止节点集合
2026-09-12 02:23:02 +08:00
k88936 eada20c199 恢复自动切分前重新校验状态
继续分离前确认 sidecar 存在并检查前置条件

恢复入口异常统一写入工作流失败通知
2026-09-12 02:20:52 +08:00
k88936 e8cf773aac 统一自动切分失败完成提示
分离入口异常时写入工作流完成失败通知
2026-09-12 02:19:48 +08:00
k88936 12fbb61fad 限制分离恢复状态写入大小
写盘前校验与读取一致的八兆字节上限

超限时记录原因并拒绝不可恢复检查点
2026-09-12 02:17:55 +08:00
k88936 478e08fb92 将 PNG 依赖限定为测试环境
从生产依赖移除仅测试使用的 png crate

在 dev-dependencies 中声明 PNG 测试依赖
2026-09-12 02:13:52 +08:00
k88936 0e67fbf80a 停止对最终工作流步骤重复预检
资产分离作为最后步骤不再校验不存在的下一步
2026-09-12 02:12:15 +08:00
k88936 ed2cfbad36 避免预览容器变化重置缩放
自动适配仅在图片或逻辑尺寸变化时执行

通过尺寸引用保留初始视口兜底值
2026-09-12 02:11:22 +08:00
k88936 560422286b 稳定组件面板展开与移除交互
仅在组件存在性变化时自动展开面板

为移除组件增加确认并保留失败弹窗
2026-09-12 02:08:56 +08:00
suzmii 90177308e0 pitfalls:补记「同一条命令的口径差异」——CI 用提交范围比较 git diff --check
Project CI / Repository checks (pull_request) Successful in 3m17s
Project CI / Frontend tests (pull_request) Successful in 3m55s
Project CI / Backend tests (pull_request) Successful in 6m17s
Project CI / Native shell tests (pull_request) Successful in 17m11s
- docs/project-memory/shared-memory/pitfalls.md:在「只跑门禁子集 → 同一天两次 CI 红」条目的「原因」里补第三类成因
- 口径差异:CI 跑 git diff --check "${base_ref}"..."${head_ref}"(提交范围),本地裸跑 git diff --check(工作树 vs 索引)在干净树上恒为空,所以本地绿不能证明 CI 这一跳会过
- 实例:pitfalls.md 末尾多出的空行(f16aa440b 引入),因前两次推送分别停在 check:git-hooks 与 check:rustfmt 而一直未被这一跳检查
2026-09-12 02:07:49 +08:00
k88936 e04075fd95 为分离模型请求增加重试退避
瞬时请求失败时按递增毫秒延迟后重试

将重试循环末尾改为不可达断言
2026-09-12 02:07:02 +08:00
k88936 d7776f2a17 修正文生绑定提示语法
改进分离要求和返工建议英文表述
2026-09-12 02:05:18 +08:00
k88936 4d9e69841e 加固分离提示词生成
绑定提示改用切片参数避免多余复制

清理提取提示中的描述与返工备注文本
2026-09-12 02:04:32 +08:00
suzmii a5c7938d05 修 CI:去掉 pitfalls.md 末尾多余空行(git diff --check 报 new blank line at EOF)
- docs/project-memory/shared-memory/pitfalls.md:删掉文件末尾多出的一个空行,使文件以单个换行结尾(UTF-8 无 BOM、LF 不变,仅 -1 行)
- 该空行由先前提交 f16aa440b 引入;前两次 CI 分别停在 check:git-hooks 与 check:rustfmt,都没走到最后一道 git diff --check,因此一直潜伏
- 自检口径按 CI:git diff --check fafe6b63c..HEAD(CI 是提交范围比较;本地裸跑 git diff --check 在干净树上恒为空,看不出来)
2026-09-12 02:02:12 +08:00
suzmii 31fcbb79dc pitfalls:记一条「只跑门禁子集 → 同一天两次 CI 红」
Project CI / Repository checks (pull_request) Failing after 2m51s
Project CI / Frontend tests (pull_request) Successful in 3m29s
Project CI / Backend tests (pull_request) Successful in 7m5s
Project CI / Native shell tests (pull_request) Successful in 17m8s
- 现象:dd7cf401a 给 lint-staged 加 *.rs 键,但本地从未跑过 check:git-hooks(它是 npm run lint 链里的一环),而 scripts/git-hooks.test.mjs 用 assert.deepEqual 钉住 lint-staged 的整份配置形状 → CI 以 deepStrictEqual 失败;本批更早还因 check:rustfmt 红过一次(15660a98b 修 8 处格式偏差),成因是 pre-commit 的 lint-staged 当时只覆盖 *.{js,mjs,cjs,ts,tsx},Rust 格式本地无守卫
- 原因:npm run lint 是一条 && 长链(encoding / npm-workspaces / git-hooks / rustfmt / spacetime-schema / production-ops / preview-deployer / maintenance-page / eslint / typecheck),中间任一步失败则其后步骤根本不执行,「跑到第 N 步就以为本地绿了」;更隐蔽的是本地若因环境原因在中间断掉(如 Windows 上 check:git-hooks 第 2 个用例的 EBUSY),后面那些本来能通过的步骤也从未被验证
- 处理:push 前按完整链路跑;&& 链在某一步失败时,必须把失败步之后的每一步单独再跑一遍(10 步 + git diff --check)并逐条记 exit code(取 exit code 不要接管道);改动碰到 package.json / .husky/ / scripts/ 下的门禁资产时,check:git-hooks 是必跑项
- 验证:本次 check:git-hooks 因本机 Windows EBUSY 中断后,补跑其后各步全部 exit 0(spacetime-schema / production-ops / preview-deployer / maintenance-page / lint:eslint / typecheck / encoding),只有 check:rustfmt 红且红在别人在途的 .rs(assets.rs:519 落在其未提交 hunk +470,62、commands.rs:3079 落在其未提交 hunk +3068,58);变异验证:把 *.rs 从 package.json 摘掉 → 第 1 个用例以同样的 deepStrictEqual operator 变红,还原(SHA256 一致)后回 ok
- 纯文档追加:文件末尾 +8 行、无删改;本条只提交 docs/project-memory/shared-memory/pitfalls.md 一个路径
2026-09-12 01:28:05 +08:00
suzmii 21da95387b decision-log:把守卫范围与本地限制两条裁定写进既有条目
- 取舍 bullet 补裁定理由:保持「整个 workspace」检查、不换成只查暂存文件(rustfmt --check --skip-children 与 cargo fmt 的口径不一致);本批两次 CI 红的共同根因是「本地绿 ≠ CI 绿」,守卫必须与 CI 同口径
- 取舍 bullet 补流程归因:共树里的硌人是「共享 worktree」的症状、不是守卫的问题,对应流程修正是「一条线一个 worktree」
- 本地限制 bullet 定性为「本机环境限制,不是 CI 会红」,写明根因(Windows/WSL 跨 /mnt/c 的临时目录句柄在子进程退出后仍被持有)、删除重试实测无效且已还原、残留目录会累积(清前 16 个、最早 2026-09-05,本轮已清 0),并给出「Linux CI 上通过」的依据
- 明确裁定:接受该用例在 Windows 上红,不改它语义、本批不再修
2026-09-12 01:15:11 +08:00
suzmii 9fea60b850 append 锁:预算与项目写锁对齐、超时报可诊断的持锁方、争用做有界退避重试
Project CI / Repository checks (pull_request) Failing after 3m22s
Project CI / Frontend tests (pull_request) Successful in 3m46s
Project CI / Backend tests (pull_request) Successful in 6m30s
Project CI / Native shell tests (pull_request) Successful in 17m14s
- project/agent_db.rs:等待预算从 10ms×100≈1s 改为 5ms×2000≈10s,与项目写锁完整窗口同口径;新增 lock_short(5ms×200≈1s)供只读路径使用
- project/agent_db.rs:超时文案在锁路径后追加持锁方线索(读锁文件里的诊断元数据,读不到就明说不可读),现场不再只拿到一句"检查运行时配置"
- project/agent_db.rs:取锁成功后把 label/pid/processStartedAt/acquiredAt 写进锁文件;仅作诊断,不参与判活、回收或抢占,同一进程重复取同一把锁不重写
- project/agent_db.rs:抽出 PROJECT_APPEND_LOCK_TIMEOUT_MARKER 常量,控制流不再各自复制中文
- project/conversation.rs:整份读对话记录的两处只读入口改用短窗口,避免把面板读路径一起拖住
- agent/direct_project_history.rs:争用类失败做一次有界退避重试(250ms);格式类失败不重试
- agent/direct_runtime.rs:锁争用给可操作提示(另一个客户端进程正在读写该项目历史或项目锁,请稍后重试,确认没有其它客户端再重启),retryable 保持 true,但现在确实会自动重试
- 用例:预算口径、锁文件诊断元数据、持锁方线索、被独占持有时超时且不留残留、争用重试成功、超出预算失败关闭、格式类不重试
- 变异验证:预算常量改回 1s → 预算用例红(left 10ms / right 5ms);去掉重试 → 重试用例红(append after retry 直接报跨进程锁超时);验证后已还原
2026-09-12 01:09:37 +08:00
suzmii cafd989bfb decision-log:记录 pre-commit 新增 Rust 格式守卫的取舍与本地限制
- 新增 2026-09-11 条目:背景(本地无 Rust 守卫、CI check:rustfmt 是唯一防线)、决策(lint-staged 增 *.rs + 包装脚本对两个 workspace 只查不改)、连带维护点(git-hooks.test.mjs 钉住整份配置形状,增键必须同步)
- 记下刻意保留的取舍:无暂存 .rs 时不触发;一旦暂存 .rs 则按整个 workspace 检查(与 CI 同口径),副作用是别人的未暂存未格式化 .rs 会挡住本次提交
- 记下未修的本地限制:check:git-hooks 第 2 个用例在 Windows 因 finally 里 rmSync 报 EBUSY 而红(断言全过、红在清理),TEMP 里堆了 16 个残留目录最早到 2026-09-05,加删除重试实测无效,CI 在 Linux 上不受影响
- 不动历史条目:2026-08-12 那条的「提交门禁」一行按本文件顶部口径只用于追溯
2026-09-12 01:01:51 +08:00
lhk229 86adaa738f 修复策划首轮错 lane 挂载导致 Agent 不工作
Project CI / Repository checks (pull_request) Successful in 2m38s
Project CI / Frontend tests (pull_request) Successful in 3m19s
Project CI / Backend tests (pull_request) Successful in 6m24s
Project CI / Native shell tests (pull_request) Successful in 17m51s
运行模式改为随项目上下文同步派生,移除 effect 后置修正

做成游戏切换记录按项目路径与创建时间定位,跨项目自动失效

消除首帧游戏运行时挂载消耗首轮 claim 后策划实例无法补发的问题
2026-09-12 00:48:02 +08:00
suzmii 2a7bfadd72 修 CI:git-hooks 回归用例跟上 lint-staged 新增的 *.rs 守卫
- scripts/git-hooks.test.mjs 用 assert.deepEqual 钉住 package.json 的 lint-staged 整份配置形状,dd7cf401a 新增 *.rs 键时漏了同步,Repository checks(经 npm run lint → check:git-hooks)deepStrictEqual 失败
- 按新形态补上 '*.rs': ['node scripts/lint-staged-rustfmt.mjs'],不放宽断言:仍是整份配置的 deepStrictEqual,改回「只要含 js 那条就算过」这类弱化写法一律不做
- 第 2 个用例里的本地 lintStagedConfig 是 temp repo 的测试替身,不是对真实配置的期望:temp repo 里没有 Rust 文件,加 *.rs 只会命中 0 个文件,故不动
- 变异验证:把 *.rs 从 package.json 摘掉 → 本用例以同样的 deepStrictEqual operator 变红(# fail 2);还原(package.json 字节级哈希一致)后复跑该用例回到 ok
2026-09-12 00:43:49 +08:00
suzmii 77871bfa56 把可能弹 UAC 的 ACL 提权修复移出 append 锁的持锁窗口
- project/agent_db.rs:Windows 取锁成功路径不再在"已持有零共享句柄"时做带提权的 ACL 修复;持锁期间只做不提权的严格校验,校验不过就先释放句柄、再提权修复,并返回"这轮没取到锁"由外层重试循环按修复后的 DACL 重新打开
- project/agent_db.rs:新增 release_project_append_os_lock_then_repair_acl,参数按值接收锁句柄且函数体第一件事是 drop,使"边持锁边等 UAC"在签名层面无法被表达
- 原因:提权修复走 powershell Start-Process -Verb RunAs -Wait 同步等用户点 UAC,在持锁期间等它等于把用户犹豫的时间记进别人的持锁窗口;只有 Windows 存在这条路径
- 判据(结构级):提权修复只在此一处被调用,且调用点必须交出句柄所有权;测试环境不弹真 UAC(config.rs 测试分支本地收紧),故不写假 UAC 用例
- 真机判据:DACL 有缺陷的机器上,持锁方进入修复期间不再持锁,等待方从"超时"变为可成功
- 不变项:首次创建锁文件的本地 harden 仍留在持锁期间(本进程新建对象不因继承 DACL 自动提权)
2026-09-12 00:12:52 +08:00
suzmii 1affb5eec3 锁内只保留 append:DirectProject 历史的幂等回扫移出持锁窗口
- direct_project_history.rs:幂等回扫与序列化移到取锁之前,取锁后常态只做一次追加,不再在锁内读完并逐行解析整份历史
- direct_project_history.rs:回扫到取锁之间若历史文件变了(len/mtime 与回扫时不一致)才回到锁内重扫一次;同一 id 不写第二行的语义不放宽,只是常态不再为它读整份文件
- direct_project_history.rs:新增 direct_project_history_duplicate_at 三态判定(Absent/Identical/Conflict)与回扫状态快照,对外行为与原实现一致(幂等 no-op、id 冲突失败关闭)
- direct_project_history.rs:新增回扫探针(两个时点回调)与三条用例:回扫在 append 锁外、锁外回扫后并发追加仍不重复写、id 冲突仍失败关闭
- project/agent_db.rs:新增测试专用探针 project_append_os_lock_is_held_for_test,用与生产同一套打开方式判断追加写目标的锁此刻是否被持有
- 变异验证:把回扫塞回锁内后 idempotency_reverse_scan_runs_outside_the_append_lock 变红(exit 101),报出「幂等回扫必须发生在 append 锁外」,验证后已还原
2026-09-12 00:07:04 +08:00
suzmii f11942f357 展开态补回空态提示:复用栏目页同一个 .game-resource-page-empty 与文案,不新增样式
Project CI / Repository checks (pull_request) Failing after 1m18s
Project CI / Frontend tests (pull_request) Successful in 3m29s
Project CI / Backend tests (pull_request) Successful in 6m42s
Project CI / Native shell tests (pull_request) Successful in 17m44s
- index.tsx:展开态在"可见资源为 0"时渲染 <p class="game-resource-page-empty">没有匹配资源</p>,与栏目页那一条同一条判据口径与同一句文案
- 它挂在既有的画布浮层 host 下(该 host 自身不定位),因此按画本场景根居中,观感与栏目页一致,不需要任何新 CSS
- 测试:空项目的「所有资源」用例补三条断言——进入展开态后标题栏是 .is-active[data-resource-book-category="all"]、卡片宿主数为 0、空态文案是「没有匹配资源」(把"复用既有空态、不新增样式"变成可执行判据)
2026-09-11 23:55:36 +08:00
suzmii 85358b2ca5 「所有资源」页的决策与验收判据跟上当前形态:分带几何口径 + 两页共用同一份布局数据
- decision-log 新增「各栏目按分带铺在同一张画布上」:记分带几何(buildResourceBookAllLayout + resourceBookAllTitlebarRects 复用总览标题栏渲染路径)与冻结口径(只在项目/排序/可见资源集变化时重算,拖动不重算;签名不含 token 的理由),以及本轮不动的三处"仍是另一套"(依赖连线 / 空态分带 / 总览缩略卡网格)与它们的后续顺序
- decision-log 新增「两页共用同一份布局数据」:记裁决(不开独立空间、写回同一 mode 同一 sidecar 的同一 section、提交前减带原点)、"为什么不会写偏"的依据、与"历史手动坐标只读恢复/不删除/不重置/不迁移"不冲突的理由,以及用户可自证的往返判据
- 验收文档 S7 行判据改写:旧判据 data-resource-book-all-page / data-resource-book-all-host 已随网格分支删除,改钉 .game-resource-book-scene-card[data-resource-book-category](每张资源恰好一个宿主)、.is-active[data-resource-book-category="all"] 与 .game-resource-book-view;补上"展开态可拖且在栏目页看到同一位置"这条往返判据
- 验收文档 S7 期望结果同步:由"汇总页"改为"与栏目页同一套画本场景、各栏目按竖向分带铺开"
2026-09-11 23:40:12 +08:00
suzmii 0d98bd05cc 删掉「所有资源」页的独立网格样式:它已经走画本场景,这六条没有调用方了
- 删除 .game-resource-all-resources-host:整页 absoulte 层与自己的底纹(原本是为了盖住画本场景底纹、并躲开画布容器的滚动处理)
- 删除 .game-resource-all-scroll:分组网格的自身滚动容器
- 删除 .game-resource-all-section:按栏目分组的分节卡片(边框 / 圆角 / 半透明底)
- 删除 .game-resource-all-grid:repeat(auto-fill, 180px) 卡片网格
- 删除 .game-resource-all-card:网格里的卡片占位格
- 删除 .game-resource-all-grid .game-resource-card:只读页的光标与 touch-action 覆盖(展开态已可拖,卡片要保留画布那套 touch-action: none)
- 不留任何 all 专属替代规则:展开态的外观全部由既有的 .game-resource-book-scene-card / .game-resource-card 与共享规则给出("零新增 CSS"是本次红线)
2026-09-11 23:33:59 +08:00
suzmii 9788248d9b 「所有资源」页改走画本场景:与栏目页同一套卡片宿主与几何,并可拖动
- 新增 resourceBookShowsAllCategories:把"子画布里的 all"这一态判定收在 resourceBookModel 一处
- resourceBookCategoryCardPresentation:展开态下真实栏目返回 child(卡片仍由各栏目组承载,每张资源只有一个宿主)、all 自己返回 null(只出标题栏与全量计数)
- 新增纯函数 buildResourceBookAllLayout:按栏目顺序纵向排"分带",用各栏目可见资源的 extent 定带宽高;卡片世界坐标 = 栏目内局部坐标 + 带原点
- 新增 resourceBookAllTitlebarRects:分带 → 栏目标题栏矩形,让展开态复用总览态"按矩形钉标题栏"的同一条渲染路径(ResourceBookScene 不需要知道"展开态"这个概念)
- 新增 resourceBookAllBandLocalPoint:展开态世界坐标 → 栏目内局部坐标,这是落盘前唯一的换算(减带原点)
- buildResourceBookScenePlan:展开态下 all 只出标题栏(钉在视口 + 全量计数),真实栏目按带偏移铺满 child 卡;真实栏目这一支仍按 presentation === child 取卡,"能出卡的判定"只有一处
- buildResourceBookScenePlan:返回总览的淡出改为按"刚离开的那段子画布"判定(exitingCategory 传 all 时覆盖所有栏目),并用带偏移位置淡出,否则返回动画会跳位置
- buildResourceBookScenePlan:「所有资源」组不再接 child / exiting 卡,避免同一张卡在两组里各挂一份(DOM 查询与 FLIP 键撞车)
- index.tsx:删掉独立网格页组件、其 host 块与 resourceBookAllResourcesSections memo,展开态整体交给画本场景
- index.tsx:新增内存态 resourceBookAllViewport(不落盘、不进按真实栏目键的 resourceCanvasViewports),滚轮 / 缩放 / 适应 / 平移 / 框选都作用到它
- index.tsx:分带几何按"项目 + 排序 + 可见资源集"冻结(签名 + ref 短路;签名不含 state.token——返回总览时 token 也会变,含它会在淡出期间重算),拖动不重算带高,避免"拖上面一带让后面所有带整体位移"
- index.tsx:拖动放开——展开态下每张卡都能拖,section 取 resource.category(栏目页仍只拖当前分页栏目)
- index.tsx:提交前用 resourceBookAllBandLocalPoint 把世界坐标减回带原点,写回的仍是同一 mode 同一 sidecar 的同一 section(.agent/workbench/resource-layouts/{dependency,type}.json),没有第二份空间,不改契约与 schema
- index.tsx:renderResourceBookCard 去掉 options.draggable:展开态已可拖,这个"只读"开关没有调用方了
- 测试:resourceBookModel.test 钉住展开态 presentation 与"栏目页仍是原判据";resourceBookLayout.test 退役旧分组函数用例,新增分带几何 / 标题栏矩形 / 减带原点换算 / 展开态计划(含"每张资源只有一个宿主"与按带位置淡出)断言
- 测试:appSurface 两处「所有资源」判据从旧网格宿主改为画本场景(.game-resource-book-scene-card[data-resource-book-category] 与 .is-active[data-resource-book-category="all"]),并断言旧网格容器 / 宿主一个都不再存在
2026-09-11 23:33:08 +08:00
suzmii f16aa440b9 补踩坑:第四类索引事故——git add <路径> 会把同一文件里别人的 hunk 一起暂存
- 记录 28781a420 的事故形态:该笔除我新增的用例(@@ -1260,6 +1260,51 @@)外,还混入了 peer 对「所有资源」测试期望的在途改动(@@ -9562,37 +9607,83 @@),提交描述与实际内容不符,且对方那份文件随即显示为干净、容易被误判为已收口;内容未丢
- 写清正确护栏:对可能被他人同时编辑的文件,把 git add <path> + git diff --cached(看内容、不只看文件名)+ git commit 压进同一条命令,并逐 hunk 确认每一个都是自己这次要写的;发现混入他人 hunk 后保持现状并立即上报,不在共享树里用 --amend/reset/checkout --/revert 做手术
- 写清状态信号:M (已暂存且工作区与索引一致)/ MM(add 后又改过)/  M(仅工作区),并点明「M 只能说明 add 之后没人再动过,不能说明这份文件里只有我的改动」
- 写清同类隐患:pre-commit 的 lint-staged 会对它格式化过的文件做 git add(prettier --write 之后 Applying modifications from tasks),与 npx lint-staged --diff=… 属同类反向 git add
- 与前三类索引事故(git add -A 卷走别人的文件 / stash pop 弹出别人的 stash / lint-staged --diff 反向 add)并列,指明本类正是「按文件名校验」这道护栏的失效点
- 门禁:npm run check:encoding exit 0(4399 file(s))
2026-09-11 23:08:57 +08:00
suzmii 3a850ee6e7 补两条踩坑:app-server 会 1:1 回显注入内容(读侧上限不得小于写侧允许量),以及“掉了就补读”的补扫不是修复
- 新增「Codex app-server 会 1:1 回显注入内容:读侧上限不得小于写侧允许量」:记录隔离探针实测(捆绑 codex-cli 0.147.0)——注入 5 MiB 的 item,app-server 接受并回一条 5 243 245 字节的 rawResponseItem/completed 单行,而读侧上限当时 4 MiB、写侧无上限,于是合法的注入被读行判成连接级故障,报错方向指向 app-server;同时记下 stderrBytes=405 那类摘要不能当证据(正常启动就有 275/452/546/5996 B 的插件/别名警告)、experimentalRawEvents 需要 initialize.capabilities.experimentalApi、以及探针必须用管道 stdin 与按 CommandLine 精确清理
- 新增「「掉了就补读」的补扫不是修复:自激回路会一路耗到内存」:明确标注**由并行工作线报告、本线未独立复核**,并给出取证据前不得引用的警示与“去掉补扫症状是否回来”的判据
- 门禁:npm run check:encoding exit 0(4399 files)
2026-09-11 22:51:24 +08:00
suzmii 28781a420c 补资源总览网格的声明级断言:钉住 width:100% 与 max-width 并存,防止退回单列
- 新增用例「keeps the resource overview grid off fit-content so its columns stay responsive」:断言 .game-resource-book-main-grid 同时声明 width: 100% / max-width: 1120px / margin: 0 auto / repeat(auto-fit …),并同款断言 .game-resource-book-main-heading 的 width: 100%
- 取声明体前先剥掉 CSS 注释:本次修复的注释里就写着 width: 100% 等字样,不剥掉会让断言匹配到注释而假绿(删掉真正的声明也照样通过)
- 注释里写明这条断言**验不到布局**:AGC 的 vitest 没开 css: true、styles.css 不会被加载、jsdom 也没有布局引擎,gridTemplateColumns 的解析结果与缩略卡列数只能在真机量;真机判据(3 个非 0 轨道 / grid 宽 432→1120 / 8 张缩略卡 top 只有 3 个取值,且需在总览态取样)写在用例注释里
- 变异验证:临时删掉 .game-resource-book-main-grid 的 width: 100% → 用例变红且失败信息打印的是真实声明体(证明注释剥离生效);还原后 styles.css 逐字节哈希与已提交版本一致,复跑绿灯
- 门禁:npm run typecheck exit 0;npm run check:encoding exit 0(4399 files);npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts 本用例 1 passed
2026-09-11 22:50:01 +08:00
suzmii 3db6afa052 对齐 Codex app-server 读写单行上限:写侧守卫 + DirectProject 历史注入前置校验,并把注入超限改判为不可重试
- 隔离探针实测(codex-cli 0.147.0,AGC 捆绑版本):experimentalRawEvents 线程收到 thread/inject_items 后会逐条原样回显 rawResponseItem/completed —— 注入一个 5 MiB 的 item,stdout 就回一条 5 243 245 字节的单行;而读侧上限原为 4 MiB,于是「我们注入得进去」却「我们读不回来」,报错方向指向 app-server,实际是我方读行判死
- codex_app_server.rs 的 GAME_CREATOR_CODEX_APP_SERVER_LINE_MAX_BYTES 由 4 MiB 提到 32 MiB,注明它同时充当 stdout 读侧上限与 stdin 写侧守卫;取值依据写进注释(单张图 base64 上限 10 MiB、单次图片总量 16 MiB 折 base64 约 21.3 MiB,再加 JSON 信封),再大就失去内存/DoS 边界的意义
- 新增写侧守卫 game_creator_codex_app_server_message_oversize_error:write_message 超限即失败关闭并给出字节数,绝不写出自己读不回来的行(两侧共用同一常量即这条不变量)
- 新增 DirectProject 历史注入前置校验 direct_project_history_injection_oversize_error:单条 item(扣掉 rawResponseItem/completed 回显信封余量)与整份载荷都必须落在上限内;超限指名 itemId/type/字节数并失败关闭,且不截断、不摘要、不改写历史(技术方案末节口径)
- 新增专属前缀 DIRECT_PROJECT_HISTORY_INJECTION_OVERSIZE_PREFIX,供 direct_runtime 判可重试性与给专属提示
- direct_runtime.rs:direct_codex_failure_is_retryable 把注入超限改为不可重试(同一份历史每次读结论相同,且本轮用户消息已先追加进同一文件、载荷只会更大);direct_codex_failure_recovery_hint 与 direct_codex_failure_public_summary 各补一条专属文案,用户不再看到笼统的「Codex 未完成本轮代码修改,请检查运行时配置后重试(可直接重试)」
- 新增 2 条用例:写侧守卫与读侧共用同一上限的边界(等于上限必须放行、上限+1 必须拒绝)、注入侧整份载荷与单条 item 双超限必须拒绝
- 变异验证:把写侧守卫改成 >=、把单条上限放成 usize::MAX,两条用例各在自己那一处变红;还原后逐字节哈希一致并复跑绿灯
- 门禁:npm run check:rustfmt exit 0;npm run typecheck exit 0;cargo test 定向 2 passed(2257 filtered out)
2026-09-11 22:24:30 +08:00
suzmii 1b7261685c 登记素材上传配对的踩坑与覆盖边界:断言打在生产函数上,端到端 UI 未覆盖
- `pitfalls.md` 新增「素材上传不要把『上传前读到的 revision』贴到『上传后读到的清单』上」:现象(每次上传都先吃一条拒收提示)、根因(上传本身推进 revision,错配必然发生而非竞态)、处理(上传动作与配对读收进同一个函数,调用方拿不到中间那个 revision,也就没机会贴错)、同类文案坑(`unresolved` 三条进入路径里有两条重读是**成功**的,写成"读取磁盘清单失败"就是误报)、验证与变异,并记录关联文件与提交。
- 覆盖边界(按当下口径写清,防止后人误读):断言打在生产函数 `uploadProjectAssetFilesAndReadSnapshot` 上 —— 它同时拥有上传与配对读,所以配对语义是真测的;但 AGC 侧**没有**「资源面板上传 → 拒收提示条」的端到端 UI 用例(现有 harness 只有聊天入口的 `/asset.upload`,资源面板 file input 无用例),因此「界面上不再出现拒收提示」是推理结论而非端到端断言,禁止当成端到端覆盖引用。
- 同一条边界同时写进 `projectResourceLiveUpdateModel.test.ts` 用例组头部,随断言一起走,避免只看测试文件的人误读。
- 纯文档 + 测试注释,无功能改动。
2026-09-11 22:19:14 +08:00
suzmii c3ccae75af 按实测收回 cfd89ba57 顺手加宽的一处测试超时,并写明另一处保留的理由
- `prefetches only cards that are actually in view, and still fills the first screen` 的 `}, 30000)` 收回(回到 vitest 默认 5 s):实测 93 ms,约 54 倍余量,而且真正的时间门是内层 `waitFor` 自带的 1 s。cfd89ba57 那次只是给负载留余量,没有对应的结构性成本 —— 对照 `releases Blob URLs while continuously browsing beyond the cache limit`(79 轮串行读盘、实测 6120 ms、超默认 5 s)那条的预算属结构性必需,保持不动。
- `keeps a visible card cached when later loads push the cache over its limit` 的 `}, 60000)` **保留**并写明理由:它的职责是挂起护栏,必须大于内层 `waitFor` 的 20 s 断言预算,否则内层断言自己的失败信息永远不出现(vitest 会先在测试超时处中止,只剩笼统的 "test timed out")。用例实测 120 ms,20 s 与 60 s 都不是耗时预期;硬收会让内层预算变成不可达配置,是更差的诊断而不是更紧的门禁。
- 无功能改动。
2026-09-11 22:18:40 +08:00
suzmii fef366a66b 文档跟进:资源画布的引用入口按当前状态描述(图标 @ + 文案「引用」)
- 「当前已完成」清单里「资源画布素材卡提供 `@引用`」既不准确也不再是当前形态:入口已从卡片挪到选中工具条,且可见文案与 title 都不再自带 `@`(`@` 由 `AtSign` 图标承担,文案再写一次会渲染成「@ @引用」)。
- 按「四不写」把该条直接改写成当前状态:入口位置(选中工具条)、图标与文案口径(图标 @ + 文案「引用」)、以及插入对话里仍然是 `@素材名` 芯片。
- 纯文档,无代码改动;单独提交便于 cherry-pick。
2026-09-11 22:18:09 +08:00
suzmii a88034dab1 修复资源总览网格退化成单列:父链宽度不定让 auto-fit 只解析 1 个轨道
- styles.css 的 .game-resource-book-main-grid 增加 width: 100%:父级 .game-resource-book-main-world 是列向 flex 容器,交叉轴 auto 外边距(margin: 0 auto)会吃掉自由空间并取消 stretch,使该网格按 fit-content 定宽;fit-content 定宽时网格 inline size 在内在尺寸阶段不定,按 CSS Grid 规范 auto-fit 的重复次数解析为 1,于是 2560x910 窗口下 grid 宽只有 432px、getComputedStyle(grid).gridTemplateColumns 只有 1 个轨道、8 张栏目缩略卡竖向排成一列(top 步距 230)
- 同款修 .game-resource-book-main-heading:它在同一个 flex 列里带 margin:auto,同样退化成 fit-content,标题栏只占 <h2> 宽度且 space-between 无从展开
- 两处都补注释写明「width:100% 是 auto-fit 按 max-width 解析列数的前提」,防止后人当作冗余声明删掉
- 修复后 auto-fit 按 max-width:1120px 解析重复次数:3x280+2x18=876 <= 1120、4x280+3x18=1174 > 1120,即 3 列
- 真机判据:gridTemplateColumns 应给出 3 个非 0 轨道(约 361.33px)、grid 宽 432 -> 1120、8 张缩略卡 top 只有 3 个取值;且必须在总览态核对(栏目态该层带 is-background,opacity 为 0,是背景层)
- 未改动任何既有断言;AGC vitest 不加载 styles.css(无 css: true),声明级断言随下一笔提交补进 appSurface 用例
2026-09-11 22:10:43 +08:00
suzmii e98066ee7e 驱逐后不再补扫:删掉那条会把可见卡反复重读的自激回路,并如实标注超时预算
- 删掉 publishPreview 里"驱逐后立刻补一次可见性扫描"(原 useProjectResourceCardPreviews.ts 的 `if (evictedCount > 0) sweepVisiblePreviews()`)。它原先的注释宣称"递归深度恒为 1、不自激",该不变量是假的,判据有三条:(1) 触发条件是"本轮驱逐了任意条目",而第一轮只淘汰视口外条目,那种情况下根本没有可见卡丢状态,补扫却照样把空闲且可见的卡重新入队;(2) 真正驱逐到可见卡时(全表都在视口内且仍超预算,第二轮全表 LRU 回退)补扫把刚被驱逐的卡重新入队 → 读回来又超预算 → 再驱逐 → 再补扫,每个周期跨一次异步读取,是不收敛的回路;(3) 那种回读换不来稳定结果,读回的卡立刻被下一轮 LRU 淘汰(第二轮回退是全表 LRU,刚读回的卡恰好最新),只在可见集合里轮转。因此正确反应是接受这次有界淘汰(由「全可见且超预算时仍必须淘汰」钉住),而不是反复重读;代码注释按这三条重写,不留误导后人的陈述。
- 顺带删掉只为那段补扫存在的 `evictedCount`(否则是死变量)。
- 断言:新增 useProjectResourceCardPreviews.test.ts「settles instead of re-reading evicted visible cards forever」——全部登记且都在视口内(第一轮无从下手),断言读取次数在观察窗口内不再增长、且缓存稳定在上限。
- 变异验证(提交前已跑):把补扫加回去 → 该用例**不是断言变红而是 worker 被撑爆**(`ERR_WORKER_OUT_OF_MEMORY`,约 74 秒后终止),即回路真的不收敛;还原后复跑 32 passed,该用例 2.1s 通过。
- 超时预算改为"标注并给出实测依据",不再用放宽时间门吸收负载代价:`releases Blob URLs while continuously browsing beyond the cache limit` 的 `}, 30000)` 保留,并在用例前写明理由 —— 它逐个 waitFor 等 79 张卡串行读完,轮数由条目上限 48→72 机械地从 55 涨到 79(+44%),实测 6120 ms,已超 vitest 默认 5s,属结构性必需。同一提交里的 `waitFor({ timeout: 30000 })`(由 20000 顺手放大)按实测**回到 20000** 并写明依据(该用例实测 124 ms,约 160 倍余量)。
- 门禁:useProjectResourceCardPreviews 32 passed。
2026-09-11 22:02:31 +08:00
k88936 49e88bbd9f 统一分离提示备注长度限制
复用模型层的重做备注字符上限

导出提示文本清理函数供投影复用
2026-09-11 21:55:15 +08:00