@hlix/cli 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -8
- package/THIRD_PARTY_NOTICES +588 -13
- package/dist/app-njwmny66.js +5 -0
- package/dist/cli-cy5xk6z6.js +2 -0
- package/dist/github-link-zjx3855h.js +2 -0
- package/dist/hlix-file-7kwe2ppc.js +2 -0
- package/dist/import-cpywf45x.js +2 -0
- package/dist/index-2b2mh91d.js +39 -0
- package/dist/index-nv1fntbt.js +423 -0
- package/dist/index-sn0bes3n.js +3 -0
- package/dist/index.js +2 -2
- package/dist/main-dm0g4h2e.js +175 -0
- package/dist/main-jfwez07t.js +11 -0
- package/dist/package-kttrhq89.js +2 -0
- package/package.json +15 -15
- package/dist/index-c5avvnm2.js +0 -410
- package/dist/main-z66m02gb.js +0 -211
- package/dist/package-6n7j36nb.js +0 -2
package/dist/index-c5avvnm2.js
DELETED
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import{resolve as Vd}from"node:path";import{parseArgs as Xd}from"node:util";import wl from"openapi-fetch";function Zr(z){return wl({baseUrl:z.baseUrl,headers:z.headers,fetch:z.fetch})}var Tt=(z)=>({kind:"apiKey",apiKey:z});var tn=(z)=>({kind:"bearer",token:z});function vl(z){switch(z.kind){case"apiKey":return{"x-api-key":z.apiKey};case"session":return{cookie:z.cookie};case"bearer":return{authorization:`Bearer ${z.token}`}}}function bl(z){return z?{"X-Organization-Id":z}:{}}function yi(z,J){return{...vl(z),...bl(J)}}function kl(z){if(typeof z!=="object"||z===null)return null;let{error:J}=z;return typeof J==="string"?J:null}class Ke extends Error{status;body;requestId;method;url;constructor(z,J){super(z);this.name=new.target.name,this.status=J.status,this.body=J.body,this.requestId=J.requestId??null,this.method=J.method,this.url=J.url}}class nn extends Ke{issues;constructor(z,J,V){super(z,J);this.issues=V}}class Sn extends Ke{}class At extends Ke{}class xn extends Ke{}class Rt extends Ke{}class Ot extends Ke{}class Nt extends Ke{retryAfter;constructor(z,J,V){super(z,J);this.retryAfter=V}}class jn extends Ke{}class Ft extends Ke{}class it extends Error{method;url;constructor(z,J){super(z,{cause:J.cause});this.name="HlixTransportError",this.method=J.method,this.url=J.url}}function Sl(z){if(typeof z!=="object"||z===null)return null;let J=z;if(J.success!==!1)return null;let V=J.error?.message;if(typeof V!=="string")return null;try{let X=JSON.parse(V);return Array.isArray(X)?X:[]}catch{return[]}}function xl(z){let J=z.get("retry-after");if(!J)return null;let V=Number(J);return Number.isFinite(V)&&V>=0?V:null}function Lt(z,J,V){let X={status:z.status,body:J,requestId:z.headers.get("x-request-id"),method:V.method,url:V.url},Y=kl(J),Z=`${V.method} ${V.url} failed with ${z.status}`,Q=Sl(J);if(Q)return new nn(`${V.method} ${V.url}: request body failed validation`,X,Q);let ee=Y??Z;switch(z.status){case 400:return new Sn(ee,X);case 401:return new At(ee,X);case 403:return new xn(ee,X);case 404:return new Rt(ee,X);case 409:return new Ot(ee,X);case 429:return new Nt(ee,X,xl(z.headers));case 501:return new jn(ee,X);default:return z.status>=500?new Ft(ee,X):new Ke(ee,X)}}var wi=new Set(["GET","HEAD","PUT","DELETE","OPTIONS","TRACE"]);function or(z){return wi.has(z.toUpperCase())}var jl=new Set([429,500,502,503,504]);function El(z){return jl.has(z)}var Qr={attempts:3,baseDelayMs:200,maxDelayMs:5000};function En(z,J,V,X=Math.random){if(V!==null)return Math.min(V*1000,J.maxDelayMs);let Y=Math.min(J.baseDelayMs*2**z,J.maxDelayMs);return Math.round(X()*Y)}function eo(z){if(!or(z.method))return!1;if(z.attempt+1>=z.policy.attempts)return!1;return z.status===null||El(z.status)}var Pl=(z)=>new Promise((J)=>setTimeout(J,z));function Il(z){let J=z.headers.get("retry-after");if(!J)return null;let V=Number(J);return Number.isFinite(V)&&V>=0?V:null}function vi(z){let{base:J,policy:V}=z,X=z.sleep??Pl,Y=z.random??Math.random;return async(Z)=>{let Q=Z.method.toUpperCase(),ee=or(Q)?Z.clone():null;for(let te=0;;te+=1){let re=te===0?Z:ee.clone(),ne;try{ne=await J(re)}catch(se){if(!ee||!eo({method:Q,attempt:te,policy:V,status:null}))throw new it(`${Q} ${Z.url}: ${se instanceof Error?se.message:String(se)}`,{method:Q,url:Z.url,cause:se});await X(En(te,V,null,Y));continue}if(!eo({method:Q,attempt:te,policy:V,status:ne.status}))return ne;if(!ee)return ne;await X(En(te,V,Il(ne),Y))}}}function ye(z,J){if(z.response.ok)return z.data;throw Lt(z.response,z.error??z.data,J)}var Pn=(z)=>typeof z==="string"?z:"";function to(z){let J;try{J=JSON.parse(z)}catch{return null}if(typeof J!=="object"||J===null)return null;let V=J;switch(V.type){case"idle":return{type:"idle"};case"done":return{type:"done"};case"active":return typeof V.runId==="string"?{type:"active",runId:V.runId}:{type:"active"};case"on_chat_model_stream":return{type:"on_chat_model_stream",delta:Pn(V.delta)};case"reasoning":return{type:"reasoning",delta:Pn(V.delta)};case"on_tool_start":return{type:"on_tool_start",name:Pn(V.name),input:V.input};case"on_tool_end":return{type:"on_tool_end",name:Pn(V.name),output:V.output};case"error":return{type:"error",message:Pn(V.message)};default:return null}}var no=(z)=>z.type==="done"||z.type==="idle"||z.type==="error";var _l=()=>({event:null,data:[],id:null,retry:null});function bi(z,J,V){switch(J){case"event":z.event=V;return;case"data":z.data.push(V);return;case"id":if(!V.includes("\x00"))z.id=V;return;case"retry":{if(/^\d+$/.test(V))z.retry=Number(V);return}default:return}}function Si(z){let J=z.data.join(`
|
|
3
|
-
`),{event:V,id:X}=z;if(z.data=[],z.event=null,J==="")return null;return{event:V,data:J,id:X,retry:z.retry}}function ki(z,J){if(J==="")return Si(z);if(J.startsWith(":"))return null;let V=J.indexOf(":");if(V===-1)return bi(z,J,""),null;let X=J.slice(0,V),Y=J.slice(V+1);if(Y.startsWith(" "))Y=Y.slice(1);return bi(z,X,Y),null}function Cl(z){let J=[],V=0;for(let X=0;X<z.length;X+=1){let Y=z[X];if(Y!==`
|
|
4
|
-
`&&Y!=="\r")continue;if(J.push(z.slice(V,X)),Y==="\r"&&z[X+1]===`
|
|
5
|
-
`)X+=1;V=X+1}return{lines:J,rest:z.slice(V)}}async function*sr(z,J){let V=z.getReader(),X=new TextDecoder,Y=_l(),Z="",Q=()=>void V.cancel().catch(()=>{});J?.addEventListener("abort",Q,{once:!0});try{for(;;){let{done:te,value:re}=await V.read();if(te)break;Z+=X.decode(re,{stream:!0});let{lines:ne,rest:se}=Cl(Z);Z=se;for(let ie of ne){let pe=ki(Y,ie);if(pe)yield pe}if(J?.aborted)return}if(Z+=X.decode(),Z!==""){let te=ki(Y,Z);if(te)yield te}let ee=Si(Y);if(ee)yield ee}finally{J?.removeEventListener("abort",Q),V.releaseLock()}}function at(z,J){return new Promise((V)=>{if(J?.aborted)return V();let X=setTimeout(Y,z);function Y(){clearTimeout(X),J?.removeEventListener("abort",Y),V()}J?.addEventListener("abort",Y,{once:!0})})}var oo=()=>crypto.randomUUID();function Ei(z){return{threadId:z.threadId,runId:z.runId??oo(),state:{},messages:[{id:z.messageId??oo(),role:"user",content:z.text}],tools:[],context:[],forwardedProps:z.forwardedProps??{}}}function Pi(z,J){return{threadId:z,runId:oo(),state:{},messages:[],tools:[],context:[],...J?{lastSeenEventId:J}:{}}}function so(z){let J=z.metadata;if(typeof J!=="object"||J===null)return;let V=J.eventId;return typeof V==="string"&&V?V:void 0}function io(z){let J;try{J=JSON.parse(z)}catch{return null}if(typeof J!=="object"||J===null)return null;return typeof J.type==="string"?J:null}function Ht(z,J={}){if(J.taskId)return`project:${z}:task:${J.taskId}`;if(J.cycleId)return`project:${z}:cycle:${J.cycleId}`;return`project:${z}`}var $l=new Set(["done","merged","failed","pr_created","ci_passing"]),Tl=new Set(["done","pr_created","failed","canceled"]);function ao(z,J){let V=z.tasks.find((Q)=>Q.id===J);if(!V)return{state:"running",task:V};let X=V.cycleId?z.cycles.find((Q)=>Q.id===V.cycleId):void 0;if(!(!V.cycleId||X!==void 0&&Tl.has(X.status)))return{state:"running",task:V};if($l.has(V.status))return{state:"finished",task:V};if(!X)return{state:"running",task:V};let Z=X?.status==="canceled"?"Task cycle was canceled":X?.status==="failed"?"Task cycle failed":"Task cycle ended before this task completed";return{state:"unmet",task:V,reason:Z}}async function*co(z){let J;for await(let V of z){if(V.type==="STATE_SNAPSHOT")J=structuredClone(V.snapshot);else if(V.type==="STATE_DELTA"){if(J===void 0)continue;J=Ii(J,V.delta)}else if(V.type!=="CUSTOM"||J===void 0)continue;yield{state:J,event:V}}}function lo(z){if(z==="")return[];if(!z.startsWith("/"))throw Error(`Invalid JSON pointer: ${z}`);return z.slice(1).split("/").map((J)=>J.replace(/~1/g,"/").replace(/~0/g,"~"))}function po(z,J){let V=z;for(let X of J.slice(0,-1)){if(typeof V!=="object"||V===null)throw Error(`Path not found: /${J.join("/")}`);V=V[X]}if(typeof V!=="object"||V===null)throw Error(`Path not found: /${J.join("/")}`);return{parent:V,key:J[J.length-1]}}function ir(z,J,V){if(J==="-"&&V)return z.length;let X=Number(J);if(!/^(0|[1-9]\d*)$/.test(J)||X>z.length||!V&&X===z.length)throw Error(`Invalid array index: ${J}`);return X}function xi(z,J){let V=lo(J);if(V.length===0)return z;let{parent:X,key:Y}=po(z,V);if(Array.isArray(X))return X[ir(X,Y,!1)];if(!(Y in X))throw Error(`Path not found: ${J}`);return X[Y]}function ji(z,J){let{parent:V,key:X}=po(z,lo(J));if(Array.isArray(V))return V.splice(ir(V,X,!1),1)[0];if(!(X in V))throw Error(`Path not found: ${J}`);let Y=V[X];return delete V[X],Y}function ro(z,J,V,X){let Y=lo(J);if(Y.length===0)return V;let{parent:Z,key:Q}=po(z,Y);if(Array.isArray(Z))if(X==="add")Z.splice(ir(Z,Q,!0),0,V);else Z[ir(Z,Q,!1)]=V;else{if(X==="replace"&&!(Q in Z))throw Error(`Path not found: ${J}`);Z[Q]=V}return z}function Ii(z,J){let V=structuredClone(z);for(let X of J)switch(X.op){case"add":case"replace":V=ro(V,X.path,structuredClone(X.value),X.op);break;case"remove":ji(V,X.path);break;case"copy":V=ro(V,X.path,structuredClone(xi(V,X.from)),"add");break;case"move":{let Y=ji(V,X.from);V=ro(V,X.path,Y,"add");break}case"test":if(JSON.stringify(xi(V,X.path))!==JSON.stringify(X.value))throw Error(`Test failed at ${X.path}`);break;default:throw Error(`Unknown patch operation: ${X.op}`)}return V}var Al="urn:ietf:params:oauth:grant-type:device_code",Rl="/v1/api/auth/device";class ct extends Error{reason;constructor(z,J){super(J);this.name="HlixDeviceLoginError",this.reason=z}}var ar=()=>new ct("cancelled","Login cancelled."),In=()=>new ct("expired","The login code expired. Run the login again.");function Ol(z,J){let V=new AbortController,X=[z,J].map((Y)=>{let Z=()=>V.abort(Y.reason);if(Y.aborted)V.abort(Y.reason);else Y.addEventListener("abort",Z,{once:!0});return()=>Y.removeEventListener("abort",Z)});return{signal:V.signal,release:()=>X.forEach((Y)=>Y())}}async function $i(z,J,V,X){if(!X||!z.signal)return _i(z,J,V,X,X??z.signal);let Y=Ol(z.signal,X);try{return await _i(z,J,V,X,Y.signal)}finally{Y.release()}}async function _i(z,J,V,X,Y){let Z=`${z.baseUrl.replace(/\/+$/,"")}${Rl}/${J}`,Q=z.fetch??((re)=>globalThis.fetch(re)),ee;try{ee=await Q(new Request(Z,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(V),...Y?{signal:Y}:{}}))}catch(re){if(z.signal?.aborted)throw ar();if(X?.aborted)throw In();throw new it(`POST ${Z}: ${re instanceof Error?re.message:String(re)}`,{method:"POST",url:Z,cause:re})}let te=await ee.json().catch(()=>null);if(z.signal?.aborted)throw ar();if(X?.aborted&&!te)throw In();return{ok:ee.ok,json:te??{}}}function Ci(z){try{let J=new URL(z);return J.protocol==="https:"||J.protocol==="http:"?J.href:null}catch{return null}}var et=(z)=>typeof z==="string"?z:"";async function uo(z){let{ok:J,json:V}=await $i(z,"code",{client_id:z.clientId});if(!J||!et(V.device_code)||!et(V.user_code))throw new ct("rejected",et(V.error_description)||et(V.error)||"The server would not start a browser login.");let X=Ci(et(V.verification_uri)),Y=et(V.verification_uri_complete)?Ci(et(V.verification_uri_complete)):X;if(!X||!Y)throw new ct("rejected","The server's sign-in page is not a web address.");return{deviceCode:et(V.device_code),userCode:et(V.user_code),verificationUri:X,verificationUriComplete:Y,expiresInSeconds:Number(V.expires_in)||600,intervalSeconds:Number(V.interval)||5}}async function mo(z){let J=z.sleep??at,V=z.now??Date.now,X=V()+z.code.expiresInSeconds*1000,Y=z.code.intervalSeconds*1000;for(;;){if(z.signal?.aborted)throw ar();if(V()>=X)throw In();if(await J(Y,z.signal),z.signal?.aborted)throw ar();let Z=X-V();if(Z<=0)throw In();let{ok:Q,json:ee}=await $i(z,"token",{grant_type:Al,device_code:z.code.deviceCode,client_id:z.clientId},AbortSignal.timeout(Z)),te=et(ee.access_token);if(Q&&te)return te;let re=et(ee.error);if(re==="authorization_pending")continue;if(re==="slow_down"){Y+=5000;continue}if(re==="access_denied")throw new ct("denied","The login was denied in the browser.");if(re==="expired_token")throw In();throw new ct("rejected",et(ee.error_description)||re||"The browser login failed.")}}var Nl={attempts:6,baseDelayMs:500,maxDelayMs:15000};function Fl(z){if(z instanceof Ft||z instanceof Nt)return!0;return!(z instanceof Ke)}class Mt{raw;baseUrl;headers;fetcher;constructor(z){this.baseUrl=z.baseUrl.replace(/\/+$/,"");let J=yi(z.credential,z.organizationId),V=new Set(Object.keys(J).map((Z)=>Z.toLowerCase()));this.headers={...Object.fromEntries(Object.entries(z.headers??{}).filter(([Z])=>!V.has(Z.toLowerCase()))),...J};let X={...Qr,...z.retry},Y=z.fetch??((Z)=>globalThis.fetch(Z));this.fetcher=vi({base:Y,policy:X}),this.raw=Zr({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(z,J){return{method:z,url:`${this.baseUrl}${J}`}}workspaces={list:async(z={})=>ye(await this.raw.GET("/v1/api/workspaces",z),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>ye(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(z,J={})=>ye(await this.raw.GET("/v1/api/projects/{id}",{...J,params:{path:{id:z}}}),this.at("GET",`/v1/api/projects/${z}`)),create:async(z)=>ye(await this.raw.POST("/v1/api/projects",{body:z}),this.at("POST","/v1/api/projects")),update:async(z,J)=>ye(await this.raw.PATCH("/v1/api/projects/{id}",{params:{path:{id:z}},body:J}),this.at("PATCH",`/v1/api/projects/${z}`)),delete:async(z)=>ye(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:z}}}),this.at("DELETE",`/v1/api/projects/${z}`)),start:async(z,J)=>ye(await this.raw.POST("/v1/api/projects/{id}/start",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/projects/${z}/start`)),stop:async(z)=>ye(await this.raw.POST("/v1/api/projects/{id}/stop",{params:{path:{id:z}}}),this.at("POST",`/v1/api/projects/${z}/stop`)),resume:async(z)=>ye(await this.raw.POST("/v1/api/projects/{id}/resume",{params:{path:{id:z}}}),this.at("POST",`/v1/api/projects/${z}/resume`)),status:async(z,J={})=>ye(await this.raw.GET("/v1/api/projects/{id}/status",{...J,params:{path:{id:z}}}),this.at("GET",`/v1/api/projects/${z}/status`)),canvas:{view:async(z)=>ye(await this.raw.GET("/v1/api/projects/{id}/canvas/agent",{params:{path:{id:z}}}),this.at("GET",`/v1/api/projects/${z}/canvas/agent`)),apply:async(z,J,V)=>ye(await this.raw.POST("/v1/api/projects/{id}/canvas/agent/ops",{params:{path:{id:z}},body:{ops:J,...V?{reason:V}:{}}}),this.at("POST",`/v1/api/projects/${z}/canvas/agent/ops`)),undo:async(z)=>ye(await this.raw.POST("/v1/api/projects/{id}/canvas/agent/undo",{params:{path:{id:z}}}),this.at("POST",`/v1/api/projects/${z}/canvas/agent/undo`))},deliver:async(z)=>ye(await this.raw.POST("/v1/api/projects/{id}/delivery",{params:{path:{id:z}}}),this.at("POST",`/v1/api/projects/${z}/delivery`)),attachGithubRepository:async(z,J)=>ye(await this.raw.POST("/v1/api/projects/{id}/repos/github",{params:{path:{id:z}},body:{githubRepository:J}}),this.at("POST",`/v1/api/projects/${z}/repos/github`)),terminal:async(z)=>ye(await this.raw.GET("/v1/api/projects/{id}/terminal",{params:{path:{id:z}}}),this.at("GET",`/v1/api/projects/${z}/terminal`)),observeCycle:(z,J)=>this.observeCycle(z,J),workspace:(z)=>({environment:async()=>ye(await this.raw.GET("/v1/api/projects/{id}/environment",{params:{path:{id:z}}}),this.at("GET",`/v1/api/projects/${z}/environment`)),fs:async(J)=>ye(await this.raw.POST("/v1/api/projects/{id}/workspace/fs",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/projects/${z}/workspace/fs`)),exec:async(J)=>ye(await this.raw.POST("/v1/api/projects/{id}/workspace/exec",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/projects/${z}/workspace/exec`))})};secrets={listEntries:async(z)=>ye(await this.raw.GET("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:z}}}),this.at("GET",`/v1/api/secrets/project/${z}/entries`)),upsertEntries:async(z,J)=>ye(await this.raw.PUT("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:z}},body:J}),this.at("PUT",`/v1/api/secrets/project/${z}/entries`)),importFiles:async(z,J)=>ye(await this.raw.PUT("/v1/api/secrets/project/{projectId}/files",{params:{path:{projectId:z}},body:{files:J}}),this.at("PUT",`/v1/api/secrets/project/${z}/files`)),deleteEntry:async(z,J,V)=>ye(await this.raw.DELETE("/v1/api/secrets/project/{projectId}/entries/{key}",{params:{path:{projectId:z,key:J},...V===void 0?{}:{query:{source:V}}}}),this.at("DELETE",`/v1/api/secrets/project/${z}/entries/${encodeURIComponent(J)}`)),exportEntries:async(z,J={})=>{let V=`/v1/api/secrets/project/${z}/export`,X=`${this.baseUrl}${V}`,Y=await this.fetcher(new Request(X,{method:"POST",headers:{...this.headers,"content-type":"application/json"},body:JSON.stringify({...J.source===void 0?{}:{source:J.source},...J.format===void 0?{}:{format:J.format}})}));if(!Y.ok)throw Lt(Y,await Y.json().catch(()=>{return}),{method:"POST",url:X});return Y.text()}};repos={access:async(z,J,V="read")=>ye(await this.raw.POST("/v1/api/projects/{id}/repos/{repoId}/access",{params:{path:{id:z,repoId:J}},body:{scope:V}}),this.at("POST",`/v1/api/projects/${z}/repos/${J}/access`)),head:async(z,J,V={})=>ye(await this.raw.GET("/v1/api/projects/{id}/repos/{repoId}/head",{...V,params:{path:{id:z,repoId:J}}}),this.at("GET",`/v1/api/projects/${z}/repos/${J}/head`)),protectedFiles:async(z)=>ye(await this.raw.GET("/v1/api/projects/{id}/protected-files",{params:{path:{id:z}}}),this.at("GET",`/v1/api/projects/${z}/protected-files`)),watch:(z,J,V={})=>this.watchRepo(z,J,V)};resources={importSkill:async(z,J)=>ye(await this.raw.POST("/v1/api/projects/{id}/resources/skill",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/projects/${z}/resources/skill`)),importAgent:async(z,J)=>ye(await this.raw.POST("/v1/api/projects/{id}/resources/agent",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/projects/${z}/resources/agent`)),importMcp:async(z,J)=>ye(await this.raw.POST("/v1/api/projects/{id}/resources/mcp",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/projects/${z}/resources/mcp`))};async throwUploadError(z,J){let V=null;try{V=await z.json()}catch{V=await z.text().catch(()=>null)}throw Lt(z,V,{method:"PUT",url:J})}tasks={list:async(z)=>ye(await this.raw.GET("/v1/api/tasks",{params:{query:z??{}}}),this.at("GET","/v1/api/tasks")),get:async(z)=>ye(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:z}}}),this.at("GET",`/v1/api/tasks/${z}`)),create:async(z)=>ye(await this.raw.POST("/v1/api/tasks",{body:z}),this.at("POST","/v1/api/tasks")),update:async(z,J)=>ye(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:z}},body:J}),this.at("PATCH",`/v1/api/tasks/${z}`)),listComments:async(z)=>ye(await this.raw.GET("/v1/api/tasks/{id}/comments",{params:{path:{id:z}}}),this.at("GET",`/v1/api/tasks/${z}/comments`)),addComment:async(z,J)=>ye(await this.raw.POST("/v1/api/tasks/{id}/comments",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/tasks/${z}/comments`))};modelConfig={list:async()=>ye(await this.raw.GET("/v1/api/model-config"),this.at("GET","/v1/api/model-config")),resolved:async(z)=>z?ye(await this.raw.GET("/v1/api/model-config/projects/{projectId}/resolved",{params:{path:{projectId:z}}}),this.at("GET",`/v1/api/model-config/projects/${z}/resolved`)):ye(await this.raw.GET("/v1/api/model-config/resolved"),this.at("GET","/v1/api/model-config/resolved")),set:async(z,J,V)=>V?ye(await this.raw.PUT("/v1/api/model-config/projects/{projectId}/{slot}",{params:{path:{projectId:V,slot:z}},body:J}),this.at("PUT",`/v1/api/model-config/projects/${V}/${z}`)):ye(await this.raw.PUT("/v1/api/model-config/{slot}",{params:{path:{slot:z}},body:J}),this.at("PUT",`/v1/api/model-config/${z}`)),clear:async(z,J)=>J?ye(await this.raw.DELETE("/v1/api/model-config/projects/{projectId}/{slot}",{params:{path:{projectId:J,slot:z}}}),this.at("DELETE",`/v1/api/model-config/projects/${J}/${z}`)):ye(await this.raw.DELETE("/v1/api/model-config/{slot}",{params:{path:{slot:z}}}),this.at("DELETE",`/v1/api/model-config/${z}`)),setProjectHarness:async(z,J)=>this.modelConfig.set("cycle",{harness:J},z),clearProjectHarness:async(z)=>this.modelConfig.clear("cycle",z),setHarness:async(z)=>this.modelConfig.set("cycle",{harness:z}),clearHarness:async()=>this.modelConfig.clear("cycle")};ai={models:async(z,J)=>ye(await this.raw.GET("/v1/api/ai/w/{workspaceId}/models",{params:{path:{workspaceId:z}},...J?.signal?{signal:J.signal}:{}}),this.at("GET",`/v1/api/ai/w/${z}/models`))};managedMailboxes={configuration:async()=>ye(await this.raw.GET("/v1/api/growth/managed-mailboxes/configuration",{}),this.at("GET","/v1/api/growth/managed-mailboxes/configuration")),quote:async(z)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/quotes",{body:z}),this.at("POST","/v1/api/growth/managed-mailboxes/quotes")),order:async(z)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/orders",{body:z}),this.at("POST","/v1/api/growth/managed-mailboxes/orders")),get:async(z)=>ye(await this.raw.GET("/v1/api/growth/managed-mailboxes/orders/{orderId}",{params:{path:{orderId:z}}}),this.at("GET","/v1/api/growth/managed-mailboxes/orders/{orderId}")),reconcile:async(z)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/orders/{orderId}/reconcile",{params:{path:{orderId:z}}}),this.at("POST","/v1/api/growth/managed-mailboxes/orders/{orderId}/reconcile")),listOrders:async(z)=>ye(await this.raw.GET("/v1/api/growth/managed-mailboxes/orders",{params:{query:{...z,limit:z?.limit===void 0?void 0:String(z.limit)}}}),this.at("GET","/v1/api/growth/managed-mailboxes/orders")),listResources:async(z)=>ye(await this.raw.GET("/v1/api/growth/managed-mailboxes/resources",{params:{query:{...z,limit:z?.limit===void 0?void 0:String(z.limit)}}}),this.at("GET","/v1/api/growth/managed-mailboxes/resources")),repair:async(z,J)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/repair",{params:{path:{resourceId:z}},body:J}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/repair")),cancelHosting:async(z,J)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-hosting",{params:{path:{resourceId:z}},body:J}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-hosting")),cancelWarmup:async(z,J)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-warmup",{params:{path:{resourceId:z}},body:J}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/cancel-warmup")),removeDomain:async(z,J)=>ye(await this.raw.POST("/v1/api/growth/managed-mailboxes/resources/{resourceId}/remove-domain",{params:{path:{resourceId:z}},body:J}),this.at("POST","/v1/api/growth/managed-mailboxes/resources/{resourceId}/remove-domain"))};mcpServers={list:async()=>ye(await this.raw.GET("/v1/api/mcp-servers",{}),this.at("GET","/v1/api/mcp-servers")),get:async(z)=>ye(await this.raw.GET("/v1/api/mcp-servers/{id}",{params:{path:{id:z}}}),this.at("GET",`/v1/api/mcp-servers/${z}`)),create:async(z)=>ye(await this.raw.POST("/v1/api/mcp-servers",{body:z}),this.at("POST","/v1/api/mcp-servers")),update:async(z,J)=>ye(await this.raw.PATCH("/v1/api/mcp-servers/{id}",{params:{path:{id:z}},body:J}),this.at("PATCH",`/v1/api/mcp-servers/${z}`)),delete:async(z)=>ye(await this.raw.DELETE("/v1/api/mcp-servers/{id}",{params:{path:{id:z}}}),this.at("DELETE",`/v1/api/mcp-servers/${z}`)),discover:async(z)=>ye(await this.raw.POST("/v1/api/mcp-servers/{id}/discover",{params:{path:{id:z}}}),this.at("POST",`/v1/api/mcp-servers/${z}/discover`)),connect:async(z)=>ye(await this.raw.POST("/v1/api/mcp-servers/{id}/connect",{params:{path:{id:z}}}),this.at("POST",`/v1/api/mcp-servers/${z}/connect`)),disconnect:async(z)=>ye(await this.raw.POST("/v1/api/mcp-servers/{id}/disconnect",{params:{path:{id:z}}}),this.at("POST",`/v1/api/mcp-servers/${z}/disconnect`))};tools={search:async(z)=>ye(await this.raw.GET("/v1/api/tools",{params:{query:{...z,limit:z?.limit===void 0?void 0:String(z.limit)}}}),this.at("GET","/v1/api/tools")),describe:async(z)=>ye(await this.raw.GET("/v1/api/tools/{toolId}",{params:{path:{toolId:z}}}),this.at("GET",`/v1/api/tools/${z}`)),call:async(z,J)=>ye(await this.raw.POST("/v1/api/tools/{toolId}/call",{params:{path:{toolId:z}},body:J}),this.at("POST",`/v1/api/tools/${z}/call`)),status:async(z)=>ye(await this.raw.GET("/v1/api/tool-calls/{callId}",{params:{path:{callId:z}}}),this.at("GET",`/v1/api/tool-calls/${z}`)),listCalls:async(z)=>ye(await this.raw.GET("/v1/api/tool-calls",{params:{query:{...z,limit:z?.limit===void 0?void 0:String(z.limit)}}}),this.at("GET","/v1/api/tool-calls"))};cycles={list:async(z)=>ye(await this.raw.GET("/v1/api/cycles",{params:{query:z??{}}}),this.at("GET","/v1/api/cycles")),get:async(z)=>ye(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:z}}}),this.at("GET",`/v1/api/cycles/${z}`)),propose:async(z)=>ye(await this.raw.POST("/v1/api/cycles",{body:z}),this.at("POST","/v1/api/cycles")),review:async(z)=>ye(await this.raw.GET("/v1/api/cycles/{id}/review",{params:{path:{id:z}}}),this.at("GET",`/v1/api/cycles/${z}/review`)),reviewComments:async(z)=>ye(await this.raw.GET("/v1/api/cycles/{id}/review/comments",{params:{path:{id:z}}}),this.at("GET",`/v1/api/cycles/${z}/review/comments`))};chat={send:async(z)=>ye(await this.raw.POST("/v1/api/chat/turns",{body:z}),this.at("POST","/v1/api/chat/turns")),turn:async(z,J)=>ye(await this.raw.GET("/v1/api/chat/turns/{turnId}",{params:{path:{turnId:z},query:J}}),this.at("GET",`/v1/api/chat/turns/${z}`))};live={run:(z,J,V)=>this.liveStream(`/agent/${z}/run`,Ei(J),V),connect:(z,J,V)=>this.liveStream(`/agent/${z}/connect`,Pi(J,V?.lastSeenEventId),V),follow:(z,J,V={})=>this.followLive(z,J,V),stop:async(z,J,V)=>{let X=`/agent/${z}/stop/${encodeURIComponent(J)}`;return await(await this.livePost(X,V?{runId:V}:{})).json()},project:(z,J={})=>co(this.live.follow("project-live",Ht(z,J),J)),task:(z,J,V={})=>this.watchTask(z,J,V)};async*watchTask(z,J,V){let X="";for await(let{state:Y}of this.live.project(z,{taskId:J,...V})){let Z=ao(Y,J),Q=JSON.stringify(Z);if(Q===X)continue;if(X=Q,yield Z,Z.state!=="running")return}}async*followLive(z,J,V){let X=V.retry??Nl,Y=V.lastSeenEventId,Z=0;while(!V.signal?.aborted){let Q=!1,ee=null;try{for await(let te of this.live.connect(z,J,{...V.signal?{signal:V.signal}:{},...Y?{lastSeenEventId:Y}:{}})){let re=so(te);if(re)Y=re;if(te.type!=="STATE_SNAPSHOT"&&te.type!=="MESSAGES_SNAPSHOT")Z=0;if(te.type==="RUN_STARTED"||te.type==="STATE_SNAPSHOT"||re)Q=!0;if(yield te,te.type==="RUN_FINISHED"||te.type==="RUN_ERROR")return}if(!Q)return}catch(te){if(V.signal?.aborted)return;if(!Fl(te))throw te;ee=te}if(V.signal?.aborted)return;if(Z+=1,Z>=X.attempts)throw ee??new it(`POST ${this.baseUrl}/v1/api/live/agent/${z}/connect: the stream kept closing`,{method:"POST",url:`${this.baseUrl}/v1/api/live/agent/${z}/connect`});await at(En(Z,X,null),V.signal)}}async livePost(z,J,V){let X=`${this.baseUrl}/v1/api/live${z}`,Y=await this.fetcher(new Request(X,{method:"POST",headers:{...this.headers,"content-type":"application/json",accept:"text/event-stream"},body:JSON.stringify(J),signal:V?.signal}));if(Y.ok)return Y;let Z=null;try{Z=await Y.json()}catch{Z=null}throw Lt(Y,Z,{method:"POST",url:X})}async*liveStream(z,J,V){let X=await this.livePost(z,J,V);if(!X.body)return;try{for await(let Y of sr(X.body,V?.signal)){let Z=io(Y.data);if(!Z)continue;if(yield Z,Z.type==="RUN_FINISHED"||Z.type==="RUN_ERROR")return}}finally{X.body.cancel().catch(()=>{})}}pendingRequests={list:async(z)=>ye(await this.raw.GET("/v1/api/pending-requests",{params:{query:z??{}}}),this.at("GET","/v1/api/pending-requests")),resolve:async(z,J)=>ye(await this.raw.POST("/v1/api/pending-requests/{id}/resolve",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/pending-requests/${z}/resolve`))};clientInvoices={list:async(z)=>ye(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:z??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(z)=>ye(await this.raw.GET("/v1/api/client-billing/invoices/{id}",{params:{path:{id:z}}}),this.at("GET",`/v1/api/client-billing/invoices/${z}`)),createDraft:async(z)=>ye(await this.raw.POST("/v1/api/client-billing/invoices",{body:z}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(z)=>ye(await this.raw.POST("/v1/api/client-billing/invoices/{id}/issue",{params:{path:{id:z}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${z}/issue`)),void:async(z,J)=>ye(await this.raw.POST("/v1/api/client-billing/invoices/{id}/void",{params:{path:{id:z}},body:{reason:J}}),this.at("POST",`/v1/api/client-billing/invoices/${z}/void`)),pay:async(z)=>ye(await this.raw.POST("/v1/api/client-billing/invoices/{id}/pay",{params:{path:{id:z}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${z}/pay`)),paymentLink:async(z,J={})=>ye(await this.raw.POST("/v1/api/client-billing/invoices/{id}/payment-link",{params:{path:{id:z}},body:J}),this.at("POST",`/v1/api/client-billing/invoices/${z}/payment-link`))};async*observeCycle(z,J){let V=`/v1/api/cycles/${z}/observe`;for await(let X of this.stream(V,J)){let Y=to(X.data);if(!Y)continue;if(yield Y,no(Y))return}}async*watchRepo(z,J,V){let X;while(!V.signal?.aborted){let Y=await this.repos.head(z,J,V);if(Y.commitSha!==X)X=Y.commitSha,yield{commitSha:X};await at(15000,V.signal)}}async*stream(z,J){let V=`${this.baseUrl}${z}`,X=new Request(V,{headers:{...this.headers,accept:"text/event-stream"},signal:J?.signal}),Y=await globalThis.fetch(X);if(!Y.ok||!Y.body){let Z=null;try{Z=await Y.json()}catch{Z=null}throw Lt(Y,Z,{method:"GET",url:V})}yield*sr(Y.body,J?.signal)}}class e extends Error{code;details;constructor(z,J,V){super(J);if(this.name="CliError",this.code=z,V!==void 0)this.details=V}}import{spawn as Jd}from"node:child_process";import{closeSync as fo,constants as _n,existsSync as cr,fsyncSync as Ti,lstatSync as go,mkdirSync as Ll,openSync as Ai,readFileSync as Ri,renameSync as Hl,statSync as Oi,unlinkSync as Ni,writeFileSync as Ml}from"node:fs";import{homedir as Dl}from"node:os";import{dirname as Ul,join as ho}from"node:path";var rn="https://server.hlix.ai";function lt(z=process.env){let J=z.HLIX_CONFIG_HOME??z.XDG_CONFIG_HOME??ho(Dl(),".config");return ho(J,"hlix","credentials.json")}function v(z=process.env){let J=z.HLIX_API_KEY;if(!J&&z.HLIX_SESSION_TOKEN)return{baseUrl:z.HLIX_BASE_URL??rn,apiKey:"",sessionToken:z.HLIX_SESSION_TOKEN,...z.HLIX_WORKSPACE_ID?{organizationId:z.HLIX_WORKSPACE_ID}:{}};if(J)return{baseUrl:z.HLIX_BASE_URL??rn,apiKey:J,...z.HLIX_WORKSPACE_ID?{organizationId:z.HLIX_WORKSPACE_ID}:{}};try{let V=JSON.parse(Ri(lt(z),"utf8"));return(V.apiKey||V.sessionToken)&&V.baseUrl?V:null}catch{return null}}function Fi(z=process.env){let J=lt(z);return cr(J)?J:null}function yo(z=process.env){let J=lt(z);if(!cr(J))return{path:J,removed:!1,reason:"absent"};let V=go(J);if(V.isSymbolicLink()||!V.isFile())throw Error("Refusing to remove a credential path that is not a regular file.");let X=process.getuid?.();if(X!==void 0&&Oi(J).uid!==X)throw Error("Refusing to remove a credential file owned by another user.");let Y;try{Y=JSON.parse(Ri(J,"utf8"))}catch{Y=null}let Z=Y;if(!Z||typeof Z.apiKey!=="string"||typeof Z.baseUrl!=="string")throw Error(`Refusing to remove ${J}: it is not a credential written by this CLI.`);return Ni(J),{path:J,removed:!0,reason:"removed"}}function Li(z,J=process.env){let V=lt(J),X=Ul(V);if(Ll(X,{recursive:!0,mode:448}),go(X).isSymbolicLink())throw Error("Refusing to write credentials through a symlinked directory.");if(cr(V)){let Q=go(V);if(Q.isSymbolicLink()||!Q.isFile())throw Error("Refusing to replace a credential path that is not a regular file.");let ee=process.getuid?.();if(ee!==void 0&&Oi(V).uid!==ee)throw Error("Refusing to replace a credential file owned by another user.")}let Y=ho(X,`.credentials.${process.pid}.${crypto.randomUUID()}.tmp`),Z;try{Z=Ai(Y,_n.O_WRONLY|_n.O_CREAT|_n.O_EXCL|_n.O_NOFOLLOW,384),Ml(Z,`${JSON.stringify(z,null,2)}
|
|
6
|
-
`,"utf8"),Ti(Z),fo(Z),Z=void 0,Hl(Y,V);let Q=Ai(X,_n.O_RDONLY);try{try{Ti(Q)}catch(ee){let te=ee.code;if(te!=="EINVAL"&&te!=="ENOTSUP")throw ee}}finally{fo(Q)}}catch(Q){if(Z!==void 0)fo(Z);if(cr(Y))Ni(Y);throw Q}return V}import{statSync as Md}from"node:fs";import{dirname as aa,resolve as ca}from"node:path";import{createHash as $d}from"node:crypto";import{existsSync as To,lstatSync as Td,readFileSync as na,statSync as Ad,writeFileSync as Ao}from"node:fs";import{readFile as Rd}from"node:fs/promises";import{join as Gt}from"node:path";import{parseAllDocuments as hd,stringify as yd,visit as Vi}from"yaml";import{z as be}from"zod";var wo={"claude-fable-5-1":{provider:"anthropic",contextWindow:1e6,displayName:"Fable 5.1",tier:"frontier"},"claude-opus-5":{provider:"anthropic",contextWindow:1e6,displayName:"Opus 5",tier:"frontier"},"claude-sonnet-5":{provider:"anthropic",contextWindow:1e6,displayName:"Sonnet 5",tier:"primary"},"claude-haiku-4-5":{provider:"anthropic",contextWindow:200000,displayName:"Haiku 4.5",tier:"fast"},"gpt-6-astra":{provider:"openai",contextWindow:1050000,displayName:"GPT-6 Astra",tier:"frontier"},"gpt-5.6-sol":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Sol",tier:"frontier"},"gpt-5.6-terra":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Terra",tier:"primary"},"gpt-5.6-luna":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Luna",tier:"fast"},"jev-latest":{provider:"openrouter",contextWindow:32000,displayName:"Decision Model",tier:"fast",picker:!1},"gemini-3.8-flash":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini 3.8 Flash",tier:"fast"},"gemini-embedding-2":{provider:"google_genai",contextWindow:8192,displayName:"Gemini Embedding 2",tier:"embedding",picker:!1},"grok-4.6":{provider:"openrouter",contextWindow:500000,displayName:"Grok 4.6",tier:"frontier"},"kimi-k3":{provider:"openrouter",contextWindow:1048576,displayName:"Kimi K3",tier:"primary"},"deepseek-v4-pro":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek V4 Pro",tier:"primary"},"deepseek-v4.1-flash":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek V4.1 Flash",tier:"fast"},"glm-5.3":{provider:"openrouter",contextWindow:1310720,displayName:"GLM 5.3",tier:"primary"},"glm-5.3-flash":{provider:"openrouter",contextWindow:1310720,displayName:"GLM 5.3 Flash",tier:"fast"},"qwen3.8-max":{provider:"openrouter",contextWindow:1e6,displayName:"Qwen 3.8 Max",tier:"primary"},"qwen3.8-flash":{provider:"openrouter",contextWindow:1e6,displayName:"Qwen 3.8 Flash",tier:"fast"},auto:{provider:"openrouter",contextWindow:2000000,displayName:"Auto",tier:"primary"},"pareto-code":{provider:"openrouter",contextWindow:2000000,displayName:"Auto for coding",tier:"primary"},"fable-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Fable (Latest)",tier:"frontier"},"opus-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Opus (Latest)",tier:"frontier"},"sonnet-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Sonnet (Latest)",tier:"primary"},"haiku-latest":{provider:"anthropic",contextWindow:200000,displayName:"Claude Haiku (Latest)",tier:"fast"},"gpt-latest":{provider:"openai",contextWindow:1050000,displayName:"GPT Astra (Latest)",tier:"frontier"},"grok-latest":{provider:"openrouter",contextWindow:500000,displayName:"Grok (Latest)",tier:"frontier"},"gemini-pro-latest":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini Pro (Latest)",tier:"primary"},"gemini-flash-latest":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini Flash (Latest)",tier:"fast"},"deepseek-pro-latest":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek Pro (Latest)",tier:"primary"},"deepseek-flash-latest":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek Flash (Latest)",tier:"fast"},"glm-latest":{provider:"openrouter",contextWindow:1310720,displayName:"GLM (Latest)",tier:"primary"},"glm-flash-latest":{provider:"openrouter",contextWindow:1310720,displayName:"GLM Flash (Latest)",tier:"fast"},"kimi-latest":{provider:"openrouter",contextWindow:1048576,displayName:"Kimi (Latest)",tier:"primary"},"whisper-1":{provider:"openrouter",contextWindow:0,displayName:"Whisper 1 (Speech-to-Text)",tier:"media",picker:!1},"voxtral-mini-tts":{provider:"openrouter",contextWindow:4096,displayName:"Voxtral Mini TTS (Text-to-Speech)",tier:"media",picker:!1},"seedream-4-5":{provider:"openrouter",contextWindow:4096,displayName:"Seedream 4.5 (Image)",tier:"media",picker:!1},"veo-3-1":{provider:"openrouter",contextWindow:0,displayName:"Veo 3.1 (Video)",tier:"media",picker:!1}},vo={"claude-code":"claude-sonnet-4-5",codex:"gpt-5.4"};var Wg=Object.keys(wo);var Gl={"jev-latest":"openrouter/~typesafe/jev-latest","claude-fable-5-1":"openrouter/anthropic/claude-fable-5.1","claude-opus-5":"openrouter/anthropic/claude-opus-5","claude-sonnet-5":"openrouter/anthropic/claude-sonnet-5","claude-haiku-4-5":"openrouter/anthropic/claude-haiku-4.5","gpt-6-astra":"openrouter/openai/gpt-6-astra","gpt-5.6-sol":"openrouter/openai/gpt-5.6-sol","gpt-5.6-terra":"openrouter/openai/gpt-5.6-terra","gpt-5.6-luna":"openrouter/openai/gpt-5.6-luna","gemini-3.8-flash":"openrouter/google/gemini-3.8-flash","gemini-embedding-2":"direct:google/gemini-embedding-2","grok-4.6":"openrouter/x-ai/grok-4.6","kimi-k3":"openrouter/moonshotai/kimi-k3","deepseek-v4-pro":"openrouter/deepseek/deepseek-v4-pro","deepseek-v4.1-flash":"openrouter/deepseek/deepseek-v4.1-flash","glm-5.3":"openrouter/z-ai/glm-5.3","glm-5.3-flash":"openrouter/z-ai/glm-5.3-flash","qwen3.8-max":"openrouter/qwen/qwen3.8-max-0902","qwen3.8-flash":"openrouter/qwen/qwen3.8-flash",auto:"openrouter/openrouter/auto","pareto-code":"openrouter/openrouter/pareto-code","fable-latest":"openrouter/~anthropic/claude-fable-latest","opus-latest":"openrouter/~anthropic/claude-opus-latest","sonnet-latest":"openrouter/~anthropic/claude-sonnet-latest","haiku-latest":"openrouter/~anthropic/claude-haiku-latest","gpt-latest":"openrouter/~openai/gpt-astra-latest","grok-latest":"openrouter/~x-ai/grok-latest","gemini-pro-latest":"openrouter/~google/gemini-pro-latest","gemini-flash-latest":"openrouter/~google/gemini-flash-latest","deepseek-pro-latest":"openrouter/~deepseek/deepseek-pro-latest","deepseek-flash-latest":"openrouter/~deepseek/deepseek-flash-latest","glm-latest":"openrouter/~z-ai/glm-latest","glm-flash-latest":"openrouter/~z-ai/glm-flash-latest","kimi-latest":"openrouter/~moonshotai/kimi-latest","whisper-1":"openrouter/openai/whisper-1","voxtral-mini-tts":"openrouter/mistralai/voxtral-mini-tts-2603","seedream-4-5":"openrouter/bytedance-seed/seedream-4.5","veo-3-1":"openrouter/google/veo-3.1"};var h="◆",Bl=(()=>{let z={};for(let J of Object.keys(wo)){let V=wo[J];z[J]=V.displayName,z[Gl[J]]=V.displayName,z[`${V.provider}:${J}`]=V.displayName}return z})();function j(z){if(!z)return z;let V=Bl[z]??z.split(/[/:]/).pop()??z;return`${h} ${V}`}var n={"claude-code":{id:"claude-code",localAccount:{command:"claude",args:["auth","status","--json"],fallback:"claude"},execution:{transport:"acp",sandboxKey:"claudeCode",command:"claude-agent-acp",args:[],oneshot:{command:"claude",args:["-p","--output-format","stream-json","--verbose","--dangerously-skip-permissions"],parser:"claude"},install:"npm i -g @agentclientprotocol/claude-agent-acp",auth:{envVars:["ANTHROPIC_API_KEY"]},models:{selection:"agent-config",modelEnv:"ANTHROPIC_MODEL",effort:!1},pricing:{model:vo["claude-code"],input:3,output:15,cachedRead:0.3,cachedWrite:3.75},where:["local","cloud"]},displayName:"Claude Code",description:"Anthropic coding CLI. Flagship, always installed.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:["ANTHROPIC_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0},"openai-agents":{id:"openai-agents",displayName:"OpenAI Agents SDK",description:"Model-agnostic agent SDK. Not yet available for running tasks.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:[],anyOf:["OPENAI_API_KEY","ANTHROPIC_API_KEY","GOOGLE_API_KEY","OPENROUTER_API_KEY"]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1},codex:{id:"codex",localAccount:{command:"codex",args:["login","status"],fallback:"codex"},execution:{transport:"acp",sandboxKey:"codex",command:"codex-acp",args:[],oneshot:{command:"codex",args:["exec","--json","--dangerously-bypass-approvals-and-sandbox","-"],parser:"codex"},env:{NO_BROWSER:"1"},install:"npm i -g @agentclientprotocol/codex-acp",auth:{envVars:["OPENAI_API_KEY"],method:"api-key"},models:{selection:"agent-config",modelEnv:"CODEX_MODEL",effort:!1},pricing:{model:vo.codex,input:2.5,output:15,cachedRead:0.25,cachedWrite:2.5},where:["local","cloud"]},displayName:"Codex",description:"OpenAI coding CLI. Installed on demand.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:["OPENAI_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0},aider:{id:"aider",localAccount:{command:"aider"},displayName:"Aider",description:"Model-agnostic coding CLI. Not yet available for running tasks.",driverKind:"external-acp",capabilities:["structured-result","model-select"],credentials:{required:[],anyOf:["OPENAI_API_KEY","ANTHROPIC_API_KEY","GOOGLE_API_KEY","OPENROUTER_API_KEY"]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1},gemini:{id:"gemini",localAccount:{command:"gemini",fallback:"gemini"},displayName:"Gemini CLI",localOnly:!0,description:"Verified local ACP adapter. Cloud provisioning is not enabled.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1,execution:{transport:"acp",sandboxKey:"gemini",command:"gemini",args:["--acp"],install:"npm i -g @google/gemini-cli",auth:{envVars:["GEMINI_API_KEY"],method:"gemini-api-key"},models:{selection:"agent-config",effort:!1},pricing:null,where:["local"]}},opencode:{id:"opencode",localAccount:{command:"opencode",args:["auth","list"]},displayName:"OpenCode",description:"SST's open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{localAvailable:!1,transport:"acp",sandboxKey:"opencode",command:"opencode",args:["acp"],install:"npm i -g opencode-ai",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["local","cloud"]}},goose:{id:"goose",localAccount:{command:"goose",fallback:"goose"},displayName:"Goose",description:"Block's open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{transport:"acp",sandboxKey:"goose",command:"goose",args:["acp"],install:"brew install block-goose-cli",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["local","cloud"]}},"qwen-code":{id:"qwen-code",displayName:"Qwen Code",description:"Qwen's open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{localAvailable:!1,transport:"acp",sandboxKey:"qwenCode",command:"qwen",args:["--acp","--auth-type","openai","--approval-mode","yolo"],install:"npm i -g @qwen-code/qwen-code",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["cloud"]}},pi:{id:"pi",displayName:"Pi",description:"Minimal open-source coding agent.",driverKind:"external-acp",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0,execution:{localAvailable:!1,transport:"acp",sandboxKey:"pi",command:"pi-acp",args:[],install:"npm i -g pi-acp @earendil-works/pi-coding-agent",auth:{envVars:[]},models:{selection:"agent-config",effort:!1},pricing:null,where:["cloud"]}},hlix:{id:"hlix",displayName:"Hlix",description:"Our own coding agent, built into hlix and run by the platform.",driverKind:"native",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"native-runner",version:1},modelSupport:{selection:"orchestration",effort:!1},available:!0}},lr=Object.keys(n).filter((z)=>!("localOnly"in n[z])),bo=Object.values(n).filter((z)=>!("localOnly"in z)),Kg=bo.filter(({driverKind:z})=>z==="external-acp").map(({id:z})=>z),Wl=bo.filter(({available:z,driverKind:J})=>z&&J==="external-acp"),Hi=Wl.map(({id:z})=>z),zl=bo.filter(({available:z})=>z),x=zl.map(({id:z})=>z),Mi="hlix";var y=Object.values(n).filter((z)=>("execution"in z)),l=y.map(({id:z})=>z);var Jl=/^[a-z0-9](?:[a-z0-9_-]{0,18}[a-z0-9])?$/,Kl=["main","master","develop","development","dev","staging","production","prod","release","preview","trunk","head"];function Di(z){return Jl.test(z)&&!Kl.includes(z)}import{z as ql}from"zod";var Ui=ql.enum(["small","standard","large"]);import{z as mt}from"zod";var Gi=mt.string().trim().max(200).regex(/^[^<>\x00-\x1f\x7f]*$/),Vl=mt.union([mt.literal(""),mt.email().max(254)]).transform((z)=>z.trim()),Qg=mt.object({gitName:Gi,gitEmail:Vl,hlixCoauthor:mt.boolean()}).strict(),Bi=mt.object({name:Gi.min(1),email:mt.email().max(254),hlixCoauthor:mt.boolean()}).strict();import{z as oe}from"zod";import{z as Te}from"zod";import{z as ft}from"zod";var Wi=ft.discriminatedUnion("phase",[ft.object({designId:ft.string().uuid(),phase:ft.literal("prototype"),revisionId:ft.string().uuid().optional()}),ft.object({designId:ft.string().uuid(),phase:ft.literal("implementation"),revisionId:ft.string().uuid()})]);var zi=Te.object({version:Te.literal(1),organizationId:Te.string().min(1),projectId:Te.string().min(1),cycleId:Te.string().min(1),taskId:Te.string().min(1),source:Te.string().nullable(),sourceRevision:Te.string().min(1),requestDigest:Te.string().regex(/^[a-f0-9]{64}$/),requestRevision:Te.number().int().min(1),sourceId:Te.string().nullable(),project:Te.object({name:Te.string(),stack:Te.string().nullable(),goal:Te.string()}),cycleGoal:Te.string(),designWork:Wi.optional(),taskGoal:Te.string(),requirements:Te.string(),implementationPlan:Te.string(),repo:Te.object({id:Te.string(),owner:Te.string().nullable(),name:Te.string().nullable(),cloneUrl:Te.string().nullable(),ref:Te.string()}).nullable(),prerequisite:Te.object({applicability:Te.enum(["application","tooling","unknown"]),sourceExcerpt:Te.string()}).optional(),checks:Te.array(Te.object({kind:Te.enum(["verification","startup"]),required:Te.literal(!0),command:Te.string().nullable(),executionDigest:Te.string().nullable(),port:Te.number().int().min(1).max(65535).nullable().optional(),source:Te.enum(["repo","project","runtime","candidate-discovery"])})).min(1)});import{z as Xl}from"zod";var ko=Xl.string().regex(/^op-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}-(0|[1-9][0-9]*)$/,"Invalid operation id");import{z as Ge}from"zod";var Yl=["queued","building","done","blocked"],Zl=["operator","engineer","review","platform"],ze={id:64,title:200,description:1000,note:280,feedback:1000,dependsOn:8,commit:40,source:8,updatedAt:40},Ji=100,Ql=ze.id+ze.title+ze.description+ze.note+ze.feedback+ze.dependsOn*ze.id+ze.commit+ze.source+ze.updatedAt,gt={maxItems:Ji,maxBytes:Ji*(Ql*6+1024)+1024,maxEngineerItems:50,titleChars:ze.title,descriptionChars:ze.description,feedbackChars:ze.feedback,noteChars:ze.note,maxDependsOn:ze.dependsOn},dr=/^[\w-]{1,64}$/;var Ki=Ge.object({id:Ge.string().regex(dr),title:Ge.string().min(1).max(gt.titleChars),description:Ge.string().max(gt.descriptionChars).default(""),status:Ge.enum(Yl),dependsOn:Ge.array(Ge.string().regex(dr)).max(gt.maxDependsOn).default([]),note:Ge.string().max(gt.noteChars).default(""),commit:Ge.string().regex(/^[a-f0-9]{40}$/).nullable().default(null),feedback:Ge.string().max(gt.feedbackChars).nullable().default(null),source:Ge.enum(Zl).default("operator"),updatedAt:Ge.string().max(ze.updatedAt).default("")}),lh=Ge.object({version:Ge.literal(1),cycleId:Ge.string().min(1),tasks:Ge.array(Ki).max(gt.maxItems)}),qi=Ki.partial({description:!0,dependsOn:!0,note:!0,commit:!0,feedback:!0,source:!0,updatedAt:!0}).extend({deleted:Ge.boolean().optional()});var ed=oe.enum(lr),td=oe.enum(["coder","reviewer","planner","setup"]),xo=oe.enum(Hi),So=oe.union([oe.string(),oe.number().transform(String)]),jo=oe.object({node:So.optional(),python:So.optional(),bun:So.optional(),playwright:oe.boolean().optional()}).catchall(oe.union([oe.string().min(1).max(200),oe.number().transform(String),oe.boolean()])).refine((z)=>Object.entries(z).every(([J,V])=>J==="playwright"||typeof V==="string"),"Tool versions must be strings"),Eo=oe.object({name:oe.enum(["mysql","postgres","redis"]),start:oe.string().max(1e4).optional(),ready:oe.string().max(1e4).optional(),stop:oe.string().max(1e4).optional()}),Sh=oe.object({startedAt:oe.string(),finishedAt:oe.string().optional(),status:oe.enum(["ok","partial"]),steps:oe.array(oe.object({name:oe.string(),status:oe.enum(["ok","fixed-by-override","failed"]),reason:oe.string().optional()}))}),Po=oe.object({agents:oe.array(xo).optional(),toolchain:jo.optional(),aptPackages:oe.array(oe.string()).optional(),setup:oe.string().optional(),services:oe.array(Eo).max(3).optional(),envOverrides:oe.record(oe.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),oe.string().max(1e4)).optional(),verifyCommand:oe.string().max(1e4).optional(),preview:oe.object({command:oe.string().min(1).max(1e4),port:oe.number().int().min(1024).max(65535)}).optional(),deployment:oe.discriminatedUnion("kind",[oe.object({repoId:oe.string().min(1),kind:oe.literal("static"),buildCommand:oe.string().trim().min(1).max(1e4),outDir:oe.string().min(1).max(2000).refine((z)=>/^(?!\/|[A-Za-z]:)(?!.*(?:^|\/)(?:\.\.?|\.env(?:\.[^/]*)?|\.git|\.hlix[^/]*|node_modules)(?:\/|$))[^\\\x00-\x1f\x7f]+$/i.test(z),"Output must be a public directory inside the repository")}),oe.object({repoId:oe.string().min(1),kind:oe.literal("server"),startCommand:oe.string().trim().min(1).max(1e4)})]).optional(),notes:oe.array(oe.string().max(2000)).max(100).optional(),source:oe.record(oe.string(),oe.enum(["auto","person"])).optional(),hash:oe.string().optional(),imageTag:oe.string().nullable().optional(),linearProjectId:oe.string().optional(),linearTeamId:oe.string().optional()}).partial(),xh=oe.object({owner:oe.string(),name:oe.string(),cloneUrl:oe.string(),defaultBranch:oe.string()}),nd=oe.object({key:oe.string(),cloneUrl:oe.string(),owner:oe.string().nullable(),name:oe.string().nullable(),defaultBranch:oe.string(),setupCommand:oe.string().nullable().optional(),verifyCommand:oe.string().nullable().optional()}),rd=oe.object({system:oe.boolean().optional(),name:oe.string(),skillSlugs:oe.array(oe.string()),agentSlugs:oe.array(oe.string())}),od=oe.object({path:oe.string(),content:oe.string(),executable:oe.boolean().optional(),encoding:oe.enum(["utf8","base64"]).optional()}).refine((z)=>z.encoding!=="base64"||z.content.length%4===0&&/^[A-Za-z0-9+/]*={0,2}$/.test(z.content),{message:"Base64 file content must use valid padded base64",path:["content"]}),sd=oe.object({vars:oe.record(oe.string(),oe.string()).default({}),files:oe.array(od).optional(),skills:oe.array(oe.string()).optional(),mcpServers:oe.array(oe.unknown()).optional(),managedPaths:oe.array(oe.string().refine((z)=>z.length>0&&z===z.normalize("NFC")&&!z.startsWith("/")&&!z.includes("\\")&&!/[\u0000-\u001f\u007f]/.test(z)&&z.split("/").every((J)=>J&&J!=="."&&J!==".."),"managed path must be a canonical project-relative path")).optional()}),id=oe.object({path:oe.string(),kind:oe.enum(["dotenv","credential","detected-content"]),contentBase64:oe.string(),size:oe.number().int().nonnegative(),sha256:oe.string().regex(/^[0-9a-f]{64}$/)}),ad=oe.object({mode:oe.enum(["managed","api_key","subscription"]),accountId:oe.string().min(1).max(200).nullable(),nativeModel:oe.string().trim().min(1).max(200).nullable()}).strict().refine((z)=>z.mode!=="managed"||z.accountId===null&&z.nativeModel===null,{message:"Managed funding cannot select an external account or native model"}),cd=oe.object({attemptId:oe.string().uuid(),sequence:oe.number().int().min(1).max(2147483647),tokensIn:oe.number().int().min(0).max(2147483647).optional(),tokensOut:oe.number().int().min(0).max(2147483647).optional(),costUsd:oe.number().finite().min(0).max(1e6).optional(),completeness:oe.enum(["partial","complete","unknown"]),model:oe.string().max(200).optional()}).strict().refine((z)=>z.completeness!=="complete"||z.tokensIn!==void 0&&z.tokensOut!==void 0,{message:"Complete native usage requires both token totals"}),ld=oe.object({path:oe.string().min(1).max(4096),change:oe.enum(["add","modify","delete"]),mode:oe.enum(["file","executable","symlink"]).optional(),content:oe.string().max(16777216).optional()}).strict(),dd=oe.object({revision:oe.number().int().positive(),sha:oe.string().regex(/^[a-f0-9]{40}$/),overlay:oe.array(ld).max(5000),packet:oe.string().max(200000)}).strict(),pd=oe.object({commitAttribution:Bi.optional(),taskId:oe.string(),cycleId:oe.string(),threadId:oe.string(),organizationId:oe.string().optional(),projectId:oe.string().optional(),description:oe.string(),acceptedScope:zi.optional(),baseSha:oe.string().regex(/^[a-f0-9]{40}$/).optional(),reviewFeedback:oe.string().optional(),iteration:oe.number().default(0),operationId:ko.optional(),repo:nd,branch:oe.string(),baseBranch:oe.string(),gitToken:oe.string().optional(),secrets:oe.record(oe.string(),oe.string()),packs:oe.array(rd),systemPrompt:oe.string().optional(),timeoutSeconds:oe.number().default(1800),funding:ad.optional(),nativeAttemptId:oe.string().uuid().optional(),agentEnv:oe.record(oe.string(),oe.string()).optional(),agent:ed.default(Mi),model:oe.string().min(1).optional(),effort:oe.enum(["low","medium","high"]).optional(),role:td.optional(),resultPath:oe.string().optional(),answerPrompt:oe.string().min(1).optional(),startupCommand:oe.string().nullable().optional(),startupPort:oe.number().int().min(1).max(65535).nullable().optional(),projectRuntime:Po.optional(),preparedEnvironment:oe.string().optional(),environment:sd.optional(),protectedFiles:oe.array(id).optional(),checklist:oe.array(qi).max(gt.maxItems).optional(),checklistRemoved:oe.array(oe.string().regex(dr)).max(gt.maxItems*2).optional(),continuation:dd.optional()}),jh=oe.enum(["acp"]),Eh=oe.enum(["builder","desktop","e2e"]),Ph=oe.object({batchId:oe.string(),tasks:oe.array(pd).min(1).max(20)}),ud=oe.object({inputTokens:oe.number(),outputTokens:oe.number(),costUsd:oe.number().optional()}),md=oe.object({status:oe.enum(["passed","failed","skipped"]),commandDigest:oe.string().regex(/^[a-f0-9]{64}$/).optional(),candidateRevision:oe.string().regex(/^[a-f0-9]{40,64}$/).optional(),scopeRevision:oe.string(),source:oe.enum(["configured","candidate-discovery"]),port:oe.number().int().min(1).max(65535).nullable()}),fd=oe.object({startup:md.optional(),status:oe.enum(["passed","failed","skipped"]),commandDigest:oe.string().regex(/^[a-f0-9]{64}$/).optional(),scopeRevision:oe.string(),candidateRevision:oe.string().regex(/^[a-f0-9]{40,64}$/).optional()}),gd=["succeeded","failed","incomplete"],Ih=oe.object({taskId:oe.string(),status:oe.enum(["success","failed"]),checkEvidence:fd.optional(),baseSha:oe.string().regex(/^[a-f0-9]{40}$/).optional(),preCodingSha:oe.string().regex(/^[a-f0-9]{40}$/).optional(),cost:ud.optional(),model:oe.string().optional(),error:oe.string().optional(),answer:oe.string().optional(),nativeUsage:cd.optional(),failureKind:oe.enum(["auth","usage_limit"]).optional(),resetsAt:oe.string().datetime().optional(),rateLimits:oe.array(oe.object({window:oe.string(),usedPercent:oe.number().min(0).max(100),resetsAt:oe.string().optional()})).optional(),outcome:oe.enum(gd).optional()});var wd=new Set([5901,6080,22222,22223]),_o=be.number().int().min(1024).max(65535).refine((z)=>!wd.has(z),{message:"That port is reserved by the environment's terminal or desktop"}),Dt=be.string().min(1).max(1e4),Io=be.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/),vd=be.union([be.object({run:Dt}).strict(),be.object({workflow:be.string().min(1).max(40)}).strict(),be.object({wait:be.object({port:_o}).strict()}).strict()]),bd=be.object({mode:be.enum(["sequential","parallel"]),steps:be.array(vd).min(1).max(50)}).strict(),Ut=be.object({schema:be.literal(1),hlix:be.object({workspace:be.string().min(1).max(200),project:be.string().min(1).max(200).optional(),api:be.string().url().max(300).optional()}).strict().optional(),project:be.object({name:be.string().min(1).max(100).optional(),brief:be.string().max(5000).optional(),stack:be.string().min(1).max(200).optional(),branchPrefix:be.string().refine(Di,"Use a branch prefix of letters, digits, _ and -, up to 20 characters").optional()}).strict().optional(),coder:be.object({harness:be.enum(lr).optional(),model:be.string().min(1).max(200).optional(),memoryTokens:be.number().int().min(1).max(2000000).optional(),maskToolOutputs:be.union([be.boolean(),be.number().int().min(1).max(2000000)]).optional(),yolo:be.boolean().optional()}).strict().optional(),machine:be.object({size:Ui.optional(),toolchain:jo.optional(),apt:be.array(be.string().min(1).max(200)).max(64).optional(),services:be.array(Eo).max(3).optional(),setup:Dt.optional()}).strict().optional(),workflows:be.record(be.string().min(1).max(40),bd).optional(),ports:be.array(be.object({name:be.string().min(1).max(40),port:_o,primary:be.boolean().optional()}).strict()).max(10).optional(),commands:be.object({verify:Dt.optional(),preview:be.object({command:Dt,port:_o}).strict().optional(),deploy:be.discriminatedUnion("kind",[be.object({kind:be.literal("server"),start:Dt}).strict(),be.object({kind:be.literal("static"),build:Dt,outDir:be.string().min(1).max(2000)}).strict()]).optional()}).strict().optional(),env:be.object({required:be.array(Io).max(200).optional(),public:be.record(Io,be.string().max(1e4)).optional()}).strict().optional(),team:be.object({agents:be.array(xo).max(8).optional(),notes:be.array(be.string().max(2000)).max(100).optional()}).strict().optional(),intake:be.object({github:be.boolean().optional(),linear:be.boolean().optional()}).strict().optional(),local:be.object({runtime:be.enum(["cloud","local","docker"]).optional(),image:be.string().min(1).max(300).optional(),setup:Dt.optional()}).strict().optional(),providers:be.array(be.object({name:be.string().min(1).max(80),url:be.string().url().max(300),models:be.array(be.string().min(1).max(200)).min(1).max(100),apiKeyEnv:Io.optional(),apiKey:be.string().min(1).max(2000).optional()}).strict()).max(20).optional()}).strict(),kd=`# Project setup for Hlix.
|
|
7
|
-
# Commit this file. Secret values belong in the environment, not here.
|
|
8
|
-
`,Co="https://server.hlix.ai";function mr(z){return z.replace(/\/+$/,"")===Co}function $o(z){if(!z||mr(z))return;return z}function on(z){if(z.length>262144)return{ok:!1,issues:[{path:"(file)",message:"hlix.yml is over 256 KB."}]};let J;try{J=hd(z,{uniqueKeys:!0})}catch(Q){return{ok:!1,issues:[{path:"(file)",message:Q instanceof Error?Q.message:"Could not read YAML."}]}}if(J.length!==1)return{ok:!1,issues:[{path:"(file)",message:"hlix.yml must contain one document."}]};let V=J[0];if(V.errors.length)return{ok:!1,issues:V.errors.map((Q)=>({path:"(file)",message:Q.message}))};let X=!1;if(Vi(V,{Alias(){return X=!0,Vi.BREAK}}),X)return{ok:!1,issues:[{path:"(file)",message:"YAML aliases are not allowed."}]};let Y=Ut.safeParse(V.toJS());if(!Y.success)return{ok:!1,issues:Pd(Y.error)};let Z=Yi(Y.data);if(Z.length)return{ok:!1,issues:Z};return{ok:!0,file:Y.data}}function Xi(z,J){let V=Ut.parse(Zi(z,J)),X=Yi(V);if(X.length)throw Error(X.map((Y)=>`${Y.path}: ${Y.message}`).join("; "));return V}function jt(z){let J=z.machine?.setup??Cn(z,"setup",[]),V=z.commands?.verify??Cn(z,"verify",[]),X=z.commands?.preview??xd(z),Y=Po.parse({agents:z.team?.agents,toolchain:z.machine?.toolchain,aptPackages:z.machine?.apt,setup:J,services:z.machine?.services,envOverrides:z.env?.public,verifyCommand:V,preview:X,notes:z.team?.notes}),Z=z.intake&&(z.intake.github!==void 0||z.intake.linear!==void 0)?{github:z.intake.github,linear:z.intake.linear}:void 0;return{name:z.project?.name,stack:z.project?.stack,brief:z.project?.brief,branchPrefix:z.project?.branchPrefix,sandboxSize:z.machine?.size,verifyCommand:V,previewCommand:X?.command,previewPort:X?.port,intake:Sd(Z),requiredEnv:z.env?.required??[],runtime:Y,binding:{workspaceId:z.hlix?.workspace,projectId:z.hlix?.project,apiUrl:z.hlix?.api,harness:z.coder?.harness,model:z.coder?.model,memoryTokens:z.coder?.memoryTokens===void 0?void 0:String(z.coder.memoryTokens),maskToolOutputs:z.coder?.maskToolOutputs===void 0?void 0:String(z.coder.maskToolOutputs),yolo:z.coder?.yolo===void 0?void 0:z.coder.yolo?"true":"false",sandbox:z.local?.runtime,dockerImage:z.local?.image}}}function fr(z){let J={schema:1};if(z.hlix){let V=$o(z.hlix.api);J.hlix={workspace:z.hlix.workspace,...V?{api:V}:{},...z.hlix.project?{project:z.hlix.project}:{}}}if(z.name||z.stack)J.project={name:z.name,stack:z.stack};if(z.setup)J.machine={setup:z.setup};if(z.verify||z.previewCommand&&z.previewPort)J.commands={verify:z.verify,preview:z.previewCommand&&z.previewPort?{command:z.previewCommand,port:z.previewPort}:void 0};if(z.requiredEnv?.length)J.env={required:z.requiredEnv};return Ut.parse(ur(J))}function $n(z,J=kd){let V=yd(ur(z),{lineWidth:0}).trimEnd();return`${J}${V}
|
|
9
|
-
`}function Sd(z){if(!z)return;let J={};if(z.github!==void 0)J.github=z.github;if(z.linear!==void 0)J.linear=z.linear;return Object.keys(J).length?J:void 0}function xd(z){let J=Cn(z,"preview",[]),V=z.ports?.find((X)=>X.primary)?.port??z.ports?.[0]?.port;if(!J||V===void 0)return;return{command:J,port:V}}function jd(z){return`timeout 60 bash -c 'until (echo >/dev/tcp/127.0.0.1/${z}) 2>/dev/null; do sleep 0.25; done'`}function Ed(z){let J=z.map((Y,Z)=>`( ${Y} ) & p${Z}=$!`),V=z.map((Y,Z)=>`wait $p${Z}; s${Z}=$?`),X=z.map((Y,Z)=>`s${Z}`).join("||");return`( ${J.join("; ")}; ${V.join("; ")}; exit $(( ${X} )) )`}function Cn(z,J,V){if(V.includes(J))throw Error(`workflows.${J} refers to itself.`);if(V.length>=3)throw Error(`workflows.${J} is nested more than 3 levels deep.`);let X=z.workflows?.[J];if(!X){if(V.length===0)return;throw Error(`workflows.${J} does not exist.`)}let Y=[];for(let Z of X.steps)if("run"in Z)Y.push(Z.run);else if("workflow"in Z){let Q=Cn(z,Z.workflow,[...V,J]);if(Q)Y.push(Q)}else Y.push(jd(Z.wait.port));if(!Y.length)return;return X.mode==="parallel"?Ed(Y):Y.join(" && ")}function Yi(z){try{for(let J of Object.keys(z.workflows??{}))Cn(z,J,[])}catch(J){return[{path:"workflows",message:J instanceof Error?J.message:"Invalid workflow."}]}return[]}function Pd(z){return z.issues.map((J)=>{let V="keys"in J&&Array.isArray(J.keys)?J.keys.map(String):[];return{path:[...J.path.map(String),...V].join(".")||"(file)",message:J.message}})}function pr(z){return Boolean(z)&&typeof z==="object"&&!Array.isArray(z)}function Zi(z,J){if(Array.isArray(J)||!pr(J)||!pr(z))return J;let V={...z};for(let[X,Y]of Object.entries(J))V[X]=X in z?Zi(z[X],Y):Y;return V}function ur(z){if(Array.isArray(z))return z.map(ur);if(!pr(z))return z;let J={};for(let[V,X]of Object.entries(z)){if(X===void 0)continue;let Y=ur(X);if(pr(Y)&&Object.keys(Y).length===0)continue;J[V]=Y}return J}var Qi=["hlix.yml","hlix.yaml"],sn=["hlix.local.yml","hlix.local.yaml"];var Id=/-----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,}/,_d=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,Cd=/(?:^|[,{\s])(?:["']?(?:api[_-]?key|access[_-]?token|auth(?:orization)?|client[_-]?secret|password|private[_-]?key|secret|token)["']?)\s*(?::|=)\s*["']?(?!\$\{|process\.env|import\.meta\.env|os\.(?:getenv|environ\.get)|<|replace|example|changeme)[A-Za-z0-9+/_=.:-]{12,}/im;function Tn(z,J){return Id.test(J)||_d.test(z)&&Cd.test(J)}var Od=sn;function dt(z){let J=ea(z,Qi),V=ea(z,sn);if(J&&"error"in J)return{file:null,base:null,local:null,baseName:null,error:J.error};if(V&&"error"in V)return{file:null,base:null,local:null,baseName:null,error:V.error};let X=J?.name??null,Y=V?.name??null,Z=X?ta(z,X):{file:null,error:null},Q=Y?ta(z,Y):{file:null,error:null},ee=Z.error??Q.error;if(ee||!Z.file)return{file:Z.file,base:Z.file,local:Q.file,baseName:X,error:ee};try{return{file:Q.file?Xi(Z.file,Q.file):Z.file,base:Z.file,local:Q.file,baseName:X,error:null}}catch(te){let re=te instanceof Error?te.message:"Could not merge hlix.local.yml.";return{file:null,base:Z.file,local:Q.file,baseName:X,error:re}}}function an(z){if(!z)return null;let J=jt(z).binding;if(!J.workspaceId)return null;return{schemaVersion:1,workspaceId:J.workspaceId,apiUrl:J.apiUrl??Co,projectId:J.projectId,sandbox:J.sandbox,dockerImage:J.dockerImage,memoryTokens:J.memoryTokens,maskToolOutputs:J.maskToolOutputs,harness:Ld(J.harness),model:J.model,yolo:J.yolo}}function ra(z,J){yr(z,(V)=>{let X={...V.local},Y=!1;if(!V.local?.runtime&&J.sandbox)X.runtime=J.sandbox,Y=!0;if(!V.local?.image&&J.dockerImage)X.image=J.dockerImage,Y=!0;let Z={...V.coder},Q=!1;if(!V.coder?.harness&&J.harness)Z.harness=J.harness,Q=!0;if(!V.coder?.model&&J.model)Z.model=J.model,Q=!0;if(V.coder?.memoryTokens===void 0&&J.memoryTokens){let ee=Number(J.memoryTokens);if(Number.isInteger(ee)&&ee>=20000&&ee<=2000000)Z.memoryTokens=ee,Q=!0}if(V.coder?.yolo===void 0&&(J.yolo==="true"||J.yolo==="false"))Z.yolo=J.yolo==="true",Q=!0;if(!Y&&!Q)return V;return{...V,...Y?{local:X}:{},...Q?{coder:Z}:{}}})}function oa(z){if(z.error)return z.error;if(z.baseName)return z.baseName;return"will write hlix.yml"}async function gr(z){let J=Gt(z,".gitignore"),V=To(J)?await Rd(J,"utf8"):"",X=Od.filter((Z)=>!Hd(V,Z));if(!X.length)return;let Y=V.length===0||V.endsWith(`
|
|
10
|
-
`)?"":`
|
|
11
|
-
`;Ro(J),Ao(J,`${V}${Y}${X.join(`
|
|
12
|
-
`)}
|
|
13
|
-
`,{mode:420})}function hr(z,J){let V=dt(z);if(V.error)throw Error(V.error);if(V.base)return{written:!1,file:V.base};let X=fr(J),Y=Gt(z,"hlix.yml");return Ro(Y),Ao(Y,$n(X),{mode:420}),{written:!0,file:X}}function yr(z,J){let V=dt(z);if(V.error)throw Error(V.error);let X=V.base??{schema:1},Y=J(X),Z=V.baseName??"hlix.yml",Q=Gt(z,Z);if(V.base&&Y===X)return{path:Q,name:Z,file:X,changed:!1};let ee=$n(Y),te=on(ee);if(!te.ok)throw Error(te.issues.map((re)=>`${re.path}: ${re.message}`).join("; "));return Ro(Q),Ao(Q,ee,{mode:420}),{path:Q,name:Z,file:te.file,changed:!0}}function wr(z,J){let V=yr(z,(X)=>{let Y=J.project??X.hlix?.project,Z=X.hlix?.api&&mr(X.hlix.api)&&mr(J.api)?X.hlix.api:$o(J.api),Q={workspace:J.workspace,...Z?{api:Z}:{},...Y?{project:Y}:{}};if(X.hlix?.workspace===Q.workspace&&X.hlix?.api===Q.api&&X.hlix?.project===Q.project)return X;return{...X,hlix:Q}});return{path:V.path,name:V.name,changed:V.changed}}function sa(z){let J=dt(z);if(J.error||!J.baseName)return null;return Gt(z,J.baseName)}var Nd=new Set([5901,6080,22222,22223]);function An(z,J,V){let X=z.install.map((Q)=>Q.trim()).filter(Boolean).join(`
|
|
14
|
-
`),Y=z.ports.find((Q)=>Q.port>=1024&&Q.port<=65535&&!Nd.has(Q.port))?.port,Z=z.start&&Y?z.start:void 0;return{name:V?.name,stack:V?.stack,setup:X||void 0,previewCommand:Z,previewPort:Z?Y:void 0,requiredEnv:z.requiredSecretKeys,hlix:J}}function vr(z,J){let V=Gt(z.root,J);if(!To(V))return;let X=na(V),Y=Ad(V),Z=$d("sha256").update(X).digest("hex"),Q=X.toString("utf8"),ee=z.protectedFiles.find((re)=>re.path===J);if(ee||Tn(J,Q)){let re=X.toString("base64");if(ee)ee.contentBase64=re;else z.protectedFiles.push({path:J,kind:"detected-content",contentBase64:re});let ne=ee&&(ee.kind==="dotenv"||ee.kind==="credential"||ee.kind==="detected-content")?ee.kind:"detected-content",se=z.manifest.secretFiles.find((pe)=>pe.path===J);if(se)se.size=Y.size,se.sha256=Z;else z.manifest.secretFiles.push({path:J,kind:ne,keys:[],size:Y.size,sha256:Z});let ie=z.manifest.files.findIndex((pe)=>pe.path===J);if(ie>=0){let pe=z.manifest.files[ie];z.manifest.totals.files-=1,z.manifest.totals.bytes-=pe.size,z.manifest.files.splice(ie,1)}return}let te=z.manifest.files.find((re)=>re.path===J);if(!te){z.manifest.files.push({path:J,size:Y.size,sha256:Z,tracked:!1,executable:!1}),z.manifest.totals.files+=1,z.manifest.totals.bytes+=Y.size;return}z.manifest.totals.bytes+=Y.size-te.size,te.size=Y.size,te.sha256=Z}function Ro(z){try{if(Td(z).isSymbolicLink())throw Error(`Refusing to write through a symlink: ${z}`)}catch(J){if(J.code==="ENOENT")return;throw J}}var Fd=["claude-code","codex","opencode","goose","qwen-code","pi","hlix"];function ea(z,J){let V=J.filter((Z)=>To(Gt(z,Z))),[X,Y]=V;if(X&&Y)return{error:`${V.join(" and ")} both exist. Keep one.`};return X?{name:X}:null}function Ld(z){return Fd.find((J)=>J===z)}function ta(z,J){let V=on(na(Gt(z,J),"utf8"));if(!V.ok){let X=V.issues.map((Y)=>`${Y.path}: ${Y.message}`).join("; ");return{file:null,error:`${J} ${X}`}}return{file:V.file,error:null}}function Hd(z,J){return z.split(/\r?\n/).some((V)=>V.trim()===J)}function b(z){if(!z.credential)return null;if(z.credentialSource==="session")return"session (desktop)";if(z.credentialSource==="env")return"environment (HLIX_API_KEY)";return`file (${z.credentialPath})`}function t(z){let J=ca(z);for(;;){let V=dt(J);if(V.error)throw new e("invalid_project_file",V.error);let X=an(V.file);if(X?.workspaceId&&X.apiUrl)return{root:J,config:X};let Y=aa(J);if(Y===J)return null;J=Y}}function Oo(z){let J=ca(z);for(;;){let V=dt(J);if(V.error)throw new e("invalid_project_file",V.error);if(V.base)return{root:J,loaded:V};let X=aa(J);if(X===J)return null;J=X}}function la(z){try{return Md(z).isDirectory()}catch{return!1}}function br(z){if(typeof z!=="string")return;let J=z.trim();return J?J:void 0}var ia=(z,J)=>z.replace(/\/+$/,"")===J.replace(/\/+$/,"");function r(z){let{env:J,flags:V,cwd:X}=z,Y=t(X),Z=v(J),Q=Z?J.HLIX_API_KEY?"env":J.HLIX_SESSION_TOKEN?"session":"file":null,ee=Q==="file"?Z:null,te=br(V["base-url"]),re=br(J.HLIX_BASE_URL),ne=br(V.workspace),se=br(J.HLIX_WORKSPACE_ID),ie=te??re??Y?.config.apiUrl??ee?.baseUrl??rn,pe=te?"flag":re?"env":Y?.config.apiUrl?"project":ee?.baseUrl?"credential":"default",fe=ne??se??Y?.config.workspaceId??ee?.organizationId??null,ce=ne?"flag":se?"env":Y?.config.workspaceId?"project":ee?.organizationId?"credential":null;return{baseUrl:ie,baseUrlSource:pe,workspaceId:fe,workspaceSource:ce,credential:Z,credentialSource:Q,credentialPath:lt(J),binding:Y,conflict:Dd(Y,{flagBaseUrl:te,envBaseUrl:re,flagWorkspace:ne,envWorkspace:se})}}function Dd(z,J){if(!z)return null;let V=`${z.root} is bound to`,X="Drop the override, or point --cwd at a folder bound to it.";if(J.flagWorkspace&&J.flagWorkspace!==z.config.workspaceId)return`${V} workspace ${z.config.workspaceId}, but --workspace names ${J.flagWorkspace}. ${X}`;if(J.envWorkspace&&J.envWorkspace!==z.config.workspaceId)return`${V} workspace ${z.config.workspaceId}, but HLIX_WORKSPACE_ID names ${J.envWorkspace}. ${X}`;if(J.flagBaseUrl&&!ia(J.flagBaseUrl,z.config.apiUrl))return`${V} ${z.config.apiUrl}, but --base-url names ${J.flagBaseUrl}. ${X}`;if(J.envBaseUrl&&!ia(J.envBaseUrl,z.config.apiUrl))return`${V} ${z.config.apiUrl}, but HLIX_BASE_URL names ${J.envBaseUrl}. ${X}`;return null}var Ud=/\x1b(?:\[[0-?]*[ -/]*[@-~]?|\][^\x07\x1b]*(?:\x07|\x1b\\)?|[PX^_][^\x1b]*(?:\x1b\\)?|[\x20-\x7e]?)|\x9b[0-?]*[ -/]*[@-~]?/g,Gd=/[\x00-\x08\x0b-\x1f\x7f-\x9f]/g,Bd=/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]/g,Wd=/(?<![\p{Extended_Pictographic}\p{Emoji_Modifier}\uFE0F])\u200D|\u200D(?!\p{Extended_Pictographic})|[^\P{Cf}\u200D]/gu,zd=/[\u2028\u2029]/g;function i(z,J={}){return z.replace(Ud,"").replace(J.carriageReturn?Bd:Gd,"").replace(Wd,"").replace(zd,`
|
|
15
|
-
`)}var da="hlix-desktop";async function Kd(z,J,V){let X=J.map((ee)=>ee.id);if(V){if(!X.includes(V))throw new e("workspace_mismatch",J.length===0?`This account is not a member of any workspace, including ${V}.`:`This account cannot act in workspace ${V}. Available: ${X.join(", ")}.`);return V}if(J.length===0)throw new e("workspace_required","This account is not a member of any workspace. Create or join one first.");let Y=J[0];if(Y&&J.length===1)return z.stderr(`Using your only workspace: ${Y.name} (${Y.id})
|
|
16
|
-
`),Y.id;if(z.json||!z.promptChoice)throw new e("missing_argument",`--workspace is required here: this account can act in ${J.length} workspaces. Pass one of: ${X.join(", ")}.`);let Z=Math.max(...J.map((ee)=>ee.name.length));z.stderr(`${J.map((ee,te)=>` ${te+1}) ${ee.name.padEnd(Z)} ${ee.slug} ${ee.role} ${ee.id}`).join(`
|
|
17
|
-
`)}
|
|
18
|
-
`);let Q=await z.promptChoice(`Workspace [1-${J.length}]: `,J.length);return X[Q]}function No(z){let J=new URL(z),V=J.hostname==="localhost"||J.hostname==="127.0.0.1"||J.hostname==="::1";if(J.protocol!=="https:"&&!(J.protocol==="http:"&&V))throw new e("invalid_base_url","--base-url must use HTTPS (HTTP is allowed only for localhost).")}function w(z){let J;try{let Y=new URL(z);if(Y.protocol!=="https:"&&Y.protocol!=="http:")return;J=Y.href}catch{return}let[V,X]=process.platform==="darwin"?["open",[J]]:process.platform==="win32"?["rundll32.exe",["url.dll,FileProtocolHandler",J]]:["xdg-open",[J]];try{let Y=Jd(V,X,{stdio:"ignore",detached:!0});Y.on("error",()=>{}),Y.unref()}catch{}}async function Fo(z,J){let{baseUrl:V,credential:X}=J,Y=new Mt({baseUrl:V,credential:X,retry:{attempts:1}}),Z=await Kd(z,await Y.workspaces.list(),J.requested);if(await new Mt({baseUrl:V,credential:X,organizationId:Z,retry:{attempts:1}}).projects.list(),z.signal?.aborted)throw new e("cancelled","Login cancelled.");let Q=Li(X.kind==="bearer"?{baseUrl:V,apiKey:"",sessionToken:X.token,organizationId:Z}:{baseUrl:V,apiKey:X.kind==="apiKey"?X.apiKey:"",organizationId:Z},z.env);return{baseUrl:V,organizationId:Z,path:Q}}async function Lo(z,J){No(J.baseUrl);let V;try{let X=z.signal?{signal:z.signal}:{},Y=await uo({baseUrl:J.baseUrl,clientId:da,...X});z.stderr(`Sign in to Hlix in your browser:
|
|
19
|
-
${i(Y.verificationUriComplete)}
|
|
20
|
-
and confirm the code: ${i(Y.userCode)}
|
|
21
|
-
Waiting for approval…
|
|
22
|
-
`),z.openUrl?.(Y.verificationUriComplete),V=await mo({baseUrl:J.baseUrl,clientId:da,code:Y,...X})}catch(X){if(!(X instanceof ct))throw X;if(X.reason==="denied")throw new e("login_denied",X.message);if(X.reason==="expired")throw new e("login_expired",X.message);if(X.reason==="cancelled")throw new e("cancelled",X.message);throw new e("login_failed",X.message)}return Fo(z,{baseUrl:J.baseUrl,credential:tn(V),requested:J.requested})}var qd="Run `hlix login`, or set HLIX_API_KEY for CI.";async function g(z,J){let V=r({env:z.env,flags:J.flags,cwd:J.cwd});if(V.conflict)return;let X=V.credential;if(X){if(!J.verify)return;try{await new Mt({baseUrl:V.baseUrl,credential:X.sessionToken?tn(X.sessionToken):Tt(X.apiKey),retry:{attempts:1}}).workspaces.list();return}catch(Q){if(!(Q instanceof At))throw Q;if(V.credentialSource!=="file"||z.json||!z.promptChoice)throw Q;z.stderr(`Your stored credential was rejected — signing in again.
|
|
23
|
-
`)}}else{if(z.json||!z.promptChoice)throw new e("unauthenticated",`Not signed in. ${qd}`);z.stderr(`Not signed in — starting the browser login.
|
|
24
|
-
`)}let Y=V.workspaceSource==="credential"?void 0:V.workspaceId??void 0,Z=await Lo(z,{baseUrl:V.baseUrl,requested:Y});z.stderr(`Signed in to ${Z.baseUrl}
|
|
25
|
-
`)}var q=1,Se=(z,J)=>({schemaVersion:1,command:z,data:J}),Rn=(z,J)=>({schemaVersion:1,command:z,error:J});function ke(z){return`${JSON.stringify(z,null,2)}
|
|
26
|
-
`}function Me(z){let J=Math.max(0,...z.map(([V])=>V.length));return z.map(([V,X])=>`${V.padEnd(J)} ${X}`).join(`
|
|
27
|
-
`)}function ht(z,J){let V=z.map((Y,Z)=>Math.max(Y.length,...J.map((Q)=>(Q[Z]??"").length))),X=(Y)=>Y.map((Z,Q)=>Z.padEnd(V[Q])).join(" ").trimEnd();return[X(z),X(V.map((Y)=>"-".repeat(Y))),...J.map(X)].join(`
|
|
28
|
-
`)}function Ho(z){if(z instanceof e)return{code:z.code,status:null};if(z instanceof nn)return{code:"invalid_request",status:400};if(z instanceof Sn)return{code:"bad_request",status:400};if(z instanceof At)return{code:"unauthenticated",status:401};if(z instanceof xn)return{code:"forbidden",status:403};if(z instanceof Rt)return{code:"not_found",status:404};if(z instanceof Ot)return{code:"conflict",status:409};if(z instanceof Nt)return{code:"rate_limited",status:429};if(z instanceof jn)return{code:"not_implemented",status:501};if(z instanceof Ft)return{code:"server_error",status:z.status};if(z instanceof it)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var kr=(z)=>{if(z instanceof nn&&z.issues.length>0){let J=z.issues.map((V)=>{let X=V;return` - ${Array.isArray(X.path)&&X.path.length>0?`${X.path.join(".")}: `:""}${typeof X.message==="string"?X.message:JSON.stringify(V)}`});return`${z.message}
|
|
29
|
-
${J.join(`
|
|
30
|
-
`)}`}return z instanceof Error?z.message:String(z)};function o(z,J){let V=r({env:z,flags:J.flags,cwd:J.cwd});if(V.conflict)throw new e("workspace_mismatch",V.conflict);if(!V.credential)throw new e("unauthenticated","No credential. Run `hlix login`, or set HLIX_API_KEY for CI.");return new Mt({baseUrl:V.baseUrl,credential:V.credential.sessionToken?tn(V.credential.sessionToken):Tt(V.credential.apiKey),...V.workspaceId?{organizationId:V.workspaceId}:{}})}function pa(z){let J=Math.max(...z.map((X)=>X.name.length));return`hlix — the hlix control-plane CLI
|
|
31
|
-
|
|
32
|
-
Usage:
|
|
33
|
-
hlix <command> [options]
|
|
34
|
-
|
|
35
|
-
Commands:
|
|
36
|
-
${[` hlix ${"".padEnd(J)} Open Hlix Code (interactive)`,...z.map((X)=>` hlix ${X.name.padEnd(J)} ${X.summary}`)].join(`
|
|
37
|
-
`)}
|
|
38
|
-
|
|
39
|
-
Options:
|
|
40
|
-
--json Machine-readable output (a versioned, stable contract)
|
|
41
|
-
--cwd <dir> Operate on another directory instead of the current one
|
|
42
|
-
--workspace <id> Workspace to act in, overriding the folder's binding
|
|
43
|
-
--base-url <url> API to talk to, overriding the folder's binding
|
|
44
|
-
--help Show this help
|
|
45
|
-
--version Show the installed CLI version
|
|
46
|
-
|
|
47
|
-
Hlix Code (hlix with no command):
|
|
48
|
-
--sandbox <choice> cloud (Cloud Machine), docker (Docker container), or local
|
|
49
|
-
(local environment); --local is short for --sandbox local
|
|
50
|
-
--docker-image <r> image the Docker container runs in
|
|
51
|
-
--harness <name> which coder does the work
|
|
52
|
-
--project <id> project to act in, when this folder is not bound
|
|
53
|
-
-p "<prompt>" one turn, print the answer, exit
|
|
54
|
-
--json with -p: one JSON object per event instead of prose
|
|
55
|
-
--allow-writes with -p: let the turn change files and run commands
|
|
56
|
-
--yolo approve every tool call for the whole session
|
|
57
|
-
|
|
58
|
-
A command targets the workspace named by, in order: an explicit flag, the
|
|
59
|
-
HLIX_* environment, the nearest hlix.yml, then the stored credential.
|
|
60
|
-
Run \`hlix status\` to see which one applied.
|
|
61
|
-
`}function ma(z,J){let V=[...Array(J.length+1).keys()];for(let X=1;X<=z.length;X+=1){let Y=[X];for(let Z=1;Z<=J.length;Z+=1)Y[Z]=Math.min(V[Z]+1,Y[Z-1]+1,V[Z-1]+(z[X-1]===J[Z-1]?0:1));V=Y}return V[J.length]}function Yd(z,J,V){let X=/Unknown option '--([^'=]+)/.exec(V)?.[1];if(!X)return V;let Y=J.findIndex((te)=>te.startsWith("-")),Z=Y===-1?J:J.slice(0,Y),Q=new Set(["json","help","version","cwd","workspace","base-url",...Sr(z,Z)?.command.options??[]]),ee=null;for(let te of Q){let re=ma(X,te);if(re<=2&&(!ee||re<ee.distance))ee={name:te,distance:re}}return ee?`${V}
|
|
62
|
-
Did you mean --${ee.name}?`:V}function ua(z,J){let V=new Set;for(let Z of z)V.add(Z.name),V.add(Z.name.split(" ")[0]);let X=null;for(let Z of V){let Q=ma(J,Z);if(Q<=2&&(!X||Q<X.distance))X={name:Z,distance:Q}}if(!X)return null;if(z.some((Z)=>Z.name===X.name))return X.name;let Y=z.filter((Z)=>Z.name.startsWith(`${X.name} `)).sort((Z,Q)=>Z.name.length-Q.name.length)[0];return Y?Y.name:X.name}function Sr(z,J){for(let V of[...z].sort((X,Y)=>Y.name.length-X.name.length)){let X=V.name.split(" ");if(X.every((Y,Z)=>J[Z]===Y))return{command:V,rest:J.slice(X.length)}}return null}function Zd(z,J,V){let X=Yd(z,J,V);if(!/^Unknown option '/.test(V))return X;let Y=X.replace(/\. To specify a positional argument[\s\S]*?after '--'[^\n]*/,"."),Z=Sr(z,J.filter((Q)=>!Q.startsWith("-")));return Z?`${Y}
|
|
63
|
-
|
|
64
|
-
${Z.command.usage}`:Y}async function d(z,J,V){let X=J.findIndex((we)=>we==="--api-key"||we.startsWith("--api-key=")),Y=J[X+1];if(X!==-1&&(J[X].includes("=")||Y!==void 0&&!Y.startsWith("-")))return V.stderr("error: API keys are never accepted as command-line arguments. Run `hlix login --api-key` and enter it at the hidden prompt, or pipe it in.\n"),2;let Z;try{Z=Xd({args:J,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"},"api-key":{type:"boolean"}}})}catch(we){let Pe=J.includes("--json"),ge=Zd(z,J,kr(we));if(V.onFailure?.({code:"invalid_usage",message:ge,status:null}),Pe)V.stdout(ke(Rn("cli",{code:"invalid_usage",message:ge,status:null})));else V.stderr(`${ge}
|
|
65
|
-
`);return 2}let Q=Z.values.json===!0,ee=Z.positionals;if(Z.values.version===!0){let{version:we}=await import("./package-6n7j36nb.js");return V.stdout(`${we}
|
|
66
|
-
`),0}if(ee.length===0||Z.values.help===!0){let we=Sr(z,ee);return V.stdout(we?`${we.command.usage}
|
|
67
|
-
`:pa(z)),ee.length===0&&Z.values.help!==!0?1:0}let te=Sr(z,ee);if(!te){let we=ee.join(" "),Pe=ua(z,we)??ua(z,ee[0]),ge=Pe?`Unknown command: ${we}
|
|
68
|
-
Did you mean \`hlix ${Pe}\`?`:`Unknown command: ${we}`;if(V.onFailure?.({code:"unknown_command",message:ge,status:null}),Q)V.stdout(ke(Rn(we,{code:"unknown_command",message:ge,status:null})));else V.stderr(`${ge}
|
|
69
|
-
|
|
70
|
-
${pa(z)}`);return 2}let re=new Set(["json","help","version","cwd","workspace","base-url"]),ne=new Set(te.command.options??[]),se=Object.entries(Z.values).filter(([we,Pe])=>Pe!==void 0&&!re.has(we)&&!ne.has(we)).map(([we])=>`--${we}`),ie=te.command.args??{min:0,max:0},pe=te.rest.length<ie.min?{code:"missing_argument",message:te.command.usage.split(`
|
|
71
|
-
`)[0]}:te.rest.length>ie.max?{code:"invalid_usage",message:te.command.usage.split(`
|
|
72
|
-
`)[0]}:null,fe=typeof Z.values.cwd==="string"?Z.values.cwd:void 0,ce=Vd(fe??"."),le=fe!==void 0&&!la(ce)?{code:"invalid_usage",message:`--cwd is not a directory: ${ce}`}:null,me=se.length>0?{code:"invalid_usage",message:`Unsupported option for ${te.command.name}: ${se.join(", ")}`}:le??pe;if(me){if(V.onFailure?.({...me,status:null}),Q)V.stdout(ke(Rn(te.command.name,{...me,status:null})));else{let we=te.command.usage.startsWith(me.message)?te.command.usage:`${me.message}
|
|
73
|
-
|
|
74
|
-
${te.command.usage}`;V.stderr(`error: ${we}
|
|
75
|
-
`)}return 2}let ve=Z.values,Ee={...V,args:te.rest,json:Q,flags:ve,cwd:ce,requireClient:(we)=>o(V.env,{cwd:we??ce,flags:ve})};try{if(te.command.signIn)await g(Ee,{cwd:ce,flags:ve});return await te.command.run(Ee)}catch(we){let{code:Pe,status:ge}=Ho(we);if(V.onFailure?.({code:Pe,message:i(kr(we)),status:ge,...we instanceof e&&we.details!==void 0?{details:we.details}:{}}),Q)V.stdout(ke(Rn(te.command.name,{code:Pe,message:kr(we),status:ge})));else if(V.stderr(`error: ${i(kr(we))}
|
|
76
|
-
`),process.env.HLIX_DEBUG&&we instanceof Error&&we.stack)V.stderr(`${we.stack}
|
|
77
|
-
`);return Pe==="unauthenticated"||Pe==="forbidden"?3:1}}var xr={name:"auth login",summary:"Sign in through your browser and store the credential for this machine",usage:["Usage: hlix auth login [--workspace <id>] [--base-url <url>] [--api-key]",""," --base-url Defaults to HLIX_BASE_URL, else this folder's API, else the",` one you last signed in to, else ${rn}`," --workspace Workspace (organization) id to act in. Optional: your"," workspaces are listed after you sign in, and the only one"," is taken automatically."," --api-key Sign in with an API key instead of the browser. The key is"," read from a hidden prompt, or from stdin when piped; it is"," never accepted as an argument.","","Opens your browser to approve a one-time code. For CI, set HLIX_API_KEY","and HLIX_WORKSPACE_ID in the environment instead. `hlix login` is the same command."].join(`
|
|
78
|
-
`),supportsJson:!0,options:["base-url","workspace","api-key"],agentTool:!1,async run(z){let J=typeof z.flags.workspace==="string"?z.flags.workspace:z.env.HLIX_WORKSPACE_ID,V=r({env:z.env,flags:z.flags,cwd:z.cwd}).baseUrl;No(V);let X;if(z.env.HLIX_API_KEY||z.flags["api-key"]===!0){let Y=(z.env.HLIX_API_KEY??(z.promptChoice?await z.readSecret?.("Hlix API key: "):await z.readStdin?.())??"").trim();if(!Y)throw new e("missing_credential","No API key entered. Enter it at the hidden prompt, pipe it to `hlix auth login --api-key`, or set HLIX_API_KEY for CI.");X=await Fo(z,{baseUrl:V,credential:Tt(Y),requested:J})}else{if(z.json||!z.promptChoice)throw new e("missing_credential","A browser login needs a terminal. Set HLIX_API_KEY for CI, or pipe a key to `hlix auth login --api-key`.");X=await Lo(z,{baseUrl:V,requested:J})}if(z.json)z.stdout(ke(Se(this.name,{baseUrl:X.baseUrl,organizationId:X.organizationId,credentialPath:X.path})));else z.stdout(`Signed in to ${X.baseUrl}
|
|
79
|
-
Credential stored at ${X.path}
|
|
80
|
-
`);return 0}},fa={...xr,name:"login",usage:xr.usage.replace("hlix auth login","hlix login")},Mo={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(`
|
|
81
|
-
`),supportsJson:!0,async run(z){let J=r({env:z.env,flags:z.flags,cwd:z.cwd});if(J.conflict)throw new e("workspace_mismatch",J.conflict);if(!J.credential)throw new e("unauthenticated","No credential. Run `hlix login`, or set HLIX_API_KEY for CI.");try{await z.requireClient().projects.list()}catch(X){throw z.stderr(`credential from ${J.credentialSource}, workspace ${J.workspaceId??"none"}, api ${J.baseUrl}
|
|
82
|
-
`),X}let V={credentialSource:J.credentialSource,credentialPath:J.credentialSource==="file"?J.credentialPath:null,baseUrl:J.baseUrl,baseUrlSource:J.baseUrlSource,workspaceId:J.workspaceId,workspaceSource:J.workspaceSource,valid:!0};if(z.json)return z.stdout(ke(Se(Mo.name,V))),0;return z.stdout(`${Me([["credential",b(J)??"none"],["api",`${J.baseUrl} (from ${J.baseUrlSource})`],["workspace",J.workspaceId?`${J.workspaceId} (from ${J.workspaceSource})`:"none"],["status","valid"]])}
|
|
83
|
-
`),0}},jr={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(`
|
|
84
|
-
`),supportsJson:!0,options:["yes"],async run(z){let J=r({env:z.env,flags:z.flags,cwd:z.cwd});if(J.credentialSource==="env"||J.credentialSource==="session"){let X=J.credentialSource==="session",Y=X?"session":"environment",Z=X?"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.",Q=Fi(z.env);if(!Q){let te={removed:!1,reason:Y,path:null};if(z.json)z.stdout(ke(Se(this.name,te)));else z.stdout(`${Z}
|
|
85
|
-
`);return 0}if(z.flags.yes!==!0){let te={removed:!1,reason:Y,path:Q};if(z.json)z.stdout(ke(Se(this.name,te)));else z.stdout(`${Z}
|
|
86
|
-
A stored credential also exists at ${Q} — repeat with --yes to remove it.
|
|
87
|
-
`);return 0}let ee=yo(z.env);if(z.json)z.stdout(ke(Se(this.name,ee)));else z.stdout(`Removed ${ee.path}
|
|
88
|
-
${X?"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."}
|
|
89
|
-
`);return 0}if(z.flags.yes!==!0&&J.credential){if(z.json||!z.confirm)throw new e("approval_required","Removing the stored credential needs approval. Repeat with `--yes`.");if(!await z.confirm(`Remove the stored credential at ${J.credentialPath}? Signing back in takes \`hlix login\`.`))throw new e("cancelled","Logout cancelled.")}let V=yo(z.env);if(z.json)z.stdout(ke(Se(this.name,V)));else z.stdout(V.removed?`Removed ${V.path}
|
|
90
|
-
`:`No stored credential at ${V.path}
|
|
91
|
-
`);return 0}},ga={...jr,name:"logout",usage:jr.usage.replace("hlix auth logout","hlix logout"),agentTool:!1};import{existsSync as ip,readFileSync as Sa}from"node:fs";import{homedir as xa}from"node:os";import{join as ja}from"node:path";import{constants as Er,existsSync as Uo,lstatSync as Pr,mkdirSync as ya,openSync as Qd,closeSync as ha,fsyncSync as ep,readFileSync as wa,renameSync as tp,unlinkSync as np,writeFileSync as Do}from"node:fs";import{dirname as rp,join as cn,resolve as Ir}from"node:path";function va(z){if(!Uo(z))return;let J=Pr(z);if(J.isSymbolicLink()||!J.isFile())throw Error(`Refusing to replace a non-regular Hlix file: ${z}`)}function Go(z,J){let V=rp(z);if(ya(V,{recursive:!0,mode:448}),Pr(V).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${V}`);va(z);let X=cn(V,`.hlix-${process.pid}-${crypto.randomUUID()}.tmp`),Y;try{Y=Qd(X,Er.O_WRONLY|Er.O_CREAT|Er.O_EXCL|Er.O_NOFOLLOW,384),Do(Y,J.endsWith(`
|
|
92
|
-
`)?J:`${J}
|
|
93
|
-
`,"utf8"),ep(Y),ha(Y),Y=void 0,tp(X,z)}catch(Z){if(Y!==void 0)ha(Y);if(Uo(X))np(X);throw Z}}function op(z,J){Go(z,`${JSON.stringify(J,null,2)}
|
|
94
|
-
`)}function sp(z){return cn(Ir(z),".hlix","config.json")}function ba(z){return cn(Ir(z),".hlix","state.json")}function _r(z){try{let J=JSON.parse(wa(sp(z),"utf8"));return J.schemaVersion===1&&J.workspaceId&&J.apiUrl?J:null}catch{return null}}function Cr(z){let J=cn(Ir(z),".hlix");if(ya(J,{recursive:!0,mode:448}),Pr(J).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${J}`);let V=cn(J,".gitignore");if(!Uo(V))Do(V,`state.json
|
|
95
|
-
`,{mode:420,flag:"wx"});va(V);let X=cn(Ir(z),".hlixignore");if(!Pr(X,{throwIfNoEntry:!1}))Do(X,`# Additional project-local paths to exclude from Hlix snapshots.
|
|
96
|
-
`,{mode:420,flag:"wx"})}function Bo(z,J){op(ba(z),{...J,snapshotOnly:J.snapshotOnly??a(z)?.snapshotOnly,includedPaths:J.includedPaths??a(z)?.includedPaths})}function a(z){try{let J=JSON.parse(wa(ba(z),"utf8"));return J.schemaVersion===1&&J.repoId&&/^[a-f0-9]{40}$/.test(J.commitSha)?J:null}catch{return null}}var On=20000,Wo=2000000;function S(z){if(z===void 0)return;let J=typeof z==="number"?z:Number(z.trim());return Number.isInteger(J)&&J>=On&&J<=Wo?J:void 0}function A(z){if(z===void 0)return!1;let J=E(z);if(J!==void 0)return J;let V=Number(z.trim());return Number.isInteger(V)&&V>=On?V:void 0}var p=["cloud","docker","local"],u={cloud:"Cloud Machine",docker:"Docker container",local:"local environment"},$r={"claude-code":!0,codex:!0,opencode:!0,goose:!0,"qwen-code":!0,pi:!0,hlix:!0},s=Object.keys($r),O="hlix",Ea={dockerImage:"Docker containers only",harness:"local environments and Docker containers only",memoryTokens:"all execution environments",maskToolOutputs:"all execution environments",model:"local environments and Docker containers only",sandbox:"all execution environments",yolo:"all execution environments"},ln=["dockerImage","harness","maskToolOutputs","memoryTokens","model","sandbox","yolo"],zo=["projectId","workspaceId","apiUrl"],ap=`# Machine-wide setup for Hlix.
|
|
97
|
-
# A model server of your own goes under providers. Name its secret with apiKeyEnv.
|
|
98
|
-
`;function Tr(z=process.env){return ja(z.HLIX_CONFIG_HOME??xa(),".hlix","hlix.yml")}function cp(z){return ja(z.HLIX_CONFIG_HOME??xa(),".hlix","config.json")}function lp(z=process.env){let J=_a(z);return J?pp(J):null}function k(z,J=process.env){let V=lp(J),X=Oo(z),Z=t(z)?.config??null,Q=X?.loaded.file?jt(X.loaded.file).binding:null,ee={},te={},re=(ne)=>{let se=fp(Q,ne),ie=se!==void 0?se:Z?.[ne],pe=V?.[ne];if(ie!==void 0)ee[ne]=ie,te[ne]="project";else if(pe!==void 0)ee[ne]=pe,te[ne]="global"};for(let ne of ln)re(ne);for(let ne of zo){let se=Z?.[ne];if(se!==void 0)ee[ne]=se,te[ne]="project"}return{merged:ee,sources:te,global:V,project:Z,paths:{global:Tr(J),project:X?sa(X.root):null},providers:gp(X?.loaded??null,V?.providers)}}function Pa(z){return[...ln,...zo].map((V)=>({key:V,value:z.merged[V]??null,source:z.sources[V]??"default"}))}function dp(z,J){if(z==="sandbox"&&!p.includes(J))return`sandbox must be one of ${p.join(", ")}; got "${J}".`;if(z==="harness"&&!s.includes(J))return`harness must be one of ${s.join(", ")}; got "${J}".`;if(z==="model"&&J.trim()==="")return"model must not be empty.";if(z==="memoryTokens"){let V=Number(J.trim());if(!Number.isInteger(V)||V<On)return`memoryTokens must be a whole number of tokens, at least ${On}; got "${J}".`;if(V>Wo)return`memoryTokens must be at most ${Wo}; got "${J}".`}if(z==="dockerImage"&&J.trim()==="")return"dockerImage must not be empty.";if(z==="maskToolOutputs"&&A(J)===void 0)return`maskToolOutputs must be true, false or a whole number of tokens of at least ${On}; got "${J}".`;if(z==="yolo"&&E(J)===void 0)return`yolo must be true or false; got "${J}".`;return null}function E(z){if(z===void 0)return;let J=z.trim().toLowerCase();if(["true","1","yes","on"].includes(J))return!0;if(["false","0","no","off"].includes(J))return!1;return}function Jo(z){if(ln.includes(z))return z;let J=zo.includes(z);throw new e("invalid_usage",J?`${z} is written by \`hlix init\` and \`hlix import\`, not by \`hlix config set\`.`:`Unknown setting: ${z}. Known settings: ${ln.join(", ")}.`)}function Ko(z,J){let V=dp(z,J);if(V)throw new e("invalid_usage",V);return J}function I(z){if(Ko(z.key,z.value),z.scope==="global"){let V=Tr(z.env),X=_a(z.env)??{schema:1},Y=ka(X,z.key,z.value);if(Y!==X)Ia(z.env,Y);return V}let J=Oo(z.cwd);if(!J)throw new e("not_initialized","This folder is not bound to hlix. Run `hlix init` here, or set it machine-wide with --global.");try{return yr(J.root,(V)=>ka(V,z.key,z.value)).path}catch(V){if(V instanceof e)throw V;throw new e("invalid_project_file",V instanceof Error?V.message:"Could not write hlix.yml.")}}function Ia(z,J){let V=Tr(z),X=$n(J,ap),Y=on(X);if(!Y.ok){let Z=Y.issues.map((Q)=>`${Q.path}: ${Q.message}`).join("; ");throw new e("invalid_project_file",`${V}: ${Z}`)}Go(V,X)}function _a(z){let J=Tr(z);if(ip(J)){let X;try{X=Sa(J,"utf8")}catch{return null}let Y=on(X);if(!Y.ok){let Z=Y.issues.map((Q)=>`${Q.path}: ${Q.message}`).join("; ");throw new e("invalid_project_file",`${J}: ${Z}`)}return Y.file}let V=up(z);if(!V)return null;return Ia(z,V),V}function pp(z){let J=jt(z).binding,V=J.harness&&J.harness in $r?J.harness:void 0;return{schemaVersion:1,...J.dockerImage?{dockerImage:J.dockerImage}:{},...V?{harness:V}:{},...J.memoryTokens?{memoryTokens:J.memoryTokens}:{},...J.maskToolOutputs?{maskToolOutputs:J.maskToolOutputs}:{},...J.model?{model:J.model}:{},...J.sandbox?{sandbox:J.sandbox}:{},...J.yolo?{yolo:J.yolo}:{},...z.providers?{providers:z.providers}:{}}}function up(z){let J;try{J=JSON.parse(Sa(cp(z),"utf8"))}catch{return null}if(!J||typeof J!=="object"||J.schemaVersion!==1)return null;let V=J,X={schema:1},Y={};if(typeof V.harness==="string"&&V.harness in $r)Y.harness=V.harness;if(typeof V.model==="string"&&V.model.trim())Y.model=V.model.trim();let Z=typeof V.memoryTokens==="number"?V.memoryTokens:typeof V.memoryTokens==="string"?Number(V.memoryTokens):void 0;if(Z!==void 0&&Number.isInteger(Z)&&Z>=1&&Z<=2000000)Y.memoryTokens=Z;if(V.yolo==="true"||V.yolo===!0)Y.yolo=!0;if(V.yolo==="false"||V.yolo===!1)Y.yolo=!1;if(Object.keys(Y).length)X.coder=Y;let Q={};if(V.sandbox==="cloud"||V.sandbox==="local"||V.sandbox==="docker")Q.runtime=V.sandbox;if(typeof V.dockerImage==="string"&&V.dockerImage.trim())Q.image=V.dockerImage.trim();if(Object.keys(Q).length)X.local=Q;let ee=mp(V.providers);if(ee)X.providers=ee;let te=Ut.safeParse(X);if(te.success)return te.data;if(!X.providers)return null;let re={...X,providers:void 0},ne=Ut.safeParse(re);return ne.success?ne.data:null}function mp(z){if(!Array.isArray(z))return;let J=[];for(let V of z){if(!V||typeof V!=="object")continue;let X=V;if(typeof X.name!=="string"||typeof X.url!=="string"||!Array.isArray(X.models))continue;let Y=X.models.filter((te)=>typeof te==="string"&&te.length>0);if(!Y.length)continue;let Z={name:X.name,url:X.url,models:Y,...typeof X.apiKeyEnv==="string"?{apiKeyEnv:X.apiKeyEnv}:{},...typeof X.apiKey==="string"&&X.apiKey.length>0?{apiKey:X.apiKey}:{}},Q=Ut.safeParse({schema:1,providers:[Z]}),ee=Q.success?Q.data.providers?.[0]:void 0;if(ee)J.push(ee)}return J.length?J:void 0}function fp(z,J){if(!z)return;if(J==="harness"){let V=z.harness;return V&&V in $r?V:void 0}return z[J]}function gp(z,J){let V=z?.file?.providers;if(V===void 0)return J;if(z?.local?.providers!==void 0)return V;return V.map(({name:X,url:Y,models:Z})=>({name:X,url:Y,models:Z}))}function ka(z,J,V){if(J==="sandbox"){let X=V==="docker"?"docker":V==="local"?"local":"cloud";if(z.local?.runtime===X)return z;return{...z,local:{...z.local,runtime:X}}}if(J==="dockerImage"){let X=V.trim();if(z.local?.image===X)return z;return{...z,local:{...z.local,image:X}}}if(J==="harness"){if(z.coder?.harness===V)return z;return{...z,coder:{...z.coder,harness:V}}}if(J==="model"){let X=V.trim();if(z.coder?.model===X)return z;return{...z,coder:{...z.coder,model:X}}}if(J==="memoryTokens"){let X=S(V);if(X===void 0||z.coder?.memoryTokens===X)return z;return{...z,coder:{...z.coder,memoryTokens:X}}}if(J==="maskToolOutputs"){let X=A(V);if(X===void 0||z.coder?.maskToolOutputs===X)return z;return{...z,coder:{...z.coder,maskToolOutputs:X}}}if(J==="yolo"){let X=E(V);if(X===void 0||z.coder?.yolo===X)return z;return{...z,coder:{...z.coder,yolo:X}}}return z}var Ca=ln.join(" | "),qo={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(`
|
|
99
|
-
`),supportsJson:!0,async run(z){let J=k(z.cwd,z.env),V=Pa(J);if(z.json)return z.stdout(ke(Se(qo.name,{settings:V,paths:J.paths}))),0;return z.stdout(`${ht(["setting","value","source","applies to"],V.map((X)=>[X.key,X.value??"-",X.source,Ea[X.key]??"this folder's binding"]))}
|
|
100
|
-
`),z.stdout(`
|
|
101
|
-
global ${J.paths.global}
|
|
102
|
-
`),z.stdout(`project ${J.paths.project??"- (this folder is not bound to hlix)"}
|
|
103
|
-
`),0}},Vo={name:"config get",summary:"Print one setting's effective value",usage:[`Usage: hlix config get <${Ca}> [--cwd <dir>] [--json]`,"","Prints the value the cascade resolves for one key, or exits 1 when no","file names it."].join(`
|
|
104
|
-
`),supportsJson:!0,args:{min:1,max:1},async run(z){let J=Jo(z.args[0]),V=k(z.cwd,z.env),X=V.merged[J]??null,Y=V.sources[J]??"default";if(z.json)return z.stdout(ke(Se(Vo.name,{key:J,value:X,source:Y}))),X===null?1:0;if(X===null)return z.stderr(`${J} is not set. Set it with \`hlix config set ${J} <value>\`.
|
|
105
|
-
`),1;return z.stdout(`${X}
|
|
106
|
-
`),0}},Xo={name:"config set",summary:"Set one setting for this folder, or for the machine with --global",usage:[`Usage: hlix config set <${Ca}> <value> [--global] [--cwd <dir>] [--json]`,"","Writes this folder's hlix.yml, or ~/.hlix/hlix.yml with --global.","Other keys in the file are left untouched. The binding keys","(projectId, workspaceId, apiUrl) are written by init/import and are","refused here."].join(`
|
|
107
|
-
`),supportsJson:!0,options:["global"],args:{min:2,max:2},async run(z){let J=Jo(z.args[0]),V=Ko(J,z.args[1]),X=z.flags.global===!0?"global":"project",Y=I({key:J,value:V,scope:X,cwd:z.cwd,env:z.env});if(z.json)return z.stdout(ke(Se(Xo.name,{key:J,value:V,scope:X,path:Y}))),0;return z.stdout(`${J} = ${V} (${X}: ${Y})
|
|
108
|
-
`),0}};var hp="project-manager",yp=2000,wp="Cloud work landed. Run /pull (hlix pull) to bring it into this folder.",$a=new Set(["done","pr_created"]),vp=new Set(["done","pr_created","failed","canceled"]),bp={"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 kp(z){let J=z.role?bp[z.role]:void 0;return J?`${z.name} · ${J}`:z.name}function Sp(z){return z.replace(/^project-/,"").replace(/[-_]+/g," ")}function yt(z){return typeof z==="string"&&z.trim()?z.trim():void 0}function Ta(z){if(z.status==="running")return null;let J=z.detail??{kind:""},V=Sp(z.stepId);if(J.kind==="narration"){let X=Array.isArray(J.tasks)?J.tasks.filter((Z)=>typeof Z==="string"):[];V=yt(J.title)??(X.length>0?X.join(", "):V);let Y=yt(J.reason);if(Y)V+=` — ${Y}`}else if(J.kind==="reason"&&yt(J.reason))V+=` — ${yt(J.reason)}`;else if(J.kind==="verdict")V=J.approved===!0?"review approved":`review asked for changes${yt(J.feedback)?` — ${yt(J.feedback)}`:""}`;else if(J.kind==="dispatch"&&typeof J.launched==="number")V+=` — ${J.launched} started`;return z.status==="failed"?`${V} (failed)`:V}function Aa(z){return{kind:"cycle",text:`cycle "${z.title}": ${z.stage}`}}function xp(z){return{kind:"task",text:`task "${z.title||z.id}": ${z.status}`}}function Ra(z){return{kind:"preview",text:`preview: ${z.state}${z.url?` ${z.url}`:""}`}}function jp(z,J,V){let X=[],Y=J.activity.filter((Z)=>Ta(Z)!==null&&!V.has(Z.id));if(!z){X.push({kind:"project",text:`${J.project.name}: ${J.project.status} (${J.project.runStatus})`});for(let Z of J.cycles)if(!vp.has(Z.status))X.push(Aa(Z));if(J.preview.url)X.push(Ra(J.preview))}else{if(z.project.status!==J.project.status||z.project.runStatus!==J.project.runStatus)X.push({kind:"project",text:`project: ${J.project.status} (${J.project.runStatus})`});let Z=!1;for(let Q of J.cycles){let ee=z.cycles.find((te)=>te.id===Q.id);if(ee&&ee.status===Q.status)continue;if(X.push(Aa(Q)),$a.has(Q.status)&&!(ee&&$a.has(ee.status)))Z=!0}for(let Q of J.tasks){let ee=z.tasks.find((te)=>te.id===Q.id);if(!ee||ee.status!==Q.status)X.push(xp(Q))}for(let Q of J.agents){let ee=z.agents.find((te)=>te.id===Q.id);if(ee&&ee.state!==Q.state)X.push({kind:"agent",text:`${kp(Q)} ${Q.state==="working"?"started working":"is idle"}`})}if(z.preview.url!==J.preview.url||z.preview.state!==J.preview.state){if(X.push(Ra(J.preview)),J.preview.url&&z.preview.url!==J.preview.url)Z=!0}if(Z)X.push({kind:"landed",text:wp})}for(let Z of Y){if(V.has(Z.id))continue;V.add(Z.id),X.push({kind:"activity",text:Ta(Z)})}return X}function Oa(z){if(typeof z==="string")return yt(z);if(Array.isArray(z))return yt(z.map((J)=>J&&typeof J==="object"&&J.type==="text"?String(J.text??""):"").join(""));return}var Ep=(z)=>z==="assistant"?"project manager":"to project manager";class Na{seen=new Set;drafts=new Map;spoke=!1;unsaved;lines(z){switch(z.type){case"MESSAGES_SNAPSHOT":{let J=z.messages.filter((V)=>{if(typeof V.id!=="string"||this.seen.has(V.id))return!1;if(V.role==="assistant"&&this.unsaved!==void 0&&Oa(V.content)===this.unsaved)return this.unsaved=void 0,this.seen.add(V.id),!1;return!0});for(let V of J)this.seen.add(V.id);return J.flatMap((V)=>{if(V.role!=="user"&&V.role!=="assistant")return[];let X=Oa(V.content);return X?[{kind:"message",text:`${Ep(V.role)}: ${X}`}]:[]})}case"RUN_STARTED":return this.spoke=!1,[{kind:"run",text:"project manager is working…"}];case"TEXT_MESSAGE_START":return this.drafts.set(z.messageId,""),[];case"TEXT_MESSAGE_CONTENT":return this.drafts.set(z.messageId,(this.drafts.get(z.messageId)??"")+z.delta),[];case"TEXT_MESSAGE_END":{let J=yt(this.drafts.get(z.messageId));if(this.drafts.delete(z.messageId),this.seen.has(z.messageId))return[];if(this.seen.add(z.messageId),!J)return[];return this.spoke=!0,this.unsaved=J,[{kind:"message",text:`project manager: ${J}`}]}case"TOOL_CALL_START":return[{kind:"tool",text:`project manager → ${z.toolCallName.replace(/[_-]+/g," ")}`}];case"CUSTOM":{let J=z.name==="hlix.turn_saved"?z.value?.messageId:void 0;if(typeof J==="string"&&this.spoke)this.seen.add(J),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: ${z.message}`}];default:return[]}}}async function Fa(z,J,V){let X=Ht(J),Y=new AbortController,Z=()=>Y.abort();if(V.signal?.aborted)return;V.signal?.addEventListener("abort",Z,{once:!0});let Q=new Na,ee,te=null,re=!1,ne=null,se=()=>{if(te){re=!0;return}te=(async()=>{do{re=!1;let ce=new AbortController,le=()=>ce.abort();Y.signal.addEventListener("abort",le,{once:!0}),ne=le;try{for await(let me of z.live.follow(hp,X,{signal:ce.signal}))for(let ve of Q.lines(me))V.emit(ve)}finally{ne=null,Y.signal.removeEventListener("abort",le)}}while(re&&!Y.signal.aborted)})().catch((ce)=>{if(Y.signal.aborted)return;ee=ce,Y.abort()}).finally(()=>{te=null})},ie=()=>{let ce=ne;if(!ce)return se();re=!0,at(yp,Y.signal).then(()=>{if(ne===ce)ce()})},pe=new Set,fe;try{se();for await(let{state:ce,event:le}of z.live.project(J,{signal:Y.signal})){if(le.type==="CUSTOM"){let me=le.value;if(le.name==="hlix.thread_changed"&&me?.threadId===X){if(me.kind==="run_finished")ie();else if(me.kind!=="renamed")se()}continue}for(let me of jp(fe,ce,pe))V.emit(me);fe=ce}}catch(ce){if(!Y.signal.aborted)ee??=ce}finally{Y.abort(),V.signal?.removeEventListener("abort",Z),await te}if(ee!==void 0)throw ee}function Ha(z){let V=(typeof z.flags.project==="string"?z.flags.project.trim():"")||t(z.cwd)?.config.projectId;if(!V)throw new e("missing_argument","A project is required: pass --project <id>, or run this inside a folder bound to a project.");return V}var La="The project manager is busy with another message. Try again in a moment; /watch shows what it is doing.";function Bt(z,J){if(typeof z!=="object"||z===null)return"";let V=z[J];return V===null||V===void 0?"":String(V)}var Yo={name:"projects list",summary:"List the projects in your workspace",usage:"Usage: hlix projects list [--json]",supportsJson:!0,signIn:!0,async run(z){let J=await z.requireClient().projects.list();if(z.json)return z.stdout(ke(Se(Yo.name,J))),0;let V=Array.isArray(J)?J:[];if(V.length===0)return z.stdout(`No projects.
|
|
109
|
-
`),0;return z.stdout(`${ht(["ID","NAME","STACK"],V.map((X)=>[Bt(X,"id"),Bt(X,"name"),Bt(X,"stack")]))}
|
|
110
|
-
`),0}},Zo={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(`
|
|
111
|
-
`),supportsJson:!0,signIn:!0,args:{min:0,max:1},async run(z){let J=z.args[0]??t(z.cwd)?.config.projectId;if(!J)throw new e("missing_argument","A project id is required, or run this inside a folder bound to a project.");let V=await z.requireClient().projects.get(J);if(z.json)return z.stdout(ke(Se(Zo.name,V))),0;let X=V.repos;return z.stdout(`${Me([["id",Bt(V,"id")],["name",Bt(V,"name")],["stack",Bt(V,"stack")],["status",Bt(V,"status")],["repos",Array.isArray(X)?String(X.length):""]].filter(([,Y])=>Y!==""))}
|
|
112
|
-
`),0}},Qo={name:"projects delete",summary:"Delete a project from your workspace",usage:"Usage: hlix projects delete <id|name> [--yes] [--json]",supportsJson:!0,signIn:!0,options:["yes"],args:{min:1,max:1},async run(z){let J=z.requireClient(),V=z.args[0],X=await J.projects.list(),Y=X.find((re)=>re.id===V),Z=Y?[Y]:X.filter((re)=>re.name===V);if(Z.length===0)throw new e("not_found",`No project named or identified by "${V}".`);if(Z.length>1)throw new e("invalid_usage",`More than one project is named "${V}". Use its ID.`);let Q=Z[0],ee=`Delete project "${Q.name}"?`;if(z.stderr(`${ee}
|
|
113
|
-
`),z.flags.yes!==!0){if(t(z.cwd)?.config.projectId===Q.id)throw new e("approval_required","This folder is bound to that project. Pass --yes to delete it.");if(z.json||!z.confirm)throw new e("approval_required","Project deletion requires --yes when not interactive.");if(!await z.confirm(ee))throw new e("cancelled","Project deletion cancelled.")}let te=await J.projects.delete(Q.id);if(z.json)z.stdout(ke(Se(Qo.name,te)));else z.stdout(`Deleted project "${Q.name}".
|
|
114
|
-
`);return 0}},es={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(`
|
|
115
|
-
`),supportsJson:!0,signIn:!0,options:["project"],agentTool:!1,async run(z){let J=Ha(z),V=z.requireClient();return await V.projects.get(J),await Fa(V,J,{...z.signal?{signal:z.signal}:{},emit:(X)=>z.stdout(z.json?`${JSON.stringify(Se(es.name,X))}
|
|
116
|
-
`:`${i(X.text)}
|
|
117
|
-
`)}),0}},ts={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(`
|
|
118
|
-
`),supportsJson:!0,signIn:!0,options:["project"],args:{min:1,max:1e4},freeText:!0,async run(z){let J=Ha(z),V=z.args.join(" ").trim();if(!V)throw new e("missing_argument","A message is required.");let X=z.requireClient(),Y="";try{for await(let Z of X.live.run("project-manager",{threadId:Ht(J),text:V},z.signal?{signal:z.signal}:void 0))if(Z.type==="TEXT_MESSAGE_CONTENT"){if(Y+=Z.delta,!z.json)z.stdout(i(Z.delta))}else if(Z.type==="RUN_ERROR"){if(Z.code==="409")throw new e("conflict",La);throw new e("server_error",`The project manager could not answer: ${Z.message}`)}}catch(Z){if(Z instanceof Ot)throw new e("conflict",La);throw Z}if(z.json)z.stdout(ke(Se(ts.name,{answer:Y})));else if(!Y)z.stdout(`Sent. The project manager answered without text.
|
|
119
|
-
`);else if(!Y.endsWith(`
|
|
120
|
-
`))z.stdout(`
|
|
121
|
-
`);return 0}};function ns(z,J){let V=z.args[0];if(!V)throw new e("missing_argument",`A ${J} id is required.`);return V}function Ma(z,J){let V=z.flags[J];return typeof V==="string"&&V.trim()?V.trim():void 0}function wt(z,J){if(typeof z!=="object"||z===null)return"";let V=z[J];return V===null||V===void 0?"":String(V)}var rs={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(`
|
|
122
|
-
`),supportsJson:!0,signIn:!0,options:["project","status"],async run(z){let J=Ma(z,"project")??t(z.cwd)?.config.projectId,V=Ma(z,"status"),X=await z.requireClient().tasks.list({...J?{projectId:J}:{},...V?{status:V}:{}});if(z.json)return z.stdout(ke(Se(rs.name,X))),0;let Y=Array.isArray(X)?X:[];if(Y.length===0)return z.stdout(`No tasks.
|
|
123
|
-
`),0;return z.stdout(`${ht(["ID","STATUS","TITLE"],Y.map((Z)=>[wt(Z,"id"),wt(Z,"status"),wt(Z,"title")||wt(Z,"description").split(`
|
|
124
|
-
`)[0]||""]))}
|
|
125
|
-
`),0}},os={name:"tasks get",summary:"Show one task",usage:"Usage: hlix tasks get <task-id> [--json]",supportsJson:!0,signIn:!0,args:{min:1,max:1},async run(z){let J=ns(z,"task"),V=await z.requireClient().tasks.get(J);if(z.json)return z.stdout(ke(Se(os.name,V))),0;return z.stdout(`${Me([["id",wt(V,"id")],["status",wt(V,"status")],["title",wt(V,"title")],["project",wt(V,"projectId")],["description",wt(V,"description")]])}
|
|
126
|
-
`),0}},ss={name:"tasks review",summary:"Show the verified review evidence of a task's cycle",usage:"Usage: hlix tasks review <task-id> [--json]",supportsJson:!0,signIn:!0,args:{min:1,max:1},async run(z){let J=ns(z,"task"),V=z.requireClient(),X=await V.tasks.get(J);if(!X.cycleId)throw new e("not_found",`Task ${J} belongs to no cycle, so there is no change to review.`);let Y=await V.cycles.review(X.cycleId);if(z.json)return z.stdout(ke(Se(ss.name,Y))),0;return z.stdout(`${JSON.stringify(Y,null,2)}
|
|
127
|
-
`),0}},is={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(`
|
|
128
|
-
`),supportsJson:!0,signIn:!0,args:{min:1,max:1},async run(z){let J=ns(z,"task"),V=z.requireClient(),{projectId:X}=await V.tasks.get(J),Y;for await(let Z of V.live.task(X,J))if(z.json)z.stdout(`${JSON.stringify(Se(is.name,Z))}
|
|
129
|
-
`);else if(Z.state==="unmet")z.stdout(`error: ${i(Z.reason)}
|
|
130
|
-
`);else if(Z.task&&Z.task.status!==Y)Y=Z.task.status,z.stdout(`${i(Y)}
|
|
131
|
-
`);return 0}};import{realpath as tm}from"node:fs/promises";import{resolve as nm}from"node:path";import{parse as Jp}from"jsonc-parser";import{parse as Kp}from"smol-toml";import{parse as qp}from"yaml";var Nn={install:null,previewCommand:null,previewPort:null,verifyCommand:null,packageManager:null};var Pp=[["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]],Ip=/^(?: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+[^|;&]*)?$/,_p=["vite","next","webpack","react-scripts","@rsbuild/core","parcel"],Fn=8080,Ar=8000,Cp=String.raw`import http.server as h, urllib.parse as u, sys, os, re, io
|
|
132
|
-
B = (sys.argv[2] if len(sys.argv) > 2 else "").rstrip("/")
|
|
133
|
-
D = os.path.abspath(sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else ".")
|
|
134
|
-
E = sys.argv[4] if len(sys.argv) > 4 else "index.html"
|
|
135
|
-
P = int(os.environ.get("PORT") or ${Fn})
|
|
136
|
-
L = re.compile(rb"((?:src|href|action|poster)\s*=\s*[\"'])/(?!/)" + (rb"(?!" + re.escape(B[1:].encode()) + rb"(?:/|[\"']))" if B else b""))
|
|
137
|
-
class H(h.SimpleHTTPRequestHandler):
|
|
138
|
-
def __init__(s, *a, **k):
|
|
139
|
-
super().__init__(*a, directory=D, **k)
|
|
140
|
-
def send_head(s):
|
|
141
|
-
raw = u.urlsplit(s.path).path
|
|
142
|
-
if B and (raw == B or raw.startswith(B + "/")):
|
|
143
|
-
s.path = s.path[len(B):] or "/"
|
|
144
|
-
p = u.unquote(u.urlsplit(s.path).path).replace(chr(92), "/")
|
|
145
|
-
if any(x.startswith(".") for x in p.split("/")):
|
|
146
|
-
s.send_error(404)
|
|
147
|
-
return None
|
|
148
|
-
f = s.translate_path(s.path)
|
|
149
|
-
if os.path.isdir(f) and p.endswith("/"):
|
|
150
|
-
f = os.path.join(f, E if os.path.abspath(f) == D else "index.html")
|
|
151
|
-
elif not os.path.exists(f) and "." not in p.rsplit("/", 1)[-1]:
|
|
152
|
-
f = f + ".html" if os.path.isfile(f + ".html") else os.path.join(D, E)
|
|
153
|
-
if not (f.lower().endswith((".html", ".htm")) and os.path.isfile(f)):
|
|
154
|
-
return super().send_head()
|
|
155
|
-
with open(f, "rb") as fh:
|
|
156
|
-
body = fh.read()
|
|
157
|
-
if B:
|
|
158
|
-
body = L.sub(lambda m: m.group(1) + B.encode() + b"/", body)
|
|
159
|
-
s.send_response(200)
|
|
160
|
-
s.send_header("Content-Type", "text/html; charset=utf-8")
|
|
161
|
-
s.send_header("Content-Length", str(len(body)))
|
|
162
|
-
s.end_headers()
|
|
163
|
-
return io.BytesIO(body)
|
|
164
|
-
def list_directory(s, path):
|
|
165
|
-
s.send_error(404)
|
|
166
|
-
return None
|
|
167
|
-
h.ThreadingHTTPServer(("", P), H).serve_forever()
|
|
168
|
-
`;function Nr(z=".",J="index.html"){return`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${Ln(Cp)} "$PREVIEW_PUBLIC_PATH" ${z}${J==="index.html"?"":` ${za(J)}`}`}function Ba(z){if(z.has("index.html"))return"index.html";let J=[...z].filter((V)=>!V.startsWith(".")&&!/[\\/]/.test(V)&&/\.html?$/i.test(V));return J.length===1?J[0]:null}var Wa="HLIX_PREVIEW_FAILURE";function Rr(z){return`{ echo "${Wa}=${z}"; exit 1; }`}var $p=`const handler = {
|
|
169
|
-
get(target, key) {
|
|
170
|
-
if (key === 'then' || key === 'prototype' || key === '$$typeof') return undefined
|
|
171
|
-
if (key === '__esModule') return false
|
|
172
|
-
if (key === Symbol.toPrimitive) return () => ''
|
|
173
|
-
if (key === 'displayName' || key === 'name') return 'Unavailable'
|
|
174
|
-
return stub
|
|
175
|
-
},
|
|
176
|
-
apply(target, self, args) {
|
|
177
|
-
const props = args[0]
|
|
178
|
-
return props !== null && typeof props === 'object' && !Array.isArray(props) ? null : stub
|
|
179
|
-
},
|
|
180
|
-
}
|
|
181
|
-
const stub = new Proxy(function Unavailable() {}, handler)
|
|
182
|
-
module.exports = stub
|
|
183
|
-
`,Tp=`const path = require('path')
|
|
184
|
-
const loaded = __CONFIG__
|
|
185
|
-
const dir = path.join(__dirname, 'hlix-web')
|
|
186
|
-
// React Native Web's own names, as imported directly and as Expo rewrites them.
|
|
187
|
-
const WEB_ROOT = new Set(['react-native', 'react-native-web', 'react-native-web/dist/index'])
|
|
188
|
-
function withNativeStubs(config) {
|
|
189
|
-
const upstream = config.resolver.resolveRequest
|
|
190
|
-
config.resolver.resolveRequest = (context, moduleName, platform) => {
|
|
191
|
-
if (platform === 'web' && !context.originModulePath.startsWith(dir)) {
|
|
192
|
-
if (WEB_ROOT.has(moduleName)) return { type: 'sourceFile', filePath: path.join(dir, 'react-native.js') }
|
|
193
|
-
if (moduleName.startsWith('react-native/Libraries/')) return { type: 'sourceFile', filePath: path.join(dir, 'native-stub.js') }
|
|
194
|
-
}
|
|
195
|
-
return (upstream || context.resolveRequest)(context, moduleName, platform)
|
|
196
|
-
}
|
|
197
|
-
return config
|
|
198
|
-
}
|
|
199
|
-
module.exports = typeof loaded === 'function'
|
|
200
|
-
? async (...args) => withNativeStubs(await loaded(...args))
|
|
201
|
-
: loaded && typeof loaded.then === 'function' ? loaded.then(withNativeStubs) : withNativeStubs(loaded)
|
|
202
|
-
`,Ap=String.raw`const fs = require("fs"), cp = require("child_process")
|
|
203
|
-
const [base, pm] = process.argv.slice(-2)
|
|
204
|
-
// No preview path: not the preview's own copy. Prepared already: a restart.
|
|
205
|
-
if (!base || fs.existsSync("hlix-web/native-stub.js")) process.exit(0)
|
|
206
|
-
const fail = (code, why) => { console.error("hlix: " + why); console.log("${Wa}=" + code); process.exit(1) }
|
|
207
|
-
const run = (cmd, args) => {
|
|
208
|
-
const res = cp.spawnSync(cmd, args, { stdio: "inherit", env: { ...process.env, CI: "1", EXPO_NO_TELEMETRY: "1" } })
|
|
209
|
-
if (res.status !== 0) fail("packages_unavailable", "could not install " + args.join(" "))
|
|
210
|
-
}
|
|
211
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"))
|
|
212
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
213
|
-
if (!("expo" in deps)) fail("web_build_failed", "This project no longer declares Expo; open its native preview")
|
|
214
|
-
// npm refuses a React Native major change over peer ranges; the others only warn.
|
|
215
|
-
const peers = pm === "npm" ? ["--", "--legacy-peer-deps"] : []
|
|
216
|
-
const missing = ["react-dom", "react-native-web", "@expo/metro-runtime", "babel-preset-expo"].filter((name) => !(name in deps))
|
|
217
|
-
if (missing.length) run("npx", ["expo", "install", ...missing, ...peers])
|
|
218
|
-
fs.mkdirSync("hlix-web", { recursive: true })
|
|
219
|
-
fs.writeFileSync("hlix-web/native-stub.js", ${JSON.stringify($p)})
|
|
220
|
-
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")
|
|
221
|
-
const own = ["metro.config.js", "metro.config.cjs"].find((file) => fs.existsSync(file))
|
|
222
|
-
let config = "require('expo/metro-config').getDefaultConfig(__dirname)"
|
|
223
|
-
if (own && /expo/.test(fs.readFileSync(own, "utf8"))) {
|
|
224
|
-
// Beside the original, so its own __dirname still names the project.
|
|
225
|
-
fs.renameSync(own, "metro.config.hlix-original.js")
|
|
226
|
-
config = "require('./metro.config.hlix-original.js')"
|
|
227
|
-
}
|
|
228
|
-
if (own) fs.rmSync(own, { force: true })
|
|
229
|
-
fs.writeFileSync("metro.config.js", ${JSON.stringify(Tp)}.replace("__CONFIG__", config))
|
|
230
|
-
`,Rp=String.raw`const fs = require("fs")
|
|
231
|
-
const base = (process.argv[process.argv.length - 1] || "").replace(/\/+$/, "")
|
|
232
|
-
if (!base) process.exit(0)
|
|
233
|
-
const dynamic = ["app.config.ts", "app.config.js"].filter((file) => fs.existsSync(file))
|
|
234
|
-
if (dynamic.length || fs.existsSync("app.json")) {
|
|
235
|
-
const json = dynamic.length ? { expo: require("expo/config").getConfig(process.cwd()).exp } : JSON.parse(fs.readFileSync("app.json", "utf8"))
|
|
236
|
-
const expo = json.expo || json
|
|
237
|
-
expo.experiments = { ...expo.experiments, baseUrl: base }
|
|
238
|
-
fs.writeFileSync("app.json", JSON.stringify(json, null, 2))
|
|
239
|
-
for (const file of dynamic) fs.rmSync(file)
|
|
240
|
-
}
|
|
241
|
-
`,Op=String.raw`import json, os, shutil, sys, tarfile, tempfile, urllib.request
|
|
242
|
-
root = sys.argv[1]
|
|
243
|
-
base = "https://storage.googleapis.com/flutter_infra_release/releases"
|
|
244
|
-
index = json.load(urllib.request.urlopen(base + "/releases_linux.json", timeout=60))
|
|
245
|
-
stable = index["current_release"]["stable"]
|
|
246
|
-
release = next(r for r in index["releases"] if r["hash"] == stable)
|
|
247
|
-
tmp = tempfile.mkdtemp(dir=root)
|
|
248
|
-
archive = os.path.join(tmp, "flutter.tar.xz")
|
|
249
|
-
with urllib.request.urlopen(base + "/" + release["archive"], timeout=600) as src, open(archive, "wb") as out:
|
|
250
|
-
shutil.copyfileobj(src, out)
|
|
251
|
-
with tarfile.open(archive) as tar:
|
|
252
|
-
tar.extractall(tmp, filter="tar")
|
|
253
|
-
os.remove(archive)
|
|
254
|
-
os.rename(os.path.join(tmp, "flutter"), os.path.join(root, "sdk"))
|
|
255
|
-
shutil.rmtree(tmp, ignore_errors=True)
|
|
256
|
-
print("hlix: Flutter " + release["version"] + " installed")
|
|
257
|
-
`,Np=String.raw`import sys, zipfile
|
|
258
|
-
args = [a for a in sys.argv[1:] if a not in ("-o", "-q")]
|
|
259
|
-
dest = args[args.index("-d") + 1] if "-d" in args else "."
|
|
260
|
-
zipfile.ZipFile(args[0]).extractall(dest)
|
|
261
|
-
`;function Da(z,J){return`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${Ln(z)} ${J}`}function Fp(){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)"; ${Da(Op,'"$HOME/.cache/hlix-flutter"')}; } || ${Rr("flutter_sdk_unavailable")}; }`,`{ command -v unzip >/dev/null 2>&1 || { printf '#!/bin/sh\\n%s "$@"\\n' ${za(Da(Np,""))} > "$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 || ${Rr("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/" && ${Nr("build/web")}; } || ${Rr("web_build_failed")}; }`].join(" && ")}function Lp(z){let J=`printf %s ${Ln(Ap)} | base64 -d | node - "$PREVIEW_PUBLIC_PATH" ${z}`,V=`CI=1 npx expo export --platform web --output-dir dist && ${Nr("dist")}`;return`${J} && ${Ja(Rp,"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"; ${V}; } || ${Rr("web_build_failed")}; }`}function za(z){return`'${z.replace(/'/g,"'\\''")}'`}var Hp=String.raw`const fs = require("fs")
|
|
262
|
-
const base = (process.argv[process.argv.length - 1] || "").replace(/\/+$/, "")
|
|
263
|
-
if (!base) process.exit(0)
|
|
264
|
-
const file = ["next.config.ts", "next.config.mts", "next.config.mjs", "next.config.js", "next.config.cjs"].find((name) => fs.existsSync(name))
|
|
265
|
-
const wrap = (name) => "(async (...args) => { const c = typeof " + name + " === \"function\" ? await " + name + "(...args) : await " + name + "; return { ...c, basePath: " + JSON.stringify(base) + " } })"
|
|
266
|
-
if (!file) {
|
|
267
|
-
fs.writeFileSync("next.config.mjs", "export default { basePath: " + JSON.stringify(base) + " }\n")
|
|
268
|
-
process.exit(0)
|
|
269
|
-
}
|
|
270
|
-
let text = fs.readFileSync(file, "utf8")
|
|
271
|
-
if (text.includes("__hlixPreviewConfig")) process.exit(0)
|
|
272
|
-
if (/\bexport\s+default\b/.test(text)) {
|
|
273
|
-
text = text.replace(/\bexport\s+default\b/, "const __hlixPreviewConfig =") + "\nexport default " + wrap("__hlixPreviewConfig") + "\n"
|
|
274
|
-
} else if (/\bmodule\.exports\s*=/.test(text)) {
|
|
275
|
-
text += "\nconst __hlixPreviewConfig = module.exports\nmodule.exports = " + wrap("__hlixPreviewConfig") + "\n"
|
|
276
|
-
} else {
|
|
277
|
-
process.exit(0)
|
|
278
|
-
}
|
|
279
|
-
fs.writeFileSync(file, text)
|
|
280
|
-
`,Mp=String.raw`import os, re, sys
|
|
281
|
-
hosts = [h for h in (sys.argv[2] if len(sys.argv) > 2 else "").split(",") if h]
|
|
282
|
-
if not hosts:
|
|
283
|
-
sys.exit(0)
|
|
284
|
-
match = re.search(r"DJANGO_SETTINGS_MODULE['\"]\s*,\s*['\"]([\w.]+)['\"]", open("manage.py").read())
|
|
285
|
-
if not match:
|
|
286
|
-
sys.exit(0)
|
|
287
|
-
module = match.group(1).replace(".", "/")
|
|
288
|
-
path = module + ".py" if os.path.isfile(module + ".py") else os.path.join(module, "__init__.py")
|
|
289
|
-
if not os.path.isfile(path) or "# hlix preview hosts" in open(path).read():
|
|
290
|
-
sys.exit(0)
|
|
291
|
-
with open(path, "a") as f:
|
|
292
|
-
f.write("\n# hlix preview hosts\nALLOWED_HOSTS = list(globals().get('ALLOWED_HOSTS') or ['.localhost', '127.0.0.1', '[::1]']) + %r\n" % hosts)
|
|
293
|
-
`;function Ja(z,J){return`printf %s ${Ln(z)} | base64 -d | node - "$${J}"`}var Dp=["test","typecheck","check","build","lint"],Up=/^(?:\.eslintrc(?:\.(?:js|cjs|mjs|json|ya?ml))?|eslint\.config\.(?:js|cjs|mjs|ts|cts|mts))$/;function Gp(z,J){return/\bnext\s+lint\b/.test(z)&&![...J].some((V)=>Up.test(V))}var rw=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 Bp=["dev","start","serve","preview"];function Fr(z){if(!z)return{};try{let J=JSON.parse(z);return J&&typeof J==="object"?J:{}}catch{return{}}}function Ka(z){return{...vt(z.dependencies)?z.dependencies:{},...vt(z.devDependencies)?z.devDependencies:{}}}function Ua(z){let J=Ka(Fr(z.packageJson));if("expo"in J||"react-native"in J)return!0;if(Array.from(z.rootFiles).some((V)=>V==="hlix.mobile.json"||V==="AndroidManifest.xml"||/\.xc(?:odeproj|workspace)$/.test(V)))return!0;return cs(z)}function cs(z){if(!new Set(z.rootFiles).has("pubspec.yaml"))return!1;let J=z.configFiles?.["pubspec.yaml"];return J===void 0||/^\s+sdk:\s*flutter\s*$/m.test(J)}function qa(z){let J=new Set(z.rootFiles),V=Fr(z.packageJson),X=typeof V.packageManager==="string"?V.packageManager.split("@")[0]:"",Y=X==="bun"||J.has("bun.lock")||J.has("bun.lockb")?"bun":X==="pnpm"||J.has("pnpm-lock.yaml")?"pnpm":X==="yarn"||J.has("yarn.lock")?"yarn":X==="npm"||J.has("package.json")?"npm":null,Z=Ba(J);if(!Y){if(Ua(z)&&!cs(z))return{...Nn,mobile:!0};if(cs(z))return{...Nn,previewCommand:Fp(),previewPort:Fn,mobile:!0};let re=zp(J,z.configFiles??{});if(re)return re;return Z?{...Nn,previewCommand:Nr(".",Z),previewPort:Fn}:Nn}let Q=Va(V,J,Y),ee={install:`${Y} install`,verifyCommand:Q.verifyCommand,packageManager:Y},te=Q.webApp?null:Wp(z.workspacePackages??[],Y)[0]??null;if(te){let re=(ne)=>`cd ${te.dir} && ${ne}`;return{...ee,previewCommand:re(te.previewCommand),previewPort:te.previewPort,verifyCommand:ee.verifyCommand??(te.verifyCommand?re(te.verifyCommand):null),...te.mobile?{mobile:!0}:{}}}return{...ee,previewCommand:Q.previewCommand,previewPort:Q.previewPort,...Q.mobile||!Q.previewCommand&&Ua(z)?{mobile:!0}:{}}}function Va(z,J,V,X){let Y=vt(z.scripts)?z.scripts:{},Z=(we)=>`${V} run ${we}`,Q=(we,Pe)=>`${Z(we)}${V==="npm"?" --":""} ${Pe}`,ee=Bp.find((we)=>typeof Y[we]==="string"),te=Dp.find((we)=>typeof Y[we]==="string"&&!/no test specified/i.test(String(Y[we]))&&!/(?:^|\s)(?:--watch(?:All)?|-w)(?:\s|=|$)/.test(String(Y[we]))&&!Gp(String(Y[we]),J)),re=te?Z(te):null,ne=Ka(z),se={previewCommand:null,previewPort:null,verifyCommand:re,webApp:!1,mobile:!1,explicitPort:!1};if("react-native"in ne&&!("expo"in ne)&&!_p.some((we)=>(we in ne)))return{...se,mobile:!0};if("expo"in ne)return{previewCommand:Lp(V),previewPort:X??Fn,verifyCommand:re,webApp:!0,mobile:!0,explicitPort:!1};let ie=Pp.find(([we])=>(we in ne)),pe=ee?as(String(Y[ee]))??ie?.[1]??null:null,fe=Ba(J);if(!ee&&!ie&&fe)return{...se,previewCommand:Nr(".",fe),previewPort:X??Fn};if(!ee)return se;let ce=String(Y[ee]).trim(),le=X!=null?` --port ${X}`:"",me=ce.split("&&").map((we)=>we.trim()),ve=le||(pe!=null&&as(ce)==null&&Ip.test(me.at(-1))?` --port ${pe}`:""),Ee=ve?Q(ee,ve.trim()):Z(ee);if(me.length>1&&me.every((we)=>/^vite(?:\s|$)/.test(we))&&!("@sveltejs/kit"in ne)){let we={npm:"npx",bun:"bunx",pnpm:"pnpm exec",yarn:"yarn exec"}[V];Ee=me.map((Pe,ge)=>`${we} ${Pe} --base "$PREVIEW_BASE_PATH/"${/^vite\s+build\b/.test(Pe)?"":" --host 0.0.0.0"}${ge===me.length-1?ve:""}`).join(" && ")}else if(/^vite(?:\s+(?:dev|serve|preview))?(?:\s|$)/.test(ce)&&!/&&|;|\|/.test(ce)&&!("@sveltejs/kit"in ne))Ee=Q(ee,`--base "$PREVIEW_BASE_PATH/" --host 0.0.0.0${ve}`);else if(/^astro\s+(?:dev|preview)(?:\s|$)/.test(ce))Ee=Q(ee,`--base "$PREVIEW_BASE_PATH"${ve}`);else if(/^next\s+(?:dev|start)(?:\s|$)/.test(ce))Ee=`${Ja(Hp,"PREVIEW_BASE_PATH")} && ${Ee}`;else if(/^nuxt\s+(?:dev|preview|start)(?:\s|$)/.test(ce))Ee=`NUXT_APP_BASE_URL="$PREVIEW_BASE_PATH/" ${Ee}`;return{previewCommand:Ee,previewPort:X??pe,verifyCommand:re,webApp:Boolean(ie),mobile:!1,explicitPort:as(ce)!=null}}var Ga=["web","app","frontend","site","www","client","dashboard"];function Wp(z,J){let V=z.filter((Y)=>Or(Y.dir)).map((Y)=>{let Z=Fr(Y.packageJson),Q=new Set(Y.rootFiles??[]);return{dir:Y.dir,pkg:Z,files:Q,...Va(Z,Q,J)}}).filter((Y)=>Y.webApp&&Y.previewCommand&&Y.previewPort!=null),X=(Y)=>{let Z=Ga.indexOf(Y.split("/").at(-1)??"");return Z<0?Ga.length:Z};return V.sort((Y,Z)=>Number(Y.mobile)-Number(Z.mobile)||Number(!Y.dir.startsWith("apps/"))-Number(!Z.dir.startsWith("apps/"))||X(Y.dir)-X(Z.dir)||(Y.dir<Z.dir?-1:Y.dir>Z.dir?1:0))}function Or(z){return/^[A-Za-z0-9._@-]+(?:\/[A-Za-z0-9._@-]+)*$/.test(z)&&!z.split("/").some((J)=>J===".."||J===".")}function Xa(z){let J=Fr(z.packageJson),V=Array.isArray(J.workspaces)?J.workspaces:vt(J.workspaces)&&Array.isArray(J.workspaces.packages)?J.workspaces.packages:[],X=z.configFiles?.["pnpm-workspace.yaml"]??"";for(let ee of X.split(/\r?\n/)){let te=ee.match(/^\s*-\s*["']?([^"'#\s]+)["']?/);if(te)V.push(te[1])}let Y=V.filter((ee)=>typeof ee==="string"&&!ee.startsWith("!"));if(Y.length===0&&new Set(z.rootFiles).has("turbo.json"))Y.push("apps/*","packages/*");for(let ee of Object.values(vt(J.scripts)?J.scripts:{})){if(typeof ee!=="string")continue;let te=ee.match(/^\s*cd\s+([A-Za-z0-9._@/-]+)\s*&&/)?.[1];if(te&&Or(te))Y.push(te)}let Z=new Set,Q=new Set;for(let ee of Y){let te=ee.replace(/^\.\//,"").replace(/\/$/,"");if(/^[^*]+\/\*$/.test(te)&&Or(te.slice(0,-2)))Z.add(te.slice(0,-2));else if(!te.includes("*")&&Or(te))Q.add(te)}return{parents:[...Z].sort(),packages:[...Q].sort()}}function zp(z,J){let V=`${J["requirements.txt"]??""}
|
|
294
|
-
${J["pyproject.toml"]??""}`.toLowerCase(),X=(ne)=>new RegExp(`(^|[\\s"'\\[,])${ne}\\b`,"m").test(V),Y=z.has("requirements.txt")?'"$V/bin/pip" install -q -r requirements.txt':z.has("pyproject.toml")?'"$V/bin/pip" install -q .':null,Z=(ne,se="")=>Y?`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" && ${Y}${se} && touch "$V/.ready"; }; } && "$V/bin/python" ${ne}`:null,Q=X("pytest")?Z("-m pytest",' && "$V/bin/pip" install -q pytest'):null,te=["main.py","app.py","server.py","api.py"].find((ne)=>z.has(ne))?.replace(/\.py$/,""),re=(ne,se=Q)=>({...Nn,previewCommand:ne,previewPort:Ar,verifyCommand:se});if(z.has("manage.py")){let ne=`python3 -c 'import base64,sys;exec(base64.b64decode(sys.argv[1]))' ${Ln(Mp)} "$PREVIEW_ALLOWED_HOSTS"`;return re(`${ne} && python3 manage.py runserver 0.0.0.0:${Ar}`,Q??(X("django")?Z("manage.py test"):null))}if(te&&X("fastapi"))return re(`python3 -m uvicorn ${te}:app --host 0.0.0.0 --port ${Ar} --root-path "$PREVIEW_PUBLIC_PATH"`);if(te&&X("flask"))return re(`python3 -m flask --app ${te} run --host 0.0.0.0 --port ${Ar}`);return null}function Ln(z){return btoa(z)}function as(z){let J=z.match(/(?:--port(?:=|\s+)|-p\s+|\bPORT=)(\d{2,5})\b/),V=J?Number(J[1]):NaN;return Number.isInteger(V)&&V>0&&V<=65535?V:null}function vt(z){return Boolean(z)&&typeof z==="object"&&!Array.isArray(z)}function Ya(z){let J=new Set(z.rootFiles),V=new Set;if(J.has("package.json")){for(let Y of["coverage",".cache"])V.add(Y);if(["package-lock.json","pnpm-lock.yaml","yarn.lock","bun.lock","bun.lockb"].some((Y)=>J.has(Y)))V.add("node_modules")}if(J.has("Cargo.toml"))V.add("target");if(["pyproject.toml","requirements.txt","setup.py"].some((Y)=>J.has(Y)))V.add("__pycache__");if(J.has("composer.json")&&J.has("composer.lock"))V.add("vendor");for(let Y of ls({...z,rootFiles:J}))V.add(Y);return[...V].sort()}function pt(z,J,V){let X=(z.match(/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*|[A-Za-z_$][\w$]*|[^\s]/g)??[]).filter((te)=>!te.startsWith("//")&&!te.startsWith("/*"));if(X[0]!=="{"){let te=X.findIndex((ne,se)=>ne==="export"&&X[se+1]==="default"),re=X.findIndex((ne,se)=>ne==="module"&&X.slice(se+1,se+4).join("")===".exports=");if(te<0&&re<0)return null;if(X=X.slice(te>=0?te+2:re+4),["defineConfig","defineNuxtConfig"].includes(X[0]??"")&&X[1]==="(")X=X.slice(2);if(X[0]!=="{")return null}if(X.some((te,re)=>te==="."&&X[re+1]==="."&&X[re+2]==="."))return null;let Y=(te="")=>te.replace(/^["']|["']$/g,""),Z=[],Q,ee=0;for(let te=0;te<X.length;te++){let re=X[te];if(re==="{")Z.push(X[te-1]===":"?Y(X[te-2]):"");if(re==="}")Z.pop();if(!Z.length)break;if(re==="["&&["{",","].includes(X[te-1]??""))return null;if(J&&Z.length===1&&Y(re)===J){if(X[te+1]!==":"||X[te+2]!=="{"||++ee>1)return null}if(Y(re)===V&&(J?Z.length===2&&Z.at(-1)===J:Z.length===1)&&X[te+1]!==":")return null;if(Y(re)!==V||X[te+1]!==":"||(J?Z.length!==2||Z.at(-1)!==J:Z.length!==1))continue;let ne=X[te+2]??"";if(Q!==void 0||!/^["'`][^\\$]*["'`]$/.test(ne)||![",","}"].includes(X[te+3]??""))return null;Q=ne.slice(1,-1)}return Q}function ls(z){let J={};try{let ie=JSON.parse(z.packageJson??"{}");if(vt(ie))J=ie}catch{}let V={...vt(J.dependencies)?J.dependencies:{},...vt(J.devDependencies)?J.devDependencies:{}},X=vt(J.scripts)?Object.entries(J.scripts).filter((ie)=>typeof ie[1]==="string"):[],Y=(ie,pe=ie)=>(ie in V)||X.some(([,fe])=>new RegExp(`(?:^|[;&|\\s])${pe}(?:\\s|$)`).test(fe)),Z=z.configFiles??{},Q=new Set,ee=(ie)=>{if(typeof ie!=="string")return null;let pe=ie.replace(/^\.\//,"").replace(/\/$/,"");return pe&&!pe.startsWith("/")&&!/[\\:*?\[\]#!$`"'\r\n]/.test(pe)&&!pe.split("/").some((fe)=>!fe||[".","..",".git",".hlix"].includes(fe))?pe:null},te=(ie)=>{let pe=ee(ie);if(pe)Q.add(pe)},re=(ie,pe)=>{let fe=X.filter(([ve,Ee])=>/(?:^|:)build(?:$|:)/.test(ve)||new RegExp(`\\b${ie} build\\b`).test(Ee)),ce=fe.filter(([,ve])=>new RegExp(`(?:^|\\s)${ie}(?:\\s|$)`).test(ve));if(!ce.length&&(fe.length||J.workspaces!==void 0))return null;if(fe.some((ve)=>!ce.includes(ve)&&/--(?:out|dist|root|config|project)|\s-[dpc]\b/.test(ve[1])))return null;let le,me=!1;for(let[,ve]of ce){if(/[$`\\;|<>\n]/.test(ve)||/(?:^|\s)(?:cd|pushd|popd)\s/.test(ve))return null;for(let Ee of ve.split("&&")){let we=Ee.match(/"[^"\n]*"|'[^'\n]*'|[^\s]+/g)??[];if(we.some((he)=>/["']/.test(he)&&!/^(?:"[^"\n]*"|'[^'\n]*')$/.test(he)))return null;let Pe=we.map((he)=>he.replace(/^["']|["']$/g,"")),ge=Pe.indexOf(ie);if(ge<0)continue;if(ge!==0&&!(ge===1&&["npx","bunx"].includes(Pe[0])))return null;let de=Pe.slice(ge+1);if(de[0]==="build")de.shift();let ae;for(let he=0;he<de.length;he++){let[_e,...Ae]=de[he].split("="),Re=Ae.length?Ae.join("="):void 0;if(!pe.includes(_e)||ae!==void 0)return null;let Ue=Re??de[++he],Oe=ee(Ue);if(!Oe)return null;ae=Oe}if(me&&ae!==le)return null;me=!0,le=ae}}return le},ne=(ie)=>{let pe=[...new Set([...z.rootFiles,...Object.keys(Z)])].filter((fe)=>fe.startsWith(`${ie}.config.`)||ie==="turbo"&&fe==="turbo.json");if(!pe.length)return"{}";return pe.length===1?Z[pe[0]]??null:null},se=(ie,pe,fe,ce,le,me,ve)=>{let Ee=ne(ie),we=re(ie,le);if(Ee===null||we===null)return;let Pe=me?pt(Ee,null,me):void 0,ge=pt(Ee,pe,fe);if(Pe===null||ge===null)return;let de=Pe===void 0||Pe==="."||Pe==="./"?"":ee(Pe);if(de===null)return;let he=ee(we??ge??ce);if(!he)return;te(de?`${de}/${he}`:he);for(let _e of ve??[])te(de?`${de}/${_e}`:_e)};if(Y("vite"))se("vite","build","outDir","dist",["--outDir","--out-dir"],"root");if(Y("next")){let ie=ne("next"),pe=ie===null?null:pt(ie,null,"output");if(ie!==null&&(pe===void 0||pe==="standalone"||pe==="export"&&pt(ie,null,"distDir")===void 0))se("next",null,"distDir",".next",[],void 0,pe==="export"?["out"]:[])}if(Y("astro"))se("astro",null,"outDir","dist",["--outDir","--out-dir"],"root");if(Y("nuxt")){let ie=ne("nuxt");if(ie!==null&&pt(ie,null,"nitro")===void 0&&pt(ie,null,"extends")===void 0)se("nuxt",null,"buildDir",".nuxt",[],"rootDir",[".output"])}if(Y("turbo"))se("turbo",null,"cacheDir",".turbo",["--cache-dir"]);if(Y("webpack")){let ie=ne("webpack");if(ie!==null&&pt(ie,null,"context")===void 0)se("webpack","output","path","dist",["--output-path"])}if(Y("rollup"))se("rollup","output","dir",void 0,["--dir","-d"]);if(Y("parcel")||Y("parcel-bundler","parcel")){let ie=re("parcel",["--dist-dir"]);if(ie!==null&&J.targets===void 0&&!["main","module","browser"].some((pe)=>typeof J[pe]==="string"))te(ie??"dist")}if(Y("react-scripts")&&re("react-scripts",[])!==null)te("build");if(Y("typescript","tsc")){let ie=re("tsc",["--outDir"]),pe=Object.keys(Z).filter((fe)=>/^tsconfig(?:\.[^/]*)?\.json$/.test(fe));if(ie!==null&&pe.length===1&&pe[0]==="tsconfig.json"){let fe=Z["tsconfig.json"];if(pt(fe,null,"extends")===void 0&&pt(fe,null,"references")===void 0){let ce=pt(fe,"compilerOptions","outDir");if(ce!==null)te(ie??ce)}}}if(ds(Z)){te("build"),te("dist");for(let ie of z.rootFiles)if(ie.endsWith(".egg-info"))te(ie)}return[...Q].sort()}function ds(z){let J=(z["pyproject.toml"]??"").split(/^\[build-system\]\s*$/m)[1]?.split(/^\[/m)[0]??"";return/^build-backend\s*=\s*["'][^"']+["']/m.test(J)||/(?:from\s+(?:setuptools|distutils.core)\s+import\s+.*\bsetup\b|(?:setuptools|distutils.core)\.setup\s*\()/.test(z["setup.py"]??"")}var Be=(z)=>z&&typeof z==="object"&&!Array.isArray(z)?z:{},dn=(z)=>Array.isArray(z)?z.filter((J)=>typeof J==="string"):[];function Za(z){let J=[];function V(de,ae="json"){let he=z.get(de);if(!he)return{};try{if(ae==="yaml")return Be(qp(he,{maxAliasCount:50}));if(ae==="toml")return Be(Kp(he));if(ae==="jsonc"){let _e=[],Ae=Jp(he,_e,{allowTrailingComma:!0});if(_e.length)throw Error("invalid JSONC");return Be(Ae)}return Be(JSON.parse(he))}catch{return J.push(`Could not parse ${de}`),{}}}let X=[...z.keys()].sort(),Y=V("package.json"),Z={packageJson:z.get("package.json")??null,rootFiles:X.filter((de)=>!de.includes("/")),configFiles:Object.fromEntries(["requirements.txt","pyproject.toml","pnpm-workspace.yaml"].flatMap((de)=>z.get(de)?[[de,z.get(de)]]:[]))},Q=Xa(Z),ee=X.flatMap((de)=>{let ae=de.replace(/\/package\.json$/,""),he=ae!==de&&(Q.packages.includes(ae)||Q.parents.some((Ae)=>ae.startsWith(`${Ae}/`)&&!ae.slice(Ae.length+1).includes("/"))),_e=z.get(de);return he&&_e?[{dir:ae,packageJson:_e}]:[]}),te=qa({...Z,workspacePackages:ee}),re=typeof Y.packageManager==="string"?/^(npm|pnpm|yarn|bun)@(.+)$/.exec(Y.packageManager):null,ne=Object.create(null);for(let[de,ae]of Object.entries(Be(Y.engines)))if(typeof ae==="string")ne[de]=ae;if(re)ne[re[1]]=re[2].split("+")[0];let se=V("composer.json"),ie={...Be(se["require-dev"]),...Be(se.require)},pe={...typeof ie.php==="string"?{constraint:ie.php}:{},extensions:Object.keys(ie).filter((de)=>de.startsWith("ext-")).map((de)=>de.slice(4)).sort()};for(let[de,ae]of[[".nvmrc","node"],[".node-version","node"],[".python-version","python"],[".php-version","php"],[".bun-version","bun"]]){let he=z.get(de)?.trim();if(he)ne[ae]=he}for(let de of(z.get(".tool-versions")??"").split(/\r?\n/)){let[ae,he]=de.replace(/#.*/,"").trim().split(/\s+/);if(ae&&he)ne[ae==="nodejs"?"node":ae]=he}for(let de of[".mise.toml","mise.toml"])for(let[ae,he]of Object.entries(Be(V(de,"toml").tools)))if(typeof he==="string"||typeof he==="number")ne[ae]=String(he);else J.push(`Unsupported tool version for ${ae} in ${de}`);let fe=[];for(let de of X.filter((ae)=>/(^|\/)package.json$/.test(ae))){let ae=de==="package.json"?Y:V(de),he={...Be(ae.dependencies),...Be(ae.devDependencies)};for(let _e of["nuxt","next","astro","@sveltejs/kit","vite"])if(_e in he)fe.push({path:de,name:_e})}for(let[de,ae]of[["yiisoft/yii2","yii2"],["laravel/framework","laravel"]])if(de in ie)fe.push({path:"composer.json",name:ae});let ce=new Set,le=Object.create(null);function me(de,ae){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(de))return;if(ce.add(de),/(?:^|_)HOST$/.test(de)&&typeof ae==="string"&&/^[a-zA-Z0-9_.-]+$/.test(ae))le[de]=ae}for(let de of X.filter((ae)=>/(^|\/)\.env\.(example|sample|template)$/.test(ae)))for(let ae of(z.get(de)??"").split(/\r?\n/)){let he=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*(?:#.*)?$/.exec(ae);if(he)me(he[1],he[2].replace(/^['"]|['"]$/g,""))}let ve=[],Ee=[];for(let de of X.filter((ae)=>/(^|\/)(?:docker-compose|compose)(?:[.-][^/]*)?\.ya?ml$/.test(ae)))for(let[ae,he]of Object.entries(Be(V(de,"yaml").services))){let _e=Be(he),Ae=typeof _e.image==="string"?_e.image:"",Re=Ae.split("/").at(-1)?.split(/[:@]/)[0],Ue=Re==="mysql"||Re==="mariadb"?"mysql":Re==="postgres"?"postgres":Re==="redis"?"redis":null;if(Ue)ve.push({file:de,name:ae,kind:Ue,image:Ae});else if(Re!=="traefik"&&Re!=="nginx"&&Re!=="caddy")Ee.push({file:de,name:ae});for(let[Oe,De]of Object.entries(Be(_e.environment)))me(Oe,De);for(let Oe of dn(_e.environment)){let De=Oe.indexOf("=");me(De<0?Oe:Oe.slice(0,De),De<0?null:Oe.slice(De+1))}}let we=X.find((de)=>de===".devcontainer/devcontainer.json")??X.find((de)=>de==="devcontainer.json"),Pe;if(we){let de=V(we,"jsonc");for(let ae of[de.containerEnv,de.remoteEnv])for(let[he,_e]of Object.entries(Be(ae)))me(he,_e);Pe={...typeof de.image==="string"?{image:de.image}:{},services:[...typeof de.service==="string"?[de.service]:[],...dn(de.runServices)],ports:Array.isArray(de.forwardPorts)?de.forwardPorts.filter((ae)=>Number.isInteger(ae)&&Number(ae)>0&&Number(ae)<=65535):[],commands:[de.onCreateCommand,de.updateContentCommand,de.postCreateCommand,de.postStartCommand].filter((ae)=>typeof ae==="string")}}let ge=dn(Y.workspaces).length?dn(Y.workspaces):dn(Be(Y.workspaces).packages);return ge.push(...dn(V("pnpm-workspace.yaml","yaml").packages)),{language:z.has("package.json")?"typescript":z.has("pyproject.toml")||z.has("requirements.txt")?"python":z.has("go.mod")?"go":z.has("Cargo.toml")?"rust":z.has("composer.json")?"php":z.has("Gemfile")?"ruby":"other",commands:te,packageManager:re?{name:re[1],version:re[2]}:te.packageManager?{name:te.packageManager}:null,lockfiles:X.filter((de)=>/(^|\/)(bun.lockb?|pnpm-lock.yaml|yarn.lock|package-lock.json|composer.lock|uv.lock|poetry.lock|Pipfile.lock|Cargo.lock|Gemfile.lock)$/.test(de)),toolchain:ne,php:pe,workspaces:[...new Set(ge)].sort(),frameworks:fe,turbo:z.has("turbo.json")||"turbo"in Be(Y.devDependencies)||"turbo"in Be(Y.dependencies),services:ve,unsupportedServices:Ee,envKeys:[...ce].sort(),envHosts:le,...Pe?{devcontainer:Pe}:{},warnings:J}}import{createHash as Jn}from"node:crypto";import{createReadStream as au}from"node:fs";import{lstat as yc,mkdir as cu,readFile as Wn,readdir as lu,readlink as du,realpath as wc,stat as vc,writeFile as pu}from"node:fs/promises";import{basename as zt,dirname as uu,join as Kn,relative as Mr,resolve as Dr,sep as mu}from"node:path";import{execFile as fu,spawnSync as gu}from"node:child_process";import Bn from"ignore";import{createReadStream as Vp}from"node:fs";import{lstat as pn,mkdtemp as Xp,readFile as ms,readdir as Lr,rename as Yp,rm as Zp,writeFile as Qp}from"node:fs/promises";import{join as Xe}from"node:path";import tc from"ignore";function Hn(z,J){if(Array.isArray(J))return J.some((V)=>Hn(z,V));if(!J||z.split("/").some((V)=>V===".git"||V===".hlix"))return!1;return z===J||z.startsWith(`${J}/`)}function Mn(z,J){if(typeof J!=="string")return J?.some((V)=>Mn(z,V))??!1;return Hn(z,J)||J.startsWith(`${z}/`)}function Qa(z,J,V,X){let Y=new Map,Z=z.length,Q=0;for(let ne of z){let se=ne.path.indexOf("/"),ie=se<0?ne.path:ne.path.slice(0,se+1),pe=Y.get(ie)??{count:0,bytes:0,included:!1};pe.count++,pe.bytes+=ne.size??0,pe.included||=Hn(ne.path,X),Y.set(ie,pe),Q+=ne.size??0}let ee=Q>V,te=[...Y].sort(([ne,se],[ie,pe])=>Number(se.included)-Number(pe.included)||(ee?pe.bytes-se.bytes:pe.count-se.count)||ne.localeCompare(ie)),re=[];for(let[ne,se]of te){if(Z<=J&&Q<=V)break;re.push(ne),Z-=se.count,Q-=se.bytes}return re}function ps(z,J){return J.some((V)=>z===V||V.endsWith("/")&&z.startsWith(V))}function us(z){return`upload limit; add /${z} to .hlixignore, or try --include ${z.replace(/\/$/,"")}`.slice(0,200)}function ec(z){if(z.length<=5000)return z;return[...z.slice(0,4999),{path:z[4999].path,reason:`${z.length-4999} additional skipped paths (including this path); full list: hlix import --dry-run --json`}]}var oc="# --- managed by Hlix: safe to edit above/below, this block is regenerated ---",fs="# --- end managed by Hlix ---",Hr=new Set(["agent-artifacts",".context",".claude/worktrees"]),eu=/(?:^|\/)(?:Makefile|Dockerfile|Containerfile|Justfile|Rakefile|Gemfile)(?:\.[^/]*)?$/i,tu=/\.(?:md|txt|json)$/i,nc=/(?:^|\n)\s*(?:\/\/|\/\*+|\*|#|<!--)\s*(?:@generated\b|generated by\b|do not edit\b)|(?:^|\n)\s*\/\/[#@]\s*sourceMappingURL=/i,rc=/\.(?:log(?:\.\d+)?|tmp|cache|pyc|tsbuildinfo|map)$/i;function Dn(z){let J=[...z.matchAll(new RegExp(`^${oc}\\r?$`,"gm"))],V=[...z.matchAll(new RegExp(`^${fs}\\r?$`,"gm"))];if(!J.length&&!V.length)return{before:z,after:"",managed:""};if(J.length!==1||V.length!==1||V[0].index<J[0].index)return null;let X=J[0].index,Z=V[0].index+fs.length,Q=z.slice(Z).match(/^\r?\n/)?.[0]??"";return{before:z.slice(0,X),after:z.slice(Z+Q.length),managed:z.slice(X,Z)}}function gs(z){let J=Dn(z);return(J?J.before+`
|
|
295
|
-
`+J.after:z).split(/\r?\n/).filter((V)=>V.startsWith("!")&&V.length>1).map((V)=>V.slice(1))}async function sc(z,J){let V=Xe(z,".hlixignore"),X="";try{let Y=await pn(V).catch((ae)=>{if(ae.code==="ENOENT")return null;throw ae});if(Y&&!Y.isFile())return{warning:"Kept .hlixignore unchanged: managed rules require a regular file."};if(Y)X=await ms(V,"utf8");let Z=Dn(X);if(!Z)return{warning:"Kept .hlixignore unchanged: repair its managed-block markers before refreshing."};let Q=gs(X),ee=tc().add(Q),te=[],re=[],ne=tc(),se=new Set;for(let ae of J.tracked){let he=ae.split("/");while(he.length)se.add(he.join("/")),he.pop()}let ie=0,pe=0,fe=()=>ie<30000&&pe<268435456,ce=(ae)=>se.has(ae)||Mn(ae,J.includes)||Q.some((he)=>{let _e=he.replace(/^\//,"").split(/[?*[\\]/)[0];return!_e||_e.startsWith(`${ae}/`)||ee.ignores(`${ae}/`)||ee.ignores(ae)}),le=async(ae,he,_e=!1)=>{if(J.signal?.throwIfAborted(),!fe()||ce(ae)||J.protectedPath(ae,he))return!1;ie++;let Ae=await pn(Xe(z,ae));if(Ae.isSymbolicLink())return he;if(Ae.isDirectory()){let Oe=(await Lr(Xe(z,ae))).sort();for(let De of Oe){if(De===".git")continue;if(!await le(`${ae}/${De}`,he,_e))return!1}return!0}if(!Ae.isFile()||pe+Ae.size>268435456)return!1;let Re="",Ue="";for await(let Oe of Vp(Xe(z,ae),{encoding:"utf8",signal:J.signal})){if(pe+=Buffer.byteLength(Oe),Re.length<4096)Re+=Oe.slice(0,4096-Re.length);let De=Ue+Oe;if(J.protectedContent(ae,De))return!1;Ue=De.slice(-4096)}return he||nc.test(Re)||nc.test(Ue)||!eu.test(ae)&&!/^#!|^<\?php/.test(Re)&&(_e&&tu.test(ae)||rc.test(ae))},me=new Set,ve=async(ae,he=[],_e=!1)=>{if(J.signal?.throwIfAborted(),!fe())return;let Ae=Xe(z,ae),Re=await Lr(Ae,{withFileTypes:!0}),Ue=async(Ce)=>Re.find((Le)=>Le.name===Ce)?.isFile()&&(await pn(Xe(Ae,Ce))).size<1048576?ms(Xe(Ae,Ce),"utf8"):null,Oe=await Ue("package.json"),De=await Ue("composer.json"),Ne=!1,Jt=new Set;try{let Ce=JSON.parse(await Ue("composer.lock")??"null");Ne=Array.isArray(Ce?.packages);for(let Ie of[...Ce?.packages??[],...Ce?.["packages-dev"]??[]]){if(typeof Ie.name==="string")Jt.add(Ie.name);if(Ie.dist?.type==="path")Ne=!1}}catch{}try{let Ce=JSON.parse(Oe??"{}"),Ie=Array.isArray(Ce.workspaces)?Ce.workspaces:Ce.workspaces?.packages;for(let Le of Array.isArray(Ie)?Ie:[]){if(typeof Le!=="string"||Le.startsWith("!"))continue;let Ct=(ae?`${ae}/`:"")+Le.replace(/^\.\//,"");re.push(Ct),ne.add(Ct)}}catch{}let Kt=[Oe,De].filter(Boolean).join(`
|
|
296
|
-
`),kt={};for(let Ce of Re){if(!/^(?:(?:vite|next|nuxt|astro|webpack|rollup)\.config\.[cm]?[jt]s|tsconfig(?:\.[^/]*)?\.json|turbo\.json|pyproject\.toml|setup\.py)$/.test(Ce.name))continue;let Ie=await Ue(Ce.name);if(Ie!==null)kt[Ce.name]=Ie}let qt={packageJson:Oe,rootFiles:Re.map((Ce)=>Ce.name),configFiles:kt};_e||=ds(kt);let Qn=Ya(qt);for(let Ce of ls(qt))me.add(ae?`${ae}/${Ce}`:Ce);let _t=new Set([...Qn,...he]);for(let Ce of Re.sort((Ie,Le)=>Ie.name<Le.name?-1:Ie.name>Le.name?1:0)){if([".git",".hlix",".hlixignore"].includes(Ce.name)||Ce.isSymbolicLink())continue;let Ie=ae?`${ae}/${Ce.name}`:Ce.name;if(/[\n\r\\*?[\]!#]/.test(Ie)||Ie.endsWith(" "))continue;if(ie++,!fe())return;if(Ce.isDirectory()){let Le=await pn(Xe(z,Ie,".git")).then(()=>J.isRepository(Ie),()=>!1),Ct=Hr.has(Ie)||[...Hr].some((Ze)=>Ie.startsWith(`${Ze}/`)),er=J.gitIgnored.directories.some((Ze)=>`${Ie}/`.startsWith(Ze)),$t=ne.ignores(`${Ie}/`)||re.some((Ze)=>Ze.split(/[?*[\\]/)[0].startsWith(`${Ie}/`))||Kt.includes(Ce.name)||/(?:^|\/)(?:src|lib|apps|packages|tests|resources|public)(?:\/|$)/.test(Ie),Vt=Le&&(Ct||er)&&!$t;if(Ce.name==="vendor"&&Ne)for(let Ze of await Lr(Xe(z,Ie),{withFileTypes:!0})){if(["autoload.php","composer","bin"].includes(Ze.name))continue;if(!Ze.isDirectory()){Ne=!1;break}for(let yn of await Lr(Xe(z,Ie,Ze.name)))if(!Jt.has(`${Ze.name}/${yn}`))Ne=!1}let St=Qn.includes(Ce.name)&&(Ce.name==="node_modules"||Ce.name==="vendor"&&Ne&&!/"type"\s*:\s*"path"/.test(De??"")),tr=me.has(Ie)||_e&&Ce.name.endsWith(".egg-info");if(((Ce.name==="node_modules"||Ce.name==="vendor"?St:_t.has(Ce.name))||Hr.has(Ie)&&!$t||["logs","runtime","tmp"].includes(Ce.name)||Vt||tr)&&!ce(Ie)&&await le(Ie,St||Vt||tr,_t.has(Ce.name)||Hr.has(Ie))){te.push(`/${Ie}/`);continue}if(!Le&&!["node_modules","vendor"].includes(Ce.name))await ve(Ie,_t.has("__pycache__")?["__pycache__"]:[],_e)}else if(Ce.isFile()&&(rc.test(Ce.name)||(await pn(Xe(z,Ie))).size>J.maxFileBytes)&&!ce(Ie)&&await le(Ie,!1))te.push(`/${Ie}`)}};await ve("");let Ee=X.includes(`\r
|
|
297
|
-
`)?`\r
|
|
298
|
-
`:`
|
|
299
|
-
`,we=[oc,...te.sort(),fs,""].join(Ee),ge=Z.before+(Z.before&&!Z.before.endsWith(`
|
|
300
|
-
`)?Ee:"")+we+Z.after;if(J.write!==!1&&ge!==X){let ae=await Xp(Xe(z,".hlixignore-"));try{let he=Xe(ae,"rules");await Qp(he,ge,{mode:Y?.mode??420});let _e=await pn(V).catch((Ae)=>{if(Ae.code==="ENOENT")return null;throw Ae});if(_e?!_e.isFile()||_e.ino!==Y?.ino||_e.dev!==Y?.dev||await ms(V,"utf8")!==X:Y!==null)return{warning:"Kept .hlixignore unchanged: it changed while generated paths were being checked."};await Yp(he,V)}finally{await Zp(ae,{recursive:!0,force:!0})}}let de=te.every((ae)=>ae.endsWith("/"))?"generated folders":"generated paths";return{rules:te,report:`Hlix ignored ${te.length} ${de} — see .hlixignore`}}catch(Y){return J.signal?.throwIfAborted(),{warning:`Kept .hlixignore unchanged: could not safely refresh generated paths (${Y.code??"unreadable"}).`}}}import{readFile as ru}from"node:fs/promises";import{join as ou}from"node:path";function nu(z){let J=z.trim();if(!J||/^[|>[{]/.test(J))return null;let V=J.match(/^(["'])([\s\S]*)\1$/);if(!V&&/^["']/.test(J))return null;return(V?V[2].trim():J.replace(/(?:^|\s)#.*$/,"").trim())||null}function ic(z){let J=z.split(/\r?\n/),V=J.findIndex((Q)=>/^tasks:\s*(?:#.*)?$/.test(Q));if(V===-1)return{tasks:[],partial:/^tasks:\s*\S/m.test(z)};let X=[],Y=!1,Z=-1;for(let Q of J.slice(V+1)){if(!Q.trim()||/^\s*#/.test(Q))continue;let ee=Q.length-Q.trimStart().length,te=Q.match(/^(\s*-(?:\s+|$))(.*)$/);if(te){if(Z!==-1&&ee>=Z)continue;if(X.push({}),Z=te[2]?te[1].length:-1,!te[2])continue}else if(ee===0)break;else if(X.length===0)continue;else if(Z===-1)Z=ee;else if(ee!==Z)continue;let re=(te?te[2]:Q.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!re)continue;let ne=re[1];if(ne!=="name"&&ne!=="before"&&ne!=="init"&&ne!=="command")continue;let se=nu(re[2]);if(se===null)Y=!0;else X[X.length-1][ne]=se}return{tasks:X,partial:Y}}async function Wt(z,J){try{return await ru(ou(z,...J.split("/")),"utf8")}catch(V){if(V.code==="ENOENT")return null;throw V}}function ac(z){try{let J=z.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(J)}catch{return null}}function Et(z){if(typeof z==="string"&&z.trim())return[z.trim()];if(Array.isArray(z))return z.flatMap(Et);if(z&&typeof z==="object")return Object.values(z).flatMap(Et);return[]}function hs(z){if(!z||typeof z!=="object")return[];return Object.keys(z).filter((J)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(J))}function su(z,J){let V=new Set,X=[/\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(J)X.push(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::[-?][^}]*)?\}/g);for(let Y of X)for(let Z of z.matchAll(Y))V.add(Z[1]);return[...V]}function iu(z,J){if(z.has("bun.lock")||z.has("bun.lockb")||J?.startsWith("bun@"))return"bun install";if(z.has("pnpm-lock.yaml")||J?.startsWith("pnpm@"))return"pnpm install";if(z.has("yarn.lock")||J?.startsWith("yarn@"))return"yarn install";if(z.has("package.json"))return"npm install";return null}function cc(z){let J=typeof z==="number"?z:Number(z);return Number.isInteger(J)&&J>0&&J<=65535?J:null}function tt(z,J,V){if(!z.some((X)=>X.path===J&&X.kind===V))z.push({path:J,kind:V})}async function lc(z,J,V){let X=[],Y=[],Z=[],Q=[],ee=new Map,te=new Set,re=new Set,ne=[],se={},ie=null,pe=0,fe=await Wt(z,".cursor/environment.json");if(fe){tt(X,".cursor/environment.json","cursor");let ge=ac(fe);if(!ge)ne.push("Could not parse .cursor/environment.json; it remains quarantined.");else{Y.push(...Et(ge.install));let de=Et(ge.start);if(de[0])ie=de[0];if(Array.isArray(ge.terminals))for(let ae of ge.terminals){if(!ae||typeof ae!=="object")continue;let he=ae;if(typeof he.command!=="string"||!he.command.trim())continue;Q.push({name:typeof he.name==="string"&&he.name.trim()?he.name.trim():"Terminal",command:he.command.trim(),...typeof he.cwd==="string"&&he.cwd.trim()?{cwd:he.cwd.trim()}:{}})}}}let ce=J.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":J.has("devcontainer.json")?"devcontainer.json":null;if(ce){tt(X,ce,"devcontainer");let ge=ac(V.get(ce)??await Wt(z,ce)??"");if(!ge)ne.push(`Could not parse ${ce}; it remains quarantined.`);else{Y.push(...Et(ge.onCreateCommand),...Et(ge.updateContentCommand),...Et(ge.postCreateCommand));let de=Et(ge.postStartCommand);if(!ie&&de[0])ie=de[0];for(let ae of hs(ge.secrets))te.add(ae);for(let ae of[...hs(ge.containerEnv),...hs(ge.remoteEnv)])te.add(ae);if(Array.isArray(ge.forwardPorts))for(let ae of ge.forwardPorts){let he=cc(ae);if(he)ee.set(he,{port:he,visibility:"private"})}}}if(J.has(".gitpod.yml")){tt(X,".gitpod.yml","gitpod");let ge=V.get(".gitpod.yml")??await Wt(z,".gitpod.yml");if(ge===null)ne.push("Could not read .gitpod.yml; its task commands were not imported.");else{let de=ic(ge);pe=de.tasks.filter((ae)=>ae.before).length;for(let ae of de.tasks){if(ae.before)Y.push(ae.before);if(ae.init)Y.push(ae.init);if(!ae.command)continue;if(!ie)ie=ae.command;else Q.push({name:ae.name??"Terminal",command:ae.command})}if(de.partial)ne.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 ge of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(J.has(ge))tt(X,ge,"docker");for(let ge of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(J.has(ge))tt(X,ge,"buildpack");for(let ge of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(J.has(ge))tt(X,ge,"platform");let le=V.get("package.json")??await Wt(z,"package.json");if(le){tt(X,"package.json","package");try{let ge=JSON.parse(le);if(ge.engines?.node)se.node=ge.engines.node;let de=iu(J,ge.packageManager);if(de&&Y.length===pe)Y.push(de);if(ge.scripts?.build&&Z.length===0)Z.push(`${ge.packageManager?.split("@")[0]??(J.has("bun.lock")?"bun":"npm")} run build`);let ae=ge.scripts?.dev?`${J.has("bun.lock")?"bun":"npm"} run dev`:null,he=ge.scripts?.start?`${J.has("bun.lock")?"bun":"npm"} run start`:ae;if(!ie&&he)ie=he}catch{ne.push("Could not parse package.json for environment discovery.")}}if(J.has("uv.lock"))Y.push("uv sync --frozen");else if(J.has("poetry.lock"))Y.push("poetry install --no-interaction");else if(J.has("requirements.txt"))Y.push("python -m pip install -r requirements.txt");if(J.has("go.mod"))Y.push("go mod download");if(J.has("Procfile")){tt(X,"Procfile","procfile");let de=(V.get("Procfile")??"").split(/\r?\n/).find((ae)=>/^web\s*:/.test(ae));if(de)ie=de.replace(/^web\s*:\s*/,"").trim()||ie}let me=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[ge,de]of me){let ae=(V.get(ge)??await Wt(z,ge))?.trim();if(ae)se[de]=ae,tt(X,ge,"tool-version")}let ve=V.get(".tool-versions")??await Wt(z,".tool-versions");if(ve){tt(X,".tool-versions","tool-version");for(let ge of ve.split(/\r?\n/)){let[de,ae]=ge.trim().split(/\s+/,2);if(!ae)continue;if(de==="nodejs")se.node=ae;else if(de==="python")se.python=ae;else if(de==="bun")se.bun=ae}}let Ee=V.get("mise.toml")??await Wt(z,"mise.toml");if(Ee){tt(X,"mise.toml","tool-version");for(let ge of Ee.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))se[ge[1]]=ge[2]}for(let[ge,de]of V){let ae=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(ge)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(ge);for(let he of su(de,ae))re.add(he);for(let he of de.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let _e=cc(he[1]);if(_e)ee.set(_e,{port:_e,visibility:"private"})}}if(X.length===0&&J.size>0)tt(X,"repository","detected");let we=(ge)=>[...new Set(ge.filter(Boolean))],Pe=X.length+Y.length+(ie?1:0);return{sources:X.sort((ge,de)=>ge.path.localeCompare(de.path)),toolchain:se,install:we(Y),build:we(Z),start:ie,terminals:Q,ports:[...ee.values()].sort((ge,de)=>ge.port-de.port),requiredSecretKeys:[...te].sort(),observedSecretKeys:[...re].sort(),confidence:Pe>=4?"high":Pe>=2?"medium":"low",warnings:ne}}var dc=2;var bc=300000,hu=25000,pc=52428800,yu=524288000,zn=1e4,wu="Potential secrets exist in Git history",vu="Never delete .git folders or files to get past this; use .hlixignore instead.",Ur=1048576,Un=20971520,kc=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store",...sn],Hw=Bn().add(kc);var bs="Required project environment value was not found locally: ",bu=/(^|\/)\.env\.(example|sample|template)$/i,ku=/(^|\/)\.env(?:\.[^/]+)?$/i,Su=/(^|\/)(?:\.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,xu=/\.(?:example|sample|template)$/i,ju=/(^|\/)\.(?:npmrc|yarnrc(?:\.yml)?|pypirc)$/i,Eu=/(?:^|\/)(?:__tests__|tests?|fixtures)\/|\.(?:test|spec)\.[^/]+$|\.snap$/i,Pu=/\.(?:md|mdx|txt|rst)$/i,Iu=/fake|dummy|example|placeholder|unused|changeme|xxxx|redacted|your[_-]|<[^>]*>/i,_u=/^(.)\1+$/,Cu=/RegExp\(/,ks="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,}",$u=new RegExp(ks,"g"),Tu=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,Au=/(^|\/)(?:\.agents|\.claude)\/skills\//i,Gn=new Set(["HLIX_AGENT_RUN_ID","HLIX_API_KEY","HLIX_API_URL","HLIX_BASE_URL","HLIX_PROJECT_ID","HLIX_SESSION_TOKEN","HLIX_WORKSPACE_ID"]),ys="Your hlix credentials were left out of the project's secrets — the platform provides them.",ws=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]),Ru=100,uc=12;function Ou(z){let J=z.slice(0,uc).join(", "),V=z.length-uc;return z.length===1?`Observed environment reference has no local value: ${z[0]}`:`${z.length} observed environment references have no local value: ${J}${V>0?`, +${V} more`:""}`}var Nu=250;function Pt(z){return z.split(mu).join("/")}function bt(z){if(z>=1048576)return`${(z/1048576).toFixed(1)} MB`;if(z>=1024)return`${(z/1024).toFixed(1)} KB`;return`${z} bytes`}function mc(z,J=5){return[...z].sort((V,X)=>X.size-V.size||V.path.localeCompare(X.path)).slice(0,J).map((V)=>`${V.path} (${bt(V.size)})`).join(", ")}function Fu(z,J=5){let V=new Map;for(let X of z){let Y=X.indexOf("/"),Z=Y===-1?".":X.slice(0,Y);V.set(Z,(V.get(Z)??0)+1)}return[...V].sort((X,Y)=>Y[1]-X[1]||X[0].localeCompare(Y[0])).slice(0,J).map(([X,Y])=>`${X}/ (${Y} files)`).join(", ")}function nt(z,J,V=10485760){return gu("git",["-C",z,...J],{encoding:"utf8",timeout:bc,maxBuffer:V,stdio:["ignore","pipe","pipe"]})}function m(z,J,V={}){return new Promise((X)=>{fu("git",["-C",z,...J],{encoding:"utf8",timeout:bc,maxBuffer:V.maxBuffer??10485760,...V.signal?{signal:V.signal}:{}},(Y,Z)=>{let Q=Y?.code;X({status:Y===null?0:typeof Q==="number"?Q:1,stdout:typeof Z==="string"?Z:""})})})}async function Lu(z){let J=Jn("sha256");for await(let V of au(z))J.update(V);return J.digest("hex")}function vs(z){if(Array.isArray(z))return`[${z.map(vs).join(",")}]`;if(z&&typeof z==="object")return`{${Object.entries(z).sort(([J],[V])=>J.localeCompare(V)).map(([J,V])=>`${JSON.stringify(J)}:${vs(V)}`).join(",")}}`;return JSON.stringify(z)}function Sc(z){let J={};for(let[V,X]of String(z).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let Y=X.trim();if(!Y||Y.startsWith("#"))continue;let Q=(Y.startsWith("export ")?Y.slice(7).trimStart():Y).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!Q)throw Error(`Invalid dotenv assignment on line ${V+1}`);let ee=Q[2]??"";if(ee.startsWith('"')){if(!ee.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${V+1}`);ee=ee.slice(1,-1).replace(/\\n/g,`
|
|
301
|
-
`).replace(/\\r/g,"\r")}else if(ee.startsWith("'")){if(!ee.endsWith("'"))throw Error(`Unclosed dotenv quote on line ${V+1}`);ee=ee.slice(1,-1)}else ee=ee.replace(/\s+#.*$/,"").trimEnd();J[Q[1]]=ee}return J}function Hu(z,J){return z.split(/(?<=\n)/).filter((V)=>{let X=V.trim(),Z=(X.startsWith("export ")?X.slice(7).trimStart():X).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=/)?.[1];return Z===void 0||!J.has(Z)}).join("")}function Mu(z){let J=null;for(let V=0;V<z.length;V+=1){let X=z[V];if(X==="\\"&&J!=="single"){if(z[V+1]!=="$")return!0;V+=1;continue}if(X==="'"&&J!=="double"){J=J==="single"?null:"single";continue}if(X==='"'&&J!=="single"){J=J==="double"?null:"double";continue}if(J!=="single"&&(X==="$"||X==="`"))return!0;if(J===null&&(X==="<"||X===">")&&z[V+1]==="(")return!0}return J!==null}function Du(z){let J={},V=new Set,X=new Set;for(let Y of String(z).replace(/^\uFEFF/,"").split(/\r?\n/)){let Z=Y.trim();if(!Z||Z.startsWith("#"))continue;let ee=(Z.startsWith("export ")?Z.slice(7).trimStart():Z).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!ee)continue;let te=ee[1],re=ee[2]??"";if(V.add(te),Mu(re)){delete J[te],X.add(te);continue}try{let se=Sc(`${te}=${re}`)[te];if(se===void 0)throw Error("missing literal");J[te]=re.trimStart().startsWith("'")?se:se.replace(/\\\$/g,"$"),X.delete(te)}catch{delete J[te],X.add(te)}}return{values:J,keys:[...V].sort(),dynamicKeys:[...X].sort()}}async function Uu(z){let J=nt(z,["rev-parse","--show-toplevel"]);if(J.status!==0)return!1;try{return await wc(J.stdout.trim())===z}catch{return!1}}function Gu(z,J){if(!J)return new Set;let V=nt(z,["ls-files","-z"]);if(V.status!==0)throw Error("Could not enumerate tracked files.");return new Set(V.stdout.split("\x00").filter(Boolean).map(Pt))}function Bu(z,J){if(!J)return[];let V=nt(z,["config","--get-regexp","^remote\\..*\\.url$"]);if(V.status!==0)return[];let X=[];for(let Y of V.stdout.split(`
|
|
302
|
-
`)){let Z=Y.trim();if(!Z)continue;let Q=/^remote\.(.*)\.url (.+)$/.exec(Z);if(Q)X.push({name:Q[1],url:Q[2]})}return X}function Wu(z,J){if(!J)return{files:new Set,directories:[]};let V=nt(z,["ls-files","-z","--others","--ignored","--exclude-standard","--directory"]);if(V.status!==0)throw Error("Could not enumerate ignored files.");let X=new Set,Y=[];for(let Z of V.stdout.split("\x00").filter(Boolean)){let Q=Pt(Z);if(Q.endsWith("/"))Y.push(Q);else X.add(Q)}return{files:X,directories:Y}}async function fc(z,J){let V=[],X=[],Y=[],Z="";for(let ne of[".gitignore",".hlixignore"])try{let se=Kn(z,ne),ie=await yc(se);if(ne===".gitignore"&&ie.isSymbolicLink()){X.push(ne);continue}if(ie.isFile()||ie.isSymbolicLink())try{if(ie.isSymbolicLink()&&!(await vc(se)).isFile()){V.push(ne);continue}let pe=await Wn(se,"utf8");if(ne===".hlixignore")Z=pe;let fe=ne===".hlixignore"?Dn(pe):null;if(J&&fe?.managed)pe=pe.replace(fe.managed,J.join(`
|
|
303
|
-
`));Y.push(pe)}catch{V.push(ne)}}catch(se){if(se.code!=="ENOENT")V.push(ne)}let Q=Dn(Z)?.managed??"",ee=[".git/",".hlix/",...sn],te=Q?ee:kc,re=gs(Z);return{hardMatcher:Bn().add(re.length?ee:te),matcher:Bn().add([...te,...Y.flatMap((ne)=>ne.split(/\r?\n/))]),unignored:Bn().add(re),managedMatcher:Bn().add(J??Q),hasManaged:Boolean(Q),unreadable:V,symlinked:X}}function Gr(z){if(Tu.test(z))return"mcp";if(Au.test(z))return"skill";return null}function Br(z){if(ku.test(z)&&!bu.test(z))return"dotenv";if(Su.test(z))return"credential";return null}function zu(z,J){if(J)return[Pt(J)];let V=new Map([[".env",0],[".env.development",1],[".env.local",2],[".env.development.local",3]]),X=z.filter((Y)=>V.has(zt(Y).toLocaleLowerCase("en-US"))).sort((Y,Z)=>Y.slice(0,-zt(Y).length).localeCompare(Z.slice(0,-zt(Z).length))||V.get(zt(Y).toLocaleLowerCase("en-US"))-V.get(zt(Z).toLocaleLowerCase("en-US")));return X.length>0?X:z.length===1?[...z]:[]}function Ju(z,J){try{let V=JSON.parse(J);if(!V.mcpServers||typeof V.mcpServers!=="object")return[];return Object.entries(V.mcpServers).map(([X,Y])=>{let Z=Y&&typeof Y==="object"?Y:{},Q=Z.type==="http"||Z.type==="sse"||Z.type==="stdio"?Z.type:typeof Z.command==="string"?"stdio":typeof Z.url==="string"?"http":"unknown",ee=Z.env&&typeof Z.env==="object"?Z.env:{};return{sourcePath:z,name:X,transport:Q,...typeof Z.command==="string"?{command:Z.command}:{},...Array.isArray(Z.args)&&Z.args.every((te)=>typeof te==="string")?{args:Z.args}:{},...typeof Z.url==="string"?{url:Z.url}:{},envKeys:Object.keys(ee).sort(),enabled:!1}})}catch{return[]}}function Ku(z){let J=!1,V=!1;for(let X of z.split(/\r?\n/)){let Y=X.trim();if(!Y||Y.startsWith("#")||Y.startsWith(";")||Y.startsWith("["))continue;let Z=Y.indexOf("=");if(Z===-1)continue;let Q=Y.slice(0,Z).trim().toLowerCase(),ee=Y.slice(Z+1).trim().replace(/^["']|["']$/g,"");if(!ee||/^\$(?:\{[^}]*\}|[A-Za-z_][A-Za-z0-9_]*)$/.test(ee))continue;if(Q.endsWith("_authtoken")||Q.endsWith("_password"))return!0;if(Q.endsWith("password"))V=!0;else if(Q.endsWith("username"))J=!0}return J&&V}async function qu(z,J,V,X){if(xu.test(V))return!1;if(!ju.test(V))return!0;let Y=await m(z,["show",`${J}:${V}`],{...X?{signal:X}:{}});return Y.status===0&&Ku(Y.stdout)}function Vu(z,J,V){let X=z.lastIndexOf("/",J),Y=z.indexOf("/",V);return X!==-1&&Y!==-1&&!/\s/.test(z.slice(X,J)+z.slice(V,Y))}function Xu(z){if(Eu.test(z))return"test fixture";if(Pu.test(z))return"documentation or pattern definition";return null}function Yu(z,J){let V=null;for(let X of z.split(/\r?\n/))for(let Y of X.matchAll(J)){let Z=Y[0],Q=Y.index??0,ee=Cu.test(X)||Vu(X,Q,Q+Z.length)?"documentation or pattern definition":Iu.test(Z)||_u.test(Z)?"placeholder value":null;if(ee===null)return null;V??=ee}return V}async function Zu(z,J,V,X){let Y=Xu(V);if(Y!==null)return Y;let Z=await m(z,["show",`${J}:${V}`],{...X?{signal:X}:{}});return Z.status===0?Yu(Z.stdout,$u):null}async function gc(z,J,V){let X=[],Y="unknown";for(let Z of z.split(/\r?\n/)){if(Z.startsWith("@@"))Y=Z.slice(2);else if(Z.trim()){let Q=Pt(Z.trim());if(await V(Y,Q))X.push({commit:Y,path:Q,reason:J})}if(X.length>=100)break}return X}async function hc(z,J,V={}){if(!J)return{head:null,branch:null,refs:[],commitCount:0,complete:!0,findings:[],blockingFindings:[],waivedReasons:[]};let X=nt(z,["rev-parse","HEAD"]).stdout.trim()||null,Y=nt(z,["symbolic-ref","--short","-q","HEAD"]),Z=Y.status===0?Y.stdout.trim()||null:null,Q=Number.parseInt(nt(z,["rev-list","--count","--all"]).stdout.trim(),10)||0,ee=nt(z,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]),te=ee.stdout.split(`
|
|
304
|
-
`).filter(Boolean).map((me)=>{let[ve,Ee]=me.split("\x00");return{name:ve,oid:Ee}}).filter(({name:me,oid:ve})=>/^refs\/(?:heads|tags)\/.+/.test(me)&&/^[0-9a-f]{40,64}$/.test(ve)).sort((me,ve)=>me.name.localeCompare(ve.name)),re=V.signal,ne=re?{signal:re}:{};V.onProgress?.(`history: ${Q} commit${Q===1?"":"s"}…`);let se=["log","--all",`--max-count=${zn}`,"--pretty=format:@@%H","--name-only"],ie=await m(z,[...se,"--",".env",".env.*","*.pem","*.key",".npmrc","*.tfvars"],ne),pe=await m(z,["log","--all",`--max-count=${zn}`,"-G",ks,"--pretty=format:@@%H","--name-only"],ne);re?.throwIfAborted();let fe=new Map;for(let me of[...await gc(ie.stdout,"sensitive-path",(ve,Ee)=>qu(z,ve,Ee,re)),...await gc(pe.stdout,"secret-pattern",async()=>!0)])fe.set(`${me.commit}:${me.path}:${me.reason}`,me);let ce=[...fe.values()].slice(0,100),le=new Map;for(let me of ce){if(me.reason!=="secret-pattern")continue;let ve=await Zu(z,me.commit,me.path,re);if(ve!==null)le.set(me,ve)}return V.onProgress?.(`history: ${Q} commit${Q===1?"":"s"} scanned`),{head:X,branch:Z,refs:te,commitCount:Q,complete:Q<=zn&&te.length<=1000&&ee.status===0&&ie.status===0&&pe.status===0,findings:ce,blockingFindings:ce.filter((me)=>!le.has(me)),waivedReasons:[...le.values()]}}function Qu(z,J){let V=J?.XDG_CACHE_HOME??(J?.HOME?Kn(J.HOME,".cache"):null);if(!V)return null;return Kn(V,"hlix","history",`${Jn("sha256").update(z).digest("hex")}.json`)}async function em(z,J,V){let X=J?Qu(z,V.environment):null;if(!X)return hc(z,J,V);let Y=Jn("sha256").update([nt(z,["for-each-ref","--format=%(refname)%00%(objectname)"]).stdout,nt(z,["rev-parse","HEAD"]).stdout,nt(z,["symbolic-ref","--short","-q","HEAD"]).stdout,ks,String(zn)].join("\x00")).digest("hex");try{let Q=JSON.parse(await Wn(X,"utf8"));if(Q.key===Y&&Q.history)return V.onProgress?.(`history: ${Q.history.commitCount} commits, unchanged since the last scan`),Q.history}catch{}let Z=await hc(z,J,V);if(Z.complete)try{await cu(uu(X),{recursive:!0,mode:448}),await pu(X,JSON.stringify({key:Y,history:Z}),{mode:384})}catch{}return Z}async function ut(z,J={}){let V=await wc(Dr(z));if(!(await vc(V)).isDirectory())throw Error("Import target must be a directory.");let X=await Uu(V),Y=Bu(V,X),Z=Gu(V,X),Q=new Set(X?(await m(V,["ls-files","--stage","-z"])).stdout.split("\x00").filter((ue)=>ue.startsWith("160000 ")).map((ue)=>ue.slice(ue.indexOf("\t")+1)):[]),ee=Wu(V,X),te=[...new Set([...a(V)?.includedPaths??[],...J.include?[J.include]:[]].map((ue)=>ue.replace(/^\.\//,"").replace(/\/$/,"")))],re=await fc(V),ne=J.refreshIgnore||re.hasManaged?await sc(V,{write:J.refreshIgnore===!0,tracked:X?Z:new Set((await m(V,["ls-files","-z"])).stdout.split("\x00").filter(Boolean)),includes:te,gitIgnored:ee,signal:J.signal,maxFileBytes:J.maxFileBytes??pc,isRepository:async(ue)=>{let xe=await m(Kn(V,ue),["rev-parse","--show-toplevel"]);return xe.status===0&&Dr(xe.stdout.trim())===Dr(V,ue)},protectedPath:(ue,xe)=>Boolean(Br(ue)||!xe&&Gr(ue)),protectedContent:(ue,xe)=>Tn(ue,xe)}):void 0,{hardMatcher:se,matcher:ie,unignored:pe,managedMatcher:fe,unreadable:ce,symlinked:le}=ne?await fc(V,ne.rules??[]):re,me=ce.length?`Upload left unchanged: cannot read ${ce.join(", ")}; check the ignore file target and permissions before retrying.`:void 0,ve=[],Ee=[],we=[],Pe=[],ge=[],de=[],ae=[],he=[],_e=J.envFile?Pt(Mr(V,Dr(V,J.envFile))):void 0,Ae=_e!==void 0&&_e!==""&&_e!==".."&&!_e.startsWith("../");if(J.envFile&&!Ae)he.push(`Selected environment file must stay inside the project: ${J.envFile}`);let Re=new Map,Ue=new Map,Oe=new Map,De=new Map,Ne=ne?.warning?[ne.warning]:[],Jt=new Set,Kt=[],kt=[],qt=new Map,Qn=J.maxFiles??hu,_t=J.maxFileBytes??pc,Ce=J.maxTotalBytes??yu,Ie=J.historyMode==="sanitize",Le=0,Ct=0,er=async(ue,xe=!1)=>{let He=await lu(ue,{withFileTypes:!0}).catch((Je)=>{let qe=Pt(Mr(V,ue))||"repository";if(ae.push({path:qe,reason:`Cannot read folder (${Je.code??"unreadable"}); check read and search permissions`}),Ne.push(`Cannot read folder ${qe}; check its read and search permissions. Existing cloud files are preserved.`),ue===V)me="Upload left unchanged: cannot read the project folder; check its permissions.";return[]});He.sort((Je,qe)=>Je.name.localeCompare(qe.name));for(let Je of He){if(J.signal?.throwIfAborted(),Ct+=1,Ct%Nu===0)J.onProgress?.(`scanning … ${ve.length} files`);let qe=Kn(ue,Je.name),je=Pt(Mr(V,qe));if(Je.name===".git"){if(je!==".git"&&!xe)Jt.add(Pt(Mr(V,ue)));continue}if(je.length>1000||je.includes("\\")||je.includes("\x00")){Ne.push(`Skipped a path that cannot be represented safely: ${je.slice(0,350)}`);continue}try{let We=await yc(qe),wn=Je.isDirectory()?`${je}/`:je,gi=Z.has(je)&&!Q.has(je),vn=!(Hn(je,te)||pe.ignores(wn))&&!gi&&(ie.ignores(wn)||ee.files.has(je)||ee.directories.some((Fe)=>wn.startsWith(Fe))),hi=!Mn(je,te)&&se.ignores(wn);if(hi){if(je!==".hlix")ae.push({path:je,reason:"built-in ignore"});continue}if(vn&&fe.ignores(wn))ae.push({path:je,reason:"Hlix-managed ignore"});if(We.isSymbolicLink()){if(vn)continue;if(Ee.push({path:je,target:await du(qe)}),Gr(je)||Br(je))we.push(je);continue}if(Je.isDirectory()){if(hi)continue;if(Q.has(je)&&!vn)Jt.add(je);await er(qe,vn);continue}let Xt=Gr(je),Yt=Br(je);if(vn&&!Xt&&!Yt)continue;if(!Je.isFile()){ae.push({path:je,reason:"non-regular-file"});continue}if(We.size>_t&&!Xt&&!Yt){ae.push({path:je,reason:us(je)});continue}if(We.size>_t){he.push(`File ${je} is ${bt(We.size)}, over the ${bt(_t)} per-file limit. Exclude it with .hlixignore.`);continue}let bn=await Lu(qe);if(Xt){if(We.size>Ur){he.push(`Protected configuration ${je} is ${bt(We.size)}, over the ${bt(Ur)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let Fe=await Wn(qe);if(Le+=Fe.byteLength,kt.push({path:je,size:Fe.byteLength}),Le>Un)continue;if(ge.push({path:je,kind:Xt,size:We.size,sha256:bn}),Kt.push({path:je,kind:Xt,contentBase64:Fe.toString("base64")}),Xt==="mcp")de.push(...Ju(je,Fe.toString("utf8")));continue}if(Yt){if(We.size>Ur){he.push(`Protected file ${je} is ${bt(We.size)}, over the ${bt(Ur)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let Fe=await Wn(qe);if(Le+=Fe.byteLength,kt.push({path:je,size:Fe.byteLength}),Le>Un)continue;let Zt=[],kn=new Set;if(Yt==="dotenv")try{let rr=Sc(Fe),Qt={};for(let[xt,en]of Object.entries(rr)){if(Gn.has(xt)){kn.add(xt);continue}Qt[xt]=en}Re.set(je,Qt),Zt=Object.keys(Qt).sort()}catch{he.push(`Could not parse environment file: ${je}`)}else if(zt(je)===".envrc"){let rr=Du(Fe),Qt={},xt=new Set,en=[];for(let[Ve,yl]of Object.entries(rr.values)){if(Gn.has(Ve)){kn.add(Ve);continue}if(ws.has(Ve)){Ne.push(`Ignored ambient runtime assignment in ${je}: ${Ve}`);continue}xt.add(Ve),Qt[Ve]=yl}Ue.set(je,Qt);for(let Ve of rr.dynamicKeys){if(Gn.has(Ve)){kn.add(Ve);continue}if(ws.has(Ve)){Ne.push(`Ignored ambient runtime assignment in ${je}: ${Ve}`);continue}xt.add(Ve),en.push(Ve)}if(Oe.set(je,[...xt].sort()),De.set(je,en.sort()),Zt=[...xt].sort(),en.length>0)Ne.push(`Did not execute dynamic .envrc assignments; collect their resolved local values when available: ${en.join(", ")}`)}if(kn.size>0)Ne.push(ys),Fe=Buffer.from(Hu(Fe.toString("utf8"),kn),"utf8"),bn=Jn("sha256").update(Fe).digest("hex");Pe.push({path:je,kind:Yt,keys:Zt,size:Fe.byteLength,sha256:bn}),Kt.push({path:je,kind:Yt,contentBase64:Fe.toString("base64")});continue}if(We.size<=1048576){let Fe=await Wn(qe),Zt=Fe.toString("utf8");if(qt.set(je,Zt),Tn(je,Zt)){if(Le+=Fe.byteLength,kt.push({path:je,size:Fe.byteLength}),Le>Un)continue;Pe.push({path:je,kind:"detected-content",keys:[],size:We.size,sha256:bn}),Kt.push({path:je,kind:"detected-content",contentBase64:Fe.toString("base64")});continue}}ve.push({path:je,size:We.size,sha256:bn,tracked:gi,executable:(We.mode&73)!==0})}catch(We){if(J.signal?.throwIfAborted(),Br(je)||Gr(je))throw We;ae.push({path:je,reason:`Cannot read file (${We.code??"unreadable"})`})}}};await er(V);let $t=Qa([...ve,...Ee],Math.max(0,Qn-Pe.length-ge.length),Ce,te);if($t.length)ve=ve.filter((ue)=>!ps(ue.path,$t)),Ee=Ee.filter((ue)=>!ps(ue.path,$t)),ae.push(...$t.map((ue)=>({path:ue.replace(/\/$/,""),reason:us(ue)})));if(J.onProgress?.(`scanning … ${ve.length} files`),J.onProgress?.(`secrets: ${Pe.length+ge.length} files`),J.signal?.throwIfAborted(),we.length>0){let ue=we.slice(0,5).join(", "),xe=we.length-5;Ne.push(`Imported as symlinks, so no content was read or uploaded for them and the cloud recreates the link: ${ue}${xe>0?`, +${xe} more`:""}`)}for(let ue of le)Ne.push(`Ignore file ${ue} is a symlink, so its rules were not applied. Replace it with a regular file inside the project.`);if(me)Ne.push(me);if(Le>Un)he.push(`Protected project files total ${bt(Le)}, over the ${bt(Un)} limit. Largest: ${mc(kt)}. Move large assets out of skill and config folders, or add them to .hlixignore.`);if(Pe.length>2000)he.push(`Project has ${Pe.length} environment and credential files, over the 2000 limit. Largest: ${mc(Pe)}. Exclude the ones the cloud project does not need with .hlixignore.`);if(ge.length>5000)he.push(`Project has ${ge.length} agent, skill and MCP files, over the 5000 limit. Largest folders: ${Fu(ge.map((ue)=>ue.path))}. Exclude the ones the cloud project does not need with .hlixignore.`);ve.sort((ue,xe)=>ue.path.localeCompare(xe.path)),Ee.sort((ue,xe)=>ue.path.localeCompare(xe.path)),Pe.sort((ue,xe)=>ue.path.localeCompare(xe.path)),ge.sort((ue,xe)=>ue.path.localeCompare(xe.path)),de.sort((ue,xe)=>`${ue.sourcePath}:${ue.name}`.localeCompare(`${xe.sourcePath}:${xe.name}`));let Vt=zu([...Re.keys()].sort(),Ae?_e:void 0);if(J.envFile&&Ae&&!Re.has(Vt[0]))he.push(`Selected environment file was not found or is not a dotenv file: ${J.envFile}`);let St=new Map;for(let[ue,xe]of Re)for(let He of Object.keys(xe))St.set(He,[...St.get(He)??[],ue]);for(let[ue,xe]of Oe)for(let He of xe)St.set(He,[...St.get(He)??[],ue]);let tr=[...St].filter(([,ue])=>ue.length>1).map(([ue,xe])=>({key:ue,paths:xe.sort()})).sort((ue,xe)=>ue.key.localeCompare(xe.key)),ot={};for(let ue of Vt)Object.assign(ot,Re.get(ue)??{});let Ze=[...Ue.keys()].sort((ue,xe)=>{if(ue===".envrc")return 1;if(xe===".envrc")return-1;return ue.localeCompare(xe)}),yn=new Set;for(let ue of Ze){let xe=new Set(De.get(ue)??[]);for(let He of Oe.get(ue)??[]){if(xe.has(He)){delete ot[He],yn.add(He);continue}let Je=Ue.get(ue)?.[He];if(Je!==void 0)ot[He]=Je;yn.delete(He)}}for(let ue of Jt)Ne.push(`${ue} has its own Git repository — uploaded as files, its history not included`);let ml=J.historyMode==="abort_on_findings"?"abort_on_findings":"preserve";if(Ie)Ne.push("Git history omitted; uploading a snapshot of the current files.");let Qe=await em(V,X,J);if(!Qe.complete)Ne.push(`Git history scan exceeded ${zn} commits or failed; history is preserved, but the findings may be incomplete.`);if(X&&!Qe.head)Ie=!0,Ne.push("Git has no readable HEAD; uploading the current files as a snapshot.");let di=Qe.waivedReasons;for(let ue of[...new Set(di)].sort()){let xe=di.filter((Je)=>Je===ue).length,He=xe===1;Ne.push(`${xe} Git history finding${He?"":"s"} did not block this import — ${ue}, not ${He?"a real credential":"real credentials"}; --history preserve is not needed for ${He?"it":"them"}.`)}if(Qe.blockingFindings.length>0){let ue=Qe.blockingFindings.length;Ne.unshift([`${wu} (${ue} finding${ue===1?"":"s"}${ue>5?", first 5 shown":""}); ${Ie?"history is omitted":"history is preserved"}:`,...Qe.blockingFindings.slice(0,5).map((xe)=>` ${xe.commit.slice(0,7)} ${xe.path} — ${xe.reason}`)," To exclude old commits, use --history sanitize; local Git history stays intact."].join(`
|
|
305
|
-
`))}let pi=new Set(ve.map((ue)=>ue.path)),fl=await lc(V,pi,qt),{observedSecretKeys:gl,...st}=fl;st.warnings.unshift(...Ne);let nr=new Set(st.requiredSecretKeys);for(let ue of yn)nr.add(ue);for(let ue of de)for(let xe of ue.envKeys)nr.add(xe);for(let ue of Gn)if(nr.delete(ue))st.warnings.push(ys);st.requiredSecretKeys=[...nr].sort();for(let ue of st.requiredSecretKeys){if(ot[ue]!==void 0)continue;let xe=J.environment?.[ue];if(xe===void 0){he.push(`${bs}${ue}`);continue}ot[ue]=xe}let Yr=[];for(let ue of gl){if(Gn.has(ue)){st.warnings.push(ys);continue}if(ws.has(ue))continue;if(ot[ue]!==void 0)continue;let xe=J.environment?.[ue];if(xe===void 0){Yr.push(ue);continue}ot[ue]=xe}if(Yr.length>0)st.warnings.push(Ou(Yr.sort()));st.warnings=[...new Set(st.warnings.flatMap((ue)=>ue.split(`
|
|
306
|
-
`)))].map((ue)=>ue.slice(0,500)).slice(0,Ru);let ui=Za(new Map([...pi].map((ue)=>[ue,qt.get(ue)??null]))),mi={schemaVersion:dc,rootName:J.rootName??zt(V),stack:ui.language,git:{detected:X&&!Ie,head:Ie?null:Qe.head,branch:Ie?null:Qe.branch,refs:Ie?[]:Qe.refs,commitCount:Ie?0:Qe.commitCount,historyScanComplete:Qe.complete,historyMode:ml},files:ve,symlinks:Ee,secretFiles:Pe,activeEnvFiles:Vt,secretKeys:Object.keys(ot).sort(),envCollisions:tr,quarantinedResources:ge,mcpServers:de,historicalSecretFindings:Qe.blockingFindings,skipped:ec(ae),environment:st,totals:{files:ve.length,bytes:ve.reduce((ue,xe)=>ue+xe.size,0)}},fi=vs(mi),hl=Jn("sha256").update(fi).digest("hex");return{root:V,includedPaths:te,ignoreReport:J.refreshIgnore?ne?.report??ne?.warning:void 0,uploadWarning:me,stackFacts:ui,manifest:mi,...ae.length>5000?{skippedEntries:ae}:{},manifestJson:fi,manifestSha256:hl,secretValues:ot,protectedFiles:Kt.sort((ue,xe)=>ue.path.localeCompare(xe.path)),blocking:[...new Set(he)].map((ue)=>`${ue}
|
|
307
|
-
${vu}`),blockingHistoryFindings:[],gitRemotes:Y}}var Ss={name:"init",summary:"Configure a local folder for Hlix",usage:["Usage: hlix init [folder] [--project <id>] [--json]","","Creates hlix.yml, or fills its hlix: block when the file already exists.","hlix.api is written only when the server is not https://server.hlix.ai.","A folder that only has .hlix/config.json is copied into hlix.yml.","Also creates .hlix/.gitignore and .hlixignore.","hlix.yml is the committed project file. Secret values do not belong in it.","Project configuration is safe to commit; local revision state is ignored.",""," --project <id> Bind the folder to an existing cloud project"," Then `hlix pull`, or `hlix push` if it has no files yet"].join(`
|
|
308
|
-
`),supportsJson:!0,options:["project"],args:{min:0,max:1},async run(z){if(z.args.length>1)throw Error("init accepts at most one folder.");let J=await tm(nm(z.cwd,z.args[0]??"."));await g(z,{cwd:J,flags:z.flags});let V=r({env:z.env,flags:z.flags,cwd:J});if(V.conflict)throw new e("workspace_mismatch",V.conflict);if(!V.workspaceId)throw Error("No workspace selected. Run `hlix login --workspace <id>` first.");let X=z.requireClient(J);await X.projects.list();let Y=dt(J);if(Y.error)throw new e("invalid_project_file",Y.error);let Z=an(Y.base),Q=Z?null:_r(J),ee=Z??Q;if(Q&&(Q.workspaceId!==V.workspaceId||!rm(Q.apiUrl,V.baseUrl)))throw new e("workspace_mismatch",`This folder is bound to workspace ${Q.workspaceId} at ${Q.apiUrl}; refusing to bind it to ${V.workspaceId} at ${V.baseUrl}.`);let te=typeof z.flags.project==="string"?z.flags.project:void 0;if(te&&ee?.projectId&&ee.projectId!==te)throw new e("workspace_mismatch",`This folder is bound to project ${ee.projectId}; refusing to rebind it to ${te}.`);if(te)await X.projects.get(te);let re=te??ee?.projectId,ne={schemaVersion:1,workspaceId:V.workspaceId,apiUrl:V.baseUrl,...re?{projectId:re}:{}},se={workspace:ne.workspaceId,api:ne.apiUrl,...ne.projectId?{project:ne.projectId}:{}};Cr(J),await gr(J);let ie=await ut(J,{environment:z.env,refreshIgnore:!0});if(!hr(J,An(ie.manifest.environment,se)).written)wr(J,se);if(Q)ra(J,Q);let fe={root:J,config:ne,ignoreReport:ie.ignoreReport,scan:{files:ie.manifest.totals.files,bytes:ie.manifest.totals.bytes,secretFiles:ie.manifest.secretFiles.map((ce)=>ce.path),quarantinedResources:ie.manifest.quarantinedResources.map((ce)=>ce.path),blocking:ie.blocking}};if(z.json)z.stdout(ke(Se(Ss.name,fe)));else{if(ie.ignoreReport)z.stdout(`${ie.ignoreReport}
|
|
309
|
-
`);if(z.stdout(`Initialized ${J}
|
|
310
|
-
Project: ${ne.projectId??"not imported yet"}
|
|
311
|
-
Workspace: ${ne.workspaceId}
|
|
312
|
-
`),ie.blocking.length)z.stdout(`
|
|
313
|
-
Review before import:
|
|
314
|
-
${ie.blocking.map((ce)=>`- ${ce}`).join(`
|
|
315
|
-
`)}
|
|
316
|
-
`)}return 0}};function rm(z,J){return z.replace(/\/+$/,"")===J.replace(/\/+$/,"")}import{basename as Nm,resolve as Fm}from"node:path";import{realpath as Lm}from"node:fs/promises";import{mkdtemp as Pm,rm as Jr,readFile as Im,writeFile as _m,chmod as Cm,symlink as $m,lstat as Tm}from"node:fs/promises";import{tmpdir as Am}from"node:os";import{join as Es}from"node:path";import{createHash as om}from"node:crypto";import{createReadStream as sm}from"node:fs";import{chmod as xc,copyFile as im,lstat as am,mkdir as xs,mkdtemp as cm,readdir as lm,readlink as dm,rm as js,symlink as pm}from"node:fs/promises";import{tmpdir as um}from"node:os";import{dirname as jc,join as It}from"node:path";import{spawnSync as Wr}from"node:child_process";var zr=300000;function rt(z,J){let V=Wr("git",["-c","core.hooksPath=/dev/null","-C",z,...J],{encoding:"utf8",timeout:zr,maxBuffer:20971520,stdio:["ignore","pipe","pipe"]});if(V.status!==0){let X=V.stderr.trim().split(`
|
|
317
|
-
`).at(-1)??"git command failed";throw Error(X)}return V.stdout.trim()}async function mm(z){let J=om("sha256");for await(let V of sm(z))J.update(V);return J.digest("hex")}async function fm(z){for(let J of await lm(z)){if(J===".git")continue;await js(It(z,J),{recursive:!0,force:!0})}}async function Ec(z){if(z.manifest.git.detected&&(z.manifest.historicalSecretFindings.length||!z.manifest.git.historyScanComplete))throw Error("Git history has secrets or could not be fully scanned. Use --history sanitize to import current files.");if(z.uploadWarning)throw Error(z.uploadWarning);if(z.blocking.length>0)throw Error(`Project scan has blocking findings:
|
|
318
|
-
- ${z.blocking.join(`
|
|
319
|
-
- `)}`);let J=await cm(It(um(),"hlix-snapshot-"));await xc(J,448);let V=It(J,"repo"),X=It(J,"source.git");try{if(z.manifest.git.detected){let ee=Wr("git",["clone","--mirror","--no-hardlinks",z.root,X],{encoding:"utf8",timeout:zr,stdio:["ignore","pipe","pipe"]});if(ee.status!==0)throw Error(ee.stderr.trim()||"Could not mirror repository.");let te=new Map(rt(X,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]).split(`
|
|
320
|
-
`).filter(Boolean).map((ne)=>ne.split("\x00",2)));for(let ne of z.manifest.git.refs)if(te.get(ne.name)!==ne.oid)throw Error(`Git ref changed after scan: ${ne.name}`);let re=Wr("git",["clone","--no-hardlinks",X,V],{encoding:"utf8",timeout:zr,stdio:["ignore","pipe","pipe"]});if(re.status!==0)throw Error(re.stderr.trim()||"Could not create snapshot clone.");if(!z.manifest.git.head)throw Error("Git repository has no HEAD commit.");rt(V,["checkout","-B","main",z.manifest.git.head])}else await xs(V,{recursive:!0,mode:448}),rt(V,["init","-b","main"]);await fm(V);for(let ee of z.manifest.files){let te=It(z.root,...ee.path.split("/")),re=await am(te);if(!re.isFile()||re.isSymbolicLink())throw Error(`Source changed after scan: ${ee.path}`);if(re.size!==ee.size||await mm(te)!==ee.sha256)throw Error(`Source changed after scan: ${ee.path}`);let ne=It(V,...ee.path.split("/"));await xs(jc(ne),{recursive:!0,mode:493}),await im(te,ne),await xc(ne,ee.executable?493:420)}for(let ee of z.manifest.symlinks){let te=It(z.root,...ee.path.split("/"));if(await dm(te).catch(()=>null)!==ee.target)throw Error(`Source changed after scan: ${ee.path}`);let re=It(V,...ee.path.split("/"));await xs(jc(re),{recursive:!0,mode:493}),await pm(ee.target,re)}rt(V,["config","user.name","Hlix Import"]),rt(V,["config","user.email","import@hlix.ai"]),rt(V,["read-tree","--empty"]),rt(V,["add","--force","-A"]),rt(V,["commit","--allow-empty","-m","chore(hlix): import snapshot"]);let Y=rt(V,["rev-parse","HEAD"]),Z=new Set(z.manifest.git.refs.map((ee)=>ee.name));for(let ee of rt(V,["for-each-ref","--format=%(refname)","refs/heads","refs/tags"]).split(`
|
|
321
|
-
`).filter(Boolean))if(ee!=="refs/heads/main"&&!Z.has(ee))rt(V,["update-ref","-d",ee]);let Q=z.manifest.git.refs.filter((ee)=>ee.name!=="refs/heads/main");if(Q.length>0){let ee=Wr("git",["-C",V,"update-ref","--stdin"],{encoding:"utf8",timeout:zr,input:Q.map((te)=>`update ${te.name} ${te.oid}`).join(`
|
|
322
|
-
`)+`
|
|
323
|
-
`,stdio:["pipe","pipe","pipe"]});if(ee.status!==0)throw Error(ee.stderr.trim()||"Could not recreate the approved Git refs.")}return{directory:V,commitSha:Y,dispose:()=>js(J,{recursive:!0,force:!0})}}catch(Y){throw await js(J,{recursive:!0,force:!0}),Y}}import{lstat as Ic,mkdir as gm,realpath as hm}from"node:fs/promises";import{dirname as ym,join as wm,relative as vm,resolve as bm,sep as Pc}from"node:path";function _c(z,J){let V=z;if(typeof V==="string")try{V=JSON.parse(V)}catch{return[]}if(!V||typeof V!=="object")return[];let X=V[J];if(!Array.isArray(X))return[];return X.filter((Y)=>!!Y&&typeof Y==="object")}function Cc(z){return _c(z,"files").flatMap((J)=>typeof J.path==="string"&&typeof J.sha256==="string"?[{path:J.path,sha256:J.sha256}]:[])}function $c(z){return _c(z,"symlinks").flatMap((J)=>typeof J.path==="string"&&typeof J.target==="string"?[{path:J.path,target:J.target}]:[])}async function qn(z,J,V){let X=await hm(z),Y=bm(X,...J.split("/"));if(Y!==X&&!Y.startsWith(X+Pc))throw Error(`Protected path escapes the project: ${J}`);let Z=vm(X,ym(Y)),Q=X;for(let ee of Z.split(Pc).filter(Boolean)){Q=wm(Q,ee);try{let te=await Ic(Q);if(te.isSymbolicLink()&&V){V.push(Q);break}if(!te.isDirectory()||te.isSymbolicLink())throw Error(`Protected path crosses a non-directory: ${J}`)}catch(te){if(te.code!=="ENOENT")throw te;if(!V)await gm(Q,{mode:448})}}return Y}async function Tc(z,J,V){let X=V.length,Y=await qn(z,J,V);if(V.length>X)return;try{let Z=await Ic(Y);if(Z.isSymbolicLink()){V.push(Y);return}if(!Z.isFile())throw Error(`Refusing to replace non-regular project file: ${J}`)}catch(Z){if(Z.code!=="ENOENT")throw Z}}import{spawnSync as km}from"node:child_process";import{mkdtemp as Sm,writeFile as xm,rm as jm}from"node:fs/promises";import{tmpdir as Em}from"node:os";import{join as Ac}from"node:path";function Rc(z,J,V){let X=km("git",["-c","core.hooksPath=/dev/null","-C",z,...J],{encoding:"utf8",timeout:120000,maxBuffer:41943040,env:{PATH:process.env.PATH,GIT_CONFIG_GLOBAL:V??"/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(X.status!==0)throw Error("HLIX Repos Git operation failed. The remote may have changed; refresh and retry.");return X.stdout.trim()}async function Oc(z,J){let V=new URL(z.cloneUrl);if(V.href!==z.cloneUrl||/[\r\n"\\]/.test(z.cloneUrl)||V.protocol!=="https:"||V.username||V.password||V.search||V.hash||V.port||!(V.hostname==="github.com"||/^[a-f0-9]{32}\.artifacts\.cloudflare\.net$/.test(V.hostname)))throw Error("Invalid HLIX Repos remote");if(/[\r\n]/.test(z.token))throw Error("Invalid repository credential");let X=await Sm(Ac(Em(),"hlix-git-auth-")),Y=Ac(X,"config"),Z=z.token.replace(/\?expires=\d+$/,""),Q=Buffer.from(`x-access-token:${Z}`).toString("base64");try{return await xm(Y,`[http "${z.cloneUrl}"]
|
|
324
|
-
extraHeader = Authorization: Basic ${Q}
|
|
325
|
-
followRedirects = false
|
|
326
|
-
`,{mode:384}),await J(Y)}finally{await jm(X,{recursive:!0,force:!0})}}function un(z){return new Map([...Cc(z).map((J)=>[J.path,`blob:${J.sha256}`]),...$c(z).map((J)=>[J.path,`link:${J.target}`])])}var Nc={git:Rc,access:Oc};async function mn(z){let J=t(z);if(!J?.config.projectId)throw new e("not_initialized","Run hlix import or hlix init to bind this folder to a project.");return{...J,state:a(J.root)}}async function Fc(z,J){let V=await ut(z,{environment:J,historyMode:"sanitize",maxFiles:50000,maxFileBytes:33554432,maxTotalBytes:1073741824});if(V.manifest.files=V.manifest.files.filter((X)=>X.path!==".hlixignore"),V.blocking.length)throw new e("scan_blocked",V.blocking.join(`
|
|
327
|
-
`));return V}function Rm(z,J){let V=Object.fromEntries(un(z.manifest));return!J?.files?z.manifest.files.length+z.manifest.symlinks.length>0:JSON.stringify(Object.entries(V).sort())!==JSON.stringify(Object.entries(J.files).sort())}async function Ps(z,J,V){let X=await z.projects.get(J),Y=V?X.repos.find((Z)=>Z.id===V):X.repos.find((Z)=>Z.isPrimary)??(X.repos.length===1?X.repos[0]:void 0);if(!Y)throw new e("conflict","Select a primary repository for this project before syncing.");return Y}async function Is(z,J,V,X,Y=!1,Z=Nc){let{config:Q,state:ee}=await mn(z),te=await Ps(J,Q.projectId,ee?.repoId),re=await J.repos.head(Q.projectId,te.id);if((X??ee?.commitSha)&&re.commitSha!==(X??ee?.commitSha))throw new e("conflict","HLIX Repos changed. Pull or sync before pushing.");let ne=await Ec(V);try{let se=await J.repos.access(Q.projectId,te.id,"write"),ie=await Z.access(se,async(pe)=>{Z.git(ne.directory,["fetch","--no-tags",se.cloneUrl,`refs/heads/${te.defaultBranch}`],pe);let fe=Z.git(ne.directory,["rev-parse","FETCH_HEAD"]);if(fe!==re.commitSha)throw new e("conflict","HLIX Repos changed during upload. Retry sync.");let ce=Z.git(ne.directory,["rev-parse",`${ne.commitSha}^{tree}`]),le=Z.git(ne.directory,["commit-tree",ce,"-p",fe,...Y&&V.manifest.git.detected?["-p",ne.commitSha]:[],"-m","Update HLIX Repos files"]);return Z.git(ne.directory,["push",`--force-with-lease=refs/heads/${te.defaultBranch}:${fe}`,se.cloneUrl,`${le}:refs/heads/${te.defaultBranch}`],pe),le});return Bo(z,{schemaVersion:1,repoId:te.id,commitSha:ie,files:Object.fromEntries(un(V.manifest)),snapshotOnly:!0,rootName:V.manifest.rootName}),{action:"push",commitSha:ie}}finally{await ne.dispose()}}async function Om(z,J,V,X,Y,Z){let{config:Q}=await mn(z),ee=await Ps(J,Q.projectId,V),te=await Pm(Es(Am(),"hlix-pull-"));try{let re=await J.repos.access(Q.projectId,V,"read");await Z.access(re,async(le)=>{Z.git(te,["init"]),Z.git(te,["fetch","--no-tags",re.cloneUrl,`refs/heads/${ee.defaultBranch}`],le),Z.git(te,["checkout","--detach",X])});let ne=await Fc(te),se=[],ie=[...ne.manifest.files,...ne.manifest.symlinks],pe=[...Y.manifest.files,...Y.manifest.symlinks].filter((le)=>!ie.some((me)=>me.path===le.path)),fe=new Set([...Y.manifest.files,...Y.manifest.symlinks].map((le)=>le.path));for(let le of ie){let me=le.path.split("/");for(let ve=1;ve<=me.length;ve++){let Ee=me.slice(0,ve).join("/"),we=await Tm(Es(z,Ee)).catch((Pe)=>{if(Pe.code!=="ENOENT")throw Pe;return null});if(we&&!we.isDirectory()&&!fe.has(Ee))throw new e("conflict",`Incoming repository file would replace an excluded local file: ${Ee}`)}}for(let le of[...ie,...pe])await Tc(z,le.path,se);let ce=await Promise.all(ne.manifest.files.map(async(le)=>({...le,bytes:await Im(Es(te,le.path))})));for(let le of[...new Set(se)].sort((me,ve)=>me.length-ve.length))await Jr(le,{force:!0});for(let le of pe)await Jr(await qn(z,le.path),{force:!0});for(let le of ce){let me=await qn(z,le.path);await _m(me,le.bytes,{mode:le.executable?493:420}),await Cm(me,le.executable?493:420)}for(let le of ne.manifest.symlinks){let me=await qn(z,le.path);await Jr(me,{force:!0}),await $m(le.target,me)}return Bo(z,{schemaVersion:1,repoId:V,commitSha:X,files:Object.fromEntries(un(ne.manifest)),snapshotOnly:!0,rootName:Y.manifest.rootName}),{action:"pull",commitSha:X}}finally{await Jr(te,{recursive:!0,force:!0})}}async function _s(z,J,V,X="sync",Y=!1,Z=Nc){let{config:Q,state:ee}=await mn(z),te=await Ps(J,Q.projectId,ee?.repoId),[re,ne]=await Promise.all([Fc(z,V),J.repos.head(Q.projectId,te.id)]),se=Rm(re,ee),ie=ee?.commitSha!==ne.commitSha,pe=!ee&&se&&!ne.isEmpty?"conflict":X==="push"?ie&&ee?"conflict":se?"push":"none":X==="pull"?se?"conflict":ie?"pull":"none":se&&ie&&ee?"conflict":se?"push":ie?"pull":"none";if(Y)return{action:pe,localChanged:se,cloudChanged:ie,commitSha:ne.commitSha};if(pe==="conflict")throw new e("conflict","This folder and HLIX Repos have both changed. Resolve the differences before syncing; no files were replaced.");if(pe==="push")return Is(z,J,re,ne.commitSha,!1,Z);if(pe==="pull")return Om(z,J,te.id,ne.commitSha,re,Z);return{action:"none",commitSha:ne.commitSha}}function Cs(z){return{name:z,summary:`${z} files with HLIX Repos`,usage:`Usage: hlix ${z} [--dry-run] [--json]`,supportsJson:!0,signIn:!0,options:["dry-run"],async run(J){let{root:V}=await mn(J.cwd),X=await _s(V,J.requireClient(),J.env,z,J.flags["dry-run"]===!0);return J.stdout(J.json?ke(Se(`hlix ${z}`,X)):`HLIX Repos: ${X.action} (${X.commitSha})
|
|
328
|
-
`),X.action==="conflict"?1:0}}}var Lc=Cs("push"),Hc=Cs("pull"),Mc=Cs("sync");var Hm=(z)=>`${(z/1024/1024).toFixed(1)} MB`,$s=(z,J=3)=>z.slice(0,J).join(", ")+(z.length>J?`, +${z.length-J} more`:"");function Mm(z,J,V,X,Y){let{manifest:Z}=z,Q=new Map;for(let re of Z.files){let ne=re.path.includes("/")?`${re.path.split("/")[0]}/`:"(root files)";Q.set(ne,(Q.get(ne)??0)+1)}let ee=[...Q].sort((re,ne)=>ne[1]-re[1]).map(([re,ne])=>`${re} ${ne}`);return["Import plan",...[["Project",`${J} (${V})`],["Config",Y],["Files",`${Z.totals.files} files, ${Hm(Z.totals.bytes)}`],["Folders",$s(ee,5)||"none"],["Secrets",z.protectedFiles.length?`${z.protectedFiles.length} encrypted: ${$s(z.protectedFiles.map((re)=>re.path))}`:"none found"],["History",!Z.git.detected?"no git history":X==="preserve"?`kept: ${Z.git.commitCount} commits${Z.git.branch?` on ${Z.git.branch}`:""}`:"not sent (sanitize)"],["Skipped",Z.skipped.length?$s(Z.skipped.map((re)=>re.path)):"nothing"]].map(([re,ne])=>` ${re.padEnd(9)}${ne}`),"","To change it: --name <name>, --include <path>, or list paths in .hlixignore."].join(`
|
|
329
|
-
`)}var Dc={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(z){let J=await Lm(Fm(z.cwd,z.args[0]??"."));await g(z,{cwd:J,flags:z.flags,verify:!0});let V=r({env:z.env,flags:z.flags,cwd:J});if(V.conflict)throw new e("conflict",V.conflict);if(!V.workspaceId||!V.credential)throw new e("workspace_required","Run hlix login to select a workspace.");let X=dt(J);if(X.error)throw new e("invalid_project_file",X.error);let Y=an(X.base),Z=Y?void 0:_r(J)?.projectId;if(Y?.projectId||Z)throw new e("conflict","This folder is already bound to a project. Use hlix push or sync.");let Q=z.flags.history??"preserve";if(Q!=="preserve"&&Q!=="sanitize")throw new e("invalid_usage","--history accepts preserve or sanitize.");let ee=await ut(J,{environment:z.env,historyMode:Q,envFile:typeof z.flags["env-file"]==="string"?z.flags["env-file"]:void 0,maxFiles:50000,maxFileBytes:33554432,maxTotalBytes:1073741824,include:typeof z.flags.include==="string"?z.flags.include:void 0});if(ee.blocking.length)throw new e("scan_blocked",ee.blocking.join(`
|
|
330
|
-
`));if(ee.manifest.git.detected&&(ee.manifest.historicalSecretFindings.length||!ee.manifest.git.historyScanComplete))throw new e("scan_blocked","History contains potential secrets or was not completely scanned. Review it or use --history sanitize.");let te={files:ee.manifest.totals.files,bytes:ee.manifest.totals.bytes,protectedFiles:ee.protectedFiles.length,history:Q},re=X.base?jt(X.base):null,ne=typeof z.flags.name==="string"?z.flags.name:re?.name??Nm(J),se=typeof z.flags.stack==="string"?z.flags.stack:re?.stack??ee.manifest.stack,ie=X.base??fr(An(ee.manifest.environment,{workspace:V.workspaceId,api:V.baseUrl})),pe=Um(ie,{name:ne,stack:se}),fe=Mm(ee,ne,se,Q,oa(X));if(z.flags["dry-run"]===!0)return z.stdout(z.json?ke(Se("hlix import",te)):`${fe}
|
|
331
|
-
`),0;if(z.flags.yes!==!0){if(!z.confirm)throw new e("invalid_usage","Import requires approval. Review --dry-run, then use --yes.");if(!await z.confirm(fe))return z.stdout(`Import cancelled. Nothing was sent.
|
|
332
|
-
`),0}let ce=z.requireClient(J),le=await ce.projects.create(pe.create);await gr(J),vr(ee,".gitignore"),Cr(J);let me={workspace:V.workspaceId,api:V.baseUrl,project:le.id};if(!X.base){if(hr(J,An(ee.manifest.environment,me,{name:ne,stack:se})).written)vr(ee,"hlix.yml")}let ve=wr(J,me);if(ve.changed)vr(ee,ve.name);if(Object.keys(pe.patch).length>0)await ce.projects.update(le.id,pe.patch);for(let we=0;we<ee.protectedFiles.length;we+=64)await ce.secrets.importFiles(le.id,ee.protectedFiles.slice(we,we+64).map((Pe)=>({path:Pe.path,contentBase64:Pe.contentBase64})));let Ee=await Is(J,ce,ee,void 0,Q==="preserve");return z.stdout(z.json?ke(Se("hlix import",{...te,projectId:le.id,commitSha:Ee.commitSha})):`Imported into HLIX Repos: ${le.name} (${Ee.commitSha})
|
|
333
|
-
`),0}},Dm=["claude-code","codex","goose","opencode","pi","qwen-code"];function Um(z,J){let V=jt(z),X=Gm(V.runtime);return{create:{name:J.name,stack:J.stack,repos:[],...V.brief?{brief:V.brief}:{},...X?{runtime:X}:{}},patch:{...V.verifyCommand?{verifyCommand:V.verifyCommand}:{},...V.previewCommand?{previewCommand:V.previewCommand}:{},...V.previewPort!==void 0?{previewPort:V.previewPort}:{},...V.sandboxSize?{sandboxSize:V.sandboxSize}:{},...V.branchPrefix?{branchPrefix:V.branchPrefix}:{},...V.intake?{intake:V.intake}:{}}}}function Gm(z){let J=z.agents?.filter((X)=>Dm.includes(X)),V={};if(J?.length)V.agents=J;if(z.toolchain)V.toolchain=z.toolchain;if(z.aptPackages)V.aptPackages=z.aptPackages;if(z.setup)V.setup=z.setup;if(z.services)V.services=z.services;if(z.envOverrides)V.envOverrides=z.envOverrides;if(z.verifyCommand)V.verifyCommand=z.verifyCommand;if(z.preview)V.preview=z.preview;if(z.notes)V.notes=z.notes;return Object.keys(V).length?V:void 0}import{spawnSync as hf}from"node:child_process";import{existsSync as yf,mkdirSync as wf,writeFileSync as vf}from"node:fs";import{dirname as bf}from"node:path";import{createHash as Bm}from"node:crypto";import{mkdirSync as Wm,readdirSync as Jc,readFileSync as zm,rmSync as Jm,statSync as Kc,writeFileSync as Km}from"node:fs";import{homedir as qm,tmpdir as Vm}from"node:os";import{basename as qc,isAbsolute as Xm,join as $e,relative as Ym}from"node:path";var c=(z=process.env)=>z.HOME??z.USERPROFILE??qm();function Ye(z){try{if(!Kc(z).isFile())return null;return zm(z,"utf8")}catch{return null}}function Zm(z){try{return Kc(z).isDirectory()}catch{return!1}}function fn(z,J){try{return Jc(z,{withFileTypes:!0}).filter((V)=>V.isFile()&&V.name.endsWith(J)).map((V)=>$e(z,V.name)).sort()}catch{return[]}}function Qm(z){try{return Jc(z,{withFileTypes:!0}).filter((J)=>J.isDirectory()||J.isSymbolicLink()).map((J)=>$e(z,J.name)).sort()}catch{return[]}}function As(z){let J=z.replace(/^\uFEFF/,""),V=J.indexOf(`
|
|
334
|
-
`);if(!J.startsWith("---")||V===-1)return{fields:{},body:J.trim()};let X=J.indexOf(`
|
|
335
|
-
---`,V);if(X===-1)return{fields:{},body:J.trim()};let Y={};for(let Q of J.slice(V+1,X).split(`
|
|
336
|
-
`)){let ee=/^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(Q);if(!ee)continue;Y[ee[1]]=ee[2].trim().replace(/^["']|["']$/g,"")}let Z=J.indexOf(`
|
|
337
|
-
`,X+1);return{fields:Y,body:Z===-1?"":J.slice(Z+1).trim()}}function ef(z){let J=z.trimStart(),V=/^"((?:[^"\\]|\\.)*)"/.exec(J)??/^'([^']*)'/.exec(J);if(V)return V[1].replace(/\\"/g,'"').replace(/\\n/g,`
|
|
338
|
-
`);if(J.startsWith("["))return[...J.matchAll(/"((?:[^"\\]|\\.)*)"|'([^']*)'/g)].map((Y)=>Y[1]??Y[2]??"");if(J.startsWith("{")){let Y={};for(let Z of J.matchAll(/([A-Za-z0-9_.-]+)\s*=\s*"((?:[^"\\]|\\.)*)"/g))Y[Z[1]]=Z[2].replace(/\\"/g,'"');return Y}let X=/^[^\s#]+/.exec(J)?.[0];if(X===void 0)return;if(X==="true"||X==="false")return X==="true";if(/^-?\d+(\.\d+)?$/.test(X))return Number(X);return X}function Vc(z){let J={"":{}},V="",X=z.split(`
|
|
339
|
-
`);for(let Y=0;Y<X.length;Y+=1){let Q=X[Y].trim();if(!Q||Q.startsWith("#"))continue;let ee=/^\[\[?([^\]]+)\]\]?$/.exec(Q);if(ee){V=ee[1].trim(),J[V]??={};continue}let te=/^([A-Za-z0-9_.-]+|"[^"]+")\s*=\s*(.*)$/.exec(Q);if(!te)continue;let re=te[1].replace(/^"|"$/g,""),ne=te[2];if(ne.startsWith('"""')){let ie=[],pe=ne.slice(3);if(pe.includes('"""'))ie.push(pe.slice(0,pe.indexOf('"""')));else{if(pe)ie.push(pe);while(Y+1<X.length){Y+=1;let fe=X[Y],ce=fe.indexOf('"""');if(ce===-1){ie.push(fe);continue}ie.push(fe.slice(0,ce));break}}J[V][re]=ie.join(`
|
|
340
|
-
`).replace(/^\n/,"");continue}let se=ef(ne);if(se!==void 0)J[V][re]=se}return J}function Ts(z,J){return z.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(V,X,Y)=>{let Z=J[X];return Z!==void 0&&Z!==""?Z:Y??""})}var Uc=(z,J)=>{let V={};for(let[X,Y]of Object.entries(z))if(typeof Y==="string")V[X]=Ts(Y,J);return V},tf=[{relative:"GEMINI.md",source:"gemini"},{relative:$e(".gemini","GEMINI.md"),source:"gemini"},{relative:".cursorrules",source:"cursor"},{relative:".windsurfrules",source:"windsurf"},{relative:$e(".github","copilot-instructions.md"),source:"copilot"}],nf=[{relative:$e(".gemini","GEMINI.md"),source:"gemini"}],rf=[{relative:$e(".cursor","rules"),source:"cursor",extension:".mdc"},{relative:$e(".windsurf","rules"),source:"windsurf",extension:".md"}];function of(z,J){let V=$e(z,".clinerules"),X=Zm(V)?fn(V,".md"):[V],Y=[];for(let Z of X){let Q=Ye(Z)?.trim();if(Q)Y.push({path:Z,source:"cline",scope:J,content:Q})}return Y}function sf(z,J,V){let{fields:X,body:Y}=As(J);if(X.alwaysApply==="false")return{path:z,source:"cursor",scope:V,reason:"alwaysApply: false"};if(!Y)return{path:z,source:"cursor",scope:V,reason:"no rule body"};let Z=X.globs?.replace(/^\[|\]$/g,"").trim();return{path:z,source:"cursor",scope:V,content:Y,...Z?{note:`Applies to: ${Z}`}:{}}}var af=["AGENTS.md","CLAUDE.md"],Xc=["",".claude"],D=["commands"];function cf(z,J){let V=[],X=new Set;for(let Y of[...Xc,J])for(let Z of af){let Q=$e(z,Y,Z),ee=Ye(Q)?.trim();if(!ee||X.has(ee))continue;X.add(ee),V.push({path:Q,content:ee})}return V}function Gc(z,J){return cf(z,J).map((V)=>V.content)}var _=["AGENTS.md","CLAUDE.md","GEMINI.md"];function Rs(z,J){for(let V of _)for(let X of[...Xc,J]){let Y=$e(z,X,V),Z=Ye(Y)?.trim();if(Z)return{path:Y,content:Z}}return null}var Os=(z=process.env)=>$e(z.HLIX_CONFIG_HOME??$e(c(z),".hlix"),"AGENTS.md");function P(z){let J=z.env??process.env,V=Os(J),X=Ye(V)?.trim();return{global:X?{path:V,content:X}:null,project:Rs(z.cwd,z.configDir)}}var Bc=(z)=>{let J=Math.round(z.length/4);return J>=1000?`${(J/1000).toFixed(1)}k tokens`:`${J} tokens`};function F(z,J,V=process.env){let X=[...z.global?[Zc(z.global.path,V)]:[],...z.project?[Xn(z.project.path,J)]:[]];return X.length===0?"":`rules: ${X.join(" + ")}`}function T(z,J,V=process.env,X=[]){let Y=(Z,Q,ee)=>Q?`${Z.padEnd(8)} ${ee(Q.path)} (${Bc(Q.content)})`:`${Z.padEnd(8)} none`;return[Y("user",z.global,(Z)=>Zc(Z,V)),Y("project",z.project,(Z)=>Xn(Z,J)),...X.map((Z)=>`${"nested".padEnd(8)} ${Xn(Z.path,J)} (${Bc(Z.content)})`),"","User rules go first, the project's after, so the project wins a conflict.",X.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(`
|
|
341
|
-
`)}var Wc=[{dir:".claude",source:"claude",harnessReads:!0},{dir:".agents",source:"agents",harnessReads:!0},{dir:".hlix",source:"hlix",harnessReads:!0},{dir:".codex",source:"codex",harnessReads:!1}],lf=[{relative:$e(".cursor","commands"),source:"cursor"},{relative:$e(".codex","prompts"),source:"codex"}],df=[{relative:$e(".cursor","mcp.json"),source:"cursor",key:"mcpServers",format:"json"},{relative:$e(".windsurf","mcp.json"),source:"windsurf",key:"mcpServers",format:"json"},{relative:$e(".gemini","settings.json"),source:"gemini",key:"mcpServers",format:"json"},{relative:$e(".vscode","mcp.json"),source:"vscode",key:"servers",format:"json"},{relative:$e(".codex","config.toml"),source:"codex",key:"mcp_servers",format:"toml"},{relative:".mcp.json",source:"claude",key:"mcpServers",format:"json"}];function Yc(z){return[...df,{relative:$e(z,"mcp.json"),source:"hlix",key:"mcpServers",format:"json"}]}var pf="found, not loaded (machine-wide; enable per project by copying into .hlix/mcp.json)",uf=(z)=>Yc(z).filter((J)=>J.source!=="vscode");function mf(z,J){if(!z||typeof z!=="object"||Array.isArray(z))return{reason:"not an object"};let V=z;if(V.enabled===!1||V.disabled===!0)return{reason:"disabled"};let X=typeof V.command==="string"&&V.command!=="",Y=typeof V.url==="string"&&V.url!=="";if(X&&Y)return{reason:'has both "command" and "url"'};if(X){let se=Array.isArray(V.args)?V.args.filter((pe)=>typeof pe==="string"):void 0,ie=V.env&&typeof V.env==="object"&&!Array.isArray(V.env)?Uc(V.env,J):void 0;return{config:{command:V.command,...se&&se.length>0?{args:se}:{},...ie&&Object.keys(ie).length>0?{env:ie}:{}}}}if(!Y)return{reason:'missing "command" or "url"'};let Z=V.headers??V.http_headers,Q=Z&&typeof Z==="object"&&!Array.isArray(Z)?Uc(Z,J):{},ee=V.bearer_token_env_var;if(typeof ee==="string"&&/^[A-Za-z_][A-Za-z0-9_]*$/.test(ee)&&!Object.keys(Q).some((se)=>se.toLowerCase()==="authorization"))Q.Authorization=`Bearer ${Ts(`\${${ee}}`,J)}`;let te=Object.entries(Q).find(([se])=>se.toLowerCase()==="authorization")?.[1]?.trim(),re=te&&!/^Bearer$/i.test(te)&&!te.includes("${"),ne=V.oauth===!0||V.oauth&&typeof V.oauth==="object"||typeof ee==="string"&&!J[ee];return{config:{url:Ts(V.url,J),...ne&&!re?{needsSignIn:!0}:{},...Object.keys(Q).length>0?{headers:Q}:{}}}}function zc(z,J,V,X){let Y=Ye(z),Z=[],Q=[];if(Y===null)return{servers:Z,skipped:Q};let ee=[];if(J.format==="toml"){let te=Vc(Y);ee=Object.entries(te).filter(([re])=>re.startsWith(`${J.key}.`)).map(([re,ne])=>[re.slice(J.key.length+1),ne])}else try{let re=JSON.parse(Y)?.[J.key];if(re&&typeof re==="object"&&!Array.isArray(re))ee=Object.entries(re)}catch{return Q.push({path:z,source:J.source,scope:V,reason:"not valid JSON"}),{servers:Z,skipped:Q}}for(let[te,re]of ee){let ne=mf(re,X);if("reason"in ne){Q.push({path:z,source:J.source,scope:V,reason:`${te}: ${ne.reason}`});continue}Z.push({path:z,source:J.source,scope:V,name:te,config:ne.config})}return{servers:Z,skipped:Q}}function ff(z,J,V){let{fields:X,body:Y}=As(J);if(!Y)return{path:z,source:"claude",scope:V,reason:"no instructions"};let Z=X.tools?.replace(/^\[|\]$/g,"").split(",").map((Q)=>Q.trim()).filter(Boolean);return{path:z,source:"claude",scope:V,name:X.name||qc(z,".md"),description:X.description??"",instructions:Y,...Z&&Z.length>0&&Z[0]!=="*"?{tools:Z}:{},...X.model?{model:X.model}:{}}}function gf(z){let J=Vc(z)[""]??{},V=typeof J.prompt==="string"?J.prompt.trim():"";if(!V)return null;return{description:typeof J.description==="string"?J.description:"",body:V}}function R(z,J,V={}){let X=V.configDir??".hlix",Y=V.env??process.env,Z={instructions:[],skills:[],commands:[],generatedCommands:[],mcpServers:[],subagents:[],skipped:[]},Q=(fe)=>{if("reason"in fe)Z.skipped.push(fe);else Z.instructions.push(fe)};for(let fe of tf){let ce=$e(z,fe.relative),le=Ye(ce)?.trim();if(le)Z.instructions.push({path:ce,source:fe.source,scope:"project",content:le})}for(let fe of rf)for(let ce of fn($e(z,fe.relative),fe.extension)){let le=Ye(ce);if(le===null)continue;if(fe.source==="cursor"){Q(sf(ce,le,"project"));continue}let{body:me}=As(le);if(me)Z.instructions.push({path:ce,source:fe.source,scope:"project",content:me})}for(let fe of of(z,"project"))Q(fe);let ee=Gc(z,X),te=$e(z,".codex","AGENTS.md"),re=Ye(te)?.trim();if(re&&ee.includes(re))Z.skipped.push({path:te,source:"codex",scope:"project",reason:"same content as the project's AGENTS.md"});else if(re)Z.instructions.push({path:te,source:"codex",scope:"project",content:re});for(let fe of nf){let ce=$e(J,fe.relative),le=Ye(ce)?.trim();if(le)Z.instructions.push({path:ce,source:fe.source,scope:"global",content:le})}let ne=$e(J,".codex","AGENTS.md"),se=Ye(ne)?.trim(),ie=Gc(J,X);if(se&&ie.includes(se))Z.skipped.push({path:ne,source:"codex",scope:"global",reason:"same content as the machine's AGENTS.md"});else if(se)Z.instructions.push({path:ne,source:"codex",scope:"global",content:se});for(let[fe,ce]of[[z,"project"],[J,"global"]])for(let le of Wc){let me=$e(fe,le.dir===".hlix"?X:le.dir,"skills");if(!Qm(me).some((Ee)=>Ye($e(Ee,"SKILL.md"))!==null))continue;Z.skills.push({path:me,source:le.source,scope:ce,harnessReads:le.harnessReads})}for(let[fe,ce]of[[z,"project"],[J,"global"]]){for(let le of Wc){if(!le.harnessReads)continue;let me=$e(fe,le.dir,"commands");if(fn(me,".md").length===0)continue;Z.commands.push({path:me,source:le.source,scope:ce,harnessReads:!0})}for(let le of lf){let me=$e(fe,le.relative);if(fn(me,".md").length===0)continue;Z.commands.push({path:me,source:le.source,scope:ce})}for(let le of fn($e(fe,".gemini","commands"),".toml")){let me=Ye(le),ve=me===null?null:gf(me);if(!ve){Z.skipped.push({path:le,source:"gemini",scope:ce,reason:"no prompt field"});continue}Z.generatedCommands.push({path:le,source:"gemini",scope:ce,name:qc(le,".toml"),body:`---
|
|
342
|
-
description: ${ve.description}
|
|
343
|
-
---
|
|
344
|
-
|
|
345
|
-
${ve.body}
|
|
346
|
-
`})}}for(let fe of Yc(X)){let ce=zc($e(z,fe.relative),fe,"project",Y);Z.skipped.push(...ce.skipped);for(let le of ce.servers){let me=Z.mcpServers.findIndex((ve)=>ve.name===le.name);if(me===-1)Z.mcpServers.push(le);else Z.mcpServers[me]=le}}for(let fe of uf(X)){let ce=zc($e(J,fe.relative),fe,"global",Y);for(let le of ce.servers)Z.skipped.push({path:le.path,source:le.source,scope:"global",reason:`${le.name}: ${pf}`})}let pe=[{dir:$e(".claude","agents"),source:"claude"},{dir:$e(X,"agents"),source:"hlix"}];for(let[fe,ce]of[[z,"project"],[J,"global"]])for(let le of pe.flatMap((me)=>fn($e(fe,me.dir),".md"))){let me=Ye(le);if(me===null)continue;let ve=ff(le,me,ce);if("reason"in ve)Z.skipped.push(ve);else if(Z.subagents.some((Ee)=>Ee.name===ve.name))Z.skipped.push({path:le,source:"claude",scope:ce,reason:`a project agent already claims the name ${ve.name}`});else Z.subagents.push(ve)}return Z}function H(z,J){if(z.length===0)return null;let V=$e(Vm(),"hlix-standards-commands",Bm("sha256").update(J).digest("hex").slice(0,16));try{Jm(V,{recursive:!0,force:!0}),Wm(V,{recursive:!0});for(let X of z)Km($e(V,`${X.name}.md`),X.body,"utf8");return V}catch{return null}}var Xn=(z,J)=>{let V=Ym(J,z);return!V||V.startsWith("..")||Xm(V)?z:V},Zc=(z,J=process.env)=>{let V=J.HLIX_CONFIG_HOME;if(V&&z.startsWith(`${V}/`))return`~/.hlix/${z.slice(V.length+1)}`;let X=c(J);return X&&z.startsWith(`${X}/`)?`~/${z.slice(X.length+1)}`:z};function U(z,J){if(z.length===0)return"";let V=["# 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(`
|
|
347
|
-
`),X=z.map((Y)=>{let Z=`# From ${Xn(Y.path,J)} (${Y.source})`;return`${Y.note?`${Z}
|
|
348
|
-
${Y.note}`:Z}
|
|
349
|
-
|
|
350
|
-
${Y.content}`});return`${V}
|
|
351
|
-
|
|
352
|
-
${X.join(`
|
|
353
|
-
|
|
354
|
-
`)}`}var Vn=(z,J,V)=>`${z} ${z===1?J:V}`;function B(z){let J=[];if(z.instructions.length>0)J.push(Vn(z.instructions.length,"instruction file","instruction files"));if(z.skills.length>0)J.push(Vn(z.skills.length,"skill directory","skill directories"));let V=z.commands.length+z.generatedCommands.length;if(V>0)J.push(Vn(V,"command source","command sources"));if(z.mcpServers.length>0)J.push(Vn(z.mcpServers.length,"mcp server","mcp servers"));if(z.subagents.length>0)J.push(Vn(z.subagents.length,"subagent","subagents"));if(J.length===0)return"";let X=[...new Set([...z.instructions,...z.skills,...z.commands,...z.generatedCommands,...z.mcpServers,...z.subagents].map((Y)=>Y.source))].sort();return`standards: ${J.join(" · ")} (${X.join(", ")})`}function Qc(z,J){let V=[],X=(Z,Q)=>{if(Q.length===0)return;V.push(Z,...Q.map((ee)=>` ${ee}`),"")},Y=(Z)=>`${Z.source}${Z.scope==="global"?" (global)":""} ${Xn(Z.path,J)}`;if(X("Instructions",z.instructions.map((Z)=>`${Y(Z)}${Z.note?` — ${Z.note}`:""}`)),X("Skills",z.skills.map((Z)=>`${Y(Z)}${Z.harnessReads?" — already read by the harness":""}`)),X("Commands",[...z.commands.map((Z)=>`${Y(Z)}${Z.harnessReads?" — already read by the harness":""}`),...z.generatedCommands.map((Z)=>`${Y(Z)} → /${Z.name}`)]),X("MCP servers",z.mcpServers.map((Z)=>`${Y(Z)} → ${Z.name} (${"command"in Z.config?"stdio":"http"})`)),X("Subagents",z.subagents.map((Z)=>`${Y(Z)} → ${Z.name}`)),X("Skipped",z.skipped.map((Z)=>`${Y(Z)} — ${Z.reason}`)),V.length===0)return`No standards from other agent tools were found in this folder.
|
|
355
|
-
`;return`${V.join(`
|
|
356
|
-
`).trimEnd()}
|
|
357
|
-
`}function kf(z){return z==="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(`
|
|
358
|
-
`):["# 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(`
|
|
359
|
-
`)}function Sf(z){return z.VISUAL?.trim()||z.EDITOR?.trim()||"vi"}var Ns={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 (${_.join(", then ")}).`].join(`
|
|
360
|
-
`),supportsJson:!0,options:["edit","global"],async run(z){let J=P({cwd:z.cwd,configDir:".hlix",env:z.env}),V=z.flags.global===!0;if(z.flags.edit===!0){if(z.json)throw new e("invalid_usage","`hlix rules --edit` opens an editor, so it has no --json form.");let X=V?Os(z.env):Rs(z.cwd,".hlix")?.path??`${z.cwd}/AGENTS.md`;if(!yf(X))wf(bf(X),{recursive:!0}),vf(X,kf(V?"global":"project"),"utf8"),z.stdout(`Created ${X}.
|
|
361
|
-
`);let Y=Sf(z.env),Z=hf(Y,[X],{stdio:"inherit"});if(Z.error)throw new e("invalid_usage",`Could not run ${Y}: ${Z.error.message}`);return Z.status??0}if(z.json){let X=(Y)=>Y?{path:Y.path,characters:Y.content.length}:null;return z.stdout(ke(Se(Ns.name,{user:X(J.global),project:X(J.project)}))),0}return z.stdout(`${T(J,z.cwd)}
|
|
362
|
-
`),0}};var Fs={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(`
|
|
363
|
-
`),supportsJson:!0,async run(z){let J=R(z.cwd,c(z.env),{env:z.env});if(z.json)return z.stdout(ke(Se(Fs.name,{instructions:J.instructions.map((V)=>({path:V.path,source:V.source,scope:V.scope,characters:V.content.length,...V.note?{note:V.note}:{}})),skills:J.skills,commands:[...J.commands.map((V)=>({path:V.path,source:V.source,scope:V.scope})),...J.generatedCommands.map((V)=>({path:V.path,source:V.source,scope:V.scope,command:V.name}))],mcpServers:J.mcpServers.map((V)=>({path:V.path,source:V.source,scope:V.scope,name:V.name,transport:"command"in V.config?"stdio":"http"})),subagents:J.subagents.map((V)=>({path:V.path,source:V.source,scope:V.scope,name:V.name,description:V.description,...V.model?{model:V.model}:{}})),skipped:J.skipped}))),0;return z.stdout(Qc(J,z.cwd)),0}};import{accessSync as xf,constants as jf,mkdirSync as Ef,readFileSync as Pf,realpathSync as If,statSync as tl,writeFileSync as _f}from"node:fs";import{homedir as Cf}from"node:os";import{basename as $f,dirname as el,join as gn}from"node:path";var Tf={homebrew:"Homebrew",npm:"npm",installer:"installer",unknown:"unknown origin"},nl=(z)=>z.HOME||Cf();function Hs(z){return gn(z.XDG_DATA_HOME||gn(nl(z),".local","share"),"hlix","hlix")}function rl(z){try{return If(z)}catch{return null}}function Af(z){try{let J=JSON.parse(Pf(gn(Hs(z),"install.json"),"utf8"));if(typeof J.path==="string")return J.path}catch{}return gn(nl(z),".local","bin","hlix")}function Rf(z,J){if(/\/Cellar\/hlix\//.test(z))return"homebrew";if(/\/node_modules\/@hlix\/cli\//.test(z))return"npm";if(rl(Af(J))===z)return"installer";return"unknown"}function Ls(z,J){let V=rl(z);if(!V)return null;try{if(!tl(V).isFile())return null;xf(V,jf.X_OK)}catch{return null}return{path:z,realPath:V,channel:Rf(V,J)}}function Of(z){let J=[];for(let V of(z.PATH??"").split(":")){if(!V)continue;let X=Ls(gn(V,"hlix"),z);if(X&&!J.some((Y)=>Y.realPath===X.realPath))J.push(X)}return J}function Ms(z,J=process.execPath){if(z.HLIX_SELF)return Ls(z.HLIX_SELF,z);if(/^(node|bun)(\.exe)?$/.test($f(J)))return null;return Ls(J,z)}function Ds(z){switch(z.channel){case"homebrew":return"brew uninstall hlix";case"npm":return"npm uninstall -g @hlix/cli";case"installer":return`${z.path} uninstall`;case"unknown":return`rm ${z.path}`}}var Kr=(z)=>`${z.path} (${Tf[z.channel]})`;function Us(z,J=process.execPath){let V=Ms(z,J),X=Of(z);if(V&&!X.some((ee)=>ee.realPath===V.realPath))X.push(V);if(X.length<2)return{running:V,copies:X,duplicate:null};let[Y,...Z]=X,Q=`${X.length} copies of hlix are installed: ${Kr(Y)} runs, ${Z.map(Kr).join(" and ")} ${Z.length===1?"does":"do"} not. Keep one: ${Z.map(Ds).join(" && ")}`;return{running:V,copies:X,duplicate:Q}}var Nf=86400000;function G(z,J=Date.now(),V=process.execPath){let{duplicate:X}=Us(z,V);if(!X)return null;let Y=gn(el(lt(z)),"duplicate-notice");try{if(J-tl(Y).mtimeMs<Nf)return null}catch{}try{Ef(el(Y),{recursive:!0}),_f(Y,`${X}
|
|
364
|
-
`)}catch{}return X}var sl=(z)=>z instanceof Error?z.message:String(z),ol=(z)=>z.split(/\s*\n\s*/).join(" ").trim();async function N(z,J,V,X,Y){try{let Z=await ut(J,{historyMode:V,environment:z.env,rootName:X}),Q=a(J)?.files,ee=un(Z.manifest);return{changedFiles:Q?[...new Set([...Object.keys(Q),...ee.keys()])].filter((re)=>Q[re]!==ee.get(re)).length:null,files:Z.manifest.totals.files,manifestSha256:Z.manifestSha256,changed:Y?Z.manifestSha256!==Y:null,blocking:Z.blocking,error:null}}catch(Z){return{changedFiles:null,files:null,manifestSha256:null,changed:null,blocking:[],error:sl(Z)}}}var Gs={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(z){let J=r({env:z.env,flags:z.flags,cwd:z.cwd}),V=J.binding,X=V?a(V.root):null,Y=V?await N(z,V.root,X?.snapshotOnly?"sanitize":X?.historyMode??"preserve",X?.rootName,X?.manifestSha256):null,Z=null;if(V?.config.projectId&&J.credential&&!J.conflict)try{let re=z.requireClient(),ne=await re.projects.get(V.config.projectId),se=X?.repoId??ne.repos.find((pe)=>pe.isPrimary)?.id??ne.repos[0]?.id;if(!se)throw Error("Select a primary HLIX Repos");let ie=await re.repos.head(V.config.projectId,se);Z={commitSha:ie.commitSha,changed:X?ie.commitSha!==X.commitSha:null,error:null,errorMessage:null}}catch(re){Z={commitSha:"",changed:null,error:Ho(re).code,errorMessage:re instanceof Rt?"no HLIX Repos commit yet — `hlix push` publishes this folder":sl(re)}}let Q=Us(z.env),ee={cwd:z.cwd,workspace:{id:J.workspaceId,source:J.workspaceSource},api:{baseUrl:J.baseUrl,source:J.baseUrlSource},credential:{present:J.credential!==null,source:J.credentialSource,path:J.credentialPath},conflict:J.conflict,project:V?{root:V.root,projectId:V.config.projectId??null,workspaceId:V.config.workspaceId,apiUrl:V.config.apiUrl}:null,repository:X?{repoId:X.repoId,commitSha:X.commitSha}:null,local:Y,cloud:Z,install:{channel:Q.running?.channel??null,path:Q.running?.path??null,copies:Q.copies.map(({path:re,channel:ne})=>({path:re,channel:ne})),duplicate:Q.duplicate}};if(z.json)return z.stdout(ke(Se(Gs.name,ee))),0;let te=[["folder",z.cwd],["workspace",J.workspaceId?`${J.workspaceId} (from ${J.workspaceSource})`:"none — run `hlix login --workspace <id>`"],["api",`${J.baseUrl} (from ${J.baseUrlSource})`],["credential",b(J)??"none — run `hlix login`"],["project",V?V.config.projectId??`initialized at ${V.root}, not imported yet`:"none — run `hlix import .` to bind this folder"]];if(X)te.push(["HLIX Repos",X.commitSha]);if(Y){if(te.push(["local",Y.error?`could not scan: ${Y.error}`:Y.changed===null?`${Y.files} files, no synced base commit`:Y.changed?`${Y.files} files, modified since the last sync`:`${Y.files} files, matches the last sync`]),Y.blocking.length>0)te.push(["blocking",Y.blocking.join("; ")])}if(Z)te.push(["cloud",Z.error==="not_found"?ol(Z.errorMessage??Z.error):Z.error?`not checked — ${ol(Z.errorMessage??Z.error)}`:Z.changed?`commit ${Z.commitSha} available — run \`hlix pull\``:`commit ${Z.commitSha}, up to date`]);if(J.conflict)te.push(["conflict",J.conflict]);if(Q.running)te.push(["installed",Kr(Q.running)]);if(Q.duplicate)te.push(["duplicate",Q.duplicate]);return z.stdout(`${Me(te)}
|
|
366
|
-
`),0}};import{spawnSync as il}from"node:child_process";var Bs={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,signIn:!0,options:["print","web"],args:{min:0,max:1},async run(z){let J=z.args[0]??t(z.cwd)?.config.projectId;if(!J)throw new e("missing_argument","A project id is required, or run this inside a folder bound to a project.");let V=await z.requireClient().projects.terminal(J);if(z.json)return z.stdout(ke(Se(Bs.name,V))),V.available?0:1;if(!V.available){let Q=V.environmentState?` (environment: ${V.environmentState})`:"";throw new e("not_found",`${V.reason??"Terminal unavailable"}${Q}`)}let X=z.flags.print===!0,Y=z.flags.web===!0;if(X||Y&&!V.webTerminalUrl||!Y&&!V.sshCommand)return z.stdout(`${Me([["ssh",V.sshCommand??"not available"],["browser",V.webTerminalUrl??"not available"]])}
|
|
368
|
-
`),0;if(Y){if(il(process.platform==="darwin"?"open":"xdg-open",[V.webTerminalUrl],{stdio:"ignore"}).status!==0)z.stdout(`${V.webTerminalUrl}
|
|
369
|
-
`);return 0}return il("sh",["-c",V.sshCommand],{stdio:"inherit"}).status??1}};import{rmSync as al}from"node:fs";import{dirname as Ff}from"node:path";var Ws={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(z){let J=Ms(z.env);if(!J||J.channel!=="installer")throw new e("invalid_request",J&&J.channel!=="unknown"?`This hlix was installed with ${J.channel==="homebrew"?"Homebrew":"npm"}. Remove it with: ${Ds(J)}`:"Only an hlix installed by the one-line installer can remove itself.");if(z.flags.yes!==!0){if(z.json||!z.confirm)throw new e("approval_required","Removing hlix needs approval. Repeat with `--yes`.");if(!await z.confirm(`Remove ${J.path}? Your login is kept.`))throw new e("cancelled","Uninstall cancelled.")}let V=Hs(z.env);al(J.path,{force:!0}),al(V,{recursive:!0,force:!0});let X=Ff(lt(z.env));if(z.json)z.stdout(ke(Se(Ws.name,{removed:[J.path,V],kept:X})));else z.stdout(`Removed ${J.path}
|
|
371
|
-
Your login in ${X} is kept.
|
|
372
|
-
`);return 0}};function M(z){return[...z.pulled?[`HLIX Repos: pulled ${z.pulled}`]:[],...z.pushed?[`HLIX Repos: pushed ${z.pushed}`]:[]]}async function L(z,J,V){let X=!1;while(!V.signal?.aborted){try{let Y=await _s(z,J.client,J.env);if(V.onReport({conflicts:[],...Y.action==="push"?{pushed:Y.commitSha}:Y.action==="pull"?{pulled:Y.commitSha}:{}}),!X)X=!0,V.onCaughtUp?.()}catch(Y){V.onError(Y)}await at(15000,V.signal)}}var cl={name:"mirror",summary:"Follow HLIX Repos using Git",usage:"Usage: hlix mirror [--json]",supportsJson:!0,signIn:!0,options:[],agentTool:!1,async run(z){let{root:J}=await mn(z.cwd);return await L(J,{client:z.requireClient(),env:z.env},{signal:z.signal,onReport:(V)=>{if(z.json)z.stdout(ke(Se("hlix mirror",V)));else for(let X of M(V))z.stdout(`${X}
|
|
373
|
-
`)},onError:(V)=>z.stderr(`${V instanceof Error?V.message:String(V)}
|
|
374
|
-
`)}),0}};import{lstat as Js,readFile as Lf,realpath as Hf}from"node:fs/promises";import{basename as zs,dirname as Mf,extname as Df,join as qr,parse as ll,resolve as Vr}from"node:path";function hn(z,J){let V=z.flags[J];return typeof V==="string"&&V.trim()?V.trim():void 0}function Ks(z){let J=hn(z,"project");if(J)return{root:z.cwd,projectId:J};return Uf(z.cwd)}function Uf(z){let J=t(z);if(!J?.config.projectId)throw new e("not_initialized","This folder is not bound to an Hlix project. Run `hlix import .` first.");return{root:J.root,projectId:J.config.projectId}}async function qs(z,J){let V=await Js(z);if(V.isSymbolicLink()||!V.isFile())throw Error(`Refusing to import a non-regular file: ${z}`);if(V.size>J)throw Error(`Import file exceeds ${J} bytes: ${z}`);return{path:await Hf(z),content:await Lf(z,"utf8")}}function Vs(z,J,V,X){if(z.json)z.stdout(ke(Se(J,V)));else z.stdout(`${X}
|
|
375
|
-
`)}function Gf(z){let J=/^---\r?\n([\s\S]*?)\r?\n---/.exec(z)?.[1];return(J?/^name:\s*(.+?)\s*$/m.exec(J)?.[1]:void 0)?.replace(/^["']|["']$/g,"").trim()||void 0}var Bf=[qr(".claude","skills"),qr(".agents","skills"),qr(".hlix","skills")];async function Wf(z,J){let V=[Vr(z,J),...Bf.map((X)=>Vr(z,X,J))];for(let X of V)if(await Js(X).then(()=>!0,()=>!1))return X;throw new e("not_found",`No skill at ${J}. Pass the SKILL.md or its folder, for example .claude/skills/${J}.`)}var Xs={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,signIn:!0,options:["name","project"],args:{min:1,max:1},async run(z){if(z.args.length!==1)throw Error("skill import requires one file or folder.");let J=Ks(z),V=await Wf(z.cwd,z.args[0]),X=await Js(V);if(X.isSymbolicLink())throw Error(`Refusing to import a symlink: ${V}`);let Y=X.isDirectory()?qr(V,"SKILL.md"):V,Z=await qs(Y,200000),Q=X.isDirectory()?zs(V):zs(Y)==="SKILL.md"?zs(Mf(Y)):ll(Y).name,ee=hn(z,"name")??Q;if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(ee))throw Error("Skill name must be a lowercase kebab-case slug.");let te=await z.requireClient().resources.importSkill(J.projectId,{slug:ee,content:Z.content});return Vs(z,Xs.name,te.skill,`Imported skill ${ee}`),0}},Ys={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,signIn:!0,options:["name","runtime","duty","profile","project"],args:{min:1,max:1},async run(z){if(z.args.length!==1)throw Error("agent import requires one Markdown file.");let J=Ks(z),V=Vr(z.cwd,z.args[0]);if(![".md",".mdx"].includes(Df(V).toLowerCase()))throw Error("Agent imports must be Markdown files.");let X=await qs(V,20000),Y=hn(z,"runtime");if(Y!==void 0&&!s.includes(Y)){let te=new Intl.ListFormat("en",{type:"disjunction"}).format(s);throw Error(`--runtime must be ${te}.`)}let Z=hn(z,"duty")??"executor";if(Z!=="executor"&&Z!=="intake")throw Error("--duty must be executor or intake.");let Q=hn(z,"name")??Gf(X.content)??ll(V).name.replace(/[-_]+/g," "),ee=await z.requireClient().resources.importAgent(J.projectId,{name:Q,instructions:X.content,...Y?{runtimeKind:Y}:{},duty:Z});return Vs(z,Ys.name,ee.agent,ee.agent.duty==="intake"?`Imported agent ${ee.agent.name} as this project's intake agent`:`Imported agent ${ee.agent.name}`),0}},Zs={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,signIn:!0,options:["server","allow-stdio","project"],args:{min:1,max:1},async run(z){if(z.args.length!==1)throw Error("mcp import requires one MCP JSON file.");let J=Ks(z),V=await qs(Vr(z.cwd,z.args[0]),200000),X;try{X=JSON.parse(V.content)}catch{throw Error("MCP config is not valid JSON.")}let Y=Object.entries(X.mcpServers??{});if(Y.length===0)throw Error("MCP config contains no servers.");let Z=hn(z,"server");if(!Z&&Y.length>1)throw Error("MCP config contains multiple servers; select one with --server <name>.");let Q=Z?Y.find(([ce])=>ce===Z):Y[0];if(!Q)throw Error(`MCP server not found: ${Z}`);let[ee,te]=Q,re=te.type==="http"||te.type==="sse"?te.type:typeof te.command==="string"?"stdio":typeof te.url==="string"?"http":null;if(!re)throw Error(`MCP server ${ee} has no supported transport.`);if(re==="stdio"&&z.flags["allow-stdio"]!==!0)throw Error("Stdio MCP servers execute a command on the Cloud Machine; repeat with --allow-stdio.");let ne=te.env&&typeof te.env==="object"&&!Array.isArray(te.env)?te.env:{},se=te.headers&&typeof te.headers==="object"&&!Array.isArray(te.headers)?te.headers:{};if(Object.values(se).some((ce)=>typeof ce!=="string"))throw Error(`MCP server ${ee} headers must be strings.`);for(let[ce,le]of Object.entries(ne)){if(typeof le!=="string")continue;let me=/^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/.exec(le)?.[1];if(me&&me!==ce)throw new e("invalid_usage",`MCP server ${ee}: env ${ce} references \${${me}}, but a placeholder must be the variable's own name — write "${ce}": "\${${ce}}" and store the secret as ${ce}.`)}let ie=Object.values(se).flatMap((ce)=>[...ce.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g)].map((le)=>le[1]));if(Object.keys(se).length>0&&ie.length===0)throw Error("MCP remote headers must use ${KEY} placeholders; literal credentials are refused.");let pe=/^(?:(?:Bearer|Basic|Token) )?\$\{[A-Za-z_][A-Za-z0-9_]*\}$/i;if(Object.values(se).some((ce)=>!pe.test(ce)))throw Error("MCP remote headers must be ${KEY} or an approved auth scheme followed by ${KEY}.");let fe=await z.requireClient().resources.importMcp(J.projectId,{name:ee,transport:re,...typeof te.command==="string"?{command:te.command}:{},...Array.isArray(te.args)&&te.args.every((ce)=>typeof ce==="string")?{args:te.args}:{},...typeof te.url==="string"?{url:te.url}:{},...Object.keys(se).length>0?{headers:se}:{},envKeys:[...new Set([...Object.keys(ne),...ie])].sort()});return Vs(z,Zs.name,fe.mcpServer,`Imported MCP server ${ee}`),0}};import{spawnSync as zf}from"node:child_process";import{chmod as Jf,realpath as Kf,writeFile as qf}from"node:fs/promises";import{basename as Vf,dirname as Xf,relative as Yf,resolve as pl,sep as Zf}from"node:path";var dl=64;function Zn(z){let J=t(z.cwd),X=(typeof z.flags.project==="string"?z.flags.project:void 0)??J?.config.projectId;if(!X)throw new e("not_initialized","This folder is not bound to a Hlix project. Run `hlix import .`, or pass --project <id>.");return{projectId:X,root:J?.root??z.cwd}}var Yn=(z,J)=>typeof z[J]==="string"?z[J]:void 0,Qs={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,signIn:!0,options:["project"],async run(z){let{projectId:J}=Zn(z),V=await z.requireClient().secrets.listEntries(J);if(z.json)return z.stdout(ke(Se(Qs.name,V))),0;if(V.entries.length===0)z.stdout(`No secrets stored for this project.
|
|
377
|
-
`);else z.stdout(`${ht(["key","source","format","value","updated"],V.entries.map((X)=>[X.key,X.source,X.format||"-",X.maskedValue,X.updatedAt?.slice(0,10)??"-"]))}
|
|
378
|
-
`);for(let X of V.warnings)z.stderr(`warning: ${X}
|
|
379
|
-
`);return 0}},ei={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,signIn:!0,options:["from-stdin","source","project"],args:{min:1,max:2},async run(z){let{projectId:J}=Zn(z),V=z.args[0],X=z.flags["from-stdin"]===!0;if(X&&z.args.length>1)throw new e("invalid_usage","Pass the value as an argument or with --from-stdin, not both.");if(!X&&z.args.length<2)throw new e("missing_argument","A value is required. Pass it as an argument, or pipe it with --from-stdin.");let Y;if(X){if(!z.readStdin)throw new e("invalid_usage","--from-stdin is not available in this context.");Y=(await z.readStdin()).replace(/\r?\n$/,"")}else Y=z.args[1];let Z=Yn(z.flags,"source"),Q=await z.requireClient().secrets.upsertEntries(J,{entries:[{key:V,value:Y,...Z?{source:Z}:{}}]});if(z.json)return z.stdout(ke(Se(ei.name,Q))),Q.written>0?0:1;if(Q.written===0)throw new e("bad_request",`The store refused ${V}: --source must be a project-relative file path.`);return z.stdout(`${Me([["key",V],["source",Z??".env"]])}
|
|
381
|
-
`),0}},ti={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,signIn:!0,options:["source","project"],args:{min:1,max:1},async run(z){let{projectId:J}=Zn(z),V=z.args[0],X=Yn(z.flags,"source"),Y=await z.requireClient().secrets.deleteEntry(J,V,X);if(z.json)return z.stdout(ke(Se(ti.name,Y))),Y.removed>0?0:1;if(Y.removed===0)return z.stderr(`No stored secret named ${V}${X?` in ${X}`:""}.
|
|
383
|
-
`),1;return z.stdout(`Removed ${Y.removed} entr${Y.removed===1?"y":"ies"} for ${V}.
|
|
384
|
-
`),0}},Xr={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,signIn:!0,options:["project"],args:{min:0,max:64},async run(z){let{projectId:J,root:V}=Zn(z),X=await ut(V,{historyMode:"preserve",environment:z.env}),Y=X.blocking.filter((se)=>!se.startsWith(bs));if(Y.length>0)throw new e("scan_blocked",`Project scan blocked the import:
|
|
386
|
-
- ${Y.join(`
|
|
387
|
-
- `)}`);let Z=X.protectedFiles.filter((se)=>se.kind==="dotenv"||se.kind==="credential"),Q=await Kf(z.cwd),ee=z.args.map((se)=>Yf(X.root,pl(Q,se)).split(Zf).join("/")),te=ee.filter((se)=>!Z.some((ie)=>ie.path===se));if(te.length>0)throw new e("invalid_usage",`Not a secret file in this project: ${te.join(", ")}`);let re=ee.length>0?Z.filter((se)=>ee.includes(se.path)):Z;if(re.length===0)return z.stdout(z.json?ke(Se(Xr.name,{imported:[],skipped:[],warnings:[],written:0,rejected:[]})):`No secret files found in this project.
|
|
388
|
-
`),0;if(re.length>dl)throw new e("invalid_usage",`${re.length} secret files exceeds the ${dl} the store accepts in one request. Name the files to import, a batch at a time.`);let ne=await z.requireClient().secrets.importFiles(J,re.map((se)=>({path:se.path,contentBase64:se.contentBase64})));if(z.json)return z.stdout(ke(Se(Xr.name,ne))),0;if(ne.imported.length>0)z.stdout(`${ht(["source","format","stored"],ne.imported.map((se)=>[se.path,se.format||"-",se.kind==="file"?"as file":`${se.entries} entr${se.entries===1?"y":"ies"}`]))}
|
|
389
|
-
`);if(z.stdout(`${ne.written} value${ne.written===1?"":"s"} stored.
|
|
390
|
-
`),ne.imported.some((se)=>se.kind!=="file"))z.stdout(`Each imported file replaced what the store held under its path; keys the file no longer has are gone.
|
|
391
|
-
`);for(let se of ne.skipped)z.stderr(`skipped ${se.path}: ${se.reason}
|
|
392
|
-
`);for(let se of ne.warnings)z.stderr(`warning: ${se}
|
|
393
|
-
`);for(let se of ne.rejected)z.stderr(`rejected ${se}: the store refused its source path
|
|
394
|
-
`);return 0}};function Qf(z){return zf("git",["-C",Xf(z),"ls-files","--error-unmatch","--",Vf(z)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}).status===0}var ni={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,signIn:!0,options:["source","format","out","project"],async run(z){let{projectId:J}=Zn(z),V=Yn(z.flags,"source"),X=Yn(z.flags,"format"),Y=Yn(z.flags,"out"),Z=Y===void 0?void 0:pl(z.cwd,Y);if(Z!==void 0&&Qf(Z))throw new e("invalid_usage",`Refusing to overwrite a git-tracked file with secret values: ${Z}`);let Q=await z.requireClient().secrets.exportEntries(J,{...V?{source:V}:{},...X?{format:X}:{}});if(Z!==void 0)await qf(Z,Q,{mode:384}),await Jf(Z,384);if(z.json)return z.stdout(ke(Se(ni.name,{source:V??null,format:X??null,out:Z??null,bytes:Buffer.byteLength(Q),...Z===void 0?{content:Q}:{}}))),0;if(Z===void 0)z.stdout(Q);else z.stdout(`${Me([["wrote",Z],["mode","0600"],["bytes",String(Buffer.byteLength(Q))]])}
|
|
396
|
-
`);return 0}};function oi(z){let J=z.flags.project;if(typeof J==="string"&&J)return J;return t(z.cwd)?.config.projectId??void 0}function ri(z,J){let V=z[J];if(typeof V!=="string"||V.trim()==="")throw new e("missing_argument",`--${J} is required.`);return V}var si={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,signIn:!0,options:["title","description"],args:{min:1,max:1},async run(z){let J=z.args[0],V=ri(z.flags,"title"),X=ri(z.flags,"description"),Y=await z.requireClient().cycles.propose({projectId:J,title:V,description:X});if(z.json)return z.stdout(ke(Se(si.name,Y))),0;return z.stdout(`${Me([["project",J],["title",V],["status",Y.adopted?"adopted — the project is planning it now":"recorded — it will be planned on the next pass"]])}
|
|
398
|
-
`),0}},ii={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,signIn:!0,options:["title","description"],args:{min:1,max:1},async run(z){let J=z.args[0],V=ri(z.flags,"description"),X=typeof z.flags.title==="string"?z.flags.title:void 0,Y=await z.requireClient().tasks.create({projectId:J,description:V,...X?{title:X}:{}});if(z.json)return z.stdout(ke(Se(ii.name,Y))),0;return z.stdout(`${Me([["task",Y.id],["project",J],["status",Y.status??"queued"],["note","not started — dispatch with `hlix cycles create`"]])}
|
|
400
|
-
`),0}},ai={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,signIn:!0,options:["project"],args:{min:0,max:1},async run(z){let J=z.args[0]??oi(z),V=z.requireClient(),X=J?await V.modelConfig.resolved(J):await V.modelConfig.resolved();if(z.json)return z.stdout(ke(Se(ai.name,X))),0;return z.stdout(`${Me([["scope",J?`project ${J}`:"workspace"],["harness",X.cycle.harness],["source",X.cycle.source.harness]])}
|
|
402
|
-
`),0}},ci={name:"harness set",summary:"Choose the coder a project or the workspace runs",usage:[`Usage: hlix harness set <${s.join("|")}> [project-id] [--org] [--json]`,"","With a project id, sets that project's Cycle harness. With --org, the","workspace-wide one that projects fall back to. This is a PERSISTENT server","setting that every future run on that scope uses, and it is audited. A","provider the new harness cannot use (a ChatGPT login under Goose) goes","back to hlix-managed.","","It is not the same thing as the local `harness` config key, which only","picks the coder Hlix Code spawns on this machine."].join(`
|
|
403
|
-
`),supportsJson:!0,signIn:!0,options:["org"],args:{min:1,max:2},async run(z){let J=z.args[0];if(!s.includes(J))throw new e("invalid_usage",`harness must be one of ${s.join(", ")}; got "${J}".`);let V=z.flags.org===!0,X=z.args[1]??(V?void 0:oi(z));if(X&&V)throw new e("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!X&&!V)throw new e("invalid_usage","Name the project to set, or pass --org for the whole workspace.");let Y=z.requireClient(),Z=X?await Y.modelConfig.setProjectHarness(X,J):await Y.modelConfig.setHarness(J);if(z.json)return z.stdout(ke(Se(ci.name,Z))),0;return z.stdout(`${Me([["scope",X?`project ${X}`:"workspace"],["harness",J]])}
|
|
404
|
-
`),0}},li={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,signIn:!0,options:["org"],args:{min:0,max:1},async run(z){let J=z.flags.org===!0,V=z.args[0]??(J?void 0:oi(z));if(V&&J)throw new e("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!V&&!J)throw new e("invalid_usage","Name the project to clear, or pass --org for the whole workspace.");let X=z.requireClient(),Y=V?await X.modelConfig.clearProjectHarness(V):await X.modelConfig.clearHarness();if(z.json)return z.stdout(ke(Se(li.name,Y))),0;return z.stdout(`${Me([["scope",V?`project ${V}`:"workspace"],["harness","cleared — the scope below decides now"]])}
|
|
406
|
-
`),0}};var f=[xr,Mo,jr,fa,ga,Gs,Ws,Bs,Fs,Ns,qo,Vo,Xo,Ss,Dc,Mc,Hc,Lc,cl,Xs,Ys,Zs,Qs,ei,ti,Xr,ni,Yo,Zo,Qo,es,ts,rs,os,ss,is,ii,si,ai,ci,li];import{emitKeypressEvents as eg}from"node:readline";import{createInterface as ul}from"node:readline/promises";async function W(z){if(!process.stdin.isTTY||!process.stdin.setRawMode)throw Error("Interactive login requires a terminal. Set HLIX_API_KEY for CI.");return process.stderr.write(z),eg(process.stdin),process.stdin.setRawMode(!0),process.stdin.resume(),new Promise((J,V)=>{let X="",Y=()=>{process.stdin.off("keypress",Z),process.stdin.setRawMode(!1),process.stdin.pause(),process.stderr.write(`
|
|
407
|
-
`)},Z=(Q,ee)=>{if(ee.ctrl&&ee.name==="c"||ee.name==="escape"){Y(),V(Error("Login cancelled."));return}if(ee.name==="return"||ee.name==="enter"){Y(),J(X);return}if(ee.name==="backspace"){X=X.slice(0,-1);return}if(Q&&!ee.ctrl)X+=Q};process.stdin.on("keypress",Z)})}async function C(z,J){if(!process.stdin.isTTY||!process.stderr.isTTY)throw Error("Interactive selection requires a terminal. Pass --workspace <id>.");let V=ul({input:process.stdin,output:process.stderr});try{for(let X=0;X<3;X+=1){let Y=(await V.question(z)).trim(),Z=Number(Y);if(Number.isInteger(Z)&&Z>=1&&Z<=J)return Z-1;process.stderr.write(`Enter a number between 1 and ${J}.
|
|
408
|
-
`)}throw Error("No workspace selected.")}finally{V.close()}}async function K(z){if(!process.stdin.isTTY||!process.stderr.isTTY)throw Error("Interactive approval requires a terminal. Review with --dry-run, then pass --yes.");let J=ul({input:process.stdin,output:process.stderr});try{let V=(await J.question(`${z}
|
|
409
|
-
Continue? [y/N] `)).trim().toLowerCase();return V==="y"||V==="yes"}finally{J.close()}}
|
|
410
|
-
export{e,v,h,j,n,x,y,l,b,t,r,i,w,g,q,o,d,a,S,A,p,u,s,O,k,E,I,m,c,D,_,P,F,T,R,H,U,B,G,N,M,L,f,W,C,K};
|