Commit Graph

1713 Commits

Author SHA1 Message Date
k88936 b617873f46 调整模块引用顺序及精简测试断言格式 2026-09-14 11:58:42 +08:00
k88936 513c25898c Merge remote-tracking branch 'origin/master' into feat/ui-editor-auto-seperation
Project CI / Repository checks (pull_request) Failing after 2m16s
Project CI / Frontend tests (pull_request) Successful in 4m44s
Project CI / Backend tests (pull_request) Successful in 7m39s
Project CI / Native shell tests (pull_request) Successful in 18m52s
# Conflicts:
#	apps/ai-game-creator-shell/src/view/project-development/index.tsx
2026-09-14 11:32:17 +08:00
lhk229 340d8241a5 优化策划agent (#340)
Project CI / Repository checks (push) Successful in 2m53s
Project CI / Frontend tests (push) Successful in 3m55s
Project CI / Backend tests (push) Successful in 6m50s
Project CI / Native shell tests (push) Successful in 17m42s
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/340
Co-authored-by: Linghong <ink29535@proton.me>
Co-committed-by: Linghong <ink29535@proton.me>
2026-09-13 19:32:12 +08:00
suzmii 7b21bc529e 合并 master:Cocos 插件按当前项目类型暴露
Project CI / Repository checks (pull_request) Successful in 2m44s
Project CI / Frontend tests (pull_request) Successful in 3m13s
Project CI / Backend tests (pull_request) Successful in 5m52s
Project CI / Native shell tests (pull_request) Successful in 18m57s
- 合入 origin/master c19b32178,使 PR 头包含当前 master tip,修 CI comparison base 门禁(11 秒红)
- 冲突 1 处:docs/project-memory/shared-memory/decision-log.md 两侧追加记录,两条逐字保留(HEAD 的 2026-09-11 起多条 + master 的「2026-09-13 Cocos 插件按当前项目类型暴露」),只删 3 行冲突标记
- 验证:npm run check:doc-index 通过(97 份 Markdown);npm run typecheck exit 0;check:encoding 4557 文件通过;git diff --check 干净;全仓无冲突标记
2026-09-13 17:27:14 +08:00
kdletters c19b321785 Cocos 插件按当前项目类型暴露
Project CI / Repository checks (push) Successful in 2m21s
Project CI / Frontend tests (push) Successful in 2m41s
Project CI / Backend tests (push) Successful in 5m21s
Project CI / Native shell tests (push) Successful in 19m48s
新增 Cocos 项目根识别门禁,限制插件、面板、RPC 和编辑器执行范围
让 DirectProject MCP 工具目录按当前项目类型动态过滤
切换离开 Cocos 项目时停止已运行的插件实例
补充项目级测试、Cocos 技术方案和插件说明
2026-09-13 17:12:37 +08:00
suzmii 3bf499ddfd 修复「所有资源」展开态文档卡与图片卡初始自动重叠
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Backend tests (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 2m59s
Project CI / Native shell tests (pull_request) Successful in 19m29s
- resourceBookLayout:新增分带几何缓存键 resourceBookAllLayoutKey 与取几何的 resolveResourceBookAllLayout,键纳入布局是否就绪 / 卡片真实尺寸 / 排序模式,拖动只改坐标时键保持不变
- resourceBookLayout:抽出 ResourceBookAllLayoutInput,生产组件与回归用例共用同一份「键 + 缓存」口径
- index.tsx:展开态分带几何改走 resolveResourceBookAllLayout,并传入当前布局 hook 的 ready;此前只按项目 / 排序 / 可见资源 id 冻结,依赖模式关系图就绪前算出的单行带(144 高)被永久固化,图片带仍挤在 144 + 48 处,整排压住文档卡
- tests/resourceBookLayout.test.ts:新增混合类型(12 文档 + 12 图片)第一版坐标到位后分带重算、逐对矩形不相交的主用例
- tests/resourceBookLayout.test.ts:新增同一栏混排不同尺寸卡(类型 / 依赖两种模式)不相交、sidecar 手放坐标保留并让开下一带的对照用例
- tests/resourceBookLayout.test.ts:新增缓存键的拖动稳定性、就绪翻转、卡片尺寸与排序模式变化用例
- tests/projectResourceLiveIntegration.test.tsx:新增真宿主用例,依赖模式下打开「所有资源」,读渲染出的卡片世界矩形做逐对相交检查
2026-09-13 17:06:09 +08:00
suzmii 7ae71441ba 合并 master:接入 AGC 内置插件宿主与 Cocos 编辑器能力(#338)
Project CI / Repository checks (pull_request) Successful in 2m49s
Project CI / Frontend tests (pull_request) Successful in 3m46s
Project CI / Backend tests (pull_request) Successful in 6m42s
Project CI / Native shell tests (pull_request) Successful in 17m35s
合并 origin/master 4a46f89c9 到 chore/agc-acceptance-build(HEAD 55fab1776),本次合并共涉及 117 个文件(113 个自动合并 + 4 个冲突)。

- 自动合并 113 个文件:插件宿主与插件工作区(plugin_host.rs / builtin_plugins.rs / editor_adapter(_s).rs / plugins/agc-cocos-editor / cocos-editor-bridge crate / editor-adapter-api)、构建与打包脚本、locked Cargo.lock 及 master 侧锁与资源链路改动;不逐条列出。
- 冲突 1 apps/ai-game-creator-shell/src/App.tsx:271-278:两侧各自新增一个 import(本分支 ./services/tauriEventSubscription、master ./services/pluginHost),两个 import 都保留,并按 simple-import-sort 口径排在 ./services/platformSession 之后、tauriEventSubscription 之前;四个符号都仍被使用。
- 冲突 2 docs/project-memory/shared-memory/decision-log.md:8338-8469:两侧在同一位置追加记录,逐字保留两侧记录且各自原有顺序不变(先本分支的 2026-09-11 资源卡预览 data URL / loopback HTTP 两条,后 master 的 2026-09-09~2026-09-12 通用插件宿主、Cocos 桥接与内置插件开关条目),不改写、不合并措辞。
- 冲突 3 docs/project-memory/shared-memory/pitfalls.md:79-112:同上,保留本分支的「2026-09-05 资源画本转场与视口分离」与 master 的「2026-09-11 首页自动工作区必须使用 AGC 管理目录」「2026-09-12 Cocos 项目识别不等于编辑器桥就绪」「2026-09-11 Cocos 项目必须走独立导入分支」,内容逐字保留、两侧原顺序不变。
- 冲突 4 apps/ai-game-creator-shell/src-tauri/src/agent/direct_project_history.rs:400-435:判据是「两侧不互斥」,解法为 both(语义超集)。
- 冲突 4 保留本分支的有界退避重试循环(DIRECT_PROJECT_HISTORY_CONTENTION_RETRY_BACKOFF_MS + is_direct_project_history_contention_failure + 测试注入点)与单次尝试函数 append_direct_project_history_item_once(含锁外幂等回扫与锁内状态复核)。
- 冲突 4 保留 master 的有界等待取项目写锁:把该函数内原来的零等待 crate::project::acquire_project_write_lock(root, "conversation.write") 换成 acquire_game_creator_agent_runtime_project_write_lock_with_wait(root, "conversation.write"),并原样保留 master 的注释(agc_write_file 占锁 5.5 秒期间,零等待取锁会让流式历史落盘直接失败)。
- 冲突 4 判断依据:master 只替换了同一处的取锁语义(零等待 → 约 10 秒有界等待,并有 append_waits_for_a_same_process_project_writer 用例锁定),不改变函数签名、调用方与错误类型;HEAD 的重试循环因此仍然可达,与有界等待叠加后语义更强——写文件占锁由有界等待吃掉,等待窗口耗尽后的残余争用再由一次 250ms 短退避重试兜底。未删除任何一侧行为,也未放弃任何一侧语义。
- 冲突 4 位置取舍:有界等待取锁仍放在锁外回扫与序列化之后(本分支结构),保住「幂等回扫与序列化留在锁外、不让他人等整份历史读完」的性能语义;master 的注释与调用参数逐字保留。
- 验证:npm run typecheck、npm --prefix apps/ai-game-creator-shell run typecheck、cargo check --locked --all-targets(exit 0,0 error)、npm run check:rustfmt、npm run check:encoding、git diff --check 全部通过;冲突标记扫描为空。
- 定向 Rust 测试(--test-threads=1):direct_project_history 19 passed / 0 failed(含本分支 contention_failure_is_retried_with_bounded_backoff、contention_failure_beyond_the_backoff_budget_fails_closed、shape_failure_is_not_retried 与 master 的 append_waits_for_a_same_process_project_writer);conversation 36 passed / 0 failed;write_lock 21 passed / 0 failed。两侧用例同时绿,证明有界等待取锁与有界退避重试叠加后语义自洽。
- 未跑全量测试(按仓库约定本地只跑定向,全量交给 CI);本次不 push。
2026-09-13 15:33:48 +08:00
kdletters 4a46f89c9b 接入 AGC 内置插件宿主并补齐 Cocos 编辑器能力 (#338)
Project CI / Repository checks (push) Successful in 2m45s
Project CI / Frontend tests (push) Successful in 3m27s
Project CI / Backend tests (push) Successful in 6m18s
Project CI / Native shell tests (push) Failing after 13m52s
客户端新增随包提供的插件宿主和 Cocos Creator 集成:识别并导入 Cocos 项目,通过内置桥接操作已打开的编辑器,无需安装项目 MCP 扩展。DirectProject 现在公开 36 个独立 cocos_* 工具,保留通用 JavaScript 执行入口。

- 通用插件 SDK、命令/能力/面板注册、编辑器适配器和跨进程内置插件开关。
- Cocos 场景、节点、组件、Prefab、UI、Layout/Widget、资源、保存、撤销、日志与预览调试;目录和实现由 JS/native 共用。
- 编辑事务回读、失败回滚、后续手动修改保护及不确定结果禁止重放;预览截图通过 MCP image 返回。
- DirectProject 跳过无关专业 Agent 历史,将项目打开和历史读取中的同步 I/O 移出窗口线程,消除 Cocos 执行与项目文件锁的错误耦合。

验证:
- 合并 master 后:类型/配置检查、编码检查、Rust 格式检查和提交钩子通过。
- 合并 master 后:Cocos 项目打开、插件面板和开发启动定向测试 10 通过、2 跳过;DirectProject MCP 测试 17 通过、1 项真实 Creator opt-in 忽略;插件宿主测试 9/9。
- 插件行为测试 17/17;native 测试 20/20,4 项 opt-in 测试默认忽略。
- 真实 Creator 3.8.8 的 36/36 操作 smoke,以及客户端 MCP tools/list、tools/call、UI/撤销和预览截图,在功能实现阶段已验证通过;本次 master 合并后未重复真实 GUI smoke。

验证边界:发行安装包和远端 CI 尚未验收。

Reviewed-on: #338
Co-authored-by: kdletters <kdletters@qq.com>
Co-committed-by: kdletters <kdletters@qq.com>
2026-09-13 14:48:55 +08:00
suzmii 55fab1776a AGC 画布验收问题修复与栏目画布底部工具栏
Project CI / Repository checks (pull_request) Successful in 2m55s
Project CI / Frontend tests (pull_request) Successful in 3m59s
Project CI / Backend tests (pull_request) Successful in 6m50s
Project CI / Native shell tests (pull_request) Failing after 14m3s
- 合并资源画布命名筛选与条件筛选为单一筛选浮层,Dock 只留放大镜入口
- 修复「编辑素材标签」面板标签多时不可见且不可滚:加高度上界与标签区独立滚动
- 替换素材新增点选替换模式,并在资源卡标注会话内替换血缘
- 新增栏目画布底部工具栏,按功能画布分流图片类生成、音频生成与上传入口
- 新增 Tauri IPC generate_local_project_asset,收口图片类无源生成的 kind 与提示词目录
- 同步 PRD、AGC 验收用例、决策日志、踩坑记录与待解决事项文档
2026-09-13 14:07:03 +08:00
k88936 16db7ae8aa 为识别根节点补充名称兜底
LLM 返回空根名称时使用页面根节点默认名称,避免空标题进入 UI 树。
2026-09-12 21:40:20 +08:00
k88936 0ea7c7745c 保留分离结果的必要类型断言
TypeScript 对闭包赋值结果无法完成控制流收窄,恢复断言以通过类型检查。
2026-09-12 21:37:04 +08:00
k88936 6baf358bc7 完善素材分离恢复与步骤映射
回填部分失败时重新读取恢复状态;移除冗余类型断言并改用显式步骤映射。
2026-09-12 21:34:45 +08:00
k88936 8a96190db8 限制素材分离图片的 Base64 解码大小
对源图和服务端处理图在解码前后统一执行 64 MiB 上限检查,避免无界内存分配。
2026-09-12 21:32:20 +08:00
k88936 584da5b76b 限制视觉绑定处理图的解码规模
在解码前限制 base64 字节数并校验图像宽高,避免异常响应造成过量内存分配。
2026-09-12 21:31:13 +08:00
k88936 d1a03aec0e 统一预览画布适配与缩放滑杆计算
自动适配复用 fitToCanvas,避免重复计算;滑杆直接从原始缩放比例计算步进值。
2026-09-12 21:29:04 +08:00
k88936 b90d12c5fb 补充 Windows 原子替换安全说明
记录 MoveFileExW 路径缓冲区的所有权、终止符和调用生命周期不变量。
2026-09-12 21:27:57 +08:00
k88936 8135b4c374 避免 LLM 重试循环生产环境崩溃
将理论不可达分支改为显式错误返回,防止重试边界变化触发 panic。
2026-09-12 21:27:34 +08:00
k88936 124d94de93 保证素材批次补丁失败时状态原子
在修改状态前预检所有成功绑定节点的裁剪路径,避免中途错误留下部分更新。
2026-09-12 21:27:05 +08:00
k88936 103fe6fcd6 移除无效的裁剪路径伪校验
裁剪路径由 UUID 文件名和 sidecar 目录构造,直接依靠项目相对路径校验。
2026-09-12 21:26:33 +08:00
k88936 1370094c52 为素材处理产物生成唯一文件名
处理图 sidecar 文件名改用 UUID,避免全批次返工时覆盖前一批产物。
2026-09-12 21:25:58 +08:00
k88936 be8155c4a8 保留素材切分原始失败原因
检查点写入失败时仅记录日志,继续返回图像处理、绑定或裁剪的原始错误。
2026-09-12 21:25:21 +08:00
k88936 9052ff14f8 区分素材提取的完成与问题节点
仅将已绑定节点标记为 DONE,达到返工上限的节点继续作为上下文提供给提取模型。
2026-09-12 21:24:25 +08:00
k88936 9d9f1b8164 清理素材提取提示中的备注内容
对 YAML 提示中的描述和返工备注做有界清洗,避免代码围栏破坏提示结构。
2026-09-12 21:23:44 +08:00
k88936 8629a228a1 限制并清理视觉绑定提示备注
为节点描述和返工备注增加长度上限并移除控制字符、代码围栏字符。
2026-09-12 21:23:35 +08:00
k88936 a92121e09d 校准素材切分概览的资源绑定统计
图片与字体槽位仅在引用的项目资源存在时计为已绑定。

概览组件接入字体资源表并保留无资源参数时的旧调用语义。
2026-09-12 21:22:21 +08:00
k88936 e49d6741ca 修正组件移除失败弹窗处理
移除操作失败时关闭确认弹窗以展示错误;未执行时保留弹窗。
2026-09-12 21:19:36 +08:00
k88936 f7666339fe 修正组件替换失败弹窗处理
替换操作失败时关闭确认弹窗以展示错误;未执行时保留弹窗。
2026-09-12 21:19:14 +08:00
k88936 891cf50c0e 按节点重置组件检查面板
为 ComponentPanel 绑定节点 key,切换节点时清理折叠与确认状态。
2026-09-12 21:18:30 +08:00
k88936 b15a95e774 扩大 UI 节点随机标识空间
将节点 ID 从 8 位十六进制扩展到 16 位,降低批量识别中的碰撞概率。
2026-09-12 21:18:00 +08:00
k88936 e0f743b608 修复组件计数的布尔值转换
将布尔值显式转换为 usize,恢复 Rust 工作流模块编译。
2026-09-12 21:17:41 +08:00
suzmii aa0fcc1d71 合并 master:修复 CI comparison base 门禁
Project CI / Repository checks (pull_request) Successful in 2m55s
Project CI / Frontend tests (pull_request) Successful in 3m35s
Project CI / Backend tests (pull_request) Successful in 6m26s
Project CI / Native shell tests (pull_request) Failing after 14m12s
- 合入 origin/master(b12a81e9c「修复 AGC 自主运行时测试目录权限与任务目录加固」),使 PR 头包含当前 master tip,门禁 Resolve comparison base 不再拦
- 冲突零:自动合并成功
- 验证:npm run typecheck exit 0;npm run check:rustfmt exit 0
2026-09-12 20:55:15 +08:00
suzmii 6f212a3f2c 合并资源工作台分支:PR review 前端批次并入(含滚轮归属与重命名 CAS)
Project CI / Backend tests (pull_request) Failing after 14s
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 2m50s
Project CI / Native shell tests (pull_request) Successful in 18m4s
- 把远端最新 5ab33a8db 合入本分支(PR #316 review 前端三笔:d04fe83f1、d1581892d、a9a5fba92,41 文件)
- 冲突零;同时保留两侧对滚轮的处理:本批把 ResourceBookScene 的重复 onWheel 改成 manager 原生监听(body portal 收不到),远端那笔的浮层守卫仍在 handleResourceBookWheel 内兜住留在 DOM 里带滚动区的浮层,互补不冲突
- 含追加契约:confirmResourceRename 补 expectedProjectId/expectedProjectRevision(与删除/分类同一套 CAS 口径)+ 共享错误码映射 projectAssetCommandErrorMessage
- 验证:npm run typecheck exit 0;resourceRename / resourceCanvasFloatingDismiss / projectResourceLiveIntegration / resourceReferenceInput 四文件全绿
2026-09-12 20:52:38 +08:00
suzmii d1581892d7 修复 PR #316 review(前端 TS/TSX):资源工作台与资源画布
- 素材重命名(跨范围契约):`rename_local_project_asset` 现在要求 `expectedProjectId` + `expectedProjectRevision`,前端按删除 / 分类保存同一套 CAS 口径补齐——先 `get_local_game_project_revision` 读当前 revision 再连同项目身份提交,不用可能过期的本地缓存值
- 失败文案统一:新增 `projectAssetCommandErrorMessage`,把 `project-identity-conflict` / `project-revision-conflict` 翻成用户可读中文,重命名 / 删除 / 分类保存三条链路共用一份映射,其余错误原样透出
- index.tsx:资源面板下载按 `resolveDownloadablePanelEntries` 过滤,版本卡这类合成 path 的条目不再进入落盘链路
- index.tsx:`characterAnimationPanel` 纳入画布浮层开关判据(抽 `resolveResourceCanvasFloatingPanelOpen`),「生成动画」面板与快速编辑 / 信息浮层共用同一条「点外部 / Esc 关闭」规则
- index.tsx:去掉 `ResourceBookScene` 上重复的 `onWheel`,滚轮只由 manager 上的原生 `passive:false` 监听处理,平移 / 缩放不再被翻倍
- index.tsx:快速编辑的源资源在层 id 命中不到时回落到已正规化的 `asset:<id>`,重试不再静默什么都不做;取不到时给出可见失败
- ResourceCanvasPanelView.tsx:下载按钮按可下载条数判可用、不再在上传中显示下载转圈;上传中禁掉 × / Esc / 遮罩三条关闭路径;预览占位文案抽 helper
- GameRunVersionPicker.tsx:portal 菜单在滚动 / 缩放后重算位置;外部点击判定沿用共享 `useImageCanvasFloatingOptionDismiss` + `menuRef` 边界(review 该条已修,保留现状并补位置用例)
- ResourceCanvasGenerationPanelView.tsx:`submitting` 改 `finally` 收回,成功路径不再永久锁住面板
- ResourceAssetDeleteDialog.tsx / ResourceRenameDialog.tsx / ResourceClassificationPanel.tsx:在飞时 `closeOnEscape` / `closeOnBackdrop` 与头部 × 一起挡住
- resourceEditModel.ts / resourceCanvasToolbarModel.ts / useProjectResourceCardPreviews.ts / projectResourceLiveUpdateModel.ts:抽 `resourceBaseName`、`canonicalProjectedResourceMediaType` 参数收窄去掉强转、删未使用参数、补「IO 失败会 reject」的签名说明
- resourceCanvasHistoryModel.ts:`resourceCanvasSnapshotsEqual` 不再比较不可恢复的 `manuallyPlaced`,消除「压进历史但撤销是空操作」
- resourceCanvasSectionMapping.ts:删掉从未接线、且注释与实现相矛盾的 `LEGACY_RESOURCE_CANVAS_SECTION_FALLBACK`
- resourceCanvasChrome.css:`.game-resource-panel-grid` 补 `flex: 1 1 auto; min-height: 0`,卡片网格成为真正的滚动区
- 用例:重命名 CAS 载荷与读序、CAS 拒绝文案、版本卡下载门禁、上传中关闭路径、浮层判据、菜单跟随滚动、分区映射
2026-09-12 20:49:03 +08:00
suzmii d04fe83f10 修复 PR #316 review(前端 TS/TSX):@ 引用与提示词润色主链路
- App.tsx:`conversation.write` 策略确认后的重跑改为整体复用首轮入参(`directCodexPolicyRetryInput`),不再手写字段,修掉漏传 `references` 导致 @ 引用被静默丢弃的缺陷
- resourceReferences.ts:运行画面引用的判别指纹补上 `resourceIds`(排序集合口径)/`versionId`/`elementRole`/`width`/`height`,避免不同选点撞 key 被 `dedupeChatReferences` 去重丢掉
- ResourceReferenceInput.tsx:程序化重建编辑器内容改为把 chip 内联嵌在文本里的同名 token 位置(不再另起一段堆在末尾),并把 `lastEmittedDraftRef` 记为「编辑器实际读回来的草稿」而不是 props,消除每轮多一段 `@显示名` 的渲染循环
- ResourceReferenceInput.tsx:候选浮层(候选菜单 / 素材选择器)打开时 Enter 不再提交表单,把按键让给 `LexicalTypeaheadMenuPlugin`
- ResourceReferenceInput.tsx:`assets` / `currentVersionAssetReferences` 的 memo 依赖改用内容签名;预览请求在换素材 / 卸载时主动作废上一个 scope;空态文案的嵌套三元抽成 `pickerEmptyMessage`
- usePromptPolish.ts:`polish()` 补 `catch`,注入式 `requestPolish` 拒绝时给出可见失败提示而不是未处理拒绝;`reset()` 递增请求代次作废在飞请求
- ChatPromptPolishReminder.tsx:章节级 Esc 分支补 `busy` 判据,与关闭按钮 / 遮罩同一口径(在飞不许关面板)
- LocalGamePreviewFrame.tsx:资源 id 改用专用净化(允许 `:` 与可打印非 ASCII),修掉 `local-asset:<id>`、`persisted-角色草图.png` 被整条过滤导致引用丢素材关联
- sessionPreview.ts:`get_local_game_preview_status` 读失败不再当作「确认没有在跑」去发停止命令,避免停掉真在跑的活体预览
- useHomeProjectCreation.ts:进项目流程加代次令牌,慢请求后到不再覆盖新项目
- WorkspaceLauncher.tsx:拒收恢复的阶段回写按 `projectId`/`heldRevision`/`snapshotRevision` 关联,不再把恢复结果盖到后续新拒收的提示上
- 用例:`directCodexPolicyRetryInput` 透传、引用指纹区分度、重建不循环、浮层打开时 Enter 不提交、润色拒绝 / reset 作废、预览读失败不停预览
2026-09-12 20:48:13 +08:00
kdletters b12a81e9c2 修复 AGC 自主运行时测试目录权限与任务目录加固
Project CI / Repository checks (push) Successful in 2m47s
Project CI / Frontend tests (push) Successful in 3m15s
Project CI / Backend tests (push) Successful in 7m12s
Project CI / Native shell tests (push) Failing after 13m9s
恢复 relaxed autonomous lane 的美术工具与写入门禁旁路

统一 Runtime 任务与事件目录的安全创建和校验

测试临时目录在 Windows 下初始化当前用户 owner
2026-09-12 20:31:43 +08:00
suzmii 5ab33a8db3 合并资源工作台分支:PR review 的 Rust 批次并入共享契约与滚轮修复
Project CI / Repository checks (pull_request) Successful in 2m49s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 6m58s
Project CI / Native shell tests (pull_request) Successful in 19m0s
- 把远端最新 1cc258d2a 合入本分支(PR #316 review 的 Rust 三笔:3a9e45c80、daef9f6cc、64b0d2f76)
- 覆盖:素材导出补敏感文件/控制面拒绝与自我覆盖保护、删除幂等、重命名 CAS、manifest 缓存 TOCTOU、标签上限、注入资源 ID 上限与去重、锁诊断与提权口径
- 冲突零:自动合并成功
- 注意:rename_local_project_asset 现要求 expectedProjectId/expectedProjectRevision,前端调用点由前端批次同批补齐
2026-09-12 20:24:01 +08:00
suzmii 64b0d2f766 收敛外部错误体、注入提示词与锁诊断的不设界行为
收敛外部错误体、注入提示词与锁诊断的不设界行为(PR #316 review)

- resource_editor.rs:2476 [bug · medium] 已被修复:`error_details` 改为 `error.details` 优先、顶层 `details` 兜底,与 docstring 声明的取值顺序一致;新增「两种形状同时出现」用例钉住优先级。
- resource_editor.rs:2468 [performance · low] 已被修复:4xx 错误体改走 `bytes_stream` 有界读取(64KiB 上限,超限即放弃取原因),不再用 `response.text()` 无上限缓冲外部正文。
- resource_editor.rs:2514-2525 [maintainability · low] 已被修复:provider / assetKind / mediaType / code 四个追加字段各自按 80 字符截断(`MAX_EDITOR_ERROR_DETAIL_CHARS`),最终文案长度不再随外部正文增长;新增超长字段整串比对用例。
- direct_codex_references.rs:175-182 [performance · medium] 已被修复:`resourceIds` 超过 32 条直接按模块失败关闭口径拒绝,并在同一 id 的重复项上做去重,注入提示词的「关联素材 ID」行长度与 manifest 扫描次数都有界;新增去重 + 超限用例。
- direct_runtime.rs:1795-1797 [maintainability · low] 已被修复:`direct_project_history_contention_failure` 收窄为只认追加锁超时标记(项目写锁争用已在更早的专用分支判掉,是死代码),恢复提示文案相应去掉「或项目锁」;新增用例钉住两条判据互不重叠、各自命中正确提示。
- conversation.rs:984-989 [maintainability · medium] 已被修复:`DIRECT_PROJECT_HISTORY_RECORD_TYPE` 提升为 `pub(crate)`,读取侧 `is_direct_project_history_row` 引用同一常量,`project.jsonl` 的信封契约改为编译期共享。
- agent_db.rs:3570-3574 [other · medium] 已被修复:`lock_with_attempts` 的进程内锁改为有界 `try_lock` 轮询(窗口与调用方一致,2000/200 次 × 5ms),同进程读路径不再被写者的 10s 跨进程等待拖住;顺序仍是「进程内锁 → 跨进程锁」,无 ABBA;新增用例验证短窗口 <5s 失败且释放后立即可重取。
- agent_db.rs:3668-3669 [maintainability · low] 已被修复:新增与锁同级的旁路诊断文件(普通共享写入),诊断优先读它、读不到再退回锁文件,Windows 上 zero-share 独占锁文件时也能报出持锁方;新增「取锁写出旁路文件」「锁文件不可读时退到旁路」两条用例。仅存 pid/用途/时间戳,不参与判活、回收或抢占。
- agent_db.rs:3827-3828 [maintainability · low] 已被修复:仅当修复错误真的符合提权口径(`windows_acl_error_may_need_elevation`)时才追加「自动提权修复未完成」,否则原样透传底层错误,不再重复报同一个错误并谎称尝试过提权。
- main.rs:29-31 [maintainability · low] 判定为不适用/不改:实测删掉那四个 import 会产生 18 处 E0425(`direct_tool_bridge` / `canvas_generation` / `assets` / `manifest` / `resource_editor` / `resource_dependency_graph` / `recovery_tests` 等经 `use super::*` 从 crate 根复用它们),而保留它们并不产生 `unused_imports` 警告(cargo check --all-targets 无一条指向这几行);已按原样恢复 main.rs,工作树中该文件无改动。
2026-09-12 20:20:39 +08:00
suzmii daef9f6cc9 修复素材删除幂等、重命名 CAS 与 manifest 预览缓存一致性
修复素材删除幂等、重命名 CAS 与 manifest 预览缓存一致性(PR #316 review)

- assets.rs:2048-2049 [bug · medium] 已被修复:删除登记在「身份 + revision 两项 CAS 都已通过」后遇到素材已不在 manifest 时按 no-op 成功收敛并照常推进 revision,不再报「项目资源不存在」;新增 `asset_delete_retry_converges_when_only_the_revision_advance_failed` 复现「manifest 已提交、revision 未推进」并验证重试收敛(原「不存在的素材必须报错」断言相应改为幂等语义,前端只消费 assetId/committedProjectRevision)。
- assets.rs:2035-2042 [performance · low] 已被修复:引用集合只算一次并用 `HashSet<String>` 做成员判定,`retain` 不再是 O(V²);版本守卫闭包按约定在写入前另行求值、拿不到该可变借用,故两次扫描保留并已在注释里说明。
- commands.rs:1032 [maintainability · medium] 已被修复:`RenameLocalProjectAssetInput` 补 `expectedProjectId` / `expectedProjectRevision`,`rename_local_project_asset_at` 与删除/分类更新同口径做两段身份复核 + revision CAS,失败时磁盘、manifest、revision 全不动;新增 CAS 用例(陈旧 revision / 跨项目身份 / 空身份)。注意:前端 `confirmResourceRename` 必须同时补传这两个字段(TS 侧由前端 owner 落地)。
- asset_rename.rs:84 [bug · low] 已被修复:新增 `asset_frame_directory_matches`,目录段在 Windows/macOS 按大小写不敏感比较(Linux 保持敏感),与文件名比较同口径;新增 `Assets/hero.png` 帧对齐用例。
- asset_rename.rs:249-250 [bug · medium] 已被修复:revision 推进失败改为报 `reconciliation-required: 素材已改名…且 manifest 已落盘,但项目 revision 未能推进`,明确这是「已提交但对账未完成」而非普通失败;同时新增的 CAS 使后续命令必须按新 revision 重试,重试会命中同名 no-op 分支收敛。
- tests/asset_rename.rs:257-263 [maintainability · medium] 已被修复:删除 `RenameLocalProjectAssetFaultStage` 枚举与生产签名上的 `fault` 参数,故障注入改用 `#[cfg(test)]` 的 `.agent/runtime/test-fail-next-asset-rename-manifest-write` 标记文件(与 agent_db 既有约定一致),生产 API 面不再能被推上「只回滚、不写 manifest」的路径。
- manifest.rs:1386 [bug · medium] 已被修复:预览缓存失效点下沉到唯一的装盘公共体 `write_manifest_locked_with_version_guard`(install 成功后立即失效,含安装后回读不一致的失败路径),`mutate_manifest_at_allowing_version_removals` 与绑定改写通道一并覆盖;`write_manifest_with_lock_hook` 里的重复调用已移除。
- manifest.rs:1480-1482 [bug · medium] 已被修复:填充侧改为「先取身份快照 → 读取 → 复核快照一致才入缓存」,不再可能出现「旧内容 + 新文件身份」的缓存条目。
- manifest.rs:1135 [security · low] 已被修复:新增 `normalize_manifest_asset_tags`,在共享归一化之后按数量(16)与单标签长度(32 字符)失败关闭;超长标签不截断,避免与共享标签库静默分叉。
- manifest.rs:1180-1181 [bug · medium] 已被修复:审计改为幂等——前后分类与标签完全相同时不追加记录,重试不会再写出 `previousCategory == category` 的假变更审计(保留「manifest 落盘后、推进 revision 前追加」这一既有位置约定)。
- manifest.rs:1140 [maintainability · low] 已被修复:分类写入的项目写锁标签由 `asset.register` 改为 `asset.classification.update`,争用诊断不再误报成素材登记。
- 测试:新增 preview_cache_tests(命中/TOCTOU 不入缓存/身份漂移丢弃/主写入通道显式失效)、分类重复写入不留假审计、标签上下界拒绝;7 条变异验证全部 CAUGHT。
2026-09-12 20:20:12 +08:00
suzmii 3a9e45c805 修复素材导出缺少敏感文件拒绝与自我覆盖保护
修复素材导出缺少敏感文件拒绝与自我覆盖保护(PR #316 review)

- asset_export.rs:27-30 [security · high] 已被修复:`resolve_export_source_file` 现在与通用读取路径同一口径,normalize 后先 `reject_agent_runtime_private_control_path` 再 `reject_sensitive_project_file_read`,`.env` / 本地凭据配置与 `.agent/runtime|checkpoints|workbench` 控制面都不能被复制到项目外。
- asset_export.rs:31-33 [security · medium] 已被修复:源路径改用 `resolve_local_project_path` 逐段复核符号链接与 Windows reparse point,`assets` 本身是链接/junction 时不再把项目外文件当成素材导出。
- asset_export.rs:76-78 [bug · high] 已被修复:新增 `reject_export_destination_matching_source`,在创建写句柄之前按「路径等价(大小写不敏感平台忽略大小写)」+「文件身份(含硬链接,退化身份不参与判定)」拒绝保存目标与源素材同一份文件;否则 `File::create` 先截断源文件、复制读到 0 字节还会报成功。
- asset_export.rs:93-95 [other · low] 已被修复:复制改为同目录临时文件 + `sync_all` + `rename` 原子替换,失败时清理临时文件;不再先截断既有目标、也不再留下半截文件。
- 文档:命令 docstring 不再声称「只导出 manifest 已登记素材」——DirectProject 导入的附件同样要能另存,而它们不是 manifest 资产,所以这里明确写成与通用读取同一套路径门禁。
- 测试:新增 5 条用例覆盖敏感/控制面源拒绝、中间目录符号链接逃逸、目标即源文件、硬链接目标、原子替换不留临时文件;7 条变异验证全部 CAUGHT。
2026-09-12 20:19:57 +08:00
suzmii 1cc258d2a4 合并资源工作台分支:PR review 共享契约与样式批次并入滚轮修复
Project CI / Repository checks (pull_request) Successful in 2m38s
Project CI / Frontend tests (pull_request) Successful in 3m12s
Project CI / Backend tests (pull_request) Successful in 5m33s
Project CI / Native shell tests (pull_request) Successful in 16m46s
- 把远端最新 fc6743980(浮层滚轮归属修复)合入本分支(PR #316 review 的 shared/server-rs/CSS/scripts 三笔:9835bbec9、8b8597782、3b385ef57)
- 冲突零:自动合并成功
- 验证:npm run typecheck exit 0;shared 契约/标签/筛选条与 lint-staged 用例全绿
2026-09-12 19:54:16 +08:00
k88936 a19684a5f5 Merge remote-tracking branch 'origin/master' into feat/ui-editor-auto-seperation
Project CI / Repository checks (pull_request) Failing after 1m7s
Project CI / Frontend tests (pull_request) Successful in 3m10s
Project CI / Backend tests (pull_request) Successful in 6m0s
Project CI / Native shell tests (pull_request) Successful in 18m41s
2026-09-12 19:46:41 +08:00
suzmii 8b85977828 修复 PR316 review:共享分段页签宽度下限作用域、标签契约与资源画布样式
- packages/shared/src/components/styles.css:528 [bug medium] min-width: max-content 收窄到新的 .platform-segmented-tabs--scroll 修饰类:grid 分支没有溢出容器、轨道是 minmax(0,1fr),同样的下限只会让内容画到相邻格上;grid 侧靠轨道等分与宿主 truncateLabels 收口,选中 PlatformSegmentedTabs.tsx 的 scroll 分支补修修饰类。
- packages/shared/src/components/PlatformResourceFilterBar.test.tsx 同步改成钉「下限只挂在 --scroll」+「grid 分支不带 --scroll/overflow-x-auto」(声明级断言,jsdom 不计算外部样式表,属弱验证,真机判据见提交说明)。
- packages/shared/src/components/PlatformResourceFilterBar.tsx:24 [maintainability low] Props 改为以 tagItems 为判别项的联合类型:给 tagItems 就必须给 onToggleTag,非法状态编译期不可表达;组件内部再兜 disabled={!onToggleTag} 供给不带类型检查的调用方,并补对应运行时用例。
- packages/shared/src/components/PlatformResourceFilterBar.tsx:107 [style low] 标签行补 scrollbar-hide:它是唯一还画滚动条的横向滚动容器,与 styles.css 里 .scrollbar-hide 的注释口径对齐;补类名与声明级用例。
- packages/shared/src/contracts/gameCreationAppAssetTagLibrary.ts:51 [maintainability low] assetIds 排序改为确定性 code-unit sort(),不再依赖运行环境默认 locale(标签那一层仍显式钉 zh-CN),补跨输入顺序可复现的用例。
- packages/shared/src/contracts/gameCreationAppAssetTagLibrary.ts:68 [bug low] assetTagsMatchSelection 两侧对称归一化:selectedTags 也过 normalizeGameCreationAppAssetTags,' 像素风 ' 这类未归一化的选中项不再静默匹配不上。
- packages/shared/src/contracts/gameCreationApp.test.ts [test low] 新增解析 Rust PROJECT_RESOURCE_CANVAS_SECTIONS 与 TS 常量对齐的交叉校验(仿 assetKindCanonicalMapping.test.ts 解析 Rust 常量先例),钉住两侧分区顺序不漂移。
- packages/shared/src/contracts/gameCreationApp.ts 同步「读显示 / 写回」口径注释:未知 category 已在 Rust 读侧失败关闭,「非法值 → 派生」只剩内存对象语义。
- apps/ai-game-creator-shell/src/styles.css:5790 [bug medium] :has() 悬停高亮分类值换成现行 7 个分区(ui-interaction/character/scene/audio/document/unclassified/version),删掉永不渲染的 code/art 死选择器,补齐缺失栏目的高亮。
- apps/ai-game-creator-shell/src/styles.css:6873 [bug medium] hover/focus-within/is-selected 由只写 border-color 改为完整 border: 1px solid #d57b51(基规则 border: 0 下 border-color 无效果,选中/焦点态此前完全不可见),box-sizing: border-box 下不改卡片尺寸。
- apps/ai-game-creator-shell/src/styles.css:10151 [bug medium] 去掉高优先级 :focus-within 规则里的 box-shadow: none:它盖掉了 --platform-input-focus-ring 焦点光环,direct-codex 输入区此前没有任何可见焦点(无障碍回归),现在光环生效。
- apps/ai-game-creator-shell/src/styles.css:10198 [bug low] 润色状态文字与操作排改为同一行分列(grid-row: 2 + grid-column: 1 / 2),不再整行独占或与按钮重叠,状态出现/消失不改变输入框高度。
- apps/ai-game-creator-shell/src/styles.css:10206 [maintainability low] 删除永不命中的 .resource-reference-input-at direct-codex 规则(showTriggerButton={!directCodex} 不渲染该按钮),保留说明指向真正的 .project-supervisor-reference-trigger。
- 附带 prettier 对 .design-agent-reasoning summary 单行规则的换行归一(该文件本来未过 prettier --check)。
2026-09-12 19:43:58 +08:00
suzmii fc67439802 修复资源画布浮层里的滚轮被画布消费:@ 选择器列表滚动时画布跟着平移 / 缩放
Project CI / Repository checks (pull_request) Successful in 2m27s
Project CI / Frontend tests (pull_request) Successful in 3m3s
Project CI / Backend tests (pull_request) Successful in 6m33s
Project CI / Native shell tests (pull_request) Successful in 18m54s
- 共享浮层判据抽出 isEventInsideFloatingOverlay,并新增 isFloatingOverlayWheelEvent:关闭判定与滚轮归属共用同一份口径(DOM 不在边界里的 portal 浮层 + 已登记浮层)
- isEventInsideFloatingMenu 返回值收紧为布尔,避免判据把命中的元素当真值往下传
- 资源画布唯一滚轮入口 handleResourceBookWheel 加统一守卫:浮层里的滚轮一律不消费(不 preventDefault、不动视口),不再逐浮层加 stopPropagation
- resourceCanvasFocusModel 增加 RESOURCE_CANVAS_WHEEL_OVERLAY_SELECTOR 与 isResourceCanvasWheelOverlayTarget,登记留在画布 DOM 里自带滚动区的浮层(快速编辑 / 信息 / 筛选)
- projectResourceLiveIntegration 新增用例:在选择器列表上派发真实 wheel → 浮层自己收到该事件、画布 data-resource-viewport 不变;对照组场景根派发 wheel → 视口照旧变化
- resourceCanvasFloatingDismiss 新增判据单测:portal 浮层 / 共享弹出层 / 已登记浮层三种来源归浮层,边界里的卡片与空白仍归画布,判不出归属不抢
- pitfalls.md 记录「portal 事件沿 React 树冒泡导致画布误吃滚轮」的根因与排查口径
2026-09-12 19:29:20 +08:00
suzmii e4c2f2466f 合并资源工作台分支:卡片从所属摞浮现与既有三条修复并存
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 (pull_request) Has been cancelled
- 把远端最新 05612c46a(弹窗宿主类样式迁共享表 + 标签统计刷新 + 工具条分隔线去重)合入本分支 b41b26cab(卡片全部从所属摞浮现)
- 冲突零:仅 pitfalls.md 两侧追加记录自动合并,两条都保留
- 验证:npm run typecheck exit 0;resourceBookController / resourceBookLayout / resourceTagStatsRefresh / projectAssetPickerDialogShellStyle / selectedLayerToolbarDividerDedupe 五文件全绿
2026-09-12 18:58:52 +08:00
suzmii b41b26cab8 修复资源画本进栏目只有少数卡片有位移:没有 First 帧的卡片改从那一摞起飞
- apps/ai-game-creator-shell/src/view/project-development/resourceBookController.ts:begin() 顺带按 (栏目, 类型摞列号) 记下同一摞最深那张卡的 First 矩形当"堆锚点",play() 时没有 First 帧的卡片认领它当合成 First(仍是同一套 FLIP,不新增动画系统、不为动画多渲染节点);堆锚点只在本次转场有效(maybeFinish / settle / invalidate 清掉),转场中重基(已在跑动画)不认领锚点,起点仍是"此刻像素"。
- apps/ai-game-creator-shell/src/view/project-development/resourceBookLayout.ts:展开态(allOpen)的卡片补上真实类型摞列号,不再一律 0——否则第 2 摞之后的卡片会全从第 1 摞飞出来。
- apps/ai-game-creator-shell/src/view/project-development/index.tsx:卡片宿主补 data-resource-book-stack-column / data-resource-book-stack-index,把"哪一摞"的摞身份交给转场层。
- apps/ai-game-creator-shell/tests/resourceBookController.test.ts:新增 3 条用例——每一张卡都从自己那一摞位移出来(含第 0/1 摞分别认领各自锚点、总览已渲染的仍用自己 First)、转场中重基从此刻像素而不是被拉回摞上、转场收尾后挂载的卡片不从过期锚点飞出。
- apps/ai-game-creator-shell/tests/resourceBookLayout.test.ts:新增"展开态每张卡带自己那一摞的列号"用例(同栏目两摞 ⇒ [0,0,1])。
- apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts:在既有总览/进栏目用例里钉住宿主上的摞身份属性(总览 3 张 = 下标 0,1,2;进栏目后 5 张 = 下标 0..4、同类型列号 0)。
- docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md:把资源画本转场一节更新为当前状态(堆锚点来源、锚点生命周期、展开态列号)。
- docs/project-memory/shared-memory/pitfalls.md:记录本次排障——现象、已用代码核实的原因(总览每摞只铺 3 张 ⇒ 其余卡片没有节点、没有 First 帧)、"钉住的标题栏移出 world"那笔改动不是原因的证据、处理、变异验证与真机判据。
2026-09-12 18:56:43 +08:00
k88936 46b0871e6d 补充背景节点规则说明
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Backend tests (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 2m48s
Project CI / Native shell tests (pull_request) Successful in 19m57s
2026-09-12 18:56:31 +08:00
suzmii 05612c46ae 合并资源工作台分支:弹窗宿主类样式迁到共享表与既有修复并存
Project CI / Repository checks (pull_request) Successful in 2m36s
Project CI / Frontend tests (pull_request) Successful in 3m11s
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
- 把远端最新 b498c2780(标签统计刷新 + 工具条分隔线去重)合入本分支 074924190(弹窗宿主类 platform-modal-shell/overlay/backdrop 迁到共享样式表)
- 冲突零:src/index.css 自动合并(本分支删除三条宿主类规则,远端最新新增分隔线去重规则)
- 验证:npm run typecheck exit 0;projectAssetPickerDialogShellStyle + selectedLayerToolbarDividerDedupe + resourceTagStatsRefresh 三个用例文件全绿
2026-09-12 18:51:33 +08:00
suzmii 0749241908 修复 AGC「选择替换素材」弹窗面板透明:平台弹窗外壳规则移入共享样式表
- 根因:弹窗面板用的 `platform-modal-shell`(遮罩 `platform-overlay`)规则原先只写在网页端整站样式表 src/index.css;AGC 只加载 packages/shared/src/components/styles.css 与 theme.css,类名挂上了但一条声明都没命中,面板因此无底色、无边框、无阴影,背后模糊的资源画布直接透出
- 把 platform-modal-shell / platform-modal-backdrop / platform-overlay 三条宿主类规则从 src/index.css 移进 packages/shared/src/components/styles.css:两个宿主都 import 这张表,规则只保留一份,不在 AGC 业务样式里复制平行副本;三处声明逐字照搬,网页端层叠结果不变
- 新增 apps/ai-game-creator-shell/tests/projectAssetPickerDialogShellStyle.test.tsx:从 src/main.tsx 按真实 import 关系解析出「AGC 到底加载了哪些样式表」,断言清单里有这三条规则、背景引用主题 token、light 主题下 --platform-modal-fill 各色停 alpha ≥ 0.9;DOM 契约断言面板挂 platform-modal-shell、遮罩带 platform-overlay 与 platform-theme--light;并断言这三条规则只在共享表里各定义一次(禁止平行拷贝)
- docs/project-memory/shared-memory/pitfalls.md 记录「共享弹窗的宿主类必须落在所有宿主都会加载的样式表里」的排障经验
2026-09-12 18:48:31 +08:00
suzmii b498c2780e 修复改完素材标签后聊天侧标签统计与候选不刷新
Project CI / Repository checks (pull_request) Successful in 2m56s
Project CI / Frontend tests (pull_request) Successful in 3m54s
Project CI / Backend tests (pull_request) Successful in 6m47s
Project CI / Native shell tests (pull_request) Has been cancelled
- App.tsx:新增跟随工作台壳清单快照的 effect(`manifestRef` + 同一 `projectId` 且内容确实变了才 `setManifest`),
  让聊天侧 `@` 选择器的标签计数与候选在资源命令写入后跟上画布那份清单
- tests/resourceTagStatsRefresh.test.tsx(新增):真宿主链路用例 —— 资源画布「编辑标签」保存后,
  聊天 `@` 选择器出现该标签 chip 与计数、并按它收窄候选;反向用例钉住未标注标签时不渲染标签 chip
- docs/project-memory/shared-memory/decision-log.md:记录标签派生数据的三处来源与各自数据源、
  根因(`initialProjectManifest` 只是 `useState` 初值,壳里换清单不会再进来)、修复口径与已知未覆盖项
2026-09-12 18:48:04 +08:00
suzmii bb91e8909d 修复选中资源工具条出现两条相邻分隔线
- 成因:共享工具条在 showQuickEdit 分支于「快速编辑」后输出一条分隔线,同时为 extraActions 自动生成前置分隔线(extraActionDivider);AGC 资源卡是「快速编辑可用 + 中间动作未接通不渲染」的组合,两条因此相邻
- 修法:样式层去重(相邻的两条只显示一条),不改 JSX 结构,对美术画布与资源画布两端都成立,也不会隐藏任何真正起分隔作用的那一条
- 新增契约用例 selectedLayerToolbarDividerDedupe.test.ts 钉住去重规则与它的成因两端
- 验证:该用例 3 passed;变异验证(删掉去重规则)→ 1 failed,还原后 3 passed
2026-09-12 18:23:02 +08:00