You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+9-1Lines changed: 9 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,15 @@
2
2
3
3
All notable changes to the `pi-interactive-shell` extension will be documented in this file.
4
4
5
-
## [Unreleased]
5
+
## [0.11.1] - 2026-04-12
6
+
7
+
### Changed
8
+
- Monitor event callback now guards against emitting after the monitor is disposed, preventing stale queued notifications from a dismissed session.
9
+
- Poll-diff strategy now wraps the command in a recurring loop and diffs per-interval samples instead of accumulating full PTY output.
10
+
- Monitor event history cleanup retries until referenced monitor/session/active entries are gone, preventing history leaks from one-shot timers firing too early.
11
+
12
+
### Fixed
13
+
- Fixed `await` on already-resolved detector command promise (removed unnecessary `await` on non-async return).
Copy file name to clipboardExpand all lines: README.md
+28-14Lines changed: 28 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,15 +41,15 @@ The `interactive-shell` skill is automatically symlinked to `~/.pi/agent/skills/
41
41
|**Interactive** (default) | Yes — blocks until exit | Tool return value | Editors, REPLs, SSH — when you need the result now |
42
42
|**Hands-free**| No | Poll with `sessionId`| Dev servers, builds — when you want to watch progress and send follow-up commands |
43
43
|**Dispatch**| No | Notification on completion via `triggerTurn`| Delegating tasks to subagents — fire and forget |
44
-
|**Monitor**| No | Notification when a line matches `monitorFilter`| Watchers, logs, tests — wake only when something specific happens |
44
+
|**Monitor**| No | Notification on structured monitor trigger events| Watchers, logs, tests, and state checks — wake only when something specific happens |
45
45
46
46
**Interactive** — The overlay opens, user controls the session, agent waits for it to close. Use for editors (`vim`), database shells (`psql`), or any task where the agent needs the final result immediately.
47
47
48
48
**Hands-free** — The overlay opens but returns immediately. The agent polls periodically with `sessionId` to check status and get new output. Good for long-running builds or dev servers where you want to react mid-flight (send input, check logs, kill when ready).
49
49
50
50
**Dispatch** — Returns immediately. No polling. The agent gets woken up via `triggerTurn` only when the session completes (natural exit, timeout, quiet detection, or user kill). The notification includes a tail of the output. This is the default for delegating work to subagents. Add `background: true` to skip the overlay entirely.
51
51
52
-
**Monitor** — Returns immediately. No polling, no completion notification. The agent gets woken up only when a cleaned output line matches `monitorFilter`. Use for watching logs or test output for specific events (`FAIL`, `error`, `Compiled successfully`). Runs headless; attach to inspect if needed.
52
+
**Monitor** — Returns immediately. No polling, no completion notification. The agent gets woken up when a configured monitor trigger emits an event. Supports stream triggers and poll-diff checks, optional cooldowns, persistence controls, detector commands, and event history queries. Runs headless; attach to inspect if needed.
53
53
54
54
## Quick Start
55
55
@@ -154,30 +154,44 @@ Multiple headless dispatches can run concurrently alongside a single interactive
154
154
155
155
### Monitor (Event-Driven)
156
156
157
-
Wake the agent immediately when output matches a pattern — no polling, no waiting for completion.
157
+
These examples are **agent tool calls**. End users should ask in natural language (for example: "watch my tests and alert me on failures"), and Pi should invoke `interactive_shell` with the monitor config.
158
+
159
+
Wake the agent when monitor triggers emit events — no polling and no waiting for process completion.
158
160
159
161
```typescript
160
-
//Watch tests for failures
162
+
//Stream strategy with multiple named triggers
161
163
interactive_shell({
162
164
command: 'npm test --watch',
163
165
mode: "monitor",
164
-
monitorFilter: "FAIL"
166
+
monitor: {
167
+
strategy: "stream",
168
+
triggers: [
169
+
{ id: "failed", literal: "FAIL" },
170
+
{ id: "error", regex: "/error|exception/i" }
171
+
],
172
+
throttle: { dedupeExactLine: true },
173
+
persistence: { stopAfterFirstEvent: false }
174
+
}
165
175
})
166
176
167
-
//Watch dev server for errors (case-insensitive)
177
+
//Poll-diff strategy (default 5s interval)
168
178
interactive_shell({
169
-
command: 'npm run dev',
179
+
command: 'curl -sf http://localhost:3000/health',
170
180
mode: "monitor",
171
-
monitorFilter: "/error|warn/i"
181
+
monitor: {
182
+
strategy: "poll-diff",
183
+
triggers: [{ id: "changed", regex: "/./" }],
184
+
poll: { intervalMs: 5000 }
185
+
}
172
186
})
173
187
```
174
188
175
-
Monitor mode is for **watching ongoing processes** where you care about specific output patterns, not completion. Unlike dispatch, you get woken up on the **first match**, not when the process exits. Use it for:
176
-
- Test watchers — catch failures as they happen
177
-
- Dev servers — alert on compile errors
178
-
- Log tails — react to specific events
189
+
Monitor mode emits structured payloads (`sessionId`, `eventId`, `timestamp`, `strategy`, `triggerId`, `matchedText`, `lineOrDiff`, `stream`) and can be queried later. `monitorFilter` was removed in favor of the structured `monitor` object.
179
190
180
-
`monitorFilter` accepts plain text (literal substring) or `/regex/flags`. ANSI escape codes are stripped before matching, so colors don't break your patterns. The notification includes the matched line and the matched text.
interactive_shell({ dismissBackground: "calm-reef" }) // specific session
303
317
```
304
318
305
-
Monitor sessions work the same way — they're headless background sessions that happen to wake you on matches instead of completion.
319
+
Monitor sessions work the same way — they're headless background sessions that wake you on monitor events instead of completion.
306
320
307
321
User can also `/spawn` to launch the configured default spawn agent, `/spawn codex`, `/spawn claude`, `/spawn pi`, `/spawn fork`, or `/spawn pi fork`. Add `--worktree` to spawn in a separate git worktree, for example `/spawn codex --worktree` or `/spawn pi fork --worktree`. Plain `/spawn claude` stays a normal interactive overlay. `fork` is Pi-only. Worktrees are left in place and the overlay will tell you where they were created. `/attach` or `/attach <id>` reattaches, and `/dismiss` or `/dismiss <id>` cleans up from the chat. The keyboard spawn shortcut is separate from `/spawn` and uses `spawn.shortcut`.
Copy file name to clipboardExpand all lines: examples/skills/interactive-shell/SKILL.md
+26-7Lines changed: 26 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ Pi has two ways to delegate work to other AI coding agents:
24
24
25
25
**Dispatch subagents** also use `interactive_shell` but with `mode: "dispatch"`. The agent fires the session and moves on. When the session completes, the agent is woken up via `triggerTurn` with the output in context. Add `background: true` for headless execution (no overlay).
26
26
27
-
**Monitor mode** (`mode: "monitor"`) runs headless and event-driven. It wakes the agent only when a cleaned output line matches `monitorFilter`, so there is no polling loop.
27
+
**Monitor mode** (`mode: "monitor"`) runs headless and event-driven. It wakes the agent on structured monitor trigger events (stream or poll-diff), so there is no polling loop.
28
28
29
29
**Background subagents** run invisibly via the `subagent` tool. Pi-only, but captures full output and supports parallel execution.
30
30
@@ -125,19 +125,30 @@ interactive_shell({
125
125
```
126
126
127
127
### Monitor (Event-Driven, Headless)
128
-
Run a background process and wake the agent only when output lines match `monitorFilter`.
128
+
Run a background process and wake the agent on structured monitor triggers.
129
129
130
130
```typescript
131
131
interactive_shell({
132
132
command: 'npm test --watch',
133
133
mode: "monitor",
134
-
monitorFilter: "FAIL"
134
+
monitor: {
135
+
strategy: "stream",
136
+
triggers: [
137
+
{ id: "failed", literal: "FAIL" },
138
+
{ id: "error", regex: "/error|warn/i" }
139
+
],
140
+
throttle: { dedupeExactLine: true }
141
+
}
135
142
})
136
143
137
144
interactive_shell({
138
-
command: 'npm run dev',
145
+
command: 'curl -sf http://localhost:3000/health',
139
146
mode: "monitor",
140
-
monitorFilter: "/error|warn/i"
147
+
monitor: {
148
+
strategy: "poll-diff",
149
+
triggers: [{ id: "changed", regex: "/./" }],
150
+
poll: { intervalMs: 5000 }
151
+
}
141
152
})
142
153
```
143
154
@@ -499,7 +510,11 @@ interactive_shell({ dismissBackground: true }) // all
499
510
interactive_shell({ dismissBackground: "calm-reef" }) // specific
500
511
501
512
// Start an event-driven monitor session (headless)
502
-
interactive_shell({ command: 'npm test --watch', mode: "monitor", monitorFilter: "FAIL" })
0 commit comments