@chatpanel/events 0.354.0 → 0.358.2
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/access-request.js +1 -1
- package/agent-permission.js +2 -2
- package/agent-run-hint.js +1 -1
- package/date-filter.js +1 -0
- package/feature-map.js +1 -1
- package/harness-cards.js +1 -1
- package/index.js +1 -1
- package/link-fetch.js +1 -0
- package/link-protocol.js +1 -1
- package/link-routes.js +2 -2
- package/link-scopes.js +1 -0
- package/omni.js +1 -1
- package/package.json +11 -1
- package/policy.js +1 -1
- package/record-list.js +2 -2
- package/retrieval-plan.js +2 -2
- package/runtime-host.js +1 -0
- package/sandbox-choice.js +1 -0
- package/sandbox-grant.js +1 -1
- package/sandbox-policy.js +1 -1
- package/settings-registry.js +1 -1
- package/voice-barge-in.cases.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatpanel/events",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.358.2",
|
|
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",
|
|
@@ -133,6 +133,8 @@
|
|
|
133
133
|
"./link-connect.js": "./link-connect.js",
|
|
134
134
|
"./link-sync.js": "./link-sync.js",
|
|
135
135
|
"./link-routes.js": "./link-routes.js",
|
|
136
|
+
"./link-scopes.js": "./link-scopes.js",
|
|
137
|
+
"./link-fetch.js": "./link-fetch.js",
|
|
136
138
|
"./qr.js": "./qr.js",
|
|
137
139
|
"./record-entities.js": "./record-entities.js",
|
|
138
140
|
"./decide-by-model.js": "./decide-by-model.js",
|
|
@@ -162,6 +164,7 @@
|
|
|
162
164
|
"./response-language.js": "./response-language.js",
|
|
163
165
|
"./recruit.js": "./recruit.js",
|
|
164
166
|
"./record-list.js": "./record-list.js",
|
|
167
|
+
"./date-filter.js": "./date-filter.js",
|
|
165
168
|
"./redaction-dictionary.js": "./redaction-dictionary.js",
|
|
166
169
|
"./redaction-tokens.js": "./redaction-tokens.js",
|
|
167
170
|
"./ref.js": "./ref.js",
|
|
@@ -305,6 +308,8 @@
|
|
|
305
308
|
"./read-document.js": "./read-document.js",
|
|
306
309
|
"./serp-anchors.js": "./serp-anchors.js",
|
|
307
310
|
"./search-searxng.js": "./search-searxng.js",
|
|
311
|
+
"./runtime-host.js": "./runtime-host.js",
|
|
312
|
+
"./sandbox-choice.js": "./sandbox-choice.js",
|
|
308
313
|
"./sandbox-policy.js": "./sandbox-policy.js",
|
|
309
314
|
"./secret-names.js": "./secret-names.js",
|
|
310
315
|
"./sandbox-grant.js": "./sandbox-grant.js"
|
|
@@ -440,6 +445,8 @@
|
|
|
440
445
|
"link-connect.js",
|
|
441
446
|
"link-sync.js",
|
|
442
447
|
"link-routes.js",
|
|
448
|
+
"link-scopes.js",
|
|
449
|
+
"link-fetch.js",
|
|
443
450
|
"qr.js",
|
|
444
451
|
"record-entities.js",
|
|
445
452
|
"decide-by-model.js",
|
|
@@ -489,6 +496,7 @@
|
|
|
489
496
|
"response-language.js",
|
|
490
497
|
"recruit.js",
|
|
491
498
|
"record-list.js",
|
|
499
|
+
"date-filter.js",
|
|
492
500
|
"redaction-dictionary.js",
|
|
493
501
|
"redaction-tokens.js",
|
|
494
502
|
"ref.js",
|
|
@@ -612,6 +620,8 @@
|
|
|
612
620
|
"read-document.js",
|
|
613
621
|
"serp-anchors.js",
|
|
614
622
|
"search-searxng.js",
|
|
623
|
+
"runtime-host.js",
|
|
624
|
+
"sandbox-choice.js",
|
|
615
625
|
"sandbox-policy.js",
|
|
616
626
|
"secret-names.js",
|
|
617
627
|
"sandbox-grant.js"
|
package/policy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class a extends Error{constructor(n){super(n),this.name="PolicyError"}}const x=1,S="policy",d=Object.freeze(["off","basic","full"]),A=Object.freeze({off:0,basic:1,full:2}),O=Object.freeze(["gateway","endpoints","redaction","features","agents"]),k=Object.freeze(["webllm","meetings","channels","agents"]),y=Object.freeze(["plan","default","acceptEdits","bypassPermissions"]),E=Object.freeze({plan:0,default:1,acceptEdits:2,bypassPermissions:3}),T=Object.freeze(["api.chatpanel.net","dl.chatpanel.net","huggingface.co","registry.npmjs.org","api.github.com"]),f=e=>typeof e=="string"?e.trim():"",c=e=>Array.isArray(e)?e.map(f).filter(Boolean):[];function h(e){const n=f(e).toLowerCase().replace(/^https?:\/\//,"").replace(/\/.*$/,"");if(!n)return"";if(!/^(\*\.)?[a-z0-9.-]+(:\d{1,5})?$/.test(n)&&!/^\[[0-9a-f:]+\](:\d{1,5})?$/.test(n)&&n!=="*")throw new a(`invalid host pattern "${e}"`);return n}function b(e){if(e==null)return b({});if(typeof e!="object"||Array.isArray(e))throw new a("policy must be an object");const n=e.v==null?x:Number(e.v);if(n!==x)throw new a(`unsupported policy version ${e.v}`);const t={v:n};if(e.org!=null){const r=f(e.org.id);if(!r||!/^[a-z0-9][a-z0-9._-]{0,63}$/i.test(r))throw new a("org.id must be a short identifier");t.org={id:r,name:f(e.org.name)||r}}const o=(r,s)=>{if(r==null)return;if(typeof r!="object")throw new a(`${s} must be an object`);const u={};return r.allow!=null&&(u.allow=c(r.allow).map(h).filter(Boolean)),r.deny!=null&&(u.deny=c(r.deny).map(h).filter(Boolean)),u},i=o(e.endpoints,"endpoints");i&&(t.endpoints=i);const l=o(e.egress,"egress");if(l&&(t.egress=l),e.models!=null){if(typeof e.models!="object")throw new a("models must be an object");t.models={},e.models.allow!=null&&(t.models.allow=c(e.models.allow)),e.models.deny!=null&&(t.models.deny=c(e.models.deny))}if(e.agents!=null){if(typeof e.agents!="object")throw new a("agents must be an object");const r={};if(e.agents.allow!=null&&(r.allow=c(e.agents.allow).map(s=>s.toLowerCase())),e.agents.deny!=null&&(r.deny=c(e.agents.deny).map(s=>s.toLowerCase())),e.agents.permissionModeCap!=null){const s=f(e.agents.permissionModeCap);if(!y.includes(s))throw new a(`agents.permissionModeCap must be one of ${y.join(", ")}`);r.permissionModeCap=s}t.agents=r}if(e.routing!=null){if(typeof e.routing!="object")throw new a("routing must be an object");const r=Array.isArray(e.routing.rules)?e.routing.rules:[];t.routing={rules:r.map((s,u)=>{if(!s||typeof s!="object")throw new a(`routing.rules[${u}] must be an object`);const g=c(s.models),$=c(s.endpoints).map(h).filter(Boolean);if(!g.length)throw new a(`routing.rules[${u}] needs at least one model pattern`);if(!$.length)throw new a(`routing.rules[${u}] needs at least one endpoint`);return{models:g,endpoints:$}})}}if(e.redaction!=null){if(typeof e.redaction!="object")throw new a("redaction must be an object");const r={};if(e.redaction.floor!=null){const s=f(e.redaction.floor).toLowerCase();if(!d.includes(s))throw new a(`redaction.floor must be one of ${d.join(", ")}`);r.floor=s}e.redaction.dictionary!=null&&(r.dictionary=c(e.redaction.dictionary)),e.redaction.requireBeforeCloud!=null&&(r.requireBeforeCloud=!!e.redaction.requireBeforeCloud),t.redaction=r}if(e.client!=null){if(typeof e.client!="object")throw new a("client must be an object");const r={};if(e.client.gatewayUrl!=null){const s=f(e.client.gatewayUrl);if(s&&!/^https?:\/\/[^\s/]+(\/.*)?$/.test(s))throw new a("client.gatewayUrl must be an http(s) URL");r.gatewayUrl=s.replace(/\/+$/,"")}if(e.client.managedRequired!=null&&(r.managedRequired=!!e.client.managedRequired),e.client.lock!=null){const s=c(e.client.lock);for(const u of s)if(!O.includes(u))throw new a(`client.lock: unknown setting "${u}" (one of ${O.join(", ")})`);r.lock=[...new Set(s)]}if(e.client.features!=null){if(typeof e.client.features!="object")throw new a("client.features must be an object");r.features={};for(const[s,u]of Object.entries(e.client.features)){if(!k.includes(s))throw new a(`client.features: unknown feature "${s}" (one of ${k.join(", ")})`);r.features[s]=!!u}}t.client=r}if(e.access!=null){if(typeof e.access!="object"||Array.isArray(e.access))throw new a("access must be an object");const r={};if(e.access.delegation!=null){const s=f(e.access.delegation);if(!C.includes(s))throw new a(`access.delegation must be one of ${C.join(", ")}`);r.delegation=s}for(const s of["deny","allow"]){if(e.access[s]==null)continue;const u=c(e.access[s]).map(g=>String(g).trim()).filter(Boolean);for(const g of u)if(g.length>1024||g.includes("\0"))throw new a(`access.${s}: not a path`);r[s]=u}Object.keys(r).length&&(t.access=r)}return t}const C=Object.freeze(["allowed","never"]);function I(e){return e?.access?.delegation==="never"?"never":"allowed"}function p(e){const n=f(e).toLowerCase();if(!n)return{host:"",port:""};try{const t=new URL(/^[a-z][a-z0-9+.-]*:\/\//.test(n)?n:`http://${n}`);return{host:t.hostname.replace(/^\[|\]$/g,""),port:t.port||(t.protocol==="https:"?"443":t.protocol==="http:"?"80":"")}}catch{return{host:n.split(":")[0],port:""}}}function R(e,n,t){if(e==="*")return!0;const[o,i]=e.startsWith("[")?[e.replace(/^\[([^\]]+)\].*$/,"$1"),e.replace(/^\[[^\]]+\]:?/,"")]:(()=>{const l=e.lastIndexOf(":");return l>0?[e.slice(0,l),e.slice(l+1)]:[e,""]})();if(i&&i!==t)return!1;if(o.startsWith("*.")){const l=o.slice(1);return n.endsWith(l)&&n.length>l.length}return n===o}function w(e,n,t){return(e||[]).some(o=>R(o,n,t))}function m(e){return new RegExp(`^${String(e).split("*").map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*")}$`,"i")}function U(e,n){const t=e?.endpoints;if(!t)return!0;const{host:o,port:i}=p(n);return!o||w(t.deny,o,i)?!1:t.allow&&t.allow.length?w(t.allow,o,i):!0}function z(e,n){const t=e?.models;if(!t)return!0;const o=f(n);return(t.deny||[]).some(i=>m(i).test(o))?!1:t.allow&&t.allow.length?t.allow.some(i=>m(i).test(o)):!0}function L(e,n){const t=e?.agents;if(!t)return!0;const o=f(n).toLowerCase();return(t.deny||[]).includes(o)?!1:t.allow&&t.allow.length?t.allow.includes(o):!0}function N(e,n){const t=e?.agents?.permissionModeCap,o=y.includes(n)?n:"default";return t?E[o]<=E[t]?o:t:o}function _(e,{model:n="",endpoint:t=""}={}){if(!e)return{ok:!0,reason:""};if(n&&!z(e,n))return{ok:!1,reason:`model "${n}" is not allowed by your organisation's policy`};if(t&&!U(e,t))return{ok:!1,reason:`endpoint ${p(t).host} is not allowed by your organisation's policy`};const o=e.routing?.rules||[];if(n&&t&&o.length){const i=o.find(l=>l.models.some(r=>m(r).test(n)));if(i){const{host:l,port:r}=p(t);if(!w(i.endpoints,l,r))return{ok:!1,reason:`model "${n}" may only be sent to ${i.endpoints.join(", ")} under your organisation's policy`}}}return{ok:!0,reason:""}}function P(e,n){const t=e?.redaction?.floor,o=d.includes(n)?n:"basic";return t?A[o]>=A[t]?o:t:o}function B(e,n,{local:t=!1}={}){const o=e?.egress;if(!o)return!0;const{host:i,port:l}=p(n);return!i||w(o.deny,i,l)?!1:t||T.includes(i)||e.endpoints?.allow?.length&&w(e.endpoints.allow,i,l)&&!w(e.endpoints?.deny,i,l)?!0:w(o.allow,i,l)}function q(e,n){return!!e?.client?.lock?.includes(n)}function M(e,n){const t=e?.client?.features;return!t||t[n]==null?!0:!!t[n]}function v(e,n){const t={...n||{}},o=[];if(!e)return{settings:t,changed:o};const i=e.client||{};if(i.gatewayUrl&&t.gatewayUrl!==i.gatewayUrl&&(t.gatewayUrl=i.gatewayUrl,o.push("gatewayUrl")),Array.isArray(t.endpoints)&&e.endpoints){const l=t.endpoints.filter(r=>!r||typeof r!="object"?!1:!r.baseUrl||i.gatewayUrl&&p(r.baseUrl).host===p(i.gatewayUrl).host&&p(r.baseUrl).port===p(i.gatewayUrl).port?!0:U(e,r.baseUrl));l.length!==t.endpoints.length&&(t.endpoints=l,o.push("endpoints"))}if(Array.isArray(t.endpoints)&&e.agents){const l=t.endpoints.filter(r=>r?.kind!=="bridge"||L(e,r.bridgeAgent||r.agent||r.id));l.length!==t.endpoints.length&&(t.endpoints=l,o.push("agents"))}if(Array.isArray(t.endpoints)&&!M(e,"webllm")){const l=t.endpoints.filter(r=>r?.kind!=="webllm");l.length!==t.endpoints.length&&(t.endpoints=l,o.push("webllm"))}if(e.redaction?.floor&&(t.redaction?.tier!=null||t.redactionTier!=null)){const l=t.redaction?.tier!=null?t.redaction.tier:t.redactionTier,r=P(e,l);r!==l&&(t.redaction?.tier!=null?t.redaction={...t.redaction,tier:r}:t.redactionTier=r,o.push("redaction"))}return{settings:t,changed:o}}function D(e){const n=e?.org?.name||e?.org?.id;return n?`Managed by ${n}`:"Managed"}function j(e){return Array.isArray(e)?`[${e.map(j).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${j(e[n])}`).join(",")}}`:JSON.stringify(e)}async function H(e,{subtle:n=null}={}){const t=n||globalThis.crypto?.subtle;if(!t)throw new a("no WebCrypto available on this runtime");const o=new TextEncoder().encode(j(b(e))),i=await t.digest("SHA-256",o);return[...new Uint8Array(i)].map(l=>l.toString(16).padStart(2,"0")).join("")}async function K(e,{verify:n,...t}={}){if(typeof n!="function")throw new a("verifyPolicyToken needs a verify function (entitlement.js verifySignedToken)");const o=await n(e,{...t,typ:S});if(!o||!o.policy)return null;try{return b(o.policy)}catch{return null}}export{C as ACCESS_DELEGATION,k as FEATURES,O as LOCKABLE,y as PERMISSION_MODES,S as POLICY_TOKEN_TYPE,x as POLICY_VERSION,T as PRODUCT_HOSTS,a as PolicyError,d as REDACTION_TIERS,I as accessDelegation,L as agentAllowed,v as applyPolicyToSettings,B as egressAllowed,U as endpointAllowed,M as featureEnabled,m as globToRegExp,z as modelAllowed,b as normalizeOrgPolicy,N as permissionMode,H as policyHash,D as policyLabel,P as redactionTier,_ as routeAllowed,q as settingLocked,K as verifyPolicyToken};
|
|
1
|
+
import{SANDBOX_RUNTIMES as A,SANDBOX_READ_MODES as $,parseWrapperTemplate as R}from"./sandbox-choice.js";class l extends Error{constructor(r){super(r),this.name="PolicyError"}}const O=1,z="policy",w=Object.freeze(["off","basic","full"]),k=Object.freeze({off:0,basic:1,full:2}),E=Object.freeze(["gateway","endpoints","redaction","features","agents"]),S=Object.freeze(["webllm","meetings","channels","agents"]),m=Object.freeze(["plan","default","acceptEdits","bypassPermissions"]),U=Object.freeze({plan:0,default:1,acceptEdits:2,bypassPermissions:3}),L=Object.freeze(["api.chatpanel.net","dl.chatpanel.net","huggingface.co","registry.npmjs.org","api.github.com"]),f=e=>typeof e=="string"?e.trim():"",c=e=>Array.isArray(e)?e.map(f).filter(Boolean):[];function b(e){const r=f(e).toLowerCase().replace(/^https?:\/\//,"").replace(/\/.*$/,"");if(!r)return"";if(!/^(\*\.)?[a-z0-9.-]+(:\d{1,5})?$/.test(r)&&!/^\[[0-9a-f:]+\](:\d{1,5})?$/.test(r)&&r!=="*")throw new l(`invalid host pattern "${e}"`);return r}function y(e){if(e==null)return y({});if(typeof e!="object"||Array.isArray(e))throw new l("policy must be an object");const r=e.v==null?O:Number(e.v);if(r!==O)throw new l(`unsupported policy version ${e.v}`);const n={v:r};if(e.org!=null){const t=f(e.org.id);if(!t||!/^[a-z0-9][a-z0-9._-]{0,63}$/i.test(t))throw new l("org.id must be a short identifier");n.org={id:t,name:f(e.org.name)||t}}const o=(t,s)=>{if(t==null)return;if(typeof t!="object")throw new l(`${s} must be an object`);const u={};return t.allow!=null&&(u.allow=c(t.allow).map(b).filter(Boolean)),t.deny!=null&&(u.deny=c(t.deny).map(b).filter(Boolean)),u},a=o(e.endpoints,"endpoints");a&&(n.endpoints=a);const i=o(e.egress,"egress");if(i&&(n.egress=i),e.models!=null){if(typeof e.models!="object")throw new l("models must be an object");n.models={},e.models.allow!=null&&(n.models.allow=c(e.models.allow)),e.models.deny!=null&&(n.models.deny=c(e.models.deny))}if(e.agents!=null){if(typeof e.agents!="object")throw new l("agents must be an object");const t={};if(e.agents.allow!=null&&(t.allow=c(e.agents.allow).map(s=>s.toLowerCase())),e.agents.deny!=null&&(t.deny=c(e.agents.deny).map(s=>s.toLowerCase())),e.agents.permissionModeCap!=null){const s=f(e.agents.permissionModeCap);if(!m.includes(s))throw new l(`agents.permissionModeCap must be one of ${m.join(", ")}`);t.permissionModeCap=s}n.agents=t}if(e.routing!=null){if(typeof e.routing!="object")throw new l("routing must be an object");const t=Array.isArray(e.routing.rules)?e.routing.rules:[];n.routing={rules:t.map((s,u)=>{if(!s||typeof s!="object")throw new l(`routing.rules[${u}] must be an object`);const p=c(s.models),j=c(s.endpoints).map(b).filter(Boolean);if(!p.length)throw new l(`routing.rules[${u}] needs at least one model pattern`);if(!j.length)throw new l(`routing.rules[${u}] needs at least one endpoint`);return{models:p,endpoints:j}})}}if(e.redaction!=null){if(typeof e.redaction!="object")throw new l("redaction must be an object");const t={};if(e.redaction.floor!=null){const s=f(e.redaction.floor).toLowerCase();if(!w.includes(s))throw new l(`redaction.floor must be one of ${w.join(", ")}`);t.floor=s}e.redaction.dictionary!=null&&(t.dictionary=c(e.redaction.dictionary)),e.redaction.requireBeforeCloud!=null&&(t.requireBeforeCloud=!!e.redaction.requireBeforeCloud),n.redaction=t}if(e.client!=null){if(typeof e.client!="object")throw new l("client must be an object");const t={};if(e.client.gatewayUrl!=null){const s=f(e.client.gatewayUrl);if(s&&!/^https?:\/\/[^\s/]+(\/.*)?$/.test(s))throw new l("client.gatewayUrl must be an http(s) URL");t.gatewayUrl=s.replace(/\/+$/,"")}if(e.client.managedRequired!=null&&(t.managedRequired=!!e.client.managedRequired),e.client.lock!=null){const s=c(e.client.lock);for(const u of s)if(!E.includes(u))throw new l(`client.lock: unknown setting "${u}" (one of ${E.join(", ")})`);t.lock=[...new Set(s)]}if(e.client.features!=null){if(typeof e.client.features!="object")throw new l("client.features must be an object");t.features={};for(const[s,u]of Object.entries(e.client.features)){if(!S.includes(s))throw new l(`client.features: unknown feature "${s}" (one of ${S.join(", ")})`);t.features[s]=!!u}}n.client=t}if(e.sandbox!=null){if(typeof e.sandbox!="object"||Array.isArray(e.sandbox))throw new l("sandbox must be an object");const t={};if(e.sandbox.required!=null&&(t.required=!!e.sandbox.required),e.sandbox.runtime!=null){const s=f(e.sandbox.runtime);if(!A.includes(s))throw new l(`sandbox.runtime must be one of ${A.join(", ")}`);t.runtime=s}if(e.sandbox.command!=null)try{t.command=R(e.sandbox.command)}catch(s){throw new l(s.message)}if(e.sandbox.image!=null){const s=f(e.sandbox.image);if(!/^[A-Za-z0-9][A-Za-z0-9._\/:@-]{0,254}$/.test(s))throw new l("sandbox.image must be an image reference");t.image=s}if(e.sandbox.reads!=null){const s=f(e.sandbox.reads);if(!$.includes(s))throw new l(`sandbox.reads must be one of ${$.join(", ")}`);t.reads=s}if(e.sandbox.mode!=null){const s=f(e.sandbox.mode);if(!["open","allowlist"].includes(s))throw new l("sandbox.mode must be open or allowlist (an org that sandboxes agents itself sets runtime: managed)");t.mode=s}if(t.runtime==="command"&&!t.command)throw new l("sandbox.runtime command needs sandbox.command");if(t.runtime==="container"&&!t.image)throw new l("sandbox.runtime container needs sandbox.image");Object.keys(t).length&&(n.sandbox=t)}if(e.gateway!=null){if(typeof e.gateway!="object"||Array.isArray(e.gateway))throw new l("gateway must be an object");e.gateway.confined!=null&&(n.gateway={confined:!!e.gateway.confined})}if(e.access!=null){if(typeof e.access!="object"||Array.isArray(e.access))throw new l("access must be an object");const t={};if(e.access.delegation!=null){const s=f(e.access.delegation);if(!C.includes(s))throw new l(`access.delegation must be one of ${C.join(", ")}`);t.delegation=s}for(const s of["deny","allow"]){if(e.access[s]==null)continue;const u=c(e.access[s]).map(p=>String(p).trim()).filter(Boolean);for(const p of u)if(p.length>1024||p.includes("\0"))throw new l(`access.${s}: not a path`);t[s]=u}Object.keys(t).length&&(n.access=t)}return n}function I(e={},r=null){const n=r?.sandbox||{},o={...e},a=[];for(const i of["runtime","command","image","reads","mode"])n[i]!==void 0&&(o[i]=n[i],a.push(i));return n.required!==void 0&&(o.required=n.required?"policy":!1,a.push("required")),{sandbox:o,locked:a}}const C=Object.freeze(["allowed","never"]);function D(e){return e?.access?.delegation==="never"?"never":"allowed"}function d(e){const r=f(e).toLowerCase();if(!r)return{host:"",port:""};try{const n=new URL(/^[a-z][a-z0-9+.-]*:\/\//.test(r)?r:`http://${r}`);return{host:n.hostname.replace(/^\[|\]$/g,""),port:n.port||(n.protocol==="https:"?"443":n.protocol==="http:"?"80":"")}}catch{return{host:r.split(":")[0],port:""}}}function P(e,r,n){if(e==="*")return!0;const[o,a]=e.startsWith("[")?[e.replace(/^\[([^\]]+)\].*$/,"$1"),e.replace(/^\[[^\]]+\]:?/,"")]:(()=>{const i=e.lastIndexOf(":");return i>0?[e.slice(0,i),e.slice(i+1)]:[e,""]})();if(a&&a!==n)return!1;if(o.startsWith("*.")){const i=o.slice(1);return r.endsWith(i)&&r.length>i.length}return r===o}function g(e,r,n){return(e||[]).some(o=>P(o,r,n))}function h(e){return new RegExp(`^${String(e).split("*").map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join(".*")}$`,"i")}function T(e,r){const n=e?.endpoints;if(!n)return!0;const{host:o,port:a}=d(r);return!o||g(n.deny,o,a)?!1:n.allow&&n.allow.length?g(n.allow,o,a):!0}function M(e,r){const n=e?.models;if(!n)return!0;const o=f(r);return(n.deny||[]).some(a=>h(a).test(o))?!1:n.allow&&n.allow.length?n.allow.some(a=>h(a).test(o)):!0}function _(e,r){const n=e?.agents;if(!n)return!0;const o=f(r).toLowerCase();return(n.deny||[]).includes(o)?!1:n.allow&&n.allow.length?n.allow.includes(o):!0}function v(e,r){const n=e?.agents?.permissionModeCap,o=m.includes(r)?r:"default";return n?U[o]<=U[n]?o:n:o}function H(e,{model:r="",endpoint:n=""}={}){if(!e)return{ok:!0,reason:""};if(r&&!M(e,r))return{ok:!1,reason:`model "${r}" is not allowed by your organisation's policy`};if(n&&!T(e,n))return{ok:!1,reason:`endpoint ${d(n).host} is not allowed by your organisation's policy`};const o=e.routing?.rules||[];if(r&&n&&o.length){const a=o.find(i=>i.models.some(t=>h(t).test(r)));if(a){const{host:i,port:t}=d(n);if(!g(a.endpoints,i,t))return{ok:!1,reason:`model "${r}" may only be sent to ${a.endpoints.join(", ")} under your organisation's policy`}}}return{ok:!0,reason:""}}function q(e,r){const n=e?.redaction?.floor,o=w.includes(r)?r:"basic";return n?k[o]>=k[n]?o:n:o}function W(e,r,{local:n=!1}={}){const o=e?.egress;if(!o)return!0;const{host:a,port:i}=d(r);return!a||g(o.deny,a,i)?!1:n||L.includes(a)||e.endpoints?.allow?.length&&g(e.endpoints.allow,a,i)&&!g(e.endpoints?.deny,a,i)?!0:g(o.allow,a,i)}function K(e,r){return!!e?.client?.lock?.includes(r)}function N(e,r){const n=e?.client?.features;return!n||n[r]==null?!0:!!n[r]}function Y(e,r){const n={...r||{}},o=[];if(!e)return{settings:n,changed:o};const a=e.client||{};if(a.gatewayUrl&&n.gatewayUrl!==a.gatewayUrl&&(n.gatewayUrl=a.gatewayUrl,o.push("gatewayUrl")),Array.isArray(n.endpoints)&&e.endpoints){const i=n.endpoints.filter(t=>!t||typeof t!="object"?!1:!t.baseUrl||a.gatewayUrl&&d(t.baseUrl).host===d(a.gatewayUrl).host&&d(t.baseUrl).port===d(a.gatewayUrl).port?!0:T(e,t.baseUrl));i.length!==n.endpoints.length&&(n.endpoints=i,o.push("endpoints"))}if(Array.isArray(n.endpoints)&&e.agents){const i=n.endpoints.filter(t=>t?.kind!=="bridge"||_(e,t.bridgeAgent||t.agent||t.id));i.length!==n.endpoints.length&&(n.endpoints=i,o.push("agents"))}if(Array.isArray(n.endpoints)&&!N(e,"webllm")){const i=n.endpoints.filter(t=>t?.kind!=="webllm");i.length!==n.endpoints.length&&(n.endpoints=i,o.push("webllm"))}if(e.redaction?.floor&&(n.redaction?.tier!=null||n.redactionTier!=null)){const i=n.redaction?.tier!=null?n.redaction.tier:n.redactionTier,t=q(e,i);t!==i&&(n.redaction?.tier!=null?n.redaction={...n.redaction,tier:t}:n.redactionTier=t,o.push("redaction"))}return{settings:n,changed:o}}function J(e){const r=e?.org?.name||e?.org?.id;return r?`Managed by ${r}`:"Managed"}function x(e){return Array.isArray(e)?`[${e.map(x).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${x(e[r])}`).join(",")}}`:JSON.stringify(e)}async function X(e,{subtle:r=null}={}){const n=r||globalThis.crypto?.subtle;if(!n)throw new l("no WebCrypto available on this runtime");const o=new TextEncoder().encode(x(y(e))),a=await n.digest("SHA-256",o);return[...new Uint8Array(a)].map(i=>i.toString(16).padStart(2,"0")).join("")}async function Z(e,{verify:r,...n}={}){if(typeof r!="function")throw new l("verifyPolicyToken needs a verify function (entitlement.js verifySignedToken)");const o=await r(e,{...n,typ:z});if(!o||!o.policy)return null;try{return y(o.policy)}catch{return null}}export{C as ACCESS_DELEGATION,S as FEATURES,E as LOCKABLE,m as PERMISSION_MODES,z as POLICY_TOKEN_TYPE,O as POLICY_VERSION,L as PRODUCT_HOSTS,l as PolicyError,w as REDACTION_TIERS,D as accessDelegation,_ as agentAllowed,Y as applyPolicyToSettings,W as egressAllowed,T as endpointAllowed,N as featureEnabled,h as globToRegExp,M as modelAllowed,y as normalizeOrgPolicy,v as permissionMode,X as policyHash,J as policyLabel,q as redactionTier,H as routeAllowed,I as sandboxUnderPolicy,K as settingLocked,Z as verifyPolicyToken};
|
package/record-list.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const
|
|
2
|
-
${
|
|
1
|
+
import{parseDateQuery as g,filterByDate as p}from"./date-filter.js";const m=Object.freeze(["recent","started","title"]),M=Object.freeze({recent:"Recently active",started:"Date started",title:"Title A–Z"}),i=r=>Number.isFinite(Number(r))?Number(r):0;function l(r,n="recent"){return n==="started"?i(r?.createdAt)||i(r?.updatedAt):i(r?.updatedAt)||i(r?.createdAt)}function h(r,n="recent"){const u=Array.isArray(r)?[...r]:[];if(n==="title")return u.sort((a,e)=>String(a?.title||"").localeCompare(String(e?.title||""),void 0,{sensitivity:"base"})||l(e)-l(a));const s=m.includes(n)?n:"recent";return u.sort((a,e)=>l(e,s)-l(a,s))}function b(r,n,{now:u=Date.now()}={}){const s=g(n,{now:u}),a=s.text.toLowerCase().split(/\s+/).filter(Boolean),e=p(r,s.range);return a.length?e.filter(t=>{const o=`${t?.title||""}
|
|
2
|
+
${t?.snippet||""}`.toLowerCase();return a.every(c=>o.includes(c))}):e}const k=864e5;function d(r){const n=new Date(r);return n.setHours(0,0,0,0),n.getTime()}const y=["January","February","March","April","May","June","July","August","September","October","November","December"],D=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function f(r,n=Date.now()){const u=i(r);if(!u)return{key:"undated",label:"Undated",order:9e15};const s=d(n),a=d(u),e=Math.round((s-a)/k);if(e<=0)return{key:"today",label:"Today",order:0};if(e===1)return{key:"yesterday",label:"Yesterday",order:1};if(e<7)return{key:"week",label:"Earlier this week",order:2};const t=new Date(u),o=new Date(n);if(t.getFullYear()===o.getFullYear()&&t.getMonth()===o.getMonth())return{key:"month",label:"Earlier this month",order:3};const c=t.getFullYear()===o.getFullYear()?y[t.getMonth()]:`${y[t.getMonth()]} ${t.getFullYear()}`;return{key:`m-${t.getFullYear()}-${t.getMonth()}`,label:c,order:4+(o.getFullYear()*12+o.getMonth())-(t.getFullYear()*12+t.getMonth())}}function S(r,n=Date.now(),{locale:u=void 0}={}){const s=i(r);if(!s)return"";const a=f(s,n),e=new Date(s);if(a.key==="today"||a.key==="yesterday")return e.toLocaleTimeString(u,{hour:"numeric",minute:"2-digit"});if(a.key==="week")return D[e.getDay()];const t=e.getFullYear()===new Date(n).getFullYear();return e.toLocaleDateString(u,{month:"short",day:"numeric",...t?{}:{year:"numeric"}})}function Y(r,{mode:n="recent",query:u="",now:s=Date.now()}={}){const a=h(b(r,u,{now:s}),n);if(n==="title")return a.length?[{key:"all",label:"",items:a}]:[];const e=new Map;for(const t of a){const o=f(l(t,n),s);e.has(o.key)||e.set(o.key,{key:o.key,label:o.label,order:o.order,items:[]}),e.get(o.key).items.push(t)}return[...e.values()].sort((t,o)=>t.order-o.order).map(({order:t,...o})=>o)}export{M as SORT_LABELS,m as SORT_MODES,f as dayBucket,b as filterRecords,Y as groupRecords,S as rowTime,h as sortRecords,l as sortStamp};
|
package/retrieval-plan.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{needsWhole as
|
|
2
|
-
${String(o.text||"")}`})):r}function oe(n=[],t=""){const r=String(t||"").trim();if(!r)return n;const o=/^(?:here|near me|nearby|my (?:location|area|city))$/i;return(Array.isArray(n)?n:[]).map(a=>{const s=a?.input?.args||a?.input;if(!s)return a;if(a.kind==="weather"&&o.test(String(s.location||"").trim())){const i={...s,location:r};return{...a,input:a.input.args?{...a.input,args:i}:i,label:`Weather — ${r}`}}if(typeof s.query=="string"&&/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i.test(s.query)){const i=s.query.replace(/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i,`near ${r}`);return{...a,input:a.input.args?{...a.input,args:{...s,query:i}}:{...s,query:i},subject:i,label:String(a.label||"").replace(/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i,`near ${r}`)}}return a})}function ae({question:n="",previousText:t="",previousAnswer:r="",previous:o=null,reach:a=new Set,window:s=0,personal:i=!1,lookup:d=null,now:
|
|
1
|
+
import{needsWhole as E}from"./digest.js";import{lookupSubject as q,prefetchPlan as C,answeredByPrefetch as P}from"./prefetch.js";import{partChars as _,STITCH_LIMITS as D}from"./stitch.js";import{isSmallWindow as b,FIT_HEADROOM as W,SMALL_WINDOW_ROUNDS as g}from"./context-window.js";import{isPleasantry as F}from"./tool-need.js";const L=4,j={device:3,api:2,agent:8};function Z({question:n="",sources:t=[],fixedTokens:r=0,target:o={}}={}){const a=o.kind||"api",s=Number(o.window)||0,i=b(s),d=E(n),k=Math.max(1,Number(o.concurrency)||(a==="device"?1:4)),x=Number(o.secondsPerCall)||j[a]||2,h=(Array.isArray(t)?t:[]).filter(Boolean).map(e=>({...e,chars:Math.max(0,Number(e.chars)||0)})),m=s?Math.floor(s*W)-(Number(o.reserve)||1024)-(Number(r)||0):1/0,y=Number.isFinite(m)?Math.max(0,m)*L:1/0,f=new Map,c=new Set;let u=y;for(let e=!0;e;){e=!1;const l=h.filter(w=>!c.has(w.id)),p=l.length?u/l.length:0;for(const w of l)w.chars<=p&&(c.add(w.id),u-=w.chars,e=!0)}const T=h.filter(e=>!c.has(e.id)).reduce((e,l)=>e+l.chars,0);for(const e of h)f.set(e.id,c.has(e.id)?e.chars:Math.floor(u*e.chars/(T||1)));const S=_({windowTokens:s,reserveTokens:450})||0,M=h.map(e=>{const l={id:e.id,kind:e.kind,title:e.title||"",chars:e.chars,share:f.get(e.id)};if(a==="agent")return{...l,how:"agent",calls:0,why:"an agent reads it itself — handed the material, not a digest"};if(c.has(e.id)||!Number.isFinite(y))return{...l,how:"whole",calls:0,why:"it fits"};if(!i)return{...l,how:"merge",calls:Math.ceil(e.chars/Math.max(1,l.share)),why:"a large window: what does not fit is merged by the model"};if(d&&S>0){const p=Math.min(D.parts,Math.ceil(e.chars/S)),w=Math.ceil(e.chars/S),R=Math.max(1,Math.ceil(p/4));return{...l,how:"digest",parts:p,calls:p+R,unread:Math.max(0,w-p),why:"the question needs all of it, and it does not fit: read in parts, the notes combined"}}return{...l,how:"cut",calls:0,why:d?"no room to read it in parts: the parts that bear on the question":"a focused question: the parts that bear on it, by relevance"}}),I=h.some(e=>e.prefetched),O=a==="agent"?{offer:!0,rounds:null,why:"an agent keeps its own tools"}:i&&I?{offer:!1,rounds:1,why:"a small window, and a prefetch already answered"}:i?{offer:!0,rounds:g,why:"a small window: one tool round, then the answer"}:{offer:!0,rounds:null,why:""},A=M.reduce((e,l)=>e+(l.calls||0),0),$=Math.round((Math.ceil(A/k)+1)*x);return{sources:M,tools:O,estimate:{calls:A+1,seconds:$},say:H(M,$)}}function H(n,t){const r=n.filter(i=>i.how==="digest");if(!r.length)return"";const o=r.length===1?`"${r[0].title||"what is attached"}"`:`${r.length} attachments`,a=r.reduce((i,d)=>i+d.parts,0),s=r.reduce((i,d)=>i+(d.unread||0),0);return`Reading all of ${o} in ${a} part${a===1?"":"s"} first, so the answer covers the whole of it${s?` (the last ${s} part${s===1?"":"s"} will not fit)`:""} — about ${t} s.`}const N=/\b(?:schedule|reschedule|remind(?:er)?|calendar|invite|e-?mail|inbox|send|reply|draft|create|add|save|write (?:a |an )?note|open|click|fill|book|order|cancel|delete|rename|move|upload|download|run|execute|deploy|commit|share|post)\b/i,B=/\b(?:find out|find more|more (?:info|information|details)|look into|latest|current(?:ly)?|today|tonight|tomorrow|right now|this (?:week|weekend|month|year)|price|prices|cost|stock|shares?|score|news|headlines?|weather|forecast|hours|near me|nearby|directions|traffic|flight|look (?:it |that )?up|search|google|website|link|url|https?:\/\/|who(?:'s| is| was| are)|where(?:'s| is| are)|when(?:'s| is| does| do))\b/i,U=/\b(?:my|mine|our|ours|we|us|did i|have i|i (?:said|asked|wrote|told|had|was)|remember|last time|earlier today|meetings?|notes?|transcripts?|conversations?|chats?)\b/i;function K(n){const t=String(n||"").trim();return t?N.test(t)||B.test(t)||U.test(t)||!!q(t):!1}const v=new Set(["weather","stock","news","page","web","research"]);function ee(n=[]){return(Array.isArray(n)?n:[]).some(t=>t?.kind==="prefetch"&&v.has(t.prefetch)&&String(t.text||"").trim())}function te(n=[]){return(Array.isArray(n)?n:[]).some(t=>t&&v.has(t.kind))}function Y({window:n=0,question:t="",answered:r=!1,decided:o=""}={}){return b(n)?r?{offer:!1,rounds:1,why:"a small window, and a prefetch already answered"}:o==="none"?N.test(String(t||""))?{offer:!0,rounds:g,why:"a small window: nothing to look up, and something to do"}:{offer:!1,rounds:1,why:"a small window, and the decider found nothing to look up"}:o?{offer:!0,rounds:g,why:`a small window, the decider asked for ${o}, and the fetch found nothing`}:K(t)?{offer:!0,rounds:g,why:"a small window: one tool round, then the answer"}:{offer:!1,rounds:1,why:"a small window, and a question that needs no tools"}:{offer:!0,rounds:null,why:""}}function re({window:n=0,question:t="",answered:r=!1}={}){if(!b(n))return{history:"all",memories:"all",before:!1,why:""};const o=F(t);return{history:r?"none":"all",memories:o?"none":r?"pinned":"matched",before:!0,why:[r?"a small window a fetch answered: the evidence, the question and pinned memories":"",o?"a greeting: no memories":r?"":"a small window: only the memories that bear on it"].filter(Boolean).join("; ")}}const z="From the user's own history. It may have nothing to do with the question: use it only if it answers it, otherwise answer from your own knowledge.";function ne(n=[],t={}){const r=(Array.isArray(n)?n:[]).filter(o=>o&&typeof o=="object");return t?.before?r.map(o=>({...o,before:!0,text:`${z}
|
|
2
|
+
${String(o.text||"")}`})):r}function oe(n=[],t=""){const r=String(t||"").trim();if(!r)return n;const o=/^(?:here|near me|nearby|my (?:location|area|city))$/i;return(Array.isArray(n)?n:[]).map(a=>{const s=a?.input?.args||a?.input;if(!s)return a;if(a.kind==="weather"&&o.test(String(s.location||"").trim())){const i={...s,location:r};return{...a,input:a.input.args?{...a.input,args:i}:i,label:`Weather — ${r}`}}if(typeof s.query=="string"&&/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i.test(s.query)){const i=s.query.replace(/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i,`near ${r}`);return{...a,input:a.input.args?{...a.input,args:{...s,query:i}}:{...s,query:i},subject:i,label:String(a.label||"").replace(/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i,`near ${r}`)}}return a})}function ae({question:n="",previousText:t="",previousAnswer:r="",previous:o=null,reach:a=new Set,window:s=0,personal:i=!1,lookup:d=null,now:k=Date.now()}={}){const x=b(s),h=C({text:n,previous:o,previousText:t,previousAnswer:r,reach:a,research:!0,page:!0,lookup:d??x,now:k}),m=h.some(u=>["weather","stock","news","page","web","research"].includes(u.kind)),y=!!i&&!m,f=[];h.length&&f.push(`fetch first: ${h.map(u=>u.label||u.kind).join(", ")}`),i&&m&&f.push("a world fact — the person's history is not searched for it");const c=Y({window:s,question:n,answered:h.length>0});return c.why&&f.push(c.why),{prefetch:h,world:m,research:y,tools:c,why:f}}export{z as HISTORY_NOTE,P as answeredByPrefetch,re as contextPlan,ne as historyContext,oe as placeItems,Z as planRetrieval,ae as planTurn,Y as toolPlan,K as toolsWanted,ee as worldAnswered,te as worldPlanned};
|
package/runtime-host.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function r({bunMain:t="",versions:e={},execPath:i=""}={}){if(e.electron)return!1;const n=String(t||"");if(n)return n.startsWith("/$bunfs/")||/^[A-Za-z]:[\\/]~BUN[\\/]/.test(n);const s=String(i||"").split(/[\\/]/).pop().toLowerCase();return e.bun?!1:!(s.startsWith("node")||s.startsWith("bun"))}function o(){const t=globalThis.process;return{bunMain:typeof globalThis.Bun<"u"?String(globalThis.Bun.main||""):"",versions:t?.versions||{},execPath:t?.execPath||""}}export{o as hostFacts,r as isCompiledBinary};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const r=(o,e)=>{if(!o)throw Object.assign(new Error(e),{code:"SHAPE"})},c=Object.freeze(["enumerated","inverted"]),h=Object.freeze(["srt","container","command","managed"]);function u(o){const e=Array.isArray(o)?null:String(o??"").trim();let n;if(Array.isArray(o))n=o.map(String);else if(e.startsWith("[")){try{n=JSON.parse(e)}catch{r(!1,"sandbox command: not a JSON array")}r(Array.isArray(n)&&n.every(t=>typeof t=="string"),"sandbox command: a JSON array of strings")}else n=e.split(/\s+/).filter(Boolean);return r(n.length>0&&n.length<=128,"sandbox command: 1–128 words"),r(n.every(t=>t.length<=1024&&!t.includes("\0")),"sandbox command: a word too long or with a NUL"),r(!n[0].includes("{"),"sandbox command: the first word is the wrapper program, not a placeholder"),r(n.filter(t=>t==="{cmd}").length===1,"sandbox command: exactly one {cmd} word, where the command goes"),n}function m(o,{bin:e,argv:n=[],workdir:t="",home:i="",hosts:d=[],mode:a=""}={}){const l=s=>s.replaceAll("{workdir}",t).replaceAll("{home}",i).replaceAll("{hosts}",d.join(",")).replaceAll("{mode}",a);return o.flatMap(s=>s==="{cmd}"?[e,...n]:[l(s)])}function p(o){if(!o?.ok)return{cls:"off",text:"The local runtime (bridge) is not running — nothing is sandboxed because nothing is running."};const e=o.sandbox;if(!e)return{cls:"warn",text:`This bridge (v${o.version||"?"}) predates the sandbox — update the gateway.`};const n=e.required==="policy"?" Your organisation requires it: anything it cannot be applied to is refused, and nothing runs outside it.":e.required?" Required: anything it cannot be applied to is refused rather than run as you.":"";if(e.enabled===!1)return e.required?{cls:"bad",text:`The sandbox is required but switched off, so nothing runs.${n}`}:{cls:"warn",text:"Sandbox off — agents, MCP servers and workers run as you, with your files and your network."};if(!e.runtime){const a=`${e.reason||"no runtime"}${e.install?` (${e.install})`:""}`;return e.required?{cls:"bad",text:`Nothing runs — the sandbox is required and cannot be applied here: ${a}.`}:{cls:"warn",text:`Not sandboxed — ${a}`}}const t=String(e.runtime);if(t==="managed")return{cls:"ok",text:`Managed by your organisation — your agents run inside its sandbox, so ChatPanel does not add one of its own.${n}`};if(t.startsWith("command:"))return{cls:"ok",text:`Sandboxed by your own command (${t.slice(8)}) — it decides what each process may touch; ChatPanel hands it the working folder and the hosts each one is allowed.${n}`};if(t.startsWith("container:"))return{cls:"ok",text:`Sandboxed in containers (${t.slice(10)}) — each process sees only its working folder, with no capabilities${e.mode==="none"?" and no network":""}.${n}`};const i=e.mode==="allowlist"?"only its own service, the developer hosts and what you allow":e.mode==="none"?"nothing":"any public host through the sandbox proxy — never your machine, your network or a cloud metadata address",d=e.mode==="allowlist"?e.ownSessions?" A process granted hosts of its own gets a session of its own.":" Hosts granted on a card need a session of their own, which is not available here, so they share the allow list.":"";return{cls:"ok",text:`Sandboxed (${t}, ${e.platform||""}): the working directory writable, your secrets unreadable, the network ${i}.${d}${n}`}}export{c as SANDBOX_READ_MODES,h as SANDBOX_RUNTIMES,m as expandWrapper,u as parseWrapperTemplate,p as sandboxStatus};
|
package/sandbox-grant.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventError as
|
|
1
|
+
import{EventError as p}from"./event.js";const c=t=>!!t&&typeof t=="object"&&!Array.isArray(t),n=t=>[...new Set(t)],i=(t,s)=>{if(!t)throw new p("SHAPE",s)},l=/^(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*(:\d{1,5})?$/i,u=Object.freeze({aws:"AWS",oci:"Oracle Cloud",gcloud:"Google Cloud",azure:"Azure"}),a=Object.freeze(Object.keys(u));function y(t){return n(String(t||"").split(/[\s,;]+/).map(s=>s.trim().toLowerCase()).filter(Boolean))}function f(t){if(t==null)return{hosts:[],write:[]};i(c(t),"grant: must be an object");const s=Array.isArray(t.hosts)?t.hosts:typeof t.hosts=="string"?y(t.hosts):[],o=Array.isArray(t.write)?t.write:typeof t.write=="string"?t.write.split(/[\n,]+/).map(e=>e.trim()).filter(Boolean):[];for(const e of s)i(typeof e=="string"&&e!=="*"&&l.test(e),`grant: not a host pattern: ${JSON.stringify(e)}`);for(const e of o)i(typeof e=="string"&&e.length>0&&e.length<1024&&!e.includes("\0"),`grant: not a path: ${JSON.stringify(e)}`);const r=(Array.isArray(t.signIn)?t.signIn:typeof t.signIn=="string"?t.signIn.split(/[\s,;]+/):[]).map(e=>typeof e=="string"?e.trim().toLowerCase():e).filter(e=>e!=="");for(const e of r)i(a.includes(e),`grant: not a sign-in (${a.join(", ")}): ${JSON.stringify(e)}`);return{hosts:n(s.map(e=>e.toLowerCase())),write:n(o),...t.outside===!0?{outside:!0}:{},...r.length?{signIn:n(r)}:{}}}function h(...t){const s=t.map(f);return{hosts:n(s.flatMap(o=>o.hosts)),write:n(s.flatMap(o=>o.write))}}function w(...t){const s=t.map(f),o=n(s.flatMap(r=>r.signIn||[]));return{...h(...s),...s.some(r=>r.outside)?{outside:!0}:{},...o.length?{signIn:o}:{}}}export{u as SIGN_IN_LABELS,a as SIGN_IN_NAMES,h as mergeGrants,w as mergePersonGrants,f as normalizeGrant,y as parseHostList};
|
package/sandbox-policy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventError as L}from"./event.js";import{normalizeGrant as S}from"./sandbox-grant.js";import{SECRET_DIR_NAMES as P,SECRET_DIR_PAIRS as v}from"./secret-names.js";const R=Object.freeze(["none","process","container","kubernetes"]),$=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},x=(e,t)=>t&&(e==="~"||e.startsWith("~/")||e.startsWith("~\\"))?t+e.slice(1):e,m=e=>String(e||"").replace(/\\/g,"/"),b=(e,t)=>{const n=m(g(e)),r=m(g(t));return!!n&&!!r&&(n===r||n.startsWith(`${r}/`))},N=_.map(e=>m(g(e)).replace(/^~\//,"").split("/").filter(Boolean));function I(e,t=""){const n=m(g(x(g(e),t)));if(!n)return!1;for(const o of _)if(b(n,o)||t&&b(n,x(o,t)))return!0;const r=n.split("/").filter(Boolean).map(o=>o.toLowerCase());return N.some(o=>{for(let s=0;s+o.length<=r.length;s+=1)if(o.every((a,l)=>a.toLowerCase()===r[s+l]))return!0;return!1})}const W=Object.freeze([...[...P].map(e=>`~/**/${e}`),...v.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 ee(e,{home:t="",globs:n=[..._,...W]}={}){const r=m(g(x(g(e),t)));if(!r)return null;const o=r.split("/").filter(Boolean),s=m(g(t));for(const a of n){const l=m(g(a));if(l){if(l.startsWith("~/**/")){if(s&&!b(r,s))continue;const c=l.slice(5).split("/").filter(Boolean).map(z);for(let i=0;i+c.length<=o.length;i+=1)if(c.every((d,u)=>d.test(o[i+u])))return a;continue}if(b(r,x(l,t)))return a}}return null}function z(e){return new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*")}$`,"i")}const D=".cache/chatpanel/ca-bundle.crt",te=".cache/chatpanel/ca-bundle.pem";function ne(e=""){const t=m(g(e));return t?`${t}/${D}`:`~/${D}`}const H=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"]),k=Object.freeze(["/tmp","/private/tmp","~/.cache","~/.npm","~/.local/share/uv","~/.local/state"]),C=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"],keychain:!0,sockets:["/tmp/cc-socks","/private/tmp/cc-socks"]}),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="~/Library/Keychains",K=/(^|\/)Keychains\/?$/,Y=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),y=e=>Array.isArray(e)&&e.every(t=>typeof t=="string"&&t.length>0),f=(e,t)=>{if(!e)throw new L("SHAPE",t)},p=e=>[...new Set(e)];function j(e){f(h(e),"kit: must be an object"),f(typeof e.id=="string"&&e.id.length>0,"kit: id required"),f(h(e.network)&&$.includes(e.network.mode),`kit ${e.id}: network.mode must be one of ${$.join(", ")}`),f(y(e.network.allowedDomains||[]),`kit ${e.id}: network.allowedDomains must be string[]`),f(y(e.network.deniedDomains||[]),`kit ${e.id}: network.deniedDomains must be string[]`),f(h(e.filesystem),`kit ${e.id}: filesystem required`);for(const t of["allowWrite","denyWrite","allowRead","denyRead"])f(y(e.filesystem[t]||[]),`kit ${e.id}: filesystem.${t} must be string[]`);return f(y(e.filesystem.allowWrite)&&e.filesystem.allowWrite.length>0,`kit ${e.id}: filesystem.allowWrite must name at least the working directory`),f(y(e.network.unixSockets||[])&&(e.network.unixSockets||[]).every(t=>t.startsWith("/")&&t.replace(/\/+$/,"")!==""),`kit ${e.id}: network.unixSockets must be absolute folders, never /`),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=>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:p(e.network.allowedDomains||[]),deniedDomains:p(e.network.deniedDomains||[]),...(e.network.unixSockets||[]).length?{unixSockets:p(e.network.unixSockets)}:{}},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:h(e.limits)?{...e.limits}:{}}}import{normalizeGrant as ge,mergeGrants as me,parseHostList as we}from"./sandbox-grant.js";const U=e=>String(e).replace(/([\\/])\*$/,"$1**");function oe({engine:e="custom",cwd:t,mode:n="open",extraHosts:r=[],extraWrite:o=[],extraDenyRead:s=[],grant:a=null,home:l="",reads:c="enumerated",readOnly:i=!1,peers:d=!0}={}){const u=C[e]||C.custom;f(typeof t=="string"&&t.length>0,"kit: cwd required");const O=S(a);return j({id:`${e}:${n}`,kind:"process",network:{mode:n,allowedDomains:n==="open"?["*"]:n==="none"?[]:p([...u.hosts,...Y,...r,...O.hosts]),deniedDomains:[],unixSockets:d?[...u.sockets||[]]:[]},filesystem:{allowWrite:p(i?[...k,...u.write]:[t,...k,...u.write,...[...o,...O.write].filter(A=>!I(A,l)).map(U)]),denyWrite:[],allowRead:c==="inverted"?p([t,...H,...u.write,...u.keychain?[T]:[],...G({grant:O,extraWrite:o,cwd:t,home:l})]):[t],denyRead:p([...c==="inverted"?["~",...l?[l]:[]]:[],...[..._,...W].filter(A=>!(u.keychain&&K.test(A))),...s])}})}function B(e){if(!/[*?[{]/.test(e))return e;const t=e.split(/[\\/]/),n=t.findIndex(s=>/[*?[{]/.test(s)),r=e.includes("\\")&&!e.includes("/")?"\\":"/",o=t.slice(0,n).join(r);return o&&o!=="~"?o:""}function G({grant:e=null,extraWrite:t=[],cwd:n="",home:r=""}={}){const o=i=>r&&(i==="~"||i.startsWith("~/")||i.startsWith("~\\"))?r+i.slice(1):i,s=i=>{let d=String(i||"").trim();for(;d.length>1&&(d.endsWith("/")||d.endsWith("\\"));)d=d.slice(0,-1);return d},a=(i,d)=>i===d||i.startsWith(`${d}/`)||i.startsWith(`${d}\\`),l=s(o(n)),c=[];for(const i of[...S(e).write,...Array.isArray(t)?t:[]]){const d=B(s(o(s(i))));if(d&&!I(d,r)&&!(l&&a(d,l))&&!c.some(u=>a(d,u))){for(let u=c.length-1;u>=0;u--)a(c[u],d)&&c.splice(u,1);c.push(d)}}return c}function re(e,{loopback:t=[],home:n="",platform:r="darwin"}={}){const o=j(e),s=l=>n&&l.startsWith("~")?n+l.slice(1):l,a=o.network.mode==="none"?[]:t.map(l=>`127.0.0.1:${l}`);return{network:{allowedDomains:p([...o.network.allowedDomains,...a]),deniedDomains:o.network.deniedDomains,allowLocalBinding:r==="darwin"&&a.length>0,...r==="darwin"&&o.network.unixSockets?.length?{allowUnixSockets:o.network.unixSockets}:{}},filesystem:{denyRead:o.filesystem.denyRead.map(s),allowRead:o.filesystem.allowRead.map(s),allowWrite:o.filesystem.allowWrite.map(s),denyWrite:o.filesystem.denyWrite.map(s)}}}function se({layer:e="none",runtime:t=null,kitId:n=null,mode:r=null,reason:o=null,hosts:s=null}={}){return f(R.includes(e),`sandbox record: layer must be one of ${R.join(", ")}`),{layer:e,runtime:t,kit:n,mode:r,...e==="none"&&o?{reason:o}:{},...Array.isArray(s)&&s.length?{hosts:p(s)}:{}}}function M(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 s=0;for(;o<n.length&&n[o]==="\\";)s++,o++;if(o===n.length){r+="\\".repeat(s*2);break}n[o]==='"'?r+="\\".repeat(s*2+1)+'"':r+="\\".repeat(s)+n[o]}r+='"'}return r.replace(/[()%!^"<>&|]/g,"^$&")}return n===""?"''":/^[A-Za-z0-9_\-./=:@%+,]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}const q=Object.freeze(["SSL_CERT_FILE","REQUESTS_CA_BUNDLE","CURL_CA_BUNDLE","GIT_SSL_CAINFO"]);function ie(e={},{platform:t="darwin",caBundle:n=""}={}){const r={NODE_USE_ENV_PROXY:"1"};if(n)for(const o of q)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(s=>s.trim()).filter(s=>s&&!/^(localhost|127\.0\.0\.1|::1|\[::1\])$/i.test(s)).join(","));return r}function ce(e,t=[],{platform:n="darwin"}={}){return[e,...t].map(r=>M(r,{platform:n})).join(" ")}const ae=/[\\/]+/,w=e=>String(e||"").replace(/\//g,"\\").replace(/\\+$/,"").toLowerCase(),F=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 X(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 le({kit:e,files:t=[],home:n}){f(typeof n=="string"&&n.length>0,"windows grants: home required");const r=c=>(c.startsWith("~")?n+c.slice(1):c).replace(/\//g,"\\"),o=[];for(const c of e?.filesystem?.allowWrite||[]){const i=r(c);!/^[a-z]:\\/i.test(i)&&!i.startsWith("\\\\")||(f(!F(i)&&w(i)!==w(n),`windows grants: a write on ${i} would hand the sandbox account the whole profile`),E(i,n)&&o.push(i))}const s=(c,i)=>i.some(d=>w(c)===w(d)||E(c,d)),a=[];for(const c of t){const i=X(c);i&&E(i,n)&&a.push(i)}for(const c of e?.filesystem?.allowRead||[]){const i=r(c);E(i,n)&&a.push(i)}const l=p(a).filter(c=>!s(c,o));return{read:l.filter(c=>!l.some(i=>i!==c&&E(c,i))),write:p(o)}}const V=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 de({engine:e="custom",home:t,env:n={},base:r={},carry:o=V}={}){f(typeof t=="string"&&t.length>0,"windows env: home required");const s=t.replace(/\//g,"\\"),a=/^[a-z]:/i.test(s)?s.slice(0,2):"",l={USERPROFILE:s,...a?{HOMEDRIVE:a,HOMEPATH:s.slice(2)}:{}};for(const[c,i]of Object.entries(n))typeof i=="string"&&(r[c]!==i||o.includes(c))&&(l[c]=i);return e==="codex"&&!l.CODEX_HOME&&(l.CODEX_HOME=s+"\\.codex"),l}function fe(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 a=n+1;a<r;a++)e[a]==="--env"&&typeof e[a+1]=="string"&&o.add(e[a+1].split("=")[0].toUpperCase());const s=[];for(const[a,l]of Object.entries(t||{}))f(/^[A-Za-z_][A-Za-z0-9_]*$/.test(a),`srt-win env: bad key ${a}`),f(!/[\r\n]/.test(l),`srt-win env: ${a} holds a newline`),o.has(a.toUpperCase())||s.push("--env",`${a}=${l}`);return[...e.slice(0,r),...s,...e.slice(r)]}export{D as CA_BUNDLE_RELPATH,te as CA_BUNDLE_RELPATH_LEGACY,k as COMMON_WRITE,Y as DEVELOPER_HOSTS,C as ENGINE_KITS,$ as NETWORK_MODES,R as SANDBOX_LAYERS,_ as SECRET_PATHS,W as SECRET_READ_GLOBS,H as TOOLCHAIN_READ,V as WINDOWS_CARRY_KEYS,ne as caBundlePath,I as isSecretWritePath,oe as kitFor,me as mergeGrants,ge as normalizeGrant,we as parseHostList,ee as readDenialFor,ie as sandboxEnvOverlay,se as sandboxRecord,ce as shellJoin,M as shellQuote,re as toSrtSettings,E as underWindowsHome,j as validateKit,le as windowsGrantsFor,X as windowsInstallRoot,de as windowsSandboxEnv,fe as withSrtWinEnv,G as writableRoots};
|
|
1
|
+
import{EventError as L}from"./event.js";import{normalizeGrant as y,SIGN_IN_NAMES as P,SIGN_IN_LABELS as x}from"./sandbox-grant.js";import{SECRET_DIR_NAMES as T,SECRET_DIR_PAIRS as H}from"./secret-names.js";const k=Object.freeze(["none","process","container","kubernetes","external"]),N=Object.freeze(["open","allowlist","none","gateway"]),S=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},O=(e,t)=>t&&(e==="~"||e.startsWith("~/")||e.startsWith("~\\"))?t+e.slice(1):e,m=e=>String(e||"").replace(/\\/g,"/"),A=(e,t)=>{const n=m(g(e)),r=m(g(t));return!!n&&!!r&&(n===r||n.startsWith(`${r}/`))},G=S.map(e=>m(g(e)).replace(/^~\//,"").split("/").filter(Boolean));function W(e,t=""){const n=m(g(O(g(e),t)));if(!n)return!1;for(const o of S)if(A(n,o)||t&&A(n,O(o,t)))return!0;const r=n.split("/").filter(Boolean).map(o=>o.toLowerCase());return G.some(o=>{for(let s=0;s+o.length<=r.length;s+=1)if(o.every((l,c)=>l.toLowerCase()===r[s+c]))return!0;return!1})}const j=Object.freeze([...[...T].map(e=>`~/**/${e}`),...H.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 ae(e,{home:t="",globs:n=[...S,...j]}={}){const r=m(g(O(g(e),t)));if(!r)return null;const o=r.split("/").filter(Boolean),s=m(g(t));for(const l of n){const c=m(g(l));if(c){if(c.startsWith("~/**/")){if(s&&!A(r,s))continue;const a=c.slice(5).split("/").filter(Boolean).map(K);for(let i=0;i+a.length<=o.length;i+=1)if(a.every((d,u)=>d.test(o[i+u])))return l;continue}if(A(r,O(c,t)))return l}}return null}function K(e){return new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*")}$`,"i")}const C=".cache/chatpanel/ca-bundle.crt",ce=".cache/chatpanel/ca-bundle.pem";function le(e=""){const t=m(g(e));return t?`${t}/${C}`:`~/${C}`}const B=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"]),v=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"],keychain:!0,sockets:["/tmp/cc-socks","/private/tmp/cc-socks"]}),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:[]})}),M="~/Library/Keychains",U=/(^|\/)Keychains\/?$/,I=Object.freeze({aws:Object.freeze({label:x.aws,where:"~/.aws",read:["~/.aws","~/.aws/credentials","~/.aws/sso"],hosts:["*.amazonaws.com","*.api.aws"],failure:/could not load (aws )?credentials|unable to locate credentials|CredentialsProviderError|NoCredentialProviders|failed to refresh cached credentials|aws credentials? (not found|could not be)/i}),oci:Object.freeze({label:x.oci,where:"~/.oci",read:["~/.oci","~/.oci/**/*.pem"],hosts:["*.oraclecloud.com"],failure:/could not find config file at .*\.oci|ConfigFileNotFound|oci config(uration)? (file )?(was )?not found|\.oci[\\/]config.*(not found|no such file|not permitted|permission denied)/i}),gcloud:Object.freeze({label:x.gcloud,where:"~/.config/gcloud",read:["~/.config/gcloud"],hosts:["*.googleapis.com","accounts.google.com"],failure:/could not load the default credentials|DefaultCredentialsError|could not (automatically )?(find|determine) (default )?credentials|application default credentials (were|are) not (found|available)/i}),azure:Object.freeze({label:x.azure,where:"~/.azure",read:["~/.azure"],hosts:["*.azure.com","login.microsoftonline.com"],failure:/DefaultAzureCredential failed|CredentialUnavailableError|please run 'az login'|AzureCliCredential authentication (unavailable|failed)/i})});function D(e){return f((y(e).signIn||[]).flatMap(t=>I[t].read))}function Y(e){return f((y(e).signIn||[]).flatMap(t=>I[t].hosts))}function de(e,{grant:t=null,sandboxed:n=!0,agentLabel:r="This agent",agent:o=""}={}){if(!n)return null;let s=[];try{s=y(t).signIn||[]}catch{}const l=String(e||"");for(const c of P){const a=I[c];if(!(s.includes(c)||!a.failure.test(l)))return{store:c,line:`${r} could not sign in to ${a.label}: the ChatPanel sandbox keeps your ${a.label} sign-in (${a.where}) from every agent until you allow it. To allow it for this agent only, turn on ${a.label} under "May sign in with" in its Coding Agents settings${o?`, or run: chatpanel-gateway sandbox allow ${o} ${c}`:""}. Nothing else it is denied changes.`}}return null}const F=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"]),E=e=>!!e&&typeof e=="object"&&!Array.isArray(e),_=e=>Array.isArray(e)&&e.every(t=>typeof t=="string"&&t.length>0),p=(e,t)=>{if(!e)throw new L("SHAPE",t)},f=e=>[...new Set(e)];function $(e){p(E(e),"kit: must be an object"),p(typeof e.id=="string"&&e.id.length>0,"kit: id required"),p(E(e.network)&&N.includes(e.network.mode),`kit ${e.id}: network.mode must be one of ${N.join(", ")}`),p(_(e.network.allowedDomains||[]),`kit ${e.id}: network.allowedDomains must be string[]`),p(_(e.network.deniedDomains||[]),`kit ${e.id}: network.deniedDomains must be string[]`),p(E(e.filesystem),`kit ${e.id}: filesystem required`);for(const t of["allowWrite","denyWrite","allowRead","denyRead"])p(_(e.filesystem[t]||[]),`kit ${e.id}: filesystem.${t} must be string[]`);return p(_(e.filesystem.allowWrite)&&e.filesystem.allowWrite.length>0,`kit ${e.id}: filesystem.allowWrite must name at least the working directory`),p(_(e.network.unixSockets||[])&&(e.network.unixSockets||[]).every(t=>t.startsWith("/")&&t.replace(/\/+$/,"")!==""),`kit ${e.id}: network.unixSockets must be absolute folders, never /`),e.image!=null&&p(typeof e.image=="string",`kit ${e.id}: image must be a string`),e.credentials!=null&&p(Array.isArray(e.credentials)&&e.credentials.every(t=>E(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:f(e.network.allowedDomains||[]),deniedDomains:f(e.network.deniedDomains||[]),...(e.network.unixSockets||[]).length?{unixSockets:f(e.network.unixSockets)}:{}},filesystem:{allowWrite:f(e.filesystem.allowWrite),denyWrite:f(e.filesystem.denyWrite||[]),allowRead:f(e.filesystem.allowRead||[]),denyRead:f(e.filesystem.denyRead||[])},credentials:e.credentials||[],limits:E(e.limits)?{...e.limits}:{}}}import{normalizeGrant as xe,mergeGrants as Se,mergePersonGrants as Oe,parseHostList as Ae,SIGN_IN_NAMES as Re,SIGN_IN_LABELS as Ie}from"./sandbox-grant.js";import{SANDBOX_READ_MODES as ke,SANDBOX_RUNTIMES as Ne,parseWrapperTemplate as We,expandWrapper as je}from"./sandbox-choice.js";const X=e=>String(e).replace(/([\\/])\*$/,"$1**");function q({engine:e="custom",cwd:t,mode:n="open",extraHosts:r=[],extraWrite:o=[],extraDenyRead:s=[],grant:l=null,home:c="",reads:a="enumerated",readOnly:i=!1,peers:d=!0}={}){const u=v[e]||v.custom;p(typeof t=="string"&&t.length>0,"kit: cwd required");const h=y(l);return $({id:`${e}:${n}`,kind:"process",network:{mode:n,allowedDomains:n==="open"?["*"]:n==="none"?[]:f([...u.hosts,...F,...r,...h.hosts,...Y(h)]),deniedDomains:[],unixSockets:d?[...u.sockets||[]]:[]},filesystem:{allowWrite:f(i?[...z,...u.write]:[t,...z,...u.write,...[...o,...h.write].filter(R=>!W(R,c)).map(X)]),denyWrite:[],allowRead:f(a==="inverted"?[t,...B,...u.write,...u.keychain?[M]:[],...Z({grant:h,extraWrite:o,cwd:t,home:c}),...D(h)]:[t,...D(h)]),denyRead:f([...a==="inverted"?["~",...c?[c]:[]]:[],...[...S,...j].filter(R=>!(u.keychain&&U.test(R))),...s])}})}const V=Object.freeze({noWrite:Object.freeze(["runtime/sandbox-runtime","runtime/ort","bin","node_modules","package.json","package-lock.json","git-hooks","policy.json","bridge-token","agent-threads.json","update-check.json","launch.vbs","workspace","worktrees","channels","desktop","cli","actions-runner","release.env"]),noRead:Object.freeze(["channels","desktop","cli","actions-runner","release.env","workspace","worktrees"])});function ue({stateDir:e,codeDirs:t=[],home:n="",mode:r="open",hosts:o=[],scratch:s=[],fence:l=V}={}){p(typeof e=="string"&&e.length>1,"gateway kit: stateDir required");const c=q({engine:"custom",cwd:e,mode:r,extraHosts:o,home:n,reads:"inverted",peers:!1}),a=u=>typeof u=="string"&&u.startsWith("/")&&u.replace(/\/+$/,"")!==""&&u!==n,i=t.filter(a),d=u=>`${e.replace(/\/+$/,"")}/${u}`;return $({...c,id:`gateway:${r}`,filesystem:{...c.filesystem,allowWrite:f([e,"/tmp","/private/tmp",...s.filter(a)]),denyWrite:f([...i,...l.noWrite.map(d)]),allowRead:f([...c.filesystem.allowRead,...i]),denyRead:f([...c.filesystem.denyRead,...l.noRead.map(d)])}})}function Q(e){if(!/[*?[{]/.test(e))return e;const t=e.split(/[\\/]/),n=t.findIndex(s=>/[*?[{]/.test(s)),r=e.includes("\\")&&!e.includes("/")?"\\":"/",o=t.slice(0,n).join(r);return o&&o!=="~"?o:""}function Z({grant:e=null,extraWrite:t=[],cwd:n="",home:r=""}={}){const o=i=>r&&(i==="~"||i.startsWith("~/")||i.startsWith("~\\"))?r+i.slice(1):i,s=i=>{let d=String(i||"").trim();for(;d.length>1&&(d.endsWith("/")||d.endsWith("\\"));)d=d.slice(0,-1);return d},l=(i,d)=>i===d||i.startsWith(`${d}/`)||i.startsWith(`${d}\\`),c=s(o(n)),a=[];for(const i of[...y(e).write,...Array.isArray(t)?t:[]]){const d=Q(s(o(s(i))));if(d&&!W(d,r)&&!(c&&l(d,c))&&!a.some(u=>l(d,u))){for(let u=a.length-1;u>=0;u--)l(a[u],d)&&a.splice(u,1);a.push(d)}}return a}function fe(e,{loopback:t=[],home:n="",platform:r="darwin"}={}){const o=$(e),s=c=>n&&c.startsWith("~")?n+c.slice(1):c,l=o.network.mode==="none"?[]:t.map(c=>`127.0.0.1:${c}`);return{network:{allowedDomains:f([...o.network.allowedDomains,...l]),deniedDomains:o.network.deniedDomains,allowLocalBinding:r==="darwin"&&l.length>0,...r==="darwin"&&o.network.unixSockets?.length?{allowUnixSockets:o.network.unixSockets}:{}},filesystem:{denyRead:o.filesystem.denyRead.map(s),allowRead:o.filesystem.allowRead.map(s),allowWrite:o.filesystem.allowWrite.map(s),denyWrite:o.filesystem.denyWrite.map(s)}}}function pe({layer:e="none",runtime:t=null,kitId:n=null,mode:r=null,reason:o=null,hosts:s=null}={}){return p(k.includes(e),`sandbox record: layer must be one of ${k.join(", ")}`),{layer:e,runtime:t,kit:n,mode:r,...e==="none"&&o?{reason:o}:{},...Array.isArray(s)&&s.length?{hosts:f(s)}:{}}}function J(e,{platform:t="darwin"}={}){const n=String(e);if(t==="win32"){p(!/[\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 s=0;for(;o<n.length&&n[o]==="\\";)s++,o++;if(o===n.length){r+="\\".repeat(s*2);break}n[o]==='"'?r+="\\".repeat(s*2+1)+'"':r+="\\".repeat(s)+n[o]}r+='"'}return r.replace(/[()%!^"<>&|]/g,"^$&")}return n===""?"''":/^[A-Za-z0-9_\-./=:@%+,]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}const ee=Object.freeze(["SSL_CERT_FILE","REQUESTS_CA_BUNDLE","CURL_CA_BUNDLE","GIT_SSL_CAINFO"]);function ge(e={},{platform:t="darwin",caBundle:n=""}={}){const r={NODE_USE_ENV_PROXY:"1"};if(n)for(const o of ee)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(s=>s.trim()).filter(s=>s&&!/^(localhost|127\.0\.0\.1|::1|\[::1\])$/i.test(s)).join(","));return r}function me(e,t=[],{platform:n="darwin"}={}){return[e,...t].map(r=>J(r,{platform:n})).join(" ")}const we=/[\\/]+/,w=e=>String(e||"").replace(/\//g,"\\").replace(/\\+$/,"").toLowerCase(),te=e=>/^[a-z]:$/i.test(w(e))||w(e)==="";function b(e,t){const n=w(e),r=w(t);return!!r&&n!==r&&n.startsWith(r+"\\")}function ne(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 he({kit:e,files:t=[],home:n}){p(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 i=r(a);!/^[a-z]:\\/i.test(i)&&!i.startsWith("\\\\")||(p(!te(i)&&w(i)!==w(n),`windows grants: a write on ${i} would hand the sandbox account the whole profile`),b(i,n)&&o.push(i))}const s=(a,i)=>i.some(d=>w(a)===w(d)||b(a,d)),l=[];for(const a of t){const i=ne(a);i&&b(i,n)&&l.push(i)}for(const a of e?.filesystem?.allowRead||[]){if(/[*?[]/.test(a))continue;const i=r(a);b(i,n)&&l.push(i)}const c=f(l).filter(a=>!s(a,o));return{read:c.filter(a=>!c.some(i=>i!==a&&b(a,i))),write:f(o)}}const oe=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 ye({engine:e="custom",home:t,env:n={},base:r={},carry:o=oe}={}){p(typeof t=="string"&&t.length>0,"windows env: home required");const s=t.replace(/\//g,"\\"),l=/^[a-z]:/i.test(s)?s.slice(0,2):"",c={USERPROFILE:s,...l?{HOMEDRIVE:l,HOMEPATH:s.slice(2)}:{}};for(const[a,i]of Object.entries(n))typeof i=="string"&&(r[a]!==i||o.includes(a))&&(c[a]=i);return e==="codex"&&!c.CODEX_HOME&&(c.CODEX_HOME=s+"\\.codex"),c}function Ee(e,t){p(Array.isArray(e),"srt-win argv: must be an array");const n=e.indexOf("exec"),r=n>=0?e.indexOf("--",n+1):-1;p(n>=0&&r>n,"srt-win argv: expected `exec … -- <shell> <command>`");const o=new Set;for(let l=n+1;l<r;l++)e[l]==="--env"&&typeof e[l+1]=="string"&&o.add(e[l+1].split("=")[0].toUpperCase());const s=[];for(const[l,c]of Object.entries(t||{}))p(/^[A-Za-z_][A-Za-z0-9_]*$/.test(l),`srt-win env: bad key ${l}`),p(!/[\r\n]/.test(c),`srt-win env: ${l} holds a newline`),o.has(l.toUpperCase())||s.push("--env",`${l}=${c}`);return[...e.slice(0,r),...s,...e.slice(r)]}export{C as CA_BUNDLE_RELPATH,ce as CA_BUNDLE_RELPATH_LEGACY,z as COMMON_WRITE,F as DEVELOPER_HOSTS,v as ENGINE_KITS,V as GATEWAY_FENCE,N as NETWORK_MODES,k as SANDBOX_LAYERS,ke as SANDBOX_READ_MODES,Ne as SANDBOX_RUNTIMES,S as SECRET_PATHS,j as SECRET_READ_GLOBS,Ie as SIGN_IN_LABELS,Re as SIGN_IN_NAMES,I as SIGN_IN_STORES,B as TOOLCHAIN_READ,oe as WINDOWS_CARRY_KEYS,le as caBundlePath,je as expandWrapper,ue as gatewayKit,W as isSecretWritePath,q as kitFor,Se as mergeGrants,Oe as mergePersonGrants,xe as normalizeGrant,Ae as parseHostList,We as parseWrapperTemplate,ae as readDenialFor,ge as sandboxEnvOverlay,pe as sandboxRecord,me as shellJoin,J as shellQuote,de as signInDenial,Y as signInHosts,D as signInRead,fe as toSrtSettings,b as underWindowsHome,$ as validateKit,he as windowsGrantsFor,ne as windowsInstallRoot,ye as windowsSandboxEnv,Ee as withSrtWinEnv,Z as writableRoots};
|