@agimon-ai/doompi-sandbox 0.0.1-alpha.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -0
  3. package/dist/apiContracts.cjs +17 -0
  4. package/dist/apiContracts.cjs.map +1 -0
  5. package/dist/apiContracts.d.mts +53 -0
  6. package/dist/apiContracts.d.mts.map +1 -0
  7. package/dist/apiContracts.mjs +13 -0
  8. package/dist/apiContracts.mjs.map +1 -0
  9. package/dist/brokerHost-BeGtmnK8.mjs +302 -0
  10. package/dist/brokerHost-BeGtmnK8.mjs.map +1 -0
  11. package/dist/brokerHost-BzffXeb2.cjs +340 -0
  12. package/dist/brokerHost-BzffXeb2.cjs.map +1 -0
  13. package/dist/cockpitHarness.cjs +298 -0
  14. package/dist/cockpitHarness.cjs.map +1 -0
  15. package/dist/cockpitHarness.d.mts +26 -0
  16. package/dist/cockpitHarness.d.mts.map +1 -0
  17. package/dist/cockpitHarness.mjs +295 -0
  18. package/dist/cockpitHarness.mjs.map +1 -0
  19. package/dist/extensionService-BnIZjdJN.cjs +25 -0
  20. package/dist/extensionService-BnIZjdJN.cjs.map +1 -0
  21. package/dist/extensionService-DiVpVLn9.mjs +20 -0
  22. package/dist/extensionService-DiVpVLn9.mjs.map +1 -0
  23. package/dist/extensions/mcp.cjs +26 -0
  24. package/dist/extensions/mcp.cjs.map +1 -0
  25. package/dist/extensions/mcp.d.mts +5 -0
  26. package/dist/extensions/mcp.d.mts.map +1 -0
  27. package/dist/extensions/mcp.mjs +21 -0
  28. package/dist/extensions/mcp.mjs.map +1 -0
  29. package/dist/extensions/pi.cjs +85 -0
  30. package/dist/extensions/pi.cjs.map +1 -0
  31. package/dist/extensions/pi.d.mts +6 -0
  32. package/dist/extensions/pi.d.mts.map +1 -0
  33. package/dist/extensions/pi.mjs +80 -0
  34. package/dist/extensions/pi.mjs.map +1 -0
  35. package/dist/extensions/server.cjs +92 -0
  36. package/dist/extensions/server.cjs.map +1 -0
  37. package/dist/extensions/server.d.mts +5 -0
  38. package/dist/extensions/server.d.mts.map +1 -0
  39. package/dist/extensions/server.mjs +87 -0
  40. package/dist/extensions/server.mjs.map +1 -0
  41. package/dist/harness-CEuhOTr2.mjs +716 -0
  42. package/dist/harness-CEuhOTr2.mjs.map +1 -0
  43. package/dist/harness-fK8CSaU1.cjs +785 -0
  44. package/dist/harness-fK8CSaU1.cjs.map +1 -0
  45. package/dist/index-CBt-PlVG.d.mts +22 -0
  46. package/dist/index-CBt-PlVG.d.mts.map +1 -0
  47. package/dist/index.cjs +3 -0
  48. package/dist/index.d.mts +2 -0
  49. package/dist/index.mjs +2 -0
  50. package/dist/sandboxBridge-B3FRZkC2.cjs +131 -0
  51. package/dist/sandboxBridge-B3FRZkC2.cjs.map +1 -0
  52. package/dist/sandboxBridge-D6RAncmy.mjs +72 -0
  53. package/dist/sandboxBridge-D6RAncmy.mjs.map +1 -0
  54. package/dist/sandboxHarness-BIvuRMio.d.mts +38 -0
  55. package/dist/sandboxHarness-BIvuRMio.d.mts.map +1 -0
  56. package/dist/sandboxHarness.cjs +4 -0
  57. package/dist/sandboxHarness.d.mts +38 -0
  58. package/dist/sandboxHarness.d.mts.map +1 -0
  59. package/dist/sandboxHarness.mjs +2 -0
  60. package/dist/sandboxResources-5pvXyBW9.mjs +79 -0
  61. package/dist/sandboxResources-5pvXyBW9.mjs.map +1 -0
  62. package/dist/sandboxResources-Djxj5l1V.cjs +120 -0
  63. package/dist/sandboxResources-Djxj5l1V.cjs.map +1 -0
  64. package/llms.txt +11 -0
  65. package/package.json +132 -0
  66. package/src/prompts/doompi-use-sandbox/SKILL.md +14 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cockpitHarness.mjs","names":[],"sources":["../src/services/cockpitPlan/index.ts","../src/services/cockpitHarness/index.ts"],"sourcesContent":["import type { CockpitWorkspace } from '@agimon-ai/doompi-core/cockpitContainer';\nimport { DOOMPI_SANDBOX_ENV } from '@agimon-ai/doompi-core/sandboxHarness';\n\nimport type { SandboxEngine, SandboxHostFacts } from '../../types/sandboxHarness';\nimport { DEVCONTAINER_DISABLED_ENV } from '../devcontainer';\nimport { containerEnvironment, type SandboxPlanBroker } from '../sandboxPlan';\n\n/**\n * Projects the cockpit into one detached engine run.\n *\n * The sandbox plan next door describes a disposable container wrapped around a\n * single interactive session. This one describes a long-lived container holding\n * the hub and every session it goes on to spawn, which changes four things:\n * it is detached rather than attached, it publishes a port rather than only\n * consuming them, its home volume is scoped to the cockpit rather than to one\n * repository, and it mounts a set of workspaces rather than a single repo.\n */\n\nconst CONTAINER_HOME = '/doompi-home';\n/**\n * One volume for the cockpit, not one per repository.\n *\n * A cockpit spans several workspaces, so there is no repository to key on. This\n * is also where `~/.doompi/web` lands, which is what makes paired passkeys and\n * the bundle signing key survive a container restart. A rotated signing key\n * would make every paired device refuse the cockpit, so the name must be\n * stable.\n */\nexport const COCKPIT_HOME_VOLUME = 'doompi-cockpit-home';\nexport const COCKPIT_LABEL = 'doompi.cockpit';\nconst COCKPIT_BINARY = 'doompi-web';\nconst LOOPBACK = '127.0.0.1';\n/**\n * The cockpit binds every interface inside the container.\n *\n * A published port reaches the container's external interface, never its\n * loopback, which is the same reason `oauthCallback.ts` sets its own bind\n * address. The host side of the publish is pinned to loopback, so this is not\n * exposed beyond the machine.\n */\nconst CONTAINER_BIND = '0.0.0.0';\nconst LINUX_PLATFORM = 'linux';\nconst DISABLED = '0';\n\n/** Git identity the agent commits under; no key crosses the boundary, so it cannot push. */\nexport interface CockpitGitIdentity {\n name: string;\n email: string;\n}\n\nexport interface CockpitPlanInput {\n workspaces: readonly CockpitWorkspace[];\n /** Published on the host loopback and bound inside the container. */\n port: number;\n environment: Readonly<Record<string, string | undefined>>;\n engine: SandboxEngine;\n host: SandboxHostFacts;\n imageTag: string;\n runFlags?: readonly string[];\n broker?: SandboxPlanBroker;\n gitIdentity?: CockpitGitIdentity;\n}\n\nexport interface CockpitPlan {\n imageTag: string;\n /** Full engine argv after the engine binary itself. */\n runArgs: string[];\n}\n\n/**\n * Git identity, passed as environment rather than by mounting a config.\n *\n * The agent can commit; it cannot push, because no key crosses the boundary.\n * Mounting `~/.gitconfig` would drag in whatever else it configures, and\n * forwarding an ssh agent would hand the container a live credential that\n * authenticates as the user everywhere their key reaches.\n */\nfunction gitIdentityEnvironment(identity: CockpitGitIdentity | undefined): Record<string, string> {\n if (identity === undefined) return {};\n return {\n GIT_AUTHOR_NAME: identity.name,\n GIT_AUTHOR_EMAIL: identity.email,\n GIT_COMMITTER_NAME: identity.name,\n GIT_COMMITTER_EMAIL: identity.email,\n };\n}\n\nexport function buildCockpitPlan(input: CockpitPlanInput): CockpitPlan {\n const { engine, host, broker, imageTag, port } = input;\n if (input.workspaces.length === 0) throw new Error('A cockpit container needs at least one workspace to mount.');\n\n const environment: Record<string, string> = {\n ...containerEnvironment(input.environment, broker),\n ...gitIdentityEnvironment(input.gitIdentity),\n // A workspace carrying a devcontainer config would otherwise replace the\n // whole plan with an author-controlled one that can mount anything,\n // including the docker socket. That would make the containment claim false.\n [DEVCONTAINER_DISABLED_ENV]: DISABLED,\n [DOOMPI_SANDBOX_ENV]: '1',\n };\n const environmentPairs = Object.entries(environment).sort(([left], [right]) => left.localeCompare(right));\n\n const runArgs = [\n 'run',\n // Detached, and deliberately not --rm: a container that exits on startup\n // has to survive long enough for its logs to be read. The stop path and the\n // reaper both remove it.\n '-d',\n '--label',\n `${COCKPIT_LABEL}=${String(port)}`,\n '-p',\n `${LOOPBACK}:${String(port)}:${String(port)}`,\n ...input.workspaces.flatMap((workspace) => ['-v', `${workspace.path}:${workspace.path}`]),\n '-v',\n `${COCKPIT_HOME_VOLUME}:${CONTAINER_HOME}`,\n ...(broker?.endpoint.transport === 'tcp' ? ['--add-host', `host.docker.internal:host-gateway`] : []),\n ...(broker?.endpoint.transport === 'unix' ? ['-v', `${broker.endpoint.socketDirectory}:/run/doompi`] : []),\n '-w',\n input.workspaces[0]?.path ?? CONTAINER_HOME,\n '-e',\n `HOME=${CONTAINER_HOME}`,\n ...environmentPairs.flatMap(([name, value]) => ['-e', `${name}=${value}`]),\n ...(host.platform === LINUX_PLATFORM && host.userId !== undefined\n ? [\n '--user',\n `${String(host.userId)}:${String(host.groupId ?? host.userId)}`,\n ...(engine === 'podman' ? ['--userns=keep-id'] : []),\n ]\n : []),\n // Last before the image so a configured option wins over the defaults above\n // it, and cannot be mistaken for the image or its command.\n ...(input.runFlags ?? []),\n imageTag,\n COCKPIT_BINARY,\n '--host',\n CONTAINER_BIND,\n '--port',\n String(port),\n ];\n\n return { imageTag, runArgs };\n}\n","import { execFileSync } from 'node:child_process';\n\nimport type {\n CockpitContainerHandle,\n CockpitContainerHarnessModule,\n CockpitContainerRequest,\n CockpitContainerStart,\n} from '@agimon-ai/doompi-core/cockpitContainer';\n\nimport type { EngineProcessRunner, SandboxEngine } from '../../types/sandboxHarness';\nimport { buildCockpitPlan, type CockpitGitIdentity } from '../cockpitPlan';\nimport { SpawnEngineProcessRunner } from '../engineProcess';\nimport { detectEngine, ensureImage } from '../harness';\nimport { parseRunFlags, assertRunFlags } from '../runFlags';\nimport { cockpitDockerfile } from '../sandboxImage';\nimport { cockpitImageTag } from '../sandboxImageTag';\n\n/**\n * Runs the cockpit itself in a container, detached, holding the hub and every\n * session it goes on to spawn.\n *\n * The interactive harness next door wraps one session and blocks until it\n * exits. This one returns a handle while the container keeps running, which is\n * why it is a separate entry rather than a flag on the other.\n */\n\nconst RUN_FLAGS_ENV = 'DOOMPI_SANDBOX_RUN_FLAGS';\nconst READY_TIMEOUT_MS = 60_000;\nconst READY_POLL_MS = 250;\nconst HUB_ROLE = 'hub';\n\nexport interface CockpitHarnessDependencies {\n runner?: EngineProcessRunner;\n version?: string;\n /** Test seam: reports whether the cockpit inside is answering yet. */\n probe?: (port: number) => Promise<boolean>;\n /** Test seam: the host's git identity, which is read from the real config by default. */\n gitIdentity?: () => CockpitGitIdentity | undefined;\n now?: () => number;\n}\n\n/**\n * Reads the host's committer identity.\n *\n * Passed into the container as environment rather than by mounting the config,\n * so the agent can commit without any credential crossing the boundary. It\n * cannot push, and that is the intended limit.\n */\nfunction readGitIdentity(): CockpitGitIdentity | undefined {\n const read = (key: string): string | undefined => {\n try {\n const value = execFileSync('git', ['config', '--global', '--get', key], { encoding: 'utf8' }).trim();\n return value === '' ? undefined : value;\n } catch {\n // No git, or no such key. An agent that cannot commit is a smaller\n // problem than a launch that refuses to start.\n return undefined;\n }\n };\n const name = read('user.name');\n const email = read('user.email');\n return name !== undefined && email !== undefined ? { name, email } : undefined;\n}\n\n/** Answers whether the hub inside the container is serving yet. */\nasync function defaultProbe(port: number): Promise<boolean> {\n try {\n const response = await fetch(`http://127.0.0.1:${String(port)}/api/health`);\n if (!response.ok) return false;\n return ((await response.json()) as { role?: unknown }).role === HUB_ROLE;\n } catch {\n return false;\n }\n}\n\nasync function stopContainer(runner: EngineProcessRunner, engine: SandboxEngine, id: string): Promise<boolean> {\n const stopped = await runner.capture(engine, ['stop', id]);\n // Removed explicitly because the run is not --rm: a container that dies on\n // startup has to survive long enough for its logs to be read.\n await runner.capture(engine, ['rm', '-f', id]);\n return stopped?.exitCode === 0;\n}\n\n/**\n * Whether the engine still reports this container as running.\n *\n * A removed container makes `inspect` fail rather than print `false`, so a\n * non-zero exit is read the same way: not running.\n */\nasync function isRunning(runner: EngineProcessRunner, engine: SandboxEngine, id: string): Promise<boolean> {\n const probed = await runner.capture(engine, ['inspect', '-f', '{{.State.Running}}', id]);\n return probed?.exitCode === 0 && probed.stdout.trim() === 'true';\n}\n\nexport function createCockpitHarness(dependencies: CockpitHarnessDependencies = {}): CockpitContainerHarnessModule {\n const runner = dependencies.runner ?? new SpawnEngineProcessRunner();\n const probe = dependencies.probe ?? defaultProbe;\n const readIdentity = dependencies.gitIdentity ?? readGitIdentity;\n const now = dependencies.now ?? ((): number => Date.now());\n\n return {\n async startCockpitContainer(request: CockpitContainerRequest): Promise<CockpitContainerStart> {\n if (request.workspaces.length === 0) {\n return { ok: false, error: 'A cockpit container needs at least one workspace to mount.' };\n }\n let engine: SandboxEngine;\n try {\n engine = await detectEngine(runner, request.environment);\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n const runFlags = parseRunFlags(request.environment[RUN_FLAGS_ENV]);\n try {\n assertRunFlags(runFlags, RUN_FLAGS_ENV);\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n request.onProgress?.(`using ${engine}${runFlags.length > 0 ? ` with ${runFlags.join(' ')}` : ''}`);\n\n const version = dependencies.version ?? '0.0.0';\n let imageTag: string;\n try {\n // Before the tunnel is reported ready, never inside a session spawn:\n // a cold build is minutes and the hub gives a spawning session ten\n // seconds to register.\n imageTag = await ensureImage(runner, engine, version, request.onProgress, {\n tag: cockpitImageTag(version),\n dockerfile: cockpitDockerfile(),\n });\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n\n const plan = buildCockpitPlan({\n workspaces: request.workspaces,\n port: request.port,\n environment: request.environment,\n engine,\n host: { hasTty: false, platform: process.platform, repoKey: '', version },\n imageTag,\n runFlags,\n ...(readIdentity() === undefined ? {} : { gitIdentity: readIdentity() as CockpitGitIdentity }),\n });\n\n const started = await runner.capture(engine, plan.runArgs);\n const containerId = started?.stdout.trim().split('\\n').pop() ?? '';\n if (started?.exitCode !== 0 || containerId === '') {\n return { ok: false, error: `The cockpit container did not start: ${started?.stdout.trim() ?? 'no output'}` };\n }\n request.onProgress?.('waiting for the cockpit to answer');\n\n const deadline = now() + READY_TIMEOUT_MS;\n for (;;) {\n if (await probe(request.port)) break;\n if (now() >= deadline) {\n const logs = await runner.capture(engine, ['logs', '--tail', '20', containerId]);\n await stopContainer(runner, engine, containerId);\n return {\n ok: false,\n error:\n `The cockpit did not answer within ${String(READY_TIMEOUT_MS / 1000)}s.\\n${logs?.stdout ?? ''}`.trim(),\n };\n }\n await new Promise((resolve) => setTimeout(resolve, READY_POLL_MS));\n }\n\n const handle: CockpitContainerHandle = {\n containerId,\n stop: async () => {\n await stopContainer(runner, engine, containerId);\n },\n alive: async () => await isRunning(runner, engine, containerId),\n };\n return { ok: true, handle };\n },\n\n async reapCockpitContainer(containerId: string): Promise<boolean> {\n // Named by id rather than searched for, because the caller recorded it\n // before the process that owned it went away.\n for (const engine of ['docker', 'podman', 'nerdctl', 'finch'] as const) {\n const probed = await runner.capture(engine, ['--version']);\n if (probed?.exitCode !== 0) continue;\n return await stopContainer(runner, engine, containerId);\n }\n return false;\n },\n };\n}\n\n/** The module-shaped entry a host resolves from the composition. */\nexport async function startCockpitContainer(request: CockpitContainerRequest): Promise<CockpitContainerStart> {\n return await createCockpitHarness().startCockpitContainer(request);\n}\n\nexport async function reapCockpitContainer(containerId: string): Promise<boolean> {\n return await createCockpitHarness().reapCockpitContainer(containerId);\n}\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ let _agimon_ai_doompi_core_sandboxHarness = require("@agimon-ai/doompi-core/sandboxHarness");
2
+ //#region src/services/extensionService/index.ts
3
+ const SANDBOXED_MESSAGE = "Sandboxed session: the agent, extensions, and tools run inside the container.";
4
+ const HOST_MESSAGE = "Host session: relaunch with dpi --sandbox to contain the agent in a container.";
5
+ var DefaultSandboxExtensionService = class {
6
+ environment;
7
+ constructor(environment) {
8
+ this.environment = environment;
9
+ }
10
+ async execute() {
11
+ return {
12
+ message: (0, _agimon_ai_doompi_core_sandboxHarness.insideSandbox)(this.environment) ? SANDBOXED_MESSAGE : HOST_MESSAGE,
13
+ level: "info"
14
+ };
15
+ }
16
+ };
17
+ //#endregion
18
+ Object.defineProperty(exports, "DefaultSandboxExtensionService", {
19
+ enumerable: true,
20
+ get: function() {
21
+ return DefaultSandboxExtensionService;
22
+ }
23
+ });
24
+
25
+ //# sourceMappingURL=extensionService-BnIZjdJN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensionService-BnIZjdJN.cjs","names":["insideSandbox"],"sources":["../src/services/extensionService/index.ts"],"sourcesContent":["import { insideSandbox } from '@agimon-ai/doompi-core/sandboxHarness';\n\nimport type { SandboxExtensionResult, SandboxExtensionService } from '../../types/extension';\n\nconst SANDBOXED_MESSAGE = 'Sandboxed session: the agent, extensions, and tools run inside the container.';\nconst HOST_MESSAGE = 'Host session: relaunch with dpi --sandbox to contain the agent in a container.';\n\nexport class DefaultSandboxExtensionService implements SandboxExtensionService {\n private readonly environment: Readonly<Record<string, string | undefined>>;\n\n constructor(environment: Readonly<Record<string, string | undefined>>) {\n this.environment = environment;\n }\n\n async execute(): Promise<SandboxExtensionResult> {\n return {\n message: insideSandbox(this.environment) ? SANDBOXED_MESSAGE : HOST_MESSAGE,\n level: 'info',\n };\n }\n}\n"],"mappings":";;AAIA,MAAM,oBAAoB;AAC1B,MAAM,eAAe;AAErB,IAAa,iCAAb,MAA+E;CAC7E;CAEA,YAAY,aAA2D;EACrE,KAAK,cAAc;CACrB;CAEA,MAAM,UAA2C;EAC/C,OAAO;GACL,UAAA,GAASA,sCAAAA,cAAAA,CAAc,KAAK,WAAW,IAAI,oBAAoB;GAC/D,OAAO;EACT;CACF;AACF"}
@@ -0,0 +1,20 @@
1
+ import { insideSandbox } from "@agimon-ai/doompi-core/sandboxHarness";
2
+ //#region src/services/extensionService/index.ts
3
+ const SANDBOXED_MESSAGE = "Sandboxed session: the agent, extensions, and tools run inside the container.";
4
+ const HOST_MESSAGE = "Host session: relaunch with dpi --sandbox to contain the agent in a container.";
5
+ var DefaultSandboxExtensionService = class {
6
+ environment;
7
+ constructor(environment) {
8
+ this.environment = environment;
9
+ }
10
+ async execute() {
11
+ return {
12
+ message: insideSandbox(this.environment) ? SANDBOXED_MESSAGE : HOST_MESSAGE,
13
+ level: "info"
14
+ };
15
+ }
16
+ };
17
+ //#endregion
18
+ export { DefaultSandboxExtensionService as t };
19
+
20
+ //# sourceMappingURL=extensionService-DiVpVLn9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensionService-DiVpVLn9.mjs","names":[],"sources":["../src/services/extensionService/index.ts"],"sourcesContent":["import { insideSandbox } from '@agimon-ai/doompi-core/sandboxHarness';\n\nimport type { SandboxExtensionResult, SandboxExtensionService } from '../../types/extension';\n\nconst SANDBOXED_MESSAGE = 'Sandboxed session: the agent, extensions, and tools run inside the container.';\nconst HOST_MESSAGE = 'Host session: relaunch with dpi --sandbox to contain the agent in a container.';\n\nexport class DefaultSandboxExtensionService implements SandboxExtensionService {\n private readonly environment: Readonly<Record<string, string | undefined>>;\n\n constructor(environment: Readonly<Record<string, string | undefined>>) {\n this.environment = environment;\n }\n\n async execute(): Promise<SandboxExtensionResult> {\n return {\n message: insideSandbox(this.environment) ? SANDBOXED_MESSAGE : HOST_MESSAGE,\n level: 'info',\n };\n }\n}\n"],"mappings":";;AAIA,MAAM,oBAAoB;AAC1B,MAAM,eAAe;AAErB,IAAa,iCAAb,MAA+E;CAC7E;CAEA,YAAY,aAA2D;EACrE,KAAK,cAAc;CACrB;CAEA,MAAM,UAA2C;EAC/C,OAAO;GACL,SAAS,cAAc,KAAK,WAAW,IAAI,oBAAoB;GAC/D,OAAO;EACT;CACF;AACF"}
@@ -0,0 +1,26 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ let _agimon_ai_doompi_core_mcpFacet = require("@agimon-ai/doompi-core/mcpFacet");
6
+ let _agimon_ai_doompi_core_serverFacet = require("@agimon-ai/doompi-core/serverFacet");
7
+ //#region src/extensions/workspaces/sessions/(backend)/skill/doompi-use-sandbox.mcp.ts
8
+ var doompi_use_sandbox_mcp_default = (0, _agimon_ai_doompi_core_mcpFacet.defineMcpSkill)({
9
+ name: "doompi-use-sandbox",
10
+ description: "Use @agimon-ai/doompi-sandbox: Container sandbox for DoomPi launches: the agent, extensions, and tools run inside Docker or Podman while the terminal stays on the host",
11
+ read: () => (0, _agimon_ai_doompi_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/doompi-use-sandbox/SKILL.md")
12
+ });
13
+ //#endregion
14
+ //#region generated/mcp.ts
15
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
16
+ const mcp = (0, _agimon_ai_doompi_core_mcpFacet.defineMcpPlugin)({
17
+ name: "@agimon-ai/doompi-sandbox",
18
+ session: (context) => ({ get skills() {
19
+ return [at(doompi_use_sandbox_mcp_default, context)];
20
+ } })
21
+ });
22
+ //#endregion
23
+ exports.default = mcp;
24
+ exports.mcp = mcp;
25
+
26
+ //# sourceMappingURL=mcp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.cjs","names":["defineMcpSkill","readPackageResource","defineMcpPlugin","skillDoompiUseSandbox"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/doompi-use-sandbox.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/doompi-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineMcpSkill({\n name: 'doompi-use-sandbox',\n description:\n 'Use @agimon-ai/doompi-sandbox: Container sandbox for DoomPi launches: the agent, extensions, and tools run inside Docker or Podman while the terminal stays on the host',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-sandbox/SKILL.md'),\n});\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineMcpPlugin, type DoomMcpSessionPlugin } from '@agimon-ai/doompi-core/mcpFacet';\n\nimport skillDoompiUseSandbox from '../src/extensions/workspaces/sessions/(backend)/skill/doompi-use-sandbox.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/doompi-sandbox',\n session: (context) => ({\n get skills(): DoomMcpSessionPlugin['skills'] { return [at(skillDoompiUseSandbox, context)]; },\n }) satisfies DoomMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":";;;;;;;AAGA,IAAA,kCAAA,GAAeA,gCAAAA,eAAAA,CAAe;CAC5B,MAAM;CACN,aACE;CACF,aAAA,GAAYC,mCAAAA,oBAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,MAAqC,yCAAyC;AAC5F,CAAC;;;ACFD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,OAAA,GAAMC,gCAAAA,gBAAAA,CAAgB;CACjC,MAAM;CACN,UAAU,aAAa,EACrB,IAAI,SAAyC;EAAE,OAAO,CAAC,GAAGC,gCAAuB,OAAO,CAAC;CAAG,EAC9F;AACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ //#region generated/mcp.d.ts
2
+ export declare const mcp: import("@agimon-ai/doompi-core/mcpFacet").DoomMcpPluginDefinition;
3
+ //#endregion
4
+ export { mcp as default };
5
+ //# sourceMappingURL=mcp.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.mts","names":[],"sources":["../../generated/mcp.ts"],"mappings":";qBASa,+CAAG"}
@@ -0,0 +1,21 @@
1
+ import { defineMcpPlugin, defineMcpSkill } from "@agimon-ai/doompi-core/mcpFacet";
2
+ import { readPackageResource } from "@agimon-ai/doompi-core/serverFacet";
3
+ //#region src/extensions/workspaces/sessions/(backend)/skill/doompi-use-sandbox.mcp.ts
4
+ var doompi_use_sandbox_mcp_default = defineMcpSkill({
5
+ name: "doompi-use-sandbox",
6
+ description: "Use @agimon-ai/doompi-sandbox: Container sandbox for DoomPi launches: the agent, extensions, and tools run inside Docker or Podman while the terminal stays on the host",
7
+ read: () => readPackageResource(import.meta.url, "src/prompts/doompi-use-sandbox/SKILL.md")
8
+ });
9
+ //#endregion
10
+ //#region generated/mcp.ts
11
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
12
+ const mcp = defineMcpPlugin({
13
+ name: "@agimon-ai/doompi-sandbox",
14
+ session: (context) => ({ get skills() {
15
+ return [at(doompi_use_sandbox_mcp_default, context)];
16
+ } })
17
+ });
18
+ //#endregion
19
+ export { mcp as default, mcp };
20
+
21
+ //# sourceMappingURL=mcp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.mjs","names":["skillDoompiUseSandbox"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/doompi-use-sandbox.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/doompi-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineMcpSkill({\n name: 'doompi-use-sandbox',\n description:\n 'Use @agimon-ai/doompi-sandbox: Container sandbox for DoomPi launches: the agent, extensions, and tools run inside Docker or Podman while the terminal stays on the host',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-sandbox/SKILL.md'),\n});\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineMcpPlugin, type DoomMcpSessionPlugin } from '@agimon-ai/doompi-core/mcpFacet';\n\nimport skillDoompiUseSandbox from '../src/extensions/workspaces/sessions/(backend)/skill/doompi-use-sandbox.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/doompi-sandbox',\n session: (context) => ({\n get skills(): DoomMcpSessionPlugin['skills'] { return [at(skillDoompiUseSandbox, context)]; },\n }) satisfies DoomMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":";;;AAGA,IAAA,iCAAe,eAAe;CAC5B,MAAM;CACN,aACE;CACF,YAAY,oBAAoB,YAAY,KAAK,yCAAyC;AAC5F,CAAC;;;ACFD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,MAAM,gBAAgB;CACjC,MAAM;CACN,UAAU,aAAa,EACrB,IAAI,SAAyC;EAAE,OAAO,CAAC,GAAGA,gCAAuB,OAAO,CAAC;CAAG,EAC9F;AACF,CAAC"}
@@ -0,0 +1,85 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_sandboxBridge = require("../sandboxBridge-B3FRZkC2.cjs");
6
+ const require_extensionService = require("../extensionService-BnIZjdJN.cjs");
7
+ const require_sandboxResources = require("../sandboxResources-Djxj5l1V.cjs");
8
+ let _agimon_ai_doompi_core_piExtension = require("@agimon-ai/doompi-core/piExtension");
9
+ let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
10
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts
11
+ function createSandboxPiRoot(context) {
12
+ return { value: { service: context.options?.service ?? new require_extensionService.DefaultSandboxExtensionService(process.env) } };
13
+ }
14
+ //#endregion
15
+ //#region src/extensions/workspaces/sessions/(backend)/root.cli.ts
16
+ var root_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoot)(createSandboxPiRoot);
17
+ //#endregion
18
+ //#region src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.ts
19
+ var sandbox_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineCliCommand)((context) => require_sandboxResources.createSandboxCliCommand(context.root.service));
20
+ //#endregion
21
+ //#region src/services/brokerProviders/index.ts
22
+ /**
23
+ * Points brokered providers at whichever route the launch granted.
24
+ *
25
+ * Pi reads base URLs from package-internal provider data, so redirecting a
26
+ * session means overriding the provider rather than setting an environment
27
+ * variable. The credential is left alone: the launch already replaced it with
28
+ * the session token the broker expects.
29
+ *
30
+ * A broker on a host port is addressed directly. Only a mounted socket needs
31
+ * the loopback bridge, because no SDK can dial a socket path.
32
+ */
33
+ function brokeredProviderOverrides(environment) {
34
+ const configured = environment[require_sandboxBridge.BROKER_PROVIDERS_ENV]?.trim();
35
+ if (!configured) return [];
36
+ const authority = environment["DOOMPI_BROKER_SOCKET"]?.trim() ? `127.0.0.1:${require_sandboxBridge.BROKER_CONTAINER_PORT}` : environment[require_sandboxBridge.BROKER_ADDRESS_ENV]?.trim();
37
+ if (!authority) return [];
38
+ return configured.split(",").map((provider) => provider.trim()).filter((provider) => provider.length > 0).map((provider) => ({
39
+ provider,
40
+ baseUrl: `http://${authority}/${provider}`
41
+ }));
42
+ }
43
+ //#endregion
44
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.ts
45
+ function brokeredProviderDeclarations(environment) {
46
+ return brokeredProviderOverrides(environment).map(({ provider, baseUrl }) => [provider, { baseUrl }]);
47
+ }
48
+ //#endregion
49
+ //#region src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.ts
50
+ var brokered_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((0, _agimon_ai_doompi_core_extensionFile.defineProvider)((_context) => brokeredProviderDeclarations(process.env)), { cardinality: "many" });
51
+ //#endregion
52
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.ts
53
+ var doompiUseSandbox_cli_default = (0, _agimon_ai_doompi_core_extensionFile.defineResource)(require_sandboxResources.createSandboxHelpResource(require("url").pathToFileURL(__filename).href));
54
+ //#endregion
55
+ //#region generated/pi.ts
56
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
57
+ const many = (value, context) => {
58
+ const resolved = typeof value === "function" ? value(context) : value;
59
+ return Array.isArray(resolved) ? resolved : [resolved];
60
+ };
61
+ const extension = (0, _agimon_ai_doompi_core_piExtension.definePiExtension)("@agimon-ai/doompi-sandbox", async (context) => {
62
+ const scopeSession = await root_cli_default(context);
63
+ const contextSession = {
64
+ ...context,
65
+ root: scopeSession.value
66
+ };
67
+ return {
68
+ ...(0, _agimon_ai_doompi_core_extensionFile.composeRootHooks)(scopeSession),
69
+ get commands() {
70
+ return [at(sandbox_cli_default, contextSession)];
71
+ },
72
+ get providers() {
73
+ return [...many(brokered_cli_default, contextSession)];
74
+ },
75
+ get resources() {
76
+ return [at(doompiUseSandbox_cli_default, contextSession)];
77
+ },
78
+ services: [...scopeSession.services ?? []]
79
+ };
80
+ });
81
+ //#endregion
82
+ exports.default = extension;
83
+ exports.extension = extension;
84
+
85
+ //# sourceMappingURL=pi.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi.cjs","names":["DefaultSandboxExtensionService","defineRoot","defineCliCommand","createSandboxCliCommand","BROKER_PROVIDERS_ENV","BROKER_CONTAINER_PORT","BROKER_ADDRESS_ENV","defineRoutedContribution","defineProvider","defineResource","createSandboxHelpResource","definePiExtension","rootSession","composeRootHooks","commandSandbox","providerBrokered","resourceDoompiUseSandbox"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.ts","../../src/services/brokerProviders/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.ts","../../src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { DefaultSandboxExtensionService } from '../../../../../services/extensionService';\nimport type { SandboxExtensionDependencies } from '../../../../../types/extension';\nimport type { SandboxPiScope } from './sandboxScope';\n\nexport function createSandboxPiRoot(context: PiPluginContext<SandboxExtensionDependencies>) {\n const value: SandboxPiScope = {\n service: context.options?.service ?? new DefaultSandboxExtensionService(process.env),\n };\n return { value };\n}\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createSandboxPiRoot } from './_lib/piRoot';\n\nexport default defineRoot(createSandboxPiRoot);\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { SandboxExtensionDependencies } from '../../../../../types/extension';\nimport { createSandboxCliCommand } from '../_lib/sandboxCommands';\nimport type { SandboxPiScope } from '../_lib/sandboxScope';\n\nexport default defineCliCommand((context: WithRoot<PiPluginContext<SandboxExtensionDependencies>, SandboxPiScope>) =>\n createSandboxCliCommand(context.root.service),\n);\n","import { BROKER_ADDRESS_ENV, BROKER_CONTAINER_PORT, BROKER_PROVIDERS_ENV, BROKER_SOCKET_ENV } from '../sandboxBridge';\n\nexport interface BrokeredProviderOverride {\n provider: string;\n baseUrl: string;\n}\n\n/**\n * Points brokered providers at whichever route the launch granted.\n *\n * Pi reads base URLs from package-internal provider data, so redirecting a\n * session means overriding the provider rather than setting an environment\n * variable. The credential is left alone: the launch already replaced it with\n * the session token the broker expects.\n *\n * A broker on a host port is addressed directly. Only a mounted socket needs\n * the loopback bridge, because no SDK can dial a socket path.\n */\nexport function brokeredProviderOverrides(\n environment: Readonly<Record<string, string | undefined>>,\n): BrokeredProviderOverride[] {\n const configured = environment[BROKER_PROVIDERS_ENV]?.trim();\n if (!configured) return [];\n const authority = environment[BROKER_SOCKET_ENV]?.trim()\n ? `127.0.0.1:${BROKER_CONTAINER_PORT}`\n : environment[BROKER_ADDRESS_ENV]?.trim();\n if (!authority) return [];\n return configured\n .split(',')\n .map((provider) => provider.trim())\n .filter((provider) => provider.length > 0)\n .map((provider) => ({ provider, baseUrl: `http://${authority}/${provider}` }));\n}\n","import { brokeredProviderOverrides } from '../../../../../services/brokerProviders';\n\nexport function brokeredProviderDeclarations(environment: Readonly<Record<string, string | undefined>>) {\n return brokeredProviderOverrides(environment).map(({ provider, baseUrl }) => [provider, { baseUrl }] as const);\n}\n","import { defineProvider, defineRoutedContribution } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { SandboxExtensionDependencies } from '../../../../../types/extension';\nimport { brokeredProviderDeclarations } from '../_lib/sandboxProviders';\n\nexport default defineRoutedContribution(\n defineProvider((_context: PiPluginContext<SandboxExtensionDependencies>) =>\n brokeredProviderDeclarations(process.env),\n ),\n { cardinality: 'many' },\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createSandboxHelpResource } from '../_lib/sandboxResources';\n\nexport default defineResource(createSandboxHelpResource(import.meta.url));\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandSandbox from '../src/extensions/workspaces/sessions/(backend)/command/sandbox.cli';\nimport providerBrokered from '../src/extensions/workspaces/sessions/(backend)/provider/brokered.cli';\nimport resourceDoompiUseSandbox from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandSandbox> | OptionsOf<typeof providerBrokered> | OptionsOf<typeof resourceDoompiUseSandbox>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-sandbox', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandSandbox, contextSession)]; },\n get providers(): PiPluginContributions['providers'] { return [...many(providerBrokered, contextSession)]; },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseSandbox, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;;;;;;AAMA,SAAgB,oBAAoB,SAAwD;CAI1F,OAAO,EAAE,OAAA,EAFP,SAAS,QAAQ,SAAS,WAAW,IAAIA,yBAAAA,+BAA+B,QAAQ,GAAG,EAExE,EAAE;AACjB;;;ACPA,IAAA,oBAAA,GAAeC,qCAAAA,WAAAA,CAAW,mBAAmB;;;ACG7C,IAAA,uBAAA,GAAeC,qCAAAA,iBAAAA,EAAkB,YAC/BC,yBAAAA,wBAAwB,QAAQ,KAAK,OAAO,CAC9C;;;;;;;;;;;;;;ACSA,SAAgB,0BACd,aAC4B;CAC5B,MAAM,aAAa,YAAYC,sBAAAA,qBAAqB,EAAE,KAAK;CAC3D,IAAI,CAAC,YAAY,OAAO,CAAC;CACzB,MAAM,YAAY,YAAA,uBAA8B,EAAE,KAAK,IACnD,aAAaC,sBAAAA,0BACb,YAAYC,sBAAAA,mBAAmB,EAAE,KAAK;CAC1C,IAAI,CAAC,WAAW,OAAO,CAAC;CACxB,OAAO,WACJ,MAAM,GAAG,CAAC,CACV,KAAK,aAAa,SAAS,KAAK,CAAC,CAAC,CAClC,QAAQ,aAAa,SAAS,SAAS,CAAC,CAAC,CACzC,KAAK,cAAc;EAAE;EAAU,SAAS,UAAU,UAAU,GAAG;CAAW,EAAE;AACjF;;;AC9BA,SAAgB,6BAA6B,aAA2D;CACtG,OAAO,0BAA0B,WAAW,CAAC,CAAC,KAAK,EAAE,UAAU,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAU;AAC/G;;;ACEA,IAAA,wBAAA,GAAeC,qCAAAA,yBAAAA,EAAAA,GACbC,qCAAAA,eAAAA,EAAgB,aACd,6BAA6B,QAAQ,GAAG,CAC1C,GACA,EAAE,aAAa,OAAO,CACxB;;;ACPA,IAAA,gCAAA,GAAeC,qCAAAA,eAAAA,CAAeC,yBAAAA,0BAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAAyC,CAAC;;;ACYxE,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAM,QAAc,OAA6C,YAA6B;CAC5F,MAAM,WAAW,OAAO,UAAU,aAAc,MAA4B,OAAO,IAAI;CACvF,OAAO,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAa;AAC5D;AAEA,MAAa,aAAA,GAAYC,mCAAAA,kBAAAA,CAAoC,6BAA6B,OAAO,YAAY;CAC3G,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,IAAA,GAAGC,qCAAAA,iBAAAA,CAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,qBAAgB,cAAc,CAAC;EAAG;EACjG,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAG,KAAKC,sBAAkB,cAAc,CAAC;EAAG;EAC1G,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,8BAA0B,cAAc,CAAC;EAAG;EAC7G,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { n as SandboxExtensionDependencies } from "../index-CBt-PlVG.mjs";
2
+ //#region generated/pi.d.ts
3
+ export declare const extension: import("@agimon-ai/doompi-core/runtimePiExtension").DefinedPiExtension<SandboxExtensionDependencies>;
4
+ //#endregion
5
+ export { extension as default };
6
+ //# sourceMappingURL=pi.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi.d.mts","names":[],"sources":["../../generated/pi.ts"],"mappings":";;qBAwBa,+DAAS,mBAAT"}
@@ -0,0 +1,80 @@
1
+ import { i as BROKER_CONTAINER_PORT, r as BROKER_ADDRESS_ENV, s as BROKER_PROVIDERS_ENV } from "../sandboxBridge-D6RAncmy.mjs";
2
+ import { t as DefaultSandboxExtensionService } from "../extensionService-DiVpVLn9.mjs";
3
+ import { i as createSandboxCliCommand, n as createSandboxHelpResource } from "../sandboxResources-5pvXyBW9.mjs";
4
+ import { definePiExtension } from "@agimon-ai/doompi-core/piExtension";
5
+ import { composeRootHooks, defineCliCommand, defineProvider, defineResource, defineRoot, defineRoutedContribution } from "@agimon-ai/doompi-core/extensionFile";
6
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts
7
+ function createSandboxPiRoot(context) {
8
+ return { value: { service: context.options?.service ?? new DefaultSandboxExtensionService(process.env) } };
9
+ }
10
+ //#endregion
11
+ //#region src/extensions/workspaces/sessions/(backend)/root.cli.ts
12
+ var root_cli_default = defineRoot(createSandboxPiRoot);
13
+ //#endregion
14
+ //#region src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.ts
15
+ var sandbox_cli_default = defineCliCommand((context) => createSandboxCliCommand(context.root.service));
16
+ //#endregion
17
+ //#region src/services/brokerProviders/index.ts
18
+ /**
19
+ * Points brokered providers at whichever route the launch granted.
20
+ *
21
+ * Pi reads base URLs from package-internal provider data, so redirecting a
22
+ * session means overriding the provider rather than setting an environment
23
+ * variable. The credential is left alone: the launch already replaced it with
24
+ * the session token the broker expects.
25
+ *
26
+ * A broker on a host port is addressed directly. Only a mounted socket needs
27
+ * the loopback bridge, because no SDK can dial a socket path.
28
+ */
29
+ function brokeredProviderOverrides(environment) {
30
+ const configured = environment[BROKER_PROVIDERS_ENV]?.trim();
31
+ if (!configured) return [];
32
+ const authority = environment["DOOMPI_BROKER_SOCKET"]?.trim() ? `127.0.0.1:${BROKER_CONTAINER_PORT}` : environment[BROKER_ADDRESS_ENV]?.trim();
33
+ if (!authority) return [];
34
+ return configured.split(",").map((provider) => provider.trim()).filter((provider) => provider.length > 0).map((provider) => ({
35
+ provider,
36
+ baseUrl: `http://${authority}/${provider}`
37
+ }));
38
+ }
39
+ //#endregion
40
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.ts
41
+ function brokeredProviderDeclarations(environment) {
42
+ return brokeredProviderOverrides(environment).map(({ provider, baseUrl }) => [provider, { baseUrl }]);
43
+ }
44
+ //#endregion
45
+ //#region src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.ts
46
+ var brokered_cli_default = defineRoutedContribution(defineProvider((_context) => brokeredProviderDeclarations(process.env)), { cardinality: "many" });
47
+ //#endregion
48
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.ts
49
+ var doompiUseSandbox_cli_default = defineResource(createSandboxHelpResource(import.meta.url));
50
+ //#endregion
51
+ //#region generated/pi.ts
52
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
53
+ const many = (value, context) => {
54
+ const resolved = typeof value === "function" ? value(context) : value;
55
+ return Array.isArray(resolved) ? resolved : [resolved];
56
+ };
57
+ const extension = definePiExtension("@agimon-ai/doompi-sandbox", async (context) => {
58
+ const scopeSession = await root_cli_default(context);
59
+ const contextSession = {
60
+ ...context,
61
+ root: scopeSession.value
62
+ };
63
+ return {
64
+ ...composeRootHooks(scopeSession),
65
+ get commands() {
66
+ return [at(sandbox_cli_default, contextSession)];
67
+ },
68
+ get providers() {
69
+ return [...many(brokered_cli_default, contextSession)];
70
+ },
71
+ get resources() {
72
+ return [at(doompiUseSandbox_cli_default, contextSession)];
73
+ },
74
+ services: [...scopeSession.services ?? []]
75
+ };
76
+ });
77
+ //#endregion
78
+ export { extension as default, extension };
79
+
80
+ //# sourceMappingURL=pi.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi.mjs","names":["rootSession","commandSandbox","providerBrokered","resourceDoompiUseSandbox"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/piRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/sandbox.cli.ts","../../src/services/brokerProviders/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/sandboxProviders.ts","../../src/extensions/workspaces/sessions/(backend)/provider/brokered.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { DefaultSandboxExtensionService } from '../../../../../services/extensionService';\nimport type { SandboxExtensionDependencies } from '../../../../../types/extension';\nimport type { SandboxPiScope } from './sandboxScope';\n\nexport function createSandboxPiRoot(context: PiPluginContext<SandboxExtensionDependencies>) {\n const value: SandboxPiScope = {\n service: context.options?.service ?? new DefaultSandboxExtensionService(process.env),\n };\n return { value };\n}\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createSandboxPiRoot } from './_lib/piRoot';\n\nexport default defineRoot(createSandboxPiRoot);\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { SandboxExtensionDependencies } from '../../../../../types/extension';\nimport { createSandboxCliCommand } from '../_lib/sandboxCommands';\nimport type { SandboxPiScope } from '../_lib/sandboxScope';\n\nexport default defineCliCommand((context: WithRoot<PiPluginContext<SandboxExtensionDependencies>, SandboxPiScope>) =>\n createSandboxCliCommand(context.root.service),\n);\n","import { BROKER_ADDRESS_ENV, BROKER_CONTAINER_PORT, BROKER_PROVIDERS_ENV, BROKER_SOCKET_ENV } from '../sandboxBridge';\n\nexport interface BrokeredProviderOverride {\n provider: string;\n baseUrl: string;\n}\n\n/**\n * Points brokered providers at whichever route the launch granted.\n *\n * Pi reads base URLs from package-internal provider data, so redirecting a\n * session means overriding the provider rather than setting an environment\n * variable. The credential is left alone: the launch already replaced it with\n * the session token the broker expects.\n *\n * A broker on a host port is addressed directly. Only a mounted socket needs\n * the loopback bridge, because no SDK can dial a socket path.\n */\nexport function brokeredProviderOverrides(\n environment: Readonly<Record<string, string | undefined>>,\n): BrokeredProviderOverride[] {\n const configured = environment[BROKER_PROVIDERS_ENV]?.trim();\n if (!configured) return [];\n const authority = environment[BROKER_SOCKET_ENV]?.trim()\n ? `127.0.0.1:${BROKER_CONTAINER_PORT}`\n : environment[BROKER_ADDRESS_ENV]?.trim();\n if (!authority) return [];\n return configured\n .split(',')\n .map((provider) => provider.trim())\n .filter((provider) => provider.length > 0)\n .map((provider) => ({ provider, baseUrl: `http://${authority}/${provider}` }));\n}\n","import { brokeredProviderOverrides } from '../../../../../services/brokerProviders';\n\nexport function brokeredProviderDeclarations(environment: Readonly<Record<string, string | undefined>>) {\n return brokeredProviderOverrides(environment).map(({ provider, baseUrl }) => [provider, { baseUrl }] as const);\n}\n","import { defineProvider, defineRoutedContribution } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport type { SandboxExtensionDependencies } from '../../../../../types/extension';\nimport { brokeredProviderDeclarations } from '../_lib/sandboxProviders';\n\nexport default defineRoutedContribution(\n defineProvider((_context: PiPluginContext<SandboxExtensionDependencies>) =>\n brokeredProviderDeclarations(process.env),\n ),\n { cardinality: 'many' },\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createSandboxHelpResource } from '../_lib/sandboxResources';\n\nexport default defineResource(createSandboxHelpResource(import.meta.url));\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandSandbox from '../src/extensions/workspaces/sessions/(backend)/command/sandbox.cli';\nimport providerBrokered from '../src/extensions/workspaces/sessions/(backend)/provider/brokered.cli';\nimport resourceDoompiUseSandbox from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandSandbox> | OptionsOf<typeof providerBrokered> | OptionsOf<typeof resourceDoompiUseSandbox>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-sandbox', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandSandbox, contextSession)]; },\n get providers(): PiPluginContributions['providers'] { return [...many(providerBrokered, contextSession)]; },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseSandbox, contextSession)]; },\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":";;;;;;AAMA,SAAgB,oBAAoB,SAAwD;CAI1F,OAAO,EAAE,OAAA,EAFP,SAAS,QAAQ,SAAS,WAAW,IAAI,+BAA+B,QAAQ,GAAG,EAExE,EAAE;AACjB;;;ACPA,IAAA,mBAAe,WAAW,mBAAmB;;;ACG7C,IAAA,sBAAe,kBAAkB,YAC/B,wBAAwB,QAAQ,KAAK,OAAO,CAC9C;;;;;;;;;;;;;;ACSA,SAAgB,0BACd,aAC4B;CAC5B,MAAM,aAAa,YAAY,qBAAqB,EAAE,KAAK;CAC3D,IAAI,CAAC,YAAY,OAAO,CAAC;CACzB,MAAM,YAAY,YAAA,uBAA8B,EAAE,KAAK,IACnD,aAAa,0BACb,YAAY,mBAAmB,EAAE,KAAK;CAC1C,IAAI,CAAC,WAAW,OAAO,CAAC;CACxB,OAAO,WACJ,MAAM,GAAG,CAAC,CACV,KAAK,aAAa,SAAS,KAAK,CAAC,CAAC,CAClC,QAAQ,aAAa,SAAS,SAAS,CAAC,CAAC,CACzC,KAAK,cAAc;EAAE;EAAU,SAAS,UAAU,UAAU,GAAG;CAAW,EAAE;AACjF;;;AC9BA,SAAgB,6BAA6B,aAA2D;CACtG,OAAO,0BAA0B,WAAW,CAAC,CAAC,KAAK,EAAE,UAAU,cAAc,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAU;AAC/G;;;ACEA,IAAA,uBAAe,yBACb,gBAAgB,aACd,6BAA6B,QAAQ,GAAG,CAC1C,GACA,EAAE,aAAa,OAAO,CACxB;;;ACPA,IAAA,+BAAe,eAAe,0BAA0B,YAAY,GAAG,CAAC;;;ACYxE,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAM,QAAc,OAA6C,YAA6B;CAC5F,MAAM,WAAW,OAAO,UAAU,aAAc,MAA4B,OAAO,IAAI;CACvF,OAAO,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAa;AAC5D;AAEA,MAAa,YAAY,kBAAoC,6BAA6B,OAAO,YAAY;CAC3G,MAAM,eAAe,MAAMA,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,GAAG,iBAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,qBAAgB,cAAc,CAAC;EAAG;EACjG,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAG,KAAKC,sBAAkB,cAAc,CAAC;EAAG;EAC1G,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,8BAA0B,cAAc,CAAC;EAAG;EAC7G,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}
@@ -0,0 +1,92 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_brokerHost = require("../brokerHost-BzffXeb2.cjs");
6
+ const require_extensionService = require("../extensionService-BnIZjdJN.cjs");
7
+ const require_sandboxResources = require("../sandboxResources-Djxj5l1V.cjs");
8
+ let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
9
+ let _agimon_ai_doompi_core_serverFacet = require("@agimon-ai/doompi-core/serverFacet");
10
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts
11
+ function createSandboxServerRoot({ agent }) {
12
+ if (!agent) return { value: {} };
13
+ const service = new require_extensionService.DefaultSandboxExtensionService(agent.context.environment);
14
+ let broker;
15
+ return {
16
+ value: { service },
17
+ activities: [{
18
+ name: require_sandboxResources.BROKER_STATUS_SOURCE,
19
+ async start(execution) {
20
+ if (execution.environment["DOOMPI_SANDBOX_BROKER"] === "0") return () => void 0;
21
+ const started = await require_brokerHost.startBroker({
22
+ environment: execution.environment,
23
+ onDenied: (reason) => {
24
+ execution.client.notify({
25
+ title: "DoomPi sandbox broker",
26
+ body: `Broker refused a call: ${reason}`,
27
+ level: "warning"
28
+ });
29
+ }
30
+ });
31
+ broker = started;
32
+ if (started === void 0) return () => void 0;
33
+ execution.client.setStatus(require_sandboxResources.BROKER_STATUS_SOURCE, `provider broker: ${started.providers.join(", ")}`);
34
+ return async () => {
35
+ if (broker !== started) return;
36
+ broker = void 0;
37
+ execution.client.setStatus(require_sandboxResources.BROKER_STATUS_SOURCE, void 0);
38
+ await started.stop();
39
+ };
40
+ }
41
+ }]
42
+ };
43
+ }
44
+ //#endregion
45
+ //#region src/extensions/workspaces/sessions/(backend)/root.server.ts
46
+ var root_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoot)(createSandboxServerRoot);
47
+ //#endregion
48
+ //#region src/extensions/workspaces/sessions/(backend)/command/sandbox.server.ts
49
+ var sandbox_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((context) => require_sandboxResources.createSandboxServerCommands(context), { cardinality: "many" });
50
+ //#endregion
51
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.ts
52
+ var doompiSandbox_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((0, _agimon_ai_doompi_core_extensionFile.defineResource)((context) => require_sandboxResources.createSandboxContextResource(context.root)), { cardinality: "optional" });
53
+ //#endregion
54
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.ts
55
+ var doompiUseSandbox_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((0, _agimon_ai_doompi_core_extensionFile.defineResource)((context) => require_sandboxResources.createSandboxSkillResource(context.root)), { cardinality: "optional" });
56
+ //#endregion
57
+ //#region generated/server.ts
58
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
59
+ const many = (value, context) => {
60
+ const resolved = typeof value === "function" ? value(context) : value;
61
+ return Array.isArray(resolved) ? resolved : [resolved];
62
+ };
63
+ /* v8 ignore next -- generated normalization branch */
64
+ const defined = (values) => values.filter((value) => value !== void 0);
65
+ const facet = (0, _agimon_ai_doompi_core_serverFacet.defineServerPlugin)({
66
+ name: "@agimon-ai/doompi-sandbox",
67
+ session: async (context) => {
68
+ const scopeSession = await root_server_default(context);
69
+ const contextSession = {
70
+ ...context,
71
+ root: scopeSession.value
72
+ };
73
+ return {
74
+ ...(0, _agimon_ai_doompi_core_extensionFile.composeRootHooks)(scopeSession),
75
+ get commands() {
76
+ return [...many(sandbox_server_default, contextSession)];
77
+ },
78
+ get resources() {
79
+ return defined([at(doompiSandbox_server_default, contextSession), at(doompiUseSandbox_server_default, contextSession)]);
80
+ },
81
+ services: [...scopeSession.services ?? []],
82
+ get activities() {
83
+ return [...scopeSession.activities ?? []];
84
+ }
85
+ };
86
+ }
87
+ });
88
+ //#endregion
89
+ exports.default = facet;
90
+ exports.facet = facet;
91
+
92
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.cjs","names":["DefaultSandboxExtensionService","BROKER_STATUS_SOURCE","startBroker","defineRoot","defineRoutedContribution","createSandboxServerCommands","defineRoutedContribution","defineResource","createSandboxContextResource","defineRoutedContribution","defineResource","createSandboxSkillResource","defineServerPlugin","rootSession","composeRootHooks","commandSandbox","resourceDoompiSandbox","resourceDoompiUseSandbox"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/sandbox.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.ts","../../generated/server.ts"],"sourcesContent":["import type { DoomHeadlessActivity } from '@agimon-ai/doompi-core/headless';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { BROKER_DISABLED_ENV, BROKER_STATUS_SOURCE, DISABLED_VALUE } from '../../../../../constants/sandbox';\nimport { startBroker, type RunningBroker } from '../../../../../services/brokerHost';\nimport { DefaultSandboxExtensionService } from '../../../../../services/extensionService';\nimport type { SandboxServerScope } from './sandboxScope';\n\nexport function createSandboxServerRoot({ agent }: DoomServerPluginContext) {\n if (!agent) return { value: {} as SandboxServerScope };\n const service = new DefaultSandboxExtensionService(agent.context.environment);\n let broker: RunningBroker | undefined;\n const activity: DoomHeadlessActivity = {\n name: BROKER_STATUS_SOURCE,\n async start(execution) {\n if (execution.environment[BROKER_DISABLED_ENV] === DISABLED_VALUE) return () => undefined;\n const started = await startBroker({\n environment: execution.environment,\n onDenied: (reason) => {\n void execution.client.notify({\n title: 'DoomPi sandbox broker',\n body: `Broker refused a call: ${reason}`,\n level: 'warning',\n });\n },\n });\n broker = started;\n if (started === undefined) return () => undefined;\n execution.client.setStatus(BROKER_STATUS_SOURCE, `provider broker: ${started.providers.join(', ')}`);\n return async () => {\n if (broker !== started) return;\n broker = undefined;\n execution.client.setStatus(BROKER_STATUS_SOURCE, undefined);\n await started.stop();\n };\n },\n };\n return { value: { service }, activities: [activity] };\n}\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { createSandboxServerRoot } from './_lib/serverRoot';\n\nexport default defineRoot(createSandboxServerRoot);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { createSandboxServerCommands } from '../_lib/sandboxCommands';\nimport type { SandboxServerScope } from '../_lib/sandboxScope';\n\nexport default defineRoutedContribution(\n (context: WithRoot<DoomServerPluginContext, SandboxServerScope>) => createSandboxServerCommands(context),\n { cardinality: 'many' },\n);\n","import { defineResource, defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { createSandboxContextResource } from '../_lib/sandboxResources';\nimport type { SandboxServerScope } from '../_lib/sandboxScope';\n\nexport default defineRoutedContribution(\n defineResource((context: WithRoot<DoomServerPluginContext, SandboxServerScope>) =>\n createSandboxContextResource(context.root),\n ),\n { cardinality: 'optional' },\n);\n","import { defineResource, defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { createSandboxSkillResource } from '../_lib/sandboxResources';\nimport type { SandboxServerScope } from '../_lib/sandboxScope';\n\nexport default defineRoutedContribution(\n defineResource((context: WithRoot<DoomServerPluginContext, SandboxServerScope>) =>\n createSandboxSkillResource(context.root),\n ),\n { cardinality: 'optional' },\n);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport commandSandbox from '../src/extensions/workspaces/sessions/(backend)/command/sandbox.server';\nimport resourceDoompiSandbox from '../src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server';\nimport resourceDoompiUseSandbox from '../src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n return Array.isArray(resolved) ? resolved : [resolved as T];\n};\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-sandbox',\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): DoomServerSessionPlugin['commands'] { return [...many(commandSandbox, contextSession)]; },\n get resources(): DoomServerSessionPlugin['resources'] { return defined([at(resourceDoompiSandbox, contextSession), at(resourceDoompiUseSandbox, contextSession)]); },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":";;;;;;;;;;AAQA,SAAgB,wBAAwB,EAAE,SAAkC;CAC1E,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,CAAC,EAAwB;CACrD,MAAM,UAAU,IAAIA,yBAAAA,+BAA+B,MAAM,QAAQ,WAAW;CAC5E,IAAI;CA0BJ,OAAO;EAAE,OAAO,EAAE,QAAQ;EAAG,YAAY,CAAC;GAxBxC,MAAMC,yBAAAA;GACN,MAAM,MAAM,WAAW;IACrB,IAAI,UAAU,YAAA,6BAAA,KAAqD,aAAa,KAAA;IAChF,MAAM,UAAU,MAAMC,mBAAAA,YAAY;KAChC,aAAa,UAAU;KACvB,WAAW,WAAW;MACpB,UAAe,OAAO,OAAO;OAC3B,OAAO;OACP,MAAM,0BAA0B;OAChC,OAAO;MACT,CAAC;KACH;IACF,CAAC;IACD,SAAS;IACT,IAAI,YAAY,KAAA,GAAW,aAAa,KAAA;IACxC,UAAU,OAAO,UAAUD,yBAAAA,sBAAsB,oBAAoB,QAAQ,UAAU,KAAK,IAAI,GAAG;IACnG,OAAO,YAAY;KACjB,IAAI,WAAW,SAAS;KACxB,SAAS,KAAA;KACT,UAAU,OAAO,UAAUA,yBAAAA,sBAAsB,KAAA,CAAS;KAC1D,MAAM,QAAQ,KAAK;IACrB;GACF;EAE+C,CAAC;CAAE;AACtD;;;AClCA,IAAA,uBAAA,GAAeE,qCAAAA,WAAAA,CAAW,uBAAuB;;;ACEjD,IAAA,0BAAA,GAAeC,qCAAAA,yBAAAA,EACZ,YAAmEC,yBAAAA,4BAA4B,OAAO,GACvG,EAAE,aAAa,OAAO,CACxB;;;ACHA,IAAA,gCAAA,GAAeC,qCAAAA,yBAAAA,EAAAA,GACbC,qCAAAA,eAAAA,EAAgB,YACdC,yBAAAA,6BAA6B,QAAQ,IAAI,CAC3C,GACA,EAAE,aAAa,WAAW,CAC5B;;;ACLA,IAAA,mCAAA,GAAeC,qCAAAA,yBAAAA,EAAAA,GACbC,qCAAAA,eAAAA,EAAgB,YACdC,yBAAAA,2BAA2B,QAAQ,IAAI,CACzC,GACA,EAAE,aAAa,WAAW,CAC5B;;;ACDA,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAM,QAAc,OAA6C,YAA6B;CAC5F,MAAM,WAAW,OAAO,UAAU,aAAc,MAA4B,OAAO,IAAI;CACvF,OAAO,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAa;AAC5D;;AAEA,MAAM,WAAc,WAClB,OAAO,QAAQ,UAAsB,UAAU,KAAA,CAAS;AAE1D,MAAa,SAAA,GAAQC,mCAAAA,mBAAAA,CAAmB;CACtC,MAAM;CACN,SAAS,OAAO,YAAY;EAC1B,MAAM,eAAe,MAAMC,oBAAY,OAAO;EAC9C,MAAM,iBAAiB;GAAE,GAAG;GAAS,MAAM,aAAa;EAAM;EAC9D,OAAO;GACL,IAAA,GAAGC,qCAAAA,iBAAAA,CAAiB,YAAY;GAChC,IAAI,WAAgD;IAAE,OAAO,CAAC,GAAG,KAAKC,wBAAgB,cAAc,CAAC;GAAG;GACxG,IAAI,YAAkD;IAAE,OAAO,QAAQ,CAAC,GAAGC,8BAAuB,cAAc,GAAG,GAAGC,iCAA0B,cAAc,CAAC,CAAC;GAAG;GACnK,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;GAC3C,IAAI,aAAoD;IAAE,OAAO,CAAC,GAAI,aAAa,cAAc,CAAC,CAAE;GAAG;EACzG;CACF;AACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ //#region generated/server.d.ts
2
+ export declare const facet: import("@agimon-ai/doompi-core/serverFacet").DoomServerFacet;
3
+ //#endregion
4
+ export { facet as default };
5
+ //# sourceMappingURL=server.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAqBa,oDAAK"}
@@ -0,0 +1,87 @@
1
+ import { t as startBroker } from "../brokerHost-BeGtmnK8.mjs";
2
+ import { t as DefaultSandboxExtensionService } from "../extensionService-DiVpVLn9.mjs";
3
+ import { a as createSandboxServerCommands, r as createSandboxSkillResource, s as BROKER_STATUS_SOURCE, t as createSandboxContextResource } from "../sandboxResources-5pvXyBW9.mjs";
4
+ import { composeRootHooks, defineResource, defineRoot, defineRoutedContribution } from "@agimon-ai/doompi-core/extensionFile";
5
+ import { defineServerPlugin } from "@agimon-ai/doompi-core/serverFacet";
6
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/serverRoot.ts
7
+ function createSandboxServerRoot({ agent }) {
8
+ if (!agent) return { value: {} };
9
+ const service = new DefaultSandboxExtensionService(agent.context.environment);
10
+ let broker;
11
+ return {
12
+ value: { service },
13
+ activities: [{
14
+ name: BROKER_STATUS_SOURCE,
15
+ async start(execution) {
16
+ if (execution.environment["DOOMPI_SANDBOX_BROKER"] === "0") return () => void 0;
17
+ const started = await startBroker({
18
+ environment: execution.environment,
19
+ onDenied: (reason) => {
20
+ execution.client.notify({
21
+ title: "DoomPi sandbox broker",
22
+ body: `Broker refused a call: ${reason}`,
23
+ level: "warning"
24
+ });
25
+ }
26
+ });
27
+ broker = started;
28
+ if (started === void 0) return () => void 0;
29
+ execution.client.setStatus(BROKER_STATUS_SOURCE, `provider broker: ${started.providers.join(", ")}`);
30
+ return async () => {
31
+ if (broker !== started) return;
32
+ broker = void 0;
33
+ execution.client.setStatus(BROKER_STATUS_SOURCE, void 0);
34
+ await started.stop();
35
+ };
36
+ }
37
+ }]
38
+ };
39
+ }
40
+ //#endregion
41
+ //#region src/extensions/workspaces/sessions/(backend)/root.server.ts
42
+ var root_server_default = defineRoot(createSandboxServerRoot);
43
+ //#endregion
44
+ //#region src/extensions/workspaces/sessions/(backend)/command/sandbox.server.ts
45
+ var sandbox_server_default = defineRoutedContribution((context) => createSandboxServerCommands(context), { cardinality: "many" });
46
+ //#endregion
47
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompiSandbox.server.ts
48
+ var doompiSandbox_server_default = defineRoutedContribution(defineResource((context) => createSandboxContextResource(context.root)), { cardinality: "optional" });
49
+ //#endregion
50
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompiUseSandbox.server.ts
51
+ var doompiUseSandbox_server_default = defineRoutedContribution(defineResource((context) => createSandboxSkillResource(context.root)), { cardinality: "optional" });
52
+ //#endregion
53
+ //#region generated/server.ts
54
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
55
+ const many = (value, context) => {
56
+ const resolved = typeof value === "function" ? value(context) : value;
57
+ return Array.isArray(resolved) ? resolved : [resolved];
58
+ };
59
+ /* v8 ignore next -- generated normalization branch */
60
+ const defined = (values) => values.filter((value) => value !== void 0);
61
+ const facet = defineServerPlugin({
62
+ name: "@agimon-ai/doompi-sandbox",
63
+ session: async (context) => {
64
+ const scopeSession = await root_server_default(context);
65
+ const contextSession = {
66
+ ...context,
67
+ root: scopeSession.value
68
+ };
69
+ return {
70
+ ...composeRootHooks(scopeSession),
71
+ get commands() {
72
+ return [...many(sandbox_server_default, contextSession)];
73
+ },
74
+ get resources() {
75
+ return defined([at(doompiSandbox_server_default, contextSession), at(doompiUseSandbox_server_default, contextSession)]);
76
+ },
77
+ services: [...scopeSession.services ?? []],
78
+ get activities() {
79
+ return [...scopeSession.activities ?? []];
80
+ }
81
+ };
82
+ }
83
+ });
84
+ //#endregion
85
+ export { facet as default, facet };
86
+
87
+ //# sourceMappingURL=server.mjs.map