ai-growth 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -343
- package/ROADMAP.md +48 -0
- package/dist/core/status.js +22 -4
- package/docs/agent.md +49 -0
- package/docs/development.md +74 -0
- package/docs/usage.md +217 -0
- package/package.json +3 -2
- package/scripts/smoke-device.mjs +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -1,383 +1,89 @@
|
|
|
1
1
|
# AI Growth
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
> Agent 请读 [AGENTS.md](./AGENTS.md)。
|
|
5
|
-
|
|
6
|
-
**Agent-native、Local-first 的个人成长执行系统。**
|
|
3
|
+
> **让 Agent 陪你成长。** 你说想成为什么样的人,Agent 把路铺到今天 —— 你每天只需要做今天这一件事。
|
|
7
4
|
|
|
8
5
|
[](https://www.npmjs.com/package/ai-growth)
|
|
9
6
|
[](./LICENSE)
|
|
10
7
|
[](https://nodejs.org)
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
> 第一次使用?看 [START-HERE.md](./START-HERE.md)(3 步开始 + 该对 Agent 说什么)。
|
|
10
|
+
> **Agent 请读 [AGENTS.md](./AGENTS.md)** —— 那是给 AI 的主入口,本文是给人看的。
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
npm install -g ai-growth
|
|
16
|
-
ai-growth migrate # 初始化本地数据库(数据在 ~/.ai-growth,与代码包完全分离)
|
|
17
|
-
ai-growth doctor # 环境自检
|
|
18
|
-
```
|
|
12
|
+
## 它是什么
|
|
19
13
|
|
|
20
|
-
|
|
14
|
+
`ai-growth` 是一个跑在**你自己电脑上**的个人成长系统。它把「目标 → 阶段 → 今天做什么」这条线交给 Agent 维护,把「目标是什么、要不要继续」留给你。
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
失败感来自"计划又崩了",而不是目标本身难。AI Growth 把这件事翻过来:
|
|
16
|
+
每天只给你 **1 件主线任务 + 0~2 件小事**;**昨天没做完的第二天自动过期**,不会攒成债务。你不需要自己排期、复盘、把任务搬到明天 —— 那些是 Agent 的事。
|
|
24
17
|
|
|
25
|
-
| | |
|
|
18
|
+
| 它是 | 它不是 |
|
|
26
19
|
|---|---|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
| **能落到一块小屏上** | 可选:把今天推给 AI Passport 设备(「今日任务卡」),做完按一下,卡片立刻变完成态 |
|
|
20
|
+
| 让 **Agent 帮你维护成长计划** 的系统 | 又一个待办清单(排期和搬运都不归你管) |
|
|
21
|
+
| 每天**只面对今天**的执行界面 | 打卡 App(没有连续天数、没有断签焦虑) |
|
|
22
|
+
| 用**可核对的事实**表达进度(`Stage 3 / 6`、证据条目) | 游戏化 RPG(**没有**属性值、等级、掌握度百分比、自律分) |
|
|
23
|
+
| **本地优先**:数据在自己机器上,不需要账号 | 云服务(不注册、不上传,离线也能跑) |
|
|
32
24
|
|
|
33
|
-
|
|
25
|
+
## 3 分钟开始
|
|
34
26
|
|
|
35
27
|
```bash
|
|
36
|
-
ai-growth
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
然后把 MCP 接进你常用的 Agent(见下方[接入 Agent](#接入-agent)),对它说一句
|
|
40
|
-
**「今天要做什么」**或**「开始今天的学习」**——第一次它会先访谈你,再排出第一份今日计划。
|
|
41
|
-
|
|
42
|
-
> 面板长这样(`?layout=widget` 是桌面组件紧凑布局):
|
|
43
|
-
|
|
44
|
-

|
|
45
|
-
|
|
46
|
-
<sub>图为设备端「今日任务卡」的全部卡面(与运行时同一套模板渲染)。</sub>
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
不是 Todo List,也不是虚构属性值 RPG。它的价值是:
|
|
52
|
-
|
|
53
|
-
> 用户不用持续维护计划;AI 维护计划,人保留目标、选择和最终确认权。
|
|
54
|
-
|
|
55
|
-
核心循环:
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
Human → Interview → Direction → Goal → Stage Plan → Daily Plan → Action
|
|
59
|
-
→ Evidence → Reflection → Growth Event → Memory → AI Passport → Next Plan
|
|
28
|
+
npm install -g ai-growth # 1. 安装
|
|
29
|
+
ai-growth init # 2. 初始化本地数据(数据在 ~/.ai-growth)
|
|
30
|
+
ai-growth mcp-config # 3. 打印 MCP 配置 → 粘进你的 Agent 并信任它
|
|
60
31
|
```
|
|
61
32
|
|
|
62
|
-
|
|
33
|
+
然后把 [`SKILL.md`](./SKILL.md) 交给 Agent 当行为准则,对它说一句:
|
|
63
34
|
|
|
64
|
-
|
|
65
|
-
2. 首次使用必须由 Agent 主动发起 Onboarding Interview,不允许直接生成任务。
|
|
66
|
-
3. Goal / 重要方向必须经用户确认。
|
|
67
|
-
4. 长期计划只规划到 Stage;Daily Action 每天动态生成,不提前硬编码整月。
|
|
68
|
-
5. 每天默认 `1 Main Quest + 0~2 Daily Actions`;长期改变默认负荷需用户确认。
|
|
69
|
-
6. **Daily Action 仅当天有效**:次日自动 `EXPIRED`,不产生跨天债务(不 clone 到第二天)。
|
|
70
|
-
7. **Main Quest 未完成不作废**:进入 `PENDING_REPLAN`,由 Agent 判断继续/拆分/延期。
|
|
71
|
-
8. Passport 是当前 Human State 的压缩快照,不是 Source of Truth(SoT = Growth DB + Memory)。
|
|
72
|
-
9. 所有状态变更必须经过 Core Service;MCP / Web 不直接写 DB。
|
|
73
|
-
10. 系统开机自启,不要求用户手工 `npm run mcp`。
|
|
35
|
+
> **「开始今天的学习」** 或 **「今天要做什么」**
|
|
74
36
|
|
|
75
|
-
|
|
37
|
+
第一次它会先**访谈你**(想成为什么样的人、为什么),再排出第一份今日计划。
|
|
38
|
+
**在你表态之前,它不会派任何任务** —— 这是写进代码的硬规则,不是"建议"。
|
|
76
39
|
|
|
77
|
-
##
|
|
40
|
+
## 它怎么工作
|
|
78
41
|
|
|
79
|
-
仓库根目录有三个文件专供 Agent 扫描识别:
|
|
80
|
-
|
|
81
|
-
| 文件 | 作用 |
|
|
82
|
-
|---|---|
|
|
83
|
-
| **`AGENTS.md`** | **Agent 入口**:是什么、怎么装、怎么接、怎么用、哪些规则不能违反 |
|
|
84
|
-
| `llms.txt` | 精简机器可读索引 |
|
|
85
|
-
| `server.json` | MCP Registry 清单(官方 schema 校验通过) |
|
|
86
|
-
|
|
87
|
-
Agent 拿到仓库后,一条命令就能自举——**不需要读源码**:
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
npx ai-growth help --json # 全部命令 + 产品规则 + 上手步骤
|
|
91
|
-
npx ai-growth agent-info --json # 安装路径、数据目录、MCP 配置片段、Skill 位置、下一步
|
|
92
|
-
npx ai-growth status --json # 当前状态 + suggestedNextOperation
|
|
93
42
|
```
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
### CLI
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
ai-growth help [--json] # 自描述:命令目录 + 产品铁律 + 上手步骤
|
|
102
|
-
ai-growth agent-info [--json] # Agent 引导信息
|
|
103
|
-
ai-growth info [--json] # 环境与运行状态
|
|
104
|
-
ai-growth status [--json] # 状态 + 建议下一步
|
|
105
|
-
ai-growth today [--json] # 今日计划
|
|
106
|
-
ai-growth goals|timeline|passport|metrics [--json]
|
|
107
|
-
ai-growth rollover [--json] # 跨天检查(幂等)
|
|
108
|
-
ai-growth complete|skip|delay <actionId> [...]
|
|
109
|
-
ai-growth mcp-config [--json] # 打印可粘贴的 MCP 配置
|
|
110
|
-
ai-growth skill # 打印 SKILL.md 全文
|
|
111
|
-
ai-growth doctor # 环境自检
|
|
112
|
-
ai-growth init # 初始化数据库
|
|
113
|
-
ai-growth serve # 前台启动常驻服务
|
|
43
|
+
你说想法 → Agent 访谈 → 方向 → 目标 → 阶段计划 → 今日计划 → 今日任务
|
|
44
|
+
↓
|
|
45
|
+
下一次对话 ← 记忆 ← 成长事件 ← 复盘 ← 证据 ← 完成 / 过期
|
|
114
46
|
```
|
|
115
47
|
|
|
116
|
-
|
|
117
|
-
避免 Agent 忘记加 `--json`;人类可读输出用 `--no-json`。
|
|
48
|
+
三条**不可协商**的规则(写在代码与测试里,不只写在文档里):
|
|
118
49
|
|
|
119
|
-
|
|
120
|
-
|
|
50
|
+
1. **AI 管路线,人决定目的地。** 它不替你决定人生方向。
|
|
51
|
+
2. **每天只推今天。** 每日任务次日必定过期,绝不顺延成跨天债务。
|
|
52
|
+
3. **不编数值。** 进度只用可核对的事实表达;任何"属性值 / 掌握度 % / 自律分 / 等级"都会被测试拦下。
|
|
121
53
|
|
|
122
|
-
##
|
|
54
|
+
## 你会看到什么
|
|
123
55
|
|
|
124
|
-
|
|
125
|
-
|
|
56
|
+
- **面板**:`http://localhost:4580`,网页形态,也可以当桌面组件(`?layout=widget`)
|
|
57
|
+
- **对话**:平时你就是在 Agent 里说一句话,不必打开面板
|
|
58
|
+
- **可选的小屏**:把今天推给 AI Passport 设备,做完按一下,卡片立刻变成完成态
|
|
126
59
|
|
|
127
|
-
|
|
128
|
-
cd "该项目目录"
|
|
129
|
-
./scripts/install.sh # 默认开发态:npm link(全局 ai-growth → 当前源码)
|
|
130
|
-
./scripts/install.sh --global # 生产态:npm pack + npm install -g(与源码检出解耦)
|
|
131
|
-
```
|
|
60
|
+

|
|
132
61
|
|
|
133
|
-
|
|
134
|
-
→ launchd 常驻服务(指向全局 CLI)→ MCP 配置 → Agent 入口说明 → doctor。
|
|
62
|
+
<sub>图为设备端「今日任务卡」的全部卡面,与运行时同一套模板渲染。</sub>
|
|
135
63
|
|
|
136
|
-
|
|
64
|
+
## 常见问题
|
|
137
65
|
|
|
138
|
-
|
|
|
66
|
+
| 问题 | 回答 |
|
|
139
67
|
|---|---|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
随时用 `ai-growth where` 查看当前是哪一种形态、代码在哪、数据在哪、该怎么更新。
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
## 接入 Agent
|
|
150
|
-
|
|
151
|
-
两步:**Skill** + **MCP**。
|
|
152
|
-
|
|
153
|
-
**MCP**(给出 `node` 与项目绝对路径):
|
|
154
|
-
|
|
155
|
-
```json
|
|
156
|
-
{
|
|
157
|
-
"mcpServers": {
|
|
158
|
-
"ai-growth": {
|
|
159
|
-
"command": "/path/to/node",
|
|
160
|
-
"args": ["/absolute/path/to/dist/mcp/server.js"],
|
|
161
|
-
"env": { "AI_GROWTH_DATA_DIR": "/Users/you/.ai-growth" }
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**Skill**:把仓库根目录的 `SKILL.md` 交给 Agent。WorkBuddy 用户级安装:
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
mkdir -p ~/.workbuddy/skills/ai-growth && cp SKILL.md ~/.workbuddy/skills/ai-growth/
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
接好后对 Agent 说一句 **「开启今日任务」**(同义:「今天要做什么」「开工」)——它会调用 `growth_status`,按状态决定下一步;首次使用会主动开始访谈,而不是直接派任务。
|
|
174
|
-
|
|
175
|
-
## 启动
|
|
176
|
-
|
|
177
|
-
| 服务 | 命令 | 说明 |
|
|
178
|
-
|---|---|---|
|
|
179
|
-
| 常驻 Daemon | 安装后由 launchd 托管(`ai-growth serve` 手动前台) | **同时提供调度(rollover + 提醒 + 同步重试)与面板 API** |
|
|
180
|
-
| MCP Server(stdio,由 Agent 拉起) | `ai-growth` MCP 配置指向全局安装 | 平时无需手动运行 |
|
|
181
|
-
| 面板 | http://127.0.0.1:4580(daemon 自带) | 单独跑用 `npm run api` |
|
|
182
|
-
| 健康检查 | `ai-growth doctor` 或 `bash scripts/doctor.sh` | 逐项验证环境(含构建新鲜度) |
|
|
183
|
-
| 数据库迁移 | `ai-growth migrate` | 幂等,可重复执行 |
|
|
184
|
-
| 清理构建产物 | `npm run clean` | 删除 `dist/`(`build` 已内置) |
|
|
185
|
-
|
|
186
|
-
daemon 与面板合成一个进程是刻意的:面板要能当桌面组件/桌面应用用,就必须和 daemon 同生命周期,
|
|
187
|
-
否则用户每次重启还得手工起面板——违反「不要求用户维护系统」。
|
|
188
|
-
|
|
189
|
-
## 面板(游戏面板式 HUD)
|
|
190
|
-
|
|
191
|
-
`http://127.0.0.1:4580`
|
|
192
|
-
|
|
193
|
-
深色面板风格:卡片式布局、阶段节点轨道、主任务高亮卡、事实计数条。
|
|
194
|
-
|
|
195
|
-
**🔴 面板上不会出现虚构数值。** 这是你自己定的铁律(核心原则 6 / §16.3 明确禁止六维属性、EXP、等级、
|
|
196
|
-
掌握度百分比、自律分)。所以面板的「游戏感」只体现在**视觉语言**上——卡片、发光描边、节点轨道、状态色——
|
|
197
|
-
而每一个数字都是可核对事实:
|
|
198
|
-
|
|
199
|
-
| 显示 | 来源 |
|
|
200
|
-
|---|---|
|
|
201
|
-
| `Stage 2 / 5` | Stage 序号与总数 |
|
|
202
|
-
| 已完成主任务 / 证据总数 / 成长记录 | 数据库计数 |
|
|
203
|
-
| 阶段节点轨道 | 各 Stage 的真实 status |
|
|
204
|
-
| 最近进展 | Growth Event(每条都挂着 Evidence) |
|
|
205
|
-
|
|
206
|
-
页面:**面板**(Progress First:当前主线 → 阶段轨道 → 今天最重要的一步 → 每日维护 → 累计事实 → 最近进展)、
|
|
207
|
-
**主线**(Goal 的 why/outcome/成功标准 + Stage Timeline)、**记录**(Growth Events + Evidence 流,含强度标签)、
|
|
208
|
-
**护照**(Passport 快照)、**设置**(时区、提醒渠道、手动跨天检查)。
|
|
209
|
-
|
|
210
|
-
支持 URL 深链:`#goals`、`#timeline`、`#settings`。
|
|
211
|
-
|
|
212
|
-
### 桌面组件 / 打包成桌面应用
|
|
68
|
+
| 我的数据在哪? | `~/.ai-growth/growth.db`(本地 SQLite)。代码包与数据完全分离,更新不影响数据 |
|
|
69
|
+
| 需要注册账号吗? | **不需要**。没有账号体系,也没有任何上传;服务只监听本机 |
|
|
70
|
+
| 一定要用 MCP 吗? | 不一定。Agent 不支持 MCP 时可用 CLI(`ai-growth status/today/complete`,全部支持 `--json`) |
|
|
71
|
+
| 会不会给我打自律分? | 不会。这是硬规则,见上文第 3 条 |
|
|
72
|
+
| 怎么卸载? | 见 [安装与使用](./docs/usage.md) 里的「卸载 / 重置」 |
|
|
213
73
|
|
|
214
|
-
|
|
74
|
+
## 给 Agent
|
|
215
75
|
|
|
216
|
-
|
|
217
|
-
实测 360px / 430px 宽均无横向溢出。
|
|
218
|
-
2. **无构建步骤**:纯 HTML/CSS/JS,任何 WebView 都能直接托管。状态全来自本地 API,
|
|
219
|
-
应用本身只是"视图",daemon 照常headless 运行。
|
|
220
|
-
|
|
221
|
-
后续打包路径(按成本从低到高):
|
|
222
|
-
|
|
223
|
-
| 方案 | 说明 | 成本 |
|
|
224
|
-
|---|---|---|
|
|
225
|
-
| 浏览器固定窗口 | Safari/Chrome 加到程序坞,加载 `http://localhost:4580/?layout=widget` | 0 |
|
|
226
|
-
| Übersicht 桌面组件 | 直接渲染 HTML 到桌面层,最贴近"在桌面上显示" | 低 |
|
|
227
|
-
| Tauri v2 | 体积小(~5MB),需 Rust;可做无边框 + 常驻置顶 | 中 |
|
|
228
|
-
| Electron | 无需 Rust,体积大(~150MB);`frame:false, transparent, alwaysOnTop` | 中 |
|
|
229
|
-
|
|
230
|
-
⚠️ **打包时必须让 WebView 加载 `http://localhost:4580`,不要用 `file://` 打开 index.html**:
|
|
231
|
-
页面 origin 为 `null` 时浏览器会按 CORS 拦掉对本地 API 的请求。加载 localhost 时 Host 校验也正好放行。
|
|
232
|
-
|
|
233
|
-
## 连上 AI Passport 设备
|
|
234
|
-
|
|
235
|
-
把固件刷到设备之后,让设备连上这台电脑**只需要一条命令**(它会自己确认成功):
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
ai-growth device setup --ssid "你的Wi-Fi名" --pass "Wi-Fi密码"
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
- 它会自动找到串口、写好配置、顺手开启并记住「局域网访问」,然后**等设备真的取到卡**再回报结果
|
|
242
|
-
- Wi-Fi 名含中文或空格也没关系(会自动改用十六进制编码:设备控制台本身只能收 ASCII)
|
|
243
|
-
- 设备之后每次开机都会自动连上并显示今天的卡,**不需要按任何键**
|
|
244
|
-
- 想先看当前状态/本机地址/令牌:`ai-growth device`
|
|
245
|
-
- 失败时它给出的不是错误码,而是**下一步该做什么**(连不上 Wi-Fi/够不到电脑/服务没起来)
|
|
246
|
-
|
|
247
|
-
设备上的按键:**上/下** 翻今天的卡,**确定** 完成当前这件事,**长按确定** 回到设备自带的演示菜单。
|
|
248
|
-
屏幕 1 分钟无操作会自动熄屏,按任意键立刻亮回。
|
|
249
|
-
|
|
250
|
-
## 安全边界(没有账号体系)
|
|
251
|
-
|
|
252
|
-
这不是一个需要登录的产品——它是本机进程 + Agent 工具。安全边界是 **loopback**,不是登录:
|
|
253
|
-
|
|
254
|
-
- 只监听 `127.0.0.1`,不对外暴露
|
|
255
|
-
- 校验 `Host` 头:只接受 `127.0.0.1` / `localhost` / `[::1]`,其余返回 `403 FORBIDDEN_HOST`
|
|
256
|
-
(挡住浏览器里任意网页通过 DNS rebinding / CSRF 驱动你的 Growth 数据)
|
|
257
|
-
- 静态资源做目录穿越防护
|
|
258
|
-
|
|
259
|
-
需要局域网访问时自行加反向代理与鉴权,不要直接把端口绑到 `0.0.0.0`。
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
## 数据位置
|
|
263
|
-
|
|
264
|
-
| 内容 | 路径 |
|
|
265
|
-
|---|---|
|
|
266
|
-
| 数据库 | `~/.ai-growth/growth.db`(WAL 模式) |
|
|
267
|
-
| Passport 输出 | `~/.ai-growth/passport.json` |
|
|
268
|
-
| Daemon 日志 | `~/.ai-growth/daemon.log`、`daemon-stderr.log` |
|
|
269
|
-
| 配置 | 项目根 `.env`(参考 `.env.example`)或 `~/.ai-growth/config.env` |
|
|
270
|
-
| launchd plist | `~/Library/LaunchAgents/com.lairey.ai-growth.daemon.plist` |
|
|
271
|
-
|
|
272
|
-
备份 = 复制 `~/.ai-growth/growth.db`。所有数据默认只在本机;外部同步必须显式配置 Adapter。
|
|
273
|
-
|
|
274
|
-
## 卸载 / 重置
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
./scripts/uninstall.sh # 停止并移除 launchd 服务,数据保留
|
|
278
|
-
./scripts/uninstall.sh --purge # 额外删除数据目录(需输入 yes 二次确认)
|
|
279
|
-
|
|
280
|
-
./scripts/reset-dev-data.sh --list # 只看数据概况,不做任何修改
|
|
281
|
-
./scripts/reset-dev-data.sh # 备份现有数据 → 建一个干净新库
|
|
282
|
-
./scripts/reset-dev-data.sh --force # 跳过"疑似真实数据"拦截
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
`reset-dev-data.sh` 永不静默删数据:它把数据目录改名备份,并打印回滚命令。
|
|
286
|
-
|
|
287
|
-
## 故障排查
|
|
288
|
-
|
|
289
|
-
| 现象 | 原因 / 处理 |
|
|
290
|
-
|---|---|
|
|
291
|
-
| Agent 说连不上 MCP | `bash scripts/doctor.sh` 看 MCP 一节;确认 `dist/mcp/server.js` 存在(`npm run build`) |
|
|
292
|
-
| **改了代码但行为没变** | **`dist/` 陈旧**。`npm run build`(已内置 `rm -rf dist`,幂等);`doctor.sh` 会检测 `dist ≠ src` |
|
|
293
|
-
| Web UI 打开是空白页 | 静态资源 MIME 必须正确(`.js` 不能用 `text/html` 返回)。若手工改过 server 需重启 `npm run api` |
|
|
294
|
-
| 重启后提醒不触发 | `launchctl list \| grep ai-growth`;未加载则 `launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.lairey.ai-growth.daemon.plist` |
|
|
295
|
-
| daemon 反复退出 | 看 `~/.ai-growth/daemon-stderr.log` |
|
|
296
|
-
| 时间不对 / 日期错乱 | Web UI → Settings 设置正确 timezone(自然日判断依据,非 UTC 截断) |
|
|
297
|
-
| 提醒太吵 | Settings 把 Reminder Channel 设为「关闭提醒」;每个 Daily 默认最多 1 次提醒 |
|
|
298
|
-
| 昨日任务还挂在今天 | Web UI 打开时会自动执行 rollover;也可在 Settings 手动执行 / 让 Agent 调 `run_daily_rollover` |
|
|
299
|
-
| `ONBOARDING_REQUIRED` 报错 | 未完成首次访谈就调了 `plan_today`——这是结构性保护,先完成访谈 |
|
|
300
|
-
| `REPLAN_REQUIRED` 报错 | 有未处理的 Replan,先让 Agent 调 `replan` 再规划新主线 |
|
|
301
|
-
| 想确认状态机没被绕过 | `audit_log` 表记录了关键变动(含 Replan 决策)的 before/after 与原因 |
|
|
302
|
-
| 面板打不开 / 白屏 | 面板由 daemon 提供:`bash scripts/doctor.sh` 看「面板 API」;单跑用 `npm run api`。白屏多半是 MIME 不对,重启进程即可 |
|
|
303
|
-
| 打包后 API 调用失败 | WebView 必须加载 `http://localhost:4580`,不能用 `file://`(origin 为 null 会被 CORS 拦) |
|
|
304
|
-
|
|
305
|
-
## 开发
|
|
306
|
-
|
|
307
|
-
```bash
|
|
308
|
-
npm run typecheck # tsc --noEmit
|
|
309
|
-
npm test # 118 个测试(unit + integration + e2e + dist 运行时冒烟)
|
|
310
|
-
npm run build # 幂等:先 rm -rf dist 再编译并拷贝资源
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
> **`npm test` 里有一层「运行时冒烟」**:它直接启动编译后的 `dist/mcp/server.js` 并按 MCP 协议调用工具。
|
|
314
|
-
> 这层测试专门覆盖"只有打包后才暴露"的问题(资源拷贝路径、migration 陈旧、MIME 等)——
|
|
315
|
-
> 源码测试全绿但产物是坏的,就是靠它发现的。同时也校验 `dist` 与 `src` 逐字节一致。
|
|
316
|
-
|
|
317
|
-
工程结构:
|
|
318
|
-
|
|
319
|
-
```
|
|
320
|
-
src/
|
|
321
|
-
├── core/ # 领域层:状态机、Goal/Stage/Action、Rollover、Replan、Evidence、Memory、Metrics
|
|
322
|
-
├── db/ # SQLite 连接 + 版本化 migration
|
|
323
|
-
├── mcp/ # MCP Server + 63 个 tools(统一 ToolResult 契约)
|
|
324
|
-
├── planner/ # 规划上下文与约束(LLM 判断交给 Agent,Core 只保证规则)
|
|
325
|
-
├── reminder/ # 提醒生命周期 + Scheduler + 通知 Adapter
|
|
326
|
-
├── passport/ # Passport 构建 + Sync Adapter(local-json / 可替换)
|
|
327
|
-
├── api/ # 供 Web UI 使用的 HTTP API
|
|
328
|
-
├── ui/ # Today / Goals / Timeline / Passport / Settings
|
|
329
|
-
├── daemon/ # 常驻进程入口
|
|
330
|
-
└── shared/ # 配置、时间(timezone 感知)、统一结果类型
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### 架构约定
|
|
334
|
-
|
|
335
|
-
- **状态机是唯一权威**(`src/core/stateMachine.ts`)。非法转换抛 `INVALID_STATE`,不静默通过。
|
|
336
|
-
- `IN_PROGRESS` 是**可选**中间态:`PLANNED → COMPLETED` 合法(用户说"做完了"不该被要求先点"开始")。
|
|
337
|
-
- 任何未终结的 DAILY 都能跨天 `EXPIRED`(含 `IN_PROGRESS` / `DELAYED`),否则 rollover 会崩。
|
|
338
|
-
- **Core 强制业务规则,MCP 层不重复声明**:zod schema 只做类型校验,`0~2 个 Daily`、`Goal 必须含 why` 这类规则由 Core 抛出带错误码的 `ToolResult`,保证返回结构统一。
|
|
339
|
-
- **结构性优先于文档约定**:`ONBOARDING_REQUIRED`(未访谈不得生成任务)、`REPLAN_REQUIRED`(先解决 Replan 再开新主线)都由 Core 强制,不依赖 Agent"记得遵守"。
|
|
340
|
-
- **时间**:DB 存 ISO timestamp;「哪一天」一律按配置时区计算(`src/shared/time.ts`),绝不按 UTC 截断。
|
|
341
|
-
- **幂等**:rollover(日期级 + action 级)、reminder 取消、sync job 创建、daemon 重启均可重复执行。
|
|
342
|
-
- **排序必须带稳定 tiebreaker**:SQLite 用 `updated_at DESC, rowid DESC`;`created_at` 同毫秒撞车时不可作为唯一排序键。
|
|
343
|
-
- **审计**:关键变动(含 Replan 决策本身)写入 `audit_log`(谁触发 / before / after / 原因 / 时间)。
|
|
344
|
-
|
|
345
|
-
## 当前限制
|
|
346
|
-
|
|
347
|
-
- V1 不含:六维属性 / EXP / 等级、RPG 装备、Knowledge Graph UI、课程平台、社交排名、云端账号、多人协作(均为预留接口,不阻塞上线)。
|
|
348
|
-
- Passport 外部同步:仅实现 `local-json` Adapter;接真实外部 API 时实现 `PassportSyncAdapter` 接口即可,失败会进重试队列且不影响本地状态。
|
|
349
|
-
- 通知渠道:已实现 macOS 本地通知(osascript)与 `null` 两种 Adapter。
|
|
350
|
-
- 提醒精确定时依赖 daemon 轮询(默认 30s 粒度),非秒级精确。
|
|
351
|
-
- 面板**没有账号体系也刻意不做**(本机进程 + Agent 工具,loopback 即边界)。如需局域网访问请自行加代理与鉴权。
|
|
352
|
-
- 桌面应用打包尚未实施:面板已就绪(紧凑布局 + 无构建步骤),打包属独立交付项。
|
|
353
|
-
|
|
354
|
-
详见 `DELIVERY_REPORT.md` 与 `IMPLEMENTATION_PLAN.md`。
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## 参与贡献
|
|
359
|
-
|
|
360
|
-
欢迎 Issue 与 PR。这个项目有几条**不可协商**的产品铁律(见文首「核心原则」),
|
|
361
|
-
改动前请先确认不违背它们——尤其是这两条最容易在实现里被悄悄破坏:
|
|
362
|
-
|
|
363
|
-
- **不产生虚构数值**:任何"属性值 / 掌握度 % / 自律分 / 等级"都会被测试拦下;
|
|
364
|
-
- **不制造跨天债务**:`Daily Action` 次日必须 `EXPIRED`,绝不 clone 到第二天。
|
|
365
|
-
|
|
366
|
-
提交前请跑:
|
|
367
|
-
|
|
368
|
-
```bash
|
|
369
|
-
npm run build && npx tsc --noEmit && npm test && bash scripts/doctor.sh
|
|
370
|
-
```
|
|
76
|
+
**Agent 请读 [`AGENTS.md`](./AGENTS.md)**(主入口);行为准则是 [`SKILL.md`](./SKILL.md);精简索引是 [`llms.txt`](./llms.txt)。
|
|
371
77
|
|
|
372
|
-
##
|
|
78
|
+
## 进一步阅读
|
|
373
79
|
|
|
374
|
-
|
|
|
80
|
+
| 文档 | 内容 |
|
|
375
81
|
|---|---|
|
|
376
|
-
| [START-HERE.md](./START-HERE.md) |
|
|
377
|
-
| [
|
|
378
|
-
| [
|
|
379
|
-
| [
|
|
380
|
-
| [
|
|
82
|
+
| [`START-HERE.md`](./START-HERE.md) | 第一次使用:3 步 + 该对 Agent 说什么 |
|
|
83
|
+
| [`docs/usage.md`](./docs/usage.md) | 安装与使用细节:接入 Agent、面板与桌面组件、设备、数据位置、卸载、故障排查 |
|
|
84
|
+
| [`docs/agent.md`](./docs/agent.md) | 给 Agent / 自动化:自动发现清单与 CLI 参考 |
|
|
85
|
+
| [`docs/development.md`](./docs/development.md) | 开发、架构约定、当前限制、参与贡献 |
|
|
86
|
+
| [`PRODUCT_SPEC.md`](./PRODUCT_SPEC.md) | 完整产品规范(想知道"为什么这么设计") |
|
|
381
87
|
|
|
382
88
|
## 许可
|
|
383
89
|
|
package/ROADMAP.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# 路线图与当前状态
|
|
2
|
+
|
|
3
|
+
> 给「接手这个项目的下一个人 / 下一个 Agent」看:现在到哪了、下一步做什么、有哪些坑。
|
|
4
|
+
> 更新于 2026-09-21。
|
|
5
|
+
|
|
6
|
+
## 现状(已完成并有验证)
|
|
7
|
+
|
|
8
|
+
| 项 | 状态 |
|
|
9
|
+
|---|---|
|
|
10
|
+
| Host app(CLI + MCP server + Web 面板 + 设备接入) | ✅ 可用;**197 个测试通过** |
|
|
11
|
+
| npm 发布 | ✅ [`ai-growth@1.1.1`](https://www.npmjs.com/package/ai-growth)(`npm i -g ai-growth` 实测可用) |
|
|
12
|
+
| AI Passport 玩法(设备端) | ✅ 已提交社区审核:projectId `566` / revisionId `1164` / **状态 `pending`(未公开)** |
|
|
13
|
+
| 设备真机联调 | ✅ 已实测,含「电池供电开机纯白屏」根因修复 |
|
|
14
|
+
| 文档结构 | ✅ README 给人看;`AGENTS.md` / `SKILL.md` / `llms.txt` 给 Agent;细节在 `docs/` |
|
|
15
|
+
|
|
16
|
+
## 下一步(按优先级)
|
|
17
|
+
|
|
18
|
+
1. **建公开仓库并推一次** — `package.json` / `server.json` / README 都已指向
|
|
19
|
+
`github.com/lairey-ai/ai-growth`,但仓库尚不存在 → npm 页面上的图片与文档链接现在是空的。
|
|
20
|
+
2. **等玩法审核结果** → 通过后更新玩法,把使用方法的准备步骤补上
|
|
21
|
+
`npm install -g ai-growth`(提交时只写了 `ai-growth serve`,没说怎么装)。
|
|
22
|
+
⚠️ 玩法当前有 pending 修订,**不得再提交新修订**,必须等结果。
|
|
23
|
+
3. **Windows 支持** — `ai-growth device setup` 依赖系统的 `stty` 把串口设为 raw(Node 没有 termios),
|
|
24
|
+
Windows 上没有该命令:要么明确提示不支持,要么在 Node 里直接设置串口参数。
|
|
25
|
+
4. **离线卡文案** — 设备离线卡只说"暂时连不上电脑",应补一句
|
|
26
|
+
「在电脑上重跑 `ai-growth device setup`」;否则换过 Wi-Fi 的用户不知道该做什么。
|
|
27
|
+
5. **收尾清理** — `~/.npmrc` 里存着 npm 发布令牌(可随时在 npm 后台撤销)。
|
|
28
|
+
|
|
29
|
+
## 已知约束(都踩过,别再踩)
|
|
30
|
+
|
|
31
|
+
- 🔴 **Node 版本分裂**:本机 shell 是 **Node 24**,而 `better-sqlite3` 按 **Node 22** 编译
|
|
32
|
+
→ 用 Node 24 跑 `npm test` 或全局 `ai-growth` 会因 ABI 不匹配整片失败。
|
|
33
|
+
**根治**:`brew install node@22` → 把它的 `bin` 放到 PATH 中 `/usr/local/bin` 之前 →
|
|
34
|
+
`npm rebuild better-sqlite3`。**发布时必须 `npm publish --ignore-scripts`**(跳过 prepublishOnly)。
|
|
35
|
+
- 🔴 **升版本要改两处**:`package.json` **和** `server.json`(后者版本必须与前者一致,有测试锁定)。
|
|
36
|
+
- 🔴 **npm 令牌权限**:必须选 **All packages**;选 "Only select packages" 时**发不了一个还不存在的包**。
|
|
37
|
+
- 🔴 **`ai-growth` 不在默认 PATH 上**:全局 bin 在 `~/.npm-global/bin`,只在用户的 zshrc 里加了 PATH。
|
|
38
|
+
非交互 shell(脚本、定时任务、Agent 会话)里必须显式用
|
|
39
|
+
`PATH="$HOME/.npm-global/bin:/Users/fuhaojie/.workbuddy/binaries/node/versions/22.22.2-3/bin:$PATH"`,
|
|
40
|
+
或直接调绝对路径 `"$HOME/.npm-global/bin/ai-growth"` —— 否则 `command not found`。
|
|
41
|
+
- 🔴 **常驻服务不随代码更新自动重启**:更新后用
|
|
42
|
+
`launchctl kickstart -k "gui/$(id -u)/com.lairey.ai-growth.daemon"`。
|
|
43
|
+
排查"服务没在跑"的完整步骤见 `docs/usage.md`。
|
|
44
|
+
- 🔴 **本机构建**:`npm run build` 里的 `rm -rf dist` 会被批量删除保护拦下 →
|
|
45
|
+
改用 `npx tsc -p tsconfig.json` + 手动 `cp` 资源(等价;`dist` 有逐字节一致性测试兜底)。
|
|
46
|
+
- ⚠️ **时间处理**:`dateKey` 一律由服务端按配置时区算;客户端**不要**对 ISO 串 `slice(0,10)`(会差一天)。
|
|
47
|
+
- ⚠️ **产品铁律不可违背**(见 README 与 `PRODUCT_SPEC.md`):不编数值、不制造跨天债务、
|
|
48
|
+
首次使用必须先访谈。改动前先看 `AGENTS.md` 里的禁止事项。
|
package/dist/core/status.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getProfile, ensureProfile, getSetting } from './profile.js';
|
|
2
|
-
import { getActiveGoals, getCurrentStage } from './goals.js';
|
|
2
|
+
import { getActiveGoals, getCurrentStage, listGoals, listStages } from './goals.js';
|
|
3
3
|
import { getTodayPlan } from './actions.js';
|
|
4
4
|
import { hasPendingReplan } from './rollover.js';
|
|
5
5
|
import { getActiveLifeContext } from './lifeContext.js';
|
|
@@ -14,9 +14,15 @@ export function growthStatus(ctx) {
|
|
|
14
14
|
: profile.onboardingStatus === 'IN_PROGRESS'
|
|
15
15
|
? 'IN_PROGRESS'
|
|
16
16
|
: 'COMPLETED';
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// ⚠️ 不能只看 ACTIVE 目标。目标处于 DRAFT(草稿待确认)或 CONFIRMED(已确认、尚未激活)时,
|
|
18
|
+
// getActiveGoals() 也是空的 —— 于是这里会走到"没有目标 → 去聊目标",
|
|
19
|
+
// 而用户明明已经访谈完、目标也确认过了。真机上就是这么把人卡住的:
|
|
20
|
+
// status 说 DISCUSS_GOAL,但该做的是"排阶段计划"。
|
|
21
|
+
const openGoals = listGoals(ctx, ['DRAFT', 'CONFIRMED', 'ACTIVE']);
|
|
22
|
+
const goals = openGoals.filter((g) => g.status === 'ACTIVE');
|
|
23
|
+
const primaryGoal = goals[0] ?? openGoals.find((g) => g.status === 'CONFIRMED') ?? openGoals[0];
|
|
19
24
|
const stage = primaryGoal ? getCurrentStage(ctx, primaryGoal.id) : null;
|
|
25
|
+
const hasStage = primaryGoal ? listStages(ctx, primaryGoal.id).length > 0 : false;
|
|
20
26
|
const { plan, actions: todayActionsAll } = getTodayPlan(ctx);
|
|
21
27
|
const life = getActiveLifeContext(ctx);
|
|
22
28
|
const passportUpdated = getSetting(ctx, 'passport_last_generated_at') ?? undefined;
|
|
@@ -27,9 +33,21 @@ export function growthStatus(ctx) {
|
|
|
27
33
|
else if (hasPendingReplan(ctx)) {
|
|
28
34
|
suggested = 'RESOLVE_REPLAN';
|
|
29
35
|
}
|
|
30
|
-
else if (
|
|
36
|
+
else if (openGoals.length === 0) {
|
|
31
37
|
suggested = 'DISCUSS_GOAL';
|
|
32
38
|
}
|
|
39
|
+
else if (openGoals.some((g) => g.status === 'DRAFT')) {
|
|
40
|
+
// 草稿还在等用户确认 —— 这一步必须先做,否则后面做什么都不作数
|
|
41
|
+
suggested = 'CONFIRM_GOAL';
|
|
42
|
+
}
|
|
43
|
+
else if (!hasStage) {
|
|
44
|
+
// 有目标但没阶段计划:每日任务是**从当前阶段生成的**,没有阶段就排不出今天
|
|
45
|
+
suggested = 'CREATE_STAGE_PLAN';
|
|
46
|
+
}
|
|
47
|
+
else if (goals.length === 0) {
|
|
48
|
+
// 阶段排好了但目标还没激活(PAUSED 也落这里)
|
|
49
|
+
suggested = 'ACTIVATE_GOAL';
|
|
50
|
+
}
|
|
33
51
|
else if (!plan) {
|
|
34
52
|
suggested = 'RUN_DAILY_PLANNING';
|
|
35
53
|
}
|
package/docs/agent.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# 给 Agent / 自动化用
|
|
2
|
+
|
|
3
|
+
> Agent 的主入口是 [AGENTS.md](../AGENTS.md),行为准则是 [SKILL.md](../SKILL.md),
|
|
4
|
+
> 精简索引是 [llms.txt](../llms.txt)。本文是自动发现与 CLI 参考。
|
|
5
|
+
|
|
6
|
+
## 给 Agent 用(自动发现)
|
|
7
|
+
|
|
8
|
+
仓库根目录有三个文件专供 Agent 扫描识别:
|
|
9
|
+
|
|
10
|
+
| 文件 | 作用 |
|
|
11
|
+
|---|---|
|
|
12
|
+
| **`AGENTS.md`** | **Agent 入口**:是什么、怎么装、怎么接、怎么用、哪些规则不能违反 |
|
|
13
|
+
| `llms.txt` | 精简机器可读索引 |
|
|
14
|
+
| `server.json` | MCP Registry 清单(官方 schema 校验通过) |
|
|
15
|
+
|
|
16
|
+
Agent 拿到仓库后,一条命令就能自举——**不需要读源码**:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx ai-growth help --json # 全部命令 + 产品规则 + 上手步骤
|
|
20
|
+
npx ai-growth agent-info --json # 安装路径、数据目录、MCP 配置片段、Skill 位置、下一步
|
|
21
|
+
npx ai-growth status --json # 当前状态 + suggestedNextOperation
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
用户自己装完之后,也可以直接对 Agent 说「用 ai-growth 帮我看看现在该做什么」,
|
|
25
|
+
Agent 会调 `ai-growth status --json` 拿到 `suggestedNextOperation` 并照做。
|
|
26
|
+
|
|
27
|
+
### CLI
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ai-growth help [--json] # 自描述:命令目录 + 产品铁律 + 上手步骤
|
|
31
|
+
ai-growth agent-info [--json] # Agent 引导信息
|
|
32
|
+
ai-growth info [--json] # 环境与运行状态
|
|
33
|
+
ai-growth status [--json] # 状态 + 建议下一步
|
|
34
|
+
ai-growth today [--json] # 今日计划
|
|
35
|
+
ai-growth goals|timeline|passport|metrics [--json]
|
|
36
|
+
ai-growth rollover [--json] # 跨天检查(幂等)
|
|
37
|
+
ai-growth complete|skip|delay <actionId> [...]
|
|
38
|
+
ai-growth mcp-config [--json] # 打印可粘贴的 MCP 配置
|
|
39
|
+
ai-growth skill # 打印 SKILL.md 全文
|
|
40
|
+
ai-growth doctor # 环境自检
|
|
41
|
+
ai-growth init # 初始化数据库
|
|
42
|
+
ai-growth serve # 前台启动常驻服务
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**输出契约与 MCP 工具一致**:`{ ok, data, error? }`。非 TTY(被 Agent/管道调用)时**默认 JSON**,
|
|
46
|
+
避免 Agent 忘记加 `--json`;人类可读输出用 `--no-json`。
|
|
47
|
+
|
|
48
|
+
> CLI 只覆盖读操作与少数任务操作。建目标、写 Evidence、Replan、建提醒等要接 MCP——
|
|
49
|
+
> 那些涉及确认与上下文,CLI 刻意不做。
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# 开发与贡献
|
|
2
|
+
|
|
3
|
+
> 架构约定、当前限制、提交规范。
|
|
4
|
+
|
|
5
|
+
## 开发
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run typecheck # tsc --noEmit
|
|
9
|
+
npm test # 118 个测试(unit + integration + e2e + dist 运行时冒烟)
|
|
10
|
+
npm run build # 幂等:先 rm -rf dist 再编译并拷贝资源
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> **`npm test` 里有一层「运行时冒烟」**:它直接启动编译后的 `dist/mcp/server.js` 并按 MCP 协议调用工具。
|
|
14
|
+
> 这层测试专门覆盖"只有打包后才暴露"的问题(资源拷贝路径、migration 陈旧、MIME 等)——
|
|
15
|
+
> 源码测试全绿但产物是坏的,就是靠它发现的。同时也校验 `dist` 与 `src` 逐字节一致。
|
|
16
|
+
|
|
17
|
+
工程结构:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
src/
|
|
21
|
+
├── core/ # 领域层:状态机、Goal/Stage/Action、Rollover、Replan、Evidence、Memory、Metrics
|
|
22
|
+
├── db/ # SQLite 连接 + 版本化 migration
|
|
23
|
+
├── mcp/ # MCP Server + 63 个 tools(统一 ToolResult 契约)
|
|
24
|
+
├── planner/ # 规划上下文与约束(LLM 判断交给 Agent,Core 只保证规则)
|
|
25
|
+
├── reminder/ # 提醒生命周期 + Scheduler + 通知 Adapter
|
|
26
|
+
├── passport/ # Passport 构建 + Sync Adapter(local-json / 可替换)
|
|
27
|
+
├── api/ # 供 Web UI 使用的 HTTP API
|
|
28
|
+
├── ui/ # Today / Goals / Timeline / Passport / Settings
|
|
29
|
+
├── daemon/ # 常驻进程入口
|
|
30
|
+
└── shared/ # 配置、时间(timezone 感知)、统一结果类型
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 架构约定
|
|
34
|
+
|
|
35
|
+
- **状态机是唯一权威**(`src/core/stateMachine.ts`)。非法转换抛 `INVALID_STATE`,不静默通过。
|
|
36
|
+
- `IN_PROGRESS` 是**可选**中间态:`PLANNED → COMPLETED` 合法(用户说"做完了"不该被要求先点"开始")。
|
|
37
|
+
- 任何未终结的 DAILY 都能跨天 `EXPIRED`(含 `IN_PROGRESS` / `DELAYED`),否则 rollover 会崩。
|
|
38
|
+
- **Core 强制业务规则,MCP 层不重复声明**:zod schema 只做类型校验,`0~2 个 Daily`、`Goal 必须含 why` 这类规则由 Core 抛出带错误码的 `ToolResult`,保证返回结构统一。
|
|
39
|
+
- **结构性优先于文档约定**:`ONBOARDING_REQUIRED`(未访谈不得生成任务)、`REPLAN_REQUIRED`(先解决 Replan 再开新主线)都由 Core 强制,不依赖 Agent"记得遵守"。
|
|
40
|
+
- **时间**:DB 存 ISO timestamp;「哪一天」一律按配置时区计算(`src/shared/time.ts`),绝不按 UTC 截断。
|
|
41
|
+
- **幂等**:rollover(日期级 + action 级)、reminder 取消、sync job 创建、daemon 重启均可重复执行。
|
|
42
|
+
- **排序必须带稳定 tiebreaker**:SQLite 用 `updated_at DESC, rowid DESC`;`created_at` 同毫秒撞车时不可作为唯一排序键。
|
|
43
|
+
- **审计**:关键变动(含 Replan 决策本身)写入 `audit_log`(谁触发 / before / after / 原因 / 时间)。
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 当前限制
|
|
48
|
+
|
|
49
|
+
- V1 不含:六维属性 / EXP / 等级、RPG 装备、Knowledge Graph UI、课程平台、社交排名、云端账号、多人协作(均为预留接口,不阻塞上线)。
|
|
50
|
+
- Passport 外部同步:仅实现 `local-json` Adapter;接真实外部 API 时实现 `PassportSyncAdapter` 接口即可,失败会进重试队列且不影响本地状态。
|
|
51
|
+
- 通知渠道:已实现 macOS 本地通知(osascript)与 `null` 两种 Adapter。
|
|
52
|
+
- 提醒精确定时依赖 daemon 轮询(默认 30s 粒度),非秒级精确。
|
|
53
|
+
- 面板**没有账号体系也刻意不做**(本机进程 + Agent 工具,loopback 即边界)。如需局域网访问请自行加代理与鉴权。
|
|
54
|
+
- 桌面应用打包尚未实施:面板已就绪(紧凑布局 + 无构建步骤),打包属独立交付项。
|
|
55
|
+
|
|
56
|
+
详见 `DELIVERY_REPORT.md` 与 `IMPLEMENTATION_PLAN.md`。
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 参与贡献
|
|
63
|
+
|
|
64
|
+
欢迎 Issue 与 PR。这个项目有几条**不可协商**的产品铁律(见文首「核心原则」),
|
|
65
|
+
改动前请先确认不违背它们——尤其是这两条最容易在实现里被悄悄破坏:
|
|
66
|
+
|
|
67
|
+
- **不产生虚构数值**:任何"属性值 / 掌握度 % / 自律分 / 等级"都会被测试拦下;
|
|
68
|
+
- **不制造跨天债务**:`Daily Action` 次日必须 `EXPIRED`,绝不 clone 到第二天。
|
|
69
|
+
|
|
70
|
+
提交前请跑:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run build && npx tsc --noEmit && npm test && bash scripts/doctor.sh
|
|
74
|
+
```
|
package/docs/usage.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# 安装与使用
|
|
2
|
+
|
|
3
|
+
> 本文是 README 里"细节部分"的完整版(安装、接入、面板、设备、数据、卸载、排查)。
|
|
4
|
+
> 想快速上手,看 [README](../README.md) 的「3 分钟开始」。
|
|
5
|
+
|
|
6
|
+
## 安装
|
|
7
|
+
|
|
8
|
+
**设计原则:开发与生产是同一条全局命令,数据始终在 `~/.ai-growth`。**
|
|
9
|
+
CLI / MCP / daemon / 面板都指向「全局安装的那一份」,所以**更新 = 替换全局包**,数据不受影响。
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd "该项目目录"
|
|
13
|
+
./scripts/install.sh # 默认开发态:npm link(全局 ai-growth → 当前源码)
|
|
14
|
+
./scripts/install.sh --global # 生产态:npm pack + npm install -g(与源码检出解耦)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
安装脚本 9 步:环境检查 → 依赖 → 构建 → **全局安装** → 数据库迁移
|
|
18
|
+
→ launchd 常驻服务(指向全局 CLI)→ MCP 配置 → Agent 入口说明 → doctor。
|
|
19
|
+
|
|
20
|
+
### 更新
|
|
21
|
+
|
|
22
|
+
| 形态 | 怎么更新 |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 开发态(`npm link`) | `git pull && npm install && npm run build` → 全局命令自动生效,无需重新 link |
|
|
25
|
+
| 生产态(`npm i -g`) | `npm install -g ai-growth@latest && ai-growth migrate` |
|
|
26
|
+
| 让 daemon 加载新代码 | `launchctl kickstart -k gui/$(id -u)/com.lairey.ai-growth.daemon` |
|
|
27
|
+
|
|
28
|
+
**数据不受更新影响**:`~/.ai-growth/growth.db` 与代码包完全分离,schema 变更走 migration(幂等、增量)。
|
|
29
|
+
|
|
30
|
+
随时用 `ai-growth where` 查看当前是哪一种形态、代码在哪、数据在哪、该怎么更新。
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 接入 Agent
|
|
35
|
+
|
|
36
|
+
两步:**Skill** + **MCP**。
|
|
37
|
+
|
|
38
|
+
**MCP**(给出 `node` 与项目绝对路径):
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"mcpServers": {
|
|
43
|
+
"ai-growth": {
|
|
44
|
+
"command": "/path/to/node",
|
|
45
|
+
"args": ["/absolute/path/to/dist/mcp/server.js"],
|
|
46
|
+
"env": { "AI_GROWTH_DATA_DIR": "/Users/you/.ai-growth" }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Skill**:把仓库根目录的 `SKILL.md` 交给 Agent。WorkBuddy 用户级安装:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mkdir -p ~/.workbuddy/skills/ai-growth && cp SKILL.md ~/.workbuddy/skills/ai-growth/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
接好后对 Agent 说一句 **「开启今日任务」**(同义:「今天要做什么」「开工」)——它会调用 `growth_status`,按状态决定下一步;首次使用会主动开始访谈,而不是直接派任务。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 启动
|
|
63
|
+
|
|
64
|
+
| 服务 | 命令 | 说明 |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| 常驻 Daemon | 安装后由 launchd 托管(`ai-growth serve` 手动前台) | **同时提供调度(rollover + 提醒 + 同步重试)与面板 API** |
|
|
67
|
+
| MCP Server(stdio,由 Agent 拉起) | `ai-growth` MCP 配置指向全局安装 | 平时无需手动运行 |
|
|
68
|
+
| 面板 | http://127.0.0.1:4580(daemon 自带) | 单独跑用 `npm run api` |
|
|
69
|
+
| 健康检查 | `ai-growth doctor` 或 `bash scripts/doctor.sh` | 逐项验证环境(含构建新鲜度) |
|
|
70
|
+
| 数据库迁移 | `ai-growth migrate` | 幂等,可重复执行 |
|
|
71
|
+
| 清理构建产物 | `npm run clean` | 删除 `dist/`(`build` 已内置) |
|
|
72
|
+
|
|
73
|
+
daemon 与面板合成一个进程是刻意的:面板要能当桌面组件/桌面应用用,就必须和 daemon 同生命周期,
|
|
74
|
+
否则用户每次重启还得手工起面板——违反「不要求用户维护系统」。
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 面板(游戏面板式 HUD)
|
|
79
|
+
|
|
80
|
+
`http://127.0.0.1:4580`
|
|
81
|
+
|
|
82
|
+
深色面板风格:卡片式布局、阶段节点轨道、主任务高亮卡、事实计数条。
|
|
83
|
+
|
|
84
|
+
**🔴 面板上不会出现虚构数值。** 这是你自己定的铁律(核心原则 6 / §16.3 明确禁止六维属性、EXP、等级、
|
|
85
|
+
掌握度百分比、自律分)。所以面板的「游戏感」只体现在**视觉语言**上——卡片、发光描边、节点轨道、状态色——
|
|
86
|
+
而每一个数字都是可核对事实:
|
|
87
|
+
|
|
88
|
+
| 显示 | 来源 |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `Stage 2 / 5` | Stage 序号与总数 |
|
|
91
|
+
| 已完成主任务 / 证据总数 / 成长记录 | 数据库计数 |
|
|
92
|
+
| 阶段节点轨道 | 各 Stage 的真实 status |
|
|
93
|
+
| 最近进展 | Growth Event(每条都挂着 Evidence) |
|
|
94
|
+
|
|
95
|
+
页面:**面板**(Progress First:当前主线 → 阶段轨道 → 今天最重要的一步 → 每日维护 → 累计事实 → 最近进展)、
|
|
96
|
+
**主线**(Goal 的 why/outcome/成功标准 + Stage Timeline)、**记录**(Growth Events + Evidence 流,含强度标签)、
|
|
97
|
+
**护照**(Passport 快照)、**设置**(时区、提醒渠道、手动跨天检查)。
|
|
98
|
+
|
|
99
|
+
支持 URL 深链:`#goals`、`#timeline`、`#settings`。
|
|
100
|
+
|
|
101
|
+
### 桌面组件 / 打包成桌面应用
|
|
102
|
+
|
|
103
|
+
面板已为桌面形态预留两件事:
|
|
104
|
+
|
|
105
|
+
1. **紧凑布局**:URL 加 `?layout=widget`(或窗口宽度 < 420px 自动切换)→ 单列、窄边距、隐藏品牌字。
|
|
106
|
+
实测 360px / 430px 宽均无横向溢出。
|
|
107
|
+
2. **无构建步骤**:纯 HTML/CSS/JS,任何 WebView 都能直接托管。状态全来自本地 API,
|
|
108
|
+
应用本身只是"视图",daemon 照常headless 运行。
|
|
109
|
+
|
|
110
|
+
后续打包路径(按成本从低到高):
|
|
111
|
+
|
|
112
|
+
| 方案 | 说明 | 成本 |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| 浏览器固定窗口 | Safari/Chrome 加到程序坞,加载 `http://localhost:4580/?layout=widget` | 0 |
|
|
115
|
+
| Übersicht 桌面组件 | 直接渲染 HTML 到桌面层,最贴近"在桌面上显示" | 低 |
|
|
116
|
+
| Tauri v2 | 体积小(~5MB),需 Rust;可做无边框 + 常驻置顶 | 中 |
|
|
117
|
+
| Electron | 无需 Rust,体积大(~150MB);`frame:false, transparent, alwaysOnTop` | 中 |
|
|
118
|
+
|
|
119
|
+
⚠️ **打包时必须让 WebView 加载 `http://localhost:4580`,不要用 `file://` 打开 index.html**:
|
|
120
|
+
页面 origin 为 `null` 时浏览器会按 CORS 拦掉对本地 API 的请求。加载 localhost 时 Host 校验也正好放行。
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 连上 AI Passport 设备
|
|
125
|
+
|
|
126
|
+
把固件刷到设备之后,让设备连上这台电脑**只需要一条命令**(它会自己确认成功):
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
ai-growth device setup --ssid "你的Wi-Fi名" --pass "Wi-Fi密码"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- 它会自动找到串口、写好配置、顺手开启并记住「局域网访问」,然后**等设备真的取到卡**再回报结果
|
|
133
|
+
- Wi-Fi 名含中文或空格也没关系(会自动改用十六进制编码:设备控制台本身只能收 ASCII)
|
|
134
|
+
- 设备之后每次开机都会自动连上并显示今天的卡,**不需要按任何键**
|
|
135
|
+
- 想先看当前状态/本机地址/令牌:`ai-growth device`
|
|
136
|
+
- 失败时它给出的不是错误码,而是**下一步该做什么**(连不上 Wi-Fi/够不到电脑/服务没起来)
|
|
137
|
+
|
|
138
|
+
设备上的按键:**上/下** 翻今天的卡,**确定** 完成当前这件事,**长按确定** 回到设备自带的演示菜单。
|
|
139
|
+
屏幕 1 分钟无操作会自动熄屏,按任意键立刻亮回。
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 数据位置
|
|
144
|
+
|
|
145
|
+
| 内容 | 路径 |
|
|
146
|
+
|---|---|
|
|
147
|
+
| 数据库 | `~/.ai-growth/growth.db`(WAL 模式) |
|
|
148
|
+
| Passport 输出 | `~/.ai-growth/passport.json` |
|
|
149
|
+
| Daemon 日志 | `~/.ai-growth/daemon.log`、`daemon-stderr.log` |
|
|
150
|
+
| 配置 | 项目根 `.env`(参考 `.env.example`)或 `~/.ai-growth/config.env` |
|
|
151
|
+
| launchd plist | `~/Library/LaunchAgents/com.lairey.ai-growth.daemon.plist` |
|
|
152
|
+
|
|
153
|
+
备份 = 复制 `~/.ai-growth/growth.db`。所有数据默认只在本机;外部同步必须显式配置 Adapter。
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 卸载 / 重置
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
./scripts/uninstall.sh # 停止并移除 launchd 服务,数据保留
|
|
161
|
+
./scripts/uninstall.sh --purge # 额外删除数据目录(需输入 yes 二次确认)
|
|
162
|
+
|
|
163
|
+
./scripts/reset-dev-data.sh --list # 只看数据概况,不做任何修改
|
|
164
|
+
./scripts/reset-dev-data.sh # 备份现有数据 → 建一个干净新库
|
|
165
|
+
./scripts/reset-dev-data.sh --force # 跳过"疑似真实数据"拦截
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`reset-dev-data.sh` 永不静默删数据:它把数据目录改名备份,并打印回滚命令。
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 故障排查
|
|
173
|
+
|
|
174
|
+
| 现象 | 原因 / 处理 |
|
|
175
|
+
|---|---|
|
|
176
|
+
| Agent 说连不上 MCP | `bash scripts/doctor.sh` 看 MCP 一节;确认 `dist/mcp/server.js` 存在(`npm run build`) |
|
|
177
|
+
| **改了代码但行为没变** | **`dist/` 陈旧**。`npm run build`(已内置 `rm -rf dist`,幂等);`doctor.sh` 会检测 `dist ≠ src` |
|
|
178
|
+
| Web UI 打开是空白页 | 静态资源 MIME 必须正确(`.js` 不能用 `text/html` 返回)。若手工改过 server 需重启 `npm run api` |
|
|
179
|
+
| 重启后提醒不触发 | `launchctl list \| grep ai-growth`;未加载则 `launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.lairey.ai-growth.daemon.plist` |
|
|
180
|
+
| daemon 反复退出 | 看 `~/.ai-growth/daemon-stderr.log` |
|
|
181
|
+
| 时间不对 / 日期错乱 | Web UI → Settings 设置正确 timezone(自然日判断依据,非 UTC 截断) |
|
|
182
|
+
| 提醒太吵 | Settings 把 Reminder Channel 设为「关闭提醒」;每个 Daily 默认最多 1 次提醒 |
|
|
183
|
+
| 昨日任务还挂在今天 | Web UI 打开时会自动执行 rollover;也可在 Settings 手动执行 / 让 Agent 调 `run_daily_rollover` |
|
|
184
|
+
| `ONBOARDING_REQUIRED` 报错 | 未完成首次访谈就调了 `plan_today`——这是结构性保护,先完成访谈 |
|
|
185
|
+
| `REPLAN_REQUIRED` 报错 | 有未处理的 Replan,先让 Agent 调 `replan` 再规划新主线 |
|
|
186
|
+
| 想确认状态机没被绕过 | `audit_log` 表记录了关键变动(含 Replan 决策)的 before/after 与原因 |
|
|
187
|
+
| 面板打不开 / 白屏 | 面板由 daemon 提供:`bash scripts/doctor.sh` 看「面板 API」;单跑用 `npm run api`。白屏多半是 MIME 不对,重启进程即可 |
|
|
188
|
+
| 打包后 API 调用失败 | WebView 必须加载 `http://localhost:4580`,不能用 `file://`(origin 为 null 会被 CORS 拦) |
|
|
189
|
+
|
|
190
|
+
## 常驻服务(daemon)没在跑怎么办
|
|
191
|
+
|
|
192
|
+
**症状**:面板打不开、设备显示"连不上电脑"的兜底卡,但你以为它一直在跑。
|
|
193
|
+
|
|
194
|
+
先确认状态(三条命令逐级确认,别只看一条):
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
launchctl print "gui/$(id -u)/com.lairey.ai-growth.daemon" | head # 服务是否被 launchd 托管
|
|
198
|
+
ls -l ~/Library/LaunchAgents/com.lairey.ai-growth.daemon.plist # 服务定义是否还在
|
|
199
|
+
# 最可靠的一条:直接看端口有没有人在听(不要用 curl,本机可能有代理会给出假的 502)
|
|
200
|
+
node -e "const s=require('net').connect(4580,'127.0.0.1',()=>{console.log('在跑 ✓');s.end()}).on('error',()=>console.log('没在跑 ✗'))"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**最常见的原因**:你曾用 `ai-growth serve` 在前台跑过 —— 它把 daemon 当**子进程**拉起,
|
|
204
|
+
**终端一关就把它带走了**(daemon 日志里会看到"启动了、但没有 SIGTERM 退出记录")。
|
|
205
|
+
|
|
206
|
+
**修复**(服务定义还在的话,一条命令即可):
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/com.lairey.ai-growth.daemon.plist
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
服务定义丢了就重跑安装脚本,它会重建 plist、`bootout` → `bootstrap`,并且**验证进程真的活着**
|
|
213
|
+
(`bootstrap` 返回成功不等于跑起来了 —— 这一点脚本里专门处理过)。
|
|
214
|
+
|
|
215
|
+
> 常驻服务带 `KeepAlive` + `RunAtLoad`:登录自动启动,进程意外退出会自动拉起。
|
|
216
|
+
> 它跑的是**全局安装的那一份**,所以更新代码后要用
|
|
217
|
+
> `launchctl kickstart -k "gui/$(id -u)/com.lairey.ai-growth.daemon"` 让它换上新代码。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-growth",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Agent-native、Local-first 的个人成长执行系统:AI 维护计划,人保留目标与最终确认权。",
|
|
5
5
|
"mcpName": "io.github.lairey-ai/ai-growth",
|
|
6
6
|
"type": "module",
|
|
@@ -33,11 +33,12 @@
|
|
|
33
33
|
"dist/",
|
|
34
34
|
"scripts/",
|
|
35
35
|
"launchd/",
|
|
36
|
-
"docs/
|
|
36
|
+
"docs/",
|
|
37
37
|
"SKILL.md",
|
|
38
38
|
"AGENTS.md",
|
|
39
39
|
"START-HERE.md",
|
|
40
40
|
"README.md",
|
|
41
|
+
"ROADMAP.md",
|
|
41
42
|
"LICENSE",
|
|
42
43
|
"PRODUCT_SPEC.md",
|
|
43
44
|
"IMPLEMENTATION_PLAN.md",
|
package/scripts/smoke-device.mjs
CHANGED
|
@@ -255,7 +255,7 @@ check('正确令牌(header)→ 200', (await q2('GET', '/api/device/ping', {
|
|
|
255
255
|
check('正确令牌(query,固件走这条)→ 200', (await q2('GET', '/api/device/ping?token=smoke-token-1234')).status === 200);
|
|
256
256
|
check('伪造 Host: 127.0.0.1 不能绕过 → 401', (await q2('GET', '/api/device/ping', { Host: '127.0.0.1' })).status === 401);
|
|
257
257
|
check('面板接口仍锁回环(Host 127.0.0.1 → 200)', (await q2('GET', '/api/today', { Host: '127.0.0.1' })).status === 200);
|
|
258
|
-
check('面板接口拒绝局域网 Host → 403', (await q2('GET', '/api/today', { Host: '192.168.
|
|
258
|
+
check('面板接口拒绝局域网 Host → 403', (await q2('GET', '/api/today', { Host: '192.168.1.10' })).status === 403);
|
|
259
259
|
note(`当前令牌 = ${deviceToken(ctx)}`);
|
|
260
260
|
|
|
261
261
|
// ═════════════════════ E) 跨天降级为迟记 ═════════════════════
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.lairey-ai/ai-growth",
|
|
4
4
|
"title": "AI Growth",
|
|
5
5
|
"description": "Agent-native 的个人成长执行系统:访谈定目标、动态生成每日少量任务、跨天自动作废旧任务、用真实证据积累成长记录,并同步为可迁移的 AI Passport。",
|
|
6
|
-
"version": "1.1.
|
|
6
|
+
"version": "1.1.2",
|
|
7
7
|
"websiteUrl": "https://github.com/lairey-ai/ai-growth",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/lairey-ai/ai-growth",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "ai-growth",
|
|
17
|
-
"version": "1.1.
|
|
17
|
+
"version": "1.1.2",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|