pi-background-tasks
Pi extension for durable background shell tasks, read-only delegated agents, local attested Pi runs, and fixed-purpose Fusion workflows through child Pi processes.
Package details
Install pi-background-tasks from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-background-tasks- Package
pi-background-tasks- Version
2.6.2- Published
- Sep 21, 2026
- Downloads
- 101.2K/mo · 26.7K/wk
- Author
- ismailsaleekh
- License
- ISC
- Types
- extension
- Size
- 5.5 MB
- Dependencies
- 1 dependency · 4 peers
Pi manifest JSON
{
"image": "https://raw.githubusercontent.com/ismailsaleekh/pi-background-tasks/main/logo.png",
"extensions": [
"./dist/extensions/anthropic-attribution.js",
"./dist/extensions/background-tasks.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-background-tasks
Keep Pi moving while long jobs, delegated investigations, and fixed-purpose multi-model Fusion work run in the background.
pi-background-tasks adds background jobs, delegated agents, and multi-model Fusion for Pi:
- Run long work without blocking: start named shell jobs, keep talking to Pi, and get durable completion notifications when they finish.
- Delegate context-aware investigation: launch one route-pinned, inspect-only child Pi agent seeded with a frozen projection of the current conversation, then retrieve a hash-verified result.
- Combine model perspectives through fixed-purpose Fusion: run three candidate children, blind evaluation, optional bounded evaluator repair, and merger for reasoning, investigation, targeted URL research, or validation review.
- Keep Anthropic subscription traffic attributed and compatible: by default, apply the package-owned Claude Code OAuth attribution, cache policy, and exact-match prompt sanitization to parent Anthropic routes without an external sanitizer dependency; isolated package children retain mandatory attribution even when ambient parent attribution is disabled.
| Fact | Value |
|---|---|
| Package | pi-background-tasks |
| Version | 2.6.2 |
| Node engine | >=22.19.0 |
| Pi entrypoints | ./dist/extensions/anthropic-attribution.js, ./dist/extensions/background-tasks.js |
| Package image | logo.png |
| Surface kind | Configured variants | Available by default |
|---|---|---|
| command | 11 | 11 |
| tool | 11 | 11 |
| shortcut | 3 | 2 |
| renderer | 2 | 2 |
| eventbus | 1 | 1 |
| workflow | 4 | 4 |
Public commands: /bg, /bg-clear, /bg-tasks, /bg-update, /claude-cache, /fusion, /fusion-models, /jobs, /kill, /logs, /tasks.
Public tools: bg_delegate, bg_kill, bg_logs, bg_result, bg_run, bg_run_pi_attested, bg_status, fusion_investigate, fusion_reason, fusion_research, fusion_validate.
Configuration-dependent surfaces
| Surface | Availability | Default |
|---|---|---|
command:claude-cache |
feature:attribution |
yes |
command:fusion |
feature:fusion |
yes |
command:fusion-models |
feature:fusion |
yes |
tool:bg_delegate |
feature:delegate |
yes |
tool:bg_result |
any(feature:delegate,feature:fusion) |
yes |
tool:bg_run_pi_attested |
feature:attested |
yes |
tool:fusion_investigate |
feature:fusion |
yes |
tool:fusion_reason |
feature:fusion |
yes |
tool:fusion_research |
feature:fusion |
yes |
tool:fusion_validate |
feature:fusion |
yes |
shortcut:ctrl+alt+b |
dock:ctrl+alt+b |
no |
shortcut:shift+down |
dock:shift+down |
yes |
renderer:fusion-result |
feature:fusion |
yes |
workflow:investigate |
feature:fusion |
yes |
workflow:reason |
feature:fusion |
yes |
workflow:research |
feature:fusion |
yes |
workflow:validate |
feature:fusion |
yes |
Full owner map and generated contracts live in docs/INDEX.md.
“Available by default” means after Pi has initialized extensions. Normal TUI/RPC/print/JSON modes do this; SDK embedders must provide a counted bindExtensions() binding and ensure post-reload binding. Bare createAgentSession() and empty/mode-only reload are blocked by the current public host lifecycle API. See Getting started.
Why use it?
| You want to... | Use this package because... |
|---|---|
| Start a dev server, watch build, migration dry run, or long check | bg_run and /bg return immediately, write durable output files, show a footer dock, and notify on terminal state. Ordinary isAgent:false jobs can explicitly keep the same live execution across a real same-process reload. |
| Let Pi keep working instead of sleeping or polling | Default bg_run completion delivery sends a durable terminal notification and can wake a follow-up turn. |
| Ask a second agent to inspect the repo with the current conversation as context | bg_delegate starts one read/search/list child, isolated from ambient extensions by default; bg_result verifies the committed result before returning it. |
| Compare model perspectives without exposing arbitrary parent context | Fusion children receive only the workflow input and fixed tool policy; no silent route substitution or fallback is used on delegate/Fusion paths. |
| Produce local evidence for a direct Pi run | bg_run_pi_attested records local same-user-writable artifacts and hashes after a successful structured child Pi task. |
| Use Anthropic subscription OAuth consistently | The default ambient provider applies attribution and exact-match sanitization; /claude-cache shows or changes session cache retention. Isolated package-owned Anthropic children always use the mandatory child entrypoint. |
Install
Version information comes from package.json. Use npm @latest for normal installs; use git main only when you intentionally want the current repository state.
# Global install from npm
pi install npm:pi-background-tasks@latest
# Project-local install from npm
pi install npm:pi-background-tasks@latest -l
# Git main branch; not a release tag
pi install git:github.com/ismailsaleekh/pi-background-tasks@main
# Project-local git main install
pi install git:github.com/ismailsaleekh/pi-background-tasks@main -l
# Local checkout/package path, run from this package directory
pi install .
pi install . -l
Local paths are loaded from disk without copying; use the path to this package from your current directory.
Quick start: useful in under five minutes
Install and start Pi in a project.
Launch a background command:
/bg --name "Typecheck watch" npm run typecheck -- --watch/bgstarts a tracked shell task and returns the task id plus output path. User-launched/bgtasks notify in the UI but do not automatically wake a follow-up model turn. Add one leading--survive-reloadonly when this ordinary shell process must keep running across a real same-process/reload; default tasks are still killed.Open the footer dock with the default Shift↓ binding or list tasks:
/jobsRead bounded output only when you need it:
/logs b12ab34c 20000Let a child agent inspect while you continue:
{"name":"Config reader","prompt":"Inspect the repository configuration files and report where background task settings are documented. Include file paths and quote only the relevant lines.","capability":"inspect"}Call this with
bg_delegate. When its terminal notification arrives, retrieve the answer deliberately:{"taskId":"<task id from bg_delegate>","delivery":"inline"}Call this with
bg_result. Retrieval is hash-verified and never silently truncated.For a self-contained synthesis, start Fusion in the background:
{"prompt":"Compare the tradeoffs between a watcher, a one-shot build, and a delegated repo inspection for a large refactor."}Call this with
fusion_reason, or use/fusion <prompt>interactively. The launch returns after durable preflight; wait for its terminal notification, then retrieve the verified result withbg_result.
More walkthrough detail: Getting started.
Select capabilities and avoid shortcut conflicts
The default remains the complete historical surface. To run only process tasks, set:
PI_BG_FEATURES=process pi
PI_BG_FEATURES accepts a strict unique comma-separated set from process,delegate,fusion,attested,attribution; process is mandatory. bg_result is derived and appears exactly once when delegate or Fusion is enabled. Disabled tools, commands, renderers, and ambient attribution are absent from registration and remain absent after reload.
Choose the dock key independently:
PI_BG_DOCK_SHORTCUT=ctrl+alt+b pi # avoid a Shift+Down owner
PI_BG_DOCK_SHORTCUT=off pi # use /tasks or /bg-tasks
Accepted values are exactly shift+down (default), ctrl+alt+b, and off. Invalid settings fail startup with pi_bg_config_invalid; they do not silently restore defaults. /tasks, /bg-tasks, and the separate Ctrl+Alt+C clear fallback remain available. These flags select functionality; they do not claim a cold-start performance improvement.
Full contract: Configuration and Shortcuts and dock.
Pick the right workflow
| Workflow | Blocking? | Context | Tools/network/write boundary | Best for | Expected behavior |
|---|---|---|---|---|---|
| Ordinary foreground Pi work | Yes | Full current session | Whatever tools the active session has | Short reads/edits/commands where you want live back-and-forth | Pi waits for the work before responding. |
/bg |
No | No model child unless your command starts one | Runs your shell command; not sandboxed | User-started local commands, servers, watches | UI notification and footer tracking; /bg uses notification-only by default. Optional --survive-reload is ordinary-shell-only. |
bg_run |
No | No model child unless command starts one | Runs your shell command; not sandboxed | Agent-started long commands | Returns task id/output path; defaults to notification plus automatic follow-up wake. Optional surviveReload:true requires isAgent:false. For an Anthropic child pi, do not pass --no-extensions unless you also explicitly load this package's attribution extension. |
bg_delegate + bg_result |
No launch; retrieval is point-in-time | Frozen visible conversation projection | Inspect-only child: read, grep, find, ls, artifact read; no shell, writes, network, recursion | Context-aware read-only investigation while parent continues | Launch returns immediately; result is committed by child and hash-verified by retrieval. |
bg_run_pi_attested |
No | Prompt passed to one direct child Pi run | Direct pi --mode json; no shell command; writes requested report path |
Evidence-oriented direct Pi task | Emits local attestation sidecar only after successful completion. |
/fusion / fusion_reason |
Background launch; point-in-time bg_result retrieval |
Versioned conversation projection plus prompt | Candidates/evaluator/repair/merger run with no tools | Self-contained reasoning and synthesis | Returns after durable preflight; three candidates → blind evaluator → optional bounded repair → merger. |
fusion_investigate |
Background launch; point-in-time bg_result retrieval |
Clean task input only | Candidate read-only repo tools; evaluator/repair/merger no tools | Independent repo investigation | Restate needed facts; continue only independent work while the live repository is inspected. |
fusion_research |
Background launch; point-in-time bg_result retrieval |
Clean task input only | Candidate read-only repo tools plus targeted fetch of caller-supplied public URLs only | URL-backed synthesis | Targeted URL retrieval, not web search. |
fusion_validate |
Background launch; point-in-time bg_result retrieval |
Clean task input only | Advisory read-only validation review | Second-opinion review of completed work | Do not mutate the reviewed scope while it runs; not a substitute for mechanical gates. |
See Choose a workflow for a decision tree and tradeoffs.
Copy-paste examples
bg_run: start long shell work
{
"name": "Docs preview",
"command": "npm run docs:dev",
"isAgent": false,
"timeoutSeconds": 3600,
"surviveReload": true
}
Expected: returns immediately with a task id, PID when available, and .pi/tasks/...output. Here the explicit flag retains that exact child/id/PID/nonce/path, launch policy, absolute timeout, and cumulative cap across a supported real reload. Omit it for compatible kill-on-reload behavior. New/resume/fork/clone/quit, hard crash, process restart, empty/mode-only SDK reload, and direct AgentSession.dispose() are not supported survival paths. The command runs as an ordinary local shell command with your user permissions; it can invoke networked tools or paid services if the command itself does so.
If bg_run starts an Anthropic child pi, keep normal extension discovery enabled when ambient attribution is enabled. Do not add --no-extensions unless the command also supplies this package's always-on extensions/anthropic-attribution-child.ts via -e/--extension; bg_run does not rewrite arbitrary shell argv.
bg_delegate: context-seeded read-only investigation
{
"name": "Route audit",
"prompt": "Inspect the package source and identify where delegate route pinning is enforced. Return file paths, function names, and a short explanation. If a fact exists only in omitted parent tool output, say it is unavailable rather than guessing.",
"capability": "inspect",
"extensionMode": "isolated",
"autoDeliver": "never"
}
Then retrieve:
{
"taskId": "<delegate task id>",
"delivery": "inline"
}
Expected: bg_delegate returns a launch receipt immediately. bg_result returns a typed not-ready result while running; after commit it verifies package identity, seed hash, route, block hashes, and aggregate hash before returning bytes. Oversized answers become explicit artifact references, not truncated inline text.
extensionMode defaults to "isolated", which disables ambient extension discovery. If the pinned provider exists only because a user/project Pi extension registers it, opt into "ambient". Ambient mode still loads the delegate guard and keeps the inspect tool allowlist plus skill/template/theme/context restrictions, but it executes arbitrary discovered extension code. Tool allowlists do not sandbox that code, so ambient mode weakens inspect-only process isolation. The call never accepts extension paths and never substitutes the pinned route.
bg_run_pi_attested: local evidence for one Pi child
{
"name": "Migration report",
"provider": "openai-codex",
"model": "gpt-5.5",
"prompt": "Inspect the repository and write a concise migration report to reports/migration.md.",
"reportPath": "reports/migration.md",
"timeoutSeconds": 1800
}
Expected: launches exactly one direct pi --mode json child using structured provider/model fields. It rejects direct API-key/auth-file launch arguments and only writes the attestation sidecar after successful completion and durable hashes. The attestation is local evidence, not cryptographic proof against a compromised machine or provider.
Fusion tools
{"prompt":"Design a rollback strategy for a risky database migration. Include assumptions and failure modes."}
Use with fusion_reason for self-contained synthesis.
{
"objective": "Find how background task output is capped and surfaced.",
"background": ["We are evaluating pi-background-tasks behavior for long-running commands."],
"deliverable": "File paths, constants, defaults, and user-visible behavior.",
"scope": ["src"],
"constraints": ["Read-only inspection only."]
}
Use with fusion_investigate.
{
"objective": "Summarize the installation syntax Pi documents for packages.",
"background": ["We need package README install examples to match Pi package docs."],
"deliverable": "A short summary with caveats.",
"sources": [
{"url":"https://github.com/earendil-works/pi-coding-agent","purpose":"Pi package documentation repository"}
]
}
Use with fusion_research. Only declared public http(s) URLs may be fetched; this is not a search tool.
{
"objective": "Review whether a documentation-only change is ready to ship.",
"background": ["The change edits README and package-local docs only."],
"changeSummary": "Replaced monolithic README with landing page and moved operational details into docs.",
"scope": ["README.md", "docs/getting-started.md", "docs/choose-a-workflow.md"],
"acceptanceCriteria": ["Install commands are accurate", "Safety limitations are explicit", "Examples match public schemas"],
"verification": {
"status": "provided",
"evidence": [{"check":"Focused link check", "outcome":"All local README links resolve"}]
}
}
Use with fusion_validate for advisory read-only review.
Footer dock
When tasks are running or unseen completions exist, the footer shows a compact bg ... segment. Press the configured Shift↓ (default) or Ctrl+Alt+B binding to open the focused bottom dock, or use /tasks when the key is off. Use /bg-clear to acknowledge finished-task footer notices in any terminal.
| Control | Action |
|---|---|
configured Shift↓ / Ctrl+Alt+B, or /tasks |
Open the dock |
/bg-clear |
Clear finished-task notices |
↑ / ↓, PageUp / PageDown |
Move through list or scroll output tail |
Enter / → |
Inspect details |
← |
Return to list |
k |
Stop selected running task |
R |
Rerun selected command |
c |
Show copyable output path |
x / Esc / q |
Close dock |
Agent tasks launched through pi -p ... or pi --mode json ... and marked isAgent:true can show task-owned model/context/token/tool telemetry. Missing child telemetry is shown as unavailable, not synthesized as zero.
Architecture, trust, and safety
- Runtime task files live under
.pi/tasks/<session-id>-<pid>/; Fusion artifacts under.pi/fusion/...; delegate artifacts under.pi/delegate/.... - Delegate launch budgeting uses backed route-family calibration for eligible large prompts and records a provable conservative counter-forecast across every byte class. During investigation, text and image-bearing tool output spill losslessly when retaining them would consume protected final-answer runway—even below the normal 64 KiB per-result threshold. Exact artifact ranges return as base64, final capture excludes intermediate tool-use narration, and near the runway boundary tools are disabled for graceful finalization. Runtime token estimates are advisory; Pi/provider own live context admission, avoiding Fusion BUG-185-style false refusals.
- Shell jobs are tracked by the package, but they are not sandboxed. Treat commands as local processes with your permissions and credentials.
- Delegate and Fusion child Pi processes are route-pinned where applicable; delegate/Fusion paths do not silently substitute routes.
- Fusion uses direct child
pi --mode textprocesses, not direct completion APIs. Frontier Fusion routes are admitted only through Pi Anthropic or Codex subscription OAuth; metered frontier API credentials are rejected before child creation. - Normal installations load a feature-aware ambient Claude Code OAuth attribution/sanitization entrypoint for parent Anthropic sessions; non-Anthropic sessions are unchanged. The default enables it, while omitting
attributionremoves its provider/hooks and/claude-cache. Isolated Fusion, delegate, and attested Anthropic children load the separate always-on child entrypoint explicitly before their guard/governor, regardless of that ambient flag. It requeststtl: "1h"on system/tool/conversation cache breakpoints before serialization and preserves provider-reportedcacheWrite1hevidence. SetPI_CACHE_RETENTION=short|none|longor use/claude-cachewhen ambient attribution is enabled; malformed attribution, policy, cache evidence, or non-OAuth credentials fail before transport. Provider usage is preserved verbatim, but subscription OAuth can reportcacheWrite1h = 0even when a unique cache remains readable beyond five minutes; treat positivecacheWrite1has definitive and zero as inconclusive on that channel. Anthropic budgeting follows the provider's 200K subscription policy. - Fusion research fetches only caller-supplied public
http(s)URLs with bounded retrieval. It is not web search and not a secret-exfiltration boundary. - Attestation sidecars are local, unsigned, same-user-writable evidence. They are useful for downstream local gates, but not cryptographic proof against local compromise, a compromised Pi binary, or a compromised provider.
- Metadata, attestations, delegate/Fusion artifacts, and configuration replacements use write/fsync/rename durability patterns. Failed/cancelled stored Fusion runs also have a manifest-bound
failure-summary.jsoncontaining bounded no-answer evidence metadata and artifact refs only;bg_resultreturns it as an answer-free typed terminal view after integrity checks. Ordinary task output is closed and drained before terminal publication but is not explicitly fsynced. POSIX directory entries are fsynced after atomic replacement; Windows lacks the same portable directory-entry crash-durability guarantee.
Detailed operations: Configuration.
EventBus and Autopilot integration
Other Pi extensions can control the same BackgroundTaskRegistry through Pi's events bus instead of shelling out or maintaining a second task manager. The public channels are:
| Purpose | Channel |
|---|---|
| Request | pi-background-tasks:request:v1 |
| Response | pi-background-tasks:response:v1 |
| Terminal task event | pi-background-tasks:terminal:v1 |
Operations are capabilities, run, status, logs, and kill. This is the integration point for orchestrators such as Autopilot that need non-blocking package-managed work with bounded logs and correlated terminal events. Consumers must deduplicate terminal frames by task.id: an EventBus listener failure can cause a retried publication.
Documentation map
| Need | Read |
|---|---|
| First install and first task | Getting started |
| Which workflow/tool to choose | Choose a workflow |
| Environment variables, shells, output caps, model config, offline behavior | Configuration |
| Package QA expectations | TESTING.md and TEST_PLAN.md |
| Publishing notes | PUBLISHING.md |
| License and derived-rule notice | LICENSE and THIRD_PARTY_NOTICES.md |
Contributing
Keep user-facing claims tied to source. If you change public schemas, command behavior, durability, model routing, or environment variables, update these package-local docs in the same change and run focused checks appropriate to the edit.
For startup work, use scripts/benchmark-cold-load.mjs with an owned output/scratch root, explicit --runtime source|compiled, and at least 30 fresh-process samples; the exact command and interpretation rules are in Testing operations. Its “cold” result means an empty JavaScript/Jiti module cache, not a flushed filesystem cache. It is distribution evidence, not a flaky CI threshold. Published Pi entrypoints use precompiled JavaScript; disabled delegate/Fusion/attribution lanes, the dock UI, and attested execution stay outside process-only static startup. Load those entrypoints through Pi; dist/src/** contains private implementation chunks and is not a set of standalone Node entrypoints. Native-Windows and vendor compiled-Bun timing still require their own evidence.
