@linzumi/cli 1.0.269 → 1.0.271

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.
@@ -157,7 +157,7 @@ Open: ${e.verificationUri}
157
157
  `;case"start_failed":return`Could not mint a device authorization code (${e.reason}); retrying in ${Math.round(e.retryInMs/1e3)}s.
158
158
  `}}function D_(e){let t=Math.floor(e/6e4),r=Math.floor(t/60),n=t%60;return r>0?`${r}h ${n}m`:`${n}m`}async function L_(e){let t=e.deps??{},r=t.startDeviceAuthorization??$_,n=t.pollDeviceCodeForToken??z_,o=t.now??Date.now,i=t.sleep??(g=>new Promise(y=>setTimeout(y,g))),s=e.writeStderr??(g=>process.stderr.write(g)),a=e.isInteractive??process.stderr.isTTY===!0,c=t.report??(g=>s(JR(g))),d=t.log??(()=>{}),u=We(e.kandanUrl),p=o(),m=0,f,h=0;for(;;){let g;try{g=await r({httpBaseUrl:u,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,identity:e.identity})}catch(w){h+=1;let k=Math.min(UR,qR*2**(h-1)),O=w instanceof Error?w.message:String(w);c({kind:"start_failed",reason:O,retryInMs:k}),d("device_wait.start_failed",{reason:O,retryInMs:k,attempt:h}),await i(k);continue}h=0,m+=1;let y=ZR({cycle:m,nowMs:o(),lastLoudPromptAtMs:f,isInteractive:a});y==="prompt"||y==="summary"?(f=o(),c({kind:y,cycle:m,userCode:g.userCode,verificationUri:g.verificationUri,waitedMs:o()-p})):y==="refresh_line"&&c({kind:"refresh_line",cycle:m,userCode:g.userCode,verificationUri:g.verificationUri,waitedMs:o()-p}),d("device_wait.code_issued",{cycle:m,verificationUri:g.verificationUri});let v;for(;v=await n({httpBaseUrl:u,deviceCode:g.deviceCode,expiresInSeconds:g.expiresInSeconds}),v.kind==="transient";)c({kind:"transient",reason:v.reason,waitedMs:o()-p}),d("device_wait.transient_poll_failure",{cycle:m,reason:v.reason,httpStatus:v.httpStatus??null}),await i(LR);switch(v.kind){case"token":return d("device_wait.authorized",{cycle:m,waitedMs:o()-p}),v.token;case"denied":throw new Error("local runner device authorization was denied - a signed-in user rejected this computer");case"code_expired":case"consumed":d("device_wait.code_retired",{cycle:m,outcome:v.kind});continue;case"rejected":c({kind:"transient",reason:T_(v.reason,v.httpStatus),waitedMs:o()-p}),d("device_wait.code_rejected",{cycle:m,reason:v.reason??null,httpStatus:v.httpStatus});continue}}}import{randomUUID as G_}from"node:crypto";import{chmodSync as F_,existsSync as Ml,linkSync as WR,mkdirSync as K_,readFileSync as Q_,realpathSync as yN,unlinkSync as BR,writeFileSync as Y_}from"node:fs";import{homedir as HR}from"node:os";import{basename as Il,dirname as Lo,join as Cl,resolve as V_}from"node:path";var q_="wss://serve.linzumi.com";import{homedir as FR}from"node:os";import{isAbsolute as lN,relative as pN,resolve as VR}from"node:path";import{delimiter as tN,isAbsolute as rN,join as U_,parse as nN,resolve as oN,sep as iN}from"node:path";var sN=[".volta",".nvm",".npm",".asdf",".fnm",".bun",U_(".cargo","bin"),U_(".local","bin")];function J_(e){return e==="~"?Z_():e.startsWith("~/")?VR(Z_(),e.slice(2)):e}function Z_(){let e=process.env.HOME;return e===void 0||e.trim()===""?FR():e}var jl=384,Dt="prod";function Pn(e=process.env){let t=e.LINZUMI_CONFIG_FILE;return t!==void 0&&t.trim()!==""?V_(J_(t)):V_(HR(),".linzumi","config.json")}function qo(e){let t=We(e),r=We(q_);return t===r?Dt:t}function GR(e){let t=qo(e);return t===Dt?Dt:Buffer.from(t).toString("base64url")}function W_(e=Pn()){return eb(e)}function B_(e,t=Pn()){return eb(t,e)}function X_(e,t=Pn(),r=ib){if(qo(e)===Dt)return KR(t,r);let n=B_(e,t);if(n.runnerId!==void 0)return n.runnerId;let o=ob(t,r,e),i=B_(e,t),s=i.runnerId;return s!==void 0?s:(tb({...i,runnerId:o},t,e),o)}function KR(e=Pn(),t=ib){let r=W_(e);if(r.runnerId!==void 0)return r.runnerId;let n=ob(e,t),o=W_(e),i=o.runnerId;return i!==void 0?i:(YR({...o,runnerId:n},e),n)}function QR(e=Pn(),t){return t!==void 0&&qo(t)!==Dt?Cl(Lo(e),`${Il(e)}.${GR(t)}.runner-id`):Cl(Lo(e),`${Il(e)}.runner-id`)}function YR(e,t=Pn()){tb(e,t)}function XR(e,t){Ml(e)&&F_(e,jl),Y_(e,`${JSON.stringify(t,null,2)}
159
159
  `,{encoding:"utf8",mode:jl}),F_(e,jl)}function Al(e){if(!Ml(e))return{version:1,allowedCwds:[]};let t=JSON.parse(Q_(e,"utf8"));if(!rb(t))throw new Error(`invalid Linzumi config: ${e}`);return t}function eb(e,t){let r=Al(e),n=t===void 0?Dt:qo(t),o=n===Dt?r:r[n]??tO();if(!nb(o))throw new Error(`invalid Linzumi config section ${n}: ${e}`);let i=sb(o.allowedCwds);return{version:1,...o.machineId===void 0?{}:{machineId:o.machineId},...o.runnerId===void 0?{}:{runnerId:o.runnerId},allowedCwds:i}}function tb(e,t,r){let n=r===void 0?Dt:qo(r),o=eO(e),i=n===Dt?{...Al(t),...o,version:1}:{...Al(t),version:1,[n]:o};K_(Lo(t),{recursive:!0}),XR(t,i)}function rb(e){return typeof e=="object"&&e!==null&&e.version===1&&nb(e)}function nb(e){return typeof e=="object"&&e!==null&&Array.isArray(e.allowedCwds)&&rO(e.machineId)&&Nl(e.runnerId)&&e.allowedCwds.every(t=>typeof t=="string"&&t.trim()!=="")}function eO(e){if(!rb(e))throw new Error("invalid Linzumi config");let t=sb(e.allowedCwds);return{...e.machineId===void 0?{}:{machineId:e.machineId},...e.runnerId===void 0?{}:{runnerId:e.runnerId},allowedCwds:t}}function tO(){return{allowedCwds:[]}}function rO(e){return e===void 0||typeof e=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}function Nl(e){return e===void 0||typeof e=="string"&&/^[a-zA-Z0-9_.-]+$/.test(e)}function ob(e,t,r){let n=QR(e,r);if(Ml(n))return H_(n);let o=t();if(!Nl(o))throw new Error(`invalid generated Linzumi runner id: ${o}`);K_(Lo(n),{recursive:!0});let i=Cl(Lo(n),`.${Il(n)}.${process.pid}.${G_()}.tmp`);Y_(i,`${o}
160
- `,{encoding:"utf8",flag:"wx"});try{return WR(i,n),o}catch(s){if(nO(s,"EEXIST"))return H_(n);throw s}finally{BR(i)}}function H_(e){let t=Q_(e,"utf8").trim();if(!Nl(t))throw new Error(`invalid Linzumi runner id seed: ${e}`);return t}function ib(){return`runner-${G_()}`}function sb(e){return[...new Set(e.map(t=>t.trim()).filter(t=>t!==""))]}function nO(e,t){return typeof e=="object"&&e!==null&&"code"in e&&e.code===t}import{execFileSync as oO}from"node:child_process";import{createHash as iO}from"node:crypto";import{readFileSync as sO}from"node:fs";var aO="linzumi-machine-fingerprint:v1:";function cO(e,t){return oO(e,[...t],{encoding:"utf8",timeout:5e3,maxBuffer:1024*1024})}function dO(e){return sO(e,"utf8")}function uO(e={}){let t=e.platform??process.platform,r=e.execFile??cO,n=e.readFile??dO;try{if(t==="darwin"){let s=r("ioreg",["-rd1","-c","IOPlatformExpertDevice"]).match(/"IOPlatformUUID"\s*=\s*"([0-9A-Fa-f-]{36})"/)?.[1];return s===void 0?void 0:s.toLowerCase()}if(t==="linux"){for(let o of["/etc/machine-id","/var/lib/dbus/machine-id"])try{let i=n(o).trim().toLowerCase();if(/^[0-9a-f]{32}$/.test(i))return i}catch{}return}return}catch{return}}function ab(e={}){let t=uO(e);return t===void 0?void 0:`mfp-${iO("sha256").update(`${aO}${t}`).digest("hex").slice(0,32)}`}async function cb(e,t={readCachedToken:Ds,validateToken:No,acquireAndCacheToken:fO}){if(e.explicitToken!==void 0)return e.explicitToken;let r=t.readCachedToken(e.kandanUrl,e.authFilePath);if(r!==void 0){let o=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r.accessToken,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes});if(o==="usable")return r.accessToken;e.reportRejectedCachedToken?.(o)}let n=await t.acquireAndCacheToken(e);return e.workspaceSlug!==void 0&&await pO(e,t,n),n}async function pO(e,t,r){let n;try{n=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes})}catch{return}if(n==="not_found")throw new Error(mO(e))}function mO(e){let t=new URL(We(e.kandanUrl)).host;return`Workspace '${e.workspaceSlug}' was not found on ${t}. Sign in to the web app to create it, then re-run connect.`}async function fO(e){let t=e.authMode??{kind:"browser",callbackHost:e.callbackHost},r=t.kind==="device"?await L_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,identity:{runnerId:X_(e.kandanUrl),machineFingerprint:ab(),hostname:lO()}}):await x_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,callbackHost:t.callbackHost??e.callbackHost});return N_({kandanUrl:e.kandanUrl,accessToken:r.accessToken,expiresInSeconds:r.expiresInSeconds,authFilePath:e.authFilePath}),r.accessToken}import{realpath as Ul,writeFile as LN,mkdir as qN,open as hO}from"node:fs/promises";import{constants as ub}from"node:fs";import{homedir as gO}from"node:os";import{basename as yO,extname as _O,isAbsolute as lb,join as FN,relative as pb,resolve as ql}from"node:path";function Be(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Dl(e){let t=e.split(".")[1];if(t===void 0||t.length===0)return!1;try{let r=JSON.parse(Buffer.from(t,"base64url").toString("utf8"));if(!Be(r)||r.document_surfaces!==!0)return!1;let n=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,o=typeof r.linzumi_agent_session=="string"&&n.test(r.linzumi_agent_session),i=typeof r.coding_job_id=="string"&&n.test(r.coding_job_id)&&typeof r.coding_job_thread_id=="string"&&n.test(r.coding_job_thread_id);return o||i}catch{return!1}}function we(e){return e!==void 0&&Be(e)?e:void 0}function qr(e){return Array.isArray(e)?e:void 0}function ye(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}function db(e){return typeof e=="number"&&Number.isInteger(e)?e:void 0}var bO=new Set([".csv",".diff",".gif",".htm",".html",".jpeg",".jpg",".json",".jsonl",".log",".md",".mp4",".patch",".pdf",".png",".svg",".txt",".webm",".webp",".xml",".zip"]);async function Zl(e,t){let r=await Ul(e),n=await kO(r),o=await vO(r,t),i=await wO(n,o);return{fileName:yO(o),contentType:$O(o,i.classification),sizeBytes:i.bytes.byteLength,bytes:i.bytes}}async function vO(e,t){if(t==="")throw new Error("Kandan attachment path must not be empty");let r=lb(t)?ql(t):ql(e,t);return await Ul(r)}var Ll=8192;async function wO(e,t){let r=e.find(s=>xO(s.path,t));if(r===void 0){let s=e.map(a=>a.label).join(", ");throw new Error(`Kandan attachment path must resolve inside an allowed upload root (${s}): ${t}`)}if(pb(r.path,t).split(/[\\/]+/).find(s=>s.startsWith("."))!==void 0)throw new Error(`Kandan attachment upload path must not include hidden path segments: ${t}`);let i=await hO(t,ub.O_RDONLY|ub.O_NONBLOCK);try{if(!(await i.stat()).isFile())throw new Error(`Kandan attachment path is not a file: ${t}`);let a=_O(t).toLowerCase();if(bO.has(a))return{classification:"known-type",bytes:await i.readFile()};let c=Buffer.alloc(Ll),{bytesRead:d}=await i.read(c,0,Ll,0);if(c.subarray(0,d).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);let u=await i.readFile();if(u.subarray(0,Ll).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);return{classification:"text-content",bytes:u}}finally{await i.close()}}async function kO(e){let t=[{path:e,label:"runner cwd"}],r=process.env.HOME?.trim(),n=ql(r===void 0||r===""?gO():r,"Downloads");try{let o=await Ul(n);t.some(i=>i.path===o)||t.push({path:o,label:"~/Downloads"})}catch{return t}return t}function xO(e,t){let r=pb(e,t);return r===""||!r.startsWith("..")&&!lb(r)}function SO(e){let t=e.toLowerCase();return t.endsWith(".png")?"image/png":t.endsWith(".jpg")||t.endsWith(".jpeg")?"image/jpeg":t.endsWith(".gif")?"image/gif":t.endsWith(".webp")?"image/webp":t.endsWith(".csv")?"text/csv":t.endsWith(".json")?"application/json":t.endsWith(".md")||t.endsWith(".txt")||t.endsWith(".log")?"text/plain":"application/octet-stream"}function $O(e,t){if(e.toLowerCase().endsWith(".py"))return"text/x-python";let n=SO(e);return t==="text-content"&&n==="application/octet-stream"?"text/plain":n}function Jl(e){let t=e.fetchImpl??fetch,r=We(e.kandanUrl),n=e.authMode==="personal-agent-delegation"?"/api/v2/personal-agent-mcp":"/api/v2/local-runner-mcp",o=e.operatingMode??"text",i=async(s,a,c,d={})=>{let u=new URL(a,r),p={...c,operating_mode:o},m={method:s,headers:{authorization:`Bearer ${e.accessToken}`,...e.topicWakeTurnCapability===void 0?{}:{"x-linzumi-agent-turn":e.topicWakeTurnCapability}},...d.signal===void 0?{}:{signal:d.signal}};if(s==="GET")for(let[w,k]of Object.entries(p))k!=null&&u.searchParams.set(w,String(k));else m.headers={...m.headers,"content-type":"application/json"},m.body=JSON.stringify(p);let f=await t(u,m),h=await f.json(),g=Be(h)?h:void 0;if(g===void 0)throw new Error(`Linzumi MCP API returned non-object JSON from ${a}`);if(f.ok&&g.ok===!0)return g;let y=typeof g.error=="string"?g.error:`HTTP ${f.status}`,v=typeof g.detail=="string"?g.detail:void 0;throw new Error(`Linzumi MCP API ${a} failed: ${y}${v===void 0?"":` detail=${v}`}`)};return{validateAuth:()=>i("GET",`${n}/validate`,{}),issueOnboardingDiscoveryToken:s=>i("POST",`${n}/onboarding-discovery-token`,s),getMessage:s=>i("GET",`${n}/message`,s),getThread:s=>i("GET",`${n}/thread`,s),getThreadTranscript:s=>i("GET",`${n}/thread-transcript`,s),getChannel:s=>i("GET",`${n}/channel`,s),searchWorkspace:s=>i("GET",`${n}/search`,s),askWorkspace:s=>i("POST",`${n}/ask`,s),aboutMe:s=>i("GET",`${n}/about-me`,s),webSearch:s=>i("GET",`${n}/web-search`,s),fetchUrl:s=>i("GET",`${n}/fetch-url`,s),listUiTargets:s=>i("GET",`${n}/ui-targets`,s),openUi:s=>i("POST",`${n}/open-ui`,s),getCodingJobMetadata:s=>i("GET",`${n}/coding-job-metadata`,s),listProjects:s=>i("GET",`${n}/projects`,s),getProjectTasks:s=>i("GET",`${n}/project-tasks`,s),createProjectTask:s=>i("POST",`${n}/project-tasks/create`,s),updateProjectTask:s=>i("POST",`${n}/project-tasks/update`,s),deleteProjectTask:s=>i("POST",`${n}/project-tasks/delete`,s),addProjectTaskDependency:s=>i("POST",`${n}/project-tasks/add-dependency`,s),removeProjectTaskDependency:s=>i("POST",`${n}/project-tasks/remove-dependency`,s),getCallTranscript:s=>i("GET",`${n}/call-transcript`,s),renameCodingJob:s=>i("POST",`${n}/coding-job-title`,s),upsertCodingJobPlan:(s,a)=>i("POST",`${n}/coding-job-plan`,s,a),replaceCodingJobPlanSteps:s=>i("POST",`${n}/coding-job-plan/steps`,s),updateCodingJobPlanStep:s=>i("POST",`${n}/coding-job-plan/step`,s),linkCodingJobPullRequest:s=>i("POST",`${n}/coding-job-primary-pr`,s),listVaultSecrets:s=>i("GET",`${n}/vault-secrets`,s),noteProjectDirectory:s=>i("POST",`${n}/discovered-project`,s),noteAgentConversation:s=>i("POST",`${n}/discovered-conversation`,s),noteOnboardingDiscoveryStatus:s=>i("POST",`${n}/discovery-status`,s),sendChannelMessage:s=>i("POST",`${n}/channel-message`,s),editMessage:s=>i("POST",`${n}/message/edit`,s),agentReply:s=>i("POST",`${n}/agent-reply`,s),scheduleWake:s=>i("POST",`${n}/scheduled-wakes`,s),cancelWake:s=>i("POST",`${n}/scheduled-wakes/cancel`,s),declineDocumentAction:s=>i("POST",`${n}/agent/decline-document-action`,s),completeTopicWakeNoAction:s=>i("POST",`${n}/agent/complete-topic-wake-no-action`,s),recordTopicWakeToolAttempt:()=>i("POST",`${n}/agent/topic-wake-tool-attempt`,{}),agentTurnProgress:s=>i("POST",`${n}/agent-turn-progress`,s),agentDocumentTool:s=>i("POST",`${n}/agent/document-tool`,s),agentTopicTool:s=>i("POST",`${n}/agent/topic-tool`,s),agentListCodingJobs:s=>i("GET",`${n}/agent/coding-jobs`,s),agentStartCodingJob:s=>i("POST",`${n}/agent/start-coding-job`,s),agentSpawnChildJob:s=>i("POST",`${n}/agent/spawn-child-job`,s),agentArchiveChildJob:s=>i("POST",`${n}/agent/archive-child-job`,s),agentUnarchiveChildJob:s=>i("POST",`${n}/agent/unarchive-child-job`,s),agentInterruptCodingJob:s=>i("POST",`${n}/agent/interrupt-coding-job`,s),agentSendCodingJobMessage:s=>i("POST",`${n}/agent/send-coding-job-message`,s),agentDiscoverCodingJobs:s=>i("GET",`${n}/agent/discover-coding-jobs`,s),agentReadCodingJobThread:s=>i("GET",`${n}/agent/coding-job-thread`,s),agentResolveJobApproval:s=>i("POST",`${n}/agent/resolve-job-approval`,s),agentArchiveCodingJob:s=>i("POST",`${n}/agent/archive-coding-job`,s),agentUnarchiveCodingJob:s=>i("POST",`${n}/agent/unarchive-coding-job`,s),agentSetThreadStatus:s=>i("POST",`${n}/agent/set-thread-status`,s),agentCreateChannel:s=>i("POST",`${n}/agent/create-channel`,s),agentRenameChannel:s=>i("POST",`${n}/agent/rename-channel`,s),agentArchiveChannel:s=>i("POST",`${n}/agent/archive-channel`,s),agentUnarchiveChannel:s=>i("POST",`${n}/agent/unarchive-channel`,s),agentAddReaction:s=>i("POST",`${n}/agent/add-reaction`,s),agentRemoveReaction:s=>i("POST",`${n}/agent/remove-reaction`,s),agentPinMessage:s=>i("POST",`${n}/agent/pin-message`,s),agentUnpinMessage:s=>i("POST",`${n}/agent/unpin-message`,s),prepareMessageUploads:s=>i("POST",`${n}/message-uploads/prepare`,s),attachMessageFiles:s=>i("POST",`${n}/message-files/attach`,s),prepareCustomEmoji:s=>i("POST",`${n}/custom-emoji/prepare`,s),renameCustomEmoji:s=>i("POST",`${n}/custom-emoji/rename`,s),sendThreadReply:s=>i("POST",`${n}/thread-reply`,s),sendDm:s=>i("POST",`${n}/dm`,s),dmOwner:s=>i("POST",`${n}/dm-owner`,s),getVaultValues:s=>i("POST",`${n}/vault-values`,s)}}import{closeSync as Ls,fstatSync as zO,mkdirSync as Uo,openSync as mb,readdirSync as TO,readFileSync as fb,readSync as PO,renameSync as RO,rmSync as qs,statSync as hb,writeFileSync as gb}from"node:fs";import{spawn as OO,execFile as eD}from"node:child_process";import{createHash as EO}from"node:crypto";import{createRequire as jO}from"node:module";import{createConnection as IO}from"node:net";import{homedir as CO}from"node:os";import{dirname as Us,join as Zr}from"node:path";var AO=(()=>{let e;return()=>{if(e!==void 0)return e;let{lockSync:t}=jO(import.meta.url)("proper-lockfile");return e=t,t}})(),Bl=()=>{},yb=1,MO=1;function NO(){let e=process.env.LINZUMI_DEV_SERVICES_DIR?.trim();return e!==void 0&&e!==""?e:Zr(CO(),".linzumi","dev-services")}function _b(e){let t=e.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^[-.]+|[-.]+$/g,"").slice(0,80),r=EO("sha256").update(e).digest("hex").slice(0,8),n=t===""?"runner":t;return Zr(NO(),`${n}.${r}`)}function Zs(e){let t=e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t)&&!t.includes("..")?t:void 0}function Rn(e,t){return Zr(e,"services",`${t}.json`)}function Hl(e,t){return Zr(e,"exits",`${t}.json`)}function bb(e,t){return Zr(e,"logs",`${t}.log`)}function Ur(e){return typeof e=="string"&&e!==""?e:void 0}function Lt(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function DO(e){return Array.isArray(e)?e.filter(t=>typeof t=="number"&&Number.isInteger(t)&&t>0&&t<=65535):[]}function LO(e){if(!Be(e)||e.version!==yb)return;let t=Ur(e.name),r=t===void 0?void 0:Zs(t),n=Ur(e.command),o=Ur(e.cwd),i=e.desiredState==="running"||e.desiredState==="stopped"?e.desiredState:void 0,s=Lt(e.updatedAtMs),a=Ur(e.logPath);if(r===void 0||r!==t||n===void 0||o===void 0||i===void 0||s===void 0||a===void 0)return;let c=e.failure,d;if(c!=null){let u=Be(c)?Ur(c.reason):void 0,p=Be(c)?Lt(c.atMs):void 0,m=[...u===void 0?["reason"]:[],...p===void 0?["atMs"]:[]];if(m.length===0&&u!==void 0&&p!==void 0)d={reason:u,atMs:p};else{let f=`dev-service "${r}" has a malformed persisted failure record: invalid ${m.join(", ")}`;console.warn(`[dev_services.failure_record_malformed] name=${r} invalid_fields=${m.join(",")}`),d={reason:f,atMs:s}}}return{watchdogVersion:Lt(e.watchdogVersion),name:r,command:n,cwd:o,ports:DO(e.ports),restartOnBranchChange:e.restartOnBranchChange===!0,desiredState:i,pid:Lt(e.pid),ownerPid:Lt(e.ownerPid),startedAtMs:Lt(e.startedAtMs),updatedAtMs:s,lastBranch:Ur(e.lastBranch),logPath:a,automaticRestartAttempts:Lt(e.automaticRestartAttempts)??0,automaticRestartWindowStartedAtMs:Lt(e.automaticRestartWindowStartedAtMs),automaticRestartCause:Ur(e.automaticRestartCause),failure:d}}function qO(e){return{version:yb,watchdogVersion:e.watchdogVersion??null,name:e.name,command:e.command,cwd:e.cwd,ports:[...e.ports],restartOnBranchChange:e.restartOnBranchChange,desiredState:e.desiredState,pid:e.pid??null,ownerPid:e.ownerPid??null,startedAtMs:e.startedAtMs??null,updatedAtMs:e.updatedAtMs,lastBranch:e.lastBranch??null,logPath:e.logPath,automaticRestartAttempts:e.automaticRestartAttempts,automaticRestartWindowStartedAtMs:e.automaticRestartWindowStartedAtMs??null,automaticRestartCause:e.automaticRestartCause??null,failure:e.failure===void 0?null:{reason:e.failure.reason,atMs:e.failure.atMs}}}function UO(e){return`${JSON.stringify(qO(e))}
160
+ `,{encoding:"utf8",flag:"wx"});try{return WR(i,n),o}catch(s){if(nO(s,"EEXIST"))return H_(n);throw s}finally{BR(i)}}function H_(e){let t=Q_(e,"utf8").trim();if(!Nl(t))throw new Error(`invalid Linzumi runner id seed: ${e}`);return t}function ib(){return`runner-${G_()}`}function sb(e){return[...new Set(e.map(t=>t.trim()).filter(t=>t!==""))]}function nO(e,t){return typeof e=="object"&&e!==null&&"code"in e&&e.code===t}import{execFileSync as oO}from"node:child_process";import{createHash as iO}from"node:crypto";import{readFileSync as sO}from"node:fs";var aO="linzumi-machine-fingerprint:v1:";function cO(e,t){return oO(e,[...t],{encoding:"utf8",timeout:5e3,maxBuffer:1024*1024})}function dO(e){return sO(e,"utf8")}function uO(e={}){let t=e.platform??process.platform,r=e.execFile??cO,n=e.readFile??dO;try{if(t==="darwin"){let s=r("ioreg",["-rd1","-c","IOPlatformExpertDevice"]).match(/"IOPlatformUUID"\s*=\s*"([0-9A-Fa-f-]{36})"/)?.[1];return s===void 0?void 0:s.toLowerCase()}if(t==="linux"){for(let o of["/etc/machine-id","/var/lib/dbus/machine-id"])try{let i=n(o).trim().toLowerCase();if(/^[0-9a-f]{32}$/.test(i))return i}catch{}return}return}catch{return}}function ab(e={}){let t=uO(e);return t===void 0?void 0:`mfp-${iO("sha256").update(`${aO}${t}`).digest("hex").slice(0,32)}`}async function cb(e,t={readCachedToken:Ds,validateToken:No,acquireAndCacheToken:fO}){if(e.explicitToken!==void 0)return e.explicitToken;let r=t.readCachedToken(e.kandanUrl,e.authFilePath);if(r!==void 0){let o=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r.accessToken,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes});if(o==="usable")return r.accessToken;e.reportRejectedCachedToken?.(o)}let n=await t.acquireAndCacheToken(e);return e.workspaceSlug!==void 0&&await pO(e,t,n),n}async function pO(e,t,r){let n;try{n=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes})}catch{return}if(n==="not_found")throw new Error(mO(e))}function mO(e){let t=new URL(We(e.kandanUrl)).host;return`Workspace '${e.workspaceSlug}' was not found on ${t}. Sign in to the web app to create it, then re-run connect.`}async function fO(e){let t=e.authMode??{kind:"browser",callbackHost:e.callbackHost},r=t.kind==="device"?await L_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,identity:{runnerId:X_(e.kandanUrl),machineFingerprint:ab(),hostname:lO()}}):await x_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,callbackHost:t.callbackHost??e.callbackHost});return N_({kandanUrl:e.kandanUrl,accessToken:r.accessToken,expiresInSeconds:r.expiresInSeconds,authFilePath:e.authFilePath}),r.accessToken}import{realpath as Ul,writeFile as LN,mkdir as qN,open as hO,rm as UN}from"node:fs/promises";import{constants as ub}from"node:fs";import{homedir as gO}from"node:os";import{basename as yO,extname as _O,isAbsolute as lb,join as VN,relative as pb,resolve as ql}from"node:path";function Be(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Dl(e){let t=e.split(".")[1];if(t===void 0||t.length===0)return!1;try{let r=JSON.parse(Buffer.from(t,"base64url").toString("utf8"));if(!Be(r)||r.document_surfaces!==!0)return!1;let n=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,o=typeof r.linzumi_agent_session=="string"&&n.test(r.linzumi_agent_session),i=typeof r.coding_job_id=="string"&&n.test(r.coding_job_id)&&typeof r.coding_job_thread_id=="string"&&n.test(r.coding_job_thread_id);return o||i}catch{return!1}}function we(e){return e!==void 0&&Be(e)?e:void 0}function qr(e){return Array.isArray(e)?e:void 0}function ye(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}function db(e){return typeof e=="number"&&Number.isInteger(e)?e:void 0}var bO=new Set([".csv",".diff",".gif",".htm",".html",".jpeg",".jpg",".json",".jsonl",".log",".md",".mp4",".patch",".pdf",".png",".svg",".txt",".webm",".webp",".xml",".zip"]);async function Zl(e,t){let r=await Ul(e),n=await kO(r),o=await vO(r,t),i=await wO(n,o);return{fileName:yO(o),contentType:$O(o,i.classification),sizeBytes:i.bytes.byteLength,bytes:i.bytes}}async function vO(e,t){if(t==="")throw new Error("Kandan attachment path must not be empty");let r=lb(t)?ql(t):ql(e,t);return await Ul(r)}var Ll=8192;async function wO(e,t){let r=e.find(s=>xO(s.path,t));if(r===void 0){let s=e.map(a=>a.label).join(", ");throw new Error(`Kandan attachment path must resolve inside an allowed upload root (${s}): ${t}`)}if(pb(r.path,t).split(/[\\/]+/).find(s=>s.startsWith("."))!==void 0)throw new Error(`Kandan attachment upload path must not include hidden path segments: ${t}`);let i=await hO(t,ub.O_RDONLY|ub.O_NONBLOCK);try{if(!(await i.stat()).isFile())throw new Error(`Kandan attachment path is not a file: ${t}`);let a=_O(t).toLowerCase();if(bO.has(a))return{classification:"known-type",bytes:await i.readFile()};let c=Buffer.alloc(Ll),{bytesRead:d}=await i.read(c,0,Ll,0);if(c.subarray(0,d).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);let u=await i.readFile();if(u.subarray(0,Ll).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);return{classification:"text-content",bytes:u}}finally{await i.close()}}async function kO(e){let t=[{path:e,label:"runner cwd"}],r=process.env.HOME?.trim(),n=ql(r===void 0||r===""?gO():r,"Downloads");try{let o=await Ul(n);t.some(i=>i.path===o)||t.push({path:o,label:"~/Downloads"})}catch{return t}return t}function xO(e,t){let r=pb(e,t);return r===""||!r.startsWith("..")&&!lb(r)}function SO(e){let t=e.toLowerCase();return t.endsWith(".png")?"image/png":t.endsWith(".jpg")||t.endsWith(".jpeg")?"image/jpeg":t.endsWith(".gif")?"image/gif":t.endsWith(".webp")?"image/webp":t.endsWith(".csv")?"text/csv":t.endsWith(".json")?"application/json":t.endsWith(".md")||t.endsWith(".txt")||t.endsWith(".log")?"text/plain":"application/octet-stream"}function $O(e,t){if(e.toLowerCase().endsWith(".py"))return"text/x-python";let n=SO(e);return t==="text-content"&&n==="application/octet-stream"?"text/plain":n}function Jl(e){let t=e.fetchImpl??fetch,r=We(e.kandanUrl),n=e.authMode==="personal-agent-delegation"?"/api/v2/personal-agent-mcp":"/api/v2/local-runner-mcp",o=e.operatingMode??"text",i=async(s,a,c,d={})=>{let u=new URL(a,r),p={...c,operating_mode:o},m={method:s,headers:{authorization:`Bearer ${e.accessToken}`,...e.topicWakeTurnCapability===void 0?{}:{"x-linzumi-agent-turn":e.topicWakeTurnCapability}},...d.signal===void 0?{}:{signal:d.signal}};if(s==="GET")for(let[w,k]of Object.entries(p))k!=null&&u.searchParams.set(w,String(k));else m.headers={...m.headers,"content-type":"application/json"},m.body=JSON.stringify(p);let f=await t(u,m),h=await f.json(),g=Be(h)?h:void 0;if(g===void 0)throw new Error(`Linzumi MCP API returned non-object JSON from ${a}`);if(f.ok&&g.ok===!0)return g;let y=typeof g.error=="string"?g.error:`HTTP ${f.status}`,v=typeof g.detail=="string"?g.detail:void 0;throw new Error(`Linzumi MCP API ${a} failed: ${y}${v===void 0?"":` detail=${v}`}`)};return{validateAuth:()=>i("GET",`${n}/validate`,{}),issueOnboardingDiscoveryToken:s=>i("POST",`${n}/onboarding-discovery-token`,s),getMessage:s=>i("GET",`${n}/message`,s),getThread:s=>i("GET",`${n}/thread`,s),getThreadTranscript:s=>i("GET",`${n}/thread-transcript`,s),getChannel:s=>i("GET",`${n}/channel`,s),searchWorkspace:s=>i("GET",`${n}/search`,s),askWorkspace:s=>i("POST",`${n}/ask`,s),aboutMe:s=>i("GET",`${n}/about-me`,s),webSearch:s=>i("GET",`${n}/web-search`,s),fetchUrl:s=>i("GET",`${n}/fetch-url`,s),listUiTargets:s=>i("GET",`${n}/ui-targets`,s),openUi:s=>i("POST",`${n}/open-ui`,s),getCodingJobMetadata:s=>i("GET",`${n}/coding-job-metadata`,s),listProjects:s=>i("GET",`${n}/projects`,s),getProjectTasks:s=>i("GET",`${n}/project-tasks`,s),createProjectTask:s=>i("POST",`${n}/project-tasks/create`,s),updateProjectTask:s=>i("POST",`${n}/project-tasks/update`,s),deleteProjectTask:s=>i("POST",`${n}/project-tasks/delete`,s),addProjectTaskDependency:s=>i("POST",`${n}/project-tasks/add-dependency`,s),removeProjectTaskDependency:s=>i("POST",`${n}/project-tasks/remove-dependency`,s),getCallTranscript:s=>i("GET",`${n}/call-transcript`,s),renameCodingJob:s=>i("POST",`${n}/coding-job-title`,s),upsertCodingJobPlan:(s,a)=>i("POST",`${n}/coding-job-plan`,s,a),replaceCodingJobPlanSteps:s=>i("POST",`${n}/coding-job-plan/steps`,s),updateCodingJobPlanStep:s=>i("POST",`${n}/coding-job-plan/step`,s),linkCodingJobPullRequest:s=>i("POST",`${n}/coding-job-primary-pr`,s),listVaultSecrets:s=>i("GET",`${n}/vault-secrets`,s),noteProjectDirectory:s=>i("POST",`${n}/discovered-project`,s),noteAgentConversation:s=>i("POST",`${n}/discovered-conversation`,s),noteOnboardingDiscoveryStatus:s=>i("POST",`${n}/discovery-status`,s),sendChannelMessage:s=>i("POST",`${n}/channel-message`,s),editMessage:s=>i("POST",`${n}/message/edit`,s),agentReply:s=>i("POST",`${n}/agent-reply`,s),scheduleWake:s=>i("POST",`${n}/scheduled-wakes`,s),cancelWake:s=>i("POST",`${n}/scheduled-wakes/cancel`,s),declineDocumentAction:s=>i("POST",`${n}/agent/decline-document-action`,s),completeTopicWakeNoAction:s=>i("POST",`${n}/agent/complete-topic-wake-no-action`,s),recordTopicWakeToolAttempt:()=>i("POST",`${n}/agent/topic-wake-tool-attempt`,{}),agentTurnProgress:s=>i("POST",`${n}/agent-turn-progress`,s),agentDocumentTool:s=>i("POST",`${n}/agent/document-tool`,s),agentTopicTool:s=>i("POST",`${n}/agent/topic-tool`,s),agentListCodingJobs:s=>i("GET",`${n}/agent/coding-jobs`,s),agentStartCodingJob:s=>i("POST",`${n}/agent/start-coding-job`,s),agentSpawnChildJob:s=>i("POST",`${n}/agent/spawn-child-job`,s),agentArchiveChildJob:s=>i("POST",`${n}/agent/archive-child-job`,s),agentUnarchiveChildJob:s=>i("POST",`${n}/agent/unarchive-child-job`,s),agentInterruptCodingJob:s=>i("POST",`${n}/agent/interrupt-coding-job`,s),agentSendCodingJobMessage:s=>i("POST",`${n}/agent/send-coding-job-message`,s),agentDiscoverCodingJobs:s=>i("GET",`${n}/agent/discover-coding-jobs`,s),agentReadCodingJobThread:s=>i("GET",`${n}/agent/coding-job-thread`,s),agentResolveJobApproval:s=>i("POST",`${n}/agent/resolve-job-approval`,s),agentArchiveCodingJob:s=>i("POST",`${n}/agent/archive-coding-job`,s),agentUnarchiveCodingJob:s=>i("POST",`${n}/agent/unarchive-coding-job`,s),agentSetThreadStatus:s=>i("POST",`${n}/agent/set-thread-status`,s),agentCreateChannel:s=>i("POST",`${n}/agent/create-channel`,s),agentRenameChannel:s=>i("POST",`${n}/agent/rename-channel`,s),agentArchiveChannel:s=>i("POST",`${n}/agent/archive-channel`,s),agentUnarchiveChannel:s=>i("POST",`${n}/agent/unarchive-channel`,s),agentAddReaction:s=>i("POST",`${n}/agent/add-reaction`,s),agentRemoveReaction:s=>i("POST",`${n}/agent/remove-reaction`,s),agentPinMessage:s=>i("POST",`${n}/agent/pin-message`,s),agentUnpinMessage:s=>i("POST",`${n}/agent/unpin-message`,s),prepareMessageUploads:s=>i("POST",`${n}/message-uploads/prepare`,s),attachMessageFiles:s=>i("POST",`${n}/message-files/attach`,s),prepareCustomEmoji:s=>i("POST",`${n}/custom-emoji/prepare`,s),renameCustomEmoji:s=>i("POST",`${n}/custom-emoji/rename`,s),sendThreadReply:s=>i("POST",`${n}/thread-reply`,s),sendDm:s=>i("POST",`${n}/dm`,s),dmOwner:s=>i("POST",`${n}/dm-owner`,s),getVaultValues:s=>i("POST",`${n}/vault-values`,s)}}import{closeSync as Ls,fstatSync as zO,mkdirSync as Uo,openSync as mb,readdirSync as TO,readFileSync as fb,readSync as PO,renameSync as RO,rmSync as qs,statSync as hb,writeFileSync as gb}from"node:fs";import{spawn as OO,execFile as tD}from"node:child_process";import{createHash as EO}from"node:crypto";import{createRequire as jO}from"node:module";import{createConnection as IO}from"node:net";import{homedir as CO}from"node:os";import{dirname as Us,join as Zr}from"node:path";var AO=(()=>{let e;return()=>{if(e!==void 0)return e;let{lockSync:t}=jO(import.meta.url)("proper-lockfile");return e=t,t}})(),Bl=()=>{},yb=1,MO=1;function NO(){let e=process.env.LINZUMI_DEV_SERVICES_DIR?.trim();return e!==void 0&&e!==""?e:Zr(CO(),".linzumi","dev-services")}function _b(e){let t=e.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^[-.]+|[-.]+$/g,"").slice(0,80),r=EO("sha256").update(e).digest("hex").slice(0,8),n=t===""?"runner":t;return Zr(NO(),`${n}.${r}`)}function Zs(e){let t=e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t)&&!t.includes("..")?t:void 0}function Rn(e,t){return Zr(e,"services",`${t}.json`)}function Hl(e,t){return Zr(e,"exits",`${t}.json`)}function bb(e,t){return Zr(e,"logs",`${t}.log`)}function Ur(e){return typeof e=="string"&&e!==""?e:void 0}function Lt(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function DO(e){return Array.isArray(e)?e.filter(t=>typeof t=="number"&&Number.isInteger(t)&&t>0&&t<=65535):[]}function LO(e){if(!Be(e)||e.version!==yb)return;let t=Ur(e.name),r=t===void 0?void 0:Zs(t),n=Ur(e.command),o=Ur(e.cwd),i=e.desiredState==="running"||e.desiredState==="stopped"?e.desiredState:void 0,s=Lt(e.updatedAtMs),a=Ur(e.logPath);if(r===void 0||r!==t||n===void 0||o===void 0||i===void 0||s===void 0||a===void 0)return;let c=e.failure,d;if(c!=null){let u=Be(c)?Ur(c.reason):void 0,p=Be(c)?Lt(c.atMs):void 0,m=[...u===void 0?["reason"]:[],...p===void 0?["atMs"]:[]];if(m.length===0&&u!==void 0&&p!==void 0)d={reason:u,atMs:p};else{let f=`dev-service "${r}" has a malformed persisted failure record: invalid ${m.join(", ")}`;console.warn(`[dev_services.failure_record_malformed] name=${r} invalid_fields=${m.join(",")}`),d={reason:f,atMs:s}}}return{watchdogVersion:Lt(e.watchdogVersion),name:r,command:n,cwd:o,ports:DO(e.ports),restartOnBranchChange:e.restartOnBranchChange===!0,desiredState:i,pid:Lt(e.pid),ownerPid:Lt(e.ownerPid),startedAtMs:Lt(e.startedAtMs),updatedAtMs:s,lastBranch:Ur(e.lastBranch),logPath:a,automaticRestartAttempts:Lt(e.automaticRestartAttempts)??0,automaticRestartWindowStartedAtMs:Lt(e.automaticRestartWindowStartedAtMs),automaticRestartCause:Ur(e.automaticRestartCause),failure:d}}function qO(e){return{version:yb,watchdogVersion:e.watchdogVersion??null,name:e.name,command:e.command,cwd:e.cwd,ports:[...e.ports],restartOnBranchChange:e.restartOnBranchChange,desiredState:e.desiredState,pid:e.pid??null,ownerPid:e.ownerPid??null,startedAtMs:e.startedAtMs??null,updatedAtMs:e.updatedAtMs,lastBranch:e.lastBranch??null,logPath:e.logPath,automaticRestartAttempts:e.automaticRestartAttempts,automaticRestartWindowStartedAtMs:e.automaticRestartWindowStartedAtMs??null,automaticRestartCause:e.automaticRestartCause??null,failure:e.failure===void 0?null:{reason:e.failure.reason,atMs:e.failure.atMs}}}function UO(e){return`${JSON.stringify(qO(e))}
161
161
  `}var Fl=5e3;function ZO(e,t,r){let n=`${Rn(e,t)}.lock`;try{Uo(Us(n),{recursive:!0});let o=(()=>{try{let s=hb(n),a=Date.now()-s.mtimeMs;if(s.isFile()&&a>=Fl){qs(n),r("dev_services.legacy_record_lock_recovered",{name:t,path:n,age_ms:a});return}return s.isDirectory()&&a>=Fl?a:void 0}catch(s){if((s!==null&&typeof s=="object"&&"code"in s?s.code:void 0)!=="ENOENT")throw s;return}})(),i=AO()(Rn(e,t),{lockfilePath:n,realpath:!1,retries:0,stale:Fl,update:1e3,onCompromised:s=>{throw r("dev_services.record_lock_compromised",{name:t,path:n,message:s.message}),s}});return o!==void 0&&r("dev_services.record_lease_recovered",{name:t,path:n,age_ms:o}),{ok:!0,release:i,path:n}}catch(o){let i=o instanceof Error?o.message:String(o);return r("dev_services.record_lock_failed",{name:t,path:n,message:i}),{ok:!1,error:`could not lock dev-service state at ${n}: ${i}`}}}function JO(e,t,r){try{return e.release(),{ok:!0}}catch(n){let o=n instanceof Error?n.message:String(n);return r("dev_services.record_unlock_failed",{name:t,path:e.path,message:o}),{ok:!1,error:`could not unlock dev-service state at ${e.path}: ${o}`}}}function FO(e,t,r){let n=Rn(e,t.name);try{Uo(Us(n),{recursive:!0});let o=`${n}.tmp`;return gb(o,UO(t),"utf8"),RO(o,n),{ok:!0}}catch(o){let i=o instanceof Error?o.message:String(o);return r("dev_services.record_write_failed",{path:n,message:i}),{ok:!1,error:`could not persist dev-service state at ${n}: ${i}`}}}function Vl(e,t,r,n){let o=ZO(e,t.name,r);if(!o.ok)return{ok:!1,error:o.error,persisted:!1};n?.(o.path);let i=FO(e,t,r),s=JO(o,t.name,r);return i.ok?s.ok?{ok:!0}:{ok:!1,error:s.error,persisted:!0}:{ok:!1,error:i.error,persisted:!1}}function Gl(e,t){let r=Zs(t);if(r===void 0)return;let n;try{n=fb(Rn(e,r),"utf8")}catch{return}try{return LO(JSON.parse(n))}catch{return}}function VO(e){let t;try{t=TO(Zr(e,"services"))}catch{return[]}let r=[];for(let n of t){if(!n.endsWith(".json"))continue;let o=Gl(e,n.slice(0,-5));o!==void 0&&r.push(o)}return r.sort((n,o)=>n.name.localeCompare(o.name))}function vb(e,t){let r;try{r=fb(Hl(e,t),"utf8")}catch{return}try{let n=JSON.parse(r);if(!Be(n))return;let o=Lt(n.atMs);return o===void 0?void 0:{code:typeof n.code=="number"?n.code:null,signal:typeof n.signal=="string"?n.signal:null,atMs:o}}catch{return}}function WO(e){return JSON.stringify(e)}function BO(){return`
162
162
  const { spawn } = require('node:child_process');
163
163
  const fs = require('node:fs');
@@ -247,12 +247,12 @@ const watchdog = setInterval(() => {
247
247
  `.trim()}function HO(e,t){return{command:e,args:["-e",BO(),WO(t)]}}function wb(e,t=r=>process.kill(r,0)){if(e===void 0||e<=1)return!1;try{return t(-e),!0}catch(r){return r?.code==="EPERM"}}function Kl(e,t){if(t.pid===void 0||t.pid<=1)return!1;let r=vb(e,t.name);return r!==void 0&&t.startedAtMs!==void 0&&r.atMs>=t.startedAtMs?!1:wb(t.pid)}async function Ql(e,t=750,r="127.0.0.1"){return await new Promise(n=>{let o=IO({port:e,host:r}),i=s=>{o.removeAllListeners(),o.destroy(),n(s)};o.setTimeout(t),o.once("connect",()=>i(!0)),o.once("timeout",()=>i(!1)),o.once("error",()=>i(!1))})}async function GO(e,t){let r=Kl(e,t),n=[];for(let i of t.ports)n.push({port:i,listening:r?await Ql(i):!1});let o=t.desiredState==="stopped"?"stopped":!r&&t.failure!==void 0?"failed":r?n.every(i=>i.listening)?"running":"unhealthy":"exited";return{record:t,liveness:o,portProbes:n,lastExit:vb(e,t.name),failure:t.failure}}async function Yl(e){let t=[];for(let r of VO(e))t.push(await GO(e,r));return t}function KO(e=process.env){let t=e.SHELL?.trim();return t!==void 0&&t!==""?t:"/bin/sh"}async function kb(e){let t=e.log??Bl,r=Zs(e.definition.name);if(r===void 0)return{ok:!1,error:"invalid service name: use 1-64 lowercase letters, digits, ., _ or -"};let n=e.definition.command.trim();if(n==="")return{ok:!1,error:"service command must not be empty"};try{if(!hb(e.definition.cwd).isDirectory())return{ok:!1,error:`cwd is not a directory: ${e.definition.cwd}`}}catch{return{ok:!1,error:`cwd does not exist: ${e.definition.cwd}`}}let o=Gl(e.scopeDir,r);o!==void 0&&Kl(e.scopeDir,o)&&await Wl(o.pid,t,r);let i=e.nowMs??Date.now(),s=bb(e.scopeDir,r),a=Hl(e.scopeDir,r),c;try{Uo(Us(s),{recursive:!0}),Uo(Zr(e.scopeDir,"services"),{recursive:!0}),Uo(Us(a),{recursive:!0}),c=mb(s,"a")}catch(y){return{ok:!1,error:`cannot open service log: ${y instanceof Error?y.message:String(y)}`}}try{qs(a,{force:!0})}catch{}let d=e.shellPath??KO(),u=HO(e.nodeExecPath??process.execPath,{command:d,args:["-lc",n],cwd:e.definition.cwd,pollIntervalMs:e.watchdogPollIntervalMs??500,recordPath:Rn(e.scopeDir,r),exitStatusPath:a});try{gb(c,`
248
248
  --- linzumi dev-service "${r}" starting at ${new Date(i).toISOString()} (owner pid ${e.ownerPid}) ---
249
249
  $ ${n}
250
- `)}catch{t("dev_services.start_banner_write_failed",{name:r,log_path:s})}let p={watchdogVersion:MO,name:r,command:n,cwd:e.definition.cwd,ports:[...new Set(e.definition.ports)].sort((y,v)=>y-v),restartOnBranchChange:e.definition.restartOnBranchChange===!0,desiredState:"stopped",pid:void 0,ownerPid:e.ownerPid,startedAtMs:i,updatedAtMs:i,lastBranch:void 0,logPath:s,automaticRestartAttempts:e.automaticRestartState?.attempts??0,automaticRestartWindowStartedAtMs:e.automaticRestartState?.windowStartedAtMs,automaticRestartCause:e.automaticRestartState?.cause,failure:{reason:`dev service "${r}" start did not complete`,atMs:i}},m=Vl(e.scopeDir,p,t);if(!m.ok){try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}return m}try{await e.beforeWatchdogSpawnForTest?.()}catch(y){try{Ls(c)}catch(v){t("dev_services.log_close_failed",{name:r,message:v instanceof Error?v.message:String(v)})}return{ok:!1,error:y instanceof Error?y.message:`start interrupted before watchdog spawn: ${String(y)}`}}let f;try{let y=OO(u.command,[...u.args],{cwd:e.definition.cwd,detached:!0,stdio:["ignore",c,c],env:{...process.env,ELECTRON_RUN_AS_NODE:"1"}});y.unref(),f=y.pid}catch(y){return{ok:!1,error:`spawn failed: ${y instanceof Error?y.message:String(y)}`}}finally{try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}}if(f===void 0)return{ok:!1,error:"spawn failed: no pid"};let h={...p,desiredState:"running",pid:f,failure:void 0},g=Vl(e.scopeDir,h,t,e.afterFinalRecordLockedForTest);return g.ok?(t("dev_services.started",{name:r,pid:f,owner_pid:e.ownerPid,cwd:e.definition.cwd,ports:[...h.ports]}),{ok:!0,record:h}):(g.persisted||await Wl(f,t,r,0),g)}async function Wl(e,t,r,n=3e3){if(e===void 0||e<=1)return;try{process.kill(-e,"SIGTERM")}catch{return}let o=Date.now()+n;for(;Date.now()<o;){if(!wb(e))return;await new Promise(i=>setTimeout(i,100))}try{process.kill(-e,"SIGKILL"),t("dev_services.stop_escalated",{name:r,pgid:e})}catch{}}async function Xl(e){let t=e.log??Bl,r=Gl(e.scopeDir,e.name);if(r===void 0)return{ok:!1,error:`unknown service: ${e.name}`};Kl(e.scopeDir,r)&&await Wl(r.pid,t,r.name);let n={...r,desiredState:"stopped",pid:void 0,ownerPid:void 0,updatedAtMs:e.nowMs??Date.now(),failure:void 0},o=Vl(e.scopeDir,n,t);return o.ok?(t("dev_services.stopped",{name:r.name}),{ok:!0,record:n}):o}async function xb(e){let t=e.log??Bl,r=await Xl(e);if(!r.ok)return r;try{qs(Rn(e.scopeDir,r.record.name),{force:!0}),qs(Hl(e.scopeDir,r.record.name),{force:!0})}catch(n){let o=n instanceof Error?n.message:String(n);return t("dev_services.remove_failed",{name:r.record.name,message:o}),{ok:!1,error:`could not remove dev service "${r.record.name}": ${o}`}}return r}function Sb(e,t,r=16384){let n=Zs(t);if(n===void 0)return;let o=bb(e,n),i;try{i=mb(o,"r");let s=zO(i).size,a=Math.min(s,r),c=Buffer.alloc(a);return PO(i,c,0,a,s-a),c.toString("utf8")}catch{return}finally{if(i!==void 0)try{Ls(i)}catch{}}}var aD=10*6e4;function $b(e){return{name:"linzumi",command:e.command??"linzumi",args:[...e.argsPrefix??[],"mcp","server","--api-url",e.kandanUrl,...e.authFilePath===void 0?[]:["--auth-file",e.authFilePath],...e.delegationAuthFilePath===void 0?[]:["--delegation-auth-file",e.delegationAuthFilePath],...e.ownerUsername===void 0?[]:["--owner-username",e.ownerUsername],...e.cwd===void 0?[]:["--cwd",e.cwd],...e.threadId===void 0?[]:["--thread-id",e.threadId],"--mode",e.operatingMode??"text",...e.toolScope===void 0||e.toolScope==="all"?[]:["--tool-scope",e.toolScope],...e.agentSession===!0?["--agent-session"]:[],...e.askUserQuestionTool===!0?["--ask-user-question-tool"]:[],...e.multiAgentJobs===!0?["--multi-agent-jobs"]:[]],env:{...e.accessToken===void 0?{}:{LINZUMI_MCP_ACCESS_TOKEN:e.accessToken},...e.devServices===void 0?{}:{LINZUMI_DEV_SERVICES_SCOPE:e.devServices.scope,LINZUMI_DEV_SERVICES_OWNER_PID:String(e.devServices.ownerPid)},ELECTRON_RUN_AS_NODE:"1"}}}function zb(e){return`${JSON.stringify({mcpServers:{[e.name]:{command:e.command,args:e.args,env:e.env}}},null,2)}
250
+ `)}catch{t("dev_services.start_banner_write_failed",{name:r,log_path:s})}let p={watchdogVersion:MO,name:r,command:n,cwd:e.definition.cwd,ports:[...new Set(e.definition.ports)].sort((y,v)=>y-v),restartOnBranchChange:e.definition.restartOnBranchChange===!0,desiredState:"stopped",pid:void 0,ownerPid:e.ownerPid,startedAtMs:i,updatedAtMs:i,lastBranch:void 0,logPath:s,automaticRestartAttempts:e.automaticRestartState?.attempts??0,automaticRestartWindowStartedAtMs:e.automaticRestartState?.windowStartedAtMs,automaticRestartCause:e.automaticRestartState?.cause,failure:{reason:`dev service "${r}" start did not complete`,atMs:i}},m=Vl(e.scopeDir,p,t);if(!m.ok){try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}return m}try{await e.beforeWatchdogSpawnForTest?.()}catch(y){try{Ls(c)}catch(v){t("dev_services.log_close_failed",{name:r,message:v instanceof Error?v.message:String(v)})}return{ok:!1,error:y instanceof Error?y.message:`start interrupted before watchdog spawn: ${String(y)}`}}let f;try{let y=OO(u.command,[...u.args],{cwd:e.definition.cwd,detached:!0,stdio:["ignore",c,c],env:{...process.env,ELECTRON_RUN_AS_NODE:"1"}});y.unref(),f=y.pid}catch(y){return{ok:!1,error:`spawn failed: ${y instanceof Error?y.message:String(y)}`}}finally{try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}}if(f===void 0)return{ok:!1,error:"spawn failed: no pid"};let h={...p,desiredState:"running",pid:f,failure:void 0},g=Vl(e.scopeDir,h,t,e.afterFinalRecordLockedForTest);return g.ok?(t("dev_services.started",{name:r,pid:f,owner_pid:e.ownerPid,cwd:e.definition.cwd,ports:[...h.ports]}),{ok:!0,record:h}):(g.persisted||await Wl(f,t,r,0),g)}async function Wl(e,t,r,n=3e3){if(e===void 0||e<=1)return;try{process.kill(-e,"SIGTERM")}catch{return}let o=Date.now()+n;for(;Date.now()<o;){if(!wb(e))return;await new Promise(i=>setTimeout(i,100))}try{process.kill(-e,"SIGKILL"),t("dev_services.stop_escalated",{name:r,pgid:e})}catch{}}async function Xl(e){let t=e.log??Bl,r=Gl(e.scopeDir,e.name);if(r===void 0)return{ok:!1,error:`unknown service: ${e.name}`};Kl(e.scopeDir,r)&&await Wl(r.pid,t,r.name);let n={...r,desiredState:"stopped",pid:void 0,ownerPid:void 0,updatedAtMs:e.nowMs??Date.now(),failure:void 0},o=Vl(e.scopeDir,n,t);return o.ok?(t("dev_services.stopped",{name:r.name}),{ok:!0,record:n}):o}async function xb(e){let t=e.log??Bl,r=await Xl(e);if(!r.ok)return r;try{qs(Rn(e.scopeDir,r.record.name),{force:!0}),qs(Hl(e.scopeDir,r.record.name),{force:!0})}catch(n){let o=n instanceof Error?n.message:String(n);return t("dev_services.remove_failed",{name:r.record.name,message:o}),{ok:!1,error:`could not remove dev service "${r.record.name}": ${o}`}}return r}function Sb(e,t,r=16384){let n=Zs(t);if(n===void 0)return;let o=bb(e,n),i;try{i=mb(o,"r");let s=zO(i).size,a=Math.min(s,r),c=Buffer.alloc(a);return PO(i,c,0,a,s-a),c.toString("utf8")}catch{return}finally{if(i!==void 0)try{Ls(i)}catch{}}}var cD=10*6e4;function $b(e){return{name:"linzumi",command:e.command??"linzumi",args:[...e.argsPrefix??[],"mcp","server","--api-url",e.kandanUrl,...e.authFilePath===void 0?[]:["--auth-file",e.authFilePath],...e.delegationAuthFilePath===void 0?[]:["--delegation-auth-file",e.delegationAuthFilePath],...e.ownerUsername===void 0?[]:["--owner-username",e.ownerUsername],...e.cwd===void 0?[]:["--cwd",e.cwd],...e.threadId===void 0?[]:["--thread-id",e.threadId],"--mode",e.operatingMode??"text",...e.toolScope===void 0||e.toolScope==="all"?[]:["--tool-scope",e.toolScope],...e.agentSession===!0?["--agent-session"]:[],...e.askUserQuestionTool===!0?["--ask-user-question-tool"]:[],...e.multiAgentJobs===!0?["--multi-agent-jobs"]:[]],env:{...e.accessToken===void 0?{}:{LINZUMI_MCP_ACCESS_TOKEN:e.accessToken},...e.devServices===void 0?{}:{LINZUMI_DEV_SERVICES_SCOPE:e.devServices.scope,LINZUMI_DEV_SERVICES_OWNER_PID:String(e.devServices.ownerPid)},ELECTRON_RUN_AS_NODE:"1"}}}function zb(e){return`${JSON.stringify({mcpServers:{[e.name]:{command:e.command,args:e.args,env:e.env}}},null,2)}
251
251
  `}function Tb(e){return`[mcp_servers.${e.name}]
252
252
  command = ${JSON.stringify(e.command)}
253
253
  args = ${QO(e.args)}
254
254
  ${Object.keys(e.env).length===0?"":`env = ${YO(e.env)}
255
- `}`}function QO(e){return`[${e.map(t=>JSON.stringify(t)).join(", ")}]`}function YO(e){return`{ ${Object.entries(e).map(([r,n])=>`${r} = ${JSON.stringify(n)}`).join(", ")} }`}var Pb="linzumi_ask_user_question",Zo=4,Jo=12,Fo=2,Vo=4,Rb="Other";var Ob=2147483647,XO=2147483,uD=XO*1e3-5*6e4,Eb="linzumi_ask_user_question",jb="plan_mode_native_interview_tool",Ib="no_active_turn";function eE(e){let t=e.trim().toLowerCase();switch(t){case"other":case"something else":case"something else...":return!0;default:return t.includes("other")||t.includes("something else")}}function Cb(e){let t=we(e),r=qr(t?.questions);if(r===void 0)return{type:"invalid",message:"questions: expected an array"};if(r.length===0)return{type:"invalid",message:"questions: min 1, got 0"};if(r.length>Zo)return{type:"invalid",message:`questions: max ${Zo}, got ${r.length}`};let n=[],o=new Set;for(let[i,s]of r.entries()){let a=we(s);if(a===void 0)return{type:"invalid",message:`questions[${i}]: expected an object`};let c=ye(a.question);if(c===void 0)return{type:"invalid",message:`questions[${i}].question: must be a non-empty string`};if(o.has(c))return{type:"invalid",message:`questions: duplicate question text ${JSON.stringify(c)}`};let d=ye(a.header);if(d===void 0)return{type:"invalid",message:`questions[${i}].header: must be a non-empty string`};if(d.length>Jo)return{type:"invalid",message:`questions[${i}].header: max ${Jo} chars, got ${d.length}`};if(a.multiSelect!==void 0&&typeof a.multiSelect!="boolean")return{type:"invalid",message:`questions[${i}].multiSelect: must be a boolean`};let u=qr(a.options);if(u===void 0)return{type:"invalid",message:`questions[${i}].options: expected an array`};if(u.length<Fo)return{type:"invalid",message:`questions[${i}].options: min ${Fo}, got ${u.length}`};if(u.length>Vo)return{type:"invalid",message:`questions[${i}].options: max ${Vo}, got ${u.length}`};let p=[],m=new Set;for(let[f,h]of u.entries()){let g=we(h),y=ye(g?.label);if(g===void 0||y===void 0)return{type:"invalid",message:`questions[${i}].options[${f}].label: must be a non-empty string`};if(g.description!==void 0&&typeof g.description!="string")return{type:"invalid",message:`questions[${i}].options[${f}].description: must be a string`};if(eE(y))return{type:"invalid",message:`questions[${i}].options[${f}].label: ${JSON.stringify(y)} is reserved for the built-in Other option`};if(m.has(y))return{type:"invalid",message:`questions[${i}].options: duplicate label ${JSON.stringify(y)}`};m.add(y),p.push({label:y,description:typeof g.description=="string"?g.description:""})}o.add(c),n.push({question:c,header:d,options:p,multiSelect:a.multiSelect===!0})}return{type:"ok",request:{questions:n}}}function Ab(e){return{message:"Linzumi interview: the user is being asked in the Linzumi thread.",requestedSchema:{type:"object",properties:Object.fromEntries(e.questions.map(t=>[t.question,{type:"string",description:t.header}])),required:e.questions.map(t=>t.question)},_meta:{[Eb]:{version:1,questions:e.questions.map(t=>({question:t.question,header:t.header,multiSelect:t.multiSelect,options:t.options.map(r=>({label:r.label,description:r.description}))}))}}}}function Mb(e,t){let r=we(t??void 0);if(r===void 0)return{type:"invalid",message:"the runner accepted the interview but returned no answers; it may predate linzumi_ask_user_question support"};let n={};for(let o of e.questions){let i=r[o.question];if(typeof i!="string")return{type:"invalid",message:`the runner returned no answer for question ${JSON.stringify(o.question)}`};try{n[o.question]=JSON.parse(i)}catch{return{type:"invalid",message:`the runner returned an undecodable answer for question ${JSON.stringify(o.question)}`}}}return{type:"ok",answers:n}}function Nb(e){return ye(we(we(e)?.[Eb])?.reason)}var Db=`<linzumi_markdown_media_guidance>
255
+ `}`}function QO(e){return`[${e.map(t=>JSON.stringify(t)).join(", ")}]`}function YO(e){return`{ ${Object.entries(e).map(([r,n])=>`${r} = ${JSON.stringify(n)}`).join(", ")} }`}var Pb="linzumi_ask_user_question",Zo=4,Jo=12,Fo=2,Vo=4,Rb="Other";var Ob=2147483647,XO=2147483,lD=XO*1e3-5*6e4,Eb="linzumi_ask_user_question",jb="plan_mode_native_interview_tool",Ib="no_active_turn";function eE(e){let t=e.trim().toLowerCase();switch(t){case"other":case"something else":case"something else...":return!0;default:return t.includes("other")||t.includes("something else")}}function Cb(e){let t=we(e),r=qr(t?.questions);if(r===void 0)return{type:"invalid",message:"questions: expected an array"};if(r.length===0)return{type:"invalid",message:"questions: min 1, got 0"};if(r.length>Zo)return{type:"invalid",message:`questions: max ${Zo}, got ${r.length}`};let n=[],o=new Set;for(let[i,s]of r.entries()){let a=we(s);if(a===void 0)return{type:"invalid",message:`questions[${i}]: expected an object`};let c=ye(a.question);if(c===void 0)return{type:"invalid",message:`questions[${i}].question: must be a non-empty string`};if(o.has(c))return{type:"invalid",message:`questions: duplicate question text ${JSON.stringify(c)}`};let d=ye(a.header);if(d===void 0)return{type:"invalid",message:`questions[${i}].header: must be a non-empty string`};if(d.length>Jo)return{type:"invalid",message:`questions[${i}].header: max ${Jo} chars, got ${d.length}`};if(a.multiSelect!==void 0&&typeof a.multiSelect!="boolean")return{type:"invalid",message:`questions[${i}].multiSelect: must be a boolean`};let u=qr(a.options);if(u===void 0)return{type:"invalid",message:`questions[${i}].options: expected an array`};if(u.length<Fo)return{type:"invalid",message:`questions[${i}].options: min ${Fo}, got ${u.length}`};if(u.length>Vo)return{type:"invalid",message:`questions[${i}].options: max ${Vo}, got ${u.length}`};let p=[],m=new Set;for(let[f,h]of u.entries()){let g=we(h),y=ye(g?.label);if(g===void 0||y===void 0)return{type:"invalid",message:`questions[${i}].options[${f}].label: must be a non-empty string`};if(g.description!==void 0&&typeof g.description!="string")return{type:"invalid",message:`questions[${i}].options[${f}].description: must be a string`};if(eE(y))return{type:"invalid",message:`questions[${i}].options[${f}].label: ${JSON.stringify(y)} is reserved for the built-in Other option`};if(m.has(y))return{type:"invalid",message:`questions[${i}].options: duplicate label ${JSON.stringify(y)}`};m.add(y),p.push({label:y,description:typeof g.description=="string"?g.description:""})}o.add(c),n.push({question:c,header:d,options:p,multiSelect:a.multiSelect===!0})}return{type:"ok",request:{questions:n}}}function Ab(e){return{message:"Linzumi interview: the user is being asked in the Linzumi thread.",requestedSchema:{type:"object",properties:Object.fromEntries(e.questions.map(t=>[t.question,{type:"string",description:t.header}])),required:e.questions.map(t=>t.question)},_meta:{[Eb]:{version:1,questions:e.questions.map(t=>({question:t.question,header:t.header,multiSelect:t.multiSelect,options:t.options.map(r=>({label:r.label,description:r.description}))}))}}}}function Mb(e,t){let r=we(t??void 0);if(r===void 0)return{type:"invalid",message:"the runner accepted the interview but returned no answers; it may predate linzumi_ask_user_question support"};let n={};for(let o of e.questions){let i=r[o.question];if(typeof i!="string")return{type:"invalid",message:`the runner returned no answer for question ${JSON.stringify(o.question)}`};try{n[o.question]=JSON.parse(i)}catch{return{type:"invalid",message:`the runner returned an undecodable answer for question ${JSON.stringify(o.question)}`}}}return{type:"ok",answers:n}}function Nb(e){return ye(we(we(e)?.[Eb])?.reason)}var Db=`<linzumi_markdown_media_guidance>
256
256
  Some Linzumi users have opted into rich Markdown media rendering. When you are
257
257
  writing a visible Linzumi message, channel message, or thread reply, you may use
258
258
  these Markdown-compatible media directives:
@@ -157,7 +157,7 @@ Open: ${e.verificationUri}
157
157
  `;case"start_failed":return`Could not mint a device authorization code (${e.reason}); retrying in ${Math.round(e.retryInMs/1e3)}s.
158
158
  `}}function D_(e){let t=Math.floor(e/6e4),r=Math.floor(t/60),n=t%60;return r>0?`${r}h ${n}m`:`${n}m`}async function L_(e){let t=e.deps??{},r=t.startDeviceAuthorization??$_,n=t.pollDeviceCodeForToken??z_,o=t.now??Date.now,i=t.sleep??(g=>new Promise(y=>setTimeout(y,g))),s=e.writeStderr??(g=>process.stderr.write(g)),a=e.isInteractive??process.stderr.isTTY===!0,c=t.report??(g=>s(JR(g))),d=t.log??(()=>{}),u=We(e.kandanUrl),p=o(),m=0,f,h=0;for(;;){let g;try{g=await r({httpBaseUrl:u,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,identity:e.identity})}catch(w){h+=1;let k=Math.min(UR,qR*2**(h-1)),O=w instanceof Error?w.message:String(w);c({kind:"start_failed",reason:O,retryInMs:k}),d("device_wait.start_failed",{reason:O,retryInMs:k,attempt:h}),await i(k);continue}h=0,m+=1;let y=ZR({cycle:m,nowMs:o(),lastLoudPromptAtMs:f,isInteractive:a});y==="prompt"||y==="summary"?(f=o(),c({kind:y,cycle:m,userCode:g.userCode,verificationUri:g.verificationUri,waitedMs:o()-p})):y==="refresh_line"&&c({kind:"refresh_line",cycle:m,userCode:g.userCode,verificationUri:g.verificationUri,waitedMs:o()-p}),d("device_wait.code_issued",{cycle:m,verificationUri:g.verificationUri});let v;for(;v=await n({httpBaseUrl:u,deviceCode:g.deviceCode,expiresInSeconds:g.expiresInSeconds}),v.kind==="transient";)c({kind:"transient",reason:v.reason,waitedMs:o()-p}),d("device_wait.transient_poll_failure",{cycle:m,reason:v.reason,httpStatus:v.httpStatus??null}),await i(LR);switch(v.kind){case"token":return d("device_wait.authorized",{cycle:m,waitedMs:o()-p}),v.token;case"denied":throw new Error("local runner device authorization was denied - a signed-in user rejected this computer");case"code_expired":case"consumed":d("device_wait.code_retired",{cycle:m,outcome:v.kind});continue;case"rejected":c({kind:"transient",reason:T_(v.reason,v.httpStatus),waitedMs:o()-p}),d("device_wait.code_rejected",{cycle:m,reason:v.reason??null,httpStatus:v.httpStatus});continue}}}import{randomUUID as G_}from"node:crypto";import{chmodSync as F_,existsSync as Ml,linkSync as WR,mkdirSync as K_,readFileSync as Q_,realpathSync as yN,unlinkSync as BR,writeFileSync as Y_}from"node:fs";import{homedir as HR}from"node:os";import{basename as Il,dirname as Lo,join as Cl,resolve as V_}from"node:path";var q_="wss://serve.linzumi.com";import{homedir as FR}from"node:os";import{isAbsolute as lN,relative as pN,resolve as VR}from"node:path";import{delimiter as tN,isAbsolute as rN,join as U_,parse as nN,resolve as oN,sep as iN}from"node:path";var sN=[".volta",".nvm",".npm",".asdf",".fnm",".bun",U_(".cargo","bin"),U_(".local","bin")];function J_(e){return e==="~"?Z_():e.startsWith("~/")?VR(Z_(),e.slice(2)):e}function Z_(){let e=process.env.HOME;return e===void 0||e.trim()===""?FR():e}var jl=384,Dt="prod";function Pn(e=process.env){let t=e.LINZUMI_CONFIG_FILE;return t!==void 0&&t.trim()!==""?V_(J_(t)):V_(HR(),".linzumi","config.json")}function qo(e){let t=We(e),r=We(q_);return t===r?Dt:t}function GR(e){let t=qo(e);return t===Dt?Dt:Buffer.from(t).toString("base64url")}function W_(e=Pn()){return eb(e)}function B_(e,t=Pn()){return eb(t,e)}function X_(e,t=Pn(),r=ib){if(qo(e)===Dt)return KR(t,r);let n=B_(e,t);if(n.runnerId!==void 0)return n.runnerId;let o=ob(t,r,e),i=B_(e,t),s=i.runnerId;return s!==void 0?s:(tb({...i,runnerId:o},t,e),o)}function KR(e=Pn(),t=ib){let r=W_(e);if(r.runnerId!==void 0)return r.runnerId;let n=ob(e,t),o=W_(e),i=o.runnerId;return i!==void 0?i:(YR({...o,runnerId:n},e),n)}function QR(e=Pn(),t){return t!==void 0&&qo(t)!==Dt?Cl(Lo(e),`${Il(e)}.${GR(t)}.runner-id`):Cl(Lo(e),`${Il(e)}.runner-id`)}function YR(e,t=Pn()){tb(e,t)}function XR(e,t){Ml(e)&&F_(e,jl),Y_(e,`${JSON.stringify(t,null,2)}
159
159
  `,{encoding:"utf8",mode:jl}),F_(e,jl)}function Al(e){if(!Ml(e))return{version:1,allowedCwds:[]};let t=JSON.parse(Q_(e,"utf8"));if(!rb(t))throw new Error(`invalid Linzumi config: ${e}`);return t}function eb(e,t){let r=Al(e),n=t===void 0?Dt:qo(t),o=n===Dt?r:r[n]??tO();if(!nb(o))throw new Error(`invalid Linzumi config section ${n}: ${e}`);let i=sb(o.allowedCwds);return{version:1,...o.machineId===void 0?{}:{machineId:o.machineId},...o.runnerId===void 0?{}:{runnerId:o.runnerId},allowedCwds:i}}function tb(e,t,r){let n=r===void 0?Dt:qo(r),o=eO(e),i=n===Dt?{...Al(t),...o,version:1}:{...Al(t),version:1,[n]:o};K_(Lo(t),{recursive:!0}),XR(t,i)}function rb(e){return typeof e=="object"&&e!==null&&e.version===1&&nb(e)}function nb(e){return typeof e=="object"&&e!==null&&Array.isArray(e.allowedCwds)&&rO(e.machineId)&&Nl(e.runnerId)&&e.allowedCwds.every(t=>typeof t=="string"&&t.trim()!=="")}function eO(e){if(!rb(e))throw new Error("invalid Linzumi config");let t=sb(e.allowedCwds);return{...e.machineId===void 0?{}:{machineId:e.machineId},...e.runnerId===void 0?{}:{runnerId:e.runnerId},allowedCwds:t}}function tO(){return{allowedCwds:[]}}function rO(e){return e===void 0||typeof e=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)}function Nl(e){return e===void 0||typeof e=="string"&&/^[a-zA-Z0-9_.-]+$/.test(e)}function ob(e,t,r){let n=QR(e,r);if(Ml(n))return H_(n);let o=t();if(!Nl(o))throw new Error(`invalid generated Linzumi runner id: ${o}`);K_(Lo(n),{recursive:!0});let i=Cl(Lo(n),`.${Il(n)}.${process.pid}.${G_()}.tmp`);Y_(i,`${o}
160
- `,{encoding:"utf8",flag:"wx"});try{return WR(i,n),o}catch(s){if(nO(s,"EEXIST"))return H_(n);throw s}finally{BR(i)}}function H_(e){let t=Q_(e,"utf8").trim();if(!Nl(t))throw new Error(`invalid Linzumi runner id seed: ${e}`);return t}function ib(){return`runner-${G_()}`}function sb(e){return[...new Set(e.map(t=>t.trim()).filter(t=>t!==""))]}function nO(e,t){return typeof e=="object"&&e!==null&&"code"in e&&e.code===t}import{execFileSync as oO}from"node:child_process";import{createHash as iO}from"node:crypto";import{readFileSync as sO}from"node:fs";var aO="linzumi-machine-fingerprint:v1:";function cO(e,t){return oO(e,[...t],{encoding:"utf8",timeout:5e3,maxBuffer:1024*1024})}function dO(e){return sO(e,"utf8")}function uO(e={}){let t=e.platform??process.platform,r=e.execFile??cO,n=e.readFile??dO;try{if(t==="darwin"){let s=r("ioreg",["-rd1","-c","IOPlatformExpertDevice"]).match(/"IOPlatformUUID"\s*=\s*"([0-9A-Fa-f-]{36})"/)?.[1];return s===void 0?void 0:s.toLowerCase()}if(t==="linux"){for(let o of["/etc/machine-id","/var/lib/dbus/machine-id"])try{let i=n(o).trim().toLowerCase();if(/^[0-9a-f]{32}$/.test(i))return i}catch{}return}return}catch{return}}function ab(e={}){let t=uO(e);return t===void 0?void 0:`mfp-${iO("sha256").update(`${aO}${t}`).digest("hex").slice(0,32)}`}async function cb(e,t={readCachedToken:Ds,validateToken:No,acquireAndCacheToken:fO}){if(e.explicitToken!==void 0)return e.explicitToken;let r=t.readCachedToken(e.kandanUrl,e.authFilePath);if(r!==void 0){let o=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r.accessToken,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes});if(o==="usable")return r.accessToken;e.reportRejectedCachedToken?.(o)}let n=await t.acquireAndCacheToken(e);return e.workspaceSlug!==void 0&&await pO(e,t,n),n}async function pO(e,t,r){let n;try{n=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes})}catch{return}if(n==="not_found")throw new Error(mO(e))}function mO(e){let t=new URL(We(e.kandanUrl)).host;return`Workspace '${e.workspaceSlug}' was not found on ${t}. Sign in to the web app to create it, then re-run connect.`}async function fO(e){let t=e.authMode??{kind:"browser",callbackHost:e.callbackHost},r=t.kind==="device"?await L_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,identity:{runnerId:X_(e.kandanUrl),machineFingerprint:ab(),hostname:lO()}}):await x_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,callbackHost:t.callbackHost??e.callbackHost});return N_({kandanUrl:e.kandanUrl,accessToken:r.accessToken,expiresInSeconds:r.expiresInSeconds,authFilePath:e.authFilePath}),r.accessToken}import{realpath as Ul,writeFile as LN,mkdir as qN,open as hO}from"node:fs/promises";import{constants as ub}from"node:fs";import{homedir as gO}from"node:os";import{basename as yO,extname as _O,isAbsolute as lb,join as FN,relative as pb,resolve as ql}from"node:path";function Be(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Dl(e){let t=e.split(".")[1];if(t===void 0||t.length===0)return!1;try{let r=JSON.parse(Buffer.from(t,"base64url").toString("utf8"));if(!Be(r)||r.document_surfaces!==!0)return!1;let n=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,o=typeof r.linzumi_agent_session=="string"&&n.test(r.linzumi_agent_session),i=typeof r.coding_job_id=="string"&&n.test(r.coding_job_id)&&typeof r.coding_job_thread_id=="string"&&n.test(r.coding_job_thread_id);return o||i}catch{return!1}}function we(e){return e!==void 0&&Be(e)?e:void 0}function qr(e){return Array.isArray(e)?e:void 0}function ye(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}function db(e){return typeof e=="number"&&Number.isInteger(e)?e:void 0}var bO=new Set([".csv",".diff",".gif",".htm",".html",".jpeg",".jpg",".json",".jsonl",".log",".md",".mp4",".patch",".pdf",".png",".svg",".txt",".webm",".webp",".xml",".zip"]);async function Zl(e,t){let r=await Ul(e),n=await kO(r),o=await vO(r,t),i=await wO(n,o);return{fileName:yO(o),contentType:$O(o,i.classification),sizeBytes:i.bytes.byteLength,bytes:i.bytes}}async function vO(e,t){if(t==="")throw new Error("Kandan attachment path must not be empty");let r=lb(t)?ql(t):ql(e,t);return await Ul(r)}var Ll=8192;async function wO(e,t){let r=e.find(s=>xO(s.path,t));if(r===void 0){let s=e.map(a=>a.label).join(", ");throw new Error(`Kandan attachment path must resolve inside an allowed upload root (${s}): ${t}`)}if(pb(r.path,t).split(/[\\/]+/).find(s=>s.startsWith("."))!==void 0)throw new Error(`Kandan attachment upload path must not include hidden path segments: ${t}`);let i=await hO(t,ub.O_RDONLY|ub.O_NONBLOCK);try{if(!(await i.stat()).isFile())throw new Error(`Kandan attachment path is not a file: ${t}`);let a=_O(t).toLowerCase();if(bO.has(a))return{classification:"known-type",bytes:await i.readFile()};let c=Buffer.alloc(Ll),{bytesRead:d}=await i.read(c,0,Ll,0);if(c.subarray(0,d).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);let u=await i.readFile();if(u.subarray(0,Ll).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);return{classification:"text-content",bytes:u}}finally{await i.close()}}async function kO(e){let t=[{path:e,label:"runner cwd"}],r=process.env.HOME?.trim(),n=ql(r===void 0||r===""?gO():r,"Downloads");try{let o=await Ul(n);t.some(i=>i.path===o)||t.push({path:o,label:"~/Downloads"})}catch{return t}return t}function xO(e,t){let r=pb(e,t);return r===""||!r.startsWith("..")&&!lb(r)}function SO(e){let t=e.toLowerCase();return t.endsWith(".png")?"image/png":t.endsWith(".jpg")||t.endsWith(".jpeg")?"image/jpeg":t.endsWith(".gif")?"image/gif":t.endsWith(".webp")?"image/webp":t.endsWith(".csv")?"text/csv":t.endsWith(".json")?"application/json":t.endsWith(".md")||t.endsWith(".txt")||t.endsWith(".log")?"text/plain":"application/octet-stream"}function $O(e,t){if(e.toLowerCase().endsWith(".py"))return"text/x-python";let n=SO(e);return t==="text-content"&&n==="application/octet-stream"?"text/plain":n}function Jl(e){let t=e.fetchImpl??fetch,r=We(e.kandanUrl),n=e.authMode==="personal-agent-delegation"?"/api/v2/personal-agent-mcp":"/api/v2/local-runner-mcp",o=e.operatingMode??"text",i=async(s,a,c,d={})=>{let u=new URL(a,r),p={...c,operating_mode:o},m={method:s,headers:{authorization:`Bearer ${e.accessToken}`,...e.topicWakeTurnCapability===void 0?{}:{"x-linzumi-agent-turn":e.topicWakeTurnCapability}},...d.signal===void 0?{}:{signal:d.signal}};if(s==="GET")for(let[w,k]of Object.entries(p))k!=null&&u.searchParams.set(w,String(k));else m.headers={...m.headers,"content-type":"application/json"},m.body=JSON.stringify(p);let f=await t(u,m),h=await f.json(),g=Be(h)?h:void 0;if(g===void 0)throw new Error(`Linzumi MCP API returned non-object JSON from ${a}`);if(f.ok&&g.ok===!0)return g;let y=typeof g.error=="string"?g.error:`HTTP ${f.status}`,v=typeof g.detail=="string"?g.detail:void 0;throw new Error(`Linzumi MCP API ${a} failed: ${y}${v===void 0?"":` detail=${v}`}`)};return{validateAuth:()=>i("GET",`${n}/validate`,{}),issueOnboardingDiscoveryToken:s=>i("POST",`${n}/onboarding-discovery-token`,s),getMessage:s=>i("GET",`${n}/message`,s),getThread:s=>i("GET",`${n}/thread`,s),getThreadTranscript:s=>i("GET",`${n}/thread-transcript`,s),getChannel:s=>i("GET",`${n}/channel`,s),searchWorkspace:s=>i("GET",`${n}/search`,s),askWorkspace:s=>i("POST",`${n}/ask`,s),aboutMe:s=>i("GET",`${n}/about-me`,s),webSearch:s=>i("GET",`${n}/web-search`,s),fetchUrl:s=>i("GET",`${n}/fetch-url`,s),listUiTargets:s=>i("GET",`${n}/ui-targets`,s),openUi:s=>i("POST",`${n}/open-ui`,s),getCodingJobMetadata:s=>i("GET",`${n}/coding-job-metadata`,s),listProjects:s=>i("GET",`${n}/projects`,s),getProjectTasks:s=>i("GET",`${n}/project-tasks`,s),createProjectTask:s=>i("POST",`${n}/project-tasks/create`,s),updateProjectTask:s=>i("POST",`${n}/project-tasks/update`,s),deleteProjectTask:s=>i("POST",`${n}/project-tasks/delete`,s),addProjectTaskDependency:s=>i("POST",`${n}/project-tasks/add-dependency`,s),removeProjectTaskDependency:s=>i("POST",`${n}/project-tasks/remove-dependency`,s),getCallTranscript:s=>i("GET",`${n}/call-transcript`,s),renameCodingJob:s=>i("POST",`${n}/coding-job-title`,s),upsertCodingJobPlan:(s,a)=>i("POST",`${n}/coding-job-plan`,s,a),replaceCodingJobPlanSteps:s=>i("POST",`${n}/coding-job-plan/steps`,s),updateCodingJobPlanStep:s=>i("POST",`${n}/coding-job-plan/step`,s),linkCodingJobPullRequest:s=>i("POST",`${n}/coding-job-primary-pr`,s),listVaultSecrets:s=>i("GET",`${n}/vault-secrets`,s),noteProjectDirectory:s=>i("POST",`${n}/discovered-project`,s),noteAgentConversation:s=>i("POST",`${n}/discovered-conversation`,s),noteOnboardingDiscoveryStatus:s=>i("POST",`${n}/discovery-status`,s),sendChannelMessage:s=>i("POST",`${n}/channel-message`,s),editMessage:s=>i("POST",`${n}/message/edit`,s),agentReply:s=>i("POST",`${n}/agent-reply`,s),scheduleWake:s=>i("POST",`${n}/scheduled-wakes`,s),cancelWake:s=>i("POST",`${n}/scheduled-wakes/cancel`,s),declineDocumentAction:s=>i("POST",`${n}/agent/decline-document-action`,s),completeTopicWakeNoAction:s=>i("POST",`${n}/agent/complete-topic-wake-no-action`,s),recordTopicWakeToolAttempt:()=>i("POST",`${n}/agent/topic-wake-tool-attempt`,{}),agentTurnProgress:s=>i("POST",`${n}/agent-turn-progress`,s),agentDocumentTool:s=>i("POST",`${n}/agent/document-tool`,s),agentTopicTool:s=>i("POST",`${n}/agent/topic-tool`,s),agentListCodingJobs:s=>i("GET",`${n}/agent/coding-jobs`,s),agentStartCodingJob:s=>i("POST",`${n}/agent/start-coding-job`,s),agentSpawnChildJob:s=>i("POST",`${n}/agent/spawn-child-job`,s),agentArchiveChildJob:s=>i("POST",`${n}/agent/archive-child-job`,s),agentUnarchiveChildJob:s=>i("POST",`${n}/agent/unarchive-child-job`,s),agentInterruptCodingJob:s=>i("POST",`${n}/agent/interrupt-coding-job`,s),agentSendCodingJobMessage:s=>i("POST",`${n}/agent/send-coding-job-message`,s),agentDiscoverCodingJobs:s=>i("GET",`${n}/agent/discover-coding-jobs`,s),agentReadCodingJobThread:s=>i("GET",`${n}/agent/coding-job-thread`,s),agentResolveJobApproval:s=>i("POST",`${n}/agent/resolve-job-approval`,s),agentArchiveCodingJob:s=>i("POST",`${n}/agent/archive-coding-job`,s),agentUnarchiveCodingJob:s=>i("POST",`${n}/agent/unarchive-coding-job`,s),agentSetThreadStatus:s=>i("POST",`${n}/agent/set-thread-status`,s),agentCreateChannel:s=>i("POST",`${n}/agent/create-channel`,s),agentRenameChannel:s=>i("POST",`${n}/agent/rename-channel`,s),agentArchiveChannel:s=>i("POST",`${n}/agent/archive-channel`,s),agentUnarchiveChannel:s=>i("POST",`${n}/agent/unarchive-channel`,s),agentAddReaction:s=>i("POST",`${n}/agent/add-reaction`,s),agentRemoveReaction:s=>i("POST",`${n}/agent/remove-reaction`,s),agentPinMessage:s=>i("POST",`${n}/agent/pin-message`,s),agentUnpinMessage:s=>i("POST",`${n}/agent/unpin-message`,s),prepareMessageUploads:s=>i("POST",`${n}/message-uploads/prepare`,s),attachMessageFiles:s=>i("POST",`${n}/message-files/attach`,s),prepareCustomEmoji:s=>i("POST",`${n}/custom-emoji/prepare`,s),renameCustomEmoji:s=>i("POST",`${n}/custom-emoji/rename`,s),sendThreadReply:s=>i("POST",`${n}/thread-reply`,s),sendDm:s=>i("POST",`${n}/dm`,s),dmOwner:s=>i("POST",`${n}/dm-owner`,s),getVaultValues:s=>i("POST",`${n}/vault-values`,s)}}import{closeSync as Ls,fstatSync as zO,mkdirSync as Uo,openSync as mb,readdirSync as TO,readFileSync as fb,readSync as PO,renameSync as RO,rmSync as qs,statSync as hb,writeFileSync as gb}from"node:fs";import{spawn as OO,execFile as eD}from"node:child_process";import{createHash as EO}from"node:crypto";import{createRequire as jO}from"node:module";import{createConnection as IO}from"node:net";import{homedir as CO}from"node:os";import{dirname as Us,join as Zr}from"node:path";var AO=(()=>{let e;return()=>{if(e!==void 0)return e;let{lockSync:t}=jO(import.meta.url)("proper-lockfile");return e=t,t}})(),Bl=()=>{},yb=1,MO=1;function NO(){let e=process.env.LINZUMI_DEV_SERVICES_DIR?.trim();return e!==void 0&&e!==""?e:Zr(CO(),".linzumi","dev-services")}function _b(e){let t=e.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^[-.]+|[-.]+$/g,"").slice(0,80),r=EO("sha256").update(e).digest("hex").slice(0,8),n=t===""?"runner":t;return Zr(NO(),`${n}.${r}`)}function Zs(e){let t=e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t)&&!t.includes("..")?t:void 0}function Rn(e,t){return Zr(e,"services",`${t}.json`)}function Hl(e,t){return Zr(e,"exits",`${t}.json`)}function bb(e,t){return Zr(e,"logs",`${t}.log`)}function Ur(e){return typeof e=="string"&&e!==""?e:void 0}function Lt(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function DO(e){return Array.isArray(e)?e.filter(t=>typeof t=="number"&&Number.isInteger(t)&&t>0&&t<=65535):[]}function LO(e){if(!Be(e)||e.version!==yb)return;let t=Ur(e.name),r=t===void 0?void 0:Zs(t),n=Ur(e.command),o=Ur(e.cwd),i=e.desiredState==="running"||e.desiredState==="stopped"?e.desiredState:void 0,s=Lt(e.updatedAtMs),a=Ur(e.logPath);if(r===void 0||r!==t||n===void 0||o===void 0||i===void 0||s===void 0||a===void 0)return;let c=e.failure,d;if(c!=null){let u=Be(c)?Ur(c.reason):void 0,p=Be(c)?Lt(c.atMs):void 0,m=[...u===void 0?["reason"]:[],...p===void 0?["atMs"]:[]];if(m.length===0&&u!==void 0&&p!==void 0)d={reason:u,atMs:p};else{let f=`dev-service "${r}" has a malformed persisted failure record: invalid ${m.join(", ")}`;console.warn(`[dev_services.failure_record_malformed] name=${r} invalid_fields=${m.join(",")}`),d={reason:f,atMs:s}}}return{watchdogVersion:Lt(e.watchdogVersion),name:r,command:n,cwd:o,ports:DO(e.ports),restartOnBranchChange:e.restartOnBranchChange===!0,desiredState:i,pid:Lt(e.pid),ownerPid:Lt(e.ownerPid),startedAtMs:Lt(e.startedAtMs),updatedAtMs:s,lastBranch:Ur(e.lastBranch),logPath:a,automaticRestartAttempts:Lt(e.automaticRestartAttempts)??0,automaticRestartWindowStartedAtMs:Lt(e.automaticRestartWindowStartedAtMs),automaticRestartCause:Ur(e.automaticRestartCause),failure:d}}function qO(e){return{version:yb,watchdogVersion:e.watchdogVersion??null,name:e.name,command:e.command,cwd:e.cwd,ports:[...e.ports],restartOnBranchChange:e.restartOnBranchChange,desiredState:e.desiredState,pid:e.pid??null,ownerPid:e.ownerPid??null,startedAtMs:e.startedAtMs??null,updatedAtMs:e.updatedAtMs,lastBranch:e.lastBranch??null,logPath:e.logPath,automaticRestartAttempts:e.automaticRestartAttempts,automaticRestartWindowStartedAtMs:e.automaticRestartWindowStartedAtMs??null,automaticRestartCause:e.automaticRestartCause??null,failure:e.failure===void 0?null:{reason:e.failure.reason,atMs:e.failure.atMs}}}function UO(e){return`${JSON.stringify(qO(e))}
160
+ `,{encoding:"utf8",flag:"wx"});try{return WR(i,n),o}catch(s){if(nO(s,"EEXIST"))return H_(n);throw s}finally{BR(i)}}function H_(e){let t=Q_(e,"utf8").trim();if(!Nl(t))throw new Error(`invalid Linzumi runner id seed: ${e}`);return t}function ib(){return`runner-${G_()}`}function sb(e){return[...new Set(e.map(t=>t.trim()).filter(t=>t!==""))]}function nO(e,t){return typeof e=="object"&&e!==null&&"code"in e&&e.code===t}import{execFileSync as oO}from"node:child_process";import{createHash as iO}from"node:crypto";import{readFileSync as sO}from"node:fs";var aO="linzumi-machine-fingerprint:v1:";function cO(e,t){return oO(e,[...t],{encoding:"utf8",timeout:5e3,maxBuffer:1024*1024})}function dO(e){return sO(e,"utf8")}function uO(e={}){let t=e.platform??process.platform,r=e.execFile??cO,n=e.readFile??dO;try{if(t==="darwin"){let s=r("ioreg",["-rd1","-c","IOPlatformExpertDevice"]).match(/"IOPlatformUUID"\s*=\s*"([0-9A-Fa-f-]{36})"/)?.[1];return s===void 0?void 0:s.toLowerCase()}if(t==="linux"){for(let o of["/etc/machine-id","/var/lib/dbus/machine-id"])try{let i=n(o).trim().toLowerCase();if(/^[0-9a-f]{32}$/.test(i))return i}catch{}return}return}catch{return}}function ab(e={}){let t=uO(e);return t===void 0?void 0:`mfp-${iO("sha256").update(`${aO}${t}`).digest("hex").slice(0,32)}`}async function cb(e,t={readCachedToken:Ds,validateToken:No,acquireAndCacheToken:fO}){if(e.explicitToken!==void 0)return e.explicitToken;let r=t.readCachedToken(e.kandanUrl,e.authFilePath);if(r!==void 0){let o=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r.accessToken,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes});if(o==="usable")return r.accessToken;e.reportRejectedCachedToken?.(o)}let n=await t.acquireAndCacheToken(e);return e.workspaceSlug!==void 0&&await pO(e,t,n),n}async function pO(e,t,r){let n;try{n=await t.validateToken({kandanUrl:e.kandanUrl,accessToken:r,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,requiredScopes:e.requiredScopes})}catch{return}if(n==="not_found")throw new Error(mO(e))}function mO(e){let t=new URL(We(e.kandanUrl)).host;return`Workspace '${e.workspaceSlug}' was not found on ${t}. Sign in to the web app to create it, then re-run connect.`}async function fO(e){let t=e.authMode??{kind:"browser",callbackHost:e.callbackHost},r=t.kind==="device"?await L_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,identity:{runnerId:X_(e.kandanUrl),machineFingerprint:ab(),hostname:lO()}}):await x_({kandanUrl:e.kandanUrl,workspaceSlug:e.workspaceSlug,channelSlug:e.channelSlug,onboarding:e.onboarding,callbackHost:t.callbackHost??e.callbackHost});return N_({kandanUrl:e.kandanUrl,accessToken:r.accessToken,expiresInSeconds:r.expiresInSeconds,authFilePath:e.authFilePath}),r.accessToken}import{realpath as Ul,writeFile as LN,mkdir as qN,open as hO,rm as UN}from"node:fs/promises";import{constants as ub}from"node:fs";import{homedir as gO}from"node:os";import{basename as yO,extname as _O,isAbsolute as lb,join as VN,relative as pb,resolve as ql}from"node:path";function Be(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Dl(e){let t=e.split(".")[1];if(t===void 0||t.length===0)return!1;try{let r=JSON.parse(Buffer.from(t,"base64url").toString("utf8"));if(!Be(r)||r.document_surfaces!==!0)return!1;let n=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,o=typeof r.linzumi_agent_session=="string"&&n.test(r.linzumi_agent_session),i=typeof r.coding_job_id=="string"&&n.test(r.coding_job_id)&&typeof r.coding_job_thread_id=="string"&&n.test(r.coding_job_thread_id);return o||i}catch{return!1}}function we(e){return e!==void 0&&Be(e)?e:void 0}function qr(e){return Array.isArray(e)?e:void 0}function ye(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}function db(e){return typeof e=="number"&&Number.isInteger(e)?e:void 0}var bO=new Set([".csv",".diff",".gif",".htm",".html",".jpeg",".jpg",".json",".jsonl",".log",".md",".mp4",".patch",".pdf",".png",".svg",".txt",".webm",".webp",".xml",".zip"]);async function Zl(e,t){let r=await Ul(e),n=await kO(r),o=await vO(r,t),i=await wO(n,o);return{fileName:yO(o),contentType:$O(o,i.classification),sizeBytes:i.bytes.byteLength,bytes:i.bytes}}async function vO(e,t){if(t==="")throw new Error("Kandan attachment path must not be empty");let r=lb(t)?ql(t):ql(e,t);return await Ul(r)}var Ll=8192;async function wO(e,t){let r=e.find(s=>xO(s.path,t));if(r===void 0){let s=e.map(a=>a.label).join(", ");throw new Error(`Kandan attachment path must resolve inside an allowed upload root (${s}): ${t}`)}if(pb(r.path,t).split(/[\\/]+/).find(s=>s.startsWith("."))!==void 0)throw new Error(`Kandan attachment upload path must not include hidden path segments: ${t}`);let i=await hO(t,ub.O_RDONLY|ub.O_NONBLOCK);try{if(!(await i.stat()).isFile())throw new Error(`Kandan attachment path is not a file: ${t}`);let a=_O(t).toLowerCase();if(bO.has(a))return{classification:"known-type",bytes:await i.readFile()};let c=Buffer.alloc(Ll),{bytesRead:d}=await i.read(c,0,Ll,0);if(c.subarray(0,d).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);let u=await i.readFile();if(u.subarray(0,Ll).includes(0))throw new Error(`Kandan attachment upload requires a known media/document type or text content (binary content is not allowed): ${t}`);return{classification:"text-content",bytes:u}}finally{await i.close()}}async function kO(e){let t=[{path:e,label:"runner cwd"}],r=process.env.HOME?.trim(),n=ql(r===void 0||r===""?gO():r,"Downloads");try{let o=await Ul(n);t.some(i=>i.path===o)||t.push({path:o,label:"~/Downloads"})}catch{return t}return t}function xO(e,t){let r=pb(e,t);return r===""||!r.startsWith("..")&&!lb(r)}function SO(e){let t=e.toLowerCase();return t.endsWith(".png")?"image/png":t.endsWith(".jpg")||t.endsWith(".jpeg")?"image/jpeg":t.endsWith(".gif")?"image/gif":t.endsWith(".webp")?"image/webp":t.endsWith(".csv")?"text/csv":t.endsWith(".json")?"application/json":t.endsWith(".md")||t.endsWith(".txt")||t.endsWith(".log")?"text/plain":"application/octet-stream"}function $O(e,t){if(e.toLowerCase().endsWith(".py"))return"text/x-python";let n=SO(e);return t==="text-content"&&n==="application/octet-stream"?"text/plain":n}function Jl(e){let t=e.fetchImpl??fetch,r=We(e.kandanUrl),n=e.authMode==="personal-agent-delegation"?"/api/v2/personal-agent-mcp":"/api/v2/local-runner-mcp",o=e.operatingMode??"text",i=async(s,a,c,d={})=>{let u=new URL(a,r),p={...c,operating_mode:o},m={method:s,headers:{authorization:`Bearer ${e.accessToken}`,...e.topicWakeTurnCapability===void 0?{}:{"x-linzumi-agent-turn":e.topicWakeTurnCapability}},...d.signal===void 0?{}:{signal:d.signal}};if(s==="GET")for(let[w,k]of Object.entries(p))k!=null&&u.searchParams.set(w,String(k));else m.headers={...m.headers,"content-type":"application/json"},m.body=JSON.stringify(p);let f=await t(u,m),h=await f.json(),g=Be(h)?h:void 0;if(g===void 0)throw new Error(`Linzumi MCP API returned non-object JSON from ${a}`);if(f.ok&&g.ok===!0)return g;let y=typeof g.error=="string"?g.error:`HTTP ${f.status}`,v=typeof g.detail=="string"?g.detail:void 0;throw new Error(`Linzumi MCP API ${a} failed: ${y}${v===void 0?"":` detail=${v}`}`)};return{validateAuth:()=>i("GET",`${n}/validate`,{}),issueOnboardingDiscoveryToken:s=>i("POST",`${n}/onboarding-discovery-token`,s),getMessage:s=>i("GET",`${n}/message`,s),getThread:s=>i("GET",`${n}/thread`,s),getThreadTranscript:s=>i("GET",`${n}/thread-transcript`,s),getChannel:s=>i("GET",`${n}/channel`,s),searchWorkspace:s=>i("GET",`${n}/search`,s),askWorkspace:s=>i("POST",`${n}/ask`,s),aboutMe:s=>i("GET",`${n}/about-me`,s),webSearch:s=>i("GET",`${n}/web-search`,s),fetchUrl:s=>i("GET",`${n}/fetch-url`,s),listUiTargets:s=>i("GET",`${n}/ui-targets`,s),openUi:s=>i("POST",`${n}/open-ui`,s),getCodingJobMetadata:s=>i("GET",`${n}/coding-job-metadata`,s),listProjects:s=>i("GET",`${n}/projects`,s),getProjectTasks:s=>i("GET",`${n}/project-tasks`,s),createProjectTask:s=>i("POST",`${n}/project-tasks/create`,s),updateProjectTask:s=>i("POST",`${n}/project-tasks/update`,s),deleteProjectTask:s=>i("POST",`${n}/project-tasks/delete`,s),addProjectTaskDependency:s=>i("POST",`${n}/project-tasks/add-dependency`,s),removeProjectTaskDependency:s=>i("POST",`${n}/project-tasks/remove-dependency`,s),getCallTranscript:s=>i("GET",`${n}/call-transcript`,s),renameCodingJob:s=>i("POST",`${n}/coding-job-title`,s),upsertCodingJobPlan:(s,a)=>i("POST",`${n}/coding-job-plan`,s,a),replaceCodingJobPlanSteps:s=>i("POST",`${n}/coding-job-plan/steps`,s),updateCodingJobPlanStep:s=>i("POST",`${n}/coding-job-plan/step`,s),linkCodingJobPullRequest:s=>i("POST",`${n}/coding-job-primary-pr`,s),listVaultSecrets:s=>i("GET",`${n}/vault-secrets`,s),noteProjectDirectory:s=>i("POST",`${n}/discovered-project`,s),noteAgentConversation:s=>i("POST",`${n}/discovered-conversation`,s),noteOnboardingDiscoveryStatus:s=>i("POST",`${n}/discovery-status`,s),sendChannelMessage:s=>i("POST",`${n}/channel-message`,s),editMessage:s=>i("POST",`${n}/message/edit`,s),agentReply:s=>i("POST",`${n}/agent-reply`,s),scheduleWake:s=>i("POST",`${n}/scheduled-wakes`,s),cancelWake:s=>i("POST",`${n}/scheduled-wakes/cancel`,s),declineDocumentAction:s=>i("POST",`${n}/agent/decline-document-action`,s),completeTopicWakeNoAction:s=>i("POST",`${n}/agent/complete-topic-wake-no-action`,s),recordTopicWakeToolAttempt:()=>i("POST",`${n}/agent/topic-wake-tool-attempt`,{}),agentTurnProgress:s=>i("POST",`${n}/agent-turn-progress`,s),agentDocumentTool:s=>i("POST",`${n}/agent/document-tool`,s),agentTopicTool:s=>i("POST",`${n}/agent/topic-tool`,s),agentListCodingJobs:s=>i("GET",`${n}/agent/coding-jobs`,s),agentStartCodingJob:s=>i("POST",`${n}/agent/start-coding-job`,s),agentSpawnChildJob:s=>i("POST",`${n}/agent/spawn-child-job`,s),agentArchiveChildJob:s=>i("POST",`${n}/agent/archive-child-job`,s),agentUnarchiveChildJob:s=>i("POST",`${n}/agent/unarchive-child-job`,s),agentInterruptCodingJob:s=>i("POST",`${n}/agent/interrupt-coding-job`,s),agentSendCodingJobMessage:s=>i("POST",`${n}/agent/send-coding-job-message`,s),agentDiscoverCodingJobs:s=>i("GET",`${n}/agent/discover-coding-jobs`,s),agentReadCodingJobThread:s=>i("GET",`${n}/agent/coding-job-thread`,s),agentResolveJobApproval:s=>i("POST",`${n}/agent/resolve-job-approval`,s),agentArchiveCodingJob:s=>i("POST",`${n}/agent/archive-coding-job`,s),agentUnarchiveCodingJob:s=>i("POST",`${n}/agent/unarchive-coding-job`,s),agentSetThreadStatus:s=>i("POST",`${n}/agent/set-thread-status`,s),agentCreateChannel:s=>i("POST",`${n}/agent/create-channel`,s),agentRenameChannel:s=>i("POST",`${n}/agent/rename-channel`,s),agentArchiveChannel:s=>i("POST",`${n}/agent/archive-channel`,s),agentUnarchiveChannel:s=>i("POST",`${n}/agent/unarchive-channel`,s),agentAddReaction:s=>i("POST",`${n}/agent/add-reaction`,s),agentRemoveReaction:s=>i("POST",`${n}/agent/remove-reaction`,s),agentPinMessage:s=>i("POST",`${n}/agent/pin-message`,s),agentUnpinMessage:s=>i("POST",`${n}/agent/unpin-message`,s),prepareMessageUploads:s=>i("POST",`${n}/message-uploads/prepare`,s),attachMessageFiles:s=>i("POST",`${n}/message-files/attach`,s),prepareCustomEmoji:s=>i("POST",`${n}/custom-emoji/prepare`,s),renameCustomEmoji:s=>i("POST",`${n}/custom-emoji/rename`,s),sendThreadReply:s=>i("POST",`${n}/thread-reply`,s),sendDm:s=>i("POST",`${n}/dm`,s),dmOwner:s=>i("POST",`${n}/dm-owner`,s),getVaultValues:s=>i("POST",`${n}/vault-values`,s)}}import{closeSync as Ls,fstatSync as zO,mkdirSync as Uo,openSync as mb,readdirSync as TO,readFileSync as fb,readSync as PO,renameSync as RO,rmSync as qs,statSync as hb,writeFileSync as gb}from"node:fs";import{spawn as OO,execFile as tD}from"node:child_process";import{createHash as EO}from"node:crypto";import{createRequire as jO}from"node:module";import{createConnection as IO}from"node:net";import{homedir as CO}from"node:os";import{dirname as Us,join as Zr}from"node:path";var AO=(()=>{let e;return()=>{if(e!==void 0)return e;let{lockSync:t}=jO(import.meta.url)("proper-lockfile");return e=t,t}})(),Bl=()=>{},yb=1,MO=1;function NO(){let e=process.env.LINZUMI_DEV_SERVICES_DIR?.trim();return e!==void 0&&e!==""?e:Zr(CO(),".linzumi","dev-services")}function _b(e){let t=e.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^[-.]+|[-.]+$/g,"").slice(0,80),r=EO("sha256").update(e).digest("hex").slice(0,8),n=t===""?"runner":t;return Zr(NO(),`${n}.${r}`)}function Zs(e){let t=e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t)&&!t.includes("..")?t:void 0}function Rn(e,t){return Zr(e,"services",`${t}.json`)}function Hl(e,t){return Zr(e,"exits",`${t}.json`)}function bb(e,t){return Zr(e,"logs",`${t}.log`)}function Ur(e){return typeof e=="string"&&e!==""?e:void 0}function Lt(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function DO(e){return Array.isArray(e)?e.filter(t=>typeof t=="number"&&Number.isInteger(t)&&t>0&&t<=65535):[]}function LO(e){if(!Be(e)||e.version!==yb)return;let t=Ur(e.name),r=t===void 0?void 0:Zs(t),n=Ur(e.command),o=Ur(e.cwd),i=e.desiredState==="running"||e.desiredState==="stopped"?e.desiredState:void 0,s=Lt(e.updatedAtMs),a=Ur(e.logPath);if(r===void 0||r!==t||n===void 0||o===void 0||i===void 0||s===void 0||a===void 0)return;let c=e.failure,d;if(c!=null){let u=Be(c)?Ur(c.reason):void 0,p=Be(c)?Lt(c.atMs):void 0,m=[...u===void 0?["reason"]:[],...p===void 0?["atMs"]:[]];if(m.length===0&&u!==void 0&&p!==void 0)d={reason:u,atMs:p};else{let f=`dev-service "${r}" has a malformed persisted failure record: invalid ${m.join(", ")}`;console.warn(`[dev_services.failure_record_malformed] name=${r} invalid_fields=${m.join(",")}`),d={reason:f,atMs:s}}}return{watchdogVersion:Lt(e.watchdogVersion),name:r,command:n,cwd:o,ports:DO(e.ports),restartOnBranchChange:e.restartOnBranchChange===!0,desiredState:i,pid:Lt(e.pid),ownerPid:Lt(e.ownerPid),startedAtMs:Lt(e.startedAtMs),updatedAtMs:s,lastBranch:Ur(e.lastBranch),logPath:a,automaticRestartAttempts:Lt(e.automaticRestartAttempts)??0,automaticRestartWindowStartedAtMs:Lt(e.automaticRestartWindowStartedAtMs),automaticRestartCause:Ur(e.automaticRestartCause),failure:d}}function qO(e){return{version:yb,watchdogVersion:e.watchdogVersion??null,name:e.name,command:e.command,cwd:e.cwd,ports:[...e.ports],restartOnBranchChange:e.restartOnBranchChange,desiredState:e.desiredState,pid:e.pid??null,ownerPid:e.ownerPid??null,startedAtMs:e.startedAtMs??null,updatedAtMs:e.updatedAtMs,lastBranch:e.lastBranch??null,logPath:e.logPath,automaticRestartAttempts:e.automaticRestartAttempts,automaticRestartWindowStartedAtMs:e.automaticRestartWindowStartedAtMs??null,automaticRestartCause:e.automaticRestartCause??null,failure:e.failure===void 0?null:{reason:e.failure.reason,atMs:e.failure.atMs}}}function UO(e){return`${JSON.stringify(qO(e))}
161
161
  `}var Fl=5e3;function ZO(e,t,r){let n=`${Rn(e,t)}.lock`;try{Uo(Us(n),{recursive:!0});let o=(()=>{try{let s=hb(n),a=Date.now()-s.mtimeMs;if(s.isFile()&&a>=Fl){qs(n),r("dev_services.legacy_record_lock_recovered",{name:t,path:n,age_ms:a});return}return s.isDirectory()&&a>=Fl?a:void 0}catch(s){if((s!==null&&typeof s=="object"&&"code"in s?s.code:void 0)!=="ENOENT")throw s;return}})(),i=AO()(Rn(e,t),{lockfilePath:n,realpath:!1,retries:0,stale:Fl,update:1e3,onCompromised:s=>{throw r("dev_services.record_lock_compromised",{name:t,path:n,message:s.message}),s}});return o!==void 0&&r("dev_services.record_lease_recovered",{name:t,path:n,age_ms:o}),{ok:!0,release:i,path:n}}catch(o){let i=o instanceof Error?o.message:String(o);return r("dev_services.record_lock_failed",{name:t,path:n,message:i}),{ok:!1,error:`could not lock dev-service state at ${n}: ${i}`}}}function JO(e,t,r){try{return e.release(),{ok:!0}}catch(n){let o=n instanceof Error?n.message:String(n);return r("dev_services.record_unlock_failed",{name:t,path:e.path,message:o}),{ok:!1,error:`could not unlock dev-service state at ${e.path}: ${o}`}}}function FO(e,t,r){let n=Rn(e,t.name);try{Uo(Us(n),{recursive:!0});let o=`${n}.tmp`;return gb(o,UO(t),"utf8"),RO(o,n),{ok:!0}}catch(o){let i=o instanceof Error?o.message:String(o);return r("dev_services.record_write_failed",{path:n,message:i}),{ok:!1,error:`could not persist dev-service state at ${n}: ${i}`}}}function Vl(e,t,r,n){let o=ZO(e,t.name,r);if(!o.ok)return{ok:!1,error:o.error,persisted:!1};n?.(o.path);let i=FO(e,t,r),s=JO(o,t.name,r);return i.ok?s.ok?{ok:!0}:{ok:!1,error:s.error,persisted:!0}:{ok:!1,error:i.error,persisted:!1}}function Gl(e,t){let r=Zs(t);if(r===void 0)return;let n;try{n=fb(Rn(e,r),"utf8")}catch{return}try{return LO(JSON.parse(n))}catch{return}}function VO(e){let t;try{t=TO(Zr(e,"services"))}catch{return[]}let r=[];for(let n of t){if(!n.endsWith(".json"))continue;let o=Gl(e,n.slice(0,-5));o!==void 0&&r.push(o)}return r.sort((n,o)=>n.name.localeCompare(o.name))}function vb(e,t){let r;try{r=fb(Hl(e,t),"utf8")}catch{return}try{let n=JSON.parse(r);if(!Be(n))return;let o=Lt(n.atMs);return o===void 0?void 0:{code:typeof n.code=="number"?n.code:null,signal:typeof n.signal=="string"?n.signal:null,atMs:o}}catch{return}}function WO(e){return JSON.stringify(e)}function BO(){return`
162
162
  const { spawn } = require('node:child_process');
163
163
  const fs = require('node:fs');
@@ -247,12 +247,12 @@ const watchdog = setInterval(() => {
247
247
  `.trim()}function HO(e,t){return{command:e,args:["-e",BO(),WO(t)]}}function wb(e,t=r=>process.kill(r,0)){if(e===void 0||e<=1)return!1;try{return t(-e),!0}catch(r){return r?.code==="EPERM"}}function Kl(e,t){if(t.pid===void 0||t.pid<=1)return!1;let r=vb(e,t.name);return r!==void 0&&t.startedAtMs!==void 0&&r.atMs>=t.startedAtMs?!1:wb(t.pid)}async function Ql(e,t=750,r="127.0.0.1"){return await new Promise(n=>{let o=IO({port:e,host:r}),i=s=>{o.removeAllListeners(),o.destroy(),n(s)};o.setTimeout(t),o.once("connect",()=>i(!0)),o.once("timeout",()=>i(!1)),o.once("error",()=>i(!1))})}async function GO(e,t){let r=Kl(e,t),n=[];for(let i of t.ports)n.push({port:i,listening:r?await Ql(i):!1});let o=t.desiredState==="stopped"?"stopped":!r&&t.failure!==void 0?"failed":r?n.every(i=>i.listening)?"running":"unhealthy":"exited";return{record:t,liveness:o,portProbes:n,lastExit:vb(e,t.name),failure:t.failure}}async function Yl(e){let t=[];for(let r of VO(e))t.push(await GO(e,r));return t}function KO(e=process.env){let t=e.SHELL?.trim();return t!==void 0&&t!==""?t:"/bin/sh"}async function kb(e){let t=e.log??Bl,r=Zs(e.definition.name);if(r===void 0)return{ok:!1,error:"invalid service name: use 1-64 lowercase letters, digits, ., _ or -"};let n=e.definition.command.trim();if(n==="")return{ok:!1,error:"service command must not be empty"};try{if(!hb(e.definition.cwd).isDirectory())return{ok:!1,error:`cwd is not a directory: ${e.definition.cwd}`}}catch{return{ok:!1,error:`cwd does not exist: ${e.definition.cwd}`}}let o=Gl(e.scopeDir,r);o!==void 0&&Kl(e.scopeDir,o)&&await Wl(o.pid,t,r);let i=e.nowMs??Date.now(),s=bb(e.scopeDir,r),a=Hl(e.scopeDir,r),c;try{Uo(Us(s),{recursive:!0}),Uo(Zr(e.scopeDir,"services"),{recursive:!0}),Uo(Us(a),{recursive:!0}),c=mb(s,"a")}catch(y){return{ok:!1,error:`cannot open service log: ${y instanceof Error?y.message:String(y)}`}}try{qs(a,{force:!0})}catch{}let d=e.shellPath??KO(),u=HO(e.nodeExecPath??process.execPath,{command:d,args:["-lc",n],cwd:e.definition.cwd,pollIntervalMs:e.watchdogPollIntervalMs??500,recordPath:Rn(e.scopeDir,r),exitStatusPath:a});try{gb(c,`
248
248
  --- linzumi dev-service "${r}" starting at ${new Date(i).toISOString()} (owner pid ${e.ownerPid}) ---
249
249
  $ ${n}
250
- `)}catch{t("dev_services.start_banner_write_failed",{name:r,log_path:s})}let p={watchdogVersion:MO,name:r,command:n,cwd:e.definition.cwd,ports:[...new Set(e.definition.ports)].sort((y,v)=>y-v),restartOnBranchChange:e.definition.restartOnBranchChange===!0,desiredState:"stopped",pid:void 0,ownerPid:e.ownerPid,startedAtMs:i,updatedAtMs:i,lastBranch:void 0,logPath:s,automaticRestartAttempts:e.automaticRestartState?.attempts??0,automaticRestartWindowStartedAtMs:e.automaticRestartState?.windowStartedAtMs,automaticRestartCause:e.automaticRestartState?.cause,failure:{reason:`dev service "${r}" start did not complete`,atMs:i}},m=Vl(e.scopeDir,p,t);if(!m.ok){try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}return m}try{await e.beforeWatchdogSpawnForTest?.()}catch(y){try{Ls(c)}catch(v){t("dev_services.log_close_failed",{name:r,message:v instanceof Error?v.message:String(v)})}return{ok:!1,error:y instanceof Error?y.message:`start interrupted before watchdog spawn: ${String(y)}`}}let f;try{let y=OO(u.command,[...u.args],{cwd:e.definition.cwd,detached:!0,stdio:["ignore",c,c],env:{...process.env,ELECTRON_RUN_AS_NODE:"1"}});y.unref(),f=y.pid}catch(y){return{ok:!1,error:`spawn failed: ${y instanceof Error?y.message:String(y)}`}}finally{try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}}if(f===void 0)return{ok:!1,error:"spawn failed: no pid"};let h={...p,desiredState:"running",pid:f,failure:void 0},g=Vl(e.scopeDir,h,t,e.afterFinalRecordLockedForTest);return g.ok?(t("dev_services.started",{name:r,pid:f,owner_pid:e.ownerPid,cwd:e.definition.cwd,ports:[...h.ports]}),{ok:!0,record:h}):(g.persisted||await Wl(f,t,r,0),g)}async function Wl(e,t,r,n=3e3){if(e===void 0||e<=1)return;try{process.kill(-e,"SIGTERM")}catch{return}let o=Date.now()+n;for(;Date.now()<o;){if(!wb(e))return;await new Promise(i=>setTimeout(i,100))}try{process.kill(-e,"SIGKILL"),t("dev_services.stop_escalated",{name:r,pgid:e})}catch{}}async function Xl(e){let t=e.log??Bl,r=Gl(e.scopeDir,e.name);if(r===void 0)return{ok:!1,error:`unknown service: ${e.name}`};Kl(e.scopeDir,r)&&await Wl(r.pid,t,r.name);let n={...r,desiredState:"stopped",pid:void 0,ownerPid:void 0,updatedAtMs:e.nowMs??Date.now(),failure:void 0},o=Vl(e.scopeDir,n,t);return o.ok?(t("dev_services.stopped",{name:r.name}),{ok:!0,record:n}):o}async function xb(e){let t=e.log??Bl,r=await Xl(e);if(!r.ok)return r;try{qs(Rn(e.scopeDir,r.record.name),{force:!0}),qs(Hl(e.scopeDir,r.record.name),{force:!0})}catch(n){let o=n instanceof Error?n.message:String(n);return t("dev_services.remove_failed",{name:r.record.name,message:o}),{ok:!1,error:`could not remove dev service "${r.record.name}": ${o}`}}return r}function Sb(e,t,r=16384){let n=Zs(t);if(n===void 0)return;let o=bb(e,n),i;try{i=mb(o,"r");let s=zO(i).size,a=Math.min(s,r),c=Buffer.alloc(a);return PO(i,c,0,a,s-a),c.toString("utf8")}catch{return}finally{if(i!==void 0)try{Ls(i)}catch{}}}var aD=10*6e4;function $b(e){return{name:"linzumi",command:e.command??"linzumi",args:[...e.argsPrefix??[],"mcp","server","--api-url",e.kandanUrl,...e.authFilePath===void 0?[]:["--auth-file",e.authFilePath],...e.delegationAuthFilePath===void 0?[]:["--delegation-auth-file",e.delegationAuthFilePath],...e.ownerUsername===void 0?[]:["--owner-username",e.ownerUsername],...e.cwd===void 0?[]:["--cwd",e.cwd],...e.threadId===void 0?[]:["--thread-id",e.threadId],"--mode",e.operatingMode??"text",...e.toolScope===void 0||e.toolScope==="all"?[]:["--tool-scope",e.toolScope],...e.agentSession===!0?["--agent-session"]:[],...e.askUserQuestionTool===!0?["--ask-user-question-tool"]:[],...e.multiAgentJobs===!0?["--multi-agent-jobs"]:[]],env:{...e.accessToken===void 0?{}:{LINZUMI_MCP_ACCESS_TOKEN:e.accessToken},...e.devServices===void 0?{}:{LINZUMI_DEV_SERVICES_SCOPE:e.devServices.scope,LINZUMI_DEV_SERVICES_OWNER_PID:String(e.devServices.ownerPid)},ELECTRON_RUN_AS_NODE:"1"}}}function zb(e){return`${JSON.stringify({mcpServers:{[e.name]:{command:e.command,args:e.args,env:e.env}}},null,2)}
250
+ `)}catch{t("dev_services.start_banner_write_failed",{name:r,log_path:s})}let p={watchdogVersion:MO,name:r,command:n,cwd:e.definition.cwd,ports:[...new Set(e.definition.ports)].sort((y,v)=>y-v),restartOnBranchChange:e.definition.restartOnBranchChange===!0,desiredState:"stopped",pid:void 0,ownerPid:e.ownerPid,startedAtMs:i,updatedAtMs:i,lastBranch:void 0,logPath:s,automaticRestartAttempts:e.automaticRestartState?.attempts??0,automaticRestartWindowStartedAtMs:e.automaticRestartState?.windowStartedAtMs,automaticRestartCause:e.automaticRestartState?.cause,failure:{reason:`dev service "${r}" start did not complete`,atMs:i}},m=Vl(e.scopeDir,p,t);if(!m.ok){try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}return m}try{await e.beforeWatchdogSpawnForTest?.()}catch(y){try{Ls(c)}catch(v){t("dev_services.log_close_failed",{name:r,message:v instanceof Error?v.message:String(v)})}return{ok:!1,error:y instanceof Error?y.message:`start interrupted before watchdog spawn: ${String(y)}`}}let f;try{let y=OO(u.command,[...u.args],{cwd:e.definition.cwd,detached:!0,stdio:["ignore",c,c],env:{...process.env,ELECTRON_RUN_AS_NODE:"1"}});y.unref(),f=y.pid}catch(y){return{ok:!1,error:`spawn failed: ${y instanceof Error?y.message:String(y)}`}}finally{try{Ls(c)}catch(y){t("dev_services.log_close_failed",{name:r,message:y instanceof Error?y.message:String(y)})}}if(f===void 0)return{ok:!1,error:"spawn failed: no pid"};let h={...p,desiredState:"running",pid:f,failure:void 0},g=Vl(e.scopeDir,h,t,e.afterFinalRecordLockedForTest);return g.ok?(t("dev_services.started",{name:r,pid:f,owner_pid:e.ownerPid,cwd:e.definition.cwd,ports:[...h.ports]}),{ok:!0,record:h}):(g.persisted||await Wl(f,t,r,0),g)}async function Wl(e,t,r,n=3e3){if(e===void 0||e<=1)return;try{process.kill(-e,"SIGTERM")}catch{return}let o=Date.now()+n;for(;Date.now()<o;){if(!wb(e))return;await new Promise(i=>setTimeout(i,100))}try{process.kill(-e,"SIGKILL"),t("dev_services.stop_escalated",{name:r,pgid:e})}catch{}}async function Xl(e){let t=e.log??Bl,r=Gl(e.scopeDir,e.name);if(r===void 0)return{ok:!1,error:`unknown service: ${e.name}`};Kl(e.scopeDir,r)&&await Wl(r.pid,t,r.name);let n={...r,desiredState:"stopped",pid:void 0,ownerPid:void 0,updatedAtMs:e.nowMs??Date.now(),failure:void 0},o=Vl(e.scopeDir,n,t);return o.ok?(t("dev_services.stopped",{name:r.name}),{ok:!0,record:n}):o}async function xb(e){let t=e.log??Bl,r=await Xl(e);if(!r.ok)return r;try{qs(Rn(e.scopeDir,r.record.name),{force:!0}),qs(Hl(e.scopeDir,r.record.name),{force:!0})}catch(n){let o=n instanceof Error?n.message:String(n);return t("dev_services.remove_failed",{name:r.record.name,message:o}),{ok:!1,error:`could not remove dev service "${r.record.name}": ${o}`}}return r}function Sb(e,t,r=16384){let n=Zs(t);if(n===void 0)return;let o=bb(e,n),i;try{i=mb(o,"r");let s=zO(i).size,a=Math.min(s,r),c=Buffer.alloc(a);return PO(i,c,0,a,s-a),c.toString("utf8")}catch{return}finally{if(i!==void 0)try{Ls(i)}catch{}}}var cD=10*6e4;function $b(e){return{name:"linzumi",command:e.command??"linzumi",args:[...e.argsPrefix??[],"mcp","server","--api-url",e.kandanUrl,...e.authFilePath===void 0?[]:["--auth-file",e.authFilePath],...e.delegationAuthFilePath===void 0?[]:["--delegation-auth-file",e.delegationAuthFilePath],...e.ownerUsername===void 0?[]:["--owner-username",e.ownerUsername],...e.cwd===void 0?[]:["--cwd",e.cwd],...e.threadId===void 0?[]:["--thread-id",e.threadId],"--mode",e.operatingMode??"text",...e.toolScope===void 0||e.toolScope==="all"?[]:["--tool-scope",e.toolScope],...e.agentSession===!0?["--agent-session"]:[],...e.askUserQuestionTool===!0?["--ask-user-question-tool"]:[],...e.multiAgentJobs===!0?["--multi-agent-jobs"]:[]],env:{...e.accessToken===void 0?{}:{LINZUMI_MCP_ACCESS_TOKEN:e.accessToken},...e.devServices===void 0?{}:{LINZUMI_DEV_SERVICES_SCOPE:e.devServices.scope,LINZUMI_DEV_SERVICES_OWNER_PID:String(e.devServices.ownerPid)},ELECTRON_RUN_AS_NODE:"1"}}}function zb(e){return`${JSON.stringify({mcpServers:{[e.name]:{command:e.command,args:e.args,env:e.env}}},null,2)}
251
251
  `}function Tb(e){return`[mcp_servers.${e.name}]
252
252
  command = ${JSON.stringify(e.command)}
253
253
  args = ${QO(e.args)}
254
254
  ${Object.keys(e.env).length===0?"":`env = ${YO(e.env)}
255
- `}`}function QO(e){return`[${e.map(t=>JSON.stringify(t)).join(", ")}]`}function YO(e){return`{ ${Object.entries(e).map(([r,n])=>`${r} = ${JSON.stringify(n)}`).join(", ")} }`}var Pb="linzumi_ask_user_question",Zo=4,Jo=12,Fo=2,Vo=4,Rb="Other";var Ob=2147483647,XO=2147483,uD=XO*1e3-5*6e4,Eb="linzumi_ask_user_question",jb="plan_mode_native_interview_tool",Ib="no_active_turn";function eE(e){let t=e.trim().toLowerCase();switch(t){case"other":case"something else":case"something else...":return!0;default:return t.includes("other")||t.includes("something else")}}function Cb(e){let t=we(e),r=qr(t?.questions);if(r===void 0)return{type:"invalid",message:"questions: expected an array"};if(r.length===0)return{type:"invalid",message:"questions: min 1, got 0"};if(r.length>Zo)return{type:"invalid",message:`questions: max ${Zo}, got ${r.length}`};let n=[],o=new Set;for(let[i,s]of r.entries()){let a=we(s);if(a===void 0)return{type:"invalid",message:`questions[${i}]: expected an object`};let c=ye(a.question);if(c===void 0)return{type:"invalid",message:`questions[${i}].question: must be a non-empty string`};if(o.has(c))return{type:"invalid",message:`questions: duplicate question text ${JSON.stringify(c)}`};let d=ye(a.header);if(d===void 0)return{type:"invalid",message:`questions[${i}].header: must be a non-empty string`};if(d.length>Jo)return{type:"invalid",message:`questions[${i}].header: max ${Jo} chars, got ${d.length}`};if(a.multiSelect!==void 0&&typeof a.multiSelect!="boolean")return{type:"invalid",message:`questions[${i}].multiSelect: must be a boolean`};let u=qr(a.options);if(u===void 0)return{type:"invalid",message:`questions[${i}].options: expected an array`};if(u.length<Fo)return{type:"invalid",message:`questions[${i}].options: min ${Fo}, got ${u.length}`};if(u.length>Vo)return{type:"invalid",message:`questions[${i}].options: max ${Vo}, got ${u.length}`};let p=[],m=new Set;for(let[f,h]of u.entries()){let g=we(h),y=ye(g?.label);if(g===void 0||y===void 0)return{type:"invalid",message:`questions[${i}].options[${f}].label: must be a non-empty string`};if(g.description!==void 0&&typeof g.description!="string")return{type:"invalid",message:`questions[${i}].options[${f}].description: must be a string`};if(eE(y))return{type:"invalid",message:`questions[${i}].options[${f}].label: ${JSON.stringify(y)} is reserved for the built-in Other option`};if(m.has(y))return{type:"invalid",message:`questions[${i}].options: duplicate label ${JSON.stringify(y)}`};m.add(y),p.push({label:y,description:typeof g.description=="string"?g.description:""})}o.add(c),n.push({question:c,header:d,options:p,multiSelect:a.multiSelect===!0})}return{type:"ok",request:{questions:n}}}function Ab(e){return{message:"Linzumi interview: the user is being asked in the Linzumi thread.",requestedSchema:{type:"object",properties:Object.fromEntries(e.questions.map(t=>[t.question,{type:"string",description:t.header}])),required:e.questions.map(t=>t.question)},_meta:{[Eb]:{version:1,questions:e.questions.map(t=>({question:t.question,header:t.header,multiSelect:t.multiSelect,options:t.options.map(r=>({label:r.label,description:r.description}))}))}}}}function Mb(e,t){let r=we(t??void 0);if(r===void 0)return{type:"invalid",message:"the runner accepted the interview but returned no answers; it may predate linzumi_ask_user_question support"};let n={};for(let o of e.questions){let i=r[o.question];if(typeof i!="string")return{type:"invalid",message:`the runner returned no answer for question ${JSON.stringify(o.question)}`};try{n[o.question]=JSON.parse(i)}catch{return{type:"invalid",message:`the runner returned an undecodable answer for question ${JSON.stringify(o.question)}`}}}return{type:"ok",answers:n}}function Nb(e){return ye(we(we(e)?.[Eb])?.reason)}var Db=`<linzumi_markdown_media_guidance>
255
+ `}`}function QO(e){return`[${e.map(t=>JSON.stringify(t)).join(", ")}]`}function YO(e){return`{ ${Object.entries(e).map(([r,n])=>`${r} = ${JSON.stringify(n)}`).join(", ")} }`}var Pb="linzumi_ask_user_question",Zo=4,Jo=12,Fo=2,Vo=4,Rb="Other";var Ob=2147483647,XO=2147483,lD=XO*1e3-5*6e4,Eb="linzumi_ask_user_question",jb="plan_mode_native_interview_tool",Ib="no_active_turn";function eE(e){let t=e.trim().toLowerCase();switch(t){case"other":case"something else":case"something else...":return!0;default:return t.includes("other")||t.includes("something else")}}function Cb(e){let t=we(e),r=qr(t?.questions);if(r===void 0)return{type:"invalid",message:"questions: expected an array"};if(r.length===0)return{type:"invalid",message:"questions: min 1, got 0"};if(r.length>Zo)return{type:"invalid",message:`questions: max ${Zo}, got ${r.length}`};let n=[],o=new Set;for(let[i,s]of r.entries()){let a=we(s);if(a===void 0)return{type:"invalid",message:`questions[${i}]: expected an object`};let c=ye(a.question);if(c===void 0)return{type:"invalid",message:`questions[${i}].question: must be a non-empty string`};if(o.has(c))return{type:"invalid",message:`questions: duplicate question text ${JSON.stringify(c)}`};let d=ye(a.header);if(d===void 0)return{type:"invalid",message:`questions[${i}].header: must be a non-empty string`};if(d.length>Jo)return{type:"invalid",message:`questions[${i}].header: max ${Jo} chars, got ${d.length}`};if(a.multiSelect!==void 0&&typeof a.multiSelect!="boolean")return{type:"invalid",message:`questions[${i}].multiSelect: must be a boolean`};let u=qr(a.options);if(u===void 0)return{type:"invalid",message:`questions[${i}].options: expected an array`};if(u.length<Fo)return{type:"invalid",message:`questions[${i}].options: min ${Fo}, got ${u.length}`};if(u.length>Vo)return{type:"invalid",message:`questions[${i}].options: max ${Vo}, got ${u.length}`};let p=[],m=new Set;for(let[f,h]of u.entries()){let g=we(h),y=ye(g?.label);if(g===void 0||y===void 0)return{type:"invalid",message:`questions[${i}].options[${f}].label: must be a non-empty string`};if(g.description!==void 0&&typeof g.description!="string")return{type:"invalid",message:`questions[${i}].options[${f}].description: must be a string`};if(eE(y))return{type:"invalid",message:`questions[${i}].options[${f}].label: ${JSON.stringify(y)} is reserved for the built-in Other option`};if(m.has(y))return{type:"invalid",message:`questions[${i}].options: duplicate label ${JSON.stringify(y)}`};m.add(y),p.push({label:y,description:typeof g.description=="string"?g.description:""})}o.add(c),n.push({question:c,header:d,options:p,multiSelect:a.multiSelect===!0})}return{type:"ok",request:{questions:n}}}function Ab(e){return{message:"Linzumi interview: the user is being asked in the Linzumi thread.",requestedSchema:{type:"object",properties:Object.fromEntries(e.questions.map(t=>[t.question,{type:"string",description:t.header}])),required:e.questions.map(t=>t.question)},_meta:{[Eb]:{version:1,questions:e.questions.map(t=>({question:t.question,header:t.header,multiSelect:t.multiSelect,options:t.options.map(r=>({label:r.label,description:r.description}))}))}}}}function Mb(e,t){let r=we(t??void 0);if(r===void 0)return{type:"invalid",message:"the runner accepted the interview but returned no answers; it may predate linzumi_ask_user_question support"};let n={};for(let o of e.questions){let i=r[o.question];if(typeof i!="string")return{type:"invalid",message:`the runner returned no answer for question ${JSON.stringify(o.question)}`};try{n[o.question]=JSON.parse(i)}catch{return{type:"invalid",message:`the runner returned an undecodable answer for question ${JSON.stringify(o.question)}`}}}return{type:"ok",answers:n}}function Nb(e){return ye(we(we(e)?.[Eb])?.reason)}var Db=`<linzumi_markdown_media_guidance>
256
256
  Some Linzumi users have opted into rich Markdown media rendering. When you are
257
257
  writing a visible Linzumi message, channel message, or thread reply, you may use
258
258
  these Markdown-compatible media directives:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linzumi/cli",
3
- "version": "1.0.269",
3
+ "version": "1.0.271",
4
4
  "description": "Linzumi CLI \u2014 point a Codex agent at the real code on your laptop, with your team watching and steering from shared threads.",
5
5
  "type": "module",
6
6
  "bin": {