@kynver-app/runtime 0.2.143 → 0.2.144

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/cli.js CHANGED
@@ -211,7 +211,7 @@ ${e.stderr}`.toLowerCase();return t.includes("api rate limit exceeded")||t.inclu
211
211
  `,{mode:384})}catch{}}function Xte(e,t){return e?e.access===t.access&&e.source===t.source&&e.folders.length===t.folders.length&&e.folders.every((r,n)=>r===t.folders[n]):!1}function fL(e,t={signed:!1}){let r=t.file??zv(),n=t.now??(()=>new Date),o={access:e.access,folders:[...e.folders],source:e.source,signed:t.signed,at:n().toISOString()},s=Rf(r);return Xte(s.applied,o)?null:(mL(r,{applied:o,website:s.website}),{from:s.applied,to:o})}function gL(e,t={}){let r=t.file??zv(),n=t.now??(()=>new Date),o=Rf(r),s={access:e.access,folders:[...e.folders],changedAt:e.changedAt,nonce:e.nonce,at:n().toISOString()},i=o.website;return i&&i.access===s.access&&i.changedAt===s.changedAt&&i.nonce===s.nonce&&i.folders.length===s.folders.length&&i.folders.every((l,c)=>l===s.folders[c])?i:(mL(r,{applied:o.applied,website:s}),s)}function fa(e){switch(e){case"off":return"off";case"folder":return"one folder";case"folders":return"chosen folders";case"full":return"full computer";default:return String(e)}}import{appendFileSync as Qte,mkdirSync as Zte}from"node:fs";import{homedir as ere}from"node:os";import Xv from"node:path";var tre=Xv.join(".kynver","logs","chat-commands.jsonl"),hL=2e3;function Qv(e=ere()){return Xv.join(e,tre)}function Zv(e){let t=r=>r===void 0?void 0:r.length>hL?`${r.slice(0,hL)}\u2026`:r;return{...e,...e.command!==void 0?{command:t(e.command)}:{},...e.path!==void 0?{path:t(e.path)}:{}}}function ga(e,t=Qv()){try{return Zte(Xv.dirname(t),{recursive:!0}),Qte(t,`${JSON.stringify(Zv(e))}
212
212
  `,{encoding:"utf8",mode:384}),!0}catch(r){return console.error(JSON.stringify({event:"chat_command_log_write_failed",error:r instanceof Error?r.message:String(r)})),!1}}import{execFile as nre,spawnSync as vL}from"node:child_process";import{existsSync as ore,readFileSync as sre}from"node:fs";import{homedir as ire,platform as are}from"node:os";import yL from"node:path";Me();N();yi();function rre(e){let r=e.chatProvider?.trim()||e.workerProvider?.trim()||"";return Ve(r)}function As(e,t=process.env){return rre(e)!=="gemini"?"http":Qn(it(t))==="antigravity"?"antigravity":"http"}function Cf(e,t,r=process.env){return e==="cursor"?"cursor":e==="codex"?"codex":e==="gemini"?As(t,r)==="antigravity"?"antigravity":"none":e==="anthropic"?"claude-code":"none"}function lre(e,t){return e==="cursor"?or(t):e==="codex"?t.KYNVER_CODEX_BIN?.trim()||t.CODEX_BIN?.trim()||Wt():e==="antigravity"?it(t):e==="claude-code"?t.KYNVER_CLAUDE_BIN?.trim()||t.CLAUDE_BIN?.trim()||"claude":null}var cre=/\d+\.\d+(?:\.\d+)?(?:[-+][\w.]+)?/,wL=10*6e4,Sf=new Map,_f=new Set;function kL(e,t,r){let n=`${t??""} ${r??""}`;return e===0?n.match(cre)?.[0]??null:null}function xf(e,t=process.env,r=Date.now()){let n=lre(e,t);if(!n)return null;let o=Sf.get(n);if(o&&r-o.at<wL)return o.version;if(o){if(!_f.has(n)){_f.add(n);try{let[i,a]=ce(n,["--version"]);nre(i,a,oe({encoding:"utf8",timeout:5e3}),(l,c,u)=>{_f.delete(n),Sf.set(n,{at:Date.now(),version:l?null:kL(0,c,u)})})}catch{_f.delete(n),Sf.set(n,{at:r,version:o.version})}}return o.version}let s=null;try{let[i,a]=ce(n,["--version"]),l=vL(i,a,oe({encoding:"utf8",timeout:5e3}));s=kL(l.status,l.stdout,l.stderr)}catch{s=null}return Sf.set(n,{at:r,version:s}),s}var bL=new Map;function Ef(e=process.env,t={}){if(e.ANTHROPIC_API_KEY?.trim())return!0;let r=t.home??ire(),n=t.now??Date.now(),o=bL.get(r);if(o&&n-o.at<wL)return o.signedIn;let s=ure(yL.join(e.CLAUDE_CONFIG_DIR?.trim()||yL.join(r,".claude"),".credentials.json"));return!s&&(t.os??are())==="darwin"&&(s=(t.keychain??dre)()),bL.set(r,{at:n,signedIn:s}),s}function ure(e){if(!ore(e))return!1;try{let t=JSON.parse(sre(e,"utf8")).claudeAiOauth,r=n=>typeof n=="string"&&n.length>0;return!!t&&(r(t.refreshToken)||r(t.accessToken))}catch{return!1}}function dre(){try{return vL("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore",timeout:5e3}).status===0}catch{return!1}}import{createHash as pre,verify as mre,createPublicKey as fre}from"node:crypto";var RL="turnEnvelope",gre=Buffer.from("302a300506032b6570032100","hex");function tw(e){if(!e||typeof e!="object"||Array.isArray(e))return e;let t={...e};return delete t[RL],t}function hre(e){return pre("sha256").update(At(tw(e)),"utf8").digest("hex")}function rw(e){return!e||typeof e!="object"||Array.isArray(e)?null:e[RL]??null}function yre(e){if(!e||typeof e!="object")return!1;let t=e;if(typeof t.signature!="string"||!t.signature||typeof t.publicKeyId!="string"||!t.publicKeyId)return!1;let r=t.payload;return!(!r||typeof r!="object"||r.v!==1||r.kind!=="chat-turn"||typeof r.turnId!="string"||!r.turnId||typeof r.agentOsId!="string"||!r.agentOsId||r.userId!==null&&(typeof r.userId!="string"||!r.userId)||r.boxId!==null&&typeof r.boxId!="string"||r.access!==null&&(!r.access||typeof r.access!="object"||Array.isArray(r.access))||typeof r.payloadHash!="string"||!/^[0-9a-f]{64}$/.test(r.payloadHash)||typeof r.exp!="number"||!Number.isFinite(r.exp)||typeof r.nonce!="string"||!r.nonce)}function kre(e,t){let r=e&&typeof e=="object"&&!Array.isArray(e)?e.computerAccess??null:null;return r===null&&t===null?!0:r===null||t===null?!1:At(r)===At(t)}var Af=class{constructor(t=1e4){this.maxEntries=t}maxEntries;byNonce=new Map;byTurn=new Map;consume(t){let r=t.nowSec??Math.floor(Date.now()/1e3);this.purge(r);let n=this.byNonce.get(t.nonce);if(n)return n.turnId!==t.turnId?{ok:!1,replay:ew(n,"turn_mismatch")}:n.state==="verified"?{ok:!0,redelivered:!0}:{ok:!1,replay:ew(n,n.state==="started"?"in_flight":"already_ran")};let o=this.byTurn.get(t.turnId);if(o){if(o.state!=="verified")return{ok:!1,replay:ew(o,o.state==="started"?"in_flight":"already_ran")};this.byNonce.delete(o.nonce);let i={...o,nonce:t.nonce,untilSec:Math.max(o.untilSec,t.expSec+60)};return this.byNonce.set(t.nonce,i),this.byTurn.set(t.turnId,i),{ok:!0,redelivered:!0}}if(this.byNonce.size>=this.maxEntries){let i=this.byNonce.values().next().value;i&&this.forget(i)}let s={nonce:t.nonce,turnId:t.turnId,firstSeenSec:r,state:"verified",untilSec:t.expSec+60};return this.byNonce.set(t.nonce,s),this.byTurn.set(t.turnId,s),{ok:!0,redelivered:!1}}markStarted(t){let r=this.byTurn.get(t);return r?(r.state==="verified"&&(r.state="started"),!0):!1}markFinished(t){let r=this.byTurn.get(t);return r?(r.state="finished",!0):!1}stateOf(t){return this.byTurn.get(t)?.state??null}purge(t=Math.floor(Date.now()/1e3)){for(let r of[...this.byNonce.values()])r.untilSec<=t&&this.forget(r)}forget(t){this.byNonce.delete(t.nonce),this.byTurn.get(t.turnId)===t&&this.byTurn.delete(t.turnId)}get size(){return this.byNonce.size}};function ew(e,t){return{state:t,firstSeenAt:new Date(e.firstSeenSec*1e3).toISOString(),turnId:e.turnId}}function bre(e){return fre({key:Buffer.concat([gre,Buffer.from(e)]),format:"der",type:"spki"})}function SL(e,t,r={}){let n=r.env??process.env,o=r.nowSec??Math.floor(Date.now()/1e3),s=rw(e);if(s===null)return{ok:!1,code:"unsigned",reason:"turn carries no signed envelope"};if(!yre(s))return{ok:!1,code:"malformed",reason:"malformed chat-turn envelope"};let i=s;if(i.payload.agentOsId!==t.agentOsId)return{ok:!1,code:"agent_os_mismatch",reason:"envelope is for another workspace"};if(i.payload.turnId!==t.turnId)return{ok:!1,code:"turn_id_mismatch",reason:"envelope is for another turn"};if(i.payload.exp<=o)return{ok:!1,code:"expired",reason:"envelope expired"};let a=is(i.publicKeyId,n);if(!a)return{ok:!1,code:"no_verification_key",reason:`no verification key for publicKeyId "${i.publicKeyId}"`};let l;try{l=Buffer.from(i.signature,"base64url")}catch{return{ok:!1,code:"bad_signature",reason:"signature is not base64url"}}if(l.length!==64)return{ok:!1,code:"bad_signature",reason:"signature is not a 64-byte Ed25519 signature"};let c=!1;try{let d=Buffer.from(At(i.payload),"utf8");c=mre(null,d,bre(a),l)}catch(d){return{ok:!1,code:"bad_signature",reason:`signature verification failed: ${d.message}`}}if(!c)return{ok:!1,code:"bad_signature",reason:"Ed25519 signature mismatch"};if(hre(e)!==i.payload.payloadHash)return{ok:!1,code:"payload_tampered",reason:"turn payload does not match its signed hash"};if(!kre(e,i.payload.access))return{ok:!1,code:"access_mismatch",reason:"computer access on the turn differs from the signed setting"};if(!r.nonces)return{ok:!0,payload:i.payload,redelivered:!1};let u=r.nonces.consume({nonce:i.payload.nonce,turnId:i.payload.turnId,expSec:i.payload.exp,nowSec:o});return u.ok?{ok:!0,payload:i.payload,redelivered:u.redelivered}:{ok:!1,code:"replayed",reason:`envelope nonce already used on this computer (${vre(u.replay)})`,replay:u.replay}}function vre(e){return`${e.state==="in_flight"?"this computer is running that turn now":e.state==="already_ran"?"that turn already ran here":`the nonce belongs to turn ${e.turnId}`}; first seen ${e.firstSeenAt}`}var wre="KYNVER_CHAT_TURN_SIGNATURE";function _L(e=process.env,t={}){let r=(e[wre]??t.chatTurnSignature??"").toString().trim().toLowerCase();return r==="optional"||r==="off"||r==="0"||r==="false"?"optional":"required"}function CL(e,t){return t?`turn_rejected_${e}: ${t}`:`turn_rejected_${e}`}function xL(e,t){if(!(rw(e.payload)!==null)&&t.policy==="optional"){let o=e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload.computerAccess??null:null;return{ok:!0,access:Rre(o)?o:null,signed:!1,userId:null,redelivered:!1}}let n=SL(e.payload,{agentOsId:t.agentOsId,turnId:e.turnId},{env:t.env,nowSec:t.nowSec,nonces:t.nonces});return n.ok?{ok:!0,access:n.payload.access,signed:!0,userId:n.payload.userId,redelivered:n.redelivered}:{ok:!1,code:n.code,reason:n.reason,...n.replay?{replay:n.replay}:{}}}function Rre(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e.byBox;return!!t&&typeof t=="object"&&!Array.isArray(t)}import{createHash as Ore}from"node:crypto";var nw="KYNVER_CONVERSATION",ow="KYNVER_AGENT_TAB_ENGINE",EL="X-Kynver-Conversation",Sre=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function qc(e){return typeof e=="string"&&Sre.test(e.trim())?e.trim():null}function Pf(e){return`Kynver conversation id: ${e}. When work you start from this conversation later finishes, fails, needs the user or opens / merges a PR, post the update here only: \`kynver tab post --conversation ${e} "<text>"\` (or the agent_tab_post tool with this conversationId). When you create a Kynver task for it, pass originConversationId=${e} so its updates come back here too.`}function AL(e,t){let r=qc(e);return r?{[nw]:r,[ow]:t}:{}}var _re=["hermes","openclaw","claude-code","grok-bot"],ha={hermes:"Hermes",openclaw:"OpenClaw","claude-code":"Claude Code","grok-bot":"Grok Bot"};function zc(e){return typeof e=="string"&&_re.includes(e)}var Cre=/^[A-Za-z0-9-]{8,64}$/,PL=32e3,xre=4e3,Ere=5,Are=20*1024*1024,Pre=/^[A-Za-z0-9_.:-]{8,128}$/;function IL(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;if(t.kind!=="agent-tab"||!zc(t.engine)||typeof t.sessionKey!="string"||!Pre.test(t.sessionKey))return null;let r=typeof t.text=="string"?t.text.slice(0,PL):"",n=[],o=0;if(Array.isArray(t.attachments))for(let c of t.attachments.slice(0,Ere)){if(!c||typeof c!="object")continue;let{name:u,mime:d,contentBase64:p}=c;if(!(typeof u!="string"||typeof p!="string")){if(o+=Math.floor(p.length*3/4),o>Are)break;n.push({name:u.slice(0,200),mime:typeof d=="string"?d.slice(0,100):"application/octet-stream",contentBase64:p})}}let s=Ire(t.control);if(!s&&!r.trim()&&n.length===0)return null;let i=typeof t.styleNote=="string"?t.styleNote.trim().slice(0,xre):"",a=typeof t.replyTurnId=="string"&&Cre.test(t.replyTurnId)?t.replyTurnId:null,l=qc(t.conversationId);return{kind:"agent-tab",engine:t.engine,sessionKey:t.sessionKey,text:r,attachments:n,...t.computerAccess!==void 0?{computerAccess:t.computerAccess}:{},...i?{styleNote:i}:{},...a?{replyTurnId:a}:{},...s?{control:s}:{},...l?{conversationId:l}:{}}}function Ire(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return t.op==="stop"?{op:"stop"}:t.op==="steer"&&typeof t.text=="string"&&t.text.trim()?{op:"steer",text:t.text.slice(0,PL)}:null}var OL=32e3,Tre=8*1024*1024,Nre=20*1024*1024,Dre=10,TL=[2e3,4e3,8e3,16e3,32e3],Mre=e=>new Promise(t=>setTimeout(t,e));function Lre(e){return`${e.apiBaseUrl.replace(/\/$/,"")}/api/agent-os/by-id/${encodeURIComponent(e.agentOsId)}/agent-tabs/box`}function Bre(e,t,r){let n=e.trim()?e:`${t} finished without writing a reply.`;return r.length>0&&(n+=`
213
213
 
214
- _${r.length===1?"A file":`${r.length} files`} couldn't be attached: ${r.join(", ")}._`),n.length>OL?`${n.slice(0,OL-1)}\u2026`:n}var Ure=ha;function NL(e){let t=e.fetchFn??fetch,r=e.wait??Mre,n=e.redactText??(c=>Cc(e.agentOsId,c)),o=c=>{let u=$m(e.agentOsId,c),d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(u)}catch{return u}if(d.includes("\0"))return u;let p=n(d);return p===d?u:Buffer.from(p,"utf8")},s=Lre(e),i=new URL(e.apiBaseUrl).origin,a=async(c,u)=>{let p={Authorization:`Bearer ${await e.bearer()}`},m=u.body;u.json!==void 0&&(p["Content-Type"]="application/json",m=JSON.stringify(u.json));let f=await t(c,{method:u.method??"POST",headers:p,body:m});return f.status===401&&e.onUnauthorized?.(),f},l=async c=>{try{let u=o(Buffer.from(c.contentBase64,"base64")),d=Ore("sha256").update(u).digest("hex"),p=await a(`${s}/uploads`,{json:{name:n(c.name).slice(0,200),size:u.length,sha256:d}});if(!p.ok)return null;let m=await p.json();for(let y=0;y<m.parts;y++){let k=u.subarray(y*m.partBytes,(y+1)*m.partBytes),h=new URL(m.partUrl.replace("{index}",String(y)),i).toString(),b=!1;for(let w=0;w<3&&!b;w++)b=!!(await t(h,{method:"PUT",body:new Uint8Array(k)}).catch(()=>null))?.ok,b||await r(1e3*(w+1));if(!b)return null}let f=await a(new URL(m.completeUrl,i).toString(),{method:"POST"});if(!f.ok)return null;let g=await f.json();return typeof g.file?.id=="string"?g.file.id:null}catch{return null}};return{async heartbeat(c){try{let u=await a(`${s}/turns/${encodeURIComponent(c)}/heartbeat`,{json:{}});return u.status!==404&&u.status!==410?"continue":(await u.json().catch(()=>null))?.code==="turn_stopped"?"stop":"gone"}catch{return"continue"}},async deliver({replyTurnId:c,engine:u,text:d,files:p}){let m=[],f=[],g=0;for(let k of p.slice(0,Dre)){let h=k.sizeBytes??Math.floor(k.contentBase64.length*3/4),b=n(k.name).slice(0,200);if(h<=Tre&&g+h<=Nre){let S=o(Buffer.from(k.contentBase64,"base64"));g+=S.length,m.push({name:b,contentBase64:S.toString("base64")});continue}let w=await l(k);w?m.push({fileId:w}):f.push(b.slice(0,80))}let y={engine:u,idempotencyKey:`turn-reply:${c}`,turnId:c,text:Bre(n(d),Ure[u],f),attachments:m,notify:!0};for(let k=0;;k++){let h=0;try{let w=await a(`${s}/posts`,{json:y});if(h=w.status,w.ok)return!0}catch{h=0}if(!(h===0||h===401||h===408||h===429||h>=500)||k>=TL.length)return!1;await r(TL[k])}}}}async function ya(e){if(e.auth){let t=await e.auth.authorization();if(t)return{bearer:t.bearer,kind:t.kind,boxId:t.boxId??e.boxId}}return{bearer:e.apiKey,kind:"api_key",boxId:e.boxId}}function Cn(e,t,r){r===401&&t.kind==="box_token"&&e.auth?.invalidateToken()}L();import{randomBytes as lne}from"node:crypto";import{existsSync as cne,rmSync as une}from"node:fs";import{appendFileSync as Zre,chmodSync as ene,existsSync as HL,mkdirSync as tne,readFileSync as jL,renameSync as rne,statSync as nne,writeFileSync as one}from"node:fs";import sne from"node:path";import{createHash as jre,randomBytes as WL}from"node:crypto";import{chmodSync as UL,existsSync as Vre,mkdirSync as Gre,readFileSync as Jre,renameSync as Yre,rmSync as qre,writeFileSync as zre}from"node:fs";import{homedir as Xre}from"node:os";import FL from"node:path";var $re=/^(localhost|.*\.localhost|.*\.local|.*\.internal|0\.0\.0\.0|\[.*\]|\d{1,3}(\.\d{1,3}){3})$/i,Wre=/^(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})$/;function DL(e,t={}){if(typeof e!="string"||!e.trim())return{ok:!1,reason:"a site address is required"};let r=e.trim();/^[a-z][a-z0-9+.-]*:/i.test(r)||(r=`https://${r}`);let n;try{n=new URL(r)}catch{return{ok:!1,reason:"not a valid web address"}}return n.protocol!=="https:"?{ok:!1,reason:"saved logins are only used on https:// sites"}:n.username||n.password?{ok:!1,reason:"the address must not contain a username or password"}:t.allowLan===!0&&Wre.test(n.hostname)&&n.hostname.split(".").every(s=>Number(s)<=255)?{ok:!0,origin:n.origin,unicodeHost:!1}:!n.hostname.includes(".")||$re.test(n.hostname)?{ok:!1,reason:"use the site's public address (e.g. https://www.instagram.com)"}:{ok:!0,origin:n.origin,unicodeHost:n.hostname.split(".").some(s=>s.startsWith("xn--"))}}function Xc(e){if(typeof e!="string"||!e)return null;try{let t=new URL(e).origin;return t&&t!=="null"?t:null}catch{return null}}function sw(e,t){let r=Xc(t);return r!==null&&r===e}import{createHmac as Fre}from"node:crypto";var Kre="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function ML(e){let t=e.replace(/[\s-]/g,"").replace(/=+$/,"").toUpperCase();if(!t||!/^[A-Z2-7]+$/.test(t))return null;let r=0,n=0,o=[];for(let s of t)n=n<<5|Kre.indexOf(s),r+=5,r>=8&&(o.push(n>>>r-8&255),r-=8);return o.length?Buffer.from(o):null}function If(e){let t=e.trim();if(!t)return null;if(/^otpauth:\/\//i.test(t)){let n;try{n=new URL(t)}catch{return null}if(n.host.toLowerCase()!=="totp")return null;let o=ML(n.searchParams.get("secret")??"");if(!o)return null;let s=(n.searchParams.get("algorithm")??"SHA1").toUpperCase(),i=Number(n.searchParams.get("digits")??"6"),a=Number(n.searchParams.get("period")??"30");return s!=="SHA1"&&s!=="SHA256"&&s!=="SHA512"||i!==6&&i!==7&&i!==8||!Number.isInteger(a)||a<10||a>300?null:{key:o,algorithm:s,digits:i,period:a}}let r=ML(t);return r?{key:r,algorithm:"SHA1",digits:6,period:30}:null}function Hre(e,t,r,n){let o=Buffer.alloc(8);o.writeBigUInt64BE(t);let s=Fre(n.toLowerCase(),e).update(o).digest(),i=s[s.length-1]&15,a=(s[i]&127)<<24|s[i+1]<<16|s[i+2]<<8|s[i+3];return String(a%10**r).padStart(r,"0")}function LL(e,t=Date.now()){let r=BigInt(Math.floor(t/1e3/e.period));return Hre(e.key,r,e.digits,e.algorithm)}function BL(e,t=Date.now()){let r=Math.floor(t/1e3)%e.period;return e.period-r}var Ur={maxRecords:200,maxLabel:80,maxUsername:254,maxPassword:1024,maxTotp:512};function Qc(){return FL.join(Xre(),".kynver","site-logins")}function iw(e){return`${jre("sha256").update(`kynver-site-login:${e}`).digest("hex").slice(0,32)}.vault.json`}var Y=class extends Error{constructor(r,n){super(r);this.code=n;this.name="SiteLoginError"}code},KL=/[\u0000-\u001f\u007f]/;function $L(e,t,r,n=!0){let o=typeof e=="string"?e.trim():"";if(!o&&n)throw new Y(`${t} is required`,"invalid");if(o.length>r)throw new Y(`${t} is too long (max ${r})`,"invalid");if(KL.test(o))throw new Y(`${t} contains control characters`,"invalid");return o}var Of=class{constructor(t){this.opts=t;let r=t.agentOsId.trim();if(!r||KL.test(r)||r.length>200)throw new Y("invalid workspace id","invalid");this.agentOsId=r,this.rootDir=t.rootDir??Qc(),this.filePath=FL.join(this.rootDir,iw(r)),this.now=t.now??Date.now}opts;agentOsId;filePath;rootDir;now;exists(){return Vre(this.filePath)}keyMode(){return this.exists()?this.read().keyMode:null}async createWithPassphrase(t){if(this.exists())throw new Y("a saved-login vault already exists on this computer","exists");if(t.length<Sc)throw new Y(`the vault passphrase must be at least ${Sc} characters`,"invalid");let r=eN(),n=tN(this.opts.scryptCost),o=await Db(t,n,this.opts.minScryptN);return this.write({v:1,agentOsId:this.agentOsId,keyMode:"passphrase",kdf:n,wrappedKey:ao(o,r,Lb(this.agentOsId)),keyCheck:ao(r,Mm,Dm(this.agentOsId)),records:[]}),o.fill(0),r}createWithKeychainKey(t){if(this.exists())throw new Y("a saved-login vault already exists on this computer","exists");this.write({v:1,agentOsId:this.agentOsId,keyMode:"keychain",keyCheck:ao(t,Mm,Dm(this.agentOsId)),records:[]})}async unlockWithPassphrase(t){let r=this.read();if(r.keyMode!=="passphrase"||!r.kdf||!r.wrappedKey)throw new Y("this vault is unlocked by the Kynver desktop app, not a passphrase","invalid");let n=null;try{n=await Db(t,r.kdf,this.opts.minScryptN);let o=hs(n,r.wrappedKey,Lb(this.agentOsId));return this.verifyKey(r,o),o}catch(o){throw o instanceof Y?o:o instanceof ir&&/unsafe|salt/.test(o.message)?new Y(o.message,"corrupt"):new Y("wrong vault passphrase","bad_key")}finally{n?.fill(0)}}unlockWithKey(t){return this.verifyKey(this.read(),t),t}wipe(){return this.exists()?(qre(this.filePath,{force:!0}),!0):!1}list(){return this.exists()?this.read().records.map(({secret:t,...r})=>r):[]}get(t){return this.list().find(r=>r.handle===t)??null}add(t,r){let n=this.read();if(this.verifyKey(n,t),n.records.length>=Ur.maxRecords)throw new Y(`at most ${Ur.maxRecords} saved logins per workspace`,"full");let o=this.buildRecord(t,r,Qre(),new Date(this.now()).toISOString());n.records.push(o),this.write(n);let{secret:s,...i}=o;return i}replace(t,r,n){let o=this.read();this.verifyKey(o,t);let s=o.records.findIndex(c=>c.handle===r);if(s<0)throw new Y("no saved login with that id","not_found");let i=this.buildRecord(t,n,r,o.records[s].createdAt);o.records[s]=i,this.write(o);let{secret:a,...l}=i;return l}remove(t){if(!this.exists())return!1;let r=this.read(),n=r.records.filter(o=>o.handle!==t);return n.length===r.records.length?!1:(r.records=n,this.write(r),!0)}readSecret(t,r){let n=this.read();this.verifyKey(n,t);let o=n.records.find(i=>i.handle===r);if(!o)throw new Y("no saved login with that id","not_found");let s;try{s=hs(t,o.secret,Bb({agentOsId:this.agentOsId,...o}))}catch{throw new Y("this saved login failed its integrity check and was not used","corrupt")}try{let i=JSON.parse(s.toString("utf8"));if(typeof i.p!="string")throw new Error("shape");let{secret:a,...l}=o;return{summary:l,secret:{password:i.p,...typeof i.t=="string"?{totp:i.t}:{}}}}catch{throw new Y("this saved login failed its integrity check and was not used","corrupt")}finally{s.fill(0)}}touch(t){let r=this.read(),n=r.records.find(o=>o.handle===t);n&&(n.lastUsedAt=new Date(this.now()).toISOString(),this.write(r))}buildRecord(t,r,n,o){let s=DL(r.origin,{allowLan:r.allowLan===!0});if(!s.ok)throw new Y(s.reason,"invalid");let i=$L(r.label,"label",Ur.maxLabel),a=$L(r.username,"username",Ur.maxUsername),l=typeof r.password=="string"?r.password:"";if(!l)throw new Y("password is required","invalid");if(l.length>Ur.maxPassword)throw new Y("password is too long","invalid");let c=typeof r.totp=="string"&&r.totp.trim()?r.totp.trim():void 0;if(c&&(c.length>Ur.maxTotp||!If(c)))throw new Y("the authenticator key is not a valid base32 secret or otpauth://totp link","invalid");let u={handle:n,origin:s.origin,label:i,username:a,hasTotp:!!c,createdAt:o,lastUsedAt:null},d=Buffer.from(JSON.stringify(c?{p:l,t:c}:{p:l}),"utf8");try{return{...u,secret:ao(t,d,Bb({agentOsId:this.agentOsId,...u}))}}finally{d.fill(0)}}verifyKey(t,r){try{let n=hs(r,t.keyCheck,Dm(this.agentOsId));if(!rN(n,Mm))throw new Error("mismatch")}catch{throw new Y("the vault key does not open this vault","bad_key")}}read(){if(!this.exists())throw new Y("no saved-login vault on this computer yet","missing");let t;try{t=JSON.parse(Jre(this.filePath,"utf8"))}catch{throw new Y("the saved-login vault file is unreadable","corrupt")}if(!t||t.v!==1||t.keyMode!=="passphrase"&&t.keyMode!=="keychain"||!t.keyCheck||!Array.isArray(t.records))throw new Y("the saved-login vault file is not a vault Kynver understands","corrupt");if(t.agentOsId!==this.agentOsId)throw new Y("this saved-login vault belongs to a different workspace","corrupt");return t.records=t.records.filter(r=>r&&typeof r.handle=="string"&&typeof r.origin=="string"&&typeof r.label=="string"&&typeof r.username=="string"&&r.secret&&typeof r.secret.n=="string"&&typeof r.secret.c=="string"),t}write(t){Gre(this.rootDir,{recursive:!0,mode:448});try{UL(this.rootDir,448)}catch{}let r=`${this.filePath}.${WL(4).toString("hex")}.tmp`;zre(r,`${JSON.stringify(t)}
214
+ _${r.length===1?"A file":`${r.length} files`} couldn't be attached: ${r.join(", ")}._`),n.length>OL?`${n.slice(0,OL-1)}\u2026`:n}var Ure=ha;function NL(e){let t=e.fetchFn??fetch,r=e.wait??Mre,n=e.redactText??(c=>Cc(e.agentOsId,c)),o=c=>{let u=$m(e.agentOsId,c),d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(u)}catch{return u}if(d.includes("\0"))return u;let p=n(d);return p===d?u:Buffer.from(p,"utf8")},s=Lre(e),i=new URL(e.apiBaseUrl).origin,a=async(c,u)=>{let p={Authorization:`Bearer ${await e.bearer()}`},m=u.body;u.json!==void 0&&(p["Content-Type"]="application/json",m=JSON.stringify(u.json));let f=await t(c,{method:u.method??"POST",headers:p,body:m});return f.status===401&&e.onUnauthorized?.(),f},l=async c=>{try{let u=o(Buffer.from(c.contentBase64,"base64")),d=Ore("sha256").update(u).digest("hex"),p=await a(`${s}/uploads`,{json:{name:n(c.name).slice(0,200),size:u.length,sha256:d}});if(!p.ok)return null;let m=await p.json();for(let y=0;y<m.parts;y++){let k=u.subarray(y*m.partBytes,(y+1)*m.partBytes),h=new URL(m.partUrl.replace("{index}",String(y)),i).toString(),b=!1;for(let w=0;w<3&&!b;w++)b=!!(await t(h,{method:"PUT",body:new Uint8Array(k)}).catch(()=>null))?.ok,b||await r(1e3*(w+1));if(!b)return null}let f=await a(new URL(m.completeUrl,i).toString(),{method:"POST"});if(!f.ok)return null;let g=await f.json();return typeof g.file?.id=="string"?g.file.id:null}catch{return null}};return{async heartbeat(c){try{let u=await a(`${s}/turns/${encodeURIComponent(c)}/heartbeat`,{json:{}});if(u.status!==404&&u.status!==410)return"continue";let d=await u.json().catch(()=>null);return d?.code==="turn_stopped"?"stop":u.status===404&&d?.code==="turn_unknown"?"continue":"gone"}catch{return"continue"}},async deliver({replyTurnId:c,engine:u,text:d,files:p}){let m=[],f=[],g=0;for(let k of p.slice(0,Dre)){let h=k.sizeBytes??Math.floor(k.contentBase64.length*3/4),b=n(k.name).slice(0,200);if(h<=Tre&&g+h<=Nre){let S=o(Buffer.from(k.contentBase64,"base64"));g+=S.length,m.push({name:b,contentBase64:S.toString("base64")});continue}let w=await l(k);w?m.push({fileId:w}):f.push(b.slice(0,80))}let y={engine:u,idempotencyKey:`turn-reply:${c}`,turnId:c,text:Bre(n(d),Ure[u],f),attachments:m,notify:!0};for(let k=0;;k++){let h=0;try{let w=await a(`${s}/posts`,{json:y});if(h=w.status,w.ok)return!0}catch{h=0}if(!(h===0||h===401||h===408||h===429||h>=500)||k>=TL.length)return!1;await r(TL[k])}}}}async function ya(e){if(e.auth){let t=await e.auth.authorization();if(t)return{bearer:t.bearer,kind:t.kind,boxId:t.boxId??e.boxId}}return{bearer:e.apiKey,kind:"api_key",boxId:e.boxId}}function Cn(e,t,r){r===401&&t.kind==="box_token"&&e.auth?.invalidateToken()}L();import{randomBytes as lne}from"node:crypto";import{existsSync as cne,rmSync as une}from"node:fs";import{appendFileSync as Zre,chmodSync as ene,existsSync as HL,mkdirSync as tne,readFileSync as jL,renameSync as rne,statSync as nne,writeFileSync as one}from"node:fs";import sne from"node:path";import{createHash as jre,randomBytes as WL}from"node:crypto";import{chmodSync as UL,existsSync as Vre,mkdirSync as Gre,readFileSync as Jre,renameSync as Yre,rmSync as qre,writeFileSync as zre}from"node:fs";import{homedir as Xre}from"node:os";import FL from"node:path";var $re=/^(localhost|.*\.localhost|.*\.local|.*\.internal|0\.0\.0\.0|\[.*\]|\d{1,3}(\.\d{1,3}){3})$/i,Wre=/^(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})$/;function DL(e,t={}){if(typeof e!="string"||!e.trim())return{ok:!1,reason:"a site address is required"};let r=e.trim();/^[a-z][a-z0-9+.-]*:/i.test(r)||(r=`https://${r}`);let n;try{n=new URL(r)}catch{return{ok:!1,reason:"not a valid web address"}}return n.protocol!=="https:"?{ok:!1,reason:"saved logins are only used on https:// sites"}:n.username||n.password?{ok:!1,reason:"the address must not contain a username or password"}:t.allowLan===!0&&Wre.test(n.hostname)&&n.hostname.split(".").every(s=>Number(s)<=255)?{ok:!0,origin:n.origin,unicodeHost:!1}:!n.hostname.includes(".")||$re.test(n.hostname)?{ok:!1,reason:"use the site's public address (e.g. https://www.instagram.com)"}:{ok:!0,origin:n.origin,unicodeHost:n.hostname.split(".").some(s=>s.startsWith("xn--"))}}function Xc(e){if(typeof e!="string"||!e)return null;try{let t=new URL(e).origin;return t&&t!=="null"?t:null}catch{return null}}function sw(e,t){let r=Xc(t);return r!==null&&r===e}import{createHmac as Fre}from"node:crypto";var Kre="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function ML(e){let t=e.replace(/[\s-]/g,"").replace(/=+$/,"").toUpperCase();if(!t||!/^[A-Z2-7]+$/.test(t))return null;let r=0,n=0,o=[];for(let s of t)n=n<<5|Kre.indexOf(s),r+=5,r>=8&&(o.push(n>>>r-8&255),r-=8);return o.length?Buffer.from(o):null}function If(e){let t=e.trim();if(!t)return null;if(/^otpauth:\/\//i.test(t)){let n;try{n=new URL(t)}catch{return null}if(n.host.toLowerCase()!=="totp")return null;let o=ML(n.searchParams.get("secret")??"");if(!o)return null;let s=(n.searchParams.get("algorithm")??"SHA1").toUpperCase(),i=Number(n.searchParams.get("digits")??"6"),a=Number(n.searchParams.get("period")??"30");return s!=="SHA1"&&s!=="SHA256"&&s!=="SHA512"||i!==6&&i!==7&&i!==8||!Number.isInteger(a)||a<10||a>300?null:{key:o,algorithm:s,digits:i,period:a}}let r=ML(t);return r?{key:r,algorithm:"SHA1",digits:6,period:30}:null}function Hre(e,t,r,n){let o=Buffer.alloc(8);o.writeBigUInt64BE(t);let s=Fre(n.toLowerCase(),e).update(o).digest(),i=s[s.length-1]&15,a=(s[i]&127)<<24|s[i+1]<<16|s[i+2]<<8|s[i+3];return String(a%10**r).padStart(r,"0")}function LL(e,t=Date.now()){let r=BigInt(Math.floor(t/1e3/e.period));return Hre(e.key,r,e.digits,e.algorithm)}function BL(e,t=Date.now()){let r=Math.floor(t/1e3)%e.period;return e.period-r}var Ur={maxRecords:200,maxLabel:80,maxUsername:254,maxPassword:1024,maxTotp:512};function Qc(){return FL.join(Xre(),".kynver","site-logins")}function iw(e){return`${jre("sha256").update(`kynver-site-login:${e}`).digest("hex").slice(0,32)}.vault.json`}var Y=class extends Error{constructor(r,n){super(r);this.code=n;this.name="SiteLoginError"}code},KL=/[\u0000-\u001f\u007f]/;function $L(e,t,r,n=!0){let o=typeof e=="string"?e.trim():"";if(!o&&n)throw new Y(`${t} is required`,"invalid");if(o.length>r)throw new Y(`${t} is too long (max ${r})`,"invalid");if(KL.test(o))throw new Y(`${t} contains control characters`,"invalid");return o}var Of=class{constructor(t){this.opts=t;let r=t.agentOsId.trim();if(!r||KL.test(r)||r.length>200)throw new Y("invalid workspace id","invalid");this.agentOsId=r,this.rootDir=t.rootDir??Qc(),this.filePath=FL.join(this.rootDir,iw(r)),this.now=t.now??Date.now}opts;agentOsId;filePath;rootDir;now;exists(){return Vre(this.filePath)}keyMode(){return this.exists()?this.read().keyMode:null}async createWithPassphrase(t){if(this.exists())throw new Y("a saved-login vault already exists on this computer","exists");if(t.length<Sc)throw new Y(`the vault passphrase must be at least ${Sc} characters`,"invalid");let r=eN(),n=tN(this.opts.scryptCost),o=await Db(t,n,this.opts.minScryptN);return this.write({v:1,agentOsId:this.agentOsId,keyMode:"passphrase",kdf:n,wrappedKey:ao(o,r,Lb(this.agentOsId)),keyCheck:ao(r,Mm,Dm(this.agentOsId)),records:[]}),o.fill(0),r}createWithKeychainKey(t){if(this.exists())throw new Y("a saved-login vault already exists on this computer","exists");this.write({v:1,agentOsId:this.agentOsId,keyMode:"keychain",keyCheck:ao(t,Mm,Dm(this.agentOsId)),records:[]})}async unlockWithPassphrase(t){let r=this.read();if(r.keyMode!=="passphrase"||!r.kdf||!r.wrappedKey)throw new Y("this vault is unlocked by the Kynver desktop app, not a passphrase","invalid");let n=null;try{n=await Db(t,r.kdf,this.opts.minScryptN);let o=hs(n,r.wrappedKey,Lb(this.agentOsId));return this.verifyKey(r,o),o}catch(o){throw o instanceof Y?o:o instanceof ir&&/unsafe|salt/.test(o.message)?new Y(o.message,"corrupt"):new Y("wrong vault passphrase","bad_key")}finally{n?.fill(0)}}unlockWithKey(t){return this.verifyKey(this.read(),t),t}wipe(){return this.exists()?(qre(this.filePath,{force:!0}),!0):!1}list(){return this.exists()?this.read().records.map(({secret:t,...r})=>r):[]}get(t){return this.list().find(r=>r.handle===t)??null}add(t,r){let n=this.read();if(this.verifyKey(n,t),n.records.length>=Ur.maxRecords)throw new Y(`at most ${Ur.maxRecords} saved logins per workspace`,"full");let o=this.buildRecord(t,r,Qre(),new Date(this.now()).toISOString());n.records.push(o),this.write(n);let{secret:s,...i}=o;return i}replace(t,r,n){let o=this.read();this.verifyKey(o,t);let s=o.records.findIndex(c=>c.handle===r);if(s<0)throw new Y("no saved login with that id","not_found");let i=this.buildRecord(t,n,r,o.records[s].createdAt);o.records[s]=i,this.write(o);let{secret:a,...l}=i;return l}remove(t){if(!this.exists())return!1;let r=this.read(),n=r.records.filter(o=>o.handle!==t);return n.length===r.records.length?!1:(r.records=n,this.write(r),!0)}readSecret(t,r){let n=this.read();this.verifyKey(n,t);let o=n.records.find(i=>i.handle===r);if(!o)throw new Y("no saved login with that id","not_found");let s;try{s=hs(t,o.secret,Bb({agentOsId:this.agentOsId,...o}))}catch{throw new Y("this saved login failed its integrity check and was not used","corrupt")}try{let i=JSON.parse(s.toString("utf8"));if(typeof i.p!="string")throw new Error("shape");let{secret:a,...l}=o;return{summary:l,secret:{password:i.p,...typeof i.t=="string"?{totp:i.t}:{}}}}catch{throw new Y("this saved login failed its integrity check and was not used","corrupt")}finally{s.fill(0)}}touch(t){let r=this.read(),n=r.records.find(o=>o.handle===t);n&&(n.lastUsedAt=new Date(this.now()).toISOString(),this.write(r))}buildRecord(t,r,n,o){let s=DL(r.origin,{allowLan:r.allowLan===!0});if(!s.ok)throw new Y(s.reason,"invalid");let i=$L(r.label,"label",Ur.maxLabel),a=$L(r.username,"username",Ur.maxUsername),l=typeof r.password=="string"?r.password:"";if(!l)throw new Y("password is required","invalid");if(l.length>Ur.maxPassword)throw new Y("password is too long","invalid");let c=typeof r.totp=="string"&&r.totp.trim()?r.totp.trim():void 0;if(c&&(c.length>Ur.maxTotp||!If(c)))throw new Y("the authenticator key is not a valid base32 secret or otpauth://totp link","invalid");let u={handle:n,origin:s.origin,label:i,username:a,hasTotp:!!c,createdAt:o,lastUsedAt:null},d=Buffer.from(JSON.stringify(c?{p:l,t:c}:{p:l}),"utf8");try{return{...u,secret:ao(t,d,Bb({agentOsId:this.agentOsId,...u}))}}finally{d.fill(0)}}verifyKey(t,r){try{let n=hs(r,t.keyCheck,Dm(this.agentOsId));if(!rN(n,Mm))throw new Error("mismatch")}catch{throw new Y("the vault key does not open this vault","bad_key")}}read(){if(!this.exists())throw new Y("no saved-login vault on this computer yet","missing");let t;try{t=JSON.parse(Jre(this.filePath,"utf8"))}catch{throw new Y("the saved-login vault file is unreadable","corrupt")}if(!t||t.v!==1||t.keyMode!=="passphrase"&&t.keyMode!=="keychain"||!t.keyCheck||!Array.isArray(t.records))throw new Y("the saved-login vault file is not a vault Kynver understands","corrupt");if(t.agentOsId!==this.agentOsId)throw new Y("this saved-login vault belongs to a different workspace","corrupt");return t.records=t.records.filter(r=>r&&typeof r.handle=="string"&&typeof r.origin=="string"&&typeof r.label=="string"&&typeof r.username=="string"&&r.secret&&typeof r.secret.n=="string"&&typeof r.secret.c=="string"),t}write(t){Gre(this.rootDir,{recursive:!0,mode:448});try{UL(this.rootDir,448)}catch{}let r=`${this.filePath}.${WL(4).toString("hex")}.tmp`;zre(r,`${JSON.stringify(t)}
215
215
  `,{mode:384}),Yre(r,this.filePath);try{UL(this.filePath,384)}catch{}}};function Qre(){let e="abcdefghijkmnpqrstuvwxyz23456789",t=WL(10);return`lg_${Array.from(t,r=>e[r%e.length]).join("")}`}var ine=512*1024,VL=1e3,ane=10080*60*1e3,Tf=class{constructor(t,r=Qc(),n=Date.now){this.rootDir=r;this.now=n;this.filePath=sne.join(r,iw(t).replace(/\.vault\.json$/,".audit.jsonl"))}rootDir;now;filePath;record(t){let r={at:new Date(this.now()).toISOString(),...t};try{tne(this.rootDir,{recursive:!0,mode:448}),this.rotateIfLarge(),Zre(this.filePath,`${JSON.stringify(r)}
216
216
  `,{mode:384}),ene(this.filePath,384)}catch{}return r}entries(t=VL){if(!HL(this.filePath))return[];try{return jL(this.filePath,"utf8").split(`
217
217
  `).filter(Boolean).slice(-t).map(n=>{try{return JSON.parse(n)}catch{return null}}).filter(n=>n!==null)}catch{return[]}}lastFill(){let t=this.entries().filter(r=>r.event==="fill");return t[t.length-1]??null}originRefusalsSince(t=ane){let r=this.now()-t;return this.entries().filter(n=>n.event==="fill"&&n.code==="origin_mismatch"&&Date.parse(n.at)>=r).length}rotateIfLarge(){if(!HL(this.filePath)||nne(this.filePath).size<ine)return;let t=jL(this.filePath,"utf8").split(`
@@ -198,7 +198,7 @@ ${e.stderr}`.toLowerCase();return t.includes("api rate limit exceeded")||t.inclu
198
198
  `,{mode:384})}catch{}}function oQ(e,t){return e?e.access===t.access&&e.source===t.source&&e.folders.length===t.folders.length&&e.folders.every((r,n)=>r===t.folders[n]):!1}function GM(e,t={signed:!1}){let r=t.file??Wb(),n=t.now??(()=>new Date),o={access:e.access,folders:[...e.folders],source:e.source,signed:t.signed,at:n().toISOString()},s=Vp(r);return oQ(s.applied,o)?null:(VM(r,{applied:o,website:s.website}),{from:s.applied,to:o})}function JM(e,t={}){let r=t.file??Wb(),n=t.now??(()=>new Date),o=Vp(r),s={access:e.access,folders:[...e.folders],changedAt:e.changedAt,nonce:e.nonce,at:n().toISOString()},i=o.website;return i&&i.access===s.access&&i.changedAt===s.changedAt&&i.nonce===s.nonce&&i.folders.length===s.folders.length&&i.folders.every((l,c)=>l===s.folders[c])?i:(VM(r,{applied:o.applied,website:s}),s)}function fi(e){switch(e){case"off":return"off";case"folder":return"one folder";case"folders":return"chosen folders";case"full":return"full computer";default:return String(e)}}var tQ,Kb=p(()=>{"use strict";tQ=Fb.join(".kynver","chat-access-state.json")});import{appendFileSync as sQ,mkdirSync as iQ}from"node:fs";import{homedir as aQ}from"node:os";import $b from"node:path";function Hb(e=aQ()){return $b.join(e,lQ)}function jb(e){let t=r=>r===void 0?void 0:r.length>qM?`${r.slice(0,qM)}\u2026`:r;return{...e,...e.command!==void 0?{command:t(e.command)}:{},...e.path!==void 0?{path:t(e.path)}:{}}}function mi(e,t=Hb()){try{return iQ($b.dirname(t),{recursive:!0}),sQ(t,`${JSON.stringify(jb(e))}
199
199
  `,{encoding:"utf8",mode:384}),!0}catch(r){return console.error(JSON.stringify({event:"chat_command_log_write_failed",error:r instanceof Error?r.message:String(r)})),!1}}var lQ,qM,Cl=p(()=>{"use strict";lQ=$b.join(".kynver","logs","chat-commands.jsonl"),qM=2e3});function cQ(e){let r=e.chatProvider?.trim()||e.workerProvider?.trim()||"";return Xe(r)}function Io(e,t=process.env){return cQ(e)!=="gemini"?"http":Ws(_t(t))==="antigravity"?"antigravity":"http"}var Gp=p(()=>{"use strict";ho();ia()});import{execFile as uQ,spawnSync as QM}from"node:child_process";import{existsSync as dQ,readFileSync as pQ}from"node:fs";import{homedir as fQ,platform as mQ}from"node:os";import YM from"node:path";function Yp(e,t,r=process.env){return e==="cursor"?"cursor":e==="codex"?"codex":e==="gemini"?Io(t,r)==="antigravity"?"antigravity":"none":e==="anthropic"?"claude-code":"none"}function gQ(e,t){return e==="cursor"?co(t):e==="codex"?t.KYNVER_CODEX_BIN?.trim()||t.CODEX_BIN?.trim()||Ur():e==="antigravity"?_t(t):e==="claude-code"?t.KYNVER_CLAUDE_BIN?.trim()||t.CLAUDE_BIN?.trim()||"claude":null}function zM(e,t,r){let n=`${t??""} ${r??""}`;return e===0?n.match(hQ)?.[0]??null:null}function zp(e,t=process.env,r=Date.now()){let n=gQ(e,t);if(!n)return null;let o=Jp.get(n);if(o&&r-o.at<ZM)return o.version;if(o){if(!qp.has(n)){qp.add(n);try{let[i,a]=se(n,["--version"]);uQ(i,a,Z({encoding:"utf8",timeout:5e3}),(l,c,u)=>{qp.delete(n),Jp.set(n,{at:Date.now(),version:l?null:zM(0,c,u)})})}catch{qp.delete(n),Jp.set(n,{at:r,version:o.version})}}return o.version}let s=null;try{let[i,a]=se(n,["--version"]),l=QM(i,a,Z({encoding:"utf8",timeout:5e3}));s=zM(l.status,l.stdout,l.stderr)}catch{s=null}return Jp.set(n,{at:r,version:s}),s}function Xp(e=process.env,t={}){if(e.ANTHROPIC_API_KEY?.trim())return!0;let r=t.home??fQ(),n=t.now??Date.now(),o=XM.get(r);if(o&&n-o.at<ZM)return o.signedIn;let s=yQ(YM.join(e.CLAUDE_CONFIG_DIR?.trim()||YM.join(r,".claude"),".credentials.json"));return!s&&(t.os??mQ())==="darwin"&&(s=(t.keychain??kQ)()),XM.set(r,{at:n,signedIn:s}),s}function yQ(e){if(!dQ(e))return!1;try{let t=JSON.parse(pQ(e,"utf8")).claudeAiOauth,r=n=>typeof n=="string"&&n.length>0;return!!t&&(r(t.refreshToken)||r(t.accessToken))}catch{return!1}}function kQ(){try{return QM("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore",timeout:5e3}).status===0}catch{return!1}}var hQ,ZM,Jp,qp,XM,El=p(()=>{"use strict";fo();Ls();ho();We();U();Gp();hQ=/\d+\.\d+(?:\.\d+)?(?:[-+][\w.]+)?/,ZM=10*6e4,Jp=new Map,qp=new Set;XM=new Map});import{createHash as bQ,verify as vQ,createPublicKey as RQ}from"node:crypto";function Gb(e){if(!e||typeof e!="object"||Array.isArray(e))return e;let t={...e};return delete t[eL],t}function SQ(e){return bQ("sha256").update(dt(Gb(e)),"utf8").digest("hex")}function Jb(e){return!e||typeof e!="object"||Array.isArray(e)?null:e[eL]??null}function _Q(e){if(!e||typeof e!="object")return!1;let t=e;if(typeof t.signature!="string"||!t.signature||typeof t.publicKeyId!="string"||!t.publicKeyId)return!1;let r=t.payload;return!(!r||typeof r!="object"||r.v!==1||r.kind!=="chat-turn"||typeof r.turnId!="string"||!r.turnId||typeof r.agentOsId!="string"||!r.agentOsId||r.userId!==null&&(typeof r.userId!="string"||!r.userId)||r.boxId!==null&&typeof r.boxId!="string"||r.access!==null&&(!r.access||typeof r.access!="object"||Array.isArray(r.access))||typeof r.payloadHash!="string"||!/^[0-9a-f]{64}$/.test(r.payloadHash)||typeof r.exp!="number"||!Number.isFinite(r.exp)||typeof r.nonce!="string"||!r.nonce)}function xQ(e,t){let r=e&&typeof e=="object"&&!Array.isArray(e)?e.computerAccess??null:null;return r===null&&t===null?!0:r===null||t===null?!1:dt(r)===dt(t)}function Vb(e,t){return{state:t,firstSeenAt:new Date(e.firstSeenSec*1e3).toISOString(),turnId:e.turnId}}function CQ(e){return RQ({key:Buffer.concat([wQ,Buffer.from(e)]),format:"der",type:"spki"})}function tL(e,t,r={}){let n=r.env??process.env,o=r.nowSec??Math.floor(Date.now()/1e3),s=Jb(e);if(s===null)return{ok:!1,code:"unsigned",reason:"turn carries no signed envelope"};if(!_Q(s))return{ok:!1,code:"malformed",reason:"malformed chat-turn envelope"};let i=s;if(i.payload.agentOsId!==t.agentOsId)return{ok:!1,code:"agent_os_mismatch",reason:"envelope is for another workspace"};if(i.payload.turnId!==t.turnId)return{ok:!1,code:"turn_id_mismatch",reason:"envelope is for another turn"};if(i.payload.exp<=o)return{ok:!1,code:"expired",reason:"envelope expired"};let a=eo(i.publicKeyId,n);if(!a)return{ok:!1,code:"no_verification_key",reason:`no verification key for publicKeyId "${i.publicKeyId}"`};let l;try{l=Buffer.from(i.signature,"base64url")}catch{return{ok:!1,code:"bad_signature",reason:"signature is not base64url"}}if(l.length!==64)return{ok:!1,code:"bad_signature",reason:"signature is not a 64-byte Ed25519 signature"};let c=!1;try{let d=Buffer.from(dt(i.payload),"utf8");c=vQ(null,d,CQ(a),l)}catch(d){return{ok:!1,code:"bad_signature",reason:`signature verification failed: ${d.message}`}}if(!c)return{ok:!1,code:"bad_signature",reason:"Ed25519 signature mismatch"};if(SQ(e)!==i.payload.payloadHash)return{ok:!1,code:"payload_tampered",reason:"turn payload does not match its signed hash"};if(!xQ(e,i.payload.access))return{ok:!1,code:"access_mismatch",reason:"computer access on the turn differs from the signed setting"};if(!r.nonces)return{ok:!0,payload:i.payload,redelivered:!1};let u=r.nonces.consume({nonce:i.payload.nonce,turnId:i.payload.turnId,expSec:i.payload.exp,nowSec:o});return u.ok?{ok:!0,payload:i.payload,redelivered:u.redelivered}:{ok:!1,code:"replayed",reason:`envelope nonce already used on this computer (${EQ(u.replay)})`,replay:u.replay}}function EQ(e){return`${e.state==="in_flight"?"this computer is running that turn now":e.state==="already_ran"?"that turn already ran here":`the nonce belongs to turn ${e.turnId}`}; first seen ${e.firstSeenAt}`}var eL,wQ,Qp,Zp=p(()=>{"use strict";an();pa();eL="turnEnvelope",wQ=Buffer.from("302a300506032b6570032100","hex");Qp=class{constructor(t=1e4){this.maxEntries=t}maxEntries;byNonce=new Map;byTurn=new Map;consume(t){let r=t.nowSec??Math.floor(Date.now()/1e3);this.purge(r);let n=this.byNonce.get(t.nonce);if(n)return n.turnId!==t.turnId?{ok:!1,replay:Vb(n,"turn_mismatch")}:n.state==="verified"?{ok:!0,redelivered:!0}:{ok:!1,replay:Vb(n,n.state==="started"?"in_flight":"already_ran")};let o=this.byTurn.get(t.turnId);if(o){if(o.state!=="verified")return{ok:!1,replay:Vb(o,o.state==="started"?"in_flight":"already_ran")};this.byNonce.delete(o.nonce);let i={...o,nonce:t.nonce,untilSec:Math.max(o.untilSec,t.expSec+60)};return this.byNonce.set(t.nonce,i),this.byTurn.set(t.turnId,i),{ok:!0,redelivered:!0}}if(this.byNonce.size>=this.maxEntries){let i=this.byNonce.values().next().value;i&&this.forget(i)}let s={nonce:t.nonce,turnId:t.turnId,firstSeenSec:r,state:"verified",untilSec:t.expSec+60};return this.byNonce.set(t.nonce,s),this.byTurn.set(t.turnId,s),{ok:!0,redelivered:!1}}markStarted(t){let r=this.byTurn.get(t);return r?(r.state==="verified"&&(r.state="started"),!0):!1}markFinished(t){let r=this.byTurn.get(t);return r?(r.state="finished",!0):!1}stateOf(t){return this.byTurn.get(t)?.state??null}purge(t=Math.floor(Date.now()/1e3)){for(let r of[...this.byNonce.values()])r.untilSec<=t&&this.forget(r)}forget(t){this.byNonce.delete(t.nonce),this.byTurn.get(t.turnId)===t&&this.byTurn.delete(t.turnId)}get size(){return this.byNonce.size}}});function rL(e=process.env,t={}){let r=(e[AQ]??t.chatTurnSignature??"").toString().trim().toLowerCase();return r==="optional"||r==="off"||r==="0"||r==="false"?"optional":"required"}function nL(e,t){return t?`turn_rejected_${e}: ${t}`:`turn_rejected_${e}`}function oL(e,t){if(!(Jb(e.payload)!==null)&&t.policy==="optional"){let o=e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload.computerAccess??null:null;return{ok:!0,access:IQ(o)?o:null,signed:!1,userId:null,redelivered:!1}}let n=tL(e.payload,{agentOsId:t.agentOsId,turnId:e.turnId},{env:t.env,nowSec:t.nowSec,nonces:t.nonces});return n.ok?{ok:!0,access:n.payload.access,signed:!0,userId:n.payload.userId,redelivered:n.redelivered}:{ok:!1,code:n.code,reason:n.reason,...n.replay?{replay:n.replay}:{}}}function IQ(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e.byBox;return!!t&&typeof t=="object"&&!Array.isArray(t)}var AQ,qb=p(()=>{"use strict";Zp();AQ="KYNVER_CHAT_TURN_SIGNATURE"});function Yb(e){return typeof e=="string"&&TQ.test(e.trim())?e.trim():null}function ef(e){return`Kynver conversation id: ${e}. When work you start from this conversation later finishes, fails, needs the user or opens / merges a PR, post the update here only: \`kynver tab post --conversation ${e} "<text>"\` (or the agent_tab_post tool with this conversationId). When you create a Kynver task for it, pass originConversationId=${e} so its updates come back here too.`}function iL(e,t){let r=Yb(e);return r?{[PQ]:r,[OQ]:t}:{}}var PQ,OQ,sL,TQ,tf=p(()=>{"use strict";PQ="KYNVER_CONVERSATION",OQ="KYNVER_AGENT_TAB_ENGINE",sL="X-Kynver-Conversation",TQ=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i});function DQ(e){return typeof e=="string"&&NQ.includes(e)}function lL(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;if(t.kind!=="agent-tab"||!DQ(t.engine)||typeof t.sessionKey!="string"||!FQ.test(t.sessionKey))return null;let r=typeof t.text=="string"?t.text.slice(0,aL):"",n=[],o=0;if(Array.isArray(t.attachments))for(let c of t.attachments.slice(0,BQ)){if(!c||typeof c!="object")continue;let{name:u,mime:d,contentBase64:f}=c;if(!(typeof u!="string"||typeof f!="string")){if(o+=Math.floor(f.length*3/4),o>UQ)break;n.push({name:u.slice(0,200),mime:typeof d=="string"?d.slice(0,100):"application/octet-stream",contentBase64:f})}}let s=WQ(t.control);if(!s&&!r.trim()&&n.length===0)return null;let i=typeof t.styleNote=="string"?t.styleNote.trim().slice(0,LQ):"",a=typeof t.replyTurnId=="string"&&MQ.test(t.replyTurnId)?t.replyTurnId:null,l=Yb(t.conversationId);return{kind:"agent-tab",engine:t.engine,sessionKey:t.sessionKey,text:r,attachments:n,...t.computerAccess!==void 0?{computerAccess:t.computerAccess}:{},...i?{styleNote:i}:{},...a?{replyTurnId:a}:{},...s?{control:s}:{},...l?{conversationId:l}:{}}}function WQ(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return t.op==="stop"?{op:"stop"}:t.op==="steer"&&typeof t.text=="string"&&t.text.trim()?{op:"steer",text:t.text.slice(0,aL)}:null}var NQ,rf,MQ,aL,LQ,BQ,UQ,FQ,zb=p(()=>{"use strict";tf();NQ=["hermes","openclaw","claude-code","grok-bot"],rf={hermes:"Hermes",openclaw:"OpenClaw","claude-code":"Claude Code","grok-bot":"Grok Bot"};MQ=/^[A-Za-z0-9-]{8,64}$/,aL=32e3,LQ=4e3,BQ=5,UQ=20*1024*1024,FQ=/^[A-Za-z0-9_.:-]{8,128}$/});import{createHash as KQ}from"node:crypto";function GQ(e){return`${e.apiBaseUrl.replace(/\/$/,"")}/api/agent-os/by-id/${encodeURIComponent(e.agentOsId)}/agent-tabs/box`}function JQ(e,t,r){let n=e.trim()?e:`${t} finished without writing a reply.`;return r.length>0&&(n+=`
200
200
 
201
- _${r.length===1?"A file":`${r.length} files`} couldn't be attached: ${r.join(", ")}._`),n.length>cL?`${n.slice(0,cL-1)}\u2026`:n}function dL(e){let t=e.fetchFn??fetch,r=e.wait??VQ,n=e.redactText??(c=>dO(e.agentOsId,c)),o=c=>{let u=fO(e.agentOsId,c),d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(u)}catch{return u}if(d.includes("\0"))return u;let f=n(d);return f===d?u:Buffer.from(f,"utf8")},s=GQ(e),i=new URL(e.apiBaseUrl).origin,a=async(c,u)=>{let f={Authorization:`Bearer ${await e.bearer()}`},m=u.body;u.json!==void 0&&(f["Content-Type"]="application/json",m=JSON.stringify(u.json));let g=await t(c,{method:u.method??"POST",headers:f,body:m});return g.status===401&&e.onUnauthorized?.(),g},l=async c=>{try{let u=o(Buffer.from(c.contentBase64,"base64")),d=KQ("sha256").update(u).digest("hex"),f=await a(`${s}/uploads`,{json:{name:n(c.name).slice(0,200),size:u.length,sha256:d}});if(!f.ok)return null;let m=await f.json();for(let k=0;k<m.parts;k++){let v=u.subarray(k*m.partBytes,(k+1)*m.partBytes),y=new URL(m.partUrl.replace("{index}",String(k)),i).toString(),b=!1;for(let S=0;S<3&&!b;S++)b=!!(await t(y,{method:"PUT",body:new Uint8Array(v)}).catch(()=>null))?.ok,b||await r(1e3*(S+1));if(!b)return null}let g=await a(new URL(m.completeUrl,i).toString(),{method:"POST"});if(!g.ok)return null;let h=await g.json();return typeof h.file?.id=="string"?h.file.id:null}catch{return null}};return{async heartbeat(c){try{let u=await a(`${s}/turns/${encodeURIComponent(c)}/heartbeat`,{json:{}});return u.status!==404&&u.status!==410?"continue":(await u.json().catch(()=>null))?.code==="turn_stopped"?"stop":"gone"}catch{return"continue"}},async deliver({replyTurnId:c,engine:u,text:d,files:f}){let m=[],g=[],h=0;for(let v of f.slice(0,jQ)){let y=v.sizeBytes??Math.floor(v.contentBase64.length*3/4),b=n(v.name).slice(0,200);if(y<=$Q&&h+y<=HQ){let w=o(Buffer.from(v.contentBase64,"base64"));h+=w.length,m.push({name:b,contentBase64:w.toString("base64")});continue}let S=await l(v);S?m.push({fileId:S}):g.push(b.slice(0,80))}let k={engine:u,idempotencyKey:`turn-reply:${c}`,turnId:c,text:JQ(n(d),qQ[u],g),attachments:m,notify:!0};for(let v=0;;v++){let y=0;try{let S=await a(`${s}/posts`,{json:k});if(y=S.status,S.ok)return!0}catch{y=0}if(!(y===0||y===401||y===408||y===429||y>=500)||v>=uL.length)return!1;await r(uL[v])}}}}var cL,$Q,HQ,jQ,uL,VQ,qQ,pL=p(()=>{"use strict";jr();zb();cL=32e3,$Q=8*1024*1024,HQ=20*1024*1024,jQ=10,uL=[2e3,4e3,8e3,16e3,32e3],VQ=e=>new Promise(t=>setTimeout(t,e));qQ=rf});async function gi(e){if(e.auth){let t=await e.auth.authorization();if(t)return{bearer:t.bearer,kind:t.kind,boxId:t.boxId??e.boxId}}return{bearer:e.apiKey,kind:"api_key",boxId:e.boxId}}function qr(e,t,r){r===401&&t.kind==="box_token"&&e.auth?.invalidateToken()}var hi=p(()=>{"use strict"});import{closeSync as YQ,existsSync as zQ,fstatSync as XQ,openSync as QQ,readSync as ZQ}from"node:fs";function mL(e){if(!(typeof e!="string"||!e.trim()))return e.length>fL?`${e.slice(0,fL)}\u2026`:e}function hL(){return{lastSuccessAt:null,lastSuccessKind:null,steps24h:0,failures24h:{},recentFailures:[]}}function oZ(e,t){let r=hL(),n=[];for(let o of e){let s;try{s=JSON.parse(o)}catch{continue}let i=typeof s.at=="string"?Date.parse(s.at):Number.NaN;if(!Number.isNaN(i)&&(s.ok===!0&&(!r.lastSuccessAt||i>=Date.parse(r.lastSuccessAt))&&(r.lastSuccessAt=new Date(i).toISOString(),r.lastSuccessKind=s.kind??null),!(t-i>nZ)&&(r.steps24h+=1,s.ok===!1))){let a=typeof s.reason=="string"&&/^[a-z_]{1,40}$/.test(s.reason)?s.reason:"other";r.failures24h[a]=(r.failures24h[a]??0)+1;let l=mL(s.command),c=mL(s.path);n.push({at:new Date(i).toISOString(),kind:typeof s.kind=="string"?s.kind:null,...l?{command:l}:{},...c?{path:c}:{},...typeof s.exitCode=="number"&&Number.isFinite(s.exitCode)?{exitCode:Math.trunc(s.exitCode)}:{},reason:a})}}return r.recentFailures=n.sort((o,s)=>Date.parse(s.at)-Date.parse(o.at)).slice(0,eZ),r}function sZ(e){if(!zQ(e))return[];let t=QQ(e,"r");try{let r=XQ(t).size,n=Math.min(r,tZ),o=Buffer.alloc(n);return ZQ(t,o,0,n,r-n),o.toString("utf8").split(`
201
+ _${r.length===1?"A file":`${r.length} files`} couldn't be attached: ${r.join(", ")}._`),n.length>cL?`${n.slice(0,cL-1)}\u2026`:n}function dL(e){let t=e.fetchFn??fetch,r=e.wait??VQ,n=e.redactText??(c=>dO(e.agentOsId,c)),o=c=>{let u=fO(e.agentOsId,c),d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(u)}catch{return u}if(d.includes("\0"))return u;let f=n(d);return f===d?u:Buffer.from(f,"utf8")},s=GQ(e),i=new URL(e.apiBaseUrl).origin,a=async(c,u)=>{let f={Authorization:`Bearer ${await e.bearer()}`},m=u.body;u.json!==void 0&&(f["Content-Type"]="application/json",m=JSON.stringify(u.json));let g=await t(c,{method:u.method??"POST",headers:f,body:m});return g.status===401&&e.onUnauthorized?.(),g},l=async c=>{try{let u=o(Buffer.from(c.contentBase64,"base64")),d=KQ("sha256").update(u).digest("hex"),f=await a(`${s}/uploads`,{json:{name:n(c.name).slice(0,200),size:u.length,sha256:d}});if(!f.ok)return null;let m=await f.json();for(let k=0;k<m.parts;k++){let v=u.subarray(k*m.partBytes,(k+1)*m.partBytes),y=new URL(m.partUrl.replace("{index}",String(k)),i).toString(),b=!1;for(let S=0;S<3&&!b;S++)b=!!(await t(y,{method:"PUT",body:new Uint8Array(v)}).catch(()=>null))?.ok,b||await r(1e3*(S+1));if(!b)return null}let g=await a(new URL(m.completeUrl,i).toString(),{method:"POST"});if(!g.ok)return null;let h=await g.json();return typeof h.file?.id=="string"?h.file.id:null}catch{return null}};return{async heartbeat(c){try{let u=await a(`${s}/turns/${encodeURIComponent(c)}/heartbeat`,{json:{}});if(u.status!==404&&u.status!==410)return"continue";let d=await u.json().catch(()=>null);return d?.code==="turn_stopped"?"stop":u.status===404&&d?.code==="turn_unknown"?"continue":"gone"}catch{return"continue"}},async deliver({replyTurnId:c,engine:u,text:d,files:f}){let m=[],g=[],h=0;for(let v of f.slice(0,jQ)){let y=v.sizeBytes??Math.floor(v.contentBase64.length*3/4),b=n(v.name).slice(0,200);if(y<=$Q&&h+y<=HQ){let w=o(Buffer.from(v.contentBase64,"base64"));h+=w.length,m.push({name:b,contentBase64:w.toString("base64")});continue}let S=await l(v);S?m.push({fileId:S}):g.push(b.slice(0,80))}let k={engine:u,idempotencyKey:`turn-reply:${c}`,turnId:c,text:JQ(n(d),qQ[u],g),attachments:m,notify:!0};for(let v=0;;v++){let y=0;try{let S=await a(`${s}/posts`,{json:k});if(y=S.status,S.ok)return!0}catch{y=0}if(!(y===0||y===401||y===408||y===429||y>=500)||v>=uL.length)return!1;await r(uL[v])}}}}var cL,$Q,HQ,jQ,uL,VQ,qQ,pL=p(()=>{"use strict";jr();zb();cL=32e3,$Q=8*1024*1024,HQ=20*1024*1024,jQ=10,uL=[2e3,4e3,8e3,16e3,32e3],VQ=e=>new Promise(t=>setTimeout(t,e));qQ=rf});async function gi(e){if(e.auth){let t=await e.auth.authorization();if(t)return{bearer:t.bearer,kind:t.kind,boxId:t.boxId??e.boxId}}return{bearer:e.apiKey,kind:"api_key",boxId:e.boxId}}function qr(e,t,r){r===401&&t.kind==="box_token"&&e.auth?.invalidateToken()}var hi=p(()=>{"use strict"});import{closeSync as YQ,existsSync as zQ,fstatSync as XQ,openSync as QQ,readSync as ZQ}from"node:fs";function mL(e){if(!(typeof e!="string"||!e.trim()))return e.length>fL?`${e.slice(0,fL)}\u2026`:e}function hL(){return{lastSuccessAt:null,lastSuccessKind:null,steps24h:0,failures24h:{},recentFailures:[]}}function oZ(e,t){let r=hL(),n=[];for(let o of e){let s;try{s=JSON.parse(o)}catch{continue}let i=typeof s.at=="string"?Date.parse(s.at):Number.NaN;if(!Number.isNaN(i)&&(s.ok===!0&&(!r.lastSuccessAt||i>=Date.parse(r.lastSuccessAt))&&(r.lastSuccessAt=new Date(i).toISOString(),r.lastSuccessKind=s.kind??null),!(t-i>nZ)&&(r.steps24h+=1,s.ok===!1))){let a=typeof s.reason=="string"&&/^[a-z_]{1,40}$/.test(s.reason)?s.reason:"other";r.failures24h[a]=(r.failures24h[a]??0)+1;let l=mL(s.command),c=mL(s.path);n.push({at:new Date(i).toISOString(),kind:typeof s.kind=="string"?s.kind:null,...l?{command:l}:{},...c?{path:c}:{},...typeof s.exitCode=="number"&&Number.isFinite(s.exitCode)?{exitCode:Math.trunc(s.exitCode)}:{},reason:a})}}return r.recentFailures=n.sort((o,s)=>Date.parse(s.at)-Date.parse(o.at)).slice(0,eZ),r}function sZ(e){if(!zQ(e))return[];let t=QQ(e,"r");try{let r=XQ(t).size,n=Math.min(r,tZ),o=Buffer.alloc(n);return ZQ(t,o,0,n,r-n),o.toString("utf8").split(`
202
202
  `).filter(Boolean)}finally{YQ(t)}}function nf(e=Hb(),t=Date.now()){let r=gL.get(e);if(r&&t-r.at<rZ)return r.summary;let n;try{n=oZ(sZ(e),t)}catch{n=hL()}return gL.set(e,{at:t,summary:n}),n}var eZ,fL,tZ,rZ,nZ,gL,Xb=p(()=>{"use strict";Cl();eZ=20,fL=240;tZ=512*1024,rZ=3e4,nZ=1440*60*1e3;gL=new Map});import{appendFileSync as iZ,mkdirSync as aZ}from"node:fs";import{homedir as lZ}from"node:os";import Qb from"node:path";function yL(e=lZ()){return Qb.join(e,cZ)}function kL(e){let r=(e instanceof Error?e.message:String(e)).split(":")[0].trim();return/^[a-z_]{1,40}$/.test(r)?r:"other"}function bL(e,t=yL()){try{aZ(Qb.dirname(t),{recursive:!0}),iZ(t,`${JSON.stringify({kind:"step",...e})}
203
203
  `,{encoding:"utf8",mode:384})}catch{}}function vL(e=yL()){return nf(e)}var cZ,Zb=p(()=>{"use strict";Xb();cZ=Qb.join(".kynver","logs","chat-claude-code-steps.jsonl")});function Po(e){let t=Yp(e.provider,e.config,e.env??process.env),r=e.boxId?nu(e.payloadAccess,e.boxId):null,n=fs({engine:t,local:{chatComputerAccess:e.config.chatComputerAccess,chatWorkFolders:e.config.chatWorkFolders},website:r,home:e.home});return{engine:t,access:n}}var of=p(()=>{"use strict";El();Jn()});function RL(e,t,r={}){let n=r.env??process.env,{engine:o,access:s}=Po({provider:e,config:t,env:n});return{access:s.access,folders:s.folders.map(ze),source:s.source==="website"?"local":s.source,engine:o,engineVersion:o==="none"?null:(r.version??zp)(o,n),log:(r.summary??nf)(),...o==="claude-code"?{claudeCode:{signedIn:(r.signedIn??Xp)(n),steps:(r.stepSummary??vL)()}}:{}}}var wL=p(()=>{"use strict";ht();El();Zb();of();Xb()});function SL(e){try{return Ze().report(e)}catch{return null}}function sf(e,t){try{return RL(e,t)}catch{return}}function Al(){try{return B_().apiKey}catch{return"none"}}async function yi(e,t){for(let n=0;n<e&&!t();n+=500)await new Promise(o=>setTimeout(o,Math.min(500,e-n)))}var Oo,af=p(()=>{"use strict";$();vs();wL();hi();Oo=gi});function _L(e){let t=null;return dL({apiBaseUrl:e.apiBaseUrl??new URL(e.bridgeUrl).origin,agentOsId:e.agentOsId,bearer:async()=>(t=await Oo(e),t.bearer),onUnauthorized:()=>{t&&qr(e,t,401)}})}async function Ee(e,t,r){let n=await Oo(e),o=await fetch(`${e.bridgeUrl}/runtime-chat/turns/${encodeURIComponent(t)}/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.bearer}`},body:JSON.stringify({agentOsId:e.agentOsId,boxId:e.boxId,events:ip(e.agentOsId,r)})});return qr(e,n,o.status),o.ok}var Il=p(()=>{"use strict";pL();hi();jr();af()});async function xL(e,t,r){return e.security?.noteRejected(r.code),console.error(JSON.stringify({event:"chat_turn_rejected",turnId:t.turnId,requestId:t.requestId??"",code:r.code,...r.detail?{detail:r.detail}:{},reason:r.reason,policy:r.policy,...r.extra??{}})),mi({at:new Date().toISOString(),chat:t.requestId??null,turnId:t.turnId,kind:"tool",engine:"none",access:"off",command:`turn refused: ${r.code}${r.detail?` (${r.detail})`:""}`,folder:"",ok:!1,reason:`turn_rejected_${r.code}`}),await Ee(e,t.turnId,[{seq:0,kind:"error",error:nL(r.code,r.detail)}]).catch(()=>{}),{ok:!1}}async function ev(e,t,r){let n=oL({turnId:t.turnId,agentOsId:t.agentOsId,payload:t.payload},{agentOsId:e.agentOsId,policy:r.policy,nonces:r.nonces,env:r.env,nowSec:r.nowSec});if(!n.ok)return n.code==="replayed"&&n.replay?.state==="in_flight"?(e.security?.noteDuplicateOffer(),console.error(JSON.stringify({event:"chat_turn_duplicate_offer_dropped",turnId:t.turnId,requestId:t.requestId??"",firstSeenAt:n.replay.firstSeenAt,reason:n.reason})),{ok:!1}):xL(e,t,{code:n.code,reason:n.reason,policy:r.policy,...n.replay?{detail:n.replay.state,extra:{firstSeenAt:n.replay.firstSeenAt,firstTurnId:n.replay.turnId}}:{}});n.signed&&n.access?.others==="default"&&console.error(JSON.stringify({event:"chat_turn_non_owner",turnId:t.turnId,requestId:t.requestId??"",agentOsId:e.agentOsId,boxId:e.boxId,userId:n.userId??"",access:"off"}));let o=r.config;if(!o)try{o=A()}catch{o={}}let s=$M({signedAccess:n.access,boxId:e.boxId,agentOsId:e.agentOsId,engine:Yp(e.chatProvider,o,r.env??process.env),local:{chatComputerAccess:o.chatComputerAccess,chatWorkFolders:o.chatWorkFolders},state:Vp(r.stateFile),env:r.env,nowSec:r.nowSec});if(!s.ok)return xL(e,t,{code:s.code,detail:s.detail,reason:s.reason,policy:r.policy,extra:{from:fi(s.from),to:fi(s.to),signed:n.signed}});s.website&&JM(s.website,{file:r.stateFile});let a={...Gb(t.payload),...n.access?{computerAccess:n.access}:{}};return n.access||delete a.computerAccess,n.redelivered&&console.error(JSON.stringify({event:"chat_turn_redelivered",turnId:t.turnId,requestId:t.requestId??""})),{ok:!0,trust:{signed:n.signed,access:n.access},payload:a,redelivered:n.redelivered}}var tv=p(()=>{"use strict";$();HM();Kb();Cl();El();Zp();qb();Il()});var uZ,In,lf=p(()=>{"use strict";nk();uZ=150,In=class{constructor(t,r=uZ,n,o=!1){this.flushFn=t;this.floorMs=r;this.leading=o;this.stream=n&&!n.empty?uO(n,s=>{s&&this.flushFn(s)}):null}flushFn;floorMs;leading;buffer="";timer=null;closed=!1;sentAny=!1;stream;push(t){if(!(this.closed||!t)){if(this.buffer+=t,this.leading&&!this.sentAny){this.sentAny=!0,this.flushNow();return}this.timer||(this.timer=setTimeout(()=>{this.timer=null,this.flushNow()},this.floorMs))}}flushNow(t=!1){let r=this.buffer;if(this.buffer="",this.stream){r&&this.stream.write(r),t&&this.stream.flush();return}r&&this.flushFn(r)}flush(){this.closed||(this.timer&&(clearTimeout(this.timer),this.timer=null),this.flushNow())}close(){this.closed||(this.closed=!0,this.timer&&(clearTimeout(this.timer),this.timer=null),this.flushNow(!0))}}});function CL(e){if(!Array.isArray(e)||e.length===0||e.some(n=>typeof n!="string"))return{ok:!1,mutating:!1,reason:"argv must be a non-empty string array"};for(let n of e){if(gZ.some(o=>n===o||n.startsWith(`${o}=`)))return{ok:!1,mutating:!1,reason:`forbidden flag: ${n}`};if(n.includes(`
204
204
  `)||n.includes("\0"))return{ok:!1,mutating:!1,reason:"control characters refused"}}let t=e[0],r=e.length>1&&!e[1].startsWith("--")?`${t} ${e[1]}`:t;if(t==="doctor"){let n=e[1]&&!e[1].startsWith("--")?e[1]:void 0;return n&&!hZ.has(n)?{ok:!1,mutating:!1,reason:`verb not allowlisted: ${r}`}:{ok:!0,mutating:e.some(s=>s==="--remediate"||s==="--remediate-default-repo"||s.startsWith("--remediate="))}}return t==="cleanup"?{ok:!0,mutating:e.includes("--execute")}:r==="update finish"?{ok:!1,mutating:!0,reason:fZ}:r==="run dispatch"?{ok:!1,mutating:!0,reason:pZ}:dZ.has(r)?{ok:!0,mutating:!1}:mZ.has(r)?{ok:!0,mutating:!0}:{ok:!1,mutating:!1,reason:`verb not allowlisted: ${r}`}}var dZ,pZ,fZ,mZ,gZ,hZ,EL=p(()=>{"use strict";dZ=new Set(["run list","run status","worker list","worker status","worker tail","status","cron status","monitor status","monitor list","update check","update status"]),pZ="run dispatch is blocked from runtime_command \u2014 use agent_os_submit_action_intent with kind dispatch_workers (live dispatch requires Action Required approval)",fZ='update finish is internal to `kynver update` \u2014 call ["update"] (confirmed) to update Kynver',mZ=new Set(["run create","run sweep","worker start","worker stop","worker complete","cleanup","update"]),gZ=["--secret","--api-key","--keeper-child"],hZ=new Set(["runner-install","node-runtime","local-store","context-envelope","runtime-takeover"])});import{spawn as yZ}from"node:child_process";function vZ(e,t,r,n=process.env){let o=J_(r,{agentOsId:e,argv:t},n);return o.ok?null:`command authorization proof invalid: ${o.reason}`}async function IL(e,t,r={}){if(r.agentOsId){let a=vZ(r.agentOsId,e,r.authProof,r.env??process.env);if(a)return{exitCode:null,timedOut:!1,refused:a}}else return{exitCode:null,timedOut:!1,refused:"command authorization proof required (missing agentOsId)"};let n=CL(e);if(!n.ok)return{exitCode:null,timedOut:!1,refused:n.reason};let o=r.cliEntry??process.argv[1],s=r.timeoutMs??kZ,i=new In(t,void 0,rr(r.agentOsId??""));return new Promise(a=>{let l=0,c=!1,u=yZ(process.execPath,[o,...e],Z({stdio:["ignore","pipe","pipe"],env:process.env})),d=m=>{if(l>=AL)return;let g=m.toString("utf8").slice(0,AL-l);l+=g.length,i.push(g)};u.stdout?.on("data",d),u.stderr?.on("data",d);let f=setTimeout(()=>{c=!0,at(u,"SIGTERM"),setTimeout(()=>at(u,"SIGKILL"),bZ).unref()},s);u.on("error",m=>{clearTimeout(f),i.push(`spawn failed: ${m.message}`),i.close(),a({exitCode:null,timedOut:!1,refused:void 0})}),u.on("close",m=>{clearTimeout(f),i.close(),a({exitCode:m,timedOut:c})})})}var kZ,bZ,AL,PL=p(()=>{"use strict";U();lf();jr();EL();pa();kZ=10*6e4,bZ=5e3,AL=2e5});var Pn,cf=p(()=>{"use strict";Pn=class{pending=new Set;track(t){let r=t.finally(()=>{this.pending.delete(r)});return this.pending.add(r),r}async drain(){this.pending.size!==0&&await Promise.allSettled([...this.pending])}}});async function rv(e,t){let r=0,n=!1,o=new Pn,s=Array.isArray(t.payload?.argv)?t.payload.argv:[],i=await IL(s,a=>{n||o.track(Ee(e,t.turnId,[{seq:r++,kind:"delta",text:a}]).then(l=>(l||(n=!0),l)))},{agentOsId:e.agentOsId,authProof:t.payload?.authProof});await o.drain(),n||(i.refused?await Ee(e,t.turnId,[{seq:r++,kind:"error",error:`command_refused: ${i.refused}`}]).catch(()=>{}):await Ee(e,t.turnId,[{seq:r++,kind:"final",message:{exitCode:i.exitCode,timedOut:i.timedOut}}]).catch(()=>{})),console.error(JSON.stringify({event:"command_turn_done",turnId:t.turnId,argv:s.slice(0,4),exitCode:i.exitCode,timedOut:i.timedOut,refused:i.refused??null}))}var nv=p(()=>{"use strict";PL();cf();Il()});function uf(e){let t=e.appendLog??(s=>{mi(s)}),r=e.now??(()=>new Date),n=0,o=(s,i)=>jb({at:r().toISOString(),chat:e.chat,turnId:e.turnId,engine:i.engine,access:i.access.access,folder:i.access.workDir,...s});return{sink:((s,i)=>{let a=o(s,i);n+=1,t(a),e.send(a)}),attach(s,i,a){let l=o(s,i);n+=1,t(l),e.send({...l,toolUseId:a.toolUseId,...a.file?{file:a.file}:{}})},get steps(){return n}}}var ov=p(()=>{"use strict";Cl()});import{readFileSync as RZ,statSync as wZ}from"node:fs";import OL from"node:path";function xZ(e){if(!Array.isArray(e))return[];let t=[];for(let r of e){if(!r||typeof r!="object")continue;let n=r;if(n.type!=="tool_use"||n.name!==SZ||typeof n.id!="string")continue;let o=n.input&&typeof n.input=="object"?n.input:{};t.push({toolUseId:n.id,rawPath:typeof o.path=="string"?o.path:""})}return t}function To(e,t,r){return{step:{kind:"attach",path:e,ok:!1,reason:t,...r!==void 0?{outputBytes:r}:{}}}}function CZ(e,t,r={}){let n=r.stat??wZ,o=r.read??RZ,s=r.maxBytes??_Z,i=e.rawPath.trim();if(!i||i.includes("\0"))return To(i,"invalid_path");let a=OL.resolve(t.workDir,pc(i));if(t.access==="off")return To(a,"access_off");if(!su(t,a))return To(a,"outside_folders");let l;try{let c=n(a);if(!c.isFile())return To(a,"not_a_file");l=c.size}catch{return To(a,"not_found")}if(l>s)return To(a,"too_large",l);try{let c=o(a);return{step:{kind:"attach",path:a,outputBytes:c.length,ok:!0},file:{name:OL.basename(a),sizeBytes:c.length,contentBase64:c.toString("base64")}}}catch{return To(a,"read_failed")}}function TL(e,t,r){let n=xZ(e);for(let o of n){let s=CZ(o,t.access);r.attach(s.step,t,{toolUseId:o.toolUseId,...s.file?{file:s.file}:{}})}return n.length}var SZ,_Z,NL=p(()=>{"use strict";Jn();ht();SZ="attach_file",_Z=50*1024*1024});function ML(e){if(e.startsWith(`${DL}:`)||!Qy(e))return e;let t=e.replace(/\s+/g," ").trim().slice(0,300);return`${DL}: ${t}`}var DL,LL=p(()=>{"use strict";qd();DL="provider_usage_exhausted"});import{readFileSync as EZ}from"node:fs";import{homedir as AZ,platform as IZ}from"node:os";import PZ from"node:path";import{execFileSync as OZ}from"node:child_process";function BL(e,t=Date.now()){try{let r=JSON.parse(e),n=r.claudeAiOauth?.accessToken,o=r.claudeAiOauth?.expiresAt;return typeof n!="string"||!n||typeof o=="number"&&o-t<6e4?null:n}catch{return null}}function TZ(){if(IZ()==="darwin")try{let e=OZ("security",["find-generic-password","-s","Claude Code-credentials","-w"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return BL(e.trim())}catch{return null}try{let e=EZ(PZ.join(AZ(),".claude",".credentials.json"),"utf8");return BL(e)}catch{return null}}function Pl(e=process.env,t={}){let r=e.ANTHROPIC_API_KEY?.trim();if(r)return{kind:"api_key",key:r};let n=e.KYNVER_CHAT_USE_CLAUDE_OAUTH;if(t.oauthOptIn===!0||n==="1"||n==="true"||n==="yes"){let s=TZ();if(s)return{kind:"oauth",token:s}}return null}var sv=p(()=>{"use strict"});import{existsSync as UL}from"node:fs";import{homedir as NZ}from"node:os";import Ol from"node:path";import{spawnSync as DZ}from"node:child_process";function MZ(e){if(Ol.isAbsolute(e)||e.includes("/")||e.includes("\\"))return UL(e);try{let t=DZ(process.platform==="win32"?"where":"which",[e],{windowsHide:!0,encoding:"utf8",timeout:3e3});return t.status===0&&!!t.stdout?.trim()}catch{return!1}}function LZ(e=process.env){let t=NZ(),r=[],n=e.CODEX_HOME?.trim();return n&&r.push(Ol.join(Ol.resolve(n),"auth.json")),r.push(Ol.join(t,".codex","auth.json")),r.push(Ol.join(t,".config","codex","auth.json")),r}function FL(e){return`${e.error}: ${e.detail}`}function pf(e=process.env){let t=e.KYNVER_CODEX_BIN?.trim()||e.CODEX_BIN?.trim()||Ur();return MZ(t)?e.CODEX_API_KEY?.trim()?{ok:!0,creds:{codexBin:t,authSource:"api_key_env"}}:LZ(e).find(n=>UL(n))?{ok:!0,creds:{codexBin:t,authSource:"oauth_local"}}:{ok:!1,error:iv,detail:"Run `codex login` on this computer, or set CODEX_API_KEY. Website chat will not fall back to hosted models."}:{ok:!1,error:df,detail:"`codex` CLI not found. Install the Codex CLI (https://developers.openai.com/codex/) and keep it on PATH."}}var df,iv,ff=p(()=>{"use strict";fo();df="codex_cli_unavailable",iv="codex_not_logged_in"});import{spawnSync as BZ}from"node:child_process";function FZ(e,t,r){return UZ.test(`${t}
package/dist/index.js CHANGED
@@ -229,7 +229,7 @@ ${e.stderr}`.toLowerCase();return t.includes("api rate limit exceeded")||t.inclu
229
229
  `,{mode:384})}catch{}}function ise(e,t){return e?e.access===t.access&&e.source===t.source&&e.folders.length===t.folders.length&&e.folders.every((r,n)=>r===t.folders[n]):!1}function l$(e,t={signed:!1}){let r=t.file??JS(),n=t.now??(()=>new Date),o={access:e.access,folders:[...e.folders],source:e.source,signed:t.signed,at:n().toISOString()},s=rh(r);return ise(s.applied,o)?null:(a$(r,{applied:o,website:s.website}),{from:s.applied,to:o})}function c$(e,t={}){let r=t.file??JS(),n=t.now??(()=>new Date),o=rh(r),s={access:e.access,folders:[...e.folders],changedAt:e.changedAt,nonce:e.nonce,at:n().toISOString()},i=o.website;return i&&i.access===s.access&&i.changedAt===s.changedAt&&i.nonce===s.nonce&&i.folders.length===s.folders.length&&i.folders.every((l,c)=>l===s.folders[c])?i:(a$(r,{applied:o.applied,website:s}),s)}function el(e){switch(e){case"off":return"off";case"folder":return"one folder";case"folders":return"chosen folders";case"full":return"full computer";default:return String(e)}}import{appendFileSync as ase,mkdirSync as lse}from"node:fs";import{homedir as cse}from"node:os";import qS from"node:path";var use=qS.join(".kynver","logs","chat-commands.jsonl"),u$=2e3;function zS(e=cse()){return qS.join(e,use)}function XS(e){let t=r=>r===void 0?void 0:r.length>u$?`${r.slice(0,u$)}\u2026`:r;return{...e,...e.command!==void 0?{command:t(e.command)}:{},...e.path!==void 0?{path:t(e.path)}:{}}}function tl(e,t=zS()){try{return lse(qS.dirname(t),{recursive:!0}),ase(t,`${JSON.stringify(XS(e))}
230
230
  `,{encoding:"utf8",mode:384}),!0}catch(r){return console.error(JSON.stringify({event:"chat_command_log_write_failed",error:r instanceof Error?r.message:String(r)})),!1}}import{execFile as pse,spawnSync as f$}from"node:child_process";import{existsSync as mse,readFileSync as fse}from"node:fs";import{homedir as gse,platform as hse}from"node:os";import d$ from"node:path";Ne();T();Qi();function dse(e){let r=e.chatProvider?.trim()||e.workerProvider?.trim()||"";return He(r)}function ti(e,t=process.env){return dse(e)!=="gemini"?"http":po(ze(t))==="antigravity"?"antigravity":"http"}function sh(e,t,r=process.env){return e==="cursor"?"cursor":e==="codex"?"codex":e==="gemini"?ti(t,r)==="antigravity"?"antigravity":"none":e==="anthropic"?"claude-code":"none"}function yse(e,t){return e==="cursor"?ur(t):e==="codex"?t.KYNVER_CODEX_BIN?.trim()||t.CODEX_BIN?.trim()||jt():e==="antigravity"?ze(t):e==="claude-code"?t.KYNVER_CLAUDE_BIN?.trim()||t.CLAUDE_BIN?.trim()||"claude":null}var kse=/\d+\.\d+(?:\.\d+)?(?:[-+][\w.]+)?/,g$=10*6e4,nh=new Map,oh=new Set;function p$(e,t,r){let n=`${t??""} ${r??""}`;return e===0?n.match(kse)?.[0]??null:null}function ih(e,t=process.env,r=Date.now()){let n=yse(e,t);if(!n)return null;let o=nh.get(n);if(o&&r-o.at<g$)return o.version;if(o){if(!oh.has(n)){oh.add(n);try{let[i,a]=se(n,["--version"]);pse(i,a,oe({encoding:"utf8",timeout:5e3}),(l,c,u)=>{oh.delete(n),nh.set(n,{at:Date.now(),version:l?null:p$(0,c,u)})})}catch{oh.delete(n),nh.set(n,{at:r,version:o.version})}}return o.version}let s=null;try{let[i,a]=se(n,["--version"]),l=f$(i,a,oe({encoding:"utf8",timeout:5e3}));s=p$(l.status,l.stdout,l.stderr)}catch{s=null}return nh.set(n,{at:r,version:s}),s}var m$=new Map;function ah(e=process.env,t={}){if(e.ANTHROPIC_API_KEY?.trim())return!0;let r=t.home??gse(),n=t.now??Date.now(),o=m$.get(r);if(o&&n-o.at<g$)return o.signedIn;let s=bse(d$.join(e.CLAUDE_CONFIG_DIR?.trim()||d$.join(r,".claude"),".credentials.json"));return!s&&(t.os??hse())==="darwin"&&(s=(t.keychain??vse)()),m$.set(r,{at:n,signedIn:s}),s}function bse(e){if(!mse(e))return!1;try{let t=JSON.parse(fse(e,"utf8")).claudeAiOauth,r=n=>typeof n=="string"&&n.length>0;return!!t&&(r(t.refreshToken)||r(t.accessToken))}catch{return!1}}function vse(){try{return f$("security",["find-generic-password","-s","Claude Code-credentials"],{stdio:"ignore",timeout:5e3}).status===0}catch{return!1}}import{createHash as Rse,verify as wse,createPublicKey as Sse}from"node:crypto";var h$="turnEnvelope",_se=Buffer.from("302a300506032b6570032100","hex");function ZS(e){if(!e||typeof e!="object"||Array.isArray(e))return e;let t={...e};return delete t[h$],t}function Cse(e){return Rse("sha256").update(ht(ZS(e)),"utf8").digest("hex")}function e_(e){return!e||typeof e!="object"||Array.isArray(e)?null:e[h$]??null}function xse(e){if(!e||typeof e!="object")return!1;let t=e;if(typeof t.signature!="string"||!t.signature||typeof t.publicKeyId!="string"||!t.publicKeyId)return!1;let r=t.payload;return!(!r||typeof r!="object"||r.v!==1||r.kind!=="chat-turn"||typeof r.turnId!="string"||!r.turnId||typeof r.agentOsId!="string"||!r.agentOsId||r.userId!==null&&(typeof r.userId!="string"||!r.userId)||r.boxId!==null&&typeof r.boxId!="string"||r.access!==null&&(!r.access||typeof r.access!="object"||Array.isArray(r.access))||typeof r.payloadHash!="string"||!/^[0-9a-f]{64}$/.test(r.payloadHash)||typeof r.exp!="number"||!Number.isFinite(r.exp)||typeof r.nonce!="string"||!r.nonce)}function Ese(e,t){let r=e&&typeof e=="object"&&!Array.isArray(e)?e.computerAccess??null:null;return r===null&&t===null?!0:r===null||t===null?!1:ht(r)===ht(t)}var lh=class{constructor(t=1e4){this.maxEntries=t}maxEntries;byNonce=new Map;byTurn=new Map;consume(t){let r=t.nowSec??Math.floor(Date.now()/1e3);this.purge(r);let n=this.byNonce.get(t.nonce);if(n)return n.turnId!==t.turnId?{ok:!1,replay:QS(n,"turn_mismatch")}:n.state==="verified"?{ok:!0,redelivered:!0}:{ok:!1,replay:QS(n,n.state==="started"?"in_flight":"already_ran")};let o=this.byTurn.get(t.turnId);if(o){if(o.state!=="verified")return{ok:!1,replay:QS(o,o.state==="started"?"in_flight":"already_ran")};this.byNonce.delete(o.nonce);let i={...o,nonce:t.nonce,untilSec:Math.max(o.untilSec,t.expSec+60)};return this.byNonce.set(t.nonce,i),this.byTurn.set(t.turnId,i),{ok:!0,redelivered:!0}}if(this.byNonce.size>=this.maxEntries){let i=this.byNonce.values().next().value;i&&this.forget(i)}let s={nonce:t.nonce,turnId:t.turnId,firstSeenSec:r,state:"verified",untilSec:t.expSec+60};return this.byNonce.set(t.nonce,s),this.byTurn.set(t.turnId,s),{ok:!0,redelivered:!1}}markStarted(t){let r=this.byTurn.get(t);return r?(r.state==="verified"&&(r.state="started"),!0):!1}markFinished(t){let r=this.byTurn.get(t);return r?(r.state="finished",!0):!1}stateOf(t){return this.byTurn.get(t)?.state??null}purge(t=Math.floor(Date.now()/1e3)){for(let r of[...this.byNonce.values()])r.untilSec<=t&&this.forget(r)}forget(t){this.byNonce.delete(t.nonce),this.byTurn.get(t.turnId)===t&&this.byTurn.delete(t.turnId)}get size(){return this.byNonce.size}};function QS(e,t){return{state:t,firstSeenAt:new Date(e.firstSeenSec*1e3).toISOString(),turnId:e.turnId}}function Ase(e){return Sse({key:Buffer.concat([_se,Buffer.from(e)]),format:"der",type:"spki"})}function y$(e,t,r={}){let n=r.env??process.env,o=r.nowSec??Math.floor(Date.now()/1e3),s=e_(e);if(s===null)return{ok:!1,code:"unsigned",reason:"turn carries no signed envelope"};if(!xse(s))return{ok:!1,code:"malformed",reason:"malformed chat-turn envelope"};let i=s;if(i.payload.agentOsId!==t.agentOsId)return{ok:!1,code:"agent_os_mismatch",reason:"envelope is for another workspace"};if(i.payload.turnId!==t.turnId)return{ok:!1,code:"turn_id_mismatch",reason:"envelope is for another turn"};if(i.payload.exp<=o)return{ok:!1,code:"expired",reason:"envelope expired"};let a=_s(i.publicKeyId,n);if(!a)return{ok:!1,code:"no_verification_key",reason:`no verification key for publicKeyId "${i.publicKeyId}"`};let l;try{l=Buffer.from(i.signature,"base64url")}catch{return{ok:!1,code:"bad_signature",reason:"signature is not base64url"}}if(l.length!==64)return{ok:!1,code:"bad_signature",reason:"signature is not a 64-byte Ed25519 signature"};let c=!1;try{let d=Buffer.from(ht(i.payload),"utf8");c=wse(null,d,Ase(a),l)}catch(d){return{ok:!1,code:"bad_signature",reason:`signature verification failed: ${d.message}`}}if(!c)return{ok:!1,code:"bad_signature",reason:"Ed25519 signature mismatch"};if(Cse(e)!==i.payload.payloadHash)return{ok:!1,code:"payload_tampered",reason:"turn payload does not match its signed hash"};if(!Ese(e,i.payload.access))return{ok:!1,code:"access_mismatch",reason:"computer access on the turn differs from the signed setting"};if(!r.nonces)return{ok:!0,payload:i.payload,redelivered:!1};let u=r.nonces.consume({nonce:i.payload.nonce,turnId:i.payload.turnId,expSec:i.payload.exp,nowSec:o});return u.ok?{ok:!0,payload:i.payload,redelivered:u.redelivered}:{ok:!1,code:"replayed",reason:`envelope nonce already used on this computer (${Pse(u.replay)})`,replay:u.replay}}function Pse(e){return`${e.state==="in_flight"?"this computer is running that turn now":e.state==="already_ran"?"that turn already ran here":`the nonce belongs to turn ${e.turnId}`}; first seen ${e.firstSeenAt}`}var Ise="KYNVER_CHAT_TURN_SIGNATURE";function k$(e=process.env,t={}){let r=(e[Ise]??t.chatTurnSignature??"").toString().trim().toLowerCase();return r==="optional"||r==="off"||r==="0"||r==="false"?"optional":"required"}function b$(e,t){return t?`turn_rejected_${e}: ${t}`:`turn_rejected_${e}`}function v$(e,t){if(!(e_(e.payload)!==null)&&t.policy==="optional"){let o=e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload.computerAccess??null:null;return{ok:!0,access:Ose(o)?o:null,signed:!1,userId:null,redelivered:!1}}let n=y$(e.payload,{agentOsId:t.agentOsId,turnId:e.turnId},{env:t.env,nowSec:t.nowSec,nonces:t.nonces});return n.ok?{ok:!0,access:n.payload.access,signed:!0,userId:n.payload.userId,redelivered:n.redelivered}:{ok:!1,code:n.code,reason:n.reason,...n.replay?{replay:n.replay}:{}}}function Ose(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e.byBox;return!!t&&typeof t=="object"&&!Array.isArray(t)}import{createHash as Wse}from"node:crypto";var t_="KYNVER_CONVERSATION",r_="KYNVER_AGENT_TAB_ENGINE",R$="X-Kynver-Conversation",Tse=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Ku(e){return typeof e=="string"&&Tse.test(e.trim())?e.trim():null}function ch(e){return`Kynver conversation id: ${e}. When work you start from this conversation later finishes, fails, needs the user or opens / merges a PR, post the update here only: \`kynver tab post --conversation ${e} "<text>"\` (or the agent_tab_post tool with this conversationId). When you create a Kynver task for it, pass originConversationId=${e} so its updates come back here too.`}function w$(e,t){let r=Ku(e);return r?{[t_]:r,[r_]:t}:{}}var Nse=["hermes","openclaw","claude-code","grok-bot"],rl={hermes:"Hermes",openclaw:"OpenClaw","claude-code":"Claude Code","grok-bot":"Grok Bot"};function Hu(e){return typeof e=="string"&&Nse.includes(e)}var Dse=/^[A-Za-z0-9-]{8,64}$/,S$=32e3,Mse=4e3,Lse=5,Bse=20*1024*1024,Use=/^[A-Za-z0-9_.:-]{8,128}$/;function _$(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;if(t.kind!=="agent-tab"||!Hu(t.engine)||typeof t.sessionKey!="string"||!Use.test(t.sessionKey))return null;let r=typeof t.text=="string"?t.text.slice(0,S$):"",n=[],o=0;if(Array.isArray(t.attachments))for(let c of t.attachments.slice(0,Lse)){if(!c||typeof c!="object")continue;let{name:u,mime:d,contentBase64:p}=c;if(!(typeof u!="string"||typeof p!="string")){if(o+=Math.floor(p.length*3/4),o>Bse)break;n.push({name:u.slice(0,200),mime:typeof d=="string"?d.slice(0,100):"application/octet-stream",contentBase64:p})}}let s=$se(t.control);if(!s&&!r.trim()&&n.length===0)return null;let i=typeof t.styleNote=="string"?t.styleNote.trim().slice(0,Mse):"",a=typeof t.replyTurnId=="string"&&Dse.test(t.replyTurnId)?t.replyTurnId:null,l=Ku(t.conversationId);return{kind:"agent-tab",engine:t.engine,sessionKey:t.sessionKey,text:r,attachments:n,...t.computerAccess!==void 0?{computerAccess:t.computerAccess}:{},...i?{styleNote:i}:{},...a?{replyTurnId:a}:{},...s?{control:s}:{},...l?{conversationId:l}:{}}}function $se(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return t.op==="stop"?{op:"stop"}:t.op==="steer"&&typeof t.text=="string"&&t.text.trim()?{op:"steer",text:t.text.slice(0,S$)}:null}var C$=32e3,Fse=8*1024*1024,Kse=20*1024*1024,Hse=10,x$=[2e3,4e3,8e3,16e3,32e3],jse=e=>new Promise(t=>setTimeout(t,e));function Vse(e){return`${e.apiBaseUrl.replace(/\/$/,"")}/api/agent-os/by-id/${encodeURIComponent(e.agentOsId)}/agent-tabs/box`}function Gse(e,t,r){let n=e.trim()?e:`${t} finished without writing a reply.`;return r.length>0&&(n+=`
231
231
 
232
- _${r.length===1?"A file":`${r.length} files`} couldn't be attached: ${r.join(", ")}._`),n.length>C$?`${n.slice(0,C$-1)}\u2026`:n}var Yse=rl;function E$(e){let t=e.fetchFn??fetch,r=e.wait??jse,n=e.redactText??(c=>Zc(e.agentOsId,c)),o=c=>{let u=Bf(e.agentOsId,c),d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(u)}catch{return u}if(d.includes("\0"))return u;let p=n(d);return p===d?u:Buffer.from(p,"utf8")},s=Vse(e),i=new URL(e.apiBaseUrl).origin,a=async(c,u)=>{let p={Authorization:`Bearer ${await e.bearer()}`},m=u.body;u.json!==void 0&&(p["Content-Type"]="application/json",m=JSON.stringify(u.json));let f=await t(c,{method:u.method??"POST",headers:p,body:m});return f.status===401&&e.onUnauthorized?.(),f},l=async c=>{try{let u=o(Buffer.from(c.contentBase64,"base64")),d=Wse("sha256").update(u).digest("hex"),p=await a(`${s}/uploads`,{json:{name:n(c.name).slice(0,200),size:u.length,sha256:d}});if(!p.ok)return null;let m=await p.json();for(let y=0;y<m.parts;y++){let k=u.subarray(y*m.partBytes,(y+1)*m.partBytes),h=new URL(m.partUrl.replace("{index}",String(y)),i).toString(),b=!1;for(let R=0;R<3&&!b;R++)b=!!(await t(h,{method:"PUT",body:new Uint8Array(k)}).catch(()=>null))?.ok,b||await r(1e3*(R+1));if(!b)return null}let f=await a(new URL(m.completeUrl,i).toString(),{method:"POST"});if(!f.ok)return null;let g=await f.json();return typeof g.file?.id=="string"?g.file.id:null}catch{return null}};return{async heartbeat(c){try{let u=await a(`${s}/turns/${encodeURIComponent(c)}/heartbeat`,{json:{}});return u.status!==404&&u.status!==410?"continue":(await u.json().catch(()=>null))?.code==="turn_stopped"?"stop":"gone"}catch{return"continue"}},async deliver({replyTurnId:c,engine:u,text:d,files:p}){let m=[],f=[],g=0;for(let k of p.slice(0,Hse)){let h=k.sizeBytes??Math.floor(k.contentBase64.length*3/4),b=n(k.name).slice(0,200);if(h<=Fse&&g+h<=Kse){let S=o(Buffer.from(k.contentBase64,"base64"));g+=S.length,m.push({name:b,contentBase64:S.toString("base64")});continue}let R=await l(k);R?m.push({fileId:R}):f.push(b.slice(0,80))}let y={engine:u,idempotencyKey:`turn-reply:${c}`,turnId:c,text:Gse(n(d),Yse[u],f),attachments:m,notify:!0};for(let k=0;;k++){let h=0;try{let R=await a(`${s}/posts`,{json:y});if(h=R.status,R.ok)return!0}catch{h=0}if(!(h===0||h===401||h===408||h===429||h>=500)||k>=x$.length)return!1;await r(x$[k])}}}}async function nl(e){if(e.auth){let t=await e.auth.authorization();if(t)return{bearer:t.bearer,kind:t.kind,boxId:t.boxId??e.boxId}}return{bearer:e.apiKey,kind:"api_key",boxId:e.boxId}}function Hn(e,t,r){r===401&&t.kind==="box_token"&&e.auth?.invalidateToken()}L();import{randomBytes as yie}from"node:crypto";import{existsSync as kie,rmSync as bie}from"node:fs";import{appendFileSync as lie,chmodSync as cie,existsSync as B$,mkdirSync as uie,readFileSync as U$,renameSync as die,statSync as pie,writeFileSync as mie}from"node:fs";import fie from"node:path";import{createHash as Zse,randomBytes as D$}from"node:crypto";import{chmodSync as T$,existsSync as eie,mkdirSync as tie,readFileSync as rie,renameSync as nie,rmSync as oie,writeFileSync as sie}from"node:fs";import{homedir as iie}from"node:os";import M$ from"node:path";var Jse=/^(localhost|.*\.localhost|.*\.local|.*\.internal|0\.0\.0\.0|\[.*\]|\d{1,3}(\.\d{1,3}){3})$/i,qse=/^(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})$/;function A$(e,t={}){if(typeof e!="string"||!e.trim())return{ok:!1,reason:"a site address is required"};let r=e.trim();/^[a-z][a-z0-9+.-]*:/i.test(r)||(r=`https://${r}`);let n;try{n=new URL(r)}catch{return{ok:!1,reason:"not a valid web address"}}return n.protocol!=="https:"?{ok:!1,reason:"saved logins are only used on https:// sites"}:n.username||n.password?{ok:!1,reason:"the address must not contain a username or password"}:t.allowLan===!0&&qse.test(n.hostname)&&n.hostname.split(".").every(s=>Number(s)<=255)?{ok:!0,origin:n.origin,unicodeHost:!1}:!n.hostname.includes(".")||Jse.test(n.hostname)?{ok:!1,reason:"use the site's public address (e.g. https://www.instagram.com)"}:{ok:!0,origin:n.origin,unicodeHost:n.hostname.split(".").some(s=>s.startsWith("xn--"))}}function ju(e){if(typeof e!="string"||!e)return null;try{let t=new URL(e).origin;return t&&t!=="null"?t:null}catch{return null}}function n_(e,t){let r=ju(t);return r!==null&&r===e}import{createHmac as zse}from"node:crypto";var Xse="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function P$(e){let t=e.replace(/[\s-]/g,"").replace(/=+$/,"").toUpperCase();if(!t||!/^[A-Z2-7]+$/.test(t))return null;let r=0,n=0,o=[];for(let s of t)n=n<<5|Xse.indexOf(s),r+=5,r>=8&&(o.push(n>>>r-8&255),r-=8);return o.length?Buffer.from(o):null}function uh(e){let t=e.trim();if(!t)return null;if(/^otpauth:\/\//i.test(t)){let n;try{n=new URL(t)}catch{return null}if(n.host.toLowerCase()!=="totp")return null;let o=P$(n.searchParams.get("secret")??"");if(!o)return null;let s=(n.searchParams.get("algorithm")??"SHA1").toUpperCase(),i=Number(n.searchParams.get("digits")??"6"),a=Number(n.searchParams.get("period")??"30");return s!=="SHA1"&&s!=="SHA256"&&s!=="SHA512"||i!==6&&i!==7&&i!==8||!Number.isInteger(a)||a<10||a>300?null:{key:o,algorithm:s,digits:i,period:a}}let r=P$(t);return r?{key:r,algorithm:"SHA1",digits:6,period:30}:null}function Qse(e,t,r,n){let o=Buffer.alloc(8);o.writeBigUInt64BE(t);let s=zse(n.toLowerCase(),e).update(o).digest(),i=s[s.length-1]&15,a=(s[i]&127)<<24|s[i+1]<<16|s[i+2]<<8|s[i+3];return String(a%10**r).padStart(r,"0")}function I$(e,t=Date.now()){let r=BigInt(Math.floor(t/1e3/e.period));return Qse(e.key,r,e.digits,e.algorithm)}function O$(e,t=Date.now()){let r=Math.floor(t/1e3)%e.period;return e.period-r}var Yr={maxRecords:200,maxLabel:80,maxUsername:254,maxPassword:1024,maxTotp:512};function Vu(){return M$.join(iie(),".kynver","site-logins")}function o_(e){return`${Zse("sha256").update(`kynver-site-login:${e}`).digest("hex").slice(0,32)}.vault.json`}var J=class extends Error{constructor(r,n){super(r);this.code=n;this.name="SiteLoginError"}code},L$=/[\u0000-\u001f\u007f]/;function N$(e,t,r,n=!0){let o=typeof e=="string"?e.trim():"";if(!o&&n)throw new J(`${t} is required`,"invalid");if(o.length>r)throw new J(`${t} is too long (max ${r})`,"invalid");if(L$.test(o))throw new J(`${t} contains control characters`,"invalid");return o}var dh=class{constructor(t){this.opts=t;let r=t.agentOsId.trim();if(!r||L$.test(r)||r.length>200)throw new J("invalid workspace id","invalid");this.agentOsId=r,this.rootDir=t.rootDir??Vu(),this.filePath=M$.join(this.rootDir,o_(r)),this.now=t.now??Date.now}opts;agentOsId;filePath;rootDir;now;exists(){return eie(this.filePath)}keyMode(){return this.exists()?this.read().keyMode:null}async createWithPassphrase(t){if(this.exists())throw new J("a saved-login vault already exists on this computer","exists");if(t.length<Xc)throw new J(`the vault passphrase must be at least ${Xc} characters`,"invalid");let r=uD(),n=dD(this.opts.scryptCost),o=await IR(t,n,this.opts.minScryptN);return this.write({v:1,agentOsId:this.agentOsId,keyMode:"passphrase",kdf:n,wrappedKey:wo(o,r,TR(this.agentOsId)),keyCheck:wo(r,Nf,Tf(this.agentOsId)),records:[]}),o.fill(0),r}createWithKeychainKey(t){if(this.exists())throw new J("a saved-login vault already exists on this computer","exists");this.write({v:1,agentOsId:this.agentOsId,keyMode:"keychain",keyCheck:wo(t,Nf,Tf(this.agentOsId)),records:[]})}async unlockWithPassphrase(t){let r=this.read();if(r.keyMode!=="passphrase"||!r.kdf||!r.wrappedKey)throw new J("this vault is unlocked by the Kynver desktop app, not a passphrase","invalid");let n=null;try{n=await IR(t,r.kdf,this.opts.minScryptN);let o=$s(n,r.wrappedKey,TR(this.agentOsId));return this.verifyKey(r,o),o}catch(o){throw o instanceof J?o:o instanceof hr&&/unsafe|salt/.test(o.message)?new J(o.message,"corrupt"):new J("wrong vault passphrase","bad_key")}finally{n?.fill(0)}}unlockWithKey(t){return this.verifyKey(this.read(),t),t}wipe(){return this.exists()?(oie(this.filePath,{force:!0}),!0):!1}list(){return this.exists()?this.read().records.map(({secret:t,...r})=>r):[]}get(t){return this.list().find(r=>r.handle===t)??null}add(t,r){let n=this.read();if(this.verifyKey(n,t),n.records.length>=Yr.maxRecords)throw new J(`at most ${Yr.maxRecords} saved logins per workspace`,"full");let o=this.buildRecord(t,r,aie(),new Date(this.now()).toISOString());n.records.push(o),this.write(n);let{secret:s,...i}=o;return i}replace(t,r,n){let o=this.read();this.verifyKey(o,t);let s=o.records.findIndex(c=>c.handle===r);if(s<0)throw new J("no saved login with that id","not_found");let i=this.buildRecord(t,n,r,o.records[s].createdAt);o.records[s]=i,this.write(o);let{secret:a,...l}=i;return l}remove(t){if(!this.exists())return!1;let r=this.read(),n=r.records.filter(o=>o.handle!==t);return n.length===r.records.length?!1:(r.records=n,this.write(r),!0)}readSecret(t,r){let n=this.read();this.verifyKey(n,t);let o=n.records.find(i=>i.handle===r);if(!o)throw new J("no saved login with that id","not_found");let s;try{s=$s(t,o.secret,NR({agentOsId:this.agentOsId,...o}))}catch{throw new J("this saved login failed its integrity check and was not used","corrupt")}try{let i=JSON.parse(s.toString("utf8"));if(typeof i.p!="string")throw new Error("shape");let{secret:a,...l}=o;return{summary:l,secret:{password:i.p,...typeof i.t=="string"?{totp:i.t}:{}}}}catch{throw new J("this saved login failed its integrity check and was not used","corrupt")}finally{s.fill(0)}}touch(t){let r=this.read(),n=r.records.find(o=>o.handle===t);n&&(n.lastUsedAt=new Date(this.now()).toISOString(),this.write(r))}buildRecord(t,r,n,o){let s=A$(r.origin,{allowLan:r.allowLan===!0});if(!s.ok)throw new J(s.reason,"invalid");let i=N$(r.label,"label",Yr.maxLabel),a=N$(r.username,"username",Yr.maxUsername),l=typeof r.password=="string"?r.password:"";if(!l)throw new J("password is required","invalid");if(l.length>Yr.maxPassword)throw new J("password is too long","invalid");let c=typeof r.totp=="string"&&r.totp.trim()?r.totp.trim():void 0;if(c&&(c.length>Yr.maxTotp||!uh(c)))throw new J("the authenticator key is not a valid base32 secret or otpauth://totp link","invalid");let u={handle:n,origin:s.origin,label:i,username:a,hasTotp:!!c,createdAt:o,lastUsedAt:null},d=Buffer.from(JSON.stringify(c?{p:l,t:c}:{p:l}),"utf8");try{return{...u,secret:wo(t,d,NR({agentOsId:this.agentOsId,...u}))}}finally{d.fill(0)}}verifyKey(t,r){try{let n=$s(r,t.keyCheck,Tf(this.agentOsId));if(!pD(n,Nf))throw new Error("mismatch")}catch{throw new J("the vault key does not open this vault","bad_key")}}read(){if(!this.exists())throw new J("no saved-login vault on this computer yet","missing");let t;try{t=JSON.parse(rie(this.filePath,"utf8"))}catch{throw new J("the saved-login vault file is unreadable","corrupt")}if(!t||t.v!==1||t.keyMode!=="passphrase"&&t.keyMode!=="keychain"||!t.keyCheck||!Array.isArray(t.records))throw new J("the saved-login vault file is not a vault Kynver understands","corrupt");if(t.agentOsId!==this.agentOsId)throw new J("this saved-login vault belongs to a different workspace","corrupt");return t.records=t.records.filter(r=>r&&typeof r.handle=="string"&&typeof r.origin=="string"&&typeof r.label=="string"&&typeof r.username=="string"&&r.secret&&typeof r.secret.n=="string"&&typeof r.secret.c=="string"),t}write(t){tie(this.rootDir,{recursive:!0,mode:448});try{T$(this.rootDir,448)}catch{}let r=`${this.filePath}.${D$(4).toString("hex")}.tmp`;sie(r,`${JSON.stringify(t)}
232
+ _${r.length===1?"A file":`${r.length} files`} couldn't be attached: ${r.join(", ")}._`),n.length>C$?`${n.slice(0,C$-1)}\u2026`:n}var Yse=rl;function E$(e){let t=e.fetchFn??fetch,r=e.wait??jse,n=e.redactText??(c=>Zc(e.agentOsId,c)),o=c=>{let u=Bf(e.agentOsId,c),d;try{d=new TextDecoder("utf-8",{fatal:!0}).decode(u)}catch{return u}if(d.includes("\0"))return u;let p=n(d);return p===d?u:Buffer.from(p,"utf8")},s=Vse(e),i=new URL(e.apiBaseUrl).origin,a=async(c,u)=>{let p={Authorization:`Bearer ${await e.bearer()}`},m=u.body;u.json!==void 0&&(p["Content-Type"]="application/json",m=JSON.stringify(u.json));let f=await t(c,{method:u.method??"POST",headers:p,body:m});return f.status===401&&e.onUnauthorized?.(),f},l=async c=>{try{let u=o(Buffer.from(c.contentBase64,"base64")),d=Wse("sha256").update(u).digest("hex"),p=await a(`${s}/uploads`,{json:{name:n(c.name).slice(0,200),size:u.length,sha256:d}});if(!p.ok)return null;let m=await p.json();for(let y=0;y<m.parts;y++){let k=u.subarray(y*m.partBytes,(y+1)*m.partBytes),h=new URL(m.partUrl.replace("{index}",String(y)),i).toString(),b=!1;for(let R=0;R<3&&!b;R++)b=!!(await t(h,{method:"PUT",body:new Uint8Array(k)}).catch(()=>null))?.ok,b||await r(1e3*(R+1));if(!b)return null}let f=await a(new URL(m.completeUrl,i).toString(),{method:"POST"});if(!f.ok)return null;let g=await f.json();return typeof g.file?.id=="string"?g.file.id:null}catch{return null}};return{async heartbeat(c){try{let u=await a(`${s}/turns/${encodeURIComponent(c)}/heartbeat`,{json:{}});if(u.status!==404&&u.status!==410)return"continue";let d=await u.json().catch(()=>null);return d?.code==="turn_stopped"?"stop":u.status===404&&d?.code==="turn_unknown"?"continue":"gone"}catch{return"continue"}},async deliver({replyTurnId:c,engine:u,text:d,files:p}){let m=[],f=[],g=0;for(let k of p.slice(0,Hse)){let h=k.sizeBytes??Math.floor(k.contentBase64.length*3/4),b=n(k.name).slice(0,200);if(h<=Fse&&g+h<=Kse){let S=o(Buffer.from(k.contentBase64,"base64"));g+=S.length,m.push({name:b,contentBase64:S.toString("base64")});continue}let R=await l(k);R?m.push({fileId:R}):f.push(b.slice(0,80))}let y={engine:u,idempotencyKey:`turn-reply:${c}`,turnId:c,text:Gse(n(d),Yse[u],f),attachments:m,notify:!0};for(let k=0;;k++){let h=0;try{let R=await a(`${s}/posts`,{json:y});if(h=R.status,R.ok)return!0}catch{h=0}if(!(h===0||h===401||h===408||h===429||h>=500)||k>=x$.length)return!1;await r(x$[k])}}}}async function nl(e){if(e.auth){let t=await e.auth.authorization();if(t)return{bearer:t.bearer,kind:t.kind,boxId:t.boxId??e.boxId}}return{bearer:e.apiKey,kind:"api_key",boxId:e.boxId}}function Hn(e,t,r){r===401&&t.kind==="box_token"&&e.auth?.invalidateToken()}L();import{randomBytes as yie}from"node:crypto";import{existsSync as kie,rmSync as bie}from"node:fs";import{appendFileSync as lie,chmodSync as cie,existsSync as B$,mkdirSync as uie,readFileSync as U$,renameSync as die,statSync as pie,writeFileSync as mie}from"node:fs";import fie from"node:path";import{createHash as Zse,randomBytes as D$}from"node:crypto";import{chmodSync as T$,existsSync as eie,mkdirSync as tie,readFileSync as rie,renameSync as nie,rmSync as oie,writeFileSync as sie}from"node:fs";import{homedir as iie}from"node:os";import M$ from"node:path";var Jse=/^(localhost|.*\.localhost|.*\.local|.*\.internal|0\.0\.0\.0|\[.*\]|\d{1,3}(\.\d{1,3}){3})$/i,qse=/^(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})$/;function A$(e,t={}){if(typeof e!="string"||!e.trim())return{ok:!1,reason:"a site address is required"};let r=e.trim();/^[a-z][a-z0-9+.-]*:/i.test(r)||(r=`https://${r}`);let n;try{n=new URL(r)}catch{return{ok:!1,reason:"not a valid web address"}}return n.protocol!=="https:"?{ok:!1,reason:"saved logins are only used on https:// sites"}:n.username||n.password?{ok:!1,reason:"the address must not contain a username or password"}:t.allowLan===!0&&qse.test(n.hostname)&&n.hostname.split(".").every(s=>Number(s)<=255)?{ok:!0,origin:n.origin,unicodeHost:!1}:!n.hostname.includes(".")||Jse.test(n.hostname)?{ok:!1,reason:"use the site's public address (e.g. https://www.instagram.com)"}:{ok:!0,origin:n.origin,unicodeHost:n.hostname.split(".").some(s=>s.startsWith("xn--"))}}function ju(e){if(typeof e!="string"||!e)return null;try{let t=new URL(e).origin;return t&&t!=="null"?t:null}catch{return null}}function n_(e,t){let r=ju(t);return r!==null&&r===e}import{createHmac as zse}from"node:crypto";var Xse="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function P$(e){let t=e.replace(/[\s-]/g,"").replace(/=+$/,"").toUpperCase();if(!t||!/^[A-Z2-7]+$/.test(t))return null;let r=0,n=0,o=[];for(let s of t)n=n<<5|Xse.indexOf(s),r+=5,r>=8&&(o.push(n>>>r-8&255),r-=8);return o.length?Buffer.from(o):null}function uh(e){let t=e.trim();if(!t)return null;if(/^otpauth:\/\//i.test(t)){let n;try{n=new URL(t)}catch{return null}if(n.host.toLowerCase()!=="totp")return null;let o=P$(n.searchParams.get("secret")??"");if(!o)return null;let s=(n.searchParams.get("algorithm")??"SHA1").toUpperCase(),i=Number(n.searchParams.get("digits")??"6"),a=Number(n.searchParams.get("period")??"30");return s!=="SHA1"&&s!=="SHA256"&&s!=="SHA512"||i!==6&&i!==7&&i!==8||!Number.isInteger(a)||a<10||a>300?null:{key:o,algorithm:s,digits:i,period:a}}let r=P$(t);return r?{key:r,algorithm:"SHA1",digits:6,period:30}:null}function Qse(e,t,r,n){let o=Buffer.alloc(8);o.writeBigUInt64BE(t);let s=zse(n.toLowerCase(),e).update(o).digest(),i=s[s.length-1]&15,a=(s[i]&127)<<24|s[i+1]<<16|s[i+2]<<8|s[i+3];return String(a%10**r).padStart(r,"0")}function I$(e,t=Date.now()){let r=BigInt(Math.floor(t/1e3/e.period));return Qse(e.key,r,e.digits,e.algorithm)}function O$(e,t=Date.now()){let r=Math.floor(t/1e3)%e.period;return e.period-r}var Yr={maxRecords:200,maxLabel:80,maxUsername:254,maxPassword:1024,maxTotp:512};function Vu(){return M$.join(iie(),".kynver","site-logins")}function o_(e){return`${Zse("sha256").update(`kynver-site-login:${e}`).digest("hex").slice(0,32)}.vault.json`}var J=class extends Error{constructor(r,n){super(r);this.code=n;this.name="SiteLoginError"}code},L$=/[\u0000-\u001f\u007f]/;function N$(e,t,r,n=!0){let o=typeof e=="string"?e.trim():"";if(!o&&n)throw new J(`${t} is required`,"invalid");if(o.length>r)throw new J(`${t} is too long (max ${r})`,"invalid");if(L$.test(o))throw new J(`${t} contains control characters`,"invalid");return o}var dh=class{constructor(t){this.opts=t;let r=t.agentOsId.trim();if(!r||L$.test(r)||r.length>200)throw new J("invalid workspace id","invalid");this.agentOsId=r,this.rootDir=t.rootDir??Vu(),this.filePath=M$.join(this.rootDir,o_(r)),this.now=t.now??Date.now}opts;agentOsId;filePath;rootDir;now;exists(){return eie(this.filePath)}keyMode(){return this.exists()?this.read().keyMode:null}async createWithPassphrase(t){if(this.exists())throw new J("a saved-login vault already exists on this computer","exists");if(t.length<Xc)throw new J(`the vault passphrase must be at least ${Xc} characters`,"invalid");let r=uD(),n=dD(this.opts.scryptCost),o=await IR(t,n,this.opts.minScryptN);return this.write({v:1,agentOsId:this.agentOsId,keyMode:"passphrase",kdf:n,wrappedKey:wo(o,r,TR(this.agentOsId)),keyCheck:wo(r,Nf,Tf(this.agentOsId)),records:[]}),o.fill(0),r}createWithKeychainKey(t){if(this.exists())throw new J("a saved-login vault already exists on this computer","exists");this.write({v:1,agentOsId:this.agentOsId,keyMode:"keychain",keyCheck:wo(t,Nf,Tf(this.agentOsId)),records:[]})}async unlockWithPassphrase(t){let r=this.read();if(r.keyMode!=="passphrase"||!r.kdf||!r.wrappedKey)throw new J("this vault is unlocked by the Kynver desktop app, not a passphrase","invalid");let n=null;try{n=await IR(t,r.kdf,this.opts.minScryptN);let o=$s(n,r.wrappedKey,TR(this.agentOsId));return this.verifyKey(r,o),o}catch(o){throw o instanceof J?o:o instanceof hr&&/unsafe|salt/.test(o.message)?new J(o.message,"corrupt"):new J("wrong vault passphrase","bad_key")}finally{n?.fill(0)}}unlockWithKey(t){return this.verifyKey(this.read(),t),t}wipe(){return this.exists()?(oie(this.filePath,{force:!0}),!0):!1}list(){return this.exists()?this.read().records.map(({secret:t,...r})=>r):[]}get(t){return this.list().find(r=>r.handle===t)??null}add(t,r){let n=this.read();if(this.verifyKey(n,t),n.records.length>=Yr.maxRecords)throw new J(`at most ${Yr.maxRecords} saved logins per workspace`,"full");let o=this.buildRecord(t,r,aie(),new Date(this.now()).toISOString());n.records.push(o),this.write(n);let{secret:s,...i}=o;return i}replace(t,r,n){let o=this.read();this.verifyKey(o,t);let s=o.records.findIndex(c=>c.handle===r);if(s<0)throw new J("no saved login with that id","not_found");let i=this.buildRecord(t,n,r,o.records[s].createdAt);o.records[s]=i,this.write(o);let{secret:a,...l}=i;return l}remove(t){if(!this.exists())return!1;let r=this.read(),n=r.records.filter(o=>o.handle!==t);return n.length===r.records.length?!1:(r.records=n,this.write(r),!0)}readSecret(t,r){let n=this.read();this.verifyKey(n,t);let o=n.records.find(i=>i.handle===r);if(!o)throw new J("no saved login with that id","not_found");let s;try{s=$s(t,o.secret,NR({agentOsId:this.agentOsId,...o}))}catch{throw new J("this saved login failed its integrity check and was not used","corrupt")}try{let i=JSON.parse(s.toString("utf8"));if(typeof i.p!="string")throw new Error("shape");let{secret:a,...l}=o;return{summary:l,secret:{password:i.p,...typeof i.t=="string"?{totp:i.t}:{}}}}catch{throw new J("this saved login failed its integrity check and was not used","corrupt")}finally{s.fill(0)}}touch(t){let r=this.read(),n=r.records.find(o=>o.handle===t);n&&(n.lastUsedAt=new Date(this.now()).toISOString(),this.write(r))}buildRecord(t,r,n,o){let s=A$(r.origin,{allowLan:r.allowLan===!0});if(!s.ok)throw new J(s.reason,"invalid");let i=N$(r.label,"label",Yr.maxLabel),a=N$(r.username,"username",Yr.maxUsername),l=typeof r.password=="string"?r.password:"";if(!l)throw new J("password is required","invalid");if(l.length>Yr.maxPassword)throw new J("password is too long","invalid");let c=typeof r.totp=="string"&&r.totp.trim()?r.totp.trim():void 0;if(c&&(c.length>Yr.maxTotp||!uh(c)))throw new J("the authenticator key is not a valid base32 secret or otpauth://totp link","invalid");let u={handle:n,origin:s.origin,label:i,username:a,hasTotp:!!c,createdAt:o,lastUsedAt:null},d=Buffer.from(JSON.stringify(c?{p:l,t:c}:{p:l}),"utf8");try{return{...u,secret:wo(t,d,NR({agentOsId:this.agentOsId,...u}))}}finally{d.fill(0)}}verifyKey(t,r){try{let n=$s(r,t.keyCheck,Tf(this.agentOsId));if(!pD(n,Nf))throw new Error("mismatch")}catch{throw new J("the vault key does not open this vault","bad_key")}}read(){if(!this.exists())throw new J("no saved-login vault on this computer yet","missing");let t;try{t=JSON.parse(rie(this.filePath,"utf8"))}catch{throw new J("the saved-login vault file is unreadable","corrupt")}if(!t||t.v!==1||t.keyMode!=="passphrase"&&t.keyMode!=="keychain"||!t.keyCheck||!Array.isArray(t.records))throw new J("the saved-login vault file is not a vault Kynver understands","corrupt");if(t.agentOsId!==this.agentOsId)throw new J("this saved-login vault belongs to a different workspace","corrupt");return t.records=t.records.filter(r=>r&&typeof r.handle=="string"&&typeof r.origin=="string"&&typeof r.label=="string"&&typeof r.username=="string"&&r.secret&&typeof r.secret.n=="string"&&typeof r.secret.c=="string"),t}write(t){tie(this.rootDir,{recursive:!0,mode:448});try{T$(this.rootDir,448)}catch{}let r=`${this.filePath}.${D$(4).toString("hex")}.tmp`;sie(r,`${JSON.stringify(t)}
233
233
  `,{mode:384}),nie(r,this.filePath);try{T$(this.filePath,384)}catch{}}};function aie(){let e="abcdefghijkmnpqrstuvwxyz23456789",t=D$(10);return`lg_${Array.from(t,r=>e[r%e.length]).join("")}`}var gie=512*1024,$$=1e3,hie=10080*60*1e3,ph=class{constructor(t,r=Vu(),n=Date.now){this.rootDir=r;this.now=n;this.filePath=fie.join(r,o_(t).replace(/\.vault\.json$/,".audit.jsonl"))}rootDir;now;filePath;record(t){let r={at:new Date(this.now()).toISOString(),...t};try{uie(this.rootDir,{recursive:!0,mode:448}),this.rotateIfLarge(),lie(this.filePath,`${JSON.stringify(r)}
234
234
  `,{mode:384}),cie(this.filePath,384)}catch{}return r}entries(t=$$){if(!B$(this.filePath))return[];try{return U$(this.filePath,"utf8").split(`
235
235
  `).filter(Boolean).slice(-t).map(n=>{try{return JSON.parse(n)}catch{return null}}).filter(n=>n!==null)}catch{return[]}}lastFill(){let t=this.entries().filter(r=>r.event==="fill");return t[t.length-1]??null}originRefusalsSince(t=hie){let r=this.now()-t;return this.entries().filter(n=>n.event==="fill"&&n.code==="origin_mismatch"&&Date.parse(n.at)>=r).length}rotateIfLarge(){if(!B$(this.filePath)||pie(this.filePath).size<gie)return;let t=U$(this.filePath,"utf8").split(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kynver-app/runtime",
3
- "version": "0.2.143",
3
+ "version": "0.2.144",
4
4
  "description": "Kynver AgentOS local execution runtime and CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",