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

@codegraff/sdk

v0.4.2

Published

TypeScript / Node SDK for the codegraff agent — drives `graff --json` over stdio. Types auto-generated from `graff --schema`.

Readme

@codegraff/sdk

TypeScript / Node SDK for the codegraff agent. It drives the graff binary over its --json stdio protocol, and the types are auto-generated from graff --schema.

Install

npm install @codegraff/sdk

Native binary included

npm installs the matching native graff executable through an optional platform package, so a separate CLI install or PATH setup is not required on supported macOS, Linux, and Windows arm64/x64 systems. Provider authentication is still required through the normal environment variables or graff login credentials.

If optional dependencies are disabled, the SDK falls back to graff on PATH. Development and custom builds can always set an explicit binary:

const graff = Harness.init({ binary: "./zig-out/bin/graff" });

Quick start

import { Harness, runAgent } from "@codegraff/sdk";

// one-shot, streamed
for await (const ev of runAgent({ prompt: "summarize README.md", model: "gpt-5.5", yolo: true })) {
  if (ev.type === "text") process.stdout.write(ev.text);
  if (ev.type === "tool_call") console.log("→", ev.name, ev.input);
  if (ev.type === "turn") console.log("\ncost $", ev.cost_usd);
}

// long-lived, multi-turn session
const harness = Harness.init({ model: "claude-opus-4-8", yolo: true });
const session = harness.session();
console.log(await session.ask("what files are here?")); // returns final text
const result = await session.askResult("summarize the changes");
console.log(result.text, result.inputTokens, result.costUsd);
console.log(await session.review("review HEAD against main")); // isolated + read-only
for await (const ev of session.send("ask me a follow-up before continuing")) {
  if (ev.type === "ask_user") session.answer({ text: "continue", callId: ev.call_id });
}
await session.close();

Harness.init accepts { model, yolo, cwd, env, binary, systemPrompt, maxToolCalls, maxModelCalls, dedupeToolCalls, args }. model may be a model name or a provider id (e.g. "codex", "moonshot"). Also exported: MODELS and PROVIDERS.

Runtime controls and cancellation

Turns and acknowledged controls are serialized per session, so overlapping calls cannot steal each other's events. answer() remains out-of-band so it can answer an active ask_user prompt.

await session.setModel("codex", "gpt-5.6-luna");
await session.setEffort("high");
await session.compact();

const controller = new AbortController();
const pending = session.ask({ prompt: "long task", signal: controller.signal });
controller.abort(); // interrupts the active model/tool turn
await pending;      // rejects with the terminal cancellation error

askResult() returns final text plus context, token, cache, cost, and provider-call usage. ask() remains the compatibility shorthand that returns only final text. The same controls, abort behavior, structured results, and out-of-band answers are available on RemoteHarness.

Events

Both runAgent and session.send yield an AsyncGenerator<Event>:

  • text — assistant text delta
  • tool_call — the agent invoked a tool (name, input)
  • tool_result — a tool returned
  • ask_user — the agent needs input; answer it with session.answer({ text, callId })
  • turn — turn finished; carries the final text, context_tokens, and cost_usd
  • error — something went wrong

Remote (edge runtimes)

Edge runtimes can't spawn a subprocess. Run graff serve somewhere and drive it over HTTP with fetch + Web Streams (works on Cloudflare Workers, Deno, Bun, browsers, Node >= 18):

import { RemoteHarness, runAgentRemote } from "@codegraff/sdk/remote";

for await (const ev of runAgentRemote({ url: "https://my-bridge.example", token, prompt: "summarize README.md" })) {
  if (ev.type === "text") console.log(ev.text);
}

const h = RemoteHarness.init({ url: "http://127.0.0.1:8787", token, yolo: true });
console.log(await h.ask("what files are here?"));
console.log(await h.ask({
  prompt: "read the code in this image",
  images: [
    { type: "image_url", url: "https://example.com/code.png" },
    { type: "image_base64", mediaType: "image/png", data: pngBase64 },
  ],
}));
await h.close();

images are native provider vision parts, not text pasted into the prompt. They work on local Harness and edge-safe RemoteHarness turns and are validated against the selected model and the 16-image/3.7 MB-per-image limits.

Orchestration (#276): agent()/parallel()/pipeline(), budgets, resumable runs

@codegraff/sdk/orchestrate is a deterministic scripting layer on top of the harness's subagent/workflow tools/agent_output — instead of asking the root model to decide, on its own judgement, to fan out, the SDK drives those tools programmatically:

import { agent, parallel, pipeline, Run } from "@codegraff/sdk/orchestrate";

// one subagent call
const r = await agent("summarize README.md", { agent: "researcher" });
console.log(r.ok, r.text, r.usage.contextTokens);

// parallel(): explicit barrier, a failed thunk resolves null (never rejects)
const reviews = await parallel([
  () => agent("review auth.ts for bugs", { agent: "reviewer" }),
  () => agent("review db.ts for bugs", { agent: "reviewer" }),
]);

// pipeline(): per-item flow, no barrier between an item's stages -- one
// slow file never blocks another file's later stages
const results = await pipeline(
  ["a.ts", "b.ts"],
  async (_prev, file) => agent(`refactor ${file}`, { isolation: "worktree" }),
  async (prev, file) => agent(`review this diff for ${file}:\n${(prev as any).text}`),
);

A Run adds a token-aware budget and a JSONL journal + prefix-resume so a re-invoked script skips unchanged calls and goes live from the first divergence:

const run = new Run({ budget: { maxTokens: 200_000 } });
await run.agent("step one");
await run.agent("step two");
console.log(run.budget.spent(), run.budget.remaining());

// later / after a crash: replay unchanged calls, run only what diverged
const resumed = new Run({ resumeFrom: run.journalPath });
await resumed.agent("step one"); // cached, no process spawned

See orchestrate.ts's file header for the exact journal format and the concurrency/determinism guarantees (and their documented edges) for parallel()/pipeline().

ACP (graff acp)

A host that wants ACP v1 session/updates (thought / tool_call / text), not --json events, should spawn graff acp instead of Harness. @codegraff/sdk/acp is the spawn plus JSON-RPC write/read:

import { acp } from "@codegraff/sdk/acp";

const session = await acp({ model: "gpt-5.5" });
session.onUpdate((update) => console.log(update.sessionUpdate));
const { stopReason, updates } = await session.prompt("hello");
console.log(stopReason, updates.length);
await session.close();

spawnAcp() skips the initialize → session/new handshake. Recipe, method names, --no-local-tools, and license: Embedding graff.

Same-process (no child): @codegraff/sdk/embed createGraffAgent() loads graff-core.wasm (zig build wasm-core). First-slice turn is echo:.

Links

License

BSD-3-Clause