Skip to content

Latest commit

 

History

History
578 lines (461 loc) · 24 KB

PLANNING.md

File metadata and controls

578 lines (461 loc) · 24 KB

Anna App: Mini Notes with LLM Summary — 完整项目规划

生成日期:2026-07-03 状态:规划阶段,尚未开始编码


一、项目整体理解

1.1 项目定位

这是一个 Anna App 平台本地开发能力验证项目,不是普通 Web App。核心目标是证明你理解 Anna App 的平台模型:

Anna App iframe(前端)
  → AnnaAppRuntime.connect()           // 连接 Host
  → anna.storage.*                     // 通过 Host API 读写存储
  → anna.tools.invoke(...)             // 通过 Host API 调用本地工具
  → 本地 Executa Tool(JSON-RPC/stdio) // 工具进程
  → sampling/createMessage             // 工具反向请求 Host LLM
  → Summary 返回 UI                    // 结果回传前端

1.2 关键约束

约束 说明
不能绕过 Anna 平台模型 不直接调 localStorage/HTTP API/llm.complete
必须走 Executa Tool 总结必须通过 anna.tools.invoke → Executa → sampling → Host LLM
必须是工程化前端 源码目录 + 构建脚本,不能是单文件 HTML
必须可本地复现 anna-app dev --no-llm + anna-app executa dev --mock-sampling
必须能三平台打包 darwin-arm64/x86_64 + windows-x86_64 binary

1.3 核心用户

  • 审阅者:会按 README 步骤逐步验收
  • 你自己:需要本地开发、调试、测试

1.4 核心场景

  1. 用户打开 Anna App,看到笔记列表(可能为空)
  2. 用户输入文字,点击保存 → 笔记存入 anna.storage
  3. 用户点击删除 → 笔记从 anna.storage 移除
  4. 用户点击 Summarize → 前端调 anna.tools.invoke → Executa Tool → sampling → LLM 总结 → UI 展示

二、MVP 版本功能

MVP(必须完成)

编号 功能 验收方式
M1 创建笔记 输入文字 → 保存 → anna.storage.set 调用可追踪
M2 笔记列表 从 anna.storage.get 读取并展示
M3 删除笔记 删除 → anna.storage.set 更新存储
M4 LLM 总结 Summarize 按钮 → anna.tools.invoke → Executa → sampling
M5 空状态 无笔记时显示引导文案
M6 错误状态 --no-llm 下 Summarize 显示 [-32603] 错误
M7 manifest.json 完整声明 schema/executas/permissions/ui/dev
M8 Executa Tool JSON-RPC/stdio, initialize/describe/invoke/health/shutdown
M9 Mock sampling fixture .jsonl 文件用于 --mock-sampling
M10 前端构建 npm run build 生成可加载 bundle
M11 二进制打包 三平台 binary archive
M12 GitHub Actions release workflow 三平台构建 + smoke test
M13 README 完整说明

可以暂时砍掉的功能

功能 原因
笔记编辑 题目明确不要求
搜索/标签/分类 题目明确不要求
多笔记本 题目明确不要求
富文本/附件 题目明确不要求
协同编辑 题目明确不要求
复杂 UI 美化 题目明确不要求
真实 LLM API 集成 题目明确不要求
云端 APS 存储 题目明确不要求
时间戳显示 可选,MVP 可先不做
加载动画 锦上添花,MVP 后加

三、完整功能模块

Mini Notes App
├── 1. 前端 UI(React + TypeScript + Vite)
│   ├── 1.1 AnnaAppRuntime 连接层(connect/disconnect/error)
│   ├── 1.2 Storage 服务层(get/set 封装)
│   ├── 1.3 Tools 服务层(invoke 封装)
│   ├── 1.4 笔记列表组件(列表/空状态/错误状态)
│   ├── 1.5 创建笔记组件(输入框/验证/提交)
│   ├── 1.6 删除笔记组件(确认/执行)
│   └── 1.7 总结组件(按钮/结果展示/错误展示)
│
├── 2. Executa Tool(Node.js/TypeScript → 打包为 binary)
│   ├── 2.1 JSON-RPC 2.0 over stdio 服务器
│   ├── 2.2 initialize(capability negotiation v2)
│   ├── 2.3 describe(返回 tool manifest)
│   ├── 2.4 invoke(summarize handler → sampling)
│   ├── 2.5 health(健康检查)
│   ├── 2.6 shutdown(优雅退出)
│   └── 2.7 日志系统(stderr)
│
├── 3. 配置与元数据
│   ├── 3.1 manifest.json(Anna App 清单)
│   ├── 3.2 executa/executa.json(Executa 清单)
│   └── 3.3 package.json(前端 + 根 workspace)
│
├── 4. 测试与 Mock
│   ├── 4.1 mock-sampling fixture(.jsonl)
│   └── 4.2 手动测试脚本
│
├── 5. 构建与打包
│   ├── 5.1 前端构建脚本(Vite → dist/)
│   ├── 5.2 Executa binary 打包脚本
│   └── 5.3 GitHub Actions release workflow
│
└── 6. 文档
    └── 6.1 README.md

四、推荐技术栈

层次 技术选型 理由
前端框架 React 18 + TypeScript 生态成熟,类型安全
构建工具 Vite 快速构建,Anna App 友好
包管理 pnpm monorepo 支持好
Executa Tool Node.js + TypeScript 与前端统一语言,降低心智负担
Binary 打包 pkg / bun build / sea 将 Node.js 打包为独立二进制
JSON-RPC 手写轻量实现 依赖少,协议简单,可控制
CI/CD GitHub Actions 题目要求
Lint ESLint + Prettier 代码质量

关于 Executa Tool 语言的补充说明

虽然题目不限语言,但推荐 Node.js/TypeScript 因为:

  • 与前端统一语言,减少上下文切换
  • 可用 pkg(by Vercel)或 bun build --compile 打包为三平台二进制
  • JSON-RPC 处理已有成熟库可参考

备选方案:Go(天然跨平台编译,单 binary,但需要学两套语言);Python(生态好但 binary 打包重)。


五、项目文件结构

mini-notes-app/
├── manifest.json                 # Anna App 根清单
├── package.json                  # workspace root
├── pnpm-workspace.yaml           # pnpm monorepo 配置
├── README.md                     # 完整说明文档
│
├── ui/                           # 前端项目
│   ├── package.json
│   ├── vite.config.ts
│   ├── tsconfig.json
│   ├── index.html
│   └── src/
│       ├── main.tsx              # 入口:挂载 React + 连接 Anna
│       ├── App.tsx               # 根组件
│       ├── anna/                 # Anna Runtime 连接层
│       │   ├── runtime.ts        # AnnaAppRuntime.connect() 封装
│       │   ├── storage.ts        # anna.storage.get/set 封装
│       │   └── tools.ts          # anna.tools.invoke 封装
│       ├── components/           # UI 组件
│       │   ├── NoteList.tsx      # 笔记列表
│       │   ├── NoteItem.tsx      # 单条笔记
│       │   ├── NoteInput.tsx     # 创建笔记输入
│       │   ├── Summarize.tsx     # 总结按钮与结果
│       │   ├── EmptyState.tsx    # 空状态
│       │   └── ErrorBanner.tsx   # 错误提示
│       ├── hooks/                # 自定义 Hook
│       │   └── useNotes.ts       # 笔记 CRUD 状态管理
│       └── types.ts              # TypeScript 类型定义
│
├── executa/                      # Executa Tool
│   ├── executa.json              # Executa manifest
│   ├── package.json
│   ├── tsconfig.json
│   └── src/
│       ├── index.ts              # 入口:stdio 循环
│       ├── rpc.ts                # JSON-RPC 2.0 实现
│       ├── handlers/             # 方法处理器
│       │   ├── initialize.ts     # v2 capability negotiation
│       │   ├── describe.ts       # 返回 manifest
│       │   ├── invoke.ts         # summarize handler
│       │   ├── health.ts         # 健康检查
│       │   └── shutdown.ts       # 优雅退出
│       └── types.ts              # 类型定义
│
├── fixtures/                     # 测试 fixture
│   └── sampling-mock.jsonl       # --mock-sampling fixture
│
├── scripts/                      # 工具脚本
│   ├── build-executa.sh          # 本机二进制打包
│   ├── test-rpc.sh               # 手动 JSON-RPC 测试
│   └── build-executa.ps1         # Windows 打包脚本
│
└── .github/
    └── workflows/
        └── release.yml           # GitHub Actions release workflow

六、开发步骤

阶段 1:项目骨架(预计 1-2 小时)

步骤 任务 产出
1.1 初始化 monorepo(pnpm workspace) 根 package.json, pnpm-workspace.yaml
1.2 创建 manifest.json(Anna App 清单) manifest.json
1.3 初始化前端项目(React + Vite + TS) ui/ 目录, 可构建
1.4 初始化 Executa Tool 项目(Node.js + TS) executa/ 目录

阶段 2:Executa Tool 核心(预计 3-4 小时)

步骤 任务 产出
2.1 实现 JSON-RPC 2.0 over stdio 框架 读 stdin → 路由 → 写 stdout
2.2 实现 initialize handler v2 capability negotiation
2.3 实现 describe handler 返回 tool manifest
2.4 实现 health + shutdown handler 基础运维
2.5 实现 invoke handler(summarize) 构建 sampling 请求
2.6 实现 sampling/createMessage 反向请求 reverse JSON-RPC
2.7 手动测试 initialize/describe/invoke 验证 stdio 通信

阶段 3:前端核心(预计 3-4 小时)

步骤 任务 产出
3.1 实现 AnnaAppRuntime 连接层 runtime.ts
3.2 实现 anna.storage.* 封装 storage.ts
3.3 实现 anna.tools.invoke 封装 tools.ts
3.4 实现创建笔记(UI + storage.set) NoteInput.tsx
3.5 实现笔记列表(storage.get + 展示) NoteList.tsx, NoteItem.tsx
3.6 实现删除笔记(storage.set 更新) NoteItem 删除按钮
3.7 实现空状态 + 错误状态 EmptyState, ErrorBanner
3.8 实现 Summarize(tools.invoke + 结果展示) Summarize.tsx
3.9 配置 Vite 构建为 Anna App bundle vite.config.ts

阶段 4:Mock Sampling Fixture(预计 0.5 小时)

| 4.1 | 创建 sampling-mock.jsonl | fixtures/ 目录 |

阶段 5:集成测试(预计 1-2 小时)

步骤 任务 产出
5.1 anna-app validate --strict 通过校验
5.2 anna-app dev --no-llm UI 测试 创建/查看/删除正常
5.3 anna-app executa dev --mock-sampling sampling 路径验证
5.4 手动 JSON-RPC 测试 脚本或说明

阶段 6:打包与发布(预计 2-3 小时)

步骤 任务 产出
6.1 编写本机二进制打包脚本 scripts/build-executa.sh
6.2 验证 archive 结构 manifest + binary
6.3 编写 GitHub Actions workflow .github/workflows/release.yml
6.4 测试 release workflow 三平台 assets

阶段 7:文档(预计 1-2 小时)

| 7.1 | 编写 README.md | 覆盖所有验收标准 |


七、任务进度表

(详见 TASKS.md,此处为概览)

阶段 名称 状态 预计时间
1 项目骨架 ⬜ Pending 1-2h
2 Executa Tool 核心 ⬜ Pending 3-4h
3 前端核心 ⬜ Pending 3-4h
4 Mock Fixture ⬜ Pending 0.5h
5 集成测试 ⬜ Pending 1-2h
6 打包与发布 ⬜ Pending 2-3h
7 文档 ⬜ Pending 1-2h

总预计时间:12-18 小时


八、页面设计建议

8.1 页面结构

┌──────────────────────────────────────┐
│  Mini Notes                    [icon] │  ← 标题栏
├──────────────────────────────────────┤
│  ┌──────────────────────────────┐    │
│  │ 输入你的笔记...              │    │  ← 输入框
│  └──────────────────────────────┘    │
│  [保存]  [✨ Summarize 全部笔记]     │  ← 操作按钮
├──────────────────────────────────────┤
│  笔记列表 (3)                        │  ← 列表标题
│  ┌──────────────────────────────┐    │
│  │ 1. 明天跟客户 follow up  [✕] │    │  ← 笔记项
│  │ 2. 修复登录 bug          [✕] │    │
│  │ 3. Workshop 内容想法     [✕] │    │
│  └──────────────────────────────┘    │
├──────────────────────────────────────┤
│  📝 Summary                         │  ← 总结区(初始隐藏)
│  你记录了 3 条笔记,主要涉及...     │
└──────────────────────────────────────┘

8.2 信息层级

  1. 品牌/标题 → 用户知道这是什么 App
  2. 输入区 → 主要操作入口
  3. 笔记列表 → 核心内容
  4. 总结区 → 增强功能

8.3 组件状态矩阵

组件 正常态 空状态 加载态 错误态 禁用态
NoteInput 可输入 — 保存中... 保存失败提示 空内容时保存按钮禁用
NoteList 展示笔记 "还没有笔记,写一条吧" 加载中... "加载失败,请重试" —
NoteItem 内容 + 删除按钮 — 删除中... 删除失败提示 —
Summarize 按钮可点击 "没有笔记可总结" "正在总结..." [-32603] 错误 —

8.4 交互细节

  • 保存后清空输入框,光标回到输入框
  • 删除不需要确认弹窗(笔记很短,误删代价低),但可以做 1 秒的撤销 toast
  • Summarize 按钮在没有笔记时禁用
  • 错误信息使用红色/橙色文字,不是 alert 弹窗

8.5 如何让页面看起来像真实产品

  1. 品牌色:选一个主色(如 indigo-600),统一按钮、链接、图标
  2. 圆角:卡片 8px,按钮 6px,输入框 6px
  3. 阴影:列表卡片加轻微阴影 shadow-sm
  4. 间距:统一使用 4px 倍数(4/8/12/16/24/32)
  5. 字体:系统字体栈,标题稍大(16px),正文 14px
  6. 图标:使用简单的 emoji 或 SVG icon
  7. hover 效果:按钮 hover 变色,列表项 hover 加背景色
  8. 过渡动画:删除时 200ms fade out

九、知识库组织方案

9.1 应上传的资料

资料 作用 来源
Anna App 开发文档 理解 Host API、storage、tools staging.anna.partners/developers
示例仓库源码 Executa Tool 写法参考 github.com/whtcjdtc2007/anna-executa-examples
MCP Sampling 规范 理解 sampling/createMessage modelcontextprotocol.io
@anna-ai/app-runtime README SDK API 参考 npm
@anna-ai/cli README CLI 命令参考 npm
Executa binary distribution 文档 打包规范 staging.anna.partners/developers

9.2 Notebook 组织方式

Anna App 知识库
├── 1. 平台概念        ← Anna App 是什么,Host API 模型
├── 2. Storage API     ← anna.storage.get/set 用法
├── 3. Tools API       ← anna.tools.invoke 用法
├── 4. Executa Tool    ← JSON-RPC/stdio/manifest/sampling
├── 5. MCP Sampling    ← sampling/createMessage 协议细节
├── 6. CLI 命令        ← anna-app dev/validate/executa
├── 7. 二进制分发      ← 打包结构/platform key/archive 格式
└── 8. 示例代码        ← 参考仓库中的最佳实践

9.3 应向知识库提出的问题

  1. anna.storage.get 和 anna.storage.set 的完整签名和返回值格式是什么?
  2. anna.tools.invoke 的 tool_id 应该从哪里来?如何与 manifest 对应?
  3. Executa Tool 的 describe 返回的 manifest 完整结构是什么?
  4. sampling/createMessage 请求的完整字段有哪些?哪些是必须的?
  5. anna-app dev --no-llm 和 anna-app executa dev --mock-sampling 的区别是什么?
  6. 二进制 archive 的根目录 manifest.json 应该包含哪些字段?
  7. required_executas 和 ui.host_api.tools 如何保持一致?

9.4 如何避免回答脱离资料来源

  • 每个回答标注来源文档章节
  • 不确定的 API 行为先在本地用 anna-app dev 验证
  • 示例代码必须能在本地跑通再写入项目

十、可复用 Skill 设计

10.1 可沉淀的 Skill

Skill 名称 触发场景 价值
anna-app-init 初始化 Anna App 项目 一键生成骨架
anna-app-validate 提交前校验 自动跑 validate --strict
executa-dev 开发 Executa Tool 自动启动 dev + mock sampling
executa-build 打包二进制 自动识别平台打包
release-anna-app 发布 GitHub Release 三平台构建 + 上传

10.2 推荐的第一个 Skill:anna-app-init

这是最有复用价值的 Skill,每次新建 Anna App 都要做同样的事。

---
name: anna-app-init
description: 初始化一个 Anna App 项目骨架,包括 manifest.json、前端项目、Executa Tool 项目
---

# Anna App Init Skill

## 触发条件
用户说"创建 Anna App 项目"/"初始化 Anna App"/"new anna app"

## 执行步骤

1. 询问用户 App 名称和基本描述
2. 创建目录结构(manifest.json, ui/, executa/, fixtures/, scripts/, .github/)
3. 生成 manifest.json(含 schema, required_executas, permissions, ui, dev)
4. 初始化前端项目(Vite + React + TypeScript)
5. 初始化 Executa Tool 项目(Node.js + TypeScript + JSON-RPC 骨架)
6. 创建 mock sampling fixture 模板
7. 创建 README 模板
8. 运行 `pnpm install`

## 输出
- 完整的项目骨架
- 可立即 `anna-app dev --no-llm` 启动
- 可立即 `anna-app validate --strict` 通过

十一、专家评审意见

🎯 产品经理

维度 评价
最认可 核心链路清晰:创建→存储→总结,功能范围控制得好
最大问题 缺少"撤销删除"的用户体验考量,虽然题目不要求
修改建议 Summarize 按钮建议放在列表上方而非底部,方便用户随时看到
优先改一处 输入框应支持 Enter 键提交,降低操作成本

🖥️ 前端工程师

维度 评价
最认可 分层清晰(runtime/storage/tools → components → hooks)
最大问题 AnnaAppRuntime 连接是异步的,组件需要处理"连接中"状态
修改建议 用 React Context 包裹 anna 实例,避免 prop drilling
优先改一处 确保 Vite 构建产物是纯静态文件,manifest.json 的 ui.bundle.entry 指向正确的入口

⚙️ 后端工程师

维度 评价
最认可 Executa Tool 的 JSON-RPC/stdio 设计遵循标准协议
最大问题 stdin 逐行读取可能遇到多行 JSON(pretty-print),需处理
修改建议 使用 readline + JSON.parse 逐行解析,而不是简单的 split
优先改一处 stdout flush 必须在每次响应后立即执行,否则 host 会卡住

🤖 AI / 算法工程师

维度 评价
最认可 sampling 链路完整,从 tool invoke 到 createMessage 到响应
最大问题 prompt 设计直接影响总结质量,目前没看到 prompt 模板
修改建议 在 invoke handler 中设计 prompt 模板:"请用中文总结以下笔记:\n{notes}"
优先改一处 sampling/createMessage 的 maxTokens 应设为合理值(如 500),避免浪费

👤 用户

维度 评价
最认可 功能简单直接,没有学习成本
最大问题 删除按钮太小容易误触,且没有撤销
修改建议 删除按钮放在笔记右侧,用灰色 ✕ 图标,hover 变红
优先改一处 输入框 placeholder 改成更友好的文案:"写点什么..."

📋 项目评审老师

维度 评价
最认可 验收标准覆盖全面,README 要求详尽
最大问题 README 需要解释每个命令的"为什么",不只是"怎么做"
修改建议 在 README 中加入一段"Anna App 平台模型解释",展示关键链路
优先改一处 manifest.json 的字段必须有注释或 README 解释其含义

🏗️ 技术负责人

维度 评价
最认可 monorepo 结构合理,前端/Tool 分离清晰
最大问题 binary 打包选型未确定——pkg 已停止维护,bun build 不够成熟
修改建议 推荐使用 Node.js SEA (Single Executable Applications) 或改用 Go 实现 Executa
优先改一处 先确定 binary 打包方案并验证,这是最大风险点

十二、风险清单

风险 等级 影响 缓解措施
Binary 打包方案不可行 🔴 高 无法交付三平台二进制 优先验证,备选 Go 重写
Anna App SDK 版本不兼容 🟡 中 API 行为与预期不同 写死 SDK 版本号,README 注明
stdin/stdout 通信问题 🟡 中 Executa 不响应或响应乱序 充分测试 readline + flush
sampling 协议理解偏差 🟡 中 sampling 请求格式错误 参考 MCP 规范 + 示例仓库
GitHub Actions 权限问题 🟢 低 release 上传失败 使用标准 action,提前测试
Vite 构建产物不兼容 🟢 低 bundle 无法被 Anna App 加载 确保是纯静态文件,相对路径

十三、验收标准

# 标准 通过条件
1 安装依赖 pnpm install 无报错
2 构建前端 pnpm build 生成 ui/dist/
3 manifest 校验 anna-app validate --strict 通过
4 UI harness anna-app dev --no-llm 可访问
5 创建笔记 输入文字→保存→anna.storage.set 被调用
6 查看笔记 列表展示→anna.storage.get 被调用
7 删除笔记 点击删除→列表更新→anna.storage.set 被调用
8 Summarize(--no-llm) 点击→anna.tools.invoke 被调用→显示 [-32603] 错误
9 Executa sampling anna-app executa dev --mock-sampling fixture.jsonl 通过
10 sampling 证据 fixture/log 确认 sampling/createMessage 被发起
11 手动 RPC 测试 initialize/describe/invoke 均正常响应
12 二进制打包 本机脚本生成 archive,结构符合规范
13 GitHub Release workflow 触发→三平台 assets→smoke test 通过
14 README 覆盖所有要求主题

十四、第一步应该立刻做什么

🎯 立刻行动清单

  1. 阅读 Anna 开发者文档和示例仓库(2-3 小时)

    • 理解 Host API 的完整签名
    • 理解 Executa Tool 的 manifest 格式
    • 理解 binary distribution 的 archive 结构
    • 跑通示例仓库中的至少一个 Executa Tool
  2. 初始化项目骨架(30 分钟)

    • mkdir mini-notes-app && cd mini-notes-app
    • 创建 manifest.json
    • pnpm init + 配置 workspace
    • pnpm create vite ui --template react-ts
    • 创建 executa/ 目录
  3. 验证骨架可用(30 分钟)

    • 写一个最小可用的前端(只展示 "Hello Anna")
    • 写一个最小 Executa Tool(只实现 initialize + describe)
    • anna-app validate --strict 确认骨架正确
    • anna-app dev --no-llm 确认能加载
  4. 然后按照「六、开发步骤」阶段 1 → 2 → 3... 推进

⚠️ 重要提醒:先跑通"最小骨架可加载"再开始写业务代码。如果骨架都加载不了,后面都是白费。


本文档将随项目进展持续更新。下一步:创建 PROJECT.md、PLAN.md、TASKS.md 等管理文件。