@parlor/agent-host 0.3.0 → 0.3.1
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/dist/agent-options.d.ts +5 -0
- package/dist/agent-options.d.ts.map +1 -1
- package/dist/agent-options.js +32 -0
- package/dist/agent-options.js.map +1 -1
- package/dist/agent-survey.d.ts +15 -0
- package/dist/agent-survey.d.ts.map +1 -0
- package/dist/agent-survey.js +51 -0
- package/dist/agent-survey.js.map +1 -0
- package/dist/codex-app-server.d.ts +7 -0
- package/dist/codex-app-server.d.ts.map +1 -0
- package/dist/codex-app-server.js +46 -0
- package/dist/codex-app-server.js.map +1 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +79 -13
- package/dist/daemon.js.map +1 -1
- package/dist/learned.d.ts +2 -0
- package/dist/learned.d.ts.map +1 -1
- package/dist/learned.js +1 -0
- package/dist/learned.js.map +1 -1
- package/dist/link.d.ts +3 -1
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +23 -1
- package/dist/link.js.map +1 -1
- package/dist/mcp-proxy.d.ts.map +1 -1
- package/dist/mcp-proxy.js +108 -16
- package/dist/mcp-proxy.js.map +1 -1
- package/dist/spec-kit.d.ts +2 -0
- package/dist/spec-kit.d.ts.map +1 -1
- package/dist/spec-kit.js +6 -1
- package/dist/spec-kit.js.map +1 -1
- package/package.json +9 -9
package/dist/mcp-proxy.js
CHANGED
|
@@ -30,12 +30,63 @@ function parse(text) {
|
|
|
30
30
|
}
|
|
31
31
|
const result = (id, value) => JSON.stringify({ jsonrpc: "2.0", id, result: value });
|
|
32
32
|
const failure = (id, code, message) => JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } });
|
|
33
|
+
/**
|
|
34
|
+
* What a new session asks before its first prompt, answered by the app the same way each
|
|
35
|
+
* time for the same parameters. A session gets the last answer at once while the app is
|
|
36
|
+
* asked again behind it; a list that changed is announced to the agent.
|
|
37
|
+
*/
|
|
38
|
+
const HANDSHAKE = new Set([
|
|
39
|
+
"server/discover",
|
|
40
|
+
"initialize",
|
|
41
|
+
"tools/list",
|
|
42
|
+
"resources/list",
|
|
43
|
+
"resources/templates/list",
|
|
44
|
+
"prompts/list",
|
|
45
|
+
]);
|
|
46
|
+
const LIST_CHANGED = {
|
|
47
|
+
"tools/list": "notifications/tools/list_changed",
|
|
48
|
+
"resources/list": "notifications/resources/list_changed",
|
|
49
|
+
"prompts/list": "notifications/prompts/list_changed",
|
|
50
|
+
};
|
|
51
|
+
/** Statuses the same request gets again: never a credential, rate or server failure. */
|
|
52
|
+
const STABLE_REFUSALS = new Set([400, 404, 405]);
|
|
53
|
+
const handshakeKey = (message) => typeof message.method === "string" && HANDSHAKE.has(message.method)
|
|
54
|
+
? `${message.method} ${JSON.stringify(message.params ?? null)}`
|
|
55
|
+
: undefined;
|
|
56
|
+
function knownAnswer(answer) {
|
|
57
|
+
if (answer === undefined)
|
|
58
|
+
return undefined;
|
|
59
|
+
if (answer.result !== undefined)
|
|
60
|
+
return { result: answer.result };
|
|
61
|
+
const { error } = answer;
|
|
62
|
+
return error === undefined ? undefined : { error };
|
|
63
|
+
}
|
|
64
|
+
/** What the session learns from an `initialize` or `tools/list` answer, wherever it came from. */
|
|
65
|
+
function learn(live, method, answer) {
|
|
66
|
+
if (!("result" in answer))
|
|
67
|
+
return;
|
|
68
|
+
if (method === "initialize") {
|
|
69
|
+
live.initialized = answer.result;
|
|
70
|
+
const version = answer.result
|
|
71
|
+
?.protocolVersion;
|
|
72
|
+
if (typeof version === "string")
|
|
73
|
+
live.protocolVersion = version;
|
|
74
|
+
}
|
|
75
|
+
if (method === "tools/list")
|
|
76
|
+
live.tools = answer.result;
|
|
77
|
+
}
|
|
33
78
|
/** One line per message on the agent's stdio: only a body with a raw newline is compacted. */
|
|
34
79
|
const asLine = (text) => text.includes("\n") ? JSON.stringify(JSON.parse(text)) : text;
|
|
35
80
|
function betweenTurns(live, message) {
|
|
36
81
|
if (message.id === undefined || typeof message.method !== "string")
|
|
37
82
|
return undefined;
|
|
38
83
|
const { id } = message;
|
|
84
|
+
const key = handshakeKey(message);
|
|
85
|
+
const known = key === undefined ? undefined : live.known?.get(key);
|
|
86
|
+
if (known) {
|
|
87
|
+
learn(live, message.method, known);
|
|
88
|
+
return JSON.stringify({ jsonrpc: "2.0", id, ...known });
|
|
89
|
+
}
|
|
39
90
|
switch (message.method) {
|
|
40
91
|
case "ping":
|
|
41
92
|
return result(id, {});
|
|
@@ -85,11 +136,13 @@ function refusal(status) {
|
|
|
85
136
|
? "This computer can no longer act for the app: the turn ended or the computer was disconnected."
|
|
86
137
|
: `The app answered HTTP ${status}.`;
|
|
87
138
|
}
|
|
139
|
+
/** Sends one message to the app; resolves with its status and what the request was answered. */
|
|
88
140
|
async function forward(live, token, line, message, reply) {
|
|
89
141
|
const method = typeof message.method === "string" ? message.method : "response";
|
|
90
142
|
const controller = new AbortController();
|
|
91
143
|
live.inflight.add(controller);
|
|
92
144
|
let status = 0;
|
|
145
|
+
let given;
|
|
93
146
|
try {
|
|
94
147
|
const response = await fetch(`${live.appOrigin}/_parlor/mcp`, {
|
|
95
148
|
method: "POST",
|
|
@@ -121,23 +174,21 @@ async function forward(live, token, line, message, reply) {
|
|
|
121
174
|
continue;
|
|
122
175
|
if (answer.id === message.id) {
|
|
123
176
|
answered = true;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (typeof version === "string")
|
|
129
|
-
live.protocolVersion = version;
|
|
130
|
-
}
|
|
131
|
-
if (method === "tools/list" && answer.result !== undefined)
|
|
132
|
-
live.tools = answer.result;
|
|
177
|
+
given = answer;
|
|
178
|
+
const known = knownAnswer(answer);
|
|
179
|
+
if (known)
|
|
180
|
+
learn(live, method, known);
|
|
133
181
|
}
|
|
134
182
|
reply(asLine(text));
|
|
135
183
|
}
|
|
136
184
|
if (message.id !== undefined && !answered) {
|
|
137
|
-
|
|
185
|
+
const refused = failure(message.id, REFUSED_CODE, refusal(status));
|
|
186
|
+
given = parse(refused);
|
|
187
|
+
reply(refused);
|
|
138
188
|
}
|
|
139
189
|
}
|
|
140
190
|
catch (error) {
|
|
191
|
+
status = 0;
|
|
141
192
|
if (message.id !== undefined) {
|
|
142
193
|
reply(controller.signal.aborted
|
|
143
194
|
? failure(message.id, NO_TURN_CODE, NO_TURN_MESSAGE)
|
|
@@ -148,6 +199,34 @@ async function forward(live, token, line, message, reply) {
|
|
|
148
199
|
live.inflight.delete(controller);
|
|
149
200
|
logEvent("proxy_forward", { appOrigin: live.appOrigin, rpcMethod: method, status });
|
|
150
201
|
}
|
|
202
|
+
return { status, answer: given };
|
|
203
|
+
}
|
|
204
|
+
/** Keeps the app's answer to a handshake request when the same request gets it again. */
|
|
205
|
+
function remember(live, key, outcome) {
|
|
206
|
+
const { status } = outcome;
|
|
207
|
+
const stable = (status >= 200 && status < 300) || STABLE_REFUSALS.has(status);
|
|
208
|
+
const known = stable ? knownAnswer(outcome.answer) : undefined;
|
|
209
|
+
// A refused initialize would leave every later session without the app's tools.
|
|
210
|
+
if (!known || (key.startsWith("initialize ") && !("result" in known)))
|
|
211
|
+
return undefined;
|
|
212
|
+
live.known?.set(key, known);
|
|
213
|
+
return known;
|
|
214
|
+
}
|
|
215
|
+
/** Answers a handshake request from what the app said last, then asks the app again. */
|
|
216
|
+
function replay(live, token, line, message, key, known, reply) {
|
|
217
|
+
const method = message.method;
|
|
218
|
+
learn(live, method, known);
|
|
219
|
+
reply(JSON.stringify({ jsonrpc: "2.0", id: message.id, ...known }));
|
|
220
|
+
void forward(live, token, line, message, () => undefined).then((outcome) => {
|
|
221
|
+
const fresh = remember(live, key, outcome);
|
|
222
|
+
const changed = LIST_CHANGED[method];
|
|
223
|
+
if (!changed || !fresh || JSON.stringify(fresh) === JSON.stringify(known))
|
|
224
|
+
return;
|
|
225
|
+
const notice = JSON.stringify({ jsonrpc: "2.0", method: changed });
|
|
226
|
+
for (const socket of live.sockets)
|
|
227
|
+
if (!socket.destroyed)
|
|
228
|
+
socket.write(`${notice}\n`);
|
|
229
|
+
});
|
|
151
230
|
}
|
|
152
231
|
function handle(live, line, reply) {
|
|
153
232
|
const message = parse(line);
|
|
@@ -160,13 +239,17 @@ function handle(live, line, reply) {
|
|
|
160
239
|
reply(answer);
|
|
161
240
|
return;
|
|
162
241
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
message
|
|
166
|
-
|
|
242
|
+
const key = message.id === undefined ? undefined : handshakeKey(message);
|
|
243
|
+
if (key === undefined) {
|
|
244
|
+
void forward(live, token, line, message, reply);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const known = live.known?.get(key);
|
|
248
|
+
if (known) {
|
|
249
|
+
replay(live, token, line, message, key, known, reply);
|
|
167
250
|
return;
|
|
168
251
|
}
|
|
169
|
-
void forward(live, token, line, message, reply);
|
|
252
|
+
void forward(live, token, line, message, reply).then((outcome) => remember(live, key, outcome));
|
|
170
253
|
}
|
|
171
254
|
/**
|
|
172
255
|
* One agent outside a turn, on one socket. Reads run as asked; the first change in the
|
|
@@ -175,6 +258,7 @@ function handle(live, line, reply) {
|
|
|
175
258
|
function outsideSession(app, socket, reply) {
|
|
176
259
|
const live = {
|
|
177
260
|
appOrigin: app.appOrigin.replace(/\/+$/, ""),
|
|
261
|
+
known: undefined,
|
|
178
262
|
token: undefined,
|
|
179
263
|
protocolVersion: undefined,
|
|
180
264
|
initialized: undefined,
|
|
@@ -296,6 +380,7 @@ function withGuidance(line, app, agent) {
|
|
|
296
380
|
}
|
|
297
381
|
export function createMcpProxy(hostBinary) {
|
|
298
382
|
const sessions = new Map();
|
|
383
|
+
const handshakes = new Map();
|
|
299
384
|
let server;
|
|
300
385
|
let socketPath;
|
|
301
386
|
let outside = () => undefined;
|
|
@@ -356,8 +441,15 @@ export function createMcpProxy(hostBinary) {
|
|
|
356
441
|
if (socketPath === undefined)
|
|
357
442
|
throw new Error("The MCP proxy is not listening yet.");
|
|
358
443
|
const nonce = randomBytes(24).toString("base64url");
|
|
444
|
+
const origin = appOrigin.replace(/\/+$/, "");
|
|
445
|
+
let known = handshakes.get(origin);
|
|
446
|
+
if (!known) {
|
|
447
|
+
known = new Map();
|
|
448
|
+
handshakes.set(origin, known);
|
|
449
|
+
}
|
|
359
450
|
const live = {
|
|
360
|
-
appOrigin:
|
|
451
|
+
appOrigin: origin,
|
|
452
|
+
known,
|
|
361
453
|
token: undefined,
|
|
362
454
|
protocolVersion: undefined,
|
|
363
455
|
initialized: undefined,
|
package/dist/mcp-proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-proxy.js","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { once } from \"node:events\";\nimport { chmod, mkdir, rm } from \"node:fs/promises\";\nimport { connect, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname } from \"node:path\";\n\nimport type { Delegation } from \"@parlor/server\";\n\nimport type { StdioMcpServer } from \"./acp.js\";\nimport { onLines } from \"./lines.js\";\nimport { logEvent } from \"./log.js\";\n\n/**\n * The agent's MCP server for an app is this host: a stdio server (`parlor-host\n * mcp-proxy`) that connects back to the daemon's 0600 socket and names its session by a\n * nonce. The daemon forwards each message to `<app>/_parlor/mcp` with the current turn's\n * token, so no app credential is ever in the agent's config, logs or environment.\n */\nexport interface McpProxy {\n listen(socketPath: string): Promise<void>;\n open(appServer: string, appOrigin: string): ProxySession;\n /**\n * Serves `parlor-host mcp-proxy --app <origin>`: a coding agent on this computer outside\n * any turn, such as Claude Code in a terminal. `undefined` refuses the app.\n */\n serveOutside(resolve: (appOrigin: string) => OutsideApp | undefined): void;\n stopListening(): Promise<void>;\n close(): Promise<void>;\n}\n\nexport interface ProxySession {\n readonly nonce: string;\n /** The entry for `session/new`. */\n readonly server: StdioMcpServer;\n /** Forward with this token until `end`; a `tools/call` outside a turn gets NO_TURN_MESSAGE. */\n begin(token: Delegation): void;\n renew(token: Delegation): void;\n end(): void;\n dispose(): void;\n}\n\n/** An app a coding agent on this computer may use outside its sidebar. */\nexport interface OutsideApp {\n readonly appOrigin: string;\n readonly appName: string;\n /** The name the user asks the agent with, its MCP server name. */\n readonly name: string;\n /** Whose account the agent acts as: its email, or its name. */\n readonly account: string;\n /** A token for `agent`'s calls, fresh enough to use now. */\n token(agent: string): Promise<string>;\n /** Asks on this computer, for an agent that cannot ask the user itself. */\n askHere(question: string): Promise<boolean>;\n}\n\nexport const NO_TURN_MESSAGE =\n \"No turn is active: the user has not asked anything right now. Wait for their next message.\";\n\nexport const DISCONNECTED_MESSAGE =\n \"This computer no longer serves the app: it was disconnected, or Parlor Host stopped.\";\n\nconst OUTSIDE_PREFIX = \"app \";\nconst AGENT_NAMES: Readonly<Record<string, string>> = {\n \"claude-code\": \"Claude Code\",\n \"codex-mcp-client\": \"Codex\",\n codex: \"Codex\",\n};\n\nconst SOCKET_ENV = \"PARLOR_HOST_PROXY_SOCKET\";\nconst NONCE_ENV = \"PARLOR_HOST_PROXY_NONCE\";\nconst NO_TURN_CODE = -32000;\nconst REFUSED_CODE = -32001;\n\ntype JsonRpcId = string | number | null;\n\ninterface Message {\n readonly jsonrpc?: unknown;\n readonly id?: JsonRpcId;\n readonly method?: unknown;\n readonly result?: unknown;\n}\n\ninterface Live {\n readonly appOrigin: string;\n token: string | undefined;\n protocolVersion: string | undefined;\n initialized: unknown;\n tools: unknown;\n readonly inflight: Set<AbortController>;\n readonly sockets: Set<Socket>;\n}\n\nfunction parse(text: string): Message | undefined {\n try {\n const value: unknown = JSON.parse(text);\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Message)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst result = (id: JsonRpcId, value: unknown) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, result: value });\n\nconst failure = (id: JsonRpcId, code: number, message: string) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, error: { code, message } });\n\n/** One line per message on the agent's stdio: only a body with a raw newline is compacted. */\nconst asLine = (text: string) =>\n text.includes(\"\\n\") ? JSON.stringify(JSON.parse(text)) : text;\n\nfunction betweenTurns(live: Live, message: Message): string | undefined {\n if (message.id === undefined || typeof message.method !== \"string\") return undefined;\n const { id } = message;\n switch (message.method) {\n case \"ping\":\n return result(id, {});\n case \"initialize\":\n return live.initialized === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.initialized);\n case \"tools/list\":\n return live.tools === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.tools);\n case \"tools/call\":\n return result(id, {\n content: [{ type: \"text\", text: NO_TURN_MESSAGE }],\n isError: true,\n });\n default:\n return failure(id, NO_TURN_CODE, NO_TURN_MESSAGE);\n }\n}\n\nasync function* serverSentData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let data: string[] = [];\n for await (const chunk of body) {\n buffer += decoder.decode(chunk, { stream: true });\n let end = buffer.indexOf(\"\\n\");\n while (end !== -1) {\n const line = buffer.slice(0, end).replace(/\\r$/, \"\");\n buffer = buffer.slice(end + 1);\n if (line === \"\") {\n if (data.length > 0) yield data.join(\"\\n\");\n data = [];\n } else if (line.startsWith(\"data:\")) {\n data.push(line.slice(line.startsWith(\"data: \") ? 6 : 5));\n }\n end = buffer.indexOf(\"\\n\");\n }\n }\n if (data.length > 0) yield data.join(\"\\n\");\n}\n\nfunction refusal(status: number): string {\n return status === 401\n ? \"This computer can no longer act for the app: the turn ended or the computer was disconnected.\"\n : `The app answered HTTP ${status}.`;\n}\n\nasync function forward(\n live: Live,\n token: string,\n line: string,\n message: Message,\n reply: (line: string) => void,\n): Promise<void> {\n const method = typeof message.method === \"string\" ? message.method : \"response\";\n const controller = new AbortController();\n live.inflight.add(controller);\n let status = 0;\n try {\n const response = await fetch(`${live.appOrigin}/_parlor/mcp`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${token}`,\n accept: \"application/json, text/event-stream\",\n \"content-type\": \"application/json\",\n ...(live.protocolVersion ? { \"mcp-protocol-version\": live.protocolVersion } : {}),\n },\n body: line,\n signal: controller.signal,\n });\n status = response.status;\n const bodies: string[] = [];\n if ((response.headers.get(\"content-type\") ?? \"\").includes(\"text/event-stream\")) {\n if (response.body)\n for await (const data of serverSentData(response.body)) bodies.push(data);\n } else {\n const text = await response.text();\n if (text.trim() !== \"\") bodies.push(text);\n }\n let answered = false;\n for (const text of bodies) {\n const answer = parse(text);\n if (answer?.jsonrpc !== \"2.0\") continue;\n if (answer.id === message.id) {\n answered = true;\n if (method === \"initialize\" && answer.result !== undefined) {\n live.initialized = answer.result;\n const version = (answer.result as { readonly protocolVersion?: unknown })\n .protocolVersion;\n if (typeof version === \"string\") live.protocolVersion = version;\n }\n if (method === \"tools/list\" && answer.result !== undefined)\n live.tools = answer.result;\n }\n reply(asLine(text));\n }\n if (message.id !== undefined && !answered) {\n reply(failure(message.id, REFUSED_CODE, refusal(status)));\n }\n } catch (error) {\n if (message.id !== undefined) {\n reply(\n controller.signal.aborted\n ? failure(message.id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : failure(\n message.id,\n REFUSED_CODE,\n `The app could not be reached: ${String(error)}`,\n ),\n );\n }\n } finally {\n live.inflight.delete(controller);\n logEvent(\"proxy_forward\", { appOrigin: live.appOrigin, rpcMethod: method, status });\n }\n}\n\nfunction handle(live: Live, line: string, reply: (line: string) => void): void {\n const message = parse(line);\n if (!message) return;\n const token = live.token;\n if (token === undefined) {\n const answer = betweenTurns(live, message);\n if (answer) reply(answer);\n return;\n }\n if (\n message.method === \"tools/list\" &&\n live.tools !== undefined &&\n message.id !== undefined\n ) {\n reply(result(message.id, live.tools));\n return;\n }\n void forward(live, token, line, message, reply);\n}\n\n/**\n * One agent outside a turn, on one socket. Reads run as asked; the first change in the\n * conversation waits for the user, through the agent's own elicitation where it has it.\n */\nfunction outsideSession(\n app: OutsideApp,\n socket: Socket,\n reply: (line: string) => void,\n): (line: string) => void {\n const live: Live = {\n appOrigin: app.appOrigin.replace(/\\/+$/, \"\"),\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set([socket]),\n };\n let agent = \"A coding agent\";\n let elicits = false;\n let changesAllowed: Promise<boolean> | undefined;\n let asked = 0;\n const answers = new Map<string, (allowed: boolean) => void>();\n\n const send = async (line: string, message: Message, onReply = reply) => {\n let token: string;\n try {\n token = await app.token(agent);\n } catch (error) {\n if (message.id !== undefined) {\n onReply(\n failure(message.id, REFUSED_CODE, `${app.appName} refused: ${String(error)}`),\n );\n }\n return;\n }\n await forward(live, token, line, message, onReply);\n };\n\n const readOnly = async (tool: string): Promise<boolean> => {\n if (live.tools === undefined) {\n const id = `parlor-tools-${++asked}`;\n const list = { jsonrpc: \"2.0\", id, method: \"tools/list\", params: {} };\n await send(JSON.stringify(list), list, () => undefined);\n }\n const tools = (live.tools as { readonly tools?: readonly ToolEntry[] } | undefined)\n ?.tools;\n return (\n tools?.find((entry) => entry.name === tool)?.annotations?.readOnlyHint === true\n );\n };\n\n const askToChange = (): Promise<boolean> => {\n const question = `${agent} wants to change ${app.appName} (${app.appOrigin}) as ${app.account}. Allow changes from this conversation?`;\n if (!elicits) return app.askHere(question);\n const id = `parlor-allow-${++asked}`;\n const answered = new Promise<boolean>((resolve) => answers.set(id, resolve));\n reply(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: \"elicitation/create\",\n params: {\n message: question,\n requestedSchema: { type: \"object\", properties: {} },\n },\n }),\n );\n return answered;\n };\n\n return (line) => {\n const message = parse(line);\n if (!message) return;\n if (message.method === undefined && typeof message.id === \"string\") {\n const answer = answers.get(message.id);\n if (answer) {\n answers.delete(message.id);\n const action = (message.result as { readonly action?: unknown } | undefined)\n ?.action;\n answer(action === \"accept\");\n return;\n }\n }\n if (message.method === \"initialize\") {\n const params = (message as { readonly params?: InitializeParams }).params;\n const client = params?.clientInfo?.name;\n if (typeof client === \"string\" && client !== \"\")\n agent = AGENT_NAMES[client] ?? client;\n elicits = params?.capabilities?.elicitation !== undefined;\n logEvent(\"outside_agent\", { appOrigin: app.appOrigin, agent, elicits });\n void send(line, message, (answer) => reply(withGuidance(answer, app, agent)));\n return;\n }\n if (message.method === \"tools/call\" && message.id !== undefined) {\n const tool = (message as { readonly params?: { readonly name?: unknown } }).params\n ?.name;\n void (async () => {\n if (typeof tool === \"string\" && !(await readOnly(tool))) {\n changesAllowed ??= askToChange().then((allowed) => {\n if (!allowed) changesAllowed = undefined;\n return allowed;\n });\n if (!(await changesAllowed)) {\n reply(\n result(message.id!, {\n content: [\n {\n type: \"text\",\n text: `Nothing was changed: the user did not allow changes to ${app.appName} from this conversation, or could not be asked here. Tell them so. If they ask for the change again, they are asked again first; nothing in ${app.appName} itself turns this on.`,\n },\n ],\n isError: true,\n }),\n );\n return;\n }\n }\n await send(line, message);\n })();\n return;\n }\n void send(line, message);\n };\n}\n\ninterface ToolEntry {\n readonly name?: string;\n readonly annotations?: { readonly readOnlyHint?: boolean };\n}\n\ninterface InitializeParams {\n readonly clientInfo?: { readonly name?: unknown };\n readonly capabilities?: { readonly elicitation?: unknown };\n}\n\n/** The app's own instructions, led by when to use it at all: only when the user names it. */\nfunction withGuidance(line: string, app: OutsideApp, agent: string): string {\n const answer = parse(line);\n const initialized = answer?.result as { readonly instructions?: unknown } | undefined;\n if (!initialized || typeof initialized !== \"object\") return line;\n const guidance = `Use these tools only when the user names ${app.appName} or \"${app.name}\" in their request: they act on the live app at ${app.appOrigin} as ${app.account}, and ${agent} runs outside the app here. Reading is free; before the first change in this conversation the user is asked to allow changes.`;\n const own =\n typeof initialized.instructions === \"string\" ? initialized.instructions : \"\";\n return JSON.stringify({\n ...answer,\n result: { ...initialized, instructions: own ? `${guidance}\\n\\n${own}` : guidance },\n });\n}\n\nexport function createMcpProxy(hostBinary: string): McpProxy {\n const sessions = new Map<string, Live>();\n let server: Server | undefined;\n let socketPath: string | undefined;\n let outside: (appOrigin: string) => OutsideApp | undefined = () => undefined;\n\n const accept = (socket: Socket) => {\n let live: Live | undefined;\n let outsideLine: ((line: string) => void) | undefined;\n const reply = (line: string) => {\n if (!socket.destroyed) socket.write(`${line}\\n`);\n };\n onLines(socket, (line) => {\n if (outsideLine !== undefined) {\n outsideLine(line);\n return;\n }\n if (live !== undefined) {\n handle(live, line, reply);\n return;\n }\n const first = line.trim();\n if (first.startsWith(OUTSIDE_PREFIX)) {\n const appOrigin = first.slice(OUTSIDE_PREFIX.length);\n const app = outside(appOrigin);\n if (!app) {\n reply(JSON.stringify({ refused: notServedMessage(appOrigin) }));\n socket.end();\n return;\n }\n outsideLine = outsideSession(app, socket, reply);\n return;\n }\n live = sessions.get(first);\n if (live) live.sockets.add(socket);\n else socket.destroy();\n });\n socket.on(\"close\", () => live?.sockets.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n };\n\n return {\n async listen(path) {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n await rm(path, { force: true });\n const listening = createServer(accept);\n await new Promise<void>((resolve, reject) => {\n listening.once(\"error\", reject);\n listening.listen(path, () => resolve());\n });\n await chmod(path, 0o600);\n server = listening;\n socketPath = path;\n },\n serveOutside(resolve) {\n outside = resolve;\n },\n open(appServer, appOrigin) {\n if (socketPath === undefined)\n throw new Error(\"The MCP proxy is not listening yet.\");\n const nonce = randomBytes(24).toString(\"base64url\");\n const live: Live = {\n appOrigin: appOrigin.replace(/\\/+$/, \"\"),\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set(),\n };\n sessions.set(nonce, live);\n const end = () => {\n live.token = undefined;\n for (const controller of live.inflight) controller.abort();\n };\n return {\n nonce,\n server: {\n name: appServer,\n command: hostBinary,\n args: [\"mcp-proxy\"],\n env: { [SOCKET_ENV]: socketPath, [NONCE_ENV]: nonce },\n },\n begin: (token) => {\n live.token = token.token;\n },\n renew: (token) => {\n if (live.token !== undefined) live.token = token.token;\n },\n end,\n dispose: () => {\n end();\n sessions.delete(nonce);\n for (const socket of live.sockets) socket.destroy();\n },\n };\n },\n async stopListening() {\n const closing = server;\n server = undefined;\n if (!closing) return;\n closing.close();\n if (socketPath) await rm(socketPath, { force: true });\n },\n async close() {\n for (const live of sessions.values()) {\n for (const controller of live.inflight) controller.abort();\n for (const socket of live.sockets) socket.destroy();\n }\n sessions.clear();\n const closing = server;\n server = undefined;\n if (closing) {\n await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (socketPath) await rm(socketPath, { force: true });\n }\n },\n };\n}\n\n/** Why an agent outside a turn cannot use `appOrigin` here. */\nfunction notServedMessage(appOrigin: string): string {\n return `This computer does not let coding agents use ${appOrigin}: it is not connected, or that was turned off. Connect it again with \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n}\n\nconst notRunningMessage = (appOrigin: string) =>\n `Parlor Host is not running on this computer, so ${appOrigin} cannot be reached. Open the app's agent sidebar, or run \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n\n/**\n * `parlor-host mcp-proxy`: stdio to the daemon socket and back. Inside a turn the\n * environment names the session; `--app` serves an agent outside any turn. Once the daemon\n * hangs up, every request still unanswered, and every later one, is answered with an error\n * here.\n */\nexport async function runMcpProxyProcess(\n env: NodeJS.ProcessEnv,\n outside?: { readonly appOrigin: string; readonly socketPath: string },\n): Promise<void> {\n const path = outside?.socketPath ?? env[SOCKET_ENV];\n const nonce = env[NONCE_ENV];\n if (!path || (!outside && !nonce)) {\n throw new Error(`${SOCKET_ENV} and ${NONCE_ENV} must be set, or --app.`);\n }\n let why = outside ? notRunningMessage(outside.appOrigin) : DISCONNECTED_MESSAGE;\n const unanswered = new Set<JsonRpcId>();\n const toAgent = (line: string) => void process.stdout.write(`${line}\\n`);\n const refuse = (id: JsonRpcId) => toAgent(failure(id, REFUSED_CODE, why));\n process.stdout.on(\"error\", () => undefined);\n\n const daemon = connect(path);\n daemon.on(\"error\", () => daemon.destroy());\n daemon.once(\"connect\", () => {\n if (outside) why = DISCONNECTED_MESSAGE;\n });\n const hungUp = new Promise<void>((resolve) =>\n daemon.once(\"close\", () => {\n for (const id of unanswered) refuse(id);\n unanswered.clear();\n resolve();\n }),\n );\n daemon.write(outside ? `${OUTSIDE_PREFIX}${outside.appOrigin}\\n` : `${nonce}\\n`);\n onLines(daemon, (line) => {\n const refused = (parse(line) as { readonly refused?: unknown } | undefined)?.refused;\n if (typeof refused === \"string\") {\n why = refused;\n return;\n }\n const message = parse(line);\n if (message?.id !== undefined && message.method === undefined) {\n unanswered.delete(message.id);\n }\n toAgent(line);\n });\n\n const agent = onLines(process.stdin, (line) => {\n const message = parse(line);\n const id = typeof message?.method === \"string\" ? message.id : undefined;\n if (!daemon.destroyed) {\n if (id !== undefined) unanswered.add(id);\n daemon.write(`${line}\\n`);\n } else if (id !== undefined) {\n refuse(id);\n }\n });\n await once(agent, \"close\");\n daemon.end();\n await hungUp;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-proxy.js","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { once } from \"node:events\";\nimport { chmod, mkdir, rm } from \"node:fs/promises\";\nimport { connect, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname } from \"node:path\";\n\nimport type { Delegation } from \"@parlor/server\";\n\nimport type { StdioMcpServer } from \"./acp.js\";\nimport { onLines } from \"./lines.js\";\nimport { logEvent } from \"./log.js\";\n\n/**\n * The agent's MCP server for an app is this host: a stdio server (`parlor-host\n * mcp-proxy`) that connects back to the daemon's 0600 socket and names its session by a\n * nonce. The daemon forwards each message to `<app>/_parlor/mcp` with the current turn's\n * token, so no app credential is ever in the agent's config, logs or environment.\n */\nexport interface McpProxy {\n listen(socketPath: string): Promise<void>;\n open(appServer: string, appOrigin: string): ProxySession;\n /**\n * Serves `parlor-host mcp-proxy --app <origin>`: a coding agent on this computer outside\n * any turn, such as Claude Code in a terminal. `undefined` refuses the app.\n */\n serveOutside(resolve: (appOrigin: string) => OutsideApp | undefined): void;\n stopListening(): Promise<void>;\n close(): Promise<void>;\n}\n\nexport interface ProxySession {\n readonly nonce: string;\n /** The entry for `session/new`. */\n readonly server: StdioMcpServer;\n /** Forward with this token until `end`; a `tools/call` outside a turn gets NO_TURN_MESSAGE. */\n begin(token: Delegation): void;\n renew(token: Delegation): void;\n end(): void;\n dispose(): void;\n}\n\n/** An app a coding agent on this computer may use outside its sidebar. */\nexport interface OutsideApp {\n readonly appOrigin: string;\n readonly appName: string;\n /** The name the user asks the agent with, its MCP server name. */\n readonly name: string;\n /** Whose account the agent acts as: its email, or its name. */\n readonly account: string;\n /** A token for `agent`'s calls, fresh enough to use now. */\n token(agent: string): Promise<string>;\n /** Asks on this computer, for an agent that cannot ask the user itself. */\n askHere(question: string): Promise<boolean>;\n}\n\nexport const NO_TURN_MESSAGE =\n \"No turn is active: the user has not asked anything right now. Wait for their next message.\";\n\nexport const DISCONNECTED_MESSAGE =\n \"This computer no longer serves the app: it was disconnected, or Parlor Host stopped.\";\n\nconst OUTSIDE_PREFIX = \"app \";\nconst AGENT_NAMES: Readonly<Record<string, string>> = {\n \"claude-code\": \"Claude Code\",\n \"codex-mcp-client\": \"Codex\",\n codex: \"Codex\",\n};\n\nconst SOCKET_ENV = \"PARLOR_HOST_PROXY_SOCKET\";\nconst NONCE_ENV = \"PARLOR_HOST_PROXY_NONCE\";\nconst NO_TURN_CODE = -32000;\nconst REFUSED_CODE = -32001;\n\ntype JsonRpcId = string | number | null;\n\ninterface Message {\n readonly jsonrpc?: unknown;\n readonly id?: JsonRpcId;\n readonly method?: unknown;\n readonly result?: unknown;\n}\n\n/** An app's answer to one handshake request, without its id. */\ntype KnownAnswer = { readonly result: unknown } | { readonly error: unknown };\n\ninterface Live {\n readonly appOrigin: string;\n /** The app's answers to the handshake every session repeats; undefined outside turns' sessions. */\n readonly known: Map<string, KnownAnswer> | undefined;\n token: string | undefined;\n protocolVersion: string | undefined;\n initialized: unknown;\n tools: unknown;\n readonly inflight: Set<AbortController>;\n readonly sockets: Set<Socket>;\n}\n\nfunction parse(text: string): Message | undefined {\n try {\n const value: unknown = JSON.parse(text);\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Message)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst result = (id: JsonRpcId, value: unknown) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, result: value });\n\nconst failure = (id: JsonRpcId, code: number, message: string) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, error: { code, message } });\n\n/**\n * What a new session asks before its first prompt, answered by the app the same way each\n * time for the same parameters. A session gets the last answer at once while the app is\n * asked again behind it; a list that changed is announced to the agent.\n */\nconst HANDSHAKE: ReadonlySet<string> = new Set([\n \"server/discover\",\n \"initialize\",\n \"tools/list\",\n \"resources/list\",\n \"resources/templates/list\",\n \"prompts/list\",\n]);\nconst LIST_CHANGED: Readonly<Record<string, string>> = {\n \"tools/list\": \"notifications/tools/list_changed\",\n \"resources/list\": \"notifications/resources/list_changed\",\n \"prompts/list\": \"notifications/prompts/list_changed\",\n};\n/** Statuses the same request gets again: never a credential, rate or server failure. */\nconst STABLE_REFUSALS: ReadonlySet<number> = new Set([400, 404, 405]);\n\nconst handshakeKey = (message: Message) =>\n typeof message.method === \"string\" && HANDSHAKE.has(message.method)\n ? `${message.method} ${JSON.stringify((message as { readonly params?: unknown }).params ?? null)}`\n : undefined;\n\nfunction knownAnswer(answer: Message | undefined): KnownAnswer | undefined {\n if (answer === undefined) return undefined;\n if (answer.result !== undefined) return { result: answer.result };\n const { error } = answer as { readonly error?: unknown };\n return error === undefined ? undefined : { error };\n}\n\n/** What the session learns from an `initialize` or `tools/list` answer, wherever it came from. */\nfunction learn(live: Live, method: string, answer: KnownAnswer): void {\n if (!(\"result\" in answer)) return;\n if (method === \"initialize\") {\n live.initialized = answer.result;\n const version = (answer.result as { readonly protocolVersion?: unknown } | undefined)\n ?.protocolVersion;\n if (typeof version === \"string\") live.protocolVersion = version;\n }\n if (method === \"tools/list\") live.tools = answer.result;\n}\n\n/** One line per message on the agent's stdio: only a body with a raw newline is compacted. */\nconst asLine = (text: string) =>\n text.includes(\"\\n\") ? JSON.stringify(JSON.parse(text)) : text;\n\nfunction betweenTurns(live: Live, message: Message): string | undefined {\n if (message.id === undefined || typeof message.method !== \"string\") return undefined;\n const { id } = message;\n const key = handshakeKey(message);\n const known = key === undefined ? undefined : live.known?.get(key);\n if (known) {\n learn(live, message.method, known);\n return JSON.stringify({ jsonrpc: \"2.0\", id, ...known });\n }\n switch (message.method) {\n case \"ping\":\n return result(id, {});\n case \"initialize\":\n return live.initialized === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.initialized);\n case \"tools/list\":\n return live.tools === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.tools);\n case \"tools/call\":\n return result(id, {\n content: [{ type: \"text\", text: NO_TURN_MESSAGE }],\n isError: true,\n });\n default:\n return failure(id, NO_TURN_CODE, NO_TURN_MESSAGE);\n }\n}\n\nasync function* serverSentData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let data: string[] = [];\n for await (const chunk of body) {\n buffer += decoder.decode(chunk, { stream: true });\n let end = buffer.indexOf(\"\\n\");\n while (end !== -1) {\n const line = buffer.slice(0, end).replace(/\\r$/, \"\");\n buffer = buffer.slice(end + 1);\n if (line === \"\") {\n if (data.length > 0) yield data.join(\"\\n\");\n data = [];\n } else if (line.startsWith(\"data:\")) {\n data.push(line.slice(line.startsWith(\"data: \") ? 6 : 5));\n }\n end = buffer.indexOf(\"\\n\");\n }\n }\n if (data.length > 0) yield data.join(\"\\n\");\n}\n\nfunction refusal(status: number): string {\n return status === 401\n ? \"This computer can no longer act for the app: the turn ended or the computer was disconnected.\"\n : `The app answered HTTP ${status}.`;\n}\n\n/** Sends one message to the app; resolves with its status and what the request was answered. */\nasync function forward(\n live: Live,\n token: string,\n line: string,\n message: Message,\n reply: (line: string) => void,\n): Promise<{ readonly status: number; readonly answer: Message | undefined }> {\n const method = typeof message.method === \"string\" ? message.method : \"response\";\n const controller = new AbortController();\n live.inflight.add(controller);\n let status = 0;\n let given: Message | undefined;\n try {\n const response = await fetch(`${live.appOrigin}/_parlor/mcp`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${token}`,\n accept: \"application/json, text/event-stream\",\n \"content-type\": \"application/json\",\n ...(live.protocolVersion ? { \"mcp-protocol-version\": live.protocolVersion } : {}),\n },\n body: line,\n signal: controller.signal,\n });\n status = response.status;\n const bodies: string[] = [];\n if ((response.headers.get(\"content-type\") ?? \"\").includes(\"text/event-stream\")) {\n if (response.body)\n for await (const data of serverSentData(response.body)) bodies.push(data);\n } else {\n const text = await response.text();\n if (text.trim() !== \"\") bodies.push(text);\n }\n let answered = false;\n for (const text of bodies) {\n const answer = parse(text);\n if (answer?.jsonrpc !== \"2.0\") continue;\n if (answer.id === message.id) {\n answered = true;\n given = answer;\n const known = knownAnswer(answer);\n if (known) learn(live, method, known);\n }\n reply(asLine(text));\n }\n if (message.id !== undefined && !answered) {\n const refused = failure(message.id, REFUSED_CODE, refusal(status));\n given = parse(refused);\n reply(refused);\n }\n } catch (error) {\n status = 0;\n if (message.id !== undefined) {\n reply(\n controller.signal.aborted\n ? failure(message.id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : failure(\n message.id,\n REFUSED_CODE,\n `The app could not be reached: ${String(error)}`,\n ),\n );\n }\n } finally {\n live.inflight.delete(controller);\n logEvent(\"proxy_forward\", { appOrigin: live.appOrigin, rpcMethod: method, status });\n }\n return { status, answer: given };\n}\n\n/** Keeps the app's answer to a handshake request when the same request gets it again. */\nfunction remember(\n live: Live,\n key: string,\n outcome: { readonly status: number; readonly answer: Message | undefined },\n): KnownAnswer | undefined {\n const { status } = outcome;\n const stable = (status >= 200 && status < 300) || STABLE_REFUSALS.has(status);\n const known = stable ? knownAnswer(outcome.answer) : undefined;\n // A refused initialize would leave every later session without the app's tools.\n if (!known || (key.startsWith(\"initialize \") && !(\"result\" in known))) return undefined;\n live.known?.set(key, known);\n return known;\n}\n\n/** Answers a handshake request from what the app said last, then asks the app again. */\nfunction replay(\n live: Live,\n token: string,\n line: string,\n message: Message,\n key: string,\n known: KnownAnswer,\n reply: (line: string) => void,\n): void {\n const method = message.method as string;\n learn(live, method, known);\n reply(JSON.stringify({ jsonrpc: \"2.0\", id: message.id, ...known }));\n void forward(live, token, line, message, () => undefined).then((outcome) => {\n const fresh = remember(live, key, outcome);\n const changed = LIST_CHANGED[method];\n if (!changed || !fresh || JSON.stringify(fresh) === JSON.stringify(known)) return;\n const notice = JSON.stringify({ jsonrpc: \"2.0\", method: changed });\n for (const socket of live.sockets) if (!socket.destroyed) socket.write(`${notice}\\n`);\n });\n}\n\nfunction handle(live: Live, line: string, reply: (line: string) => void): void {\n const message = parse(line);\n if (!message) return;\n const token = live.token;\n if (token === undefined) {\n const answer = betweenTurns(live, message);\n if (answer) reply(answer);\n return;\n }\n const key = message.id === undefined ? undefined : handshakeKey(message);\n if (key === undefined) {\n void forward(live, token, line, message, reply);\n return;\n }\n const known = live.known?.get(key);\n if (known) {\n replay(live, token, line, message, key, known, reply);\n return;\n }\n void forward(live, token, line, message, reply).then((outcome) =>\n remember(live, key, outcome),\n );\n}\n\n/**\n * One agent outside a turn, on one socket. Reads run as asked; the first change in the\n * conversation waits for the user, through the agent's own elicitation where it has it.\n */\nfunction outsideSession(\n app: OutsideApp,\n socket: Socket,\n reply: (line: string) => void,\n): (line: string) => void {\n const live: Live = {\n appOrigin: app.appOrigin.replace(/\\/+$/, \"\"),\n known: undefined,\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set([socket]),\n };\n let agent = \"A coding agent\";\n let elicits = false;\n let changesAllowed: Promise<boolean> | undefined;\n let asked = 0;\n const answers = new Map<string, (allowed: boolean) => void>();\n\n const send = async (line: string, message: Message, onReply = reply) => {\n let token: string;\n try {\n token = await app.token(agent);\n } catch (error) {\n if (message.id !== undefined) {\n onReply(\n failure(message.id, REFUSED_CODE, `${app.appName} refused: ${String(error)}`),\n );\n }\n return;\n }\n await forward(live, token, line, message, onReply);\n };\n\n const readOnly = async (tool: string): Promise<boolean> => {\n if (live.tools === undefined) {\n const id = `parlor-tools-${++asked}`;\n const list = { jsonrpc: \"2.0\", id, method: \"tools/list\", params: {} };\n await send(JSON.stringify(list), list, () => undefined);\n }\n const tools = (live.tools as { readonly tools?: readonly ToolEntry[] } | undefined)\n ?.tools;\n return (\n tools?.find((entry) => entry.name === tool)?.annotations?.readOnlyHint === true\n );\n };\n\n const askToChange = (): Promise<boolean> => {\n const question = `${agent} wants to change ${app.appName} (${app.appOrigin}) as ${app.account}. Allow changes from this conversation?`;\n if (!elicits) return app.askHere(question);\n const id = `parlor-allow-${++asked}`;\n const answered = new Promise<boolean>((resolve) => answers.set(id, resolve));\n reply(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: \"elicitation/create\",\n params: {\n message: question,\n requestedSchema: { type: \"object\", properties: {} },\n },\n }),\n );\n return answered;\n };\n\n return (line) => {\n const message = parse(line);\n if (!message) return;\n if (message.method === undefined && typeof message.id === \"string\") {\n const answer = answers.get(message.id);\n if (answer) {\n answers.delete(message.id);\n const action = (message.result as { readonly action?: unknown } | undefined)\n ?.action;\n answer(action === \"accept\");\n return;\n }\n }\n if (message.method === \"initialize\") {\n const params = (message as { readonly params?: InitializeParams }).params;\n const client = params?.clientInfo?.name;\n if (typeof client === \"string\" && client !== \"\")\n agent = AGENT_NAMES[client] ?? client;\n elicits = params?.capabilities?.elicitation !== undefined;\n logEvent(\"outside_agent\", { appOrigin: app.appOrigin, agent, elicits });\n void send(line, message, (answer) => reply(withGuidance(answer, app, agent)));\n return;\n }\n if (message.method === \"tools/call\" && message.id !== undefined) {\n const tool = (message as { readonly params?: { readonly name?: unknown } }).params\n ?.name;\n void (async () => {\n if (typeof tool === \"string\" && !(await readOnly(tool))) {\n changesAllowed ??= askToChange().then((allowed) => {\n if (!allowed) changesAllowed = undefined;\n return allowed;\n });\n if (!(await changesAllowed)) {\n reply(\n result(message.id!, {\n content: [\n {\n type: \"text\",\n text: `Nothing was changed: the user did not allow changes to ${app.appName} from this conversation, or could not be asked here. Tell them so. If they ask for the change again, they are asked again first; nothing in ${app.appName} itself turns this on.`,\n },\n ],\n isError: true,\n }),\n );\n return;\n }\n }\n await send(line, message);\n })();\n return;\n }\n void send(line, message);\n };\n}\n\ninterface ToolEntry {\n readonly name?: string;\n readonly annotations?: { readonly readOnlyHint?: boolean };\n}\n\ninterface InitializeParams {\n readonly clientInfo?: { readonly name?: unknown };\n readonly capabilities?: { readonly elicitation?: unknown };\n}\n\n/** The app's own instructions, led by when to use it at all: only when the user names it. */\nfunction withGuidance(line: string, app: OutsideApp, agent: string): string {\n const answer = parse(line);\n const initialized = answer?.result as { readonly instructions?: unknown } | undefined;\n if (!initialized || typeof initialized !== \"object\") return line;\n const guidance = `Use these tools only when the user names ${app.appName} or \"${app.name}\" in their request: they act on the live app at ${app.appOrigin} as ${app.account}, and ${agent} runs outside the app here. Reading is free; before the first change in this conversation the user is asked to allow changes.`;\n const own =\n typeof initialized.instructions === \"string\" ? initialized.instructions : \"\";\n return JSON.stringify({\n ...answer,\n result: { ...initialized, instructions: own ? `${guidance}\\n\\n${own}` : guidance },\n });\n}\n\nexport function createMcpProxy(hostBinary: string): McpProxy {\n const sessions = new Map<string, Live>();\n const handshakes = new Map<string, Map<string, KnownAnswer>>();\n let server: Server | undefined;\n let socketPath: string | undefined;\n let outside: (appOrigin: string) => OutsideApp | undefined = () => undefined;\n\n const accept = (socket: Socket) => {\n let live: Live | undefined;\n let outsideLine: ((line: string) => void) | undefined;\n const reply = (line: string) => {\n if (!socket.destroyed) socket.write(`${line}\\n`);\n };\n onLines(socket, (line) => {\n if (outsideLine !== undefined) {\n outsideLine(line);\n return;\n }\n if (live !== undefined) {\n handle(live, line, reply);\n return;\n }\n const first = line.trim();\n if (first.startsWith(OUTSIDE_PREFIX)) {\n const appOrigin = first.slice(OUTSIDE_PREFIX.length);\n const app = outside(appOrigin);\n if (!app) {\n reply(JSON.stringify({ refused: notServedMessage(appOrigin) }));\n socket.end();\n return;\n }\n outsideLine = outsideSession(app, socket, reply);\n return;\n }\n live = sessions.get(first);\n if (live) live.sockets.add(socket);\n else socket.destroy();\n });\n socket.on(\"close\", () => live?.sockets.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n };\n\n return {\n async listen(path) {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n await rm(path, { force: true });\n const listening = createServer(accept);\n await new Promise<void>((resolve, reject) => {\n listening.once(\"error\", reject);\n listening.listen(path, () => resolve());\n });\n await chmod(path, 0o600);\n server = listening;\n socketPath = path;\n },\n serveOutside(resolve) {\n outside = resolve;\n },\n open(appServer, appOrigin) {\n if (socketPath === undefined)\n throw new Error(\"The MCP proxy is not listening yet.\");\n const nonce = randomBytes(24).toString(\"base64url\");\n const origin = appOrigin.replace(/\\/+$/, \"\");\n let known = handshakes.get(origin);\n if (!known) {\n known = new Map();\n handshakes.set(origin, known);\n }\n const live: Live = {\n appOrigin: origin,\n known,\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set(),\n };\n sessions.set(nonce, live);\n const end = () => {\n live.token = undefined;\n for (const controller of live.inflight) controller.abort();\n };\n return {\n nonce,\n server: {\n name: appServer,\n command: hostBinary,\n args: [\"mcp-proxy\"],\n env: { [SOCKET_ENV]: socketPath, [NONCE_ENV]: nonce },\n },\n begin: (token) => {\n live.token = token.token;\n },\n renew: (token) => {\n if (live.token !== undefined) live.token = token.token;\n },\n end,\n dispose: () => {\n end();\n sessions.delete(nonce);\n for (const socket of live.sockets) socket.destroy();\n },\n };\n },\n async stopListening() {\n const closing = server;\n server = undefined;\n if (!closing) return;\n closing.close();\n if (socketPath) await rm(socketPath, { force: true });\n },\n async close() {\n for (const live of sessions.values()) {\n for (const controller of live.inflight) controller.abort();\n for (const socket of live.sockets) socket.destroy();\n }\n sessions.clear();\n const closing = server;\n server = undefined;\n if (closing) {\n await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (socketPath) await rm(socketPath, { force: true });\n }\n },\n };\n}\n\n/** Why an agent outside a turn cannot use `appOrigin` here. */\nfunction notServedMessage(appOrigin: string): string {\n return `This computer does not let coding agents use ${appOrigin}: it is not connected, or that was turned off. Connect it again with \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n}\n\nconst notRunningMessage = (appOrigin: string) =>\n `Parlor Host is not running on this computer, so ${appOrigin} cannot be reached. Open the app's agent sidebar, or run \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n\n/**\n * `parlor-host mcp-proxy`: stdio to the daemon socket and back. Inside a turn the\n * environment names the session; `--app` serves an agent outside any turn. Once the daemon\n * hangs up, every request still unanswered, and every later one, is answered with an error\n * here.\n */\nexport async function runMcpProxyProcess(\n env: NodeJS.ProcessEnv,\n outside?: { readonly appOrigin: string; readonly socketPath: string },\n): Promise<void> {\n const path = outside?.socketPath ?? env[SOCKET_ENV];\n const nonce = env[NONCE_ENV];\n if (!path || (!outside && !nonce)) {\n throw new Error(`${SOCKET_ENV} and ${NONCE_ENV} must be set, or --app.`);\n }\n let why = outside ? notRunningMessage(outside.appOrigin) : DISCONNECTED_MESSAGE;\n const unanswered = new Set<JsonRpcId>();\n const toAgent = (line: string) => void process.stdout.write(`${line}\\n`);\n const refuse = (id: JsonRpcId) => toAgent(failure(id, REFUSED_CODE, why));\n process.stdout.on(\"error\", () => undefined);\n\n const daemon = connect(path);\n daemon.on(\"error\", () => daemon.destroy());\n daemon.once(\"connect\", () => {\n if (outside) why = DISCONNECTED_MESSAGE;\n });\n const hungUp = new Promise<void>((resolve) =>\n daemon.once(\"close\", () => {\n for (const id of unanswered) refuse(id);\n unanswered.clear();\n resolve();\n }),\n );\n daemon.write(outside ? `${OUTSIDE_PREFIX}${outside.appOrigin}\\n` : `${nonce}\\n`);\n onLines(daemon, (line) => {\n const refused = (parse(line) as { readonly refused?: unknown } | undefined)?.refused;\n if (typeof refused === \"string\") {\n why = refused;\n return;\n }\n const message = parse(line);\n if (message?.id !== undefined && message.method === undefined) {\n unanswered.delete(message.id);\n }\n toAgent(line);\n });\n\n const agent = onLines(process.stdin, (line) => {\n const message = parse(line);\n const id = typeof message?.method === \"string\" ? message.id : undefined;\n if (!daemon.destroyed) {\n if (id !== undefined) unanswered.add(id);\n daemon.write(`${line}\\n`);\n } else if (id !== undefined) {\n refuse(id);\n }\n });\n await once(agent, \"close\");\n daemon.end();\n await hungUp;\n}\n"]}
|
package/dist/spec-kit.d.ts
CHANGED
|
@@ -66,6 +66,8 @@ export declare const welcome: {
|
|
|
66
66
|
export declare function hostRoutes(options: {
|
|
67
67
|
readonly wake: boolean;
|
|
68
68
|
readonly turn?: () => unknown;
|
|
69
|
+
/** Pushed on the stream's `chat` channel, as a server on host protocol 3 does. */
|
|
70
|
+
readonly push?: () => unknown;
|
|
69
71
|
}): Route;
|
|
70
72
|
export declare const claimedTurn: (turnId: string, agentId: string, context: string, text: string) => {
|
|
71
73
|
id: string;
|
package/dist/spec-kit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-kit.d.ts","sourceRoot":"","sources":["../src/spec-kit.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"spec-kit.d.ts","sourceRoot":"","sources":["../src/spec-kit.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAYnB,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAKtB,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAQxB,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D,eAAO,MAAM,QAAQ,iCAAiC,CAAC;AAIvD,qBAAa,OAAO;;IAGN,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAnC,YAAqB,MAAM,EAAE,MAAM,EAAI;IAEjC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAqBlE;IAED,4FAA4F;IACtF,OAAO,CACX,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAC9B,OAAO,GAAE,SAAS,MAAM,EAAO,GAC9B,OAAO,CAAC;QACT,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;KAC3B,CAAC,CAoBD;CACF;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAsErD;AAED,wBAAgB,cAAc,IAAI,QAAQ,GAAG;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;CAC3C,CAyCA;AAED,wBAAgB,WAAW,IAAI,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,aAAa,EAAE,CAAA;CAAE,CAuBnF;AAID,qBAAa,UAAU;IAEnB,QAAQ,CAAC,IAAI,EAAE,UAAU;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAH3B,OAAO,eAIH;IAEJ,OAAa,MAAM,CACjB,EAAE,SAAa,EACf,IAAI,SAAoB,EACxB,QAAQ,SAAQ,GACf,OAAO,CAAC,UAAU,CAAC,CA6BrB;IAED,IAAI,EAAE,oCAEL;YAEa,IAAI;IAmBZ,UAAU,CACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,QAAQ,UAAQ,GACf,OAAO,CAAC,aAAa,CAAC,CAQxB;IAEK,UAAU,CACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,aAAa,CAAC,CAQxB;IAED,iGAAiG;IAC3F,QAAQ,CACZ,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAC1E,OAAO,CAAC,WAAW,CAAC,CAiBtB;CACF;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,EAAE,CAAC;IACJ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,MAAM,KAAK,GAAG,CAClB,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC;AAEb,wBAAsB,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAsB5D;AAED,eAAO,MAAM,IAAI,aAAc,cAAc,SAAS,OAAO,qDAG9B,CAAC;AAEhC,eAAO,MAAM,OAAO;;;;;;CAMnB,CAAC;AAEF,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC;CAC/B,GAAG,KAAK,CA8ER;AAED,eAAO,MAAM,WAAW,WACd,MAAM,WACL,MAAM,WACN,MAAM,QACT,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkBH,KAAK;QAAY,SAAS;;;CAEnC,CAAC;AAEH,eAAO,MAAM,QAAQ,WAAY,MAAM,QAAQ,MAAM,aAAa,MAAM,KAAG,QAQzE,CAAC"}
|
package/dist/spec-kit.js
CHANGED
|
@@ -320,7 +320,12 @@ export function hostRoutes(options) {
|
|
|
320
320
|
}
|
|
321
321
|
if (path === "/_parlor/sync/stream") {
|
|
322
322
|
response.writeHead(200, { "content-type": "text/event-stream" });
|
|
323
|
-
|
|
323
|
+
const capabilities = options.push ? ["chat"] : [];
|
|
324
|
+
response.write(`event: handshake\ndata: ${JSON.stringify({ capabilities, keepAliveMs: 10_000 })}\n\n`);
|
|
325
|
+
if (options.push) {
|
|
326
|
+
const frame = { type: "claimed", turn: options.push() };
|
|
327
|
+
response.write(`event: chat\ndata: ${JSON.stringify(frame)}\n\n`);
|
|
328
|
+
}
|
|
324
329
|
if (options.wake) {
|
|
325
330
|
const events = [{ version: 1, id: "e1", tags: [["parlor_chat", "t1"]] }];
|
|
326
331
|
response.write(`event: message\ndata: ${JSON.stringify({ events, cursor: "1.e1" })}\n\n`);
|
package/dist/spec-kit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-kit.js","sourceRoot":"","sources":["../src/spec-kit.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n createServer as createHttpServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport {\n answerStatement,\n betterAuthProvider,\n deviceCommitment,\n parlorAuth,\n promptStatement,\n statementBytes,\n vouchStatement,\n} from \"@parlor/auth\";\nimport {\n type AnswerToSign,\n HOST_PROTOCOL,\n type ItemSignature,\n type PromptToSign,\n} from \"@parlor/chat\";\nimport { chat } from \"@parlor/chat/server\";\nimport { asId, defineAction } from \"@parlor/core\";\nimport { createRegistry } from \"@parlor/core/registry\";\nimport { createDatabase, type DatabaseHandle } from \"@parlor/data\";\nimport {\n createServer,\n type DeviceKeys,\n type DeviceVouch,\n type FrameworkServer,\n} from \"@parlor/server\";\nimport { betterAuth } from \"better-auth\";\nimport { memoryAdapter } from \"better-auth/adapters/memory\";\nimport { getAuthTables } from \"better-auth/db\";\nimport { serve } from \"srvx\";\nimport { z } from \"zod\";\n\nimport { hostAssertion } from \"./assertion.js\";\nimport type { AppGrant, HostKeys } from \"./grants.js\";\nimport type { TrustedDevice, TrustStore } from \"./trust.js\";\n\nexport const PASSWORD = \"correct horse battery staple\";\n\nconst digest = (password: string) => createHash(\"sha256\").update(password).digest(\"hex\");\n\nexport class Browser {\n readonly #cookies = new Map<string, string>();\n\n constructor(readonly origin: string) {}\n\n async fetch(url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers);\n if (this.#cookies.size > 0) {\n headers.set(\n \"cookie\",\n [...this.#cookies].map(([name, value]) => `${name}=${value}`).join(\"; \"),\n );\n }\n if (init.method === \"POST\" && !headers.has(\"origin\"))\n headers.set(\"origin\", this.origin);\n const response = await fetch(new URL(url, this.origin), {\n ...init,\n headers,\n redirect: \"manual\",\n });\n for (const cookie of response.headers.getSetCookie()) {\n const [pair] = cookie.split(\";\");\n const at = pair!.indexOf(\"=\");\n this.#cookies.set(pair!.slice(0, at), pair!.slice(at + 1));\n }\n return response;\n }\n\n /** Answers the consent page as a browser would, sending its checked boxes but `uncheck`. */\n async consent(\n url: string,\n decision: \"connect\" | \"cancel\",\n uncheck: readonly string[] = [],\n ): Promise<{\n readonly page: string;\n readonly answer: Response;\n }> {\n const page = await (await this.fetch(url)).text();\n const fields = new URLSearchParams(\n [...page.matchAll(/<input type=\"hidden\" name=\"([^\"]+)\" value=\"([^\"]*)\">/g)].map(\n (match) => [match[1]!, match[2]!.replaceAll(\"&\", \"&\")],\n ),\n );\n for (const [, name, value] of page.matchAll(\n /<input type=\"checkbox\" name=\"([^\"]+)\" value=\"([^\"]*)\" checked>/g,\n )) {\n if (!uncheck.includes(name!)) fields.set(name!, value!);\n }\n fields.set(\"decision\", decision);\n const action = /<form method=\"post\" action=\"([^\"]+)\"/.exec(page)?.[1] ?? \"\";\n const answer = await this.fetch(action, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: fields.toString(),\n });\n return { page, answer };\n }\n}\n\nexport interface SpecApp {\n readonly origin: string;\n readonly server: FrameworkServer;\n signUp(name: string): Promise<Browser>;\n close(): Promise<void>;\n}\n\nexport async function startSpecApp(): Promise<SpecApp> {\n const database: DatabaseHandle = await createDatabase({ dataDir: \"memory://\" });\n let server: FrameworkServer | undefined;\n const listener = serve({\n port: 0,\n hostname: \"127.0.0.1\",\n silent: true,\n fetch: (request) => server!.fetch(request),\n });\n await listener.ready();\n const origin = new URL(listener.url!).origin;\n const authOptions = parlorAuth({\n origin,\n signInPage: \"/sign-in\",\n appName: \"Hello\",\n secret: \"a-test-secret-that-is-long-enough-for-better-auth\",\n emailAndPassword: {\n enabled: true,\n password: {\n hash: (password) => Promise.resolve(digest(password)),\n verify: ({ hash, password }) => Promise.resolve(digest(password) === hash),\n },\n },\n });\n const tables = Object.values(getAuthTables(authOptions)).map((table) => [\n table.modelName,\n [],\n ]);\n const instance = betterAuth({\n ...authOptions,\n database: memoryAdapter(Object.fromEntries(tables)),\n });\n server = createServer({\n actions: createRegistry({\n listTasks: defineAction({\n description: \"List tasks.\",\n input: z.object({}),\n run: () => [],\n }),\n }),\n auth: betterAuthProvider({ instance }),\n plugins: [chat()],\n database: {\n read: () => database.read(),\n transaction: (run) => database.transaction(run),\n listen: (channel, handler, options) => database.listen(channel, handler, options),\n },\n });\n return {\n origin,\n server,\n async signUp(name) {\n const browser = new Browser(origin);\n const response = await browser.fetch(\"/_parlor/auth/sign-up/email\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n name,\n email: `${name.toLowerCase()}@example.com`,\n password: PASSWORD,\n }),\n });\n if (response.status !== 200) throw new Error(`sign-up answered ${response.status}`);\n return browser;\n },\n async close() {\n await listener.close(true);\n await server!.close();\n },\n };\n}\n\nexport function memoryHostKeys(): HostKeys & {\n readonly origins: () => readonly string[];\n} {\n const kept = new Map<string, { key: CryptoKey; kid: string; grantId: string }>();\n const sign = (key: CryptoKey) => async (payload: Uint8Array) =>\n Buffer.from(\n await crypto.subtle.sign(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n key,\n new Uint8Array(payload),\n ),\n ).toString(\"base64url\");\n return {\n origins: () => [...kept.keys()],\n async create(appOrigin) {\n const pair = await crypto.subtle.generateKey(\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"sign\", \"verify\"],\n );\n const { kty, crv, x, y } = await crypto.subtle.exportKey(\"jwk\", pair.publicKey);\n const publicKey = { kty: kty!, crv: crv!, x: x!, y: y! };\n const thumbprint = createHash(\"sha256\")\n .update(JSON.stringify({ crv, kty, x, y }))\n .digest(\"base64url\");\n return {\n publicKey,\n thumbprint,\n sign: sign(pair.privateKey),\n keep: async (grantId) => {\n kept.set(appOrigin, { key: pair.privateKey, kid: thumbprint, grantId });\n },\n };\n },\n async assert(appOrigin, request) {\n const key = kept.get(appOrigin);\n if (!key) throw new Error(`no key for ${appOrigin}`);\n return hostAssertion(sign(key.key), key, request);\n },\n async remove(appOrigin) {\n kept.delete(appOrigin);\n },\n };\n}\n\nexport function memoryTrust(): TrustStore & { readonly pins: () => TrustedDevice[] } {\n const pinned = new Map<string, TrustedDevice>();\n const keyOf = (appOrigin: string, deviceId: string) => `${appOrigin}\\n${deviceId}`;\n return {\n pins: () => [...pinned.values()],\n get: async (appOrigin, deviceId) => pinned.get(keyOf(appOrigin, deviceId)),\n list: async (appOrigin) =>\n [...pinned.entries()]\n .filter(([key]) => key.startsWith(`${appOrigin}\\n`))\n .map(([, device]) => device),\n pin: async (appOrigin, device) =>\n void pinned.set(keyOf(appOrigin, device.deviceId), device),\n forget: async (appOrigin, deviceId) => {\n for (const key of [...pinned.keys()]) {\n if (\n key.startsWith(`${appOrigin}\\n`) &&\n (deviceId === undefined || key.endsWith(`\\n${deviceId}`))\n ) {\n pinned.delete(key);\n }\n }\n },\n };\n}\n\nconst ES256 = { name: \"ECDSA\", hash: \"SHA-256\" } as const;\n\nexport class TestDevice {\n private constructor(\n readonly keys: DeviceKeys,\n private readonly signing: CryptoKey,\n private readonly presence: CryptoKey,\n ) {}\n\n static async create(\n id = \"device-1\",\n name = \"Chrome on macOS\",\n platform = \"web\",\n ): Promise<TestDevice> {\n const make = async () => {\n const pair = await crypto.subtle.generateKey(\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"sign\", \"verify\"],\n );\n const { kty, crv, x, y } = await crypto.subtle.exportKey(\"jwk\", pair.publicKey);\n return {\n privateKey: pair.privateKey,\n publicKey: { kty: kty!, crv: crv!, x: x!, y: y! },\n };\n };\n const [signing, presence] = [await make(), await make()];\n return new TestDevice(\n {\n id: asId(\"device\", id),\n name,\n platform,\n signingKey: signing.publicKey,\n presenceKey: {\n format: \"es256-raw\",\n keyId: \"presence\",\n publicKey: presence.publicKey,\n },\n },\n signing.privateKey,\n presence.privateKey,\n );\n }\n\n get id() {\n return this.keys.id;\n }\n\n private async sign(\n key: CryptoKey,\n bytes: Uint8Array,\n presence: \"none\" | \"user\",\n at: number,\n ) {\n const signature = await crypto.subtle.sign(ES256, key, new Uint8Array(bytes));\n return {\n deviceId: this.id,\n at,\n signature: {\n keyId: \"key\",\n presence,\n format: \"es256-raw\",\n signature: Buffer.from(signature).toString(\"base64url\"),\n },\n } satisfies ItemSignature;\n }\n\n async signPrompt(\n app: string,\n prompt: PromptToSign,\n at: number,\n presence = false,\n ): Promise<ItemSignature> {\n const statement = await promptStatement(app, prompt, at);\n return this.sign(\n presence ? this.presence : this.signing,\n statementBytes(statement),\n presence ? \"user\" : \"none\",\n at,\n );\n }\n\n async signAnswer(\n app: string,\n answer: AnswerToSign,\n at: number,\n presence: boolean,\n ): Promise<ItemSignature> {\n const statement = await answerStatement(app, answer, at);\n return this.sign(\n presence ? this.presence : this.signing,\n statementBytes(statement),\n presence ? \"user\" : \"none\",\n at,\n );\n }\n\n /** This device's vouch for `device`, signed with its presence key unless `presence` is false. */\n async vouchFor(\n app: string,\n device: DeviceKeys,\n at: number,\n options: { readonly presence?: boolean; readonly commitment?: string } = {},\n ): Promise<DeviceVouch> {\n const commitment =\n options.commitment ??\n (await deviceCommitment(\n app,\n device.id,\n device.signingKey,\n device.presenceKey?.publicKey,\n ));\n const presence = options.presence ?? true;\n const { signature } = await this.sign(\n presence ? this.presence : this.signing,\n statementBytes(vouchStatement(app, this.id, device.id, commitment, at)),\n presence ? \"user\" : \"none\",\n at,\n );\n return { voucher: this.id, commitment, at, signature };\n }\n}\n\nexport interface StubApp {\n readonly origin: string;\n readonly seen: {\n readonly method: string;\n readonly path: string;\n readonly body: string;\n }[];\n close(): Promise<void>;\n}\n\nexport type Route = (\n request: IncomingMessage,\n body: string,\n response: ServerResponse,\n) => boolean;\n\nexport async function stubApp(route: Route): Promise<StubApp> {\n const seen: StubApp[\"seen\"][number][] = [];\n const server: Server = createHttpServer((request, response) => {\n let body = \"\";\n request.setEncoding(\"utf8\");\n request.on(\"data\", (chunk: string) => (body += chunk));\n request.on(\"end\", () => {\n const path = new URL(request.url ?? \"/\", \"http://stub\").pathname;\n seen.push({ method: request.method ?? \"GET\", path, body });\n if (!route(request, body, response)) response.writeHead(404).end();\n });\n });\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n return {\n origin: `http://127.0.0.1:${(server.address() as AddressInfo).port}`,\n seen,\n close: () =>\n new Promise((resolve) => {\n server.closeAllConnections();\n server.close(() => resolve());\n }),\n };\n}\n\nexport const json = (response: ServerResponse, value: unknown, status = 200) =>\n response\n .writeHead(status, { \"content-type\": \"application/json\" })\n .end(JSON.stringify(value));\n\nexport const welcome = {\n id: \"h\",\n accepted: true,\n protocol: HOST_PROTOCOL,\n leaseMs: 60_000,\n heartbeatMs: 30_000,\n};\n\nexport function hostRoutes(options: {\n readonly wake: boolean;\n readonly turn?: () => unknown;\n}): Route {\n let claimed = false;\n return (request, body, response) => {\n const path = new URL(request.url ?? \"/\", \"http://stub\").pathname;\n const action = path.startsWith(\"/_parlor/chat/actions/\")\n ? path.split(\"/\").at(-1)\n : undefined;\n if (action === \"hostHello\")\n return (json(response, { data: welcome, tags: [] }), true);\n if (action === \"hostClaim\") {\n if (options.turn && !claimed) {\n claimed = true;\n return (json(response, { data: options.turn(), tags: [] }), true);\n }\n return (\n json(response, { error: { code: \"not_found\", message: \"No turn.\" } }, 404), true\n );\n }\n if (action === \"hostSignals\") return (json(response, { data: [], tags: [] }), true);\n if (action) {\n return (\n json(response, {\n data: {\n id: \"t1\",\n leaseUntil: Date.now() + 60_000,\n token: { token: \"turn-2\", expiresAt: Date.now() + 60_000 },\n },\n tags: [],\n }),\n true\n );\n }\n if (path === \"/_parlor/sync/token\") {\n return (\n json(response, {\n protocol: 1,\n transport: \"sse\",\n endpoint: \"/_parlor/sync/stream\",\n pollIntervalMs: 2_000,\n }),\n true\n );\n }\n if (path === \"/_parlor/sync/stream\") {\n response.writeHead(200, { \"content-type\": \"text/event-stream\" });\n response.write(\n `event: handshake\\ndata: ${JSON.stringify({ capabilities: [], keepAliveMs: 10_000 })}\\n\\n`,\n );\n if (options.wake) {\n const events = [{ version: 1, id: \"e1\", tags: [[\"parlor_chat\", \"t1\"]] }];\n response.write(\n `event: message\\ndata: ${JSON.stringify({ events, cursor: \"1.e1\" })}\\n\\n`,\n );\n }\n return true;\n }\n if (path === \"/_parlor/mcp\") {\n const message = JSON.parse(body) as { id?: number; method: string };\n if (message.id === undefined) return (response.writeHead(202).end(), true);\n const result =\n message.method === \"initialize\"\n ? {\n protocolVersion: \"2025-06-18\",\n capabilities: { tools: {} },\n serverInfo: { name: \"stub\", version: \"1\" },\n }\n : message.method === \"tools/list\"\n ? { tools: [] }\n : { content: [{ type: \"text\", text: \"[]\" }] };\n return (json(response, { jsonrpc: \"2.0\", id: message.id, result }), true);\n }\n return false;\n };\n}\n\nexport const claimedTurn = (\n turnId: string,\n agentId: string,\n context: string,\n text: string,\n) => ({\n id: \"t1\",\n turnId,\n agent: { hostId: \"h-A\", agentId },\n clientId: \"tab\",\n prompt: {\n id: `p-${turnId}`,\n threadId: \"t1\",\n turnId,\n seq: 1,\n at: Date.now(),\n author: \"user\",\n kind: \"prompt\",\n body: { text, agent: { hostId: \"h-A\", agentId } },\n },\n device: undefined,\n context,\n token: { token: \"turn-1\", expiresAt: Date.now() + 60_000 },\n leaseUntil: Date.now() + 60_000,\n});\n\nexport const grantFor = (origin: string, name: string, workspace: string): AppGrant => ({\n appOrigin: origin,\n appName: name,\n grantId: asId(\"grant\", `host:${name}`),\n hostId: asId(\"host\", `h-${name}`),\n account: { userId: asId(\"user\", \"alice\"), name: \"Alice\", email: \"alice@example.com\" },\n workspace,\n createdAt: 1,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"spec-kit.js","sourceRoot":"","sources":["../src/spec-kit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,YAAY,IAAI,gBAAgB,GAIjC,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,aAAa,GAGd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,YAAY,GAIb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI/C,MAAM,CAAC,MAAM,QAAQ,GAAG,8BAA8B,CAAC;AAEvD,MAAM,MAAM,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzF,MAAM,OAAO,OAAO;IAGG,MAAM;IAFlB,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE9C,YAAqB,MAAc;sBAAd,MAAM;IAAW,CAAC;IAEvC,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,IAAI,GAAgB,EAAE;QAC7C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACT,QAAQ,EACR,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACzE,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;YACtD,GAAG,IAAI;YACP,OAAO;YACP,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,EAAE,GAAG,IAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,4FAA4F;IAC5F,KAAK,CAAC,OAAO,CACX,GAAW,EACX,QAA8B,EAC9B,OAAO,GAAsB,EAAE;QAK/B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,eAAe,CAChC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,uDAAuD,CAAC,CAAC,CAAC,GAAG,CAC7E,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAC3D,CACF,CAAC;QACF,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CACzC,iEAAiE,CAClE,EAAE,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAK,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,IAAK,EAAE,KAAM,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACtC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;SACxB,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;CACF;AASD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,QAAQ,GAAmB,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IAChF,IAAI,MAAmC,CAAC;IACxC,MAAM,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,EAAE,CAAC;QACP,QAAQ,EAAE,WAAW;QACrB,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAO,CAAC,KAAK,CAAC,OAAO,CAAC;KAC3C,CAAC,CAAC;IACH,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAI,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,WAAW,GAAG,UAAU,CAAC;QAC7B,MAAM;QACN,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,mDAAmD;QAC3D,gBAAgB,EAAE;YAChB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE;gBACR,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACrD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;aAC3E;SACF;KACF,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACtE,KAAK,CAAC,SAAS;QACf,EAAE;KACH,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,UAAU,CAAC;QAC1B,GAAG,WAAW;QACd,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;KACpD,CAAC,CAAC;IACH,MAAM,GAAG,YAAY,CAAC;QACpB,OAAO,EAAE,cAAc,CAAC;YACtB,SAAS,EAAE,YAAY,CAAC;gBACtB,WAAW,EAAE,aAAa;gBAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnB,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;aACd,CAAC;SACH,CAAC;QACF,IAAI,EAAE,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC3B,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC;YAC/C,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;SAClF;KACF,CAAC,CAAC;IACH,OAAO;QACL,MAAM;QACN,MAAM;QACN,KAAK,CAAC,MAAM,CAAC,IAAI;YACf,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE;gBAClE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,IAAI;oBACJ,KAAK,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc;oBAC1C,QAAQ,EAAE,QAAQ;iBACnB,CAAC;aACH,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACpF,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,MAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc;IAG5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAA4D,CAAC;IACjF,MAAM,IAAI,GAAG,CAAC,GAAc,EAAE,EAAE,CAAC,KAAK,EAAE,OAAmB,EAAE,EAAE,CAC7D,MAAM,CAAC,IAAI,CACT,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CACtB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,GAAG,EACH,IAAI,UAAU,CAAC,OAAO,CAAC,CACxB,CACF,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1B,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,CAAC,MAAM,CAAC,SAAS;YACpB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,CAC1C,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,KAAK,EACL,CAAC,MAAM,EAAE,QAAQ,CAAC,CACnB,CAAC;YACF,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAChF,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,GAAI,EAAE,GAAG,EAAE,GAAI,EAAE,CAAC,EAAE,CAAE,EAAE,CAAC,EAAE,CAAE,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC;iBACpC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;iBAC1C,MAAM,CAAC,WAAW,CAAC,CAAC;YACvB,OAAO;gBACL,SAAS;gBACT,UAAU;gBACV,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;gBAC3B,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBACtB,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC1E,CAAC;aACF,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO;YAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;YACrD,OAAO,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACpD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,SAAS;YACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,SAAiB,EAAE,QAAgB,EAAE,EAAE,CAAC,GAAG,SAAS,KAAK,QAAQ,EAAE,CAAC;IACnF,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAChC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC1E,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CACxB,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC;aACnD,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC;QAChC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAC/B,KAAK,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAC5D,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;YACpC,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBACrC,IACE,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,IAAI,CAAC;oBAChC,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC,EACzD,CAAC;oBACD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAW,CAAC;AAE1D,MAAM,OAAO,UAAU;IAEV,IAAI;IACI,OAAO;IACP,QAAQ;IAH3B,YACW,IAAgB,EACR,OAAkB,EAClB,QAAmB;oBAF3B,IAAI;uBACI,OAAO;wBACP,QAAQ;IACxB,CAAC;IAEJ,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,EAAE,GAAG,UAAU,EACf,IAAI,GAAG,iBAAiB,EACxB,QAAQ,GAAG,KAAK;QAEhB,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;YACtB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,CAC1C,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,IAAI,EACJ,CAAC,MAAM,EAAE,QAAQ,CAAC,CACnB,CAAC;YACF,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAChF,OAAO;gBACL,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,SAAS,EAAE,EAAE,GAAG,EAAE,GAAI,EAAE,GAAG,EAAE,GAAI,EAAE,CAAC,EAAE,CAAE,EAAE,CAAC,EAAE,CAAE,EAAE;aAClD,CAAC;QACJ,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,UAAU,CACnB;YACE,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACtB,IAAI;YACJ,QAAQ;YACR,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,WAAW,EAAE;gBACX,MAAM,EAAE,WAAW;gBACnB,KAAK,EAAE,UAAU;gBACjB,SAAS,EAAE,QAAQ,CAAC,SAAS;aAC9B;SACF,EACD,OAAO,CAAC,UAAU,EAClB,QAAQ,CAAC,UAAU,CACpB,CAAC;IACJ,CAAC;IAED,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,IAAI,CAChB,GAAc,EACd,KAAiB,EACjB,QAAyB,EACzB,EAAU;QAEV,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9E,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,EAAE;YACjB,EAAE;YACF,SAAS,EAAE;gBACT,KAAK,EAAE,KAAK;gBACZ,QAAQ;gBACR,MAAM,EAAE,WAAW;gBACnB,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;aACxD;SACsB,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,UAAU,CACd,GAAW,EACX,MAAoB,EACpB,EAAU,EACV,QAAQ,GAAG,KAAK;QAEhB,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,IAAI,CACd,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EACvC,cAAc,CAAC,SAAS,CAAC,EACzB,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAC1B,EAAE,CACH,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CACd,GAAW,EACX,MAAoB,EACpB,EAAU,EACV,QAAiB;QAEjB,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,IAAI,CACd,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EACvC,cAAc,CAAC,SAAS,CAAC,EACzB,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAC1B,EAAE,CACH,CAAC;IACJ,CAAC;IAED,iGAAiG;IACjG,KAAK,CAAC,QAAQ,CACZ,GAAW,EACX,MAAkB,EAClB,EAAU,EACV,OAAO,GAAkE,EAAE;QAE3E,MAAM,UAAU,GACd,OAAO,CAAC,UAAU;YAClB,CAAC,MAAM,gBAAgB,CACrB,GAAG,EACH,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,WAAW,EAAE,SAAS,CAC9B,CAAC,CAAC;QACL,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CACnC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EACvC,cAAc,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,EACvE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAC1B,EAAE,CACH,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;IACzD,CAAC;CACF;AAkBD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAY;IACxC,MAAM,IAAI,GAA8B,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAW,gBAAgB,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC5D,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACrB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC;gBAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7E,OAAO;QACL,MAAM,EAAE,oBAAqB,MAAM,CAAC,OAAO,EAAkB,CAAC,IAAI,EAAE;QACpE,IAAI;QACJ,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACtB,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC;KACL,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,QAAwB,EAAE,KAAc,EAAE,MAAM,GAAG,GAAG,EAAE,EAAE,CAC7E,QAAQ;KACL,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;KACzD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,EAAE,EAAE,GAAG;IACP,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,aAAa;IACvB,OAAO,EAAE,MAAM;IACf,WAAW,EAAE,MAAM;CACpB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,OAK1B;IACC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC;QACjE,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC;YACtD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,MAAM,KAAK,WAAW;YACxB,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC7B,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,CACL,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,CACjF,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACpF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CACL,IAAI,CAAC,QAAQ,EAAE;gBACb,IAAI,EAAE;oBACJ,EAAE,EAAE,IAAI;oBACR,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM;oBAC/B,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE;iBAC3D;gBACD,IAAI,EAAE,EAAE;aACT,CAAC;gBACF,IAAI,CACL,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;YACnC,OAAO,CACL,IAAI,CAAC,QAAQ,EAAE;gBACb,QAAQ,EAAE,CAAC;gBACX,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,sBAAsB;gBAChC,cAAc,EAAE,KAAK;aACtB,CAAC;gBACF,IAAI,CACL,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;YACpC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACjE,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,QAAQ,CAAC,KAAK,CACZ,2BAA2B,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,MAAM,CACvF,CAAC;YACF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBACxD,QAAQ,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpE,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;gBACzE,QAAQ,CAAC,KAAK,CACZ,yBAAyB,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,CAC1E,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAoC,CAAC;YACpE,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS;gBAAE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;YAC3E,MAAM,MAAM,GACV,OAAO,CAAC,MAAM,KAAK,YAAY;gBAC7B,CAAC,CAAC;oBACE,eAAe,EAAE,YAAY;oBAC7B,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC3B,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE;iBAC3C;gBACH,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,YAAY;oBAC/B,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;oBACf,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAAc,EACd,OAAe,EACf,OAAe,EACf,IAAY,EACZ,EAAE,CAAC,CAAC;IACJ,EAAE,EAAE,IAAI;IACR,MAAM;IACN,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE;IACjC,QAAQ,EAAE,KAAK;IACf,MAAM,EAAE;QACN,EAAE,EAAE,KAAK,MAAM,EAAE;QACjB,QAAQ,EAAE,IAAI;QACd,MAAM;QACN,GAAG,EAAE,CAAC;QACN,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;QACd,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;KAClD;IACD,MAAM,EAAE,SAAS;IACjB,OAAO;IACP,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE;IAC1D,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,SAAiB,EAAY,EAAE,CAAC,CAAC;IACtF,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;IACtC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;IACjC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE;IACrF,SAAS;IACT,SAAS,EAAE,CAAC;CACb,CAAC,CAAC","sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n createServer as createHttpServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport {\n answerStatement,\n betterAuthProvider,\n deviceCommitment,\n parlorAuth,\n promptStatement,\n statementBytes,\n vouchStatement,\n} from \"@parlor/auth\";\nimport {\n type AnswerToSign,\n HOST_PROTOCOL,\n type ItemSignature,\n type PromptToSign,\n} from \"@parlor/chat\";\nimport { chat } from \"@parlor/chat/server\";\nimport { asId, defineAction } from \"@parlor/core\";\nimport { createRegistry } from \"@parlor/core/registry\";\nimport { createDatabase, type DatabaseHandle } from \"@parlor/data\";\nimport {\n createServer,\n type DeviceKeys,\n type DeviceVouch,\n type FrameworkServer,\n} from \"@parlor/server\";\nimport { betterAuth } from \"better-auth\";\nimport { memoryAdapter } from \"better-auth/adapters/memory\";\nimport { getAuthTables } from \"better-auth/db\";\nimport { serve } from \"srvx\";\nimport { z } from \"zod\";\n\nimport { hostAssertion } from \"./assertion.js\";\nimport type { AppGrant, HostKeys } from \"./grants.js\";\nimport type { TrustedDevice, TrustStore } from \"./trust.js\";\n\nexport const PASSWORD = \"correct horse battery staple\";\n\nconst digest = (password: string) => createHash(\"sha256\").update(password).digest(\"hex\");\n\nexport class Browser {\n readonly #cookies = new Map<string, string>();\n\n constructor(readonly origin: string) {}\n\n async fetch(url: string, init: RequestInit = {}): Promise<Response> {\n const headers = new Headers(init.headers);\n if (this.#cookies.size > 0) {\n headers.set(\n \"cookie\",\n [...this.#cookies].map(([name, value]) => `${name}=${value}`).join(\"; \"),\n );\n }\n if (init.method === \"POST\" && !headers.has(\"origin\"))\n headers.set(\"origin\", this.origin);\n const response = await fetch(new URL(url, this.origin), {\n ...init,\n headers,\n redirect: \"manual\",\n });\n for (const cookie of response.headers.getSetCookie()) {\n const [pair] = cookie.split(\";\");\n const at = pair!.indexOf(\"=\");\n this.#cookies.set(pair!.slice(0, at), pair!.slice(at + 1));\n }\n return response;\n }\n\n /** Answers the consent page as a browser would, sending its checked boxes but `uncheck`. */\n async consent(\n url: string,\n decision: \"connect\" | \"cancel\",\n uncheck: readonly string[] = [],\n ): Promise<{\n readonly page: string;\n readonly answer: Response;\n }> {\n const page = await (await this.fetch(url)).text();\n const fields = new URLSearchParams(\n [...page.matchAll(/<input type=\"hidden\" name=\"([^\"]+)\" value=\"([^\"]*)\">/g)].map(\n (match) => [match[1]!, match[2]!.replaceAll(\"&\", \"&\")],\n ),\n );\n for (const [, name, value] of page.matchAll(\n /<input type=\"checkbox\" name=\"([^\"]+)\" value=\"([^\"]*)\" checked>/g,\n )) {\n if (!uncheck.includes(name!)) fields.set(name!, value!);\n }\n fields.set(\"decision\", decision);\n const action = /<form method=\"post\" action=\"([^\"]+)\"/.exec(page)?.[1] ?? \"\";\n const answer = await this.fetch(action, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: fields.toString(),\n });\n return { page, answer };\n }\n}\n\nexport interface SpecApp {\n readonly origin: string;\n readonly server: FrameworkServer;\n signUp(name: string): Promise<Browser>;\n close(): Promise<void>;\n}\n\nexport async function startSpecApp(): Promise<SpecApp> {\n const database: DatabaseHandle = await createDatabase({ dataDir: \"memory://\" });\n let server: FrameworkServer | undefined;\n const listener = serve({\n port: 0,\n hostname: \"127.0.0.1\",\n silent: true,\n fetch: (request) => server!.fetch(request),\n });\n await listener.ready();\n const origin = new URL(listener.url!).origin;\n const authOptions = parlorAuth({\n origin,\n signInPage: \"/sign-in\",\n appName: \"Hello\",\n secret: \"a-test-secret-that-is-long-enough-for-better-auth\",\n emailAndPassword: {\n enabled: true,\n password: {\n hash: (password) => Promise.resolve(digest(password)),\n verify: ({ hash, password }) => Promise.resolve(digest(password) === hash),\n },\n },\n });\n const tables = Object.values(getAuthTables(authOptions)).map((table) => [\n table.modelName,\n [],\n ]);\n const instance = betterAuth({\n ...authOptions,\n database: memoryAdapter(Object.fromEntries(tables)),\n });\n server = createServer({\n actions: createRegistry({\n listTasks: defineAction({\n description: \"List tasks.\",\n input: z.object({}),\n run: () => [],\n }),\n }),\n auth: betterAuthProvider({ instance }),\n plugins: [chat()],\n database: {\n read: () => database.read(),\n transaction: (run) => database.transaction(run),\n listen: (channel, handler, options) => database.listen(channel, handler, options),\n },\n });\n return {\n origin,\n server,\n async signUp(name) {\n const browser = new Browser(origin);\n const response = await browser.fetch(\"/_parlor/auth/sign-up/email\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n name,\n email: `${name.toLowerCase()}@example.com`,\n password: PASSWORD,\n }),\n });\n if (response.status !== 200) throw new Error(`sign-up answered ${response.status}`);\n return browser;\n },\n async close() {\n await listener.close(true);\n await server!.close();\n },\n };\n}\n\nexport function memoryHostKeys(): HostKeys & {\n readonly origins: () => readonly string[];\n} {\n const kept = new Map<string, { key: CryptoKey; kid: string; grantId: string }>();\n const sign = (key: CryptoKey) => async (payload: Uint8Array) =>\n Buffer.from(\n await crypto.subtle.sign(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n key,\n new Uint8Array(payload),\n ),\n ).toString(\"base64url\");\n return {\n origins: () => [...kept.keys()],\n async create(appOrigin) {\n const pair = await crypto.subtle.generateKey(\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"sign\", \"verify\"],\n );\n const { kty, crv, x, y } = await crypto.subtle.exportKey(\"jwk\", pair.publicKey);\n const publicKey = { kty: kty!, crv: crv!, x: x!, y: y! };\n const thumbprint = createHash(\"sha256\")\n .update(JSON.stringify({ crv, kty, x, y }))\n .digest(\"base64url\");\n return {\n publicKey,\n thumbprint,\n sign: sign(pair.privateKey),\n keep: async (grantId) => {\n kept.set(appOrigin, { key: pair.privateKey, kid: thumbprint, grantId });\n },\n };\n },\n async assert(appOrigin, request) {\n const key = kept.get(appOrigin);\n if (!key) throw new Error(`no key for ${appOrigin}`);\n return hostAssertion(sign(key.key), key, request);\n },\n async remove(appOrigin) {\n kept.delete(appOrigin);\n },\n };\n}\n\nexport function memoryTrust(): TrustStore & { readonly pins: () => TrustedDevice[] } {\n const pinned = new Map<string, TrustedDevice>();\n const keyOf = (appOrigin: string, deviceId: string) => `${appOrigin}\\n${deviceId}`;\n return {\n pins: () => [...pinned.values()],\n get: async (appOrigin, deviceId) => pinned.get(keyOf(appOrigin, deviceId)),\n list: async (appOrigin) =>\n [...pinned.entries()]\n .filter(([key]) => key.startsWith(`${appOrigin}\\n`))\n .map(([, device]) => device),\n pin: async (appOrigin, device) =>\n void pinned.set(keyOf(appOrigin, device.deviceId), device),\n forget: async (appOrigin, deviceId) => {\n for (const key of [...pinned.keys()]) {\n if (\n key.startsWith(`${appOrigin}\\n`) &&\n (deviceId === undefined || key.endsWith(`\\n${deviceId}`))\n ) {\n pinned.delete(key);\n }\n }\n },\n };\n}\n\nconst ES256 = { name: \"ECDSA\", hash: \"SHA-256\" } as const;\n\nexport class TestDevice {\n private constructor(\n readonly keys: DeviceKeys,\n private readonly signing: CryptoKey,\n private readonly presence: CryptoKey,\n ) {}\n\n static async create(\n id = \"device-1\",\n name = \"Chrome on macOS\",\n platform = \"web\",\n ): Promise<TestDevice> {\n const make = async () => {\n const pair = await crypto.subtle.generateKey(\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n true,\n [\"sign\", \"verify\"],\n );\n const { kty, crv, x, y } = await crypto.subtle.exportKey(\"jwk\", pair.publicKey);\n return {\n privateKey: pair.privateKey,\n publicKey: { kty: kty!, crv: crv!, x: x!, y: y! },\n };\n };\n const [signing, presence] = [await make(), await make()];\n return new TestDevice(\n {\n id: asId(\"device\", id),\n name,\n platform,\n signingKey: signing.publicKey,\n presenceKey: {\n format: \"es256-raw\",\n keyId: \"presence\",\n publicKey: presence.publicKey,\n },\n },\n signing.privateKey,\n presence.privateKey,\n );\n }\n\n get id() {\n return this.keys.id;\n }\n\n private async sign(\n key: CryptoKey,\n bytes: Uint8Array,\n presence: \"none\" | \"user\",\n at: number,\n ) {\n const signature = await crypto.subtle.sign(ES256, key, new Uint8Array(bytes));\n return {\n deviceId: this.id,\n at,\n signature: {\n keyId: \"key\",\n presence,\n format: \"es256-raw\",\n signature: Buffer.from(signature).toString(\"base64url\"),\n },\n } satisfies ItemSignature;\n }\n\n async signPrompt(\n app: string,\n prompt: PromptToSign,\n at: number,\n presence = false,\n ): Promise<ItemSignature> {\n const statement = await promptStatement(app, prompt, at);\n return this.sign(\n presence ? this.presence : this.signing,\n statementBytes(statement),\n presence ? \"user\" : \"none\",\n at,\n );\n }\n\n async signAnswer(\n app: string,\n answer: AnswerToSign,\n at: number,\n presence: boolean,\n ): Promise<ItemSignature> {\n const statement = await answerStatement(app, answer, at);\n return this.sign(\n presence ? this.presence : this.signing,\n statementBytes(statement),\n presence ? \"user\" : \"none\",\n at,\n );\n }\n\n /** This device's vouch for `device`, signed with its presence key unless `presence` is false. */\n async vouchFor(\n app: string,\n device: DeviceKeys,\n at: number,\n options: { readonly presence?: boolean; readonly commitment?: string } = {},\n ): Promise<DeviceVouch> {\n const commitment =\n options.commitment ??\n (await deviceCommitment(\n app,\n device.id,\n device.signingKey,\n device.presenceKey?.publicKey,\n ));\n const presence = options.presence ?? true;\n const { signature } = await this.sign(\n presence ? this.presence : this.signing,\n statementBytes(vouchStatement(app, this.id, device.id, commitment, at)),\n presence ? \"user\" : \"none\",\n at,\n );\n return { voucher: this.id, commitment, at, signature };\n }\n}\n\nexport interface StubApp {\n readonly origin: string;\n readonly seen: {\n readonly method: string;\n readonly path: string;\n readonly body: string;\n }[];\n close(): Promise<void>;\n}\n\nexport type Route = (\n request: IncomingMessage,\n body: string,\n response: ServerResponse,\n) => boolean;\n\nexport async function stubApp(route: Route): Promise<StubApp> {\n const seen: StubApp[\"seen\"][number][] = [];\n const server: Server = createHttpServer((request, response) => {\n let body = \"\";\n request.setEncoding(\"utf8\");\n request.on(\"data\", (chunk: string) => (body += chunk));\n request.on(\"end\", () => {\n const path = new URL(request.url ?? \"/\", \"http://stub\").pathname;\n seen.push({ method: request.method ?? \"GET\", path, body });\n if (!route(request, body, response)) response.writeHead(404).end();\n });\n });\n await new Promise<void>((resolve) => server.listen(0, \"127.0.0.1\", resolve));\n return {\n origin: `http://127.0.0.1:${(server.address() as AddressInfo).port}`,\n seen,\n close: () =>\n new Promise((resolve) => {\n server.closeAllConnections();\n server.close(() => resolve());\n }),\n };\n}\n\nexport const json = (response: ServerResponse, value: unknown, status = 200) =>\n response\n .writeHead(status, { \"content-type\": \"application/json\" })\n .end(JSON.stringify(value));\n\nexport const welcome = {\n id: \"h\",\n accepted: true,\n protocol: HOST_PROTOCOL,\n leaseMs: 60_000,\n heartbeatMs: 30_000,\n};\n\nexport function hostRoutes(options: {\n readonly wake: boolean;\n readonly turn?: () => unknown;\n /** Pushed on the stream's `chat` channel, as a server on host protocol 3 does. */\n readonly push?: () => unknown;\n}): Route {\n let claimed = false;\n return (request, body, response) => {\n const path = new URL(request.url ?? \"/\", \"http://stub\").pathname;\n const action = path.startsWith(\"/_parlor/chat/actions/\")\n ? path.split(\"/\").at(-1)\n : undefined;\n if (action === \"hostHello\")\n return (json(response, { data: welcome, tags: [] }), true);\n if (action === \"hostClaim\") {\n if (options.turn && !claimed) {\n claimed = true;\n return (json(response, { data: options.turn(), tags: [] }), true);\n }\n return (\n json(response, { error: { code: \"not_found\", message: \"No turn.\" } }, 404), true\n );\n }\n if (action === \"hostSignals\") return (json(response, { data: [], tags: [] }), true);\n if (action) {\n return (\n json(response, {\n data: {\n id: \"t1\",\n leaseUntil: Date.now() + 60_000,\n token: { token: \"turn-2\", expiresAt: Date.now() + 60_000 },\n },\n tags: [],\n }),\n true\n );\n }\n if (path === \"/_parlor/sync/token\") {\n return (\n json(response, {\n protocol: 1,\n transport: \"sse\",\n endpoint: \"/_parlor/sync/stream\",\n pollIntervalMs: 2_000,\n }),\n true\n );\n }\n if (path === \"/_parlor/sync/stream\") {\n response.writeHead(200, { \"content-type\": \"text/event-stream\" });\n const capabilities = options.push ? [\"chat\"] : [];\n response.write(\n `event: handshake\\ndata: ${JSON.stringify({ capabilities, keepAliveMs: 10_000 })}\\n\\n`,\n );\n if (options.push) {\n const frame = { type: \"claimed\", turn: options.push() };\n response.write(`event: chat\\ndata: ${JSON.stringify(frame)}\\n\\n`);\n }\n if (options.wake) {\n const events = [{ version: 1, id: \"e1\", tags: [[\"parlor_chat\", \"t1\"]] }];\n response.write(\n `event: message\\ndata: ${JSON.stringify({ events, cursor: \"1.e1\" })}\\n\\n`,\n );\n }\n return true;\n }\n if (path === \"/_parlor/mcp\") {\n const message = JSON.parse(body) as { id?: number; method: string };\n if (message.id === undefined) return (response.writeHead(202).end(), true);\n const result =\n message.method === \"initialize\"\n ? {\n protocolVersion: \"2025-06-18\",\n capabilities: { tools: {} },\n serverInfo: { name: \"stub\", version: \"1\" },\n }\n : message.method === \"tools/list\"\n ? { tools: [] }\n : { content: [{ type: \"text\", text: \"[]\" }] };\n return (json(response, { jsonrpc: \"2.0\", id: message.id, result }), true);\n }\n return false;\n };\n}\n\nexport const claimedTurn = (\n turnId: string,\n agentId: string,\n context: string,\n text: string,\n) => ({\n id: \"t1\",\n turnId,\n agent: { hostId: \"h-A\", agentId },\n clientId: \"tab\",\n prompt: {\n id: `p-${turnId}`,\n threadId: \"t1\",\n turnId,\n seq: 1,\n at: Date.now(),\n author: \"user\",\n kind: \"prompt\",\n body: { text, agent: { hostId: \"h-A\", agentId } },\n },\n device: undefined,\n context,\n token: { token: \"turn-1\", expiresAt: Date.now() + 60_000 },\n leaseUntil: Date.now() + 60_000,\n});\n\nexport const grantFor = (origin: string, name: string, workspace: string): AppGrant => ({\n appOrigin: origin,\n appName: name,\n grantId: asId(\"grant\", `host:${name}`),\n hostId: asId(\"host\", `h-${name}`),\n account: { userId: asId(\"user\", \"alice\"), name: \"Alice\", email: \"alice@example.com\" },\n workspace,\n createdAt: 1,\n});\n"]}
|