@boardwalk-labs/engine 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
2
4
  // Thin launcher for `boardwalk-server` (SPEC §5). All real logic lives in compiled,
3
5
  // type-checked, tested TypeScript (src/server_main.ts) — this shim only exists so npm `bin`
4
6
  // and the Docker CMD share one entrypoint that resolves dist/ relative to the package.
@@ -1,4 +1,2 @@
1
- // The provider-neutral conversation model for the agent() loop. The leaf builds these;
2
- // each protocol adapter maps them to its wire format. Keeping the loop neutral is what lets
3
- // two adapters (Anthropic + OpenAI-compatible) cover every supported endpoint.
1
+ // SPDX-License-Identifier: Apache-2.0
4
2
  export {};
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The agent() leaf: a real agentic loop (SDK SPEC §2.1.1) — streamed model turns with tool
2
3
  // use (program-defined ToolDefs + memory file tools + MCP server tools), skills loaded into
3
4
  // context, schema output, secret redaction, and usage reporting. Runs IN THE PROGRAM PROCESS
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Provider adapters for the agent() leaf — two wire protocols cover everything (SPEC §2.3):
2
3
  // Anthropic's Messages API (streamed) and OpenAI-style chat completions (the lingua franca of
3
4
  // OpenAI, Google's compat surface, vLLM, Ollama, Together, Fireworks, Groq…). Each adapter
@@ -1,10 +1,4 @@
1
- // The approximate token-price table behind budget.max_usd (SPEC §2.2: "USD via a bundled
2
- // approximate rate table, documented as approximate").
3
- //
4
- // This is a GUARDRAIL, not a bill: the engine never charges anyone — it terminates a run that
5
- // crosses the author's declared ceiling. Prices drift; entries here are deliberately coarse
6
- // pattern matches with a conservative default, so an unknown model still consumes budget
7
- // rather than running unmetered.
1
+ // SPDX-License-Identifier: Apache-2.0
8
2
  // Order matters: first match wins, most-specific first.
9
3
  const RULES = [
10
4
  { pattern: /claude-opus/i, rate: { inUsdPerMtok: 15, outUsdPerMtok: 75 } },
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Secret redaction for the agent() leaf.
2
3
  //
3
4
  // The invariant: secret VALUES live only in deterministic program code; everything bound for a
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Model + provider resolution for the agent() leaf (SPEC §2.3 "model resolution").
2
3
  //
3
4
  // `provider` and `model` are ORTHOGONAL (decided 2026-06-12):
package/dist/agent/sse.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Server-Sent Events parsing, shared by the provider adapters (streamed model turns) and the
2
3
  // MCP streamable-HTTP transport (a server may answer any POST with an SSE stream). One parser
3
4
  // so the two consumers can't drift on framing edge cases (CRLF, split chunks, [DONE]).
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Capability assembly for an agent() call (SDK SPEC §2.1.1). Capabilities are PER-AGENT
2
3
  // (decided 2026-06-11): each call brings its own tools/skills/memory — there is nothing to
3
4
  // check against the manifest, but everything the call names must RESOLVE (fail loudly —
package/dist/clock.js CHANGED
@@ -1,6 +1,4 @@
1
- // Injectable time source. The scheduler and lifecycle take a Clock instead of calling
2
- // Date.now()/setTimeout directly so tests can drive time deterministically (scheduler clock
3
- // tests, DST cases, catch-up policy) without real waits.
1
+ // SPDX-License-Identifier: Apache-2.0
4
2
  /** The real wall clock. */
5
3
  export const systemClock = {
6
4
  now: () => Date.now(),
package/dist/cron/cron.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Cron parsing + next-fire computation for the scheduler (SPEC §2.1).
2
3
  //
3
4
  // One-validator philosophy: the SDK manifest schema only checks a cron trigger shallowly
package/dist/engine.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The engine facade — the one object both consumers construct (SPEC §1):
2
3
  // - SERVER mode: `start()` boots the recovery sweep + the cron scheduler loop and the
3
4
  // process stays up (the HTTP surface sits on top of this object).
package/dist/errors.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Engine errors carry a stable machine-readable code (surfaced in run_status `failed` events
2
3
  // and API responses) plus an actionable message. Messages NEVER contain secret values.
3
4
  export const ENGINE_ERROR_CODES = [
package/dist/ids.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // ULIDs — the engine's primary-key format: time-sortable, URL-safe,
2
3
  // no auto-increment integers. Implemented in-house: 26 chars of Crockford base32 over
3
4
  // 48 bits of timestamp + 80 bits of crypto randomness. Zero dependencies on purpose —
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // @boardwalk-labs/engine — the open-source single-node runtime.
2
3
  //
3
4
  // Two consumers, one implementation (SPEC §1): the CLI embeds it for `boardwalk dev`
@@ -1,6 +1,4 @@
1
- // Runtime narrowing for JsonValue. Values arriving over the run process's JSON-serialized IPC
2
- // channel are JSON by construction, but "by construction" is exactly what trust boundaries
3
- // don't get to assume — so narrow structurally instead of casting.
1
+ // SPDX-License-Identifier: Apache-2.0
4
2
  import { EngineError } from "./errors.js";
5
3
  /** True when `value` is a plain JSON tree (no functions, symbols, bigints, class instances). */
6
4
  export function isJsonValue(value) {
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The MCP connection: the protocol conversation (initialize handshake, tools/list pagination,
2
3
  // tools/call) over any transport. Lives in the RUN PROCESS — tool execution must happen where
3
4
  // the program runs — while OAuth token state stays parent-side (the transport's hook brokers
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // JSON-RPC 2.0 request/notification correlation for the hand-rolled MCP client (the
2
3
  // @modelcontextprotocol/sdk dependency tree was rejected for the flagship — zero new deps).
3
4
  // The transport moves frames; this layer owns ids, correlation, timeouts, and the trust
package/dist/mcp/oauth.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // PARENT-side OAuth 2.1 for MCP servers (MCP authorization spec, 2025-06-18): discovery
2
3
  // (RFC 9728 protected-resource metadata → RFC 8414 AS metadata), RFC 7591 dynamic client
3
4
  // registration, the authorization-code + PKCE (S256) grant with a loopback redirect, RFC 8707
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // PARENT-side MCP OAuth token persistence. Tokens live with the engine — never in the run
2
3
  // process beyond the single brokered value a request needs — in one JSON file under the data
3
4
  // dir, mode 0600 (they are credentials, treated like secrets: values
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // MCP streamable-HTTP transport (spec rev 2025-06-18 §Transports): every client message is a
2
3
  // POST to the server URL; the response is either a single JSON body or an SSE stream of
3
4
  // JSON-RPC messages (one shared parser with the provider adapters — src/agent/sse.ts). The
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // MCP stdio transport: spawn the server command and speak newline-delimited JSON over its
2
3
  // stdin/stdout (the MCP stdio framing). Runs in the RUN PROCESS — the program is the trusted
3
4
  // layer, so its inline `command`/`env` are honored as-is; the server's stderr is inherited so
package/dist/run/child.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The run-process entry point. Spawned by the supervisor with an IPC channel; never run
2
3
  // directly. Protocol: wait for `init`, install the SDK host + run inputs, then IMPORT the
3
4
  // program bundle — the module body is the program, so importing the file IS running it
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The WorkflowHost installed in the run process.
2
3
  //
3
4
  // Split of responsibilities (SPEC §2.3): anything that only needs the local process happens
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Default idempotency keys for workflows.call / workflows.run.
2
3
  //
3
4
  // Contract (SDK CallOptions): "a deterministic key over (parent_run_id, target, input)" — a
package/dist/run/ipc.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The supervisor ⇄ run-process IPC protocol.
2
3
  //
3
4
  // One run = one spawned Node process (SPEC §2.2). The child executes the user's program and
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // Per-run on-disk layout + the SDK-sharing symlink.
2
3
  //
3
4
  // <dataDir>/runs/<runId>/
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The run supervisor — owns run-lifecycle state transitions and process supervision
2
3
  // (SPEC §2.2). Layering: knows nothing about HTTP or the CLI; persistence
3
4
  // goes through the Store; what workflows *do* lives in the child process.
Binary file
@@ -1,8 +1,4 @@
1
- // Shared HTTP plumbing for the engine server: the error type every route throws, JSON
2
- // request/response helpers, and query/body parsing. Bare node:http is deliberate (no
3
- // third-party HTTP framework anywhere in the Boardwalk stack) — these helpers are the entire
4
- // "framework", so every trust boundary (bodies, query params, headers) is narrowed with Zod
5
- // or a type predicate before any engine call sees the data.
1
+ // SPDX-License-Identifier: Apache-2.0
6
2
  import { z } from "zod";
7
3
  import { CHANNELS, DEFAULT_CHANNELS } from "@boardwalk-labs/workflow";
8
4
  import { EngineError } from "../errors.js";
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The JSON API (SPEC §2.4): list workflows/runs, trigger a manual run, read a run + its
2
3
  // events, cancel. Handlers translate HTTP into engine/store calls and nothing else — all SQL
3
4
  // lives in the store, all run semantics in the engine.
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // POST /hooks/:workflow/:triggerIndex — the webhook trigger endpoint, and this engine's v0
2
3
  // answer to the open webhook-auth question (documented in SPEC §2.4):
3
4
  // per-workflow credentials live in *server* environment variables —
@@ -1,7 +1,4 @@
1
- // URL → handler resolution for the engine server. One flat match over decoded path segments —
2
- // the route table is small enough that a real trie/middleware stack would be pure ceremony.
3
- // Method mismatches on a known path get 405 + Allow (not 404), so clients can tell "wrong
4
- // verb" from "no such thing".
1
+ // SPDX-License-Identifier: Apache-2.0
5
2
  import { HttpError } from "../http.js";
6
3
  import { handleCancelRun, handleGetRun, handleListEvents, handleListRuns, handleListWorkflows, handleStartRun, } from "./api.js";
7
4
  import { handleWebhook } from "./hooks.js";
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // GET /api/runs/:id/stream — the SSE live tail (SPEC §2.4): replay
2
3
  // persisted events after the resume cursor, then follow live ones. Every frame carries
3
4
  // `id: <cursor>`, so a dropped client reconnects with Last-Event-ID and misses nothing —
@@ -1,7 +1,4 @@
1
- // GET / — the local run-log page (SPEC §2.4): one self-contained HTML document, no build
2
- // step, no external assets. It is a log viewer, not a console: list workflows, list recent
3
- // runs, click a run to tail it over the SSE endpoint. All rendering uses textContent — no
4
- // markup is ever built from API data, so nothing a workflow prints can inject into the page.
1
+ // SPDX-License-Identifier: Apache-2.0
5
2
  export function handleUiPage(ctx) {
6
3
  ctx.res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
7
4
  ctx.res.end(RUN_LOG_PAGE);
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The engine's HTTP surface (SPEC §2.4): JSON API + SSE live tail + webhook triggers + the
2
3
  // local run-log page, on bare node:http. This file owns the socket lifecycle only — routing
3
4
  // lives in routes/router.ts, and every handler goes through engine/store methods, never SQL.
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The composition root for the `boardwalk-server` binary (SPEC §2.4 + §5): parse config,
2
3
  // construct the Engine, mount the HTTP surface, wire graceful shutdown. Everything here is
3
4
  // glue — run semantics live in the engine, routing in the server, so this file stays thin
@@ -1,14 +1,4 @@
1
- // Versioned, forward-only schema migrations for the engine database.
2
- //
3
- // The schema version lives in SQLite's `PRAGMA user_version` (an integer in the database
4
- // header): reading it costs nothing, needs no bookkeeping table, and — crucially — setting it
5
- // participates in the same transaction as the migration's DDL. A crash mid-migration therefore
6
- // leaves the database exactly at the previous version with none of the new schema applied
7
- // (multi-row writes are transactional; a half-migrated database is a state
8
- // the engine could not recover from).
9
- //
10
- // Forward-only: an older engine refuses a newer database instead of guessing what future
11
- // columns mean. Downgrades are restore-from-backup, not code.
1
+ // SPDX-License-Identifier: Apache-2.0
12
2
  import { EngineError } from "../errors.js";
13
3
  // v1 — the full SPEC §4 schema. STRICT tables so SQLite enforces the declared column types
14
4
  // (a TEXT primary key can never silently hold an integer; INTEGER columns reject REALs).
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
1
2
  // The engine's one persistence module — every SQL statement in the engine lives here
2
3
  // (storage access goes through one persistence module). The backend is
3
4
  // node:sqlite, synchronous on purpose: a single-node engine gains nothing from an async
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boardwalk-labs/engine",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "The Boardwalk single-node engine: cron scheduling, run lifecycle, SQLite state, and the local run log. Powers `boardwalk dev` and the self-hosted server.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  "coverage": "vitest run --coverage"
41
41
  },
42
42
  "dependencies": {
43
- "@boardwalk-labs/workflow": "^0.1.0",
43
+ "@boardwalk-labs/workflow": "^0.1.2",
44
44
  "zod": "^4.0.0"
45
45
  },
46
46
  "devDependencies": {