Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Fake-agent unit tests are necessary but not sufficient. Any change to how agents

A throwaway harness for this should live in the repo root (not `/tmp`, whose symlink breaks relative imports), import from `./src`, and be deleted before commit — don't commit harnesses.

Child-session persistence changes must keep the default off and test the private storage path, missing/corrupt-session fallback, durable turn-boundary continuation, and paused-worktree cleanup. Tests must use an isolated fake home and never write transcripts into the developer's normal Pi session index.

## Style

Formatting and linting are handled by Biome (`npm run format`, `npm run lint`). Match the existing code; don't reformat files you aren't otherwise changing.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ return await agent(

- **Real parallel orchestration** — fan out up to 16 concurrent and 1000 total subagents from one orchestration script.
- **Per-agent model routing** — use `small`, `medium`, or `big` tiers, or choose an exact provider/model and thinking level.
- **Journaled resume** — replay completed agents after interruption without rerunning them or spending their tokens again. The orchestrator can also resume with an **edited script** (`resumeFromRunId`): unchanged `agent()` calls replay from cache and only edited/new ones re-run — so a single bad prompt no longer means paying to re-run the whole workflow.
- **Journaled resume** — replay completed agents without rerunning or repaying them, resume edited scripts from the unchanged prefix, and optionally continue interrupted child sessions from their last durable turn boundary.
- **Git worktree isolation** — let parallel agents edit safely on throwaway branches with `isolation: "worktree"`.
- **Measured usage** — report real tokens and cost from each subagent session; add run, phase, or agent budgets only when you want them.
- **Visible background runs** — track phases, agents, models, fresh/cache tokens, cost, and live tok/s from the progress panel or `/workflows` navigator.
Expand Down Expand Up @@ -107,7 +107,9 @@ return await agent(

For an always-on exhaustive mode, use `/ultracode`; `/effort high` is the lighter standing option.

## Commands
## Commands and run control

Pi can manage background runs directly with the `workflow_control` tool instead of asking you to type a command. It supports `list`, `status`, `pause`, `resume`, `stop`, `restart`, and `remove`; run-specific actions use the canonical run ID returned when the workflow starts. Status output includes the run state, current phase, agent counts, active labels, and recorded token total. `remove` accepts only terminal runs, so stop running or paused work first.

| Command | Purpose |
| --- | --- |
Expand Down Expand Up @@ -182,7 +184,11 @@ Extension state lives outside the repository under `~/.pi/workflows`:
- project runs, journals, locks, and saved overrides: `~/.pi/workflows/projects/<project>/`
- older project-local `.pi/workflows/runs` and `.pi/workflows/saved` remain readable as fallbacks

Subagents are in-memory by default. Set `persistAgentSessions: true` to retain full transcripts in Pi's standard session directory. This creates one file per agent and may store sensitive material that an agent read, so enable it deliberately.
Subagents are in-memory by default. Set `persistAgentSessions: true` in `~/.pi/workflows/settings.json` (or a project override) to opt in to durable child transcripts. They are stored under the project's private workflow state directory (`~/.pi/workflows/projects/<project>/agent-sessions/`), outside Pi's normal `/resume` picker. This creates one file per agent and may store secrets or other sensitive material that an agent read, so enable it deliberately.

Run files use a versioned, backward-compatible state model with stable execution IDs, exact terminal usage, and crash-safe temp/rename writes plus backup recovery. After a crash, orphaned running work is recovered as paused and waits for an explicit resume. Resume replays the longest unchanged completed prefix—including nested workflows—without double-charging completed usage. With child persistence enabled, an interrupted agent reopens its private transcript and compatible isolated worktree; otherwise it starts fresh. Missing, corrupt, or unwritable child sessions also fall back to a fresh session and are reported in run logs.

Continuation begins at the last durable Pi message/tool-result boundary. Provider streams cannot resume mid-token, and a tool interrupted before its result was durably recorded may have uncertain side effects; the continuation prompt tells the agent to inspect existing state before acting.

Completed background runs persist their full result in the project run JSON. The conversation delivery includes a pointer to that file when the visible summary is shortened.

Expand Down
9 changes: 6 additions & 3 deletions extensions/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import {
createEffortState,
createWorkflowControlTool,
createWorkflowStorage,
createWorkflowTool,
installResultDelivery,
Expand Down Expand Up @@ -33,7 +34,9 @@ export default function extension(pi: ExtensionAPI) {
});

const workflowTool = createWorkflowTool({ cwd, manager, storage });
const workflowControlTool = createWorkflowControlTool({ manager });
pi.registerTool(workflowTool);
pi.registerTool(workflowControlTool);
// Auto-resume runs that paused on a provider usage limit once the quota is
// likely refilled. Standalone: only consumes the manager's public surface, so
// it stays decoupled from manager/persistence internals. Its constructor also
Expand Down Expand Up @@ -68,9 +71,9 @@ export default function extension(pi: ExtensionAPI) {
// advertise the shared registry's models.
manager.setModelRegistry(ctx.modelRegistry);
const active = pi.getActiveTools();
if (!active.includes(workflowTool.name)) {
pi.setActiveTools([...active, workflowTool.name]);
}
const workflowTools = [workflowTool.name, workflowControlTool.name];
const missing = workflowTools.filter((name) => !active.includes(name));
if (missing.length) pi.setActiveTools([...active, ...missing]);
// Scope the /workflows history to this session: runs persist on disk across
// sessions, but the navigator/task panel show only the current session's runs.
// Switching back to a previous session re-shows that session's runs.
Expand Down
Loading