@nookplot/runtime 0.5.131 → 0.5.132
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/__tests__/apiMarketplace.test.d.ts +2 -0
- package/dist/__tests__/apiMarketplace.test.d.ts.map +1 -0
- package/dist/__tests__/apiMarketplace.test.js +102 -0
- package/dist/__tests__/apiMarketplace.test.js.map +1 -0
- package/dist/__tests__/autonomous.actionDispatch.test.d.ts +2 -0
- package/dist/__tests__/autonomous.actionDispatch.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.actionDispatch.test.js +287 -0
- package/dist/__tests__/autonomous.actionDispatch.test.js.map +1 -0
- package/dist/__tests__/autonomous.dedup.test.d.ts +2 -0
- package/dist/__tests__/autonomous.dedup.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.dedup.test.js +125 -0
- package/dist/__tests__/autonomous.dedup.test.js.map +1 -0
- package/dist/__tests__/autonomous.doomLoop.test.d.ts +2 -0
- package/dist/__tests__/autonomous.doomLoop.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.doomLoop.test.js +126 -0
- package/dist/__tests__/autonomous.doomLoop.test.js.map +1 -0
- package/dist/__tests__/autonomous.getAvailableActions.test.d.ts +2 -0
- package/dist/__tests__/autonomous.getAvailableActions.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.getAvailableActions.test.js +233 -0
- package/dist/__tests__/autonomous.getAvailableActions.test.js.map +1 -0
- package/dist/__tests__/autonomous.guardrails.test.d.ts +2 -0
- package/dist/__tests__/autonomous.guardrails.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.guardrails.test.js +215 -0
- package/dist/__tests__/autonomous.guardrails.test.js.map +1 -0
- package/dist/__tests__/autonomous.hooks.test.d.ts +2 -0
- package/dist/__tests__/autonomous.hooks.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.hooks.test.js +107 -0
- package/dist/__tests__/autonomous.hooks.test.js.map +1 -0
- package/dist/__tests__/autonomous.latentSpace.test.d.ts +2 -0
- package/dist/__tests__/autonomous.latentSpace.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.latentSpace.test.js +224 -0
- package/dist/__tests__/autonomous.latentSpace.test.js.map +1 -0
- package/dist/__tests__/autonomous.lifecycle.test.d.ts +2 -0
- package/dist/__tests__/autonomous.lifecycle.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.lifecycle.test.js +147 -0
- package/dist/__tests__/autonomous.lifecycle.test.js.map +1 -0
- package/dist/__tests__/autonomous.loadedSkillRefs.test.d.ts +2 -0
- package/dist/__tests__/autonomous.loadedSkillRefs.test.d.ts.map +1 -0
- package/dist/__tests__/autonomous.loadedSkillRefs.test.js +150 -0
- package/dist/__tests__/autonomous.loadedSkillRefs.test.js.map +1 -0
- package/dist/__tests__/chatEngine.episodicHook.test.d.ts +2 -0
- package/dist/__tests__/chatEngine.episodicHook.test.d.ts.map +1 -0
- package/dist/__tests__/chatEngine.episodicHook.test.js +160 -0
- package/dist/__tests__/chatEngine.episodicHook.test.js.map +1 -0
- package/dist/__tests__/chatEngine.test.d.ts +2 -0
- package/dist/__tests__/chatEngine.test.d.ts.map +1 -0
- package/dist/__tests__/chatEngine.test.js +482 -0
- package/dist/__tests__/chatEngine.test.js.map +1 -0
- package/dist/__tests__/codegen-drift.test.d.ts +23 -0
- package/dist/__tests__/codegen-drift.test.d.ts.map +1 -0
- package/dist/__tests__/codegen-drift.test.js +185 -0
- package/dist/__tests__/codegen-drift.test.js.map +1 -0
- package/dist/__tests__/contentSafety.test.d.ts +2 -0
- package/dist/__tests__/contentSafety.test.d.ts.map +1 -0
- package/dist/__tests__/contentSafety.test.js +90 -0
- package/dist/__tests__/contentSafety.test.js.map +1 -0
- package/dist/__tests__/conversation/compactionMemory.test.d.ts +2 -0
- package/dist/__tests__/conversation/compactionMemory.test.d.ts.map +1 -0
- package/dist/__tests__/conversation/compactionMemory.test.js +447 -0
- package/dist/__tests__/conversation/compactionMemory.test.js.map +1 -0
- package/dist/__tests__/conversation/modelThresholdsParity.test.d.ts +2 -0
- package/dist/__tests__/conversation/modelThresholdsParity.test.d.ts.map +1 -0
- package/dist/__tests__/conversation/modelThresholdsParity.test.js +79 -0
- package/dist/__tests__/conversation/modelThresholdsParity.test.js.map +1 -0
- package/dist/__tests__/doomLoop.test.d.ts +6 -0
- package/dist/__tests__/doomLoop.test.d.ts.map +1 -0
- package/dist/__tests__/doomLoop.test.js +144 -0
- package/dist/__tests__/doomLoop.test.js.map +1 -0
- package/dist/__tests__/guardrails.test.d.ts +2 -0
- package/dist/__tests__/guardrails.test.d.ts.map +1 -0
- package/dist/__tests__/guardrails.test.js +236 -0
- package/dist/__tests__/guardrails.test.js.map +1 -0
- package/dist/__tests__/helpers/mockRuntime.d.ts +11 -0
- package/dist/__tests__/helpers/mockRuntime.d.ts.map +1 -0
- package/dist/__tests__/helpers/mockRuntime.js +146 -0
- package/dist/__tests__/helpers/mockRuntime.js.map +1 -0
- package/dist/__tests__/hooks.test.d.ts +9 -0
- package/dist/__tests__/hooks.test.d.ts.map +1 -0
- package/dist/__tests__/hooks.test.js +192 -0
- package/dist/__tests__/hooks.test.js.map +1 -0
- package/dist/__tests__/manifestActivationHook.test.d.ts +2 -0
- package/dist/__tests__/manifestActivationHook.test.d.ts.map +1 -0
- package/dist/__tests__/manifestActivationHook.test.js +312 -0
- package/dist/__tests__/manifestActivationHook.test.js.map +1 -0
- package/dist/__tests__/memory.test.d.ts +2 -0
- package/dist/__tests__/memory.test.d.ts.map +1 -0
- package/dist/__tests__/memory.test.js +192 -0
- package/dist/__tests__/memory.test.js.map +1 -0
- package/dist/__tests__/onChainActions.parity.test.d.ts +12 -0
- package/dist/__tests__/onChainActions.parity.test.d.ts.map +1 -0
- package/dist/__tests__/onChainActions.parity.test.js +104 -0
- package/dist/__tests__/onChainActions.parity.test.js.map +1 -0
- package/dist/__tests__/querySegmentation.test.d.ts +2 -0
- package/dist/__tests__/querySegmentation.test.d.ts.map +1 -0
- package/dist/__tests__/querySegmentation.test.js +187 -0
- package/dist/__tests__/querySegmentation.test.js.map +1 -0
- package/dist/__tests__/sandbox.test.d.ts +13 -0
- package/dist/__tests__/sandbox.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox.test.js +413 -0
- package/dist/__tests__/sandbox.test.js.map +1 -0
- package/dist/__tests__/signing.test.d.ts +2 -0
- package/dist/__tests__/signing.test.d.ts.map +1 -0
- package/dist/__tests__/signing.test.js +260 -0
- package/dist/__tests__/signing.test.js.map +1 -0
- package/dist/__tests__/wakeUpStack.test.d.ts +2 -0
- package/dist/__tests__/wakeUpStack.test.d.ts.map +1 -0
- package/dist/__tests__/wakeUpStack.test.js +239 -0
- package/dist/__tests__/wakeUpStack.test.js.map +1 -0
- package/dist/actionCatalog.d.ts +57 -0
- package/dist/actionCatalog.d.ts.map +1 -0
- package/dist/actionCatalog.generated.d.ts +4 -0
- package/dist/actionCatalog.generated.d.ts.map +1 -0
- package/dist/actionCatalog.generated.js +2194 -0
- package/dist/actionCatalog.generated.js.map +1 -0
- package/dist/actionCatalog.js +214 -0
- package/dist/actionCatalog.js.map +1 -0
- package/dist/api-marketplace.d.ts +111 -0
- package/dist/api-marketplace.d.ts.map +1 -0
- package/dist/api-marketplace.js +154 -0
- package/dist/api-marketplace.js.map +1 -0
- package/dist/artifactEmbeddings.d.ts +69 -0
- package/dist/artifactEmbeddings.d.ts.map +1 -0
- package/dist/artifactEmbeddings.js +52 -0
- package/dist/artifactEmbeddings.js.map +1 -0
- package/dist/autonomous.d.ts +271 -0
- package/dist/autonomous.d.ts.map +1 -0
- package/dist/autonomous.js +3517 -0
- package/dist/autonomous.js.map +1 -0
- package/dist/bounties.d.ts +112 -0
- package/dist/bounties.d.ts.map +1 -0
- package/dist/bounties.js +140 -0
- package/dist/bounties.js.map +1 -0
- package/dist/bundles.d.ts +174 -0
- package/dist/bundles.d.ts.map +1 -0
- package/dist/bundles.js +208 -0
- package/dist/bundles.js.map +1 -0
- package/dist/channels.d.ts +131 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +227 -0
- package/dist/channels.js.map +1 -0
- package/dist/chat/chatEngine.d.ts +138 -0
- package/dist/chat/chatEngine.d.ts.map +1 -0
- package/dist/chat/chatEngine.js +613 -0
- package/dist/chat/chatEngine.js.map +1 -0
- package/dist/chat/index.d.ts +30 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +29 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/terminal.d.ts +19 -0
- package/dist/chat/terminal.d.ts.map +1 -0
- package/dist/chat/terminal.js +17 -0
- package/dist/chat/terminal.js.map +1 -0
- package/dist/chat/terminals/discordTerminal.d.ts +22 -0
- package/dist/chat/terminals/discordTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/discordTerminal.js +132 -0
- package/dist/chat/terminals/discordTerminal.js.map +1 -0
- package/dist/chat/terminals/openclawTerminal.d.ts +43 -0
- package/dist/chat/terminals/openclawTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/openclawTerminal.js +186 -0
- package/dist/chat/terminals/openclawTerminal.js.map +1 -0
- package/dist/chat/terminals/stdinTerminal.d.ts +18 -0
- package/dist/chat/terminals/stdinTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/stdinTerminal.js +58 -0
- package/dist/chat/terminals/stdinTerminal.js.map +1 -0
- package/dist/chat/terminals/telegramTerminal.d.ts +27 -0
- package/dist/chat/terminals/telegramTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/telegramTerminal.js +123 -0
- package/dist/chat/terminals/telegramTerminal.js.map +1 -0
- package/dist/cognitiveWorkspace.d.ts +107 -0
- package/dist/cognitiveWorkspace.d.ts.map +1 -0
- package/dist/cognitiveWorkspace.js +94 -0
- package/dist/cognitiveWorkspace.js.map +1 -0
- package/dist/communities.d.ts +40 -0
- package/dist/communities.d.ts.map +1 -0
- package/dist/communities.js +53 -0
- package/dist/communities.js.map +1 -0
- package/dist/connection.d.ts +90 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +429 -0
- package/dist/connection.js.map +1 -0
- package/dist/contentSafety.d.ts +64 -0
- package/dist/contentSafety.d.ts.map +1 -0
- package/dist/contentSafety.js +119 -0
- package/dist/contentSafety.js.map +1 -0
- package/dist/conversation/compactionMemory.d.ts +124 -0
- package/dist/conversation/compactionMemory.d.ts.map +1 -0
- package/dist/conversation/compactionMemory.js +379 -0
- package/dist/conversation/compactionMemory.js.map +1 -0
- package/dist/conversation/conversationLogStore.d.ts +111 -0
- package/dist/conversation/conversationLogStore.d.ts.map +1 -0
- package/dist/conversation/conversationLogStore.js +248 -0
- package/dist/conversation/conversationLogStore.js.map +1 -0
- package/dist/conversation/conversationMemory.d.ts +59 -0
- package/dist/conversation/conversationMemory.d.ts.map +1 -0
- package/dist/conversation/conversationMemory.js +32 -0
- package/dist/conversation/conversationMemory.js.map +1 -0
- package/dist/conversation/index.d.ts +16 -0
- package/dist/conversation/index.d.ts.map +1 -0
- package/dist/conversation/index.js +5 -0
- package/dist/conversation/index.js.map +1 -0
- package/dist/conversation/modelLimits.d.ts +43 -0
- package/dist/conversation/modelLimits.d.ts.map +1 -0
- package/dist/conversation/modelLimits.js +67 -0
- package/dist/conversation/modelLimits.js.map +1 -0
- package/dist/cro.d.ts +243 -0
- package/dist/cro.d.ts.map +1 -0
- package/dist/cro.js +263 -0
- package/dist/cro.js.map +1 -0
- package/dist/defaultGuardrails.d.ts +21 -0
- package/dist/defaultGuardrails.d.ts.map +1 -0
- package/dist/defaultGuardrails.js +90 -0
- package/dist/defaultGuardrails.js.map +1 -0
- package/dist/delegations.d.ts +63 -0
- package/dist/delegations.d.ts.map +1 -0
- package/dist/delegations.js +41 -0
- package/dist/delegations.js.map +1 -0
- package/dist/discovery.d.ts +172 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +300 -0
- package/dist/discovery.js.map +1 -0
- package/dist/doomLoop.d.ts +52 -0
- package/dist/doomLoop.d.ts.map +1 -0
- package/dist/doomLoop.js +173 -0
- package/dist/doomLoop.js.map +1 -0
- package/dist/economy.d.ts +244 -0
- package/dist/economy.d.ts.map +1 -0
- package/dist/economy.js +263 -0
- package/dist/economy.js.map +1 -0
- package/dist/email.d.ts +125 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +91 -0
- package/dist/email.js.map +1 -0
- package/dist/embeddingExchange.d.ts +141 -0
- package/dist/embeddingExchange.d.ts.map +1 -0
- package/dist/embeddingExchange.js +95 -0
- package/dist/embeddingExchange.js.map +1 -0
- package/dist/episodicMemoryHook.d.ts +39 -0
- package/dist/episodicMemoryHook.d.ts.map +1 -0
- package/dist/episodicMemoryHook.js +58 -0
- package/dist/episodicMemoryHook.js.map +1 -0
- package/dist/evaluator.d.ts +113 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +144 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/events.d.ts +58 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +86 -0
- package/dist/events.js.map +1 -0
- package/dist/formatters.d.ts +31 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +227 -0
- package/dist/formatters.js.map +1 -0
- package/dist/gpu.d.ts +137 -0
- package/dist/gpu.d.ts.map +1 -0
- package/dist/gpu.js +166 -0
- package/dist/gpu.js.map +1 -0
- package/dist/guardrails.d.ts +182 -0
- package/dist/guardrails.d.ts.map +1 -0
- package/dist/guardrails.js +277 -0
- package/dist/guardrails.js.map +1 -0
- package/dist/guilds.d.ts +158 -0
- package/dist/guilds.d.ts.map +1 -0
- package/dist/guilds.js +205 -0
- package/dist/guilds.js.map +1 -0
- package/dist/heartbeat.d.ts +43 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +72 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/hooks.d.ts +172 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +91 -0
- package/dist/hooks.js.map +1 -0
- package/dist/identity.d.ts +61 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +76 -0
- package/dist/identity.js.map +1 -0
- package/dist/inbox.d.ts +77 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +98 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +321 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +361 -0
- package/dist/index.js.map +1 -0
- package/dist/insights.d.ts +166 -0
- package/dist/insights.d.ts.map +1 -0
- package/dist/insights.js +100 -0
- package/dist/insights.js.map +1 -0
- package/dist/intents.d.ts +132 -0
- package/dist/intents.d.ts.map +1 -0
- package/dist/intents.js +81 -0
- package/dist/intents.js.map +1 -0
- package/dist/knowledgeContext.d.ts +68 -0
- package/dist/knowledgeContext.d.ts.map +1 -0
- package/dist/knowledgeContext.js +109 -0
- package/dist/knowledgeContext.js.map +1 -0
- package/dist/leaderboard.d.ts +30 -0
- package/dist/leaderboard.d.ts.map +1 -0
- package/dist/leaderboard.js +34 -0
- package/dist/leaderboard.js.map +1 -0
- package/dist/manifest.d.ts +127 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +123 -0
- package/dist/manifest.js.map +1 -0
- package/dist/manifestActivationHook.d.ts +72 -0
- package/dist/manifestActivationHook.d.ts.map +1 -0
- package/dist/manifestActivationHook.js +180 -0
- package/dist/manifestActivationHook.js.map +1 -0
- package/dist/marketplace.d.ts +156 -0
- package/dist/marketplace.d.ts.map +1 -0
- package/dist/marketplace.js +215 -0
- package/dist/marketplace.js.map +1 -0
- package/dist/matching.d.ts +192 -0
- package/dist/matching.d.ts.map +1 -0
- package/dist/matching.js +138 -0
- package/dist/matching.js.map +1 -0
- package/dist/memory.d.ts +287 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +379 -0
- package/dist/memory.js.map +1 -0
- package/dist/mining.d.ts +155 -0
- package/dist/mining.d.ts.map +1 -0
- package/dist/mining.js +365 -0
- package/dist/mining.js.map +1 -0
- package/dist/oracle.d.ts +30 -0
- package/dist/oracle.d.ts.map +1 -0
- package/dist/oracle.js +31 -0
- package/dist/oracle.js.map +1 -0
- package/dist/policies.d.ts +132 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +62 -0
- package/dist/policies.js.map +1 -0
- package/dist/proactive.d.ts +197 -0
- package/dist/proactive.d.ts.map +1 -0
- package/dist/proactive.js +229 -0
- package/dist/proactive.js.map +1 -0
- package/dist/projects.d.ts +307 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +438 -0
- package/dist/projects.js.map +1 -0
- package/dist/querySegmentation.d.ts +54 -0
- package/dist/querySegmentation.d.ts.map +1 -0
- package/dist/querySegmentation.js +80 -0
- package/dist/querySegmentation.js.map +1 -0
- package/dist/sandbox.d.ts +156 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +425 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/signalActionMap.d.ts +59 -0
- package/dist/signalActionMap.d.ts.map +1 -0
- package/dist/signalActionMap.js +305 -0
- package/dist/signalActionMap.js.map +1 -0
- package/dist/signing.d.ts +94 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +158 -0
- package/dist/signing.js.map +1 -0
- package/dist/social.d.ts +176 -0
- package/dist/social.d.ts.map +1 -0
- package/dist/social.js +232 -0
- package/dist/social.js.map +1 -0
- package/dist/specialization.d.ts +108 -0
- package/dist/specialization.d.ts.map +1 -0
- package/dist/specialization.js +104 -0
- package/dist/specialization.js.map +1 -0
- package/dist/swarms.d.ts +106 -0
- package/dist/swarms.d.ts.map +1 -0
- package/dist/swarms.js +99 -0
- package/dist/swarms.js.map +1 -0
- package/dist/teaching.d.ts +171 -0
- package/dist/teaching.d.ts.map +1 -0
- package/dist/teaching.js +87 -0
- package/dist/teaching.js.map +1 -0
- package/dist/tools.d.ts +223 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +325 -0
- package/dist/tools.js.map +1 -0
- package/dist/treasury-ops.d.ts +101 -0
- package/dist/treasury-ops.d.ts.map +1 -0
- package/dist/treasury-ops.js +59 -0
- package/dist/treasury-ops.js.map +1 -0
- package/dist/types.d.ts +1193 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/wakeUpStack.d.ts +94 -0
- package/dist/wakeUpStack.d.ts.map +1 -0
- package/dist/wakeUpStack.js +215 -0
- package/dist/wakeUpStack.js.map +1 -0
- package/dist/workspace.d.ts +318 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +207 -0
- package/dist/workspace.js.map +1 -0
- package/dist/xmtp.d.ts +85 -0
- package/dist/xmtp.d.ts.map +1 -0
- package/dist/xmtp.js +250 -0
- package/dist/xmtp.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox — abstract base for agent-local code execution.
|
|
3
|
+
*
|
|
4
|
+
* `LocalSandbox` runs commands directly on the host (no isolation, dev only).
|
|
5
|
+
* `DockerSandbox` spawns a long-lived container and shells out to `docker exec`
|
|
6
|
+
* for each call. Both share the same surface so callers can swap them via:
|
|
7
|
+
*
|
|
8
|
+
* const sandbox = process.env.NODE_ENV === "production"
|
|
9
|
+
* ? await DockerSandbox.create({ image: "python:3.12.7-slim" })
|
|
10
|
+
* : await LocalSandbox.create();
|
|
11
|
+
*
|
|
12
|
+
* Sandboxes are AGENT-LOCAL — they are never registered in `ACTION_CATALOG`
|
|
13
|
+
* and never reachable over the network. `asTools()` returns local tool specs
|
|
14
|
+
* an agent can hand to its LLM, but the dispatch happens entirely in-process.
|
|
15
|
+
*
|
|
16
|
+
* Adversarial defaults (DockerSandbox):
|
|
17
|
+
* - `--network none` unless `allowNetwork: true`.
|
|
18
|
+
* - `--cpus 1 --memory 512m` unless overridden.
|
|
19
|
+
* - Mounts only under the caller's cwd unless `allowAnyMount: true`.
|
|
20
|
+
* - Mounts are read-only unless `readonly: false` is set per-mount.
|
|
21
|
+
* - Default image is `python:3.12.7-slim` — pinned minor to resist tag
|
|
22
|
+
* re-publish; callers running untrusted code at scale should override to
|
|
23
|
+
* a digest (`python@sha256:…`) for true immutability.
|
|
24
|
+
* - `close()` is idempotent and actually removes the container.
|
|
25
|
+
*
|
|
26
|
+
* @module sandbox
|
|
27
|
+
*/
|
|
28
|
+
export interface SandboxMount {
|
|
29
|
+
host: string;
|
|
30
|
+
container: string;
|
|
31
|
+
/**
|
|
32
|
+
* Default: read-only. Pass `readonly: false` to enable writes. Read-only is
|
|
33
|
+
* the safer default because untrusted code inside the sandbox cannot use a
|
|
34
|
+
* writable mount to persist changes back to the host filesystem.
|
|
35
|
+
*/
|
|
36
|
+
readonly?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Default Docker image. Pinned to a specific patch version + `slim` variant:
|
|
40
|
+
* - `slim` reduces attack surface (no build toolchain, no compilers).
|
|
41
|
+
* - Pinning to `3.12.7` resists the "tag re-publish" supply-chain vector
|
|
42
|
+
* where a fresh push to `python:3.12` replaces the content behind the tag.
|
|
43
|
+
*
|
|
44
|
+
* Callers running untrusted code at scale SHOULD override with a digest pin:
|
|
45
|
+
* new DockerSandbox({ image: "python@sha256:<digest>" })
|
|
46
|
+
*
|
|
47
|
+
* Bump this default when Python ships a meaningful security release; the
|
|
48
|
+
* argv-injection regex for `image` still requires leading alphanumeric.
|
|
49
|
+
*/
|
|
50
|
+
export declare const DEFAULT_SANDBOX_IMAGE = "python:3.12.7-slim";
|
|
51
|
+
export interface SandboxOptions {
|
|
52
|
+
/** Container image. Default {@link DEFAULT_SANDBOX_IMAGE}. Ignored by `LocalSandbox`. */
|
|
53
|
+
image?: string;
|
|
54
|
+
/** Container port → host port (null = random). */
|
|
55
|
+
ports?: Record<number, number | null>;
|
|
56
|
+
/** Env vars passed into the container / child env. */
|
|
57
|
+
env?: Record<string, string>;
|
|
58
|
+
/** Bind mounts. By default rejected if outside cwd; `allowAnyMount` opts out. */
|
|
59
|
+
mounts?: SandboxMount[];
|
|
60
|
+
/** Allow mount paths outside the caller's cwd. Audit your callers. */
|
|
61
|
+
allowAnyMount?: boolean;
|
|
62
|
+
/** Allow container network access. Off by default for Docker. */
|
|
63
|
+
allowNetwork?: boolean;
|
|
64
|
+
/** CPU limit (cores). Default 1. Docker only. */
|
|
65
|
+
cpus?: number;
|
|
66
|
+
/** Memory limit (e.g. `"512m"`, `"2g"`). Default `"512m"`. Docker only. */
|
|
67
|
+
memory?: string;
|
|
68
|
+
/** Override `docker` binary path. Default `"docker"`. Docker only. */
|
|
69
|
+
dockerBin?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface ExecOptions {
|
|
72
|
+
/** Stdin to pipe into the process. */
|
|
73
|
+
input?: string;
|
|
74
|
+
/** Working directory inside the sandbox. */
|
|
75
|
+
cwd?: string;
|
|
76
|
+
/** Per-call env additions (merged on top of sandbox env). */
|
|
77
|
+
env?: Record<string, string>;
|
|
78
|
+
}
|
|
79
|
+
/** Local tool definition the sandbox exposes via `asTools()`.
|
|
80
|
+
*
|
|
81
|
+
* Distinct from `ToolDefinition` in `tools.ts` (which mirrors the gateway
|
|
82
|
+
* action registry). This shape is for in-process LLM tool-calling — the
|
|
83
|
+
* invoke fn dispatches inside this runtime, never over the wire. */
|
|
84
|
+
export interface SandboxToolDefinition {
|
|
85
|
+
name: string;
|
|
86
|
+
description: string;
|
|
87
|
+
/** JSON Schema of the tool input. */
|
|
88
|
+
parameters: Record<string, unknown>;
|
|
89
|
+
invoke: (args: Record<string, unknown>) => Promise<string>;
|
|
90
|
+
}
|
|
91
|
+
export declare abstract class Sandbox {
|
|
92
|
+
/** Run a command. Returns stdout. Throws with stderr on non-zero exit. */
|
|
93
|
+
abstract exec(cmd: string[], opts?: ExecOptions): Promise<string>;
|
|
94
|
+
/** Copy a local file into the sandbox. */
|
|
95
|
+
abstract put(localPath: string, sandboxPath: string): Promise<void>;
|
|
96
|
+
/** Copy a sandbox file out to a local path. Returns the local path written. */
|
|
97
|
+
abstract get(sandboxPath: string, localPath: string): Promise<string>;
|
|
98
|
+
/** Map a container port to a reachable host endpoint string. */
|
|
99
|
+
abstract endpoint(port: number): string;
|
|
100
|
+
/** Idempotent. Safe to call multiple times. Tests verify the resource is freed. */
|
|
101
|
+
abstract close(): Promise<void>;
|
|
102
|
+
/** Run a Python script via stdin. */
|
|
103
|
+
python(script: string): Promise<string>;
|
|
104
|
+
/** Run a shell command. */
|
|
105
|
+
sh(command: string): Promise<string>;
|
|
106
|
+
/** Returns local tool specs callers can pass to their LLM tool list. */
|
|
107
|
+
asTools(): SandboxToolDefinition[];
|
|
108
|
+
}
|
|
109
|
+
export declare class LocalSandbox extends Sandbox {
|
|
110
|
+
private readonly env;
|
|
111
|
+
private readonly cwd;
|
|
112
|
+
private closed;
|
|
113
|
+
private constructor();
|
|
114
|
+
static create(opts?: SandboxOptions): Promise<LocalSandbox>;
|
|
115
|
+
exec(cmd: string[], opts?: ExecOptions): Promise<string>;
|
|
116
|
+
put(localPath: string, sandboxPath: string): Promise<void>;
|
|
117
|
+
get(sandboxPath: string, localPath: string): Promise<string>;
|
|
118
|
+
endpoint(_port: number): string;
|
|
119
|
+
close(): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
export declare class DockerSandbox extends Sandbox {
|
|
122
|
+
private readonly opts;
|
|
123
|
+
private readonly internal;
|
|
124
|
+
private constructor();
|
|
125
|
+
/** Spin up a long-lived container. Throws if Docker is unreachable. */
|
|
126
|
+
static create(opts?: SandboxOptions): Promise<DockerSandbox>;
|
|
127
|
+
/** Reattach to an existing container by id. */
|
|
128
|
+
static connect(containerId: string, opts?: SandboxOptions): Promise<DockerSandbox>;
|
|
129
|
+
/** Visible for tests — does NOT execute docker. */
|
|
130
|
+
static buildRunArgs(opts: {
|
|
131
|
+
image: string;
|
|
132
|
+
cpus: number;
|
|
133
|
+
memory: string;
|
|
134
|
+
ports?: Record<number, number | null>;
|
|
135
|
+
env?: Record<string, string>;
|
|
136
|
+
mounts?: SandboxMount[];
|
|
137
|
+
allowNetwork: boolean;
|
|
138
|
+
}): string[];
|
|
139
|
+
private static validateMounts;
|
|
140
|
+
private static discoverPorts;
|
|
141
|
+
exec(cmd: string[], opts?: ExecOptions): Promise<string>;
|
|
142
|
+
put(localPath: string, sandboxPath: string): Promise<void>;
|
|
143
|
+
get(sandboxPath: string, localPath: string): Promise<string>;
|
|
144
|
+
endpoint(port: number): string;
|
|
145
|
+
/** Idempotent. Force-removes the container and marks closed. */
|
|
146
|
+
close(): Promise<void>;
|
|
147
|
+
/** Test inspection — container id assigned at create. */
|
|
148
|
+
get containerId(): string;
|
|
149
|
+
}
|
|
150
|
+
/** Sentinel for downstream code that wants to detect a sandbox at the type
|
|
151
|
+
* level without importing the abstract class directly. */
|
|
152
|
+
export declare function isSandbox(value: unknown): value is Sandbox;
|
|
153
|
+
/** Returns true if `docker version` succeeds. Useful for callers that want
|
|
154
|
+
* to fall back to `LocalSandbox` when Docker is unavailable. */
|
|
155
|
+
export declare function isDockerAvailable(dockerBin?: string): Promise<boolean>;
|
|
156
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
|
package/dist/sandbox.js
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox — abstract base for agent-local code execution.
|
|
3
|
+
*
|
|
4
|
+
* `LocalSandbox` runs commands directly on the host (no isolation, dev only).
|
|
5
|
+
* `DockerSandbox` spawns a long-lived container and shells out to `docker exec`
|
|
6
|
+
* for each call. Both share the same surface so callers can swap them via:
|
|
7
|
+
*
|
|
8
|
+
* const sandbox = process.env.NODE_ENV === "production"
|
|
9
|
+
* ? await DockerSandbox.create({ image: "python:3.12.7-slim" })
|
|
10
|
+
* : await LocalSandbox.create();
|
|
11
|
+
*
|
|
12
|
+
* Sandboxes are AGENT-LOCAL — they are never registered in `ACTION_CATALOG`
|
|
13
|
+
* and never reachable over the network. `asTools()` returns local tool specs
|
|
14
|
+
* an agent can hand to its LLM, but the dispatch happens entirely in-process.
|
|
15
|
+
*
|
|
16
|
+
* Adversarial defaults (DockerSandbox):
|
|
17
|
+
* - `--network none` unless `allowNetwork: true`.
|
|
18
|
+
* - `--cpus 1 --memory 512m` unless overridden.
|
|
19
|
+
* - Mounts only under the caller's cwd unless `allowAnyMount: true`.
|
|
20
|
+
* - Mounts are read-only unless `readonly: false` is set per-mount.
|
|
21
|
+
* - Default image is `python:3.12.7-slim` — pinned minor to resist tag
|
|
22
|
+
* re-publish; callers running untrusted code at scale should override to
|
|
23
|
+
* a digest (`python@sha256:…`) for true immutability.
|
|
24
|
+
* - `close()` is idempotent and actually removes the container.
|
|
25
|
+
*
|
|
26
|
+
* @module sandbox
|
|
27
|
+
*/
|
|
28
|
+
import { spawn } from "node:child_process";
|
|
29
|
+
import { promises as fs, realpathSync } from "node:fs";
|
|
30
|
+
import path from "node:path";
|
|
31
|
+
// ── Argv-injection guards ────────────────────────────────────
|
|
32
|
+
//
|
|
33
|
+
// These validators exist because `SandboxOptions` flows into a `docker run`
|
|
34
|
+
// argv. Even though we use array-form spawn (no shell), Docker itself parses
|
|
35
|
+
// flags, and some fields (env values, image names) can be weaponized if
|
|
36
|
+
// callers ever pipe untrusted input through. All are defense-in-depth — the
|
|
37
|
+
// sandbox is agent-local and caller-constructed today.
|
|
38
|
+
/** POSIX env var name: `[A-Za-z_][A-Za-z0-9_]*`. Rejects anything that could
|
|
39
|
+
* confuse shells or POSIX env-parsers in the container. */
|
|
40
|
+
const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
41
|
+
/** Docker image reference: letters/digits/`._/:@-`, must start with an
|
|
42
|
+
* alphanumeric so it never looks like a flag to `docker run`. */
|
|
43
|
+
const DOCKER_IMAGE_RE = /^[A-Za-z0-9][A-Za-z0-9._/:@-]*$/;
|
|
44
|
+
function assertEnvPair(key, value) {
|
|
45
|
+
if (!ENV_KEY_RE.test(key)) {
|
|
46
|
+
throw new Error(`DockerSandbox: invalid env key '${key}' (must match ${ENV_KEY_RE.source})`);
|
|
47
|
+
}
|
|
48
|
+
if (value.includes("\n") || value.includes("\0")) {
|
|
49
|
+
throw new Error(`DockerSandbox: env value for '${key}' contains newline or NUL`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function assertImage(image) {
|
|
53
|
+
if (!DOCKER_IMAGE_RE.test(image)) {
|
|
54
|
+
throw new Error(`DockerSandbox: invalid image '${image}' (must match ${DOCKER_IMAGE_RE.source})`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Default Docker image. Pinned to a specific patch version + `slim` variant:
|
|
59
|
+
* - `slim` reduces attack surface (no build toolchain, no compilers).
|
|
60
|
+
* - Pinning to `3.12.7` resists the "tag re-publish" supply-chain vector
|
|
61
|
+
* where a fresh push to `python:3.12` replaces the content behind the tag.
|
|
62
|
+
*
|
|
63
|
+
* Callers running untrusted code at scale SHOULD override with a digest pin:
|
|
64
|
+
* new DockerSandbox({ image: "python@sha256:<digest>" })
|
|
65
|
+
*
|
|
66
|
+
* Bump this default when Python ships a meaningful security release; the
|
|
67
|
+
* argv-injection regex for `image` still requires leading alphanumeric.
|
|
68
|
+
*/
|
|
69
|
+
export const DEFAULT_SANDBOX_IMAGE = "python:3.12.7-slim";
|
|
70
|
+
// ── Base ─────────────────────────────────────────────────────
|
|
71
|
+
export class Sandbox {
|
|
72
|
+
/** Run a Python script via stdin. */
|
|
73
|
+
async python(script) {
|
|
74
|
+
return this.exec(["python3", "-"], { input: script });
|
|
75
|
+
}
|
|
76
|
+
/** Run a shell command. */
|
|
77
|
+
async sh(command) {
|
|
78
|
+
return this.exec(["sh", "-c", command]);
|
|
79
|
+
}
|
|
80
|
+
/** Returns local tool specs callers can pass to their LLM tool list. */
|
|
81
|
+
asTools() {
|
|
82
|
+
return [
|
|
83
|
+
{
|
|
84
|
+
name: "python",
|
|
85
|
+
description: "Run a Python 3 script in the sandbox. Returns stdout.",
|
|
86
|
+
parameters: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
script: { type: "string", description: "Python source to execute." },
|
|
90
|
+
},
|
|
91
|
+
required: ["script"],
|
|
92
|
+
},
|
|
93
|
+
invoke: async (args) => this.python(String(args.script ?? "")),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "sh",
|
|
97
|
+
description: "Run a shell command in the sandbox. Returns stdout.",
|
|
98
|
+
parameters: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {
|
|
101
|
+
command: { type: "string", description: "Shell command line." },
|
|
102
|
+
},
|
|
103
|
+
required: ["command"],
|
|
104
|
+
},
|
|
105
|
+
invoke: async (args) => this.sh(String(args.command ?? "")),
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ── LocalSandbox (no isolation; dev / tests only) ────────────
|
|
111
|
+
/**
|
|
112
|
+
* Silence the dev-only warning when set truthy. Escape hatch for test harnesses
|
|
113
|
+
* or intentionally-unsafe prototypes that don't want log noise. Production
|
|
114
|
+
* agents should never set this — use {@link DockerSandbox} instead.
|
|
115
|
+
*/
|
|
116
|
+
const LOCAL_SANDBOX_SILENCE_ENV = "NOOKPLOT_LOCAL_SANDBOX_SILENCE";
|
|
117
|
+
function emitLocalSandboxWarning() {
|
|
118
|
+
const env = process.env;
|
|
119
|
+
if (env.NODE_ENV === "test")
|
|
120
|
+
return;
|
|
121
|
+
if (env[LOCAL_SANDBOX_SILENCE_ENV])
|
|
122
|
+
return;
|
|
123
|
+
// Keep the message terse — it prints on every `create()` and that's fine:
|
|
124
|
+
// a production agent creating many LocalSandboxes is itself a bug signal.
|
|
125
|
+
console.warn("[LocalSandbox] No process isolation — commands run directly on the host. " +
|
|
126
|
+
"Use DockerSandbox for untrusted code in production. " +
|
|
127
|
+
`Silence with ${LOCAL_SANDBOX_SILENCE_ENV}=1.`);
|
|
128
|
+
}
|
|
129
|
+
export class LocalSandbox extends Sandbox {
|
|
130
|
+
env;
|
|
131
|
+
cwd;
|
|
132
|
+
closed = false;
|
|
133
|
+
constructor(opts = {}) {
|
|
134
|
+
super();
|
|
135
|
+
this.env = { ...opts.env };
|
|
136
|
+
this.cwd = process.cwd();
|
|
137
|
+
}
|
|
138
|
+
static async create(opts = {}) {
|
|
139
|
+
emitLocalSandboxWarning();
|
|
140
|
+
return new LocalSandbox(opts);
|
|
141
|
+
}
|
|
142
|
+
async exec(cmd, opts = {}) {
|
|
143
|
+
if (this.closed)
|
|
144
|
+
throw new Error("LocalSandbox: closed");
|
|
145
|
+
if (cmd.length === 0)
|
|
146
|
+
throw new Error("LocalSandbox: empty command");
|
|
147
|
+
const [bin, ...args] = cmd;
|
|
148
|
+
return runProcess(bin, args, {
|
|
149
|
+
input: opts.input,
|
|
150
|
+
cwd: opts.cwd ?? this.cwd,
|
|
151
|
+
env: { ...process.env, ...this.env, ...(opts.env ?? {}) },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async put(localPath, sandboxPath) {
|
|
155
|
+
if (this.closed)
|
|
156
|
+
throw new Error("LocalSandbox: closed");
|
|
157
|
+
await fs.mkdir(path.dirname(sandboxPath), { recursive: true });
|
|
158
|
+
await fs.copyFile(localPath, sandboxPath);
|
|
159
|
+
}
|
|
160
|
+
async get(sandboxPath, localPath) {
|
|
161
|
+
if (this.closed)
|
|
162
|
+
throw new Error("LocalSandbox: closed");
|
|
163
|
+
await fs.mkdir(path.dirname(localPath), { recursive: true });
|
|
164
|
+
await fs.copyFile(sandboxPath, localPath);
|
|
165
|
+
return localPath;
|
|
166
|
+
}
|
|
167
|
+
endpoint(_port) {
|
|
168
|
+
throw new Error("LocalSandbox: endpoint() unsupported (no port mapping)");
|
|
169
|
+
}
|
|
170
|
+
async close() {
|
|
171
|
+
this.closed = true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export class DockerSandbox extends Sandbox {
|
|
175
|
+
opts;
|
|
176
|
+
internal;
|
|
177
|
+
constructor(opts, internal) {
|
|
178
|
+
super();
|
|
179
|
+
this.opts = {
|
|
180
|
+
...opts,
|
|
181
|
+
image: opts.image ?? DEFAULT_SANDBOX_IMAGE,
|
|
182
|
+
cpus: opts.cpus ?? 1,
|
|
183
|
+
memory: opts.memory ?? "512m",
|
|
184
|
+
};
|
|
185
|
+
this.internal = internal;
|
|
186
|
+
}
|
|
187
|
+
/** Spin up a long-lived container. Throws if Docker is unreachable. */
|
|
188
|
+
static async create(opts = {}) {
|
|
189
|
+
const dockerBin = opts.dockerBin ?? "docker";
|
|
190
|
+
const image = opts.image ?? DEFAULT_SANDBOX_IMAGE;
|
|
191
|
+
const cpus = opts.cpus ?? 1;
|
|
192
|
+
const memory = opts.memory ?? "512m";
|
|
193
|
+
DockerSandbox.validateMounts(opts.mounts ?? [], opts.allowAnyMount === true);
|
|
194
|
+
const args = DockerSandbox.buildRunArgs({
|
|
195
|
+
image,
|
|
196
|
+
cpus,
|
|
197
|
+
memory,
|
|
198
|
+
ports: opts.ports,
|
|
199
|
+
env: opts.env,
|
|
200
|
+
mounts: opts.mounts,
|
|
201
|
+
allowNetwork: opts.allowNetwork === true,
|
|
202
|
+
});
|
|
203
|
+
const containerIdRaw = await runProcess(dockerBin, args, {});
|
|
204
|
+
const containerId = containerIdRaw.trim();
|
|
205
|
+
if (!containerId) {
|
|
206
|
+
throw new Error("DockerSandbox: docker run returned empty container id");
|
|
207
|
+
}
|
|
208
|
+
const hostPortByContainer = await DockerSandbox.discoverPorts(dockerBin, containerId, Object.keys(opts.ports ?? {}).map((p) => Number(p)));
|
|
209
|
+
return new DockerSandbox(opts, {
|
|
210
|
+
containerId,
|
|
211
|
+
hostPortByContainer,
|
|
212
|
+
dockerBin,
|
|
213
|
+
closed: false,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/** Reattach to an existing container by id. */
|
|
217
|
+
static async connect(containerId, opts = {}) {
|
|
218
|
+
const dockerBin = opts.dockerBin ?? "docker";
|
|
219
|
+
const inspect = await runProcess(dockerBin, ["inspect", "--format", "{{.State.Running}}", containerId], {});
|
|
220
|
+
if (inspect.trim() !== "true") {
|
|
221
|
+
throw new Error(`DockerSandbox: container ${containerId} is not running`);
|
|
222
|
+
}
|
|
223
|
+
const hostPortByContainer = await DockerSandbox.discoverPorts(dockerBin, containerId, Object.keys(opts.ports ?? {}).map((p) => Number(p)));
|
|
224
|
+
return new DockerSandbox(opts, {
|
|
225
|
+
containerId,
|
|
226
|
+
hostPortByContainer,
|
|
227
|
+
dockerBin,
|
|
228
|
+
closed: false,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
/** Visible for tests — does NOT execute docker. */
|
|
232
|
+
static buildRunArgs(opts) {
|
|
233
|
+
assertImage(opts.image);
|
|
234
|
+
const args = [
|
|
235
|
+
"run",
|
|
236
|
+
"-d",
|
|
237
|
+
"--rm",
|
|
238
|
+
"--cpus",
|
|
239
|
+
String(opts.cpus),
|
|
240
|
+
"--memory",
|
|
241
|
+
opts.memory,
|
|
242
|
+
];
|
|
243
|
+
if (!opts.allowNetwork)
|
|
244
|
+
args.push("--network", "none");
|
|
245
|
+
for (const [containerPortStr, hostPort] of Object.entries(opts.ports ?? {})) {
|
|
246
|
+
const containerPort = Number(containerPortStr);
|
|
247
|
+
if (hostPort === null || hostPort === undefined) {
|
|
248
|
+
args.push("-p", `${containerPort}`);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
args.push("-p", `${hostPort}:${containerPort}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
for (const [key, value] of Object.entries(opts.env ?? {})) {
|
|
255
|
+
assertEnvPair(key, value);
|
|
256
|
+
args.push("-e", `${key}=${value}`);
|
|
257
|
+
}
|
|
258
|
+
for (const mount of opts.mounts ?? []) {
|
|
259
|
+
// Default to read-only. Writes require explicit `readonly: false`.
|
|
260
|
+
// Undefined/true/missing → ro; only `false` opts into rw. This closes
|
|
261
|
+
// the "untrusted code writes back to the host" path by default.
|
|
262
|
+
const flag = mount.readonly === false ? "rw" : "ro";
|
|
263
|
+
args.push("-v", `${path.resolve(mount.host)}:${mount.container}:${flag}`);
|
|
264
|
+
}
|
|
265
|
+
// `assertImage` above rejects leading-dash image names, so positional
|
|
266
|
+
// placement of `image` cannot be mis-parsed as a docker-run flag.
|
|
267
|
+
args.push(opts.image, "sleep", "infinity");
|
|
268
|
+
return args;
|
|
269
|
+
}
|
|
270
|
+
static validateMounts(mounts, allowAny) {
|
|
271
|
+
if (allowAny)
|
|
272
|
+
return;
|
|
273
|
+
// Use realpath on BOTH sides so a symlink inside cwd pointing outside it
|
|
274
|
+
// cannot slip past the check. Matches the Python side's behavior.
|
|
275
|
+
let cwd;
|
|
276
|
+
try {
|
|
277
|
+
cwd = realpathSync(process.cwd());
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
cwd = path.resolve(process.cwd());
|
|
281
|
+
}
|
|
282
|
+
for (const mount of mounts) {
|
|
283
|
+
const abs = path.resolve(mount.host);
|
|
284
|
+
let resolved;
|
|
285
|
+
try {
|
|
286
|
+
resolved = realpathSync(abs);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// Path doesn't exist yet — fall back to the lexical resolution.
|
|
290
|
+
resolved = abs;
|
|
291
|
+
}
|
|
292
|
+
const rel = path.relative(cwd, resolved);
|
|
293
|
+
const escapes = rel === ".." || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel);
|
|
294
|
+
if (escapes) {
|
|
295
|
+
throw new Error(`DockerSandbox: mount '${mount.host}' resolves outside cwd; pass allowAnyMount: true to override`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
static async discoverPorts(dockerBin, containerId, requestedContainerPorts) {
|
|
300
|
+
const out = new Map();
|
|
301
|
+
for (const containerPort of requestedContainerPorts) {
|
|
302
|
+
try {
|
|
303
|
+
const raw = await runProcess(dockerBin, ["port", containerId, String(containerPort)], {});
|
|
304
|
+
// Format: "0.0.0.0:54321\n" — take the first line and the port after the colon.
|
|
305
|
+
const first = raw.split(/\r?\n/)[0]?.trim() ?? "";
|
|
306
|
+
const colon = first.lastIndexOf(":");
|
|
307
|
+
if (colon >= 0) {
|
|
308
|
+
const hostPort = Number(first.slice(colon + 1));
|
|
309
|
+
if (Number.isFinite(hostPort))
|
|
310
|
+
out.set(containerPort, hostPort);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// Port not exposed — skip; endpoint() will throw with a clear message.
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return out;
|
|
318
|
+
}
|
|
319
|
+
async exec(cmd, opts = {}) {
|
|
320
|
+
if (this.internal.closed)
|
|
321
|
+
throw new Error("DockerSandbox: closed");
|
|
322
|
+
if (cmd.length === 0)
|
|
323
|
+
throw new Error("DockerSandbox: empty command");
|
|
324
|
+
const args = ["exec"];
|
|
325
|
+
if (opts.input !== undefined)
|
|
326
|
+
args.push("-i");
|
|
327
|
+
if (opts.cwd)
|
|
328
|
+
args.push("-w", opts.cwd);
|
|
329
|
+
for (const [k, v] of Object.entries(opts.env ?? {})) {
|
|
330
|
+
args.push("-e", `${k}=${v}`);
|
|
331
|
+
}
|
|
332
|
+
args.push(this.internal.containerId, ...cmd);
|
|
333
|
+
return runProcess(this.internal.dockerBin, args, { input: opts.input });
|
|
334
|
+
}
|
|
335
|
+
async put(localPath, sandboxPath) {
|
|
336
|
+
if (this.internal.closed)
|
|
337
|
+
throw new Error("DockerSandbox: closed");
|
|
338
|
+
await runProcess(this.internal.dockerBin, ["cp", localPath, `${this.internal.containerId}:${sandboxPath}`], {});
|
|
339
|
+
}
|
|
340
|
+
async get(sandboxPath, localPath) {
|
|
341
|
+
if (this.internal.closed)
|
|
342
|
+
throw new Error("DockerSandbox: closed");
|
|
343
|
+
await fs.mkdir(path.dirname(localPath), { recursive: true });
|
|
344
|
+
await runProcess(this.internal.dockerBin, ["cp", `${this.internal.containerId}:${sandboxPath}`, localPath], {});
|
|
345
|
+
return localPath;
|
|
346
|
+
}
|
|
347
|
+
endpoint(port) {
|
|
348
|
+
const hostPort = this.internal.hostPortByContainer.get(port);
|
|
349
|
+
if (hostPort === undefined) {
|
|
350
|
+
throw new Error(`DockerSandbox: port ${port} not mapped`);
|
|
351
|
+
}
|
|
352
|
+
return `localhost:${hostPort}`;
|
|
353
|
+
}
|
|
354
|
+
/** Idempotent. Force-removes the container and marks closed. */
|
|
355
|
+
async close() {
|
|
356
|
+
if (this.internal.closed)
|
|
357
|
+
return;
|
|
358
|
+
this.internal.closed = true;
|
|
359
|
+
try {
|
|
360
|
+
await runProcess(this.internal.dockerBin, ["rm", "-f", this.internal.containerId], {});
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
// Container may already be gone (e.g. --rm fired). Closed flag still
|
|
364
|
+
// flipped, so subsequent calls short-circuit. Leaving a leaked container
|
|
365
|
+
// would be a security bug — but `rm -f` is the strongest guarantee
|
|
366
|
+
// available from this side; failures here mean Docker itself is wedged.
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/** Test inspection — container id assigned at create. */
|
|
370
|
+
get containerId() {
|
|
371
|
+
return this.internal.containerId;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/** Spawn a process, capture stdout. Throws on non-zero exit. */
|
|
375
|
+
function runProcess(bin, args, opts) {
|
|
376
|
+
return new Promise((resolve, reject) => {
|
|
377
|
+
const spawnOpts = {
|
|
378
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
379
|
+
};
|
|
380
|
+
if (opts.cwd)
|
|
381
|
+
spawnOpts.cwd = opts.cwd;
|
|
382
|
+
if (opts.env)
|
|
383
|
+
spawnOpts.env = opts.env;
|
|
384
|
+
const child = spawn(bin, args, spawnOpts);
|
|
385
|
+
const stdoutChunks = [];
|
|
386
|
+
const stderrChunks = [];
|
|
387
|
+
child.stdout?.on("data", (chunk) => stdoutChunks.push(chunk));
|
|
388
|
+
child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
|
|
389
|
+
child.on("error", reject);
|
|
390
|
+
child.on("close", (code) => {
|
|
391
|
+
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
392
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
393
|
+
if (code === 0) {
|
|
394
|
+
resolve(stdout);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
const detail = stderr.trim() || stdout.trim() || "(no output)";
|
|
398
|
+
reject(new Error(`${bin} exited ${code}: ${detail}`));
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
if (opts.input !== undefined && child.stdin) {
|
|
402
|
+
child.stdin.end(opts.input);
|
|
403
|
+
}
|
|
404
|
+
else if (child.stdin) {
|
|
405
|
+
child.stdin.end();
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/** Sentinel for downstream code that wants to detect a sandbox at the type
|
|
410
|
+
* level without importing the abstract class directly. */
|
|
411
|
+
export function isSandbox(value) {
|
|
412
|
+
return value instanceof Sandbox;
|
|
413
|
+
}
|
|
414
|
+
/** Returns true if `docker version` succeeds. Useful for callers that want
|
|
415
|
+
* to fall back to `LocalSandbox` when Docker is unavailable. */
|
|
416
|
+
export async function isDockerAvailable(dockerBin = "docker") {
|
|
417
|
+
try {
|
|
418
|
+
await runProcess(dockerBin, ["version", "--format", "{{.Server.Version}}"], {});
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"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"}
|