Skip to content
Merged
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
7 changes: 5 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Add common bun installation paths to PATH
export PATH="/opt/homebrew/bin:$HOME/.bun/bin:$PATH"

# Never run SDK integration tests in pre-commit.
unset VIBESDK_RUN_INTEGRATION_TESTS

# Optional override flags
# - SKIP_TESTS=1: skip all pre-commit checks
# - RUN_ALL_TESTS=1: run full suite instead of related
Expand Down Expand Up @@ -36,7 +39,7 @@ fi
# Exclude heavy directories that are not relevant at commit time.
if [ "${RUN_ALL_TESTS:-}" = "1" ]; then
echo "[pre-commit] RUN_ALL_TESTS=1 set; running full test suite"
bunx vitest run --passWithNoTests --exclude "container/**" --exclude "generated/**"
bunx vitest run --passWithNoTests --exclude "container/**" --exclude "generated/**" --exclude "sdk/test/integration/**"
exit $?
fi

Expand All @@ -63,4 +66,4 @@ EOF

echo "[pre-commit] Running related tests for staged files"
# Vitest takes file paths as filters.
bunx vitest related --run --passWithNoTests --exclude "container/**" --exclude "generated/**" "$@"
bunx vitest related --run --passWithNoTests --exclude "container/**" --exclude "generated/**" --exclude "sdk/test/integration/**" "$@"
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"tui": "tsx --tsconfig tsconfig.app.json cli/tui.tsx",
"cf-typegen": "wrangler types --include-runtime false",
"test": "vitest run",
"test:integration": "VIBESDK_RUN_INTEGRATION_TESTS=1 vitest run sdk/test/integration/integration.test.ts",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:bun": "bun run vitest run",
Expand Down
140 changes: 140 additions & 0 deletions sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# @cf-vibesdk/sdk

Client SDK for the VibeSDK platform.

## Install

```bash
npm install @cf-vibesdk/sdk
```

## Quickstart (Bun)

```ts
import { PhasicClient } from '@cf-vibesdk/sdk';

const client = new PhasicClient({
baseUrl: 'http://localhost:5173',
apiKey: process.env.VIBESDK_API_KEY!,
});

const session = await client.build('Build a simple hello world page.', {
projectType: 'app',
autoGenerate: true,
});

// High-level lifecycle waits
await session.wait.generationStarted();
await session.wait.deployable();

// Preview deployment (command + awaitable)
const previewWait = session.wait.previewDeployed();
session.deployPreview();
const deployed = await previewWait;

console.log('Preview URL:', deployed.previewURL);

// Workspace is always kept in sync from agent state + WS events
console.log(session.files.listPaths());
console.log(session.files.read('README.md'));

session.close();
```

## Quickstart (Node)

Node requires a WebSocket factory (the browser `WebSocket` global is not available):

```ts
import { PhasicClient } from '@cf-vibesdk/sdk';
import { createNodeWebSocketFactory } from '@cf-vibesdk/sdk/node';

const client = new PhasicClient({
baseUrl: 'http://localhost:5173',
apiKey: process.env.VIBESDK_API_KEY!,
webSocketFactory: createNodeWebSocketFactory(),
});

const session = await client.build('Build a simple hello world page.', {
projectType: 'app',
autoGenerate: true,
});

await session.wait.generationStarted();
await session.wait.deployable();
session.close();
```

## Authentication

Use either:

- `apiKey`: a VibeSDK API key (recommended for CLIs and automation)
- `token`: an already-minted JWT access token

When `apiKey` is provided, the SDK exchanges it for a short-lived access token and caches it.

## Workspace (no platform file APIs)

The SDK reconstructs and maintains a local view of the codebase using:

- `agent_connected.state.generatedFilesMap`
- `cf_agent_state.state.generatedFilesMap`
- incremental `file_*` messages

APIs:

- `session.files.listPaths()`
- `session.files.read(path)`
- `session.files.snapshot()`
- `session.files.tree()`

## Waiting primitives

Use high-level waits instead of depending on agent-internal message ordering:

- `session.wait.generationStarted()`
- `session.wait.generationComplete()`
- `session.wait.deployable()` (phasic resolves on `phase_validated`)
- `session.wait.previewDeployed()`
- `session.wait.cloudflareDeployed()`

All waits default to a long timeout (10 minutes). You can override per call:

```ts
await session.wait.generationComplete({ timeoutMs: 2 * 60_000 });
```

## Reliable WebSocket connections

Connections automatically reconnect with exponential backoff + jitter.

Events:

- `session.on('ws:reconnecting', ({ attempt, delayMs, reason }) => { ... })`

To disable reconnect:

```ts
session.connect({ retry: { enabled: false } });
```

## Low-level access

For advanced clients, you can subscribe to the raw typed WS stream:

- `session.on('ws:message', (msg) => { ... })`

The SDK also exposes `ws:raw` when the platform sends malformed/untyped payloads.

## Tests

From `sdk/`:

- Unit: `bun run test`
- Integration (requires local platform + API key): `bun run test:integration`

Integration expects:

- `VIBESDK_INTEGRATION_API_KEY`
- optional `VIBESDK_INTEGRATION_BASE_URL` (default `http://localhost:5173`)
61 changes: 61 additions & 0 deletions sdk/bun.lock

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

38 changes: 38 additions & 0 deletions sdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@cf-vibesdk/sdk",
"version": "0.0.2",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./node": {
"types": "./dist/node.d.ts",
"default": "./dist/node.js"
}
},
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "rm -rf ./dist && bun build ./src/index.ts ./src/node.ts --outdir ./dist --target bun",
"bundle-types": "dts-bundle-generator --export-referenced-types false --project ./tsconfig.protocol.json -o ./dist/index.d.ts ./src/index.ts && dts-bundle-generator --export-referenced-types false --project ./tsconfig.protocol.json -o ./dist/node.d.ts ./src/node.ts",
"typecheck": "tsc -p ./tsconfig.json --noEmit",
"test": "bun test test/*.test.ts",
"test:integration": "bun test --timeout 600000 test/integration/*.test.ts"
},
"dependencies": {
"ws": "^8.18.3"
},
"devDependencies": {
"@types/ws": "^8.18.1",
"dts-bundle-generator": "^9.5.1",
"typescript": "^5.9.3"
}
}


12 changes: 12 additions & 0 deletions sdk/src/agentic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { VibeClientOptions } from './types';
import { VibeClient } from './client';

export class AgenticClient extends VibeClient {
constructor(options: VibeClientOptions) {
super(options);
}

override async build(prompt: string, options: Parameters<VibeClient['build']>[1] = {}) {
return super.build(prompt, { ...options, behaviorType: options.behaviorType ?? 'agentic' });
}
}
Loading