# pi-better-workflows

Deterministic multi-agent workflows for [Pi](https://pi.dev). GitHub: https://github.com/anishthite/better-workflows This package registers a `workflow` tool that runs JavaScript orchestration scripts with subagents, background execution, resumable journals, phases, structured output, and optional git worktree isolation.

It is intentionally close to Claude Code's `Workflow` tool semantics, with one Pi-specific safety improvement: if a workflow result is truncated inline, the tool description tells the assistant to read the persisted run journal before answering.

## Install

```bash
pi install npm:pi-better-workflows
```

For local development:

```bash
pi install /absolute/path/to/pi-better-workflows
```

The package manifest exposes `./extensions/workflow.ts` through the `pi.extensions` field, so Pi loads it as a normal package extension.

> Both this package and other workflow extensions may register a tool named `workflow`. Enable only one at a time.

## Quick start

Ask Pi to run a workflow, or call the tool directly with a script:

```js
export const meta = {
  name: 'summarize-files',
  description: 'Summarize important project files',
  phases: [
    { title: 'Read', detail: 'Inspect files' },
    { title: 'Synthesize', detail: 'Merge findings' },
  ],
}

phase('Read')
const summaries = await pipeline(
  ['README.md', 'package.json'],
  file => agent(`Read ${file} and summarize the useful facts.`, {
    label: `read:${file}`,
    phase: 'Read',
  })
)

phase('Synthesize')
return await agent(`Combine these summaries:\n${summaries.join('\n\n')}`, {
  label: 'final',
  phase: 'Synthesize',
})
```

The tool returns a `runId` immediately. Results are delivered back into the conversation when the background run finishes.

## Tool API

`workflow` accepts:

| Field | Purpose |
|---|---|
| `script` | Inline workflow JavaScript. Must start with `export const meta = { ... }`. |
| `scriptPath` | Run a previously saved workflow script. |
| `name` | Run a named/saved workflow when available. |
| `args` | JSON value exposed to the script as global `args`. |
| `resumeFromRunId` | Replay unchanged completed `agent()` calls from a prior run journal. |
| `title`, `description` | Accepted for compatibility and ignored; use `meta` instead. |

## Script runtime

Workflow scripts are plain JavaScript running in a deterministic sandbox.

Globals:

| Global | Purpose |
|---|---|
| `agent(prompt, opts)` | Spawn a Pi subagent; returns text or schema-validated JSON. |
| `pipeline(items, ...stages)` | Run items through async stages without a barrier between stages. |
| `parallel(thunks)` | Run async thunks concurrently and wait for all of them. |
| `phase(title)` | Move subsequent work into a progress phase. |
| `log(message)` | Emit workflow progress. |
| `workflow(ref, args)` | Run one nested workflow. |
| `args` | User-provided JSON input. |
| `budget` | `{ total, spent(), remaining() }`; `total` is currently `null`. |

Useful `agent()` options:

| Option | Purpose |
|---|---|
| `label` | Short unique label for progress and resume identity. |
| `phase` | Explicit phase assignment. |
| `schema` | JSON Schema for structured output. |
| `model` | Per-agent model override. |
| `effort` | Per-agent reasoning effort override. |
| `isolation: 'worktree'` | Run the agent in a temporary git worktree. |
| `agentType` | Use a named Pi subagent definition. |

Determinism rules: `Date.now()`, `Math.random()`, and argless `new Date()` throw inside the sandbox so resume stays stable.

Caps: concurrent agents are limited to `min(16, cpu cores - 2)`, each run can create up to 1000 agents, and one `pipeline()`/`parallel()` call can process up to 4096 items.

## Commands and storage

Use `/workflows` in Pi to inspect recent workflow runs.

Runtime files are stored under:

```text
~/.pi/better-workflows/scripts/  # persisted inline scripts
~/.pi/better-workflows/runs/     # run journals and results
```

If an inline completion is truncated, read the full journal before summarizing:

```bash
jq '.result' ~/.pi/better-workflows/runs/<runId>.json
```

## Development

```bash
# Pure runtime smoke tests
node $(npm root -g)/pi-subagents/node_modules/jiti/lib/jiti-cli.mjs test/smoke.ts

# Pi SDK load check
node --import $(npm root -g)/pi-subagents/node_modules/jiti/lib/jiti-register.mjs test/loadcheck.ts
```

## Package contents

```text
extensions/workflow.ts   Pi extension entry point
src/tool.ts              tool schema and registration
src/runtime.ts           workflow sandbox and runtime globals
src/agent.ts             Pi subagent bridge
src/manager.ts           background run manager
src/persistence.ts       script and journal storage
src/worktree.ts          git worktree isolation
src/structured-output.ts structured_output helper for schema agents
test/                    smoke, load, probe, and e2e checks
```

## License

MIT
