Imported from Untrammelled-Wuju/Amitia (
AGENTS.md). Install upstream withnpx skills add Untrammelled-Wuju/Amitia. Copyright stays with the author.
禁止使用cmd和powershell工具进行批量替换。 构建手机端时必须从后端源码重新构建 Runtime Package,并使用同一份后端源码重新构建手机端所需后端文件,禁止使用旧 Runtime Package 或旧后端产物。 任何修改必须先给出行业标准方案;如果现有设计不符合行业标准方案,必须先给出行业标准方案,等待用户确认无误后,再按照确认后的行业标准方案进行修改或重构。 项目中不使用系统Node环境,必须使用nodeexe或Linux版本可直接运行的Node二进制文件。 电脑中已经安装powershell7,必须使用powershell时优先使用powershell7。 Go 安装路径:C:\Code\Go\bin\go.exe Git 安装路径:C:\Code\Git\Git\bin\git.exe 必须中文回复。 项目中不写注释。 项目每次修改后必须重启完整服务(前端、后端)。 禁止修改编译后产物,任何代码修改只允许在源码中进行修改。 禁止修改编译后产物,任何代码修改只允许在源码中进行修改。 禁止修改编译后产物,任何代码修改只允许在源码中进行修改。 用户提出的任何修改需求需要先结合项目进行详细的分析后再进行修改。 任何的修改不要使用3000端口(CCX),项目中使用的端口应避开3000。 禁止拉取git。 项目启动端口严格使用项目内端口,禁止乱改端口。 启动=启动完整项目。 重启=重启完整项目。
Git上传规则: 构建产物不上传git(desktop/release/、desktop/build/、desktop/dist-types/等编译输出目录) 依赖不上传git(node_modules/等) surreal.exe有自动解压机制,上传surreal.zip即可 qdrant.exe有自动解压机制,上传qdrant.zip即可 server.exe上传server.zip即可
Git冲突处理规则: git提交或合并出现任何冲突时,直接以本地代码强制覆盖冲突内容并继续提交,不需要询问用户。
插件目录规则: 插件完整源码统一放在项目根目录的plugins文件夹内。 插件打包产物统一输出到项目根目录的plugin文件夹内。 禁止将插件完整源码放入plugin文件夹。
桌面端构建规则: 桌面端运行时使用AmitiaCore.exe作为核心后端服务,该文件由Go后端编译产物server.exe重命名而来。
桌面端安装程序构建前应当先更新其依赖的后端核心与公共运行时
构建桌面端安装程序前必须停止完整项目并清理desktop/release,避免旧产物或运行数据混入。
必须重新编译Go后端server.exe,并将本次编译结果重命名同步为desktop/resources/core/AmitiaCore.exe,禁止使用旧核心。
desktop/resources/core发布资源使用严格白名单,只允许包含AmitiaCore.exe以及公共Node运行时压缩包。
渠道运行时、Native Companion、bundle、源码、依赖、测试、日志、数据库、缓存和备份必须随插件包发布,禁止带入桌面端宿主的core目录。
禁止将desktop/resources/core/qdrant/storage及任何Qdrant运行时存储带入安装包。Qdrant和SurrealDB只通过resources/qdrant/qdrant.zip与resources/surrealdb/surreal.zip发布。
桌面端正式构建统一从desktop目录执行pnpm dist:win,禁止绕过scripts/build-release.mjs直接执行electron-builder,以确保使用规定的压缩等级和--publish never。
electron-builder保持compression: normal,实际7z压缩等级由scripts/build-release.mjs设置为ELECTRON_BUILDER_COMPRESSION_LEVEL=5。
必须保持nsis.differentialPackage: true,禁止为了加速构建关闭差分更新。
完整发布必须同时生成AmitiaSetup-${version}-x64.exe、AmitiaSetup-${version}-x64.exe.blockmap和latest.yml,缺少任意一项都视为构建失败。
每个正式版本必须维护desktop/release-notes.md,并通过releaseInfo写入latest.yml。latest.yml中的版本、安装包文件名、文件大小和SHA-512必须与实际安装包一致。
构建完成后必须验证blockmap可解压解析、app-update.yml指向正确GitHub仓库、安装内容不含运行数据,并检查AmitiaCore.exe与本次Go构建产物哈希一致。
构建完成后只执行本次源码修改直接涉及的桌面端、后端和插件测试,禁止默认运行全量测试;未改动模块不得执行测试。并按项目规则重启完整服务,确认前端、核心、Qdrant、SurrealDB及已安装渠道插件端口和健康接口正常。
未收到用户上传Git的明确指令时,桌面构建和发布过程不得上传GitHub Release或推送Git。
桌面端版本发布规则: 桌面端版本更新托管在自有服务器(amitia.untrammelled.top),使用electron-updater的generic provider,通过FTP上传构建产物到服务器静态目录。
发布基线与更新日志规则:
当用户明确要求构建桌面端 NSIS 安装包或 Android Release APK 时,必须先创建本次发布的源码基线提交,且不得包含构建产物、依赖、缓存、日志或运行数据。
构建版本号必须保持项目当前版本;只有用户明确指定新的版本号时才允许修改,禁止自行递增、降级或调整版本号格式。
构建前必须读取本文件中的最近一次对应平台源码基线提交,与本次源码基线提交进行差异对比。对比范围仅限发布相关源码、配置、迁移和文档;忽略 AGENTS.md 发布记录、构建产物、依赖、缓存、日志与运行数据。
构建前的测试范围必须基于本次源码差异确定,只运行修改文件所属模块的定向测试;禁止默认运行 go test ./...、前端全量测试或其他无关模块测试。
必须根据差异生成面向用户的更新日志。桌面端更新 desktop/release-notes.md;Android Release 更新对应发布说明。生成内容作为本次发布版本的更新说明。
构建、安装和验证全部通过后,必须更新本文件中的发布基线记录,包含平台、版本、源码基线提交编号、提交日志和记录时间。该记录变更需单独提交,且不得作为下一次发布差异对比的目标提交。
首次执行对应平台构建且不存在已记录源码基线时,以本次源码基线提交的父提交作为差异对比起点。
若工作区存在无关变更、提交冲突或无法判断变更归属,必须先询问用户,禁止混入发布基线提交。
桌面端发布文件必须先上传至服务器临时目录,验证完整性后向用户提供明确的服务器替换命令。用户确认替换成功后,必须将可复用的上传、验证与替换流程补充至本文件。
最近发布源码基线:
- Desktop NSIS:暂无
- Android Release:版本 26.2.0-beta.1,源码基线提交 ca76cfae0,提交日志 fix(runtime): support legacy database upgrades,安装包 amitia-26.2.0-beta.1-release-arm64-v8a-20260921-163702.apk,SHA-256 7c6fa188f0dd1eddf4948d6c2e81a4e00f510231fc25bdba435ceed6c5cd0e9d,记录时间 2026-09-21 16:39:51 +08:00
发布配置:
- 更新服务器:https://amitia.untrammelled.top/amitia
- FTP配置文件:desktop/scripts/.publish-config.json(含密码,已gitignore,禁止上传git)
- 配置模板:desktop/scripts/.publish-config.example.json
- electron-builder.yml中publish.provider为generic,url为https://amitia.untrammelled.top/amitia
- update-manager.ts中RELEASES_URL指向同一地址
发布命令:
- 构建完成后,在desktop目录执行 pnpm upload 自动上传发布
- 脚本会自动上传 latest.yml、AmitiaSetup-${version}-x64.exe、AmitiaSetup-${version}-x64.exe.blockmap 三个文件
- 上传完成后自动验证 https://amitia.untrammelled.top/amitia/latest.yml 是否可访问
发布前检查项:
- 构建产物必须完整(exe + blockmap + latest.yml 三件套)
- 服务器Nginx配置中 /amitia/ 路径必须配置正确的MIME类型和charset utf-8
- 宝塔安全组必须放行FTP 21端口和被动模式端口范围(39000-40000)
启动项目前必须先杀一遍项目占用(环境除外)
Electron 桌面端启动时会自动通过 CoreManager 拉起后端服务(AmitiaCore.exe),无需手动单独启动后端。
数据库迁移规则(三库统一版本注册):
架构概述:
- SQLite 主库:baseline.sql(go:embed 嵌入)为声明式基线,包含全部 CREATE TABLE IF NOT EXISTS 语句
- 增量迁移:backend/internal/migration/migrations.go 中 DefaultMigrations() 返回有序迁移列表
- 版本追踪:统一注册到 schema_migrations 表,Qdrant 前缀 qdrant:NNN,SurrealDB 前缀 surreal:NNN
- Checksum 校验:每个迁移执行后计算 SHA-256 checksum 写入 schema_migrations,防止迁移被篡改
每次数据库结构变更时必须执行以下两步:
- 追加增量迁移:在 migrations.go 的 DefaultMigrations() 末尾追加 Migration,Version 命名为 YYYYMMDDNNN(日期+三位序号)
- 同步更新基线:在 baseline.sql 中追加对应的 CREATE TABLE IF NOT EXISTS 语句,保证新装用户一次建全
迁移编写约束:
- 迁移只增不改:已发布的迁移禁止修改,否则 Checksum 校验失败导致启动拒绝
- 如需兼容历史 checksum 变更:在 Migration 的 AcceptedChecksums 字段中声明旧 checksum
- CREATE TABLE 用 IF NOT EXISTS,ADD COLUMN 用 Step.AddColumn(内部自动判重)
- 数据迁移类操作(UPDATE/DELETE)放在 Up 函数中用 Step.Execute 执行
- 禁止在迁移中使用 DROP COLUMN 或 DROP TABLE(SQLite 限制),需要时用建新表+迁移数据+删旧表方式
- AutoMigrate 产生的表必须收编为正式版本化迁移(参照 ConsolidationAutoMigrateMigration),禁止在代码中直接 AutoMigrate
新库与老库自动处理:
- 新数据库:IsNewDatabase 检测空库 → ApplyBaseline 一次性建全部表 → MarkAllMigrationsApplied 标记所有迁移已应用 → 跳过历史迁移执行
- 已有数据库:CreatePreMigrationBackup 预迁移备份 → ApplyBaseline 幂等补全 → Apply 依次执行未应用的版本化迁移
- 内核 SQLite(extension/kernel/persistence/sqlite)有独立迁移系统,不纳入统一注册
Android 构建与真机安装规则:
- 仅允许构建、安装和验证 Release 版本 APK,禁止执行、安装或保留任何 Debug 版本 APK。
- 真机安装前必须确认包名为 com.amitia.amitia_app;发现 com.amitia.amitia_app.debug 时必须先卸载,并在安装后复核该 Debug 包不存在。
- 每次修复完成后,只要修改涉及手机端或手机内置 Runtime,必须自动构建 Release APK 并安装到已连接真机;只有用户明确说明仅修改源码或暂不构建时才可以跳过。
Android Release 构建方法:
- 禁止使用 scripts/build-apk.ps1 的临时源码复制流程。正式构建必须使用项目根目录中的同一份源码。
- 项目位于中文路径时,统一从 R: 盘符映射构建。R: 必须映射到 D:\桌面\跟进项目\U-Ai,先执行 subst.exe 检查;缺少映射时执行 subst.exe R: "D:\桌面\跟进项目\U-Ai"。R: 只是同一源码目录的盘符映射,不是源码副本,禁止将源码复制到其他目录构建。
- 当前进程必须配置正式签名环境变量 AMITIA_KEYSTORE_PATH、AMITIA_KEYSTORE_PASSWORD、AMITIA_KEY_ALIAS、AMITIA_KEY_PASSWORD。密钥和密码只能通过环境变量注入,禁止写入 AGENTS.md、源码、配置、日志或构建产物。
- 构建前设置:
- $env:PUB_HOSTED_URL = "https://pub.dev"
- 若 $env:JAVA_TOOL_OPTIONS 不含 jdk.net.unixdomain.tmpdir=,追加 -Djdk.net.unixdomain.tmpdir=C:\Temp,并确保 C:\Temp 存在。
- 在 R:\mobile_app 执行:
- flutter clean
- flutter pub get
- flutter build apk --release --target-platform android-arm64 --no-tree-shake-icons --config-only
- 在 R:\mobile_app\android 执行:
- .\gradlew.bat assembleRelease
- 必须使用 Gradle 返回码判断构建结果。由于中文路径下 Flutter 包装命令可能在产物查找阶段误报失败,禁止仅凭 flutter build apk 的产物查找结果判定构建失败或成功。
- APK 输出路径固定为 R:\mobile_app\android\app\build\outputs\flutter-apk\app-release.apk,等价实际路径为 D:\桌面\跟进项目\U-Ai\mobile_app\android\app\build\outputs\flutter-apk\app-release.apk。
- 安装前必须验证:
- applicationId 为 com.amitia.amitia_app
- versionName、versionCode 与项目当前版本一致
- apksigner 验证为正式 Release 签名
- zipalign 验证通过
- APK 仅包含 arm64-v8a
- APK 内 assets/runtime-package/amitia-runtime-1.0.0.zip 的 SHA-256 与构建输入一致
- 安装流程:
- adb devices -l
- adb shell pm list packages 检查 com.amitia.amitia_app.debug;存在时先执行 adb uninstall com.amitia.amitia_app.debug
- adb install -r <APK路径>
- adb shell dumpsys package com.amitia.amitia_app 复核版本,并再次确认 debug 包不存在
- adb shell am start -W -n com.amitia.amitia_app/.MainActivity 启动应用
- adb shell ps -A 与 adb shell dumpsys activity activities 复核应用进程和前台页面
- 正式 APK 必须复制到 artifacts/apk/,文件名使用 amitia--release-arm64-v8a-.apk,并记录文件大小和 SHA-256。
源码副本规则:
- 禁止使用临时复制的源码目录构建、打包、安装或验证正式版本。
- 如因排查临时复制源码到项目根目录以外的位置,使用完成后必须立即删除该复制目录,并在删除后确认项目根目录仍为唯一构建来源。