@fradser/pi-monitor
Result-contract background monitoring for Pi — capture noisy command output outside model context and expose one structured terminal result
Package details
Install @fradser/pi-monitor from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@fradser/pi-monitor- Package
@fradser/pi-monitor- Version
2.0.2- Published
- Aug 18, 2026
- Downloads
- 453/mo · 453/wk
- Author
- fradser
- License
- MIT
- Types
- extension, skill
- Size
- 38.2 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"skills": [
"./skills"
],
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Monitor Pi Package
Result-contract background monitoring for Pi. Run a non-interactive command, keep noisy progress output outside the model context, and wake the agent once with a structured terminal result.
Why result contracts
Raw build, deploy, test, and server logs contain far more progress text than an agent needs. Streaming those lines into the conversation repeatedly consumes context and can trigger unnecessary model turns.
Use monitor_start for long-running commands. After it returns, the current
agent turn ends immediately. Do not sleep, poll, wait, or do follow-up work;
wait for the terminal result to wake the agent. Other tools and commands remain
available and are never blocked by the monitor. The terminal result automatically
wakes the agent once when:
result_patternmatches:successfailure_patternmatches:failure- the command exits non-zero:
failure - the command exits zero without matching:
result_missing - the timeout expires:
timeout
Tools and command
| Tool / Command | Description |
|---|---|
monitor_start |
Run a command and wait for a declared success or failure result |
monitor_stop |
Stop one or all active monitors without emitting a result |
/monitor |
Inspect active and recent monitors and their retained output |
Installation
pi install npm:pi-monitor-fradser
# or from this repository:
pi install /path/to/pi-packages/packages/monitor
Preferred usage: JSON sentinel
When the command can be wrapped, print a unique sentinel containing JSON:
sh -c '
if pnpm test; then
printf '\''__PI_MONITOR_RESULT__ {"status":"success"}\n'\''
else
code=$?
printf '\''__PI_MONITOR_FAILURE__ {"status":"failure","exitCode":%s}\n'\'' "$code"
exit "$code"
fi
'
Start the monitor with named json captures:
monitor_start
command="<wrapped command>"
description="test suite result"
result_pattern="__PI_MONITOR_RESULT__ (?<json>\\{.*\\})"
failure_pattern="__PI_MONITOR_FAILURE__ (?<json>\\{.*\\})"
A successful result wakes the agent once with compact text:
[monitor monitor_1] test suite result
status=success
elapsed=8.4s
result={"status":"success"}
Matching existing command output
For commands that already print a stable terminal line, use a result regex with named captures:
monitor_start
command="pnpm dev"
description="development server"
result_pattern="Ready on (?<url>https?://\\S+)"
failure_pattern="(?:EADDRINUSE|FATAL|Failed to start):? (?<reason>.*)"
timeout_ms=120000
Avoid broad patterns such as success|error|ready. A result pattern is a
terminal contract, not a general log filter.
Diagnostics
Ordinary output never triggers background model turns. When a terminal result is
failure, timeout, or result_missing, the terminal notification already
includes a bounded tail of source-labelled output. There is no output-reading
or status-polling tool; wait for the one terminal notification instead of
calling another tool or sleeping and checking again.
A running monitor showing 0 retained, 0 dropped while the source clearly
produced output usually means an intermediate filter is block-buffering: grep,
sed, and awk buffer when their stdout is a pipe, so lines stall until ~4 KB
accumulates or the process exits. Keep filter stages line-buffered (grep --line-buffered, sed -l, awk with fflush()), or emit the terminal result
without a filter stage.
Output is labelled by source:
[stdout] compiling application
[stderr] connection refused
The retained history and terminal diagnostic tail are bounded:
- individual displayed line: 10 KiB
- unterminated input fragment: 64 KiB
- retained output: 2,000 lines and 256 KiB per monitor
- terminal diagnostic tail: 100 lines and 32 KiB maximum
- recently finished monitor history: 20 monitors
Result semantics
- Both stdout and stderr are scanned for
result_patternandfailure_pattern. - The first terminal match wins and stops the process group.
- Named regex captures are returned in
captures. - The model-facing terminal message uses compact
key=valuetext. A named capture calledjsonis parsed intoresultand emitted as compact JSON; complete structured data remains in messagedetailsfor extensions/UI. - A
jsoncapture is parsed when it contains valid JSON no larger than 32 KiB. - Completion waits for the child process
closeevent so unterminated final output can still satisfy the contract. - Stopping a process group sends
SIGTERM, then sendsSIGKILLafter a one-second grace period even if the shell child has already closed. The escalation timer keeps the session alive through that grace period, so descendants that ignoreSIGTERMcannot outlive the monitor during shutdown. - Non-persistent monitors time out after five minutes by default, with a maximum
of one hour.
persistent=truedisables the timeout. - All active monitors are stopped on session shutdown.
Consult /skill:using-monitor for the agent-facing usage procedure.