Files
Arcrun/registry/components/code/index.ts
T
Leo 60f5f10ba5 feat(code): 新增通用 code 零件(sandbox inline JS)—— Arcrun#10 設計+PoC
n8n Code node 式逃生口:config 帶 inline JS、stdin 帶 input JSON、
stdout 回 {success,data}|{success:false,error,error_type}。

沙箱=QuickJS-wasm:user JS 跑在 QuickJS context,global 只有純 ECMAScript
內建 + 唯一 curated builtin sha256(純函式);碰不到網路/檔案/env/secret/
Worker 物件圖。資源上限:timeout(interrupt)/memory/stack/output/code size。

本輪=設計+PoC,未部署 leo21c。sandbox.mjs + test/ 為 Node/vitest 可跑實作
(12 測試全綠,含 card→envelope 與原模組 planCard 逐欄全等)。index.ts 為
Worker host 骨架、DESIGN.md 記錄機制/安全性質/生產路徑/設計岔路(A/B)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJiLCRUU2o3aSpPEzVCt2o
2026-07-06 04:27:15 +00:00

48 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* arcrun `code` 零件 —— Worker host(骨架,尚未部署驗證)
*
* POST / → { code, input, limits? } → QuickJS-wasm 沙箱 → { success, data } | { success:false, error, error_type }
*
* 與其他 logic 零件的差異:
* - 其他零件 = 一顆「arcrun 自建 TinyGo→wasm」,靜態 bundle 進 Worker[[wasm_modules]]),
* 跑在 component-worker-template 的 WASI-preview1 shim 上。
* - `code` 零件 = 載入「QuickJSJS 直譯器)編成的 wasm」,把 user 的 inline JS 當「資料」
* 餵進去跑。QuickJS 的 wasm 由 quickjs-emscripten 提供(有 Cloudflare Workers 相容 variant)。
*
* ⚠️ 此檔為設計骨架。PoC 的可執行 + 受測實作在 ./sandbox.mjsNode/vitest 綠燈)。
* live 化差異見 DESIGN.md「② 生產路徑」與「curated builtinssha256)」。
*/
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { getQuickJS } from 'quickjs-emscripten';
const app = new Hono();
app.use('*', cors());
app.get('/', (c) => c.json({ ok: true, component: 'code' }));
app.post('/', async (c) => {
let body: { code?: unknown; input?: unknown; limits?: Record<string, number> };
try {
body = await c.req.json();
} catch {
return c.json({ success: false, error: 'request body must be JSON', error_type: 'ContractError' }, 400);
}
// runCode 語義與簽章同 ./sandbox.mjsPoC 已受測)。生產版把 sha256 curated builtin
// 換成「純 JS SHA-256 prelude」(無 host call、Node/Worker 皆決定性),見 DESIGN.md。
const result = await runCodeInWorker(String(body.code ?? ''), body.input, body.limits);
return c.json(result);
});
export default app;
// 生產實作(待補:把 sandbox.mjs 的 runCode 移植成 Worker 版)。
declare function runCodeInWorker(
code: string,
input: unknown,
limits?: Record<string, number>,
): Promise<unknown>;
// 保留 import 以標示相依(bundler 不 tree-shake 掉):
void getQuickJS;