@opencoredev/sandbox-sdk 0.2.0 → 1.0.0-beta.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.
- package/CHANGELOG.md +32 -11
- package/README.md +350 -25
- package/dist/ai.d.ts +5 -0
- package/dist/ai.js +1 -0
- package/dist/chunk-59t3rqja.js +2 -0
- package/dist/chunk-cwx6cc31.js +2 -0
- package/dist/chunk-exv1kf89.js +60 -0
- package/dist/chunk-gc8zdxyb.js +2 -0
- package/dist/chunk-hjzhc3qg.js +40 -0
- package/dist/chunk-md6fmprc.js +1 -0
- package/dist/chunk-t5vr9nd8.js +8 -0
- package/dist/chunk-v6y7eqxw.js +27 -0
- package/dist/chunk-yed8mvs7.js +2 -0
- package/dist/chunk-yrsb6hws.js +5 -0
- package/dist/chunk-z9rjzn28.js +2 -0
- package/dist/errors.d.ts +60 -0
- package/dist/files.d.ts +57 -0
- package/dist/git.d.ts +28 -0
- package/dist/handle.d.ts +4 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1 -0
- package/dist/keys.d.ts +5 -0
- package/dist/logs.d.ts +8 -0
- package/dist/mastra.d.ts +43 -0
- package/dist/mastra.js +1 -0
- package/dist/memory.d.ts +34 -0
- package/dist/memory.js +11 -0
- package/dist/openai.d.ts +39 -0
- package/dist/openai.js +1 -0
- package/dist/peer.d.ts +5 -0
- package/dist/processes.d.ts +71 -0
- package/dist/provider.d.ts +138 -0
- package/dist/provider.js +0 -0
- package/dist/providers/agentos/errors.d.ts +4 -0
- package/dist/providers/agentos/index.d.ts +11 -0
- package/dist/providers/agentos/index.js +2 -0
- package/dist/providers/boat/index.d.ts +23 -0
- package/dist/providers/boat/index.js +1 -0
- package/dist/providers/boat-api/errors.d.ts +6 -0
- package/dist/providers/boat-api/exec.d.ts +11 -0
- package/dist/providers/boat-api/index.d.ts +22 -0
- package/dist/providers/boxd/errors.d.ts +3 -0
- package/dist/providers/boxd/execute.d.ts +3 -0
- package/dist/providers/boxd/guest.d.ts +14 -0
- package/dist/providers/boxd/index.d.ts +23 -0
- package/dist/providers/boxd/index.js +85 -0
- package/dist/providers/boxd/transfers.d.ts +19 -0
- package/dist/providers/daytona/buffered.d.ts +3 -0
- package/dist/providers/daytona/errors.d.ts +3 -0
- package/dist/providers/daytona/exec.d.ts +14 -0
- package/dist/providers/daytona/index.d.ts +24 -0
- package/dist/providers/daytona/index.js +88 -0
- package/dist/providers/e2b/errors.d.ts +3 -0
- package/dist/providers/e2b/index.d.ts +15 -0
- package/dist/providers/e2b/index.js +1 -0
- package/dist/providers/freestyle/deadline.d.ts +4 -0
- package/dist/providers/freestyle/errors.d.ts +16 -0
- package/dist/providers/freestyle/execute.d.ts +12 -0
- package/dist/providers/freestyle/index.d.ts +14 -0
- package/dist/providers/freestyle/index.js +133 -0
- package/dist/providers/freestyle/wire.d.ts +10 -0
- package/dist/providers/local/docker.d.ts +32 -0
- package/dist/providers/local/index.d.ts +17 -0
- package/dist/providers/local/index.js +2 -0
- package/dist/providers/railway/errors.d.ts +4 -0
- package/dist/providers/railway/index.d.ts +24 -0
- package/dist/providers/railway/index.js +1 -0
- package/dist/providers/sandboxer/index.d.ts +33 -0
- package/dist/providers/sandboxer/index.js +1 -0
- package/dist/providers/superserve/bootstrap.d.ts +11 -0
- package/dist/providers/superserve/errors.d.ts +3 -0
- package/dist/providers/superserve/execute.d.ts +13 -0
- package/dist/providers/superserve/index.d.ts +23 -0
- package/dist/providers/superserve/index.js +126 -0
- package/dist/providers/tenki/deadline.d.ts +2 -0
- package/dist/providers/tenki/errors.d.ts +10 -0
- package/dist/providers/tenki/exec.d.ts +4 -0
- package/dist/providers/tenki/files.d.ts +3 -0
- package/dist/providers/tenki/index.d.ts +28 -0
- package/dist/providers/tenki/index.js +172 -0
- package/dist/providers/tenki/ready.d.ts +7 -0
- package/dist/providers/tenki/stream.d.ts +3 -0
- package/dist/providers/upstash/buffered.d.ts +3 -0
- package/dist/providers/upstash/errors.d.ts +3 -0
- package/dist/providers/upstash/exec.d.ts +18 -0
- package/dist/providers/upstash/files.d.ts +15 -0
- package/dist/providers/upstash/index.d.ts +38 -0
- package/dist/providers/upstash/index.js +111 -0
- package/dist/providers/vercel/errors.d.ts +3 -0
- package/dist/providers/vercel/index.d.ts +14 -0
- package/dist/providers/vercel/index.js +1 -0
- package/dist/providers/vercel/provider.d.ts +10 -0
- package/dist/providers/vercel/transport.d.ts +40 -0
- package/dist/run.d.ts +41 -0
- package/dist/testing.d.ts +17 -0
- package/dist/testing.js +6 -0
- package/dist/tool-security.d.ts +9 -0
- package/dist/tools.d.ts +117 -0
- package/dist/tools.js +1 -0
- package/dist/types.d.ts +189 -0
- package/package.json +164 -106
- package/dist/agentos-CbrZW7R0.mjs +0 -390
- package/dist/agentos-CbrZW7R0.mjs.map +0 -1
- package/dist/ai/harness.d.mts +0 -16
- package/dist/ai/harness.mjs +0 -69
- package/dist/ai/harness.mjs.map +0 -1
- package/dist/ai/index.d.mts +0 -54
- package/dist/ai/index.mjs +0 -4
- package/dist/ai-DeFa8yPk.mjs +0 -243
- package/dist/ai-DeFa8yPk.mjs.map +0 -1
- package/dist/capabilities-BWvOVFbH.d.mts +0 -15
- package/dist/capabilities-CaSNd6J1.mjs +0 -125
- package/dist/capabilities-CaSNd6J1.mjs.map +0 -1
- package/dist/capabilities-xs9kaHrK.mjs +0 -28
- package/dist/capabilities-xs9kaHrK.mjs.map +0 -1
- package/dist/errors-BuF9bYOQ.mjs +0 -68
- package/dist/errors-BuF9bYOQ.mjs.map +0 -1
- package/dist/eve/index.d.mts +0 -19
- package/dist/eve/index.mjs +0 -155
- package/dist/eve/index.mjs.map +0 -1
- package/dist/index-CkTwqD0X.d.mts +0 -25
- package/dist/index-Dh9xob2s.d.mts +0 -31
- package/dist/index.d.mts +0 -5
- package/dist/index.mjs +0 -40
- package/dist/index.mjs.map +0 -1
- package/dist/managed-provider-BsZGVQ4I.mjs +0 -148
- package/dist/managed-provider-BsZGVQ4I.mjs.map +0 -1
- package/dist/mastra/index.d.mts +0 -118
- package/dist/mastra/index.mjs +0 -662
- package/dist/mastra/index.mjs.map +0 -1
- package/dist/metadata.d.mts +0 -34
- package/dist/metadata.mjs +0 -135
- package/dist/metadata.mjs.map +0 -1
- package/dist/provider-DOBErkBO.d.mts +0 -91
- package/dist/provider-utils-CfB9nvJx.mjs +0 -57
- package/dist/provider-utils-CfB9nvJx.mjs.map +0 -1
- package/dist/providers/agentos/index.d.mts +0 -7
- package/dist/providers/agentos/index.mjs +0 -9
- package/dist/providers/box/index.d.mts +0 -34
- package/dist/providers/box/index.mjs +0 -348
- package/dist/providers/box/index.mjs.map +0 -1
- package/dist/providers/daytona/index.d.mts +0 -21
- package/dist/providers/daytona/index.mjs +0 -206
- package/dist/providers/daytona/index.mjs.map +0 -1
- package/dist/providers/e2b/index.d.mts +0 -17
- package/dist/providers/e2b/index.mjs +0 -169
- package/dist/providers/e2b/index.mjs.map +0 -1
- package/dist/providers/local/index.d.mts +0 -22
- package/dist/providers/local/index.mjs +0 -22
- package/dist/providers/local/index.mjs.map +0 -1
- package/dist/providers/railway/index.d.mts +0 -29
- package/dist/providers/railway/index.mjs +0 -211
- package/dist/providers/railway/index.mjs.map +0 -1
- package/dist/providers/upstash/index.d.mts +0 -17
- package/dist/providers/upstash/index.mjs +0 -211
- package/dist/providers/upstash/index.mjs.map +0 -1
- package/dist/providers/vercel/index.d.mts +0 -28
- package/dist/providers/vercel/index.mjs +0 -186
- package/dist/providers/vercel/index.mjs.map +0 -1
- package/dist/sandbox-DdEqoXJF.d.mts +0 -26
- package/dist/sandbox-DgtY5hvt.mjs +0 -112
- package/dist/sandbox-DgtY5hvt.mjs.map +0 -1
- package/dist/testing/index.d.mts +0 -27
- package/dist/testing/index.mjs +0 -173
- package/dist/testing/index.mjs.map +0 -1
- package/dist/types-Bv6I2U1c.d.mts +0 -103
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import{s,i,t,b,f,I}from"./chunk-t5vr9nd8.js";import{v}from"./chunk-59t3rqja.js";import{C}from"./chunk-cwx6cc31.js";import{e,r}from"./chunk-gc8zdxyb.js";import{posix as V,resolve as W,relative as he}from"node:path";import{tmpdir as le}from"node:os";import{execFile as ye}from"node:child_process";import{promisify as $e}from"node:util";import{promises as X}from"node:fs";function ue(d,m){let g=m.split(/(\*\*\/|\*\*|\*|\?)/).map((M)=>M==="**/"?"(?:.*/)?":M==="**"?".*":M==="*"?"[^/]*":M==="?"?".":M.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")).join("");return new RegExp(`^${g}$`).test(d)||!m.includes("/")&&new RegExp(`^${g}$`).test(V.basename(d))}function ce(d,m,g,M=()=>{}){let h=d.files,S=new Set,T=$e(ye);async function N(o){if((await d.exec(m,{command:o,cwd:"/workspace",env:s,timeoutMs:120000,onChunk(){}})).exitCode!==0)throw new e("File transfer failed. The remote archive command failed. Ensure tar is installed and paths are accessible.",{code:"provider"})}let A=async(o)=>{try{return M(),await o()}catch(n){throw g.error(n,d.name,m)}};async function B(o=".",n={}){let p=i(o),y=[];async function c(a){for(let w of await h.list(m,a)){if(!n.glob||ue(V.relative(p,w.path),n.glob))y.push(w);if(n.recursive&&w.type==="directory")await c(w.path)}}return await c(p),y}async function F(o,n){let p=await A(()=>h.read(m,i(o)));return n?.as==="bytes"?p:new TextDecoder().decode(p)}async function D(o,n){let p=typeof o==="string"?[[o,n??""]]:Object.entries(o),y=new Set;await A(async()=>{for(let[c,a]of p){let w=i(c),u=V.dirname(w);if(!h.writeCreatesParents&&!y.has(u))await h.mkdir(m,u),y.add(u);await h.write(m,w,typeof a==="string"?new TextEncoder().encode(a):a)}})}let U="/tmp/.sandbox-sdk/changes.git";async function J(o,n){let p="";if((await d.exec(m,{command:`git --git-dir=${t(U)} --work-tree=/workspace ${o}`,cwd:"/workspace",env:{...s,GIT_INDEX_FILE:`${U}/sdk.index`},stdin:n,timeoutMs:120000,onChunk(c){if(c.stream==="stdout")p+=c.text}})).exitCode!==0)throw new e("File checkpoint failed. Git could not update the hidden index. Ensure git is installed and /workspace is readable.",{code:"provider"});return p}async function Y(o){let n=["-name .git",...(h.internal??[]).map((a)=>`-path ${t(`./${V.relative("/workspace",i(a))}`)}`)].join(" -o "),p=`command -v git >/dev/null 2>&1 || exit 69
|
|
2
|
+
command -v find >/dev/null 2>&1 || exit 78
|
|
3
|
+
g=${t(U)}
|
|
4
|
+
# A fresh index per call: a killed attempt leaves no index.lock to block later checkpoints.
|
|
5
|
+
export GIT_INDEX_FILE="$g/tree.$$.index"; paths="$g/tree.$$.paths"; trap 'rm -f "$GIT_INDEX_FILE" "$GIT_INDEX_FILE.lock" "$paths"' EXIT
|
|
6
|
+
[ -d "$g" ] || git init -q --bare "$g" >/dev/null || exit 69
|
|
7
|
+
cd /workspace && find . \\( ${n} \\) -prune -o ! -type d -print0 > "$paths" || exit 1
|
|
8
|
+
git --git-dir="$g" --work-tree=/workspace read-tree --empty || exit 1
|
|
9
|
+
git --git-dir="$g" --work-tree=/workspace update-index --add --remove -z --stdin < "$paths" || exit 1
|
|
10
|
+
tree=$(git --git-dir="$g" --work-tree=/workspace write-tree) || exit 1
|
|
11
|
+
${o?`mkdir -p ${t(V.dirname(o))} && printf '%s' "$tree" > ${t(o)} || exit 1
|
|
12
|
+
`:""}printf '%s\\n' "$tree"`,y="",c=await d.exec(m,{command:p,cwd:"/workspace",env:s,timeoutMs:120000,onChunk(a){if(a.stream==="stdout")y+=a.text}});if(c.exitCode===78){let a=await ne();if(o)await D(o,a);return a}if(c.exitCode===69)throw new e("File checkpoint failed. Git is unavailable. Install git in the sandbox image.",{code:"unsupported"});if(c.exitCode!==0)throw new e("File checkpoint failed. Git could not update the hidden index. Ensure git is installed and /workspace is readable.",{code:"provider"});return y.trim()}async function ne(){if(!await ee(U)){if((await d.exec(m,{command:`git init --bare ${t(U)}`,cwd:"/workspace",env:s,timeoutMs:1e4,onChunk(){}})).exitCode!==0)throw new e("File checkpoint failed. Git is unavailable. Install git in the sandbox image.",{code:"unsupported"})}let o=[],n=new Set((h.internal??[]).map((y)=>i(y)));async function p(y){for(let c of await h.list(m,y)){if(V.basename(c.path)===".git"||n.has(c.path))continue;if(c.type==="directory")await p(c.path);else o.push(V.relative("/workspace",c.path))}}if(await p("/workspace"),await J("read-tree --empty"),o.length)await J("update-index --add --remove -z --stdin",o.join("\x00")+"\x00");return(await J("write-tree")).trim()}async function ee(o){try{return await h.stat(m,o),!0}catch(n){if(n instanceof e&&["file_not_found","not_found"].includes(n.code))return!1;throw n}}async function k(){let o={};for(let n of await B(".",{recursive:!0}))if(n.type==="file")o[n.path]=Buffer.from(await h.read(m,n.path)).toString("base64");return o}let P=(o)=>`/tmp/.sandbox-sdk/marks/${encodeURIComponent(o)}.json`;async function x(o){let n=JSON.parse(new TextDecoder().decode(await h.read(m,P(o))));if(!n||typeof n!=="object"||Array.isArray(n))r("Invalid file checkpoint");let p={};for(let[y,c]of Object.entries(n)){if(typeof c!=="string")r("Invalid file checkpoint content");p[y]=c}return p}async function l(o,n){try{return await n()}catch(p){if((o??"start")==="start"&&!await ee(P("start")).catch(()=>!0))throw new e("No start checkpoint. createSandbox records one only with trackChanges: true. Pass trackChanges: true or call files.mark() and changes({ since }).",{code:"invalid_argument"});throw p}}let z=(o)=>l(o,()=>F(P(o??"start")));return{[Symbol.dispose](){for(let o of S)o()},read:F,write:D,list:(o,n)=>A(()=>B(o,n)),stat:(o)=>A(()=>h.stat(m,i(o))),exists:(o)=>A(async()=>{try{return await h.stat(m,i(o)),!0}catch(n){if(n instanceof e&&["file_not_found","not_found"].includes(n.code))return!1;throw n}}),remove:(o,n)=>A(()=>h.remove(m,i(o),{recursive:n?.recursive??!1})),edit:(o,{find:n,replace:p})=>A(async()=>{if(!n)r("find cannot be empty");let y=await F(o),c=[],a=y.indexOf(n);while(a!==-1)c.push(y.slice(0,a).split(`
|
|
13
|
+
`).length),a=y.indexOf(n,a+1);if(c.length!==1)throw new e(`Edit failed at ${o}. ${c.length?`Matches on lines ${c.join(", ")}`:"Text not found"}. Supply a unique exact match.`,{code:c.length?"edit_not_unique":"edit_not_found"});await D(o,y.replace(n,()=>p))}),upload:(o,n,p)=>A(async()=>{let y=W(o);if(d.name!=="memory"&&h.transfer!=="files"&&(await X.lstat(y)).isDirectory()){let a=await X.mkdtemp(W(le(),"sandbox-sdk-upload-")),w=`/tmp/.sandbox-sdk/upload-${crypto.randomUUID()}.tar`;try{let u=W(a,"files.tar");await T("tar",["-cf",u,"-C",y,...(p?.ignore??[]).flatMap((O)=>["--exclude",O]),"."],{timeout:120000}),await D(w,new Uint8Array(await X.readFile(u))),await h.mkdir(m,i(n)),await N(`tar -xf ${t(w)} -C ${t(i(n))} --no-same-owner`)}finally{await X.rm(a,{recursive:!0,force:!0}),await h.remove(m,w,{recursive:!1}).catch(()=>{})}return}async function c(a,w){let u=await X.lstat(a);if(u.isSymbolicLink())r("Uploading symlinks is unsupported");if(u.isDirectory()){await h.mkdir(m,i(w));for(let O of await X.readdir(a))if(!p?.ignore?.some((R)=>ue(he(y,W(a,O)),R)||R===O))await c(W(a,O),V.join(w,O))}else await D(w,new Uint8Array(await X.readFile(a)))}await c(y,n)}),download:(o,n)=>A(async()=>{if(d.name!=="memory"&&h.transfer!=="files"&&(await h.stat(m,i(o))).type==="directory"){let y=await X.mkdtemp(W(le(),"sandbox-sdk-download-")),c=`/tmp/.sandbox-sdk/download-${crypto.randomUUID()}.tar`;try{await N(`tar -cf ${t(c)} -C ${t(i(o))} .`);let a=W(y,"files.tar");await X.writeFile(a,await h.read(m,c)),await X.mkdir(W(n),{recursive:!0}),await T("tar",["-xf",a,"-C",W(n),"--no-same-owner","--no-same-permissions"],{timeout:120000})}finally{await X.rm(y,{recursive:!0,force:!0}),await h.remove(m,c,{recursive:!1}).catch(()=>{})}return}async function p(y,c){let a=await h.stat(m,y);if(a.type==="symlink")r("Downloading symlinks is unsupported");if(a.type==="directory"){await X.mkdir(c,{recursive:!0});for(let w of await h.list(m,y))await p(w.path,W(c,V.basename(w.path)))}else await X.mkdir(W(c,".."),{recursive:!0}),await X.writeFile(c,await h.read(m,y))}await p(i(o),W(n))}),search:(o,n={})=>A(async()=>{let p=[],y=n.maxMatches??200;if(!Number.isSafeInteger(y)||y<1)r("maxMatches must be positive");for(let c of await B(n.path,{recursive:!0,glob:n.glob}))if(c.type==="file"){let a=(await F(c.path)).split(`
|
|
14
|
+
`);for(let[w,u]of a.entries())if(u.includes(o)){if(p.push({path:c.path,line:w+1,text:g.text(u)}),p.length>=y)return p}}return p}),watch(o,n,p={}){M();let y=!1,c,a,w=async()=>{try{let O=new Map((await B(o,p)).map((R)=>[R.path,`${R.size}:${R.modifiedAt}`]));if(c){for(let[R,_]of O)if(!c.has(R)||c.get(R)!==_){if(!y)n({type:c.has(R)?"modified":"added",path:R})}for(let R of c.keys())if(!O.has(R)&&!y)n({type:"removed",path:R})}c=O}catch(O){p.onError?.(g.error(O,d.name,m))}if(!y)a=setTimeout(()=>void w(),p.intervalMs??250),a.unref?.()},u=()=>{y=!0,clearTimeout(a),S.delete(u)};return S.add(u),w(),u},mark:(o=`mark-${Date.now()}-${Math.random().toString(36).slice(2)}`)=>A(async()=>{if(d.name==="memory")await D(P(o),JSON.stringify(await k()));else await Y(P(o));return o}),changes:(o={})=>A(async()=>{if(d.name!=="memory"){let u=(await z(o.since)).trim(),O=await Y();if(!/^[0-9a-f]{40,64}$/.test(u))r("Invalid git checkpoint");let R=(await J(`diff --no-renames --name-status -z ${u} ${O}`)).split("\x00"),_={added:[],modified:[],removed:[],patch:g.text(await J(`diff --no-ext-diff --binary ${u} ${O}`))};for(let j=0;j+1<R.length;j+=2){let E=R[j],G=R[j+1];if(G)(E==="A"?_.added:E==="D"?_.removed:_.modified).push(i(G))}return _}let n=await l(o.since,()=>x(o.since??"start")),p=await k(),y=Object.keys(p).filter((u)=>!(u in n)),c=Object.keys(n).filter((u)=>!(u in p)),a=Object.keys(p).filter((u)=>(u in n)&&n[u]!==p[u]),w=[...y,...a,...c].map((u)=>{let O=Buffer.from(n[u]??"","base64").toString(),R=Buffer.from(p[u]??"","base64").toString(),_=O?O.replace(/\n$/,"").split(`
|
|
15
|
+
`):[],j=R?R.replace(/\n$/,"").split(`
|
|
16
|
+
`):[];return`--- ${u in n?"a/"+V.relative("/workspace",u):"/dev/null"}
|
|
17
|
+
+++ ${u in p?"b/"+V.relative("/workspace",u):"/dev/null"}
|
|
18
|
+
@@ -${_.length?1:0},${_.length} +${j.length?1:0},${j.length} @@
|
|
19
|
+
${_.map((E)=>"-"+E+`
|
|
20
|
+
`).join("")}${_.length&&!O.endsWith(`
|
|
21
|
+
`)?`\
|
|
22
|
+
`:""}${j.map((E)=>"+"+E+`
|
|
23
|
+
`).join("")}${j.length&&!R.endsWith(`
|
|
24
|
+
`)?`\
|
|
25
|
+
`:""}`}).join("");return{added:y,modified:a,removed:c,patch:g.text(w)}})}}function fe(d,m,g){async function M(h,S,T){if(!S)return await d(`git ${h}`,{cwd:T});g.add([S]);let N=`/tmp/.sandbox-sdk/credential-${crypto.randomUUID()}`,A=`#!/bin/sh
|
|
26
|
+
if [ "$1" = get ]; then printf 'username=x-access-token\\npassword='; cat ${t(N+".token")}; printf '\\n'; fi
|
|
27
|
+
`;await d(`umask 077; mkdir -p /tmp/.sandbox-sdk; cat > ${t(N+".token")}; printf '%s' ${t(A)} > ${t(N)}`,{stdin:S});try{return await d(`git -c credential.helper= -c ${t(`credential.helper=!sh ${t(N)}`)} ${h}`,{cwd:T})}finally{await Promise.all([m.remove(N).catch(()=>{}),m.remove(N+".token").catch(()=>{})])}}return{clone:(h,S={})=>M(`clone ${S.branch?`--branch ${t(S.branch)} `:""}${S.depth?`--depth ${t(S.depth)} `:""}-- ${t(h)} ${t(S.dir??"app")}`,S.token),status:(h)=>Promise.resolve(d("git status --porcelain",{cwd:h})),diff:(h)=>Promise.resolve(d("git diff",{cwd:h})),commit:async(h,S)=>{if(S.all)await d("git add -A",{cwd:h});return await d(`git commit -m ${t(S.message)}${S.author?` --author=${t(S.author)}`:""}`,{cwd:h})},push:(h,S={})=>M(`push -- ${t(S.remote??"origin")}${S.branch?` ${t(S.branch)}`:""}`,S.token,h),checkout:(h,S)=>Promise.resolve(d(`git checkout ${S.create?"-b ":""}${t(S.branch)}`,{cwd:h}))}}function me(d){let m=[],g=d.stream==="stdout"?"O":"E",M=d.text.split(`
|
|
28
|
+
`);for(let h=0;h<M.length;h++){let S=M[h]??"",T=h<M.length-1;for(let N=0;N<S.length;){let A=Math.min(S.length,N+8192),B=S.charCodeAt(A-1);if(A<S.length&&B>=55296&&B<=56319)A--;m.push((T&&A===S.length?g:g.toLowerCase())+S.slice(N,A)+`
|
|
29
|
+
`),N=A}if(!S&&T)m.push(g+`
|
|
30
|
+
`)}return m}function pe(d,m,g,M){let h=Buffer.from(d.buffer,d.byteOffset,d.byteLength),S=[],T=Math.min(m,h.length),N=0;while(T<h.length&&N<g){let A=T===0?0:h.lastIndexOf(10,T-1)+1,B=h[A];if(T===A)T++;let F=h.indexOf(10,T);if(F<0)break;let D=Math.min(F,T+g-N),U=(Y)=>((h[Y]??0)&192)===128;while(D>T&&D<F&&U(D))D--;if(D===T&&T<F){if(N)break;D++;while(D<F&&U(D))D++}let J=h.subarray(T,D).toString();if(N+=D-T,T=D,T===F&&(B===79||B===69)&&N<g)J+=`
|
|
31
|
+
`,N++,T++;else if(T===F&&B!==79&&B!==69)T++;S.push({stream:B===69||B===101?"stderr":"stdout",text:J,cursor:String(M+T)})}return{events:S,offset:T}}function be(d){let m=2166136261;for(let M=0;M<d.length;M++)m=Math.imul(m^d.charCodeAt(M),16777619)>>>0;return`${(d.trim().split(/\s+/)[0]??"").split("/").pop()?.replace(/[^a-zA-Z0-9_-]/g,"").slice(0,48)||"process"}-${m.toString(16).padStart(8,"0")}`}function ge(d){let m={stdout:"",stderr:""};if(d===void 0||/^\d+$/.test(d))return{offset:d,pending:m};if(Buffer.byteLength(d)>1048576)r("Invalid line cursor");let g;try{g=JSON.parse(d)}catch{r("Invalid line cursor")}if(!g||typeof g!=="object"||!("v"in g)||g.v!==1||!("offset"in g)||typeof g.offset!=="string"||!/^\d+$/.test(g.offset)||!Number.isSafeInteger(Number(g.offset))||!("stdout"in g)||typeof g.stdout!=="string"||!("stderr"in g)||typeof g.stderr!=="string"||Buffer.byteLength(g.stdout)>65536||Buffer.byteLength(g.stderr)>65536)r("Invalid line cursor");return{offset:g.offset,pending:{stdout:g.stdout,stderr:g.stderr}}}var oe=(d)=>new Promise((m)=>setTimeout(m,d));function we(d,m,g,M,h){let S=d.processRecordRoot??"/tmp/.sandbox-sdk/procs",T=new Map,N=new Map,A=async(k)=>{try{return await k()}catch(P){throw M.error(P,d.name,m)}},B=(k)=>{if(!/^[a-zA-Z0-9_-]{1,128}$/.test(k))r("Process name must contain 1–128 letters, numbers, hyphens or underscores");return`${S}/${k}`},F=(k,P={},x)=>d.exec(m,{command:k,stdin:x,cwd:"/workspace",env:{...h,...P,...s},timeoutMs:1e4,onChunk(){}});async function D(k){try{return Number(await g.read(`${k}/exit`))}catch(P){if(P instanceof e&&(["file_not_found","not_found"].includes(P.code)||P.code==="provider"&&!await g.exists(`${k}/exit`)))return null;throw P}}async function U(k){let P=B(k),[x,l,z]=await Promise.all([g.read(`${P}/spec.json`),D(P),g.read(`${P}/pid`)]),o=JSON.parse(x);if(!o||typeof o!=="object"||!("command"in o)||typeof o.command!=="string"||!("startedAt"in o)||typeof o.startedAt!=="number")r("Invalid process record");return{name:k,command:M.text(o.command),status:l===null?"running":l===0?"exited":"failed",pid:Number(z),ports:"port"in o&&typeof o.port==="number"?[o.port]:[],startedAt:o.startedAt,exitCode:l}}async function J(k,P={}){if(!Number.isInteger(k)||k<1||k>65535)r("Port must be between 1 and 65535");let x=await d.previewUrl(m,k);if(P.path)x.url=new URL(P.path,x.url).toString();if(P.waitMs!==void 0){let l=Date.now()+P.waitMs;do{try{let z=x.url,o=new URL(z).origin,n=new Headers(x.headers),p=new Map,y=(c)=>{let a=c.split(";")[0]?.trim()??"",w=a.indexOf("=");if(w>0)p.set(a.slice(0,w),a)};for(let c of(n.get("cookie")??"").split(";"))y(c);for(let c=0;c<5;c++){let a=await fetch(z,{headers:n,redirect:"manual",signal:AbortSignal.timeout(Math.max(1,Math.min(1000,l-Date.now())))});if(await a.body?.cancel(),a.ok)return x;let w=a.headers.get("location");if(![301,302,303,307,308].includes(a.status)||!w)break;let u=new URL(w,z);if(u.origin!==o)break;for(let O of a.headers.getSetCookie())y(O);if(p.size)n.set("cookie",[...p.values()].join("; "));if(z=u.toString(),Date.now()>=l)break}}catch{}if(Date.now()>=l)break;await oe(Math.min(50,Math.max(1,l-Date.now())))}while(Date.now()<=l);throw new e(`Preview failed. Port ${k} did not answer. Check the process and its logs.`,{code:"port_not_ready"})}return x}function Y(k){let P=B(k),x=N.get(k);if(x)return x;let l="starting",z,o=!1,n;async function p(c={}){let a=ge(c.after).offset,w=a===void 0?void 0:Number(a),u=c.maxBytes??16384;if(w!==void 0&&(!Number.isSafeInteger(w)||w<0)||!Number.isSafeInteger(u)||u<1||u>1048576)r("Invalid log cursor or maxBytes");let O=Math.min(u,65536),R=32770,_,j,E,G;if(d.name==="memory"&&d.files.readRange)l=(await U(k)).status,_=Number(await g.read(`${P}/base`)),E=(await g.stat(`${P}/out.log`)).size,j=Math.max(0,(w??_)-_-R),G=await d.files.readRange(m,`${P}/out.log`,{offset:j,length:O+R*2});else{let q="",H=await d.exec(m,{command:`[ -f ${t(`${P}/spec.json`)} ] || exit 66; cat ${t(`${P}/spec.json`)} || exit 1; printf '\\000'; while ! mkdir ${t(`${P}/lock`)} 2>/dev/null; do sleep .01; done; trap 'rmdir ${t(`${P}/lock`)}' EXIT; b=$(cat ${t(`${P}/base`)}); n=$(wc -c < ${t(`${P}/out.log`)}); a=${w??'"$b"'}; s=$((a-b-${R})); [ "$s" -ge 0 ] || s=0; e=running; if [ -f ${t(`${P}/exit`)} ]; then e=$(cat ${t(`${P}/exit`)}); fi; printf '%s %s %s %s\\n' "$b" "$s" "$n" "$e"; dd if=${t(`${P}/out.log`)} bs=1 skip="$s" count=${O+R*2} 2>/dev/null | base64`,cwd:"/workspace",env:{...h,...s},timeoutMs:1e4,onChunk(ae){if(ae.stream==="stdout"){q+=ae.text;let de=q.indexOf("\x00");if(de>=0&&Buffer.byteLength(q.slice(de+1))>262144)r("Oversized log page")}}});if(H.exitCode===66)throw new e("Process record not found. This process has not been started. Check the process name.",{code:"file_not_found"});if(H.timedOut||H.exitCode!==0)throw new e("Log range read failed. Retry the log request.",{code:"provider"});let te=q.indexOf("\x00");if(te<0)r("Invalid process record");let K=JSON.parse(q.slice(0,te));if(!K||typeof K!=="object"||!("command"in K)||typeof K.command!=="string"||!("startedAt"in K)||typeof K.startedAt!=="number")r("Invalid process record");let ie=q.indexOf(`
|
|
32
|
+
`,te+1),Q=q.slice(te+1,ie).split(" ");_=Number(Q[0]),j=Number(Q[1]),E=Number(Q[2]);let se=Q[3];if(se!=="running"&&(se===void 0||!Number.isInteger(Number(se))))r("Invalid remote process status");if(l=se==="running"?"running":Number(se)===0?"exited":"failed",ie<0||![_,j,E].every((ae)=>Number.isSafeInteger(ae)&&ae>=0))r("Invalid remote log page");G=Buffer.from(q.slice(ie+1),"base64")}let L=Math.max(_,w??_),Z=pe(G,Math.max(0,L-_-j),O,_+j),re=_+j+Z.offset;return{events:Z.events.map((q)=>({...q,text:M.text(q.text)})),nextCursor:String(re),truncated:(w??_)<_||re<_+E}}let y={name:k,get status(){return l},get url(){return z},get ready(){return o},logs:(c={})=>A(async()=>{let a=await p(c);return{text:M.text(a.events.map((w)=>w.text).join("")),nextCursor:a.nextCursor,truncated:a.truncated}}),async*lines(c={}){let a=ge(c.after),{offset:w,pending:u}=a,O=(R)=>JSON.stringify({v:1,offset:R,...u});do{let R=await A(()=>p({after:w,maxBytes:1048576}));w=R.nextCursor;for(let _ of R.events){if(u[_.stream]+=_.text,Buffer.byteLength(u[_.stream])>65536){let j=Buffer.from(u[_.stream]).subarray(-65510),E=0;while(((j[E]??0)&192)===128)E++;u[_.stream]="[line truncated]"+j.subarray(E).toString()}if(u[_.stream].endsWith(`
|
|
33
|
+
`)){let j=u[_.stream].slice(0,-1);u[_.stream]="",yield{text:j,stream:_.stream,cursor:O(_.cursor)}}}if(!R.truncated&&l!=="running"&&l!=="starting"){for(let _ of["stdout","stderr"])if(u[_]){let j=u[_];u[_]="",yield{text:j,stream:_,cursor:O(w)}}break}if(!R.truncated)await oe(25)}while(!0)},stop:(c={})=>A(async()=>{let a=await U(k);if(l=a.status,a.exitCode!==null)return;let w=T.get(k);if(w)await w.stop({graceMs:c.graceMs??1000});else await F(`kill -TERM -${a.pid} 2>/dev/null || true`),await oe(c.graceMs??1000),await F(`kill -KILL -${a.pid} 2>/dev/null || true`);if(!await g.exists(`${P}/exit`))await g.write(`${P}/exit`,"143");l="exited"}),restart:()=>A(async()=>{if(await y.stop(),!n){let c=await U(k),a=JSON.parse(await g.read(`${P}/restart.json`));if(!a||typeof a!=="object")r("Invalid process restart record");let w={name:k};if("cwd"in a&&typeof a.cwd==="string")w.cwd=a.cwd;if("env"in a&&a.env&&typeof a.env==="object"){w.env={};for(let[u,O]of Object.entries(a.env))if(typeof O==="string")w.env[u]=O}if("readyTimeoutMs"in a&&typeof a.readyTimeoutMs==="number")w.readyTimeoutMs=a.readyTimeoutMs;if("readiness"in a&&a.readiness&&typeof a.readiness==="object"){let u=a.readiness;if("log"in u&&typeof u.log==="string")w.ready={log:new RegExp(u.log,"flags"in u&&typeof u.flags==="string"?u.flags:"")};else if("port"in u&&typeof u.port==="number")w.ready={port:u.port};else if("http"in u&&u.http&&typeof u.http==="object"&&"port"in u.http&&typeof u.http.port==="number")w.ready={http:{port:u.http.port,path:"path"in u.http&&typeof u.http.path==="string"?u.http.path:void 0}}}await ee("command"in a&&typeof a.command==="string"?a.command:c.command,w)}else await n()}),wait:()=>A(async()=>{while(!await g.exists(`${P}/exit`))await oe(25);let c=await U(k);return l=c.status,{exitCode:c.exitCode,signal:c.exitCode===143?"SIGTERM":c.exitCode===137?"SIGKILL":null}})};return N.set(k,y),ne.set(k,{state(c){l=c},access(c){z=c},ready(c){o=c},launch(c){n=c}}),y}let ne=new Map;async function ee(k,P={}){return A(async()=>{let x={...P,name:P.name??be(k)};if(d.processMode==="unsupported")throw new e("Background processes are unsupported. This runtime cannot run the SDK process-record shim. Use its native process API or another provider.",{code:"unsupported"});let l=B(x.name);if(d.name==="memory"&&d.startProcess&&await g.exists(`${l}/spec.json`)&&!await g.exists(`${l}/exit`))r(`Process ${x.name} is already running`);let z=Y(x.name),o=ne.get(x.name),n=x.ready&&"port"in x.ready?x.ready.port:x.ready&&("http"in x.ready)?x.ready.http.port:void 0,p=async()=>{let y=JSON.stringify({command:M.text(k),cwd:i(x.cwd),env:Object.fromEntries(Object.entries(x.env??{}).map(([j,E])=>[j,M.text(E)])),startedAt:Date.now(),port:n,readiness:x.ready&&("log"in x.ready?{log:x.ready.log.source,flags:x.ready.log.flags}:x.ready),readyTimeoutMs:x.readyTimeoutMs}),c=JSON.stringify({command:k,cwd:i(x.cwd),env:x.env,readiness:x.ready&&("log"in x.ready?{log:x.ready.log.source,flags:x.ready.log.flags}:x.ready),readyTimeoutMs:x.readyTimeoutMs}),a=`${l}/redact.sed`;if(d.name==="memory"&&d.startProcess){o?.state("starting"),o?.ready(!1),await g.write(`${l}/spec.json`,y),await g.write(`${l}/restart.json`,c);let j=await g.exists(`${l}/base`)?Number(await g.read(`${l}/base`))+(await g.stat(`${l}/out.log`)).size:0;if(await g.write(`${l}/out.log`,""),await g.write(`${l}/base`,String(j)),await g.exists(`${l}/exit`))await g.remove(`${l}/exit`)}else{let E=M.secrets.flatMap((L)=>L.split(`
|
|
34
|
+
`)).filter(Boolean).flatMap((L)=>{let Z=(re)=>re.replace(/[\\[\].*^$|]/g,"\\$&");return[`s|${Z(L)}|[REDACTED]|g`,...Array.from({length:L.length-1},(re,q)=>[`s|${Z(L.slice(0,L.length-1-q))}$|[REDACTED]|`,`s|^${Z(L.slice(q+1))}|[REDACTED]|`]).flat()]}).join(`
|
|
35
|
+
`)+`
|
|
36
|
+
`,G=await F(`mkdir -p ${t(l)} || exit 1; if [ -f ${t(`${l}/spec.json`)} ] && [ ! -f ${t(`${l}/exit`)} ]; then exit 73; fi; b=0; if [ -f ${t(`${l}/base`)} ]; then b=$(cat ${t(`${l}/base`)}); n=$(wc -c < ${t(`${l}/out.log`)}); b=$((b+n)); fi; IFS= read -r s && IFS= read -r r && printf '%s' "$s" | base64 -d > ${t(`${l}/spec.json`)} && (umask 077; printf '%s' "$r" | base64 -d > ${t(`${l}/restart.json`)}) && : > ${t(`${l}/out.log`)} && printf '%s' "$b" > ${t(`${l}/base`)} && rm -f ${t(`${l}/exit`)}`,{},Buffer.from(y).toString("base64")+`
|
|
37
|
+
`+Buffer.from(c).toString("base64")+`
|
|
38
|
+
`);if(G.exitCode===73)r(`Process ${x.name} is already running`);if(G.timedOut||G.exitCode!==0)throw new e("Process setup failed. Could not prepare durable records. Check that /tmp is writable and retry.",{code:"provider"});await d.files.write(m,a,new TextEncoder().encode(E)),o?.state("starting"),o?.ready(!1)}if(o?.launch(p),d.startProcess&&d.name==="memory"){let j,E=[],G=0,L=0,Z=()=>j??=(async()=>{while(E.length||L){let H=E;E=[],G=0;let te=L;L=0;let K=await g.read(`${l}/out.log`,{as:"bytes"}),ie=Number(await g.read(`${l}/base`));if(te)ie+=K.length+te,K=new Uint8Array;let Q=Buffer.concat([K,Buffer.from(H.join(""))]);if(Q.length>10485760){let se=Q.indexOf(10,Q.length-5242880)+1;ie+=se,Q=Q.subarray(se)}await g.write(`${l}/base`,String(ie)),await g.write(`${l}/out.log`,Q)}})().finally(()=>{j=void 0}),re=f(M,(H)=>{for(let te of me(H)){E.push(te),G+=Buffer.byteLength(te);while(G>1048576&&E.length>1){let K=E.shift()??"";G-=Buffer.byteLength(K),L+=Buffer.byteLength(K)}}Z().catch(()=>o?.state("failed"))}),q=await d.startProcess(m,{command:k,cwd:i(x.cwd),env:{...h,...x.env,...s},onChunk:(H)=>re.push(H)});T.set(x.name,q),await g.write(`${l}/pid`,String(q.pid)),q.wait().then(async(H)=>{re.flush(),await Z(),await g.write(`${l}/exit`,String(H.exitCode??137)),o?.state(H.exitCode===0?"exited":"failed")}).catch(async(H)=>{await g.write(`${l}/exit`,"1").catch(()=>{}),o?.state("failed")})}else{let j=`append() { while ! mkdir ${t(`${l}/lock`)} 2>/dev/null; do sleep 0.01; done; printf '%s%s\\n' "$1" "$2" >> ${t(`${l}/out.log`)}; n=$(wc -c < ${t(`${l}/out.log`)}); if [ "$n" -gt 10485760 ]; then tail -c 5242880 ${t(`${l}/out.log`)} | tail -n +2 > ${t(`${l}/rotate`)}; kept=$(wc -c < ${t(`${l}/rotate`)}); b=$(cat ${t(`${l}/base`)}); echo $((b+n-kept)) > ${t(`${l}/base`)}; mv ${t(`${l}/rotate`)} ${t(`${l}/out.log`)}; fi; rmdir ${t(`${l}/lock`)}; };`,E=(L,Z)=>`(nl=$(printf '\\nX'); nl=\${nl%X}; while :; do chunk=$(dd bs=4096 count=1 2>/dev/null; printf .); chunk=\${chunk%.}; [ -n "$chunk" ] || break; need=0; for byte in $(printf '%s' "$chunk" | tail -c 4 | od -An -tu1); do if [ "$byte" -ge 240 ]; then need=3; elif [ "$byte" -ge 224 ]; then need=2; elif [ "$byte" -ge 192 ]; then need=1; elif [ "$byte" -ge 128 ]; then [ "$need" -le 0 ] || need=$((need-1)); else need=0; fi; done; if [ "$need" -gt 0 ]; then rest=$(dd bs=1 count="$need" 2>/dev/null; printf .); rest=\${rest%.}; chunk="$chunk$rest"; fi; chunk=$(printf '%s\\n' "$chunk" | sed -u -f ${t(a)}; printf .); chunk=\${chunk%.}; chunk=\${chunk%"$nl"}; while [ -n "$chunk" ]; do case "$chunk" in *"$nl"*) line=\${chunk%%"$nl"*}; append ${L} "$line"; chunk=\${chunk#*"$nl"};; *) append ${L.toLowerCase()} "$chunk"; chunk=;; esac; done; done < ${t(Z)}) &`,G=`chmod 600 ${t(a)}; trap 'code=$?; printf "%s" "$code" > ${t(`${l}/exit`)}' EXIT; trap 'exit 143' TERM; cd ${t(i(x.cwd))} || exit 1; ${j} rm -f ${t(`${l}/stdout`)} ${t(`${l}/stderr`)}; mkfifo ${t(`${l}/stdout`)} ${t(`${l}/stderr`)}; ${E("O",`${l}/stdout`)} out=$!; ${E("E",`${l}/stderr`)} err=$!; sh -c ${t(k)} > ${t(`${l}/stdout`)} 2> ${t(`${l}/stderr`)}; code=$?; wait "$out" "$err"; exit "$code"`;if(d.startProcess){let L=await d.startProcess(m,{command:G,cwd:"/workspace",env:{...h,...x.env,...s},onChunk(){}});T.set(x.name,L),await g.write(`${l}/pid`,String(L.pid)),L.wait().then(async(Z)=>{if(!await g.exists(`${l}/exit`))await g.write(`${l}/exit`,String(Z.exitCode??137))}).catch(async()=>{await g.write(`${l}/exit`,"1").catch(()=>{})})}else await F(`nohup setsid sh -c ${t(G)} > /dev/null 2>&1 < /dev/null & echo $! > ${t(`${l}/pid`)}`,x.env)}if(o?.state("running"),!x.ready){o?.ready(!0);return}let w=Date.now()+(x.readyTimeoutMs??60000),u,O="",R=!1,_=()=>O.replace(/\n$/,"").split(`
|
|
39
|
+
`).slice(-50).join(`
|
|
40
|
+
`);do{let j=await z.logs({after:u,maxBytes:1048576});if(u=j.nextCursor,O=Buffer.from(O+j.text).subarray(-262144).toString(),R=await g.exists(`${l}/exit`),R&&j.truncated)continue;if(R)throw new e(`Process exited before readiness. Exit ${(await U(x.name)).exitCode}. Check the last logs: ${_()}`,{code:"process_exited"});if("log"in x.ready){if(x.ready.log.lastIndex=0,x.ready.log.test(O)){o?.ready(!0);return}}else if(n)try{let E=await J(n,d.name==="memory"?{}:{path:"http"in x.ready?x.ready.http.path:void 0,waitMs:Math.max(1,Math.min(5000,w-Date.now()))});o?.access(E.url),o?.ready(!0);return}catch(E){if(!(E instanceof e)||E.code!=="port_not_ready")throw E}if(Date.now()>=w)break;await oe(25)}while(R||Date.now()<=w);throw new e(`Process is still running but readiness timed out. No readiness signal arrived. Inspect logs: ${_()}`,{code:"timeout"})};return await p(),z})}return{start:ee,process:Y,preview:(k,P)=>A(()=>J(k,P)),processes:()=>A(async()=>{let k;try{k=await g.list(S)}catch(l){if(l instanceof e&&(["file_not_found","not_found"].includes(l.code)||l.code==="provider"&&!await g.exists(S)))return[];throw l}let P=[],x=k.filter((l)=>l.type==="directory");for(let l=0;l<x.length;l+=4)P.push(...await Promise.all(x.slice(l,l+4).map((z)=>U(z.path.split("/").pop()??""))));return P})}}async function qe(d,m,g,M,h,S=!0){let T=!1,N=!1,A=0,B=0,F=()=>{if(T||N)throw new e("Sandbox handle is closed. Local resources were detached. Connect a new handle.",{code:"not_found",provider:d.name,sandboxId:m.id})},D=ce(d,m.id,h,F),U={},J="/tmp/.sandbox-sdk/secret-names.json";if(g){if(M.trackChanges)await D.mark("start");else if(M.from!==void 0)await D.remove("/tmp/.sandbox-sdk/marks/start.json").catch(()=>{});let n=Object.keys(M.secrets??{});if(n.length||M.from!==void 0){let p=JSON.stringify(n);if(d.files.writeCreatesParents||d.name==="memory")await D.write(J,p);else if((await d.exec(m.id,{command:`mkdir -p /tmp/.sandbox-sdk && printf '%s' ${t(p)} > ${t(J)}`,cwd:"/",env:s,timeoutMs:1e4,onChunk(){}})).exitCode!==0)throw new e("Secret setup failed. Could not record secret names in /tmp/.sandbox-sdk. Ensure /tmp is writable.",{code:"provider",provider:d.name,sandboxId:m.id})}}else if(S){let n="",p=await d.exec(m.id,{command:b,cwd:"/",env:{},timeoutMs:1e4,onChunk(y){if(y.stream==="stdout")n+=y.text}});if(p.timedOut||p.exitCode!==0)throw new e("Secret recovery failed. Could not read the sandbox environment. Retry connecting.",{code:"provider",provider:d.name,sandboxId:m.id});if(n){let y=n.indexOf("\x00");if(y<0)r("Invalid secret recovery record");let c;try{c=JSON.parse(n.slice(0,y))}catch{throw new e("Secret recovery failed. The secret names record is not valid JSON. Repair the record and reconnect.",{code:"provider"})}if(!Array.isArray(c)||c.some((w)=>typeof w!=="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(w)))r("Invalid secret names record");let a=new Map;for(let w of n.slice(y+1).split("\x00")){let u=w.indexOf("=");if(u>=0)a.set(w.slice(0,u),w.slice(u+1))}for(let w of c)if(typeof w==="string")U[w]=a.get(w)??"";h.add(Object.values(U))}}let Y={...U,...M.env,...M.secrets},ne=I(d,m.id,h,Y,(n)=>{A++,B+=n},F),ee=we(d,m.id,ce(d,m.id,h),h,Y),k=async(n)=>{F();try{return await n()}catch(p){throw h.error(p,d.name,m.id)}},P={id:m.id,key:m.key,provider:d.name,created:g,labels:m.labels,capabilities:new Set(d.capabilities),get native(){F();try{return d.native(m.id)}catch(n){throw h.error(n,d.name,m.id)}},run(n,p){return F(),ne(n,p)},$(n,...p){return F(),ne(n.reduce((y,c,a)=>y+c+(a<p.length?t(p[a]):""),""))},files:D,git:fe((n,p)=>(F(),ne(n,p)),D,h),start:(n,p)=>k(()=>ee.start(n,p)),process(n){return F(),ee.process(n)},processes:()=>k(()=>ee.processes()),preview:(n,p)=>k(()=>ee.preview(n,p)),usage:()=>k(async()=>({...await d.usage?.(m.id),createdAt:m.createdAt,runningMs:Date.now()-m.createdAt,commands:A,bytesOut:B})),async close(){if(T||N)return;try{await d.close?.(m.id),D[Symbol.dispose](),T=!0}catch(n){throw h.error(n,d.name,m.id)}},async destroy(){if(N)return;try{if(v(d,m.id),await d.destroy(m.id),D[Symbol.dispose](),N=!0,M.key)await M.locator?.delete?.(M.key)}catch(n){throw h.error(n,d.name,m.id)}},async[Symbol.asyncDispose](){if(M.key)await P.close();else await P.destroy()}},{pause:x,resume:l,snapshot:z,terminal:o}=d;if(d.capabilities.has("pause")&&x&&l)Object.assign(P,{pause:()=>k(()=>x.call(d,m.id)),resume:()=>k(()=>l.call(d,m.id))});if(d.capabilities.has("snapshot")&&z)Object.assign(P,{snapshot:()=>k(()=>z.call(d,m.id))});if(d.capabilities.has("terminal")&&o)Object.assign(P,{terminal:(n)=>k(async()=>{let p=await o.call(d,m.id,n),y=new Set;return{write:(a)=>k(async()=>{await p.write(a)}),resize:(a,w)=>k(async()=>{await p.resize(a,w)}),onData(a){F();let w=f(h,(R)=>a(R.text)),u=p.onData((R)=>w.push({stream:"stdout",text:R})),O=()=>{u(),w.flush(),y.delete(O)};return y.add(O),O},close:()=>k(async()=>{for(let a of y)a();await p.close()})}})});return C(P,h),P}export{qe as makeHandle};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s,i,t,b,O,u,k,f,I}from"./chunk-t5vr9nd8.js";export{u as BufferCap,k as OutputBus,f as chunkRedactor,s as defaults,O as isRunActive,I as makeRun,i as pathOf,t as quote,b as secretRecoveryCommand};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{r}from"./chunk-gc8zdxyb.js";import{posix as U}from"node:path";var s={CI:"1",PAGER:"cat",GIT_TERMINAL_PROMPT:"0",DEBIAN_FRONTEND:"noninteractive",TERM:"dumb",NO_COLOR:"1"},i=(e=".")=>U.resolve("/workspace",e),t=(e)=>`'${String(e).replaceAll("'","'\\''")}'`,b="if [ -f /tmp/.sandbox-sdk/secret-names.json ]; then cat /tmp/.sandbox-sdk/secret-names.json || exit 1; printf '\\000'; env -0; fi",W=`trap 'rm -rf -- "$2"' EXIT
|
|
2
|
+
(umask 077; mkdir -p "$2") || exit 1
|
|
3
|
+
{ { "$3" -c "$1" 3>&- 4>&-; printf '%s\\n' "$?" > "$2/status"; } 2>&1 >&3 | cat >&4; } 3>&1 4>&2 | cat
|
|
4
|
+
read -r code < "$2/status"
|
|
5
|
+
exit "$code"`,X=(e,n,c="sh")=>`sh -c ${t(W)} sh ${t(e)} ${t(n)} ${t(c)}`,P=new Map,O=(e,n)=>(P.get(e)?.get(n)??0)>0;function J(e,n){let c=P.get(e);if(!c)c=new Map,P.set(e,c);let l=c;return l.set(n,(l.get(n)??0)+1),()=>{let h=(l.get(n)??1)-1;if(h)l.set(n,h);else l.delete(n);if(!l.size)P.delete(e)}}class u{limit;head=Buffer.alloc(0);tail=Buffer.alloc(0);total=0;constructor(e){this.limit=e}add(e){let n=Buffer.from(e);this.total+=n.length;let c=Math.ceil(this.limit/2),l=Math.min(n.length,c-this.head.length);if(l>0)this.head=Buffer.concat([this.head,n.subarray(0,l)]);if(this.tail=Buffer.concat([this.tail,n.subarray(Math.max(0,l))]),this.tail.length>this.limit-c)this.tail=this.tail.subarray(this.tail.length-(this.limit-c))}get truncated(){return this.total>this.limit}text(){if(!this.truncated)return Buffer.concat([this.head,this.tail]).toString();let e=new TextDecoder().decode(this.head,{stream:!0}),n=0;while(n<this.tail.length&&((this.tail[n]??0)&192)===128)n++;let c=this.tail.subarray(n).toString();return e+`
|
|
6
|
+
[${this.total-Buffer.byteLength(e)-Buffer.byteLength(c)} bytes cut]
|
|
7
|
+
`+c}}class k{listeners=new Set;ended=!1;failure;emit(e){for(let n of this.listeners)n(e)}fail(e){this.failure=e,this.end()}end(){this.ended=!0;for(let e of this.listeners)e()}async*stream(){let e=[],n=0,c=()=>{},l=(h)=>{if(h){let x=Buffer.byteLength(h.text)>1048576?Buffer.from(h.text).subarray(-1048576).toString():h.text;e.push({...h,text:x}),n+=Buffer.byteLength(x);while(n>1048576&&e.length>1)n-=Buffer.byteLength(e.shift()?.text??"")}c()};this.listeners.add(l);try{while(!this.ended||e.length){let h=e.shift();if(h)n-=Buffer.byteLength(h.text),yield h;else await new Promise((x)=>{c=x})}if(this.failure)throw this.failure}finally{this.listeners.delete(l)}}}function f(e,n,c=!1){let l=[];function h(x=!1){let R=e.secrets,B=new Set(R.map((a)=>a[0]));while(l.length){let a=l[0];if(!a)break;if(!B.has(a.text[0])){let o=1;while(o<a.text.length&&!B.has(a.text[o]))o++;if(n({stream:a.stream,text:a.text.slice(0,o)}),a.text=a.text.slice(o),!a.text)l.shift();continue}let C=l.filter((o)=>c||o.stream===a.stream).map((o)=>o.text).join(""),v=R.find((o)=>C.startsWith(o));if(v){n({stream:a.stream,text:"[REDACTED]"});let o=v.length;for(let g of l)if((c||g.stream===a.stream)&&o){let w=Math.min(o,g.text.length);g.text=g.text.slice(w),o-=w}}else{if(!x&&R.some((g)=>g.startsWith(C))){if(l.reduce((g,w)=>g+Buffer.byteLength(w.text),0)<=1048576)break;n({stream:a.stream,text:"[REDACTED]"}),l.shift();continue}let o=1;while(o<a.text.length&&!B.has(a.text[o]))o++;n({stream:a.stream,text:a.text.slice(0,o)}),a.text=a.text.slice(o)}for(let o=l.length-1;o>=0;o--)if(!l[o]?.text)l.splice(o,1)}}return{push(x){if(!e.secrets.length){n(x);return}l.push({...x}),h()},flush(){h(!0)}}}function I(e,n,c,l,h,x=()=>{}){return(R,B={})=>{let a={...B},C,v=new k,o=(m=!1)=>C??=g(m).catch((y)=>{let p=c.error(y,e.name,n);throw v.fail(p),p});async function g(m){x();let y=a.timeoutMs??120000,p=a.maxOutputBytes??1048576;if(!Number.isFinite(y)||y<=0||!Number.isSafeInteger(p)||p<1)r("timeoutMs and maxOutputBytes must be positive");let q=i(a.cwd),H=Date.now(),_=new u(p),A=new u(p),S=new u(p*2),E=new AbortController,M=a.signal?.aborted??!1,T=()=>{M=!0,E.abort()};a.signal?.addEventListener("abort",T,{once:!0});let z=setTimeout(T,y),D=`/tmp/.sandbox-sdk/runs/${crypto.randomUUID()}`,G=!1,F=J(e.name,n),N=f(c,(d)=>{S.add(d.text),v.emit(d)},!0),j=f(c,(d)=>{(d.stream==="stdout"?_:A).add(d.text),N.push(d)});try{if(M)E.abort();let d=M?{exitCode:null,timedOut:!0}:await e.exec(n,{command:e.inlineActivity?R:X(R,D,e.commandShell),cwd:q,env:{...l,...a.env,...s},stdin:a.stdin,timeoutMs:y,signal:E.signal,streaming:m,envMode:a.env===void 0?"sandbox":void 0,activityPath:e.inlineActivity?D:void 0,onChunk:(L)=>j.push(L)});return G=d.exitCode!==null&&d.exitCode>=0&&d.exitCode<128&&!d.timedOut&&!E.signal.aborted,M||=d.timedOut,j.flush(),N.flush(),h(_.total+A.total),{ok:!M&&d.exitCode===0,exitCode:M?null:d.exitCode,stdout:_.text(),stderr:A.text(),output:S.text(),durationMs:Date.now()-H,truncated:_.truncated||A.truncated||S.truncated,timedOut:M,cwd:q,command:c.text(R)}}catch(d){j.flush(),N.flush();let L=c.error(d,e.name,n);throw v.fail(L),L}finally{if(clearTimeout(z),a.signal?.removeEventListener("abort",T),!G&&!e.inlineActivity)await Promise.resolve().then(()=>e.files.remove(n,D,{recursive:!0})).catch(()=>{});F(),v.end()}}let w={then(m,y){return o().then(m,y)},[Symbol.asyncIterator](){let m=v.stream(),y=m.next();o(!0).catch(()=>{});let p=!0;return{next:()=>{if(p)return p=!1,y;return m.next()},return:()=>m.return(void 0)}},cwd(m){if(C)r("Run already started");return a.cwd=m,w},env(m){if(C)r("Run already started");return a.env={...a.env,...m},w},timeout(m){if(C)r("Run already started");return a.timeoutMs=m,w}};return w}}
|
|
8
|
+
export{s,i,t,b,O,u,k,f,I};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import{u}from"./chunk-t5vr9nd8.js";import{_,P}from"./chunk-cwx6cc31.js";import{e,r}from"./chunk-gc8zdxyb.js";import{createHash as ce}from"node:crypto";import{posix as W}from"node:path";import{z as o}from"zod";var b=o.string(),Z=o.number().int().positive(),G=o.string().regex(/^[a-zA-Z0-9_-]{1,128}$/),te=Z.max(65535),c={run:o.object({command:b,cwd:b.optional(),timeoutMs:Z.optional()}).strict(),read_file:o.object({path:b,offset:o.number().int().nonnegative().optional(),limit:Z.optional()}).strict(),write_file:o.object({path:b,content:b}).strict(),edit_file:o.object({path:b,find:b.min(1),replace:b}).strict(),start_process:o.object({name:G,command:b,cwd:b.optional(),port:te.optional()}).strict(),process_logs:o.object({name:G,cursor:b.optional()}).strict(),stop_process:o.object({name:G}).strict(),search:o.object({query:b,path:b.optional(),glob:b.optional()}).strict(),list_files:o.object({path:b.optional(),glob:b.optional()}).strict(),changes:o.object({}).strict(),preview:o.object({port:te,path:b.optional()}).strict()},le={run:"Run a noninteractive command with a timeout. cwd and exports do not persist. Do not use for servers; use start_process, or file tools for reading and editing.",read_file:"Read numbered lines and a SHA-256; offset is a zero-based line index. Do not use for directory listings or binary contents.",write_file:"Create or replace a UTF-8 file. Do not use for a small change to an existing file; use edit_file.",edit_file:"Replace exactly one literal match. Do not use ambiguous snippets; include surrounding lines when a match is repeated.",start_process:"Start a named background process; with port, wait for readiness and return its URL. Do not use for short commands; use run.",process_logs:"Read a page of a named process's logs; pass the returned cursor for the next page. Do not restart a process to retrieve output.",stop_process:"Stop a named background process. Do not use to destroy the sandbox or stop unrelated processes.",search:"Find literal text in files under a path. Do not use for regular expressions; use run with rg instead.",list_files:"List files recursively under a path. Do not use to read file contents.",changes:"Show added, modified and removed files since these tools were created. Do not use for Git history.",preview:"Get the preview URL for a port. Do not use to start a server; use start_process first. Access headers stay server-side."},ue=["run","read_file","write_file","edit_file","start_process","process_logs","stop_process"],oe=(l)=>ce("sha256").update(l).digest("hex");function w(l,I={}){_(l,"");let A=W.resolve("/workspace",I.root??"."),z=new Set(I.allow??ue);for(let n of I.deny??[])z.delete(n);function re(n="."){let h=W.resolve(A,n);if(h!==A&&!h.startsWith(A==="/"?"/":`${A}/`))r("Path escapes tool root. Use a path inside the configured root");return h}async function N(n="."){let h=re(n),g="/";for(let y of h.split("/").filter(Boolean)){g=W.join(g,y);try{if((await l.files.stat(g)).type==="symlink")r("Symlink path rejected. It may escape tool root. Use a regular path")}catch(M){if(!(M instanceof e&&M.code==="file_not_found"))throw M}}return h}async function Q(n){let h=await I.beforeRun?.(n);if(h===!1)r("Command denied by beforeRun. Application policy refused execution. Choose an allowed command");return typeof h==="string"?h:n}let O=(n)=>_(l,n),C=new Map;function q(n,h){let g=C.get(n)??{buffer:Buffer.alloc(0),base:0,total:0},y=Buffer.from(O(h)),M=Buffer.concat([g.buffer,y]),B=g.total+y.length,F=M.subarray(-1048576);C.set(n,{buffer:F,base:B-F.length,total:B});while(C.size>8){let E=C.keys().next().value;if(E)C.delete(E)}}async function V(){let n=new Map,h=await N();if(!await l.files.exists(h))return n;for(let g of await l.files.list(h,{recursive:!0}))if(g.type==="file")n.set(g.path,oe(await l.files.read(await N(g.path),{as:"bytes"})));return n}let H=z.has("changes")?V().then((n)=>({value:n}),(n)=>({error:n})):void 0;function se(n){let h=c[n],g=I.limits?.[n]??{},y=g.maxOutputBytes??16384,M=g.timeoutMs??30000;if(!Number.isSafeInteger(y)||y<256||!Number.isSafeInteger(M)||M<1)r("Tool limits must have maxOutputBytes >= 256 and timeoutMs > 0");for(let B of[g.maxReadBytes,g.maxMatches])if(B!==void 0&&(!Number.isSafeInteger(B)||B<1))r("maxReadBytes and maxMatches must be positive integers");return{name:n,description:le[n],inputSchema:h,async execute(B,F,E){let ne=Date.now(),J=!1;function K(i){try{I.onEvent?.(i)}catch{J=!0}try{F?.(i)}catch{J=!0}}function f(i,t,s="",a,T=""){let R=O(`${i?"OK":"FAILED"}${s?` ${s}`:""} ${((Date.now()-ne)/1000).toFixed(1)}s${a?` cwd=${a}`:""}`),j=new u(Math.floor(y/4));j.add(R);let d=j.text(),p=new u(Math.max(1,y-Buffer.byteLength(d)-Buffer.byteLength(T)-100));return p.add(O(t+(J?`
|
|
2
|
+
UI streaming callback failed. Execution was allowed to finish. Fix onEvent before reconnecting the UI.`:""))),{text:O(`${d}
|
|
3
|
+
output:
|
|
4
|
+
${T}${p.text()}`)}}try{let i=de.parse({tool:n,input:B});if(H){let t=await H;if("error"in t&&i.tool==="changes")throw t.error}if(E?.aborted)r("Tool cancelled. The calling agent aborted execution. Retry only if still needed");switch(i.tool){case"run":{let t=i.input,s=await N(t.cwd),a=l.run(await Q(t.command),{cwd:s,timeoutMs:Math.min(t.timeoutMs??M,M),maxOutputBytes:y,signal:E}),T=new u(Math.max(1,y-512)),R=`run_${crypto.randomUUID().replaceAll("-","")}`;q(R,"");let j=P(l,(m)=>{T.add(m.text),q(R,m.text);let k={tool:n,kind:"output",stream:m.stream,text:O(m.text)};K(k)});try{for await(let m of a)j.push(m)}finally{j.flush()}let d=await a,p=T.text().replace(/\[(\d+) bytes cut\]/,"[$1 bytes cut, use process_logs]");return f(d.ok,`${p}${d.timedOut?E?.aborted?`
|
|
5
|
+
Aborted. The calling agent cancelled execution and the command was terminated. Retry only if still needed.`:`
|
|
6
|
+
Timed out. Command exceeded its limit and was terminated. Increase the configured timeout or use start_process for servers.`:""}${!d.ok&&!d.timedOut?`
|
|
7
|
+
Command exited with status ${d.exitCode}. Inspect the output and correct the command before retrying.`:""}`,`exit=${d.exitCode}`,s,T.truncated?`name=${R} cursor=0 use=process_logs
|
|
8
|
+
`:"")}case"read_file":{let t=i.input,s=await N(t.path),a=await l.files.read(s,{as:"bytes"}),T=oe(a),R=g.maxReadBytes??1048576;if(a.length>R)return f(!1,`File is ${a.length} bytes, above maxReadBytes=${R}. Raise read_file's maxReadBytes or use run to extract a smaller file.`,`sha=${T}`);let j;try{if(j=new TextDecoder("utf-8",{fatal:!0}).decode(a),j.includes("\x00"))throw Error("binary")}catch{return f(!0,`binary file; size=${a.length} bytes; sha=${T}. Use download outside the agent tools to retrieve bytes.`)}let d=O(j).split(`
|
|
9
|
+
`),p=t.offset??0,m=[],k=0;for(let[D,x]of d.slice(p,p+(t.limit??200)).entries()){let v=`${p+D+1}: ${x}`;if(m.length&&k+Buffer.byteLength(v)>y-600)break;m.push(v),k+=Buffer.byteLength(v)+1}let S=p+m.length,L="";if(k>y-600){let D=`read_${crypto.randomUUID().replaceAll("-","")}`;q(D,m.join(`
|
|
10
|
+
`)),L=`name=${D} cursor=0 use=process_logs
|
|
11
|
+
`}return f(!0,`${m.join(`
|
|
12
|
+
`)}
|
|
13
|
+
${S<d.length?"[more lines; use read_file with nextOffset as offset]":""}`,"",void 0,`sha=${T} lines=${d.length} nextOffset=${S<d.length?S:"end"}
|
|
14
|
+
${L}`)}case"write_file":{let t=i.input;return await l.files.write(await N(t.path),t.content),f(!0,"File written.")}case"edit_file":{let t=i.input;return await l.files.edit(await N(t.path),{find:t.find,replace:t.replace}),f(!0,"One exact match replaced.")}case"start_process":{let t=i.input,s;try{s=await l.start(await Q(t.command),{name:t.name,cwd:await N(t.cwd),ready:t.port?{port:t.port}:void 0,readyTimeoutMs:M})}catch(a){if(!(a instanceof e&&a.code==="timeout"))throw a;return f(!1,`name=${t.name} ready=false cursor=0
|
|
15
|
+
${a.message}
|
|
16
|
+
Use process_logs to inspect startup or stop_process to terminate it.`)}return f(s.status!=="failed",`name=${t.name} ready=${s.ready} status=${s.status} url=${s.url??"none"}
|
|
17
|
+
cursor=0
|
|
18
|
+
Use process_logs to inspect output.${!s.ready?`
|
|
19
|
+
Not ready. The process may still be running. Use stop_process to stop it.`:""}`)}case"process_logs":{let t=i.input,s=C.get(t.name);if(s){let x=t.cursor===void 0?s.base:Number(t.cursor);if(!Number.isSafeInteger(x)||x<0||x>s.total)r("Invalid foreground log cursor. It is outside the retained output. Use cursor=0 to replay");let v=Math.max(x,s.base),X=(ie)=>{let ee=s.buffer[ie-s.base];return ee!==void 0&&(ee&192)===128};while(v<s.total&&X(v))v++;let U=Math.min(s.total,v+Math.max(64,y-512));while(U>v&&U<s.total&&X(U))U--;let Y=s.buffer.subarray(v-s.base,U-s.base).toString(),ae={tool:n,kind:"output",stream:"stdout",text:O(Y)};return K(ae),f(!0,`cursor=${U} more=${U<s.total}
|
|
20
|
+
${x<s.base?`[${s.base-x} bytes expired from replay window]
|
|
21
|
+
`:""}${Y}${U<s.total?`
|
|
22
|
+
[more output; use process_logs with cursor]`:""}`)}let a=l.process(t.name),T=new u(10485760),R=P(l,(x)=>T.add(x.text)),j,d=!1;for(let x=0;x<16;x++){let v=await a.logs({after:j,maxBytes:1048576});if(R.push({stream:"stdout",text:v.text}),d=v.truncated&&v.nextCursor!==j,j=v.nextCursor,!d)break}if(a.status==="exited"||a.status==="failed")R.flush();let p=Buffer.from(T.text()),m=t.cursor===void 0?0:Number(t.cursor);if(!Number.isSafeInteger(m)||m<0||m>p.length)r("Log cursor is invalid or expired after rotation. The retained log view changed. Use cursor=0 to replay");let k=m,S=Math.min(p.length,m+Math.max(32,y-512)),L=(x)=>((p[x]??0)&192)===128;while(k<p.length&&L(k))k++;while(S>k&&S<p.length&&L(S))S--;let D=p.subarray(k,S).toString();return K({tool:n,kind:"output",stream:"stdout",text:D}),f(!0,`${D}${S<p.length||d?`
|
|
23
|
+
[more output; use process_logs with cursor]`:""}`,"",void 0,`cursor=${S} more=${S<p.length||d}
|
|
24
|
+
`)}case"stop_process":return await l.process(i.input.name).stop(),f(!0,"Process stopped.");case"search":{let t=i.input;return f(!0,JSON.stringify(await l.files.search(t.query,{path:await N(t.path),glob:t.glob,maxMatches:g.maxMatches??100})))}case"list_files":{let t=i.input;return f(!0,JSON.stringify(await l.files.list(await N(t.path),{recursive:!0,glob:t.glob})))}case"changes":{let t=await H;if(!t||!("value"in t))r("Changes baseline unavailable");let s=await V();return f(!0,JSON.stringify({added:[...s.keys()].filter((a)=>!t.value.has(a)),modified:[...s.keys()].filter((a)=>t.value.has(a)&&t.value.get(a)!==s.get(a)),removed:[...t.value.keys()].filter((a)=>!s.has(a))}))}case"preview":{let t=i.input;if(t.path&&(!t.path.startsWith("/")||t.path.startsWith("//")))r("Preview path must be an absolute URL path. External URLs are not allowed. Use /path");let s=await l.preview(t.port,{path:t.path});return f(!0,`url=${s.url}`)}default:return i}}catch(i){if(i instanceof e)return f(!1,`${i.message}
|
|
25
|
+
code=${i.code} retryable=${i.retryable}
|
|
26
|
+
Next: ${i.hint}`);if(i instanceof o.ZodError)return f(!1,"Invalid tool input. Parameters do not match the tool schema. Check the required fields and types, then retry.");return f(!1,"Tool failed. An unexpected execution or callback error occurred. Check server-side diagnostics and retry.")}}}}return[...z].map((n)=>se(n))}var de=o.discriminatedUnion("tool",[o.object({tool:o.literal("run"),input:c.run}),o.object({tool:o.literal("read_file"),input:c.read_file}),o.object({tool:o.literal("write_file"),input:c.write_file}),o.object({tool:o.literal("edit_file"),input:c.edit_file}),o.object({tool:o.literal("start_process"),input:c.start_process}),o.object({tool:o.literal("process_logs"),input:c.process_logs}),o.object({tool:o.literal("stop_process"),input:c.stop_process}),o.object({tool:o.literal("search"),input:c.search}),o.object({tool:o.literal("list_files"),input:c.list_files}),o.object({tool:o.literal("changes"),input:c.changes}),o.object({tool:o.literal("preview"),input:c.preview})]);
|
|
27
|
+
export{c,w};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{e}from"./chunk-gc8zdxyb.js";async function o(n,s,t){try{return await t()}catch(r){if(!(r instanceof Error&&("code"in r)&&r.code==="ERR_MODULE_NOT_FOUND"&&r.message.includes(`'${n}'`)))throw r;throw new e(`${n} is not installed. The ${s} adapter loads it as an optional peer. Install ${n} next to @opencoredev/sandbox-sdk.`,{code:"unavailable",provider:s,cause:r})}}
|
|
2
|
+
export{o};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{s}from"./chunk-t5vr9nd8.js";import{o}from"./chunk-yed8mvs7.js";import{e}from"./chunk-gc8zdxyb.js";import{deflateRawSync as re,inflateRawSync as oe}from"node:zlib";import{posix as ne}from"node:path";function y(d="boat",r="Boat",n="BOAT_API_KEY",h=!1){function l(w,k){if(w instanceof e)return w;let z=typeof w==="object"&&w!==null&&"response"in w?w.response:void 0,g=z instanceof Response?z.status:void 0,p="provider";if(g===401||g===403)p="auth";else if(g===404)p="not_found";else if(g===402||g===429)p="quota";else if(g===400)p="invalid_argument";else if(g===408||w instanceof Error&&w.name==="TimeoutError")p="timeout";else if(g!==void 0&&g>=500)p="unavailable";else if(w instanceof Error&&w.name==="AbortError")p="aborted";let B=p==="auth"?`Set ${n} to a valid ${r} API key.`:`Check the sandbox and ${r} service before retrying.`,O=typeof w==="object"&&w!==null&&"apiCode"in w&&typeof w.apiCode==="string"&&/^[a-z][a-z0-9_]{0,63}$/.test(w.apiCode)?` ${w.apiCode}`:"",_=h&&g!==void 0?` (HTTP ${g}${O})`:"";return new e(`${r} request failed${_}. The provider reported ${p}. ${B}`,{code:p,provider:d,sandboxId:k,hint:B,retryable:p==="unavailable"||p==="quota"})}function C(w,k="provider",z){let g=w.replaceAll("Boat",r);return new e(k==="auth"?g:`${g}. Check the ${r} provider configuration and retry.`,{code:k,provider:d,sandboxId:z})}return{boatError:l,failure:C}}var L=`flock -x /tmp/.sandbox-sdk-workspace-ready.lock sh -c 'if [ ! -f /tmp/.sandbox-sdk/prepared-workspace ]; then sudo mkdir -p /workspace && sudo chown "$(id -u):$(id -g)" /workspace && command -v node git tar setsid nohup mkfifo sed base64 >/dev/null && mkdir -p /tmp/.sandbox-sdk && touch /tmp/.sandbox-sdk/prepared-workspace || exit 1; fi' || exit 1`,b=(d)=>`'${d.replaceAll("'","'\\''")}'`;async function Y(d,r,n,h={},l=new Map,C=y()){let{boatError:w,failure:k}=C;if(n.signal?.aborted)return{exitCode:null,timedOut:!0};let{followCommand:z}=await import("@boatdev/sdk"),g=new AbortController,p=!1,B=()=>{},O=new Promise((c)=>{B=()=>{p=!0,c("cancelled")}}),_=setTimeout(B,n.timeoutMs);n.signal?.addEventListener("abort",B,{once:!0});let R,M=!1,t=!1,a,i,m=`/tmp/.sandbox-sdk-setup-${crypto.randomUUID()}`;async function f(){if(R===void 0)return;try{if((await d.stopCommand({sandboxId:r,processId:R})).running!==!1)throw k("Boat did not confirm process-tree cancellation","outcome_unknown",r)}catch{throw k("Remote cancellation could not be confirmed; destroy the sandbox before retrying","outcome_unknown",r)}}try{let c=Object.entries(n.env).filter(([u,A])=>!Object.entries(s).some(([P,D])=>u===P&&A===D)&&h[u]!==A),v=Object.entries(s).filter(([u,A])=>n.env[u]===A).map(([u,A])=>`export ${b(`${u}=${A}`)}`).join("; ");if(v)v+="; ";let S="/tmp/.sandbox-sdk/changes.git/sdk.index",q=c.filter(([u,A])=>u==="GIT_INDEX_FILE"&&A===S);c=c.filter(([u,A])=>u!=="GIT_INDEX_FILE"||A!==S);for(let[u,A]of q)v+=`export ${b(`${u}=${A}`)}; `;if(c.length){let u=JSON.stringify(c),A=n.envMode==="sandbox"?l.get(u):void 0;if(A)v+=`. ${b(await A)} || exit 1; `;else{i=`/tmp/.sandbox-sdk/env-${crypto.randomUUID()}`;let P=`${i}/env`,D=i,W=(async()=>{let X=await d.command({sandboxId:r,commandRequest:{command:`node -e ${b("const f=require('fs');f.mkdirSync('/tmp/.sandbox-sdk',{recursive:true});f.mkdirSync(process.argv[1],{mode:0o700});f.writeFileSync(process.argv[1]+'/env','',{flag:'wx',mode:0o600})")} ${b(D)}`,timeoutSeconds:60}});if(!("exitCode"in X)||X.exitCode!==0)throw k("Boat could not prepare command environment","provider",r);return await d.writeFile({sandboxId:r,fileWriteRequest:{path:P,content:c.map(([ee,te])=>`export ${b(`${ee}=${te}`)}`).join(`
|
|
2
|
+
`)+`
|
|
3
|
+
`,encoding:"utf8"}}),P})();if(n.envMode==="sandbox")l.set(u,W);try{await W}catch(G){if(n.envMode==="sandbox")l.delete(u);throw G}if(n.envMode==="sandbox")i=void 0,v+=`. ${b(P)} || exit 1; `;else v+=`chmod 600 ${b(P)} && . ${b(P)} && /bin/rm -f -- ${b(P)} && /bin/rmdir -- ${b(D)} || exit 1; `}}let E=Buffer.from(n.stdin??""),T=`printf %s ${b(E.toString("base64"))} | base64 -d | `,U="";if(E.length>16384){a=`/tmp/.sandbox-sdk/stdin-${crypto.randomUUID()}`;for(let u=0;u<E.length;u+=32768){if(p)return{exitCode:null,timedOut:!0};let A="const f=require('fs');f.mkdirSync('/tmp/.sandbox-sdk',{recursive:true});f.writeFileSync(process.argv[1],Buffer.from(process.argv[2],'base64'),{flag:process.argv[3],mode:0o600})",P=await d.command({sandboxId:r,commandRequest:{command:`umask 077; node -e ${b(A)} ${b(a)} ${b(E.subarray(u,u+32768).toString("base64"))} ${u?"a":"w"}`,timeoutSeconds:60}});if(!("exitCode"in P)||P.exitCode!==0)throw k("Boat could not prepare command stdin","provider",r)}T="",U=` < ${b(a)}`}if(p)return{exitCode:null,timedOut:!0};let V=`(${L}) || { echo setup-failed > ${b(m)}; exit 125; }; ${T}(${v}cd ${b(n.cwd)} && exec sh -c ${b(n.command)})${U}`;t=!0;let N=await d.command({sandboxId:r,commandRequest:{command:V,detached:!0}});if(!("processId"in N)||!Number.isSafeInteger(N.processId)||N.processId<1)throw k("Boat did not confirm a detached process ID","outcome_unknown",r);if(R=N.processId,n.signal?.aborted)B();let F=(async()=>{for await(let u of z(d,r,N.processId,{signal:g.signal}))if(u.type==="stdout"||u.type==="stderr"){if(typeof u.data!=="string")throw k("Invalid Boat output frame","provider",r);n.onChunk({stream:u.type,text:u.data})}else if(u.type==="exit"){if(typeof u.exitCode!=="number"&&u.exitCode!==null)throw k("Boat returned no command exit code","outcome_unknown",r);return M=!0,{exitCode:u.exitCode,timedOut:u.timedOut===!0}}else if(u.type==="error")throw k("Boat command stream failed","provider",r);throw k("Boat stream ended without an exit result","outcome_unknown",r)})();F.catch(()=>{});let j=await Promise.race([F,O]);if(j==="cancelled"||p)return await f(),g.abort(),await F.catch(()=>{}),{exitCode:null,timedOut:!0};if(!j.timedOut&&j.exitCode===125){let u=await d.command({sandboxId:r,commandRequest:{command:`if [ -f ${b(m)} ]; then cat ${b(m)}; rm -f -- ${b(m)}; fi`,timeoutSeconds:10}});if(!("stdout"in u)||u.exitCode!==0)throw k("Boat could not confirm command initialization","outcome_unknown",r);if(u.stdout.trim()==="setup-failed")throw k("Boat workspace initialization failed; the requested command did not run","provider",r)}return j}catch(c){if(R!==void 0&&!M)await f();if(t&&R===void 0&&!["auth","quota","invalid_argument","not_found"].includes(w(c,r).code))throw k("Command launch outcome is unknown; inspect or destroy the sandbox before retrying","outcome_unknown",r);throw c}finally{if(g.abort(),clearTimeout(_),n.signal?.removeEventListener("abort",B),i)await d.command({sandboxId:r,commandRequest:{command:`rm -rf -- ${b(i)}`,timeoutSeconds:10}}).catch(()=>{});if(a)await d.command({sandboxId:r,commandRequest:{command:`rm -f -- ${b(a)}`,timeoutSeconds:10}}).catch(()=>{})}}var ae={name:"boat",label:"Boat",keyEnv:"BOAT_API_KEY",baseEnv:"BOAT_API_BASE",baseUrl:"https://boat.dev/api/v1"},J="sandbox-sdk:1:",se={"sandbox-sdk":"1"},ie={small:"small",medium:"default",large:"large"};function de(d,r,n){let h={...d.labels};delete h["sandbox-sdk"];let l=JSON.stringify([d.key??null,h]);if(Buffer.byteLength(l)>65536)throw r("Key and labels exceed the metadata size limit","unsupported");let C=J+re(l).toString("base64url");if(C.length>120)throw r(`Key and labels exceed ${n}'s encoded name budget; shorten them`,"unsupported");return C}function Q(d){if(!d.startsWith(J))return;try{let r=JSON.parse(oe(Buffer.from(d.slice(J.length),"base64url"),{maxOutputLength:65536}).toString());if(!Array.isArray(r)||r.length!==2)return;let[n,h]=r;if(n!==null&&typeof n!=="string")return;if(typeof h!=="object"||h===null||Array.isArray(h))return;let l={};for(let[C,w]of Object.entries(h)){if(typeof w!=="string")return;Object.defineProperty(l,C,{value:w,enumerable:!0,writable:!0,configurable:!0})}return{...n===null?{}:{key:n},labels:{...l,...se}}}catch{return}}function K(d,r,n,h=[]){let l=Q(d.name);if(!l)throw r("Sandbox has no valid SDK metadata; connect an SDK-created sandbox","not_found",d.id);let C=d.createdAt?.getTime();if(C===void 0||!Number.isFinite(C))throw r(`${n} returned no valid creation timestamp`,"provider",d.id);return{id:d.id,...l,createdAt:C,state:h.includes(d.state)?"paused":["ready","idle","running"].includes(d.state)?"running":"stopped"}}function H(d,r,n){if(typeof d!=="object"||d===null||!("path"in d)||typeof d.path!=="string"||!("type"in d)||!("size"in d)||typeof d.size!=="number"||!("modifiedAt"in d)||typeof d.modifiedAt!=="number")throw r(`Invalid file metadata from ${n}`);let h=d.type;if(h!=="file"&&h!=="directory"&&h!=="symlink")throw r(`Invalid file type from ${n}`);return{path:d.path,type:h,size:d.size,modifiedAt:d.modifiedAt}}var Z="const fs=require('fs'),p=require('path');const stat=x=>{const s=fs.lstatSync(x);return {path:x,type:s.isSymbolicLink()?'symlink':s.isDirectory()?'directory':'file',size:s.size,modifiedAt:s.mtimeMs}};";function x(d={},r=ae){let{failure:n,boatError:h}=y(r.name,r.label,r.keyEnv,r.name!=="boat"),l=r.label,C,w,k=new Map,z=new Map,g=new Map;async function p(){return C??=(async()=>{let t=d.apiKey??process.env[r.keyEnv];if(!t)throw n(`${l} API key is missing. Authentication is required. Set ${r.keyEnv} or pass apiKey.`,"auth");let a=d.requestTimeoutMs??90000;if(!Number.isSafeInteger(a)||a<=0)throw n("requestTimeoutMs must be a positive integer","invalid_argument");let{BoatApi:i,Configuration:m}=await o("@boatdev/sdk",r.name,()=>import("@boatdev/sdk"));return w=new i(new m({basePath:d.baseUrl??d.apiUrl??(r.baseEnv?process.env[r.baseEnv]:void 0)??r.baseUrl,accessToken:t,fetchApi:(f,c)=>(r.fetch??fetch)(f,{...c,signal:c?.signal?AbortSignal.any([c.signal,AbortSignal.timeout(a)]):AbortSignal.timeout(a)})})),w})()}async function B(t,a){try{return await t()}catch(i){throw h(i,a)}}async function O(t,a,i=!1,m=!1){let f=await(await p()).command({sandboxId:t,commandRequest:{command:m?`${L}; ${a}`:a,timeoutSeconds:60}});if(!("stdout"in f))throw n(`${l} returned an unexpected detached result`,"outcome_unknown",t);if(f.stdoutTruncated||f.stderrTruncated)throw n(`${l} truncated operation output; no partial file data was returned`,"provider",t);if(f.exitCode!==0)throw n(i&&f.exitCode===44?"File does not exist":`${l} file or setup operation failed`,i&&f.exitCode===44?"file_not_found":"provider",t);return f.stdout}let _=(t,a,i=[])=>B(()=>O(t,`node -e ${b(`try {${a}} catch(e) {process.exit(e.code==='ENOENT'?44:45)}`)} ${i.map(b).join(" ")}`,!0,i.some((m)=>m==="/workspace"||m.startsWith("/workspace/"))),t);async function R(t,a,i,m){let f=[];for(let c=0;c<m;c+=16384){let I=Math.min(16384,m-c),v=await _(t,"const f=require('fs'),fd=f.openSync(process.argv[1],'r');try{const b=Buffer.alloc(Number(process.argv[3]));const n=f.readSync(fd,b,0,b.length,Number(process.argv[2]));process.stdout.write(b.subarray(0,n).toString('base64'))}finally{f.closeSync(fd)}",[a,String(i+c),String(I)]),S=Buffer.from(v,"base64");if(f.push(S),S.length<I)break}return new Uint8Array(Buffer.concat(f))}let M={name:r.name,keyMode:"best-effort",capabilities:new Set(["size"]),create:(t)=>B(async()=>{if(t.network!==void 0&&t.network!=="all")throw n(`${l} network policy is unsupported by this adapter`,"unsupported");if(t.size!==void 0&&typeof t.size!=="string")throw n(`${l} supports small, medium and large presets; custom sizes are unavailable`,"unsupported");if(t.idleTimeoutMs!==void 0||t.timeoutMs!==void 0)throw n(`${l} auto-stop is resettable and is not an idle timer or hard lifetime; timeoutMs and idleTimeoutMs are unsupported`,"unsupported");if(t.from!==void 0&&!r.createFrom)throw n(`${l} snapshots are not supported by this adapter`,"unsupported");let a=de(t,n,l);if(t.signal?.aborted)throw n("Creation was aborted","aborted");let i=await p(),m={idempotencyKey:crypto.randomUUID(),createSandboxRequest:{noEnv:!0,...t.from===void 0?{}:{from:t.from},env:t.env,type:t.size===void 0?d.machine??d.type:ie[t.size]}},f;for(let c=0;c<3;c++)try{f=(await i.create(m)).sandbox;break}catch(I){let v=h(I).code;if(["auth","invalid_argument","quota","not_found"].includes(v))throw I;if(c===2)throw n(`${l} create outcome remains unknown; recover with idempotency key ${m.idempotencyKey} and the same request body within 24 hours`,"outcome_unknown");await new Promise((S)=>setTimeout(S,250*(c+1)))}if(!f)throw n(`${l} returned no sandbox after create`,"outcome_unknown");z.set(f.id,{...t.env});try{if(t.signal?.aborted)throw n("Creation was aborted","aborted");let c=await i.update({sandboxId:f.id,updateSandboxRequest:{name:a}});if(t.signal?.aborted)throw n("Creation was aborted","aborted");let I=c.sandbox;if(I.name!==a)return await M.connect(f.id);let v={...K(I,n,l,r.pausedStates),state:"running"};return g.set(f.id,I),v}catch(c){throw await M.destroy(f.id),c}}),connect:(t)=>B(async()=>{let{sandbox:a}=await(await p()).get({sandboxId:t}),i=K(a,n,l,r.pausedStates);return g.set(t,a),i},t),list:(t)=>B(async()=>{let a=[],i,m=new Set;do{let f=await(await p()).sandboxes({limit:200,cursor:i});for(let I of f.sandboxes){if(!Q(I.name))continue;let v=K(I,n,l,r.pausedStates);if(Object.entries(t).every(([S,q])=>v.labels[S]===q))a.push(v),g.set(v.id,I)}if(!f.pageInfo?.hasMore)break;let c=f.pageInfo.nextCursor;if(!c||m.has(c))throw n(`${l} returned an invalid pagination cursor`);m.add(c),i=c}while(i!==void 0);return a}),async find(t){return(await M.list({})).find((a)=>a.key===t)},destroy:(t)=>B(async()=>{try{if(r.destroy)await r.destroy(await p(),t);else await(await p()).deleteSandbox({sandboxId:t,xAsciiConfirmDelete:t})}catch(a){if(h(a).code!=="not_found")throw a}g.delete(t),z.delete(t),k.delete(t)},t),exec:(t,a)=>B(async()=>{let i=k.get(t);if(!i)i=new Map,k.set(t,i);return Y(await p(),t,a,z.get(t),i,{failure:n,boatError:h})},t),files:{writeCreatesParents:!0,readRange:(t,a,i)=>R(t,a,i.offset,i.length),read:async(t,a)=>{let i=await _(t,"const f=require('fs'),fd=f.openSync(process.argv[1],'r');try{const size=f.fstatSync(fd).size,b=Buffer.alloc(Math.min(size,16384)),n=f.readSync(fd,b,0,b.length,0);process.stdout.write(size+'\\n'+b.subarray(0,n).toString('base64'))}finally{f.closeSync(fd)}",[a]),m=i.indexOf(`
|
|
4
|
+
`),f=Number(i.slice(0,m));if(m<0||!Number.isSafeInteger(f)||f<0)throw n(`Invalid ${l} file size`);let c=Buffer.from(i.slice(m+1),"base64");if(f<=16384)return new Uint8Array(c);if(f<=1048576)return new Uint8Array(Buffer.concat([c,await R(t,a,c.length,f-c.length)]));if(r.downloadMaxBytes!==void 0&&f>r.downloadMaxBytes)return new Uint8Array(Buffer.concat([c,await R(t,a,c.length,f-c.length)]));return B(async()=>{let I=`/tmp/.sandbox-sdk/download-${crypto.randomUUID()}`,v=`${I}/file`;try{let S=Number(await _(t,"const f=require('fs');f.mkdirSync('/tmp/.sandbox-sdk',{recursive:true});f.mkdirSync(process.argv[2],{mode:0o700});f.copyFileSync(process.argv[1],process.argv[2]+'/file');process.stdout.write(String(f.statSync(process.argv[2]+'/file').size))",[a,I]));if(!Number.isSafeInteger(S)||S<0)throw n("Invalid staged file size","provider",t);if(r.download){let U=await r.download(await p(),t,v);if(U.length!==S)throw n("Incomplete artifact download","provider",t);return U}let q=await(await p()).createDownloadUrl({sandboxId:t,fileUrlRequest:{path:v,ttlSeconds:300}}),E=await fetch(q.url,{signal:AbortSignal.timeout(d.requestTimeoutMs??90000)});if(!E.ok)throw await E.body?.cancel(),n("Signed file download failed","unavailable",t);let T=new Uint8Array(await E.arrayBuffer());if(T.length!==S)throw n("Incomplete signed file download","provider",t);return T}finally{await _(t,"require('fs').rmSync(process.argv[1],{recursive:true,force:true})",[I]).catch(()=>{})}},t)},write:(t,a,i)=>B(async()=>{let m=await p(),f=ne.normalize(a);if(i.length<=4194304&&(f.startsWith("/home/user/")||f.startsWith("/tmp/")))try{await m.writeFile({sandboxId:t,fileWriteRequest:{path:a,content:Buffer.from(i).toString("base64"),encoding:"base64"}});return}catch(S){if(h(S).code!=="invalid_argument")throw S}let c=`/tmp/.sandbox-sdk/write-${crypto.randomUUID()}`,I=`${c}/chunk`,v=!1;try{await _(t,"const f=require('fs');f.mkdirSync('/tmp/.sandbox-sdk',{recursive:true});f.mkdirSync(process.argv[1],{mode:0o700})",[c]);let S=4194304;for(let q=0;q<Math.max(i.length,1);q+=S){let E=q+S>=i.length;if(await m.writeFile({sandboxId:t,fileWriteRequest:{path:I,content:Buffer.from(i.subarray(q,q+S)).toString("base64"),encoding:"base64"}}),await _(t,"const f=require('fs');try{f.mkdirSync(require('path').dirname(process.argv[1]),{recursive:true});f.writeFileSync(process.argv[1],f.readFileSync(process.argv[2]+'/chunk'),{flag:process.argv[3]})}finally{if(process.argv[4]==='true')f.rmSync(process.argv[2],{recursive:true,force:true});else f.rmSync(process.argv[2]+'/chunk',{force:true})}",[a,c,q?"a":"w",String(E)]),E)v=!0}}finally{if(!v)await _(t,"require('fs').rmSync(process.argv[1],{recursive:true,force:true})",[c]).catch(()=>{})}},t),stat:async(t,a)=>{let i=JSON.parse(await _(t,Z+"process.stdout.write(JSON.stringify(stat(process.argv[1])))",[a]));return H(i,n,l)},list:async(t,a)=>{let i=JSON.parse(await _(t,Z+"process.stdout.write(JSON.stringify(fs.readdirSync(process.argv[1]).map(x=>stat(p.join(process.argv[1],x)))))",[a]));if(!Array.isArray(i))throw n(`Invalid ${l} directory listing`);return i.map((m)=>H(m,n,l))},mkdir:async(t,a)=>{await _(t,"require('fs').mkdirSync(process.argv[1],{recursive:true})",[a])},remove:async(t,a,i)=>{await _(t,"require('fs').rmSync(process.argv[1],{recursive:process.argv[2]==='true'})",[a,String(i.recursive)])}},previewUrl:(t,a)=>B(async()=>{let i=await(await p()).hostPort({sandboxId:t,hostPortRequest:{port:a}});if(!i.url)throw n(`${l} returned no preview URL`,"provider",t);if(r.preview)return r.preview(i.url);let m=new URL(i.url),f=m.searchParams.get("_token");if(f){if(!/^[A-Za-z0-9._~-]+$/.test(f))throw n("Invalid preview token","provider",t);return m.searchParams.delete("_token"),{url:m.toString(),headers:{Cookie:`_port_auth=${f}`}}}if(i.isProtected||i.access==="private")throw n("Protected preview returned no token","provider",t);return{url:m.toString()}},t),native(t){let a=g.get(t);if(!a||!w)throw n("Sandbox is not connected; connect it first","not_found",t);return{sandbox:a,client:w}}};return M}
|
|
5
|
+
export{y,x};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function m(i){let n=[];function f(t){if(typeof t==="string"){let e=Buffer.from(t),r=Buffer.alloc(5);r[0]=117,r.writeUInt32LE(e.length,1),n.push(r,e)}else if(typeof t==="number"){let e=Buffer.alloc(9);e[0]=103,e.writeDoubleLE(t,1),n.push(e)}else if(Array.isArray(t)){let e=Buffer.alloc(5);e[0]=91,e.writeUInt32LE(t.length,1),n.push(e);for(let r of t)f(r)}else if(t!==void 0){n.push(Buffer.from("{"));for(let[e,r]of Object.entries(t))if(r!==void 0)f(e),f(r);n.push(Buffer.from("0"))}}return f(i),Buffer.concat(n)}
|
|
2
|
+
export{m};
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a {@link SandboxError} was thrown. A non-zero exit, a command timeout, or an
|
|
3
|
+
* aborted `run` is never an error; those resolve with `ok: false`.
|
|
4
|
+
*
|
|
5
|
+
* - `auth`: credentials are missing or rejected.
|
|
6
|
+
* - `not_found`: the sandbox or handle no longer exists, or the handle was closed.
|
|
7
|
+
* - `quota`: a provider limit or billing stopped the request. Usually retryable.
|
|
8
|
+
* - `unavailable`: the provider is down or unreachable. Usually retryable.
|
|
9
|
+
* - `unsupported`: the provider cannot do what was asked (size, network policy, lifetime).
|
|
10
|
+
* - `timeout`: a provider operation or a readiness check took too long.
|
|
11
|
+
* - `aborted`: your `AbortSignal` fired.
|
|
12
|
+
* - `outcome_unknown`: the request may or may not have happened.
|
|
13
|
+
* - `process_exited`: a background process exited before it was ready.
|
|
14
|
+
* - `port_not_ready`: a preview did not answer with a 2xx before `waitMs` ran out.
|
|
15
|
+
* - `edit_not_found` / `edit_not_unique`: `files.edit` matched zero or several times.
|
|
16
|
+
* - `file_not_found`: the path does not exist.
|
|
17
|
+
* - `invalid_argument`: the input is invalid. Retrying will not help.
|
|
18
|
+
* - `provider`: any other provider or adapter failure.
|
|
19
|
+
*/
|
|
20
|
+
export type ErrorCode = "auth" | "not_found" | "quota" | "unavailable" | "unsupported" | "timeout" | "aborted" | "outcome_unknown" | "process_exited" | "port_not_ready" | "edit_not_found" | "edit_not_unique" | "file_not_found" | "invalid_argument" | "provider";
|
|
21
|
+
/** Second argument to the {@link SandboxError} constructor. */
|
|
22
|
+
export interface ErrorOptions {
|
|
23
|
+
code: ErrorCode;
|
|
24
|
+
/** Provider name. Default: `"unknown"`. */
|
|
25
|
+
provider?: string;
|
|
26
|
+
sandboxId?: string;
|
|
27
|
+
/** Whether the same call can succeed on retry. Default: `false`. */
|
|
28
|
+
retryable?: boolean;
|
|
29
|
+
/** The next step, on its own. Default: a generic step for `code`. */
|
|
30
|
+
hint?: string;
|
|
31
|
+
cause?: unknown;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The only error type the SDK throws. Branch on `code` and `retryable`; show `hint` to users.
|
|
35
|
+
* Secrets registered with the sandbox are redacted from `message`, `hint`, and `cause`.
|
|
36
|
+
*/
|
|
37
|
+
export declare class SandboxError extends Error {
|
|
38
|
+
/** What kind of failure this is. */
|
|
39
|
+
readonly code: ErrorCode;
|
|
40
|
+
/** Whether the same call can succeed if you retry it. */
|
|
41
|
+
readonly retryable: boolean;
|
|
42
|
+
/** The next step, on its own, for logs and UIs. */
|
|
43
|
+
readonly hint: string;
|
|
44
|
+
/** Provider name, or `"unknown"`. */
|
|
45
|
+
readonly provider: string;
|
|
46
|
+
/** The sandbox involved, when there is one. */
|
|
47
|
+
readonly sandboxId?: string;
|
|
48
|
+
constructor(message: string, options: ErrorOptions);
|
|
49
|
+
}
|
|
50
|
+
/** @internal Redacts registered secrets from text and errors. */
|
|
51
|
+
export declare class Redactor {
|
|
52
|
+
private values;
|
|
53
|
+
add(values: Iterable<string>): void;
|
|
54
|
+
text(value: string): string;
|
|
55
|
+
get secrets(): string[];
|
|
56
|
+
get maxLength(): number;
|
|
57
|
+
error(error: unknown, provider: string, sandboxId?: string): SandboxError;
|
|
58
|
+
}
|
|
59
|
+
/** @internal Throws an `invalid_argument` SandboxError. */
|
|
60
|
+
export declare function invalid(message: string): never;
|
package/dist/files.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Provider, FileInfo } from "./provider.js";
|
|
2
|
+
import { SandboxError, type Redactor } from "./errors.js";
|
|
3
|
+
export interface FileEvent {
|
|
4
|
+
type: "added" | "modified" | "removed";
|
|
5
|
+
path: string;
|
|
6
|
+
}
|
|
7
|
+
export interface FileDiff {
|
|
8
|
+
added: string[];
|
|
9
|
+
modified: string[];
|
|
10
|
+
removed: string[];
|
|
11
|
+
patch: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Files {
|
|
14
|
+
read(path: string): Promise<string>;
|
|
15
|
+
read(path: string, options: {
|
|
16
|
+
as: "bytes";
|
|
17
|
+
}): Promise<Uint8Array>;
|
|
18
|
+
write(path: string, data: string | Uint8Array): Promise<void>;
|
|
19
|
+
write(files: Record<string, string | Uint8Array>): Promise<void>;
|
|
20
|
+
edit(path: string, edit: {
|
|
21
|
+
find: string;
|
|
22
|
+
replace: string;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
list(path?: string, options?: {
|
|
25
|
+
recursive?: boolean;
|
|
26
|
+
glob?: string;
|
|
27
|
+
}): Promise<FileInfo[]>;
|
|
28
|
+
stat(path: string): Promise<FileInfo>;
|
|
29
|
+
exists(path: string): Promise<boolean>;
|
|
30
|
+
remove(path: string, options?: {
|
|
31
|
+
recursive?: boolean;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
upload(source: string, target: string, options?: {
|
|
34
|
+
ignore?: string[];
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
download(source: string, target: string): Promise<void>;
|
|
37
|
+
search(query: string, options?: {
|
|
38
|
+
path?: string;
|
|
39
|
+
glob?: string;
|
|
40
|
+
maxMatches?: number;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
path: string;
|
|
43
|
+
line: number;
|
|
44
|
+
text: string;
|
|
45
|
+
}[]>;
|
|
46
|
+
watch(path: string, callback: (event: FileEvent) => void, options?: {
|
|
47
|
+
recursive?: boolean;
|
|
48
|
+
intervalMs?: number;
|
|
49
|
+
onError?: (error: SandboxError) => void;
|
|
50
|
+
}): () => void;
|
|
51
|
+
mark(name?: string): Promise<string>;
|
|
52
|
+
changes(options?: {
|
|
53
|
+
since?: string;
|
|
54
|
+
}): Promise<FileDiff>;
|
|
55
|
+
}
|
|
56
|
+
export declare function globMatch(path: string, glob: string): boolean;
|
|
57
|
+
export declare function makeFiles(provider: Provider, id: string, redactor: Redactor, guard?: () => void): Files & Disposable;
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RunHandle, RunOptions, RunResult } from "./types.js";
|
|
2
|
+
import type { Files } from "./files.js";
|
|
3
|
+
import type { Redactor } from "./errors.js";
|
|
4
|
+
export interface Git {
|
|
5
|
+
clone(url: string, options?: {
|
|
6
|
+
dir?: string;
|
|
7
|
+
branch?: string;
|
|
8
|
+
depth?: number;
|
|
9
|
+
token?: string;
|
|
10
|
+
}): Promise<RunResult>;
|
|
11
|
+
status(dir?: string): Promise<RunResult>;
|
|
12
|
+
diff(dir?: string): Promise<RunResult>;
|
|
13
|
+
commit(dir: string, options: {
|
|
14
|
+
message: string;
|
|
15
|
+
all?: boolean;
|
|
16
|
+
author?: string;
|
|
17
|
+
}): Promise<RunResult>;
|
|
18
|
+
push(dir: string, options?: {
|
|
19
|
+
token?: string;
|
|
20
|
+
remote?: string;
|
|
21
|
+
branch?: string;
|
|
22
|
+
}): Promise<RunResult>;
|
|
23
|
+
checkout(dir: string, options: {
|
|
24
|
+
branch: string;
|
|
25
|
+
create?: boolean;
|
|
26
|
+
}): Promise<RunResult>;
|
|
27
|
+
}
|
|
28
|
+
export declare function makeGit(run: (command: string, options?: RunOptions) => RunHandle, files: Files, redactor: Redactor): Git;
|
package/dist/handle.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Provider, SandboxInfo } from "./provider.js";
|
|
2
|
+
import type { CreateOptions, SandboxBase } from "./types.js";
|
|
3
|
+
import { Redactor } from "./errors.js";
|
|
4
|
+
export declare function makeHandle<N>(provider: Provider<N>, info: SandboxInfo, created: boolean, options: CreateOptions, redactor: Redactor, recoverSecrets?: boolean): Promise<SandboxBase<N>>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Provider, Capability, SandboxInfo } from "./provider.js";
|
|
2
|
+
import type { ConnectOptions, CreateOptions, ListOptions, MethodsFor, ProviderSandbox, ReapOptions, SandboxBase } from "./types.js";
|
|
3
|
+
export { SandboxError } from "./errors.js";
|
|
4
|
+
export type { ErrorCode, ErrorOptions } from "./errors.js";
|
|
5
|
+
export type { Sandbox, SandboxBase, ProviderSandbox, CreateOptions, ConnectOptions, ListOptions, ReapOptions, PreviewOptions, Usage, Locator, RunOptions, RunHandle, RunResult, OutputChunk, Capability, CapabilityMethods, MethodsFor, SandboxInfo, FileInfo, Labels, Preview, Terminal } from "./types.js";
|
|
6
|
+
export type { Files, FileDiff, FileEvent } from "./files.js";
|
|
7
|
+
export type { ProcessHandle, ProcessInfo, StartOptions, Readiness } from "./processes.js";
|
|
8
|
+
export type { Git } from "./git.js";
|
|
9
|
+
/**
|
|
10
|
+
* Check a capability at runtime and narrow the sandbox type to include its methods.
|
|
11
|
+
* Use it when the provider is chosen at runtime: `if (hasCapability(box, "pause")) await box.pause();`
|
|
12
|
+
*/
|
|
13
|
+
export declare function hasCapability<B extends SandboxBase<unknown>, K extends Capability>(box: B, capability: K): box is B & (K extends Capability ? MethodsFor<K> : never);
|
|
14
|
+
export declare function createSandbox<P extends Provider>(provider: P, options?: CreateOptions): Promise<ProviderSandbox<P>>;
|
|
15
|
+
export declare function connectSandbox<P extends Provider>(provider: P, id: string, options?: ConnectOptions): Promise<ProviderSandbox<P>>;
|
|
16
|
+
export declare function listSandboxes(provider: Provider, options?: ListOptions): Promise<SandboxInfo[]>;
|
|
17
|
+
export declare function reapSandboxes(provider: Provider, options?: ReapOptions): Promise<number>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{T,p,g,S,E}from"./chunk-59t3rqja.js";import{e}from"./chunk-gc8zdxyb.js";export{e as SandboxError,g as connectSandbox,p as createSandbox,T as hasCapability,S as listSandboxes,E as reapSandboxes};
|
package/dist/keys.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Provider } from "./provider.js";
|
|
2
|
+
export declare const knownKey: (provider: Provider, key: string) => string | undefined;
|
|
3
|
+
export declare function rememberKey(provider: Provider, key: string, id: string): void;
|
|
4
|
+
export declare function forgetKey(provider: Provider, key: string): void;
|
|
5
|
+
export declare function forgetSandbox(provider: Provider, id: string): void;
|
package/dist/logs.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { OutputChunk } from "./provider.js";
|
|
2
|
+
export declare function encodeChunk(chunk: OutputChunk): string[];
|
|
3
|
+
export declare function decodePage(bytes: Uint8Array, offset: number, max: number, base: number): {
|
|
4
|
+
events: (OutputChunk & {
|
|
5
|
+
cursor: string;
|
|
6
|
+
})[];
|
|
7
|
+
offset: number;
|
|
8
|
+
};
|
package/dist/mastra.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Sandbox } from "./types.js";
|
|
2
|
+
import { type SandboxToolsOptions } from "./tools.js";
|
|
3
|
+
export type { SandboxToolsOptions } from "./tools.js";
|
|
4
|
+
export declare function sandboxTools(box: Sandbox, options?: SandboxToolsOptions): {
|
|
5
|
+
[k: string]: import("@mastra/core/tools").Tool<{
|
|
6
|
+
command: string;
|
|
7
|
+
cwd?: string | undefined;
|
|
8
|
+
timeoutMs?: number | undefined;
|
|
9
|
+
} | {
|
|
10
|
+
path: string;
|
|
11
|
+
offset?: number | undefined;
|
|
12
|
+
limit?: number | undefined;
|
|
13
|
+
} | {
|
|
14
|
+
path: string;
|
|
15
|
+
content: string;
|
|
16
|
+
} | {
|
|
17
|
+
path: string;
|
|
18
|
+
find: string;
|
|
19
|
+
replace: string;
|
|
20
|
+
} | {
|
|
21
|
+
name: string;
|
|
22
|
+
command: string;
|
|
23
|
+
cwd?: string | undefined;
|
|
24
|
+
port?: number | undefined;
|
|
25
|
+
} | {
|
|
26
|
+
name: string;
|
|
27
|
+
cursor?: string | undefined;
|
|
28
|
+
} | {
|
|
29
|
+
name: string;
|
|
30
|
+
} | {
|
|
31
|
+
query: string;
|
|
32
|
+
path?: string | undefined;
|
|
33
|
+
glob?: string | undefined;
|
|
34
|
+
} | {
|
|
35
|
+
path?: string | undefined;
|
|
36
|
+
glob?: string | undefined;
|
|
37
|
+
} | Record<string, never> | {
|
|
38
|
+
port: number;
|
|
39
|
+
path?: string | undefined;
|
|
40
|
+
}, {
|
|
41
|
+
text: string;
|
|
42
|
+
}, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "run" | "read_file" | "write_file" | "edit_file" | "start_process" | "process_logs" | "stop_process" | "search" | "list_files" | "changes" | "preview", unknown>;
|
|
43
|
+
};
|
package/dist/mastra.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-t5vr9nd8.js";import{w}from"./chunk-v6y7eqxw.js";import"./chunk-cwx6cc31.js";import{createTool as s}from"@mastra/core/tools";import{z as e}from"zod";function c(p,r){return Object.fromEntries(w(p,r).map((o)=>[o.name,s({id:o.name,description:o.description,inputSchema:o.inputSchema,outputSchema:e.object({text:e.string()}),execute:(t,a)=>o.execute(t,void 0,a?.abortSignal),toModelOutput:(t)=>({type:"text",value:t.text})})]))}export{c as sandboxTools};
|
package/dist/memory.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Provider, FileInfo } from "./provider.js";
|
|
2
|
+
export interface CommandContext {
|
|
3
|
+
args: string[];
|
|
4
|
+
cwd: string;
|
|
5
|
+
env: Record<string, string>;
|
|
6
|
+
stdin: string;
|
|
7
|
+
signal: AbortSignal;
|
|
8
|
+
stdout(text: string): void;
|
|
9
|
+
stderr(text: string): void;
|
|
10
|
+
files: {
|
|
11
|
+
read(path: string): Promise<Uint8Array>;
|
|
12
|
+
write(path: string, data: string | Uint8Array): Promise<void>;
|
|
13
|
+
list(path: string): Promise<FileInfo[]>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export type CommandHandler = (context: CommandContext) => number | Promise<number>;
|
|
17
|
+
interface Node {
|
|
18
|
+
data: Uint8Array | null;
|
|
19
|
+
modifiedAt: number;
|
|
20
|
+
}
|
|
21
|
+
export interface MemoryOptions {
|
|
22
|
+
handlers?: Record<string, CommandHandler>;
|
|
23
|
+
}
|
|
24
|
+
export interface MemoryNative {
|
|
25
|
+
readonly files: Map<string, Node>;
|
|
26
|
+
}
|
|
27
|
+
/** Offline fake. No git, shell programs outside the handler table, PTYs, or real
|
|
28
|
+
* sockets. Preview URLs use memory.invalid and must never be fetched. Register
|
|
29
|
+
* handlers with memory({handlers}) or provider.register(name, handler).
|
|
30
|
+
*/
|
|
31
|
+
export declare function memory(options?: MemoryOptions): Provider<MemoryNative, "network-policy"> & {
|
|
32
|
+
register(name: string, handler: CommandHandler): void;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
package/dist/memory.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{b}from"./chunk-t5vr9nd8.js";import{e}from"./chunk-gc8zdxyb.js";import{posix as m}from"node:path";function Y(Z={}){let w=new Map,y=new Map,h=(r,t)=>new e(`${r}. Memory resource does not exist or request is invalid. Check the path or ID.`,{code:t,provider:"memory"}),v=(r)=>{let t=w.get(r);if(!t)throw h(`Sandbox ${r} not found`,"not_found");if(t.idleTimeoutMs)clearTimeout(t.idleTimer),t.idleTimer=setTimeout(()=>{if(t.active.size)v(r);else E.destroy(r)},t.idleTimeoutMs),t.idleTimer.unref?.();return t},M=(r,t)=>{let n=v(r).nodes.get(m.resolve("/",t));if(!n)throw h(`File ${t} not found`,"file_not_found");return n},R=()=>Date.now();function A(r,t){let n=v(r);for(let o=m.resolve("/",t);;o=m.dirname(o)){let i=n.nodes.get(o);if(i?.data)throw h(`${o} is not a directory`,"invalid_argument");if(!i)n.nodes.set(o,{data:null,modifiedAt:R()});if(o==="/")break}}let T={writeCreatesParents:!0,async readRange(r,t,n){let o=M(r,t);if(o.data===null)throw h(`${t} is a directory`,"invalid_argument");return o.data.slice(n.offset,n.offset+n.length)},async read(r,t){let n=M(r,t);if(n.data===null)throw h(`${t} is a directory`,"invalid_argument");return n.data.slice()},async write(r,t,n){let o=v(r);A(r,m.dirname(t)),o.nodes.set(m.resolve("/",t),{data:n.slice(),modifiedAt:Math.max(R(),(o.nodes.get(t)?.modifiedAt??0)+1)})},async stat(r,t){let n=M(r,t);return{path:m.resolve("/",t),type:n.data===null?"directory":"file",size:n.data?.length??0,modifiedAt:n.modifiedAt}},async list(r,t){let n=m.resolve("/",t);if(M(r,t).data!==null)throw h(`${t} is not a directory`,"invalid_argument");let o=[];for(let i of v(r).nodes.keys())if(i!==n&&m.dirname(i)===n)o.push(await T.stat(r,i));return o.sort((i,s)=>i.path.localeCompare(s.path))},async remove(r,t,n){let o=v(r),i=m.resolve("/",t);M(r,i);let s=[...o.nodes.keys()].filter((p)=>p.startsWith(i+"/"));if(s.length&&!n.recursive)throw h(`${t} is not empty`,"invalid_argument");for(let p of s)o.nodes.delete(p);o.nodes.delete(i)},async mkdir(r,t){A(r,t)}},q=({args:r,signal:t})=>new Promise((n)=>{if(t.aborted){n(137);return}let o=setTimeout(()=>{t.removeEventListener("abort",i),n(0)},Math.max(0,Number(r[0]??0)*1000)),i=()=>{clearTimeout(o),n(137)};t.addEventListener("abort",i,{once:!0})});y.set("echo",({args:r,stdout:t})=>{let n=r[0]==="-n";return t((n?r.slice(1):r).join(" ")+(n?"":`
|
|
2
|
+
`)),0}),y.set("printf",({args:r,stdout:t})=>{let n=1;return t((r[0]??"").replace(/\\n/g,`
|
|
3
|
+
`).replace(/\\t/g,"\t").replace(/%[sd%]/g,(o)=>o==="%%"?"%":r[n++]??"")),0}),y.set("pwd",({cwd:r,stdout:t})=>(t(r+`
|
|
4
|
+
`),0)),y.set("true",()=>0),y.set("false",()=>1),y.set("exit",({args:r})=>Number(r[0]??0)),y.set("sleep",q),y.set("cat",async({args:r,stdin:t,stdout:n,stderr:o,files:i})=>{if(!r.length)n(t);else for(let s of r)try{n(new TextDecoder().decode(await i.read(s)))}catch{return o(`cat: ${s}: No such file or directory
|
|
5
|
+
`),1}return 0}),y.set("ls",async({args:r,stdout:t,files:n})=>(t((await n.list(r.find((o)=>!o.startsWith("-"))??".")).map((o)=>m.basename(o.path)).join(`
|
|
6
|
+
`)+`
|
|
7
|
+
`),0)),y.set("printenv",({args:r,env:t,stdout:n})=>(n((r.length?r.map((o)=>t[o]??""):Object.entries(t).map(([o,i])=>`${o}=${i}`)).join(`
|
|
8
|
+
`)+`
|
|
9
|
+
`),0));for(let[r,t]of Object.entries(Z.handlers??{}))y.set(r,t);function W(r,t){let n=[],o="",i=!1,s="plain",p=()=>{if(i)n.push({text:o,operator:!1});o="",i=!1};for(let d=0;d<r.length;d++){let c=r[d]??"";if(s==="single"){if(c==="'")s="plain";else o+=c;continue}if(c==="'"&&s==="plain"){s="single",i=!0;continue}if(c==='"'){s=s==="double"?"plain":"double",i=!0;continue}if(c==="\\"){let u=r[++d]??"";o+=u==="n"?"\\n":u,i=!0;continue}if(c==="$"){let u=r.slice(d+1),C=/^(?:\{([A-Za-z_][A-Za-z0-9_]*)\}|([A-Za-z_][A-Za-z0-9_]*))/.exec(u);if(C){o+=t[C[1]??C[2]??""]??"",d+=C[0].length,i=!0;continue}}if(s==="plain"&&/\s/.test(c)){p();continue}if(s==="plain"&&"><".includes(c)&&i&&/^\d+$/.test(o)){let u=o;o="",i=!1,n.push({text:u+c,operator:!0});continue}if(s==="plain"&&c===">"&&r.slice(d,d+3)===">&2"){p(),n.push({text:">&2",operator:!0}),d+=2;continue}if(s==="plain"&&";&>|<".includes(c)){p();let u=c;if(r[d+1]===c)u+=r[++d];n.push({text:u,operator:!0});continue}o+=c,i=!0}if(s!=="plain")throw h("Unclosed shell quote","invalid_argument");return p(),n}async function z(r,t){let n=v(r),o=new AbortController;n.active.add(o);let i=!1,s=()=>{i=!0,o.abort()};if(t.signal?.addEventListener("abort",s,{once:!0}),t.signal?.aborted)s();let p=setTimeout(s,t.timeoutMs),d=t.cwd,c={...n.env,...t.env},u=0,C=!1;try{if(t.activityPath)A(r,m.dirname(t.activityPath)),await T.write(r,t.activityPath,new Uint8Array([1]));if(t.command===b){let l=n.nodes.get("/tmp/.sandbox-sdk/secret-names.json");if(l?.data)t.onChunk({stream:"stdout",text:new TextDecoder().decode(l.data)+"\x00"+Object.entries(c).map(([f,_])=>`${f}=${_}\x00`).join("")});return{exitCode:0,timedOut:!1}}let g=W(t.command,c),G=g.find((l)=>l.operator&&![";","&&","||",">",">&2"].includes(l.text)),K=g.find((l,f)=>l.operator&&l.text===">"&&(!g[f+1]||g[f+1]?.operator||g[f+2]&&!g[f+2]?.operator)),B=g.find((l,f)=>l.operator&&["&&","||"].includes(l.text)&&(!g[f-1]||[";","&&","||"].includes(g[f-1]?.text??"")||!g[f+1]||g[f+1]?.operator)),j=0,J=g.find((l)=>{if(!l.operator)return!1;if([";","&&","||"].includes(l.text))j=0;else if([">",">&2"].includes(l.text))return++j>1;return!1}),U=G??K??B??J;if(U)return t.onChunk({stream:"stderr",text:`Unsupported shell syntax: ${U.text} (memory provider)
|
|
10
|
+
`}),{exitCode:127,timedOut:!1};let O=[],I=";";async function H(l){let f=O;O=[];let _=f.findIndex((a)=>a.operator&&a.text===">&2");if(_>=0)f.splice(_,1);let N=f.findIndex((a)=>a.operator&&a.text===">"),S=N>=0?f[N+1]?.text:void 0;if(N>=0)f.splice(N);let P=f.map((a)=>a.text);if(!P.length||C||o.signal.aborted||I==="&&"&&u!==0||I==="||"&&u===0){I=l;return}I=l;let k=P.shift()??"";if(k==="cd"){if(d=m.resolve(d,P[0]??"/workspace"),M(r,d).data!==null)throw h("Not a directory","invalid_argument");u=0;return}if(k==="export"){for(let a of P){let x=a.indexOf("=");if(x>=0)c[a.slice(0,x)]=a.slice(x+1)}return}if(k==="kill"){let a=Math.abs(Number(P.find((x)=>/^-?\d+$/.test(x))));n.processes.get(a)?.controller.abort();return}if(k==="exit")C=!0;let D=y.get(k);if(!D){t.onChunk({stream:"stderr",text:`${k}: command not found (memory handler not registered)
|
|
11
|
+
`}),u=127;return}let F="",L=(a,x)=>{if(!o.signal.aborted)if(S&&a==="stdout")F+=x;else t.onChunk({stream:a,text:x})};if(u=await D({args:P,cwd:d,env:c,stdin:t.stdin??"",signal:o.signal,stdout:(a)=>L(_>=0?"stderr":"stdout",a),stderr:(a)=>L("stderr",a),files:{read:(a)=>T.read(r,m.resolve(d,a)),write:(a,x)=>T.write(r,m.resolve(d,a),typeof x==="string"?new TextEncoder().encode(x):x),list:(a)=>T.list(r,m.resolve(d,a))}}),S)await T.write(r,m.resolve(d,S),new TextEncoder().encode(F))}for(let l of g)if(l.operator&&[";","&&","||"].includes(l.text))await H(l.text);else O.push(l);return await H(";"),{exitCode:i?null:u,timedOut:i}}finally{if(t.activityPath){if(n.nodes.delete(t.activityPath),w.has(r))v(r)}n.active.delete(o),clearTimeout(p),t.signal?.removeEventListener("abort",s)}}let E={name:"memory",inlineActivity:!0,keyMode:"exact",capabilities:new Set(["network-policy"]),files:T,register(r,t){y.set(r,t)},async create(r){if(r.size!==void 0)throw new e("Memory cannot enforce machine size. Omit size or choose a provider with size support.",{code:"unsupported",provider:"memory"});if(r.key){if([...w.values()].find((i)=>i.info.key===r.key))throw new e("Key already exists. Another caller created it. Find the existing sandbox.",{code:"provider",provider:"memory"})}let t=`mem-${crypto.randomUUID()}`,n={id:t,key:r.key,labels:{...r.labels},state:"running",createdAt:R()};if(w.set(t,{info:n,nodes:new Map,env:{...r.env},processes:new Map,nextPid:100,active:new Set,idleTimeoutMs:r.idleTimeoutMs}),r.timeoutMs){let o=v(t);o.lifetimeTimer=setTimeout(()=>{E.destroy(t)},r.timeoutMs),o.lifetimeTimer.unref?.()}return A(t,"/workspace"),A(t,"/tmp"),n},async find(r){return[...w.values()].find((t)=>t.info.key===r)?.info},async connect(r){return v(r).info},async list(r){return[...w.values()].map((t)=>t.info).filter((t)=>Object.entries(r).every(([n,o])=>t.labels[n]===o))},async destroy(r){let t=w.get(r);if(!t)return;clearTimeout(t.idleTimer),clearTimeout(t.lifetimeTimer);for(let n of t.active)n.abort();for(let n of t.processes.values())n.controller.abort();await Promise.allSettled([...t.processes.values()].map((n)=>n.result)),w.delete(r)},exec:z,async previewUrl(r,t){return v(r),{url:`https://${r}-${t}.memory.invalid/`}},native(r){return{files:v(r).nodes}},async startProcess(r,t){let n=v(r),o=n.nextPid++,i=new AbortController,s=z(r,{...t,timeoutMs:2147483647,signal:i.signal});return n.processes.set(o,{controller:i,result:s}),s.then(()=>n.processes.delete(o),()=>n.processes.delete(o)),{pid:o,wait:async()=>{let p=await s;return{exitCode:p.timedOut?143:p.exitCode,signal:p.timedOut?"SIGTERM":null}},stop:async()=>{i.abort(),await s}}}};return E}export{Y as memory};
|
package/dist/openai.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Sandbox } from "./types.js";
|
|
2
|
+
import { type SandboxToolsOptions } from "./tools.js";
|
|
3
|
+
export type { SandboxToolsOptions } from "./tools.js";
|
|
4
|
+
export declare function sandboxTools(box: Sandbox, options?: SandboxToolsOptions): import("@openai/agents").FunctionTool<unknown, import("zod").ZodObject<{
|
|
5
|
+
command: import("zod").ZodString;
|
|
6
|
+
cwd: import("zod").ZodOptional<import("zod").ZodString>;
|
|
7
|
+
timeoutMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
8
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
9
|
+
path: import("zod").ZodString;
|
|
10
|
+
offset: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
11
|
+
limit: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
12
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
13
|
+
path: import("zod").ZodString;
|
|
14
|
+
content: import("zod").ZodString;
|
|
15
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
16
|
+
path: import("zod").ZodString;
|
|
17
|
+
find: import("zod").ZodString;
|
|
18
|
+
replace: import("zod").ZodString;
|
|
19
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
20
|
+
name: import("zod").ZodString;
|
|
21
|
+
command: import("zod").ZodString;
|
|
22
|
+
cwd: import("zod").ZodOptional<import("zod").ZodString>;
|
|
23
|
+
port: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
24
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
25
|
+
name: import("zod").ZodString;
|
|
26
|
+
cursor: import("zod").ZodOptional<import("zod").ZodString>;
|
|
27
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
28
|
+
name: import("zod").ZodString;
|
|
29
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
30
|
+
query: import("zod").ZodString;
|
|
31
|
+
path: import("zod").ZodOptional<import("zod").ZodString>;
|
|
32
|
+
glob: import("zod").ZodOptional<import("zod").ZodString>;
|
|
33
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
34
|
+
path: import("zod").ZodOptional<import("zod").ZodString>;
|
|
35
|
+
glob: import("zod").ZodOptional<import("zod").ZodString>;
|
|
36
|
+
}, import("zod/v4/core").$strict> | import("zod").ZodObject<{}, import("zod/v4/core").$strict> | import("zod").ZodObject<{
|
|
37
|
+
port: import("zod").ZodNumber;
|
|
38
|
+
path: import("zod").ZodOptional<import("zod").ZodString>;
|
|
39
|
+
}, import("zod/v4/core").$strict>, string>[];
|
package/dist/openai.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./chunk-t5vr9nd8.js";import{w}from"./chunk-v6y7eqxw.js";import"./chunk-cwx6cc31.js";import{tool as r}from"@openai/agents";function m(t,e){return w(t,e).map((o)=>r({name:o.name,description:o.description,parameters:o.inputSchema,strict:!0,execute:async(s,n,a)=>(await o.execute(s,void 0,a?.signal)).text}))}export{m as sandboxTools};
|