Skip to content
Draft
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
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Verify Reflow demo

on:
push:
branches: [lsc]
pull_request:
branches: [lsc]

permissions:
contents: read

jobs:
verify:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Type check
run: npm run typecheck
- name: Lint
run: npm run lint
- name: Unit test
run: npm test
- name: Install Chromium for E2E
run: npx playwright install --with-deps chromium
- name: Core pipeline E2E
run: npm run test:e2e
- name: Static export
run: npm run export:web
49 changes: 49 additions & 0 deletions .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Deploy Reflow demo to GitHub Pages

on:
push:
branches: [lsc]

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Configure GitHub Pages
uses: actions/configure-pages@v5
- name: Export static web app
env:
GITHUB_PAGES: 'true'
run: npm run export:web
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v4
with:
path: dist

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

# Playwright
test-results/
playwright-report/

example

# generated native folders
/ios
/android
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "recommendations": ["expo.vscode-expo-tools"] }
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit",
"source.sortMembers": "explicit"
}
}
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Expo HAS CHANGED

Read the exact versioned docs at https://docs.expo.dev/versions/v57.0.0/ before writing any code.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
190 changes: 189 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,189 @@
# Reflow
# Reflow

Reflow 是一个移动优先的个人执行管理 Demo。它的目标不是再提供一个待办清单,而是把零散输入变成可以立刻开始的下一步行动,并让执行过程自然沉淀为回顾。

首版聚焦一条可在浏览器本地完整演示的闭环:

```text
捕捉事项 → 生成 Proposal → 编辑并接受 → 加入今天
→ 开始执行 → 记录耗时 / 进展 / 打断 → 完成 → 回顾更新 → 刷新后保留
```

> 当前是验证产品形态与交互的本地 Demo:不接真实 AI、后端、账号、云同步或第三方服务。

- 在线 Demo:[https://lsclin.github.io/Reflow/](https://lsclin.github.io/Reflow/)
- 当前开发分支:[lsclin/Reflow · lsc](https://github.com/lsclin/Reflow/tree/lsc)

## 显式 Pipeline 架构(非 Agent)

Reflow 第一版采用固定、可测试的 Pipeline,而不是通用 Agent:

```text
Capture → ProposalService → AIProposal → UserDecision
→ Task / Knowledge Outcome → Execution Logs → Deterministic Review
```

| 节点 | 输入 | 输出 | 失败与写入边界 |
| --- | --- | --- | --- |
| Capture Factory | Web 文本与来源元数据 | `InboxCapture` | 空文本返回结构化校验失败;当前实现 `webText`,模型已预留语音、邮件、飞书、日历、分享扩展和移动端快捷入口。 |
| ProposalService | `ProposalRequest` | `ProposalResult`(Proposal 集合或 `ProposalFailure`) | 失败可重试;Service 只能读取请求,不能访问 Store、Reducer、AsyncStorage 或任务数据写入接口。 |
| UserDecision | 待确认 Proposal 与用户编辑 | 持久化 `UserDecision` | 只有领域 Reducer 能创建、合并、拆分任务或创建知识卡片;忽略只拒绝 Proposal。 |
| Execution Logs | 明确领域动作 | 任务状态、`TimeEntry`、`ProgressLog` | 缺失任务、非法耗时、非法排期会返回结构化失败且不写入事实数据。 |
| Deterministic Review | 任务与执行事实 | `ReviewFacts` / `ReviewSummary` | 指标由程序计算;未来模型最多解释已计算事实,不能计算或覆盖关键指标。 |

`MockProposalService` 是可注入的默认 Provider。未来接入 OpenAI 或 Claude 时,只需要实现同一个 `ProposalService` 接口;UI、Store 和执行领域动作不需要改写。

这意味着首版**不实现** ReAct 循环、自主工具选择、多 Agent、长期自主运行或通用 Agent Runtime。重点是让每个步骤可靠、可追踪、可撤销。

## 当前状态

- 已完成:五页 Web Demo、完整核心闭环、显式 Pipeline、确定性 Mock Proposal、九种用户可见分类、可撤销决策事件、执行日志、计划与实际日历、派生回顾和本地持久化。
- 已验证:TypeScript、ESLint、31 个单元测试、3 条 Playwright E2E,以及普通与 GitHub Pages base path 两种静态导出。
- 自动化:`lsc` 每次 push 都会运行 CI 并部署 GitHub Pages;最新日历同步版本已经成功发布。
- 当前定位:第一版可演示 MVP 的必须项已经完成;拖拽、简化日/周视图、知识产物和额外 E2E 等增强能力已部分完成。当前重点是验证产品闭环与信息架构,不代表已经具备正式产品的云端与外部集成能力。

最初的里程碑与验收清单见 [docs/implementation-plan.md](docs/implementation-plan.md)。

## 页面与体验

| 路由 | 页面 | 用途 |
| --- | --- | --- |
| `/` | 今天 | 快速捕捉、查看今天清单、开始/暂停任务与调整顺序。 |
| `/inbox` | 收件箱 | 在“待你确认 / 最近处理”中理解并编辑 Proposal,选择任务去向或知识产物,并撤销最近一次安全可逆决定。 |
| `/active` | 进行中 | 管理唯一的当前执行任务,记录进展、耗时、打断、暂停或完成。 |
| `/calendar` | 日历 | 统一展示计划事项、今天清单中的未排期事项和实际完成记录;支持月视图、简化日/周视图、日期选择与空档建议。 |
| `/review` | 回顾 | 按日、周、月从实际任务与日志派生完成数、耗时、打断和分类分布。 |

桌面浏览器中应用内容会居中为单栏;手机浏览器中会铺满屏幕。左上角品牌入口包含“重置 Demo 数据”。

## 领域模型与规则

Reflow 明确区分“事项属于什么”和“事项现在在哪里”,避免将工作流状态混进内容分类。

| 维度 | 含义 |
| --- | --- |
| `TaskCategory` | 工作推进、沟通跟进、学习研究、生活事务、健康、未识别。 |
| `TaskStatus` | 未开始、进行中、已完成。 |
| `WorkflowBucket` | 收件箱、今天、等待他人、稍后处理、归档。 |
| `CaptureOutcome` | 任务、知识沉淀、忽略。 |

用户界面不会暴露这些内部维度,而是统一呈现九种“AI 归类结果”:工作推进、沟通跟进、学习研究、生活事务、健康、等待他人、稍后处理、知识沉淀、未识别。等待他人、稍后处理和知识沉淀在底层仍分别映射到工作流去向或产物类型。

主要事实对象是 `InboxCapture`、`AIProposal`、`UserDecision`、`TaskItem`、`KnowledgeCard`、`TimeEntry` 和 `ProgressLog`。`UserDecision` 会保存用户编辑内容、工作流去向、最终产物与可逆效果;刷新后最近一次未撤销决策仍可追踪和撤销。回顾结果不是持久化事实,而是根据任务和执行日志实时派生。

领域层使用明确动作:`startTask`、`pauseTask`、`completeTask`、`moveTask`、`recordTime`、`recordProgress`、`recordInterruption`、`scheduleTask` 和 `deleteTask`。同一时刻最多只能有一个进行中任务。

`MockProposalService` 使用固定关键词、拆分规则和重复事项识别生成建议;相同输入会获得相同结果,不使用随机数,也不声称是实际 AI。

日历内容同样只做确定性派生:有计划时间的任务出现在计划日;没有计划时间但仍在“今天”的未完成任务显示为“未排期”;完成任务按 `completedAt` 出现在实际完成日。计划日和完成日不一致时两天都会保留记录,同一天则按任务去重。

## 技术方案

- **应用框架**:Expo SDK 57、React 19、React Native 0.86、TypeScript。
- **路由与 Web**:Expo Router + React Native Web;静态导出由 Metro 完成。
- **状态管理**:React Context + Reducer,跨页面共享领域状态。
- **持久化**:`@react-native-async-storage/async-storage`,浏览器键保持为 `reflow.demo.v1`,领域数据版本为 v3,并自动迁移 v1/v2 数据。
- **排序**:Web 优先使用 `@dnd-kit`;非 Web 端保留上移/下移 fallback。
- **测试**:Jest + jest-expo 覆盖 Pipeline、Reducer、Mock Proposal、Selector、迁移与持久化;Playwright 覆盖核心闭环、收件箱和日历同步。

项目目录:

```text
src/
app/ Expo Router 路由与应用根布局
core/ Capture Factory、Pipeline、类型、Mock Proposal、Reducer、Selector、持久化与 Store
features/ 各页面及跨端共享 UI 组件
docs/ 产品执行清单与后续里程碑
```

## 本地启动

前置条件:已安装 Node.js 与 npm。可用下面命令确认环境:

```bash
node --version
npm --version
```

安装依赖并启动 Web 开发服务器:

```bash
npm install
npm run web
```

终端会显示访问地址,通常为 `http://localhost:8081`。也可以运行:

```bash
npm start
npm run android
npm run ios
```

首版以 Web 为验收目标;Android/iOS 命令用于验证共享路由与组件的后续复用能力。

## 建议的手动验收流程

1. 打开左上角品牌入口,点击“重置 Demo 数据”。
2. 在“今天”输入一个新事项,例如“推进季度复盘材料”。
3. 进入“收件箱”,确认 AI 整理结果和归类理由,再点击“确认并加入今天”。
4. 打开“日历”,确认新任务以“未排期”出现在今天。
5. 返回“今天”并开始该任务。
6. 在“进行中”记录一句进展、补记 15 分钟,然后完成任务。
7. 再次打开“日历”,确认任务变为“实际完成”;若计划日和完成日不同,两个日期应分别保留记录。
8. 打开“回顾”,确认完成数和实际耗时已更新。
9. 刷新页面,确认任务、决策、日历记录和回顾结果仍然保留。

## 检查、测试与导出

```bash
# TypeScript 类型检查
npm run typecheck

# ESLint
npm run lint

# 31 个单元测试:Capture Factory、Pipeline、Mock Proposal、Reducer、Selector、统计与持久化
npm test

# 3 条端到端流程:核心闭环、收件箱与日历同步
npm run test:e2e

# 静态 Web 导出,产物位于 dist/
npm run export:web
```

GitHub Pages 构建时需要带仓库前缀:

```bash
$env:GITHUB_PAGES = 'true'
npm run export:web
```

PowerShell 中可用下列命令预览导出产物:

```powershell
python -m http.server 4173 -d dist
```

然后访问 `http://localhost:4173`。首次运行 Playwright 时,如本机尚无浏览器运行时,执行 `npx playwright install chromium`。

推送到 `lsc` 会自动运行类型检查、lint、Jest、核心 E2E 和静态导出;随后以 `GITHUB_PAGES=true` 导出并部署到 Pages。fork 的 `github-pages` 环境已允许 `lsc` 发布;合并到上游后,应把部署触发分支切换为 `main`。

## 数据、隐私与重置

- Demo 数据只保存在当前浏览器,不会上传到服务器。
- 持久化内容仅包含领域数据:任务、捕捉及其 Pipeline 状态、Proposal、决策事件、耗时、进展和知识卡片。
- 弹窗开关、loading、toast、当前 Tab 等瞬时 UI 状态不会保存。
- 数据版本或内容损坏时会自动回退到种子数据。
- 可从左上角品牌入口使用“重置 Demo 数据”恢复初始演示状态。

## 协作约定

- 所有第一版开发都在 `lsc` 分支进行,不重写 `main` 历史,也不 force push。
- 当前上游仓库使用 Fork + Draft PR 协作方式;提交前应依次执行类型检查、lint、测试和静态导出。
- 新功能优先保障核心闭环,不让拖拽、复杂日/周视图、部署细节或额外动画阻塞主要体验。

## 首版范围外

首版暂不包括登录、云同步、真实 AI、邮件/飞书接入、系统日历、通知、语音识别、周期任务、复杂排程冲突、多人协作和原生安装包发布。日/周视图目前是简化日期视图,不包含完整时间网格。这些能力应在核心闭环稳定后逐步接入。
22 changes: 22 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { ConfigContext, ExpoConfig } from 'expo/config';

export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
name: 'Reflow',
slug: 'reflow',
version: '0.1.0',
orientation: 'portrait',
scheme: 'reflow',
userInterfaceStyle: 'light',
icon: './assets/images/icon.png',
web: {
output: 'static',
bundler: 'metro',
favicon: './assets/images/favicon.png',
},
plugins: ['expo-router'],
experiments: {
typedRoutes: true,
baseUrl: process.env.GITHUB_PAGES === 'true' ? '/Reflow' : undefined,
},
});
3 changes: 3 additions & 0 deletions assets/expo.icon/Assets/expo-symbol 2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/expo.icon/Assets/grid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading