- TypeScript 94.2%
- JavaScript 4.9%
- CSS 0.7%
- HTML 0.2%
| .zed | ||
| docs | ||
| examples | ||
| platforms | ||
| rorqual | ||
| stroma/packages/core | ||
| tools | ||
| web | ||
| .gitignore | ||
| bunfig.toml | ||
| deno.json | ||
| deno.lock | ||
| README.md | ||
Rorqual
Stroma es un runtime de composición espaciotemporal, agnóstico del runtime. Rorqual es el harness de agentes construido encima.
Qué hay aquí
| Ruta | Qué es |
|---|---|
stroma/packages/core |
Runtime de composición: Context, fibers, efectos revertibles, coeffectos y loader. |
rorqual/ |
Harness de agentes: LLM, tools, sesiones, fs, web, shell, approval, extensiones, HTTP/SSE, CLI. |
platforms/ |
Un paquete por runtime: @rorqual/platform-deno, -node y -bun. |
web/ |
Cliente web estático, sin build. |
examples/ |
Ejemplos host-free y smokes de las capacidades contra sistemas reales. |
tools/ |
Runners de test, contrato de conformidad y shims de desarrollo. |
docs/ |
Guías de uso, portabilidad, decisiones y backlog de mejoras. |
La regla de dirección: las plataformas dependen del harness, nunca al revés. @stroma/core y
@rorqual/harness no importan ningún paquete de platforms/, así que se pueden bundlear para un
runtime que todavía no tenga plataforma.
Herramientas
| Runtime | Versión | Para qué |
|---|---|---|
| Deno | 2.9+ | Tareas del repositorio, suite principal y ejemplos. |
| Node | 24.15+ | Plataforma Node y suite del harness en Node. |
| Bun | 1.4.3+ | Plataforma Bun y su contrato de conformidad. |
Deno es hoy la herramienta con la que se ejecutan las tareas y la suite del repositorio. No es una dependencia del modelo: el núcleo y el harness solo usan estándares ECMAScript/Web, y la elección de plataforma es explícita. Node y Bun son opcionales para trabajar en el núcleo.
No hay dependencias externas de runtime. Los tests usan @std/assert (JSR).
Verificación rápida
Desde la raíz del repo:
deno task test # 419 tests (~3 s)
deno run examples/hello.ts # Stroma puro, sin host ni red
deno run examples/agent.ts # agent loop con LLM simulado
deno run --allow-read=. examples/loader.ts # loader declarativo
deno task smoke:extension # autoextensión de extremo a extremo
deno task verify # type-check + hosts + cinco suites
deno task verify ejecuta la matriz completa: 419 tests en Deno, 419 en Node y el contrato de
plataforma en Deno (17), Node (18) y Bun (17). La suite completa bajo Bun sigue pendiente por
@std/assert; su contrato sí corre con bun:test.
Uso
Stroma se compone con Context.create(). Un provider publica una key y un consumidor se activa
cuando está disponible; retirar el provider descarga al consumidor y revierte sus efectos.
import { Context } from "@stroma/core"
interface Clock {
now(): number
}
declare module "@stroma/core" {
interface Services {
clock: Clock
}
}
const ctx = Context.create()
const clock = ctx.use({
inject: [],
provide: ["clock"],
apply: async function* (c) {
yield c.provide("clock", { now: () => Date.now() })
},
})
await clock.await()
const greeter = ctx.use({
inject: ["clock"],
provide: [],
apply: async function* (c) {
console.log(`activo a las ${c.clock.now()}`)
yield () => console.log("desactivado")
},
})
await greeter.await()
Rorqual añade el harness. La composición elige la plataforma de forma explícita y le pasa los puertos; no hay detección por globals:
import { httpComponent, sessionStoreComponent } from "@rorqual/harness"
import { denoServe, denoSessionFileSystem } from "@rorqual/platform-deno"
// Fragmento: la composición ya publicó `events`, `llm` y `tools`.
// `authToken`: credencial Bearer que aporta el entrypoint; no vive en el harness.
await ctx.use(sessionStoreComponent({
directory: ".rorqual/sessions",
fileSystem: denoSessionFileSystem,
})).await()
await ctx.use(httpComponent({ serve: denoServe, authToken })).await()
El mismo harness se monta con @rorqual/platform-node o @rorqual/platform-bun cambiando solo los
puertos. Ver docs/guia-node.md y docs/guia-bun.md.
La autoextensión se monta por sesión con extensionHostComponent({ store }), las tools
create_component/remove_component/list_components y approvalComponent; el store lo aporta la
plataforma (denoExtensionStore, nodeExtensionStore). El agente genera un mod.js, lo instala
con aprobación y la tool aparece en el turno siguiente. Ver docs/guia-uso.md y
docs/fase-7-revision.md.
Las cuatro formas de uso —librería, CLI, HTTP/SSE y cliente web— están en
examples/README.md y en platforms/<runtime>/examples/.
Comandos
| Comando | Qué hace |
|---|---|
deno task test |
Suite del harness, Stroma y cliente web (419). |
deno task test:node |
La misma suite bajo Node (419). |
deno task test:platform:deno |
Contrato de plataforma Deno (17). |
deno task test:platform:node |
Contrato de plataforma Node (18). |
deno task test:platform:bun |
Contrato de plataforma Bun (17). |
deno task verify |
Todo lo anterior más check y check:no-host. |
deno task check |
Type-check de entrypoints, plataformas y ejemplos. |
deno task check:no-host |
Falla si el núcleo o el harness nombran un host. |
deno task smoke:<nombre> |
Smokes contra sistemas reales: store, http, web, etc. |
deno lint / deno fmt --check |
Lint y formato. |
Plataformas
| Runtime | Núcleo | Plataforma | Verificación |
|---|---|---|---|
| Deno | ✅ | ✅ | 419 del harness + 17 de contrato |
| Node | ✅ | ✅ | 419 del harness + 18 de contrato |
| Bun | ✅ | ✅ | 17 de contrato; suite completa pendiente |
| Workers / navegador | ✅ | — | Fuera de alcance por ahora; el núcleo los soporta |
«Todos los runtimes» no significa «todas las capacidades en todos»: significa que el núcleo no elige
por ti y que cada host declara qué puede ofrecer. Un runtime sin procesos no puede ofrecer shell;
eso es una capacidad no disponible, no un fallo de portabilidad.
Documentación
docs/tesis-stroma-rorqual.md— tesis de composición espaciotemporal, modelo, estado y no-objetivos.docs/guia-uso.md— guía práctica, comandos, LLM real, HTTP/SSE y CLI.docs/guia-node.mdydocs/guia-bun.md— uso sin Deno.platforms/README.md— contrato de plataforma y cómo añadir un runtime.examples/README.md— las cuatro formas de uso y los smokes.docs/stroma-portabilidad.md— análisis, fases y lo que falta.docs/distribucion.md— publicación dual JSR + npm: mapa, invariantes y procedimiento de release.docs/mejoras-pendientes.md— backlog de mejoras derivado de comparar con DSH, pi, OpenCode y Codex (trece mejoras, catorce preguntas abiertas).docs/fase-7-revision.md— cierre de la Fase 7 (autoextensión).docs/fase-7-plan.md— análisis previo de la autoextensión (Fase 7).docs/development-log.md— decisiones (D1–D116) y deuda (P8–P11).
Principios
- El Context como frontera. Un componente no toca globals de la plataforma; recibe un contexto que media dependencias, efectos, listeners y recursos.
- El núcleo no conoce ninguna plataforma.
Deno.*,node:*yBun.*viven solo enplatforms/. - La composición elige. Los puertos son obligatorios y explícitos; no hay defaults mágicos.
- Deno es una plataforma más y, hoy, la herramienta del repo. No define la arquitectura ni tiene un estatus de referencia en el modelo.
- Cada efecto tiene dueño e inverso. Retirar una fiber revierte lo que instaló, en LIFO.
Antes de cerrar un cambio, deno task verify debe salir con 0.