agent-nuvira 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +891 -0
- package/dist/agent-sdk/src/agent.d.ts +118 -0
- package/dist/agent-sdk/src/agent.d.ts.map +1 -0
- package/dist/agent-sdk/src/agent.js +88 -0
- package/dist/agent-sdk/src/agent.js.map +1 -0
- package/dist/agent-sdk/src/index.d.ts +33 -0
- package/dist/agent-sdk/src/index.d.ts.map +1 -0
- package/dist/agent-sdk/src/index.js +32 -0
- package/dist/agent-sdk/src/index.js.map +1 -0
- package/dist/agent-sdk/src/register.d.ts +70 -0
- package/dist/agent-sdk/src/register.d.ts.map +1 -0
- package/dist/agent-sdk/src/register.js +181 -0
- package/dist/agent-sdk/src/register.js.map +1 -0
- package/dist/agent-sdk/src/scaffold.d.ts +50 -0
- package/dist/agent-sdk/src/scaffold.d.ts.map +1 -0
- package/dist/agent-sdk/src/scaffold.js +291 -0
- package/dist/agent-sdk/src/scaffold.js.map +1 -0
- package/dist/agent-sdk/src/testing.d.ts +187 -0
- package/dist/agent-sdk/src/testing.d.ts.map +1 -0
- package/dist/agent-sdk/src/testing.js +243 -0
- package/dist/agent-sdk/src/testing.js.map +1 -0
- package/dist/agent-sdk/src/types.d.ts +202 -0
- package/dist/agent-sdk/src/types.d.ts.map +1 -0
- package/dist/agent-sdk/src/types.js +11 -0
- package/dist/agent-sdk/src/types.js.map +1 -0
- package/dist/agents/agent.d.ts +132 -0
- package/dist/agents/agent.d.ts.map +1 -0
- package/dist/agents/agent.js +19 -0
- package/dist/agents/agent.js.map +1 -0
- package/dist/agents/agents/context-gatherer.d.ts +42 -0
- package/dist/agents/agents/context-gatherer.d.ts.map +1 -0
- package/dist/agents/agents/context-gatherer.js +366 -0
- package/dist/agents/agents/context-gatherer.js.map +1 -0
- package/dist/agents/agents/debugger.d.ts +58 -0
- package/dist/agents/agents/debugger.d.ts.map +1 -0
- package/dist/agents/agents/debugger.js +257 -0
- package/dist/agents/agents/debugger.js.map +1 -0
- package/dist/agents/agents/git-agent.d.ts +34 -0
- package/dist/agents/agents/git-agent.d.ts.map +1 -0
- package/dist/agents/agents/git-agent.js +200 -0
- package/dist/agents/agents/git-agent.js.map +1 -0
- package/dist/agents/agents/github-release-agent.d.ts +65 -0
- package/dist/agents/agents/github-release-agent.d.ts.map +1 -0
- package/dist/agents/agents/github-release-agent.js +439 -0
- package/dist/agents/agents/github-release-agent.js.map +1 -0
- package/dist/agents/agents/package-agent.d.ts +33 -0
- package/dist/agents/agents/package-agent.d.ts.map +1 -0
- package/dist/agents/agents/package-agent.js +233 -0
- package/dist/agents/agents/package-agent.js.map +1 -0
- package/dist/agents/agents/planner.d.ts +26 -0
- package/dist/agents/agents/planner.d.ts.map +1 -0
- package/dist/agents/agents/planner.js +222 -0
- package/dist/agents/agents/planner.js.map +1 -0
- package/dist/agents/agents/reviewer.d.ts +34 -0
- package/dist/agents/agents/reviewer.d.ts.map +1 -0
- package/dist/agents/agents/reviewer.js +159 -0
- package/dist/agents/agents/reviewer.js.map +1 -0
- package/dist/agents/agents/runner.d.ts +73 -0
- package/dist/agents/agents/runner.d.ts.map +1 -0
- package/dist/agents/agents/runner.js +299 -0
- package/dist/agents/agents/runner.js.map +1 -0
- package/dist/agents/agents/security-agent.d.ts +33 -0
- package/dist/agents/agents/security-agent.d.ts.map +1 -0
- package/dist/agents/agents/security-agent.js +184 -0
- package/dist/agents/agents/security-agent.js.map +1 -0
- package/dist/agents/agents/tester.d.ts +96 -0
- package/dist/agents/agents/tester.d.ts.map +1 -0
- package/dist/agents/agents/tester.js +410 -0
- package/dist/agents/agents/tester.js.map +1 -0
- package/dist/agents/agents/writer.d.ts +51 -0
- package/dist/agents/agents/writer.d.ts.map +1 -0
- package/dist/agents/agents/writer.js +384 -0
- package/dist/agents/agents/writer.js.map +1 -0
- package/dist/agents/context-vault.d.ts +49 -0
- package/dist/agents/context-vault.d.ts.map +1 -0
- package/dist/agents/context-vault.js +134 -0
- package/dist/agents/context-vault.js.map +1 -0
- package/dist/agents/orchestrator.d.ts +97 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +696 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/utils/file-tree.d.ts +28 -0
- package/dist/agents/utils/file-tree.d.ts.map +1 -0
- package/dist/agents/utils/file-tree.js +93 -0
- package/dist/agents/utils/file-tree.js.map +1 -0
- package/dist/cli/agent.d.ts +25 -0
- package/dist/cli/agent.d.ts.map +1 -0
- package/dist/cli/agent.js +374 -0
- package/dist/cli/agent.js.map +1 -0
- package/dist/cli/benchmark.d.ts +24 -0
- package/dist/cli/benchmark.d.ts.map +1 -0
- package/dist/cli/benchmark.js +235 -0
- package/dist/cli/benchmark.js.map +1 -0
- package/dist/cli/cache.d.ts +12 -0
- package/dist/cli/cache.d.ts.map +1 -0
- package/dist/cli/cache.js +58 -0
- package/dist/cli/cache.js.map +1 -0
- package/dist/cli/chat.d.ts +37 -0
- package/dist/cli/chat.d.ts.map +1 -0
- package/dist/cli/chat.js +393 -0
- package/dist/cli/chat.js.map +1 -0
- package/dist/cli/commands.d.ts +24 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +18 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +19 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +162 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/dashboard.d.ts +34 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +126 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/doctor.d.ts +68 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +585 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/edit.d.ts +11 -0
- package/dist/cli/edit.d.ts.map +1 -0
- package/dist/cli/edit.js +86 -0
- package/dist/cli/edit.js.map +1 -0
- package/dist/cli/execute.d.ts +25 -0
- package/dist/cli/execute.d.ts.map +1 -0
- package/dist/cli/execute.js +186 -0
- package/dist/cli/execute.js.map +1 -0
- package/dist/cli/federation.d.ts +31 -0
- package/dist/cli/federation.d.ts.map +1 -0
- package/dist/cli/federation.js +387 -0
- package/dist/cli/federation.js.map +1 -0
- package/dist/cli/history.d.ts +22 -0
- package/dist/cli/history.d.ts.map +1 -0
- package/dist/cli/history.js +140 -0
- package/dist/cli/history.js.map +1 -0
- package/dist/cli/init.d.ts +49 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +423 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/learn.d.ts +31 -0
- package/dist/cli/learn.d.ts.map +1 -0
- package/dist/cli/learn.js +320 -0
- package/dist/cli/learn.js.map +1 -0
- package/dist/cli/memory.d.ts +38 -0
- package/dist/cli/memory.d.ts.map +1 -0
- package/dist/cli/memory.js +295 -0
- package/dist/cli/memory.js.map +1 -0
- package/dist/cli/model-picker.d.ts +18 -0
- package/dist/cli/model-picker.d.ts.map +1 -0
- package/dist/cli/model-picker.js +225 -0
- package/dist/cli/model-picker.js.map +1 -0
- package/dist/cli/models.d.ts +11 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +132 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +11 -0
- package/dist/cli/plan.d.ts.map +1 -0
- package/dist/cli/plan.js +94 -0
- package/dist/cli/plan.js.map +1 -0
- package/dist/cli/plugins.d.ts +15 -0
- package/dist/cli/plugins.d.ts.map +1 -0
- package/dist/cli/plugins.js +123 -0
- package/dist/cli/plugins.js.map +1 -0
- package/dist/cli/router.d.ts +20 -0
- package/dist/cli/router.d.ts.map +1 -0
- package/dist/cli/router.js +142 -0
- package/dist/cli/router.js.map +1 -0
- package/dist/cli/run.d.ts +22 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +110 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/sandbox.d.ts +27 -0
- package/dist/cli/sandbox.d.ts.map +1 -0
- package/dist/cli/sandbox.js +264 -0
- package/dist/cli/sandbox.js.map +1 -0
- package/dist/cli/sdk.d.ts +27 -0
- package/dist/cli/sdk.d.ts.map +1 -0
- package/dist/cli/sdk.js +204 -0
- package/dist/cli/sdk.js.map +1 -0
- package/dist/cli/stats.d.ts +18 -0
- package/dist/cli/stats.d.ts.map +1 -0
- package/dist/cli/stats.js +78 -0
- package/dist/cli/stats.js.map +1 -0
- package/dist/cli/team.d.ts +42 -0
- package/dist/cli/team.d.ts.map +1 -0
- package/dist/cli/team.js +473 -0
- package/dist/cli/team.js.map +1 -0
- package/dist/cli/workflow.d.ts +27 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +347 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/config/manager.d.ts +37 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +147 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +53 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/context/cache.d.ts +27 -0
- package/dist/context/cache.d.ts.map +1 -0
- package/dist/context/cache.js +116 -0
- package/dist/context/cache.js.map +1 -0
- package/dist/context/history.d.ts +87 -0
- package/dist/context/history.d.ts.map +1 -0
- package/dist/context/history.js +249 -0
- package/dist/context/history.js.map +1 -0
- package/dist/context/parser.d.ts +61 -0
- package/dist/context/parser.d.ts.map +1 -0
- package/dist/context/parser.js +194 -0
- package/dist/context/parser.js.map +1 -0
- package/dist/federation/client.d.ts +49 -0
- package/dist/federation/client.d.ts.map +1 -0
- package/dist/federation/client.js +239 -0
- package/dist/federation/client.js.map +1 -0
- package/dist/federation/protocol.d.ts +155 -0
- package/dist/federation/protocol.d.ts.map +1 -0
- package/dist/federation/protocol.js +57 -0
- package/dist/federation/protocol.js.map +1 -0
- package/dist/federation/server.d.ts +25 -0
- package/dist/federation/server.d.ts.map +1 -0
- package/dist/federation/server.js +401 -0
- package/dist/federation/server.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/inference/factory.d.ts +20 -0
- package/dist/inference/factory.d.ts.map +1 -0
- package/dist/inference/factory.js +46 -0
- package/dist/inference/factory.js.map +1 -0
- package/dist/inference/gemini-adapter.d.ts +17 -0
- package/dist/inference/gemini-adapter.d.ts.map +1 -0
- package/dist/inference/gemini-adapter.js +176 -0
- package/dist/inference/gemini-adapter.js.map +1 -0
- package/dist/inference/groq-adapter.d.ts +17 -0
- package/dist/inference/groq-adapter.d.ts.map +1 -0
- package/dist/inference/groq-adapter.js +103 -0
- package/dist/inference/groq-adapter.js.map +1 -0
- package/dist/inference/interface.d.ts +49 -0
- package/dist/inference/interface.d.ts.map +1 -0
- package/dist/inference/interface.js +2 -0
- package/dist/inference/interface.js.map +1 -0
- package/dist/inference/local-adapter.d.ts +35 -0
- package/dist/inference/local-adapter.d.ts.map +1 -0
- package/dist/inference/local-adapter.js +311 -0
- package/dist/inference/local-adapter.js.map +1 -0
- package/dist/inference/model-catalog.d.ts +53 -0
- package/dist/inference/model-catalog.d.ts.map +1 -0
- package/dist/inference/model-catalog.js +306 -0
- package/dist/inference/model-catalog.js.map +1 -0
- package/dist/inference/nim-adapter.d.ts +17 -0
- package/dist/inference/nim-adapter.d.ts.map +1 -0
- package/dist/inference/nim-adapter.js +103 -0
- package/dist/inference/nim-adapter.js.map +1 -0
- package/dist/inference/openrouter-adapter.d.ts +17 -0
- package/dist/inference/openrouter-adapter.d.ts.map +1 -0
- package/dist/inference/openrouter-adapter.js +105 -0
- package/dist/inference/openrouter-adapter.js.map +1 -0
- package/dist/inference/sse.d.ts +20 -0
- package/dist/inference/sse.d.ts.map +1 -0
- package/dist/inference/sse.js +91 -0
- package/dist/inference/sse.js.map +1 -0
- package/dist/learning/agent-stats.d.ts +109 -0
- package/dist/learning/agent-stats.d.ts.map +1 -0
- package/dist/learning/agent-stats.js +240 -0
- package/dist/learning/agent-stats.js.map +1 -0
- package/dist/learning/benchmark.d.ts +161 -0
- package/dist/learning/benchmark.d.ts.map +1 -0
- package/dist/learning/benchmark.js +589 -0
- package/dist/learning/benchmark.js.map +1 -0
- package/dist/learning/cost-tracker.d.ts +101 -0
- package/dist/learning/cost-tracker.d.ts.map +1 -0
- package/dist/learning/cost-tracker.js +224 -0
- package/dist/learning/cost-tracker.js.map +1 -0
- package/dist/learning/feedback.d.ts +88 -0
- package/dist/learning/feedback.d.ts.map +1 -0
- package/dist/learning/feedback.js +169 -0
- package/dist/learning/feedback.js.map +1 -0
- package/dist/learning/hybrid-router.d.ts +201 -0
- package/dist/learning/hybrid-router.d.ts.map +1 -0
- package/dist/learning/hybrid-router.js +450 -0
- package/dist/learning/hybrid-router.js.map +1 -0
- package/dist/learning/model-compare.d.ts +76 -0
- package/dist/learning/model-compare.d.ts.map +1 -0
- package/dist/learning/model-compare.js +252 -0
- package/dist/learning/model-compare.js.map +1 -0
- package/dist/learning/model-router.d.ts +68 -0
- package/dist/learning/model-router.d.ts.map +1 -0
- package/dist/learning/model-router.js +140 -0
- package/dist/learning/model-router.js.map +1 -0
- package/dist/learning/pattern-extractor.d.ts +99 -0
- package/dist/learning/pattern-extractor.d.ts.map +1 -0
- package/dist/learning/pattern-extractor.js +310 -0
- package/dist/learning/pattern-extractor.js.map +1 -0
- package/dist/learning/scorer.d.ts +51 -0
- package/dist/learning/scorer.d.ts.map +1 -0
- package/dist/learning/scorer.js +64 -0
- package/dist/learning/scorer.js.map +1 -0
- package/dist/learning/self-improver.d.ts +48 -0
- package/dist/learning/self-improver.d.ts.map +1 -0
- package/dist/learning/self-improver.js +161 -0
- package/dist/learning/self-improver.js.map +1 -0
- package/dist/memory/embedder.d.ts +65 -0
- package/dist/memory/embedder.d.ts.map +1 -0
- package/dist/memory/embedder.js +424 -0
- package/dist/memory/embedder.js.map +1 -0
- package/dist/memory/memory-integration.d.ts +56 -0
- package/dist/memory/memory-integration.d.ts.map +1 -0
- package/dist/memory/memory-integration.js +95 -0
- package/dist/memory/memory-integration.js.map +1 -0
- package/dist/memory/trajectory-store.d.ts +149 -0
- package/dist/memory/trajectory-store.d.ts.map +1 -0
- package/dist/memory/trajectory-store.js +476 -0
- package/dist/memory/trajectory-store.js.map +1 -0
- package/dist/memory/vector-store.d.ts +78 -0
- package/dist/memory/vector-store.d.ts.map +1 -0
- package/dist/memory/vector-store.js +186 -0
- package/dist/memory/vector-store.js.map +1 -0
- package/dist/plugins/agent-plugin.d.ts +73 -0
- package/dist/plugins/agent-plugin.d.ts.map +1 -0
- package/dist/plugins/agent-plugin.js +199 -0
- package/dist/plugins/agent-plugin.js.map +1 -0
- package/dist/plugins/registry.d.ts +61 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +67 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/sandbox/images.d.ts +31 -0
- package/dist/sandbox/images.d.ts.map +1 -0
- package/dist/sandbox/images.js +129 -0
- package/dist/sandbox/images.js.map +1 -0
- package/dist/sandbox/manager.d.ts +134 -0
- package/dist/sandbox/manager.d.ts.map +1 -0
- package/dist/sandbox/manager.js +470 -0
- package/dist/sandbox/manager.js.map +1 -0
- package/dist/sandbox/types.d.ts +113 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +107 -0
- package/dist/sandbox/types.js.map +1 -0
- package/dist/security/scanner.d.ts +53 -0
- package/dist/security/scanner.d.ts.map +1 -0
- package/dist/security/scanner.js +271 -0
- package/dist/security/scanner.js.map +1 -0
- package/dist/team/config.d.ts +50 -0
- package/dist/team/config.d.ts.map +1 -0
- package/dist/team/config.js +108 -0
- package/dist/team/config.js.map +1 -0
- package/dist/team/memory.d.ts +63 -0
- package/dist/team/memory.d.ts.map +1 -0
- package/dist/team/memory.js +282 -0
- package/dist/team/memory.js.map +1 -0
- package/dist/team/review.d.ts +123 -0
- package/dist/team/review.d.ts.map +1 -0
- package/dist/team/review.js +293 -0
- package/dist/team/review.js.map +1 -0
- package/dist/utils/env.d.ts +19 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +250 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +45 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/web-dashboard/server.d.ts +59 -0
- package/dist/web-dashboard/server.d.ts.map +1 -0
- package/dist/web-dashboard/server.js +418 -0
- package/dist/web-dashboard/server.js.map +1 -0
- package/dist/workflow/registry.d.ts +127 -0
- package/dist/workflow/registry.d.ts.map +1 -0
- package/dist/workflow/registry.js +482 -0
- package/dist/workflow/registry.js.map +1 -0
- package/dist/workflow/templates.d.ts +93 -0
- package/dist/workflow/templates.d.ts.map +1 -0
- package/dist/workflow/templates.js +481 -0
- package/dist/workflow/templates.js.map +1 -0
- package/package.json +78 -0
- package/src/web-dashboard/public/assets/index-B08nDkSB.css +1 -0
- package/src/web-dashboard/public/assets/index-BKL8YOFD.js +135 -0
- package/src/web-dashboard/public/assets/index-BKL8YOFD.js.map +1 -0
- package/src/web-dashboard/public/index.html +13 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SandboxManager — Docker-based sandbox isolation for code execution.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Container lifecycle management (create, exec, destroy)
|
|
6
|
+
* - Resource limits (CPU, memory, disk, PIDs, network)
|
|
7
|
+
* - Volume/project mounting
|
|
8
|
+
* - Command execution with timeout enforcement
|
|
9
|
+
* - Non-root user execution
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* ```ts
|
|
13
|
+
* const manager = new SandboxManager();
|
|
14
|
+
*
|
|
15
|
+
* // Check if Docker is available
|
|
16
|
+
* const available = await manager.isDockerAvailable();
|
|
17
|
+
*
|
|
18
|
+
* // Create a sandbox
|
|
19
|
+
* const containerId = await manager.createContainer('node:20-slim', {
|
|
20
|
+
* memoryLimit: '512m',
|
|
21
|
+
* cpuLimit: 1,
|
|
22
|
+
* networkAccess: false,
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Copy project, run commands
|
|
26
|
+
* await manager.copyProjectToContainer(containerId, '/path/to/project');
|
|
27
|
+
* const result = await manager.runCommand(containerId, 'npm test');
|
|
28
|
+
*
|
|
29
|
+
* // Always clean up
|
|
30
|
+
* await manager.destroyContainer(containerId);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { execSync, spawn } from 'node:child_process';
|
|
34
|
+
import { existsSync } from 'node:fs';
|
|
35
|
+
import { join } from 'node:path';
|
|
36
|
+
import { tmpdir } from 'node:os';
|
|
37
|
+
import { mkdtempSync, readdirSync } from 'node:fs';
|
|
38
|
+
import { logger } from '../utils/logger.js';
|
|
39
|
+
import { DEFAULT_RESOURCE_LIMITS, getSandboxConfig, } from './types.js';
|
|
40
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
41
|
+
/** Maximum number of managed containers to track */
|
|
42
|
+
const MAX_CONTAINERS = 20;
|
|
43
|
+
/** Temporary directory for building context before copying to container */
|
|
44
|
+
const BUFF_TMP_PREFIX = 'buff-docker-';
|
|
45
|
+
// ─── SandboxManager ─────────────────────────────────────────────────────────
|
|
46
|
+
export class SandboxManager {
|
|
47
|
+
config;
|
|
48
|
+
/** Managed containers tracked by this manager instance */
|
|
49
|
+
containers = new Map();
|
|
50
|
+
/** Whether Docker availability has been checked */
|
|
51
|
+
dockerChecked = false;
|
|
52
|
+
/** Cached result of Docker availability check */
|
|
53
|
+
dockerAvailable = false;
|
|
54
|
+
/** Cached error message from Docker check */
|
|
55
|
+
dockerError = '';
|
|
56
|
+
constructor(config = getSandboxConfig()) {
|
|
57
|
+
this.config = config;
|
|
58
|
+
}
|
|
59
|
+
// ─── Docker Availability ──────────────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* Check if Docker is installed and the daemon is running.
|
|
62
|
+
* Caches the result so repeated calls are instant.
|
|
63
|
+
*/
|
|
64
|
+
async isDockerAvailable() {
|
|
65
|
+
if (this.dockerChecked)
|
|
66
|
+
return this.dockerAvailable;
|
|
67
|
+
try {
|
|
68
|
+
const result = await this.execHostCommand('docker info --format "{{.ServerVersion}}"');
|
|
69
|
+
this.dockerAvailable = result.exitCode === 0 && result.stdout.trim().length > 0;
|
|
70
|
+
this.dockerError = result.stderr;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
this.dockerAvailable = false;
|
|
74
|
+
this.dockerError = err instanceof Error ? err.message : String(err);
|
|
75
|
+
}
|
|
76
|
+
this.dockerChecked = true;
|
|
77
|
+
return this.dockerAvailable;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the error message from the last Docker availability check.
|
|
81
|
+
*/
|
|
82
|
+
getDockerError() {
|
|
83
|
+
return this.dockerError;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Force re-check Docker availability on the next call.
|
|
87
|
+
*/
|
|
88
|
+
resetDockerCheck() {
|
|
89
|
+
this.dockerChecked = false;
|
|
90
|
+
}
|
|
91
|
+
// ─── Container Lifecycle ─────────────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Create a Docker sandbox container with the given image and resource limits.
|
|
94
|
+
*
|
|
95
|
+
* @param image - Docker image to use (e.g., 'node:20-slim')
|
|
96
|
+
* @param limits - Resource limit overrides
|
|
97
|
+
* @param workDir - Working directory inside the container
|
|
98
|
+
* @returns The container ID
|
|
99
|
+
*/
|
|
100
|
+
async createContainer(image, limits, workDir) {
|
|
101
|
+
if (!(await this.isDockerAvailable())) {
|
|
102
|
+
throw new Error('Docker is not available. ' + (this.dockerError || 'Is Docker installed and running?'));
|
|
103
|
+
}
|
|
104
|
+
// Enforce max container limit
|
|
105
|
+
if (this.containers.size >= MAX_CONTAINERS) {
|
|
106
|
+
// Clean up stale containers (created > 30 min ago)
|
|
107
|
+
await this.cleanupStaleContainers();
|
|
108
|
+
if (this.containers.size >= MAX_CONTAINERS) {
|
|
109
|
+
throw new Error(`Maximum of ${MAX_CONTAINERS} sandbox containers reached. ` +
|
|
110
|
+
'Please destroy unused containers with destroyContainer().');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const resolvedImage = image || this.config.image.image;
|
|
114
|
+
const resolvedLimits = { ...DEFAULT_RESOURCE_LIMITS, ...limits };
|
|
115
|
+
const resolvedWorkDir = workDir || this.config.workDir;
|
|
116
|
+
// Generate unique container name
|
|
117
|
+
const name = 'buff-sandbox-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 6);
|
|
118
|
+
// Build docker run arguments
|
|
119
|
+
const args = [
|
|
120
|
+
'run',
|
|
121
|
+
'--detach', // Run in background
|
|
122
|
+
'--name', name, // Assign a name for easy reference
|
|
123
|
+
'--workdir', resolvedWorkDir, // Set working directory
|
|
124
|
+
'--init', // Use tini as init for proper signal handling
|
|
125
|
+
'--stop-timeout', String(Math.floor(this.config.stopTimeoutMs / 1000)),
|
|
126
|
+
];
|
|
127
|
+
// Resource limits
|
|
128
|
+
args.push('--memory', resolvedLimits.memoryLimit);
|
|
129
|
+
args.push('--memory-swap', resolvedLimits.memoryLimit); // No swap
|
|
130
|
+
args.push('--cpus', String(resolvedLimits.cpuLimit));
|
|
131
|
+
args.push('--pids-limit', String(resolvedLimits.pidsLimit));
|
|
132
|
+
// Disk / storage limit (via size quota if available)
|
|
133
|
+
try {
|
|
134
|
+
args.push('--storage-opt', `size=${resolvedLimits.diskLimit}`);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// storage-opt may not be supported on all Docker configurations
|
|
138
|
+
}
|
|
139
|
+
// Network access
|
|
140
|
+
if (!resolvedLimits.networkAccess) {
|
|
141
|
+
args.push('--network', 'none');
|
|
142
|
+
}
|
|
143
|
+
// Security: read-only root filesystem, drop capabilities, non-root user
|
|
144
|
+
args.push('--read-only'); // Read-only root filesystem
|
|
145
|
+
args.push('--cap-drop', 'ALL'); // Drop all Linux capabilities
|
|
146
|
+
args.push('--security-opt', 'no-new-privileges:true'); // No privilege escalation
|
|
147
|
+
args.push('--user', this.config.containerUser);
|
|
148
|
+
// Create a writable tmp directory for the workspace
|
|
149
|
+
args.push('--tmpfs', '/tmp:noexec,nosuid,size=64m');
|
|
150
|
+
// Mount a temp directory for workspace (rw since / is read-only)
|
|
151
|
+
const hostTmpDir = mkdtempSync(join(tmpdir(), BUFF_TMP_PREFIX));
|
|
152
|
+
args.push('--mount', `type=bind,source=${hostTmpDir},target=${resolvedWorkDir}`);
|
|
153
|
+
args.push('--env', `BUFF_WORKSPACE=${resolvedWorkDir}`);
|
|
154
|
+
// The image
|
|
155
|
+
args.push(resolvedImage);
|
|
156
|
+
// Keep the container alive
|
|
157
|
+
args.push('tail', '-f', '/dev/null');
|
|
158
|
+
// Run the container
|
|
159
|
+
const runResult = await this.execHostCommand(`docker ${args.join(' ')}`, 120_000);
|
|
160
|
+
if (runResult.exitCode !== 0) {
|
|
161
|
+
throw new Error(`Failed to create sandbox container: ${runResult.stderr || runResult.stdout}`);
|
|
162
|
+
}
|
|
163
|
+
const containerId = runResult.stdout.trim();
|
|
164
|
+
const managed = {
|
|
165
|
+
containerId,
|
|
166
|
+
name,
|
|
167
|
+
createdAt: Date.now(),
|
|
168
|
+
status: 'created',
|
|
169
|
+
limits: resolvedLimits,
|
|
170
|
+
image: resolvedImage,
|
|
171
|
+
};
|
|
172
|
+
this.containers.set(containerId, managed);
|
|
173
|
+
logger.debug(`Created sandbox container: ${name} (${containerId.slice(0, 12)}...)`);
|
|
174
|
+
return containerId;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Copy project files (or a specific directory) into the sandbox container.
|
|
178
|
+
*
|
|
179
|
+
* Uses `docker cp` to copy files into the container's working directory.
|
|
180
|
+
*
|
|
181
|
+
* @param containerId - Container ID
|
|
182
|
+
* @param sourceDir - Source directory on the host
|
|
183
|
+
* @param targetDir - Target directory inside container (defaults to workDir)
|
|
184
|
+
*/
|
|
185
|
+
async copyProjectToContainer(containerId, sourceDir, targetDir) {
|
|
186
|
+
const container = this.ensureContainer(containerId);
|
|
187
|
+
const resolvedTarget = targetDir || this.config.workDir;
|
|
188
|
+
if (!existsSync(sourceDir)) {
|
|
189
|
+
throw new Error(`Source directory does not exist: ${sourceDir}`);
|
|
190
|
+
}
|
|
191
|
+
// Use docker cp to copy the project
|
|
192
|
+
// We need to ensure the target directory exists first
|
|
193
|
+
await this.execInContainer(containerId, `mkdir -p "${resolvedTarget}"`);
|
|
194
|
+
// Copy each top-level entry (excluding node_modules, .git, etc.)
|
|
195
|
+
const entries = readdirSync(sourceDir);
|
|
196
|
+
// Use tar for efficient copying (docker cp supports piping via tar)
|
|
197
|
+
const excluded = new Set(['node_modules', '.git', 'dist', '.next', 'coverage', '.cache', '__pycache__']);
|
|
198
|
+
const visibleEntries = entries.filter((e) => !e.startsWith('.') && !excluded.has(e));
|
|
199
|
+
if (visibleEntries.length === 0) {
|
|
200
|
+
// Just cop an empty directory structure
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// Use a tar pipe for efficient bulk copy
|
|
204
|
+
const tarArgs = visibleEntries.map((e) => `"${join(sourceDir, e)}"`).join(' ');
|
|
205
|
+
const copyCmd = `tar cf - ${tarArgs} | docker exec -i "${containerId}" tar xf - -C "${resolvedTarget}"`;
|
|
206
|
+
const result = await this.execHostCommand(copyCmd, 120_000);
|
|
207
|
+
if (result.exitCode !== 0) {
|
|
208
|
+
// Fall back to individual copies
|
|
209
|
+
for (const entry of visibleEntries) {
|
|
210
|
+
try {
|
|
211
|
+
await this.execHostCommand(`docker cp "${join(sourceDir, entry)}" "${containerId}:${resolvedTarget}/"`, 60_000);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Skip files that fail to copy
|
|
215
|
+
logger.debug(`Failed to copy ${entry} to sandbox`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
logger.debug(`Copied ${visibleEntries.length} entries to sandbox container: ${container.name}`);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Execute a command inside the sandbox container with timeout enforcement.
|
|
223
|
+
*
|
|
224
|
+
* @param containerId - Container ID
|
|
225
|
+
* @param command - Command to execute (as a string, passed to /bin/sh -c)
|
|
226
|
+
* @param timeoutMs - Timeout in milliseconds (default: config timeout)
|
|
227
|
+
* @returns Execution result with stdout, stderr, exit code
|
|
228
|
+
*/
|
|
229
|
+
async runCommand(containerId, command, timeoutMs) {
|
|
230
|
+
const container = this.ensureContainer(containerId);
|
|
231
|
+
const resolvedTimeout = timeoutMs || this.config.limits.timeoutMs;
|
|
232
|
+
// Escape the command for safe shell execution
|
|
233
|
+
const escapedCommand = command.replace(/"/g, '\\"').replace(/`/g, '\\`').replace(/\$/g, '\\$');
|
|
234
|
+
const shell = this.config.image.shell || '/bin/bash';
|
|
235
|
+
const execCmd = `docker exec -i "${container.containerId}" ${shell} -c "${escapedCommand}"`;
|
|
236
|
+
const startTime = Date.now();
|
|
237
|
+
let timedOut = false;
|
|
238
|
+
// Use a timeout wrapper
|
|
239
|
+
const timeoutCmd = `timeout ${Math.floor(resolvedTimeout / 1000)} ${execCmd}`;
|
|
240
|
+
try {
|
|
241
|
+
const result = await this.execHostCommand(timeoutCmd, resolvedTimeout + 10_000);
|
|
242
|
+
if (result.exitCode === 124) {
|
|
243
|
+
// Exit code 124 means 'timeout' command killed the process
|
|
244
|
+
timedOut = true;
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
success: result.exitCode === 0,
|
|
248
|
+
stdout: result.stdout,
|
|
249
|
+
stderr: result.stderr,
|
|
250
|
+
exitCode: timedOut ? 124 : result.exitCode,
|
|
251
|
+
durationMs: Date.now() - startTime,
|
|
252
|
+
timedOut,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
return {
|
|
257
|
+
success: false,
|
|
258
|
+
stdout: '',
|
|
259
|
+
stderr: '',
|
|
260
|
+
exitCode: -1,
|
|
261
|
+
durationMs: Date.now() - startTime,
|
|
262
|
+
timedOut,
|
|
263
|
+
error: err instanceof Error ? err.message : String(err),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Run a command and stream its stdout output (for long-running commands).
|
|
269
|
+
* Calls onChunk for each line of stdout.
|
|
270
|
+
*/
|
|
271
|
+
async runCommandWithOutput(containerId, command, onChunk, timeoutMs) {
|
|
272
|
+
const container = this.ensureContainer(containerId);
|
|
273
|
+
const resolvedTimeout = timeoutMs || this.config.limits.timeoutMs;
|
|
274
|
+
return new Promise((resolvePromise) => {
|
|
275
|
+
const startTime = Date.now();
|
|
276
|
+
const escapedCommand = command.replace(/"/g, '\\"').replace(/`/g, '\\`');
|
|
277
|
+
const shell = this.config.image.shell || '/bin/bash';
|
|
278
|
+
const fullCommand = `docker exec -i "${container.containerId}" ${shell} -c "${escapedCommand}"`;
|
|
279
|
+
const childProcess = spawn(fullCommand, [], {
|
|
280
|
+
shell: true,
|
|
281
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
282
|
+
timeout: resolvedTimeout,
|
|
283
|
+
});
|
|
284
|
+
let stdout = '';
|
|
285
|
+
let stderr = '';
|
|
286
|
+
let timedOut = false;
|
|
287
|
+
const timer = setTimeout(() => {
|
|
288
|
+
timedOut = true;
|
|
289
|
+
childProcess.kill('SIGTERM');
|
|
290
|
+
// Give it a moment to exit, then SIGKILL
|
|
291
|
+
setTimeout(() => {
|
|
292
|
+
try {
|
|
293
|
+
childProcess.kill('SIGKILL');
|
|
294
|
+
}
|
|
295
|
+
catch { /* already dead */ }
|
|
296
|
+
}, 2000);
|
|
297
|
+
}, resolvedTimeout);
|
|
298
|
+
childProcess.stdout?.on('data', (data) => {
|
|
299
|
+
const chunk = data.toString();
|
|
300
|
+
stdout += chunk;
|
|
301
|
+
onChunk?.(chunk);
|
|
302
|
+
});
|
|
303
|
+
childProcess.stderr?.on('data', (data) => {
|
|
304
|
+
stderr += data.toString();
|
|
305
|
+
});
|
|
306
|
+
childProcess.on('close', (exitCode) => {
|
|
307
|
+
clearTimeout(timer);
|
|
308
|
+
const duration = Date.now() - startTime;
|
|
309
|
+
resolvePromise({
|
|
310
|
+
success: exitCode === 0,
|
|
311
|
+
stdout,
|
|
312
|
+
stderr,
|
|
313
|
+
exitCode: timedOut ? 124 : (exitCode ?? -1),
|
|
314
|
+
durationMs: duration,
|
|
315
|
+
timedOut,
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
childProcess.on('error', (err) => {
|
|
319
|
+
clearTimeout(timer);
|
|
320
|
+
resolvePromise({
|
|
321
|
+
success: false,
|
|
322
|
+
stdout,
|
|
323
|
+
stderr: stderr || err.message,
|
|
324
|
+
exitCode: -1,
|
|
325
|
+
durationMs: Date.now() - startTime,
|
|
326
|
+
timedOut: false,
|
|
327
|
+
error: err.message,
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Get the status of a managed container.
|
|
334
|
+
*/
|
|
335
|
+
async getContainerStatus(containerId) {
|
|
336
|
+
const container = this.ensureContainer(containerId);
|
|
337
|
+
try {
|
|
338
|
+
const result = await this.execHostCommand(`docker inspect --format "{{.State.Status}}" "${containerId}"`);
|
|
339
|
+
if (result.exitCode === 0) {
|
|
340
|
+
const status = result.stdout.trim();
|
|
341
|
+
container.status = status;
|
|
342
|
+
return status;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
// Container might not exist
|
|
347
|
+
}
|
|
348
|
+
container.status = 'removed';
|
|
349
|
+
return 'removed';
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Stop and remove a sandbox container.
|
|
353
|
+
*/
|
|
354
|
+
async destroyContainer(containerId) {
|
|
355
|
+
const container = this.ensureContainer(containerId);
|
|
356
|
+
try {
|
|
357
|
+
// Stop the container gracefully first
|
|
358
|
+
await this.execHostCommand(`docker stop --time ${Math.floor(this.config.stopTimeoutMs / 1000)} "${containerId}" 2>/dev/null`, 30_000);
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// Ignore stop errors
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
// Remove the container
|
|
365
|
+
await this.execHostCommand(`docker rm -f "${containerId}" 2>/dev/null`, 30_000);
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Ignore removal errors
|
|
369
|
+
}
|
|
370
|
+
container.status = 'removed';
|
|
371
|
+
this.containers.delete(containerId);
|
|
372
|
+
logger.debug(`Destroyed sandbox container: ${container.name}`);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Destroy all managed containers.
|
|
376
|
+
*/
|
|
377
|
+
async destroyAll() {
|
|
378
|
+
const ids = [...this.containers.keys()];
|
|
379
|
+
await Promise.all(ids.map((id) => this.destroyContainer(id).catch(() => { })));
|
|
380
|
+
this.containers.clear();
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Get information about all managed containers.
|
|
384
|
+
*/
|
|
385
|
+
getManagedContainers() {
|
|
386
|
+
return [...this.containers.values()];
|
|
387
|
+
}
|
|
388
|
+
// ─── Private Helpers ─────────────────────────────────────────────────────
|
|
389
|
+
/**
|
|
390
|
+
* Ensure a container ID is tracked and still exists.
|
|
391
|
+
*/
|
|
392
|
+
ensureContainer(containerId) {
|
|
393
|
+
const container = this.containers.get(containerId);
|
|
394
|
+
if (!container) {
|
|
395
|
+
throw new Error(`Container not managed by this SandboxManager: ${containerId.slice(0, 12)}...`);
|
|
396
|
+
}
|
|
397
|
+
return container;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Run a command on the host machine (not inside a container).
|
|
401
|
+
* Used for docker CLI operations.
|
|
402
|
+
*/
|
|
403
|
+
async execHostCommand(command, timeoutMs = 60_000) {
|
|
404
|
+
return new Promise((resolve) => {
|
|
405
|
+
try {
|
|
406
|
+
const output = execSync(command, {
|
|
407
|
+
timeout: timeoutMs,
|
|
408
|
+
stdio: 'pipe',
|
|
409
|
+
encoding: 'utf-8',
|
|
410
|
+
shell: '/bin/sh',
|
|
411
|
+
maxBuffer: 10 * 1024 * 1024, // 10 MB
|
|
412
|
+
});
|
|
413
|
+
resolve({
|
|
414
|
+
exitCode: 0,
|
|
415
|
+
stdout: output.trim(),
|
|
416
|
+
stderr: '',
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
catch (err) {
|
|
420
|
+
const error = err;
|
|
421
|
+
resolve({
|
|
422
|
+
exitCode: error.status ?? 1,
|
|
423
|
+
stdout: (typeof error.stdout === 'string' ? error.stdout : String(error.stdout || '')).trim(),
|
|
424
|
+
stderr: (typeof error.stderr === 'string' ? error.stderr : String(error.stderr || '')).trim(),
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Execute a command inside a container using docker exec.
|
|
431
|
+
* Used internally for setup operations like mkdir.
|
|
432
|
+
*/
|
|
433
|
+
async execInContainer(containerId, command) {
|
|
434
|
+
const escaped = command.replace(/"/g, '\\"');
|
|
435
|
+
return this.execHostCommand(`docker exec "${containerId}" /bin/sh -c "${escaped}"`, 30_000);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Remove containers that have been managed for more than 30 minutes.
|
|
439
|
+
*/
|
|
440
|
+
async cleanupStaleContainers() {
|
|
441
|
+
const staleTime = Date.now() - 30 * 60 * 1000;
|
|
442
|
+
const stale = [...this.containers.entries()].filter(([_, c]) => c.createdAt < staleTime);
|
|
443
|
+
for (const [id] of stale) {
|
|
444
|
+
try {
|
|
445
|
+
await this.destroyContainer(id);
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
// Best-effort cleanup
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// ─── Singleton / Convenience API ────────────────────────────────────────────
|
|
454
|
+
let defaultManager = null;
|
|
455
|
+
/**
|
|
456
|
+
* Get or create the default SandboxManager singleton.
|
|
457
|
+
*/
|
|
458
|
+
export function getSandboxManager() {
|
|
459
|
+
if (!defaultManager) {
|
|
460
|
+
defaultManager = new SandboxManager();
|
|
461
|
+
}
|
|
462
|
+
return defaultManager;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Reset the default SandboxManager singleton (useful for testing).
|
|
466
|
+
*/
|
|
467
|
+
export function resetSandboxManager() {
|
|
468
|
+
defaultManager = null;
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/sandbox/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox types — Configuration types for Docker-based sandbox isolation.
|
|
3
|
+
*
|
|
4
|
+
* The sandbox system provides process-level isolation for running generated
|
|
5
|
+
* code and tests inside Docker containers with configurable resource limits.
|
|
6
|
+
*
|
|
7
|
+
* Basic usage:
|
|
8
|
+
* ```ts
|
|
9
|
+
* const manager = new SandboxManager({ memoryLimit: '512m', cpuLimit: 1 });
|
|
10
|
+
* const id = await manager.createContainer();
|
|
11
|
+
* await manager.copyProject(id, '/path/to/project');
|
|
12
|
+
* const result = await manager.runCommand(id, 'npm test');
|
|
13
|
+
* await manager.destroyContainer(id);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
/** Resource limit constraints for a sandbox container */
|
|
17
|
+
export interface ResourceLimits {
|
|
18
|
+
/** Max memory (e.g., '512m', '2g'). Default: '1g' */
|
|
19
|
+
memoryLimit?: string;
|
|
20
|
+
/** Max CPU cores (e.g., 0.5, 1, 2). Default: 1 */
|
|
21
|
+
cpuLimit?: number;
|
|
22
|
+
/** Max disk space (e.g., '1g', '10g'). Default: '2g' */
|
|
23
|
+
diskLimit?: string;
|
|
24
|
+
/** Max PIDs inside container. Default: 100 */
|
|
25
|
+
pidsLimit?: number;
|
|
26
|
+
/** Whether to enable network access. Default: false */
|
|
27
|
+
networkAccess?: boolean;
|
|
28
|
+
/** Max duration in ms before container is killed. Default: 600000 (10 min) */
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
}
|
|
31
|
+
/** A pre-defined or custom Docker image for sandbox containers */
|
|
32
|
+
export interface SandboxImage {
|
|
33
|
+
/** Image name (e.g., 'node:20-slim') */
|
|
34
|
+
image: string;
|
|
35
|
+
/** Human-readable label (e.g., 'Node.js 20') */
|
|
36
|
+
label: string;
|
|
37
|
+
/** Package manager / runtime details */
|
|
38
|
+
runtimes: string[];
|
|
39
|
+
/** Install command prefix (e.g., 'npm install') */
|
|
40
|
+
installCommand?: string;
|
|
41
|
+
/** Test command prefix (e.g., 'npm test') */
|
|
42
|
+
testCommand?: string;
|
|
43
|
+
/** Shell to use inside container */
|
|
44
|
+
shell?: string;
|
|
45
|
+
}
|
|
46
|
+
/** Complete sandbox configuration */
|
|
47
|
+
export interface SandboxConfig {
|
|
48
|
+
/** Whether Docker sandbox is enabled */
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
/** Resource limits */
|
|
51
|
+
limits: Required<ResourceLimits>;
|
|
52
|
+
/** Image to use for sandbox containers */
|
|
53
|
+
image: SandboxImage;
|
|
54
|
+
/** Container working directory */
|
|
55
|
+
workDir: string;
|
|
56
|
+
/** Non-root user to run as */
|
|
57
|
+
containerUser: string;
|
|
58
|
+
/** Timeout for stopping a container gracefully (ms) */
|
|
59
|
+
stopTimeoutMs: number;
|
|
60
|
+
}
|
|
61
|
+
/** Lifecycle state of a managed container */
|
|
62
|
+
export type ContainerStatus = 'created' | 'running' | 'stopped' | 'removed';
|
|
63
|
+
/** Track a managed sandbox container */
|
|
64
|
+
export interface ManagedContainer {
|
|
65
|
+
/** Container ID (Docker container hash) */
|
|
66
|
+
containerId: string;
|
|
67
|
+
/** Human-readable name (e.g., 'buff-sandbox-abc123') */
|
|
68
|
+
name: string;
|
|
69
|
+
/** Creation timestamp */
|
|
70
|
+
createdAt: number;
|
|
71
|
+
/** Current status */
|
|
72
|
+
status: ContainerStatus;
|
|
73
|
+
/** Resource limits applied */
|
|
74
|
+
limits: ResourceLimits;
|
|
75
|
+
/** Image used */
|
|
76
|
+
image: string;
|
|
77
|
+
}
|
|
78
|
+
/** Result of executing a command inside a sandbox container */
|
|
79
|
+
export interface SandboxExecResult {
|
|
80
|
+
/** Whether the command exited with code 0 */
|
|
81
|
+
success: boolean;
|
|
82
|
+
/** Standard output */
|
|
83
|
+
stdout: string;
|
|
84
|
+
/** Standard error */
|
|
85
|
+
stderr: string;
|
|
86
|
+
/** Exit code */
|
|
87
|
+
exitCode: number;
|
|
88
|
+
/** Execution duration in ms */
|
|
89
|
+
durationMs: number;
|
|
90
|
+
/** Whether the container was killed due to timeout */
|
|
91
|
+
timedOut: boolean;
|
|
92
|
+
/** Error message if execution failed entirely */
|
|
93
|
+
error?: string;
|
|
94
|
+
}
|
|
95
|
+
export declare const DEFAULT_RESOURCE_LIMITS: Required<ResourceLimits>;
|
|
96
|
+
export declare const DEFAULT_SANDBOX_CONFIG: SandboxConfig;
|
|
97
|
+
/**
|
|
98
|
+
* Get the current sandbox configuration.
|
|
99
|
+
* Reads from ~/.buff/sandbox-config.json (if exists), falls back to defaults.
|
|
100
|
+
*/
|
|
101
|
+
export declare function getSandboxConfig(): SandboxConfig;
|
|
102
|
+
/**
|
|
103
|
+
* Update the sandbox configuration and persist to disk.
|
|
104
|
+
*/
|
|
105
|
+
/**
|
|
106
|
+
* Reset the sandbox config cache. Useful for testing.
|
|
107
|
+
*/
|
|
108
|
+
export declare function resetSandboxConfigCache(): void;
|
|
109
|
+
/**
|
|
110
|
+
* Update the sandbox configuration and persist to disk.
|
|
111
|
+
*/
|
|
112
|
+
export declare function setSandboxConfig(config: Partial<SandboxConfig>): SandboxConfig;
|
|
113
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sandbox/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACjC,0CAA0C;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;CACvB;AAID,6CAA6C;AAC7C,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5E,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,8BAA8B;IAC9B,MAAM,EAAE,cAAc,CAAC;IACvB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAID,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,cAAc,CAO5D,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,aAcpC,CAAC;AAQF;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAwBhD;AAED;;GAEG;AACH;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAqB9E"}
|