Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
95db7ba
docs(stack): align runtime architecture documentation
jgoux Aug 5, 2026
b2943a0
fix(process-compose): make unhealthy lifecycle terminal
jgoux Aug 5, 2026
7d19e70
refactor(stack): establish explicit domain model
jgoux Aug 5, 2026
c4aabe0
chore(stack): integrate lifecycle prerequisites
jgoux Aug 5, 2026
442698f
refactor(process-compose): isolate supervisor policies
jgoux Aug 5, 2026
3e56622
refactor(stack): consolidate local lifecycle ownership
jgoux Aug 5, 2026
854f874
Merge remote-tracking branch 'origin/develop' into agent/stack-domain…
jgoux Aug 5, 2026
47d1387
Merge branch 'agent/stack-domain-model' into agent/stack-runtime-impl…
jgoux Aug 5, 2026
d6dd4dd
chore(process-compose): merge current develop
jgoux Aug 5, 2026
a596636
chore(process-compose): update supervisor branch base
jgoux Aug 5, 2026
d188f8b
Merge remote-tracking branch 'origin/develop' into agent/stack-domain…
jgoux Aug 5, 2026
fa591c0
Merge branch 'agent/stack-domain-model' into agent/stack-runtime-impl…
jgoux Aug 5, 2026
8e2ed76
fix(process-compose): handle terminal health failures
jgoux Aug 5, 2026
21b5638
Merge branch 'agent/process-compose-lifecycle-correctness' into agent…
jgoux Aug 5, 2026
57979d5
fix(process-compose): bound supervisor cleanup commands
jgoux Aug 5, 2026
daeffc2
Merge branch 'agent/process-compose-lifecycle-correctness' into agent…
jgoux Aug 5, 2026
3817fcd
fix(stack): scope readiness deadlines to health waits
jgoux Aug 5, 2026
77782df
test(stack): await lazy Docker service readiness
jgoux Aug 5, 2026
b7e84b6
fix(stack): terminate daemon after lazy timeout
jgoux Aug 5, 2026
d24cdb9
fix(process-compose): surface recovery hook failures
jgoux Aug 5, 2026
384e0ee
Merge branch 'agent/process-compose-lifecycle-correctness' into agent…
jgoux Aug 5, 2026
4c9bb66
Merge branch 'agent/process-compose-supervisor-cleanup' into agent/st…
jgoux Aug 5, 2026
6017cc3
test(process-compose): cover recovery hook transition
jgoux Aug 5, 2026
7aec419
Merge branch 'agent/process-compose-supervisor-cleanup' into agent/st…
jgoux Aug 5, 2026
f1ade49
fix(process-compose): fail blocked healthy dependents
jgoux Aug 5, 2026
851479d
Merge branch 'agent/process-compose-lifecycle-correctness' into agent…
jgoux Aug 5, 2026
ccdc785
Merge branch 'agent/process-compose-supervisor-cleanup' into agent/st…
jgoux Aug 5, 2026
27e8561
fix(process-compose): hard-kill timed-out cleanup
jgoux Aug 5, 2026
7fe14af
Merge branch 'agent/process-compose-supervisor-cleanup' of github.com…
jgoux Aug 5, 2026
a1f7a11
fix(stack): make readiness teardown terminal
jgoux Aug 5, 2026
42c775c
fix(process-compose): await restartable dependencies
jgoux Aug 5, 2026
39cc38d
Merge branch 'agent/process-compose-lifecycle-correctness' of github.…
jgoux Aug 5, 2026
c9de7d0
Merge branch 'agent/process-compose-supervisor-cleanup' of github.com…
jgoux Aug 5, 2026
48a6057
fix(stack): synchronize status after readiness
jgoux Aug 5, 2026
62f861a
Merge branch 'agent/process-compose-lifecycle-correctness' of github.…
jgoux Aug 5, 2026
0985e68
Merge branch 'agent/process-compose-supervisor-cleanup' of github.com…
jgoux Aug 5, 2026
c9de546
fix(stack): derive startup coordination timeouts
jgoux Aug 5, 2026
759dd1f
Merge branch 'agent/process-compose-lifecycle-correctness' of github.…
jgoux Aug 5, 2026
6f815fb
Merge branch 'agent/process-compose-supervisor-cleanup' of github.com…
jgoux Aug 5, 2026
a14d408
fix(stack): align startup budget deadlines
jgoux Aug 6, 2026
db7d015
fix(process-compose): await restarting completed dependencies
jgoux Aug 6, 2026
2c825a0
chore(process-compose): integrate lifecycle hardening
jgoux Aug 6, 2026
6a1cdfe
chore(stack): integrate lifecycle hardening
jgoux Aug 6, 2026
af6c027
fix(stack): align dependent startup deadlines
jgoux Aug 6, 2026
908ed4d
chore(stack): document dependency startup path
jgoux Aug 6, 2026
5a298f1
test(stack): align Docker setup timeout
jgoux Aug 6, 2026
1184ec5
fix(process-compose): terminate timed-out cleanup trees
jgoux Aug 6, 2026
e01aaf7
fix(stack): align activation lifecycle ownership
jgoux Aug 6, 2026
5bd8454
Merge remote-tracking branch 'origin/agent/process-compose-supervisor…
jgoux Aug 6, 2026
65feb43
Merge remote-tracking branch 'origin/agent/process-compose-lifecycle-…
jgoux Aug 6, 2026
e403043
Merge remote-tracking branch 'origin/agent/process-compose-supervisor…
jgoux Aug 6, 2026
7505537
fix(stack): close foreground runtime on readiness timeout
jgoux Aug 6, 2026
e089d7d
fix(process-compose): preserve active restart policy
jgoux Aug 6, 2026
f275859
fix(stack): serialize projected state snapshots
jgoux Aug 6, 2026
6a737c2
Merge remote-tracking branch 'origin/agent/process-compose-lifecycle-…
jgoux Aug 6, 2026
eb18b78
Merge remote-tracking branch 'origin/agent/process-compose-supervisor…
jgoux Aug 6, 2026
ed31de0
fix(process-compose): use active policy for readiness
jgoux Aug 6, 2026
267de27
fix(stack): budget native database initialization
jgoux Aug 6, 2026
58c889b
Merge branch 'agent/process-compose-lifecycle-correctness' into agent…
jgoux Aug 6, 2026
bd2aa0a
Merge branch 'agent/process-compose-supervisor-cleanup' into agent/st…
jgoux Aug 6, 2026
eeac2a0
fix(process-compose): handle stopped dependencies
jgoux Aug 6, 2026
1131ac6
Merge branch 'agent/process-compose-lifecycle-correctness' into agent…
jgoux Aug 6, 2026
24a9dca
Merge branch 'agent/process-compose-supervisor-cleanup' into agent/st…
jgoux Aug 6, 2026
6b27914
Merge remote-tracking branch 'origin/develop' into agent/stack-domain…
jgoux Aug 6, 2026
4358f44
Merge remote-tracking branch 'origin/agent/stack-domain-model' into a…
jgoux Aug 6, 2026
3ced584
Merge remote-tracking branch 'origin/agent/process-compose-supervisor…
jgoux Aug 6, 2026
2434029
Merge remote-tracking branch 'origin/develop' into agent/stack-runtim…
jgoux Aug 6, 2026
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
26 changes: 15 additions & 11 deletions packages/stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ service and its projected status.
### Readiness

```typescript
await stack.ready(); // Inherit the stack's finite two-minute default
await stack.ready(); // Inherit the stack's finite three-minute default
await stack.ready({ mode: "finite", timeoutMs: 30_000 });
await stack.ready({ mode: "infinite" }); // Explicit debugging override
await stack.serviceReady("postgres");
Expand All @@ -209,7 +209,10 @@ In eager mode, `start()` blocks until every enabled service is ready. In lazy mo
for direct listeners and services activated so far. Unrequested lazy services report `Dormant`.
Calling `serviceReady()` for a dormant lazy
service fails immediately; activate it through the proxy or call `startService()` first. Foreground
and detached stacks use the same readiness rules.
and detached stacks use the same readiness rules. The configured policy also applies to service
start, restart, activation, and reload operations; a call-specific option overrides it. A finite
deadline fails with `STACK_READINESS_TIMEOUT` and disposes the local runtime, so the handle cannot
be used to relaunch processes afterward.

### Status

Expand Down Expand Up @@ -308,15 +311,16 @@ try {
}
```

| Code | Description |
| ------------------- | -------------------------------------------- |
| `SERVICE_NOT_FOUND` | Referenced a service that doesn't exist |
| `SERVICE_NOT_READY` | Service failed to become healthy |
| `BUILD_ERROR` | Failed to build the service dependency graph |
| `BINARY_NOT_FOUND` | No binary available for the current platform |
| `DOWNLOAD_ERROR` | Binary download failed |
| `PORT_CONFLICT` | Requested port is already in use |
| `PORT_ALLOCATION` | Failed to allocate a free port |
| Code | Description |
| ------------------------- | -------------------------------------------- |
| `SERVICE_NOT_FOUND` | Referenced a service that doesn't exist |
| `SERVICE_NOT_READY` | Service failed to become healthy |
| `STACK_READINESS_TIMEOUT` | Stack readiness exceeded its finite deadline |
| `BUILD_ERROR` | Failed to build the service dependency graph |
| `BINARY_NOT_FOUND` | No binary available for the current platform |
| `DOWNLOAD_ERROR` | Binary download failed |
| `PORT_CONFLICT` | Requested port is already in use |
| `PORT_ALLOCATION` | Failed to allocate a free port |

## Examples

Expand Down
29 changes: 17 additions & 12 deletions packages/stack/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ functions options, and per-service configuration. `false` disables an optional s
4. applies per-service defaults and current `DEFAULT_VERSIONS`;
5. records auto-managed paths for scoped cleanup.

Readiness policy is part of the resolved configuration. The package default is a finite two-minute
Readiness policy is part of the resolved configuration. The package default is a finite three-minute
deadline; callers can choose a different finite deadline or explicit infinite waiting. Per-call
`ReadyOptions` take precedence over the stack policy, while `inherit` delegates to the stack
policy. The Promise `ready()` / `serviceReady()` Adapter applies that resolver today. The Effect
lifecycle Interface remains unbounded until deadline enforcement is centralized there.
policy. The local Implementation applies this resolver to startup, service activation, restart,
reload, and explicit readiness waits. A finite deadline fails with `StackReadinessError` and runs
the same scoped cleanup used by disposal. Promise and remote Adapters pass `ReadyOptions` through
to that Implementation instead of layering a second timeout rule around it.

The current zero-config stack enables PostgreSQL, PostgREST, Auth, and Edge Runtime. Realtime,
Storage, imgproxy, Mailpit, Postgres Meta, Studio, Analytics, Vector, and Supavisor are enabled only
Expand Down Expand Up @@ -119,7 +121,7 @@ Vector without Analytics, and Studio without Postgres Meta.

## Lifecycle ownership

The current local Implementation is `StackLifecycleCoordinator`. It owns one scoped lifecycle:
The local Implementation is `LocalStack`. Its scoped layer owns one lifecycle:

- preparation and its single-flight deferred;
- graph construction and the process-compose runtime;
Expand All @@ -129,19 +131,21 @@ The current local Implementation is `StackLifecycleCoordinator`. It owns one sco
- exact cleanup targets and metadata persistence;
- disposal of processes, Docker resources, ports, and auto-managed paths.

`Stack.ts` currently provides a thin public Effect Interface over that coordinator. `ApiProxy`
uses the narrower `StackServiceActivator` Interface so an incoming request can activate a lazy
backend without gaining unrelated lifecycle operations.
`Stack.ts` contains only the public Effect Interface and transport schemas. `LocalStack` constructs
the state once and publishes both `Stack` and the narrower `StackServiceActivator` Interface from
the same scoped layer. `ApiProxy` therefore activates a lazy backend without gaining unrelated
lifecycle operations or requiring a second pass-through lifecycle tag.

Before the orchestrator exists, the coordinator publishes synthetic `Pending` and `Downloading`
Before the orchestrator exists, `LocalStack` publishes synthetic `Pending` and `Downloading`
states. After construction, it subscribes to raw process-compose state and publishes only public
projected states. `StackServiceState` adds `Downloading`, `Initializing`, and `Dormant` to the raw
process statuses.

`start()` prepares artifacts, creates the runtime once, starts the appropriate services, and waits
for their generic process-compose readiness. `stop()` preserves explicit per-service stop intent;
`dispose()` additionally closes the scoped runtime and executes cleanup. Generic process-compose
readiness remains intentionally policy-free and unbounded.
`dispose()` additionally closes the scoped runtime and executes cleanup. Stack readiness policy is
enforced around generic process-compose waits, which remain intentionally policy-free and
unbounded. Structural `Equal.equals` comparison suppresses duplicate projected state emissions.

## Eager and lazy activation

Expand Down Expand Up @@ -237,8 +241,9 @@ Detached mode adds:
- `StateManager`: atomically persists and discovers durable metadata and live state.

The management transport includes health, status, status stream, start/stop, readiness,
per-service lifecycle, logs/history, and Edge Runtime reload routes. It is local Unix-socket
transport, not the public Supabase API proxy.
per-service lifecycle, logs/history, and Edge Runtime reload routes. Readiness waits use validated
`ReadyOptions` JSON bodies and preserve `StackReadinessError` across the transport. It is local
Unix-socket transport, not the public Supabase API proxy.

See [detach mode](./detach-mode.md) for paths, process startup, and compiled executable dispatch.

Expand Down
18 changes: 14 additions & 4 deletions packages/stack/docs/detach-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,16 @@ metadata and service data remain.
`DaemonServer` exposes the local `Stack` Interface on the Unix socket. Current routes include:

- `/health`, `/status`, and `/status/stream`;
- `/start`, `/stop`, and `/ready`;
- `/start`, `/stop`, and `POST /ready`;
- per-service start, stop, restart, and readiness;
- merged and per-service live logs plus buffered history;
- functions and Edge Runtime reload.

State and log streams use SSE. Ordinary responses and typed failures use validated JSON shapes.
`RemoteStack` decodes that transport back into the same Effect `Stack` Interface used in
foreground mode, including `ServiceNotFoundError`, `ServiceReadyError`, and `StackBuildError`.
State and log streams use SSE. Readiness routes use `POST` with a validated readiness-policy body;
omitting an override sends the explicit `inherit` representation. Ordinary responses and typed
failures use validated JSON shapes. `RemoteStack` decodes that transport back into the same Effect
`Stack` Interface used in foreground mode, including `ServiceNotFoundError`, `ServiceReadyError`,
`StackBuildError`, and `StackReadinessError`.

The management socket is not the public local API endpoint. `ApiProxy` still owns the configured
HTTP API port inside the daemon process.
Expand All @@ -141,6 +143,14 @@ package. In particular:
On normal `/stop`, the daemon gracefully stops the stack, signals HTTP shutdown after the response
has had time to flush, disposes both managed runtimes, and removes live state/runtime paths.

A readiness deadline is terminal for that local runtime: the stack disposes its scoped resources,
the daemon returns the typed timeout response, and then the daemon shuts down. This prevents later
requests from relaunching processes after cleanup has already run. The boundary is deliberately
fail-closed across the whole daemon, rather than isolated to the service that timed out: once
processes and port leases are being released, the management and proxy servers cannot safely keep
advertising a usable runtime. This terminal path does not drain unrelated in-flight requests to
otherwise healthy services; callers must reconnect after starting a fresh daemon.

If the daemon has died, CLI stop/status detects a stale PID. Stop can use cleanup targets persisted
in `stack.json` to force-remove known Docker containers before removing the stale state. This
crash-recovery metadata is deliberately separate from user-facing `/status` connection data.
Expand Down
62 changes: 32 additions & 30 deletions packages/stack/src/ApiProxy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Effect, Layer, Option, Context, Duration, Schedule, Result } from "effect";
import { Deferred, Effect, Layer, Option, Context, Schedule, Result } from "effect";
import {
Headers,
HttpBody,
Expand All @@ -9,12 +9,11 @@ import {
HttpServerRequest,
HttpServerResponse,
} from "effect/unstable/http";
import { activationTimeoutSecondsForService, StackServiceActivator } from "./ServiceActivation.ts";
import type { ServiceName } from "./versions.ts";
import { StackServiceActivator } from "./ServiceActivation.ts";
import type { ServiceName } from "./ServiceName.ts";

export interface ProxyConfig {
readonly listenPort: number;
readonly activationTimeout?: Duration.Input;
readonly gotruePort: number;
readonly postgrestPort: number;
readonly postgrestAdminPort: number;
Expand Down Expand Up @@ -132,19 +131,17 @@ function makeProxyHandler(
client: HttpClient.HttpClient,
config: ProxyConfig,
activator: StackServiceActivator["Service"],
signalTerminalFailure: Effect.Effect<void>,
opts: ProxyHandlerOptions,
) {
return (req: HttpServerRequest.HttpServerRequest) =>
Effect.gen(function* () {
const activation = yield* activator
.activate(opts.service)
.pipe(
Effect.timeout(
config.activationTimeout ??
Duration.seconds(activationTimeoutSecondsForService(opts.service)),
),
Effect.result,
);
const activation = yield* activator.activate(opts.service).pipe(
Effect.tapError((error) =>
error._tag === "StackReadinessError" ? signalTerminalFailure : Effect.void,
),
Effect.result,
);
if (Result.isFailure(activation)) {
return HttpServerResponse.text("Service unavailable", {
status: 503,
Expand Down Expand Up @@ -225,6 +222,8 @@ export class ApiProxy extends Context.Service<
ApiProxy,
{
readonly address: HttpServer.Address;
/** Completes when terminal lazy-activation failure requires daemon teardown. */
readonly awaitTerminalFailure: Effect.Effect<void>;
}
>()("local/ApiProxy") {
static layer = (
Expand All @@ -239,13 +238,15 @@ export class ApiProxy extends Context.Service<
const server = yield* HttpServer.HttpServer;
const client = yield* HttpClient.HttpClient;
const activator = yield* StackServiceActivator;
const terminalFailure = yield* Deferred.make<void>();
const signalTerminalFailure = Deferred.succeed(terminalFailure, void 0).pipe(Effect.asVoid);

const routes = [
HttpRouter.route("*", "/health", HttpServerResponse.text("OK", { status: 200 })),
HttpRouter.route(
"*",
"/.well-known/oauth-authorization-server",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "auth",
backendPort: config.gotruePort,
backendPath: "/.well-known/oauth-authorization-server",
Expand All @@ -254,7 +255,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/auth/v1/verify",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "auth",
backendPort: config.gotruePort,
stripPrefix: "/auth/v1",
Expand All @@ -263,7 +264,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/auth/v1/callback",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "auth",
backendPort: config.gotruePort,
stripPrefix: "/auth/v1",
Expand All @@ -272,7 +273,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/auth/v1/authorize",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "auth",
backendPort: config.gotruePort,
stripPrefix: "/auth/v1",
Expand All @@ -281,7 +282,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/auth/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "auth",
backendPort: config.gotruePort,
stripPrefix: "/auth/v1",
Expand All @@ -291,7 +292,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/rest/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "postgrest",
backendPort: config.postgrestPort,
stripPrefix: "/rest/v1",
Expand All @@ -301,7 +302,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/rest-admin/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "postgrest",
backendPort: config.postgrestAdminPort,
stripPrefix: "/rest-admin/v1",
Expand All @@ -310,7 +311,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/graphql/v1",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "postgrest",
backendPort: config.postgrestPort,
backendPath: "/rpc/graphql",
Expand All @@ -321,7 +322,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/functions/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "edge-runtime",
backendPort: config.edgeRuntimePort,
stripPrefix: "/functions/v1",
Expand All @@ -333,7 +334,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/realtime/v1/api/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "realtime",
backendPort: config.realtimePort,
stripPrefix: "/realtime/v1",
Expand All @@ -343,7 +344,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/realtime/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "realtime",
backendPort: config.realtimePort,
stripPrefix: "/realtime/v1",
Expand All @@ -352,7 +353,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/storage/v1/s3/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "storage",
backendPort: config.storagePort,
stripPrefix: "/storage/v1",
Expand All @@ -361,7 +362,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/storage/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "storage",
backendPort: config.storagePort,
stripPrefix: "/storage/v1",
Expand All @@ -371,7 +372,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/pg/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "pgmeta",
backendPort: config.pgmetaPort,
stripPrefix: "/pg",
Expand All @@ -380,7 +381,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/analytics/v1/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "analytics",
backendPort: config.analyticsPort,
stripPrefix: "/analytics/v1",
Expand All @@ -389,7 +390,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/pooler/v2/*",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "pooler",
backendPort: config.poolerPort,
stripPrefix: "/pooler",
Expand All @@ -398,7 +399,7 @@ export class ApiProxy extends Context.Service<
HttpRouter.route(
"*",
"/mcp",
makeProxyHandler(client, config, activator, {
makeProxyHandler(client, config, activator, signalTerminalFailure, {
service: "studio",
backendPort: config.studioPort,
backendPath: "/api/mcp",
Expand All @@ -423,6 +424,7 @@ export class ApiProxy extends Context.Service<

return {
address: server.address,
awaitTerminalFailure: Deferred.await(terminalFailure),
};
}),
);
Expand Down
Loading
Loading