New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

gpt-workflow

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gpt-workflow

Deterministic multi-agent workflows powered by Codex App Server

latest
Source
npmnpm
Version
0.4.2
Version published
Weekly downloads
3
-76.92%
Maintainers
1
Weekly downloads
 
Created
Source

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.

How did I use Codex to build gpt-workflow?

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 parseWorkflowJournalEntry — Getting 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.

FAQs

Package last updated on 21 Oct 2026

Related posts