@hlix/cli 1.1.0 → 1.2.0

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.
@@ -1,400 +0,0 @@
1
- #!/usr/bin/env node
2
- import{resolve as kd}from"node:path";import{parseArgs as Sd}from"node:util";import Xc from"openapi-fetch";function Hr(H){return Xc({baseUrl:H.baseUrl,headers:H.headers,fetch:H.fetch})}var Wt=(H)=>({kind:"apiKey",apiKey:H});var Mr=(H)=>({kind:"bearer",token:H});function Yc(H){switch(H.kind){case"apiKey":return{"x-api-key":H.apiKey};case"session":return{cookie:H.cookie};case"bearer":return{authorization:`Bearer ${H.token}`}}}function Zc(H){return H?{"X-Organization-Id":H}:{}}function ti(H,U){return{...Yc(H),...Zc(U)}}function Qc(H){if(typeof H!=="object"||H===null)return null;let{error:U}=H;return typeof U==="string"?U:null}class De extends Error{status;body;requestId;method;url;constructor(H,U){super(H);this.name=new.target.name,this.status=U.status,this.body=U.body,this.requestId=U.requestId??null,this.method=U.method,this.url=U.url}}class zt extends De{issues;constructor(H,U,G){super(H,U);this.issues=G}}class un extends De{}class mn extends De{}class fn extends De{}class St extends De{}class xt extends De{}class jt extends De{retryAfter;constructor(H,U,G){super(H,U);this.retryAfter=G}}class gn extends De{}class Et extends De{}class mt extends Error{method;url;constructor(H,U){super(H,{cause:U.cause});this.name="HlixTransportError",this.method=U.method,this.url=U.url}}function el(H){if(typeof H!=="object"||H===null)return null;let U=H;if(U.success!==!1)return null;let G=U.error?.message;if(typeof G!=="string")return null;try{let B=JSON.parse(G);return Array.isArray(B)?B:[]}catch{return[]}}function tl(H){let U=H.get("retry-after");if(!U)return null;let G=Number(U);return Number.isFinite(G)&&G>=0?G:null}function Pt(H,U,G){let B={status:H.status,body:U,requestId:H.headers.get("x-request-id"),method:G.method,url:G.url},W=Qc(U),z=`${G.method} ${G.url} failed with ${H.status}`,J=el(U);if(J)return new zt(`${G.method} ${G.url}: request body failed validation`,B,J);let K=W??z;switch(H.status){case 400:return new un(K,B);case 401:return new mn(K,B);case 403:return new fn(K,B);case 404:return new St(K,B);case 409:return new xt(K,B);case 429:return new jt(K,B,tl(H.headers));case 501:return new gn(K,B);default:return H.status>=500?new Et(K,B):new De(K,B)}}var ni=new Set(["GET","HEAD","PUT","DELETE","OPTIONS","TRACE"]);function Kn(H){return ni.has(H.toUpperCase())}var nl=new Set([429,500,502,503,504]);function rl(H){return nl.has(H)}var Dr={attempts:3,baseDelayMs:200,maxDelayMs:5000};function hn(H,U,G,B=Math.random){if(G!==null)return Math.min(G*1000,U.maxDelayMs);let W=Math.min(U.baseDelayMs*2**H,U.maxDelayMs);return Math.round(B()*W)}function Ur(H){if(!Kn(H.method))return!1;if(H.attempt+1>=H.policy.attempts)return!1;return H.status===null||rl(H.status)}var ol=(H)=>new Promise((U)=>setTimeout(U,H));function sl(H){let U=H.headers.get("retry-after");if(!U)return null;let G=Number(U);return Number.isFinite(G)&&G>=0?G:null}function ri(H){let{base:U,policy:G}=H,B=H.sleep??ol,W=H.random??Math.random;return async(z)=>{let J=z.method.toUpperCase(),K=Kn(J)?z.clone():null;for(let q=0;;q+=1){let X=q===0?z:K.clone(),V;try{V=await U(X)}catch(Z){if(!K||!Ur({method:J,attempt:q,policy:G,status:null}))throw new mt(`${J} ${z.url}: ${Z instanceof Error?Z.message:String(Z)}`,{method:J,url:z.url,cause:Z});await B(hn(q,G,null,W));continue}if(!Ur({method:J,attempt:q,policy:G,status:V.status}))return V;if(!K)return V;await B(hn(q,G,sl(V),W))}}}function de(H,U){if(H.response.ok)return H.data;throw Pt(H.response,H.error??H.data,U)}var yn=(H)=>typeof H==="string"?H:"";function Gr(H){let U;try{U=JSON.parse(H)}catch{return null}if(typeof U!=="object"||U===null)return null;let G=U;switch(G.type){case"idle":return{type:"idle"};case"done":return{type:"done"};case"active":return typeof G.runId==="string"?{type:"active",runId:G.runId}:{type:"active"};case"on_chat_model_stream":return{type:"on_chat_model_stream",delta:yn(G.delta)};case"reasoning":return{type:"reasoning",delta:yn(G.delta)};case"on_tool_start":return{type:"on_tool_start",name:yn(G.name),input:G.input};case"on_tool_end":return{type:"on_tool_end",name:yn(G.name),output:G.output};case"error":return{type:"error",message:yn(G.message)};default:return null}}var Br=(H)=>H.type==="done"||H.type==="idle"||H.type==="error";var il=()=>({event:null,data:[],id:null,retry:null});function oi(H,U,G){switch(U){case"event":H.event=G;return;case"data":H.data.push(G);return;case"id":if(!G.includes("\x00"))H.id=G;return;case"retry":{if(/^\d+$/.test(G))H.retry=Number(G);return}default:return}}function ii(H){let U=H.data.join(`
3
- `),{event:G,id:B}=H;if(H.data=[],H.event=null,U==="")return null;return{event:G,data:U,id:B,retry:H.retry}}function si(H,U){if(U==="")return ii(H);if(U.startsWith(":"))return null;let G=U.indexOf(":");if(G===-1)return oi(H,U,""),null;let B=U.slice(0,G),W=U.slice(G+1);if(W.startsWith(" "))W=W.slice(1);return oi(H,B,W),null}function al(H){let U=[],G=0;for(let B=0;B<H.length;B+=1){let W=H[B];if(W!==`
4
- `&&W!=="\r")continue;if(U.push(H.slice(G,B)),W==="\r"&&H[B+1]===`
5
- `)B+=1;G=B+1}return{lines:U,rest:H.slice(G)}}async function*qn(H,U){let G=H.getReader(),B=new TextDecoder,W=il(),z="",J=()=>void G.cancel().catch(()=>{});U?.addEventListener("abort",J,{once:!0});try{for(;;){let{done:q,value:X}=await G.read();if(q)break;z+=B.decode(X,{stream:!0});let{lines:V,rest:Z}=al(z);z=Z;for(let Q of V){let ne=si(W,Q);if(ne)yield ne}if(U?.aborted)return}if(z+=B.decode(),z!==""){let q=si(W,z);if(q)yield q}let K=ii(W);if(K)yield K}finally{U?.removeEventListener("abort",J),G.releaseLock()}}function ft(H,U){return new Promise((G)=>{if(U?.aborted)return G();let B=setTimeout(W,H);function W(){clearTimeout(B),U?.removeEventListener("abort",W),G()}U?.addEventListener("abort",W,{once:!0})})}var zr=()=>crypto.randomUUID();function li(H){return{threadId:H.threadId,runId:H.runId??zr(),state:{},messages:[{id:H.messageId??zr(),role:"user",content:H.text}],tools:[],context:[],forwardedProps:H.forwardedProps??{}}}function di(H,U){return{threadId:H,runId:zr(),state:{},messages:[],tools:[],context:[],...U?{lastSeenEventId:U}:{}}}function Jr(H){let U=H.metadata;if(typeof U!=="object"||U===null)return;let G=U.eventId;return typeof G==="string"&&G?G:void 0}function Kr(H){let U;try{U=JSON.parse(H)}catch{return null}if(typeof U!=="object"||U===null)return null;return typeof U.type==="string"?U:null}function _t(H,U={}){if(U.taskId)return`project:${H}:task:${U.taskId}`;if(U.cycleId)return`project:${H}:cycle:${U.cycleId}`;return`project:${H}`}var cl=new Set(["done","merged","failed","pr_created","ci_passing"]),ll=new Set(["done","pr_created","failed","canceled"]);function qr(H,U){let G=H.tasks.find((J)=>J.id===U);if(!G)return{state:"running",task:G};let B=G.cycleId?H.cycles.find((J)=>J.id===G.cycleId):void 0;if(!(!G.cycleId||B!==void 0&&ll.has(B.status)))return{state:"running",task:G};if(cl.has(G.status))return{state:"finished",task:G};if(!B)return{state:"running",task:G};let z=B?.status==="canceled"?"Task cycle was canceled":B?.status==="failed"?"Task cycle failed":"Task cycle ended before this task completed";return{state:"unmet",task:G,reason:z}}async function*Vr(H){let U;for await(let G of H){if(G.type==="STATE_SNAPSHOT")U=structuredClone(G.snapshot);else if(G.type==="STATE_DELTA"){if(U===void 0)continue;U=pi(U,G.delta)}else if(G.type!=="CUSTOM"||U===void 0)continue;yield{state:U,event:G}}}function Xr(H){if(H==="")return[];if(!H.startsWith("/"))throw Error(`Invalid JSON pointer: ${H}`);return H.slice(1).split("/").map((U)=>U.replace(/~1/g,"/").replace(/~0/g,"~"))}function Yr(H,U){let G=H;for(let B of U.slice(0,-1)){if(typeof G!=="object"||G===null)throw Error(`Path not found: /${U.join("/")}`);G=G[B]}if(typeof G!=="object"||G===null)throw Error(`Path not found: /${U.join("/")}`);return{parent:G,key:U[U.length-1]}}function Vn(H,U,G){if(U==="-"&&G)return H.length;let B=Number(U);if(!/^(0|[1-9]\d*)$/.test(U)||B>H.length||!G&&B===H.length)throw Error(`Invalid array index: ${U}`);return B}function ai(H,U){let G=Xr(U);if(G.length===0)return H;let{parent:B,key:W}=Yr(H,G);if(Array.isArray(B))return B[Vn(B,W,!1)];if(!(W in B))throw Error(`Path not found: ${U}`);return B[W]}function ci(H,U){let{parent:G,key:B}=Yr(H,Xr(U));if(Array.isArray(G))return G.splice(Vn(G,B,!1),1)[0];if(!(B in G))throw Error(`Path not found: ${U}`);let W=G[B];return delete G[B],W}function Wr(H,U,G,B){let W=Xr(U);if(W.length===0)return G;let{parent:z,key:J}=Yr(H,W);if(Array.isArray(z))if(B==="add")z.splice(Vn(z,J,!0),0,G);else z[Vn(z,J,!1)]=G;else{if(B==="replace"&&!(J in z))throw Error(`Path not found: ${U}`);z[J]=G}return H}function pi(H,U){let G=structuredClone(H);for(let B of U)switch(B.op){case"add":case"replace":G=Wr(G,B.path,structuredClone(B.value),B.op);break;case"remove":ci(G,B.path);break;case"copy":G=Wr(G,B.path,structuredClone(ai(G,B.from)),"add");break;case"move":{let W=ci(G,B.from);G=Wr(G,B.path,W,"add");break}case"test":if(JSON.stringify(ai(G,B.path))!==JSON.stringify(B.value))throw Error(`Test failed at ${B.path}`);break;default:throw Error(`Unknown patch operation: ${B.op}`)}return G}var dl={attempts:6,baseDelayMs:500,maxDelayMs:15000};function pl(H){if(H instanceof Et||H instanceof jt)return!0;return!(H instanceof De)}class Jt{raw;baseUrl;headers;fetcher;constructor(H){this.baseUrl=H.baseUrl.replace(/\/+$/,"");let U=ti(H.credential,H.organizationId),G=new Set(Object.keys(U).map((z)=>z.toLowerCase()));this.headers={...Object.fromEntries(Object.entries(H.headers??{}).filter(([z])=>!G.has(z.toLowerCase()))),...U};let B={...Dr,...H.retry},W=H.fetch??((z)=>globalThis.fetch(z));this.fetcher=ri({base:W,policy:B}),this.raw=Hr({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(H,U){return{method:H,url:`${this.baseUrl}${U}`}}workspaces={list:async(H={})=>de(await this.raw.GET("/v1/api/workspaces",H),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>de(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(H,U={})=>de(await this.raw.GET("/v1/api/projects/{id}",{...U,params:{path:{id:H}}}),this.at("GET",`/v1/api/projects/${H}`)),create:async(H)=>de(await this.raw.POST("/v1/api/projects",{body:H}),this.at("POST","/v1/api/projects")),update:async(H,U)=>de(await this.raw.PATCH("/v1/api/projects/{id}",{params:{path:{id:H}},body:U}),this.at("PATCH",`/v1/api/projects/${H}`)),delete:async(H)=>de(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:H}}}),this.at("DELETE",`/v1/api/projects/${H}`)),start:async(H,U)=>de(await this.raw.POST("/v1/api/projects/{id}/start",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/projects/${H}/start`)),stop:async(H)=>de(await this.raw.POST("/v1/api/projects/{id}/stop",{params:{path:{id:H}}}),this.at("POST",`/v1/api/projects/${H}/stop`)),resume:async(H)=>de(await this.raw.POST("/v1/api/projects/{id}/resume",{params:{path:{id:H}}}),this.at("POST",`/v1/api/projects/${H}/resume`)),status:async(H,U={})=>de(await this.raw.GET("/v1/api/projects/{id}/status",{...U,params:{path:{id:H}}}),this.at("GET",`/v1/api/projects/${H}/status`)),canvas:{view:async(H)=>de(await this.raw.GET("/v1/api/projects/{id}/canvas/agent",{params:{path:{id:H}}}),this.at("GET",`/v1/api/projects/${H}/canvas/agent`)),apply:async(H,U,G)=>de(await this.raw.POST("/v1/api/projects/{id}/canvas/agent/ops",{params:{path:{id:H}},body:{ops:U,...G?{reason:G}:{}}}),this.at("POST",`/v1/api/projects/${H}/canvas/agent/ops`)),undo:async(H)=>de(await this.raw.POST("/v1/api/projects/{id}/canvas/agent/undo",{params:{path:{id:H}}}),this.at("POST",`/v1/api/projects/${H}/canvas/agent/undo`))},deliver:async(H)=>de(await this.raw.POST("/v1/api/projects/{id}/delivery",{params:{path:{id:H}}}),this.at("POST",`/v1/api/projects/${H}/delivery`)),attachGithubRepository:async(H,U)=>de(await this.raw.POST("/v1/api/projects/{id}/repos/github",{params:{path:{id:H}},body:{githubRepository:U}}),this.at("POST",`/v1/api/projects/${H}/repos/github`)),terminal:async(H)=>de(await this.raw.GET("/v1/api/projects/{id}/terminal",{params:{path:{id:H}}}),this.at("GET",`/v1/api/projects/${H}/terminal`)),observeCycle:(H,U)=>this.observeCycle(H,U),workspace:(H)=>({environment:async()=>de(await this.raw.GET("/v1/api/projects/{id}/environment",{params:{path:{id:H}}}),this.at("GET",`/v1/api/projects/${H}/environment`)),fs:async(U)=>de(await this.raw.POST("/v1/api/projects/{id}/workspace/fs",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/projects/${H}/workspace/fs`)),exec:async(U)=>de(await this.raw.POST("/v1/api/projects/{id}/workspace/exec",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/projects/${H}/workspace/exec`))})};secrets={listEntries:async(H)=>de(await this.raw.GET("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:H}}}),this.at("GET",`/v1/api/secrets/project/${H}/entries`)),upsertEntries:async(H,U)=>de(await this.raw.PUT("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:H}},body:U}),this.at("PUT",`/v1/api/secrets/project/${H}/entries`)),importFiles:async(H,U)=>de(await this.raw.PUT("/v1/api/secrets/project/{projectId}/files",{params:{path:{projectId:H}},body:{files:U}}),this.at("PUT",`/v1/api/secrets/project/${H}/files`)),deleteEntry:async(H,U,G)=>de(await this.raw.DELETE("/v1/api/secrets/project/{projectId}/entries/{key}",{params:{path:{projectId:H,key:U},...G===void 0?{}:{query:{source:G}}}}),this.at("DELETE",`/v1/api/secrets/project/${H}/entries/${encodeURIComponent(U)}`)),exportEntries:async(H,U={})=>{let G=`/v1/api/secrets/project/${H}/export`,B=`${this.baseUrl}${G}`,W=await this.fetcher(new Request(B,{method:"POST",headers:{...this.headers,"content-type":"application/json"},body:JSON.stringify({...U.source===void 0?{}:{source:U.source},...U.format===void 0?{}:{format:U.format}})}));if(!W.ok)throw Pt(W,await W.json().catch(()=>{return}),{method:"POST",url:B});return W.text()}};repos={access:async(H,U,G="read")=>de(await this.raw.POST("/v1/api/projects/{id}/repos/{repoId}/access",{params:{path:{id:H,repoId:U}},body:{scope:G}}),this.at("POST",`/v1/api/projects/${H}/repos/${U}/access`)),head:async(H,U,G={})=>de(await this.raw.GET("/v1/api/projects/{id}/repos/{repoId}/head",{...G,params:{path:{id:H,repoId:U}}}),this.at("GET",`/v1/api/projects/${H}/repos/${U}/head`)),protectedFiles:async(H)=>de(await this.raw.GET("/v1/api/projects/{id}/protected-files",{params:{path:{id:H}}}),this.at("GET",`/v1/api/projects/${H}/protected-files`)),watch:(H,U,G={})=>this.watchRepo(H,U,G)};resources={importSkill:async(H,U)=>de(await this.raw.POST("/v1/api/projects/{id}/resources/skill",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/projects/${H}/resources/skill`)),importAgent:async(H,U)=>de(await this.raw.POST("/v1/api/projects/{id}/resources/agent",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/projects/${H}/resources/agent`)),importMcp:async(H,U)=>de(await this.raw.POST("/v1/api/projects/{id}/resources/mcp",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/projects/${H}/resources/mcp`))};async throwUploadError(H,U){let G=null;try{G=await H.json()}catch{G=await H.text().catch(()=>null)}throw Pt(H,G,{method:"PUT",url:U})}tasks={list:async(H)=>de(await this.raw.GET("/v1/api/tasks",{params:{query:H??{}}}),this.at("GET","/v1/api/tasks")),get:async(H)=>de(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:H}}}),this.at("GET",`/v1/api/tasks/${H}`)),create:async(H)=>de(await this.raw.POST("/v1/api/tasks",{body:H}),this.at("POST","/v1/api/tasks")),update:async(H,U)=>de(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:H}},body:U}),this.at("PATCH",`/v1/api/tasks/${H}`)),listComments:async(H)=>de(await this.raw.GET("/v1/api/tasks/{id}/comments",{params:{path:{id:H}}}),this.at("GET",`/v1/api/tasks/${H}/comments`)),addComment:async(H,U)=>de(await this.raw.POST("/v1/api/tasks/{id}/comments",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/tasks/${H}/comments`))};modelConfig={list:async()=>de(await this.raw.GET("/v1/api/model-config"),this.at("GET","/v1/api/model-config")),resolved:async(H)=>H?de(await this.raw.GET("/v1/api/model-config/projects/{projectId}/resolved",{params:{path:{projectId:H}}}),this.at("GET",`/v1/api/model-config/projects/${H}/resolved`)):de(await this.raw.GET("/v1/api/model-config/resolved"),this.at("GET","/v1/api/model-config/resolved")),set:async(H,U,G)=>G?de(await this.raw.PUT("/v1/api/model-config/projects/{projectId}/{slot}",{params:{path:{projectId:G,slot:H}},body:U}),this.at("PUT",`/v1/api/model-config/projects/${G}/${H}`)):de(await this.raw.PUT("/v1/api/model-config/{slot}",{params:{path:{slot:H}},body:U}),this.at("PUT",`/v1/api/model-config/${H}`)),clear:async(H,U)=>U?de(await this.raw.DELETE("/v1/api/model-config/projects/{projectId}/{slot}",{params:{path:{projectId:U,slot:H}}}),this.at("DELETE",`/v1/api/model-config/projects/${U}/${H}`)):de(await this.raw.DELETE("/v1/api/model-config/{slot}",{params:{path:{slot:H}}}),this.at("DELETE",`/v1/api/model-config/${H}`)),setProjectHarness:async(H,U)=>this.modelConfig.set("cycle",{harness:U},H),clearProjectHarness:async(H)=>this.modelConfig.clear("cycle",H),setHarness:async(H)=>this.modelConfig.set("cycle",{harness:H}),clearHarness:async()=>this.modelConfig.clear("cycle")};ai={models:async(H,U)=>de(await this.raw.GET("/v1/api/ai/w/{workspaceId}/models",{params:{path:{workspaceId:H}},...U?.signal?{signal:U.signal}:{}}),this.at("GET",`/v1/api/ai/w/${H}/models`))};managedMailboxes={configuration:async()=>de(await this.raw.GET("/v1/api/growth/managed-mailboxes/configuration",{}),this.at("GET","/v1/api/growth/managed-mailboxes/configuration")),quote:async(H)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/quotes",{body:H}),this.at("POST","/v1/api/growth/managed-mailboxes/quotes")),order:async(H)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/orders",{body:H}),this.at("POST","/v1/api/growth/managed-mailboxes/orders")),get:async(H)=>de(await this.raw.GET("/v1/api/growth/managed-mailboxes/orders/{orderId}",{params:{path:{orderId:H}}}),this.at("GET","/v1/api/growth/managed-mailboxes/orders/{orderId}")),reconcile:async(H)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/orders/{orderId}/reconcile",{params:{path:{orderId:H}}}),this.at("POST","/v1/api/growth/managed-mailboxes/orders/{orderId}/reconcile")),listOrders:async(H)=>de(await this.raw.GET("/v1/api/growth/managed-mailboxes/orders",{params:{query:{...H,limit:H?.limit===void 0?void 0:String(H.limit)}}}),this.at("GET","/v1/api/growth/managed-mailboxes/orders")),listResources:async(H)=>de(await this.raw.GET("/v1/api/growth/managed-mailboxes/resources",{params:{query:{...H,limit:H?.limit===void 0?void 0:String(H.limit)}}}),this.at("GET","/v1/api/growth/managed-mailboxes/resources")),repair:async(H,U)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/repair",{params:{path:{resourceId:H}},body:U}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/repair")),cancelHosting:async(H,U)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-hosting",{params:{path:{resourceId:H}},body:U}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-hosting")),cancelWarmup:async(H,U)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-warmup",{params:{path:{resourceId:H}},body:U}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-warmup")),removeDomain:async(H,U)=>de(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/remove-domain",{params:{path:{resourceId:H}},body:U}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/remove-domain"))};mcpServers={list:async()=>de(await this.raw.GET("/v1/api/mcp-servers",{}),this.at("GET","/v1/api/mcp-servers")),get:async(H)=>de(await this.raw.GET("/v1/api/mcp-servers/{id}",{params:{path:{id:H}}}),this.at("GET",`/v1/api/mcp-servers/${H}`)),create:async(H)=>de(await this.raw.POST("/v1/api/mcp-servers",{body:H}),this.at("POST","/v1/api/mcp-servers")),update:async(H,U)=>de(await this.raw.PATCH("/v1/api/mcp-servers/{id}",{params:{path:{id:H}},body:U}),this.at("PATCH",`/v1/api/mcp-servers/${H}`)),delete:async(H)=>de(await this.raw.DELETE("/v1/api/mcp-servers/{id}",{params:{path:{id:H}}}),this.at("DELETE",`/v1/api/mcp-servers/${H}`)),discover:async(H)=>de(await this.raw.POST("/v1/api/mcp-servers/{id}/discover",{params:{path:{id:H}}}),this.at("POST",`/v1/api/mcp-servers/${H}/discover`)),connect:async(H)=>de(await this.raw.POST("/v1/api/mcp-servers/{id}/connect",{params:{path:{id:H}}}),this.at("POST",`/v1/api/mcp-servers/${H}/connect`)),disconnect:async(H)=>de(await this.raw.POST("/v1/api/mcp-servers/{id}/disconnect",{params:{path:{id:H}}}),this.at("POST",`/v1/api/mcp-servers/${H}/disconnect`))};tools={search:async(H)=>de(await this.raw.GET("/v1/api/tools",{params:{query:{...H,limit:H?.limit===void 0?void 0:String(H.limit)}}}),this.at("GET","/v1/api/tools")),describe:async(H)=>de(await this.raw.GET("/v1/api/tools/{toolId}",{params:{path:{toolId:H}}}),this.at("GET",`/v1/api/tools/${H}`)),call:async(H,U)=>de(await this.raw.POST("/v1/api/tools/{toolId}/call",{params:{path:{toolId:H}},body:U}),this.at("POST",`/v1/api/tools/${H}/call`)),status:async(H)=>de(await this.raw.GET("/v1/api/tool-calls/{callId}",{params:{path:{callId:H}}}),this.at("GET",`/v1/api/tool-calls/${H}`)),listCalls:async(H)=>de(await this.raw.GET("/v1/api/tool-calls",{params:{query:{...H,limit:H?.limit===void 0?void 0:String(H.limit)}}}),this.at("GET","/v1/api/tool-calls"))};cycles={list:async(H)=>de(await this.raw.GET("/v1/api/cycles",{params:{query:H??{}}}),this.at("GET","/v1/api/cycles")),get:async(H)=>de(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:H}}}),this.at("GET",`/v1/api/cycles/${H}`)),propose:async(H)=>de(await this.raw.POST("/v1/api/cycles",{body:H}),this.at("POST","/v1/api/cycles")),review:async(H)=>de(await this.raw.GET("/v1/api/cycles/{id}/review",{params:{path:{id:H}}}),this.at("GET",`/v1/api/cycles/${H}/review`)),reviewComments:async(H)=>de(await this.raw.GET("/v1/api/cycles/{id}/review/comments",{params:{path:{id:H}}}),this.at("GET",`/v1/api/cycles/${H}/review/comments`))};chat={send:async(H)=>de(await this.raw.POST("/v1/api/chat/turns",{body:H}),this.at("POST","/v1/api/chat/turns")),turn:async(H,U)=>de(await this.raw.GET("/v1/api/chat/turns/{turnId}",{params:{path:{turnId:H},query:U}}),this.at("GET",`/v1/api/chat/turns/${H}`))};live={run:(H,U,G)=>this.liveStream(`/agent/${H}/run`,li(U),G),connect:(H,U,G)=>this.liveStream(`/agent/${H}/connect`,di(U,G?.lastSeenEventId),G),follow:(H,U,G={})=>this.followLive(H,U,G),stop:async(H,U,G)=>{let B=`/agent/${H}/stop/${encodeURIComponent(U)}`;return await(await this.livePost(B,G?{runId:G}:{})).json()},project:(H,U={})=>Vr(this.live.follow("project-live",_t(H,U),U)),task:(H,U,G={})=>this.watchTask(H,U,G)};async*watchTask(H,U,G){let B="";for await(let{state:W}of this.live.project(H,{taskId:U,...G})){let z=qr(W,U),J=JSON.stringify(z);if(J===B)continue;if(B=J,yield z,z.state!=="running")return}}async*followLive(H,U,G){let B=G.retry??dl,W=G.lastSeenEventId,z=0;while(!G.signal?.aborted){let J=!1,K=null;try{for await(let q of this.live.connect(H,U,{...G.signal?{signal:G.signal}:{},...W?{lastSeenEventId:W}:{}})){let X=Jr(q);if(X)W=X;if(q.type!=="STATE_SNAPSHOT"&&q.type!=="MESSAGES_SNAPSHOT")z=0;if(q.type==="RUN_STARTED"||q.type==="STATE_SNAPSHOT"||X)J=!0;if(yield q,q.type==="RUN_FINISHED"||q.type==="RUN_ERROR")return}if(!J)return}catch(q){if(G.signal?.aborted)return;if(!pl(q))throw q;K=q}if(G.signal?.aborted)return;if(z+=1,z>=B.attempts)throw K??new mt(`POST ${this.baseUrl}/v1/api/live/agent/${H}/connect: the stream kept closing`,{method:"POST",url:`${this.baseUrl}/v1/api/live/agent/${H}/connect`});await ft(hn(z,B,null),G.signal)}}async livePost(H,U,G){let B=`${this.baseUrl}/v1/api/live${H}`,W=await this.fetcher(new Request(B,{method:"POST",headers:{...this.headers,"content-type":"application/json",accept:"text/event-stream"},body:JSON.stringify(U),signal:G?.signal}));if(W.ok)return W;let z=null;try{z=await W.json()}catch{z=null}throw Pt(W,z,{method:"POST",url:B})}async*liveStream(H,U,G){let B=await this.livePost(H,U,G);if(!B.body)return;try{for await(let W of qn(B.body,G?.signal)){let z=Kr(W.data);if(!z)continue;if(yield z,z.type==="RUN_FINISHED"||z.type==="RUN_ERROR")return}}finally{B.body.cancel().catch(()=>{})}}pendingRequests={list:async(H)=>de(await this.raw.GET("/v1/api/pending-requests",{params:{query:H??{}}}),this.at("GET","/v1/api/pending-requests")),resolve:async(H,U)=>de(await this.raw.POST("/v1/api/pending-requests/{id}/resolve",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/pending-requests/${H}/resolve`))};clientInvoices={list:async(H)=>de(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:H??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(H)=>de(await this.raw.GET("/v1/api/client-billing/invoices/{id}",{params:{path:{id:H}}}),this.at("GET",`/v1/api/client-billing/invoices/${H}`)),createDraft:async(H)=>de(await this.raw.POST("/v1/api/client-billing/invoices",{body:H}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(H)=>de(await this.raw.POST("/v1/api/client-billing/invoices/{id}/issue",{params:{path:{id:H}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${H}/issue`)),void:async(H,U)=>de(await this.raw.POST("/v1/api/client-billing/invoices/{id}/void",{params:{path:{id:H}},body:{reason:U}}),this.at("POST",`/v1/api/client-billing/invoices/${H}/void`)),pay:async(H)=>de(await this.raw.POST("/v1/api/client-billing/invoices/{id}/pay",{params:{path:{id:H}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${H}/pay`)),paymentLink:async(H,U={})=>de(await this.raw.POST("/v1/api/client-billing/invoices/{id}/payment-link",{params:{path:{id:H}},body:U}),this.at("POST",`/v1/api/client-billing/invoices/${H}/payment-link`))};async*observeCycle(H,U){let G=`/v1/api/cycles/${H}/observe`;for await(let B of this.stream(G,U)){let W=Gr(B.data);if(!W)continue;if(yield W,Br(W))return}}async*watchRepo(H,U,G){let B;while(!G.signal?.aborted){let W=await this.repos.head(H,U,G);if(W.commitSha!==B)B=W.commitSha,yield{commitSha:B};await ft(15000,G.signal)}}async*stream(H,U){let G=`${this.baseUrl}${H}`,B=new Request(G,{headers:{...this.headers,accept:"text/event-stream"},signal:U?.signal}),W=await globalThis.fetch(B);if(!W.ok||!W.body){let z=null;try{z=await W.json()}catch{z=null}throw Pt(W,z,{method:"GET",url:G})}yield*qn(W.body,U?.signal)}}class e extends Error{code;details;constructor(H,U,G){super(U);if(this.name="CliError",this.code=H,G!==void 0)this.details=G}}var ul=/\x1b(?:\[[0-?]*[ -/]*[@-~]?|\][^\x07\x1b]*(?:\x07|\x1b\\)?|[PX^_][^\x1b]*(?:\x1b\\)?|[\x20-\x7e]?)|\x9b[0-?]*[ -/]*[@-~]?/g,ml=/[\x00-\x08\x0b-\x1f\x7f-\x9f]/g,fl=/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g,gl=/(?<![\p{Extended_Pictographic}\p{Emoji_Modifier}\uFE0F])\u200D|\u200D(?!\p{Extended_Pictographic})|[^\P{Cf}\u200D]/gu,hl=/[\u2028\u2029]/g;function i(H,U={}){return H.replace(ul,"").replace(U.carriageReturn?fl:ml,"").replace(gl,"").replace(hl,`
6
- `)}var F=1,he=(H,U)=>({schemaVersion:1,command:H,data:U}),wn=(H,U)=>({schemaVersion:1,command:H,error:U});function ge(H){return`${JSON.stringify(H,null,2)}
7
- `}function Ae(H){let U=Math.max(0,...H.map(([G])=>G.length));return H.map(([G,B])=>`${G.padEnd(U)} ${B}`).join(`
8
- `)}function nt(H,U){let G=H.map((W,z)=>Math.max(W.length,...U.map((J)=>(J[z]??"").length))),B=(W)=>W.map((z,J)=>z.padEnd(G[J])).join(" ").trimEnd();return[B(H),B(G.map((W)=>"-".repeat(W))),...U.map(B)].join(`
9
- `)}import{statSync as vd}from"node:fs";import{dirname as Bi,resolve as Wi}from"node:path";import{closeSync as Zr,constants as vn,existsSync as Xn,fsyncSync as ui,lstatSync as Qr,mkdirSync as yl,openSync as mi,readFileSync as fi,renameSync as wl,statSync as gi,unlinkSync as hi,writeFileSync as vl}from"node:fs";import{homedir as bl}from"node:os";import{dirname as kl,join as eo}from"node:path";var It="https://server.hlix.ai";function Ze(H=process.env){let U=H.HLIX_CONFIG_HOME??H.XDG_CONFIG_HOME??eo(bl(),".config");return eo(U,"hlix","credentials.json")}function yi(H=process.env){let U=H.HLIX_API_KEY;if(!U&&H.HLIX_SESSION_TOKEN)return{baseUrl:H.HLIX_BASE_URL??It,apiKey:"",sessionToken:H.HLIX_SESSION_TOKEN,...H.HLIX_WORKSPACE_ID?{organizationId:H.HLIX_WORKSPACE_ID}:{}};if(U)return{baseUrl:H.HLIX_BASE_URL??It,apiKey:U,...H.HLIX_WORKSPACE_ID?{organizationId:H.HLIX_WORKSPACE_ID}:{}};try{let G=JSON.parse(fi(Ze(H),"utf8"));return G.apiKey&&G.baseUrl?G:null}catch{return null}}function wi(H=process.env){let U=Ze(H);return Xn(U)?U:null}function to(H=process.env){let U=Ze(H);if(!Xn(U))return{path:U,removed:!1,reason:"absent"};let G=Qr(U);if(G.isSymbolicLink()||!G.isFile())throw Error("Refusing to remove a credential path that is not a regular file.");let B=process.getuid?.();if(B!==void 0&&gi(U).uid!==B)throw Error("Refusing to remove a credential file owned by another user.");let W;try{W=JSON.parse(fi(U,"utf8"))}catch{W=null}let z=W;if(!z||typeof z.apiKey!=="string"||typeof z.baseUrl!=="string")throw Error(`Refusing to remove ${U}: it is not a credential written by this CLI.`);return hi(U),{path:U,removed:!0,reason:"removed"}}function vi(H,U=process.env){let G=Ze(U),B=kl(G);if(yl(B,{recursive:!0,mode:448}),Qr(B).isSymbolicLink())throw Error("Refusing to write credentials through a symlinked directory.");if(Xn(G)){let J=Qr(G);if(J.isSymbolicLink()||!J.isFile())throw Error("Refusing to replace a credential path that is not a regular file.");let K=process.getuid?.();if(K!==void 0&&gi(G).uid!==K)throw Error("Refusing to replace a credential file owned by another user.")}let W=eo(B,`.credentials.${process.pid}.${crypto.randomUUID()}.tmp`),z;try{z=mi(W,vn.O_WRONLY|vn.O_CREAT|vn.O_EXCL|vn.O_NOFOLLOW,384),vl(z,`${JSON.stringify(H,null,2)}
10
- `,"utf8"),ui(z),Zr(z),z=void 0,wl(W,G);let J=mi(B,vn.O_RDONLY);try{try{ui(J)}catch(K){let q=K.code;if(q!=="EINVAL"&&q!=="ENOTSUP")throw K}}finally{Zr(J)}}catch(J){if(z!==void 0)Zr(z);if(Xn(W))hi(W);throw J}return G}import{createHash as dd}from"node:crypto";import{existsSync as ho,lstatSync as pd,readFileSync as Hi,statSync as ud,writeFileSync as yo}from"node:fs";import{readFile as md}from"node:fs/promises";import{join as Tt}from"node:path";import{parseAllDocuments as Xl,stringify as Yl,visit as Ti}from"yaml";import{z as ue}from"zod";var no={"claude-fable-5-1":{provider:"anthropic",contextWindow:1e6,displayName:"Fable 5.1",tier:"frontier"},"claude-opus-5":{provider:"anthropic",contextWindow:1e6,displayName:"Opus 5",tier:"frontier"},"claude-sonnet-5":{provider:"anthropic",contextWindow:1e6,displayName:"Sonnet 5",tier:"primary"},"claude-haiku-4-5":{provider:"anthropic",contextWindow:200000,displayName:"Haiku 4.5",tier:"fast"},"gpt-6-astra":{provider:"openai",contextWindow:1050000,displayName:"GPT-6 Astra",tier:"frontier"},"gpt-5.6-sol":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Sol",tier:"frontier"},"gpt-5.6-terra":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Terra",tier:"primary"},"gpt-5.6-luna":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Luna",tier:"fast"},"jev-latest":{provider:"openrouter",contextWindow:32000,displayName:"Decision Model",tier:"fast",picker:!1},"gemini-3.8-flash":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini 3.8 Flash",tier:"fast"},"gemini-embedding-2":{provider:"google_genai",contextWindow:8192,displayName:"Gemini Embedding 2",tier:"embedding",picker:!1},"grok-4.6":{provider:"openrouter",contextWindow:500000,displayName:"Grok 4.6",tier:"frontier"},"kimi-k3":{provider:"openrouter",contextWindow:1048576,displayName:"Kimi K3",tier:"primary"},"deepseek-v4-pro":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek V4 Pro",tier:"primary"},"deepseek-v4.1-flash":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek V4.1 Flash",tier:"fast"},"glm-5.3":{provider:"openrouter",contextWindow:1310720,displayName:"GLM 5.3",tier:"primary"},"glm-5.3-flash":{provider:"openrouter",contextWindow:1310720,displayName:"GLM 5.3 Flash",tier:"fast"},"qwen3.8-max":{provider:"openrouter",contextWindow:1e6,displayName:"Qwen 3.8 Max",tier:"primary"},"qwen3.8-flash":{provider:"openrouter",contextWindow:1e6,displayName:"Qwen 3.8 Flash",tier:"fast"},auto:{provider:"openrouter",contextWindow:2000000,displayName:"Auto",tier:"primary"},"pareto-code":{provider:"openrouter",contextWindow:2000000,displayName:"Auto for coding",tier:"primary"},"fable-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Fable (Latest)",tier:"frontier"},"opus-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Opus (Latest)",tier:"frontier"},"sonnet-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Sonnet (Latest)",tier:"primary"},"haiku-latest":{provider:"anthropic",contextWindow:200000,displayName:"Claude Haiku (Latest)",tier:"fast"},"gpt-latest":{provider:"openai",contextWindow:1050000,displayName:"GPT Astra (Latest)",tier:"frontier"},"grok-latest":{provider:"openrouter",contextWindow:500000,displayName:"Grok (Latest)",tier:"frontier"},"gemini-pro-latest":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini Pro (Latest)",tier:"primary"},"gemini-flash-latest":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini Flash (Latest)",tier:"fast"},"deepseek-pro-latest":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek Pro (Latest)",tier:"primary"},"deepseek-flash-latest":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek Flash (Latest)",tier:"fast"},"glm-latest":{provider:"openrouter",contextWindow:1310720,displayName:"GLM (Latest)",tier:"primary"},"glm-flash-latest":{provider:"openrouter",contextWindow:1310720,displayName:"GLM Flash (Latest)",tier:"fast"},"kimi-latest":{provider:"openrouter",contextWindow:1048576,displayName:"Kimi (Latest)",tier:"primary"},"whisper-1":{provider:"openrouter",contextWindow:0,displayName:"Whisper 1 (Speech-to-Text)",tier:"media",picker:!1},"voxtral-mini-tts":{provider:"openrouter",contextWindow:4096,displayName:"Voxtral Mini TTS (Text-to-Speech)",tier:"media",picker:!1},"seedream-4-5":{provider:"openrouter",contextWindow:4096,displayName:"Seedream 4.5 (Image)",tier:"media",picker:!1},"veo-3-1":{provider:"openrouter",contextWindow:0,displayName:"Veo 3.1 (Video)",tier:"media",picker:!1}},ro={"claude-code":"claude-sonnet-4-5",codex:"gpt-5.4"};var fg=Object.keys(no);var Sl={"jev-latest":"openrouter/~typesafe/jev-latest","claude-fable-5-1":"openrouter/anthropic/claude-fable-5.1","claude-opus-5":"openrouter/anthropic/claude-opus-5","claude-sonnet-5":"openrouter/anthropic/claude-sonnet-5","claude-haiku-4-5":"openrouter/anthropic/claude-haiku-4.5","gpt-6-astra":"openrouter/openai/gpt-6-astra","gpt-5.6-sol":"openrouter/openai/gpt-5.6-sol","gpt-5.6-terra":"openrouter/openai/gpt-5.6-terra","gpt-5.6-luna":"openrouter/openai/gpt-5.6-luna","gemini-3.8-flash":"openrouter/google/gemini-3.8-flash","gemini-embedding-2":"direct:google/gemini-embedding-2","grok-4.6":"openrouter/x-ai/grok-4.6","kimi-k3":"openrouter/moonshotai/kimi-k3","deepseek-v4-pro":"openrouter/deepseek/deepseek-v4-pro","deepseek-v4.1-flash":"openrouter/deepseek/deepseek-v4.1-flash","glm-5.3":"openrouter/z-ai/glm-5.3","glm-5.3-flash":"openrouter/z-ai/glm-5.3-flash","qwen3.8-max":"openrouter/qwen/qwen3.8-max-0902","qwen3.8-flash":"openrouter/qwen/qwen3.8-flash",auto:"openrouter/openrouter/auto","pareto-code":"openrouter/openrouter/pareto-code","fable-latest":"openrouter/~anthropic/claude-fable-latest","opus-latest":"openrouter/~anthropic/claude-opus-latest","sonnet-latest":"openrouter/~anthropic/claude-sonnet-latest","haiku-latest":"openrouter/~anthropic/claude-haiku-latest","gpt-latest":"openrouter/~openai/gpt-astra-latest","grok-latest":"openrouter/~x-ai/grok-latest","gemini-pro-latest":"openrouter/~google/gemini-pro-latest","gemini-flash-latest":"openrouter/~google/gemini-flash-latest","deepseek-pro-latest":"openrouter/~deepseek/deepseek-pro-latest","deepseek-flash-latest":"openrouter/~deepseek/deepseek-flash-latest","glm-latest":"openrouter/~z-ai/glm-latest","glm-flash-latest":"openrouter/~z-ai/glm-flash-latest","kimi-latest":"openrouter/~moonshotai/kimi-latest","whisper-1":"openrouter/openai/whisper-1","voxtral-mini-tts":"openrouter/mistralai/voxtral-mini-tts-2603","seedream-4-5":"openrouter/bytedance-seed/seedream-4.5","veo-3-1":"openrouter/google/veo-3.1"};var f="◆",xl=(()=>{let H={};for(let U of Object.keys(no)){let G=no[U];H[U]=G.displayName,H[Sl[U]]=G.displayName,H[`${G.provider}:${U}`]=G.displayName}return H})();function A(H){if(!H)return H;let G=xl[H]??H.split(/[/:]/).pop()??H;return`${f} ${G}`}var n={"claude-code":{id:"claude-code",localAccount:{command:"claude",args:["auth","status","--json"],fallback:"claude"},execution:{transport:"acp",sandboxKey:"claudeCode",command:"claude-agent-acp",args:[],oneshot:{command:"claude",args:["-p","--output-format","stream-json","--verbose","--dangerously-skip-permissions"],parser:"claude"},install:"npm i -g @agentclientprotocol/claude-agent-acp",auth:{envVars:["ANTHROPIC_API_KEY"]},models:{selection:"agent-config",modelEnv:"ANTHROPIC_MODEL",effort:!1},pricing:{model:ro["claude-code"],input:3,output:15,cachedRead:0.3,cachedWrite:3.75},where:["local","cloud"]},displayName:"Claude Code",description:"Anthropic coding CLI. Flagship, always installed.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:["ANTHROPIC_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0},"openai-agents":{id:"openai-agents",displayName:"OpenAI Agents SDK",description:"Model-agnostic agent SDK. Not yet available for running tasks.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:[],anyOf:["OPENAI_API_KEY","ANTHROPIC_API_KEY","GOOGLE_API_KEY","OPENROUTER_API_KEY"]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1},codex:{id:"codex",localAccount:{command:"codex",args:["login","status"],fallback:"codex"},execution:{transport:"acp",sandboxKey:"codex",command:"codex-acp",args:[],oneshot:{command:"codex",args:["exec","--json","--dangerously-bypass-approvals-and-sandbox","-"],parser:"codex"},env:{NO_BROWSER:"1"},install:"npm i -g @agentclientprotocol/codex-acp",auth:{envVars:["OPENAI_API_KEY"],method:"api-key"},models:{selection:"agent-config",modelEnv:"CODEX_MODEL",effort:!1},pricing:{model:ro.codex,input:2.5,output:15,cachedRead:0.25,cachedWrite:2.5},where:["local","cloud"]},displayName:"Codex",description:"OpenAI coding CLI. Installed on demand.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:["OPENAI_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0},aider:{id:"aider",localAccount:{command:"aider"},displayName:"Aider",description:"Model-agnostic coding CLI. Not yet available for running tasks.",driverKind:"external-acp",capabilities:["structured-result","model-select"],credentials:{required:[],anyOf:["OPENAI_API_KEY","ANTHROPIC_API_KEY","GOOGLE_API_KEY","OPENROUTER_API_KEY"]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1},gemini:{id:"gemini",localAccount:{command:"gemini",fallback:"gemini"},displayName:"Gemini CLI",localOnly:!0,description:"Verified local ACP adapter. Cloud provisioning is not enabled.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1,execution:{transport:"acp",sandboxKey:"gemini",command:"gemini",args:["--acp"],install:"npm i -g @google/gemini-cli",auth:{envVars:["GEMINI_API_KEY"],method:"gemini-api-key"},models:{selection:"agent-config",effort:!1},pricing:null,where:["local"]}},opencode:{id:"opencode",localAccount:{command:"opencode",args:["auth","list"]},displayName:"OpenCode",description:"SST's open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{localAvailable:!1,transport:"acp",sandboxKey:"opencode",command:"opencode",args:["acp"],install:"npm i -g opencode-ai",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["local","cloud"]}},goose:{id:"goose",localAccount:{command:"goose",fallback:"goose"},displayName:"Goose",description:"Block's open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{transport:"acp",sandboxKey:"goose",command:"goose",args:["acp"],install:"brew install block-goose-cli",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["local","cloud"]}},"qwen-code":{id:"qwen-code",displayName:"Qwen Code",description:"Qwen's open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{localAvailable:!1,transport:"acp",sandboxKey:"qwenCode",command:"qwen",args:["--acp","--auth-type","openai","--approval-mode","yolo"],install:"npm i -g @qwen-code/qwen-code",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["cloud"]}},pi:{id:"pi",displayName:"Pi",description:"Minimal open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{localAvailable:!1,transport:"acp",sandboxKey:"pi",command:"pi-acp",args:[],install:"npm i -g pi-acp @earendil-works/pi-coding-agent",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["cloud"]}},hlix:{id:"hlix",displayName:"Hlix",description:"Our own coding agent, built into hlix and run by the platform.",driverKind:"native",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"native-runner",version:1},modelSupport:{selection:"orchestration",effort:!1},available:!0}},Yn=Object.keys(n).filter((H)=>!("localOnly"in n[H])),oo=Object.values(n).filter((H)=>!("localOnly"in H)),yg=oo.filter(({driverKind:H})=>H==="external-acp").map(({id:H})=>H),jl=oo.filter(({available:H,driverKind:U})=>H&&U==="external-acp"),bi=jl.map(({id:H})=>H),El=oo.filter(({available:H})=>H),w=El.map(({id:H})=>H),ki="hlix";var h=Object.values(n).filter((H)=>("execution"in H)),l=h.map(({id:H})=>H);var Pl=/^[a-z0-9](?:[a-z0-9_-]{0,18}[a-z0-9])?$/,_l=["main","master","develop","development","dev","staging","production","prod","release","preview","trunk","head"];function Si(H){return Pl.test(H)&&!_l.includes(H)}import{z as Il}from"zod";var xi=Il.enum(["small","standard","large"]);import{z as rt}from"zod";var ji=rt.string().trim().max(200).regex(/^[^<>\x00-\x1f\x7f]*$/),$l=rt.union([rt.literal(""),rt.email().max(254)]).transform((H)=>H.trim()),xg=rt.object({gitName:ji,gitEmail:$l,hlixCoauthor:rt.boolean()}).strict(),Ei=rt.object({name:ji.min(1),email:rt.email().max(254),hlixCoauthor:rt.boolean()}).strict();import{z as Y}from"zod";import{z as je}from"zod";import{z as ot}from"zod";var Pi=ot.discriminatedUnion("phase",[ot.object({designId:ot.string().uuid(),phase:ot.literal("prototype"),revisionId:ot.string().uuid().optional()}),ot.object({designId:ot.string().uuid(),phase:ot.literal("implementation"),revisionId:ot.string().uuid()})]);var _i=je.object({version:je.literal(1),organizationId:je.string().min(1),projectId:je.string().min(1),cycleId:je.string().min(1),taskId:je.string().min(1),source:je.string().nullable(),sourceRevision:je.string().min(1),requestDigest:je.string().regex(/^[a-f0-9]{64}$/),requestRevision:je.number().int().min(1),sourceId:je.string().nullable(),project:je.object({name:je.string(),stack:je.string().nullable(),goal:je.string()}),cycleGoal:je.string(),designWork:Pi.optional(),taskGoal:je.string(),requirements:je.string(),implementationPlan:je.string(),repo:je.object({id:je.string(),owner:je.string().nullable(),name:je.string().nullable(),cloneUrl:je.string().nullable(),ref:je.string()}).nullable(),prerequisite:je.object({applicability:je.enum(["application","tooling","unknown"]),sourceExcerpt:je.string()}).optional(),checks:je.array(je.object({kind:je.enum(["verification","startup"]),required:je.literal(!0),command:je.string().nullable(),executionDigest:je.string().nullable(),port:je.number().int().min(1).max(65535).nullable().optional(),source:je.enum(["repo","project","runtime","candidate-discovery"])})).min(1)});import{z as Cl}from"zod";var so=Cl.string().regex(/^op-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}-(0|[1-9][0-9]*)$/,"Invalid operation id");import{z as Ne}from"zod";var Tl=["queued","building","done","blocked"],Al=["operator","engineer","review","platform"],He={id:64,title:200,description:1000,note:280,feedback:1000,dependsOn:8,commit:40,source:8,updatedAt:40},Ii=100,Rl=He.id+He.title+He.description+He.note+He.feedback+He.dependsOn*He.id+He.commit+He.source+He.updatedAt,st={maxItems:Ii,maxBytes:Ii*(Rl*6+1024)+1024,maxEngineerItems:50,titleChars:He.title,descriptionChars:He.description,feedbackChars:He.feedback,noteChars:He.note,maxDependsOn:He.dependsOn},Zn=/^[\w-]{1,64}$/;var $i=Ne.object({id:Ne.string().regex(Zn),title:Ne.string().min(1).max(st.titleChars),description:Ne.string().max(st.descriptionChars).default(""),status:Ne.enum(Tl),dependsOn:Ne.array(Ne.string().regex(Zn)).max(st.maxDependsOn).default([]),note:Ne.string().max(st.noteChars).default(""),commit:Ne.string().regex(/^[a-f0-9]{40}$/).nullable().default(null),feedback:Ne.string().max(st.feedbackChars).nullable().default(null),source:Ne.enum(Al).default("operator"),updatedAt:Ne.string().max(He.updatedAt).default("")}),Rg=Ne.object({version:Ne.literal(1),cycleId:Ne.string().min(1),tasks:Ne.array($i).max(st.maxItems)}),Ci=$i.partial({description:!0,dependsOn:!0,note:!0,commit:!0,feedback:!0,source:!0,updatedAt:!0}).extend({deleted:Ne.boolean().optional()});var Ol=Y.enum(Yn),Nl=Y.enum(["coder","reviewer","planner","setup"]),ao=Y.enum(bi),io=Y.union([Y.string(),Y.number().transform(String)]),co=Y.object({node:io.optional(),python:io.optional(),bun:io.optional(),playwright:Y.boolean().optional()}).catchall(Y.union([Y.string().min(1).max(200),Y.number().transform(String),Y.boolean()])).refine((H)=>Object.entries(H).every(([U,G])=>U==="playwright"||typeof G==="string"),"Tool versions must be strings"),lo=Y.object({name:Y.enum(["mysql","postgres","redis"]),start:Y.string().max(1e4).optional(),ready:Y.string().max(1e4).optional(),stop:Y.string().max(1e4).optional()}),Jg=Y.object({startedAt:Y.string(),finishedAt:Y.string().optional(),status:Y.enum(["ok","partial"]),steps:Y.array(Y.object({name:Y.string(),status:Y.enum(["ok","fixed-by-override","failed"]),reason:Y.string().optional()}))}),po=Y.object({agents:Y.array(ao).optional(),toolchain:co.optional(),aptPackages:Y.array(Y.string()).optional(),setup:Y.string().optional(),services:Y.array(lo).max(3).optional(),envOverrides:Y.record(Y.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),Y.string().max(1e4)).optional(),verifyCommand:Y.string().max(1e4).optional(),preview:Y.object({command:Y.string().min(1).max(1e4),port:Y.number().int().min(1024).max(65535)}).optional(),deployment:Y.discriminatedUnion("kind",[Y.object({repoId:Y.string().min(1),kind:Y.literal("static"),buildCommand:Y.string().trim().min(1).max(1e4),outDir:Y.string().min(1).max(2000).refine((H)=>/^(?!\/|[A-Za-z]:)(?!.*(?:^|\/)(?:\.\.?|\.env(?:\.[^/]*)?|\.git|\.hlix[^/]*|node_modules)(?:\/|$))[^\\\x00-\x1f\x7f]+$/i.test(H),"Output must be a public directory inside the repository")}),Y.object({repoId:Y.string().min(1),kind:Y.literal("server"),startCommand:Y.string().trim().min(1).max(1e4)})]).optional(),notes:Y.array(Y.string().max(2000)).max(100).optional(),source:Y.record(Y.string(),Y.enum(["auto","person"])).optional(),hash:Y.string().optional(),imageTag:Y.string().nullable().optional(),linearProjectId:Y.string().optional(),linearTeamId:Y.string().optional()}).partial(),Kg=Y.object({owner:Y.string(),name:Y.string(),cloneUrl:Y.string(),defaultBranch:Y.string()}),Fl=Y.object({key:Y.string(),cloneUrl:Y.string(),owner:Y.string().nullable(),name:Y.string().nullable(),defaultBranch:Y.string(),setupCommand:Y.string().nullable().optional(),verifyCommand:Y.string().nullable().optional()}),Ll=Y.object({system:Y.boolean().optional(),name:Y.string(),skillSlugs:Y.array(Y.string()),agentSlugs:Y.array(Y.string())}),Hl=Y.object({path:Y.string(),content:Y.string(),executable:Y.boolean().optional(),encoding:Y.enum(["utf8","base64"]).optional()}).refine((H)=>H.encoding!=="base64"||H.content.length%4===0&&/^[A-Za-z0-9+/]*={0,2}$/.test(H.content),{message:"Base64 file content must use valid padded base64",path:["content"]}),Ml=Y.object({vars:Y.record(Y.string(),Y.string()).default({}),files:Y.array(Hl).optional(),skills:Y.array(Y.string()).optional(),mcpServers:Y.array(Y.unknown()).optional(),managedPaths:Y.array(Y.string().refine((H)=>H.length>0&&H===H.normalize("NFC")&&!H.startsWith("/")&&!H.includes("\\")&&!/[\u0000-\u001f\u007f]/.test(H)&&H.split("/").every((U)=>U&&U!=="."&&U!==".."),"managed path must be a canonical project-relative path")).optional()}),Dl=Y.object({path:Y.string(),kind:Y.enum(["dotenv","credential","detected-content"]),contentBase64:Y.string(),size:Y.number().int().nonnegative(),sha256:Y.string().regex(/^[0-9a-f]{64}$/)}),Ul=Y.object({mode:Y.enum(["managed","api_key","subscription"]),accountId:Y.string().min(1).max(200).nullable(),nativeModel:Y.string().trim().min(1).max(200).nullable()}).strict().refine((H)=>H.mode!=="managed"||H.accountId===null&&H.nativeModel===null,{message:"Managed funding cannot select an external account or native model"}),Gl=Y.object({attemptId:Y.string().uuid(),sequence:Y.number().int().min(1).max(2147483647),tokensIn:Y.number().int().min(0).max(2147483647).optional(),tokensOut:Y.number().int().min(0).max(2147483647).optional(),costUsd:Y.number().finite().min(0).max(1e6).optional(),completeness:Y.enum(["partial","complete","unknown"]),model:Y.string().max(200).optional()}).strict().refine((H)=>H.completeness!=="complete"||H.tokensIn!==void 0&&H.tokensOut!==void 0,{message:"Complete native usage requires both token totals"}),Bl=Y.object({path:Y.string().min(1).max(4096),change:Y.enum(["add","modify","delete"]),mode:Y.enum(["file","executable","symlink"]).optional(),content:Y.string().max(16777216).optional()}).strict(),Wl=Y.object({revision:Y.number().int().positive(),sha:Y.string().regex(/^[a-f0-9]{40}$/),overlay:Y.array(Bl).max(5000),packet:Y.string().max(200000)}).strict(),zl=Y.object({commitAttribution:Ei.optional(),taskId:Y.string(),cycleId:Y.string(),threadId:Y.string(),organizationId:Y.string().optional(),projectId:Y.string().optional(),description:Y.string(),acceptedScope:_i.optional(),baseSha:Y.string().regex(/^[a-f0-9]{40}$/).optional(),reviewFeedback:Y.string().optional(),iteration:Y.number().default(0),operationId:so.optional(),repo:Fl,branch:Y.string(),baseBranch:Y.string(),gitToken:Y.string().optional(),secrets:Y.record(Y.string(),Y.string()),packs:Y.array(Ll),systemPrompt:Y.string().optional(),timeoutSeconds:Y.number().default(1800),funding:Ul.optional(),nativeAttemptId:Y.string().uuid().optional(),agentEnv:Y.record(Y.string(),Y.string()).optional(),agent:Ol.default(ki),model:Y.string().min(1).optional(),effort:Y.enum(["low","medium","high"]).optional(),role:Nl.optional(),resultPath:Y.string().optional(),answerPrompt:Y.string().min(1).optional(),startupCommand:Y.string().nullable().optional(),startupPort:Y.number().int().min(1).max(65535).nullable().optional(),projectRuntime:po.optional(),preparedEnvironment:Y.string().optional(),environment:Ml.optional(),protectedFiles:Y.array(Dl).optional(),checklist:Y.array(Ci).max(st.maxItems).optional(),checklistRemoved:Y.array(Y.string().regex(Zn)).max(st.maxItems*2).optional(),continuation:Wl.optional()}),qg=Y.enum(["acp"]),Vg=Y.enum(["builder","desktop","e2e"]),Xg=Y.object({batchId:Y.string(),tasks:Y.array(zl).min(1).max(20)}),Jl=Y.object({inputTokens:Y.number(),outputTokens:Y.number(),costUsd:Y.number().optional()}),Kl=Y.object({status:Y.enum(["passed","failed","skipped"]),commandDigest:Y.string().regex(/^[a-f0-9]{64}$/).optional(),candidateRevision:Y.string().regex(/^[a-f0-9]{40,64}$/).optional(),scopeRevision:Y.string(),source:Y.enum(["configured","candidate-discovery"]),port:Y.number().int().min(1).max(65535).nullable()}),ql=Y.object({startup:Kl.optional(),status:Y.enum(["passed","failed","skipped"]),commandDigest:Y.string().regex(/^[a-f0-9]{64}$/).optional(),scopeRevision:Y.string(),candidateRevision:Y.string().regex(/^[a-f0-9]{40,64}$/).optional()}),Vl=["succeeded","failed","incomplete"],Yg=Y.object({taskId:Y.string(),status:Y.enum(["success","failed"]),checkEvidence:ql.optional(),baseSha:Y.string().regex(/^[a-f0-9]{40}$/).optional(),preCodingSha:Y.string().regex(/^[a-f0-9]{40}$/).optional(),cost:Jl.optional(),model:Y.string().optional(),error:Y.string().optional(),answer:Y.string().optional(),nativeUsage:Gl.optional(),failureKind:Y.enum(["auth","usage_limit"]).optional(),resetsAt:Y.string().datetime().optional(),rateLimits:Y.array(Y.object({window:Y.string(),usedPercent:Y.number().min(0).max(100),resetsAt:Y.string().optional()})).optional(),outcome:Y.enum(Vl).optional()});var Zl=new Set([5901,6080,22222,22223]),mo=ue.number().int().min(1024).max(65535).refine((H)=>!Zl.has(H),{message:"That port is reserved by the environment's terminal or desktop"}),$t=ue.string().min(1).max(1e4),uo=ue.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),Ql=ue.union([ue.object({run:$t}).strict(),ue.object({workflow:ue.string().min(1).max(40)}).strict(),ue.object({wait:ue.object({port:mo}).strict()}).strict()]),ed=ue.object({mode:ue.enum(["sequential","parallel"]),steps:ue.array(Ql).min(1).max(50)}).strict(),Ct=ue.object({schema:ue.literal(1),hlix:ue.object({workspace:ue.string().min(1).max(200),project:ue.string().min(1).max(200).optional(),api:ue.string().url().max(300).optional()}).strict().optional(),project:ue.object({name:ue.string().min(1).max(100).optional(),brief:ue.string().max(5000).optional(),stack:ue.string().min(1).max(200).optional(),branchPrefix:ue.string().refine(Si,"Use a branch prefix of letters, digits, _ and -, up to 20 characters").optional()}).strict().optional(),coder:ue.object({harness:ue.enum(Yn).optional(),model:ue.string().min(1).max(200).optional(),memoryTokens:ue.number().int().min(1).max(2000000).optional(),yolo:ue.boolean().optional()}).strict().optional(),machine:ue.object({size:xi.optional(),toolchain:co.optional(),apt:ue.array(ue.string().min(1).max(200)).max(64).optional(),services:ue.array(lo).max(3).optional(),setup:$t.optional()}).strict().optional(),workflows:ue.record(ue.string().min(1).max(40),ed).optional(),ports:ue.array(ue.object({name:ue.string().min(1).max(40),port:mo,primary:ue.boolean().optional()}).strict()).max(10).optional(),commands:ue.object({verify:$t.optional(),preview:ue.object({command:$t,port:mo}).strict().optional(),deploy:ue.discriminatedUnion("kind",[ue.object({kind:ue.literal("server"),start:$t}).strict(),ue.object({kind:ue.literal("static"),build:$t,outDir:ue.string().min(1).max(2000)}).strict()]).optional()}).strict().optional(),env:ue.object({required:ue.array(uo).max(200).optional(),public:ue.record(uo,ue.string().max(1e4)).optional()}).strict().optional(),team:ue.object({agents:ue.array(ao).max(8).optional(),notes:ue.array(ue.string().max(2000)).max(100).optional()}).strict().optional(),intake:ue.object({github:ue.boolean().optional(),linear:ue.boolean().optional()}).strict().optional(),local:ue.object({runtime:ue.enum(["cloud","local","docker"]).optional(),image:ue.string().min(1).max(300).optional(),setup:$t.optional()}).strict().optional(),providers:ue.array(ue.object({name:ue.string().min(1).max(80),url:ue.string().url().max(300),models:ue.array(ue.string().min(1).max(200)).min(1).max(100),apiKeyEnv:uo.optional(),apiKey:ue.string().min(1).max(2000).optional()}).strict()).max(20).optional()}).strict(),td=`# Project setup for Hlix.
11
- # Commit this file. Secret values belong in the environment, not here.
12
- `,fo="https://server.hlix.ai";function tr(H){return H.replace(/\/+$/,"")===fo}function go(H){if(!H||tr(H))return;return H}function Kt(H){if(H.length>262144)return{ok:!1,issues:[{path:"(file)",message:"hlix.yml is over 256 KB."}]};let U;try{U=Xl(H,{uniqueKeys:!0})}catch(J){return{ok:!1,issues:[{path:"(file)",message:J instanceof Error?J.message:"Could not read YAML."}]}}if(U.length!==1)return{ok:!1,issues:[{path:"(file)",message:"hlix.yml must contain one document."}]};let G=U[0];if(G.errors.length)return{ok:!1,issues:G.errors.map((J)=>({path:"(file)",message:J.message}))};let B=!1;if(Ti(G,{Alias(){return B=!0,Ti.BREAK}}),B)return{ok:!1,issues:[{path:"(file)",message:"YAML aliases are not allowed."}]};let W=Ct.safeParse(G.toJS());if(!W.success)return{ok:!1,issues:id(W.error)};let z=Ri(W.data);if(z.length)return{ok:!1,issues:z};return{ok:!0,file:W.data}}function Ai(H,U){let G=Ct.parse(Oi(H,U)),B=Ri(G);if(B.length)throw Error(B.map((W)=>`${W.path}: ${W.message}`).join("; "));return G}function gt(H){let U=H.machine?.setup??bn(H,"setup",[]),G=H.commands?.verify??bn(H,"verify",[]),B=H.commands?.preview??rd(H),W=po.parse({agents:H.team?.agents,toolchain:H.machine?.toolchain,aptPackages:H.machine?.apt,setup:U,services:H.machine?.services,envOverrides:H.env?.public,verifyCommand:G,preview:B,notes:H.team?.notes}),z=H.intake&&(H.intake.github!==void 0||H.intake.linear!==void 0)?{github:H.intake.github,linear:H.intake.linear}:void 0;return{name:H.project?.name,stack:H.project?.stack,brief:H.project?.brief,branchPrefix:H.project?.branchPrefix,sandboxSize:H.machine?.size,verifyCommand:G,previewCommand:B?.command,previewPort:B?.port,intake:nd(z),requiredEnv:H.env?.required??[],runtime:W,binding:{workspaceId:H.hlix?.workspace,projectId:H.hlix?.project,apiUrl:H.hlix?.api,harness:H.coder?.harness,model:H.coder?.model,memoryTokens:H.coder?.memoryTokens===void 0?void 0:String(H.coder.memoryTokens),yolo:H.coder?.yolo===void 0?void 0:H.coder.yolo?"true":"false",sandbox:H.local?.runtime,dockerImage:H.local?.image}}}function nr(H){let U={schema:1};if(H.hlix){let G=go(H.hlix.api);U.hlix={workspace:H.hlix.workspace,...G?{api:G}:{},...H.hlix.project?{project:H.hlix.project}:{}}}if(H.name||H.stack)U.project={name:H.name,stack:H.stack};if(H.setup)U.machine={setup:H.setup};if(H.verify||H.previewCommand&&H.previewPort)U.commands={verify:H.verify,preview:H.previewCommand&&H.previewPort?{command:H.previewCommand,port:H.previewPort}:void 0};if(H.requiredEnv?.length)U.env={required:H.requiredEnv};return Ct.parse(er(U))}function kn(H,U=td){let G=Yl(er(H),{lineWidth:0}).trimEnd();return`${U}${G}
13
- `}function nd(H){if(!H)return;let U={};if(H.github!==void 0)U.github=H.github;if(H.linear!==void 0)U.linear=H.linear;return Object.keys(U).length?U:void 0}function rd(H){let U=bn(H,"preview",[]),G=H.ports?.find((B)=>B.primary)?.port??H.ports?.[0]?.port;if(!U||G===void 0)return;return{command:U,port:G}}function od(H){return`timeout 60 bash -c 'until (echo >/dev/tcp/127.0.0.1/${H}) 2>/dev/null; do sleep 0.25; done'`}function sd(H){let U=H.map((W,z)=>`( ${W} ) & p${z}=$!`),G=H.map((W,z)=>`wait $p${z}; s${z}=$?`),B=H.map((W,z)=>`s${z}`).join("||");return`( ${U.join("; ")}; ${G.join("; ")}; exit $(( ${B} )) )`}function bn(H,U,G){if(G.includes(U))throw Error(`workflows.${U} refers to itself.`);if(G.length>=3)throw Error(`workflows.${U} is nested more than 3 levels deep.`);let B=H.workflows?.[U];if(!B){if(G.length===0)return;throw Error(`workflows.${U} does not exist.`)}let W=[];for(let z of B.steps)if("run"in z)W.push(z.run);else if("workflow"in z){let J=bn(H,z.workflow,[...G,U]);if(J)W.push(J)}else W.push(od(z.wait.port));if(!W.length)return;return B.mode==="parallel"?sd(W):W.join(" && ")}function Ri(H){try{for(let U of Object.keys(H.workflows??{}))bn(H,U,[])}catch(U){return[{path:"workflows",message:U instanceof Error?U.message:"Invalid workflow."}]}return[]}function id(H){return H.issues.map((U)=>{let G="keys"in U&&Array.isArray(U.keys)?U.keys.map(String):[];return{path:[...U.path.map(String),...G].join(".")||"(file)",message:U.message}})}function Qn(H){return Boolean(H)&&typeof H==="object"&&!Array.isArray(H)}function Oi(H,U){if(Array.isArray(U)||!Qn(U)||!Qn(H))return U;let G={...H};for(let[B,W]of Object.entries(U))G[B]=B in H?Oi(H[B],W):W;return G}function er(H){if(Array.isArray(H))return H.map(er);if(!Qn(H))return H;let U={};for(let[G,B]of Object.entries(H)){if(B===void 0)continue;let W=er(B);if(Qn(W)&&Object.keys(W).length===0)continue;U[G]=W}return U}var Ni=["hlix.yml","hlix.yaml"],qt=["hlix.local.yml","hlix.local.yaml"];var ad=/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|npm_[A-Za-z0-9]{30,}|gh[opusr]_[A-Za-z0-9_]{30,}|glpat-[A-Za-z0-9_-]{20,}|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z_-]{30,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}|xox[baprs]-[A-Za-z0-9-]{20,}/,cd=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,ld=/(?:^|[,{\s])(?:["']?(?:api[_-]?key|access[_-]?token|auth(?:orization)?|client[_-]?secret|password|private[_-]?key|secret|token)["']?)\s*(?::|=)\s*["']?(?!\$\{|process\.env|import\.meta\.env|os\.(?:getenv|environ\.get)|<|replace|example|changeme)[A-Za-z0-9+/_=.:-]{12,}/im;function Sn(H,U){return ad.test(U)||cd.test(H)&&ld.test(U)}var fd=qt;function Qe(H){let U=Fi(H,Ni),G=Fi(H,qt);if(U&&"error"in U)return{file:null,base:null,local:null,baseName:null,error:U.error};if(G&&"error"in G)return{file:null,base:null,local:null,baseName:null,error:G.error};let B=U?.name??null,W=G?.name??null,z=B?Li(H,B):{file:null,error:null},J=W?Li(H,W):{file:null,error:null},K=z.error??J.error;if(K||!z.file)return{file:z.file,base:z.file,local:J.file,baseName:B,error:K};try{return{file:J.file?Ai(z.file,J.file):z.file,base:z.file,local:J.file,baseName:B,error:null}}catch(q){let X=q instanceof Error?q.message:"Could not merge hlix.local.yml.";return{file:null,base:z.file,local:J.file,baseName:B,error:X}}}function Vt(H){if(!H)return null;let U=gt(H).binding;if(!U.workspaceId)return null;return{schemaVersion:1,workspaceId:U.workspaceId,apiUrl:U.apiUrl??fo,projectId:U.projectId,sandbox:U.sandbox,dockerImage:U.dockerImage,memoryTokens:U.memoryTokens,harness:yd(U.harness),model:U.model,yolo:U.yolo}}function Mi(H,U){sr(H,(G)=>{let B={...G.local},W=!1;if(!G.local?.runtime&&U.sandbox)B.runtime=U.sandbox,W=!0;if(!G.local?.image&&U.dockerImage)B.image=U.dockerImage,W=!0;let z={...G.coder},J=!1;if(!G.coder?.harness&&U.harness)z.harness=U.harness,J=!0;if(!G.coder?.model&&U.model)z.model=U.model,J=!0;if(G.coder?.memoryTokens===void 0&&U.memoryTokens){let K=Number(U.memoryTokens);if(Number.isInteger(K)&&K>=20000&&K<=2000000)z.memoryTokens=K,J=!0}if(G.coder?.yolo===void 0&&(U.yolo==="true"||U.yolo==="false"))z.yolo=U.yolo==="true",J=!0;if(!W&&!J)return G;return{...G,...W?{local:B}:{},...J?{coder:z}:{}}})}function Di(H){if(H.error)return H.error;if(H.baseName)return H.baseName;return"will write hlix.yml"}async function rr(H){let U=Tt(H,".gitignore"),G=ho(U)?await md(U,"utf8"):"",B=fd.filter((z)=>!wd(G,z));if(!B.length)return;let W=G.length===0||G.endsWith(`
14
- `)?"":`
15
- `;wo(U),yo(U,`${G}${W}${B.join(`
16
- `)}
17
- `,{mode:420})}function or(H,U){let G=Qe(H);if(G.error)throw Error(G.error);if(G.base)return{written:!1,file:G.base};let B=nr(U),W=Tt(H,"hlix.yml");return wo(W),yo(W,kn(B),{mode:420}),{written:!0,file:B}}function sr(H,U){let G=Qe(H);if(G.error)throw Error(G.error);let B=G.base??{schema:1},W=U(B),z=G.baseName??"hlix.yml",J=Tt(H,z);if(G.base&&W===B)return{path:J,name:z,file:B,changed:!1};let K=kn(W),q=Kt(K);if(!q.ok)throw Error(q.issues.map((X)=>`${X.path}: ${X.message}`).join("; "));return wo(J),yo(J,K,{mode:420}),{path:J,name:z,file:q.file,changed:!0}}function ir(H,U){let G=sr(H,(B)=>{let W=U.project??B.hlix?.project,z=B.hlix?.api&&tr(B.hlix.api)&&tr(U.api)?B.hlix.api:go(U.api),J={workspace:U.workspace,...z?{api:z}:{},...W?{project:W}:{}};if(B.hlix?.workspace===J.workspace&&B.hlix?.api===J.api&&B.hlix?.project===J.project)return B;return{...B,hlix:J}});return{path:G.path,name:G.name,changed:G.changed}}function Ui(H){let U=Qe(H);if(U.error||!U.baseName)return null;return Tt(H,U.baseName)}var gd=new Set([5901,6080,22222,22223]);function xn(H,U,G){let B=H.install.map((J)=>J.trim()).filter(Boolean).join(`
18
- `),W=H.ports.find((J)=>J.port>=1024&&J.port<=65535&&!gd.has(J.port))?.port,z=H.start&&W?H.start:void 0;return{name:G?.name,stack:G?.stack,setup:B||void 0,previewCommand:z,previewPort:z?W:void 0,requiredEnv:H.requiredSecretKeys,hlix:U}}function ar(H,U){let G=Tt(H.root,U);if(!ho(G))return;let B=Hi(G),W=ud(G),z=dd("sha256").update(B).digest("hex"),J=B.toString("utf8"),K=H.protectedFiles.find((X)=>X.path===U);if(K||Sn(U,J)){let X=B.toString("base64");if(K)K.contentBase64=X;else H.protectedFiles.push({path:U,kind:"detected-content",contentBase64:X});let V=K&&(K.kind==="dotenv"||K.kind==="credential"||K.kind==="detected-content")?K.kind:"detected-content",Z=H.manifest.secretFiles.find((ne)=>ne.path===U);if(Z)Z.size=W.size,Z.sha256=z;else H.manifest.secretFiles.push({path:U,kind:V,keys:[],size:W.size,sha256:z});let Q=H.manifest.files.findIndex((ne)=>ne.path===U);if(Q>=0){let ne=H.manifest.files[Q];H.manifest.totals.files-=1,H.manifest.totals.bytes-=ne.size,H.manifest.files.splice(Q,1)}return}let q=H.manifest.files.find((X)=>X.path===U);if(!q){H.manifest.files.push({path:U,size:W.size,sha256:z,tracked:!1,executable:!1}),H.manifest.totals.files+=1,H.manifest.totals.bytes+=W.size;return}H.manifest.totals.bytes+=W.size-q.size,q.size=W.size,q.sha256=z}function wo(H){try{if(pd(H).isSymbolicLink())throw Error(`Refusing to write through a symlink: ${H}`)}catch(U){if(U.code==="ENOENT")return;throw U}}var hd=["claude-code","codex","opencode","goose","qwen-code","pi","hlix"];function Fi(H,U){let G=U.filter((z)=>ho(Tt(H,z))),[B,W]=G;if(B&&W)return{error:`${G.join(" and ")} both exist. Keep one.`};return B?{name:B}:null}function yd(H){return hd.find((U)=>U===H)}function Li(H,U){let G=Kt(Hi(Tt(H,U),"utf8"));if(!G.ok){let B=G.issues.map((W)=>`${W.path}: ${W.message}`).join("; ");return{file:null,error:`${U} ${B}`}}return{file:G.file,error:null}}function wd(H,U){return H.split(/\r?\n/).some((G)=>G.trim()===U)}function y(H){if(!H.credential)return null;if(H.credentialSource==="session")return"session (desktop)";if(H.credentialSource==="env")return"environment (HLIX_API_KEY)";return`file (${H.credentialPath})`}function t(H){let U=Wi(H);for(;;){let G=Qe(U);if(G.error)throw new e("invalid_project_file",G.error);let B=Vt(G.file);if(B?.workspaceId&&B.apiUrl)return{root:U,config:B};let W=Bi(U);if(W===U)return null;U=W}}function vo(H){let U=Wi(H);for(;;){let G=Qe(U);if(G.error)throw new e("invalid_project_file",G.error);if(G.base)return{root:U,loaded:G};let B=Bi(U);if(B===U)return null;U=B}}function zi(H){try{return vd(H).isDirectory()}catch{return!1}}function cr(H){if(typeof H!=="string")return;let U=H.trim();return U?U:void 0}var Gi=(H,U)=>H.replace(/\/+$/,"")===U.replace(/\/+$/,"");function o(H){let{env:U,flags:G,cwd:B}=H,W=t(B),z=yi(U),J=z?U.HLIX_API_KEY?"env":U.HLIX_SESSION_TOKEN?"session":"file":null,K=J==="file"?z:null,q=cr(G["base-url"]),X=cr(U.HLIX_BASE_URL),V=cr(G.workspace),Z=cr(U.HLIX_WORKSPACE_ID),Q=q??X??W?.config.apiUrl??K?.baseUrl??It,ne=q?"flag":X?"env":W?.config.apiUrl?"project":K?.baseUrl?"credential":"default",ce=V??Z??W?.config.workspaceId??K?.organizationId??null,te=V?"flag":Z?"env":W?.config.workspaceId?"project":K?.organizationId?"credential":null;return{baseUrl:Q,baseUrlSource:ne,workspaceId:ce,workspaceSource:te,credential:z,credentialSource:J,credentialPath:Ze(U),binding:W,conflict:bd(W,{flagBaseUrl:q,envBaseUrl:X,flagWorkspace:V,envWorkspace:Z})}}function bd(H,U){if(!H)return null;let G=`${H.root} is bound to`,B="Drop the override, or point --cwd at a folder bound to it.";if(U.flagWorkspace&&U.flagWorkspace!==H.config.workspaceId)return`${G} workspace ${H.config.workspaceId}, but --workspace names ${U.flagWorkspace}. ${B}`;if(U.envWorkspace&&U.envWorkspace!==H.config.workspaceId)return`${G} workspace ${H.config.workspaceId}, but HLIX_WORKSPACE_ID names ${U.envWorkspace}. ${B}`;if(U.flagBaseUrl&&!Gi(U.flagBaseUrl,H.config.apiUrl))return`${G} ${H.config.apiUrl}, but --base-url names ${U.flagBaseUrl}. ${B}`;if(U.envBaseUrl&&!Gi(U.envBaseUrl,H.config.apiUrl))return`${G} ${H.config.apiUrl}, but HLIX_BASE_URL names ${U.envBaseUrl}. ${B}`;return null}function bo(H){if(H instanceof e)return{code:H.code,status:null};if(H instanceof zt)return{code:"invalid_request",status:400};if(H instanceof un)return{code:"bad_request",status:400};if(H instanceof mn)return{code:"unauthenticated",status:401};if(H instanceof fn)return{code:"forbidden",status:403};if(H instanceof St)return{code:"not_found",status:404};if(H instanceof xt)return{code:"conflict",status:409};if(H instanceof jt)return{code:"rate_limited",status:429};if(H instanceof gn)return{code:"not_implemented",status:501};if(H instanceof Et)return{code:"server_error",status:H.status};if(H instanceof mt)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var lr=(H)=>{if(H instanceof zt&&H.issues.length>0){let U=H.issues.map((G)=>{let B=G;return` - ${Array.isArray(B.path)&&B.path.length>0?`${B.path.join(".")}: `:""}${typeof B.message==="string"?B.message:JSON.stringify(G)}`});return`${H.message}
19
- ${U.join(`
20
- `)}`}return H instanceof Error?H.message:String(H)};function r(H,U){let G=o({env:H,flags:U.flags,cwd:U.cwd});if(G.conflict)throw new e("workspace_mismatch",G.conflict);if(!G.credential)throw new e("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");return new Jt({baseUrl:G.baseUrl,credential:G.credential.sessionToken?Mr(G.credential.sessionToken):Wt(G.credential.apiKey),...G.workspaceId?{organizationId:G.workspaceId}:{}})}function Ji(H){let U=Math.max(...H.map((B)=>B.name.length));return`hlix — the hlix control-plane CLI
21
-
22
- Usage:
23
- hlix <command> [options]
24
-
25
- Commands:
26
- ${[` hlix ${"".padEnd(U)} Open Hlix Code (interactive)`,...H.map((B)=>` hlix ${B.name.padEnd(U)} ${B.summary}`)].join(`
27
- `)}
28
-
29
- Options:
30
- --json Machine-readable output (a versioned, stable contract)
31
- --cwd <dir> Operate on another directory instead of the current one
32
- --workspace <id> Workspace to act in, overriding the folder's binding
33
- --base-url <url> API to talk to, overriding the folder's binding
34
- --help Show this help
35
- --version Show the installed CLI version
36
-
37
- Hlix Code (hlix with no command):
38
- --sandbox <choice> cloud (Cloud Machine), docker (Docker container), or local
39
- (local environment); --local is short for --sandbox local
40
- --docker-image <r> image the Docker container runs in
41
- --harness <name> which coder does the work
42
- --project <id> project to act in, when this folder is not bound
43
- -p "<prompt>" one turn, print the answer, exit
44
- --json with -p: one JSON object per event instead of prose
45
- --allow-writes with -p: let the turn change files and run commands
46
- --yolo approve every tool call for the whole session
47
-
48
- A command targets the workspace named by, in order: an explicit flag, the
49
- HLIX_* environment, the nearest hlix.yml, then the stored credential.
50
- Run \`hlix status\` to see which one applied.
51
- `}function qi(H,U){let G=[...Array(U.length+1).keys()];for(let B=1;B<=H.length;B+=1){let W=[B];for(let z=1;z<=U.length;z+=1)W[z]=Math.min(G[z]+1,W[z-1]+1,G[z-1]+(H[B-1]===U[z-1]?0:1));G=W}return G[U.length]}function xd(H,U,G){let B=/Unknown option '--([^'=]+)/.exec(G)?.[1];if(!B)return G;let W=U.findIndex((q)=>q.startsWith("-")),z=W===-1?U:U.slice(0,W),J=new Set(["json","help","version","cwd","workspace","base-url",...dr(H,z)?.command.options??[]]),K=null;for(let q of J){let X=qi(B,q);if(X<=2&&(!K||X<K.distance))K={name:q,distance:X}}return K?`${G}
52
- Did you mean --${K.name}?`:G}function Ki(H,U){let G=new Set;for(let z of H)G.add(z.name),G.add(z.name.split(" ")[0]);let B=null;for(let z of G){let J=qi(U,z);if(J<=2&&(!B||J<B.distance))B={name:z,distance:J}}if(!B)return null;if(H.some((z)=>z.name===B.name))return B.name;let W=H.filter((z)=>z.name.startsWith(`${B.name} `)).sort((z,J)=>z.name.length-J.name.length)[0];return W?W.name:B.name}function dr(H,U){for(let G of[...H].sort((B,W)=>W.name.length-B.name.length)){let B=G.name.split(" ");if(B.every((W,z)=>U[z]===W))return{command:G,rest:U.slice(B.length)}}return null}function jd(H,U,G){let B=xd(H,U,G);if(!/^Unknown option '/.test(G))return B;let W=B.replace(/\. To specify a positional argument[\s\S]*?after '--'[^\n]*/,"."),z=dr(H,U.filter((J)=>!J.startsWith("-")));return z?`${W}
53
-
54
- ${z.command.usage}`:W}async function d(H,U,G){if(U.some((se)=>se==="--api-key"||se.startsWith("--api-key=")))return G.stderr("error: API keys are never accepted as command-line arguments. Run `hlix auth login` and use the hidden prompt.\n"),2;let B;try{B=Sd({args:U,allowPositionals:!0,strict:!0,options:{json:{type:"boolean"},help:{type:"boolean"},version:{type:"boolean"},cwd:{type:"string"},"base-url":{type:"string"},workspace:{type:"string"},"dry-run":{type:"boolean"},"no-connect-origin":{type:"boolean"},attach:{type:"boolean"},print:{type:"boolean"},web:{type:"boolean"},"env-file":{type:"string"},include:{type:"string"},history:{type:"string"},name:{type:"string"},stack:{type:"string"},status:{type:"string"},project:{type:"string"},yes:{type:"boolean"},global:{type:"boolean"},org:{type:"boolean"},title:{type:"string"},description:{type:"string"},force:{type:"boolean"},runtime:{type:"string"},duty:{type:"string"},profile:{type:"string"},server:{type:"string"},"allow-stdio":{type:"boolean"},source:{type:"string"},format:{type:"string"},out:{type:"string"},"from-stdin":{type:"boolean"},once:{type:"boolean"}}})}catch(se){let me=U.includes("--json"),fe=jd(H,U,lr(se));if(G.onFailure?.({code:"invalid_usage",message:fe,status:null}),me)G.stdout(ge(wn("cli",{code:"invalid_usage",message:fe,status:null})));else G.stderr(`${fe}
55
- `);return 2}let W=B.values.json===!0,z=B.positionals;if(B.values.version===!0){let{version:se}=await import("./package-ctda701x.js");return G.stdout(`${se}
56
- `),0}if(z.length===0||B.values.help===!0){let se=dr(H,z);return G.stdout(se?`${se.command.usage}
57
- `:Ji(H)),z.length===0&&B.values.help!==!0?1:0}let J=dr(H,z);if(!J){let se=z.join(" "),me=Ki(H,se)??Ki(H,z[0]),fe=me?`Unknown command: ${se}
58
- Did you mean \`hlix ${me}\`?`:`Unknown command: ${se}`;if(G.onFailure?.({code:"unknown_command",message:fe,status:null}),W)G.stdout(ge(wn(se,{code:"unknown_command",message:fe,status:null})));else G.stderr(`${fe}
59
-
60
- ${Ji(H)}`);return 2}let K=new Set(["json","help","version","cwd","workspace","base-url"]),q=new Set(J.command.options??[]),X=Object.entries(B.values).filter(([se,me])=>me!==void 0&&!K.has(se)&&!q.has(se)).map(([se])=>`--${se}`),V=J.command.args??{min:0,max:0},Z=J.rest.length<V.min?{code:"missing_argument",message:J.command.usage.split(`
61
- `)[0]}:J.rest.length>V.max?{code:"invalid_usage",message:J.command.usage.split(`
62
- `)[0]}:null,Q=typeof B.values.cwd==="string"?B.values.cwd:void 0,ne=kd(Q??"."),ce=Q!==void 0&&!zi(ne)?{code:"invalid_usage",message:`--cwd is not a directory: ${ne}`}:null,te=X.length>0?{code:"invalid_usage",message:`Unsupported option for ${J.command.name}: ${X.join(", ")}`}:ce??Z;if(te){if(G.onFailure?.({...te,status:null}),W)G.stdout(ge(wn(J.command.name,{...te,status:null})));else{let se=J.command.usage.startsWith(te.message)?J.command.usage:`${te.message}
63
-
64
- ${J.command.usage}`;G.stderr(`error: ${se}
65
- `)}return 2}let re=B.values,ae={...G,args:J.rest,json:W,flags:re,cwd:ne,requireClient:(se)=>r(G.env,{cwd:se??ne,flags:re})};try{return await J.command.run(ae)}catch(se){let{code:me,status:fe}=bo(se);if(G.onFailure?.({code:me,message:i(lr(se)),status:fe,...se instanceof e&&se.details!==void 0?{details:se.details}:{}}),W)G.stdout(ge(wn(J.command.name,{code:me,message:lr(se),status:fe})));else if(G.stderr(`error: ${i(lr(se))}
66
- `),process.env.HLIX_DEBUG&&se instanceof Error&&se.stack)G.stderr(`${se.stack}
67
- `);return me==="unauthenticated"||me==="forbidden"?3:1}}async function Ed(H,U,G){let B=U.map((K)=>K.id);if(G){if(!B.includes(G))throw new e("workspace_mismatch",U.length===0?`This key belongs to a user who is not a member of any workspace, including ${G}.`:`This key cannot act in workspace ${G}. Available: ${B.join(", ")}.`);return G}if(U.length===0)throw new e("workspace_required","This key belongs to a user who is not a member of any workspace. Create or join one first.");let W=U[0];if(W&&U.length===1)return H.stderr(`Using your only workspace: ${W.name} (${W.id})
68
- `),W.id;if(H.json||!H.promptChoice)throw new e("missing_argument",`--workspace is required here: this key can act in ${U.length} workspaces. Pass one of: ${B.join(", ")}.`);let z=Math.max(...U.map((K)=>K.name.length));H.stderr(`${U.map((K,q)=>` ${q+1}) ${K.name.padEnd(z)} ${K.slug} ${K.role} ${K.id}`).join(`
69
- `)}
70
- `);let J=await H.promptChoice(`Workspace [1-${U.length}]: `,U.length);return B[J]}var ko={name:"auth login",summary:"Verify and store a credential for this machine",usage:["Usage: hlix auth login [--workspace <id>] [--base-url <url>]","",` --base-url Defaults to ${It}`," --workspace Workspace (organization) id to act in. Optional: the key's"," own workspaces are listed after it is read, and the only"," one is taken automatically.","","The API key is read from a hidden prompt and never accepted as an argument.","For CI, set HLIX_API_KEY and HLIX_WORKSPACE_ID in the environment."].join(`
71
- `),supportsJson:!0,options:["base-url","workspace"],async run(H){let U=typeof H.flags.workspace==="string"?H.flags.workspace:H.env.HLIX_WORKSPACE_ID,G=H.env.HLIX_API_KEY??await H.readSecret?.("Hlix API key: ")??"";if(!G)throw new e("missing_credential","No API key entered. Run from a terminal or set HLIX_API_KEY for CI.");let B=typeof H.flags["base-url"]==="string"?H.flags["base-url"]:H.env.HLIX_BASE_URL??It,W=new URL(B),z=W.hostname==="localhost"||W.hostname==="127.0.0.1"||W.hostname==="::1";if(W.protocol!=="https:"&&!(W.protocol==="http:"&&z))throw new e("invalid_base_url","--base-url must use HTTPS (HTTP is allowed only for localhost).");let J=new Jt({baseUrl:B,credential:Wt(G),retry:{attempts:1}}),K=await Ed(H,await J.workspaces.list(),U);await new Jt({baseUrl:B,credential:Wt(G),organizationId:K,retry:{attempts:1}}).projects.list();let X=vi({baseUrl:B,apiKey:G,organizationId:K},H.env);if(H.json)H.stdout(ge(he(ko.name,{baseUrl:B,organizationId:K,credentialPath:X})));else H.stdout(`Signed in to ${B}
72
- Credential stored at ${X}
73
- `);return 0}},So={name:"auth status",summary:"Show which credential is in use, where it came from, and whether it works",usage:["Usage: hlix auth status [--json]","","Names the SOURCE of the credential — the stored file, HLIX_API_KEY, or the","desktop app's own session when hlix was opened from its Terminal tab — and","verifies it against the API. The credential itself is never printed, not even","a prefix: machine output gets piped into logs."].join(`
74
- `),supportsJson:!0,async run(H){let U=o({env:H.env,flags:H.flags,cwd:H.cwd});if(U.conflict)throw new e("workspace_mismatch",U.conflict);if(!U.credential)throw new e("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");try{await H.requireClient().projects.list()}catch(B){throw H.stderr(`credential from ${U.credentialSource}, workspace ${U.workspaceId??"none"}, api ${U.baseUrl}
75
- `),B}let G={credentialSource:U.credentialSource,credentialPath:U.credentialSource==="file"?U.credentialPath:null,baseUrl:U.baseUrl,baseUrlSource:U.baseUrlSource,workspaceId:U.workspaceId,workspaceSource:U.workspaceSource,valid:!0};if(H.json)return H.stdout(ge(he(So.name,G))),0;return H.stdout(`${Ae([["credential",y(U)??"none"],["api",`${U.baseUrl} (from ${U.baseUrlSource})`],["workspace",U.workspaceId?`${U.workspaceId} (from ${U.workspaceSource})`:"none"],["status","valid"]])}
76
- `),0}},Xt={name:"auth logout",summary:"Remove the stored credential from this machine",usage:["Usage: hlix auth logout [--yes] [--json]","","Removes ~/.config/hlix/credentials.json after confirming. A credential","supplied through HLIX_API_KEY is not removed — unset it in the shell that","set it — and neither is the desktop app's own session; sign out in the app."].join(`
77
- `),supportsJson:!0,options:["yes"],async run(H){let U=o({env:H.env,flags:H.flags,cwd:H.cwd});if(U.credentialSource==="env"||U.credentialSource==="session"){let B=U.credentialSource==="session",W=B?"session":"environment",z=B?"This session belongs to the Hlix desktop app; sign out there to end it.":"HLIX_API_KEY is set in this environment; unset it there to sign out.",J=wi(H.env);if(!J){let q={removed:!1,reason:W,path:null};if(H.json)H.stdout(ge(he(Xt.name,q)));else H.stdout(`${z}
78
- `);return 0}if(H.flags.yes!==!0){let q={removed:!1,reason:W,path:J};if(H.json)H.stdout(ge(he(Xt.name,q)));else H.stdout(`${z}
79
- A stored credential also exists at ${J} — repeat with --yes to remove it.
80
- `);return 0}let K=to(H.env);if(H.json)H.stdout(ge(he(Xt.name,K)));else H.stdout(`Removed ${K.path}
81
- ${B?"The desktop app's session is still in use; sign out there to finish.":"HLIX_API_KEY is still set in this environment; unset it there to finish signing out."}
82
- `);return 0}if(H.flags.yes!==!0&&U.credential){if(H.json||!H.confirm)throw new e("approval_required","Removing the stored credential needs approval. Repeat with `--yes`.");if(!await H.confirm(`Remove the stored credential at ${U.credentialPath}? Signing back in needs the API key again.`))throw new e("cancelled","Logout cancelled.")}let G=to(H.env);if(H.json)H.stdout(ge(he(Xt.name,G)));else H.stdout(G.removed?`Removed ${G.path}
83
- `:`No stored credential at ${G.path}
84
- `);return 0}};import{existsSync as Rd,readFileSync as ta}from"node:fs";import{homedir as na}from"node:os";import{join as ra}from"node:path";import{constants as pr,existsSync as jo,lstatSync as ur,mkdirSync as Xi,openSync as Pd,closeSync as Vi,fsyncSync as _d,readFileSync as Yi,renameSync as Id,unlinkSync as $d,writeFileSync as xo}from"node:fs";import{dirname as Cd,join as Yt,resolve as mr}from"node:path";function Zi(H){if(!jo(H))return;let U=ur(H);if(U.isSymbolicLink()||!U.isFile())throw Error(`Refusing to replace a non-regular Hlix file: ${H}`)}function Eo(H,U){let G=Cd(H);if(Xi(G,{recursive:!0,mode:448}),ur(G).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${G}`);Zi(H);let B=Yt(G,`.hlix-${process.pid}-${crypto.randomUUID()}.tmp`),W;try{W=Pd(B,pr.O_WRONLY|pr.O_CREAT|pr.O_EXCL|pr.O_NOFOLLOW,384),xo(W,U.endsWith(`
85
- `)?U:`${U}
86
- `,"utf8"),_d(W),Vi(W),W=void 0,Id(B,H)}catch(z){if(W!==void 0)Vi(W);if(jo(B))$d(B);throw z}}function Td(H,U){Eo(H,`${JSON.stringify(U,null,2)}
87
- `)}function Ad(H){return Yt(mr(H),".hlix","config.json")}function Qi(H){return Yt(mr(H),".hlix","state.json")}function fr(H){try{let U=JSON.parse(Yi(Ad(H),"utf8"));return U.schemaVersion===1&&U.workspaceId&&U.apiUrl?U:null}catch{return null}}function gr(H){let U=Yt(mr(H),".hlix");if(Xi(U,{recursive:!0,mode:448}),ur(U).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${U}`);let G=Yt(U,".gitignore");if(!jo(G))xo(G,`state.json
88
- `,{mode:420,flag:"wx"});Zi(G);let B=Yt(mr(H),".hlixignore");if(!ur(B,{throwIfNoEntry:!1}))xo(B,`# Additional project-local paths to exclude from Hlix snapshots.
89
- `,{mode:420,flag:"wx"})}function Po(H,U){Td(Qi(H),{...U,snapshotOnly:U.snapshotOnly??a(H)?.snapshotOnly,includedPaths:U.includedPaths??a(H)?.includedPaths})}function a(H){try{let U=JSON.parse(Yi(Qi(H),"utf8"));return U.schemaVersion===1&&U.repoId&&/^[a-f0-9]{40}$/.test(U.commitSha)?U:null}catch{return null}}var _o=20000,Io=2000000;function b(H){if(H===void 0)return;let U=typeof H==="number"?H:Number(H.trim());return Number.isInteger(U)&&U>=_o&&U<=Io?U:void 0}var p=["cloud","docker","local"],u={cloud:"Cloud Machine",docker:"Docker container",local:"local environment"},hr={"claude-code":!0,codex:!0,opencode:!0,goose:!0,"qwen-code":!0,pi:!0,hlix:!0},s=Object.keys(hr),I="hlix",oa={dockerImage:"Docker containers only",harness:"local environments and Docker containers only",memoryTokens:"all execution environments",model:"local environments and Docker containers only",sandbox:"all execution environments",yolo:"all execution environments"},Zt=["dockerImage","harness","memoryTokens","model","sandbox","yolo"],$o=["projectId","workspaceId","apiUrl"],Od=`# Machine-wide setup for Hlix.
90
- # A model server of your own goes under providers. Name its secret with apiKeyEnv.
91
- `;function yr(H=process.env){return ra(H.HLIX_CONFIG_HOME??na(),".hlix","hlix.yml")}function Nd(H){return ra(H.HLIX_CONFIG_HOME??na(),".hlix","config.json")}function Fd(H=process.env){let U=aa(H);return U?Hd(U):null}function v(H,U=process.env){let G=Fd(U),B=vo(H),z=t(H)?.config??null,J=B?.loaded.file?gt(B.loaded.file).binding:null,K={},q={},X=(V)=>{let Z=Ud(J,V),Q=Z!==void 0?Z:z?.[V],ne=G?.[V];if(Q!==void 0)K[V]=Q,q[V]="project";else if(ne!==void 0)K[V]=ne,q[V]="global"};for(let V of Zt)X(V);for(let V of $o){let Z=z?.[V];if(Z!==void 0)K[V]=Z,q[V]="project"}return{merged:K,sources:q,global:G,project:z,paths:{global:yr(U),project:B?Ui(B.root):null},providers:Gd(B?.loaded??null,G?.providers)}}function sa(H){return[...Zt,...$o].map((G)=>({key:G,value:H.merged[G]??null,source:H.sources[G]??"default"}))}function Ld(H,U){if(H==="sandbox"&&!p.includes(U))return`sandbox must be one of ${p.join(", ")}; got "${U}".`;if(H==="harness"&&!s.includes(U))return`harness must be one of ${s.join(", ")}; got "${U}".`;if(H==="model"&&U.trim()==="")return"model must not be empty.";if(H==="memoryTokens"){let G=Number(U.trim());if(!Number.isInteger(G)||G<_o)return`memoryTokens must be a whole number of tokens, at least ${_o}; got "${U}".`;if(G>Io)return`memoryTokens must be at most ${Io}; got "${U}".`}if(H==="dockerImage"&&U.trim()==="")return"dockerImage must not be empty.";if(H==="yolo"&&S(U)===void 0)return`yolo must be true or false; got "${U}".`;return null}function S(H){if(H===void 0)return;let U=H.trim().toLowerCase();if(["true","1","yes","on"].includes(U))return!0;if(["false","0","no","off"].includes(U))return!1;return}function Co(H){if(Zt.includes(H))return H;let U=$o.includes(H);throw new e("invalid_usage",U?`${H} is written by \`hlix init\` and \`hlix import\`, not by \`hlix config set\`.`:`Unknown setting: ${H}. Known settings: ${Zt.join(", ")}.`)}function To(H,U){let G=Ld(H,U);if(G)throw new e("invalid_usage",G);return U}function k(H){if(To(H.key,H.value),H.scope==="global"){let G=yr(H.env),B=aa(H.env)??{schema:1},W=ea(B,H.key,H.value);if(W!==B)ia(H.env,W);return G}let U=vo(H.cwd);if(!U)throw new e("not_initialized","This folder is not bound to hlix. Run `hlix init` here, or set it machine-wide with --global.");try{return sr(U.root,(G)=>ea(G,H.key,H.value)).path}catch(G){if(G instanceof e)throw G;throw new e("invalid_project_file",G instanceof Error?G.message:"Could not write hlix.yml.")}}function ia(H,U){let G=yr(H),B=kn(U,Od),W=Kt(B);if(!W.ok){let z=W.issues.map((J)=>`${J.path}: ${J.message}`).join("; ");throw new e("invalid_project_file",`${G}: ${z}`)}Eo(G,B)}function aa(H){let U=yr(H);if(Rd(U)){let B;try{B=ta(U,"utf8")}catch{return null}let W=Kt(B);if(!W.ok){let z=W.issues.map((J)=>`${J.path}: ${J.message}`).join("; ");throw new e("invalid_project_file",`${U}: ${z}`)}return W.file}let G=Md(H);if(!G)return null;return ia(H,G),G}function Hd(H){let U=gt(H).binding,G=U.harness&&U.harness in hr?U.harness:void 0;return{schemaVersion:1,...U.dockerImage?{dockerImage:U.dockerImage}:{},...G?{harness:G}:{},...U.memoryTokens?{memoryTokens:U.memoryTokens}:{},...U.model?{model:U.model}:{},...U.sandbox?{sandbox:U.sandbox}:{},...U.yolo?{yolo:U.yolo}:{},...H.providers?{providers:H.providers}:{}}}function Md(H){let U;try{U=JSON.parse(ta(Nd(H),"utf8"))}catch{return null}if(!U||typeof U!=="object"||U.schemaVersion!==1)return null;let G=U,B={schema:1},W={};if(typeof G.harness==="string"&&G.harness in hr)W.harness=G.harness;if(typeof G.model==="string"&&G.model.trim())W.model=G.model.trim();let z=typeof G.memoryTokens==="number"?G.memoryTokens:typeof G.memoryTokens==="string"?Number(G.memoryTokens):void 0;if(z!==void 0&&Number.isInteger(z)&&z>=1&&z<=2000000)W.memoryTokens=z;if(G.yolo==="true"||G.yolo===!0)W.yolo=!0;if(G.yolo==="false"||G.yolo===!1)W.yolo=!1;if(Object.keys(W).length)B.coder=W;let J={};if(G.sandbox==="cloud"||G.sandbox==="local"||G.sandbox==="docker")J.runtime=G.sandbox;if(typeof G.dockerImage==="string"&&G.dockerImage.trim())J.image=G.dockerImage.trim();if(Object.keys(J).length)B.local=J;let K=Dd(G.providers);if(K)B.providers=K;let q=Ct.safeParse(B);if(q.success)return q.data;if(!B.providers)return null;let X={...B,providers:void 0},V=Ct.safeParse(X);return V.success?V.data:null}function Dd(H){if(!Array.isArray(H))return;let U=[];for(let G of H){if(!G||typeof G!=="object")continue;let B=G;if(typeof B.name!=="string"||typeof B.url!=="string"||!Array.isArray(B.models))continue;let W=B.models.filter((q)=>typeof q==="string"&&q.length>0);if(!W.length)continue;let z={name:B.name,url:B.url,models:W,...typeof B.apiKeyEnv==="string"?{apiKeyEnv:B.apiKeyEnv}:{},...typeof B.apiKey==="string"&&B.apiKey.length>0?{apiKey:B.apiKey}:{}},J=Ct.safeParse({schema:1,providers:[z]}),K=J.success?J.data.providers?.[0]:void 0;if(K)U.push(K)}return U.length?U:void 0}function Ud(H,U){if(!H)return;if(U==="harness"){let G=H.harness;return G&&G in hr?G:void 0}return H[U]}function Gd(H,U){let G=H?.file?.providers;if(G===void 0)return U;if(H?.local?.providers!==void 0)return G;return G.map(({name:B,url:W,models:z})=>({name:B,url:W,models:z}))}function ea(H,U,G){if(U==="sandbox"){let B=G==="docker"?"docker":G==="local"?"local":"cloud";if(H.local?.runtime===B)return H;return{...H,local:{...H.local,runtime:B}}}if(U==="dockerImage"){let B=G.trim();if(H.local?.image===B)return H;return{...H,local:{...H.local,image:B}}}if(U==="harness"){if(H.coder?.harness===G)return H;return{...H,coder:{...H.coder,harness:G}}}if(U==="model"){let B=G.trim();if(H.coder?.model===B)return H;return{...H,coder:{...H.coder,model:B}}}if(U==="memoryTokens"){let B=b(G);if(B===void 0||H.coder?.memoryTokens===B)return H;return{...H,coder:{...H.coder,memoryTokens:B}}}if(U==="yolo"){let B=S(G);if(B===void 0||H.coder?.yolo===B)return H;return{...H,coder:{...H.coder,yolo:B}}}return H}var ca=Zt.join(" | "),Ao={name:"config list",summary:"Show every setting in effect and which file supplied it",usage:["Usage: hlix config list [--cwd <dir>] [--json]","","Merges the machine-wide file with this folder's, per key, and names the","source of each value: project, global, or default (no file names it)."].join(`
92
- `),supportsJson:!0,async run(H){let U=v(H.cwd,H.env),G=sa(U);if(H.json)return H.stdout(ge(he(Ao.name,{settings:G,paths:U.paths}))),0;return H.stdout(`${nt(["setting","value","source","applies to"],G.map((B)=>[B.key,B.value??"-",B.source,oa[B.key]??"this folder's binding"]))}
93
- `),H.stdout(`
94
- global ${U.paths.global}
95
- `),H.stdout(`project ${U.paths.project??"- (this folder is not bound to hlix)"}
96
- `),0}},Ro={name:"config get",summary:"Print one setting's effective value",usage:[`Usage: hlix config get <${ca}> [--cwd <dir>] [--json]`,"","Prints the value the cascade resolves for one key, or exits 1 when no","file names it."].join(`
97
- `),supportsJson:!0,args:{min:1,max:1},async run(H){let U=Co(H.args[0]),G=v(H.cwd,H.env),B=G.merged[U]??null,W=G.sources[U]??"default";if(H.json)return H.stdout(ge(he(Ro.name,{key:U,value:B,source:W}))),B===null?1:0;if(B===null)return H.stderr(`${U} is not set. Set it with \`hlix config set ${U} <value>\`.
98
- `),1;return H.stdout(`${B}
99
- `),0}},Oo={name:"config set",summary:"Set one setting for this folder, or for the machine with --global",usage:[`Usage: hlix config set <${ca}> <value> [--global] [--cwd <dir>] [--json]`,"","Writes this folder's hlix.yml, or ~/.hlix/hlix.yml with --global.","Other keys in the file are left untouched. The binding keys","(projectId, workspaceId, apiUrl) are written by init/import and are","refused here."].join(`
100
- `),supportsJson:!0,options:["global"],args:{min:2,max:2},async run(H){let U=Co(H.args[0]),G=To(U,H.args[1]),B=H.flags.global===!0?"global":"project",W=k({key:U,value:G,scope:B,cwd:H.cwd,env:H.env});if(H.json)return H.stdout(ge(he(Oo.name,{key:U,value:G,scope:B,path:W}))),0;return H.stdout(`${U} = ${G} (${B}: ${W})
101
- `),0}};var Bd="project-manager",Wd=2000,zd="Cloud work landed. Run /pull (hlix pull) to bring it into this folder.",la=new Set(["done","pr_created"]),Jd=new Set(["done","pr_created","failed","canceled"]),Kd={"project-manager":"Project Manager","senior-engineer":"Senior Engineer","product-engineer":"Product Engineer","ui-engineer":"UI Engineer","qa-engineer":"QA Engineer","security-engineer":"Security Engineer","technical-writer":"Technical Writer"};function qd(H){let U=H.role?Kd[H.role]:void 0;return U?`${H.name} · ${U}`:H.name}function Vd(H){return H.replace(/^project-/,"").replace(/[-_]+/g," ")}function it(H){return typeof H==="string"&&H.trim()?H.trim():void 0}function da(H){if(H.status==="running")return null;let U=H.detail??{kind:""},G=Vd(H.stepId);if(U.kind==="narration"){let B=Array.isArray(U.tasks)?U.tasks.filter((z)=>typeof z==="string"):[];G=it(U.title)??(B.length>0?B.join(", "):G);let W=it(U.reason);if(W)G+=` — ${W}`}else if(U.kind==="reason"&&it(U.reason))G+=` — ${it(U.reason)}`;else if(U.kind==="verdict")G=U.approved===!0?"review approved":`review asked for changes${it(U.feedback)?` — ${it(U.feedback)}`:""}`;else if(U.kind==="dispatch"&&typeof U.launched==="number")G+=` — ${U.launched} started`;return H.status==="failed"?`${G} (failed)`:G}function pa(H){return{kind:"cycle",text:`cycle "${H.title}": ${H.stage}`}}function Xd(H){return{kind:"task",text:`task "${H.title||H.id}": ${H.status}`}}function ua(H){return{kind:"preview",text:`preview: ${H.state}${H.url?` ${H.url}`:""}`}}function Yd(H,U,G){let B=[],W=U.activity.filter((z)=>da(z)!==null&&!G.has(z.id));if(!H){B.push({kind:"project",text:`${U.project.name}: ${U.project.status} (${U.project.runStatus})`});for(let z of U.cycles)if(!Jd.has(z.status))B.push(pa(z));if(U.preview.url)B.push(ua(U.preview))}else{if(H.project.status!==U.project.status||H.project.runStatus!==U.project.runStatus)B.push({kind:"project",text:`project: ${U.project.status} (${U.project.runStatus})`});let z=!1;for(let J of U.cycles){let K=H.cycles.find((q)=>q.id===J.id);if(K&&K.status===J.status)continue;if(B.push(pa(J)),la.has(J.status)&&!(K&&la.has(K.status)))z=!0}for(let J of U.tasks){let K=H.tasks.find((q)=>q.id===J.id);if(!K||K.status!==J.status)B.push(Xd(J))}for(let J of U.agents){let K=H.agents.find((q)=>q.id===J.id);if(K&&K.state!==J.state)B.push({kind:"agent",text:`${qd(J)} ${J.state==="working"?"started working":"is idle"}`})}if(H.preview.url!==U.preview.url||H.preview.state!==U.preview.state){if(B.push(ua(U.preview)),U.preview.url&&H.preview.url!==U.preview.url)z=!0}if(z)B.push({kind:"landed",text:zd})}for(let z of W){if(G.has(z.id))continue;G.add(z.id),B.push({kind:"activity",text:da(z)})}return B}function ma(H){if(typeof H==="string")return it(H);if(Array.isArray(H))return it(H.map((U)=>U&&typeof U==="object"&&U.type==="text"?String(U.text??""):"").join(""));return}var Zd=(H)=>H==="assistant"?"project manager":"to project manager";class fa{seen=new Set;drafts=new Map;spoke=!1;unsaved;lines(H){switch(H.type){case"MESSAGES_SNAPSHOT":{let U=H.messages.filter((G)=>{if(typeof G.id!=="string"||this.seen.has(G.id))return!1;if(G.role==="assistant"&&this.unsaved!==void 0&&ma(G.content)===this.unsaved)return this.unsaved=void 0,this.seen.add(G.id),!1;return!0});for(let G of U)this.seen.add(G.id);return U.flatMap((G)=>{if(G.role!=="user"&&G.role!=="assistant")return[];let B=ma(G.content);return B?[{kind:"message",text:`${Zd(G.role)}: ${B}`}]:[]})}case"RUN_STARTED":return this.spoke=!1,[{kind:"run",text:"project manager is working…"}];case"TEXT_MESSAGE_START":return this.drafts.set(H.messageId,""),[];case"TEXT_MESSAGE_CONTENT":return this.drafts.set(H.messageId,(this.drafts.get(H.messageId)??"")+H.delta),[];case"TEXT_MESSAGE_END":{let U=it(this.drafts.get(H.messageId));if(this.drafts.delete(H.messageId),this.seen.has(H.messageId))return[];if(this.seen.add(H.messageId),!U)return[];return this.spoke=!0,this.unsaved=U,[{kind:"message",text:`project manager: ${U}`}]}case"TOOL_CALL_START":return[{kind:"tool",text:`project manager → ${H.toolCallName.replace(/[_-]+/g," ")}`}];case"CUSTOM":{let U=H.name==="hlix.turn_saved"?H.value?.messageId:void 0;if(typeof U==="string"&&this.spoke)this.seen.add(U),this.unsaved=void 0;return[]}case"RUN_FINISHED":return this.spoke=!1,[{kind:"run",text:"project manager finished"}];case"RUN_ERROR":return this.spoke=!1,[{kind:"run",text:`project manager stopped: ${H.message}`}];default:return[]}}}async function ga(H,U,G){let B=_t(U),W=new AbortController,z=()=>W.abort();if(G.signal?.aborted)return;G.signal?.addEventListener("abort",z,{once:!0});let J=new fa,K,q=null,X=!1,V=null,Z=()=>{if(q){X=!0;return}q=(async()=>{do{X=!1;let te=new AbortController,re=()=>te.abort();W.signal.addEventListener("abort",re,{once:!0}),V=re;try{for await(let ae of H.live.follow(Bd,B,{signal:te.signal}))for(let se of J.lines(ae))G.emit(se)}finally{V=null,W.signal.removeEventListener("abort",re)}}while(X&&!W.signal.aborted)})().catch((te)=>{if(W.signal.aborted)return;K=te,W.abort()}).finally(()=>{q=null})},Q=()=>{let te=V;if(!te)return Z();X=!0,ft(Wd,W.signal).then(()=>{if(V===te)te()})},ne=new Set,ce;try{Z();for await(let{state:te,event:re}of H.live.project(U,{signal:W.signal})){if(re.type==="CUSTOM"){let ae=re.value;if(re.name==="hlix.thread_changed"&&ae?.threadId===B){if(ae.kind==="run_finished")Q();else if(ae.kind!=="renamed")Z()}continue}for(let ae of Yd(ce,te,ne))G.emit(ae);ce=te}}catch(te){if(!W.signal.aborted)K??=te}finally{W.abort(),G.signal?.removeEventListener("abort",z),await q}if(K!==void 0)throw K}function ya(H){let G=(typeof H.flags.project==="string"?H.flags.project.trim():"")||t(H.cwd)?.config.projectId;if(!G)throw new e("missing_argument","A project is required: pass --project <id>, or run this inside a folder bound to a project.");return G}var ha="The project manager is busy with another message. Try again in a moment; /watch shows what it is doing.";function At(H,U){if(typeof H!=="object"||H===null)return"";let G=H[U];return G===null||G===void 0?"":String(G)}var No={name:"projects list",summary:"List the projects in your workspace",usage:"Usage: hlix projects list [--json]",supportsJson:!0,async run(H){let U=await H.requireClient().projects.list();if(H.json)return H.stdout(ge(he(No.name,U))),0;let G=Array.isArray(U)?U:[];if(G.length===0)return H.stdout(`No projects.
102
- `),0;return H.stdout(`${nt(["ID","NAME","STACK"],G.map((B)=>[At(B,"id"),At(B,"name"),At(B,"stack")]))}
103
- `),0}},Fo={name:"projects get",summary:"Show one project, defaulting to the one this folder is bound to",usage:["Usage: hlix projects get [project-id] [--json]","","With no id, the project this folder is bound to is used."].join(`
104
- `),supportsJson:!0,args:{min:0,max:1},async run(H){let U=H.args[0]??t(H.cwd)?.config.projectId;if(!U)throw new e("missing_argument","A project id is required, or run this inside a folder bound to a project.");let G=await H.requireClient().projects.get(U);if(H.json)return H.stdout(ge(he(Fo.name,G))),0;let B=G.repos;return H.stdout(`${Ae([["id",At(G,"id")],["name",At(G,"name")],["stack",At(G,"stack")],["status",At(G,"status")],["repos",Array.isArray(B)?String(B.length):""]].filter(([,W])=>W!==""))}
105
- `),0}},Lo={name:"projects delete",summary:"Delete a project from your workspace",usage:"Usage: hlix projects delete <id|name> [--yes] [--json]",supportsJson:!0,options:["yes"],args:{min:1,max:1},async run(H){let U=H.requireClient(),G=H.args[0],B=await U.projects.list(),W=B.find((X)=>X.id===G),z=W?[W]:B.filter((X)=>X.name===G);if(z.length===0)throw new e("not_found",`No project named or identified by "${G}".`);if(z.length>1)throw new e("invalid_usage",`More than one project is named "${G}". Use its ID.`);let J=z[0],K=`Delete project "${J.name}"?`;if(H.stderr(`${K}
106
- `),H.flags.yes!==!0){if(t(H.cwd)?.config.projectId===J.id)throw new e("approval_required","This folder is bound to that project. Pass --yes to delete it.");if(H.json||!H.confirm)throw new e("approval_required","Project deletion requires --yes when not interactive.");if(!await H.confirm(K))throw new e("cancelled","Project deletion cancelled.")}let q=await U.projects.delete(J.id);if(H.json)H.stdout(ge(he(Lo.name,q)));else H.stdout(`Deleted project "${J.name}".
107
- `);return 0}},Ho={name:"projects watch",summary:"Stream the project manager's feed: decisions, cycles, tasks and messages",usage:["Usage: hlix projects watch [--project <id>] [--json]","","Follows the project as its manager sees it: cycle and task changes, the","decisions it makes, its messages, and the runs it starts, including the ones","it starts on its own. Read-only; it runs until you stop it.","","With no --project, the project this folder is bound to is watched.","","With --json, each line is one envelope (JSONL): data is { kind, text }, where","kind is project, cycle, task, agent, preview, activity, message, tool, run or","landed (finished cloud work to pull)."].join(`
108
- `),supportsJson:!0,options:["project"],agentTool:!1,async run(H){let U=ya(H),G=H.requireClient();return await G.projects.get(U),await ga(G,U,{...H.signal?{signal:H.signal}:{},emit:(B)=>H.stdout(H.json?`${JSON.stringify(he(Ho.name,B))}
109
- `:`${i(B.text)}
110
- `)}),0}},Mo={name:"projects message",summary:"Send a message to the project manager and print its answer",usage:["Usage: hlix projects message [--project <id>] <text> [--json]","","Posts to the project's thread, the same one the dashboard chat uses, and","prints the project manager's answer as it is written. A manager already","answering someone else is busy: the command fails with conflict and nothing","is sent. With --json, data is { answer }."].join(`
111
- `),supportsJson:!0,options:["project"],args:{min:1,max:1e4},freeText:!0,async run(H){let U=ya(H),G=H.args.join(" ").trim();if(!G)throw new e("missing_argument","A message is required.");let B=H.requireClient(),W="";try{for await(let z of B.live.run("project-manager",{threadId:_t(U),text:G},H.signal?{signal:H.signal}:void 0))if(z.type==="TEXT_MESSAGE_CONTENT"){if(W+=z.delta,!H.json)H.stdout(i(z.delta))}else if(z.type==="RUN_ERROR"){if(z.code==="409")throw new e("conflict",ha);throw new e("server_error",`The project manager could not answer: ${z.message}`)}}catch(z){if(z instanceof xt)throw new e("conflict",ha);throw z}if(H.json)H.stdout(ge(he(Mo.name,{answer:W})));else if(!W)H.stdout(`Sent. The project manager answered without text.
112
- `);else if(!W.endsWith(`
113
- `))H.stdout(`
114
- `);return 0}};function Do(H,U){let G=H.args[0];if(!G)throw new e("missing_argument",`A ${U} id is required.`);return G}function wa(H,U){let G=H.flags[U];return typeof G==="string"&&G.trim()?G.trim():void 0}function at(H,U){if(typeof H!=="object"||H===null)return"";let G=H[U];return G===null||G===void 0?"":String(G)}var Uo={name:"tasks list",summary:"List tasks, defaulting to the project this folder is bound to",usage:["Usage: hlix tasks list [--project <id>] [--status <status>] [--json]","","With no --project, a folder bound to a project lists that project's tasks;","anywhere else it lists the workspace's tasks."].join(`
115
- `),supportsJson:!0,options:["project","status"],async run(H){let U=wa(H,"project")??t(H.cwd)?.config.projectId,G=wa(H,"status"),B=await H.requireClient().tasks.list({...U?{projectId:U}:{},...G?{status:G}:{}});if(H.json)return H.stdout(ge(he(Uo.name,B))),0;let W=Array.isArray(B)?B:[];if(W.length===0)return H.stdout(`No tasks.
116
- `),0;return H.stdout(`${nt(["ID","STATUS","TITLE"],W.map((z)=>[at(z,"id"),at(z,"status"),at(z,"title")||at(z,"description").split(`
117
- `)[0]||""]))}
118
- `),0}},Go={name:"tasks get",summary:"Show one task",usage:"Usage: hlix tasks get <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(H){let U=Do(H,"task"),G=await H.requireClient().tasks.get(U);if(H.json)return H.stdout(ge(he(Go.name,G))),0;return H.stdout(`${Ae([["id",at(G,"id")],["status",at(G,"status")],["title",at(G,"title")],["project",at(G,"projectId")],["description",at(G,"description")]])}
119
- `),0}},Bo={name:"tasks review",summary:"Show the verified review evidence of a task's cycle",usage:"Usage: hlix tasks review <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(H){let U=Do(H,"task"),G=H.requireClient(),B=await G.tasks.get(U);if(!B.cycleId)throw new e("not_found",`Task ${U} belongs to no cycle, so there is no change to review.`);let W=await G.cycles.review(B.cycleId);if(H.json)return H.stdout(ge(he(Bo.name,W))),0;return H.stdout(`${JSON.stringify(W,null,2)}
120
- `),0}},Wo={name:"tasks watch",summary:"Stream a task's status changes until it finishes",usage:["Usage: hlix tasks watch <task-id> [--json]","","Prints the task's status each time it changes and exits when the task is","over: finished, or left unfinished by a cycle that ended (with the reason).","A task the reviewer failed is retried while its cycle is in review, so","watching continues through it.","","With --json, each change is printed as one envelope per line (JSONL) so a","consumer can read them as they arrive: data is { state, task, reason? },","where state is running, finished or unmet."].join(`
121
- `),supportsJson:!0,args:{min:1,max:1},async run(H){let U=Do(H,"task"),G=H.requireClient(),{projectId:B}=await G.tasks.get(U),W;for await(let z of G.live.task(B,U))if(H.json)H.stdout(`${JSON.stringify(he(Wo.name,z))}
122
- `);else if(z.state==="unmet")H.stdout(`error: ${i(z.reason)}
123
- `);else if(z.task&&z.task.status!==W)W=z.task.status,H.stdout(`${i(W)}
124
- `);return 0}};import{realpath as Iu}from"node:fs/promises";import{resolve as $u}from"node:path";import{parse as vp}from"jsonc-parser";import{parse as bp}from"smol-toml";import{parse as kp}from"yaml";var jn={install:null,previewCommand:null,previewPort:null,verifyCommand:null,packageManager:null};var Qd=[["next",3000],["nuxt",3000],["@remix-run/dev",5173],["@sveltejs/kit",5173],["astro",4321],["@angular/cli",4200],["gatsby",8000],["react-scripts",3000],["vite",5173],["hono",3000]],ep=/^(?:vite(?!\s+build\b)|astro\s+(?:dev|preview)|next\s+(?:dev|start)|nux[ti]\s+dev|ng\s+serve|gatsby\s+(?:develop|serve)|react-router\s+dev|remix\s+vite:(?:dev|preview))(?:\s+[^|;&]*)?$/,tp=["vite","next","webpack","react-scripts","@rsbuild/core","parcel"],En=8080,wr=8000,np=String.raw`import http.server as h, urllib.parse as u, sys, os, re, io
125
- B = (sys.argv[2] if len(sys.argv) > 2 else "").rstrip("/")
126
- D = os.path.abspath(sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else ".")
127
- E = sys.argv[4] if len(sys.argv) > 4 else "index.html"
128
- P = int(os.environ.get("PORT") or ${En})
129
- L = re.compile(rb"((?:src|href|action|poster)\s*=\s*[\"'])/(?!/)" + (rb"(?!" + re.escape(B[1:].encode()) + rb"(?:/|[\"']))" if B else b""))
130
- class H(h.SimpleHTTPRequestHandler):
131
- def __init__(s, *a, **k):
132
- super().__init__(*a, directory=D, **k)
133
- def send_head(s):
134
- raw = u.urlsplit(s.path).path
135
- if B and (raw == B or raw.startswith(B + "/")):
136
- s.path = s.path[len(B):] or "/"
137
- p = u.unquote(u.urlsplit(s.path).path).replace(chr(92), "/")
138
- if any(x.startswith(".") for x in p.split("/")):
139
- s.send_error(404)
140
- return None
141
- f = s.translate_path(s.path)
142
- if os.path.isdir(f) and p.endswith("/"):
143
- f = os.path.join(f, E if os.path.abspath(f) == D else "index.html")
144
- elif not os.path.exists(f) and "." not in p.rsplit("/", 1)[-1]:
145
- f = f + ".html" if os.path.isfile(f + ".html") else os.path.join(D, E)
146
- if not (f.lower().endswith((".html", ".htm")) and os.path.isfile(f)):
147
- return super().send_head()
148
- with open(f, "rb") as fh:
149
- body = fh.read()
150
- if B:
151
- body = L.sub(lambda m: m.group(1) + B.encode() + b"/", body)
152
- s.send_response(200)
153
- s.send_header("Content-Type", "text/html; charset=utf-8")
154
- s.send_header("Content-Length", str(len(body)))
155
- s.end_headers()
156
- return io.BytesIO(body)
157
- def list_directory(s, path):
158
- s.send_error(404)
159
- return None
160
- h.ThreadingHTTPServer(("", P), H).serve_forever()
161
- `;function kr(H=".",U="index.html"){return`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${Pn(np)} "$PREVIEW_PUBLIC_PATH" ${H}${U==="index.html"?"":` ${ja(U)}`}`}function Sa(H){if(H.has("index.html"))return"index.html";let U=[...H].filter((G)=>!G.startsWith(".")&&!/[\\/]/.test(G)&&/\.html?$/i.test(G));return U.length===1?U[0]:null}var xa="HLIX_PREVIEW_FAILURE";function vr(H){return`{ echo "${xa}=${H}"; exit 1; }`}var rp=`const handler = {
162
- get(target, key) {
163
- if (key === 'then' || key === 'prototype' || key === '$$typeof') return undefined
164
- if (key === '__esModule') return false
165
- if (key === Symbol.toPrimitive) return () => ''
166
- if (key === 'displayName' || key === 'name') return 'Unavailable'
167
- return stub
168
- },
169
- apply(target, self, args) {
170
- const props = args[0]
171
- return props !== null && typeof props === 'object' && !Array.isArray(props) ? null : stub
172
- },
173
- }
174
- const stub = new Proxy(function Unavailable() {}, handler)
175
- module.exports = stub
176
- `,op=`const path = require('path')
177
- const loaded = __CONFIG__
178
- const dir = path.join(__dirname, 'hlix-web')
179
- // React Native Web's own names, as imported directly and as Expo rewrites them.
180
- const WEB_ROOT = new Set(['react-native', 'react-native-web', 'react-native-web/dist/index'])
181
- function withNativeStubs(config) {
182
- const upstream = config.resolver.resolveRequest
183
- config.resolver.resolveRequest = (context, moduleName, platform) => {
184
- if (platform === 'web' && !context.originModulePath.startsWith(dir)) {
185
- if (WEB_ROOT.has(moduleName)) return { type: 'sourceFile', filePath: path.join(dir, 'react-native.js') }
186
- if (moduleName.startsWith('react-native/Libraries/')) return { type: 'sourceFile', filePath: path.join(dir, 'native-stub.js') }
187
- }
188
- return (upstream || context.resolveRequest)(context, moduleName, platform)
189
- }
190
- return config
191
- }
192
- module.exports = typeof loaded === 'function'
193
- ? async (...args) => withNativeStubs(await loaded(...args))
194
- : loaded && typeof loaded.then === 'function' ? loaded.then(withNativeStubs) : withNativeStubs(loaded)
195
- `,sp=String.raw`const fs = require("fs"), cp = require("child_process")
196
- const [base, pm] = process.argv.slice(-2)
197
- // No preview path: not the preview's own copy. Prepared already: a restart.
198
- if (!base || fs.existsSync("hlix-web/native-stub.js")) process.exit(0)
199
- const fail = (code, why) => { console.error("hlix: " + why); console.log("${xa}=" + code); process.exit(1) }
200
- const run = (cmd, args) => {
201
- const res = cp.spawnSync(cmd, args, { stdio: "inherit", env: { ...process.env, CI: "1", EXPO_NO_TELEMETRY: "1" } })
202
- if (res.status !== 0) fail("packages_unavailable", "could not install " + args.join(" "))
203
- }
204
- const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"))
205
- const deps = { ...pkg.dependencies, ...pkg.devDependencies }
206
- if (!("expo" in deps)) fail("web_build_failed", "This project no longer declares Expo; open its native preview")
207
- // npm refuses a React Native major change over peer ranges; the others only warn.
208
- const peers = pm === "npm" ? ["--", "--legacy-peer-deps"] : []
209
- const missing = ["react-dom", "react-native-web", "@expo/metro-runtime", "babel-preset-expo"].filter((name) => !(name in deps))
210
- if (missing.length) run("npx", ["expo", "install", ...missing, ...peers])
211
- fs.mkdirSync("hlix-web", { recursive: true })
212
- fs.writeFileSync("hlix-web/native-stub.js", ${JSON.stringify(rp)})
213
- fs.writeFileSync("hlix-web/react-native.js", "const web = require('react-native-web/dist/index')\nconst stub = require('./native-stub')\nmodule.exports = new Proxy(web, { get: (target, key) => (key in target ? target[key] : stub) })\n")
214
- const own = ["metro.config.js", "metro.config.cjs"].find((file) => fs.existsSync(file))
215
- let config = "require('expo/metro-config').getDefaultConfig(__dirname)"
216
- if (own && /expo/.test(fs.readFileSync(own, "utf8"))) {
217
- // Beside the original, so its own __dirname still names the project.
218
- fs.renameSync(own, "metro.config.hlix-original.js")
219
- config = "require('./metro.config.hlix-original.js')"
220
- }
221
- if (own) fs.rmSync(own, { force: true })
222
- fs.writeFileSync("metro.config.js", ${JSON.stringify(op)}.replace("__CONFIG__", config))
223
- `,ip=String.raw`const fs = require("fs")
224
- const base = (process.argv[process.argv.length - 1] || "").replace(/\/+$/, "")
225
- if (!base) process.exit(0)
226
- const dynamic = ["app.config.ts", "app.config.js"].filter((file) => fs.existsSync(file))
227
- if (dynamic.length || fs.existsSync("app.json")) {
228
- const json = dynamic.length ? { expo: require("expo/config").getConfig(process.cwd()).exp } : JSON.parse(fs.readFileSync("app.json", "utf8"))
229
- const expo = json.expo || json
230
- expo.experiments = { ...expo.experiments, baseUrl: base }
231
- fs.writeFileSync("app.json", JSON.stringify(json, null, 2))
232
- for (const file of dynamic) fs.rmSync(file)
233
- }
234
- `,ap=String.raw`import json, os, shutil, sys, tarfile, tempfile, urllib.request
235
- root = sys.argv[1]
236
- base = "https://storage.googleapis.com/flutter_infra_release/releases"
237
- index = json.load(urllib.request.urlopen(base + "/releases_linux.json", timeout=60))
238
- stable = index["current_release"]["stable"]
239
- release = next(r for r in index["releases"] if r["hash"] == stable)
240
- tmp = tempfile.mkdtemp(dir=root)
241
- archive = os.path.join(tmp, "flutter.tar.xz")
242
- with urllib.request.urlopen(base + "/" + release["archive"], timeout=600) as src, open(archive, "wb") as out:
243
- shutil.copyfileobj(src, out)
244
- with tarfile.open(archive) as tar:
245
- tar.extractall(tmp, filter="tar")
246
- os.remove(archive)
247
- os.rename(os.path.join(tmp, "flutter"), os.path.join(root, "sdk"))
248
- shutil.rmtree(tmp, ignore_errors=True)
249
- print("hlix: Flutter " + release["version"] + " installed")
250
- `,cp=String.raw`import sys, zipfile
251
- args = [a for a in sys.argv[1:] if a not in ("-o", "-q")]
252
- dest = args[args.index("-d") + 1] if "-d" in args else "."
253
- zipfile.ZipFile(args[0]).extractall(dest)
254
- `;function va(H,U){return`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${Pn(H)} ${U}`}function lp(){return['mkdir -p "$HOME/.cache/hlix-flutter"/bin',`{ [ -x "$HOME/.cache/hlix-flutter"/sdk/bin/flutter ] || { echo "hlix: installing the Flutter SDK (first run only)"; ${va(ap,'"$HOME/.cache/hlix-flutter"')}; } || ${vr("flutter_sdk_unavailable")}; }`,`{ command -v unzip >/dev/null 2>&1 || { printf '#!/bin/sh\\n%s "$@"\\n' ${ja(va(cp,""))} > "$HOME/.cache/hlix-flutter"/bin/unzip && chmod +x "$HOME/.cache/hlix-flutter"/bin/unzip; }; }`,'PATH="$HOME/.cache/hlix-flutter"/sdk/bin:"$HOME/.cache/hlix-flutter"/bin:$PATH',"export PATH","{ flutter config --no-analytics >/dev/null 2>&1 || true; }",`{ flutter pub get || ${vr("packages_unavailable")}; }`,`{ flutter run -d web-server --web-hostname 0.0.0.0 --web-port "$PORT" </dev/null || { echo "hlix: the dev server stopped; serving a web build instead"; flutter build web --base-href "$PREVIEW_PUBLIC_PATH/" && ${kr("build/web")}; } || ${vr("web_build_failed")}; }`].join(" && ")}function dp(H){let U=`printf %s ${Pn(sp)} | base64 -d | node - "$PREVIEW_PUBLIC_PATH" ${H}`,G=`CI=1 npx expo export --platform web --output-dir dist && ${kr("dist")}`;return`${U} && ${Ea(ip,"PREVIEW_PUBLIC_PATH")} && { BROWSER=none EXPO_NO_TELEMETRY=1 npx expo start --no-dev --port "$PORT" </dev/null || { echo "hlix: the dev server stopped; serving a web build instead"; ${G}; } || ${vr("web_build_failed")}; }`}function ja(H){return`'${H.replace(/'/g,"'\\''")}'`}var pp=String.raw`const fs = require("fs")
255
- const base = (process.argv[process.argv.length - 1] || "").replace(/\/+$/, "")
256
- if (!base) process.exit(0)
257
- const file = ["next.config.ts", "next.config.mts", "next.config.mjs", "next.config.js", "next.config.cjs"].find((name) => fs.existsSync(name))
258
- const wrap = (name) => "(async (...args) => { const c = typeof " + name + " === \"function\" ? await " + name + "(...args) : await " + name + "; return { ...c, basePath: " + JSON.stringify(base) + " } })"
259
- if (!file) {
260
- fs.writeFileSync("next.config.mjs", "export default { basePath: " + JSON.stringify(base) + " }\n")
261
- process.exit(0)
262
- }
263
- let text = fs.readFileSync(file, "utf8")
264
- if (text.includes("__hlixPreviewConfig")) process.exit(0)
265
- if (/\bexport\s+default\b/.test(text)) {
266
- text = text.replace(/\bexport\s+default\b/, "const __hlixPreviewConfig =") + "\nexport default " + wrap("__hlixPreviewConfig") + "\n"
267
- } else if (/\bmodule\.exports\s*=/.test(text)) {
268
- text += "\nconst __hlixPreviewConfig = module.exports\nmodule.exports = " + wrap("__hlixPreviewConfig") + "\n"
269
- } else {
270
- process.exit(0)
271
- }
272
- fs.writeFileSync(file, text)
273
- `,up=String.raw`import os, re, sys
274
- hosts = [h for h in (sys.argv[2] if len(sys.argv) > 2 else "").split(",") if h]
275
- if not hosts:
276
- sys.exit(0)
277
- match = re.search(r"DJANGO_SETTINGS_MODULE['\"]\s*,\s*['\"]([\w.]+)['\"]", open("manage.py").read())
278
- if not match:
279
- sys.exit(0)
280
- module = match.group(1).replace(".", "/")
281
- path = module + ".py" if os.path.isfile(module + ".py") else os.path.join(module, "__init__.py")
282
- if not os.path.isfile(path) or "# hlix preview hosts" in open(path).read():
283
- sys.exit(0)
284
- with open(path, "a") as f:
285
- f.write("\n# hlix preview hosts\nALLOWED_HOSTS = list(globals().get('ALLOWED_HOSTS') or ['.localhost', '127.0.0.1', '[::1]']) + %r\n" % hosts)
286
- `;function Ea(H,U){return`printf %s ${Pn(H)} | base64 -d | node - "$${U}"`}var mp=["test","typecheck","check","build","lint"],fp=/^(?:\.eslintrc(?:\.(?:js|cjs|mjs|json|ya?ml))?|eslint\.config\.(?:js|cjs|mjs|ts|cts|mts))$/;function gp(H,U){return/\bnext\s+lint\b/.test(H)&&![...U].some((G)=>fp.test(G))}var gy=Object.freeze({CI:"true",DEBIAN_FRONTEND:"noninteractive",GIT_TERMINAL_PROMPT:"0",GIT_EDITOR:"true",npm_config_yes:"true",NPM_CONFIG_FUND:"false",NPM_CONFIG_AUDIT:"false",NPM_CONFIG_UPDATE_NOTIFIER:"false",PIP_NO_INPUT:"1",PIP_DISABLE_PIP_VERSION_CHECK:"1",NEXT_TELEMETRY_DISABLED:"1",NO_COLOR:"1",TERM:"dumb"});var hp=["dev","start","serve","preview"];function Sr(H){if(!H)return{};try{let U=JSON.parse(H);return U&&typeof U==="object"?U:{}}catch{return{}}}function Pa(H){return{...ct(H.dependencies)?H.dependencies:{},...ct(H.devDependencies)?H.devDependencies:{}}}function ba(H){let U=Pa(Sr(H.packageJson));if("expo"in U||"react-native"in U)return!0;if(Array.from(H.rootFiles).some((G)=>G==="hlix.mobile.json"||G==="AndroidManifest.xml"||/\.xc(?:odeproj|workspace)$/.test(G)))return!0;return Jo(H)}function Jo(H){if(!new Set(H.rootFiles).has("pubspec.yaml"))return!1;let U=H.configFiles?.["pubspec.yaml"];return U===void 0||/^\s+sdk:\s*flutter\s*$/m.test(U)}function _a(H){let U=new Set(H.rootFiles),G=Sr(H.packageJson),B=typeof G.packageManager==="string"?G.packageManager.split("@")[0]:"",W=B==="bun"||U.has("bun.lock")||U.has("bun.lockb")?"bun":B==="pnpm"||U.has("pnpm-lock.yaml")?"pnpm":B==="yarn"||U.has("yarn.lock")?"yarn":B==="npm"||U.has("package.json")?"npm":null,z=Sa(U);if(!W){if(ba(H)&&!Jo(H))return{...jn,mobile:!0};if(Jo(H))return{...jn,previewCommand:lp(),previewPort:En,mobile:!0};let X=wp(U,H.configFiles??{});if(X)return X;return z?{...jn,previewCommand:kr(".",z),previewPort:En}:jn}let J=Ia(G,U,W),K={install:`${W} install`,verifyCommand:J.verifyCommand,packageManager:W},q=J.webApp?null:yp(H.workspacePackages??[],W)[0]??null;if(q){let X=(V)=>`cd ${q.dir} && ${V}`;return{...K,previewCommand:X(q.previewCommand),previewPort:q.previewPort,verifyCommand:K.verifyCommand??(q.verifyCommand?X(q.verifyCommand):null),...q.mobile?{mobile:!0}:{}}}return{...K,previewCommand:J.previewCommand,previewPort:J.previewPort,...J.mobile||!J.previewCommand&&ba(H)?{mobile:!0}:{}}}function Ia(H,U,G,B){let W=ct(H.scripts)?H.scripts:{},z=(fe)=>`${G} run ${fe}`,J=(fe,Se)=>`${z(fe)}${G==="npm"?" --":""} ${Se}`,K=hp.find((fe)=>typeof W[fe]==="string"),q=mp.find((fe)=>typeof W[fe]==="string"&&!/no test specified/i.test(String(W[fe]))&&!/(?:^|\s)(?:--watch(?:All)?|-w)(?:\s|=|$)/.test(String(W[fe]))&&!gp(String(W[fe]),U)),X=q?z(q):null,V=Pa(H),Z={previewCommand:null,previewPort:null,verifyCommand:X,webApp:!1,mobile:!1,explicitPort:!1};if("react-native"in V&&!("expo"in V)&&!tp.some((fe)=>(fe in V)))return{...Z,mobile:!0};if("expo"in V)return{previewCommand:dp(G),previewPort:B??En,verifyCommand:X,webApp:!0,mobile:!0,explicitPort:!1};let Q=Qd.find(([fe])=>(fe in V)),ne=K?zo(String(W[K]))??Q?.[1]??null:null,ce=Sa(U);if(!K&&!Q&&ce)return{...Z,previewCommand:kr(".",ce),previewPort:B??En};if(!K)return Z;let te=String(W[K]).trim(),re=B!=null?` --port ${B}`:"",ae=te.split("&&").map((fe)=>fe.trim()),se=re||(ne!=null&&zo(te)==null&&ep.test(ae.at(-1))?` --port ${ne}`:""),me=se?J(K,se.trim()):z(K);if(ae.length>1&&ae.every((fe)=>/^vite(?:\s|$)/.test(fe))&&!("@sveltejs/kit"in V)){let fe={npm:"npx",bun:"bunx",pnpm:"pnpm exec",yarn:"yarn exec"}[G];me=ae.map((Se,pe)=>`${fe} ${Se} --base "$PREVIEW_BASE_PATH/"${/^vite\s+build\b/.test(Se)?"":" --host 0.0.0.0"}${pe===ae.length-1?se:""}`).join(" && ")}else if(/^vite(?:\s+(?:dev|serve|preview))?(?:\s|$)/.test(te)&&!/&&|;|\|/.test(te)&&!("@sveltejs/kit"in V))me=J(K,`--base "$PREVIEW_BASE_PATH/" --host 0.0.0.0${se}`);else if(/^astro\s+(?:dev|preview)(?:\s|$)/.test(te))me=J(K,`--base "$PREVIEW_BASE_PATH"${se}`);else if(/^next\s+(?:dev|start)(?:\s|$)/.test(te))me=`${Ea(pp,"PREVIEW_BASE_PATH")} && ${me}`;else if(/^nuxt\s+(?:dev|preview|start)(?:\s|$)/.test(te))me=`NUXT_APP_BASE_URL="$PREVIEW_BASE_PATH/" ${me}`;return{previewCommand:me,previewPort:B??ne,verifyCommand:X,webApp:Boolean(Q),mobile:!1,explicitPort:zo(te)!=null}}var ka=["web","app","frontend","site","www","client","dashboard"];function yp(H,U){let G=H.filter((W)=>br(W.dir)).map((W)=>{let z=Sr(W.packageJson),J=new Set(W.rootFiles??[]);return{dir:W.dir,pkg:z,files:J,...Ia(z,J,U)}}).filter((W)=>W.webApp&&W.previewCommand&&W.previewPort!=null),B=(W)=>{let z=ka.indexOf(W.split("/").at(-1)??"");return z<0?ka.length:z};return G.sort((W,z)=>Number(W.mobile)-Number(z.mobile)||Number(!W.dir.startsWith("apps/"))-Number(!z.dir.startsWith("apps/"))||B(W.dir)-B(z.dir)||(W.dir<z.dir?-1:W.dir>z.dir?1:0))}function br(H){return/^[A-Za-z0-9._@-]+(?:\/[A-Za-z0-9._@-]+)*$/.test(H)&&!H.split("/").some((U)=>U===".."||U===".")}function $a(H){let U=Sr(H.packageJson),G=Array.isArray(U.workspaces)?U.workspaces:ct(U.workspaces)&&Array.isArray(U.workspaces.packages)?U.workspaces.packages:[],B=H.configFiles?.["pnpm-workspace.yaml"]??"";for(let K of B.split(/\r?\n/)){let q=K.match(/^\s*-\s*["']?([^"'#\s]+)["']?/);if(q)G.push(q[1])}let W=G.filter((K)=>typeof K==="string"&&!K.startsWith("!"));if(W.length===0&&new Set(H.rootFiles).has("turbo.json"))W.push("apps/*","packages/*");for(let K of Object.values(ct(U.scripts)?U.scripts:{})){if(typeof K!=="string")continue;let q=K.match(/^\s*cd\s+([A-Za-z0-9._@/-]+)\s*&&/)?.[1];if(q&&br(q))W.push(q)}let z=new Set,J=new Set;for(let K of W){let q=K.replace(/^\.\//,"").replace(/\/$/,"");if(/^[^*]+\/\*$/.test(q)&&br(q.slice(0,-2)))z.add(q.slice(0,-2));else if(!q.includes("*")&&br(q))J.add(q)}return{parents:[...z].sort(),packages:[...J].sort()}}function wp(H,U){let G=`${U["requirements.txt"]??""}
287
- ${U["pyproject.toml"]??""}`.toLowerCase(),B=(V)=>new RegExp(`(^|[\\s"'\\[,])${V}\\b`,"m").test(G),W=H.has("requirements.txt")?'"$V/bin/pip" install -q -r requirements.txt':H.has("pyproject.toml")?'"$V/bin/pip" install -q .':null,z=(V,Z="")=>W?`V="$HOME/.cache/hlix-venvs/$(cat requirements.txt pyproject.toml 2>/dev/null | cksum | cut -d " " -f1)"; { [ -f "$V/.ready" ] || { rm -rf "$V" && python3 -m venv "$V" && ${W}${Z} && touch "$V/.ready"; }; } && "$V/bin/python" ${V}`:null,J=B("pytest")?z("-m pytest",' && "$V/bin/pip" install -q pytest'):null,q=["main.py","app.py","server.py","api.py"].find((V)=>H.has(V))?.replace(/\.py$/,""),X=(V,Z=J)=>({...jn,previewCommand:V,previewPort:wr,verifyCommand:Z});if(H.has("manage.py")){let V=`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${Pn(up)} "$PREVIEW_ALLOWED_HOSTS"`;return X(`${V} && python3 manage.py runserver 0.0.0.0:${wr}`,J??(B("django")?z("manage.py test"):null))}if(q&&B("fastapi"))return X(`python3 -m uvicorn ${q}:app --host 0.0.0.0 --port ${wr} --root-path "$PREVIEW_PUBLIC_PATH"`);if(q&&B("flask"))return X(`python3 -m flask --app ${q} run --host 0.0.0.0 --port ${wr}`);return null}function Pn(H){return btoa(H)}function zo(H){let U=H.match(/(?:--port(?:=|\s+)|-p\s+|\bPORT=)(\d{2,5})\b/),G=U?Number(U[1]):NaN;return Number.isInteger(G)&&G>0&&G<=65535?G:null}function ct(H){return Boolean(H)&&typeof H==="object"&&!Array.isArray(H)}function Ca(H){let U=new Set(H.rootFiles),G=new Set;if(U.has("package.json")){for(let W of["coverage",".cache"])G.add(W);if(["package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb"].some((W)=>U.has(W)))G.add("node_modules")}if(U.has("Cargo.toml"))G.add("target");if(["pyproject.toml","requirements.txt","setup.py"].some((W)=>U.has(W)))G.add("__pycache__");if(U.has("composer.json")&&U.has("composer.lock"))G.add("vendor");for(let W of Ko({...H,rootFiles:U}))G.add(W);return[...G].sort()}function et(H,U,G){let B=(H.match(/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*|[A-Za-z_$][\w$]*|[^\s]/g)??[]).filter((q)=>!q.startsWith("//")&&!q.startsWith("/*"));if(B[0]!=="{"){let q=B.findIndex((V,Z)=>V==="export"&&B[Z+1]==="default"),X=B.findIndex((V,Z)=>V==="module"&&B.slice(Z+1,Z+4).join("")===".exports=");if(q<0&&X<0)return null;if(B=B.slice(q>=0?q+2:X+4),["defineConfig","defineNuxtConfig"].includes(B[0]??"")&&B[1]==="(")B=B.slice(2);if(B[0]!=="{")return null}if(B.some((q,X)=>q==="."&&B[X+1]==="."&&B[X+2]==="."))return null;let W=(q="")=>q.replace(/^["']|["']$/g,""),z=[],J,K=0;for(let q=0;q<B.length;q++){let X=B[q];if(X==="{")z.push(B[q-1]===":"?W(B[q-2]):"");if(X==="}")z.pop();if(!z.length)break;if(X==="["&&["{",","].includes(B[q-1]??""))return null;if(U&&z.length===1&&W(X)===U){if(B[q+1]!==":"||B[q+2]!=="{"||++K>1)return null}if(W(X)===G&&(U?z.length===2&&z.at(-1)===U:z.length===1)&&B[q+1]!==":")return null;if(W(X)!==G||B[q+1]!==":"||(U?z.length!==2||z.at(-1)!==U:z.length!==1))continue;let V=B[q+2]??"";if(J!==void 0||!/^["'`][^\\$]*["'`]$/.test(V)||![",","}"].includes(B[q+3]??""))return null;J=V.slice(1,-1)}return J}function Ko(H){let U={};try{let Q=JSON.parse(H.packageJson??"{}");if(ct(Q))U=Q}catch{}let G={...ct(U.dependencies)?U.dependencies:{},...ct(U.devDependencies)?U.devDependencies:{}},B=ct(U.scripts)?Object.entries(U.scripts).filter((Q)=>typeof Q[1]==="string"):[],W=(Q,ne=Q)=>(Q in G)||B.some(([,ce])=>new RegExp(`(?:^|[;&|\\s])${ne}(?:\\s|$)`).test(ce)),z=H.configFiles??{},J=new Set,K=(Q)=>{if(typeof Q!=="string")return null;let ne=Q.replace(/^\.\//,"").replace(/\/$/,"");return ne&&!ne.startsWith("/")&&!/[\\:*?\[\]#!$`"'\r\n]/.test(ne)&&!ne.split("/").some((ce)=>!ce||[".","..",".git",".hlix"].includes(ce))?ne:null},q=(Q)=>{let ne=K(Q);if(ne)J.add(ne)},X=(Q,ne)=>{let ce=B.filter(([se,me])=>/(?:^|:)build(?:$|:)/.test(se)||new RegExp(`\\b${Q} build\\b`).test(me)),te=ce.filter(([,se])=>new RegExp(`(?:^|\\s)${Q}(?:\\s|$)`).test(se));if(!te.length&&(ce.length||U.workspaces!==void 0))return null;if(ce.some((se)=>!te.includes(se)&&/--(?:out|dist|root|config|project)|\s-[dpc]\b/.test(se[1])))return null;let re,ae=!1;for(let[,se]of te){if(/[$`\\;|<>\n]/.test(se)||/(?:^|\s)(?:cd|pushd|popd)\s/.test(se))return null;for(let me of se.split("&&")){let fe=me.match(/"[^"\n]*"|'[^'\n]*'|[^\s]+/g)??[];if(fe.some((le)=>/["']/.test(le)&&!/^(?:"[^"\n]*"|'[^'\n]*')$/.test(le)))return null;let Se=fe.map((le)=>le.replace(/^["']|["']$/g,"")),pe=Se.indexOf(Q);if(pe<0)continue;if(pe!==0&&!(pe===1&&["npx","bunx"].includes(Se[0])))return null;let oe=Se.slice(pe+1);if(oe[0]==="build")oe.shift();let ee;for(let le=0;le<oe.length;le++){let[be,...Ee]=oe[le].split("="),Pe=Ee.length?Ee.join("="):void 0;if(!ne.includes(be)||ee!==void 0)return null;let Oe=Pe??oe[++le],_e=K(Oe);if(!_e)return null;ee=_e}if(ae&&ee!==re)return null;ae=!0,re=ee}}return re},V=(Q)=>{let ne=[...new Set([...H.rootFiles,...Object.keys(z)])].filter((ce)=>ce.startsWith(`${Q}.config.`)||Q==="turbo"&&ce==="turbo.json");if(!ne.length)return"{}";return ne.length===1?z[ne[0]]??null:null},Z=(Q,ne,ce,te,re,ae,se)=>{let me=V(Q),fe=X(Q,re);if(me===null||fe===null)return;let Se=ae?et(me,null,ae):void 0,pe=et(me,ne,ce);if(Se===null||pe===null)return;let oe=Se===void 0||Se==="."||Se==="./"?"":K(Se);if(oe===null)return;let le=K(fe??pe??te);if(!le)return;q(oe?`${oe}/${le}`:le);for(let be of se??[])q(oe?`${oe}/${be}`:be)};if(W("vite"))Z("vite","build","outDir","dist",["--outDir","--out-dir"],"root");if(W("next")){let Q=V("next"),ne=Q===null?null:et(Q,null,"output");if(Q!==null&&(ne===void 0||ne==="standalone"||ne==="export"&&et(Q,null,"distDir")===void 0))Z("next",null,"distDir",".next",[],void 0,ne==="export"?["out"]:[])}if(W("astro"))Z("astro",null,"outDir","dist",["--outDir","--out-dir"],"root");if(W("nuxt")){let Q=V("nuxt");if(Q!==null&&et(Q,null,"nitro")===void 0&&et(Q,null,"extends")===void 0)Z("nuxt",null,"buildDir",".nuxt",[],"rootDir",[".output"])}if(W("turbo"))Z("turbo",null,"cacheDir",".turbo",["--cache-dir"]);if(W("webpack")){let Q=V("webpack");if(Q!==null&&et(Q,null,"context")===void 0)Z("webpack","output","path","dist",["--output-path"])}if(W("rollup"))Z("rollup","output","dir",void 0,["--dir","-d"]);if(W("parcel")||W("parcel-bundler","parcel")){let Q=X("parcel",["--dist-dir"]);if(Q!==null&&U.targets===void 0&&!["main","module","browser"].some((ne)=>typeof U[ne]==="string"))q(Q??"dist")}if(W("react-scripts")&&X("react-scripts",[])!==null)q("build");if(W("typescript","tsc")){let Q=X("tsc",["--outDir"]),ne=Object.keys(z).filter((ce)=>/^tsconfig(?:\.[^/]*)?\.json$/.test(ce));if(Q!==null&&ne.length===1&&ne[0]==="tsconfig.json"){let ce=z["tsconfig.json"];if(et(ce,null,"extends")===void 0&&et(ce,null,"references")===void 0){let te=et(ce,"compilerOptions","outDir");if(te!==null)q(Q??te)}}}if(qo(z)){q("build"),q("dist");for(let Q of H.rootFiles)if(Q.endsWith(".egg-info"))q(Q)}return[...J].sort()}function qo(H){let U=(H["pyproject.toml"]??"").split(/^\[build-system\]\s*$/m)[1]?.split(/^\[/m)[0]??"";return/^build-backend\s*=\s*["'][^"']+["']/m.test(U)||/(?:from\s+(?:setuptools|distutils.core)\s+import\s+.*\bsetup\b|(?:setuptools|distutils.core)\.setup\s*\()/.test(H["setup.py"]??"")}var Fe=(H)=>H&&typeof H==="object"&&!Array.isArray(H)?H:{},Qt=(H)=>Array.isArray(H)?H.filter((U)=>typeof U==="string"):[];function Ta(H){let U=[];function G(oe,ee="json"){let le=H.get(oe);if(!le)return{};try{if(ee==="yaml")return Fe(kp(le,{maxAliasCount:50}));if(ee==="toml")return Fe(bp(le));if(ee==="jsonc"){let be=[],Ee=vp(le,be,{allowTrailingComma:!0});if(be.length)throw Error("invalid JSONC");return Fe(Ee)}return Fe(JSON.parse(le))}catch{return U.push(`Could not parse ${oe}`),{}}}let B=[...H.keys()].sort(),W=G("package.json"),z={packageJson:H.get("package.json")??null,rootFiles:B.filter((oe)=>!oe.includes("/")),configFiles:Object.fromEntries(["requirements.txt","pyproject.toml","pnpm-workspace.yaml"].flatMap((oe)=>H.get(oe)?[[oe,H.get(oe)]]:[]))},J=$a(z),K=B.flatMap((oe)=>{let ee=oe.replace(/\/package\.json$/,""),le=ee!==oe&&(J.packages.includes(ee)||J.parents.some((Ee)=>ee.startsWith(`${Ee}/`)&&!ee.slice(Ee.length+1).includes("/"))),be=H.get(oe);return le&&be?[{dir:ee,packageJson:be}]:[]}),q=_a({...z,workspacePackages:K}),X=typeof W.packageManager==="string"?/^(npm|pnpm|yarn|bun)@(.+)$/.exec(W.packageManager):null,V=Object.create(null);for(let[oe,ee]of Object.entries(Fe(W.engines)))if(typeof ee==="string")V[oe]=ee;if(X)V[X[1]]=X[2].split("+")[0];let Z=G("composer.json"),Q={...Fe(Z["require-dev"]),...Fe(Z.require)},ne={...typeof Q.php==="string"?{constraint:Q.php}:{},extensions:Object.keys(Q).filter((oe)=>oe.startsWith("ext-")).map((oe)=>oe.slice(4)).sort()};for(let[oe,ee]of[[".nvmrc","node"],[".node-version","node"],[".python-version","python"],[".php-version","php"],[".bun-version","bun"]]){let le=H.get(oe)?.trim();if(le)V[ee]=le}for(let oe of(H.get(".tool-versions")??"").split(/\r?\n/)){let[ee,le]=oe.replace(/#.*/,"").trim().split(/\s+/);if(ee&&le)V[ee==="nodejs"?"node":ee]=le}for(let oe of[".mise.toml","mise.toml"])for(let[ee,le]of Object.entries(Fe(G(oe,"toml").tools)))if(typeof le==="string"||typeof le==="number")V[ee]=String(le);else U.push(`Unsupported tool version for ${ee} in ${oe}`);let ce=[];for(let oe of B.filter((ee)=>/(^|\/)package.json$/.test(ee))){let ee=oe==="package.json"?W:G(oe),le={...Fe(ee.dependencies),...Fe(ee.devDependencies)};for(let be of["nuxt","next","astro","@sveltejs/kit","vite"])if(be in le)ce.push({path:oe,name:be})}for(let[oe,ee]of[["yiisoft/yii2","yii2"],["laravel/framework","laravel"]])if(oe in Q)ce.push({path:"composer.json",name:ee});let te=new Set,re=Object.create(null);function ae(oe,ee){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(oe))return;if(te.add(oe),/(?:^|_)HOST$/.test(oe)&&typeof ee==="string"&&/^[a-zA-Z0-9_.-]+$/.test(ee))re[oe]=ee}for(let oe of B.filter((ee)=>/(^|\/)\.env\.(example|sample|template)$/.test(ee)))for(let ee of(H.get(oe)??"").split(/\r?\n/)){let le=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*(?:#.*)?$/.exec(ee);if(le)ae(le[1],le[2].replace(/^['"]|['"]$/g,""))}let se=[],me=[];for(let oe of B.filter((ee)=>/(^|\/)(?:docker-compose|compose)(?:[.-][^/]*)?\.ya?ml$/.test(ee)))for(let[ee,le]of Object.entries(Fe(G(oe,"yaml").services))){let be=Fe(le),Ee=typeof be.image==="string"?be.image:"",Pe=Ee.split("/").at(-1)?.split(/[:@]/)[0],Oe=Pe==="mysql"||Pe==="mariadb"?"mysql":Pe==="postgres"?"postgres":Pe==="redis"?"redis":null;if(Oe)se.push({file:oe,name:ee,kind:Oe,image:Ee});else if(Pe!=="traefik"&&Pe!=="nginx"&&Pe!=="caddy")me.push({file:oe,name:ee});for(let[_e,Re]of Object.entries(Fe(be.environment)))ae(_e,Re);for(let _e of Qt(be.environment)){let Re=_e.indexOf("=");ae(Re<0?_e:_e.slice(0,Re),Re<0?null:_e.slice(Re+1))}}let fe=B.find((oe)=>oe===".devcontainer/devcontainer.json")??B.find((oe)=>oe==="devcontainer.json"),Se;if(fe){let oe=G(fe,"jsonc");for(let ee of[oe.containerEnv,oe.remoteEnv])for(let[le,be]of Object.entries(Fe(ee)))ae(le,be);Se={...typeof oe.image==="string"?{image:oe.image}:{},services:[...typeof oe.service==="string"?[oe.service]:[],...Qt(oe.runServices)],ports:Array.isArray(oe.forwardPorts)?oe.forwardPorts.filter((ee)=>Number.isInteger(ee)&&Number(ee)>0&&Number(ee)<=65535):[],commands:[oe.onCreateCommand,oe.updateContentCommand,oe.postCreateCommand,oe.postStartCommand].filter((ee)=>typeof ee==="string")}}let pe=Qt(W.workspaces).length?Qt(W.workspaces):Qt(Fe(W.workspaces).packages);return pe.push(...Qt(G("pnpm-workspace.yaml","yaml").packages)),{language:H.has("package.json")?"typescript":H.has("pyproject.toml")||H.has("requirements.txt")?"python":H.has("go.mod")?"go":H.has("Cargo.toml")?"rust":H.has("composer.json")?"php":H.has("Gemfile")?"ruby":"other",commands:q,packageManager:X?{name:X[1],version:X[2]}:q.packageManager?{name:q.packageManager}:null,lockfiles:B.filter((oe)=>/(^|\/)(bun.lockb?|pnpm-lock.yaml|yarn.lock|package-lock.json|composer.lock|uv.lock|poetry.lock|Pipfile.lock|Cargo.lock|Gemfile.lock)$/.test(oe)),toolchain:V,php:ne,workspaces:[...new Set(pe)].sort(),frameworks:ce,turbo:H.has("turbo.json")||"turbo"in Fe(W.devDependencies)||"turbo"in Fe(W.dependencies),services:se,unsupportedServices:me,envKeys:[...te].sort(),envHosts:re,...Se?{devcontainer:Se}:{},warnings:U}}import{createHash as Nn}from"node:crypto";import{createReadStream as Op}from"node:fs";import{lstat as Xa,mkdir as Np,readFile as Rn,readdir as Fp,readlink as Lp,realpath as Ya,stat as Za,writeFile as Hp}from"node:fs/promises";import{basename as Ot,dirname as Mp,join as Fn,relative as Er,resolve as Pr,sep as Dp}from"node:path";import{execFile as Up,spawnSync as Gp}from"node:child_process";import An from"ignore";import{createReadStream as Sp}from"node:fs";import{lstat as en,mkdtemp as xp,readFile as Yo,readdir as xr,rename as jp,rm as Ep,writeFile as Pp}from"node:fs/promises";import{join as Be}from"node:path";import Oa from"ignore";function _n(H,U){if(Array.isArray(U))return U.some((G)=>_n(H,G));if(!U||H.split("/").some((G)=>G===".git"||G===".hlix"))return!1;return H===U||H.startsWith(`${U}/`)}function In(H,U){if(typeof U!=="string")return U?.some((G)=>In(H,G))??!1;return _n(H,U)||U.startsWith(`${H}/`)}function Aa(H,U,G,B){let W=new Map,z=H.length,J=0;for(let V of H){let Z=V.path.indexOf("/"),Q=Z<0?V.path:V.path.slice(0,Z+1),ne=W.get(Q)??{count:0,bytes:0,included:!1};ne.count++,ne.bytes+=V.size??0,ne.included||=_n(V.path,B),W.set(Q,ne),J+=V.size??0}let K=J>G,q=[...W].sort(([V,Z],[Q,ne])=>Number(Z.included)-Number(ne.included)||(K?ne.bytes-Z.bytes:ne.count-Z.count)||V.localeCompare(Q)),X=[];for(let[V,Z]of q){if(z<=U&&J<=G)break;X.push(V),z-=Z.count,J-=Z.bytes}return X}function Vo(H,U){return U.some((G)=>H===G||G.endsWith("/")&&H.startsWith(G))}function Xo(H){return`upload limit; add /${H} to .hlixignore, or try --include ${H.replace(/\/$/,"")}`.slice(0,200)}function Ra(H){if(H.length<=5000)return H;return[...H.slice(0,4999),{path:H[4999].path,reason:`${H.length-4999} additional skipped paths (including this path); full list: hlix import --dry-run --json`}]}var La="# --- managed by Hlix: safe to edit above/below, this block is regenerated ---",Zo="# --- end managed by Hlix ---",jr=new Set(["agent-artifacts",".context",".claude/worktrees"]),_p=/(?:^|\/)(?:Makefile|Dockerfile|Containerfile|Justfile|Rakefile|Gemfile)(?:\.[^/]*)?$/i,Ip=/\.(?:md|txt|json)$/i,Na=/(?:^|\n)\s*(?:\/\/|\/\*+|\*|#|<!--)\s*(?:@generated\b|generated by\b|do not edit\b)|(?:^|\n)\s*\/\/[#@]\s*sourceMappingURL=/i,Fa=/\.(?:log(?:\.\d+)?|tmp|cache|pyc|tsbuildinfo|map)$/i;function $n(H){let U=[...H.matchAll(new RegExp(`^${La}\\r?$`,"gm"))],G=[...H.matchAll(new RegExp(`^${Zo}\\r?$`,"gm"))];if(!U.length&&!G.length)return{before:H,after:"",managed:""};if(U.length!==1||G.length!==1||G[0].index<U[0].index)return null;let B=U[0].index,z=G[0].index+Zo.length,J=H.slice(z).match(/^\r?\n/)?.[0]??"";return{before:H.slice(0,B),after:H.slice(z+J.length),managed:H.slice(B,z)}}function Qo(H){let U=$n(H);return(U?U.before+`
288
- `+U.after:H).split(/\r?\n/).filter((G)=>G.startsWith("!")&&G.length>1).map((G)=>G.slice(1))}async function Ha(H,U){let G=Be(H,".hlixignore"),B="";try{let W=await en(G).catch((ee)=>{if(ee.code==="ENOENT")return null;throw ee});if(W&&!W.isFile())return{warning:"Kept .hlixignore unchanged: managed rules require a regular file."};if(W)B=await Yo(G,"utf8");let z=$n(B);if(!z)return{warning:"Kept .hlixignore unchanged: repair its managed-block markers before refreshing."};let J=Qo(B),K=Oa().add(J),q=[],X=[],V=Oa(),Z=new Set;for(let ee of U.tracked){let le=ee.split("/");while(le.length)Z.add(le.join("/")),le.pop()}let Q=0,ne=0,ce=()=>Q<30000&&ne<268435456,te=(ee)=>Z.has(ee)||In(ee,U.includes)||J.some((le)=>{let be=le.replace(/^\//,"").split(/[?*[\\]/)[0];return!be||be.startsWith(`${ee}/`)||K.ignores(`${ee}/`)||K.ignores(ee)}),re=async(ee,le,be=!1)=>{if(U.signal?.throwIfAborted(),!ce()||te(ee)||U.protectedPath(ee,le))return!1;Q++;let Ee=await en(Be(H,ee));if(Ee.isSymbolicLink())return le;if(Ee.isDirectory()){let _e=(await xr(Be(H,ee))).sort();for(let Re of _e){if(Re===".git")continue;if(!await re(`${ee}/${Re}`,le,be))return!1}return!0}if(!Ee.isFile()||ne+Ee.size>268435456)return!1;let Pe="",Oe="";for await(let _e of Sp(Be(H,ee),{encoding:"utf8",signal:U.signal})){if(ne+=Buffer.byteLength(_e),Pe.length<4096)Pe+=_e.slice(0,4096-Pe.length);let Re=Oe+_e;if(U.protectedContent(ee,Re))return!1;Oe=Re.slice(-4096)}return le||Na.test(Pe)||Na.test(Oe)||!_p.test(ee)&&!/^#!|^<\?php/.test(Pe)&&(be&&Ip.test(ee)||Fa.test(ee))},ae=new Set,se=async(ee,le=[],be=!1)=>{if(U.signal?.throwIfAborted(),!ce())return;let Ee=Be(H,ee),Pe=await xr(Ee,{withFileTypes:!0}),Oe=async(ke)=>Pe.find((Ce)=>Ce.name===ke)?.isFile()&&(await en(Be(Ee,ke))).size<1048576?Yo(Be(Ee,ke),"utf8"):null,_e=await Oe("package.json"),Re=await Oe("composer.json"),Ie=!1,Nt=new Set;try{let ke=JSON.parse(await Oe("composer.lock")??"null");Ie=Array.isArray(ke?.packages);for(let ve of[...ke?.packages??[],...ke?.["packages-dev"]??[]]){if(typeof ve.name==="string")Nt.add(ve.name);if(ve.dist?.type==="path")Ie=!1}}catch{}try{let ke=JSON.parse(_e??"{}"),ve=Array.isArray(ke.workspaces)?ke.workspaces:ke.workspaces?.packages;for(let Ce of Array.isArray(ve)?ve:[]){if(typeof Ce!=="string"||Ce.startsWith("!"))continue;let bt=(ee?`${ee}/`:"")+Ce.replace(/^\.\//,"");X.push(bt),V.add(bt)}}catch{}let Ft=[_e,Re].filter(Boolean).join(`
289
- `),dt={};for(let ke of Pe){if(!/^(?:(?:vite|next|nuxt|astro|webpack|rollup)\.config\.[cm]?[jt]s|tsconfig(?:\.[^/]*)?\.json|turbo\.json|pyproject\.toml|setup\.py)$/.test(ke.name))continue;let ve=await Oe(ke.name);if(ve!==null)dt[ke.name]=ve}let Lt={packageJson:_e,rootFiles:Pe.map((ke)=>ke.name),configFiles:dt};be||=qo(dt);let Gn=Ca(Lt);for(let ke of Ko(Lt))ae.add(ee?`${ee}/${ke}`:ke);let vt=new Set([...Gn,...le]);for(let ke of Pe.sort((ve,Ce)=>ve.name<Ce.name?-1:ve.name>Ce.name?1:0)){if([".git",".hlix",".hlixignore"].includes(ke.name)||ke.isSymbolicLink())continue;let ve=ee?`${ee}/${ke.name}`:ke.name;if(/[\n\r\\*?[\]!#]/.test(ve)||ve.endsWith(" "))continue;if(Q++,!ce())return;if(ke.isDirectory()){let Ce=await en(Be(H,ve,".git")).then(()=>U.isRepository(ve),()=>!1),bt=jr.has(ve)||[...jr].some((ze)=>ve.startsWith(`${ze}/`)),Bn=U.gitIgnored.directories.some((ze)=>`${ve}/`.startsWith(ze)),kt=V.ignores(`${ve}/`)||X.some((ze)=>ze.split(/[?*[\\]/)[0].startsWith(`${ve}/`))||Ft.includes(ke.name)||/(?:^|\/)(?:src|lib|apps|packages|tests|resources|public)(?:\/|$)/.test(ve),Ht=Ce&&(bt||Bn)&&!kt;if(ke.name==="vendor"&&Ie)for(let ze of await xr(Be(H,ve),{withFileTypes:!0})){if(["autoload.php","composer","bin"].includes(ze.name))continue;if(!ze.isDirectory()){Ie=!1;break}for(let an of await xr(Be(H,ve,ze.name)))if(!Nt.has(`${ze.name}/${an}`))Ie=!1}let pt=Gn.includes(ke.name)&&(ke.name==="node_modules"||ke.name==="vendor"&&Ie&&!/"type"\s*:\s*"path"/.test(Re??"")),Wn=ae.has(ve)||be&&ke.name.endsWith(".egg-info");if(((ke.name==="node_modules"||ke.name==="vendor"?pt:vt.has(ke.name))||jr.has(ve)&&!kt||["logs","runtime","tmp"].includes(ke.name)||Ht||Wn)&&!te(ve)&&await re(ve,pt||Ht||Wn,vt.has(ke.name)||jr.has(ve))){q.push(`/${ve}/`);continue}if(!Ce&&!["node_modules","vendor"].includes(ke.name))await se(ve,vt.has("__pycache__")?["__pycache__"]:[],be)}else if(ke.isFile()&&(Fa.test(ke.name)||(await en(Be(H,ve))).size>U.maxFileBytes)&&!te(ve)&&await re(ve,!1))q.push(`/${ve}`)}};await se("");let me=B.includes(`\r
290
- `)?`\r
291
- `:`
292
- `,fe=[La,...q.sort(),Zo,""].join(me),pe=z.before+(z.before&&!z.before.endsWith(`
293
- `)?me:"")+fe+z.after;if(U.write!==!1&&pe!==B){let ee=await xp(Be(H,".hlixignore-"));try{let le=Be(ee,"rules");await Pp(le,pe,{mode:W?.mode??420});let be=await en(G).catch((Ee)=>{if(Ee.code==="ENOENT")return null;throw Ee});if(be?!be.isFile()||be.ino!==W?.ino||be.dev!==W?.dev||await Yo(G,"utf8")!==B:W!==null)return{warning:"Kept .hlixignore unchanged: it changed while generated paths were being checked."};await jp(le,G)}finally{await Ep(ee,{recursive:!0,force:!0})}}let oe=q.every((ee)=>ee.endsWith("/"))?"generated folders":"generated paths";return{rules:q,report:`Hlix ignored ${q.length} ${oe} — see .hlixignore`}}catch(W){return U.signal?.throwIfAborted(),{warning:`Kept .hlixignore unchanged: could not safely refresh generated paths (${W.code??"unreadable"}).`}}}import{readFile as Cp}from"node:fs/promises";import{join as Tp}from"node:path";function $p(H){let U=H.trim();if(!U||/^[|>[{]/.test(U))return null;let G=U.match(/^(["'])([\s\S]*)\1$/);if(!G&&/^["']/.test(U))return null;return(G?G[2].trim():U.replace(/(?:^|\s)#.*$/,"").trim())||null}function Ma(H){let U=H.split(/\r?\n/),G=U.findIndex((J)=>/^tasks:\s*(?:#.*)?$/.test(J));if(G===-1)return{tasks:[],partial:/^tasks:\s*\S/m.test(H)};let B=[],W=!1,z=-1;for(let J of U.slice(G+1)){if(!J.trim()||/^\s*#/.test(J))continue;let K=J.length-J.trimStart().length,q=J.match(/^(\s*-(?:\s+|$))(.*)$/);if(q){if(z!==-1&&K>=z)continue;if(B.push({}),z=q[2]?q[1].length:-1,!q[2])continue}else if(K===0)break;else if(B.length===0)continue;else if(z===-1)z=K;else if(K!==z)continue;let X=(q?q[2]:J.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!X)continue;let V=X[1];if(V!=="name"&&V!=="before"&&V!=="init"&&V!=="command")continue;let Z=$p(X[2]);if(Z===null)W=!0;else B[B.length-1][V]=Z}return{tasks:B,partial:W}}async function Rt(H,U){try{return await Cp(Tp(H,...U.split("/")),"utf8")}catch(G){if(G.code==="ENOENT")return null;throw G}}function Da(H){try{let U=H.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(U)}catch{return null}}function ht(H){if(typeof H==="string"&&H.trim())return[H.trim()];if(Array.isArray(H))return H.flatMap(ht);if(H&&typeof H==="object")return Object.values(H).flatMap(ht);return[]}function es(H){if(!H||typeof H!=="object")return[];return Object.keys(H).filter((U)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(U))}function Ap(H,U){let G=new Set,B=[/\bprocess\.env\.([A-Za-z_][A-Za-z0-9_]*)/g,/\bimport\.meta\.env\.([A-Za-z_][A-Za-z0-9_]*)/g,/\bos\.(?:getenv|environ\.get)\(\s*["']([A-Za-z_][A-Za-z0-9_]*)/g,/\bos\.Getenv\(\s*["']([A-Za-z_][A-Za-z0-9_]*)/g,/\bENV\[\s*["']([A-Za-z_][A-Za-z0-9_]*)/g];if(U)B.push(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::[-?][^}]*)?\}/g);for(let W of B)for(let z of H.matchAll(W))G.add(z[1]);return[...G]}function Rp(H,U){if(H.has("bun.lock")||H.has("bun.lockb")||U?.startsWith("bun@"))return"bun install";if(H.has("pnpm-lock.yaml")||U?.startsWith("pnpm@"))return"pnpm install";if(H.has("yarn.lock")||U?.startsWith("yarn@"))return"yarn install";if(H.has("package.json"))return"npm install";return null}function Ua(H){let U=typeof H==="number"?H:Number(H);return Number.isInteger(U)&&U>0&&U<=65535?U:null}function Ke(H,U,G){if(!H.some((B)=>B.path===U&&B.kind===G))H.push({path:U,kind:G})}async function Ga(H,U,G){let B=[],W=[],z=[],J=[],K=new Map,q=new Set,X=new Set,V=[],Z={},Q=null,ne=0,ce=await Rt(H,".cursor/environment.json");if(ce){Ke(B,".cursor/environment.json","cursor");let pe=Da(ce);if(!pe)V.push("Could not parse .cursor/environment.json; it remains quarantined.");else{W.push(...ht(pe.install));let oe=ht(pe.start);if(oe[0])Q=oe[0];if(Array.isArray(pe.terminals))for(let ee of pe.terminals){if(!ee||typeof ee!=="object")continue;let le=ee;if(typeof le.command!=="string"||!le.command.trim())continue;J.push({name:typeof le.name==="string"&&le.name.trim()?le.name.trim():"Terminal",command:le.command.trim(),...typeof le.cwd==="string"&&le.cwd.trim()?{cwd:le.cwd.trim()}:{}})}}}let te=U.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":U.has("devcontainer.json")?"devcontainer.json":null;if(te){Ke(B,te,"devcontainer");let pe=Da(G.get(te)??await Rt(H,te)??"");if(!pe)V.push(`Could not parse ${te}; it remains quarantined.`);else{W.push(...ht(pe.onCreateCommand),...ht(pe.updateContentCommand),...ht(pe.postCreateCommand));let oe=ht(pe.postStartCommand);if(!Q&&oe[0])Q=oe[0];for(let ee of es(pe.secrets))q.add(ee);for(let ee of[...es(pe.containerEnv),...es(pe.remoteEnv)])q.add(ee);if(Array.isArray(pe.forwardPorts))for(let ee of pe.forwardPorts){let le=Ua(ee);if(le)K.set(le,{port:le,visibility:"private"})}}}if(U.has(".gitpod.yml")){Ke(B,".gitpod.yml","gitpod");let pe=G.get(".gitpod.yml")??await Rt(H,".gitpod.yml");if(pe===null)V.push("Could not read .gitpod.yml; its task commands were not imported.");else{let oe=Ma(pe);ne=oe.tasks.filter((ee)=>ee.before).length;for(let ee of oe.tasks){if(ee.before)W.push(ee.before);if(ee.init)W.push(ee.init);if(!ee.command)continue;if(!Q)Q=ee.command;else J.push({name:ee.name??"Terminal",command:ee.command})}if(oe.partial)V.push("Some .gitpod.yml task values are not plain `key: value` scalars and were not imported; review .gitpod.yml before approving cloud setup.")}}for(let pe of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(U.has(pe))Ke(B,pe,"docker");for(let pe of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(U.has(pe))Ke(B,pe,"buildpack");for(let pe of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(U.has(pe))Ke(B,pe,"platform");let re=G.get("package.json")??await Rt(H,"package.json");if(re){Ke(B,"package.json","package");try{let pe=JSON.parse(re);if(pe.engines?.node)Z.node=pe.engines.node;let oe=Rp(U,pe.packageManager);if(oe&&W.length===ne)W.push(oe);if(pe.scripts?.build&&z.length===0)z.push(`${pe.packageManager?.split("@")[0]??(U.has("bun.lock")?"bun":"npm")} run build`);let ee=pe.scripts?.dev?`${U.has("bun.lock")?"bun":"npm"} run dev`:null,le=pe.scripts?.start?`${U.has("bun.lock")?"bun":"npm"} run start`:ee;if(!Q&&le)Q=le}catch{V.push("Could not parse package.json for environment discovery.")}}if(U.has("uv.lock"))W.push("uv sync --frozen");else if(U.has("poetry.lock"))W.push("poetry install --no-interaction");else if(U.has("requirements.txt"))W.push("python -m pip install -r requirements.txt");if(U.has("go.mod"))W.push("go mod download");if(U.has("Procfile")){Ke(B,"Procfile","procfile");let oe=(G.get("Procfile")??"").split(/\r?\n/).find((ee)=>/^web\s*:/.test(ee));if(oe)Q=oe.replace(/^web\s*:\s*/,"").trim()||Q}let ae=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[pe,oe]of ae){let ee=(G.get(pe)??await Rt(H,pe))?.trim();if(ee)Z[oe]=ee,Ke(B,pe,"tool-version")}let se=G.get(".tool-versions")??await Rt(H,".tool-versions");if(se){Ke(B,".tool-versions","tool-version");for(let pe of se.split(/\r?\n/)){let[oe,ee]=pe.trim().split(/\s+/,2);if(!ee)continue;if(oe==="nodejs")Z.node=ee;else if(oe==="python")Z.python=ee;else if(oe==="bun")Z.bun=ee}}let me=G.get("mise.toml")??await Rt(H,"mise.toml");if(me){Ke(B,"mise.toml","tool-version");for(let pe of me.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))Z[pe[1]]=pe[2]}for(let[pe,oe]of G){let ee=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(pe)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(pe);for(let le of Ap(oe,ee))X.add(le);for(let le of oe.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let be=Ua(le[1]);if(be)K.set(be,{port:be,visibility:"private"})}}if(B.length===0&&U.size>0)Ke(B,"repository","detected");let fe=(pe)=>[...new Set(pe.filter(Boolean))],Se=B.length+W.length+(Q?1:0);return{sources:B.sort((pe,oe)=>pe.path.localeCompare(oe.path)),toolchain:Z,install:fe(W),build:fe(z),start:Q,terminals:J,ports:[...K.values()].sort((pe,oe)=>pe.port-oe.port),requiredSecretKeys:[...q].sort(),observedSecretKeys:[...X].sort(),confidence:Se>=4?"high":Se>=2?"medium":"low",warnings:V}}var Ba=2;var Qa=300000,Bp=25000,Wa=52428800,Wp=524288000,On=1e4,zp="Potential secrets exist in Git history",Jp="Never delete .git folders or files to get past this; use .hlixignore instead.",_r=1048576,Cn=20971520,ec=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store",...qt],Xy=An().add(ec);var os="Required project environment value was not found locally: ",Kp=/(^|\/)\.env\.(example|sample|template)$/i,qp=/(^|\/)\.env(?:\.[^/]+)?$/i,Vp=/(^|\/)(?:\.envrc|\.netrc|\.npmrc|\.pypirc|credentials(?:\.[^/]+)?(?:\.json|\.toml)?|service-account[^/]*\.json|firebase-adminsdk[^/]*\.json|application_default_credentials\.json|\.docker\/config\.json|\.cargo\/credentials(?:\.toml)?|\.gem\/credentials|\.bundle\/config|(?:pip|pypi)\.conf|\.aws\/credentials|[^/]+\.(?:pem|key|p12|pfx)|[^/]*\.(?:auto\.)?tfvars(?:\.json)?|application[^/]*\.(?:properties|ya?ml)|(?:local|keystore|gradle|secrets?)\.properties|appsettings[^/]*\.json|local\.settings\.json|config\/database\.ya?ml|wrangler\.toml|fly\.toml|serverless\.ya?ml|(?:credentials|secrets?)[^/]*\.(?:json|ya?ml|toml|ini|conf|cfg))$/i,Xp=/\.(?:example|sample|template)$/i,Yp=/(^|\/)\.(?:npmrc|yarnrc(?:\.yml)?|pypirc)$/i,Zp=/(?:^|\/)(?:__tests__|tests?|fixtures)\/|\.(?:test|spec)\.[^/]+$|\.snap$/i,Qp=/\.(?:md|mdx|txt|rst)$/i,eu=/fake|dummy|example|placeholder|unused|changeme|xxxx|redacted|your[_-]|<[^>]*>/i,tu=/^(.)\1+$/,nu=/RegExp\(/,ss="BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY|npm_[A-Za-z0-9]{30,}|gh[opusr]_[A-Za-z0-9_]{30,}|AKIA[0-9A-Z]{16}|xox[baprs]-[A-Za-z0-9-]{20,}",ru=new RegExp(ss,"g"),ou=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,su=/(^|\/)(?:\.agents|\.claude)\/skills\//i,Tn=new Set(["HLIX_AGENT_RUN_ID","HLIX_API_KEY","HLIX_API_URL","HLIX_BASE_URL","HLIX_PROJECT_ID","HLIX_SESSION_TOKEN","HLIX_WORKSPACE_ID"]),ts="Your hlix credentials were left out of the project's secrets — the platform provides them.",ns=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]),iu=100,za=12;function au(H){let U=H.slice(0,za).join(", "),G=H.length-za;return H.length===1?`Observed environment reference has no local value: ${H[0]}`:`${H.length} observed environment references have no local value: ${U}${G>0?`, +${G} more`:""}`}var cu=250;function yt(H){return H.split(Dp).join("/")}function lt(H){if(H>=1048576)return`${(H/1048576).toFixed(1)} MB`;if(H>=1024)return`${(H/1024).toFixed(1)} KB`;return`${H} bytes`}function Ja(H,U=5){return[...H].sort((G,B)=>B.size-G.size||G.path.localeCompare(B.path)).slice(0,U).map((G)=>`${G.path} (${lt(G.size)})`).join(", ")}function lu(H,U=5){let G=new Map;for(let B of H){let W=B.indexOf("/"),z=W===-1?".":B.slice(0,W);G.set(z,(G.get(z)??0)+1)}return[...G].sort((B,W)=>W[1]-B[1]||B[0].localeCompare(W[0])).slice(0,U).map(([B,W])=>`${B}/ (${W} files)`).join(", ")}function qe(H,U,G=10485760){return Gp("git",["-C",H,...U],{encoding:"utf8",timeout:Qa,maxBuffer:G,stdio:["ignore","pipe","pipe"]})}function m(H,U,G={}){return new Promise((B)=>{Up("git",["-C",H,...U],{encoding:"utf8",timeout:Qa,maxBuffer:G.maxBuffer??10485760,...G.signal?{signal:G.signal}:{}},(W,z)=>{let J=W?.code;B({status:W===null?0:typeof J==="number"?J:1,stdout:typeof z==="string"?z:""})})})}async function du(H){let U=Nn("sha256");for await(let G of Op(H))U.update(G);return U.digest("hex")}function rs(H){if(Array.isArray(H))return`[${H.map(rs).join(",")}]`;if(H&&typeof H==="object")return`{${Object.entries(H).sort(([U],[G])=>U.localeCompare(G)).map(([U,G])=>`${JSON.stringify(U)}:${rs(G)}`).join(",")}}`;return JSON.stringify(H)}function tc(H){let U={};for(let[G,B]of String(H).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let W=B.trim();if(!W||W.startsWith("#"))continue;let J=(W.startsWith("export ")?W.slice(7).trimStart():W).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!J)throw Error(`Invalid dotenv assignment on line ${G+1}`);let K=J[2]??"";if(K.startsWith('"')){if(!K.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${G+1}`);K=K.slice(1,-1).replace(/\\n/g,`
294
- `).replace(/\\r/g,"\r")}else if(K.startsWith("'")){if(!K.endsWith("'"))throw Error(`Unclosed dotenv quote on line ${G+1}`);K=K.slice(1,-1)}else K=K.replace(/\s+#.*$/,"").trimEnd();U[J[1]]=K}return U}function pu(H,U){return H.split(/(?<=\n)/).filter((G)=>{let B=G.trim(),z=(B.startsWith("export ")?B.slice(7).trimStart():B).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=/)?.[1];return z===void 0||!U.has(z)}).join("")}function uu(H){let U=null;for(let G=0;G<H.length;G+=1){let B=H[G];if(B==="\\"&&U!=="single"){if(H[G+1]!=="$")return!0;G+=1;continue}if(B==="'"&&U!=="double"){U=U==="single"?null:"single";continue}if(B==='"'&&U!=="single"){U=U==="double"?null:"double";continue}if(U!=="single"&&(B==="$"||B==="`"))return!0;if(U===null&&(B==="<"||B===">")&&H[G+1]==="(")return!0}return U!==null}function mu(H){let U={},G=new Set,B=new Set;for(let W of String(H).replace(/^\uFEFF/,"").split(/\r?\n/)){let z=W.trim();if(!z||z.startsWith("#"))continue;let K=(z.startsWith("export ")?z.slice(7).trimStart():z).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!K)continue;let q=K[1],X=K[2]??"";if(G.add(q),uu(X)){delete U[q],B.add(q);continue}try{let Z=tc(`${q}=${X}`)[q];if(Z===void 0)throw Error("missing literal");U[q]=X.trimStart().startsWith("'")?Z:Z.replace(/\\\$/g,"$"),B.delete(q)}catch{delete U[q],B.add(q)}}return{values:U,keys:[...G].sort(),dynamicKeys:[...B].sort()}}async function fu(H){let U=qe(H,["rev-parse","--show-toplevel"]);if(U.status!==0)return!1;try{return await Ya(U.stdout.trim())===H}catch{return!1}}function gu(H,U){if(!U)return new Set;let G=qe(H,["ls-files","-z"]);if(G.status!==0)throw Error("Could not enumerate tracked files.");return new Set(G.stdout.split("\x00").filter(Boolean).map(yt))}function hu(H,U){if(!U)return[];let G=qe(H,["config","--get-regexp","^remote\\..*\\.url$"]);if(G.status!==0)return[];let B=[];for(let W of G.stdout.split(`
295
- `)){let z=W.trim();if(!z)continue;let J=/^remote\.(.*)\.url (.+)$/.exec(z);if(J)B.push({name:J[1],url:J[2]})}return B}function yu(H,U){if(!U)return{files:new Set,directories:[]};let G=qe(H,["ls-files","-z","--others","--ignored","--exclude-standard","--directory"]);if(G.status!==0)throw Error("Could not enumerate ignored files.");let B=new Set,W=[];for(let z of G.stdout.split("\x00").filter(Boolean)){let J=yt(z);if(J.endsWith("/"))W.push(J);else B.add(J)}return{files:B,directories:W}}async function Ka(H,U){let G=[],B=[],W=[],z="";for(let V of[".gitignore",".hlixignore"])try{let Z=Fn(H,V),Q=await Xa(Z);if(V===".gitignore"&&Q.isSymbolicLink()){B.push(V);continue}if(Q.isFile()||Q.isSymbolicLink())try{if(Q.isSymbolicLink()&&!(await Za(Z)).isFile()){G.push(V);continue}let ne=await Rn(Z,"utf8");if(V===".hlixignore")z=ne;let ce=V===".hlixignore"?$n(ne):null;if(U&&ce?.managed)ne=ne.replace(ce.managed,U.join(`
296
- `));W.push(ne)}catch{G.push(V)}}catch(Z){if(Z.code!=="ENOENT")G.push(V)}let J=$n(z)?.managed??"",K=[".git/",".hlix/",...qt],q=J?K:ec,X=Qo(z);return{hardMatcher:An().add(X.length?K:q),matcher:An().add([...q,...W.flatMap((V)=>V.split(/\r?\n/))]),unignored:An().add(X),managedMatcher:An().add(U??J),hasManaged:Boolean(J),unreadable:G,symlinked:B}}function Ir(H){if(ou.test(H))return"mcp";if(su.test(H))return"skill";return null}function $r(H){if(qp.test(H)&&!Kp.test(H))return"dotenv";if(Vp.test(H))return"credential";return null}function wu(H,U){if(U)return[yt(U)];let G=new Map([[".env",0],[".env.development",1],[".env.local",2],[".env.development.local",3]]),B=H.filter((W)=>G.has(Ot(W).toLocaleLowerCase("en-US"))).sort((W,z)=>W.slice(0,-Ot(W).length).localeCompare(z.slice(0,-Ot(z).length))||G.get(Ot(W).toLocaleLowerCase("en-US"))-G.get(Ot(z).toLocaleLowerCase("en-US")));return B.length>0?B:H.length===1?[...H]:[]}function vu(H,U){try{let G=JSON.parse(U);if(!G.mcpServers||typeof G.mcpServers!=="object")return[];return Object.entries(G.mcpServers).map(([B,W])=>{let z=W&&typeof W==="object"?W:{},J=z.type==="http"||z.type==="sse"||z.type==="stdio"?z.type:typeof z.command==="string"?"stdio":typeof z.url==="string"?"http":"unknown",K=z.env&&typeof z.env==="object"?z.env:{};return{sourcePath:H,name:B,transport:J,...typeof z.command==="string"?{command:z.command}:{},...Array.isArray(z.args)&&z.args.every((q)=>typeof q==="string")?{args:z.args}:{},...typeof z.url==="string"?{url:z.url}:{},envKeys:Object.keys(K).sort(),enabled:!1}})}catch{return[]}}function bu(H){let U=!1,G=!1;for(let B of H.split(/\r?\n/)){let W=B.trim();if(!W||W.startsWith("#")||W.startsWith(";")||W.startsWith("["))continue;let z=W.indexOf("=");if(z===-1)continue;let J=W.slice(0,z).trim().toLowerCase(),K=W.slice(z+1).trim().replace(/^["']|["']$/g,"");if(!K||/^\$(?:\{[^}]*\}|[A-Za-z_][A-Za-z0-9_]*)$/.test(K))continue;if(J.endsWith("_authtoken")||J.endsWith("_password"))return!0;if(J.endsWith("password"))G=!0;else if(J.endsWith("username"))U=!0}return U&&G}async function ku(H,U,G,B){if(Xp.test(G))return!1;if(!Yp.test(G))return!0;let W=await m(H,["show",`${U}:${G}`],{...B?{signal:B}:{}});return W.status===0&&bu(W.stdout)}function Su(H,U,G){let B=H.lastIndexOf("/",U),W=H.indexOf("/",G);return B!==-1&&W!==-1&&!/\s/.test(H.slice(B,U)+H.slice(G,W))}function xu(H){if(Zp.test(H))return"test fixture";if(Qp.test(H))return"documentation or pattern definition";return null}function ju(H,U){let G=null;for(let B of H.split(/\r?\n/))for(let W of B.matchAll(U)){let z=W[0],J=W.index??0,K=nu.test(B)||Su(B,J,J+z.length)?"documentation or pattern definition":eu.test(z)||tu.test(z)?"placeholder value":null;if(K===null)return null;G??=K}return G}async function Eu(H,U,G,B){let W=xu(G);if(W!==null)return W;let z=await m(H,["show",`${U}:${G}`],{...B?{signal:B}:{}});return z.status===0?ju(z.stdout,ru):null}async function qa(H,U,G){let B=[],W="unknown";for(let z of H.split(/\r?\n/)){if(z.startsWith("@@"))W=z.slice(2);else if(z.trim()){let J=yt(z.trim());if(await G(W,J))B.push({commit:W,path:J,reason:U})}if(B.length>=100)break}return B}async function Va(H,U,G={}){if(!U)return{head:null,branch:null,refs:[],commitCount:0,complete:!0,findings:[],blockingFindings:[],waivedReasons:[]};let B=qe(H,["rev-parse","HEAD"]).stdout.trim()||null,W=qe(H,["symbolic-ref","--short","-q","HEAD"]),z=W.status===0?W.stdout.trim()||null:null,J=Number.parseInt(qe(H,["rev-list","--count","--all"]).stdout.trim(),10)||0,K=qe(H,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]),q=K.stdout.split(`
297
- `).filter(Boolean).map((ae)=>{let[se,me]=ae.split("\x00");return{name:se,oid:me}}).filter(({name:ae,oid:se})=>/^refs\/(?:heads|tags)\/.+/.test(ae)&&/^[0-9a-f]{40,64}$/.test(se)).sort((ae,se)=>ae.name.localeCompare(se.name)),X=G.signal,V=X?{signal:X}:{};G.onProgress?.(`history: ${J} commit${J===1?"":"s"}…`);let Z=["log","--all",`--max-count=${On}`,"--pretty=format:@@%H","--name-only"],Q=await m(H,[...Z,"--",".env",".env.*","*.pem","*.key",".npmrc","*.tfvars"],V),ne=await m(H,["log","--all",`--max-count=${On}`,"-G",ss,"--pretty=format:@@%H","--name-only"],V);X?.throwIfAborted();let ce=new Map;for(let ae of[...await qa(Q.stdout,"sensitive-path",(se,me)=>ku(H,se,me,X)),...await qa(ne.stdout,"secret-pattern",async()=>!0)])ce.set(`${ae.commit}:${ae.path}:${ae.reason}`,ae);let te=[...ce.values()].slice(0,100),re=new Map;for(let ae of te){if(ae.reason!=="secret-pattern")continue;let se=await Eu(H,ae.commit,ae.path,X);if(se!==null)re.set(ae,se)}return G.onProgress?.(`history: ${J} commit${J===1?"":"s"} scanned`),{head:B,branch:z,refs:q,commitCount:J,complete:J<=On&&q.length<=1000&&K.status===0&&Q.status===0&&ne.status===0,findings:te,blockingFindings:te.filter((ae)=>!re.has(ae)),waivedReasons:[...re.values()]}}function Pu(H,U){let G=U?.XDG_CACHE_HOME??(U?.HOME?Fn(U.HOME,".cache"):null);if(!G)return null;return Fn(G,"hlix","history",`${Nn("sha256").update(H).digest("hex")}.json`)}async function _u(H,U,G){let B=U?Pu(H,G.environment):null;if(!B)return Va(H,U,G);let W=Nn("sha256").update([qe(H,["for-each-ref","--format=%(refname)%00%(objectname)"]).stdout,qe(H,["rev-parse","HEAD"]).stdout,qe(H,["symbolic-ref","--short","-q","HEAD"]).stdout,ss,String(On)].join("\x00")).digest("hex");try{let J=JSON.parse(await Rn(B,"utf8"));if(J.key===W&&J.history)return G.onProgress?.(`history: ${J.history.commitCount} commits, unchanged since the last scan`),J.history}catch{}let z=await Va(H,U,G);if(z.complete)try{await Np(Mp(B),{recursive:!0,mode:448}),await Hp(B,JSON.stringify({key:W,history:z}),{mode:384})}catch{}return z}async function tt(H,U={}){let G=await Ya(Pr(H));if(!(await Za(G)).isDirectory())throw Error("Import target must be a directory.");let B=await fu(G),W=hu(G,B),z=gu(G,B),J=new Set(B?(await m(G,["ls-files","--stage","-z"])).stdout.split("\x00").filter((ie)=>ie.startsWith("160000 ")).map((ie)=>ie.slice(ie.indexOf("\t")+1)):[]),K=yu(G,B),q=[...new Set([...a(G)?.includedPaths??[],...U.include?[U.include]:[]].map((ie)=>ie.replace(/^\.\//,"").replace(/\/$/,"")))],X=await Ka(G),V=U.refreshIgnore||X.hasManaged?await Ha(G,{write:U.refreshIgnore===!0,tracked:B?z:new Set((await m(G,["ls-files","-z"])).stdout.split("\x00").filter(Boolean)),includes:q,gitIgnored:K,signal:U.signal,maxFileBytes:U.maxFileBytes??Wa,isRepository:async(ie)=>{let ye=await m(Fn(G,ie),["rev-parse","--show-toplevel"]);return ye.status===0&&Pr(ye.stdout.trim())===Pr(G,ie)},protectedPath:(ie,ye)=>Boolean($r(ie)||!ye&&Ir(ie)),protectedContent:(ie,ye)=>Sn(ie,ye)}):void 0,{hardMatcher:Z,matcher:Q,unignored:ne,managedMatcher:ce,unreadable:te,symlinked:re}=V?await Ka(G,V.rules??[]):X,ae=te.length?`Upload left unchanged: cannot read ${te.join(", ")}; check the ignore file target and permissions before retrying.`:void 0,se=[],me=[],fe=[],Se=[],pe=[],oe=[],ee=[],le=[],be=U.envFile?yt(Er(G,Pr(G,U.envFile))):void 0,Ee=be!==void 0&&be!==""&&be!==".."&&!be.startsWith("../");if(U.envFile&&!Ee)le.push(`Selected environment file must stay inside the project: ${U.envFile}`);let Pe=new Map,Oe=new Map,_e=new Map,Re=new Map,Ie=V?.warning?[V.warning]:[],Nt=new Set,Ft=[],dt=[],Lt=new Map,Gn=U.maxFiles??Bp,vt=U.maxFileBytes??Wa,ke=U.maxTotalBytes??Wp,ve=U.historyMode==="sanitize",Ce=0,bt=0,Bn=async(ie,ye=!1)=>{let Te=await Fp(ie,{withFileTypes:!0}).catch((Me)=>{let Ue=yt(Er(G,ie))||"repository";if(ee.push({path:Ue,reason:`Cannot read folder (${Me.code??"unreadable"}); check read and search permissions`}),Ie.push(`Cannot read folder ${Ue}; check its read and search permissions. Existing cloud files are preserved.`),ie===G)ae="Upload left unchanged: cannot read the project folder; check its permissions.";return[]});Te.sort((Me,Ue)=>Me.name.localeCompare(Ue.name));for(let Me of Te){if(U.signal?.throwIfAborted(),bt+=1,bt%cu===0)U.onProgress?.(`scanning … ${se.length} files`);let Ue=Fn(ie,Me.name),we=yt(Er(G,Ue));if(Me.name===".git"){if(we!==".git"&&!ye)Nt.add(yt(Er(G,ie)));continue}if(we.length>1000||we.includes("\\")||we.includes("\x00")){Ie.push(`Skipped a path that cannot be represented safely: ${we.slice(0,350)}`);continue}try{let Le=await Xa(Ue),cn=Me.isDirectory()?`${we}/`:we,Qs=z.has(we)&&!J.has(we),ln=!(_n(we,q)||ne.ignores(cn))&&!Qs&&(Q.ignores(cn)||K.files.has(we)||K.directories.some(($e)=>cn.startsWith($e))),ei=!In(we,q)&&Z.ignores(cn);if(ei){if(we!==".hlix")ee.push({path:we,reason:"built-in ignore"});continue}if(ln&&ce.ignores(cn))ee.push({path:we,reason:"Hlix-managed ignore"});if(Le.isSymbolicLink()){if(ln)continue;if(me.push({path:we,target:await Lp(Ue)}),Ir(we)||$r(we))fe.push(we);continue}if(Me.isDirectory()){if(ei)continue;if(J.has(we)&&!ln)Nt.add(we);await Bn(Ue,ln);continue}let Mt=Ir(we),Dt=$r(we);if(ln&&!Mt&&!Dt)continue;if(!Me.isFile()){ee.push({path:we,reason:"non-regular-file"});continue}if(Le.size>vt&&!Mt&&!Dt){ee.push({path:we,reason:Xo(we)});continue}if(Le.size>vt){le.push(`File ${we} is ${lt(Le.size)}, over the ${lt(vt)} per-file limit. Exclude it with .hlixignore.`);continue}let dn=await du(Ue);if(Mt){if(Le.size>_r){le.push(`Protected configuration ${we} is ${lt(Le.size)}, over the ${lt(_r)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let $e=await Rn(Ue);if(Ce+=$e.byteLength,dt.push({path:we,size:$e.byteLength}),Ce>Cn)continue;if(pe.push({path:we,kind:Mt,size:Le.size,sha256:dn}),Ft.push({path:we,kind:Mt,contentBase64:$e.toString("base64")}),Mt==="mcp")oe.push(...vu(we,$e.toString("utf8")));continue}if(Dt){if(Le.size>_r){le.push(`Protected file ${we} is ${lt(Le.size)}, over the ${lt(_r)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let $e=await Rn(Ue);if(Ce+=$e.byteLength,dt.push({path:we,size:$e.byteLength}),Ce>Cn)continue;let Ut=[],pn=new Set;if(Dt==="dotenv")try{let Jn=tc($e),Gt={};for(let[ut,Bt]of Object.entries(Jn)){if(Tn.has(ut)){pn.add(ut);continue}Gt[ut]=Bt}Pe.set(we,Gt),Ut=Object.keys(Gt).sort()}catch{le.push(`Could not parse environment file: ${we}`)}else if(Ot(we)===".envrc"){let Jn=mu($e),Gt={},ut=new Set,Bt=[];for(let[Ge,Vc]of Object.entries(Jn.values)){if(Tn.has(Ge)){pn.add(Ge);continue}if(ns.has(Ge)){Ie.push(`Ignored ambient runtime assignment in ${we}: ${Ge}`);continue}ut.add(Ge),Gt[Ge]=Vc}Oe.set(we,Gt);for(let Ge of Jn.dynamicKeys){if(Tn.has(Ge)){pn.add(Ge);continue}if(ns.has(Ge)){Ie.push(`Ignored ambient runtime assignment in ${we}: ${Ge}`);continue}ut.add(Ge),Bt.push(Ge)}if(_e.set(we,[...ut].sort()),Re.set(we,Bt.sort()),Ut=[...ut].sort(),Bt.length>0)Ie.push(`Did not execute dynamic .envrc assignments; collect their resolved local values when available: ${Bt.join(", ")}`)}if(pn.size>0)Ie.push(ts),$e=Buffer.from(pu($e.toString("utf8"),pn),"utf8"),dn=Nn("sha256").update($e).digest("hex");Se.push({path:we,kind:Dt,keys:Ut,size:$e.byteLength,sha256:dn}),Ft.push({path:we,kind:Dt,contentBase64:$e.toString("base64")});continue}if(Le.size<=1048576){let $e=await Rn(Ue),Ut=$e.toString("utf8");if(Lt.set(we,Ut),Sn(we,Ut)){if(Ce+=$e.byteLength,dt.push({path:we,size:$e.byteLength}),Ce>Cn)continue;Se.push({path:we,kind:"detected-content",keys:[],size:Le.size,sha256:dn}),Ft.push({path:we,kind:"detected-content",contentBase64:$e.toString("base64")});continue}}se.push({path:we,size:Le.size,sha256:dn,tracked:Qs,executable:(Le.mode&73)!==0})}catch(Le){if(U.signal?.throwIfAborted(),$r(we)||Ir(we))throw Le;ee.push({path:we,reason:`Cannot read file (${Le.code??"unreadable"})`})}}};await Bn(G);let kt=Aa([...se,...me],Math.max(0,Gn-Se.length-pe.length),ke,q);if(kt.length)se=se.filter((ie)=>!Vo(ie.path,kt)),me=me.filter((ie)=>!Vo(ie.path,kt)),ee.push(...kt.map((ie)=>({path:ie.replace(/\/$/,""),reason:Xo(ie)})));if(U.onProgress?.(`scanning … ${se.length} files`),U.onProgress?.(`secrets: ${Se.length+pe.length} files`),U.signal?.throwIfAborted(),fe.length>0){let ie=fe.slice(0,5).join(", "),ye=fe.length-5;Ie.push(`Imported as symlinks, so no content was read or uploaded for them and the cloud recreates the link: ${ie}${ye>0?`, +${ye} more`:""}`)}for(let ie of re)Ie.push(`Ignore file ${ie} is a symlink, so its rules were not applied. Replace it with a regular file inside the project.`);if(ae)Ie.push(ae);if(Ce>Cn)le.push(`Protected project files total ${lt(Ce)}, over the ${lt(Cn)} limit. Largest: ${Ja(dt)}. Move large assets out of skill and config folders, or add them to .hlixignore.`);if(Se.length>2000)le.push(`Project has ${Se.length} environment and credential files, over the 2000 limit. Largest: ${Ja(Se)}. Exclude the ones the cloud project does not need with .hlixignore.`);if(pe.length>5000)le.push(`Project has ${pe.length} agent, skill and MCP files, over the 5000 limit. Largest folders: ${lu(pe.map((ie)=>ie.path))}. Exclude the ones the cloud project does not need with .hlixignore.`);se.sort((ie,ye)=>ie.path.localeCompare(ye.path)),me.sort((ie,ye)=>ie.path.localeCompare(ye.path)),Se.sort((ie,ye)=>ie.path.localeCompare(ye.path)),pe.sort((ie,ye)=>ie.path.localeCompare(ye.path)),oe.sort((ie,ye)=>`${ie.sourcePath}:${ie.name}`.localeCompare(`${ye.sourcePath}:${ye.name}`));let Ht=wu([...Pe.keys()].sort(),Ee?be:void 0);if(U.envFile&&Ee&&!Pe.has(Ht[0]))le.push(`Selected environment file was not found or is not a dotenv file: ${U.envFile}`);let pt=new Map;for(let[ie,ye]of Pe)for(let Te of Object.keys(ye))pt.set(Te,[...pt.get(Te)??[],ie]);for(let[ie,ye]of _e)for(let Te of ye)pt.set(Te,[...pt.get(Te)??[],ie]);let Wn=[...pt].filter(([,ie])=>ie.length>1).map(([ie,ye])=>({key:ie,paths:ye.sort()})).sort((ie,ye)=>ie.key.localeCompare(ye.key)),Xe={};for(let ie of Ht)Object.assign(Xe,Pe.get(ie)??{});let ze=[...Oe.keys()].sort((ie,ye)=>{if(ie===".envrc")return 1;if(ye===".envrc")return-1;return ie.localeCompare(ye)}),an=new Set;for(let ie of ze){let ye=new Set(Re.get(ie)??[]);for(let Te of _e.get(ie)??[]){if(ye.has(Te)){delete Xe[Te],an.add(Te);continue}let Me=Oe.get(ie)?.[Te];if(Me!==void 0)Xe[Te]=Me;an.delete(Te)}}for(let ie of Nt)Ie.push(`${ie} has its own Git repository — uploaded as files, its history not included`);let zc=U.historyMode==="abort_on_findings"?"abort_on_findings":"preserve";if(ve)Ie.push("Git history omitted; uploading a snapshot of the current files.");let Je=await _u(G,B,U);if(!Je.complete)Ie.push(`Git history scan exceeded ${On} commits or failed; history is preserved, but the findings may be incomplete.`);if(B&&!Je.head)ve=!0,Ie.push("Git has no readable HEAD; uploading the current files as a snapshot.");let qs=Je.waivedReasons;for(let ie of[...new Set(qs)].sort()){let ye=qs.filter((Me)=>Me===ie).length,Te=ye===1;Ie.push(`${ye} Git history finding${Te?"":"s"} did not block this import — ${ie}, not ${Te?"a real credential":"real credentials"}; --history preserve is not needed for ${Te?"it":"them"}.`)}if(Je.blockingFindings.length>0){let ie=Je.blockingFindings.length;Ie.unshift([`${zp} (${ie} finding${ie===1?"":"s"}${ie>5?", first 5 shown":""}); ${ve?"history is omitted":"history is preserved"}:`,...Je.blockingFindings.slice(0,5).map((ye)=>` ${ye.commit.slice(0,7)} ${ye.path} — ${ye.reason}`)," To exclude old commits, use --history sanitize; local Git history stays intact."].join(`
298
- `))}let Vs=new Set(se.map((ie)=>ie.path)),Jc=await Ga(G,Vs,Lt),{observedSecretKeys:Kc,...Ye}=Jc;Ye.warnings.unshift(...Ie);let zn=new Set(Ye.requiredSecretKeys);for(let ie of an)zn.add(ie);for(let ie of oe)for(let ye of ie.envKeys)zn.add(ye);for(let ie of Tn)if(zn.delete(ie))Ye.warnings.push(ts);Ye.requiredSecretKeys=[...zn].sort();for(let ie of Ye.requiredSecretKeys){if(Xe[ie]!==void 0)continue;let ye=U.environment?.[ie];if(ye===void 0){le.push(`${os}${ie}`);continue}Xe[ie]=ye}let Lr=[];for(let ie of Kc){if(Tn.has(ie)){Ye.warnings.push(ts);continue}if(ns.has(ie))continue;if(Xe[ie]!==void 0)continue;let ye=U.environment?.[ie];if(ye===void 0){Lr.push(ie);continue}Xe[ie]=ye}if(Lr.length>0)Ye.warnings.push(au(Lr.sort()));Ye.warnings=[...new Set(Ye.warnings.flatMap((ie)=>ie.split(`
299
- `)))].map((ie)=>ie.slice(0,500)).slice(0,iu);let Xs=Ta(new Map([...Vs].map((ie)=>[ie,Lt.get(ie)??null]))),Ys={schemaVersion:Ba,rootName:U.rootName??Ot(G),stack:Xs.language,git:{detected:B&&!ve,head:ve?null:Je.head,branch:ve?null:Je.branch,refs:ve?[]:Je.refs,commitCount:ve?0:Je.commitCount,historyScanComplete:Je.complete,historyMode:zc},files:se,symlinks:me,secretFiles:Se,activeEnvFiles:Ht,secretKeys:Object.keys(Xe).sort(),envCollisions:Wn,quarantinedResources:pe,mcpServers:oe,historicalSecretFindings:Je.blockingFindings,skipped:Ra(ee),environment:Ye,totals:{files:se.length,bytes:se.reduce((ie,ye)=>ie+ye.size,0)}},Zs=rs(Ys),qc=Nn("sha256").update(Zs).digest("hex");return{root:G,includedPaths:q,ignoreReport:U.refreshIgnore?V?.report??V?.warning:void 0,uploadWarning:ae,stackFacts:Xs,manifest:Ys,...ee.length>5000?{skippedEntries:ee}:{},manifestJson:Zs,manifestSha256:qc,secretValues:Xe,protectedFiles:Ft.sort((ie,ye)=>ie.path.localeCompare(ye.path)),blocking:[...new Set(le)].map((ie)=>`${ie}
300
- ${Jp}`),blockingHistoryFindings:[],gitRemotes:W}}var is={name:"init",summary:"Configure a local folder for Hlix",usage:["Usage: hlix init [folder] [--project <id>] [--json]","","Creates hlix.yml, or fills its hlix: block when the file already exists.","hlix.api is written only when the server is not https://server.hlix.ai.","A folder that only has .hlix/config.json is copied into hlix.yml.","Also creates .hlix/.gitignore and .hlixignore.","hlix.yml is the committed project file. Secret values do not belong in it.","Project configuration is safe to commit; local revision state is ignored.",""," --project <id> Bind the folder to an existing cloud project"," Then `hlix pull`, or `hlix push` if it has no files yet"].join(`
301
- `),supportsJson:!0,options:["project"],args:{min:0,max:1},async run(H){if(H.args.length>1)throw Error("init accepts at most one folder.");let U=await Iu($u(H.cwd,H.args[0]??".")),G=o({env:H.env,flags:H.flags,cwd:U});if(G.conflict)throw new e("workspace_mismatch",G.conflict);if(!G.workspaceId)throw Error("No workspace selected. Run `hlix auth login --workspace <id>` first.");let B=H.requireClient(U);await B.projects.list();let W=Qe(U);if(W.error)throw new e("invalid_project_file",W.error);let z=Vt(W.base),J=z?null:fr(U),K=z??J;if(J&&(J.workspaceId!==G.workspaceId||!Cu(J.apiUrl,G.baseUrl)))throw new e("workspace_mismatch",`This folder is bound to workspace ${J.workspaceId} at ${J.apiUrl}; refusing to bind it to ${G.workspaceId} at ${G.baseUrl}.`);let q=typeof H.flags.project==="string"?H.flags.project:void 0;if(q&&K?.projectId&&K.projectId!==q)throw new e("workspace_mismatch",`This folder is bound to project ${K.projectId}; refusing to rebind it to ${q}.`);if(q)await B.projects.get(q);let X=q??K?.projectId,V={schemaVersion:1,workspaceId:G.workspaceId,apiUrl:G.baseUrl,...X?{projectId:X}:{}},Z={workspace:V.workspaceId,api:V.apiUrl,...V.projectId?{project:V.projectId}:{}};gr(U),await rr(U);let Q=await tt(U,{environment:H.env,refreshIgnore:!0});if(!or(U,xn(Q.manifest.environment,Z)).written)ir(U,Z);if(J)Mi(U,J);let ce={root:U,config:V,ignoreReport:Q.ignoreReport,scan:{files:Q.manifest.totals.files,bytes:Q.manifest.totals.bytes,secretFiles:Q.manifest.secretFiles.map((te)=>te.path),quarantinedResources:Q.manifest.quarantinedResources.map((te)=>te.path),blocking:Q.blocking}};if(H.json)H.stdout(ge(he(is.name,ce)));else{if(Q.ignoreReport)H.stdout(`${Q.ignoreReport}
302
- `);if(H.stdout(`Initialized ${U}
303
- Project: ${V.projectId??"not imported yet"}
304
- Workspace: ${V.workspaceId}
305
- `),Q.blocking.length)H.stdout(`
306
- Review before import:
307
- ${Q.blocking.map((te)=>`- ${te}`).join(`
308
- `)}
309
- `)}return 0}};function Cu(H,U){return H.replace(/\/+$/,"")===U.replace(/\/+$/,"")}import{basename as cm,resolve as lm}from"node:path";import{realpath as dm}from"node:fs/promises";import{mkdtemp as Qu,rm as Ar,readFile as em,writeFile as tm,chmod as nm,symlink as rm,lstat as om}from"node:fs/promises";import{tmpdir as sm}from"node:os";import{join as ls}from"node:path";import{createHash as Tu}from"node:crypto";import{createReadStream as Au}from"node:fs";import{chmod as nc,copyFile as Ru,lstat as Ou,mkdir as as,mkdtemp as Nu,readdir as Fu,readlink as Lu,rm as cs,symlink as Hu}from"node:fs/promises";import{tmpdir as Mu}from"node:os";import{dirname as rc,join as wt}from"node:path";import{spawnSync as Cr}from"node:child_process";var Tr=300000;function Ve(H,U){let G=Cr("git",["-c","core.hooksPath=/dev/null","-C",H,...U],{encoding:"utf8",timeout:Tr,maxBuffer:20971520,stdio:["ignore","pipe","pipe"]});if(G.status!==0){let B=G.stderr.trim().split(`
310
- `).at(-1)??"git command failed";throw Error(B)}return G.stdout.trim()}async function Du(H){let U=Tu("sha256");for await(let G of Au(H))U.update(G);return U.digest("hex")}async function Uu(H){for(let U of await Fu(H)){if(U===".git")continue;await cs(wt(H,U),{recursive:!0,force:!0})}}async function oc(H){if(H.manifest.git.detected&&(H.manifest.historicalSecretFindings.length||!H.manifest.git.historyScanComplete))throw Error("Git history has secrets or could not be fully scanned. Use --history sanitize to import current files.");if(H.uploadWarning)throw Error(H.uploadWarning);if(H.blocking.length>0)throw Error(`Project scan has blocking findings:
311
- - ${H.blocking.join(`
312
- - `)}`);let U=await Nu(wt(Mu(),"hlix-snapshot-"));await nc(U,448);let G=wt(U,"repo"),B=wt(U,"source.git");try{if(H.manifest.git.detected){let K=Cr("git",["clone","--mirror","--no-hardlinks",H.root,B],{encoding:"utf8",timeout:Tr,stdio:["ignore","pipe","pipe"]});if(K.status!==0)throw Error(K.stderr.trim()||"Could not mirror repository.");let q=new Map(Ve(B,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]).split(`
313
- `).filter(Boolean).map((V)=>V.split("\x00",2)));for(let V of H.manifest.git.refs)if(q.get(V.name)!==V.oid)throw Error(`Git ref changed after scan: ${V.name}`);let X=Cr("git",["clone","--no-hardlinks",B,G],{encoding:"utf8",timeout:Tr,stdio:["ignore","pipe","pipe"]});if(X.status!==0)throw Error(X.stderr.trim()||"Could not create snapshot clone.");if(!H.manifest.git.head)throw Error("Git repository has no HEAD commit.");Ve(G,["checkout","-B","main",H.manifest.git.head])}else await as(G,{recursive:!0,mode:448}),Ve(G,["init","-b","main"]);await Uu(G);for(let K of H.manifest.files){let q=wt(H.root,...K.path.split("/")),X=await Ou(q);if(!X.isFile()||X.isSymbolicLink())throw Error(`Source changed after scan: ${K.path}`);if(X.size!==K.size||await Du(q)!==K.sha256)throw Error(`Source changed after scan: ${K.path}`);let V=wt(G,...K.path.split("/"));await as(rc(V),{recursive:!0,mode:493}),await Ru(q,V),await nc(V,K.executable?493:420)}for(let K of H.manifest.symlinks){let q=wt(H.root,...K.path.split("/"));if(await Lu(q).catch(()=>null)!==K.target)throw Error(`Source changed after scan: ${K.path}`);let X=wt(G,...K.path.split("/"));await as(rc(X),{recursive:!0,mode:493}),await Hu(K.target,X)}Ve(G,["config","user.name","Hlix Import"]),Ve(G,["config","user.email","import@hlix.ai"]),Ve(G,["read-tree","--empty"]),Ve(G,["add","--force","-A"]),Ve(G,["commit","--allow-empty","-m","chore(hlix): import snapshot"]);let W=Ve(G,["rev-parse","HEAD"]),z=new Set(H.manifest.git.refs.map((K)=>K.name));for(let K of Ve(G,["for-each-ref","--format=%(refname)","refs/heads","refs/tags"]).split(`
314
- `).filter(Boolean))if(K!=="refs/heads/main"&&!z.has(K))Ve(G,["update-ref","-d",K]);let J=H.manifest.git.refs.filter((K)=>K.name!=="refs/heads/main");if(J.length>0){let K=Cr("git",["-C",G,"update-ref","--stdin"],{encoding:"utf8",timeout:Tr,input:J.map((q)=>`update ${q.name} ${q.oid}`).join(`
315
- `)+`
316
- `,stdio:["pipe","pipe","pipe"]});if(K.status!==0)throw Error(K.stderr.trim()||"Could not recreate the approved Git refs.")}return{directory:G,commitSha:W,dispose:()=>cs(U,{recursive:!0,force:!0})}}catch(W){throw await cs(U,{recursive:!0,force:!0}),W}}import{lstat as ic,mkdir as Gu,realpath as Bu}from"node:fs/promises";import{dirname as Wu,join as zu,relative as Ju,resolve as Ku,sep as sc}from"node:path";function ac(H,U){let G=H;if(typeof G==="string")try{G=JSON.parse(G)}catch{return[]}if(!G||typeof G!=="object")return[];let B=G[U];if(!Array.isArray(B))return[];return B.filter((W)=>!!W&&typeof W==="object")}function cc(H){return ac(H,"files").flatMap((U)=>typeof U.path==="string"&&typeof U.sha256==="string"?[{path:U.path,sha256:U.sha256}]:[])}function lc(H){return ac(H,"symlinks").flatMap((U)=>typeof U.path==="string"&&typeof U.target==="string"?[{path:U.path,target:U.target}]:[])}async function Ln(H,U,G){let B=await Bu(H),W=Ku(B,...U.split("/"));if(W!==B&&!W.startsWith(B+sc))throw Error(`Protected path escapes the project: ${U}`);let z=Ju(B,Wu(W)),J=B;for(let K of z.split(sc).filter(Boolean)){J=zu(J,K);try{let q=await ic(J);if(q.isSymbolicLink()&&G){G.push(J);break}if(!q.isDirectory()||q.isSymbolicLink())throw Error(`Protected path crosses a non-directory: ${U}`)}catch(q){if(q.code!=="ENOENT")throw q;if(!G)await Gu(J,{mode:448})}}return W}async function dc(H,U,G){let B=G.length,W=await Ln(H,U,G);if(G.length>B)return;try{let z=await ic(W);if(z.isSymbolicLink()){G.push(W);return}if(!z.isFile())throw Error(`Refusing to replace non-regular project file: ${U}`)}catch(z){if(z.code!=="ENOENT")throw z}}import{spawnSync as qu}from"node:child_process";import{mkdtemp as Vu,writeFile as Xu,rm as Yu}from"node:fs/promises";import{tmpdir as Zu}from"node:os";import{join as pc}from"node:path";function uc(H,U,G){let B=qu("git",["-c","core.hooksPath=/dev/null","-C",H,...U],{encoding:"utf8",timeout:120000,maxBuffer:41943040,env:{PATH:process.env.PATH,GIT_CONFIG_GLOBAL:G??"/dev/null",GIT_CONFIG_NOSYSTEM:"1",GIT_TERMINAL_PROMPT:"0",GIT_AUTHOR_NAME:"HLIX",GIT_AUTHOR_EMAIL:"repos@hlix.ai",GIT_COMMITTER_NAME:"HLIX",GIT_COMMITTER_EMAIL:"repos@hlix.ai"}});if(B.status!==0)throw Error("HLIX Repos Git operation failed. The remote may have changed; refresh and retry.");return B.stdout.trim()}async function mc(H,U){let G=new URL(H.cloneUrl);if(G.href!==H.cloneUrl||/[\r\n"\\]/.test(H.cloneUrl)||G.protocol!=="https:"||G.username||G.password||G.search||G.hash||G.port||!(G.hostname==="github.com"||/^[a-f0-9]{32}\.artifacts\.cloudflare\.net$/.test(G.hostname)))throw Error("Invalid HLIX Repos remote");if(/[\r\n]/.test(H.token))throw Error("Invalid repository credential");let B=await Vu(pc(Zu(),"hlix-git-auth-")),W=pc(B,"config"),z=H.token.replace(/\?expires=\d+$/,""),J=Buffer.from(`x-access-token:${z}`).toString("base64");try{return await Xu(W,`[http "${H.cloneUrl}"]
317
- extraHeader = Authorization: Basic ${J}
318
- followRedirects = false
319
- `,{mode:384}),await U(W)}finally{await Yu(B,{recursive:!0,force:!0})}}function tn(H){return new Map([...cc(H).map((U)=>[U.path,`blob:${U.sha256}`]),...lc(H).map((U)=>[U.path,`link:${U.target}`])])}var fc={git:uc,access:mc};async function nn(H){let U=t(H);if(!U?.config.projectId)throw new e("not_initialized","Run hlix import or hlix init to bind this folder to a project.");return{...U,state:a(U.root)}}async function gc(H,U){let G=await tt(H,{environment:U,historyMode:"sanitize",maxFiles:50000,maxFileBytes:33554432,maxTotalBytes:1073741824});if(G.manifest.files=G.manifest.files.filter((B)=>B.path!==".hlixignore"),G.blocking.length)throw new e("scan_blocked",G.blocking.join(`
320
- `));return G}function im(H,U){let G=Object.fromEntries(tn(H.manifest));return!U?.files?H.manifest.files.length+H.manifest.symlinks.length>0:JSON.stringify(Object.entries(G).sort())!==JSON.stringify(Object.entries(U.files).sort())}async function ds(H,U,G){let B=await H.projects.get(U),W=G?B.repos.find((z)=>z.id===G):B.repos.find((z)=>z.isPrimary)??(B.repos.length===1?B.repos[0]:void 0);if(!W)throw new e("conflict","Select a primary repository for this project before syncing.");return W}async function ps(H,U,G,B,W=!1,z=fc){let{config:J,state:K}=await nn(H),q=await ds(U,J.projectId,K?.repoId),X=await U.repos.head(J.projectId,q.id);if((B??K?.commitSha)&&X.commitSha!==(B??K?.commitSha))throw new e("conflict","HLIX Repos changed. Pull or sync before pushing.");let V=await oc(G);try{let Z=await U.repos.access(J.projectId,q.id,"write"),Q=await z.access(Z,async(ne)=>{z.git(V.directory,["fetch","--no-tags",Z.cloneUrl,`refs/heads/${q.defaultBranch}`],ne);let ce=z.git(V.directory,["rev-parse","FETCH_HEAD"]);if(ce!==X.commitSha)throw new e("conflict","HLIX Repos changed during upload. Retry sync.");let te=z.git(V.directory,["rev-parse",`${V.commitSha}^{tree}`]),re=z.git(V.directory,["commit-tree",te,"-p",ce,...W&&G.manifest.git.detected?["-p",V.commitSha]:[],"-m","Update HLIX Repos files"]);return z.git(V.directory,["push",`--force-with-lease=refs/heads/${q.defaultBranch}:${ce}`,Z.cloneUrl,`${re}:refs/heads/${q.defaultBranch}`],ne),re});return Po(H,{schemaVersion:1,repoId:q.id,commitSha:Q,files:Object.fromEntries(tn(G.manifest)),snapshotOnly:!0,rootName:G.manifest.rootName}),{action:"push",commitSha:Q}}finally{await V.dispose()}}async function am(H,U,G,B,W,z){let{config:J}=await nn(H),K=await ds(U,J.projectId,G),q=await Qu(ls(sm(),"hlix-pull-"));try{let X=await U.repos.access(J.projectId,G,"read");await z.access(X,async(re)=>{z.git(q,["init"]),z.git(q,["fetch","--no-tags",X.cloneUrl,`refs/heads/${K.defaultBranch}`],re),z.git(q,["checkout","--detach",B])});let V=await gc(q),Z=[],Q=[...V.manifest.files,...V.manifest.symlinks],ne=[...W.manifest.files,...W.manifest.symlinks].filter((re)=>!Q.some((ae)=>ae.path===re.path)),ce=new Set([...W.manifest.files,...W.manifest.symlinks].map((re)=>re.path));for(let re of Q){let ae=re.path.split("/");for(let se=1;se<=ae.length;se++){let me=ae.slice(0,se).join("/"),fe=await om(ls(H,me)).catch((Se)=>{if(Se.code!=="ENOENT")throw Se;return null});if(fe&&!fe.isDirectory()&&!ce.has(me))throw new e("conflict",`Incoming repository file would replace an excluded local file: ${me}`)}}for(let re of[...Q,...ne])await dc(H,re.path,Z);let te=await Promise.all(V.manifest.files.map(async(re)=>({...re,bytes:await em(ls(q,re.path))})));for(let re of[...new Set(Z)].sort((ae,se)=>ae.length-se.length))await Ar(re,{force:!0});for(let re of ne)await Ar(await Ln(H,re.path),{force:!0});for(let re of te){let ae=await Ln(H,re.path);await tm(ae,re.bytes,{mode:re.executable?493:420}),await nm(ae,re.executable?493:420)}for(let re of V.manifest.symlinks){let ae=await Ln(H,re.path);await Ar(ae,{force:!0}),await rm(re.target,ae)}return Po(H,{schemaVersion:1,repoId:G,commitSha:B,files:Object.fromEntries(tn(V.manifest)),snapshotOnly:!0,rootName:W.manifest.rootName}),{action:"pull",commitSha:B}}finally{await Ar(q,{recursive:!0,force:!0})}}async function us(H,U,G,B="sync",W=!1,z=fc){let{config:J,state:K}=await nn(H),q=await ds(U,J.projectId,K?.repoId),[X,V]=await Promise.all([gc(H,G),U.repos.head(J.projectId,q.id)]),Z=im(X,K),Q=K?.commitSha!==V.commitSha,ne=!K&&Z&&!V.isEmpty?"conflict":B==="push"?Q&&K?"conflict":Z?"push":"none":B==="pull"?Z?"conflict":Q?"pull":"none":Z&&Q&&K?"conflict":Z?"push":Q?"pull":"none";if(W)return{action:ne,localChanged:Z,cloudChanged:Q,commitSha:V.commitSha};if(ne==="conflict")throw new e("conflict","This folder and HLIX Repos have both changed. Resolve the differences before syncing; no files were replaced.");if(ne==="push")return ps(H,U,X,V.commitSha,!1,z);if(ne==="pull")return am(H,U,q.id,V.commitSha,X,z);return{action:"none",commitSha:V.commitSha}}function ms(H){return{name:H,summary:`${H} files with HLIX Repos`,usage:`Usage: hlix ${H} [--dry-run] [--json]`,supportsJson:!0,options:["dry-run"],async run(U){let{root:G}=await nn(U.cwd),B=await us(G,U.requireClient(),U.env,H,U.flags["dry-run"]===!0);return U.stdout(U.json?ge(he(`hlix ${H}`,B)):`HLIX Repos: ${B.action} (${B.commitSha})
321
- `),B.action==="conflict"?1:0}}}var hc=ms("push"),yc=ms("pull"),wc=ms("sync");var pm=(H)=>`${(H/1024/1024).toFixed(1)} MB`,fs=(H,U=3)=>H.slice(0,U).join(", ")+(H.length>U?`, +${H.length-U} more`:"");function um(H,U,G,B,W){let{manifest:z}=H,J=new Map;for(let X of z.files){let V=X.path.includes("/")?`${X.path.split("/")[0]}/`:"(root files)";J.set(V,(J.get(V)??0)+1)}let K=[...J].sort((X,V)=>V[1]-X[1]).map(([X,V])=>`${X} ${V}`);return["Import plan",...[["Project",`${U} (${G})`],["Config",W],["Files",`${z.totals.files} files, ${pm(z.totals.bytes)}`],["Folders",fs(K,5)||"none"],["Secrets",H.protectedFiles.length?`${H.protectedFiles.length} encrypted: ${fs(H.protectedFiles.map((X)=>X.path))}`:"none found"],["History",!z.git.detected?"no git history":B==="preserve"?`kept: ${z.git.commitCount} commits${z.git.branch?` on ${z.git.branch}`:""}`:"not sent (sanitize)"],["Skipped",z.skipped.length?fs(z.skipped.map((X)=>X.path)):"nothing"]].map(([X,V])=>` ${X.padEnd(9)}${V}`),"","To change it: --name <name>, --include <path>, or list paths in .hlixignore."].join(`
322
- `)}var vc={name:"import",summary:"Import a local project into HLIX Repos",usage:"Usage: hlix import [folder] [--history preserve|sanitize] [--name name] [--stack stack] [--dry-run] [--yes] [--json]",supportsJson:!0,options:["history","name","stack","dry-run","yes","env-file","include"],args:{min:0,max:1},async run(H){let U=await dm(lm(H.cwd,H.args[0]??".")),G=o({env:H.env,flags:H.flags,cwd:U});if(G.conflict)throw new e("conflict",G.conflict);if(!G.workspaceId||!G.credential)throw new e("workspace_required","Run hlix auth login to select a workspace.");let B=Qe(U);if(B.error)throw new e("invalid_project_file",B.error);let W=Vt(B.base),z=W?void 0:fr(U)?.projectId;if(W?.projectId||z)throw new e("conflict","This folder is already bound to a project. Use hlix push or sync.");let J=H.flags.history??"preserve";if(J!=="preserve"&&J!=="sanitize")throw new e("invalid_usage","--history accepts preserve or sanitize.");let K=await tt(U,{environment:H.env,historyMode:J,envFile:typeof H.flags["env-file"]==="string"?H.flags["env-file"]:void 0,maxFiles:50000,maxFileBytes:33554432,maxTotalBytes:1073741824,include:typeof H.flags.include==="string"?H.flags.include:void 0});if(K.blocking.length)throw new e("scan_blocked",K.blocking.join(`
323
- `));if(K.manifest.git.detected&&(K.manifest.historicalSecretFindings.length||!K.manifest.git.historyScanComplete))throw new e("scan_blocked","History contains potential secrets or was not completely scanned. Review it or use --history sanitize.");let q={files:K.manifest.totals.files,bytes:K.manifest.totals.bytes,protectedFiles:K.protectedFiles.length,history:J},X=B.base?gt(B.base):null,V=typeof H.flags.name==="string"?H.flags.name:X?.name??cm(U),Z=typeof H.flags.stack==="string"?H.flags.stack:X?.stack??K.manifest.stack,Q=B.base??nr(xn(K.manifest.environment,{workspace:G.workspaceId,api:G.baseUrl})),ne=fm(Q,{name:V,stack:Z}),ce=um(K,V,Z,J,Di(B));if(H.flags["dry-run"]===!0)return H.stdout(H.json?ge(he("hlix import",q)):`${ce}
324
- `),0;if(H.flags.yes!==!0){if(!H.confirm)throw new e("invalid_usage","Import requires approval. Review --dry-run, then use --yes.");if(!await H.confirm(ce))return H.stdout(`Import cancelled. Nothing was sent.
325
- `),0}let te=H.requireClient(U),re=await te.projects.create(ne.create);await rr(U),ar(K,".gitignore"),gr(U);let ae={workspace:G.workspaceId,api:G.baseUrl,project:re.id};if(!B.base){if(or(U,xn(K.manifest.environment,ae,{name:V,stack:Z})).written)ar(K,"hlix.yml")}let se=ir(U,ae);if(se.changed)ar(K,se.name);if(Object.keys(ne.patch).length>0)await te.projects.update(re.id,ne.patch);for(let fe=0;fe<K.protectedFiles.length;fe+=64)await te.secrets.importFiles(re.id,K.protectedFiles.slice(fe,fe+64).map((Se)=>({path:Se.path,contentBase64:Se.contentBase64})));let me=await ps(U,te,K,void 0,J==="preserve");return H.stdout(H.json?ge(he("hlix import",{...q,projectId:re.id,commitSha:me.commitSha})):`Imported into HLIX Repos: ${re.name} (${me.commitSha})
326
- `),0}},mm=["claude-code","codex","goose","opencode","pi","qwen-code"];function fm(H,U){let G=gt(H),B=gm(G.runtime);return{create:{name:U.name,stack:U.stack,repos:[],...G.brief?{brief:G.brief}:{},...B?{runtime:B}:{}},patch:{...G.verifyCommand?{verifyCommand:G.verifyCommand}:{},...G.previewCommand?{previewCommand:G.previewCommand}:{},...G.previewPort!==void 0?{previewPort:G.previewPort}:{},...G.sandboxSize?{sandboxSize:G.sandboxSize}:{},...G.branchPrefix?{branchPrefix:G.branchPrefix}:{},...G.intake?{intake:G.intake}:{}}}}function gm(H){let U=H.agents?.filter((B)=>mm.includes(B)),G={};if(U?.length)G.agents=U;if(H.toolchain)G.toolchain=H.toolchain;if(H.aptPackages)G.aptPackages=H.aptPackages;if(H.setup)G.setup=H.setup;if(H.services)G.services=H.services;if(H.envOverrides)G.envOverrides=H.envOverrides;if(H.verifyCommand)G.verifyCommand=H.verifyCommand;if(H.preview)G.preview=H.preview;if(H.notes)G.notes=H.notes;return Object.keys(G).length?G:void 0}import{spawnSync as Gm}from"node:child_process";import{existsSync as Bm,mkdirSync as Wm,writeFileSync as zm}from"node:fs";import{dirname as Jm}from"node:path";import{createHash as hm}from"node:crypto";import{mkdirSync as ym,readdirSync as Ec,readFileSync as wm,rmSync as vm,statSync as Pc,writeFileSync as bm}from"node:fs";import{homedir as km,tmpdir as Sm}from"node:os";import{basename as _c,isAbsolute as xm,join as xe,relative as jm}from"node:path";var c=(H=process.env)=>H.HOME??H.USERPROFILE??km();function We(H){try{if(!Pc(H).isFile())return null;return wm(H,"utf8")}catch{return null}}function Em(H){try{return Pc(H).isDirectory()}catch{return!1}}function rn(H,U){try{return Ec(H,{withFileTypes:!0}).filter((G)=>G.isFile()&&G.name.endsWith(U)).map((G)=>xe(H,G.name)).sort()}catch{return[]}}function Pm(H){try{return Ec(H,{withFileTypes:!0}).filter((U)=>U.isDirectory()||U.isSymbolicLink()).map((U)=>xe(H,U.name)).sort()}catch{return[]}}function hs(H){let U=H.replace(/^\uFEFF/,""),G=U.indexOf(`
327
- `);if(!U.startsWith("---")||G===-1)return{fields:{},body:U.trim()};let B=U.indexOf(`
328
- ---`,G);if(B===-1)return{fields:{},body:U.trim()};let W={};for(let J of U.slice(G+1,B).split(`
329
- `)){let K=/^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(J);if(!K)continue;W[K[1]]=K[2].trim().replace(/^["']|["']$/g,"")}let z=U.indexOf(`
330
- `,B+1);return{fields:W,body:z===-1?"":U.slice(z+1).trim()}}function _m(H){let U=H.trimStart(),G=/^"((?:[^"\\]|\\.)*)"/.exec(U)??/^'([^']*)'/.exec(U);if(G)return G[1].replace(/\\"/g,'"').replace(/\\n/g,`
331
- `);if(U.startsWith("["))return[...U.matchAll(/"((?:[^"\\]|\\.)*)"|'([^']*)'/g)].map((W)=>W[1]??W[2]??"");if(U.startsWith("{")){let W={};for(let z of U.matchAll(/([A-Za-z0-9_.-]+)\s*=\s*"((?:[^"\\]|\\.)*)"/g))W[z[1]]=z[2].replace(/\\"/g,'"');return W}let B=/^[^\s#]+/.exec(U)?.[0];if(B===void 0)return;if(B==="true"||B==="false")return B==="true";if(/^-?\d+(\.\d+)?$/.test(B))return Number(B);return B}function Ic(H){let U={"":{}},G="",B=H.split(`
332
- `);for(let W=0;W<B.length;W+=1){let J=B[W].trim();if(!J||J.startsWith("#"))continue;let K=/^\[\[?([^\]]+)\]\]?$/.exec(J);if(K){G=K[1].trim(),U[G]??={};continue}let q=/^([A-Za-z0-9_.-]+|"[^"]+")\s*=\s*(.*)$/.exec(J);if(!q)continue;let X=q[1].replace(/^"|"$/g,""),V=q[2];if(V.startsWith('"""')){let Q=[],ne=V.slice(3);if(ne.includes('"""'))Q.push(ne.slice(0,ne.indexOf('"""')));else{if(ne)Q.push(ne);while(W+1<B.length){W+=1;let ce=B[W],te=ce.indexOf('"""');if(te===-1){Q.push(ce);continue}Q.push(ce.slice(0,te));break}}U[G][X]=Q.join(`
333
- `).replace(/^\n/,"");continue}let Z=_m(V);if(Z!==void 0)U[G][X]=Z}return U}function gs(H,U){return H.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(G,B,W)=>{let z=U[B];return z!==void 0&&z!==""?z:W??""})}var bc=(H,U)=>{let G={};for(let[B,W]of Object.entries(H))if(typeof W==="string")G[B]=gs(W,U);return G},Im=[{relative:"GEMINI.md",source:"gemini"},{relative:xe(".gemini","GEMINI.md"),source:"gemini"},{relative:".cursorrules",source:"cursor"},{relative:".windsurfrules",source:"windsurf"},{relative:xe(".github","copilot-instructions.md"),source:"copilot"}],$m=[{relative:xe(".gemini","GEMINI.md"),source:"gemini"}],Cm=[{relative:xe(".cursor","rules"),source:"cursor",extension:".mdc"},{relative:xe(".windsurf","rules"),source:"windsurf",extension:".md"}];function Tm(H,U){let G=xe(H,".clinerules"),B=Em(G)?rn(G,".md"):[G],W=[];for(let z of B){let J=We(z)?.trim();if(J)W.push({path:z,source:"cline",scope:U,content:J})}return W}function Am(H,U,G){let{fields:B,body:W}=hs(U);if(B.alwaysApply==="false")return{path:H,source:"cursor",scope:G,reason:"alwaysApply: false"};if(!W)return{path:H,source:"cursor",scope:G,reason:"no rule body"};let z=B.globs?.replace(/^\[|\]$/g,"").trim();return{path:H,source:"cursor",scope:G,content:W,...z?{note:`Applies to: ${z}`}:{}}}var Rm=["AGENTS.md","CLAUDE.md"],$c=["",".claude"],j=["commands"];function Om(H,U){let G=[],B=new Set;for(let W of[...$c,U])for(let z of Rm){let J=xe(H,W,z),K=We(J)?.trim();if(!K||B.has(K))continue;B.add(K),G.push({path:J,content:K})}return G}function kc(H,U){return Om(H,U).map((G)=>G.content)}var x=["AGENTS.md","CLAUDE.md","GEMINI.md"];function ys(H,U){for(let G of x)for(let B of[...$c,U]){let W=xe(H,B,G),z=We(W)?.trim();if(z)return{path:W,content:z}}return null}var ws=(H=process.env)=>xe(H.HLIX_CONFIG_HOME??xe(c(H),".hlix"),"AGENTS.md");function E(H){let U=H.env??process.env,G=ws(U),B=We(G)?.trim();return{global:B?{path:G,content:B}:null,project:ys(H.cwd,H.configDir)}}var Sc=(H)=>{let U=Math.round(H.length/4);return U>=1000?`${(U/1000).toFixed(1)}k tokens`:`${U} tokens`};function O(H,U,G=process.env){let B=[...H.global?[Tc(H.global.path,G)]:[],...H.project?[Mn(H.project.path,U)]:[]];return B.length===0?"":`rules: ${B.join(" + ")}`}function C(H,U,G=process.env,B=[]){let W=(z,J,K)=>J?`${z.padEnd(8)} ${K(J.path)} (${Sc(J.content)})`:`${z.padEnd(8)} none`;return[W("user",H.global,(z)=>Tc(z,G)),W("project",H.project,(z)=>Mn(z,U)),...B.map((z)=>`${"nested".padEnd(8)} ${Mn(z.path,U)} (${Sc(z.content)})`),"","User rules go first, the project's after, so the project wins a conflict.",B.length===0?"A subdirectory's own rules file is added when the agent first works in it.":"A nested file was added when the agent first touched a path under it.","Edit them with `hlix rules --edit` (this project) or `hlix rules --edit --global`."].join(`
334
- `)}var xc=[{dir:".claude",source:"claude",harnessReads:!0},{dir:".agents",source:"agents",harnessReads:!0},{dir:".hlix",source:"hlix",harnessReads:!0},{dir:".codex",source:"codex",harnessReads:!1}],Nm=[{relative:xe(".cursor","commands"),source:"cursor"},{relative:xe(".codex","prompts"),source:"codex"}],Fm=[{relative:xe(".cursor","mcp.json"),source:"cursor",key:"mcpServers",format:"json"},{relative:xe(".windsurf","mcp.json"),source:"windsurf",key:"mcpServers",format:"json"},{relative:xe(".gemini","settings.json"),source:"gemini",key:"mcpServers",format:"json"},{relative:xe(".vscode","mcp.json"),source:"vscode",key:"servers",format:"json"},{relative:xe(".codex","config.toml"),source:"codex",key:"mcp_servers",format:"toml"},{relative:".mcp.json",source:"claude",key:"mcpServers",format:"json"}];function Cc(H){return[...Fm,{relative:xe(H,"mcp.json"),source:"hlix",key:"mcpServers",format:"json"}]}var Lm="found, not loaded (machine-wide; enable per project by copying into .hlix/mcp.json)",Hm=(H)=>Cc(H).filter((U)=>U.source!=="vscode");function Mm(H,U){if(!H||typeof H!=="object"||Array.isArray(H))return{reason:"not an object"};let G=H;if(G.enabled===!1||G.disabled===!0)return{reason:"disabled"};let B=typeof G.command==="string"&&G.command!=="",W=typeof G.url==="string"&&G.url!=="";if(B&&W)return{reason:'has both "command" and "url"'};if(B){let Z=Array.isArray(G.args)?G.args.filter((ne)=>typeof ne==="string"):void 0,Q=G.env&&typeof G.env==="object"&&!Array.isArray(G.env)?bc(G.env,U):void 0;return{config:{command:G.command,...Z&&Z.length>0?{args:Z}:{},...Q&&Object.keys(Q).length>0?{env:Q}:{}}}}if(!W)return{reason:'missing "command" or "url"'};let z=G.headers??G.http_headers,J=z&&typeof z==="object"&&!Array.isArray(z)?bc(z,U):{},K=G.bearer_token_env_var;if(typeof K==="string"&&/^[A-Za-z_][A-Za-z0-9_]*$/.test(K)&&!Object.keys(J).some((Z)=>Z.toLowerCase()==="authorization"))J.Authorization=`Bearer ${gs(`\${${K}}`,U)}`;let q=Object.entries(J).find(([Z])=>Z.toLowerCase()==="authorization")?.[1]?.trim(),X=q&&!/^Bearer$/i.test(q)&&!q.includes("${"),V=G.oauth===!0||G.oauth&&typeof G.oauth==="object"||typeof K==="string"&&!U[K];return{config:{url:gs(G.url,U),...V&&!X?{needsSignIn:!0}:{},...Object.keys(J).length>0?{headers:J}:{}}}}function jc(H,U,G,B){let W=We(H),z=[],J=[];if(W===null)return{servers:z,skipped:J};let K=[];if(U.format==="toml"){let q=Ic(W);K=Object.entries(q).filter(([X])=>X.startsWith(`${U.key}.`)).map(([X,V])=>[X.slice(U.key.length+1),V])}else try{let X=JSON.parse(W)?.[U.key];if(X&&typeof X==="object"&&!Array.isArray(X))K=Object.entries(X)}catch{return J.push({path:H,source:U.source,scope:G,reason:"not valid JSON"}),{servers:z,skipped:J}}for(let[q,X]of K){let V=Mm(X,B);if("reason"in V){J.push({path:H,source:U.source,scope:G,reason:`${q}: ${V.reason}`});continue}z.push({path:H,source:U.source,scope:G,name:q,config:V.config})}return{servers:z,skipped:J}}function Dm(H,U,G){let{fields:B,body:W}=hs(U);if(!W)return{path:H,source:"claude",scope:G,reason:"no instructions"};let z=B.tools?.replace(/^\[|\]$/g,"").split(",").map((J)=>J.trim()).filter(Boolean);return{path:H,source:"claude",scope:G,name:B.name||_c(H,".md"),description:B.description??"",instructions:W,...z&&z.length>0&&z[0]!=="*"?{tools:z}:{},...B.model?{model:B.model}:{}}}function Um(H){let U=Ic(H)[""]??{},G=typeof U.prompt==="string"?U.prompt.trim():"";if(!G)return null;return{description:typeof U.description==="string"?U.description:"",body:G}}function _(H,U,G={}){let B=G.configDir??".hlix",W=G.env??process.env,z={instructions:[],skills:[],commands:[],generatedCommands:[],mcpServers:[],subagents:[],skipped:[]},J=(ce)=>{if("reason"in ce)z.skipped.push(ce);else z.instructions.push(ce)};for(let ce of Im){let te=xe(H,ce.relative),re=We(te)?.trim();if(re)z.instructions.push({path:te,source:ce.source,scope:"project",content:re})}for(let ce of Cm)for(let te of rn(xe(H,ce.relative),ce.extension)){let re=We(te);if(re===null)continue;if(ce.source==="cursor"){J(Am(te,re,"project"));continue}let{body:ae}=hs(re);if(ae)z.instructions.push({path:te,source:ce.source,scope:"project",content:ae})}for(let ce of Tm(H,"project"))J(ce);let K=kc(H,B),q=xe(H,".codex","AGENTS.md"),X=We(q)?.trim();if(X&&K.includes(X))z.skipped.push({path:q,source:"codex",scope:"project",reason:"same content as the project's AGENTS.md"});else if(X)z.instructions.push({path:q,source:"codex",scope:"project",content:X});for(let ce of $m){let te=xe(U,ce.relative),re=We(te)?.trim();if(re)z.instructions.push({path:te,source:ce.source,scope:"global",content:re})}let V=xe(U,".codex","AGENTS.md"),Z=We(V)?.trim(),Q=kc(U,B);if(Z&&Q.includes(Z))z.skipped.push({path:V,source:"codex",scope:"global",reason:"same content as the machine's AGENTS.md"});else if(Z)z.instructions.push({path:V,source:"codex",scope:"global",content:Z});for(let[ce,te]of[[H,"project"],[U,"global"]])for(let re of xc){let ae=xe(ce,re.dir===".hlix"?B:re.dir,"skills");if(!Pm(ae).some((me)=>We(xe(me,"SKILL.md"))!==null))continue;z.skills.push({path:ae,source:re.source,scope:te,harnessReads:re.harnessReads})}for(let[ce,te]of[[H,"project"],[U,"global"]]){for(let re of xc){if(!re.harnessReads)continue;let ae=xe(ce,re.dir,"commands");if(rn(ae,".md").length===0)continue;z.commands.push({path:ae,source:re.source,scope:te,harnessReads:!0})}for(let re of Nm){let ae=xe(ce,re.relative);if(rn(ae,".md").length===0)continue;z.commands.push({path:ae,source:re.source,scope:te})}for(let re of rn(xe(ce,".gemini","commands"),".toml")){let ae=We(re),se=ae===null?null:Um(ae);if(!se){z.skipped.push({path:re,source:"gemini",scope:te,reason:"no prompt field"});continue}z.generatedCommands.push({path:re,source:"gemini",scope:te,name:_c(re,".toml"),body:`---
335
- description: ${se.description}
336
- ---
337
-
338
- ${se.body}
339
- `})}}for(let ce of Cc(B)){let te=jc(xe(H,ce.relative),ce,"project",W);z.skipped.push(...te.skipped);for(let re of te.servers){let ae=z.mcpServers.findIndex((se)=>se.name===re.name);if(ae===-1)z.mcpServers.push(re);else z.mcpServers[ae]=re}}for(let ce of Hm(B)){let te=jc(xe(U,ce.relative),ce,"global",W);for(let re of te.servers)z.skipped.push({path:re.path,source:re.source,scope:"global",reason:`${re.name}: ${Lm}`})}let ne=[{dir:xe(".claude","agents"),source:"claude"},{dir:xe(B,"agents"),source:"hlix"}];for(let[ce,te]of[[H,"project"],[U,"global"]])for(let re of ne.flatMap((ae)=>rn(xe(ce,ae.dir),".md"))){let ae=We(re);if(ae===null)continue;let se=Dm(re,ae,te);if("reason"in se)z.skipped.push(se);else if(z.subagents.some((me)=>me.name===se.name))z.skipped.push({path:re,source:"claude",scope:te,reason:`a project agent already claims the name ${se.name}`});else z.subagents.push(se)}return z}function N(H,U){if(H.length===0)return null;let G=xe(Sm(),"hlix-standards-commands",hm("sha256").update(U).digest("hex").slice(0,16));try{vm(G,{recursive:!0,force:!0}),ym(G,{recursive:!0});for(let B of H)bm(xe(G,`${B.name}.md`),B.body,"utf8");return G}catch{return null}}var Mn=(H,U)=>{let G=jm(U,H);return!G||G.startsWith("..")||xm(G)?H:G},Tc=(H,U=process.env)=>{let G=U.HLIX_CONFIG_HOME;if(G&&H.startsWith(`${G}/`))return`~/.hlix/${H.slice(G.length+1)}`;let B=c(U);return B&&H.startsWith(`${B}/`)?`~/${H.slice(B.length+1)}`:H};function M(H,U){if(H.length===0)return"";let G=["# Project standards from other agent tools","","These files were written for other coding agents working in this same","project. Treat them as the project's instructions and follow them."].join(`
340
- `),B=H.map((W)=>{let z=`# From ${Mn(W.path,U)} (${W.source})`;return`${W.note?`${z}
341
- ${W.note}`:z}
342
-
343
- ${W.content}`});return`${G}
344
-
345
- ${B.join(`
346
-
347
- `)}`}var Hn=(H,U,G)=>`${H} ${H===1?U:G}`;function L(H){let U=[];if(H.instructions.length>0)U.push(Hn(H.instructions.length,"instruction file","instruction files"));if(H.skills.length>0)U.push(Hn(H.skills.length,"skill directory","skill directories"));let G=H.commands.length+H.generatedCommands.length;if(G>0)U.push(Hn(G,"command source","command sources"));if(H.mcpServers.length>0)U.push(Hn(H.mcpServers.length,"mcp server","mcp servers"));if(H.subagents.length>0)U.push(Hn(H.subagents.length,"subagent","subagents"));if(U.length===0)return"";let B=[...new Set([...H.instructions,...H.skills,...H.commands,...H.generatedCommands,...H.mcpServers,...H.subagents].map((W)=>W.source))].sort();return`standards: ${U.join(" · ")} (${B.join(", ")})`}function Ac(H,U){let G=[],B=(z,J)=>{if(J.length===0)return;G.push(z,...J.map((K)=>` ${K}`),"")},W=(z)=>`${z.source}${z.scope==="global"?" (global)":""} ${Mn(z.path,U)}`;if(B("Instructions",H.instructions.map((z)=>`${W(z)}${z.note?` — ${z.note}`:""}`)),B("Skills",H.skills.map((z)=>`${W(z)}${z.harnessReads?" — already read by the harness":""}`)),B("Commands",[...H.commands.map((z)=>`${W(z)}${z.harnessReads?" — already read by the harness":""}`),...H.generatedCommands.map((z)=>`${W(z)} → /${z.name}`)]),B("MCP servers",H.mcpServers.map((z)=>`${W(z)} → ${z.name} (${"command"in z.config?"stdio":"http"})`)),B("Subagents",H.subagents.map((z)=>`${W(z)} → ${z.name}`)),B("Skipped",H.skipped.map((z)=>`${W(z)} — ${z.reason}`)),G.length===0)return`No standards from other agent tools were found in this folder.
348
- `;return`${G.join(`
349
- `).trimEnd()}
350
- `}function Km(H){return H==="global"?["# My rules","","Hlix Code reads this file in every project you open, before the project's","own rules. Write how you want an agent to work with you: the tone, the","things to always do, the things to never do.",""].join(`
351
- `):["# Project rules","","Hlix Code and every other coding agent that opens this repository read","this file. Write the rules that are true of THIS project: how to run its","tests, its conventions, what not to touch.",""].join(`
352
- `)}function qm(H){return H.VISUAL?.trim()||H.EDITOR?.trim()||"vi"}var vs={name:"rules",summary:"Show or edit the rules files the coding agent reads",usage:["Usage: hlix rules [--edit] [--global] [--cwd <dir>] [--json]","","Without --edit it reports which files Hlix Code loads and how big they are.","","--edit opens one in $EDITOR, creating it with a short header if it does not","exist yet. --global edits your own rules (~/.hlix/AGENTS.md, read in every",`project); without it the project's file (${x.join(", then ")}).`].join(`
353
- `),supportsJson:!0,options:["edit","global"],async run(H){let U=E({cwd:H.cwd,configDir:".hlix",env:H.env}),G=H.flags.global===!0;if(H.flags.edit===!0){if(H.json)throw new e("invalid_usage","`hlix rules --edit` opens an editor, so it has no --json form.");let B=G?ws(H.env):ys(H.cwd,".hlix")?.path??`${H.cwd}/AGENTS.md`;if(!Bm(B))Wm(Jm(B),{recursive:!0}),zm(B,Km(G?"global":"project"),"utf8"),H.stdout(`Created ${B}.
354
- `);let W=qm(H.env),z=Gm(W,[B],{stdio:"inherit"});if(z.error)throw new e("invalid_usage",`Could not run ${W}: ${z.error.message}`);return z.status??0}if(H.json){let B=(W)=>W?{path:W.path,characters:W.content.length}:null;return H.stdout(ge(he(vs.name,{user:B(U.global),project:B(U.project)}))),0}return H.stdout(`${C(U,H.cwd)}
355
- `),0}};var bs={name:"standards",summary:"Show the standards other agent tools left in this folder",usage:["Usage: hlix standards [--cwd <dir>] [--json]","","Reads the instruction files, skills, slash commands, MCP servers and","subagents this project already carries for Claude Code, Cursor, Windsurf,","Gemini, Codex, Cline, Copilot and VS Code, and shows where each came from.","Hlix Code loads all of it at startup; nothing has to be copied or rewritten.","","Server urls, headers and environment values are never printed."].join(`
356
- `),supportsJson:!0,async run(H){let U=_(H.cwd,c(H.env),{env:H.env});if(H.json)return H.stdout(ge(he(bs.name,{instructions:U.instructions.map((G)=>({path:G.path,source:G.source,scope:G.scope,characters:G.content.length,...G.note?{note:G.note}:{}})),skills:U.skills,commands:[...U.commands.map((G)=>({path:G.path,source:G.source,scope:G.scope})),...U.generatedCommands.map((G)=>({path:G.path,source:G.source,scope:G.scope,command:G.name}))],mcpServers:U.mcpServers.map((G)=>({path:G.path,source:G.source,scope:G.scope,name:G.name,transport:"command"in G.config?"stdio":"http"})),subagents:U.subagents.map((G)=>({path:G.path,source:G.source,scope:G.scope,name:G.name,description:G.description,...G.model?{model:G.model}:{}})),skipped:U.skipped}))),0;return H.stdout(Ac(U,H.cwd)),0}};import{accessSync as Vm,constants as Xm,mkdirSync as Ym,readFileSync as Zm,realpathSync as Qm,statSync as Oc,writeFileSync as ef}from"node:fs";import{homedir as tf}from"node:os";import{basename as nf,dirname as Rc,join as on}from"node:path";var rf={homebrew:"Homebrew",npm:"npm",installer:"installer",unknown:"unknown origin"},Nc=(H)=>H.HOME||tf();function Ss(H){return on(H.XDG_DATA_HOME||on(Nc(H),".local","share"),"hlix","hlix")}function Fc(H){try{return Qm(H)}catch{return null}}function of(H){try{let U=JSON.parse(Zm(on(Ss(H),"install.json"),"utf8"));if(typeof U.path==="string")return U.path}catch{}return on(Nc(H),".local","bin","hlix")}function sf(H,U){if(/\/Cellar\/hlix\//.test(H))return"homebrew";if(/\/node_modules\/@hlix\/cli\//.test(H))return"npm";if(Fc(of(U))===H)return"installer";return"unknown"}function ks(H,U){let G=Fc(H);if(!G)return null;try{if(!Oc(G).isFile())return null;Vm(G,Xm.X_OK)}catch{return null}return{path:H,realPath:G,channel:sf(G,U)}}function af(H){let U=[];for(let G of(H.PATH??"").split(":")){if(!G)continue;let B=ks(on(G,"hlix"),H);if(B&&!U.some((W)=>W.realPath===B.realPath))U.push(B)}return U}function xs(H,U=process.execPath){if(H.HLIX_SELF)return ks(H.HLIX_SELF,H);if(/^(node|bun)(\.exe)?$/.test(nf(U)))return null;return ks(U,H)}function js(H){switch(H.channel){case"homebrew":return"brew uninstall hlix";case"npm":return"npm uninstall -g @hlix/cli";case"installer":return`${H.path} uninstall`;case"unknown":return`rm ${H.path}`}}var Rr=(H)=>`${H.path} (${rf[H.channel]})`;function Es(H,U=process.execPath){let G=xs(H,U),B=af(H);if(G&&!B.some((K)=>K.realPath===G.realPath))B.push(G);if(B.length<2)return{running:G,copies:B,duplicate:null};let[W,...z]=B,J=`${B.length} copies of hlix are installed: ${Rr(W)} runs, ${z.map(Rr).join(" and ")} ${z.length===1?"does":"do"} not. Keep one: ${z.map(js).join(" && ")}`;return{running:G,copies:B,duplicate:J}}var cf=86400000;function D(H,U=Date.now(),G=process.execPath){let{duplicate:B}=Es(H,G);if(!B)return null;let W=on(Rc(Ze(H)),"duplicate-notice");try{if(U-Oc(W).mtimeMs<cf)return null}catch{}try{Ym(Rc(W),{recursive:!0}),ef(W,`${B}
357
- `)}catch{}return B}var Hc=(H)=>H instanceof Error?H.message:String(H),Lc=(H)=>H.split(/\s*\n\s*/).join(" ").trim();async function P(H,U,G,B,W){try{let z=await tt(U,{historyMode:G,environment:H.env,rootName:B}),J=a(U)?.files,K=tn(z.manifest);return{changedFiles:J?[...new Set([...Object.keys(J),...K.keys()])].filter((X)=>J[X]!==K.get(X)).length:null,files:z.manifest.totals.files,manifestSha256:z.manifestSha256,changed:W?z.manifestSha256!==W:null,blocking:z.blocking,error:null}}catch(z){return{changedFiles:null,files:null,manifestSha256:null,changed:null,blocking:[],error:Hc(z)}}}var Ps={name:"status",summary:"Show the workspace, folder binding, and local-vs-cloud drift",usage:["Usage: hlix status [--cwd <dir>] [--json]","","Reports the resolved workspace and API with the source that decided each,","whether this folder is bound to a project, and whether the working tree or","the cloud head has moved since the last sync. Every finding is a line in","the output, so the command itself always exits 0; only an argument error","(rejected before it runs) exits 2."].join(`
358
- `),supportsJson:!0,async run(H){let U=o({env:H.env,flags:H.flags,cwd:H.cwd}),G=U.binding,B=G?a(G.root):null,W=G?await P(H,G.root,B?.snapshotOnly?"sanitize":B?.historyMode??"preserve",B?.rootName,B?.manifestSha256):null,z=null;if(G?.config.projectId&&U.credential&&!U.conflict)try{let X=H.requireClient(),V=await X.projects.get(G.config.projectId),Z=B?.repoId??V.repos.find((ne)=>ne.isPrimary)?.id??V.repos[0]?.id;if(!Z)throw Error("Select a primary HLIX Repos");let Q=await X.repos.head(G.config.projectId,Z);z={commitSha:Q.commitSha,changed:B?Q.commitSha!==B.commitSha:null,error:null,errorMessage:null}}catch(X){z={commitSha:"",changed:null,error:bo(X).code,errorMessage:X instanceof St?"no HLIX Repos commit yet — `hlix push` publishes this folder":Hc(X)}}let J=Es(H.env),K={cwd:H.cwd,workspace:{id:U.workspaceId,source:U.workspaceSource},api:{baseUrl:U.baseUrl,source:U.baseUrlSource},credential:{present:U.credential!==null,source:U.credentialSource,path:U.credentialPath},conflict:U.conflict,project:G?{root:G.root,projectId:G.config.projectId??null,workspaceId:G.config.workspaceId,apiUrl:G.config.apiUrl}:null,repository:B?{repoId:B.repoId,commitSha:B.commitSha}:null,local:W,cloud:z,install:{channel:J.running?.channel??null,path:J.running?.path??null,copies:J.copies.map(({path:X,channel:V})=>({path:X,channel:V})),duplicate:J.duplicate}};if(H.json)return H.stdout(ge(he(Ps.name,K))),0;let q=[["folder",H.cwd],["workspace",U.workspaceId?`${U.workspaceId} (from ${U.workspaceSource})`:"none — run `hlix auth login --workspace <id>`"],["api",`${U.baseUrl} (from ${U.baseUrlSource})`],["credential",y(U)??"none — run `hlix auth login`"],["project",G?G.config.projectId??`initialized at ${G.root}, not imported yet`:"none — run `hlix import .` to bind this folder"]];if(B)q.push(["HLIX Repos",B.commitSha]);if(W){if(q.push(["local",W.error?`could not scan: ${W.error}`:W.changed===null?`${W.files} files, no synced base commit`:W.changed?`${W.files} files, modified since the last sync`:`${W.files} files, matches the last sync`]),W.blocking.length>0)q.push(["blocking",W.blocking.join("; ")])}if(z)q.push(["cloud",z.error==="not_found"?Lc(z.errorMessage??z.error):z.error?`not checked — ${Lc(z.errorMessage??z.error)}`:z.changed?`commit ${z.commitSha} available — run \`hlix pull\``:`commit ${z.commitSha}, up to date`]);if(U.conflict)q.push(["conflict",U.conflict]);if(J.running)q.push(["installed",Rr(J.running)]);if(J.duplicate)q.push(["duplicate",J.duplicate]);return H.stdout(`${Ae(q)}
359
- `),0}};import{spawnSync as Mc}from"node:child_process";var _s={name:"terminal",summary:"Open a shell into the project's Cloud Machine",usage:["Usage: hlix terminal [project-id] [--print] [--web] [--json]","","With no id, the project this folder is bound to is used."," --print Show the ssh command and browser url instead of connecting"," --web Open the browser terminal instead of ssh"].join(`
360
- `),supportsJson:!0,options:["print","web"],args:{min:0,max:1},async run(H){let U=H.args[0]??t(H.cwd)?.config.projectId;if(!U)throw new e("missing_argument","A project id is required, or run this inside a folder bound to a project.");let G=await H.requireClient().projects.terminal(U);if(H.json)return H.stdout(ge(he(_s.name,G))),G.available?0:1;if(!G.available){let J=G.environmentState?` (environment: ${G.environmentState})`:"";throw new e("not_found",`${G.reason??"Terminal unavailable"}${J}`)}let B=H.flags.print===!0,W=H.flags.web===!0;if(B||W&&!G.webTerminalUrl||!W&&!G.sshCommand)return H.stdout(`${Ae([["ssh",G.sshCommand??"not available"],["browser",G.webTerminalUrl??"not available"]])}
361
- `),0;if(W){if(Mc(process.platform==="darwin"?"open":"xdg-open",[G.webTerminalUrl],{stdio:"ignore"}).status!==0)H.stdout(`${G.webTerminalUrl}
362
- `);return 0}return Mc("sh",["-c",G.sshCommand],{stdio:"inherit"}).status??1}};import{rmSync as Dc}from"node:fs";import{dirname as lf}from"node:path";var Is={name:"uninstall",summary:"Remove this hlix if the installer put it here (keeps your login)",usage:["Usage: hlix uninstall [--yes] [--json]","","Removes the executable the one-line installer installed, and its notices.","Your login in ~/.config/hlix is kept. A copy installed with Homebrew or npm","is removed with that tool instead; this command names it."].join(`
363
- `),supportsJson:!0,options:["yes"],async run(H){let U=xs(H.env);if(!U||U.channel!=="installer")throw new e("invalid_request",U&&U.channel!=="unknown"?`This hlix was installed with ${U.channel==="homebrew"?"Homebrew":"npm"}. Remove it with: ${js(U)}`:"Only an hlix installed by the one-line installer can remove itself.");if(H.flags.yes!==!0){if(H.json||!H.confirm)throw new e("approval_required","Removing hlix needs approval. Repeat with `--yes`.");if(!await H.confirm(`Remove ${U.path}? Your login is kept.`))throw new e("cancelled","Uninstall cancelled.")}let G=Ss(H.env);Dc(U.path,{force:!0}),Dc(G,{recursive:!0,force:!0});let B=lf(Ze(H.env));if(H.json)H.stdout(ge(he(Is.name,{removed:[U.path,G],kept:B})));else H.stdout(`Removed ${U.path}
364
- Your login in ${B} is kept.
365
- `);return 0}};function T(H){return[...H.pulled?[`HLIX Repos: pulled ${H.pulled}`]:[],...H.pushed?[`HLIX Repos: pushed ${H.pushed}`]:[]]}async function R(H,U,G){let B=!1;while(!G.signal?.aborted){try{let W=await us(H,U.client,U.env);if(G.onReport({conflicts:[],...W.action==="push"?{pushed:W.commitSha}:W.action==="pull"?{pulled:W.commitSha}:{}}),!B)B=!0,G.onCaughtUp?.()}catch(W){G.onError(W)}await ft(15000,G.signal)}}var Uc={name:"mirror",summary:"Follow HLIX Repos using Git",usage:"Usage: hlix mirror [--json]",supportsJson:!0,options:[],agentTool:!1,async run(H){let{root:U}=await nn(H.cwd);return await R(U,{client:H.requireClient(),env:H.env},{signal:H.signal,onReport:(G)=>{if(H.json)H.stdout(ge(he("hlix mirror",G)));else for(let B of T(G))H.stdout(`${B}
366
- `)},onError:(G)=>H.stderr(`${G instanceof Error?G.message:String(G)}
367
- `)}),0}};import{lstat as Cs,readFile as df,realpath as pf}from"node:fs/promises";import{basename as $s,dirname as uf,extname as mf,join as Or,parse as Gc,resolve as Nr}from"node:path";function sn(H,U){let G=H.flags[U];return typeof G==="string"&&G.trim()?G.trim():void 0}function Ts(H){let U=sn(H,"project");if(U)return{root:H.cwd,projectId:U};return ff(H.cwd)}function ff(H){let U=t(H);if(!U?.config.projectId)throw new e("not_initialized","This folder is not bound to an Hlix project. Run `hlix import .` first.");return{root:U.root,projectId:U.config.projectId}}async function As(H,U){let G=await Cs(H);if(G.isSymbolicLink()||!G.isFile())throw Error(`Refusing to import a non-regular file: ${H}`);if(G.size>U)throw Error(`Import file exceeds ${U} bytes: ${H}`);return{path:await pf(H),content:await df(H,"utf8")}}function Rs(H,U,G,B){if(H.json)H.stdout(ge(he(U,G)));else H.stdout(`${B}
368
- `)}function gf(H){let U=/^---\r?\n([\s\S]*?)\r?\n---/.exec(H)?.[1];return(U?/^name:\s*(.+?)\s*$/m.exec(U)?.[1]:void 0)?.replace(/^["']|["']$/g,"").trim()||void 0}var hf=[Or(".claude","skills"),Or(".agents","skills"),Or(".hlix","skills")];async function yf(H,U){let G=[Nr(H,U),...hf.map((B)=>Nr(H,B,U))];for(let B of G)if(await Cs(B).then(()=>!0,()=>!1))return B;throw new e("not_found",`No skill at ${U}. Pass the SKILL.md or its folder, for example .claude/skills/${U}.`)}var Os={name:"skill import",summary:"Activate a local skill for the bound cloud project",usage:"Usage: hlix skill import <SKILL.md|folder> [--name <slug>] [--project <id>] [--json]",supportsJson:!0,options:["name","project"],args:{min:1,max:1},async run(H){if(H.args.length!==1)throw Error("skill import requires one file or folder.");let U=Ts(H),G=await yf(H.cwd,H.args[0]),B=await Cs(G);if(B.isSymbolicLink())throw Error(`Refusing to import a symlink: ${G}`);let W=B.isDirectory()?Or(G,"SKILL.md"):G,z=await As(W,200000),J=B.isDirectory()?$s(G):$s(W)==="SKILL.md"?$s(uf(W)):Gc(W).name,K=sn(H,"name")??J;if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(K))throw Error("Skill name must be a lowercase kebab-case slug.");let q=await H.requireClient().resources.importSkill(U.projectId,{slug:K,content:z.content});return Rs(H,Os.name,q.skill,`Imported skill ${K}`),0}},Ns={name:"agent import",summary:"Create a project-scoped agent from a local Markdown brief",usage:"Usage: hlix agent import <markdown-file> [--name <name>] [--runtime <runtime>] [--duty <duty>] [--profile <profile>] [--project <id>] [--json]",supportsJson:!0,options:["name","runtime","duty","profile","project"],args:{min:1,max:1},async run(H){if(H.args.length!==1)throw Error("agent import requires one Markdown file.");let U=Ts(H),G=Nr(H.cwd,H.args[0]);if(![".md",".mdx"].includes(mf(G).toLowerCase()))throw Error("Agent imports must be Markdown files.");let B=await As(G,20000),W=sn(H,"runtime");if(W!==void 0&&!s.includes(W)){let q=new Intl.ListFormat("en",{type:"disjunction"}).format(s);throw Error(`--runtime must be ${q}.`)}let z=sn(H,"duty")??"executor";if(z!=="executor"&&z!=="intake")throw Error("--duty must be executor or intake.");let J=sn(H,"name")??gf(B.content)??Gc(G).name.replace(/[-_]+/g," "),K=await H.requireClient().resources.importAgent(U.projectId,{name:J,instructions:B.content,...W?{runtimeKind:W}:{},duty:z});return Rs(H,Ns.name,K.agent,K.agent.duty==="intake"?`Imported agent ${K.agent.name} as this project's intake agent`:`Imported agent ${K.agent.name}`),0}},Fs={name:"mcp import",summary:"Explicitly activate one validated local MCP server",usage:"Usage: hlix mcp import <.mcp.json> [--server <name>] [--allow-stdio] [--project <id>] [--json]",supportsJson:!0,options:["server","allow-stdio","project"],args:{min:1,max:1},async run(H){if(H.args.length!==1)throw Error("mcp import requires one MCP JSON file.");let U=Ts(H),G=await As(Nr(H.cwd,H.args[0]),200000),B;try{B=JSON.parse(G.content)}catch{throw Error("MCP config is not valid JSON.")}let W=Object.entries(B.mcpServers??{});if(W.length===0)throw Error("MCP config contains no servers.");let z=sn(H,"server");if(!z&&W.length>1)throw Error("MCP config contains multiple servers; select one with --server <name>.");let J=z?W.find(([te])=>te===z):W[0];if(!J)throw Error(`MCP server not found: ${z}`);let[K,q]=J,X=q.type==="http"||q.type==="sse"?q.type:typeof q.command==="string"?"stdio":typeof q.url==="string"?"http":null;if(!X)throw Error(`MCP server ${K} has no supported transport.`);if(X==="stdio"&&H.flags["allow-stdio"]!==!0)throw Error("Stdio MCP servers execute a command on the Cloud Machine; repeat with --allow-stdio.");let V=q.env&&typeof q.env==="object"&&!Array.isArray(q.env)?q.env:{},Z=q.headers&&typeof q.headers==="object"&&!Array.isArray(q.headers)?q.headers:{};if(Object.values(Z).some((te)=>typeof te!=="string"))throw Error(`MCP server ${K} headers must be strings.`);for(let[te,re]of Object.entries(V)){if(typeof re!=="string")continue;let ae=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(re)?.[1];if(ae&&ae!==te)throw new e("invalid_usage",`MCP server ${K}: env ${te} references \${${ae}}, but a placeholder must be the variable's own name — write "${te}": "\${${te}}" and store the secret as ${te}.`)}let Q=Object.values(Z).flatMap((te)=>[...te.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g)].map((re)=>re[1]));if(Object.keys(Z).length>0&&Q.length===0)throw Error("MCP remote headers must use ${KEY} placeholders; literal credentials are refused.");let ne=/^(?:(?:Bearer|Basic|Token) )?\$\{[A-Za-z_][A-Za-z0-9_]*\}$/i;if(Object.values(Z).some((te)=>!ne.test(te)))throw Error("MCP remote headers must be ${KEY} or an approved auth scheme followed by ${KEY}.");let ce=await H.requireClient().resources.importMcp(U.projectId,{name:K,transport:X,...typeof q.command==="string"?{command:q.command}:{},...Array.isArray(q.args)&&q.args.every((te)=>typeof te==="string")?{args:q.args}:{},...typeof q.url==="string"?{url:q.url}:{},...Object.keys(Z).length>0?{headers:Z}:{},envKeys:[...new Set([...Object.keys(V),...Q])].sort()});return Rs(H,Fs.name,ce.mcpServer,`Imported MCP server ${K}`),0}};import{spawnSync as wf}from"node:child_process";import{chmod as vf,realpath as bf,writeFile as kf}from"node:fs/promises";import{basename as Sf,dirname as xf,relative as jf,resolve as Wc,sep as Ef}from"node:path";var Bc=64;function Un(H){let U=t(H.cwd),B=(typeof H.flags.project==="string"?H.flags.project:void 0)??U?.config.projectId;if(!B)throw new e("not_initialized","This folder is not bound to a Hlix project. Run `hlix import .`, or pass --project <id>.");return{projectId:B,root:U?.root??H.cwd}}var Dn=(H,U)=>typeof H[U]==="string"?H[U]:void 0,Ls={name:"secrets list",summary:"Show every secret the project holds, masked, with its source file",usage:["Usage: hlix secrets list [--project <id>] [--json]","","One row per (key, source file). Values are masked to their last four","characters and there is no flag that unmasks them — `hlix secrets export`","is the one command that returns plaintext, and it is audited."].join(`
369
- `),supportsJson:!0,options:["project"],async run(H){let{projectId:U}=Un(H),G=await H.requireClient().secrets.listEntries(U);if(H.json)return H.stdout(ge(he(Ls.name,G))),0;if(G.entries.length===0)H.stdout(`No secrets stored for this project.
370
- `);else H.stdout(`${nt(["key","source","format","value","updated"],G.entries.map((B)=>[B.key,B.source,B.format||"-",B.maskedValue,B.updatedAt?.slice(0,10)??"-"]))}
371
- `);for(let B of G.warnings)H.stderr(`warning: ${B}
372
- `);return 0}},Hs={name:"secrets set",summary:"Create or replace one secret in the store",usage:["Usage: hlix secrets set <KEY> [value] [--from-stdin] [--source <file>] [--project <id>] [--json]",""," --from-stdin Read the value from stdin instead of the argument, so it"," never reaches shell history or `ps`. Use this for real"," credentials: `pbpaste | hlix secrets set API_KEY --from-stdin`."," --source The file the value belongs to, e.g. apps/api/.env.local."," Omitted means the project root .env.","","Exactly one trailing newline is stripped from stdin, so a piped value does","not acquire the shell's."].join(`
373
- `),supportsJson:!0,options:["from-stdin","source","project"],args:{min:1,max:2},async run(H){let{projectId:U}=Un(H),G=H.args[0],B=H.flags["from-stdin"]===!0;if(B&&H.args.length>1)throw new e("invalid_usage","Pass the value as an argument or with --from-stdin, not both.");if(!B&&H.args.length<2)throw new e("missing_argument","A value is required. Pass it as an argument, or pipe it with --from-stdin.");let W;if(B){if(!H.readStdin)throw new e("invalid_usage","--from-stdin is not available in this context.");W=(await H.readStdin()).replace(/\r?\n$/,"")}else W=H.args[1];let z=Dn(H.flags,"source"),J=await H.requireClient().secrets.upsertEntries(U,{entries:[{key:G,value:W,...z?{source:z}:{}}]});if(H.json)return H.stdout(ge(he(Hs.name,J))),J.written>0?0:1;if(J.written===0)throw new e("bad_request",`The store refused ${G}: --source must be a project-relative file path.`);return H.stdout(`${Ae([["key",G],["source",z??".env"]])}
374
- `),0}},Ms={name:"secrets delete",summary:"Remove one secret from the store",usage:["Usage: hlix secrets delete <KEY> [--source <file>] [--project <id>] [--json]","","Without --source the key is removed from EVERY file that declares it,",'which is what "delete this secret" usually means. Removing nothing exits 1.'].join(`
375
- `),supportsJson:!0,options:["source","project"],args:{min:1,max:1},async run(H){let{projectId:U}=Un(H),G=H.args[0],B=Dn(H.flags,"source"),W=await H.requireClient().secrets.deleteEntry(U,G,B);if(H.json)return H.stdout(ge(he(Ms.name,W))),W.removed>0?0:1;if(W.removed===0)return H.stderr(`No stored secret named ${G}${B?` in ${B}`:""}.
376
- `),1;return H.stdout(`Removed ${W.removed} entr${W.removed===1?"y":"ies"} for ${G}.
377
- `),0}},Fr={name:"secrets import",summary:"Load this folder's secret files into the project secrets store",usage:["Usage: hlix secrets import [file...] [--project <id>] [--json]","","With no arguments, every secret file the project scanner detects. Naming","files narrows it to those; a named file the scanner does not consider a","secret is refused rather than uploaded.","","The files are uploaded as bytes and the server parses them, so every shape","it knows lands here: dotenv and .envrc, Terraform variables, Java","properties, Spring YAML, .NET appsettings, Azure Functions local settings,","npm credentials, Rails database.yml, wrangler/fly TOML and Serverless all","become readable entries under their own path. An opaque credential (a","private key, a keystore, a service-account JSON) is kept byte-exact","instead. A file whose plaintext this platform does not hold — SOPS,","Ansible Vault, git-crypt — and a .env.example are reported as skipped.","","A file that holds key/value pairs REPLACES what the store held for that","path: the file on this machine is the truth."].join(`
378
- `),supportsJson:!0,options:["project"],args:{min:0,max:64},async run(H){let{projectId:U,root:G}=Un(H),B=await tt(G,{historyMode:"preserve",environment:H.env}),W=B.blocking.filter((Z)=>!Z.startsWith(os));if(W.length>0)throw new e("scan_blocked",`Project scan blocked the import:
379
- - ${W.join(`
380
- - `)}`);let z=B.protectedFiles.filter((Z)=>Z.kind==="dotenv"||Z.kind==="credential"),J=await bf(H.cwd),K=H.args.map((Z)=>jf(B.root,Wc(J,Z)).split(Ef).join("/")),q=K.filter((Z)=>!z.some((Q)=>Q.path===Z));if(q.length>0)throw new e("invalid_usage",`Not a secret file in this project: ${q.join(", ")}`);let X=K.length>0?z.filter((Z)=>K.includes(Z.path)):z;if(X.length===0)return H.stdout(H.json?ge(he(Fr.name,{imported:[],skipped:[],warnings:[],written:0,rejected:[]})):`No secret files found in this project.
381
- `),0;if(X.length>Bc)throw new e("invalid_usage",`${X.length} secret files exceeds the ${Bc} the store accepts in one request. Name the files to import, a batch at a time.`);let V=await H.requireClient().secrets.importFiles(U,X.map((Z)=>({path:Z.path,contentBase64:Z.contentBase64})));if(H.json)return H.stdout(ge(he(Fr.name,V))),0;if(V.imported.length>0)H.stdout(`${nt(["source","format","stored"],V.imported.map((Z)=>[Z.path,Z.format||"-",Z.kind==="file"?"as file":`${Z.entries} entr${Z.entries===1?"y":"ies"}`]))}
382
- `);if(H.stdout(`${V.written} value${V.written===1?"":"s"} stored.
383
- `),V.imported.some((Z)=>Z.kind!=="file"))H.stdout(`Each imported file replaced what the store held under its path; keys the file no longer has are gone.
384
- `);for(let Z of V.skipped)H.stderr(`skipped ${Z.path}: ${Z.reason}
385
- `);for(let Z of V.warnings)H.stderr(`warning: ${Z}
386
- `);for(let Z of V.rejected)H.stderr(`rejected ${Z}: the store refused its source path
387
- `);return 0}};function Pf(H){return wf("git",["-C",xf(H),"ls-files","--error-unmatch","--",Sf(H)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}).status===0}var Ds={name:"secrets export",summary:"Render one source file back out of the store, values in clear",usage:["Usage: hlix secrets export [--source <file>] [--format <id>] [--out <path>] [--project <id>] [--json]",""," --source Which stored file to render. Omitted means the root .env."," --format Re-render it as a different shape (dotenv, tfvars, …)."," Omitted means the shape the values were parsed as."," --out Write it to this path, mode 0600, instead of stdout. A path"," git TRACKS is refused: an exported file carries plaintext and"," must not become a commit.","","This is the one command that returns secret values, and the server writes","an audit row for every call."].join(`
388
- `),supportsJson:!0,options:["source","format","out","project"],async run(H){let{projectId:U}=Un(H),G=Dn(H.flags,"source"),B=Dn(H.flags,"format"),W=Dn(H.flags,"out"),z=W===void 0?void 0:Wc(H.cwd,W);if(z!==void 0&&Pf(z))throw new e("invalid_usage",`Refusing to overwrite a git-tracked file with secret values: ${z}`);let J=await H.requireClient().secrets.exportEntries(U,{...G?{source:G}:{},...B?{format:B}:{}});if(z!==void 0)await kf(z,J,{mode:384}),await vf(z,384);if(H.json)return H.stdout(ge(he(Ds.name,{source:G??null,format:B??null,out:z??null,bytes:Buffer.byteLength(J),...z===void 0?{content:J}:{}}))),0;if(z===void 0)H.stdout(J);else H.stdout(`${Ae([["wrote",z],["mode","0600"],["bytes",String(Buffer.byteLength(J))]])}
389
- `);return 0}};function Gs(H){let U=H.flags.project;if(typeof U==="string"&&U)return U;return t(H.cwd)?.config.projectId??void 0}function Us(H,U){let G=H[U];if(typeof G!=="string"||G.trim()==="")throw new e("missing_argument",`--${U} is required.`);return G}var Bs={name:"cycles create",summary:"Propose a cycle, which starts the project working on it",usage:["Usage: hlix cycles create <project-id> --title <t> --description <d> [--json]","","This is the command that DISPATCHES work. The proposal enters the project's","own loop, which plans the cycle, creates its tasks and starts the coders —","using the project's harness (see `hlix harness get`).","","`adopted` is true when the loop took it on this call, false when it was","recorded and will be planned on the next pass. Neither is an error. The API","returns no cycle id: the roadmap owns cycles, so find it with `hlix tasks","list --project <id>` once planning has run."].join(`
390
- `),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(H){let U=H.args[0],G=Us(H.flags,"title"),B=Us(H.flags,"description"),W=await H.requireClient().cycles.propose({projectId:U,title:G,description:B});if(H.json)return H.stdout(ge(he(Bs.name,W))),0;return H.stdout(`${Ae([["project",U],["title",G],["status",W.adopted?"adopted — the project is planning it now":"recorded — it will be planned on the next pass"]])}
391
- `),0}},Ws={name:"tasks create",summary:"Add a task to a project's board",usage:["Usage: hlix tasks create <project-id> --description <d> [--title <t>] [--json]","","Creates the task row. It does NOT start it: standalone task execution is","not implemented server-side and answers 501 by design. Work is dispatched","by its cycle — use `hlix cycles create` for that."].join(`
392
- `),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(H){let U=H.args[0],G=Us(H.flags,"description"),B=typeof H.flags.title==="string"?H.flags.title:void 0,W=await H.requireClient().tasks.create({projectId:U,description:G,...B?{title:B}:{}});if(H.json)return H.stdout(ge(he(Ws.name,W))),0;return H.stdout(`${Ae([["task",W.id],["project",U],["status",W.status??"queued"],["note","not started — dispatch with `hlix cycles create`"]])}
393
- `),0}},zs={name:"harness get",summary:"Show which coder runs, and which setting chose it",usage:["Usage: hlix harness get [project-id] [--project <id>] [--json]","","With a project id — or from a bound folder — what that project would run.","Otherwise the workspace-wide answer. `source` names the setting that","decided: a project override, the workspace setting, or the default. The","JSON carries the whole Cycle group (provider, model, effort, how many run","at once) and the Operator model beside the harness."].join(`
394
- `),supportsJson:!0,options:["project"],args:{min:0,max:1},async run(H){let U=H.args[0]??Gs(H),G=H.requireClient(),B=U?await G.modelConfig.resolved(U):await G.modelConfig.resolved();if(H.json)return H.stdout(ge(he(zs.name,B))),0;return H.stdout(`${Ae([["scope",U?`project ${U}`:"workspace"],["harness",B.cycle.harness],["source",B.cycle.source.harness]])}
395
- `),0}},Js={name:"harness set",summary:"Choose the coder a project or the workspace runs",usage:[`Usage: hlix harness set <${s.join("|")}> [project-id] [--org] [--json]`,"","With a project id, sets that project's Cycle harness. With --org, the","workspace-wide one that projects fall back to. This is a PERSISTENT server","setting that every future run on that scope uses, and it is audited. A","provider the new harness cannot use (a ChatGPT login under Goose) goes","back to hlix-managed.","","It is not the same thing as the local `harness` config key, which only","picks the coder Hlix Code spawns on this machine."].join(`
396
- `),supportsJson:!0,options:["org"],args:{min:1,max:2},async run(H){let U=H.args[0];if(!s.includes(U))throw new e("invalid_usage",`harness must be one of ${s.join(", ")}; got "${U}".`);let G=H.flags.org===!0,B=H.args[1]??(G?void 0:Gs(H));if(B&&G)throw new e("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!B&&!G)throw new e("invalid_usage","Name the project to set, or pass --org for the whole workspace.");let W=H.requireClient(),z=B?await W.modelConfig.setProjectHarness(B,U):await W.modelConfig.setHarness(U);if(H.json)return H.stdout(ge(he(Js.name,z))),0;return H.stdout(`${Ae([["scope",B?`project ${B}`:"workspace"],["harness",U]])}
397
- `),0}},Ks={name:"harness clear",summary:"Remove a Cycle setting so the scope below it decides",usage:["Usage: hlix harness clear [project-id] [--org] [--json]","","With a project id, drops that project's Cycle override (harness, provider,","model, effort) so it inherits the workspace's. With --org, resets the","workspace's Cycle group to the default. Audited, like every write on this","setting.","","Answers `not_found` when that scope had no setting to clear — the","setting is already off, and saying so beats reporting a change that was","never made. Check the result with `hlix harness get`."].join(`
398
- `),supportsJson:!0,options:["org"],args:{min:0,max:1},async run(H){let U=H.flags.org===!0,G=H.args[0]??(U?void 0:Gs(H));if(G&&U)throw new e("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!G&&!U)throw new e("invalid_usage","Name the project to clear, or pass --org for the whole workspace.");let B=H.requireClient(),W=G?await B.modelConfig.clearProjectHarness(G):await B.modelConfig.clearHarness();if(H.json)return H.stdout(ge(he(Ks.name,W))),0;return H.stdout(`${Ae([["scope",G?`project ${G}`:"workspace"],["harness","cleared — the scope below decides now"]])}
399
- `),0}};var g=[ko,So,Xt,Ps,Is,_s,bs,vs,Ao,Ro,Oo,is,vc,wc,yc,hc,Uc,Os,Ns,Fs,Ls,Hs,Ms,Fr,Ds,No,Fo,Lo,Ho,Mo,Uo,Go,Bo,Wo,Ws,Bs,zs,Js,Ks];
400
- export{e,i,F,f,A,n,w,h,l,y,t,o,r,d,a,b,p,u,s,I,v,S,k,m,c,j,x,E,O,C,_,N,M,L,D,P,T,R,g};