@capybara-hq/plugin-sandbox-e2b 0.1.0-rc.0 → 0.1.0-rc.2
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/.capybara-plugin/plugin.json +99 -2
- package/README.md +1 -1
- package/dist/index.mjs +23 -12
- package/package.json +1 -1
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "sandbox-e2b",
|
|
4
|
-
"version": "0.1.0-rc.
|
|
4
|
+
"version": "0.1.0-rc.2",
|
|
5
5
|
"publisher": "Capybara",
|
|
6
6
|
"description": "Conversation sandboxes (sandbox@1) as E2B sandboxes (E2B cloud or self-hosted), with pause / resume and E2B egress controls",
|
|
7
|
+
"displayName": {
|
|
8
|
+
"zh": "E2B 沙箱",
|
|
9
|
+
"en": "E2B sandbox"
|
|
10
|
+
},
|
|
7
11
|
"homepage": "https://github.com/capybara-hq/plugins/tree/main/plugins/sandbox-e2b#readme",
|
|
8
12
|
"extension": {
|
|
9
13
|
"entry": "./dist/index.mjs",
|
|
10
14
|
"manifest": {
|
|
11
15
|
"name": "sandbox-e2b",
|
|
12
|
-
"version": "0.1.0-rc.
|
|
16
|
+
"version": "0.1.0-rc.2",
|
|
13
17
|
"sdk": "^0.1.0-rc.0",
|
|
14
18
|
"provides": [
|
|
15
19
|
"sandbox@1"
|
|
@@ -57,6 +61,99 @@
|
|
|
57
61
|
],
|
|
58
62
|
"org": []
|
|
59
63
|
}
|
|
64
|
+
},
|
|
65
|
+
"configSchemas": {
|
|
66
|
+
"deployment": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"properties": {
|
|
69
|
+
"apiKey": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"minLength": 1,
|
|
72
|
+
"x-secret": true,
|
|
73
|
+
"x-ui": {
|
|
74
|
+
"label": {
|
|
75
|
+
"zh": "API 密钥",
|
|
76
|
+
"en": "API key"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"title": "API key"
|
|
80
|
+
},
|
|
81
|
+
"apiUrl": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"format": "uri",
|
|
84
|
+
"x-ui": {
|
|
85
|
+
"label": {
|
|
86
|
+
"zh": "接口地址",
|
|
87
|
+
"en": "API URL"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"title": "API URL"
|
|
91
|
+
},
|
|
92
|
+
"domain": {
|
|
93
|
+
"default": "e2b.app",
|
|
94
|
+
"type": "string",
|
|
95
|
+
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$",
|
|
96
|
+
"x-ui": {
|
|
97
|
+
"label": {
|
|
98
|
+
"zh": "沙箱域名",
|
|
99
|
+
"en": "Sandbox domain"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"title": "Sandbox domain"
|
|
103
|
+
},
|
|
104
|
+
"template": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"minLength": 1,
|
|
107
|
+
"x-ui": {
|
|
108
|
+
"label": {
|
|
109
|
+
"zh": "模板",
|
|
110
|
+
"en": "Template"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"title": "Template"
|
|
114
|
+
},
|
|
115
|
+
"timeoutSeconds": {
|
|
116
|
+
"default": 3600,
|
|
117
|
+
"type": "integer",
|
|
118
|
+
"minimum": 60,
|
|
119
|
+
"maximum": 86400,
|
|
120
|
+
"x-ui": {
|
|
121
|
+
"label": {
|
|
122
|
+
"zh": "沙箱超时",
|
|
123
|
+
"en": "Sandbox timeout"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"title": "Sandbox timeout"
|
|
127
|
+
},
|
|
128
|
+
"domainAllowlist": {
|
|
129
|
+
"default": true,
|
|
130
|
+
"type": "boolean",
|
|
131
|
+
"x-ui": {
|
|
132
|
+
"label": {
|
|
133
|
+
"zh": "按域名出站白名单",
|
|
134
|
+
"en": "Domain egress allowlist"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"title": "Domain egress allowlist"
|
|
138
|
+
},
|
|
139
|
+
"allowOpenEgress": {
|
|
140
|
+
"default": false,
|
|
141
|
+
"type": "boolean",
|
|
142
|
+
"x-ui": {
|
|
143
|
+
"label": {
|
|
144
|
+
"zh": "允许开放出站",
|
|
145
|
+
"en": "Allow open egress"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"title": "Allow open egress"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"required": [
|
|
152
|
+
"apiKey",
|
|
153
|
+
"template"
|
|
154
|
+
],
|
|
155
|
+
"additionalProperties": false
|
|
156
|
+
}
|
|
60
157
|
}
|
|
61
158
|
}
|
|
62
159
|
}
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ Then set `template` to `capybara-sandbox`. Image conventions (the plugin depends
|
|
|
63
63
|
and files are not lost even when the kernel has no chance to `suspend` (for example the whole kernel is down). Every use pushes it back through connect (it only extends, never shortens).
|
|
64
64
|
Idle hibernation and expiry destruction are handled by the kernel's maintenance tasks. E2B's continuous run limit (24 hours on Pro, 1 hour on Hobby) is recounted after pause / resume.
|
|
65
65
|
- **Hobby plan**: the `timeout` of connect / create is at most 1 hour, so the deployment config `timeoutSeconds` must be ≤ 3600, and a single command can actually run at most
|
|
66
|
-
about 1 hour minus 2 minutes; however large the `
|
|
66
|
+
about 1 hour minus 2 minutes; however large the `Bash` `timeout` (in milliseconds) is (capped by `sandbox.limits.maxCommandSeconds`, default 7200 seconds), it will be interrupted by the pause when the sandbox expires.
|
|
67
67
|
On Hobby, set `sandbox.limits.maxCommandSeconds` to below 3480.
|
|
68
68
|
- E2B keeps a paused sandbox indefinitely until it is deleted (the kernel deletes by `destroyAfterInactiveDays`).
|
|
69
69
|
|
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ const __capybara_filename = __capybaraFileURLToPath(import.meta.url);
|
|
|
6
6
|
const __capybara_dirname = __capybaraPathDirname(__capybara_filename);
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import { defineExtension, SANDBOX_EXTENSION_POINT, secret } from "@capybara-hq/plugin-sdk";
|
|
9
|
+
import { defineExtension, SANDBOX_EXTENSION_POINT, secret, ui } from "@capybara-hq/plugin-sdk";
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
12
|
// src/provider.ts
|
|
@@ -228,7 +228,7 @@ var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
|
228
228
|
var HOSTNAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/;
|
|
229
229
|
var SANDBOX_ID_RE = /^[a-zA-Z0-9-]{1,128}$/;
|
|
230
230
|
var IN_SANDBOX_GRACE_SECONDS = 5;
|
|
231
|
-
var EXEC_WRAPPER = 'c=$1; echo $$ > "$c.pid" 2>/dev/null; if [ -e "$c.kill" ]; then exit 137; fi; timeout -s KILL "$3" /bin/bash -c "$2"; s=$?; rm -f "$c.pid"; exit $s';
|
|
231
|
+
var EXEC_WRAPPER = 'c=$1; echo $$ > "$c.pid" 2>/dev/null; if [ -e "$c.kill" ]; then exit 137; fi; timeout -s KILL "$3" /bin/bash -c "$2"; s=$?; if [ $s -eq 124 ] || [ $s -eq 137 ]; then for p in $(pgrep -s $$); do [ "$p" = $$ ] || kill -9 "$p" 2>/dev/null; done; fi; rm -f "$c.pid"; exit $s';
|
|
232
232
|
function execArgs(ctl, command, timeoutMs) {
|
|
233
233
|
const seconds = Math.ceil(timeoutMs / 1e3) + IN_SANDBOX_GRACE_SECONDS;
|
|
234
234
|
return ["-w", "/bin/sh", "-c", EXEC_WRAPPER, "capybara-exec", ctl, command, String(seconds)];
|
|
@@ -746,31 +746,42 @@ function checkLimits(l) {
|
|
|
746
746
|
var MAX_TIMEOUT_SECONDS2 = 86400;
|
|
747
747
|
var DeploymentConfig = z.object({
|
|
748
748
|
/** E2B API key(`e2b_…`)。 */
|
|
749
|
-
apiKey: secret(z.string().min(1)),
|
|
749
|
+
apiKey: ui(secret(z.string().min(1)), { label: { zh: "API 密钥", en: "API key" } }),
|
|
750
750
|
/** 控制面 API 地址;不填为 `https://api.<domain>`。自托管 E2B 填自己的地址。 */
|
|
751
|
-
apiUrl: z.url({ protocol: /^https?$/ }).optional(),
|
|
751
|
+
apiUrl: ui(z.url({ protocol: /^https?$/ }).optional(), {
|
|
752
|
+
label: { zh: "接口地址", en: "API URL" }
|
|
753
|
+
}),
|
|
752
754
|
/** 沙箱域名(envd 地址为 `https://49983-<沙箱 id>.<domain>`);API 返回了沙箱自己的域名时以返回的为准。 */
|
|
753
|
-
domain:
|
|
754
|
-
|
|
755
|
-
|
|
755
|
+
domain: ui(
|
|
756
|
+
z.string().regex(HOSTNAME_RE, {
|
|
757
|
+
message: "domain must be a lowercase hostname such as e2b.app"
|
|
758
|
+
}).default("e2b.app"),
|
|
759
|
+
{ label: { zh: "沙箱域名", en: "Sandbox domain" } }
|
|
760
|
+
),
|
|
756
761
|
/** 模板名或 id:由 plugins/sandbox-docker/image/Dockerfile 构建(见 README)。 */
|
|
757
|
-
template: z.string().min(1),
|
|
762
|
+
template: ui(z.string().min(1), { label: { zh: "模板", en: "Template" } }),
|
|
758
763
|
/**
|
|
759
764
|
* 沙箱的超时(秒,默认 3600):到点 E2B 自动暂停(不是删除)沙箱,文件保留。内核每次用沙箱时把它往后推,
|
|
760
765
|
* 长命令会按命令超时再加余量推后;空闲休眠与过期销毁由内核负责。
|
|
761
766
|
*/
|
|
762
|
-
timeoutSeconds: z.number().int().min(60).max(MAX_TIMEOUT_SECONDS2).default(3600),
|
|
767
|
+
timeoutSeconds: ui(z.number().int().min(60).max(MAX_TIMEOUT_SECONDS2).default(3600), {
|
|
768
|
+
label: { zh: "沙箱超时", en: "Sandbox timeout" }
|
|
769
|
+
}),
|
|
763
770
|
/**
|
|
764
771
|
* E2B 是否支持按域名的出站白名单(E2B 云:支持)。为 false 时(不支持的自托管版本)`allowlist` 退化为
|
|
765
772
|
* `none` 并打告警。
|
|
766
773
|
*/
|
|
767
|
-
domainAllowlist: z.boolean().default(true),
|
|
774
|
+
domainAllowlist: ui(z.boolean().default(true), {
|
|
775
|
+
label: { zh: "按域名出站白名单", en: "Domain egress allowlist" }
|
|
776
|
+
}),
|
|
768
777
|
/** 允许 `sandbox.limits.egress = "open"`(默认 false)。为 false 时 `create` 收到 open 直接报错。 */
|
|
769
|
-
allowOpenEgress: z.boolean().default(false)
|
|
778
|
+
allowOpenEgress: ui(z.boolean().default(false), {
|
|
779
|
+
label: { zh: "允许开放出站", en: "Allow open egress" }
|
|
780
|
+
})
|
|
770
781
|
}).strict();
|
|
771
782
|
var index_default = defineExtension({
|
|
772
783
|
name: "sandbox-e2b",
|
|
773
|
-
version: "0.1.0-rc.
|
|
784
|
+
version: "0.1.0-rc.2",
|
|
774
785
|
sdk: "^0.1.0-rc.0",
|
|
775
786
|
provides: [SANDBOX_EXTENSION_POINT],
|
|
776
787
|
// 只用部署配置与 E2B 的 API,不用任何需要声明的平台能力
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capybara-hq/plugin-sandbox-e2b",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Conversation sandboxes (sandbox@1) as E2B sandboxes (E2B cloud or self-hosted), with pause / resume and E2B egress controls",
|