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

gpt-workflow

v0.4.1

Published

Deterministic multi-agent workflows powered by Codex App Server

Readme

gpt-workflow

A deterministic multi-agent workflow runtime powered by Codex App Server. Control flow — loops, branches, retries — is plain JavaScript in your script; agent() delegates bounded judgment to Codex threads, and parallel(), pipeline(), and child workflow() calls fan that work out.

Compared to driving Codex directly, a workflow adds:

  • Resumability — long or token-expensive runs replay completed calls from a durable journal instead of paying for them again.
  • Validated structured output — pass a JSON schema to agent() and the runtime validates the reply and retries invalid ones, instead of you policing format in prompt text.
  • Multi-agent verification — independent critics and judge panels, where a failed call resolves to null instead of aborting the fan-out.

Install

Everything requires Bun 1.3 or newer, with the Codex CLI installed and authenticated for live runs. Node.js is not a supported runtime.

The preferred install is the Codex plugin. It bundles a skill that authors, runs, and debugs workflows for you, and it runs the published CLI through bunx, so there is no separate package to install:

codex plugin marketplace add CyrusNuevoDia/gpt-workflow
codex plugin add gpt-workflow@gpt-workflow

Restart the ChatGPT desktop app after installing and start a new task so the bundled skill loads; see plugin installation and behavior.

To drive the CLI yourself, install globally:

bun add --global gpt-workflow

For library use:

bun add gpt-workflow

Write a workflow

Store project workflows under .codex/workflows/; this example is summarize-files.js:

export const meta = {
  name: "summarize-files",
  description: "Summarize files concurrently and merge the findings"
}

const files = args.files
const summaries = await parallel(
  files.map((file) => () =>
    agent(`Read ${file} and return three factual bullets.`, {
      label: `summarize:${file}`
    })
  )
)

return { summaries: summaries.filter(Boolean) }

args is the run's input; the --args flag in the next section supplies it. meta.name is also the run-storage directory name, so it may contain only letters, numbers, periods, underscores, and hyphens, and cannot be . or ...

If an agent's thread ends in an error, times out, returns no final message, or exhausts its structured-output retries, that call resolves to null and is recorded in the run's failures — the filter(Boolean) drops those slots. Script bugs, setup problems such as missing models or bad option types, cancellation, worktree-setup failures, and transport failures reject the whole run instead.

Workflow source is trusted repository code; it runs inside node:vm as a semantic boundary, not a security sandbox for hostile JavaScript.

Run and resume

A live run spends model tokens. Resume replays completed calls from the journal — their tokens are not spent again — then runs the rest live:

gpt-workflow models
gpt-workflow run --default-model gpt-5.6-luna \
  --args '{"files":["src/cli.ts","src/runtime.ts"]}' \
  .codex/workflows/summarize-files.js
gpt-workflow run --default-model gpt-5.6-luna --resume workflow-123 \
  --args '{"files":["src/cli.ts","src/runtime.ts"]}' \
  .codex/workflows/summarize-files.js

--default-model supplies the model for agent() calls that omit options.model; without either, the run rejects with a model error. --args takes strict JSON and becomes the script's args global; pass a plain string as quoted JSON, e.g. --args '"triage"'. Invalid JSON exits 1 with a usage error on stderr before any record is emitted. For --resume, substitute the runId reported by your original run's records — real IDs look like workflow-<uuid>; these examples shorten it to workflow-123. Resume with the same --args: changed args change prompts, which miss the journal and run live. Resume is strict: a missing run ID, duplicate run ID, or run stored under a different workflow name exits before connecting to Codex.

models prints every model discovered from the authenticated App Server as NDJSON without spending model tokens. Run accepts repeatable --required-model flags plus --request-timeout-ms, --thread-start-timeout-ms, and --turn-timeout-ms. SIGINT or SIGTERM cancels active agents, records a terminal failure, flushes persisted events, and exits nonzero.

Stdout is ordered NDJSON; human diagnostics go to stderr. Every record includes schemaVersion, sequence, runId, scriptPath, runDirectory, ts (epoch milliseconds), and type. The opening run.started record carries the script's meta; the final run.completed record carries meta, result, usage, failures, and journalPath:

{"meta":{"name":"summarize-files","description":"Summarize files concurrently and merge the findings"},"type":"run.started","runDirectory":"/home/me/.codex/projects/-repo/workflows/summarize-files/runs/workflow-123","runId":"workflow-123","schemaVersion":1,"scriptPath":"/repo/.codex/workflows/summarize-files.js","sequence":0,"ts":1783971328984}
{"failures":[],"journalPath":"/home/me/.codex/projects/-repo/workflows/summarize-files/runs/workflow-123/journal.jsonl","meta":{"name":"summarize-files","description":"Summarize files concurrently and merge the findings"},"result":{"summaries":["…","…"]},"type":"run.completed","usage":{"agentCount":2,"liveAgentCount":2,"modelUsage":{"gpt-5.6-luna":{"liveAgentCount":2,"replayedAgentCount":0,"subagentTokens":3412}},"peakConcurrentAgents":2,"replayedAgentCount":0,"subagentTokens":3412},"runDirectory":"/home/me/.codex/projects/-repo/workflows/summarize-files/runs/workflow-123","runId":"workflow-123","schemaVersion":1,"scriptPath":"/repo/.codex/workflows/summarize-files.js","sequence":9,"ts":1783971339402}

After valid metadata creates the run directory, a top-level failure makes the CLI emit run.failed and exit non-zero. Source-read and metadata-parse failures write only to stderr and create no run artifact. Agent-side null failures don't fail the run: they stay visible in the run.completed record's failures and are retried on resume.

Inspect past runs

There is no need to tee the stream for later inspection: every run also persists a filtered copy of its NDJSON to $CODEX_HOME/projects/<encoded-project-path>/workflows/<workflow-name>/runs/<runId>/events.jsonl — the run, phase, and agent status records needed to rebuild run state, without the high-volume streaming deltas. Two commands read it back without spending model tokens:

gpt-workflow list
gpt-workflow status workflow-123

list prints one JSON line per run, newest first, with runId, name, scriptPath, status, timestamps, and — once the run ended — finishedAt, failureCount, and usage. status prints one JSON object that adds ordered phases, per-agent progress and token totals, and the final result and failures. Output is plain JSON, so jq applies:

gpt-workflow status workflow-123 | jq '.phases'

A run with no terminal record reports "incomplete": an in-flight and an interrupted run look identical on disk, so the CLI never claims "running" — check lastEventAt for staleness. An unknown run ID makes status exit 1 with an error on stderr.

Durable journals

Live runs persist an append-only replay journal at:

$CODEX_HOME/projects/<encoded-project-path>/workflows/<workflow-name>/runs/<runId>/journal.jsonl

CODEX_HOME defaults to ~/.codex. The project key is the absolute invocation directory with path separators replaced by dashes, including the leading root separator: /repo becomes -repo. Run state is local user data and does not need a repository ignore rule.

The same directory holds events.jsonl, the inspection copy described above; the journal remains the only replay substrate.

Resume reuses that runId and directory. Completed agent() calls are matched by their prompt and options, regardless of the order they finished in; at the first call with no journal match, that call and every later call runs live and appends to the same journal.

To inspect a journal, parse it one record at a time with parseWorkflowJournalEntryGetting started shows a streaming loop. The parser throws a SyntaxError on blank text, malformed JSON, or records that are not valid journal entries; it never returns null, so wrap each parse in try/catch when surveying a damaged journal.

The journal is workflow replay state. Codex separately persists full agent thread rollouts and exposes them through App Server thread APIs; their private on-disk layout is not a gpt-workflow contract.

Library API

import {
  AppServerClient,
  REQUIRED_APP_SERVER_MODELS,
  runWorkflowScript
} from "gpt-workflow"

const source = `
export const meta = {
  name: "summarize",
  description: "Summarize a topic"
}

return await agent("Summarize " + args.topic)
`

const client = await AppServerClient.connect({
  defaultModel: "gpt-5.6-luna",
  requiredModels: REQUIRED_APP_SERVER_MODELS
})

try {
  const execution = await runWorkflowScript(source, {
    appServer: client,
    args: { topic: "deterministic orchestration" }
  })
  console.log(execution.result, execution.journalPath)
} finally {
  await client.close()
}

Running this example spends model tokens; inject agent to drive offline tests without Codex. REQUIRED_APP_SERVER_MODELS is the model set the runtime depends on — connect rejects when the App Server cannot start or is missing any of them. runWorkflowScript accepts runDirectory for caller-owned storage and resumeFromRunId for library resume, and splits failures exactly as Write a workflow describes: agent-side failures resolve to null and land in execution.failures; everything else rejects. listRunSummaries and readRunStatus expose the list and status data programmatically; see the API reference.

Documentation

Start with Getting started or the full documentation index. Structured output schemas, budgets, agent options, and child workflows are covered in the API reference; verification and fan-out shapes in Patterns.

Migrating Claude Code workflows? See the Claude parity ledger and the migration checklist.

Working on this repository itself? See AGENTS.md.