1 Home
Virgil edited this page 2026-03-11 12:14:38 +00:00

CoreTS

Module: forge.lthn.ai/core/ts

Go service that manages a Deno TypeScript runtime as a sidecar process. Provides bidirectional communication between Go and Deno via Unix socket gRPC and JSON-RPC, sandboxed filesystem access, permission-gated module loading, and marketplace module installation. Integrates with the Core framework as a Startable/Stoppable service.

Architecture

The startup sequence is: sandboxed Medium -> SQLite Store -> gRPC Server -> manifest load/verify -> gRPC listener -> Deno sidecar -> DenoClient connection -> marketplace module auto-load.

Go exposes a gRPC CoreService server on a Unix socket. Deno exposes a JSON-RPC DenoService server on a separate socket. The DenoClient connects to Deno's socket and sends module lifecycle commands.

Key Types

Options

type Options struct {
    DenoPath       string            // path to deno binary (default: "deno")
    SocketPath     string            // Unix socket for Go's gRPC server
    DenoSocketPath string            // Unix socket for Deno's JSON-RPC server
    AppRoot        string            // sandboxed I/O root directory
    StoreDBPath    string            // SQLite DB path (default: AppRoot/.core/store.db)
    PublicKey      ed25519.PublicKey  // ed25519 key for manifest verification (optional)
    SidecarArgs    []string          // args passed to the sidecar process
}

Sidecar

Manages the Deno child process. Thread-safe via RWMutex.

type Sidecar struct { opts Options; cmd *exec.Cmd; ctx context.Context; cancel context.CancelFunc; done chan struct{} }
  • NewSidecar(opts) *Sidecar — creates sidecar with defaults (deno path, socket paths, store path).
  • Start(ctx, args...) error — launches Deno process.
  • Stop() error — terminates Deno process.

DenoClient

JSON-RPC client over Unix socket. Thread-safe (mutex-serialised requests).

type DenoClient struct { conn net.Conn; reader *bufio.Reader }
  • DialDeno(socketPath) (*DenoClient, error) — connect to Deno's server.
  • LoadModule(code, entryPoint, perms) (*LoadModuleResponse, error) — load module with permissions.
  • UnloadModule(code) (*UnloadModuleResponse, error) — unload module.
  • ModuleStatus(code) (*ModuleStatusResponse, error) — query module status.

ModulePermissions

Per-module Deno Worker sandbox permissions:

type ModulePermissions struct {
    Read  []string   // filesystem read paths
    Write []string   // filesystem write paths
    Net   []string   // network host:port pairs
    Run   []string   // executable commands
}

Permissions (standalone)

type Permissions struct { Read, Write, Net, Run []string }
  • Flags() []string — converts to Deno --allow-* CLI flags.

Validation functions:

  • CheckPath(path, allowed) bool — validates path against allowed prefixes (prevents traversal).
  • CheckNet(addr, allowed) bool — validates network address.
  • CheckRun(cmd, allowed) bool — validates command.

Service

Core framework service wrapping the full CoreDeno subsystem.

type Service struct {
    *core.ServiceRuntime[Options]
    sidecar    *Sidecar
    grpcServer *Server
    store      *store.Store
    denoClient *DenoClient
    installer  *marketplace.Installer
}
  • NewServiceFactory(opts) func(*core.Core) (any, error) — factory for core.WithService().
  • OnStartup(ctx) error — boots medium, store, gRPC, manifest, sidecar, client, installer.
  • OnShutdown(ctx) error — tears down in reverse order.
  • Accessors: Sidecar(), GRPCServer(), DenoClient(), Installer().

Server

gRPC server implementing the CoreService protobuf definition. Handles file I/O, store operations, and module registration for Deno.

Dependencies

Direct: go-io, testify, grpc, protobuf. Indirect: go-log, go-scm/manifest, go-scm/marketplace, go-io/store.

Usage

svc := ts.NewServiceFactory(ts.Options{
    AppRoot:     "/path/to/app",
    SidecarArgs: []string{"run", "--unstable", "main.ts"},
})
core.New(core.WithService(svc))