foliko 1.0.80 → 1.0.81

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 (235) hide show
  1. package/.agent/agents/code-assistant.json +14 -0
  2. package/.agent/agents/email-assistant.json +14 -0
  3. package/.agent/agents/file-assistant.json +15 -0
  4. package/.agent/agents/system-assistant.json +15 -0
  5. package/.agent/agents/web-assistant.json +12 -0
  6. package/.agent/data/ambient/goals.json +50 -0
  7. package/.agent/data/ambient/memories.json +7 -0
  8. package/.agent/data/default.json +15 -31894
  9. package/.agent/data/plugins-state.json +146 -181
  10. package/.agent/data/scheduler/tasks.json +1 -0
  11. package/.agent/mcp_config.json +1 -0
  12. package/.agent/package.json +8 -0
  13. package/.agent/plugins/__pycache__/test_plugin.cpython-312.pyc +0 -0
  14. package/.agent/plugins/system-info/index.js +387 -0
  15. package/.agent/plugins/system-info/package.json +4 -0
  16. package/.agent/plugins/system-info/test.js +40 -0
  17. package/.agent/plugins/test_plugin.py +304 -0
  18. package/.agent/plugins.json +14 -5
  19. package/.agent/python-scripts/test_sample.py +24 -0
  20. package/.agent/skills/sysinfo/SKILL.md +38 -0
  21. package/.agent/skills/sysinfo/system-info.sh +130 -0
  22. package/.agent/skills/workflow/SKILL.md +324 -0
  23. package/.agent/workflows/email-digest.json +50 -0
  24. package/.agent/workflows/file-backup.json +21 -0
  25. package/.agent/workflows/get-ip-notify.json +32 -0
  26. package/.agent/workflows/news-aggregator.json +93 -0
  27. package/.agent/workflows/news-dashboard-v2.json +94 -0
  28. package/.agent/workflows/notification-batch.json +32 -0
  29. package/.claude/settings.local.json +171 -171
  30. package/.env.example +56 -56
  31. package/cli/bin/foliko.js +12 -12
  32. package/cli/src/commands/chat.js +143 -143
  33. package/cli/src/commands/list.js +93 -93
  34. package/cli/src/index.js +75 -75
  35. package/cli/src/ui/chat-ui.js +201 -201
  36. package/cli/src/utils/ansi.js +40 -40
  37. package/cli/src/utils/markdown.js +292 -292
  38. package/examples/ambient-example.js +194 -194
  39. package/examples/basic.js +115 -115
  40. package/examples/bootstrap.js +121 -121
  41. package/examples/mcp-example.js +56 -56
  42. package/examples/skill-example.js +49 -49
  43. package/examples/test-chat.js +137 -137
  44. package/examples/test-mcp.js +85 -85
  45. package/examples/test-reload.js +59 -59
  46. package/examples/test-telegram.js +50 -50
  47. package/examples/test-tg-bot.js +45 -45
  48. package/examples/test-tg-simple.js +47 -47
  49. package/examples/test-tg.js +62 -62
  50. package/examples/test-think.js +43 -43
  51. package/examples/test-web-plugin.js +103 -103
  52. package/examples/test-weixin-feishu.js +103 -103
  53. package/examples/workflow.js +158 -158
  54. package/package.json +83 -83
  55. package/plugins/ai-plugin.js +102 -102
  56. package/plugins/ambient-agent/EventWatcher.js +113 -113
  57. package/plugins/ambient-agent/ExplorerLoop.js +640 -640
  58. package/plugins/ambient-agent/GoalManager.js +197 -197
  59. package/plugins/ambient-agent/Reflector.js +95 -95
  60. package/plugins/ambient-agent/StateStore.js +90 -90
  61. package/plugins/ambient-agent/constants.js +101 -101
  62. package/plugins/ambient-agent/index.js +579 -579
  63. package/plugins/audit-plugin.js +187 -187
  64. package/plugins/default-plugins.js +548 -548
  65. package/plugins/email/constants.js +64 -64
  66. package/plugins/email/handlers.js +461 -461
  67. package/plugins/email/index.js +278 -278
  68. package/plugins/email/monitor.js +269 -269
  69. package/plugins/email/parser.js +138 -138
  70. package/plugins/email/reply.js +151 -151
  71. package/plugins/email/utils.js +124 -124
  72. package/plugins/extension-executor-plugin.js +326 -326
  73. package/plugins/feishu-plugin.js +481 -481
  74. package/plugins/file-system-plugin.js +920 -877
  75. package/plugins/gate-trading.js +747 -747
  76. package/plugins/install-plugin.js +199 -199
  77. package/plugins/python-executor-plugin.js +367 -367
  78. package/plugins/python-plugin-loader.js +651 -651
  79. package/plugins/rules-plugin.js +294 -294
  80. package/plugins/scheduler-plugin.js +691 -691
  81. package/plugins/session-plugin.js +494 -494
  82. package/plugins/shell-executor-plugin.js +197 -197
  83. package/plugins/storage-plugin.js +263 -263
  84. package/plugins/subagent-plugin.js +845 -845
  85. package/plugins/telegram-plugin.js +482 -482
  86. package/plugins/think-plugin.js +345 -345
  87. package/plugins/tools-plugin.js +196 -196
  88. package/plugins/web-plugin.js +637 -637
  89. package/plugins/weixin-plugin.js +545 -545
  90. package/skills/find-skills/AGENTS.md +162 -162
  91. package/skills/find-skills/SKILL.md +133 -133
  92. package/skills/foliko-dev/SKILL.md +563 -583
  93. package/skills/python-plugin-dev/SKILL.md +238 -238
  94. package/src/capabilities/index.js +11 -11
  95. package/src/capabilities/skill-manager.js +609 -609
  96. package/src/capabilities/workflow-engine.js +1109 -1109
  97. package/src/core/agent-chat.js +141 -134
  98. package/src/core/agent.js +958 -958
  99. package/src/core/framework.js +465 -465
  100. package/src/core/index.js +19 -19
  101. package/src/core/plugin-base.js +262 -262
  102. package/src/core/plugin-manager.js +863 -863
  103. package/src/core/provider.js +114 -114
  104. package/src/core/sub-agent-config.js +264 -264
  105. package/src/core/system-prompt-builder.js +120 -120
  106. package/src/core/tool-registry.js +517 -517
  107. package/src/core/tool-router.js +297 -297
  108. package/src/executors/executor-base.js +58 -58
  109. package/src/executors/mcp-executor.js +845 -845
  110. package/src/index.js +25 -25
  111. package/src/utils/circuit-breaker.js +301 -301
  112. package/src/utils/error-boundary.js +363 -363
  113. package/src/utils/error.js +374 -374
  114. package/src/utils/event-emitter.js +97 -97
  115. package/src/utils/id.js +133 -133
  116. package/src/utils/index.js +217 -217
  117. package/src/utils/logger.js +181 -181
  118. package/src/utils/plugin-helpers.js +90 -90
  119. package/src/utils/retry.js +122 -122
  120. package/src/utils/sandbox.js +292 -292
  121. package/test/tool-registry-validation.test.js +218 -218
  122. package/website/script.js +136 -136
  123. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +0 -26
  124. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +0 -97
  125. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +0 -101
  126. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +0 -31
  127. package/.agent/.shared/ui-ux-pro-max/data/products.csv +0 -97
  128. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +0 -24
  129. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +0 -45
  130. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  131. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  132. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  133. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  134. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
  135. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  136. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  137. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +0 -54
  138. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  139. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  140. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  141. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  142. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +0 -59
  143. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +0 -58
  144. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  145. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  146. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +0 -31
  147. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
  148. package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
  149. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +0 -258
  150. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +0 -1067
  151. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +0 -106
  152. package/.agent/ARCHITECTURE.md +0 -288
  153. package/.agent/agents/ambient-agent.md +0 -57
  154. package/.agent/agents/debugger.md +0 -55
  155. package/.agent/agents/email-assistant.md +0 -49
  156. package/.agent/agents/file-manager.md +0 -42
  157. package/.agent/agents/python-developer.md +0 -60
  158. package/.agent/agents/scheduler.md +0 -59
  159. package/.agent/agents/web-developer.md +0 -45
  160. package/.agent/mcp_config_updated.json +0 -12
  161. package/.agent/rules/GEMINI.md +0 -273
  162. package/.agent/rules/allow-rule.md +0 -77
  163. package/.agent/rules/log-rule.md +0 -83
  164. package/.agent/rules/security-rule.md +0 -93
  165. package/.agent/scripts/auto_preview.py +0 -148
  166. package/.agent/scripts/checklist.py +0 -217
  167. package/.agent/scripts/session_manager.py +0 -120
  168. package/.agent/scripts/verify_all.py +0 -327
  169. package/.agent/skills/api-patterns/SKILL.md +0 -81
  170. package/.agent/skills/api-patterns/api-style.md +0 -42
  171. package/.agent/skills/api-patterns/auth.md +0 -24
  172. package/.agent/skills/api-patterns/documentation.md +0 -26
  173. package/.agent/skills/api-patterns/graphql.md +0 -41
  174. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  175. package/.agent/skills/api-patterns/response.md +0 -37
  176. package/.agent/skills/api-patterns/rest.md +0 -40
  177. package/.agent/skills/api-patterns/scripts/api_validator.py +0 -211
  178. package/.agent/skills/api-patterns/security-testing.md +0 -122
  179. package/.agent/skills/api-patterns/trpc.md +0 -41
  180. package/.agent/skills/api-patterns/versioning.md +0 -22
  181. package/.agent/skills/app-builder/SKILL.md +0 -75
  182. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  183. package/.agent/skills/app-builder/feature-building.md +0 -53
  184. package/.agent/skills/app-builder/project-detection.md +0 -34
  185. package/.agent/skills/app-builder/scaffolding.md +0 -118
  186. package/.agent/skills/app-builder/tech-stack.md +0 -40
  187. package/.agent/skills/app-builder/templates/SKILL.md +0 -39
  188. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +0 -76
  189. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +0 -92
  190. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +0 -88
  191. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +0 -88
  192. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +0 -83
  193. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +0 -90
  194. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +0 -90
  195. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +0 -122
  196. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +0 -122
  197. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +0 -169
  198. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +0 -134
  199. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +0 -83
  200. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +0 -119
  201. package/.agent/skills/architecture/SKILL.md +0 -55
  202. package/.agent/skills/architecture/context-discovery.md +0 -43
  203. package/.agent/skills/architecture/examples.md +0 -94
  204. package/.agent/skills/architecture/pattern-selection.md +0 -68
  205. package/.agent/skills/architecture/patterns-reference.md +0 -50
  206. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  207. package/.agent/skills/clean-code/SKILL.md +0 -201
  208. package/.agent/skills/doc.md +0 -177
  209. package/.agent/skills/frontend-design/SKILL.md +0 -418
  210. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  211. package/.agent/skills/frontend-design/color-system.md +0 -311
  212. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  213. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  214. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +0 -183
  215. package/.agent/skills/frontend-design/scripts/ux_audit.py +0 -722
  216. package/.agent/skills/frontend-design/typography-system.md +0 -345
  217. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  218. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  219. package/.agent/skills/i18n-localization/SKILL.md +0 -154
  220. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +0 -241
  221. package/.agent/skills/mcp-builder/SKILL.md +0 -176
  222. package/.agent/skills/web-design-guidelines/SKILL.md +0 -57
  223. package/.agent/workflows/brainstorm.md +0 -113
  224. package/.agent/workflows/create.md +0 -59
  225. package/.agent/workflows/debug.md +0 -103
  226. package/.agent/workflows/deploy.md +0 -176
  227. package/.agent/workflows/enhance.md +0 -63
  228. package/.agent/workflows/orchestrate.md +0 -237
  229. package/.agent/workflows/plan.md +0 -89
  230. package/.agent/workflows/preview.md +0 -81
  231. package/.agent/workflows/simple-test.md +0 -42
  232. package/.agent/workflows/status.md +0 -86
  233. package/.agent/workflows/structured-orchestrate.md +0 -180
  234. package/.agent/workflows/test.md +0 -144
  235. package/.agent/workflows/ui-ux-pro-max.md +0 -296
@@ -1,292 +1,292 @@
1
- /**
2
- * 安全沙箱工具
3
- * 用于替代 new Function() 执行不可信代码
4
- * 提供安全的代码执行环境,限制对系统资源的访问
5
- */
6
-
7
- const { VM, VMScript } = require('vm2')
8
-
9
- /**
10
- * 创建安全的沙箱上下文
11
- * @param {Object} customContext - 自定义上下文变量
12
- * @param {Object} options - 配置选项
13
- * @returns {Object} 沙箱上下文
14
- */
15
- function createSandboxContext(customContext = {}, options = {}) {
16
- const {
17
- timeout = 5000, // 超时时间(毫秒)
18
- allowSync = false, // 是否允许同步执行
19
- mockConsole = true // 是否模拟 console
20
- } = options
21
-
22
- // 创建安全的 console 对象
23
- const safeConsole = mockConsole ? {
24
- log: (...args) => { /* 静默执行,阻止日志泄露 */ },
25
- error: (...args) => { /* 静默执行 */ },
26
- warn: (...args) => { /* 静默执行 */ },
27
- info: (...args) => { /* 静默执行 */ },
28
- debug: (...args) => { /* 静默执行 */ }
29
- } : console
30
-
31
- return {
32
- // 用户提供的上下文
33
- ...customContext,
34
- // 安全的 console
35
- console: safeConsole,
36
- // 安全的 Math 对象
37
- Math,
38
- // 安全的 JSON 对象
39
- JSON: {
40
- parse: JSON.parse,
41
- stringify: JSON.stringify
42
- },
43
- // 安全的 Array 对象(限制方法)
44
- Array: {
45
- isArray: Array.isArray,
46
- from: Array.from,
47
- of: Array.of
48
- },
49
- // 安全的 String 对象
50
- String: {
51
- fromCharCode: String.fromCharCode,
52
- fromCodePoint: String.fromCodePoint,
53
- raw: String.raw
54
- },
55
- // 安全的 Number 对象
56
- Number: {
57
- isNaN: Number.isNaN,
58
- isFinite: Number.isFinite,
59
- parseInt: Number.parseInt,
60
- parseFloat: Number.parseFloat
61
- },
62
- // 安全的 Boolean 对象
63
- Boolean,
64
- // 安全的 Object 对象
65
- Object: {
66
- keys: Object.keys,
67
- values: Object.values,
68
- entries: Object.entries,
69
- assign: Object.assign,
70
- create: Object.create,
71
- freeze: Object.freeze
72
- },
73
- // 安全的 Date 对象
74
- Date: {
75
- now: Date.now
76
- },
77
- // 安全的 RegExp 对象
78
- RegExp,
79
- // 安全的 Error 对象
80
- Error,
81
- // 安全的 Promise 对象
82
- Promise,
83
- // 安全的 Set 对象
84
- Set,
85
- // 安全的 Map 对象
86
- Map,
87
- // 安全的 WeakMap 对象
88
- WeakMap,
89
- // 安全的 WeakSet 对象
90
- WeakSet,
91
- // 安全的 Symbol
92
- Symbol,
93
- // 安全的 Proxy
94
- Proxy,
95
- // 安全的 Reflect
96
- Reflect
97
- }
98
- }
99
-
100
- /**
101
- * 在沙箱中执行异步代码
102
- * @param {string} code - 要执行的代码
103
- * @param {Object} context - 上下文变量
104
- * @param {Object} options - 配置选项
105
- * @returns {Promise<any>} 执行结果
106
- */
107
- async function runInSandbox(code, context = {}, options = {}) {
108
- const { timeout = 5000 } = options
109
-
110
- try {
111
- const vm = new VM({
112
- timeout,
113
- sandbox: createSandboxContext(context, options),
114
- eval: false,
115
- wasm: false
116
- })
117
-
118
- // 包装代码为异步函数
119
- const wrappedCode = `(async () => { ${code} })()`
120
- return await vm.run(wrappedCode)
121
- } catch (error) {
122
- throw new Error(`Sandbox execution error: ${error.message}`)
123
- }
124
- }
125
-
126
- /**
127
- * 在沙箱中执行表达式(同步)
128
- * @param {string} expression - 要执行的表达式
129
- * @param {Object} context - 上下文变量
130
- * @param {Object} options - 配置选项
131
- * @returns {any} 执行结果
132
- */
133
- function evaluateInSandbox(expression, context = {}, options = {}) {
134
- const { timeout = 5000 } = options
135
-
136
- try {
137
- const vm = new VM({
138
- timeout,
139
- sandbox: createSandboxContext(context, options),
140
- eval: false,
141
- wasm: false
142
- })
143
-
144
- return vm.run(expression)
145
- } catch (error) {
146
- throw new Error(`Sandbox evaluation error: ${error.message}`)
147
- }
148
- }
149
-
150
- /**
151
- * 安全执行脚本(用于工作流中的用户脚本)
152
- * @param {string} script - 脚本代码
153
- * @param {Object} context - 上下文变量
154
- * @param {Object} options - 配置选项
155
- * @returns {Promise<any>} 执行结果
156
- */
157
- async function runScriptSafely(script, context = {}, options = {}) {
158
- const { timeout = 10000 } = options
159
-
160
- try {
161
- const vm = new VM({
162
- timeout,
163
- sandbox: createSandboxContext(context, options),
164
- eval: false,
165
- wasm: false
166
- })
167
-
168
- // 将脚本包装在异步 IIFE 中
169
- const wrappedCode = `
170
- (async () => {
171
- const { input, input_data, variables, previousResult, console } = context;
172
- ${script}
173
- })()
174
- `
175
-
176
- return await vm.run(wrappedCode)
177
- } catch (error) {
178
- throw new Error(`Script execution error: ${error.message}`)
179
- }
180
- }
181
-
182
- /**
183
- * 安全执行工作流定义
184
- * @param {string} workflowCode - 工作流代码
185
- * @param {Object} engine - 工作流引擎
186
- * @param {Object} options - 配置选项
187
- * @returns {any} 执行结果
188
- */
189
- function runWorkflowSafely(workflowCode, engine, options = {}) {
190
- const { timeout = 5000 } = options
191
-
192
- try {
193
- const vm = new VM({
194
- timeout,
195
- sandbox: {
196
- engine,
197
- console: {
198
- log: () => {},
199
- error: () => {},
200
- warn: () => {},
201
- info: () => {}
202
- },
203
- Math,
204
- JSON,
205
- Promise,
206
- Array,
207
- Object,
208
- Date,
209
- RegExp,
210
- Error,
211
- Symbol,
212
- Map,
213
- Set
214
- },
215
- eval: false,
216
- wasm: false
217
- })
218
-
219
- return vm.run(`(function(engine) { return (${workflowCode}) })(engine)`)
220
- } catch (error) {
221
- throw new Error(`Workflow execution error: ${error.message}`)
222
- }
223
- }
224
-
225
- /**
226
- * 安全执行工作流加载脚本
227
- * @param {string} content - 文件内容
228
- * @param {Object} options - 配置选项
229
- * @returns {Object} module.exports
230
- */
231
- function runWorkflowFileSafely(content, options = {}) {
232
- const { timeout = 10000 } = options
233
-
234
- try {
235
- const vm = new VM({
236
- timeout,
237
- sandbox: {
238
- module: { exports: {} },
239
- exports: {},
240
- require: () => { throw new Error('require is not allowed in sandbox') },
241
- process: {
242
- env: {},
243
- cwd: () => '/'
244
- },
245
- console: {
246
- log: () => {},
247
- error: () => {},
248
- warn: () => {},
249
- info: () => {}
250
- },
251
- __dirname: '/',
252
- __filename: '/workflow.js',
253
- Math,
254
- JSON,
255
- Promise,
256
- Array,
257
- Object,
258
- Date,
259
- RegExp,
260
- Error,
261
- Symbol,
262
- Map,
263
- Set
264
- },
265
- eval: false,
266
- wasm: false
267
- })
268
-
269
- const wrappedCode = `
270
- (function(module, exports, require, process, console, __dirname, __filename) {
271
- ${content}
272
- })
273
- `
274
-
275
- const fn = vm.run(wrappedCode)
276
- const moduleObj = { exports: {} }
277
- fn(moduleObj, moduleObj.exports, () => {}, { env: {}, cwd: () => '/' }, { log: () => {}, error: () => {}, warn: () => {}, info: () => {} }, '/', '/workflow.js')
278
-
279
- return moduleObj.exports.default || moduleObj.exports
280
- } catch (error) {
281
- throw new Error(`Workflow file execution error: ${error.message}`)
282
- }
283
- }
284
-
285
- module.exports = {
286
- createSandboxContext,
287
- runInSandbox,
288
- evaluateInSandbox,
289
- runScriptSafely,
290
- runWorkflowSafely,
291
- runWorkflowFileSafely
292
- }
1
+ /**
2
+ * 安全沙箱工具
3
+ * 用于替代 new Function() 执行不可信代码
4
+ * 提供安全的代码执行环境,限制对系统资源的访问
5
+ */
6
+
7
+ const { VM, VMScript } = require('vm2')
8
+
9
+ /**
10
+ * 创建安全的沙箱上下文
11
+ * @param {Object} customContext - 自定义上下文变量
12
+ * @param {Object} options - 配置选项
13
+ * @returns {Object} 沙箱上下文
14
+ */
15
+ function createSandboxContext(customContext = {}, options = {}) {
16
+ const {
17
+ timeout = 5000, // 超时时间(毫秒)
18
+ allowSync = false, // 是否允许同步执行
19
+ mockConsole = true // 是否模拟 console
20
+ } = options
21
+
22
+ // 创建安全的 console 对象
23
+ const safeConsole = mockConsole ? {
24
+ log: (...args) => { /* 静默执行,阻止日志泄露 */ },
25
+ error: (...args) => { /* 静默执行 */ },
26
+ warn: (...args) => { /* 静默执行 */ },
27
+ info: (...args) => { /* 静默执行 */ },
28
+ debug: (...args) => { /* 静默执行 */ }
29
+ } : console
30
+
31
+ return {
32
+ // 用户提供的上下文
33
+ ...customContext,
34
+ // 安全的 console
35
+ console: safeConsole,
36
+ // 安全的 Math 对象
37
+ Math,
38
+ // 安全的 JSON 对象
39
+ JSON: {
40
+ parse: JSON.parse,
41
+ stringify: JSON.stringify
42
+ },
43
+ // 安全的 Array 对象(限制方法)
44
+ Array: {
45
+ isArray: Array.isArray,
46
+ from: Array.from,
47
+ of: Array.of
48
+ },
49
+ // 安全的 String 对象
50
+ String: {
51
+ fromCharCode: String.fromCharCode,
52
+ fromCodePoint: String.fromCodePoint,
53
+ raw: String.raw
54
+ },
55
+ // 安全的 Number 对象
56
+ Number: {
57
+ isNaN: Number.isNaN,
58
+ isFinite: Number.isFinite,
59
+ parseInt: Number.parseInt,
60
+ parseFloat: Number.parseFloat
61
+ },
62
+ // 安全的 Boolean 对象
63
+ Boolean,
64
+ // 安全的 Object 对象
65
+ Object: {
66
+ keys: Object.keys,
67
+ values: Object.values,
68
+ entries: Object.entries,
69
+ assign: Object.assign,
70
+ create: Object.create,
71
+ freeze: Object.freeze
72
+ },
73
+ // 安全的 Date 对象
74
+ Date: {
75
+ now: Date.now
76
+ },
77
+ // 安全的 RegExp 对象
78
+ RegExp,
79
+ // 安全的 Error 对象
80
+ Error,
81
+ // 安全的 Promise 对象
82
+ Promise,
83
+ // 安全的 Set 对象
84
+ Set,
85
+ // 安全的 Map 对象
86
+ Map,
87
+ // 安全的 WeakMap 对象
88
+ WeakMap,
89
+ // 安全的 WeakSet 对象
90
+ WeakSet,
91
+ // 安全的 Symbol
92
+ Symbol,
93
+ // 安全的 Proxy
94
+ Proxy,
95
+ // 安全的 Reflect
96
+ Reflect
97
+ }
98
+ }
99
+
100
+ /**
101
+ * 在沙箱中执行异步代码
102
+ * @param {string} code - 要执行的代码
103
+ * @param {Object} context - 上下文变量
104
+ * @param {Object} options - 配置选项
105
+ * @returns {Promise<any>} 执行结果
106
+ */
107
+ async function runInSandbox(code, context = {}, options = {}) {
108
+ const { timeout = 5000 } = options
109
+
110
+ try {
111
+ const vm = new VM({
112
+ timeout,
113
+ sandbox: createSandboxContext(context, options),
114
+ eval: false,
115
+ wasm: false
116
+ })
117
+
118
+ // 包装代码为异步函数
119
+ const wrappedCode = `(async () => { ${code} })()`
120
+ return await vm.run(wrappedCode)
121
+ } catch (error) {
122
+ throw new Error(`Sandbox execution error: ${error.message}`)
123
+ }
124
+ }
125
+
126
+ /**
127
+ * 在沙箱中执行表达式(同步)
128
+ * @param {string} expression - 要执行的表达式
129
+ * @param {Object} context - 上下文变量
130
+ * @param {Object} options - 配置选项
131
+ * @returns {any} 执行结果
132
+ */
133
+ function evaluateInSandbox(expression, context = {}, options = {}) {
134
+ const { timeout = 5000 } = options
135
+
136
+ try {
137
+ const vm = new VM({
138
+ timeout,
139
+ sandbox: createSandboxContext(context, options),
140
+ eval: false,
141
+ wasm: false
142
+ })
143
+
144
+ return vm.run(expression)
145
+ } catch (error) {
146
+ throw new Error(`Sandbox evaluation error: ${error.message}`)
147
+ }
148
+ }
149
+
150
+ /**
151
+ * 安全执行脚本(用于工作流中的用户脚本)
152
+ * @param {string} script - 脚本代码
153
+ * @param {Object} context - 上下文变量
154
+ * @param {Object} options - 配置选项
155
+ * @returns {Promise<any>} 执行结果
156
+ */
157
+ async function runScriptSafely(script, context = {}, options = {}) {
158
+ const { timeout = 10000 } = options
159
+
160
+ try {
161
+ const vm = new VM({
162
+ timeout,
163
+ sandbox: createSandboxContext(context, options),
164
+ eval: false,
165
+ wasm: false
166
+ })
167
+
168
+ // 将脚本包装在异步 IIFE 中
169
+ const wrappedCode = `
170
+ (async () => {
171
+ const { input, input_data, variables, previousResult, console } = context;
172
+ ${script}
173
+ })()
174
+ `
175
+
176
+ return await vm.run(wrappedCode)
177
+ } catch (error) {
178
+ throw new Error(`Script execution error: ${error.message}`)
179
+ }
180
+ }
181
+
182
+ /**
183
+ * 安全执行工作流定义
184
+ * @param {string} workflowCode - 工作流代码
185
+ * @param {Object} engine - 工作流引擎
186
+ * @param {Object} options - 配置选项
187
+ * @returns {any} 执行结果
188
+ */
189
+ function runWorkflowSafely(workflowCode, engine, options = {}) {
190
+ const { timeout = 5000 } = options
191
+
192
+ try {
193
+ const vm = new VM({
194
+ timeout,
195
+ sandbox: {
196
+ engine,
197
+ console: {
198
+ log: () => {},
199
+ error: () => {},
200
+ warn: () => {},
201
+ info: () => {}
202
+ },
203
+ Math,
204
+ JSON,
205
+ Promise,
206
+ Array,
207
+ Object,
208
+ Date,
209
+ RegExp,
210
+ Error,
211
+ Symbol,
212
+ Map,
213
+ Set
214
+ },
215
+ eval: false,
216
+ wasm: false
217
+ })
218
+
219
+ return vm.run(`(function(engine) { return (${workflowCode}) })(engine)`)
220
+ } catch (error) {
221
+ throw new Error(`Workflow execution error: ${error.message}`)
222
+ }
223
+ }
224
+
225
+ /**
226
+ * 安全执行工作流加载脚本
227
+ * @param {string} content - 文件内容
228
+ * @param {Object} options - 配置选项
229
+ * @returns {Object} module.exports
230
+ */
231
+ function runWorkflowFileSafely(content, options = {}) {
232
+ const { timeout = 10000 } = options
233
+
234
+ try {
235
+ const vm = new VM({
236
+ timeout,
237
+ sandbox: {
238
+ module: { exports: {} },
239
+ exports: {},
240
+ require: () => { throw new Error('require is not allowed in sandbox') },
241
+ process: {
242
+ env: {},
243
+ cwd: () => '/'
244
+ },
245
+ console: {
246
+ log: () => {},
247
+ error: () => {},
248
+ warn: () => {},
249
+ info: () => {}
250
+ },
251
+ __dirname: '/',
252
+ __filename: '/workflow.js',
253
+ Math,
254
+ JSON,
255
+ Promise,
256
+ Array,
257
+ Object,
258
+ Date,
259
+ RegExp,
260
+ Error,
261
+ Symbol,
262
+ Map,
263
+ Set
264
+ },
265
+ eval: false,
266
+ wasm: false
267
+ })
268
+
269
+ const wrappedCode = `
270
+ (function(module, exports, require, process, console, __dirname, __filename) {
271
+ ${content}
272
+ })
273
+ `
274
+
275
+ const fn = vm.run(wrappedCode)
276
+ const moduleObj = { exports: {} }
277
+ fn(moduleObj, moduleObj.exports, () => {}, { env: {}, cwd: () => '/' }, { log: () => {}, error: () => {}, warn: () => {}, info: () => {} }, '/', '/workflow.js')
278
+
279
+ return moduleObj.exports.default || moduleObj.exports
280
+ } catch (error) {
281
+ throw new Error(`Workflow file execution error: ${error.message}`)
282
+ }
283
+ }
284
+
285
+ module.exports = {
286
+ createSandboxContext,
287
+ runInSandbox,
288
+ evaluateInSandbox,
289
+ runScriptSafely,
290
+ runWorkflowSafely,
291
+ runWorkflowFileSafely
292
+ }