Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .changeset/remove-repl-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
"@automatalabs/mcp-server": major
"@automatalabs/workflows": major
"@automatalabs/acp-agents": patch
"@automatalabs/pi-acp": patch
---

Remove the `repl` MCP tool and the `@automatalabs/repl-engine` package behind it.

The MCP server's model-facing surface is now the `workflow` tool plus the capability-gated `workflow_monitor` view (and the app-only `workflow-events`, `workflow-runs`, `workflow-notifications` tools). The interactive per-project QuickJS REPL, its broker, its snapshot store, and everything in the server that existed only to serve it are gone. `@automatalabs/repl-engine` is deleted from the workspace and will receive no further releases; no other package imported it.

**`@automatalabs/mcp-server` (breaking)**

- The `repl` tool is no longer registered; `SERVER_INSTRUCTIONS` describes `workflow` only.
- Removed exports: `replToolInputShape`, `replToolOutputShape`, `ReplToolOptions`, `createReplProjectState`, `ensureReplWorkspace`, `disposeReplProjectState`, `resetReplProjectState`, `renameAsideNeverOverwriting`, `ReplProjectState`, `ReplPresenceLedger`.
- `CreateWorkflowServerOptions` drops `replRunner`, `replPresence`, `replEvalBreakChannel`, `replDrainBoundMs` and `disconnectReplClientOnClose`. `replClientId` had one non-REPL job — scoping `workflow_monitor` notification claims per legacy-era MCP client — and is kept under its honest name, `clientId`.
- `WorkflowServerControl` drops `replBreakUrl()` (previously required), `replDefaultProjectDir()` and `disposeReplEvalBreakChannel()`. The shutdown hook the stdio entry used through the last of those is now the generic optional `dispose()`.
- The in-process stdio entry serves over the SDK's `StdioServerTransport`; the worker-thread relay transport that existed to break a synchronous eval out of band is removed, and the shim no longer intercepts `tools/call` to fire it.
- The daemon drops the REPL client-presence ledger and drain: `CreateDaemonOptions.replRunner` / `replDrainBoundMs` / `sessionTtlMs` / `evalBreakChannel`, `DaemonHandle.activeReplDrainCount()`, `WorkflowProjectRegistry.disposeReplStates()`, `ProjectContext.repl`, `DaemonInfo.replBreakUrl`, the `SessionRegistry` presence hooks (`onConnectionOpened`, `onLastConnectionClosed`, `onSessionDeleted`) and `evictDrainable`'s `keep` veto. Daemon idleness is sessions, runs and in-flight requests.
- Removed environment knobs: `AGENTPRISM_REPL_EVAL_TIMEOUT_MS`, `AGENTPRISM_REPL_DRAIN_BOUND_MS`.
- Existing per-project `repl/` stores on disk are left untouched and are no longer read.

**`@automatalabs/workflows` (breaking)**

- The MCP server bundled behind `npx @automatalabs/workflows mcp` no longer serves the `repl` tool, and the package no longer depends on `@automatalabs/repl-engine`. The programmatic SDK is unchanged.

**`@automatalabs/acp-agents`, `@automatalabs/pi-acp`**

- Documentation only: comments and README passages that attributed `InteractiveSession.awaitCurrentTurn()`, the `_session/loaded_turn` extension, the turn-text passthroughs, `onHandoff` and `runner.defaultBackendId()` to "the REPL broker" now describe them as the host re-attach surface they are. Those SDK and wire surfaces are unchanged and remain supported.
9 changes: 4 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Before changing code, read the relevant parts of:
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — development, tests, generated artifacts, dependency gates, attribution, PRs, and releases.
- [`README.md`](README.md) — product surface and package map.
- [`docs/api.md`](docs/api.md) — supported integration APIs.
- [`docs/authoring/`](docs/authoring/) — canonical workflow and REPL authoring documentation shipped through MCP.
- [`docs/authoring/`](docs/authoring/) — canonical workflow authoring documentation shipped through MCP.

Then read the code. The source and its tests are the current state; prose describes it and never governs it. When prose and code disagree, fix the prose.

Expand All @@ -36,20 +36,19 @@ Do not add temporary compatibility layers unless the user explicitly requests on

## Architecture and package boundaries

This is a pnpm monorepo of ten `@automatalabs/*` packages:
This is a pnpm monorepo of nine `@automatalabs/*` packages:

- `shared-types`: shared seams and wire/result types.
- `workflow-engine`: deterministic workflow execution, journaling, resume, checkpoints, and isolation.
- `acp-agents`: ACP client and backend integration for Claude, Codex, OpenCode, pi, and custom agents.
- `acp-server`: connection-pinned ACP proxy and backend-discovery server.
- `workflows`: the public SDK facade composing the engine and ACP runner.
- `repl-engine`: persistent QuickJS REPL orchestration over the same backend stack.
- `mcp-server`: MCP composition root exposing `workflow`, `repl`, the Apps-capable `workflow_monitor`, and SEP-2640 authoring skills.
- `mcp-server`: MCP composition root exposing `workflow`, the Apps-capable `workflow_monitor`, and SEP-2640 authoring skills.
- `pi-acp`: in-process pi ACP server.
- `codex-acp`: published fork maintained as a non-squashed upstream subtree.
- `agentprism-otel`: optional observability bridge.

Keep `workflow-engine` backend-agnostic and `acp-agents` engine-agnostic; they meet through `shared-types`. The primary runtime direction is `mcp-server → {workflows, repl-engine, shared-types}`, `acp-server → acp-agents`, `workflows → {workflow-engine, acp-agents, shared-types}`, `repl-engine → {workflows, acp-agents, shared-types}`, and `acp-agents → {codex-acp, pi-acp, shared-types}`.
Keep `workflow-engine` backend-agnostic and `acp-agents` engine-agnostic; they meet through `shared-types`. The primary runtime direction is `mcp-server → {workflows, shared-types}`, `acp-server → acp-agents`, `workflows → {workflow-engine, acp-agents, shared-types}`, and `acp-agents → {codex-acp, pi-acp, shared-types}`.

For MCP server work, preserve the deliberate SDK boundary: production server code uses the split MCP SDK v2 packages, legacy 2025 and modern `2026-07-28` traffic share one implementation through era-specific transport seams, and no v1 SDK object may be passed into a v2 API. `@modelcontextprotocol/ext-apps` remains browser-build/test-side; production server code must not import its v1 server helpers.

Expand Down
7 changes: 3 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing

This is a **pnpm workspace** (monorepo) of ten packages under the `@automatalabs` scope. The user-facing overview is in [`README.md`](README.md); the integration API is in [`docs/api.md`](docs/api.md).
This is a **pnpm workspace** (monorepo) of nine packages under the `@automatalabs` scope. The user-facing overview is in [`README.md`](README.md); the integration API is in [`docs/api.md`](docs/api.md).

## Prerequisites

Expand Down Expand Up @@ -30,14 +30,13 @@ pnpm typecheck # pnpm -r exec tsc --noEmit
| `packages/workflow-engine` | The deterministic engine (realm, parallel/pipeline, journal/resume, budget, worktree). |
| `packages/acp-agents` | ACP client + Claude/Codex/OpenCode/pi/custom backends (the `AgentRunner` implementation, pooling, auth/session lifecycle). |
| `packages/acp-server` | Connection-pinned ACP V1 proxy over stdio, Streamable HTTP, or WebSocket, with extension-negotiated backend discovery (bin `agentprism-acp-server`). |
| `packages/mcp-server` | The stdio MCP server / composition root (bin `agentprism-workflow`; the `workflow` and `repl` tools plus the Apps-capable `workflow_monitor` launcher — no auth tools). |
| `packages/mcp-server` | The stdio MCP server / composition root (bin `agentprism-workflow`; the `workflow` tool plus the Apps-capable `workflow_monitor` launcher — no auth tools). |
| `packages/workflows` | The importable SDK facade. |
| `packages/agentprism-otel` | Optional OpenTelemetry bridge for `WorkflowManager` events. |
| `packages/repl-engine` | The REPL orchestrator engine: persistent JS REPL in a QuickJS-in-WASM VM (workspace lifecycle, eval + job drain, per-VM memory limits, per-eval interrupts). |
| `packages/pi-acp` | Standalone in-process ACP server and library adapter for the pi coding agent. |
| `packages/codex-acp` | Our codex-acp fork (full upstream history, non-squashed subtree): the ACP server the Codex backend spawns. |

`workflow-engine` and `acp-agents` are **siblings** — neither imports the other; they meet only at the `AgentRunner` seam in `shared-types`. `workflows` is the single facade that composes them; `mcp-server` builds on `workflows`, while `acp-server` builds directly on `acp-agents`. So the primary dependency direction is `mcp-server → workflows → { workflow-engine, acp-agents, shared-types }` and `acp-server → acp-agents`. `agentprism-otel` is an independent leaf with an `@opentelemetry/api` peer dependency; it observes the manager structurally and is not in that runtime chain. `repl-engine` is **not** a leaf: it composes the `quickjs-wasi` shim with `workflows`, `acp-agents`, and `shared-types`, and its `repl` MCP tool is registered in `mcp-server` (which depends on `repl-engine`) — the `repl-orchestrator` roadmap phase is implemented (`docs/roadmap/repl-orchestrator.md`) and the package is published independently.
`workflow-engine` and `acp-agents` are **siblings** — neither imports the other; they meet only at the `AgentRunner` seam in `shared-types`. `workflows` is the single facade that composes them; `mcp-server` builds on `workflows`, while `acp-server` builds directly on `acp-agents`. So the primary dependency direction is `mcp-server → workflows → { workflow-engine, acp-agents, shared-types }` and `acp-server → acp-agents`. `agentprism-otel` is an independent leaf with an `@opentelemetry/api` peer dependency; it observes the manager structurally and is not in that runtime chain.

### Conventions

Expand Down
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ Run **dynamic, multi-agent workflow scripts** — `agent()`, `parallel()`, `pipe
**Your agent authors** a small JavaScript *script* (`export const meta`, then call `agent()` / `parallel()` / `pipeline()`); the engine runs it in a sandboxed realm, fanning each `agent()` call out to an [Agent Client Protocol](https://agentclientprotocol.com) (ACP) backend. It's available two ways:

- **As a TypeScript SDK** — `@automatalabs/workflows` — embed the runner in your own program.
- **As a stdio MCP server** — `@automatalabs/mcp-server`, built on the SDK — expose `workflow` and `repl` tools to any MCP host (Claude Code, Zed, …).
- **As a stdio MCP server** — `@automatalabs/mcp-server`, built on the SDK — expose the `workflow` tool to any MCP host (Claude Code, Zed, …).

> All ten `@automatalabs/*` packages are **published on npm** — see [Install](#install). Two are primary workflow entry points: the `@automatalabs/workflows` SDK and the `@automatalabs/mcp-server` stdio server. `@automatalabs/acp-server` is the extension-aware ACP aggregation entry point.
> All nine `@automatalabs/*` packages are **published on npm** — see [Install](#install). Two are primary workflow entry points: the `@automatalabs/workflows` SDK and the `@automatalabs/mcp-server` stdio server. `@automatalabs/acp-server` is the extension-aware ACP aggregation entry point.

---

Expand Down Expand Up @@ -117,8 +117,6 @@ One process plays **two protocol roles at once**: it's an **MCP server** (or a l

The deterministic engine (sandboxed `vm` realm, `parallel`/`pipeline`, journal/resume, worktree isolation) is independent of *how* a single agent runs and of *how* the tool is exposed.

The MCP server also exposes a second, **interactive** route: the `repl` tool. Instead of running a deterministic script to completion, it holds a persistent **QuickJS-in-WASM VM per project** (the [`@automatalabs/repl-engine`](packages/repl-engine) tier), and the client's own agent writes live JavaScript that spawns subagents over the same ACP path — workspace state (bindings, pending calls, checkpoints, logged values) persisting between tool calls and across daemon restarts. Workflows is the batch orchestrator; `repl` is the live steering plane. See [The `repl` tool](packages/mcp-server/README.md#the-repl-tool).

---

## Requirements
Expand Down Expand Up @@ -162,7 +160,7 @@ These are the packages you interact with directly. The first two are the primary
| Package | What it is |
|---|---|
| **`@automatalabs/workflows`** | The canonical public **SDK** — a thin facade that runs workflow scripts programmatically over the default ACP backend, and re-exports the supported engine + backend integration surface. Start here. |
| **`@automatalabs/mcp-server`** | The stdio **MCP server** (bin: `agentprism-workflow`) exposing the `workflow` tool (asynchronous run/resume, setup response, bounded status/result, permission response, stop, and an Apps monitor) and the `repl` tool (a persistent JavaScript REPL for live subagent orchestration) — built on `@automatalabs/workflows` and `@automatalabs/repl-engine`. |
| **`@automatalabs/mcp-server`** | The stdio **MCP server** (bin: `agentprism-workflow`) exposing the `workflow` tool (asynchronous run/resume, setup response, bounded status/result, permission response, stop, and an Apps monitor) — built on `@automatalabs/workflows`. |
| **`@automatalabs/acp-server`** | The extension-aware **ACP proxy** (bin: `agentprism-acp-server`) over stdio, Streamable HTTP, or WebSocket: probe every configured backend on a discovery connection, then pin each operational connection to Claude, Codex, OpenCode, pi, or a custom ACP server. |
| **`@automatalabs/pi-acp`** | The standalone stdio **ACP server** (bin: `pi-acp`) embedding the pi coding agent in-process; exact-pinned and spawned by the first-class `pi` backend. |

Expand All @@ -172,17 +170,16 @@ One optional integration package attaches to the SDK's manager surface:
|---|---|
| **`@automatalabs/agentprism-otel`** | OpenTelemetry traces and metrics for a `WorkflowManager`; peer-depends only on `@opentelemetry/api` and no-ops when the host has no OTel SDK. |

The five packages below are **internal building blocks**. Most are composed by the SDK (`@automatalabs/workflows` → `workflow-engine`, `acp-agents`, `shared-types`); the exceptions are `@automatalabs/repl-engine`, which **depends on** the SDK and is composed by the **MCP server** (which registers its `repl` tool), and `@automatalabs/codex-acp`, which is spawned by `acp-agents`. You normally don't depend on any of them directly: `@automatalabs/workflows` is the public entry point for the supported orchestration surface.
The four packages below are **internal building blocks**. Most are composed by the SDK (`@automatalabs/workflows` → `workflow-engine`, `acp-agents`, `shared-types`); the exception is `@automatalabs/codex-acp`, which is spawned by `acp-agents`. You normally don't depend on any of them directly: `@automatalabs/workflows` is the public entry point for the supported orchestration surface.

| Package | What it is |
|---|---|
| **`@automatalabs/acp-agents`** | The ACP client + Claude/Codex/OpenCode/pi/custom backends (the `AgentRunner` implementation, connection pooling, auth/session lifecycle, structured output, permissions, usage) and the `AcpAgent` SDK (one dedicated process per held-open agent, forks, cold reopen). Internal — public entry is `@automatalabs/workflows`. |
| **`@automatalabs/workflow-engine`** | The deterministic engine: the script realm, `parallel`/`pipeline`, journal/resume, and worktree isolation. Internal — public entry is `@automatalabs/workflows`. |
| **`@automatalabs/repl-engine`** | The published REPL orchestrator engine: a persistent JavaScript REPL in a capability-free QuickJS-in-WASM VM (workspace lifecycle, eval + job drain, per-VM memory limits, per-eval interrupts, trap-free completion reads, the append-only call store and enveloped snapshots). Its `repl` MCP tool is registered in `mcp-server` (the roadmap's `repl-orchestrator`, phase E — implemented); it depends on `workflows`, `acp-agents` (subagents are ACP sessions), and `shared-types`. |
| **`@automatalabs/codex-acp`** | The workspace fork of `agentclientprotocol/codex-acp` (imported with full history) — the ACP server the Codex backend spawns, baking turn-level `outputSchema` forwarding into its shipped dist. Consumed by `@automatalabs/acp-agents` as `workspace:*`; you never depend on it directly. |
| **`@automatalabs/shared-types`** | The `AgentRunner` seam + shared types the others compose against. Internal — public entry is `@automatalabs/workflows`. |

Dependency direction: `mcp-server` → `{ workflows, repl-engine, shared-types }`; `acp-server` → `acp-agents`; `workflows` → `{ workflow-engine, acp-agents, shared-types }`; `acp-agents` → `{ codex-acp, pi-acp, shared-types }`; `repl-engine` → `{ workflows, acp-agents, shared-types }`. The SDK (`workflows`) is the single facade that composes the deterministic engine and the ACP backend, which meet only at the `AgentRunner` seam in `shared-types`. The engine never names a backend; the agents never know they're inside a workflow. `acp-agents` spawns the bundled `codex-acp` / `pi-acp` ACP servers as its Codex and pi backends. `repl-engine` composes the QuickJS-in-WASM shim with `workflows` (for the shared per-project key) and `acp-agents` (the REPL's subagents are ACP sessions against the same backends the SDK drives), and ships its `repl` tool in `mcp-server`.
Dependency direction: `mcp-server` → `{ workflows, shared-types }`; `acp-server` → `acp-agents`; `workflows` → `{ workflow-engine, acp-agents, shared-types }`; `acp-agents` → `{ codex-acp, pi-acp, shared-types }`. The SDK (`workflows`) is the single facade that composes the deterministic engine and the ACP backend, which meet only at the `AgentRunner` seam in `shared-types`. The engine never names a backend; the agents never know they're inside a workflow. `acp-agents` spawns the bundled `codex-acp` / `pi-acp` ACP servers as its Codex and pi backends.

### Published ACP registry

Expand Down Expand Up @@ -523,7 +520,7 @@ both call rows and activity. Its structured payload, including `latestActivity`,
UTF-8 bytes and its text at 8,192 bytes.
Paused, failed, and aborted outcomes also include a redacted final-20 `logTail` immediately.

The model-facing tools are `workflow`, `repl`, and the capability-gated `workflow_monitor`; `repl` is a persistent QuickJS-in-WASM JavaScript VM (one per project) for live, stateful orchestration. The server also advertises `agentprism-workflow-authoring` through the MCP Skills Extension, and prompt-capable hosts get the compact user-controlled **`author-workflow`** MCP prompt (optional `task` argument). Backend auth belongs to the agents' credential sources (`claude /login`, `codex login`, `opencode auth login`, Pi provider environment keys, or `~/.pi/agent/auth.json`) — configured credentials need no extra step. An `AUTH_REQUIRED` fault pauses the workflow with `reason: "auth_required"` and a non-secret `authContext` naming the backend; configure that credential out-of-band, then call `{ "action":"resume", "runId":"…" }` for the paused source. Programmatic auth/provider management lives in the `@automatalabs/workflows` SDK runner APIs.
The model-facing tools are `workflow` and the capability-gated `workflow_monitor`. The server also advertises `agentprism-workflow-authoring` through the MCP Skills Extension, and prompt-capable hosts get the compact user-controlled **`author-workflow`** MCP prompt (optional `task` argument). Backend auth belongs to the agents' credential sources (`claude /login`, `codex login`, `opencode auth login`, Pi provider environment keys, or `~/.pi/agent/auth.json`) — configured credentials need no extra step. An `AUTH_REQUIRED` fault pauses the workflow with `reason: "auth_required"` and a non-secret `authContext` naming the backend; configure that credential out-of-band, then call `{ "action":"resume", "runId":"…" }` for the paused source. Programmatic auth/provider management lives in the `@automatalabs/workflows` SDK runner APIs.

---

Expand Down
Loading
Loading