@@ -1433,6 +1433,38 @@ function bareAgentProcReadPathAllowed(absPath) {
|
||||
return Boolean(p && (p === '/proc' || p.startsWith('/proc/')))
|
||||
}
|
||||
|
||||
/**
|
||||
* Kernel-runner evals guest scripts as AsyncFunction('ctx','argv', body).
|
||||
* Agent-authored code that redeclares ctx/argv or uses ESM export throws
|
||||
* "Identifier 'ctx' has already been declared" — same contract as /bin
|
||||
* utilities: define async function run(ctx, argv), never bind ctx yourself.
|
||||
* @param {string} code
|
||||
*/
|
||||
function bareAgentNormalizeGuestScript(code) {
|
||||
let src = String(code || '').replace(/^\uFEFF/, '')
|
||||
src = src.replace(/^#!.*(?:\r?\n|$)/, '')
|
||||
src = src.replace(/^\s*export\s*\{[^}]*\}\s*;?\s*$/gm, '')
|
||||
src = src.replace(/^export\s+default\s+/gm, '')
|
||||
src = src.replace(/^export\s+async\s+function\s+/gm, 'async function ')
|
||||
src = src.replace(/^export\s+function\s+/gm, 'function ')
|
||||
src = src.replace(/^export\s+const\s+/gm, 'const ')
|
||||
src = src.replace(/^export\s+let\s+/gm, 'let ')
|
||||
src = src.replace(/^export\s+var\s+/gm, 'var ')
|
||||
src = src.replace(/^(?:const|let|var)\s+ctx\b[^;\n]*;?\s*$/gm, '')
|
||||
src = src.replace(/^(?:const|let|var)\s+argv\b[^;\n]*;?\s*$/gm, '')
|
||||
src = src.replace(
|
||||
/^(?:const|let|var)\s*\{\s*ctx[\s,}][^;\n]*;?\s*$/gm,
|
||||
''
|
||||
)
|
||||
if (
|
||||
!/\b(?:async\s+)?function\s+run\s*\(/.test(src) &&
|
||||
!/\brun\s*=\s*(?:async\s*)?(?:function\s*)?\(/.test(src)
|
||||
) {
|
||||
src = 'async function run(ctx, argv) {\n' + src.trim() + '\n}\n'
|
||||
}
|
||||
return src.trim() + '\n'
|
||||
}
|
||||
|
||||
/** ~/.agent paths, config, history trim, man digest (preamble for /bin/agent). */
|
||||
|
||||
/**
|
||||
@@ -6950,7 +6982,7 @@ function bareAgentToolDefinitions() {
|
||||
function: {
|
||||
name: 'run_js_script',
|
||||
description:
|
||||
'REQUIRED to run agent-authored JavaScript: Node is not installed. Writes code to ~/.agent/_tmp_agent_run.mjs and runs it by absolute path (Bare kernel — same as /bin scripts). Do not use run_command with node/npm/npx. Prefer async function run(ctx, argv). stdout/stderr captured.',
|
||||
'Run custom guest JavaScript only. Do not use this to replace read_file, write_file, list_directory, or run_command. Node is not installed. Writes ~/.agent/_tmp_agent_run.mjs and runs it on the Bare kernel. ctx and argv are already injected — never declare them, never export. Body must be: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -9373,7 +9405,11 @@ async function bareAgentDispatchTool(o) {
|
||||
}
|
||||
|
||||
if (toolName === 'run_js_script') {
|
||||
const code = typeof args.code === 'string' ? args.code : ''
|
||||
const rawCode = typeof args.code === 'string' ? args.code : ''
|
||||
const code =
|
||||
typeof bareAgentNormalizeGuestScript === 'function'
|
||||
? bareAgentNormalizeGuestScript(rawCode)
|
||||
: rawCode
|
||||
const scriptPath = paths.dir + '/_tmp_agent_run.mjs'
|
||||
if (!vfs?.writeFile || !execLine) {
|
||||
return bareAgentJsonResult({ ok: false, error: 'vfs or execLine' })
|
||||
@@ -9387,6 +9423,17 @@ async function bareAgentDispatchTool(o) {
|
||||
/** Absolute path → kernel-runner runs .mjs like `./script.mjs` (no host `node` binary). captureExec adds stdout redirect. */
|
||||
const cmd = bareAgentShellQuote(scriptPath)
|
||||
const r = await captureExec(cmd, 60000)
|
||||
const out = r && typeof r === 'object' ? r : {}
|
||||
const text = String(out.stdout_stderr || out.error || '')
|
||||
if (/already been declared/i.test(text) || /already been declared/i.test(String(out.error || ''))) {
|
||||
return bareAgentJsonResult({
|
||||
ok: false,
|
||||
error: 'guest_script_ctx_redeclared',
|
||||
hint:
|
||||
'The kernel already injects ctx and argv. Do not write const/let/var ctx or export. Use native tools (read_file, write_file, run_command) unless you need custom JS. Script body should be only: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
|
||||
stdout_stderr: text
|
||||
})
|
||||
}
|
||||
return bareAgentJsonResult(
|
||||
r.ok === false ? r : { ok: true, stdout_stderr: r.stdout_stderr }
|
||||
)
|
||||
@@ -13380,7 +13427,7 @@ ACCESS (denylist, not allowlist). You already have full guest admin. You can cre
|
||||
- Read any absolute path, including /proc (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- Run every guest command via run_command (command_deny is empty by default). Prefer list_directory, glob_files, and file_stat over ls/find when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- Delete and move are enabled. Do not mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins.
|
||||
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Do not use run_js_script to read files, write files, or run shell — call read_file, write_file, run_command instead. Only use run_js_script for custom guest JS. The kernel already injects ctx and argv: never write const/let/var ctx, never export. Body must be only async function run(ctx, argv) { const vfs = ctx.vfs; ... }. Do not import Node builtins. Never paste a "final correct script" into the user reply — call the tool.
|
||||
- Live kernel: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are documentation only — never infer what is enabled from them.
|
||||
- web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ For the **full** list and semantics, open **`developer-guide/02-the-context-obje
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string[]} argv
|
||||
*/
|
||||
export async function run(ctx, argv) {
|
||||
async function run(ctx, argv) {
|
||||
const argv0 = argv[0] || 'script'
|
||||
const vfs = ctx.vfs
|
||||
if (!vfs?.readFile) {
|
||||
|
||||
Reference in New Issue
Block a user