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

@bolt-foundry/gambit

v0.5.3-dev.1

Published

Agent harness framework for building, running, and verifying LLM workflows in Markdown and code.

Readme

Gambit (draft README)

This package is developed in Bolt Foundry’s monorepo and mirrored into github.com/bolt-foundry/gambit. For now, that repo is a strict mirror (please do not land direct changes there).

CI runs .github/workflows/gambit-mirror.yml on every main push that touches this package, using scripts/sync-gambit-mirror.sh to open and auto-merge a PR from the bft-codebot fork into the public mirror.

Gambit helps developers build the most accurate LLM apps by making it simple to provide exactly the right amount of context at the right time.

Status quo

  • Most teams wire one long prompt to several tools and hope the model routes correctly.
  • Context often arrives as a single giant fetch or RAG blob, so costs climb and hallucinations slip in.
  • Input/outputs are rarely typed, which makes orchestration brittle and hard to test offline.
  • Debugging leans on provider logs instead of local traces, so reproducing failures is slow.

Our vision

  • Treat each step as a small deck with explicit inputs/outputs and guardrails; model calls are just one kind of action.
  • Mix LLM and compute tasks interchangeably and effortlessly inside the same deck tree.
  • Feed models only what they need per step; inject references and cards instead of dumping every document.
  • Keep orchestration logic local and testable; run decks offline with predictable traces.
  • Ship with built-in observability (streaming, REPL, debug UI) so debugging feels like regular software, not guesswork.

5-minute quickstart

Requirements: Deno 2.2+ and OPENROUTER_API_KEY (set OPENROUTER_BASE_URL if you proxy OpenRouter-style APIs).

Run the CLI directly from JSR (no install):

export OPENROUTER_API_KEY=...
deno run -A jsr:@bolt-foundry/gambit/cli --help

Run a packaged example without cloning:

export OPENROUTER_API_KEY=...
deno run -A jsr:@bolt-foundry/gambit/cli run --example hello_world.deck.md --init '"hi"'

Run the built-in assistant (from a clone of this repo):

export OPENROUTER_API_KEY=...
deno run -A src/cli.ts run src/decks/gambit-assistant.deck.md --init '"hi"' --stream

Talk to it in a REPL (default deck is src/decks/gambit-assistant.deck.md):

deno run -A src/cli.ts repl --message '"hello"' --stream --verbose

Open the debug UI:

deno run -A src/cli.ts serve src/decks/gambit-assistant.deck.md --port 8000
open http://localhost:8000/debug

Install the CLI once (uses the published JSR package):

deno install -A -n gambit jsr:@bolt-foundry/gambit/cli
gambit run path/to/root.deck.ts --init '"hi"'

If you run from a remote URL (e.g., jsr:@bolt-foundry/gambit/cli), pass an explicit deck path; the default REPL deck only exists in a local checkout.

Author your first deck

Minimal Markdown deck (model-powered):

+++
label = "hello_world"

[modelParams]
model = "openai/gpt-4o-mini"
temperature = 0
+++

You are a concise assistant. Greet the user and echo the input.

Run it:

deno run -A src/cli.ts run ./hello_world.deck.md --init '"Gambit"' --stream

Compute deck in TypeScript (no model call):

// echo.deck.ts
import { defineDeck } from "jsr:@bolt-foundry/gambit";
import { z } from "zod";

export default defineDeck({
  label: "echo",
  inputSchema: z.object({ text: z.string() }),
  outputSchema: z.object({ text: z.string(), length: z.number() }),
  run(ctx) {
    return { text: ctx.input.text, length: ctx.input.text.length };
  },
});

Run it:

deno run -A src/cli.ts run ./echo.deck.ts --init '{"text":"ping"}'

Deck with a child action (calls a TypeScript tool):

+++
label = "agent_with_time"
modelParams = { model = "openai/gpt-4o-mini", temperature = 0 }
actionDecks = [
  { name = "get_time", path = "./get_time.deck.ts", description = "Return the current ISO timestamp." },
]
+++

A tiny agent that calls get_time, then replies with the timestamp and the input.

And the child action:

// get_time.deck.ts
import { defineDeck } from "jsr:@bolt-foundry/gambit";
import { z } from "zod";

export default defineDeck({
  label: "get_time",
  inputSchema: z.object({}), // no args
  outputSchema: z.object({ iso: z.string() }),
  run() {
    return { iso: new Date().toISOString() };
  },
});

Repo highlights

  • CLI entry: src/cli.ts; runtime: src/runtime.ts; definitions: mod.ts.
  • Examples: examples/hello_world.deck.md, examples/agent_with_multi_actions/.
  • Debug UI assets: src/server.ts (built-in UI now renders schema-driven init forms beneath the user message box with a raw JSON tab, reconnect button, and a trace-formatting hook).
  • Tests/lint/format: deno task test, deno task lint, deno task fmt; compile binary: deno task compile.
  • Docs index: docs/README.md; authoring guide: docs/authoring.md; prompting notes: docs/hourglass.md; changelog: CHANGELOG.md.

Docs

  • Authoring decks/cards: docs/authoring.md
  • Runtime/guardrails: docs/runtime.md
  • CLI, REPL, debug UI: docs/cli.md
  • Examples guide: docs/examples.md
  • OpenAI Chat Completions compatibility: docs/openai-compat.md

OpenAI Chat Completions compatibility

If you already construct OpenAI Chat Completions-style requests, you can use Gambit as a drop-in-ish wrapper that applies a deck prompt and can execute only deck-defined tools (action decks).

import {
  chatCompletionsWithDeck,
  createOpenRouterProvider,
} from "jsr:@bolt-foundry/gambit";

const provider = createOpenRouterProvider({
  apiKey: Deno.env.get("OPENROUTER_API_KEY")!,
});

const resp = await chatCompletionsWithDeck({
  deckPath: "./path/to/root.deck.md",
  modelProvider: provider,
  request: {
    model: "openai/gpt-4o-mini",
    messages: [{ role: "user", content: "hello" }],
  },
});

console.log(resp.choices[0].message);

Handlers (error/busy/idle)

  • Decks may declare handlers with onError, onBusy, and onIdle. onInterval is still accepted but deprecated (alias for onBusy).
  • Busy handler input: {kind:"busy", source:{deckPath, actionName}, trigger:{reason:"timeout", elapsedMs}, childInput} plus delayMs/repeatMs knobs.
  • Idle handler input: {kind:"idle", source:{deckPath}, trigger:{reason:"idle_timeout", elapsedMs}} with delayMs (and optional repeatMs if provided).
  • Error handler input: {kind:"error", source, error:{message}, childInput} and should return an envelope {message?, code?, status?, meta?, payload?}.
  • Example implementations live under examples/handlers_ts and examples/handlers_md.
  • Debug UI streams handler output in a “status” lane (busy/idle) separate from assistant turns.

Next steps

  • Swap modelParams.model or pass --model/--model-force to test other providers.
  • Add actionDecks to a deck and call child decks; use spawnAndWait inside compute decks.
  • Use --stream and --verbose while iterating; pass --trace <file> to capture JSONL traces.