@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.
Files changed (97) hide show
  1. package/README.md +33 -2
  2. package/dist/backend.d.ts +107 -23
  3. package/dist/backend.d.ts.map +1 -1
  4. package/dist/config.d.ts +27 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +12 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/contract.d.ts +199 -15
  9. package/dist/contract.d.ts.map +1 -1
  10. package/dist/contract.js +9 -0
  11. package/dist/contract.js.map +1 -1
  12. package/dist/debug/ports-resolved.d.ts +26 -0
  13. package/dist/debug/ports-resolved.d.ts.map +1 -0
  14. package/dist/debug/ports-resolved.js +42 -0
  15. package/dist/debug/ports-resolved.js.map +1 -0
  16. package/dist/debug/relay.d.ts.map +1 -1
  17. package/dist/debug/relay.js +34 -6
  18. package/dist/debug/relay.js.map +1 -1
  19. package/dist/debug/run-projection.d.ts +53 -0
  20. package/dist/debug/run-projection.d.ts.map +1 -0
  21. package/dist/debug/run-projection.js +115 -0
  22. package/dist/debug/run-projection.js.map +1 -0
  23. package/dist/index.d.ts +8 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +7 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/routes/apps.d.ts +1 -1
  28. package/dist/routes/apps.d.ts.map +1 -1
  29. package/dist/routes/apps.js +14 -4
  30. package/dist/routes/apps.js.map +1 -1
  31. package/dist/routes/io.d.ts.map +1 -1
  32. package/dist/routes/io.js +42 -9
  33. package/dist/routes/io.js.map +1 -1
  34. package/dist/routes/session-start.d.ts +12 -12
  35. package/dist/routes/session-start.d.ts.map +1 -1
  36. package/dist/routes/session-start.js +86 -13
  37. package/dist/routes/session-start.js.map +1 -1
  38. package/dist/routes/sessions.d.ts +11 -1
  39. package/dist/routes/sessions.d.ts.map +1 -1
  40. package/dist/routes/sessions.js +429 -4
  41. package/dist/routes/sessions.js.map +1 -1
  42. package/dist/server.d.ts.map +1 -1
  43. package/dist/server.js +21 -1
  44. package/dist/server.js.map +1 -1
  45. package/dist/session/byte-ring-buffer.d.ts +6 -1
  46. package/dist/session/byte-ring-buffer.d.ts.map +1 -1
  47. package/dist/session/byte-ring-buffer.js +2 -2
  48. package/dist/session/byte-ring-buffer.js.map +1 -1
  49. package/dist/session/registry.d.ts +144 -13
  50. package/dist/session/registry.d.ts.map +1 -1
  51. package/dist/session/registry.js +166 -25
  52. package/dist/session/registry.js.map +1 -1
  53. package/dist/session/watch-supervisor.d.ts +42 -0
  54. package/dist/session/watch-supervisor.d.ts.map +1 -0
  55. package/dist/session/watch-supervisor.js +99 -0
  56. package/dist/session/watch-supervisor.js.map +1 -0
  57. package/dist/session/workspace-app.d.ts +4 -0
  58. package/dist/session/workspace-app.d.ts.map +1 -0
  59. package/dist/session/workspace-app.js +26 -0
  60. package/dist/session/workspace-app.js.map +1 -0
  61. package/dist/session/workspace-client.d.ts +33 -0
  62. package/dist/session/workspace-client.d.ts.map +1 -0
  63. package/dist/session/workspace-client.js +62 -0
  64. package/dist/session/workspace-client.js.map +1 -0
  65. package/dist/session/workspace-marker.d.ts +25 -0
  66. package/dist/session/workspace-marker.d.ts.map +1 -0
  67. package/dist/session/workspace-marker.js +35 -0
  68. package/dist/session/workspace-marker.js.map +1 -0
  69. package/dist/sse/channel.d.ts.map +1 -1
  70. package/dist/sse/channel.js +4 -0
  71. package/dist/sse/channel.js.map +1 -1
  72. package/package.json +5 -4
  73. package/src/backend.ts +111 -22
  74. package/src/config.ts +59 -0
  75. package/src/contract.ts +197 -15
  76. package/src/debug/ports-resolved.test.ts +66 -0
  77. package/src/debug/ports-resolved.ts +43 -0
  78. package/src/debug/relay.ts +32 -4
  79. package/src/debug/run-projection.test.ts +155 -0
  80. package/src/debug/run-projection.ts +122 -0
  81. package/src/index.ts +20 -1
  82. package/src/routes/apps.ts +14 -5
  83. package/src/routes/io.ts +58 -12
  84. package/src/routes/session-start.ts +106 -27
  85. package/src/routes/sessions.ts +498 -7
  86. package/src/server.ts +22 -1
  87. package/src/session/byte-ring-buffer.ts +8 -2
  88. package/src/session/registry.ts +288 -28
  89. package/src/session/ring-buffer.test.ts +4 -3
  90. package/src/session/watch-lifetime.test.ts +203 -0
  91. package/src/session/watch-supervisor.ts +112 -0
  92. package/src/session/workspace-app.ts +27 -0
  93. package/src/session/workspace-client.ts +80 -0
  94. package/src/session/workspace-marker.test.ts +35 -0
  95. package/src/session/workspace-marker.ts +39 -0
  96. package/src/sse/channel.ts +5 -0
  97. package/workspace-app/telo.yaml +228 -0
package/dist/contract.js CHANGED
@@ -6,6 +6,15 @@
6
6
  */
7
7
  /** HTTP header carrying the accepted terms version on `POST /v1/sessions`. */
8
8
  export const ACCEPTED_TERMS_HEADER = "x-telo-accepted-terms";
9
+ /** The name a single-app session's one application takes when the request
10
+ * declares no `apps` — so every `run` / `debug` / `endpoints` event names an
11
+ * app, and no client needs two readings of the same stream. */
12
+ export const DEFAULT_APP_NAME = "app";
13
+ /**
14
+ * Terminal = the session is over and the registry may schedule eviction.
15
+ * `suspended` is deliberately NOT terminal: the session record and its workspace
16
+ * checkpoint outlive the pod, and `resume` brings it back under the same id.
17
+ */
9
18
  export function isTerminal(status) {
10
19
  return status.kind === "exited" || status.kind === "failed" || status.kind === "stopped";
11
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwCH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAuH7D,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC;AAC3F,CAAC;AAeD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAExB;IACA;IAEA;IAJlB,YACkB,IAAoC,EACpC,KAAwB,EACxC,OAAe,EACC,aAAsB;QAEtC,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,SAAI,GAAJ,IAAI,CAAgC;QACpC,UAAK,GAAL,KAAK,CAAmB;QAExB,kBAAa,GAAb,aAAa,CAAS;QAGtC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwCH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AA8G7D;;gEAEgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AA4ItC;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC;AAC3F,CAAC;AA0DD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAExB;IACA;IAEA;IAJlB,YACkB,IAAoC,EACpC,KAAwB,EACxC,OAAe,EACC,aAAsB;QAEtC,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,SAAI,GAAJ,IAAI,CAAgC;QACpC,UAAK,GAAL,KAAK,CAAmB;QAExB,kBAAa,GAAb,aAAa,CAAS;QAGtC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ import { type DebugFrame } from "@telorun/debug-wire";
2
+ import type { PortMapping } from "../contract.js";
3
+ /** The kernel says this once per load: the Application's `ports:` block has
4
+ * resolved to these integers. It re-fires on every watch reload, which is what
5
+ * lets a host re-route without parsing a manifest. */
6
+ export declare const PORTS_RESOLVED_EVENT = "Kernel.PortsResolved";
7
+ /**
8
+ * The declared port set carried by a `Kernel.PortsResolved` frame, or undefined
9
+ * for any other frame.
10
+ *
11
+ * DECLARED, not bound. A runner routes what the manifest asked for; whether
12
+ * anything actually bound it is the reachability watcher's question, and it
13
+ * already answers it per port. Routing what happened to be bound instead would
14
+ * expose a port the manifest never declared, and would rest on a per-module
15
+ * convention — a transport whose kind does not emit a listening event would
16
+ * silently get no routing at all.
17
+ *
18
+ * Tolerant of a payload that is not the expected shape: a runner reads this off
19
+ * a stream produced by a kernel it does not version together with, so a frame it
20
+ * cannot make sense of is one to ignore, not to fail on.
21
+ */
22
+ export declare function portsResolvedFrom(frame: DebugFrame): PortMapping[] | undefined;
23
+ /** Identity of a port within a session: the pair, since tcp/3000 and udp/3000
24
+ * are different endpoints. */
25
+ export declare function portKey(mapping: PortMapping): string;
26
+ //# sourceMappingURL=ports-resolved.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports-resolved.d.ts","sourceRoot":"","sources":["../../src/debug/ports-resolved.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAEhE;;uDAEuD;AACvD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,EAAE,GAAG,SAAS,CAY9E;AAED;+BAC+B;AAC/B,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAEpD"}
@@ -0,0 +1,42 @@
1
+ import { isEventFrame } from "@telorun/debug-wire";
2
+ /** The kernel says this once per load: the Application's `ports:` block has
3
+ * resolved to these integers. It re-fires on every watch reload, which is what
4
+ * lets a host re-route without parsing a manifest. */
5
+ export const PORTS_RESOLVED_EVENT = "Kernel.PortsResolved";
6
+ /**
7
+ * The declared port set carried by a `Kernel.PortsResolved` frame, or undefined
8
+ * for any other frame.
9
+ *
10
+ * DECLARED, not bound. A runner routes what the manifest asked for; whether
11
+ * anything actually bound it is the reachability watcher's question, and it
12
+ * already answers it per port. Routing what happened to be bound instead would
13
+ * expose a port the manifest never declared, and would rest on a per-module
14
+ * convention — a transport whose kind does not emit a listening event would
15
+ * silently get no routing at all.
16
+ *
17
+ * Tolerant of a payload that is not the expected shape: a runner reads this off
18
+ * a stream produced by a kernel it does not version together with, so a frame it
19
+ * cannot make sense of is one to ignore, not to fail on.
20
+ */
21
+ export function portsResolvedFrom(frame) {
22
+ if (!isEventFrame(frame) || frame.event !== PORTS_RESOLVED_EVENT)
23
+ return undefined;
24
+ const raw = frame.payload?.ports;
25
+ if (!Array.isArray(raw))
26
+ return undefined;
27
+ const ports = [];
28
+ for (const entry of raw) {
29
+ const port = entry?.port;
30
+ const protocol = entry?.protocol;
31
+ if (typeof port !== "number" || !Number.isInteger(port))
32
+ continue;
33
+ ports.push({ port, protocol: protocol === "udp" ? "udp" : "tcp" });
34
+ }
35
+ return ports;
36
+ }
37
+ /** Identity of a port within a session: the pair, since tcp/3000 and udp/3000
38
+ * are different endpoints. */
39
+ export function portKey(mapping) {
40
+ return `${mapping.protocol}/${mapping.port}`;
41
+ }
42
+ //# sourceMappingURL=ports-resolved.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports-resolved.js","sourceRoot":"","sources":["../../src/debug/ports-resolved.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AAIpE;;uDAEuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IACjD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,oBAAoB;QAAE,OAAO,SAAS,CAAC;IACnF,MAAM,GAAG,GAAI,KAAK,CAAC,OAA2C,EAAE,KAAK,CAAC;IACtE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,MAAM,IAAI,GAAI,KAA4B,EAAE,IAAI,CAAC;QACjD,MAAM,QAAQ,GAAI,KAAgC,EAAE,QAAQ,CAAC;QAC7D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,SAAS;QAClE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,KAAsB,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;+BAC+B;AAC/B,MAAM,UAAU,OAAO,CAAC,OAAoB;IAC1C,OAAO,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/debug/relay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD,MAAM,WAAW,iBAAiB;IAChC;2EACuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB;;qDAEiD;IACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAID;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB7E"}
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/debug/relay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAItD,MAAM,WAAW,iBAAiB;IAChC;2EACuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB;;qDAEiD;IACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAID;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B7E"}
@@ -11,17 +11,27 @@ const RECONNECT_DELAY_MS = 500;
11
11
  */
12
12
  export async function relayDebugStream(opts) {
13
13
  const { url, onFrame, signal } = opts;
14
+ // The last id delivered, carried across reconnects. Without it a drop replays
15
+ // the producer's whole buffer, and a consumer that DERIVES state from the
16
+ // stream — the run projection counting generations — re-counts every reload
17
+ // still in that buffer. In a watch session that is one pair per save.
18
+ let lastEventId = 0;
14
19
  while (!signal.aborted) {
15
20
  try {
16
21
  const res = await fetch(url, {
17
22
  signal,
18
- headers: { accept: "text/event-stream" },
23
+ headers: {
24
+ accept: "text/event-stream",
25
+ ...(lastEventId > 0 ? { "last-event-id": String(lastEventId) } : {}),
26
+ },
19
27
  });
20
28
  if (!res.ok || !res.body) {
21
29
  await abortableDelay(RECONNECT_DELAY_MS, signal);
22
30
  continue;
23
31
  }
24
- await pump(res.body, onFrame, signal);
32
+ await pump(res.body, onFrame, signal, (id) => {
33
+ lastEventId = id;
34
+ });
25
35
  }
26
36
  catch (err) {
27
37
  if (signal.aborted)
@@ -31,7 +41,7 @@ export async function relayDebugStream(opts) {
31
41
  await abortableDelay(RECONNECT_DELAY_MS, signal);
32
42
  }
33
43
  }
34
- async function pump(body, onFrame, signal) {
44
+ async function pump(body, onFrame, signal, onId) {
35
45
  const reader = body.getReader();
36
46
  const decoder = new TextDecoder();
37
47
  let buf = "";
@@ -44,10 +54,17 @@ async function pump(body, onFrame, signal) {
44
54
  let sep;
45
55
  // SSE frames are separated by a blank line.
46
56
  while ((sep = buf.indexOf("\n\n")) >= 0) {
47
- const frame = parseSseData(buf.slice(0, sep));
57
+ const block = buf.slice(0, sep);
48
58
  buf = buf.slice(sep + 2);
49
- if (frame)
50
- onFrame(frame);
59
+ const frame = parseSseData(block);
60
+ if (!frame)
61
+ continue;
62
+ onFrame(frame);
63
+ // Checkpoint AFTER delivery, so a frame the consumer never saw is not
64
+ // skipped on the next reconnect.
65
+ const id = parseSseId(block);
66
+ if (id !== null)
67
+ onId(id);
51
68
  }
52
69
  }
53
70
  }
@@ -55,6 +72,17 @@ async function pump(body, onFrame, signal) {
55
72
  reader.cancel().catch(() => undefined);
56
73
  }
57
74
  }
75
+ /** The `id:` of one SSE frame, or null when the producer sent none — an older
76
+ * kernel, whose stream simply has no resume point. */
77
+ function parseSseId(block) {
78
+ for (const line of block.split("\n")) {
79
+ if (!line.startsWith("id:"))
80
+ continue;
81
+ const parsed = Number.parseInt(line.slice(3).trim(), 10);
82
+ return Number.isFinite(parsed) ? parsed : null;
83
+ }
84
+ return null;
85
+ }
58
86
  /** Extract and parse the `data:` payload of one SSE frame. Ignores comment
59
87
  * lines (`: heartbeat`) and unparseable frames. */
60
88
  function parseSseData(block) {
@@ -1 +1 @@
1
- {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/debug/relay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/debug/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { type DebugFrame } from "@telorun/debug-wire";
2
+ import type { RunTrigger } from "../contract.js";
3
+ import type { SessionRegistry } from "../session/registry.js";
4
+ /**
5
+ * Projects per-app `run` events out of the kernel lifecycle events the debug
6
+ * stream already carries.
7
+ *
8
+ * The runner cannot see inside the container, and parsing the merged PTY stream
9
+ * is not a contract — so a watch session always runs with the kernel debug
10
+ * stream on and this reads it. A watch reload is a stop/start pair on ONE debug
11
+ * connection, so `generation` is counted here and the kernel is asked for
12
+ * nothing.
13
+ *
14
+ * Three event names are read, and only three:
15
+ * - `Kernel.Starting` → the generation began
16
+ * - `Kernel.Stopped` → it ended, carrying `exitCode`
17
+ * - `Kernel.RunFailed` → it never reached a running state, carrying why
18
+ *
19
+ * `Kernel.Started` is deliberately ignored: it and `Kernel.Starting` bracket the
20
+ * same transition, and one `started` per generation is the contract.
21
+ */
22
+ export declare class RunProjection {
23
+ private readonly registry;
24
+ private readonly sessionId;
25
+ /** What to attribute the NEXT generation of each app to. A reload is a watch
26
+ * reload unless something told us otherwise, so `watch` is the resting value
27
+ * and `initial` / `manual` / `resume` are set by whoever caused them. */
28
+ private readonly triggers;
29
+ constructor(registry: SessionRegistry, sessionId: string);
30
+ /** Attribute an app's next generation. Called with `initial` when the session
31
+ * comes up, `manual` from the reload route, `resume` after a pod recreate. */
32
+ expect(app: string, trigger: RunTrigger): void;
33
+ /** Attribute every app's next generation — the session-wide cases (initial,
34
+ * resume) always move all of them together. */
35
+ expectAll(trigger: RunTrigger): void;
36
+ /** Feed one frame from `app`'s debug stream. Frames that are not one of the
37
+ * three lifecycle events pass through untouched. */
38
+ frame(app: string, frame: DebugFrame): void;
39
+ /**
40
+ * Close the open generation because its WORKLOAD ended, not because the kernel
41
+ * said so. A container that goes away under `--watch` emits no `Kernel.Stopped`
42
+ * — there is nothing left to emit it — so the backend reports the ending and
43
+ * this turns it into the same run outcome the kernel path produces.
44
+ */
45
+ endGeneration(app: string, outcome: {
46
+ code?: number;
47
+ reason?: string;
48
+ }): void;
49
+ /** Open a generation unless one is already open — `Kernel.Starting` followed
50
+ * by a `Kernel.RunFailed` from the boot phase must not count twice. */
51
+ private begin;
52
+ }
53
+ //# sourceMappingURL=run-projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-projection.d.ts","sourceRoot":"","sources":["../../src/debug/run-projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP5B;;8EAE0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;gBAGvC,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,MAAM;IAGpC;mFAC+E;IAC/E,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAI9C;oDACgD;IAChD,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAKpC;yDACqD;IACrD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IA4B3C;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAY7E;4EACwE;IACxE,OAAO,CAAC,KAAK;CASd"}
@@ -0,0 +1,115 @@
1
+ import { isEventFrame } from "@telorun/debug-wire";
2
+ /**
3
+ * Projects per-app `run` events out of the kernel lifecycle events the debug
4
+ * stream already carries.
5
+ *
6
+ * The runner cannot see inside the container, and parsing the merged PTY stream
7
+ * is not a contract — so a watch session always runs with the kernel debug
8
+ * stream on and this reads it. A watch reload is a stop/start pair on ONE debug
9
+ * connection, so `generation` is counted here and the kernel is asked for
10
+ * nothing.
11
+ *
12
+ * Three event names are read, and only three:
13
+ * - `Kernel.Starting` → the generation began
14
+ * - `Kernel.Stopped` → it ended, carrying `exitCode`
15
+ * - `Kernel.RunFailed` → it never reached a running state, carrying why
16
+ *
17
+ * `Kernel.Started` is deliberately ignored: it and `Kernel.Starting` bracket the
18
+ * same transition, and one `started` per generation is the contract.
19
+ */
20
+ export class RunProjection {
21
+ registry;
22
+ sessionId;
23
+ /** What to attribute the NEXT generation of each app to. A reload is a watch
24
+ * reload unless something told us otherwise, so `watch` is the resting value
25
+ * and `initial` / `manual` / `resume` are set by whoever caused them. */
26
+ triggers = new Map();
27
+ constructor(registry, sessionId) {
28
+ this.registry = registry;
29
+ this.sessionId = sessionId;
30
+ }
31
+ /** Attribute an app's next generation. Called with `initial` when the session
32
+ * comes up, `manual` from the reload route, `resume` after a pod recreate. */
33
+ expect(app, trigger) {
34
+ this.triggers.set(app, trigger);
35
+ }
36
+ /** Attribute every app's next generation — the session-wide cases (initial,
37
+ * resume) always move all of them together. */
38
+ expectAll(trigger) {
39
+ const entry = this.registry.get(this.sessionId);
40
+ for (const app of entry?.apps.keys() ?? [])
41
+ this.triggers.set(app, trigger);
42
+ }
43
+ /** Feed one frame from `app`'s debug stream. Frames that are not one of the
44
+ * three lifecycle events pass through untouched. */
45
+ frame(app, frame) {
46
+ if (!isEventFrame(frame))
47
+ return;
48
+ switch (frame.event) {
49
+ case "Kernel.Starting":
50
+ this.begin(app);
51
+ return;
52
+ case "Kernel.Stopped":
53
+ this.registry.finishGeneration(this.sessionId, app, {
54
+ phase: "completed",
55
+ code: exitCodeOf(frame.payload),
56
+ });
57
+ return;
58
+ case "Kernel.RunFailed":
59
+ // A LOAD failure emits no `Kernel.Starting` — the kernel never got that
60
+ // far — so open the generation here rather than reporting a failure of a
61
+ // generation the client never saw start. The pair is what a consumer
62
+ // reads as "this attempt happened and did not survive".
63
+ this.begin(app);
64
+ this.registry.finishGeneration(this.sessionId, app, {
65
+ phase: "failed",
66
+ reason: failureReason(frame.payload),
67
+ });
68
+ return;
69
+ default:
70
+ return;
71
+ }
72
+ }
73
+ /**
74
+ * Close the open generation because its WORKLOAD ended, not because the kernel
75
+ * said so. A container that goes away under `--watch` emits no `Kernel.Stopped`
76
+ * — there is nothing left to emit it — so the backend reports the ending and
77
+ * this turns it into the same run outcome the kernel path produces.
78
+ */
79
+ endGeneration(app, outcome) {
80
+ const channel = this.registry.get(this.sessionId)?.apps.get(app);
81
+ if (!channel || channel.startedAt === null)
82
+ return;
83
+ this.registry.finishGeneration(this.sessionId, app, outcome.reason === undefined && outcome.code !== undefined
84
+ ? { phase: "completed", code: outcome.code }
85
+ : { phase: "failed", reason: outcome.reason ?? "workload ended" });
86
+ }
87
+ /** Open a generation unless one is already open — `Kernel.Starting` followed
88
+ * by a `Kernel.RunFailed` from the boot phase must not count twice. */
89
+ begin(app) {
90
+ const channel = this.registry.get(this.sessionId)?.apps.get(app);
91
+ if (!channel || channel.startedAt !== null)
92
+ return;
93
+ const trigger = this.triggers.get(app) ?? "watch";
94
+ // Consumed: the next generation is a plain watch reload unless something
95
+ // says otherwise again.
96
+ this.triggers.delete(app);
97
+ this.registry.startGeneration(this.sessionId, app, trigger);
98
+ }
99
+ }
100
+ function exitCodeOf(payload) {
101
+ const code = payload?.exitCode;
102
+ return typeof code === "number" ? code : 0;
103
+ }
104
+ /** The most actionable thing the failure carries: a diagnostic code when the
105
+ * kernel had one (`CEL_UNKNOWN_FIELD`, `ERR_MANIFEST_VALIDATION_FAILED`), else
106
+ * its message. A code is what a reader — an agent above all — branches on. */
107
+ function failureReason(payload) {
108
+ const p = payload;
109
+ if (typeof p?.code === "string" && p.code !== "")
110
+ return p.code;
111
+ if (typeof p?.message === "string" && p.message !== "")
112
+ return p.message;
113
+ return "run failed";
114
+ }
115
+ //# sourceMappingURL=run-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-projection.js","sourceRoot":"","sources":["../../src/debug/run-projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmB,MAAM,qBAAqB,CAAC;AAKpE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,aAAa;IAOL;IACA;IAPnB;;8EAE0E;IACzD,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE1D,YACmB,QAAyB,EACzB,SAAiB;QADjB,aAAQ,GAAR,QAAQ,CAAiB;QACzB,cAAS,GAAT,SAAS,CAAQ;IACjC,CAAC;IAEJ;mFAC+E;IAC/E,MAAM,CAAC,GAAW,EAAE,OAAmB;QACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAED;oDACgD;IAChD,SAAS,CAAC,OAAmB;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAED;yDACqD;IACrD,KAAK,CAAC,GAAW,EAAE,KAAiB;QAClC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;YAAE,OAAO;QACjC,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;YACpB,KAAK,iBAAiB;gBACpB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChB,OAAO;YACT,KAAK,gBAAgB;gBACnB,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;oBAClD,KAAK,EAAE,WAAW;oBAClB,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;iBAChC,CAAC,CAAC;gBACH,OAAO;YACT,KAAK,kBAAkB;gBACrB,wEAAwE;gBACxE,yEAAyE;gBACzE,qEAAqE;gBACrE,wDAAwD;gBACxD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChB,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;oBAClD,KAAK,EAAE,QAAQ;oBACf,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC;iBACrC,CAAC,CAAC;gBACH,OAAO;YACT;gBACE,OAAO;QACX,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,GAAW,EAAE,OAA2C;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;YAAE,OAAO;QACnD,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAC5B,IAAI,CAAC,SAAS,EACd,GAAG,EACH,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;YACxD,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;YAC5C,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,gBAAgB,EAAE,CACpE,CAAC;IACJ,CAAC;IAED;4EACwE;IAChE,KAAK,CAAC,GAAW;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;YAAE,OAAO;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;QAClD,yEAAyE;QACzE,wBAAwB;QACxB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;CACF;AAED,SAAS,UAAU,CAAC,OAAgB;IAClC,MAAM,IAAI,GAAI,OAA8C,EAAE,QAAQ,CAAC;IACvE,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;+EAE+E;AAC/E,SAAS,aAAa,CAAC,OAAgB;IACrC,MAAM,CAAC,GAAG,OAA4D,CAAC;IACvE,IAAI,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IAChE,IAAI,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,EAAE;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IACzE,OAAO,YAAY,CAAC;AACtB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,15 +5,21 @@ export * from "./server.js";
5
5
  export { sessionConfigSchema, type SessionConfigSchemaOptions } from "./capabilities-schema.js";
6
6
  export { BaseImageCatalog, filterTags, parseDockerHubRef, resolveTagDigest, type TagFilter, type BaseImageCatalogOptions, } from "./base-image-catalog.js";
7
7
  export { extractDependencyKey, type DependencyKey } from "./dependency-key.js";
8
- export { SessionRegistry, SessionLimitError, SessionEvictedError, type SessionEntry, type RegistryDeps, } from "./session/registry.js";
8
+ export { SessionRegistry, SessionLimitError, SessionEvictedError, UnknownAppError, type AppChannel, type RunAttribution, type SessionEntry, type RegisterArgs, type RegistryDeps, type WorkspaceCheckpoint, } from "./session/registry.js";
9
+ export { WatchSupervisor, type WatchSupervisorDeps } from "./session/watch-supervisor.js";
10
+ export { RunProjection } from "./debug/run-projection.js";
11
+ export { portKey, portsResolvedFrom, PORTS_RESOLVED_EVENT, } from "./debug/ports-resolved.js";
9
12
  export { EventRingBuffer, type BufferedEvent } from "./session/ring-buffer.js";
10
13
  export { ByteRingBuffer, type BufferedBytes } from "./session/byte-ring-buffer.js";
11
14
  export { normalizeBundlePath, validateSessionId, BundlePathError } from "./session/bundle-path.js";
15
+ export { WorkspaceClient } from "./session/workspace-client.js";
16
+ export { workspaceAppManifest, WORKSPACE_APP_FILENAME } from "./session/workspace-app.js";
17
+ export { workspaceMarkerWrite, WORKSPACE_MARKER_CONTENTS, WORKSPACE_MARKER_FILENAME, } from "./session/workspace-marker.js";
12
18
  export { streamSessionEvents, type SseStreamArgs } from "./sse/channel.js";
13
19
  export { healthRoute } from "./routes/health.js";
14
20
  export { capabilitiesRoute } from "./routes/capabilities.js";
15
21
  export { probeRoute, type ProbeRouteDeps } from "./routes/probe.js";
16
- export { sessionsRoute, type SessionsRouteDeps } from "./routes/sessions.js";
22
+ export { sessionsRoute, type SessionsRouteDeps, type WatchConfig } from "./routes/sessions.js";
17
23
  export { appsRoute, type AppsRouteDeps } from "./routes/apps.js";
18
24
  export { ioRoute, type IoRouteDeps } from "./routes/io.js";
19
25
  export { relayDebugStream, type DebugRelayOptions } from "./debug/relay.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -5,10 +5,16 @@ export * from "./server.js";
5
5
  export { sessionConfigSchema } from "./capabilities-schema.js";
6
6
  export { BaseImageCatalog, filterTags, parseDockerHubRef, resolveTagDigest, } from "./base-image-catalog.js";
7
7
  export { extractDependencyKey } from "./dependency-key.js";
8
- export { SessionRegistry, SessionLimitError, SessionEvictedError, } from "./session/registry.js";
8
+ export { SessionRegistry, SessionLimitError, SessionEvictedError, UnknownAppError, } from "./session/registry.js";
9
+ export { WatchSupervisor } from "./session/watch-supervisor.js";
10
+ export { RunProjection } from "./debug/run-projection.js";
11
+ export { portKey, portsResolvedFrom, PORTS_RESOLVED_EVENT, } from "./debug/ports-resolved.js";
9
12
  export { EventRingBuffer } from "./session/ring-buffer.js";
10
13
  export { ByteRingBuffer } from "./session/byte-ring-buffer.js";
11
14
  export { normalizeBundlePath, validateSessionId, BundlePathError } from "./session/bundle-path.js";
15
+ export { WorkspaceClient } from "./session/workspace-client.js";
16
+ export { workspaceAppManifest, WORKSPACE_APP_FILENAME } from "./session/workspace-app.js";
17
+ export { workspaceMarkerWrite, WORKSPACE_MARKER_CONTENTS, WORKSPACE_MARKER_FILENAME, } from "./session/workspace-marker.js";
12
18
  export { streamSessionEvents } from "./sse/channel.js";
13
19
  export { healthRoute } from "./routes/health.js";
14
20
  export { capabilitiesRoute } from "./routes/capabilities.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAmC,MAAM,0BAA0B,CAAC;AAChG,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,gBAAgB,GAGjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAsB,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GAGpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAsB,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsB,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAsB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAA0B,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAsB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAoB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAA0B,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EACL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAmC,MAAM,0BAA0B,CAAC;AAChG,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,gBAAgB,GAGjB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAsB,MAAM,qBAAqB,CAAC;AAE/E,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,GAOhB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAA4B,MAAM,+BAA+B,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAsB,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAsB,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAsB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAuB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,aAAa,EAA4C,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAsB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAoB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAA0B,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EACL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import type { FastifyPluginAsync } from "fastify";
2
2
  import type { RunnerBackend } from "../backend.js";
3
3
  import type { ResolvedRunnerApp } from "../config.js";
4
- import type { RunnerTerms } from "../contract.js";
4
+ import { type RunnerTerms } from "../contract.js";
5
5
  import type { SessionRegistry } from "../session/registry.js";
6
6
  export interface AppsRouteDeps {
7
7
  backend: RunnerBackend;
@@ -1 +1 @@
1
- {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/routes/apps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,eAAe,CAAC;IAC1B;kEAC8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;+EAC2E;IAC3E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;mCAE+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC1C;AAoBD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,kBAAkB,CAwDjE"}
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/routes/apps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAsC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,eAAe,CAAC;IAC1B;kEAC8D;IAC9D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;+EAC2E;IAC3E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;mCAE+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC1C;AAoBD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,kBAAkB,CAiEjE"}
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_APP_NAME } from "../contract.js";
1
2
  import { enforceTerms, portsSchema, startWorkloadSession } from "./session-start.js";
2
3
  const startAppBodySchema = {
3
4
  type: "object",
@@ -48,15 +49,24 @@ export function appsRoute(deps) {
48
49
  ...appEntry.env,
49
50
  };
50
51
  return startWorkloadSession(app, deps, {
51
- // Self-contained image — no bundle to deliver; the entry path is an
52
- // unused placeholder so the backend spec stays total.
52
+ // Self-contained image — no bundle to deliver, and no entry path:
53
+ // the image's own entrypoint runs.
53
54
  bundle: { entryRelativePath: "telo.yaml", files: [] },
54
- entryRelativePath: "telo.yaml",
55
55
  env,
56
- ports: req.body?.ports ?? [],
57
56
  config: { image: appEntry.image, pullPolicy: appEntry.pullPolicy },
58
57
  selfContained: true,
59
58
  inspect: req.body?.inspect ?? false,
59
+ // An operator-predefined app session is one run of one application.
60
+ // Watch is a workspace shape, and this door carries no workspace.
61
+ mode: "run",
62
+ apps: [
63
+ {
64
+ name: DEFAULT_APP_NAME,
65
+ entryRelativePath: "",
66
+ ports: req.body?.ports ?? [],
67
+ io: "tty",
68
+ },
69
+ ],
60
70
  }, reply);
61
71
  });
62
72
  };
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/routes/apps.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAuBrF,MAAM,kBAAkB,GAAG;IACzB,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACzC;QACD,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KAC7B;CACO,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,IAAmB;IAC3C,OAAO,KAAK,EAAE,GAAoB,EAAE,EAAE;QACpC,GAAG,CAAC,IAAI,CACN,yBAAyB,EACzB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EACxC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;YACnB,kEAAkE;YAClE,wEAAwE;YACxE,6DAA6D;YAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC7C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,aAAa;oBACpB,OAAO,EACL,QAAQ,GAAG,CAAC,MAAM,CAAC,IAAI,iCAAiC;wBACxD,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;4BACjB,CAAC,CAAC,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;4BAC1C,CAAC,CAAC,yCAAyC,CAAC;wBAC9C,0BAA0B;iBAC7B,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO;YAElD,qEAAqE;YACrE,iEAAiE;YACjE,+CAA+C;YAC/C,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG;gBACV,GAAG,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CACpE;gBACD,GAAG,QAAQ,CAAC,GAAG;aAChB,CAAC;YAEF,OAAO,oBAAoB,CACzB,GAAG,EACH,IAAI,EACJ;gBACE,oEAAoE;gBACpE,sDAAsD;gBACtD,MAAM,EAAE,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;gBACrD,iBAAiB,EAAE,WAAW;gBAC9B,GAAG;gBACH,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC5B,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE;gBAClE,aAAa,EAAE,IAAI;gBACnB,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK;aACpC,EACD,KAAK,CACN,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/routes/apps.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/routes/io.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAkB,MAAM,SAAS,CAAC;AAKnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;CAC7B;AAkBD,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,kBAAkB,CAQ7D"}
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/routes/io.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAkB,MAAM,SAAS,CAAC;AAKnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;CAC7B;AAuBD,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,kBAAkB,CAQ7D"}