@telorun/runner-core 0.8.1 → 0.9.0
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/README.md +33 -2
- package/dist/backend.d.ts +107 -23
- package/dist/backend.d.ts.map +1 -1
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/contract.d.ts +199 -15
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +9 -0
- package/dist/contract.js.map +1 -1
- package/dist/debug/ports-resolved.d.ts +26 -0
- package/dist/debug/ports-resolved.d.ts.map +1 -0
- package/dist/debug/ports-resolved.js +42 -0
- package/dist/debug/ports-resolved.js.map +1 -0
- package/dist/debug/relay.d.ts.map +1 -1
- package/dist/debug/relay.js +34 -6
- package/dist/debug/relay.js.map +1 -1
- package/dist/debug/run-projection.d.ts +53 -0
- package/dist/debug/run-projection.d.ts.map +1 -0
- package/dist/debug/run-projection.js +115 -0
- package/dist/debug/run-projection.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/routes/apps.d.ts +1 -1
- package/dist/routes/apps.d.ts.map +1 -1
- package/dist/routes/apps.js +14 -4
- package/dist/routes/apps.js.map +1 -1
- package/dist/routes/io.d.ts.map +1 -1
- package/dist/routes/io.js +42 -9
- package/dist/routes/io.js.map +1 -1
- package/dist/routes/session-start.d.ts +12 -12
- package/dist/routes/session-start.d.ts.map +1 -1
- package/dist/routes/session-start.js +86 -13
- package/dist/routes/session-start.js.map +1 -1
- package/dist/routes/sessions.d.ts +11 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +429 -4
- package/dist/routes/sessions.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +21 -1
- package/dist/server.js.map +1 -1
- package/dist/session/byte-ring-buffer.d.ts +6 -1
- package/dist/session/byte-ring-buffer.d.ts.map +1 -1
- package/dist/session/byte-ring-buffer.js +2 -2
- package/dist/session/byte-ring-buffer.js.map +1 -1
- package/dist/session/registry.d.ts +144 -13
- package/dist/session/registry.d.ts.map +1 -1
- package/dist/session/registry.js +166 -25
- package/dist/session/registry.js.map +1 -1
- package/dist/session/watch-supervisor.d.ts +42 -0
- package/dist/session/watch-supervisor.d.ts.map +1 -0
- package/dist/session/watch-supervisor.js +99 -0
- package/dist/session/watch-supervisor.js.map +1 -0
- package/dist/session/workspace-app.d.ts +4 -0
- package/dist/session/workspace-app.d.ts.map +1 -0
- package/dist/session/workspace-app.js +26 -0
- package/dist/session/workspace-app.js.map +1 -0
- package/dist/session/workspace-client.d.ts +33 -0
- package/dist/session/workspace-client.d.ts.map +1 -0
- package/dist/session/workspace-client.js +62 -0
- package/dist/session/workspace-client.js.map +1 -0
- package/dist/session/workspace-marker.d.ts +25 -0
- package/dist/session/workspace-marker.d.ts.map +1 -0
- package/dist/session/workspace-marker.js +35 -0
- package/dist/session/workspace-marker.js.map +1 -0
- package/dist/sse/channel.d.ts.map +1 -1
- package/dist/sse/channel.js +4 -0
- package/dist/sse/channel.js.map +1 -1
- package/package.json +5 -4
- package/src/backend.ts +111 -22
- package/src/config.ts +59 -0
- package/src/contract.ts +197 -15
- package/src/debug/ports-resolved.test.ts +66 -0
- package/src/debug/ports-resolved.ts +43 -0
- package/src/debug/relay.ts +32 -4
- package/src/debug/run-projection.test.ts +155 -0
- package/src/debug/run-projection.ts +122 -0
- package/src/index.ts +20 -1
- package/src/routes/apps.ts +14 -5
- package/src/routes/io.ts +58 -12
- package/src/routes/session-start.ts +106 -27
- package/src/routes/sessions.ts +498 -7
- package/src/server.ts +22 -1
- package/src/session/byte-ring-buffer.ts +8 -2
- package/src/session/registry.ts +288 -28
- package/src/session/ring-buffer.test.ts +4 -3
- package/src/session/watch-lifetime.test.ts +203 -0
- package/src/session/watch-supervisor.ts +112 -0
- package/src/session/workspace-app.ts +27 -0
- package/src/session/workspace-client.ts +80 -0
- package/src/session/workspace-marker.test.ts +35 -0
- package/src/session/workspace-marker.ts +39 -0
- package/src/sse/channel.ts +5 -0
- package/workspace-app/telo.yaml +228 -0
package/dist/routes/sessions.js
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
|
+
import { DEFAULT_APP_NAME, } from "../contract.js";
|
|
1
2
|
import { BundlePathError, normalizeBundlePath } from "../session/bundle-path.js";
|
|
2
|
-
import { enforceTerms, portsSchema, startWorkloadSession } from "./session-start.js";
|
|
3
|
+
import { enforceTerms, launchWorkload, portsSchema, startWorkloadSession } from "./session-start.js";
|
|
3
4
|
import { streamSessionEvents } from "../sse/channel.js";
|
|
5
|
+
const appsSchema = {
|
|
6
|
+
type: "array",
|
|
7
|
+
minItems: 1,
|
|
8
|
+
items: {
|
|
9
|
+
type: "object",
|
|
10
|
+
required: ["name", "entryRelativePath"],
|
|
11
|
+
properties: {
|
|
12
|
+
name: { type: "string", minLength: 1, maxLength: 63 },
|
|
13
|
+
entryRelativePath: { type: "string", minLength: 1 },
|
|
14
|
+
ports: portsSchema,
|
|
15
|
+
io: { type: "string", enum: ["tty", "streams"] },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
4
19
|
const startBodySchema = {
|
|
5
20
|
type: "object",
|
|
6
21
|
required: ["bundle", "env", "config"],
|
|
@@ -38,8 +53,38 @@ const startBodySchema = {
|
|
|
38
53
|
},
|
|
39
54
|
},
|
|
40
55
|
inspect: { type: "boolean" },
|
|
56
|
+
mode: { type: "string", enum: ["run", "watch"] },
|
|
57
|
+
agent: { type: "string", minLength: 1 },
|
|
58
|
+
apps: appsSchema,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
const changeSetSchema = {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
write: {
|
|
65
|
+
type: "array",
|
|
66
|
+
items: {
|
|
67
|
+
type: "object",
|
|
68
|
+
required: ["path", "content"],
|
|
69
|
+
properties: {
|
|
70
|
+
path: { type: "string", minLength: 1 },
|
|
71
|
+
content: { type: "string" },
|
|
72
|
+
encoding: { type: "string", enum: ["utf8", "base64"] },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
delete: { type: "array", items: { type: "string", minLength: 1 } },
|
|
41
77
|
},
|
|
42
78
|
};
|
|
79
|
+
/** A DNS label — the app name appears in a container name and in every run
|
|
80
|
+
* event, so it has to survive both. */
|
|
81
|
+
const APP_NAME_PATTERN = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
82
|
+
/** Names a session's own containers already use. The docker backend keys every
|
|
83
|
+
* container of a session in one map, so an app called `workspace` would
|
|
84
|
+
* overwrite the workspace handle — leaking the real container, since
|
|
85
|
+
* `AutoRemove` only fires on stop. Reserved in core so one rule covers both
|
|
86
|
+
* backends rather than k8s being safe only by its `app-` prefix. */
|
|
87
|
+
const RESERVED_APP_NAMES = new Set(["workspace", "agent"]);
|
|
43
88
|
export function sessionsRoute(deps) {
|
|
44
89
|
return async (app) => {
|
|
45
90
|
app.post("/v1/sessions", { schema: { body: startBodySchema } }, async (req, reply) => {
|
|
@@ -56,6 +101,14 @@ export function sessionsRoute(deps) {
|
|
|
56
101
|
reply.send({
|
|
57
102
|
sessionId: entry.sessionId,
|
|
58
103
|
status: entry.status,
|
|
104
|
+
mode: entry.mode,
|
|
105
|
+
agent: entry.agent,
|
|
106
|
+
apps: [...entry.apps.values()].map((a) => ({
|
|
107
|
+
name: a.name,
|
|
108
|
+
io: a.io,
|
|
109
|
+
generation: a.generation,
|
|
110
|
+
ports: a.ports,
|
|
111
|
+
})),
|
|
59
112
|
createdAt: entry.createdAt.toISOString(),
|
|
60
113
|
exitedAt: entry.exitedAt?.toISOString(),
|
|
61
114
|
});
|
|
@@ -86,8 +139,326 @@ export function sessionsRoute(deps) {
|
|
|
86
139
|
sessionId: req.params.id,
|
|
87
140
|
corsOrigins: deps.corsOrigins,
|
|
88
141
|
}));
|
|
142
|
+
// ---- Workspace surface -------------------------------------------------
|
|
143
|
+
// Every write from OUTSIDE the pod goes through these; the co-resident agent
|
|
144
|
+
// writes the same volume directly with its own filesystem tools. Two writers,
|
|
145
|
+
// N watchers, one directory — which is what replaces three delivery paths.
|
|
146
|
+
app.get("/v1/sessions/:id/workspace", async (req, reply) => {
|
|
147
|
+
const ws = resolveWorkspace(deps, req.params.id, reply);
|
|
148
|
+
if (!ws)
|
|
149
|
+
return;
|
|
150
|
+
reply.send(await ws.tree());
|
|
151
|
+
});
|
|
152
|
+
app.post("/v1/sessions/:id/workspace", { schema: { body: changeSetSchema } }, async (req, reply) => {
|
|
153
|
+
const entry = requireWatchSession(deps, req.params.id, reply);
|
|
154
|
+
if (!entry)
|
|
155
|
+
return;
|
|
156
|
+
// The reload budget belongs on the route that CAUSES reloads. Guarding
|
|
157
|
+
// `POST /reload` alone left the editor's save path — one write per save,
|
|
158
|
+
// each triggering a kernel reload — unbounded, which is the shape the
|
|
159
|
+
// budget exists to prevent.
|
|
160
|
+
if (!admitReload(entry, deps.watch.reloadLimitPerMinute)) {
|
|
161
|
+
reply.code(429).send({
|
|
162
|
+
error: "reload_rate_limited",
|
|
163
|
+
message: `more than ${deps.watch.reloadLimitPerMinute} workspace writes in the last minute`,
|
|
164
|
+
});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const ws = entry.session?.workspace;
|
|
168
|
+
if (!ws) {
|
|
169
|
+
reply.code(409).send({ error: "not_running", message: "session has no live workspace" });
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
for (const w of req.body.write ?? [])
|
|
174
|
+
normalizeBundlePath(w.path);
|
|
175
|
+
for (const p of req.body.delete ?? [])
|
|
176
|
+
normalizeBundlePath(p);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
if (err instanceof BundlePathError) {
|
|
180
|
+
reply.code(400).send({ error: "invalid_path", message: err.message });
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
reply.send(await ws.apply(req.body));
|
|
186
|
+
});
|
|
187
|
+
app.get("/v1/sessions/:id/workspace/file", async (req, reply) => {
|
|
188
|
+
const ws = resolveWorkspace(deps, req.params.id, reply);
|
|
189
|
+
if (!ws)
|
|
190
|
+
return;
|
|
191
|
+
const path = req.query.path?.trim();
|
|
192
|
+
if (!path) {
|
|
193
|
+
reply.code(400).send({ error: "invalid_path", message: "?path= is required" });
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
normalizeBundlePath(path);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
if (err instanceof BundlePathError) {
|
|
201
|
+
reply.code(400).send({ error: "invalid_path", message: err.message });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
throw err;
|
|
205
|
+
}
|
|
206
|
+
reply.send(await ws.readFile(path));
|
|
207
|
+
});
|
|
208
|
+
// `--watch` reloads on change, and pressing Run again after a one-shot app
|
|
209
|
+
// completed is not a change. This touches the named app's entry manifest
|
|
210
|
+
// through the same write path everything else uses — no signalling into the
|
|
211
|
+
// container, no shared PID namespace, no `exec`.
|
|
212
|
+
app.post("/v1/sessions/:id/reload", async (req, reply) => {
|
|
213
|
+
const entry = requireWatchSession(deps, req.params.id, reply);
|
|
214
|
+
if (!entry)
|
|
215
|
+
return;
|
|
216
|
+
const session = entry.session;
|
|
217
|
+
if (!session?.reload) {
|
|
218
|
+
reply.code(409).send({ error: "not_running", message: "session has no live workload" });
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (!admitReload(entry, deps.watch.reloadLimitPerMinute)) {
|
|
222
|
+
reply.code(429).send({
|
|
223
|
+
error: "reload_rate_limited",
|
|
224
|
+
message: `more than ${deps.watch.reloadLimitPerMinute} reloads in the last minute`,
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Omitting `app` reloads every app in the session.
|
|
229
|
+
const requested = req.query.app?.trim();
|
|
230
|
+
if (requested && !entry.apps.has(requested)) {
|
|
231
|
+
reply.code(404).send({
|
|
232
|
+
error: "unknown_app",
|
|
233
|
+
message: `session runs no app named '${requested}'`,
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const targets = requested ? [requested] : [...entry.apps.keys()];
|
|
238
|
+
for (const name of targets)
|
|
239
|
+
entry.attribution?.expect(name, "manual");
|
|
240
|
+
for (const name of targets)
|
|
241
|
+
await session.reload(name);
|
|
242
|
+
reply.code(202).send({ reloaded: targets });
|
|
243
|
+
});
|
|
244
|
+
// A pod's container list is fixed at creation, so changing WHICH apps run
|
|
245
|
+
// costs a checkpoint and a pod recreate — the suspend/resume path, reused.
|
|
246
|
+
// Editing a file stays free; this is the rare action that pays.
|
|
247
|
+
app.put("/v1/sessions/:id/apps", { schema: { body: { type: "object", required: ["apps"], properties: { apps: appsSchema } } } }, async (req, reply) => {
|
|
248
|
+
const entry = requireWatchSession(deps, req.params.id, reply);
|
|
249
|
+
if (!entry)
|
|
250
|
+
return;
|
|
251
|
+
const session = entry.session;
|
|
252
|
+
if (!session?.setApps) {
|
|
253
|
+
reply.code(409).send({ error: "not_running", message: "session has no live workload" });
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const resolved = resolveApps(req.body.apps, undefined, []);
|
|
257
|
+
if ("error" in resolved) {
|
|
258
|
+
reply.code(400).send(resolved.error);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
// Channels for the NEW apps go in first — the backend starts emitting
|
|
262
|
+
// output as soon as a container is up, and a push to an unknown app is
|
|
263
|
+
// silently dropped. Removals wait until the backend has succeeded, so a
|
|
264
|
+
// failed recreate leaves the session describing what is still running.
|
|
265
|
+
for (const spec of resolved.apps) {
|
|
266
|
+
if (!entry.apps.has(spec.name)) {
|
|
267
|
+
deps.registry.addApp(entry, { name: spec.name, io: spec.io, ports: spec.ports });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
entry.attribution?.expectAll("resume");
|
|
271
|
+
try {
|
|
272
|
+
await session.setApps(resolved.apps);
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
// `setApps` recreates the workload, so rejecting is a normal outcome
|
|
276
|
+
// (pod create, start deadline, workspace never ready). Undo the
|
|
277
|
+
// channels we added and fail the session rather than leaving it
|
|
278
|
+
// `running` with nothing behind it.
|
|
279
|
+
for (const spec of resolved.apps) {
|
|
280
|
+
if (!entry.launch?.apps.some((a) => a.name === spec.name)) {
|
|
281
|
+
entry.apps.delete(spec.name);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
285
|
+
deps.registry.emit(entry.sessionId, {
|
|
286
|
+
type: "status",
|
|
287
|
+
status: { kind: "failed", message: `changing the app set failed: ${message}` },
|
|
288
|
+
});
|
|
289
|
+
reply.code(500).send({ error: "set_apps_failed", message });
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
for (const name of [...entry.apps.keys()]) {
|
|
293
|
+
if (!resolved.apps.some((a) => a.name === name))
|
|
294
|
+
entry.apps.delete(name);
|
|
295
|
+
}
|
|
296
|
+
// The retained launch is what `resume` rebuilds from. Leaving it stale
|
|
297
|
+
// would rebuild the ORIGINAL app set under a registry holding the new
|
|
298
|
+
// one: output for the running containers dropped, and a session document
|
|
299
|
+
// listing apps that are not running.
|
|
300
|
+
if (entry.launch)
|
|
301
|
+
entry.launch = { ...entry.launch, apps: resolved.apps };
|
|
302
|
+
reply.code(202).send({ apps: resolved.apps.map((a) => a.name) });
|
|
303
|
+
});
|
|
304
|
+
// A suspended session is best-effort by design: the checkpoint lives in the
|
|
305
|
+
// runner's memory, so a restart loses it and this answers 404. The editor
|
|
306
|
+
// holds the authoritative workspace and re-seeds from its own copy — which
|
|
307
|
+
// is a requirement ON the editor, not an observation about it.
|
|
308
|
+
app.post("/v1/sessions/:id/resume", async (req, reply) => {
|
|
309
|
+
const entry = deps.registry.get(req.params.id);
|
|
310
|
+
if (!entry || entry.status.kind !== "suspended") {
|
|
311
|
+
reply.code(404).send({
|
|
312
|
+
error: "not_suspended",
|
|
313
|
+
message: `session '${req.params.id}' is not suspended`,
|
|
314
|
+
});
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const checkpoint = entry.checkpoint;
|
|
318
|
+
const launch = entry.launch;
|
|
319
|
+
if (!checkpoint || !launch) {
|
|
320
|
+
reply.code(409).send({
|
|
321
|
+
error: "no_checkpoint",
|
|
322
|
+
message: "session was suspended before a workspace checkpoint was taken",
|
|
323
|
+
});
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
entry.attribution?.expectAll("resume");
|
|
327
|
+
entry.session = null;
|
|
328
|
+
deps.registry.emit(entry.sessionId, { type: "status", status: { kind: "starting" } });
|
|
329
|
+
// The checkpoint IS the bundle for the new pod — a cold pod re-downloads
|
|
330
|
+
// its module closure, and only the workspace is checkpointed, never the
|
|
331
|
+
// cache.
|
|
332
|
+
launchWorkload(app, deps, {
|
|
333
|
+
...launch,
|
|
334
|
+
bundle: {
|
|
335
|
+
entryRelativePath: launch.apps[0]?.entryRelativePath ?? "telo.yaml",
|
|
336
|
+
files: checkpoint.files.map((f) => ({
|
|
337
|
+
relativePath: f.path,
|
|
338
|
+
contents: f.content,
|
|
339
|
+
encoding: f.encoding,
|
|
340
|
+
})),
|
|
341
|
+
},
|
|
342
|
+
}, entry);
|
|
343
|
+
reply.code(202).send({ sessionId: entry.sessionId });
|
|
344
|
+
});
|
|
89
345
|
};
|
|
90
346
|
}
|
|
347
|
+
/** Reject anything but a live watch session, with the reason. */
|
|
348
|
+
function requireWatchSession(deps, sessionId, reply) {
|
|
349
|
+
const entry = deps.registry.get(sessionId);
|
|
350
|
+
if (!entry) {
|
|
351
|
+
reply.code(404).send({ error: "not_found", message: `session '${sessionId}' not in registry` });
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
if (entry.mode !== "watch") {
|
|
355
|
+
reply.code(409).send({
|
|
356
|
+
error: "not_a_watch_session",
|
|
357
|
+
message: "this surface exists only on a watch session",
|
|
358
|
+
});
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
return entry;
|
|
362
|
+
}
|
|
363
|
+
function resolveWorkspace(deps, sessionId, reply) {
|
|
364
|
+
const entry = requireWatchSession(deps, sessionId, reply);
|
|
365
|
+
if (!entry)
|
|
366
|
+
return undefined;
|
|
367
|
+
const workspace = entry.session?.workspace;
|
|
368
|
+
if (!workspace) {
|
|
369
|
+
reply.code(409).send({ error: "not_running", message: "session has no live workspace" });
|
|
370
|
+
return undefined;
|
|
371
|
+
}
|
|
372
|
+
return workspace;
|
|
373
|
+
}
|
|
374
|
+
/** Sliding one-minute window. Recorded only on an ADMITTED reload, so a client
|
|
375
|
+
* hammering a rate-limited endpoint cannot extend its own penalty. */
|
|
376
|
+
function admitReload(entry, limitPerMinute) {
|
|
377
|
+
const now = Date.now();
|
|
378
|
+
entry.reloads = entry.reloads.filter((t) => now - t < 60_000);
|
|
379
|
+
if (entry.reloads.length >= limitPerMinute)
|
|
380
|
+
return false;
|
|
381
|
+
entry.reloads.push(now);
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Normalize the declared app set. Omitted, it defaults to a single app named
|
|
386
|
+
* `app` taking the bundle's own entry and the request's `ports` — so a
|
|
387
|
+
* single-app session is written exactly as it is today.
|
|
388
|
+
*
|
|
389
|
+
* Ports are unique across the WHOLE session, not per app: session hosts are
|
|
390
|
+
* `<port>-<sessionId>.<base-domain>`, a single label, so two apps both listening
|
|
391
|
+
* on 3000 collide with nothing to distinguish them. Rejecting at create is a
|
|
392
|
+
* better outcome than a URL that silently reaches the wrong app — the user
|
|
393
|
+
* controls both manifests.
|
|
394
|
+
*/
|
|
395
|
+
function resolveApps(declared, bundleEntry, fallbackPorts) {
|
|
396
|
+
const specs = declared ?? [
|
|
397
|
+
{
|
|
398
|
+
name: DEFAULT_APP_NAME,
|
|
399
|
+
entryRelativePath: bundleEntry ?? "",
|
|
400
|
+
ports: fallbackPorts,
|
|
401
|
+
},
|
|
402
|
+
];
|
|
403
|
+
const seenNames = new Set();
|
|
404
|
+
const portOwner = new Map();
|
|
405
|
+
const apps = [];
|
|
406
|
+
for (const spec of specs) {
|
|
407
|
+
if (!APP_NAME_PATTERN.test(spec.name)) {
|
|
408
|
+
return {
|
|
409
|
+
error: {
|
|
410
|
+
error: "invalid_app_name",
|
|
411
|
+
message: `app name '${spec.name}' must be a DNS label (lowercase alphanumeric and '-')`,
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
if (RESERVED_APP_NAMES.has(spec.name)) {
|
|
416
|
+
return {
|
|
417
|
+
error: {
|
|
418
|
+
error: "reserved_app_name",
|
|
419
|
+
message: `app name '${spec.name}' is reserved — a session's own containers use it`,
|
|
420
|
+
},
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
if (seenNames.has(spec.name)) {
|
|
424
|
+
return {
|
|
425
|
+
error: { error: "duplicate_app_name", message: `app '${spec.name}' is declared twice` },
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
seenNames.add(spec.name);
|
|
429
|
+
let entryRelativePath;
|
|
430
|
+
try {
|
|
431
|
+
entryRelativePath = normalizeBundlePath(spec.entryRelativePath);
|
|
432
|
+
}
|
|
433
|
+
catch (err) {
|
|
434
|
+
if (err instanceof BundlePathError) {
|
|
435
|
+
return { error: { error: "invalid_bundle", message: err.message } };
|
|
436
|
+
}
|
|
437
|
+
throw err;
|
|
438
|
+
}
|
|
439
|
+
const ports = spec.ports ?? [];
|
|
440
|
+
for (const port of ports) {
|
|
441
|
+
const key = `${port.protocol}/${port.port}`;
|
|
442
|
+
const owner = portOwner.get(key);
|
|
443
|
+
if (owner) {
|
|
444
|
+
return {
|
|
445
|
+
error: {
|
|
446
|
+
error: "port_conflict",
|
|
447
|
+
message: `apps '${owner}' and '${spec.name}' both declare ${port.protocol} port ${port.port}; session hosts carry no app name, so the two would be indistinguishable`,
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
portOwner.set(key, spec.name);
|
|
452
|
+
}
|
|
453
|
+
apps.push({
|
|
454
|
+
name: spec.name,
|
|
455
|
+
entryRelativePath,
|
|
456
|
+
ports,
|
|
457
|
+
io: (spec.io ?? "tty"),
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
return { apps };
|
|
461
|
+
}
|
|
91
462
|
async function startSession(app, deps, body, reply) {
|
|
92
463
|
let entryRelative;
|
|
93
464
|
try {
|
|
@@ -115,14 +486,68 @@ async function startSession(app, deps, body, reply) {
|
|
|
115
486
|
return;
|
|
116
487
|
}
|
|
117
488
|
}
|
|
489
|
+
const mode = body.mode ?? "run";
|
|
490
|
+
if (mode === "watch" && !deps.watch.enabled) {
|
|
491
|
+
reply.code(400).send({
|
|
492
|
+
error: "watch_disabled",
|
|
493
|
+
message: "this runner does not offer watch sessions (see /v1/capabilities)",
|
|
494
|
+
});
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
// An agent with nothing watching its writes is a silent no-op, so the pairing
|
|
498
|
+
// is enforced rather than tolerated.
|
|
499
|
+
let agent;
|
|
500
|
+
if (body.agent) {
|
|
501
|
+
if (mode !== "watch") {
|
|
502
|
+
reply.code(400).send({
|
|
503
|
+
error: "agent_requires_watch",
|
|
504
|
+
message: "`agent` requires `mode: \"watch\"` — nothing would observe the agent's writes",
|
|
505
|
+
});
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
agent = deps.apps?.[body.agent];
|
|
509
|
+
if (!agent) {
|
|
510
|
+
const offered = Object.keys(deps.apps ?? {});
|
|
511
|
+
reply.code(400).send({
|
|
512
|
+
error: "unknown_agent",
|
|
513
|
+
message: `agent '${body.agent}' is not offered by this runner` +
|
|
514
|
+
(offered.length > 0 ? ` — offered: ${offered.join(", ")}` : ""),
|
|
515
|
+
});
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
if (mode === "watch") {
|
|
520
|
+
// A suspended session holds no pod, so it does not consume the resource the
|
|
521
|
+
// ceiling exists to bound — and it is reclaimable, so counting it would let
|
|
522
|
+
// a few visitors who left hold every slot for the whole suspended TTL.
|
|
523
|
+
const live = deps.registry
|
|
524
|
+
.list()
|
|
525
|
+
.filter((e) => e.mode === "watch" && e.exitedAt === null && e.status.kind !== "suspended").length;
|
|
526
|
+
if (live >= deps.watch.maxSessions) {
|
|
527
|
+
reply.code(409).send({
|
|
528
|
+
error: "too_many_watch_sessions",
|
|
529
|
+
message: `runner is at its configured max of ${deps.watch.maxSessions} concurrent watch sessions`,
|
|
530
|
+
});
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const resolved = resolveApps(body.apps, entryRelative, body.ports ?? []);
|
|
535
|
+
if ("error" in resolved) {
|
|
536
|
+
reply.code(400).send(resolved.error);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
118
539
|
return startWorkloadSession(app, deps, {
|
|
119
540
|
bundle: body.bundle,
|
|
120
|
-
entryRelativePath: entryRelative,
|
|
121
541
|
env: body.env,
|
|
122
|
-
ports: body.ports ?? [],
|
|
123
542
|
config: body.config,
|
|
124
543
|
selfContained: false,
|
|
125
|
-
|
|
544
|
+
// A watch session always runs with the kernel debug stream on: that stream
|
|
545
|
+
// is the only place run outcomes exist, and parsing the merged PTY output
|
|
546
|
+
// would not be a contract.
|
|
547
|
+
inspect: mode === "watch" ? true : (body.inspect ?? false),
|
|
548
|
+
mode,
|
|
549
|
+
apps: resolved.apps,
|
|
550
|
+
agent,
|
|
126
551
|
}, reply);
|
|
127
552
|
}
|
|
128
553
|
//# sourceMappingURL=sessions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAIhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAuB,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAO5F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAIhF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAuB,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAO5F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB;;;4EAGwE;IACxE,YAAY,EAAE,kBAAkB,GAAG,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC9D,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;0EAEsE;IACtE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/D;;;0CAGsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,eAAe,CAAC;IACrB,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAwFzE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC,GAC5C,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
package/dist/server.js
CHANGED
|
@@ -8,6 +8,7 @@ import { ioRoute } from "./routes/io.js";
|
|
|
8
8
|
import { probeRoute } from "./routes/probe.js";
|
|
9
9
|
import { sessionsRoute } from "./routes/sessions.js";
|
|
10
10
|
import { SessionRegistry } from "./session/registry.js";
|
|
11
|
+
import { WatchSupervisor } from "./session/watch-supervisor.js";
|
|
11
12
|
export async function buildServer(deps) {
|
|
12
13
|
const app = Fastify({
|
|
13
14
|
logger: { level: deps.config.logLevel },
|
|
@@ -17,7 +18,7 @@ export async function buildServer(deps) {
|
|
|
17
18
|
// default to `*` and let operators narrow via RUNNER_CORS_ORIGINS.
|
|
18
19
|
await app.register(cors, {
|
|
19
20
|
origin: deps.config.corsOrigins,
|
|
20
|
-
methods: ["GET", "POST", "DELETE", "OPTIONS"],
|
|
21
|
+
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
21
22
|
});
|
|
22
23
|
await app.register(websocket);
|
|
23
24
|
const registry = deps.registry ??
|
|
@@ -25,7 +26,18 @@ export async function buildServer(deps) {
|
|
|
25
26
|
maxSessions: deps.config.maxSessions,
|
|
26
27
|
exitTtlMs: deps.config.exitTtlMs,
|
|
27
28
|
replayBufferBytes: deps.config.replayBufferBytes,
|
|
29
|
+
suspendedTtlMs: deps.config.watch.suspendedTtlMs,
|
|
28
30
|
});
|
|
31
|
+
// The checkpoint timer and the idle reaper. Started unconditionally: it walks
|
|
32
|
+
// watch sessions only, and with watch disabled there are none.
|
|
33
|
+
const supervisor = new WatchSupervisor({
|
|
34
|
+
registry,
|
|
35
|
+
idleMs: deps.config.watch.idleMs,
|
|
36
|
+
checkpointMs: deps.config.watch.checkpointMs,
|
|
37
|
+
log: app.log,
|
|
38
|
+
});
|
|
39
|
+
supervisor.start();
|
|
40
|
+
app.addHook("onClose", async () => supervisor.stop());
|
|
29
41
|
// The app catalog is injected into the served capabilities document here, so
|
|
30
42
|
// what /v1/capabilities advertises and what the session route accepts can
|
|
31
43
|
// never drift — both come from `deps.apps`.
|
|
@@ -49,6 +61,14 @@ export async function buildServer(deps) {
|
|
|
49
61
|
// The capabilities document is the single source of the runner's terms;
|
|
50
62
|
// every session-creating route enforces what /v1/capabilities advertises.
|
|
51
63
|
terms: capabilitiesValue.terms,
|
|
64
|
+
// A co-resident agent IS an operator-predefined application — one that
|
|
65
|
+
// happens to share a pod — so it resolves against the same catalog.
|
|
66
|
+
apps: deps.apps,
|
|
67
|
+
watch: {
|
|
68
|
+
enabled: deps.config.watch.enabled,
|
|
69
|
+
maxSessions: deps.config.watch.maxSessions,
|
|
70
|
+
reloadLimitPerMinute: deps.config.watch.reloadLimitPerMinute,
|
|
71
|
+
},
|
|
52
72
|
}));
|
|
53
73
|
await app.register(appsRoute({
|
|
54
74
|
backend: deps.backend,
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAyD,MAAM,SAAS,CAAC;AAChF,OAAO,IAAI,MAAM,eAAe,CAAC;AACjC,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAK3C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import type { ByteStreamTag } from "../contract.js";
|
|
1
2
|
export interface BufferedBytes {
|
|
2
3
|
seq: number;
|
|
3
4
|
bytes: Buffer;
|
|
5
|
+
/** Which stream produced these bytes. `tty` under a terminal attach, where
|
|
6
|
+
* there is genuinely one merged stream; `stdout` / `stderr` only where the
|
|
7
|
+
* transport really did separate them. */
|
|
8
|
+
stream: ByteStreamTag;
|
|
4
9
|
}
|
|
5
10
|
/**
|
|
6
11
|
* Byte-capped FIFO ring buffer for raw PTY output replay. Mirrors
|
|
@@ -16,7 +21,7 @@ export declare class ByteRingBuffer {
|
|
|
16
21
|
private totalBytes;
|
|
17
22
|
private nextSeq;
|
|
18
23
|
constructor(maxBytes: number);
|
|
19
|
-
push(bytes: Buffer): BufferedBytes;
|
|
24
|
+
push(bytes: Buffer, stream?: ByteStreamTag): BufferedBytes;
|
|
20
25
|
private evict;
|
|
21
26
|
replay(afterSeq: number): {
|
|
22
27
|
entries: BufferedBytes[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"byte-ring-buffer.d.ts","sourceRoot":"","sources":["../../src/session/byte-ring-buffer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"byte-ring-buffer.d.ts","sourceRoot":"","sources":["../../src/session/byte-ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd;;8CAE0C;IAC1C,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;IAKb,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAK;gBAES,QAAQ,EAAE,MAAM;IAM7C,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,aAAqB,GAAG,aAAa;IASjE,OAAO,CAAC,KAAK;IAUb,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;IAOvE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
|
|
@@ -17,9 +17,9 @@ export class ByteRingBuffer {
|
|
|
17
17
|
throw new Error(`ByteRingBuffer maxBytes must be a positive integer, got ${maxBytes}`);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
push(bytes) {
|
|
20
|
+
push(bytes, stream = "tty") {
|
|
21
21
|
const seq = this.nextSeq++;
|
|
22
|
-
const entry = { seq, bytes };
|
|
22
|
+
const entry = { seq, bytes, stream };
|
|
23
23
|
this.entries.push(entry);
|
|
24
24
|
this.totalBytes += bytes.byteLength;
|
|
25
25
|
this.evict();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"byte-ring-buffer.js","sourceRoot":"","sources":["../../src/session/byte-ring-buffer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"byte-ring-buffer.js","sourceRoot":"","sources":["../../src/session/byte-ring-buffer.ts"],"names":[],"mappings":"AAWA;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;IAKI;IAJZ,OAAO,GAAoB,EAAE,CAAC;IACvC,UAAU,GAAG,CAAC,CAAC;IACf,OAAO,GAAG,CAAC,CAAC;IAEpB,YAA6B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;QAC3C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,2DAA2D,QAAQ,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAED,IAAI,CAAC,KAAa,EAAE,SAAwB,KAAK;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAkB,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK;QACX,yEAAyE;QACzE,gDAAgD;QAChD,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO;gBAAE,MAAM;YACpB,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,MAAM,CAAC,QAAgB;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC;QACvD,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,GAAG,SAAS,CAAC;QACxC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF"}
|