JSPM

@sudocode-ai/environment-harness

0.1.2-dev.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 2
    • Score
      100M100P100Q25299F
    • License MIT

    GitHub Codespace manager for creating and managing sandboxed development environments

    Package Exports

    • @sudocode-ai/environment-harness
    • @sudocode-ai/environment-harness/package.json

    Readme

    @sudocode-ai/environment-harness

    TypeScript/Node.js library for creating and managing GitHub Codespaces as sandboxed development environments.

    Installation

    npm install @sudocode-ai/environment-harness

    Prerequisites

    • Node.js: Version 18.0.0 or higher (tested with Node 18-25)
    • GitHub CLI: Install from cli.github.com
    • GitHub Token: Personal access token or OAuth token with codespace permissions
      • Required scopes: codespace, repo

    Quick Start

    Creating a Sandbox

    Create a new GitHub Codespace with sudocode and Claude Code installed:

    import { create_sandbox } from '@sudocode-ai/environment-harness';
    
    const result = await create_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      repository: 'owner/repo',
      ref: 'main',  // Optional: branch, tag, or commit
      claudeOAuthToken: process.env.CLAUDE_OAUTH_TOKEN,  // Optional
    });
    
    console.log('Sandbox created:', result.codespace.name);
    console.log('Web URL:', result.codespace.webUrl);
    console.log('GitHub token:', result.githubToken);
    console.log('Sudocode server port:', result.sudocodeServer.port);
    console.log('Tools installed:', result.toolsInstalled);

    Resuming an Existing Sandbox

    Resume a previously created sandbox (handles auto-stopped codespaces):

    import { resume_sandbox } from '@sudocode-ai/environment-harness';
    
    const result = await resume_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      codespaceName: 'symmetrical-space-telegram-abc123',
      serverPort: 3000,  // Optional: sudocode server port
    });
    
    console.log('Reconnected to:', result.codespace.name);
    console.log('Server running on port:', result.sudocodeServer.port);
    console.log('GitHub token:', result.githubToken);

    Deleting a Sandbox

    Delete a sandbox and clean up all resources:

    import { delete_sandbox } from '@sudocode-ai/environment-harness';
    
    const result = await delete_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      codespaceName: 'symmetrical-space-telegram-abc123',
    });
    
    console.log('Sandbox deleted:', result.codespaceName);
    console.log('Success:', result.success);

    API Reference

    create_sandbox(params)

    Creates a new GitHub Codespace with required tools installed.

    Parameters:

    • githubToken (string, required): GitHub token with codespace permissions
    • repository (string, required): Repository in format "owner/repo"
    • ref (string, optional): Git ref (branch/tag/commit), defaults to repository default branch
    • devcontainerPath (string, optional): Path to .devcontainer subdirectory
    • idleTimeoutMinutes (number, optional): Minutes of inactivity before auto-shutdown
    • retentionPeriodMinutes (number, optional): Minutes to retain codespace after shutdown
    • claudeOAuthToken (string, optional): Claude OAuth token for Claude Code

    Returns: Promise<SandboxResult>

    • codespace: Codespace details (name, id, state, webUrl)
    • githubToken: GitHub token from codespace environment (ghu_* format)
    • sudocodeServer: Server details (port)
    • toolsInstalled: List of installed tools

    Throws:

    • GitHubAPIError: If API call fails (invalid token, permissions, repository not found)
    • Error: If codespace creation times out or provisioning fails

    resume_sandbox(params)

    Resumes an existing sandbox, handling state transitions and restarting services.

    Parameters:

    • githubToken (string, required): GitHub token with codespace permissions
    • codespaceName (string, required): Unique codespace identifier
    • serverPort (number, optional): Port for sudocode server (default: 3000)

    Returns: Promise<SandboxResult>

    Throws:

    • GitHubAPIError: If API call fails (invalid token, permissions)
    • Error: If codespace not found, SSH connection fails, or token extraction fails

    delete_sandbox(params)

    Deletes a sandbox (idempotent operation).

    Parameters:

    • githubToken (string, required): GitHub token with codespace permissions
    • codespaceName (string, required): Unique codespace identifier

    Returns: Promise<DeleteSandboxResult>

    • success: Whether deletion was successful
    • codespaceName: Name of the deleted codespace

    Throws:

    • GitHubAPIError: If API call fails (invalid token, permissions)

    Authentication Setup

    GitHub Token

    You can create a GitHub personal access token at github.com/settings/tokens.

    Required scopes:

    • codespace - Create and manage codespaces
    • repo - Access repositories

    Set the token as an environment variable:

    export GITHUB_TOKEN=ghp_your_token_here

    Claude OAuth Token (Optional)

    If you want Claude Code installed in your sandboxes, provide a Claude OAuth token:

    export CLAUDE_OAUTH_TOKEN=your_oauth_token

    Error Handling

    The library throws typed errors that you can catch and handle:

    import { create_sandbox } from '@sudocode-ai/environment-harness';
    
    try {
      const result = await create_sandbox({
        githubToken: process.env.GITHUB_TOKEN!,
        repository: 'owner/repo',
      });
      console.log('Success:', result.codespace.name);
    } catch (error) {
      if (error.name === 'GitHubAPIError') {
        console.error('GitHub API error:', error.message);
        // Handle API-specific errors (auth, permissions, rate limits)
      } else {
        console.error('Unexpected error:', error);
        // Handle other errors (timeouts, network issues)
      }
    }

    Advanced Usage

    Custom Timeout Configuration

    const result = await create_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      repository: 'owner/repo',
      idleTimeoutMinutes: 30,  // Auto-stop after 30 minutes of inactivity
      retentionPeriodMinutes: 60,  // Delete 60 minutes after stopping
    });

    Custom Devcontainer Path

    const result = await create_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      repository: 'owner/repo',
      devcontainerPath: '.devcontainer/custom-config',
    });

    Full Lifecycle Example

    import {
      create_sandbox,
      resume_sandbox,
      delete_sandbox
    } from '@sudocode-ai/environment-harness';
    
    // Create
    const created = await create_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      repository: 'owner/repo',
    });
    console.log('Created:', created.codespace.name);
    
    // Resume later (e.g., after it auto-stopped)
    const resumed = await resume_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      codespaceName: created.codespace.name,
    });
    console.log('Resumed:', resumed.codespace.state);
    
    // Clean up
    const deleted = await delete_sandbox({
      githubToken: process.env.GITHUB_TOKEN!,
      codespaceName: created.codespace.name,
    });
    console.log('Deleted:', deleted.success);

    Development

    # Install dependencies
    npm install
    
    # Run tests
    npm test
    
    # Run integration tests (requires GitHub token)
    npm run test:integration
    
    # Build
    npm run build
    
    # Type check
    npm run typecheck
    
    # Dry run npm pack (validate package contents)
    npm run pack:dry

    Publishing

    To publish a new version to npm:

    Pre-publish Validation

    # 1. Build the package
    npm run build
    
    # 2. Run all tests
    npm test
    
    # 3. Validate package contents
    npm run pack:dry

    Publish to npm

    # 1. Bump version (patch | minor | major)
    npm version patch
    
    # 2. Publish to npm (first time requires --access public)
    npm publish --access public
    
    # 3. Push tags to git
    git push origin main --tags

    Post-publish Verification

    # Test installation
    npm install @sudocode-ai/environment-harness
    
    # Verify in a test project
    node -e "import('@sudocode-ai/environment-harness').then(m => console.log(m))"

    Notes:

    • The prepublishOnly script automatically runs build and tests before publishing
    • Package contents are controlled by the files field in package.json (only dist/ is included)
    • .env files and other gitignored files are automatically excluded

    Testing

    Integration tests require a GitHub token with codespace permissions:

    export GITHUB_TOKEN=ghp_your_token_here
    npm run test:integration

    Compatibility

    • Node.js: >= 18.0.0
    • TypeScript: >= 5.0
    • ESM only (no CommonJS support)

    License

    MIT