@chatpanel/events 0.212.0 → 0.213.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chatpanel/events",
3
- "version": "0.212.0",
3
+ "version": "0.213.0",
4
4
  "description": "The canonical ChatPanel event-log and capability contracts — typed durable facts, clock-free deterministic linearization, schema upcasting, and the invariants the replay harness asserts. Pure, dependency-free ESM shared by the ChatPanel extension, gateway and bridge.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/sandbox-policy.js CHANGED
@@ -1 +1 @@
1
- import{EventError as D}from"./event.js";import{normalizeGrant as O}from"./sandbox-grant.js";import{SECRET_DIR_NAMES as $,SECRET_DIR_PAIRS as j}from"./secret-names.js";const b=Object.freeze(["none","process","container","kubernetes"]),A=Object.freeze(["open","allowlist","none","gateway"]),_=Object.freeze(["~/.chatpanel","~/.ssh","~/.gnupg","~/.aws","~/.azure","~/.config/gcloud","~/.kube","~/.netrc","~/.docker/config.json","~/.npmrc","~/.pypirc"]),g=e=>{let t=String(e||"").trim();for(;t.length>1&&(t.endsWith("/")||t.endsWith("\\"));)t=t.slice(0,-1);return t},R=(e,t)=>t&&(e==="~"||e.startsWith("~/")||e.startsWith("~\\"))?t+e.slice(1):e,y=e=>String(e||"").replace(/\\/g,"/"),x=(e,t)=>{const n=y(g(e)),r=y(g(t));return!!n&&!!r&&(n===r||n.startsWith(`${r}/`))},C=_.map(e=>y(g(e)).replace(/^~\//,"").split("/").filter(Boolean));function S(e,t=""){const n=y(g(R(g(e),t)));if(!n)return!1;for(const o of _)if(x(n,o)||t&&x(n,R(o,t)))return!0;const r=n.split("/").filter(Boolean).map(o=>o.toLowerCase());return C.some(o=>{for(let i=0;i+o.length<=r.length;i+=1)if(o.every((c,l)=>c.toLowerCase()===r[i+l]))return!0;return!1})}const P=Object.freeze([...[...$].map(e=>`~/**/${e}`),...j.map(([e,t])=>`~/**/${e}/${t}`),...[".env",".netrc","_netrc",".git-credentials",".pgpass",".my.cnf",".npmrc",".pypirc",".htpasswd",".terraformrc",".vault-token","credentials","credentials.toml","id_rsa","id_dsa","id_ecdsa","id_ed25519","*.pem","*.p12","*.pfx","*.jks","*.keystore","*.kdbx","*.ppk"].map(e=>`~/**/${e}`)]),v=Object.freeze(["~/.npm","~/.cache","~/.local","~/Library/Caches","~/.nvm","~/.volta","~/.asdf","~/.nodenv","~/.bun","~/.deno","~/.pyenv","~/.rye","~/.pdm","~/.cargo","~/.rustup","~/go","~/.goenv","~/.m2","~/.gradle","~/.sdkman","~/.jenv","~/.gem","~/.rbenv","~/.bundle","~/.composer","~/.nuget","~/.dotnet","~/.stack","~/.ghcup","~/.opam","~/.pub-cache","~/.gitconfig","~/.config/git"]),z=Object.freeze(["/tmp","/private/tmp","~/.cache","~/.npm","~/.local/share/uv","~/.local/state"]),I=Object.freeze({codex:Object.freeze({hosts:["api.openai.com","chatgpt.com","auth.openai.com","*.openai.com"],write:["~/.codex"]}),claude:Object.freeze({hosts:["api.anthropic.com","*.anthropic.com","claude.ai","statsig.anthropic.com"],write:["~/.claude","~/.claude.json"]}),antigravity:Object.freeze({hosts:["*.googleapis.com","*.google.com","oauth2.googleapis.com"],write:["~/.gemini","~/.antigravity","~/.config/antigravity"]}),custom:Object.freeze({hosts:[],write:[]}),mcp:Object.freeze({hosts:[],write:[]}),extract:Object.freeze({hosts:[],write:[]}),"model-server":Object.freeze({hosts:["huggingface.co","*.huggingface.co","*.hf.co","cdn-lfs.huggingface.co","cas-bridge.xethub.hf.co","dl.chatpanel.net"],write:[]})}),N=Object.freeze(["github.com","*.github.com","*.githubusercontent.com","gitlab.com","bitbucket.org","registry.npmjs.org","pypi.org","files.pythonhosted.org","crates.io","static.crates.io","proxy.golang.org","sum.golang.org","huggingface.co","*.huggingface.co"]),w=e=>!!e&&typeof e=="object"&&!Array.isArray(e),E=e=>Array.isArray(e)&&e.every(t=>typeof t=="string"&&t.length>0),f=(e,t)=>{if(!e)throw new D("SHAPE",t)},p=e=>[...new Set(e)];function W(e){f(w(e),"kit: must be an object"),f(typeof e.id=="string"&&e.id.length>0,"kit: id required"),f(w(e.network)&&A.includes(e.network.mode),`kit ${e.id}: network.mode must be one of ${A.join(", ")}`),f(E(e.network.allowedDomains||[]),`kit ${e.id}: network.allowedDomains must be string[]`),f(E(e.network.deniedDomains||[]),`kit ${e.id}: network.deniedDomains must be string[]`),f(w(e.filesystem),`kit ${e.id}: filesystem required`);for(const t of["allowWrite","denyWrite","allowRead","denyRead"])f(E(e.filesystem[t]||[]),`kit ${e.id}: filesystem.${t} must be string[]`);return f(E(e.filesystem.allowWrite)&&e.filesystem.allowWrite.length>0,`kit ${e.id}: filesystem.allowWrite must name at least the working directory`),e.image!=null&&f(typeof e.image=="string",`kit ${e.id}: image must be a string`),e.credentials!=null&&f(Array.isArray(e.credentials)&&e.credentials.every(t=>w(t)&&typeof t.name=="string"&&typeof t.forHost=="string"),`kit ${e.id}: credentials must be [{ name, forHost }]`),{id:e.id,kind:e.kind||"process",image:e.image||null,network:{mode:e.network.mode,allowedDomains:p(e.network.allowedDomains||[]),deniedDomains:p(e.network.deniedDomains||[])},filesystem:{allowWrite:p(e.filesystem.allowWrite),denyWrite:p(e.filesystem.denyWrite||[]),allowRead:p(e.filesystem.allowRead||[]),denyRead:p(e.filesystem.denyRead||[])},credentials:e.credentials||[],limits:w(e.limits)?{...e.limits}:{}}}import{normalizeGrant as oe,mergeGrants as re,parseHostList as se}from"./sandbox-grant.js";function B({engine:e="custom",cwd:t,mode:n="open",extraHosts:r=[],extraWrite:o=[],extraDenyRead:i=[],grant:c=null,home:l="",reads:a="enumerated"}={}){const s=I[e]||I.custom;f(typeof t=="string"&&t.length>0,"kit: cwd required");const d=O(c);return W({id:`${e}:${n}`,kind:"process",network:{mode:n,allowedDomains:n==="open"?["*"]:n==="none"?[]:p([...s.hosts,...N,...r,...d.hosts]),deniedDomains:[]},filesystem:{allowWrite:p([t,...z,...s.write,...[...o,...d.write].filter(u=>!S(u,l))]),denyWrite:[],allowRead:a==="inverted"?p([t,...v,...s.write,...L({grant:d,extraWrite:o,cwd:t,home:l})]):[t],denyRead:p([...a==="inverted"?["~",...l?[l]:[]]:[],..._,...P,...i])}})}function L({grant:e=null,extraWrite:t=[],cwd:n="",home:r=""}={}){const o=s=>r&&(s==="~"||s.startsWith("~/")||s.startsWith("~\\"))?r+s.slice(1):s,i=s=>{let d=String(s||"").trim();for(;d.length>1&&(d.endsWith("/")||d.endsWith("\\"));)d=d.slice(0,-1);return d},c=(s,d)=>s===d||s.startsWith(`${d}/`)||s.startsWith(`${d}\\`),l=i(o(n)),a=[];for(const s of[...O(e).write,...Array.isArray(t)?t:[]]){const d=i(o(i(s)));if(d&&!S(d,r)&&!(l&&c(d,l))&&!a.some(u=>c(d,u))){for(let u=a.length-1;u>=0;u--)c(a[u],d)&&a.splice(u,1);a.push(d)}}return a}function q(e,{loopback:t=[],home:n="",platform:r="darwin"}={}){const o=W(e),i=l=>n&&l.startsWith("~")?n+l.slice(1):l,c=o.network.mode==="none"?[]:t.map(l=>`127.0.0.1:${l}`);return{network:{allowedDomains:p([...o.network.allowedDomains,...c]),deniedDomains:o.network.deniedDomains,allowLocalBinding:r==="darwin"&&c.length>0},filesystem:{denyRead:o.filesystem.denyRead.map(i),allowRead:o.filesystem.allowRead.map(i),allowWrite:o.filesystem.allowWrite.map(i),denyWrite:o.filesystem.denyWrite.map(i)}}}function X({layer:e="none",runtime:t=null,kitId:n=null,mode:r=null,reason:o=null,hosts:i=null}={}){return f(b.includes(e),`sandbox record: layer must be one of ${b.join(", ")}`),{layer:e,runtime:t,kit:n,mode:r,...e==="none"&&o?{reason:o}:{},...Array.isArray(i)&&i.length?{hosts:p(i)}:{}}}function T(e,{platform:t="darwin"}={}){const n=String(e);if(t==="win32"){f(!/[\r\n]/.test(n),"win32 command line: an argument holds a newline, which cmd.exe cannot carry");let r=n;if(n===""||/[ \t\v"]/.test(n)){r='"';for(let o=0;o<n.length;o++){let i=0;for(;o<n.length&&n[o]==="\\";)i++,o++;if(o===n.length){r+="\\".repeat(i*2);break}n[o]==='"'?r+="\\".repeat(i*2+1)+'"':r+="\\".repeat(i)+n[o]}r+='"'}return r.replace(/[()%!^"<>&|]/g,"^$&")}return n===""?"''":/^[A-Za-z0-9_\-./=:@%+,]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}const H=Object.freeze(["SSL_CERT_FILE","REQUESTS_CA_BUNDLE","CURL_CA_BUNDLE","GIT_SSL_CAINFO"]);function F(e={},{platform:t="darwin",caBundle:n=""}={}){const r={NODE_USE_ENV_PROXY:"1"};if(n)for(const o of H)e[o]||(r[o]=n);if(t==="linux")for(const o of["no_proxy","NO_PROXY"])typeof e[o]=="string"&&(r[o]=e[o].split(",").map(i=>i.trim()).filter(i=>i&&!/^(localhost|127\.0\.0\.1|::1|\[::1\])$/i.test(i)).join(","));return r}function V(e,t=[],{platform:n="darwin"}={}){return[e,...t].map(r=>T(r,{platform:n})).join(" ")}const Q=/[\\/]+/,m=e=>String(e||"").replace(/\//g,"\\").replace(/\\+$/,"").toLowerCase(),k=e=>/^[a-z]:$/i.test(m(e))||m(e)==="";function h(e,t){const n=m(e),r=m(t);return!!r&&n!==r&&n.startsWith(r+"\\")}function K(e){const t=String(e||"").replace(/\//g,"\\").split("\\");if(t.length<2)return"";const n=t.findIndex(r=>r.toLowerCase()==="node_modules");return(n>0?t.slice(0,n):t.slice(0,-1)).join("\\")}function Z({kit:e,files:t=[],home:n}){f(typeof n=="string"&&n.length>0,"windows grants: home required");const r=a=>(a.startsWith("~")?n+a.slice(1):a).replace(/\//g,"\\"),o=[];for(const a of e?.filesystem?.allowWrite||[]){const s=r(a);!/^[a-z]:\\/i.test(s)&&!s.startsWith("\\\\")||(f(!k(s)&&m(s)!==m(n),`windows grants: a write on ${s} would hand the sandbox account the whole profile`),h(s,n)&&o.push(s))}const i=(a,s)=>s.some(d=>m(a)===m(d)||h(a,d)),c=[];for(const a of t){const s=K(a);s&&h(s,n)&&c.push(s)}for(const a of e?.filesystem?.allowRead||[]){const s=r(a);h(s,n)&&c.push(s)}const l=p(c).filter(a=>!i(a,o));return{read:l.filter(a=>!l.some(s=>s!==a&&h(a,s))),write:p(o)}}const Y=Object.freeze(["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","CLAUDE_CONFIG_DIR","OPENAI_API_KEY","OPENAI_BASE_URL","OPENAI_API_BASE","CODEX_HOME","GEMINI_API_KEY","GOOGLE_API_KEY","DEEPSEEK_API_KEY","DSH_HOME","OPENROUTER_API_KEY","GROQ_API_KEY","XAI_API_KEY","MISTRAL_API_KEY"]);function J({engine:e="custom",home:t,env:n={},base:r={},carry:o=Y}={}){f(typeof t=="string"&&t.length>0,"windows env: home required");const i=t.replace(/\//g,"\\"),c=/^[a-z]:/i.test(i)?i.slice(0,2):"",l={USERPROFILE:i,...c?{HOMEDRIVE:c,HOMEPATH:i.slice(2)}:{}};for(const[a,s]of Object.entries(n))typeof s=="string"&&(r[a]!==s||o.includes(a))&&(l[a]=s);return e==="codex"&&!l.CODEX_HOME&&(l.CODEX_HOME=i+"\\.codex"),l}function ee(e,t){f(Array.isArray(e),"srt-win argv: must be an array");const n=e.indexOf("exec"),r=n>=0?e.indexOf("--",n+1):-1;f(n>=0&&r>n,"srt-win argv: expected `exec … -- <shell> <command>`");const o=new Set;for(let c=n+1;c<r;c++)e[c]==="--env"&&typeof e[c+1]=="string"&&o.add(e[c+1].split("=")[0].toUpperCase());const i=[];for(const[c,l]of Object.entries(t||{}))f(/^[A-Za-z_][A-Za-z0-9_]*$/.test(c),`srt-win env: bad key ${c}`),f(!/[\r\n]/.test(l),`srt-win env: ${c} holds a newline`),o.has(c.toUpperCase())||i.push("--env",`${c}=${l}`);return[...e.slice(0,r),...i,...e.slice(r)]}export{z as COMMON_WRITE,N as DEVELOPER_HOSTS,I as ENGINE_KITS,A as NETWORK_MODES,b as SANDBOX_LAYERS,_ as SECRET_PATHS,P as SECRET_READ_GLOBS,v as TOOLCHAIN_READ,Y as WINDOWS_CARRY_KEYS,S as isSecretWritePath,B as kitFor,re as mergeGrants,oe as normalizeGrant,se as parseHostList,F as sandboxEnvOverlay,X as sandboxRecord,V as shellJoin,T as shellQuote,q as toSrtSettings,h as underWindowsHome,W as validateKit,Z as windowsGrantsFor,K as windowsInstallRoot,J as windowsSandboxEnv,ee as withSrtWinEnv,L as writableRoots};
1
+ import{EventError as j}from"./event.js";import{normalizeGrant as A}from"./sandbox-grant.js";import{SECRET_DIR_NAMES as C,SECRET_DIR_PAIRS as P}from"./secret-names.js";const x=Object.freeze(["none","process","container","kubernetes"]),R=Object.freeze(["open","allowlist","none","gateway"]),y=Object.freeze(["~/.chatpanel","~/.ssh","~/.gnupg","~/.aws","~/.azure","~/.config/gcloud","~/.kube","~/.netrc","~/.docker/config.json","~/.npmrc","~/.pypirc"]),g=e=>{let t=String(e||"").trim();for(;t.length>1&&(t.endsWith("/")||t.endsWith("\\"));)t=t.slice(0,-1);return t},_=(e,t)=>t&&(e==="~"||e.startsWith("~/")||e.startsWith("~\\"))?t+e.slice(1):e,m=e=>String(e||"").replace(/\\/g,"/"),O=(e,t)=>{const n=m(g(e)),r=m(g(t));return!!n&&!!r&&(n===r||n.startsWith(`${r}/`))},L=y.map(e=>m(g(e)).replace(/^~\//,"").split("/").filter(Boolean));function S(e,t=""){const n=m(g(_(g(e),t)));if(!n)return!1;for(const o of y)if(O(n,o)||t&&O(n,_(o,t)))return!0;const r=n.split("/").filter(Boolean).map(o=>o.toLowerCase());return L.some(o=>{for(let i=0;i+o.length<=r.length;i+=1)if(o.every((c,l)=>c.toLowerCase()===r[i+l]))return!0;return!1})}const $=Object.freeze([...[...C].map(e=>`~/**/${e}`),...P.map(([e,t])=>`~/**/${e}/${t}`),...[".env",".netrc","_netrc",".git-credentials",".pgpass",".my.cnf",".npmrc",".pypirc",".htpasswd",".terraformrc",".vault-token","credentials","credentials.toml","id_rsa","id_dsa","id_ecdsa","id_ed25519","*.pem","*.p12","*.pfx","*.jks","*.keystore","*.kdbx","*.ppk"].map(e=>`~/**/${e}`)]);function F(e,{home:t="",globs:n=[...y,...$]}={}){const r=m(g(_(g(e),t)));if(!r)return null;const o=r.split("/").filter(Boolean),i=m(g(t));for(const c of n){const l=m(g(c));if(l){if(l.startsWith("~/**/")){if(i&&!O(r,i))continue;const a=l.slice(5).split("/").filter(Boolean).map(v);for(let s=0;s+a.length<=o.length;s+=1)if(a.every((f,p)=>f.test(o[s+p])))return c;continue}if(O(r,_(l,t)))return c}}return null}function v(e){return new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*")}$`,"i")}const I=".cache/chatpanel/ca-bundle.crt",X=".cache/chatpanel/ca-bundle.pem";function V(e=""){const t=m(g(e));return t?`${t}/${I}`:`~/${I}`}const N=Object.freeze(["~/.npm","~/.cache","~/.local","~/Library/Caches","~/.nvm","~/.volta","~/.asdf","~/.nodenv","~/.bun","~/.deno","~/.pyenv","~/.rye","~/.pdm","~/.cargo","~/.rustup","~/go","~/.goenv","~/.m2","~/.gradle","~/.sdkman","~/.jenv","~/.gem","~/.rbenv","~/.bundle","~/.composer","~/.nuget","~/.dotnet","~/.stack","~/.ghcup","~/.opam","~/.pub-cache","~/.gitconfig","~/.config/git"]),z=Object.freeze(["/tmp","/private/tmp","~/.cache","~/.npm","~/.local/share/uv","~/.local/state"]),W=Object.freeze({codex:Object.freeze({hosts:["api.openai.com","chatgpt.com","auth.openai.com","*.openai.com"],write:["~/.codex"]}),claude:Object.freeze({hosts:["api.anthropic.com","*.anthropic.com","claude.ai","statsig.anthropic.com"],write:["~/.claude","~/.claude.json"]}),antigravity:Object.freeze({hosts:["*.googleapis.com","*.google.com","oauth2.googleapis.com"],write:["~/.gemini","~/.antigravity","~/.config/antigravity"]}),custom:Object.freeze({hosts:[],write:[]}),mcp:Object.freeze({hosts:[],write:[]}),extract:Object.freeze({hosts:[],write:[]}),"model-server":Object.freeze({hosts:["huggingface.co","*.huggingface.co","*.hf.co","cdn-lfs.huggingface.co","cas-bridge.xethub.hf.co","dl.chatpanel.net"],write:[]})}),T=Object.freeze(["github.com","*.github.com","*.githubusercontent.com","gitlab.com","bitbucket.org","registry.npmjs.org","pypi.org","files.pythonhosted.org","crates.io","static.crates.io","proxy.golang.org","sum.golang.org","huggingface.co","*.huggingface.co"]),h=e=>!!e&&typeof e=="object"&&!Array.isArray(e),b=e=>Array.isArray(e)&&e.every(t=>typeof t=="string"&&t.length>0),d=(e,t)=>{if(!e)throw new j("SHAPE",t)},u=e=>[...new Set(e)];function D(e){d(h(e),"kit: must be an object"),d(typeof e.id=="string"&&e.id.length>0,"kit: id required"),d(h(e.network)&&R.includes(e.network.mode),`kit ${e.id}: network.mode must be one of ${R.join(", ")}`),d(b(e.network.allowedDomains||[]),`kit ${e.id}: network.allowedDomains must be string[]`),d(b(e.network.deniedDomains||[]),`kit ${e.id}: network.deniedDomains must be string[]`),d(h(e.filesystem),`kit ${e.id}: filesystem required`);for(const t of["allowWrite","denyWrite","allowRead","denyRead"])d(b(e.filesystem[t]||[]),`kit ${e.id}: filesystem.${t} must be string[]`);return d(b(e.filesystem.allowWrite)&&e.filesystem.allowWrite.length>0,`kit ${e.id}: filesystem.allowWrite must name at least the working directory`),e.image!=null&&d(typeof e.image=="string",`kit ${e.id}: image must be a string`),e.credentials!=null&&d(Array.isArray(e.credentials)&&e.credentials.every(t=>h(t)&&typeof t.name=="string"&&typeof t.forHost=="string"),`kit ${e.id}: credentials must be [{ name, forHost }]`),{id:e.id,kind:e.kind||"process",image:e.image||null,network:{mode:e.network.mode,allowedDomains:u(e.network.allowedDomains||[]),deniedDomains:u(e.network.deniedDomains||[])},filesystem:{allowWrite:u(e.filesystem.allowWrite),denyWrite:u(e.filesystem.denyWrite||[]),allowRead:u(e.filesystem.allowRead||[]),denyRead:u(e.filesystem.denyRead||[])},credentials:e.credentials||[],limits:h(e.limits)?{...e.limits}:{}}}import{normalizeGrant as ce,mergeGrants as le,parseHostList as fe}from"./sandbox-grant.js";function Q({engine:e="custom",cwd:t,mode:n="open",extraHosts:r=[],extraWrite:o=[],extraDenyRead:i=[],grant:c=null,home:l="",reads:a="enumerated"}={}){const s=W[e]||W.custom;d(typeof t=="string"&&t.length>0,"kit: cwd required");const f=A(c);return D({id:`${e}:${n}`,kind:"process",network:{mode:n,allowedDomains:n==="open"?["*"]:n==="none"?[]:u([...s.hosts,...T,...r,...f.hosts]),deniedDomains:[]},filesystem:{allowWrite:u([t,...z,...s.write,...[...o,...f.write].filter(p=>!S(p,l))]),denyWrite:[],allowRead:a==="inverted"?u([t,...N,...s.write,...H({grant:f,extraWrite:o,cwd:t,home:l})]):[t],denyRead:u([...a==="inverted"?["~",...l?[l]:[]]:[],...y,...$,...i])}})}function H({grant:e=null,extraWrite:t=[],cwd:n="",home:r=""}={}){const o=s=>r&&(s==="~"||s.startsWith("~/")||s.startsWith("~\\"))?r+s.slice(1):s,i=s=>{let f=String(s||"").trim();for(;f.length>1&&(f.endsWith("/")||f.endsWith("\\"));)f=f.slice(0,-1);return f},c=(s,f)=>s===f||s.startsWith(`${f}/`)||s.startsWith(`${f}\\`),l=i(o(n)),a=[];for(const s of[...A(e).write,...Array.isArray(t)?t:[]]){const f=i(o(i(s)));if(f&&!S(f,r)&&!(l&&c(f,l))&&!a.some(p=>c(f,p))){for(let p=a.length-1;p>=0;p--)c(a[p],f)&&a.splice(p,1);a.push(f)}}return a}function Z(e,{loopback:t=[],home:n="",platform:r="darwin"}={}){const o=D(e),i=l=>n&&l.startsWith("~")?n+l.slice(1):l,c=o.network.mode==="none"?[]:t.map(l=>`127.0.0.1:${l}`);return{network:{allowedDomains:u([...o.network.allowedDomains,...c]),deniedDomains:o.network.deniedDomains,allowLocalBinding:r==="darwin"&&c.length>0},filesystem:{denyRead:o.filesystem.denyRead.map(i),allowRead:o.filesystem.allowRead.map(i),allowWrite:o.filesystem.allowWrite.map(i),denyWrite:o.filesystem.denyWrite.map(i)}}}function J({layer:e="none",runtime:t=null,kitId:n=null,mode:r=null,reason:o=null,hosts:i=null}={}){return d(x.includes(e),`sandbox record: layer must be one of ${x.join(", ")}`),{layer:e,runtime:t,kit:n,mode:r,...e==="none"&&o?{reason:o}:{},...Array.isArray(i)&&i.length?{hosts:u(i)}:{}}}function k(e,{platform:t="darwin"}={}){const n=String(e);if(t==="win32"){d(!/[\r\n]/.test(n),"win32 command line: an argument holds a newline, which cmd.exe cannot carry");let r=n;if(n===""||/[ \t\v"]/.test(n)){r='"';for(let o=0;o<n.length;o++){let i=0;for(;o<n.length&&n[o]==="\\";)i++,o++;if(o===n.length){r+="\\".repeat(i*2);break}n[o]==='"'?r+="\\".repeat(i*2+1)+'"':r+="\\".repeat(i)+n[o]}r+='"'}return r.replace(/[()%!^"<>&|]/g,"^$&")}return n===""?"''":/^[A-Za-z0-9_\-./=:@%+,]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}const K=Object.freeze(["SSL_CERT_FILE","REQUESTS_CA_BUNDLE","CURL_CA_BUNDLE","GIT_SSL_CAINFO"]);function ee(e={},{platform:t="darwin",caBundle:n=""}={}){const r={NODE_USE_ENV_PROXY:"1"};if(n)for(const o of K)e[o]||(r[o]=n);if(t==="linux")for(const o of["no_proxy","NO_PROXY"])typeof e[o]=="string"&&(r[o]=e[o].split(",").map(i=>i.trim()).filter(i=>i&&!/^(localhost|127\.0\.0\.1|::1|\[::1\])$/i.test(i)).join(","));return r}function te(e,t=[],{platform:n="darwin"}={}){return[e,...t].map(r=>k(r,{platform:n})).join(" ")}const ne=/[\\/]+/,w=e=>String(e||"").replace(/\//g,"\\").replace(/\\+$/,"").toLowerCase(),U=e=>/^[a-z]:$/i.test(w(e))||w(e)==="";function E(e,t){const n=w(e),r=w(t);return!!r&&n!==r&&n.startsWith(r+"\\")}function Y(e){const t=String(e||"").replace(/\//g,"\\").split("\\");if(t.length<2)return"";const n=t.findIndex(r=>r.toLowerCase()==="node_modules");return(n>0?t.slice(0,n):t.slice(0,-1)).join("\\")}function oe({kit:e,files:t=[],home:n}){d(typeof n=="string"&&n.length>0,"windows grants: home required");const r=a=>(a.startsWith("~")?n+a.slice(1):a).replace(/\//g,"\\"),o=[];for(const a of e?.filesystem?.allowWrite||[]){const s=r(a);!/^[a-z]:\\/i.test(s)&&!s.startsWith("\\\\")||(d(!U(s)&&w(s)!==w(n),`windows grants: a write on ${s} would hand the sandbox account the whole profile`),E(s,n)&&o.push(s))}const i=(a,s)=>s.some(f=>w(a)===w(f)||E(a,f)),c=[];for(const a of t){const s=Y(a);s&&E(s,n)&&c.push(s)}for(const a of e?.filesystem?.allowRead||[]){const s=r(a);E(s,n)&&c.push(s)}const l=u(c).filter(a=>!i(a,o));return{read:l.filter(a=>!l.some(s=>s!==a&&E(a,s))),write:u(o)}}const B=Object.freeze(["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","CLAUDE_CONFIG_DIR","OPENAI_API_KEY","OPENAI_BASE_URL","OPENAI_API_BASE","CODEX_HOME","GEMINI_API_KEY","GOOGLE_API_KEY","DEEPSEEK_API_KEY","DSH_HOME","OPENROUTER_API_KEY","GROQ_API_KEY","XAI_API_KEY","MISTRAL_API_KEY"]);function re({engine:e="custom",home:t,env:n={},base:r={},carry:o=B}={}){d(typeof t=="string"&&t.length>0,"windows env: home required");const i=t.replace(/\//g,"\\"),c=/^[a-z]:/i.test(i)?i.slice(0,2):"",l={USERPROFILE:i,...c?{HOMEDRIVE:c,HOMEPATH:i.slice(2)}:{}};for(const[a,s]of Object.entries(n))typeof s=="string"&&(r[a]!==s||o.includes(a))&&(l[a]=s);return e==="codex"&&!l.CODEX_HOME&&(l.CODEX_HOME=i+"\\.codex"),l}function se(e,t){d(Array.isArray(e),"srt-win argv: must be an array");const n=e.indexOf("exec"),r=n>=0?e.indexOf("--",n+1):-1;d(n>=0&&r>n,"srt-win argv: expected `exec … -- <shell> <command>`");const o=new Set;for(let c=n+1;c<r;c++)e[c]==="--env"&&typeof e[c+1]=="string"&&o.add(e[c+1].split("=")[0].toUpperCase());const i=[];for(const[c,l]of Object.entries(t||{}))d(/^[A-Za-z_][A-Za-z0-9_]*$/.test(c),`srt-win env: bad key ${c}`),d(!/[\r\n]/.test(l),`srt-win env: ${c} holds a newline`),o.has(c.toUpperCase())||i.push("--env",`${c}=${l}`);return[...e.slice(0,r),...i,...e.slice(r)]}export{I as CA_BUNDLE_RELPATH,X as CA_BUNDLE_RELPATH_LEGACY,z as COMMON_WRITE,T as DEVELOPER_HOSTS,W as ENGINE_KITS,R as NETWORK_MODES,x as SANDBOX_LAYERS,y as SECRET_PATHS,$ as SECRET_READ_GLOBS,N as TOOLCHAIN_READ,B as WINDOWS_CARRY_KEYS,V as caBundlePath,S as isSecretWritePath,Q as kitFor,le as mergeGrants,ce as normalizeGrant,fe as parseHostList,F as readDenialFor,ee as sandboxEnvOverlay,J as sandboxRecord,te as shellJoin,k as shellQuote,Z as toSrtSettings,E as underWindowsHome,D as validateKit,oe as windowsGrantsFor,Y as windowsInstallRoot,re as windowsSandboxEnv,se as withSrtWinEnv,H as writableRoots};