nx-kv 0.9.0 → 0.10.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,102 @@
2
2
 
3
3
  本文件记录对外可见的变更。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。
4
4
 
5
+ ## [Unreleased]
6
+
7
+ ## [0.10.0] - 2026-10-20
8
+
9
+ ### Added
10
+
11
+ - **新增 `timegoal` 模块:把"持续运行 N 小时"任务固化到 nx-kv。** 完全独立的命令族
12
+ / 独立 store / 独立循环链路——**与 localtask wait 没有任何关系**(不调用、不被调用、
13
+ store 也不共享),可以同时跑也可以分开跑。UI 上嵌在「本地任务」主题卡里只是为了查
14
+ 看便利(数据/逻辑完全独立——拔掉 localtask 本模块照样跑)。
15
+
16
+ - 命令族 `nx-kv timegoal <...>`:
17
+ - **`set`** 新建/替换本目录 timegoal(`--duration 60-86400`、`--prompt "<...>"`),
18
+ 重置起点;
19
+ - **`update`** 改提示词,可选**同时改时长**(`--duration`)——**保留起点**
20
+ (`deadline = startedAt + 新时长`,已用时间仍算数);agent 自我迭代提示词、
21
+ 用户 Web 端编辑都用这条,避免一次小改动把整套 3 小时清零;
22
+ - **`show`** 仅查询;**`check`** 时间运算 + **原文回显 prompt**
23
+ (让 agent 永远以 store 为准,避免长对话里漂移),到点返回 `reached:true`;
24
+ - **`clear`** 清空(无则 `no_goal`,面板按钮可无脑调用);
25
+ - **`list`** 总览所有有 timegoal 的目录。
26
+ - **典型流程**:开头 `set` 一次 → 每轮 `check` 拿 `prompt` 当本轮根指令干活 →
27
+ 调研发现 prompt 漏条件就 `update` 替换 → 到 `reached:true` 那轮立刻停手。
28
+ - 独立 store `~/.nx-kv/timegoals.json`(`NX_KV_TIMEGOAL_STORE` 可覆盖),
29
+ 与 localtask 的 `localtasks.json` 完全分离——两套循环并行不冲突。
30
+ - **UI 完整编辑入口**(`localtask/view.jsx`,任务看板):
31
+ - 页面顶部新增「时间目标」汇总卡:列出**所有目录**的 timegoal(含还没在
32
+ 看板里出现过的目录——CLI 先设、agent 后 wait),支持**新建**(填目录 +
33
+ 时长 + 提示词)、**编辑**(改时长/提示词;默认保留起点,勾「重置起点」
34
+ 才从头计)、**清空**;状态列显示 `剩 mm:ss` / `已到点`,每 1.5s 刷新。
35
+ - 主题卡里 timegoal 行**恒显示**:已设置 → 倒计时 + 查看/编辑/清空;
36
+ 未设置 → 「未设置时间目标 + 设置」(直接为该目录新建)。
37
+ - 时长输入带快捷按钮(30 分钟 / 1 / 2 / 3 / 8 小时),不用手打秒数。
38
+ - 编辑一律走 `PATCH /api/timegoals`(保留起点);只有勾「重置起点」才走
39
+ `POST`(= `set`,计时清零)。
40
+ - 模块边界:timegoal service 不读 localtask service;`topicKeyFor / stampNow
41
+ / parseStampMs` 是 4-6 行的纯工具,本地复制避免跨模块耦合;纯函数
42
+ `evalTimegoal(goal, nowMs)` 不读时钟、便于单测钉边界。
43
+ - 单测 `tests/unit/timegoal.test.mjs`:duration / prompt 边界、`evalTimegoal`
44
+ 四时段、set → show → check 链路、update 保留起点、不同 cwd 隔离、模拟到点、
45
+ store 损坏容忍、环境变量覆盖、prompt 含换行/Unicode 原样回显。
46
+ - 配套 skill `kv-timegoal`:`nx-kv skill install kv-timegoal`。`SKILL.md` 与
47
+ `references/workflow.md` 强调 timegoal 与 localtask wait 等其它命令族完全独立
48
+ ——skill 文字里不出现"`localtask wait` + `timegoal check`"的搭配示例。
49
+
50
+ ### Fixed
51
+
52
+ - **短时限等待被秒级截断「吃掉」:`waitingUntil` 只存到秒。** `stampNow` 是**截断**
53
+ 不是四舍五入——真实 deadline `S+1.97s` 存成 `"S+1"` 后解析回来是 `S+1.000`,比真实
54
+ 时刻早了近 1 秒。等待时长只有 1~2 秒时这点误差能吃掉**整个窗口**:wait 若恰好在
55
+ 某秒最后 ~40ms 启动,事件流 100ms 后轮询时判定「不在等待」→ `waiting` 事件永远推
56
+ 不出来(`tests/unit/localtask-sse.test.mjs` 由此带 ~4% 的 flake,实测 flake 率与
57
+ 40ms/1000ms 的理论值吻合)。
58
+ - **修法**:`setWaiting` 额外写毫秒精度的 `waitingUntilMs`(epoch ms);判定一律走
59
+ `deadlineMsOf()`(优先毫秒值,老数据回退解析字符串)——`isLiveWaiting` /
60
+ `watchEvents` / 面板倒计时全部改用它。`watchEvents` 判「新一轮等待」也从比较
61
+ 秒级字符串改成比较毫秒 deadline(同一秒内开始的两次等待字符串相同,靠它判会漏)。
62
+ - 真实影响:默认 180s 超时下截断误差无感(相对误差太小),但**判据正确性**不应
63
+ 依赖时长够长;面板倒计时也不再提前 1 秒归零。
64
+ - 回归测试 4 例:字符串已过期但毫秒值未到 → 仍算等待中;毫秒值也过期 → 不算;
65
+ 老数据无 `waitingUntilMs` 回退字符串;真实 wait 写入毫秒值且与字符串同秒。
66
+
67
+ - **「等待中」永远不结束:僵尸 `waiting` 标志残留。** 面板上某个主题永远显示
68
+ 「等待中 已等 760:35 · 剩 0:00」,点「关闭」也没反应。
69
+ - **根因**:`waiting` 标志由 wait 进程写入、结束时在 `finally` 里复位;但 wait
70
+ 被**强杀**(SIGKILL / 任务管理器杀 / 终端关掉 / 机器崩了)时 `finally` 不会执行,
71
+ 标志就永久留在 store 里。曾实测:gs-ac 的 wait 在 22:29 开始、应在 22:32 超时
72
+ 收尾,但进程没了 —— 于是标志卡住,用户 23:14 点「关闭」也**没有活进程**来消费
73
+ `cancelRequested`。
74
+ - **修复**:判定「是否真的在等」统一走新函数 `isLiveWaiting(t)` ——
75
+ `waiting` 为真**且**截止时刻还没过。截止已过 = 那个 wait 本来也该收尾了 =
76
+ 没人真在等。此前 `countWaitingTopics()` 与 `watchEvents()` 各有一份内联判断,
77
+ `topicView()` 却只看裸标志,于是面板看到的是假状态。
78
+ - 改动点:`topicView()` 对外把 `waiting` 抹成假值、另给 `staleWaiting` 标记;
79
+ `pruneTopics()` / `removeTopic()` / `removeTopics()` / `cancelWait()` /
80
+ `countWaitingTopics()` 全部改用 `isLiveWaiting`。
81
+ - **连带修好的三处卡死**:僵尸等待的主题过去永远躲过 `prune`(空主题也清不掉)、
82
+ 被「等待中不能删」挡住、也阻塞面板空闲自释放。
83
+ - 面板显示改为「**已结束(上次等待超时,进程已退出)**」,如实说明发生了什么,
84
+ 而不是让倒计时一直转。
85
+ - 单测 `tests/unit/localtask-stale.test.mjs`(7 例):`isLiveWaiting` 四个分支 +
86
+ 僵尸等待在 list / count / prune / remove / cancel 各路径的表现 + 正常等待不受影响。
87
+
88
+ - **`localtask wait` 会重复打开多个浏览器窗口**。根因是「有没有活标签」这条判据失效:
89
+ 服务端 `panelPresence()` 统计的是 `/api/localtasks/events` 上的活动 SSE 连接,
90
+ 但面板页改成 1.5s 轮询后**再也没有建立过 SSE**,presence 恒为 0 ——
91
+ 于是每次 wait 都以为没人在看、都开一个新窗口,等待期间还每 20s 再开一个。
92
+ - **面板补上常驻 SSE**(`localtask/view.jsx`):既是 presence 的信号,也顺手把
93
+ waiting / reminder / resolved 变成即时刷新,轮询退化为兜底。
94
+ - **wait 开窗加三道闸**:初次开页即计入冷却(页面加载到 SSE 连上之间有空窗,
95
+ 否则 5s 后第一次复查就会再开一个);单次探测为 0 不算标签被关,要**连续两次**
96
+ (≈10s)探不到才重开 —— 后台标签被冻结、SSE 自动重连、网络抖动都会短暂掉 0;
97
+ 一次 wait 最多开 3 个窗口,避免浏览器拦脚本时刷成窗口风暴。
98
+ - 单测 `tests/unit/localtask-window.test.mjs`:`shouldReopenWindow` 四个分支 +
99
+ `panelPresence` 的连接计数与断开归零。
100
+
5
101
  ## [0.9.0] - 2026-10-16
6
102
 
7
103
  ### Added
package/README.md CHANGED
@@ -141,6 +141,39 @@ nx-kv skill install kv-submit # 提交侧:总结上下文、提炼需求
141
141
  nx-kv skill install kv-localget # 领取侧:主动领取排给本目录的任务
142
142
  ```
143
143
 
144
+ ## 时间目标(timegoal,不需登录)
145
+
146
+ 把「AI 持续运行 N 小时」这类长任务**固化到工具里**,而不是散落在外部脚本:
147
+
148
+ 每个**工作目录**绑定一个 timegoal = 「持续秒数 + 一段完整全局提示词」。
149
+
150
+ ```bash
151
+ # 开头设一次:3 小时 + 完整提示词(提示词会被原文固化到 store)
152
+ nx-kv timegoal set --cwd "$PWD" --duration 10800 --prompt "<完整全局提示词>" --json
153
+
154
+ # 每轮调一次:算出还剩多少时间,并把提示词【原文】回显给你
155
+ nx-kv timegoal check --cwd "$PWD" --json
156
+ # → { reached:false, remainingSec:10780, prompt:"<完整提示词原文>", deadline, ... }
157
+
158
+ # 提示词要改(agent 自我迭代 / 用户在面板上改)——只换提示词,保住计时起点
159
+ nx-kv timegoal update --cwd "$PWD" --prompt "<新版>" [--duration <秒>] --json
160
+
161
+ # 其余:show(仅查)/ clear(清空)/ list(总览所有目录)
162
+ ```
163
+
164
+ **为什么需要它**:长对话里 agent 一定会把自己手里的提示词改写、漂移、漏条件。
165
+ `check` 每次把 store 里的**原文**回显出来,agent 就没有"凭记忆发挥"的空间。
166
+ 到点时 `reached:true`,agent 据此停手、收尾。
167
+
168
+ **完全独立的模块**:独立 store(`~/.nx-kv/timegoals.json`)、独立命令族、
169
+ 独立循环——不调用 `localtask wait`、不被它调用,两者可以同时跑。
170
+ 面板上嵌在「本地任务」页(顶部「时间目标」汇总卡 + 每个主题卡里一行),
171
+ 纯粹是为了查看与编辑方便。
172
+
173
+ ```bash
174
+ nx-kv skill install kv-timegoal # 持续 N 小时任务的时序与提示词模板
175
+ ```
176
+
144
177
  ## ⚠️ 定位一律按内容,不按 id
145
178
 
146
179
  待办的 id **非常容易重复**,两条独立的原因:
@@ -202,13 +235,14 @@ nx-kv todo get --ref "旧记录" --topic fr # 或按主题收窄
202
235
 
203
236
  ```
204
237
  src/core/ 零业务语义:kvapi / fileapi(后端客户端) / attachstore(附件本地镜像) / config / errors / fstree
205
- src/modules/ 功能域:system / setting / auth / group / localtask / todo / file / bundled
238
+ src/modules/ 功能域:system / setting / auth / group / localtask / timegoal / todo / file / bundled
206
239
  src/runtime/ 装配层:registry / spec / cli / api / server
207
240
  src/web/frontend/ React 壳
208
241
  assets/nx-kv/ 内置 skill:KV 清单操作手册(远程)
209
242
  assets/kv-waittask/ 内置 skill:对话内本地任务接力(等待侧)
210
243
  assets/kv-submit/ 内置 skill:需求提炼与委托提交(提交侧)
211
244
  assets/kv-localget/ 内置 skill:领取本目录本地任务(领取侧)
245
+ assets/kv-timegoal/ 内置 skill:持续 N 小时任务的时间目标与提示词回显
212
246
  ```
213
247
 
214
248
  分层由 `eslint.config.js` 的 `no-restricted-imports` 强制;
@@ -221,6 +255,7 @@ nx-kv skill install # 装到 ~/.claude/skills/nx-kv(KV 清单操作手册
221
255
  nx-kv skill install kv-waittask # 本地任务接力:最后一步阻塞等用户喂任务
222
256
  nx-kv skill install kv-submit # 提交侧:总结上下文、提炼需求,委托别的 agent
223
257
  nx-kv skill install kv-localget # 领取侧:主动领取排给本目录的任务
258
+ nx-kv skill install kv-timegoal # 持续 N 小时任务:每轮回显提示词原文、到点自动停手
224
259
  nx-kv skill list # 列出可装 skill、默认安装项与可装 group
225
260
  nx-kv skill groups # 列出 group → 包含哪些 skill
226
261
  nx-kv skill install --group=<key> # 一键装整组(与 <name> 二选一)
@@ -17,6 +17,10 @@
17
17
  "kv-localget": {
18
18
  "skills": ["kv-localget"],
19
19
  "summary": "领取排给本目录的本地任务 + 队列管理(领取侧)"
20
+ },
21
+ "kv-timegoal": {
22
+ "skills": ["kv-timegoal"],
23
+ "summary": "把「持续运行 N 小时」任务固化到 nx-kv:每轮回显原文提示词防偏移 + 时间到点自动停手"
20
24
  }
21
25
  }
22
26
  }
@@ -0,0 +1,160 @@
1
+ ---
2
+ name: kv-timegoal
3
+ description: 把"AI 持续运行 N 小时(如 3 小时)"任务固化到 nx-kv 里——用 CLI 设置时间目标 + 完整全局提示词,每轮自动回显提示词原文避免长对话里 agent 漂移(防偏移),到点返回 reached:true,agent 据此停手收尾。timegoal 是独立模块(独立 store、独立循环、独立命令族),与 localtask wait 等任何其它机制都没有关系;UI 上嵌入在「本地任务」主题卡里只是为了方便查看,逻辑上完全不依赖。agent 可通过 `timegoal update` 自己迭代提示词、用户也可在 web 端动态编辑(都不重置计时器)。典型用法:设置 3 小时"调研开源 Redis 差距并逼近生产级数据库"任务;每轮调 subagent 找差距、写 CHANGELOG、调 update 改 prompt,调 check 看是否到点。触发词:timegoal、time goal、时间目标、3 小时、两小时、持续运行、定时任务、跑一晚上、强制 N 小时、N 小时任务、self-improve prompt、自我迭代提示词、agent 改自己的 prompt、到点自动结束、到点停手、循环任务、跑完为止、UX prompt 防漂移、防偏移。
4
+ ---
5
+
6
+ # kv-timegoal — 把"持续 N 小时任务"固化到 nx-kv
7
+
8
+ 一个带"到期硬出口"的循环:开头一次性 `set`,**完整全局提示词固化进 store**;
9
+ 每轮调 `check`,**拿到的 `prompt` 字段就是这轮的根指令**(永远从 store 原文回显,
10
+ 不让 agent 在长对话里漂移);`reached:true` 那轮**自动停手**,写最终总结退出。
11
+
12
+ ## 怎么用
13
+
14
+ ### 1. 开头 set 一次
15
+
16
+ ```bash
17
+ nx-kv timegoal set --cwd "$PWD" \
18
+ --duration 10800 \
19
+ --prompt "<完整全局提示词>" --json
20
+ ```
21
+
22
+ - `--duration` 持续秒数,**60-86400**(1 分钟到 24 小时)。例:3 小时 = `10800`
23
+ - `--prompt` 完整全局提示词,≤20000 字
24
+ - `--cwd` 绑定的目录(缺省用当前目录);**一个目录一个 timegoal**
25
+
26
+ 返回:
27
+
28
+ ```jsonc
29
+ {
30
+ "status": "ok",
31
+ "replaced": false, // 之前没设过;已有则 true(会重置起点)
32
+ "goal": {
33
+ "durationSec": 10800,
34
+ "startedAt": "2026-10-19 20:31:12",
35
+ "deadline": "2026-10-19 23:31:12", // = startedAt + duration
36
+ "prompt": "<完整提示词原文>" // 已固化
37
+ }
38
+ }
39
+ ```
40
+
41
+ ### 2. 每轮循环
42
+
43
+ ```
44
+ 每轮开始:
45
+ nx-kv timegoal check --cwd "$PWD" --json
46
+ → { remainingSec, prompt, ... }
47
+ → 把 prompt 字段当作本轮根指令(不要从对话历史里重新拼)
48
+
49
+ 干活(按 prompt 的指令:调 subagent、写代码、改 CHANGELOG 等)
50
+
51
+ 写一行本轮总结到 .timegoal-log.md(或 git CHANGELOG.md)
52
+
53
+ 如本轮调研发现 prompt 漏条件:
54
+ nx-kv timegoal update --cwd "$PWD" --prompt "<新版>" --json
55
+ (只换 prompt,截止时间不动)
56
+
57
+ 回到本轮开头
58
+
59
+ 拿到的 {reached: true} 那一轮:
60
+ 写完本轮总结 → 不再开新轮 → 退出本循环
61
+ ```
62
+
63
+ ### 3. check 的返回形状
64
+
65
+ ```jsonc
66
+ {
67
+ "hasGoal": true,
68
+ "reached": false, // true 即停手信号
69
+ "elapsedSec": 120, // 已用秒
70
+ "remainingSec": 10680, // 还剩秒
71
+ "startedAt": "2026-10-19 20:31:12",
72
+ "deadline": "2026-10-19 23:31:12",
73
+ "now": "2026-10-19 20:33:12",
74
+ "prompt": "<完整提示词原文>", // ← 这才是该轮的根指令
75
+ "cwd": "/path/to/workdir",
76
+ "key": "<目录 key>",
77
+ "name": "<目录名>"
78
+ }
79
+ ```
80
+
81
+ 边界:
82
+
83
+ - 没设过 timegoal → `{hasGoal:false, reached:false, prompt:""}`(需先 `set`)
84
+ - 到点后 `reached:true`,goal 对象仍在;可继续 `check` 看 prompt,直到 `clear`
85
+
86
+ ## 四条硬规则
87
+
88
+ 1. **一次 `set`,整个循环只看 `check` 的返回。** 不要再从对话历史里拼"原始 prompt"
89
+ —— 长对话里 agent 一定会自己改写、漂移、漏条件。**永远把 `check` 返回的
90
+ `prompt` 字段当作本轮根指令**。
91
+ 2. **想改 prompt 必须用 `timegoal update`,不要 `set`。** `set` 会**重置起点**
92
+ (一次小迭代把 3 小时清零!);`update` 保留起点——只换 prompt,或顺带
93
+ `--duration` 调整时长(deadline 相应平移,已用时间仍算数)。
94
+ 3. **`reached:true` 立刻停手。** 干完手头这步、最后写一遍最终总结到
95
+ `.timegoal-log.md`(或 git CHANGELOG.md),**不再开新轮**;这次循环结束。
96
+ 4. **每轮结尾必写一行总结**到 `<workdir>/.timegoal-log.md`(或 git CHANGELOG),
97
+ 格式自定,目的是"失败也能复盘":时间 / 干了什么 / 下一步计划。
98
+
99
+ ## 完整命令清单
100
+
101
+ ```bash
102
+ nx-kv timegoal set --cwd <dir> --duration <秒> --prompt "<...>" # 设/换(新起点)
103
+ nx-kv timegoal update --cwd <dir> --prompt "<新版>" [--duration <秒>] # 改提示词/时长(保起点)
104
+ nx-kv timegoal show --cwd <dir> # 仅查(不算时间)
105
+ nx-kv timegoal check --cwd <dir> # 算时间 + 回显 prompt
106
+ nx-kv timegoal clear --cwd <dir> # 清空
107
+ nx-kv timegoal list # 所有有 timegoal 的目录
108
+ ```
109
+
110
+ 全部命令都支持 `--json`(推荐 agent 用)。
111
+
112
+ `update` 与 `set` 的区别:
113
+
114
+ | | `set` | `update` |
115
+ | --- | --- | --- |
116
+ | 起点 `startedAt` | **重置**(计时从头算) | **保留**(已用时间仍算数) |
117
+ | 时长 | 必填 | 可选(省略=不变) |
118
+ | prompt | 必填 | 必填 |
119
+ | 用途 | 开一局新的 | 迭代提示词 / 调整时长 |
120
+
121
+ `update` 改时长时:`deadline = startedAt + 新时长`。
122
+
123
+ ## Web 端操作
124
+
125
+ 面板「本地任务」页有两处入口(都是**纯 UI 便利**,数据与逻辑仍属 timegoal 模块):
126
+
127
+ **1. 顶部「时间目标」汇总卡** —— 列出所有目录的 timegoal(包括还没在看板里出现过
128
+ 的目录):
129
+
130
+ - **新建**:填目录 + 时长 + 提示词 → 创建
131
+ - **编辑**:改时长 / 提示词;默认**保留计时起点**,勾「重置起点」才从头计
132
+ - **清空**:删除该目录的 timegoal
133
+ - 状态列显示 `剩 mm:ss` 或 `已到点`,每 1.5s 自动刷新
134
+
135
+ **2. 主题卡里的 timegoal 行**:
136
+
137
+ - 已设置 → `时间目标剩余 mm:ss` / `已到点(用时 ...)` +「查看提示词 / 编辑 / 清空」
138
+ - 未设置 → 「未设置时间目标」+「设置」(为该目录新建)
139
+
140
+ 时长输入带快捷按钮(30 分钟 / 1 / 2 / 3 / 8 小时)。
141
+
142
+ ## 与其它机制的关系
143
+
144
+ **没有依赖关系。** timegoal 只做两件事:算时间、回显提示词原文。
145
+
146
+ - 不调用 `localtask wait`:等不到任务是别的事,与是否到点无关
147
+ - 不阻塞任何东西:可以同时跑人机接力、派任务给别的 agent、外部 cron
148
+ - 不需要登录 KV 后端:纯本机
149
+
150
+ 你可以把它当成一个独立计时器 + 便签本:`set` 把便签写进文件,`check` 读出来
151
+ 顺便告诉你还剩多少时间。
152
+
153
+ ## 安装
154
+
155
+ ```bash
156
+ nx-kv skill install kv-timegoal
157
+ ```
158
+
159
+ 要详细时序与一份可抄走的 prompt 模板("调研开源 Redis 差距并逼近生产级数据库"
160
+ 那种 3 小时任务的范例),读 `references/workflow.md`(按需加载,不查时序不必读)。
@@ -0,0 +1,151 @@
1
+ # kv-timegoal · 时序与完整示例
2
+
3
+ 按需加载:只是想看命令的话回到 [[kv-timegoal|SKILL.md]],不必读这份。
4
+ 下面给一份能复刻的"3 小时调研 Redis 差距并自迭代实现生产级数据库"任务
5
+ 完整时序,含可直接抄走的 prompt 模板。
6
+
7
+ ---
8
+
9
+ ## 完整时序(一次 timegoal 循环长什么样)
10
+
11
+ ```
12
+ ┌──────────────────┐
13
+ │ ~/.nx-kv/ │
14
+ │ timegoals.json │
15
+ │ (独立存储) │
16
+ └──────────────────┘
17
+ ▲
18
+ │ set/update/check/clear
19
+ │ 都只读写这一个文件
20
+ │
21
+ ┌─────────┐ ▼
22
+ │ user │ cli: nx-kv timegoal <...> ──────►─┐
23
+ │ (人) │ │
24
+ │ │ web: 时间目标 主题卡里内嵌显示 │ ┌──────────────┐
25
+ │ │ (逻辑上无关) │ │ nx-kv │
26
+ └─────────┘ │ │ timegoal │
27
+ │ │ module │
28
+ │ │ (独立模块) │
29
+ └──────┬───────┘
30
+ │
31
+ ┌─────────────┐ ▼
32
+ │ agent │ cli: nx-kv timegoal set/update/check (事实源)
33
+ │ (LLM) │ ★ agent 唯一读取指令来源 = check 返回的 prompt 字段
34
+ └──────┬──────┘
35
+ │
36
+ │ 每一轮:
37
+ ▼
38
+ ┌───────────────────────────────────────────────────────┐
39
+ │ 1. nx-kv timegoal check --cwd "$PWD" --json │
40
+ │ ↓ 拿到 {remainingSec, prompt} │
41
+ │ 2. 把 prompt 字段当本轮根指令 │
42
+ │ 3. 干活(按 prompt 指令): │
43
+ │ · 调 subagent 调研差距、产出最小补丁 + 测试 │
44
+ │ · 把本轮成果追加到 CHANGELOG.md 与 .timegoal-log.md │
45
+ │ 4. 如本轮调研发现 prompt 漏条件: │
46
+ │ nx-kv timegoal update --prompt "<V2>" --json │
47
+ │ (**只换 prompt、截止时间不动**) │
48
+ │ 5. 回到第 1 步 │
49
+ └───────────────────────────────────────────────────────┘
50
+ │
51
+ ▼
52
+ ┌───────────────────────────────────────────────────────┐
53
+ │ 拿到的 {reached: true} 那一轮: │
54
+ │ · 写完本轮总结 │
55
+ │ · 不再开新轮、不再 check(除非写最终总结查 prompt) │
56
+ │ · 退出本循环 │
57
+ └───────────────────────────────────────────────────────┘
58
+ ```
59
+
60
+ **关键**:timegoal 循环里**只有 `timegoal` 命令族**,没有 `localtask wait`、
61
+ 没有别的 nx-kv 命令。可以把它单独跑、可以并行跑——互不感知。
62
+
63
+ ## 完整可抄走的 prompt 模板("调研 Redis 差距并逼近生产级数据库")
64
+
65
+ ```text
66
+ 你是「Redis-compatible 生产级数据库」的迭代研发 agent;目标是用 N 小时
67
+ (到 set 的 deadline 为止)持续调研当前项目与开源 Redis 的能力差距,
68
+ 逐轮修复差距、把改进写到 CHANGELOG.md,并自我迭代本 prompt 让下一轮更高效。
69
+
70
+ 每轮你必须做:
71
+ 1. 调 subagent(general-purpose)对比「当前项目 + 上一轮改进」与「开源
72
+ Redis 最新稳定版」的能力清单,输出 1-3 个本轮最高 ROI 的差距修复项。
73
+ 2. 对每项写出最小可工作补丁 + 测试,写完跑测试;失败的子任务要在下一轮
74
+ 优先重试。
75
+ 3. 把本轮成果追加一行到 CHANGELOG.md(格式:「- [YYYY-MM-DD HH:mm] 干了什么」)。
76
+ 4. 把本轮总结写到 .timegoal-log.md 的同一行尾(每轮一行)。
77
+ 5. 如果 subagent 给出"prompt 优化建议":调 `nx-kv timegoal update --cwd "$PWD"
78
+ --prompt "<新版 V(N+1)>"` 把下一轮的 prompt 替换掉。**不要调 set**——
79
+ set 会把已用时间清零。
80
+
81
+ 硬性约束:
82
+ - 严禁超过本轮剩余时间预算(remainingSec < 30 时立刻停手、写总结、不开新轮)
83
+ - 严禁自己改 deadline;想缩短就 `timegoal clear` 再 `timegoal set`
84
+ - 每轮开始时先 `nx-kv timegoal check --cwd "$PWD" --json`,把返回里的
85
+ `prompt` 字段当作本轮根指令;**不要从对话历史里重新拼**——以 store 为准
86
+ - 写代码必须随附测试;测试失败的修补不计入本轮成果
87
+ ```
88
+
89
+ 把这个 prompt 一次性 `timegoal set` 进 store,agent 之后每一轮照着干到点为止。
90
+
91
+ ## 实际跑(手工模拟)
92
+
93
+ ```bash
94
+ WORKDIR=/path/to/your-project
95
+ cd "$WORKDIR"
96
+
97
+ # 1. set
98
+ nx-kv timegoal set --cwd "$PWD" --duration 10800 \
99
+ --prompt "..." --json
100
+
101
+ # 2. 立刻 check:reached:false
102
+ nx-kv timegoal check --cwd "$PWD" --json
103
+
104
+ # 3. sleep 6s
105
+ sleep 6
106
+
107
+ # 4. 再 check:注意 elapsedSec 增加
108
+ nx-kv timegoal check --cwd "$PWD" --json
109
+
110
+ # 5. update:只换 prompt,deadline 不动
111
+ nx-kv timegoal update --cwd "$PWD" --prompt "V2 改得更简洁" --json
112
+
113
+ # 6. check:prompt 已是 V2,deadline 仍是 1 小时后
114
+ nx-kv timegoal check --cwd "$PWD" --json
115
+
116
+ # 7. 等到点(或手动改 store)后:reached:true
117
+ # (实操:把 ~/.nx-kv/timegoals.json 里 startedAt 改成 4 小时前)
118
+
119
+ # 8. clear
120
+ nx-kv timegoal clear --cwd "$PWD" --json
121
+
122
+ # 全程不曾、也不需调过 localtask / todo / 等任何其它命令族
123
+ ```
124
+
125
+ ## 常见问题
126
+
127
+ | 现象 | 原因 / 做法 |
128
+ | --- | --- |
129
+ | `reached` 没翻 | 检查客户端时区或 set 时是否给了 `--duration` 过短(默认下限 60s) |
130
+ | update 失败"主题「X」尚未设置 timegoal" | 先 `set` 再 `update`;`update` 不创建 |
131
+ | clear 返回"无需清空" | 本来就没设过;这是 info 不是 error |
132
+ | 想换目录 | clear 旧的 → set 新的;目录(cwd)是绑定的 |
133
+ | 想中途换 task queue | **与 timegoal 无关**——本模块不参与队列,那是其它事 |
134
+ | 想同时用 localtask 等用户 | **可以同时跑**——两套独立循环、各管各的;timegoal 只关心自身 deadline |
135
+
136
+ ## timegoal 的运行边界
137
+
138
+ ```
139
+ timegoal 循环里只有 timegoal 命令族——没有别的 nx-kv 命令参与。
140
+
141
+ 跑 100 轮 timegoal 不需要任何其它机制配合;
142
+ 反过来,跑别的东西也不需要 timegoal 配合。
143
+
144
+ · timegoal 只做两件事:算时间、回显提示词原文
145
+ · 不阻塞任何东西——可以同时跑人机接力、派任务给别的 agent、外部 cron
146
+ · 不需要登录 KV 后端——纯本机
147
+ · 数据落在本机文件(timegoals.json),可由环境变量 NX_KV_TIMEGOAL_STORE 改路径
148
+ ```
149
+
150
+ **唯一的交互面**是 CLI 与 web 主题卡上的三个按钮(查看 / 编辑 / 清空),
151
+ 没有任何隐式联动。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx-kv",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "nx-kv — KV 清单管理中枢(远程)+ 本机本地任务队列(localtask):serve 驱动 CLI 与 Web 面板,同源同构,附带可安装 skill 供 agent 提交 / 领取 / 阻塞接收任务",
5
5
  "type": "module",
6
6
  "bin": {