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

@workspace-agent/sdk

v0.0.1-beta.6

Published

Node.js SDK for Workspace Agent API - Manage containerized development environments

Downloads

35

Readme

@workspace-agent/sdk

A comprehensive Node.js/TypeScript SDK for the Workspace Agent API. Manage containerized development environments with full support for files, git, terminals, processes, and LSP.

Features

  • Workspace Management - Create, start, stop, and delete workspaces
  • Multiple Runtimes - Bun, Node.js, Python, Go, and Rust
  • File Operations - Read, write, delete, copy, and move files
  • Git Integration - Clone, pull, commit, branch, and view history
  • Interactive Terminals - PTY-based terminal sessions via WebSocket
  • Process Management - Start background processes, sync execution, logs
  • LSP Client - Full Language Server Protocol support
  • Real-time Metrics - CPU, memory, network, and I/O monitoring via SSE
  • TypeScript First - Complete type definitions and JSDoc documentation
  • Fluent API - Builder pattern for easy workspace creation

Installation

npm install @workspace-agent/sdk
# or
yarn add @workspace-agent/sdk
# or
pnpm add @workspace-agent/sdk
# or
bun add @workspace-agent/sdk

Quick Start

import { WorkspaceClient } from '@workspace-agent/sdk';

const client = new WorkspaceClient();

// Create a workspace
const workspace = await client.workspaces.create({
  name: 'my-project',
  runtime: 'bun'
});

// Write some code
await workspace.files.write('index.ts', `
  console.log('Hello from workspace!');
`);

// Run it
const result = await workspace.exec(['bun', 'run', 'index.ts']);
console.log(result.output); // Hello from workspace!

// Clean up
await workspace.delete();

API Reference

WorkspaceClient

The main entry point for the SDK.

import { WorkspaceClient } from '@workspace-agent/sdk';

// Default configuration (localhost:18080)
const client = new WorkspaceClient();

// Custom configuration
const client = new WorkspaceClient({
  baseUrl: 'http://api.example.com:18080',
  timeout: 60000,
  debug: true
});

Runtimes

List available runtime environments:

const runtimes = await client.runtimes.list();
// [
//   { id: 'bun', name: 'Bun', dockerImage: 'workspace-agent/bun:latest', ... },
//   { id: 'node', name: 'Node.js', ... },
//   { id: 'python', name: 'Python', ... },
//   { id: 'go', name: 'Go', ... },
//   { id: 'rust', name: 'Rust', ... }
// ]

Workspaces

// Create workspace
const workspace = await client.workspaces.create({
  name: 'my-project',
  runtime: 'bun',
  repoUrl: 'https://github.com/user/repo.git', // optional
  branch: 'main' // optional
});

// Fluent builder pattern
const workspace = await client
  .create('my-project')
  .withRuntime('node')
  .withRepo('https://github.com/user/repo.git', 'develop')
  .build();

// Quick create
const workspace = await client.quickCreate('my-project', 'bun');

// List workspaces
const workspaces = await client.workspaces.list();

// Get by ID
const workspace = await client.workspaces.get('ws-abc12345');

// Find by name
const workspace = await client.findByName('my-project');

// Find by pattern
const devWorkspaces = await client.find('dev-*');

// Start/Stop
await workspace.start();
await workspace.stop();

// Delete
await workspace.delete();

Files

// List files
const files = await workspace.files.list('src');

// Read file
const content = await workspace.files.read('package.json');

// Read JSON
const pkg = await workspace.files.readJson<{name: string}>('package.json');

// Write file
await workspace.files.write('config.json', '{"key": "value"}');

// Write JSON
await workspace.files.writeJson('config.json', { key: 'value' });

// Check existence
if (await workspace.files.exists('package.json')) {
  console.log('Node.js project detected');
}

// Copy/Move/Delete
await workspace.files.copy('src/main.ts', 'src/main.backup.ts');
await workspace.files.move('old.txt', 'new.txt');
await workspace.files.delete('temp.txt');

Git

// Clone repository
await workspace.git.clone({
  url: 'https://github.com/user/repo.git',
  branch: 'main',
  target: 'my-app'
});

// Clone private repo
await workspace.git.clone({
  url: 'https://github.com/user/private-repo.git',
  username: 'user',
  password: 'github_pat_xxx'
});

// Pull changes
await workspace.git.pull();
await workspace.git.pull({ remote: 'origin', branch: 'develop' });

// Check status
const status = await workspace.git.status();
if (await workspace.git.isDirty()) {
  console.log('Uncommitted changes');
}

// Stage and commit
await workspace.git.add(['src/main.ts', 'package.json']);
await workspace.git.commit('feat: add new feature');

// Or commit all at once
await workspace.git.commitAll('chore: update deps');

// Create branch
await workspace.git.branch('feature/new-feature', true); // create and checkout

// View history
const commits = await workspace.git.log(10);
for (const commit of commits) {
  console.log(`${commit.hash} ${commit.message}`);
}

Terminal

Interactive PTY terminal sessions:

// Create and connect to terminal
const terminal = await workspace.terminal.spawn();

// Listen for output
terminal.on('data', (data) => {
  process.stdout.write(data);
});

// Send commands (include \n to execute)
terminal.write('ls -la\n');
terminal.write('npm install\n');

// Resize terminal
terminal.resize(120, 40);

// Send control characters
terminal.sendCtrlC();  // Ctrl+C
terminal.sendCtrlD();  // Ctrl+D (EOF)
terminal.clear();      // Clear screen

// Disconnect when done
terminal.disconnect();

// Quick command execution
const output = await workspace.terminal.exec('pwd');
console.log(output); // /workspace

Processes

Background process management:

// Start background process
const proc = await workspace.processes.start({
  command: ['bun', 'run', 'dev'],
  cwd: '/workspace/app',
  env: { PORT: '3000' }
});

console.log(`Started ${proc.id} (PID: ${proc.pid})`);

// List processes
const processes = await workspace.processes.list();

// Get logs
const logs = await workspace.processes.logs(proc.id, { tail: 50 });

// Kill process
await workspace.processes.kill(proc.id);

// Kill all
await workspace.processes.killAll();

// Sync execution (wait for completion)
const result = await workspace.processes.exec({
  command: ['npm', 'test'],
  timeoutSecs: 120,
  separateStderr: true
});

if (result.success) {
  console.log(result.output);
} else {
  console.error(result.stderr);
}

// Convenience method
const output = await workspace.processes.run('npm run build');

// Or use workspace.exec shorthand
const { output, exitCode } = await workspace.exec(['npm', 'test']);

LSP (Language Server Protocol)

Full LSP client for IDE-like features:

// Connect and initialize
const lsp = await workspace.lsp.start();

// Open a document
lsp.didOpen(
  'file:///workspace/src/main.ts',
  'typescript',
  'const x: number = "hello";'
);

// Listen for diagnostics
lsp.on('diagnostics', (uri, diagnostics) => {
  for (const diag of diagnostics) {
    console.log(`${uri}:${diag.range.start.line}: ${diag.message}`);
  }
});

// Get completions
const completions = await lsp.completion(
  'file:///workspace/src/main.ts',
  { line: 0, character: 6 }
);

// Get hover info
const hover = await lsp.hover(
  'file:///workspace/src/main.ts',
  { line: 0, character: 6 }
);

// Go to definition
const definitions = await lsp.definition(
  'file:///workspace/src/main.ts',
  { line: 10, character: 15 }
);

// Find references
const refs = await lsp.references(
  'file:///workspace/src/main.ts',
  { line: 5, character: 10 }
);

// Update document
lsp.didChange('file:///workspace/src/main.ts', 2, 'const x: number = 42;');

// Close document
lsp.didClose('file:///workspace/src/main.ts');

// Shutdown
await lsp.shutdown();

Metrics

Real-time resource monitoring for workspaces:

// Get current metrics snapshot
const metrics = await workspace.metrics.get();
console.log(`CPU: ${metrics.cpu.usagePercent.toFixed(2)}%`);
console.log(`Memory: ${(metrics.memory.usage / 1024 / 1024).toFixed(1)} MB`);
console.log(`Memory Limit: ${(metrics.memory.limit / 1024 / 1024).toFixed(1)} MB`);

// Get formatted summary
const summary = await workspace.metrics.summary();
console.log(summary);
// CPU: 12.5% | Memory: 256.0 MB / 512.0 MB (50.0%) | Network: RX 1.2 MB / TX 0.5 MB

// Stream metrics in real-time (SSE)
const stream = workspace.metrics.stream({ intervalMs: 500 });

stream.on('data', (metrics) => {
  console.log(`CPU: ${metrics.cpu.usagePercent.toFixed(1)}%`);
  console.log(`Memory: ${metrics.memory.usagePercent.toFixed(1)}%`);
});

stream.on('error', (error) => {
  console.error('Stream error:', error);
});

await stream.start();

// Stop streaming when done
stream.stop();

// Watch metrics for a duration
const samples = await workspace.metrics.watch(5000, 500);
console.log(`Collected ${samples.length} samples`);

const avgCpu = samples.reduce((sum, m) => sum + m.cpu.usagePercent, 0) / samples.length;
console.log(`Average CPU: ${avgCpu.toFixed(2)}%`);

// Continuous monitoring with callback
const stopMonitor = workspace.metrics.monitor((metrics) => {
  console.log(`CPU: ${metrics.cpu.usagePercent.toFixed(1)}%`);
}, { intervalMs: 1000 });

// Later, stop monitoring
stopMonitor();

Error Handling

import { WorkspaceApiError } from '@workspace-agent/sdk';

try {
  await client.workspaces.get('non-existent');
} catch (error) {
  if (error instanceof WorkspaceApiError) {
    console.error(`API Error ${error.status}: ${error.message}`);
  }
}

Examples

Create a Bun Project

const workspace = await client.quickCreate('bun-app', 'bun');

// Initialize project
await workspace.exec(['bun', 'init', '-y']);

// Add dependencies
await workspace.exec(['bun', 'add', 'hono']);

// Create server
await workspace.files.write('index.ts', `
import { Hono } from 'hono';

const app = new Hono();
app.get('/', (c) => c.text('Hello Hono!'));

export default app;
`);

// Start dev server
const server = await workspace.processes.start({
  command: ['bun', 'run', '--hot', 'index.ts']
});

console.log('Server started on PID:', server.pid);

Interactive Development Session

const workspace = await client.quickCreate('dev-session');

// Start terminal
const terminal = await workspace.terminal.spawn();

// Pipe to stdout
terminal.on('data', (data) => process.stdout.write(data));

// Pipe stdin (Node.js example)
process.stdin.setRawMode(true);
process.stdin.on('data', (data) => terminal.write(data.toString()));

// Handle exit
terminal.on('close', () => {
  process.stdin.setRawMode(false);
  process.exit();
});

Type Checking with LSP

const workspace = await client.quickCreate('type-check');

await workspace.files.write('test.ts', `
interface User {
  id: number;
  name: string;
}

const user: User = {
  id: "123",  // Type error!
  name: 123   // Type error!
};
`);

const lsp = await workspace.lsp.start();

const errors: string[] = [];

lsp.on('diagnostics', (uri, diagnostics) => {
  for (const d of diagnostics) {
    if (d.severity === 1) { // Error
      errors.push(`Line ${d.range.start.line + 1}: ${d.message}`);
    }
  }
});

lsp.didOpen('file:///workspace/test.ts', 'typescript',
  await workspace.files.read('test.ts'));

// Wait for diagnostics
await new Promise(resolve => setTimeout(resolve, 1000));

console.log('Type errors found:');
errors.forEach(e => console.log(`  ${e}`));

await lsp.shutdown();

TypeScript Support

The SDK is written in TypeScript and provides complete type definitions:

import type {
  Workspace,
  RuntimeId,
  FileEntry,
  GitCommit,
  ProcessInfo,
  LspDiagnostic,
  WorkspaceMetrics,
  CpuMetrics,
  MemoryMetrics
} from '@workspace-agent/sdk';

Requirements

  • Node.js 18+
  • Workspace API server running (default: http://localhost:18080)

License

MIT