feat: initial project structure and generate API types
Initialized `package.json`, add tsup build config (CJS/ESM/DTS), wire up full Makefile targets (lint/test/check/build), add missing BadRequest response component to OpenAPI spec, generate TypeScript types from spec, configure biome to exclude generated files, and add `@types/ws`
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -136,3 +136,6 @@ dist
|
|||||||
.yarn/install-state.gz
|
.yarn/install-state.gz
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
|
# AI agents
|
||||||
|
.opencode
|
||||||
|
PLAN.md
|
||||||
|
|||||||
67
AGENTS.md
Normal file
67
AGENTS.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Project
|
||||||
|
|
||||||
|
Wrenn JavaScript SDK — a client library for the Wrenn microVM platform. e2b drop-in replacement.
|
||||||
|
Package name: `@wrenn/sdk`. Node.js 18+, TypeScript 5.5+, managed with [pnpm](https://pnpm.io/).
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install # install deps
|
||||||
|
make lint # biome check + format check (no auto-fix)
|
||||||
|
make test # unit tests only (vitest)
|
||||||
|
make test-integration # all tests including integration (needs live server)
|
||||||
|
make generate # regenerate types from OpenAPI spec (openapi-typescript)
|
||||||
|
make check # lint + unit test
|
||||||
|
make build # tsup build (CJS + ESM + DTS)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `make test` runs all non-integration tests. To run a specific test file: `pnpm vitest run tests/commands.test.ts`
|
||||||
|
- No separate typecheck step — `vitest` and `tsup` handle type checking during test/build. `tsc --noEmit` is available but not wired up in CI.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- `src/` — the library package
|
||||||
|
- `capsule.ts` — high-level `Capsule` class (main user-facing class)
|
||||||
|
- `client.ts` — low-level `WrennClient` with `CapsulesResource` and `SnapshotsResource`
|
||||||
|
- `commands.ts` — command execution, streaming, and background process management
|
||||||
|
- `files.ts` — filesystem operations
|
||||||
|
- `pty.ts` — interactive terminal (PTY) over WebSocket
|
||||||
|
- `exceptions.ts` — typed error hierarchy (`WrennError` base)
|
||||||
|
- `models/generated.ts` — **auto-generated** from OpenAPI spec via `openapi-typescript` (never edit directly; run `make generate`)
|
||||||
|
- `git/` — git operations inside capsules (clone, push, pull, status, branches, etc.)
|
||||||
|
- `code-interpreter/` — specialized capsule for stateful Jupyter kernel execution
|
||||||
|
- `_shared/http.ts` — thin `fetch` wrapper with auth headers, base URL, and error mapping
|
||||||
|
- `_shared/websocket.ts` — WebSocket helper wrapping `ws`
|
||||||
|
- `config.ts` — constants (`DEFAULT_BASE_URL`, env var names)
|
||||||
|
- `tests/` — unit tests use `msw` to mock HTTP; integration tests are in `tests/integration/`
|
||||||
|
- `api/openapi.yaml` — OpenAPI spec used for type generation
|
||||||
|
|
||||||
|
## Key Conventions
|
||||||
|
|
||||||
|
- Generated types live in `src/models/generated.ts`. Never edit them. Run `make generate` to update.
|
||||||
|
- No sync/async split — JS is naturally async. One `Capsule` class, all methods return `Promise`.
|
||||||
|
- `Sandbox` is a deprecated alias for `Capsule`. New code should use `Capsule`.
|
||||||
|
- Uses native `fetch` for HTTP (Node 18+), `ws` for WebSockets, `zod` for runtime validation.
|
||||||
|
- Resource disposal via `Symbol.asyncDispose` (`await using`). Also supports manual `.close()`.
|
||||||
|
- Streaming methods return `AsyncGenerator` (e.g. `commands.stream()`, `files.downloadStream()`).
|
||||||
|
- Static + instance method pattern: `capsule.destroy()` (instance) and `Capsule.destroy(id, opts)` (static).
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
- Unit tests mock HTTP via `msw` (Mock Service Worker for Node).
|
||||||
|
- Integration tests require env vars: `WRENN_API_KEY` (or `WRENN_TOKEN`), optionally `WRENN_BASE_URL`.
|
||||||
|
- Integration test fixtures in `tests/integration/setup.ts` create real capsules and clean them up.
|
||||||
|
- Tests use `vitest` — no `@jest` globals. Use `import { describe, it, expect } from 'vitest'`.
|
||||||
|
|
||||||
|
## CI
|
||||||
|
|
||||||
|
Woodpecker CI (`.woodpecker/check.yml`) runs on push to `main` and `dev`:
|
||||||
|
1. `make lint`
|
||||||
|
2. `make test`
|
||||||
|
3. `make test-integration`
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Runtime: `ws` (WebSocket), `zod` (validation). Everything else is dev-only.
|
||||||
29
Makefile
Normal file
29
Makefile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Makefile
|
||||||
|
.PHONY: generate lint test test-integration check build
|
||||||
|
|
||||||
|
SPEC_URL = "https://raw.githubusercontent.com/wrennhq/wrenn/refs/heads/main/internal/api/openapi.yaml"
|
||||||
|
SPEC_PATH = "api/openapi.yaml"
|
||||||
|
|
||||||
|
generate:
|
||||||
|
@echo "Fetching latest OpenAPI spec from Git repo..."
|
||||||
|
mkdir -p api
|
||||||
|
curl -fsSL $(SPEC_URL) -o $(SPEC_PATH)
|
||||||
|
@echo "Generating TypeScript types..."
|
||||||
|
mkdir -p src/models
|
||||||
|
pnpm generate
|
||||||
|
|
||||||
|
lint:
|
||||||
|
pnpm exec biome check .
|
||||||
|
|
||||||
|
test:
|
||||||
|
pnpm vitest run --exclude tests/integration
|
||||||
|
|
||||||
|
test-integration:
|
||||||
|
pnpm test:integration
|
||||||
|
|
||||||
|
check:
|
||||||
|
$(MAKE) lint
|
||||||
|
$(MAKE) test
|
||||||
|
|
||||||
|
build:
|
||||||
|
pnpm build
|
||||||
3174
api/openapi.yaml
Normal file
3174
api/openapi.yaml
Normal file
File diff suppressed because it is too large
Load Diff
35
biome.json
Normal file
35
biome.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://biomejs.dev/schemas/2.4.14/schema.json",
|
||||||
|
"vcs": {
|
||||||
|
"enabled": true,
|
||||||
|
"clientKind": "git",
|
||||||
|
"useIgnoreFile": true
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"ignoreUnknown": false,
|
||||||
|
"includes": ["**", "!src/models/generated.ts", "!dist"]
|
||||||
|
},
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"indentStyle": "tab"
|
||||||
|
},
|
||||||
|
"linter": {
|
||||||
|
"enabled": true,
|
||||||
|
"rules": {
|
||||||
|
"recommended": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"quoteStyle": "double"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"assist": {
|
||||||
|
"enabled": true,
|
||||||
|
"actions": {
|
||||||
|
"source": {
|
||||||
|
"organizeImports": "on"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
package.json
Normal file
44
package.json
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "js-sdk",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Wrenn JavaScript SDK — a client library for the Wrenn microVM platform.",
|
||||||
|
"type": "module",
|
||||||
|
"main": "./dist/cjs/index.js",
|
||||||
|
"module": "./dist/esm/index.js",
|
||||||
|
"types": "./dist/dts/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/dts/index.d.ts",
|
||||||
|
"import": "./dist/esm/index.js",
|
||||||
|
"require": "./dist/cjs/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsup",
|
||||||
|
"check": "make lint && make test",
|
||||||
|
"test": "vitest run",
|
||||||
|
"lint": "make lint",
|
||||||
|
"test:watch": "vitest",
|
||||||
|
"test:integration": "vitest run --config vitest.integration.config.ts",
|
||||||
|
"generate": "openapi-typescript api/openapi.yaml --output src/models/generated.ts",
|
||||||
|
"format": "biome format --write ."
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"packageManager": "pnpm@10.26.1",
|
||||||
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "^2.4.14",
|
||||||
|
"@types/node": "^25.6.0",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
|
"msw": "^2.14.3",
|
||||||
|
"openapi-typescript": "^7.13.0",
|
||||||
|
"tsup": "^8.5.1",
|
||||||
|
"typescript": "^6.0.3",
|
||||||
|
"vitest": "^4.1.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ws": "^8.20.0",
|
||||||
|
"zod": "^4.4.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
2321
pnpm-lock.yaml
generated
Normal file
2321
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
4252
src/models/generated.ts
Normal file
4252
src/models/generated.ts
Normal file
File diff suppressed because it is too large
Load Diff
45
tsconfig.json
Normal file
45
tsconfig.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Visit https://aka.ms/tsconfig to read more about this file
|
||||||
|
"compilerOptions": {
|
||||||
|
// File Layout
|
||||||
|
// "rootDir": "./src",
|
||||||
|
// "outDir": "./dist",
|
||||||
|
|
||||||
|
// Environment Settings
|
||||||
|
// See also https://aka.ms/tsconfig/module
|
||||||
|
"module": "nodenext",
|
||||||
|
"target": "esnext",
|
||||||
|
"types": [],
|
||||||
|
// For nodejs:
|
||||||
|
// "lib": ["esnext"],
|
||||||
|
// "types": ["node"],
|
||||||
|
// and npm install -D @types/node
|
||||||
|
|
||||||
|
// Other Outputs
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
|
||||||
|
// Stricter Typechecking Options
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"exactOptionalPropertyTypes": true,
|
||||||
|
|
||||||
|
// Style Options
|
||||||
|
// "noImplicitReturns": true,
|
||||||
|
// "noImplicitOverride": true,
|
||||||
|
// "noUnusedLocals": true,
|
||||||
|
// "noUnusedParameters": true,
|
||||||
|
// "noFallthroughCasesInSwitch": true,
|
||||||
|
// "noPropertyAccessFromIndexSignature": true,
|
||||||
|
|
||||||
|
// Recommended Options
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noUncheckedSideEffectImports": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"ignoreDeprecations": "6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
tsup.config.ts
Normal file
11
tsup.config.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { defineConfig } from "tsup";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
entry: ["src/index.ts"],
|
||||||
|
format: ["cjs", "esm"],
|
||||||
|
dts: { resolve: true },
|
||||||
|
outDir: "dist",
|
||||||
|
clean: true,
|
||||||
|
sourcemap: true,
|
||||||
|
minify: false,
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user