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

@oneharness/sdk

v0.21.2

Published

Typed Node.js SDK for oneharness

Readme

@oneharness/sdk

Typed Node.js access to the oneharness engine. The SDK launches its exact-version packaged CLI dependency and validates every response and stream envelope with named Zod schemas generated from the Rust wire types. The corresponding TypeScript declarations come from the same Rust JSON Schema bundle.

import { OneHarness, RunReportSchema, type RunReport } from "@oneharness/sdk";

const oneharness = new OneHarness();
const report = await oneharness.run({ prompt: "Summarize this repository", harnesses: ["codex"], events: true });
const checked: RunReport = RunReportSchema.parse(report);
console.log(checked.results[0]?.text, checked.results[0]?.usage.input_tokens);

The client covers every verb the CLI exposes, so nothing needs a hand-built command line: run, runMock, runStream, list, detect, config, sync, init, usage, gate, mock, interrupt, history, historyList, historyWatch, historyClear, historyMigrate, historyReindex, and historyPointers. That coverage is gated, not asserted here. runMock uses the deterministic responder shipped in the CLI; see Testing patterns. Both streaming methods return async iterators:

for await (const envelope of oneharness.runStream({
  prompt: "Inspect this repository",
  harnesses: ["codex"],
})) {
  if (envelope.type === "event" && envelope.event.name === "shell") break;
}

for await (const envelope of oneharness.historyWatch({
  labels: { graph: "release" },
  after: lastHistoryId,
})) {
  console.log(envelope.record.history_id, envelope.record.status);
}

Every JSON-returning method passes --format json --compact itself, so the CLI's own default (a human-readable text view) never reaches the SDK. A run over several harnesses is a fallback chain by default — the first candidate that can run does, and the report's fallback block says which; pass runMode: "parallel" to run them all at once.

Breaking or returning from either iterator terminates its oneharness subprocess. Every line is validated before it is yielded; malformed or unknown envelope variants fail the iterator. Additive fields within known output envelopes are accepted and preserved.

null usage fields mean the harness did not report the value; zero remains a real measured zero. String-valued harness/model/event identifiers should be treated as open sets for forward compatibility. history and historyWatch raise the exported HistoryNotFoundError when a session, record, or watch cursor cannot be resolved.

Every contract the CLI reads or prints is exported as a Zod schema named after its generated TypeScript type plus Schema (RunReport → RunReportSchema), generated from the same Rust wire types. Each schema's z.infer type is compile-time checked against its generated TypeScript type.

Output objects accept and preserve unknown fields. That deliberate loose-object behavior lets an older SDK validate a newer additive CLI response without erasing fields before an application can inspect them. Known fields are still validated recursively. The input schemas RunOptionsSchema, HistoryLookupSchema, HistoryListOptionsSchema, and HistoryWatchOptionsSchema are deliberately strict instead: unknown input keys are rejected because this SDK version cannot forward an option it does not understand, which also catches misspellings. Every method validates its input before spawning the CLI.

Nullable CLI fields remain required object keys: the generated response schemas model Rust's serialization contract, so an unavailable value is null, while an omitted guaranteed field is malformed. Optional RunOptions, HistoryLookup, and HistoryListOptions fields may be absent or explicitly undefined; every HistoryListOptions field is optional, so historyList() and historyList({}) both list the default store.

Continuation passes the prior result's native session id with a new user message:

const first = await oneharness.run({ prompt: "Inspect the bug", harnesses: ["codex"] });
const next = await oneharness.run({
  prompt: "Now propose the smallest fix",
  harnesses: ["codex"],
  resume: first.results[0]?.session_id ?? undefined,
});

Standardized history records and session summaries use their generated schemas too:

import { HistoryListSchema, HistoryRecordSchema } from "@oneharness/sdk";

const records = await oneharness.history({ last: true });
const sessions = await oneharness.historyList({ allProjects: true });
HistoryRecordSchema.parse(records[0]);
HistoryListSchema.parse(sessions);

HistoryLookupSchema states the selector rule itself: a lookup is a union of the only two ways to select a session, so it accepts last: true or a non-empty session and rejects a lookup that selects neither. history({}), history({ last: false }), and history({ session: "" }) fail validation rather than reaching the CLI, and HistoryLookup rejects them at compile time too.

last: true has priority over a name, so history({ session: "old", last: true }) returns the most recent session and history({ session: "old", last: false }) returns old. The two cases overlap deliberately — the union resolves last: true to its last-session variant first — which keeps last an ordinary boolean beside a named session, so a caller can pass one straight through.