{"_id":"@aeondave/opencode-background-agents","_rev":"2-d6a48e978ed81ce9841b95f6f00708b7","name":"@aeondave/opencode-background-agents","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@aeondave/opencode-background-agents","version":"0.1.0","keywords":["opencode","opencode-plugin","agents","subagents","delegation","background-agents"],"license":"MIT","_id":"@aeondave/opencode-background-agents@0.1.0","maintainers":[{"name":"aeondave","email":"nova.davide@gmail.com"}],"homepage":"https://github.com/AeonDave/opencode-background-agents#readme","bugs":{"url":"https://github.com/AeonDave/opencode-background-agents/issues"},"dist":{"shasum":"92a6bb465dffeef8a9e893df219ce04aeb2ff3d3","tarball":"https://registry.npmjs.org/@aeondave/opencode-background-agents/-/opencode-background-agents-0.1.0.tgz","fileCount":19,"integrity":"sha512-4kGPc8j4D1wTry04R8LxZVBVKzg5BXJql7MdiqRK2gzz5vMGXdoHyq4lzaQWbejh5jrsFI2QYFR24uyMFvdToA==","signatures":[{"sig":"MEYCIQDeRWeUsMkseft+k+8zoP8Qrj1ejimfqT8aaxTKEoHRvAIhAM3uqoK960aR4Y7kHMzvN1I5JV9S5/WwfzVMzIBfvHtN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":145083},"main":"src/plugin/background-agents.ts","type":"module","exports":{".":"./src/plugin/background-agents.ts"},"gitHead":"01d7ddf627a5352b43d1acfa545168e8b4f0ee71","scripts":{"test":"bun test","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aeondave","email":"nova.davide@gmail.com"},"repository":{"url":"git+https://github.com/AeonDave/opencode-background-agents.git","type":"git"},"_npmVersion":"11.17.0","description":"Async, supervised background agent delegation for OpenCode - delegate, steer, stop, and persist sub-agent work.","directories":{},"_nodeVersion":"26.3.0","dependencies":{"unique-names-generator":"^4.7.1"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","fast-check":"^4.8.0","typescript":"latest","@opencode-ai/sdk":"^1.17.4","@opencode-ai/plugin":"^1.17.4"},"peerDependencies":{"@opencode-ai/sdk":"*","@opencode-ai/plugin":"*"},"peerDependenciesMeta":{"@opencode-ai/sdk":{"optional":true},"@opencode-ai/plugin":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/opencode-background-agents_0.1.0_1781272165956_0.9404087446711769","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aeondave/opencode-background-agents","version":"0.1.1","description":"Async, supervised background agent delegation for OpenCode - delegate, steer, stop, and persist sub-agent work.","keywords":["opencode","opencode-plugin","agents","subagents","delegation","background-agents"],"homepage":"https://github.com/AeonDave/opencode-background-agents#readme","bugs":{"url":"https://github.com/AeonDave/opencode-background-agents/issues"},"repository":{"type":"git","url":"git+https://github.com/AeonDave/opencode-background-agents.git"},"license":"MIT","type":"module","main":"src/plugin/background-agents.ts","exports":{".":"./src/plugin/background-agents.ts"},"scripts":{"typecheck":"tsc --noEmit","test":"bun test"},"dependencies":{"unique-names-generator":"^4.7.1"},"peerDependencies":{"@opencode-ai/plugin":"*","@opencode-ai/sdk":"*"},"peerDependenciesMeta":{"@opencode-ai/plugin":{"optional":true},"@opencode-ai/sdk":{"optional":true}},"devDependencies":{"@opencode-ai/plugin":"^1.17.4","@opencode-ai/sdk":"^1.17.4","@types/bun":"latest","fast-check":"^4.8.0","typescript":"latest"},"gitHead":"692161cdfa8a3038bcc31a9fff6b92b7a714df12","_id":"@aeondave/opencode-background-agents@0.1.1","_nodeVersion":"26.3.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-qsWuutnkgZ1y4+DQxkxaHb1uh0ie94yZfTqeHv7maaxglXki467Vv8PCdfX8sXJtzVOEkc8/pemDtEm0xfpJOA==","shasum":"b34d211efc920994ac594a4f50148b5aa40793e1","tarball":"https://registry.npmjs.org/@aeondave/opencode-background-agents/-/opencode-background-agents-0.1.1.tgz","fileCount":19,"unpackedSize":149377,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDf+iQDHNf8NXgeW/Mq4ZVdW1irKnKxoXUO3O9qUcU/+AiBOsKk3A4uggNeOxQ9ttIbJgeaC9MVPjd7IfaM1yiNBOQ=="}]},"_npmUser":{"name":"aeondave","email":"nova.davide@gmail.com"},"directories":{},"maintainers":[{"name":"aeondave","email":"nova.davide@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/opencode-background-agents_0.1.1_1781702531987_0.4407074333540739"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-12T13:49:25.766Z","modified":"2026-06-17T13:22:12.266Z","0.1.0":"2026-06-12T13:49:26.085Z","0.1.1":"2026-06-17T13:22:12.167Z"},"bugs":{"url":"https://github.com/AeonDave/opencode-background-agents/issues"},"license":"MIT","homepage":"https://github.com/AeonDave/opencode-background-agents#readme","keywords":["opencode","opencode-plugin","agents","subagents","delegation","background-agents"],"repository":{"type":"git","url":"git+https://github.com/AeonDave/opencode-background-agents.git"},"description":"Async, supervised background agent delegation for OpenCode - delegate, steer, stop, and persist sub-agent work.","maintainers":[{"name":"aeondave","email":"nova.davide@gmail.com"}],"readme":"# opencode-background-agents\n\nAsync background delegation for [OpenCode](https://github.com/sst/opencode) — fire off tasks, keep working, steer or stop mid-run, and retrieve persisted results after compaction or restart.\n\n## Contents\n\n- [Why use it](#why-use-it)\n- [How it works](#how-it-works)\n- [Tools](#tools)\n- [Interactive control](#interactive-control)\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [Best practices](#best-practices)\n- [Monitoring](#monitoring)\n- [Lifecycle and reliability](#lifecycle-and-reliability)\n- [Development](#development)\n- [FAQ](#faq)\n- [Credits](#credits)\n- [Disclaimer](#disclaimer)\n- [License](#license)\n\n## Why use it\n\nContext windows fill up. When compaction kicks in, past research vanishes and the AI re-does work it already did. This plugin addresses that by:\n\n- **Keeping you unblocked.** Delegate a task and continue the conversation immediately; no waiting for a sub-agent to finish.\n- **Surviving compaction.** Results are written to disk as markdown. After compaction, the AI retrieves them by ID rather than re-running the task.\n- **Giving mid-run control.** Check status, inject instructions, or abort a delegation while it runs — not just fire-and-forget.\n- **Sizing resources per task.** Timeout and model are set at delegation time: a short window and a cheap model for quick lookups; a long window and a strong model for deep research or builds.\n- **Allowing write-capable agents.** Write- and bash-capable sub-agents can run in the background too, not only read-only ones (toggleable via env var).\n\n## How it works\n\n```\n1. Delegate   →  \"Research OAuth2 PKCE best practices\"\n2. Continue   →  Keep coding, brainstorming, reviewing\n3. Supervise  →  status / steer / stop while it runs (optional)\n4. Notified   →  <task-notification> arrives on terminal state\n5. Retrieve   →  delegation_read(id) returns the full result\n```\n\nEach delegation runs in its own isolated OpenCode session and is auto-tagged with a title and summary on completion. Results are persisted to `~/.local/share/opencode/delegations/<project>/` as markdown, so the AI can locate and retrieve past work even after compaction, restarts, or crashes.\n\n## Tools\n\n| Tool | Purpose |\n|------|---------|\n| `delegate(prompt, agent, timeout_minutes?, model?)` | Launch a background task; returns a readable ID immediately. The supervisor can size the timeout and pick the model per task. |\n| `delegation_read(id)` | Retrieve the full persisted result of a delegation. |\n| `delegation_list()` | List all delegations with titles, summaries, and read state. |\n| `delegation_status()` | Live status of active delegations (elapsed, tool calls, heartbeat, steer count) — instant, never polls. |\n| `delegation_peek(id)` | Live transcript digest of a running delegation — read intermediate work to decide whether to steer or stop. |\n| `delegation_steer(id, message)` | Inject an extra instruction into a running delegation. |\n| `delegation_stop(id)` | Abort a running delegation and keep its partial output. |\n\n## Interactive control\n\n`status`, `peek`, `steer`, and `stop` give mid-run supervisor control without blocking the main conversation.\n\n- **Status** is read from memory and instant. Use it to notice that a delegation needs attention.\n- **Peek** reads the live transcript of a running delegation — assistant text, tool activity, steers sent so far — without affecting it. Use it to gather evidence before deciding whether to steer or stop.\n- **Steer** uses OpenCode's native server-side steering (`delivery: \"steer\"`, OpenCode >= 1.17): the instruction is injected into the agent's current run, even while the session is mid-step. On older servers the plugin falls back to a direct v1 prompt; if the session is busy and rejects it, the tool reports the failure so the supervisor can retry or stop. A delivered steer extends the run and resets the timeout window.\n- **Stop** aborts the session cleanly. Partial output is saved and readable via `delegation_read(id)`, marked `[STOPPED BY SUPERVISOR]`.\n\nCompletion is delivered via `<task-notification>` — there is no need to poll.\n\nNotifications are split by audience: the model receives the `<task-notification>` XML as a hidden synthetic part (the TUI does not render it), while the human gets a TUI toast. The chat stays clean and the supervisor still receives full machine-readable context.\n\n## Installation\n\n### From npm\n\nAdd the package to the `plugin` array in your OpenCode config at `~/.config/opencode/opencode.json`:\n\n```jsonc\n{\n  \"plugin\": [\"@aeondave/opencode-background-agents@latest\"]\n}\n```\n\nOpenCode installs the plugin and its dependencies automatically on the next start. To pin a version, replace `@latest` with a specific version (e.g. `@0.1.0`).\n\n### From source (git clone)\n\nRun from a local checkout — useful before publishing or while hacking on the plugin.\n\n1. Clone the repository and install dependencies:\n\n   ```bash\n   git clone https://github.com/AeonDave/opencode-background-agents.git\n   cd opencode-background-agents\n   npm install\n   ```\n\n2. Create a shim file in your global plugin directory that re-exports the checkout's entry point. The directory is `plugin` (singular):\n\n   - Path: `~/.config/opencode/plugin/background-agents.ts`\n   - Content — a single line pointing at the absolute path of the cloned entry point:\n\n   ```ts\n   export { default } from \"/absolute/path/to/opencode-background-agents/src/plugin/background-agents.ts\"\n   ```\n\n   On Windows, use forward slashes and include the drive letter:\n\n   ```ts\n   export { default } from \"C:/opencode-background-agents/src/plugin/background-agents.ts\"\n   ```\n\n3. Restart OpenCode. The plugin loads from your working tree, so edits to `src/` take effect on the next restart. Delete the shim file to uninstall.\n\n> Use one method at a time. If you add the npm entry, remove the local shim (and vice versa) to avoid loading the plugin twice.\n\n## Configuration\n\n| Environment variable | Default | Effect |\n|----------------------|---------|--------|\n| `BACKGROUND_AGENTS_STRICT_READONLY` | unset | When set to `1`, only read-only sub-agents may use `delegate`; write/bash-capable agents are rejected and told to use the native `task` tool. |\n| `BACKGROUND_AGENTS_TIMEOUT_MINUTES` | `15` | Default max runtime per delegation. `0` = no timeout. |\n\nBy default the read-only restriction is relaxed: write- and bash-capable sub-agents can run as background delegations, with a logged warning. Background sessions live outside OpenCode's undo/branching tree, so their file and bash side effects cannot be reverted through the UI. Enable strict mode if you want the original safe behavior.\n\n### Timeouts\n\nEach delegation gets its own timeout window (default 15 minutes). The supervisor sets it per task via `delegate(..., timeout_minutes)` — short for quick lookups, long for deep research or builds, or `0` for no timeout at all. Because the supervisor can steer or stop a delegation at any moment, an unbounded run is a legitimate choice, not a leak. A delivered steer re-opens a fresh window of the same size. `delegation_status()` shows remaining time (or `no timeout`) per task.\n\n## Best practices\n\n- **Size timeouts per task.** Use a short window for quick lookups and a long one for builds or deep research. Use `0` when you genuinely want the agent to run until done — you can always stop it.\n- **Size the model per task.** `delegate(..., model: \"provider/model-id\")` overrides the agent's configured model for that one delegation: a cheap, fast model for simple lookups, a strong one for deep work. Omitted, the agent's default applies. An invalid model fails the delegation with an error notification.\n- **Do not poll.** `delegation_status()` is instant and cheap. `<task-notification>` will arrive automatically on completion.\n- **Peek before steering.** Read the live transcript with `delegation_peek` to understand what the agent is doing before sending a correction. Steering without evidence often misdirects rather than corrects.\n- **Read results via `delegation_read`.** Do not try to reconstruct output from status or peek; the full persisted markdown is always available once the delegation reaches a terminal state.\n- **Enable strict read-only mode when undo safety matters.** If you need to guarantee that background work does not touch the filesystem outside OpenCode's undo tree, set `BACKGROUND_AGENTS_STRICT_READONLY=1`.\n\n## Monitoring\n\nBesides `delegation_status()`, you can navigate sub-agent sessions directly in the TUI:\n\n| Shortcut | Action |\n|----------|--------|\n| `Ctrl+X Up` | Jump to parent session |\n| `Ctrl+X Left` | Previous sub-agent |\n| `Ctrl+X Right` | Next sub-agent |\n\nNavigating into a running child session is read-only. Use `delegation_steer` to actually send instructions to it.\n\n## Lifecycle and reliability\n\n- Stable delegation IDs are reused across state, artifact path, notifications, and retrieval.\n- Explicit lifecycle transitions: `registered` → `running` → terminal state.\n- Terminal-state protection: late progress events cannot regress a completed or stopped delegation.\n- Results are persisted before terminal notification delivery.\n- Compaction carries forward running and unread completed delegations with retrieval hints.\n- **Restart recovery.** Active delegations are mirrored to `<id>.state.json` beside their artifact. On plugin start, orphaned state files are re-adopted and reconciled against the server: sessions still running resume normally (steer, stop, status, and read all work again); settled sessions are finalized from their messages so the parent still receives its notification.\n\nThis is plugin-level lifecycle parity. It does not replicate OpenCode's internal task queue, notification-priority controls, or native undo/branching for write-capable background execution.\n\n## Development\n\n```bash\nnpm install        # install dev dependencies\nnpm run typecheck\nbun test           # unit + property-based (fast-check) test suite\n```\n\nThe test suite covers the full delegation lifecycle against a fake OpenCode client (async dispatch, completion notifications, native and fallback steering, stop, timeout vs unlimited runs, peek, crash-recovery restore), native-steer capability detection, and fuzzing of the state serializer and metadata fallback.\n\n## FAQ\n\n**How does the AI know what each delegation contains?**\nEach delegation is auto-tagged with a title and summary when it completes, so `delegation_list()` shows described entries rather than opaque IDs.\n\n**Does this persist after the session ends?**\nYes. Results are saved to disk and survive compaction, restarts, and crashes. Delegations that were still running when OpenCode exited are re-adopted on the next start and finalized normally.\n\n**Does this bloat my context?**\nThe opposite — heavy work runs in a separate session, and only the distilled result returns when you call `delegation_read()`.\n\n**Can write-capable agents run in the background?**\nYes, by default. Their changes live outside OpenCode's undo/branching tree and cannot be reverted via the UI. Set `BACKGROUND_AGENTS_STRICT_READONLY=1` to forbid this.\n\n**Can I use a different model for a specific delegation?**\nYes. Pass `model: \"provider/model-id\"` as the fourth argument to `delegate` (e.g. `anthropic/claude-haiku-4-5`). The override applies only to that delegation; other delegations keep their agent's configured model. An invalid format is rejected immediately by the tool; a nonexistent model fails the delegation with an error notification. The active model shows up in `delegation_status()` and `delegation_peek`.\n\n## Credits\n\nThe core concept — async fire-and-forget delegation with disk-persisted results — comes from [kdcokenny/opencode-background-agents](https://github.com/kdcokenny/opencode-background-agents). The underlying delegation engine is based on [oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode) by @code-yeongyu (MIT). This project extends both with interactive supervisor control and lifecycle reliability.\n\n## Disclaimer\n\nThis project is not built by the OpenCode team and is not affiliated with [OpenCode](https://github.com/sst/opencode).\n\n## License\n\nMIT\n","readmeFilename":"README.md"}