mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-21 22:11:26 +08:00
refactor(ffi): 降级 FFI 为可选兼容层并整理文档
将 bat-ffi 明确收敛为无状态 C ABI 兼容层,默认集成路径改为 bat --json 进程边界或未来稳定 SDK。 同步 README、当前状态、项目计划、架构文档、开发指南和缺口清单,移除 FFI 作为主集成边界的表述。 新增 AGENTS.md 和 CONTRIBUTING.md,压缩 CLAUDE.md 为兼容入口,并归档阶段性报告、同步 .gitignore 规则。
This commit is contained in:
+5
-2
@@ -45,8 +45,11 @@ go.work.sum
|
|||||||
logs/
|
logs/
|
||||||
pg_log/
|
pg_log/
|
||||||
|
|
||||||
# Generated reports
|
# Generated/local-only reports
|
||||||
/docs/reports/fuck-u-code-current.md
|
/docs/reports/generated/
|
||||||
|
/docs/reports/fuck-u-code-*.md
|
||||||
|
/docs/reports/*-current.generated.md
|
||||||
|
/docs/reports/**/SMOKE_REPORT.md
|
||||||
|
|
||||||
# Backups
|
# Backups
|
||||||
/deployments/backups/
|
/deployments/backups/
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# Agent 开发规则
|
||||||
|
|
||||||
|
本文件是 BlueArchive Toolkit 中 AI agent、自动化开发助手和长期维护脚本的权威入口。它替代旧 `CLAUDE.md` 中真正长期有效的工程规则。
|
||||||
|
|
||||||
|
## 语言和表达
|
||||||
|
|
||||||
|
1. 默认使用简体中文交流、写文档、写提交说明、写开发日志和写 API 说明。
|
||||||
|
2. 代码中的包名、类型名、函数名、变量名、数据库字段、协议字段和命令参数保持英文命名规范。
|
||||||
|
3. 代码注释只在能降低理解成本时添加;不要写复述代码行为的空泛注释。
|
||||||
|
4. 如果任务、上游规范或第三方 API 明确要求英文,可以在对应位置使用英文。
|
||||||
|
|
||||||
|
## 项目定位
|
||||||
|
|
||||||
|
BlueArchive Toolkit 是长期维护的开源工具链,不是 demo、一次性脚本或临时试验项目。
|
||||||
|
|
||||||
|
长期目标包括但不限于:
|
||||||
|
|
||||||
|
1. 官方资源同步、版本管理、增量同步、断点续传、重试、限速、缓存和校验。
|
||||||
|
2. Content Addressable Storage(CAS)、引用计数、垃圾回收、多版本共享和完整性校验。
|
||||||
|
3. UnityFS / AssetBundle / Addressables / Manifest 解析框架,并保持解析器与业务逻辑解耦。
|
||||||
|
4. 文本提取、翻译记忆、术语库、AI Provider 抽象、Patch、CLI、Web、API、SDK 和插件系统。
|
||||||
|
5. 支持未来扩展到其他区域、语言或 Unity 游戏;不要把架构写死到单一版本。
|
||||||
|
|
||||||
|
## 工程边界
|
||||||
|
|
||||||
|
1. 默认工作于用户本地环境。不要把生产环境当作开发环境。
|
||||||
|
2. 真实资源下载、smoke run 和手动验证必须写入隔离目录,例如 `/tmp` 或显式指定的测试目录。
|
||||||
|
3. 不要默认读取、修改或污染现有客户端目录、生产资源目录或 `/home/wanye/D/BlueArchive` 这类本地资源目录。
|
||||||
|
4. 不要要求安装官方启动器作为生产运行前提。可以分析启动器资源或官方公开数据,但生产链路必须能在 Linux 环境中独立运行。
|
||||||
|
5. 涉及官方资源时,优先使用官方 `.hash`、catalog、manifest 和可复现 fixture 做校验依据。
|
||||||
|
|
||||||
|
## 架构原则
|
||||||
|
|
||||||
|
1. 仓库采用 monorepo;模块必须边界清晰、高内聚、低耦合。
|
||||||
|
2. 公共接口应稳定、可测试、可维护,并为未来扩展保留合理空间。
|
||||||
|
3. Rust 侧优先承担二进制解析、AssetBundle、Patch、CAS 和官方资源后端能力;Go 侧优先承担 CLI、运维入口和面向用户的命令编排。边界调整必须先说明理由。
|
||||||
|
4. Rust/Go 默认集成路径优先进程边界(当前为 `bat --json`)或未来稳定 SDK;`bat-ffi` 仅作为可选无状态 C ABI 兼容层,不能扩展成 daemon、下载器、CAS handle 或主控制面。
|
||||||
|
5. SDK 不得与 CLI 耦合;解析器不得与业务流程耦合;Provider、存储后端、Patch 算法和解析器应保留插件化扩展点。
|
||||||
|
6. 不引入 God Object、God Class、超长函数、超长文件、硬编码、魔法数字、重复代码、临时实现或只为当前测试通过的伪实现。
|
||||||
|
7. 不使用 `TODO`、`FIXME` 掩盖未完成设计。确实无法完成时,应在当前缺口文档中说明边界、风险和后续工作。
|
||||||
|
|
||||||
|
## 开发流程
|
||||||
|
|
||||||
|
1. 动手前先读相关文档和代码,确认当前真实状态。
|
||||||
|
2. 对跨模块、架构、数据格式或用户工作流有影响的改动,先给出设计判断或简短计划。
|
||||||
|
3. 实现后必须同步验证。验证范围要覆盖改动实际影响面,而不是只跑最窄的命令。
|
||||||
|
4. 涉及用户可见行为、运行方式、架构边界或缺口状态时,必须同步更新文档。
|
||||||
|
5. 保持改动范围和任务目标一致;不要顺手做无关重构或格式化 churn。
|
||||||
|
6. 如果需求、技术路线或设计存在明显风险,应直接指出并给出可执行替代方案。
|
||||||
|
7. 不确定的事实必须查证或询问;不要凭空调用不存在的接口、命令、路径或线上资源。
|
||||||
|
|
||||||
|
## 质量要求
|
||||||
|
|
||||||
|
1. 所有错误必须显式处理,并给出可诊断信息。
|
||||||
|
2. 日志应结构化或至少足够定位阶段、路径、版本、URL、重试、校验和失败原因。
|
||||||
|
3. 下载、写文件、状态切换和发布操作必须考虑原子性、断点续传、并发锁、失败恢复和清理策略。
|
||||||
|
4. 本地状态文件和索引必须有版本字段或兼容策略。
|
||||||
|
5. 新增 fixture、golden 或回归样本时,应说明它覆盖的真实风险。
|
||||||
|
6. 默认验证命令见 `docs/guides/development.md`;稳定工程基线见 `docs/guides/baseline.md`。
|
||||||
|
|
||||||
|
## 文档职责
|
||||||
|
|
||||||
|
长期规则的权威位置如下:
|
||||||
|
|
||||||
|
1. `AGENTS.md`:agent 行为、工程边界、架构原则和质量要求。
|
||||||
|
2. `CONTRIBUTING.md`:贡献者工作流、提交规范、验证和 PR 要求。
|
||||||
|
3. `docs/guides/development.md`:环境准备、开发命令、测试、调试和真实资源验证方式。
|
||||||
|
4. `PROJECT_PLAN.md`:产品目标、阶段路线图和长期能力规划。
|
||||||
|
5. `CURRENT_STATUS.md`:当前实现状态。
|
||||||
|
6. `docs/reports/CURRENT_GAPS.md`:当前缺口、优先级和关闭顺序。
|
||||||
|
|
||||||
|
`CLAUDE.md` 只保留兼容入口,不应继续新增长期规则。
|
||||||
@@ -1,452 +1,14 @@
|
|||||||
# BlueArchive Toolkit 项目开发任务(Claude Opus 4.6)
|
# Claude 兼容入口
|
||||||
|
|
||||||
你现在不是普通 AI,而是本项目唯一的长期架构师(Chief Architect)、首席开发工程师(Lead Developer)、代码审查者(Code Reviewer)、技术负责人(Tech Lead)以及长期维护者(Maintainer)。
|
本文件仅作为 Claude Code 等旧工具默认读取 `CLAUDE.md` 时的兼容入口,不再承载项目长期规则。
|
||||||
|
|
||||||
请始终牢记:
|
当前权威文档:
|
||||||
|
|
||||||
**整个开发过程中,必须始终使用简体中文回复。**
|
- `AGENTS.md`:AI agent 和自动化开发助手必须遵守的长期规则。
|
||||||
|
- `CONTRIBUTING.md`:贡献者协作、提交、验证和文档要求。
|
||||||
|
- `docs/guides/development.md`:本地开发环境、工作流、测试和调试指南。
|
||||||
|
- `PROJECT_PLAN.md`:项目长期目标和路线图。
|
||||||
|
- `CURRENT_STATUS.md`:当前工作区真实状态。
|
||||||
|
- `docs/reports/CURRENT_GAPS.md`:当前缺口、优先级和关闭顺序。
|
||||||
|
|
||||||
包括但不限于:
|
使用 Claude 时,请先读取 `AGENTS.md`,再按任务需要读取 `CONTRIBUTING.md` 和 `docs/guides/development.md`。如果本文件与上述权威文档冲突,以上述权威文档为准。
|
||||||
|
|
||||||
* 所有解释
|
|
||||||
* 所有设计
|
|
||||||
* 所有分析
|
|
||||||
* 所有文档
|
|
||||||
* 所有 README
|
|
||||||
* 所有注释
|
|
||||||
* 所有 API 文档
|
|
||||||
* 所有提交说明
|
|
||||||
* 所有开发日志
|
|
||||||
|
|
||||||
均默认使用简体中文。
|
|
||||||
|
|
||||||
代码中的类名、接口名、方法名、变量名、包名等仍然保持英文命名规范。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 项目背景
|
|
||||||
|
|
||||||
我要开发一个名为 **BlueArchive Toolkit** 的大型开源项目。
|
|
||||||
|
|
||||||
该项目目标不是 Demo,也不是脚本,而是一个能够长期维护、持续扩展、达到工业级质量的完整平台。
|
|
||||||
|
|
||||||
本项目默认工作于用户本地环境。
|
|
||||||
|
|
||||||
整个系统围绕 Blue Archive(日服)资源展开,但请不要假设项目仅服务于某一个游戏版本,整个架构必须具有良好的可扩展能力,以便未来支持其他区域、其他语言甚至其他 Unity 游戏。
|
|
||||||
|
|
||||||
整个项目必须按照 Production Ready 标准开发。
|
|
||||||
|
|
||||||
严禁以 Demo、最小实现(Minimum Viable Product)、临时方案、占位实现等思路完成任何模块。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 项目目标
|
|
||||||
|
|
||||||
项目需要逐步实现并形成完整生态。
|
|
||||||
|
|
||||||
包括但不限于:
|
|
||||||
|
|
||||||
## 资源同步
|
|
||||||
|
|
||||||
能够同步资源。
|
|
||||||
|
|
||||||
支持:
|
|
||||||
|
|
||||||
* Manifest
|
|
||||||
* 版本管理
|
|
||||||
* 增量同步
|
|
||||||
* Hash 校验
|
|
||||||
* 多线程下载
|
|
||||||
* 断点续传
|
|
||||||
* 自动重试
|
|
||||||
* 限速
|
|
||||||
* 下载缓存
|
|
||||||
* 本地对象存储
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 存储系统
|
|
||||||
|
|
||||||
采用 Content Addressable Storage(CAS)。
|
|
||||||
|
|
||||||
必须支持:
|
|
||||||
|
|
||||||
* Hash 去重
|
|
||||||
* 引用计数
|
|
||||||
* 垃圾回收
|
|
||||||
* 多版本共享
|
|
||||||
* 完整性校验
|
|
||||||
|
|
||||||
不得使用简单目录堆放文件。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Unity AssetBundle
|
|
||||||
|
|
||||||
设计完整解析框架。
|
|
||||||
|
|
||||||
要求支持插件化。
|
|
||||||
|
|
||||||
未来能够支持:
|
|
||||||
|
|
||||||
* TextAsset
|
|
||||||
* Localization
|
|
||||||
* MonoBehaviour
|
|
||||||
* ScriptableObject
|
|
||||||
* Texture
|
|
||||||
* Sprite
|
|
||||||
* Audio
|
|
||||||
* Video
|
|
||||||
* 其他 Unity 资源
|
|
||||||
|
|
||||||
解析器必须独立。
|
|
||||||
|
|
||||||
不得与业务逻辑耦合。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 文本提取
|
|
||||||
|
|
||||||
自动提取:
|
|
||||||
|
|
||||||
* 剧情
|
|
||||||
* UI
|
|
||||||
* 系统文本
|
|
||||||
* 配置文本
|
|
||||||
|
|
||||||
统一导出标准格式。
|
|
||||||
|
|
||||||
不得直接修改原始资源。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Translation Memory
|
|
||||||
|
|
||||||
建立翻译记忆库。
|
|
||||||
|
|
||||||
支持:
|
|
||||||
|
|
||||||
* 自动匹配
|
|
||||||
* 模糊匹配
|
|
||||||
* Provider 来源
|
|
||||||
* 审核状态
|
|
||||||
* 历史记录
|
|
||||||
* 多语言
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Glossary
|
|
||||||
|
|
||||||
建立术语库。
|
|
||||||
|
|
||||||
术语优先级必须高于 AI。
|
|
||||||
|
|
||||||
所有 AI 翻译必须优先遵循术语。
|
|
||||||
|
|
||||||
支持:
|
|
||||||
|
|
||||||
* 多语言
|
|
||||||
* 别名
|
|
||||||
* 分类
|
|
||||||
* 冲突检测
|
|
||||||
* 审核
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## AI 翻译
|
|
||||||
|
|
||||||
设计 Provider 抽象层。
|
|
||||||
|
|
||||||
未来支持:
|
|
||||||
|
|
||||||
* DeepL
|
|
||||||
* OpenAI
|
|
||||||
* Anthropic
|
|
||||||
* Google
|
|
||||||
* Azure
|
|
||||||
* 自定义 Provider
|
|
||||||
|
|
||||||
所有 Provider 必须统一接口。
|
|
||||||
|
|
||||||
不得耦合具体实现。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Patch
|
|
||||||
|
|
||||||
设计完整 Patch 系统。
|
|
||||||
|
|
||||||
支持:
|
|
||||||
|
|
||||||
* 增量 Patch
|
|
||||||
* Binary Patch
|
|
||||||
* JSON Patch
|
|
||||||
* Rollback
|
|
||||||
* Integrity Check
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
设计完整命令体系。
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
sync
|
|
||||||
|
|
||||||
extract
|
|
||||||
|
|
||||||
translate
|
|
||||||
|
|
||||||
patch
|
|
||||||
|
|
||||||
verify
|
|
||||||
|
|
||||||
doctor
|
|
||||||
|
|
||||||
serve
|
|
||||||
|
|
||||||
cache
|
|
||||||
|
|
||||||
manifest
|
|
||||||
|
|
||||||
bundle
|
|
||||||
|
|
||||||
所有命令必须统一风格。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Web
|
|
||||||
|
|
||||||
设计完整后台。
|
|
||||||
|
|
||||||
包括:
|
|
||||||
|
|
||||||
* 登录
|
|
||||||
* 权限
|
|
||||||
* 翻译审核
|
|
||||||
* 术语管理
|
|
||||||
* 全文搜索
|
|
||||||
* 历史版本
|
|
||||||
* Diff
|
|
||||||
* Dashboard
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## SDK
|
|
||||||
|
|
||||||
整个项目必须提供 SDK。
|
|
||||||
|
|
||||||
方便其他项目调用。
|
|
||||||
|
|
||||||
不得把 SDK 与 CLI 耦合。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
所有接口:
|
|
||||||
|
|
||||||
RESTful。
|
|
||||||
|
|
||||||
OpenAPI。
|
|
||||||
|
|
||||||
版本管理。
|
|
||||||
|
|
||||||
统一错误码。
|
|
||||||
|
|
||||||
统一响应结构。
|
|
||||||
|
|
||||||
支持未来扩展。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Database
|
|
||||||
|
|
||||||
自行设计完整数据库。
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
高性能。
|
|
||||||
|
|
||||||
规范化。
|
|
||||||
|
|
||||||
支持 Migration。
|
|
||||||
|
|
||||||
支持未来扩展。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Plugin System
|
|
||||||
|
|
||||||
整个项目必须支持插件。
|
|
||||||
|
|
||||||
以后新增:
|
|
||||||
|
|
||||||
新的解析器
|
|
||||||
|
|
||||||
新的翻译 Provider
|
|
||||||
|
|
||||||
新的存储后端
|
|
||||||
|
|
||||||
新的 Patch 算法
|
|
||||||
|
|
||||||
不得修改核心代码。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 技术栈
|
|
||||||
|
|
||||||
请根据不同模块自行选择最适合的技术。
|
|
||||||
|
|
||||||
我倾向于:
|
|
||||||
|
|
||||||
* Go(CLI、Downloader、API)
|
|
||||||
* Rust(二进制解析、AssetBundle、Patch)
|
|
||||||
* Vue3 + TypeScript(Web)
|
|
||||||
* PostgreSQL
|
|
||||||
* Redis
|
|
||||||
* Docker
|
|
||||||
* GitHub Actions
|
|
||||||
|
|
||||||
但如果你认为有更合理的方案,请给出完整论证后再调整。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 架构要求
|
|
||||||
|
|
||||||
采用 Monorepo。
|
|
||||||
|
|
||||||
严格模块化。
|
|
||||||
|
|
||||||
高内聚。
|
|
||||||
|
|
||||||
低耦合。
|
|
||||||
|
|
||||||
支持长期维护。
|
|
||||||
|
|
||||||
支持未来十年以上持续开发。
|
|
||||||
|
|
||||||
所有模块必须具有明确边界。
|
|
||||||
|
|
||||||
禁止出现:
|
|
||||||
|
|
||||||
* God Object
|
|
||||||
* God Class
|
|
||||||
* 超长函数
|
|
||||||
* 超长文件
|
|
||||||
* Magic Number
|
|
||||||
* Hard Code
|
|
||||||
* 重复代码
|
|
||||||
* 临时实现
|
|
||||||
* Demo 思维
|
|
||||||
* TODO
|
|
||||||
* FIXME
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 开发要求
|
|
||||||
|
|
||||||
不要一次性生成整个项目。
|
|
||||||
|
|
||||||
必须按照真正的软件工程流程。
|
|
||||||
|
|
||||||
每开始一个模块:
|
|
||||||
|
|
||||||
先分析。
|
|
||||||
|
|
||||||
再设计。
|
|
||||||
|
|
||||||
给出架构。
|
|
||||||
|
|
||||||
等待确认(如果我没有要求直接实现)。
|
|
||||||
|
|
||||||
然后编码。
|
|
||||||
|
|
||||||
然后测试。
|
|
||||||
|
|
||||||
然后 Benchmark。
|
|
||||||
|
|
||||||
然后 Documentation。
|
|
||||||
|
|
||||||
最后 Review。
|
|
||||||
|
|
||||||
再继续下一模块。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 代码质量
|
|
||||||
|
|
||||||
所有代码必须达到 Production Ready。
|
|
||||||
|
|
||||||
所有公共接口必须稳定。
|
|
||||||
|
|
||||||
所有配置不得硬编码。
|
|
||||||
|
|
||||||
所有错误必须处理。
|
|
||||||
|
|
||||||
所有日志必须结构化。
|
|
||||||
|
|
||||||
所有模块必须可测试。
|
|
||||||
|
|
||||||
所有模块必须可维护。
|
|
||||||
|
|
||||||
所有模块必须具有扩展能力。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 文档
|
|
||||||
|
|
||||||
每完成一个模块:
|
|
||||||
|
|
||||||
自动同步更新:
|
|
||||||
|
|
||||||
README
|
|
||||||
|
|
||||||
Architecture
|
|
||||||
|
|
||||||
Sequence Diagram
|
|
||||||
|
|
||||||
Flow Diagram
|
|
||||||
|
|
||||||
API Documentation
|
|
||||||
|
|
||||||
Developer Guide
|
|
||||||
|
|
||||||
User Guide
|
|
||||||
|
|
||||||
Deployment Guide
|
|
||||||
|
|
||||||
Change Log
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# AI 行为要求
|
|
||||||
|
|
||||||
你不是代码生成器。
|
|
||||||
|
|
||||||
你应该主动思考。
|
|
||||||
|
|
||||||
主动发现问题。
|
|
||||||
|
|
||||||
主动优化设计。
|
|
||||||
|
|
||||||
主动指出潜在风险。
|
|
||||||
|
|
||||||
主动提出更优方案。
|
|
||||||
|
|
||||||
如果你认为我的设计存在问题,应直接指出并给出充分理由,而不是机械执行。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 最重要要求
|
|
||||||
|
|
||||||
不要为了满足当前需求而牺牲整个项目未来架构。
|
|
||||||
|
|
||||||
整个项目应以工业级开源项目为目标。
|
|
||||||
|
|
||||||
请像维护一个会持续十年以上的大型开源项目一样进行设计和开发,而不是完成一次性的开发任务。
|
|
||||||
|
|
||||||
如果你认为我提出的需求、技术路线或设计思路存在不合理之处,请直接指出,不要因为迎合我的要求而保留明显存在缺陷的设计。你的职责是作为首席架构师提供最佳工程方案,而不是机械执行我的所有想法。
|
|
||||||
|
|
||||||
此外,如果你不知道一些具体的东西,必须询问我,不准虚空调用
|
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# 贡献指南
|
||||||
|
|
||||||
|
感谢参与 BlueArchive Toolkit。这个项目按长期维护的开源工具链标准推进,不接受只为临时通过、不可维护或污染本地资源目录的改动。
|
||||||
|
|
||||||
|
## 开始前
|
||||||
|
|
||||||
|
1. 阅读 `README.md`、`CURRENT_STATUS.md` 和 `docs/reports/CURRENT_GAPS.md`,确认当前实现状态和优先级。
|
||||||
|
2. 涉及官方资源同步、Rust 后端、Go CLI 或架构边界时,额外阅读 `docs/guides/development.md`、`docs/guides/official-resource-test-pull.md` 和相关 ADR。
|
||||||
|
3. AI agent 或自动化助手还必须遵守 `AGENTS.md`。
|
||||||
|
|
||||||
|
## 工作流
|
||||||
|
|
||||||
|
1. 基于当前开发分支创建功能分支。
|
||||||
|
2. 先分析现有文档和代码,再决定实现方式。
|
||||||
|
3. 保持改动聚焦,避免无关重构、批量格式化或元数据 churn。
|
||||||
|
4. 实现后运行覆盖改动范围的测试、格式化和 lint。
|
||||||
|
5. 如果用户可见行为、运行命令、架构边界、缺口状态或数据格式发生变化,同步更新文档。
|
||||||
|
|
||||||
|
## 提交规范
|
||||||
|
|
||||||
|
提交信息使用 Conventional Commits:
|
||||||
|
|
||||||
|
- `feat:` 新功能
|
||||||
|
- `fix:` 修复 bug
|
||||||
|
- `docs:` 文档更新
|
||||||
|
- `test:` 测试或 fixture 更新
|
||||||
|
- `refactor:` 不改变行为的重构
|
||||||
|
- `chore:` 构建、依赖或辅助工具调整
|
||||||
|
|
||||||
|
提交说明默认使用简体中文。代码标识符和协议字段仍使用英文。
|
||||||
|
|
||||||
|
## 验证要求
|
||||||
|
|
||||||
|
基础验证命令见 `docs/guides/development.md`。常用最低门禁:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --check
|
||||||
|
cargo test --workspace
|
||||||
|
cargo clippy --workspace -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
如果改动只影响部分 crate,可以先跑更窄的测试,但合并前必须确保影响面被覆盖。官方资源同步、下载、daemon、status、verify 或 repair 相关改动还应运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test -p bat-infrastructure --bin bat -- --nocapture
|
||||||
|
cargo test -p bat-infrastructure -- --nocapture
|
||||||
|
```
|
||||||
|
|
||||||
|
真实官方网络 smoke run 必须写入隔离目录,禁止写入现有游戏客户端或生产资源目录。
|
||||||
|
|
||||||
|
## 资源和数据安全
|
||||||
|
|
||||||
|
1. 不要把生产环境当作开发环境。
|
||||||
|
2. 不要默认读取或修改 `/home/wanye/D/BlueArchive` 等已有资源目录。
|
||||||
|
3. 不要提交真实账号、token、cookie、私有路径、下载产物、数据库或本地 CAS 数据。
|
||||||
|
4. 新增 fixture 应尽量最小化,只保留验证解析、校验或错误处理所需的数据。
|
||||||
|
|
||||||
|
## PR 要求
|
||||||
|
|
||||||
|
PR 描述应包含:
|
||||||
|
|
||||||
|
1. 改动摘要。
|
||||||
|
2. 影响范围。
|
||||||
|
3. 已运行的验证命令。
|
||||||
|
4. 未覆盖风险或后续缺口。
|
||||||
|
5. 相关 issue、ADR 或文档链接。
|
||||||
|
|
||||||
|
如果改动关闭缺口或 issue,请在 PR 或提交中明确引用。
|
||||||
+13
-6
@@ -173,28 +173,35 @@ Rust 侧官方日服资源链路已经从实验验证推进到正式入口:
|
|||||||
|
|
||||||
### `bat-ffi`
|
### `bat-ffi`
|
||||||
|
|
||||||
状态:**粗粒度 JSON API 可用,稳定边界仍需继续收敛**
|
状态:**可选无状态兼容层,非主集成边界**
|
||||||
|
|
||||||
已包含:
|
已包含:
|
||||||
|
|
||||||
- `bat_version`。
|
- `bat_version`。
|
||||||
- `bat_manifest_inspect_json`:解析 Addressables manifest 并返回 JSON summary。
|
- `bat_manifest_inspect_json`:解析 Addressables manifest 并返回 JSON summary。
|
||||||
- `bat_sync_plan_json`:根据 current/previous snapshot 生成官方同步计划 JSON。
|
- `bat_sync_plan_json`:根据 current/previous snapshot 生成官方同步计划 JSON。
|
||||||
- `internal/ffi/ffi.go` 提供 Go 包装骨架。
|
- `internal/ffi/ffi.go` 提供可选 CGO 兼容包装骨架。
|
||||||
|
|
||||||
|
定位约束:
|
||||||
|
|
||||||
|
- `bat-ffi` 只暴露粗粒度、无状态、一次调用一次 JSON 输入输出的 C ABI helper。
|
||||||
|
- 它不持有 downloader、daemon、CAS handle、资源目录锁或长生命周期状态。
|
||||||
|
- Go CLI 和生产运维默认应调用 `bat --json` 进程边界;未来稳定 SDK 也优先于 FFI。
|
||||||
|
- FFI 仅用于需要嵌入 C ABI 的兼容场景,不能作为官方同步控制面或主集成边界。
|
||||||
|
|
||||||
待完成:
|
待完成:
|
||||||
|
|
||||||
- Go CLI 调用链路。
|
|
||||||
- 错误码与结构化响应约定。
|
- 错误码与结构化响应约定。
|
||||||
- 发布用头文件、构建脚本和跨平台产物。
|
- 如确有兼容需求,再补发布用头文件、构建脚本和跨平台产物。
|
||||||
|
|
||||||
### Go / API / Web
|
### Go / API / Web
|
||||||
|
|
||||||
状态:**Go FFI 包骨架存在,CLI/API/Web 仍未实现**
|
状态:**CLI/API/Web 仍未实现,仅有可选 CGO 兼容包装**
|
||||||
|
|
||||||
当前情况:
|
当前情况:
|
||||||
|
|
||||||
- `internal/ffi/ffi.go` 已存在。
|
- `internal/ffi/ffi.go` 已存在。
|
||||||
|
- Go CLI 默认集成方向是调用 Rust `bat --json` 并转发结构化 report,而不是依赖 FFI。
|
||||||
- `cmd/`、`pkg/`、`api/`、`web/` 仍无可用产品入口。
|
- `cmd/`、`pkg/`、`api/`、`web/` 仍无可用产品入口。
|
||||||
- `go test ./...` 在没有 Go package 时可能无测试可运行;Makefile 会清晰跳过空 Go 阶段。
|
- `go test ./...` 在没有 Go package 时可能无测试可运行;Makefile 会清晰跳过空 Go 阶段。
|
||||||
|
|
||||||
@@ -256,7 +263,7 @@ cargo run -p bat-infrastructure --bin bat -- \
|
|||||||
|
|
||||||
下一阶段必须优先完成:
|
下一阶段必须优先完成:
|
||||||
|
|
||||||
1. Go CLI 最小可用入口:`bat doctor`、`bat sync --help`、Rust 官方同步命令包装。
|
1. Go CLI 最小可用入口:`bat doctor`、`bat sync --help`、通过 `bat --json` 包装 Rust 官方同步命令。
|
||||||
2. 官方同步结果接入 CAS + ResourceRepository 的用户级工作流。
|
2. 官方同步结果接入 CAS + ResourceRepository 的用户级工作流。
|
||||||
3. AssetBundle UnityFS 基础解析。
|
3. AssetBundle UnityFS 基础解析。
|
||||||
4. Addressables parser 对更多官方 catalog 结构的覆盖。
|
4. Addressables parser 对更多官方 catalog 结构的覆盖。
|
||||||
|
|||||||
Generated
+1
-199
@@ -8,56 +8,6 @@ version = "0.2.21"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstream"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
|
||||||
dependencies = [
|
|
||||||
"anstyle",
|
|
||||||
"anstyle-parse",
|
|
||||||
"anstyle-query",
|
|
||||||
"anstyle-wincon",
|
|
||||||
"colorchoice",
|
|
||||||
"is_terminal_polyfill",
|
|
||||||
"utf8parse",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle"
|
|
||||||
version = "1.0.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle-parse"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
|
||||||
dependencies = [
|
|
||||||
"utf8parse",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle-query"
|
|
||||||
version = "1.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.61.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle-wincon"
|
|
||||||
version = "3.0.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
|
||||||
dependencies = [
|
|
||||||
"anstyle",
|
|
||||||
"once_cell_polyfill",
|
|
||||||
"windows-sys 0.61.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.103"
|
version = "1.0.103"
|
||||||
@@ -180,15 +130,8 @@ dependencies = [
|
|||||||
name = "bat-ffi"
|
name = "bat-ffi"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"bat-adapters",
|
"bat-adapters",
|
||||||
"bat-assetbundle",
|
|
||||||
"bat-cas-engine",
|
|
||||||
"bat-core",
|
|
||||||
"bat-infrastructure",
|
"bat-infrastructure",
|
||||||
"bat-patch",
|
|
||||||
"cbindgen",
|
|
||||||
"libc",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -279,25 +222,6 @@ version = "1.12.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cbindgen"
|
|
||||||
version = "0.27.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb"
|
|
||||||
dependencies = [
|
|
||||||
"clap",
|
|
||||||
"heck 0.4.1",
|
|
||||||
"indexmap",
|
|
||||||
"log",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"syn",
|
|
||||||
"tempfile",
|
|
||||||
"toml",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.67"
|
version = "1.2.67"
|
||||||
@@ -314,39 +238,6 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap"
|
|
||||||
version = "4.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
|
|
||||||
dependencies = [
|
|
||||||
"clap_builder",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap_builder"
|
|
||||||
version = "4.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
|
|
||||||
dependencies = [
|
|
||||||
"anstream",
|
|
||||||
"anstyle",
|
|
||||||
"clap_lex",
|
|
||||||
"strsim",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "clap_lex"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colorchoice"
|
|
||||||
version = "1.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concurrent-queue"
|
name = "concurrent-queue"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -680,12 +571,6 @@ dependencies = [
|
|||||||
"hashbrown 0.15.5",
|
"hashbrown 0.15.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "heck"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -838,12 +723,6 @@ dependencies = [
|
|||||||
"hashbrown 0.17.1",
|
"hashbrown 0.17.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "is_terminal_polyfill"
|
|
||||||
version = "1.70.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
@@ -1050,12 +929,6 @@ version = "1.21.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell_polyfill"
|
|
||||||
version = "1.70.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking"
|
name = "parking"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
@@ -1317,15 +1190,6 @@ dependencies = [
|
|||||||
"zmij",
|
"zmij",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_spanned"
|
|
||||||
version = "0.6.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -1498,7 +1362,7 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"either",
|
"either",
|
||||||
"heck 0.5.0",
|
"heck",
|
||||||
"hex",
|
"hex",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -1635,12 +1499,6 @@ dependencies = [
|
|||||||
"unicode-properties",
|
"unicode-properties",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
@@ -1766,47 +1624,6 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.8.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
"serde_spanned",
|
|
||||||
"toml_datetime",
|
|
||||||
"toml_edit",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_datetime"
|
|
||||||
version = "0.6.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_edit"
|
|
||||||
version = "0.22.27"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
|
||||||
dependencies = [
|
|
||||||
"indexmap",
|
|
||||||
"serde",
|
|
||||||
"serde_spanned",
|
|
||||||
"toml_datetime",
|
|
||||||
"toml_write",
|
|
||||||
"winnow",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml_write"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
@@ -1890,12 +1707,6 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf8parse"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
@@ -2011,15 +1822,6 @@ version = "0.48.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winnow"
|
|
||||||
version = "0.7.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "writeable"
|
name = "writeable"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
|
|||||||
+8
-5
@@ -1,6 +1,6 @@
|
|||||||
# BlueArchiveToolkit 文档索引
|
# BlueArchiveToolkit 文档索引
|
||||||
|
|
||||||
- **更新时间**:2026-07-14
|
- **更新时间**:2026-07-15
|
||||||
- **说明**:本索引用于快速定位当前权威文档和历史资料。
|
- **说明**:本索引用于快速定位当前权威文档和历史资料。
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -15,7 +15,9 @@
|
|||||||
- `docs/guides/official-full-pull-smoke.md`:真实官方全量拉取 smoke runbook 和可重复命令。
|
- `docs/guides/official-full-pull-smoke.md`:真实官方全量拉取 smoke runbook 和可重复命令。
|
||||||
- `docs/architecture/official-resource-backend.md`:官方资源后端职责、工作原理和审核说明。
|
- `docs/architecture/official-resource-backend.md`:官方资源后端职责、工作原理和审核说明。
|
||||||
- `CHANGELOG.md`:版本变更记录。
|
- `CHANGELOG.md`:版本变更记录。
|
||||||
- `CLAUDE.md`:长期开发约束和项目要求。
|
- `AGENTS.md`:AI agent 和自动化开发助手长期规则。
|
||||||
|
- `CONTRIBUTING.md`:贡献者协作、提交和验证要求。
|
||||||
|
- `CLAUDE.md`:Claude Code 等旧工具的兼容入口。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -28,8 +30,6 @@
|
|||||||
- `deployments/systemd/`:官方资源同步生产 systemd unit 和环境文件示例。
|
- `deployments/systemd/`:官方资源同步生产 systemd unit 和环境文件示例。
|
||||||
- `docs/guides/official-resource-test-pull.md`:官方资源拉取与自动更新用户指南。
|
- `docs/guides/official-resource-test-pull.md`:官方资源拉取与自动更新用户指南。
|
||||||
- `docs/guides/official-full-pull-smoke.md`:真实官方全量拉取 smoke runbook 和可重复命令。
|
- `docs/guides/official-full-pull-smoke.md`:真实官方全量拉取 smoke runbook 和可重复命令。
|
||||||
- `docs/reports/current-stage-prepush.md`:当前阶段说明与推送前核查记录。
|
|
||||||
- `docs/reports/current-status-handoff.md`:给下一次对话使用的当前进度交接说明。
|
|
||||||
- `docs/guides/baseline.md`:稳定工程基线指南。
|
- `docs/guides/baseline.md`:稳定工程基线指南。
|
||||||
- `docs/architecture/adr/0001-engine-and-application-boundaries.md`:Rust/Go 边界决策。
|
- `docs/architecture/adr/0001-engine-and-application-boundaries.md`:Rust/Go 边界决策。
|
||||||
- `docs/architecture/adr/0002-cas-v1-design-boundary.md`:CAS V1 边界决策。
|
- `docs/architecture/adr/0002-cas-v1-design-boundary.md`:CAS V1 边界决策。
|
||||||
@@ -60,6 +60,7 @@
|
|||||||
历史报告已按来源和主题归档,供追溯使用,不再代表当前状态。
|
历史报告已按来源和主题归档,供追溯使用,不再代表当前状态。
|
||||||
|
|
||||||
- `docs/reports/historical/root/`:原根目录阶段报告。
|
- `docs/reports/historical/root/`:原根目录阶段报告。
|
||||||
|
- `docs/reports/historical/current-stage/`:已被 `CURRENT_STATUS.md` 和当前指南取代的阶段交接、推送前核查报告。
|
||||||
- `docs/reports/historical/week2/`:Week 2 相关报告。
|
- `docs/reports/historical/week2/`:Week 2 相关报告。
|
||||||
- `docs/reports/historical/week3/`:Week 3 相关报告。注意:这些报告中存在“完成”和“回滚”的冲突描述。
|
- `docs/reports/historical/week3/`:Week 3 相关报告。注意:这些报告中存在“完成”和“回滚”的冲突描述。
|
||||||
- `docs/reports/historical/build-logs/`:历史构建、测试、Clippy 输出。
|
- `docs/reports/historical/build-logs/`:历史构建、测试、Clippy 输出。
|
||||||
@@ -81,6 +82,8 @@
|
|||||||
7. `docs/guides/baseline.md`
|
7. `docs/guides/baseline.md`
|
||||||
8. `docs/architecture/README.md`
|
8. `docs/architecture/README.md`
|
||||||
9. `docs/guides/development.md`
|
9. `docs/guides/development.md`
|
||||||
|
10. `CONTRIBUTING.md`
|
||||||
|
11. `AGENTS.md`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -98,7 +101,7 @@
|
|||||||
- 真实官方网络全量拉取 smoke 已固化为 `scripts/official-full-pull-smoke.sh` 和 `make official-smoke`,默认写入 `/tmp` 隔离目录并输出本地运行报告。
|
- 真实官方网络全量拉取 smoke 已固化为 `scripts/official-full-pull-smoke.sh` 和 `make official-smoke`,默认写入 `/tmp` 隔离目录并输出本地运行报告。
|
||||||
- `bat` 运行时 progress log 已覆盖总体下载进度、单文件下载进度和校验结果摘要。
|
- `bat` 运行时 progress log 已覆盖总体下载进度、单文件下载进度和校验结果摘要。
|
||||||
- Addressables 当前真实形态 fixture/golden 覆盖。
|
- Addressables 当前真实形态 fixture/golden 覆盖。
|
||||||
- SQLite Resource Repository 和粗粒度 FFI JSON 接口。
|
- SQLite Resource Repository 和可选无状态 `bat-ffi` JSON 兼容接口。
|
||||||
|
|
||||||
优先待办:
|
优先待办:
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -15,7 +15,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
2. **Rust 核心引擎**:负责 CAS、AssetBundle 解析、Patch、二进制安全处理和性能敏感逻辑。
|
2. **Rust 核心引擎**:负责 CAS、AssetBundle 解析、Patch、二进制安全处理和性能敏感逻辑。
|
||||||
3. **Go 服务层**:负责 CLI 编排、资源同步、下载器、API Server、任务调度和外部集成。
|
3. **Go 服务层**:负责 CLI 编排、资源同步、下载器、API Server、任务调度和外部集成。
|
||||||
4. **Web 管理后台**:负责翻译审核、术语管理、全文搜索、历史版本、Diff 和 Dashboard。
|
4. **Web 管理后台**:负责翻译审核、术语管理、全文搜索、历史版本、Diff 和 Dashboard。
|
||||||
5. **SDK/API**:提供稳定的 Go SDK、进程边界或必要时的 FFI 边界和 REST/OpenAPI 接口,方便其他工具复用。
|
5. **SDK/API**:提供稳定的 Go SDK、进程边界和 REST/OpenAPI 接口,方便其他工具复用;FFI 仅保留为可选兼容层。
|
||||||
6. **插件系统**:允许新增解析器、翻译 Provider、存储后端、Patch 算法,而不修改核心代码。
|
6. **插件系统**:允许新增解析器、翻译 Provider、存储后端、Patch 算法,而不修改核心代码。
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -33,14 +33,14 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
5. `bat-infrastructure` 已改为 CAS 仓储适配层,不再重复实现对象存储。
|
5. `bat-infrastructure` 已改为 CAS 仓储适配层,不再重复实现对象存储。
|
||||||
6. `bat-infrastructure` 已提供官方资源 pull/update 服务,正式入口是 Rust binary `bat`。
|
6. `bat-infrastructure` 已提供官方资源 pull/update 服务,正式入口是 Rust binary `bat`。
|
||||||
7. `bat` 支持 `--auto-discover`、`--watch`、`--daemon`、默认 1 小时间隔、本地 manifest audit/repair、官方 seed `.hash` 校验、snapshot/cache,以及基于 Unix socket JSON-RPC 的 `status/stop/restart/reload/refresh/logs/verify/repair/doctor/clean-stable` 运维命令。
|
7. `bat` 支持 `--auto-discover`、`--watch`、`--daemon`、默认 1 小时间隔、本地 manifest audit/repair、官方 seed `.hash` 校验、snapshot/cache,以及基于 Unix socket JSON-RPC 的 `status/stop/restart/reload/refresh/logs/verify/repair/doctor/clean-stable` 运维命令。
|
||||||
8. `bat-ffi` 已提供 Manifest inspect 和官方 sync plan 的粗粒度 JSON API。
|
8. `bat-ffi` 已提供 Manifest inspect 和官方 sync plan 的可选无状态粗粒度 JSON C ABI helper。
|
||||||
9. 文档已整理:根目录保留入口文档,历史报告进入 `docs/reports/historical/`,误嵌套的 `docs/docs` 已合并。
|
9. 文档已整理:根目录保留入口文档,历史报告进入 `docs/reports/historical/`,误嵌套的 `docs/docs` 已合并。
|
||||||
|
|
||||||
### 仍是骨架或占位
|
### 仍是骨架或占位
|
||||||
|
|
||||||
1. AssetBundle 解析器仍是占位 trait,未解析 UnityFS、压缩块、TypeTree 或对象表。
|
1. AssetBundle 解析器仍是占位 trait,未解析 UnityFS、压缩块、TypeTree 或对象表。
|
||||||
2. Patch 的 Binary/JSON 模块仍返回空结果,不具备真实补丁能力。
|
2. Patch 的 Binary/JSON 模块仍返回空结果,不具备真实补丁能力。
|
||||||
3. Go CLI/API/SDK 仍没有产品级入口;只有 `internal/ffi` 的早期包装。
|
3. Go CLI/API/SDK 仍没有产品级入口;只有 `internal/ffi` 的可选兼容包装骨架。
|
||||||
4. Addressables parser 已覆盖当前真实形态 fixture/golden,但还不是完整 Unity Addressables/SBP catalog 兼容层。
|
4. Addressables parser 已覆盖当前真实形态 fixture/golden,但还不是完整 Unity Addressables/SBP catalog 兼容层。
|
||||||
5. 官方同步结果尚未作为用户级流程自动导入 CAS + ResourceRepository。
|
5. 官方同步结果尚未作为用户级流程自动导入 CAS + ResourceRepository。
|
||||||
6. 真实官方网络全量下载 smoke test 尚未记录。
|
6. 真实官方网络全量下载 smoke test 尚未记录。
|
||||||
@@ -66,11 +66,11 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
2. **Engine**:Rust 实现性能敏感和安全敏感能力,包括 CAS、AssetBundle、Patch、二进制格式校验。
|
2. **Engine**:Rust 实现性能敏感和安全敏感能力,包括 CAS、AssetBundle、Patch、二进制格式校验。
|
||||||
3. **Infrastructure**:实现数据库、文件系统、缓存、对象存储、HTTP 客户端、任务队列。
|
3. **Infrastructure**:实现数据库、文件系统、缓存、对象存储、HTTP 客户端、任务队列。
|
||||||
4. **Application**:编排用例,例如同步资源、提取文本、生成补丁、审核翻译。
|
4. **Application**:编排用例,例如同步资源、提取文本、生成补丁、审核翻译。
|
||||||
5. **Interface**:CLI、REST API、Web UI、SDK、FFI。
|
5. **Interface**:CLI、REST API、Web UI、SDK,以及可选 FFI 兼容层。
|
||||||
|
|
||||||
### 3.2 技术决策
|
### 3.2 技术决策
|
||||||
|
|
||||||
1. **Rust**:保留为核心引擎语言,用于 CAS、AssetBundle、Patch、完整资源拉取和更新检查核心逻辑,FFI 仅作为可选边界。
|
1. **Rust**:保留为核心引擎语言,用于 CAS、AssetBundle、Patch、完整资源拉取和更新检查核心逻辑;`bat --json` 进程边界是当前主集成路径,FFI 仅作为可选兼容层。
|
||||||
2. **Go**:用于最小稳定 CLI、服务编排、API Server、任务编排、Provider 集成;不强制要求 Rust 核心能力必须写成库供 Go 调用。
|
2. **Go**:用于最小稳定 CLI、服务编排、API Server、任务编排、Provider 集成;不强制要求 Rust 核心能力必须写成库供 Go 调用。
|
||||||
3. **PostgreSQL**:作为服务端主数据库,承载翻译记忆库、术语库、任务、审核和用户权限。
|
3. **PostgreSQL**:作为服务端主数据库,承载翻译记忆库、术语库、任务、审核和用户权限。
|
||||||
4. **SQLite**:仅作为本地 CLI 可选元数据后端,必须通过仓储抽象隔离,不能绑定业务逻辑。
|
4. **SQLite**:仅作为本地 CLI 可选元数据后端,必须通过仓储抽象隔离,不能绑定业务逻辑。
|
||||||
@@ -141,7 +141,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
|
|
||||||
**目标**:完成可长期使用的 Content Addressable Storage。
|
**目标**:完成可长期使用的 Content Addressable Storage。
|
||||||
|
|
||||||
**当前状态**:已完成 CAS V1。Go CLI 以最小稳定入口优先,Rust 继续承载完整资源拉取与更新检查核心逻辑;FFI 边界保持可选。
|
**当前状态**:已完成 CAS V1。Go CLI 以最小稳定入口优先,Rust 继续承载完整资源拉取与更新检查核心逻辑;`bat-ffi` 仅保留为可选兼容层。
|
||||||
|
|
||||||
交付物:
|
交付物:
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
3. 实现引用计数、对象元数据、完整性校验、GC、统计信息。
|
3. 实现引用计数、对象元数据、完整性校验、GC、统计信息。
|
||||||
4. 实现本地元数据后端:优先 SQLite,但必须隔离在 repository adapter 中。
|
4. 实现本地元数据后端:优先 SQLite,但必须隔离在 repository adapter 中。
|
||||||
5. 编写迁移、恢复、损坏检测和 `doctor cas`。
|
5. 编写迁移、恢复、损坏检测和 `doctor cas`。
|
||||||
6. 提供稳定的 Go 调用边界,优先进程或 SDK,必要时再补 FFI。
|
6. 提供稳定的 Go 调用边界,优先进程或 SDK;FFI 只保留为可选兼容层,不作为默认集成方案。
|
||||||
|
|
||||||
验收标准:
|
验收标准:
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
3. Rust 官方下载器:**已完成当前生产入口需要的核心能力**。包含官方 URL 校验、`.part` 续传、重试、本地 manifest size+BLAKE3 校验、官方 seed `.hash` 校验和 repair。
|
3. Rust 官方下载器:**已完成当前生产入口需要的核心能力**。包含官方 URL 校验、`.part` 续传、重试、本地 manifest size+BLAKE3 校验、官方 seed `.hash` 校验和 repair。
|
||||||
4. Rust 自动更新入口:**已完成当前生产入口**。`bat` 支持 snapshot、marker diff、bootstrap cache、one-shot、`--watch`、`--daemon`、默认 1 小时间隔、北京时间固定强制刷新,以及 Unix socket JSON-RPC 后台运维命令返回。
|
4. Rust 自动更新入口:**已完成当前生产入口**。`bat` 支持 snapshot、marker diff、bootstrap cache、one-shot、`--watch`、`--daemon`、默认 1 小时间隔、北京时间固定强制刷新,以及 Unix socket JSON-RPC 后台运维命令返回。
|
||||||
5. Go CLI:**未完成**。需要实现 `bat doctor`、`bat sync --help`、Rust 官方同步命令包装和 JSON/human 输出。
|
5. Go CLI:**未完成**。需要实现 `bat doctor`、`bat sync --help`、Rust 官方同步命令包装和 JSON/human 输出。
|
||||||
6. 用户级 `sync`、`manifest inspect`、`cache status`:**未完成**。Rust FFI 已提供 Manifest inspect 和 sync plan JSON 边界,但 Go CLI 尚未串联。
|
6. 用户级 `sync`、`manifest inspect`、`cache status`:**未完成**。Rust `bat --json` 是 Go CLI 默认进程边界;`bat-ffi` 只提供可选兼容用的 Manifest inspect 和 sync plan JSON helper。
|
||||||
7. 下载结果写入 CAS + ResourceRepository:**部分完成**。CAS 和 SQLite ResourceRepository 已存在,官方同步入口尚未把完整下载结果作为用户级流程自动导入。
|
7. 下载结果写入 CAS + ResourceRepository:**部分完成**。CAS 和 SQLite ResourceRepository 已存在,官方同步入口尚未把完整下载结果作为用户级流程自动导入。
|
||||||
8. Linux 生产同步不依赖已安装官方启动器:**已完成当前 Rust 入口**。`--auto-discover` 只使用官方 HTTP metadata 和临时目录解析 `GameMainConfig`。
|
8. Linux 生产同步不依赖已安装官方启动器:**已完成当前 Rust 入口**。`--auto-discover` 只使用官方 HTTP metadata 和临时目录解析 `GameMainConfig`。
|
||||||
9. 真实官方网络全量下载 smoke test:**未完成记录**。需要在隔离目录执行并记录 dry-run、首次下载、二次 up-to-date 和本地损坏 repair。
|
9. 真实官方网络全量下载 smoke test:**未完成记录**。需要在隔离目录执行并记录 dry-run、首次下载、二次 up-to-date 和本地损坏 repair。
|
||||||
@@ -381,7 +381,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
## 6. 近期 10 个具体任务
|
## 6. 近期 10 个具体任务
|
||||||
|
|
||||||
1. 落地 Go CLI 的最小生产入口:`bat doctor`、`bat sync --help`、`bat official sync --help`。
|
1. 落地 Go CLI 的最小生产入口:`bat doctor`、`bat sync --help`、`bat official sync --help`。
|
||||||
2. 让 Go CLI 能调用 Rust `bat --json` 官方同步入口或 FFI/进程边界,并稳定转发结构化 report。
|
2. 让 Go CLI 默认调用 Rust `bat --json` 官方同步入口,并稳定转发结构化 report;除非有明确兼容需求,不走 FFI。
|
||||||
3. 记录一次真实官方网络 smoke:dry-run、首次下载、二次 up-to-date、本地损坏 repair。
|
3. 记录一次真实官方网络 smoke:dry-run、首次下载、二次 up-to-date、本地损坏 repair。
|
||||||
4. 将官方同步下载结果接入 CAS + `SqliteResourceRepository` 的用户级流程。
|
4. 将官方同步下载结果接入 CAS + `SqliteResourceRepository` 的用户级流程。
|
||||||
5. 继续扩展 Addressables parser 的真实 catalog 变体覆盖和错误诊断。
|
5. 继续扩展 Addressables parser 的真实 catalog 变体覆盖和错误诊断。
|
||||||
@@ -416,7 +416,7 @@ BlueArchiveToolkit 不是一次性脚本,也不是演示项目。最终交付
|
|||||||
|
|
||||||
1. Rust 提供稳定引擎能力,不承担 CLI 编排,但负责完整资源拉取和更新检查的核心逻辑。
|
1. Rust 提供稳定引擎能力,不承担 CLI 编排,但负责完整资源拉取和更新检查的核心逻辑。
|
||||||
2. Go 负责用户命令、最小稳定 CLI、服务编排、网络和 Provider。
|
2. Go 负责用户命令、最小稳定 CLI、服务编排、网络和 Provider。
|
||||||
3. 跨边界优先进程或 SDK,FFI 只作为可选的粗粒度、安全、可测试 API。
|
3. 跨边界优先进程或 SDK,FFI 只作为可选的粗粒度、无状态、安全、可测试兼容 API。
|
||||||
4. Rust 不需要被强制写成 Go 调用库;当前 `bat --watch` / `bat --daemon` 是允许长期运行的 Rust 生产任务。
|
4. Rust 不需要被强制写成 Go 调用库;当前 `bat --watch` / `bat --daemon` 是允许长期运行的 Rust 生产任务。
|
||||||
|
|
||||||
### 官方资源真实下载风险
|
### 官方资源真实下载风险
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
- `bat`:官方资源自动发现、全量拉取、原子发布到 `current -> versions/<id>`、本地 manifest audit/repair、`.part` 断点续传、403/404/5xx 分类重试、下载 quarantine 诊断、ZIP 结构校验、官方 seed `.hash` 校验、snapshot/cache、`--watch` 常驻更新、`--daemon` 后台运行,以及 Unix socket JSON-RPC 后台控制命令 `status/stop/restart/reload/refresh/logs/verify/repair/doctor/clean-stable`。
|
- `bat`:官方资源自动发现、全量拉取、原子发布到 `current -> versions/<id>`、本地 manifest audit/repair、`.part` 断点续传、403/404/5xx 分类重试、下载 quarantine 诊断、ZIP 结构校验、官方 seed `.hash` 校验、snapshot/cache、`--watch` 常驻更新、`--daemon` 后台运行,以及 Unix socket JSON-RPC 后台控制命令 `status/stop/restart/reload/refresh/logs/verify/repair/doctor/clean-stable`。
|
||||||
- 官方同步会维护 `<output>/official-version-state.json`,明确记录当前已完成版本、正在拉取版本、上一个可用版本和失败版本。
|
- 官方同步会维护 `<output>/official-version-state.json`,明确记录当前已完成版本、正在拉取版本、上一个可用版本和失败版本。
|
||||||
- 资源导入链路可将 manifest 条目写入 CAS + `ResourceRepository`,AssetBundle 会记录 UnityFS 摘要,TextAsset/Table/Media 会按类型分类索引。
|
- 资源导入链路可将 manifest 条目写入 CAS + `ResourceRepository`,AssetBundle 会记录 UnityFS 摘要,TextAsset/Table/Media 会按类型分类索引。
|
||||||
- `bat-ffi` 粗粒度 JSON 接口:Manifest inspect 和官方 sync plan。
|
- `bat-ffi` 可选无状态 C ABI 兼容层:仅保留 Manifest inspect 和官方 sync plan 的粗粒度 JSON helper,不作为 Go CLI 或生产同步的主集成边界。
|
||||||
- 文档路线图、当前状态、缺口清单、官方资源运行指南。
|
- 文档路线图、当前状态、缺口清单、官方资源运行指南。
|
||||||
|
|
||||||
仍未完成:
|
仍未完成:
|
||||||
@@ -134,8 +134,9 @@ make official-smoke
|
|||||||
|
|
||||||
## 技术栈
|
## 技术栈
|
||||||
|
|
||||||
- Rust:CAS、官方资源同步核心、AssetBundle/Patch 引擎、FFI。
|
- Rust:CAS、官方资源同步核心、AssetBundle/Patch 引擎;当前生产同步入口是 `bat` binary。
|
||||||
- Go:计划中的最小 CLI、服务编排、API Server、SDK;当前仅有 FFI 包骨架。
|
- Go:计划中的最小 CLI、服务编排、API Server、SDK;默认通过 `bat --json` 进程边界或未来 SDK 集成 Rust 能力。
|
||||||
|
- `bat-ffi`:可选兼容层,只暴露无状态粗粒度 JSON C ABI,不承载 daemon、下载器、CAS handle 或主控制面。
|
||||||
- PostgreSQL:计划中的服务端主数据库。
|
- PostgreSQL:计划中的服务端主数据库。
|
||||||
- Redis:计划中的缓存、队列状态、限流和短期锁。
|
- Redis:计划中的缓存、队列状态、限流和短期锁。
|
||||||
- Vue 3 + TypeScript:计划中的 Web 管理后台。
|
- Vue 3 + TypeScript:计划中的 Web 管理后台。
|
||||||
@@ -154,8 +155,8 @@ BlueArchiveToolkit/
|
|||||||
│ ├── bat-cas-engine/
|
│ ├── bat-cas-engine/
|
||||||
│ ├── bat-assetbundle/
|
│ ├── bat-assetbundle/
|
||||||
│ ├── bat-patch/
|
│ ├── bat-patch/
|
||||||
│ └── bat-ffi/
|
│ └── bat-ffi/ # 可选无状态 C ABI 兼容层
|
||||||
├── internal/ffi/ # Go 调用 Rust FFI 的早期包装
|
├── internal/ffi/ # 可选 CGO 兼容包装,不是 Go CLI 主路径
|
||||||
├── cmd/ # Go CLI 入口,尚未实现
|
├── cmd/ # Go CLI 入口,尚未实现
|
||||||
├── pkg/ # Go SDK 包,尚未实现
|
├── pkg/ # Go SDK 包,尚未实现
|
||||||
├── api/ # API 定义,尚未实现
|
├── api/ # API 定义,尚未实现
|
||||||
@@ -173,7 +174,7 @@ BlueArchiveToolkit/
|
|||||||
|
|
||||||
近期优先级:
|
近期优先级:
|
||||||
|
|
||||||
1. 落地 Go CLI 最小可用入口:`bat doctor`、`bat sync --help`、Rust 同步命令包装。
|
1. 落地 Go CLI 最小可用入口:`bat doctor`、`bat sync --help`、通过 `bat --json` 包装 Rust 同步命令。
|
||||||
2. 补齐 AssetBundle UnityFS header/block/directory 解析。
|
2. 补齐 AssetBundle UnityFS header/block/directory 解析。
|
||||||
3. 扩展 Addressables catalog 解析覆盖,继续用真实形态 fixture/golden 锁定行为。
|
3. 扩展 Addressables catalog 解析覆盖,继续用真实形态 fixture/golden 锁定行为。
|
||||||
4. 将官方同步结果接入 CAS + ResourceRepository 的用户级工作流。
|
4. 将官方同步结果接入 CAS + ResourceRepository 的用户级工作流。
|
||||||
|
|||||||
@@ -9,20 +9,9 @@ license.workspace = true
|
|||||||
crate-type = ["cdylib", "staticlib"]
|
crate-type = ["cdylib", "staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bat-core = { path = "../../core" }
|
|
||||||
bat-adapters = { path = "../../adapters" }
|
bat-adapters = { path = "../../adapters" }
|
||||||
bat-infrastructure = { path = "../../infrastructure" }
|
bat-infrastructure = { path = "../../infrastructure" }
|
||||||
bat-cas-engine = { path = "../bat-cas-engine" }
|
|
||||||
bat-assetbundle = { path = "../bat-assetbundle" }
|
|
||||||
bat-patch = { path = "../bat-patch" }
|
|
||||||
|
|
||||||
anyhow.workspace = true
|
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
||||||
# FFI 绑定
|
|
||||||
libc = "0.2"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cbindgen = "0.27"
|
|
||||||
|
|||||||
+118
-40
@@ -1,8 +1,9 @@
|
|||||||
//! # BAT FFI
|
//! # BAT FFI compatibility layer
|
||||||
//!
|
//!
|
||||||
//! Go 和 Rust 之间的 FFI 绑定层
|
//! Optional C ABI compatibility layer for coarse-grained JSON helpers.
|
||||||
//!
|
//! Production orchestration should prefer the `bat --json` process boundary or a
|
||||||
//! 导出 C ABI 接口供 Go 通过 CGO 调用
|
//! future stable SDK. This crate intentionally stays stateless: it must not own
|
||||||
|
//! downloader state, daemon lifecycle, CAS handles, or long-lived resources.
|
||||||
|
|
||||||
#![warn(clippy::all)]
|
#![warn(clippy::all)]
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ use std::collections::HashMap;
|
|||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
/// FFI 版本号
|
/// FFI compatibility API version.
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
/// Sync snapshot JSON 输入。
|
/// Sync snapshot JSON 输入。
|
||||||
@@ -111,13 +112,13 @@ struct SyncPlanView {
|
|||||||
delta: SyncDeltaView,
|
delta: SyncDeltaView,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取版本号(C ABI)
|
/// Returns the compatibility API version as an owned C string.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn bat_version() -> *const c_char {
|
pub extern "C" fn bat_version() -> *const c_char {
|
||||||
c_string(VERSION).into_raw()
|
c_string(VERSION).into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 释放 C 字符串内存
|
/// Frees C strings allocated by this crate.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// 调用者必须确保:
|
/// 调用者必须确保:
|
||||||
@@ -130,7 +131,7 @@ pub unsafe extern "C" fn bat_free_string(s: *mut c_char) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解析 Addressables Manifest,并返回 JSON summary。
|
/// Parses an Addressables manifest and returns a stateless JSON summary.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn bat_manifest_inspect_json(raw_json: *const c_char) -> *mut c_char {
|
pub extern "C" fn bat_manifest_inspect_json(raw_json: *const c_char) -> *mut c_char {
|
||||||
let result = (|| -> Result<ManifestInspectView, String> {
|
let result = (|| -> Result<ManifestInspectView, String> {
|
||||||
@@ -170,7 +171,7 @@ pub extern "C" fn bat_manifest_inspect_json(raw_json: *const c_char) -> *mut c_c
|
|||||||
json_result(result)
|
json_result(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 构建官方同步计划 JSON summary。
|
/// Builds an official sync plan JSON summary without persisting state.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn bat_sync_plan_json(
|
pub extern "C" fn bat_sync_plan_json(
|
||||||
current_json: *const c_char,
|
current_json: *const c_char,
|
||||||
@@ -368,16 +369,31 @@ mod tests {
|
|||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn parse_json_response(raw: String) -> serde_json::Value {
|
||||||
fn test_ffi_version() {
|
serde_json::from_str(&raw).unwrap()
|
||||||
let version_ptr = bat_version();
|
|
||||||
let version = take_string(version_ptr);
|
|
||||||
assert!(!version.is_empty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn inspect_manifest(raw_json: &str) -> serde_json::Value {
|
||||||
fn test_manifest_inspect_json() {
|
let raw_json = CString::new(raw_json).unwrap();
|
||||||
let catalog_json = r#"{
|
parse_json_response(take_string(bat_manifest_inspect_json(raw_json.as_ptr())))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sync_plan(current_json: &str, previous_json: Option<&str>) -> serde_json::Value {
|
||||||
|
let current_json = CString::new(current_json).unwrap();
|
||||||
|
let previous_json = previous_json.map(|value| CString::new(value).unwrap());
|
||||||
|
let previous_ptr = previous_json
|
||||||
|
.as_ref()
|
||||||
|
.map(|value| value.as_ptr())
|
||||||
|
.unwrap_or(std::ptr::null());
|
||||||
|
|
||||||
|
parse_json_response(take_string(bat_sync_plan_json(
|
||||||
|
current_json.as_ptr(),
|
||||||
|
previous_ptr,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn catalog_json() -> &'static str {
|
||||||
|
r#"{
|
||||||
"m_LocatorId": "AddressablesMainContentCatalog",
|
"m_LocatorId": "AddressablesMainContentCatalog",
|
||||||
"m_InternalIds": [
|
"m_InternalIds": [
|
||||||
"synthetic/minimal.bundle"
|
"synthetic/minimal.bundle"
|
||||||
@@ -391,34 +407,96 @@ mod tests {
|
|||||||
"dependencies": ["shared.bundle"]
|
"dependencies": ["shared.bundle"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}"#;
|
}"#
|
||||||
|
}
|
||||||
|
|
||||||
let result_ptr = bat_manifest_inspect_json(CString::new(catalog_json).unwrap().as_ptr());
|
fn sync_snapshot_json(bundle_version: &str) -> String {
|
||||||
let result = take_string(result_ptr);
|
format!(
|
||||||
assert!(result.contains(r#""ok":true"#));
|
r#"{{
|
||||||
assert!(result.contains(r#""resource_count":1"#));
|
"connection_group_name":"Prod-Audit",
|
||||||
|
"app_version":"1.70.0",
|
||||||
|
"bundle_version":"{bundle_version}",
|
||||||
|
"addressables_root":"https://prod-clientpatch.bluearchiveyostar.com/r93_token",
|
||||||
|
"endpoints":[
|
||||||
|
{{
|
||||||
|
"kind":"TableCatalog",
|
||||||
|
"platform":null,
|
||||||
|
"url":"https://prod-clientpatch.bluearchiveyostar.com/r93_token/TableBundles/TableCatalog.bytes"
|
||||||
|
}}
|
||||||
|
]
|
||||||
|
}}"#
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ffi_version() {
|
||||||
|
let version_ptr = bat_version();
|
||||||
|
let version = take_string(version_ptr);
|
||||||
|
assert!(!version.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_manifest_inspect_json() {
|
||||||
|
let result = inspect_manifest(catalog_json());
|
||||||
|
assert_eq!(result["ok"], true);
|
||||||
|
assert_eq!(result["data"]["resource_count"], 1);
|
||||||
|
assert_eq!(
|
||||||
|
result["data"]["resources"][0]["path"],
|
||||||
|
"synthetic/minimal.bundle"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sync_plan_json() {
|
fn test_sync_plan_json() {
|
||||||
let current = r#"{
|
let current = sync_snapshot_json("s8tloc7lo3");
|
||||||
"connection_group_name":"Prod-Audit",
|
let result = sync_plan(¤t, None);
|
||||||
"app_version":"1.70.0",
|
assert_eq!(result["ok"], true);
|
||||||
"bundle_version":"s8tloc7lo3",
|
assert_eq!(result["data"]["decision"], "DownloadVerifyAndPublish");
|
||||||
"addressables_root":"https://prod-clientpatch.bluearchiveyostar.com/r93_token",
|
assert_eq!(result["data"]["should_download"], true);
|
||||||
"endpoints":[
|
assert_eq!(result["data"]["should_publish"], true);
|
||||||
{
|
}
|
||||||
"kind":"TableCatalog",
|
|
||||||
"platform":null,
|
|
||||||
"url":"https://prod-clientpatch.bluearchiveyostar.com/r93_token/TableBundles/TableCatalog.bytes"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}"#;
|
|
||||||
|
|
||||||
let result_ptr =
|
#[test]
|
||||||
bat_sync_plan_json(CString::new(current).unwrap().as_ptr(), std::ptr::null());
|
fn stateless_ffi_json_api_repeats_without_cached_state() {
|
||||||
let result = take_string(result_ptr);
|
let first_manifest = inspect_manifest(catalog_json());
|
||||||
assert!(result.contains(r#""ok":true"#));
|
let second_manifest = inspect_manifest(catalog_json());
|
||||||
assert!(result.contains(r#""decision":"DownloadVerifyAndPublish""#));
|
assert_eq!(first_manifest, second_manifest);
|
||||||
|
|
||||||
|
let current = sync_snapshot_json("s8tloc7lo3");
|
||||||
|
let initial_plan = sync_plan(¤t, None);
|
||||||
|
let up_to_date_plan = sync_plan(¤t, Some(¤t));
|
||||||
|
let initial_plan_again = sync_plan(¤t, None);
|
||||||
|
|
||||||
|
assert_eq!(initial_plan["data"]["decision"], "DownloadVerifyAndPublish");
|
||||||
|
assert_eq!(up_to_date_plan["data"]["decision"], "UpToDate");
|
||||||
|
assert_eq!(
|
||||||
|
initial_plan_again["data"]["decision"],
|
||||||
|
initial_plan["data"]["decision"]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
initial_plan_again["data"]["should_download"],
|
||||||
|
initial_plan["data"]["should_download"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ffi_json_api_returns_structured_errors() {
|
||||||
|
let manifest_error =
|
||||||
|
parse_json_response(take_string(bat_manifest_inspect_json(std::ptr::null())));
|
||||||
|
assert_eq!(manifest_error["ok"], false);
|
||||||
|
assert!(manifest_error["error"]
|
||||||
|
.as_str()
|
||||||
|
.unwrap()
|
||||||
|
.contains("null pointer"));
|
||||||
|
|
||||||
|
let sync_error = parse_json_response(take_string(bat_sync_plan_json(
|
||||||
|
std::ptr::null(),
|
||||||
|
std::ptr::null(),
|
||||||
|
)));
|
||||||
|
assert_eq!(sync_error["ok"], false);
|
||||||
|
assert!(sync_error["error"]
|
||||||
|
.as_str()
|
||||||
|
.unwrap()
|
||||||
|
.contains("null pointer"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ BlueArchive Toolkit 采用 **Monorepo + 多语言混合** 架构,旨在构建
|
|||||||
### 3. 数据流设计
|
### 3. 数据流设计
|
||||||
|
|
||||||
```
|
```
|
||||||
用户请求 → CLI/API → Go 业务层 → Rust 核心/同步层 → CAS 存储 → 数据库
|
用户请求 → CLI/API → Go 业务层 → bat --json / SDK → Rust 核心/同步层 → CAS 存储 → 数据库
|
||||||
↓ ↓
|
↓ ↓
|
||||||
Web UI 缓存层 (Redis)
|
Web UI 缓存层 (Redis)
|
||||||
```
|
```
|
||||||
@@ -128,7 +128,8 @@ current symlink → official-sync-snapshot.json + official-download-manifest.jso
|
|||||||
**后续 Go 职责**:
|
**后续 Go 职责**:
|
||||||
|
|
||||||
- 提供最小稳定 CLI。
|
- 提供最小稳定 CLI。
|
||||||
- 包装或调用 Rust 同步入口,需要机器输出时使用 `--json` 并转发结构化 report。
|
- 默认通过 `bat --json` 进程边界包装 Rust 同步入口,并转发结构化 report。
|
||||||
|
- `bat-ffi` 仅作为可选无状态 C ABI 兼容层,不承载官方同步 daemon、下载器或 CAS handle。
|
||||||
- 编排 API Server、任务队列、Provider 和用户配置。
|
- 编排 API Server、任务队列、Provider 和用户配置。
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -320,7 +321,8 @@ CREATE TABLE resource_versions (
|
|||||||
```
|
```
|
||||||
开发机器 (本地)
|
开发机器 (本地)
|
||||||
├── CLI (Go)
|
├── CLI (Go)
|
||||||
├── Rust 库
|
├── Rust bat 进程 / 未来 SDK
|
||||||
|
├── 可选 bat-ffi 兼容层
|
||||||
└── 连接 → 远程数据库服务器 (裸金属)
|
└── 连接 → 远程数据库服务器 (裸金属)
|
||||||
├── PostgreSQL
|
├── PostgreSQL
|
||||||
└── Redis
|
└── Redis
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ BlueArchiveToolkit 的最终目标覆盖资源同步、CAS、AssetBundle 解析
|
|||||||
|
|
||||||
3. **Go 应用层**
|
3. **Go 应用层**
|
||||||
- 负责 CLI、资源同步、下载器、API Server、任务调度、配置、日志、Provider 编排。
|
- 负责 CLI、资源同步、下载器、API Server、任务调度、配置、日志、Provider 编排。
|
||||||
- 通过稳定 SDK、进程边界,必要时再通过 FFI 调用 Rust 引擎能力。
|
- 通过稳定 SDK 或进程边界调用 Rust 能力;FFI 只作为可选兼容层。
|
||||||
- 不重复实现 AssetBundle 解析、Patch 算法或 CAS 对象存储核心逻辑。
|
- 不重复实现 AssetBundle 解析、Patch 算法或 CAS 对象存储核心逻辑。
|
||||||
|
|
||||||
4. **Web 层**
|
4. **Web 层**
|
||||||
@@ -48,7 +48,7 @@ BlueArchiveToolkit 的最终目标覆盖资源同步、CAS、AssetBundle 解析
|
|||||||
|
|
||||||
1. Rust 引擎 API 必须保持业务无关,不出现 CLI 命令、HTTP 状态码、Web 页面状态。
|
1. Rust 引擎 API 必须保持业务无关,不出现 CLI 命令、HTTP 状态码、Web 页面状态。
|
||||||
2. Go 应用层不得复制 Rust 引擎中的 Hash、Patch、AssetBundle 核心算法。
|
2. Go 应用层不得复制 Rust 引擎中的 Hash、Patch、AssetBundle 核心算法。
|
||||||
3. 跨边界优先级应是进程边界或稳定 SDK,其次才是 FFI;若使用 FFI,必须只暴露粗粒度批量和事务语义。
|
3. 跨边界优先级应是进程边界或稳定 SDK,其次才是 FFI;若使用 FFI,必须只暴露粗粒度、无状态、一次调用一次输入输出的兼容 API。
|
||||||
4. 所有跨边界错误必须能映射到统一错误码和可读诊断信息。
|
4. 所有跨边界错误必须能映射到统一错误码和可读诊断信息。
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -63,7 +63,7 @@ BlueArchiveToolkit 的最终目标覆盖资源同步、CAS、AssetBundle 解析
|
|||||||
|
|
||||||
代价:
|
代价:
|
||||||
|
|
||||||
1. 需要维护 FFI 或 SDK 边界。
|
1. 需要维护进程、SDK 和可选 FFI 兼容边界。
|
||||||
2. 错误类型、数据结构和版本兼容性需要更早设计。
|
2. 错误类型、数据结构和版本兼容性需要更早设计。
|
||||||
3. 集成测试必须覆盖跨语言调用,而不能只看单 crate 单元测试。
|
3. 集成测试必须覆盖跨语言调用,而不能只看单 crate 单元测试。
|
||||||
|
|
||||||
@@ -75,4 +75,5 @@ BlueArchiveToolkit 的最终目标覆盖资源同步、CAS、AssetBundle 解析
|
|||||||
|
|
||||||
1. `crates/bat-cas-engine` 是 CAS 核心实现位置。
|
1. `crates/bat-cas-engine` 是 CAS 核心实现位置。
|
||||||
2. `infrastructure` 不再复制 CAS 存储算法,只做 `bat-core::repositories::CasRepository` 适配。
|
2. `infrastructure` 不再复制 CAS 存储算法,只做 `bat-core::repositories::CasRepository` 适配。
|
||||||
3. Go CLI 后续通过稳定边界调用 CAS,不直接操作 CAS 内部目录结构。
|
3. Go CLI 后续默认通过 `bat --json` 进程边界或稳定 SDK 调用 Rust 能力,不直接操作 CAS 内部目录结构。
|
||||||
|
4. `bat-ffi` 只能保持为可选无状态兼容层,不能承担 daemon lifecycle、下载器状态、资源锁或 CAS handle。
|
||||||
|
|||||||
@@ -183,6 +183,12 @@
|
|||||||
|
|
||||||
`OfficialUpdateService` 是当前 Rust 侧的自动更新核心,正式命令入口是 `bat`。
|
`OfficialUpdateService` 是当前 Rust 侧的自动更新核心,正式命令入口是 `bat`。
|
||||||
|
|
||||||
|
集成边界:
|
||||||
|
|
||||||
|
1. 当前生产和 Go CLI 默认集成路径是运行 `bat --json` 并消费结构化 report。
|
||||||
|
2. systemd、容器或上层 Go 进程只负责守护 `bat --watch` / `bat --daemon`,不直接接管下载器内部状态。
|
||||||
|
3. `bat-ffi` 只允许作为可选无状态 C ABI 兼容层,用于 Manifest inspect 和 sync plan 这类一次性 JSON helper;它不是官方同步 daemon、下载器、资源锁、CAS handle 或主控制面的承载位置。
|
||||||
|
|
||||||
流程是:
|
流程是:
|
||||||
|
|
||||||
1. 显式执行 `--auto-discover` 或读取已审计 `server-info` 输入。
|
1. 显式执行 `--auto-discover` 或读取已审计 `server-info` 输入。
|
||||||
|
|||||||
@@ -288,8 +288,9 @@ BlueArchiveToolkit/
|
|||||||
## 📚 相关文档
|
## 📚 相关文档
|
||||||
|
|
||||||
- [完整架构审查报告](./ARCHITECTURE_REVIEW.md)(1900+ 行)
|
- [完整架构审查报告](./ARCHITECTURE_REVIEW.md)(1900+ 行)
|
||||||
- [当前架构文档](./architecture/README.md)
|
- [当前架构文档](../architecture/README.md)
|
||||||
- [CLAUDE.md](../CLAUDE.md) - 项目开发指南
|
- [开发指南](../guides/development.md) - 当前开发流程
|
||||||
|
- [Agent 开发规则](../../AGENTS.md) - AI agent 长期规则
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,10 @@ chore: establish development baseline
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git status --short --branch
|
git status --short --branch
|
||||||
git check-ignore -v Cargo.lock CLAUDE.md
|
git check-ignore -v Cargo.lock CLAUDE.md AGENTS.md CONTRIBUTING.md
|
||||||
```
|
```
|
||||||
|
|
||||||
`Cargo.lock` 和 `CLAUDE.md` 必须纳入版本控制。
|
`Cargo.lock`、`CLAUDE.md`、`AGENTS.md` 和 `CONTRIBUTING.md` 必须纳入版本控制。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# 开发指南
|
# 开发指南
|
||||||
|
|
||||||
|
本指南是本地开发流程的权威入口。贡献协作规则见 `../../CONTRIBUTING.md`,AI agent 长期规则见 `../../AGENTS.md`。
|
||||||
|
|
||||||
## 环境准备
|
## 环境准备
|
||||||
|
|
||||||
### 安装依赖
|
### 安装依赖
|
||||||
@@ -59,6 +61,14 @@ make test
|
|||||||
make fmt
|
make fmt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
开发约束:
|
||||||
|
|
||||||
|
1. 先阅读相关文档和代码,再判断实现方式。
|
||||||
|
2. 跨模块、架构、数据格式或用户工作流变更必须先说明设计取舍。
|
||||||
|
3. 保持改动聚焦,不做无关重构、批量格式化或元数据 churn。
|
||||||
|
4. 公共接口、状态文件、manifest、catalog、patch 和下载流程变更必须补充测试或 fixture。
|
||||||
|
5. 用户可见命令、运行路径、配置、状态文件、日志或缺口状态变化时,同步更新 README、指南、架构文档或 `docs/reports/CURRENT_GAPS.md`。
|
||||||
|
|
||||||
### 3. 提交
|
### 3. 提交
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -86,6 +96,10 @@ git push origin feature/your-feature-name
|
|||||||
|
|
||||||
## 代码规范
|
## 代码规范
|
||||||
|
|
||||||
|
默认使用简体中文写文档、提交说明、开发日志和面向用户的说明。代码标识符、协议字段、数据库字段、包名和命令参数保持英文命名规范。
|
||||||
|
|
||||||
|
禁止使用 demo、临时实现、硬编码路径或只为当前测试通过的伪实现。确实未完成的能力应写入当前缺口文档,而不是用 `TODO` 或 `FIXME` 隐藏。
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
- 遵循 [Effective Go](https://golang.org/doc/effective_go)
|
- 遵循 [Effective Go](https://golang.org/doc/effective_go)
|
||||||
- 使用 `gofmt` 格式化
|
- 使用 `gofmt` 格式化
|
||||||
@@ -104,16 +118,30 @@ git push origin feature/your-feature-name
|
|||||||
|
|
||||||
## 测试
|
## 测试
|
||||||
|
|
||||||
### 当前必跑测试
|
### 合并前通用门禁
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
cargo fmt --check
|
||||||
|
cargo test --workspace
|
||||||
|
cargo clippy --workspace --all-targets -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
Go CLI 尚未实现时,`go test ./...` 可能没有产品级 package 可运行;Makefile 会在空 Go 阶段清晰跳过。
|
||||||
|
|
||||||
|
### 常用聚焦命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test -p bat-core -- --nocapture
|
||||||
cargo test -p bat-adapters -- --nocapture
|
cargo test -p bat-adapters -- --nocapture
|
||||||
cargo test -p bat-ffi -- --nocapture
|
cargo test -p bat-ffi -- --nocapture
|
||||||
cargo test -p bat-infrastructure -- --nocapture
|
cargo test -p bat-infrastructure -- --nocapture
|
||||||
cargo test -p bat-infrastructure --bin bat -- --nocapture
|
cargo test -p bat-infrastructure --bin bat -- --nocapture
|
||||||
|
cargo clippy -p bat-core -p bat-adapters -p bat-infrastructure --all-targets -- -D warnings
|
||||||
```
|
```
|
||||||
|
|
||||||
Go CLI 尚未实现时,`go test ./...` 可能没有产品级 package 可运行;Makefile 会在空 Go 阶段清晰跳过。
|
官方资源同步、下载、daemon、status、verify 或 repair 相关改动必须至少覆盖 `bat-infrastructure` 和 `bat` 二进制测试。
|
||||||
|
|
||||||
|
`bat-ffi` 只是可选无状态 C ABI 兼容层。修改 FFI 导出、JSON schema、错误返回或 `internal/ffi` CGO 包装时必须运行 `cargo test -p bat-ffi -- --nocapture`;Go CLI 和生产同步默认应通过 `bat --json` 进程边界集成。
|
||||||
|
|
||||||
### 集成测试
|
### 集成测试
|
||||||
|
|
||||||
@@ -141,6 +169,8 @@ cargo run -p bat-infrastructure --bin bat -- \
|
|||||||
|
|
||||||
开发环境真实下载默认写入 `./bat-resources`;如果要覆盖,必须使用 `/tmp` 或其他隔离目录,不要写入现有资源目录。
|
开发环境真实下载默认写入 `./bat-resources`;如果要覆盖,必须使用 `/tmp` 或其他隔离目录,不要写入现有资源目录。
|
||||||
|
|
||||||
|
生产或 CI 环境不得依赖安装官方启动器。需要启动器信息时,只能分析启动器资源、官方 manifest 或公开更新数据,并将解析结果固化为可验证流程。
|
||||||
|
|
||||||
### 基准测试
|
### 基准测试
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -180,9 +210,11 @@ cargo fetch
|
|||||||
|
|
||||||
先确认失败是否来自真实网络或本地资源路径。默认测试应使用 fixture/mock,不应依赖官方线上资源或开发机已有资源目录。
|
先确认失败是否来自真实网络或本地资源路径。默认测试应使用 fixture/mock,不应依赖官方线上资源或开发机已有资源目录。
|
||||||
|
|
||||||
### 3. FFI 绑定问题
|
### 3. FFI 兼容层问题
|
||||||
|
|
||||||
重新生成绑定:
|
`bat-ffi` 不是主集成边界,只用于需要 C ABI 的兼容场景。默认 Go CLI 集成优先运行 Rust `bat --json`。
|
||||||
|
|
||||||
|
重新构建兼容库:
|
||||||
```bash
|
```bash
|
||||||
cd crates/bat-ffi
|
cd crates/bat-ffi
|
||||||
cargo build
|
cargo build
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
现象:
|
现象:
|
||||||
|
|
||||||
- `cmd/bat` 目录存在,但无 `main.go`。
|
- `cmd/bat` 目录存在,但无 `main.go`。
|
||||||
- `internal/ffi/ffi.go` 已存在,但还不是用户可运行 CLI。
|
- `internal/ffi/ffi.go` 已存在,但只是可选 CGO 兼容包装,不是用户可运行 CLI,也不是默认 Go/Rust 集成边界。
|
||||||
- `go test ./...` 当前没有产品级 Go package 覆盖。
|
- `go test ./...` 当前没有产品级 Go package 覆盖。
|
||||||
|
|
||||||
影响:
|
影响:
|
||||||
@@ -185,6 +185,7 @@
|
|||||||
- `bat doctor` 可运行。
|
- `bat doctor` 可运行。
|
||||||
- `bat --help` 命令结构稳定。
|
- `bat --help` 命令结构稳定。
|
||||||
- 命令支持默认人类可读输出和 `--json` 机器输出。
|
- 命令支持默认人类可读输出和 `--json` 机器输出。
|
||||||
|
- Go CLI 默认通过 Rust `bat --json` 进程边界获取同步 report;除非明确兼容需求,不依赖 FFI。
|
||||||
|
|
||||||
### G-009:API Server 和 OpenAPI 尚未实现
|
### G-009:API Server 和 OpenAPI 尚未实现
|
||||||
|
|
||||||
@@ -378,6 +379,7 @@
|
|||||||
|
|
||||||
- 架构 README 已明确当前 Rust 官方同步入口、Go 计划边界和目标架构差异。
|
- 架构 README 已明确当前 Rust 官方同步入口、Go 计划边界和目标架构差异。
|
||||||
- 官方资源后端说明由 `docs/architecture/official-resource-backend.md` 承载。
|
- 官方资源后端说明由 `docs/architecture/official-resource-backend.md` 承载。
|
||||||
|
- `bat-ffi` 已降级为可选无状态兼容层,主集成边界明确为 `bat --json` 进程边界或未来稳定 SDK。
|
||||||
|
|
||||||
### G-017:CI 未落地
|
### G-017:CI 未落地
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# 历史报告归档说明
|
||||||
|
|
||||||
|
本目录只保存追溯资料,不代表当前项目状态。当前状态以根目录 `CURRENT_STATUS.md`、`PROJECT_PLAN.md`、`DOCS_INDEX.md` 和 `docs/reports/CURRENT_GAPS.md` 为准。
|
||||||
|
|
||||||
|
归档分类:
|
||||||
|
|
||||||
|
- `current-stage/`:曾用于阶段交接或推送前核查的临时 current report,已由当前状态文档和指南取代。
|
||||||
|
- `root/`:早期位于仓库根目录的阶段报告。
|
||||||
|
- `week2/`、`week3/`:早期周报、阶段报告和质量报告。
|
||||||
|
- `quality/`:早期质量状态报告。
|
||||||
|
- `build-logs/`:历史构建、测试和 Clippy 输出。
|
||||||
|
- `nested-docs/`:从误嵌套 `docs/docs` 移出的历史报告。
|
||||||
|
|
||||||
|
新增运行产物、smoke 输出、质量扫描输出和本地分析报告不要放入本目录;这些文件应写入 `/tmp`、显式的隔离输出目录,或被 `.gitignore` 覆盖的本地生成报告目录。
|
||||||
+34
-29
@@ -1,3 +1,8 @@
|
|||||||
|
// Package ffi is an optional CGO compatibility wrapper around bat-ffi.
|
||||||
|
//
|
||||||
|
// It is not the primary Go integration path. Product CLI orchestration should
|
||||||
|
// prefer the Rust bat process boundary with --json output, or a future stable
|
||||||
|
// SDK. Keep this package stateless and limited to coarse JSON helper calls.
|
||||||
package ffi
|
package ffi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -13,45 +18,45 @@ extern char* bat_sync_plan_json(const char* current_json, const char* previous_j
|
|||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Version() (string, error) {
|
func Version() (string, error) {
|
||||||
ptr := C.bat_version()
|
ptr := C.bat_version()
|
||||||
if ptr == nil {
|
if ptr == nil {
|
||||||
return "", errors.New("bat_version returned nil")
|
return "", errors.New("bat_version returned nil")
|
||||||
}
|
}
|
||||||
defer C.bat_free_string((*C.char)(unsafe.Pointer(ptr)))
|
defer C.bat_free_string((*C.char)(unsafe.Pointer(ptr)))
|
||||||
return C.GoString(ptr), nil
|
return C.GoString(ptr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InspectManifest(rawJSON string) (string, error) {
|
func InspectManifest(rawJSON string) (string, error) {
|
||||||
cRaw := C.CString(rawJSON)
|
cRaw := C.CString(rawJSON)
|
||||||
defer C.free(unsafe.Pointer(cRaw))
|
defer C.free(unsafe.Pointer(cRaw))
|
||||||
|
|
||||||
ptr := C.bat_manifest_inspect_json(cRaw)
|
ptr := C.bat_manifest_inspect_json(cRaw)
|
||||||
if ptr == nil {
|
if ptr == nil {
|
||||||
return "", errors.New("bat_manifest_inspect_json returned nil")
|
return "", errors.New("bat_manifest_inspect_json returned nil")
|
||||||
}
|
}
|
||||||
defer C.bat_free_string((*C.char)(unsafe.Pointer(ptr)))
|
defer C.bat_free_string((*C.char)(unsafe.Pointer(ptr)))
|
||||||
return C.GoString(ptr), nil
|
return C.GoString(ptr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildSyncPlan(currentJSON, previousJSON string) (string, error) {
|
func BuildSyncPlan(currentJSON, previousJSON string) (string, error) {
|
||||||
cCurrent := C.CString(currentJSON)
|
cCurrent := C.CString(currentJSON)
|
||||||
defer C.free(unsafe.Pointer(cCurrent))
|
defer C.free(unsafe.Pointer(cCurrent))
|
||||||
|
|
||||||
var cPrevious *C.char
|
var cPrevious *C.char
|
||||||
if previousJSON != "" {
|
if previousJSON != "" {
|
||||||
cPrevious = C.CString(previousJSON)
|
cPrevious = C.CString(previousJSON)
|
||||||
defer C.free(unsafe.Pointer(cPrevious))
|
defer C.free(unsafe.Pointer(cPrevious))
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr := C.bat_sync_plan_json(cCurrent, cPrevious)
|
ptr := C.bat_sync_plan_json(cCurrent, cPrevious)
|
||||||
if ptr == nil {
|
if ptr == nil {
|
||||||
return "", errors.New("bat_sync_plan_json returned nil")
|
return "", errors.New("bat_sync_plan_json returned nil")
|
||||||
}
|
}
|
||||||
defer C.bat_free_string((*C.char)(unsafe.Pointer(ptr)))
|
defer C.bat_free_string((*C.char)(unsafe.Pointer(ptr)))
|
||||||
return C.GoString(ptr), nil
|
return C.GoString(ptr), nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user