workerclaw 0.2.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.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/dist/active-behavior/behavior-scheduler.d.ts +119 -0
  4. package/dist/active-behavior/behavior-scheduler.d.ts.map +1 -0
  5. package/dist/active-behavior/behavior-scheduler.js +297 -0
  6. package/dist/active-behavior/behavior-scheduler.js.map +1 -0
  7. package/dist/active-behavior/frequency-control.d.ts +72 -0
  8. package/dist/active-behavior/frequency-control.d.ts.map +1 -0
  9. package/dist/active-behavior/frequency-control.js +206 -0
  10. package/dist/active-behavior/frequency-control.js.map +1 -0
  11. package/dist/active-behavior/index.d.ts +8 -0
  12. package/dist/active-behavior/index.d.ts.map +1 -0
  13. package/dist/active-behavior/index.js +6 -0
  14. package/dist/active-behavior/index.js.map +1 -0
  15. package/dist/agent/agent-engine.d.ts +122 -0
  16. package/dist/agent/agent-engine.d.ts.map +1 -0
  17. package/dist/agent/agent-engine.js +380 -0
  18. package/dist/agent/agent-engine.js.map +1 -0
  19. package/dist/agent/context-window.d.ts +69 -0
  20. package/dist/agent/context-window.d.ts.map +1 -0
  21. package/dist/agent/context-window.js +210 -0
  22. package/dist/agent/context-window.js.map +1 -0
  23. package/dist/agent/llm-client.d.ts +37 -0
  24. package/dist/agent/llm-client.d.ts.map +1 -0
  25. package/dist/agent/llm-client.js +155 -0
  26. package/dist/agent/llm-client.js.map +1 -0
  27. package/dist/agent/personality.d.ts +71 -0
  28. package/dist/agent/personality.d.ts.map +1 -0
  29. package/dist/agent/personality.js +147 -0
  30. package/dist/agent/personality.js.map +1 -0
  31. package/dist/agent/session-manager.d.ts +111 -0
  32. package/dist/agent/session-manager.d.ts.map +1 -0
  33. package/dist/agent/session-manager.js +205 -0
  34. package/dist/agent/session-manager.js.map +1 -0
  35. package/dist/agent/tool-executor.d.ts +34 -0
  36. package/dist/agent/tool-executor.d.ts.map +1 -0
  37. package/dist/agent/tool-executor.js +145 -0
  38. package/dist/agent/tool-executor.js.map +1 -0
  39. package/dist/agent/tool-registry.d.ts +67 -0
  40. package/dist/agent/tool-registry.d.ts.map +1 -0
  41. package/dist/agent/tool-registry.js +272 -0
  42. package/dist/agent/tool-registry.js.map +1 -0
  43. package/dist/cli/configure.d.ts +16 -0
  44. package/dist/cli/configure.d.ts.map +1 -0
  45. package/dist/cli/configure.js +212 -0
  46. package/dist/cli/configure.js.map +1 -0
  47. package/dist/cli/index.d.ts +17 -0
  48. package/dist/cli/index.d.ts.map +1 -0
  49. package/dist/cli/index.js +256 -0
  50. package/dist/cli/index.js.map +1 -0
  51. package/dist/cli/prompter.d.ts +59 -0
  52. package/dist/cli/prompter.d.ts.map +1 -0
  53. package/dist/cli/prompter.js +120 -0
  54. package/dist/cli/prompter.js.map +1 -0
  55. package/dist/cli/sections/index.d.ts +9 -0
  56. package/dist/cli/sections/index.d.ts.map +1 -0
  57. package/dist/cli/sections/index.js +9 -0
  58. package/dist/cli/sections/index.js.map +1 -0
  59. package/dist/cli/sections/llm.d.ts +14 -0
  60. package/dist/cli/sections/llm.d.ts.map +1 -0
  61. package/dist/cli/sections/llm.js +155 -0
  62. package/dist/cli/sections/llm.js.map +1 -0
  63. package/dist/cli/sections/personality.d.ts +14 -0
  64. package/dist/cli/sections/personality.d.ts.map +1 -0
  65. package/dist/cli/sections/personality.js +90 -0
  66. package/dist/cli/sections/personality.js.map +1 -0
  67. package/dist/cli/sections/platform.d.ts +14 -0
  68. package/dist/cli/sections/platform.d.ts.map +1 -0
  69. package/dist/cli/sections/platform.js +179 -0
  70. package/dist/cli/sections/platform.js.map +1 -0
  71. package/dist/cli/sections/security.d.ts +14 -0
  72. package/dist/cli/sections/security.d.ts.map +1 -0
  73. package/dist/cli/sections/security.js +106 -0
  74. package/dist/cli/sections/security.js.map +1 -0
  75. package/dist/cli/sections/skills.d.ts +10 -0
  76. package/dist/cli/sections/skills.d.ts.map +1 -0
  77. package/dist/cli/sections/skills.js +149 -0
  78. package/dist/cli/sections/skills.js.map +1 -0
  79. package/dist/cli.d.ts +8 -0
  80. package/dist/cli.d.ts.map +1 -0
  81. package/dist/cli.js +116 -0
  82. package/dist/cli.js.map +1 -0
  83. package/dist/core/config.d.ts +175 -0
  84. package/dist/core/config.d.ts.map +1 -0
  85. package/dist/core/config.js +109 -0
  86. package/dist/core/config.js.map +1 -0
  87. package/dist/core/events.d.ts +211 -0
  88. package/dist/core/events.d.ts.map +1 -0
  89. package/dist/core/events.js +152 -0
  90. package/dist/core/events.js.map +1 -0
  91. package/dist/core/logger.d.ts +23 -0
  92. package/dist/core/logger.d.ts.map +1 -0
  93. package/dist/core/logger.js +53 -0
  94. package/dist/core/logger.js.map +1 -0
  95. package/dist/core/workerclaw.d.ts +83 -0
  96. package/dist/core/workerclaw.d.ts.map +1 -0
  97. package/dist/core/workerclaw.js +161 -0
  98. package/dist/core/workerclaw.js.map +1 -0
  99. package/dist/index.d.ts +27 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +21 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/ingress/message-parser.d.ts +36 -0
  104. package/dist/ingress/message-parser.d.ts.map +1 -0
  105. package/dist/ingress/message-parser.js +107 -0
  106. package/dist/ingress/message-parser.js.map +1 -0
  107. package/dist/ingress/miniabc-client.d.ts +109 -0
  108. package/dist/ingress/miniabc-client.d.ts.map +1 -0
  109. package/dist/ingress/miniabc-client.js +345 -0
  110. package/dist/ingress/miniabc-client.js.map +1 -0
  111. package/dist/ingress/platform-api.d.ts +82 -0
  112. package/dist/ingress/platform-api.d.ts.map +1 -0
  113. package/dist/ingress/platform-api.js +209 -0
  114. package/dist/ingress/platform-api.js.map +1 -0
  115. package/dist/sandbox/command-sandbox.d.ts +46 -0
  116. package/dist/sandbox/command-sandbox.d.ts.map +1 -0
  117. package/dist/sandbox/command-sandbox.js +144 -0
  118. package/dist/sandbox/command-sandbox.js.map +1 -0
  119. package/dist/sandbox/fs-sandbox.d.ts +56 -0
  120. package/dist/sandbox/fs-sandbox.d.ts.map +1 -0
  121. package/dist/sandbox/fs-sandbox.js +119 -0
  122. package/dist/sandbox/fs-sandbox.js.map +1 -0
  123. package/dist/sandbox/network-sandbox.d.ts +41 -0
  124. package/dist/sandbox/network-sandbox.d.ts.map +1 -0
  125. package/dist/sandbox/network-sandbox.js +114 -0
  126. package/dist/sandbox/network-sandbox.js.map +1 -0
  127. package/dist/security/content-scanner.d.ts +59 -0
  128. package/dist/security/content-scanner.d.ts.map +1 -0
  129. package/dist/security/content-scanner.js +289 -0
  130. package/dist/security/content-scanner.js.map +1 -0
  131. package/dist/security/gate.d.ts +78 -0
  132. package/dist/security/gate.d.ts.map +1 -0
  133. package/dist/security/gate.js +150 -0
  134. package/dist/security/gate.js.map +1 -0
  135. package/dist/security/permission-level.d.ts +68 -0
  136. package/dist/security/permission-level.d.ts.map +1 -0
  137. package/dist/security/permission-level.js +191 -0
  138. package/dist/security/permission-level.js.map +1 -0
  139. package/dist/security/rate-limiter.d.ts +52 -0
  140. package/dist/security/rate-limiter.d.ts.map +1 -0
  141. package/dist/security/rate-limiter.js +133 -0
  142. package/dist/security/rate-limiter.js.map +1 -0
  143. package/dist/security/source-verifier.d.ts +33 -0
  144. package/dist/security/source-verifier.d.ts.map +1 -0
  145. package/dist/security/source-verifier.js +106 -0
  146. package/dist/security/source-verifier.js.map +1 -0
  147. package/dist/skills/builtin/code.d.ts +27 -0
  148. package/dist/skills/builtin/code.d.ts.map +1 -0
  149. package/dist/skills/builtin/code.js +132 -0
  150. package/dist/skills/builtin/code.js.map +1 -0
  151. package/dist/skills/builtin/index.d.ts +12 -0
  152. package/dist/skills/builtin/index.d.ts.map +1 -0
  153. package/dist/skills/builtin/index.js +16 -0
  154. package/dist/skills/builtin/index.js.map +1 -0
  155. package/dist/skills/builtin/search.d.ts +27 -0
  156. package/dist/skills/builtin/search.d.ts.map +1 -0
  157. package/dist/skills/builtin/search.js +105 -0
  158. package/dist/skills/builtin/search.js.map +1 -0
  159. package/dist/skills/builtin/writing.d.ts +22 -0
  160. package/dist/skills/builtin/writing.d.ts.map +1 -0
  161. package/dist/skills/builtin/writing.js +93 -0
  162. package/dist/skills/builtin/writing.js.map +1 -0
  163. package/dist/skills/index.d.ts +11 -0
  164. package/dist/skills/index.d.ts.map +1 -0
  165. package/dist/skills/index.js +10 -0
  166. package/dist/skills/index.js.map +1 -0
  167. package/dist/skills/pack-loader.d.ts +31 -0
  168. package/dist/skills/pack-loader.d.ts.map +1 -0
  169. package/dist/skills/pack-loader.js +167 -0
  170. package/dist/skills/pack-loader.js.map +1 -0
  171. package/dist/skills/pack-registry.d.ts +40 -0
  172. package/dist/skills/pack-registry.d.ts.map +1 -0
  173. package/dist/skills/pack-registry.js +80 -0
  174. package/dist/skills/pack-registry.js.map +1 -0
  175. package/dist/skills/pack-types.d.ts +64 -0
  176. package/dist/skills/pack-types.d.ts.map +1 -0
  177. package/dist/skills/pack-types.js +7 -0
  178. package/dist/skills/pack-types.js.map +1 -0
  179. package/dist/skills/skill-registry.d.ts +83 -0
  180. package/dist/skills/skill-registry.d.ts.map +1 -0
  181. package/dist/skills/skill-registry.js +206 -0
  182. package/dist/skills/skill-registry.js.map +1 -0
  183. package/dist/skills/skill-runner.d.ts +49 -0
  184. package/dist/skills/skill-runner.d.ts.map +1 -0
  185. package/dist/skills/skill-runner.js +128 -0
  186. package/dist/skills/skill-runner.js.map +1 -0
  187. package/dist/skills/types.d.ts +94 -0
  188. package/dist/skills/types.d.ts.map +1 -0
  189. package/dist/skills/types.js +7 -0
  190. package/dist/skills/types.js.map +1 -0
  191. package/dist/task/concurrency.d.ts +87 -0
  192. package/dist/task/concurrency.d.ts.map +1 -0
  193. package/dist/task/concurrency.js +269 -0
  194. package/dist/task/concurrency.js.map +1 -0
  195. package/dist/task/task-evaluator.d.ts +52 -0
  196. package/dist/task/task-evaluator.d.ts.map +1 -0
  197. package/dist/task/task-evaluator.js +141 -0
  198. package/dist/task/task-evaluator.js.map +1 -0
  199. package/dist/task/task-manager.d.ts +112 -0
  200. package/dist/task/task-manager.d.ts.map +1 -0
  201. package/dist/task/task-manager.js +382 -0
  202. package/dist/task/task-manager.js.map +1 -0
  203. package/dist/task/task-state-machine.d.ts +63 -0
  204. package/dist/task/task-state-machine.d.ts.map +1 -0
  205. package/dist/task/task-state-machine.js +149 -0
  206. package/dist/task/task-state-machine.js.map +1 -0
  207. package/dist/types/agent.d.ts +79 -0
  208. package/dist/types/agent.d.ts.map +1 -0
  209. package/dist/types/agent.js +7 -0
  210. package/dist/types/agent.js.map +1 -0
  211. package/dist/types/index.d.ts +7 -0
  212. package/dist/types/index.d.ts.map +1 -0
  213. package/dist/types/index.js +5 -0
  214. package/dist/types/index.js.map +1 -0
  215. package/dist/types/message.d.ts +87 -0
  216. package/dist/types/message.d.ts.map +1 -0
  217. package/dist/types/message.js +30 -0
  218. package/dist/types/message.js.map +1 -0
  219. package/dist/types/task.d.ts +176 -0
  220. package/dist/types/task.d.ts.map +1 -0
  221. package/dist/types/task.js +5 -0
  222. package/dist/types/task.js.map +1 -0
  223. package/package.json +57 -0
  224. package/workerclaw.config.example.json +78 -0
@@ -0,0 +1,209 @@
1
+ /**
2
+ * 平台 API 客户端
3
+ *
4
+ * 负责与智工坊平台 HTTP API 通信
5
+ * - 任务结果上报
6
+ * - 任务状态更新
7
+ * - 心跳续约
8
+ */
9
+ import { createLogger } from '../core/logger.js';
10
+ import { EventBus, WorkerClawEvent } from '../core/events.js';
11
+ export class PlatformApiClient {
12
+ logger = createLogger('PlatformAPI');
13
+ eventBus;
14
+ config;
15
+ constructor(config, eventBus) {
16
+ if ('platform' in config) {
17
+ this.config = config.platform;
18
+ this.eventBus = eventBus;
19
+ }
20
+ else {
21
+ this.config = config;
22
+ this.eventBus = eventBus || new EventBus();
23
+ }
24
+ }
25
+ /**
26
+ * 上报任务结果
27
+ */
28
+ async reportResult(taskId, result) {
29
+ const endpoint = `${this.config.apiUrl}/tasks/${taskId}/result`;
30
+ try {
31
+ this.eventBus.emit(WorkerClawEvent.API_REPORT, {
32
+ taskId,
33
+ endpoint,
34
+ });
35
+ const response = await this.request(endpoint, 'POST', {
36
+ taskId,
37
+ status: result.status,
38
+ content: result.content,
39
+ outputs: result.outputs,
40
+ tokensUsed: result.tokensUsed,
41
+ durationMs: result.durationMs,
42
+ error: result.error,
43
+ reportedAt: new Date().toISOString(),
44
+ });
45
+ if (response.ok) {
46
+ this.logger.info(`任务结果上报成功 [${taskId}]`, { status: result.status });
47
+ return true;
48
+ }
49
+ else {
50
+ this.logger.error(`任务结果上报失败 [${taskId}]`, {
51
+ status: response.status,
52
+ body: await response.text().catch(() => 'unknown'),
53
+ });
54
+ this.eventBus.emit(WorkerClawEvent.API_ERROR, {
55
+ taskId,
56
+ endpoint,
57
+ error: new Error(`HTTP ${response.status}`),
58
+ });
59
+ return false;
60
+ }
61
+ }
62
+ catch (err) {
63
+ const error = err;
64
+ this.logger.error(`任务结果上报异常 [${taskId}]`, { error: error.message });
65
+ this.eventBus.emit(WorkerClawEvent.API_ERROR, {
66
+ taskId,
67
+ endpoint,
68
+ error,
69
+ });
70
+ return false;
71
+ }
72
+ }
73
+ /**
74
+ * 更新任务状态
75
+ */
76
+ async updateStatus(taskId, status, reason) {
77
+ const endpoint = `${this.config.apiUrl}/tasks/${taskId}/status`;
78
+ try {
79
+ const response = await this.request(endpoint, 'PUT', {
80
+ taskId,
81
+ status,
82
+ reason,
83
+ updatedAt: new Date().toISOString(),
84
+ });
85
+ if (response.ok) {
86
+ this.logger.debug(`任务状态更新成功 [${taskId}] → ${status}`);
87
+ return true;
88
+ }
89
+ else {
90
+ this.logger.warn(`任务状态更新失败 [${taskId}]`, { httpStatus: response.status });
91
+ return false;
92
+ }
93
+ }
94
+ catch (err) {
95
+ this.logger.warn(`任务状态更新异常 [${taskId}]`, { error: err.message });
96
+ return false;
97
+ }
98
+ }
99
+ /**
100
+ * 发送心跳续约
101
+ */
102
+ async heartbeat() {
103
+ const endpoint = `${this.config.apiUrl}/heartbeat`;
104
+ try {
105
+ const response = await this.request(endpoint, 'POST', {
106
+ botId: this.config.botId,
107
+ timestamp: new Date().toISOString(),
108
+ });
109
+ return response.ok;
110
+ }
111
+ catch {
112
+ return false;
113
+ }
114
+ }
115
+ /**
116
+ * Agent 注册
117
+ * 调用平台 API 自动创建 Agent 账户
118
+ */
119
+ async registerAgent(params) {
120
+ const endpoint = `${this.config.apiUrl}/api/openclaw/register`;
121
+ try {
122
+ const response = await fetch(endpoint, {
123
+ method: 'POST',
124
+ headers: {
125
+ 'Content-Type': 'application/json',
126
+ },
127
+ body: JSON.stringify(params),
128
+ signal: AbortSignal.timeout(15000),
129
+ });
130
+ const data = await response.json();
131
+ if (response.ok && (data.success || data.data)) {
132
+ return {
133
+ success: true,
134
+ botId: data.botId || data.data?.botId,
135
+ token: data.token || data.data?.token,
136
+ nickname: data.nickname || data.data?.nickname,
137
+ email: data.email || data.data?.email,
138
+ };
139
+ }
140
+ else {
141
+ return {
142
+ success: false,
143
+ error: data.error || data.message || `HTTP ${response.status}`,
144
+ };
145
+ }
146
+ }
147
+ catch (err) {
148
+ return {
149
+ success: false,
150
+ error: err.message,
151
+ };
152
+ }
153
+ }
154
+ /**
155
+ * 获取 Bot 信息
156
+ */
157
+ async getBotInfo(botId) {
158
+ const id = botId || this.config.botId;
159
+ const endpoint = `${this.config.apiUrl}/bots/${id}`;
160
+ try {
161
+ const response = await this.request(endpoint, 'GET', undefined);
162
+ if (!response.ok)
163
+ return null;
164
+ return await response.json();
165
+ }
166
+ catch {
167
+ return null;
168
+ }
169
+ }
170
+ /**
171
+ * 测试连接(验证 token 有效性)
172
+ */
173
+ async testConnection() {
174
+ try {
175
+ const response = await this.request(`${this.config.apiUrl}/heartbeat`, 'POST', {
176
+ botId: this.config.botId,
177
+ timestamp: new Date().toISOString(),
178
+ });
179
+ if (response.ok) {
180
+ return { success: true, botId: this.config.botId };
181
+ }
182
+ return { success: false };
183
+ }
184
+ catch {
185
+ return { success: false };
186
+ }
187
+ }
188
+ /**
189
+ * 通用 HTTP 请求方法
190
+ */
191
+ async request(url, method, body) {
192
+ const headers = {
193
+ 'Content-Type': 'application/json',
194
+ };
195
+ if (this.config.token) {
196
+ headers['Authorization'] = `Bearer ${this.config.token}`;
197
+ }
198
+ const options = {
199
+ method,
200
+ headers,
201
+ signal: AbortSignal.timeout(10000),
202
+ };
203
+ if (body !== undefined && method !== 'GET') {
204
+ options.body = JSON.stringify(body);
205
+ }
206
+ return fetch(url, options);
207
+ }
208
+ }
209
+ //# sourceMappingURL=platform-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-api.js","sourceRoot":"","sources":["../../src/ingress/platform-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 命令执行沙箱
3
+ *
4
+ * 进程级轻量沙箱,参考 OpenClaw 2026.3.22 安全增强
5
+ * - 危险命令模式阻断
6
+ * - 命令执行超时
7
+ * - 输出大小限制
8
+ * - 环境变量过滤
9
+ */
10
+ import type { PermissionLevel } from '../security/permission-level.js';
11
+ export interface CommandSandboxConfig {
12
+ commandTimeoutMs: number;
13
+ maxOutputKB: number;
14
+ allowLocalhost: boolean;
15
+ }
16
+ export interface CommandResult {
17
+ success: boolean;
18
+ stdout: string;
19
+ stderr: string;
20
+ exitCode: number | null;
21
+ durationMs: number;
22
+ truncated: boolean;
23
+ blocked?: string;
24
+ }
25
+ export declare class CommandSandbox {
26
+ private logger;
27
+ private config;
28
+ constructor(config: CommandSandboxConfig);
29
+ /**
30
+ * 在沙箱中执行命令
31
+ */
32
+ execute(command: string, options?: {
33
+ cwd?: string;
34
+ env?: Record<string, string>;
35
+ permissionLevel?: PermissionLevel;
36
+ }): Promise<CommandResult>;
37
+ /**
38
+ * 检查危险命令模式
39
+ */
40
+ checkDangerousPatterns(command: string): string | null;
41
+ /**
42
+ * 过滤环境变量
43
+ */
44
+ private filterEnvVars;
45
+ }
46
+ //# sourceMappingURL=command-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/command-sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAwCvE,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB;AAID,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,oBAAoB;IAKxC;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QACvC,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;KACnC,GAAG,OAAO,CAAC,aAAa,CAAC;IA4D1B;;OAEG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUtD;;OAEG;IACH,OAAO,CAAC,aAAa;CAoBtB"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * 命令执行沙箱
3
+ *
4
+ * 进程级轻量沙箱,参考 OpenClaw 2026.3.22 安全增强
5
+ * - 危险命令模式阻断
6
+ * - 命令执行超时
7
+ * - 输出大小限制
8
+ * - 环境变量过滤
9
+ */
10
+ import { exec } from 'node:child_process';
11
+ import { promisify } from 'node:util';
12
+ import { createLogger } from '../core/logger.js';
13
+ const execAsync = promisify(exec);
14
+ // ==================== 危险命令模式 ====================
15
+ const DANGEROUS_PATTERNS = [
16
+ // OpenClaw 2026.3.22: JVM 注入
17
+ /MAVEN_OPTS/i,
18
+ /JAVA_TOOL_OPTIONS/i,
19
+ // OpenClaw 2026.3.22: glibc 漏洞利用
20
+ /GLIBC_TUNABLES/i,
21
+ // OpenClaw 2026.3.22: .NET 依赖劫持
22
+ /DOTNET_ADDITIONAL_DEPS/i,
23
+ /DOTNET_STARTUP_HOOKS/i,
24
+ // 通用危险命令
25
+ /rm\s+-rf\s+\/(?!\s)/,
26
+ /curl.*\|.*sh/i,
27
+ /wget.*\|.*sh/i,
28
+ /mkfs/i,
29
+ /dd\s+if=/i,
30
+ />\s*\/dev\//i,
31
+ /chmod\s+777\s+\//i,
32
+ /chown\s+.*\s+\//i,
33
+ /nc\s+-[el]/i,
34
+ /socat/i,
35
+ /python.*-c.*import\s+socket/i,
36
+ /bash\s+-i\s+>&/i,
37
+ ];
38
+ // 禁止的环境变量
39
+ const BLOCKED_ENV_VARS = [
40
+ 'MAVEN_OPTS', 'JAVA_TOOL_OPTIONS', 'GLIBC_TUNABLES',
41
+ 'DOTNET_ADDITIONAL_DEPS', 'DOTNET_STARTUP_HOOKS',
42
+ 'LD_PRELOAD', 'DYLD_INSERT_LIBRARIES',
43
+ 'PYTHONPATH', 'NODE_PATH',
44
+ ];
45
+ // ==================== 命令沙箱 ====================
46
+ export class CommandSandbox {
47
+ logger;
48
+ config;
49
+ constructor(config) {
50
+ this.config = config;
51
+ this.logger = createLogger('CommandSandbox');
52
+ }
53
+ /**
54
+ * 在沙箱中执行命令
55
+ */
56
+ async execute(command, options) {
57
+ const startTime = Date.now();
58
+ // 1. 危险命令检查
59
+ const blockResult = this.checkDangerousPatterns(command);
60
+ if (blockResult) {
61
+ this.logger.warn('命令被沙箱阻断', { reason: blockResult, command: command.slice(0, 100) });
62
+ return {
63
+ success: false,
64
+ stdout: '',
65
+ stderr: `命令被安全沙箱阻断: ${blockResult}`,
66
+ exitCode: -1,
67
+ durationMs: Date.now() - startTime,
68
+ truncated: false,
69
+ blocked: blockResult,
70
+ };
71
+ }
72
+ // 2. 过滤环境变量
73
+ const safeEnv = this.filterEnvVars(options?.env);
74
+ // 3. 执行命令(带超时)
75
+ try {
76
+ const { stdout, stderr } = await execAsync(command, {
77
+ cwd: options?.cwd || process.cwd(),
78
+ env: safeEnv,
79
+ timeout: this.config.commandTimeoutMs,
80
+ maxBuffer: this.config.maxOutputKB * 1024,
81
+ // 限制子进程不产生新的子进程
82
+ shell: '/bin/bash',
83
+ });
84
+ const durationMs = Date.now() - startTime;
85
+ const truncated = stdout.length > this.config.maxOutputKB * 1024;
86
+ return {
87
+ success: true,
88
+ stdout: truncated ? stdout.slice(0, this.config.maxOutputKB * 512) : stdout,
89
+ stderr,
90
+ exitCode: 0,
91
+ durationMs,
92
+ truncated,
93
+ };
94
+ }
95
+ catch (err) {
96
+ const durationMs = Date.now() - startTime;
97
+ const stdout = err.stdout || '';
98
+ const stderr = err.stderr || '';
99
+ const truncated = stdout.length > this.config.maxOutputKB * 1024;
100
+ return {
101
+ success: false,
102
+ stdout: truncated ? stdout.slice(0, this.config.maxOutputKB * 512) : stdout,
103
+ stderr: stderr || err.message,
104
+ exitCode: err.code || -1,
105
+ durationMs,
106
+ truncated,
107
+ };
108
+ }
109
+ }
110
+ /**
111
+ * 检查危险命令模式
112
+ */
113
+ checkDangerousPatterns(command) {
114
+ for (const pattern of DANGEROUS_PATTERNS) {
115
+ if (pattern.test(command)) {
116
+ const match = command.match(pattern);
117
+ return `匹配危险模式: "${match?.[0]?.slice(0, 50)}"`;
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ /**
123
+ * 过滤环境变量
124
+ */
125
+ filterEnvVars(extraEnv) {
126
+ const env = {};
127
+ // 基础安全环境变量
128
+ const safeBase = ['PATH', 'HOME', 'LANG', 'TERM', 'NODE_ENV', 'TZ'];
129
+ for (const key of safeBase) {
130
+ if (process.env[key])
131
+ env[key] = process.env[key];
132
+ }
133
+ // 额外的安全变量
134
+ if (extraEnv) {
135
+ for (const [key, value] of Object.entries(extraEnv)) {
136
+ if (!BLOCKED_ENV_VARS.includes(key.toUpperCase())) {
137
+ env[key] = value;
138
+ }
139
+ }
140
+ }
141
+ return env;
142
+ }
143
+ }
144
+ //# sourceMappingURL=command-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-sandbox.js","sourceRoot":"","sources":["../../src/sandbox/command-sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * 文件系统沙箱
3
+ *
4
+ * 路径验证 + 工作目录隔离
5
+ * - 阻止路径遍历
6
+ * - 每个任务独立工作目录
7
+ * - 白名单/黑名单路径控制
8
+ */
9
+ export interface FsSandboxConfig {
10
+ /** 沙箱根目录 */
11
+ workDir: string;
12
+ /** 允许访问的路径(绝对路径列表) */
13
+ allowedPaths: string[];
14
+ /** 禁止访问的路径 */
15
+ deniedPaths: string[];
16
+ }
17
+ export interface PathValidation {
18
+ allowed: boolean;
19
+ resolvedPath: string;
20
+ reason?: string;
21
+ }
22
+ export declare class FsSandbox {
23
+ private logger;
24
+ private config;
25
+ private taskDirs;
26
+ constructor(config: FsSandboxConfig);
27
+ /**
28
+ * 验证路径是否允许访问
29
+ */
30
+ validatePath(requestedPath: string): PathValidation;
31
+ /**
32
+ * 为任务创建隔离工作目录
33
+ */
34
+ createTaskWorkDir(taskId: string): Promise<string>;
35
+ /**
36
+ * 获取任务工作目录
37
+ */
38
+ getTaskWorkDir(taskId: string): string | undefined;
39
+ /**
40
+ * 清理任务工作目录
41
+ */
42
+ cleanupTaskWorkDir(taskId: string): Promise<void>;
43
+ /**
44
+ * 清理所有任务工作目录
45
+ */
46
+ cleanupAll(): Promise<void>;
47
+ /**
48
+ * 确保沙箱根目录存在
49
+ */
50
+ ensureWorkDir(): Promise<void>;
51
+ /**
52
+ * 解析并标准化路径
53
+ */
54
+ private resolveAndNormalize;
55
+ }
56
+ //# sourceMappingURL=fs-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/fs-sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,eAAe;IAC9B,YAAY;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAID,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAA6B;gBAEjC,MAAM,EAAE,eAAe;IAKnC;;OAEG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc;IAmDnD;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQxD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIlD;;OAEG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAavD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMjC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAM5B"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * 文件系统沙箱
3
+ *
4
+ * 路径验证 + 工作目录隔离
5
+ * - 阻止路径遍历
6
+ * - 每个任务独立工作目录
7
+ * - 白名单/黑名单路径控制
8
+ */
9
+ import { resolve, isAbsolute, join } from 'node:path';
10
+ import { mkdir, rm } from 'node:fs/promises';
11
+ import { createLogger } from '../core/logger.js';
12
+ // ==================== 文件系统沙箱 ====================
13
+ export class FsSandbox {
14
+ logger;
15
+ config;
16
+ taskDirs = new Map();
17
+ constructor(config) {
18
+ this.config = config;
19
+ this.logger = createLogger('FsSandbox');
20
+ }
21
+ /**
22
+ * 验证路径是否允许访问
23
+ */
24
+ validatePath(requestedPath) {
25
+ const resolved = this.resolveAndNormalize(requestedPath);
26
+ // 1. 检查黑名单
27
+ for (const denied of this.config.deniedPaths) {
28
+ if (resolved.startsWith(denied) || resolved === denied) {
29
+ return {
30
+ allowed: false,
31
+ resolvedPath: '',
32
+ reason: `路径 "${requestedPath}" 在禁止访问列表中(匹配 ${denied})`,
33
+ };
34
+ }
35
+ }
36
+ // 2. 检查白名单
37
+ const isAllowed = this.config.allowedPaths.some(allowed => resolved.startsWith(allowed));
38
+ // 3. 检查是否在任务工作目录内
39
+ const isInTaskDir = [...this.taskDirs.values()].some(taskDir => resolved.startsWith(taskDir));
40
+ // 4. 检查是否在沙箱根目录内
41
+ const workDirResolved = resolve(this.config.workDir);
42
+ const isInWorkDir = resolved.startsWith(workDirResolved);
43
+ if (!isAllowed && !isInTaskDir && !isInWorkDir) {
44
+ return {
45
+ allowed: false,
46
+ resolvedPath: '',
47
+ reason: `路径 "${requestedPath}" 不在允许的访问范围内`,
48
+ };
49
+ }
50
+ // 5. 检查路径遍历(已通过 resolve 处理,这里做二次校验)
51
+ if (requestedPath.includes('..')) {
52
+ const normalized = resolve(requestedPath);
53
+ if (!normalized.startsWith(resolve(this.config.workDir))) {
54
+ return {
55
+ allowed: false,
56
+ resolvedPath: '',
57
+ reason: '路径遍历攻击已阻止',
58
+ };
59
+ }
60
+ }
61
+ return { allowed: true, resolvedPath: resolved };
62
+ }
63
+ /**
64
+ * 为任务创建隔离工作目录
65
+ */
66
+ async createTaskWorkDir(taskId) {
67
+ const dir = join(resolve(this.config.workDir), `task-${taskId}-${Date.now()}`);
68
+ await mkdir(dir, { recursive: true });
69
+ this.taskDirs.set(taskId, dir);
70
+ this.logger.debug(`创建任务工作目录: ${dir}`);
71
+ return dir;
72
+ }
73
+ /**
74
+ * 获取任务工作目录
75
+ */
76
+ getTaskWorkDir(taskId) {
77
+ return this.taskDirs.get(taskId);
78
+ }
79
+ /**
80
+ * 清理任务工作目录
81
+ */
82
+ async cleanupTaskWorkDir(taskId) {
83
+ const dir = this.taskDirs.get(taskId);
84
+ if (!dir)
85
+ return;
86
+ try {
87
+ await rm(dir, { recursive: true, force: true });
88
+ this.taskDirs.delete(taskId);
89
+ this.logger.debug(`清理任务工作目录: ${dir}`);
90
+ }
91
+ catch (err) {
92
+ this.logger.warn(`清理工作目录失败: ${dir}`, err.message);
93
+ }
94
+ }
95
+ /**
96
+ * 清理所有任务工作目录
97
+ */
98
+ async cleanupAll() {
99
+ for (const taskId of [...this.taskDirs.keys()]) {
100
+ await this.cleanupTaskWorkDir(taskId);
101
+ }
102
+ }
103
+ /**
104
+ * 确保沙箱根目录存在
105
+ */
106
+ async ensureWorkDir() {
107
+ await mkdir(resolve(this.config.workDir), { recursive: true });
108
+ }
109
+ /**
110
+ * 解析并标准化路径
111
+ */
112
+ resolveAndNormalize(inputPath) {
113
+ if (!isAbsolute(inputPath)) {
114
+ inputPath = resolve(inputPath);
115
+ }
116
+ return resolve(inputPath);
117
+ }
118
+ }
119
+ //# sourceMappingURL=fs-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-sandbox.js","sourceRoot":"","sources":["../../src/sandbox/fs-sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * 网络访问沙箱
3
+ *
4
+ * URL 验证 + 域名白名单 + SSRF 防护
5
+ * 参考 OpenClaw 的安全增强设计
6
+ */
7
+ import type { PermissionLevel } from '../security/permission-level.js';
8
+ export interface NetworkSandboxConfig {
9
+ allowLocalhost: boolean;
10
+ allowedDomains: string[];
11
+ deniedDomains: string[];
12
+ blockUnknownDomains: boolean;
13
+ }
14
+ export interface UrlValidation {
15
+ allowed: boolean;
16
+ reason?: string;
17
+ protocol?: string;
18
+ hostname?: string;
19
+ }
20
+ export declare class NetworkSandbox {
21
+ private logger;
22
+ private config;
23
+ constructor(config: NetworkSandboxConfig);
24
+ /**
25
+ * 验证 URL 是否允许访问
26
+ */
27
+ validateUrl(url: string, permissionLevel?: PermissionLevel): UrlValidation;
28
+ /**
29
+ * 检查是否是本地/内网地址
30
+ */
31
+ isLocalAddress(hostname: string): boolean;
32
+ /**
33
+ * 域名匹配(支持通配符 *)
34
+ */
35
+ private matchDomain;
36
+ /**
37
+ * 验证并返回安全的 URL(用于 fetch 包装)
38
+ */
39
+ safeFetchUrl(url: string, permissionLevel?: PermissionLevel): string;
40
+ }
41
+ //# sourceMappingURL=network-sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network-sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/network-sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAIvE,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAID,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoBD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,oBAAoB;IAKxC;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,eAAe,GAAG,aAAa;IAoD1E;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAezC;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,eAAe,GAAG,MAAM;CAOrE"}