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

archal

v0.9.19

Published

Test your agents & integrations against service clones

Downloads

1,012

Readme

archal

Pre-deployment testing for AI agents via Archal's hosted service clones, including route-mode clones for Discord, GitHub, Slack, Stripe, Linear, Jira, Ramp, Apify, Tavily, Supabase, and Google Workspace.

Known compatibility notes

  • npm install -g archal may print peer-dependency warnings from the vendored CLI runtime. These are safe to ignore; all required modules are bundled.
  • The vitest integration under archal/vitest requires vitest@^2.1.0. Projects on vitest 3 should pin a workspace to vitest 2 for Archal tests to avoid duplicate module resolution.

File issues at https://github.com/Archal-Labs/archal/issues.

Install

npm install -g archal

Then authenticate:

archal login

This writes credentials to ~/.archal/credentials.json. You can also set ARCHAL_TOKEN directly in CI. Use a workspace API key (archal_ws_...) for CI instead of a personal token.

Workspace API keys are runtime and CI credentials bound to one workspace. They can run clones, upload and read traces, and read usage for that workspace. They cannot manage audit events or workspace API keys. Use an owner/admin user credential, either archal login or a dashboard-issued user API key, for workspace administration.

CLI

The CLI is the primary interface. archal run executes a scenario (a markdown file describing a task, the expected behavior, and success criteria) against a hosted clone session and reports a satisfaction score.

Quick start

# 1. Log in
archal login

# 2. Initialize your project
archal init

# 3. Edit .archal/harness.mjs to call your agent

# 4. Run the starter scenario from .archal.json
archal run

archal init creates .archal.json, .archal/harness.mjs, and scenarios/first-run.md. The generated harness is a guarded stub: Archal refuses to run it until you edit the file to call your real agent, so a first run cannot be scored from placeholder text.

archal run auto-discovers an .archal.json at the project root. A minimal config looks like this:

{
  "agent": {
    "command": "node",
    "args": [".archal/harness.mjs"]
  },
  "scenarios": ["scenarios/first-run.md"],
  "clones": ["github", "stripe"],
  "runs": 1
}

Supported clones

archal clone lists the eleven clones available today:

| Clone | Notes | |---|---| | Discord | Guilds, channels, messages, members | | GitHub | Repos, issues, PRs, labels, reviews | | Slack | Channels, messages, users, reactions | | Stripe | Customers, subscriptions, invoices, products | | Linear | Teams, issues, projects, cycles | | Jira | Projects, issues, workflows, components | | Ramp | Cards, transactions, reimbursements, users | | Apify | Actors, tasks, runs, datasets | | Tavily | Search and extraction responses | | Supabase | Auth, Postgres, storage, edge functions | | Google Workspace | Gmail, Drive, Calendar, Docs, People |

Command reference

| Command | What it does | |---|---| | archal login | Authenticate with Archal | | archal logout | Remove stored credentials | | archal clone | Browse the clone catalog | | archal clone start [clones...] | Start a hosted clone session | | archal clone status | Inspect the active session | | archal clone stop | Stop the active session | | archal clone list | List all your active sessions | | archal clone attach <uuid> | Reattach to a session by id | | archal clone renew <seconds> | Extend the session lifetime | | archal clone reset | Reset clone state without tearing down the session | | archal clone seed <clone> <name> | Load a named seed into a running clone | | archal run [scenario] | Run a scenario file (or use --config for .archal.json) | | archal scenario list | Browse local and hosted scenarios | | archal seed list [clone] | List prebuilt clone seeds | | archal trace | View recent scenario traces | | archal trace <name> | View trace details for a run | | archal usage | Check active workspace session-minutes and plan |

Run archal <command> --help for flag details.

Vitest integration (secondary use case)

You can also import archal/vitest to route SDK traffic from a vitest suite through a hosted clone, with no code changes to your production code. This is useful if you want to test the HTTP side of an integration without hitting real provider APIs.

The vitest helper supports the hosted route-mode clone catalog: Apify, Discord, GitHub, Google Workspace, Jira, Linear, Ramp, Slack, Stripe, Supabase, and Tavily. If you only need scenario-level evaluation, the CLI flow above is simpler to set up.

Minimal config

import { defineConfig } from 'vitest/config';
import { withArchal } from 'archal/vitest';

export default defineConfig({
  test: withArchal(
    {
      // everything you already had in test:, unchanged
      globals: true,
      coverage: { provider: 'v8' },
    },
    {
      services: {
        stripe: { mode: 'route', seed: 'small-business' },
      },
    },
  ),
});

withArchal(existingTest, { services }) wraps an existing vitest.config.ts's test: block, preserving every field you already had. Pass {} as the first argument if you're starting from scratch.

Your existing tests work unchanged:

import { it, expect } from 'vitest';
import Stripe from 'stripe';

it('creates a customer', async () => {
  const stripe = new Stripe('sk_test_fake');        // fake key is fine
  const customer = await stripe.customers.create({  // goes to clone, not real Stripe
    email: '[email protected]',
  });
  expect(customer.id).toMatch(/^cus_/);
});

Per-test state isolation

import { beforeEach } from 'vitest';
import { resetArchalClones } from 'archal/vitest';

beforeEach(async () => {
  await resetArchalClones();
});

Webhook testing

The hosted clone runs in AWS ECS, so it can't POST to your localhost. Instead, your test pulls queued deliveries with waitForArchalWebhook() and invokes your handler directly with the exact payload the clone would have sent.

import { it, expect } from 'vitest';
import Stripe from 'stripe';
import { waitForArchalWebhook } from 'archal/vitest';
import { handleStripeWebhook } from './src/webhooks';

const stripe = new Stripe('sk_test_fake');

it('records a subscription when customer.subscription.created fires', async () => {
  // 1. Register a webhook endpoint (the clone needs to know what events to queue)
  await stripe.webhookEndpoints.create({
    url: 'http://test.local/stripe-wh',
    enabled_events: ['customer.subscription.created'],
  });

  // 2. Trigger the event
  const customer = await stripe.customers.create({ email: '[email protected]' });
  const sub = await stripe.subscriptions.create({
    customer: customer.id,
    items: [{ price: 'price_existing_in_seed' }],
  });

  // 3. Pull the queued delivery
  const event = await waitForArchalWebhook('stripe', 'customer.subscription.created');
  expect(event.payload.data.object.id).toBe(sub.id);

  // 4. Invoke your handler with the exact payload
  await handleStripeWebhook(event.body, event.headers['Stripe-Signature'], process.env.STRIPE_WEBHOOK_SECRET);
});

Webhook coverage:

| Service | Support | Notes | |---|---|---| | Stripe | ✅ | | | GitHub | ✅ | | | Slack | ✅ | Receiver-side signature only | | Jira | ✅ | Delivered via history buffer (also POSTed to registered URLs) | | Linear | ✅ | Delivered via history buffer (also POSTed to registered URLs) | | Supabase | ❌ | Database-triggered; test against real Postgres | | Google Workspace | ❌ | GCP Pub/Sub push notifications, not webhooks |

Parallel workers caveat: waitForArchalWebhook() consumes deliveries from a shared queue by default. When vitest runs test files in parallel across workers, worker A can swallow worker B's event. If your tests depend on webhook events, set testIsolation: 'serial' in your config.

Test isolation across parallel workers

Each vitest worker is routed to its own per-worker state on the clone, so parallel tests across workers don't see each other's writes. The integration reads VITEST_WORKER_ID in each worker process and tags every outbound SDK request with an X-Archal-Worker-Id header. The clone maintains a separate state engine per worker id, seeded from the baseline on first request.

Isolation-enabled clones: Stripe, GitHub, Slack, Jira, Linear.

Clones without isolation (Supabase, Google Workspace, Ramp) fall back to shared state. If your tests depend on global assertions against those clones, set testIsolation: 'serial'.

Authentication

In priority order:

  1. ARCHAL_TOKEN env var
  2. Stored credentials from archal login in ~/.archal/credentials.json

This auth is only for Archal's hosted session provisioning. Your app's provider credentials do not need to be real when traffic is routed through a clone. Use placeholder tokens that satisfy the SDK's local validation rules, such as sk_test_fake, ghp_fake_token_for_clone, or a dummy Google bearer token.

What you'll see in the terminal

On the first archal run, session provisioning takes about 30 seconds (ECS Fargate cold start). A progress line prints every few seconds so the wait is visible:

[archal] provisioning stripe clone... 5s
[archal] provisioning stripe clone... 10s
...

Subsequent runs with the same configuration reuse the warm session (~2 seconds).

At the end of every run, the estimated workspace session-minute usage is printed:

[archal] ~2 clone-minutes for this run (38.5s × 1 clone: stripe)

Docs

Full documentation: https://docs.archal.ai