@agimon-ai/doompi-sandbox 0.0.1-alpha.78 → 0.0.1-alpha.80
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/{src/schemas/apiContracts.cjs → apiContracts.cjs} +5 -1
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/{src/schemas/apiContracts.d.mts.map → apiContracts.d.mts.map} +1 -1
- package/dist/{src/schemas/apiContracts.mjs → apiContracts.mjs} +1 -1
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/brokerHost-BSb-qpbK.mjs +302 -0
- package/dist/brokerHost-BSb-qpbK.mjs.map +1 -0
- package/dist/brokerHost-D-hLs18x.cjs +340 -0
- package/dist/brokerHost-D-hLs18x.cjs.map +1 -0
- package/dist/{src/services/cockpitHarness/index.cjs → cockpitHarness.cjs} +110 -15
- package/dist/cockpitHarness.cjs.map +1 -0
- package/dist/{src/services/cockpitHarness/index.d.cts → cockpitHarness.d.mts} +12 -5
- package/dist/cockpitHarness.d.mts.map +1 -0
- package/dist/{src/services/cockpitHarness/index.mjs → cockpitHarness.mjs} +101 -7
- package/dist/cockpitHarness.mjs.map +1 -0
- package/dist/{src/services/extensionService/index.cjs → extensionService-BnIZjdJN.cjs} +9 -4
- package/dist/extensionService-BnIZjdJN.cjs.map +1 -0
- package/dist/{src/services/extensionService/index.mjs → extensionService-DiVpVLn9.mjs} +3 -3
- package/dist/extensionService-DiVpVLn9.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +5 -5
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.d.mts +1 -1
- package/dist/extensions/mcp.d.mts.map +1 -1
- package/dist/extensions/mcp.mjs +2 -2
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/pi.cjs +56 -12
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.mts +2 -2
- package/dist/extensions/pi.d.mts.map +1 -1
- package/dist/extensions/pi.mjs +50 -6
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +57 -11
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +1 -1
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +52 -6
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/harness-BMkPGehU.cjs +784 -0
- package/dist/harness-BMkPGehU.cjs.map +1 -0
- package/dist/harness-BWrlo9bu.mjs +715 -0
- package/dist/harness-BWrlo9bu.mjs.map +1 -0
- package/dist/index-CBt-PlVG.d.mts +22 -0
- package/dist/index-CBt-PlVG.d.mts.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.mts +1 -2
- package/dist/index.mjs +1 -1
- package/dist/{src/services/sandboxBridge/index.cjs → sandboxBridge-B3FRZkC2.cjs} +61 -11
- package/dist/sandboxBridge-B3FRZkC2.cjs.map +1 -0
- package/dist/{src/services/sandboxBridge/index.mjs → sandboxBridge-D6RAncmy.mjs} +2 -2
- package/dist/sandboxBridge-D6RAncmy.mjs.map +1 -0
- package/dist/{src/types/sandboxHarness.d.cts → sandboxHarness-BIvuRMio.d.mts} +7 -6
- package/dist/sandboxHarness-BIvuRMio.d.mts.map +1 -0
- package/dist/sandboxHarness.cjs +4 -0
- package/dist/{src/services/harness/index.d.cts → sandboxHarness.d.mts} +18 -5
- package/dist/sandboxHarness.d.mts.map +1 -0
- package/dist/sandboxHarness.mjs +2 -0
- package/dist/sandboxResources-CWIT6svf.mjs +72 -0
- package/dist/sandboxResources-CWIT6svf.mjs.map +1 -0
- package/dist/sandboxResources-CuJ5sBk1.cjs +113 -0
- package/dist/sandboxResources-CuJ5sBk1.cjs.map +1 -0
- package/package.json +23 -23
- package/dist/_virtual/_rolldown/runtime.cjs +0 -23
- package/dist/api-contracts.cjs +0 -7
- package/dist/api-contracts.d.cts +0 -2
- package/dist/api-contracts.d.mts +0 -2
- package/dist/api-contracts.mjs +0 -2
- package/dist/cockpit-harness.cjs +0 -5
- package/dist/cockpit-harness.d.cts +0 -2
- package/dist/cockpit-harness.d.mts +0 -2
- package/dist/cockpit-harness.mjs +0 -2
- package/dist/extensions/mcp.d.cts +0 -5
- package/dist/extensions/mcp.d.cts.map +0 -1
- package/dist/extensions/pi.d.cts +0 -6
- package/dist/extensions/pi.d.cts.map +0 -1
- package/dist/extensions/server.d.cts +0 -5
- package/dist/extensions/server.d.cts.map +0 -1
- package/dist/index.d.cts +0 -3
- package/dist/sandbox-harness.cjs +0 -4
- package/dist/sandbox-harness.d.cts +0 -2
- package/dist/sandbox-harness.d.mts +0 -2
- package/dist/sandbox-harness.mjs +0 -2
- package/dist/src/constants/sandbox.cjs +0 -12
- package/dist/src/constants/sandbox.cjs.map +0 -1
- package/dist/src/constants/sandbox.mjs +0 -9
- package/dist/src/constants/sandbox.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/piRoot.cjs +0 -9
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/piRoot.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/piRoot.mjs +0 -9
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/piRoot.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxCommands.cjs +0 -32
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxCommands.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxCommands.mjs +0 -31
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxCommands.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.cjs +0 -9
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.mjs +0 -9
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxResources.cjs +0 -41
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxResources.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxResources.mjs +0 -39
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/sandboxResources.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.cjs +0 -41
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.mjs +0 -41
- package/dist/src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.cjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.server.cjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.server.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/command/sandbox.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.cjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.cjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.cjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.cjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.cjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/root.cli.mjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.cjs +0 -7
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.cjs.map +0 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.mjs +0 -8
- package/dist/src/extensions/workspaces/sessions/(backend)/root.server.mjs.map +0 -1
- package/dist/src/schemas/apiContracts.cjs.map +0 -1
- package/dist/src/schemas/apiContracts.d.cts +0 -53
- package/dist/src/schemas/apiContracts.d.cts.map +0 -1
- package/dist/src/schemas/apiContracts.mjs.map +0 -1
- package/dist/src/services/brokerHost/index.cjs +0 -102
- package/dist/src/services/brokerHost/index.cjs.map +0 -1
- package/dist/src/services/brokerHost/index.d.cts +0 -15
- package/dist/src/services/brokerHost/index.d.cts.map +0 -1
- package/dist/src/services/brokerHost/index.d.mts +0 -15
- package/dist/src/services/brokerHost/index.d.mts.map +0 -1
- package/dist/src/services/brokerHost/index.mjs +0 -98
- package/dist/src/services/brokerHost/index.mjs.map +0 -1
- package/dist/src/services/brokerProviders/index.cjs +0 -27
- package/dist/src/services/brokerProviders/index.cjs.map +0 -1
- package/dist/src/services/brokerProviders/index.mjs +0 -27
- package/dist/src/services/brokerProviders/index.mjs.map +0 -1
- package/dist/src/services/brokerRoutes/index.cjs +0 -90
- package/dist/src/services/brokerRoutes/index.cjs.map +0 -1
- package/dist/src/services/brokerRoutes/index.mjs +0 -90
- package/dist/src/services/brokerRoutes/index.mjs.map +0 -1
- package/dist/src/services/brokerServer/index.cjs +0 -127
- package/dist/src/services/brokerServer/index.cjs.map +0 -1
- package/dist/src/services/brokerServer/index.mjs +0 -124
- package/dist/src/services/brokerServer/index.mjs.map +0 -1
- package/dist/src/services/cockpitHarness/index.cjs.map +0 -1
- package/dist/src/services/cockpitHarness/index.d.cts.map +0 -1
- package/dist/src/services/cockpitHarness/index.d.mts +0 -19
- package/dist/src/services/cockpitHarness/index.d.mts.map +0 -1
- package/dist/src/services/cockpitHarness/index.mjs.map +0 -1
- package/dist/src/services/cockpitPlan/index.cjs +0 -106
- package/dist/src/services/cockpitPlan/index.cjs.map +0 -1
- package/dist/src/services/cockpitPlan/index.d.cts +0 -9
- package/dist/src/services/cockpitPlan/index.d.cts.map +0 -1
- package/dist/src/services/cockpitPlan/index.d.mts +0 -9
- package/dist/src/services/cockpitPlan/index.d.mts.map +0 -1
- package/dist/src/services/cockpitPlan/index.mjs +0 -104
- package/dist/src/services/cockpitPlan/index.mjs.map +0 -1
- package/dist/src/services/devcontainer/index.cjs +0 -115
- package/dist/src/services/devcontainer/index.cjs.map +0 -1
- package/dist/src/services/devcontainer/index.mjs +0 -107
- package/dist/src/services/devcontainer/index.mjs.map +0 -1
- package/dist/src/services/devcontainer/runtime.cjs +0 -75
- package/dist/src/services/devcontainer/runtime.cjs.map +0 -1
- package/dist/src/services/devcontainer/runtime.mjs +0 -70
- package/dist/src/services/devcontainer/runtime.mjs.map +0 -1
- package/dist/src/services/engineProcess/index.cjs +0 -70
- package/dist/src/services/engineProcess/index.cjs.map +0 -1
- package/dist/src/services/engineProcess/index.mjs +0 -70
- package/dist/src/services/engineProcess/index.mjs.map +0 -1
- package/dist/src/services/extensionService/index.cjs.map +0 -1
- package/dist/src/services/extensionService/index.d.cts +0 -9
- package/dist/src/services/extensionService/index.d.cts.map +0 -1
- package/dist/src/services/extensionService/index.d.mts +0 -9
- package/dist/src/services/extensionService/index.d.mts.map +0 -1
- package/dist/src/services/extensionService/index.mjs.map +0 -1
- package/dist/src/services/harness/index.cjs +0 -184
- package/dist/src/services/harness/index.cjs.map +0 -1
- package/dist/src/services/harness/index.d.cts.map +0 -1
- package/dist/src/services/harness/index.d.mts +0 -25
- package/dist/src/services/harness/index.d.mts.map +0 -1
- package/dist/src/services/harness/index.mjs +0 -177
- package/dist/src/services/harness/index.mjs.map +0 -1
- package/dist/src/services/loginPorts/index.cjs +0 -31
- package/dist/src/services/loginPorts/index.cjs.map +0 -1
- package/dist/src/services/loginPorts/index.mjs +0 -29
- package/dist/src/services/loginPorts/index.mjs.map +0 -1
- package/dist/src/services/oauthCallback/index.cjs +0 -35
- package/dist/src/services/oauthCallback/index.cjs.map +0 -1
- package/dist/src/services/oauthCallback/index.mjs +0 -32
- package/dist/src/services/oauthCallback/index.mjs.map +0 -1
- package/dist/src/services/runFlags/index.cjs +0 -29
- package/dist/src/services/runFlags/index.cjs.map +0 -1
- package/dist/src/services/runFlags/index.mjs +0 -28
- package/dist/src/services/runFlags/index.mjs.map +0 -1
- package/dist/src/services/sandboxBridge/index.cjs.map +0 -1
- package/dist/src/services/sandboxBridge/index.mjs.map +0 -1
- package/dist/src/services/sandboxEnvironment/index.cjs +0 -46
- package/dist/src/services/sandboxEnvironment/index.cjs.map +0 -1
- package/dist/src/services/sandboxEnvironment/index.mjs +0 -45
- package/dist/src/services/sandboxEnvironment/index.mjs.map +0 -1
- package/dist/src/services/sandboxImage/index.cjs +0 -80
- package/dist/src/services/sandboxImage/index.cjs.map +0 -1
- package/dist/src/services/sandboxImage/index.mjs +0 -78
- package/dist/src/services/sandboxImage/index.mjs.map +0 -1
- package/dist/src/services/sandboxImageTag/index.cjs +0 -25
- package/dist/src/services/sandboxImageTag/index.cjs.map +0 -1
- package/dist/src/services/sandboxImageTag/index.mjs +0 -24
- package/dist/src/services/sandboxImageTag/index.mjs.map +0 -1
- package/dist/src/services/sandboxPlan/index.cjs +0 -107
- package/dist/src/services/sandboxPlan/index.cjs.map +0 -1
- package/dist/src/services/sandboxPlan/index.mjs +0 -106
- package/dist/src/services/sandboxPlan/index.mjs.map +0 -1
- package/dist/src/types/extension.d.cts +0 -14
- package/dist/src/types/extension.d.cts.map +0 -1
- package/dist/src/types/extension.d.mts +0 -14
- package/dist/src/types/extension.d.mts.map +0 -1
- package/dist/src/types/sandboxHarness.d.cts.map +0 -1
- package/dist/src/types/sandboxHarness.d.mts +0 -37
- package/dist/src/types/sandboxHarness.d.mts.map +0 -1
- /package/dist/{src/schemas/apiContracts.d.mts → apiContracts.d.mts} +0 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
1
5
|
//#region src/schemas/apiContracts.ts
|
|
2
6
|
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
|
-
const apiContracts = (0, require("@agimon-ai/doompi-core/
|
|
7
|
+
const apiContracts = (0, require("@agimon-ai/doompi-core/apiContracts").defineApiContract)({
|
|
4
8
|
version: 1,
|
|
5
9
|
http: [],
|
|
6
10
|
sockets: [],
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;;;;AAGA,MAAa,gBAAA,gDAAeA,CAAAA,CAAAA,kBAAAA,CAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineApiContract } from "@agimon-ai/doompi-core/
|
|
1
|
+
import { defineApiContract } from "@agimon-ai/doompi-core/apiContracts";
|
|
2
2
|
//#region src/schemas/apiContracts.ts
|
|
3
3
|
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
4
4
|
const apiContracts = defineApiContract({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/doompi-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAa,eAAe,kBAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import http from "node:http";
|
|
6
|
+
import https from "node:https";
|
|
7
|
+
//#region src/services/brokerRoutes/index.ts
|
|
8
|
+
/**
|
|
9
|
+
* Providers the broker can terminate, mirroring Pi's own provider data.
|
|
10
|
+
*
|
|
11
|
+
* Curated rather than derived: Pi keeps base URLs in package-internal JSON that
|
|
12
|
+
* carries no stability promise. A provider missing here is simply not brokered,
|
|
13
|
+
* and its credential stays on the host.
|
|
14
|
+
*/
|
|
15
|
+
const ROUTES = [
|
|
16
|
+
{
|
|
17
|
+
provider: "anthropic",
|
|
18
|
+
upstream: "https://api.anthropic.com",
|
|
19
|
+
hostKeyEnv: ["ANTHROPIC_API_KEY"]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
provider: "openai",
|
|
23
|
+
upstream: "https://api.openai.com/v1",
|
|
24
|
+
hostKeyEnv: ["OPENAI_API_KEY"]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
provider: "google",
|
|
28
|
+
upstream: "https://generativelanguage.googleapis.com/v1beta",
|
|
29
|
+
hostKeyEnv: ["GEMINI_API_KEY"]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
provider: "groq",
|
|
33
|
+
upstream: "https://api.groq.com/openai/v1",
|
|
34
|
+
hostKeyEnv: ["GROQ_API_KEY"]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
provider: "xai",
|
|
38
|
+
upstream: "https://api.x.ai/v1",
|
|
39
|
+
hostKeyEnv: ["XAI_API_KEY"]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
provider: "openrouter",
|
|
43
|
+
upstream: "https://openrouter.ai/api/v1",
|
|
44
|
+
hostKeyEnv: ["OPENROUTER_API_KEY"]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
provider: "deepseek",
|
|
48
|
+
upstream: "https://api.deepseek.com",
|
|
49
|
+
hostKeyEnv: ["DEEPSEEK_API_KEY"]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
provider: "mistral",
|
|
53
|
+
upstream: "https://api.mistral.ai",
|
|
54
|
+
hostKeyEnv: ["MISTRAL_API_KEY"]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
provider: "together",
|
|
58
|
+
upstream: "https://api.together.ai/v1",
|
|
59
|
+
hostKeyEnv: ["TOGETHER_API_KEY"]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
provider: "cerebras",
|
|
63
|
+
upstream: "https://api.cerebras.ai/v1",
|
|
64
|
+
hostKeyEnv: ["CEREBRAS_API_KEY"]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
provider: "moonshotai",
|
|
68
|
+
upstream: "https://api.moonshot.ai/v1",
|
|
69
|
+
hostKeyEnv: ["MOONSHOT_API_KEY"]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
provider: "zai",
|
|
73
|
+
upstream: "https://api.z.ai/api/coding/paas/v4",
|
|
74
|
+
hostKeyEnv: ["ZAI_API_KEY"]
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
/** Selects the providers this host can actually broker for a session. */
|
|
78
|
+
function resolveBrokeredCredentials(environment) {
|
|
79
|
+
const resolved = [];
|
|
80
|
+
for (const route of ROUTES) for (const envName of route.hostKeyEnv) {
|
|
81
|
+
const value = environment[envName]?.trim();
|
|
82
|
+
if (value) {
|
|
83
|
+
resolved.push({
|
|
84
|
+
route,
|
|
85
|
+
envName,
|
|
86
|
+
value
|
|
87
|
+
});
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return resolved;
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/services/brokerServer/index.ts
|
|
95
|
+
/** Headers a provider SDK may carry its credential in. */
|
|
96
|
+
const CREDENTIAL_HEADERS = [
|
|
97
|
+
"x-api-key",
|
|
98
|
+
"authorization",
|
|
99
|
+
"x-goog-api-key"
|
|
100
|
+
];
|
|
101
|
+
/** Query parameter some Google clients use instead of a header. */
|
|
102
|
+
const CREDENTIAL_QUERY = "key";
|
|
103
|
+
const BEARER_PREFIX = "bearer ";
|
|
104
|
+
/** Connection-scoped headers that must not cross to the upstream request. */
|
|
105
|
+
const HOP_BY_HOP = /* @__PURE__ */ new Set([
|
|
106
|
+
"connection",
|
|
107
|
+
"keep-alive",
|
|
108
|
+
"proxy-authenticate",
|
|
109
|
+
"proxy-authorization",
|
|
110
|
+
"te",
|
|
111
|
+
"trailer",
|
|
112
|
+
"transfer-encoding",
|
|
113
|
+
"upgrade",
|
|
114
|
+
"host",
|
|
115
|
+
"content-length"
|
|
116
|
+
]);
|
|
117
|
+
const PATH_PATTERN = /^\/([^/?]+)(.*)$/;
|
|
118
|
+
function matchesToken(candidate, token) {
|
|
119
|
+
const left = Buffer.from(candidate);
|
|
120
|
+
const right = Buffer.from(token);
|
|
121
|
+
return left.length === right.length && timingSafeEqual(left, right);
|
|
122
|
+
}
|
|
123
|
+
function credentialValue(headerValue) {
|
|
124
|
+
return headerValue.toLowerCase().startsWith(BEARER_PREFIX) ? headerValue.slice(7) : headerValue;
|
|
125
|
+
}
|
|
126
|
+
function withCredential(headerValue, realKey) {
|
|
127
|
+
return headerValue.toLowerCase().startsWith(BEARER_PREFIX) ? `Bearer ${realKey}` : realKey;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Rewrites the request's credential, proving the caller holds the session token.
|
|
131
|
+
*
|
|
132
|
+
* Which header carries the key differs per provider SDK, so every candidate is
|
|
133
|
+
* checked rather than assumed. Returns undefined when nothing presented the
|
|
134
|
+
* token, which is what makes an unauthenticated caller indistinguishable from a
|
|
135
|
+
* misrouted one.
|
|
136
|
+
*/
|
|
137
|
+
function swapCredential(headers, search, token, realKey) {
|
|
138
|
+
const forwarded = {};
|
|
139
|
+
let authenticated = false;
|
|
140
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
141
|
+
if (value === void 0 || HOP_BY_HOP.has(name)) continue;
|
|
142
|
+
const single = Array.isArray(value) ? value[0] : value;
|
|
143
|
+
if (CREDENTIAL_HEADERS.includes(name) && single !== void 0) {
|
|
144
|
+
if (!matchesToken(credentialValue(single), token)) return void 0;
|
|
145
|
+
forwarded[name] = withCredential(single, realKey);
|
|
146
|
+
authenticated = true;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
forwarded[name] = value;
|
|
150
|
+
}
|
|
151
|
+
const queryKey = search.get(CREDENTIAL_QUERY);
|
|
152
|
+
if (queryKey !== null) {
|
|
153
|
+
if (!matchesToken(queryKey, token)) return void 0;
|
|
154
|
+
search.set(CREDENTIAL_QUERY, realKey);
|
|
155
|
+
authenticated = true;
|
|
156
|
+
}
|
|
157
|
+
return authenticated ? forwarded : void 0;
|
|
158
|
+
}
|
|
159
|
+
function reject(response, status, message) {
|
|
160
|
+
response.writeHead(status, { "content-type": "application/json" });
|
|
161
|
+
response.end(JSON.stringify({ error: {
|
|
162
|
+
type: "doompi_broker",
|
|
163
|
+
message
|
|
164
|
+
} }));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Terminates provider calls from a sandboxed session on the host.
|
|
168
|
+
*
|
|
169
|
+
* The container never holds a real credential: it presents the session token,
|
|
170
|
+
* and only a request that proves possession of it is forwarded upstream with
|
|
171
|
+
* the host's key attached. Bodies stream in both directions so token-by-token
|
|
172
|
+
* responses are not buffered.
|
|
173
|
+
*/
|
|
174
|
+
function createBrokerServer(options) {
|
|
175
|
+
const requestUpstream = options.requestUpstream ?? https.request;
|
|
176
|
+
return http.createServer((request, response) => {
|
|
177
|
+
const match = PATH_PATTERN.exec(request.url ?? "");
|
|
178
|
+
const provider = match?.[1];
|
|
179
|
+
const credential = provider ? options.credentials.get(provider) : void 0;
|
|
180
|
+
if (!match || !credential) {
|
|
181
|
+
options.onDenied?.(`unroutable provider path ${request.url ?? ""}`);
|
|
182
|
+
reject(response, 404, "Unknown provider for this sandbox session.");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const target = new URL(`${credential.route.upstream}${match[2] || ""}`);
|
|
186
|
+
const headers = swapCredential(request.headers, target.searchParams, options.token, credential.value);
|
|
187
|
+
if (!headers) {
|
|
188
|
+
options.onDenied?.(`missing or invalid session token for ${credential.route.provider}`);
|
|
189
|
+
reject(response, 401, "This sandbox session did not present its broker token.");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const upstream = requestUpstream(target, {
|
|
193
|
+
method: request.method,
|
|
194
|
+
headers: {
|
|
195
|
+
...headers,
|
|
196
|
+
host: target.host
|
|
197
|
+
}
|
|
198
|
+
}, (upstreamResponse) => {
|
|
199
|
+
response.writeHead(upstreamResponse.statusCode ?? 502, upstreamResponse.headers);
|
|
200
|
+
upstreamResponse.pipe(response);
|
|
201
|
+
});
|
|
202
|
+
upstream.on("error", (error) => {
|
|
203
|
+
options.onDenied?.(`upstream ${credential.route.provider} failed: ${error.message}`);
|
|
204
|
+
if (!response.headersSent) reject(response, 502, "The provider could not be reached from the host.");
|
|
205
|
+
else response.destroy();
|
|
206
|
+
});
|
|
207
|
+
request.on("aborted", () => upstream.destroy());
|
|
208
|
+
request.pipe(upstream);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/services/brokerHost/index.ts
|
|
213
|
+
const SOCKET_DIRECTORY_PREFIX = "doompi-broker-";
|
|
214
|
+
const SOCKET_FILE_NAME = "broker.sock";
|
|
215
|
+
const OWNER_ONLY_DIRECTORY = 448;
|
|
216
|
+
const TOKEN_BYTES = 32;
|
|
217
|
+
const LOOPBACK = "127.0.0.1";
|
|
218
|
+
const LINUX_PLATFORM = "linux";
|
|
219
|
+
const EPHEMERAL_PORT = 0;
|
|
220
|
+
/**
|
|
221
|
+
* Starts the host-side provider broker for one sandboxed session.
|
|
222
|
+
*
|
|
223
|
+
* Answers undefined when the host holds no brokerable credential, which keeps
|
|
224
|
+
* a session that authenticates some other way on the unbrokered path instead
|
|
225
|
+
* of failing it.
|
|
226
|
+
*/
|
|
227
|
+
async function startBroker(options) {
|
|
228
|
+
const resolved = resolveBrokeredCredentials(options.environment);
|
|
229
|
+
if (resolved.length === 0) return void 0;
|
|
230
|
+
const token = randomBytes(TOKEN_BYTES).toString("base64url");
|
|
231
|
+
const server = createBrokerServer({
|
|
232
|
+
credentials: new Map(resolved.map((credential) => [credential.route.provider, credential])),
|
|
233
|
+
token,
|
|
234
|
+
onDenied: options.onDenied
|
|
235
|
+
});
|
|
236
|
+
const { endpoint, dispose } = (options.platform ?? process.platform) === LINUX_PLATFORM && options.forceLoopback !== true ? await listenOnSocket(server, options.socketDirectory) : await listenOnLoopback(server);
|
|
237
|
+
return {
|
|
238
|
+
endpoint,
|
|
239
|
+
token,
|
|
240
|
+
providers: resolved.map((credential) => credential.route.provider),
|
|
241
|
+
withheldEnv: resolved.map((credential) => credential.envName),
|
|
242
|
+
stop: () => stopBroker(server, dispose)
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Native Linux shares a kernel with the container, so a bind-mounted socket
|
|
247
|
+
* needs no port and is reachable as an ordinary file.
|
|
248
|
+
*/
|
|
249
|
+
async function listenOnSocket(server, fixedDirectory) {
|
|
250
|
+
const socketDirectory = fixedDirectory ?? fs.mkdtempSync(path.join(os.tmpdir(), SOCKET_DIRECTORY_PREFIX));
|
|
251
|
+
fs.mkdirSync(socketDirectory, { recursive: true });
|
|
252
|
+
fs.chmodSync(socketDirectory, OWNER_ONLY_DIRECTORY);
|
|
253
|
+
const socketPath = path.join(socketDirectory, SOCKET_FILE_NAME);
|
|
254
|
+
fs.rmSync(socketPath, { force: true });
|
|
255
|
+
await new Promise((resolve, reject) => {
|
|
256
|
+
server.once("error", reject);
|
|
257
|
+
server.listen(socketPath, () => resolve());
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
endpoint: {
|
|
261
|
+
transport: "unix",
|
|
262
|
+
socketDirectory
|
|
263
|
+
},
|
|
264
|
+
dispose: () => fixedDirectory ? fs.rmSync(socketPath, { force: true }) : fs.rmSync(socketDirectory, {
|
|
265
|
+
recursive: true,
|
|
266
|
+
force: true
|
|
267
|
+
})
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Everywhere else the container runs in its own virtual machine, which cannot
|
|
272
|
+
* connect to a host unix socket even when the file is shared through: the
|
|
273
|
+
* connect fails with ENOTSUP. Loopback keeps the broker off the network while
|
|
274
|
+
* still being reachable through the engine's host gateway, and the session
|
|
275
|
+
* token is what stops another local process from using it.
|
|
276
|
+
*/
|
|
277
|
+
async function listenOnLoopback(server) {
|
|
278
|
+
await new Promise((resolve, reject) => {
|
|
279
|
+
server.once("error", reject);
|
|
280
|
+
server.listen(EPHEMERAL_PORT, LOOPBACK, () => resolve());
|
|
281
|
+
});
|
|
282
|
+
const address = server.address();
|
|
283
|
+
if (address === null || typeof address === "string") throw new Error("The broker did not report a listening port.");
|
|
284
|
+
return {
|
|
285
|
+
endpoint: {
|
|
286
|
+
transport: "tcp",
|
|
287
|
+
port: address.port
|
|
288
|
+
},
|
|
289
|
+
dispose: () => void 0
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
async function stopBroker(server, dispose) {
|
|
293
|
+
await new Promise((resolve) => {
|
|
294
|
+
server.close(() => resolve());
|
|
295
|
+
server.closeAllConnections();
|
|
296
|
+
});
|
|
297
|
+
dispose();
|
|
298
|
+
}
|
|
299
|
+
//#endregion
|
|
300
|
+
export { startBroker as t };
|
|
301
|
+
|
|
302
|
+
//# sourceMappingURL=brokerHost-BSb-qpbK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brokerHost-BSb-qpbK.mjs","names":[],"sources":["../src/services/brokerRoutes/index.ts","../src/services/brokerServer/index.ts","../src/services/brokerHost/index.ts"],"sourcesContent":["export interface BrokerRoute {\n /** Pi provider name, which is also the broker's first path segment. */\n provider: string;\n /** Upstream origin plus any base path Pi's own provider data carries. */\n upstream: string;\n /** Host environment variables that may hold the real credential, in priority order. */\n hostKeyEnv: readonly string[];\n}\n\n/**\n * Providers the broker can terminate, mirroring Pi's own provider data.\n *\n * Curated rather than derived: Pi keeps base URLs in package-internal JSON that\n * carries no stability promise. A provider missing here is simply not brokered,\n * and its credential stays on the host.\n */\nconst ROUTES: readonly BrokerRoute[] = [\n { provider: 'anthropic', upstream: 'https://api.anthropic.com', hostKeyEnv: ['ANTHROPIC_API_KEY'] },\n { provider: 'openai', upstream: 'https://api.openai.com/v1', hostKeyEnv: ['OPENAI_API_KEY'] },\n { provider: 'google', upstream: 'https://generativelanguage.googleapis.com/v1beta', hostKeyEnv: ['GEMINI_API_KEY'] },\n { provider: 'groq', upstream: 'https://api.groq.com/openai/v1', hostKeyEnv: ['GROQ_API_KEY'] },\n { provider: 'xai', upstream: 'https://api.x.ai/v1', hostKeyEnv: ['XAI_API_KEY'] },\n { provider: 'openrouter', upstream: 'https://openrouter.ai/api/v1', hostKeyEnv: ['OPENROUTER_API_KEY'] },\n { provider: 'deepseek', upstream: 'https://api.deepseek.com', hostKeyEnv: ['DEEPSEEK_API_KEY'] },\n { provider: 'mistral', upstream: 'https://api.mistral.ai', hostKeyEnv: ['MISTRAL_API_KEY'] },\n { provider: 'together', upstream: 'https://api.together.ai/v1', hostKeyEnv: ['TOGETHER_API_KEY'] },\n { provider: 'cerebras', upstream: 'https://api.cerebras.ai/v1', hostKeyEnv: ['CEREBRAS_API_KEY'] },\n { provider: 'moonshotai', upstream: 'https://api.moonshot.ai/v1', hostKeyEnv: ['MOONSHOT_API_KEY'] },\n { provider: 'zai', upstream: 'https://api.z.ai/api/coding/paas/v4', hostKeyEnv: ['ZAI_API_KEY'] },\n];\n\nexport function brokerRoutes(): readonly BrokerRoute[] {\n return ROUTES;\n}\n\nexport function findBrokerRoute(provider: string): BrokerRoute | undefined {\n return ROUTES.find((route) => route.provider === provider);\n}\n\nexport interface ResolvedCredential {\n route: BrokerRoute;\n /** Environment variable the container would otherwise have received. */\n envName: string;\n value: string;\n}\n\n/** Selects the providers this host can actually broker for a session. */\nexport function resolveBrokeredCredentials(\n environment: Readonly<Record<string, string | undefined>>,\n): ResolvedCredential[] {\n const resolved: ResolvedCredential[] = [];\n for (const route of ROUTES) {\n for (const envName of route.hostKeyEnv) {\n const value = environment[envName]?.trim();\n if (value) {\n resolved.push({ route, envName, value });\n break;\n }\n }\n }\n return resolved;\n}\n","import { timingSafeEqual } from 'node:crypto';\nimport http from 'node:http';\nimport https from 'node:https';\n\nimport type { ResolvedCredential } from '../brokerRoutes';\n\n/** Headers a provider SDK may carry its credential in. */\nconst CREDENTIAL_HEADERS = ['x-api-key', 'authorization', 'x-goog-api-key'] as const;\n/** Query parameter some Google clients use instead of a header. */\nconst CREDENTIAL_QUERY = 'key';\nconst BEARER_PREFIX = 'bearer ';\n/** Connection-scoped headers that must not cross to the upstream request. */\nconst HOP_BY_HOP = new Set([\n 'connection',\n 'keep-alive',\n 'proxy-authenticate',\n 'proxy-authorization',\n 'te',\n 'trailer',\n 'transfer-encoding',\n 'upgrade',\n 'host',\n 'content-length',\n]);\nconst PATH_PATTERN = /^\\/([^/?]+)(.*)$/;\n\nexport interface BrokerServerOptions {\n /** Providers this session may reach, keyed by Pi provider name. */\n credentials: ReadonlyMap<string, ResolvedCredential>;\n /** Secret the container presents in place of a real credential. */\n token: string;\n /** Receives one line per rejected request, for host-side visibility. */\n onDenied?: (reason: string) => void;\n /** Seam for tests; defaults to the real https transport. */\n requestUpstream?: typeof https.request;\n}\n\nfunction matchesToken(candidate: string, token: string): boolean {\n const left = Buffer.from(candidate);\n const right = Buffer.from(token);\n return left.length === right.length && timingSafeEqual(left, right);\n}\n\nfunction credentialValue(headerValue: string): string {\n return headerValue.toLowerCase().startsWith(BEARER_PREFIX) ? headerValue.slice(BEARER_PREFIX.length) : headerValue;\n}\n\nfunction withCredential(headerValue: string, realKey: string): string {\n return headerValue.toLowerCase().startsWith(BEARER_PREFIX) ? `Bearer ${realKey}` : realKey;\n}\n\n/**\n * Rewrites the request's credential, proving the caller holds the session token.\n *\n * Which header carries the key differs per provider SDK, so every candidate is\n * checked rather than assumed. Returns undefined when nothing presented the\n * token, which is what makes an unauthenticated caller indistinguishable from a\n * misrouted one.\n */\nfunction swapCredential(\n headers: http.IncomingHttpHeaders,\n search: URLSearchParams,\n token: string,\n realKey: string,\n): http.OutgoingHttpHeaders | undefined {\n const forwarded: http.OutgoingHttpHeaders = {};\n let authenticated = false;\n\n for (const [name, value] of Object.entries(headers)) {\n if (value === undefined || HOP_BY_HOP.has(name)) continue;\n const single = Array.isArray(value) ? value[0] : value;\n if ((CREDENTIAL_HEADERS as readonly string[]).includes(name) && single !== undefined) {\n if (!matchesToken(credentialValue(single), token)) return undefined;\n forwarded[name] = withCredential(single, realKey);\n authenticated = true;\n continue;\n }\n forwarded[name] = value;\n }\n\n const queryKey = search.get(CREDENTIAL_QUERY);\n if (queryKey !== null) {\n if (!matchesToken(queryKey, token)) return undefined;\n search.set(CREDENTIAL_QUERY, realKey);\n authenticated = true;\n }\n\n return authenticated ? forwarded : undefined;\n}\n\nfunction reject(response: http.ServerResponse, status: number, message: string): void {\n response.writeHead(status, { 'content-type': 'application/json' });\n response.end(JSON.stringify({ error: { type: 'doompi_broker', message } }));\n}\n\n/**\n * Terminates provider calls from a sandboxed session on the host.\n *\n * The container never holds a real credential: it presents the session token,\n * and only a request that proves possession of it is forwarded upstream with\n * the host's key attached. Bodies stream in both directions so token-by-token\n * responses are not buffered.\n */\nexport function createBrokerServer(options: BrokerServerOptions): http.Server {\n const requestUpstream = options.requestUpstream ?? https.request;\n\n return http.createServer((request, response) => {\n const match = PATH_PATTERN.exec(request.url ?? '');\n const provider = match?.[1];\n const credential = provider ? options.credentials.get(provider) : undefined;\n if (!match || !credential) {\n options.onDenied?.(`unroutable provider path ${request.url ?? ''}`);\n reject(response, 404, 'Unknown provider for this sandbox session.');\n return;\n }\n\n const target = new URL(`${credential.route.upstream}${match[2] || ''}`);\n const headers = swapCredential(request.headers, target.searchParams, options.token, credential.value);\n if (!headers) {\n options.onDenied?.(`missing or invalid session token for ${credential.route.provider}`);\n reject(response, 401, 'This sandbox session did not present its broker token.');\n return;\n }\n\n const upstream = requestUpstream(\n target,\n { method: request.method, headers: { ...headers, host: target.host } },\n (upstreamResponse) => {\n response.writeHead(upstreamResponse.statusCode ?? 502, upstreamResponse.headers);\n upstreamResponse.pipe(response);\n },\n );\n upstream.on('error', (error: Error) => {\n options.onDenied?.(`upstream ${credential.route.provider} failed: ${error.message}`);\n if (!response.headersSent) reject(response, 502, 'The provider could not be reached from the host.');\n else response.destroy();\n });\n request.on('aborted', () => upstream.destroy());\n request.pipe(upstream);\n });\n}\n","import { randomBytes } from 'node:crypto';\nimport fs from 'node:fs';\nimport type http from 'node:http';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type { BrokerEndpoint } from '../../types/sandboxHarness';\nimport { resolveBrokeredCredentials } from '../brokerRoutes';\nimport { createBrokerServer } from '../brokerServer';\n\nconst SOCKET_DIRECTORY_PREFIX = 'doompi-broker-';\nconst SOCKET_FILE_NAME = 'broker.sock';\nconst OWNER_ONLY_DIRECTORY = 0o700;\nconst TOKEN_BYTES = 32;\nconst LOOPBACK = '127.0.0.1';\nconst LINUX_PLATFORM = 'linux';\nconst EPHEMERAL_PORT = 0;\n\nexport interface RunningBroker {\n /** How a container reaches this broker. */\n endpoint: BrokerEndpoint;\n /** Secret the container presents instead of any real credential. */\n token: string;\n /** Pi provider names the session may reach. */\n providers: string[];\n /** Host environment variables whose value the container receives as the token. */\n withheldEnv: string[];\n stop(): Promise<void>;\n}\n\nexport interface StartBrokerOptions {\n environment: Readonly<Record<string, string | undefined>>;\n onDenied?: (reason: string) => void;\n /** Seam for tests; defaults to this host's platform. */\n platform?: string;\n /**\n * Fixed directory to hold the socket instead of a fresh temporary one.\n *\n * A reused container keeps the mounts it was created with, so a dev\n * container has to find the socket at the same path on every launch.\n */\n socketDirectory?: string;\n /** Forces the loopback transport even where a socket would work. */\n forceLoopback?: boolean;\n}\n\n/**\n * Starts the host-side provider broker for one sandboxed session.\n *\n * Answers undefined when the host holds no brokerable credential, which keeps\n * a session that authenticates some other way on the unbrokered path instead\n * of failing it.\n */\nexport async function startBroker(options: StartBrokerOptions): Promise<RunningBroker | undefined> {\n const resolved = resolveBrokeredCredentials(options.environment);\n if (resolved.length === 0) return undefined;\n\n const token = randomBytes(TOKEN_BYTES).toString('base64url');\n const credentials = new Map(resolved.map((credential) => [credential.route.provider, credential]));\n const server = createBrokerServer({ credentials, token, onDenied: options.onDenied });\n const platform = options.platform ?? process.platform;\n\n const useSocket = platform === LINUX_PLATFORM && options.forceLoopback !== true;\n const { endpoint, dispose } = useSocket\n ? await listenOnSocket(server, options.socketDirectory)\n : await listenOnLoopback(server);\n\n return {\n endpoint,\n token,\n providers: resolved.map((credential) => credential.route.provider),\n withheldEnv: resolved.map((credential) => credential.envName),\n stop: () => stopBroker(server, dispose),\n };\n}\n\n/**\n * Native Linux shares a kernel with the container, so a bind-mounted socket\n * needs no port and is reachable as an ordinary file.\n */\nasync function listenOnSocket(\n server: http.Server,\n fixedDirectory?: string,\n): Promise<{ endpoint: BrokerEndpoint; dispose: () => void }> {\n const socketDirectory = fixedDirectory ?? fs.mkdtempSync(path.join(os.tmpdir(), SOCKET_DIRECTORY_PREFIX));\n fs.mkdirSync(socketDirectory, { recursive: true });\n fs.chmodSync(socketDirectory, OWNER_ONLY_DIRECTORY);\n const socketPath = path.join(socketDirectory, SOCKET_FILE_NAME);\n // A previous session that died without closing leaves the node behind, and\n // bind fails on an existing path.\n fs.rmSync(socketPath, { force: true });\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(socketPath, () => resolve());\n });\n return {\n endpoint: { transport: 'unix', socketDirectory },\n // A fixed directory outlives the session that borrowed it.\n dispose: () =>\n fixedDirectory\n ? fs.rmSync(socketPath, { force: true })\n : fs.rmSync(socketDirectory, { recursive: true, force: true }),\n };\n}\n\n/**\n * Everywhere else the container runs in its own virtual machine, which cannot\n * connect to a host unix socket even when the file is shared through: the\n * connect fails with ENOTSUP. Loopback keeps the broker off the network while\n * still being reachable through the engine's host gateway, and the session\n * token is what stops another local process from using it.\n */\nasync function listenOnLoopback(server: http.Server): Promise<{ endpoint: BrokerEndpoint; dispose: () => void }> {\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(EPHEMERAL_PORT, LOOPBACK, () => resolve());\n });\n const address = server.address();\n if (address === null || typeof address === 'string') throw new Error('The broker did not report a listening port.');\n return { endpoint: { transport: 'tcp', port: address.port }, dispose: () => undefined };\n}\n\nasync function stopBroker(server: http.Server, dispose: () => void): Promise<void> {\n await new Promise<void>((resolve) => {\n server.close(() => resolve());\n // An in-flight provider stream would otherwise hold the listener open past\n // the session that owns it.\n server.closeAllConnections();\n });\n dispose();\n}\n"],"mappings":"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"}
|