npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sudopod

v0.2.0

Published

Stateless library for deploying and managing remote development environments

Readme

sudopod

A stateless TypeScript library for deploying and managing remote development environments. Currently supports GitHub Codespaces with Coder support planned.

Features

  • Connector-based architecture: Unified interface for multiple remote development platforms
  • Stateless design: No local state management required, all operations are idempotent
  • Type-safe: Full TypeScript support with comprehensive type definitions
  • Flexible configuration: Support for custom deployment options per connector
  • Authentication tokens: Built-in support for Claude LTT and other authentication methods

Installation

npm install sudopod

Quick Start

Deploy a Codespace

import { createConnector } from 'sudopod';

// Create a Codespaces connector
const connector = createConnector({ type: 'codespaces' });

// Deploy a new development environment
const deployment = await connector.deploy({
  git: {
    owner: 'myorg',
    repo: 'myrepo',
    branch: 'main'
  },
  server: {
    port: 3000,
    idleTimeout: 4320, // 72 hours in minutes
    keepAliveHours: 72
  },
  connectorOptions: {
    machine: 'basicLinux32gb',
    retentionPeriod: 14
  }
});

console.log('Deployment created:', deployment.id);
console.log('Access URLs:', deployment.urls);

List Deployments

// List all codespaces
const deployments = await connector.list();

// List with filters
const filtered = await connector.list({
  status: ['running'],
  owner: 'myorg',
  repo: 'myrepo'
});

console.log(`Found ${filtered.length} running deployments`);

Check Status

const status = await connector.getStatus('my-codespace-name');
console.log('Status:', status); // 'running', 'stopped', 'starting', etc.

Stop a Deployment

await connector.stop('my-codespace-name');
console.log('Deployment stopped');

Authentication

GitHub Codespaces

The Codespaces connector uses the GitHub CLI (gh) for authentication. Before using sudopod with Codespaces, ensure:

  1. Install the GitHub CLI: https://cli.github.com
  2. Authenticate with GitHub:
    gh auth login

The connector will automatically validate authentication and throw helpful errors if not configured.

Claude LTT (Long-Term Token)

To enable Claude Code authentication in your deployments:

const deployment = await connector.deploy({
  git: { owner: 'myorg', repo: 'myrepo', branch: 'main' },
  server: { port: 3000 },
  models: {
    claudeLtt: 'your-claude-ltt-token-here'
  }
});

The token will be set as the CLAUDE_LTT environment variable in the deployed environment.

API Reference

createConnector(config: ConnectorConfig): Connector

Factory function to create a connector instance.

// Codespaces connector
const codespaces = createConnector({ type: 'codespaces' });

// Coder connector (not yet implemented)
const coder = createConnector({
  type: 'coder',
  url: 'https://coder.example.com',
  apiKey: 'your-api-key'
});

Connector Interface

All connectors implement the following interface:

deploy(options: DeployOptions): Promise<Deployment>

Deploy a new remote development environment.

Options:

  • git.owner (string): GitHub organization or user
  • git.repo (string): Repository name
  • git.branch (string): Git branch to checkout
  • server.port (number, optional): Server port (default: 3000)
  • server.idleTimeout (number, optional): Idle timeout in minutes
  • server.keepAliveHours (number, optional): Hours to keep alive (default: 72)
  • workspaceDir (string, optional): Custom workspace directory
  • dev (boolean, optional): Use local sudocode installation
  • models.claudeLtt (string, optional): Claude authentication token
  • connectorOptions (object, optional): Connector-specific options

Codespaces Connector Options:

  • machine (string): Machine size (default: 'basicLinux32gb')
    • Options: 'basicLinux32gb', 'standardLinux32gb', 'premiumLinux', etc.
  • retentionPeriod (number): Days to retain stopped codespace (default: 14)

Returns: Deployment object with deployment details and URLs

stop(name: string): Promise<void>

Stop and delete a deployment.

getStatus(name: string): Promise<DeploymentStatus>

Get the current status of a deployment.

Returns: One of:

  • 'provisioning' - Being created
  • 'starting' - Starting up
  • 'running' - Active and available
  • 'stopping' - Shutting down
  • 'stopped' - Stopped/paused
  • 'failed' - Deployment failed

list(filters?: ListFilters): Promise<Deployment[]>

List all deployments, optionally filtered.

Filters:

  • status (DeploymentStatus[]): Filter by status
  • owner (string): Filter by repository owner
  • repo (string): Filter by repository name
  • createdAfter (string): Filter by creation date (ISO 8601)
  • createdBefore (string): Filter by creation date (ISO 8601)

getUrls(name: string, port?: number): Promise<DeploymentUrls>

Get access URLs for a deployment.

Returns:

  • workspace (string): Web IDE URL
  • sudocode (string): Sudocode server URL
  • ssh (string): SSH command or URL

Type Definitions

Deployment

interface Deployment {
  id: string;
  name: string;
  connector: 'codespaces' | 'coder';
  git: {
    owner: string;
    repo: string;
    branch: string;
  };
  status: DeploymentStatus;
  createdAt: string;
  urls: DeploymentUrls;
  keepAliveHours: number;
  idleTimeout?: number;
  metadata?: Record<string, any>;
}

Error Handling

Sudopod provides specialized error classes for different failure scenarios:

import {
  SudopodError,
  AuthenticationError,
  DeploymentFailedError,
  ConnectorError,
  ConnectorNotFoundError
} from 'sudopod';

try {
  await connector.deploy(options);
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Authentication failed:', error.message);
    // Guide user to authenticate with gh CLI
  } else if (error instanceof DeploymentFailedError) {
    console.error('Deployment failed:', error.message);
    // Handle deployment failure
  } else if (error instanceof ConnectorError) {
    console.error('Connector error:', error.operation, error.message);
    // Handle connector-specific error
  }
}

Idle Timeout Mechanism

The Codespaces connector implements a sophisticated idle timeout system:

How It Works

  1. GitHub's 5-minute auto-stop: GitHub Codespaces have a hardcoded 5-minute idle timeout that automatically stops codespaces when inactive.

  2. Idle timeout daemon: Sudopod starts a background daemon that:

    • Monitors the sudocode server log file for activity
    • Sends SSH keepalive commands every 30 seconds to prevent GitHub's auto-stop
    • Stops sending keepalive after the configured idleTimeout expires
    • Automatically resumes keepalive if activity is detected again
  3. Graceful pause: When the idle timeout expires, the daemon stops sending SSH commands, allowing GitHub's 5-minute auto-stop to trigger, pausing the codespace.

Configuration

const deployment = await connector.deploy({
  // ... other options
  server: {
    port: 3000,
    idleTimeout: 4320, // 72 hours in minutes (default: 72 hours)
    keepAliveHours: 72  // Hours to preserve VM after pause
  }
});
  • idleTimeout: Controls when the daemon stops preventing auto-pause
  • keepAliveHours: Controls VM retention after the codespace pauses (prevents deletion)

Advanced Usage

Custom Workspace Directory

const deployment = await connector.deploy({
  git: { owner: 'myorg', repo: 'myrepo', branch: 'main' },
  workspaceDir: '/workspaces/custom-path',
  server: { port: 3000 }
});

Development Mode (Local Sudocode)

const deployment = await connector.deploy({
  git: { owner: 'myorg', repo: 'myrepo', branch: 'main' },
  dev: true, // Install sudocode from local source
  server: { port: 3000 }
});

Large Machine Deployment

const deployment = await connector.deploy({
  git: { owner: 'myorg', repo: 'myrepo', branch: 'main' },
  server: { port: 3000 },
  connectorOptions: {
    machine: 'premiumLinux',
    retentionPeriod: 30 // Keep for 30 days after stopping
  }
});

Development

Setup

git clone https://github.com/sudocodeai/sudopod.git
cd sudopod
npm install

Build

npm run build

Testing

# Run unit tests
npm run test

# Run unit tests only
npm run test:unit

# Run integration tests (requires GitHub authentication)
npm run test:integration

# Validate built package structure and exports
npm run test:package

# Run end-to-end deployment test (requires GitHub auth + test repo)
npm run test:e2e:deploy

# Run all tests
npm run test:all

# Watch mode
npm run test:watch

End-to-End Deployment Test

The e2e deployment test performs a real deployment using the sudopod SDK:

# Set test repository
export CODESPACES_TEST_BRANCH=main  # Optional, defaults to 'main'

# Run the test (deploys, validates, and cleans up)
npm run test:e2e:deploy

# Skip cleanup to keep the codespace running
SKIP_CLEANUP=1 npm run test:e2e:deploy

This test:

  1. Imports the built package from dist/
  2. Creates a Codespaces connector
  3. Deploys a real GitHub Codespace
  4. Validates deployment status and URLs
  5. Tests all connector methods (getStatus, list, getUrls)
  6. Cleans up by stopping the deployment (unless SKIP_CLEANUP=1)

Project Structure

sudopod/
├── src/
│   ├── core/           # Core connector interface and factory
│   ├── connectors/     # Connector implementations
│   │   ├── codespaces.ts
│   │   └── coder.ts
│   ├── utils/          # Utility functions
│   │   └── codespaces/ # Codespaces-specific utilities
│   ├── types.ts        # TypeScript type definitions
│   └── index.ts        # Package exports
├── tests/
│   ├── unit/           # Unit tests
│   └── integration/    # Integration tests
├── dist/               # Compiled output
└── package.json

Roadmap

  • [x] GitHub Codespaces connector
  • [x] Idle timeout daemon
  • [x] Claude LTT authentication support
  • [ ] Coder connector implementation
  • [ ] Deployment lifecycle hooks
  • [ ] Custom connector plugins

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Submit a pull request

License

MIT

Support

For issues and questions:

  • GitHub Issues: https://github.com/sudocodeai/sudopod/issues
  • Documentation: https://github.com/sudocodeai/sudopod