kslock-daemon 0.1.6 → 0.1.8
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/index.js +31 -25
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
`);import
|
|
4
|
-
`):["# kslock inbox","",`Scope: ${t.runtimeScopeKey??`${t.agentId}/all-channels`}`,"",`Pending messages: ${t.messages.length}`,`Updated at: ${t.updatedAt}`,"",...t.messages.flatMap((e,n)=>[`## ${n+1}. delivery ${e.deliveryId}`,"",`- messageId: ${e.messageId}`,`- channelId: ${e.channelId}`,`- threadId: ${e.threadId??"none"}`,`- taskId: ${e.taskId??"none"}`,`- createdAt: ${e.createdAt}`,"",e.content,"",...
|
|
5
|
-
`)}async function
|
|
6
|
-
`),await
|
|
7
|
-
`,"utf8")}async function
|
|
8
|
-
`)}function
|
|
9
|
-
`)}function
|
|
10
|
-
`,"utf8")}import{spawn as
|
|
2
|
+
import De from"node:os";import{existsSync as dr,readFileSync as vt}from"node:fs";import{join as ne}from"node:path";function It(t,e=process.env){let n=e.KSLOCK_SERVER_URL||e.DAEMON_SERVER_URL||"",r=e.KSLOCK_MACHINE_KEY||e.DAEMON_MACHINE_KEY||"";for(let s=0;s<t.length;s+=1){let o=t[s];if(o!=="start"){if(o==="--server-url"&&t[s+1]){n=t[++s];continue}o==="--machine-key"&&t[s+1]&&(r=t[++s])}}return!n||!r?null:{serverUrl:n.replace(/\/$/,""),machineKey:r,daemonVersion:Pe(e),hostname:De.hostname(),os:De.platform(),arch:De.arch(),reconnectBaseMs:1e3}}function xt(t=process.env,e=process.cwd()){let n=fr(t.KSLOCK_ENV??t.NODE_ENV),r=mr(e),s=[ne(r,".env.local"),n?ne(r,`.env.${n}`):null];for(let o of s)o&&dr(o)&&gr(o,t)}function Pe(t=process.env){let e=t.KSLOCK_DAEMON_VERSION?.trim();return e||(pr()??"0.0.0-dev")}function pr(){try{let t=JSON.parse(vt(new URL("../package.json",import.meta.url),"utf8"));return typeof t.version=="string"&&t.version.trim()?t.version.trim():null}catch{return null}}function mr(t){return t.endsWith(ne("apps","daemon"))?ne(t,"..",".."):t}function gr(t,e){for(let n of vt(t,"utf8").split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;let s=r.indexOf("=");if(s===-1)continue;let o=r.slice(0,s).trim();if(e[o]!==void 0)continue;let i=r.slice(s+1).trim();i.startsWith('"')&&i.endsWith('"')&&(i=i.slice(1,-1)),i.startsWith("'")&&i.endsWith("'")&&(i=i.slice(1,-1)),e[o]=i}}function fr(t){let e=t?.trim().toLowerCase();if(e)return e==="development"||e==="local"?"dev":e==="production"?"prod":e}var Fe=["Usage: kslock-daemon [start] --server-url <url> --machine-key <key>"," kslock-daemon check-messages --agent-id <agent-id> [--channel-id <channel-id>] [--json]","","Environment:"," KSLOCK_SERVER_URL API server URL, for example https://api.kslock.ai"," KSLOCK_MACHINE_KEY Machine key created from the web console"," KSLOCK_DAEMON_VERSION Override reported daemon version, optional"].join(`
|
|
3
|
+
`);import ar from"ws";var re=class{constructor(e){this.sendFrame=e}delivered(e){this.sendFrame({type:"agent:delivery_ack",deliveryId:e.deliveryId,agentId:e.agentId,status:"delivered"})}completed(e){this.sendFrame({type:"agent:delivery_ack",deliveryId:e.deliveryId,agentId:e.agentId,status:"completed"})}failed(e,n){this.sendFrame({type:"agent:delivery_ack",deliveryId:e.deliveryId,agentId:e.agentId,status:"failed",error:n})}status(e,n,r){this.sendFrame({type:"agent:status",agentId:e.agentId,status:n,...r!==void 0?{sessionId:r}:{}})}runtimeLog(e,n,r){this.sendFrame({type:"runtime:log",agentId:e.agentId,deliveryId:e.deliveryId,stream:n,content:r})}message(e,n,r=[]){this.sendFrame({type:"agent:message",agentId:e.agentId,channelId:e.channelId,threadId:e.threadId,replyToMessageId:e.messageId,deliveryId:e.deliveryId,content:n,...r.length>0?{generatedAttachments:r}:{}})}messageDelta(e,n,r){!n&&!r||this.sendFrame({type:"agent:message_delta",agentId:e.agentId,channelId:e.channelId,threadId:e.threadId,replyToMessageId:e.messageId,deliveryId:e.deliveryId,contentDelta:n,...r!==void 0?{contentSnapshot:r}:{}})}taskInProgress(e){e.taskId&&this.sendFrame({type:"task:status",taskId:e.taskId,agentId:e.agentId,status:"in_progress",message:`${e.runtimeType} agent started working on the task.`})}taskInReview(e){e.taskId&&this.sendFrame({type:"task:status",taskId:e.taskId,agentId:e.agentId,status:"in_review",message:`${e.runtimeType} agent completed the task and requested review.`})}};function R(t){return t.taskId?{type:"task",id:t.taskId}:t.threadId?{type:"thread",id:t.threadId}:t.requesterUserId?{type:"user",id:t.requesterUserId}:{type:"channel",id:t.channelId}}function f(t){let e=R(t);return`${t.agentId}:${t.channelId}:${e.type}:${e.id}`}function L(t){return encodeURIComponent(t)}var se=class{constructor(e){this.onCancelledBeforeStart=e}deliveryQueues=new Map;activeDeliveries=new Map;activeScopes=new Map;cancelledDeliveries=new Map;async enqueue(e,n,r={}){if(this.canRunAsBusyDelivery(e,r))try{await r.onBusyDelivery?.(e)}catch{}let s=f(e),i=(this.deliveryQueues.get(s)??Promise.resolve()).catch(()=>{}).then(()=>this.run(e,n));this.deliveryQueues.set(s,i),await i.finally(()=>{this.deliveryQueues.get(s)===i&&this.deliveryQueues.delete(s)})}cancel(e,n="cancelled_by_user"){this.cancelledDeliveries.set(e,n),this.activeDeliveries.get(e)?.abort(n)}canRunAsBusyDelivery(e,n){if(!n.allowBusyDelivery)return!1;let r=this.activeScopes.get(f(e));return!!(r&&r.runtimeType===e.runtimeType&&r.deliveryIds.size>0)}async run(e,n){let r=this.cancelledDeliveries.get(e.deliveryId);if(r){this.cancelledDeliveries.delete(e.deliveryId),this.onCancelledBeforeStart(e,r);return}let s=new AbortController;this.activeDeliveries.set(e.deliveryId,s),this.markAgentActive(e);try{await n(e,s.signal)}finally{this.activeDeliveries.delete(e.deliveryId),this.cancelledDeliveries.delete(e.deliveryId),this.markAgentInactive(e)}}markAgentActive(e){let n=f(e),r=this.activeScopes.get(n)??{runtimeType:e.runtimeType,deliveryIds:new Set};r.runtimeType=e.runtimeType,r.deliveryIds.add(e.deliveryId),this.activeScopes.set(n,r)}markAgentInactive(e){let n=f(e),r=this.activeScopes.get(n);r&&(r.deliveryIds.delete(e.deliveryId),r.deliveryIds.size===0&&this.activeScopes.delete(n))}};import{mkdir as wr,readdir as bt,readFile as At,rename as vr,writeFile as Ir}from"node:fs/promises";import{join as ie}from"node:path";import{homedir as hr}from"node:os";import{join as j}from"node:path";function yr(){return j(hr(),".agent-collab")}function _e(t){return j(yr(),"agents",L(t))}function Le(t,e){return j(_e(t),"channels",L(e))}function A(t){let e=R(t);return j(Le(t.agentId,t.channelId),"scopes",L(e.type),L(e.id))}function St(t){return j(A(t),"logs")}var kt="inbox.json",xr="inbox.md",oe=new Map;function Ct(t){return ie(A(t),kt)}function je(t){return ie(A(t),xr)}async function Et(t){return Pt(t,async()=>{let e=await Oe(t);return e.messages.some(n=>n.deliveryId===t.deliveryId)||e.messages.push(Ar(t)),Dt(t,e)})}async function ae(t,e){return Pt(t,async()=>{let n=await Oe(t),r=n.messages.filter(s=>s.deliveryId!==e);return r.length===n.messages.length?n:Dt(t,{...n,updatedAt:new Date().toISOString(),messages:r})})}async function Tt(t){return t.channelId?kr(t)?Oe(t):Mt(t.agentId,t.channelId):Sr(t.agentId)}function $e(t){return t.messages.length===0?["# kslock inbox","","No pending messages.",""].join(`
|
|
4
|
+
`):["# kslock inbox","",`Scope: ${t.runtimeScopeKey??`${t.agentId}/all-channels`}`,"",`Pending messages: ${t.messages.length}`,`Updated at: ${t.updatedAt}`,"",...t.messages.flatMap((e,n)=>[`## ${n+1}. delivery ${e.deliveryId}`,"",`- messageId: ${e.messageId}`,`- channelId: ${e.channelId}`,`- threadId: ${e.threadId??"none"}`,`- taskId: ${e.taskId??"none"}`,`- createdAt: ${e.createdAt}`,"",e.content,"",...Cr(e)])].join(`
|
|
5
|
+
`)}async function Oe(t){try{let e=await At(Ct(t),"utf8"),n=JSON.parse(e);return{agentId:t.agentId,channelId:t.channelId,runtimeScopeKey:f(t),updatedAt:typeof n.updatedAt=="string"?n.updatedAt:new Date().toISOString(),messages:Array.isArray(n.messages)?n.messages.filter(Ft):[]}}catch{return{agentId:t.agentId,channelId:t.channelId,runtimeScopeKey:f(t),updatedAt:new Date().toISOString(),messages:[]}}}async function Sr(t){let e=ie(_e(t),"channels"),n=[],r=new Date().toISOString();try{let s=await bt(e,{withFileTypes:!0});for(let o of s){if(!o.isDirectory())continue;let i=decodeURIComponent(o.name),a=await Mt(t,i);n.push(...a.messages),a.updatedAt>r&&(r=a.updatedAt)}}catch{}return{agentId:t,channelId:null,runtimeScopeKey:null,updatedAt:r,messages:n.sort((s,o)=>s.createdAt.localeCompare(o.createdAt))}}async function Mt(t,e){let n=[],r=new Date().toISOString();for(let s of await Rr(Le(t,e)))n.push(...s.messages),s.updatedAt>r&&(r=s.updatedAt);return{agentId:t,channelId:e,runtimeScopeKey:null,updatedAt:r,messages:n.sort((s,o)=>s.createdAt.localeCompare(o.createdAt))}}async function Rr(t){let e=[];async function n(r){let s;try{s=await bt(r,{withFileTypes:!0})}catch{return}for(let o of s){let i=ie(r,o.name);if(o.isDirectory()){await n(i);continue}if(o.isFile()&&o.name===kt){let a=await br(i);a&&e.push(a)}}}return await n(t),e}async function br(t){try{let e=JSON.parse(await At(t,"utf8"));return{agentId:typeof e.agentId=="string"?e.agentId:"",channelId:typeof e.channelId=="string"?e.channelId:null,runtimeScopeKey:typeof e.runtimeScopeKey=="string"?e.runtimeScopeKey:null,updatedAt:typeof e.updatedAt=="string"?e.updatedAt:new Date().toISOString(),messages:Array.isArray(e.messages)?e.messages.filter(Ft):[]}}catch{return null}}async function Dt(t,e){let n={...e,updatedAt:new Date().toISOString()};if(!e.channelId)throw new Error("cannot write aggregate agent inbox");let r=A(t);return await wr(r,{recursive:!0}),await Rt(Ct(t),`${JSON.stringify(n,null,2)}
|
|
6
|
+
`),await Rt(je(t),$e(n)),n}async function Rt(t,e){let n=`${t}.${process.pid}.${Date.now()}.tmp`;await Ir(n,e,"utf8"),await vr(n,t)}async function Pt(t,e){let n=f(t),r=oe.get(n)??Promise.resolve(),s=()=>{},o=r.catch(()=>{}).then(()=>new Promise(i=>{s=i}));oe.set(n,o),await r.catch(()=>{});try{return await e()}finally{s(),oe.get(n)===o&&oe.delete(n)}}function Ar(t){return{deliveryId:t.deliveryId,messageId:t.messageId,serverId:t.serverId,channelId:t.channelId,threadId:t.threadId,taskId:t.taskId,content:t.content,attachments:t.attachments.map(e=>({id:e.id,filename:e.filename,contentType:e.contentType,size:e.size})),createdAt:new Date().toISOString()}}function kr(t){return!!("taskId"in t&&t.taskId||"threadId"in t&&t.threadId||"requesterUserId"in t&&t.requesterUserId)}function Cr(t){return t.attachments.length===0?[]:["Attachments:",...t.attachments.map(e=>`- ${e.filename} (${e.contentType}, ${e.size} bytes)`),""]}function Ft(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.deliveryId=="string"&&typeof e.messageId=="string"&&typeof e.serverId=="string"&&typeof e.channelId=="string"&&(typeof e.threadId=="string"||e.threadId===null)&&(typeof e.taskId=="string"||e.taskId===null)&&typeof e.content=="string"&&Array.isArray(e.attachments)&&typeof e.createdAt=="string"}import{appendFile as Er,mkdir as Tr,rename as Mr,stat as Dr}from"node:fs/promises";import{join as Pr}from"node:path";var Fr="session.log",_r=1e6,Lr=5;async function T(t,e,n){let r=St(t);await Tr(r,{recursive:!0});let s=Pr(r,Fr);await jr(s);let o=JSON.stringify({time:new Date().toISOString(),agentId:t.agentId,channelId:t.channelId,stream:e,content:n});await Er(s,`${o}
|
|
7
|
+
`,"utf8")}async function jr(t){try{if((await Dr(t)).size<_r)return}catch{return}for(let e=Lr-1;e>=1;e-=1)await _t(`${t}.${e}`,`${t}.${e+1}`);await _t(t,`${t}.1`)}async function _t(t,e){try{await Mr(t,e)}catch{}}import{stat as $r,readFile as Or}from"node:fs/promises";import{tmpdir as Nr}from"node:os";import{basename as Kr,extname as Br,isAbsolute as qr,resolve as $,sep as Jr}from"node:path";import{fileURLToPath as zr}from"node:url";var Ur=6,Gr=10*1024*1024;async function jt(t,e={}){let n=Wr(t);if(n.length===0)return[];let r=e.maxAttachments??Ur,s=e.maxBytes??Gr,o=[],i=new Set;for(let a of n){if(o.length>=r)break;let u=Hr(a.markdownUrl,e.workspacePath);if(!u||i.has(u)||(i.add(u),!Xr(u,e.workspacePath)))continue;let c=Yr(u);if(c)try{let l=await $r(u);if(!l.isFile()||l.size<=0||l.size>s)continue;let d=await Or(u);o.push({filename:Kr(u),contentType:c,contentBase64:d.toString("base64"),markdownUrl:a.markdownUrl,alt:a.alt||null})}catch{continue}}return o}function Wr(t){let e=[],n=/!\[([^\]]*)\]\(([^)]+)\)/g,r;for(;r=n.exec(t);){let s=Vr(r[2]??"");s&&e.push({alt:r[1]??"",markdownUrl:s})}return e}function Vr(t){let e=t.trim();if(!e)return"";if(e.startsWith("<")){let n=e.indexOf(">");if(n>0)return e.slice(1,n).trim()}return e=e.replace(/\s+["'][^"']*["']\s*$/,"").trim(),e}function Hr(t,e){if(/^(https?:|data:|blob:|\/api\/)/i.test(t))return null;try{if(t.startsWith("file://"))return $(zr(t))}catch{return null}let n=t.split("#",1)[0]??t,r=n.split("?",1)[0]??n,s=Qr(r);return s?qr(s)?$(s):e?$(e,s):null:null}function Qr(t){try{return decodeURI(t)}catch{return t}}function Xr(t,e){return e&&Lt(t,e)?!0:Lt(t,Nr())}function Lt(t,e){let n=$(t),r=$(e);return n===r||n.startsWith(`${r}${Jr}`)}function Yr(t){let e=Br(t).toLowerCase();return e===".png"?"image/png":e===".jpg"||e===".jpeg"?"image/jpeg":e===".gif"?"image/gif":e===".webp"?"image/webp":e===".svg"?"image/svg+xml":null}function Ot(t){let e=t.pendingCount===1?"message":"messages";return[`[System notification: You have ${t.pendingCount} pending inbox ${e}.]`,"","Do not lose your current task context. At the next safe breakpoint, inspect the inbox before context-sensitive side effects.",`Run: ${t.checkMessagesCommand}`,`Fallback file: ${t.inboxFile}`,"","Pending inbox deliveries remain queued and will be delivered as their own turns after the current turn finishes."].join(`
|
|
8
|
+
`)}function O(t){let e=["kslock-daemon check-messages",`--agent-id ${$t(t.agentId)}`,`--channel-id ${$t(t.channelId)}`].join(" "),n=je(t);return{KSLOCK_RUNTIME_SCOPE_KEY:f(t),KSLOCK_INBOX_FILE:n,KSLOCK_CHECK_MESSAGES_COMMAND:e}}function Nt(t){let e=O(t);return["Runtime inbox:",`- Current runtime scope: ${e.KSLOCK_RUNTIME_SCOPE_KEY}`,"- While you are busy, kslock may notify you about pending inbox messages.",`- Inspect them with: ${e.KSLOCK_CHECK_MESSAGES_COMMAND}`,`- If the command is unavailable, read: ${e.KSLOCK_INBOX_FILE}`,"- Pending inbox deliveries are queued and will arrive as their own turns; keep replies scoped to the current delivered message unless the user explicitly asks otherwise."].join(`
|
|
9
|
+
`)}function $t(t){return/^[A-Za-z0-9_./:@-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}var ue=class{constructor(e){this.publisher=e}create(e,n,r){let s=R(e);return{cwd:e.workspacePath??void 0,abortSignal:n,env:{...process.env,AGENT_ID:e.agentId,SERVER_ID:e.serverId,CHANNEL_ID:e.channelId,REQUESTER_USER_ID:e.requesterUserId??"",RUNTIME_SCOPE_KEY:f(e),RUNTIME_SCOPE_TYPE:s.type,RUNTIME_SCOPE_ID:s.id,WORKSPACE_ID:e.workspaceId??"",AGENT_TOKEN:e.agentToken,AGENT_PROXY_URL:"",AGENT_RUNTIME:e.runtimeType,...O(e)},onLog:(o,i)=>{r?.(),this.publisher.runtimeLog(e,o,i),T(e,o,i)},onPartial:(o,i)=>{r?.(),this.publisher.messageDelta(e,o,i)}}}};function Kt(t){let e=Zr(t.env??process.env),n=new AbortController,r=Date.now(),s=!1,o=null,i=()=>{n.abort(t.parentSignal?.reason??"runtime_cancelled")};t.parentSignal?.aborted?i():t.parentSignal?.addEventListener("abort",i,{once:!0});let a=()=>{e<=0||n.signal.aborted||(o&&clearTimeout(o),o=setTimeout(()=>{let u=Date.now()-r;if(u<e){a();return}s=!0;let c=`runtime stalled: no output for ${Math.round(u/1e3)}s on delivery ${t.frame.deliveryId}`;t.onStall(c),n.abort("runtime_stalled")},e))};return a(),{get signal(){return n.signal},get stalled(){return s},progress(){r=Date.now(),a()},dispose(){o&&(clearTimeout(o),o=null),t.parentSignal?.removeEventListener("abort",i)}}}function Zr(t){let e=t.KSLOCK_DELIVERY_STALL_MS;if(!e)return 9e5;let n=Number(e);return!Number.isFinite(n)||n<0?9e5:n}var ce=class{constructor(e,n){this.runtimes=e;this.publisher=n;this.contextFactory=new ue(n)}contextFactory;activeDeliveriesByAgent=new Map;async run(e,n){await ae(e,e.deliveryId),this.publisher.delivered(e),this.publisher.taskInProgress(e),this.startAgentWork(e);try{this.publisher.runtimeLog(e,"system",`using ${e.executionPolicy.preset} execution policy for @${e.agentHandle}`);let r=this.runtimes.get(e.runtimeType),s=Kt({frame:e,parentSignal:n,onStall:i=>{this.publisher.runtimeLog(e,"stderr",i),T(e,"stderr",i)}}),o;try{o=await r.handleDelivery(e,this.contextFactory.create(e,s.signal,()=>s.progress()))}catch(i){throw s.stalled?new Error("runtime_stalled"):i}finally{s.dispose()}if(e.attachments.length>0&&await T(e,"system",`delivery has attachments: ${e.attachments.map(i=>i.filename).join(", ")}`),o.sessionId&&this.activeAgentCount(e.agentId)<=1&&this.publisher.status(e,"working",o.sessionId),!o.suppressMessage&&o.content.trim()){let i=await jt(o.content,{workspacePath:e.workspacePath});i.length>0&&this.publisher.runtimeLog(e,"system",`attached generated image(s): ${i.map(a=>a.filename).join(", ")}`),this.publisher.message(e,o.content,i)}this.publisher.taskInReview(e),this.publisher.completed(e),this.finishAgentWork(e,"idle",o.sessionId??null)}catch(r){let s=r instanceof Error?r.message:`${e.runtimeType} runtime failed`;T(e,"stderr",s),this.publisher.failed(e,s),this.finishAgentWork(e,"error")}}startAgentWork(e){let n=this.activeAgentCount(e.agentId);this.activeDeliveriesByAgent.set(e.agentId,n+1),n===0&&this.publisher.status(e,"working")}finishAgentWork(e,n,r){let s=this.activeAgentCount(e.agentId),o=Math.max(0,s-1);if(o===0){this.activeDeliveriesByAgent.delete(e.agentId),this.publisher.status(e,n,r);return}this.activeDeliveriesByAgent.set(e.agentId,o)}activeAgentCount(e){return this.activeDeliveriesByAgent.get(e)??0}};import{resolve as _s}from"node:path";import{mkdir as es,readFile as ts,writeFile as ns}from"node:fs/promises";import{join as Bt}from"node:path";function y(t){return A(t)}async function I(t){try{let e=await ts(Bt(y(t),"session.json"),"utf8");return{...JSON.parse(e),agentId:t.agentId,channelId:t.channelId,runtimeScopeKey:f(t)}}catch{return null}}async function x(t){let e=y(t);await es(e,{recursive:!0}),await ns(Bt(e,"session.json"),`${JSON.stringify(t,null,2)}
|
|
10
|
+
`,"utf8")}import{spawn as Be}from"node:child_process";import{constants as rs}from"node:fs";import{access as ss,readdir as os}from"node:fs/promises";import{homedir as Ke}from"node:os";import{delimiter as is,join as k}from"node:path";var as=/^[a-zA-Z0-9._-]+$/,Ne=new Map;async function S(t,e){let n=us(t,e),r=`${n.command}:${n.envVars.join(",")}:${n.extraCandidates.join(",")}`,s=[...cs(n),...n.extraCandidates,...ms(n.command)],o=Ne.get(r);if(o&&(s.length===0||s.includes(o))&&await qt(o))return o;o&&Ne.delete(r);let i=[...s,await ds(n.command),...await ps(n.command),n.command].filter(Boolean);for(let a of hs(i))if(await qt(a))return Ne.set(r,a),a;return null}function qe(t,e=[]){return new Promise(n=>{let r="",s="",o=!1,i=c=>{o||(o=!0,n(c))},a=Be(t,[...e,"--version"],{stdio:["ignore","pipe","pipe"]}),u=setTimeout(()=>{a.kill("SIGTERM"),i(null)},3e3);u.unref?.(),a.stdout.on("data",c=>{r+=c.toString()}),a.stderr.on("data",c=>{s+=c.toString()}),a.on("error",()=>{clearTimeout(u),i(null)}),a.on("exit",()=>{clearTimeout(u),i((r||s).trim().split(/\r?\n/)[0]||null)})})}function us(t,e){return typeof t!="string"?{command:t.command,envVars:t.envVars??[],extraCandidates:t.extraCandidates??[]}:{command:t,envVars:e?[e]:[],extraCandidates:[]}}function cs(t){return[...t.envVars,...ls(t.command)].map(e=>process.env[e]?.trim()).filter(Boolean)}function ls(t){let e=t.toUpperCase().replace(/[^A-Z0-9]+/g,"_");return[`${e}_BIN`,`${e}_PATH`,`KSLOCK_${e}_BIN`,`KSLOCK_RUNTIME_${e}_BIN`]}async function ds(t){if(!as.test(t))return null;let e=process.env.SHELL||"/bin/zsh";return new Promise(n=>{let r="",s=Be(e,["-lc",`command -v ${t}`],{stdio:["ignore","pipe","ignore"]});s.stdout.on("data",o=>{r+=o.toString()}),s.on("error",()=>n(null)),s.on("exit",o=>{let i=r.trim().split(/\r?\n/)[0];n(o===0&&i?i:null)})})}async function ps(t){return[...await fs(t),k(Ke(),".local","bin",t),k(Ke(),"bin",t),k("/opt/homebrew/bin",t),k("/usr/local/bin",t)]}function ms(t){return gs(process.env.KSLOCK_RUNTIME_PATHS||process.env.KSLOCK_RUNTIME_PATH).map(e=>k(e,t))}function gs(t){return(t??"").split(is).map(e=>e.trim()).filter(Boolean)}async function fs(t){let e=k(Ke(),".nvm","versions","node");try{return(await os(e)).sort((r,s)=>s.localeCompare(r)).map(r=>k(e,r,"bin",t))}catch{return[]}}async function qt(t){if(t.includes("/"))try{return await ss(t,rs.X_OK),!0}catch{return!1}return new Promise(e=>{let n=!1,r=i=>{n||(n=!0,e(i))},s=Be(t,["--version"],{stdio:"ignore"}),o=setTimeout(()=>{s.kill("SIGTERM"),r(!1)},3e3);o.unref?.(),s.on("error",()=>{clearTimeout(o),r(!1)}),s.on("exit",()=>{clearTimeout(o),r(!0)})})}function hs(t){return[...new Set(t)]}import{Buffer as Jt}from"node:buffer";import{mkdir as ys,writeFile as ws}from"node:fs/promises";import{tmpdir as zt}from"node:os";import{join as le}from"node:path";var Je=16e3;async function w(t,e={}){let n=t.attachments.length===0?t.content:await vs(t,e);return`${Ss(t)}
|
|
11
|
+
|
|
12
|
+
${Rs(t)}
|
|
11
13
|
|
|
12
14
|
${n}
|
|
13
15
|
|
|
14
|
-
${
|
|
16
|
+
${Nt(t)}`}async function vs(t,e){let r=(await Promise.all(t.attachments.map(s=>Is(t,s,e)))).map(xs).join(`
|
|
15
17
|
`);return`${t.content}
|
|
16
18
|
|
|
17
19
|
Attachments:
|
|
18
|
-
${r}`}async function
|
|
19
|
-
`)}function
|
|
20
|
-
`)}
|
|
21
|
-
`).
|
|
22
|
-
|
|
20
|
+
${r}`}async function Is(t,e,n){let r=e.downloadUrl??e.previewUrl,s=As(r);if(!s)return{filename:e.filename,contentType:e.contentType,size:e.size,localPath:null,textPreview:null,sourceUrl:r&&!r.startsWith("data:")?r:null,warning:r?"attachment content is not embedded in the daemon frame":null};let o=null,i=null;try{o=await bs(t,e.id,e.filename,s.buffer,n.workspacePath)}catch(a){i=a instanceof Error?`failed to write local attachment file: ${a.message}`:"failed to write local attachment file"}return{filename:e.filename,contentType:e.contentType||s.contentType,size:e.size,localPath:o,textPreview:ks(s.contentType||e.contentType,e.filename)?Cs(s.buffer.toString("utf8")):null,sourceUrl:null,warning:i}}function xs(t){let e=[`- ${t.filename} (${t.contentType}, ${t.size} bytes)`];return t.localPath&&e.push(` Local path: ${t.localPath}`),t.sourceUrl&&e.push(` Source URL: ${t.sourceUrl}`),t.textPreview?(e.push(" Text preview:"),e.push(Es(t.textPreview))):t.contentType.startsWith("image/")&&t.localPath&&e.push(" Image attachment saved as a local file. Inspect the local path when image/file tools are available."),t.warning&&e.push(` Warning: ${t.warning}`),e.join(`
|
|
21
|
+
`)}function Ss(t){let e=R(t);return["kslock context:",`- Requester: ${t.requesterUserId?`${t.requesterDisplayName||t.requesterUserId} (${t.requesterUserId})`:"system or unknown"}`,`- Channel: ${t.channelId}`,`- Thread: ${t.threadId??"none"}`,`- Task: ${t.taskId??"none"}`,`- Runtime session scope: ${e.type}:${e.id}`,`- Runtime scope key: ${f(t)}`].join(`
|
|
22
|
+
`)}function Rs(t){let e=t.context?.items??[];if(e.length===0)return["Platform injected context:","- No channel context is configured for this delivery."].join(`
|
|
23
|
+
`);let n=["Platform injected context:","The following context was configured in KinAgents and is safe to use as business context.","It does not grant filesystem, shell, network, deployment, or external write permissions."];for(let r of e)n.push(""),n.push(`## ${r.title}`),n.push(r.content);return t.context?.truncated&&(n.push(""),n.push("[Some configured context was truncated by the platform context limit.]")),n.join(`
|
|
24
|
+
`)}async function bs(t,e,n,r,s){let o=`${Ut(e,"attachment")}-${Ut(n,"file")}`;if(s)try{return await ze(le(s,".kslock","attachments",t.deliveryId),o,r)}catch{return ze(le(zt(),"kslock-daemon","attachments",t.deliveryId),o,r)}return ze(le(zt(),"kslock-daemon","attachments",t.deliveryId),o,r)}async function ze(t,e,n){await ys(t,{recursive:!0});let r=le(t,e);return await ws(r,n),r}function As(t){if(!t?.startsWith("data:"))return null;let e=t.indexOf(",");if(e<0)return null;let n=t.slice(5,e),r=t.slice(e+1),s=n.split(";").filter(Boolean),o=s[0]||"application/octet-stream",i=s.includes("base64");try{return{buffer:i?Jt.from(r.replace(/\s/g,""),"base64"):Jt.from(decodeURIComponent(r)),contentType:o}}catch{return null}}function ks(t,e){let n=t.toLowerCase();return n.startsWith("text/")||["application/json","application/ld+json","application/xml","application/javascript","application/x-javascript","application/yaml","application/x-yaml"].includes(n)?!0:/\.(csv|env|html?|js|json|log|md|markdown|sql|styl|svg|ts|tsx|txt|vue|xml|ya?ml)$/i.test(e)}function Cs(t){let e=t.replace(/\r\n/g,`
|
|
25
|
+
`).replace(/\u0000/g,"");return e.length<=Je?e:`${e.slice(0,Je)}
|
|
26
|
+
...[truncated ${e.length-Je} chars]`}function Es(t){return t.split(`
|
|
23
27
|
`).map(e=>` ${e}`).join(`
|
|
24
|
-
`)}function
|
|
25
|
-
`)
|
|
26
|
-
`),!0)}ensureState(e){let n=e.context.cwd||process.cwd(),r=g(e.frame),s=this.states.get(r);if(s&&!s.closed&&s.command===e.command&&s.cwd===n)return this.clearIdleTimer(s),s;s&&this.dispose(e.frame);let o=I(e.frame,this.spec.resolveModel(e.context.env));e.context.onLog("system",o?`${this.spec.displayName} using model override ${o}`:`${this.spec.displayName} using configured model`);let i=hs(e.command,this.spec.buildArgs({frame:e.frame,sessionId:e.sessionId,resume:e.resume,model:o}),{cwd:n,env:e.context.env,stdio:["pipe","pipe","pipe"]}),a={agentId:e.frame.agentId,scopeKey:r,command:e.command,cwd:n,env:e.context.env,child:i,stdoutBuffer:"",stderrBuffer:"",sessionId:e.sessionId,current:null,injected:[],queue:[],idleTimer:null,closed:!1};return this.states.set(r,a),this.bindProcess(a),a}bindProcess(e){e.child.stdout.on("data",n=>{e.stdoutBuffer=Ut(e.stdoutBuffer+n.toString(),r=>{this.handleLine(e,r)})}),e.child.stderr.on("data",n=>{e.stderrBuffer=Ut(e.stderrBuffer+n.toString(),r=>{e.current?.context.onLog("stderr",r)})}),e.child.on("error",n=>{this.rejectState(e,n instanceof Error?n:new Error(String(n)))}),e.child.on("close",n=>{e.closed=!0,this.states.delete(e.scopeKey),(e.current||e.queue.length>0)&&this.rejectState(e,new Error(`${this.spec.displayName} process exited with code ${n??"unknown"}`))})}handleLine(e,n){let r=ue(n);if(!r){e.current?.context.onLog("stdout",n);return}let s=this.spec.extractSessionId(r);s&&(e.sessionId=s);let o=this.spec.extractEventName(r);o&&e.current?.context.onLog("system",`[${this.spec.type}:event] ${o}`);let i=this.spec.normalizeError(this.spec.summarizeError(r));if(i){this.finishCurrent(e,new Error(i));return}let a=this.spec.extractText(r);if(a&&e.current){let u=e.current;if(Gt(r))u.output.trim()||(u.output=a);else{let c=a.startsWith(u.snapshot)?a:`${u.snapshot}${a}`,l=c.slice(u.snapshot.length);u.snapshot=c,u.output=c,l&&u.context.onPartial?.(l,c)}}Gt(r)&&this.finishCurrent(e)}pump(e){if(e.closed||e.current)return;let n=e.queue.shift();if(!n){this.scheduleIdleDispose(e);return}this.clearIdleTimer(e),e.current=n,n.context.onLog("system",`${this.spec.displayName} session ${e.sessionId}`),e.child.stdin.write(this.encodeUserMessage(n.prompt,e.sessionId)+`
|
|
27
|
-
`)
|
|
28
|
-
`)
|
|
29
|
-
`)};return
|
|
28
|
+
`)}function Ut(t,e){return t.trim().replace(/[<>:"/\\|?*\x00-\x1F]/g,"_").replace(/^\.+$/,"").slice(0,160)||e}import{spawn as Ts}from"node:child_process";var Ms=3e4,b=class extends Error{constructor(n,r,s){super(r);this.code=n;this.data=s}},M=class{constructor(e){this.options=e;this.child=Ts(e.command,e.args,{cwd:e.cwd,env:e.env,stdio:["pipe","pipe","pipe"]}),this.child.stdout.on("data",n=>this.handleStdout(n.toString())),this.child.stderr.on("data",n=>this.options.onStderr?.(n.toString())),this.child.on("error",n=>this.closeWithError(n)),this.child.on("exit",(n,r)=>{this.closeWithError(new Error(`acp process exited with ${Ps(n,r)}`))})}child;pending=new Map;nextId=1;stdoutBuffer="";closed=!1;request(e,n={},r={}){if(this.closed)return Promise.reject(new Error("acp process is closed"));let s=this.nextId++,o=r.timeoutMs===void 0?Ms:r.timeoutMs;return new Promise((i,a)=>{let u={resolve:c=>i(c),reject:a};o!==null&&(u.timer=setTimeout(()=>{this.pending.delete(s),a(new Error(`acp request ${e} timed out after ${o}ms`))},o),u.timer.unref?.()),this.pending.set(s,u),this.send({jsonrpc:"2.0",id:s,method:e,params:n})})}notify(e,n={}){this.closed||this.send({jsonrpc:"2.0",method:e,params:n})}close(){this.closed||(this.closed=!0,this.child.stdin.end(),this.child.killed||this.child.kill("SIGTERM"),this.rejectAll(new Error("acp process closed")))}send(e){this.child.stdin.write(`${JSON.stringify(e)}
|
|
29
|
+
`)}handleStdout(e){for(this.stdoutBuffer+=e;;){let n=this.stdoutBuffer.indexOf(`
|
|
30
|
+
`);if(n<0)break;let r=this.stdoutBuffer.slice(0,n).trim();this.stdoutBuffer=this.stdoutBuffer.slice(n+1),r&&this.handleLine(r)}}handleLine(e){let n;try{n=JSON.parse(e)}catch{this.options.onStderr?.(`invalid acp stdout: ${e}`);return}if("id"in n&&(n.result!==void 0||n.error!==void 0)){this.handleResponse(n);return}if(n.method&&"id"in n){this.handleRequest(n);return}n.method&&this.options.onNotification?.(n)}handleResponse(e){let n=e.id;if(n===void 0)return;let r=this.pending.get(n);if(r){if(this.pending.delete(n),r.timer&&clearTimeout(r.timer),e.error){r.reject(new b(e.error.code,e.error.message,e.error.data));return}r.resolve(e.result)}}async handleRequest(e){if(e.id!==void 0)try{let n=this.options.onRequest?await this.options.onRequest(e):Ds(e.method??"unknown");this.send({jsonrpc:"2.0",id:e.id,result:n})}catch(n){let r=n instanceof b?n:new b(-32603,n instanceof Error?n.message:"internal error");this.send({jsonrpc:"2.0",id:e.id,error:{code:r.code,message:r.message,...r.data===void 0?{}:{data:r.data}}})}}closeWithError(e){this.closed||(this.closed=!0,this.rejectAll(e))}rejectAll(e){for(let[n,r]of this.pending)this.pending.delete(n),r.timer&&clearTimeout(r.timer),r.reject(e)}};function Ds(t){throw new b(-32601,`Unsupported ACP client method: ${t}`)}function Ps(t,e){return t!==null?`code ${t}`:e?`signal ${e}`:"unknown status"}import{spawn as Fs}from"node:child_process";function Gt(t,e=3e3){return new Promise(n=>{let r="",s=!1,o=u=>{s||(s=!0,n(u))},i=Fs(t.command,[...t.args,"--help"],{cwd:t.cwd,env:t.env,stdio:["ignore","pipe","pipe"]}),a=setTimeout(()=>{i.kill("SIGTERM"),o(!1)},e);a.unref?.(),i.stdout.on("data",u=>{r+=u.toString()}),i.stderr.on("data",u=>{r+=u.toString()}),i.on("error",()=>{clearTimeout(a),o(!1)}),i.on("exit",u=>{clearTimeout(a),o(u===0||/usage|help|acp|agent client protocol/i.test(r))})})}async function Wt(t,e=5e3){let n=new M({...t,onRequest:()=>{throw new Error("unexpected acp request during detection")}});try{return await Ue(n,e),!0}catch{return!1}finally{n.close()}}function Ue(t,e=3e4){return t.request("initialize",{protocolVersion:1,clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1},terminal:!1},clientInfo:{name:"kinagents-daemon",title:"KinAgents daemon",version:process.env.KSLOCK_DAEMON_VERSION??"0.0.0"}},{timeoutMs:e})}function Vt(t){let e=R(t);return e.type==="task"?`kinagents:task:${e.id}:agent:${t.agentId}`:`kinagents:channel:${t.channelId}:${e.type}:${e.id}:agent:${t.agentId}`}var N=class{constructor(e){this.profile=e;this.type=e.runtimeType,this.capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:e.supportsExecutionPolicy}}type;busyDeliveryMode="queue";capabilities;async detect(){let e=await this.resolveCommand();return!e||!await Gt({command:e,args:this.profile.args,env:process.env})?!1:Wt({command:e,args:this.profile.args,env:process.env})}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error(`${this.profile.label} runtime is not available`);let s=await I(e),o=s?.runtimeType===this.type?s.runtimeSessionId:null,i=o?`resuming ${o}`:"starting new session";n.onLog("system",`${this.profile.label} ${i} in ${n.cwd??process.cwd()}`),n.onLog("system",`${this.profile.label} scope ${Vt(e)}`);let a;try{a=await this.runAcp(r,e,n,o)}catch(u){if(!o)throw u;n.onLog("stderr",`${this.profile.label} resume ${o} failed; starting a new session. ${u instanceof Error?u.message:""}`),a=await this.runAcp(r,e,n,null)}return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:f(e),runtimeType:this.type,runtimeSessionId:a.sessionId,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),n.onLog("system",`${this.profile.label} session ${a.sessionId}`),a.stopReason&&a.stopReason!=="end_turn"&&n.onLog("system",`${this.profile.label} stopped with ${a.stopReason}`),{content:a.output.trim()||`${this.profile.label} completed without output`,sessionId:a.sessionId}}async runAcp(e,n,r,s){let o=null,i=!1,a="",u="",c=null,l=_s(r.cwd??process.cwd()),d=new M({command:e,args:this.profile.args,cwd:l,env:r.env,onStderr:p=>{let g=p.trim();g&&r.onLog("stderr",`[${this.type}:acp] ${g}`)},onNotification:p=>{if(!i||!o)return;let g=Ls(p,o);if(!g)return;let h=this.handleSessionUpdate(g,r);h&&(a+=h,u+=h,r.onPartial?.(h,u))},onRequest:p=>this.handleClientRequest(p,r)}),m=()=>{o&&d.notify("session/cancel",{sessionId:o}),c=setTimeout(()=>d.close(),5e3),c.unref?.()};r.abortSignal?.addEventListener("abort",m,{once:!0});try{let p=await Ue(d);o=await this.openSession(d,p,l,s,r);let g=await w(n,{workspacePath:l});i=!0;let h=await d.request("session/prompt",{sessionId:o,prompt:[{type:"text",text:g}]},{timeoutMs:null});return i=!1,{output:a,sessionId:o,stopReason:h.stopReason??null}}finally{i=!1,c&&clearTimeout(c),r.abortSignal?.removeEventListener("abort",m),d.close()}}async openSession(e,n,r,s,o){let i=n.agentCapabilities??{};if(s){if((i.sessionCapabilities??{}).resume)return await e.request("session/resume",Ge(r,s)),s;if(i.loadSession)return await e.request("session/load",Ge(r,s)),s;o.onLog("system",`${this.profile.label} does not support session resume/load; starting new session`)}let a=await e.request("session/new",Ge(r));if(!a.sessionId)throw new Error(`${this.profile.label} did not return an ACP session id`);return a.sessionId}handleSessionUpdate(e,n){let r=typeof e.sessionUpdate=="string"?e.sessionUpdate:"";if(r==="agent_message_chunk")return Ht(e.content);if(r==="agent_thought_chunk"){let s=Ht(e.content);return s&&n.onLog("system",`[${this.type}:thought] ${Os(s)}`),""}return r==="tool_call"?(n.onLog("system",`[${this.type}:tool] ${Qt(e)}`),""):r==="tool_call_update"?(n.onLog("system",`[${this.type}:tool] ${Qt(e)}`),""):(r==="plan"&&n.onLog("system",`[${this.type}:plan] ${js(e)}`),"")}handleClientRequest(e,n){if(e.method==="session/request_permission"){let r=$s(e.params);return r?(n.onLog("system",`[${this.type}:permission] auto-selected ${r}`),{outcome:{outcome:"selected",optionId:r}}):(n.onLog("system",`[${this.type}:permission] cancelled request without selectable option`),{outcome:{outcome:"cancelled"}})}throw new b(-32601,`Unsupported ACP client method: ${e.method??"unknown"}`)}async resolveCommand(){return S({command:this.profile.command,envVars:this.profile.envVars})}};function Ge(t,e){return{...e?{sessionId:e}:{},cwd:t,mcpServers:[]}}function Ls(t,e){if(t.method!=="session/update")return null;let n=t.params;return!n||n.sessionId!==e?null:C(n.update)?n.update:null}function Ht(t){return C(t)?t.type==="text"&&typeof t.text=="string"?t.text:t.type==="resource"&&C(t.resource)&&typeof t.resource.text=="string"?t.resource.text:"":""}function Qt(t){let e=typeof t.title=="string"?t.title:"",n=typeof t.status=="string"?t.status:"",r=typeof t.toolCallId=="string"?t.toolCallId:"";return[e||r||"tool",n].filter(Boolean).join(" ")}function js(t){let e=Array.isArray(t.entries)?t.entries:[];return e.length===0?"updated":e.map(n=>{if(!C(n))return"";let r=typeof n.content=="string"?n.content:"",s=typeof n.status=="string"?n.status:"";return[r,s&&`(${s})`].filter(Boolean).join(" ")}).filter(Boolean).slice(0,5).join("; ")||"updated"}function $s(t){let e=C(t)&&Array.isArray(t.options)?t.options:[],r=e.find(s=>{if(!C(s))return!1;let o=typeof s.kind=="string"?s.kind:"",i=typeof s.optionId=="string"?s.optionId:"";return o.startsWith("allow")||/allow/i.test(i)})??e[0];return C(r)&&typeof r.optionId=="string"?r.optionId:null}function Os(t){let e=t.trim().replace(/\s+/g," ");return e.length>300?`${e.slice(0,300)}...`:e}function C(t){return!!(t&&typeof t=="object"&&!Array.isArray(t))}var Xt={runtimeType:"openclaw",label:"OpenClaw ACP",command:"openclaw",envVars:["OPENCLAW_BIN","KSLOCK_OPENCLAW_BIN","KSLOCK_RUNTIME_OPENCLAW_BIN"],args:["acp"],supportsExecutionPolicy:!1},Yt={runtimeType:"hermes",label:"Hermes ACP",command:"hermes",envVars:["HERMES_BIN","KSLOCK_HERMES_BIN","KSLOCK_RUNTIME_HERMES_BIN"],args:["acp"],supportsExecutionPolicy:!1},We=[Xt,Yt];import{randomUUID as In}from"node:crypto";import{spawn as Ns}from"node:child_process";var Ks=5e3,Zt=8*1024*1024;async function tn(t){let e=await Ve(t,["debug","models"]);return e.code!==0?[]:Bs(e.stdout)}async function nn(t){let e=await Ve(t,["models"]);return e.code!==0?[]:rn(e.stdout)}async function de(t){let e=await Ve(t,["models"]);return e.code!==0?[]:rn(e.stdout)}function Bs(t){let e=t.indexOf("{");if(e<0)return[];try{let n=JSON.parse(t.slice(e));return Array.isArray(n.models)?sn(n.models.flatMap(r=>{if(!r||typeof r!="object")return[];let s=r;return s.visibility&&s.visibility!=="list"?[]:typeof s.slug!="string"||!s.slug.trim()?[]:[{id:s.slug.trim(),label:typeof s.display_name=="string"&&s.display_name.trim()?s.display_name.trim():s.slug.trim()}]})):[]}catch{return[]}}function rn(t){return sn(t.split(/\r?\n/).map(e=>e.trim()).flatMap(e=>{if(!e||/^[\s#=-]+$/.test(e))return[];let r=e.match(/[a-z0-9][a-z0-9_.-]+\/[a-z0-9][a-z0-9_.:-]+/i)?.[0]??e.match(/^[a-z0-9][a-z0-9_.:-]+/i)?.[0]??"";return!r||["id","model","models","provider"].includes(r.toLowerCase())?[]:[{id:r,label:r}]}))}function Ve(t,e){return new Promise(n=>{let r="",s="",o=!1,i=null,a=Ns(t,e,{stdio:["ignore","pipe","pipe"]}),u=c=>{o||(o=!0,i&&clearTimeout(i),n(c))};i=setTimeout(()=>{a.kill("SIGTERM"),u({stdout:r,stderr:s,code:null})},Ks),i.unref?.(),a.stdout.on("data",c=>{r=en(r,c.toString())}),a.stderr.on("data",c=>{s=en(s,c.toString())}),a.on("error",()=>u({stdout:r,stderr:s,code:null})),a.on("exit",c=>u({stdout:r,stderr:s,code:c}))})}function en(t,e){return t.length>=Zt?t:(t+e).slice(0,Zt)}function sn(t){let e=new Map;for(let n of t)n.id&&e.set(n.id,n);return[...e.values()]}function v(t,e){return t.runtimeModel?.trim()||e}import{spawn as qs}from"node:child_process";function pe(t){try{return JSON.parse(t)}catch{return null}}var D=class{constructor(e){this.spec=e}states=new Map;runTurn(e){return new Promise((n,r)=>{let s={frame:e.frame,context:e.context,prompt:e.prompt,resolve:n,reject:r,output:"",snapshot:"",injected:!1,abort:()=>{}};if(s.abort=()=>{this.removeTurn(e.frame,s),r(new Error("runtime_cancelled"))},e.context.abortSignal?.aborted){s.abort();return}e.context.abortSignal?.addEventListener("abort",s.abort,{once:!0});try{let o=this.ensureState(e);if(o.current){s.injected=!0,o.injected.push(s),s.context.onLog("system",`${this.spec.displayName} busy stdin delivery`),o.child.stdin.write(this.encodeUserMessage(s.prompt,o.sessionId)+`
|
|
31
|
+
`);return}o.queue.push(s),this.pump(o)}catch(o){r(o instanceof Error?o:new Error(String(o)))}})}dispose(e){let n=f(e),r=this.states.get(n);r&&(r.closed=!0,this.clearIdleTimer(r),r.child.kill("SIGTERM"),this.states.delete(n))}notify(e,n){let r=this.states.get(f(e));return!r||r.closed||!r.current?!1:(r.child.stdin.write(this.encodeUserMessage(n,r.sessionId)+`
|
|
32
|
+
`),!0)}ensureState(e){let n=e.context.cwd||process.cwd(),r=f(e.frame),s=this.states.get(r);if(s&&!s.closed&&s.command===e.command&&s.cwd===n)return this.clearIdleTimer(s),s;s&&this.dispose(e.frame);let o=v(e.frame,this.spec.resolveModel(e.context.env));e.context.onLog("system",o?`${this.spec.displayName} using model override ${o}`:`${this.spec.displayName} using configured model`);let i=qs(e.command,this.spec.buildArgs({frame:e.frame,sessionId:e.sessionId,resume:e.resume,model:o}),{cwd:n,env:e.context.env,stdio:["pipe","pipe","pipe"]}),a={agentId:e.frame.agentId,scopeKey:r,command:e.command,cwd:n,env:e.context.env,child:i,stdoutBuffer:"",stderrBuffer:"",sessionId:e.sessionId,current:null,injected:[],queue:[],idleTimer:null,closed:!1};return this.states.set(r,a),this.bindProcess(a),a}bindProcess(e){e.child.stdout.on("data",n=>{e.stdoutBuffer=on(e.stdoutBuffer+n.toString(),r=>{this.handleLine(e,r)})}),e.child.stderr.on("data",n=>{e.stderrBuffer=on(e.stderrBuffer+n.toString(),r=>{e.current?.context.onLog("stderr",r)})}),e.child.on("error",n=>{this.rejectState(e,n instanceof Error?n:new Error(String(n)))}),e.child.on("close",n=>{e.closed=!0,this.states.delete(e.scopeKey),(e.current||e.queue.length>0)&&this.rejectState(e,new Error(`${this.spec.displayName} process exited with code ${n??"unknown"}`))})}handleLine(e,n){let r=pe(n);if(!r){e.current?.context.onLog("stdout",n);return}let s=this.spec.extractSessionId(r);s&&(e.sessionId=s);let o=this.spec.extractEventName(r);o&&e.current?.context.onLog("system",`[${this.spec.type}:event] ${o}`);let i=this.spec.normalizeError(this.spec.summarizeError(r));if(i){this.finishCurrent(e,new Error(i));return}let a=this.spec.extractText(r);if(a&&e.current){let u=e.current;if(an(r))u.output.trim()||(u.output=a);else{let c=a.startsWith(u.snapshot)?a:`${u.snapshot}${a}`,l=c.slice(u.snapshot.length);u.snapshot=c,u.output=c,l&&u.context.onPartial?.(l,c)}}an(r)&&this.finishCurrent(e)}pump(e){if(e.closed||e.current)return;let n=e.queue.shift();if(!n){this.scheduleIdleDispose(e);return}this.clearIdleTimer(e),e.current=n,n.context.onLog("system",`${this.spec.displayName} session ${e.sessionId}`),e.child.stdin.write(this.encodeUserMessage(n.prompt,e.sessionId)+`
|
|
33
|
+
`)}finishCurrent(e,n){let r=e.current;if(!r)return;let s=e.injected.splice(0);if(e.current=null,n){this.rejectTurn(r,n);for(let o of s)this.rejectTurn(o,n);for(let o of e.queue.splice(0))this.rejectTurn(o,n);e.closed=!0,e.child.kill("SIGTERM"),this.states.delete(e.scopeKey)}else{this.resolveTurn(r,e.sessionId);for(let o of s)this.resolveTurn(o,e.sessionId);this.pump(e)}}resolveTurn(e,n){this.cleanupTurn(e);let r=e.output.trim();e.resolve({content:r,sessionId:n,suppressMessage:e.injected&&!r})}rejectTurn(e,n){this.cleanupTurn(e),e.reject(n)}cleanupTurn(e){e.context.abortSignal?.removeEventListener("abort",e.abort)}removeTurn(e,n){let r=f(e),s=this.states.get(r);s&&(s.queue=s.queue.filter(o=>o!==n),s.injected=s.injected.filter(o=>o!==n),s.current===n&&(s.current=null,this.clearIdleTimer(s),s.child.kill("SIGTERM"),this.states.delete(r)))}rejectState(e,n){let r=e.current;e.current=null,this.clearIdleTimer(e),r&&this.rejectTurn(r,n);for(let s of e.injected.splice(0))this.rejectTurn(s,n);for(let s of e.queue.splice(0))this.rejectTurn(s,n);this.states.delete(e.scopeKey)}scheduleIdleDispose(e){if(e.closed||e.current||e.queue.length>0||e.idleTimer)return;let n=Js();n<=0||(e.idleTimer=setTimeout(()=>{e.closed||e.current||e.queue.length>0||(e.closed=!0,e.child.kill("SIGTERM"),this.states.delete(e.scopeKey))},n),e.idleTimer.unref?.())}clearIdleTimer(e){e.idleTimer&&(clearTimeout(e.idleTimer),e.idleTimer=null)}encodeUserMessage(e,n){return JSON.stringify({type:"user",message:{role:"user",content:[{type:"text",text:e}]},session_id:n})}};function on(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function an(t){return!!(t&&typeof t=="object"&&t.type==="result")}function Js(){let t=process.env.KSLOCK_RUNTIME_IDLE_TTL_MS;if(!t)return 1800*1e3;let e=Number(t);return!Number.isFinite(e)||e<0?1800*1e3:e}function He(t){return t.preset==="read_only"?["--permission-mode","dontAsk","--tools","Read,Grep,Glob,LS"]:t.preset==="full_access"?["--dangerously-skip-permissions"]:["--permission-mode","acceptEdits","--allowedTools",["Read","Grep","Glob","LS","Edit","MultiEdit","Write","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git show *)","Bash(pnpm test *)","Bash(pnpm run test *)","Bash(pnpm typecheck *)","Bash(pnpm run typecheck *)","Bash(pnpm lint *)","Bash(pnpm run lint *)","Bash(pnpm build *)","Bash(pnpm run build *)","Bash(npm test *)","Bash(npm run test *)","Bash(npm run typecheck *)","Bash(npm run lint *)","Bash(npm run build *)","Bash(yarn test *)","Bash(yarn typecheck *)","Bash(yarn lint *)","Bash(yarn build *)","Bash(tsc *)","Bash(vitest *)"].join(","),"--disallowedTools",["Bash(rm *)","Bash(sudo *)","Bash(chmod *)","Bash(chown *)","Bash(curl *)","Bash(wget *)"].join(",")]}function Qe(t){return["-p","--output-format","stream-json","--verbose","--include-partial-messages",...t.resume?["--resume",t.sessionId]:["--session-id",t.sessionId],...un(t.model),...He(t.frame.executionPolicy),t.message]}function Xe(t){return["--output-format","stream-json","--input-format","stream-json","--verbose","--include-partial-messages",...t.resume?["--resume",t.sessionId]:["--session-id",t.sessionId],...un(t.model),...He(t.frame.executionPolicy)]}function me(t){return t.CLAUDE_MODEL?.trim()||t.ANTHROPIC_MODEL?.trim()||null}function un(t){return t?["--model",t]:[]}var ge="Claude \u8FD4\u56DE\u9519\u8BEF\uFF0C\u672A\u63D0\u4F9B\u8BE6\u7EC6\u539F\u56E0";function Ze(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","subtype","event","event_name"])if(typeof e[n]=="string")return e[n];return null}function fe(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["session_id","sessionId"])if(typeof e[n]=="string"&&zs(e[n]))return e[n];for(let n of Object.values(e)){let r=fe(n);if(r)return r}return null}function B(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.result=="string"&&e.result.trim())return e.result;if(typeof e.content=="string"&&e.content.trim())return e.content;let n=e.message;if(n&&typeof n=="object"){let r=cn(n.content);if(r)return r}return cn(e.content)}function q(t){if(!t)return null;let e=Us(t),r=(e?K(e):t)?.trim();return!r||Ye(r)?null:r}function P(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.type=="string"?e.type:"",r=typeof e.subtype=="string"?e.subtype:"";return n==="error"||r==="error"||r==="failure"||e.is_error===!0||n==="result"&&r&&r!=="success"?K(t)??ge:null}function J(t,e){return!t||t===ge&&e!==ge?e:t}function cn(t){if(typeof t=="string"&&t.trim())return t;if(!Array.isArray(t))return null;let e=t.map(n=>{if(!n||typeof n!="object")return"";let r=n;return typeof r.text=="string"?r.text:""}).filter(Boolean).join("");return e.trim()?e:null}function K(t){if(typeof t=="string"&&t&&!Ye(t))return t;if(!t||typeof t!="object")return null;let e=t;for(let r of["message","detail","reason","error"]){let s=e[r];if(typeof s=="string"&&s&&!Ye(s))return s}let n=K(e.error);if(n)return n;for(let r of Object.values(e)){let s=K(r);if(s)return s}return null}function zs(t){return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(t)}function Ye(t){let e=t.trim().toLowerCase();return e==="error"||e==="failure"}function Us(t){try{return JSON.parse(t)}catch{return null}}import{spawn as Gs}from"node:child_process";function fn(t){return new Promise((e,n)=>{let r=[],s=[],o="",i=[],a="",u="",c="",l=Gs(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["ignore","pipe","pipe"]});if(t.signal?.aborted){l.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{l.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),l.stdout.on("data",d=>{u=ln(u+d.toString(),m=>{let p=dn(m);if(p){let g=t.onJson(p)??P(p);g&&(a=J(a,g));let h=B(p);h&&(pn(p)?s.push(h):o=mn(h,o,t.onPartial));return}r.push(m),t.onLog("stdout",m)})}),l.stderr.on("data",d=>{c=ln(c+d.toString(),m=>{i.push(m),t.onLog("stderr",m)})}),l.on("error",n),l.on("exit",d=>{if(u.trim()){let p=dn(u.trim());if(p){let g=t.onJson(p)??P(p);g&&(a=J(a,g));let h=B(p);h&&(pn(p)?s.push(h):o=mn(h,o,t.onPartial))}else r.push(u.trim()),t.onLog("stdout",u.trim())}if(c.trim()&&(i.push(c.trim()),t.onLog("stderr",c.trim())),t.onLog("system",`${t.command} exited with code ${d??"unknown"}`),d===0){e({output:Ws(s,o,r)});return}let m=q(gn(i))??gn(i);n(new Error(a||m||`${t.command} exited with code ${d}`))})})}function ln(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function dn(t){try{return JSON.parse(t)}catch{return null}}function pn(t){return!!(t&&typeof t=="object"&&t.type==="result")}function mn(t,e,n){let r=t.startsWith(e)?t:`${e}${t}`,s=r.slice(e.length);return s&&n?.(s,r),r}function Ws(t,e,n){let r=t.at(-1)?.trim();if(r)return r;let s=e.trim();return s||n.join(`
|
|
34
|
+
`).trim()}function gn(t){return t.map(e=>e.trim()).filter(Boolean).at(-1)??""}import{mkdir as Vs,readFile as Hs,writeFile as hn}from"node:fs/promises";import{join as Qs}from"node:path";var Xs="claude-last-message.txt";function Ys(t){return Qs(y(t),Xs)}async function yn(t){await Vs(y(t),{recursive:!0});let e=Ys(t);return await hn(e,"","utf8"),e}async function wn(t,e){await hn(t,e,"utf8")}async function vn(t){try{return await Hs(t,"utf8")}catch{return""}}var z=class{type="claude";busyDeliveryMode="gated";sessions=new D({type:"claude",displayName:"claude",buildArgs:Xe,resolveModel:me,extractSessionId:fe,extractText:B,extractEventName:Ze,summarizeError:P,normalizeError:q,preferFailure:J});capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:!0};async detect(){return!!await this.resolveCommand()}notifyInbox(e,n){return this.sessions.notify(e,n)}async listModels(){let e=await this.resolveCommand();return e?de(e):[]}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error("claude runtime is not available");let s=await I(e),o=s?.runtimeType===this.type?s.runtimeSessionId:null,i=o??In(),a=o?`resuming ${o}`:`starting new session ${i}`;n.onLog("system",`claude ${a} in ${n.cwd??process.cwd()}`);let u;try{u=await this.runClaudeStream(r,e,n,i,!!o)}catch(c){if(xn(c))n.onLog("stderr",`claude stream-json session failed; falling back to print mode. ${c instanceof Error?c.message:""}`),u=await this.runClaude(r,e,n,i,!!o);else if(o){let l=In();n.onLog("stderr",`claude resume ${o} failed; starting a new session ${l}. ${c instanceof Error?c.message:""}`),u=await this.runClaudeStream(r,e,n,l,!1).catch(d=>{if(!xn(d))throw d;return n.onLog("stderr",`claude stream retry failed; falling back to print mode. ${d instanceof Error?d.message:""}`),this.runClaude(r,e,n,l,!1)})}else throw c}return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:f(e),runtimeType:this.type,runtimeSessionId:u.sessionId,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),n.onLog("system",`claude session ${u.sessionId}`),u.suppressMessage?{content:u.output.trim(),sessionId:u.sessionId,suppressMessage:!0}:{content:u.output.trim()||"claude runtime completed without output",sessionId:u.sessionId}}async runClaudeStream(e,n,r,s,o){r.onLog("system",o?`claude stream resume ${s}`:`claude stream session-id ${s}`);let i=await this.sessions.runTurn({command:e,frame:n,context:r,prompt:await w(n,{workspacePath:r.cwd}),sessionId:s,resume:o});return{output:i.content,sessionId:i.sessionId??s,suppressMessage:i.suppressMessage}}async runClaude(e,n,r,s,o){let i=await w(n,{workspacePath:r.cwd}),a=v(n,me(r.env)),u=await yn(n);r.onLog("system",a?`claude using model override ${a}`:"claude using configured model"),r.onLog("system",o?`claude resume ${s}`:`claude session-id ${s}`);let c=new Set,l=await fn({command:e,args:Qe({frame:n,message:i,sessionId:s,resume:o,model:a}),cwd:r.cwd,env:r.env,signal:r.abortSignal,onPartial:r.onPartial,onJson:d=>{let m=fe(d);m&&c.add(m);let p=Ze(d);p&&r.onLog("system",`[claude:event] ${p}`);let g=q(P(d));return g?(r.onLog("stderr",`[claude:error] ${g}`),g):null},onLog:r.onLog});return await wn(u,l.output),{output:l.output||await vn(u),sessionId:[...c].at(-1)??s}}async resolveCommand(){return S({command:"claude",envVars:["CLAUDE_BIN"]})}};function xn(t){if(process.env.KSLOCK_CLAUDE_DISABLE_PRINT_FALLBACK==="1")return!1;let e=t instanceof Error?t.message:String(t);return/process exited|unknown option|unrecognized|input-format|stream-json|stdin|not supported/i.test(e)}import{mkdir as lo,writeFile as po}from"node:fs/promises";import{join as mo}from"node:path";function E(t){return t.preset==="read_only"?"read-only":t.preset==="full_access"?"danger-full-access":"workspace-write"}function et(t){let e=["-a","never","-s",E(t.frame.executionPolicy),"exec"];return t.sessionId?[...e,"resume","--json","--skip-git-repo-check",...Sn(t.model),"--output-last-message",t.outputFile,t.sessionId,t.prompt]:[...e,"--json","--skip-git-repo-check",...Sn(t.model),"--output-last-message",t.outputFile,t.prompt]}function he(t){return t.CODEX_MODEL?.trim()||null}function Sn(t){return t?["--model",t]:[]}var tt="Codex \u8FD4\u56DE\u9519\u8BEF\uFF0C\u672A\u63D0\u4F9B\u8BE6\u7EC6\u539F\u56E0",Zs=/The ['‘"]?([^'’"]+)['’"]? model requires a newer version of Codex\. Please upgrade to the latest app or CLI and try again\./i;function we(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","event","event_name","method"])if(typeof e[n]=="string")return e[n];return null}function nt(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["session_id","sessionId","thread_id","threadId","conversation_id","conversationId"])if(typeof e[n]=="string"&&e[n])return e[n];for(let n of Object.values(e)){let r=nt(n);if(r)return r}return null}function G(t){if(!t)return null;let e=to(t),r=(e?U(e):t)?.trim();return!r||ye(r)?null:eo(r)}function ve(t){if(!t||typeof t!="object")return null;let e=we(t);return e!=="error"&&e!=="turn.failed"?null:tt}function F(t){if(!t||typeof t!="object")return null;let e=t,n=we(t);if(n!=="error"&&n!=="turn.failed")return null;for(let s of["message","detail","reason"])if(typeof e[s]=="string"&&e[s]&&!ye(e[s]))return e[s];let r=U(e.error);if(r)return r;for(let[s,o]of Object.entries(e)){if(["type","event","event_name","method","status","error"].includes(s))continue;let i=U(o);if(i)return i}return null}function rt(t,e){return!t||t===tt&&e!==tt?e:t}function U(t){if(typeof t=="string"&&t&&!ye(t))return t;if(!t||typeof t!="object")return null;let e=t;for(let r of["message","detail","reason"])if(typeof e[r]=="string"&&e[r]&&!ye(e[r]))return e[r];let n=U(e.error);if(n)return n;for(let r of Object.values(e)){let s=U(r);if(s)return s}return null}function ye(t){let e=t.trim().toLowerCase();return e==="error"||e==="turn.failed"}function eo(t){let e=t.match(Zs);return e?`Codex CLI \u7248\u672C\u8FC7\u4F4E\uFF0C\u6682\u4E0D\u652F\u6301\u6A21\u578B ${e[1]??"\u5F53\u524D\u6A21\u578B"}\u3002\u8BF7\u5347\u7EA7 Codex CLI \u540E\u91CD\u542F daemon\uFF0C\u6216\u5C06 CODEX_MODEL \u8C03\u6574\u4E3A\u5F53\u524D CLI \u652F\u6301\u7684\u6A21\u578B\u540E\u91CD\u8BD5\u3002`:t}function to(t){try{return JSON.parse(t)}catch{return null}}import{spawn as no}from"node:child_process";var Ie=class{states=new Map;async runTurn(e){return new Promise((n,r)=>{let s={frame:e.frame,context:e.context,prompt:e.prompt,resolve:n,reject:r,output:"",streamedAgentMessageIds:new Set,streamedReasoningIds:new Set,injected:!1,steerSent:!1,abort:()=>{}};if(s.abort=()=>{this.removeTurn(e.frame,s),r(new Error("runtime_cancelled"))},e.context.abortSignal?.aborted){s.abort();return}e.context.abortSignal?.addEventListener("abort",s.abort,{once:!0});try{let o=this.ensureState(e);if(o.current||o.queue.length>0){s.injected=!0,o.injected.push(s),s.context.onLog("system","codex steering active turn"),this.flushInjectedSteers(o);return}o.queue.push(s),this.pump(o)}catch(o){r(o instanceof Error?o:new Error(String(o)))}})}dispose(e){let n=f(e),r=this.states.get(n);r&&(r.closed=!0,this.clearIdleTimer(r),r.child.kill("SIGTERM"),this.states.delete(n))}notify(e,n){let r=this.states.get(f(e));return!r||r.closed||!r.current&&r.queue.length===0?!1:(r.pendingNotifications.push(n),this.flushPendingNotifications(r),!0)}ensureState(e){let n=f(e.frame),r=e.context.cwd||process.cwd(),s=this.states.get(n);if(s&&!s.closed&&s.command===e.command&&s.cwd===r)return this.clearIdleTimer(s),s;s&&this.dispose(e.frame);let o=no(e.command,["app-server","--listen","stdio://"],{cwd:r,env:e.context.env,stdio:["pipe","pipe","pipe"]}),i={agentId:e.frame.agentId,scopeKey:n,command:e.command,cwd:r,env:e.context.env,child:o,stdoutBuffer:"",stderrBuffer:"",requestId:0,initializeRequestId:null,pendingThreadRequest:this.buildThreadRequest(e.frame,e.sessionId,e.model,r),threadId:null,activeTurnId:null,sessionAnnounced:!1,current:null,injected:[],pendingNotifications:[],queue:[],idleTimer:null,closed:!1};return this.states.set(n,i),this.bindProcess(n,i),i.initializeRequestId=this.sendRequest(i,"initialize",{clientInfo:{name:"kslock-daemon",version:"1.0.0"},capabilities:{experimentalApi:!0}}),i}buildThreadRequest(e,n,r,s){let o={cwd:s,approvalPolicy:"never",sandbox:E(e.executionPolicy),developerInstructions:[`You are @${e.agentHandle} in kslock channel ${e.channelId}.`,"Reply with the final answer for the delivered message."].join(`
|
|
35
|
+
`)};return r&&(o.model=r),n?{method:"thread/resume",params:{threadId:n,...o}}:{method:"thread/start",params:o}}bindProcess(e,n){n.child.stdout.on("data",r=>{n.stdoutBuffer=Rn(n.stdoutBuffer+r.toString(),s=>{for(let o of this.parseLine(n,s))this.handleEvent(n,o)})}),n.child.stderr.on("data",r=>{n.stderrBuffer=Rn(n.stderrBuffer+r.toString(),s=>{n.current?.context.onLog("stderr",s)})}),n.child.on("error",r=>{this.rejectState(e,n,r instanceof Error?r:new Error(String(r)))}),n.child.on("close",r=>{n.closed=!0,this.states.delete(e);let s=new Error(`codex app-server exited with code ${r??"unknown"}`);(n.current||n.queue.length>0)&&this.rejectState(e,n,s)})}parseLine(e,n){let r=pe(n);if(!r||typeof r!="object")return[];let s=r,o=[];if(s.result&&typeof s.result=="object"){if(s.id===e.initializeRequestId)return e.initializeRequestId=null,this.sendNotification(e,"initialized",{}),e.pendingThreadRequest&&(this.sendRequest(e,e.pendingThreadRequest.method,e.pendingThreadRequest.params),e.pendingThreadRequest=null),o;let i=s.result,a=i.thread;if(a&&typeof a=="object"&&typeof a.id=="string")return this.handleThreadReady(e,String(a.id),o),o;let u=i.turn;if(u&&typeof u=="object"&&typeof u.id=="string")return e.activeTurnId=String(u.id),this.flushInjectedSteers(e),this.flushPendingNotifications(e),o;if(typeof i.turnId=="string")return e.activeTurnId=i.turnId,this.flushInjectedSteers(e),this.flushPendingNotifications(e),o}if(s.error){let i=G(F(s.error))??F(s.error);return o.push({kind:"error",message:i||"Codex app-server request failed"}),o}switch(s.method){case"thread/started":{let i=s.params,a=i&&typeof i=="object"?i.thread:null,u=a&&typeof a=="object"?a.id:null;typeof u=="string"&&this.handleThreadReady(e,u,o);break}case"turn/started":{let i=s.params,a=i&&typeof i=="object"?i.turn:null,u=a&&typeof a=="object"?a.id:null;typeof u=="string"&&(e.activeTurnId=u,this.flushInjectedSteers(e),this.flushPendingNotifications(e)),o.push({kind:"thinking",text:""});break}case"item/agentMessage/delta":{let i=s.params,a=i?.delta,u=i?.itemId;typeof u=="string"&&e.current?.streamedAgentMessageIds.add(u),typeof a=="string"&&a.length>0&&o.push({kind:"text",text:a});break}case"item/reasoning/summaryTextDelta":case"item/reasoning/textDelta":{let i=s.params,a=i?.delta,u=i?.itemId;typeof u=="string"&&e.current?.streamedReasoningIds.add(u),typeof a=="string"&&a.length>0&&o.push({kind:"thinking",text:a});break}case"item/started":case"item/completed":o.push(...this.parseItemEvent(e,s));break;case"turn/completed":{let a=s.params?.turn,u=a?.error;if(a?.status==="failed"&&u&&typeof u=="object"){let c=u.message;o.push({kind:"error",message:typeof c=="string"?c:"Codex turn failed"})}e.activeTurnId=null,o.push({kind:"turn_end",sessionId:e.threadId});break}case"error":{let i=G(F(s.params))??ve(s);o.push({kind:"error",message:i||"Unknown Codex app-server error"});break}}return o}parseItemEvent(e,n){let r=[],o=n.params?.item;if(!o||typeof o.type!="string")return r;let i=n.method==="item/started",a=n.method==="item/completed";switch(o.type){case"reasoning":if(a&&typeof o.id=="string"&&!e.current?.streamedReasoningIds.has(o.id)){let u=ro(o);u&&r.push({kind:"thinking",text:u})}break;case"agentMessage":a&&typeof o.id=="string"&&!e.current?.streamedAgentMessageIds.has(o.id)&&typeof o.text=="string"&&o.text&&r.push({kind:"text",text:o.text});break;case"commandExecution":i&&typeof o.command=="string"&&r.push({kind:"tool_call",name:"shell",input:{command:o.command}}),a&&r.push({kind:"tool_output",name:"shell"});break;case"contextCompaction":i&&r.push({kind:"compaction_started"}),a&&r.push({kind:"compaction_finished"});break;case"mcpToolCall":i&&r.push({kind:"tool_call",name:typeof o.tool=="string"?o.tool:"mcp_tool",input:o.arguments}),a&&r.push({kind:"tool_output",name:typeof o.tool=="string"?o.tool:"mcp_tool"});break}return r}handleEvent(e,n){let r=e.current;if(!(!r&&n.kind!=="session"))switch(n.kind){case"session":e.threadId=n.sessionId,r?.context.onLog("system",`codex session ${n.sessionId}`);break;case"thinking":n.text&&r?.context.onLog("system",`[codex:thinking] ${n.text}`);break;case"text":this.appendText(e,n.text);break;case"tool_call":r?.context.onLog("system",`[codex:tool] ${n.name}`);break;case"tool_output":r?.context.onLog("system",`[codex:tool_result] ${n.name}`);break;case"compaction_started":r?.context.onLog("system","codex compacting context");break;case"compaction_finished":r?.context.onLog("system","codex context compaction finished");break;case"error":this.finishCurrent(e,new Error(n.message));break;case"turn_end":n.sessionId&&(e.threadId=n.sessionId),this.finishCurrent(e);break}}handleThreadReady(e,n,r){e.threadId=n,e.sessionAnnounced||(r.push({kind:"session",sessionId:n}),e.sessionAnnounced=!0),this.pump(e)}pump(e){if(e.current||e.closed||!e.threadId)return;let n=e.queue.shift();if(!n){this.scheduleIdleDispose(e);return}this.clearIdleTimer(e),e.current=n,n.context.onLog("system",e.activeTurnId?"codex steering active turn":"codex starting turn"),this.sendRequest(e,"turn/start",{threadId:e.threadId,input:[{type:"text",text:n.prompt}]})}finishCurrent(e,n){let r=e.current;if(!r)return;let s=e.injected.splice(0);if(e.current=null,n){this.rejectTurn(r,n);for(let o of s)this.rejectTurn(o,n);for(let o of e.queue.splice(0))this.rejectTurn(o,n);e.closed=!0,this.clearIdleTimer(e),e.child.kill("SIGTERM"),this.states.delete(f(r.frame))}else{this.resolveTurn(r,e.threadId);for(let o of s)this.resolveTurn(o,e.threadId);this.pump(e)}}appendText(e,n){let r=e.current;r&&(r.output+=n,r.context.onPartial?.(n,r.output))}flushInjectedSteers(e){if(!(!e.threadId||!e.activeTurnId))for(let n of e.injected)n.steerSent||(n.steerSent=!0,this.sendRequest(e,"turn/steer",{threadId:e.threadId,expectedTurnId:e.activeTurnId,input:[{type:"text",text:n.prompt}]}))}flushPendingNotifications(e){if(!(!e.threadId||!e.activeTurnId||e.pendingNotifications.length===0))for(let n of e.pendingNotifications.splice(0))this.sendRequest(e,"turn/steer",{threadId:e.threadId,expectedTurnId:e.activeTurnId,input:[{type:"text",text:n}]})}resolveTurn(e,n){this.cleanupTurn(e);let r=e.output.trim();e.resolve({content:r,sessionId:n,suppressMessage:e.injected&&!r})}rejectTurn(e,n){this.cleanupTurn(e),e.reject(n)}cleanupTurn(e){e.context.abortSignal?.removeEventListener("abort",e.abort),e.streamedAgentMessageIds.clear(),e.streamedReasoningIds.clear()}removeTurn(e,n){let r=f(e),s=this.states.get(r);s&&(s.queue=s.queue.filter(o=>o!==n),s.injected=s.injected.filter(o=>o!==n),s.current===n&&(s.current=null,this.clearIdleTimer(s),s.child.kill("SIGTERM"),this.states.delete(r)))}rejectState(e,n,r){let s=n.current;n.current=null,this.clearIdleTimer(n),s&&this.rejectTurn(s,r);for(let o of n.injected.splice(0))this.rejectTurn(o,r);for(let o of n.queue.splice(0))this.rejectTurn(o,r);this.states.delete(e)}scheduleIdleDispose(e){if(e.closed||e.current||e.queue.length>0||e.idleTimer)return;let n=so();n<=0||(e.idleTimer=setTimeout(()=>{e.closed||e.current||e.queue.length>0||(e.closed=!0,e.child.kill("SIGTERM"),this.states.delete(e.scopeKey))},n),e.idleTimer.unref?.())}clearIdleTimer(e){e.idleTimer&&(clearTimeout(e.idleTimer),e.idleTimer=null)}sendRequest(e,n,r){return e.requestId+=1,e.child.stdin.write(JSON.stringify({jsonrpc:"2.0",id:e.requestId,method:n,params:r})+`
|
|
30
36
|
`),e.requestId}sendNotification(e,n,r){e.child.stdin.write(JSON.stringify({jsonrpc:"2.0",method:n,params:r})+`
|
|
31
|
-
`)}};function
|
|
32
|
-
`).trim()}function Ps(){let t=process.env.KSLOCK_RUNTIME_IDLE_TTL_MS;if(!t)return 1800*1e3;let e=Number(t);return!Number.isFinite(e)||e<0?1800*1e3:e}import{spawn as _s}from"node:child_process";var Ls="Reading additional input from stdin...";function mn(t){return new Promise((e,n)=>{let r=[],s="",o="",i="",a=_s(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["ignore","pipe","pipe"]});if(t.signal?.aborted){a.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{a.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),a.stdout.on("data",u=>{o=ln(o+u.toString(),c=>{let l=dn(c);if(l){let d=t.onJson(l);d&&(s=Qe(s,d));return}t.onLog("stdout",c)})}),a.stderr.on("data",u=>{i=ln(i+u.toString(),c=>{Xe(c)||(r.push(c),t.onLog("stderr",c))})}),a.on("error",n),a.on("exit",u=>{if(o.trim()){let c=dn(o.trim());if(c){let l=t.onJson(c);l&&(s=Qe(s,l))}else t.onLog("stdout",o.trim())}if(i.trim()&&!Xe(i.trim())&&(r.push(i.trim()),t.onLog("stderr",i.trim())),t.onLog("system",`${t.command} exited with code ${u??"unknown"}`),u===0){e();return}n(new Error(s||js(r)||`${t.command} exited with code ${u}`))})})}function ln(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function dn(t){try{return JSON.parse(t)}catch{return null}}function Xe(t){return t.trim()===Ls}function js(t){return t.map(e=>e.trim()).filter(e=>e&&!Xe(e)).at(-1)??""}import{readFile as Os}from"node:fs/promises";async function pn(t){try{return await Os(t,"utf8")}catch{return""}}function gn(t){if(!t||typeof t!="object")return null;let e=t,n=$s(t)??"";for(let s of["delta","text_delta","content_delta"])if(typeof e[s]=="string"&&e[s])return e[s];if(n.includes("delta")||n.includes("stream")){for(let s of["text","content","message"])if(typeof e[s]=="string"&&e[s])return e[s]}return fn(e.delta??e.message??e.item)}function fn(t){if(typeof t=="string"&&t)return t;if(!t||typeof t!="object")return null;let e=t;for(let n of["delta","text_delta","content_delta","text"])if(typeof e[n]=="string"&&e[n])return e[n];for(let n of Object.values(e)){let r=fn(n);if(r)return r}return null}function $s(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","event","event_name","method"])if(typeof e[n]=="string")return e[n];return null}var z=class{type="codex";appServers=new ye;busyDeliveryMode="direct";capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:!0};async detect(){return!!await this.resolveCommand()}notifyInbox(e,n){return this.appServers.notify(e,n)}async listModels(){let e=await this.resolveCommand();return e?Bt(e):[]}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error("codex runtime is not available");let s=await w(e),o=s?.runtimeType===this.type?s.runtimeSessionId:null,i=o?`resuming ${o}`:"starting new session";n.onLog("system",`codex ${i} in ${n.cwd??process.cwd()}`);let a;try{a=await this.runCodexAppServer(r,e,n,o)}catch(c){if(yn(c))n.onLog("stderr",`codex app-server failed; falling back to codex exec. ${c instanceof Error?c.message:""}`),a=await this.runCodex(r,e,n,o);else if(o)n.onLog("stderr",`codex resume ${o} failed; starting a new session. ${c instanceof Error?c.message:""}`),a=await this.runCodexAppServer(r,e,n,null).catch(l=>{if(!yn(l))throw l;return n.onLog("stderr",`codex app-server retry failed; falling back to codex exec. ${l instanceof Error?l.message:""}`),this.runCodex(r,e,n,null)});else throw c}let u=a.sessionId??o??null;return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:g(e),runtimeType:this.type,runtimeSessionId:u,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),u?n.onLog("system",`codex session ${u}`):n.onLog("system","codex completed without exposing a resumable session id"),a.suppressMessage?{content:a.output.trim(),sessionId:u,suppressMessage:!0}:{content:a.output.trim()||"codex runtime completed without output",sessionId:u}}async runCodexAppServer(e,n,r,s){let o=await v(n,{workspacePath:r.cwd}),i=I(n,me(r.env));r.onLog("system",i?`codex app-server using model override ${i}`:"codex app-server using configured model"),r.onLog("system",`codex app-server sandbox ${A(n.executionPolicy)}`);let a=await this.appServers.runTurn({command:e,frame:n,context:r,prompt:o,sessionId:s,model:i});return{output:a.content,sessionId:a.sessionId??null,suppressMessage:a.suppressMessage}}async runCodex(e,n,r,s){let o=h(n);await Ns(o,{recursive:!0});let i=Bs(o,"last-message.txt");await Ks(i,"","utf8");let a=await v(n,{workspacePath:r.cwd}),u=I(n,me(r.env));r.onLog("system",u?`codex using model override ${u}`:"codex using configured model"),r.onLog("system",`codex sandbox ${A(n.executionPolicy)}`);let c=new Set;return await mn({command:e,args:We({frame:n,prompt:a,outputFile:i,model:u,sessionId:s}),cwd:r.cwd,env:r.env,signal:r.abortSignal,onJson:l=>{let d=gn(l);d&&r.onPartial?.(d);let p=He(l);p&&c.add(p);let m=ge(l);m&&r.onLog("system",`[codex:event] ${m}`);let f=q(M(l))??fe(l);return f?(r.onLog("stderr",`[codex:error] ${f}`),f):null},onLog:r.onLog}),{output:await pn(i),sessionId:[...c].at(-1)??null}}async resolveCommand(){return S({command:"codex",envVars:["CODEX_BIN","CODEX_CLI_PATH"]})}};function yn(t){if(process.env.KSLOCK_CODEX_DISABLE_EXEC_FALLBACK==="1")return!1;let e=t instanceof Error?t.message:String(t);return/app-server exited|unrecognized|unknown command|invalid subcommand|not supported/i.test(e)}import{randomUUID as Tn}from"node:crypto";function Ye(t){return t.preset==="read_only"?["--permission-mode","dontAsk","--tools","Read,Grep,Glob,LS"]:t.preset==="full_access"?["--dangerously-skip-permissions"]:["--permission-mode","acceptEdits","--allowedTools",["Read","Grep","Glob","LS","Edit","MultiEdit","Write","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git show *)","Bash(pnpm test *)","Bash(pnpm run test *)","Bash(pnpm typecheck *)","Bash(pnpm run typecheck *)","Bash(pnpm lint *)","Bash(pnpm run lint *)","Bash(pnpm build *)","Bash(pnpm run build *)","Bash(npm test *)","Bash(npm run test *)","Bash(npm run typecheck *)","Bash(npm run lint *)","Bash(npm run build *)","Bash(yarn test *)","Bash(yarn typecheck *)","Bash(yarn lint *)","Bash(yarn build *)","Bash(tsc *)","Bash(vitest *)"].join(","),"--disallowedTools",["Bash(rm *)","Bash(sudo *)","Bash(chmod *)","Bash(chown *)","Bash(curl *)","Bash(wget *)"].join(",")]}function Ze(t){return["-p","--output-format","stream-json","--verbose","--include-partial-messages",...t.resume?["--resume",t.sessionId]:["--session-id",t.sessionId],...hn(t.model),...Ye(t.frame.executionPolicy)]}function et(t){return["--output-format","stream-json","--input-format","stream-json","--verbose","--include-partial-messages",...t.resume?["--resume",t.sessionId]:["--session-id",t.sessionId],...hn(t.model),...Ye(t.frame.executionPolicy)]}function he(t){return t.KSCC_MODEL?.trim()||t.ANTHROPIC_MODEL?.trim()||null}function hn(t){return t?["--model",t]:[]}var ve="kscc \u8FD4\u56DE\u9519\u8BEF\uFF0C\u672A\u63D0\u4F9B\u8BE6\u7EC6\u539F\u56E0";function nt(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","subtype","event","event_name"])if(typeof e[n]=="string")return e[n];return null}function Ie(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["session_id","sessionId"])if(typeof e[n]=="string"&&qs(e[n]))return e[n];for(let n of Object.values(e)){let r=Ie(n);if(r)return r}return null}function U(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.result=="string"&&e.result.trim())return e.result;if(typeof e.content=="string"&&e.content.trim())return e.content;let n=e.message;if(n&&typeof n=="object"){let r=vn(n.content);if(r)return r}return vn(e.content)}function G(t){if(!t)return null;let e=zs(t),r=(e?J(e):t)?.trim();return!r||tt(r)?null:r}function D(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.type=="string"?e.type:"",r=typeof e.subtype=="string"?e.subtype:"";return n==="error"||r==="error"||r==="failure"||e.is_error===!0||n==="result"&&r&&r!=="success"?J(t)??ve:null}function W(t,e){return!t||t===ve&&e!==ve?e:t}function vn(t){if(typeof t=="string"&&t.trim())return t;if(!Array.isArray(t))return null;let e=t.map(n=>{if(!n||typeof n!="object")return"";let r=n;return typeof r.text=="string"?r.text:""}).filter(Boolean).join("");return e.trim()?e:null}function J(t){if(typeof t=="string"&&t&&!tt(t))return t;if(!t||typeof t!="object")return null;let e=t;for(let r of["message","detail","reason","error"]){let s=e[r];if(typeof s=="string"&&s&&!tt(s))return s}let n=J(e.error);if(n)return n;for(let r of Object.values(e)){let s=J(r);if(s)return s}return null}function qs(t){return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(t)}function tt(t){let e=t.trim().toLowerCase();return e==="error"||e==="failure"}function zs(t){try{return JSON.parse(t)}catch{return null}}import{spawn as Js}from"node:child_process";function bn(t){return new Promise((e,n)=>{let r=[],s=[],o="",i=[],a="",u="",c="",l=Js(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["pipe","pipe","pipe"]});if(l.stdin.on("error",()=>{}),t.signal?.aborted){l.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{l.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),l.stdin.end(t.stdin??""),l.stdout.on("data",d=>{u=In(u+d.toString(),p=>{let m=wn(p);if(m){let f=t.onJson(m)??D(m);f&&(a=W(a,f));let y=U(m);y&&(xn(m)?s.push(y):o=Sn(y,o,t.onPartial));return}r.push(p),t.onLog("stdout",p)})}),l.stderr.on("data",d=>{c=In(c+d.toString(),p=>{i.push(p),t.onLog("stderr",p)})}),l.on("error",n),l.on("exit",d=>{if(u.trim()){let m=wn(u.trim());if(m){let f=t.onJson(m)??D(m);f&&(a=W(a,f));let y=U(m);y&&(xn(m)?s.push(y):o=Sn(y,o,t.onPartial))}else r.push(u.trim()),t.onLog("stdout",u.trim())}if(c.trim()&&(i.push(c.trim()),t.onLog("stderr",c.trim())),t.onLog("system",`${t.command} exited with code ${d??"unknown"}`),d===0){e({output:Us(s,o,r)});return}let p=G(Rn(i))??Rn(i);n(new Error(a||p||`${t.command} exited with code ${d}`))})})}function In(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function wn(t){try{return JSON.parse(t)}catch{return null}}function xn(t){return!!(t&&typeof t=="object"&&t.type==="result")}function Sn(t,e,n){let r=t.startsWith(e)?t:`${e}${t}`,s=r.slice(e.length);return s&&n?.(s,r),r}function Us(t,e,n){let r=t.at(-1)?.trim();if(r)return r;let s=e.trim();return s||n.join(`
|
|
33
|
-
`).trim()}function Rn(t){return t.map(e=>e.trim()).filter(Boolean).at(-1)??""}import{mkdir as Gs,readFile as Ws,writeFile as kn}from"node:fs/promises";import{join as Vs}from"node:path";var Hs="kscc-last-message.txt";function Qs(t){return Vs(h(t),Hs)}async function An(t){await Gs(h(t),{recursive:!0});let e=Qs(t);return await kn(e,"","utf8"),e}async function Cn(t,e){await kn(t,e,"utf8")}async function En(t){try{return await Ws(t,"utf8")}catch{return""}}var V=class{type="kscc";busyDeliveryMode="gated";sessions=new E({type:"kscc",displayName:"kscc",buildArgs:et,resolveModel:he,extractSessionId:Ie,extractText:U,extractEventName:nt,summarizeError:D,normalizeError:G,preferFailure:W});capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:!0};async detect(){return!!await this.resolveCommand()}notifyInbox(e,n){return this.sessions.notify(e,n)}async listModels(){let e=await this.resolveCommand();return e?ae(e):[]}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error("kscc runtime is not available");let s=await w(e),o=s?.runtimeType===this.type?s.runtimeSessionId:null,i=o??Tn(),a=o?`resuming ${o}`:`starting new session ${i}`;n.onLog("system",`kscc ${a} in ${n.cwd??process.cwd()}`);let u;try{u=await this.runKsccStream(r,e,n,i,!!o)}catch(c){if(Mn(c))n.onLog("stderr",`kscc stream-json session failed; falling back to print mode. ${c instanceof Error?c.message:""}`),u=await this.runKscc(r,e,n,i,!!o);else if(o){let l=Tn();n.onLog("stderr",`kscc resume ${o} failed; starting a new session ${l}. ${c instanceof Error?c.message:""}`),u=await this.runKsccStream(r,e,n,l,!1).catch(d=>{if(!Mn(d))throw d;return n.onLog("stderr",`kscc stream retry failed; falling back to print mode. ${d instanceof Error?d.message:""}`),this.runKscc(r,e,n,l,!1)})}else throw c}return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:g(e),runtimeType:this.type,runtimeSessionId:u.sessionId,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),n.onLog("system",`kscc session ${u.sessionId}`),u.suppressMessage?{content:u.output.trim(),sessionId:u.sessionId,suppressMessage:!0}:{content:u.output.trim()||"kscc runtime completed without output",sessionId:u.sessionId}}async runKsccStream(e,n,r,s,o){r.onLog("system",o?`kscc stream resume ${s}`:`kscc stream session-id ${s}`);let i=await this.sessions.runTurn({command:e,frame:n,context:r,prompt:await v(n,{workspacePath:r.cwd}),sessionId:s,resume:o});return{output:i.content,sessionId:i.sessionId??s,suppressMessage:i.suppressMessage}}async runKscc(e,n,r,s,o){let i=await v(n,{workspacePath:r.cwd}),a=I(n,he(r.env)),u=await An(n);r.onLog("system",a?`kscc using model override ${a}`:"kscc using configured model"),r.onLog("system",o?`kscc resume ${s}`:`kscc session-id ${s}`);let c=new Set,l=await bn({command:e,args:Ze({frame:n,sessionId:s,resume:o,model:a}),stdin:i,cwd:r.cwd,env:r.env,signal:r.abortSignal,onPartial:r.onPartial,onJson:d=>{let p=Ie(d);p&&c.add(p);let m=nt(d);m&&r.onLog("system",`[kscc:event] ${m}`);let f=G(D(d));return f?(r.onLog("stderr",`[kscc:error] ${f}`),f):null},onLog:r.onLog});return await Cn(u,l.output),{output:l.output||await En(u),sessionId:[...c].at(-1)??s}}async resolveCommand(){return S({command:"kscc",envVars:["KSCC_BIN"]})}};function Mn(t){if(process.env.KSLOCK_KSCC_DISABLE_PRINT_FALLBACK==="1")return!1;let e=t instanceof Error?t.message:String(t);return/process exited|unknown option|unrecognized|input-format|stream-json|stdin|not supported/i.test(e)}function Dn(t){return t.preset==="full_access"?"allow":t.preset==="read_only"?{"*":"deny",read:{"*":"allow","*.env":"deny","*.env.*":"deny","*.env.example":"allow"},glob:"allow",grep:"allow",list:"allow",lsp:"allow",todoread:"allow",edit:"deny",bash:"deny",task:"deny",skill:"deny",todowrite:"deny",webfetch:"deny",websearch:"deny",codesearch:"deny",external_directory:"deny",doom_loop:"deny"}:{"*":"deny",read:{"*":"allow","*.env":"deny","*.env.*":"deny","*.env.example":"allow"},glob:"allow",grep:"allow",list:"allow",lsp:"allow",todoread:"allow",todowrite:"allow",edit:"allow",skill:"allow",bash:{"*":"deny","git status *":"allow","git diff *":"allow","git log *":"allow","git show *":"allow","pnpm test *":"allow","pnpm run test *":"allow","pnpm typecheck *":"allow","pnpm run typecheck *":"allow","pnpm lint *":"allow","pnpm run lint *":"allow","pnpm build *":"allow","pnpm run build *":"allow","npm test *":"allow","npm run test *":"allow","npm run typecheck *":"allow","npm run lint *":"allow","npm run build *":"allow","yarn test *":"allow","yarn typecheck *":"allow","yarn lint *":"allow","yarn build *":"allow","tsc *":"allow","vitest *":"allow","rm *":"deny","sudo *":"deny","chmod *":"deny","chown *":"deny","curl *":"deny","wget *":"deny"},task:"deny",webfetch:"deny",websearch:"deny",codesearch:"deny",external_directory:"deny",doom_loop:"deny"}}var rt="1.14.30";function st(t){return["run","--format","json","--pure",...Ys(t.workspacePath),...Xs(t.sessionId),...Zs(t.model),...eo(t.frame.executionPolicy),"--",t.message]}function ot(t,e){return{...t,OPENCODE_PERMISSION:JSON.stringify(Dn(e))}}function it(t){return t.OPENCODE_MODEL?.trim()||null}function we(t){return!t||Pn(t)?null:`OpenCode CLI ${t} \u6682\u4E0D\u652F\u6301\uFF0C\u5F53\u524D\u8FD0\u884C\u65F6\u8981\u6C42 opencode >= ${rt}\u3002\u8BF7\u5347\u7EA7 opencode \u540E\u91CD\u542F daemon\u3002`}function Pn(t){if(!t)return!0;let e=Fn(t),n=Fn(rt);if(!e||!n)return!0;for(let r=0;r<3;r+=1){if(e[r]>n[r])return!0;if(e[r]<n[r])return!1}return!0}function Fn(t){let e=t.match(/(\d+)\.(\d+)\.(\d+)/);return e?[Number(e[1]),Number(e[2]),Number(e[3])]:null}function Xs(t){return t?["--session",t]:[]}function Ys(t){return t?["--dir",t]:[]}function Zs(t){return t?["--model",t]:[]}function eo(t){return t.preset==="full_access"?["--dangerously-skip-permissions"]:[]}var xe="opencode \u8FD4\u56DE\u9519\u8BEF\uFF0C\u672A\u63D0\u4F9B\u8BE6\u7EC6\u539F\u56E0";function Ln(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","subtype","event","event_name","eventName"])if(typeof e[n]=="string")return e[n];return null}function ut(t){if(!t||typeof t!="object")return null;let e=t;for(let r of["sessionID","sessionId","session_id"])if(typeof e[r]=="string"&&e[r].trim())return e[r];let n=e.session;if(n&&typeof n=="object"){let r=n.id;if(typeof r=="string"&&r.trim())return r}for(let r of Object.values(e)){let s=ut(r);if(s)return s}return null}function ct(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.result=="string"&&e.result.trim())return e.result;if(typeof e.output=="string"&&e.output.trim())return e.output;let n=_n(e.message);if(n)return n;let r=_n(e.part);if(r)return r;if(to(e)){if(typeof e.content=="string"&&e.content.trim())return e.content;if(typeof e.text=="string"&&e.text.trim())return e.text;let s=Se(e.content);if(s)return s;let o=Se(e.parts);if(o)return o}return null}function Re(t){if(!t)return null;let e=no(t),r=(e?H(e):t)?.trim();return!r||at(r)?null:r}function Q(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.type=="string"?e.type.toLowerCase():"",r=typeof e.subtype=="string"?e.subtype.toLowerCase():"";return n.includes("error")||r==="error"||r==="failure"||e.is_error===!0||n==="result"&&r&&r!=="success"?H(t)??xe:null}function lt(t,e){return!t||t===xe&&e!==xe?e:t}function _n(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.role=="string"?e.role.toLowerCase():"",r=typeof e.type=="string"?e.type.toLowerCase():"";return n&&n!=="assistant"?null:typeof e.text=="string"&&e.text.trim()?e.text:typeof e.content=="string"&&e.content.trim()?e.content:r&&r!=="text"&&!r.includes("assistant")&&!r.includes("message")&&!r.includes("part")?null:Se(e.content)??Se(e.parts)}function Se(t){if(typeof t=="string"&&t.trim())return t;if(!Array.isArray(t))return null;let e=t.map(n=>{if(!n||typeof n!="object")return"";let r=n;return typeof r.text=="string"?r.text:typeof r.content=="string"?r.content:""}).filter(Boolean).join("");return e.trim()?e:null}function to(t){let e=typeof t.role=="string"?t.role.toLowerCase():"";if(e&&e!=="assistant")return!1;let n=typeof t.type=="string"?t.type.toLowerCase():"";return n?n==="result"||n==="text"||n.includes("assistant")||n.includes("message")||n.includes("part"):e==="assistant"}function H(t){if(typeof t=="string"&&t&&!at(t))return t;if(!t||typeof t!="object")return null;let e=t;for(let r of["message","detail","reason","error"]){let s=e[r];if(typeof s=="string"&&s&&!at(s))return s}let n=H(e.error);if(n)return n;for(let r of Object.values(e)){let s=H(r);if(s)return s}return null}function at(t){let e=t.trim().toLowerCase();return e==="error"||e==="failure"}function no(t){try{return JSON.parse(t)}catch{return null}}import{spawn as ro}from"node:child_process";function Bn(t){return new Promise((e,n)=>{let r=[],s=[],o="",i=[],a="",u="",c="",l=ro(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["ignore","pipe","pipe"]});if(t.signal?.aborted){l.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{l.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),l.stdout.on("data",d=>{u=jn(u+d.toString(),p=>{let m=On(p);if(m){let f=t.onJson(m)??Q(m);f&&(a=lt(a,f));let y=ct(m);y&&($n(m)?s.push(y):o=Nn(y,o,t.onPartial));return}r.push(p),t.onLog("stdout",p)})}),l.stderr.on("data",d=>{c=jn(c+d.toString(),p=>{i.push(p),t.onLog("stderr",p)})}),l.on("error",n),l.on("exit",d=>{if(u.trim()){let m=On(u.trim());if(m){let f=t.onJson(m)??Q(m);f&&(a=lt(a,f));let y=ct(m);y&&($n(m)?s.push(y):o=Nn(y,o,t.onPartial))}else r.push(u.trim()),t.onLog("stdout",u.trim())}if(c.trim()&&(i.push(c.trim()),t.onLog("stderr",c.trim())),t.onLog("system",`${t.command} exited with code ${d??"unknown"}`),d===0){e({output:so(s,o,r)});return}let p=Re(Kn(i))??Kn(i);n(new Error(a||p||`${t.command} exited with code ${d}`))})})}function jn(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function On(t){try{return JSON.parse(t)}catch{return null}}function $n(t){if(!t||typeof t!="object")return!1;let e=t,n=typeof e.type=="string"?e.type.toLowerCase():"";return n==="result"||n.includes("result")||n.includes("complete")}function Nn(t,e,n){let r=t.startsWith(e)?t:`${e}${t}`,s=r.slice(e.length);return s&&n?.(s,r),r}function so(t,e,n){let r=t.at(-1)?.trim();if(r)return r;let s=e.trim();return s||n.join(`
|
|
34
|
-
`).trim()}function
|
|
37
|
+
`)}};function Rn(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function ro(t){let e=Array.isArray(t.summary)?t.summary.filter(r=>typeof r=="string"):[],n=Array.isArray(t.content)?t.content.filter(r=>typeof r=="string"):[];return[...e,...n].join(`
|
|
38
|
+
`).trim()}function so(){let t=process.env.KSLOCK_RUNTIME_IDLE_TTL_MS;if(!t)return 1800*1e3;let e=Number(t);return!Number.isFinite(e)||e<0?1800*1e3:e}import{spawn as oo}from"node:child_process";var io="Reading additional input from stdin...";function kn(t){return new Promise((e,n)=>{let r=[],s="",o="",i="",a=oo(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["ignore","pipe","pipe"]});if(t.signal?.aborted){a.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{a.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),a.stdout.on("data",u=>{o=bn(o+u.toString(),c=>{let l=An(c);if(l){let d=t.onJson(l);d&&(s=rt(s,d));return}t.onLog("stdout",c)})}),a.stderr.on("data",u=>{i=bn(i+u.toString(),c=>{st(c)||(r.push(c),t.onLog("stderr",c))})}),a.on("error",n),a.on("exit",u=>{if(o.trim()){let c=An(o.trim());if(c){let l=t.onJson(c);l&&(s=rt(s,l))}else t.onLog("stdout",o.trim())}if(i.trim()&&!st(i.trim())&&(r.push(i.trim()),t.onLog("stderr",i.trim())),t.onLog("system",`${t.command} exited with code ${u??"unknown"}`),u===0){e();return}n(new Error(s||ao(r)||`${t.command} exited with code ${u}`))})})}function bn(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function An(t){try{return JSON.parse(t)}catch{return null}}function st(t){return t.trim()===io}function ao(t){return t.map(e=>e.trim()).filter(e=>e&&!st(e)).at(-1)??""}import{readFile as uo}from"node:fs/promises";async function Cn(t){try{return await uo(t,"utf8")}catch{return""}}function En(t){if(!t||typeof t!="object")return null;let e=t,n=co(t)??"";for(let s of["delta","text_delta","content_delta"])if(typeof e[s]=="string"&&e[s])return e[s];if(n.includes("delta")||n.includes("stream")){for(let s of["text","content","message"])if(typeof e[s]=="string"&&e[s])return e[s]}return Tn(e.delta??e.message??e.item)}function Tn(t){if(typeof t=="string"&&t)return t;if(!t||typeof t!="object")return null;let e=t;for(let n of["delta","text_delta","content_delta","text"])if(typeof e[n]=="string"&&e[n])return e[n];for(let n of Object.values(e)){let r=Tn(n);if(r)return r}return null}function co(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","event","event_name","method"])if(typeof e[n]=="string")return e[n];return null}var W=class{type="codex";appServers=new Ie;busyDeliveryMode="direct";capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:!0};async detect(){return!!await this.resolveCommand()}notifyInbox(e,n){return this.appServers.notify(e,n)}async listModels(){let e=await this.resolveCommand();return e?tn(e):[]}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error("codex runtime is not available");let s=await I(e),o=s?.runtimeType===this.type?s.runtimeSessionId:null,i=o?`resuming ${o}`:"starting new session";n.onLog("system",`codex ${i} in ${n.cwd??process.cwd()}`);let a;try{a=await this.runCodexAppServer(r,e,n,o)}catch(c){if(Mn(c))n.onLog("stderr",`codex app-server failed; falling back to codex exec. ${c instanceof Error?c.message:""}`),a=await this.runCodex(r,e,n,o);else if(o)n.onLog("stderr",`codex resume ${o} failed; starting a new session. ${c instanceof Error?c.message:""}`),a=await this.runCodexAppServer(r,e,n,null).catch(l=>{if(!Mn(l))throw l;return n.onLog("stderr",`codex app-server retry failed; falling back to codex exec. ${l instanceof Error?l.message:""}`),this.runCodex(r,e,n,null)});else throw c}let u=a.sessionId??o??null;return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:f(e),runtimeType:this.type,runtimeSessionId:u,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),u?n.onLog("system",`codex session ${u}`):n.onLog("system","codex completed without exposing a resumable session id"),a.suppressMessage?{content:a.output.trim(),sessionId:u,suppressMessage:!0}:{content:a.output.trim()||"codex runtime completed without output",sessionId:u}}async runCodexAppServer(e,n,r,s){let o=await w(n,{workspacePath:r.cwd}),i=v(n,he(r.env));r.onLog("system",i?`codex app-server using model override ${i}`:"codex app-server using configured model"),r.onLog("system",`codex app-server sandbox ${E(n.executionPolicy)}`);let a=await this.appServers.runTurn({command:e,frame:n,context:r,prompt:o,sessionId:s,model:i});return{output:a.content,sessionId:a.sessionId??null,suppressMessage:a.suppressMessage}}async runCodex(e,n,r,s){let o=y(n);await lo(o,{recursive:!0});let i=mo(o,"last-message.txt");await po(i,"","utf8");let a=await w(n,{workspacePath:r.cwd}),u=v(n,he(r.env));r.onLog("system",u?`codex using model override ${u}`:"codex using configured model"),r.onLog("system",`codex sandbox ${E(n.executionPolicy)}`);let c=new Set;return await kn({command:e,args:et({frame:n,prompt:a,outputFile:i,model:u,sessionId:s}),cwd:r.cwd,env:r.env,signal:r.abortSignal,onJson:l=>{let d=En(l);d&&r.onPartial?.(d);let m=nt(l);m&&c.add(m);let p=we(l);p&&r.onLog("system",`[codex:event] ${p}`);let g=G(F(l))??ve(l);return g?(r.onLog("stderr",`[codex:error] ${g}`),g):null},onLog:r.onLog}),{output:await Cn(i),sessionId:[...c].at(-1)??null}}async resolveCommand(){return S({command:"codex",envVars:["CODEX_BIN","CODEX_CLI_PATH"]})}};function Mn(t){if(process.env.KSLOCK_CODEX_DISABLE_EXEC_FALLBACK==="1")return!1;let e=t instanceof Error?t.message:String(t);return/app-server exited|unrecognized|unknown command|invalid subcommand|not supported/i.test(e)}import{randomUUID as Jn}from"node:crypto";function ot(t){return t.preset==="read_only"?["--permission-mode","dontAsk","--tools","Read,Grep,Glob,LS"]:t.preset==="full_access"?["--dangerously-skip-permissions"]:["--permission-mode","acceptEdits","--allowedTools",["Read","Grep","Glob","LS","Edit","MultiEdit","Write","Bash(git status *)","Bash(git diff *)","Bash(git log *)","Bash(git show *)","Bash(pnpm test *)","Bash(pnpm run test *)","Bash(pnpm typecheck *)","Bash(pnpm run typecheck *)","Bash(pnpm lint *)","Bash(pnpm run lint *)","Bash(pnpm build *)","Bash(pnpm run build *)","Bash(npm test *)","Bash(npm run test *)","Bash(npm run typecheck *)","Bash(npm run lint *)","Bash(npm run build *)","Bash(yarn test *)","Bash(yarn typecheck *)","Bash(yarn lint *)","Bash(yarn build *)","Bash(tsc *)","Bash(vitest *)"].join(","),"--disallowedTools",["Bash(rm *)","Bash(sudo *)","Bash(chmod *)","Bash(chown *)","Bash(curl *)","Bash(wget *)"].join(",")]}function it(t){return["-p","--output-format","stream-json","--verbose","--include-partial-messages",...t.resume?["--resume",t.sessionId]:["--session-id",t.sessionId],...Dn(t.model),...ot(t.frame.executionPolicy)]}function at(t){return["--output-format","stream-json","--input-format","stream-json","--verbose","--include-partial-messages",...t.resume?["--resume",t.sessionId]:["--session-id",t.sessionId],...Dn(t.model),...ot(t.frame.executionPolicy)]}function xe(t){return t.KSCC_MODEL?.trim()||t.ANTHROPIC_MODEL?.trim()||null}function Dn(t){return t?["--model",t]:[]}var Se="kscc \u8FD4\u56DE\u9519\u8BEF\uFF0C\u672A\u63D0\u4F9B\u8BE6\u7EC6\u539F\u56E0";function ct(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","subtype","event","event_name"])if(typeof e[n]=="string")return e[n];return null}function Re(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["session_id","sessionId"])if(typeof e[n]=="string"&&go(e[n]))return e[n];for(let n of Object.values(e)){let r=Re(n);if(r)return r}return null}function H(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.result=="string"&&e.result.trim())return e.result;if(typeof e.content=="string"&&e.content.trim())return e.content;let n=e.message;if(n&&typeof n=="object"){let r=Pn(n.content);if(r)return r}return Pn(e.content)}function Q(t){if(!t)return null;let e=fo(t),r=(e?V(e):t)?.trim();return!r||ut(r)?null:r}function _(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.type=="string"?e.type:"",r=typeof e.subtype=="string"?e.subtype:"";return n==="error"||r==="error"||r==="failure"||e.is_error===!0||n==="result"&&r&&r!=="success"?V(t)??Se:null}function X(t,e){return!t||t===Se&&e!==Se?e:t}function Pn(t){if(typeof t=="string"&&t.trim())return t;if(!Array.isArray(t))return null;let e=t.map(n=>{if(!n||typeof n!="object")return"";let r=n;return typeof r.text=="string"?r.text:""}).filter(Boolean).join("");return e.trim()?e:null}function V(t){if(typeof t=="string"&&t&&!ut(t))return t;if(!t||typeof t!="object")return null;let e=t;for(let r of["message","detail","reason","error"]){let s=e[r];if(typeof s=="string"&&s&&!ut(s))return s}let n=V(e.error);if(n)return n;for(let r of Object.values(e)){let s=V(r);if(s)return s}return null}function go(t){return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(t)}function ut(t){let e=t.trim().toLowerCase();return e==="error"||e==="failure"}function fo(t){try{return JSON.parse(t)}catch{return null}}import{spawn as ho}from"node:child_process";function On(t){return new Promise((e,n)=>{let r=[],s=[],o="",i=[],a="",u="",c="",l=ho(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["pipe","pipe","pipe"]});if(l.stdin.on("error",()=>{}),t.signal?.aborted){l.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{l.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),l.stdin.end(t.stdin??""),l.stdout.on("data",d=>{u=Fn(u+d.toString(),m=>{let p=_n(m);if(p){let g=t.onJson(p)??_(p);g&&(a=X(a,g));let h=H(p);h&&(Ln(p)?s.push(h):o=jn(h,o,t.onPartial));return}r.push(m),t.onLog("stdout",m)})}),l.stderr.on("data",d=>{c=Fn(c+d.toString(),m=>{i.push(m),t.onLog("stderr",m)})}),l.on("error",n),l.on("exit",d=>{if(u.trim()){let p=_n(u.trim());if(p){let g=t.onJson(p)??_(p);g&&(a=X(a,g));let h=H(p);h&&(Ln(p)?s.push(h):o=jn(h,o,t.onPartial))}else r.push(u.trim()),t.onLog("stdout",u.trim())}if(c.trim()&&(i.push(c.trim()),t.onLog("stderr",c.trim())),t.onLog("system",`${t.command} exited with code ${d??"unknown"}`),d===0){e({output:yo(s,o,r)});return}let m=Q($n(i))??$n(i);n(new Error(a||m||`${t.command} exited with code ${d}`))})})}function Fn(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function _n(t){try{return JSON.parse(t)}catch{return null}}function Ln(t){return!!(t&&typeof t=="object"&&t.type==="result")}function jn(t,e,n){let r=t.startsWith(e)?t:`${e}${t}`,s=r.slice(e.length);return s&&n?.(s,r),r}function yo(t,e,n){let r=t.at(-1)?.trim();if(r)return r;let s=e.trim();return s||n.join(`
|
|
39
|
+
`).trim()}function $n(t){return t.map(e=>e.trim()).filter(Boolean).at(-1)??""}import{mkdir as wo,readFile as vo,writeFile as Nn}from"node:fs/promises";import{join as Io}from"node:path";var xo="kscc-last-message.txt";function So(t){return Io(y(t),xo)}async function Kn(t){await wo(y(t),{recursive:!0});let e=So(t);return await Nn(e,"","utf8"),e}async function Bn(t,e){await Nn(t,e,"utf8")}async function qn(t){try{return await vo(t,"utf8")}catch{return""}}var Y=class{type="kscc";busyDeliveryMode="gated";sessions=new D({type:"kscc",displayName:"kscc",buildArgs:at,resolveModel:xe,extractSessionId:Re,extractText:H,extractEventName:ct,summarizeError:_,normalizeError:Q,preferFailure:X});capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:!0};async detect(){return!!await this.resolveCommand()}notifyInbox(e,n){return this.sessions.notify(e,n)}async listModels(){let e=await this.resolveCommand();return e?de(e):[]}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error("kscc runtime is not available");let s=await I(e),o=s?.runtimeType===this.type?s.runtimeSessionId:null,i=o??Jn(),a=o?`resuming ${o}`:`starting new session ${i}`;n.onLog("system",`kscc ${a} in ${n.cwd??process.cwd()}`);let u;try{u=await this.runKsccStream(r,e,n,i,!!o)}catch(c){if(zn(c))n.onLog("stderr",`kscc stream-json session failed; falling back to print mode. ${c instanceof Error?c.message:""}`),u=await this.runKscc(r,e,n,i,!!o);else if(o){let l=Jn();n.onLog("stderr",`kscc resume ${o} failed; starting a new session ${l}. ${c instanceof Error?c.message:""}`),u=await this.runKsccStream(r,e,n,l,!1).catch(d=>{if(!zn(d))throw d;return n.onLog("stderr",`kscc stream retry failed; falling back to print mode. ${d instanceof Error?d.message:""}`),this.runKscc(r,e,n,l,!1)})}else throw c}return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:f(e),runtimeType:this.type,runtimeSessionId:u.sessionId,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),n.onLog("system",`kscc session ${u.sessionId}`),u.suppressMessage?{content:u.output.trim(),sessionId:u.sessionId,suppressMessage:!0}:{content:u.output.trim()||"kscc runtime completed without output",sessionId:u.sessionId}}async runKsccStream(e,n,r,s,o){r.onLog("system",o?`kscc stream resume ${s}`:`kscc stream session-id ${s}`);let i=await this.sessions.runTurn({command:e,frame:n,context:r,prompt:await w(n,{workspacePath:r.cwd}),sessionId:s,resume:o});return{output:i.content,sessionId:i.sessionId??s,suppressMessage:i.suppressMessage}}async runKscc(e,n,r,s,o){let i=await w(n,{workspacePath:r.cwd}),a=v(n,xe(r.env)),u=await Kn(n);r.onLog("system",a?`kscc using model override ${a}`:"kscc using configured model"),r.onLog("system",o?`kscc resume ${s}`:`kscc session-id ${s}`);let c=new Set,l=await On({command:e,args:it({frame:n,sessionId:s,resume:o,model:a}),stdin:i,cwd:r.cwd,env:r.env,signal:r.abortSignal,onPartial:r.onPartial,onJson:d=>{let m=Re(d);m&&c.add(m);let p=ct(d);p&&r.onLog("system",`[kscc:event] ${p}`);let g=Q(_(d));return g?(r.onLog("stderr",`[kscc:error] ${g}`),g):null},onLog:r.onLog});return await Bn(u,l.output),{output:l.output||await qn(u),sessionId:[...c].at(-1)??s}}async resolveCommand(){return S({command:"kscc",envVars:["KSCC_BIN"]})}};function zn(t){if(process.env.KSLOCK_KSCC_DISABLE_PRINT_FALLBACK==="1")return!1;let e=t instanceof Error?t.message:String(t);return/process exited|unknown option|unrecognized|input-format|stream-json|stdin|not supported/i.test(e)}function Un(t){return t.preset==="full_access"?"allow":t.preset==="read_only"?{"*":"deny",read:{"*":"allow","*.env":"deny","*.env.*":"deny","*.env.example":"allow"},glob:"allow",grep:"allow",list:"allow",lsp:"allow",todoread:"allow",edit:"deny",bash:"deny",task:"deny",skill:"deny",todowrite:"deny",webfetch:"deny",websearch:"deny",codesearch:"deny",external_directory:"deny",doom_loop:"deny"}:{"*":"deny",read:{"*":"allow","*.env":"deny","*.env.*":"deny","*.env.example":"allow"},glob:"allow",grep:"allow",list:"allow",lsp:"allow",todoread:"allow",todowrite:"allow",edit:"allow",skill:"allow",bash:{"*":"deny","git status *":"allow","git diff *":"allow","git log *":"allow","git show *":"allow","pnpm test *":"allow","pnpm run test *":"allow","pnpm typecheck *":"allow","pnpm run typecheck *":"allow","pnpm lint *":"allow","pnpm run lint *":"allow","pnpm build *":"allow","pnpm run build *":"allow","npm test *":"allow","npm run test *":"allow","npm run typecheck *":"allow","npm run lint *":"allow","npm run build *":"allow","yarn test *":"allow","yarn typecheck *":"allow","yarn lint *":"allow","yarn build *":"allow","tsc *":"allow","vitest *":"allow","rm *":"deny","sudo *":"deny","chmod *":"deny","chown *":"deny","curl *":"deny","wget *":"deny"},task:"deny",webfetch:"deny",websearch:"deny",codesearch:"deny",external_directory:"deny",doom_loop:"deny"}}var lt="1.14.30";function dt(t){return["run","--format","json","--pure",...bo(t.workspacePath),...Ro(t.sessionId),...Ao(t.model),...ko(t.frame.executionPolicy),"--",t.message]}function pt(t,e){return{...t,OPENCODE_PERMISSION:JSON.stringify(Un(e))}}function mt(t){return t.OPENCODE_MODEL?.trim()||null}function be(t){return!t||Wn(t)?null:`OpenCode CLI ${t} \u6682\u4E0D\u652F\u6301\uFF0C\u5F53\u524D\u8FD0\u884C\u65F6\u8981\u6C42 opencode >= ${lt}\u3002\u8BF7\u5347\u7EA7 opencode \u540E\u91CD\u542F daemon\u3002`}function Wn(t){if(!t)return!0;let e=Gn(t),n=Gn(lt);if(!e||!n)return!0;for(let r=0;r<3;r+=1){if(e[r]>n[r])return!0;if(e[r]<n[r])return!1}return!0}function Gn(t){let e=t.match(/(\d+)\.(\d+)\.(\d+)/);return e?[Number(e[1]),Number(e[2]),Number(e[3])]:null}function Ro(t){return t?["--session",t]:[]}function bo(t){return t?["--dir",t]:[]}function Ao(t){return t?["--model",t]:[]}function ko(t){return t.preset==="full_access"?["--dangerously-skip-permissions"]:[]}var Ae="opencode \u8FD4\u56DE\u9519\u8BEF\uFF0C\u672A\u63D0\u4F9B\u8BE6\u7EC6\u539F\u56E0";function Hn(t){if(!t||typeof t!="object")return null;let e=t;for(let n of["type","subtype","event","event_name","eventName"])if(typeof e[n]=="string")return e[n];return null}function ft(t){if(!t||typeof t!="object")return null;let e=t;for(let r of["sessionID","sessionId","session_id"])if(typeof e[r]=="string"&&e[r].trim())return e[r];let n=e.session;if(n&&typeof n=="object"){let r=n.id;if(typeof r=="string"&&r.trim())return r}for(let r of Object.values(e)){let s=ft(r);if(s)return s}return null}function ht(t){if(!t||typeof t!="object")return null;let e=t;if(typeof e.result=="string"&&e.result.trim())return e.result;if(typeof e.output=="string"&&e.output.trim())return e.output;let n=Vn(e.message);if(n)return n;let r=Vn(e.part);if(r)return r;if(Co(e)){if(typeof e.content=="string"&&e.content.trim())return e.content;if(typeof e.text=="string"&&e.text.trim())return e.text;let s=ke(e.content);if(s)return s;let o=ke(e.parts);if(o)return o}return null}function Ce(t){if(!t)return null;let e=Eo(t),r=(e?Z(e):t)?.trim();return!r||gt(r)?null:r}function ee(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.type=="string"?e.type.toLowerCase():"",r=typeof e.subtype=="string"?e.subtype.toLowerCase():"";return n.includes("error")||r==="error"||r==="failure"||e.is_error===!0||n==="result"&&r&&r!=="success"?Z(t)??Ae:null}function yt(t,e){return!t||t===Ae&&e!==Ae?e:t}function Vn(t){if(!t||typeof t!="object")return null;let e=t,n=typeof e.role=="string"?e.role.toLowerCase():"",r=typeof e.type=="string"?e.type.toLowerCase():"";return n&&n!=="assistant"?null:typeof e.text=="string"&&e.text.trim()?e.text:typeof e.content=="string"&&e.content.trim()?e.content:r&&r!=="text"&&!r.includes("assistant")&&!r.includes("message")&&!r.includes("part")?null:ke(e.content)??ke(e.parts)}function ke(t){if(typeof t=="string"&&t.trim())return t;if(!Array.isArray(t))return null;let e=t.map(n=>{if(!n||typeof n!="object")return"";let r=n;return typeof r.text=="string"?r.text:typeof r.content=="string"?r.content:""}).filter(Boolean).join("");return e.trim()?e:null}function Co(t){let e=typeof t.role=="string"?t.role.toLowerCase():"";if(e&&e!=="assistant")return!1;let n=typeof t.type=="string"?t.type.toLowerCase():"";return n?n==="result"||n==="text"||n.includes("assistant")||n.includes("message")||n.includes("part"):e==="assistant"}function Z(t){if(typeof t=="string"&&t&&!gt(t))return t;if(!t||typeof t!="object")return null;let e=t;for(let r of["message","detail","reason","error"]){let s=e[r];if(typeof s=="string"&&s&&!gt(s))return s}let n=Z(e.error);if(n)return n;for(let r of Object.values(e)){let s=Z(r);if(s)return s}return null}function gt(t){let e=t.trim().toLowerCase();return e==="error"||e==="failure"}function Eo(t){try{return JSON.parse(t)}catch{return null}}import{spawn as To}from"node:child_process";function tr(t){return new Promise((e,n)=>{let r=[],s=[],o="",i=[],a="",u="",c="",l=To(t.command,t.args,{cwd:t.cwd||process.cwd(),env:t.env,stdio:["ignore","pipe","pipe"]});if(t.signal?.aborted){l.kill("SIGTERM"),n(new Error("runtime_cancelled"));return}t.signal?.addEventListener("abort",()=>{l.kill("SIGTERM"),n(new Error("runtime_cancelled"))},{once:!0}),l.stdout.on("data",d=>{u=Qn(u+d.toString(),m=>{let p=Xn(m);if(p){let g=t.onJson(p)??ee(p);g&&(a=yt(a,g));let h=ht(p);h&&(Yn(p)?s.push(h):o=Zn(h,o,t.onPartial));return}r.push(m),t.onLog("stdout",m)})}),l.stderr.on("data",d=>{c=Qn(c+d.toString(),m=>{i.push(m),t.onLog("stderr",m)})}),l.on("error",n),l.on("exit",d=>{if(u.trim()){let p=Xn(u.trim());if(p){let g=t.onJson(p)??ee(p);g&&(a=yt(a,g));let h=ht(p);h&&(Yn(p)?s.push(h):o=Zn(h,o,t.onPartial))}else r.push(u.trim()),t.onLog("stdout",u.trim())}if(c.trim()&&(i.push(c.trim()),t.onLog("stderr",c.trim())),t.onLog("system",`${t.command} exited with code ${d??"unknown"}`),d===0){e({output:Mo(s,o,r)});return}let m=Ce(er(i))??er(i);n(new Error(a||m||`${t.command} exited with code ${d}`))})})}function Qn(t,e){let n=t.split(/\r?\n/),r=n.pop()??"";for(let s of n)s.trim()&&e(s);return r}function Xn(t){try{return JSON.parse(t)}catch{return null}}function Yn(t){if(!t||typeof t!="object")return!1;let e=t,n=typeof e.type=="string"?e.type.toLowerCase():"";return n==="result"||n.includes("result")||n.includes("complete")}function Zn(t,e,n){let r=t.startsWith(e)?t:`${e}${t}`,s=r.slice(e.length);return s&&n?.(s,r),r}function Mo(t,e,n){let r=t.at(-1)?.trim();if(r)return r;let s=e.trim();return s||n.join(`
|
|
40
|
+
`).trim()}function er(t){return t.map(e=>e.trim()).filter(Boolean).at(-1)??""}import{mkdir as Do,readFile as Po,writeFile as nr}from"node:fs/promises";import{join as Fo}from"node:path";var _o="opencode-last-message.txt";function Lo(t){return Fo(y(t),_o)}async function rr(t){await Do(y(t),{recursive:!0});let e=Lo(t);return await nr(e,"","utf8"),e}async function sr(t,e){await nr(t,e,"utf8")}async function or(t){try{return await Po(t,"utf8")}catch{return""}}var te=class{type="opencode";busyDeliveryMode="queue";capabilities={supportsSession:!0,supportsStreaming:!0,supportsExecutionPolicy:!0};async detect(){let e=await this.resolveCommand();return e?!be(await qe(e)):!1}async listModels(){let e=await this.resolveCommand();return e?nn(e):[]}async handleDelivery(e,n){let r=await this.resolveCommand();if(!r)throw new Error("opencode runtime is not available");let s=be(await qe(r));if(s)throw new Error(s);let o=await I(e),i=o?.runtimeType===this.type?o.runtimeSessionId:null,a=i?`resuming ${i}`:"starting new session";n.onLog("system",`opencode ${a} in ${n.cwd??process.cwd()}`);let u;try{u=await this.runOpenCode(r,e,n,i)}catch(c){if(!i)throw c;n.onLog("stderr",`opencode resume ${i} failed; starting a new session. ${c instanceof Error?c.message:""}`),u=await this.runOpenCode(r,e,n,null)}return await x({agentId:e.agentId,channelId:e.channelId,runtimeScopeKey:f(e),runtimeType:this.type,runtimeSessionId:u.sessionId,workspacePath:n.cwd??null,updatedAt:new Date().toISOString()}),u.sessionId&&n.onLog("system",`opencode session ${u.sessionId}`),{content:u.output.trim()||"opencode runtime completed without output",sessionId:u.sessionId}}async runOpenCode(e,n,r,s){let o=await w(n,{workspacePath:r.cwd}),i=v(n,mt(r.env)),a=await rr(n),u=pt(r.env,n.executionPolicy);r.onLog("system",i?`opencode using model override ${i}`:"opencode using configured model"),r.onLog("system",s?`opencode session ${s}`:"opencode new session");let c=new Set,l=await tr({command:e,args:dt({frame:n,message:o,sessionId:s,model:i,workspacePath:r.cwd}),cwd:r.cwd,env:u,signal:r.abortSignal,onPartial:r.onPartial,onJson:d=>{let m=ft(d);m&&c.add(m);let p=Hn(d);p&&r.onLog("system",`[opencode:event] ${p}`);let g=Ce(ee(d));return g?(r.onLog("stderr",`[opencode:error] ${g}`),g):null},onLog:r.onLog});return await sr(a,l.output),{output:l.output||await or(a),sessionId:[...c].at(-1)??s}}async resolveCommand(){return S({command:"opencode",envVars:["OPENCODE_BIN"]})}};var wt=class{runtimes=new Map;constructor(e){for(let n of e)this.runtimes.set(n.type,n)}get(e){let n=this.runtimes.get(e);if(!n)throw new Error(`runtime ${e} is not registered`);return n}detectable(){return[...this.runtimes.values()]}async detectCapabilities(){return Promise.all(this.detectable().map(async e=>{try{let n=e.detect?await e.detect():!0,r=n&&e.listModels?await e.listModels().catch(()=>[]):[];return{type:e.type,available:n,...e.capabilities,...r.length>0?{models:r}:{}}}catch{return{type:e.type,available:!1,...e.capabilities}}}))}};function ir(){return new wt([new W,new z,new Y,new te,...We.map(t=>new N(t))])}var Ee=class{runtimes=ir();publisher;runner;queue;constructor(e){this.publisher=new re(e),this.runner=new ce(this.runtimes,this.publisher),this.queue=new se((n,r)=>{ae(n,n.deliveryId),this.publisher.failed(n,r),this.publisher.status(n,"error")})}async deliver(e){await this.queue.enqueue(e,(n,r)=>this.runner.run(n,r),{allowBusyDelivery:!0,onBusyDelivery:n=>this.handleBusyDelivery(n)})}cancelDelivery(e,n="cancelled_by_user"){this.queue.cancel(e,n)}handlePermissionResponse(e){}async detectAvailableRuntimes(){return(await this.detectRuntimeCapabilities()).filter(n=>n.available).map(n=>n.type)}async detectRuntimeCapabilities(){return(await this.runtimes.detectCapabilities()).map(n=>({...n,available:n.available}))}async handleBusyDelivery(e){let n=this.runtimes.get(e.runtimeType),r=await Et(e),s=O(e),o=Ot({pendingCount:r.messages.length,checkMessagesCommand:s.KSLOCK_CHECK_MESSAGES_COMMAND,inboxFile:s.KSLOCK_INBOX_FILE});this.publisher.delivered(e),this.publisher.runtimeLog(e,"system",`queued in agent inbox (${r.messages.length} pending)`),await n.notifyInbox?.(e,o)||this.publisher.runtimeLog(e,"system","agent inbox notification deferred until the queued delivery starts")}};var Te=class{frames=[];enqueue(e){return jo(e)?(this.frames.push(e),this.frames.length>200&&this.frames.splice(0,this.frames.length-200),!0):!1}drain(){return this.frames.splice(0)}get size(){return this.frames.length}};function jo(t){return t.type==="agent:delivery_ack"||t.type==="agent:message"||t.type==="agent:status"||t.type==="task:status"}var Me=class{constructor(e){this.config=e}ws=null;reconnectAttempts=0;reconnectTimer=null;stopped=!1;outbox=new Te;agentManager=new Ee(e=>this.send(e));connect(){this.stopped=!1;let e=this.buildWebSocketUrl();this.ws=new ar(e),this.ws.on("open",()=>{this.handleOpen()}),this.ws.on("message",n=>{let r=$o(n.toString());r&&this.handleFrame(r)}),this.ws.on("close",(n,r)=>{console.log(`[Daemon] Disconnected${Oo(n,r)}`),this.ws=null,this.scheduleReconnect()}),this.ws.on("error",n=>{console.error(`[Daemon] WebSocket error: ${n.message}`)})}close(){this.stopped=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws?.close()}async handleFrame(e){if(e.type==="ping"){this.send({type:"pong",requestId:e.requestId});return}if(e.type==="error"){console.error(`[Daemon] Server error ${e.code}: ${e.message}`),(e.code==="invalid_machine_key"||e.code==="machine_key_revoked")&&(this.stopped=!0);return}if(e.type==="agent:deliver"){await this.agentManager.deliver(e);return}if(e.type==="agent:cancel"){this.agentManager.cancelDelivery(e.deliveryId,e.reason);return}e.type==="permission:response"&&this.agentManager.handlePermissionResponse(e)}async handleOpen(){this.reconnectAttempts=0,console.log(`[Daemon] Connected to ${this.config.serverUrl}`);let e=await this.agentManager.detectRuntimeCapabilities();this.send({type:"machine:ready",daemonVersion:this.config.daemonVersion,hostname:this.config.hostname,os:this.config.os,arch:this.config.arch,availableRuntimes:e.filter(n=>n.available).map(n=>n.type),runtimeCapabilities:e}),this.flushOutbox()}send(e){this.sendNow(e)||this.stopped||this.outbox.enqueue(e)&&console.warn(`[Daemon] Queued ${e.type}; websocket is not open`)}sendNow(e){if(!this.ws||this.ws.readyState!==ar.OPEN)return!1;try{return this.ws.send(JSON.stringify(e)),!0}catch{return!1}}flushOutbox(){if(this.outbox.size===0)return;let e=this.outbox.drain();console.log(`[Daemon] Flushing ${e.length} queued frame(s)`);for(let n of e)this.sendNow(n)||this.outbox.enqueue(n)}buildWebSocketUrl(){return`${this.config.serverUrl.replace(/^http/,"ws")}/daemon/connect?key=${encodeURIComponent(this.config.machineKey)}`}scheduleReconnect(){if(this.stopped||this.reconnectTimer)return;let e=Math.min(this.config.reconnectBaseMs*2**this.reconnectAttempts,3e4);this.reconnectAttempts+=1,console.log(`[Daemon] Reconnecting in ${e}ms`),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.stopped||this.connect()},e)}};function $o(t){try{return JSON.parse(t)}catch{return null}}function Oo(t,e){let n=e.toString();return!t&&!n?"":` (code ${t}${n?`, reason: ${n}`:""})`}function cr(t=process.argv.slice(2)){if(t[0]==="check-messages"||t[0]==="check_messages")return No(t.slice(1)),null;if(t.includes("--help")||t.includes("-h"))return console.log(Fe),null;if(t.includes("--version")||t.includes("-v"))return console.log(Pe()),null;xt();let e=It(t);if(!e)return console.error(Fe),process.exitCode=1,null;let n=new Me(e);n.connect();let r=()=>{n.close(),process.exit(0)};return process.once("SIGINT",r),process.once("SIGTERM",r),n}async function No(t){let e=ur(t,"--agent-id")??process.env.AGENT_ID,n=ur(t,"--channel-id")??process.env.CHANNEL_ID;if(!e){console.error("Usage: kslock-daemon check-messages --agent-id <agent-id> [--channel-id <channel-id>]"),process.exitCode=1;return}let r=await Tt({agentId:e,channelId:n});if(t.includes("--json")){console.log(JSON.stringify(r,null,2));return}console.log($e(r))}function ur(t,e){let n=t.indexOf(e);return n<0?null:t[n+1]??null}cr();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kslock-daemon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Local machine daemon for kslock agent collaboration.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"esbuild": "0.25.12",
|
|
29
|
+
"tsx": "^4.19.2",
|
|
29
30
|
"@types/ws": "^8.5.13"
|
|
30
31
|
},
|
|
31
32
|
"scripts": {
|