ts/docs/index.md
Snider 9466bd7bc5 docs: add human-friendly documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:02:40 +00:00

117 lines
5.1 KiB
Markdown

---
title: CoreTS
description: Go service that manages a Deno TypeScript runtime as a sandboxed sidecar process, providing permission-gated I/O over gRPC and Unix sockets.
---
# CoreTS
CoreTS (`forge.lthn.ai/core/ts`) is a Go package that embeds a **Deno TypeScript runtime** as a managed sidecar process. It provides a bidirectional communication bridge between Go and Deno over Unix sockets, with fine-grained permission gating for filesystem, key-value store, and process operations.
The Go side exposes a **CoreService** gRPC server that Deno calls for I/O. The Deno side exposes a **DenoService** JSON-RPC server that Go calls for module lifecycle management. TypeScript modules run in isolated Deno Workers with per-module permission sandboxing.
**Module path:** `forge.lthn.ai/core/ts`
**Licence:** EUPL-1.2
## Quick Start
Register CoreTS as a service in a Core application:
```go
import (
"context"
core "forge.lthn.ai/core/go/pkg/core"
ts "forge.lthn.ai/core/ts"
)
opts := ts.Options{
DenoPath: "deno",
SocketPath: "/tmp/core/core.sock",
AppRoot: "/app",
SidecarArgs: []string{"run", "-A", "--unstable-worker-options", "runtime/main.ts"},
}
app, err := core.New(core.WithService(ts.NewServiceFactory(opts)))
if err != nil {
panic(err)
}
```
On startup, the service will:
1. Create a sandboxed I/O medium scoped to `AppRoot`
2. Open a SQLite-backed key-value store
3. Start a gRPC server on a Unix socket
4. Load and optionally verify the application manifest
5. Launch the Deno sidecar process
6. Wait for Deno's JSON-RPC server and connect as a client
7. Auto-load any previously installed marketplace modules
## Package Layout
| Path | Language | Purpose |
|------|----------|---------|
| `*.go` | Go | Sidecar management, gRPC server, permission checks, service integration |
| `proto/coredeno.proto` | Protobuf | Service definitions for CoreService and DenoService |
| `proto/*.pb.go` | Go | Generated protobuf and gRPC stubs |
| `runtime/main.ts` | TypeScript | Deno entry point -- boots the runtime, connects to Go |
| `runtime/client.ts` | TypeScript | gRPC client that calls CoreService on the Go side |
| `runtime/server.ts` | TypeScript | JSON-RPC server that implements DenoService for Go to call |
| `runtime/modules.ts` | TypeScript | Module registry with Worker isolation and I/O bridge |
| `runtime/worker-entry.ts` | TypeScript | Worker bootstrap -- loaded as entry point for every module Worker |
| `runtime/polyfill.ts` | TypeScript | Patches for Deno 2.x http2/grpc-js compatibility issues |
| `runtime/testdata/` | TypeScript | Test fixtures for integration tests |
## Go Source Files
| File | Purpose |
|------|---------|
| `coredeno.go` | `Options`, `Permissions`, `Sidecar` types and `NewSidecar()` constructor |
| `lifecycle.go` | `Sidecar.Start()`, `Stop()`, `IsRunning()` -- process lifecycle |
| `listener.go` | `ListenGRPC()` -- Unix socket gRPC listener with graceful shutdown |
| `server.go` | `Server` -- CoreService gRPC implementation with permission gating |
| `denoclient.go` | `DenoClient` -- JSON-RPC client for calling the Deno sidecar |
| `permissions.go` | `CheckPath()`, `CheckNet()`, `CheckRun()` -- permission helpers |
| `service.go` | `Service` -- framework integration (Startable/Stoppable lifecycle) |
## Dependencies
| Module | Purpose |
|--------|---------|
| `forge.lthn.ai/core/go` | Core framework (DI container, `ServiceRuntime`, lifecycle interfaces) |
| `forge.lthn.ai/core/go-io` | Sandboxed filesystem I/O (`Medium` interface, `MockMedium`) |
| `forge.lthn.ai/core/go-io/store` | SQLite-backed key-value store |
| `forge.lthn.ai/core/go-scm/manifest` | Module manifest loading and ed25519 verification |
| `forge.lthn.ai/core/go-scm/marketplace` | Module installation from Git repositories |
| `google.golang.org/grpc` | gRPC server and client |
| `google.golang.org/protobuf` | Protocol buffer runtime |
| `github.com/stretchr/testify` | Test assertions (dev only) |
The Deno runtime uses npm packages managed via `runtime/deno.json`:
| Package | Purpose |
|---------|---------|
| `@grpc/grpc-js` | gRPC client for calling CoreService |
| `@grpc/proto-loader` | Dynamic protobuf loading |
## Configuration
The `Options` struct controls all behaviour:
```go
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 // Application root directory (sandboxed I/O boundary)
StoreDBPath string // SQLite path (default: AppRoot/.core/store.db)
PublicKey ed25519.PublicKey // Ed25519 key for manifest verification (optional)
SidecarArgs []string // Arguments passed to the Deno process
}
```
If `SocketPath` is not set, it defaults to `$XDG_RUNTIME_DIR/core/deno.sock` (or `/tmp/core/deno.sock` on macOS).
If `DenoSocketPath` is not set, it defaults to the same directory as `SocketPath` with filename `deno.sock`.
If `StoreDBPath` is not set and `AppRoot` is provided, it defaults to `AppRoot/.core/store.db`.