pinecall 0.2.0 → 0.3.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 (56) hide show
  1. package/README.md +12 -5
  2. package/dist/cli/chat.d.ts.map +1 -1
  3. package/dist/cli/chat.js +4 -2
  4. package/dist/cli/chat.js.map +1 -1
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +5 -2
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/knowledge.d.ts.map +1 -1
  9. package/dist/cli/knowledge.js +6 -3
  10. package/dist/cli/knowledge.js.map +1 -1
  11. package/dist/cli/line.d.ts.map +1 -1
  12. package/dist/cli/line.js +9 -6
  13. package/dist/cli/line.js.map +1 -1
  14. package/dist/cli/prompt.d.ts.map +1 -1
  15. package/dist/cli/prompt.js +2 -1
  16. package/dist/cli/prompt.js.map +1 -1
  17. package/dist/cli/run-console.d.ts +15 -0
  18. package/dist/cli/run-console.d.ts.map +1 -0
  19. package/dist/cli/run-console.js +49 -0
  20. package/dist/cli/run-console.js.map +1 -0
  21. package/dist/cli/run-screens.d.ts +1 -0
  22. package/dist/cli/run-screens.d.ts.map +1 -1
  23. package/dist/cli/run-screens.js +1 -1
  24. package/dist/cli/run-screens.js.map +1 -1
  25. package/dist/cli/run.d.ts +4 -5
  26. package/dist/cli/run.d.ts.map +1 -1
  27. package/dist/cli/run.js +73 -46
  28. package/dist/cli/run.js.map +1 -1
  29. package/dist/cli/serve/server.d.ts +35 -0
  30. package/dist/cli/serve/server.d.ts.map +1 -0
  31. package/dist/cli/serve/server.js +199 -0
  32. package/dist/cli/serve/server.js.map +1 -0
  33. package/dist/cli/serve/sidecar.d.ts +31 -0
  34. package/dist/cli/serve/sidecar.d.ts.map +1 -0
  35. package/dist/cli/serve/sidecar.js +74 -0
  36. package/dist/cli/serve/sidecar.js.map +1 -0
  37. package/dist/cli/serve.d.ts +14 -0
  38. package/dist/cli/serve.d.ts.map +1 -0
  39. package/dist/cli/serve.js +81 -0
  40. package/dist/cli/serve.js.map +1 -0
  41. package/dist/cli/testing/reproduction.d.ts +6 -1
  42. package/dist/cli/testing/reproduction.d.ts.map +1 -1
  43. package/dist/cli/testing/reproduction.js +11 -1
  44. package/dist/cli/testing/reproduction.js.map +1 -1
  45. package/dist/cli/ui/admin/assets/{index-DotmbMtQ.js → index-BpdIOuyO.js} +1 -1
  46. package/dist/cli/ui/admin/index.html +1 -1
  47. package/dist/cli/ui/console/assets/index-BUlGAwqn.css +1 -0
  48. package/dist/cli/ui/console/assets/index-D9StTnoH.js +102 -0
  49. package/dist/cli/ui/console/index.html +2 -2
  50. package/dist/client/client.d.ts +6 -0
  51. package/dist/client/client.d.ts.map +1 -1
  52. package/dist/client/client.js +20 -0
  53. package/dist/client/client.js.map +1 -1
  54. package/package.json +1 -1
  55. package/dist/cli/ui/console/assets/index-BVvP6fgr.js +0 -100
  56. package/dist/cli/ui/console/assets/index-DPF4-rtt.css +0 -1
package/dist/cli/run.js CHANGED
@@ -7,13 +7,12 @@ import { showMachine } from "./machine.js";
7
7
  import { theDoor } from "./env.js";
8
8
  import { callsFrom, describing, theLine } from "./line.js";
9
9
  import { connectedLine, doorsOf } from "./connected.js";
10
- import { cannotTell, ENV_FLAG, notThisWorld, standing } from "./world.js";
10
+ import { cannotTell, ENV_FLAG, notThisWorld, PRODUCTION, standing } from "./world.js";
11
11
  import { orgOf } from "./whoami.js";
12
12
  import { callingFrom } from "./profiles.js";
13
13
  import { agentFilesOfTheProject, instanceFor, load, mountOptions } from "./load.js";
14
14
  import { AGENT_FLAG, homesFor } from "./home.js";
15
15
  import { goldensOf } from "./testing/goldens.js";
16
- import { asked, Refused } from "./testing/gateway.js";
17
16
  import { chattingFrom, linesFromThisProcess } from "./ui/chatting.js";
18
17
  import { devHandler, ownVerbs } from "./ui/doors.js";
19
18
  import { driftingFrom } from "./ui/drifting.js";
@@ -24,19 +23,23 @@ import { reproducingFrom } from "./ui/reproducing.js";
24
23
  import { simulatingFrom, simulatingPiecesFor } from "./ui/simulating.js";
25
24
  import { testingFrom, testingPiecesFor } from "./ui/testing.js";
26
25
  import { live, plain, stream } from "./run-screens.js";
26
+ import { consoleLine, HOSTED, NOWHERE, whyNoConsole } from "./run-console.js";
27
+ import { NoSidecar, openOrReuse, theOneUp } from "./serve/sidecar.js";
27
28
  export const group = {
28
29
  purpose: "the app and its doors: the process you deploy",
29
- usage: `usage: pinecall run [agent.tsx] [--agent <name>] [--env production] [--ui] [--events] [--show-prompt]
30
+ usage: `usage: pinecall run [agent.tsx] [--agent <name>] [--env production] [--serve] [--ui] [--events] [--show-prompt]
30
31
 
31
32
  With nothing after it: the agent registered on the gateway, one line per log entry on stdout,
32
- no port bound and no page served: the gateway serves the console, and this prints its URL with a
33
- one-use code that signs the browser in. It answers that console for this directory.
33
+ no port bound and no page served. It answers the console for this directory — in the sandbox
34
+ that console is \`pinecall serve\`, on this machine; in production it is the gateway's own.
34
35
 
35
36
  At the root of a project of several agents — agents/<name>.tsx — every agent at once, on one
36
37
  socket, each line prefixed by its slug; --agent <name> (or its slug) runs one of them.
37
38
 
38
39
  --env <world> say which world you believe this key opens, and be refused if it opens the
39
40
  other. Nothing said is the sandbox; a deployment types --env production
41
+ --serve also serve the sandbox's console on http://localhost:4100, or point at the one
42
+ already up: \`pinecall run\` and \`pinecall serve\` in one terminal
40
43
  --show-prompt the prompt a fresh instance would produce, then exit. No key, no gateway
41
44
  --events one JSON line per log entry instead of the lines, for a pipe
42
45
  --ui the full-screen terminal view; keys: p pause · c clear · e events · s prompt · q quit`,
@@ -47,7 +50,8 @@ export const group = {
47
50
  *
48
51
  * This is the verb that goes under pm2 and into a container, and it is the same process in
49
52
  * the sandbox and in production: it runs the agent, binds no port and serves no page. What a
50
- * person looks at is `--ui` in this terminal, or the log over the gateway's API.
53
+ * person looks at is `--ui` in this terminal, or a console: the gateway's own for production, and
54
+ * `pinecall serve` on this machine for the sandbox — which `--serve` opens beside this process.
51
55
  * See docs/decisions/tenant-cli.md.
52
56
  */
53
57
  export async function run(argv) {
@@ -58,6 +62,7 @@ export async function run(argv) {
58
62
  "show-prompt": { type: "boolean", default: false },
59
63
  events: { type: "boolean", default: false },
60
64
  ui: { type: "boolean", default: false },
65
+ serve: { type: "boolean", default: false },
61
66
  ...AGENT_FLAG,
62
67
  ...ENV_FLAG,
63
68
  },
@@ -103,10 +108,60 @@ export async function run(argv) {
103
108
  process.stderr.write(`${elsewhere}\n`);
104
109
  return 2;
105
110
  }
111
+ // The sandbox's console is this machine's: opened here when asked, else the one already up is
112
+ // named, else the line says which verb opens it. Production's is the gateway's own page.
113
+ let sidecar;
114
+ let local;
115
+ if (who.env === PRODUCTION) {
116
+ if (values.serve === true) {
117
+ process.stderr.write(`--serve is the sandbox's console, and this key opens ${PRODUCTION}: production is watched at ${door.url}\n`);
118
+ return 2;
119
+ }
120
+ }
121
+ else if (values.serve === true) {
122
+ try {
123
+ sidecar = await openOrReuse(door, who);
124
+ local = sidecar.url;
125
+ }
126
+ catch (failed) {
127
+ if (!(failed instanceof NoSidecar))
128
+ throw failed;
129
+ process.stderr.write(`${failed.message}\n`);
130
+ return 2;
131
+ }
132
+ }
133
+ else {
134
+ local = await theOneUp(door, who);
135
+ }
106
136
  const url = door.url;
107
137
  // One socket for every agent of the project: the gateway takes several slugs on one app socket,
108
138
  // and every call is routed to the class it names.
109
139
  const pc = new Pinecall({ url, apiKey: door.apiKey });
140
+ // A gateway that restarts is a blip, not a crash: the client redials on its own, and what a
141
+ // person needs is one line saying so — not a stack per attempt. --events prints only its JSON.
142
+ let lost = false;
143
+ pc.onErrors((failed) => {
144
+ // Anything that is not the socket — a tool that threw where nobody waited, a frame that would
145
+ // not parse — is said whole, as it always was.
146
+ if (!aLostSocket(failed))
147
+ return console.error(failed);
148
+ if (!lost && values.events !== true && values.ui !== true)
149
+ process.stderr.write(`gateway ${failed.message} — reconnecting\n`);
150
+ lost = true;
151
+ });
152
+ // The gateway keeps whose phone is whose beside its live table and not in a row, because it is
153
+ // only meaningful next to a socket. So every connect says it again — the first and each
154
+ // reconnect, in every mode, for every agent and not only one that declares a number: a
155
+ // production number is the box's route and no class declares it, yet a developer's own phone
156
+ // dialling it reaches their copy (the runtime's rings-for door). A restarted gateway learns it
157
+ // here rather than sending the person's test call to production.
158
+ pc.onConnected(() => {
159
+ if (lost && values.events !== true && values.ui !== true)
160
+ process.stderr.write("gateway back\n");
161
+ lost = false;
162
+ if (who.env !== PRODUCTION)
163
+ void sayWhoCallsFromHere(door);
164
+ });
110
165
  // Whoever opens the app socket closes it. Left open it keeps this process alive after the
111
166
  // signal has been read — a plain `kill` on `pinecall run` did nothing until this landed —
112
167
  // and the gateway holds the slug until it shuts.
@@ -162,7 +217,7 @@ export async function run(argv) {
162
217
  env: who.env,
163
218
  source: door.source,
164
219
  }),
165
- after: () => onceUp(door, mounted.slug, rings(mounted.options.routes)),
220
+ after: () => onceUp(door, mounted.slug, rings(mounted.options.routes), who.env === PRODUCTION ? HOSTED : (local ?? NOWHERE)),
166
221
  }));
167
222
  return await plain(pc, agents, url);
168
223
  }
@@ -185,44 +240,25 @@ export async function run(argv) {
185
240
  for (const chatting of chattings)
186
241
  await chatting.close();
187
242
  pc.close();
243
+ await sidecar?.close();
188
244
  }
189
245
  }
190
- // What a gateway answers for a path no router of its declared.
191
- const NO_SUCH_DOOR = 404;
192
- // The console is the gateway's page at `/a/<agent>`, and it holds a key of its own — never this
193
- // process's. So this process mints a one-use code standing for its key (five minutes, once) and
194
- // prints the URL that carries it; the page spends it for a key of the tab's own. A gateway that
195
- // refuses the code is one line, and the app runs on.
196
- /** Where the console of this agent is, with the code that signs the browser in. */
197
- export function consoleUrl(gateway, slug, code) {
198
- return `${gateway.replace(/\/$/, "")}/a/${encodeURIComponent(slug)}?login=${encodeURIComponent(code)}`;
199
- }
200
- // A 404 at this door means the gateway has no such door, which means it is OLDER than this CLI —
201
- // a long-running dev gateway is the usual way to meet it, since nothing restarts one for you. A
202
- // status is not a thing a person can act on, so the sentence says the cause and the fix instead.
203
- const OLDER_GATEWAY = "this gateway has no login-code door, so it is older than this CLI. Restart it: it serves the console too, and that will be stale as well.";
204
- /** Why the console line has no URL in it, in words that name the next move. */
205
- export function whyNoConsole(refused) {
206
- if (refused instanceof Refused) {
207
- return refused.status === NO_SUCH_DOOR ? OLDER_GATEWAY : `the gateway answered ${refused.status}`;
208
- }
209
- return refused instanceof Error ? refused.message : String(refused);
210
- }
211
246
  // What is only true once the socket is up: the console's URL, and — when the agent answers at a
212
247
  // number — whose terminal that number rings in. Both are asked of the gateway, and neither is
213
248
  // worth failing the run over: a gateway that refuses says so on its own line and the app runs on.
214
- async function onceUp(door, slug, rings) {
215
- const said = [await consoleLine(door, slug)];
216
- if (rings) {
217
- // The gateway keeps whose phone is whose beside its live table and not in a row, because it
218
- // is only meaningful next to a socket. So every connect says it again: a restarted gateway,
219
- // or one this terminal has never told, learns it here rather than routing the person's own
220
- // test call into a colleague's terminal.
221
- await sayWhoCallsFromHere(door);
249
+ async function onceUp(door, slug, rings, where) {
250
+ const said = [await consoleLine(door, slug, where)];
251
+ if (rings)
222
252
  said.push(await lineLine(door, slug));
223
- }
224
253
  return said;
225
254
  }
255
+ // What `ws` and the network say when the gateway is not there: a refused or reset connection, a
256
+ // name that does not resolve, or a proxy in front of it answering for it while it restarts.
257
+ const LOST = /^(Unexpected server response|WebSocket|socket hang up|connect |getaddrinfo |read ECONN|write E)/;
258
+ /** Whether this failure is the gateway being away, which a reconnect answers, and not the app's own. */
259
+ export function aLostSocket(failed) {
260
+ return typeof failed.code === "string" || LOST.test(failed.message);
261
+ }
226
262
  /** Re-send the phone `pinecall line from` remembered for this gateway. Silent: it is upkeep. */
227
263
  async function sayWhoCallsFromHere(door) {
228
264
  const kept = callingFrom();
@@ -251,15 +287,6 @@ async function lineLine(door, slug) {
251
287
  return `line not available: ${whyNoConsole(refused)}`;
252
288
  }
253
289
  }
254
- async function consoleLine(door, slug) {
255
- try {
256
- const minted = await asked(door, "/v1/login/codes", { method: "POST", body: {} });
257
- return `console ${consoleUrl(door.url, slug, minted.code)} (opens within five minutes, once)`;
258
- }
259
- catch (refused) {
260
- return `console not available: ${whyNoConsole(refused)}`;
261
- }
262
- }
263
290
  function instanceOf(mounted, call) {
264
291
  return call === undefined ? undefined : mounted.instanceOf(call);
265
292
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /** The local server behind `pinecall serve`: the console's files and the gateway's doors, on the loopback. */
2
+ import type { Door } from "../testing/gateway.js";
3
+ /** The port a person remembers: `http://localhost:4100` is the sandbox's console on every laptop. */
4
+ export declare const DEFAULT_PORT = 4100;
5
+ /** Where a sidecar says what it is, so a `pinecall run` beside it can tell one from a stranger's port. */
6
+ export declare const ABOUT = "/.pinecall/serve";
7
+ /** What a sidecar answers at ABOUT: enough for another process to decide whether it is its own. */
8
+ export interface About {
9
+ pinecall: "serve";
10
+ gateway: string;
11
+ org: string;
12
+ env: string;
13
+ }
14
+ /**
15
+ * The sandbox's console for as long as this process lives. It serves the built console and forwards
16
+ * `/v1/*` to the gateway with the profile's key on the header. The key is a field of this object
17
+ * and is written into exactly one place: the authorization header of a request this process makes.
18
+ * The page holds none.
19
+ *
20
+ * The URL is stable on purpose, so nothing secret is in it. What keeps a stranger out is the two
21
+ * headers a browser cannot forge for a page: `Host` must be this loopback (a DNS name rebound to
22
+ * 127.0.0.1 arrives with its own), and `Origin`, when a browser sends one, must be this server's
23
+ * (a page elsewhere asking this port is cross-origin, and is refused before the key is spent).
24
+ */
25
+ export declare class LocalConsole {
26
+ #private;
27
+ private constructor();
28
+ /** Bind the loopback on that port and serve the console in `files` for this door. Rejects when the port is taken. */
29
+ static open(door: Door, files: string, about: Omit<About, "pinecall">, port?: number): Promise<LocalConsole>;
30
+ /** Where the console is, as a person types it. */
31
+ get url(): string;
32
+ /** Close every socket and the port. After this, nothing answers at `url`. */
33
+ close(): Promise<void>;
34
+ }
35
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cli/serve/server.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAQ9G,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAKlD,qGAAqG;AACrG,eAAO,MAAM,YAAY,OAAO,CAAC;AAEjC,0GAA0G;AAC1G,eAAO,MAAM,KAAK,qBAAqB,CAAC;AAgCxC,mGAAmG;AACnG,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAY;;IAOvB,OAAO,eAUN;IAED,qHAAqH;IACrH,OAAa,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,IAAI,GAAE,MAAqB,GAAG,OAAO,CAAC,YAAY,CAAC,CAI/H;IAED,kDAAkD;IAClD,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,6EAA6E;IACvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;CAyGF"}
@@ -0,0 +1,199 @@
1
+ /** The local server behind `pinecall serve`: the console's files and the gateway's doors, on the loopback. */
2
+ import { createReadStream, existsSync, readFileSync, statSync } from "node:fs";
3
+ import { createServer } from "node:http";
4
+ import { extname, join, normalize, resolve, sep } from "node:path";
5
+ import { Readable } from "node:stream";
6
+ // Loopback only: nothing on the network can reach this console.
7
+ const LOOPBACK = "127.0.0.1";
8
+ /** The port a person remembers: `http://localhost:4100` is the sandbox's console on every laptop. */
9
+ export const DEFAULT_PORT = 4100;
10
+ /** Where a sidecar says what it is, so a `pinecall run` beside it can tell one from a stranger's port. */
11
+ export const ABOUT = "/.pinecall/serve";
12
+ // The gateway's doors, as the console asks for them. Everything else is a file of the console, or
13
+ // the console's page for a screen it routes itself.
14
+ const DOORS = "/v1/";
15
+ // The widget is the gateway's file too, and the console's Widget screen loads it from its own
16
+ // origin. It needs no key, so none is sent.
17
+ const WIDGET = "/widget/";
18
+ const TYPES = {
19
+ ".html": "text/html; charset=utf-8",
20
+ ".js": "text/javascript; charset=utf-8",
21
+ ".css": "text/css; charset=utf-8",
22
+ ".json": "application/json",
23
+ ".map": "application/json",
24
+ ".svg": "image/svg+xml",
25
+ ".png": "image/png",
26
+ ".woff2": "font/woff2",
27
+ };
28
+ // The headers a browser's request carries that the gateway needs to see. Everything else — the
29
+ // cookies, the origin, the user agent — is the browser's business and stops here.
30
+ // `pinecall-corner` is an admin opening a colleague's copy: the gateway judges it, not this server.
31
+ const FORWARDED = ["content-type", "accept", "last-event-id", "range", "pinecall-corner"];
32
+ // What the page reads to know it is this one and not the gateway's: no login, no key, the sandbox.
33
+ // And where the gateway is, for the one thing the page says about it: the widget's tag a site
34
+ // pastes loads from there, never from this loopback.
35
+ const marks = (gateway) => `<meta name="pinecall-console" content="local"><meta name="pinecall-gateway" content="${gateway.replace(/"/g, "&quot;")}">`;
36
+ /**
37
+ * The sandbox's console for as long as this process lives. It serves the built console and forwards
38
+ * `/v1/*` to the gateway with the profile's key on the header. The key is a field of this object
39
+ * and is written into exactly one place: the authorization header of a request this process makes.
40
+ * The page holds none.
41
+ *
42
+ * The URL is stable on purpose, so nothing secret is in it. What keeps a stranger out is the two
43
+ * headers a browser cannot forge for a page: `Host` must be this loopback (a DNS name rebound to
44
+ * 127.0.0.1 arrives with its own), and `Origin`, when a browser sends one, must be this server's
45
+ * (a page elsewhere asking this port is cross-origin, and is refused before the key is spent).
46
+ */
47
+ export class LocalConsole {
48
+ #server;
49
+ #door;
50
+ #files;
51
+ #about;
52
+ #port = 0;
53
+ constructor(door, files, about) {
54
+ this.#door = door;
55
+ this.#about = about;
56
+ // Resolved, which is what strips a trailing separator: the directory arrives as a URL's path
57
+ // and so ends in one, and `#serve` compares against `#files + sep`. Left as it came, EVERY
58
+ // request fell through to the page — including the bundle, which the browser parsed as HTML.
59
+ this.#files = resolve(files);
60
+ this.#server = createServer((request, response) => {
61
+ void this.#answer(request, response);
62
+ });
63
+ }
64
+ /** Bind the loopback on that port and serve the console in `files` for this door. Rejects when the port is taken. */
65
+ static async open(door, files, about, port = DEFAULT_PORT) {
66
+ const served = new LocalConsole(door, files, { pinecall: "serve", ...about });
67
+ await served.#listen(port);
68
+ return served;
69
+ }
70
+ /** Where the console is, as a person types it. */
71
+ get url() {
72
+ return `http://localhost:${this.#port}`;
73
+ }
74
+ /** Close every socket and the port. After this, nothing answers at `url`. */
75
+ async close() {
76
+ this.#server.closeAllConnections();
77
+ await new Promise((closed) => this.#server.close(() => closed()));
78
+ }
79
+ async #listen(port) {
80
+ await new Promise((bound, failed) => {
81
+ this.#server.once("error", failed);
82
+ this.#server.listen(port, LOOPBACK, bound);
83
+ });
84
+ this.#port = this.#server.address().port;
85
+ }
86
+ async #answer(request, response) {
87
+ if (!this.#fromThisMachinesOwnPage(request)) {
88
+ response.writeHead(403, { "content-type": "text/plain; charset=utf-8" });
89
+ response.end("not from here\n");
90
+ return;
91
+ }
92
+ const asked = new URL(request.url ?? "/", this.url);
93
+ if (asked.pathname === ABOUT) {
94
+ json(response, 200, this.#about);
95
+ }
96
+ else if (asked.pathname.startsWith(DOORS)) {
97
+ await this.#forward(request, response, `${asked.pathname}${asked.search}`, true);
98
+ }
99
+ else if (asked.pathname.startsWith(WIDGET)) {
100
+ await this.#forward(request, response, `${asked.pathname}${asked.search}`, false);
101
+ }
102
+ else {
103
+ this.#serve(response, asked.pathname);
104
+ }
105
+ }
106
+ #fromThisMachinesOwnPage(request) {
107
+ const here = new Set([`localhost:${this.#port}`, `${LOOPBACK}:${this.#port}`]);
108
+ if (!here.has(request.headers.host ?? ""))
109
+ return false;
110
+ const origin = request.headers.origin;
111
+ return origin === undefined || here.has(origin.replace(/^http:\/\//, ""));
112
+ }
113
+ // The one place the key is spent. The response streams back as it arrives, which is what a log
114
+ // over SSE needs; a browser that navigates away aborts the request behind it.
115
+ async #forward(request, response, path, signed) {
116
+ const headers = signed ? { authorization: `Bearer ${this.#door.apiKey}` } : {};
117
+ for (const name of FORWARDED) {
118
+ const value = request.headers[name];
119
+ if (typeof value === "string")
120
+ headers[name] = value;
121
+ }
122
+ // The response closing before it finished is the browser going away — a tab closed, a screen
123
+ // left — and the door behind it is let go with it. (The request's own `close` is not that: it
124
+ // fires the moment its body has been read.)
125
+ const stopping = new AbortController();
126
+ response.once("close", () => {
127
+ if (!response.writableFinished)
128
+ stopping.abort();
129
+ });
130
+ // A body the console sends is one JSON object, read whole before the door is asked: the
131
+ // doors it writes to take a document, never a stream.
132
+ const method = request.method ?? "GET";
133
+ const body = method === "GET" || method === "HEAD" ? {} : { body: await whole(request) };
134
+ let answered;
135
+ try {
136
+ answered = await fetch(new URL(path, this.#door.url), { method, headers, signal: stopping.signal, ...body });
137
+ }
138
+ catch (failed) {
139
+ if (stopping.signal.aborted)
140
+ return;
141
+ response.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
142
+ response.end(`the gateway did not answer: ${failed instanceof Error ? failed.message : String(failed)}\n`);
143
+ return;
144
+ }
145
+ const relayed = {
146
+ "content-type": answered.headers.get("content-type") ?? "application/octet-stream",
147
+ "cache-control": "no-store",
148
+ };
149
+ // A recording is served in byte ranges so a player can seek; those headers are the range's own
150
+ // and travel back with it. `content-length` does not: fetch has already decoded the body, so
151
+ // the gateway's count of compressed bytes would cut the answer short.
152
+ for (const name of ["content-range", "accept-ranges"]) {
153
+ const value = answered.headers.get(name);
154
+ if (value !== null)
155
+ relayed[name] = value;
156
+ }
157
+ response.writeHead(answered.status, relayed);
158
+ if (answered.body === null) {
159
+ response.end();
160
+ return;
161
+ }
162
+ const relaying = Readable.fromWeb(answered.body);
163
+ // The browser leaving mid-stream aborts the fetch, and the abort surfaces here as the body's
164
+ // own error. It is the one way a stream is expected to end, not a failure of this process —
165
+ // unheard, it was an uncaught exception that took the whole console down (2026-09-09).
166
+ relaying.on("error", () => response.destroy());
167
+ relaying.pipe(response);
168
+ }
169
+ // A path that names a file of the console is that file; every other path is a screen the console
170
+ // routes itself, so it gets the page. Nothing above the console's directory is ever read.
171
+ #serve(response, path) {
172
+ const file = join(this.#files, normalize(path));
173
+ if (!file.startsWith(this.#files + sep) || !existsSync(file) || statSync(file).isDirectory()) {
174
+ response.writeHead(200, { "content-type": TYPES[".html"], "cache-control": "no-store" });
175
+ response.end(this.#page());
176
+ return;
177
+ }
178
+ response.writeHead(200, { "content-type": TYPES[extname(file)] ?? "application/octet-stream" });
179
+ createReadStream(file).pipe(response);
180
+ }
181
+ // Read on every request and not once: a console rebuilt while `serve` runs names new assets in a
182
+ // new page, and a person reloading should get it.
183
+ #page() {
184
+ return readFileSync(join(this.#files, "index.html"), "utf8").replace("<head>", `<head>${marks(this.#about.gateway)}`);
185
+ }
186
+ }
187
+ /** One JSON answer, whole. */
188
+ function json(response, status, body) {
189
+ response.writeHead(status, { "content-type": TYPES[".json"], "cache-control": "no-store" });
190
+ response.end(`${JSON.stringify(body)}\n`);
191
+ }
192
+ /** Every byte of a request's body, as one buffer. */
193
+ async function whole(request) {
194
+ const chunks = [];
195
+ for await (const chunk of request)
196
+ chunks.push(Buffer.from(chunk));
197
+ return Buffer.concat(chunks);
198
+ }
199
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/serve/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /** One sandbox console per machine: open it, or find the one already up and use that. */
2
+ import type { Door } from "../testing/gateway.js";
3
+ import { type Who } from "../whoami.js";
4
+ import { type About } from "./server.js";
5
+ export declare const NOT_BUILT = "the console is not built: run scripts/build once, then pinecall serve";
6
+ /** A sidecar in hand: where it is, whether this process opened it, and how to let go of it. */
7
+ export interface Sidecar {
8
+ url: string;
9
+ /** False when another `pinecall serve` was already up and this one is only pointing at it. */
10
+ ours: boolean;
11
+ close(): Promise<void>;
12
+ }
13
+ /** The port could not be had, or the console was never built: a sentence for the person, not a stack. */
14
+ export declare class NoSidecar extends Error {
15
+ readonly name = "NoSidecar";
16
+ }
17
+ /** Where the built console is, or undefined in a tree that never built one. */
18
+ export declare function consoleFiles(): string | undefined;
19
+ /** What is serving on that port, when it is a sidecar of ours; undefined for a stranger or nothing. */
20
+ export declare function aliveAt(port?: number): Promise<About | undefined>;
21
+ /** The sidecar already up on that port for this very gateway and org, as a URL; else undefined. */
22
+ export declare function theOneUp(door: Door, who: Who, port?: number): Promise<string | undefined>;
23
+ /**
24
+ * The console for this door: the sidecar already serving it, or a new one.
25
+ *
26
+ * A port in use is one of three things. A sidecar for this same gateway and org is THE console,
27
+ * and is used as it is — two projects on one laptop share one page. A sidecar for another gateway
28
+ * or org, or somebody else's program, is not ours to look through, so the next port is tried.
29
+ */
30
+ export declare function openOrReuse(door: Door, who: Who, port?: number): Promise<Sidecar>;
31
+ //# sourceMappingURL=sidecar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../../../src/cli/serve/sidecar.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAKzF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAS,KAAK,GAAG,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAqC,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAI5E,eAAO,MAAM,SAAS,0EAA0E,CAAC;AASjG,+FAA+F;AAC/F,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,8FAA8F;IAC9F,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,yGAAyG;AACzG,qBAAa,SAAU,SAAQ,KAAK;IAClC,SAAkB,IAAI,eAAe;CACtC;AAKD,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAKjD;AAED,uGAAuG;AACvG,wBAAsB,OAAO,CAAC,IAAI,GAAE,MAAqB,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAQrF;AAED,mGAAmG;AACnG,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,MAAqB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAG7G;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,MAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CAerG"}
@@ -0,0 +1,74 @@
1
+ /** One sandbox console per machine: open it, or find the one already up and use that. */
2
+ import { existsSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { orgOf } from "../whoami.js";
5
+ import { ABOUT, DEFAULT_PORT, LocalConsole } from "./server.js";
6
+ // A checkout runs everything else from its sources; the console is the one thing that has to be
7
+ // bundled first, because a browser reads no TypeScript. The sentence names the command.
8
+ export const NOT_BUILT = "the console is not built: run scripts/build once, then pinecall serve";
9
+ // How many ports past the first are tried when a stranger holds it. A person with five things on
10
+ // 4100–4104 has said something about their machine, and is told which flag answers it.
11
+ const TRIES = 5;
12
+ // A sidecar answers this at once or is not one: the probe must never hold `pinecall run` back.
13
+ const PROBE_MS = 400;
14
+ /** The port could not be had, or the console was never built: a sentence for the person, not a stack. */
15
+ export class NoSidecar extends Error {
16
+ name = "NoSidecar";
17
+ }
18
+ // The console is a browser program inside this package: vite writes its build to
19
+ // dist/cli/ui/console, which is what `files` publishes. From the compiled verb that is a sibling
20
+ // of this directory's parent; from the source under a loader it is the same path in dist.
21
+ /** Where the built console is, or undefined in a tree that never built one. */
22
+ export function consoleFiles() {
23
+ const compiled = fileURLToPath(new URL("../ui/console/", import.meta.url));
24
+ const source = fileURLToPath(new URL("../ui/console/main.tsx", import.meta.url));
25
+ const found = existsSync(source) ? fileURLToPath(new URL("../../../dist/cli/ui/console/", import.meta.url)) : compiled;
26
+ return existsSync(`${found}index.html`) ? found : undefined;
27
+ }
28
+ /** What is serving on that port, when it is a sidecar of ours; undefined for a stranger or nothing. */
29
+ export async function aliveAt(port = DEFAULT_PORT) {
30
+ try {
31
+ const answer = await fetch(`http://127.0.0.1:${port}${ABOUT}`, { signal: AbortSignal.timeout(PROBE_MS) });
32
+ const said = (await answer.json());
33
+ return answer.ok && said.pinecall === "serve" ? said : undefined;
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ }
39
+ /** The sidecar already up on that port for this very gateway and org, as a URL; else undefined. */
40
+ export async function theOneUp(door, who, port = DEFAULT_PORT) {
41
+ const alive = await aliveAt(port);
42
+ return alive !== undefined && sameAs(alive, door, who) ? `http://localhost:${port}` : undefined;
43
+ }
44
+ /**
45
+ * The console for this door: the sidecar already serving it, or a new one.
46
+ *
47
+ * A port in use is one of three things. A sidecar for this same gateway and org is THE console,
48
+ * and is used as it is — two projects on one laptop share one page. A sidecar for another gateway
49
+ * or org, or somebody else's program, is not ours to look through, so the next port is tried.
50
+ */
51
+ export async function openOrReuse(door, who, port = DEFAULT_PORT) {
52
+ const files = consoleFiles();
53
+ if (files === undefined)
54
+ throw new NoSidecar(NOT_BUILT);
55
+ const about = { gateway: door.url, org: orgOf(who), env: who.env };
56
+ for (let trying = port; trying < port + TRIES; trying += 1) {
57
+ try {
58
+ const opened = await LocalConsole.open(door, files, about, trying);
59
+ return { url: opened.url, ours: true, close: () => opened.close() };
60
+ }
61
+ catch (failed) {
62
+ if (failed.code !== "EADDRINUSE")
63
+ throw failed;
64
+ const up = await theOneUp(door, who, trying);
65
+ if (up !== undefined)
66
+ return { url: up, ours: false, close: async () => undefined };
67
+ }
68
+ }
69
+ throw new NoSidecar(`ports ${port}–${port + TRIES - 1} are all taken by something else: name a free one with --port`);
70
+ }
71
+ function sameAs(alive, door, who) {
72
+ return alive.gateway === door.url && alive.org === orgOf(who) && alive.env === who.env;
73
+ }
74
+ //# sourceMappingURL=sidecar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../../src/cli/serve/sidecar.ts"],"names":[],"mappings":"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"}