ai-growth 1.1.1 → 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/ROADMAP.md +48 -0
- package/dist/core/status.js +22 -4
- package/docs/usage.md +29 -0
- package/package.json +2 -1
- package/scripts/smoke-device.mjs +1 -1
- package/server.json +2 -2
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/usage.md
CHANGED
|
@@ -186,3 +186,32 @@ ai-growth device setup --ssid "你的Wi-Fi名" --pass "Wi-Fi密码"
|
|
|
186
186
|
| 想确认状态机没被绕过 | `audit_log` 表记录了关键变动(含 Replan 决策)的 before/after 与原因 |
|
|
187
187
|
| 面板打不开 / 白屏 | 面板由 daemon 提供:`bash scripts/doctor.sh` 看「面板 API」;单跑用 `npm run api`。白屏多半是 MIME 不对,重启进程即可 |
|
|
188
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",
|
|
@@ -38,6 +38,7 @@
|
|
|
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
|
},
|