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

@lgrammel/prototype-2

v2.0.3

Published

A minimal hosted coding agent for one GitHub repository.

Readme

@lgrammel/prototype-2

Workbench is a minimal hosted coding agent for one configured GitHub repository per deployment.

The package includes an offline, version-matched coding-agent guide and configuration reference for initialized projects.

Initialize

From the root of the private GitHub repository that Workbench should manage, run:

npx @lgrammel/prototype-2@latest init
# Or select another curated harness and optional native model:
npx @lgrammel/prototype-2@latest init --harness pi --model anthropic/claude-sonnet-4.6

The initializer creates an independent workbench/ project, installs this package as a normal dependency, and scaffolds the required repository-owned default agent as a Codex harness by default, without creating optional tools/, automations/, or tasks/ directories. Pass --harness claude-code or --harness pi to select a different curated harness, and optionally pass --model; without flags, setup uses Codex with gpt-5.6-sol as the default plus gpt-5.6-terra and gpt-5.6-luna choices. It also creates .agents/skills/workbench-configuration/SKILL.md at the host repository root so coding agents can locate and safely improve the Workbench configuration. Commit and push the generated files. You do not need to create a local .env file or run Workbench, its migrations, checks, or build locally.

Deploy to Vercel

  1. Create a fine-grained GitHub personal access token scoped to the target repository with Contents: Read and write and Pull requests: Read and write permissions. Add Issues: Read and write when a task automation manages issue labels.
  2. Import the repository into Vercel as a new project. Set Root Directory to workbench, then deploy. The first deployment may report missing configuration; finish the following steps and redeploy it.
  3. Add the Neon integration to the Vercel project and confirm that it created a pooled DATABASE_URL in the Production environment.
  4. In Project Settings → Environment Variables, add these Production variables:
    • GITHUB_REPOSITORY: the private target in owner/repository form; its default branch must be main
    • GITHUB_TOKEN: the fine-grained token from step 1; mark it sensitive
    • GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL: the identity for commits published by Workbench
    • GITHUB_WEBHOOK_SECRET: optional secret of at least 16 characters for GitHub automations
    • CRON_SECRET: optional secret of at least 16 characters for scheduled automations
  5. In Project Settings → Security, enable Secure Backend Access with OIDC Federation. In Project Settings → Deployment Protection, enable Vercel Authentication with a scope that protects All Deployments. Workbench relies on this as its access-control boundary. An external webhook or scheduler also needs Vercel's Protection Bypass for Automation so its request reaches Workbench's independently authenticated endpoint.
  6. Redeploy Production, open the protected URL, create a chat, and ask Workbench to inspect the repository without changing it.

No Sandbox image setting is required; Workbench uses Vercel's managed default. To use the optional Prototype-2 Playwright image with preinstalled browser tooling, set WORKBENCH_SANDBOX_IMAGE to its complete immutable @sha256:<digest> reference after the publisher shares that VCR repository with the project. Workbench rejects mutable references; changing the setting affects new chats only.

The generated Vercel build applies pending database migrations before every build. Trusted workflow steps retrieve the request-scoped OIDC token automatically and broker it without exposing it to the model sandbox, so do not add AI_GATEWAY_API_KEY.

Agents

List the agent templates bundled with the installed runtime or create another agent:

cd workbench
npx workbench agent templates
npx workbench agent create bugfix --template bugfix
npx workbench agent create codex-reviewer --template bugfix --harness codex --model gpt-5.6-sol

Templates select agent behavior; --harness independently selects codex, claude-code, or pi execution. Omit --model to use that harness's generator defaults. ACP definitions stay explicit in agent.ts because their package, executable, and Gateway environment mapping are implementation-specific.

When --harness is omitted, the generated definition uses the flexible WorkflowAgent execution mode with top-level model, optional reasoningEffort, and required tools fields. With --harness, generation uses the selected HarnessAgent adapter and its native tools without adding a top-level tools object. The generic harness can rely on its native prompt:

import { defineAgent, harness } from "@lgrammel/prototype-2";

export default defineAgent({
  label: "Codex harness",
  description: "Codex Harness agent",
  execute: harness.codex,
  model: ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"],
  reasoningEffort: ["high", "medium", "low"],
  publishMode: "manual",
});

The first configured model and effort are the defaults. When an agent exposes multiple values, a human chooses once while creating a chat and Workbench keeps that choice for the chat. A behavior-specific agent can explicitly add instructions: loadAgentFile("instructions.md"); there is no implicit prompt-file discovery. harness.claudeCode and harness.pi expose their native effort controls. harness.acp accepts an exact-versioned sandbox-installed ACP implementation and declarative AI Gateway environment sources, covering runtimes without a dedicated Workbench driver. Workbench tools are optional for a harness definition; adding a top-level tools object supplements the native tools. Matching configuration resumes bounded opaque state with the current user turn, while a new or changed configuration starts a fresh native session from the full persisted transcript.

Both execution modes use the same persistent chat sandbox and publication flow. All model-controlled commands and native harness processes run as unprivileged UID 65534 without Git credentials or access to protected Git metadata; only trusted Workbench code can commit or publish.

Human chats default to main; the user can name another repository branch when creating a chat. Workbench pins the selected ref and SHA before provisioning its sandbox. A non-main chat can inspect and modify its isolated filesystem, but cannot commit or publish code and therefore must use an agent whose publishMode is manual.

Upgrade the application, inspect tool-template changes, and safely update pristine tools:

cd workbench
npm install @lgrammel/prototype-2@latest
npx workbench tool diff
npx workbench tool update

Modified or intentionally deleted tools are preserved. Commit and push the reviewed source, manifest, and lockfile changes to deploy the upgrade through Vercel.

Shell image outputs

Repository-owned tools can ask the Workbench shell to import images created by a command:

const result = await shell.run(
  'playwright screenshot http://127.0.0.1:3000 "$WORKBENCH_OUTPUT_DIR/home.png"',
  {
    outputImages: [{ path: "home.png", description: "Rendered home page" }],
  },
);

outputImages accepts up to four relative paths beneath the per-command WORKBENCH_OUTPUT_DIR. The structured result contains output, exitCode, truncated, and validated artifacts. Each artifact includes immutable metadata and a ready-to-copy Markdown image reference for the agent's final response. PNG, JPEG, and WebP are supported. The Playwright command in this example requires browser tooling from the target project or the optional custom Sandbox image; the default managed image does not guarantee it.

Automations

Automations are optional reviewed TypeScript definitions under workbench/automations/<id>/automation.ts. They are configured in code and bundled at deployment; the application provides a read-only viewer with recent execution attempts, manual Run now, retry for failed, skipped, or unsuccessful dispatched attempts, links to agent chats, and inline task and effect evidence. It does not provide an automation or task editor.

import { defineAutomation } from "@lgrammel/prototype-2";
import { z } from "zod";

const selectionSchema = z.object({
  repository: z.string(),
  task: z.string(),
});

export default defineAutomation({
  label: "Repository health check",
  description: "Implement one small, high-confidence maintenance improvement.",
  trigger: { type: "manual" },
  source: {
    description: "Configured repository and maintenance task",
    schema: selectionSchema,
    select: ({ repository }) => ({
      repository: repository.name,
      task: "Find, implement, and verify one small maintenance improvement.",
    }),
  },
  execution: {
    type: "agent",
    agentId: "default",
    messageTemplate: `Work on {{repository}}.\n\nTask:\n{{task}}`,
  },
  sourceUrlTemplate: "https://github.com/{{repository}}",
  maximumConcurrentExecutions: 1,
});

The source selector runs in trusted server/workflow code. Its result must match schema and contain only JSON data. Every {{path.to.value}} placeholder must resolve; a missing value fails the execution instead of producing a partial prompt. Selected external text remains untrusted model input. Each accepted agent execution creates a fresh chat using the selected agent's unchanged tools, applicability, publication mode, and publication policy.

An agent execution can also select a branch or GitHub pull-request checkout from that validated source. A pull-request review may declare the narrow github.pull-request-comment effect, whose trusted target callback must resolve to the checked-out pull request and whose body callback can use only validated source data and the bounded final response. Workbench applies the effect only after the agent succeeds, revalidates the open pull request at its pinned head, and records an idempotent request and receipt. Non-main and pull-request checkouts cannot publish code. See the packaged configuration reference for a complete example.

Automations choose one explicit execution:

execution:
  | { type: "agent"; agentId: string; messageTemplate: string; checkout?; effect? }
  | { type: "task"; task: ImportedTask; input: ({ source }) => TaskInput; effect?: ManagedEffect }

Existing agent definitions with top-level agentId and messageTemplate remain valid and normalize to agent execution. A task is a separate default export under workbench/tasks/<id>/task.ts:

import { defineTask } from "@lgrammel/prototype-2";
import { z } from "zod";

export default defineTask({
  label: "Classify issue",
  description: "Choose one configured issue-type label.",
  inputSchema: z.object({ title: z.string(), body: z.string() }),
  execution: {
    type: "structured-model",
    model: "openai/gpt-5.4",
    prompt: ({ input }) => `Classify this untrusted issue:\n${JSON.stringify(input)}`,
    outputSchema: z.object({ label: z.string(), rationale: z.string() }),
  },
});

The MVP supports only this pure, bounded structured-model task. It creates no chat or sandbox and receives no tools or GitHub credentials. An automation imports the task, maps validated source to its typed input, and may own the narrow github.issue-managed-label effect. Workbench persists and validates the decision before the effect, restricts the selected label to the configured managed set, preserves unrelated labels, and applies retries idempotently. See the packaged configuration reference for the complete task binding and effect. Keep a write-capable automation disabled until its managed labels and token permission are configured, then explicitly enable and redeploy it.

Agent-backed definitions can also hand work to a different deployed agent without an external coordinator; task-backed automations cannot be handoff sources or targets:

{ type: "handoff", from: { type: "automation", automationId: "implement-change" } }
{ type: "handoff", from: { type: "human", agentId: "default" } }

An automation-source handoff dispatches automatically only after the source agent succeeds and its automatic publication, if any, succeeds or is skipped and its configured agent effect succeeds. A human-source handoff appears as a follow-up suggestion after the latest eligible successful human-started run and requires a click. The result is a linked child chat whose separate persistent sandbox is an exact point-in-time fork of the source workspace. The target gets a fresh execution session and retains its own deployed instructions, tools, applicability, publication mode, and publication policy. Bounded textual and metadata context accompanies the fork, but managed artifact binaries do not.

Source and target agents must differ. Definition loading rejects missing references, automatic cycles, chains deeper than eight, and more than ten automatic handoffs from one source. Stable source-run/target-automation idempotency prevents duplicate children, and source/child lineage links remain visible. Failed or cancelled agent/publication work and failed effects do not hand off. This native coordination needs no external API call, webhook, scheduler, or GitHub event and is not a general workflow/DAG editor.

Trigger endpoints

  • Manual/API: POST /api/automations/<id>/trigger with an optional JSON body such as { "idempotencyKey": "caller-event-123", "payload": {} }. The viewer uses this endpoint only for definitions with trigger: { type: "manual" }.
  • Schedule: GET /api/automations/schedule with Authorization: Bearer <CRON_SECRET>. A scheduler tick evaluates all enabled schedule definitions; their intervalMinutes values determine stable, deduplicated time buckets. A Vercel Cron can call the endpoint and automatically sends CRON_SECRET in that header. Choose a tick frequency supported by the deployment's Vercel plan; the configuration reference includes the vercel.json configuration.
  • GitHub: POST /api/automations/github. Workbench verifies X-Hub-Signature-256 against GITHUB_WEBHOOK_SECRET, requires X-GitHub-Event and X-GitHub-Delivery, checks the configured repository, and dispatches matching event and optional actions definitions.

Deployment Protection runs before these handlers. Give automated callers a dedicated Vercel automation-bypass secret. Prefer the x-vercel-protection-bypass header; for GitHub webhooks, which cannot set arbitrary headers, append the same parameter to the webhook URL. The bypass token only gets the request through Vercel and does not replace Workbench's webhook signature or cron-secret checks. Keep all three secrets separate and out of automation source and rendered messages.

Changing, adding, or removing a definition requires review and redeployment. Updating the npm package refreshes only the package-owned runtime and never creates, rewrites, or deletes the repository's automations/ or tasks/ tree.