pi-pier 0.2.3 → 0.2.5

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 CHANGED
@@ -43,10 +43,9 @@ The installer also verifies node / pi / herdr versions, probes local paths, and
43
43
  | Tool | Purpose |
44
44
  |---|---|
45
45
  | `todo_write` | Full-replacement todo list. Session JSONL is the single source of truth; correct rollback on branch switches. Projected live onto the pane title (`▶i ○p ■b ✓c (N/M) · current task`). `/todos` command to view/edit/unblock |
46
- | `subagent` | Delegate self-contained subtasks to an isolated pi session in its own herdr pane (separate context window). Foreground / parallel / background modes |
47
- | `list_agents` | Live state of background subagents (running / idle + panes) |
48
- | `send_message` | Follow-up work for a subagent (queued if busy, wakes if idle) |
49
- | `interrupt_agent` | Stop a subagent's current turn; it stays alive for more messages |
46
+ | `subagent` | Delegate self-contained subtasks to an isolated pi session in its own herdr pane. Actions: `spawn` (default; foreground / parallel / background), `list`, `send`, `interrupt`, `resume` |
47
+ | `terminal` | Persistent interactive shells in dedicated herdr panes. Actions: `open`, `send`, `read`, `signal`, `close`, `list` |
48
+ | `ask_user_question` | Human gate: pane shows blocked in herdr while waiting |
50
49
 
51
50
  ### Behaviors
52
51
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-pier",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "pier: pi extension that fuses pi agent sessions with the herdr pane/tab orchestrator — todo_write loop closure + interactive subagents in isolated panes",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -2,85 +2,157 @@
2
2
  name: pi-herdr-workflow
3
3
  description: >-
4
4
  How to use the pi-herdr workbench fusion: todo_write discipline, subagent
5
- delegation (foreground/parallel/background), list_agents/send_message/
6
- interrupt_agent, and how the human watches everything in herdr panes.
5
+ delegation (foreground/parallel/background via action spawn/list/send/
6
+ interrupt/resume), terminal persistent shells, and how the human watches
7
+ everything in herdr panes.
7
8
  Load when the user asks about multi-step plans, delegating subtasks,
8
9
  background work, or checking on running subagents.
9
10
  license: MIT
10
11
  ---
11
12
 
12
- # pi-herdr 工作台工作流
13
-
14
- 你在一个 herdr 终端工作区(pane)里运行。本 skill 教你把 `todo_write` 与
15
- `subagent` 工具用好;人类在 herdr 的 TUI 里实时观察:每个 pane 的窗格头
16
- 显示 `▶x ○y ■b ✓z · 当前任务`,语义状态(working/blocked/idle)上卷到侧边栏。
17
-
18
- ## 1. todo 纪律(全量替换语义)
19
-
20
- - `todo_write` 每次调用提交**完整列表**(last-wins),没有部分更新。
21
- - 条目 = `content`(非空、唯一、5–10 词的命令式短语,写"做什么"不写"怎么做",**不带编号前缀**)+ `status`(pending | in_progress | completed | blocked | abandoned)。
22
- - `blocked` = 在等外部条件(信息、人、别的系统),必须带 `blocker` 说明等什么;`abandoned` = 显式放弃(不删条目,保留计划痕迹)。
23
- - 多阶段计划用可选 `phase` 分组(≤30 字);单阶段就不写 phase。
24
- - 保持列表精简(≤15 条):一条 = 一个有意义的交付单元,不是微步骤。
25
- - 正在推进的标 `in_progress`(真正并行时才允许多条);**完成立即标 completed**。
26
- - **测试失败/实现不完整/有未解决错误时绝不算 completed**——保持 in_progress,或改成 blocked 并说明 blocker。
27
- - **绝不把 todo_write 当成一轮里的唯一工具调用**——搭着真实工作一起提交。
28
- - 记不清某条任务的原文时,从上一轮 todo_write 结果里找,**不许凭记忆编**(防幻影条目)。
29
- - **不要**把已委派给子代理的工作写进自己的 todo——那是子代理自己的职责;
30
- 你的列表只跟踪你自己的工作。等子代理结果回流后再验收归档。
31
- - 多子代理协作时在 content 里写清**文件所有权**(例如 "重构 auth 模块(只碰 src/auth/)"),
32
- 避免两个 agent 抢同一文件。
33
- - **你是被委派的工作 pane**(`PI_HERDR_SUBAGENT=1`)时,本插件自动执行严格模式:
34
- 你的列表任何时候**至多一条 in_progress**(多写会被归一化),全部完成会自动晋升下一条 pending。
35
- 你是主控 pane 时保持并行语义,纪律由本节承担。
36
-
37
- ## 2. 子代理委派
38
-
39
- 子代理 pane 跑的是**交互式 pi TUI**(独立会话):人类可以随时进入该 pane
40
- 直接与子代理对话;你的委派 prompt 会以消息形式出现在它的对话里。
41
-
42
- ### 选型
43
- - **前台**(默认):调用后等待结果返回。适合"下一步依赖其结果"的委派。
44
- - **后台**(`run_in_background: true`):立即返回 `agentId`;子代理在独立
45
- pane 常驻运行。适合长任务/并行推进。它会**持续存在**(有自己的持久会话),
46
- 结算时你会收到一条 "Background subagent <id> finished..." 通知消息。
47
- - 一条消息里的多个 subagent 调用会并行执行(上限 4 并发)。
48
- - 可选 `role`(如 `advisor`)只是标签:v1 不改工具面、不改生命周期,与普通 task 一样走 TTL;省略 = `task`。复活走 `resume_subagent`,不要假设 pane 会自动补回来。
49
-
50
- ### 任务 tab 分组(`tab` 参数)
51
- - 每个委派默认开一个**以任务命名的新 tab**(名字取自 `description`)。
52
- - 一组相关的子任务用同一个 `tab` 名字收进同一个 tab(例如网络调研 + 现状
53
- 摸索都用 `tab: "调研"`),人类在 herdr 里一个 tab 内看完全部相关 pane。
54
- - 名字要短(≤20 字)、人类一眼能懂;tab 栏就是任务板。
55
- - 不要为了少开 tab 而把无关任务塞进同一个 tab;一个 tab = 一个任务目标。
56
- - **任务 tab 是临时的**:tab 内全部子代理结算后(默认宽限约 10 分钟)tab
57
- 会自动关闭——不要假设它的 pane 长期存在;需要回看/继续时用
58
- `resume_subagent(taskId)` 从历史复活,而不是引用已关的 pane。
59
-
60
- ### prompt 纪律
61
- - prompt 必须**自包含**:子代理看不到你的对话历史,只有这段 prompt。
62
- - 明确输入(哪些文件/事实)、明确产出(交什么)、明确边界(不碰什么)。
63
- - 用文件/工件传递共享上下文,不要把大段内容塞进 prompt。
64
- - 独立任务才委派;互相依赖的工作拆给同一子代理。
65
-
66
- ### 后台子代理的后续管理
67
- - `list_agents`:查看全部后台子代理与状态(running/idle)。
68
- - `send_message(agentId, message)`:给子代理追加任务(FIFO;已结算的子代理
69
- 会被唤醒继续干)。
70
- - `interrupt_agent(agentId)`:打断子代理当前轮次(它仍驻留,可继续 send_message)。
71
- - 子代理结算后不要重新委派同一个 agentId 之外的新任务时,可再 send_message 唤醒。
72
-
73
- ## 3. 人类闸门
74
-
75
- - 需要人类决策(审批、取舍、方向选择)时,用 `ask_user_question`(本插件提供)——
76
- 等待回答期间,你的 pane 在 herdr 里呈 **blocked** 状态,人类会看到并介入;
77
- 答案会作为工具结果回到你的上下文,然后继续工作。
78
- - 子代理 pane 在 herdr 里可被人类直接进入交互;你的委派描述(pane 标签)
79
- 要写得人类一眼能懂。
80
-
81
- ## 4. 多 agent 纪律(工程实践映射)
82
-
83
- - 你是仲裁者:验收每个子代理的输出,再合入你的工作;不要把仲裁权下放。
84
- - 关键结论安排独立复核(换个子代理 reviewer 复核),不盲信单一子代理。
85
- - 同构的并行子代理会犯同样的错:给不同子代理不同的任务边界与产出格式。
86
- - 委派后继续做你自己的事,不要干等(前台调用除外)。
13
+ # pi-herdr workbench workflow
14
+
15
+ You run inside a herdr terminal pane. This skill is how to use `todo_write` and
16
+ `subagent` well. The human watches live in herdr: each pane header shows
17
+ `▶x ○y ■b ✓z · current task`, and semantic state (working / blocked / idle)
18
+ rolls up to the sidebar.
19
+
20
+ ## 1. Todo discipline (full-replace semantics)
21
+
22
+ - Every `todo_write` submits the **entire list** (last-wins). There is no partial update.
23
+ - An item is `content` (non-empty, unique, 5–10 word imperative phrase: *what*, not *how*, **no numeric prefix**) + `status` (`pending` | `in_progress` | `completed` | `blocked` | `abandoned`).
24
+ - `blocked` = waiting on an external condition (info, a person, another system) and **must** include `blocker` saying what is missing; `abandoned` = explicit drop (keep the row; do not delete the plan trail).
25
+ - Multi-phase plans may group with optional `phase` (≤30 chars). Single-phase: omit `phase`.
26
+ - Keep the list small (≤15): one item = one meaningful deliverable, not a micro-step.
27
+ - Mark what you are actually doing `in_progress` (multiple only when truly parallel); **mark `completed` the moment it is done**.
28
+ - **Never mark completed when tests fail, the implementation is incomplete, or errors remain** — stay `in_progress`, or switch to `blocked` with a blocker.
29
+ - **Never make `todo_write` the only tool call in a turn** — batch it with real work.
30
+ - If you forget an item's exact wording, copy it from the previous `todo_write` result. **Do not invent from memory** (phantom items).
31
+ - **Do not** put work you already delegated to a subagent on *your* todo list — that is the subagent's job. Your list tracks *your* work. Accept and archive after the result comes back.
32
+ - When several subagents collaborate, put **file ownership** in `content` (e.g. "refactor auth (only src/auth/)") so two agents do not fight over the same file.
33
+ - When **you** are a delegated worker pane (`PI_HERDR_SUBAGENT=1`), this plugin enforces strict mode: **at most one `in_progress`** at a time (extras are normalized), and finishing the current item auto-promotes the next `pending`. The master pane keeps parallel semantics; this section is the discipline.
34
+
35
+ ## 2. Subagent delegation
36
+
37
+ A subagent pane is an **interactive pi TUI** (independent session). A human can enter that pane and talk to it at any time. Your delegation prompt appears as a message in its conversation.
38
+
39
+ The `subagent` tool has 5 operations controlled by the `action` parameter (default: `spawn`):
40
+
41
+ ### spawn (default action)
42
+
43
+ Create a subagent in a new pane:
44
+ - **Foreground** (default): the call waits for a result. Use when the next step depends on it.
45
+ - **Background** (`run_in_background: true`): returns `agentId` immediately; the subagent keeps running in its own pane. Use for long / parallel work. It **persists** (own session). On settle you get a "Background subagent <id> finished..." notice.
46
+ - Multiple `subagent` calls (with `action: "spawn"`) in one message run in parallel (cap 4).
47
+ - Optional `role` (e.g. `advisor`) matches a profile when found; unknown names are labels only.
48
+
49
+ **Task-tab grouping** (`tab`):
50
+ - Each delegation defaults to a **new tab named from `description`**.
51
+ - Related subtasks share one `tab` name (e.g. web research + status probe both `tab: "research"`) so the human sees every related pane in one herdr tab.
52
+ - Keep names short (≤20 chars) and obvious; the tab bar *is* the task board.
53
+ - Do not cram unrelated work into one tab to "save tabs". One tab = one goal.
54
+ - **Task tabs are temporary**: after every subagent in the tab has settled (default grace ~10 minutes) the tab closes. Do not assume those panes last. To review or continue, use `action: "resume"` from history — do not cite a closed pane.
55
+
56
+ **Prompt discipline**:
57
+ - The prompt must be **self-contained**: the subagent cannot see your conversation, only this prompt.
58
+ - State inputs (which files / facts), outputs (what to deliver), and bounds (what not to touch).
59
+ - Share context via files / artifacts. Do not dump large blobs into the prompt.
60
+ - Delegate only independent work; dependent steps go to the same subagent.
61
+
62
+ ### list
63
+
64
+ Show all background subagents with status (`running` / `idle` / `blocked`), `agentId`, and last activity.
65
+
66
+ Call: `subagent(action: "list")`
67
+
68
+ ### send
69
+
70
+ Append follow-up message to background subagent:
71
+ - If working: delivered at next tool-gap (steering, seconds).
72
+ - If idle: wakes for new turn.
73
+ - After settle, `send` to wake it; do not spawn duplicate.
74
+
75
+ Call: `subagent(action: "send", agentId: "<id>", message: "...")`
76
+
77
+ ### interrupt
78
+
79
+ Abort subagent's current turn (fire-and-return). Pane stays; can `send` again.
80
+
81
+ Call: `subagent(action: "interrupt", agentId: "<id>")`
82
+
83
+ ### resume
84
+
85
+ Revive finished subagent from ledger by `taskId`. Opens saved conversation in new pane; then `send` work.
86
+
87
+ The ledger is an append-only JSONL file at `~/.pi/agent/herdr-pi/history/<flattened-cwd>/history.jsonl`, one row per status change. Use `list` for live panes from this session; for tasks from earlier sessions or closed panes, read/grep the ledger for the `taskId`.
88
+
89
+ Call: `subagent(action: "resume", taskId: "<uuid>")`
90
+
91
+ ## 3. Human gate
92
+
93
+ - For a human decision (approval, tradeoff, direction), use `ask_user_question` (this plugin). While waiting, your pane is **blocked** in herdr so the human can see and intervene. The answer comes back as the tool result, then you continue.
94
+ - A human can enter a subagent pane directly. Write the delegation `description` (pane label) so a human understands it at a glance.
95
+
96
+ ## 4. Multi-agent engineering rules
97
+
98
+ - You are the arbiter: accept each subagent's output, then merge it. Do not outsource arbitration.
99
+ - Independent review for critical conclusions (a different subagent as reviewer). Do not trust a single worker blindly.
100
+ - Homogeneous parallel workers make the same mistakes: give them different bounds and output shapes.
101
+ - After delegating, keep doing your own work. Do not idle-wait (except a foreground call).
102
+
103
+ ## 5. Terminal management (master only)
104
+
105
+ The `terminal` tool has 6 operations for persistent shell sessions (dev servers, REPLs, stateful work):
106
+
107
+ ### open
108
+
109
+ Create a persistent interactive terminal (resident shell in its own herdr pane) and return its `terminal_id`.
110
+
111
+ The shell keeps its cwd, environment variables, and background processes across `terminal` calls — use it for dev servers, REPLs, or multi-step shell work instead of one-shot bash calls.
112
+
113
+ Call: `terminal(action: "open", cwd: "<path>")`
114
+ Returns: `terminal_id` and readiness status (prompt detected or busy).
115
+
116
+ ### send
117
+
118
+ Send a text command (plain text only, no ANSI escapes) to a persistent terminal; Enter is appended automatically.
119
+
120
+ Returns after the keystrokes are delivered — poll with `action: "read"` for output (long-running commands keep producing output across reads).
121
+
122
+ Call: `terminal(action: "send", terminal_id: "<id>", text: "npm run dev")`
123
+
124
+ ### read
125
+
126
+ Read new output from a persistent terminal since your last read (cursor-based increment; the first read returns the recent buffer).
127
+
128
+ Parameters:
129
+ - `terminal_id`: your terminal from `open`. Alternatively `pane_id`: a pane in this session's own tab (narrow scope by design).
130
+ - `max_chars`: output cap for this read.
131
+
132
+ Output is ANSI-stripped and bounded; if the buffer scrolled past your last read you get a reset marker plus the current tail. Detecting a fullscreen TUI program (vim/less/top) returns an error with suggestions instead of garbage.
133
+
134
+ Call: `terminal(action: "read", terminal_id: "<id>")`
135
+
136
+ ### signal
137
+
138
+ Send a control key to a persistent terminal: ctrl+c (interrupt), ctrl+d (EOF), ctrl+z (suspend), esc, enter.
139
+
140
+ Use ctrl+c to stop a running command; anything beyond this whitelist is outside the terminal seam.
141
+
142
+ Call: `terminal(action: "signal", terminal_id: "<id>", key: "ctrl+c")`
143
+
144
+ ### close
145
+
146
+ Close a persistent terminal (kills its shell process tree and removes the pane).
147
+
148
+ Terminal state does not survive close — persist anything you need to files first.
149
+
150
+ Call: `terminal(action: "close", terminal_id: "<id>")`
151
+
152
+ ### list
153
+
154
+ List this session's persistent terminals with open/closed and pane-liveness status.
155
+
156
+ Entries whose pane is gone (human closed it, restart) are marked closed — terminal sessions do not survive pane closure or restarts; persist state to files instead of relying on terminal reuse.
157
+
158
+ Call: `terminal(action: "list")`