Repository navigation
feat: add monitor events - #52569
feat: add monitor events#52569Eslamasabry wants to merge 7 commits into
Conversation
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Active monitors outlive deleted sessions, retained records grow without bounds, and completed monitor output becomes inaccessible.
Review effort: Balanced
Findings: 3
Open (3)
What changed in this PR
Adds durable background monitors that stream shell stdout into sessions, expose lifecycle APIs/events, and appear in the TUI.
Changes:
- Adds monitor execution, limits, recovery, permissions, and agent tools.
- Exposes monitor schemas, events, API routes, and generated clients.
- Adds TUI task status, output/stop controls, and extensive tests.
| File | Description |
|---|---|
services/www/public/openapi.json |
Updates published API snapshot. |
services/www/openapi.json |
Updates website API snapshot. |
packages/tui/test/fixture/tui-client.ts |
Mocks monitor listing. |
packages/tui/test/component/dialog-shell-output.test.tsx |
Updates empty-state assertion. |
packages/tui/test/cli/tui/composer-keymap.test.tsx |
Tests monitor rendering, stopping, and reconnects. |
packages/tui/src/routes/session/index.tsx |
Adds background-task palette command. |
packages/tui/src/routes/session/composer/shell-tab.tsx |
Displays and controls monitor tasks. |
packages/tui/src/config/keybind.ts |
Renames shell-task keybind descriptions. |
packages/server/test/monitor.test.ts |
Tests listing and restart recovery. |
packages/server/src/routes.ts |
Registers and recovers monitor service. |
packages/server/src/handlers/monitor.ts |
Implements monitor list handler. |
packages/server/src/handlers.ts |
Registers monitor handler. |
packages/schema/test/monitor.test.ts |
Tests monitor contracts and events. |
packages/schema/src/monitor.ts |
Defines monitor schemas and events. |
packages/schema/src/index.ts |
Exports monitor schema. |
packages/schema/src/event-manifest.ts |
Registers monitor events. |
packages/protocol/test/event.test.ts |
Verifies public event classification. |
packages/protocol/src/groups/monitor.ts |
Defines monitor HTTP API group. |
packages/protocol/src/client.ts |
Maps monitor client namespace. |
packages/protocol/src/api.ts |
Adds monitor protocol group. |
packages/protocol/openapi.json |
Updates protocol API snapshot. |
packages/core/test/tool-monitor.test.ts |
Tests monitor permission handling. |
packages/core/test/shell-stream.test.ts |
Tests streaming and process cleanup. |
packages/core/test/monitor.test.ts |
Tests monitor lifecycle and limits. |
packages/core/test/monitor-output.test.ts |
Tests output decoding and bounds. |
packages/core/test/location-layer.test.ts |
Verifies monitor tool registration. |
packages/core/src/tool/shell-permission.ts |
Shares shell authorization preparation. |
packages/core/src/tool/plugin/shell.ts |
Uses shared permission preparation. |
packages/core/src/tool/plugin/monitor.ts |
Adds monitor agent tools. |
packages/core/src/shell.ts |
Adds stdout capture and forced stopping. |
packages/core/src/session/runner/prompt/system.txt |
Marks monitor output as untrusted. |
packages/core/src/plugin/internal.ts |
Registers monitor service and plugin. |
packages/core/src/monitor/output.ts |
Implements bounded line batching. |
packages/core/src/monitor.ts |
Implements monitor persistence and lifecycle. |
packages/client/test/solid-monitor.test.ts |
Tests monitor cache synchronization. |
packages/client/test/contract-identity.test.ts |
Verifies schema export identity. |
packages/client/src/solid/data.ts |
Adds reactive monitor state. |
packages/client/src/promise/index.ts |
Exports promise monitor API type. |
packages/client/src/promise/generated/types.ts |
Adds generated monitor types. |
packages/client/src/promise/generated/client.ts |
Adds generated promise endpoint. |
packages/client/src/promise/api.ts |
Exposes promise monitor API. |
packages/client/src/effect/index.ts |
Exports Effect monitor contracts. |
packages/client/src/effect/generated/client.ts |
Adds generated Effect endpoint. |
packages/client/src/effect/api/api.ts |
Defines Effect monitor API. |
packages/client/script/build.ts |
Includes monitor types in generation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


Issue for this PR
Related to #49842 and the closed, unmerged Monitor proposal #33806. This builds on v2’s existing shell jobs and synthetic inbox. Scheduled wakes in #52103 remain separate.
Type of change
What does this PR do?
Problem: Agents poll and sleep to track changing work, wasting tokens and turns. Background shell already reports completion, but cannot report incremental progress.
What this adds:
The agent can call
monitor({ command, description, timeoutMs?, delivery? }), receive a task ID, and end its turn. Stdout lines become clearly labelled events in the same session and wake the agent automatically. Stderr only goes to the shell log.monitor_stop({ id })cancels a watch.The TUI’s existing background task list shows monitor descriptions, event counts, start/deadline times, and terminal status. It includes a command-palette entry, output access, and stop progress/error feedback.
Typed
monitor.started,monitor.event, andmonitor.endedevents and session-scoped list, output, and stop endpoints support reconnecting clients. Output stays accessible after completion and server restart without requiring live shell state.Design:
Tool.Service.transformpath inpackages/core/src/tool/plugin/monitor.ts, wired byplugin/internal.ts.packages/core/src/monitor.tsowns server-side jobs throughJob.Service. A KV record stores monitor/session/shell IDs, saved PID, description, delivery mode, start/deadline/end times, event and byte counters, status, reason, and exit code.packages/core/src/shell.tsstreams stdout separately while retaining the existing combined log. Complete lines are batched over a 200 ms window, then admitted throughSession.syntheticand the durable inbox.SessionRunCoordinatorwake/busy handling delivers defaultsteerevents at safe step boundaries without cancelling tools.delivery: "queue"waits until the turn ends. Idle sessions wake automatically.packages/server/src/routes.tsreconciles running records before serving requests after restart. They becomeended: server_restarted; no process is resumed and no saved PID is signalled.packages/schema/src/monitor.tsjoinevent-manifest.tsand flow through the existing bus/SSE and generated clients. The TUI extends its existing shell task list.Safety:
[background event from monitor '<description>' — not a user message]. The system prompt treats event contents as untrusted data, never authority to change the user’s request or permissions.Follow-ups out of scope: WebSocket sources and keeping live monitors running across a server restart.
How did you verify your code works?
Latest review follow-up: Fixed all three review findings: bounded terminal history and owned-log cleanup, cancellation on session deletion (including deletion during approval), and reopening completed output independently of shell cache state. Added session-scoped output and stop APIs and regenerated both clients and all OpenAPI snapshots.
Latest-head validation with Bun 1.4.2:
bun run checkpassed: lint and all 36 typecheck tasks.bun run lint:effect-simplificationspassed.bun run buildpassed, including link validation.git diff --checkpassed.The complete test suite was not rerun for this follow-up. The full-suite results below describe the original submission.
Tests: Added coverage for line batching and UTF-8 boundaries, stderr exclusion, exit codes, process-group cleanup, deadlines, rate/size limits, busy queue/default steering, event labels, permission denial, startup cancellation, restart recovery, generated API access, client reconnect races, and narrow/wide TUI rendering.
Original submission validation with the repository-pinned Bun 1.4.2, without new dependencies or lockfile changes:
bun install --frozen-lockfilebun run checkbun run lint:effect-simplificationsTZ=UTC GITHUB_ACTIONS=false bun turbo test --concurrency=3 --continue=alwaysbun run check:generatedinpackages/clientandservices/wwwgit diff origin/v2 --checkFocused core monitor tests: 21 passed. Shell/process tests: 103 passed, 19 existing skips. Schema, protocol, server, client reconnect, and TUI rendering/stop tests also passed.
Batching, deadline, and rate tests use the existing Effect test clock. Subprocess tests use readiness handshakes and short deadlines.
Final package results:
Every other task passed. All Monitor tests passed.
Full-suite environment limitations:
EPERM), blocking four existingpersistent-pty-daemon.test.tstests./procprocess IDs, blocking the existing ACP lifecycle test that enumerates children withpgrep -P.No tests were skipped or modified to hide these restrictions.
TZ=UTCmatches CI and avoids an existing Date parity test’s timezone assumption.OpenAPI snapshots were regenerated with the repository scripts. The generator also updates already-stale credential/pairing entries; no corresponding runtime behavior changed.
Screenshots / recordings
The TUI was checked at 100 and 48 columns, including running monitors, restart status, and stop-error feedback, in dark and light themes. Screenshot attachment is pending because the browser upload failed.
Illustrative demo—the agent writes and starts its own CI watcher:
Checklist