# Fystash

Fystash Bijection component — Sandbox → Revision → Branch → Run → Evidence from Bijection actions.

- Package: @bijectionhq/fystash
- Category: AI & Agents
- Status: Preview
- License: Apache-2.0
- Bijection source (repository access required): https://github.com/bijectionhq/fystash/tree/d7344138c1b1b8173d55a3ca6f247d2a0c5f0041
- Upstream: https://github.com/fystash/convex-component/tree/5c54a99856b3dc6adda379981113a9c4ef4837a9
- Documentation: https://docs.bijection.com/components/using
- Directory: https://bijection.com/components/fystash

## Get the source

Bijection repository access is required. Request access at https://bijection.com/contact.

```sh
git clone https://github.com/bijectionhq/fystash.git
cd fystash
git checkout d7344138c1b1b8173d55a3ca6f247d2a0c5f0041
```

## Before using this component

Read the package README at the recorded revision for setup, dependencies, and API examples. Upstream documentation describes the original package and may differ from the Bijection adaptation. This is a source candidate for evaluation. Catalog inclusion does not establish npm availability or runtime qualification. Check compatibility with your SDK and deployment before adoption. External providers run their own compute.

## Upstream package documentation

Recorded 2026-10-23. This describes @fystash/convex; check the Bijection adaptation separately.

The Fystash component wraps the Fystash AI sandbox API for use inside Convex actions, exposing a typed client that manages the full sandbox lifecycle: start, exec, evidence collection, and stop. It handles authentication and API configuration through Convex's component environment system, keeping credentials isolated from the host app. Developers get a structured interface over Fystash's Sandbox, Revision, Branch, Run, and Evidence model without writing raw HTTP calls.

### Use cases

- Running automated test suites (e.g., pytest) inside an isolated Fystash sandbox triggered by a Convex action, then collecting pass/fail evidence
- Orchestrating infrastructure plan approval workflows where a sandbox must be started, a plan generated and approved, and the result recorded before teardown
- Integrating Fystash sandbox execution into Convex mutation pipelines where the sandbox result feeds downstream database writes or queries
- Listing previously recorded sandboxes from a Convex query for audit or status display in an application UI
- Using the granular catalog step API (compile, createBranch, plan, approvePlan, apply, waitReady) when finer control over the sandbox lifecycle is required than startSandbox provides

### How it works

The component is registered in `convex/convex.config.ts` using `app.use(fystash, { env: { ... } })`, which explicitly threads `FYSTASH_API_URL`, `FYSTASH_ACCESS_TOKEN`, and `FYSTASH_PROJECT_ID` from the host app's environment into the component's isolated scope. Because Convex components cannot read the host app's environment variables directly, this explicit forwarding is required.

The primary client is instantiated with `new Fystash(components.fystash)` and used inside Convex actions. The high-level path is `startSandbox` (requires an `approver` argument, no silent plan approval) followed by `exec`, `listEvidence`, and `stop` with an outcome value. All sandbox interaction methods are actions because they make outbound HTTP calls to the Fystash public API via `@fystash/sdk`.

A lower-level catalog API is also available for cases requiring step-by-step control: `compile`, `createBranch`, `plan`, `approvePlan`, `apply`, `waitReady`, `exec`, `listEvidence`, and `stop`. This gives developers explicit control at each stage of the Fystash lifecycle. Listing recorded sandboxes uses `fystash.listSandboxes(ctx)`, which is a Convex query rather than an action since it reads from local state rather than calling the external API.

### Upstream README

# @fystash/convex

Convex component for [Fystash](https://fystash.ai) — start a Sandbox from a
Convex action, then exec, list Evidence, and stop.

Canonical lifecycle: **Sandbox → Revision → Branch → Run → Evidence**.

`0.2.0` replaces the scrapped rooms/spawn API. Do not call `createRoom`,
`spawn`, `runFleet`, or `destroy`. `@fystash_ai/convex@0.1.x` is deprecated.

Uses [`@fystash/sdk`](https://www.npmjs.com/package/@fystash/sdk).

## Install

```bash
npm i @fystash/convex@^0.2.0 @fystash/sdk
```

```ts
// convex/convex.config.ts
import { defineApp } from "convex/server";
import { v } from "convex/values";
import fystash from "@fystash/convex/convex.config.js";

const app = defineApp({
  env: {
    FYSTASH_API_URL: v.optional(v.string()),
    FYSTASH_ACCESS_TOKEN: v.optional(v.string()),
    FYSTASH_PROJECT_ID: v.optional(v.string()),
  },
});
app.use(fystash, {
  env: {
    FYSTASH_API_URL: app.env.FYSTASH_API_URL,
    FYSTASH_ACCESS_TOKEN: app.env.FYSTASH_ACCESS_TOKEN,
    FYSTASH_PROJECT_ID: app.env.FYSTASH_PROJECT_ID,
  },
});
export default app;
```

Set on the Convex deployment (or `.env.local` for `convex dev`):

```
FYSTASH_API_URL=https://api.fystash.ai/v1
FYSTASH_ACCESS_TOKEN=…
FYSTASH_PROJECT_ID=proj_…
```

Components are isolated from app env — pass `FYSTASH_*` through `app.use`.
The component never reads `~/.fystash/credentials.json`.

## Use

```ts
// convex/sandboxes.ts
import { action } from "./_generated/server";
import { components } from "./_generated/api";
import { Fystash } from "@fystash/convex";
import { v } from "convex/values";

const fystash = new Fystash(components.fystash);

export const hello = action({
  args: { manifest: v.string(), approver: v.string() },
  handler: async (ctx, { manifest, approver }) => {
    const sandbox = await fystash.startSandbox(ctx, { manifest, approver });
    const exec = await fystash.exec(ctx, {
      runId: sandbox.runId,
      argv: ["pytest", "-q"],
    });
    const evidence = await fystash.listEvidence(ctx, { runId: sandbox.runId });
    await fystash.stop(ctx, { runId: sandbox.runId, outcome: "succeeded" });
    return { sandbox, exec, evidence };
  },
});
```

`startSandbox` requires `approver`. It will not silently approve a Plan.

Or call the catalog steps: `compile` → `createBranch` → `plan` → `approvePlan` →
`apply` → `waitReady` → `exec` → `listEvidence` → `stop`.

Fystash calls are Convex **actions** (they hit the public API). Listing recorded
sandboxes is a query: `fystash.listSandboxes(ctx)`.

## Develop (this repo)

```bash
npm i
npm run build:codegen
```

Example app: `example/`.