npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sahagan-agents-workflow

v1.5.0

Published

Multi-agent workflow for Claude Code and Codex — one shared rule set, five specialist roles, budget-bounded delegation, and a cross-CLI bridge

Readme

sahagan-agents-workflow 🐱

npm version License: MIT npm downloads

A multi-agent working method for Claude Code and OpenAI Codex, packaged as a workspace template you can install in one command.

Most agent setups are a pile of prompts. This one is a workflow: a single shared rule set that both AI tools obey, five specialist roles with real boundaries, a budget that stops runaway spending, an independent QA gate that cannot be faked, and a bridge that lets a Claude session hand work to Codex and back — on the same rules, in the same repository, with the accounting written down.


The team

| Role | Name | Owns | Reviews | |------|------|------|---------| | Orchestrator | Angpao (อั่งเปา) | Coordination, state, task log, memory | Scope, routing, synthesis | | Dev Lead | Phayu (พายุ) | Code, within assigned file ownership | Architecture and implementation | | QA Lead | Taifoon (ใต้ฝุ่น) | Nothing — read-only by design | Independent quality and security gate | | UX/UI Designer | Timsum (ติ่มซำ) | UI and design files in scope | UX and accessibility | | Research Specialist | Bonus (โบนัส) | Research reports only | Research, source and codebase archaeology |

The orchestrator does not write code. The reviewer does not write files. Each worker is a leaf: it does the one task it was given and stops — it never spawns another agent or calls another CLI. That single constraint is what keeps a multi-agent run from turning into an unbounded tree of subprocesses.

PIXEL AGENTS — agents working in VS Code Spawned agents are real OS subprocesses, so they show up in the PIXEL AGENTS VS Code extension as pixel characters in an office layout.


Install

npm install -g sahagan-agents-workflow

Quick start

aw init my-app                       # create the workspace
# open my-app.code-workspace in VS Code
# run /session-start — Angpao loads the rules, memory and pending work

aw init asks two questions: your language (English by default, Thai available) and your AI tool — Claude Code, Codex, or both. Choosing both is the point of this release: one workspace, one rule set, two runtimes.


What makes this different

One rule set, two runtimes

CLAUDE.md and AGENTS.md are thin entrypoints. Neither contains rules. Both point at WORKFLOW.md, the single shared rule file that Claude Code, Codex and even a plain chat window all read. Change a rule once and every runtime gets it. There is no second copy to drift.

WORKFLOW.md                          the rules — read once per session by the orchestrator
├── interconnect/coordination.md     routing, the task packet, parallel and review rules
├── interconnect/worker-contract.md  the short contract a leaf worker receives (≈4 KB, not the whole rule set)
├── interconnect/runtime-adapters.md how to actually invoke each tool, and what each sandbox really guarantees
└── interconnect/model-budget-policy.md   which model for which job, and the spend ceiling

Workers get a contract, not the library

A naive setup injects the full persona and rule set into every spawn, and pays for it on every call. Here the orchestrator loads the rules once; each worker receives a compact worker contract plus a role brief scoped to its task. Long personas and reference documents are passed as paths with versions, and read only within scope.

A budget that is actually enforced

The default work package is four dispatches: do → review → fix → re-check, with at most one premium-model call. The bridge counts dispatches per task ID in a ledger and refuses the fifth. A call that failed to even start a process is recorded as voided, so it does not consume a slot it never used.

Honest status, by construction

The bridge reports process_succeeded when a subprocess returned without a runtime error — and in the same object reports taskStatus: "unverified" and qaApproved: false. A process exiting zero is not a passing task, a worker's self-review is never an independent QA pass, and the workflow requires you to say so plainly when a reviewer was unavailable. Every layer of this template is written to make an unearned "done" hard to produce by accident.

Roles are boundaries, not costumes

workMode (what kind of work) is separate from accessMode (what the runtime may touch). Only accessMode selects the sandbox and tool list: a review runs readonly with Read,Glob,Grep; write work runs with Edit,Write added. A Claude leaf never receives Bash or an agent-spawning tool. A Codex leaf gets the filesystem sandbox and has native delegation switched off, but the sandbox restricts writes rather than command execution — the wrapper says so in its own output rather than implying more. The role table is documentation; the access mode is what the runtime enforces.


The cross-CLI bridge

template/scripts/agent_bridge.py lets the runtime you are sitting in hand a bounded task to the other one. A Claude Code session can dispatch to Codex; a Codex session can dispatch to Claude Code. The receiver is a leaf: it does the task, returns its report, and stops.

It is a wrapper around the CLIs you already have installed and logged into. It is not an API proxy, it does not move quota between accounts, and it does not enable any billing.

Using it

# 1. copy the packet template and fill it in
cp context/agent-task.template.json context/task-PROJ-101.json

# 2. dry run — validates the packet, renders the exact argv, calls no model
python scripts/agent_bridge.py --provider codex --profile economy --packet context/task-PROJ-101.json

# 3. run it for real
python scripts/agent_bridge.py --provider codex --profile economy --packet context/task-PROJ-101.json --execute

Swap --provider claude to send the other way. --profile premium selects the stronger model and requires a written premiumReason and a known billingBasis in the packet before it will execute.

The task packet

{
  "taskId": "PROJ-101",
  "projectRoot": "/absolute/path/to/project",   // must exist
  "role": "dev-lead",
  "roleBrief": "Implement only the owned files; report evidence and blockers.",
  "workMode": "write",        // write | revise | expand | deterministic | review
  "accessMode": "write",      // readonly | write  — this alone controls the sandbox
  "goal": "State the bounded task.",
  "ownedFiles": ["src/api.ts"],                 // relative, no "..", nothing else may be touched
  "sources": [{ "path": "/absolute/path", "version": "commit-or-date" }],
  "constraints": ["Do not modify files outside ownedFiles."],
  "acceptanceCriteria": ["State observable completion evidence."],
  "billingBasis": "subscription"                // subscription | authorized_credits | unknown
}

The packet is validated before anything runs: review may not request write access, write modes may not run read-only, owned paths may not escape the project, sources must exist, and premium requires its justification. Bad packets are rejected with a reason instead of being sent to a model.

What it guarantees, and what it does not

Enforced by the runtime: the Codex filesystem sandbox (read-only vs workspace-write) with native delegation disabled, and for Claude a tool allowlist plus an empty strict MCP configuration so the leaf inherits no external tools. Codex is given no tool allowlist and no MCP restriction by this wrapper, and its dry-run report states that explicitly.

Enforced by the wrapper: one active CLI workflow at a time (single-flight lock), leaf depth of one, the dispatch and premium ceilings, a 24,000-character prompt cap, and a 600-second timeout.

Cooperative only: file ownership, task scope, and work-package identity — the ledger counts per task ID, so starting a new ID starts a new budget, and nothing but the operator's discipline prevents that. Native or direct CLI calls made outside the bridge are outside its lock and its counters too. The policy still applies to all of these, but by agreement rather than by enforcement, and the wrapper says so in its own output rather than implying a guarantee it cannot make.

Operational details that matter in practice

  • Stale locks recover safely. The lock records its owner's PID. A later run releases it only when that process is genuinely gone, logging stale_lock_released to the ledger. A PID that cannot be inspected is treated as alive — the safe direction. --lock-status reports the state without acquiring or releasing anything.
  • Worker output is never lost. If the run directory cannot be written, the report carries stdoutInline and stderrInline rather than discarding the work.
  • A corrupt ledger fails loudly. One malformed line stops the bridge with the file, the line number and the repair instruction, because silently skipping records would undercount the budget.
  • Evidence is kept. Every dispatch writes stdout and stderr under context/agent-bridge-runs/, with an append-only ledger at context/agent-bridge-ledger.jsonl.

The bridge ships with its unit test suite, which lands at agents-workflow/tests/ in your workspace. Run it from the workflow directory any time — it is the only way to confirm the bridge behaves on your own Python and OS before trusting it with --execute:

python -m unittest discover -s tests -t tests

Session lifecycle

/session-start

Angpao reads WORKFLOW.md and the coordination rules, scans persona/ so newly added roles are discovered rather than remembered, loads PROJECT.md, memories/MEMORY.md and the relevant memory files, parses the whole of projects/task-log.jsonl to find the latest status per task ID, reconciles it against context/session-state.json, and reports what is genuinely pending — separating stale entries from confirmed ones.

/session-end

Completed work is appended to the task log with evidence; unfinished work records its last action and blockers. Decisions worth keeping go into memories/ as individual files with an index line. Rules are improved only where the session produced evidence — and improvements go into the shared rule files, never into a parallel copy. Nothing is committed or pushed automatically.

Both skills are mirrored byte-for-byte in .claude/skills/ and .agents/skills/ so Claude Code and Codex run the same protocol.


State and handoff

| File | Purpose | |------|---------| | projects/task-log.jsonl | Append-only history. Read the latest record per taskId; never overwrite. | | context/session-state.json | Snapshot of the current session: runtime, agents, decisions, validation, budget. | | context/session-state.template.json | Clean starting point. Never copy it over a state file that has live work in it. | | context/handoff.template.md | Crossing runtimes, machines or days: goal, ownership, source versions, what is done and not done, QA result, next instruction. | | memories/MEMORY.md | One-line index into memories/ — loaded at session start. |


CLI reference

aw init <project-name> [parent-dir]

Creates workspace-<project-name>/ containing agents-workflow/ and a VS Code .code-workspace file. Copies the bundled template (no network needed), applies your language choice, keeps the entrypoints for your chosen tool, initialises a local git repository, installs the agent skills from GitHub, and checks whether Python is available for the bridge.

aw upgrade [agents-workflow-path]

Applies the template bundled with the installed package. If a newer version of the package exists, upgrade installs it and then stops, asking you to rerun the same command so the newly installed package applies its own bundled template rather than the one you started with.

On the run that does the work, it walks the entire bundled template and compares every file against your installed copy — new and changed files are listed explicitly, changed files are backed up to a timestamped .upgrade-backup-* directory before being replaced, and the skills are refreshed and re-mirrored.

Never overwritten: memories/, projects/, tasks/, research/, PROJECT.md, context/session-state.json, and the bridge's runtime state (context/agent-bridge-ledger.jsonl, context/agent-bridge.lock, context/agent-bridge-runs/).

aw help

Full help, including the bridge dry-run example.


Workspace layout

workspace-my-app/
├── my-app.code-workspace
└── agents-workflow/
    ├── WORKFLOW.md                  shared rules — the one source of truth
    ├── CLAUDE.md / AGENTS.md        thin entrypoints, one per runtime
    ├── PROJECT.md                   your project's own facts
    ├── interconnect/
    │   ├── coordination.md          routing, task packet, review rules
    │   ├── worker-contract.md       the compact contract a leaf receives
    │   ├── runtime-adapters.md      how to invoke each tool; what each sandbox really means
    │   ├── model-budget-policy.md   model and spend policy, in prose
    │   ├── model-budget-policy.json the values the bridge actually enforces
    │   └── no-mcp.json              empty strict MCP config for leaf workers
    ├── persona/                     the five roles, in full
    ├── context/                     session state, task packet and handoff templates
    ├── scripts/agent_bridge.py      the cross-CLI bridge
    ├── tests/                       the bridge's unit tests
    ├── templates/project-runtime/   model/effort config to copy into any project root
    ├── memories/                    project memory (yours — never overwritten)
    ├── projects/task-log.jsonl      append-only task history
    ├── .claude/                     Claude Code settings, subagents, skills
    ├── .agents/skills/              the same session skills, for Codex
    └── .codex/config.toml           Codex model defaults for this root

Choosing models

Role and model are deliberately separate. A worker does not inherit the orchestrator's expensive model — general work runs on a mid-tier model at medium reasoning, and a premium model is chosen once per work package with a stated reason.

interconnect/model-budget-policy.json holds the values the bridge enforces: the economy and premium model per provider, the dispatch ceilings, the prompt cap and the timeout. Set the model names to what your account can actually use — the shipped values are examples, not entitlements. An optional allowedModelPrefixes map lets a team pin a floor and refuse silent downgrades; leave it out and any non-empty model name is accepted.

Model and effort settings only apply to sessions opened at the root that contains the config file. To make them apply inside a project repository, copy templates/project-runtime/ into that root and merge the keys rather than overwriting — permissions and hooks live in the same file.


Skills

Installed automatically by aw init and refreshed by aw upgrade:

| Skill | Used by | Source | |-------|---------|--------| | api-and-interface-design | Phayu | addyosmani/agent-skills | | debugging-and-error-recovery | Phayu | addyosmani/agent-skills | | ui-ux-pro-max | Timsum | nextlevelbuilder/ui-ux-pro-max-skill | | planning-and-task-breakdown | Angpao, Bonus | addyosmani/agent-skills | | code-review-and-quality | Taifoon | addyosmani/agent-skills | | security-and-hardening | Taifoon | addyosmani/agent-skills |

Bundled with the template: session-start, session-end, initproject. The downloaded skills are installed into .claude/skills/ and mirrored into .agents/skills/, so Codex finds them where the shared rules say to look.

Phayu injects at most one skill per task — api-and-interface-design for interface and contract work, debugging-and-error-recovery for bug hunting, and neither for general implementation. Injecting two at once is explicitly disallowed.


Requirements

  • Node.js 18+ for the CLI
  • Claude Code and/or Codex CLI, installed and signed in
  • Python 3.9+ — only for the cross-CLI bridge; everything else works without it
  • git for skill installation and workspace initialisation

Design principles

  1. One rule set. Change it once; every runtime sees it. No parallel copies to drift apart.
  2. Leaf workers. A spawned agent never spawns. Depth is one, and concurrency is one by default.
  3. Access mode is the enforcement. Role names are documentation; the sandbox and tool list decide what can actually happen.
  4. Independent review. A writer reviewing its own work is a self-review and must be reported as one.
  5. Bounded spend. Four dispatches per work package, one premium call, counted in a ledger.
  6. Say what is true. A zero exit code is not a passing task. An unavailable reviewer is a blocked gate, not an approval.
  7. The template stays neutral. Project-specific rules live in their own file, registered in WORKFLOW.md. Nothing in the shared core hardcodes a project, a path or an account.

License

MIT © Sahagan — see LICENSE.

Issues and pull requests: github.com/Sahagan/sahagan-agents-workflow