@dfosco/storyboard 0.5.0-beta.41 → 0.5.0-beta.43
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.
- package/dist/runtime/{api-Bbh7Mcv9.d.ts → api-CJeUwdWK.d.ts} +13 -29
- package/dist/runtime/client/index.d.ts +1 -2
- package/dist/runtime/client/index.js +10 -18
- package/dist/runtime/client/index.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +53 -145
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/schema/index.d.ts +17 -25
- package/dist/runtime/schema/index.js +5 -18
- package/dist/runtime/schema/index.js.map +1 -1
- package/dist/runtime/server/main.js +47 -140
- package/dist/runtime/server/main.js.map +1 -1
- package/dist/storyboard-ui.css +1 -1
- package/dist/tailwind.css +1 -1
- package/package.json +1 -1
- package/src/core/canvas/server.js +0 -1
- package/src/core/cli/dev.js +2 -47
- package/src/core/cli/index.js +5 -4
- package/src/core/cli/reset.js +117 -0
- package/src/core/cli/setup.js +6 -0
- package/src/internals/vite/data-plugin.js +27 -13
- package/src/internals/vite/data-plugin.test.js +15 -0
- package/src/runtime/client/index.ts +7 -6
- package/src/runtime/devserver/orchestrator.ts +17 -41
- package/src/runtime/proxy/controller.ts +28 -0
- package/src/runtime/schema/api.ts +4 -13
- package/src/runtime/schema/devserver.ts +12 -24
- package/src/runtime/server/http.ts +1 -39
- package/src/runtime/pool/hot-pool.ts +0 -103
- package/src/runtime/pool/index.ts +0 -2
|
@@ -4,8 +4,8 @@ import { z } from 'zod';
|
|
|
4
4
|
* `POST /devserver/acquire` — request a devserver for a `(devDomain, worktree)` slot.
|
|
5
5
|
*
|
|
6
6
|
* If a devserver already exists for the slot, the runtime returns its existing
|
|
7
|
-
* lease
|
|
8
|
-
*
|
|
7
|
+
* lease. Otherwise it spawns a new Vite process. The slot is locked for the
|
|
8
|
+
* duration of the call.
|
|
9
9
|
*/
|
|
10
10
|
declare const AcquireRequest: z.ZodObject<{
|
|
11
11
|
slot: z.ZodObject<{
|
|
@@ -20,8 +20,6 @@ declare const AcquireRequest: z.ZodObject<{
|
|
|
20
20
|
}>;
|
|
21
21
|
/** Absolute path of the worktree directory; the runtime spawns Vite with `cwd: targetCwd`. */
|
|
22
22
|
targetCwd: z.ZodString;
|
|
23
|
-
/** Lease TTL in seconds. Defaults to 5 min; CLI clients renew on each command. */
|
|
24
|
-
ttlSeconds: z.ZodDefault<z.ZodNumber>;
|
|
25
23
|
/**
|
|
26
24
|
* Escape hatch for the deprecated default devDomain `"storyboard"`. CI and
|
|
27
25
|
* one-off scripts may pass true; the CLI never does.
|
|
@@ -33,7 +31,6 @@ declare const AcquireRequest: z.ZodObject<{
|
|
|
33
31
|
worktree?: string & z.BRAND<"WorktreeName">;
|
|
34
32
|
};
|
|
35
33
|
targetCwd?: string;
|
|
36
|
-
ttlSeconds?: number;
|
|
37
34
|
allowDefaultDomain?: boolean;
|
|
38
35
|
}, {
|
|
39
36
|
slot?: {
|
|
@@ -41,7 +38,6 @@ declare const AcquireRequest: z.ZodObject<{
|
|
|
41
38
|
worktree?: string;
|
|
42
39
|
};
|
|
43
40
|
targetCwd?: string;
|
|
44
|
-
ttlSeconds?: number;
|
|
45
41
|
allowDefaultDomain?: boolean;
|
|
46
42
|
}>;
|
|
47
43
|
type AcquireRequest = z.infer<typeof AcquireRequest>;
|
|
@@ -84,8 +80,8 @@ declare const AcquireResponse: z.ZodObject<{
|
|
|
84
80
|
id: z.ZodString;
|
|
85
81
|
pid: z.ZodNumber;
|
|
86
82
|
port: z.ZodBranded<z.ZodNumber, "Port">;
|
|
87
|
-
status: z.ZodEnum<["
|
|
88
|
-
slot: z.
|
|
83
|
+
status: z.ZodEnum<["spawning", "ready", "stopped"]>;
|
|
84
|
+
slot: z.ZodObject<{
|
|
89
85
|
devDomain: z.ZodBranded<z.ZodString, "DevDomain">;
|
|
90
86
|
worktree: z.ZodBranded<z.ZodString, "WorktreeName">;
|
|
91
87
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -94,12 +90,12 @@ declare const AcquireResponse: z.ZodObject<{
|
|
|
94
90
|
}, {
|
|
95
91
|
devDomain?: string;
|
|
96
92
|
worktree?: string;
|
|
97
|
-
}
|
|
98
|
-
cwd: z.
|
|
93
|
+
}>;
|
|
94
|
+
cwd: z.ZodString;
|
|
99
95
|
spawnedAt: z.ZodString;
|
|
100
96
|
updatedAt: z.ZodString;
|
|
101
97
|
}, "strip", z.ZodTypeAny, {
|
|
102
|
-
status?: "
|
|
98
|
+
status?: "spawning" | "ready" | "stopped";
|
|
103
99
|
id?: string;
|
|
104
100
|
pid?: number;
|
|
105
101
|
port?: number & z.BRAND<"Port">;
|
|
@@ -111,7 +107,7 @@ declare const AcquireResponse: z.ZodObject<{
|
|
|
111
107
|
spawnedAt?: string;
|
|
112
108
|
updatedAt?: string;
|
|
113
109
|
}, {
|
|
114
|
-
status?: "
|
|
110
|
+
status?: "spawning" | "ready" | "stopped";
|
|
115
111
|
id?: string;
|
|
116
112
|
pid?: number;
|
|
117
113
|
port?: number;
|
|
@@ -135,7 +131,7 @@ declare const AcquireResponse: z.ZodObject<{
|
|
|
135
131
|
expiresAt?: string;
|
|
136
132
|
};
|
|
137
133
|
devServer?: {
|
|
138
|
-
status?: "
|
|
134
|
+
status?: "spawning" | "ready" | "stopped";
|
|
139
135
|
id?: string;
|
|
140
136
|
pid?: number;
|
|
141
137
|
port?: number & z.BRAND<"Port">;
|
|
@@ -159,7 +155,7 @@ declare const AcquireResponse: z.ZodObject<{
|
|
|
159
155
|
expiresAt?: string;
|
|
160
156
|
};
|
|
161
157
|
devServer?: {
|
|
162
|
-
status?: "
|
|
158
|
+
status?: "spawning" | "ready" | "stopped";
|
|
163
159
|
id?: string;
|
|
164
160
|
pid?: number;
|
|
165
161
|
port?: number;
|
|
@@ -173,7 +169,7 @@ declare const AcquireResponse: z.ZodObject<{
|
|
|
173
169
|
};
|
|
174
170
|
}>;
|
|
175
171
|
type AcquireResponse = z.infer<typeof AcquireResponse>;
|
|
176
|
-
/** `POST /devserver/release` — relinquish the lease and
|
|
172
|
+
/** `POST /devserver/release` — relinquish the lease and stop the devserver. */
|
|
177
173
|
declare const ReleaseRequest: z.ZodObject<{
|
|
178
174
|
leaseId: z.ZodString;
|
|
179
175
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -182,18 +178,6 @@ declare const ReleaseRequest: z.ZodObject<{
|
|
|
182
178
|
leaseId?: string;
|
|
183
179
|
}>;
|
|
184
180
|
type ReleaseRequest = z.infer<typeof ReleaseRequest>;
|
|
185
|
-
/** `POST /devserver/renew` — extend the lease without changing devserver state. */
|
|
186
|
-
declare const RenewRequest: z.ZodObject<{
|
|
187
|
-
leaseId: z.ZodString;
|
|
188
|
-
ttlSeconds: z.ZodDefault<z.ZodNumber>;
|
|
189
|
-
}, "strip", z.ZodTypeAny, {
|
|
190
|
-
ttlSeconds?: number;
|
|
191
|
-
leaseId?: string;
|
|
192
|
-
}, {
|
|
193
|
-
ttlSeconds?: number;
|
|
194
|
-
leaseId?: string;
|
|
195
|
-
}>;
|
|
196
|
-
type RenewRequest = z.infer<typeof RenewRequest>;
|
|
197
181
|
/** `GET /proxy/state` — current routing table the runtime believes Caddy holds. */
|
|
198
182
|
declare const ProxyState: z.ZodObject<{
|
|
199
183
|
routes: z.ZodArray<z.ZodObject<{
|
|
@@ -226,7 +210,7 @@ declare const ProxyState: z.ZodObject<{
|
|
|
226
210
|
caddyReachable?: boolean;
|
|
227
211
|
}>;
|
|
228
212
|
type ProxyState = z.infer<typeof ProxyState>;
|
|
229
|
-
/** `GET /pool/status` —
|
|
213
|
+
/** `GET /pool/status` — kept for backward compat; always reports zeros. */
|
|
230
214
|
declare const PoolStatus: z.ZodObject<{
|
|
231
215
|
warm: z.ZodNumber;
|
|
232
216
|
bound: z.ZodNumber;
|
|
@@ -302,4 +286,4 @@ declare const RuntimeError: z.ZodObject<{
|
|
|
302
286
|
}>;
|
|
303
287
|
type RuntimeError = z.infer<typeof RuntimeError>;
|
|
304
288
|
|
|
305
|
-
export { AcquireRequest as A, Health as H, ProxyState as P, ReleaseRequest as R, AcquireResponse as a,
|
|
289
|
+
export { AcquireRequest as A, Health as H, ProxyState as P, ReleaseRequest as R, AcquireResponse as a, PoolStatus as b, ProxyUpsertRequest as c, ProxyRemoveRequest as d, RuntimeError as e };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { H as Health, A as AcquireRequest, a as AcquireResponse, R as ReleaseRequest,
|
|
2
|
+
import { H as Health, A as AcquireRequest, a as AcquireResponse, R as ReleaseRequest, P as ProxyState, c as ProxyUpsertRequest, d as ProxyRemoveRequest, b as PoolStatus, e as RuntimeError } from '../api-CJeUwdWK.js';
|
|
3
3
|
|
|
4
4
|
interface RuntimeClientOptions {
|
|
5
5
|
/** Override base URL (mostly for tests). */
|
|
@@ -20,7 +20,6 @@ declare class RuntimeClient {
|
|
|
20
20
|
health(): Promise<Health>;
|
|
21
21
|
acquire(input: z.input<typeof AcquireRequest>): Promise<AcquireResponse>;
|
|
22
22
|
release(input: z.input<typeof ReleaseRequest>): Promise<void>;
|
|
23
|
-
renew(input: z.input<typeof RenewRequest>): Promise<void>;
|
|
24
23
|
proxyState(): Promise<ProxyState>;
|
|
25
24
|
proxyUpsert(input: z.input<typeof ProxyUpsertRequest>): Promise<ProxyState>;
|
|
26
25
|
proxyRemove(input: z.input<typeof ProxyRemoveRequest>): Promise<ProxyState>;
|
|
@@ -17,14 +17,10 @@ var DevServerSlot = z.object({
|
|
|
17
17
|
// src/runtime/schema/devserver.ts
|
|
18
18
|
import { z as z2 } from "zod";
|
|
19
19
|
var DevServerStatus = z2.enum([
|
|
20
|
-
"idle",
|
|
21
|
-
// pre-warmed in the hot pool, no project bound yet
|
|
22
20
|
"spawning",
|
|
23
21
|
// process started, waiting for `ready in …` from Vite stdout
|
|
24
22
|
"ready",
|
|
25
23
|
// bound to a slot, accepting traffic via Caddy
|
|
26
|
-
"draining",
|
|
27
|
-
// releasing — finishing in-flight requests before kill
|
|
28
24
|
"stopped"
|
|
29
25
|
// process exited, slot freed, port returned to the pool
|
|
30
26
|
]);
|
|
@@ -33,9 +29,9 @@ var DevServer = z2.object({
|
|
|
33
29
|
pid: z2.number().int().positive(),
|
|
34
30
|
port: Port,
|
|
35
31
|
status: DevServerStatus,
|
|
36
|
-
slot: DevServerSlot
|
|
37
|
-
/** Absolute path of the worktree directory
|
|
38
|
-
cwd: z2.string()
|
|
32
|
+
slot: DevServerSlot,
|
|
33
|
+
/** Absolute path of the worktree directory. */
|
|
34
|
+
cwd: z2.string(),
|
|
39
35
|
/** ISO timestamp; immutable after spawn. */
|
|
40
36
|
spawnedAt: z2.string().datetime(),
|
|
41
37
|
/** ISO timestamp of last status change. */
|
|
@@ -47,7 +43,7 @@ var Lease = z2.object({
|
|
|
47
43
|
slot: DevServerSlot,
|
|
48
44
|
/** Public proxy URL the client should print to the user. Authoritative. */
|
|
49
45
|
url: z2.string().url(),
|
|
50
|
-
/**
|
|
46
|
+
/** Far-future sentinel — leases don't actually expire. */
|
|
51
47
|
expiresAt: z2.string().datetime()
|
|
52
48
|
});
|
|
53
49
|
var ProxyRoute = z2.object({
|
|
@@ -63,8 +59,6 @@ var AcquireRequest = z3.object({
|
|
|
63
59
|
slot: DevServerSlot,
|
|
64
60
|
/** Absolute path of the worktree directory; the runtime spawns Vite with `cwd: targetCwd`. */
|
|
65
61
|
targetCwd: z3.string().min(1),
|
|
66
|
-
/** Lease TTL in seconds. Defaults to 5 min; CLI clients renew on each command. */
|
|
67
|
-
ttlSeconds: z3.number().int().min(30).max(60 * 60).default(300),
|
|
68
62
|
/**
|
|
69
63
|
* Escape hatch for the deprecated default devDomain `"storyboard"`. CI and
|
|
70
64
|
* one-off scripts may pass true; the CLI never does.
|
|
@@ -78,10 +72,6 @@ var AcquireResponse = z3.object({
|
|
|
78
72
|
var ReleaseRequest = z3.object({
|
|
79
73
|
leaseId: z3.string().uuid()
|
|
80
74
|
});
|
|
81
|
-
var RenewRequest = z3.object({
|
|
82
|
-
leaseId: z3.string().uuid(),
|
|
83
|
-
ttlSeconds: z3.number().int().min(30).max(60 * 60).default(300)
|
|
84
|
-
});
|
|
85
75
|
var ProxyState = z3.object({
|
|
86
76
|
routes: z3.array(ProxyRoute),
|
|
87
77
|
caddyReachable: z3.boolean()
|
|
@@ -246,6 +236,12 @@ var RuntimeClient = class {
|
|
|
246
236
|
}
|
|
247
237
|
}
|
|
248
238
|
async acquire(input) {
|
|
239
|
+
if (this.autoStart) {
|
|
240
|
+
try {
|
|
241
|
+
await this.health();
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
}
|
|
249
245
|
const body = AcquireRequest.parse(input);
|
|
250
246
|
return request(this.baseUrl, "POST", "/devserver/acquire", body, AcquireResponse);
|
|
251
247
|
}
|
|
@@ -253,10 +249,6 @@ var RuntimeClient = class {
|
|
|
253
249
|
const body = ReleaseRequest.parse(input);
|
|
254
250
|
await request(this.baseUrl, "POST", "/devserver/release", body, null);
|
|
255
251
|
}
|
|
256
|
-
async renew(input) {
|
|
257
|
-
const body = RenewRequest.parse(input);
|
|
258
|
-
await request(this.baseUrl, "POST", "/devserver/renew", body, null);
|
|
259
|
-
}
|
|
260
252
|
async proxyState() {
|
|
261
253
|
return request(this.baseUrl, "GET", "/proxy/state", void 0, ProxyState);
|
|
262
254
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/runtime/client/index.ts","../../../src/runtime/schema/identity.ts","../../../src/runtime/schema/devserver.ts","../../../src/runtime/schema/api.ts"],"sourcesContent":["import { spawn } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport {\n AcquireRequest,\n AcquireResponse,\n Health,\n PoolStatus,\n ProxyRemoveRequest,\n ProxyState,\n ProxyUpsertRequest,\n ReleaseRequest,\n RenewRequest,\n RuntimeError,\n} from '../schema/index.js'\nimport type { z } from 'zod'\n\n/**\n * Typed JS/TS client for the Storyboard Runtime daemon.\n *\n * Consumers should always go through this client rather than hand-rolling\n * `fetch` calls — the client is the only place where the daemon's URL is\n * known, and it's the only place where on-demand daemon spawning happens.\n */\n\nconst RUNTIME_BASE = 'http://127.0.0.1:4321'\n\nexport interface RuntimeClientOptions {\n /** Override base URL (mostly for tests). */\n baseUrl?: string\n /** Auto-start the daemon if it isn't running. Default: true. */\n autoStart?: boolean\n}\n\nexport class RuntimeRequestError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code: z.infer<typeof RuntimeError>['code'],\n public readonly details?: unknown,\n ) {\n super(message)\n this.name = 'RuntimeRequestError'\n }\n}\n\nasync function request<S extends z.ZodTypeAny>(\n baseUrl: string,\n method: 'GET' | 'POST',\n path: string,\n body: unknown,\n responseSchema: S | null,\n): Promise<S extends z.ZodTypeAny ? z.output<S> : void> {\n const init: RequestInit = {\n method,\n headers: body !== undefined ? { 'Content-Type': 'application/json' } : undefined,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n }\n let res: Response\n try {\n res = await fetch(`${baseUrl}${path}`, init)\n } catch (err) {\n throw new RuntimeRequestError(\n `Cannot reach Storyboard Runtime at ${baseUrl} — is the daemon running? (${(err as Error).message})`,\n 0,\n 'INTERNAL',\n )\n }\n const text = await res.text()\n let parsed: unknown\n try { parsed = text ? JSON.parse(text) : {} }\n catch { parsed = { error: text, code: 'INTERNAL' } }\n\n if (!res.ok) {\n const err = RuntimeError.safeParse(parsed)\n if (err.success) {\n throw new RuntimeRequestError(err.data.error, res.status, err.data.code, err.data.details)\n }\n throw new RuntimeRequestError(`HTTP ${res.status}`, res.status, 'INTERNAL', parsed)\n }\n if (responseSchema === null) return undefined as never\n return responseSchema.parse(parsed) as never\n}\n\n/**\n * Spawn the daemon as a detached child. Resolves once the health endpoint\n * answers (or rejects after a short timeout).\n */\nasync function spawnDaemon(baseUrl: string): Promise<void> {\n const here = dirname(fileURLToPath(import.meta.url))\n // bin/storyboard-runtime.js lives next to dist/, two levels up from\n // dist/runtime/client/index.js (the published path).\n const binPath = resolve(here, '..', '..', '..', 'bin', 'storyboard-runtime.js')\n const child = spawn(process.execPath, [binPath], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n })\n child.unref()\n\n // Poll /health until the daemon is up.\n const deadline = Date.now() + 5000\n while (Date.now() < deadline) {\n try {\n const r = await fetch(`${baseUrl}/health`)\n if (r.ok) return\n } catch { /* not up yet */ }\n await new Promise(r => setTimeout(r, 100))\n }\n throw new Error(\n `Storyboard Runtime did not become ready within 5s ` +\n `(tried to spawn ${binPath})`,\n )\n}\n\n/**\n * Read the @dfosco/storyboard package.json version that this client is\n * shipping with. Used to detect mismatches against a long-lived daemon\n * that may have been spawned by a previous install.\n */\nfunction readClientVersion(): string {\n try {\n const here = dirname(fileURLToPath(import.meta.url))\n const candidates = [\n resolve(here, '..', '..', '..', 'package.json'),\n resolve(here, '..', '..', 'package.json'),\n ]\n for (const p of candidates) {\n if (existsSync(p)) {\n const pkg = JSON.parse(readFileSync(p, 'utf8')) as { version?: string }\n if (typeof pkg.version === 'string') return pkg.version\n }\n }\n } catch { /* ignore */ }\n return '0.0.0'\n}\n\nconst CLIENT_VERSION = readClientVersion()\n\n/**\n * Send SIGTERM to the daemon PID and clear its lock/pid files so\n * spawnDaemon() can start a fresh one.\n */\nfunction killExistingDaemon(): void {\n try {\n const pidPath = resolve(process.env.HOME || '', '.storyboard', 'runtime.pid')\n if (!existsSync(pidPath)) return\n const pid = Number(readFileSync(pidPath, 'utf8').trim())\n if (Number.isFinite(pid) && pid > 0) {\n try { process.kill(pid, 'SIGTERM') } catch { /* already dead */ }\n }\n } catch { /* ignore */ }\n}\n\nexport class RuntimeClient {\n readonly baseUrl: string\n readonly autoStart: boolean\n\n constructor(opts: RuntimeClientOptions = {}) {\n this.baseUrl = opts.baseUrl ?? RUNTIME_BASE\n this.autoStart = opts.autoStart !== false\n }\n\n async health(): Promise<Health> {\n try {\n const result = await request(this.baseUrl, 'GET', '/health', undefined, Health)\n // Auto-respawn on version mismatch — a long-lived daemon from a\n // previous install otherwise keeps serving stale code after upgrade.\n // Skip when client reports 0.0.0 (dev/source layout where package\n // version isn't meaningful).\n if (\n this.autoStart &&\n CLIENT_VERSION !== '0.0.0' &&\n result.version !== '0.0.0' &&\n result.version !== CLIENT_VERSION\n ) {\n killExistingDaemon()\n // Give the OS a moment to release port 4321\n await new Promise(r => setTimeout(r, 250))\n await spawnDaemon(this.baseUrl)\n return request(this.baseUrl, 'GET', '/health', undefined, Health)\n }\n return result\n } catch (err) {\n if (this.autoStart && err instanceof RuntimeRequestError && err.status === 0) {\n await spawnDaemon(this.baseUrl)\n return request(this.baseUrl, 'GET', '/health', undefined, Health)\n }\n throw err\n }\n }\n\n async acquire(input: z.input<typeof AcquireRequest>): Promise<AcquireResponse> {\n const body = AcquireRequest.parse(input)\n return request(this.baseUrl, 'POST', '/devserver/acquire', body, AcquireResponse)\n }\n\n async release(input: z.input<typeof ReleaseRequest>): Promise<void> {\n const body = ReleaseRequest.parse(input)\n await request(this.baseUrl, 'POST', '/devserver/release', body, null)\n }\n\n async renew(input: z.input<typeof RenewRequest>): Promise<void> {\n const body = RenewRequest.parse(input)\n await request(this.baseUrl, 'POST', '/devserver/renew', body, null)\n }\n\n async proxyState(): Promise<ProxyState> {\n return request(this.baseUrl, 'GET', '/proxy/state', undefined, ProxyState)\n }\n\n async proxyUpsert(input: z.input<typeof ProxyUpsertRequest>): Promise<ProxyState> {\n const body = ProxyUpsertRequest.parse(input)\n return request(this.baseUrl, 'POST', '/proxy/upsert', body, ProxyState)\n }\n\n async proxyRemove(input: z.input<typeof ProxyRemoveRequest>): Promise<ProxyState> {\n const body = ProxyRemoveRequest.parse(input)\n return request(this.baseUrl, 'POST', '/proxy/remove', body, ProxyState)\n }\n\n async poolStatus(): Promise<PoolStatus> {\n return request(this.baseUrl, 'GET', '/pool/status', undefined, PoolStatus)\n }\n}\n\n/** Default singleton client for casual callers. */\nexport const runtime = new RuntimeClient()\n","import { z } from 'zod'\n\n/**\n * The legacy/default devDomain. Acquire requests using this value are rejected\n * unless `allowDefaultDomain` is set — see DevServerOrchestrator for details.\n */\nexport const DEFAULT_DEV_DOMAIN = 'storyboard'\n\n/**\n * A devDomain identifies a Storyboard repo on this machine.\n *\n * The literal default value `\"storyboard\"` is intentionally *not* allowed by\n * `acquire` (see schema/acquire.ts) — every checkout MUST set its own\n * `devDomain` in `storyboard.config.json`. This is the structural fix for H3\n * in the server-state RCA: two repos can never share a host space.\n *\n * Allowed: lowercase letters, digits, hyphens. Must start with a letter.\n * 1–32 chars. The runtime constructs the public host as `${devDomain}.localhost`.\n */\nexport const DevDomain = z\n .string()\n .min(1)\n .max(32)\n .regex(/^[a-z][a-z0-9-]*$/, 'devDomain must match /^[a-z][a-z0-9-]*$/')\n .brand<'DevDomain'>()\nexport type DevDomain = z.infer<typeof DevDomain>\n\n/**\n * A worktree name. `\"main\"` is reserved for the repo root.\n *\n * Names are URL-safe by construction so we never have to escape them when\n * building branch URLs (`/branch--<name>/...`).\n */\nexport const WorktreeName = z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9][a-z0-9._-]*$/i, 'worktree name must be URL-safe')\n .brand<'WorktreeName'>()\nexport type WorktreeName = z.infer<typeof WorktreeName>\n\n/**\n * A TCP port the runtime has leased to a devserver. The runtime is the sole\n * authority for port allocation; clients never pick their own port.\n */\nexport const Port = z.number().int().min(1024).max(65535).brand<'Port'>()\nexport type Port = z.infer<typeof Port>\n\n/**\n * The composite key `(devDomain, worktree)` uniquely identifies a devserver.\n *\n * The runtime guarantees at most one devserver per slot — illegal collisions\n * (e.g. two repos trying to claim `(storyboard, main)`) are rejected with\n * `409 CONFLICT` rather than silently overwriting routes.\n */\nexport const DevServerSlot = z.object({\n devDomain: DevDomain,\n worktree: WorktreeName,\n})\nexport type DevServerSlot = z.infer<typeof DevServerSlot>\n\n/**\n * Convert a slot to its canonical string key, used for map lookups and\n * logging. Format: `${devDomain}::${worktree}`.\n */\nexport function slotKey(slot: DevServerSlot): string {\n return `${slot.devDomain}::${slot.worktree}`\n}\n","import { z } from 'zod'\nimport { DevDomain, DevServerSlot, Port, WorktreeName } from './identity.js'\n\n/**\n * DevServer lifecycle FSM.\n *\n * Transitions are enforced in code; illegal transitions throw. This is the\n * structural fix for the per-repo server's \"best-effort\" state — a devserver\n * that thinks it's `ready` but whose port is dead cannot exist here.\n *\n * ```\n * idle → spawning → ready → draining → stopped\n * │ │ │\n * └───────────┴────────┴──────→ stopped (on crash)\n * ```\n */\nexport const DevServerStatus = z.enum([\n 'idle', // pre-warmed in the hot pool, no project bound yet\n 'spawning', // process started, waiting for `ready in …` from Vite stdout\n 'ready', // bound to a slot, accepting traffic via Caddy\n 'draining', // releasing — finishing in-flight requests before kill\n 'stopped', // process exited, slot freed, port returned to the pool\n])\nexport type DevServerStatus = z.infer<typeof DevServerStatus>\n\n/** Allowed FSM transitions. Centralised so misuse is a one-line review catch. */\nexport const ALLOWED_TRANSITIONS: Record<DevServerStatus, readonly DevServerStatus[]> = {\n idle: ['spawning', 'stopped'],\n spawning: ['ready', 'stopped'],\n ready: ['draining', 'stopped'],\n draining: ['stopped'],\n stopped: [],\n} as const\n\nexport class IllegalTransitionError extends Error {\n constructor(from: DevServerStatus, to: DevServerStatus) {\n super(`Illegal devserver transition: ${from} → ${to}`)\n this.name = 'IllegalTransitionError'\n }\n}\n\nexport function assertTransition(from: DevServerStatus, to: DevServerStatus): void {\n if (!ALLOWED_TRANSITIONS[from].includes(to)) {\n throw new IllegalTransitionError(from, to)\n }\n}\n\n/**\n * A devserver record as exposed by the runtime API.\n *\n * `slot` is `null` for hot-pool members that haven't been acquired yet.\n * Once bound, `slot.devDomain + slot.worktree` is unique across the whole\n * runtime; the orchestrator rejects duplicate binds.\n */\nexport const DevServer = z.object({\n id: z.string().uuid(),\n pid: z.number().int().positive(),\n port: Port,\n status: DevServerStatus,\n slot: DevServerSlot.nullable(),\n /** Absolute path of the worktree directory once bound; null while in the pool. */\n cwd: z.string().nullable(),\n /** ISO timestamp; immutable after spawn. */\n spawnedAt: z.string().datetime(),\n /** ISO timestamp of last status change. */\n updatedAt: z.string().datetime(),\n})\nexport type DevServer = z.infer<typeof DevServer>\n\n/**\n * A short-lived lease handed to a CLI client when it acquires a devserver.\n *\n * Leases are the *only* way a client controls a devserver — the runtime\n * refuses commands without a valid leaseId. This means a stale `sb dev`\n * process can't kill a devserver belonging to a newer session.\n */\nexport const Lease = z.object({\n id: z.string().uuid(),\n devServerId: z.string().uuid(),\n slot: DevServerSlot,\n /** Public proxy URL the client should print to the user. Authoritative. */\n url: z.string().url(),\n /** Renew before this timestamp or the lease expires and the devserver drains. */\n expiresAt: z.string().datetime(),\n})\nexport type Lease = z.infer<typeof Lease>\n\n/**\n * A Caddy proxy route owned by the runtime. The `@id` is always the devDomain;\n * this lets the runtime PATCH a single route in place without touching others.\n *\n * `upstreams` is keyed by plain string (validated elsewhere as WorktreeName)\n * to avoid `Partial<Record<branded, …>>` shenanigans at the value-spread sites.\n */\nexport const ProxyRoute = z.object({\n devDomain: DevDomain,\n host: z.string(),\n /** worktree name → upstream port. `main` is the host's catch-all. */\n upstreams: z.record(z.string(), Port),\n})\nexport type ProxyRoute = z.infer<typeof ProxyRoute>\n","import { z } from 'zod'\nimport { DevServerSlot, Port } from './identity.js'\nimport { DevServer, Lease, ProxyRoute } from './devserver.js'\n\n/**\n * `POST /devserver/acquire` — request a devserver for a `(devDomain, worktree)` slot.\n *\n * If a devserver already exists for the slot, the runtime returns its existing\n * lease (renewed). Otherwise it either rents a hot-pool member or spawns a new\n * Vite process. The slot is locked for the duration of the call.\n */\nexport const AcquireRequest = z.object({\n slot: DevServerSlot,\n /** Absolute path of the worktree directory; the runtime spawns Vite with `cwd: targetCwd`. */\n targetCwd: z.string().min(1),\n /** Lease TTL in seconds. Defaults to 5 min; CLI clients renew on each command. */\n ttlSeconds: z.number().int().min(30).max(60 * 60).default(300),\n /**\n * Escape hatch for the deprecated default devDomain `\"storyboard\"`. CI and\n * one-off scripts may pass true; the CLI never does.\n */\n allowDefaultDomain: z.boolean().default(false),\n})\nexport type AcquireRequest = z.infer<typeof AcquireRequest>\n\nexport const AcquireResponse = z.object({\n lease: Lease,\n devServer: DevServer,\n})\nexport type AcquireResponse = z.infer<typeof AcquireResponse>\n\n/** `POST /devserver/release` — relinquish the lease and trigger draining. */\nexport const ReleaseRequest = z.object({\n leaseId: z.string().uuid(),\n})\nexport type ReleaseRequest = z.infer<typeof ReleaseRequest>\n\n/** `POST /devserver/renew` — extend the lease without changing devserver state. */\nexport const RenewRequest = z.object({\n leaseId: z.string().uuid(),\n ttlSeconds: z.number().int().min(30).max(60 * 60).default(300),\n})\nexport type RenewRequest = z.infer<typeof RenewRequest>\n\n/** `GET /proxy/state` — current routing table the runtime believes Caddy holds. */\nexport const ProxyState = z.object({\n routes: z.array(ProxyRoute),\n caddyReachable: z.boolean(),\n})\nexport type ProxyState = z.infer<typeof ProxyState>\n\n/** `GET /pool/status` — hot-pool inventory. */\nexport const PoolStatus = z.object({\n warm: z.number().int().nonnegative(),\n bound: z.number().int().nonnegative(),\n capacity: z.number().int().nonnegative(),\n})\nexport type PoolStatus = z.infer<typeof PoolStatus>\n\n/** `POST /proxy/upsert` — bind (devDomain, worktree) → port in the proxy. */\nexport const ProxyUpsertRequest = z.object({\n devDomain: z.string(),\n worktree: z.string(),\n port: z.number(),\n})\nexport type ProxyUpsertRequest = z.infer<typeof ProxyUpsertRequest>\n\n/** `POST /proxy/remove` — drop a worktree's route from the proxy. */\nexport const ProxyRemoveRequest = z.object({\n devDomain: z.string(),\n worktree: z.string(),\n})\nexport type ProxyRemoveRequest = z.infer<typeof ProxyRemoveRequest>\n\n/** `GET /health` — daemon liveness probe. */\nexport const Health = z.object({\n ok: z.literal(true),\n version: z.string(),\n uptimeSeconds: z.number().nonnegative(),\n port: Port,\n})\nexport type Health = z.infer<typeof Health>\n\n/** Runtime error envelope. All non-2xx responses share this shape. */\nexport const RuntimeError = z.object({\n error: z.string(),\n code: z.enum([\n 'NOT_IMPLEMENTED',\n 'BAD_REQUEST',\n 'CONFLICT',\n 'NOT_FOUND',\n 'FORBIDDEN_DEFAULT_DOMAIN',\n 'INTERNAL',\n 'CADDY_UNREACHABLE',\n 'PORT_EXHAUSTED',\n 'TIMEOUT',\n ]),\n details: z.unknown().optional(),\n})\nexport type RuntimeError = z.infer<typeof RuntimeError>\n"],"mappings":"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","names":["z","z","z","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/runtime/client/index.ts","../../../src/runtime/schema/identity.ts","../../../src/runtime/schema/devserver.ts","../../../src/runtime/schema/api.ts"],"sourcesContent":["import { spawn } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, resolve } from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\nimport {\n AcquireRequest,\n AcquireResponse,\n Health,\n PoolStatus,\n ProxyRemoveRequest,\n ProxyState,\n ProxyUpsertRequest,\n ReleaseRequest,\n RuntimeError,\n} from '../schema/index.js'\nimport type { z } from 'zod'\n\n/**\n * Typed JS/TS client for the Storyboard Runtime daemon.\n *\n * Consumers should always go through this client rather than hand-rolling\n * `fetch` calls — the client is the only place where the daemon's URL is\n * known, and it's the only place where on-demand daemon spawning happens.\n */\n\nconst RUNTIME_BASE = 'http://127.0.0.1:4321'\n\nexport interface RuntimeClientOptions {\n /** Override base URL (mostly for tests). */\n baseUrl?: string\n /** Auto-start the daemon if it isn't running. Default: true. */\n autoStart?: boolean\n}\n\nexport class RuntimeRequestError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code: z.infer<typeof RuntimeError>['code'],\n public readonly details?: unknown,\n ) {\n super(message)\n this.name = 'RuntimeRequestError'\n }\n}\n\nasync function request<S extends z.ZodTypeAny>(\n baseUrl: string,\n method: 'GET' | 'POST',\n path: string,\n body: unknown,\n responseSchema: S | null,\n): Promise<S extends z.ZodTypeAny ? z.output<S> : void> {\n const init: RequestInit = {\n method,\n headers: body !== undefined ? { 'Content-Type': 'application/json' } : undefined,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n }\n let res: Response\n try {\n res = await fetch(`${baseUrl}${path}`, init)\n } catch (err) {\n throw new RuntimeRequestError(\n `Cannot reach Storyboard Runtime at ${baseUrl} — is the daemon running? (${(err as Error).message})`,\n 0,\n 'INTERNAL',\n )\n }\n const text = await res.text()\n let parsed: unknown\n try { parsed = text ? JSON.parse(text) : {} }\n catch { parsed = { error: text, code: 'INTERNAL' } }\n\n if (!res.ok) {\n const err = RuntimeError.safeParse(parsed)\n if (err.success) {\n throw new RuntimeRequestError(err.data.error, res.status, err.data.code, err.data.details)\n }\n throw new RuntimeRequestError(`HTTP ${res.status}`, res.status, 'INTERNAL', parsed)\n }\n if (responseSchema === null) return undefined as never\n return responseSchema.parse(parsed) as never\n}\n\n/**\n * Spawn the daemon as a detached child. Resolves once the health endpoint\n * answers (or rejects after a short timeout).\n */\nasync function spawnDaemon(baseUrl: string): Promise<void> {\n const here = dirname(fileURLToPath(import.meta.url))\n // bin/storyboard-runtime.js lives next to dist/, two levels up from\n // dist/runtime/client/index.js (the published path).\n const binPath = resolve(here, '..', '..', '..', 'bin', 'storyboard-runtime.js')\n const child = spawn(process.execPath, [binPath], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n })\n child.unref()\n\n // Poll /health until the daemon is up.\n const deadline = Date.now() + 5000\n while (Date.now() < deadline) {\n try {\n const r = await fetch(`${baseUrl}/health`)\n if (r.ok) return\n } catch { /* not up yet */ }\n await new Promise(r => setTimeout(r, 100))\n }\n throw new Error(\n `Storyboard Runtime did not become ready within 5s ` +\n `(tried to spawn ${binPath})`,\n )\n}\n\n/**\n * Read the @dfosco/storyboard package.json version that this client is\n * shipping with. Used to detect mismatches against a long-lived daemon\n * that may have been spawned by a previous install.\n */\nfunction readClientVersion(): string {\n try {\n const here = dirname(fileURLToPath(import.meta.url))\n const candidates = [\n resolve(here, '..', '..', '..', 'package.json'),\n resolve(here, '..', '..', 'package.json'),\n ]\n for (const p of candidates) {\n if (existsSync(p)) {\n const pkg = JSON.parse(readFileSync(p, 'utf8')) as { version?: string }\n if (typeof pkg.version === 'string') return pkg.version\n }\n }\n } catch { /* ignore */ }\n return '0.0.0'\n}\n\nconst CLIENT_VERSION = readClientVersion()\n\n/**\n * Send SIGTERM to the daemon PID and clear its lock/pid files so\n * spawnDaemon() can start a fresh one.\n */\nfunction killExistingDaemon(): void {\n try {\n const pidPath = resolve(process.env.HOME || '', '.storyboard', 'runtime.pid')\n if (!existsSync(pidPath)) return\n const pid = Number(readFileSync(pidPath, 'utf8').trim())\n if (Number.isFinite(pid) && pid > 0) {\n try { process.kill(pid, 'SIGTERM') } catch { /* already dead */ }\n }\n } catch { /* ignore */ }\n}\n\nexport class RuntimeClient {\n readonly baseUrl: string\n readonly autoStart: boolean\n\n constructor(opts: RuntimeClientOptions = {}) {\n this.baseUrl = opts.baseUrl ?? RUNTIME_BASE\n this.autoStart = opts.autoStart !== false\n }\n\n async health(): Promise<Health> {\n try {\n const result = await request(this.baseUrl, 'GET', '/health', undefined, Health)\n // Auto-respawn on version mismatch — a long-lived daemon from a\n // previous install otherwise keeps serving stale code after upgrade.\n // Skip when client reports 0.0.0 (dev/source layout where package\n // version isn't meaningful).\n if (\n this.autoStart &&\n CLIENT_VERSION !== '0.0.0' &&\n result.version !== '0.0.0' &&\n result.version !== CLIENT_VERSION\n ) {\n killExistingDaemon()\n // Give the OS a moment to release port 4321\n await new Promise(r => setTimeout(r, 250))\n await spawnDaemon(this.baseUrl)\n return request(this.baseUrl, 'GET', '/health', undefined, Health)\n }\n return result\n } catch (err) {\n if (this.autoStart && err instanceof RuntimeRequestError && err.status === 0) {\n await spawnDaemon(this.baseUrl)\n return request(this.baseUrl, 'GET', '/health', undefined, Health)\n }\n throw err\n }\n }\n\n async acquire(input: z.input<typeof AcquireRequest>): Promise<AcquireResponse> {\n // Force a health check first — this is the sole codepath that detects\n // a stale daemon (different version, crashed mid-restart, etc.) and\n // respawns it. Without this, `sb run` would happily POST against an\n // outdated daemon and inherit all of its bugs.\n if (this.autoStart) {\n try { await this.health() } catch { /* health() will throw on hard failure; let acquire surface it */ }\n }\n const body = AcquireRequest.parse(input)\n return request(this.baseUrl, 'POST', '/devserver/acquire', body, AcquireResponse)\n }\n\n async release(input: z.input<typeof ReleaseRequest>): Promise<void> {\n const body = ReleaseRequest.parse(input)\n await request(this.baseUrl, 'POST', '/devserver/release', body, null)\n }\n\n async proxyState(): Promise<ProxyState> {\n return request(this.baseUrl, 'GET', '/proxy/state', undefined, ProxyState)\n }\n\n async proxyUpsert(input: z.input<typeof ProxyUpsertRequest>): Promise<ProxyState> {\n const body = ProxyUpsertRequest.parse(input)\n return request(this.baseUrl, 'POST', '/proxy/upsert', body, ProxyState)\n }\n\n async proxyRemove(input: z.input<typeof ProxyRemoveRequest>): Promise<ProxyState> {\n const body = ProxyRemoveRequest.parse(input)\n return request(this.baseUrl, 'POST', '/proxy/remove', body, ProxyState)\n }\n\n async poolStatus(): Promise<PoolStatus> {\n return request(this.baseUrl, 'GET', '/pool/status', undefined, PoolStatus)\n }\n}\n\n/** Default singleton client for casual callers. */\nexport const runtime = new RuntimeClient()\n","import { z } from 'zod'\n\n/**\n * The legacy/default devDomain. Acquire requests using this value are rejected\n * unless `allowDefaultDomain` is set — see DevServerOrchestrator for details.\n */\nexport const DEFAULT_DEV_DOMAIN = 'storyboard'\n\n/**\n * A devDomain identifies a Storyboard repo on this machine.\n *\n * The literal default value `\"storyboard\"` is intentionally *not* allowed by\n * `acquire` (see schema/acquire.ts) — every checkout MUST set its own\n * `devDomain` in `storyboard.config.json`. This is the structural fix for H3\n * in the server-state RCA: two repos can never share a host space.\n *\n * Allowed: lowercase letters, digits, hyphens. Must start with a letter.\n * 1–32 chars. The runtime constructs the public host as `${devDomain}.localhost`.\n */\nexport const DevDomain = z\n .string()\n .min(1)\n .max(32)\n .regex(/^[a-z][a-z0-9-]*$/, 'devDomain must match /^[a-z][a-z0-9-]*$/')\n .brand<'DevDomain'>()\nexport type DevDomain = z.infer<typeof DevDomain>\n\n/**\n * A worktree name. `\"main\"` is reserved for the repo root.\n *\n * Names are URL-safe by construction so we never have to escape them when\n * building branch URLs (`/branch--<name>/...`).\n */\nexport const WorktreeName = z\n .string()\n .min(1)\n .max(64)\n .regex(/^[a-z0-9][a-z0-9._-]*$/i, 'worktree name must be URL-safe')\n .brand<'WorktreeName'>()\nexport type WorktreeName = z.infer<typeof WorktreeName>\n\n/**\n * A TCP port the runtime has leased to a devserver. The runtime is the sole\n * authority for port allocation; clients never pick their own port.\n */\nexport const Port = z.number().int().min(1024).max(65535).brand<'Port'>()\nexport type Port = z.infer<typeof Port>\n\n/**\n * The composite key `(devDomain, worktree)` uniquely identifies a devserver.\n *\n * The runtime guarantees at most one devserver per slot — illegal collisions\n * (e.g. two repos trying to claim `(storyboard, main)`) are rejected with\n * `409 CONFLICT` rather than silently overwriting routes.\n */\nexport const DevServerSlot = z.object({\n devDomain: DevDomain,\n worktree: WorktreeName,\n})\nexport type DevServerSlot = z.infer<typeof DevServerSlot>\n\n/**\n * Convert a slot to its canonical string key, used for map lookups and\n * logging. Format: `${devDomain}::${worktree}`.\n */\nexport function slotKey(slot: DevServerSlot): string {\n return `${slot.devDomain}::${slot.worktree}`\n}\n","import { z } from 'zod'\nimport { DevDomain, DevServerSlot, Port, WorktreeName } from './identity.js'\n\n/**\n * DevServer lifecycle FSM.\n *\n * ```\n * spawning → ready → stopped\n * └────────────────┘ (on crash)\n * ```\n */\nexport const DevServerStatus = z.enum([\n 'spawning', // process started, waiting for `ready in …` from Vite stdout\n 'ready', // bound to a slot, accepting traffic via Caddy\n 'stopped', // process exited, slot freed, port returned to the pool\n])\nexport type DevServerStatus = z.infer<typeof DevServerStatus>\n\n/** Allowed FSM transitions. Centralised so misuse is a one-line review catch. */\nexport const ALLOWED_TRANSITIONS: Record<DevServerStatus, readonly DevServerStatus[]> = {\n spawning: ['ready', 'stopped'],\n ready: ['stopped'],\n stopped: [],\n} as const\n\nexport class IllegalTransitionError extends Error {\n constructor(from: DevServerStatus, to: DevServerStatus) {\n super(`Illegal devserver transition: ${from} → ${to}`)\n this.name = 'IllegalTransitionError'\n }\n}\n\nexport function assertTransition(from: DevServerStatus, to: DevServerStatus): void {\n if (!ALLOWED_TRANSITIONS[from].includes(to)) {\n throw new IllegalTransitionError(from, to)\n }\n}\n\n/**\n * A devserver record as exposed by the runtime API. Always bound to a slot\n * after acquire (no pre-spawned pool members), so `slot` and `cwd` are required.\n */\nexport const DevServer = z.object({\n id: z.string().uuid(),\n pid: z.number().int().positive(),\n port: Port,\n status: DevServerStatus,\n slot: DevServerSlot,\n /** Absolute path of the worktree directory. */\n cwd: z.string(),\n /** ISO timestamp; immutable after spawn. */\n spawnedAt: z.string().datetime(),\n /** ISO timestamp of last status change. */\n updatedAt: z.string().datetime(),\n})\nexport type DevServer = z.infer<typeof DevServer>\n\n/**\n * A lease handed to a CLI client when it acquires a devserver.\n *\n * Leases are the *only* way a client controls a devserver — the runtime\n * refuses commands without a valid leaseId. They live as long as the\n * acquiring CLI process; expiry is a far-future sentinel.\n */\nexport const Lease = z.object({\n id: z.string().uuid(),\n devServerId: z.string().uuid(),\n slot: DevServerSlot,\n /** Public proxy URL the client should print to the user. Authoritative. */\n url: z.string().url(),\n /** Far-future sentinel — leases don't actually expire. */\n expiresAt: z.string().datetime(),\n})\nexport type Lease = z.infer<typeof Lease>\n\n/**\n * A Caddy proxy route owned by the runtime. The `@id` is always the devDomain;\n * this lets the runtime PATCH a single route in place without touching others.\n *\n * `upstreams` is keyed by plain string (validated elsewhere as WorktreeName)\n * to avoid `Partial<Record<branded, …>>` shenanigans at the value-spread sites.\n */\nexport const ProxyRoute = z.object({\n devDomain: DevDomain,\n host: z.string(),\n /** worktree name → upstream port. `main` is the host's catch-all. */\n upstreams: z.record(z.string(), Port),\n})\nexport type ProxyRoute = z.infer<typeof ProxyRoute>\n","import { z } from 'zod'\nimport { DevServerSlot, Port } from './identity.js'\nimport { DevServer, Lease, ProxyRoute } from './devserver.js'\n\n/**\n * `POST /devserver/acquire` — request a devserver for a `(devDomain, worktree)` slot.\n *\n * If a devserver already exists for the slot, the runtime returns its existing\n * lease. Otherwise it spawns a new Vite process. The slot is locked for the\n * duration of the call.\n */\nexport const AcquireRequest = z.object({\n slot: DevServerSlot,\n /** Absolute path of the worktree directory; the runtime spawns Vite with `cwd: targetCwd`. */\n targetCwd: z.string().min(1),\n /**\n * Escape hatch for the deprecated default devDomain `\"storyboard\"`. CI and\n * one-off scripts may pass true; the CLI never does.\n */\n allowDefaultDomain: z.boolean().default(false),\n})\nexport type AcquireRequest = z.infer<typeof AcquireRequest>\n\nexport const AcquireResponse = z.object({\n lease: Lease,\n devServer: DevServer,\n})\nexport type AcquireResponse = z.infer<typeof AcquireResponse>\n\n/** `POST /devserver/release` — relinquish the lease and stop the devserver. */\nexport const ReleaseRequest = z.object({\n leaseId: z.string().uuid(),\n})\nexport type ReleaseRequest = z.infer<typeof ReleaseRequest>\n\n/** `GET /proxy/state` — current routing table the runtime believes Caddy holds. */\nexport const ProxyState = z.object({\n routes: z.array(ProxyRoute),\n caddyReachable: z.boolean(),\n})\nexport type ProxyState = z.infer<typeof ProxyState>\n\n/** `GET /pool/status` — kept for backward compat; always reports zeros. */\nexport const PoolStatus = z.object({\n warm: z.number().int().nonnegative(),\n bound: z.number().int().nonnegative(),\n capacity: z.number().int().nonnegative(),\n})\nexport type PoolStatus = z.infer<typeof PoolStatus>\n\n/** `POST /proxy/upsert` — bind (devDomain, worktree) → port in the proxy. */\nexport const ProxyUpsertRequest = z.object({\n devDomain: z.string(),\n worktree: z.string(),\n port: z.number(),\n})\nexport type ProxyUpsertRequest = z.infer<typeof ProxyUpsertRequest>\n\n/** `POST /proxy/remove` — drop a worktree's route from the proxy. */\nexport const ProxyRemoveRequest = z.object({\n devDomain: z.string(),\n worktree: z.string(),\n})\nexport type ProxyRemoveRequest = z.infer<typeof ProxyRemoveRequest>\n\n/** `GET /health` — daemon liveness probe. */\nexport const Health = z.object({\n ok: z.literal(true),\n version: z.string(),\n uptimeSeconds: z.number().nonnegative(),\n port: Port,\n})\nexport type Health = z.infer<typeof Health>\n\n/** Runtime error envelope. All non-2xx responses share this shape. */\nexport const RuntimeError = z.object({\n error: z.string(),\n code: z.enum([\n 'NOT_IMPLEMENTED',\n 'BAD_REQUEST',\n 'CONFLICT',\n 'NOT_FOUND',\n 'FORBIDDEN_DEFAULT_DOMAIN',\n 'INTERNAL',\n 'CADDY_UNREACHABLE',\n 'PORT_EXHAUSTED',\n 'TIMEOUT',\n ]),\n details: z.unknown().optional(),\n})\nexport type RuntimeError = z.infer<typeof RuntimeError>\n"],"mappings":"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","names":["z","z","z","z","z"]}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ALLOWED_TRANSITIONS, DEFAULT_DEV_DOMAIN, DevDomain, DevServer, DevServerSlot, DevServerStatus, IllegalTransitionError, Lease, Port, ProxyRoute, WorktreeName, assertTransition, slotKey } from './schema/index.js';
|
|
2
|
-
export { A as AcquireRequest, a as AcquireResponse, H as Health,
|
|
2
|
+
export { A as AcquireRequest, a as AcquireResponse, H as Health, b as PoolStatus, d as ProxyRemoveRequest, P as ProxyState, c as ProxyUpsertRequest, R as ReleaseRequest, e as RuntimeError } from './api-CJeUwdWK.js';
|
|
3
3
|
export { RuntimeClient, RuntimeRequestError, runtime } from './client/index.js';
|
|
4
4
|
export { startDaemon } from './server/main.js';
|
|
5
5
|
import 'zod';
|