pinecall 0.3.1 → 0.4.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 (50) hide show
  1. package/dist/cli/config.d.ts.map +1 -1
  2. package/dist/cli/config.js +14 -6
  3. package/dist/cli/config.js.map +1 -1
  4. package/dist/cli/env.d.ts +18 -2
  5. package/dist/cli/env.d.ts.map +1 -1
  6. package/dist/cli/env.js +47 -8
  7. package/dist/cli/env.js.map +1 -1
  8. package/dist/cli/gateway.d.ts.map +1 -1
  9. package/dist/cli/gateway.js +9 -5
  10. package/dist/cli/gateway.js.map +1 -1
  11. package/dist/cli/index.d.ts.map +1 -1
  12. package/dist/cli/index.js +1 -4
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/cli/profiles.d.ts +33 -3
  15. package/dist/cli/profiles.d.ts.map +1 -1
  16. package/dist/cli/profiles.js +75 -9
  17. package/dist/cli/profiles.js.map +1 -1
  18. package/dist/cli/ui/console/assets/{index-DTMBzpRG.js → index-DhcpHPdk.js} +10 -10
  19. package/dist/cli/ui/console/assets/index-iylvEP0_.css +1 -0
  20. package/dist/cli/ui/console/index.html +2 -2
  21. package/dist/cli/ui/console/pinecall-logo.png +0 -0
  22. package/dist/cli/ui/console/pinecall-mark.png +0 -0
  23. package/dist/cli/world.d.ts.map +1 -1
  24. package/dist/cli/world.js +2 -1
  25. package/dist/cli/world.js.map +1 -1
  26. package/package.json +2 -2
  27. package/dist/cli/signup.d.ts +0 -25
  28. package/dist/cli/signup.d.ts.map +0 -1
  29. package/dist/cli/signup.js +0 -126
  30. package/dist/cli/signup.js.map +0 -1
  31. package/dist/cli/ui/admin/assets/index-BlHXSYVz.css +0 -1
  32. package/dist/cli/ui/admin/assets/index-BpdIOuyO.js +0 -58
  33. package/dist/cli/ui/admin/index.html +0 -20
  34. package/dist/cli/ui/browser.d.ts +0 -10
  35. package/dist/cli/ui/browser.d.ts.map +0 -1
  36. package/dist/cli/ui/browser.js +0 -30
  37. package/dist/cli/ui/browser.js.map +0 -1
  38. package/dist/cli/ui/console/assets/index-C7LdwphQ.css +0 -1
  39. package/dist/cli/ui/index.d.ts +0 -15
  40. package/dist/cli/ui/index.d.ts.map +0 -1
  41. package/dist/cli/ui/index.js +0 -117
  42. package/dist/cli/ui/index.js.map +0 -1
  43. package/dist/cli/ui/refused.d.ts +0 -8
  44. package/dist/cli/ui/refused.d.ts.map +0 -1
  45. package/dist/cli/ui/refused.js +0 -11
  46. package/dist/cli/ui/refused.js.map +0 -1
  47. package/dist/cli/ui/server.d.ts +0 -22
  48. package/dist/cli/ui/server.d.ts.map +0 -1
  49. package/dist/cli/ui/server.js +0 -211
  50. package/dist/cli/ui/server.js.map +0 -1
@@ -1,211 +0,0 @@
1
- /** The local server behind `pinecall ui`: the console's files and the gateway's doors, under one nonce on 127.0.0.1. */
2
- import { randomBytes } from "node:crypto";
3
- import { createReadStream, existsSync, readFileSync, statSync } from "node:fs";
4
- import { createServer } from "node:http";
5
- import { extname, join, normalize, resolve, sep } from "node:path";
6
- import { Readable } from "node:stream";
7
- import { Refusal, refusedAs } from "./refusal.js";
8
- // Loopback only, and the kernel picks the port: nothing on the network can reach this console,
9
- // and two `ui`s on one laptop do not fight over a number.
10
- const LOOPBACK = "127.0.0.1";
11
- // Everything answers under a random path — the console's files and, with them, the door to the
12
- // gateway that this process opens with the org key. A process on this machine that scans the
13
- // loopback finds a port; without the URL this process printed, it finds a 404 and nothing behind
14
- // it. The key itself never leaves this process: the browser sends requests, this server signs them.
15
- const NONCE_BYTES = 16;
16
- // The gateway's doors, as the console asks for them relative to its base. Everything else under
17
- // the nonce is a file of the console, or the console's page for a screen it routes itself.
18
- const DOORS = "v1/";
19
- // This process's OWN doors, beside the gateway's: what only the terminal that typed `ui` can do,
20
- // because it stands in the agent's directory. Which ones there are is ui/doors.ts, and this
21
- // server knows no more about them than their paths.
22
- const OWN = "ui/";
23
- const TYPES = {
24
- ".html": "text/html; charset=utf-8",
25
- ".js": "text/javascript; charset=utf-8",
26
- ".css": "text/css; charset=utf-8",
27
- ".json": "application/json",
28
- ".map": "application/json",
29
- ".svg": "image/svg+xml",
30
- ".woff2": "font/woff2",
31
- };
32
- // The headers a browser's request carries that the gateway needs to see. Everything else — the
33
- // cookies, the origin, the user agent — is the browser's business and stops here.
34
- const FORWARDED = ["content-type", "accept", "last-event-id", "range"];
35
- /**
36
- * The console's server for the life of one command. Under its nonce it serves the built console
37
- * and forwards `v1/*` to the gateway with the org key on the header; outside the nonce it answers
38
- * 404 and nothing else. The key is a field of this object and is written into exactly one place:
39
- * the authorization header of a request this process makes.
40
- */
41
- export class LocalConsole {
42
- #server;
43
- #nonce;
44
- #door;
45
- #files;
46
- #own;
47
- #url = "";
48
- constructor(door, files, own) {
49
- this.#door = door;
50
- this.#own = own;
51
- // Resolved, which is what strips a trailing separator: the directory arrives as a URL's path
52
- // and so ends in one, and `#serve` compares against `#files + sep`. Left as it came, that
53
- // comparison is `…/console//`, which no file under it starts with, and EVERY request fell
54
- // through to the page — including the bundle, which the browser then parsed as HTML.
55
- this.#files = resolve(files);
56
- this.#nonce = randomBytes(NONCE_BYTES).toString("hex");
57
- this.#server = createServer((request, response) => {
58
- void this.#answer(request, response);
59
- });
60
- }
61
- /** Bind the loopback on a free port and serve the console in `files` for this door. */
62
- static async open(door, files, own = []) {
63
- const served = new LocalConsole(door, files, own);
64
- await served.#listen();
65
- return served;
66
- }
67
- /** Where the console is: the loopback, the port, the nonce. The one URL that answers anything. */
68
- get url() {
69
- return this.#url;
70
- }
71
- /** Where one screen of the console is, by the path the console routes. */
72
- at(path) {
73
- return `${this.#url}${path.replace(/^\//, "")}`;
74
- }
75
- /** Close every socket and the port. After this, nothing answers at `url`. */
76
- async close() {
77
- this.#server.closeAllConnections();
78
- await new Promise((closed) => this.#server.close(() => closed()));
79
- }
80
- async #listen() {
81
- await new Promise((bound, failed) => {
82
- this.#server.once("error", failed);
83
- this.#server.listen(0, LOOPBACK, bound);
84
- });
85
- const { port } = this.#server.address();
86
- this.#url = `http://${LOOPBACK}:${port}/${this.#nonce}/`;
87
- }
88
- async #answer(request, response) {
89
- const asked = new URL(request.url ?? "/", this.#url);
90
- const under = `/${this.#nonce}/`;
91
- if (!asked.pathname.startsWith(under)) {
92
- response.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
93
- response.end("not here\n");
94
- return;
95
- }
96
- const path = asked.pathname.slice(under.length);
97
- if (path.startsWith(DOORS)) {
98
- await this.#forward(request, response, `/${path}${asked.search}`);
99
- }
100
- else if (path.startsWith(OWN)) {
101
- await this.#answerOwn(request, response, path);
102
- }
103
- else {
104
- this.#serve(response, path);
105
- }
106
- }
107
- // The doors this process answers itself, read off the table it was opened with. A refusal
108
- // travels as FastAPI's would — a status and a `detail` sentence — so the page reads both kinds
109
- // of door the same way.
110
- async #answerOwn(request, response, path) {
111
- const method = request.method ?? "GET";
112
- const door = this.#own.find((one) => `${OWN}${one.path}` === path);
113
- const answer = method === "GET" ? door?.get : method === "POST" ? door?.post : undefined;
114
- try {
115
- if (answer === undefined)
116
- throw new Refusal(404, `nothing at ${path}`);
117
- json(response, 200, await answer(JSON.parse((await whole(request)).toString() || "{}")));
118
- }
119
- catch (refused) {
120
- const said = refusedAs(refused);
121
- json(response, said.status, { detail: said.detail });
122
- }
123
- }
124
- // The one place the key is spent. The response streams back as it arrives, which is what a log
125
- // over SSE needs; a browser that navigates away aborts the request behind it.
126
- async #forward(request, response, path) {
127
- const headers = { authorization: `Bearer ${this.#door.apiKey}` };
128
- for (const name of FORWARDED) {
129
- const value = request.headers[name];
130
- if (typeof value === "string")
131
- headers[name] = value;
132
- }
133
- // The response closing before it finished is the browser going away — a tab closed, a screen
134
- // left — and the door behind it is let go with it. (The request's own `close` is not that: it
135
- // fires the moment its body has been read.)
136
- const stopping = new AbortController();
137
- response.once("close", () => {
138
- if (!response.writableFinished)
139
- stopping.abort();
140
- });
141
- // A body the console sends is one JSON object, read whole before the door is asked: the
142
- // doors it writes to take a document, never a stream.
143
- const method = request.method ?? "GET";
144
- const body = method === "GET" || method === "HEAD" ? {} : { body: await whole(request) };
145
- let answered;
146
- try {
147
- answered = await fetch(new URL(path, this.#door.url), { method, headers, signal: stopping.signal, ...body });
148
- }
149
- catch (failed) {
150
- if (stopping.signal.aborted)
151
- return;
152
- response.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
153
- response.end(`the gateway did not answer: ${failed instanceof Error ? failed.message : String(failed)}\n`);
154
- return;
155
- }
156
- const relayed = {
157
- "content-type": answered.headers.get("content-type") ?? "application/octet-stream",
158
- "cache-control": "no-store",
159
- };
160
- // A recording is served in byte ranges so a player can seek; those three headers are the
161
- // range's own and travel back with it.
162
- for (const name of ["content-range", "accept-ranges", "content-length"]) {
163
- const value = answered.headers.get(name);
164
- if (value !== null)
165
- relayed[name] = value;
166
- }
167
- response.writeHead(answered.status, relayed);
168
- if (answered.body === null) {
169
- response.end();
170
- return;
171
- }
172
- const relaying = Readable.fromWeb(answered.body);
173
- // The browser leaving mid-stream aborts the fetch, and the abort surfaces here as the body's
174
- // own error. It is the one way a stream is expected to end, not a failure of this process —
175
- // unheard, it was an uncaught exception that took the whole console down (2026-09-09).
176
- relaying.on("error", () => response.destroy());
177
- relaying.pipe(response);
178
- }
179
- // A path that names a file of the console is that file; every other path is a screen the console
180
- // routes itself, so it gets the page. Nothing above the console's directory is ever read.
181
- #serve(response, path) {
182
- const file = join(this.#files, normalize(`/${path}`));
183
- if (!file.startsWith(this.#files + sep) || !existsSync(file) || statSync(file).isDirectory()) {
184
- response.writeHead(200, { "content-type": TYPES[".html"], "cache-control": "no-store" });
185
- response.end(this.#page());
186
- return;
187
- }
188
- response.writeHead(200, { "content-type": TYPES[extname(file)] ?? "application/octet-stream" });
189
- createReadStream(file).pipe(response);
190
- }
191
- // Read on every request and not once: a console rebuilt while `ui` runs names new assets in a
192
- // new page, and a person reloading should get it. The page is served for every screen the
193
- // console routes itself, at any depth, so its assets are addressed from the base and not from
194
- // wherever the address bar happens to stand.
195
- #page() {
196
- return readFileSync(join(this.#files, "index.html"), "utf8").replace("<head>", `<head><base href="/${this.#nonce}/">`);
197
- }
198
- }
199
- /** One JSON answer, whole. */
200
- function json(response, status, body) {
201
- response.writeHead(status, { "content-type": TYPES[".json"], "cache-control": "no-store" });
202
- response.end(`${JSON.stringify(body)}\n`);
203
- }
204
- /** Every byte of a request's body, as one buffer. */
205
- async function whole(request) {
206
- const chunks = [];
207
- for await (const chunk of request)
208
- chunks.push(Buffer.from(chunk));
209
- return Buffer.concat(chunks);
210
- }
211
- //# sourceMappingURL=server.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/ui/server.ts"],"names":[],"mappings":"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"}