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
60 changes: 60 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
# Build
npm run build # Compile TypeScript to ./dist/

# Test
npm test # Run all tests with coverage (requires .env file)
npm run test:ci # Run tests for CI (no .env required)

# Run a single test file
npx jest tests/run/yepcodeRun.test.ts

# Lint
npm run lint # Check for lint errors
npm run lint:fix # Auto-fix lint errors
```

Tests require a `.env` file with `YEPCODE_*` credentials to run against the real API.

## Architecture

This is a zero-dependency TypeScript SDK for the YepCode Cloud API. It requires Node.js >= 18 (uses native `fetch`). Output is compiled CommonJS to `./dist/`.

### Public surface (`src/index.ts`)

Four exported classes:
- **`YepCodeRun`** — Execute JavaScript/Python code in isolated YepCode sandboxes. Creates processes (deduplicated by SHA256 hash of code), executes them, and returns `Execution` instances.
- **`YepCodeEnv`** — CRUD for team-level environment variables with auto-pagination.
- **`YepCodeStorage`** — Upload/list/download/delete files (accepts `File`, `Blob`, or `Readable` streams).
- **`YepCodeApi`** — Raw HTTP client exposing the full REST API (processes, executions, schedules, modules, sandboxes, service accounts).

### Key internals

**`src/api/yepcodeApi.ts`** — The core HTTP client (~820 lines). Handles:
- Auth via API token, client credentials (OAuth), or direct access token
- Auto-refresh of expired access tokens
- All REST endpoints as typed methods

**`src/run/execution.ts`** — Wraps a running execution with adaptive polling:
- 250ms × 4, then 500ms × 8, then 1000ms thereafter
- Logs polled every 2s or on completion
- Event callbacks: `onLog`, `onFinish`, `onError`

**`src/api/configManager.ts`** — Reads `YEPCODE_API_TOKEN`, `YEPCODE_CLIENT_ID`, `YEPCODE_CLIENT_SECRET`, `YEPCODE_TEAM_ID`, `YEPCODE_ACCESS_TOKEN`, `YEPCODE_API_HOST` from the environment.

**`src/utils/languageDetector.ts`** — Regex/scoring-based JS vs Python detection used when language is not specified explicitly.

## OpenAPI spec

The live spec is always available at:
```
https://cloud.yepcode.io/api/rest/public/api-docs
```

Fetch it with `WebFetch` to audit which endpoints are missing from `src/api/yepcodeApi.ts` before adding new ones. New endpoints are deployed to that URL before this SDK is updated.
65 changes: 59 additions & 6 deletions src/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Readable } from "stream";

export type ProgrammingLanguage = "JAVASCRIPT" | "PYTHON";

export interface YepCodeApiConfig {
apiHost?: string;
timeout?: number;
Expand All @@ -15,7 +17,7 @@ export interface CreateProcessInput {
slug?: string;
description?: string;
readme?: string;
programmingLanguage?: "JAVASCRIPT" | "PYTHON";
programmingLanguage?: ProgrammingLanguage;
sourceCode?: string;
parametersSchema?: string;
webhook?: WebhookInput;
Expand Down Expand Up @@ -141,7 +143,7 @@ export interface Process {
[key: string]: any;
};
};
programmingLanguage?: "JAVASCRIPT" | "PYTHON";
programmingLanguage?: ProgrammingLanguage;
sourceCode?: string;
webhook?: ProcessWebhook;
settings?: ProcessSettings;
Expand Down Expand Up @@ -279,7 +281,7 @@ export interface WebhookInput {

export interface VersionedProcess {
id: string;
programmingLanguage: "JAVASCRIPT" | "PYTHON";
programmingLanguage: ProgrammingLanguage;
sourceCode: string;
parametersSchema: string;
readme: string;
Expand Down Expand Up @@ -330,7 +332,7 @@ export interface VersionedProcessAliasesPaginatedResult {
export interface Module {
id: string;
name: string;
programmingLanguage?: "JAVASCRIPT" | "PYTHON";
programmingLanguage?: ProgrammingLanguage;
sourceCode?: string;
createdBy?: string;
createdAt?: string;
Expand All @@ -340,7 +342,7 @@ export interface Module {

export interface CreateModuleInput {
name: string;
programmingLanguage?: "JAVASCRIPT" | "PYTHON";
programmingLanguage?: ProgrammingLanguage;
sourceCode?: string;
script?: {
programmingLanguage?: string;
Expand All @@ -367,7 +369,7 @@ export interface ModulesPaginatedResult {

export interface VersionedModule {
id: string;
programmingLanguage: "JAVASCRIPT" | "PYTHON";
programmingLanguage: ProgrammingLanguage;
sourceCode: string;
comment?: string;
createdBy?: string;
Expand Down Expand Up @@ -488,3 +490,54 @@ export interface ServiceAccountsListResult {
total: number;
data: ServiceAccount[];
}

/**
* Teams
*/
export interface ErrorHandlerConfig {
processId?: string;
tag?: string;
}

export interface ErrorHandlerConfigInput {
processId?: string;
tag?: string;
}

export interface Team {
slug?: string;
name?: string;
zoneId?: string;
parentTeamSlugs?: string[];
paramsSchemaValidationEnabled?: boolean;
errorHandlerConfig?: ErrorHandlerConfig | null;
createdAt?: string;
}

export interface UpdateTeamInput {
name?: string;
zoneId?: string;
parentTeamSlugs?: string[] | null;
paramsSchemaValidationEnabled?: boolean;
errorHandlerConfig?: ErrorHandlerConfigInput | null;
}

/**
* Dependencies
*/
export interface ProgrammingLanguageManifestInstallation {
status?: "PENDING" | "INSTALLING" | "INSTALLED" | "FAILED";
error?: string;
dependencies?: { [name: string]: string };
}

export interface ProgrammingLanguageManifest {
id?: string;
programmingLanguage?: ProgrammingLanguage;
dependencies?: { [name: string]: string };
nextInstallation?: ProgrammingLanguageManifestInstallation;
}

export interface UpdateTeamDependenciesInput {
dependencies?: { [name: string]: string };
}
38 changes: 38 additions & 0 deletions src/api/yepcodeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ import {
Sandbox,
CreateSandboxInput,
UpdateSandboxInput,
Team,
UpdateTeamInput,
ProgrammingLanguage,
ProgrammingLanguageManifest,
UpdateTeamDependenciesInput,
} from "./types";
import { Readable } from "stream";

Expand Down Expand Up @@ -816,4 +821,37 @@ export class YepCodeApi {
async deleteServiceAccount(id: string): Promise<void> {
return this.request("DELETE", `/auth/service-accounts/${id}`);
}

// Team endpoints
async getTeam(): Promise<Team> {
return this.request("GET", "/team");
}

async updateTeam(data: UpdateTeamInput): Promise<Team> {
return this.request("PATCH", "/team", { data });
}

// Dependencies endpoints
async getTeamDependencies(
language: ProgrammingLanguage
): Promise<ProgrammingLanguageManifest> {
return this.request("GET", `/dependencies/${language}`);
}

async updateTeamDependencies(
language: ProgrammingLanguage,
data: UpdateTeamDependenciesInput
): Promise<ProgrammingLanguageManifest> {
return this.request("PUT", `/dependencies/${language}`, { data });
}

async installTeamDependencies(language: ProgrammingLanguage): Promise<void> {
return this.request("POST", `/dependencies/${language}/install`);
}

async discardTeamDependenciesInstallation(
language: ProgrammingLanguage
): Promise<ProgrammingLanguageManifest> {
return this.request("DELETE", `/dependencies/${language}/install`);
}
}
Loading