nx-kv 0.13.0 → 0.14.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 +65 -0
- package/assets/groups.json +16 -20
- package/assets/kv-get/SKILL.md +100 -0
- package/assets/{kv-localget/SKILL.md → kv-get/references/localget.md} +21 -4
- package/assets/{kv-timegoal/references/workflow.md → kv-get/references/timegoal-workflow.md} +1 -1
- package/assets/{kv-timegoal/SKILL.md → kv-get/references/timegoal.md} +14 -1
- package/assets/{kv-waittask/references/kv-waittask-workflow.md → kv-get/references/wait-workflow.md} +11 -2
- package/assets/{kv-waittask/SKILL.md → kv-get/references/waitloop.md} +10 -1
- package/assets/kv-repo/SKILL.md +29 -2
- package/assets/kv-submit/SKILL.md +20 -6
- package/assets/nx-kv/references/repo-registry.md +2 -2
- package/package.json +1 -1
- package/src/core/instruction-template.js +109 -0
- package/src/core/keys.js +32 -0
- package/src/core/zip.js +69 -5
- package/src/modules/docs/docref.js +77 -0
- package/src/modules/docs/index.js +354 -0
- package/src/modules/docs/knowledge.js +340 -0
- package/src/modules/docs/links.js +43 -0
- package/src/modules/docs/paths.js +102 -0
- package/src/modules/docs/refs.js +201 -0
- package/src/modules/docs/repos-bridge.js +11 -0
- package/src/modules/docs/seed.js +147 -0
- package/src/modules/docs/store.js +213 -0
- package/src/modules/docs/wikilink.js +63 -0
- package/src/modules/localtask/index.js +169 -23
- package/src/modules/localtask/service.js +253 -356
- package/src/modules/repos/boards.js +48 -90
- package/src/modules/repos/index.js +146 -52
- package/src/modules/repos/service.js +109 -104
- package/src/modules/repos/transfer.js +198 -27
- package/src/modules/tasktool/get.js +54 -0
- package/src/modules/tasktool/getloop.js +84 -0
- package/src/modules/tasktool/groupctx.js +73 -0
- package/src/modules/{timegoal → tasktool}/index.js +27 -9
- package/src/modules/tasktool/taskgoal.js +100 -0
- package/src/modules/{timegoal/service.js → tasktool/timegoal.js} +141 -16
- package/src/modules/tasktool/wait.js +485 -0
- package/src/modules/todo/index.js +1 -1
- package/src/runtime/registry.js +3 -2
- package/src/web/frontend/App.jsx +181 -123
- package/src/web/frontend/components/Introduction/index.jsx +76 -0
- package/src/web/frontend/components/Introduction/rail.jsx +141 -0
- package/src/web/frontend/components/Introduction/style.css +43 -0
- package/src/web/frontend/components/Introduction/use-intro.js +153 -0
- package/src/{modules/todo → web/frontend/components/cloud}/editor.jsx +2 -2
- package/src/{modules/todo → web/frontend/components/cloud}/group-popup.jsx +3 -3
- package/src/{modules/todo → web/frontend/components/cloud}/markdown.jsx +1 -1
- package/src/{modules/todo → web/frontend/components/cloud}/row-menu.jsx +1 -1
- package/src/{modules/todo → web/frontend/components/cloud}/upload.js +1 -1
- package/src/web/frontend/components/icons.jsx +8 -0
- package/src/web/frontend/{modules/md-workspace → components/md}/attach-bar.jsx +1 -1
- package/src/web/frontend/components/md/doc-outline-rail.jsx +2 -0
- package/src/web/frontend/{modules/md-workspace → components/md}/md-panes.jsx +2 -2
- package/src/web/frontend/{modules/md-workspace → components/md}/template-editor.jsx +2 -2
- package/src/web/frontend/{modules/md-workspace → components/md}/tool-bar.jsx +2 -7
- package/src/{modules → web/frontend/components}/repos/transfer-panel.jsx +2 -2
- package/src/web/frontend/components/sidebar/index.jsx +39 -6
- package/src/web/frontend/components/sidebar/model.js +1 -0
- package/src/web/frontend/components/sidebar/panel.jsx +135 -40
- package/src/web/frontend/components/sidebar/rescue-fab.jsx +78 -0
- package/src/web/frontend/components/sidebar/row-menu.jsx +2 -15
- package/src/web/frontend/components/sidebar/side-state.js +48 -0
- package/src/web/frontend/main.jsx +1 -0
- package/src/web/frontend/modules/{md-workspace → md}/doc-store.js +9 -1
- package/src/web/frontend/modules/{md-workspace → md}/md-parse.js +105 -10
- package/src/web/frontend/modules/{md-workspace → md}/style.css +207 -11
- package/src/{modules/todo/view.jsx → web/frontend/page/cloud/index.jsx} +9 -9
- package/src/web/frontend/{modules/md-workspace/view.jsx → page/dir/index.jsx} +73 -20
- package/src/web/frontend/{modules/md-workspace → page/dir}/landing.jsx +72 -11
- package/src/web/frontend/{modules/md-workspace/page-panel.jsx → page/dir/task.jsx} +119 -12
- package/src/web/frontend/page/doc/index.jsx +410 -0
- package/src/{modules/repos/group-view.jsx → web/frontend/page/group/index.jsx} +51 -17
- package/src/{modules/localtask/view-overview.jsx → web/frontend/page/overview/index.jsx} +5 -5
- package/src/web/frontend/{modules/md-workspace/progress-panel.jsx → page/progress/index.jsx} +1 -1
- package/src/{modules/repos/view.jsx → web/frontend/page/repos/index.jsx} +93 -142
- package/src/web/frontend/page/settings/index.jsx +614 -0
- package/src/web/frontend/page/settings/style.css +182 -0
- package/src/web/frontend/{modules/md-workspace/template-manager.jsx → page/templates/index.jsx} +49 -47
- package/src/web/frontend/panels.jsx +55 -13
- package/src/web/frontend/registry.js +6 -6
- package/src/web/frontend/style-v2.css +131 -45
- package/src/web/frontend/style.css +0 -39
- package/src/web/frontend/workspace.js +228 -13
- package/src/web/public/assets/CliHints-BDC8qSBg.js +1 -0
- package/src/web/public/assets/Introduction-CZvmavXZ.js +1 -0
- package/src/web/public/assets/Introduction-Q36q9sjA.css +1 -0
- package/src/web/public/assets/{view-D-Ve3jn9.js → cloud-DDTf0Ljk.js} +3 -3
- package/src/web/public/assets/dir-Bauem8qN.js +3 -0
- package/src/web/public/assets/doc-store-CRH31l1Q.js +1 -0
- package/src/web/public/assets/group-BWeJJ-4E.js +1 -0
- package/src/web/public/assets/index-BzFIjdgF.css +1 -0
- package/src/web/public/assets/index-D7TgK5c2.js +48 -0
- package/src/web/public/assets/jsx-runtime-D3jfb0Ew.js +1 -0
- package/src/web/public/assets/md-edit-ops-Bl0Zx0aJ.js +22 -0
- package/src/web/public/assets/md-history-DbrRw05Z.js +4 -0
- package/src/web/public/assets/{view-overview-B6pbN-hr.js → overview-DuQqT7Sm.js} +1 -1
- package/src/web/public/assets/{progress-panel-BWuNb1HU.js → progress-CcuQs9HB.js} +3 -3
- package/src/web/public/assets/repos-CR5N8i-H.js +10 -0
- package/src/web/public/assets/settings-UGe4AuO-.css +1 -0
- package/src/web/public/assets/settings-xaB1ARF_.js +1 -0
- package/src/web/public/assets/task-1grt3vdp.js +2 -0
- package/src/web/public/assets/templates-CRf1uhuz.js +2 -0
- package/src/web/public/index.html +3 -3
- package/src/web/public/assets/CliHints-BNQsBqZi.js +0 -1
- package/src/web/public/assets/doc-store-CA9Jn7_9.js +0 -1
- package/src/web/public/assets/group-view-CJVzYtci.js +0 -1
- package/src/web/public/assets/index-H_va8kI7.css +0 -1
- package/src/web/public/assets/index-clupHox-.js +0 -69
- package/src/web/public/assets/jsx-runtime-Dk72oS4N.js +0 -1
- package/src/web/public/assets/page-panel-wVjYxy-c.js +0 -5
- package/src/web/public/assets/view-BaFnDBlk.js +0 -19
- package/src/web/public/assets/view-CyStUXmO.js +0 -2
- /package/assets/{kv-repo-mmx-gitrepo/SKILL.md → kv-repo/references/mmx-gitclone.md} +0 -0
- /package/src/web/frontend/{modules/md-workspace → components/md}/attachments.js +0 -0
- /package/src/web/frontend/{modules/md-workspace → components/md}/sel-menu.jsx +0 -0
- /package/src/web/frontend/{modules/md-workspace → components/md}/shortcut-sheet.jsx +0 -0
- /package/src/web/frontend/modules/{md-workspace → md}/md-edit-ops.js +0 -0
- /package/src/web/frontend/modules/{md-workspace → md}/md-history.js +0 -0
- /package/src/web/frontend/modules/{md-workspace → md}/use-templates.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,71 @@
|
|
|
2
2
|
|
|
3
3
|
本文件记录对外可见的变更。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。
|
|
4
4
|
|
|
5
|
+
## [0.14.0] - 2026-11-03 wait 收尾指令模板化 + 回调提示词/持续 get 可配多条 + timegoal 面板入口 + 前缀归组改一次性命令 + 删全局默认时长
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **回调提示词可配多条**:`localtask config` 的收尾指令从单条升级为**列表**
|
|
10
|
+
(`settings.taskSuffix` 存 `string[]`,上限 10 条、单条 ≤2000 字)。设置面板
|
|
11
|
+
「模板与任务工具」改为按条编辑(每条一个文本框 + 删除,「添加一条…」追加,
|
|
12
|
+
一次保存整体生效);CLI 新增 `--suffix-add "<指令>"` 追加一条、
|
|
13
|
+
`--suffix-remove <序号>` 按序号删一条(与 `--suffix` / `--no-suffix` / `--reset-suffix`
|
|
14
|
+
互斥)。交付语义不变:多条按空行拼接后统一分流——任一条含 `{{` 整体渲染进
|
|
15
|
+
`instruction` 字段,纯文本仍追加正文末尾;删光 = 关闭。
|
|
16
|
+
- 兼容:旧单条 store(string)读入时整体迁为一列、不拆段;`--suffix "<文本>"`
|
|
17
|
+
仍是「整体替换为这一条」;设置视图同时暴露 `taskSuffix`(多条拼接串,旧消费者
|
|
18
|
+
无感)与 `taskSuffixList`(canonical 列表,UI/CLI 按条编辑用)。
|
|
19
|
+
- **项目级「持续 get」模板同步支持多条**(`getLoop.template` 存 `string[]`,同上限
|
|
20
|
+
规则):设置面板「项目级设置」的持续 get 区块同款按条编辑;交付时多条按空行
|
|
21
|
+
拼接后统一渲染,全部留空 = 用默认模板;`getLoopForCwd` 暴露 `template`(拼接串)
|
|
22
|
+
与 `templateList`(列表)。CLI `--get-loop-template` 仍是「整体替换为这一条」。
|
|
23
|
+
|
|
24
|
+
- **timegoal 时长删除全局默认,只在发布任务时设置**:任务时间目标的时长只在
|
|
25
|
+
`localtask add --duration` 显式给出(发布时校验写法),不再有「发布没给时长就按
|
|
26
|
+
全局默认计时」的兜底。设置面板「模板与任务工具」的「任务时间目标默认时长」输入框
|
|
27
|
+
与 CLI `localtask config --default-duration / --clear-default-duration` 一并移除。
|
|
28
|
+
- ⚠️ 升级注意:存量 store 里的 `settings.defaultDuration` 残留值被忽略(下次落盘
|
|
29
|
+
丢弃);此前靠默认时长隐式带时间目标的任务,现在发布时需显式 `--duration`。
|
|
30
|
+
|
|
31
|
+
- **timegoal 面板入口补齐(发布 + 编辑都可设)**:此前带时长的任务只能 CLI 发布——
|
|
32
|
+
面板任务编辑页没有时间目标入口。现在编辑页标题栏下新增「⏱ 时间目标」行(时长 +
|
|
33
|
+
可选附加要求):草稿提交即带声明(POST `/api/localtasks` 的 `duration`/`goalPrompt`
|
|
34
|
+
字段本来就已支持);**未领取**的任务在编辑页可改/清声明(`localtask update` 新增
|
|
35
|
+
`--duration` / `--goal-prompt` / `--clear-goal`,`--text` 在只改时间目标时可省);
|
|
36
|
+
已领取计时中的任务声明冻结(要调先 reopen 重开)。目录任务表任务标题旁显示
|
|
37
|
+
`⏱ <时长>` 徽标(悬停看附加要求)。
|
|
38
|
+
- 语义约束:`--clear-goal` 与 `--duration` 互斥;只带附加要求不带时长在发布端报错;
|
|
39
|
+
改时长不带 `--goal-prompt` 则保留原附加要求。
|
|
40
|
+
|
|
41
|
+
- **按前缀归组改为一次性命令,废除常驻规则**:原「仓库名以某前缀开头 → 自动算成员」
|
|
42
|
+
的前缀分组规则(`board prefix list/add/remove`、仓库页「按前缀分组」区块)整块移除,
|
|
43
|
+
改为一条一次性命令 `nx-kv board prefix <prefix> [--board <看板>]`——跑一次就把名字
|
|
44
|
+
以 `<prefix>` 开头(大小写不敏感)的已登记仓库**固化成目标看板的显式成员**(与手工
|
|
45
|
+
挂的完全同权);`--board` 省略 = 按前缀名自动建同名看板。成员关系从此只有显式成员
|
|
46
|
+
一个来源;之后新登记的仓库要再跑一次命令。组详情页随之去掉「归属(手动/按前缀)」列。
|
|
47
|
+
- ⚠️ 升级注意:存量 `prefixGroups` 规则不再生效、下次落盘时被丢弃;原来由规则
|
|
48
|
+
动态归组的仓库会回到未分组——需要的话对每个前缀各跑一次 `board prefix` 补回。
|
|
49
|
+
|
|
50
|
+
- **wait 收尾指令模板化(task / waittask / timegoal 融合)**:`localtask config --suffix`
|
|
51
|
+
从「固定追加语」升级为**占位符模板**。含 `{{` 的值在 wait 返回时由服务端渲染成融合
|
|
52
|
+
指令,放进返回载荷的新字段 `instruction`;默认模板 = 该目录 timegoal 状态
|
|
53
|
+
(`〔时间目标「目录名」剩余 X〕`,到点显示「已到点(已超时 X)」)+ 原收尾要求。
|
|
54
|
+
**模板模式下 `task.text` 保持库存原文、不再追加指令**(正文与指令分区打印)。
|
|
55
|
+
- 兼容:纯文本(无 `{{`)维持 v0.x 的 task.text 追加行为(旧 skill 副本不失效);
|
|
56
|
+
`''` 仍 = 关闭;显式存过旧默认文本的 store 需 `localtask config --reset-suffix`
|
|
57
|
+
才拿到新默认模板。
|
|
58
|
+
- 占位符:`{{goal.name}} {{goal.remainingHuman}} {{goal.deadline}} {{goal.prompt}}
|
|
59
|
+
{{task.id}} {{task.text}} {{source}} {{summary}} {{cwd}} {{name}}`;段落
|
|
60
|
+
`{{#goal}}…{{/goal}}`、`{{#task}}…{{/task}}` 上下文缺失时整段消失。渲染是服务端
|
|
61
|
+
**单遍确定性替换**——goal.prompt / task.text 里的 `{{...}}` 逐字保留、绝不二次
|
|
62
|
+
展开(防漂移契约延伸到字符串层)。
|
|
63
|
+
- 新核心模块 `src/core/instruction-template.js`(纯函数、零依赖);模板长度上限
|
|
64
|
+
500 → 2000(渲染产物不设限)。渲染走 `showTimegoal` 只读路径,不写盘、不影响
|
|
65
|
+
`timegoal check` 契约与到点自动收尾(goal_expired)行为。
|
|
66
|
+
- ⚠️ 降级注意:旧版 nx-kv 打开存了新默认模板的 store 会把原始 `{{...}}` 当纯文本
|
|
67
|
+
追加进 task.text(自定义模板超过旧版 500 上限的还会被截断)——请整版升级,
|
|
68
|
+
不要混跑新旧二进制。
|
|
69
|
+
|
|
5
70
|
## [0.13.0] - 2026-10-31 任务模板可配置 + 完成任务可删除 + 无队列仓库可从侧边栏新建任务 + 仓库前缀分组
|
|
6
71
|
|
|
7
72
|
### Added
|
package/assets/groups.json
CHANGED
|
@@ -3,32 +3,28 @@
|
|
|
3
3
|
"$comment": "group 名 → skill 名列表的别名表。当前 group 名 ≡ skill 名(一对一);skills 是数组,为「一个 group 含多个 skill」预留。路径恒由 assets/<skills[i]>/ 推导——本文件只做聚合,不是第二条事实源。",
|
|
4
4
|
"groups": {
|
|
5
5
|
"nx-kv": {
|
|
6
|
-
"skills": [
|
|
6
|
+
"skills": [
|
|
7
|
+
"nx-kv"
|
|
8
|
+
],
|
|
7
9
|
"summary": "KV 清单管理中枢主 skill(默认 install 装的就是这个):todo / group / 工作空间(远程,需登录)"
|
|
8
10
|
},
|
|
9
|
-
"kv-
|
|
10
|
-
"skills": [
|
|
11
|
-
|
|
11
|
+
"kv-get": {
|
|
12
|
+
"skills": [
|
|
13
|
+
"kv-get"
|
|
14
|
+
],
|
|
15
|
+
"summary": "领取与完成本机任务:get 领活 / wait 等人回填 / 时间目标 check 门禁 / done 完成 / reopen 按反馈重开"
|
|
12
16
|
},
|
|
13
17
|
"kv-submit": {
|
|
14
|
-
"skills": [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"skills": ["kv-localget"],
|
|
19
|
-
"summary": "领取排给本目录的本地任务 + 队列管理(领取侧)"
|
|
20
|
-
},
|
|
21
|
-
"kv-timegoal": {
|
|
22
|
-
"skills": ["kv-timegoal"],
|
|
23
|
-
"summary": "把「持续运行 N 小时」任务固化到 nx-kv:每轮回显原文提示词防偏移 + 时间到点自动停手"
|
|
18
|
+
"skills": [
|
|
19
|
+
"kv-submit"
|
|
20
|
+
],
|
|
21
|
+
"summary": "总结上下文、提炼用户需求,提交到别的目录队列委托其它 agent(提交侧);可带 --duration 时间目标"
|
|
24
22
|
},
|
|
25
23
|
"kv-repo": {
|
|
26
|
-
"skills": [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"skills": ["kv-repo-mmx-gitrepo"],
|
|
31
|
-
"summary": "mmx 深度搜索并克隆参考仓库——repo ref clone 统一落 gitRepoRoot、remote 为 key 登记绑定,替代散装的 git clone + git.remote 清单流程"
|
|
24
|
+
"skills": [
|
|
25
|
+
"kv-repo"
|
|
26
|
+
],
|
|
27
|
+
"summary": "仓库组识别与关系报告;克隆外源参考仓库并强制读(读参考实现不许只凭搜索摘要)"
|
|
32
28
|
}
|
|
33
29
|
}
|
|
34
30
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kv-get
|
|
3
|
+
description: 领取与完成排给本工作目录的本地任务(别人通过 kv-submit 委托的、用户在面板/弹窗排队的,都落在「目录名即主题」的队列里)——用 localtask get 取活(默认直接领;项目开启「持续 get」后自动阻塞等人回填)、localtask wait 挂着等人接力、localtask done 标记完成(带时间目标的任务未到点会被拒绝,提示派 sub agent 重提需求)、localtask reopen 把用户的修改反馈送回队列重新执行。触发词:领取本地任务、看看有没有排给我的任务、本地队列、领取委托任务、拿任务、本目录的任务、排队任务、localtask get、localtask wait、标记完成、任务完成、修改反馈、重新执行、kv-get。凡「主动获取排给本目录的任务」以及「把任务标记完成/按反馈重开」的场景都走本 skill。反例:把需求提交/委托给别的目录用 kv-submit;查本机仓库分组与参考仓库用 kv-repo;操作远程 KV 清单(todo)用 nx-kv。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# kv-get — 领取、执行、完成(领取侧)
|
|
7
|
+
|
|
8
|
+
一个 skill 覆盖本机任务的**完整生命周期**:领 → 干 → 标完成 → 按反馈重开。
|
|
9
|
+
细节拆在 references 里,按需读:
|
|
10
|
+
|
|
11
|
+
- [[localget]] — 领取侧:队列管理、单条查看/编辑/删除/调序
|
|
12
|
+
- [[waitloop]] — 等待侧契约:wait 是本轮最后一步,唯一合法出口是 timeout
|
|
13
|
+
- [[timegoal]] — 时间目标:目录级与**任务级**(领取即计时)的 check 门禁
|
|
14
|
+
- [[wait-workflow]] / [[timegoal-workflow]] — 两套循环的细则
|
|
15
|
+
|
|
16
|
+
## 三个动作,三种语义(别混用)
|
|
17
|
+
|
|
18
|
+
| 动作 | 命令 | 语义 |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| **领活** | `nx-kv localtask get --summary "<现状>" --json` | 队列有任务**立即领走**;没有就**立即返回 timeout**(不阻塞、不开窗)——「暂时没活」是正常业务结果 |
|
|
21
|
+
| **等人** | `nx-kv localtask wait --summary "<现状>" --timeout 30 --json` | 阻塞等人回填;**本轮最后一步**,唯一合法出口是 timeout |
|
|
22
|
+
| **挂着领** | 同上,但项目开启了「持续 get」 | `get` 升级为 waitgoal:无任务自动唤起(打开目录页面 + 项目配置的分钟数),期间用户回填就直接领到;领到的交付文本自带「继续 get 直到超时」的项目模板 |
|
|
23
|
+
|
|
24
|
+
「持续 get」是**项目级**开关(设置面板 → 项目级设置,或 `repo update --get-loop on`),
|
|
25
|
+
默认关闭——默认就是「直接 get」。
|
|
26
|
+
|
|
27
|
+
## 领取到的东西必须读全
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
nx-kv localtask get --summary "<本轮现状>" --json
|
|
31
|
+
# → { status:"ok", task:{id,text,...}, instruction:"…" }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- `task.text` = 任务正文(Markdown),**永远读它**;
|
|
35
|
+
- `instruction` = 服务端渲染的指令段,**有则必读**(与 task.text 一起构成这一轮的根指令):
|
|
36
|
+
- **项目组上下文**(领的是组内仓库时):组定位、组介绍、本项目在组里的位置、兄弟成员的角色、组绑定参考文件的**可读路径**——这些路径是磁盘上的真实文件,需要细节就直接读;
|
|
37
|
+
- **收尾指令**(可配置,默认「本轮最后再 wait 一次」);
|
|
38
|
+
- **任务级时间目标的 check 指令**(见下)。
|
|
39
|
+
|
|
40
|
+
## 时间目标:领取即计时,未到点不许标完成
|
|
41
|
+
|
|
42
|
+
发布方可以给单条任务带时长(`localtask add … --duration 2h`)。这种任务被领取时
|
|
43
|
+
**自动起表**,交付文本里带一条固定指令:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
nx-kv timegoal check --task task:<topicKey>:<taskId> --summary "<本轮现状>" --progress "<进展/下一步>"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
每轮推进先跑一次 check(它会原文回显时间目标提示词,防长对话漂移)。
|
|
50
|
+
**时间未到不能标完成**——`localtask done` 会返回业务结果(不是错误):
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{ "status": "blocked", "reason": "goal_not_reached", "remainingSec": 1830,
|
|
54
|
+
"hint": "时间未到,不能标记完成——请派出 sub agent 重新提出新的需求;到点后…再来标完成" }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
此时**不要**硬标完成、也不要自己改时间:按提示**派 sub agent 重新提出新的需求**,
|
|
58
|
+
再继续推进;到点(check 返回 `reached:true`)后再 `done`:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
nx-kv localtask done --id <n> --summary "<完成总结>" --json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
没有时间目标的任务直接 done 即可。目录级 timegoal(`timegoal set --cwd …`)是另一回事:
|
|
65
|
+
它是「这个目录整体要跑多久」的预算,见 [[timegoal]]。
|
|
66
|
+
|
|
67
|
+
## 完成与反馈:闭环的两端
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# 标记完成(完成总结必填——它就是下一轮 agent 能看到的「上轮做了什么」)
|
|
71
|
+
nx-kv localtask done --id <n> --summary "<完成总结>" [--progress "<完成度/下一步>"]
|
|
72
|
+
|
|
73
|
+
# 用户看了结果提修改意见 → 任务回到待领取,agent 可再次领取(执行循环继续)
|
|
74
|
+
nx-kv localtask reopen --id <n> [--text "<改后的正文(Markdown)>"] --json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`reopen` 会作废领取时间(新一轮从**再次领取**开始重新计时)、清掉完成标记,
|
|
78
|
+
但**保留上一轮的完成总结**——下一轮接手时 agent 能看到自己上轮做到哪。
|
|
79
|
+
|
|
80
|
+
## 硬规则
|
|
81
|
+
|
|
82
|
+
1. **同一个目录同一时刻只挂一个 wait**(waiters 是进程内注册表,一个 key 只能有一个)。
|
|
83
|
+
2. **timeout 是业务结果,不是错误**(exit 0):按「暂时没活」收尾,**不要**当失败重试。
|
|
84
|
+
3. **wait 是本轮最后一步**:拿到任务或超时之前,不要提前结束本轮。
|
|
85
|
+
4. **instruction 有则必读**:里面的组上下文/时间目标/收尾要求都是硬约束。
|
|
86
|
+
5. **带时间目标的任务不许提前标完成**——被拒绝就按提示派 sub agent 重提需求。
|
|
87
|
+
6. **同一时刻只挂一个 wait**;`get` 与 `wait` 不要并发跑(都在同一队列上抢任务)。
|
|
88
|
+
|
|
89
|
+
## 队列管理(需要时)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
nx-kv localtask list --json # 全部主题:目录、现状、等待中、待领取数
|
|
93
|
+
nx-kv localtask show --id <n> --json # 查看单条(get 已是「领取」动词)
|
|
94
|
+
nx-kv localtask update --id <n> --text "<新内容>" --json # 改正文;--duration 2h 设时间目标、--clear-goal 清除(仅未领取时可改)
|
|
95
|
+
nx-kv localtask remove --id <n> --json # 软删除(CLI restore 可恢复)
|
|
96
|
+
nx-kv localtask reorder --id <n> --before-id <m> --json
|
|
97
|
+
nx-kv localtask topic remove --cwd "<目录>" # 删整个主题(等待中需 --force)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
以上都不传 `--cwd` 时按进程当前目录定位。
|
|
@@ -16,24 +16,41 @@ description: 领取排给本工作目录的本地任务——别人通过 kv-sub
|
|
|
16
16
|
nx-kv localtask list --json
|
|
17
17
|
# → {topics:[{key,cwd,name,summary,waiting,pending,total,tasks:[...]}], waiting, settings}
|
|
18
18
|
|
|
19
|
-
# 2. 有待领取 →
|
|
20
|
-
nx-kv localtask
|
|
19
|
+
# 2. 有待领取 → 取走最早的一条(默认「直接 get」:队列非空立即返回,不开窗不阻塞)
|
|
20
|
+
nx-kv localtask get --summary "<本轮现状,如:空闲,领取新任务>" --json
|
|
21
21
|
# → {status:"ok", queued:true, task:{id,text,...}}
|
|
22
22
|
|
|
23
|
+
# 2b. 想挂着等活(阻塞等人回填)→ 用 wait(kv-waittask 的循环契约)
|
|
24
|
+
nx-kv localtask wait --summary "<本轮现状>" --timeout 30 --json
|
|
25
|
+
|
|
23
26
|
# 3. 执行 task.text(内容永远读 task.text,id 只是编号),产出落在本目录
|
|
27
|
+
|
|
28
|
+
# 4. 干完标记完成(带时间目标的任务:未到点会被拒绝)
|
|
29
|
+
nx-kv localtask done --id <n> --summary "<完成总结>" --json
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
- `queued:true` = 从队列取到任务,直接执行。
|
|
33
|
+
- 返回可能带 `instruction` 字段(收尾指令模板的渲染结果,默认含该目录 timegoal 的
|
|
34
|
+
剩余预算 +「计划最后再 wait 一次」)——有则必读,与 `task.text` 一起构成这一轮的
|
|
35
|
+
根指令;字段缺席 = 已关闭或本轮没有可渲染内容(如模板只有 goal 段而该目录无目标)。
|
|
27
36
|
- `{status:"timeout"}`(exit 0,不是错误)= 时限内没有新任务:想继续等就再
|
|
28
37
|
wait(挂起等待,期间别人提交的会立刻送达),不想等就收工。
|
|
38
|
+
- **get 的两种形态**:默认「直接 get」(没任务立即返回 timeout,不阻塞);项目在设置
|
|
39
|
+
面板里开启「持续 get(waitgoal)」后,get 变成**阻塞唤起**——自动打开对应目录页面、
|
|
40
|
+
等项目配置的分钟数,期间用户回填就直接领到;领到的交付文本自带「继续 get 直到
|
|
41
|
+
超时」的项目模板(不用自己记循环)。
|
|
42
|
+
- **带时间目标的任务**(发布时 `--duration 2h`):领取即计时,交付的 instruction 里
|
|
43
|
+
带 `timegoal check --task …` 指令;**时间未到不许标记完成**——`localtask done`
|
|
44
|
+
会返回 `{status:"blocked", reason:"goal_not_reached"}`,此时应派出 sub agent
|
|
45
|
+
重新提出新的需求再继续,而不是硬标完成。
|
|
29
46
|
- `--timeout <秒>`:阻塞上限(缺省用页面配置 180 秒,最大 600);「查完就走」
|
|
30
47
|
用短超时,「挂着等活」用长超时。
|
|
31
48
|
|
|
32
49
|
## 队列管理(需要时)
|
|
33
50
|
|
|
34
51
|
```bash
|
|
35
|
-
nx-kv localtask
|
|
36
|
-
nx-kv localtask update --id <n> --text "<新内容>" #
|
|
52
|
+
nx-kv localtask show --id <n> # 查看单条(get 已改为领取动作)
|
|
53
|
+
nx-kv localtask update --id <n> --text "<新内容>" # 改写任务内容;--duration/--clear-goal 改时间目标(仅未领取时)
|
|
37
54
|
nx-kv localtask remove --id <n> # 删除单条
|
|
38
55
|
nx-kv localtask reorder --id <n> --before-id <m> # 调整领取顺序(或 --after-id)
|
|
39
56
|
nx-kv localtask topic remove --cwd "<目录>" # 删除整个主题(等待中需 --force)
|
|
@@ -171,10 +171,23 @@ nx-kv timegoal log --cwd <dir> # 回看每
|
|
|
171
171
|
|
|
172
172
|
**没有依赖关系。** timegoal 只做两件事:算时间、回显提示词原文。
|
|
173
173
|
|
|
174
|
-
- 不调用 `localtask wait
|
|
174
|
+
- 不调用 `localtask wait`:等不到任务是别的事,与是否到点有关
|
|
175
|
+
- **两种 timegoal**:目录级(`--cwd`,与目录一对一)与**任务级**(`--task
|
|
176
|
+
task:<topicKey>:<taskId>`,发布时 `localtask add --duration 2h` 随任务携带,
|
|
177
|
+
**领取即计时**)。任务级的 goal key 会随任务交付的 instruction 一起给你,
|
|
178
|
+
直接照抄执行即可;`timegoal check --task <key> --summary … --progress …` 记日志,
|
|
179
|
+
未到点 `localtask done` 会拒绝标记完成。
|
|
175
180
|
- 不阻塞任何东西:可以同时跑人机接力、派任务给别的 agent、外部 cron
|
|
176
181
|
- 不需要登录 KV 后端:纯本机
|
|
177
182
|
|
|
183
|
+
**与 wait 的融合(只读,单向)**:这个目录挂着 timegoal 时,`localtask wait`
|
|
184
|
+
返回的 `instruction` 字段会带上目标状态(默认模板:`〔时间目标「目录名」剩余 X〕`;
|
|
185
|
+
到点后显示「已到点」)——kv-waittask 循环里的 agent 不调 check 也能看到预算。
|
|
186
|
+
融合是**渲染时只读**(`showTimegoal` 只读路径,不写盘、不写 check 日志、不影响
|
|
187
|
+
计时与到点判定),timegoal 自身的命令族与契约完全不变;`check` 的 prompt 原文
|
|
188
|
+
回显仍是防漂移的唯一正式通道。要到 wait 的 instruction 里携带 prompt 原文,
|
|
189
|
+
用 `localtask config --suffix` 自定义模板并写入 `{{goal.prompt}}`。
|
|
190
|
+
|
|
178
191
|
你可以把它当成一个独立计时器 + 便签本:`set` 把便签写进文件,`check` 读出来
|
|
179
192
|
顺便告诉你还剩多少时间。
|
|
180
193
|
|
package/assets/{kv-waittask/references/kv-waittask-workflow.md → kv-get/references/wait-workflow.md}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# kv-waittask-workflow — 阻塞等待用户回填任务的完整 SOP
|
|
2
2
|
|
|
3
|
-
> 归属 [[
|
|
3
|
+
> 归属 [[waitloop]]。当你要在一个对话里**不结束本轮**、靠一个阻塞工具
|
|
4
4
|
> 调用等浏览器里继续回填任务时,按本 SOP 走。
|
|
5
5
|
>
|
|
6
6
|
> **循环是强制的:每完成一步、提交结果后,结束动作只能是 wait——领取新任务。
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
自动打开浏览器弹窗,然后阻塞。
|
|
22
22
|
4. 用户在弹窗/面板看清现状,回填新任务 → 提交(Enter 或按钮)。
|
|
23
23
|
5. wait 解除阻塞,stdout(--json) 返回 {status:"ok", task},进程退出。
|
|
24
|
-
6. agent 从工具结果读 task.text
|
|
24
|
+
6. agent 从工具结果读 task.text(任务本体)与 instruction(收尾指令模板的渲染结果,
|
|
25
|
+
有则必读),继续干活、提交结果;做完【必须】回到第 2 步——
|
|
25
26
|
循环,不许自行中断。
|
|
26
27
|
7. 若阻塞时限(默认 180 秒)内没有回填:wait 返回 {status:"timeout"}(exit 0),
|
|
27
28
|
agent 不再等待,收尾并结束本轮——这是整个循环唯一的合法出口。
|
|
@@ -78,6 +79,7 @@ wait 必带一句当前现状总结(≤2000 字,连续空白会折叠为单
|
|
|
78
79
|
"task": { "id": 3, "text": "选择工作空间 A", "status": "consumed",
|
|
79
80
|
"createdAt": "2026-10-11 10:00:00", "consumedAt": "2026-10-11 10:00:04",
|
|
80
81
|
"roundSummary": "已完成登录,等待选择工作空间" },
|
|
82
|
+
"instruction": "〔时间目标「demo」剩余 2.5 小时〕规划计划,然后完成这个任务;计划的最后一个动作,是再次调用 nx-kv localtask wait(带上 --cwd 当前工作目录、--summary 当前现状、--json)收尾本轮,在拿到下一条任务或超时之前不要提前结束。",
|
|
81
83
|
"delivered": true,
|
|
82
84
|
"queued": false,
|
|
83
85
|
"source": "local"
|
|
@@ -88,6 +90,13 @@ wait 必带一句当前现状总结(≤2000 字,连续空白会折叠为单
|
|
|
88
90
|
- `source` = 任务来自哪个队列:`"local"`(本目录队列,含实时回填)或 `"global"`
|
|
89
91
|
(全局任务池);agent 不必区分,照常执行 `task.text`。
|
|
90
92
|
- **任务内容永远读 `task.text`**,多行换行原样保留。
|
|
93
|
+
- **`instruction` 有则必读**:收尾指令模板的服务端渲染结果——默认含该目录 timegoal
|
|
94
|
+
的剩余预算(没挂目标则无这段)+「计划最后再 wait 一次」。模板含 `{{task.text}}`
|
|
95
|
+
时 instruction 自包含(正文以它为准)。字段缺席 = 已关闭或本轮没有可渲染内容,只执行任务。
|
|
96
|
+
- **配置**:`nx-kv localtask config --suffix "<模板>"`(占位符
|
|
97
|
+
`{{goal.name}} {{goal.remainingHuman}} {{goal.prompt}} {{task.text}} {{source}} {{name}}…`,
|
|
98
|
+
段落 `{{#goal}}…{{/goal}}` 上下文缺失整段消失;`--no-suffix` 关闭、
|
|
99
|
+
`--reset-suffix` 恢复默认)。字段缺席 = 已关闭或本轮没有可渲染内容。
|
|
91
100
|
|
|
92
101
|
超时(exit 0,业务结果而非错误):
|
|
93
102
|
|
|
@@ -83,6 +83,15 @@ nx-kv localtask wait --summary "<当前现状总结>" --json
|
|
|
83
83
|
成功结果里带 `cwd` 与 `summary`;`task` 形如
|
|
84
84
|
`{id, text, status, createdAt, consumedAt, roundSummary}`,**任务内容在 `task.text`**。
|
|
85
85
|
|
|
86
|
+
**`instruction` 字段(有则必读)**:配置了收尾指令**模板**(默认即是)时,wait 返回
|
|
87
|
+
额外带 `instruction` —— 服务端渲染的**本轮根指令**:默认含时间目标状态
|
|
88
|
+
(`〔时间目标「目录名」剩余 X〕`,该目录挂了 timegoal 才出现)+ 收尾要求
|
|
89
|
+
(计划最后再 wait 一次)。规则:
|
|
90
|
+
|
|
91
|
+
- `task.text` 永远是任务本体原文;`instruction` 是**包裹它的执行指令**,两者一起读。
|
|
92
|
+
- 自定义模板可含 `{{task.text}}`(此时 instruction 自包含,正文以它为准)。
|
|
93
|
+
- 该目录的 timegoal 到点后,instruction 会显示「已到点」——预算用完,本轮该收尾了。
|
|
94
|
+
|
|
86
95
|
## 一次循环长什么样
|
|
87
96
|
|
|
88
97
|
```
|
|
@@ -114,7 +123,7 @@ agent:工具结果拿到 task.text → 干活 → 提交结果
|
|
|
114
123
|
nx-kv localtask list # 主题总览(各目录、现状、待领取数)
|
|
115
124
|
nx-kv localtask add "<回填内容>" --cwd "<目录>" # 给某目录的队列排任务
|
|
116
125
|
nx-kv localtask get --id <n> [--cwd "<目录>"] # 查看单条
|
|
117
|
-
nx-kv localtask update --id <n> --text "<新内容>" #
|
|
126
|
+
nx-kv localtask update --id <n> --text "<新内容>" # 编辑任务内容;--duration/--clear-goal 改时间目标(仅未领取时)
|
|
118
127
|
nx-kv localtask remove --id <n> [--cwd "<目录>"] # 删除单条任务
|
|
119
128
|
nx-kv localtask reorder --id <n> --before-id <m> # 调整待领取优先级(或 --after-id)
|
|
120
129
|
nx-kv localtask topic remove --cwd "<工作目录>" # 删除整个主题(等待中需 --force)
|
package/assets/kv-repo/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kv-repo
|
|
3
|
-
description:
|
|
3
|
+
description: 本机仓库上下文的两件事——①识别并汇报仓库分组(看板/项目组)与组内关系,一键加载成员、领域描述与配合关系;②克隆外源参考仓库并**强制读完**它(clone 落到统一 gitRepoRoot,登记为 ref,之后用 Read 工具真读关键文件再回答/实现,不许只凭搜索摘要下结论)。用 nx-kv repo / board 命令拿分组与描述,用 nx-kv repo ref clone 克隆参考仓库。触发词:/kv-repo、kv-repo、仓库组、相关仓库、这个仓库属于哪个组、组里都有什么、它们什么关系、中心/终端、领域描述、关键路径、读并维护领域描述、克隆参考仓库、clone 参考仓库、调研开源项目、找参考实现、强制读、读完再答。反例:登记/扫描/增删仓库与看板用 nx-kv 主 skill 的 repo-registry;git 状态与 diff 一律找 git 自己。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# kv-repo — 仓库组识别与关系报告
|
|
@@ -68,6 +68,32 @@ nx-kv repo ref check # 参考仓库完整性:目录/origin 一
|
|
|
68
68
|
定位顺序:拿到任务/目录 → `repo list` 按**路径或目录名**找到仓库
|
|
69
69
|
→ 它的 `boards[]` 给出所属组 → 回 `board list` 读该组的 `desc` 与**兄弟仓库**。
|
|
70
70
|
|
|
71
|
+
## 克隆外源参考仓库 + **强制读**(第二件事)
|
|
72
|
+
|
|
73
|
+
当任务需要「看看别人怎么做的」,参考仓库**要真读**,不是搜两眼摘要就下结论。
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# 1) 克隆并登记为参考仓库(落到统一 gitRepoRoot,remote 为唯一 key)
|
|
77
|
+
nx-kv repo ref clone <git-url> --json
|
|
78
|
+
# → { repo:{ key, path, name, … } } # path 就是本机落盘位置
|
|
79
|
+
|
|
80
|
+
# 2) 绑定到当前仓库或看板(可选,但强烈建议——下次自动带出上下文)
|
|
81
|
+
nx-kv repo bind <ref-key> --repo <本仓库id> --note "参考它的 xxx 实现" --json
|
|
82
|
+
|
|
83
|
+
# 3) **强制读**:用 Read 工具真读关键文件——README、docs/、契约文件、入口实现
|
|
84
|
+
# (落盘路径从第 1 步的 path 取;先看文件清单再决定读哪几个)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**强制读的纪律**:
|
|
88
|
+
|
|
89
|
+
- clone 完**必须读**:至少 README + 与任务直接相关的源文件/契约文件,并把**读到的具体位置**
|
|
90
|
+
(文件路径 + 关键行/函数名)写进结论;
|
|
91
|
+
- **不许**只凭 `grep` 命中的一行或搜索摘要就下结论——摘要会把上下文丢掉;
|
|
92
|
+
- 读完再回答/实现;引用参考实现时说明「参考的是哪个仓库的哪个文件」。
|
|
93
|
+
|
|
94
|
+
多路并行调研时的纪律(搜索纪律见 [[mmx-gitclone]]):3–5 路并行深搜、最多 clone 2 个最有价值的项目、
|
|
95
|
+
SSH 优先失败双向回退、`--depth 1` 浅克隆。
|
|
96
|
+
|
|
71
97
|
## 维护:发现过期就修(这是本 skill 的另一半职责)
|
|
72
98
|
|
|
73
99
|
读到的 desc 与代码现实不符(路径变了、关系变了、压根没写)时,顺手补上:
|
|
@@ -86,6 +112,7 @@ nx-kv board note <仓库id|路径> --board <看板id> --note "这个仓库在组
|
|
|
86
112
|
|
|
87
113
|
## 边界
|
|
88
114
|
|
|
89
|
-
- 本 skill
|
|
115
|
+
- 本 skill 读分组与描述、克隆参考仓库并强制读;**登记/扫描/增删仓库看板**走 nx-kv 主 skill(repo-registry)。
|
|
116
|
+
- 参考仓库的**写入/同步**(pull、完整性检查)走 `nx-kv repo ref sync/check`。
|
|
90
117
|
- 不碰 git:状态 / diff / pull / push 一律直接用 git 自己。
|
|
91
118
|
- 数据按 groupId 隔离,查询前先确认工作空间对不对(`nx-kv group current`)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kv-submit
|
|
3
|
-
description: 把当前对话里的需求打包成任务,通过 nx-kv localtask add 提交到另一个工作目录的队列,委托在那里的 agent 完成——先总结上下文(聊了什么、定了什么、涉及哪些文件)、再提炼出用户的真实需求(目标、约束、验收标准),写成不依赖本对话就能执行的自包含任务文本再提交;可给正在等待的 agent 实时补任务,也可给不在等待的目录排队。触发词:提交任务、委托、派任务、丢给另一个 agent、交给那边做、转发需求、整理成任务提交、总结上下文提交、提炼需求、长对话提炼、保存会话、会话交接、localtask add、kv-submit。凡「把这个对话里的东西变成任务交给别的 agent」的场景都走本 skill
|
|
3
|
+
description: 把当前对话里的需求打包成任务,通过 nx-kv localtask add 提交到另一个工作目录的队列,委托在那里的 agent 完成——先总结上下文(聊了什么、定了什么、涉及哪些文件)、再提炼出用户的真实需求(目标、约束、验收标准),写成不依赖本对话就能执行的自包含任务文本再提交;可给正在等待的 agent 实时补任务,也可给不在等待的目录排队。触发词:提交任务、委托、派任务、丢给另一个 agent、交给那边做、转发需求、整理成任务提交、总结上下文提交、提炼需求、长对话提炼、保存会话、会话交接、localtask add、kv-submit。凡「把这个对话里的东西变成任务交给别的 agent」的场景都走本 skill。反例:你自己在等用户回填、或要领取/完成/重开本目录的任务用 kv-get;操作远程 KV 清单(todo)用 nx-kv。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# kv-submit — 提炼需求,委托其它 agent(提交侧)
|
|
@@ -30,6 +30,9 @@ nx-kv localtask add "<任务文本>" --cwd "<目标目录>" --summary "<该目
|
|
|
30
30
|
# 不限定接收方、谁闲谁领 → 推到全局任务池(--cwd 被忽略):
|
|
31
31
|
# 任何目录的 agent 在本地队列空时都会自动领取(返回 source:"global")
|
|
32
32
|
nx-kv localtask add --global "<任务文本>" --json
|
|
33
|
+
|
|
34
|
+
# 带时间目标(可选):领取即计时,未到点不许标记完成
|
|
35
|
+
nx-kv localtask add "<任务文本>" --cwd "<目标工作目录>" --duration 2h --goal-prompt "<附加要求>" --json
|
|
33
36
|
```
|
|
34
37
|
|
|
35
38
|
返回 `{status:"ok", task:{id,text,...}, queued|delivered}`:
|
|
@@ -39,6 +42,18 @@ nx-kv localtask add --global "<任务文本>" --json
|
|
|
39
42
|
全局任务池,任何目录空闲的 agent 自动领取。
|
|
40
43
|
- 记下 `task.id`,向用户报告「已提交到哪个目录(或全局池)、第几号任务」。
|
|
41
44
|
|
|
45
|
+
## 用户看完结果要改 → 重开那条任务
|
|
46
|
+
|
|
47
|
+
任务被领走、干完(`localtask done`)之后,用户提了修改意见——**那条任务要重开**,
|
|
48
|
+
否则 agent 看不到新一轮的诉求(已领取的任务不会再被派发):
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
nx-kv localtask reopen --id <n> --text "<改后的正文(Markdown)>" --json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
重开 = 回到待领取 + 领取时间作废(新一轮重新计时),上一轮的完成总结保留。
|
|
55
|
+
`--text` 不给则只重开、不改正文。重开的细节见 kv-get skill。
|
|
56
|
+
|
|
42
57
|
## 任务文本怎么写(一句话版)
|
|
43
58
|
|
|
44
59
|
接收方没有你的上下文,任务文本按这个顺序组织成一段(单行,用 ①②③ 编号,
|
|
@@ -66,8 +81,8 @@ nx-kv localtask add --global "<任务文本>" --json
|
|
|
66
81
|
|
|
67
82
|
| 场景 | 用哪个 |
|
|
68
83
|
| --- | --- |
|
|
69
|
-
| 你自己干完活、等用户在浏览器回填下一条 | kv-
|
|
70
|
-
| 主动领取排给**本目录**的任务 | kv-
|
|
84
|
+
| 你自己干完活、等用户在浏览器回填下一条 | kv-get(wait / done / reopen) |
|
|
85
|
+
| 主动领取排给**本目录**的任务 | kv-get(get) |
|
|
71
86
|
| 操作远程 KV 后端的 todo 清单(需登录) | nx-kv |
|
|
72
87
|
| 给**正在等待**的 agent 补一条任务 | 本 skill(add 到它的目录) |
|
|
73
88
|
| 不限定接收方、让任何空闲 agent 自取 | 本 skill(`add --global` 推全局任务池) |
|
|
@@ -77,13 +92,12 @@ nx-kv localtask add --global "<任务文本>" --json
|
|
|
77
92
|
三者共享同一份本机任务存储与按目录划分的队列(`~/.nx-kv/localtasks.json`):
|
|
78
93
|
|
|
79
94
|
- **kv-submit(本 skill)**:提交侧——总结上下文、提炼需求、投递到别的目录。
|
|
80
|
-
- **kv-
|
|
81
|
-
- **kv-localget**:领取侧——目标目录的 agent 主动领队列里的任务。
|
|
95
|
+
- **kv-get**:领取侧——目标目录的 agent 领活(get)、等人接力(wait)、标完成(done)、按反馈重开(reopen)。
|
|
82
96
|
- **nx-kv**:远程 KV 后端的 todo 清单(需登录、按 groupId 隔离),与本机队列无关。
|
|
83
97
|
|
|
84
98
|
## 安装
|
|
85
99
|
|
|
86
100
|
```bash
|
|
87
101
|
nx-kv skill install kv-submit # 装到 ~/.claude/skills/kv-submit
|
|
88
|
-
nx-kv skill list # 列出 nx-kv / kv-
|
|
102
|
+
nx-kv skill list # 列出 nx-kv / kv-get / kv-submit / kv-repo
|
|
89
103
|
```
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- 需要把某个目录登记为受管仓库,或扫描某目录批量发现仓库
|
|
9
9
|
- 需要维护仓库的元信息:名称、描述、备注,或改登记路径
|
|
10
10
|
- **需要 git 状态、差异、拉取、推送时不要进这里**——开发仓库不做 git 操作(见下)
|
|
11
|
-
- **要搜索并克隆参考项目时用 [[kv-repo
|
|
11
|
+
- **要搜索并克隆参考项目时用 [[kv-repo]]**——那是参考仓库的克隆与**强制读** SOP
|
|
12
12
|
- **只查分组与关系(不改动)时用 [[kv-repo]]**——那是仓库组的查询/报告侧
|
|
13
13
|
|
|
14
14
|
## 边界:git 操作只给参考仓库
|
|
@@ -76,7 +76,7 @@ git -C <path> pull --no-edit
|
|
|
76
76
|
mmx-research-gitclone 的整体吸纳(2026-10-27):远程 clone 下来学习/参考的仓库与
|
|
77
77
|
开发仓库同住中心清单,但统一存放在 `gitRepoRoot`(`nx-kv setting set --gitRepoRoot <非C盘目录>`,
|
|
78
78
|
**不设置则 clone 显式拒绝**——绝不默默堆进用户目录)。完整搜索→克隆 SOP 见
|
|
79
|
-
[[kv-repo
|
|
79
|
+
[[kv-repo]];这里登记命令面的速查:
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
82
|
nx-kv repo ref clone <url> [--name N] [--desc D] [--board <看板id>] [--bind <开发仓库>] [--depth 1] [--no-bind]
|
package/package.json
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// 指令模板渲染 —— wait 返回「收尾指令」的纯字符串机制(core 层,零依赖)。
|
|
2
|
+
//
|
|
3
|
+
// localtask 的 settings.taskSuffix 从"固定追加语"升级为模板:含 {{ 标记的值在
|
|
4
|
+
// wait 返回时渲染成融合指令(goal 状态 + 收尾要求),放进返回载荷的 instruction
|
|
5
|
+
// 字段;不含 {{ 的纯文本沿用旧的"追加到 task.text"行为(见 localtask service 的
|
|
6
|
+
// buildTaskDelivery)。本文件只做字符串机制,不含任何业务语义——业务默认值
|
|
7
|
+
// (DEFAULT_TASK_SUFFIX)留在 localtask service。
|
|
8
|
+
//
|
|
9
|
+
// 语法(v1 无转义:模板正文无法表达字面 {{,纯文本后缀不该含 {{):
|
|
10
|
+
// 段落 {{#goal}}…{{/goal}}、{{#task}}…{{/task}}
|
|
11
|
+
// ctx.goal / ctx.task 缺失(null/undefined)时整段丢弃
|
|
12
|
+
// 占位符 {{goal.name}} {{goal.deadline}} {{goal.remainingHuman}} {{goal.prompt}}
|
|
13
|
+
// {{task.id}} {{task.text}} {{source}} {{summary}} {{cwd}} {{name}}
|
|
14
|
+
// 按 `.` 分段走 ctx,任何一步缺失或未知路径一律 ''(宽容,绝不抛错)
|
|
15
|
+
//
|
|
16
|
+
// 两条硬保证:
|
|
17
|
+
// 1. **单遍渲染**:扫描器只走模板一遍,插入值直接进输出缓冲、不再扫描——
|
|
18
|
+
// task.text / goal.prompt 里出现 {{...}}、{{#goal}}、{{/task}} 都逐字原样。
|
|
19
|
+
// 这是"prompt 原文回显不被改写"契约在字符串层的延伸。
|
|
20
|
+
// 2. **不折叠空白**:段落标记若独占一行(紧跟换行),标记连同那个换行一起消费——
|
|
21
|
+
// 段落丢弃后不留空行、保留时也不多出空行;对输出绝不做 \n{3,} 之类的折叠,
|
|
22
|
+
// 那会破坏插入的 prompt 原文。
|
|
23
|
+
//
|
|
24
|
+
// 时间格式化(formatDuration/formatGoalTiming)语义对齐 timegoal 模块的 fmtDur 与
|
|
25
|
+
// renderCheck 措辞("剩余 X"/"已到点(已超时 X)")——core 不能 import 模块,故本地实现。
|
|
26
|
+
//
|
|
27
|
+
// 单测:tests/unit/instruction-template.test.mjs(段落/占位符/单遍/空白全钉死)。
|
|
28
|
+
|
|
29
|
+
const TOKEN_RE = /\{\{(#|\/)(goal|task)\}\}|\{\{([^{}]*)\}\}/g;
|
|
30
|
+
const SECTION_TAGS = new Set(['{{#goal}}', '{{/goal}}', '{{#task}}', '{{/task}}']);
|
|
31
|
+
|
|
32
|
+
/** 含任意 {{ 即视为模板(决定走渲染路径还是旧的纯文本追加路径)。 */
|
|
33
|
+
export function hasTemplateMarkers(template) {
|
|
34
|
+
return /\{\{/.test(String(template ?? ''));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** 秒 → 人话:"2 天" / "1.5 小时" / "90 分钟" / "45 秒"(与 timegoal fmtDur 同风格)。 */
|
|
38
|
+
export function formatDuration(sec) {
|
|
39
|
+
const s = Math.max(0, Math.floor(Number(sec) || 0));
|
|
40
|
+
if (s >= 86400) return `${(s / 86400).toFixed(s % 86400 ? 1 : 0)} 天`;
|
|
41
|
+
if (s >= 3600) return `${(s / 3600).toFixed(s % 3600 ? 1 : 0)} 小时`;
|
|
42
|
+
if (s >= 60) return `${(s / 60).toFixed(s % 60 ? 1 : 0)} 分钟`;
|
|
43
|
+
return `${s} 秒`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** 目标时间状态:"剩余 X" | "已到点" | "已到点(已超时 X)"(措辞对齐 timegoal renderCheck)。 */
|
|
47
|
+
export function formatGoalTiming({ reached, remainingSec, overtimeSec } = {}) {
|
|
48
|
+
if (!reached) return `剩余 ${formatDuration(remainingSec)}`;
|
|
49
|
+
const over = Math.max(0, Math.floor(Number(overtimeSec) || 0));
|
|
50
|
+
return over > 0 ? `已到点(已超时 ${formatDuration(over)})` : '已到点';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 按路径取值:'goal.name' → ctx.goal.name;任何一步缺失 → ''(null/undefined 都算缺失)。
|
|
54
|
+
// 只认**自有属性**(hasOwnProperty 守卫)——否则 {{constructor}} 之类会顺着原型链
|
|
55
|
+
// 解析出 Object 的内置成员。
|
|
56
|
+
function resolvePath(path, ctx) {
|
|
57
|
+
let cur = ctx;
|
|
58
|
+
for (const seg of String(path).split('.')) {
|
|
59
|
+
if (cur === null || cur === undefined) return '';
|
|
60
|
+
cur = Object.prototype.hasOwnProperty.call(cur, seg) ? cur[seg] : undefined;
|
|
61
|
+
}
|
|
62
|
+
return cur === null || cur === undefined ? '' : String(cur);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 渲染模板为一条指令文本。
|
|
67
|
+
* - 段落按 ctx 有无整段丢弃;close 按名匹配才弹栈(错配 close 是无操作——宽容但
|
|
68
|
+
* 不泄漏被丢弃段的内容,行为由单测钉死)。
|
|
69
|
+
* - 空白规则:段落标记独占一行时(紧跟换行),标记连同该换行一起消费——丢弃段
|
|
70
|
+
* 不留空行,保留段也不多空行。
|
|
71
|
+
* - 未知段落标记(如 {{#other}})落进占位符分支按未知路径渲染为 ''。
|
|
72
|
+
* - 结果整体 trim;全部内容被丢弃/为空时返回 ''——调用方应据此**省略** instruction
|
|
73
|
+
* 字段而不是输出空串。
|
|
74
|
+
* @param {string} template 模板(含 {{ 标记;调用前用 hasTemplateMarkers 分流)
|
|
75
|
+
* @param {object} ctx { goal, task, source, summary, cwd, name }
|
|
76
|
+
* @returns {string}
|
|
77
|
+
*/
|
|
78
|
+
export function renderInstruction(template, ctx = {}) {
|
|
79
|
+
const src = String(template ?? '');
|
|
80
|
+
const frames = []; // {name, keep}
|
|
81
|
+
const emitting = () => frames.every((f) => f.keep);
|
|
82
|
+
let out = '';
|
|
83
|
+
let last = 0;
|
|
84
|
+
TOKEN_RE.lastIndex = 0;
|
|
85
|
+
for (let m = TOKEN_RE.exec(src); m; m = TOKEN_RE.exec(src)) {
|
|
86
|
+
// 字面段:插入值(此处是模板里的字面文本)只在发射态进入输出
|
|
87
|
+
if (emitting()) out += src.slice(last, m.index);
|
|
88
|
+
const token = m[0];
|
|
89
|
+
let consumed = TOKEN_RE.lastIndex;
|
|
90
|
+
if (m[1] === '#') {
|
|
91
|
+
const name = m[2];
|
|
92
|
+
frames.push({ name, keep: name === 'goal' ? !!(ctx && ctx.goal) : !!(ctx && ctx.task) });
|
|
93
|
+
} else if (m[1] === '/') {
|
|
94
|
+
// 按名匹配才弹栈:错配的 close(如 goal 段里写 {{/task}})是无操作——
|
|
95
|
+
// 宽容但不泄漏:被丢弃段的内容不会因为一个错配 close 就提前"出栈"见光。
|
|
96
|
+
const top = frames[frames.length - 1];
|
|
97
|
+
if (top && top.name === m[2]) frames.pop();
|
|
98
|
+
} else if (emitting()) {
|
|
99
|
+
out += resolvePath(m[3].trim(), ctx);
|
|
100
|
+
}
|
|
101
|
+
// 独占一行的段落标记:连同紧跟的换行一起消费(丢弃段不留空行;保留段不多空行)。
|
|
102
|
+
// 只对四个已知标记生效,且只吞"标记之后"的换行——标记之前的换行天然属于上一行。
|
|
103
|
+
if (SECTION_TAGS.has(token) && src[consumed] === '\n') consumed += 1;
|
|
104
|
+
last = consumed;
|
|
105
|
+
TOKEN_RE.lastIndex = consumed;
|
|
106
|
+
}
|
|
107
|
+
if (emitting()) out += src.slice(last);
|
|
108
|
+
return out.trim();
|
|
109
|
+
}
|