合并最新master并保留埋点与工作台接线
合并master的发布入口、工作台与CI更新。 保留项目离开埋点、运行通知及双方后台接口测试。 同步双方决策记录并验证客户端和后台相关检查。
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# AGC 客户端更新检查与下载
|
||||
|
||||
更新时间:`2026-09-21`
|
||||
更新时间:`2026-09-22`
|
||||
|
||||
本文件是 AGC 客户端自动更新的主规范:更新能力由 Tauri 官方插件 `tauri-plugin-updater` 承担,并按下文渠道分发。
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
- 数据不跨渠道共享:本地项目、工程快照、模板、登录态、诊断日志与 Runner/项目锁按渠道身份分目录。切渠道等于换一个客户端,不迁移、不合并本地数据;渠道内的 origin 隔离规则不变。
|
||||
- 主窗口与工作区/启动器窗口标题取构建期产品名,让同机并存的渠道客户端在任务栏与 Alt-Tab 中可区分;默认渠道标题仍是「陶泥儿」。
|
||||
- 首装包与更新包的对象名包含产品名(如 `陶泥儿 Release_0.1.96_x64-setup.exe`、`陶泥儿 Release_0.1.96_aarch64.dmg`)。清单 `downloads` 地址由发布脚本按本次真实产物派生,禁止写死产品名;首装包选择按 `<版本>_<架构>.dmg` 唯一匹配,不依赖产品名字面量。
|
||||
- 产品名中的空格在清单 URL 中必须使用标准百分号编码(如 `%20`);网站服务端允许这种合法文件名编码,但仍拒绝控制字符、路径分隔符、DEL 和非法百分号编码,不得通过改写真实产物名绕过校验。
|
||||
- Windows 提权 ACL 修复助手按目录名识别安装身份:`<基线>` 与 `<基线>.<渠道>` 都在 AGC 自有的 managed 范围内;相似前缀(例如 `world.genarrative.ai-game-creator-backup`)不在范围内,落回 user-selected 范围或直接拒绝。
|
||||
|
||||
## 非目标
|
||||
@@ -136,8 +137,8 @@
|
||||
- 发布入口只解析一次目标,优先级为 CLI `--target value` / `--target=value` / `-t value`、`AGC_BUILD_TARGET`、Windows 默认值;重复/空目标与不支持目标失败关闭。版本高水位、构建 feature/渠道端点、bundle 路径、产物后缀、清单平台键及摘要必须消费同一个发布上下文,不能分别回读默认目标。
|
||||
- 渠道由 `AGC_UPDATE_CHANNEL` 显式指定,默认 dev;Windows 与 macOS 目标均支持 dev、release 和自定义渠道,目标校验独立进行。
|
||||
- 渠道 `--config` 在 Tauri 构建前最后合并,同时注入 `productName`、`identifier` 与 updater 端点:安装身份与更新端点必须来自同一个渠道,不能各自回读默认值。macOS 发布入口构建 `*.app`、updater 归档与 DMG 前先按发布渠道解析产品名,产物名一律派生而不写死。
|
||||
- 定时调度只在本轮到达的提交包含 AGC 相关路径(客户端、共享包、`server-rs/crates`、AGC 插件、桌面壳图标、根依赖清单)时才触发渠道发布;纯文档或流水线自身的提交只跑 Full Build,不推高客户端版本号。判定失败或勾选强制触发时按"需要发布"处理。
|
||||
- 更新摘要自动生成:发布脚本用渠道清单里的 `commit` 字段(上一次发布的提交)到本次提交之间、且只覆盖客户端相关路径的提交列表生成 `notes`(每条 `- 提交标题(短 SHA)`,最多 12 条、主题 80 字、整体 900 字,超出折叠或截断),同时写入旧协议清单的 `releaseNotes` 和归档文件 `release-notes.txt`。`AGC_UPDATE_RELEASE_NOTES` 非空时以手动文案为准;无法判定起点(缺少上次 `commit` 或本地没有该提交)时不写摘要。清单缺少 `commit` 时回退用上一次成功构建的 `COMMIT_HASH`(CI 通过 `AGC_UPDATE_PREVIOUS_COMMIT` 传入)作为锚点,因此首次启用摘要或更换渠道后也能立即产出摘要。锚点仍不可得(清单读取失败或没有 CI 锚点)时降级为「最近客户端改动」列表并注明可能与上一版重复 —— 摘要属于附注,任何情况下都不允许因为它让发布失败。
|
||||
- 定时调度分别判断服务端与客户端 scope:dev 小时调度在提交含 AGC 相关路径时发布对应渠道,纯文档或流水线自身的提交仍只跑 Full Build;release 每日调度在服务端相关路径变化时发布正式 Full Build,在 AGC 相关路径变化时发布 release 客户端,并在同一调度内等待、汇总各 lane 结果,失败 lane 下一轮补发。判定失败或勾选强制触发时按"需要发布"处理。
|
||||
- 更新摘要自动生成:发布脚本用渠道清单里的 `commit` 字段(上一次发布的提交)到本次提交之间、且只覆盖客户端相关路径的提交列表生成 `notes`(每条 `- 提交标题`,标题只取 commit message 第一行并忽略后续说明行;最多 12 条、主题 80 字、整体 900 字,超出折叠或截断),同时写入旧协议清单的 `releaseNotes` 和归档文件 `release-notes.txt`。`AGC_UPDATE_RELEASE_NOTES` 非空时以手动文案为准;无法判定起点(缺少上次 `commit` 或本地没有该提交)时不写摘要。清单缺少 `commit` 时回退用上一次成功构建的 `COMMIT_HASH`(CI 通过 `AGC_UPDATE_PREVIOUS_COMMIT` 传入)作为锚点,因此首次启用摘要或更换渠道后也能立即产出摘要。锚点仍不可得(清单读取失败或没有 CI 锚点)时降级为「最近客户端改动」列表并注明可能与上一版重复 —— 摘要属于附注,任何情况下都不允许因为它让发布失败。
|
||||
- 清单里的 `commit` 是非标准字段:更新插件忽略未知字段,发布脚本用它定位下一次摘要的起点。
|
||||
- 上传:安装包与 `.sig` 上传到 `agc/<channel>-win|mac/<version>/`,清单以 `--force` 覆盖上传到对应分区的 `latest.json`,保证 latest 指针与清单内 URL 指向已存在的对象。
|
||||
- 首装发布:发布脚本生成 `downloads`,Windows 复用已选 NSIS `.exe`,Mac 选择本次版本和目标架构匹配的非空 `.dmg`;缺失、歧义或版本/架构不匹配时失败,不发布带悬空地址的清单。上传顺序为更新包、签名及首装包全部成功后再更新渠道清单,Windows 相同对象只上传一次。`dry-run` 不写 OSS。各渠道独立写自己的清单,由 BFF 汇总,Windows 与 Mac 发布不会覆盖彼此的下载项;Mac 跨架构合并仍遵循现有单架构发布约束。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AGC 总版本号与发号
|
||||
|
||||
更新时间:`2026-09-20`
|
||||
更新时间:`2026-09-22`
|
||||
|
||||
## 背景
|
||||
|
||||
@@ -18,7 +18,7 @@ AGC 客户端此前按「渠道各自比高水位自增」发号:`dev-win` 与
|
||||
|
||||
- `next = 总号 + 1`;总号不存在时先一次性播种,见下节。
|
||||
- 顺序固定为「先写总号 → 再构建 → 再发渠道清单」;任何一步失败都不回滚,只烧号。
|
||||
- 统一构建:发一次号,通过 `AGC_RELEASE_VERSION` 同时传给 `dev-win`、`dev-mac`(以及后续渠道),各渠道共用同一个号。
|
||||
- 统一构建:发一次号,通过 `AGC_RELEASE_VERSION` 同时传给同一渠道组的两个平台;dev 调度写 `dev-win` / `dev-mac`,每日 release 调度写 `release-win` / `release-mac`,组内共用同一个号。
|
||||
- 单渠道热修:发一次号,只传给该渠道;其他渠道清单保持原值。
|
||||
- 显式传入 `AGC_RELEASE_VERSION` 的构建不再自行发号,只做高水位断言。
|
||||
|
||||
@@ -39,8 +39,8 @@ AGC 客户端此前按「渠道各自比高水位自增」发号:`dev-win` 与
|
||||
- 发号模块:`apps/ai-game-creator-shell/scripts/agc-global-version.mjs`(读总号 / 播种 / 发号 / 写后回读 / 渠道高水位断言 / dry-run 预览)。
|
||||
- 发号入口:`apps/ai-game-creator-shell/scripts/issue-global-version.mjs`(CI 与本地共用,输出固定为 `AGC_GLOBAL_VERSION=<version>`)。
|
||||
- 构建侧:`build-release.mjs` 的 `prepareReleaseVersion()` 优先采用传入总号,未传入时现场发号;`resolveRemoteHighWaterVersion()` 降级为断言来源,只用于「请求号低于本渠道清单版本即失败关闭」。
|
||||
- CI:`jenkins/Jenkinsfile.agc-global-version-issue` + `jenkins/agc-global-version-issue-job-config.xml`;调度管线 `jenkins/Jenkinsfile.scheduled-revision-trigger` 与手动管线先调发号 Job,再把号透传给 AGC Build。
|
||||
- 发号 Job 的 Copy Artifact 采用生产权限模式,`options` 里的 `copyArtifactPermission(...)` 必须显式列出**全部**消费者:定时调度 `Genarrative-Scheduled-Revision-Trigger` 与手动发布 `Genarrative-Manual-Build-And-Deploy`。用户触发的构建按「认证用户」判权(SYSTEM 定时构建短路放行),漏列时手动发布会报 `Unable to find project for artifact copy: Genarrative-Agc-Global-Version-Issue`,且失败点在发号之后。改完该 `options` 后必须先单独跑一次发号 Job,让 Declarative Pipeline 把 Job property 写回 Jenkins。
|
||||
- CI:`jenkins/Jenkinsfile.agc-global-version-issue` + `jenkins/agc-global-version-issue-job-config.xml`;dev 调度管线 `jenkins/Jenkinsfile.scheduled-revision-trigger`、每日 release 调度管线 `jenkins/Jenkinsfile.scheduled-release-trigger` 与手动管线先调发号 Job,再把号透传给 AGC Build;release 调度的服务端 Full Build 不使用 AGC 总号,只使用固定 `COMMIT_HASH` 与 Full Build 自身版本。
|
||||
- 发号 Job 的 Copy Artifact 采用生产权限模式,`options` 里的 `copyArtifactPermission(...)` 必须显式列出**全部**消费者:小时 dev 调度 `Genarrative-Scheduled-Revision-Trigger`、每日 release 调度 `Genarrative-Scheduled-Release-Trigger` 与手动发布 `Genarrative-Manual-Build-And-Deploy`。用户触发的构建按「认证用户」判权(SYSTEM 定时构建短路放行),漏列时手动发布会报 `Unable to find project for artifact copy: Genarrative-Agc-Global-Version-Issue`,且失败点在发号之后。改完该 `options` 后必须先单独跑一次发号 Job,让 Declarative Pipeline 把 Job property 写回 Jenkins。
|
||||
|
||||
## 不改的东西
|
||||
|
||||
|
||||
@@ -241,6 +241,25 @@ Rust 侧在 `server-rs/crates/shared-contracts` 维护唯一权威 `GameCreation
|
||||
|
||||
Rust 分片日志在失败时输出有界 stdout 尾部中的失败段,保留 panic 位置、断言详情和 Rust 汇总;selected 只表示该分片选中的用例数量。成功分片保留简短摘要。定向验证使用相关 Rust 用例与 `node --test apps/ai-game-creator-shell/scripts/run-rust-shell-test-shards.test.mjs`。
|
||||
|
||||
## 策划 Agent 对话显示与滚动合同
|
||||
|
||||
策划工作台的对话区保留阶段状态、工作区状态、消息、可选确认/澄清和输入区。面板高度由工作台和视口决定;空消息、短回复和流式长回复不能改变消息区域的上下边界。阶段、状态条、输入区按内容排列,消息区独占剩余空间并内部滚动;待处理卡片出现时只让出其实际所需且有上限的空间,不依赖可选节点的序号分配伸缩高度。
|
||||
|
||||
- 工作区状态条复用现有聊天状态条的字号、间距和状态点。长项目名允许换行,不能撑宽面板;长错误、澄清和批量文件导入结果在受限区域内完整可读,不能挤走输入框。输入编辑器保留原有高度上限,模型/推理菜单继续允许弹出面板。
|
||||
- 已在消息底部时,实时正文与思考增高后继续跟随;用户主动上滚阅读历史后不自动抢回底部,发送新消息后恢复跟随。阶段/待处理卡片改变消息可用高度时,仍遵守同一跟随意图。滚动仅为临时 UI 状态,不写入正式会话。
|
||||
- 历史消息只有收到真实发送时间才能显示时间。现有策划持久消息不含逐消息时间,读取或刷新时保持未知,不以当前时刻补造。当前会话刚提交的乐观消息可以显示已知发送时间;正式快照覆盖后不补造或猜配旧消息时间。
|
||||
- ≤760px 时资源区与对话区单列排列,策划工作台在固定外壳内纵向滚动,用户向下滚动可到达输入区。布局使用内容高度,并以同等或更高选择器优先级覆盖外壳的 `height: 100%`;资源区明确为 560px,对话区高度为 `clamp(560px, calc(100dvh - 154px), 900px)`。文件树与消息列表各自内部滚动,长内容不增加两块面板高度。>760px 继续共用外壳剩余高度,不启用工作台整体滚动。正式主窗最小宽度不变,窄屏验收覆盖浏览器响应式布局。
|
||||
- 审批、澄清、导入期间禁用、错误重试、项目归属和发送权限沿用现有行为。此次调整不改变 Runtime、API、持久协议或数据库,无数据迁移;不重做开发 Agent 的对话布局。
|
||||
|
||||
验收使用策划组件与现有界面测试覆盖流式/历史跟随、未知时间、审批澄清和导入禁用;使用真实浏览器与当前样式核对桌面/窄屏的空、短、长消息,长项目名、长错误与长澄清,以及输入框和菜单位置。布局验收必须包含 `window-chrome → window-chrome__content → launcher-shell → launcher-main → game-project-workbench` 的完整外壳层级,覆盖 390px、760px、761px 和桌面尺寸;窄屏实际滚动工作台后,输入框须进入可视范围且可操作,长文件树、长消息和待确认内容不能使面板失去高度边界。不能只断言输入框位于聊天面板内部。开发 Agent 的既有布局回归同批执行。真实 Provider 请求不作为纯展示修复的前置条件,验证记录须区分模拟事件与真实 Provider。
|
||||
|
||||
| 验收面 | 对应证据 |
|
||||
| --- | --- |
|
||||
| 策划与开发 Agent 布局隔离、伸缩与窄屏滚动可达 | `chatDialogFrameLayout.test.ts` 包含外壳的选择器层叠回归;Chrome 实际组件、完整外壳与完整样式的 390px/760px/761px/桌面几何、滚动和输入操作检查 |
|
||||
| 实时正文/思考跟随、上滚停留、发送恢复 | `appSurface/design-agent.suite.ts` 的实时事件与发送恢复用例;还原旧滚动依赖时新增用例失败 |
|
||||
| 历史未知时间与乐观发送时间 | 同套界面测试覆盖读取、乐观发送和正式快照覆盖;恢复 `Date.now()` 补造时新增用例失败 |
|
||||
| 审批/澄清、文件导入禁用及共用控件 | `appSurface.test.ts` 现有交互回归与 Chrome 模型菜单位置检查;不改变原生调用和业务状态 |
|
||||
|
||||
## 策划 Agent 批量局部修改
|
||||
|
||||
`patch_file` 的所有 edits 均匹配同一份原文件,参数顺序不影响结果。完成唯一匹配与不重叠校验后,按原文起点升序拼接未修改片段与替换文本,最后一次性写入;任一校验失败时不写文件。回归用例覆盖乱序 edits、中文内容与替换长度增减,并核对完整落盘内容。此行为仅属于策划 Agent 文件工具。
|
||||
@@ -1805,7 +1824,8 @@ Direct 回合的所有权属于进程内项目身份锁,不属于当前页面
|
||||
- 失败关闭:单个文件失败不推进该文件的索引项,失败文件与剩余文件在下一次周期或下次关闭时重试。鉴权失败(401/403)与格式类拒绝(400/413)是确定性失败,停止本轮剩余请求并等待用户处理后重试;服务端配额或频率拒绝(429)与传输类失败按可重试处理。
|
||||
- 配额与限流:单文件 64 MiB、单次同步上传预算 512 MiB(超出部分延后到下一次)、单项目常驻上限 2 GiB(客户端在扫描后先判,超限直接给出明确失败;服务端按清单累计体积复核并返回 413);服务端按用户做进程内小时配额(文件 3000 次、清单 120 次)并对同一项目强制 5 秒最小清单间隔,超限返回 429 且带 `Retry-After`。进程内配额只用于抑制异常客户端与失控重试,跨节点配额由"单项目上限 + 清单引用回收"保证。
|
||||
- 生命周期:同步有界超时(单文件与整次同步分别设上限),项目关闭与应用退出路径不因同步失败而阻塞或延迟退出超过超时上限。
|
||||
- 上传内容边界:复用项目索引与 checkpoint 同一份 `should_skip_project_snapshot_path` 口径——整个 `.agent`(含 runtime、logs、checkpoint、manifest、project.lock)、版本控制目录、`node_modules`/`target`/`dist`/`build`/`coverage`/`.cache`、凭据目录与 `.pem`/`.key` 等敏感后缀都不参与同步;符号链接与重解析点同样跳过。单文件(64 MiB)与单次同步总量(512 MiB)各有上限,超限文件进入跳过或延后清单而不是静默丢弃。
|
||||
- 上传内容边界:`.agent` 是项目身份与 Agent 状态的权威位置,**整目录参与同步**(`manifest.json`、`agent.db` 及其 WAL/SHM、conversations、logs、checkpoint、workbench、`project.lock`、`.manifest.json.lock`)。因此快照同步使用独立口径 `should_skip_project_snapshot_sync_path`:它与 `should_skip_project_snapshot_path` 共用同一份组件与后缀规则,只额外放行 `.agent` 组件本身,以及 `.agent` 内的 Agent 状态数据库后缀(`.db`/`.db-wal`/`.db-shm`)。其余排除项在 `.agent` 内同样生效——版本控制目录、`node_modules`/`target`/`dist`/`build`/`coverage`/`.cache`、凭据目录、`.pem`/`.key`/`.sql` 等敏感后缀与 `.env*` 都不参与同步;符号链接与重解析点在扫描阶段跳过(不能被当作普通文件传输)。单文件(64 MiB)与单次同步总量(512 MiB)各有上限,超限文件进入跳过或延后清单而不是静默丢弃。
|
||||
- 该口径只对快照同步生效:项目索引、checkpoint、Agent 上下文与 git 检查继续排除整个 `.agent`。收录 `.agent` 意味着会话记录、运行日志与诊断快照随项目离机并写入该用户自己的私有前缀,这是本轮产品决定(远端工程包要能还原项目身份与 AGC 历史),不是遗漏。
|
||||
|
||||
### 契约与兼容
|
||||
|
||||
@@ -1829,7 +1849,7 @@ Direct 回合的所有权属于进程内项目身份锁,不属于当前页面
|
||||
- `GET /admin/api/project-snapshots/{userId}/{projectId}/download` 只读取该用户/项目的固定清单与其引用对象,返回 `application/zip` 附件。ZIP 中路径直接使用原始相对路径,不包含 userId、摘要目录或 OSS 前缀;名称使用经过安全处理的项目名和 revision。下载固定本次读到的清单,远端并发回收导致对象缺失则整体失败,不能静默遗漏。
|
||||
- `partial` 快照下载返回 409;`unverified` 历史快照可导出已同步文件,列表明确显示“完整性未知”,动作称“下载已存文件”。`ready` 才显示“下载完整工程”。ZIP 构建核验每一文件的长度与 fnv1a64 摘要,拒绝穿越、绝对路径、重复/大小写冲突路径、非法项目身份;缺失或损坏整体失败,不返回成功的残缺 ZIP。
|
||||
- ZIP 使用服务端临时文件并限制并发,不将 2 GiB 工程整体驻留内存;成功、失败、客户端取消均清理临时文件。单文件、总量、文件数沿用上传上限,超限明确拒绝。零字节工程文件可以上传和导出。OSS 凭据与签名不下发浏览器,列表失败保留错误而非伪造空列表。
|
||||
- 工程归档范围与上传策略一致:源码、素材及引擎配置按原路径保存,依赖/构建缓存、凭据、`.agent` 会话与运行日志排除;此 ZIP 不声明能恢复 AGC 对话历史。后台读取需要目标前缀的 ListObjects 与 GetObject 权限,不新增数据库表,不改 External API。
|
||||
- 工程归档范围与上传策略一致:源码、素材、引擎配置与 `.agent`(含会话、运行日志、checkpoint、`agent.db`)都按原相对路径保存,依赖/构建缓存与凭据排除;因此该 ZIP 可以还原项目身份与 AGC 对话历史(归档只保证字节还原,不承诺跨机器可用性)。后台读取需要目标前缀的 ListObjects 与 GetObject 权限,不新增数据库表,不改 External API。
|
||||
- 验收覆盖真实单窗口生命周期登记、首次/增量/零字节上传、后台列表分页和权限、ZIP 解压目录及摘要、部分/历史清单、缺失对象、路径拒绝、下载取消清理,并分别报告定向测试和真实环境证据。
|
||||
|
||||
### 未决问题
|
||||
|
||||
Reference in New Issue
Block a user