# @agimon-ai/doompi-autostop

Shuts a [DoomPi](https://www.npmjs.com/package/@agimon-ai/doompi) session down once the agent
settles and stays idle.

A scripted run wants the session to exit on its own when the work is done. Waiting for
`agent_settled` alone is not enough: the agent can settle and immediately pick up a queued
message, and it can settle while the last response is still streaming. So this package settles,
waits, looks again, and only then stops.

## The policy

| Moment             | Session state                     | Outcome              |
| ------------------ | --------------------------------- | -------------------- |
| `agent_settled`    | messages queued                   | stand down           |
| `agent_settled`    | queue empty                       | look again in 5s     |
| the scheduled look | messages queued                   | stand down           |
| the scheduled look | background runner or agent active | look again in 5s     |
| the scheduled look | still streaming                   | look again in 100ms  |
| the scheduled look | idle, queue and background empty  | `context.shutdown()` |

Any `input` or `agent_start` event disarms a pending stop. The cooldown is the grace period;
the 100 ms recheck waits out a stream that has not finished draining. Only two kinds of
background work keep a settled session alive: supervised Doom Runner processes (`doom-runner`)
while they are still running (a runner listed as `completed` or `failed` no longer counts)
and running subagents (`team-direct-runs`, `doom-task`) owned by the current session, including
provider errors from them. Workflow runs (`workflow-mcp`) never hold a session open: a workflow
step does not launch another workflow, so a run the session started is not a reason to stay.

Each wait is recorded as `doom_autostop.waiting_on_background_work` telemetry naming the work
holding the session, along with `doom_autostop.stood_down` and `doom_autostop.shutdown_requested`.

`decideOnSettled` and `decideOnRecheck` handle the plain Pi session state. The idle shutdown
watch adds the authoritative background-work gate before the policy may stop the session.

## What it registers

| Entry             | Surface                                                                               |
| ----------------- | ------------------------------------------------------------------------------------- |
| `./extensions/pi` | `input`, `agent_start` and `agent_settled` hooks, plus the shutdown that disarms them |

The extension owns a Cordis fiber; `session_shutdown` disposes it, which cancels any armed stop.
That matters because Pi reloads extensions in process. A timer left armed by the previous load
would stop the session it was reloaded into.

## Installation

DoomPi depends on this package and activates it when a run asks for `--auto-stop`. It is not
selectable from `.doom/modes.yaml`.

## License

MIT
