Merge remote-tracking branch 'origin/master' into feat/game-works-management
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m5s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 3m28s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 5m5s
Project CI / Frontend tests (pull_request) Successful in 2m43s
Project CI / Backend tests (pull_request) Successful in 6m12s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m37s
Project CI / Repository checks (pull_request) Failing after 3m54s
Project CI / Native shell tests (pull_request) Successful in 5m59s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m5s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 3m28s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 5m5s
Project CI / Frontend tests (pull_request) Successful in 2m43s
Project CI / Backend tests (pull_request) Successful in 6m12s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m37s
Project CI / Repository checks (pull_request) Failing after 3m54s
Project CI / Native shell tests (pull_request) Successful in 5m59s
This commit is contained in:
@@ -52,7 +52,14 @@ DirectProject 已经解决过同一类问题([`【ADR】DirectProject命令接
|
||||
`runtimeSessionInstallFailed` / `authClientInitFailed` 三个 catch 用本操作的固定文案,路径等敏感片段
|
||||
由报告侧的 sanitize 换成占位符。
|
||||
- `#[tauri::command]` 的 `Err` 直接携带该枚举(Tauri 2 的 `InvokeError(pub serde_json::Value)` 支持结构化错误)。
|
||||
这是 DirectProject 已有的做法(`enqueue_direct_codex_turn -> Result<(), DirectTurnEnqueueFailure>`),不是新约定。
|
||||
这是 DirectProject 已有的做法(`enqueue_direct_codex_turn -> Result<(), EnqueueError>`),不是新约定。
|
||||
DirectProject 的三条通道固定为三张类型表:入队拒绝 `EnqueueError`、宿主内部回合错误 `TurnError`
|
||||
(不导出、不跨进程)、`turn.completed.failure` 载荷 `TurnFailure`;类型随所属深模块命名
|
||||
(`agent/codex_app_server/turn_error.rs`、`agent/thread_manager/wire/failure.rs`),不再带 `Direct` 前缀;
|
||||
回合终态判定 `TurnCompletion` 是宿主内部判别联合(`agent/thread_manager/turn_completion.rs`),不导出、不进 `wire/`。
|
||||
`TurnFailure` 里仍带字符串的两臂专门标成"待清的债":`SuperErrorFromStringPlusStage`(`stage` 是 typed 枚举、
|
||||
`detail` 仍是产生层字符串)与 `Unclassified`(连阶段都没有),名字故意起丑,`detail` typed 化后即改名;
|
||||
`TurnError::classify`(返回 `TurnErrorClassified{ShouldStop, ShouldContinue}`)是**唯一**投影点,任何地方都不许再把 typed 失败重包成"阶段失败 + 预拼文案"。
|
||||
- 变体按**可判定的事实**命名。服务端 400 只提供 `status + message`(`AppError.code` 仍是通用
|
||||
`BAD_REQUEST`),所以 400 变体按"哪条请求的输入被拒"命名(如 `passwordLoginRejected`),
|
||||
不假装能区分密码长度/手机号格式;**任何地方都不允许对错误文案做判断**。
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
## 验证命令
|
||||
|
||||
1. `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml direct_thread -- --nocapture`
|
||||
2. `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml export_bindings`(生成 `src/features/project-workspace/generated/`),随后用 `prettier --write` 格式化生成目录,避免未格式化的 ts-rs 输出混进提交
|
||||
2. `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml export_bindings`(生成 ts-rs 绑定);生成物保持原始输出直接提交,不要再跑 prettier(见 `decision-log.md` 2026-10-03「生成绑定不再经 prettier」)
|
||||
3. `npm run test -- apps/ai-game-creator-shell/tests/directThreadChat.test.ts apps/ai-game-creator-shell/tests/directTurnPresentation.test.ts apps/ai-game-creator-shell/tests/directHistoryPaging.test.ts apps/ai-game-creator-shell/tests/directHistoryAnchorGate.test.ts`
|
||||
4. `npm run test -- apps/ai-game-creator-shell/tests/appSurface.test.ts`(`project-development.suite.ts` 由该入口注册,不能作为独立测试入口;同时验证现役 Design Agent 的会话恢复与审批界面。)
|
||||
5. TypeScript 类型检查与 ESLint(范围同前次 DirectProject 迁移)。
|
||||
|
||||
@@ -1,4 +1,41 @@
|
||||
# 决策记录
|
||||
|
||||
## 2026-10-03 生成绑定不再经 prettier:ts-rs 原始输出即提交形态
|
||||
|
||||
- 背景:`scripts/check-generated-bindings.mjs` 对 AGC 的 `chat/generated` / `services/generated` 在重生成后会就地跑一遍 `npx prettier --write` 再比较。这会直接改写生成文件,还把「Rust 声明真的变了」与「prettier 版本 / 配置造成的格式漂移」混在同一条告警里——本次报出的 `ThreadRequestKind.ts` / `TurnCompletedStatus.ts`「内容变化」无法复现为语义变化(已提交内容与当前 Rust 枚举一致),prettier 归一化把格式差异也报成了「与 Rust 声明不一致」;生成物被仓库格式化工具二次改写后,重跑 `cargo test export_bindings` 也不再幂等。
|
||||
- 决策:生成绑定一律以 ts-rs 原始输出提交,不接受 prettier / eslint 等工具二次改写。`check-generated-bindings.mjs` 删掉 prettier 步骤,直接逐字节比较原始输出;`packages/shared/src/contracts/generated`、`chat/generated`、`services/generated`、`features/ui-editor/types` 四个目录统一登记进 `.prettierignore` 与 `.eslintrc.cjs` 的 `ignorePatterns`;`.prettierrc.json` 里为 `contracts/generated` 设的 `printWidth: 1000` / `singleQuote: false` 覆盖随之删除。
|
||||
- 边界:ts-rs 原始输出在多行对象 / 枚举变体行尾带空格,`.gitattributes` 对四个生成目录设 `whitespace=-trailing-space`,CI 的 `git diff --check` 不再误报;手写文件的行尾空白检查不变。生成 `.ts` 仍提交进仓库供前端消费,并标 `linguist-generated=true`。
|
||||
- 影响范围:`scripts/check-generated-bindings.mjs`、`.prettierignore`、`.prettierrc.json`、`.eslintrc.cjs`、`.gitattributes`、`apps/ai-game-creator-shell/src/{view/project-development/chat,services}/generated/**`。
|
||||
- 验证:`cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml export_bindings`、`npm run check:generated-bindings`(shared-contracts 1 + AGC 104 = 105 个文件)、`npx prettier --check` 四个生成目录(全部跳过)、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-10-03 回合错误的处置分类层与线程条目脱敏边界
|
||||
|
||||
- 背景:`TurnError::terminal_failure -> Option<TurnFailure>` 用一个 `None` 同时表达"没有失败"和"不是失败、要继续跑(返修 / 复核控制流)",调用方看到 `None` 只会理解成前者,`dispatch.rs` 两处只能 `.expect("回合失败必可投影成失败载荷")`;同时 ThreadManager 在搬运线程条目时做字段级脱敏与限长,前端要被截断,而且与失败载荷的脱敏是两套实现。
|
||||
- 决策(分类层):`TurnError::classify(&self, root) -> TurnErrorClassified{ShouldStop(TurnFailure), ShouldContinue { detail: String }}` 取代 `terminal_failure`——真失败继续投影成 `TurnFailure`(脱敏 + 截断仍在这一处),控制流带自己的说明走 `ShouldContinue`;`dispatch.rs` 两处改成按分类 match,`ShouldContinue` 不写终态、不伪造失败。"这一轮怎么收场"仍只由 `TurnCompletion` 定义,private `SessionOutcome` 并入 `session_completion`。
|
||||
- 决策(脱敏边界):ThreadManager **不做任何字段级脱敏与限长**——`wire/items.rs` 的 `bounded` / `detail_text` / `sanitize_detail_text` / `relativize_project_root_paths` / `thread_delta_text` 与三个字符上限常量删除,条目与流式增量原样透传;脱敏移到前端 `chat/conversation/directThreadSanitize`,在 bootstrap / consume / 历史切片进入聊天状态之前统一做(前端手里有 `projectPath`,能把项目内绝对路径归一成相对路径)。失败载荷(错误文案)的脱敏不属于 ThreadManager,保留在 `TurnError::classify` 投影时。订阅侧的 8 MiB / 8192 事件缓冲上限不动:那是背压,不是字段限长。
|
||||
- 边界:错误尚未持久化,`TurnErrorClassified` 是纯宿主内部类型、不加 `Serialize` / `TS`;线上 `TurnFailure` 与 `ThreadEvent` 形状、占位符词表(`<absolute-path>` / `[redacted-secret]` / `[redacted-sensitive-field]` / `[redacted-config]` / `[redacted sensitive context]`)都不变。`TurnFailure` 名字加了 `// TODO badnaming` 待后续改。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/agent/{codex_app_server/{turn_error.rs,mod.rs},thread_manager/{dispatch.rs,turn_completion.rs,wire/{items.rs,failure.rs,tests.rs}},generation/prompt_context.rs}`、`apps/ai-game-creator-shell/src-tauri/src/commands/desktop.rs`、前端 `chat/{controller/useDirectThreadChatSubscription.ts,conversation/directThreadSanitize.ts}`、`chat/generated/{ThreadItem,TurnFailure}.ts`、`tests/directThreadSanitize.test.ts`。
|
||||
- 验证:`cargo test -- agent:: --skip export_bindings`(949 passed;删掉一条已无对象的流式脱敏用例)、`npm run check:generated-bindings`、`npm run ai-game-creator-shell:typecheck`、`npx vitest run apps/ai-game-creator-shell/tests/directThreadSanitize.test.ts`(12 passed)、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`;全量 vitest 的 `gameDistributionPublish*` / `recentProjectsHook` localStorage 失败为既有问题。
|
||||
|
||||
## 2026-10-02 DirectProject 失败载荷两臂改名与 typed 失败原样下发
|
||||
|
||||
- 背景:`turn.completed.failure` 的两个载荷臂把字符串债藏在像正常类型的名字后面(`TurnFailed { stage, detail: String }`、`TurnFailedUnclassified { detail: String }`);同时 `direct_runtime` 与 `thread_manager::dispatch` 各有一处收口把**任意** `TurnError` 重包成 `TurnFailed { stage: turn_failure_stage(), detail: 预拼收口文案 }`,typed 变体(模型调用 / 超时 / 通道断开)在下发前就被吃掉,前端只能看到 catch-all 与一个伪造的 `code-generation` 阶段。
|
||||
- 决策(命名):两个载荷臂按"这是待清债"的既有约定起丑名字——`TurnFailed → SuperErrorFromStringPlusStage`(只有 `stage` 是 typed、`detail` 仍是产生层字符串)、`TurnFailedUnclassified → Unclassified`(连阶段都没有);线上 `type` 同步为 `superErrorFromStringPlusStage` / `unclassified`,生成文件 `TurnFailed.ts` / `TurnFailedUnclassified.ts` 删除。`stage` 留在变体内部,**不做成 wrapper 层的正交字段**:其余 8 个变体根本没有阶段,包到外层只会给它们编假值。
|
||||
- 决策(透传):删掉上述两处收口重包,`Err(failure)` 原样透传;`.agent/runtime/errors`、应用日志与错误上报池的审计写盘保留,只是返回值不再当失败载荷的 `detail`。前端因此第一次能按真实变体(`modelCallFailed` / `timedOut` / `transportClosed`…)选文案。
|
||||
- 边界:不改 `SuperErrorEnumFromStringTyped`(仍在 `is_retryable` / `is_model_repairable` 上做内部分类,detail 的 typed 化留给上游改造);不迁就存量字符串分流、不加别名;错误尚未持久化,线上 `type` 值直接改、不做迁移。
|
||||
- 影响范围:`agent/codex_app_server/turn_error.rs`、`agent/direct_runtime/{mod.rs,user_input.rs}`、`agent/thread_manager/{dispatch.rs,turn_completion.rs,wire/failure.rs}`、前端 `chat/{conversation/directTurnFailure.ts,generated/**}`、`src/features/agent-runtime/model.ts`(注释)、`tests/directThreadChat.test.ts`。
|
||||
- 验证:`cargo check`(bin)、`cargo test -- agent:: --skip export_bindings`(948 passed)、`cargo test export_bindings` 后 `npx prettier --write chat/generated/*.ts`、`npm run ai-game-creator-shell:typecheck`、`npx vitest run apps/ai-game-creator-shell/tests`(`NODE_OPTIONS=--localstorage-file=…`,196 files / 1930 passed)、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-10-02 DirectProject 回合错误命名化与 wire 模块拆分
|
||||
|
||||
- 背景:DirectProject 三条错误通道的类型还带着 `Direct` / `DirectCodex` 前缀(`DirectTurnError` / `DirectTurnEnqueueError` / `DirectTurnFailure`),且 `thread_manager/wire.rs`(1600+ 行)把条目投影、事件、失败载荷与终态判定混在一个文件里;`direct_turn_error.rs` 也留在 `agent/` 顶层而不是它服务的 `codex_app_server` 深模块旁边。
|
||||
- 决策(命名):既然类型已经归到具名深模块,去掉冗余前缀——`DirectTurnError → TurnError`、`DirectTurnEnqueueError → EnqueueError`、`DirectTurnFailure → TurnFailure`、`DirectTurnDeadline → Deadline`、`DirectCodexFailureStage → FailureStage`、`DirectCodexNativeKind → NativeKind`、`DirectModelCallKind → ModelCallKind`;`direct_codex_user_item` 里的 `DirectCodexUserItem/UserMessageItem/UserRole/UserContentPart/UserAttachmentReferencePart/UserRuntimeRegionPart → UserItem/UserMessageItem/UserRole/UserContentPart/UserAttachmentReferencePart/UserRuntimeRegionPart`;`codex_app_server` 内部的 `DirectCodexTurnKind/DirectCodexTurnObservation/DirectTurnRunFailure/DirectTurnReport/DirectTurnTerminalContext/DirectTurnCancelView → TurnKind/TurnObservation/RunFailure/TurnReport/TerminalContext/TurnCancelView`;`direct_now_ms → now_ms`。载荷 struct 名仍是"变体裸名",`TurnFailure` 的投影点仍是 `TurnError::classify` 一处。
|
||||
- 决策(模块归位):`agent/thread_manager/wire.rs` 提升为目录并按职责拆分——`wire/{mod,clock,items,turn,failure,tests}.rs`,`wire/` 只留**线上形状**(`TurnFailure` 载荷与 `ThreadEvent`);`agent/direct_turn_failure.rs` 的终态判定并入 `agent/thread_manager/turn_completion.rs`;`agent/direct_turn_error.rs`(三条错误表与分类)移到 `agent/codex_app_server/turn_error.rs`。`thread_manager::wire::*` 仍从 `mod.rs` 平铺 re-export,外部路径不变。
|
||||
- 决策(终态类型):宿主侧的回合终态从 `struct TurnTerminal { status, failure }` 改为判别联合 `enum TurnCompletion { Completed, Interrupted, Aborted, Failed(TurnFailure) }`——`status` 由变体反推(投影回 `turn.completed` 时才变回字符串),失败必须带载荷、正常收场不许带;「有载荷就一定是失败」这条反推关系不变。`TurnCompletion` **不是线上形状**:不加 `Serialize` / `TS`、不导出、不下发,放在 `thread_manager/turn_completion.rs` 而不是 `wire/`;收尾阶段推出来的 `status` 字符串在这里一次性收进类型,认不出的值 fail closed(按未分类失败),不冒充正常收场。`thread_manager/mod.rs` 的过期回合释放兜底也改走 `TurnCompletion::Aborted.event(...)`。
|
||||
- 边界:只改类型 / 函数 / 生成文件命名与模块位置,不改线上 JSON 形状(`TurnFailure` 的 `type` 判别值与字段名不变,`TurnCompletion` 只影响宿主内部);不迁就存量字符串分流,不保留别名或 `Display` 回落。`DirectTurnFailureKind`、`wire_kind()`、`Display for TurnError` 与 `From<TurnError> for String` 已在上一轮删除。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/agent/{codex_app_server/{mod.rs,execution.rs,turn_error.rs},thread_manager/{mod.rs,dispatch.rs,wire/},direct_runtime/{mod.rs,user_input.rs},direct_codex_user_item/*,runtime_driver/entrypoints.rs,...}`、前端 `chat/{controller,conversation}/**` 与 `chat/generated/**`(旧绑定文件删除、新绑定文件随 `cargo test export_bindings` 生成)、`scripts/check-generated-bindings.mjs`、`tests/**`。
|
||||
- 验证:`cargo check`(bin)、`cargo test -- agent::thread_manager`(69 passed)与 `cargo test -- terminal`(73 passed)、`npm run ai-game-creator-shell:typecheck`、`npx vitest run apps/ai-game-creator-shell/tests`(DirectProject 相关用例全绿;`gameDistributionPublish*` / `recentProjectsHook` 的 localStorage 失败为既有问题,与本次无关)、`npm run check:generated-bindings`(104 个文件)、`npm run check:encoding`、`git diff --check`。
|
||||
|
||||
## 2026-10-02 资源编辑远端失败的原始原因穿出到工具错误,资源编辑错误通道补一层 typed
|
||||
|
||||
- 背景:轮询到 `status=failed` 时客户端只读 `status`,丢掉平台在同一个响应里给的 `error`(契约 `ExternalEditorGenerationJobResponse.error`),统一写 `terminal_failure_code = remote-generation-failed` 并返回「remote-terminal-failed: 资源编辑生成失败」。平台的可行动原因就此消失:模型与用户卡片只看到一句「失败了」,重试路径(`ensure_resource_edit_phase_resumable`)也只有分类码。这违反 `pitfalls.md`「远端资源编辑终态必须指出唯一出口」里已写下的口径——「首次失败的原始拒绝说明继续由当次错误文案承担」;提交期 HTTP 400 分支(`editor_api_rejection_reason`)兑现了,轮询分支没有。另外 `remote-terminal-failed:` 只是文案前缀(全仓没有 `starts_with` 解析它),在第一句失败文案里与「失败」重复。
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
- **原因**:① 登录已下沉 Rust,`login_client_with_password` 等命令失败返回 `Err(String)`,Tauri 以**裸字符串**拒绝 `invoke`,前端拿不到任何类型信息;② `shouldCaptureClientError` 对非 object 值走默认 `return true`,`handleLoginSubmit` 的 catch 把预期业务拒绝报进了错误池。技术方案里"预期 4xx 登录/鉴权失败不进池"的口径早就成立,是错误通道的实现方式违背了它。
|
||||
- **处理(现行口径)**:命令错误一律按具体变体结构化(`Result<_, ClientAuthError>` + ts-rs 导出),认证命令统一经 `invokeClientAuth` 调用:结构化拒绝原样装进已有的 `ClientAuthErrorWrapper`(只有一个 `error` 字段,值是判别联合),UI 在 catch 里按具体变体分流——认得的业务 / 会话变体只给用户反馈,系统变体原样 `throw` 经 `unhandledrejection` 入池,非结构化拒绝原样抛出;删除 `shouldCaptureClientError`。详见 [`【ADR】AGC命令错误结构化与错误报告口径-2026-10-01`](../../adr/【ADR】AGC命令错误结构化与错误报告口径-2026-10-01.md) 与 [`【ADR】AGC认证失败的JS侧载体与抛出时机-2026-10-01`](../../adr/【ADR】AGC认证失败的JS侧载体与抛出时机-2026-10-01.md)。
|
||||
- **判据/取证**:`npx vitest run apps/ai-game-creator-shell/tests/authFailureReporting.test.tsx`——登录返回结构化业务变体时 `report_client_error` 不被调用;系统变体只上报一次(`source` 取全局 `unhandledrejection` handler 的显式入参;载体不再携带 `action`)。Rust 侧 `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml auth_error` 钉住变体 `type` 与 400/401/429/5xx/网络映射。
|
||||
- **形状约定**:`ClientAuthError` 顶层只放调用方要分流的类别,可枚举细分收进类型化枚举 `reason` 字段——无字段变体在 TS 里就是 `{ type: 'x' }`;带载荷变体是 `{ type: 'x' } & X`,`X` 由 ts-rs 导出到 `src/services/generated/X.ts`(Rust 侧是 newtype 变体持有同名结构体),细分原因枚举(`ServerAddressReason` / `AuthNetworkReason` / `AuthResponseInvalidReason`)同样由 ts-rs 生成。**不要手写这些类型**,也不要在前端再加一层分类 / 提示文案派生函数——判别一律写在 catch 子句里:`const failure = error.error; switch (failure.type)`,无字段 `case` 用本 catch 的固定文案,带载荷 `case` 先 `as X` 再读自己的字段,`reason` 是枚举时再 `switch (payload.reason)`,两处 `default` 都用 `expectNever` 保证漏接编译失败。改形状只能改 Rust 再跑 `cargo test` 重新导出,生成物随后交给 prettier;ts-rs 只写文件、不删文件,变体从有载荷改成无字段时要手动清掉孤立的 `X.ts`(本次 `AuthResponseServerRejected.ts` 就是这样删的)。
|
||||
- **形状约定**:`ClientAuthError` 顶层只放调用方要分流的类别,可枚举细分收进类型化枚举 `reason` 字段——无字段变体在 TS 里就是 `{ type: 'x' }`;带载荷变体是 `{ type: 'x' } & X`,`X` 由 ts-rs 导出到 `src/services/generated/X.ts`(Rust 侧是 newtype 变体持有同名结构体),细分原因枚举(`ServerAddressReason` / `AuthNetworkReason` / `AuthResponseInvalidReason`)同样由 ts-rs 生成。**不要手写这些类型**,也不要在前端再加一层分类 / 提示文案派生函数——判别一律写在 catch 子句里:`const failure = error.error; switch (failure.type)`,无字段 `case` 用本 catch 的固定文案,带载荷 `case` 先 `as X` 再读自己的字段,`reason` 是枚举时再 `switch (payload.reason)`,两处 `default` 都用 `expectNever` 保证漏接编译失败。改形状只能改 Rust 再跑 `cargo test` 重新导出,生成物保持 ts-rs 原始输出(不再经 prettier / eslint 二次改写,见本节「生成绑定」口径);ts-rs 只写文件、不删文件,变体从有载荷改成无字段时要手动清掉孤立的 `X.ts`(本次 `AuthResponseServerRejected.ts` 就是这样删的)。
|
||||
- **Rust 侧不得把结构化错误降级成字符串**:`refresh_session_inner` 的非权威失败直接返回 `Err(ClientAuthError)`,视图不带 `errorMessage`;一旦折成 `String`,前端就只能拿文案判断,变体信息永久丢失。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/auth_session.rs`、`apps/ai-game-creator-shell/src/services/{clientAuth.ts,errorReporting.ts,platformSession.ts}`、`apps/ai-game-creator-shell/src/app/AuthenticatedClient.tsx`。
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
- **仍未修**:`/` 开头的 delta 片段被判成绝对路径(上面 ②)。要修必须把「上一个字符」带进边界判定(正文增量可从 `direct_project_history` 的累计文本取,思考增量目前没有累计器),属于跨 delta 状态的取舍,本次未一并改。
|
||||
- **判据/取证**:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell direct_thread_delta`——新增 `direct_thread_delta_sanitization_preserves_line_breaks` 钉住「逐段脱敏 == 整段脱敏」,去掉 `split_inclusive` 即红;真实文本的回归用渲染侧夹具复核(修复前 table/li/h2 全 0,修复后与整段脱敏一致:1 个 table / 3 个 th / 4 个 h2)。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/mod.rs`、`.../agent/generation/prompt_context.rs`、`.../agent/thread_manager/wire.rs`、`apps/ai-game-creator-shell/src/view/project-development/chat/conversation/directThreadChat.ts`、`#384`。
|
||||
- **现状(2026-10-03 更新)**:逐 delta 的 Rust 脱敏已整体退役——ThreadManager 改为原样透传,流式正文与历史条目的脱敏统一移到前端 `directThreadSanitize`,在事件进聊天状态前逐段处理并保留换行。上面两条根因与"仍未修"针对的实现已不存在,保留作历史。
|
||||
|
||||
## 2026-10-01 文件列举被无关临时锁删除打断
|
||||
|
||||
@@ -5794,7 +5795,8 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- **处理(现行口径)**:不要把重写结果当改动提交。跑过 `cargo test` 或构建后只恢复 `apps/ai-game-creator-shell/src/view/project-development/chat/generated/DirectCodexUser*.ts` 的仓库版本,再删掉多出来的 `DirectCodexUserMessageEnvelope.ts`;不要恢复整个 `generated/` 目录,以免误删 DirectThread 的现役绑定。绑定与前端形状冲突时以**已提交的 DirectCodexUser 绑定 + 前端**为基准排查。
|
||||
- **验证**:恢复仓库版本后 `npm run ai-game-creator-shell:typecheck` exit 0(`[skill-pack] OK`);保留重写结果时同一条命令 exit 2。release 构建本身还会在 `src/features/ui-editor/types/` 落下 `BindingChange.ts` / `BindingDTO.ts` 两个无人引用的生成产物;它们不属于前端契约,发现后直接删除,不提交。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/agent/direct_codex_user_item/`(ts-rs 导出源)、`apps/ai-game-creator-shell/src/features/project-workspace/resourceReferences.ts`、`apps/ai-game-creator-shell/scripts/build-release.mjs`(`beforeBuildCommand`)。
|
||||
- **2026-09-24 补充(纯格式 churn 的一档)**:直接运行 AGC 的测试二进制(含全量套件,里面带 `export_bindings`)同样会把 `src/view/project-development/chat/generated/DirectThread*.ts` 重写成 raw ts-rs 形态——双引号、行尾空格、`};` 变 `, };`——于是 `git diff --check` 报一片 trailing whitespace,而 `npm run check:generated-bindings`(只覆盖 `packages/shared/src/contracts/generated`)不会报警。处理:对这组文件跑一次 `npx prettier --write "apps/ai-game-creator-shell/src/view/project-development/chat/generated/*.ts"` 做归一化,再确认 `git diff --stat` 为空——为空就说明这一档只是格式 churn,没有语义变化;不要为它盲目 `git checkout` 整个目录。该目录目前没有自动漂移门禁,靠「跑完测试后归一化 + diff 检查」把关。
|
||||
- **2026-09-24 补充(纯格式 churn 的一档)**:直接运行 AGC 的测试二进制(含全量套件,里面带 `export_bindings`)同样会把 `src/view/project-development/chat/generated/DirectThread*.ts` 重写成 raw ts-rs 形态——双引号、行尾空格、`};` 变 `, };`——于是 `git diff --check` 报一片 trailing whitespace,而 `npm run check:generated-bindings`(只覆盖 `packages/shared/src/contracts/generated`)不会报警。处理(2026-10-03 更新,口径已变):不再跑 prettier 归一化——`chat/generated` 与 `services/generated` 的提交形态就是 ts-rs 原始输出;两个目录已进 `.prettierignore` + eslint `ignorePatterns`,`git diff --check` 由 `.gitattributes` 的 `whitespace=-trailing-space` 豁免,`npm run check:generated-bindings` 会逐字节比较原始输出。跑完 `cargo test` 后 `git diff` 为空即为幂等。
|
||||
- **2026-10-02 补充(过滤跑也躲不开)**:`cargo test` 的位置参数是**子串匹配**,`-- agent::thread_manager::` 这类"只跑几个模块"的过滤会连带命中 `agent::thread_manager::wire::failure::export_bindings_turnfailure`,于是照样重写 `chat/generated/` 与 `src/services/generated/`(后者是 auth 绑定)。要按模块跑又不碰生成目录,用 `cargo test --bin genarrative-ai-game-creator-shell -- agent:: --skip export_bindings`;已经被重写时不要再做 prettier 归一化:两个目录的提交形态就是原始输出,按需重新生成或 `git checkout --`,再用 `npm run check:generated-bindings` 确认无漂移。
|
||||
|
||||
## 2026-09-16 Node 26 下 vitest 的 jsdom 用例拿不到 window.localStorage
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
|
||||
- `project.jsonl` 与项目主对话共用信封类型,不要为了"可见但不喂模型"新增行结构。
|
||||
- 埋点 `settle` 早于成绩入库会静默丢事件(未来"进历史但不喂模型"的条目同理要落在注入侧,不在读取侧)。
|
||||
- `cargo test export_bindings` 会重写全部 `chat/generated/`(引号风格漂移),跑完要 `git checkout --`
|
||||
掉不是本次新增的文件。
|
||||
- `cargo test export_bindings` 会重写全部 `chat/generated/`;生成目录的提交形态就是 ts-rs 原始输出
|
||||
(2026-10-03 起已从 prettier / eslint 排除),跑完用 `git diff` 为空确认幂等,不要做 prettier 归一化。
|
||||
- 本机 rust 全量 `--bins` 测试会挂在 mock server 的 `inet_csk_accept` 上,用 `--bins "agent::"` 之类过滤跑。
|
||||
|
||||
## review 收口第二轮(2026-09-24)
|
||||
|
||||
Reference in New Issue
Block a user