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.
- package/README.md +12 -5
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +4 -2
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/knowledge.d.ts.map +1 -1
- package/dist/cli/knowledge.js +6 -3
- package/dist/cli/knowledge.js.map +1 -1
- package/dist/cli/line.d.ts.map +1 -1
- package/dist/cli/line.js +9 -6
- package/dist/cli/line.js.map +1 -1
- package/dist/cli/prompt.d.ts.map +1 -1
- package/dist/cli/prompt.js +2 -1
- package/dist/cli/prompt.js.map +1 -1
- package/dist/cli/run-console.d.ts +15 -0
- package/dist/cli/run-console.d.ts.map +1 -0
- package/dist/cli/run-console.js +49 -0
- package/dist/cli/run-console.js.map +1 -0
- package/dist/cli/run-screens.d.ts +1 -0
- package/dist/cli/run-screens.d.ts.map +1 -1
- package/dist/cli/run-screens.js +1 -1
- package/dist/cli/run-screens.js.map +1 -1
- package/dist/cli/run.d.ts +4 -5
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +73 -46
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/serve/server.d.ts +35 -0
- package/dist/cli/serve/server.d.ts.map +1 -0
- package/dist/cli/serve/server.js +199 -0
- package/dist/cli/serve/server.js.map +1 -0
- package/dist/cli/serve/sidecar.d.ts +31 -0
- package/dist/cli/serve/sidecar.d.ts.map +1 -0
- package/dist/cli/serve/sidecar.js +74 -0
- package/dist/cli/serve/sidecar.js.map +1 -0
- package/dist/cli/serve.d.ts +14 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +81 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/testing/reproduction.d.ts +6 -1
- package/dist/cli/testing/reproduction.d.ts.map +1 -1
- package/dist/cli/testing/reproduction.js +11 -1
- package/dist/cli/testing/reproduction.js.map +1 -1
- package/dist/cli/ui/admin/assets/{index-DotmbMtQ.js → index-BpdIOuyO.js} +1 -1
- package/dist/cli/ui/admin/index.html +1 -1
- package/dist/cli/ui/console/assets/index-BUlGAwqn.css +1 -0
- package/dist/cli/ui/console/assets/index-D9StTnoH.js +102 -0
- package/dist/cli/ui/console/index.html +2 -2
- package/dist/client/client.d.ts +6 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +20 -0
- package/dist/client/client.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/ui/console/assets/index-BVvP6fgr.js +0 -100
- 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
|
|
33
|
-
|
|
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
|
|
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
|
}
|
package/dist/cli/run.js.map
CHANGED
|
@@ -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, """)}">`;
|
|
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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"}
|