diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
deleted file mode 100644
index 1416bfa3..00000000
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-name: Bug report
-description: 报告 FlareMo 的可复现问题
-title: "[Bug]: "
-labels: ["bug"]
-body:
- - type: input
- id: version
- attributes:
- label: 版本
- description: Release tag 或 commit SHA
- placeholder: v0.1.0 或 1596998
- validations:
- required: true
- - type: dropdown
- id: deploy
- attributes:
- label: 部署方式
- options:
- - Deploy to Cloudflare button
- - 手动 Wrangler 部署
- - 本地 wrangler dev
- - 其他
- validations:
- required: true
- - type: textarea
- id: steps
- attributes:
- label: 复现步骤
- description: 写清楚从空白状态到问题出现的步骤
- validations:
- required: true
- - type: textarea
- id: expected
- attributes:
- label: 期望结果
- validations:
- required: true
- - type: textarea
- id: actual
- attributes:
- label: 实际结果
- validations:
- required: true
- - type: textarea
- id: logs
- attributes:
- label: 日志或截图
- description: 可以贴 Wrangler 日志、浏览器 console、请求响应或截图
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
deleted file mode 100644
index ca9678ec..00000000
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-name: Feature request
-description: 提出 FlareMo 的功能建议
-title: "[Feature]: "
-labels: ["enhancement"]
-body:
- - type: textarea
- id: problem
- attributes:
- label: 你要解决什么问题
- description: 不要只写功能名,说明真实使用场景
- validations:
- required: true
- - type: textarea
- id: proposal
- attributes:
- label: 你希望怎么做
- validations:
- required: true
- - type: dropdown
- id: area
- attributes:
- label: 影响范围
- options:
- - Web UI
- - Memos-compatible API
- - D1 / Drizzle
- - R2 / attachments
- - Cloudflare Access / deploy
- - MCP
- - Docs
- - Other
- validations:
- required: true
diff --git a/.github/ISSUE_TEMPLATE/memos_compatibility.yml b/.github/ISSUE_TEMPLATE/memos_compatibility.yml
deleted file mode 100644
index 7a9f6704..00000000
--- a/.github/ISSUE_TEMPLATE/memos_compatibility.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: Memos compatibility
-description: 报告 Memos 客户端、脚本或 API 兼容问题
-title: "[Memos compatibility]: "
-labels: ["memos-compatible"]
-body:
- - type: input
- id: client
- attributes:
- label: 客户端或工具
- placeholder: 例如某个 Memos client、脚本或 curl
- validations:
- required: true
- - type: input
- id: endpoint
- attributes:
- label: 请求路径
- placeholder: GET /api/v1/memos
- validations:
- required: true
- - type: textarea
- id: request
- attributes:
- label: 请求
- description: 请求参数、请求体和关键 headers。不要贴 Access secret。
- - type: textarea
- id: response
- attributes:
- label: FlareMo 返回
- validations:
- required: true
- - type: textarea
- id: expected
- attributes:
- label: 期望的 Memos 行为
- validations:
- required: true
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
deleted file mode 100644
index b86230ff..00000000
--- a/.github/pull_request_template.md
+++ /dev/null
@@ -1,29 +0,0 @@
-## 变更
-
--
-
-## 影响范围
-
-- [ ] Web UI
-- [ ] `/api/app/*`
-- [ ] Memos-compatible `/api/v1/*`
-- [ ] D1 / Drizzle migration
-- [ ] R2 / attachments
-- [ ] Cloudflare Access / deploy
-- [ ] Docs
-
-## 验证
-
-请写明本地执行结果:
-
-```bash
-pnpm format:check
-pnpm verify
-pnpm deploy:dry-run
-```
-
-## 升级说明
-
-是否需要执行 D1 migration、调整 Access policy 或修改 Cloudflare 资源:
-
--
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 00000000..2bd5a0a9
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+22
diff --git a/AGENTS.md b/AGENTS.md
index 3111e17b..e09d3b27 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -10,7 +10,7 @@ FlareMo 是一个 Cloudflare 原生的个人知识管理系统:
- D1 是笔记、用户、关系、分享、设置和附件元数据的事实源。
- R2 只存附件、导出包和对象文件。
- `/api/v1/*` 提供 Memos 兼容 API 子集。
-- 应用层使用 Better Auth:浏览器使用 HttpOnly cookie session,脚本、Memos-compatible 客户端和 MCP 使用可撤销的 `memos_pat_` Personal Access Token。
+- 应用层使用 Better Auth:浏览器使用 HttpOnly cookie session,脚本、Memos-compatible 客户端和 MCP 使用可撤销的 `memos_pat_` Personal Access Token。PAT 带权限范围(`notes` 覆盖笔记/待办/文章/MCP,`admin` 额外覆盖 `/api/app/admin/*` 管理面)且默认 90 天有效期(1–365 天);旧的未存 permissions 的令牌保持完全访问以兼容既有脚本,不新建无 scope 的 PAT。
- Cloudflare Access 是可选的外层防线和迁移期防线;启用时,客户端仍必须通过 Access policy,并在应用层提供 cookie session 或 `memos_pat_`。
- 当前默认是一套单用户 bootstrap;禁止公开 signup,但认证表和 `auth_user_links` 为未来多用户保留扩展边界。
@@ -26,7 +26,7 @@ pnpm build
pnpm backup:drill
```
-`pnpm verify`(13 步全量门禁)只在维护者明确要求时运行,见下方「敏捷开发节奏」。
+`pnpm verify`(7 步全量门禁)只在维护者明确要求时运行,见下方「敏捷开发节奏」。
本地开发:
@@ -57,7 +57,7 @@ pnpm deploy:dry-run
pnpm deploy
```
-`pnpm verify` 是 13 步全量门禁(含 e2e),**只在维护者明确要求时执行**(发版也不需要)。
+`pnpm verify` 是 7 步全量门禁(含 e2e),**只在维护者明确要求时执行**(发版也不需要)。
只验证 Cloudflare 配置和打包:
@@ -78,8 +78,8 @@ pnpm deploy:dry-run
- 应用层认证边界是 Better Auth;不要新增绕开 Better Auth 的登录页、共享密码或第二套应用令牌。Cloudflare Access 可以作为可选外层防线,但不能被误当成应用用户身份映射。
- 凭据相关的 Origin 契约必须保持不变:cookie session 的状态变更请求(包括 `POST`、`PATCH`、`DELETE` 等非安全方法)必须携带并精确匹配 `FLAREMO_PUBLIC_URL` 或 `FLAREMO_TRUSTED_ORIGINS`;PAT 请求可以省略 Origin,但一旦携带也必须精确匹配同一 allowlist,否则返回 `403`。不要用 wildcard、`Referer` 或 Cloudflare Access headers 替代 Origin 校验。
- 不得把 `BETTER_AUTH_SECRET`、`FLAREMO_BOOTSTRAP_SECRET`、初始密码、cookie 或 `memos_pat_` 明文写进代码、文档、migration、issue、PR、日志或聊天;生产 secret 只能通过 Wrangler secret 或 Cloudflare 控制台安全配置。
-- `Temp/` 是参考仓库目录,不能提交。
-- 使用 GitHub Actions 时只允许两类 workflow:`.github/workflows/ci.yml`(瘦 CI:format / lint / typecheck / 单元测试,兕底与外部 PR 门禁)和 `.github/workflows/flaremo-update.yml`(只服务自部署用户自己的部署仓库,同步上游 Release 并创建升级 PR)。永远不用 GitHub Actions 做生产部署器(no CI/CD),不跑 E2E 进 CI;全量门禁 `pnpm verify` 只在维护者明确要求时于本地执行(发版也不需要)。不重新启用 Dependabot 或 Workers Builds。
+- `Temp/` 是本机临时脚本与参考目录(已 gitignore),不能提交。
+- 上游仓库**不包含** `.github/workflows`、没有 CI,也不做 push/自动生产部署。自托管部署仓库需要 GitHub Actions 时,从 `docs/templates/workflows/` 复制 `deploy-cloudflare.yml`(只响应 `workflow_dispatch`)和 `flaremo-update.yml`(只创建升级 PR),不要把上游或常规仓库改成 push/CI 自动生产部署,也不要新增其它 workflow、不跑 E2E 进 CI;全量门禁 `pnpm verify` 只在维护者明确要求时于本地执行(发版也不需要)。不重新启用 Dependabot 或 Workers Builds。
- 改路由、守卫、导航行为时必须同步补 e2e 用例(2026-09-10 事故教训:v0.15.3 守卫重构后门禁拦不住匿名首页无限加载,因为 e2e 只覆盖了深度链接没覆盖 `/`;门禁的有效性 = 测试覆盖率)。**补用例 ≠ 主动跑**:写进仓库即可,跑不跑由维护者决定。
- 敏捷开发节奏(2026-09-16 维护者定调):小步快跑,验证只跑与改动直接相关的定向用例(单个 Vitest 文件 / e2e spec)。**全量门禁 `pnpm verify` 只在维护者明确要求时执行——发版、部署、日常提交都不跑**。质量底线不变:改动涉及的测试必须绿、`pnpm format` 通过。
@@ -116,7 +116,7 @@ issue -> branch -> PR 流程只用于:对外贡献者、维护者明确要求
- 改动涉及的测试必须绿:只跑该改动相关的 vitest 文件(e2e 见上:opt-in,不主动跑)。
- 提交前跑一次 `pnpm format`(很快)。
-- 部署不需要先跑全量门禁:直接部署(`deploy-kosx.mjs` 默认已跳过 verify),迁移、构建和线上冒烟仍由部署脚本执行。
+- 部署不需要先跑全量门禁:直接部署(`flaremo-cloud` 仓库的 `scripts/deploy-kosx.mjs` 默认已跳过 verify;该脚本不在本仓库),迁移、构建和线上冒烟仍由部署脚本执行。
- 全量 `pnpm verify` 只在维护者明确要求时执行;发版脚本(`pnpm release`)默认不跑,`--verify` 可按需开启。
涉及部署、Wrangler、D1、R2 或 Access 的改动,建议跑 `pnpm deploy:dry-run`。
@@ -125,6 +125,7 @@ issue -> branch -> PR 流程只用于:对外贡献者、维护者明确要求
## 文档入口
- `README.md`:项目入口和部署入口。
+- `docs/README.md`:文档索引(入门 / 架构 / 部署 / 兼容 / 设计 / 历史设计稿分类)。
- **README 语言版本规则(2026-09-22 整理后定案)**:`README.md` 是唯一基准(英文),`README.zh-CN` / `.ja` / `.ko` / `.fr` / `.es` / `.ru` / `.ar` 七个翻译版是它的结构镜像(逐节 1:1,只差译文)。改主 README 时必须同步更新对应翻译版;只动某一节也要把该节同步到全部语言版。各版本专有约定:zh-CN 的文档链接指向中文文档根 `docs/`,其他语言版指向 `docs/en/`(`plugin-platform-standard.md` 无英文专版,保持根路径);语言切换器里的链接名保持各语言原生写法,不算混排。
- `docs/tech-stack.md`:确定的技术栈。
- `docs/architecture-notes.md`:架构和兼容边界。
@@ -133,7 +134,9 @@ issue -> branch -> PR 流程只用于:对外贡献者、维护者明确要求
- `docs/release.md`:发版规则。
- `docs/maintenance.md`:维护、备份和恢复。
- `docs/memos-compatibility.md`:Memos 兼容矩阵。
+- `docs/import-from-memos.md`:从 Memos 0.31 导出包迁移到 FlareMo(英文版在 `docs/en/`)。
- `docs/memos-ecosystem.md`:第三方客户端、认证方式和真实兼容验证记录。
- `docs/design-system.md`:Ember 设计系统(色彩、字体、动效、组件和文案约定)。
- `docs/semantic-search.md`:语义搜索、Vectorize 和 Workers AI 的边界。
+- `docs/templates/workflows/`:自托管部署仓库用的 GitHub Actions workflow 模板(`deploy-cloudflare.yml`、`flaremo-update.yml`)。
- `ROADMAP.md`:稳定方向和公开任务池。
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a8501fa..1ea9446d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,1001 +1,411 @@
# Changelog
-FlareMo 使用 SemVer。每个 release 都要写清楚升级影响、Cloudflare 资源变化和 Memos 兼容面变化。
+FlareMo 使用 SemVer。每个 release 都要写清楚升级影响、Cloudflare 资源变化和兼容层变化。
-## v0.22.0
+## v0.30.0
-团队项目工作台版本:新增团队项目视图(外部贡献合并),并完成一轮安全审计、全量 E2E 修复与工程卫生清理。**无 migration、无新增 Cloudflare 资源、无 API 破坏性变化。**
+**个人访问令牌(PAT)收窄为带 scope 与有效期的凭证。** 无 D1 migration(`auth_apikeys.permissions` 列早已存在),无 Cloudflare 资源变化;已有令牌继续可用。
-### 新增与改进
+### 安全
-- **团队项目工作台**(`/team-projects`,外部贡献 PR #148):集中查看项目、负责人、状态、当前进展、下一步与跟进日期,并可进入详情维护概况、记录进展/会议结论、上传与查看资料。项目仍是团队 memo,通过正文里的 ```kosx-pm 元数据块(协议 `kosx.pm/1`)识别;只有含有效元数据块的记录进入项目列表,普通笔记不受影响。团队/我的项目筛选只改变展示、不构成权限隔离;个人任务看板 `/projects` 原样保留。
-- 团队项目完整文案提供中文与英文两套;其余语言使用英文文案。
+- PAT 新增 `notes` / `admin` 权限范围:`notes` 覆盖 `/api/v1/*`、MCP 与文章/待办/附件等业务面,`admin` 额外覆盖 `/api/app/admin/*`。Worker 在每个 PAT 请求上校验 scope,管理面只接受 admin。
+- 新建 PAT 默认 90 天有效期,允许 1–365 天,不再提供「永不过期」;升级前创建的旧令牌 `auth_apikeys.permissions` 为空,保持完全访问以兼容既有脚本(账户页会显示“笔记 + 管理”,建议按最小权限重建)。
+- 账户页令牌对话框新增权限选择与默认 90 天占位,令牌列表展示 scope;`docs/architecture-notes.md`、`docs/deploy.md`、`docs/memos-compatibility.md`(含英文版)与 `AGENTS.md` 同步说明。
-### 安全审计
+### 工程
-对本次发布范围(含新合并的外部贡献)做了完整审计,结论与处置:
+- 新增 `pat-scopes.test.ts`(默认 scope/90 天、admin 面拦截、旧令牌兼容)并更新 team-admin、admin-member-removal 与 e2e 验收用例。
+- 新增 `docs/assets/screenshots/v0.29.0/`:发版前目检截图归档(桌面 / 暗色 / RTL / 手机 / 设置)。
+## v0.29.0
-- **依赖**:`pnpm audit` 无已知漏洞;供应链策略(`minimumReleaseAge`、构建脚本白名单、overrides 钉版本)校验通过。
-- **新贡献的代码**:无 DOM XSS sink(无 `dangerouslySetInnerHTML`/`innerHTML`/`eval`/`new Function`);元数据块解析全程 fail-closed(非法 JSON、重复块、未闭合块均降级为错误提示,不误解析);所有跳转均为内部路径且经 `validListUrl` 校验,无开放重定向;引用的外链经 `http/https` 协议白名单校验;不存在可触达的原型污染(仅保留 `__proto__`/`constructor` 作为普通键,无递归合并);**未新增任何后端端点、表、migration 或权限模型**,读写全部经由既有的、由服务端重新鉴权的 API。
-- **凭据卫生**:本次范围内无密钥泄漏,`.dev.vars` 与 `wrangler.jsonc` 均未被 git 跟踪。
-- **已修**:英文文案 23 处以 `":s"` 结尾的错字(所有英文标签与错误提示此前显示为 `Owner:s`、`Save failed:s`),成因是目录构造处的 `replace(/\\s/g, " ")` 在模板字符串里匹配的是字面反斜杠而非空白符。
+**部署链路、维护可靠性与工程门禁的一轮加固。** 无 D1 migration,无 Cloudflare 资源变化;已有部署按正常流程升级即可。
-**需要维护者决策的既有行为(非本次引入,未改动)**:`canEditMemo` 是「仅作者」,不含角色谓词,因此一名曾被设为成员、发表过团队笔记、之后被降级为读者的账号,仍可编辑自己既有的团队笔记内容(读者被明确拒绝的是**新建/重新发布**,即 `canPublishTeamMemo`)。这是作者本位权限模型的固有性质,改动会波及 Web/API/MCP/兼容面四个入口,故留待明确决策,不在本版静默变更。
+### 部署与文档
-### 修复
+- 自托管部署/更新 workflow 恢复为模板 `docs/templates/workflows/`;README(8 语言)、AGENTS、ROADMAP 与 deploy/update/maintenance/release/github-action 文档统一为「复制模板」口径,并明确上游仓库没有 CI。
+- `wrangler.json` 移除空的可选变量(`FLAREMO_TRUSTED_ORIGINS`、`FLAREMO_DEPLOY_REPOSITORY`),修复 Deploy to Cloudflare 表单把它们当必填项的问题;一键部署章节补齐公开 origin、embedding 维度(1024)与 Repository 指向说明。
+- 修正过期文档:恢复手册里已删除的 memory reindex 步骤、`run_worker_first` 路径白名单、`/capture` 残留描述、CHANGELOG 的死小节,以及英文 agent/deploy 文档与「全量门禁 opt-in」矛盾的说明。
+- 全量门禁步数统一为 7 步(`scripts/preflight.mjs` 是唯一口径),`CONTRIBUTING` / `release` / `maintenance` / `AGENTS` 同步。
-- 团队项目路由的 `validateSearch` 不再把 `edit=false` 写进 URL(此前每次访问都会被序列化,导致鉴权守卫捕获的跳转目标与实际落地地址不一致)。
-- 团队项目英文文案的 `":s"` 错字(见上)。
-- 删除时间轴组件里为旧 E2E 契约保留的隐藏 `monthLabels` 容器及其已失效的 prop 链路——纯死代码,唯一消费者是一个已失效的断言。
+### 维护与可靠性
-### 工程卫生
+- 每日 cron 的每个维护 pass 独立 try/catch,并输出 `scheduled maintenance complete` 汇总(步骤、耗时、计数、失败项);单个 pass 失败不再跳过当天的附件清理、计数重建、回顾通知与 Web Push。
+- 文章回收站清理补批次上限与逐行保护;回收站清理的 owner 查询改为批量,消除逐行点查的 N+1。
+- Web Push 通知的 icon/badge 指向真实图片资源;PWA 更新提示新增「稍后」,复用已有的 `pwa.updateLater` 文案。
+- `pnpm backup:drill` 默认只保留最近 10 次本地演练目录与 3 次远端恢复演练(`--keep=N` 或 `FLAREMO_BACKUP_KEEP` 可调);新增 `pnpm clean` 清理构建与测试产物。
-- 清理 24 条既有 biome 告警(未使用导入/变量、可选链、非空断言),全为语义等价的机械修正;仓库告警从 44 降至 20,剩余的均为移植 CSS 的 `noDescendingSpecificity`(样式组织建议、非错误,已按视觉验收,重排有回归风险故保留)。
-- **全量 E2E 达到 75/75 全绿**。此前长期有 1–2 个用例在整轮里必挂、单独跑却通过,逐个查明都是共享浏览器 profile 的持久状态串味,而非产品缺陷:
- - workspace 布局统一改版后,多份 spec 仍指向旧 UI(内联搜索已迁至 ⌘K spotlight 弹窗、设置面板按断点挂载两份、语音设置改为「状态行 + 配置弹窗」、记忆页改为内联快速输入器、`/capture` 并入统一工作区)。
- - 新增 `startWithCleanClientState` 测试助手,统一清理 composer 发送目标偏好(`localStorage`)、标签折叠、PWA 提示,并清空 IndexedDB 的草稿与提交队列。发送目标是 per-space 记忆的:前一个用例把个人空间记成 private 后,团队空间里本该 protected 的新记录会被正确地填成个人,于是「它出现在团队时间线」的断言失败——产品行为正确,是测试互相污染。
- - 清理 IndexedDB 一律「清空 object store」而非 `deleteDatabase`:删除在应用持有连接时会被阻塞并落到用例中途,把刚写好的草稿一起删掉;且对不存在的库调用 `open` 会创建空库,使应用自身的 `open` 跳过 `onupgradeneeded`。
- - 另修掉两处测试自身缺陷:共享页 `preload="none"` 音频的断言与模板设计相悖(访客按下播放前浏览器不取媒体,duration 恒为空)、记忆编辑用例未限定卡片的 `.first()` 会打开别人的菜单。
+### 安全与数据
-### Memos 兼容面变化
+- 更新检查改为 Worker 代理 `GET /api/app/releases/latest`:边缘缓存 10 分钟、校验 `repository` 形状(只接受 `owner/name`)、上游失败映射为 502;浏览器不再直连 `api.github.com`,国内网络与 60 次/小时/IP 限流不再影响「系统更新」入口。
+- `/api/v1/memos` 增加响应级契约测试:create / list / get / attachments 的返回体用 `@flaremo/contracts` 的 zod schema 校验,响应字段漂移不再只靠 path+method 的覆盖检查。`/api/app` 的 articles / projects / tasks 也补了同样的契约校验。
+- 补 admin 端点的集成测试:插件商店的鉴权与目录失败降级、`embeddings/rebuild` 的 owner 守卫与未配置提示,以及 PAT 删除成员时 R2 失败的回归测试(验证失败 job 会被记录,此前 PAT 调用会静默停在 removing)。
+- 修正 e2e 规格里过期的侧栏标签(`memos` → `notes`);发版前完整跑通 Playwright 端到端套件(71 个用例),并用截图目检了桌面/手机、明暗主题、阿拉伯语 RTL、回顾/待办/文章/设置页。
+- 新增 `docs/README.md` 文档索引,按入门 / 架构 / 部署 / 兼容 / 设计 / 历史设计稿分类;`llms.txt` 与 `AGENTS.md` 已链接。
+- 低强调文字的对比度:explorer 计数、可见性提示、月份表头、回收站分组等正文从 `muted-foreground/70–/80` 改为全色,tabs 的非激活文字由 `foreground/60` 提到 `/70`。
+- `FLAREMO_TRUSTED_ORIGINS` 与 `FLAREMO_PUBLIC_URL` 使用同一套 HTTPS 校验(localhost 除外),http origin 在部署启动时直接报配置错误。
+- cookie 请求先按会话 cookie 是否存在分流:无凭据仍返回 401;跨站状态变更在 session 查询之前返回 403。
+- 管理员删除成员失败时,PAT 调用也会写入 failed job(此前被 session-only 的 context 解析器吞掉,排障时看不到原因)。
+- 插件商店复用 admin 的 owner 守卫,删除重复实现。
-- 无变化。
-
-### 数据库 migration
+### 前端
-- 无。
+- 全局快捷键不再劫持按钮、菜单、下拉与组合框里的方向键和字母键。
+- 语言包晚于首屏到达时触发一次重渲染,不再让页面停在英文(阿拉伯语也不会出现 RTL 布局配英文)。
+- Spotlight 搜索补 combobox / listbox / option 语义与 `aria-activedescendant`。
+- 方向相关的物理 utility 改为逻辑 utility(`text-start` / `ms-auto` / `end-*` / `border-s` / `rounded-s`),32 个文件与 toggle-group 分段控件都覆盖;阿拉伯语 RTL 下菜单、对齐与定位不再反向(居中用的 `left-1/2 + -translate-x-1/2` 保留物理方向)。
+- 修复 RTL 下代码块被镜像的问题:`.memo-markdown` / 文章编辑器的 `pre`、`code` 以及 SSR 文章页的 `article pre/code` 统一 `direction: ltr; unicode-bidi: isolate`,阿拉伯语界面里的代码、括号与行内命令不再反向(发版前端到端目检发现)。
+- 所有 `queryKey` 收口到 `lib/query-keys.ts`(新增 projects/articles/memoContext/memoRelated/statsHourly 等 20+ 组 key,并抽出 `invalidateTaskSurfaces` 共享失效助手);新增测试禁止再写行内 queryKey 字面量,避免拼错 key 后静默不刷新。
+- 清理 71 个无引用 i18n key(8 语言各 71 行,1027 → 956 键),新增 usage 测试(白名单只保留 10 个待接线的 `pwa.install*` key),parity 测试继续保证 8 语言键集合一致。
+- 删除未使用的 `haptics` 与 `getDailyReview`,共享设置组件移到 `components/settings-section.tsx`。
-### Cloudflare 资源变化
+### 工程
-- 无新增或改名。部署前无需手动操作。
+- `pnpm verify` 改为 7 步;新增 `scripts:test` 自动发现 `scripts/**/*.test.mjs`,补跑此前从未纳入门禁的 `setup:usage`、`migrate-memos-export` 测试,并新增备份保留策略测试。
+- 清理 10 个已不在依赖图中的 override,启用 `minimumReleaseAge: 1440`(供应链策略与 docs/release.md 一致);补 `engines.node >= 22` 与 `.nvmrc`。
-### Better Auth 应用认证变化
+## v0.28.0
-- 无。cookie session、bootstrap、注册开关、PAT 前缀与撤销行为、`FLAREMO_PUBLIC_URL` / `FLAREMO_TRUSTED_ORIGINS` 与各 secret 的配置要求均不变。
+**破坏性收缩:删除 Agent Memory 的 D1 表、向量索引绑定与导出字段。** migration `0044_drop_agent_memory` 会删除 `memory_*` 八张表、`memory_fts` 及其触发器;导出 bundle 升到 v7,不再包含 `memories` / `memory_*` 字段。升级后记忆表数据不可恢复,升级前必须备份 D1。
### 升级步骤
-1. 直接部署即可(无 migration、无资源变化)。
-2. 部署后 `/team-projects` 立即可用;既有的 `/projects` 个人任务看板不受影响。
+1. 备份 D1(记忆数据不会迁移;确认不再需要后再执行)。
+2. 正常部署;migration 先清理遗留的 memory embedding/import 审计行,再按外键顺序删除记忆表。
+3. 旧版导出的 bundle(v1–v6)仍可导入:其中的 memory 字段会被忽略,不再写入。
+4. 追踪配置已移除 `VECTORIZE_MEMORIES` binding;已有部署可保留或手动删除 `flaremo-memories` Vectorize index,代码不再读取它。
-### 已知问题
+### 行为变化
-- 团队项目工作台目前只有中英文文案,其余语言回落到英文。
-- 项目记录的原始协议元数据在普通 memo 视图中可见(记录本身仍是团队 memo)。
-- 工作台使用内置的精简 fetch 层而非共享 API client,因此不会在 401 时触发全局「需重新登录」事件,而是就地显示未登录状态;服务端仍会对每个请求独立鉴权。
-- 上述「降级为读者后仍可编辑自己既有团队笔记」的权限边界待决策。
-- 兼容面仍未覆盖完整 CEL、完整上游 webhook 事件/egress 语义、完整多用户 ACL、原生 JWT parity,第三方客户端 smoke test 仍未完成。
+- `memory_*` 表与 `memory_fts` 删除,memo/任务/账户删除路径不再处理记忆表。
+- 导入导出、备份/恢复清单与导入回滚审计不再包含记忆;bundle 版本为 7。
+- 向量用量报告、重建端点与账户清理只处理 memo 索引;`embedding_tasks` 中的 memory 任务在 migration 中清除。
+- `maxMemoryItemsPerUser` 配额维度与 `memory_recall` 相关文档全部移除。
-## v0.21.0
+## v0.27.0
-记忆账本与启动性能版本:Harness 适配落地(ZCode / Codex / Antigravity 插件 + 本地核心 + 原生记忆搬家)、记忆账本 v2 领域层与审核减负、Horizon 天文表盘、Workspace 统一布局,以及一轮幅度很大的 Worker 启动图瘦身。**这是自 v0.20.1 以来的 81 个提交的合并发布,含 4 个新 migration(纯新增 + 回填,向后兼容)。**
-
-### 新增与改进
-
-- **记忆账本 v2**:事实键版本断代、证据链、双时态与混合召回;接入层与 CLI(裁决/复原/版本链端点、`memory_compile` 工具、退出码契约);v2.4 审核减负(AI 提炼默认直接生效、一眼扫替代逐条裁决、seed 直生效);键槽口径对齐唯一索引,提案不占位、不被误退位。
-- **Harness 适配(P0 替换式)**:ZCode / Codex / Antigravity 插件、本地核心与原生记忆搬家,另含 Pi Agent 进程内扩展;导入遇瞬时不可达会退避重试。
-- **Web**:独立子页收敛为持久 Workspace 布局;记忆项目面板、FilterPill 与设计系统对齐;Horizon 天文表盘(12 小时表盘、月/周/年视图深度对齐、卫星光子)。
-- **导出走 Queue**:绑定 `flaremo-data-export` 后 `POST /api/v1/export/tasks` 投递 `{taskId}` 并立即返回 queued,由 queue 消费端与 scheduled maintenance 共用的同一幂等 executor 执行导出;未绑定 Queue 的部署维持请求内执行不变。cron 兜底(stale 任务过期标记 + 过期产物清理)语义不变。
-
-### 性能
-
-- **Worker 启动图**:静态可达模块 1229 → 488、源码 5.87 → 2.54 MiB(约 -57%)。移出启动图的有 Better Auth 全簇、kysely、@noble、jose、@bufbuild(Connect protobuf)、cel-js、transliteration、fflate、shiki,以及 articles / SSR 公开页 / MCP / 采集四块路由树的入口态惰性化。可用 `pnpm startup-graph` 持续度量。
-- **D1 读放大**:新增按「作者 + UTC 小时 + 当前 status」分桶的聚合表 `memo_hourly_counts`,`stats` 的 `counts` / `active_days` / `activity` 三项与写入路径的 memo 配额检查不再扫 `memos` 全表;成本从「随 memo 总数增长」变为「随实际有活动的 UTC 小时数增长」。`tags` 字段与带 space 分区的查询仍是实时扫表(见 `docs/deploy.md` 的覆盖范围表)。
-- **其他**:记忆分页与批量水合、认证单查、import 与 webhook 串行往返收拢为 `inArray` + `db.batch`、前端首屏减重(ShareImageDialog / 插件 payload 懒加载 + i18n 按需语言包)。
-
-### 修复
-
-- **重复邮箱身份修复(`/api/app/*`)**:添加成员、修改邮箱使用一个已被占用的地址时,此前会落到 `users` / `auth_users` 唯一索引的裸驱动错误上,返回 500 `Internal server error`——真实原因只在日志里。现在由 domain 层统一判定为 409 `That email is already in use.`,前端映射为本地化文案;邮箱在写入 domain 表时归一化为小写并做大小写不敏感占用比较,堵掉「大小写变体绕过字节唯一索引、进而留下一条无团队归属的孤儿成员记录」的路径。`jsonError` 同时收口:保留框架异常(Better Auth 等)自带的 4xx 与其可读文案,不再一律压成 500(仅 4xx 生效,5xx 与无状态错误仍返回泛化文案,避免内部细节外泄)。**状态码变更**:修改邮箱撞已占用地址从 400 改为 409(`/api/app/*` 自有面,仅前端消费)。
-- **聚合表一致性**:评论创建与成员移除此前会写坏 `memo_hourly_counts`;聚合表重算会撞穿 D1 的 100 绑定参数上限,导致夜间校准从未真正生效——两者均已修复。
-- **Memos 兼容面错误处理收口**:`/api/v1` current REST 与 social 树的 `{code, message, details}` 错误信封合并为单份实现;`CompatValidationError` 与非法 JSON body 现在正确映射 400(此前会落 500)。
-- **评论创建的 memo 配额检查此前从未生效**;编辑 memo 时从新内容重新提取标签;年视图按导航年份锚定活动窗口、热力图年视图请求 366 天窗口;跳年笔记的绝对时间补上年份。
-- **Web**:服务端拒绝退出时不再假装已退出;403 不再误报「登录状态已失效」,Origin 不受信时给出明确提示;侧栏跳时间线补全 search 参数;窗口聚焦时的全量重拉导致的列表重放动画已停止(全局 staleTime 30s + 关闭 refetchOnWindowFocus)。
-- **分享卡**:长文本自适应高度、段落间距收紧、容器不再溢出裁切;视频内联播放的 403 已修(video.twimg.com 按 Referer 白名单防盗链)。
-- **备份/恢复**:`memo_hourly_counts` 此前未登记持久化清单,导致恢复演练既不覆盖也不校验它——现已归类为可重建表,并在恢复时从 `memos` 直接重算(不重放陈旧计数)。恢复清单另补记忆账本三张新表。恢复脚本的 R2 bucket 校验改为从 `wrangler.jsonc` 读取绑定名(此前硬编码 `flaremo-attachments`,任何自定义 bucket 名的部署都会卡在发布门禁上)。
-
-### Memos 兼容面变化
-
-- current REST 与 social 树的错误信封合并为单份实现;非法 JSON body 与 `CompatValidationError` 由 500 归位 400。
-- Connect 与 current 面的注册路径同样受重复邮箱修复影响(域层统一判定)。
-- 兼容子集范围未扩大:仍不主张完整 Memos Server parity。
-
-### 数据库 migration
-
-- `0030_memory_ledger_v2`:新增 `memory_evidence`、`memory_events`、`memory_rejections` 三表 + `memory_items` 的 `(user_id, scope_type, scope_key, fact_key)` 索引。
-- `0031_memory_ledger_followup`:新增 `memory_compile_archives`;删除 `memory_items_user_fingerprint_idx`(已被 0030 的复合索引取代)。
-- `0032_omniscient_energizer`:新增两个部分索引(推理待审扫描、向量回收扫描)。
-- `0033_large_multiple_man`:新增 `memo_hourly_counts` 聚合并从 `memos` 回填(用 `strftime` 打 ISO 时间戳,避免被下一次校准误判为陈旧墓碑而删除)。
-- 全部为**纯新增 + 回填**,向后兼容上一正式版本的 Worker;自动部署会先迁移再发布。
-
-### Cloudflare 资源变化
-
-- 可选新增 Queue:`flaremo-data-export`(binding `DATA_EXPORT_QUEUE`)。不绑定则该能力维持旧的请求内执行,无需强制创建。
-- `wrangler.jsonc.example` 的 `assets.run_worker_first` 补齐 worker 渲染路径(`/article/*`、`/share/*`、`/feed.xml`、`/sitemap.xml`、`/sitemap-articles.xml`、`/favicon.ico`)。**自托管升级需同步自己的 `wrangler.jsonc`**,否则这些路径会落回 SPA fallback。
-- 无 R2 / D1 / Vectorize 资源的新增或改名。
-
-### Better Auth 应用认证变化
-
-- 无 cookie session、bootstrap、注册开关、PAT 前缀或撤销行为的变化。
-- 新增的重复邮箱判定改变了「修改邮箱撞已占用地址」的状态码(400 → 409)与「添加成员撞已占用邮箱」的响应(500 → 409),均为 `/api/app/*` 自有面。
-- `FLAREMO_PUBLIC_URL`、`FLAREMO_TRUSTED_ORIGINS` 与各 secret 的配置要求不变。
+**删除 Agent Memory。** `/memory` 页面、`/api/app/memory`、`/memory/mcp`、Dreaming/冲突巡检、记忆量配额、`flaremo` CLI 与 harness 记忆插件全部下架;Agent 只通过笔记 MCP(`/mcp`、`/api/v1/mcp`)和一个新的 `flaremo-notes` Skill 读写用户的 memo。
### 升级步骤
-1. 备份 D1 与 R2(认证表在恢复清单内)。
-2. 同步自己的 `wrangler.jsonc`:补 `run_worker_first` 路径;如需队列导出能力,创建 `flaremo-data-export` 并加 `DATA_EXPORT_QUEUE` 绑定。
-3. 部署(自动先应用 migration 再发布 Worker)。
-4. 升级后无需手动操作:聚合表已在迁移里回填,夜间校准会继续自愈。
+1. 如果装过旧的 harness 记忆插件,先在旧版本仓库运行 `flaremo uninstall`(或手动移除 `~/.flaremo` 与各 harness 的插件/hook),再升级本版;否则会话开头的记忆注入会请求已删除的 `/memory/mcp`。
+2. 本版无 D1 migration、无 Cloudflare 资源变化;`memory_*` 表保留,下一版再按破坏性收缩规则删除。
+3. 把 MCP 客户端指向 `/mcp`,用 `memos_pat_` 令牌认证;工具名见 `skills/flaremo-notes/SKILL.md`。
-### 已知问题
+### 行为变化
-- `tags` 字段与带 space 分区的 stats 查询仍是实时扫表;D1 免费套餐下高频调用 `/api/app/stats` 仍可能触顶每日行数预算(估算方法与量级换算见 `docs/deploy.md`)。
-- 仓库内仍有 44 条 biome warning(未使用导入/变量、可选链风格、非空断言等),非门禁项,不影响发布。
-- 兼容面仍未覆盖完整 CEL、完整上游 webhook 事件/egress 语义、完整多用户 ACL、原生 JWT parity,第三方客户端 smoke test 仍未完成。
-
-## v0.20.1
-
-稳健性收口版本:修复工作区乐观更新的一处缓存键读取错位——乐观插入与乐观更新此前按错误的槽位解析时间线缓存键,主时间线的新记录只能等服务端失效后才出现,回收站/归档视图里的更新会把卡片短暂闪没;现在按真实键形(space/view/query/tag/untagged)逐槽读取并按可见性判定落位(私有记录不再被乐观插进团队时间线)。/calendar 日历页正式下线:任务管理收敛至 /projects(看板/截止日期/逾期提醒),逾期推送、通知铃、任务搜索、PWA 快捷方式全部改指 /projects,文案统一为「任务」;探索页只读小月历与逾期提醒保留;后端 `/api/app/calendar` 聚合端点保留(Memos 兼容面零变化)。地基清理:删除日历下线后的 8 语言死键(46 键/语言)、前端孤儿 `getCalendarView`、SPA 白名单死表项;README 与 PRD 的日历段落改写/补注记;长文件按职责再拆(worker 装配入口、import/export、管理端用户卡),函数体逐字搬移、消费方 import 零改动。稳健性:注册开关与集成凭证读取失败时留下错误日志(此前静默降级);`pnpm release` 新增 tag 与全部 workspace 版本、`FLAREMO_API_VERSION` 的一致性断言,漏 bump 会在发版前置被拦截。无 API 变化、无数据变化。
-
-### 升级影响
-
-- 无 migration、无资源变化、无 API 变化,直接部署即可。
-- 依赖 /calendar 深链的自动化或收藏请改指 /projects(/calendar 路由已移除);站内所有跳转已同步迁移。
-- 乐观更新修复会让「发送后卡片立即出现」恢复为预期行为,此前依赖失效回包的延迟不受影响。
-
-## v0.20.0
-
-工作区流畅度版本:搜索输入 250ms 防抖并随新请求中断旧请求(列表与语义搜索均可携带 AbortSignal);worker 端 /memos 的创建者昵称与附件两个查询并行化,减少首屏往返;搜索/筛选场景的乐观更新修复——编辑搜索结果不再被时间线状态过滤错误吞掉;加载失败可恢复——刷新/加载更多失败时保留已加载内容并给出重试入口,筛选命中为空、归档、回收站各有专属空态;搜索与标签筛选新增一键清除;工作区编辑器与搜索抽为独立组件(WorkspaceComposer/WorkspaceSearch),App.tsx 大幅瘦身。无 API 变化、无数据变化。
-
-### 升级影响
-
-- 无 migration、无资源变化、无 API 变化,直接部署即可。
-- e2e 新增 workspace-flow 用例覆盖搜索防抖、筛选清除与失败恢复。
-
-## v0.19.0
-
-体验优化版本:说明性小字全部改为悬停信息图标(InfoTip);团队成员行操作收进图标菜单并新增搜索与分页;品牌外观移入独立标签页(不再嵌在团队管理内);性能优化——修复窗口聚焦时全量重新拉取导致列表重放入场动画的卡顿(全局 staleTime 30s + 关闭 refetchOnWindowFocus,长列表不再逐卡播放动画)。无 API 变化、无数据变化。
-
-### 升级影响
-
-- 无 migration、无资源变化、无 API 变化,直接部署即可。
-
-## v0.18.0
-
-交互升级版本:设置类页面的操作表单全面弹窗化——添加成员、品牌外观编辑、修改密码、修改邮箱、删除账户、创建访问令牌、编辑用户名现在都以弹窗(Dialog/AlertDialog)打开;令牌吊销新增确认弹窗。状态展示类面板(传输、用量、令牌列表、品牌当前值)保持平铺。无 API 变化、无数据变化。
-
-### 升级影响
-
-- 无 migration、无资源变化、无 API 变化,直接部署即可。
-- 纯前端交互调整;e2e 覆盖更新并新增成员弹窗用例(29 用例)。
+- 删除 `/memory` Web 页面与导航入口;memo 详情页不再显示关联记忆,也不再提供「提炼为记忆」。
+- 删除 `/api/app/memory/*`、`/memory/mcp`、`POST /memos/:id/memory`。
+- 关闭每日 Dreaming 自动抽取与每周冲突巡检;不再产生新的 AI 记忆条目。
+- 删除 `flaremo` CLI、`harness/` 跨 Agent 插件、`skills/flaremo-memory`;新增 `skills/flaremo-notes`,笔记 MCP 工具面不变。
+- 账户用量面板不再显示「Agent 记忆条数」。
+- 旧版导出的 bundle 仍可导入;本版导出保留 memory 字段一版,下一版随表删除。
-## v0.17.1
+## v0.26.0
-文案清理版本:删除界面中的装饰性小字——登录页侧栏的 eyebrow、描述段落与特性胶囊,Transfer 面板与品牌外观卡的说明性副标题。功能性文案(确认提示、警告、筛选帮助、空态引导)全部保留。无功能变化。
+**安全与一致性修复版本。无 migration、无 Cloudflare 资源变化;升级后不需要迁移数据。** 公开分享页与文章页新增更严格的 CSP;导入的资源名与附件大小改为服务端校验;只读席位(reader)的发布边界补齐评论与导入两条路径;管理员凭据类接口改为仅接受浏览器会话。
-### 升级影响
-
-- 无 migration、无资源变化、无 API 变化,直接部署即可。
-
-## v0.17.0
-
-设计系统版本:与 KOSX(impact.kosx.ai)设计语言完全对齐——纯 token 级变更,无功能变化。flame 主色相旋转至 KOSX signal 橙(#ff6a00)色系、中性色降饱和至纸墨色系(dark 主题锚定 KOSX paper #0a0a0a / surface #1c1c1e)、全局圆角 0.75rem→0.875rem、字体栈对齐 KOSX(Helvetica Neue / PingFang SC)、动效采用 KOSX 标志性缓动 cubic-bezier(0.22, 1, 0.36, 1)。
-
-### 升级影响
-
-- 无数据库 migration、无 Cloudflare 资源变化、无 API 兼容面变化,直接部署即可。
-- 自部署用户升级后界面颜色/圆角/字体会有轻微视觉变化(同一设计语言内的调优),功能与布局零变化。若你在本地覆写过 `index.css` token,需要手动合并。
-
-## v0.16.0
-
-新功能版本:管理员现在可以在后台「团队管理 → 品牌外观」配置实例的产品名称与 Logo(白标能力,面向企业定制与自部署品牌化)。配置存 D1,Logo 图片存 R2(`branding/` 前缀);未配置时完全保持 FlareMo 默认外观。
-
-### 升级影响
-
-- 无数据库 migration(复用现有 `settings` 表)、无新 Cloudflare 资源(复用 `ATTACHMENTS` R2 bucket),直接部署即可。
-- 新增公开只读端点 `GET /api/app/branding`(匿名可访问,返回产品名与 Logo URL)与 `GET /api/app/branding/marks/:variant`(Logo 流式输出,带 ETag 与 300s 缓存)。
-- `GET /api/app/health` 的 `product` 字段现在返回配置后的产品名(未配置仍为 `FlareMo`)。
-- 管理员专用端点:`GET/PUT /api/app/admin/branding`、`PUT/DELETE /api/app/admin/branding/marks/:variant`(仅 owner;Logo 限 PNG/WebP/SVG,≤512KB)。
-
-## v0.15.4
-
-紧急修复版本:修复 v0.15.3 登录守卫回归——匿名或会话过期的访客在首页永远停留在「加载中…」,无法到达登录页(线上 KosX 实例因此自 0.15.3 部署起不可用)。**v0.15.3 自建用户请立即升级。**
-
-### 升级影响
-
-- 无数据库 migration、无 Cloudflare 资源变化、无 API 兼容面变化,直接部署即可;升级后用原有账号重新登录。
-
-### 修复
+### 升级步骤
-- **登录守卫回归**:`AuthenticatedRoute` 此前把 `/` 排除在匿名跳转 `/login` 之外(0.15.3 修路由循环时引入),会话失效的访客在首页无限停留在加载屏。现在任何未登录访问(含首页)都会跳转登录页并保留 `redirect` 回跳;到达 `/login` 后重置一次性标记,登出后回到 `/` 也能再次正确弹跳。
-- 新增 e2e 用例覆盖「匿名访问 `/` 必须跳转登录」,防止回归。
+1. 照常备份 D1 与 R2。
+2. `pnpm deploy`:无 migration,直接发布 Worker。
+3. 部署后检查登录、时间线、分享页、文章页、任务侧栏与成员管理各一次。
-## v0.15.3
+### 行为变化
-安全与正确性修复版本:修复语义搜索/记忆召回的 namespace 透传(此前带 namespace 的向量查询必然 0 命中)、封堵管理员经密码重置接管 owner 的路径、修复 Memos 兼容 force 删除的 R2 对象泄漏,并补齐部署护栏、限流默认值与一批文档/站点修正。含一处数据库 migration(附件清理部分索引,向前兼容)。
+- **管理员 PAT 不能再铸造凭据**:`POST /api/app/admin/users` 与 `POST /api/app/admin/users/:id/reset-password` 现在只接受浏览器会话;用 PAT 调用会返回 401。按邮箱幂等开通读者的 `PUT /api/app/admin/team/reader` 仍保留 PAT 通道,供支付回调或脚本使用。
+- **标签解析统一**:web 端改用与服务端相同的解析器,标签段会 trim 并转小写;URL 里的 `#fragment` 不再被误认为标签。
+- 时间线首页的回顾横幅改为请求 count-only 的 `/api/app/review/today/summary`;侧栏提醒改用 `/api/app/tasks/reminders`;记录卡片上的任务徽标改用 `/api/app/tasks/badges`,不再拉取全部任务。
+- 公开分享页与文章页响应新增 `Content-Security-Policy` 与 `X-Content-Type-Options: nosniff`。
-### 升级影响
+### 安全
-- **语义搜索索引布局变更**:memo 向量从「按作者 namespace」迁到单一共享 namespace(metadata 仍携带 `user_id`;查询侧由 N 次 Vectorize 查询变为 1 次,成本不随成员数增长;授权边界不变,仍然回 D1 按 `memoReadScope` 过滤)。**升级后存量向量位于旧 namespace,对新查询不可见**:等已有笔记被再次编辑时自动重建,或用重建工具(`rebuildEmbeddingIndexes`,现亦可经 owner 专用 `POST /api/app/admin/embeddings/rebuild` 触发;恢复演练同一路径)全量重排。Agent Memory 向量不受影响(保持按用户 namespace,recall 本就限定本人)。
-- 开源默认 `wrangler.jsonc` 现在绑定 `RATE_LIMITER`(登录等凭证端点的每 IP 限流默认生效);未部署该绑定的自建配置实例不受影响(限流自动降级为不启用)。`wrangler.jsonc` 不再随仓分发,改由 `wrangler.jsonc.example` 起步。
-- 新增数据库 migration `0017_attachments_cleanup_index`,`wrangler d1 migrations apply` 即可,向前兼容。
+- **修复公开页附件 ID 的存储型 XSS**:导入的附件 ID 此前只校验为任意字符串,分享页/文章页又把它直接拼进 `src`/`href`。现在导入侧只接受安全字符集,渲染侧对 ID 与 URL 双重编码/转义,公开页再套严格 CSP。
+- **修复导入附件配额绕过**:`attachments.size` 此前直接采用 bundle 声明值,声明 0 字节即可让配额账本永远为 0。现在按 base64 实际解码长度记账;覆盖导入且无二进制时保留原大小。
+- **只读席位边界补齐**:reader 不能再通过评论把内容发布进团队空间(父记录非 private 时拒绝),导入的 team/public 记录会降级为 private。
+- **D1 参数上限再修四处**:附件与表情水合、语义搜索、评论水合在满页(100 个 id)时会把 98/96 个 id 加上 `memoReadScope` 的绑定数推到 100 以上,直接触发 `too many SQL variables`。预留值统一提高,并新增 100 条记录的回归测试。
### 修复
-- **记忆语义召回修复(重要)**:`CloudflareVectorIndex.query` 此前把 namespace 误写成 metadata filter——Vectorize 的 `namespace` 是查询顶层选项,`filter` 匹配的是向量 metadata 字段,而没有任何向量存过名为 namespace 的字段,因此凡带 namespace 的查询必然 0 命中;同时恢复 MCP `memory_recall` 召回依赖里丢失的按用户 namespace 传参。两者叠加曾导致配置了向量索引的部署上 `memory_recall` 恒返回空列表且不回退 FTS。domain 层新增按 namespace 分区的 fake index 回归测试。
-- 记忆语义召回的降级路径现在记录服务端错误日志(原先静默吞掉一切 provider/index 失败)。
-- 团队管理员无法再通过密码重置接口触碰 owner,且非 owner 会话不能重置其他管理员的密码(与角色变更/成员移除一致的接管防护)。
-- Memos 兼容 API 的 force 删除改走统一的硬删除助手:先处理附件再删行,R2 对象不再永久泄漏(Web/Memos/MCP 三条硬删除路径收敛为同一实现)。
-- 语义搜索结果携带服务端计算的 `can_manage`,前端语义结果恢复编辑/删除操作。
-- 成员移除与自助注销的产物清理改走队列执行器(大成员体量可达百万级 vector id,不再占用请求子请求预算;未绑定队列的极简部署保持内联执行)。
-- outbox 维护巡检只在变更类请求上触发,读请求不再支付每请求 6-10 条查询的固定税;后台任务失败改为记录服务端日志(原先静默 `.catch(() => undefined)`)。
-- 新增 owner 专用 `POST /api/app/admin/embeddings/rebuild`:从 D1 全量重建 memo/memory 向量索引(运维恢复入口)。
-- 附件清理 cron 的候选查询补部分索引(原为全表扫描)。
-- domain 层 `sql IN ${array}` 写法统一改为 `inArray`。
+- **头像切换格式后仍返回旧图**:上传只写新后缀、不删旧后缀,读取顺序固定 `webp → png → jpg → gif`,导致 PNG 换 JPEG 后永远显示旧 PNG。现在写入新图后会清理其余后缀。
+- **校验失败不再把 Zod 原始 JSON 弹给用户**:全部路由改用统一的 `zValidator` 包装,返回 `{ error: { message } }`,与 `jsonError` 一致。
+- **补充全局 `app.onError`**:未包 try/catch 的路由或中间件异常现在也返回 JSON,不再落到 Hono 默认的 text/plain 500。
+- **文章 sitemap 与 RSS 的可见性规则下沉 domain**:路由层不再手写第二份 `published + not deleted` 查询。
-### 前端
-
-- App.tsx 进一步拆分(983 → 709 行):memo mutations 与乐观更新收敛为 `use-memo-mutations`,导出/导入流程收敛为 `use-data-transfer`(纯搬移,行为不变)。
-- 打破 App.tsx ↔ router-tree.tsx 的循环 import:路由定义移入叶子模块,App 经 lazy 引用,消除潜在 TDZ 崩溃面。
-- 登录后回跳登录前目标页(`redirect` search 参数;仅接受同源相对路径,防开放重定向)。
-- 死代码清理(未使用的 getMemory/listMemoryRelations)与休眠的 eslint/prettier 第二套 lint 栈移除(web 工作区统一 biome)。
-- 测试基建:28 份测试文件各自手写的迁移清单统一为共享 `applyFlaremoMigrations`(按 drizzle journal 顺序应用全部 migration),消除清单漂移。
-
-### 站点与配置
-
-- 公开仓去除作者生产环境标识:`wrangler.jsonc` 不再入库(`.gitignore`),新增 `wrangler.jsonc.example`(占位 `database_id` 与公网 URL),README/部署文档改为 `cp` 示例起步;Deploy Button 一键流程随之移除(配置不再随仓 provision),官网 hero CTA 改指部署指南。
-- 默认 `wrangler.jsonc` 补绑 `RATE_LIMITER`:开源部署的登录限流默认生效(此前未绑该限流器的部署登录不限流)。
-- 移除官网 Pricing 页($0 档营销页)及全部定价/层级入口——公开仓零商业痕迹。
-- README/ROADMAP/docs 过时的「未实现」声明修正(语义搜索、每日回顾、随机漫步、相关笔记均已上线);agent-memory 文档的向量索引描述与实现对齐;maintenance.md 移除已拆除的 Workers Builds 自动部署声明。
-
-## v0.15.2
-
-稳定性与安全加固版本。全库系统性审计后的集中清偿:Memos 兼容面的错误信息收敛与隐私收紧、登录限流补齐、列表查询批量化、请求级实例复用、团队模式验收测试补齐,以及前端大文件的结构拆分。无数据库 migration、无 Cloudflare 资源变化。
-
-### 安全与隐私
+### 性能
-- 错误信息不再泄露内部细节:Memos 兼容层(current/social/Connect)与 MCP 工具错误只透出领域级错误文案;D1 报错、TypeError 等未预期错误一律返回固定的 "Internal server error" / "Tool call failed."(服务端日志保留完整信息)。
-- 用户列表不再泄露成员邮箱:Memos 兼容面 `ListUsers`/`BatchGetUsers`/`GetUser` 与 REST `/api/v1/users(:user)` 对非本人请求改用不含 email 的公开 DTO(用户名与展示字段保留);本人请求与管理面不受影响。
-- 匿名网络探测封堵:`GetLinkMetadata`/`BatchGetLinkMetadata`(服务端代抓任意 URL)从匿名可达改为要求登录,未认证请求返回 401。
-- 登录爆破面补齐限流:Connect `AuthService/SignIn` 与 REST `/api/v1/auth/signin` 纳入与 `/api/auth/*` 相同的每 IP 边缘限流桶(`RATE_LIMITER`)。
-- 全站统计收敛为管理能力:Memos `UserService/ListAllUserStats` 原先任何成员可触发全站逐用户统计,现要求团队管理员,且由逐用户多次查询的扇出改为两条 GROUP BY 聚合查询。
+- 每日回顾的 20 个“往年今日”窗口与 4 个年龄档查询合并为一次 `db.batch`,首页横幅不再水合记录与附件。
+- 记录卡片的任务徽标按当前页 memo id 批量查询(每 100 个 id 一个请求),不再为每个卡片订阅最多 20 页的全量任务缓存。
+- 侧栏提醒改为一条聚合 count 查询。
-### 性能与稳健性
+### 工程
-- 请求路径实例复用:Hono 应用(全部中间件与路由表)按 Worker 生命周期构建一次;Better Auth 实例与 D1 wrapper 按 isolate 缓存(`getFlareMoRuntime`),不再每请求重建;需要非默认选项的路径(bootstrap 注册等)仍按需构建。
-- Memos 原生 access token 的 subject 解析不再每请求全表扫描 `auth_user_links`(按 D1 实例短 TTL 缓存;成员移出仍然立即失效)。
-- 列表页水合批量化:兼容面 memo 列表、评论列表与公开列表的附件、表情回应改为每页两条批量查询(原先每条 memo 至少 2 次往返,pageSize 上限 1000 时单请求可达数千条 D1 查询)。
-- 语义搜索:作者 namespace 清单按实例缓存;向量候选回读下沉为 domain 函数(`getSemanticSearchMemos`),路由层不再直查 memos 表。
-- 数据导出的 base64 转换分块处理(原先逐字节字符串拼接,32MiB 级附件内存放大明显),并复用 bundle 已有附件信息去掉逐附件重复查询。
-- Cron 附件清理改单条 IN 批量更新;成员移除队列的畸形消息直接丢弃,不再毒化整批重试。
-- 内容尺寸上限下沉 domain:`createMemo`/`updateMemo` 统一强制 content ≤ 100,000 字符、payload 序列化 ≤ 100,000 字符(与 Web/MCP 路径既有 contracts 上限对齐),Memos 兼容写路径不再无上限。
-- 内联 owner 判断收敛为 domain `isOwner`。
+- 标签解析、附件引用解析、品牌色白名单收敛到 `@flaremo/contracts`,删掉 web/worker/domain 三处“保持同步”的复制实现。
-### 前端
+### 文档
-- 列表 DTO 下发服务端计算的 `can_manage`(`canEditMemo` 为唯一规则来源),前端删除手写的角色×可见性规则副本。
-- Agent Memory、通知、导出重试等 mutation 补齐失败 toast;导出重试按钮不再产生 unhandled rejection。
-- 时间线编辑与可见性切换同步失效 memo-context、memo-related 查询,详情页不再闪旧数据。
-- 修订历史与回顾 tab 补错误分支(失败不再被当成空态)。
-- 结构拆分(纯搬移、行为不变):App.tsx 1519 → 983 行(路由树移至 `router-tree.tsx`,纯工具函数移入 lib),账户页 1107 → 397 行(五个面板组件拆至 `pages/account/`)。
-- 更新检查优先使用 `/api/app/health` 返回的 `update_repository`,fork/自部署不再指向写死的上游仓库。
-- 死代码与重复工具函数清理(formatBytes、资源名剥离、错误文案助手收敛进 lib)。
+- **定位调整:FlareMo 不再以「兼容某个外部产品」作为身份,改为「跑在 Cloudflare 上的 AI 原生第二大脑,含知识管理」。** 8 语 README、官网首页与 meta、`llms.txt`、`ROADMAP`、GitHub 描述与 topics 全部撤下外部品牌;`/api/v1` 兼容层与迁移脚本保留,但降级为迁移与开发文档里的说明,不再作为卖点。同时修正了官网 FAQ 中「完全兼容某客户端」的过度承诺。
-### 团队模式测试
+## v0.25.0
-- 补齐 docs/team-mode.md 验收矩阵中此前无覆盖的断言:最后一位有效管理员守卫(domain + admin API 双层)、成员移出后 PAT 失效、移除操作重放幂等且不误删团队/公开内容、旧 `protected` 数据升级转 `private`、默认关闭注册被拒、跨成员全文搜索隔离。
+**新增 migration `0041_attachment_thumbnail_size`(`attachments` 加一列)、`0042_import_task_rows`(导入 checkpoint 台账)、`0043_data_task_options`(任务选项列),均为增量变更;无 Cloudflare 资源变化。导入导出包升级到 v6,Memos 兼容面新增时区偏移时间戳。**
-### Memos 兼容面变化
-
-- 未认证的 `GetLinkMetadata`/`BatchGetLinkMetadata` 由 400(参数校验)变为 401(要求认证)。
-- 非本人的用户 DTO 不再包含 `email` 字段。
-- `ListAllUserStats` 需要团队管理员,成员调用返回 403。
-- 写路径新增内容尺寸上限,超限返回 400。
-- memo 列表 DTO 新增可选 `can_manage` 布尔字段,存量客户端可忽略。
-
-### 升级影响
+### 升级步骤
-- 无数据库 migration、无 Cloudflare 资源变化;自托管直接 `pnpm deploy` 即可。
-- 若依赖未认证链接预览或成员可见全站统计的第三方 Memos 客户端,需要改为登录会话 / 管理员凭据。
-- 错误响应文案有变化但协议结构不变;依赖具体报错字符串的自动化请改按状态码判断。
-- update 检查:配置了 `FLAREMO_DEPLOY_REPOSITORY` 的部署会在健康检查返回后查询自己的仓库 release。
+1. 部署前照常备份 D1 与 R2(含认证表)。
+2. `pnpm deploy`:先应用 `0041`、`0042`、`0043`,再发布 Worker。
+3. 部署后检查登录、时间线、图片附件(缩略图)、导入任务与分享弹窗各一次。
-## v0.15.1
+### 已知问题
-CI 部署回归修复版本。让 `pnpm deploy:preflight` 不再阻断 CI 构建环境的自动化首次部署,并合入两个依赖更新。
+- 同步导入的 `overwrite` 模式仍按旧行为直接改写现有行;它没有 ledger 可回滚。大包/任务导入只支持 `skip` 与 `duplicate`,两者都具备失败回滚与重试。
+- 导出包 v6 不再携带分享 token,导入时会重新生成;旧分享链接不会在恢复后继续有效,需要重新复制。
### 修复
-- 自动部署环境回归修复:`pnpm deploy:preflight` 在 CI 构建环境(`CI=true`,Workers Builds / Deploy to Cloudflare)中降级为警告不阻断。自动部署环境不携带操作者 secrets,正式 secret 由部署者通过 `wrangler secret put` 配置;本地手动发布仍强制校验 `BETTER_AUTH_SECRET`。v0.15.0 中该门禁曾让一键部署新用户的首次部署必失败。
-
-### 升级影响
-
-- 自托管行为不变:本地手动 `pnpm deploy` 仍强制校验 `BETTER_AUTH_SECRET`(≥32 字符)。
-- 依赖更新:hono 4.13.5、vitest 4.1.11;`pnpm-lock.yaml` 经 `minimumReleaseAge` 供应链策略重新解析(electron-to-chromium、node-releases、obug、seroval 回落到合规版本;dev 依赖 wrangler 等随 SemVer 范围小幅前移)。
-- 无数据库 migration、无 Cloudflare 资源变化、Memos 兼容面不变。
-
-## v0.15.0
-
-团队模式版本。为多用户部署补齐团队协作闭环:owner/admin/member 角色、管理员成员管理、三档可见性权限矩阵、可重试的成员移除清理;同时发布 Worker 生命周期工厂 `createFlareMoWorker`(HTTP routes、请求后 outbox、Queue 消费与 Cron maintenance 同一入口)和灾备持久化清单,自托管配置新增两个 Queue。
+- **硬删父记录不再把评论提级成普通记录**:评论原本只靠 `memo_relations` 标记为评论,关系行随父记录级联删除后,评论会以普通记录出现在时间线、标签统计与活跃度里。现在删除父记录会连同整棵回复树一起删除,并把评论附件标记为待回收。
+- **补上三处 D1 100 参数上限的漏网**:评论页一次水合 60 条以上、移除拥有 50 条以上私密记录的成员、单条记录绑定 100 个附件时,原先会因绑定参数超限直接 500。关系查询改为按「每个 id 绑定两次」计算分块,并对分块后重复返回的关系行去重;附件绑定逐块查询与更新。
+- **缩略图计入存储配额**:上传请求里的 `thumbnail` 分片此前既不限额也不计入 `attachments.size`,可以绕过配额向 R2 写入任意大小的预览图。现在缩略图有 1 MiB 上限、字节数计入配额(新列 `thumbnail_size`),主文件对外的 `size` 语义不变。
+- **插件资产加固**:匿名可访问的插件资产路由此前只给 HTML 加 `CSP: sandbox`。插件包里的 SVG 直接导航时会在应用同源执行脚本,可读取会话并铸造长期 PAT。现在 SVG 同样套 `sandbox` 并加 `Content-Disposition: attachment`;`` 用法不受影响。
+- **回收站清扫不再被单条坏数据卡死**:过期记录逐条 try/catch,失败只记日志;每轮最多排干 10 批(每批 200 条),没有进展时停止。此前一条异常会让其后的附件 GC、小时计数校准、回顾通知、到期提醒与 Web Push 全部跳过,且每天都卡在同一条。
+- **导入跨账号保护**:资源 id 是全局的。把 A 账号的导出包导入 B 账号时,此前要么写到一半撞主键 500,要么通过按 id 的 upsert 覆盖对方的记忆/项目/任务。现在写入前先检查五类资源的归属,发现他人记录直接拒绝;无二进制的重复导入也不再复用原 R2 key(避免两行共用同一对象、删一个毁另一个)。
+- **快捷键**:弹窗守卫此前查的是 Radix 的 `data-state`,而项目已迁移 Base UI(只输出 `data-open`)且确认框角色是 `alertdialog`,导致弹窗打开时 `e`/`p`/`/`/`?` 仍会操作背后的记录。j/k 焦点也改用记录 id 而非数组下标,切换归档/搜索/空间后不会再对错记录执行归档或置顶。
+- **分享弹窗**:选择「公开」后不再立刻关闭,分享链接在弹窗内立即可见、可复制;切到个人/团队仍按原行为关闭。详情页评论草稿按记录重新挂载,切换记录不会把上一条的草稿发到新记录下。
+- **文章**:自动保存改为串行链,慢网下后发的旧响应不会覆盖新正文;发布/取消发布后同步更新详情缓存,头部按钮与弹层状态不再相反。
+- **其它交互**:详情页勾选待办失败时回滚并重新校验;回顾设置的标签在请求进行中禁用;待办行在提交中禁用,连点不会丢状态。
+- **搜索**:聚光灯搜索的远端请求加 250ms 防抖,并在输入法组合期间暂停;本地缓存结果仍即时反馈。窄屏的搜索入口统一为打开聚光灯,不再维护一套独立的内联输入。
+- **Memos 兼容**:`createTime`/`updateTime` 等时间戳接受 `+08:00` 这类时区偏移;webhook 地址校验补齐 IPv4-mapped IPv6、末尾点和 CGNAT/保留网段。
+- **发布门禁**:`persistence:check` 登记 `memo_review_marks`(v0.24.0 起该检查一直失败);`backup:drill` 的 R2 查询补 `--config ./wrangler.jsonc`,不再被根目录占位 `wrangler.json` 抢先解析。
+- **首屏体积**:`@floating-ui` 单独成块,不再经由 Base UI 的静态依赖把整个编辑器 chunk(约 570 kB,gzip 约 178 kB)带进首屏预加载;输入框、文章编辑器与气泡菜单仍按需加载。
+- **文档**:官网文档目录新增中英文《从 Memos 迁移到 FlareMo》;`CONTRIBUTING.md`、`llms.txt`、发版与 Agent 部署文档更正为「仓库没有 CI」,不再宣称存在 `ci.yml`。
+
+## v0.24.0
+
+**新增 migration `0039_memo_review_marks`(只加一张表,向后兼容)与 `0040_memory_core_rules_locked`(只改数据),无 Cloudflare 资源变化,Memos 兼容面不变。**
-### 新增能力
-
-- 完整 Worker 生命周期工厂:公开导出 `createFlareMoWorker(options)`。它将同一份 `FlareMoAppOptions` 同时用于 HTTP routes、请求后的 webhook/embedding outbox、Queue 消费和 Cron maintenance;外部组合壳不再需要复制 default handler 的内部实现,也不会因只导出 `fetch` 而漏跑 durable work。
-- 团队角色与成员管理:`owner`(初始化账号,不可删除或降级)/ `admin`(团队管理员)/ `member` 三角色,成员状态 `active`/`removed`。「团队管理」界面支持查看有效成员、添加成员、设置/取消管理员、移出成员、为成员生成一次性密码重置链接。添加成员只需姓名 + 邮箱:服务端创建账号并签发 1 小时一次性激活链接(`/reset?token=…`),成员自设密码,管理员不经手也不可知晓密码;邮箱仅作唯一登录标识(不发邮件、不做邮箱验证,`FLAREMO_EMAIL_PROVIDER=none` 语义)。
-- 可见性权限矩阵:`private` 仅作者、`protected` 团队可见(有效成员只读)、`public` 全网公开(匿名只读);管理员可管理团队与公开内容,但不能读取成员私密内容。权限判断统一收敛在 domain 层,Web、Memos-compatible API、MCP、附件、全文/语义搜索与 SSE 共用同一矩阵;语义搜索 Vectorize 只出候选,最终结果回 D1 按当前成员过滤。
-- 成员移除闭环:移出立即禁止访问并撤销全部 session、PAT 与随机分享链接;其私密笔记与附件、个人项目/任务/Agent Memory、R2 对象与 Vectorize 派生向量被删除;团队与公开内容及历史作者名保留。操作落 `member_removal_jobs`(记录操作人/阶段/尝试次数/错误,可安全重试),经 `flaremo-member-removal` Queue 异步执行,未绑定 Queue 的部署回落 scheduled maintenance 兜底,且两条路径共用同一幂等执行器。
-- 灾备持久化清单:`scripts/persistence-manifest.mjs` 是所有 D1 `sqliteTable` 的唯一分类来源。恢复演练覆盖 memo/SSE/webhook/通知、数据任务、成员移除任务、Agent Memory、用量、项目/任务等事实源表,逐表比较恢复计数,并在恢复后把 Vectorize 的 `embedding_tasks` 重建为待处理 reindex 工作。
-- 前端 hashed 静态资源(`/assets/*-hash.*`)响应加 `cache-control: public, max-age=31536000, immutable`;HTML 与应用路由维持正常 revalidation。
-- `pnpm deploy:preflight`:发布前校验 `BETTER_AUTH_SECRET` 已配置、非占位值且字符多样性足够。
-
-### Memos 兼容面变化
-
-- 多用户部署的 `protected` 语义收紧:由「任何登录用户可见」改为「同实例有效成员可见」;`private`(仅作者)与 `public`(匿名只读)语义不变,单用户部署无感知。
-- 未由兼容接口显式开启注册时,公开注册继续拒绝(默认关闭不变)。注册开关(`GET/PATCH /api/app/admin/settings`)保留为兼容端点且仅 owner 可用;团队模式下加成员走管理员接口。
+### 升级步骤
-### Cloudflare、数据库与认证影响
+1. 部署前照常备份 D1 与 R2(含认证表)。
+2. `pnpm deploy`:先应用 `0039`、`0040`,再发布 Worker。
+3. 部署后检查登录、时间线、回顾页与文章页各一次。
-- D1 migration 0014–0016:`users.status` 列 + role/status 复合索引;`memos` 查询索引;`member_removal_jobs` 表。0014 同时把存量 `protected` 笔记转为 `private`(见升级说明)。
-- 自托管 wrangler 配置新增两个 Queue(producer + consumer):`flaremo-member-removal`(max_batch_size 10 / max_retries 5)与 `flaremo-data-export`(5 / 5)。Queue 需要 Workers Paid 计划;不绑定时成员移除与数据导出仍可经 cron 兜底执行,但清理有延迟。
-- 新增管理端点(团队管理员 cookie session,受 Origin allowlist 约束):`POST /api/app/admin/users`、`PATCH /api/app/admin/users/:id/role`、`DELETE /api/app/admin/users/:id`、`POST /api/app/admin/users/:id/reset-password`、`GET /api/app/admin/member-removal-jobs(/:id)`、`POST /api/app/admin/member-removal-jobs/:id/retry`。
+### 已知问题
-### 升级影响
+- Memos 导出转换脚本按 1.x 导出格式实现:评论会变成独立记录,外部链接附件会被跳过,不支持 ZIP64。
+- 兼容面仍未覆盖完整 CEL、完整上游 webhook 事件/egress 语义、完整多用户 ACL、原生 JWT parity,第三方客户端 smoke test 仍未完成。
-- **升级会把存量 `protected` 笔记自动改为 `private`**(0014 迁移),避免升级后旧「登录可见」内容被新团队语义意外共享;升级完成后再按需改为团队可见。`public` 笔记保持公开。
-- 自托管升级顺序:先在目标账户创建两个 Queue(`wrangler queues create flaremo-member-removal`、`wrangler queues create flaremo-data-export`)并在 wrangler.jsonc 增加 bindings,然后 `pnpm deploy`(自动应用 migration)。迁移完成后在管理员页确认成员移除任务可正常领取。
-- 既有 `owner` 自动成为团队管理员,既有成员初始化为 `active`;不允许移出或降级最后一位有效管理员。
-- 自托管 Worker 的 default export 行为不变。高级 host 若需要完整生产生命周期(含 Queue 消费),应从 `createFlareMoApp` 迁移到 `createFlareMoWorker`;前者仍保留给测试和只需路由装配的场景。
-- 灾备流程在新 Vectorize index 上恢复时,必须使用新建或明确清空的 index,再让重建 outbox 执行;不能复用旧 D1 的 `indexed` 状态作为向量存在证明。Queue 消息是可重放的 job ID,恢复 D1 后先确认 Queue 资源与 migration 状态,再放行后台清理。
+- **记录按写下的样子显示**(issue #157):此前记录按 Markdown 排版,连续空行被折成一段间距,单独一行的 `#` 被当成空标题消失,行首缩进被去掉,保存后再打开就对不上写下时的样子。现在记录、评论与详情页保留这些:多出的每个空行仍占一行,`#`、`## #` 这类没有正文的标题按原字符显示,行首缩进保留且不会被误当成代码块。真正的标题、列表、任务、引用、代码块和标签不受影响。文章是排版过的文档,不在此列。
+- **今日回顾不再整表扫描**:`GET /api/app/review/today` 的「往年今天」此前用 `datetime()` 包住 `created_at` 比较月日,扫过该用户的全部记录且无法用索引。现改为往前 20 年、每年一个有界的日期范围(走 `memos_user_created_id_idx`,每年最多 50 条),2 月 29 日只匹配真正有这一天的年份。选出的记录与原来一致。
+- **小时活跃度改读聚合表**:日、周、月视图的 `GET /api/app/stats/hourly` 此前按请求区间分组扫描 `memos`。现改为读 `memo_hourly_counts`(与日热力图同一个计数),按 UTC 小时换算回本地小时。请求跨度限制在 31 天以内,更长的区间返回 400。计数口径不变:正常与已归档的记录,不含评论。
+- **宣传文案不再提及 flomo**:README 八个语言版本与官网首页去掉了对 flomo 的点名。导入实际只接受 Memos 导出的数据包,原文案与实现不符。
+- **从 Memos 0.31 迁移**:新增 `scripts/migrate-memos-export.mjs`,把 Memos 的 ZIP 导出(manifest + 每条记录 JSON + Markdown 正文 + 附件)转成 FlareMo「导入」接受的 JSON 包,含附件字节、时间戳、置顶与可见性映射;Space 记录收紧为仅自己可见,评论按独立记录导入。教程见 `docs/import-from-memos.md`(英文版 `docs/en/import-from-memos.md`),README 八个语言版本的导入说明同步改写并加链接。
+- **Workers Builds 缺配置不再只报 ENOENT**(issue #151):`pnpm deploy` 的 preflight 发现根目录没有 `wrangler.jsonc` 时,会按 `FLAREMO_PUBLIC_URL` / `FLAREMO_D1_DATABASE_ID` / `WRANGLER_JSONC` 自动从模板生成;一个都没有时直接列出「复制模板 + provision」或「设置构建变量」两条路径。`docs/deploy.md` 新增 Workers Builds 小节。
+- **README 截图重拍**:八种语言共用的桌面明色、桌面暗色、移动端三张换成当前界面(Ember 3、侧栏与页头新分工),新增待办看板与文章列表两张功能截图;图片体积从约 1MB 降到 70KB 左右。
+
+- **导入有了任务级 checkpoint,失败不再留下半成品**:每条导入写入都会在同一批次里登记到 `import_task_rows`。失败(包括 Worker 被中断后由 cron 发现)先按台账回滚所有顶层记录及附件对象,再标记失败;任务重试会从干净状态重跑,不会重复插入。`/api/v1/import/tasks/:id/retry` 用创建任务时存入 R2 的原始 bundle 直接重试,导入面板对失败的导入显示「重试」。同步 `/import` 的 `skip`/`duplicate` 也走同一套台账;`overwrite` 保持旧行为。
+- **导出包升级到 v6**:memo 条目新增 `team_id`,团队可见记录恢复到接收方自己的团队;跨团队或不存在的团队回退为仅自己可见,不再产生「protected 但没有 team」的行。分享条目不再导出 `token`(capability URL 不应写进备份文件),导入时重新生成。
+- **移除 dev-only 的 `shadcn` CLI 依赖**:它只用于生成组件,不参与构建或运行;连带清掉 Dependabot 报的 `minimatch` 与 `deepmerge` 两条开发依赖告警。需要时用 `pnpm dlx shadcn@latest`。
+- **记忆页重做**:
+ - 「随身小抄」此前每次打开都报错(前端没传必填的 `agent`,还把返回的对象当字符串用),现已修好:显示 Agent 通过 MCP 实际拿到的那份内容、带上几条、约多少 tokens、因篇幅没带上的条目,可以切换到某个项目里看。
+ - 「铁律」只认已锁定(`verification=locked`)的记忆,与编译器和 Agent 的规则一致。此前菜单里「钉住」只锁定、不进「铁律」筛选;编辑弹窗的「铁律」开关只改 `tier`、实际并不锁定。现在开关就是锁定/解锁,锁定时 `tier` 同步为 core。migration `0040` 把用户自己写的、`tier=core` 但未锁定的有效记忆补成锁定。
+ - 「待我确认」里,Agent 想替换或与之矛盾的那条旧记忆显示在提议上方(`/api/app/memory/review` 每条新增 `conflict_with`),按钮改为「换成新的 / 保留原来的」;依据变了的记忆问「仍然成立 / 归档」;`review_reason` 不再显示原始代码。提议只出现在「待我确认」,不再混进「全部」等列表。顶部提醒改为与首页回顾横幅同样的安静样式。
+ - 「项目」去掉概览卡片与项目横幅,改为按项目分组的列表,项目名重名时显示更完整的路径。卡片头部显示来源 Agent 和「用过 N 次」,「AI 摸索」统一为「AI 发现」,「通过/删除」改为「采纳/不采纳」(不采纳是归档,可在归档里找回);观察到的记忆可「我确认过」;提议不能直接设为铁律;已换新的记忆不再显示无效的「复原」。自定义项目从 `window.prompt` 改为小弹窗。
+ - 后端:确认已锁定的记忆不再把它降级为已确认;解锁只对已锁定的记忆生效(此前对提议解锁会让它直接生效而不退役旧事实);已归档或已换新的记忆不再因依据变化回到待确认队列。
+- **评论在时间线里展开**:有共享团队时,每条记录卡片右上角多一个评论按钮(有评论时常显条数,没有时悬停出现,触屏常显),点开后评论区直接在卡片下方展开,不必再进详情页;只显示最近 5 条,更多的跳到详情页。评论带头像和作者名,输入框随内容变高,回车发送、Shift+回车换行;团队可见的记录里输入 `@` 会弹出成员补全(与服务端提及通知同一份名单),详情页的评论框同样支持。草稿和展开状态在虚拟列表滚出再滚回时保留。新增 `comments.action`、`comments.placeholderMentions`、`comments.mentionList`、`comments.viewAll`。
+- **待办页去掉页内侧栏**:「今天 / 接下来 7 天 / 全部任务」改为页头右侧的分段切换(与回顾页同一套样式,抽到 `nav-item-styles.ts` 的 `SEGMENT_*`),项目改为列表上方的「全部项目 ▾」选择器,选中项目后旁边出现「…」菜单(编辑、归档、删除);日期视图与项目可以组合,计数随项目变化。回收站沉在列表底部。页面宽度由 1024 收到 768。`project-row.tsx` 改为 `project-menu.tsx`,新增 `project-picker.tsx`。
+- **今日回顾重做**:「往年今日」改名「今日回顾」。旧记录一次只读一条,上方是进度条,←/→ 翻页,读完显示完成卡片。
+ - 取材改到服务端(新接口 `GET /api/app/review/today`):往年今天每年一条(最多 3 条,阶梯不满时补到每年两条),再按 3–13 天、2–8 周、2–5 个月、5–12 个月四个时间段各取一条,直接按日期范围读 D1,不再只看最近 100 条,所以写得多的人也能翻到几个月前的记录。昨天、前天写的不算回顾。整叠最多 7 条,用当天日期做种子挑选,同一天刷新不变,第二天换一批。标签显示真实距离(「5 天前」「3 周前」「4 个月前」)。
+ - 读过会被记住(新表 `memo_review_marks`,`POST /api/app/review/marks`):刷新或换设备从没读的那条继续,全部读完直接显示完成卡片;读过的记录 30 天内不再出现;首页横幅改为「今日回顾 · 还有 N 条旧记录」,读完就不再显示。
+ - 每张卡片下方可以「补一句」(在卡片里展开评论框,写下今天的看法)、「归档」或「不再回顾」,后两个都能撤销。
+ - 右上角「回顾设置」(`GET/PATCH /api/app/review/settings`):选择不回顾的标签(含子标签),查看并一键恢复设为不再回顾的记录。
+ - 去掉「最近 7 天」统计卡片(与侧栏热力图重复),完成卡片里保留一句「这一周你写下了 N 条新记录」。待办摘要从回顾页移除(`today-tasks.tsx` 已删)。随机漫游加上同样的标题与说明,操作行改为「上一站 / 结束漫游 / 继续漫游」。
+- **文章页改为紧凑列表**:上方「全部 / 草稿 / 已发布 / 回收站」筛选(回收站为空时不显示),文章放在同一张纸上逐行排列,右侧是状态与日期,「查看公开页」「删除」收进「…」菜单。页面宽度与时间线一致。新增 `article.filterAll`、`article.filterEmpty`。
+- 记忆卡片的「…」改为悬停出现,与记录卡片一致。
+
+- **侧栏与页头分工**:时间线页头的下拉框只剩空间筛选(全部空间 / 个人空间 / 团队空间),移到页头右侧、搜索框旁边,没有共享团队时不显示;页头左侧改为和其他页面一样的标题(记录 / 归档 / 回收站)。归档、回收站从下拉框移到侧栏底部,成为独立的页面入口,可以和空间筛选组合(切换空间不再把你从归档带回时间线)。侧栏「全部记录」改名「记录」,`space.all` 改为「全部空间」,避免两个「全部」含义不同。新增文案键 `sidebar.storage`(8 语言)。e2e `memo-flow`、`space-flow`、`workspace-flow` 改为从侧栏进入归档与回收站,已改未跑。
+- **设计系统 Ember 3**:`accent` 改为中性暖灰,菜单焦点、命令面板选中、空状态图标不再铺品牌浅底;页面标题图标改为墨色;日历热力图数字保持墨色,只用底色深浅表示活跃度;空状态图标改为一张小纸片;浮层入场缩放从 95% 收到 97%,位移从 8px 收到 4px,并新增三档时长 token;新增共享组件 `Kbd`、`SendButton` 与页头搜索框样式 `HEADER_SEARCH_FIELD_CLASS`,记忆页的发送按钮和搜索框与时间线保持一致;全站开启中英混排自动间距与行首标点挤压。中文文案里残留的「笔记 / 便签」统一为「记录 / 记忆」。设计文档 `docs/design-system.md` 同步。
+- **搜索只保留 ⌘K 一个入口**:手机端去掉时间线顶部的搜索框,改为页头放大镜打开同一个命令面板,有生效的查询时图标带小圆点。宽屏页头搜索框在有查询时直接显示查询词与清除按钮,点击仍打开面板。
+- **全屏书写只写记录**:输入框的「写长文」改名为「全屏书写」,图标改为展开箭头;画布去掉标题栏和「记录 / 文章」切换,发送后进入时间线。文章统一从「文章」页的「写文章」开始。旧草稿里如果存过标题,发送时会作为记录的一级标题保留。删除 `composer-type-menu.tsx`、`workspace-search.tsx`。
+
+- **产品结构精简**:侧栏「往年今日」「记忆漫游」合并为一行「回顾」,页头分段切换「往年今日 / 随机漫游」(`nav.randomWalk` 中文值改为「随机漫游」,避免与 AI「记忆」撞名;新增 `nav.review`,八种语言同步)。待办页去掉页头「新建任务」「新建项目」按钮:建任务用「添加待办」行,行尾新增展开按钮打开完整表单并带上已输入的标题与日期;建项目用左栏「+新建项目」。新建记忆默认不再勾选「铁律」;小抄按钮加上文字。只有一个人的工作区隐藏团队概念:视图菜单只剩「全部 / 归档 / 回收站」,详情页私密记录不再显示可见性徽章(`/api/app/me` 的 `team` 新增 `member_count`,旧服务器不返回时按有团队处理)。语言切换从侧栏底部移入账户菜单子菜单。
+
+- **图片查看器**:同一条记录里的多张图片可以用两侧箭头或 ←/→ 翻页,左上角显示「3 / 4」;默认缩放改为「铺满宽度但不超过原图尺寸」,小图不再被放大发虚,手机上大图也不再被裁掉一半;点击图片周围的暗处即可关闭;缩放按钮只在鼠标设备上显示(触屏用双指缩放);下载按钮与其他按钮同样式。新增 `imageViewer.previous`、`imageViewer.next`,八种语言同步。
+- **空状态**:归档、回收站的空状态分别用归档盒、垃圾桶图标(原先与首页同用收件箱);记忆页空状态改用与其他页面一致的图标块,说明文字不再折出孤字;待办页空状态去掉与上方「添加待办」输入行、页头按钮重复的「新建项目 / 新建任务」按钮,文案改为指向上方输入行(`projects.allTasksEmptyDescription` 八种语言改写)。
+- **侧栏**:一个标签都没有时不再显示「无标签」行(此时它等于全部记录),「还没有标签」提示与导航行左对齐;手机抽屉右上角的关闭按钮原先被吸顶头部盖住、几乎看不见,现已置顶;触屏上标签行的展开箭头不再与「…」重叠。
+- **账户菜单**:分成「账户、外观、通知」「导出、导入、检查更新」「退出登录」三组。
+- **手机端**:待办页页头只留「新建任务」(新建项目在下方横滑栏里),标题不再被挤;评论框在触屏上不再显示 ⌘↵ 快捷键提示。
+- **侧栏标签**:每个标签都显示条数(原先只显示大于 1 的),展开箭头放在条数前;重命名、删除两个常驻占位的小按钮收进「…」菜单,悬停时占用条数的位置(触屏常显),与待办页项目行一致。重命名改为在原行就地输入,回车保存,Esc 或点别处取消,去掉下方的保存/取消按钮。
+- **时间线筛选条**:日期、标签、无标签三种筛选标签统一为 28px 高、整枚可点;只有一个筛选时不再显示「清除筛选」(标签自带 ×)。
+- **侧栏待办提醒**:「今日到期」「本月已逾期」改为与导航行同样的安静行,用小圆点表示紧急程度,文字不再整行标红。
+- **分享与笔记详情打磨**:生成图片卡片的模板选择器改成单行横滑(9 个模板原先折成 7+2),并给 `