@hlix/cli 1.0.3 → 1.0.4

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.
@@ -0,0 +1,407 @@
1
+ #!/usr/bin/env node
2
+ class e extends Error{code;details;constructor(O,N,L){super(N);if(this.name="CliError",this.code=O,L!==void 0)this.details=L}}var j=1,ae=(O,N)=>({schemaVersion:1,command:O,data:N}),Bt=(O,N)=>({schemaVersion:1,command:O,error:N});function oe(O){return`${JSON.stringify(O,null,2)}
3
+ `}function je(O){let N=Math.max(0,...O.map(([L])=>L.length));return O.map(([L,F])=>`${L.padEnd(N)} ${F}`).join(`
4
+ `)}function Je(O,N){let L=O.map((H,M)=>Math.max(H.length,...N.map((U)=>(U[M]??"").length))),F=(H)=>H.map((M,U)=>M.padEnd(L[U])).join(" ").trimEnd();return[F(O),F(L.map((H)=>"-".repeat(H))),...N.map(F)].join(`
5
+ `)}import{statSync as Ia}from"node:fs";import{dirname as Ta,resolve as Ra}from"node:path";import{closeSync as Qn,constants as Jt,existsSync as jn,fsyncSync as Ys,lstatSync as er,mkdirSync as va,openSync as Zs,readFileSync as Qs,renameSync as ba,statSync as eo,unlinkSync as to,writeFileSync as ka}from"node:fs";import{homedir as Sa}from"node:os";import{dirname as ja,join as tr}from"node:path";var at="https://server.hlix.ai";function De(O=process.env){let N=O.HLIX_CONFIG_HOME??O.XDG_CONFIG_HOME??tr(Sa(),".config");return tr(N,"hlix","credentials.json")}function no(O=process.env){let N=O.HLIX_API_KEY;if(!N&&O.HLIX_SESSION_TOKEN)return{baseUrl:O.HLIX_BASE_URL??at,apiKey:"",sessionToken:O.HLIX_SESSION_TOKEN,...O.HLIX_WORKSPACE_ID?{organizationId:O.HLIX_WORKSPACE_ID}:{}};if(N)return{baseUrl:O.HLIX_BASE_URL??at,apiKey:N,...O.HLIX_WORKSPACE_ID?{organizationId:O.HLIX_WORKSPACE_ID}:{}};try{let L=JSON.parse(Qs(De(O),"utf8"));return L.apiKey&&L.baseUrl?L:null}catch{return null}}function ro(O=process.env){let N=De(O);return jn(N)?N:null}function nr(O=process.env){let N=De(O);if(!jn(N))return{path:N,removed:!1,reason:"absent"};let L=er(N);if(L.isSymbolicLink()||!L.isFile())throw Error("Refusing to remove a credential path that is not a regular file.");let F=process.getuid?.();if(F!==void 0&&eo(N).uid!==F)throw Error("Refusing to remove a credential file owned by another user.");let H;try{H=JSON.parse(Qs(N,"utf8"))}catch{H=null}let M=H;if(!M||typeof M.apiKey!=="string"||typeof M.baseUrl!=="string")throw Error(`Refusing to remove ${N}: it is not a credential written by this CLI.`);return to(N),{path:N,removed:!0,reason:"removed"}}function so(O,N=process.env){let L=De(N),F=ja(L);if(va(F,{recursive:!0,mode:448}),er(F).isSymbolicLink())throw Error("Refusing to write credentials through a symlinked directory.");if(jn(L)){let U=er(L);if(U.isSymbolicLink()||!U.isFile())throw Error("Refusing to replace a credential path that is not a regular file.");let G=process.getuid?.();if(G!==void 0&&eo(L).uid!==G)throw Error("Refusing to replace a credential file owned by another user.")}let H=tr(F,`.credentials.${process.pid}.${crypto.randomUUID()}.tmp`),M;try{M=Zs(H,Jt.O_WRONLY|Jt.O_CREAT|Jt.O_EXCL|Jt.O_NOFOLLOW,384),ka(M,`${JSON.stringify(O,null,2)}
6
+ `,"utf8"),Ys(M),Qn(M),M=void 0,ba(H,L);let U=Zs(F,Jt.O_RDONLY);try{try{Ys(U)}catch(G){let D=G.code;if(D!=="EINVAL"&&D!=="ENOTSUP")throw G}}finally{Qn(U)}}catch(U){if(M!==void 0)Qn(M);if(jn(H))to(H);throw U}return L}import{constants as En,existsSync as sr,lstatSync as or,mkdirSync as Ea,openSync as xa,closeSync as oo,fsyncSync as Pa,readFileSync as io,renameSync as $a,unlinkSync as _a,writeFileSync as rr}from"node:fs";import{dirname as Ca,join as Wt,resolve as xn}from"node:path";function ao(O){if(!sr(O))return;let N=or(O);if(N.isSymbolicLink()||!N.isFile())throw Error(`Refusing to replace a non-regular Hlix file: ${O}`)}function qt(O,N){let L=Ca(O);if(Ea(L,{recursive:!0,mode:448}),or(L).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${L}`);ao(O);let F=Wt(L,`.hlix-${process.pid}-${crypto.randomUUID()}.tmp`),H;try{H=xa(F,En.O_WRONLY|En.O_CREAT|En.O_EXCL|En.O_NOFOLLOW,384),rr(H,`${JSON.stringify(N,null,2)}
7
+ `,"utf8"),Pa(H),oo(H),H=void 0,$a(F,O)}catch(M){if(H!==void 0)oo(H);if(sr(F))_a(F);throw M}}function zt(O){return Wt(xn(O),".hlix","config.json")}function co(O){return Wt(xn(O),".hlix","state.json")}function Pt(O){try{let N=JSON.parse(io(zt(O),"utf8"));return N.schemaVersion===1&&N.workspaceId&&N.apiUrl?N:null}catch{return null}}function Pn(O,N){qt(zt(O),N);let L=Wt(xn(O),".hlix",".gitignore");if(!sr(L))rr(L,`state.json
8
+ `,{mode:420,flag:"wx"});ao(L);let F=Wt(xn(O),".hlixignore");if(!or(F,{throwIfNoEntry:!1}))rr(F,`# Additional project-local paths to exclude from Hlix snapshots.
9
+ `,{mode:420,flag:"wx"})}function ir(O,N){qt(co(O),{...N,snapshotOnly:N.snapshotOnly??i(O)?.snapshotOnly,includedPaths:N.includedPaths??i(O)?.includedPaths})}function i(O){try{let N=JSON.parse(io(co(O),"utf8"));return N.schemaVersion===1&&N.repoId&&/^[a-f0-9]{40}$/.test(N.commitSha)?N:null}catch{return null}}function m(O){if(!O.credential)return null;if(O.credentialSource==="session")return"session (desktop)";if(O.credentialSource==="env")return"environment (HLIX_API_KEY)";return`file (${O.credentialPath})`}function t(O){let N=Ra(O);for(;;){let L=Pt(N);if(L)return{root:N,config:L};let F=Ta(N);if(F===N)return null;N=F}}function po(O){try{return Ia(O).isDirectory()}catch{return!1}}function $n(O){if(typeof O!=="string")return;let N=O.trim();return N?N:void 0}var lo=(O,N)=>O.replace(/\/+$/,"")===N.replace(/\/+$/,"");function r(O){let{env:N,flags:L,cwd:F}=O,H=t(F),M=no(N),U=M?N.HLIX_API_KEY?"env":N.HLIX_SESSION_TOKEN?"session":"file":null,G=U==="file"?M:null,D=$n(L["base-url"]),B=$n(N.HLIX_BASE_URL),J=$n(L.workspace),W=$n(N.HLIX_WORKSPACE_ID),z=D??B??H?.config.apiUrl??G?.baseUrl??at,Q=D?"flag":B?"env":H?.config.apiUrl?"project":G?.baseUrl?"credential":"default",te=J??W??H?.config.workspaceId??G?.organizationId??null,V=J?"flag":W?"env":H?.config.workspaceId?"project":G?.organizationId?"credential":null;return{baseUrl:z,baseUrlSource:Q,workspaceId:te,workspaceSource:V,credential:M,credentialSource:U,credentialPath:De(N),binding:H,conflict:Aa(H,{flagBaseUrl:D,envBaseUrl:B,flagWorkspace:J,envWorkspace:W})}}function Aa(O,N){if(!O)return null;let L=`${O.root} is bound to`,F="Drop the override, or point --cwd at a folder bound to it.";if(N.flagWorkspace&&N.flagWorkspace!==O.config.workspaceId)return`${L} workspace ${O.config.workspaceId}, but --workspace names ${N.flagWorkspace}. ${F}`;if(N.envWorkspace&&N.envWorkspace!==O.config.workspaceId)return`${L} workspace ${O.config.workspaceId}, but HLIX_WORKSPACE_ID names ${N.envWorkspace}. ${F}`;if(N.flagBaseUrl&&!lo(N.flagBaseUrl,O.config.apiUrl))return`${L} ${O.config.apiUrl}, but --base-url names ${N.flagBaseUrl}. ${F}`;if(N.envBaseUrl&&!lo(N.envBaseUrl,O.config.apiUrl))return`${L} ${O.config.apiUrl}, but HLIX_BASE_URL names ${N.envBaseUrl}. ${F}`;return null}import{resolve as tc}from"node:path";import{parseArgs as nc}from"node:util";import Oa from"openapi-fetch";function ar(O){return Oa({baseUrl:O.baseUrl,headers:O.headers,fetch:O.fetch})}var $t=(O)=>({kind:"apiKey",apiKey:O});var cr=(O)=>({kind:"bearer",token:O});function Na(O){switch(O.kind){case"apiKey":return{"x-api-key":O.apiKey};case"session":return{cookie:O.cookie};case"bearer":return{authorization:`Bearer ${O.token}`}}}function La(O){return O?{"X-Organization-Id":O}:{}}function uo(O,N){return{...Na(O),...La(N)}}function Fa(O){if(typeof O!=="object"||O===null)return null;let{error:N}=O;return typeof N==="string"?N:null}class Ce extends Error{status;body;requestId;method;url;constructor(O,N){super(O);this.name=new.target.name,this.status=N.status,this.body=N.body,this.requestId=N.requestId??null,this.method=N.method,this.url=N.url}}class _t extends Ce{issues;constructor(O,N,L){super(O,N);this.issues=L}}class Kt extends Ce{}class Vt extends Ce{}class Xt extends Ce{}class ct extends Ce{}class lt extends Ce{}class dt extends Ce{retryAfter;constructor(O,N,L){super(O,N);this.retryAfter=L}}class Yt extends Ce{}class pt extends Ce{}class Ze extends Error{method;url;constructor(O,N){super(O,{cause:N.cause});this.name="HlixTransportError",this.method=N.method,this.url=N.url}}function Ha(O){if(typeof O!=="object"||O===null)return null;let N=O;if(N.success!==!1)return null;let L=N.error?.message;if(typeof L!=="string")return null;try{let F=JSON.parse(L);return Array.isArray(F)?F:[]}catch{return[]}}function Ma(O){let N=O.get("retry-after");if(!N)return null;let L=Number(N);return Number.isFinite(L)&&L>=0?L:null}function ut(O,N,L){let F={status:O.status,body:N,requestId:O.headers.get("x-request-id"),method:L.method,url:L.url},H=Fa(N),M=`${L.method} ${L.url} failed with ${O.status}`,U=Ha(N);if(U)return new _t(`${L.method} ${L.url}: request body failed validation`,F,U);let G=H??M;switch(O.status){case 400:return new Kt(G,F);case 401:return new Vt(G,F);case 403:return new Xt(G,F);case 404:return new ct(G,F);case 409:return new lt(G,F);case 429:return new dt(G,F,Ma(O.headers));case 501:return new Yt(G,F);default:return O.status>=500?new pt(G,F):new Ce(G,F)}}var mo=new Set(["GET","HEAD","PUT","DELETE","OPTIONS","TRACE"]);function _n(O){return mo.has(O.toUpperCase())}var Ua=new Set([429,500,502,503,504]);function Da(O){return Ua.has(O)}var lr={attempts:3,baseDelayMs:200,maxDelayMs:5000};function Zt(O,N,L,F=Math.random){if(L!==null)return Math.min(L*1000,N.maxDelayMs);let H=Math.min(N.baseDelayMs*2**O,N.maxDelayMs);return Math.round(F()*H)}function dr(O){if(!_n(O.method))return!1;if(O.attempt+1>=O.policy.attempts)return!1;return O.status===null||Da(O.status)}var Ga=(O)=>new Promise((N)=>setTimeout(N,O));function Ba(O){let N=O.headers.get("retry-after");if(!N)return null;let L=Number(N);return Number.isFinite(L)&&L>=0?L:null}function fo(O){let{base:N,policy:L}=O,F=O.sleep??Ga,H=O.random??Math.random;return async(M)=>{let U=M.method.toUpperCase(),G=_n(U)?M.clone():null;for(let D=0;;D+=1){let B=D===0?M:G.clone(),J;try{J=await N(B)}catch(W){if(!G||!dr({method:U,attempt:D,policy:L,status:null}))throw new Ze(`${U} ${M.url}: ${W instanceof Error?W.message:String(W)}`,{method:U,url:M.url,cause:W});await F(Zt(D,L,null,H));continue}if(!dr({method:U,attempt:D,policy:L,status:J.status}))return J;if(!G)return J;await F(Zt(D,L,Ba(J),H))}}}function se(O,N){if(O.response.ok)return O.data;throw ut(O.response,O.error??O.data,N)}var Qt=(O)=>typeof O==="string"?O:"";function pr(O){let N;try{N=JSON.parse(O)}catch{return null}if(typeof N!=="object"||N===null)return null;let L=N;switch(L.type){case"idle":return{type:"idle"};case"done":return{type:"done"};case"active":return typeof L.runId==="string"?{type:"active",runId:L.runId}:{type:"active"};case"on_chat_model_stream":return{type:"on_chat_model_stream",delta:Qt(L.delta)};case"reasoning":return{type:"reasoning",delta:Qt(L.delta)};case"on_tool_start":return{type:"on_tool_start",name:Qt(L.name),input:L.input};case"on_tool_end":return{type:"on_tool_end",name:Qt(L.name),output:L.output};case"error":return{type:"error",message:Qt(L.message)};default:return null}}var ur=(O)=>O.type==="done"||O.type==="idle"||O.type==="error";var Ja=()=>({event:null,data:[],id:null,retry:null});function go(O,N,L){switch(N){case"event":O.event=L;return;case"data":O.data.push(L);return;case"id":if(!L.includes("\x00"))O.id=L;return;case"retry":{if(/^\d+$/.test(L))O.retry=Number(L);return}default:return}}function yo(O){let N=O.data.join(`
10
+ `),{event:L,id:F}=O;if(O.data=[],O.event=null,N==="")return null;return{event:L,data:N,id:F,retry:O.retry}}function ho(O,N){if(N==="")return yo(O);if(N.startsWith(":"))return null;let L=N.indexOf(":");if(L===-1)return go(O,N,""),null;let F=N.slice(0,L),H=N.slice(L+1);if(H.startsWith(" "))H=H.slice(1);return go(O,F,H),null}function Wa(O){let N=[],L=0;for(let F=0;F<O.length;F+=1){let H=O[F];if(H!==`
11
+ `&&H!=="\r")continue;if(N.push(O.slice(L,F)),H==="\r"&&O[F+1]===`
12
+ `)F+=1;L=F+1}return{lines:N,rest:O.slice(L)}}async function*Cn(O,N){let L=O.getReader(),F=new TextDecoder,H=Ja(),M="",U=()=>void L.cancel().catch(()=>{});N?.addEventListener("abort",U,{once:!0});try{for(;;){let{done:D,value:B}=await L.read();if(D)break;M+=F.decode(B,{stream:!0});let{lines:J,rest:W}=Wa(M);M=W;for(let z of J){let Q=ho(H,z);if(Q)yield Q}if(N?.aborted)return}if(M+=F.decode(),M!==""){let D=ho(H,M);if(D)yield D}let G=yo(H);if(G)yield G}finally{N?.removeEventListener("abort",U),L.releaseLock()}}function Qe(O,N){return new Promise((L)=>{if(N?.aborted)return L();let F=setTimeout(H,O);function H(){clearTimeout(F),N?.removeEventListener("abort",H),L()}N?.addEventListener("abort",H,{once:!0})})}var fr=()=>crypto.randomUUID();function bo(O){return{threadId:O.threadId,runId:O.runId??fr(),state:{},messages:[{id:O.messageId??fr(),role:"user",content:O.text}],tools:[],context:[],forwardedProps:O.forwardedProps??{}}}function ko(O,N){return{threadId:O,runId:fr(),state:{},messages:[],tools:[],context:[],...N?{lastSeenEventId:N}:{}}}function gr(O){let N=O.metadata;if(typeof N!=="object"||N===null)return;let L=N.eventId;return typeof L==="string"&&L?L:void 0}function hr(O){let N;try{N=JSON.parse(O)}catch{return null}if(typeof N!=="object"||N===null)return null;return typeof N.type==="string"?N:null}function mt(O,N={}){if(N.taskId)return`project:${O}:task:${N.taskId}`;if(N.cycleId)return`project:${O}:cycle:${N.cycleId}`;return`project:${O}`}var qa=new Set(["done","merged","failed","pr_created","ci_passing"]),za=new Set(["done","pr_created","failed","canceled"]);function yr(O,N){let L=O.tasks.find((U)=>U.id===N);if(!L)return{state:"running",task:L};let F=L.cycleId?O.cycles.find((U)=>U.id===L.cycleId):void 0;if(!(!L.cycleId||F!==void 0&&za.has(F.status)))return{state:"running",task:L};if(qa.has(L.status))return{state:"finished",task:L};if(!F)return{state:"running",task:L};let M=F?.status==="canceled"?"Task cycle was canceled":F?.status==="failed"?"Task cycle failed":"Task cycle ended before this task completed";return{state:"unmet",task:L,reason:M}}async function*wr(O){let N;for await(let L of O){if(L.type==="STATE_SNAPSHOT")N=structuredClone(L.snapshot);else if(L.type==="STATE_DELTA"){if(N===void 0)continue;N=So(N,L.delta)}else if(L.type!=="CUSTOM"||N===void 0)continue;yield{state:N,event:L}}}function vr(O){if(O==="")return[];if(!O.startsWith("/"))throw Error(`Invalid JSON pointer: ${O}`);return O.slice(1).split("/").map((N)=>N.replace(/~1/g,"/").replace(/~0/g,"~"))}function br(O,N){let L=O;for(let F of N.slice(0,-1)){if(typeof L!=="object"||L===null)throw Error(`Path not found: /${N.join("/")}`);L=L[F]}if(typeof L!=="object"||L===null)throw Error(`Path not found: /${N.join("/")}`);return{parent:L,key:N[N.length-1]}}function In(O,N,L){if(N==="-"&&L)return O.length;let F=Number(N);if(!/^(0|[1-9]\d*)$/.test(N)||F>O.length||!L&&F===O.length)throw Error(`Invalid array index: ${N}`);return F}function wo(O,N){let L=vr(N);if(L.length===0)return O;let{parent:F,key:H}=br(O,L);if(Array.isArray(F))return F[In(F,H,!1)];if(!(H in F))throw Error(`Path not found: ${N}`);return F[H]}function vo(O,N){let{parent:L,key:F}=br(O,vr(N));if(Array.isArray(L))return L.splice(In(L,F,!1),1)[0];if(!(F in L))throw Error(`Path not found: ${N}`);let H=L[F];return delete L[F],H}function mr(O,N,L,F){let H=vr(N);if(H.length===0)return L;let{parent:M,key:U}=br(O,H);if(Array.isArray(M))if(F==="add")M.splice(In(M,U,!0),0,L);else M[In(M,U,!1)]=L;else{if(F==="replace"&&!(U in M))throw Error(`Path not found: ${N}`);M[U]=L}return O}function So(O,N){let L=structuredClone(O);for(let F of N)switch(F.op){case"add":case"replace":L=mr(L,F.path,structuredClone(F.value),F.op);break;case"remove":vo(L,F.path);break;case"copy":L=mr(L,F.path,structuredClone(wo(L,F.from)),"add");break;case"move":{let H=vo(L,F.from);L=mr(L,F.path,H,"add");break}case"test":if(JSON.stringify(wo(L,F.path))!==JSON.stringify(F.value))throw Error(`Test failed at ${F.path}`);break;default:throw Error(`Unknown patch operation: ${F.op}`)}return L}var Ka={attempts:6,baseDelayMs:500,maxDelayMs:15000};function Va(O){if(O instanceof pt||O instanceof dt)return!0;return!(O instanceof Ce)}class Ct{raw;baseUrl;headers;fetcher;constructor(O){this.baseUrl=O.baseUrl.replace(/\/+$/,"");let N=uo(O.credential,O.organizationId),L=new Set(Object.keys(N).map((M)=>M.toLowerCase()));this.headers={...Object.fromEntries(Object.entries(O.headers??{}).filter(([M])=>!L.has(M.toLowerCase()))),...N};let F={...lr,...O.retry},H=O.fetch??((M)=>globalThis.fetch(M));this.fetcher=fo({base:H,policy:F}),this.raw=ar({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(O,N){return{method:O,url:`${this.baseUrl}${N}`}}workspaces={list:async(O={})=>se(await this.raw.GET("/v1/api/workspaces",O),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>se(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(O,N={})=>se(await this.raw.GET("/v1/api/projects/{id}",{...N,params:{path:{id:O}}}),this.at("GET",`/v1/api/projects/${O}`)),create:async(O)=>se(await this.raw.POST("/v1/api/projects",{body:O}),this.at("POST","/v1/api/projects")),delete:async(O)=>se(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:O}}}),this.at("DELETE",`/v1/api/projects/${O}`)),start:async(O,N)=>se(await this.raw.POST("/v1/api/projects/{id}/start",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/projects/${O}/start`)),stop:async(O)=>se(await this.raw.POST("/v1/api/projects/{id}/stop",{params:{path:{id:O}}}),this.at("POST",`/v1/api/projects/${O}/stop`)),resume:async(O)=>se(await this.raw.POST("/v1/api/projects/{id}/resume",{params:{path:{id:O}}}),this.at("POST",`/v1/api/projects/${O}/resume`)),status:async(O,N={})=>se(await this.raw.GET("/v1/api/projects/{id}/status",{...N,params:{path:{id:O}}}),this.at("GET",`/v1/api/projects/${O}/status`)),deliver:async(O)=>se(await this.raw.POST("/v1/api/projects/{id}/delivery",{params:{path:{id:O}}}),this.at("POST",`/v1/api/projects/${O}/delivery`)),attachGithubRepository:async(O,N)=>se(await this.raw.POST("/v1/api/projects/{id}/repos/github",{params:{path:{id:O}},body:{githubRepository:N}}),this.at("POST",`/v1/api/projects/${O}/repos/github`)),terminal:async(O)=>se(await this.raw.GET("/v1/api/projects/{id}/terminal",{params:{path:{id:O}}}),this.at("GET",`/v1/api/projects/${O}/terminal`)),observeCycle:(O,N)=>this.observeCycle(O,N),workspace:(O)=>({environment:async()=>se(await this.raw.GET("/v1/api/projects/{id}/environment",{params:{path:{id:O}}}),this.at("GET",`/v1/api/projects/${O}/environment`)),fs:async(N)=>se(await this.raw.POST("/v1/api/projects/{id}/workspace/fs",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/projects/${O}/workspace/fs`)),exec:async(N)=>se(await this.raw.POST("/v1/api/projects/{id}/workspace/exec",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/projects/${O}/workspace/exec`))})};secrets={listEntries:async(O)=>se(await this.raw.GET("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:O}}}),this.at("GET",`/v1/api/secrets/project/${O}/entries`)),upsertEntries:async(O,N)=>se(await this.raw.PUT("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:O}},body:N}),this.at("PUT",`/v1/api/secrets/project/${O}/entries`)),importFiles:async(O,N)=>se(await this.raw.PUT("/v1/api/secrets/project/{projectId}/files",{params:{path:{projectId:O}},body:{files:N}}),this.at("PUT",`/v1/api/secrets/project/${O}/files`)),deleteEntry:async(O,N,L)=>se(await this.raw.DELETE("/v1/api/secrets/project/{projectId}/entries/{key}",{params:{path:{projectId:O,key:N},...L===void 0?{}:{query:{source:L}}}}),this.at("DELETE",`/v1/api/secrets/project/${O}/entries/${encodeURIComponent(N)}`)),exportEntries:async(O,N={})=>{let L=`/v1/api/secrets/project/${O}/export`,F=`${this.baseUrl}${L}`,H=await this.fetcher(new Request(F,{method:"POST",headers:{...this.headers,"content-type":"application/json"},body:JSON.stringify({...N.source===void 0?{}:{source:N.source},...N.format===void 0?{}:{format:N.format}})}));if(!H.ok)throw ut(H,await H.json().catch(()=>{return}),{method:"POST",url:F});return H.text()}};repos={access:async(O,N,L="read")=>se(await this.raw.POST("/v1/api/projects/{id}/repos/{repoId}/access",{params:{path:{id:O,repoId:N}},body:{scope:L}}),this.at("POST",`/v1/api/projects/${O}/repos/${N}/access`)),head:async(O,N,L={})=>se(await this.raw.GET("/v1/api/projects/{id}/repos/{repoId}/head",{...L,params:{path:{id:O,repoId:N}}}),this.at("GET",`/v1/api/projects/${O}/repos/${N}/head`)),protectedFiles:async(O)=>se(await this.raw.GET("/v1/api/projects/{id}/protected-files",{params:{path:{id:O}}}),this.at("GET",`/v1/api/projects/${O}/protected-files`)),watch:(O,N,L={})=>this.watchRepo(O,N,L)};resources={importSkill:async(O,N)=>se(await this.raw.POST("/v1/api/projects/{id}/resources/skill",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/projects/${O}/resources/skill`)),importAgent:async(O,N)=>se(await this.raw.POST("/v1/api/projects/{id}/resources/agent",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/projects/${O}/resources/agent`)),importMcp:async(O,N)=>se(await this.raw.POST("/v1/api/projects/{id}/resources/mcp",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/projects/${O}/resources/mcp`))};async throwUploadError(O,N){let L=null;try{L=await O.json()}catch{L=await O.text().catch(()=>null)}throw ut(O,L,{method:"PUT",url:N})}tasks={list:async(O)=>se(await this.raw.GET("/v1/api/tasks",{params:{query:O??{}}}),this.at("GET","/v1/api/tasks")),get:async(O)=>se(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:O}}}),this.at("GET",`/v1/api/tasks/${O}`)),create:async(O)=>se(await this.raw.POST("/v1/api/tasks",{body:O}),this.at("POST","/v1/api/tasks")),update:async(O,N)=>se(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:O}},body:N}),this.at("PATCH",`/v1/api/tasks/${O}`)),listComments:async(O)=>se(await this.raw.GET("/v1/api/tasks/{id}/comments",{params:{path:{id:O}}}),this.at("GET",`/v1/api/tasks/${O}/comments`)),addComment:async(O,N)=>se(await this.raw.POST("/v1/api/tasks/{id}/comments",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/tasks/${O}/comments`))};modelConfig={list:async()=>se(await this.raw.GET("/v1/api/model-config"),this.at("GET","/v1/api/model-config")),resolved:async(O)=>O?se(await this.raw.GET("/v1/api/model-config/projects/{projectId}/resolved",{params:{path:{projectId:O}}}),this.at("GET",`/v1/api/model-config/projects/${O}/resolved`)):se(await this.raw.GET("/v1/api/model-config/resolved"),this.at("GET","/v1/api/model-config/resolved")),set:async(O,N,L)=>L?se(await this.raw.PUT("/v1/api/model-config/projects/{projectId}/{slot}",{params:{path:{projectId:L,slot:O}},body:N}),this.at("PUT",`/v1/api/model-config/projects/${L}/${O}`)):se(await this.raw.PUT("/v1/api/model-config/{slot}",{params:{path:{slot:O}},body:N}),this.at("PUT",`/v1/api/model-config/${O}`)),clear:async(O,N)=>N?se(await this.raw.DELETE("/v1/api/model-config/projects/{projectId}/{slot}",{params:{path:{projectId:N,slot:O}}}),this.at("DELETE",`/v1/api/model-config/projects/${N}/${O}`)):se(await this.raw.DELETE("/v1/api/model-config/{slot}",{params:{path:{slot:O}}}),this.at("DELETE",`/v1/api/model-config/${O}`)),setProjectHarness:async(O,N)=>this.modelConfig.set("cycle",{harness:N},O),clearProjectHarness:async(O)=>this.modelConfig.clear("cycle",O),setHarness:async(O)=>this.modelConfig.set("cycle",{harness:O}),clearHarness:async()=>this.modelConfig.clear("cycle")};ai={models:async(O,N)=>se(await this.raw.GET("/v1/api/ai/w/{workspaceId}/models",{params:{path:{workspaceId:O}},...N?.signal?{signal:N.signal}:{}}),this.at("GET",`/v1/api/ai/w/${O}/models`))};managedMailboxes={configuration:async()=>se(await this.raw.GET("/v1/api/growth/managed-mailboxes/configuration",{}),this.at("GET","/v1/api/growth/managed-mailboxes/configuration")),quote:async(O)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/quotes",{body:O}),this.at("POST","/v1/api/growth/managed-mailboxes/quotes")),order:async(O)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/orders",{body:O}),this.at("POST","/v1/api/growth/managed-mailboxes/orders")),get:async(O)=>se(await this.raw.GET("/v1/api/growth/managed-mailboxes/orders/{orderId}",{params:{path:{orderId:O}}}),this.at("GET","/v1/api/growth/managed-mailboxes/orders/{orderId}")),reconcile:async(O)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/orders/{orderId}/reconcile",{params:{path:{orderId:O}}}),this.at("POST","/v1/api/growth/managed-mailboxes/orders/{orderId}/reconcile")),listOrders:async(O)=>se(await this.raw.GET("/v1/api/growth/managed-mailboxes/orders",{params:{query:{...O,limit:O?.limit===void 0?void 0:String(O.limit)}}}),this.at("GET","/v1/api/growth/managed-mailboxes/orders")),listResources:async(O)=>se(await this.raw.GET("/v1/api/growth/managed-mailboxes/resources",{params:{query:{...O,limit:O?.limit===void 0?void 0:String(O.limit)}}}),this.at("GET","/v1/api/growth/managed-mailboxes/resources")),repair:async(O,N)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/repair",{params:{path:{resourceId:O}},body:N}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/repair")),cancelHosting:async(O,N)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-hosting",{params:{path:{resourceId:O}},body:N}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-hosting")),cancelWarmup:async(O,N)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-warmup",{params:{path:{resourceId:O}},body:N}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-warmup")),removeDomain:async(O,N)=>se(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/remove-domain",{params:{path:{resourceId:O}},body:N}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/remove-domain"))};mcpServers={list:async()=>se(await this.raw.GET("/v1/api/mcp-servers",{}),this.at("GET","/v1/api/mcp-servers")),get:async(O)=>se(await this.raw.GET("/v1/api/mcp-servers/{id}",{params:{path:{id:O}}}),this.at("GET",`/v1/api/mcp-servers/${O}`)),create:async(O)=>se(await this.raw.POST("/v1/api/mcp-servers",{body:O}),this.at("POST","/v1/api/mcp-servers")),update:async(O,N)=>se(await this.raw.PATCH("/v1/api/mcp-servers/{id}",{params:{path:{id:O}},body:N}),this.at("PATCH",`/v1/api/mcp-servers/${O}`)),delete:async(O)=>se(await this.raw.DELETE("/v1/api/mcp-servers/{id}",{params:{path:{id:O}}}),this.at("DELETE",`/v1/api/mcp-servers/${O}`)),discover:async(O)=>se(await this.raw.POST("/v1/api/mcp-servers/{id}/discover",{params:{path:{id:O}}}),this.at("POST",`/v1/api/mcp-servers/${O}/discover`)),connect:async(O)=>se(await this.raw.POST("/v1/api/mcp-servers/{id}/connect",{params:{path:{id:O}}}),this.at("POST",`/v1/api/mcp-servers/${O}/connect`)),disconnect:async(O)=>se(await this.raw.POST("/v1/api/mcp-servers/{id}/disconnect",{params:{path:{id:O}}}),this.at("POST",`/v1/api/mcp-servers/${O}/disconnect`))};tools={search:async(O)=>se(await this.raw.GET("/v1/api/tools",{params:{query:{...O,limit:O?.limit===void 0?void 0:String(O.limit)}}}),this.at("GET","/v1/api/tools")),describe:async(O)=>se(await this.raw.GET("/v1/api/tools/{toolId}",{params:{path:{toolId:O}}}),this.at("GET",`/v1/api/tools/${O}`)),call:async(O,N)=>se(await this.raw.POST("/v1/api/tools/{toolId}/call",{params:{path:{toolId:O}},body:N}),this.at("POST",`/v1/api/tools/${O}/call`)),status:async(O)=>se(await this.raw.GET("/v1/api/tool-calls/{callId}",{params:{path:{callId:O}}}),this.at("GET",`/v1/api/tool-calls/${O}`)),listCalls:async(O)=>se(await this.raw.GET("/v1/api/tool-calls",{params:{query:{...O,limit:O?.limit===void 0?void 0:String(O.limit)}}}),this.at("GET","/v1/api/tool-calls"))};cycles={list:async(O)=>se(await this.raw.GET("/v1/api/cycles",{params:{query:O??{}}}),this.at("GET","/v1/api/cycles")),get:async(O)=>se(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:O}}}),this.at("GET",`/v1/api/cycles/${O}`)),propose:async(O)=>se(await this.raw.POST("/v1/api/cycles",{body:O}),this.at("POST","/v1/api/cycles")),review:async(O)=>se(await this.raw.GET("/v1/api/cycles/{id}/review",{params:{path:{id:O}}}),this.at("GET",`/v1/api/cycles/${O}/review`)),reviewComments:async(O)=>se(await this.raw.GET("/v1/api/cycles/{id}/review/comments",{params:{path:{id:O}}}),this.at("GET",`/v1/api/cycles/${O}/review/comments`))};chat={send:async(O)=>se(await this.raw.POST("/v1/api/chat/turns",{body:O}),this.at("POST","/v1/api/chat/turns")),turn:async(O,N)=>se(await this.raw.GET("/v1/api/chat/turns/{turnId}",{params:{path:{turnId:O},query:N}}),this.at("GET",`/v1/api/chat/turns/${O}`))};live={run:(O,N,L)=>this.liveStream(`/agent/${O}/run`,bo(N),L),connect:(O,N,L)=>this.liveStream(`/agent/${O}/connect`,ko(N,L?.lastSeenEventId),L),follow:(O,N,L={})=>this.followLive(O,N,L),stop:async(O,N,L)=>{let F=`/agent/${O}/stop/${encodeURIComponent(N)}`;return await(await this.livePost(F,L?{runId:L}:{})).json()},project:(O,N={})=>wr(this.live.follow("project-live",mt(O,N),N)),task:(O,N,L={})=>this.watchTask(O,N,L)};async*watchTask(O,N,L){let F="";for await(let{state:H}of this.live.project(O,{taskId:N,...L})){let M=yr(H,N),U=JSON.stringify(M);if(U===F)continue;if(F=U,yield M,M.state!=="running")return}}async*followLive(O,N,L){let F=L.retry??Ka,H=L.lastSeenEventId,M=0;while(!L.signal?.aborted){let U=!1,G=null;try{for await(let D of this.live.connect(O,N,{...L.signal?{signal:L.signal}:{},...H?{lastSeenEventId:H}:{}})){let B=gr(D);if(B)H=B;if(D.type!=="STATE_SNAPSHOT"&&D.type!=="MESSAGES_SNAPSHOT")M=0;if(D.type==="RUN_STARTED"||D.type==="STATE_SNAPSHOT"||B)U=!0;if(yield D,D.type==="RUN_FINISHED"||D.type==="RUN_ERROR")return}if(!U)return}catch(D){if(L.signal?.aborted)return;if(!Va(D))throw D;G=D}if(L.signal?.aborted)return;if(M+=1,M>=F.attempts)throw G??new Ze(`POST ${this.baseUrl}/v1/api/live/agent/${O}/connect: the stream kept closing`,{method:"POST",url:`${this.baseUrl}/v1/api/live/agent/${O}/connect`});await Qe(Zt(M,F,null),L.signal)}}async livePost(O,N,L){let F=`${this.baseUrl}/v1/api/live${O}`,H=await this.fetcher(new Request(F,{method:"POST",headers:{...this.headers,"content-type":"application/json",accept:"text/event-stream"},body:JSON.stringify(N),signal:L?.signal}));if(H.ok)return H;let M=null;try{M=await H.json()}catch{M=null}throw ut(H,M,{method:"POST",url:F})}async*liveStream(O,N,L){let F=await this.livePost(O,N,L);if(!F.body)return;try{for await(let H of Cn(F.body,L?.signal)){let M=hr(H.data);if(!M)continue;if(yield M,M.type==="RUN_FINISHED"||M.type==="RUN_ERROR")return}}finally{F.body.cancel().catch(()=>{})}}pendingRequests={list:async(O)=>se(await this.raw.GET("/v1/api/pending-requests",{params:{query:O??{}}}),this.at("GET","/v1/api/pending-requests")),resolve:async(O,N)=>se(await this.raw.POST("/v1/api/pending-requests/{id}/resolve",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/pending-requests/${O}/resolve`))};clientInvoices={list:async(O)=>se(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:O??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(O)=>se(await this.raw.GET("/v1/api/client-billing/invoices/{id}",{params:{path:{id:O}}}),this.at("GET",`/v1/api/client-billing/invoices/${O}`)),createDraft:async(O)=>se(await this.raw.POST("/v1/api/client-billing/invoices",{body:O}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(O)=>se(await this.raw.POST("/v1/api/client-billing/invoices/{id}/issue",{params:{path:{id:O}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${O}/issue`)),void:async(O,N)=>se(await this.raw.POST("/v1/api/client-billing/invoices/{id}/void",{params:{path:{id:O}},body:{reason:N}}),this.at("POST",`/v1/api/client-billing/invoices/${O}/void`)),pay:async(O)=>se(await this.raw.POST("/v1/api/client-billing/invoices/{id}/pay",{params:{path:{id:O}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${O}/pay`)),paymentLink:async(O,N={})=>se(await this.raw.POST("/v1/api/client-billing/invoices/{id}/payment-link",{params:{path:{id:O}},body:N}),this.at("POST",`/v1/api/client-billing/invoices/${O}/payment-link`))};async*observeCycle(O,N){let L=`/v1/api/cycles/${O}/observe`;for await(let F of this.stream(L,N)){let H=pr(F.data);if(!H)continue;if(yield H,ur(H))return}}async*watchRepo(O,N,L){let F;while(!L.signal?.aborted){let H=await this.repos.head(O,N,L);if(H.commitSha!==F)F=H.commitSha,yield{commitSha:F};await Qe(15000,L.signal)}}async*stream(O,N){let L=`${this.baseUrl}${O}`,F=new Request(L,{headers:{...this.headers,accept:"text/event-stream"},signal:N?.signal}),H=await globalThis.fetch(F);if(!H.ok||!H.body){let M=null;try{M=await H.json()}catch{M=null}throw ut(H,M,{method:"GET",url:L})}yield*Cn(H.body,N?.signal)}}var Xa=/\x1b(?:\[[0-?]*[ -/]*[@-~]?|\][^\x07\x1b]*(?:\x07|\x1b\\)?|[PX^_][^\x1b]*(?:\x1b\\)?|[\x20-\x7e]?)|\x9b[0-?]*[ -/]*[@-~]?/g,Ya=/[\x00-\x08\x0b-\x1f\x7f-\x9f]/g,Za=/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g,Qa=/(?<![\p{Extended_Pictographic}\p{Emoji_Modifier}\uFE0F])\u200D|\u200D(?!\p{Extended_Pictographic})|[^\P{Cf}\u200D]/gu,ec=/[\u2028\u2029]/g;function s(O,N={}){return O.replace(Xa,"").replace(N.carriageReturn?Za:Ya,"").replace(Qa,"").replace(ec,`
13
+ `)}function kr(O){if(O instanceof e)return{code:O.code,status:null};if(O instanceof _t)return{code:"invalid_request",status:400};if(O instanceof Kt)return{code:"bad_request",status:400};if(O instanceof Vt)return{code:"unauthenticated",status:401};if(O instanceof Xt)return{code:"forbidden",status:403};if(O instanceof ct)return{code:"not_found",status:404};if(O instanceof lt)return{code:"conflict",status:409};if(O instanceof dt)return{code:"rate_limited",status:429};if(O instanceof Yt)return{code:"not_implemented",status:501};if(O instanceof pt)return{code:"server_error",status:O.status};if(O instanceof Ze)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var Tn=(O)=>{if(O instanceof _t&&O.issues.length>0){let N=O.issues.map((L)=>{let F=L;return` - ${Array.isArray(F.path)&&F.path.length>0?`${F.path.join(".")}: `:""}${typeof F.message==="string"?F.message:JSON.stringify(L)}`});return`${O.message}
14
+ ${N.join(`
15
+ `)}`}return O instanceof Error?O.message:String(O)};function n(O,N){let L=r({env:O,flags:N.flags,cwd:N.cwd});if(L.conflict)throw new e("workspace_mismatch",L.conflict);if(!L.credential)throw new e("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");return new Ct({baseUrl:L.baseUrl,credential:L.credential.sessionToken?cr(L.credential.sessionToken):$t(L.credential.apiKey),...L.workspaceId?{organizationId:L.workspaceId}:{}})}function jo(O){let N=Math.max(...O.map((F)=>F.name.length));return`hlix — the hlix control-plane CLI
16
+
17
+ Usage:
18
+ hlix <command> [options]
19
+
20
+ Commands:
21
+ ${[` hlix ${"".padEnd(N)} Open Hlix Code (interactive)`,...O.map((F)=>` hlix ${F.name.padEnd(N)} ${F.summary}`)].join(`
22
+ `)}
23
+
24
+ Options:
25
+ --json Machine-readable output (a versioned, stable contract)
26
+ --cwd <dir> Operate on another directory instead of the current one
27
+ --workspace <id> Workspace to act in, overriding the folder's binding
28
+ --base-url <url> API to talk to, overriding the folder's binding
29
+ --help Show this help
30
+ --version Show the installed CLI version
31
+
32
+ Hlix Code (hlix with no command):
33
+ --sandbox <choice> cloud (Cloud Machine), docker (Docker container), or local
34
+ (local environment); --local is short for --sandbox local
35
+ --docker-image <r> image the Docker container runs in
36
+ --harness <name> which coder does the work
37
+ --project <id> project to act in, when this folder is not bound
38
+ -p "<prompt>" one turn, print the answer, exit
39
+ --json with -p: one JSON object per event instead of prose
40
+ --allow-writes with -p: let the turn change files and run commands
41
+ --yolo approve every tool call for the whole session
42
+
43
+ A command targets the workspace named by, in order: an explicit flag, the
44
+ HLIX_* environment, the nearest .hlix/config.json, then the stored credential.
45
+ Run \`hlix status\` to see which one applied.
46
+ `}function xo(O,N){let L=[...Array(N.length+1).keys()];for(let F=1;F<=O.length;F+=1){let H=[F];for(let M=1;M<=N.length;M+=1)H[M]=Math.min(L[M]+1,H[M-1]+1,L[M-1]+(O[F-1]===N[M-1]?0:1));L=H}return L[N.length]}function rc(O,N,L){let F=/Unknown option '--([^'=]+)/.exec(L)?.[1];if(!F)return L;let H=N.findIndex((D)=>D.startsWith("-")),M=H===-1?N:N.slice(0,H),U=new Set(["json","help","version","cwd","workspace","base-url",...Rn(O,M)?.command.options??[]]),G=null;for(let D of U){let B=xo(F,D);if(B<=2&&(!G||B<G.distance))G={name:D,distance:B}}return G?`${L}
47
+ Did you mean --${G.name}?`:L}function Eo(O,N){let L=new Set;for(let M of O)L.add(M.name),L.add(M.name.split(" ")[0]);let F=null;for(let M of L){let U=xo(N,M);if(U<=2&&(!F||U<F.distance))F={name:M,distance:U}}if(!F)return null;if(O.some((M)=>M.name===F.name))return F.name;let H=O.filter((M)=>M.name.startsWith(`${F.name} `)).sort((M,U)=>M.name.length-U.name.length)[0];return H?H.name:F.name}function Rn(O,N){for(let L of[...O].sort((F,H)=>H.name.length-F.name.length)){let F=L.name.split(" ");if(F.every((H,M)=>N[M]===H))return{command:L,rest:N.slice(F.length)}}return null}function sc(O,N,L){let F=rc(O,N,L);if(!/^Unknown option '/.test(L))return F;let H=F.replace(/\. To specify a positional argument[\s\S]*?after '--'[^\n]*/,"."),M=Rn(O,N.filter((U)=>!U.startsWith("-")));return M?`${H}
48
+
49
+ ${M.command.usage}`:H}async function c(O,N,L){if(N.some((Y)=>Y==="--api-key"||Y.startsWith("--api-key=")))return L.stderr("error: API keys are never accepted as command-line arguments. Run `hlix auth login` and use the hidden prompt.\n"),2;let F;try{F=nc({args:N,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(Y){let ie=N.includes("--json"),le=sc(O,N,Tn(Y));if(L.onFailure?.({code:"invalid_usage",message:le,status:null}),ie)L.stdout(oe(Bt("cli",{code:"invalid_usage",message:le,status:null})));else L.stderr(`${le}
50
+ `);return 2}let H=F.values.json===!0,M=F.positionals;if(F.values.version===!0){let{version:Y}=await import("./package-vwz9740v.js");return L.stdout(`${Y}
51
+ `),0}if(M.length===0||F.values.help===!0){let Y=Rn(O,M);return L.stdout(Y?`${Y.command.usage}
52
+ `:jo(O)),M.length===0&&F.values.help!==!0?1:0}let U=Rn(O,M);if(!U){let Y=M.join(" "),ie=Eo(O,Y)??Eo(O,M[0]),le=ie?`Unknown command: ${Y}
53
+ Did you mean \`hlix ${ie}\`?`:`Unknown command: ${Y}`;if(L.onFailure?.({code:"unknown_command",message:le,status:null}),H)L.stdout(oe(Bt(Y,{code:"unknown_command",message:le,status:null})));else L.stderr(`${le}
54
+
55
+ ${jo(O)}`);return 2}let G=new Set(["json","help","version","cwd","workspace","base-url"]),D=new Set(U.command.options??[]),B=Object.entries(F.values).filter(([Y,ie])=>ie!==void 0&&!G.has(Y)&&!D.has(Y)).map(([Y])=>`--${Y}`),J=U.command.args??{min:0,max:0},W=U.rest.length<J.min?{code:"missing_argument",message:U.command.usage.split(`
56
+ `)[0]}:U.rest.length>J.max?{code:"invalid_usage",message:U.command.usage.split(`
57
+ `)[0]}:null,z=typeof F.values.cwd==="string"?F.values.cwd:void 0,Q=tc(z??"."),te=z!==void 0&&!po(Q)?{code:"invalid_usage",message:`--cwd is not a directory: ${Q}`}:null,V=B.length>0?{code:"invalid_usage",message:`Unsupported option for ${U.command.name}: ${B.join(", ")}`}:te??W;if(V){if(L.onFailure?.({...V,status:null}),H)L.stdout(oe(Bt(U.command.name,{...V,status:null})));else{let Y=U.command.usage.startsWith(V.message)?U.command.usage:`${V.message}
58
+
59
+ ${U.command.usage}`;L.stderr(`error: ${Y}
60
+ `)}return 2}let X=F.values,ee={...L,args:U.rest,json:H,flags:X,cwd:Q,requireClient:(Y)=>n(L.env,{cwd:Y??Q,flags:X})};try{return await U.command.run(ee)}catch(Y){let{code:ie,status:le}=kr(Y);if(L.onFailure?.({code:ie,message:s(Tn(Y)),status:le,...Y instanceof e&&Y.details!==void 0?{details:Y.details}:{}}),H)L.stdout(oe(Bt(U.command.name,{code:ie,message:Tn(Y),status:le})));else if(L.stderr(`error: ${s(Tn(Y))}
61
+ `),process.env.HLIX_DEBUG&&Y instanceof Error&&Y.stack)L.stderr(`${Y.stack}
62
+ `);return ie==="unauthenticated"||ie==="forbidden"?3:1}}import{readFileSync as oc}from"node:fs";import{homedir as ic}from"node:os";import{join as ac}from"node:path";var Po=20000;function g(O){if(O===void 0)return;let N=typeof O==="number"?O:Number(O.trim());return Number.isInteger(N)&&N>=Po?N:void 0}var l=["cloud","docker","local"],d={cloud:"Cloud Machine",docker:"Docker container",local:"local environment"},cc={"claude-code":!0,codex:!0,opencode:!0,goose:!0,"qwen-code":!0,pi:!0,hlix:!0},o=Object.keys(cc),S="hlix",$o={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"},It=["dockerImage","harness","memoryTokens","model","sandbox","yolo"],Sr=["projectId","workspaceId","apiUrl"];function jr(O=process.env){return ac(O.HLIX_CONFIG_HOME??ic(),".hlix","config.json")}function _o(O=process.env){try{let N=JSON.parse(oc(jr(O),"utf8"));return N.schemaVersion===1?N:null}catch{return null}}function f(O,N=process.env){let L=_o(N),F=t(O),H=F?.root??null,M=F?.config??null,U={},G={},D=(B)=>{let J=M?.[B],W=L?.[B];if(J!==void 0)U[B]=J,G[B]="project";else if(W!==void 0)U[B]=W,G[B]="global"};for(let B of It)D(B);for(let B of Sr){let J=M?.[B];if(J!==void 0)U[B]=J,G[B]="project"}return{merged:U,sources:G,global:L,project:M,paths:{global:jr(N),project:H?zt(H):null}}}function Co(O){return[...It,...Sr].map((L)=>({key:L,value:O.merged[L]??null,source:O.sources[L]??"default"}))}function lc(O,N){if(O==="sandbox"&&!l.includes(N))return`sandbox must be one of ${l.join(", ")}; got "${N}".`;if(O==="harness"&&!o.includes(N))return`harness must be one of ${o.join(", ")}; got "${N}".`;if(O==="model"&&N.trim()==="")return"model must not be empty.";if(O==="memoryTokens"&&g(N)===void 0)return`memoryTokens must be a whole number of tokens, at least ${Po}; got "${N}".`;if(O==="dockerImage"&&N.trim()==="")return"dockerImage must not be empty.";if(O==="yolo"&&x(N)===void 0)return`yolo must be true or false; got "${N}".`;return null}function x(O){if(O===void 0)return;let N=O.trim().toLowerCase();if(["true","1","yes","on"].includes(N))return!0;if(["false","0","no","off"].includes(N))return!1;return}function Er(O){if(It.includes(O))return O;let N=Sr.includes(O);throw new e("invalid_usage",N?`${O} is written by \`hlix init\` and \`hlix import\`, not by \`hlix config set\`.`:`Unknown setting: ${O}. Known settings: ${It.join(", ")}.`)}function Io(O,N){let L=lc(O,N);if(L)throw new e("invalid_usage",L);return N}function y(O){if(O.scope==="global"){let F=jr(O.env),H=_o(O.env)??{schemaVersion:1};return qt(F,{...H,[O.key]:O.value}),F}let N=t(O.cwd);if(!N)throw new e("not_initialized","This folder is not bound to hlix. Run `hlix init` here, or set it machine-wide with --global.");let L=zt(N.root);return qt(L,{...N.config,[O.key]:O.value}),L}import{createHash as dc}from"node:crypto";import{mkdirSync as pc,readdirSync as Lo,readFileSync as uc,rmSync as mc,statSync as Fo,writeFileSync as fc}from"node:fs";import{homedir as gc,tmpdir as hc}from"node:os";import{basename as Ho,isAbsolute as yc,join as fe,relative as wc}from"node:path";var a=(O=process.env)=>O.HOME??O.USERPROFILE??gc();function Re(O){try{if(!Fo(O).isFile())return null;return uc(O,"utf8")}catch{return null}}function vc(O){try{return Fo(O).isDirectory()}catch{return!1}}function Tt(O,N){try{return Lo(O,{withFileTypes:!0}).filter((L)=>L.isFile()&&L.name.endsWith(N)).map((L)=>fe(O,L.name)).sort()}catch{return[]}}function bc(O){try{return Lo(O,{withFileTypes:!0}).filter((N)=>N.isDirectory()||N.isSymbolicLink()).map((N)=>fe(O,N.name)).sort()}catch{return[]}}function Pr(O){let N=O.replace(/^\uFEFF/,""),L=N.indexOf(`
63
+ `);if(!N.startsWith("---")||L===-1)return{fields:{},body:N.trim()};let F=N.indexOf(`
64
+ ---`,L);if(F===-1)return{fields:{},body:N.trim()};let H={};for(let U of N.slice(L+1,F).split(`
65
+ `)){let G=/^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(U);if(!G)continue;H[G[1]]=G[2].trim().replace(/^["']|["']$/g,"")}let M=N.indexOf(`
66
+ `,F+1);return{fields:H,body:M===-1?"":N.slice(M+1).trim()}}function kc(O){let N=O.trimStart(),L=/^"((?:[^"\\]|\\.)*)"/.exec(N)??/^'([^']*)'/.exec(N);if(L)return L[1].replace(/\\"/g,'"').replace(/\\n/g,`
67
+ `);if(N.startsWith("["))return[...N.matchAll(/"((?:[^"\\]|\\.)*)"|'([^']*)'/g)].map((H)=>H[1]??H[2]??"");if(N.startsWith("{")){let H={};for(let M of N.matchAll(/([A-Za-z0-9_.-]+)\s*=\s*"((?:[^"\\]|\\.)*)"/g))H[M[1]]=M[2].replace(/\\"/g,'"');return H}let F=/^[^\s#]+/.exec(N)?.[0];if(F===void 0)return;if(F==="true"||F==="false")return F==="true";if(/^-?\d+(\.\d+)?$/.test(F))return Number(F);return F}function Mo(O){let N={"":{}},L="",F=O.split(`
68
+ `);for(let H=0;H<F.length;H+=1){let U=F[H].trim();if(!U||U.startsWith("#"))continue;let G=/^\[\[?([^\]]+)\]\]?$/.exec(U);if(G){L=G[1].trim(),N[L]??={};continue}let D=/^([A-Za-z0-9_.-]+|"[^"]+")\s*=\s*(.*)$/.exec(U);if(!D)continue;let B=D[1].replace(/^"|"$/g,""),J=D[2];if(J.startsWith('"""')){let z=[],Q=J.slice(3);if(Q.includes('"""'))z.push(Q.slice(0,Q.indexOf('"""')));else{if(Q)z.push(Q);while(H+1<F.length){H+=1;let te=F[H],V=te.indexOf('"""');if(V===-1){z.push(te);continue}z.push(te.slice(0,V));break}}N[L][B]=z.join(`
69
+ `).replace(/^\n/,"");continue}let W=kc(J);if(W!==void 0)N[L][B]=W}return N}function xr(O,N){return O.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(L,F,H)=>{let M=N[F];return M!==void 0&&M!==""?M:H??""})}var To=(O,N)=>{let L={};for(let[F,H]of Object.entries(O))if(typeof H==="string")L[F]=xr(H,N);return L},Sc=[{relative:"GEMINI.md",source:"gemini"},{relative:fe(".gemini","GEMINI.md"),source:"gemini"},{relative:".cursorrules",source:"cursor"},{relative:".windsurfrules",source:"windsurf"},{relative:fe(".github","copilot-instructions.md"),source:"copilot"}],jc=[{relative:fe(".gemini","GEMINI.md"),source:"gemini"}],Ec=[{relative:fe(".cursor","rules"),source:"cursor",extension:".mdc"},{relative:fe(".windsurf","rules"),source:"windsurf",extension:".md"}];function xc(O,N){let L=fe(O,".clinerules"),F=vc(L)?Tt(L,".md"):[L],H=[];for(let M of F){let U=Re(M)?.trim();if(U)H.push({path:M,source:"cline",scope:N,content:U})}return H}function Pc(O,N,L){let{fields:F,body:H}=Pr(N);if(F.alwaysApply==="false")return{path:O,source:"cursor",scope:L,reason:"alwaysApply: false"};if(!H)return{path:O,source:"cursor",scope:L,reason:"no rule body"};let M=F.globs?.replace(/^\[|\]$/g,"").trim();return{path:O,source:"cursor",scope:L,content:H,...M?{note:`Applies to: ${M}`}:{}}}var $c=["AGENTS.md","CLAUDE.md"],Uo=["",".claude"],C=["commands"];function _c(O,N){let L=[],F=new Set;for(let H of[...Uo,N])for(let M of $c){let U=fe(O,H,M),G=Re(U)?.trim();if(!G||F.has(G))continue;F.add(G),L.push({path:U,content:G})}return L}function Ro(O,N){return _c(O,N).map((L)=>L.content)}var h=["AGENTS.md","CLAUDE.md","GEMINI.md"];function $r(O,N){for(let L of h)for(let F of[...Uo,N]){let H=fe(O,F,L),M=Re(H)?.trim();if(M)return{path:H,content:M}}return null}var _r=(O=process.env)=>fe(O.HLIX_CONFIG_HOME??fe(a(O),".hlix"),"AGENTS.md");function w(O){let N=O.env??process.env,L=_r(N),F=Re(L)?.trim();return{global:F?{path:L,content:F}:null,project:$r(O.cwd,O.configDir)}}var Ao=(O)=>{let N=Math.round(O.length/4);return N>=1000?`${(N/1000).toFixed(1)}k tokens`:`${N} tokens`};function A(O,N,L=process.env){let F=[...O.global?[Go(O.global.path,L)]:[],...O.project?[tn(O.project.path,N)]:[]];return F.length===0?"":`rules: ${F.join(" + ")}`}function b(O,N,L=process.env,F=[]){let H=(M,U,G)=>U?`${M.padEnd(8)} ${G(U.path)} (${Ao(U.content)})`:`${M.padEnd(8)} none`;return[H("user",O.global,(M)=>Go(M,L)),H("project",O.project,(M)=>tn(M,N)),...F.map((M)=>`${"nested".padEnd(8)} ${tn(M.path,N)} (${Ao(M.content)})`),"","User rules go first, the project's after, so the project wins a conflict.",F.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(`
70
+ `)}var Oo=[{dir:".claude",source:"claude",harnessReads:!0},{dir:".agents",source:"agents",harnessReads:!0},{dir:".hlix",source:"hlix",harnessReads:!0},{dir:".codex",source:"codex",harnessReads:!1}],Cc=[{relative:fe(".cursor","commands"),source:"cursor"},{relative:fe(".codex","prompts"),source:"codex"}],Ic=[{relative:fe(".cursor","mcp.json"),source:"cursor",key:"mcpServers",format:"json"},{relative:fe(".windsurf","mcp.json"),source:"windsurf",key:"mcpServers",format:"json"},{relative:fe(".gemini","settings.json"),source:"gemini",key:"mcpServers",format:"json"},{relative:fe(".vscode","mcp.json"),source:"vscode",key:"servers",format:"json"},{relative:fe(".codex","config.toml"),source:"codex",key:"mcp_servers",format:"toml"},{relative:".mcp.json",source:"claude",key:"mcpServers",format:"json"}];function Do(O){return[...Ic,{relative:fe(O,"mcp.json"),source:"hlix",key:"mcpServers",format:"json"}]}var Tc="found, not loaded (machine-wide; enable per project by copying into .hlix/mcp.json)",Rc=(O)=>Do(O).filter((N)=>N.source!=="vscode");function Ac(O,N){if(!O||typeof O!=="object"||Array.isArray(O))return{reason:"not an object"};let L=O;if(L.enabled===!1||L.disabled===!0)return{reason:"disabled"};let F=typeof L.command==="string"&&L.command!=="",H=typeof L.url==="string"&&L.url!=="";if(F&&H)return{reason:'has both "command" and "url"'};if(F){let W=Array.isArray(L.args)?L.args.filter((Q)=>typeof Q==="string"):void 0,z=L.env&&typeof L.env==="object"&&!Array.isArray(L.env)?To(L.env,N):void 0;return{config:{command:L.command,...W&&W.length>0?{args:W}:{},...z&&Object.keys(z).length>0?{env:z}:{}}}}if(!H)return{reason:'missing "command" or "url"'};let M=L.headers??L.http_headers,U=M&&typeof M==="object"&&!Array.isArray(M)?To(M,N):{},G=L.bearer_token_env_var;if(typeof G==="string"&&/^[A-Za-z_][A-Za-z0-9_]*$/.test(G)&&!Object.keys(U).some((W)=>W.toLowerCase()==="authorization"))U.Authorization=`Bearer ${xr(`\${${G}}`,N)}`;let D=Object.entries(U).find(([W])=>W.toLowerCase()==="authorization")?.[1]?.trim(),B=D&&!/^Bearer$/i.test(D)&&!D.includes("${"),J=L.oauth===!0||L.oauth&&typeof L.oauth==="object"||typeof G==="string"&&!N[G];return{config:{url:xr(L.url,N),...J&&!B?{needsSignIn:!0}:{},...Object.keys(U).length>0?{headers:U}:{}}}}function No(O,N,L,F){let H=Re(O),M=[],U=[];if(H===null)return{servers:M,skipped:U};let G=[];if(N.format==="toml"){let D=Mo(H);G=Object.entries(D).filter(([B])=>B.startsWith(`${N.key}.`)).map(([B,J])=>[B.slice(N.key.length+1),J])}else try{let B=JSON.parse(H)?.[N.key];if(B&&typeof B==="object"&&!Array.isArray(B))G=Object.entries(B)}catch{return U.push({path:O,source:N.source,scope:L,reason:"not valid JSON"}),{servers:M,skipped:U}}for(let[D,B]of G){let J=Ac(B,F);if("reason"in J){U.push({path:O,source:N.source,scope:L,reason:`${D}: ${J.reason}`});continue}M.push({path:O,source:N.source,scope:L,name:D,config:J.config})}return{servers:M,skipped:U}}function Oc(O,N,L){let{fields:F,body:H}=Pr(N);if(!H)return{path:O,source:"claude",scope:L,reason:"no instructions"};let M=F.tools?.replace(/^\[|\]$/g,"").split(",").map((U)=>U.trim()).filter(Boolean);return{path:O,source:"claude",scope:L,name:F.name||Ho(O,".md"),description:F.description??"",instructions:H,...M&&M.length>0&&M[0]!=="*"?{tools:M}:{},...F.model?{model:F.model}:{}}}function Nc(O){let N=Mo(O)[""]??{},L=typeof N.prompt==="string"?N.prompt.trim():"";if(!L)return null;return{description:typeof N.description==="string"?N.description:"",body:L}}function v(O,N,L={}){let F=L.configDir??".hlix",H=L.env??process.env,M={instructions:[],skills:[],commands:[],generatedCommands:[],mcpServers:[],subagents:[],skipped:[]},U=(te)=>{if("reason"in te)M.skipped.push(te);else M.instructions.push(te)};for(let te of Sc){let V=fe(O,te.relative),X=Re(V)?.trim();if(X)M.instructions.push({path:V,source:te.source,scope:"project",content:X})}for(let te of Ec)for(let V of Tt(fe(O,te.relative),te.extension)){let X=Re(V);if(X===null)continue;if(te.source==="cursor"){U(Pc(V,X,"project"));continue}let{body:ee}=Pr(X);if(ee)M.instructions.push({path:V,source:te.source,scope:"project",content:ee})}for(let te of xc(O,"project"))U(te);let G=Ro(O,F),D=fe(O,".codex","AGENTS.md"),B=Re(D)?.trim();if(B&&G.includes(B))M.skipped.push({path:D,source:"codex",scope:"project",reason:"same content as the project's AGENTS.md"});else if(B)M.instructions.push({path:D,source:"codex",scope:"project",content:B});for(let te of jc){let V=fe(N,te.relative),X=Re(V)?.trim();if(X)M.instructions.push({path:V,source:te.source,scope:"global",content:X})}let J=fe(N,".codex","AGENTS.md"),W=Re(J)?.trim(),z=Ro(N,F);if(W&&z.includes(W))M.skipped.push({path:J,source:"codex",scope:"global",reason:"same content as the machine's AGENTS.md"});else if(W)M.instructions.push({path:J,source:"codex",scope:"global",content:W});for(let[te,V]of[[O,"project"],[N,"global"]])for(let X of Oo){let ee=fe(te,X.dir===".hlix"?F:X.dir,"skills");if(!bc(ee).some((ie)=>Re(fe(ie,"SKILL.md"))!==null))continue;M.skills.push({path:ee,source:X.source,scope:V,harnessReads:X.harnessReads})}for(let[te,V]of[[O,"project"],[N,"global"]]){for(let X of Oo){if(!X.harnessReads)continue;let ee=fe(te,X.dir,"commands");if(Tt(ee,".md").length===0)continue;M.commands.push({path:ee,source:X.source,scope:V,harnessReads:!0})}for(let X of Cc){let ee=fe(te,X.relative);if(Tt(ee,".md").length===0)continue;M.commands.push({path:ee,source:X.source,scope:V})}for(let X of Tt(fe(te,".gemini","commands"),".toml")){let ee=Re(X),Y=ee===null?null:Nc(ee);if(!Y){M.skipped.push({path:X,source:"gemini",scope:V,reason:"no prompt field"});continue}M.generatedCommands.push({path:X,source:"gemini",scope:V,name:Ho(X,".toml"),body:`---
71
+ description: ${Y.description}
72
+ ---
73
+
74
+ ${Y.body}
75
+ `})}}for(let te of Do(F)){let V=No(fe(O,te.relative),te,"project",H);M.skipped.push(...V.skipped);for(let X of V.servers){let ee=M.mcpServers.findIndex((Y)=>Y.name===X.name);if(ee===-1)M.mcpServers.push(X);else M.mcpServers[ee]=X}}for(let te of Rc(F)){let V=No(fe(N,te.relative),te,"global",H);for(let X of V.servers)M.skipped.push({path:X.path,source:X.source,scope:"global",reason:`${X.name}: ${Tc}`})}let Q=[{dir:fe(".claude","agents"),source:"claude"},{dir:fe(F,"agents"),source:"hlix"}];for(let[te,V]of[[O,"project"],[N,"global"]])for(let X of Q.flatMap((ee)=>Tt(fe(te,ee.dir),".md"))){let ee=Re(X);if(ee===null)continue;let Y=Oc(X,ee,V);if("reason"in Y)M.skipped.push(Y);else if(M.subagents.some((ie)=>ie.name===Y.name))M.skipped.push({path:X,source:"claude",scope:V,reason:`a project agent already claims the name ${Y.name}`});else M.subagents.push(Y)}return M}function I(O,N){if(O.length===0)return null;let L=fe(hc(),"hlix-standards-commands",dc("sha256").update(N).digest("hex").slice(0,16));try{mc(L,{recursive:!0,force:!0}),pc(L,{recursive:!0});for(let F of O)fc(fe(L,`${F.name}.md`),F.body,"utf8");return L}catch{return null}}var tn=(O,N)=>{let L=wc(N,O);return!L||L.startsWith("..")||yc(L)?O:L},Go=(O,N=process.env)=>{let L=N.HLIX_CONFIG_HOME;if(L&&O.startsWith(`${L}/`))return`~/.hlix/${O.slice(L.length+1)}`;let F=a(N);return F&&O.startsWith(`${F}/`)?`~/${O.slice(F.length+1)}`:O};function T(O,N){if(O.length===0)return"";let L=["# 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(`
76
+ `),F=O.map((H)=>{let M=`# From ${tn(H.path,N)} (${H.source})`;return`${H.note?`${M}
77
+ ${H.note}`:M}
78
+
79
+ ${H.content}`});return`${L}
80
+
81
+ ${F.join(`
82
+
83
+ `)}`}var en=(O,N,L)=>`${O} ${O===1?N:L}`;function R(O){let N=[];if(O.instructions.length>0)N.push(en(O.instructions.length,"instruction file","instruction files"));if(O.skills.length>0)N.push(en(O.skills.length,"skill directory","skill directories"));let L=O.commands.length+O.generatedCommands.length;if(L>0)N.push(en(L,"command source","command sources"));if(O.mcpServers.length>0)N.push(en(O.mcpServers.length,"mcp server","mcp servers"));if(O.subagents.length>0)N.push(en(O.subagents.length,"subagent","subagents"));if(N.length===0)return"";let F=[...new Set([...O.instructions,...O.skills,...O.commands,...O.generatedCommands,...O.mcpServers,...O.subagents].map((H)=>H.source))].sort();return`standards: ${N.join(" · ")} (${F.join(", ")})`}function Bo(O,N){let L=[],F=(M,U)=>{if(U.length===0)return;L.push(M,...U.map((G)=>` ${G}`),"")},H=(M)=>`${M.source}${M.scope==="global"?" (global)":""} ${tn(M.path,N)}`;if(F("Instructions",O.instructions.map((M)=>`${H(M)}${M.note?` — ${M.note}`:""}`)),F("Skills",O.skills.map((M)=>`${H(M)}${M.harnessReads?" — already read by the harness":""}`)),F("Commands",[...O.commands.map((M)=>`${H(M)}${M.harnessReads?" — already read by the harness":""}`),...O.generatedCommands.map((M)=>`${H(M)} → /${M.name}`)]),F("MCP servers",O.mcpServers.map((M)=>`${H(M)} → ${M.name} (${"command"in M.config?"stdio":"http"})`)),F("Subagents",O.subagents.map((M)=>`${H(M)} → ${M.name}`)),F("Skipped",O.skipped.map((M)=>`${H(M)} — ${M.reason}`)),L.length===0)return`No standards from other agent tools were found in this folder.
84
+ `;return`${L.join(`
85
+ `).trimEnd()}
86
+ `}import{accessSync as Lc,constants as Fc,mkdirSync as Hc,readFileSync as Mc,realpathSync as Uc,statSync as Wo,writeFileSync as Dc}from"node:fs";import{homedir as Gc}from"node:os";import{basename as Bc,dirname as Jo,join as Rt}from"node:path";var Jc={homebrew:"Homebrew",npm:"npm",installer:"installer",unknown:"unknown origin"},qo=(O)=>O.HOME||Gc();function Ir(O){return Rt(O.XDG_DATA_HOME||Rt(qo(O),".local","share"),"hlix","hlix")}function zo(O){try{return Uc(O)}catch{return null}}function Wc(O){try{let N=JSON.parse(Mc(Rt(Ir(O),"install.json"),"utf8"));if(typeof N.path==="string")return N.path}catch{}return Rt(qo(O),".local","bin","hlix")}function qc(O,N){if(/\/Cellar\/hlix\//.test(O))return"homebrew";if(/\/node_modules\/@hlix\/cli\//.test(O))return"npm";if(zo(Wc(N))===O)return"installer";return"unknown"}function Cr(O,N){let L=zo(O);if(!L)return null;try{if(!Wo(L).isFile())return null;Lc(L,Fc.X_OK)}catch{return null}return{path:O,realPath:L,channel:qc(L,N)}}function zc(O){let N=[];for(let L of(O.PATH??"").split(":")){if(!L)continue;let F=Cr(Rt(L,"hlix"),O);if(F&&!N.some((H)=>H.realPath===F.realPath))N.push(F)}return N}function Tr(O,N=process.execPath){if(O.HLIX_SELF)return Cr(O.HLIX_SELF,O);if(/^(node|bun)(\.exe)?$/.test(Bc(N)))return null;return Cr(N,O)}function Rr(O){switch(O.channel){case"homebrew":return"brew uninstall hlix";case"npm":return"npm uninstall -g @hlix/cli";case"installer":return`${O.path} uninstall`;case"unknown":return`rm ${O.path}`}}var An=(O)=>`${O.path} (${Jc[O.channel]})`;function Ar(O,N=process.execPath){let L=Tr(O,N),F=zc(O);if(L&&!F.some((G)=>G.realPath===L.realPath))F.push(L);if(F.length<2)return{running:L,copies:F,duplicate:null};let[H,...M]=F,U=`${F.length} copies of hlix are installed: ${An(H)} runs, ${M.map(An).join(" and ")} ${M.length===1?"does":"do"} not. Keep one: ${M.map(Rr).join(" && ")}`;return{running:L,copies:F,duplicate:U}}var Kc=86400000;function P(O,N=Date.now(),L=process.execPath){let{duplicate:F}=Ar(O,L);if(!F)return null;let H=Rt(Jo(De(O)),"duplicate-notice");try{if(N-Wo(H).mtimeMs<Kc)return null}catch{}try{Hc(Jo(H),{recursive:!0}),Dc(H,`${F}
87
+ `)}catch{}return F}async function Vc(O,N,L){let F=N.map((G)=>G.id);if(L){if(!F.includes(L))throw new e("workspace_mismatch",N.length===0?`This key belongs to a user who is not a member of any workspace, including ${L}.`:`This key cannot act in workspace ${L}. Available: ${F.join(", ")}.`);return L}if(N.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 H=N[0];if(H&&N.length===1)return O.stderr(`Using your only workspace: ${H.name} (${H.id})
88
+ `),H.id;if(O.json||!O.promptChoice)throw new e("missing_argument",`--workspace is required here: this key can act in ${N.length} workspaces. Pass one of: ${F.join(", ")}.`);let M=Math.max(...N.map((G)=>G.name.length));O.stderr(`${N.map((G,D)=>` ${D+1}) ${G.name.padEnd(M)} ${G.slug} ${G.role} ${G.id}`).join(`
89
+ `)}
90
+ `);let U=await O.promptChoice(`Workspace [1-${N.length}]: `,N.length);return F[U]}var Or={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 ${at}`," --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(`
91
+ `),supportsJson:!0,options:["base-url","workspace"],async run(O){let N=typeof O.flags.workspace==="string"?O.flags.workspace:O.env.HLIX_WORKSPACE_ID,L=O.env.HLIX_API_KEY??await O.readSecret?.("Hlix API key: ")??"";if(!L)throw new e("missing_credential","No API key entered. Run from a terminal or set HLIX_API_KEY for CI.");let F=typeof O.flags["base-url"]==="string"?O.flags["base-url"]:O.env.HLIX_BASE_URL??at,H=new URL(F),M=H.hostname==="localhost"||H.hostname==="127.0.0.1"||H.hostname==="::1";if(H.protocol!=="https:"&&!(H.protocol==="http:"&&M))throw new e("invalid_base_url","--base-url must use HTTPS (HTTP is allowed only for localhost).");let U=new Ct({baseUrl:F,credential:$t(L),retry:{attempts:1}}),G=await Vc(O,await U.workspaces.list(),N);await new Ct({baseUrl:F,credential:$t(L),organizationId:G,retry:{attempts:1}}).projects.list();let B=so({baseUrl:F,apiKey:L,organizationId:G},O.env);if(O.json)O.stdout(oe(ae(Or.name,{baseUrl:F,organizationId:G,credentialPath:B})));else O.stdout(`Signed in to ${F}
92
+ Credential stored at ${B}
93
+ `);return 0}},Nr={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(`
94
+ `),supportsJson:!0,async run(O){let N=r({env:O.env,flags:O.flags,cwd:O.cwd});if(N.conflict)throw new e("workspace_mismatch",N.conflict);if(!N.credential)throw new e("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");try{await O.requireClient().projects.list()}catch(F){throw O.stderr(`credential from ${N.credentialSource}, workspace ${N.workspaceId??"none"}, api ${N.baseUrl}
95
+ `),F}let L={credentialSource:N.credentialSource,credentialPath:N.credentialSource==="file"?N.credentialPath:null,baseUrl:N.baseUrl,baseUrlSource:N.baseUrlSource,workspaceId:N.workspaceId,workspaceSource:N.workspaceSource,valid:!0};if(O.json)return O.stdout(oe(ae(Nr.name,L))),0;return O.stdout(`${je([["credential",m(N)??"none"],["api",`${N.baseUrl} (from ${N.baseUrlSource})`],["workspace",N.workspaceId?`${N.workspaceId} (from ${N.workspaceSource})`:"none"],["status","valid"]])}
96
+ `),0}},At={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(`
97
+ `),supportsJson:!0,options:["yes"],async run(O){let N=r({env:O.env,flags:O.flags,cwd:O.cwd});if(N.credentialSource==="env"||N.credentialSource==="session"){let F=N.credentialSource==="session",H=F?"session":"environment",M=F?"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.",U=ro(O.env);if(!U){let D={removed:!1,reason:H,path:null};if(O.json)O.stdout(oe(ae(At.name,D)));else O.stdout(`${M}
98
+ `);return 0}if(O.flags.yes!==!0){let D={removed:!1,reason:H,path:U};if(O.json)O.stdout(oe(ae(At.name,D)));else O.stdout(`${M}
99
+ A stored credential also exists at ${U} — repeat with --yes to remove it.
100
+ `);return 0}let G=nr(O.env);if(O.json)O.stdout(oe(ae(At.name,G)));else O.stdout(`Removed ${G.path}
101
+ ${F?"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."}
102
+ `);return 0}if(O.flags.yes!==!0&&N.credential){if(O.json||!O.confirm)throw new e("approval_required","Removing the stored credential needs approval. Repeat with `--yes`.");if(!await O.confirm(`Remove the stored credential at ${N.credentialPath}? Signing back in needs the API key again.`))throw new e("cancelled","Logout cancelled.")}let L=nr(O.env);if(O.json)O.stdout(oe(ae(At.name,L)));else O.stdout(L.removed?`Removed ${L.path}
103
+ `:`No stored credential at ${L.path}
104
+ `);return 0}};var Ko=It.join(" | "),Lr={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(`
105
+ `),supportsJson:!0,async run(O){let N=f(O.cwd,O.env),L=Co(N);if(O.json)return O.stdout(oe(ae(Lr.name,{settings:L,paths:N.paths}))),0;return O.stdout(`${Je(["setting","value","source","applies to"],L.map((F)=>[F.key,F.value??"-",F.source,$o[F.key]??"this folder's binding"]))}
106
+ `),O.stdout(`
107
+ global ${N.paths.global}
108
+ `),O.stdout(`project ${N.paths.project??"- (this folder is not bound to hlix)"}
109
+ `),0}},Fr={name:"config get",summary:"Print one setting's effective value",usage:[`Usage: hlix config get <${Ko}> [--cwd <dir>] [--json]`,"","Prints the value the cascade resolves for one key, or exits 1 when no","file names it."].join(`
110
+ `),supportsJson:!0,args:{min:1,max:1},async run(O){let N=Er(O.args[0]),L=f(O.cwd,O.env),F=L.merged[N]??null,H=L.sources[N]??"default";if(O.json)return O.stdout(oe(ae(Fr.name,{key:N,value:F,source:H}))),F===null?1:0;if(F===null)return O.stderr(`${N} is not set. Set it with \`hlix config set ${N} <value>\`.
111
+ `),1;return O.stdout(`${F}
112
+ `),0}},Hr={name:"config set",summary:"Set one setting for this folder, or for the machine with --global",usage:[`Usage: hlix config set <${Ko}> <value> [--global] [--cwd <dir>] [--json]`,"","Writes this folder's .hlix/config.json, or the machine-wide file 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(`
113
+ `),supportsJson:!0,options:["global"],args:{min:2,max:2},async run(O){let N=Er(O.args[0]),L=Io(N,O.args[1]),F=O.flags.global===!0?"global":"project",H=y({key:N,value:L,scope:F,cwd:O.cwd,env:O.env});if(O.json)return O.stdout(oe(ae(Hr.name,{key:N,value:L,scope:F,path:H}))),0;return O.stdout(`${N} = ${L} (${F}: ${H})
114
+ `),0}};var Xc="project-manager",Yc=2000,Zc="Cloud work landed. Run /pull (hlix pull) to bring it into this folder.",Vo=new Set(["done","pr_created"]),Qc=new Set(["done","pr_created","failed","canceled"]),el={"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 tl(O){let N=O.role?el[O.role]:void 0;return N?`${O.name} · ${N}`:O.name}function nl(O){return O.replace(/^project-/,"").replace(/[-_]+/g," ")}function We(O){return typeof O==="string"&&O.trim()?O.trim():void 0}function Xo(O){if(O.status==="running")return null;let N=O.detail??{kind:""},L=nl(O.stepId);if(N.kind==="narration"){let F=Array.isArray(N.tasks)?N.tasks.filter((M)=>typeof M==="string"):[];L=We(N.title)??(F.length>0?F.join(", "):L);let H=We(N.reason);if(H)L+=` — ${H}`}else if(N.kind==="reason"&&We(N.reason))L+=` — ${We(N.reason)}`;else if(N.kind==="verdict")L=N.approved===!0?"review approved":`review asked for changes${We(N.feedback)?` — ${We(N.feedback)}`:""}`;else if(N.kind==="dispatch"&&typeof N.launched==="number")L+=` — ${N.launched} started`;return O.status==="failed"?`${L} (failed)`:L}function Yo(O){return{kind:"cycle",text:`cycle "${O.title}": ${O.stage}`}}function rl(O){return{kind:"task",text:`task "${O.title||O.id}": ${O.status}`}}function Zo(O){return{kind:"preview",text:`preview: ${O.state}${O.url?` ${O.url}`:""}`}}function sl(O,N,L){let F=[],H=N.activity.filter((M)=>Xo(M)!==null&&!L.has(M.id));if(!O){F.push({kind:"project",text:`${N.project.name}: ${N.project.status} (${N.project.runStatus})`});for(let M of N.cycles)if(!Qc.has(M.status))F.push(Yo(M));if(N.preview.url)F.push(Zo(N.preview))}else{if(O.project.status!==N.project.status||O.project.runStatus!==N.project.runStatus)F.push({kind:"project",text:`project: ${N.project.status} (${N.project.runStatus})`});let M=!1;for(let U of N.cycles){let G=O.cycles.find((D)=>D.id===U.id);if(G&&G.status===U.status)continue;if(F.push(Yo(U)),Vo.has(U.status)&&!(G&&Vo.has(G.status)))M=!0}for(let U of N.tasks){let G=O.tasks.find((D)=>D.id===U.id);if(!G||G.status!==U.status)F.push(rl(U))}for(let U of N.agents){let G=O.agents.find((D)=>D.id===U.id);if(G&&G.state!==U.state)F.push({kind:"agent",text:`${tl(U)} ${U.state==="working"?"started working":"is idle"}`})}if(O.preview.url!==N.preview.url||O.preview.state!==N.preview.state){if(F.push(Zo(N.preview)),N.preview.url&&O.preview.url!==N.preview.url)M=!0}if(M)F.push({kind:"landed",text:Zc})}for(let M of H){if(L.has(M.id))continue;L.add(M.id),F.push({kind:"activity",text:Xo(M)})}return F}function Qo(O){if(typeof O==="string")return We(O);if(Array.isArray(O))return We(O.map((N)=>N&&typeof N==="object"&&N.type==="text"?String(N.text??""):"").join(""));return}var ol=(O)=>O==="assistant"?"project manager":"to project manager";class ei{seen=new Set;drafts=new Map;spoke=!1;unsaved;lines(O){switch(O.type){case"MESSAGES_SNAPSHOT":{let N=O.messages.filter((L)=>{if(typeof L.id!=="string"||this.seen.has(L.id))return!1;if(L.role==="assistant"&&this.unsaved!==void 0&&Qo(L.content)===this.unsaved)return this.unsaved=void 0,this.seen.add(L.id),!1;return!0});for(let L of N)this.seen.add(L.id);return N.flatMap((L)=>{if(L.role!=="user"&&L.role!=="assistant")return[];let F=Qo(L.content);return F?[{kind:"message",text:`${ol(L.role)}: ${F}`}]:[]})}case"RUN_STARTED":return this.spoke=!1,[{kind:"run",text:"project manager is working…"}];case"TEXT_MESSAGE_START":return this.drafts.set(O.messageId,""),[];case"TEXT_MESSAGE_CONTENT":return this.drafts.set(O.messageId,(this.drafts.get(O.messageId)??"")+O.delta),[];case"TEXT_MESSAGE_END":{let N=We(this.drafts.get(O.messageId));if(this.drafts.delete(O.messageId),this.seen.has(O.messageId))return[];if(this.seen.add(O.messageId),!N)return[];return this.spoke=!0,this.unsaved=N,[{kind:"message",text:`project manager: ${N}`}]}case"TOOL_CALL_START":return[{kind:"tool",text:`project manager → ${O.toolCallName.replace(/[_-]+/g," ")}`}];case"CUSTOM":{let N=O.name==="hlix.turn_saved"?O.value?.messageId:void 0;if(typeof N==="string"&&this.spoke)this.seen.add(N),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: ${O.message}`}];default:return[]}}}async function ti(O,N,L){let F=mt(N),H=new AbortController,M=()=>H.abort();if(L.signal?.aborted)return;L.signal?.addEventListener("abort",M,{once:!0});let U=new ei,G,D=null,B=!1,J=null,W=()=>{if(D){B=!0;return}D=(async()=>{do{B=!1;let V=new AbortController,X=()=>V.abort();H.signal.addEventListener("abort",X,{once:!0}),J=X;try{for await(let ee of O.live.follow(Xc,F,{signal:V.signal}))for(let Y of U.lines(ee))L.emit(Y)}finally{J=null,H.signal.removeEventListener("abort",X)}}while(B&&!H.signal.aborted)})().catch((V)=>{if(H.signal.aborted)return;G=V,H.abort()}).finally(()=>{D=null})},z=()=>{let V=J;if(!V)return W();B=!0,Qe(Yc,H.signal).then(()=>{if(J===V)V()})},Q=new Set,te;try{W();for await(let{state:V,event:X}of O.live.project(N,{signal:H.signal})){if(X.type==="CUSTOM"){let ee=X.value;if(X.name==="hlix.thread_changed"&&ee?.threadId===F){if(ee.kind==="run_finished")z();else if(ee.kind!=="renamed")W()}continue}for(let ee of sl(te,V,Q))L.emit(ee);te=V}}catch(V){if(!H.signal.aborted)G??=V}finally{H.abort(),L.signal?.removeEventListener("abort",M),await D}if(G!==void 0)throw G}function ri(O){let L=(typeof O.flags.project==="string"?O.flags.project.trim():"")||t(O.cwd)?.config.projectId;if(!L)throw new e("missing_argument","A project is required: pass --project <id>, or run this inside a folder bound to a project.");return L}var ni="The project manager is busy with another message. Try again in a moment; /watch shows what it is doing.";function ft(O,N){if(typeof O!=="object"||O===null)return"";let L=O[N];return L===null||L===void 0?"":String(L)}var Mr={name:"projects list",summary:"List the projects in your workspace",usage:"Usage: hlix projects list [--json]",supportsJson:!0,async run(O){let N=await O.requireClient().projects.list();if(O.json)return O.stdout(oe(ae(Mr.name,N))),0;let L=Array.isArray(N)?N:[];if(L.length===0)return O.stdout(`No projects.
115
+ `),0;return O.stdout(`${Je(["ID","NAME","STACK"],L.map((F)=>[ft(F,"id"),ft(F,"name"),ft(F,"stack")]))}
116
+ `),0}},Ur={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(`
117
+ `),supportsJson:!0,args:{min:0,max:1},async run(O){let N=O.args[0]??t(O.cwd)?.config.projectId;if(!N)throw new e("missing_argument","A project id is required, or run this inside a folder bound to a project.");let L=await O.requireClient().projects.get(N);if(O.json)return O.stdout(oe(ae(Ur.name,L))),0;let F=L.repos;return O.stdout(`${je([["id",ft(L,"id")],["name",ft(L,"name")],["stack",ft(L,"stack")],["status",ft(L,"status")],["repos",Array.isArray(F)?String(F.length):""]].filter(([,H])=>H!==""))}
118
+ `),0}},Dr={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(O){let N=O.requireClient(),L=O.args[0],F=await N.projects.list(),H=F.find((B)=>B.id===L),M=H?[H]:F.filter((B)=>B.name===L);if(M.length===0)throw new e("not_found",`No project named or identified by "${L}".`);if(M.length>1)throw new e("invalid_usage",`More than one project is named "${L}". Use its ID.`);let U=M[0],G=`Delete project "${U.name}"?`;if(O.stderr(`${G}
119
+ `),O.flags.yes!==!0){if(t(O.cwd)?.config.projectId===U.id)throw new e("approval_required","This folder is bound to that project. Pass --yes to delete it.");if(O.json||!O.confirm)throw new e("approval_required","Project deletion requires --yes when not interactive.");if(!await O.confirm(G))throw new e("cancelled","Project deletion cancelled.")}let D=await N.projects.delete(U.id);if(O.json)O.stdout(oe(ae(Dr.name,D)));else O.stdout(`Deleted project "${U.name}".
120
+ `);return 0}},Gr={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(`
121
+ `),supportsJson:!0,options:["project"],agentTool:!1,async run(O){let N=ri(O),L=O.requireClient();return await L.projects.get(N),await ti(L,N,{...O.signal?{signal:O.signal}:{},emit:(F)=>O.stdout(O.json?`${JSON.stringify(ae(Gr.name,F))}
122
+ `:`${s(F.text)}
123
+ `)}),0}},Br={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(`
124
+ `),supportsJson:!0,options:["project"],args:{min:1,max:1e4},freeText:!0,async run(O){let N=ri(O),L=O.args.join(" ").trim();if(!L)throw new e("missing_argument","A message is required.");let F=O.requireClient(),H="";try{for await(let M of F.live.run("project-manager",{threadId:mt(N),text:L},O.signal?{signal:O.signal}:void 0))if(M.type==="TEXT_MESSAGE_CONTENT"){if(H+=M.delta,!O.json)O.stdout(s(M.delta))}else if(M.type==="RUN_ERROR"){if(M.code==="409")throw new e("conflict",ni);throw new e("server_error",`The project manager could not answer: ${M.message}`)}}catch(M){if(M instanceof lt)throw new e("conflict",ni);throw M}if(O.json)O.stdout(oe(ae(Br.name,{answer:H})));else if(!H)O.stdout(`Sent. The project manager answered without text.
125
+ `);else if(!H.endsWith(`
126
+ `))O.stdout(`
127
+ `);return 0}};function Jr(O,N){let L=O.args[0];if(!L)throw new e("missing_argument",`A ${N} id is required.`);return L}function si(O,N){let L=O.flags[N];return typeof L==="string"&&L.trim()?L.trim():void 0}function qe(O,N){if(typeof O!=="object"||O===null)return"";let L=O[N];return L===null||L===void 0?"":String(L)}var Wr={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(`
128
+ `),supportsJson:!0,options:["project","status"],async run(O){let N=si(O,"project")??t(O.cwd)?.config.projectId,L=si(O,"status"),F=await O.requireClient().tasks.list({...N?{projectId:N}:{},...L?{status:L}:{}});if(O.json)return O.stdout(oe(ae(Wr.name,F))),0;let H=Array.isArray(F)?F:[];if(H.length===0)return O.stdout(`No tasks.
129
+ `),0;return O.stdout(`${Je(["ID","STATUS","TITLE"],H.map((M)=>[qe(M,"id"),qe(M,"status"),qe(M,"title")||qe(M,"description").split(`
130
+ `)[0]||""]))}
131
+ `),0}},qr={name:"tasks get",summary:"Show one task",usage:"Usage: hlix tasks get <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(O){let N=Jr(O,"task"),L=await O.requireClient().tasks.get(N);if(O.json)return O.stdout(oe(ae(qr.name,L))),0;return O.stdout(`${je([["id",qe(L,"id")],["status",qe(L,"status")],["title",qe(L,"title")],["project",qe(L,"projectId")],["description",qe(L,"description")]])}
132
+ `),0}},zr={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(O){let N=Jr(O,"task"),L=O.requireClient(),F=await L.tasks.get(N);if(!F.cycleId)throw new e("not_found",`Task ${N} belongs to no cycle, so there is no change to review.`);let H=await L.cycles.review(F.cycleId);if(O.json)return O.stdout(oe(ae(zr.name,H))),0;return O.stdout(`${JSON.stringify(H,null,2)}
133
+ `),0}},Kr={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(`
134
+ `),supportsJson:!0,args:{min:1,max:1},async run(O){let N=Jr(O,"task"),L=O.requireClient(),{projectId:F}=await L.tasks.get(N),H;for await(let M of L.live.task(F,N))if(O.json)O.stdout(`${JSON.stringify(ae(Kr.name,M))}
135
+ `);else if(M.state==="unmet")O.stdout(`error: ${s(M.reason)}
136
+ `);else if(M.task&&M.task.status!==H)H=M.task.status,O.stdout(`${s(H)}
137
+ `);return 0}};import{realpath as Hd}from"node:fs/promises";import{resolve as Md}from"node:path";import{parse as Cl}from"jsonc-parser";import{parse as Il}from"smol-toml";import{parse as Tl}from"yaml";var Nn={install:null,previewCommand:null,previewPort:null,verifyCommand:null,packageManager:null};var il=[["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]],al=/^(?: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+[^|;&]*)?$/,cl=["vite","next","webpack","react-scripts","@rsbuild/core","parcel"],nn=8080,On=8000,ll=String.raw`import http.server as h, urllib.parse as u, sys, os, re, io
138
+ B = (sys.argv[2] if len(sys.argv) > 2 else "").rstrip("/")
139
+ D = os.path.abspath(sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else ".")
140
+ E = sys.argv[4] if len(sys.argv) > 4 else "index.html"
141
+ P = int(os.environ.get("PORT") or ${nn})
142
+ L = re.compile(rb"((?:src|href|action|poster)\s*=\s*[\"'])/(?!/)" + (rb"(?!" + re.escape(B[1:].encode()) + rb"(?:/|[\"']))" if B else b""))
143
+ class H(h.SimpleHTTPRequestHandler):
144
+ def __init__(s, *a, **k):
145
+ super().__init__(*a, directory=D, **k)
146
+ def send_head(s):
147
+ raw = u.urlsplit(s.path).path
148
+ if B and (raw == B or raw.startswith(B + "/")):
149
+ s.path = s.path[len(B):] or "/"
150
+ p = u.unquote(u.urlsplit(s.path).path).replace(chr(92), "/")
151
+ if any(x.startswith(".") for x in p.split("/")):
152
+ s.send_error(404)
153
+ return None
154
+ f = s.translate_path(s.path)
155
+ if os.path.isdir(f) and p.endswith("/"):
156
+ f = os.path.join(f, E if os.path.abspath(f) == D else "index.html")
157
+ elif not os.path.exists(f) and "." not in p.rsplit("/", 1)[-1]:
158
+ f = f + ".html" if os.path.isfile(f + ".html") else os.path.join(D, E)
159
+ if not (f.lower().endswith((".html", ".htm")) and os.path.isfile(f)):
160
+ return super().send_head()
161
+ with open(f, "rb") as fh:
162
+ body = fh.read()
163
+ if B:
164
+ body = L.sub(lambda m: m.group(1) + B.encode() + b"/", body)
165
+ s.send_response(200)
166
+ s.send_header("Content-Type", "text/html; charset=utf-8")
167
+ s.send_header("Content-Length", str(len(body)))
168
+ s.end_headers()
169
+ return io.BytesIO(body)
170
+ def list_directory(s, path):
171
+ s.send_error(404)
172
+ return None
173
+ h.ThreadingHTTPServer(("", P), H).serve_forever()
174
+ `;function Hn(O=".",N="index.html"){return`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${rn(ll)} "$PREVIEW_PUBLIC_PATH" ${O}${N==="index.html"?"":` ${li(N)}`}`}function ai(O){if(O.has("index.html"))return"index.html";let N=[...O].filter((L)=>!L.startsWith(".")&&!/[\\/]/.test(L)&&/\.html?$/i.test(L));return N.length===1?N[0]:null}var ci="HLIX_PREVIEW_FAILURE";function Ln(O){return`{ echo "${ci}=${O}"; exit 1; }`}var dl=`const handler = {
175
+ get(target, key) {
176
+ if (key === 'then' || key === 'prototype' || key === '$$typeof') return undefined
177
+ if (key === '__esModule') return false
178
+ if (key === Symbol.toPrimitive) return () => ''
179
+ if (key === 'displayName' || key === 'name') return 'Unavailable'
180
+ return stub
181
+ },
182
+ apply(target, self, args) {
183
+ const props = args[0]
184
+ return props !== null && typeof props === 'object' && !Array.isArray(props) ? null : stub
185
+ },
186
+ }
187
+ const stub = new Proxy(function Unavailable() {}, handler)
188
+ module.exports = stub
189
+ `,pl=`const path = require('path')
190
+ const loaded = __CONFIG__
191
+ const dir = path.join(__dirname, 'hlix-web')
192
+ // React Native Web's own names, as imported directly and as Expo rewrites them.
193
+ const WEB_ROOT = new Set(['react-native', 'react-native-web', 'react-native-web/dist/index'])
194
+ function withNativeStubs(config) {
195
+ const upstream = config.resolver.resolveRequest
196
+ config.resolver.resolveRequest = (context, moduleName, platform) => {
197
+ if (platform === 'web' && !context.originModulePath.startsWith(dir)) {
198
+ if (WEB_ROOT.has(moduleName)) return { type: 'sourceFile', filePath: path.join(dir, 'react-native.js') }
199
+ if (moduleName.startsWith('react-native/Libraries/')) return { type: 'sourceFile', filePath: path.join(dir, 'native-stub.js') }
200
+ }
201
+ return (upstream || context.resolveRequest)(context, moduleName, platform)
202
+ }
203
+ return config
204
+ }
205
+ module.exports = typeof loaded === 'function'
206
+ ? async (...args) => withNativeStubs(await loaded(...args))
207
+ : loaded && typeof loaded.then === 'function' ? loaded.then(withNativeStubs) : withNativeStubs(loaded)
208
+ `,ul=[[86,57],[85,56],[83,55],[81,54],[79,53],[76,52],[74,51]],ml=String.raw`const fs = require("fs"), cp = require("child_process")
209
+ const [base, pm] = process.argv.slice(-2)
210
+ // No preview path: not the preview's own copy. Prepared already: a restart.
211
+ if (!base || fs.existsSync("hlix-web/native-stub.js")) process.exit(0)
212
+ const fail = (code, why) => { console.error("hlix: " + why); console.log("${ci}=" + code); process.exit(1) }
213
+ const run = (cmd, args) => {
214
+ const res = cp.spawnSync(cmd, args, { stdio: "inherit", env: { ...process.env, CI: "1", EXPO_NO_TELEMETRY: "1" } })
215
+ if (res.status !== 0) fail("packages_unavailable", "could not install " + args.join(" "))
216
+ }
217
+ const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"))
218
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies }
219
+ const bare = !("expo" in deps)
220
+ // npm refuses a React Native major change over peer ranges; the others only warn.
221
+ const peers = pm === "npm" ? ["--", "--legacy-peer-deps"] : []
222
+ if (bare) {
223
+ const minor = Number((String(deps["react-native"] || "").match(/0\.(\d+)/) || [])[1] || 0)
224
+ const sdk = (${JSON.stringify(ul)}).find(([m]) => minor >= m)
225
+ if (!sdk) fail("react_native_too_old", "React Native 0." + minor + " is older than any release with web support")
226
+ const add = { npm: ["install", "--legacy-peer-deps", "--no-audit", "--no-fund"], pnpm: ["add"], yarn: ["add"], bun: ["add"] }[pm] || ["install"]
227
+ run(pm, [...add, "expo@~" + sdk[1] + ".0.0"])
228
+ }
229
+ const missing = ["react-dom", "react-native-web", "@expo/metro-runtime", "babel-preset-expo"].filter((name) => !(name in deps))
230
+ if (missing.length) run("npx", ["expo", "install", ...missing, ...peers])
231
+ if (bare) {
232
+ run("npx", ["expo", "install", "--fix", ...peers])
233
+ fs.mkdirSync("hlix-web", { recursive: true })
234
+ fs.writeFileSync("hlix-web/entry.js", "import 'expo'\nimport { AppRegistry } from 'react-native'\nimport '../index'\nconst rootTag = document.getElementById('root') || document.body.appendChild(document.createElement('div'))\nAppRegistry.runApplication(AppRegistry.getAppKeys()[0], { rootTag })\n")
235
+ const next = JSON.parse(fs.readFileSync("package.json", "utf8"))
236
+ next.main = "hlix-web/entry.js"
237
+ fs.writeFileSync("package.json", JSON.stringify(next, null, 2))
238
+ for (const file of ["babel.config.js", ".babelrc", ".babelrc.js", "babel.config.cjs"]) {
239
+ if (!fs.existsSync(file)) continue
240
+ fs.writeFileSync(file, fs.readFileSync(file, "utf8").replace(/module:(?:@react-native\/babel-preset|metro-react-native-babel-preset)/g, "babel-preset-expo"))
241
+ }
242
+ }
243
+ fs.mkdirSync("hlix-web", { recursive: true })
244
+ fs.writeFileSync("hlix-web/native-stub.js", ${JSON.stringify(dl)})
245
+ 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")
246
+ const own = ["metro.config.js", "metro.config.cjs"].find((file) => fs.existsSync(file))
247
+ let config = "require('expo/metro-config').getDefaultConfig(__dirname)"
248
+ if (own && !bare && /expo/.test(fs.readFileSync(own, "utf8"))) {
249
+ // Beside the original, so its own __dirname still names the project.
250
+ fs.renameSync(own, "metro.config.hlix-original.js")
251
+ config = "require('./metro.config.hlix-original.js')"
252
+ }
253
+ if (own) fs.rmSync(own, { force: true })
254
+ fs.writeFileSync("metro.config.js", ${JSON.stringify(pl)}.replace("__CONFIG__", config))
255
+ `,fl=String.raw`const fs = require("fs")
256
+ const base = (process.argv[process.argv.length - 1] || "").replace(/\/+$/, "")
257
+ if (!base) process.exit(0)
258
+ const dynamic = ["app.config.ts", "app.config.js"].filter((file) => fs.existsSync(file))
259
+ if (dynamic.length || fs.existsSync("app.json")) {
260
+ const json = dynamic.length ? { expo: require("expo/config").getConfig(process.cwd()).exp } : JSON.parse(fs.readFileSync("app.json", "utf8"))
261
+ const expo = json.expo || json
262
+ expo.experiments = { ...expo.experiments, baseUrl: base }
263
+ fs.writeFileSync("app.json", JSON.stringify(json, null, 2))
264
+ for (const file of dynamic) fs.rmSync(file)
265
+ }
266
+ `,gl=String.raw`import json, os, shutil, sys, tarfile, tempfile, urllib.request
267
+ root = sys.argv[1]
268
+ base = "https://storage.googleapis.com/flutter_infra_release/releases"
269
+ index = json.load(urllib.request.urlopen(base + "/releases_linux.json", timeout=60))
270
+ stable = index["current_release"]["stable"]
271
+ release = next(r for r in index["releases"] if r["hash"] == stable)
272
+ tmp = tempfile.mkdtemp(dir=root)
273
+ archive = os.path.join(tmp, "flutter.tar.xz")
274
+ with urllib.request.urlopen(base + "/" + release["archive"], timeout=600) as src, open(archive, "wb") as out:
275
+ shutil.copyfileobj(src, out)
276
+ with tarfile.open(archive) as tar:
277
+ tar.extractall(tmp, filter="tar")
278
+ os.remove(archive)
279
+ os.rename(os.path.join(tmp, "flutter"), os.path.join(root, "sdk"))
280
+ shutil.rmtree(tmp, ignore_errors=True)
281
+ print("hlix: Flutter " + release["version"] + " installed")
282
+ `,hl=String.raw`import sys, zipfile
283
+ args = [a for a in sys.argv[1:] if a not in ("-o", "-q")]
284
+ dest = args[args.index("-d") + 1] if "-d" in args else "."
285
+ zipfile.ZipFile(args[0]).extractall(dest)
286
+ `;function oi(O,N){return`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${rn(O)} ${N}`}function yl(){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)"; ${oi(gl,'"$HOME/.cache/hlix-flutter"')}; } || ${Ln("flutter_sdk_unavailable")}; }`,`{ command -v unzip >/dev/null 2>&1 || { printf '#!/bin/sh\\n%s "$@"\\n' ${li(oi(hl,""))} > "$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 || ${Ln("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/" && ${Hn("build/web")}; } || ${Ln("web_build_failed")}; }`].join(" && ")}function wl(O){let N=`printf %s ${rn(ml)} | base64 -d | node - "$PREVIEW_PUBLIC_PATH" ${O}`,L=`CI=1 npx expo export --platform web --output-dir dist && ${Hn("dist")}`;return`${N} && ${di(fl,"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"; ${L}; } || ${Ln("web_build_failed")}; }`}function li(O){return`'${O.replace(/'/g,"'\\''")}'`}var vl=String.raw`const fs = require("fs")
287
+ const base = (process.argv[process.argv.length - 1] || "").replace(/\/+$/, "")
288
+ if (!base) process.exit(0)
289
+ const file = ["next.config.ts", "next.config.mts", "next.config.mjs", "next.config.js", "next.config.cjs"].find((name) => fs.existsSync(name))
290
+ const wrap = (name) => "(async (...args) => { const c = typeof " + name + " === \"function\" ? await " + name + "(...args) : await " + name + "; return { ...c, basePath: " + JSON.stringify(base) + " } })"
291
+ if (!file) {
292
+ fs.writeFileSync("next.config.mjs", "export default { basePath: " + JSON.stringify(base) + " }\n")
293
+ process.exit(0)
294
+ }
295
+ let text = fs.readFileSync(file, "utf8")
296
+ if (text.includes("__hlixPreviewConfig")) process.exit(0)
297
+ if (/\bexport\s+default\b/.test(text)) {
298
+ text = text.replace(/\bexport\s+default\b/, "const __hlixPreviewConfig =") + "\nexport default " + wrap("__hlixPreviewConfig") + "\n"
299
+ } else if (/\bmodule\.exports\s*=/.test(text)) {
300
+ text += "\nconst __hlixPreviewConfig = module.exports\nmodule.exports = " + wrap("__hlixPreviewConfig") + "\n"
301
+ } else {
302
+ process.exit(0)
303
+ }
304
+ fs.writeFileSync(file, text)
305
+ `,bl=String.raw`import os, re, sys
306
+ hosts = [h for h in (sys.argv[2] if len(sys.argv) > 2 else "").split(",") if h]
307
+ if not hosts:
308
+ sys.exit(0)
309
+ match = re.search(r"DJANGO_SETTINGS_MODULE['\"]\s*,\s*['\"]([\w.]+)['\"]", open("manage.py").read())
310
+ if not match:
311
+ sys.exit(0)
312
+ module = match.group(1).replace(".", "/")
313
+ path = module + ".py" if os.path.isfile(module + ".py") else os.path.join(module, "__init__.py")
314
+ if not os.path.isfile(path) or "# hlix preview hosts" in open(path).read():
315
+ sys.exit(0)
316
+ with open(path, "a") as f:
317
+ f.write("\n# hlix preview hosts\nALLOWED_HOSTS = list(globals().get('ALLOWED_HOSTS') or ['.localhost', '127.0.0.1', '[::1]']) + %r\n" % hosts)
318
+ `;function di(O,N){return`printf %s ${rn(O)} | base64 -d | node - "$${N}"`}var kl=["test","typecheck","check","build","lint"],Sl=/^(?:\.eslintrc(?:\.(?:js|cjs|mjs|json|ya?ml))?|eslint\.config\.(?:js|cjs|mjs|ts|cts|mts))$/;function jl(O,N){return/\bnext\s+lint\b/.test(O)&&![...N].some((L)=>Sl.test(L))}var Um=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 El=["dev","start","serve","preview"];function Xr(O){if(!O)return{};try{let N=JSON.parse(O);return N&&typeof N==="object"?N:{}}catch{return{}}}function xl(O){return{...ze(O.dependencies)?O.dependencies:{},...ze(O.devDependencies)?O.devDependencies:{}}}function Pl(O){if(!new Set(O.rootFiles).has("pubspec.yaml"))return!1;let N=O.configFiles?.["pubspec.yaml"];return N===void 0||/^\s+sdk:\s*flutter\s*$/m.test(N)}function pi(O){let N=new Set(O.rootFiles),L=Xr(O.packageJson),F=typeof L.packageManager==="string"?L.packageManager.split("@")[0]:"",H=F==="bun"||N.has("bun.lock")||N.has("bun.lockb")?"bun":F==="pnpm"||N.has("pnpm-lock.yaml")?"pnpm":F==="yarn"||N.has("yarn.lock")?"yarn":F==="npm"||N.has("package.json")?"npm":null,M=ai(N);if(!H){if(Pl(O))return{...Nn,previewCommand:yl(),previewPort:nn,mobile:!0};let B=_l(N,O.configFiles??{});if(B)return B;return M?{...Nn,previewCommand:Hn(".",M),previewPort:nn}:Nn}let U=ui(L,N,H),G={install:`${H} install`,verifyCommand:U.verifyCommand,packageManager:H},D=U.webApp?null:$l(O.workspacePackages??[],H)[0]??null;if(D){let B=(J)=>`cd ${D.dir} && ${J}`;return{...G,previewCommand:B(D.previewCommand),previewPort:D.previewPort,verifyCommand:G.verifyCommand??(D.verifyCommand?B(D.verifyCommand):null),...D.mobile?{mobile:!0}:{}}}return{...G,previewCommand:U.previewCommand,previewPort:U.previewPort,...U.mobile?{mobile:!0}:{}}}function ui(O,N,L,F){let H=ze(O.scripts)?O.scripts:{},M=(le)=>`${L} run ${le}`,U=(le,ge)=>`${M(le)}${L==="npm"?" --":""} ${ge}`,G=El.find((le)=>typeof H[le]==="string"),D=kl.find((le)=>typeof H[le]==="string"&&!/no test specified/i.test(String(H[le]))&&!/(?:^|\s)(?:--watch(?:All)?|-w)(?:\s|=|$)/.test(String(H[le]))&&!jl(String(H[le]),N)),B=D?M(D):null,J=xl(O),W={previewCommand:null,previewPort:null,verifyCommand:B,webApp:!1,mobile:!1,explicitPort:!1};if("expo"in J||"react-native"in J&&!cl.some((le)=>(le in J)))return{previewCommand:wl(L),previewPort:F??nn,verifyCommand:B,webApp:!0,mobile:!0,explicitPort:!1};let z=il.find(([le])=>(le in J)),Q=G?Vr(String(H[G]))??z?.[1]??null:null,te=ai(N);if(!G&&!z&&te)return{...W,previewCommand:Hn(".",te),previewPort:F??nn};if(!G)return W;let V=String(H[G]).trim(),X=F!=null?` --port ${F}`:"",ee=V.split("&&").map((le)=>le.trim()),Y=X||(Q!=null&&Vr(V)==null&&al.test(ee.at(-1))?` --port ${Q}`:""),ie=Y?U(G,Y.trim()):M(G);if(ee.length>1&&ee.every((le)=>/^vite(?:\s|$)/.test(le))&&!("@sveltejs/kit"in J)){let le={npm:"npx",bun:"bunx",pnpm:"pnpm exec",yarn:"yarn exec"}[L];ie=ee.map((ge,re)=>`${le} ${ge} --base "$PREVIEW_BASE_PATH/"${/^vite\s+build\b/.test(ge)?"":" --host 0.0.0.0"}${re===ee.length-1?Y:""}`).join(" && ")}else if(/^vite(?:\s+(?:dev|serve|preview))?(?:\s|$)/.test(V)&&!/&&|;|\|/.test(V)&&!("@sveltejs/kit"in J))ie=U(G,`--base "$PREVIEW_BASE_PATH/" --host 0.0.0.0${Y}`);else if(/^astro\s+(?:dev|preview)(?:\s|$)/.test(V))ie=U(G,`--base "$PREVIEW_BASE_PATH"${Y}`);else if(/^next\s+(?:dev|start)(?:\s|$)/.test(V))ie=`${di(vl,"PREVIEW_BASE_PATH")} && ${ie}`;else if(/^nuxt\s+(?:dev|preview|start)(?:\s|$)/.test(V))ie=`NUXT_APP_BASE_URL="$PREVIEW_BASE_PATH/" ${ie}`;return{previewCommand:ie,previewPort:F??Q,verifyCommand:B,webApp:Boolean(z),mobile:!1,explicitPort:Vr(V)!=null}}var ii=["web","app","frontend","site","www","client","dashboard"];function $l(O,N){let L=O.filter((H)=>Fn(H.dir)).map((H)=>{let M=Xr(H.packageJson),U=new Set(H.rootFiles??[]);return{dir:H.dir,pkg:M,files:U,...ui(M,U,N)}}).filter((H)=>H.webApp&&H.previewCommand&&H.previewPort!=null),F=(H)=>{let M=ii.indexOf(H.split("/").at(-1)??"");return M<0?ii.length:M};return L.sort((H,M)=>Number(H.mobile)-Number(M.mobile)||Number(!H.dir.startsWith("apps/"))-Number(!M.dir.startsWith("apps/"))||F(H.dir)-F(M.dir)||(H.dir<M.dir?-1:H.dir>M.dir?1:0))}function Fn(O){return/^[A-Za-z0-9._@-]+(?:\/[A-Za-z0-9._@-]+)*$/.test(O)&&!O.split("/").some((N)=>N===".."||N===".")}function mi(O){let N=Xr(O.packageJson),L=Array.isArray(N.workspaces)?N.workspaces:ze(N.workspaces)&&Array.isArray(N.workspaces.packages)?N.workspaces.packages:[],F=O.configFiles?.["pnpm-workspace.yaml"]??"";for(let G of F.split(/\r?\n/)){let D=G.match(/^\s*-\s*["']?([^"'#\s]+)["']?/);if(D)L.push(D[1])}let H=L.filter((G)=>typeof G==="string"&&!G.startsWith("!"));if(H.length===0&&new Set(O.rootFiles).has("turbo.json"))H.push("apps/*","packages/*");for(let G of Object.values(ze(N.scripts)?N.scripts:{})){if(typeof G!=="string")continue;let D=G.match(/^\s*cd\s+([A-Za-z0-9._@/-]+)\s*&&/)?.[1];if(D&&Fn(D))H.push(D)}let M=new Set,U=new Set;for(let G of H){let D=G.replace(/^\.\//,"").replace(/\/$/,"");if(/^[^*]+\/\*$/.test(D)&&Fn(D.slice(0,-2)))M.add(D.slice(0,-2));else if(!D.includes("*")&&Fn(D))U.add(D)}return{parents:[...M].sort(),packages:[...U].sort()}}function _l(O,N){let L=`${N["requirements.txt"]??""}
319
+ ${N["pyproject.toml"]??""}`.toLowerCase(),F=(J)=>new RegExp(`(^|[\\s"'\\[,])${J}\\b`,"m").test(L),H=O.has("requirements.txt")?'"$V/bin/pip" install -q -r requirements.txt':O.has("pyproject.toml")?'"$V/bin/pip" install -q .':null,M=(J,W="")=>H?`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" && ${H}${W} && touch "$V/.ready"; }; } && "$V/bin/python" ${J}`:null,U=F("pytest")?M("-m pytest",' && "$V/bin/pip" install -q pytest'):null,D=["main.py","app.py","server.py","api.py"].find((J)=>O.has(J))?.replace(/\.py$/,""),B=(J,W=U)=>({...Nn,previewCommand:J,previewPort:On,verifyCommand:W});if(O.has("manage.py")){let J=`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${rn(bl)} "$PREVIEW_ALLOWED_HOSTS"`;return B(`${J} && python3 manage.py runserver 0.0.0.0:${On}`,U??(F("django")?M("manage.py test"):null))}if(D&&F("fastapi"))return B(`python3 -m uvicorn ${D}:app --host 0.0.0.0 --port ${On} --root-path "$PREVIEW_PUBLIC_PATH"`);if(D&&F("flask"))return B(`python3 -m flask --app ${D} run --host 0.0.0.0 --port ${On}`);return null}function rn(O){return btoa(O)}function Vr(O){let N=O.match(/(?:--port(?:=|\s+)|-p\s+|\bPORT=)(\d{2,5})\b/),L=N?Number(N[1]):NaN;return Number.isInteger(L)&&L>0&&L<=65535?L:null}function ze(O){return Boolean(O)&&typeof O==="object"&&!Array.isArray(O)}function fi(O){let N=new Set(O.rootFiles),L=new Set;if(N.has("package.json")){for(let H of["coverage",".cache"])L.add(H);if(["package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb"].some((H)=>N.has(H)))L.add("node_modules")}if(N.has("Cargo.toml"))L.add("target");if(["pyproject.toml","requirements.txt","setup.py"].some((H)=>N.has(H)))L.add("__pycache__");if(N.has("composer.json")&&N.has("composer.lock"))L.add("vendor");for(let H of Yr({...O,rootFiles:N}))L.add(H);return[...L].sort()}function Ge(O,N,L){let F=(O.match(/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*|[A-Za-z_$][\w$]*|[^\s]/g)??[]).filter((D)=>!D.startsWith("//")&&!D.startsWith("/*"));if(F[0]!=="{"){let D=F.findIndex((J,W)=>J==="export"&&F[W+1]==="default"),B=F.findIndex((J,W)=>J==="module"&&F.slice(W+1,W+4).join("")===".exports=");if(D<0&&B<0)return null;if(F=F.slice(D>=0?D+2:B+4),["defineConfig","defineNuxtConfig"].includes(F[0]??"")&&F[1]==="(")F=F.slice(2);if(F[0]!=="{")return null}if(F.some((D,B)=>D==="."&&F[B+1]==="."&&F[B+2]==="."))return null;let H=(D="")=>D.replace(/^["']|["']$/g,""),M=[],U,G=0;for(let D=0;D<F.length;D++){let B=F[D];if(B==="{")M.push(F[D-1]===":"?H(F[D-2]):"");if(B==="}")M.pop();if(!M.length)break;if(B==="["&&["{",","].includes(F[D-1]??""))return null;if(N&&M.length===1&&H(B)===N){if(F[D+1]!==":"||F[D+2]!=="{"||++G>1)return null}if(H(B)===L&&(N?M.length===2&&M.at(-1)===N:M.length===1)&&F[D+1]!==":")return null;if(H(B)!==L||F[D+1]!==":"||(N?M.length!==2||M.at(-1)!==N:M.length!==1))continue;let J=F[D+2]??"";if(U!==void 0||!/^["'`][^\\$]*["'`]$/.test(J)||![",","}"].includes(F[D+3]??""))return null;U=J.slice(1,-1)}return U}function Yr(O){let N={};try{let z=JSON.parse(O.packageJson??"{}");if(ze(z))N=z}catch{}let L={...ze(N.dependencies)?N.dependencies:{},...ze(N.devDependencies)?N.devDependencies:{}},F=ze(N.scripts)?Object.entries(N.scripts).filter((z)=>typeof z[1]==="string"):[],H=(z,Q=z)=>(z in L)||F.some(([,te])=>new RegExp(`(?:^|[;&|\\s])${Q}(?:\\s|$)`).test(te)),M=O.configFiles??{},U=new Set,G=(z)=>{if(typeof z!=="string")return null;let Q=z.replace(/^\.\//,"").replace(/\/$/,"");return Q&&!Q.startsWith("/")&&!/[\\:*?\[\]#!$`"'\r\n]/.test(Q)&&!Q.split("/").some((te)=>!te||[".","..",".git",".hlix"].includes(te))?Q:null},D=(z)=>{let Q=G(z);if(Q)U.add(Q)},B=(z,Q)=>{let te=F.filter(([Y,ie])=>/(?:^|:)build(?:$|:)/.test(Y)||new RegExp(`\\b${z} build\\b`).test(ie)),V=te.filter(([,Y])=>new RegExp(`(?:^|\\s)${z}(?:\\s|$)`).test(Y));if(!V.length&&(te.length||N.workspaces!==void 0))return null;if(te.some((Y)=>!V.includes(Y)&&/--(?:out|dist|root|config|project)|\s-[dpc]\b/.test(Y[1])))return null;let X,ee=!1;for(let[,Y]of V){if(/[$`\\;|<>\n]/.test(Y)||/(?:^|\s)(?:cd|pushd|popd)\s/.test(Y))return null;for(let ie of Y.split("&&")){let le=ie.match(/"[^"\n]*"|'[^'\n]*'|[^\s]+/g)??[];if(le.some((ne)=>/["']/.test(ne)&&!/^(?:"[^"\n]*"|'[^'\n]*')$/.test(ne)))return null;let ge=le.map((ne)=>ne.replace(/^["']|["']$/g,"")),re=ge.indexOf(z);if(re<0)continue;if(re!==0&&!(re===1&&["npx","bunx"].includes(ge[0])))return null;let K=ge.slice(re+1);if(K[0]==="build")K.shift();let q;for(let ne=0;ne<K.length;ne++){let[ue,...he]=K[ne].split("="),ye=he.length?he.join("="):void 0;if(!Q.includes(ue)||q!==void 0)return null;let xe=ye??K[++ne],we=G(xe);if(!we)return null;q=we}if(ee&&q!==X)return null;ee=!0,X=q}}return X},J=(z)=>{let Q=[...new Set([...O.rootFiles,...Object.keys(M)])].filter((te)=>te.startsWith(`${z}.config.`)||z==="turbo"&&te==="turbo.json");if(!Q.length)return"{}";return Q.length===1?M[Q[0]]??null:null},W=(z,Q,te,V,X,ee,Y)=>{let ie=J(z),le=B(z,X);if(ie===null||le===null)return;let ge=ee?Ge(ie,null,ee):void 0,re=Ge(ie,Q,te);if(ge===null||re===null)return;let K=ge===void 0||ge==="."||ge==="./"?"":G(ge);if(K===null)return;let ne=G(le??re??V);if(!ne)return;D(K?`${K}/${ne}`:ne);for(let ue of Y??[])D(K?`${K}/${ue}`:ue)};if(H("vite"))W("vite","build","outDir","dist",["--outDir","--out-dir"],"root");if(H("next")){let z=J("next"),Q=z===null?null:Ge(z,null,"output");if(z!==null&&(Q===void 0||Q==="standalone"||Q==="export"&&Ge(z,null,"distDir")===void 0))W("next",null,"distDir",".next",[],void 0,Q==="export"?["out"]:[])}if(H("astro"))W("astro",null,"outDir","dist",["--outDir","--out-dir"],"root");if(H("nuxt")){let z=J("nuxt");if(z!==null&&Ge(z,null,"nitro")===void 0&&Ge(z,null,"extends")===void 0)W("nuxt",null,"buildDir",".nuxt",[],"rootDir",[".output"])}if(H("turbo"))W("turbo",null,"cacheDir",".turbo",["--cache-dir"]);if(H("webpack")){let z=J("webpack");if(z!==null&&Ge(z,null,"context")===void 0)W("webpack","output","path","dist",["--output-path"])}if(H("rollup"))W("rollup","output","dir",void 0,["--dir","-d"]);if(H("parcel")||H("parcel-bundler","parcel")){let z=B("parcel",["--dist-dir"]);if(z!==null&&N.targets===void 0&&!["main","module","browser"].some((Q)=>typeof N[Q]==="string"))D(z??"dist")}if(H("react-scripts")&&B("react-scripts",[])!==null)D("build");if(H("typescript","tsc")){let z=B("tsc",["--outDir"]),Q=Object.keys(M).filter((te)=>/^tsconfig(?:\.[^/]*)?\.json$/.test(te));if(z!==null&&Q.length===1&&Q[0]==="tsconfig.json"){let te=M["tsconfig.json"];if(Ge(te,null,"extends")===void 0&&Ge(te,null,"references")===void 0){let V=Ge(te,"compilerOptions","outDir");if(V!==null)D(z??V)}}}if(Zr(M)){D("build"),D("dist");for(let z of O.rootFiles)if(z.endsWith(".egg-info"))D(z)}return[...U].sort()}function Zr(O){let N=(O["pyproject.toml"]??"").split(/^\[build-system\]\s*$/m)[1]?.split(/^\[/m)[0]??"";return/^build-backend\s*=\s*["'][^"']+["']/m.test(N)||/(?:from\s+(?:setuptools|distutils.core)\s+import\s+.*\bsetup\b|(?:setuptools|distutils.core)\.setup\s*\()/.test(O["setup.py"]??"")}var Pe=(O)=>O&&typeof O==="object"&&!Array.isArray(O)?O:{},Ot=(O)=>Array.isArray(O)?O.filter((N)=>typeof N==="string"):[];function gi(O){let N=[];function L(K,q="json"){let ne=O.get(K);if(!ne)return{};try{if(q==="yaml")return Pe(Tl(ne,{maxAliasCount:50}));if(q==="toml")return Pe(Il(ne));if(q==="jsonc"){let ue=[],he=Cl(ne,ue,{allowTrailingComma:!0});if(ue.length)throw Error("invalid JSONC");return Pe(he)}return Pe(JSON.parse(ne))}catch{return N.push(`Could not parse ${K}`),{}}}let F=[...O.keys()].sort(),H=L("package.json"),M={packageJson:O.get("package.json")??null,rootFiles:F.filter((K)=>!K.includes("/")),configFiles:Object.fromEntries(["requirements.txt","pyproject.toml","pnpm-workspace.yaml"].flatMap((K)=>O.get(K)?[[K,O.get(K)]]:[]))},U=mi(M),G=F.flatMap((K)=>{let q=K.replace(/\/package\.json$/,""),ne=q!==K&&(U.packages.includes(q)||U.parents.some((he)=>q.startsWith(`${he}/`)&&!q.slice(he.length+1).includes("/"))),ue=O.get(K);return ne&&ue?[{dir:q,packageJson:ue}]:[]}),D=pi({...M,workspacePackages:G}),B=typeof H.packageManager==="string"?/^(npm|pnpm|yarn|bun)@(.+)$/.exec(H.packageManager):null,J=Object.create(null);for(let[K,q]of Object.entries(Pe(H.engines)))if(typeof q==="string")J[K]=q;if(B)J[B[1]]=B[2].split("+")[0];let W=L("composer.json"),z={...Pe(W["require-dev"]),...Pe(W.require)},Q={...typeof z.php==="string"?{constraint:z.php}:{},extensions:Object.keys(z).filter((K)=>K.startsWith("ext-")).map((K)=>K.slice(4)).sort()};for(let[K,q]of[[".nvmrc","node"],[".node-version","node"],[".python-version","python"],[".php-version","php"],[".bun-version","bun"]]){let ne=O.get(K)?.trim();if(ne)J[q]=ne}for(let K of(O.get(".tool-versions")??"").split(/\r?\n/)){let[q,ne]=K.replace(/#.*/,"").trim().split(/\s+/);if(q&&ne)J[q==="nodejs"?"node":q]=ne}for(let K of[".mise.toml","mise.toml"])for(let[q,ne]of Object.entries(Pe(L(K,"toml").tools)))if(typeof ne==="string"||typeof ne==="number")J[q]=String(ne);else N.push(`Unsupported tool version for ${q} in ${K}`);let te=[];for(let K of F.filter((q)=>/(^|\/)package.json$/.test(q))){let q=K==="package.json"?H:L(K),ne={...Pe(q.dependencies),...Pe(q.devDependencies)};for(let ue of["nuxt","next","astro","@sveltejs/kit","vite"])if(ue in ne)te.push({path:K,name:ue})}for(let[K,q]of[["yiisoft/yii2","yii2"],["laravel/framework","laravel"]])if(K in z)te.push({path:"composer.json",name:q});let V=new Set,X=Object.create(null);function ee(K,q){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(K))return;if(V.add(K),/(?:^|_)HOST$/.test(K)&&typeof q==="string"&&/^[a-zA-Z0-9_.-]+$/.test(q))X[K]=q}for(let K of F.filter((q)=>/(^|\/)\.env\.(example|sample|template)$/.test(q)))for(let q of(O.get(K)??"").split(/\r?\n/)){let ne=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*(?:#.*)?$/.exec(q);if(ne)ee(ne[1],ne[2].replace(/^['"]|['"]$/g,""))}let Y=[],ie=[];for(let K of F.filter((q)=>/(^|\/)(?:docker-compose|compose)(?:[.-][^/]*)?\.ya?ml$/.test(q)))for(let[q,ne]of Object.entries(Pe(L(K,"yaml").services))){let ue=Pe(ne),he=typeof ue.image==="string"?ue.image:"",ye=he.split("/").at(-1)?.split(/[:@]/)[0],xe=ye==="mysql"||ye==="mariadb"?"mysql":ye==="postgres"?"postgres":ye==="redis"?"redis":null;if(xe)Y.push({file:K,name:q,kind:xe,image:he});else if(ye!=="traefik"&&ye!=="nginx"&&ye!=="caddy")ie.push({file:K,name:q});for(let[we,Ee]of Object.entries(Pe(ue.environment)))ee(we,Ee);for(let we of Ot(ue.environment)){let Ee=we.indexOf("=");ee(Ee<0?we:we.slice(0,Ee),Ee<0?null:we.slice(Ee+1))}}let le=F.find((K)=>K===".devcontainer/devcontainer.json")??F.find((K)=>K==="devcontainer.json"),ge;if(le){let K=L(le,"jsonc");for(let q of[K.containerEnv,K.remoteEnv])for(let[ne,ue]of Object.entries(Pe(q)))ee(ne,ue);ge={...typeof K.image==="string"?{image:K.image}:{},services:[...typeof K.service==="string"?[K.service]:[],...Ot(K.runServices)],ports:Array.isArray(K.forwardPorts)?K.forwardPorts.filter((q)=>Number.isInteger(q)&&Number(q)>0&&Number(q)<=65535):[],commands:[K.onCreateCommand,K.updateContentCommand,K.postCreateCommand,K.postStartCommand].filter((q)=>typeof q==="string")}}let re=Ot(H.workspaces).length?Ot(H.workspaces):Ot(Pe(H.workspaces).packages);return re.push(...Ot(L("pnpm-workspace.yaml","yaml").packages)),{language:O.has("package.json")?"typescript":O.has("pyproject.toml")||O.has("requirements.txt")?"python":O.has("go.mod")?"go":O.has("Cargo.toml")?"rust":O.has("composer.json")?"php":O.has("Gemfile")?"ruby":"other",commands:D,packageManager:B?{name:B[1],version:B[2]}:D.packageManager?{name:D.packageManager}:null,lockfiles:F.filter((K)=>/(^|\/)(bun.lockb?|pnpm-lock.yaml|yarn.lock|package-lock.json|composer.lock|uv.lock|poetry.lock|Pipfile.lock|Cargo.lock|Gemfile.lock)$/.test(K)),toolchain:J,php:Q,workspaces:[...new Set(re)].sort(),frameworks:te,turbo:O.has("turbo.json")||"turbo"in Pe(H.devDependencies)||"turbo"in Pe(H.dependencies),services:Y,unsupportedServices:ie,envKeys:[...V].sort(),envHosts:X,...ge?{devcontainer:ge}:{},warnings:N}}import{createHash as mn}from"node:crypto";import{createReadStream as Jl}from"node:fs";import{lstat as Li,mkdir as Wl,readFile as pn,readdir as ql,readlink as zl,realpath as Fi,stat as Hi,writeFile as Kl}from"node:fs/promises";import{basename as ht,dirname as Vl,join as fn,relative as Dn,resolve as Gn,sep as Xl}from"node:path";import{execFile as Yl,spawnSync as Zl}from"node:child_process";import dn from"ignore";import{createReadStream as Rl}from"node:fs";import{lstat as Nt,mkdtemp as Al,readFile as ts,readdir as Mn,rename as Ol,rm as Nl,writeFile as Ll}from"node:fs/promises";import{join as Ae}from"node:path";import wi from"ignore";function sn(O,N){if(Array.isArray(N))return N.some((L)=>sn(O,L));if(!N||O.split("/").some((L)=>L===".git"||L===".hlix"))return!1;return O===N||O.startsWith(`${N}/`)}function on(O,N){if(typeof N!=="string")return N?.some((L)=>on(O,L))??!1;return sn(O,N)||N.startsWith(`${O}/`)}function hi(O,N,L,F){let H=new Map,M=O.length,U=0;for(let J of O){let W=J.path.indexOf("/"),z=W<0?J.path:J.path.slice(0,W+1),Q=H.get(z)??{count:0,bytes:0,included:!1};Q.count++,Q.bytes+=J.size??0,Q.included||=sn(J.path,F),H.set(z,Q),U+=J.size??0}let G=U>L,D=[...H].sort(([J,W],[z,Q])=>Number(W.included)-Number(Q.included)||(G?Q.bytes-W.bytes:Q.count-W.count)||J.localeCompare(z)),B=[];for(let[J,W]of D){if(M<=N&&U<=L)break;B.push(J),M-=W.count,U-=W.bytes}return B}function Qr(O,N){return N.some((L)=>O===L||L.endsWith("/")&&O.startsWith(L))}function es(O){return`upload limit; add /${O} to .hlixignore, or try --include ${O.replace(/\/$/,"")}`.slice(0,200)}function yi(O){if(O.length<=5000)return O;return[...O.slice(0,4999),{path:O[4999].path,reason:`${O.length-4999} additional skipped paths (including this path); full list: hlix import --dry-run --json`}]}var ki="# --- managed by Hlix: safe to edit above/below, this block is regenerated ---",ns="# --- end managed by Hlix ---",Un=new Set(["agent-artifacts",".context",".claude/worktrees"]),Fl=/(?:^|\/)(?:Makefile|Dockerfile|Containerfile|Justfile|Rakefile|Gemfile)(?:\.[^/]*)?$/i,Hl=/\.(?:md|txt|json)$/i,vi=/(?:^|\n)\s*(?:\/\/|\/\*+|\*|#|<!--)\s*(?:@generated\b|generated by\b|do not edit\b)|(?:^|\n)\s*\/\/[#@]\s*sourceMappingURL=/i,bi=/\.(?:log(?:\.\d+)?|tmp|cache|pyc|tsbuildinfo|map)$/i;function an(O){let N=[...O.matchAll(new RegExp(`^${ki}\\r?$`,"gm"))],L=[...O.matchAll(new RegExp(`^${ns}\\r?$`,"gm"))];if(!N.length&&!L.length)return{before:O,after:"",managed:""};if(N.length!==1||L.length!==1||L[0].index<N[0].index)return null;let F=N[0].index,M=L[0].index+ns.length,U=O.slice(M).match(/^\r?\n/)?.[0]??"";return{before:O.slice(0,F),after:O.slice(M+U.length),managed:O.slice(F,M)}}function rs(O){let N=an(O);return(N?N.before+`
320
+ `+N.after:O).split(/\r?\n/).filter((L)=>L.startsWith("!")&&L.length>1).map((L)=>L.slice(1))}async function Si(O,N){let L=Ae(O,".hlixignore"),F="";try{let H=await Nt(L).catch((q)=>{if(q.code==="ENOENT")return null;throw q});if(H&&!H.isFile())return{warning:"Kept .hlixignore unchanged: managed rules require a regular file."};if(H)F=await ts(L,"utf8");let M=an(F);if(!M)return{warning:"Kept .hlixignore unchanged: repair its managed-block markers before refreshing."};let U=rs(F),G=wi().add(U),D=[],B=[],J=wi(),W=new Set;for(let q of N.tracked){let ne=q.split("/");while(ne.length)W.add(ne.join("/")),ne.pop()}let z=0,Q=0,te=()=>z<30000&&Q<268435456,V=(q)=>W.has(q)||on(q,N.includes)||U.some((ne)=>{let ue=ne.replace(/^\//,"").split(/[?*[\\]/)[0];return!ue||ue.startsWith(`${q}/`)||G.ignores(`${q}/`)||G.ignores(q)}),X=async(q,ne,ue=!1)=>{if(N.signal?.throwIfAborted(),!te()||V(q)||N.protectedPath(q,ne))return!1;z++;let he=await Nt(Ae(O,q));if(he.isSymbolicLink())return ne;if(he.isDirectory()){let we=(await Mn(Ae(O,q))).sort();for(let Ee of we){if(Ee===".git")continue;if(!await X(`${q}/${Ee}`,ne,ue))return!1}return!0}if(!he.isFile()||Q+he.size>268435456)return!1;let ye="",xe="";for await(let we of Rl(Ae(O,q),{encoding:"utf8",signal:N.signal})){if(Q+=Buffer.byteLength(we),ye.length<4096)ye+=we.slice(0,4096-ye.length);let Ee=xe+we;if(N.protectedContent(q,Ee))return!1;xe=Ee.slice(-4096)}return ne||vi.test(ye)||vi.test(xe)||!Fl.test(q)&&!/^#!|^<\?php/.test(ye)&&(ue&&Hl.test(q)||bi.test(q))},ee=new Set,Y=async(q,ne=[],ue=!1)=>{if(N.signal?.throwIfAborted(),!te())return;let he=Ae(O,q),ye=await Mn(he,{withFileTypes:!0}),xe=async(me)=>ye.find((ke)=>ke.name===me)?.isFile()&&(await Nt(Ae(he,me))).size<1048576?ts(Ae(he,me),"utf8"):null,we=await xe("package.json"),Ee=await xe("composer.json"),ve=!1,yt=new Set;try{let me=JSON.parse(await xe("composer.lock")??"null");ve=Array.isArray(me?.packages);for(let pe of[...me?.packages??[],...me?.["packages-dev"]??[]]){if(typeof pe.name==="string")yt.add(pe.name);if(pe.dist?.type==="path")ve=!1}}catch{}try{let me=JSON.parse(we??"{}"),pe=Array.isArray(me.workspaces)?me.workspaces:me.workspaces?.packages;for(let ke of Array.isArray(pe)?pe:[]){if(typeof ke!=="string"||ke.startsWith("!"))continue;let st=(q?`${q}/`:"")+ke.replace(/^\.\//,"");B.push(st),J.add(st)}}catch{}let wt=[we,Ee].filter(Boolean).join(`
321
+ `),Ve={};for(let me of ye){if(!/^(?:(?:vite|next|nuxt|astro|webpack|rollup)\.config\.[cm]?[jt]s|tsconfig(?:\.[^/]*)?\.json|turbo\.json|pyproject\.toml|setup\.py)$/.test(me.name))continue;let pe=await xe(me.name);if(pe!==null)Ve[me.name]=pe}let vt={packageJson:we,rootFiles:ye.map((me)=>me.name),configFiles:Ve};ue||=Zr(Ve);let wn=fi(vt);for(let me of Yr(vt))ee.add(q?`${q}/${me}`:me);let rt=new Set([...wn,...ne]);for(let me of ye.sort((pe,ke)=>pe.name<ke.name?-1:pe.name>ke.name?1:0)){if([".git",".hlix",".hlixignore"].includes(me.name)||me.isSymbolicLink())continue;let pe=q?`${q}/${me.name}`:me.name;if(/[\n\r\\*?[\]!#]/.test(pe)||pe.endsWith(" "))continue;if(z++,!te())return;if(me.isDirectory()){let ke=await Nt(Ae(O,pe,".git")).then(()=>N.isRepository(pe),()=>!1),st=Un.has(pe)||[...Un].some((Oe)=>pe.startsWith(`${Oe}/`)),vn=N.gitIgnored.directories.some((Oe)=>`${pe}/`.startsWith(Oe)),ot=J.ignores(`${pe}/`)||B.some((Oe)=>Oe.split(/[?*[\\]/)[0].startsWith(`${pe}/`))||wt.includes(me.name)||/(?:^|\/)(?:src|lib|apps|packages|tests|resources|public)(?:\/|$)/.test(pe),bt=ke&&(st||vn)&&!ot;if(me.name==="vendor"&&ve)for(let Oe of await Mn(Ae(O,pe),{withFileTypes:!0})){if(["autoload.php","composer","bin"].includes(Oe.name))continue;if(!Oe.isDirectory()){ve=!1;break}for(let Mt of await Mn(Ae(O,pe,Oe.name)))if(!yt.has(`${Oe.name}/${Mt}`))ve=!1}let Xe=wn.includes(me.name)&&(me.name==="node_modules"||me.name==="vendor"&&ve&&!/"type"\s*:\s*"path"/.test(Ee??"")),bn=ee.has(pe)||ue&&me.name.endsWith(".egg-info");if(((me.name==="node_modules"||me.name==="vendor"?Xe:rt.has(me.name))||Un.has(pe)&&!ot||["logs","runtime","tmp"].includes(me.name)||bt||bn)&&!V(pe)&&await X(pe,Xe||bt||bn,rt.has(me.name)||Un.has(pe))){D.push(`/${pe}/`);continue}if(!ke&&!["node_modules","vendor"].includes(me.name))await Y(pe,rt.has("__pycache__")?["__pycache__"]:[],ue)}else if(me.isFile()&&(bi.test(me.name)||(await Nt(Ae(O,pe))).size>N.maxFileBytes)&&!V(pe)&&await X(pe,!1))D.push(`/${pe}`)}};await Y("");let ie=F.includes(`\r
322
+ `)?`\r
323
+ `:`
324
+ `,le=[ki,...D.sort(),ns,""].join(ie),re=M.before+(M.before&&!M.before.endsWith(`
325
+ `)?ie:"")+le+M.after;if(N.write!==!1&&re!==F){let q=await Al(Ae(O,".hlixignore-"));try{let ne=Ae(q,"rules");await Ll(ne,re,{mode:H?.mode??420});let ue=await Nt(L).catch((he)=>{if(he.code==="ENOENT")return null;throw he});if(ue?!ue.isFile()||ue.ino!==H?.ino||ue.dev!==H?.dev||await ts(L,"utf8")!==F:H!==null)return{warning:"Kept .hlixignore unchanged: it changed while generated paths were being checked."};await Ol(ne,L)}finally{await Nl(q,{recursive:!0,force:!0})}}let K=D.every((q)=>q.endsWith("/"))?"generated folders":"generated paths";return{rules:D,report:`Hlix ignored ${D.length} ${K} — see .hlixignore`}}catch(H){return N.signal?.throwIfAborted(),{warning:`Kept .hlixignore unchanged: could not safely refresh generated paths (${H.code??"unreadable"}).`}}}import{readFile as Ul}from"node:fs/promises";import{join as Dl}from"node:path";function Ml(O){let N=O.trim();if(!N||/^[|>[{]/.test(N))return null;let L=N.match(/^(["'])([\s\S]*)\1$/);if(!L&&/^["']/.test(N))return null;return(L?L[2].trim():N.replace(/(?:^|\s)#.*$/,"").trim())||null}function ji(O){let N=O.split(/\r?\n/),L=N.findIndex((U)=>/^tasks:\s*(?:#.*)?$/.test(U));if(L===-1)return{tasks:[],partial:/^tasks:\s*\S/m.test(O)};let F=[],H=!1,M=-1;for(let U of N.slice(L+1)){if(!U.trim()||/^\s*#/.test(U))continue;let G=U.length-U.trimStart().length,D=U.match(/^(\s*-(?:\s+|$))(.*)$/);if(D){if(M!==-1&&G>=M)continue;if(F.push({}),M=D[2]?D[1].length:-1,!D[2])continue}else if(G===0)break;else if(F.length===0)continue;else if(M===-1)M=G;else if(G!==M)continue;let B=(D?D[2]:U.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!B)continue;let J=B[1];if(J!=="name"&&J!=="before"&&J!=="init"&&J!=="command")continue;let W=Ml(B[2]);if(W===null)H=!0;else F[F.length-1][J]=W}return{tasks:F,partial:H}}async function gt(O,N){try{return await Ul(Dl(O,...N.split("/")),"utf8")}catch(L){if(L.code==="ENOENT")return null;throw L}}function Ei(O){try{let N=O.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(N)}catch{return null}}function et(O){if(typeof O==="string"&&O.trim())return[O.trim()];if(Array.isArray(O))return O.flatMap(et);if(O&&typeof O==="object")return Object.values(O).flatMap(et);return[]}function ss(O){if(!O||typeof O!=="object")return[];return Object.keys(O).filter((N)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(N))}function Gl(O,N){let L=new Set,F=[/\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(N)F.push(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::[-?][^}]*)?\}/g);for(let H of F)for(let M of O.matchAll(H))L.add(M[1]);return[...L]}function Bl(O,N){if(O.has("bun.lock")||O.has("bun.lockb")||N?.startsWith("bun@"))return"bun install";if(O.has("pnpm-lock.yaml")||N?.startsWith("pnpm@"))return"pnpm install";if(O.has("yarn.lock")||N?.startsWith("yarn@"))return"yarn install";if(O.has("package.json"))return"npm install";return null}function xi(O){let N=typeof O==="number"?O:Number(O);return Number.isInteger(N)&&N>0&&N<=65535?N:null}function Le(O,N,L){if(!O.some((F)=>F.path===N&&F.kind===L))O.push({path:N,kind:L})}async function Pi(O,N,L){let F=[],H=[],M=[],U=[],G=new Map,D=new Set,B=new Set,J=[],W={},z=null,Q=0,te=await gt(O,".cursor/environment.json");if(te){Le(F,".cursor/environment.json","cursor");let re=Ei(te);if(!re)J.push("Could not parse .cursor/environment.json; it remains quarantined.");else{H.push(...et(re.install));let K=et(re.start);if(K[0])z=K[0];if(Array.isArray(re.terminals))for(let q of re.terminals){if(!q||typeof q!=="object")continue;let ne=q;if(typeof ne.command!=="string"||!ne.command.trim())continue;U.push({name:typeof ne.name==="string"&&ne.name.trim()?ne.name.trim():"Terminal",command:ne.command.trim(),...typeof ne.cwd==="string"&&ne.cwd.trim()?{cwd:ne.cwd.trim()}:{}})}}}let V=N.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":N.has("devcontainer.json")?"devcontainer.json":null;if(V){Le(F,V,"devcontainer");let re=Ei(L.get(V)??await gt(O,V)??"");if(!re)J.push(`Could not parse ${V}; it remains quarantined.`);else{H.push(...et(re.onCreateCommand),...et(re.updateContentCommand),...et(re.postCreateCommand));let K=et(re.postStartCommand);if(!z&&K[0])z=K[0];for(let q of ss(re.secrets))D.add(q);for(let q of[...ss(re.containerEnv),...ss(re.remoteEnv)])D.add(q);if(Array.isArray(re.forwardPorts))for(let q of re.forwardPorts){let ne=xi(q);if(ne)G.set(ne,{port:ne,visibility:"private"})}}}if(N.has(".gitpod.yml")){Le(F,".gitpod.yml","gitpod");let re=L.get(".gitpod.yml")??await gt(O,".gitpod.yml");if(re===null)J.push("Could not read .gitpod.yml; its task commands were not imported.");else{let K=ji(re);Q=K.tasks.filter((q)=>q.before).length;for(let q of K.tasks){if(q.before)H.push(q.before);if(q.init)H.push(q.init);if(!q.command)continue;if(!z)z=q.command;else U.push({name:q.name??"Terminal",command:q.command})}if(K.partial)J.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 re of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(N.has(re))Le(F,re,"docker");for(let re of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(N.has(re))Le(F,re,"buildpack");for(let re of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(N.has(re))Le(F,re,"platform");let X=L.get("package.json")??await gt(O,"package.json");if(X){Le(F,"package.json","package");try{let re=JSON.parse(X);if(re.engines?.node)W.node=re.engines.node;let K=Bl(N,re.packageManager);if(K&&H.length===Q)H.push(K);if(re.scripts?.build&&M.length===0)M.push(`${re.packageManager?.split("@")[0]??(N.has("bun.lock")?"bun":"npm")} run build`);let q=re.scripts?.dev?`${N.has("bun.lock")?"bun":"npm"} run dev`:null,ne=re.scripts?.start?`${N.has("bun.lock")?"bun":"npm"} run start`:q;if(!z&&ne)z=ne}catch{J.push("Could not parse package.json for environment discovery.")}}if(N.has("uv.lock"))H.push("uv sync --frozen");else if(N.has("poetry.lock"))H.push("poetry install --no-interaction");else if(N.has("requirements.txt"))H.push("python -m pip install -r requirements.txt");if(N.has("go.mod"))H.push("go mod download");if(N.has("Procfile")){Le(F,"Procfile","procfile");let K=(L.get("Procfile")??"").split(/\r?\n/).find((q)=>/^web\s*:/.test(q));if(K)z=K.replace(/^web\s*:\s*/,"").trim()||z}let ee=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[re,K]of ee){let q=(L.get(re)??await gt(O,re))?.trim();if(q)W[K]=q,Le(F,re,"tool-version")}let Y=L.get(".tool-versions")??await gt(O,".tool-versions");if(Y){Le(F,".tool-versions","tool-version");for(let re of Y.split(/\r?\n/)){let[K,q]=re.trim().split(/\s+/,2);if(!q)continue;if(K==="nodejs")W.node=q;else if(K==="python")W.python=q;else if(K==="bun")W.bun=q}}let ie=L.get("mise.toml")??await gt(O,"mise.toml");if(ie){Le(F,"mise.toml","tool-version");for(let re of ie.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))W[re[1]]=re[2]}for(let[re,K]of L){let q=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(re)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(re);for(let ne of Gl(K,q))B.add(ne);for(let ne of K.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let ue=xi(ne[1]);if(ue)G.set(ue,{port:ue,visibility:"private"})}}if(F.length===0&&N.size>0)Le(F,"repository","detected");let le=(re)=>[...new Set(re.filter(Boolean))],ge=F.length+H.length+(z?1:0);return{sources:F.sort((re,K)=>re.path.localeCompare(K.path)),toolchain:W,install:le(H),build:le(M),start:z,terminals:U,ports:[...G.values()].sort((re,K)=>re.port-K.port),requiredSecretKeys:[...D].sort(),observedSecretKeys:[...B].sort(),confidence:ge>=4?"high":ge>=2?"medium":"low",warnings:J}}var $i=2;var Mi=300000,Ql=25000,_i=52428800,ed=524288000,un=1e4,td="Potential secrets exist in Git history",nd="Never delete .git folders or files to get past this; use .hlixignore instead.",Bn=1048576,cn=20971520,Ui=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store"],bf=dn().add(Ui);var ls="Required project environment value was not found locally: ",rd=/(^|\/)\.env\.(example|sample|template)$/i,sd=/(^|\/)\.env(?:\.[^/]+)?$/i,od=/(^|\/)(?:\.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,id=/\.(?:example|sample|template)$/i,ad=/(^|\/)\.(?:npmrc|yarnrc(?:\.yml)?|pypirc)$/i,cd=/(?:^|\/)(?:__tests__|tests?|fixtures)\/|\.(?:test|spec)\.[^/]+$|\.snap$/i,ld=/\.(?:md|mdx|txt|rst)$/i,dd=/fake|dummy|example|placeholder|unused|changeme|xxxx|redacted|your[_-]|<[^>]*>/i,pd=/^(.)\1+$/,ud=/RegExp\(/,ds="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,}",md=new RegExp(ds,"g"),fd=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,gd=/(^|\/)(?:\.agents|\.claude)\/skills\//i,as=/-----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,}/,kf=new RegExp(as.source,"g"),Ci=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,Ii=/(?:^|[,{\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,ln=new Set(["HLIX_AGENT_RUN_ID","HLIX_API_KEY","HLIX_API_URL","HLIX_BASE_URL","HLIX_PROJECT_ID","HLIX_SESSION_TOKEN","HLIX_WORKSPACE_ID"]),os="Your hlix credentials were left out of the project's secrets — the platform provides them.",is=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]),hd=100,Ti=12;function yd(O){let N=O.slice(0,Ti).join(", "),L=O.length-Ti;return O.length===1?`Observed environment reference has no local value: ${O[0]}`:`${O.length} observed environment references have no local value: ${N}${L>0?`, +${L} more`:""}`}var wd=250;function tt(O){return O.split(Xl).join("/")}function Ke(O){if(O>=1048576)return`${(O/1048576).toFixed(1)} MB`;if(O>=1024)return`${(O/1024).toFixed(1)} KB`;return`${O} bytes`}function Ri(O,N=5){return[...O].sort((L,F)=>F.size-L.size||L.path.localeCompare(F.path)).slice(0,N).map((L)=>`${L.path} (${Ke(L.size)})`).join(", ")}function vd(O,N=5){let L=new Map;for(let F of O){let H=F.indexOf("/"),M=H===-1?".":F.slice(0,H);L.set(M,(L.get(M)??0)+1)}return[...L].sort((F,H)=>H[1]-F[1]||F[0].localeCompare(H[0])).slice(0,N).map(([F,H])=>`${F}/ (${H} files)`).join(", ")}function Fe(O,N,L=10485760){return Zl("git",["-C",O,...N],{encoding:"utf8",timeout:Mi,maxBuffer:L,stdio:["ignore","pipe","pipe"]})}function u(O,N,L={}){return new Promise((F)=>{Yl("git",["-C",O,...N],{encoding:"utf8",timeout:Mi,maxBuffer:L.maxBuffer??10485760,...L.signal?{signal:L.signal}:{}},(H,M)=>{let U=H?.code;F({status:H===null?0:typeof U==="number"?U:1,stdout:typeof M==="string"?M:""})})})}async function bd(O){let N=mn("sha256");for await(let L of Jl(O))N.update(L);return N.digest("hex")}function cs(O){if(Array.isArray(O))return`[${O.map(cs).join(",")}]`;if(O&&typeof O==="object")return`{${Object.entries(O).sort(([N],[L])=>N.localeCompare(L)).map(([N,L])=>`${JSON.stringify(N)}:${cs(L)}`).join(",")}}`;return JSON.stringify(O)}function Di(O){let N={};for(let[L,F]of String(O).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let H=F.trim();if(!H||H.startsWith("#"))continue;let U=(H.startsWith("export ")?H.slice(7).trimStart():H).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!U)throw Error(`Invalid dotenv assignment on line ${L+1}`);let G=U[2]??"";if(G.startsWith('"')){if(!G.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${L+1}`);G=G.slice(1,-1).replace(/\\n/g,`
326
+ `).replace(/\\r/g,"\r")}else if(G.startsWith("'")){if(!G.endsWith("'"))throw Error(`Unclosed dotenv quote on line ${L+1}`);G=G.slice(1,-1)}else G=G.replace(/\s+#.*$/,"").trimEnd();N[U[1]]=G}return N}function kd(O,N){return O.split(/(?<=\n)/).filter((L)=>{let F=L.trim(),M=(F.startsWith("export ")?F.slice(7).trimStart():F).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=/)?.[1];return M===void 0||!N.has(M)}).join("")}function Sd(O){let N=null;for(let L=0;L<O.length;L+=1){let F=O[L];if(F==="\\"&&N!=="single"){if(O[L+1]!=="$")return!0;L+=1;continue}if(F==="'"&&N!=="double"){N=N==="single"?null:"single";continue}if(F==='"'&&N!=="single"){N=N==="double"?null:"double";continue}if(N!=="single"&&(F==="$"||F==="`"))return!0;if(N===null&&(F==="<"||F===">")&&O[L+1]==="(")return!0}return N!==null}function jd(O){let N={},L=new Set,F=new Set;for(let H of String(O).replace(/^\uFEFF/,"").split(/\r?\n/)){let M=H.trim();if(!M||M.startsWith("#"))continue;let G=(M.startsWith("export ")?M.slice(7).trimStart():M).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!G)continue;let D=G[1],B=G[2]??"";if(L.add(D),Sd(B)){delete N[D],F.add(D);continue}try{let W=Di(`${D}=${B}`)[D];if(W===void 0)throw Error("missing literal");N[D]=B.trimStart().startsWith("'")?W:W.replace(/\\\$/g,"$"),F.delete(D)}catch{delete N[D],F.add(D)}}return{values:N,keys:[...L].sort(),dynamicKeys:[...F].sort()}}async function Ed(O){let N=Fe(O,["rev-parse","--show-toplevel"]);if(N.status!==0)return!1;try{return await Fi(N.stdout.trim())===O}catch{return!1}}function xd(O,N){if(!N)return new Set;let L=Fe(O,["ls-files","-z"]);if(L.status!==0)throw Error("Could not enumerate tracked files.");return new Set(L.stdout.split("\x00").filter(Boolean).map(tt))}function Pd(O,N){if(!N)return[];let L=Fe(O,["config","--get-regexp","^remote\\..*\\.url$"]);if(L.status!==0)return[];let F=[];for(let H of L.stdout.split(`
327
+ `)){let M=H.trim();if(!M)continue;let U=/^remote\.(.*)\.url (.+)$/.exec(M);if(U)F.push({name:U[1],url:U[2]})}return F}function $d(O,N){if(!N)return{files:new Set,directories:[]};let L=Fe(O,["ls-files","-z","--others","--ignored","--exclude-standard","--directory"]);if(L.status!==0)throw Error("Could not enumerate ignored files.");let F=new Set,H=[];for(let M of L.stdout.split("\x00").filter(Boolean)){let U=tt(M);if(U.endsWith("/"))H.push(U);else F.add(U)}return{files:F,directories:H}}async function Ai(O,N){let L=[],F=[],H=[],M="";for(let B of[".gitignore",".hlixignore"])try{let J=fn(O,B),W=await Li(J);if(B===".gitignore"&&W.isSymbolicLink()){F.push(B);continue}if(W.isFile()||W.isSymbolicLink())try{if(W.isSymbolicLink()&&!(await Hi(J)).isFile()){L.push(B);continue}let z=await pn(J,"utf8");if(B===".hlixignore")M=z;let Q=B===".hlixignore"?an(z):null;if(N&&Q?.managed)z=z.replace(Q.managed,N.join(`
328
+ `));H.push(z)}catch{L.push(B)}}catch(J){if(J.code!=="ENOENT")L.push(B)}let U=an(M)?.managed??"",G=U?[".git/",".hlix/"]:Ui,D=rs(M);return{hardMatcher:dn().add(D.length?[".git/",".hlix/"]:G),matcher:dn().add([...G,...H.flatMap((B)=>B.split(/\r?\n/))]),unignored:dn().add(D),managedMatcher:dn().add(N??U),hasManaged:Boolean(U),unreadable:L,symlinked:F}}function Jn(O){if(fd.test(O))return"mcp";if(gd.test(O))return"skill";return null}function Wn(O){if(sd.test(O)&&!rd.test(O))return"dotenv";if(od.test(O))return"credential";return null}function _d(O,N){if(N)return[tt(N)];let L=new Map([[".env",0],[".env.development",1],[".env.local",2],[".env.development.local",3]]),F=O.filter((H)=>L.has(ht(H).toLocaleLowerCase("en-US"))).sort((H,M)=>H.slice(0,-ht(H).length).localeCompare(M.slice(0,-ht(M).length))||L.get(ht(H).toLocaleLowerCase("en-US"))-L.get(ht(M).toLocaleLowerCase("en-US")));return F.length>0?F:O.length===1?[...O]:[]}function Cd(O,N){try{let L=JSON.parse(N);if(!L.mcpServers||typeof L.mcpServers!=="object")return[];return Object.entries(L.mcpServers).map(([F,H])=>{let M=H&&typeof H==="object"?H:{},U=M.type==="http"||M.type==="sse"||M.type==="stdio"?M.type:typeof M.command==="string"?"stdio":typeof M.url==="string"?"http":"unknown",G=M.env&&typeof M.env==="object"?M.env:{};return{sourcePath:O,name:F,transport:U,...typeof M.command==="string"?{command:M.command}:{},...Array.isArray(M.args)&&M.args.every((D)=>typeof D==="string")?{args:M.args}:{},...typeof M.url==="string"?{url:M.url}:{},envKeys:Object.keys(G).sort(),enabled:!1}})}catch{return[]}}function Id(O){let N=!1,L=!1;for(let F of O.split(/\r?\n/)){let H=F.trim();if(!H||H.startsWith("#")||H.startsWith(";")||H.startsWith("["))continue;let M=H.indexOf("=");if(M===-1)continue;let U=H.slice(0,M).trim().toLowerCase(),G=H.slice(M+1).trim().replace(/^["']|["']$/g,"");if(!G||/^\$(?:\{[^}]*\}|[A-Za-z_][A-Za-z0-9_]*)$/.test(G))continue;if(U.endsWith("_authtoken")||U.endsWith("_password"))return!0;if(U.endsWith("password"))L=!0;else if(U.endsWith("username"))N=!0}return N&&L}async function Td(O,N,L,F){if(id.test(L))return!1;if(!ad.test(L))return!0;let H=await u(O,["show",`${N}:${L}`],{...F?{signal:F}:{}});return H.status===0&&Id(H.stdout)}function Rd(O,N,L){let F=O.lastIndexOf("/",N),H=O.indexOf("/",L);return F!==-1&&H!==-1&&!/\s/.test(O.slice(F,N)+O.slice(L,H))}function Ad(O){if(cd.test(O))return"test fixture";if(ld.test(O))return"documentation or pattern definition";return null}function Od(O,N){let L=null;for(let F of O.split(/\r?\n/))for(let H of F.matchAll(N)){let M=H[0],U=H.index??0,G=ud.test(F)||Rd(F,U,U+M.length)?"documentation or pattern definition":dd.test(M)||pd.test(M)?"placeholder value":null;if(G===null)return null;L??=G}return L}async function Nd(O,N,L,F){let H=Ad(L);if(H!==null)return H;let M=await u(O,["show",`${N}:${L}`],{...F?{signal:F}:{}});return M.status===0?Od(M.stdout,md):null}async function Oi(O,N,L){let F=[],H="unknown";for(let M of O.split(/\r?\n/)){if(M.startsWith("@@"))H=M.slice(2);else if(M.trim()){let U=tt(M.trim());if(await L(H,U))F.push({commit:H,path:U,reason:N})}if(F.length>=100)break}return F}async function Ni(O,N,L={}){if(!N)return{head:null,branch:null,refs:[],commitCount:0,complete:!0,findings:[],blockingFindings:[],waivedReasons:[]};let F=Fe(O,["rev-parse","HEAD"]).stdout.trim()||null,H=Fe(O,["symbolic-ref","--short","-q","HEAD"]),M=H.status===0?H.stdout.trim()||null:null,U=Number.parseInt(Fe(O,["rev-list","--count","--all"]).stdout.trim(),10)||0,G=Fe(O,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]),D=G.stdout.split(`
329
+ `).filter(Boolean).map((ee)=>{let[Y,ie]=ee.split("\x00");return{name:Y,oid:ie}}).filter(({name:ee,oid:Y})=>/^refs\/(?:heads|tags)\/.+/.test(ee)&&/^[0-9a-f]{40,64}$/.test(Y)).sort((ee,Y)=>ee.name.localeCompare(Y.name)),B=L.signal,J=B?{signal:B}:{};L.onProgress?.(`history: ${U} commit${U===1?"":"s"}…`);let W=["log","--all",`--max-count=${un}`,"--pretty=format:@@%H","--name-only"],z=await u(O,[...W,"--",".env",".env.*","*.pem","*.key",".npmrc","*.tfvars"],J),Q=await u(O,["log","--all",`--max-count=${un}`,"-G",ds,"--pretty=format:@@%H","--name-only"],J);B?.throwIfAborted();let te=new Map;for(let ee of[...await Oi(z.stdout,"sensitive-path",(Y,ie)=>Td(O,Y,ie,B)),...await Oi(Q.stdout,"secret-pattern",async()=>!0)])te.set(`${ee.commit}:${ee.path}:${ee.reason}`,ee);let V=[...te.values()].slice(0,100),X=new Map;for(let ee of V){if(ee.reason!=="secret-pattern")continue;let Y=await Nd(O,ee.commit,ee.path,B);if(Y!==null)X.set(ee,Y)}return L.onProgress?.(`history: ${U} commit${U===1?"":"s"} scanned`),{head:F,branch:M,refs:D,commitCount:U,complete:U<=un&&D.length<=1000&&G.status===0&&z.status===0&&Q.status===0,findings:V,blockingFindings:V.filter((ee)=>!X.has(ee)),waivedReasons:[...X.values()]}}function Ld(O,N){let L=N?.XDG_CACHE_HOME??(N?.HOME?fn(N.HOME,".cache"):null);if(!L)return null;return fn(L,"hlix","history",`${mn("sha256").update(O).digest("hex")}.json`)}async function Fd(O,N,L){let F=N?Ld(O,L.environment):null;if(!F)return Ni(O,N,L);let H=mn("sha256").update([Fe(O,["for-each-ref","--format=%(refname)%00%(objectname)"]).stdout,Fe(O,["rev-parse","HEAD"]).stdout,Fe(O,["symbolic-ref","--short","-q","HEAD"]).stdout,ds,String(un)].join("\x00")).digest("hex");try{let U=JSON.parse(await pn(F,"utf8"));if(U.key===H&&U.history)return L.onProgress?.(`history: ${U.history.commitCount} commits, unchanged since the last scan`),U.history}catch{}let M=await Ni(O,N,L);if(M.complete)try{await Wl(Vl(F),{recursive:!0,mode:448}),await Kl(F,JSON.stringify({key:H,history:M}),{mode:384})}catch{}return M}async function Be(O,N={}){let L=await Fi(Gn(O));if(!(await Hi(L)).isDirectory())throw Error("Import target must be a directory.");let F=await Ed(L),H=Pd(L,F),M=xd(L,F),U=new Set(F?(await u(L,["ls-files","--stage","-z"])).stdout.split("\x00").filter((Z)=>Z.startsWith("160000 ")).map((Z)=>Z.slice(Z.indexOf("\t")+1)):[]),G=$d(L,F),D=[...new Set([...i(L)?.includedPaths??[],...N.include?[N.include]:[]].map((Z)=>Z.replace(/^\.\//,"").replace(/\/$/,"")))],B=await Ai(L),J=N.refreshIgnore||B.hasManaged?await Si(L,{write:N.refreshIgnore===!0,tracked:F?M:new Set((await u(L,["ls-files","-z"])).stdout.split("\x00").filter(Boolean)),includes:D,gitIgnored:G,signal:N.signal,maxFileBytes:N.maxFileBytes??_i,isRepository:async(Z)=>{let ce=await u(fn(L,Z),["rev-parse","--show-toplevel"]);return ce.status===0&&Gn(ce.stdout.trim())===Gn(L,Z)},protectedPath:(Z,ce)=>Boolean(Wn(Z)||!ce&&Jn(Z)),protectedContent:(Z,ce)=>as.test(ce)||Ci.test(Z)&&Ii.test(ce)}):void 0,{hardMatcher:W,matcher:z,unignored:Q,managedMatcher:te,unreadable:V,symlinked:X}=J?await Ai(L,J.rules??[]):B,ee=V.length?`Upload left unchanged: cannot read ${V.join(", ")}; check the ignore file target and permissions before retrying.`:void 0,Y=[],ie=[],le=[],ge=[],re=[],K=[],q=[],ne=[],ue=N.envFile?tt(Dn(L,Gn(L,N.envFile))):void 0,he=ue!==void 0&&ue!==""&&ue!==".."&&!ue.startsWith("../");if(N.envFile&&!he)ne.push(`Selected environment file must stay inside the project: ${N.envFile}`);let ye=new Map,xe=new Map,we=new Map,Ee=new Map,ve=J?.warning?[J.warning]:[],yt=new Set,wt=[],Ve=[],vt=new Map,wn=N.maxFiles??Ql,rt=N.maxFileBytes??_i,me=N.maxTotalBytes??ed,pe=N.historyMode==="sanitize",ke=0,st=0,vn=async(Z,ce=!1)=>{let Se=await ql(Z,{withFileTypes:!0}).catch((_e)=>{let Ie=tt(Dn(L,Z))||"repository";if(q.push({path:Ie,reason:`Cannot read folder (${_e.code??"unreadable"}); check read and search permissions`}),ve.push(`Cannot read folder ${Ie}; check its read and search permissions. Existing cloud files are preserved.`),Z===L)ee="Upload left unchanged: cannot read the project folder; check its permissions.";return[]});Se.sort((_e,Ie)=>_e.name.localeCompare(Ie.name));for(let _e of Se){if(N.signal?.throwIfAborted(),st+=1,st%wd===0)N.onProgress?.(`scanning … ${Y.length} files`);let Ie=fn(Z,_e.name),de=tt(Dn(L,Ie));if(_e.name===".git"){if(de!==".git"&&!ce)yt.add(tt(Dn(L,Z)));continue}if(de.length>1000||de.includes("\\")||de.includes("\x00")){ve.push(`Skipped a path that cannot be represented safely: ${de.slice(0,350)}`);continue}try{let $e=await Li(Ie),Ut=_e.isDirectory()?`${de}/`:de,Vs=M.has(de)&&!U.has(de),Dt=!(sn(de,D)||Q.ignores(Ut))&&!Vs&&(z.ignores(Ut)||G.files.has(de)||G.directories.some((be)=>Ut.startsWith(be))),Xs=!on(de,D)&&W.ignores(Ut);if(Xs){if(de!==".hlix")q.push({path:de,reason:"built-in ignore"});continue}if(Dt&&te.ignores(Ut))q.push({path:de,reason:"Hlix-managed ignore"});if($e.isSymbolicLink()){if(Dt)continue;if(ie.push({path:de,target:await zl(Ie)}),Jn(de)||Wn(de))le.push(de);continue}if(_e.isDirectory()){if(Xs)continue;if(U.has(de)&&!Dt)yt.add(de);await vn(Ie,Dt);continue}let kt=Jn(de),St=Wn(de);if(Dt&&!kt&&!St)continue;if(!_e.isFile()){q.push({path:de,reason:"non-regular-file"});continue}if($e.size>rt&&!kt&&!St){q.push({path:de,reason:es(de)});continue}if($e.size>rt){ne.push(`File ${de} is ${Ke($e.size)}, over the ${Ke(rt)} per-file limit. Exclude it with .hlixignore.`);continue}let Gt=await bd(Ie);if(kt){if($e.size>Bn){ne.push(`Protected configuration ${de} is ${Ke($e.size)}, over the ${Ke(Bn)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let be=await pn(Ie);if(ke+=be.byteLength,Ve.push({path:de,size:be.byteLength}),ke>cn)continue;if(re.push({path:de,kind:kt,size:$e.size,sha256:Gt}),wt.push({path:de,kind:kt,contentBase64:be.toString("base64")}),kt==="mcp")K.push(...Cd(de,be.toString("utf8")));continue}if(St){if($e.size>Bn){ne.push(`Protected file ${de} is ${Ke($e.size)}, over the ${Ke(Bn)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let be=await pn(Ie);if(ke+=be.byteLength,Ve.push({path:de,size:be.byteLength}),ke>cn)continue;let it=[],jt=new Set;if(St==="dotenv")try{let Sn=Di(be),Et={};for(let[Ye,xt]of Object.entries(Sn)){if(ln.has(Ye)){jt.add(Ye);continue}Et[Ye]=xt}ye.set(de,Et),it=Object.keys(Et).sort()}catch{ne.push(`Could not parse environment file: ${de}`)}else if(ht(de)===".envrc"){let Sn=jd(be),Et={},Ye=new Set,xt=[];for(let[Te,wa]of Object.entries(Sn.values)){if(ln.has(Te)){jt.add(Te);continue}if(is.has(Te)){ve.push(`Ignored ambient runtime assignment in ${de}: ${Te}`);continue}Ye.add(Te),Et[Te]=wa}xe.set(de,Et);for(let Te of Sn.dynamicKeys){if(ln.has(Te)){jt.add(Te);continue}if(is.has(Te)){ve.push(`Ignored ambient runtime assignment in ${de}: ${Te}`);continue}Ye.add(Te),xt.push(Te)}if(we.set(de,[...Ye].sort()),Ee.set(de,xt.sort()),it=[...Ye].sort(),xt.length>0)ve.push(`Did not execute dynamic .envrc assignments; collect their resolved local values when available: ${xt.join(", ")}`)}if(jt.size>0)ve.push(os),be=Buffer.from(kd(be.toString("utf8"),jt),"utf8"),Gt=mn("sha256").update(be).digest("hex");ge.push({path:de,kind:St,keys:it,size:be.byteLength,sha256:Gt}),wt.push({path:de,kind:St,contentBase64:be.toString("base64")});continue}if($e.size<=1048576){let be=await pn(Ie),it=be.toString("utf8");if(vt.set(de,it),as.test(it)||Ci.test(de)&&Ii.test(it)){if(ke+=be.byteLength,Ve.push({path:de,size:be.byteLength}),ke>cn)continue;ge.push({path:de,kind:"detected-content",keys:[],size:$e.size,sha256:Gt}),wt.push({path:de,kind:"detected-content",contentBase64:be.toString("base64")});continue}}Y.push({path:de,size:$e.size,sha256:Gt,tracked:Vs,executable:($e.mode&73)!==0})}catch($e){if(N.signal?.throwIfAborted(),Wn(de)||Jn(de))throw $e;q.push({path:de,reason:`Cannot read file (${$e.code??"unreadable"})`})}}};await vn(L);let ot=hi([...Y,...ie],Math.max(0,wn-ge.length-re.length),me,D);if(ot.length)Y=Y.filter((Z)=>!Qr(Z.path,ot)),ie=ie.filter((Z)=>!Qr(Z.path,ot)),q.push(...ot.map((Z)=>({path:Z.replace(/\/$/,""),reason:es(Z)})));if(N.onProgress?.(`scanning … ${Y.length} files`),N.onProgress?.(`secrets: ${ge.length+re.length} files`),N.signal?.throwIfAborted(),le.length>0){let Z=le.slice(0,5).join(", "),ce=le.length-5;ve.push(`Imported as symlinks, so no content was read or uploaded for them and the cloud recreates the link: ${Z}${ce>0?`, +${ce} more`:""}`)}for(let Z of X)ve.push(`Ignore file ${Z} is a symlink, so its rules were not applied. Replace it with a regular file inside the project.`);if(ee)ve.push(ee);if(ke>cn)ne.push(`Protected project files total ${Ke(ke)}, over the ${Ke(cn)} limit. Largest: ${Ri(Ve)}. Move large assets out of skill and config folders, or add them to .hlixignore.`);if(ge.length>2000)ne.push(`Project has ${ge.length} environment and credential files, over the 2000 limit. Largest: ${Ri(ge)}. Exclude the ones the cloud project does not need with .hlixignore.`);if(re.length>5000)ne.push(`Project has ${re.length} agent, skill and MCP files, over the 5000 limit. Largest folders: ${vd(re.map((Z)=>Z.path))}. Exclude the ones the cloud project does not need with .hlixignore.`);Y.sort((Z,ce)=>Z.path.localeCompare(ce.path)),ie.sort((Z,ce)=>Z.path.localeCompare(ce.path)),ge.sort((Z,ce)=>Z.path.localeCompare(ce.path)),re.sort((Z,ce)=>Z.path.localeCompare(ce.path)),K.sort((Z,ce)=>`${Z.sourcePath}:${Z.name}`.localeCompare(`${ce.sourcePath}:${ce.name}`));let bt=_d([...ye.keys()].sort(),he?ue:void 0);if(N.envFile&&he&&!ye.has(bt[0]))ne.push(`Selected environment file was not found or is not a dotenv file: ${N.envFile}`);let Xe=new Map;for(let[Z,ce]of ye)for(let Se of Object.keys(ce))Xe.set(Se,[...Xe.get(Se)??[],Z]);for(let[Z,ce]of we)for(let Se of ce)Xe.set(Se,[...Xe.get(Se)??[],Z]);let bn=[...Xe].filter(([,Z])=>Z.length>1).map(([Z,ce])=>({key:Z,paths:ce.sort()})).sort((Z,ce)=>Z.key.localeCompare(ce.key)),Me={};for(let Z of bt)Object.assign(Me,ye.get(Z)??{});let Oe=[...xe.keys()].sort((Z,ce)=>{if(Z===".envrc")return 1;if(ce===".envrc")return-1;return Z.localeCompare(ce)}),Mt=new Set;for(let Z of Oe){let ce=new Set(Ee.get(Z)??[]);for(let Se of we.get(Z)??[]){if(ce.has(Se)){delete Me[Se],Mt.add(Se);continue}let _e=xe.get(Z)?.[Se];if(_e!==void 0)Me[Se]=_e;Mt.delete(Se)}}for(let Z of yt)ve.push(`${Z} has its own Git repository — uploaded as files, its history not included`);let fa=N.historyMode==="abort_on_findings"?"abort_on_findings":"preserve";if(pe)ve.push("Git history omitted; uploading a snapshot of the current files.");let Ne=await Fd(L,F,N);if(!Ne.complete)ve.push(`Git history scan exceeded ${un} commits or failed; history is preserved, but the findings may be incomplete.`);if(F&&!Ne.head)pe=!0,ve.push("Git has no readable HEAD; uploading the current files as a snapshot.");let Js=Ne.waivedReasons;for(let Z of[...new Set(Js)].sort()){let ce=Js.filter((_e)=>_e===Z).length,Se=ce===1;ve.push(`${ce} Git history finding${Se?"":"s"} did not block this import — ${Z}, not ${Se?"a real credential":"real credentials"}; --history preserve is not needed for ${Se?"it":"them"}.`)}if(Ne.blockingFindings.length>0){let Z=Ne.blockingFindings.length;ve.unshift([`${td} (${Z} finding${Z===1?"":"s"}${Z>5?", first 5 shown":""}); ${pe?"history is omitted":"history is preserved"}:`,...Ne.blockingFindings.slice(0,5).map((ce)=>` ${ce.commit.slice(0,7)} ${ce.path} — ${ce.reason}`)," To exclude old commits, use --history sanitize; local Git history stays intact."].join(`
330
+ `))}let Ws=new Set(Y.map((Z)=>Z.path)),ga=await Pi(L,Ws,vt),{observedSecretKeys:ha,...Ue}=ga;Ue.warnings.unshift(...ve);let kn=new Set(Ue.requiredSecretKeys);for(let Z of Mt)kn.add(Z);for(let Z of K)for(let ce of Z.envKeys)kn.add(ce);for(let Z of ln)if(kn.delete(Z))Ue.warnings.push(os);Ue.requiredSecretKeys=[...kn].sort();for(let Z of Ue.requiredSecretKeys){if(Me[Z]!==void 0)continue;let ce=N.environment?.[Z];if(ce===void 0){ne.push(`${ls}${Z}`);continue}Me[Z]=ce}let Zn=[];for(let Z of ha){if(ln.has(Z)){Ue.warnings.push(os);continue}if(is.has(Z))continue;if(Me[Z]!==void 0)continue;let ce=N.environment?.[Z];if(ce===void 0){Zn.push(Z);continue}Me[Z]=ce}if(Zn.length>0)Ue.warnings.push(yd(Zn.sort()));Ue.warnings=[...new Set(Ue.warnings.flatMap((Z)=>Z.split(`
331
+ `)))].map((Z)=>Z.slice(0,500)).slice(0,hd);let qs=gi(new Map([...Ws].map((Z)=>[Z,vt.get(Z)??null]))),zs={schemaVersion:$i,rootName:N.rootName??ht(L),stack:qs.language,git:{detected:F&&!pe,head:pe?null:Ne.head,branch:pe?null:Ne.branch,refs:pe?[]:Ne.refs,commitCount:pe?0:Ne.commitCount,historyScanComplete:Ne.complete,historyMode:fa},files:Y,symlinks:ie,secretFiles:ge,activeEnvFiles:bt,secretKeys:Object.keys(Me).sort(),envCollisions:bn,quarantinedResources:re,mcpServers:K,historicalSecretFindings:Ne.blockingFindings,skipped:yi(q),environment:Ue,totals:{files:Y.length,bytes:Y.reduce((Z,ce)=>Z+ce.size,0)}},Ks=cs(zs),ya=mn("sha256").update(Ks).digest("hex");return{root:L,includedPaths:D,ignoreReport:N.refreshIgnore?J?.report??J?.warning:void 0,uploadWarning:ee,stackFacts:qs,manifest:zs,...q.length>5000?{skippedEntries:q}:{},manifestJson:Ks,manifestSha256:ya,secretValues:Me,protectedFiles:wt.sort((Z,ce)=>Z.path.localeCompare(ce.path)),blocking:[...new Set(ne)].map((Z)=>`${Z}
332
+ ${nd}`),blockingHistoryFindings:[],gitRemotes:H}}var ps={name:"init",summary:"Configure a local folder for Hlix",usage:["Usage: hlix init [folder] [--project <id>] [--json]","","Creates .hlix/config.json, .hlix/.gitignore, and .hlixignore.","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(`
333
+ `),supportsJson:!0,options:["project"],args:{min:0,max:1},async run(O){if(O.args.length>1)throw Error("init accepts at most one folder.");let N=await Hd(Md(O.cwd,O.args[0]??".")),L=r({env:O.env,flags:O.flags,cwd:N});if(L.conflict)throw new e("workspace_mismatch",L.conflict);if(!L.workspaceId)throw Error("No workspace selected. Run `hlix auth login --workspace <id>` first.");let F=O.requireClient(N);await F.projects.list();let H=Pt(N),M=typeof O.flags.project==="string"?O.flags.project:void 0;if(M&&H?.projectId&&H.projectId!==M)throw new e("workspace_mismatch",`This folder is bound to project ${H.projectId}; refusing to rebind it to ${M}.`);if(M)await F.projects.get(M);let U={...H??{schemaVersion:1,workspaceId:L.workspaceId,apiUrl:L.baseUrl},...M?{projectId:M}:{}};Pn(N,U);let G=await Be(N,{environment:O.env,refreshIgnore:!0}),D={root:N,config:U,ignoreReport:G.ignoreReport,scan:{files:G.manifest.totals.files,bytes:G.manifest.totals.bytes,secretFiles:G.manifest.secretFiles.map((B)=>B.path),quarantinedResources:G.manifest.quarantinedResources.map((B)=>B.path),blocking:G.blocking}};if(O.json)O.stdout(oe(ae(ps.name,D)));else{if(G.ignoreReport)O.stdout(`${G.ignoreReport}
334
+ `);if(O.stdout(`Initialized ${N}
335
+ Project: ${U.projectId??"not imported yet"}
336
+ Workspace: ${U.workspaceId}
337
+ `),G.blocking.length)O.stdout(`
338
+ Review before import:
339
+ ${G.blocking.map((B)=>`- ${B}`).join(`
340
+ `)}
341
+ `)}return 0}};import{basename as yp,resolve as wp}from"node:path";import{realpath as vp}from"node:fs/promises";import{mkdtemp as cp,rm as Kn,readFile as lp,writeFile as dp,chmod as pp,symlink as up,lstat as mp}from"node:fs/promises";import{tmpdir as fp}from"node:os";import{join as fs}from"node:path";import{createHash as Ud}from"node:crypto";import{createReadStream as Dd}from"node:fs";import{chmod as Gi,copyFile as Gd,lstat as Bd,mkdir as us,mkdtemp as Jd,readdir as Wd,readlink as qd,rm as ms,symlink as zd}from"node:fs/promises";import{tmpdir as Kd}from"node:os";import{dirname as Bi,join as nt}from"node:path";import{spawnSync as qn}from"node:child_process";var zn=300000;function He(O,N){let L=qn("git",["-c","core.hooksPath=/dev/null","-C",O,...N],{encoding:"utf8",timeout:zn,maxBuffer:20971520,stdio:["ignore","pipe","pipe"]});if(L.status!==0){let F=L.stderr.trim().split(`
342
+ `).at(-1)??"git command failed";throw Error(F)}return L.stdout.trim()}async function Vd(O){let N=Ud("sha256");for await(let L of Dd(O))N.update(L);return N.digest("hex")}async function Xd(O){for(let N of await Wd(O)){if(N===".git")continue;await ms(nt(O,N),{recursive:!0,force:!0})}}async function Ji(O){if(O.manifest.git.detected&&(O.manifest.historicalSecretFindings.length||!O.manifest.git.historyScanComplete))throw Error("Git history has secrets or could not be fully scanned. Use --history sanitize to import current files.");if(O.uploadWarning)throw Error(O.uploadWarning);if(O.blocking.length>0)throw Error(`Project scan has blocking findings:
343
+ - ${O.blocking.join(`
344
+ - `)}`);let N=await Jd(nt(Kd(),"hlix-snapshot-"));await Gi(N,448);let L=nt(N,"repo"),F=nt(N,"source.git");try{if(O.manifest.git.detected){let G=qn("git",["clone","--mirror","--no-hardlinks",O.root,F],{encoding:"utf8",timeout:zn,stdio:["ignore","pipe","pipe"]});if(G.status!==0)throw Error(G.stderr.trim()||"Could not mirror repository.");let D=new Map(He(F,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]).split(`
345
+ `).filter(Boolean).map((J)=>J.split("\x00",2)));for(let J of O.manifest.git.refs)if(D.get(J.name)!==J.oid)throw Error(`Git ref changed after scan: ${J.name}`);let B=qn("git",["clone","--no-hardlinks",F,L],{encoding:"utf8",timeout:zn,stdio:["ignore","pipe","pipe"]});if(B.status!==0)throw Error(B.stderr.trim()||"Could not create snapshot clone.");if(!O.manifest.git.head)throw Error("Git repository has no HEAD commit.");He(L,["checkout","-B","main",O.manifest.git.head])}else await us(L,{recursive:!0,mode:448}),He(L,["init","-b","main"]);await Xd(L);for(let G of O.manifest.files){let D=nt(O.root,...G.path.split("/")),B=await Bd(D);if(!B.isFile()||B.isSymbolicLink())throw Error(`Source changed after scan: ${G.path}`);if(B.size!==G.size||await Vd(D)!==G.sha256)throw Error(`Source changed after scan: ${G.path}`);let J=nt(L,...G.path.split("/"));await us(Bi(J),{recursive:!0,mode:493}),await Gd(D,J),await Gi(J,G.executable?493:420)}for(let G of O.manifest.symlinks){let D=nt(O.root,...G.path.split("/"));if(await qd(D).catch(()=>null)!==G.target)throw Error(`Source changed after scan: ${G.path}`);let B=nt(L,...G.path.split("/"));await us(Bi(B),{recursive:!0,mode:493}),await zd(G.target,B)}He(L,["config","user.name","Hlix Import"]),He(L,["config","user.email","import@hlix.ai"]),He(L,["read-tree","--empty"]),He(L,["add","--force","-A"]),He(L,["commit","--allow-empty","-m","chore(hlix): import snapshot"]);let H=He(L,["rev-parse","HEAD"]),M=new Set(O.manifest.git.refs.map((G)=>G.name));for(let G of He(L,["for-each-ref","--format=%(refname)","refs/heads","refs/tags"]).split(`
346
+ `).filter(Boolean))if(G!=="refs/heads/main"&&!M.has(G))He(L,["update-ref","-d",G]);let U=O.manifest.git.refs.filter((G)=>G.name!=="refs/heads/main");if(U.length>0){let G=qn("git",["-C",L,"update-ref","--stdin"],{encoding:"utf8",timeout:zn,input:U.map((D)=>`update ${D.name} ${D.oid}`).join(`
347
+ `)+`
348
+ `,stdio:["pipe","pipe","pipe"]});if(G.status!==0)throw Error(G.stderr.trim()||"Could not recreate the approved Git refs.")}return{directory:L,commitSha:H,dispose:()=>ms(N,{recursive:!0,force:!0})}}catch(H){throw await ms(N,{recursive:!0,force:!0}),H}}import{lstat as qi,mkdir as Yd,realpath as Zd}from"node:fs/promises";import{dirname as Qd,join as ep,relative as tp,resolve as np,sep as Wi}from"node:path";function zi(O,N){let L=O;if(typeof L==="string")try{L=JSON.parse(L)}catch{return[]}if(!L||typeof L!=="object")return[];let F=L[N];if(!Array.isArray(F))return[];return F.filter((H)=>!!H&&typeof H==="object")}function Ki(O){return zi(O,"files").flatMap((N)=>typeof N.path==="string"&&typeof N.sha256==="string"?[{path:N.path,sha256:N.sha256}]:[])}function Vi(O){return zi(O,"symlinks").flatMap((N)=>typeof N.path==="string"&&typeof N.target==="string"?[{path:N.path,target:N.target}]:[])}async function gn(O,N,L){let F=await Zd(O),H=np(F,...N.split("/"));if(H!==F&&!H.startsWith(F+Wi))throw Error(`Protected path escapes the project: ${N}`);let M=tp(F,Qd(H)),U=F;for(let G of M.split(Wi).filter(Boolean)){U=ep(U,G);try{let D=await qi(U);if(D.isSymbolicLink()&&L){L.push(U);break}if(!D.isDirectory()||D.isSymbolicLink())throw Error(`Protected path crosses a non-directory: ${N}`)}catch(D){if(D.code!=="ENOENT")throw D;if(!L)await Yd(U,{mode:448})}}return H}async function Xi(O,N,L){let F=L.length,H=await gn(O,N,L);if(L.length>F)return;try{let M=await qi(H);if(M.isSymbolicLink()){L.push(H);return}if(!M.isFile())throw Error(`Refusing to replace non-regular project file: ${N}`)}catch(M){if(M.code!=="ENOENT")throw M}}import{spawnSync as rp}from"node:child_process";import{mkdtemp as sp,writeFile as op,rm as ip}from"node:fs/promises";import{tmpdir as ap}from"node:os";import{join as Yi}from"node:path";function Zi(O,N,L){let F=rp("git",["-c","core.hooksPath=/dev/null","-C",O,...N],{encoding:"utf8",timeout:120000,maxBuffer:41943040,env:{PATH:process.env.PATH,GIT_CONFIG_GLOBAL:L??"/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(F.status!==0)throw Error("HLIX Repos Git operation failed. The remote may have changed; refresh and retry.");return F.stdout.trim()}async function Qi(O,N){let L=new URL(O.cloneUrl);if(L.href!==O.cloneUrl||/[\r\n"\\]/.test(O.cloneUrl)||L.protocol!=="https:"||L.username||L.password||L.search||L.hash||L.port||!(L.hostname==="github.com"||/^[a-f0-9]{32}\.artifacts\.cloudflare\.net$/.test(L.hostname)))throw Error("Invalid HLIX Repos remote");if(/[\r\n]/.test(O.token))throw Error("Invalid repository credential");let F=await sp(Yi(ap(),"hlix-git-auth-")),H=Yi(F,"config"),M=O.token.replace(/\?expires=\d+$/,""),U=Buffer.from(`x-access-token:${M}`).toString("base64");try{return await op(H,`[http "${O.cloneUrl}"]
349
+ extraHeader = Authorization: Basic ${U}
350
+ followRedirects = false
351
+ `,{mode:384}),await N(H)}finally{await ip(F,{recursive:!0,force:!0})}}function Lt(O){return new Map([...Ki(O).map((N)=>[N.path,`blob:${N.sha256}`]),...Vi(O).map((N)=>[N.path,`link:${N.target}`])])}var ea={git:Zi,access:Qi};async function Ft(O){let N=t(O);if(!N?.config.projectId)throw new e("not_initialized","Run hlix import or hlix init to bind this folder to a project.");return{...N,state:i(N.root)}}async function ta(O,N){let L=await Be(O,{environment:N,historyMode:"sanitize",maxFiles:50000,maxFileBytes:33554432,maxTotalBytes:1073741824});if(L.manifest.files=L.manifest.files.filter((F)=>F.path!==".hlixignore"),L.blocking.length)throw new e("scan_blocked",L.blocking.join(`
352
+ `));return L}function gp(O,N){let L=Object.fromEntries(Lt(O.manifest));return!N?.files?O.manifest.files.length+O.manifest.symlinks.length>0:JSON.stringify(Object.entries(L).sort())!==JSON.stringify(Object.entries(N.files).sort())}async function gs(O,N,L){let F=await O.projects.get(N),H=L?F.repos.find((M)=>M.id===L):F.repos.find((M)=>M.isPrimary)??(F.repos.length===1?F.repos[0]:void 0);if(!H)throw new e("conflict","Select a primary repository for this project before syncing.");return H}async function hs(O,N,L,F,H=!1,M=ea){let{config:U,state:G}=await Ft(O),D=await gs(N,U.projectId,G?.repoId),B=await N.repos.head(U.projectId,D.id);if((F??G?.commitSha)&&B.commitSha!==(F??G?.commitSha))throw new e("conflict","HLIX Repos changed. Pull or sync before pushing.");let J=await Ji(L);try{let W=await N.repos.access(U.projectId,D.id,"write"),z=await M.access(W,async(Q)=>{M.git(J.directory,["fetch","--no-tags",W.cloneUrl,`refs/heads/${D.defaultBranch}`],Q);let te=M.git(J.directory,["rev-parse","FETCH_HEAD"]);if(te!==B.commitSha)throw new e("conflict","HLIX Repos changed during upload. Retry sync.");let V=M.git(J.directory,["rev-parse",`${J.commitSha}^{tree}`]),X=M.git(J.directory,["commit-tree",V,"-p",te,...H&&L.manifest.git.detected?["-p",J.commitSha]:[],"-m","Update HLIX Repos files"]);return M.git(J.directory,["push",`--force-with-lease=refs/heads/${D.defaultBranch}:${te}`,W.cloneUrl,`${X}:refs/heads/${D.defaultBranch}`],Q),X});return ir(O,{schemaVersion:1,repoId:D.id,commitSha:z,files:Object.fromEntries(Lt(L.manifest)),snapshotOnly:!0,rootName:L.manifest.rootName}),{action:"push",commitSha:z}}finally{await J.dispose()}}async function hp(O,N,L,F,H,M){let{config:U}=await Ft(O),G=await gs(N,U.projectId,L),D=await cp(fs(fp(),"hlix-pull-"));try{let B=await N.repos.access(U.projectId,L,"read");await M.access(B,async(X)=>{M.git(D,["init"]),M.git(D,["fetch","--no-tags",B.cloneUrl,`refs/heads/${G.defaultBranch}`],X),M.git(D,["checkout","--detach",F])});let J=await ta(D),W=[],z=[...J.manifest.files,...J.manifest.symlinks],Q=[...H.manifest.files,...H.manifest.symlinks].filter((X)=>!z.some((ee)=>ee.path===X.path)),te=new Set([...H.manifest.files,...H.manifest.symlinks].map((X)=>X.path));for(let X of z){let ee=X.path.split("/");for(let Y=1;Y<=ee.length;Y++){let ie=ee.slice(0,Y).join("/"),le=await mp(fs(O,ie)).catch((ge)=>{if(ge.code!=="ENOENT")throw ge;return null});if(le&&!le.isDirectory()&&!te.has(ie))throw new e("conflict",`Incoming repository file would replace an excluded local file: ${ie}`)}}for(let X of[...z,...Q])await Xi(O,X.path,W);let V=await Promise.all(J.manifest.files.map(async(X)=>({...X,bytes:await lp(fs(D,X.path))})));for(let X of[...new Set(W)].sort((ee,Y)=>ee.length-Y.length))await Kn(X,{force:!0});for(let X of Q)await Kn(await gn(O,X.path),{force:!0});for(let X of V){let ee=await gn(O,X.path);await dp(ee,X.bytes,{mode:X.executable?493:420}),await pp(ee,X.executable?493:420)}for(let X of J.manifest.symlinks){let ee=await gn(O,X.path);await Kn(ee,{force:!0}),await up(X.target,ee)}return ir(O,{schemaVersion:1,repoId:L,commitSha:F,files:Object.fromEntries(Lt(J.manifest)),snapshotOnly:!0,rootName:H.manifest.rootName}),{action:"pull",commitSha:F}}finally{await Kn(D,{recursive:!0,force:!0})}}async function ys(O,N,L,F="sync",H=!1,M=ea){let{config:U,state:G}=await Ft(O),D=await gs(N,U.projectId,G?.repoId),[B,J]=await Promise.all([ta(O,L),N.repos.head(U.projectId,D.id)]),W=gp(B,G),z=G?.commitSha!==J.commitSha,Q=!G&&W&&!J.isEmpty?"conflict":F==="push"?z&&G?"conflict":W?"push":"none":F==="pull"?W?"conflict":z?"pull":"none":W&&z&&G?"conflict":W?"push":z?"pull":"none";if(H)return{action:Q,localChanged:W,cloudChanged:z,commitSha:J.commitSha};if(Q==="conflict")throw new e("conflict","This folder and HLIX Repos have both changed. Resolve the differences before syncing; no files were replaced.");if(Q==="push")return hs(O,N,B,J.commitSha,!1,M);if(Q==="pull")return hp(O,N,D.id,J.commitSha,B,M);return{action:"none",commitSha:J.commitSha}}function ws(O){return{name:O,summary:`${O} files with HLIX Repos`,usage:`Usage: hlix ${O} [--dry-run] [--json]`,supportsJson:!0,options:["dry-run"],async run(N){let{root:L}=await Ft(N.cwd),F=await ys(L,N.requireClient(),N.env,O,N.flags["dry-run"]===!0);return N.stdout(N.json?oe(ae(`hlix ${O}`,F)):`HLIX Repos: ${F.action} (${F.commitSha})
353
+ `),F.action==="conflict"?1:0}}}var na=ws("push"),ra=ws("pull"),sa=ws("sync");var bp=(O)=>`${(O/1024/1024).toFixed(1)} MB`,vs=(O,N=3)=>O.slice(0,N).join(", ")+(O.length>N?`, +${O.length-N} more`:"");function kp(O,N,L,F){let{manifest:H}=O,M=new Map;for(let D of H.files){let B=D.path.includes("/")?`${D.path.split("/")[0]}/`:"(root files)";M.set(B,(M.get(B)??0)+1)}let U=[...M].sort((D,B)=>B[1]-D[1]).map(([D,B])=>`${D} ${B}`);return["Import plan",...[["Project",`${N} (${L})`],["Files",`${H.totals.files} files, ${bp(H.totals.bytes)}`],["Folders",vs(U,5)||"none"],["Secrets",O.protectedFiles.length?`${O.protectedFiles.length} encrypted: ${vs(O.protectedFiles.map((D)=>D.path))}`:"none found"],["History",!H.git.detected?"no git history":F==="preserve"?`kept: ${H.git.commitCount} commits${H.git.branch?` on ${H.git.branch}`:""}`:"not sent (sanitize)"],["Skipped",H.skipped.length?vs(H.skipped.map((D)=>D.path)):"nothing"]].map(([D,B])=>` ${D.padEnd(9)}${B}`),"","To change it: --name <name>, --include <path>, or list paths in .hlixignore."].join(`
354
+ `)}var oa={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(O){let N=await vp(wp(O.cwd,O.args[0]??".")),L=r({env:O.env,flags:O.flags,cwd:N});if(L.conflict)throw new e("conflict",L.conflict);if(!L.workspaceId||!L.credential)throw new e("workspace_required","Run hlix auth login to select a workspace.");if(Pt(N)?.projectId)throw new e("conflict","This folder is already bound to a project. Use hlix push or sync.");let H=O.flags.history??"preserve";if(H!=="preserve"&&H!=="sanitize")throw new e("invalid_usage","--history accepts preserve or sanitize.");let M=await Be(N,{environment:O.env,historyMode:H,envFile:typeof O.flags["env-file"]==="string"?O.flags["env-file"]:void 0,maxFiles:50000,maxFileBytes:33554432,maxTotalBytes:1073741824,include:typeof O.flags.include==="string"?O.flags.include:void 0});if(M.blocking.length)throw new e("scan_blocked",M.blocking.join(`
355
+ `));if(M.manifest.git.detected&&(M.manifest.historicalSecretFindings.length||!M.manifest.git.historyScanComplete))throw new e("scan_blocked","History contains potential secrets or was not completely scanned. Review it or use --history sanitize.");let U={files:M.manifest.totals.files,bytes:M.manifest.totals.bytes,protectedFiles:M.protectedFiles.length,history:H},G=typeof O.flags.name==="string"?O.flags.name:yp(N),D=typeof O.flags.stack==="string"?O.flags.stack:M.manifest.stack,B=kp(M,G,D,H);if(O.flags["dry-run"]===!0)return O.stdout(O.json?oe(ae("hlix import",U)):`${B}
356
+ `),0;if(O.flags.yes!==!0){if(!O.confirm)throw new e("invalid_usage","Import requires approval. Review --dry-run, then use --yes.");if(!await O.confirm(B))return O.stdout(`Import cancelled. Nothing was sent.
357
+ `),0}let J=O.requireClient(N),W=await J.projects.create({name:G,stack:D,repos:[]});Pn(N,{schemaVersion:1,projectId:W.id,workspaceId:L.workspaceId,apiUrl:L.baseUrl});for(let Q=0;Q<M.protectedFiles.length;Q+=64)await J.secrets.importFiles(W.id,M.protectedFiles.slice(Q,Q+64).map((te)=>({path:te.path,contentBase64:te.contentBase64})));let z=await hs(N,J,M,void 0,H==="preserve");return O.stdout(O.json?oe(ae("hlix import",{...U,projectId:W.id,commitSha:z.commitSha})):`Imported into HLIX Repos: ${W.name} (${z.commitSha})
358
+ `),0}};import{spawnSync as Sp}from"node:child_process";import{existsSync as jp,mkdirSync as Ep,writeFileSync as xp}from"node:fs";import{dirname as Pp}from"node:path";function $p(O){return O==="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(`
359
+ `):["# 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(`
360
+ `)}function _p(O){return O.VISUAL?.trim()||O.EDITOR?.trim()||"vi"}var bs={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 (${h.join(", then ")}).`].join(`
361
+ `),supportsJson:!0,options:["edit","global"],async run(O){let N=w({cwd:O.cwd,configDir:".hlix",env:O.env}),L=O.flags.global===!0;if(O.flags.edit===!0){if(O.json)throw new e("invalid_usage","`hlix rules --edit` opens an editor, so it has no --json form.");let F=L?_r(O.env):$r(O.cwd,".hlix")?.path??`${O.cwd}/AGENTS.md`;if(!jp(F))Ep(Pp(F),{recursive:!0}),xp(F,$p(L?"global":"project"),"utf8"),O.stdout(`Created ${F}.
362
+ `);let H=_p(O.env),M=Sp(H,[F],{stdio:"inherit"});if(M.error)throw new e("invalid_usage",`Could not run ${H}: ${M.error.message}`);return M.status??0}if(O.json){let F=(H)=>H?{path:H.path,characters:H.content.length}:null;return O.stdout(oe(ae(bs.name,{user:F(N.global),project:F(N.project)}))),0}return O.stdout(`${b(N,O.cwd)}
363
+ `),0}};var ks={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(`
364
+ `),supportsJson:!0,async run(O){let N=v(O.cwd,a(O.env),{env:O.env});if(O.json)return O.stdout(oe(ae(ks.name,{instructions:N.instructions.map((L)=>({path:L.path,source:L.source,scope:L.scope,characters:L.content.length,...L.note?{note:L.note}:{}})),skills:N.skills,commands:[...N.commands.map((L)=>({path:L.path,source:L.source,scope:L.scope})),...N.generatedCommands.map((L)=>({path:L.path,source:L.source,scope:L.scope,command:L.name}))],mcpServers:N.mcpServers.map((L)=>({path:L.path,source:L.source,scope:L.scope,name:L.name,transport:"command"in L.config?"stdio":"http"})),subagents:N.subagents.map((L)=>({path:L.path,source:L.source,scope:L.scope,name:L.name,description:L.description,...L.model?{model:L.model}:{}})),skipped:N.skipped}))),0;return O.stdout(Bo(N,O.cwd)),0}};var aa=(O)=>O instanceof Error?O.message:String(O),ia=(O)=>O.split(/\s*\n\s*/).join(" ").trim();async function k(O,N,L,F,H){try{let M=await Be(N,{historyMode:L,environment:O.env,rootName:F}),U=i(N)?.files,G=Lt(M.manifest);return{changedFiles:U?[...new Set([...Object.keys(U),...G.keys()])].filter((B)=>U[B]!==G.get(B)).length:null,files:M.manifest.totals.files,manifestSha256:M.manifestSha256,changed:H?M.manifestSha256!==H:null,blocking:M.blocking,error:null}}catch(M){return{changedFiles:null,files:null,manifestSha256:null,changed:null,blocking:[],error:aa(M)}}}var Ss={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(`
365
+ `),supportsJson:!0,async run(O){let N=r({env:O.env,flags:O.flags,cwd:O.cwd}),L=N.binding,F=L?i(L.root):null,H=L?await k(O,L.root,F?.snapshotOnly?"sanitize":F?.historyMode??"preserve",F?.rootName,F?.manifestSha256):null,M=null;if(L?.config.projectId&&N.credential&&!N.conflict)try{let B=O.requireClient(),J=await B.projects.get(L.config.projectId),W=F?.repoId??J.repos.find((Q)=>Q.isPrimary)?.id??J.repos[0]?.id;if(!W)throw Error("Select a primary HLIX Repos");let z=await B.repos.head(L.config.projectId,W);M={commitSha:z.commitSha,changed:F?z.commitSha!==F.commitSha:null,error:null,errorMessage:null}}catch(B){M={commitSha:"",changed:null,error:kr(B).code,errorMessage:B instanceof ct?"no HLIX Repos commit yet — `hlix push` publishes this folder":aa(B)}}let U=Ar(O.env),G={cwd:O.cwd,workspace:{id:N.workspaceId,source:N.workspaceSource},api:{baseUrl:N.baseUrl,source:N.baseUrlSource},credential:{present:N.credential!==null,source:N.credentialSource,path:N.credentialPath},conflict:N.conflict,project:L?{root:L.root,projectId:L.config.projectId??null,workspaceId:L.config.workspaceId,apiUrl:L.config.apiUrl}:null,repository:F?{repoId:F.repoId,commitSha:F.commitSha}:null,local:H,cloud:M,install:{channel:U.running?.channel??null,path:U.running?.path??null,copies:U.copies.map(({path:B,channel:J})=>({path:B,channel:J})),duplicate:U.duplicate}};if(O.json)return O.stdout(oe(ae(Ss.name,G))),0;let D=[["folder",O.cwd],["workspace",N.workspaceId?`${N.workspaceId} (from ${N.workspaceSource})`:"none — run `hlix auth login --workspace <id>`"],["api",`${N.baseUrl} (from ${N.baseUrlSource})`],["credential",m(N)??"none — run `hlix auth login`"],["project",L?L.config.projectId??`initialized at ${L.root}, not imported yet`:"none — run `hlix import .` to bind this folder"]];if(F)D.push(["HLIX Repos",F.commitSha]);if(H){if(D.push(["local",H.error?`could not scan: ${H.error}`:H.changed===null?`${H.files} files, no synced base commit`:H.changed?`${H.files} files, modified since the last sync`:`${H.files} files, matches the last sync`]),H.blocking.length>0)D.push(["blocking",H.blocking.join("; ")])}if(M)D.push(["cloud",M.error==="not_found"?ia(M.errorMessage??M.error):M.error?`not checked — ${ia(M.errorMessage??M.error)}`:M.changed?`commit ${M.commitSha} available — run \`hlix pull\``:`commit ${M.commitSha}, up to date`]);if(N.conflict)D.push(["conflict",N.conflict]);if(U.running)D.push(["installed",An(U.running)]);if(U.duplicate)D.push(["duplicate",U.duplicate]);return O.stdout(`${je(D)}
366
+ `),0}};import{spawnSync as ca}from"node:child_process";var js={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(`
367
+ `),supportsJson:!0,options:["print","web"],args:{min:0,max:1},async run(O){let N=O.args[0]??t(O.cwd)?.config.projectId;if(!N)throw new e("missing_argument","A project id is required, or run this inside a folder bound to a project.");let L=await O.requireClient().projects.terminal(N);if(O.json)return O.stdout(oe(ae(js.name,L))),L.available?0:1;if(!L.available){let U=L.environmentState?` (environment: ${L.environmentState})`:"";throw new e("not_found",`${L.reason??"Terminal unavailable"}${U}`)}let F=O.flags.print===!0,H=O.flags.web===!0;if(F||H&&!L.webTerminalUrl||!H&&!L.sshCommand)return O.stdout(`${je([["ssh",L.sshCommand??"not available"],["browser",L.webTerminalUrl??"not available"]])}
368
+ `),0;if(H){if(ca(process.platform==="darwin"?"open":"xdg-open",[L.webTerminalUrl],{stdio:"ignore"}).status!==0)O.stdout(`${L.webTerminalUrl}
369
+ `);return 0}return ca("sh",["-c",L.sshCommand],{stdio:"inherit"}).status??1}};import{rmSync as la}from"node:fs";import{dirname as Cp}from"node:path";var Es={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(`
370
+ `),supportsJson:!0,options:["yes"],async run(O){let N=Tr(O.env);if(!N||N.channel!=="installer")throw new e("invalid_request",N&&N.channel!=="unknown"?`This hlix was installed with ${N.channel==="homebrew"?"Homebrew":"npm"}. Remove it with: ${Rr(N)}`:"Only an hlix installed by the one-line installer can remove itself.");if(O.flags.yes!==!0){if(O.json||!O.confirm)throw new e("approval_required","Removing hlix needs approval. Repeat with `--yes`.");if(!await O.confirm(`Remove ${N.path}? Your login is kept.`))throw new e("cancelled","Uninstall cancelled.")}let L=Ir(O.env);la(N.path,{force:!0}),la(L,{recursive:!0,force:!0});let F=Cp(De(O.env));if(O.json)O.stdout(oe(ae(Es.name,{removed:[N.path,L],kept:F})));else O.stdout(`Removed ${N.path}
371
+ Your login in ${F} is kept.
372
+ `);return 0}};function E(O){return[...O.pulled?[`HLIX Repos: pulled ${O.pulled}`]:[],...O.pushed?[`HLIX Repos: pushed ${O.pushed}`]:[]]}async function _(O,N,L){let F=!1;while(!L.signal?.aborted){try{let H=await ys(O,N.client,N.env);if(L.onReport({conflicts:[],...H.action==="push"?{pushed:H.commitSha}:H.action==="pull"?{pulled:H.commitSha}:{}}),!F)F=!0,L.onCaughtUp?.()}catch(H){L.onError(H)}await Qe(15000,L.signal)}}var da={name:"mirror",summary:"Follow HLIX Repos using Git",usage:"Usage: hlix mirror [--json]",supportsJson:!0,options:[],agentTool:!1,async run(O){let{root:N}=await Ft(O.cwd);return await _(N,{client:O.requireClient(),env:O.env},{signal:O.signal,onReport:(L)=>{if(O.json)O.stdout(oe(ae("hlix mirror",L)));else for(let F of E(L))O.stdout(`${F}
373
+ `)},onError:(L)=>O.stderr(`${L instanceof Error?L.message:String(L)}
374
+ `)}),0}};import{lstat as Ps,readFile as Ip,realpath as Tp}from"node:fs/promises";import{basename as xs,dirname as Rp,extname as Ap,join as Vn,parse as pa,resolve as Xn}from"node:path";function Ht(O,N){let L=O.flags[N];return typeof L==="string"&&L.trim()?L.trim():void 0}function $s(O){let N=Ht(O,"project");if(N)return{root:O.cwd,projectId:N};return Op(O.cwd)}function Op(O){let N=t(O);if(!N?.config.projectId)throw new e("not_initialized","This folder is not bound to an Hlix project. Run `hlix import .` first.");return{root:N.root,projectId:N.config.projectId}}async function _s(O,N){let L=await Ps(O);if(L.isSymbolicLink()||!L.isFile())throw Error(`Refusing to import a non-regular file: ${O}`);if(L.size>N)throw Error(`Import file exceeds ${N} bytes: ${O}`);return{path:await Tp(O),content:await Ip(O,"utf8")}}function Cs(O,N,L,F){if(O.json)O.stdout(oe(ae(N,L)));else O.stdout(`${F}
375
+ `)}function Np(O){let N=/^---\r?\n([\s\S]*?)\r?\n---/.exec(O)?.[1];return(N?/^name:\s*(.+?)\s*$/m.exec(N)?.[1]:void 0)?.replace(/^["']|["']$/g,"").trim()||void 0}var Lp=[Vn(".claude","skills"),Vn(".agents","skills"),Vn(".hlix","skills")];async function Fp(O,N){let L=[Xn(O,N),...Lp.map((F)=>Xn(O,F,N))];for(let F of L)if(await Ps(F).then(()=>!0,()=>!1))return F;throw new e("not_found",`No skill at ${N}. Pass the SKILL.md or its folder, for example .claude/skills/${N}.`)}var Is={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(O){if(O.args.length!==1)throw Error("skill import requires one file or folder.");let N=$s(O),L=await Fp(O.cwd,O.args[0]),F=await Ps(L);if(F.isSymbolicLink())throw Error(`Refusing to import a symlink: ${L}`);let H=F.isDirectory()?Vn(L,"SKILL.md"):L,M=await _s(H,200000),U=F.isDirectory()?xs(L):xs(H)==="SKILL.md"?xs(Rp(H)):pa(H).name,G=Ht(O,"name")??U;if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(G))throw Error("Skill name must be a lowercase kebab-case slug.");let D=await O.requireClient().resources.importSkill(N.projectId,{slug:G,content:M.content});return Cs(O,Is.name,D.skill,`Imported skill ${G}`),0}},Ts={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(O){if(O.args.length!==1)throw Error("agent import requires one Markdown file.");let N=$s(O),L=Xn(O.cwd,O.args[0]);if(![".md",".mdx"].includes(Ap(L).toLowerCase()))throw Error("Agent imports must be Markdown files.");let F=await _s(L,20000),H=Ht(O,"runtime");if(H!==void 0&&!o.includes(H)){let D=new Intl.ListFormat("en",{type:"disjunction"}).format(o);throw Error(`--runtime must be ${D}.`)}let M=Ht(O,"duty")??"executor";if(M!=="executor"&&M!=="intake")throw Error("--duty must be executor or intake.");let U=Ht(O,"name")??Np(F.content)??pa(L).name.replace(/[-_]+/g," "),G=await O.requireClient().resources.importAgent(N.projectId,{name:U,instructions:F.content,...H?{runtimeKind:H}:{},duty:M});return Cs(O,Ts.name,G.agent,G.agent.duty==="intake"?`Imported agent ${G.agent.name} as this project's intake agent`:`Imported agent ${G.agent.name}`),0}},Rs={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(O){if(O.args.length!==1)throw Error("mcp import requires one MCP JSON file.");let N=$s(O),L=await _s(Xn(O.cwd,O.args[0]),200000),F;try{F=JSON.parse(L.content)}catch{throw Error("MCP config is not valid JSON.")}let H=Object.entries(F.mcpServers??{});if(H.length===0)throw Error("MCP config contains no servers.");let M=Ht(O,"server");if(!M&&H.length>1)throw Error("MCP config contains multiple servers; select one with --server <name>.");let U=M?H.find(([V])=>V===M):H[0];if(!U)throw Error(`MCP server not found: ${M}`);let[G,D]=U,B=D.type==="http"||D.type==="sse"?D.type:typeof D.command==="string"?"stdio":typeof D.url==="string"?"http":null;if(!B)throw Error(`MCP server ${G} has no supported transport.`);if(B==="stdio"&&O.flags["allow-stdio"]!==!0)throw Error("Stdio MCP servers execute a command on the Cloud Machine; repeat with --allow-stdio.");let J=D.env&&typeof D.env==="object"&&!Array.isArray(D.env)?D.env:{},W=D.headers&&typeof D.headers==="object"&&!Array.isArray(D.headers)?D.headers:{};if(Object.values(W).some((V)=>typeof V!=="string"))throw Error(`MCP server ${G} headers must be strings.`);for(let[V,X]of Object.entries(J)){if(typeof X!=="string")continue;let ee=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(X)?.[1];if(ee&&ee!==V)throw new e("invalid_usage",`MCP server ${G}: env ${V} references \${${ee}}, but a placeholder must be the variable's own name — write "${V}": "\${${V}}" and store the secret as ${V}.`)}let z=Object.values(W).flatMap((V)=>[...V.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g)].map((X)=>X[1]));if(Object.keys(W).length>0&&z.length===0)throw Error("MCP remote headers must use ${KEY} placeholders; literal credentials are refused.");let Q=/^(?:(?:Bearer|Basic|Token) )?\$\{[A-Za-z_][A-Za-z0-9_]*\}$/i;if(Object.values(W).some((V)=>!Q.test(V)))throw Error("MCP remote headers must be ${KEY} or an approved auth scheme followed by ${KEY}.");let te=await O.requireClient().resources.importMcp(N.projectId,{name:G,transport:B,...typeof D.command==="string"?{command:D.command}:{},...Array.isArray(D.args)&&D.args.every((V)=>typeof V==="string")?{args:D.args}:{},...typeof D.url==="string"?{url:D.url}:{},...Object.keys(W).length>0?{headers:W}:{},envKeys:[...new Set([...Object.keys(J),...z])].sort()});return Cs(O,Rs.name,te.mcpServer,`Imported MCP server ${G}`),0}};import{spawnSync as Hp}from"node:child_process";import{chmod as Mp,realpath as Up,writeFile as Dp}from"node:fs/promises";import{basename as Gp,dirname as Bp,relative as Jp,resolve as ma,sep as Wp}from"node:path";var ua=64;function yn(O){let N=t(O.cwd),F=(typeof O.flags.project==="string"?O.flags.project:void 0)??N?.config.projectId;if(!F)throw new e("not_initialized","This folder is not bound to a Hlix project. Run `hlix import .`, or pass --project <id>.");return{projectId:F,root:N?.root??O.cwd}}var hn=(O,N)=>typeof O[N]==="string"?O[N]:void 0,As={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(`
376
+ `),supportsJson:!0,options:["project"],async run(O){let{projectId:N}=yn(O),L=await O.requireClient().secrets.listEntries(N);if(O.json)return O.stdout(oe(ae(As.name,L))),0;if(L.entries.length===0)O.stdout(`No secrets stored for this project.
377
+ `);else O.stdout(`${Je(["key","source","format","value","updated"],L.entries.map((F)=>[F.key,F.source,F.format||"-",F.maskedValue,F.updatedAt?.slice(0,10)??"-"]))}
378
+ `);for(let F of L.warnings)O.stderr(`warning: ${F}
379
+ `);return 0}},Os={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(`
380
+ `),supportsJson:!0,options:["from-stdin","source","project"],args:{min:1,max:2},async run(O){let{projectId:N}=yn(O),L=O.args[0],F=O.flags["from-stdin"]===!0;if(F&&O.args.length>1)throw new e("invalid_usage","Pass the value as an argument or with --from-stdin, not both.");if(!F&&O.args.length<2)throw new e("missing_argument","A value is required. Pass it as an argument, or pipe it with --from-stdin.");let H;if(F){if(!O.readStdin)throw new e("invalid_usage","--from-stdin is not available in this context.");H=(await O.readStdin()).replace(/\r?\n$/,"")}else H=O.args[1];let M=hn(O.flags,"source"),U=await O.requireClient().secrets.upsertEntries(N,{entries:[{key:L,value:H,...M?{source:M}:{}}]});if(O.json)return O.stdout(oe(ae(Os.name,U))),U.written>0?0:1;if(U.written===0)throw new e("bad_request",`The store refused ${L}: --source must be a project-relative file path.`);return O.stdout(`${je([["key",L],["source",M??".env"]])}
381
+ `),0}},Ns={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(`
382
+ `),supportsJson:!0,options:["source","project"],args:{min:1,max:1},async run(O){let{projectId:N}=yn(O),L=O.args[0],F=hn(O.flags,"source"),H=await O.requireClient().secrets.deleteEntry(N,L,F);if(O.json)return O.stdout(oe(ae(Ns.name,H))),H.removed>0?0:1;if(H.removed===0)return O.stderr(`No stored secret named ${L}${F?` in ${F}`:""}.
383
+ `),1;return O.stdout(`Removed ${H.removed} entr${H.removed===1?"y":"ies"} for ${L}.
384
+ `),0}},Yn={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(`
385
+ `),supportsJson:!0,options:["project"],args:{min:0,max:64},async run(O){let{projectId:N,root:L}=yn(O),F=await Be(L,{historyMode:"preserve",environment:O.env}),H=F.blocking.filter((W)=>!W.startsWith(ls));if(H.length>0)throw new e("scan_blocked",`Project scan blocked the import:
386
+ - ${H.join(`
387
+ - `)}`);let M=F.protectedFiles.filter((W)=>W.kind==="dotenv"||W.kind==="credential"),U=await Up(O.cwd),G=O.args.map((W)=>Jp(F.root,ma(U,W)).split(Wp).join("/")),D=G.filter((W)=>!M.some((z)=>z.path===W));if(D.length>0)throw new e("invalid_usage",`Not a secret file in this project: ${D.join(", ")}`);let B=G.length>0?M.filter((W)=>G.includes(W.path)):M;if(B.length===0)return O.stdout(O.json?oe(ae(Yn.name,{imported:[],skipped:[],warnings:[],written:0,rejected:[]})):`No secret files found in this project.
388
+ `),0;if(B.length>ua)throw new e("invalid_usage",`${B.length} secret files exceeds the ${ua} the store accepts in one request. Name the files to import, a batch at a time.`);let J=await O.requireClient().secrets.importFiles(N,B.map((W)=>({path:W.path,contentBase64:W.contentBase64})));if(O.json)return O.stdout(oe(ae(Yn.name,J))),0;if(J.imported.length>0)O.stdout(`${Je(["source","format","stored"],J.imported.map((W)=>[W.path,W.format||"-",W.kind==="file"?"as file":`${W.entries} entr${W.entries===1?"y":"ies"}`]))}
389
+ `);if(O.stdout(`${J.written} value${J.written===1?"":"s"} stored.
390
+ `),J.imported.some((W)=>W.kind!=="file"))O.stdout(`Each imported file replaced what the store held under its path; keys the file no longer has are gone.
391
+ `);for(let W of J.skipped)O.stderr(`skipped ${W.path}: ${W.reason}
392
+ `);for(let W of J.warnings)O.stderr(`warning: ${W}
393
+ `);for(let W of J.rejected)O.stderr(`rejected ${W}: the store refused its source path
394
+ `);return 0}};function qp(O){return Hp("git",["-C",Bp(O),"ls-files","--error-unmatch","--",Gp(O)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}).status===0}var Ls={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(`
395
+ `),supportsJson:!0,options:["source","format","out","project"],async run(O){let{projectId:N}=yn(O),L=hn(O.flags,"source"),F=hn(O.flags,"format"),H=hn(O.flags,"out"),M=H===void 0?void 0:ma(O.cwd,H);if(M!==void 0&&qp(M))throw new e("invalid_usage",`Refusing to overwrite a git-tracked file with secret values: ${M}`);let U=await O.requireClient().secrets.exportEntries(N,{...L?{source:L}:{},...F?{format:F}:{}});if(M!==void 0)await Dp(M,U,{mode:384}),await Mp(M,384);if(O.json)return O.stdout(oe(ae(Ls.name,{source:L??null,format:F??null,out:M??null,bytes:Buffer.byteLength(U),...M===void 0?{content:U}:{}}))),0;if(M===void 0)O.stdout(U);else O.stdout(`${je([["wrote",M],["mode","0600"],["bytes",String(Buffer.byteLength(U))]])}
396
+ `);return 0}};function Hs(O){let N=O.flags.project;if(typeof N==="string"&&N)return N;return t(O.cwd)?.config.projectId??void 0}function Fs(O,N){let L=O[N];if(typeof L!=="string"||L.trim()==="")throw new e("missing_argument",`--${N} is required.`);return L}var Ms={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(`
397
+ `),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(O){let N=O.args[0],L=Fs(O.flags,"title"),F=Fs(O.flags,"description"),H=await O.requireClient().cycles.propose({projectId:N,title:L,description:F});if(O.json)return O.stdout(oe(ae(Ms.name,H))),0;return O.stdout(`${je([["project",N],["title",L],["status",H.adopted?"adopted — the project is planning it now":"recorded — it will be planned on the next pass"]])}
398
+ `),0}},Us={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(`
399
+ `),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(O){let N=O.args[0],L=Fs(O.flags,"description"),F=typeof O.flags.title==="string"?O.flags.title:void 0,H=await O.requireClient().tasks.create({projectId:N,description:L,...F?{title:F}:{}});if(O.json)return O.stdout(oe(ae(Us.name,H))),0;return O.stdout(`${je([["task",H.id],["project",N],["status",H.status??"queued"],["note","not started — dispatch with `hlix cycles create`"]])}
400
+ `),0}},Ds={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(`
401
+ `),supportsJson:!0,options:["project"],args:{min:0,max:1},async run(O){let N=O.args[0]??Hs(O),L=O.requireClient(),F=N?await L.modelConfig.resolved(N):await L.modelConfig.resolved();if(O.json)return O.stdout(oe(ae(Ds.name,F))),0;return O.stdout(`${je([["scope",N?`project ${N}`:"workspace"],["harness",F.cycle.harness],["source",F.cycle.source.harness]])}
402
+ `),0}},Gs={name:"harness set",summary:"Choose the coder a project or the workspace runs",usage:[`Usage: hlix harness set <${o.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(`
403
+ `),supportsJson:!0,options:["org"],args:{min:1,max:2},async run(O){let N=O.args[0];if(!o.includes(N))throw new e("invalid_usage",`harness must be one of ${o.join(", ")}; got "${N}".`);let L=O.flags.org===!0,F=O.args[1]??(L?void 0:Hs(O));if(F&&L)throw new e("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!F&&!L)throw new e("invalid_usage","Name the project to set, or pass --org for the whole workspace.");let H=O.requireClient(),M=F?await H.modelConfig.setProjectHarness(F,N):await H.modelConfig.setHarness(N);if(O.json)return O.stdout(oe(ae(Gs.name,M))),0;return O.stdout(`${je([["scope",F?`project ${F}`:"workspace"],["harness",N]])}
404
+ `),0}},Bs={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(`
405
+ `),supportsJson:!0,options:["org"],args:{min:0,max:1},async run(O){let N=O.flags.org===!0,L=O.args[0]??(N?void 0:Hs(O));if(L&&N)throw new e("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!L&&!N)throw new e("invalid_usage","Name the project to clear, or pass --org for the whole workspace.");let F=O.requireClient(),H=L?await F.modelConfig.clearProjectHarness(L):await F.modelConfig.clearHarness();if(O.json)return O.stdout(oe(ae(Bs.name,H))),0;return O.stdout(`${je([["scope",L?`project ${L}`:"workspace"],["harness","cleared — the scope below decides now"]])}
406
+ `),0}};var p=[Or,Nr,At,Ss,Es,js,ks,bs,Lr,Fr,Hr,ps,oa,sa,ra,na,da,Is,Ts,Rs,As,Os,Ns,Yn,Ls,Mr,Ur,Dr,Gr,Br,Wr,qr,zr,Kr,Us,Ms,Ds,Gs,Bs];
407
+ export{e,s,j,i,m,t,r,n,c,g,l,d,o,S,f,x,y,u,a,C,h,w,A,b,v,I,T,R,P,k,E,_,p};