From trebuchet
Serverless deployment architecture with CloudGateway, CloudProvider abstraction, ServiceRegistry, ActorStateStore, and local development setup. Use when users need to understand cloud deployment concepts or deploy actors to serverless platforms.
npx claudepluginhub briannadoubt/claude-marketplace --plugin trebuchetThis skill uses the workspace's default tool permissions.
Learn how Trebuchet enables serverless deployment of distributed actors.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
Learn how Trebuchet enables serverless deployment of distributed actors.
TrebuchetCloud provides the abstractions needed to deploy Swift distributed actors to serverless platforms. Instead of running a persistent server, your actors execute on-demand in response to invocations.
┌───────────────────────────────────────────────────────────────┐
│ Cloud Environment │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ CloudGateway │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │ │
│ │ │ UserService │ │ GameRoom │ │ Lobby │ │ │
│ │ └─────────────┘ └─────────────┘ └────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ StateStore │ │ Registry │ │ HTTP Endpoint │ │
│ │ (DynamoDB) │ │ (CloudMap) │ │ (API Gateway) │ │
│ └──────────────┘ └──────────────┘ └───────────────────┘ │
└───────────────────────────────────────────────────────────────┘
The CloudGateway is the entry point for hosting actors in cloud environments. It handles:
import TrebuchetCloud
let gateway = CloudGateway(configuration: .init(
host: "0.0.0.0",
port: 8080,
stateStore: myStateStore,
registry: myRegistry
))
try await gateway.expose(myActor, as: "my-actor")
try await gateway.run()
The CloudProvider protocol abstracts cloud platform specifics:
public protocol CloudProvider: Sendable {
associatedtype FunctionConfig: Sendable
associatedtype DeploymentResult: CloudDeployment
func deploy<A: DistributedActor>(
_ actorType: A.Type,
as actorID: String,
config: FunctionConfig,
factory: @Sendable (TrebuchetActorSystem) -> A
) async throws -> DeploymentResult
func transport(for deployment: DeploymentResult) async throws -> any TrebuchetTransport
}
Implementations:
The ServiceRegistry protocol enables actor discovery:
public protocol ServiceRegistry: Sendable {
func register(
actorID: String,
endpoint: CloudEndpoint,
metadata: [String: String],
ttl: Duration?
) async throws
func resolve(actorID: String) async throws -> CloudEndpoint?
func deregister(actorID: String) async throws
}
Implementations:
The ActorStateStore protocol provides state persistence:
public protocol ActorStateStore: Sendable {
func load<State: Codable & Sendable>(
for actorID: String,
as type: State.Type
) async throws -> State?
func save<State: Codable & Sendable>(
_ state: State,
for actorID: String
) async throws
func delete(for actorID: String) async throws
}
Implementations:
Actors that need persistent state implement StatefulActor:
import TrebuchetCloud
@Trebuchet
distributed actor ShoppingCart: StatefulActor {
typealias PersistentState = CartState
let stateStore: ActorStateStore
var persistentState = CartState()
init(actorSystem: TrebuchetActorSystem, stateStore: ActorStateStore) async throws {
self.actorSystem = actorSystem
self.stateStore = stateStore
try await loadState(from: stateStore)
}
distributed func addItem(_ item: Item) async throws -> CartState {
persistentState.items.append(item)
try await saveState(to: stateStore)
return persistentState
}
func loadState(from store: any ActorStateStore) async throws {
if let state = try await store.load(for: id.id, as: CartState.self) {
persistentState = state
}
}
func saveState(to store: any ActorStateStore) async throws {
try await store.save(persistentState, for: id.id)
}
}
struct CartState: Codable, Sendable {
var items: [Item] = []
}
Actors deployed to cloud functions can discover and invoke each other in two ways:
import TrebuchetCloud
import TrebuchetAWS
// From within an actor running in Lambda
@Trebuchet
distributed actor GameRoom {
let client: TrebuchetCloudClient
distributed func notifyLobby() async throws {
// Resolve another actor via service registry
let lobby = try await client.resolve(Lobby.self, id: "lobby")
// Invoke it (triggers another Lambda invocation)
try await lobby.onGameStarted(roomID: id.id)
}
}
Added in v0.3.0 - For programmatic actor invocation without HTTP overhead:
import TrebuchetCloud
let gateway = CloudGateway(configuration: .init(
stateStore: stateStore,
registry: registry
))
// Register actors
try await gateway.expose(myActor, as: "my-actor")
// Programmatic invocation (actor-to-actor, no HTTP)
let envelope = InvocationEnvelope(
callID: UUID(),
actorID: TrebuchetActorID(id: "my-actor"),
targetIdentifier: "myMethod(param:)",
genericSubstitutions: [],
arguments: [try JSONEncoder().encode("value")]
)
let response = await gateway.process(envelope)
Use cases:
For local development, use the in-memory implementations:
import TrebuchetCloud
let gateway = CloudGateway.development(host: "localhost", port: 8080)
This creates a gateway with:
InMemoryStateStore for state persistenceInMemoryRegistry for service discoveryimport Trebuchet
import TrebuchetCloud
@main
struct DevServer {
static func main() async throws {
// Create local gateway
let gateway = CloudGateway.development(host: "localhost", port: 8080)
// Create actors
let room = GameRoom(actorSystem: gateway.system)
let lobby = Lobby(actorSystem: gateway.system)
// Expose actors
try await gateway.expose(room, as: "game-room")
try await gateway.expose(lobby, as: "lobby")
print("Local development server running on http://localhost:8080")
try await gateway.run()
}
}
@Trebuchet macrotrebuchet.yamltrebuchet deploy --provider awsCreate a trebuchet.yaml to configure deployment:
name: my-game-server
version: "1"
defaults:
provider: aws
region: us-east-1
memory: 512
timeout: 30
actors:
GameRoom:
memory: 1024
stateful: true
Lobby:
memory: 256
state:
type: dynamodb
discovery:
type: cloudmap
namespace: my-game
CloudGateway supports middleware for cross-cutting concerns:
import TrebuchetCloud
import TrebuchetSecurity
import TrebuchetObservability
let gateway = CloudGateway(configuration: .init(
middlewares: [
ValidationMiddleware(...), // Request validation
AuthenticationMiddleware(...), // Authentication
AuthorizationMiddleware(...), // Authorization
RateLimitingMiddleware(...), // Rate limiting
TracingMiddleware(...) // Distributed tracing
],
stateStore: stateStore,
registry: registry
))