Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 90 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ A common agent flow asks jev-code to find relevant files before editing, check c
it into small, size-limited pieces, such as one changed block of a file or one failure from a log.
3. **Exact checks run first.** Plain rules catch things like an added `test.skip`, deleted assertions,
deleted test files, and lockfile, CI or config changes.
4. **Jev answers fixed-choice questions about each piece.** Using your required TypeSafe API key, jev-code asks
4. **Jev answers fixed-choice questions about each piece.** Using your Jev credential (TypeSafe API key,
an AI Gateway key with `JEV_PROVIDER=vercel`, or Cloudflare account id + API token with
`JEV_PROVIDER=cloudflare`), jev-code asks
[TypeSafe Jev](https://typesafe.ai), a model that answers multiple-choice questions, about one small piece
at a time. For example: "How closely is this changed block related to the task?" jev-code's own code, not
the model, turns the answers into flags using fixed thresholds.
Expand All @@ -47,7 +49,9 @@ A common agent flow asks jev-code to find relevant files before editing, check c
> **Release status:** the `jev-code` package on npm is `0.0.1`, a placeholder with no working commands.
> This README describes `0.1.0`, which is not released yet. Until it is, build from source.

**Requirements:** Node.js 22.18 or newer, `git`, a Git repository to check, and a TypeSafe API key. CI tests on Linux; Windows is untested.
**Requirements:** Node.js 22.18 or newer, `git`, a Git repository to check, and a Jev credential:
either a TypeSafe API key (default provider) or an AI Gateway key (`JEV_PROVIDER=vercel`), per the
[Jev providers](#jev-providers) section. CI tests on Linux; Windows is untested.

**Install** (from source, until 0.1.0 is on npm):

Expand All @@ -61,10 +65,14 @@ node dist/cli.js --help # use "node /path/to/jev-code/dist/cli.js" wherever th

After 0.1.0 is released: `npm install --global jev-code`.

**API key.** jev-code reads the required key only from this environment variable, never from files or flags:
**API key.** jev-code reads the required key only from environment variables, never from files or flags. Which key it needs depends on the provider (see below):

```sh
export TYPESAFE_API_KEY="<your TypeSafe API key>"
export TYPESAFE_API_KEY="<your TypeSafe API key>" # default provider (or see Jev providers
# for the Vercel/Cloudflare alternatives)
export AI_GATEWAY_API_KEY="<your gateway key>" # JEV_PROVIDER=vercel
export CLOUDFLARE_ACCOUNT_ID="<your account id>" # JEV_PROVIDER=cloudflare
export CLOUDFLARE_API_TOKEN="<your API token>" # JEV_PROVIDER=cloudflare
```

**Example.** An agent was asked to fix a crash. It did, but it also skipped the test and removed an assertion.
Expand Down Expand Up @@ -170,7 +178,7 @@ There is no `pass` or `approved` result. Run `jev-code --help` for exit-code mea

By default, run records are saved under `.jev-code/runs/<run-id>/`. They can contain code and log lines, so they are private to your user and ignored by Git. Use `--no-persist` to disable them.

jev-code first sends TypeSafe the redacted request, input shape, diff presence, available capabilities and option names for routing. The selected workflow then sends only the task and bounded evidence it needs, such as changed blocks or short failure-log sections. Obvious secret files and common token formats are filtered on a best-effort basis, but jev-code is not a secret scanner. Review TypeSafe's data terms before sending private or regulated code.
jev-code first sends TypeSafe the redacted request, input shape, diff presence, available capabilities and option names for routing. The selected workflow then sends only the task and bounded evidence it needs, such as changed blocks or short failure-log sections. Obvious secret files and common token formats are filtered on a best-effort basis, but jev-code is not a secret scanner. With the default provider, requests go to TypeSafe; with `JEV_PROVIDER=vercel`, requests additionally pass through the Vercel AI Gateway, which processes them even under zero-data-retention routing; with `JEV_PROVIDER=cloudflare`, requests additionally pass through Cloudflare infrastructure. Review the gateway's or Cloudflare's and the upstream provider's data terms before sending private or regulated code.

jev-code does not replace tests, type checks, linters, security tools, or human review.

Expand All @@ -187,10 +195,85 @@ npm run smoke # runs the built CLI in a temporary Git repository with
npm run check:package # package manifest and file-list checks used by the release workflow
```

`node scripts/smoke-real.ts` makes a few real Jev requests after `npm run build`; it skips itself without
`TYPESAFE_API_KEY`. See [docs/architecture.md](docs/architecture.md) for how the code is organized and
`npm run smoke:real` makes a few real TypeSafe Jev requests after `npm run build`; it skips itself
without `TYPESAFE_API_KEY`. `npm run smoke:vercel` performs one minimal real Jev evaluation through
the Vercel AI Gateway; it requires `JEV_SMOKE=1` and `AI_GATEWAY_API_KEY` and skips itself otherwise.
`npm run smoke:cloudflare` performs one minimal real Jev evaluation through Cloudflare Workers AI;
it requires `JEV_SMOKE=1`, `CLOUDFLARE_ACCOUNT_ID`, and a Cloudflare API token
(`CLOUDFLARE_API_TOKEN` or `JEV_CLOUDFLARE_API_TOKEN`) and skips itself otherwise, so no live test
is part of `npm run check`. See [docs/architecture.md](docs/architecture.md) for how the code is organized and
[docs/RELEASING.md](docs/RELEASING.md) for how releases are published.

## Jev providers

Jev inference is pluggable. All providers expose the same Jev/System One capability to the review
engine through the same request/response schema, so workflows and reports are provider-independent.
The providers are different services, though: when a proxy does not report TypeSafe's separate
confidence statistic, confidence is synthesized from the distribution and threshold-gated decisions
can differ from TypeSafe-direct (see below). Selection is entirely through configuration, at start:

```sh
export JEV_PROVIDER=typesafe # default: direct TypeSafe API
export TYPESAFE_API_KEY="<key>"
```

or

```sh
export JEV_PROVIDER=vercel # Vercel AI Gateway hosting of Jev
export AI_GATEWAY_API_KEY="<key>" # canonical variable read by the ai package
```

or

```sh
export JEV_PROVIDER=cloudflare # Cloudflare Workers AI hosting of Jev
export CLOUDFLARE_ACCOUNT_ID="<your Cloudflare account id>"
export CLOUDFLARE_API_TOKEN="<your Cloudflare API token>"
# JEV_CLOUDFLARE_API_TOKEN may be used as an application-specific alias for the
# token; when both are set, the alias wins.

jev-code \
"Check the current changes against the user's task" \
--task-file task.md \
--json
```

An invalid `JEV_PROVIDER` name fails immediately at startup (exit 64), not halfway through a review.

**Model selection.** `--model` / `TYPESAFE_MODEL` select the TypeSafe-direct model for the default
provider. The Vercel provider runs in the gateway's model namespace: TypeSafe-direct ids
(`jev-1.13.0`) are a different namespace and are never forwarded — an unqualified id falls back to
the configured gateway model, and a slash-qualified gateway id (`typesafe-ai/jev-preview`) is
honored. The gateway model itself is configured with `JEV_GATEWAY_MODEL` (default `typesafe-ai/jev`,
the canonical Jev id on the Vercel AI Gateway). The Cloudflare provider likewise runs in Cloudflare's
own model namespace, which currently exposes Jev through the always-current alias `typesafe/jev`
rather than TypeSafe's pinned versions: unqualified ids are never forwarded, and only
`typesafe/`-qualified ids pass through. The alias is configurable with `JEV_CLOUDFLARE_MODEL`
(default `typesafe/jev`).

**Zero data retention.** Evaluations can contain repository source code and diffs, so the Vercel
provider routes only to providers with zero data retention agreements
(`providerOptions.gateway.zeroDataRetention = true`) by default. Set
`JEV_GATEWAY_ZERO_DATA_RETENTION=0` only for troubleshooting. The Cloudflare provider has no
equivalent routing flag: requests pass through Cloudflare infrastructure, and jev-code makes no
data-retention claim for that path — review Cloudflare's and TypeSafe's data/privacy terms before
sending private source code.

Differences worth knowing:

- TypeSafe's separate per-question confidence statistic is preserved from gateway responses
(`providerMetadata.typesafe.confidence`, Choice/Score questions) and from Cloudflare's native Jev
answers (`confidence`). When that statistic is genuinely unavailable, the provider falls back to a
value derived from the reported distribution (the mass of the selected choice, or the maximum
level mass for score) — an approximation, not the model's own confidence, so threshold-gated
decisions can differ from TypeSafe-direct in that case.
- Noul/boolean answers carry probability only; TypeSafe reports no separate confidence for them.
Cloudflare speaks Jev's native contract, so unlike Vercel it needs no boolean translation.
- Usage numbers come from the gateway or from Cloudflare; when they are omitted, input usage is
reported as a conservative estimate of the request size (the same estimate the input-token budget
reserves), and output usage as zero.

## TypeSafe

Jev and TypeSafe are products of TypeSafe. jev-code is an independent open-source project and is **not**
Expand Down
10 changes: 7 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ higher folder supplies the implementation. `test/architecture.test.ts` scans eve
| ----------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `core` | Send structured questions to Jev safely: validate answers, enforce budgets, batch, retry | npm packages, `fs`, `child_process`, the SDK; only `node:` built-ins |
| `workflows` | Product logic: gather evidence, run exact checks, ask questions, turn answers into a report | any package or Node built-in, `process.env`, the SDK |
| `adapters` | Real implementations of the ports: read-only Git, file reads, parsers, redaction, SDK client | the `cli` folder |
| `adapters` | Real implementations of the ports: read-only Git, file reads, parsers, redaction, Jev providers (TypeSafe SDK, Vercel AI Gateway, Cloudflare Workers AI) | the `cli` folder |
| `cli` | Parse arguments, wire adapters into workflows, print output, choose the exit code | nothing |

`src/cli.ts` (the `jev-code` binary) and `src/index.ts` (package exports) belong to `cli`. Every other
Expand All @@ -27,8 +27,12 @@ production file must live in one of the four folders. Tests and scripts may impo

Using `check` as the example:

1. **cli** parses the natural-language request and flags, reads `TYPESAFE_API_KEY` and `TYPESAFE_MODEL`
through `adapters/config.ts`, and builds the dependencies in `adapters/dependencies.ts`.
1. **cli** parses the natural-language request and flags, reads `JEV_PROVIDER`, `TYPESAFE_API_KEY`,
`AI_GATEWAY_API_KEY`, `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_API_TOKEN` and `TYPESAFE_MODEL`
through `adapters/config.ts`, and builds the dependencies
in `adapters/dependencies.ts`. The provider factory selects `TypeSafeJevProvider` (direct API,
default), `VercelJevProvider` (Vercel AI Gateway), or `CloudflareJevProvider` (Cloudflare Workers
AI REST run endpoint); unknown provider names fail at startup.
2. **routing** (`cli/router.ts`) receives the redacted request plus deterministic context: diff presence,
input shape, available capabilities, and supplied option names. One validated choice selects `find`,
`check`, `triage_failures`, `triage_comments`, or `cannot_tell`. Fixed confidence and capability gates turn
Expand Down
123 changes: 122 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@
"format": "biome format --write .",
"test": "node --test --test-reporter=spec \"test/**/*.test.ts\"",
"smoke": "node scripts/smoke-cli.ts",
"smoke:real": "node scripts/smoke-real.ts",
"smoke:vercel": "node scripts/smoke-vercel.ts",
"smoke:cloudflare": "node scripts/smoke-cloudflare.ts",
"check": "npm run lint && npm run typecheck && npm test && npm run build && npm run smoke",
"check:package": "npm run build && node scripts/release.ts manifest && node scripts/release.ts pack --dry-run"
},
"dependencies": {
"@typesafe-ai/sdk": "0.6.0"
"@typesafe-ai/sdk": "0.6.0",
"ai": "7.0.107"
},
"devDependencies": {
"@biomejs/biome": "2.5.14",
Expand Down
Loading