Open workflow system

Extend the same workflow model your team already trusts.

Add capabilities, not side systems. The SDK and plugin surface extend the same runtime, trace model, and verification structure across GraphQL, browser steps, internal clients, and your own domain logic.

repo-native TypeScriptfirst-class pluginsshared configure() runtimeone model across surfaces

Real TypeScript

Keep extending real workflows your team can review, refactor, and keep in the repo.

First-class plugins

Add GraphQL, browser steps, auth helpers, or internal clients without inventing side systems.

One workflow model

Local runs, CI, browser steps, and Cloud all extend the same runtime and verification structure.

Why the runtime matters

The core SDK already gives you the parts most teams need: requests, assertions, secrets, templating, and structured traces. Plugins build on top of that runtime instead of pushing you into a second system.

products.test.ts
import { test } from "@glubean/sdk";

test("list products", async (ctx) => {
  const base = ctx.vars.require("BASE_URL");

  const data = await ctx.http
    .get(`${base}/products?limit=5`)
    .json();

  ctx.expect(data.products.length).toBe(5);
  ctx.log(`Found ${data.total} products`);
});
Core: Auto-traced HTTP requests with timing and status
Core: Template variables and secrets resolved per environment
Core: Structured assertions with useful diffs on failure
Core: Shared helpers that stay plain TypeScript
Core: Secrets auto-redacted before upload to Cloud

Why plugins matter

Use official packages when they fit, then add your own organization-specific capabilities without leaving the workflow system. The point is not a pile of adapters. The point is one runtime that absorbs more of your stack over time.

@glubean/graphql

Ground GraphQL queries and mutations in the same traced workflow you already use for HTTP.

@glubean/browser

Extend the same workflow into Puppeteer-powered browser steps without losing structure.

@glubean/grpc

Typed gRPC client with proto-first DX, full trace and metadata capture out of the box.

@glubean/auth

OAuth, API key, and custom auth flows as a shared plugin — configure once, use everywhere.

Your own plugin

Wrap internal services, auth flows, or domain helpers as reusable capabilities for the whole team.

GraphQL stays inside the same trace model

users.test.ts
import { test, configure } from "@glubean/sdk";
import { graphql } from "@glubean/graphql";

const { gql } = configure({
  plugins: {
    gql: graphql({
      endpoint: "{{GRAPHQL_URL}}",
      headers: { Authorization: "Bearer {{API_KEY}}" },
    }),
  },
});

export const getUser = test("get-user", async (ctx) => {
  const { data } = await gql.query<{ user: { name: string } }>(`
    query GetUser($id: ID!) {
      user(id: $id) { name email }
    }
  `, { variables: { id: "1" } });

  ctx.expect(data?.user.name).toBe("Alice");
});

Browser steps extend the same workflow into Puppeteer

login.test.ts
import { test, configure } from "@glubean/sdk";
import { browser } from "@glubean/browser";

const { chrome } = configure({
  plugins: { chrome: browser({ launch: true }) },
});

const ui = test.extend({
  page: async (ctx, use) => {
    const pg = await chrome.newPage(ctx);
    try { await use(pg); }
    finally { await pg.close(); }
  },
});

export const login = ui("login-flow", async (ctx) => {
  await ctx.page.goto("/login");
  await ctx.page.type("#email", "user@test.com");
  await ctx.page.type("#password", "secret");
  await ctx.page.clickAndNavigate('button[type="submit"]');
  await ctx.page.expectURL("/dashboard");
  await ctx.page.expectText("h1", "Welcome back");
});

Why custom plugins matter

Wrap an internal service client, auth helper, or domain-specific workflow primitive once, then reuse it everywhere. This is the difference between a convenient test file and a verification system that compounds.

payments-plugin.ts
import { definePlugin, configure, test } from "@glubean/sdk";

const payments = (opts: { baseUrlKey: string }) =>
  definePlugin((runtime) => {
    const client = runtime.http.extend({
      prefixUrl: runtime.requireVar(opts.baseUrlKey),
      headers: {
        Authorization: `Bearer ${runtime.requireSecret("STRIPE_KEY")}`,
      },
    });
    return {
      charge: (amount: number) =>
        client.post("charges", { json: { amount } }).json(),
      refund: (id: string) =>
        client.post(`charges/${id}/refund`).json(),
    };
  });

const { pay } = configure({
  plugins: { pay: payments({ baseUrlKey: "PAYMENTS_URL" }) },
});

export const chargeAndRefund = test("charge-refund", async (ctx) => {
  const charge = await pay.charge(2500);
  ctx.expect(charge.status).toBe("succeeded");

  const refund = await pay.refund(charge.id);
  ctx.expect(refund.status).toBe("refunded");
});
Plugins receive runtime context, including vars, secrets, and the traced HTTP client
Initialization stays lazy, so setup cost lands only when the plugin is used
Types flow through configure() without casts or wrapper DSLs
Official and custom plugins compose into one runtime for the whole workflow

Why one runtime matters

Official packages and custom plugins join in one configure() call. That keeps the workflow surface consistent across local runs, CI, and Cloud.

configure.ts
const { gql, chrome, pay } = configure({
  plugins: {
    gql:    graphql({ endpoint: "{{GQL_URL}}" }),
    chrome: browser({ launch: true }),
    pay:    payments({ baseUrlKey: "PAY_URL" }),
  },
});
Shared auth, clients, and plugin setup live in one place
Workflow files stay small because heavy setup moves into configure()
The same runtime can power extension authoring, CI runs, and Cloud history

Runtime note: Node.js, plugin-friendly

Glubean runs on Node.js with native TypeScript support — no build step required. The entire npm ecosystem is available, so any package you already use works out of the box. The practical rule is simple: if you can import it, it is a good plugin candidate. When you need heavier browser coverage, keep Playwright where it fits and use Glubean where the shared workflow model matters more.