@xenosystem/agent-sdk 0.10.30 → 0.10.32
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/dist/artifacts/index.cjs +6 -6
- package/dist/artifacts/index.js +7 -7
- package/dist/artifacts/metafile-cjs.json +1 -1
- package/dist/artifacts/metafile-esm.json +1 -1
- package/dist/automation/index.cjs +1 -1
- package/dist/automation/index.d.cts +6 -2
- package/dist/automation/index.d.ts +6 -2
- package/dist/automation/index.js +1 -1
- package/dist/automation/metafile-cjs.json +1 -1
- package/dist/automation/metafile-esm.json +1 -1
- package/dist/control-plane/index.cjs +1 -1
- package/dist/control-plane/index.js +1 -1
- package/dist/coordination/index.cjs +2 -2
- package/dist/coordination/index.d.cts +9 -3
- package/dist/coordination/index.d.ts +9 -3
- package/dist/coordination/index.js +2 -2
- package/dist/coordination/metafile-cjs.json +1 -1
- package/dist/coordination/metafile-esm.json +1 -1
- package/dist/electron/index.cjs +222 -188
- package/dist/electron/index.d.cts +8 -2
- package/dist/electron/index.d.ts +8 -2
- package/dist/electron/index.js +222 -188
- package/dist/electron/metafile-cjs.json +1 -1
- package/dist/electron/metafile-esm.json +1 -1
- package/dist/hooks/index.cjs +4 -4
- package/dist/hooks/index.d.cts +18 -0
- package/dist/hooks/index.d.ts +18 -0
- package/dist/hooks/index.js +4 -4
- package/dist/hooks/metafile-cjs.json +1 -1
- package/dist/hooks/metafile-esm.json +1 -1
- package/dist/hosted/index.cjs +1 -1
- package/dist/hosted/index.d.cts +21 -3
- package/dist/hosted/index.d.ts +21 -3
- package/dist/hosted/index.js +1 -1
- package/dist/hosted/metafile-cjs.json +1 -1
- package/dist/hosted/metafile-esm.json +1 -1
- package/dist/index.cjs +432 -380
- package/dist/index.d.cts +283 -19
- package/dist/index.d.ts +283 -19
- package/dist/index.js +431 -379
- package/dist/intelligence/index.cjs +5 -5
- package/dist/intelligence/index.js +6 -6
- package/dist/intelligence/metafile-cjs.json +1 -1
- package/dist/intelligence/metafile-esm.json +1 -1
- package/dist/mcp/index.cjs +21 -21
- package/dist/mcp/index.d.cts +61 -6
- package/dist/mcp/index.d.ts +61 -6
- package/dist/mcp/index.js +21 -21
- package/dist/mcp/metafile-cjs.json +1 -1
- package/dist/mcp/metafile-esm.json +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/providers/metafile-cjs.json +1 -1
- package/dist/providers/metafile-esm.json +1 -1
- package/dist/recipes/metafile-cjs.json +1 -1
- package/dist/recipes/metafile-esm.json +1 -1
- package/dist/research/metafile-cjs.json +1 -1
- package/dist/research/metafile-esm.json +1 -1
- package/dist/session/index.cjs +24 -24
- package/dist/session/index.js +21 -21
- package/dist/session/metafile-cjs.json +1 -1
- package/dist/session/metafile-esm.json +1 -1
- package/dist/sharing/index.cjs +2 -2
- package/dist/sharing/index.js +3 -3
- package/dist/sharing/metafile-cjs.json +1 -1
- package/dist/sharing/metafile-esm.json +1 -1
- package/dist/skills/index.d.cts +5 -1
- package/dist/skills/index.d.ts +5 -1
- package/dist/utils/index.cjs +19 -18
- package/dist/utils/index.d.cts +5 -2
- package/dist/utils/index.d.ts +5 -2
- package/dist/utils/index.js +19 -18
- package/dist/utils/metafile-cjs.json +1 -1
- package/dist/utils/metafile-esm.json +1 -1
- package/package.json +2 -2
package/dist/hooks/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var B=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var se=(e,o)=>{for(var t in o)B(e,t,{get:o[t],enumerable:!0})},ie=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of ne(o))!re.call(e,r)&&r!==t&&B(e,r,{get:()=>o[r],enumerable:!(n=te(o,r))||n.enumerable});return e};var ae=e=>ie(B({},"__esModule",{value:!0}),e);var Me={};se(Me,{AgentHookRunner:()=>b,CommandHookRunner:()=>X,HookRunner:()=>N,HookRuntime:()=>_,HttpHookRunner:()=>C,PromptHookRunner:()=>S,buildHookEnvironment:()=>U,hookResultStatus:()=>k,normalizeHookDecision:()=>x,runAgentHook:()=>D,runCommandHook:()=>E,runHookDefinition:()=>M,runHooks:()=>A,runHttpHook:()=>O,runPromptHook:()=>v});module.exports=ae(Me);var G=require("node:child_process");var L=require("node:child_process"),ue=5e3,J=128;function le(e,o,t){let n={tool:e,timeoutMs:t};return o.timedOut?{...n,terminated:!1,reason:"timeout",exitCode:null,detail:`${e} did not finish within ${t}ms`}:o.error!==void 0?{...n,terminated:!1,reason:"spawn-error",exitCode:null,detail:o.error}:o.status===0?{...n,terminated:!0,reason:"terminated",exitCode:0}:e==="taskkill"&&o.status===J?{...n,terminated:!0,reason:"not-running",exitCode:J}:{...n,terminated:!1,reason:"failed",exitCode:o.status,detail:`${e} exited with code ${o.status??"unknown"}`}}var ce=(e,o,t)=>new Promise(n=>{let r=!1,s={},u=a=>{r||(r=!0,s.timer&&clearTimeout(s.timer),n(a))},i;try{i=(0,L.spawn)(e,[...o],{stdio:"ignore",windowsHide:!0})}catch(a){u({status:null,timedOut:!1,error:a instanceof Error?a.message:String(a)});return}s.timer=setTimeout(()=>{try{i.kill("SIGKILL")}catch{}u({status:null,timedOut:!0})},t),s.timer.unref?.(),i.once("error",a=>{u({status:null,timedOut:!1,error:a.code??a.message})}),i.once("close",a=>{u(a===null?{status:null,timedOut:!1,error:"no exit status"}:{status:a,timedOut:!1})})});function j(e){return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):ue}function de(e,o){return{terminated:!1,reason:"failed",tool:e,exitCode:null,timeoutMs:o,detail:"pid is not a positive integer"}}function me(e){return["/PID",String(e),"/T","/F"]}async function z(e,o={}){let t=j(o.timeoutMs);return!Number.isSafeInteger(e)||e<=0?de("taskkill",t):fe("taskkill","taskkill.exe",me(e),{timeoutMs:t,run:o.run})}async function fe(e,o,t,n={}){let r=j(n.timeoutMs),s;try{s=await(n.run??ce)(o,t,r)}catch(u){s={status:null,timedOut:!1,error:u instanceof Error?u.message:String(u)}}return le(e,s,r)}var pe=3e4,ke=64*1024,Pe=/(^|_)(TOKEN|SECRET|PASSWORD|PASS|KEY|CREDENTIAL|COOKIE|AUTH|AUTHORIZATION)(_|$)/i,He=new Set(["PATH","Path","PATHEXT","SystemRoot","WINDIR","ComSpec","TMP","TEMP","HOME","USERPROFILE"]);function I(){return Date.now()}function V(e,o){return!Number.isFinite(e)||e===void 0?o:Math.max(1,Math.floor(e))}function W(e,o,t){if(Buffer.byteLength(e)>=t)return{value:e,truncated:!0};let n=e+o.toString("utf8");return Buffer.byteLength(n)<=t?{value:n,truncated:!1}:{value:Buffer.from(n,"utf8").subarray(0,t).toString("utf8"),truncated:!0}}function $(e){return e.replace(/\r\n/g,`
|
|
2
2
|
`).split(`
|
|
3
|
-
`).map(o=>o.trim()).find(o=>o.length>0)}function
|
|
3
|
+
`).map(o=>o.trim()).find(o=>o.length>0)}function x(e){if(typeof e!="object"||e===null||Array.isArray(e))throw new Error("Hook stdout JSON must be an object");let o=e,t=o.decision;if(t==="allow")return{decision:t,...typeof o.systemMessage=="string"?{systemMessage:o.systemMessage}:{},...typeof o.context=="string"?{context:o.context}:{}};if(t==="block"){let n=typeof o.reason=="string"&&o.reason.trim()?o.reason.trim():"Hook blocked the operation";return{decision:t,reason:n,...typeof o.systemMessage=="string"?{systemMessage:o.systemMessage}:{}}}if(t==="ask"){let n=typeof o.reason=="string"&&o.reason.trim()?o.reason.trim():"Hook requested user confirmation",r=typeof o.prompt=="string"&&o.prompt.trim()?o.prompt.trim():n;return{decision:t,reason:n,prompt:r}}if(t==="modify")return{decision:t,patch:o.patch,...typeof o.reason=="string"?{reason:o.reason}:{}};if(t==="continue")return{decision:t,...typeof o.context=="string"?{context:o.context}:{},...typeof o.systemMessage=="string"?{systemMessage:o.systemMessage}:{}};throw new Error(`Unsupported hook decision: ${String(t)}`)}function ge(e){let o=e.trim();if(o)return x(JSON.parse(o))}function U(e,o,t=process.env){let n={};for(let[r,s]of Object.entries(t))s!==void 0&&(!He.has(r)&&Pe.test(r)||(n[r]=s));for(let[r,s]of Object.entries(o.env??{}))n[r]=s;return n.XENO_PROJECT_DIR=e.cwd,n.XENO_SESSION_ID=e.sessionId,n.XENO_RUN_ID=e.runId,n.XENO_ROOT_RUN_ID=e.rootRunId,n.XENO_AGENT_ID=e.agentId,n.XENO_HOOK_EVENT=e.event,n.XENO_PERMISSION_MODE=e.permissionMode,n.XENO_MODEL=e.model,e.effort&&(n.XENO_EFFORT=e.effort),e.parentAgentId&&(n.XENO_PARENT_AGENT_ID=e.parentAgentId),e.transcriptPath&&(n.XENO_TRANSCRIPT_PATH=e.transcriptPath),n}var ye=5e3;function we(e,o,t,n){if(process.platform==="win32"){z(o,{timeoutMs:ye,run:n}).then(r=>{if(t(r),!r.terminated&&e.exitCode===null&&e.signalCode===null)try{e.kill("SIGKILL")}catch{}});return}try{process.kill(-o,"SIGTERM")}catch{try{process.kill(o,"SIGTERM")}catch{return}}setTimeout(()=>{try{process.kill(-o,"SIGKILL")}catch{try{process.kill(o,"SIGKILL")}catch{}}},1e3).unref()}function k(e){return e?e.decision==="block"?"blocked":e.decision==="ask"?"asked":e.decision==="modify"?"modified":e.decision==="continue"?"continued":"allowed":"allowed"}async function E(e,o,t={}){let n=I(),r=V(e.timeoutMs??t.defaultTimeoutMs,pe),s=V(e.maxOutputBytes??t.defaultMaxOutputBytes,ke),u=U(o,e,t.env),i=e.cwd??o.cwd;return new Promise(a=>{let l="",c="",p=!1,m=!1,P=!1,w=!1,h,H=(0,G.spawn)(e.command,e.args??[],{cwd:i,env:u,shell:e.shell??!1,detached:process.platform!=="win32",windowsHide:!0,stdio:["pipe","pipe","pipe"]}),K=d=>{w||(w=!0,clearTimeout(oe),a(d))},oe=setTimeout(()=>{P=!0,H.pid&&we(H,H.pid,d=>{h=d},t.processTreeKillRunner)},r);H.stdout.on("data",d=>{let f=W(l,d,s);l=f.value,p=p||f.truncated}),H.stderr.on("data",d=>{let f=W(c,d,s);c=f.value,m=m||f.truncated}),H.on("error",d=>{let f=e.failClosed?{decision:"block",reason:`Hook command failed: ${d.message}`}:void 0;K({hook:e,status:f?k(f):"errored",...f?{decision:f}:{},stdout:l,stderr:c,stdoutTruncated:p,stderrTruncated:m,timedOut:P,durationMs:I()-n,error:d.message})}),H.on("close",(d,f)=>{if(P){let y=e.failClosed?{decision:"block",reason:`Hook timed out after ${r}ms`}:void 0;K({hook:e,status:y?k(y):"timed_out",...y?{decision:y}:{},exitCode:d,signal:f,stdout:l,stderr:c,stdoutTruncated:p,stderrTruncated:m,timedOut:P,durationMs:I()-n,error:h&&!h.terminated?`Hook timed out after ${r}ms; its process tree was not terminated (${h.reason})`:`Hook timed out after ${r}ms`,...h?{processTreeKill:h}:{}});return}let g,T;if(d===0)try{g=ge(l)}catch(y){T=y instanceof Error?y.message:String(y),e.failClosed&&(g={decision:"block",reason:`Invalid hook output: ${T}`})}else d===2?g={decision:"block",reason:$(l)??$(c)??"Hook blocked the operation"}:e.failClosed&&(g={decision:"block",reason:$(c)??`Hook exited with code ${d??"unknown"}`});K({hook:e,status:T&&!g?"errored":k(g),...g?{decision:g}:{},exitCode:d,signal:f,stdout:l,stderr:c,stdoutTruncated:p,stderrTruncated:m,timedOut:P,durationMs:I()-n,...T?{error:T}:{}})}),H.stdin.end(JSON.stringify(o))})}function he(e){return e.trim().toLowerCase().replace(/\.+$/,"")}function q(e,o){let t=he(o);if(!t)return!1;if(t==="*")return!0;if(t.startsWith("*.")){let n=t.slice(2);return e===n||e.endsWith(`.${n}`)}return e===t||e.endsWith(`.${t}`)}function Y(e,o){let t;try{t=new URL(o).hostname.toLowerCase().replace(/\.+$/,"")}catch{return{decision:"deny",allowed:!1,hostname:null,matchedDomain:null,reason:"network policy denied malformed URL"}}let n=e.network.denyDomains.find(s=>q(t,s));if(n)return{decision:"deny",allowed:!1,hostname:t,matchedDomain:n,reason:`network policy denied ${t} by ${n}`};let r=e.network.allowDomains.find(s=>q(t,s));return r?{decision:"allow",allowed:!0,hostname:t,matchedDomain:r,reason:`network policy allowed ${t} by ${r}`}:{decision:e.network.default,allowed:e.network.default!=="deny",hostname:t,matchedDomain:null,reason:`network policy default ${e.network.default} for ${t}`}}var Te=3e4,xe=64*1024;function F(){return Date.now()}function Z(e,o){return!Number.isFinite(e)||e===void 0?o:Math.max(1,Math.floor(e))}function Q(e,o,t){if(Buffer.byteLength(e)>=t)return{value:e,truncated:!0};let n=e+o.toString("utf8");return Buffer.byteLength(n)<=t?{value:n,truncated:!1}:{value:Buffer.from(n,"utf8").subarray(0,t).toString("utf8"),truncated:!0}}function Ee(e){return e.replace(/\r\n/g,`
|
|
4
4
|
`).split(`
|
|
5
|
-
`).map(o=>o.trim()).find(o=>o.length>0)}function
|
|
5
|
+
`).map(o=>o.trim()).find(o=>o.length>0)}function Oe(e){let o=e.trim();if(o)return x(JSON.parse(o))}async function Re(e,o){if(!e.body){let s=await e.text(),u=Q("",Buffer.from(s,"utf8"),o);return{stdout:u.value,stdoutTruncated:u.truncated}}let t=e.body.getReader(),n="",r=!1;try{for(;;){let{done:s,value:u}=await t.read();if(s)break;let i=Q(n,Buffer.from(u),o);if(n=i.value,r=r||i.truncated,r){await t.cancel();break}}}finally{t.releaseLock()}return{stdout:n,stdoutTruncated:r}}function ve(e,o){let t=new Headers(e.headers??{});return t.has("content-type")||t.set("content-type","application/json"),t.has("accept")||t.set("accept","application/json"),t.set("x-xeno-hook-event",o.event),t.set("x-xeno-session-id",o.sessionId),t.set("x-xeno-run-id",o.runId),t}function De(e,o){if(!o.permissionProfile)return;let t=Y(o.permissionProfile,e.url);if(!t.allowed)throw new Error(`HTTP hook network policy denied: ${t.reason}`)}async function O(e,o,t={}){let n=F(),r=Z(e.timeoutMs??t.defaultTimeoutMs,Te),s=Z(e.maxOutputBytes??t.defaultMaxOutputBytes,xe),u=new AbortController,i=!1,a=setTimeout(()=>{i=!0,u.abort()},r);try{De(e,t);let l=await fetch(e.url,{method:e.method??"POST",headers:ve(e,o),body:JSON.stringify(o),signal:u.signal}),{stdout:c,stdoutTruncated:p}=await Re(l,s),m,P;if(l.ok)try{m=Oe(c)}catch(w){P=w instanceof Error?w.message:String(w),e.failClosed&&(m={decision:"block",reason:`Invalid HTTP hook output: ${P}`})}else e.failClosed&&(m={decision:"block",reason:Ee(c)??`HTTP hook failed with status ${l.status}`});return{hook:e,status:P&&!m?"errored":l.ok||m?k(m):"errored",...m?{decision:m}:{},stdout:c,stderr:"",stdoutTruncated:p,stderrTruncated:!1,timedOut:i,durationMs:F()-n,...l.ok?{}:{error:`HTTP ${l.status} ${l.statusText}`.trim()},...P?{error:P}:{}}}catch(l){let c=l instanceof Error?l.message:String(l),p=e.failClosed?{decision:"block",reason:i?`HTTP hook timed out after ${r}ms`:`HTTP hook failed: ${c}`}:void 0;return{hook:e,status:p?k(p):i?"timed_out":"errored",...p?{decision:p}:{},stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1,timedOut:i,durationMs:F()-n,error:i?`HTTP hook timed out after ${r}ms`:c}}finally{clearTimeout(a)}}var R=require("node:perf_hooks");async function ee(e,o,t,n){let r=R.performance.now();if(!t){let i=`No ${e.type} hook executor is configured.`,a=e.failClosed?{decision:"block",reason:i}:void 0;return{hook:e,status:a?k(a):"errored",...a?{decision:a}:{},stdout:"",stderr:i,stdoutTruncated:!1,stderrTruncated:!1,timedOut:!1,durationMs:R.performance.now()-r,error:i}}let s=Math.max(1,Math.trunc(e.timeoutMs??n.defaultTimeoutMs??3e4)),u;try{let i=await Promise.race([t(e,o),new Promise((a,l)=>{u=setTimeout(()=>l(new Error(`Hook timed out after ${s}ms`)),s),u.unref?.()})]);return{hook:e,status:k(i),decision:i,stdout:JSON.stringify(i),stderr:"",stdoutTruncated:!1,stderrTruncated:!1,timedOut:!1,durationMs:R.performance.now()-r}}catch(i){let a=i instanceof Error?i.message:String(i),l=/timed out/i.test(a),c=e.failClosed?{decision:"block",reason:a}:void 0;return{hook:e,status:c?k(c):l?"timed_out":"errored",...c?{decision:c}:{},stdout:"",stderr:a,stdoutTruncated:!1,stderrTruncated:!1,timedOut:l,durationMs:R.performance.now()-r,error:a}}finally{u&&clearTimeout(u)}}function v(e,o,t={}){return ee(e,o,t.promptExecutor,t)}function D(e,o,t={}){return ee(e,o,t.agentExecutor,t)}var S=class{constructor(o,t={}){this.executor=o;this.options=t}executor;options;run(o,t){return v(o,t,{...this.options,promptExecutor:this.executor})}},b=class{constructor(o,t={}){this.executor=o;this.options=t}executor;options;run(o,t){return D(o,t,{...this.options,agentExecutor:this.executor})}};function Ie(e,o){return!e.events||e.events.length===0||e.events.includes(o)}function Se(e,o,t){e&&("context"in e&&typeof e.context=="string"&&e.context.trim()&&o.push(e.context.trim()),"systemMessage"in e&&typeof e.systemMessage=="string"&&e.systemMessage.trim()&&t.push(e.systemMessage.trim()))}function be(e){return e&&(e.decision==="block"||e.decision==="ask"||e.decision==="modify")?e:null}async function M(e,o,t={}){switch(e.type){case"command":return E(e,o,t);case"http":return O(e,o,t);case"prompt":return v(e,o,t);case"agent":return D(e,o,t);default:throw new Error(`Unsupported hook type: ${String(e.type??"unknown")}`)}}async function A(e,o,t={}){let n=[],r=[],s=[];for(let u of e){if(!Ie(u,o.event))continue;if(u.async){M(u,o,t).catch(()=>{});continue}let i=await M(u,o,t);n.push(i),Se(i.decision,r,s);let a=be(i.decision);if(a)return{decision:a,results:n,context:r,systemMessages:s}}return{decision:r.length>0||s.length>0?{decision:"continue",...r.length>0?{context:r.join(`
|
|
6
6
|
|
|
7
7
|
`)}:{},...s.length>0?{systemMessage:s.join(`
|
|
8
8
|
|
|
9
|
-
`)}:{}}:{decision:"allow"},results:n,context:r,systemMessages:s}}var
|
|
9
|
+
`)}:{}}:{decision:"allow"},results:n,context:r,systemMessages:s}}var N=class{constructor(o,t={}){this.hooks=o;this.options=t}hooks;options;run(o){return A(this.hooks,o,this.options)}},_=class{constructor(o,t={}){this.config=o;this.options=t}config;options;run(o){let t=[...this.config.hooks??[],...this.config.events?.[o.event]??[]];return A([...new Set(t)],o,this.options)}},X=class{constructor(o={}){this.options=o}options;run(o,t){return E(o,t,this.options)}},C=class{constructor(o={}){this.options=o}options;run(o,t){return O(o,t,this.options)}};0&&(module.exports={AgentHookRunner,CommandHookRunner,HookRunner,HookRuntime,HttpHookRunner,PromptHookRunner,buildHookEnvironment,hookResultStatus,normalizeHookDecision,runAgentHook,runCommandHook,runHookDefinition,runHooks,runHttpHook,runPromptHook});
|
package/dist/hooks/index.d.cts
CHANGED
|
@@ -45,6 +45,22 @@ declare const AGENT_PERMISSION_MODES: readonly [
|
|
|
45
45
|
"bypassPermissions"
|
|
46
46
|
];
|
|
47
47
|
type AgentPermissionMode = (typeof AGENT_PERMISSION_MODES)[number];
|
|
48
|
+
type XenoProcessTreeKillTool = "taskkill" | "powershell";
|
|
49
|
+
type XenoProcessTreeKillReason = "terminated" | "not-running" | "timeout" | "spawn-error" | "failed";
|
|
50
|
+
interface XenoProcessTreeKillResult {
|
|
51
|
+
terminated: boolean;
|
|
52
|
+
reason: XenoProcessTreeKillReason;
|
|
53
|
+
tool: XenoProcessTreeKillTool;
|
|
54
|
+
exitCode: number | null;
|
|
55
|
+
timeoutMs: number;
|
|
56
|
+
detail?: string;
|
|
57
|
+
}
|
|
58
|
+
interface XenoBoundedProcessOutcome {
|
|
59
|
+
status: number | null;
|
|
60
|
+
timedOut: boolean;
|
|
61
|
+
error?: string;
|
|
62
|
+
}
|
|
63
|
+
type XenoBoundedProcessRunner = (file: string, args: readonly string[], timeoutMs: number) => Promise<XenoBoundedProcessOutcome>;
|
|
48
64
|
type HookEventName = "SessionStart" | "UserPromptSubmit" | "PermissionRequest" | "PreToolUse" | "PostToolUse" | "PreCompact" | "PostCompact" | "Stop" | "StopFailure" | "SubagentStart" | "SubagentStop";
|
|
49
65
|
type HookPermissionMode = AgentPermissionMode;
|
|
50
66
|
interface HookInputBase {
|
|
@@ -146,6 +162,7 @@ interface HookExecutionResult {
|
|
|
146
162
|
timedOut: boolean;
|
|
147
163
|
durationMs: number;
|
|
148
164
|
error?: string;
|
|
165
|
+
processTreeKill?: XenoProcessTreeKillResult;
|
|
149
166
|
}
|
|
150
167
|
interface HookRunResult {
|
|
151
168
|
decision: HookDecision;
|
|
@@ -160,6 +177,7 @@ interface HookRuntimeOptions {
|
|
|
160
177
|
permissionProfile?: PermissionProfile;
|
|
161
178
|
promptExecutor?: HookModelExecutor;
|
|
162
179
|
agentExecutor?: HookModelExecutor;
|
|
180
|
+
processTreeKillRunner?: XenoBoundedProcessRunner;
|
|
163
181
|
}
|
|
164
182
|
declare function normalizeHookDecision(value: unknown): HookDecision;
|
|
165
183
|
declare function buildHookEnvironment(input: HookInvocationInput, definition: CommandHookDefinition, sourceEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -45,6 +45,22 @@ declare const AGENT_PERMISSION_MODES: readonly [
|
|
|
45
45
|
"bypassPermissions"
|
|
46
46
|
];
|
|
47
47
|
type AgentPermissionMode = (typeof AGENT_PERMISSION_MODES)[number];
|
|
48
|
+
type XenoProcessTreeKillTool = "taskkill" | "powershell";
|
|
49
|
+
type XenoProcessTreeKillReason = "terminated" | "not-running" | "timeout" | "spawn-error" | "failed";
|
|
50
|
+
interface XenoProcessTreeKillResult {
|
|
51
|
+
terminated: boolean;
|
|
52
|
+
reason: XenoProcessTreeKillReason;
|
|
53
|
+
tool: XenoProcessTreeKillTool;
|
|
54
|
+
exitCode: number | null;
|
|
55
|
+
timeoutMs: number;
|
|
56
|
+
detail?: string;
|
|
57
|
+
}
|
|
58
|
+
interface XenoBoundedProcessOutcome {
|
|
59
|
+
status: number | null;
|
|
60
|
+
timedOut: boolean;
|
|
61
|
+
error?: string;
|
|
62
|
+
}
|
|
63
|
+
type XenoBoundedProcessRunner = (file: string, args: readonly string[], timeoutMs: number) => Promise<XenoBoundedProcessOutcome>;
|
|
48
64
|
type HookEventName = "SessionStart" | "UserPromptSubmit" | "PermissionRequest" | "PreToolUse" | "PostToolUse" | "PreCompact" | "PostCompact" | "Stop" | "StopFailure" | "SubagentStart" | "SubagentStop";
|
|
49
65
|
type HookPermissionMode = AgentPermissionMode;
|
|
50
66
|
interface HookInputBase {
|
|
@@ -146,6 +162,7 @@ interface HookExecutionResult {
|
|
|
146
162
|
timedOut: boolean;
|
|
147
163
|
durationMs: number;
|
|
148
164
|
error?: string;
|
|
165
|
+
processTreeKill?: XenoProcessTreeKillResult;
|
|
149
166
|
}
|
|
150
167
|
interface HookRunResult {
|
|
151
168
|
decision: HookDecision;
|
|
@@ -160,6 +177,7 @@ interface HookRuntimeOptions {
|
|
|
160
177
|
permissionProfile?: PermissionProfile;
|
|
161
178
|
promptExecutor?: HookModelExecutor;
|
|
162
179
|
agentExecutor?: HookModelExecutor;
|
|
180
|
+
processTreeKillRunner?: XenoBoundedProcessRunner;
|
|
163
181
|
}
|
|
164
182
|
declare function normalizeHookDecision(value: unknown): HookDecision;
|
|
165
183
|
declare function buildHookEnvironment(input: HookInvocationInput, definition: CommandHookDefinition, sourceEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{spawn as
|
|
1
|
+
import{spawn as ie}from"node:child_process";import{spawn as Q,spawnSync as Re}from"node:child_process";var ee=5e3,$=128;function oe(e,o,t){let n={tool:e,timeoutMs:t};return o.timedOut?{...n,terminated:!1,reason:"timeout",exitCode:null,detail:`${e} did not finish within ${t}ms`}:o.error!==void 0?{...n,terminated:!1,reason:"spawn-error",exitCode:null,detail:o.error}:o.status===0?{...n,terminated:!0,reason:"terminated",exitCode:0}:e==="taskkill"&&o.status===$?{...n,terminated:!0,reason:"not-running",exitCode:$}:{...n,terminated:!1,reason:"failed",exitCode:o.status,detail:`${e} exited with code ${o.status??"unknown"}`}}var te=(e,o,t)=>new Promise(n=>{let r=!1,s={},u=a=>{r||(r=!0,s.timer&&clearTimeout(s.timer),n(a))},i;try{i=Q(e,[...o],{stdio:"ignore",windowsHide:!0})}catch(a){u({status:null,timedOut:!1,error:a instanceof Error?a.message:String(a)});return}s.timer=setTimeout(()=>{try{i.kill("SIGKILL")}catch{}u({status:null,timedOut:!0})},t),s.timer.unref?.(),i.once("error",a=>{u({status:null,timedOut:!1,error:a.code??a.message})}),i.once("close",a=>{u(a===null?{status:null,timedOut:!1,error:"no exit status"}:{status:a,timedOut:!1})})});function U(e){return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):ee}function ne(e,o){return{terminated:!1,reason:"failed",tool:e,exitCode:null,timeoutMs:o,detail:"pid is not a positive integer"}}function re(e){return["/PID",String(e),"/T","/F"]}async function F(e,o={}){let t=U(o.timeoutMs);return!Number.isSafeInteger(e)||e<=0?ne("taskkill",t):se("taskkill","taskkill.exe",re(e),{timeoutMs:t,run:o.run})}async function se(e,o,t,n={}){let r=U(n.timeoutMs),s;try{s=await(n.run??te)(o,t,r)}catch(u){s={status:null,timedOut:!1,error:u instanceof Error?u.message:String(u)}}return oe(e,s,r)}var ae=3e4,ue=64*1024,le=/(^|_)(TOKEN|SECRET|PASSWORD|PASS|KEY|CREDENTIAL|COOKIE|AUTH|AUTHORIZATION)(_|$)/i,ce=new Set(["PATH","Path","PATHEXT","SystemRoot","WINDIR","ComSpec","TMP","TEMP","HOME","USERPROFILE"]);function x(){return Date.now()}function J(e,o){return!Number.isFinite(e)||e===void 0?o:Math.max(1,Math.floor(e))}function j(e,o,t){if(Buffer.byteLength(e)>=t)return{value:e,truncated:!0};let n=e+o.toString("utf8");return Buffer.byteLength(n)<=t?{value:n,truncated:!1}:{value:Buffer.from(n,"utf8").subarray(0,t).toString("utf8"),truncated:!0}}function b(e){return e.replace(/\r\n/g,`
|
|
2
2
|
`).split(`
|
|
3
|
-
`).map(o=>o.trim()).find(o=>o.length>0)}function
|
|
3
|
+
`).map(o=>o.trim()).find(o=>o.length>0)}function E(e){if(typeof e!="object"||e===null||Array.isArray(e))throw new Error("Hook stdout JSON must be an object");let o=e,t=o.decision;if(t==="allow")return{decision:t,...typeof o.systemMessage=="string"?{systemMessage:o.systemMessage}:{},...typeof o.context=="string"?{context:o.context}:{}};if(t==="block"){let n=typeof o.reason=="string"&&o.reason.trim()?o.reason.trim():"Hook blocked the operation";return{decision:t,reason:n,...typeof o.systemMessage=="string"?{systemMessage:o.systemMessage}:{}}}if(t==="ask"){let n=typeof o.reason=="string"&&o.reason.trim()?o.reason.trim():"Hook requested user confirmation",r=typeof o.prompt=="string"&&o.prompt.trim()?o.prompt.trim():n;return{decision:t,reason:n,prompt:r}}if(t==="modify")return{decision:t,patch:o.patch,...typeof o.reason=="string"?{reason:o.reason}:{}};if(t==="continue")return{decision:t,...typeof o.context=="string"?{context:o.context}:{},...typeof o.systemMessage=="string"?{systemMessage:o.systemMessage}:{}};throw new Error(`Unsupported hook decision: ${String(t)}`)}function de(e){let o=e.trim();if(o)return E(JSON.parse(o))}function z(e,o,t=process.env){let n={};for(let[r,s]of Object.entries(t))s!==void 0&&(!ce.has(r)&&le.test(r)||(n[r]=s));for(let[r,s]of Object.entries(o.env??{}))n[r]=s;return n.XENO_PROJECT_DIR=e.cwd,n.XENO_SESSION_ID=e.sessionId,n.XENO_RUN_ID=e.runId,n.XENO_ROOT_RUN_ID=e.rootRunId,n.XENO_AGENT_ID=e.agentId,n.XENO_HOOK_EVENT=e.event,n.XENO_PERMISSION_MODE=e.permissionMode,n.XENO_MODEL=e.model,e.effort&&(n.XENO_EFFORT=e.effort),e.parentAgentId&&(n.XENO_PARENT_AGENT_ID=e.parentAgentId),e.transcriptPath&&(n.XENO_TRANSCRIPT_PATH=e.transcriptPath),n}var me=5e3;function fe(e,o,t,n){if(process.platform==="win32"){F(o,{timeoutMs:me,run:n}).then(r=>{if(t(r),!r.terminated&&e.exitCode===null&&e.signalCode===null)try{e.kill("SIGKILL")}catch{}});return}try{process.kill(-o,"SIGTERM")}catch{try{process.kill(o,"SIGTERM")}catch{return}}setTimeout(()=>{try{process.kill(-o,"SIGKILL")}catch{try{process.kill(o,"SIGKILL")}catch{}}},1e3).unref()}function P(e){return e?e.decision==="block"?"blocked":e.decision==="ask"?"asked":e.decision==="modify"?"modified":e.decision==="continue"?"continued":"allowed":"allowed"}async function O(e,o,t={}){let n=x(),r=J(e.timeoutMs??t.defaultTimeoutMs,ae),s=J(e.maxOutputBytes??t.defaultMaxOutputBytes,ue),u=z(o,e,t.env),i=e.cwd??o.cwd;return new Promise(a=>{let l="",c="",p=!1,m=!1,k=!1,w=!1,h,H=ie(e.command,e.args??[],{cwd:i,env:u,shell:e.shell??!1,detached:process.platform!=="win32",windowsHide:!0,stdio:["pipe","pipe","pipe"]}),S=d=>{w||(w=!0,clearTimeout(Z),a(d))},Z=setTimeout(()=>{k=!0,H.pid&&fe(H,H.pid,d=>{h=d},t.processTreeKillRunner)},r);H.stdout.on("data",d=>{let f=j(l,d,s);l=f.value,p=p||f.truncated}),H.stderr.on("data",d=>{let f=j(c,d,s);c=f.value,m=m||f.truncated}),H.on("error",d=>{let f=e.failClosed?{decision:"block",reason:`Hook command failed: ${d.message}`}:void 0;S({hook:e,status:f?P(f):"errored",...f?{decision:f}:{},stdout:l,stderr:c,stdoutTruncated:p,stderrTruncated:m,timedOut:k,durationMs:x()-n,error:d.message})}),H.on("close",(d,f)=>{if(k){let y=e.failClosed?{decision:"block",reason:`Hook timed out after ${r}ms`}:void 0;S({hook:e,status:y?P(y):"timed_out",...y?{decision:y}:{},exitCode:d,signal:f,stdout:l,stderr:c,stdoutTruncated:p,stderrTruncated:m,timedOut:k,durationMs:x()-n,error:h&&!h.terminated?`Hook timed out after ${r}ms; its process tree was not terminated (${h.reason})`:`Hook timed out after ${r}ms`,...h?{processTreeKill:h}:{}});return}let g,T;if(d===0)try{g=de(l)}catch(y){T=y instanceof Error?y.message:String(y),e.failClosed&&(g={decision:"block",reason:`Invalid hook output: ${T}`})}else d===2?g={decision:"block",reason:b(l)??b(c)??"Hook blocked the operation"}:e.failClosed&&(g={decision:"block",reason:b(c)??`Hook exited with code ${d??"unknown"}`});S({hook:e,status:T&&!g?"errored":P(g),...g?{decision:g}:{},exitCode:d,signal:f,stdout:l,stderr:c,stdoutTruncated:p,stderrTruncated:m,timedOut:k,durationMs:x()-n,...T?{error:T}:{}})}),H.stdin.end(JSON.stringify(o))})}function pe(e){return e.trim().toLowerCase().replace(/\.+$/,"")}function V(e,o){let t=pe(o);if(!t)return!1;if(t==="*")return!0;if(t.startsWith("*.")){let n=t.slice(2);return e===n||e.endsWith(`.${n}`)}return e===t||e.endsWith(`.${t}`)}function W(e,o){let t;try{t=new URL(o).hostname.toLowerCase().replace(/\.+$/,"")}catch{return{decision:"deny",allowed:!1,hostname:null,matchedDomain:null,reason:"network policy denied malformed URL"}}let n=e.network.denyDomains.find(s=>V(t,s));if(n)return{decision:"deny",allowed:!1,hostname:t,matchedDomain:n,reason:`network policy denied ${t} by ${n}`};let r=e.network.allowDomains.find(s=>V(t,s));return r?{decision:"allow",allowed:!0,hostname:t,matchedDomain:r,reason:`network policy allowed ${t} by ${r}`}:{decision:e.network.default,allowed:e.network.default!=="deny",hostname:t,matchedDomain:null,reason:`network policy default ${e.network.default} for ${t}`}}var ke=3e4,Pe=64*1024;function M(){return Date.now()}function G(e,o){return!Number.isFinite(e)||e===void 0?o:Math.max(1,Math.floor(e))}function q(e,o,t){if(Buffer.byteLength(e)>=t)return{value:e,truncated:!0};let n=e+o.toString("utf8");return Buffer.byteLength(n)<=t?{value:n,truncated:!1}:{value:Buffer.from(n,"utf8").subarray(0,t).toString("utf8"),truncated:!0}}function He(e){return e.replace(/\r\n/g,`
|
|
4
4
|
`).split(`
|
|
5
|
-
`).map(o=>o.trim()).find(o=>o.length>0)}function
|
|
5
|
+
`).map(o=>o.trim()).find(o=>o.length>0)}function ge(e){let o=e.trim();if(o)return E(JSON.parse(o))}async function ye(e,o){if(!e.body){let s=await e.text(),u=q("",Buffer.from(s,"utf8"),o);return{stdout:u.value,stdoutTruncated:u.truncated}}let t=e.body.getReader(),n="",r=!1;try{for(;;){let{done:s,value:u}=await t.read();if(s)break;let i=q(n,Buffer.from(u),o);if(n=i.value,r=r||i.truncated,r){await t.cancel();break}}}finally{t.releaseLock()}return{stdout:n,stdoutTruncated:r}}function we(e,o){let t=new Headers(e.headers??{});return t.has("content-type")||t.set("content-type","application/json"),t.has("accept")||t.set("accept","application/json"),t.set("x-xeno-hook-event",o.event),t.set("x-xeno-session-id",o.sessionId),t.set("x-xeno-run-id",o.runId),t}function he(e,o){if(!o.permissionProfile)return;let t=W(o.permissionProfile,e.url);if(!t.allowed)throw new Error(`HTTP hook network policy denied: ${t.reason}`)}async function R(e,o,t={}){let n=M(),r=G(e.timeoutMs??t.defaultTimeoutMs,ke),s=G(e.maxOutputBytes??t.defaultMaxOutputBytes,Pe),u=new AbortController,i=!1,a=setTimeout(()=>{i=!0,u.abort()},r);try{he(e,t);let l=await fetch(e.url,{method:e.method??"POST",headers:we(e,o),body:JSON.stringify(o),signal:u.signal}),{stdout:c,stdoutTruncated:p}=await ye(l,s),m,k;if(l.ok)try{m=ge(c)}catch(w){k=w instanceof Error?w.message:String(w),e.failClosed&&(m={decision:"block",reason:`Invalid HTTP hook output: ${k}`})}else e.failClosed&&(m={decision:"block",reason:He(c)??`HTTP hook failed with status ${l.status}`});return{hook:e,status:k&&!m?"errored":l.ok||m?P(m):"errored",...m?{decision:m}:{},stdout:c,stderr:"",stdoutTruncated:p,stderrTruncated:!1,timedOut:i,durationMs:M()-n,...l.ok?{}:{error:`HTTP ${l.status} ${l.statusText}`.trim()},...k?{error:k}:{}}}catch(l){let c=l instanceof Error?l.message:String(l),p=e.failClosed?{decision:"block",reason:i?`HTTP hook timed out after ${r}ms`:`HTTP hook failed: ${c}`}:void 0;return{hook:e,status:p?P(p):i?"timed_out":"errored",...p?{decision:p}:{},stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1,timedOut:i,durationMs:M()-n,error:i?`HTTP hook timed out after ${r}ms`:c}}finally{clearTimeout(a)}}import{performance as v}from"node:perf_hooks";async function Y(e,o,t,n){let r=v.now();if(!t){let i=`No ${e.type} hook executor is configured.`,a=e.failClosed?{decision:"block",reason:i}:void 0;return{hook:e,status:a?P(a):"errored",...a?{decision:a}:{},stdout:"",stderr:i,stdoutTruncated:!1,stderrTruncated:!1,timedOut:!1,durationMs:v.now()-r,error:i}}let s=Math.max(1,Math.trunc(e.timeoutMs??n.defaultTimeoutMs??3e4)),u;try{let i=await Promise.race([t(e,o),new Promise((a,l)=>{u=setTimeout(()=>l(new Error(`Hook timed out after ${s}ms`)),s),u.unref?.()})]);return{hook:e,status:P(i),decision:i,stdout:JSON.stringify(i),stderr:"",stdoutTruncated:!1,stderrTruncated:!1,timedOut:!1,durationMs:v.now()-r}}catch(i){let a=i instanceof Error?i.message:String(i),l=/timed out/i.test(a),c=e.failClosed?{decision:"block",reason:a}:void 0;return{hook:e,status:c?P(c):l?"timed_out":"errored",...c?{decision:c}:{},stdout:"",stderr:a,stdoutTruncated:!1,stderrTruncated:!1,timedOut:l,durationMs:v.now()-r,error:a}}finally{u&&clearTimeout(u)}}function D(e,o,t={}){return Y(e,o,t.promptExecutor,t)}function I(e,o,t={}){return Y(e,o,t.agentExecutor,t)}var N=class{constructor(o,t={}){this.executor=o;this.options=t}executor;options;run(o,t){return D(o,t,{...this.options,promptExecutor:this.executor})}},_=class{constructor(o,t={}){this.executor=o;this.options=t}executor;options;run(o,t){return I(o,t,{...this.options,agentExecutor:this.executor})}};function Te(e,o){return!e.events||e.events.length===0||e.events.includes(o)}function xe(e,o,t){e&&("context"in e&&typeof e.context=="string"&&e.context.trim()&&o.push(e.context.trim()),"systemMessage"in e&&typeof e.systemMessage=="string"&&e.systemMessage.trim()&&t.push(e.systemMessage.trim()))}function Ee(e){return e&&(e.decision==="block"||e.decision==="ask"||e.decision==="modify")?e:null}async function X(e,o,t={}){switch(e.type){case"command":return O(e,o,t);case"http":return R(e,o,t);case"prompt":return D(e,o,t);case"agent":return I(e,o,t);default:throw new Error(`Unsupported hook type: ${String(e.type??"unknown")}`)}}async function L(e,o,t={}){let n=[],r=[],s=[];for(let u of e){if(!Te(u,o.event))continue;if(u.async){X(u,o,t).catch(()=>{});continue}let i=await X(u,o,t);n.push(i),xe(i.decision,r,s);let a=Ee(i.decision);if(a)return{decision:a,results:n,context:r,systemMessages:s}}return{decision:r.length>0||s.length>0?{decision:"continue",...r.length>0?{context:r.join(`
|
|
6
6
|
|
|
7
7
|
`)}:{},...s.length>0?{systemMessage:s.join(`
|
|
8
8
|
|
|
9
|
-
`)}:{}}:{decision:"allow"},results:n,context:r,systemMessages:s}}var
|
|
9
|
+
`)}:{}}:{decision:"allow"},results:n,context:r,systemMessages:s}}var C=class{constructor(o,t={}){this.hooks=o;this.options=t}hooks;options;run(o){return L(this.hooks,o,this.options)}},A=class{constructor(o,t={}){this.config=o;this.options=t}config;options;run(o){let t=[...this.config.hooks??[],...this.config.events?.[o.event]??[]];return L([...new Set(t)],o,this.options)}},K=class{constructor(o={}){this.options=o}options;run(o,t){return O(o,t,this.options)}},B=class{constructor(o={}){this.options=o}options;run(o,t){return R(o,t,this.options)}};export{_ as AgentHookRunner,K as CommandHookRunner,C as HookRunner,A as HookRuntime,B as HttpHookRunner,N as PromptHookRunner,z as buildHookEnvironment,P as hookResultStatus,E as normalizeHookDecision,I as runAgentHook,O as runCommandHook,X as runHookDefinition,L as runHooks,R as runHttpHook,D as runPromptHook};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/hooks/command-hook.ts":{"bytes":
|
|
1
|
+
{"inputs":{"src/runtime/process-tree-kill.ts":{"bytes":9124,"imports":[{"path":"node:child_process","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/command-hook.ts":{"bytes":10829,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"src/runtime/process-tree-kill.ts","kind":"import-statement","original":"../runtime/process-tree-kill.js"}],"format":"esm"},"src/security/permission-profile.ts":{"bytes":7737,"imports":[],"format":"esm"},"src/hooks/http-hook.ts":{"bytes":6142,"imports":[{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"},{"path":"src/security/permission-profile.ts","kind":"import-statement","original":"../security/permission-profile.js"}],"format":"esm"},"src/hooks/model-hook.ts":{"bytes":3723,"imports":[{"path":"node:perf_hooks","kind":"import-statement","external":true},{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"}],"format":"esm"},"src/hooks/runner.ts":{"bytes":4318,"imports":[{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"},{"path":"src/hooks/http-hook.ts","kind":"import-statement","original":"./http-hook.js"},{"path":"src/hooks/model-hook.ts","kind":"import-statement","original":"./model-hook.js"}],"format":"esm"},"src/hooks/index.ts":{"bytes":813,"imports":[{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"},{"path":"src/hooks/http-hook.ts","kind":"import-statement","original":"./http-hook.js"},{"path":"src/hooks/model-hook.ts","kind":"import-statement","original":"./model-hook.js"},{"path":"src/hooks/runner.ts","kind":"import-statement","original":"./runner.js"}],"format":"esm"}},"outputs":{"dist/hooks/index.cjs":{"imports":[{"path":"node:child_process","kind":"require-call","external":true},{"path":"node:child_process","kind":"require-call","external":true},{"path":"node:perf_hooks","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/hooks/index.ts","inputs":{"src/hooks/index.ts":{"bytesInOutput":361},"src/hooks/command-hook.ts":{"bytesInOutput":4741},"src/runtime/process-tree-kill.ts":{"bytesInOutput":1689},"src/security/permission-profile.ts":{"bytesInOutput":902},"src/hooks/http-hook.ts":{"bytesInOutput":2575},"src/hooks/model-hook.ts":{"bytesInOutput":1471},"src/hooks/runner.ts":{"bytesInOutput":1584}},"bytes":14011}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/hooks/command-hook.ts":{"bytes":
|
|
1
|
+
{"inputs":{"src/runtime/process-tree-kill.ts":{"bytes":9124,"imports":[{"path":"node:child_process","kind":"import-statement","external":true}],"format":"esm"},"src/hooks/command-hook.ts":{"bytes":10829,"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"src/runtime/process-tree-kill.ts","kind":"import-statement","original":"../runtime/process-tree-kill.js"}],"format":"esm"},"src/security/permission-profile.ts":{"bytes":7737,"imports":[],"format":"esm"},"src/hooks/http-hook.ts":{"bytes":6142,"imports":[{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"},{"path":"src/security/permission-profile.ts","kind":"import-statement","original":"../security/permission-profile.js"}],"format":"esm"},"src/hooks/model-hook.ts":{"bytes":3723,"imports":[{"path":"node:perf_hooks","kind":"import-statement","external":true},{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"}],"format":"esm"},"src/hooks/runner.ts":{"bytes":4318,"imports":[{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"},{"path":"src/hooks/http-hook.ts","kind":"import-statement","original":"./http-hook.js"},{"path":"src/hooks/model-hook.ts","kind":"import-statement","original":"./model-hook.js"}],"format":"esm"},"src/hooks/index.ts":{"bytes":813,"imports":[{"path":"src/hooks/command-hook.ts","kind":"import-statement","original":"./command-hook.js"},{"path":"src/hooks/http-hook.ts","kind":"import-statement","original":"./http-hook.js"},{"path":"src/hooks/model-hook.ts","kind":"import-statement","original":"./model-hook.js"},{"path":"src/hooks/runner.ts","kind":"import-statement","original":"./runner.js"}],"format":"esm"}},"outputs":{"dist/hooks/index.js":{"imports":[{"path":"node:child_process","kind":"import-statement","external":true},{"path":"node:child_process","kind":"import-statement","external":true},{"path":"node:perf_hooks","kind":"import-statement","external":true}],"exports":["AgentHookRunner","CommandHookRunner","HookRunner","HookRuntime","HttpHookRunner","PromptHookRunner","buildHookEnvironment","hookResultStatus","normalizeHookDecision","runAgentHook","runCommandHook","runHookDefinition","runHooks","runHttpHook","runPromptHook"],"entryPoint":"src/hooks/index.ts","inputs":{"src/hooks/command-hook.ts":{"bytesInOutput":4738},"src/runtime/process-tree-kill.ts":{"bytesInOutput":1706},"src/hooks/index.ts":{"bytesInOutput":0},"src/security/permission-profile.ts":{"bytesInOutput":902},"src/hooks/http-hook.ts":{"bytesInOutput":2575},"src/hooks/model-hook.ts":{"bytesInOutput":1433},"src/hooks/runner.ts":{"bytesInOutput":1584}},"bytes":13252}}}
|
package/dist/hosted/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var O=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var ge=(e,t)=>{for(var r in t)O(e,r,{get:t[r],enumerable:!0})},fe=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of me(t))!pe.call(e,o)&&o!==r&&O(e,o,{get:()=>t[o],enumerable:!(n=le(t,o))||n.enumerable});return e};var he=e=>fe(O({},"__esModule",{value:!0}),e);var Ge={};ge(Ge,{XENO_HOSTED_CONTROL_SCHEMA_VERSION:()=>q,XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION:()=>v,XENO_HOSTED_EVENT_SCHEMA_VERSION:()=>P,XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA:()=>w,XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS:()=>G,XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION:()=>M,XENO_HOSTED_EXECUTION_PROTOCOL_VERSION:()=>re,XENO_HOSTED_EXECUTION_TOOL_NAMES:()=>ne,XENO_HOSTED_RESULT_SCHEMA_VERSION:()=>L,XENO_HOSTED_RUN_SCHEMA_VERSION:()=>Qe,XENO_HOSTED_TRIGGER_SCHEMA_VERSION:()=>Ye,assertValidXenoHostedExecutionJob:()=>Me,createXenoHostedControlCommand:()=>ce,createXenoHostedEnvironmentManifest:()=>ye,createXenoHostedEvent:()=>xe,createXenoHostedExecutionBoundaryReceipt:()=>oe,createXenoHostedRunResult:()=>de,deriveHostedIdempotencyKey:()=>Ee,hostedEnvironmentIdentity:()=>be,normalizeXenoHostedControlAcknowledgement:()=>Ue,verifyXenoHostedControlCommand:()=>ze,verifyXenoHostedEnvironmentManifest:()=>I,verifyXenoHostedEventChain:()=>we,verifyXenoHostedExecutionAdapterCertification:()=>Oe,verifyXenoHostedExecutionJob:()=>se,verifyXenoHostedRunResult:()=>Je,verifyXenoHostedWebhook:()=>Ae,xenoHostedExecutionAdapterSigningPayload:()=>Xe});module.exports=he(Ge);var v=1,Qe=1,P=1,Ye=1;var x=require("node:crypto");function u(e){return JSON.stringify(N(e,new Set))}function N(e,t){if(e===null||typeof e!="object"){if(typeof e=="number"&&!Number.isFinite(e))throw new TypeError("Artifact JSON cannot contain non-finite numbers");return e}if(t.has(e))throw new TypeError("Artifact JSON cannot contain cycles");if(t.add(e),Array.isArray(e)){let n=e.map(o=>N(o,t));return t.delete(e),n}let r={};for(let n of Object.keys(e).sort((o,s)=>o.localeCompare(s))){let o=e[n];if(o===void 0)throw new TypeError(`Artifact JSON property ${n} is undefined`);r[n]=N(o,t)}return t.delete(e),r}function y(e,t={}){for(let r of e){let n=r.codePointAt(0);if(n===127)return!0;if(!(n>31)&&!(n===9&&t.allowTab===!0)&&!((n===10||n===13)&&t.allowLineBreaks===!0))return!0}return!1}function ye(e){let t={...J(e),schemaVersion:1,kind:"xeno-hosted-environment"};return{...t,checksum:{algorithm:"sha256",value:S(t)}}}function I(e){let t=[];if(e?.schemaVersion!==1||e.kind!=="xeno-hosted-environment")return t.push("Unsupported hosted environment manifest"),{valid:!1,errors:t};let r;try{let{checksum:n,schemaVersion:o,kind:s,...i}=e;r={...J(i),schemaVersion:1,kind:"xeno-hosted-environment"}}catch(n){return t.push(n instanceof Error?n.message:String(n)),{valid:!1,errors:t}}return u(r)!==u(ke(e))&&t.push("Hosted environment manifest is not normalized"),(e.checksum?.algorithm!=="sha256"||e.checksum.value!==S(r))&&t.push("Hosted environment checksum mismatch"),{valid:t.length===0,errors:t}}function xe(e){let t=p(e.streamId,"streamId"),r=K(e.sequence,"sequence");if(e.previous){if(e.previous.streamId!==t)throw new Error("Previous event belongs to another stream");if(e.previous.sequence+1!==r)throw new Error("Hosted event sequence must be contiguous")}else if(r!==1)throw new Error("The first hosted event sequence must be 1");let n={schemaVersion:1,kind:"xeno-hosted-event",eventId:p(e.eventId??`hevt_${(0,x.randomUUID)()}`,"eventId"),streamId:t,sequence:r,timestamp:W(e.timestamp??new Date().toISOString(),"timestamp"),type:F(e.type,"type"),actorId:p(e.actorId,"actorId"),...e.idempotencyKey?{idempotencyKey:c(e.idempotencyKey,"idempotencyKey",512)}:{},payload:ve(e.payload??{},"payload"),previousHash:e.previous?.hash??null};return{...n,hash:S(n)}}function we(e,t){let r=[],n,o=t?t.afterSequence+1:1,s=t?.lastHash??null;for(let a of e){if(a.schemaVersion!==1||a.kind!=="xeno-hosted-event"){r.push(`Unsupported hosted event at sequence ${String(a.sequence)}`);continue}a.sequence!==o&&r.push(`Hosted event sequence gap at ${a.sequence}; expected ${o}`),a.previousHash!==s&&r.push(`Hosted event previous hash mismatch at ${a.sequence}`);let{hash:m,...h}=a;m!==S(h)&&r.push(`Hosted event hash mismatch at ${a.sequence}`),n&&n.streamId!==a.streamId&&r.push(`Hosted event stream changed at ${a.sequence}`),n=a,o=a.sequence+1,s=a.hash}let i=e.at(-1);return{valid:r.length===0,errors:r,cursor:i?{streamId:i.streamId,afterSequence:i.sequence,lastHash:i.hash}:t??null}}function be(e){let t=I(e);if(!t.valid)throw new Error(t.errors.join("; "));return`${e.environmentId}@${e.revision}:${e.checksum.value}`}function Ee(...e){if(e.length===0)throw new Error("At least one idempotency-key part is required");let t=e.map((r,n)=>Te(r,`parts[${n}]`));return`xeno:${(0,x.createHash)("sha256").update(t.join("\0")).digest("hex")}`}function J(e){let t=e.secrets.map((o,s)=>({ref:p(o.ref,`secrets[${s}].ref`),target:o.target.kind==="environment"?{kind:"environment",name:Se(o.target.name)}:{kind:"file",path:T(o.target.path,`secrets[${s}].target.path`)},required:!!o.required,exposeToChildProcesses:!!o.exposeToChildProcesses})),r=new Set,n=new Set;for(let o of t){if(r.has(o.ref))throw new Error(`Duplicate secret ref: ${o.ref}`);r.add(o.ref);let s=`${o.target.kind}:${o.target.kind==="environment"?o.target.name:o.target.path}`;if(n.has(s))throw new Error(`Duplicate secret target: ${s}`);n.add(s)}if(e.network.default!=="deny")throw new Error("Hosted network policy must be default-deny");return{environmentId:p(e.environmentId,"environmentId"),revision:K(e.revision,"revision"),createdAt:W(e.createdAt,"createdAt"),createdBy:p(e.createdBy,"createdBy"),workspaceId:p(e.workspaceId,"workspaceId"),name:c(e.name,"name",160),repository:{provider:e.repository.provider,repository:c(e.repository.repository,"repository.repository",2048),ref:c(e.repository.ref,"repository.ref",512),...e.repository.commit?{commit:He(e.repository.commit,"repository.commit")}:{},...e.repository.subdirectory?{subdirectory:T(e.repository.subdirectory,"repository.subdirectory")}:{},...e.repository.shallow!==void 0?{shallow:!!e.repository.shallow}:{}},image:{reference:c(e.image.reference,"image.reference",2048),digest:_e(e.image.digest),os:e.image.os,architecture:e.image.architecture},setup:e.setup.map((o,s)=>({id:p(o.id,`setup[${s}].id`),command:c(o.command,`setup[${s}].command`,32768),...o.workingDirectory?{workingDirectory:T(o.workingDirectory,`setup[${s}].workingDirectory`)}:{},timeoutMs:d(o.timeoutMs,`setup[${s}].timeoutMs`,1e3,36e5),network:o.network})),caches:e.caches.map((o,s)=>({key:c(o.key,`caches[${s}].key`,512),path:T(o.path,`caches[${s}].path`),...o.restoreKeys?.length?{restoreKeys:Re(o.restoreKeys,`caches[${s}].restoreKeys`,512)}:{},...o.readOnly!==void 0?{readOnly:!!o.readOnly}:{},...o.maxBytes!==void 0?{maxBytes:d(o.maxBytes,`caches[${s}].maxBytes`,1,Number.MAX_SAFE_INTEGER)}:{}})),network:{default:"deny",dns:e.network.dns,destinations:e.network.destinations.map((o,s)=>({host:Ie(o.host,`network.destinations[${s}].host`),...o.ports?.length?{ports:[...new Set(o.ports.map(i=>d(i,"port",1,65535)))].sort((i,a)=>i-a)}:{},...o.protocols?.length?{protocols:[...new Set(o.protocols)].sort()}:{},reason:c(o.reason,`network.destinations[${s}].reason`,500)})).sort((o,s)=>o.host.localeCompare(s.host)),...e.network.maxResponseBytes!==void 0?{maxResponseBytes:d(e.network.maxResponseBytes,"network.maxResponseBytes",1,Number.MAX_SAFE_INTEGER)}:{}},secrets:t,resources:{cpuMillis:d(e.resources.cpuMillis,"resources.cpuMillis",10,1e6),memoryBytes:d(e.resources.memoryBytes,"resources.memoryBytes",16*1024*1024,Number.MAX_SAFE_INTEGER),diskBytes:d(e.resources.diskBytes,"resources.diskBytes",16*1024*1024,Number.MAX_SAFE_INTEGER),processLimit:d(e.resources.processLimit,"resources.processLimit",1,65535),wallTimeMs:d(e.resources.wallTimeMs,"resources.wallTimeMs",1e3,10080*60*1e3)},retention:{workspaceTtlMs:d(e.retention.workspaceTtlMs,"retention.workspaceTtlMs",0,365*24*60*60*1e3),eventTtlMs:d(e.retention.eventTtlMs,"retention.eventTtlMs",6e4,365*24*60*60*1e3),artifactTtlMs:d(e.retention.artifactTtlMs,"retention.artifactTtlMs",6e4,365*24*60*60*1e3),wipeWorkspace:!!e.retention.wipeWorkspace},labels:Object.fromEntries(Object.entries(e.labels).map(([o,s])=>[F(o,"label key"),c(s,`labels.${o}`,500)]).sort(([o],[s])=>o.localeCompare(s)))}}function ke(e){let{checksum:t,...r}=e;return r}function S(e){return(0,x.createHash)("sha256").update(u(e)).digest("hex")}function ve(e,t){let r=u(e);if(Buffer.byteLength(r,"utf8")>256*1024)throw new Error(`${t} exceeds 262144 bytes`);return JSON.parse(r)}function p(e,t){let r=c(e,t,512);if(!/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(r))throw new Error(`${t} is invalid`);return r}function F(e,t){let r=c(e,t,160);if(!/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(r))throw new Error(`${t} is invalid`);return r}function c(e,t,r){let n=e.trim();if(!n||n.length>r||y(n,{allowTab:!0,allowLineBreaks:!0}))throw new Error(`${t} is invalid`);return n}function Te(e,t){let r=e.trim();if(r.length>4096||y(r,{allowTab:!0,allowLineBreaks:!0}))throw new Error(`${t} is invalid`);return r}function K(e,t){return d(e,t,1,Number.MAX_SAFE_INTEGER)}function d(e,t,r,n){if(!Number.isSafeInteger(e)||e<r||e>n)throw new Error(`${t} must be an integer between ${r} and ${n}`);return e}function W(e,t){let r=Date.parse(e);if(!Number.isFinite(r)||new Date(r).toISOString()!==e)throw new Error(`${t} must be an ISO-8601 UTC timestamp`);return e}function Ie(e,t){let r=c(e.toLowerCase(),t,253);if(r==="localhost"||/^(?:\d{1,3}\.){3}\d{1,3}$/.test(r)||r.includes(":")||!/^(?:\*\.)?(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(r))throw new Error(`${t} must be a public DNS hostname or wildcard hostname`);return r}function T(e,t){let r=c(e.replaceAll("\\","/"),t,4096);if(r.startsWith("/")||/^[A-Za-z]:\//.test(r)||r.split("/").includes(".."))throw new Error(`${t} must be workspace-relative`);return r.replace(/^\.\//,"")}function Se(e){let t=c(e,"secret environment name",256);if(!/^[A-Z_][A-Z0-9_]*$/.test(t))throw new Error("Secret environment target must be an uppercase environment variable name");return t}function _e(e){let t=e.trim().toLowerCase();if(!/^sha256:[a-f0-9]{64}$/.test(t))throw new Error("image.digest must be a sha256 OCI digest");return t}function He(e,t){return c(e,t,512)}function Re(e,t,r){return[...new Set(e.map((n,o)=>c(n,`${t}[${o}]`,r)))]}var g=require("node:crypto");function Ae(e){let t=typeof e.body=="string"?Buffer.from(e.body,"utf8"):Buffer.from(e.body),r=(0,g.createHash)("sha256").update(t).digest("hex"),n=e.signature?.trim();if(!n)return{valid:!1,source:e.source,bodySha256:r,error:"missing-signature"};if(!e.secret||e.secret.length<16)throw new Error("Webhook secret must contain at least 16 characters");let o,s=n;if(e.source==="slack"){if(!e.timestamp||!/^\d+$/.test(e.timestamp))return{valid:!1,source:e.source,bodySha256:r,error:"invalid-timestamp"};let a=Number(e.timestamp)*1e3,m=Math.abs((e.now??new Date).getTime()-a);if(!Number.isFinite(a)||m>(e.maxClockSkewMs??5*6e4))return{valid:!1,source:e.source,bodySha256:r,timestamp:e.timestamp,error:"stale-timestamp"};o=`v0=${(0,g.createHmac)("sha256",e.secret).update(`v0:${e.timestamp}:`).update(t).digest("hex")}`}else e.source==="gitlab"?o=e.secret:e.source==="teams"?o=`HMAC ${(0,g.createHmac)("sha256",Buffer.from(e.secret,"base64")).update(t).digest("base64")}`:(o=`${e.source==="github"||e.source==="jira"?"sha256=":e.source==="xeno"?"v1=":""}${(0,g.createHmac)("sha256",e.secret).update(t).digest("hex")}`,e.source==="linear"&&s.startsWith("sha256=")&&(s=s.slice(7)));let i=Ce(o,s);return{valid:i,source:e.source,bodySha256:r,...e.timestamp?{timestamp:e.timestamp}:{},...i?{}:{error:"invalid-signature"}}}function Ce(e,t){let r=Buffer.from(e,"utf8"),n=Buffer.from(t,"utf8");return r.length===n.length&&(0,g.timingSafeEqual)(r,n)}var A=require("node:crypto");var w="xeno.hosted-execution-adapter-certification.v2",M=2,G=744*60*60*1e3;function Xe(e){return Z(e),Buffer.from(D(e),"utf8")}function Oe(e,t){if(e?.schemaVersion!==w)throw new Error(`Hosted execution adapter certificate must use ${w}`);let{signature:r,...n}=e;if(Z(n),r?.algorithm!=="ed25519")throw new Error("Hosted execution adapter signature must use ed25519");let o=H(t.executableSha256,"executableSha256"),s=H(t.controlPlaneCandidateSha256,"controlPlaneCandidateSha256");if(n.adapter.executableSha256!==o)throw new Error("Hosted execution adapter executable does not match its signed certificate");if(n.controlPlaneCandidateSha256!==s)throw new Error("Hosted execution adapter certificate is bound to another control-plane candidate");let i=t.platform??process.platform,a=t.architecture??process.arch;if(n.platform.os!==i||n.platform.architecture!==a)throw new Error(`Hosted execution adapter certificate targets ${n.platform.os}-${n.platform.architecture}, not ${i}-${a}`);let m=R(n.issuedAt,"issuedAt"),h=R(n.expiresAt,"expiresAt"),z=(t.now??new Date).getTime();if(m>z+5*6e4)throw new Error("Hosted execution adapter certificate is not yet valid");if(h<=z)throw new Error("Hosted execution adapter certificate has expired");if(h<=m||h-m>G)throw new Error("Hosted execution adapter certificate lifetime must be positive and at most 31 days");let U=t.trustedKeys[n.reviewer.keyId];if(!U)throw new Error(`Hosted execution adapter reviewer key is not trusted: ${n.reviewer.keyId}`);if(!(0,A.verify)(null,Buffer.from(D(n),"utf8"),U,Pe(r.value,"signature.value")))throw new Error("Hosted execution adapter certificate signature is invalid");return{certificationId:n.certificationId,adapterName:n.adapter.name,adapterVersion:n.adapter.version,protocolVersion:n.adapter.protocolVersion,executableSha256:o,controlPlaneCandidateSha256:s,certificateSha256:(0,A.createHash)("sha256").update(D(e)).digest("hex"),expiresAt:n.expiresAt,reviewerKeyId:n.reviewer.keyId}}function Z(e){if(e.schemaVersion!==w)throw new Error(`Hosted execution adapter certificate must use ${w}`);if(_(e.certificationId,"certificationId"),_(e.adapter?.name,"adapter.name"),_(e.adapter?.version,"adapter.version"),e.adapter?.protocolVersion!==M)throw new Error(`Hosted execution adapter protocol must be ${M}`);H(e.adapter.executableSha256,"adapter.executableSha256"),H(e.controlPlaneCandidateSha256,"controlPlaneCandidateSha256"),_(e.reviewer?.keyId,"reviewer.keyId");let t=["immutableImages","filesystemIsolation","networkDefaultDeny","destinationAllowlist","secretProjection","nonRootExecution","readOnlyRoot","processTreeCleanup","resourceLimits","interactiveControl","artifactProtocol","gitResultReporting"];if(!e.capabilities||t.some(r=>e.capabilities[r]!==!0))throw new Error("Hosted execution adapter certificate does not attest every required containment capability");R(e.issuedAt,"issuedAt"),R(e.expiresAt,"expiresAt")}function D(e){return u(e)}function H(e,t){let r=e?.trim().toLowerCase();if(!/^[a-f0-9]{64}$/.test(r))throw new Error(`${t} must be a lowercase SHA-256 digest`);return r}function _(e,t){let r=e?.trim();if(!r||r.length>256||!/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(r))throw new Error(`${t} is invalid`);return r}function R(e,t){let r=Date.parse(e);if(!Number.isFinite(r)||new Date(r).toISOString()!==e)throw new Error(`${t} must be an ISO-8601 UTC timestamp`);return r}function Pe(e,t){if(typeof e!="string"||e.length===0||e.length>4096||!/^[A-Za-z0-9+/]+={0,2}$/.test(e))throw new Error(`${t} must be bounded base64`);let r=Buffer.from(e,"base64");if(r.toString("base64")!==e)throw new Error(`${t} is not canonical base64`);return r}var te=require("node:crypto");var Q=["low","medium","high","xhigh","max"],Y=["default","plan","acceptEdits","auto","dontAsk","bypassPermissions"];var re=2,ne=["Read","Write","Edit","Glob","Grep","WebFetch"],Ne=new Set(ne);function oe(e){if(!ie(e.certificationId))throw new Error("certificationId is invalid");let t=new Set(e.authority.secretRefs);return{certificationId:e.certificationId,environmentChecksum:e.environment.checksum.value,imageDigest:e.environment.image.digest,networkPolicySha256:ee({authority:e.authority.network,policy:e.environment.network}),secretProjectionSha256:ee(e.environment.secrets.filter(r=>t.has(r.ref))),filesystem:e.authority.filesystem,network:e.authority.network==="deny"?"deny":"allowlist",immutableImage:!0,readOnlyRoot:!0,nonRoot:!0,processTreeCleanup:!0,resourceLimits:!0,inferenceGateway:"brokered"}}function se(e){let t=[];if(!Le(e))return{valid:!1,errors:["Hosted execution job must be an object"]};let r=e;if(r.protocolVersion!==re||r.kind!=="xeno-hosted-execution-job")return t.push("Unsupported hosted execution protocol"),{valid:!1,errors:t};b(r.runId,"runId",t),b(r.userId,"userId",t),b(r.workspaceId,"workspaceId",t),V(r.workspaceHostPath,"workspaceHostPath",4096,t),V(r.prompt,"prompt",512*1024,t),V(r.model,"model",512,t),r.effort!==void 0&&!Q.includes(r.effort)&&t.push("effort is invalid"),Y.includes(r.permissionMode)||t.push("permissionMode is invalid"),(typeof r.runScopedToken!="string"||!r.runScopedToken.startsWith("xrun_")||r.runScopedToken.length>16*1024)&&t.push("runScopedToken is not a bounded run-scoped token");let n;try{n=new URL(r.inferenceBaseUrl),(n.protocol!=="https:"||n.username||n.password||n.hash)&&t.push("inferenceBaseUrl must be credential-free HTTPS")}catch{t.push("inferenceBaseUrl is invalid")}let o=I(r.environment);t.push(...o.errors.map(i=>`environment: ${i}`)),r.environment?.workspaceId!==r.workspaceId&&t.push("environment workspace does not match the job"),r.environment?.image?.os!=="linux"&&t.push("hosted execution image must target Linux");let s=r.environment?.repository?.commit;(typeof s!="string"||!/^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(s))&&t.push("environment repository requires a full 40- or 64-character commit object id"),De(r.authority,t),Ve(r.budget,r.environment,t),Be(r.allowedTools,t),$e(r,t),qe(r,t),n&&!r.environment?.network?.destinations?.some(i=>{let a=i.ports?.length?i.ports:[443];return i.host.toLowerCase()===n.hostname.toLowerCase()&&a.includes(Number(n.port||443))})&&t.push("inference origin is absent from the environment network allowlist");try{let i=je(r.environment?.repository);r.environment?.network?.destinations?.some(a=>{let m=a.ports?.length?a.ports:[443];return a.host.toLowerCase()===i.hostname&&m.includes(i.port)})||t.push("repository origin is absent from the environment network allowlist")}catch{t.push("environment repository must resolve to a credential-free HTTPS origin")}return{valid:t.length===0,errors:t}}function Me(e){let t=se(e);if(!t.valid)throw new Error(`Invalid hosted execution job: ${t.errors.join("; ")}`)}function De(e,t){(!e||!["read","workspace-write"].includes(e.filesystem))&&t.push("authority.filesystem is invalid"),(!e||!["deny","environment-policy"].includes(e.network))&&t.push("authority.network is invalid"),(!e||!["deny","approval-required"].includes(e.externalActions))&&t.push("authority.externalActions is invalid"),!Array.isArray(e?.secretRefs)||new Set(e.secretRefs).size!==e.secretRefs.length?t.push("authority.secretRefs must be a unique array"):e.secretRefs.forEach((r,n)=>b(r,`authority.secretRefs[${n}]`,t))}function Ve(e,t,r){(!e||!Number.isFinite(e.maxCredits)||e.maxCredits<=0)&&r.push("budget.maxCredits is invalid"),(!e||!B(e.maxDurationMs)||e.maxDurationMs>(t?.resources?.wallTimeMs??0))&&r.push("budget.maxDurationMs is invalid or exceeds the environment limit"),e?.maxTokens!==void 0&&!B(e.maxTokens)&&r.push("budget.maxTokens is invalid"),e?.maxToolCalls!==void 0&&!B(e.maxToolCalls)&&r.push("budget.maxToolCalls is invalid")}function Be(e,t){if(!Array.isArray(e)||e.length<1||e.length>512||new Set(e).size!==e.length){t.push("allowedTools must contain 1..512 unique tool names");return}e.forEach((r,n)=>{b(r,`allowedTools[${n}]`,t),Ne.has(r)||t.push(`allowedTools[${n}] is not in the hosted v0.1 registry`)})}function $e(e,t){if(!Array.isArray(e.secrets)||e.secrets.length>128){t.push("secrets must be a bounded array");return}let r=new Set(e.authority?.secretRefs??[]),n=new Map((e.environment?.secrets??[]).map(s=>[s.ref,s])),o=new Set;for(let[s,i]of e.secrets.entries()){let a=n.get(i.ref);if(!a||!r.has(i.ref)||o.has(i.ref)){t.push(`secrets[${s}] is undeclared, unauthorized, or duplicated`);continue}o.add(i.ref),(E(a.target)!==E(i.target)||a.exposeToChildProcesses!==i.exposeToChildProcesses)&&t.push(`secrets[${s}] does not match its declared projection`),(typeof i.value!="string"||i.value.length<1||Buffer.byteLength(i.value,"utf8")>1024*1024)&&t.push(`secrets[${s}] value is empty or too large`)}for(let s of e.environment?.secrets??[])s.required&&(!r.has(s.ref)||!o.has(s.ref))&&t.push(`required secret ${s.ref} is absent or unauthorized`);[...r].some(s=>!n.has(s))&&t.push("authority references an undeclared secret")}function qe(e,t){let r=e.expectedBoundary;if(!r){t.push("expectedBoundary is missing");return}let n;try{n=oe({certificationId:r.certificationId,environment:e.environment,authority:e.authority})}catch{t.push("expectedBoundary does not match the hosted execution contract");return}(!ie(r.certificationId)||E(r)!==E(n))&&t.push("expectedBoundary does not match the hosted execution contract")}function b(e,t,r){(typeof e!="string"||!/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,511}$/.test(e))&&r.push(`${t} is invalid`)}function V(e,t,r,n){(typeof e!="string"||e.length<1||e.length>r||e.includes("\0"))&&n.push(`${t} is invalid`)}function B(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>0}function ie(e){return typeof e=="string"&&/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,511}$/.test(e)}function Le(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function E(e){return u(e)}function ee(e){return(0,te.createHash)("sha256").update(E(e)).digest("hex")}function je(e){if(!e)throw new Error("repository source is missing");let t=e.repository.replace(/^\/+|\/+$/g,""),r=e.provider==="github"&&!t.includes("://")?`https://github.com/${t}.git`:e.provider==="gitlab"&&!t.includes("://")?`https://gitlab.com/${t}.git`:e.provider==="bitbucket"&&!t.includes("://")?`https://bitbucket.org/${t}.git`:e.repository,n=new URL(r);if(n.protocol!=="https:"||n.username||n.password||n.hash)throw new Error("repository origin is not credential-free HTTPS");return{hostname:n.hostname.toLowerCase(),port:Number(n.port||443)}}var X=require("node:crypto");var q=1,L=1;function ce(e){let t={schemaVersion:q,kind:"xeno-hosted-control",controlId:l(e.controlId??`hctl_${(0,X.randomUUID)()}`,"controlId"),runId:l(e.runId,"runId"),workspaceId:l(e.workspaceId,"workspaceId"),actorId:l(e.actorId,"actorId"),idempotencyKey:f(e.idempotencyKey,"idempotencyKey",512),createdAt:j(e.createdAt,"createdAt"),action:Fe(e.action)};return{...t,hash:{algorithm:"sha256",value:ue(t)}}}function ze(e){let t=[];try{let{hash:r,schemaVersion:n,kind:o,...s}=e,i=ce(s);(e.schemaVersion!==q||e.kind!=="xeno-hosted-control")&&t.push("Unsupported hosted control command"),k(C(e))!==k(C(i))&&t.push("Hosted control command is not normalized"),(r?.algorithm!=="sha256"||r.value!==i.hash.value)&&t.push("Hosted control command hash mismatch")}catch(r){t.push(r instanceof Error?r.message:String(r))}return{valid:t.length===0,errors:t}}function Ue(e){if(!["accepted","applied","rejected","unsupported"].includes(e.status))throw new Error("Hosted control acknowledgement status is invalid");return{controlId:l(e.controlId,"controlId"),status:e.status,acknowledgedAt:j(e.acknowledgedAt,"acknowledgedAt"),...e.reason?{reason:f(e.reason,"reason",2048)}:{}}}function de(e){let t=e.git?{...e.git.branch?{branch:$(e.git.branch,"git.branch")}:{},...e.git.baseRef?{baseRef:$(e.git.baseRef,"git.baseRef")}:{},...e.git.commit?{commit:$(e.git.commit,"git.commit")}:{}}:void 0,r={schemaVersion:L,kind:"xeno-hosted-run-result",runId:l(e.runId,"runId"),workspaceId:l(e.workspaceId,"workspaceId"),completedAt:j(e.completedAt,"completedAt"),...t&&Object.keys(t).length>0?{git:t}:{},...e.pullRequest?{pullRequest:Ke(e.pullRequest)}:{},artifactIds:ae(e.artifactIds,"artifactIds"),evidenceArtifactIds:ae(e.evidenceArtifactIds,"evidenceArtifactIds")};return{...r,hash:{algorithm:"sha256",value:ue(r)}}}function Je(e){let t=[];try{let{hash:r,schemaVersion:n,kind:o,...s}=e,i=de(s);(e.schemaVersion!==L||e.kind!=="xeno-hosted-run-result")&&t.push("Unsupported hosted run result"),k(C(e))!==k(C(i))&&t.push("Hosted run result is not normalized"),(r?.algorithm!=="sha256"||r.value!==i.hash.value)&&t.push("Hosted run result hash mismatch")}catch(r){t.push(r instanceof Error?r.message:String(r))}return{valid:t.length===0,errors:t}}function Fe(e){if(e?.type==="message")return{type:"message",message:f(e.message,"action.message",32768)};if(e?.type==="approval"){if(e.decision!=="approved"&&e.decision!=="rejected")throw new Error("Hosted approval decision is invalid");return{type:"approval",requestId:l(e.requestId,"action.requestId"),decision:e.decision,scopeHash:We(e.scopeHash,"action.scopeHash"),...e.rationale?{rationale:f(e.rationale,"action.rationale",4096)}:{}}}throw new Error("Hosted control action is invalid")}function Ke(e){let t;try{t=new URL(e.url)}catch{throw new Error("pullRequest.url is invalid")}if(t.protocol!=="https:"||t.username||t.password)throw new Error("pullRequest.url must be credential-free HTTPS");if(!Number.isSafeInteger(e.number)||e.number<1)throw new Error("pullRequest.number must be a positive integer");return{provider:l(e.provider,"pullRequest.provider"),repository:f(e.repository,"pullRequest.repository",2048),number:e.number,url:t.toString()}}function ae(e,t){if(!Array.isArray(e)||e.length>1e4)throw new Error(`${t} is invalid`);return[...new Set(e.map((r,n)=>l(r,`${t}[${n}]`)))].sort()}function $(e,t){return f(e,t,512)}function l(e,t){let r=f(e,t,512);if(!/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(r))throw new Error(`${t} is invalid`);return r}function f(e,t,r){let n=e?.trim();if(!n||n.length>r||y(n,{allowTab:!0,allowLineBreaks:!0}))throw new Error(`${t} is invalid`);return n}function j(e,t){let r=Date.parse(e);if(!Number.isFinite(r)||new Date(r).toISOString()!==e)throw new Error(`${t} must be ISO-8601 UTC`);return e}function We(e,t){let r=e?.trim().toLowerCase();if(!/^[a-f0-9]{64}$/.test(r))throw new Error(`${t} must be a lowercase SHA-256 digest`);return r}function ue(e){return(0,X.createHash)("sha256").update(k(e)).digest("hex")}function k(e){return u(e)}function C(e){let{hash:t,...r}=e;return r}0&&(module.exports={XENO_HOSTED_CONTROL_SCHEMA_VERSION,XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION,XENO_HOSTED_EVENT_SCHEMA_VERSION,XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA,XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS,XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION,XENO_HOSTED_EXECUTION_PROTOCOL_VERSION,XENO_HOSTED_EXECUTION_TOOL_NAMES,XENO_HOSTED_RESULT_SCHEMA_VERSION,XENO_HOSTED_RUN_SCHEMA_VERSION,XENO_HOSTED_TRIGGER_SCHEMA_VERSION,assertValidXenoHostedExecutionJob,createXenoHostedControlCommand,createXenoHostedEnvironmentManifest,createXenoHostedEvent,createXenoHostedExecutionBoundaryReceipt,createXenoHostedRunResult,deriveHostedIdempotencyKey,hostedEnvironmentIdentity,normalizeXenoHostedControlAcknowledgement,verifyXenoHostedControlCommand,verifyXenoHostedEnvironmentManifest,verifyXenoHostedEventChain,verifyXenoHostedExecutionAdapterCertification,verifyXenoHostedExecutionJob,verifyXenoHostedRunResult,verifyXenoHostedWebhook,xenoHostedExecutionAdapterSigningPayload});
|
|
1
|
+
"use strict";var P=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var xe=Object.prototype.hasOwnProperty;var we=(e,t)=>{for(var n in t)P(e,n,{get:t[n],enumerable:!0})},be=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ye(t))!xe.call(e,o)&&o!==n&&P(e,o,{get:()=>t[o],enumerable:!(r=he(t,o))||r.enumerable});return e};var Ee=e=>be(P({},"__esModule",{value:!0}),e);var nt={};we(nt,{XENO_HOSTED_CONTROL_SCHEMA_VERSION:()=>j,XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION:()=>S,XENO_HOSTED_EVENT_SCHEMA_VERSION:()=>N,XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA:()=>w,XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS:()=>Q,XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION:()=>D,XENO_HOSTED_EXECUTION_PROTOCOL_VERSION:()=>ie,XENO_HOSTED_EXECUTION_TOOL_NAMES:()=>ae,XENO_HOSTED_RESULT_SCHEMA_VERSION:()=>U,XENO_HOSTED_RUN_SCHEMA_VERSION:()=>ot,XENO_HOSTED_TRIGGER_SCHEMA_VERSION:()=>st,XenoHostedExecutionJobError:()=>C,assertValidXenoHostedExecutionJob:()=>Le,createXenoHostedControlCommand:()=>pe,createXenoHostedEnvironmentManifest:()=>ke,createXenoHostedEvent:()=>Se,createXenoHostedExecutionBoundaryReceipt:()=>ce,createXenoHostedRunResult:()=>ge,deriveHostedIdempotencyKey:()=>Te,hostedEnvironmentIdentity:()=>_e,hostedSlashCommandRefusal:()=>de,normalizeXenoHostedControlAcknowledgement:()=>Ze,verifyXenoHostedControlCommand:()=>We,verifyXenoHostedEnvironmentManifest:()=>_,verifyXenoHostedEventChain:()=>ve,verifyXenoHostedExecutionAdapterCertification:()=>Ve,verifyXenoHostedExecutionJob:()=>ue,verifyXenoHostedRunResult:()=>Qe,verifyXenoHostedWebhook:()=>Ne,xenoHostedExecutionAdapterSigningPayload:()=>De});module.exports=Ee(nt);var S=1,ot=1,N=1,st=1;var x=require("node:crypto");function l(e){return JSON.stringify(M(e,new Set))}function M(e,t){if(e===null||typeof e!="object"){if(typeof e=="number"&&!Number.isFinite(e))throw new TypeError("Artifact JSON cannot contain non-finite numbers");return e}if(t.has(e))throw new TypeError("Artifact JSON cannot contain cycles");if(t.add(e),Array.isArray(e)){let r=e.map(o=>M(o,t));return t.delete(e),r}let n={};for(let r of Object.keys(e).sort((o,s)=>o.localeCompare(s))){let o=e[r];if(o===void 0)throw new TypeError(`Artifact JSON property ${r} is undefined`);n[r]=M(o,t)}return t.delete(e),n}function y(e,t={}){for(let n of e){let r=n.codePointAt(0);if(r===127)return!0;if(!(r>31)&&!(r===9&&t.allowTab===!0)&&!((r===10||r===13)&&t.allowLineBreaks===!0))return!0}return!1}function ke(e){let t={...K(e),schemaVersion:1,kind:"xeno-hosted-environment"};return{...t,checksum:{algorithm:"sha256",value:T(t)}}}function _(e){let t=[];if(e?.schemaVersion!==1||e.kind!=="xeno-hosted-environment")return t.push("Unsupported hosted environment manifest"),{valid:!1,errors:t};let n;try{let{checksum:r,schemaVersion:o,kind:s,...i}=e;n={...K(i),schemaVersion:1,kind:"xeno-hosted-environment"}}catch(r){return t.push(r instanceof Error?r.message:String(r)),{valid:!1,errors:t}}return l(n)!==l(Re(e))&&t.push("Hosted environment manifest is not normalized"),(e.checksum?.algorithm!=="sha256"||e.checksum.value!==T(n))&&t.push("Hosted environment checksum mismatch"),{valid:t.length===0,errors:t}}function Se(e){let t=p(e.streamId,"streamId"),n=W(e.sequence,"sequence");if(e.previous){if(e.previous.streamId!==t)throw new Error("Previous event belongs to another stream");if(e.previous.sequence+1!==n)throw new Error("Hosted event sequence must be contiguous")}else if(n!==1)throw new Error("The first hosted event sequence must be 1");let r={schemaVersion:1,kind:"xeno-hosted-event",eventId:p(e.eventId??`hevt_${(0,x.randomUUID)()}`,"eventId"),streamId:t,sequence:n,timestamp:Z(e.timestamp??new Date().toISOString(),"timestamp"),type:G(e.type,"type"),actorId:p(e.actorId,"actorId"),...e.idempotencyKey?{idempotencyKey:c(e.idempotencyKey,"idempotencyKey",512)}:{},payload:Ie(e.payload??{},"payload"),previousHash:e.previous?.hash??null};return{...r,hash:T(r)}}function ve(e,t){let n=[],r,o=t?t.afterSequence+1:1,s=t?.lastHash??null;for(let a of e){if(a.schemaVersion!==1||a.kind!=="xeno-hosted-event"){n.push(`Unsupported hosted event at sequence ${String(a.sequence)}`);continue}a.sequence!==o&&n.push(`Hosted event sequence gap at ${a.sequence}; expected ${o}`),a.previousHash!==s&&n.push(`Hosted event previous hash mismatch at ${a.sequence}`);let{hash:d,...f}=a;d!==T(f)&&n.push(`Hosted event hash mismatch at ${a.sequence}`),r&&r.streamId!==a.streamId&&n.push(`Hosted event stream changed at ${a.sequence}`),r=a,o=a.sequence+1,s=a.hash}let i=e.at(-1);return{valid:n.length===0,errors:n,cursor:i?{streamId:i.streamId,afterSequence:i.sequence,lastHash:i.hash}:t??null}}function _e(e){let t=_(e);if(!t.valid)throw new Error(t.errors.join("; "));return`${e.environmentId}@${e.revision}:${e.checksum.value}`}function Te(...e){if(e.length===0)throw new Error("At least one idempotency-key part is required");let t=e.map((n,r)=>He(n,`parts[${r}]`));return`xeno:${(0,x.createHash)("sha256").update(t.join("\0")).digest("hex")}`}function K(e){let t=e.secrets.map((o,s)=>({ref:p(o.ref,`secrets[${s}].ref`),target:o.target.kind==="environment"?{kind:"environment",name:Ce(o.target.name)}:{kind:"file",path:v(o.target.path,`secrets[${s}].target.path`)},required:!!o.required,exposeToChildProcesses:!!o.exposeToChildProcesses})),n=new Set,r=new Set;for(let o of t){if(n.has(o.ref))throw new Error(`Duplicate secret ref: ${o.ref}`);n.add(o.ref);let s=`${o.target.kind}:${o.target.kind==="environment"?o.target.name:o.target.path}`;if(r.has(s))throw new Error(`Duplicate secret target: ${s}`);r.add(s)}if(e.network.default!=="deny")throw new Error("Hosted network policy must be default-deny");return{environmentId:p(e.environmentId,"environmentId"),revision:W(e.revision,"revision"),createdAt:Z(e.createdAt,"createdAt"),createdBy:p(e.createdBy,"createdBy"),workspaceId:p(e.workspaceId,"workspaceId"),name:c(e.name,"name",160),repository:{provider:e.repository.provider,repository:c(e.repository.repository,"repository.repository",2048),ref:c(e.repository.ref,"repository.ref",512),...e.repository.commit?{commit:Oe(e.repository.commit,"repository.commit")}:{},...e.repository.subdirectory?{subdirectory:v(e.repository.subdirectory,"repository.subdirectory")}:{},...e.repository.shallow!==void 0?{shallow:!!e.repository.shallow}:{}},image:{reference:c(e.image.reference,"image.reference",2048),digest:Xe(e.image.digest),os:e.image.os,architecture:e.image.architecture},setup:e.setup.map((o,s)=>({id:p(o.id,`setup[${s}].id`),command:c(o.command,`setup[${s}].command`,32768),...o.workingDirectory?{workingDirectory:v(o.workingDirectory,`setup[${s}].workingDirectory`)}:{},timeoutMs:u(o.timeoutMs,`setup[${s}].timeoutMs`,1e3,36e5),network:o.network})),caches:e.caches.map((o,s)=>({key:c(o.key,`caches[${s}].key`,512),path:v(o.path,`caches[${s}].path`),...o.restoreKeys?.length?{restoreKeys:Pe(o.restoreKeys,`caches[${s}].restoreKeys`,512)}:{},...o.readOnly!==void 0?{readOnly:!!o.readOnly}:{},...o.maxBytes!==void 0?{maxBytes:u(o.maxBytes,`caches[${s}].maxBytes`,1,Number.MAX_SAFE_INTEGER)}:{}})),network:{default:"deny",dns:e.network.dns,destinations:e.network.destinations.map((o,s)=>({host:Ae(o.host,`network.destinations[${s}].host`),...o.ports?.length?{ports:[...new Set(o.ports.map(i=>u(i,"port",1,65535)))].sort((i,a)=>i-a)}:{},...o.protocols?.length?{protocols:[...new Set(o.protocols)].sort()}:{},reason:c(o.reason,`network.destinations[${s}].reason`,500)})).sort((o,s)=>o.host.localeCompare(s.host)),...e.network.maxResponseBytes!==void 0?{maxResponseBytes:u(e.network.maxResponseBytes,"network.maxResponseBytes",1,Number.MAX_SAFE_INTEGER)}:{}},secrets:t,resources:{cpuMillis:u(e.resources.cpuMillis,"resources.cpuMillis",10,1e6),memoryBytes:u(e.resources.memoryBytes,"resources.memoryBytes",16*1024*1024,Number.MAX_SAFE_INTEGER),diskBytes:u(e.resources.diskBytes,"resources.diskBytes",16*1024*1024,Number.MAX_SAFE_INTEGER),processLimit:u(e.resources.processLimit,"resources.processLimit",1,65535),wallTimeMs:u(e.resources.wallTimeMs,"resources.wallTimeMs",1e3,10080*60*1e3)},retention:{workspaceTtlMs:u(e.retention.workspaceTtlMs,"retention.workspaceTtlMs",0,365*24*60*60*1e3),eventTtlMs:u(e.retention.eventTtlMs,"retention.eventTtlMs",6e4,365*24*60*60*1e3),artifactTtlMs:u(e.retention.artifactTtlMs,"retention.artifactTtlMs",6e4,365*24*60*60*1e3),wipeWorkspace:!!e.retention.wipeWorkspace},labels:Object.fromEntries(Object.entries(e.labels).map(([o,s])=>[G(o,"label key"),c(s,`labels.${o}`,500)]).sort(([o],[s])=>o.localeCompare(s)))}}function Re(e){let{checksum:t,...n}=e;return n}function T(e){return(0,x.createHash)("sha256").update(l(e)).digest("hex")}function Ie(e,t){let n=l(e);if(Buffer.byteLength(n,"utf8")>256*1024)throw new Error(`${t} exceeds 262144 bytes`);return JSON.parse(n)}function p(e,t){let n=c(e,t,512);if(!/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(n))throw new Error(`${t} is invalid`);return n}function G(e,t){let n=c(e,t,160);if(!/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(n))throw new Error(`${t} is invalid`);return n}function c(e,t,n){let r=e.trim();if(!r||r.length>n||y(r,{allowTab:!0,allowLineBreaks:!0}))throw new Error(`${t} is invalid`);return r}function He(e,t){let n=e.trim();if(n.length>4096||y(n,{allowTab:!0,allowLineBreaks:!0}))throw new Error(`${t} is invalid`);return n}function W(e,t){return u(e,t,1,Number.MAX_SAFE_INTEGER)}function u(e,t,n,r){if(!Number.isSafeInteger(e)||e<n||e>r)throw new Error(`${t} must be an integer between ${n} and ${r}`);return e}function Z(e,t){let n=Date.parse(e);if(!Number.isFinite(n)||new Date(n).toISOString()!==e)throw new Error(`${t} must be an ISO-8601 UTC timestamp`);return e}function Ae(e,t){let n=c(e.toLowerCase(),t,253);if(n==="localhost"||/^(?:\d{1,3}\.){3}\d{1,3}$/.test(n)||n.includes(":")||!/^(?:\*\.)?(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(n))throw new Error(`${t} must be a public DNS hostname or wildcard hostname`);return n}function v(e,t){let n=c(e.replaceAll("\\","/"),t,4096);if(n.startsWith("/")||/^[A-Za-z]:\//.test(n)||n.split("/").includes(".."))throw new Error(`${t} must be workspace-relative`);return n.replace(/^\.\//,"")}function Ce(e){let t=c(e,"secret environment name",256);if(!/^[A-Z_][A-Z0-9_]*$/.test(t))throw new Error("Secret environment target must be an uppercase environment variable name");return t}function Xe(e){let t=e.trim().toLowerCase();if(!/^sha256:[a-f0-9]{64}$/.test(t))throw new Error("image.digest must be a sha256 OCI digest");return t}function Oe(e,t){return c(e,t,512)}function Pe(e,t,n){return[...new Set(e.map((r,o)=>c(r,`${t}[${o}]`,n)))]}var g=require("node:crypto");function Ne(e){let t=typeof e.body=="string"?Buffer.from(e.body,"utf8"):Buffer.from(e.body),n=(0,g.createHash)("sha256").update(t).digest("hex"),r=e.signature?.trim();if(!r)return{valid:!1,source:e.source,bodySha256:n,error:"missing-signature"};if(!e.secret||e.secret.length<16)throw new Error("Webhook secret must contain at least 16 characters");let o,s=r;if(e.source==="slack"){if(!e.timestamp||!/^\d+$/.test(e.timestamp))return{valid:!1,source:e.source,bodySha256:n,error:"invalid-timestamp"};let a=Number(e.timestamp)*1e3,d=Math.abs((e.now??new Date).getTime()-a);if(!Number.isFinite(a)||d>(e.maxClockSkewMs??5*6e4))return{valid:!1,source:e.source,bodySha256:n,timestamp:e.timestamp,error:"stale-timestamp"};o=`v0=${(0,g.createHmac)("sha256",e.secret).update(`v0:${e.timestamp}:`).update(t).digest("hex")}`}else e.source==="gitlab"?o=e.secret:e.source==="teams"?o=`HMAC ${(0,g.createHmac)("sha256",Buffer.from(e.secret,"base64")).update(t).digest("base64")}`:(o=`${e.source==="github"||e.source==="jira"?"sha256=":e.source==="xeno"?"v1=":""}${(0,g.createHmac)("sha256",e.secret).update(t).digest("hex")}`,e.source==="linear"&&s.startsWith("sha256=")&&(s=s.slice(7)));let i=Me(o,s);return{valid:i,source:e.source,bodySha256:n,...e.timestamp?{timestamp:e.timestamp}:{},...i?{}:{error:"invalid-signature"}}}function Me(e,t){let n=Buffer.from(e,"utf8"),r=Buffer.from(t,"utf8");return n.length===r.length&&(0,g.timingSafeEqual)(n,r)}var A=require("node:crypto");var w="xeno.hosted-execution-adapter-certification.v2",D=2,Q=744*60*60*1e3;function De(e){return Y(e),Buffer.from(V(e),"utf8")}function Ve(e,t){if(e?.schemaVersion!==w)throw new Error(`Hosted execution adapter certificate must use ${w}`);let{signature:n,...r}=e;if(Y(r),n?.algorithm!=="ed25519")throw new Error("Hosted execution adapter signature must use ed25519");let o=I(t.executableSha256,"executableSha256"),s=I(t.controlPlaneCandidateSha256,"controlPlaneCandidateSha256");if(r.adapter.executableSha256!==o)throw new Error("Hosted execution adapter executable does not match its signed certificate");if(r.controlPlaneCandidateSha256!==s)throw new Error("Hosted execution adapter certificate is bound to another control-plane candidate");let i=t.platform??process.platform,a=t.architecture??process.arch;if(r.platform.os!==i||r.platform.architecture!==a)throw new Error(`Hosted execution adapter certificate targets ${r.platform.os}-${r.platform.architecture}, not ${i}-${a}`);let d=H(r.issuedAt,"issuedAt"),f=H(r.expiresAt,"expiresAt"),J=(t.now??new Date).getTime();if(d>J+5*6e4)throw new Error("Hosted execution adapter certificate is not yet valid");if(f<=J)throw new Error("Hosted execution adapter certificate has expired");if(f<=d||f-d>Q)throw new Error("Hosted execution adapter certificate lifetime must be positive and at most 31 days");let F=t.trustedKeys[r.reviewer.keyId];if(!F)throw new Error(`Hosted execution adapter reviewer key is not trusted: ${r.reviewer.keyId}`);if(!(0,A.verify)(null,Buffer.from(V(r),"utf8"),F,$e(n.value,"signature.value")))throw new Error("Hosted execution adapter certificate signature is invalid");return{certificationId:r.certificationId,adapterName:r.adapter.name,adapterVersion:r.adapter.version,protocolVersion:r.adapter.protocolVersion,executableSha256:o,controlPlaneCandidateSha256:s,certificateSha256:(0,A.createHash)("sha256").update(V(e)).digest("hex"),expiresAt:r.expiresAt,reviewerKeyId:r.reviewer.keyId}}function Y(e){if(e.schemaVersion!==w)throw new Error(`Hosted execution adapter certificate must use ${w}`);if(R(e.certificationId,"certificationId"),R(e.adapter?.name,"adapter.name"),R(e.adapter?.version,"adapter.version"),e.adapter?.protocolVersion!==D)throw new Error(`Hosted execution adapter protocol must be ${D}`);I(e.adapter.executableSha256,"adapter.executableSha256"),I(e.controlPlaneCandidateSha256,"controlPlaneCandidateSha256"),R(e.reviewer?.keyId,"reviewer.keyId");let t=["immutableImages","filesystemIsolation","networkDefaultDeny","destinationAllowlist","secretProjection","nonRootExecution","readOnlyRoot","processTreeCleanup","resourceLimits","interactiveControl","artifactProtocol","gitResultReporting"];if(!e.capabilities||t.some(n=>e.capabilities[n]!==!0))throw new Error("Hosted execution adapter certificate does not attest every required containment capability");H(e.issuedAt,"issuedAt"),H(e.expiresAt,"expiresAt")}function V(e){return l(e)}function I(e,t){let n=e?.trim().toLowerCase();if(!/^[a-f0-9]{64}$/.test(n))throw new Error(`${t} must be a lowercase SHA-256 digest`);return n}function R(e,t){let n=e?.trim();if(!n||n.length>256||!/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(n))throw new Error(`${t} is invalid`);return n}function H(e,t){let n=Date.parse(e);if(!Number.isFinite(n)||new Date(n).toISOString()!==e)throw new Error(`${t} must be an ISO-8601 UTC timestamp`);return n}function $e(e,t){if(typeof e!="string"||e.length===0||e.length>4096||!/^[A-Za-z0-9+/]+={0,2}$/.test(e))throw new Error(`${t} must be bounded base64`);let n=Buffer.from(e,"base64");if(n.toString("base64")!==e)throw new Error(`${t} is not canonical base64`);return n}var se=require("node:crypto");var ee=["low","medium","high","xhigh","max"],te=["default","plan","acceptEdits","auto","dontAsk","bypassPermissions"];var Be=/^\/([A-Za-z][A-Za-z0-9_.:-]*)(?=\s|$)/,$="Nothing was sent to the model.",ne="unsupported_slash_command",yt=Object.freeze({"thread.run":"prompt","turn.start":"input","turn.steer":"input","schedule.create":"prompt","schedule.update":"prompt"});function re(e){let t=e.trimStart();if(t==="/"||/^\/\s/.test(t))return"";let n=Be.exec(t);return n?n[1].toLowerCase():null}var ie=2,ae=["Read","Write","Edit","Glob","Grep","WebFetch"],qe=new Set(ae);function ce(e){if(!le(e.certificationId))throw new Error("certificationId is invalid");let t=new Set(e.authority.secretRefs);return{certificationId:e.certificationId,environmentChecksum:e.environment.checksum.value,imageDigest:e.environment.image.digest,networkPolicySha256:oe({authority:e.authority.network,policy:e.environment.network}),secretProjectionSha256:oe(e.environment.secrets.filter(n=>t.has(n.ref))),filesystem:e.authority.filesystem,network:e.authority.network==="deny"?"deny":"allowlist",immutableImage:!0,readOnlyRoot:!0,nonRoot:!0,processTreeCleanup:!0,resourceLimits:!0,inferenceGateway:"brokered"}}var C=class extends Error{code="INVALID_HOSTED_EXECUTION_JOB";errors;reason;command;field;constructor(t){super(`Invalid hosted execution job: ${t.errors.join("; ")}`),this.name="XenoHostedExecutionJobError",this.errors=[...t.errors],t.slashCommand&&(this.reason=t.slashCommand.reason,this.command=t.slashCommand.command,this.field=t.slashCommand.field)}};function de(e){if(typeof e!="string")return null;let t=re(e);if(t===null)return null;let n={reason:ne,field:"prompt"};if(!t)return{...n,command:"/",message:`prompt begins with a bare "/"; a hosted job prompt is sent to the model as text and hosted execution runs no commands. Rephrase the prompt so it does not begin with "/". ${$}`};let r=`/${t}`;return{...n,command:r,message:`prompt is the slash command ${r}; a hosted job prompt is sent to the model as text and hosted execution runs no commands, so slash commands are refused. Rephrase the prompt so it does not begin with "${r}". ${$}`}}function ue(e){let t=[];if(!Ke(e))return{valid:!1,errors:["Hosted execution job must be an object"]};let n=e;if(n.protocolVersion!==ie||n.kind!=="xeno-hosted-execution-job")return t.push("Unsupported hosted execution protocol"),{valid:!1,errors:t};b(n.runId,"runId",t),b(n.userId,"userId",t),b(n.workspaceId,"workspaceId",t),B(n.workspaceHostPath,"workspaceHostPath",4096,t),B(n.prompt,"prompt",512*1024,t),B(n.model,"model",512,t),n.effort!==void 0&&!ee.includes(n.effort)&&t.push("effort is invalid"),te.includes(n.permissionMode)||t.push("permissionMode is invalid"),(typeof n.runScopedToken!="string"||!n.runScopedToken.startsWith("xrun_")||n.runScopedToken.length>16*1024)&&t.push("runScopedToken is not a bounded run-scoped token");let r;try{r=new URL(n.inferenceBaseUrl),(r.protocol!=="https:"||r.username||r.password||r.hash)&&t.push("inferenceBaseUrl must be credential-free HTTPS")}catch{t.push("inferenceBaseUrl is invalid")}let o=_(n.environment);t.push(...o.errors.map(a=>`environment: ${a}`)),n.environment?.workspaceId!==n.workspaceId&&t.push("environment workspace does not match the job"),n.environment?.image?.os!=="linux"&&t.push("hosted execution image must target Linux");let s=n.environment?.repository?.commit;(typeof s!="string"||!/^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(s))&&t.push("environment repository requires a full 40- or 64-character commit object id"),je(n.authority,t),Ue(n.budget,n.environment,t),ze(n.allowedTools,t),Je(n,t),Fe(n,t),r&&!n.environment?.network?.destinations?.some(a=>{let d=a.ports?.length?a.ports:[443];return a.host.toLowerCase()===r.hostname.toLowerCase()&&d.includes(Number(r.port||443))})&&t.push("inference origin is absent from the environment network allowlist");try{let a=Ge(n.environment?.repository);n.environment?.network?.destinations?.some(d=>{let f=d.ports?.length?d.ports:[443];return d.host.toLowerCase()===a.hostname&&f.includes(a.port)})||t.push("repository origin is absent from the environment network allowlist")}catch{t.push("environment repository must resolve to a credential-free HTTPS origin")}let i=de(n.prompt);return i?(t.push(i.message),{valid:!1,errors:t,slashCommand:i}):{valid:t.length===0,errors:t}}function Le(e){let t=ue(e);if(!t.valid)throw new C(t)}function je(e,t){(!e||!["read","workspace-write"].includes(e.filesystem))&&t.push("authority.filesystem is invalid"),(!e||!["deny","environment-policy"].includes(e.network))&&t.push("authority.network is invalid"),(!e||!["deny","approval-required"].includes(e.externalActions))&&t.push("authority.externalActions is invalid"),!Array.isArray(e?.secretRefs)||new Set(e.secretRefs).size!==e.secretRefs.length?t.push("authority.secretRefs must be a unique array"):e.secretRefs.forEach((n,r)=>b(n,`authority.secretRefs[${r}]`,t))}function Ue(e,t,n){(!e||!Number.isFinite(e.maxCredits)||e.maxCredits<=0)&&n.push("budget.maxCredits is invalid"),(!e||!q(e.maxDurationMs)||e.maxDurationMs>(t?.resources?.wallTimeMs??0))&&n.push("budget.maxDurationMs is invalid or exceeds the environment limit"),e?.maxTokens!==void 0&&!q(e.maxTokens)&&n.push("budget.maxTokens is invalid"),e?.maxToolCalls!==void 0&&!q(e.maxToolCalls)&&n.push("budget.maxToolCalls is invalid")}function ze(e,t){if(!Array.isArray(e)||e.length<1||e.length>512||new Set(e).size!==e.length){t.push("allowedTools must contain 1..512 unique tool names");return}e.forEach((n,r)=>{b(n,`allowedTools[${r}]`,t),qe.has(n)||t.push(`allowedTools[${r}] is not in the hosted v0.1 registry`)})}function Je(e,t){if(!Array.isArray(e.secrets)||e.secrets.length>128){t.push("secrets must be a bounded array");return}let n=new Set(e.authority?.secretRefs??[]),r=new Map((e.environment?.secrets??[]).map(s=>[s.ref,s])),o=new Set;for(let[s,i]of e.secrets.entries()){let a=r.get(i.ref);if(!a||!n.has(i.ref)||o.has(i.ref)){t.push(`secrets[${s}] is undeclared, unauthorized, or duplicated`);continue}o.add(i.ref),(E(a.target)!==E(i.target)||a.exposeToChildProcesses!==i.exposeToChildProcesses)&&t.push(`secrets[${s}] does not match its declared projection`),(typeof i.value!="string"||i.value.length<1||Buffer.byteLength(i.value,"utf8")>1024*1024)&&t.push(`secrets[${s}] value is empty or too large`)}for(let s of e.environment?.secrets??[])s.required&&(!n.has(s.ref)||!o.has(s.ref))&&t.push(`required secret ${s.ref} is absent or unauthorized`);[...n].some(s=>!r.has(s))&&t.push("authority references an undeclared secret")}function Fe(e,t){let n=e.expectedBoundary;if(!n){t.push("expectedBoundary is missing");return}let r;try{r=ce({certificationId:n.certificationId,environment:e.environment,authority:e.authority})}catch{t.push("expectedBoundary does not match the hosted execution contract");return}(!le(n.certificationId)||E(n)!==E(r))&&t.push("expectedBoundary does not match the hosted execution contract")}function b(e,t,n){(typeof e!="string"||!/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,511}$/.test(e))&&n.push(`${t} is invalid`)}function B(e,t,n,r){(typeof e!="string"||e.length<1||e.length>n||e.includes("\0"))&&r.push(`${t} is invalid`)}function q(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>0}function le(e){return typeof e=="string"&&/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,511}$/.test(e)}function Ke(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function E(e){return l(e)}function oe(e){return(0,se.createHash)("sha256").update(E(e)).digest("hex")}function Ge(e){if(!e)throw new Error("repository source is missing");let t=e.repository.replace(/^\/+|\/+$/g,""),n=e.provider==="github"&&!t.includes("://")?`https://github.com/${t}.git`:e.provider==="gitlab"&&!t.includes("://")?`https://gitlab.com/${t}.git`:e.provider==="bitbucket"&&!t.includes("://")?`https://bitbucket.org/${t}.git`:e.repository,r=new URL(n);if(r.protocol!=="https:"||r.username||r.password||r.hash)throw new Error("repository origin is not credential-free HTTPS");return{hostname:r.hostname.toLowerCase(),port:Number(r.port||443)}}var O=require("node:crypto");var j=1,U=1;function pe(e){let t={schemaVersion:j,kind:"xeno-hosted-control",controlId:m(e.controlId??`hctl_${(0,O.randomUUID)()}`,"controlId"),runId:m(e.runId,"runId"),workspaceId:m(e.workspaceId,"workspaceId"),actorId:m(e.actorId,"actorId"),idempotencyKey:h(e.idempotencyKey,"idempotencyKey",512),createdAt:z(e.createdAt,"createdAt"),action:Ye(e.action)};return{...t,hash:{algorithm:"sha256",value:fe(t)}}}function We(e){let t=[];try{let{hash:n,schemaVersion:r,kind:o,...s}=e,i=pe(s);(e.schemaVersion!==j||e.kind!=="xeno-hosted-control")&&t.push("Unsupported hosted control command"),k(X(e))!==k(X(i))&&t.push("Hosted control command is not normalized"),(n?.algorithm!=="sha256"||n.value!==i.hash.value)&&t.push("Hosted control command hash mismatch")}catch(n){t.push(n instanceof Error?n.message:String(n))}return{valid:t.length===0,errors:t}}function Ze(e){if(!["accepted","applied","rejected","unsupported"].includes(e.status))throw new Error("Hosted control acknowledgement status is invalid");return{controlId:m(e.controlId,"controlId"),status:e.status,acknowledgedAt:z(e.acknowledgedAt,"acknowledgedAt"),...e.reason?{reason:h(e.reason,"reason",2048)}:{}}}function ge(e){let t=e.git?{...e.git.branch?{branch:L(e.git.branch,"git.branch")}:{},...e.git.baseRef?{baseRef:L(e.git.baseRef,"git.baseRef")}:{},...e.git.commit?{commit:L(e.git.commit,"git.commit")}:{}}:void 0,n={schemaVersion:U,kind:"xeno-hosted-run-result",runId:m(e.runId,"runId"),workspaceId:m(e.workspaceId,"workspaceId"),completedAt:z(e.completedAt,"completedAt"),...t&&Object.keys(t).length>0?{git:t}:{},...e.pullRequest?{pullRequest:et(e.pullRequest)}:{},artifactIds:me(e.artifactIds,"artifactIds"),evidenceArtifactIds:me(e.evidenceArtifactIds,"evidenceArtifactIds")};return{...n,hash:{algorithm:"sha256",value:fe(n)}}}function Qe(e){let t=[];try{let{hash:n,schemaVersion:r,kind:o,...s}=e,i=ge(s);(e.schemaVersion!==U||e.kind!=="xeno-hosted-run-result")&&t.push("Unsupported hosted run result"),k(X(e))!==k(X(i))&&t.push("Hosted run result is not normalized"),(n?.algorithm!=="sha256"||n.value!==i.hash.value)&&t.push("Hosted run result hash mismatch")}catch(n){t.push(n instanceof Error?n.message:String(n))}return{valid:t.length===0,errors:t}}function Ye(e){if(e?.type==="message")return{type:"message",message:h(e.message,"action.message",32768)};if(e?.type==="approval"){if(e.decision!=="approved"&&e.decision!=="rejected")throw new Error("Hosted approval decision is invalid");return{type:"approval",requestId:m(e.requestId,"action.requestId"),decision:e.decision,scopeHash:tt(e.scopeHash,"action.scopeHash"),...e.rationale?{rationale:h(e.rationale,"action.rationale",4096)}:{}}}throw new Error("Hosted control action is invalid")}function et(e){let t;try{t=new URL(e.url)}catch{throw new Error("pullRequest.url is invalid")}if(t.protocol!=="https:"||t.username||t.password)throw new Error("pullRequest.url must be credential-free HTTPS");if(!Number.isSafeInteger(e.number)||e.number<1)throw new Error("pullRequest.number must be a positive integer");return{provider:m(e.provider,"pullRequest.provider"),repository:h(e.repository,"pullRequest.repository",2048),number:e.number,url:t.toString()}}function me(e,t){if(!Array.isArray(e)||e.length>1e4)throw new Error(`${t} is invalid`);return[...new Set(e.map((n,r)=>m(n,`${t}[${r}]`)))].sort()}function L(e,t){return h(e,t,512)}function m(e,t){let n=h(e,t,512);if(!/^[A-Za-z0-9][A-Za-z0-9._:@/-]*$/.test(n))throw new Error(`${t} is invalid`);return n}function h(e,t,n){let r=e?.trim();if(!r||r.length>n||y(r,{allowTab:!0,allowLineBreaks:!0}))throw new Error(`${t} is invalid`);return r}function z(e,t){let n=Date.parse(e);if(!Number.isFinite(n)||new Date(n).toISOString()!==e)throw new Error(`${t} must be ISO-8601 UTC`);return e}function tt(e,t){let n=e?.trim().toLowerCase();if(!/^[a-f0-9]{64}$/.test(n))throw new Error(`${t} must be a lowercase SHA-256 digest`);return n}function fe(e){return(0,O.createHash)("sha256").update(k(e)).digest("hex")}function k(e){return l(e)}function X(e){let{hash:t,...n}=e;return n}0&&(module.exports={XENO_HOSTED_CONTROL_SCHEMA_VERSION,XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION,XENO_HOSTED_EVENT_SCHEMA_VERSION,XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA,XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS,XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION,XENO_HOSTED_EXECUTION_PROTOCOL_VERSION,XENO_HOSTED_EXECUTION_TOOL_NAMES,XENO_HOSTED_RESULT_SCHEMA_VERSION,XENO_HOSTED_RUN_SCHEMA_VERSION,XENO_HOSTED_TRIGGER_SCHEMA_VERSION,XenoHostedExecutionJobError,assertValidXenoHostedExecutionJob,createXenoHostedControlCommand,createXenoHostedEnvironmentManifest,createXenoHostedEvent,createXenoHostedExecutionBoundaryReceipt,createXenoHostedRunResult,deriveHostedIdempotencyKey,hostedEnvironmentIdentity,hostedSlashCommandRefusal,normalizeXenoHostedControlAcknowledgement,verifyXenoHostedControlCommand,verifyXenoHostedEnvironmentManifest,verifyXenoHostedEventChain,verifyXenoHostedExecutionAdapterCertification,verifyXenoHostedExecutionJob,verifyXenoHostedRunResult,verifyXenoHostedWebhook,xenoHostedExecutionAdapterSigningPayload});
|
package/dist/hosted/index.d.cts
CHANGED
|
@@ -353,6 +353,7 @@ interface XenoVerifiedHostedExecutionAdapterCertification {
|
|
|
353
353
|
}
|
|
354
354
|
declare function xenoHostedExecutionAdapterSigningPayload(certificate: Omit<XenoHostedExecutionAdapterCertification, "signature">): Buffer;
|
|
355
355
|
declare function verifyXenoHostedExecutionAdapterCertification(certificate: XenoHostedExecutionAdapterCertification, options: XenoHostedExecutionAdapterVerificationOptions): XenoVerifiedHostedExecutionAdapterCertification;
|
|
356
|
+
declare const XENO_UNSUPPORTED_SLASH_COMMAND_REASON = "unsupported_slash_command";
|
|
356
357
|
declare const XENO_HOSTED_EXECUTION_PROTOCOL_VERSION: 2;
|
|
357
358
|
declare const XENO_HOSTED_EXECUTION_TOOL_NAMES: readonly [
|
|
358
359
|
"Read",
|
|
@@ -408,10 +409,27 @@ declare function createXenoHostedExecutionBoundaryReceipt(options: {
|
|
|
408
409
|
environment: XenoHostedEnvironmentManifest;
|
|
409
410
|
authority: XenoHostedAuthority;
|
|
410
411
|
}): XenoHostedExecutionBoundaryReceipt;
|
|
411
|
-
|
|
412
|
+
interface XenoHostedSlashCommandRefusal {
|
|
413
|
+
reason: typeof XENO_UNSUPPORTED_SLASH_COMMAND_REASON;
|
|
414
|
+
command: string;
|
|
415
|
+
field: "prompt";
|
|
416
|
+
message: string;
|
|
417
|
+
}
|
|
418
|
+
interface XenoHostedExecutionJobVerification {
|
|
412
419
|
valid: boolean;
|
|
413
420
|
errors: string[];
|
|
414
|
-
|
|
421
|
+
slashCommand?: XenoHostedSlashCommandRefusal;
|
|
422
|
+
}
|
|
423
|
+
declare class XenoHostedExecutionJobError extends Error {
|
|
424
|
+
readonly code: "INVALID_HOSTED_EXECUTION_JOB";
|
|
425
|
+
readonly errors: readonly string[];
|
|
426
|
+
readonly reason?: typeof XENO_UNSUPPORTED_SLASH_COMMAND_REASON;
|
|
427
|
+
readonly command?: string;
|
|
428
|
+
readonly field?: "prompt";
|
|
429
|
+
constructor(verification: XenoHostedExecutionJobVerification);
|
|
430
|
+
}
|
|
431
|
+
declare function hostedSlashCommandRefusal(prompt: unknown): XenoHostedSlashCommandRefusal | null;
|
|
432
|
+
declare function verifyXenoHostedExecutionJob(value: unknown): XenoHostedExecutionJobVerification;
|
|
415
433
|
declare function assertValidXenoHostedExecutionJob(value: unknown): asserts value is XenoHostedExecutionJob;
|
|
416
434
|
declare const XENO_HOSTED_CONTROL_SCHEMA_VERSION: 1;
|
|
417
435
|
declare const XENO_HOSTED_RESULT_SCHEMA_VERSION: 1;
|
|
@@ -487,4 +505,4 @@ declare function verifyXenoHostedRunResult(result: XenoHostedRunResult): {
|
|
|
487
505
|
valid: boolean;
|
|
488
506
|
errors: string[];
|
|
489
507
|
};
|
|
490
|
-
export { type VerifyXenoHostedWebhookOptions, XENO_HOSTED_CONTROL_SCHEMA_VERSION, XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION, XENO_HOSTED_EVENT_SCHEMA_VERSION, XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA, XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS, XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_TOOL_NAMES, XENO_HOSTED_RESULT_SCHEMA_VERSION, XENO_HOSTED_RUN_SCHEMA_VERSION, XENO_HOSTED_TRIGGER_SCHEMA_VERSION, type XenoHostedArchitecture, type XenoHostedAuthority, type XenoHostedBudget, type XenoHostedCacheMount, type XenoHostedControlAcknowledgement, type XenoHostedControlAction, type XenoHostedControlCommand, type XenoHostedControlCommandPayload, type XenoHostedEnvironmentManifest, type XenoHostedEnvironmentManifestPayload, type XenoHostedEventRecord, type XenoHostedExecutionAdapterCertification, type XenoHostedExecutionAdapterVerificationOptions, type XenoHostedExecutionBoundaryReceipt, type XenoHostedExecutionJob, type XenoHostedExecutionSecretValue, type XenoHostedImageReference, type XenoHostedNetworkDestination, type XenoHostedNetworkPolicy, type XenoHostedOs, type XenoHostedQuotaLease, type XenoHostedReplayCursor, type XenoHostedReplayPage, type XenoHostedRepositorySource, type XenoHostedResourceLimits, type XenoHostedRetentionPolicy, type XenoHostedRunRecord, type XenoHostedRunRequest, type XenoHostedRunResult, type XenoHostedRunResultPayload, type XenoHostedRunStatus, type XenoHostedSecretProjection, type XenoHostedSetupStep, type XenoHostedTriggerDefinition, type XenoHostedTriggerDelivery, type XenoHostedTriggerKind, type XenoHostedWebhookSource, type XenoHostedWebhookVerification, type XenoVerifiedHostedExecutionAdapterCertification, assertValidXenoHostedExecutionJob, createXenoHostedControlCommand, createXenoHostedEnvironmentManifest, createXenoHostedEvent, createXenoHostedExecutionBoundaryReceipt, createXenoHostedRunResult, deriveHostedIdempotencyKey, hostedEnvironmentIdentity, normalizeXenoHostedControlAcknowledgement, verifyXenoHostedControlCommand, verifyXenoHostedEnvironmentManifest, verifyXenoHostedEventChain, verifyXenoHostedExecutionAdapterCertification, verifyXenoHostedExecutionJob, verifyXenoHostedRunResult, verifyXenoHostedWebhook, xenoHostedExecutionAdapterSigningPayload };
|
|
508
|
+
export { type VerifyXenoHostedWebhookOptions, XENO_HOSTED_CONTROL_SCHEMA_VERSION, XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION, XENO_HOSTED_EVENT_SCHEMA_VERSION, XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA, XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS, XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_TOOL_NAMES, XENO_HOSTED_RESULT_SCHEMA_VERSION, XENO_HOSTED_RUN_SCHEMA_VERSION, XENO_HOSTED_TRIGGER_SCHEMA_VERSION, type XenoHostedArchitecture, type XenoHostedAuthority, type XenoHostedBudget, type XenoHostedCacheMount, type XenoHostedControlAcknowledgement, type XenoHostedControlAction, type XenoHostedControlCommand, type XenoHostedControlCommandPayload, type XenoHostedEnvironmentManifest, type XenoHostedEnvironmentManifestPayload, type XenoHostedEventRecord, type XenoHostedExecutionAdapterCertification, type XenoHostedExecutionAdapterVerificationOptions, type XenoHostedExecutionBoundaryReceipt, type XenoHostedExecutionJob, XenoHostedExecutionJobError, type XenoHostedExecutionJobVerification, type XenoHostedExecutionSecretValue, type XenoHostedImageReference, type XenoHostedNetworkDestination, type XenoHostedNetworkPolicy, type XenoHostedOs, type XenoHostedQuotaLease, type XenoHostedReplayCursor, type XenoHostedReplayPage, type XenoHostedRepositorySource, type XenoHostedResourceLimits, type XenoHostedRetentionPolicy, type XenoHostedRunRecord, type XenoHostedRunRequest, type XenoHostedRunResult, type XenoHostedRunResultPayload, type XenoHostedRunStatus, type XenoHostedSecretProjection, type XenoHostedSetupStep, type XenoHostedSlashCommandRefusal, type XenoHostedTriggerDefinition, type XenoHostedTriggerDelivery, type XenoHostedTriggerKind, type XenoHostedWebhookSource, type XenoHostedWebhookVerification, type XenoVerifiedHostedExecutionAdapterCertification, assertValidXenoHostedExecutionJob, createXenoHostedControlCommand, createXenoHostedEnvironmentManifest, createXenoHostedEvent, createXenoHostedExecutionBoundaryReceipt, createXenoHostedRunResult, deriveHostedIdempotencyKey, hostedEnvironmentIdentity, hostedSlashCommandRefusal, normalizeXenoHostedControlAcknowledgement, verifyXenoHostedControlCommand, verifyXenoHostedEnvironmentManifest, verifyXenoHostedEventChain, verifyXenoHostedExecutionAdapterCertification, verifyXenoHostedExecutionJob, verifyXenoHostedRunResult, verifyXenoHostedWebhook, xenoHostedExecutionAdapterSigningPayload };
|
package/dist/hosted/index.d.ts
CHANGED
|
@@ -353,6 +353,7 @@ interface XenoVerifiedHostedExecutionAdapterCertification {
|
|
|
353
353
|
}
|
|
354
354
|
declare function xenoHostedExecutionAdapterSigningPayload(certificate: Omit<XenoHostedExecutionAdapterCertification, "signature">): Buffer;
|
|
355
355
|
declare function verifyXenoHostedExecutionAdapterCertification(certificate: XenoHostedExecutionAdapterCertification, options: XenoHostedExecutionAdapterVerificationOptions): XenoVerifiedHostedExecutionAdapterCertification;
|
|
356
|
+
declare const XENO_UNSUPPORTED_SLASH_COMMAND_REASON = "unsupported_slash_command";
|
|
356
357
|
declare const XENO_HOSTED_EXECUTION_PROTOCOL_VERSION: 2;
|
|
357
358
|
declare const XENO_HOSTED_EXECUTION_TOOL_NAMES: readonly [
|
|
358
359
|
"Read",
|
|
@@ -408,10 +409,27 @@ declare function createXenoHostedExecutionBoundaryReceipt(options: {
|
|
|
408
409
|
environment: XenoHostedEnvironmentManifest;
|
|
409
410
|
authority: XenoHostedAuthority;
|
|
410
411
|
}): XenoHostedExecutionBoundaryReceipt;
|
|
411
|
-
|
|
412
|
+
interface XenoHostedSlashCommandRefusal {
|
|
413
|
+
reason: typeof XENO_UNSUPPORTED_SLASH_COMMAND_REASON;
|
|
414
|
+
command: string;
|
|
415
|
+
field: "prompt";
|
|
416
|
+
message: string;
|
|
417
|
+
}
|
|
418
|
+
interface XenoHostedExecutionJobVerification {
|
|
412
419
|
valid: boolean;
|
|
413
420
|
errors: string[];
|
|
414
|
-
|
|
421
|
+
slashCommand?: XenoHostedSlashCommandRefusal;
|
|
422
|
+
}
|
|
423
|
+
declare class XenoHostedExecutionJobError extends Error {
|
|
424
|
+
readonly code: "INVALID_HOSTED_EXECUTION_JOB";
|
|
425
|
+
readonly errors: readonly string[];
|
|
426
|
+
readonly reason?: typeof XENO_UNSUPPORTED_SLASH_COMMAND_REASON;
|
|
427
|
+
readonly command?: string;
|
|
428
|
+
readonly field?: "prompt";
|
|
429
|
+
constructor(verification: XenoHostedExecutionJobVerification);
|
|
430
|
+
}
|
|
431
|
+
declare function hostedSlashCommandRefusal(prompt: unknown): XenoHostedSlashCommandRefusal | null;
|
|
432
|
+
declare function verifyXenoHostedExecutionJob(value: unknown): XenoHostedExecutionJobVerification;
|
|
415
433
|
declare function assertValidXenoHostedExecutionJob(value: unknown): asserts value is XenoHostedExecutionJob;
|
|
416
434
|
declare const XENO_HOSTED_CONTROL_SCHEMA_VERSION: 1;
|
|
417
435
|
declare const XENO_HOSTED_RESULT_SCHEMA_VERSION: 1;
|
|
@@ -487,4 +505,4 @@ declare function verifyXenoHostedRunResult(result: XenoHostedRunResult): {
|
|
|
487
505
|
valid: boolean;
|
|
488
506
|
errors: string[];
|
|
489
507
|
};
|
|
490
|
-
export { type VerifyXenoHostedWebhookOptions, XENO_HOSTED_CONTROL_SCHEMA_VERSION, XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION, XENO_HOSTED_EVENT_SCHEMA_VERSION, XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA, XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS, XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_TOOL_NAMES, XENO_HOSTED_RESULT_SCHEMA_VERSION, XENO_HOSTED_RUN_SCHEMA_VERSION, XENO_HOSTED_TRIGGER_SCHEMA_VERSION, type XenoHostedArchitecture, type XenoHostedAuthority, type XenoHostedBudget, type XenoHostedCacheMount, type XenoHostedControlAcknowledgement, type XenoHostedControlAction, type XenoHostedControlCommand, type XenoHostedControlCommandPayload, type XenoHostedEnvironmentManifest, type XenoHostedEnvironmentManifestPayload, type XenoHostedEventRecord, type XenoHostedExecutionAdapterCertification, type XenoHostedExecutionAdapterVerificationOptions, type XenoHostedExecutionBoundaryReceipt, type XenoHostedExecutionJob, type XenoHostedExecutionSecretValue, type XenoHostedImageReference, type XenoHostedNetworkDestination, type XenoHostedNetworkPolicy, type XenoHostedOs, type XenoHostedQuotaLease, type XenoHostedReplayCursor, type XenoHostedReplayPage, type XenoHostedRepositorySource, type XenoHostedResourceLimits, type XenoHostedRetentionPolicy, type XenoHostedRunRecord, type XenoHostedRunRequest, type XenoHostedRunResult, type XenoHostedRunResultPayload, type XenoHostedRunStatus, type XenoHostedSecretProjection, type XenoHostedSetupStep, type XenoHostedTriggerDefinition, type XenoHostedTriggerDelivery, type XenoHostedTriggerKind, type XenoHostedWebhookSource, type XenoHostedWebhookVerification, type XenoVerifiedHostedExecutionAdapterCertification, assertValidXenoHostedExecutionJob, createXenoHostedControlCommand, createXenoHostedEnvironmentManifest, createXenoHostedEvent, createXenoHostedExecutionBoundaryReceipt, createXenoHostedRunResult, deriveHostedIdempotencyKey, hostedEnvironmentIdentity, normalizeXenoHostedControlAcknowledgement, verifyXenoHostedControlCommand, verifyXenoHostedEnvironmentManifest, verifyXenoHostedEventChain, verifyXenoHostedExecutionAdapterCertification, verifyXenoHostedExecutionJob, verifyXenoHostedRunResult, verifyXenoHostedWebhook, xenoHostedExecutionAdapterSigningPayload };
|
|
508
|
+
export { type VerifyXenoHostedWebhookOptions, XENO_HOSTED_CONTROL_SCHEMA_VERSION, XENO_HOSTED_ENVIRONMENT_SCHEMA_VERSION, XENO_HOSTED_EVENT_SCHEMA_VERSION, XENO_HOSTED_EXECUTION_ADAPTER_CERTIFICATION_SCHEMA, XENO_HOSTED_EXECUTION_ADAPTER_MAX_CERTIFICATE_LIFETIME_MS, XENO_HOSTED_EXECUTION_ADAPTER_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_PROTOCOL_VERSION, XENO_HOSTED_EXECUTION_TOOL_NAMES, XENO_HOSTED_RESULT_SCHEMA_VERSION, XENO_HOSTED_RUN_SCHEMA_VERSION, XENO_HOSTED_TRIGGER_SCHEMA_VERSION, type XenoHostedArchitecture, type XenoHostedAuthority, type XenoHostedBudget, type XenoHostedCacheMount, type XenoHostedControlAcknowledgement, type XenoHostedControlAction, type XenoHostedControlCommand, type XenoHostedControlCommandPayload, type XenoHostedEnvironmentManifest, type XenoHostedEnvironmentManifestPayload, type XenoHostedEventRecord, type XenoHostedExecutionAdapterCertification, type XenoHostedExecutionAdapterVerificationOptions, type XenoHostedExecutionBoundaryReceipt, type XenoHostedExecutionJob, XenoHostedExecutionJobError, type XenoHostedExecutionJobVerification, type XenoHostedExecutionSecretValue, type XenoHostedImageReference, type XenoHostedNetworkDestination, type XenoHostedNetworkPolicy, type XenoHostedOs, type XenoHostedQuotaLease, type XenoHostedReplayCursor, type XenoHostedReplayPage, type XenoHostedRepositorySource, type XenoHostedResourceLimits, type XenoHostedRetentionPolicy, type XenoHostedRunRecord, type XenoHostedRunRequest, type XenoHostedRunResult, type XenoHostedRunResultPayload, type XenoHostedRunStatus, type XenoHostedSecretProjection, type XenoHostedSetupStep, type XenoHostedSlashCommandRefusal, type XenoHostedTriggerDefinition, type XenoHostedTriggerDelivery, type XenoHostedTriggerKind, type XenoHostedWebhookSource, type XenoHostedWebhookVerification, type XenoVerifiedHostedExecutionAdapterCertification, assertValidXenoHostedExecutionJob, createXenoHostedControlCommand, createXenoHostedEnvironmentManifest, createXenoHostedEvent, createXenoHostedExecutionBoundaryReceipt, createXenoHostedRunResult, deriveHostedIdempotencyKey, hostedEnvironmentIdentity, hostedSlashCommandRefusal, normalizeXenoHostedControlAcknowledgement, verifyXenoHostedControlCommand, verifyXenoHostedEnvironmentManifest, verifyXenoHostedEventChain, verifyXenoHostedExecutionAdapterCertification, verifyXenoHostedExecutionJob, verifyXenoHostedRunResult, verifyXenoHostedWebhook, xenoHostedExecutionAdapterSigningPayload };
|