@linzumi/cli 1.0.193 → 1.0.195
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/README.md +1 -1
- package/dist/impl-res/cloud-supervisor.mjs +1 -1
- package/dist/impl-res/index.js +131 -131
- package/dist/impl-ts/cloud-supervisor.mjs +1 -1
- package/dist/impl-ts/index.js +478 -478
- package/package.json +1 -1
- package/scripts/differentialMutations.mjs +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ var br=Object.create;var Pn=Object.defineProperty;var vr=Object.getOwnPropertyDe
|
|
|
12
12
|
`);function er(){return["-c",'mcp_oauth_credentials_store="file"',"-c",'cli_auth_credentials_store="file"']}var Cs=5*6e4;var Ts=(()=>{let e=process.env.LINZUMI_CODEX_WS_KEEPALIVE_MS;if(e===void 0)return 2e4;let n=Number.parseInt(e,10);return Number.isInteger(n)&&n>0?n:2e4})();function As(e){let n=e;if(typeof n.ping=="function"&&n.readyState===WebSocket.OPEN)try{n.ping()}catch{}}function rr(e,n={}){return["app-server",...Fs(n),"--listen",e]}var Is=["-c","features.apps=false"],Rs="LINZUMI_CODEX_STREAM_IDLE_TIMEOUT_MS",Ms="LINZUMI_CODEX_STREAM_IDLE_TIMEOUT_SOURCE",js=5e3,Ns=6e5,Js=["flag","env","server_default"];function $s(e){return Js.find(n=>n===e)}function Ls(e){let n=e?.trim();if(e===void 0||n===void 0||n==="")return{state:"unset"};if(!/^[0-9]+$/.test(n))return{state:"invalid",raw:e};let t=Number(n);return!Number.isSafeInteger(t)||t<js||t>Ns?{state:"invalid",raw:e}:{state:"applied",timeoutMs:t}}function Ds(e=process.env){let n=Ls(e[Rs]);if(n.state==="unset")return n;let t=$s(e[Ms]?.trim())??"env";return{...n,source:t}}function Us(e=process.env){let n=Ds(e);return n.state==="applied"?n.timeoutMs:void 0}var or="openai-linzumi";function sr(){let e=or;return["-c",`model_providers.${e}.name="OpenAI"`,"-c",`model_providers.${e}.wire_api="responses"`,"-c",`model_providers.${e}.requires_openai_auth=true`,"-c",`model_providers.${e}.supports_websockets=true`]}function zs(e){let n=or;return[...sr(),"-c",`model_providers.${n}.stream_idle_timeout_ms=${e}`,"-c",`model_provider="${n}"`]}function Fs(e,n=process.env){let t=Us(n);return[...Is,...er(),...e.model===void 0?[]:["-c",`model=${JSON.stringify(e.model)}`],...e.reasoningEffort===void 0?[]:["-c",`model_reasoning_effort=${JSON.stringify(e.reasoningEffort)}`],...e.fast===!0?["-c",`service_tier=${JSON.stringify("fast")}`]:[],...(e.mcpServers??[]).flatMap(r=>yn(r,{neverEquivalentGranularApprovalPolicy:e.neverEquivalentGranularApprovalPolicy===!0})),...e.modelProvider===void 0?t===void 0?sr():zs(t):qs(e.modelProvider,t)]}function qs(e,n){return["-c",`model_providers.${e.id}.name=${JSON.stringify(e.name)}`,"-c",`model_providers.${e.id}.base_url=${JSON.stringify(e.baseUrl)}`,"-c",`model_providers.${e.id}.env_key=${JSON.stringify(e.envKey)}`,"-c",`model_providers.${e.id}.wire_api=${JSON.stringify(e.wireApi)}`,...Object.entries(e.httpHeaders??{}).flatMap(([t,r])=>["-c",`model_providers.${e.id}.http_headers.${t}=${JSON.stringify(r)}`]),...Object.entries(e.envHttpHeaders??{}).flatMap(([t,r])=>["-c",`model_providers.${e.id}.env_http_headers.${t}=${JSON.stringify(r)}`]),...n===void 0?[]:["-c",`model_providers.${e.id}.stream_idle_timeout_ms=${n}`],"-c",`model_provider=${JSON.stringify(e.id)}`]}async function ir(e,n=t=>new fn.default(t)){let t=await Hs(e,n),r=new Map,o=new Set,s=new Set,i=[],a=new Set,d={nextId:1,closeError:void 0},c=u=>{let m=new Error(u);r.forEach(l=>l.reject(m)),r.clear()},f=setInterval(()=>As(t),Ts);f.unref?.();let p=u=>{if(clearInterval(f),c(u),d.closeError===void 0){d.closeError=new Error(u);for(let m of a)tr(m,d.closeError);a.clear()}};return t.addEventListener("close",()=>p("codex app-server websocket closed")),t.addEventListener("error",()=>p("codex app-server websocket closed")),t.addEventListener("message",u=>{let m=String(u.data),l=Ws(m);if(l===void 0){Vs(m);return}if(we({direction:"codex_to_commander",captureKind:Gs(l),message:l,rawText:m}),"id"in l&&("result"in l||"error"in l)){let x=r.get(l.id);x!==void 0&&(r.delete(l.id),x.resolve(l));return}if("id"in l&&typeof l.method=="string"){Qs(t,l,s);return}if(!("id"in l)&&typeof l.method=="string"){let x=l;o.size===0?i.push(x):o.forEach(P=>nr(P,x))}}),await Xs(t,r),{request:(u,m)=>{let l=d.nextId;return d.nextId+=1,ar(t,r,m===void 0?{jsonrpc:"2.0",id:l,method:u}:{jsonrpc:"2.0",id:l,method:u,params:m})},notify:(u,m)=>{let l=m===void 0?{jsonrpc:"2.0",method:u}:{jsonrpc:"2.0",method:u,params:m};we({direction:"commander_to_codex",captureKind:"outgoing",message:l,rawText:JSON.stringify(l)}),t.send(JSON.stringify(l))},onNotification:u=>{o.add(u),i.splice(0).forEach(m=>nr(u,m))},onRequest:u=>{s.add(u)},onClose:u=>{if(d.closeError!==void 0){tr(u,d.closeError);return}a.add(u)},isClosed:()=>d.closeError!==void 0,close:()=>{clearInterval(f),t.close()}}}function we(e){gn()&&hn({provider:"codex-app-server",captureKind:e.captureKind,rawText:e.rawText,rawValue:{message:e.message},captureMetadata:{direction:e.direction,capturedAtMs:Date.now(),capturePid:process.pid,...Bs(e.message),...e.extraMetadata??{}}})}function Vs(e){gn()&&hn({provider:"codex-app-server",captureKind:"incoming",rawText:e,captureMetadata:{direction:"codex_to_commander",capturedAtMs:Date.now(),capturePid:process.pid,malformed:!0}})}function Bs(e){return!("params"in e)||!J(e.params)?{}:It(e.params)}function Gs(e){return"id"in e&&("result"in e||"error"in e)?"response":"id"in e&&typeof e.method=="string"?"request":"notification"}function Ws(e){let n=String(e);try{let t=JSON.parse(n);if(!J(t))throw new Error("codex app-server sent non-object JSON-RPC message");return t}catch(t){ce("codex.app_server_frame_malformed",{purpose:"codex.app_server",message:t instanceof Error?t.message:String(t),payload:Ht(n,512),payloadChars:n.length});return}}function nr(e,n){try{e(n)}catch(t){ce("codex.notification_callback_failed",{purpose:"codex.app_server",method:n.method,message:t instanceof Error?t.message:String(t)})}}function tr(e,n){try{e(n)}catch(t){ce("codex.close_callback_failed",{purpose:"codex.app_server",message:t instanceof Error?t.message:String(t)})}}async function Hs(e,n,t=2e3){let r=Date.now()+t,o;for(;Date.now()<=r;){let s=n(e);try{return await Ys(s),s}catch(i){o=i instanceof Error?i:new Error(String(i)),Ks(s)}}throw o??new Error("websocket open failed")}function Ks(e){try{e.close()}catch{}}async function Qs(e,n,t){let r=o=>Zs(e,o,n.method);try{if(t.size===0){r({jsonrpc:"2.0",id:n.id,error:{code:-32601,message:`unhandled Codex app-server request: ${n.method}`}});return}for(let o of t){let s=await o(n);if(s!==void 0){r({jsonrpc:"2.0",id:n.id,result:s});return}}r({jsonrpc:"2.0",id:n.id,error:{code:-32601,message:`unhandled Codex app-server request: ${n.method}`}})}catch(o){r({jsonrpc:"2.0",id:n.id,error:{code:-32e3,message:o instanceof Error?o.message:String(o)}})}}function Zs(e,n,t){let r=JSON.stringify(n);we({direction:"commander_to_codex",captureKind:"response",message:n,rawText:r,extraMetadata:{requestMethod:t}}),e.send(r)}async function Xs(e,n){let t=await ar(e,n,{jsonrpc:"2.0",id:"initialize",method:"initialize",params:{clientInfo:{name:"kandan-local-codex-runner",version:"0.0.1"},capabilities:{experimentalApi:!0}}});if("error"in t)throw new Error(`codex initialize failed: ${t.error.message}`);let r={jsonrpc:"2.0",method:"initialized"};we({direction:"commander_to_codex",captureKind:"outgoing",message:r,rawText:JSON.stringify(r)}),e.send(JSON.stringify(r))}function ar(e,n,t){return e.readyState!==WebSocket.OPEN?Promise.reject(new Error("codex app-server websocket is not open")):new Promise((r,o)=>{n.set(t.id,{resolve:r,reject:o}),we({direction:"commander_to_codex",captureKind:"request",message:t,rawText:JSON.stringify(t)}),e.send(JSON.stringify(t))})}function Ys(e){return new Promise((n,t)=>{e.addEventListener("open",()=>n(),{once:!0}),e.addEventListener("error",()=>t(new Error("websocket open failed")),{once:!0})})}var Sd=300*1e3;function De(e){let n=new URL(e);switch(n.protocol){case"ws:":n.protocol="http:";break;case"wss:":n.protocol="https:";break;case"http:":case"https:":break;default:throw new Error("--api-url must be ws://, wss://, http://, or https://")}return n.pathname="",n.search="",n.hash="",n.toString().replace(/\/$/,"")}function _n(e){let n=e.fetchImpl??fetch,t=De(e.kandanUrl),r=e.authMode==="personal-agent-delegation"?"/api/v2/personal-agent-mcp":"/api/v2/local-runner-mcp",o=e.operatingMode??"text",s=async(i,a,d,c={})=>{let f=new URL(a,t),p={...d,operating_mode:o},y={method:i,headers:{authorization:`Bearer ${e.accessToken}`},...c.signal===void 0?{}:{signal:c.signal}};if(i==="GET")for(let[M,$]of Object.entries(p))$!=null&&f.searchParams.set(M,String($));else y.headers={...y.headers,"content-type":"application/json"},y.body=JSON.stringify(p);let u=await n(f,y),m=await u.json(),l=J(m)?m:void 0;if(l===void 0)throw new Error(`Linzumi MCP API returned non-object JSON from ${a}`);if(u.ok&&l.ok===!0)return l;let x=typeof l.error=="string"?l.error:`HTTP ${u.status}`,P=typeof l.detail=="string"?l.detail:void 0;throw new Error(`Linzumi MCP API ${a} failed: ${x}${P===void 0?"":` detail=${P}`}`)};return{validateAuth:()=>s("GET",`${r}/validate`,{}),issueOnboardingDiscoveryToken:i=>s("POST",`${r}/onboarding-discovery-token`,i),getMessage:i=>s("GET",`${r}/message`,i),getThread:i=>s("GET",`${r}/thread`,i),getThreadTranscript:i=>s("GET",`${r}/thread-transcript`,i),getChannel:i=>s("GET",`${r}/channel`,i),searchWorkspace:i=>s("GET",`${r}/search`,i),askWorkspace:i=>s("POST",`${r}/ask`,i),aboutMe:i=>s("GET",`${r}/about-me`,i),webSearch:i=>s("GET",`${r}/web-search`,i),fetchUrl:i=>s("GET",`${r}/fetch-url`,i),listUiTargets:i=>s("GET",`${r}/ui-targets`,i),openUi:i=>s("POST",`${r}/open-ui`,i),getCodingJobMetadata:i=>s("GET",`${r}/coding-job-metadata`,i),listProjects:i=>s("GET",`${r}/projects`,i),getProjectTasks:i=>s("GET",`${r}/project-tasks`,i),createProjectTask:i=>s("POST",`${r}/project-tasks/create`,i),updateProjectTask:i=>s("POST",`${r}/project-tasks/update`,i),deleteProjectTask:i=>s("POST",`${r}/project-tasks/delete`,i),addProjectTaskDependency:i=>s("POST",`${r}/project-tasks/add-dependency`,i),removeProjectTaskDependency:i=>s("POST",`${r}/project-tasks/remove-dependency`,i),getCallTranscript:i=>s("GET",`${r}/call-transcript`,i),renameCodingJob:i=>s("POST",`${r}/coding-job-title`,i),upsertCodingJobPlan:(i,a)=>s("POST",`${r}/coding-job-plan`,i,a),replaceCodingJobPlanSteps:i=>s("POST",`${r}/coding-job-plan/steps`,i),updateCodingJobPlanStep:i=>s("POST",`${r}/coding-job-plan/step`,i),linkCodingJobPullRequest:i=>s("POST",`${r}/coding-job-primary-pr`,i),listVaultSecrets:i=>s("GET",`${r}/vault-secrets`,i),noteProjectDirectory:i=>s("POST",`${r}/discovered-project`,i),noteAgentConversation:i=>s("POST",`${r}/discovered-conversation`,i),noteOnboardingDiscoveryStatus:i=>s("POST",`${r}/discovery-status`,i),sendChannelMessage:i=>s("POST",`${r}/channel-message`,i),editMessage:i=>s("POST",`${r}/message/edit`,i),agentReply:i=>s("POST",`${r}/agent-reply`,i),agentTurnProgress:i=>s("POST",`${r}/agent-turn-progress`,i),agentDocumentTool:i=>s("POST",`${r}/agent/document-tool`,i),agentListCodingJobs:i=>s("GET",`${r}/agent/coding-jobs`,i),agentStartCodingJob:i=>s("POST",`${r}/agent/start-coding-job`,i),agentSpawnChildJob:i=>s("POST",`${r}/agent/spawn-child-job`,i),agentInterruptCodingJob:i=>s("POST",`${r}/agent/interrupt-coding-job`,i),agentSendCodingJobMessage:i=>s("POST",`${r}/agent/send-coding-job-message`,i),agentDiscoverCodingJobs:i=>s("GET",`${r}/agent/discover-coding-jobs`,i),agentReadCodingJobThread:i=>s("GET",`${r}/agent/coding-job-thread`,i),agentResolveJobApproval:i=>s("POST",`${r}/agent/resolve-job-approval`,i),agentArchiveCodingJob:i=>s("POST",`${r}/agent/archive-coding-job`,i),agentUnarchiveCodingJob:i=>s("POST",`${r}/agent/unarchive-coding-job`,i),agentSetThreadStatus:i=>s("POST",`${r}/agent/set-thread-status`,i),agentCreateChannel:i=>s("POST",`${r}/agent/create-channel`,i),agentRenameChannel:i=>s("POST",`${r}/agent/rename-channel`,i),agentArchiveChannel:i=>s("POST",`${r}/agent/archive-channel`,i),agentUnarchiveChannel:i=>s("POST",`${r}/agent/unarchive-channel`,i),agentAddReaction:i=>s("POST",`${r}/agent/add-reaction`,i),agentRemoveReaction:i=>s("POST",`${r}/agent/remove-reaction`,i),agentPinMessage:i=>s("POST",`${r}/agent/pin-message`,i),agentUnpinMessage:i=>s("POST",`${r}/agent/unpin-message`,i),prepareMessageUploads:i=>s("POST",`${r}/message-uploads/prepare`,i),attachMessageFiles:i=>s("POST",`${r}/message-files/attach`,i),prepareCustomEmoji:i=>s("POST",`${r}/custom-emoji/prepare`,i),renameCustomEmoji:i=>s("POST",`${r}/custom-emoji/rename`,i),sendThreadReply:i=>s("POST",`${r}/thread-reply`,i),sendDm:i=>s("POST",`${r}/dm`,i),dmOwner:i=>s("POST",`${r}/dm-owner`,i),getVaultValues:i=>s("POST",`${r}/vault-values`,i)}}import{existsSync as ei,mkdirSync as Od,readFileSync as ni,renameSync as Td,rmSync as Ad,writeFileSync as Id}from"node:fs";import{homedir as ti}from"node:os";import{dirname as jd,join as ri}from"node:path";function oi(){return ri(ti(),".linzumi","auth.json")}function xn(e,n=oi()){if(!ei(n))return;let t=si(ni(n,"utf8")),r=De(e),o=t.local_codex_runner?.[r];if(!(o===void 0||o.access_token.trim()==="")&&!(o.expires_at!==void 0&&Date.parse(o.expires_at)<=Date.now()))return{accessToken:o.access_token,kandanBaseUrl:r,issuedAt:o.issued_at,expiresAt:o.expires_at}}function si(e){let n=JSON.parse(e);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("Kandan auth cache must contain a JSON object");let t=n,r=t.local_codex_runner,o=t.personal_agent_delegation;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new Error("Kandan auth cache local_codex_runner must be an object");if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))throw new Error("Kandan auth cache personal_agent_delegation must be an object");return{version:1,local_codex_runner:ai(r),personal_agent_delegation:ii(o)}}function ii(e){if(typeof e!="object"||e===null||Array.isArray(e))return;let n=e.access_token,t=e.issued_at,r=e.expires_at;if(!(typeof n!="string"||typeof t!="string"))return{access_token:n,issued_at:t,expires_at:typeof r=="string"?r:void 0}}function ai(e){if(!(typeof e!="object"||e===null||Array.isArray(e)))return Object.fromEntries(Object.entries(e).flatMap(([n,t])=>{if(typeof t!="object"||t===null||Array.isArray(t))return[];let r=t.access_token,o=t.issued_at,s=t.expires_at;return typeof r!="string"||typeof o!="string"?[]:[[n,{access_token:r,issued_at:o,expires_at:typeof s=="string"?s:void 0}]]}))}var bn={mcpAuthFileContents:"LINZUMI_CLOUD_MCP_AUTH_JSON",llmProxyToken:"LINZUMI_CLOUD_LLM_PROXY_TOKEN"};function dr(e){let n;try{n=JSON.parse(Buffer.from(e,"base64").toString("utf8"))}catch{throw new Error("invalid guest cloud turn config payload (not base64 JSON)")}if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("invalid guest cloud turn config payload");let t=n;for(let[r,o]of[["codexVersion",t.codexVersion],["sandbox",t.sandbox],["approvalPolicy",t.approvalPolicy],["kandanUrl",t.kandanUrl],["cwd",t.cwd]])if(typeof o!="string"||o==="")throw new Error(`invalid guest cloud turn config payload (${r} missing)`);if(!Array.isArray(t.input))throw new Error("invalid guest cloud turn config payload (input)");if(typeof t.appServerPort!="number"||!Number.isInteger(t.appServerPort))throw new Error("invalid guest cloud turn config payload (appServerPort)");return t}var ne="/home/agent",di=`${ne}/.linzumi-provisioned`;var vn="/dev/shm/linzumi",Kd=`${vn}/codex`,Qd=`${vn}/mcp-auth.json`;var Zd=`${vn}/codex.env`;var tc=`${ne}/cloud-supervisor.mjs`,cr=`${ne}/mcp-server.mjs`,Sn=`${ne}/.secrets`,wn=`${Sn}/mcp-auth.json`,Ue=`${ne}/.codex`,lr=`${Ue}/linzumi-thread-map.json`;var kn=`${ne}/.turn-heartbeats`,ur=5e3,ci=/^[A-Za-z0-9-]{8,64}$/;function En(e){if(!ci.test(e))throw new Error(`invalid cloud turn nonce: ${JSON.stringify(e.slice(0,80))}`)}var hi=3e4,yi=200;function le(e){return e.replace(/\bsmk_[A-Za-z0-9._-]+/g,"smk_[REDACTED]").replace(/\b(sk|lz|tok|bearer)[-_][A-Za-z0-9._-]{8,}/gi,"$1_[REDACTED]")}var Fe;function _i(e){Fe=e;try{ue(mr(e),{recursive:!0}),ke(e,"")}catch{Fe=void 0}}function z(e){let n=`${JSON.stringify(e)}
|
|
13
13
|
`;if(process.stdout.write(n),Fe!==void 0)try{ui(Fe,n)}catch{}}function ze(e,n,t){z({phase:"exit",ok:e,reason:le(n),turnMs:t})}function xi(e){return{id:e.id,name:e.name,baseUrl:e.baseUrl,envKey:e.envKey,wireApi:e.wireApi,...e.httpHeaders===void 0?{}:{httpHeaders:{...e.httpHeaders}},...e.envHttpHeaders===void 0?{}:{envHttpHeaders:{...e.envHttpHeaders}}}}function bi(e){if(e.sandbox!=="danger-full-access")throw new Error(`guest cloud turn requires sandbox "danger-full-access", got ${JSON.stringify(e.sandbox)}`);if(e.approvalPolicy!=="never")throw new Error(`guest cloud turn requires approvalPolicy "never", got ${JSON.stringify(e.approvalPolicy)}`)}function vi(e,n=Ue){let t=Xt({command:"node",argsPrefix:[cr],kandanUrl:e.kandanUrl,authFilePath:wn,ownerUsername:e.ownerUsername,operatingMode:"text",cwd:e.cwd,threadId:e.threadId,agentSession:!0});return rr(`ws://127.0.0.1:${e.appServerPort}`,{model:e.model,reasoningEffort:e.reasoningEffort,mcpServers:[t],neverEquivalentGranularApprovalPolicy:Vt(e.approvalPolicy,e.sandbox),...e.modelProvider===void 0?{}:{modelProvider:xi(e.modelProvider)},env:{CODEX_HOME:n,...gr(e)}})}function gr(e){let n=process.env[bn.llmProxyToken];return e.modelProvider===void 0||n===void 0||n===""?{}:{[e.modelProvider.envKey]:n}}function Si(e,n){let t=process.env[bn.mcpAuthFileContents];if(t===void 0||t==="")throw new Error("guest cloud turn missing MCP auth-cache (LINZUMI_CLOUD_MCP_AUTH_JSON)");ue(e,{recursive:!0,mode:448}),fr(e,448),ke(n,t,{mode:384}),fr(n,384)}function wi(e){try{pr(e,{recursive:!0,force:!0})}catch{}}var ki=64;function hr(e){try{let n=JSON.parse(fi(e,"utf8"));if(typeof n!="object"||n===null||Array.isArray(n))return{};let t={};for(let[r,o]of Object.entries(n))typeof o=="string"&&o!==""&&(t[r]=o);return t}catch{return{}}}function Ei(e,n,t){try{let r=hr(e);delete r[n];let o=Object.entries(r),s=o.slice(Math.max(0,o.length-(ki-1)));s.push([n,t]),ue(mr(e),{recursive:!0}),ke(e,JSON.stringify(Object.fromEntries(s)))}catch{}}var Pi=new Set(["turn/completed","turn/failed","turn/aborted"]),Ci=2e3;function yr(e){let n=T(T(e)?.item);if(n===void 0||_(n.type)!=="agentMessage")return"";let t=_(n.text);return t!==void 0&&t!==""?t:(Le(n.content)??[]).map(s=>{let i=T(s);if(i===void 0)return;let a=_(i.type);if(!(a!=="text"&&a!=="output_text"&&a!=="input_text"))return _(i.text)??_(i.content)}).filter(s=>s!==void 0&&s!=="").join(`
|
|
14
14
|
|
|
15
|
-
`)}function Oi(e){let n=T(T(e)?.item);if(n===void 0)return!1;let t=_(n.type);if(t!=="mcpToolCall"&&t!=="dynamicToolCall"&&t!=="collabAgentToolCall"||_(n.status)!=="completed"||n.error!==void 0&&n.error!==null||n.success===!1)return!1;let r=_(n.tool)??"";return(r.split("__").pop()??r)==="linzumi_agent_reply"}var Ti=15e3;function Ai(e){return/already_replied|no_active_asker_binding/i.test(e)}async function Ii(e){let n=e.body.trim();if(n==="")return"skipped";let t=xn(e.kandanUrl,e.mcpAuthPath);if(t===void 0)throw new Error("reply relay: no agent token in the guest MCP auth file");let r=async(s,i)=>{let a=new AbortController,d=setTimeout(()=>a.abort(),Ti);try{return await fetch(s,{...i,signal:a.signal})}finally{clearTimeout(d)}},o=_n({kandanUrl:e.kandanUrl,accessToken:t.accessToken,operatingMode:"text",fetchImpl:r});try{return await o.agentReply({body:n}),"posted"}catch(s){let i=s instanceof Error?s.message:String(s);if(Ai(i))return"already";throw new Error(`reply relay failed: ${i}`)}}var Ri=900,Mi=1e4,ji=3,Ni=8e3;function Ji(e){return/\bHTTP 4\d\d\b/.test(e)||/\b(forbidden|not_agent_session|no_active_asker_binding|invalid_agent_turn_progress_request|body_required|already_replied)\b/i.test(e)}function $i(e){return async n=>{let t=xn(e.kandanUrl,e.mcpAuthPath);if(t===void 0)throw new Error("turn progress: no agent token in the guest MCP auth file");let r=async(s,i)=>{let a=new AbortController,d=setTimeout(()=>a.abort(),Mi);try{return await fetch(s,{...i,signal:a.signal})}finally{clearTimeout(d)}};return _n({kandanUrl:e.kandanUrl,accessToken:t.accessToken,operatingMode:"text",fetchImpl:r}).agentTurnProgress(n)}}function Li(e){let n=Date.now,t=e.flushIntervalMs??Ri,r=e.log??z,o=e.post??$i({kandanUrl:e.kandanUrl,mcpAuthPath:e.mcpAuthPath}),s=new Map,i=!1,a=0,d=0,c,f,p=!1,y=!1,u=(v,h)=>{let S=s.get(v);if(S!==void 0)return S;let k={kind:h,text:"",snapshotIndex:0,state:"streaming",dirty:!1,lastFlushMs:0,ackedState:void 0};return s.set(v,k),k},m=v=>v.state==="streaming"?v.lastFlushMs+t:0,l=async(v,h)=>{let S=h.text,k=h.state;h.dirty=!1,h.snapshotIndex+=1,h.lastFlushMs=n();try{return await o({stream_key:`${e.streamKeyPrefix}:${v}`,item_id:v,kind:h.kind,body:S,stream_state:k,snapshot_index:h.snapshotIndex,...e.sourceSeq===void 0?{}:{source_seq:e.sourceSeq}}),d+=1,a=0,h.ackedState=k,!0}catch(b){a+=1;let w=b instanceof Error?b.message:String(b);return Ji(w)?(y=!0,i=!0,r({phase:"progress",outcome:"permanent_reject",message:le(w)}),!1):(r({phase:"progress",outcome:"post_failed",consecutive_failures:a,message:le(w)}),a>=ji&&(i=!0,r({phase:"progress",outcome:"disabled"})),!1)}},x=async()=>{for(;;){if(i)return;let v=n(),h,S=!1;for(let[k,b]of s){if(!b.dirty||b.text==="")continue;let w=m(b);w<=v?(await l(k,b),S=!0):h=h===void 0?w:Math.min(h,w)}if(!S){h!==void 0&&(clearTimeout(f),f=setTimeout(P,Math.max(10,h-n())),f.unref?.());return}}};function P(){i||p||c!==void 0||(c=x().catch(()=>{}).finally(()=>{c=void 0}))}return{onNotification:v=>{try{let h=T(v.params)??{};if(v.method==="item/agentMessage/delta"){let S=Gt(h);if(S!==void 0){let k=u(S.itemKey,"codex_assistant_message");k.text+=S.delta,k.dirty=!0,P()}return}if(v.method==="item/reasoning/textDelta"){let S=Wt(h);if(S!==void 0){let k=u(S.itemKey,"codex_reasoning");k.text+=S.delta,k.dirty=!0,P()}return}if(v.method==="item/completed"){let S=T(h.item),k=_(S?.type),b=_(S?.id);if(b===void 0)return;if(k==="agentMessage"){let w=yr(v.params),g=u(b,"codex_assistant_message");w!==""&&(g.text=w),g.state="completed",g.dirty=!0,P()}else if(k==="reasoning"){let w=s.get(b);w!==void 0&&(w.state="completed",w.dirty=!0,P())}}}catch(h){r({phase:"progress",outcome:"notification_error",message:le(h instanceof Error?h.message:String(h))})}},finish:async v=>{try{let h=n()+(e.finishDeadlineMs??Ni),S=()=>new Promise(b=>setTimeout(b,Math.max(0,h-n())).unref?.());p=!0,clearTimeout(f),c!==void 0&&await Promise.race([c,S()]);for(let b of s.values())b.state==="streaming"&&b.text!==""&&(b.state=v);let k=250;for(;;){let b=[...s.entries()].filter(([,g])=>g.text!==""&&g.state!==g.ackedState);if(b.length===0||y||n()>=h)break;let w=!1;for(let[g,A]of b){if(y||n()>=h)break;await l(g,A)||(w=!0)}w&&!y&&n()<h&&await new Promise(g=>setTimeout(g,k))}r({phase:"progress",outcome:"finished",frames_posted:d,disabled:i})}catch(h){r({phase:"progress",outcome:"finish_error",message:le(h instanceof Error?h.message:String(h))})}}}}function Di(e){if(e==="item/commandExecution/requestApproval"||e==="item/fileChange/requestApproval")return{decision:"approved"}}async function Ui(e,n,t){for(;;){if(t.exitCode!==null&&t.exitCode!==void 0)throw new Error(`codex app-server exited before it accepted a connection (code ${t.exitCode})`);try{return await ir(e)}catch(r){if(Date.now()>=n)throw r;await new Promise(o=>setTimeout(o,yi))}}}var zi=360*60*1e3;function Fi(e,n){try{for(let t of pi(e))try{let r=qe(e,t);n-mi(r).mtimeMs>zi&&gi(r)}catch{}}catch{}}function qi(e,n,t=ur){En(n);let r=qe(e,`${n}.beat`),o=()=>{try{ke(r,`${Date.now()}
|
|
15
|
+
`)}function Oi(e){let n=T(T(e)?.item);if(n===void 0)return!1;let t=_(n.type);if(t!=="mcpToolCall"&&t!=="dynamicToolCall"&&t!=="collabAgentToolCall"||_(n.status)!=="completed"||n.error!==void 0&&n.error!==null||n.success===!1)return!1;let r=_(n.tool)??"";return(r.split("__").pop()??r)==="linzumi_agent_reply"}var Ti=15e3;function Ai(e){return/already_replied|no_active_asker_binding/i.test(e)}async function Ii(e){let n=e.body.trim();if(n==="")return"skipped";let t=xn(e.kandanUrl,e.mcpAuthPath);if(t===void 0)throw new Error("reply relay: no agent token in the guest MCP auth file");let r=async(s,i)=>{let a=new AbortController,d=setTimeout(()=>a.abort(),Ti);try{return await fetch(s,{...i,signal:a.signal})}finally{clearTimeout(d)}},o=_n({kandanUrl:e.kandanUrl,accessToken:t.accessToken,operatingMode:"text",fetchImpl:r});try{return await o.agentReply({body:n}),"posted"}catch(s){let i=s instanceof Error?s.message:String(s);if(Ai(i))return"already";throw new Error(`reply relay failed: ${i}`)}}var Ri=900,Mi=1e4,ji=3,Ni=8e3;function Ji(e){return/\bHTTP 4\d\d\b/.test(e)||/\b(forbidden|not_agent_session|no_active_asker_binding|invalid_agent_turn_progress_request|body_required|already_replied)\b/i.test(e)}function $i(e){return async n=>{let t=xn(e.kandanUrl,e.mcpAuthPath);if(t===void 0)throw new Error("turn progress: no agent token in the guest MCP auth file");let r=async(s,i)=>{let a=new AbortController,d=setTimeout(()=>a.abort(),Mi);try{return await fetch(s,{...i,signal:a.signal})}finally{clearTimeout(d)}};return _n({kandanUrl:e.kandanUrl,accessToken:t.accessToken,operatingMode:"text",fetchImpl:r}).agentTurnProgress(n)}}function Li(e){let n=Date.now,t=e.flushIntervalMs??Ri,r=e.log??z,o=e.post??$i({kandanUrl:e.kandanUrl,mcpAuthPath:e.mcpAuthPath}),s=new Map,i=!1,a=0,d=0,c,f,p=!1,y=!1,u=(v,h)=>{let S=s.get(v);if(S!==void 0)return S;let k={kind:h,text:"",snapshotIndex:0,state:"streaming",dirty:!1,lastFlushMs:0,ackedState:void 0};return s.set(v,k),k},m=v=>v.state==="streaming"?v.lastFlushMs+t:0,l=async(v,h)=>{let S=h.text,k=h.state;h.dirty=!1,h.snapshotIndex+=1,h.lastFlushMs=n();try{return await o({stream_key:`${e.streamKeyPrefix}:${v}`,item_id:v,kind:h.kind,body:S,stream_state:k,snapshot_index:h.snapshotIndex,...e.sourceSeq===void 0?{}:{source_seq:e.sourceSeq}}),d+=1,a=0,h.ackedState=k,!0}catch(b){a+=1;let w=b instanceof Error?b.message:String(b);return Ji(w)?(y=!0,i=!0,r({phase:"progress",outcome:"permanent_reject",message:le(w)}),!1):(r({phase:"progress",outcome:"post_failed",consecutive_failures:a,message:le(w)}),a>=ji&&(i=!0,r({phase:"progress",outcome:"disabled"})),!1)}},x=async()=>{for(;;){if(i)return;let v=n(),h,S=!1;for(let[k,b]of s){if(!b.dirty||b.text===""||b.state!=="streaming"&&!p)continue;let w=m(b);w<=v?(await l(k,b),S=!0):h=h===void 0?w:Math.min(h,w)}if(!S){h!==void 0&&(clearTimeout(f),f=setTimeout(P,Math.max(10,h-n())),f.unref?.());return}}};function P(){i||p||c!==void 0||(c=x().catch(()=>{}).finally(()=>{c=void 0}))}return{onNotification:v=>{try{let h=T(v.params)??{};if(v.method==="item/agentMessage/delta"){let S=Gt(h);if(S!==void 0){let k=u(S.itemKey,"codex_assistant_message");k.text+=S.delta,k.dirty=!0,P()}return}if(v.method==="item/reasoning/textDelta"){let S=Wt(h);if(S!==void 0){let k=u(S.itemKey,"codex_reasoning");k.text+=S.delta,k.dirty=!0,P()}return}if(v.method==="item/completed"){let S=T(h.item),k=_(S?.type),b=_(S?.id);if(b===void 0)return;if(k==="agentMessage"){let w=yr(v.params),g=u(b,"codex_assistant_message");w!==""&&(g.text=w),g.state="completed",g.dirty=!0,P()}else if(k==="reasoning"){let w=s.get(b);w!==void 0&&(w.state="completed",w.dirty=!0,P())}}}catch(h){r({phase:"progress",outcome:"notification_error",message:le(h instanceof Error?h.message:String(h))})}},finish:async v=>{try{let h=n()+(e.finishDeadlineMs??Ni),S=()=>new Promise(b=>setTimeout(b,Math.max(0,h-n())).unref?.());p=!0,clearTimeout(f),c!==void 0&&await Promise.race([c,S()]);for(let b of s.values())b.state==="streaming"&&b.text!==""&&(b.state=v);let k=250;for(;;){let b=[...s.entries()].filter(([,g])=>g.text!==""&&g.state!==g.ackedState);if(b.length===0||y||n()>=h)break;let w=!1;for(let[g,A]of b){if(y||n()>=h)break;await l(g,A)||(w=!0)}w&&!y&&n()<h&&await new Promise(g=>setTimeout(g,k))}r({phase:"progress",outcome:"finished",frames_posted:d,disabled:i})}catch(h){r({phase:"progress",outcome:"finish_error",message:le(h instanceof Error?h.message:String(h))})}}}}function Di(e){if(e==="item/commandExecution/requestApproval"||e==="item/fileChange/requestApproval")return{decision:"approved"}}async function Ui(e,n,t){for(;;){if(t.exitCode!==null&&t.exitCode!==void 0)throw new Error(`codex app-server exited before it accepted a connection (code ${t.exitCode})`);try{return await ir(e)}catch(r){if(Date.now()>=n)throw r;await new Promise(o=>setTimeout(o,yi))}}}var zi=360*60*1e3;function Fi(e,n){try{for(let t of pi(e))try{let r=qe(e,t);n-mi(r).mtimeMs>zi&&gi(r)}catch{}}catch{}}function qi(e,n,t=ur){En(n);let r=qe(e,`${n}.beat`),o=()=>{try{ke(r,`${Date.now()}
|
|
16
16
|
`)}catch{}};try{ue(e,{recursive:!0})}catch{}Fi(e,Date.now()),o();let s=setInterval(o,t);return s.unref?.(),()=>{clearInterval(s);try{pr(r,{force:!0})}catch{}}}function Vi(e,n,t){try{En(n),ue(e,{recursive:!0}),ke(qe(e,`${n}.exit`),`${JSON.stringify({phase:"exit",ok:t.ok,reason:le(t.reason),turnMs:t.turnMs})}
|
|
17
17
|
`)}catch{}}async function Bi(e,n={}){let t=n.now??Date.now,r=n.secretsDir??Sn,o=n.mcpAuthPath??wn,s=n.codexHome??Ue,i=n.threadMapPath??lr,a=t();bi(e);let d=e.turnNonce!==void 0&&e.turnNonce!==""?qi(n.heartbeatDir??kn,e.turnNonce,n.heartbeatIntervalMs):void 0,c,f=()=>{try{c?.pid!==void 0&&c.kill("SIGINT")}catch{}};try{Si(r,o);let p=vi(e,s),y=`ws://127.0.0.1:${e.appServerPort}`;n.spawnCodex===void 0&&ue(s,{recursive:!0,mode:448}),c=n.spawnCodex?n.spawnCodex(p):li("codex",p,{cwd:e.cwd,env:{PATH:process.env.PATH??"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",...process.env.HOME===void 0?{}:{HOME:process.env.HOME},CODEX_HOME:s,...gr(e)},stdio:["ignore","ignore","inherit"],detached:!1});let u=await Ui(y,a+hi,c);try{u.onRequest?.(g=>Di(g.method));let m=e.codexThreadId,l;if(m!==void 0&&m!==""){let g=hr(i)[m];g!==void 0&&("error"in await u.request("thread/resume",{threadId:g,...zt({cwd:e.cwd,channelSession:{model:e.model,reasoningEffort:e.reasoningEffort,approvalPolicy:e.approvalPolicy,sandbox:e.sandbox}})})||(l=g))}if(l===void 0){let g=await u.request("thread/start",{cwd:e.cwd,serviceName:"kandan-cloud-agent",personality:"pragmatic",approvalPolicy:e.approvalPolicy,...e.model===void 0?{}:{model:e.model},...e.sandbox===void 0?{}:{sandbox:e.sandbox}});if("error"in g)throw new Error(`thread/start failed: ${g.error.message}`);let A=_(T(T(g.result)?.thread)?.id);if(A===void 0)throw new Error("thread/start response did not include thread.id");l=A,m!==void 0&&m!==""&&Ei(i,m,l),z({phase:"thread",mode:"started"})}else z({phase:"thread",mode:"resumed"});let x="",P=!1,M=!1,$=Li({kandanUrl:e.kandanUrl,mcpAuthPath:o,streamKeyPrefix:e.turnNonce!==void 0&&e.turnNonce!==""?`cloud:${e.turnNonce}`:`cloud:${a}`,...e.sourceSeq===void 0?{}:{sourceSeq:e.sourceSeq},post:n.progressPost,flushIntervalMs:n.progressFlushIntervalMs,now:t}),v,h=new Promise((g,A)=>{v={resolve:g,reject:A}}),S=g=>{if(M){z({phase:"codex-exit",benign:!0});return}setTimeout(()=>{M||v?.reject(g())},n.postTerminalGraceMs??Ci).unref?.()};u.onNotification(g=>{if(z({phase:"notification",method:g.method}),$.onNotification(g),g.method==="item/completed"){let H=yr(g.params);H!==""&&(x=H),Oi(g.params)&&(P=!0)}if(!Pi.has(g.method))return;M=!0;let A=g.method==="turn/completed";v?.resolve({ok:A,reason:g.method==="turn/completed"?"turn completed":`turn terminal: ${g.method}`,turnMs:t()-a})}),u.onClose?.(g=>S(()=>new Error(`codex connection closed before a turn terminal: ${g?.message??"connection closed"}`))),c?.once("exit",g=>S(()=>new Error(`codex app-server process exited mid-turn (code ${g})`)));let k=await u.request("turn/start",{threadId:l,input:e.input,...Ft({cwd:e.cwd,channelSession:{model:e.model,reasoningEffort:e.reasoningEffort,approvalPolicy:e.approvalPolicy,sandbox:e.sandbox}})});if("error"in k)throw new Error(`turn/start failed: ${k.error.message}`);let b;try{b=await h}catch(g){throw await $.finish("failed"),g}let w=b;if(b.ok){let g=n.relayReply??Ii;try{let A=await g({kandanUrl:e.kandanUrl,mcpAuthPath:o,body:x});z({phase:"reply",relay:A,reply_tool_call_seen:P,captured_chars:x.length}),A==="skipped"&&!P&&(w={ok:!1,reason:"turn completed but no reply was posted: codex produced no visible output to relay and never called linzumi_agent_reply",turnMs:b.turnMs})}catch(A){let H=A instanceof Error?A.message:String(A);z({phase:"reply",relay:"failed",reason:H}),w={ok:!1,reason:H,turnMs:b.turnMs}}}return await $.finish(w.ok?"completed":"failed"),w}finally{u.close()}}finally{d?.(),f(),wi(r)}}async function _r(e=process.argv,n={}){let t=e[2];if(t==="--selftest")return z({phase:"selftest",ok:!0,node:process.version}),0;if(t===void 0||t==="")return ze(!1,"missing turn config argv[2]",0),1;let r;try{r=dr(t)}catch(a){return ze(!1,`config decode failed: ${a instanceof Error?a.message:String(a)}`,0),1}let o=n.heartbeatDir??kn;_i(qe(o,"last-turn.debug.jsonl")),z({phase:"boot",turn_nonce:r.turnNonce??null,node:process.version});let s=n.runTurn??Bi,i=a=>{r.turnNonce!==void 0&&r.turnNonce!==""&&Vi(o,r.turnNonce,a)};try{let a=await s(r);return i(a),ze(a.ok,a.reason,a.turnMs),a.ok?0:1}catch(a){let d=a instanceof Error?a.message:String(a);return i({ok:!1,reason:d,turnMs:0}),ze(!1,d,0),1}}function xr(e){let n=!1,t=()=>{n||(n=!0,process.exit(e))};try{process.stdout.write("",t)}catch{t()}setTimeout(t,1e3).unref?.()}_r(process.argv).then(e=>{xr(e)}).catch(e=>{process.stdout.write(`${JSON.stringify({phase:"exit",ok:!1,reason:e instanceof Error?e.message:String(e),turnMs:0})}
|
|
18
18
|
`),xr(1)});
|