Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ ResearchThread 是一个**本地优先**的桌面工具(Tauri 2,macOS + Wind

## 当前状态

- 更新日期:2026-09-11
- 阶段:**M3 完成 + 种子发布加固**(M1/M2/M3 全部落地,实机验证)——发布前审阅确认的九项门槛已全部代码落地:
- 更新日期:2026-09-12
- 阶段:**M3 完成 + 种子发布加固 + macOS 实机验证通过**(M1/M2/M3 全部落地,实机验证)——发布前审阅确认的九项门槛已全部代码落地:
- **事务式写入**(`storage/atomicWrite.ts`):写 `.rt-tmp` → 原文件让位 `.rt-bak` → 新内容就位 → 清备份;任何一步失败或进程中断后,**原文件或备份必有一个可恢复**;启动时 `recoverInterruptedWrites()` 扫描恢复并记账。测试注入 rename 失败/持续故障/崩溃残留全覆盖
- **单实例**(`tauri-plugin-single-instance`):第二实例启动即聚焦已有主窗口后退出,杜绝双 watcher + 同名 tmp/bak 互踩
- **外部编辑并发策略**:storage 保存前比对磁盘内容与应用最后已知内容(`seen` 缓存,读/写后更新),不一致抛 `ExternalConflictError`,UI 弹「覆盖保存(acknowledge 后重试)/ 重新加载 / 取消」。`updateTaskMeta` / `appendEntry` / `updateEntry` / `updateProjectDescription` / `saveWeekly` **五路全部受保护**(appendEntry 同样检查冲突后整文件重写,比纯追加更安全)
Expand All @@ -35,8 +35,10 @@ ResearchThread 是一个**本地优先**的桌面工具(Tauri 2,macOS + Wind
- **周报正确性**:任务定位主键改完整相对路径(修跨项目同名任务归错),活跃工作线 ☆ 置顶稳定排序
- **watcher 路径归一化**:Windows 反斜杠事件先归一再剥数据目录前缀(此前 `.git` / `.activity` 过滤失配、活动账记绝对路径);`.rt-bak` 一并过滤
- **发布物料**:关于页读真实版本(`getVersion()`)标「种子测试版」;[docs/seed-manual.md](docs/seed-manual.md) 种子手册——隐私边界(**明确撤回「打包数据目录反馈」**,改为脱敏反馈模板)、SmartScreen 安装步骤、卸载数据保留说明、外部编辑并发规则
- **发布包与安装提示**:`npm run make-release`([scripts/make-release.mjs](scripts/make-release.mjs))把 NSIS 安装包、SHA256SUMS、README、种子手册归拢到 `release/`(gitignore,脚本可重复生成);安装器中文化(`bundle.windows.nsis.languages` 简中+英文+语言选择器)并以 `bundle.license`(`src-tauri/INSTALL-NOTES.txt`)在安装前展示中文安装须知;应用首启弹欢迎卡(数据位置/快照警告含义/脱敏反馈,`settings.introSeen` 持久化开关)
- 下一步:干净 Windows 账户实测(首装 / 无 git / 无 CLI / 双开 / 升级 / 卸载重装 / 快照恢复演练)→ 全部过门后打 release tag 发 **Windows x64 受控种子版**;随后回到 **第二步阶梯 2a**(AgentRunner CLI 后端,见下条与 PART2.md)
- **发布包与安装提示**:`npm run make-release`([scripts/make-release.mjs](scripts/make-release.mjs))平台感知(win 收 NSIS exe / darwin 收 DMG),归拢安装包、SHA256SUMS、README、种子手册到 `release/`(gitignore,脚本可重复生成);安装器中文化(`bundle.windows.nsis.languages` 简中+英文+语言选择器)并以 `bundle.license`(`src-tauri/INSTALL-NOTES.txt`)在安装前展示中文安装须知;应用首启弹欢迎卡(数据位置/快照警告含义/脱敏反馈,`settings.introSeen` 持久化开关)
- **macOS 适配(v0.1.0,PR feat/v0.1-macos-support)**:Tauri 配置拆三文件(`tauri.conf.json` 公共 / `tauri.windows.conf.json` NSIS+WebView2Loader / `tauri.macos.conf.json` app+dmg+minimumSystemVersion 12.0,构建时自动合并);文件管理器改 `plugin-opener`(`openPath`,替代硬编码 explorer);**Finder/Dock 启动 PATH 修复**(`fix-path-env` crate,lib.rs setup 里 `fix()`,mac 验收 = Finder 双击启动后终端 git/claude/codex 可用);shell capability 拆平台(`shell-windows.json` / `shell-macos.json`——mac 只留 git/claude/codex/npm/node,explorer/cmd/powershell 不进 mac 白名单);universal 构建命令与 mac 测试矩阵见 docs/release.md §0/§3/§4-6。**签名两阶段**:内测不签名(**macOS 15+ 无「右键→打开」通道**,被拦后走「系统设置→隐私与安全性→仍要打开」,实机 2026-09-12 确认;macOS 12–14 才是右键→打开),面向陌生用户前必须 Developer ID + 公证
- **macOS 实机验证(2026-09-12,issue #4 已回报)**:universal DMG(lipo x86_64+arm64)、Finder 启动 PATH 三件套(git/claude/codex 全通)、数据持久、快照、.trash、冲突链路、单实例、⌘⇧Space、DMG 安装/重装/卸载保留全过;**修复 P1**:tauri-plugin-fs 点文件开关只认 `plugins.fs` 插件配置(capabilities 同名字段被忽略),Unix 默认拒绝点路径导致 macOS 数据层初始化必失败(`3e1ab0b`);**确认 macOS 15+ 无「右键打开」Gatekeeper 通道**(真实下载实测),指引按系统版本分流(`51c45a8`)。待办 issue:DMG 安装须知文件、首启 quarantine 检测提示卡、Developer ID 签名+公证
- 下一步:Windows 侧拉取分支回归(fs 修复对 Windows no-op,跑 vitest + NSIS 重归拢)→ 审阅合并 PR #3 → 干净 Windows 账户实测(首装 / 无 git / 无 CLI / 双开 / 升级 / 卸载重装 / 快照恢复演练)→ 全部过门后打 release tag 发 **Windows x64 受控种子版 + macOS universal DMG**;随后回到 **第二步阶梯 2a**(AgentRunner CLI 后端,见下条与 PART2.md)
- 第二步技术报告见 [PART2.md](PART2.md):CLI 后端选型(claude 首选/codex 坑清单)、MCP 工具面与 will_write 归属协议、2c 解析器选型、风险登记册与排期——**实施 2a–2d 前必读**
- **Windows 构建环境(本机)**:Rust stable-msvc 装了但**缺 Windows SDK**(提权安装 SDK 未获批准);当前用 `stable-x86_64-pc-windows-gnu` + `rust-lld` + Strawberry Perl 的 dlltool 编译通过。**启动命令**:
```bash
Expand All @@ -46,11 +48,11 @@ ResearchThread 是一个**本地优先**的桌面工具(Tauri 2,macOS + Wind
```
`src-tauri/.cargo/config.toml` 固定了 rust-lld 链接器;`Cargo.toml` 的 lib crate-type 只保留 `["lib"]`(cdylib 会撞 65535 导出上限)。改 `capabilities/*.json` 后需 `touch build.rs && cargo build` 强制重嵌(dev watch 不监听 capabilities)。
- **打包安装器**:`npm run tauri build`(同上环境)→ NSIS 安装包在 `src-tauri/target/release/bundle/nsis/`,per-user 安装免管理员;随后 `npm run make-release` 归拢发布包到 `release/`(安装包 + SHA256SUMS + README + 种子手册)。**坑**:GNU 构建动态链接 `WebView2Loader.dll`(dev 时由构建目录提供,安装后缺失会导致启动即退 EXIT=127)——已通过 `bundle.resources` 打进安装器(`src-tauri/WebView2Loader.dll`,勿删);升级 webview2-com-sys 后需同步更新该 dll。安装器未签名,首次安装会过 SmartScreen 警告(安装须知页已说明「更多信息→仍要运行」)。
- 终端面板 shell 白名单:`capabilities/default.json` 中 `shell:allow-spawn`/`shell:allow-execute` 的 allow 条目(name/cmd/args:true),新增可执行程序需同步加两处
- 终端面板 shell 白名单:按平台拆分在 `capabilities/shell-windows.json` / `capabilities/shell-macos.json` 的 `shell:allow-spawn`/`shell:allow-execute` allow 条目(name/cmd/args:true),新增可执行程序需同步加两处(其余公共能力在 `capabilities/common.json`)

## 关键决策(改动前必须与用户确认)

1. **存储 = Markdown 文件树 + YAML frontmatter,不用数据库**。理由:第二步 agent 经 MCP 工具读写(零迁移);Obsidian 可打开同一目录;git 提供版本历史。数据目录(默认 `~/ResearchThread/`,可在设置中修改)与代码仓库分离。**文件树是项目地图的唯一事实源**,一切地图视图都是 `get_project_map()` 的派生渲染,绝不持久化为第二事实源。
1. **存储 = Markdown 文件树 + YAML frontmatter,不用数据库**。理由:第二步 agent 经 MCP 工具读写(零迁移);Obsidian 可打开同一目录;git 提供版本历史。数据目录固定 `~/ResearchThread/`(当前不提供设置项修改)与代码仓库分离。**文件树是项目地图的唯一事实源**,一切地图视图都是 `get_project_map()` 的派生渲染,绝不持久化为第二事实源。
2. **storage 拆分为纯核心 + IO 适配器**(`core.ts` 无 Tauri API,`fsAdapter.ts` 注入 `tauri-plugin-fs`)。目的:2b 阶段同一核心配 `node:fs` 即可跑成 MCP server。**storage 写回契约**(宽松读 / 规范写 / 字段级合并保留未知字段 / 原子写 / 容忍 CRLF)见 PLAN.md 第三节,是数据完整性的关键,**违反契约的改动必须有测试覆盖**。
3. **起步零自定义 Rust**:文件 IO 走官方 `tauri-plugin-fs` 的 JS API。极简是第一阶段的起步策略而非长期约束——重大引入(如真 PTY)前与用户确认即可;**PTY 已降级为远期可选**(对话面板出现后终端退化为工具抽屉)。
4. **前端 = React 19 + Vite + Tailwind v4(2026-09-10 定)**:用户采纳外部按 UI.md 交付的 UI,并明确「可以扩大规模,只要匹配需求」。集成时剥离其 SSR(TanStack Start/Nitro)、登录(better-auth)、数据库(pglite/pg/kysely)——本地优先单机桌面应用不需要这些。**`DataAccess` 接口(UI.md 第 2 节)是 UI 与 storage 的唯一边界**,UI 组件不得绕过它触文件或自建数据。原「M1 末评估框架去留」的决策点提前完成。交付中超出 M1 范围的视图(搜索/今日/周报/图谱/agent 对话)按插件门控保留、默认关闭,不投入打磨(图谱与反目标冲突,保持禁用)。
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# ResearchThread

本地优先的科研/工作流程管理桌面应用(Tauri 2)。当前种子构建:**Windows x64**;macOS 为计划目标、尚未构建验证。把手写「思路整理」工作流数字化:**空间 → 项目 → 任务**三级层级 + 双层上下文(项目整体上下文 / 任务上下文)+ 周文档。
本地优先的科研/工作流程管理桌面应用(Tauri 2)。发布目标:**Windows x64 + macOS 12+(universal:Apple Silicon + Intel,DMG)**——macOS 适配代码已入库,DMG 需在 macOS 机构建(流程见 [docs/release.md](docs/release.md) §3)。把手写「思路整理」工作流数字化:**空间 → 项目 → 任务**三级层级 + 双层上下文(项目整体上下文 / 任务上下文)+ 周文档。

第二步(已规划、未开始):**人只说自然语言,agent 维护整个项目地图**——口述新任务/新项目/任务转折即可,agent 经 MCP 工具接口执行并定时产出日报/周报。

## 状态

**M3 完成 + 种子发布加固**(2026-09-11,M1–M3 全部落地并实机验证):数据落盘(Markdown 文件树)、活动日志、文件监听、收件箱、今日视角、终端面板、数据目录初始化、周文档一键生成、全文搜索、项目归档、markdown 预览之上,按发布前审阅补齐数据安全九项:事务式可恢复写入、单实例、外部编辑冲突防护、每日快照健康(git 缺失界面可见)、未保存草稿退出保护、周文档覆盖确认、周报正确性修正、watcher 路径归一化、种子手册(隐私边界 + 脱敏反馈模板)。下一步:干净 Windows 环境实测 → release tag → 受控种子版;随后第二步阶梯 2a。计划见 [PLAN.md](PLAN.md)。
**M3 完成 + 种子发布加固**(2026-09-11,M1–M3 全部落地并实机验证):数据落盘(Markdown 文件树)、活动日志、文件监听、收件箱、今日视角、终端面板、数据目录初始化、周文档一键生成、全文搜索、项目归档、markdown 预览之上,按发布前审阅补齐数据安全九项:事务式可恢复写入、单实例、外部编辑冲突防护、每日快照健康(git 缺失界面可见)、未保存草稿退出保护、周文档覆盖确认、周报正确性修正、watcher 路径归一化、种子手册(隐私边界 + 脱敏反馈模板)。**macOS 实机验证完成**(2026-09-12,PR #3):universal DMG(x86_64+arm64)、Finder 启动 PATH、应用内终端三件套、冲突/快照/.trash/单实例全矩阵通过;修复 macOS 数据层初始化 bug(fs 插件点文件作用域);确认 macOS 15+ 无「右键打开」Gatekeeper 通道,安装指引已按系统版本分流。下一步:干净 Windows 环境实测 → release tag → 受控种子版;随后第二步阶梯 2a。计划见 [PLAN.md](PLAN.md)。

## 文档导航

Expand All @@ -22,7 +22,7 @@
## 技术栈

- React 19 + Vite + Tailwind v4(SPA;按 [UI.md](UI.md) 契约集成外部交付的 UI,剥离其 SSR/登录/数据库)
- Tauri 2 桌面壳(plugin-fs / plugin-shell / single-instance / global-shortcut;生产线启用 CSP,见 [docs/release.md](docs/release.md) §5)
- Tauri 2 桌面壳(plugin-fs / plugin-shell / plugin-opener / single-instance / global-shortcut;生产线启用 CSP,见 [docs/release.md](docs/release.md) §5)
- 数据访问统一走 `src/dataAccess.ts` 接口([UI.md](UI.md) 第 2 节契约):浏览器 dev → MockDataAccess;Tauri 桌面 → StorageDataAccess(Markdown 文件树落盘)
- 数据层 `src/storage/`:纯核心 `core.ts`(无 Tauri API)+ IO 适配器 `fsAdapter.ts`(plugin-fs)+ 事务式写入 `atomicWrite.ts` + 每日快照健康 `snapshot.ts`;同一核心配 `node:fs` 即成 2b 阶段 MCP server(`tests/storageNode.test.ts` 的适配器即雏形)
- Vitest 守护写回契约与数据安全(宽松读/规范写/保留未知字段/外部冲突防护/软删除/中断恢复);CI 见 `.github/workflows/ci.yml`
Expand Down
Loading
Loading