pactive 0.0.2-alpha.1 → 0.0.4-alpha.1
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/.opcteam-plugin/plugin.json +8 -4
- package/BREAKING-CHANGES.md +14 -3
- package/README.md +86 -6
- package/bin/pactive.mjs +917 -4
- package/commands/pactive.md +4 -1
- package/dsh/index.js +214 -6
- package/mcp/tools/definitions.mjs +205 -8
- package/package.json +1 -1
- package/pi/extension.ts +246 -8
- package/pi/skills/pactive/SKILL.md +57 -20
- package/skills/pactive/SKILL.md +57 -20
- package/src/core/assistants.mjs +237 -0
- package/src/core/config.mjs +40 -3
- package/src/core/fleet.mjs +80 -0
- package/src/core/guard.mjs +117 -32
- package/src/core/idle.mjs +11 -8
- package/src/core/index.mjs +3 -0
- package/src/core/scheduler.mjs +16 -4
- package/src/core/state.mjs +134 -12
- package/src/core/tick.mjs +128 -0
- package/src/hosts/herdr/fleet-view.mjs +31 -0
- package/src/hosts/herdr/index.mjs +429 -0
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pactive",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4-alpha.1",
|
|
4
4
|
"description": "Pactive 主动机制:空闲判定、定时任务与跨会话消息(hooks + MCP)。",
|
|
5
|
-
"author": {
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "pk09"
|
|
7
|
+
},
|
|
6
8
|
"mcpServers": {
|
|
7
9
|
"pactive": {
|
|
8
10
|
"command": "node",
|
|
9
|
-
"args": [
|
|
11
|
+
"args": [
|
|
12
|
+
"${OPCTEAM_PLUGIN_ROOT}/mcp/server.mjs"
|
|
13
|
+
]
|
|
10
14
|
}
|
|
11
15
|
}
|
|
12
|
-
}
|
|
16
|
+
}
|
package/BREAKING-CHANGES.md
CHANGED
|
@@ -29,9 +29,20 @@
|
|
|
29
29
|
|
|
30
30
|
## 未发布
|
|
31
31
|
|
|
32
|
-
当前版本 `0.0.
|
|
32
|
+
当前版本 `0.0.3-alpha.1`(已发布)。以下按版本倒序列出。
|
|
33
33
|
|
|
34
|
-
## 0.0.
|
|
34
|
+
## 0.0.4-alpha.1 — 2026-11-05(已发布)
|
|
35
|
+
|
|
36
|
+
- **复用 Herdr**(I74–I79):`pactive fleet up|ls|down|open`,把助理绑到 herdr 的 pane/agent 上;`tick` 投递带 `paneId`。
|
|
37
|
+
- 不破坏既有:命令面只增不改,协议串仍 `pactive/1`。
|
|
38
|
+
|
|
39
|
+
## 0.0.3-alpha.1 — 2026-11-05(已发布)
|
|
40
|
+
|
|
41
|
+
- **自然语言优先**:默认全部用自然语言操作(I57–I60);新增 CLI `config get/set`、`schedule`、`tasks`、`cancel`。
|
|
42
|
+
- **助理舰队**:`assistant add|ls|show|enable|disable|rm|rename`、`schedule --assistant`、`pactive tick`;state schema v1→v2(旧状态自动迁移为 `default` 助理)。
|
|
43
|
+
- 协议串仍为 `pactive/1`,以上均为**新增**,不破坏既有调用。
|
|
44
|
+
|
|
45
|
+
## 0.0.2-alpha.1 — 2026-11-05(已发布)
|
|
35
46
|
|
|
36
47
|
### 破坏性
|
|
37
48
|
|
|
@@ -47,7 +58,7 @@
|
|
|
47
58
|
- **状态根默认值变化**:默认由 `~/.acti` 改为 `~/.pactive`。不迁移旧目录内容;需要沿用旧状态时显式设置
|
|
48
59
|
`PACTIVE_STATE_DIR=<旧目录>`。
|
|
49
60
|
|
|
50
|
-
## 0.0.1-alpha.1 — 2026-11-05
|
|
61
|
+
## 0.0.1-alpha.1 — 2026-11-05(已发布)
|
|
51
62
|
|
|
52
63
|
### 破坏性
|
|
53
64
|
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
跨宿主的**主动能力运行时**:在宿主(Pi / OPCteam / DSH)之外统一判定「该不该主动说话」,
|
|
4
4
|
把触发、投递、回应、结账写进一条 append-only 事件账本,并提供 CLI / doctor / 定时任务 / 跨会话消息。
|
|
5
5
|
|
|
6
|
-
> **状态:v0.0.
|
|
6
|
+
> **状态:v0.0.3-alpha.1(预发布,已发布到 npm:`pactive`)。** 本文只描述**契约层面**的接口。
|
|
7
7
|
> 每一项能力后都标注了**当前实际验证到哪一步**——绝大多数条目当前为「未验证」。
|
|
8
8
|
> 本文档不构成「已支持」的声明;请以「宿主兼容矩阵」与「未验证项」两节为准。
|
|
9
9
|
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
## 1. 安装
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
# 从 npm
|
|
15
|
+
# 从 npm(已发布;当前 latest = alpha)
|
|
16
16
|
npm i -g pactive # 命令:pactive(旧命令已退役,见 BREAKING-CHANGES.md)
|
|
17
17
|
|
|
18
18
|
# 从本地 tarball
|
|
19
19
|
npm pack
|
|
20
|
-
npm i -g --prefix /tmp/pactive-prefix ./pactive-0.0.
|
|
20
|
+
npm i -g --prefix /tmp/pactive-prefix ./pactive-0.0.3-alpha.1.tgz
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
运行环境:**Node.js ≥ 22.19.0**(`engines.node`)。
|
|
@@ -44,7 +44,10 @@ pactive dsh # dsh --profile pactive(只写 pactive
|
|
|
44
44
|
`pi.skills` → `pi/skills/pactive`);`pi install pactive` 依赖该字段。
|
|
45
45
|
- 宿主退出码 / 信号原样透传(信号 → 128+n)。
|
|
46
46
|
- **stdout 纯净**:Pactive 自身的回执、诊断、进度一律走 stderr,
|
|
47
|
-
stdout
|
|
47
|
+
stdout 只承载被启动宿主的输出,以及显式请求的机器可读结果(`--print-plan`、
|
|
48
|
+
`doctor --json`、`config/tasks/assistant ls --json`、`--help`——`--help | head -8` 要可 grep)。
|
|
49
|
+
- 例外:`assistant ls` / `assistant show` 的**人读清单**走 stdout——它就是被查询的答案
|
|
50
|
+
(`pactive assistant ls | wc -l` 必须数得出助理个数),与 `--help` 同理。
|
|
48
51
|
|
|
49
52
|
### 2.2 其它子命令
|
|
50
53
|
|
|
@@ -55,6 +58,17 @@ pactive dsh # dsh --profile pactive(只写 pactive
|
|
|
55
58
|
| `pactive --print-plan <host>` | 打印注入计划 JSON(零写盘) | 0(未知宿主 2) |
|
|
56
59
|
| `pactive doctor [--json]` | 宿主 / 版本 / 注入模式 / 状态根 / 权限 / 残留 | 0(有 FAIL 段则 1) |
|
|
57
60
|
| `pactive install <host>` / `pactive uninstall <host>` | 幂等安装 / 卸载 | 0(有残留则 1) |
|
|
61
|
+
| `pactive config get [<key>] [--assistant <name\|id>] [--json]` | 只读:当前值与默认值(白名单 8 个 key;带 `--assistant` 读该助理的覆盖值) | 0(未知 key 2) |
|
|
62
|
+
| `pactive config set <key> <value> [--assistant <name\|id>] --confirm` | 写配置;**缺 `--confirm` 就零写盘**;带 `--assistant` 只写该助理的 policy 覆盖 | 0(缺 confirm 2、未知 key 2、值非法 2、该 key 不可按助理覆盖 2) |
|
|
63
|
+
| `pactive schedule "<prompt>" --when <when> [--assistant <name\|id>]` | 登记定时任务(`10m` / `18:30` / ISO / `every 1h`);不填助理就记到 `default` | 0(when 无法解析 2、未知助理 2) |
|
|
64
|
+
| `pactive tasks [--assistant <name\|id>] [--json]` | 列出任务:id / 类型 / 下次到期 / 归属 / 正文 | 0(未知助理 2) |
|
|
65
|
+
| `pactive cancel <taskId>` | 取消一条任务 | 0(未知 id 1) |
|
|
66
|
+
| `pactive tick [--assistant <name\|id>] [--json]` | 跑**一轮**「到期任务 + 空闲判定」,可投递项落 ledger(`delivered` / `blocked`+reason) | 0 |
|
|
67
|
+
| `pactive assistant add <name> [--title …] [--role …] [--scope <glob>] --confirm` | 新建助理(默认 `enabled=false`);缺 `--confirm` 零写盘 | 0(缺 confirm 2、重名 2) |
|
|
68
|
+
| `pactive assistant ls [--json]` / `show <name\|id>` | 只读:名称 / id / 开关 / 任务数 / 触发次数 / 下次到期 | 0(未知助理 2) |
|
|
69
|
+
| `pactive assistant enable\|disable <name\|id> --confirm` | 开关一个助理 | 0(缺 confirm 2、未知助理 2) |
|
|
70
|
+
| `pactive assistant rename <name\|id> <newName> --confirm` | 重命名(**id 不变**,任务跟着走) | 0(缺 confirm 2、未知助理 2、重名 2) |
|
|
71
|
+
| `pactive assistant rm <name\|id> --confirm` | 删除助理**并连带删除它的任务**(不留孤儿) | 0(缺 confirm 2、未知助理 2) |
|
|
58
72
|
| `pactive <未知宿主>` | 列出 pi / opcteam / dsh 到 stderr | 2 |
|
|
59
73
|
| 宿主二进制缺失 | 提示安装 + `PACTIVE_<HOST>_BIN` 覆盖 | 127 |
|
|
60
74
|
|
|
@@ -65,7 +79,53 @@ pactive dsh # dsh --profile pactive(只写 pactive
|
|
|
65
79
|
| `PACTIVE_STATE_DIR` | 状态根覆盖(默认按宿主约定解析) |
|
|
66
80
|
| `PACTIVE_HOME` | 包根覆盖(测试用) |
|
|
67
81
|
| `PACTIVE_PI_BIN` / `PACTIVE_OPCTEAM_BIN` / `PACTIVE_DSH_BIN` | 宿主二进制路径覆盖 |
|
|
82
|
+
| `PACTIVE_HERDR_BIN` | herdr 二进制路径覆盖(`fleet` 复用 herdr;测试用 fake herdr) |
|
|
83
|
+
| `PACTIVE_FLEET_CWD` | `fleet up` 建 pane 时的工作目录(缺省 = 当前目录) |
|
|
84
|
+
| `PACTIVE_HERDR_TIMEOUT_MS` | herdr 调用的超时(默认 120000;`agent start` 本身最长等 30s) |
|
|
68
85
|
|
|
86
|
+
### 2.2b 助理舰队(不变量 I61–I66)
|
|
87
|
+
|
|
88
|
+
「不是一个助理,可以是无限个助理」。每个助理是**数据**不是代码:建第 4 个、第 40 个都不需要改代码或重装。
|
|
89
|
+
|
|
90
|
+
- `assistantId = <name>#<ownerKey 短哈希>`:稳定、可读;`rename` 不改 id。
|
|
91
|
+
- **按助理隔离**:护栏计数(每小时上限 / 最小间隔 / 冷却)、`epoch` 归属、`tasks`、ledger 分区各算一份;**A 的冷却压不住 B**。
|
|
92
|
+
- **每助理策略,缺省回落全局**:`policy.*` 可用 `config set … --assistant <name>` 覆盖;新建助理默认 `enabled=false`。
|
|
93
|
+
- **全局闸门**(不可被多助理绕过):`globalGuard.hourlyLimit`(默认 24 次/小时),超限时每个助理都记 `reason=global-limit`,不静默丢。
|
|
94
|
+
- **增删不留孤儿**:`assistant rm` 连带删除它的任务;ledger 只追加,历史保留。
|
|
95
|
+
- **人工闸门**:建 / 删 / 开关 / 重命名一律要 `--confirm`;模型侧只给可复制命令(I66)。
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
D=$(mktemp -d); export PACTIVE_STATE_DIR=$D
|
|
99
|
+
pactive assistant add 盯盘 --confirm
|
|
100
|
+
pactive assistant add 巡检 --confirm
|
|
101
|
+
pactive assistant ls # 一行一个,可直接 wc -l
|
|
102
|
+
pactive schedule "看盘片" --when 10m --assistant 盯盘
|
|
103
|
+
PACTIVE_STATE_DIR=$D pactive tick # 到期任务 + 空闲判定 → ledger
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
状态形状(schema v2):`assistants{}` / `guardByAssistant{}` / `globalGuard{}`,且 `tasks[].assistantId` 必填。
|
|
107
|
+
schema v1 的旧状态会在**读取时**迁移为 `assistants["default"]`(`enabled` 沿用旧 `idle.enabled`,原任务全归 `default`);
|
|
108
|
+
迁移失败会**显式报错**而不是隔离成空状态(I20)。
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
### 2.2c 常驻:复用 herdr 的 pane(不变量 I74–I79)
|
|
112
|
+
|
|
113
|
+
Pactive **不自建多路复用 / 不自绘 UI**(I74)——显示、存活、滚动缓冲、SSH 全部复用 [herdr](https://herdr.dev)。Pactive 只做三件事:把助理绑到一个 pane、按回执写账本、看门狗能读的绑定表。
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pactive fleet up --assistant 盯盘 # 建 pane + herdr agent start(幂等:已绑定则复用)
|
|
117
|
+
pactive fleet up --assistant 盯盘 --dry-run # 只打印将执行的 herdr 命令,零副作用
|
|
118
|
+
pactive fleet ls # 助理 ↔ pane_id ↔ agent 名 ↔ agent 状态 ↔ 最近投递
|
|
119
|
+
pactive fleet down --assistant 盯盘 # 只关 pane,助理/任务/历史都还在(I75)
|
|
120
|
+
pactive tick --ensure-fleet # 投递前补齐缺失 pane;pane 失效 → 回执 unreachable
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- **绑定落盘**:`assistants[id].pane = { paneId, agentName, host, surface, tabId, boundAt }`(schema v2 内新增字段,旧状态零迁移)。
|
|
124
|
+
- **agent 面 vs pane 面**:`pi/claude/codex/gemini/…` 走 `herdr agent start --kind <host>`,投递 `herdr agent prompt … --wait --timeout`;**OPCteam / DSH 在 herdr 里没有 agent kind**,只能 `herdr pane run`,绑定只记 `paneId`。
|
|
125
|
+
- **投递成功判据**(I77):`agent prompt` 返回 ok **且** herdr 自己观察到 `working|blocked`。`agent_prompt_stalled` → 记 `queued`;caller `timeout` → `queued` + `ambiguous: true`(不谎称任何一种);agent/pane 消失 → `unreachable` 并清空绑定。**不用** `pane read | grep` 判成功——屏幕文本不可靠。
|
|
126
|
+
- **降级必须说出口**(I78):无 `HERDR_ENV` / 无 `herdr` → `fleet up` exit 非 0 并列出具体原因,同时提示「daemon + outbox 仍可投递」。
|
|
127
|
+
- **一助理一 pane**(I79):`fleet up` 幂等;同名 agent 已在跑时**复用**该 pane(`adopted`)而不是再开一个。
|
|
128
|
+
- `PACTIVE_HERDR_BIN` 可注入 herdr 路径(测试用 fake herdr 记录 argv,不碰真会话)。
|
|
69
129
|
---
|
|
70
130
|
|
|
71
131
|
## 3. 宿主兼容矩阵
|
|
@@ -90,6 +150,9 @@ ACP 通道(第四个 adapter)**本期不实现**,仅留接口 stub 与文
|
|
|
90
150
|
Pactive 的默认状态是**不主动说话**:
|
|
91
151
|
|
|
92
152
|
- `idle.enabled = false`(空闲触发默认关闭)。引擎在、开关关。
|
|
153
|
+
- **每个助理也各有一个开关,同样默认关闭**:`assistant add` 之后 `enabled=false`,
|
|
154
|
+
要显式 `assistant enable <name> --confirm` 才会参与空闲/主动触发。
|
|
155
|
+
用户用 `schedule` 明确要求的任务不受助理开关限制,但同样受护栏与全局闸门约束。
|
|
93
156
|
- 打开 idle 必须走**人工闸门**:只有 CLI 带 `--confirm` 才能改;
|
|
94
157
|
MCP / 模型调用只能得到 `need_human_confirmation`,配置不变。
|
|
95
158
|
- 空闲判定是四要素合取,缺一不触发:控制权已交回(Stop 后)、当前不忙、
|
|
@@ -120,13 +183,30 @@ Pactive 的默认状态是**不主动说话**:
|
|
|
120
183
|
2. DSH Cordis bundle 在真实 GUI / 会话下的行为 —— 只计划验到 `--dump-config` 与工具注册。
|
|
121
184
|
3. OPCteam:改名后只验证到 `plugin validate`;**命令发现 / MCP 注册 / 人工批准后工具真正执行 / hooks 实战效果**均未在真实会话复验(本机未登录)。
|
|
122
185
|
4. 三宿主端到端冒烟:Pi(`pactive pi -p "/pactive status"` → `[pactive] idle=false reason=disabled`,exit 0)与 DSH(`install` → `--dump-config` 有 `# == pactive` 段 → `uninstall` 零残留)**已实测**;OPCteam 受阻于未登录,**未完成**。
|
|
123
|
-
5. npm 安装链:**已实测**(`npm pack` → `npm i -g --prefix <prefix> ./pactive-0.0.
|
|
186
|
+
5. npm 安装链:**已实测**(`npm pack` → `npm i -g --prefix <prefix> ./pactive-0.0.3-alpha.1.tgz` → `<prefix>/bin/pactive --version` = `0.0.3-alpha.1` → `<prefix>/bin/pactive doctor` = OK;同一 PATH 下旧命令 `acti` 已 `command not found`,exit 127)。**已验证**:真实 npm registry 安装(`npm i -g pactive@alpha`,0.0.3-alpha.1 已上线)。
|
|
124
187
|
6. npm 发布与回滚链路(`npm publish --tag alpha` / `npm view pactive version` / `npm deprecate`)。
|
|
125
188
|
7. Windows(Node spawn / 路径差异)—— 未在任何 Windows 机器验证。
|
|
126
189
|
8. ACP 通道(I51–I56)—— 全部未实现、未探针。
|
|
127
190
|
9. 空闲唤醒在 headless 下能否产生第二回合(B12 边界)。
|
|
128
191
|
10. 卸载残留枚举为 0 的实测(`装两次 → 卸两次 → 残留 0`)。
|
|
129
|
-
11. 安全项:假 key
|
|
192
|
+
11. 安全项:假 key 不落地、目录/文件权限 **已实测**;「子进程 env 过滤」(I30)在 herdr 适配器落地后**已有可测对象并实测**
|
|
193
|
+
(`tests/security/security.test.mjs`:herdr 子进程 env 内 0 命中 `*_API_KEY` / `*_TOKEN` / `*_SECRET`)。
|
|
194
|
+
12. 舰队(I61–I66):`tick` 只驱动到 **ledger**(`triggered` + `delivered` / `blocked`+reason);
|
|
195
|
+
**真正把 prompt 注入某个会话**(`delivered → answered → outcome` 闭环)**未实现**,因此
|
|
196
|
+
「按 assistantId 的守恒等式 triggered==delivered==answered==outcome」目前只能核到
|
|
197
|
+
`triggered==delivered`;`answered`/`outcome` 恒为 0 —— 这是**未验证**,不是通过。
|
|
198
|
+
13. 舰队:`tick` 是**一次性驱动**,没有任何常驻时钟/daemon;不跑 `tick` 就不会触发(「7×24 常驻」仍未落地)。
|
|
199
|
+
14. 舰队:多助理的并发隔离只在**同一进程内的状态层**验证过(`tests/core/assistants.test.mjs`、`tests/core/tick.test.mjs`);
|
|
200
|
+
多进程同时 `tick` 的行为只依赖既有的 `mutateState` 文件锁,**未做多进程实测**。
|
|
201
|
+
15. herdr 复用(I74–I79):**已实测**(herdr 0.9.5,真机):`fleet up` 建 pane + `agent start --kind pi` → `fleet ls` 与
|
|
202
|
+
`herdr agent list` 一一对应(status=idle)→ 第二次 `fleet up` 复用同一 pane → `tick` 经 `agent prompt --wait`
|
|
203
|
+
真投递(ledger `delivered` 带 `assistantId` + `paneId` + `status=done`)→ `fleet down` 关 pane、助理仍在、
|
|
204
|
+
`herdr agent list` 里 `pactive-` agent 数量回到 0。**未验证**:
|
|
205
|
+
- `fleet open`(`herdr agent focus`)只按帮助文本实现,**未**在真机点过(会切走用户焦点,故意不做);
|
|
206
|
+
- `--tab <label>` 分支(`herdr tab create`)只有 fake herdr 证据,**未**在真机建过标签;
|
|
207
|
+
- OPCteam / DSH 的 pane 面投递在真机上只到「已受理 → `queued`」,**没有任何** `delivered`:pane 面无 agent 状态可观测;
|
|
208
|
+
- 多助理(≥2)同时在 herdr 里常驻的布局与并发投递**未**实测(只做了 1 个助理的真机往返 + 3 助理的 fake 证据);
|
|
209
|
+
- `agent prompt --wait` 会**阻塞到该回合 settle**(或 caller 超时),长任务的 tick 因此会长时间持锁:这是已知限制,未做长回合实测。
|
|
130
210
|
|
|
131
211
|
---
|
|
132
212
|
|