@slcrun/cli
v0.1.0
Published
SLC CLI tool for deploying and developing Durable Actor applications
Downloads
9
Maintainers
Readme
SLC CLI
Command-line tool for deploying and developing Durable Actor applications on the SLC platform.
Overview
SLC CLI enables you to:
- Deploy your Durable Actor workers to regional nodes
- Develop applications locally with remote node support
- Bundle TypeScript/JavaScript workers into optimized bundles
Each deployed application becomes available as an invokable actor service on the regional node.
Installation
Prerequisites
- Node.js 20 or higher
- npm or yarn
Install from npm (Recommended)
npm install -g @slcrun/cliAfter installation, you can use the slc command from anywhere.
Install from Source
# Clone the repository
git clone <repository-url>
cd cli
# Install dependencies
npm install
# Build the CLI
npm run build
# Link globally (optional)
npm linkAfter linking, you can use slc from anywhere.
Quick Start
- Create a worker file (
worker.ts):
export default async function handler(ctx: {
actorId: string;
state: {
get(): Promise<any>;
set(partial: any): Promise<void>;
};
request: Request;
}): Promise<Response | any> {
const state = await ctx.state.get() || { count: 0 };
const newCount = state.count + 1;
await ctx.state.set({ count: newCount });
return new Response(
JSON.stringify({ actorId: ctx.actorId, count: newCount }),
{ headers: { "Content-Type": "application/json" } }
);
}- Create a config file (
slc.config.json):
{
"name": "my-app",
"entry": "./worker.ts"
}Note: The apiBaseUrl field is optional. If not specified, the CLI will use the endpoint from your ~/.slcrc configuration file (defaults to https://api.slc.run).
- Deploy:
slc deploy- Invoke your actor:
# Using the gateway (recommended)
curl -X POST https://api.slc.run/v1/invoke/my-project/my-app/user-123 \
-H "Content-Type: application/json" \
-H "x-slc-api-key: sk_your_api_key" \
-d '{}'Commands
slc deploy
Deploys your application to the regional node specified in slc.config.json.
What it does:
- Reads
slc.config.jsonfrom the current directory - Bundles your worker using esbuild
- Uploads the bundle to the regional node via
/_control/deploy-app - Makes your app available at
/invoke/<app-name>/:actorId
Usage:
slc deployOutput:
Bundling worker...
Uploading to https://api.slc.run...
✓ Deployed app 'my-app'
Invoke via: POST https://api.slc.run/v1/invoke/my-project/my-app/:actorIdRequirements:
- Must be run from a directory containing
slc.config.json - The entry file specified in config must exist
- The regional node must be running and accessible
slc dev
Starts development mode (currently informational).
Usage:
slc devNote: Local development server coming soon. For now, deploy and test directly against the remote node.
Configuration
slc.config.json
Create this file in your project root to configure deployment:
{
"name": "my-app",
"entry": "./worker.ts"
}Fields:
name(required): Your app name. Used in the invocation URL:/v1/invoke/<projectId>/<name>/:actorIdentry(required): Path to your worker file (relative to config file location)apiBaseUrl(optional): Base URL of the SLC API. If not specified, uses the endpoint from~/.slcrc(defaults tohttps://api.slc.run)
Example:
{
"name": "counter-app",
"entry": "./src/worker.ts"
}Worker Handler
Your worker file must export a default async function with this signature:
export default async function handler(ctx: {
actorId: string;
state: {
get(): Promise<any>;
set(partial: any): Promise<void>;
};
request: Request | { method: string; body?: any };
}): Promise<Response | any>Context Properties
actorId: Unique identifier for the actor instance (from URL:/invoke/:app/:actorId)state: Persistent state managementget(): Retrieves the current state for this actorset(partial): Updates the state (merges with existing state)
request: Request object withmethodand optionallybody
Return Value
Return a Response object or any JSON-serializable value:
// Option 1: Return Response
return new Response(
JSON.stringify({ message: "Hello" }),
{ headers: { "Content-Type": "application/json" } }
);
// Option 2: Return plain object (will be JSON-serialized)
return { message: "Hello" };Examples
The CLI includes several example applications:
Counter App
Simple counter that increments on each request.
cd examples/counter-app
slc deploySee examples/counter-app/README.md for details.
Chat Room App
Per-room message storage with GET/POST endpoints.
cd examples/chat-room-app
slc deploySee examples/chat-room-app/README.md for details.
Hello World App
Basic example demonstrating state management and request handling.
cd examples/hello-world-app
slc deploySee examples/hello-world-app/README.md for details.
How It Works
Deployment Flow
Bundle: Your TypeScript/JavaScript worker is bundled using esbuild
- Format: ESM (ES modules)
- Platform: Node.js
- Target: Node 20+
- All dependencies are bundled (no external deps)
Upload: The bundle is sent to the regional node via HTTP POST to
/v1/_control/deploy-app(versioned) or/_control/deploy-app(legacy)- Payload:
{ name: "<app-name>", bundle: "<bundled-code>" }
- Payload:
Registration: The node stores the bundle and makes it available at
/v1/invoke/<projectId>/<app-name>/:actorId(versioned) or/invoke/<app-name>/:actorId(legacy)
Invocation Flow
When you invoke an actor:
- Request:
POST /v1/invoke/<projectId>/<app-name>/:actorId(versioned) orPOST /invoke/<app-name>/:actorId(legacy) - Node looks up the app bundle
- Node uses DOSupervisor to get/create actor by
actorId - Node provides handler with:
actorIdstatewrapper (get/set)request(method/body)
- Handler executes and returns response
- Node returns handler's response as HTTP response
Regional Node Endpoints
The regional node provides several endpoints:
Invoke Actor (Versioned)
POST /v1/invoke/:projectId/:app/:actorId
GET /v1/invoke/:projectId/:app/:actorId
DELETE /v1/invoke/:projectId/:app/:actorIdInvokes a handler for a specific actor in an app. Requires x-slc-api-key header.
Invoke Actor (Legacy, Deprecated)
POST /invoke/:app/:actorId
GET /invoke/:app/:actorId
DELETE /invoke/:app/:actorIdLegacy endpoints (deprecated, will be removed in future versions).
Deploy App (Versioned)
POST /v1/_control/deploy-appDeploys a new app bundle (used by slc deploy). Requires x-slc-api-key header.
Deploy App (Legacy, Deprecated)
POST /_control/deploy-appLegacy endpoint (deprecated, will be removed in future versions).
Health Check (Versioned)
GET /v1/_healthReturns node health status, database info, and actor count.
Health Check (Legacy, Deprecated)
GET /_healthLegacy endpoint (deprecated, will be removed in future versions).
Debug Metrics
GET /_debug/metricsReturns runtime metrics: request counts, active actors, uptime.
See examples/NODE_INTEGRATION_GUIDE.md for implementation details.
Development
Build
npm run buildDevelopment Mode
npm run devThis runs the CLI in development mode using tsx (no build step required).
Project Structure
cli/
├── src/
│ ├── commands/
│ │ ├── deploy.ts # Deploy command implementation
│ │ └── dev.ts # Dev command implementation
│ └── index.ts # CLI entry point
├── examples/ # Example applications
├── dist/ # Compiled output
└── package.jsonTroubleshooting
"slc.config.json not found"
- Make sure you're running
slc deployfrom the directory containingslc.config.json - Check that the file is named exactly
slc.config.json
"Entry file not found"
- Verify the
entrypath inslc.config.jsonis correct - Path is relative to the
slc.config.jsonfile location
"Failed to connect to "
- Ensure the regional node is running
- Check that
apiBaseUrlinslc.config.jsonis correct - Verify network connectivity to the node
"Deployment failed: 500"
- Check the node logs for errors
- Verify your worker code is valid TypeScript/JavaScript
- Ensure the bundle doesn't exceed size limits
Requirements
- Node.js: 20 or higher
- TypeScript: 5.7+ (for TypeScript workers)
- Regional Node: Must be running and accessible
License
ISC
