@hlix/cli 0.4.4 → 0.4.5

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 CHANGED
@@ -33,8 +33,8 @@ For CI, and for anything else that must not change underneath you, pin the
33
33
  version instead of floating to `latest`:
34
34
 
35
35
  ```bash
36
- npm install --global @hlix/cli@0.4.4
37
- npx @hlix/cli@0.4.4 status --json
36
+ npm install --global @hlix/cli@0.4.5
37
+ npx @hlix/cli@0.4.5 status --json
38
38
  ```
39
39
 
40
40
  ## Authenticate
@@ -6,10 +6,10 @@ import{l as Rr,m as Ar,q as Hr}from"./index-rraz48fm.js";import{r as Rs}from"./i
6
6
  `,"utf8"),Mn(o),bt(o),o=void 0,is(s,n);let i=Bn(r,Pe.O_RDONLY);try{try{Mn(i)}catch(a){let c=a.code;if(c!=="EINVAL"&&c!=="ENOTSUP")throw a}}finally{bt(i)}}catch(i){if(o!==void 0)bt(o);if(Qe(s))qn(s);throw i}return n}import{constants as et,existsSync as tt,lstatSync as Vn,mkdirSync as ds,openSync as ps,closeSync as Wn,fsyncSync as us,readFileSync as Xn,renameSync as ms,unlinkSync as fs,writeFileSync as Pt}from"node:fs";import{dirname as gs,join as Ce,resolve as nt}from"node:path";function hs(e){if(!tt(e))return;let t=Vn(e);if(t.isSymbolicLink()||!t.isFile())throw Error(`Refusing to replace a non-regular Hlix file: ${e}`)}function $e(e,t){let n=gs(e);if(ds(n,{recursive:!0,mode:448}),Vn(n).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${n}`);hs(e);let r=Ce(n,`.hlix-${process.pid}-${crypto.randomUUID()}.tmp`),s;try{s=ps(r,et.O_WRONLY|et.O_CREAT|et.O_EXCL|et.O_NOFOLLOW,384),Pt(s,`${JSON.stringify(t,null,2)}
7
7
  `,"utf8"),us(s),Wn(s),s=void 0,ms(r,e)}catch(o){if(s!==void 0)Wn(s);if(tt(r))fs(r);throw o}}function Ie(e){return Ce(nt(e),".hlix","config.json")}function Yn(e){return Ce(nt(e),".hlix","state.json")}function le(e){try{let t=JSON.parse(Xn(Ie(e),"utf8"));return t.schemaVersion===1&&t.workspaceId&&t.apiUrl?t:null}catch{return null}}function xe(e,t){$e(Ie(e),t);let n=Ce(nt(e),".hlix",".gitignore");if(!tt(n))Pt(n,`state.json
8
8
  `,{mode:420,flag:"wx"});let r=Ce(nt(e),".hlixignore");if(!tt(r))Pt(r,`# Additional project-local paths to exclude from Hlix snapshots.
9
- `,{mode:420,flag:"wx"})}function _e(e,t){$e(Yn(e),t)}function rt(e){try{let t=JSON.parse(Xn(Yn(e),"utf8"));return t.schemaVersion===1&&t.revisionId&&t.generation>0?t:null}catch{return null}}var Ct="https://server.hlix.ai";function O(e){let t=vs(e);for(;;){let n=le(t);if(n)return{root:t,config:n};let r=ws(t);if(r===t)return null;t=r}}function Qn(e){try{return ys(e).isDirectory()}catch{return!1}}function st(e){if(typeof e!=="string")return;let t=e.trim();return t?t:void 0}var Zn=(e,t)=>e.replace(/\/+$/,"")===t.replace(/\/+$/,"");function B(e){let{env:t,flags:n,cwd:r}=e,s=O(r),o=Dn(t),i=o?t.HLIX_API_KEY||t.HLIX_SESSION_TOKEN?"env":"file":null,a=i==="file"?o:null,c=st(n["base-url"]),l=st(t.HLIX_BASE_URL),p=st(n.workspace),d=st(t.HLIX_WORKSPACE_ID),u=c??l??s?.config.apiUrl??a?.baseUrl??Ct,m=c?"flag":l?"env":s?.config.apiUrl?"project":a?.baseUrl?"credential":"default",w=p??d??s?.config.workspaceId??a?.organizationId??null,b=p?"flag":d?"env":s?.config.workspaceId?"project":a?.organizationId?"credential":null;return{baseUrl:u,baseUrlSource:m,workspaceId:w,workspaceSource:b,credential:o,credentialSource:i,credentialPath:ce(t),binding:s,conflict:ks(s,{flagBaseUrl:c,envBaseUrl:l,flagWorkspace:p,envWorkspace:d})}}function ks(e,t){if(!e)return null;let n=`${e.root} is bound to`,r="Drop the override, or point --cwd at a folder bound to it.";if(t.flagWorkspace&&t.flagWorkspace!==e.config.workspaceId)return`${n} workspace ${e.config.workspaceId}, but --workspace names ${t.flagWorkspace}. ${r}`;if(t.envWorkspace&&t.envWorkspace!==e.config.workspaceId)return`${n} workspace ${e.config.workspaceId}, but HLIX_WORKSPACE_ID names ${t.envWorkspace}. ${r}`;if(t.flagBaseUrl&&!Zn(t.flagBaseUrl,e.config.apiUrl))return`${n} ${e.config.apiUrl}, but --base-url names ${t.flagBaseUrl}. ${r}`;if(t.envBaseUrl&&!Zn(t.envBaseUrl,e.config.apiUrl))return`${n} ${e.config.apiUrl}, but HLIX_BASE_URL names ${t.envBaseUrl}. ${r}`;return null}import{resolve as As}from"node:path";import{parseArgs as Hs}from"node:util";import bs from"openapi-fetch";function $t(e){return bs({baseUrl:e.baseUrl,headers:e.headers,fetch:e.fetch})}var de=(e)=>({kind:"apiKey",apiKey:e});var It=(e)=>({kind:"bearer",token:e});function Ss(e){switch(e.kind){case"apiKey":return{"x-api-key":e.apiKey};case"session":return{cookie:e.cookie};case"bearer":return{authorization:`Bearer ${e.token}`}}}function js(e){return e?{"X-Organization-Id":e}:{}}function er(e,t){return{...Ss(e),...js(t)}}function Es(e){if(typeof e!=="object"||e===null)return null;let{error:t}=e;return typeof t==="string"?t:null}class U extends Error{status;body;requestId;method;url;constructor(e,t){super(e);this.name=new.target.name,this.status=t.status,this.body=t.body,this.requestId=t.requestId??null,this.method=t.method,this.url=t.url}}class Oe extends U{issues;constructor(e,t,n){super(e,t);this.issues=n}}class Te extends U{}class Re extends U{}class Ae extends U{}class He extends U{}class Fe extends U{}class Ne extends U{retryAfter;constructor(e,t,n){super(e,t);this.retryAfter=n}}class Ue extends U{}class Le extends U{}class pe extends Error{method;url;constructor(e,t){super(e,{cause:t.cause});this.name="HlixTransportError",this.method=t.method,this.url=t.url}}function Ps(e){if(typeof e!=="object"||e===null)return null;let t=e;if(t.success!==!1)return null;let n=t.error?.message;if(typeof n!=="string")return null;try{let r=JSON.parse(n);return Array.isArray(r)?r:[]}catch{return[]}}function Cs(e){let t=e.get("retry-after");if(!t)return null;let n=Number(t);return Number.isFinite(n)&&n>=0?n:null}function ue(e,t,n){let r={status:e.status,body:t,requestId:e.headers.get("x-request-id"),method:n.method,url:n.url},s=Es(t),o=`${n.method} ${n.url} failed with ${e.status}`,i=Ps(t);if(i)return new Oe(`${n.method} ${n.url}: request body failed validation`,r,i);let a=s??o;switch(e.status){case 400:return new Te(a,r);case 401:return new Re(a,r);case 403:return new Ae(a,r);case 404:return new He(a,r);case 409:return new Fe(a,r);case 429:return new Ne(a,r,Cs(e.headers));case 501:return new Ue(a,r);default:return e.status>=500?new Le(a,r):new U(a,r)}}var tr=new Set(["GET","HEAD","PUT","DELETE","OPTIONS","TRACE"]);function ot(e){return tr.has(e.toUpperCase())}var $s=new Set([429,500,502,503,504]);function Is(e){return $s.has(e)}var xt={attempts:3,baseDelayMs:200,maxDelayMs:5000};function _t(e,t,n,r=Math.random){if(n!==null)return Math.min(n*1000,t.maxDelayMs);let s=Math.min(t.baseDelayMs*2**e,t.maxDelayMs);return Math.round(r()*s)}function Ot(e){if(!ot(e.method))return!1;if(e.attempt+1>=e.policy.attempts)return!1;return e.status===null||Is(e.status)}var xs=(e)=>new Promise((t)=>setTimeout(t,e));function _s(e){let t=e.headers.get("retry-after");if(!t)return null;let n=Number(t);return Number.isFinite(n)&&n>=0?n:null}function nr(e){let{base:t,policy:n}=e,r=e.sleep??xs,s=e.random??Math.random;return async(o)=>{let i=o.method.toUpperCase(),a=ot(i)?o.clone():null;for(let c=0;;c+=1){let l=c===0?o:a.clone(),p;try{p=await t(l)}catch(d){if(!a||!Ot({method:i,attempt:c,policy:n,status:null}))throw new pe(`${i} ${o.url}: ${d instanceof Error?d.message:String(d)}`,{method:i,url:o.url,cause:d});await r(_t(c,n,null,s));continue}if(!Ot({method:i,attempt:c,policy:n,status:p.status}))return p;if(!a)return p;await r(_t(c,n,_s(p),s))}}}function v(e,t){if(e.response.ok)return e.data;throw ue(e.response,e.error??e.data,t)}var Me=(e)=>typeof e==="string"?e:"";function Tt(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=="object"||t===null)return null;let n=t;switch(n.type){case"idle":return{type:"idle"};case"done":return{type:"done"};case"active":return typeof n.runId==="string"?{type:"active",runId:n.runId}:{type:"active"};case"on_chat_model_stream":return{type:"on_chat_model_stream",delta:Me(n.delta)};case"reasoning":return{type:"reasoning",delta:Me(n.delta)};case"on_tool_start":return{type:"on_tool_start",name:Me(n.name),input:n.input};case"on_tool_end":return{type:"on_tool_end",name:Me(n.name),output:n.output};case"error":return{type:"error",message:Me(n.message)};default:return null}}var Rt=(e)=>e.type==="done"||e.type==="idle"||e.type==="error";var Os=()=>({event:null,data:[],id:null,retry:null});function rr(e,t,n){switch(t){case"event":e.event=n;return;case"data":e.data.push(n);return;case"id":if(!n.includes("\x00"))e.id=n;return;case"retry":{if(/^\d+$/.test(n))e.retry=Number(n);return}default:return}}function or(e){let t=e.data.join(`
9
+ `,{mode:420,flag:"wx"})}function _e(e,t){$e(Yn(e),t)}function rt(e){try{let t=JSON.parse(Xn(Yn(e),"utf8"));return t.schemaVersion===1&&t.revisionId&&t.generation>0?t:null}catch{return null}}var Ct="https://server.hlix.ai";function O(e){let t=vs(e);for(;;){let n=le(t);if(n)return{root:t,config:n};let r=ws(t);if(r===t)return null;t=r}}function Qn(e){try{return ys(e).isDirectory()}catch{return!1}}function st(e){if(typeof e!=="string")return;let t=e.trim();return t?t:void 0}var Zn=(e,t)=>e.replace(/\/+$/,"")===t.replace(/\/+$/,"");function B(e){let{env:t,flags:n,cwd:r}=e,s=O(r),o=Dn(t),i=o?t.HLIX_API_KEY||t.HLIX_SESSION_TOKEN?"env":"file":null,a=i==="file"?o:null,c=st(n["base-url"]),l=st(t.HLIX_BASE_URL),p=st(n.workspace),d=st(t.HLIX_WORKSPACE_ID),u=c??l??s?.config.apiUrl??a?.baseUrl??Ct,m=c?"flag":l?"env":s?.config.apiUrl?"project":a?.baseUrl?"credential":"default",v=p??d??s?.config.workspaceId??a?.organizationId??null,b=p?"flag":d?"env":s?.config.workspaceId?"project":a?.organizationId?"credential":null;return{baseUrl:u,baseUrlSource:m,workspaceId:v,workspaceSource:b,credential:o,credentialSource:i,credentialPath:ce(t),binding:s,conflict:ks(s,{flagBaseUrl:c,envBaseUrl:l,flagWorkspace:p,envWorkspace:d})}}function ks(e,t){if(!e)return null;let n=`${e.root} is bound to`,r="Drop the override, or point --cwd at a folder bound to it.";if(t.flagWorkspace&&t.flagWorkspace!==e.config.workspaceId)return`${n} workspace ${e.config.workspaceId}, but --workspace names ${t.flagWorkspace}. ${r}`;if(t.envWorkspace&&t.envWorkspace!==e.config.workspaceId)return`${n} workspace ${e.config.workspaceId}, but HLIX_WORKSPACE_ID names ${t.envWorkspace}. ${r}`;if(t.flagBaseUrl&&!Zn(t.flagBaseUrl,e.config.apiUrl))return`${n} ${e.config.apiUrl}, but --base-url names ${t.flagBaseUrl}. ${r}`;if(t.envBaseUrl&&!Zn(t.envBaseUrl,e.config.apiUrl))return`${n} ${e.config.apiUrl}, but HLIX_BASE_URL names ${t.envBaseUrl}. ${r}`;return null}import{resolve as As}from"node:path";import{parseArgs as Hs}from"node:util";import bs from"openapi-fetch";function $t(e){return bs({baseUrl:e.baseUrl,headers:e.headers,fetch:e.fetch})}var de=(e)=>({kind:"apiKey",apiKey:e});var It=(e)=>({kind:"bearer",token:e});function Ss(e){switch(e.kind){case"apiKey":return{"x-api-key":e.apiKey};case"session":return{cookie:e.cookie};case"bearer":return{authorization:`Bearer ${e.token}`}}}function js(e){return e?{"X-Organization-Id":e}:{}}function er(e,t){return{...Ss(e),...js(t)}}function Es(e){if(typeof e!=="object"||e===null)return null;let{error:t}=e;return typeof t==="string"?t:null}class U extends Error{status;body;requestId;method;url;constructor(e,t){super(e);this.name=new.target.name,this.status=t.status,this.body=t.body,this.requestId=t.requestId??null,this.method=t.method,this.url=t.url}}class Oe extends U{issues;constructor(e,t,n){super(e,t);this.issues=n}}class Te extends U{}class Re extends U{}class Ae extends U{}class He extends U{}class Fe extends U{}class Ne extends U{retryAfter;constructor(e,t,n){super(e,t);this.retryAfter=n}}class Ue extends U{}class Le extends U{}class pe extends Error{method;url;constructor(e,t){super(e,{cause:t.cause});this.name="HlixTransportError",this.method=t.method,this.url=t.url}}function Ps(e){if(typeof e!=="object"||e===null)return null;let t=e;if(t.success!==!1)return null;let n=t.error?.message;if(typeof n!=="string")return null;try{let r=JSON.parse(n);return Array.isArray(r)?r:[]}catch{return[]}}function Cs(e){let t=e.get("retry-after");if(!t)return null;let n=Number(t);return Number.isFinite(n)&&n>=0?n:null}function ue(e,t,n){let r={status:e.status,body:t,requestId:e.headers.get("x-request-id"),method:n.method,url:n.url},s=Es(t),o=`${n.method} ${n.url} failed with ${e.status}`,i=Ps(t);if(i)return new Oe(`${n.method} ${n.url}: request body failed validation`,r,i);let a=s??o;switch(e.status){case 400:return new Te(a,r);case 401:return new Re(a,r);case 403:return new Ae(a,r);case 404:return new He(a,r);case 409:return new Fe(a,r);case 429:return new Ne(a,r,Cs(e.headers));case 501:return new Ue(a,r);default:return e.status>=500?new Le(a,r):new U(a,r)}}var tr=new Set(["GET","HEAD","PUT","DELETE","OPTIONS","TRACE"]);function ot(e){return tr.has(e.toUpperCase())}var $s=new Set([429,500,502,503,504]);function Is(e){return $s.has(e)}var xt={attempts:3,baseDelayMs:200,maxDelayMs:5000};function _t(e,t,n,r=Math.random){if(n!==null)return Math.min(n*1000,t.maxDelayMs);let s=Math.min(t.baseDelayMs*2**e,t.maxDelayMs);return Math.round(r()*s)}function Ot(e){if(!ot(e.method))return!1;if(e.attempt+1>=e.policy.attempts)return!1;return e.status===null||Is(e.status)}var xs=(e)=>new Promise((t)=>setTimeout(t,e));function _s(e){let t=e.headers.get("retry-after");if(!t)return null;let n=Number(t);return Number.isFinite(n)&&n>=0?n:null}function nr(e){let{base:t,policy:n}=e,r=e.sleep??xs,s=e.random??Math.random;return async(o)=>{let i=o.method.toUpperCase(),a=ot(i)?o.clone():null;for(let c=0;;c+=1){let l=c===0?o:a.clone(),p;try{p=await t(l)}catch(d){if(!a||!Ot({method:i,attempt:c,policy:n,status:null}))throw new pe(`${i} ${o.url}: ${d instanceof Error?d.message:String(d)}`,{method:i,url:o.url,cause:d});await r(_t(c,n,null,s));continue}if(!Ot({method:i,attempt:c,policy:n,status:p.status}))return p;if(!a)return p;await r(_t(c,n,_s(p),s))}}}function w(e,t){if(e.response.ok)return e.data;throw ue(e.response,e.error??e.data,t)}var Me=(e)=>typeof e==="string"?e:"";function Tt(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=="object"||t===null)return null;let n=t;switch(n.type){case"idle":return{type:"idle"};case"done":return{type:"done"};case"active":return typeof n.runId==="string"?{type:"active",runId:n.runId}:{type:"active"};case"on_chat_model_stream":return{type:"on_chat_model_stream",delta:Me(n.delta)};case"reasoning":return{type:"reasoning",delta:Me(n.delta)};case"on_tool_start":return{type:"on_tool_start",name:Me(n.name),input:n.input};case"on_tool_end":return{type:"on_tool_end",name:Me(n.name),output:n.output};case"error":return{type:"error",message:Me(n.message)};default:return null}}var Rt=(e)=>e.type==="done"||e.type==="idle"||e.type==="error";var Os=()=>({event:null,data:[],id:null,retry:null});function rr(e,t,n){switch(t){case"event":e.event=n;return;case"data":e.data.push(n);return;case"id":if(!n.includes("\x00"))e.id=n;return;case"retry":{if(/^\d+$/.test(n))e.retry=Number(n);return}default:return}}function or(e){let t=e.data.join(`
10
10
  `),n=e.event,r=e.id;if(e.data=[],e.event=null,t==="")return null;return{event:n,data:t,id:r,retry:e.retry}}function sr(e,t){if(t==="")return or(e);if(t.startsWith(":"))return null;let n=t.indexOf(":");if(n===-1)return rr(e,t,""),null;let r=t.slice(0,n),s=t.slice(n+1);if(s.startsWith(" "))s=s.slice(1);return rr(e,r,s),null}function Ts(e){let t=[],n=0;for(let r=0;r<e.length;r+=1){let s=e[r];if(s!==`
11
11
  `&&s!=="\r")continue;if(t.push(e.slice(n,r)),s==="\r"&&e[r+1]===`
12
- `)r+=1;n=r+1}return{lines:t,rest:e.slice(n)}}async function*At(e,t){let n=e.getReader(),r=new TextDecoder,s=Os(),o="",i=()=>void n.cancel().catch(()=>{});t?.addEventListener("abort",i,{once:!0});try{for(;;){let{done:c,value:l}=await n.read();if(c)break;o+=r.decode(l,{stream:!0});let{lines:p,rest:d}=Ts(o);o=d;for(let u of p){let m=sr(s,u);if(m)yield m}if(t?.aborted)return}if(o+=r.decode(),o!==""){let c=sr(s,o);if(c)yield c}let a=or(s);if(a)yield a}finally{t?.removeEventListener("abort",i),n.releaseLock()}}class me{raw;baseUrl;headers;fetcher;constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.headers=er(e.credential,e.organizationId);let t={...xt,...e.retry},n=e.fetch??((r)=>globalThis.fetch(r));this.fetcher=nr({base:n,policy:t}),this.raw=$t({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(e,t){return{method:e,url:`${this.baseUrl}${t}`}}workspaces={list:async()=>v(await this.raw.GET("/v1/api/workspaces"),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>v(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(e)=>v(await this.raw.GET("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}`)),create:async(e)=>v(await this.raw.POST("/v1/api/projects",{body:e}),this.at("POST","/v1/api/projects")),delete:async(e)=>v(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("DELETE",`/v1/api/projects/${e}`)),start:async(e,t)=>v(await this.raw.POST("/v1/api/projects/{id}/start",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/start`)),refreshPreview:async(e)=>v(await this.raw.POST("/v1/api/projects/{id}/preview/refresh",{params:{path:{id:e}}}),this.at("POST",`/v1/api/projects/${e}/preview/refresh`)),terminal:async(e)=>v(await this.raw.GET("/v1/api/projects/{id}/terminal",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/terminal`)),observeAgent:(e,t,n)=>this.observeAgent(e,t,n),workspace:(e)=>({fs:async(t)=>v(await this.raw.POST("/v1/api/projects/{id}/workspace/fs",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/workspace/fs`)),exec:async(t)=>v(await this.raw.POST("/v1/api/projects/{id}/workspace/exec",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/workspace/exec`))})};secrets={listEntries:async(e)=>v(await this.raw.GET("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:e}}}),this.at("GET",`/v1/api/secrets/project/${e}/entries`)),upsertEntries:async(e,t)=>v(await this.raw.PUT("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:e}},body:t}),this.at("PUT",`/v1/api/secrets/project/${e}/entries`)),importFiles:async(e,t)=>v(await this.raw.PUT("/v1/api/secrets/project/{projectId}/files",{params:{path:{projectId:e}},body:{files:t}}),this.at("PUT",`/v1/api/secrets/project/${e}/files`)),deleteEntry:async(e,t,n)=>v(await this.raw.DELETE("/v1/api/secrets/project/{projectId}/entries/{key}",{params:{path:{projectId:e,key:t},...n===void 0?{}:{query:{source:n}}}}),this.at("DELETE",`/v1/api/secrets/project/${e}/entries/${encodeURIComponent(t)}`)),exportEntries:async(e,t={})=>{let n=`/v1/api/secrets/project/${e}/export`,r=`${this.baseUrl}${n}`,s=await this.fetcher(new Request(r,{method:"POST",headers:{...this.headers,"content-type":"application/json"},body:JSON.stringify({...t.source===void 0?{}:{source:t.source},...t.format===void 0?{}:{format:t.format}})}));if(!s.ok)throw ue(s,await s.json().catch(()=>{return}),{method:"POST",url:r});return s.text()}};imports={create:async(e)=>{let t=await this.raw.POST("/v1/api/imports",{body:e});return v(t,this.at("POST","/v1/api/imports"))},get:async(e)=>v(await this.raw.GET("/v1/api/imports/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/imports/${e}`)),finalize:async(e,t)=>{let n=await this.raw.POST("/v1/api/imports/{id}/finalize",{params:{path:{id:e}},body:t});return v(n,this.at("POST",`/v1/api/imports/${e}/finalize`))},uploadBundle:async(e,t,n={})=>{let r=n.chunkSize??8388608;if(r<=0||r%262144!==0)throw Error("Import upload chunkSize must be a positive multiple of 256 KiB");let s=e.url.startsWith("/")?`${this.baseUrl}${e.url}`:e.url;if(e.kind==="hlix-stream"){let i=new Request(s,{method:"PUT",headers:{...this.headers,"content-type":"application/x-git-bundle","content-length":String(t.size)},body:t,signal:n.signal}),a=await this.fetcher(i);if(!a.ok)await this.throwUploadError(a,s);n.onProgress?.(t.size,t.size);return}let o=0;while(o<t.size){let i=Math.min(o+r,t.size),a=new Request(s,{method:"PUT",headers:{"content-type":"application/x-git-bundle","content-length":String(i-o),"content-range":`bytes ${o}-${i-1}/${t.size}`},body:t.slice(o,i),signal:n.signal}),c=await this.fetcher(a);if(c.status!==308&&!c.ok)await this.throwUploadError(c,s);let l=c.headers.get("range")?.match(/bytes=0-(\d+)/)?.[1];if(o=l?Number(l)+1:i,!Number.isSafeInteger(o)||o<i||o>t.size)throw Error("Import upload server returned an invalid acknowledged range");n.onProgress?.(o,t.size)}}};revisions={head:async(e)=>v(await this.raw.GET("/v1/api/projects/{id}/revisions/head",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/revisions/head`)),protectedFiles:async(e)=>v(await this.raw.GET("/v1/api/projects/{id}/protected-files",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/protected-files`)),createUpload:async(e,t)=>{let n=await this.raw.POST("/v1/api/projects/{id}/revisions/uploads",{params:{path:{id:e}},body:t});return v(n,this.at("POST",`/v1/api/projects/${e}/revisions/uploads`))},finalize:async(e,t,n)=>{let r=await this.raw.POST("/v1/api/projects/{id}/revisions/uploads/{uploadId}/finalize",{params:{path:{id:e,uploadId:t}},body:n});return v(r,this.at("POST",`/v1/api/projects/${e}/revisions/uploads/${t}/finalize`))},uploadBundle:async(e,t,n={})=>this.imports.uploadBundle(e,t,n),downloadBundle:async(e,t)=>{let n=`/v1/api/projects/${e}/revisions/${t}/bundle`,r=new Request(`${this.baseUrl}${n}`,{method:"GET",headers:this.headers}),s=await this.fetcher(r);if(!s.ok)await this.throwUploadError(s,`${this.baseUrl}${n}`);return s.blob()}};resources={importSkill:async(e,t)=>v(await this.raw.POST("/v1/api/projects/{id}/resources/skill",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/resources/skill`)),importAgent:async(e,t)=>v(await this.raw.POST("/v1/api/projects/{id}/resources/agent",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/resources/agent`)),importMcp:async(e,t)=>v(await this.raw.POST("/v1/api/projects/{id}/resources/mcp",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/resources/mcp`))};async throwUploadError(e,t){let n=null;try{n=await e.json()}catch{n=await e.text().catch(()=>null)}throw ue(e,n,{method:"PUT",url:t})}tasks={list:async(e)=>v(await this.raw.GET("/v1/api/tasks",{params:{query:e??{}}}),this.at("GET","/v1/api/tasks")),get:async(e)=>v(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}`)),create:async(e)=>v(await this.raw.POST("/v1/api/tasks",{body:e}),this.at("POST","/v1/api/tasks")),update:async(e,t)=>v(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:e}},body:t}),this.at("PATCH",`/v1/api/tasks/${e}`)),listComments:async(e)=>v(await this.raw.GET("/v1/api/tasks/{id}/comments",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}/comments`)),addComment:async(e,t)=>v(await this.raw.POST("/v1/api/tasks/{id}/comments",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/tasks/${e}/comments`)),review:async(e)=>v(await this.raw.GET("/v1/api/tasks/{id}/review",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}/review`)),stream:(e,t)=>this.stream(`/v1/api/tasks/${e}/stream`,t)};modelConfig={setProjectHarness:async(e,t)=>v(await this.raw.PUT("/v1/api/model-config/harness/{projectId}",{params:{path:{projectId:e}},body:{harness:t}}),this.at("PUT",`/v1/api/model-config/harness/${e}`)),clearProjectHarness:async(e)=>v(await this.raw.DELETE("/v1/api/model-config/harness/{projectId}",{params:{path:{projectId:e}}}),this.at("DELETE",`/v1/api/model-config/harness/${e}`)),setHarness:async(e)=>v(await this.raw.PUT("/v1/api/model-config/harness",{body:{harness:e}}),this.at("PUT","/v1/api/model-config/harness")),clearHarness:async()=>v(await this.raw.DELETE("/v1/api/model-config/harness"),this.at("DELETE","/v1/api/model-config/harness")),resolvedHarness:async()=>v(await this.raw.GET("/v1/api/model-config/harness/resolved"),this.at("GET","/v1/api/model-config/harness/resolved")),resolvedProjectHarness:async(e)=>v(await this.raw.GET("/v1/api/model-config/harness/{projectId}/resolved",{params:{path:{projectId:e}}}),this.at("GET",`/v1/api/model-config/harness/${e}/resolved`))};cycles={list:async(e)=>v(await this.raw.GET("/v1/api/cycles",{params:{query:e??{}}}),this.at("GET","/v1/api/cycles")),get:async(e)=>v(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/cycles/${e}`)),propose:async(e)=>v(await this.raw.POST("/v1/api/cycles",{body:e}),this.at("POST","/v1/api/cycles")),stream:(e,t)=>this.stream(`/v1/api/cycles/${e}/stream`,t)};clientInvoices={list:async(e)=>v(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:e??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(e)=>v(await this.raw.GET("/v1/api/client-billing/invoices/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/client-billing/invoices/${e}`)),createDraft:async(e)=>v(await this.raw.POST("/v1/api/client-billing/invoices",{body:e}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(e)=>v(await this.raw.POST("/v1/api/client-billing/invoices/{id}/issue",{params:{path:{id:e}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${e}/issue`)),void:async(e,t)=>v(await this.raw.POST("/v1/api/client-billing/invoices/{id}/void",{params:{path:{id:e}},body:{reason:t}}),this.at("POST",`/v1/api/client-billing/invoices/${e}/void`)),pay:async(e)=>v(await this.raw.POST("/v1/api/client-billing/invoices/{id}/pay",{params:{path:{id:e}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${e}/pay`)),paymentLink:async(e,t={})=>v(await this.raw.POST("/v1/api/client-billing/invoices/{id}/payment-link",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/client-billing/invoices/${e}/payment-link`))};async*observeAgent(e,t,n){let r=`/v1/api/projects/${e}/agents/${t}/observe`;for await(let s of this.stream(r,n)){let o=Tt(s.data);if(!o)continue;if(yield o,Rt(o))return}}async*stream(e,t){let n=`${this.baseUrl}${e}`,r=new Request(n,{headers:{...this.headers,accept:"text/event-stream"},signal:t?.signal}),s=await globalThis.fetch(r);if(!s.ok||!s.body){let o=null;try{o=await s.json()}catch{o=null}throw ue(s,o,{method:"GET",url:n})}yield*At(s.body,t?.signal)}}function Nt(e){if(e instanceof f)return{code:e.code,status:null};if(e instanceof Oe)return{code:"invalid_request",status:400};if(e instanceof Te)return{code:"bad_request",status:400};if(e instanceof Re)return{code:"unauthenticated",status:401};if(e instanceof Ae)return{code:"forbidden",status:403};if(e instanceof He)return{code:"not_found",status:404};if(e instanceof Fe)return{code:"conflict",status:409};if(e instanceof Ne)return{code:"rate_limited",status:429};if(e instanceof Ue)return{code:"not_implemented",status:501};if(e instanceof Le)return{code:"server_error",status:e.status};if(e instanceof pe)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var Ht=(e)=>e instanceof Error?e.message:String(e);function Fs(e,t){let n=B({env:e,flags:t.flags,cwd:t.cwd});if(n.conflict)throw new f("workspace_mismatch",n.conflict);if(!n.credential)throw new f("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");return new me({baseUrl:n.baseUrl,credential:n.credential.sessionToken?It(n.credential.sessionToken):de(n.credential.apiKey),...n.workspaceId?{organizationId:n.workspaceId}:{}})}function ir(e){let t=Math.max(...e.map((r)=>r.name.length));return`hlix — the hlix control-plane CLI
12
+ `)r+=1;n=r+1}return{lines:t,rest:e.slice(n)}}async function*At(e,t){let n=e.getReader(),r=new TextDecoder,s=Os(),o="",i=()=>void n.cancel().catch(()=>{});t?.addEventListener("abort",i,{once:!0});try{for(;;){let{done:c,value:l}=await n.read();if(c)break;o+=r.decode(l,{stream:!0});let{lines:p,rest:d}=Ts(o);o=d;for(let u of p){let m=sr(s,u);if(m)yield m}if(t?.aborted)return}if(o+=r.decode(),o!==""){let c=sr(s,o);if(c)yield c}let a=or(s);if(a)yield a}finally{t?.removeEventListener("abort",i),n.releaseLock()}}class me{raw;baseUrl;headers;fetcher;constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.headers=er(e.credential,e.organizationId);let t={...xt,...e.retry},n=e.fetch??((r)=>globalThis.fetch(r));this.fetcher=nr({base:n,policy:t}),this.raw=$t({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(e,t){return{method:e,url:`${this.baseUrl}${t}`}}workspaces={list:async()=>w(await this.raw.GET("/v1/api/workspaces"),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>w(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(e)=>w(await this.raw.GET("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}`)),create:async(e)=>w(await this.raw.POST("/v1/api/projects",{body:e}),this.at("POST","/v1/api/projects")),delete:async(e)=>w(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("DELETE",`/v1/api/projects/${e}`)),start:async(e,t)=>w(await this.raw.POST("/v1/api/projects/{id}/start",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/start`)),refreshPreview:async(e)=>w(await this.raw.POST("/v1/api/projects/{id}/preview/refresh",{params:{path:{id:e}}}),this.at("POST",`/v1/api/projects/${e}/preview/refresh`)),terminal:async(e)=>w(await this.raw.GET("/v1/api/projects/{id}/terminal",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/terminal`)),observeAgent:(e,t,n)=>this.observeAgent(e,t,n),workspace:(e)=>({fs:async(t)=>w(await this.raw.POST("/v1/api/projects/{id}/workspace/fs",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/workspace/fs`)),exec:async(t)=>w(await this.raw.POST("/v1/api/projects/{id}/workspace/exec",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/workspace/exec`))})};secrets={listEntries:async(e)=>w(await this.raw.GET("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:e}}}),this.at("GET",`/v1/api/secrets/project/${e}/entries`)),upsertEntries:async(e,t)=>w(await this.raw.PUT("/v1/api/secrets/project/{projectId}/entries",{params:{path:{projectId:e}},body:t}),this.at("PUT",`/v1/api/secrets/project/${e}/entries`)),importFiles:async(e,t)=>w(await this.raw.PUT("/v1/api/secrets/project/{projectId}/files",{params:{path:{projectId:e}},body:{files:t}}),this.at("PUT",`/v1/api/secrets/project/${e}/files`)),deleteEntry:async(e,t,n)=>w(await this.raw.DELETE("/v1/api/secrets/project/{projectId}/entries/{key}",{params:{path:{projectId:e,key:t},...n===void 0?{}:{query:{source:n}}}}),this.at("DELETE",`/v1/api/secrets/project/${e}/entries/${encodeURIComponent(t)}`)),exportEntries:async(e,t={})=>{let n=`/v1/api/secrets/project/${e}/export`,r=`${this.baseUrl}${n}`,s=await this.fetcher(new Request(r,{method:"POST",headers:{...this.headers,"content-type":"application/json"},body:JSON.stringify({...t.source===void 0?{}:{source:t.source},...t.format===void 0?{}:{format:t.format}})}));if(!s.ok)throw ue(s,await s.json().catch(()=>{return}),{method:"POST",url:r});return s.text()}};imports={create:async(e)=>{let t=await this.raw.POST("/v1/api/imports",{body:e});return w(t,this.at("POST","/v1/api/imports"))},get:async(e)=>w(await this.raw.GET("/v1/api/imports/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/imports/${e}`)),finalize:async(e,t)=>{let n=await this.raw.POST("/v1/api/imports/{id}/finalize",{params:{path:{id:e}},body:t});return w(n,this.at("POST",`/v1/api/imports/${e}/finalize`))},uploadBundle:async(e,t,n={})=>{let r=n.chunkSize??8388608;if(r<=0||r%262144!==0)throw Error("Import upload chunkSize must be a positive multiple of 256 KiB");let s=e.url.startsWith("/")?`${this.baseUrl}${e.url}`:e.url;if(e.kind==="hlix-stream"){let i=new Request(s,{method:"PUT",headers:{...this.headers,"content-type":"application/x-git-bundle","content-length":String(t.size)},body:t,signal:n.signal}),a=await this.fetcher(i);if(!a.ok)await this.throwUploadError(a,s);n.onProgress?.(t.size,t.size);return}let o=0;while(o<t.size){let i=Math.min(o+r,t.size),a=new Request(s,{method:"PUT",headers:{"content-type":"application/x-git-bundle","content-length":String(i-o),"content-range":`bytes ${o}-${i-1}/${t.size}`},body:t.slice(o,i),signal:n.signal}),c=await this.fetcher(a);if(c.status!==308&&!c.ok)await this.throwUploadError(c,s);let l=c.headers.get("range")?.match(/bytes=0-(\d+)/)?.[1];if(o=l?Number(l)+1:i,!Number.isSafeInteger(o)||o<i||o>t.size)throw Error("Import upload server returned an invalid acknowledged range");n.onProgress?.(o,t.size)}}};revisions={head:async(e)=>w(await this.raw.GET("/v1/api/projects/{id}/revisions/head",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/revisions/head`)),protectedFiles:async(e)=>w(await this.raw.GET("/v1/api/projects/{id}/protected-files",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/protected-files`)),createUpload:async(e,t)=>{let n=await this.raw.POST("/v1/api/projects/{id}/revisions/uploads",{params:{path:{id:e}},body:t});return w(n,this.at("POST",`/v1/api/projects/${e}/revisions/uploads`))},finalize:async(e,t,n)=>{let r=await this.raw.POST("/v1/api/projects/{id}/revisions/uploads/{uploadId}/finalize",{params:{path:{id:e,uploadId:t}},body:n});return w(r,this.at("POST",`/v1/api/projects/${e}/revisions/uploads/${t}/finalize`))},uploadBundle:async(e,t,n={})=>this.imports.uploadBundle(e,t,n),downloadBundle:async(e,t)=>{let n=`/v1/api/projects/${e}/revisions/${t}/bundle`,r=new Request(`${this.baseUrl}${n}`,{method:"GET",headers:this.headers}),s=await this.fetcher(r);if(!s.ok)await this.throwUploadError(s,`${this.baseUrl}${n}`);return s.blob()}};resources={importSkill:async(e,t)=>w(await this.raw.POST("/v1/api/projects/{id}/resources/skill",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/resources/skill`)),importAgent:async(e,t)=>w(await this.raw.POST("/v1/api/projects/{id}/resources/agent",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/resources/agent`)),importMcp:async(e,t)=>w(await this.raw.POST("/v1/api/projects/{id}/resources/mcp",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/projects/${e}/resources/mcp`))};async throwUploadError(e,t){let n=null;try{n=await e.json()}catch{n=await e.text().catch(()=>null)}throw ue(e,n,{method:"PUT",url:t})}tasks={list:async(e)=>w(await this.raw.GET("/v1/api/tasks",{params:{query:e??{}}}),this.at("GET","/v1/api/tasks")),get:async(e)=>w(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}`)),create:async(e)=>w(await this.raw.POST("/v1/api/tasks",{body:e}),this.at("POST","/v1/api/tasks")),update:async(e,t)=>w(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:e}},body:t}),this.at("PATCH",`/v1/api/tasks/${e}`)),listComments:async(e)=>w(await this.raw.GET("/v1/api/tasks/{id}/comments",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}/comments`)),addComment:async(e,t)=>w(await this.raw.POST("/v1/api/tasks/{id}/comments",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/tasks/${e}/comments`)),review:async(e)=>w(await this.raw.GET("/v1/api/tasks/{id}/review",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}/review`)),stream:(e,t)=>this.stream(`/v1/api/tasks/${e}/stream`,t)};modelConfig={setProjectHarness:async(e,t)=>w(await this.raw.PUT("/v1/api/model-config/harness/{projectId}",{params:{path:{projectId:e}},body:{harness:t}}),this.at("PUT",`/v1/api/model-config/harness/${e}`)),clearProjectHarness:async(e)=>w(await this.raw.DELETE("/v1/api/model-config/harness/{projectId}",{params:{path:{projectId:e}}}),this.at("DELETE",`/v1/api/model-config/harness/${e}`)),setHarness:async(e)=>w(await this.raw.PUT("/v1/api/model-config/harness",{body:{harness:e}}),this.at("PUT","/v1/api/model-config/harness")),clearHarness:async()=>w(await this.raw.DELETE("/v1/api/model-config/harness"),this.at("DELETE","/v1/api/model-config/harness")),resolvedHarness:async()=>w(await this.raw.GET("/v1/api/model-config/harness/resolved"),this.at("GET","/v1/api/model-config/harness/resolved")),resolvedProjectHarness:async(e)=>w(await this.raw.GET("/v1/api/model-config/harness/{projectId}/resolved",{params:{path:{projectId:e}}}),this.at("GET",`/v1/api/model-config/harness/${e}/resolved`))};ai={models:async(e,t)=>w(await this.raw.GET("/v1/api/ai/w/{workspaceId}/models",{params:{path:{workspaceId:e}},...t?.signal?{signal:t.signal}:{}}),this.at("GET",`/v1/api/ai/w/${e}/models`))};cycles={list:async(e)=>w(await this.raw.GET("/v1/api/cycles",{params:{query:e??{}}}),this.at("GET","/v1/api/cycles")),get:async(e)=>w(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/cycles/${e}`)),propose:async(e)=>w(await this.raw.POST("/v1/api/cycles",{body:e}),this.at("POST","/v1/api/cycles")),stream:(e,t)=>this.stream(`/v1/api/cycles/${e}/stream`,t)};clientInvoices={list:async(e)=>w(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:e??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(e)=>w(await this.raw.GET("/v1/api/client-billing/invoices/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/client-billing/invoices/${e}`)),createDraft:async(e)=>w(await this.raw.POST("/v1/api/client-billing/invoices",{body:e}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(e)=>w(await this.raw.POST("/v1/api/client-billing/invoices/{id}/issue",{params:{path:{id:e}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${e}/issue`)),void:async(e,t)=>w(await this.raw.POST("/v1/api/client-billing/invoices/{id}/void",{params:{path:{id:e}},body:{reason:t}}),this.at("POST",`/v1/api/client-billing/invoices/${e}/void`)),pay:async(e)=>w(await this.raw.POST("/v1/api/client-billing/invoices/{id}/pay",{params:{path:{id:e}},body:{}}),this.at("POST",`/v1/api/client-billing/invoices/${e}/pay`)),paymentLink:async(e,t={})=>w(await this.raw.POST("/v1/api/client-billing/invoices/{id}/payment-link",{params:{path:{id:e}},body:t}),this.at("POST",`/v1/api/client-billing/invoices/${e}/payment-link`))};async*observeAgent(e,t,n){let r=`/v1/api/projects/${e}/agents/${t}/observe`;for await(let s of this.stream(r,n)){let o=Tt(s.data);if(!o)continue;if(yield o,Rt(o))return}}async*stream(e,t){let n=`${this.baseUrl}${e}`,r=new Request(n,{headers:{...this.headers,accept:"text/event-stream"},signal:t?.signal}),s=await globalThis.fetch(r);if(!s.ok||!s.body){let o=null;try{o=await s.json()}catch{o=null}throw ue(s,o,{method:"GET",url:n})}yield*At(s.body,t?.signal)}}function Nt(e){if(e instanceof f)return{code:e.code,status:null};if(e instanceof Oe)return{code:"invalid_request",status:400};if(e instanceof Te)return{code:"bad_request",status:400};if(e instanceof Re)return{code:"unauthenticated",status:401};if(e instanceof Ae)return{code:"forbidden",status:403};if(e instanceof He)return{code:"not_found",status:404};if(e instanceof Fe)return{code:"conflict",status:409};if(e instanceof Ne)return{code:"rate_limited",status:429};if(e instanceof Ue)return{code:"not_implemented",status:501};if(e instanceof Le)return{code:"server_error",status:e.status};if(e instanceof pe)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var Ht=(e)=>e instanceof Error?e.message:String(e);function Fs(e,t){let n=B({env:e,flags:t.flags,cwd:t.cwd});if(n.conflict)throw new f("workspace_mismatch",n.conflict);if(!n.credential)throw new f("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");return new me({baseUrl:n.baseUrl,credential:n.credential.sessionToken?It(n.credential.sessionToken):de(n.credential.apiKey),...n.workspaceId?{organizationId:n.workspaceId}:{}})}function ir(e){let t=Math.max(...e.map((r)=>r.name.length));return`hlix — the hlix control-plane CLI
13
13
 
14
14
  Usage:
15
15
  hlix <command> [options]
@@ -31,17 +31,17 @@ HLIX_* environment, the nearest .hlix/config.json, then the stored credential.
31
31
  Run \`hlix status\` to see which one applied.
32
32
  `}function Ns(e,t){let n=[...Array(t.length+1).keys()];for(let r=1;r<=e.length;r+=1){let s=[r];for(let o=1;o<=t.length;o+=1)s[o]=Math.min(n[o]+1,s[o-1]+1,n[o-1]+(e[r-1]===t[o-1]?0:1));n=s}return n[t.length]}function Us(e,t,n){let r=/Unknown option '--([^'=]+)/.exec(n)?.[1];if(!r)return n;let s=t.findIndex((c)=>c.startsWith("-")),o=s===-1?t:t.slice(0,s),i=new Set(["json","help","version","cwd","workspace","base-url",...Ft(e,o)?.command.options??[]]),a=null;for(let c of i){let l=Ns(r,c);if(l<=2&&(!a||l<a.distance))a={name:c,distance:l}}return a?`${n}
33
33
  Did you mean --${a.name}?`:n}function Ft(e,t){for(let n of[...e].sort((r,s)=>s.name.length-r.name.length)){let r=n.name.split(" ");if(r.every((s,o)=>t[o]===s))return{command:n,rest:t.slice(r.length)}}return null}async function wa(e,t,n){if(t.some((E)=>E==="--api-key"||E.startsWith("--api-key=")))return n.stderr("error: API keys are never accepted as command-line arguments. Run `hlix auth login` and use the hidden prompt.\n"),2;let r;try{r=Hs({args:t,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"},print:{type:"boolean"},web:{type:"boolean"},"env-file":{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"}}})}catch(E){let R=t.includes("--json"),H=Us(e,t,Ht(E));if(R)n.stdout(y(Ee("cli",{code:"invalid_usage",message:H,status:null})));else n.stderr(`${H}
34
- `);return 2}let s=r.values.json===!0,o=r.positionals;if(r.values.version===!0){let{version:E}=await import("./package-f3wbdpaa.js");return n.stdout(`${E}
34
+ `);return 2}let s=r.values.json===!0,o=r.positionals;if(r.values.version===!0){let{version:E}=await import("./package-bkxredkn.js");return n.stdout(`${E}
35
35
  `),0}if(o.length===0||r.values.help===!0){let E=Ft(e,o);return n.stdout(E?`${E.command.usage}
36
36
  `:ir(e)),o.length===0&&r.values.help!==!0?1:0}let i=Ft(e,o);if(!i){let E=o.join(" ");if(s)n.stdout(y(Ee(E,{code:"unknown_command",message:`Unknown command: ${E}`,status:null})));else n.stderr(`Unknown command: ${E}
37
37
 
38
38
  ${ir(e)}`);return 2}let a=new Set(["json","help","version","cwd","workspace","base-url"]),c=new Set(i.command.options??[]),l=Object.entries(r.values).filter(([E,R])=>R!==void 0&&!a.has(E)&&!c.has(E)).map(([E])=>`--${E}`),p=i.command.args??{min:0,max:0},d=i.rest.length<p.min?{code:"missing_argument",message:i.command.usage.split(`
39
39
  `)[0]}:i.rest.length>p.max?{code:"invalid_usage",message:i.command.usage.split(`
40
- `)[0]}:null,u=typeof r.values.cwd==="string"?r.values.cwd:void 0,m=As(u??"."),w=u!==void 0&&!Qn(m)?{code:"invalid_usage",message:`--cwd is not a directory: ${m}`}:null,b=l.length>0?{code:"invalid_usage",message:`Unsupported option for ${i.command.name}: ${l.join(", ")}`}:w??d;if(b){if(s)n.stdout(y(Ee(i.command.name,{...b,status:null})));else n.stderr(`error: ${b.message}
40
+ `)[0]}:null,u=typeof r.values.cwd==="string"?r.values.cwd:void 0,m=As(u??"."),v=u!==void 0&&!Qn(m)?{code:"invalid_usage",message:`--cwd is not a directory: ${m}`}:null,b=l.length>0?{code:"invalid_usage",message:`Unsupported option for ${i.command.name}: ${l.join(", ")}`}:v??d;if(b){if(s)n.stdout(y(Ee(i.command.name,{...b,status:null})));else n.stderr(`error: ${b.message}
41
41
 
42
42
  ${i.command.usage}
43
43
  `);return 2}let T=r.values,D={...n,args:i.rest,json:s,flags:T,cwd:m,requireClient:(E)=>Fs(n.env,{cwd:E??m,flags:T})};try{return await i.command.run(D)}catch(E){let{code:R,status:H}=Nt(E);if(s)n.stdout(y(Ee(i.command.name,{code:R,message:Ht(E),status:H})));else n.stderr(`error: ${Ht(E)}
44
- `);return R==="unauthenticated"||R==="forbidden"?3:1}}import{readFileSync as Ls}from"node:fs";import{homedir as Ms}from"node:os";import{join as Bs}from"node:path";var ar=["cloud","docker","local"],fe=["claude-code","codex","cursor-agent","hlix"],Ia="hlix",cr={harness:"local and docker sandboxes only",model:"all sandboxes",sandbox:"all sandboxes"},ge=["harness","model","sandbox"],Ut=["projectId","workspaceId","apiUrl"];function Lt(e=process.env){return Bs(e.HLIX_CONFIG_HOME??Ms(),".hlix","config.json")}function lr(e=process.env){try{let t=JSON.parse(Ls(Lt(e),"utf8"));return t.schemaVersion===1?t:null}catch{return null}}function Mt(e,t=process.env){let n=lr(t),r=O(e),s=r?.root??null,o=r?.config??null,i={},a={},c=(l)=>{let p=o?.[l],d=n?.[l];if(p!==void 0)i[l]=p,a[l]="project";else if(d!==void 0)i[l]=d,a[l]="global"};for(let l of ge)c(l);for(let l of Ut){let p=o?.[l];if(p!==void 0)i[l]=p,a[l]="project"}return{merged:i,sources:a,global:n,project:o,paths:{global:Lt(t),project:s?Ie(s):null}}}function dr(e){return[...ge,...Ut].map((n)=>({key:n,value:e.merged[n]??null,source:e.sources[n]??"default"}))}function Ks(e,t){if(e==="sandbox"&&!ar.includes(t))return`sandbox must be one of ${ar.join(", ")}; got "${t}".`;if(e==="harness"&&!fe.includes(t))return`harness must be one of ${fe.join(", ")}; got "${t}".`;if(e==="model"&&t.trim()==="")return"model must not be empty.";return null}function Bt(e){if(ge.includes(e))return e;let t=Ut.includes(e);throw new f("invalid_usage",t?`${e} is written by \`hlix init\` and \`hlix import\`, not by \`hlix config set\`.`:`Unknown setting: ${e}. Known settings: ${ge.join(", ")}.`)}function pr(e,t){let n=Ks(e,t);if(n)throw new f("invalid_usage",n);return t}function ur(e){if(e.scope==="global"){let r=Lt(e.env),s=lr(e.env)??{schemaVersion:1};return $e(r,{...s,[e.key]:e.value}),r}let t=O(e.cwd);if(!t)throw new f("not_initialized","This folder is not bound to hlix. Run `hlix init` here, or set it machine-wide with --global.");let n=Ie(t.root);return $e(n,{...t.config,[e.key]:e.value}),n}async function zs(e,t,n){let r=t.map((a)=>a.id);if(n){if(!r.includes(n))throw new f("workspace_mismatch",t.length===0?`This key belongs to a user who is not a member of any workspace, including ${n}.`:`This key cannot act in workspace ${n}. Available: ${r.join(", ")}.`);return n}if(t.length===0)throw new f("workspace_required","This key belongs to a user who is not a member of any workspace. Create or join one first.");let s=t[0];if(s&&t.length===1)return e.stderr(`Using your only workspace: ${s.name} (${s.id})
44
+ `);return R==="unauthenticated"||R==="forbidden"?3:1}}import{readFileSync as Ls}from"node:fs";import{homedir as Ms}from"node:os";import{join as Bs}from"node:path";var ar=["cloud","docker","local"],fe=["claude-code","codex","cursor-agent","hlix"],Ia="hlix",cr={harness:"local and docker sandboxes only",model:"local and docker sandboxes only",sandbox:"all sandboxes"},ge=["harness","model","sandbox"],Ut=["projectId","workspaceId","apiUrl"];function Lt(e=process.env){return Bs(e.HLIX_CONFIG_HOME??Ms(),".hlix","config.json")}function lr(e=process.env){try{let t=JSON.parse(Ls(Lt(e),"utf8"));return t.schemaVersion===1?t:null}catch{return null}}function Mt(e,t=process.env){let n=lr(t),r=O(e),s=r?.root??null,o=r?.config??null,i={},a={},c=(l)=>{let p=o?.[l],d=n?.[l];if(p!==void 0)i[l]=p,a[l]="project";else if(d!==void 0)i[l]=d,a[l]="global"};for(let l of ge)c(l);for(let l of Ut){let p=o?.[l];if(p!==void 0)i[l]=p,a[l]="project"}return{merged:i,sources:a,global:n,project:o,paths:{global:Lt(t),project:s?Ie(s):null}}}function dr(e){return[...ge,...Ut].map((n)=>({key:n,value:e.merged[n]??null,source:e.sources[n]??"default"}))}function Ks(e,t){if(e==="sandbox"&&!ar.includes(t))return`sandbox must be one of ${ar.join(", ")}; got "${t}".`;if(e==="harness"&&!fe.includes(t))return`harness must be one of ${fe.join(", ")}; got "${t}".`;if(e==="model"&&t.trim()==="")return"model must not be empty.";return null}function Bt(e){if(ge.includes(e))return e;let t=Ut.includes(e);throw new f("invalid_usage",t?`${e} is written by \`hlix init\` and \`hlix import\`, not by \`hlix config set\`.`:`Unknown setting: ${e}. Known settings: ${ge.join(", ")}.`)}function pr(e,t){let n=Ks(e,t);if(n)throw new f("invalid_usage",n);return t}function ur(e){if(e.scope==="global"){let r=Lt(e.env),s=lr(e.env)??{schemaVersion:1};return $e(r,{...s,[e.key]:e.value}),r}let t=O(e.cwd);if(!t)throw new f("not_initialized","This folder is not bound to hlix. Run `hlix init` here, or set it machine-wide with --global.");let n=Ie(t.root);return $e(n,{...t.config,[e.key]:e.value}),n}async function zs(e,t,n){let r=t.map((a)=>a.id);if(n){if(!r.includes(n))throw new f("workspace_mismatch",t.length===0?`This key belongs to a user who is not a member of any workspace, including ${n}.`:`This key cannot act in workspace ${n}. Available: ${r.join(", ")}.`);return n}if(t.length===0)throw new f("workspace_required","This key belongs to a user who is not a member of any workspace. Create or join one first.");let s=t[0];if(s&&t.length===1)return e.stderr(`Using your only workspace: ${s.name} (${s.id})
45
45
  `),s.id;if(e.json||!e.promptChoice)throw new f("missing_argument",`--workspace is required here: this key can act in ${t.length} workspaces. Pass one of: ${r.join(", ")}.`);let o=Math.max(...t.map((a)=>a.name.length));e.stderr(`${t.map((a,c)=>` ${c+1}) ${a.name.padEnd(o)} ${a.slug} ${a.role} ${a.id}`).join(`
46
46
  `)}
47
47
  `);let i=await e.promptChoice(`Workspace [1-${t.length}]: `,t.length);return r[i]}var Kt={name:"auth login",summary:"Verify and store a credential for this machine",usage:["Usage: hlix auth login [--workspace <id>] [--base-url <url>]",""," --base-url Defaults to https://server.hlix.ai"," --workspace Workspace (organization) id to act in. Optional: the key's"," own workspaces are listed after it is read, and the only"," one is taken automatically.","","The API key is read from a hidden prompt and never accepted as an argument.","For CI, set HLIX_API_KEY and HLIX_WORKSPACE_ID in the environment."].join(`
@@ -82,9 +82,9 @@ global ${t.paths.global}
82
82
  `),supportsJson:!0,args:{min:1,max:1},async run(e){let t=Vt(e,"task"),n=e.requireClient();for await(let r of n.tasks.stream(t)){let s;try{s=JSON.parse(r.data)}catch{s=r.data}if(e.json)e.stdout(`${JSON.stringify(k(Qt.name,s))}
83
83
  `);else{let o=K(s,"status"),i=K(s,"error");e.stdout(i?`error: ${i}
84
84
  `:`${o||r.data}
85
- `)}}return 0}};import{realpath as Po}from"node:fs/promises";import{resolve as Co}from"node:path";import{createHash as Pr}from"node:crypto";import{createReadStream as Vs}from"node:fs";import{lstat as Cr,readFile as at,readdir as Xs,realpath as $r,stat as Ys}from"node:fs/promises";import{basename as se,join as Ir,relative as kr,resolve as br,sep as Zs}from"node:path";import{spawnSync as Qs}from"node:child_process";import Sr from"ignore";import{readFile as Ds}from"node:fs/promises";import{join as Js}from"node:path";function qs(e){let t=e.trim();if(!t||/^[|>[{]/.test(t))return null;let n=t.match(/^(["'])([\s\S]*)\1$/);if(!n&&/^["']/.test(t))return null;return(n?n[2].trim():t.replace(/(?:^|\s)#.*$/,"").trim())||null}function gr(e){let t=e.split(/\r?\n/),n=t.findIndex((i)=>/^tasks:\s*(?:#.*)?$/.test(i));if(n===-1)return{tasks:[],partial:/^tasks:\s*\S/m.test(e)};let r=[],s=!1,o=-1;for(let i of t.slice(n+1)){if(!i.trim()||/^\s*#/.test(i))continue;let a=i.length-i.trimStart().length,c=i.match(/^(\s*-(?:\s+|$))(.*)$/);if(c){if(o!==-1&&a>=o)continue;if(r.push({}),o=c[2]?c[1].length:-1,!c[2])continue}else if(a===0)break;else if(r.length===0)continue;else if(o===-1)o=a;else if(a!==o)continue;let l=(c?c[2]:i.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!l)continue;let p=l[1];if(p!=="name"&&p!=="before"&&p!=="init"&&p!=="command")continue;let d=qs(l[2]);if(d===null)s=!0;else r[r.length-1][p]=d}return{tasks:r,partial:s}}async function re(e,t){try{return await Ds(Js(e,...t.split("/")),"utf8")}catch(n){if(n.code==="ENOENT")return null;throw n}}function hr(e){try{let t=e.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(t)}catch{return null}}function Q(e){if(typeof e==="string"&&e.trim())return[e.trim()];if(Array.isArray(e))return e.flatMap(Q);if(e&&typeof e==="object")return Object.values(e).flatMap(Q);return[]}function en(e){if(!e||typeof e!=="object")return[];return Object.keys(e).filter((t)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))}function Gs(e,t){let n=new Set,r=[/\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(t)r.push(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::[-?][^}]*)?\}/g);for(let s of r)for(let o of e.matchAll(s))n.add(o[1]);return[...n]}function Ws(e,t){if(e.has("bun.lock")||e.has("bun.lockb")||t?.startsWith("bun@"))return"bun install --frozen-lockfile";if(e.has("pnpm-lock.yaml")||t?.startsWith("pnpm@"))return"pnpm install --frozen-lockfile";if(e.has("yarn.lock")||t?.startsWith("yarn@"))return"yarn install --immutable";if(e.has("package-lock.json")||e.has("npm-shrinkwrap.json"))return"npm ci";if(e.has("package.json"))return"npm install";return null}function yr(e){let t=typeof e==="number"?e:Number(e);return Number.isInteger(t)&&t>0&&t<=65535?t:null}function L(e,t,n){if(!e.some((r)=>r.path===t&&r.kind===n))e.push({path:t,kind:n})}async function wr(e,t,n){let r=[],s=[],o=[],i=[],a=new Map,c=new Set,l=new Set,p=[],d={},u=null,m=0,w=await re(e,".cursor/environment.json");if(w){L(r,".cursor/environment.json","cursor");let g=hr(w);if(!g)p.push("Could not parse .cursor/environment.json; it remains quarantined.");else{s.push(...Q(g.install));let P=Q(g.start);if(P[0])u=P[0];if(Array.isArray(g.terminals))for(let S of g.terminals){if(!S||typeof S!=="object")continue;let I=S;if(typeof I.command!=="string"||!I.command.trim())continue;i.push({name:typeof I.name==="string"&&I.name.trim()?I.name.trim():"Terminal",command:I.command.trim(),...typeof I.cwd==="string"&&I.cwd.trim()?{cwd:I.cwd.trim()}:{}})}}}let b=t.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":t.has("devcontainer.json")?"devcontainer.json":null;if(b){L(r,b,"devcontainer");let g=hr(n.get(b)??await re(e,b)??"");if(!g)p.push(`Could not parse ${b}; it remains quarantined.`);else{s.push(...Q(g.onCreateCommand),...Q(g.updateContentCommand),...Q(g.postCreateCommand));let P=Q(g.postStartCommand);if(!u&&P[0])u=P[0];for(let S of en(g.secrets))c.add(S);for(let S of[...en(g.containerEnv),...en(g.remoteEnv)])c.add(S);if(Array.isArray(g.forwardPorts))for(let S of g.forwardPorts){let I=yr(S);if(I)a.set(I,{port:I,visibility:"private"})}}}if(t.has(".gitpod.yml")){L(r,".gitpod.yml","gitpod");let g=n.get(".gitpod.yml")??await re(e,".gitpod.yml");if(g===null)p.push("Could not read .gitpod.yml; its task commands were not imported.");else{let P=gr(g);m=P.tasks.filter((S)=>S.before).length;for(let S of P.tasks){if(S.before)s.push(S.before);if(S.init)s.push(S.init);if(!S.command)continue;if(!u)u=S.command;else i.push({name:S.name??"Terminal",command:S.command})}if(P.partial)p.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 g of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(t.has(g))L(r,g,"docker");for(let g of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(t.has(g))L(r,g,"buildpack");for(let g of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(t.has(g))L(r,g,"platform");let T=n.get("package.json")??await re(e,"package.json");if(T){L(r,"package.json","package");try{let g=JSON.parse(T);if(g.engines?.node)d.node=g.engines.node;let P=Ws(t,g.packageManager);if(P&&s.length===m)s.push(P);if(g.scripts?.build&&o.length===0)o.push(`${g.packageManager?.split("@")[0]??(t.has("bun.lock")?"bun":"npm")} run build`);let S=g.scripts?.dev?`${t.has("bun.lock")?"bun":"npm"} run dev`:null,I=g.scripts?.start?`${t.has("bun.lock")?"bun":"npm"} run start`:S;if(!u&&I)u=I}catch{p.push("Could not parse package.json for environment discovery.")}}if(t.has("uv.lock"))s.push("uv sync --frozen");else if(t.has("poetry.lock"))s.push("poetry install --no-interaction");else if(t.has("requirements.txt"))s.push("python -m pip install -r requirements.txt");if(t.has("go.mod"))s.push("go mod download");if(t.has("Procfile")){L(r,"Procfile","procfile");let P=(n.get("Procfile")??"").split(/\r?\n/).find((S)=>/^web\s*:/.test(S));if(P)u=P.replace(/^web\s*:\s*/,"").trim()||u}let D=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[g,P]of D){let S=(n.get(g)??await re(e,g))?.trim();if(S)d[P]=S,L(r,g,"tool-version")}let E=n.get(".tool-versions")??await re(e,".tool-versions");if(E){L(r,".tool-versions","tool-version");for(let g of E.split(/\r?\n/)){let[P,S]=g.trim().split(/\s+/,2);if(!S)continue;if(P==="nodejs")d.node=S;else if(P==="python")d.python=S;else if(P==="bun")d.bun=S}}let R=n.get("mise.toml")??await re(e,"mise.toml");if(R){L(r,"mise.toml","tool-version");for(let g of R.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))d[g[1]]=g[2]}for(let[g,P]of n){let S=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(g)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(g);for(let I of Gs(P,S))l.add(I);for(let I of P.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let z=yr(I[1]);if(z)a.set(z,{port:z,visibility:"private"})}}if(r.length===0&&t.size>0)L(r,"repository","detected");let H=(g)=>[...new Set(g.filter(Boolean))],ke=r.length+s.length+(u?1:0);return{sources:r.sort((g,P)=>g.path.localeCompare(P.path)),toolchain:d,install:H(s),build:H(o),start:u,terminals:i,ports:[...a.values()].sort((g,P)=>g.port-P.port),requiredSecretKeys:[...c].sort(),observedSecretKeys:[...l].sort(),confidence:ke>=4?"high":ke>=2?"medium":"low",warnings:p}}var vr=2;var eo=25000,to=52428800,no=524288000,ct=1e4,it=1048576,ye=10485760,jr=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store"],rn="Required project environment value was not found locally: ",ro=/(^|\/)\.env\.(example|sample|template)$/i,so=/(^|\/)\.env(?:\.[^/]+)?$/i,oo=/(^|\/)(?:\.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,io=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,ao=/(^|\/)(?:AGENTS\.md|CLAUDE\.md|\.cursorrules|\.github\/copilot-instructions\.md)$/i,co=/(^|\/)(?:\.agents|\.claude)\/skills\//i,lo=/-----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,}/,po=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,uo=/(?:^|[,{\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,Be=/^HLIX_[A-Za-z0-9_]*$/,tn=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]);function Ke(e){return e.split(Zs).join("/")}function ee(e,t,n=10485760){return Qs("git",["-C",e,...t],{encoding:"utf8",maxBuffer:n,stdio:["ignore","pipe","pipe"]})}async function mo(e){let t=Pr("sha256");for await(let n of Vs(e))t.update(n);return t.digest("hex")}function nn(e){if(Array.isArray(e))return`[${e.map(nn).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${nn(n)}`).join(",")}}`;return JSON.stringify(e)}function xr(e){let t={};for(let[n,r]of String(e).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let s=r.trim();if(!s||s.startsWith("#"))continue;let i=(s.startsWith("export ")?s.slice(7).trimStart():s).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!i)throw Error(`Invalid dotenv assignment on line ${n+1}`);let a=i[2]??"";if(a.startsWith('"')){if(!a.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${n+1}`);a=a.slice(1,-1).replace(/\\n/g,`
85
+ `)}}return 0}};import{realpath as Po}from"node:fs/promises";import{resolve as Co}from"node:path";import{createHash as Pr}from"node:crypto";import{createReadStream as Vs}from"node:fs";import{lstat as Cr,readFile as at,readdir as Xs,realpath as $r,stat as Ys}from"node:fs/promises";import{basename as se,join as Ir,relative as kr,resolve as br,sep as Zs}from"node:path";import{spawnSync as Qs}from"node:child_process";import Sr from"ignore";import{readFile as Ds}from"node:fs/promises";import{join as Js}from"node:path";function qs(e){let t=e.trim();if(!t||/^[|>[{]/.test(t))return null;let n=t.match(/^(["'])([\s\S]*)\1$/);if(!n&&/^["']/.test(t))return null;return(n?n[2].trim():t.replace(/(?:^|\s)#.*$/,"").trim())||null}function gr(e){let t=e.split(/\r?\n/),n=t.findIndex((i)=>/^tasks:\s*(?:#.*)?$/.test(i));if(n===-1)return{tasks:[],partial:/^tasks:\s*\S/m.test(e)};let r=[],s=!1,o=-1;for(let i of t.slice(n+1)){if(!i.trim()||/^\s*#/.test(i))continue;let a=i.length-i.trimStart().length,c=i.match(/^(\s*-(?:\s+|$))(.*)$/);if(c){if(o!==-1&&a>=o)continue;if(r.push({}),o=c[2]?c[1].length:-1,!c[2])continue}else if(a===0)break;else if(r.length===0)continue;else if(o===-1)o=a;else if(a!==o)continue;let l=(c?c[2]:i.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!l)continue;let p=l[1];if(p!=="name"&&p!=="before"&&p!=="init"&&p!=="command")continue;let d=qs(l[2]);if(d===null)s=!0;else r[r.length-1][p]=d}return{tasks:r,partial:s}}async function re(e,t){try{return await Ds(Js(e,...t.split("/")),"utf8")}catch(n){if(n.code==="ENOENT")return null;throw n}}function hr(e){try{let t=e.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(t)}catch{return null}}function Q(e){if(typeof e==="string"&&e.trim())return[e.trim()];if(Array.isArray(e))return e.flatMap(Q);if(e&&typeof e==="object")return Object.values(e).flatMap(Q);return[]}function en(e){if(!e||typeof e!=="object")return[];return Object.keys(e).filter((t)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))}function Gs(e,t){let n=new Set,r=[/\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(t)r.push(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::[-?][^}]*)?\}/g);for(let s of r)for(let o of e.matchAll(s))n.add(o[1]);return[...n]}function Ws(e,t){if(e.has("bun.lock")||e.has("bun.lockb")||t?.startsWith("bun@"))return"bun install --frozen-lockfile";if(e.has("pnpm-lock.yaml")||t?.startsWith("pnpm@"))return"pnpm install --frozen-lockfile";if(e.has("yarn.lock")||t?.startsWith("yarn@"))return"yarn install --immutable";if(e.has("package-lock.json")||e.has("npm-shrinkwrap.json"))return"npm ci";if(e.has("package.json"))return"npm install";return null}function yr(e){let t=typeof e==="number"?e:Number(e);return Number.isInteger(t)&&t>0&&t<=65535?t:null}function L(e,t,n){if(!e.some((r)=>r.path===t&&r.kind===n))e.push({path:t,kind:n})}async function wr(e,t,n){let r=[],s=[],o=[],i=[],a=new Map,c=new Set,l=new Set,p=[],d={},u=null,m=0,v=await re(e,".cursor/environment.json");if(v){L(r,".cursor/environment.json","cursor");let g=hr(v);if(!g)p.push("Could not parse .cursor/environment.json; it remains quarantined.");else{s.push(...Q(g.install));let P=Q(g.start);if(P[0])u=P[0];if(Array.isArray(g.terminals))for(let S of g.terminals){if(!S||typeof S!=="object")continue;let I=S;if(typeof I.command!=="string"||!I.command.trim())continue;i.push({name:typeof I.name==="string"&&I.name.trim()?I.name.trim():"Terminal",command:I.command.trim(),...typeof I.cwd==="string"&&I.cwd.trim()?{cwd:I.cwd.trim()}:{}})}}}let b=t.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":t.has("devcontainer.json")?"devcontainer.json":null;if(b){L(r,b,"devcontainer");let g=hr(n.get(b)??await re(e,b)??"");if(!g)p.push(`Could not parse ${b}; it remains quarantined.`);else{s.push(...Q(g.onCreateCommand),...Q(g.updateContentCommand),...Q(g.postCreateCommand));let P=Q(g.postStartCommand);if(!u&&P[0])u=P[0];for(let S of en(g.secrets))c.add(S);for(let S of[...en(g.containerEnv),...en(g.remoteEnv)])c.add(S);if(Array.isArray(g.forwardPorts))for(let S of g.forwardPorts){let I=yr(S);if(I)a.set(I,{port:I,visibility:"private"})}}}if(t.has(".gitpod.yml")){L(r,".gitpod.yml","gitpod");let g=n.get(".gitpod.yml")??await re(e,".gitpod.yml");if(g===null)p.push("Could not read .gitpod.yml; its task commands were not imported.");else{let P=gr(g);m=P.tasks.filter((S)=>S.before).length;for(let S of P.tasks){if(S.before)s.push(S.before);if(S.init)s.push(S.init);if(!S.command)continue;if(!u)u=S.command;else i.push({name:S.name??"Terminal",command:S.command})}if(P.partial)p.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 g of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(t.has(g))L(r,g,"docker");for(let g of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(t.has(g))L(r,g,"buildpack");for(let g of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(t.has(g))L(r,g,"platform");let T=n.get("package.json")??await re(e,"package.json");if(T){L(r,"package.json","package");try{let g=JSON.parse(T);if(g.engines?.node)d.node=g.engines.node;let P=Ws(t,g.packageManager);if(P&&s.length===m)s.push(P);if(g.scripts?.build&&o.length===0)o.push(`${g.packageManager?.split("@")[0]??(t.has("bun.lock")?"bun":"npm")} run build`);let S=g.scripts?.dev?`${t.has("bun.lock")?"bun":"npm"} run dev`:null,I=g.scripts?.start?`${t.has("bun.lock")?"bun":"npm"} run start`:S;if(!u&&I)u=I}catch{p.push("Could not parse package.json for environment discovery.")}}if(t.has("uv.lock"))s.push("uv sync --frozen");else if(t.has("poetry.lock"))s.push("poetry install --no-interaction");else if(t.has("requirements.txt"))s.push("python -m pip install -r requirements.txt");if(t.has("go.mod"))s.push("go mod download");if(t.has("Procfile")){L(r,"Procfile","procfile");let P=(n.get("Procfile")??"").split(/\r?\n/).find((S)=>/^web\s*:/.test(S));if(P)u=P.replace(/^web\s*:\s*/,"").trim()||u}let D=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[g,P]of D){let S=(n.get(g)??await re(e,g))?.trim();if(S)d[P]=S,L(r,g,"tool-version")}let E=n.get(".tool-versions")??await re(e,".tool-versions");if(E){L(r,".tool-versions","tool-version");for(let g of E.split(/\r?\n/)){let[P,S]=g.trim().split(/\s+/,2);if(!S)continue;if(P==="nodejs")d.node=S;else if(P==="python")d.python=S;else if(P==="bun")d.bun=S}}let R=n.get("mise.toml")??await re(e,"mise.toml");if(R){L(r,"mise.toml","tool-version");for(let g of R.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))d[g[1]]=g[2]}for(let[g,P]of n){let S=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(g)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(g);for(let I of Gs(P,S))l.add(I);for(let I of P.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let z=yr(I[1]);if(z)a.set(z,{port:z,visibility:"private"})}}if(r.length===0&&t.size>0)L(r,"repository","detected");let H=(g)=>[...new Set(g.filter(Boolean))],ke=r.length+s.length+(u?1:0);return{sources:r.sort((g,P)=>g.path.localeCompare(P.path)),toolchain:d,install:H(s),build:H(o),start:u,terminals:i,ports:[...a.values()].sort((g,P)=>g.port-P.port),requiredSecretKeys:[...c].sort(),observedSecretKeys:[...l].sort(),confidence:ke>=4?"high":ke>=2?"medium":"low",warnings:p}}var vr=2;var eo=25000,to=52428800,no=524288000,ct=1e4,it=1048576,ye=10485760,jr=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store"],rn="Required project environment value was not found locally: ",ro=/(^|\/)\.env\.(example|sample|template)$/i,so=/(^|\/)\.env(?:\.[^/]+)?$/i,oo=/(^|\/)(?:\.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,io=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,ao=/(^|\/)(?:AGENTS\.md|CLAUDE\.md|\.cursorrules|\.github\/copilot-instructions\.md)$/i,co=/(^|\/)(?:\.agents|\.claude)\/skills\//i,lo=/-----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,}/,po=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,uo=/(?:^|[,{\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,Be=/^HLIX_[A-Za-z0-9_]*$/,tn=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]);function Ke(e){return e.split(Zs).join("/")}function ee(e,t,n=10485760){return Qs("git",["-C",e,...t],{encoding:"utf8",maxBuffer:n,stdio:["ignore","pipe","pipe"]})}async function mo(e){let t=Pr("sha256");for await(let n of Vs(e))t.update(n);return t.digest("hex")}function nn(e){if(Array.isArray(e))return`[${e.map(nn).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${nn(n)}`).join(",")}}`;return JSON.stringify(e)}function xr(e){let t={};for(let[n,r]of String(e).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let s=r.trim();if(!s||s.startsWith("#"))continue;let i=(s.startsWith("export ")?s.slice(7).trimStart():s).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!i)throw Error(`Invalid dotenv assignment on line ${n+1}`);let a=i[2]??"";if(a.startsWith('"')){if(!a.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${n+1}`);a=a.slice(1,-1).replace(/\\n/g,`
86
86
  `).replace(/\\r/g,"\r")}else if(a.startsWith("'")){if(!a.endsWith("'"))throw Error(`Unclosed dotenv quote on line ${n+1}`);a=a.slice(1,-1)}else a=a.replace(/\s+#.*$/,"").trimEnd();t[i[1]]=a}return t}function fo(e){let t=null;for(let n=0;n<e.length;n+=1){let r=e[n];if(r==="\\"&&t!=="single"){if(e[n+1]!=="$")return!0;n+=1;continue}if(r==="'"&&t!=="double"){t=t==="single"?null:"single";continue}if(r==='"'&&t!=="single"){t=t==="double"?null:"double";continue}if(t!=="single"&&(r==="$"||r==="`"))return!0;if(t===null&&(r==="<"||r===">")&&e[n+1]==="(")return!0}return t!==null}function go(e){let t={},n=new Set,r=new Set;for(let s of String(e).replace(/^\uFEFF/,"").split(/\r?\n/)){let o=s.trim();if(!o||o.startsWith("#"))continue;let a=(o.startsWith("export ")?o.slice(7).trimStart():o).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!a)continue;let c=a[1],l=a[2]??"";if(n.add(c),fo(l)){delete t[c],r.add(c);continue}try{let d=xr(`${c}=${l}`)[c];if(d===void 0)throw Error("missing literal");t[c]=l.trimStart().startsWith("'")?d:d.replace(/\\\$/g,"$"),r.delete(c)}catch{delete t[c],r.add(c)}}return{values:t,keys:[...n].sort(),dynamicKeys:[...r].sort()}}async function ho(e){let t=ee(e,["rev-parse","--show-toplevel"]);if(t.status!==0)return!1;try{return await $r(t.stdout.trim())===e}catch{return!1}}function yo(e,t){if(!t)return new Set;let n=ee(e,["ls-files","-z"]);if(n.status!==0)throw Error("Could not enumerate tracked files.");return new Set(n.stdout.split("\x00").filter(Boolean).map(Ke))}async function wo(e){let t=Sr().add(jr),n=Sr().add(jr);for(let r of[".gitignore",".hlixignore"])try{let s=Ir(e,r);if((await Cr(s)).isFile())n.add(await at(s,"utf8"))}catch(s){if(s.code!=="ENOENT")throw s}return{hardMatcher:t,matcher:n}}function vo(e){if(io.test(e))return"mcp";if(co.test(e))return"skill";if(ao.test(e))return"agent";return null}function ko(e){if(so.test(e)&&!ro.test(e))return"dotenv";if(oo.test(e))return"credential";return null}function bo(e){if(e.has("package.json"))return"typescript";if(e.has("pyproject.toml")||e.has("requirements.txt"))return"python";if(e.has("go.mod"))return"go";if(e.has("Cargo.toml"))return"rust";if(e.has("composer.json"))return"php";if(e.has("Gemfile"))return"ruby";return"other"}function So(e,t){if(t)return[Ke(t)];let n=new Map([[".env",0],[".env.development",1],[".env.local",2],[".env.development.local",3]]),r=e.filter((s)=>n.has(se(s).toLocaleLowerCase("en-US"))).sort((s,o)=>s.slice(0,-se(s).length).localeCompare(o.slice(0,-se(o).length))||n.get(se(s).toLocaleLowerCase("en-US"))-n.get(se(o).toLocaleLowerCase("en-US")));return r.length>0?r:e.length===1?[...e]:[]}function jo(e,t){try{let n=JSON.parse(t);if(!n.mcpServers||typeof n.mcpServers!=="object")return[];return Object.entries(n.mcpServers).map(([r,s])=>{let o=s&&typeof s==="object"?s:{},i=o.type==="http"||o.type==="sse"||o.type==="stdio"?o.type:typeof o.command==="string"?"stdio":typeof o.url==="string"?"http":"unknown",a=o.env&&typeof o.env==="object"?o.env:{};return{sourcePath:e,name:r,transport:i,...typeof o.command==="string"?{command:o.command}:{},...Array.isArray(o.args)&&o.args.every((c)=>typeof c==="string")?{args:o.args}:{},...typeof o.url==="string"?{url:o.url}:{},envKeys:Object.keys(a).sort(),enabled:!1}})}catch{return[]}}function Er(e,t){let n=[],r="unknown";for(let s of e.split(/\r?\n/)){if(s.startsWith("@@"))r=s.slice(2);else if(s.trim())n.push({commit:r,path:Ke(s.trim()),reason:t});if(n.length>=100)break}return n}function Eo(e,t){if(!t)return{head:null,branch:null,refs:[],commitCount:0,complete:!0,findings:[]};let n=ee(e,["rev-parse","HEAD"]).stdout.trim()||null,r=ee(e,["symbolic-ref","--short","-q","HEAD"]),s=r.status===0?r.stdout.trim()||null:null,o=Number.parseInt(ee(e,["rev-list","--count","--all"]).stdout.trim(),10)||0,i=ee(e,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]),a=i.stdout.split(`
87
- `).filter(Boolean).map((u)=>{let[m,w]=u.split("\x00");return{name:m,oid:w}}).filter(({name:u,oid:m})=>/^refs\/(?:heads|tags)\/.+/.test(u)&&/^[0-9a-f]{40,64}$/.test(m)).sort((u,m)=>u.name.localeCompare(m.name)),c=["log","--all",`--max-count=${ct}`,"--pretty=format:@@%H","--name-only"],l=ee(e,[...c,"--",".env",".env.*","*.pem","*.key",".npmrc","*.tfvars"]),p=ee(e,["log","--all",`--max-count=${ct}`,"-G","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,}","--pretty=format:@@%H","--name-only"]),d=new Map;for(let u of[...Er(l.stdout,"sensitive-path"),...Er(p.stdout,"secret-pattern")])d.set(`${u.commit}:${u.path}:${u.reason}`,u);return{head:n,branch:s,refs:a,commitCount:o,complete:o<=ct&&a.length<=1000&&i.status===0&&l.status===0&&p.status===0,findings:[...d.values()].slice(0,100)}}async function q(e,t={}){let n=await $r(br(e));if(!(await Ys(n)).isDirectory())throw Error("Import target must be a directory.");let r=await ho(n),s=yo(n,r),{hardMatcher:o,matcher:i}=await wo(n),a=[],c=[],l=[],p=[],d=[],u=[],m=t.envFile?Ke(kr(n,br(n,t.envFile))):void 0,w=m!==void 0&&m!==""&&m!==".."&&!m.startsWith("../");if(t.envFile&&!w)u.push(`Selected environment file must stay inside the project: ${t.envFile}`);let b=new Map,T=new Map,D=new Map,E=new Map,R=[],H=[],ke=new Map,g=t.maxFiles??eo,P=t.maxFileBytes??to,S=t.maxTotalBytes??no,I=0,z=0,An=async(h)=>{let j=await Xs(h,{withFileTypes:!0});j.sort((x,F)=>x.name.localeCompare(F.name));for(let x of j){let F=Ir(h,x.name),C=Ke(kr(n,F));if(x.name===".git"){if(C!==".git")u.push(`Nested Git repository is not supported: ${C}`);continue}let M=await Cr(F),Un=x.isDirectory()?`${C}/`:C,kt=s.has(C),Ln=!kt&&i.ignores(Un),rs=!kt&&o.ignores(Un);if(M.isSymbolicLink()){if(d.push({path:C,reason:"symlink"}),!Ln)u.push(`Symlinks are not imported in this release: ${C}`);continue}if(x.isDirectory()){if(rs)continue;await An(F);continue}let Se=vo(C),je=ko(C);if(Ln&&!Se&&!je)continue;if(!x.isFile()){d.push({path:C,reason:"non-regular-file"});continue}if(a.length+c.length+l.length>=g){u.push(`Project exceeds the ${g} file limit.`);return}if(M.size>P){u.push(`File exceeds the ${P} byte limit: ${C}`);continue}if(I+=M.size,I>S){u.push(`Project exceeds the ${S} byte total limit.`);return}let Ye=await mo(F);if(Se){if(M.size>it){u.push(`Protected configuration exceeds the ${it} byte limit: ${C}`);continue}let N=await at(F);if(z+=N.byteLength,z>ye){u.push(`Protected project files exceed the ${ye} byte total limit.`);continue}if(l.push({path:C,kind:Se,size:M.size,sha256:Ye}),H.push({path:C,kind:Se,contentBase64:N.toString("base64")}),Se==="mcp")p.push(...jo(C,N.toString("utf8")));continue}if(je){if(M.size>it){u.push(`Protected file exceeds the ${it} byte limit: ${C}`);continue}let N=await at(F);if(z+=N.byteLength,z>ye){u.push(`Protected project files exceed the ${ye} byte total limit.`);continue}let te=[];if(je==="dotenv")try{let Ze=xr(N),ie={};for(let[Z,ae]of Object.entries(Ze)){if(Be.test(Z)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${Z}`);continue}ie[Z]=ae}b.set(C,ie),te=Object.keys(ie).sort()}catch{u.push(`Could not parse environment file: ${C}`)}else if(se(C)===".envrc"){let Ze=go(N),ie={},Z=new Set,ae=[];for(let[A,ss]of Object.entries(Ze.values)){if(Be.test(A)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${A}`);continue}if(tn.has(A)){R.push(`Ignored ambient runtime assignment in ${C}: ${A}`);continue}Z.add(A),ie[A]=ss}T.set(C,ie);for(let A of Ze.dynamicKeys){if(Be.test(A)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${A}`);continue}if(tn.has(A)){R.push(`Ignored ambient runtime assignment in ${C}: ${A}`);continue}Z.add(A),ae.push(A)}if(D.set(C,[...Z].sort()),E.set(C,ae.sort()),te=[...Z].sort(),ae.length>0)R.push(`Did not execute dynamic .envrc assignments; collect their resolved local values when available: ${ae.join(", ")}`)}c.push({path:C,kind:je,keys:te,size:M.size,sha256:Ye}),H.push({path:C,kind:je,contentBase64:N.toString("base64")});continue}if(M.size<=1048576){let N=await at(F),te=N.toString("utf8");if(ke.set(C,te),lo.test(te)||po.test(C)&&uo.test(te)){if(z+=N.byteLength,z>ye){u.push(`Protected project files exceed the ${ye} byte total limit.`);continue}c.push({path:C,kind:"detected-content",keys:[],size:M.size,sha256:Ye}),H.push({path:C,kind:"detected-content",contentBase64:N.toString("base64")});continue}}a.push({path:C,size:M.size,sha256:Ye,tracked:kt,executable:(M.mode&73)!==0})}};await An(n),a.sort((h,j)=>h.path.localeCompare(j.path)),c.sort((h,j)=>h.path.localeCompare(j.path)),l.sort((h,j)=>h.path.localeCompare(j.path)),p.sort((h,j)=>`${h.sourcePath}:${h.name}`.localeCompare(`${j.sourcePath}:${j.name}`));let ht=So([...b.keys()].sort(),w?m:void 0);if(t.envFile&&w&&!b.has(ht[0]))u.push(`Selected environment file was not found or is not a dotenv file: ${t.envFile}`);let be=new Map;for(let[h,j]of b)for(let x of Object.keys(j))be.set(x,[...be.get(x)??[],h]);for(let[h,j]of D)for(let x of j)be.set(x,[...be.get(x)??[],h]);let Zr=[...be].filter(([,h])=>h.length>1).map(([h,j])=>({key:h,paths:j.sort()})).sort((h,j)=>h.key.localeCompare(j.key)),J={};for(let h of ht)Object.assign(J,b.get(h)??{});let Qr=[...T.keys()].sort((h,j)=>{if(h===".envrc")return 1;if(j===".envrc")return-1;return h.localeCompare(j)}),yt=new Set;for(let h of Qr){let j=new Set(E.get(h)??[]);for(let x of D.get(h)??[]){if(j.has(x)){delete J[x],yt.add(x);continue}let F=T.get(h)?.[x];if(F!==void 0)J[x]=F;yt.delete(x)}}let wt=t.historyMode??"abort_on_findings",Y=Eo(n,r);if(!Y.complete&&wt!=="preserve")u.push(`Git history scan exceeded ${ct} commits or failed; import requires explicit --history preserve.`);if(Y.findings.length>0&&wt==="abort_on_findings")u.push("Potential secrets exist in Git history. Abort, sanitize the repository, or explicitly use --history preserve.");let Hn=new Set(a.map((h)=>h.path)),es=await wr(n,Hn,ke),{observedSecretKeys:ts,...G}=es;G.warnings.push(...R);let vt=new Set(G.requiredSecretKeys);for(let h of yt)vt.add(h);for(let h of p)for(let j of h.envKeys)vt.add(j);G.requiredSecretKeys=[...vt].sort();for(let h of G.requiredSecretKeys){if(Be.test(h)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${h}`);continue}if(J[h]!==void 0)continue;let j=t.environment?.[h];if(j===void 0){u.push(`${rn}${h}`);continue}J[h]=j}for(let h of ts){if(Be.test(h)){G.warnings.push(`Ignored reserved Hlix control-plane environment reference: ${h}`);continue}if(tn.has(h))continue;if(J[h]!==void 0)continue;let j=t.environment?.[h];if(j===void 0){G.warnings.push(`Observed environment reference has no local value: ${h}`);continue}J[h]=j}G.warnings=[...new Set(G.warnings)].sort();let Fn={schemaVersion:vr,rootName:t.rootName??se(n),stack:bo(Hn),git:{detected:r,head:Y.head,branch:Y.branch,refs:Y.refs,commitCount:Y.commitCount,historyScanComplete:Y.complete,historyMode:wt},files:a,secretFiles:c,activeEnvFiles:ht,secretKeys:Object.keys(J).sort(),envCollisions:Zr,quarantinedResources:l,mcpServers:p,historicalSecretFindings:Y.findings,skipped:d,environment:G,totals:{files:a.length,bytes:a.reduce((h,j)=>h+j.size,0)}},Nn=nn(Fn),ns=Pr("sha256").update(Nn).digest("hex");return{root:n,manifest:Fn,manifestJson:Nn,manifestSha256:ns,secretValues:J,protectedFiles:H.sort((h,j)=>h.path.localeCompare(j.path)),blocking:[...new Set(u)]}}var sn={name:"init",summary:"Configure a local folder for Hlix",usage:["Usage: hlix init [folder] [--project <id>] [--json]","","Creates .hlix/config.json, .hlix/.gitignore, and .hlixignore.","Project configuration is safe to commit; local revision state is ignored.",""," --project <id> Bind the folder to an existing cloud project (then `hlix pull`)"].join(`
87
+ `).filter(Boolean).map((u)=>{let[m,v]=u.split("\x00");return{name:m,oid:v}}).filter(({name:u,oid:m})=>/^refs\/(?:heads|tags)\/.+/.test(u)&&/^[0-9a-f]{40,64}$/.test(m)).sort((u,m)=>u.name.localeCompare(m.name)),c=["log","--all",`--max-count=${ct}`,"--pretty=format:@@%H","--name-only"],l=ee(e,[...c,"--",".env",".env.*","*.pem","*.key",".npmrc","*.tfvars"]),p=ee(e,["log","--all",`--max-count=${ct}`,"-G","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,}","--pretty=format:@@%H","--name-only"]),d=new Map;for(let u of[...Er(l.stdout,"sensitive-path"),...Er(p.stdout,"secret-pattern")])d.set(`${u.commit}:${u.path}:${u.reason}`,u);return{head:n,branch:s,refs:a,commitCount:o,complete:o<=ct&&a.length<=1000&&i.status===0&&l.status===0&&p.status===0,findings:[...d.values()].slice(0,100)}}async function q(e,t={}){let n=await $r(br(e));if(!(await Ys(n)).isDirectory())throw Error("Import target must be a directory.");let r=await ho(n),s=yo(n,r),{hardMatcher:o,matcher:i}=await wo(n),a=[],c=[],l=[],p=[],d=[],u=[],m=t.envFile?Ke(kr(n,br(n,t.envFile))):void 0,v=m!==void 0&&m!==""&&m!==".."&&!m.startsWith("../");if(t.envFile&&!v)u.push(`Selected environment file must stay inside the project: ${t.envFile}`);let b=new Map,T=new Map,D=new Map,E=new Map,R=[],H=[],ke=new Map,g=t.maxFiles??eo,P=t.maxFileBytes??to,S=t.maxTotalBytes??no,I=0,z=0,An=async(h)=>{let j=await Xs(h,{withFileTypes:!0});j.sort((x,F)=>x.name.localeCompare(F.name));for(let x of j){let F=Ir(h,x.name),C=Ke(kr(n,F));if(x.name===".git"){if(C!==".git")u.push(`Nested Git repository is not supported: ${C}`);continue}let M=await Cr(F),Un=x.isDirectory()?`${C}/`:C,kt=s.has(C),Ln=!kt&&i.ignores(Un),rs=!kt&&o.ignores(Un);if(M.isSymbolicLink()){if(d.push({path:C,reason:"symlink"}),!Ln)u.push(`Symlinks are not imported in this release: ${C}`);continue}if(x.isDirectory()){if(rs)continue;await An(F);continue}let Se=vo(C),je=ko(C);if(Ln&&!Se&&!je)continue;if(!x.isFile()){d.push({path:C,reason:"non-regular-file"});continue}if(a.length+c.length+l.length>=g){u.push(`Project exceeds the ${g} file limit.`);return}if(M.size>P){u.push(`File exceeds the ${P} byte limit: ${C}`);continue}if(I+=M.size,I>S){u.push(`Project exceeds the ${S} byte total limit.`);return}let Ye=await mo(F);if(Se){if(M.size>it){u.push(`Protected configuration exceeds the ${it} byte limit: ${C}`);continue}let N=await at(F);if(z+=N.byteLength,z>ye){u.push(`Protected project files exceed the ${ye} byte total limit.`);continue}if(l.push({path:C,kind:Se,size:M.size,sha256:Ye}),H.push({path:C,kind:Se,contentBase64:N.toString("base64")}),Se==="mcp")p.push(...jo(C,N.toString("utf8")));continue}if(je){if(M.size>it){u.push(`Protected file exceeds the ${it} byte limit: ${C}`);continue}let N=await at(F);if(z+=N.byteLength,z>ye){u.push(`Protected project files exceed the ${ye} byte total limit.`);continue}let te=[];if(je==="dotenv")try{let Ze=xr(N),ie={};for(let[Z,ae]of Object.entries(Ze)){if(Be.test(Z)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${Z}`);continue}ie[Z]=ae}b.set(C,ie),te=Object.keys(ie).sort()}catch{u.push(`Could not parse environment file: ${C}`)}else if(se(C)===".envrc"){let Ze=go(N),ie={},Z=new Set,ae=[];for(let[A,ss]of Object.entries(Ze.values)){if(Be.test(A)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${A}`);continue}if(tn.has(A)){R.push(`Ignored ambient runtime assignment in ${C}: ${A}`);continue}Z.add(A),ie[A]=ss}T.set(C,ie);for(let A of Ze.dynamicKeys){if(Be.test(A)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${A}`);continue}if(tn.has(A)){R.push(`Ignored ambient runtime assignment in ${C}: ${A}`);continue}Z.add(A),ae.push(A)}if(D.set(C,[...Z].sort()),E.set(C,ae.sort()),te=[...Z].sort(),ae.length>0)R.push(`Did not execute dynamic .envrc assignments; collect their resolved local values when available: ${ae.join(", ")}`)}c.push({path:C,kind:je,keys:te,size:M.size,sha256:Ye}),H.push({path:C,kind:je,contentBase64:N.toString("base64")});continue}if(M.size<=1048576){let N=await at(F),te=N.toString("utf8");if(ke.set(C,te),lo.test(te)||po.test(C)&&uo.test(te)){if(z+=N.byteLength,z>ye){u.push(`Protected project files exceed the ${ye} byte total limit.`);continue}c.push({path:C,kind:"detected-content",keys:[],size:M.size,sha256:Ye}),H.push({path:C,kind:"detected-content",contentBase64:N.toString("base64")});continue}}a.push({path:C,size:M.size,sha256:Ye,tracked:kt,executable:(M.mode&73)!==0})}};await An(n),a.sort((h,j)=>h.path.localeCompare(j.path)),c.sort((h,j)=>h.path.localeCompare(j.path)),l.sort((h,j)=>h.path.localeCompare(j.path)),p.sort((h,j)=>`${h.sourcePath}:${h.name}`.localeCompare(`${j.sourcePath}:${j.name}`));let ht=So([...b.keys()].sort(),v?m:void 0);if(t.envFile&&v&&!b.has(ht[0]))u.push(`Selected environment file was not found or is not a dotenv file: ${t.envFile}`);let be=new Map;for(let[h,j]of b)for(let x of Object.keys(j))be.set(x,[...be.get(x)??[],h]);for(let[h,j]of D)for(let x of j)be.set(x,[...be.get(x)??[],h]);let Zr=[...be].filter(([,h])=>h.length>1).map(([h,j])=>({key:h,paths:j.sort()})).sort((h,j)=>h.key.localeCompare(j.key)),J={};for(let h of ht)Object.assign(J,b.get(h)??{});let Qr=[...T.keys()].sort((h,j)=>{if(h===".envrc")return 1;if(j===".envrc")return-1;return h.localeCompare(j)}),yt=new Set;for(let h of Qr){let j=new Set(E.get(h)??[]);for(let x of D.get(h)??[]){if(j.has(x)){delete J[x],yt.add(x);continue}let F=T.get(h)?.[x];if(F!==void 0)J[x]=F;yt.delete(x)}}let wt=t.historyMode??"abort_on_findings",Y=Eo(n,r);if(!Y.complete&&wt!=="preserve")u.push(`Git history scan exceeded ${ct} commits or failed; import requires explicit --history preserve.`);if(Y.findings.length>0&&wt==="abort_on_findings")u.push("Potential secrets exist in Git history. Abort, sanitize the repository, or explicitly use --history preserve.");let Hn=new Set(a.map((h)=>h.path)),es=await wr(n,Hn,ke),{observedSecretKeys:ts,...G}=es;G.warnings.push(...R);let vt=new Set(G.requiredSecretKeys);for(let h of yt)vt.add(h);for(let h of p)for(let j of h.envKeys)vt.add(j);G.requiredSecretKeys=[...vt].sort();for(let h of G.requiredSecretKeys){if(Be.test(h)){u.push(`Hlix control-plane environment keys cannot be imported into a project: ${h}`);continue}if(J[h]!==void 0)continue;let j=t.environment?.[h];if(j===void 0){u.push(`${rn}${h}`);continue}J[h]=j}for(let h of ts){if(Be.test(h)){G.warnings.push(`Ignored reserved Hlix control-plane environment reference: ${h}`);continue}if(tn.has(h))continue;if(J[h]!==void 0)continue;let j=t.environment?.[h];if(j===void 0){G.warnings.push(`Observed environment reference has no local value: ${h}`);continue}J[h]=j}G.warnings=[...new Set(G.warnings)].sort();let Fn={schemaVersion:vr,rootName:t.rootName??se(n),stack:bo(Hn),git:{detected:r,head:Y.head,branch:Y.branch,refs:Y.refs,commitCount:Y.commitCount,historyScanComplete:Y.complete,historyMode:wt},files:a,secretFiles:c,activeEnvFiles:ht,secretKeys:Object.keys(J).sort(),envCollisions:Zr,quarantinedResources:l,mcpServers:p,historicalSecretFindings:Y.findings,skipped:d,environment:G,totals:{files:a.length,bytes:a.reduce((h,j)=>h+j.size,0)}},Nn=nn(Fn),ns=Pr("sha256").update(Nn).digest("hex");return{root:n,manifest:Fn,manifestJson:Nn,manifestSha256:ns,secretValues:J,protectedFiles:H.sort((h,j)=>h.path.localeCompare(j.path)),blocking:[...new Set(u)]}}var sn={name:"init",summary:"Configure a local folder for Hlix",usage:["Usage: hlix init [folder] [--project <id>] [--json]","","Creates .hlix/config.json, .hlix/.gitignore, and .hlixignore.","Project configuration is safe to commit; local revision state is ignored.",""," --project <id> Bind the folder to an existing cloud project (then `hlix pull`)"].join(`
88
88
  `),supportsJson:!0,options:["project"],args:{min:0,max:1},async run(e){if(e.args.length>1)throw Error("init accepts at most one folder.");let t=await Po(Co(e.cwd,e.args[0]??".")),n=B({env:e.env,flags:e.flags,cwd:t});if(n.conflict)throw new f("workspace_mismatch",n.conflict);if(!n.workspaceId)throw Error("No workspace selected. Run `hlix auth login --workspace <id>` first.");let r=e.requireClient(t);await r.projects.list();let s=le(t),o=typeof e.flags.project==="string"?e.flags.project:void 0;if(o&&s?.projectId&&s.projectId!==o)throw new f("workspace_mismatch",`This folder is bound to project ${s.projectId}; refusing to rebind it to ${o}.`);if(o)await r.projects.get(o);let i={...s??{schemaVersion:1,workspaceId:n.workspaceId,apiUrl:n.baseUrl},...o?{projectId:o}:{}};xe(t,i);let a=await q(t,{environment:e.env}),c={root:t,config:i,scan:{files:a.manifest.totals.files,bytes:a.manifest.totals.bytes,secretFiles:a.manifest.secretFiles.map((l)=>l.path),quarantinedResources:a.manifest.quarantinedResources.map((l)=>l.path),blocking:a.blocking}};if(e.json)e.stdout(y(k(sn.name,c)));else if(e.stdout(`Initialized ${t}
89
89
  Project: ${i.projectId??"not imported yet"}
90
90
  Workspace: ${i.workspaceId}
@@ -96,7 +96,7 @@ ${a.blocking.map((l)=>`- ${l}`).join(`
96
96
  `).at(-1)??"git command failed";throw Error(r)}return n.stdout.trim()}async function Tr(e){let t=$o("sha256");for await(let n of Io(e))t.update(n);return t.digest("hex")}async function Ao(e){for(let t of await Oo(e)){if(t===".git")continue;await an(oe(e,t),{recursive:!0,force:!0})}}async function lt(e){if(e.blocking.length>0)throw Error(`Project scan has blocking findings:
97
97
  - ${e.blocking.join(`
98
98
  - `)}`);let t=await _o(oe(To(),"hlix-snapshot-"));await on(t,448);let n=oe(t,"repo"),r=oe(t,"source.git"),s=oe(t,"project.bundle");try{if(e.manifest.git.detected){let d=ze("git",["clone","--mirror","--no-hardlinks",e.root,r],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(d.status!==0)throw Error(d.stderr.trim()||"Could not mirror repository.");let u=new Map(V(r,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]).split(`
99
- `).filter(Boolean).map((w)=>w.split("\x00",2)));for(let w of e.manifest.git.refs)if(u.get(w.name)!==w.oid)throw Error(`Git ref changed after scan: ${w.name}`);let m=ze("git",["clone","--no-hardlinks",r,n],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(m.status!==0)throw Error(m.stderr.trim()||"Could not create snapshot clone.");if(!e.manifest.git.head)throw Error("Git repository has no HEAD commit.");V(n,["checkout","-B","main",e.manifest.git.head])}else await Or(n,{recursive:!0,mode:448}),V(n,["init","-b","main"]);await Ao(n);for(let d of e.manifest.files){let u=oe(e.root,...d.path.split("/")),m=await _r(u);if(!m.isFile()||m.isSymbolicLink())throw Error(`Source changed after scan: ${d.path}`);if(m.size!==d.size||await Tr(u)!==d.sha256)throw Error(`Source changed after scan: ${d.path}`);let w=oe(n,...d.path.split("/"));await Or(Ro(w),{recursive:!0,mode:493}),await xo(u,w),await on(w,d.executable?493:420)}V(n,["config","user.name","Hlix Import"]),V(n,["config","user.email","import@hlix.ai"]),V(n,["add","-A"]),V(n,["commit","--allow-empty","-m","chore(hlix): import snapshot"]);let o=V(n,["rev-parse","HEAD"]),i=e.manifest.git.refs.filter((d)=>d.name!=="refs/heads/main");if(i.length>0){let d=ze("git",["-C",n,"update-ref","--stdin"],{encoding:"utf8",input:i.map((u)=>`update ${u.name} ${u.oid}`).join(`
99
+ `).filter(Boolean).map((v)=>v.split("\x00",2)));for(let v of e.manifest.git.refs)if(u.get(v.name)!==v.oid)throw Error(`Git ref changed after scan: ${v.name}`);let m=ze("git",["clone","--no-hardlinks",r,n],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(m.status!==0)throw Error(m.stderr.trim()||"Could not create snapshot clone.");if(!e.manifest.git.head)throw Error("Git repository has no HEAD commit.");V(n,["checkout","-B","main",e.manifest.git.head])}else await Or(n,{recursive:!0,mode:448}),V(n,["init","-b","main"]);await Ao(n);for(let d of e.manifest.files){let u=oe(e.root,...d.path.split("/")),m=await _r(u);if(!m.isFile()||m.isSymbolicLink())throw Error(`Source changed after scan: ${d.path}`);if(m.size!==d.size||await Tr(u)!==d.sha256)throw Error(`Source changed after scan: ${d.path}`);let v=oe(n,...d.path.split("/"));await Or(Ro(v),{recursive:!0,mode:493}),await xo(u,v),await on(v,d.executable?493:420)}V(n,["config","user.name","Hlix Import"]),V(n,["config","user.email","import@hlix.ai"]),V(n,["add","-A"]),V(n,["commit","--allow-empty","-m","chore(hlix): import snapshot"]);let o=V(n,["rev-parse","HEAD"]),i=e.manifest.git.refs.filter((d)=>d.name!=="refs/heads/main");if(i.length>0){let d=ze("git",["-C",n,"update-ref","--stdin"],{encoding:"utf8",input:i.map((u)=>`update ${u.name} ${u.oid}`).join(`
100
100
  `)+`
101
101
  `,stdio:["pipe","pipe","pipe"]});if(d.status!==0)throw Error(d.stderr.trim()||"Could not recreate the approved Git refs.")}let a=i.map((d)=>d.name),c=ze("git",["-C",n,"bundle","create",s,"--stdin"],{encoding:"utf8",input:["refs/heads/main",...a].join(`
102
102
  `)+`
@@ -106,7 +106,7 @@ ${a.blocking.map((l)=>`- ${l}`).join(`
106
106
  `)+`
107
107
  `)}return o.blocking.length?1:0}if(o.blocking.length)throw new f("scan_blocked",`Project scan blocked import:
108
108
  - ${o.blocking.join(`
109
- - `)}`);let a=await lt(o);try{let c=e.requireClient(t),l=await c.imports.create({idempotencyKey:Mo(o.manifestSha256,a.bundleSha256),name:i.name,stack:i.stack,defaultBranch:"main",historyMode:o.manifest.git.historyMode,manifest:o.manifest,manifestSha256:o.manifestSha256,bundleSha256:a.bundleSha256,bundleSize:a.bundleSize,commitSha:a.commitSha});if(l.import.status==="pending_upload"){if(!l.upload)throw Error(`Import ${l.import.id} is ${l.import.status} but has no upload target.`);await c.imports.uploadBundle(l.upload,new Blob([Uint8Array.from(await Fo(a.bundlePath))]),{onProgress:(w,b)=>{if(!e.json)e.stderr(`Uploading ${w}/${b} bytes\r`)}})}let d=(l.import.status==="ready"?{import:l.import}:await c.imports.finalize(l.import.id,{secrets:o.secretValues,protectedFiles:o.protectedFiles})).import,u=d.projectId??d.requestedProjectId;if(!u||!d.revisionId||!d.generation)throw Error("Import completed without project revision metadata.");xe(t,{schemaVersion:1,projectId:u,workspaceId:n.workspaceId,apiUrl:n.baseUrl}),_e(t,{schemaVersion:1,revisionId:d.revisionId,generation:d.generation,commitSha:a.commitSha,manifestSha256:o.manifestSha256,historyMode:o.manifest.git.historyMode,rootName:o.manifest.rootName});let m={projectId:u,revisionId:d.revisionId,generation:d.generation,commitSha:a.commitSha,files:o.manifest.totals.files,bytes:o.manifest.totals.bytes};if(e.json)e.stdout(y(k(dt.name,m)));else e.stderr(`
109
+ - `)}`);let a=await lt(o);try{let c=e.requireClient(t),l=await c.imports.create({idempotencyKey:Mo(o.manifestSha256,a.bundleSha256),name:i.name,stack:i.stack,defaultBranch:"main",historyMode:o.manifest.git.historyMode,manifest:o.manifest,manifestSha256:o.manifestSha256,bundleSha256:a.bundleSha256,bundleSize:a.bundleSize,commitSha:a.commitSha});if(l.import.status==="pending_upload"){if(!l.upload)throw Error(`Import ${l.import.id} is ${l.import.status} but has no upload target.`);await c.imports.uploadBundle(l.upload,new Blob([Uint8Array.from(await Fo(a.bundlePath))]),{onProgress:(v,b)=>{if(!e.json)e.stderr(`Uploading ${v}/${b} bytes\r`)}})}let d=(l.import.status==="ready"?{import:l.import}:await c.imports.finalize(l.import.id,{secrets:o.secretValues,protectedFiles:o.protectedFiles})).import,u=d.projectId??d.requestedProjectId;if(!u||!d.revisionId||!d.generation)throw Error("Import completed without project revision metadata.");xe(t,{schemaVersion:1,projectId:u,workspaceId:n.workspaceId,apiUrl:n.baseUrl}),_e(t,{schemaVersion:1,revisionId:d.revisionId,generation:d.generation,commitSha:a.commitSha,manifestSha256:o.manifestSha256,historyMode:o.manifest.git.historyMode,rootName:o.manifest.rootName});let m={projectId:u,revisionId:d.revisionId,generation:d.generation,commitSha:a.commitSha,files:o.manifest.totals.files,bytes:o.manifest.totals.bytes};if(e.json)e.stdout(y(k(dt.name,m)));else e.stderr(`
110
110
  `),e.stdout(`Imported ${i.name}
111
111
  Project ID: ${u}
112
112
  Revision: ${d.generation}
@@ -117,16 +117,16 @@ Revision: ${d.generation}
117
117
  `),supportsJson:!0,options:["print","web"],args:{min:0,max:1},async run(e){let t=e.args[0]??O(e.cwd)?.config.projectId;if(!t)throw new f("missing_argument","A project id is required, or run this inside a folder bound to a project.");let n=await e.requireClient().projects.terminal(t);if(e.json)return e.stdout(y(k(dn.name,n))),n.available?0:1;if(!n.available){let i=n.environmentState?` (environment: ${n.environmentState})`:"";throw new f("not_found",`${n.reason??"Terminal unavailable"}${i}`)}let r=e.flags.print===!0,s=e.flags.web===!0;if(r||s&&!n.webTerminalUrl||!s&&!n.sshCommand)return e.stdout(`${_([["ssh",n.sshCommand??"not available"],["browser",n.webTerminalUrl??"not available"]])}
118
118
  `),0;if(s){if(Fr(process.platform==="darwin"?"open":"xdg-open",[n.webTerminalUrl],{stdio:"ignore"}).status!==0)e.stdout(`${n.webTerminalUrl}
119
119
  `);return 0}return Fr("sh",["-c",n.sshCommand],{stdio:"inherit"}).status??1}};import{createHash as si}from"node:crypto";import{readFile as oi,realpath as ii}from"node:fs/promises";import{createHash as qo}from"node:crypto";import{constants as pt}from"node:fs";import{chmod as Nr,copyFile as Do,lstat as pn,mkdir as Jo,mkdtemp as Go,open as Wo,realpath as Vo,rename as Xo,rm as Je,writeFile as Yo}from"node:fs/promises";import{tmpdir as Zo}from"node:os";import{dirname as Br,join as X,relative as Qo,resolve as ei,sep as Ur}from"node:path";import{spawnSync as ti}from"node:child_process";function Kr(e){let t=e;if(typeof t==="string")try{t=JSON.parse(t)}catch{return{}}if(!t||typeof t!=="object")return{};let n=t,r=n.git&&typeof n.git==="object"?n.git:{},s=r.historyMode==="preserve"||r.historyMode==="abort_on_findings"?r.historyMode:void 0,o=typeof n.rootName==="string"&&n.rootName.trim()?n.rootName:void 0;return{historyMode:s,rootName:o}}function zr(e){let t=e;if(typeof t==="string")try{t=JSON.parse(t)}catch{return[]}if(!t||typeof t!=="object")return[];let n=t.files;if(!Array.isArray(n))return[];return n.flatMap((r)=>{if(!r||typeof r!=="object")return[];let s=r;return typeof s.path==="string"&&typeof s.sha256==="string"?[{path:s.path,sha256:s.sha256}]:[]})}function De(e,t){let n=ti("git",["-C",e,...t],{encoding:"utf8",maxBuffer:52428800,stdio:["ignore","pipe","pipe"]});if(n.status!==0)throw Error(n.stderr.trim().split(`
120
- `).at(-1)??"Git command failed");return n.stdout.trim()}function Lr(e){return qo("sha256").update(e).digest("hex")}async function un(e,t){let n=await Vo(e),r=ei(n,...t.split("/"));if(r!==n&&!r.startsWith(n+Ur))throw Error(`Protected path escapes the project: ${t}`);let s=Qo(n,Br(r)),o=n;for(let i of s.split(Ur).filter(Boolean)){o=X(o,i);try{let a=await pn(o);if(!a.isDirectory()||a.isSymbolicLink())throw Error(`Protected path crosses a non-directory: ${t}`)}catch(a){if(a.code!=="ENOENT")throw a;await Jo(o,{mode:448})}}return r}async function Mr(e,t,n){let r=await un(e,t);try{let i=await pn(r);if(!i.isFile()||i.isSymbolicLink())throw Error(`Refusing to replace non-regular protected file: ${t}`)}catch(i){if(i.code!=="ENOENT")throw i}let s=X(Br(r),`.hlix-pull-${crypto.randomUUID()}.tmp`),o=await Wo(s,pt.O_WRONLY|pt.O_CREAT|pt.O_EXCL|pt.O_NOFOLLOW,384);try{await o.writeFile(n),await o.sync()}finally{await o.close()}try{await Xo(s,r)}catch(i){throw await Je(s,{force:!0}),i}}async function ni(e,t){let n=await un(e,t);try{let r=await pn(n);if(!r.isFile()||r.isSymbolicLink())throw Error(`Refusing to replace non-regular project file: ${t}`)}catch(r){if(r.code!=="ENOENT")throw r}}async function qr(e,t,n,r,s){let o=await Go(X(Zo(),"hlix-pull-"));await Nr(o,448);let i=X(o,"project.bundle"),a=X(o,"checkout");try{let c=Buffer.from(await r.arrayBuffer());if(c.byteLength!==n.bundleSize||Lr(c)!==n.bundleSha256)throw Error("Downloaded revision bundle failed integrity verification.");if(await Yo(i,c,{mode:384}),De(o,["clone","--no-hardlinks","--branch","main",i,a]),De(a,["bundle","verify",i]),De(a,["rev-parse","HEAD"])!==n.commitSha)throw Error("Downloaded revision bundle does not match the cloud commit.");let l=n.manifest,p=new Map;for(let m of[...l.secretFiles,...l.quarantinedResources])p.set(m.path,m);if(s.files.length!==p.size)throw Error("Cloud protected files do not match the revision manifest.");let d=new Map;for(let m of s.files){let w=p.get(m.path),b=Buffer.from(m.contentBase64,"base64");if(b.toString("base64").replace(/=+$/,"")!==m.contentBase64.replace(/=+$/,"")||!w||w.kind!==m.kind||b.byteLength!==w.size||Lr(b)!==w.sha256)throw Error(`Cloud protected file failed integrity verification: ${m.path}`);d.set(m.path,b)}let u=new Set([...l.files.map((m)=>m.path),...t.manifest.secretFiles.map((m)=>m.path),...t.manifest.quarantinedResources.map((m)=>m.path),...d.keys()]);for(let m of[...u].sort())await ni(e,m);for(let[m,w]of d)await Mr(a,m,w);if(t.manifest.git.detected){De(e,["fetch",i,"refs/heads/main"]),De(e,["reset","--hard","FETCH_HEAD"]);let m=new Set(l.files.map((w)=>w.path));for(let w of t.manifest.files)if(!m.has(w.path))await Je(X(e,...w.path.split("/")),{force:!0})}else{for(let m of t.manifest.files)await Je(X(e,...m.path.split("/")),{force:!0});for(let m of l.files){let w=await un(e,m.path);await Do(X(a,...m.path.split("/")),w),await Nr(w,m.executable?493:420)}}for(let m of[...t.manifest.secretFiles,...t.manifest.quarantinedResources])if(!d.has(m.path))await Je(X(e,...m.path.split("/")),{force:!0});for(let[m,w]of d)await Mr(e,m,w)}finally{await Je(o,{recursive:!0,force:!0})}}function we(e,t,n){let r=new Map(zr(n.manifest).map((c)=>[c.path,c.sha256])),s=new Map(e.manifest.files.map((c)=>[c.path,c.sha256])),o=0,i=0;for(let[c,l]of s){let p=r.get(c);if(p===void 0)o+=1;else if(p!==l)i+=1}let a=0;for(let c of r.keys())if(!s.has(c))a+=1;return{localChanged:!t.manifestSha256||e.manifestSha256!==t.manifestSha256,cloudChanged:n.id!==t.revisionId||n.generation!==t.generation,local:{revisionId:t.revisionId,generation:t.generation},cloud:{revisionId:n.id,generation:n.generation,commitSha:n.commitSha},files:{local:s.size,cloud:r.size,localOnly:o,cloudOnly:a,differing:i}}}function mn(e,t,n){let{localChanged:r,cloudChanged:s}=t;if(e==="push")return s?"conflict":r?"push":"none";if(e==="pull"){if(!s)return"none";return r&&!n?"conflict":"pull"}if(r&&s)return"conflict";return r?"push":s?"pull":"none"}function fn(e,t,n){return e==="pull"&&t.localChanged&&!n}var ri={push:{push:"Would push the local changes as a new cloud revision.",pull:"",none:"Nothing to push — local matches the last synced revision.",conflict:"Would refuse: the cloud changed since this folder's base revision."},pull:{push:"",pull:"Would replace local files with the cloud revision.",none:"Nothing to pull — the cloud head is the local base revision.",conflict:"Would refuse: local files changed. Re-run with --force to replace them."},sync:{push:"Would push the local changes as a new cloud revision.",pull:"Would pull the cloud revision into this folder.",none:"Already in sync.",conflict:"Would refuse: local and cloud both changed since the last sync."}};function Dr(e,t,n,r){let s=n.files;return[`${e} --dry-run: ${ri[e][t]}`,...r?["Requires --yes (or interactive approval) to execute."]:[],"",_([["local",`generation ${n.local.generation} (${n.local.revisionId})${n.localChanged?" — modified":""}`],["cloud",`generation ${n.cloud.generation} (${n.cloud.revisionId})${n.cloudChanged?" — ahead":""}`],["files",`${s.local} local, ${s.cloud} cloud — ${s.localOnly} local-only, ${s.cloudOnly} cloud-only, ${s.differing} differing`]])].join(`
120
+ `).at(-1)??"Git command failed");return n.stdout.trim()}function Lr(e){return qo("sha256").update(e).digest("hex")}async function un(e,t){let n=await Vo(e),r=ei(n,...t.split("/"));if(r!==n&&!r.startsWith(n+Ur))throw Error(`Protected path escapes the project: ${t}`);let s=Qo(n,Br(r)),o=n;for(let i of s.split(Ur).filter(Boolean)){o=X(o,i);try{let a=await pn(o);if(!a.isDirectory()||a.isSymbolicLink())throw Error(`Protected path crosses a non-directory: ${t}`)}catch(a){if(a.code!=="ENOENT")throw a;await Jo(o,{mode:448})}}return r}async function Mr(e,t,n){let r=await un(e,t);try{let i=await pn(r);if(!i.isFile()||i.isSymbolicLink())throw Error(`Refusing to replace non-regular protected file: ${t}`)}catch(i){if(i.code!=="ENOENT")throw i}let s=X(Br(r),`.hlix-pull-${crypto.randomUUID()}.tmp`),o=await Wo(s,pt.O_WRONLY|pt.O_CREAT|pt.O_EXCL|pt.O_NOFOLLOW,384);try{await o.writeFile(n),await o.sync()}finally{await o.close()}try{await Xo(s,r)}catch(i){throw await Je(s,{force:!0}),i}}async function ni(e,t){let n=await un(e,t);try{let r=await pn(n);if(!r.isFile()||r.isSymbolicLink())throw Error(`Refusing to replace non-regular project file: ${t}`)}catch(r){if(r.code!=="ENOENT")throw r}}async function qr(e,t,n,r,s){let o=await Go(X(Zo(),"hlix-pull-"));await Nr(o,448);let i=X(o,"project.bundle"),a=X(o,"checkout");try{let c=Buffer.from(await r.arrayBuffer());if(c.byteLength!==n.bundleSize||Lr(c)!==n.bundleSha256)throw Error("Downloaded revision bundle failed integrity verification.");if(await Yo(i,c,{mode:384}),De(o,["clone","--no-hardlinks","--branch","main",i,a]),De(a,["bundle","verify",i]),De(a,["rev-parse","HEAD"])!==n.commitSha)throw Error("Downloaded revision bundle does not match the cloud commit.");let l=n.manifest,p=new Map;for(let m of[...l.secretFiles,...l.quarantinedResources])p.set(m.path,m);if(s.files.length!==p.size)throw Error("Cloud protected files do not match the revision manifest.");let d=new Map;for(let m of s.files){let v=p.get(m.path),b=Buffer.from(m.contentBase64,"base64");if(b.toString("base64").replace(/=+$/,"")!==m.contentBase64.replace(/=+$/,"")||!v||v.kind!==m.kind||b.byteLength!==v.size||Lr(b)!==v.sha256)throw Error(`Cloud protected file failed integrity verification: ${m.path}`);d.set(m.path,b)}let u=new Set([...l.files.map((m)=>m.path),...t.manifest.secretFiles.map((m)=>m.path),...t.manifest.quarantinedResources.map((m)=>m.path),...d.keys()]);for(let m of[...u].sort())await ni(e,m);for(let[m,v]of d)await Mr(a,m,v);if(t.manifest.git.detected){De(e,["fetch",i,"refs/heads/main"]),De(e,["reset","--hard","FETCH_HEAD"]);let m=new Set(l.files.map((v)=>v.path));for(let v of t.manifest.files)if(!m.has(v.path))await Je(X(e,...v.path.split("/")),{force:!0})}else{for(let m of t.manifest.files)await Je(X(e,...m.path.split("/")),{force:!0});for(let m of l.files){let v=await un(e,m.path);await Do(X(a,...m.path.split("/")),v),await Nr(v,m.executable?493:420)}}for(let m of[...t.manifest.secretFiles,...t.manifest.quarantinedResources])if(!d.has(m.path))await Je(X(e,...m.path.split("/")),{force:!0});for(let[m,v]of d)await Mr(e,m,v)}finally{await Je(o,{recursive:!0,force:!0})}}function we(e,t,n){let r=new Map(zr(n.manifest).map((c)=>[c.path,c.sha256])),s=new Map(e.manifest.files.map((c)=>[c.path,c.sha256])),o=0,i=0;for(let[c,l]of s){let p=r.get(c);if(p===void 0)o+=1;else if(p!==l)i+=1}let a=0;for(let c of r.keys())if(!s.has(c))a+=1;return{localChanged:!t.manifestSha256||e.manifestSha256!==t.manifestSha256,cloudChanged:n.id!==t.revisionId||n.generation!==t.generation,local:{revisionId:t.revisionId,generation:t.generation},cloud:{revisionId:n.id,generation:n.generation,commitSha:n.commitSha},files:{local:s.size,cloud:r.size,localOnly:o,cloudOnly:a,differing:i}}}function mn(e,t,n){let{localChanged:r,cloudChanged:s}=t;if(e==="push")return s?"conflict":r?"push":"none";if(e==="pull"){if(!s)return"none";return r&&!n?"conflict":"pull"}if(r&&s)return"conflict";return r?"push":s?"pull":"none"}function fn(e,t,n){return e==="pull"&&t.localChanged&&!n}var ri={push:{push:"Would push the local changes as a new cloud revision.",pull:"",none:"Nothing to push — local matches the last synced revision.",conflict:"Would refuse: the cloud changed since this folder's base revision."},pull:{push:"",pull:"Would replace local files with the cloud revision.",none:"Nothing to pull — the cloud head is the local base revision.",conflict:"Would refuse: local files changed. Re-run with --force to replace them."},sync:{push:"Would push the local changes as a new cloud revision.",pull:"Would pull the cloud revision into this folder.",none:"Already in sync.",conflict:"Would refuse: local and cloud both changed since the last sync."}};function Dr(e,t,n,r){let s=n.files;return[`${e} --dry-run: ${ri[e][t]}`,...r?["Requires --yes (or interactive approval) to execute."]:[],"",_([["local",`generation ${n.local.generation} (${n.local.revisionId})${n.localChanged?" — modified":""}`],["cloud",`generation ${n.cloud.generation} (${n.cloud.revisionId})${n.cloudChanged?" — ahead":""}`],["files",`${s.local} local, ${s.cloud} cloud — ${s.localOnly} local-only, ${s.cloudOnly} cloud-only, ${s.differing} differing`]])].join(`
121
121
  `)}function ai(e,t,n){return si("sha256").update(`project-push-v1\x00${e}\x00${t}\x00${n}`).digest("hex")}var ci={schemaVersion:1,revisionId:"",generation:0,commitSha:""};async function ve(e,{allowUnsynced:t=!1}={}){let n=O(e);if(!n?.config.projectId)throw new f("not_initialized","This folder is not bound to an imported Hlix project. Run `hlix import .` first.");let r=rt(n.root)??(t?ci:null);if(!r)throw new f("not_initialized","This folder is bound to a project but has never been pulled. Run `hlix pull` first.");return{root:await ii(n.root),config:n.config,state:r}}async function Ge(e,t,n,r){let s=await q(e,{historyMode:n,environment:t,rootName:r});if(s.blocking.length>0)throw new f("scan_blocked",`Project scan blocked sync:
122
122
  - ${s.blocking.join(`
123
123
  - `)}`);return s}async function gn(e,t,n,r){let{state:s,config:o}=await ve(r,{allowUnsynced:n==="pull"}),i=e.requireClient(),[a,c]=await Promise.all([Ge(r,e.env,s.historyMode??"preserve",s.rootName),i.revisions.head(o.projectId)]),l=we(a,s,c.revision),p=mn(n,l,e.flags.force===!0),d=fn(p,l,e.flags.yes===!0);if(e.json)e.stdout(y(k(t,{dryRun:!0,action:p,approvalRequired:d,...l})));else e.stdout(`${Dr(n,p,l,d)}
124
124
  `);return p==="conflict"?1:0}async function li(e,t){if(e.flags.yes===!0)return;if(e.json||!e.confirm)throw new f("approval_required","`pull --force` replaces local files. Review with `hlix pull --dry-run`, then repeat with `--yes`.");let n=[`hlix pull --force will replace this folder with cloud revision ${t.cloud.generation}.`,`Local-only files to delete: ${t.files.localOnly}`,`Files to replace with the cloud copy: ${t.files.differing}`,"Local changes that were never pushed cannot be recovered by Hlix."].join(`
125
- `);if(!await e.confirm(n))throw new f("cancelled","Pull cancelled.")}async function Jr(e,t,n,r){let{state:s,config:o}=await ve(e),i=t.requireClient(),a=s.historyMode??"preserve",c=n??await Ge(e,t.env,a,s.rootName),l=r??(await i.revisions.head(o.projectId)).revision;if(l.id!==s.revisionId||l.generation!==s.generation)throw new f("conflict","Cloud changed since the local base. Run `hlix pull` or resolve with `hlix sync`.");if(s.manifestSha256&&c.manifestSha256===s.manifestSha256)return{action:"none",revisionId:s.revisionId,generation:s.generation};let p=await lt(c);try{let d=await i.revisions.createUpload(o.projectId,{idempotencyKey:ai(s.revisionId,c.manifestSha256,p.bundleSha256),expectedRevisionId:s.revisionId,expectedGeneration:s.generation,manifest:c.manifest,manifestSha256:c.manifestSha256,bundleSha256:p.bundleSha256,bundleSize:p.bundleSize,commitSha:p.commitSha});if(d.revisionUpload.status==="pending_upload"){if(!d.upload)throw Error("Revision upload has no bundle target.");await i.revisions.uploadBundle(d.upload,new Blob([Uint8Array.from(await oi(p.bundlePath))]),{onProgress:(m,w)=>{if(!t.json)t.stderr(`Uploading ${m}/${w} bytes\r`)}})}let u=await i.revisions.finalize(o.projectId,d.revisionUpload.id,{secrets:c.secretValues,protectedFiles:c.protectedFiles});if(!u.revision)throw Error("Revision finalized without head metadata.");return _e(e,{schemaVersion:1,revisionId:u.revision.id,generation:u.revision.generation,commitSha:u.revision.commitSha,manifestSha256:u.revision.manifestSha256,historyMode:a,rootName:s.rootName??c.manifest.rootName}),{action:"push",...u.revision}}finally{await p.dispose()}}async function Gr(e,t,n,r,s){let{state:o,config:i}=await ve(e,{allowUnsynced:!0}),a=t.requireClient(),c=o.historyMode??"preserve",l=r??await Ge(e,t.env,c,o.rootName),p=s??(await a.revisions.head(i.projectId)).revision;if(p.id===o.revisionId&&p.generation===o.generation)return{action:"none",revisionId:o.revisionId,generation:o.generation};let d=o.manifestSha256?l.manifestSha256!==o.manifestSha256:(()=>{let{files:E}=we(l,o,p);return E.localOnly+E.differing>0})();if(d&&!n)throw new f("conflict","Local files changed since the last sync. Push them, or use `hlix pull --force` to replace them.");if(d)await li(t,we(l,o,p));let[u,m]=await Promise.all([a.revisions.downloadBundle(i.projectId,p.id),a.revisions.protectedFiles(i.projectId)]);await qr(e,l,p,u,m);let w=Kr(p.manifest),b=w.historyMode??c,T=w.rootName??o.rootName??l.manifest.rootName,D=await Ge(e,t.env,b,T);return _e(e,{schemaVersion:1,revisionId:p.id,generation:p.generation,commitSha:p.commitSha,manifestSha256:D.manifestSha256,historyMode:b,rootName:T}),{action:"pull",revisionId:p.id,generation:p.generation,commitSha:p.commitSha}}function hn(e,t,n){if(e.json)e.stdout(y(k(t,n)));else if("action"in n&&n.action==="none")e.stdout(`Already in sync.
125
+ `);if(!await e.confirm(n))throw new f("cancelled","Pull cancelled.")}async function Jr(e,t,n,r){let{state:s,config:o}=await ve(e),i=t.requireClient(),a=s.historyMode??"preserve",c=n??await Ge(e,t.env,a,s.rootName),l=r??(await i.revisions.head(o.projectId)).revision;if(l.id!==s.revisionId||l.generation!==s.generation)throw new f("conflict","Cloud changed since the local base. Run `hlix pull` or resolve with `hlix sync`.");if(s.manifestSha256&&c.manifestSha256===s.manifestSha256)return{action:"none",revisionId:s.revisionId,generation:s.generation};let p=await lt(c);try{let d=await i.revisions.createUpload(o.projectId,{idempotencyKey:ai(s.revisionId,c.manifestSha256,p.bundleSha256),expectedRevisionId:s.revisionId,expectedGeneration:s.generation,manifest:c.manifest,manifestSha256:c.manifestSha256,bundleSha256:p.bundleSha256,bundleSize:p.bundleSize,commitSha:p.commitSha});if(d.revisionUpload.status==="pending_upload"){if(!d.upload)throw Error("Revision upload has no bundle target.");await i.revisions.uploadBundle(d.upload,new Blob([Uint8Array.from(await oi(p.bundlePath))]),{onProgress:(m,v)=>{if(!t.json)t.stderr(`Uploading ${m}/${v} bytes\r`)}})}let u=await i.revisions.finalize(o.projectId,d.revisionUpload.id,{secrets:c.secretValues,protectedFiles:c.protectedFiles});if(!u.revision)throw Error("Revision finalized without head metadata.");return _e(e,{schemaVersion:1,revisionId:u.revision.id,generation:u.revision.generation,commitSha:u.revision.commitSha,manifestSha256:u.revision.manifestSha256,historyMode:a,rootName:s.rootName??c.manifest.rootName}),{action:"push",...u.revision}}finally{await p.dispose()}}async function Gr(e,t,n,r,s){let{state:o,config:i}=await ve(e,{allowUnsynced:!0}),a=t.requireClient(),c=o.historyMode??"preserve",l=r??await Ge(e,t.env,c,o.rootName),p=s??(await a.revisions.head(i.projectId)).revision;if(p.id===o.revisionId&&p.generation===o.generation)return{action:"none",revisionId:o.revisionId,generation:o.generation};let d=o.manifestSha256?l.manifestSha256!==o.manifestSha256:(()=>{let{files:E}=we(l,o,p);return E.localOnly+E.differing>0})();if(d&&!n)throw new f("conflict","Local files changed since the last sync. Push them, or use `hlix pull --force` to replace them.");if(d)await li(t,we(l,o,p));let[u,m]=await Promise.all([a.revisions.downloadBundle(i.projectId,p.id),a.revisions.protectedFiles(i.projectId)]);await qr(e,l,p,u,m);let v=Kr(p.manifest),b=v.historyMode??c,T=v.rootName??o.rootName??l.manifest.rootName,D=await Ge(e,t.env,b,T);return _e(e,{schemaVersion:1,revisionId:p.id,generation:p.generation,commitSha:p.commitSha,manifestSha256:D.manifestSha256,historyMode:b,rootName:T}),{action:"pull",revisionId:p.id,generation:p.generation,commitSha:p.commitSha}}function hn(e,t,n){if(e.json)e.stdout(y(k(t,n)));else if("action"in n&&n.action==="none")e.stdout(`Already in sync.
126
126
  `);else e.stdout(`${String("action"in n?n.action:"sync")} complete.
127
127
  `)}var ut={name:"push",summary:"Push local changes as an immutable cloud revision",usage:"Usage: hlix push [--dry-run] [--json]",supportsJson:!0,options:["dry-run"],async run(e){if(e.args.length)throw Error("push accepts no positional arguments.");let{root:t}=await ve(e.cwd);if(e.flags["dry-run"]===!0)return gn(e,ut.name,"push",t);return hn(e,ut.name,await Jr(t,e)),0}},mt={name:"pull",summary:"Pull the cloud head into the local project",usage:["Usage: hlix pull [--force] [--yes] [--dry-run] [--json]",""," --force Replace local changes with the cloud revision"," --yes Skip the confirmation --force otherwise requires"," --dry-run Report the divergence and change nothing"].join(`
128
128
  `),supportsJson:!0,options:["force","yes","dry-run"],async run(e){if(e.args.length)throw Error("pull accepts no positional arguments.");let{root:t}=await ve(e.cwd,{allowUnsynced:!0});if(e.flags["dry-run"]===!0)return gn(e,mt.name,"pull",t);return hn(e,mt.name,await Gr(t,e,e.flags.force===!0)),0}},ft={name:"sync",summary:"Reconcile local and cloud changes without guessing conflicts",usage:"Usage: hlix sync [--dry-run] [--json]",supportsJson:!0,options:["dry-run"],async run(e){if(e.args.length)throw Error("sync accepts no positional arguments.");let{root:t,state:n,config:r}=await ve(e.cwd);if(e.flags["dry-run"]===!0)return gn(e,ft.name,"sync",t);let s=e.requireClient(),[o,i]=await Promise.all([Ge(t,e.env,n.historyMode??"preserve",n.rootName),s.revisions.head(r.projectId)]),a=i.revision,c=we(o,n,a);if(c.localChanged&&c.cloudChanged)throw new f("conflict","Both local and cloud changed since the last sync. Pull or push explicitly after reviewing the conflict.");let l=c.localChanged?await Jr(t,e,o,a):c.cloudChanged?await Gr(t,e,!1,o,a):{action:"none",revisionId:n.revisionId,generation:n.generation};return hn(e,ft.name,l),0}};import{lstat as Wr,readFile as di,realpath as pi}from"node:fs/promises";import{basename as yn,dirname as ui,extname as mi,join as fi,parse as Vr,resolve as wn}from"node:path";function We(e,t){let n=e.flags[t];return typeof n==="string"&&n.trim()?n.trim():void 0}function vn(e){let t=O(e);if(!t?.config.projectId)throw new f("not_initialized","This folder is not bound to an Hlix project. Run `hlix import .` first.");return{root:t.root,projectId:t.config.projectId}}async function kn(e,t){let n=await Wr(e);if(n.isSymbolicLink()||!n.isFile())throw Error(`Refusing to import a non-regular file: ${e}`);if(n.size>t)throw Error(`Import file exceeds ${t} bytes: ${e}`);return{path:await pi(e),content:await di(e,"utf8")}}function bn(e,t,n,r){if(e.json)e.stdout(y(k(t,n)));else e.stdout(`${r}
129
- `)}var Sn={name:"skill import",summary:"Activate a local skill for the bound cloud project",usage:"Usage: hlix skill import <SKILL.md|folder> [--name <slug>] [--json]",supportsJson:!0,options:["name"],args:{min:1,max:1},async run(e){if(e.args.length!==1)throw Error("skill import requires one file or folder.");let t=vn(e.cwd),n=wn(e.cwd,e.args[0]),r=await Wr(n);if(r.isSymbolicLink())throw Error(`Refusing to import a symlink: ${n}`);let s=r.isDirectory()?fi(n,"SKILL.md"):n,o=await kn(s,200000),i=r.isDirectory()?yn(n):yn(s)==="SKILL.md"?yn(ui(s)):Vr(s).name,a=We(e,"name")??i;if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(a))throw Error("Skill name must be a lowercase kebab-case slug.");let c=await e.requireClient().resources.importSkill(t.projectId,{slug:a,content:o.content});return bn(e,Sn.name,c.skill,`Imported skill ${a}`),0}},jn={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>] [--json]",supportsJson:!0,options:["name","runtime","duty","profile"],args:{min:1,max:1},async run(e){if(e.args.length!==1)throw Error("agent import requires one Markdown file.");let t=vn(e.cwd),n=wn(e.cwd,e.args[0]);if(![".md",".mdx"].includes(mi(n).toLowerCase()))throw Error("Agent imports must be Markdown files.");let r=await kn(n,20000),s=We(e,"runtime")??"hlix";if(!["claude-code","codex","cursor-agent","hlix"].includes(s))throw Error("--runtime must be claude-code, codex, cursor-agent, or hlix.");let o=We(e,"duty")??"executor";if(o!=="executor"&&o!=="intake")throw Error("--duty must be executor or intake.");let i=We(e,"name")??Vr(n).name.replace(/[-_]+/g," "),a=await e.requireClient().resources.importAgent(t.projectId,{name:i,instructions:r.content,runtimeKind:s,duty:o});return bn(e,jn.name,a.agent,a.agent.duty==="intake"?`Imported agent ${a.agent.name} as this project's intake agent`:`Imported agent ${a.agent.name}`),0}},En={name:"mcp import",summary:"Explicitly activate one validated local MCP server",usage:"Usage: hlix mcp import <.mcp.json> [--server <name>] [--allow-stdio] [--json]",supportsJson:!0,options:["server","allow-stdio"],args:{min:1,max:1},async run(e){if(e.args.length!==1)throw Error("mcp import requires one MCP JSON file.");let t=vn(e.cwd),n=await kn(wn(e.cwd,e.args[0]),200000),r;try{r=JSON.parse(n.content)}catch{throw Error("MCP config is not valid JSON.")}let s=Object.entries(r.mcpServers??{});if(s.length===0)throw Error("MCP config contains no servers.");let o=We(e,"server");if(!o&&s.length>1)throw Error("MCP config contains multiple servers; select one with --server <name>.");let i=o?s.find(([b])=>b===o):s[0];if(!i)throw Error(`MCP server not found: ${o}`);let[a,c]=i,l=c.type==="http"||c.type==="sse"?c.type:typeof c.command==="string"?"stdio":typeof c.url==="string"?"http":null;if(!l)throw Error(`MCP server ${a} has no supported transport.`);if(l==="stdio"&&e.flags["allow-stdio"]!==!0)throw Error("Stdio MCP servers execute a local command in the cloud; repeat with --allow-stdio.");let p=c.env&&typeof c.env==="object"&&!Array.isArray(c.env)?c.env:{},d=c.headers&&typeof c.headers==="object"&&!Array.isArray(c.headers)?c.headers:{};if(Object.values(d).some((b)=>typeof b!=="string"))throw Error(`MCP server ${a} headers must be strings.`);let u=Object.values(d).flatMap((b)=>[...b.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g)].map((T)=>T[1]));if(Object.keys(d).length>0&&u.length===0)throw Error("MCP remote headers must use ${KEY} placeholders; literal credentials are refused.");let m=/^(?:(?:Bearer|Basic|Token) )?\$\{[A-Za-z_][A-Za-z0-9_]*\}$/i;if(Object.values(d).some((b)=>!m.test(b)))throw Error("MCP remote headers must be ${KEY} or an approved auth scheme followed by ${KEY}.");let w=await e.requireClient().resources.importMcp(t.projectId,{name:a,transport:l,...typeof c.command==="string"?{command:c.command}:{},...Array.isArray(c.args)&&c.args.every((b)=>typeof b==="string")?{args:c.args}:{},...typeof c.url==="string"?{url:c.url}:{},...Object.keys(d).length>0?{headers:d}:{},envKeys:[...new Set([...Object.keys(p),...u])].sort()});return bn(e,En.name,w.mcpServer,`Imported MCP server ${a}`),0}};import{spawnSync as gi}from"node:child_process";import{chmod as hi,realpath as yi,writeFile as wi}from"node:fs/promises";import{basename as vi,dirname as ki,relative as bi,resolve as Yr,sep as Si}from"node:path";var Xr=64;function Xe(e){let t=O(e.cwd),r=(typeof e.flags.project==="string"?e.flags.project:void 0)??t?.config.projectId;if(!r)throw new f("not_initialized","This folder is not bound to a Hlix project. Run `hlix import .`, or pass --project <id>.");return{projectId:r,root:t?.root??e.cwd}}var Ve=(e,t)=>typeof e[t]==="string"?e[t]:void 0,Pn={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(`
129
+ `)}var Sn={name:"skill import",summary:"Activate a local skill for the bound cloud project",usage:"Usage: hlix skill import <SKILL.md|folder> [--name <slug>] [--json]",supportsJson:!0,options:["name"],args:{min:1,max:1},async run(e){if(e.args.length!==1)throw Error("skill import requires one file or folder.");let t=vn(e.cwd),n=wn(e.cwd,e.args[0]),r=await Wr(n);if(r.isSymbolicLink())throw Error(`Refusing to import a symlink: ${n}`);let s=r.isDirectory()?fi(n,"SKILL.md"):n,o=await kn(s,200000),i=r.isDirectory()?yn(n):yn(s)==="SKILL.md"?yn(ui(s)):Vr(s).name,a=We(e,"name")??i;if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(a))throw Error("Skill name must be a lowercase kebab-case slug.");let c=await e.requireClient().resources.importSkill(t.projectId,{slug:a,content:o.content});return bn(e,Sn.name,c.skill,`Imported skill ${a}`),0}},jn={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>] [--json]",supportsJson:!0,options:["name","runtime","duty","profile"],args:{min:1,max:1},async run(e){if(e.args.length!==1)throw Error("agent import requires one Markdown file.");let t=vn(e.cwd),n=wn(e.cwd,e.args[0]);if(![".md",".mdx"].includes(mi(n).toLowerCase()))throw Error("Agent imports must be Markdown files.");let r=await kn(n,20000),s=We(e,"runtime")??"hlix";if(!["claude-code","codex","cursor-agent","hlix"].includes(s))throw Error("--runtime must be claude-code, codex, cursor-agent, or hlix.");let o=We(e,"duty")??"executor";if(o!=="executor"&&o!=="intake")throw Error("--duty must be executor or intake.");let i=We(e,"name")??Vr(n).name.replace(/[-_]+/g," "),a=await e.requireClient().resources.importAgent(t.projectId,{name:i,instructions:r.content,runtimeKind:s,duty:o});return bn(e,jn.name,a.agent,a.agent.duty==="intake"?`Imported agent ${a.agent.name} as this project's intake agent`:`Imported agent ${a.agent.name}`),0}},En={name:"mcp import",summary:"Explicitly activate one validated local MCP server",usage:"Usage: hlix mcp import <.mcp.json> [--server <name>] [--allow-stdio] [--json]",supportsJson:!0,options:["server","allow-stdio"],args:{min:1,max:1},async run(e){if(e.args.length!==1)throw Error("mcp import requires one MCP JSON file.");let t=vn(e.cwd),n=await kn(wn(e.cwd,e.args[0]),200000),r;try{r=JSON.parse(n.content)}catch{throw Error("MCP config is not valid JSON.")}let s=Object.entries(r.mcpServers??{});if(s.length===0)throw Error("MCP config contains no servers.");let o=We(e,"server");if(!o&&s.length>1)throw Error("MCP config contains multiple servers; select one with --server <name>.");let i=o?s.find(([b])=>b===o):s[0];if(!i)throw Error(`MCP server not found: ${o}`);let[a,c]=i,l=c.type==="http"||c.type==="sse"?c.type:typeof c.command==="string"?"stdio":typeof c.url==="string"?"http":null;if(!l)throw Error(`MCP server ${a} has no supported transport.`);if(l==="stdio"&&e.flags["allow-stdio"]!==!0)throw Error("Stdio MCP servers execute a local command in the cloud; repeat with --allow-stdio.");let p=c.env&&typeof c.env==="object"&&!Array.isArray(c.env)?c.env:{},d=c.headers&&typeof c.headers==="object"&&!Array.isArray(c.headers)?c.headers:{};if(Object.values(d).some((b)=>typeof b!=="string"))throw Error(`MCP server ${a} headers must be strings.`);let u=Object.values(d).flatMap((b)=>[...b.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g)].map((T)=>T[1]));if(Object.keys(d).length>0&&u.length===0)throw Error("MCP remote headers must use ${KEY} placeholders; literal credentials are refused.");let m=/^(?:(?:Bearer|Basic|Token) )?\$\{[A-Za-z_][A-Za-z0-9_]*\}$/i;if(Object.values(d).some((b)=>!m.test(b)))throw Error("MCP remote headers must be ${KEY} or an approved auth scheme followed by ${KEY}.");let v=await e.requireClient().resources.importMcp(t.projectId,{name:a,transport:l,...typeof c.command==="string"?{command:c.command}:{},...Array.isArray(c.args)&&c.args.every((b)=>typeof b==="string")?{args:c.args}:{},...typeof c.url==="string"?{url:c.url}:{},...Object.keys(d).length>0?{headers:d}:{},envKeys:[...new Set([...Object.keys(p),...u])].sort()});return bn(e,En.name,v.mcpServer,`Imported MCP server ${a}`),0}};import{spawnSync as gi}from"node:child_process";import{chmod as hi,realpath as yi,writeFile as wi}from"node:fs/promises";import{basename as vi,dirname as ki,relative as bi,resolve as Yr,sep as Si}from"node:path";var Xr=64;function Xe(e){let t=O(e.cwd),r=(typeof e.flags.project==="string"?e.flags.project:void 0)??t?.config.projectId;if(!r)throw new f("not_initialized","This folder is not bound to a Hlix project. Run `hlix import .`, or pass --project <id>.");return{projectId:r,root:t?.root??e.cwd}}var Ve=(e,t)=>typeof e[t]==="string"?e[t]:void 0,Pn={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(`
130
130
  `),supportsJson:!0,options:["project"],async run(e){let{projectId:t}=Xe(e),n=await e.requireClient().secrets.listEntries(t);if(e.json)return e.stdout(y(k(Pn.name,n))),0;if(n.entries.length===0)e.stdout(`No secrets stored for this project.
131
131
  `);else e.stdout(`${W(["key","source","format","value","updated"],n.entries.map((r)=>[r.key,r.source,r.format||"-",r.maskedValue,r.updatedAt?.slice(0,10)??"-"]))}
132
132
  `);for(let r of n.warnings)e.stderr(`warning: ${r}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as C,c as h,e as T,f as p,k as a}from"./index-5wxt3qe0.js";import"./index-rraz48fm.js";import{r as i}from"./index-y1n35st0.js";import{emitKeypressEvents as y}from"node:readline";import{createInterface as u}from"node:readline/promises";async function d(r){if(!process.stdin.isTTY||!process.stdin.setRawMode)throw Error("Interactive login requires a terminal. Set HLIX_API_KEY for CI.");return process.stderr.write(r),y(process.stdin),process.stdin.setRawMode(!0),process.stdin.resume(),new Promise((e,t)=>{let s="",c=()=>{process.stdin.off("keypress",n),process.stdin.setRawMode(!1),process.stdin.pause(),process.stderr.write(`
2
+ import{b as C,c as h,e as T,f as p,k as a}from"./index-benazc7g.js";import"./index-rraz48fm.js";import{r as i}from"./index-y1n35st0.js";import{emitKeypressEvents as y}from"node:readline";import{createInterface as u}from"node:readline/promises";async function d(r){if(!process.stdin.isTTY||!process.stdin.setRawMode)throw Error("Interactive login requires a terminal. Set HLIX_API_KEY for CI.");return process.stderr.write(r),y(process.stdin),process.stdin.setRawMode(!0),process.stdin.resume(),new Promise((e,t)=>{let s="",c=()=>{process.stdin.off("keypress",n),process.stdin.setRawMode(!1),process.stdin.pause(),process.stderr.write(`
3
3
  `)},n=(m,o)=>{if(o.ctrl&&o.name==="c"||o.name==="escape"){c(),t(Error("Login cancelled."));return}if(o.name==="return"||o.name==="enter"){c(),e(s);return}if(o.name==="backspace"){s=s.slice(0,-1);return}if(m&&!o.ctrl)s+=m};process.stdin.on("keypress",n)})}async function l(r,e){if(!process.stdin.isTTY||!process.stderr.isTTY)throw Error("Interactive selection requires a terminal. Pass --workspace <id>.");let t=u({input:process.stdin,output:process.stderr});try{for(let s=0;s<3;s+=1){let c=(await t.question(r)).trim(),n=Number(c);if(Number.isInteger(n)&&n>=1&&n<=e)return n-1;process.stderr.write(`Enter a number between 1 and ${e}.
4
4
  `)}throw Error("No workspace selected.")}finally{t.close()}}async function f(r){if(!process.stdin.isTTY||!process.stderr.isTTY)throw Error("Interactive approval requires a terminal. Review with --dry-run, then pass --yes.");let e=u({input:process.stdin,output:process.stderr});try{let t=(await e.question(`${r}
5
- Continue? [y/N] `)).trim().toLowerCase();return t==="y"||t==="yes"}finally{e.close()}}import{readFileSync as v,realpathSync as w}from"node:fs";import{fileURLToPath as b}from"node:url";function x(){if(i.main==i.module===!0)return!0;let r=process.argv[1];if(!r)return!1;try{return w(r)===w(b(import.meta.url))}catch{return!1}}var g={"-h":"--help","-v":"--version"};function S(r){return r.map((e)=>g[e]??e)}function E(r,e=a){let t=r[0];if(t===void 0)return!1;if(t in g||t==="--help"||t==="--version")return!0;return e.some((s)=>s.name.split(" ")[0]===t)}function P(r,e){if(E(r))return e.cli(S(r));return e.code(r[0]==="code"?r.slice(1):r)}if(x()){let r=await P(process.argv.slice(2),{cli:(e)=>p(a,e,{stdout:(t)=>process.stdout.write(t),stderr:(t)=>process.stderr.write(t),env:process.env,readSecret:d,confirm:f,...process.stdin.isTTY&&process.stderr.isTTY?{promptChoice:l}:{},readStdin:async()=>v(0,"utf8")}),code:async(e)=>{let{version:t}=await import("./package-f3wbdpaa.js");return(await import("./harness-settings-9xpgt0fb.js")).configureHarnessEnvironment({version:t}),(await import("./main-py292c5v.js")).runHlixCode(e)}});process.exit(r)}export{a as COMMANDS,C as JSON_SCHEMA_VERSION,T as clientFor,P as dispatch,h as findProjectBinding,E as isCliInvocation,S as normalizeCliArgv,p as runCli};
5
+ Continue? [y/N] `)).trim().toLowerCase();return t==="y"||t==="yes"}finally{e.close()}}import{readFileSync as v,realpathSync as w}from"node:fs";import{fileURLToPath as b}from"node:url";function x(){if(i.main==i.module===!0)return!0;let r=process.argv[1];if(!r)return!1;try{return w(r)===w(b(import.meta.url))}catch{return!1}}var g={"-h":"--help","-v":"--version"};function S(r){return r.map((e)=>g[e]??e)}function E(r,e=a){let t=r[0];if(t===void 0)return!1;if(t in g||t==="--help"||t==="--version")return!0;return e.some((s)=>s.name.split(" ")[0]===t)}function P(r,e){if(E(r))return e.cli(S(r));return e.code(r[0]==="code"?r.slice(1):r)}if(x()){let r=await P(process.argv.slice(2),{cli:(e)=>p(a,e,{stdout:(t)=>process.stdout.write(t),stderr:(t)=>process.stderr.write(t),env:process.env,readSecret:d,confirm:f,...process.stdin.isTTY&&process.stderr.isTTY?{promptChoice:l}:{},readStdin:async()=>v(0,"utf8")}),code:async(e)=>{let{version:t}=await import("./package-bkxredkn.js");return(await import("./harness-settings-9xpgt0fb.js")).configureHarnessEnvironment({version:t}),(await import("./main-4pat9308.js")).runHlixCode(e)}});process.exit(r)}export{a as COMMANDS,C as JSON_SCHEMA_VERSION,T as clientFor,P as dispatch,h as findProjectBinding,E as isCliInvocation,S as normalizeCliArgv,p as runCli};
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import{a as y,d as _,e as m,f as X,g as A,h as x,i as P,j as ke,k}from"./index-benazc7g.js";import{l as ve,m as Se,n as Ce,o as Ie,p as He}from"./index-rraz48fm.js";import{r as Ct}from"./index-y1n35st0.js";import{relative as It,resolve as Ht}from"node:path";import{parseArgs as Pt}from"node:util";import{createMastraCode as jt}from"mastracode";import{loadMcpConfig as _t}from"@mastra/code-sdk/mcp/config";import{executeSubagent as At}from"@mastra/code-sdk/agents/subagents/execute";import{exploreSubagent as Mt}from"@mastra/code-sdk/agents/subagents/explore";import{planSubagent as Rt}from"@mastra/code-sdk/agents/subagents/plan";import{hasHeadlessFlag as Tt,parseHeadlessArgs as Ot,runMC as $t}from"mastracode/headless";import{MastraTUI as Et}from"mastracode/tui";var Me=[["You are already on the latest version","Update Hlix Code with npm or brew"],["A new version of Mastra Code is available","Hlix Code updates via npm or brew"],["-g mastracode@","-g @hlix/cli@"],["Error: Auth storage not configured","Use hlix models or --sandbox local"],["To use Mastra Code you need at least one API key or OAuth login","Run `hlix auth login`, or add a provider key for your own"],["See https://mastra.ai/models for supported providers and API key env vars.","Your hlix workspace supplies the models; a provider key is optional."],["https://mastra.ai/docs/memory/observational-memory","Observational memory summarizes long threads."],["Manage Mastra Code plugins","Manage Hlix Code plugins"],["Mastra Code","Hlix Code"],["MastraCode","Hlix Code"],["mastracode","hlix"]];function b(e){let t=e;for(let[s,r]of Me)t=t.split(s).join(r);return t}function K(e){let s=e.state?.terminal;if(!s||typeof s.write!=="function")throw Error("Hlix Code cannot rebrand this MastraCode TUI: no `state.terminal.write` to wrap.");let r=s.write.bind(s);s.write=(o)=>r(b(o))}import{mkdirSync as Ne,writeFileSync as Fe}from"node:fs";import{join as G}from"node:path";import{createTool as Re}from"@mastra/core/tools";import{z as u}from"zod";var I=(e)=>`hlix_${e.split(" ").join("_")}`,Te=u.object({args:u.array(u.string()).optional().describe("Positional arguments that follow the command name."),flags:u.record(u.string(),u.union([u.string(),u.boolean()])).optional().describe('Options without the leading dashes, e.g. { "yes": true, "name": "api" }.')}),Oe=u.object({exitCode:u.number(),stdout:u.string(),stderr:u.string()});function $e(e,t,s){let r=e.name.split(" ").concat(t.args??[]);for(let[o,a]of Object.entries(t.flags??{})){if(a===!1)continue;if(r.push(`--${o}`),typeof a==="string")r.push(a)}if(!t.flags?.cwd)r.push("--cwd",s);if(e.supportsJson&&!t.flags?.json)r.push("--json");return r}async function Ee(e,t,s,r=process.env){let o="",a="";return{exitCode:await X([e],$e(e,t,s),{stdout:(c)=>{o+=c},stderr:(c)=>{a+=c},env:r}),stdout:o,stderr:a}}function z(e){let t={};for(let s of e.commands??k){let r=I(s.name);t[r]=Re({id:r,description:`${s.summary}
3
+
4
+ ${s.usage}`,inputSchema:Te,outputSchema:Oe,execute:async(o)=>Ee(s,o,e.cwd,e.env)})}return t}var We=(e)=>`${e.split(" ").join("-")}.md`;function Le(e){return["---",`description: ${e.summary}`,"---","",`Call the tool \`${I(e.name)}\` with the user's arguments: $ARGUMENTS.`,"Show the result.",""].join(`
5
+ `)}var De={"follow.md":["---","description: Watch a cloud task being coded, live","---","","Call the tool `hlix_tasks_follow` with `taskId` set to $ARGUMENTS. It streams the","coder's text and tool calls into this session. Summarise what it did.",""].join(`
6
+ `),"harness.md":["---","description: Show or change the harness — which coder does the work","---","","Call the tool `hlix_harness` with `harness` set to $ARGUMENTS when the user","named one, and with no argument when they did not. Show `message` verbatim.",""].join(`
7
+ `)};function J(e,t=k){let s=G(e,".hlix","commands");Ne(s,{recursive:!0});let r=[],o=[...t.map((a)=>[We(a.name),Le(a)]),...Object.entries(De)];for(let[a,i]of o){let c=G(s,a);try{Fe(c,i,{flag:"wx"}),r.push(c)}catch(n){if(n.code!=="EEXIST")throw n}}return r}import{execFileSync as Ue}from"node:child_process";import{createACPTool as Be}from"@mastra/acp";import{createTool as qe}from"@mastra/core/tools";import{z as h}from"zod";var w={"claude-code":{harness:"claude-code",label:"Claude Code",command:"claude-agent-acp",args:[],authEnvVars:["ANTHROPIC_API_KEY"],install:"npm i -g @agentclientprotocol/claude-agent-acp"},codex:{harness:"codex",label:"Codex",command:"codex-acp",args:[],authEnvVars:["OPENAI_API_KEY"],env:{NO_BROWSER:"1"},install:"npm i -g @agentclientprotocol/codex-acp"},"cursor-agent":{harness:"cursor-agent",label:"Cursor Agent",command:"cursor-agent",args:["acp"],authEnvVars:["CURSOR_API_KEY"],install:"curl https://cursor.com/install -fsS | bash"}};function Z(e){if(e.flag)return{harness:Ye(e.flag,"--harness"),source:"flag"};if(e.configured)return{harness:e.configured,source:e.configSource??"project"};return{harness:P,source:"default"}}function Ye(e,t){if(x.includes(e))return e;throw Error(`${t} must be one of ${x.join(", ")}; got "${e}".`)}var H="hlix_tasks_follow",Ke=(e)=>`hlix_coder_${e.split("-").join("_")}`;function ee(e,t){let s=t.source==="default"?"":` (${t.source==="flag"?"--harness":t.source})`;return`${e} · harness: ${t.harness}${s}`}function te(e,t=3000){try{return Ue("which",[e],{timeout:t,stdio:"ignore"}),!0}catch{return!1}}var j=(e)=>`harness ${e.harness} needs \`${e.command}\` on PATH. Install it with: ${e.install}`;function Xe(e){let t=e.options??[],s=t.find((r)=>r.kind==="allow_once")??t.find((r)=>r.kind==="reject_once");if(!s)return{outcome:{outcome:"cancelled"}};return{outcome:{outcome:"selected",optionId:s.optionId}}}var V=["view","search_content","find_files","file_stat","lsp_inspect"],Q=["ask_user","task_write","task_update","task_complete","task_check"],ze=(e)=>[`harness ${e} runs in the project's Coding Workspace, not on this machine.`,"This session can follow and stream that work, but cannot start it:","which coder the platform uses comes from the project's harness preference,","and this CLI has no command that creates a task."].join(" "),se=(e)=>[e==="unknown"?"This project's harness could not be read from the server. Do NOT guess which coder it runs — say so, and offer to check with the `hlix_harness` tool.":`This project's harness is ${e}: the platform runs ${e} for the coding work it executes, in the project's Coding Workspace.`,"Change it with the `hlix_harness` tool, which writes the project's setting.","","To do coding work here, dispatch it and then watch it:","1. `hlix_cycles_create` with the project id, a title and a description. That"," is what STARTS work — it enters the project's loop, which plans the cycle,"," creates its tasks and starts the coder. It returns no cycle id.","2. `hlix_tasks_list` with that project to find the tasks planning produced.",`3. \`${H}\` with a task id, which streams that coder's own text and`," tool calls into this session live. Report what it did.","","`hlix_tasks_create` only adds a board row; it does not start anything, and","there is no way to start a single task. Never claim otherwise."].join(`
8
+ `),Ge=(e,t)=>[`The user chose the ${e.label} harness. Do not edit files or run commands`,`yourself. Hand the whole task to \`${t}\` as one natural-language brief,`,`then report what it did. ${e.label} reads and writes the same working`,"directory you are in.","",`It authenticates from ${e.authEnvVars.join(" or ")} in this shell's`,"environment. If it reports a credential problem, say so — do not retry."].join(`
9
+ `);function re(e){if(e.sandbox==="cloud"||e.active==="hlix")return[];let t=new Set(e.unavailable??[]),s=e.model?{defaultModelId:e.model}:{},r=[{id:"hlix",name:"Hlix",description:"The hlix agent codes here, with the full toolset.",...s}];for(let o of Object.values(w)){let a=e.active===o.harness,i=Ke(o.harness);r.push({id:o.harness,name:o.label,description:`${o.label} runs on this machine over ACP and edits ${e.cwd}.`,instructions:Ge(o,i),availableTools:t.has(o.harness)?[...V,...Q,H]:[i,...V,...Q,H],...t.has(o.harness)?{}:{additionalTools:{[i]:Be({id:i,description:`Run a coding task with ${o.label}. Give it one natural-language brief; it reads and writes the working directory and returns its final output.`,command:o.command,args:o.args,cwd:e.cwd,...o.env?{env:o.env}:{},...e.workspace?{workspace:e.workspace}:{},onPermissionRequest:async(c)=>Xe(c)})}},...s,...a?{metadata:{default:!0}}:{}})}return r}function Je(e){let t=[...e.available],s=(o,a="none")=>({harness:e.current,available:t,action:a,message:o});if(!e.requested)return s(`harness: ${e.current}. Available here: ${t.join(", ")}.`);if(!x.includes(e.requested))return s(`/harness must name one of ${x.join(", ")}; got "${e.requested}".`);let r=e.requested;if(e.sandbox==="cloud"){let o=`${e.sandboxLine} · harness: ${r} (project preference)`;return{harness:r,available:t,action:"preference",message:r==="hlix"?o:`${o}. ${ze(r)}`}}if(!t.includes(r))return s(j(w[r]));if(!e.modesBuilt)return s(`This session runs the hlix coder, so there is no ${r} mode to switch to. Restart with \`hlix --harness ${r}\`, or make it the default with \`hlix config set harness ${r}\`.`,"restart");return{harness:r,available:t,action:"mode",message:`${e.sandboxLine} · harness: ${r}`}}function oe(e){return qe({id:"hlix_harness",description:"Show or change the harness — which coder does the work. In a local or docker sandbox it switches this session's coder; in a cloud sandbox it writes the project's harness preference, which is what the platform runs. With no argument it reports the current harness.",inputSchema:h.object({harness:h.string().optional().describe(`One of ${x.join(", ")}. Omit to report the current one.`)}),outputSchema:h.object({harness:h.string(),available:h.array(h.string()),message:h.string()}),execute:async(t)=>{let s=e.session(),r=Je({...t.harness?{requested:t.harness}:{},current:s?.mode.get()??P,available:e.available,sandbox:e.sandbox,sandboxLine:e.sandboxLine,modesBuilt:e.modesBuilt}),o={harness:r.harness,available:r.available,message:r.message};if(r.action==="mode"&&s)return await s.mode.switch({modeId:r.harness}),o;if(r.action==="preference"){if(!e.setProjectHarness)return{...o,message:"This folder is not bound to a hlix project, so there is no project preference to write. Run `hlix init` or pass --project <id>."};await e.setProjectHarness(r.harness)}return o}})}import{createTool as Ve}from"@mastra/core/tools";import{writeToolProgress as Qe}from"mastracode/plugin";import{z as p}from"zod";function Ze(e){switch(e.type){case"on_chat_model_stream":return e.delta?{event:"text",text:e.delta}:null;case"reasoning":return e.delta?{event:"text",text:e.delta}:null;case"on_tool_start":return{event:"tool_start",toolName:e.name,args:e.input};case"on_tool_end":return{event:"tool_end",toolName:e.name,result:e.output,isError:et(e.output)};case"error":return{event:"finish",isError:!0,result:e.message};case"done":return{event:"finish",isError:!1};default:return null}}function et(e){return typeof e==="object"&&e!==null&&e.status==="failed"}async function tt(e,t){let s=[],r=[],o="streamed",a="The coder's turn ended.";for await(let i of e){if(i.type==="idle"){o="idle",a="Nothing is being coded right now. The task is not in build or test.";break}if(i.type==="error")o="error",a=i.message;if(i.type==="on_chat_model_stream")s.push(i.delta);if(i.type==="on_tool_start")r.push(i.name);let c=Ze(i);if(c)await t(c)}return{status:o,text:s.join(""),tools:r,message:a}}function ne(e){return Ve({id:"hlix_tasks_follow",description:"Watch a hlix task being coded in the cloud, live. Streams the coder's text and tool calls into this session as they happen, and returns what it did. Use it after a task starts building.",inputSchema:p.object({taskId:p.string().describe("The task to follow.")}),outputSchema:p.object({status:p.enum(["streamed","idle","error","unassigned"]),text:p.string(),tools:p.array(p.string()),message:p.string()}),execute:async(t,s)=>{let r=m(e.env??process.env,{cwd:e.cwd,flags:{}}),o=await r.tasks.get(t.taskId);if(!o.agentId)return{status:"unassigned",text:"",tools:[],message:"No agent has picked this task up yet, so there is no coder to watch. Check `hlix_tasks_get` again once it is building."};return tt(r.projects.observeAgent(o.projectId,o.agentId),(a)=>Qe(s,a))}})}import{buildMode as st}from"@mastra/code-sdk/agents/modes/build";import{fastMode as rt}from"@mastra/code-sdk/agents/modes/explore";import{planMode as ot}from"@mastra/code-sdk/agents/modes/plan";import{setCustomProvidersSource as nt}from"@mastra/code-sdk/agents/model";import{getCustomProviderId as v,loadSettings as at}from"@mastra/code-sdk/onboarding/settings";var S="hlix",ae="default",it=(e)=>`${S}/${e}`;function ct(e){return{name:S,url:`${e.baseUrl.replace(/\/+$/,"")}/v1/api/ai/w/${e.workspaceId}`,apiKey:e.apiKey,models:[...new Set([ae,...e.models??[]])]}}var lt=3000;async function ie(e){let t=_({env:e.env,flags:{},cwd:e.cwd});if(t.conflict||!t.credential||!t.workspaceId)return{};try{return{ids:(await m(e.env,{cwd:e.cwd,flags:{}}).ai.models(t.workspaceId,{signal:AbortSignal.timeout(e.timeoutMs??lt)})).models.map((r)=>r.id)}}catch(s){return{warning:`could not read your workspace's models (${s instanceof Error?s.message:String(s)}). Offering the workspace default only.`}}}function dt(e){let t=e.provider??"",s=v(S);return t===s||t.endsWith(`/${s}`)}function ce(e){let t=e.listAvailableModels.bind(e);return e.listAvailableModels=async()=>(await t()).filter(dt),e}function ut(e){let t=[st,ot,rt];return e?t.map((s)=>({...s,defaultModelId:e})):t}function le(e){let t=_({env:e.env,flags:{},cwd:e.cwd});if(t.conflict||!t.credential||!t.workspaceId)return null;let s=ct({baseUrl:t.baseUrl,workspaceId:t.workspaceId,apiKey:t.credential.apiKey,...e.models?{models:e.models}:{}}),r=v(s.name);return nt(()=>[...at().customProviders.filter((o)=>v(o.name)!==r),s]),{provider:s,modelId:it(ae)}}var de=(e,t)=>e.length>0?[...e]:ut(t),mt=(e)=>new RegExp(`^(?:[^/]+/)?${v(S)}/.+`).test(e);function ue(e){if(e.configured){let t=e.configuredSource??"config";if(!e.cloud||!e.wired||mt(e.configured))return{id:e.configured,source:t};return{id:e.wired.modelId,source:"workspace",notice:`model ${e.configured} from ${t} is not available on the cloud sandbox; using hlix default`}}return e.wired?{id:e.wired.modelId,source:"workspace"}:null}var me=(e,t)=>t?`${e} · model: ${t.id} (${t.source})`:e;import{execFileSync as yt}from"node:child_process";import{DockerSandbox as bt}from"@mastra/docker";import{LocalFilesystem as kt,Workspace as vt}from"@mastra/core/workspace";import{posix as pe}from"node:path";import{MastraFilesystem as pt,MastraSandbox as ht,Workspace as gt}from"@mastra/core/workspace";var ft=600000,xt=["recursive","overwrite","force","maxDepth","extension"];function g(e){let t=e??{},s={};for(let r of xt)if(t[r]!==void 0)s[r]=t[r];return Object.keys(s).length>0?{options:s}:{}}var he=(e)=>e instanceof Date?e:new Date(typeof e==="string"||typeof e==="number"?e:0);class ge extends pt{id;name="RemoteFilesystem";provider="hlix-coding-workspace";basePath;status="ready";client;constructor(e,t){super({name:"RemoteFilesystem"});this.client=e,this.basePath=t.root,this.id=t.id??`hlix-remote-fs:${t.root}`}getInfo(){return{id:this.id,name:this.name,provider:this.provider,status:this.status,metadata:{root:this.basePath}}}resolveAbsolutePath(e){return pe.isAbsolute(e)?e:pe.join(this.basePath,e)}async call(e){let{result:t}=await this.client.fs({...e,encoding:e.encoding??"utf8",path:this.resolveAbsolutePath(e.path)});return t}async readFile(e,t){let r=await this.call({op:"read",path:e,encoding:"base64"}),o=Buffer.from(r.content,r.encoding);return t?.encoding?o.toString(t.encoding):o}async writeFile(e,t,s){await this.call({op:"write",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64",...g(s)})}async appendFile(e,t){await this.call({op:"append",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64"})}async deleteFile(e,t){await this.call({op:"delete",path:e,...g(t)})}async copyFile(e,t,s){await this.call({op:"copy",path:e,dest:this.resolveAbsolutePath(t),...g(s)})}async moveFile(e,t,s){await this.call({op:"move",path:e,dest:this.resolveAbsolutePath(t),...g(s)})}async mkdir(e,t){await this.call({op:"mkdir",path:e,...g(t)})}async rmdir(e,t){await this.call({op:"rmdir",path:e,...g(t)})}async readdir(e,t){return await this.call({op:"readdir",path:e,...g(t)})??[]}async exists(e){return await this.call({op:"exists",path:e})===!0}async stat(e){let t=await this.call({op:"stat",path:e});return{...t,createdAt:he(t.createdAt),modifiedAt:he(t.modifiedAt)}}}var wt=(e)=>`'${e.split("'").join("'\\''")}'`;class fe extends ht{id;name="RemoteSandbox";provider="hlix-coding-workspace";status="ready";client;constructor(e,t){super({name:"RemoteSandbox"});if(this.client=e,this.id=`hlix-remote-sandbox:${t.projectId}`,t.root)this.setWorkingDirectory(t.root)}async start(){}getInfo(){return{id:this.id,name:this.name,provider:this.provider,status:this.status,createdAt:new Date(0)}}async executeCommand(e,t=[],s){let r=[e,...t.map(wt)].join(" "),o=Date.now(),a=s?.cwd??this.workingDirectory,i=await this.client.exec({command:r,...a?{cwd:a}:{},timeoutMs:s?.timeout??ft});return{success:i.exitCode===0,exitCode:i.exitCode,stdout:i.stdout,stderr:i.stderr,executionTimeMs:Date.now()-o,command:e,args:t}}}function xe(e,t){let s=t.root??"/workspace";return new gt({id:`hlix-project:${t.projectId}`,name:"Hlix Coding Workspace",filesystem:new ge(e,{root:s}),sandbox:new fe(e,{projectId:t.projectId,root:s})})}function St(e,t){if(A.includes(e))return e;throw new y("invalid_usage",`${t==="flag"?"--sandbox":"sandbox in .hlix/config.json"} must be one of ${A.join(", ")}; got "${e}".`)}function we(e){if(e.flag){let t=e.flagSource??"flag";return{choice:St(e.flag,t),reason:t==="flag"?`--sandbox ${e.flag}`:"config"}}if(e.projectId)return{choice:"cloud",reason:`project ${e.projectId}`};if(e.dockerAvailable())return{choice:"docker",reason:"auto"};return{choice:"local",reason:"auto"}}var ye=(e)=>`sandbox: ${e.choice} (${e.reason})`;function be(e=3000){try{return yt("docker",["info"],{timeout:e,stdio:"ignore"}),!0}catch{return!1}}function M(e,t){if(e.choice==="local")return;if(e.choice==="cloud"){if(!t.remote||!t.projectId)throw new y("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");return xe(t.remote,{projectId:t.projectId})}let s="/workspace";return new vt({id:"hlix-code-docker",name:"Hlix Code (Docker)",filesystem:new kt({basePath:t.cwd}),...t.skills&&t.skills.length>0?{skills:t.skills}:{},sandbox:new bt({id:"hlix-code",volumes:{[t.cwd]:s},workingDirectory:s})})}var Nt=["Your name is Hlix Code. You are hlix's coding agent.","An earlier line of these instructions calls you Mastra Code — that is the","name of a framework hlix builds on, not your name. Never introduce yourself","as Mastra Code and never offer it as what the user is running. Naming the","underlying framework is fine when the user asks how hlix is implemented."].join(`
10
+ `),Ft=["Hlix Code could not resolve a model.","Run `hlix auth login` to use your workspace's models (no model key of your own needed),","or set your provider's key (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY) to use your own subscription."].join(`
11
+ `),Wt=(e)=>e instanceof Error?e.message:String(e),Lt=["You are running inside Hlix Code, the terminal harness for the hlix control plane.","Every `hlix` CLI command is available to you as a tool named `hlix_<command>`,","with spaces replaced by underscores — `hlix_status`, `hlix_tasks_list`, `hlix_push`.","Use those tools instead of running `hlix` through the shell: they resolve the","folder's workspace binding and credential the same way the CLI does, and they","return the CLI's machine-readable output.","Report a non-zero exit code and its stderr to the user verbatim. Never invent a","project, task or workspace id — read one with a tool first.","","This project's secrets live in the hlix secrets store, not in a file in this","folder: `hlix_secrets_list` shows them keyed by (key, source file) with every","value masked, and `hlix_secrets_set` changes one. When the user asks for a",'local env file, call `hlix_secrets_export` with `{ flags: { out: ".env" } }` —',"it writes the rendered file at mode 0600 and refuses a path git tracks. Do not","repeat an exported secret value back into the conversation."].join(`
12
+ `);function Dt(e){if(!e||e.entries.length===0)return"";let t=e.entries.length,s=new Set(e.entries.map((r)=>r.source)).size;return`secrets: ${t} ${t===1?"entry":"entries"} (${s} ${s===1?"source":"sources"})`}async function Ut(e,t){try{return await m(process.env,{cwd:e,flags:{}}).secrets.listEntries(t)}catch{return null}}function Bt(e){let{values:t}=Pt({args:e,allowPositionals:!0,strict:!1,options:{local:{type:"boolean"},sandbox:{type:"string"},harness:{type:"string"},project:{type:"string"},cwd:{type:"string"}}}),s=typeof t.sandbox==="string"?t.sandbox:t.local===!0?"local":void 0;return{...s?{sandbox:s,sandboxSource:"flag"}:{},...typeof t.harness==="string"?{harness:t.harness}:{},...typeof t.project==="string"?{project:t.project}:{},cwd:Ht(typeof t.cwd==="string"?t.cwd:".")}}function qt(e){let t=Object.keys(w),r=e.sandbox==="cloud"?t:t.filter((n)=>e.installed(n)),o=["hlix",...r],a=t.filter((n)=>!r.includes(n)),i=e.requested.harness;if(i==="hlix"||r.includes(i))return{harness:e.requested,available:o,unavailable:a,refusal:null,warning:null};let c=j(w[i]);if(e.requested.source==="flag")return{harness:e.requested,available:o,unavailable:a,refusal:c,warning:null};return{harness:{harness:"hlix",source:"default"},available:o,unavailable:a,refusal:null,warning:`${c} Falling back to harness hlix.`}}async function Yt(e,t){try{let r=await m(process.env,{cwd:e,flags:{}}).modelConfig.resolvedProjectHarness(t);return{harness:r.harness,source:r.source}}catch{return null}}function Kt(e,t){let s=t.skills&&t.skills.length>0?{skills:t.skills}:{};if(e.choice!=="cloud")return M(e,{cwd:t.cwd,...s});if(!t.projectId)throw new y("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");let o=m(process.env,{cwd:t.cwd,flags:{}}).projects.workspace(t.projectId);return M(e,{cwd:t.cwd,projectId:t.projectId,remote:o})}var R=".hlix";function Xt(e){return e.skills.filter((t)=>!t.harnessReads).map((t)=>t.path)}function zt(e,t){return e.skills.filter((s)=>s.scope==="project").map((s)=>It(t,s.path)).filter((s)=>s!==""&&!s.startsWith(".."))}function Gt(e,t){if(e.length===0)return;let s={explore:"fast",plan:"plan",execute:"build"},r=t.find((n)=>n.metadata?.default===!0)?.id??t.find((n)=>n.id==="build")?.id??t[0]?.id,o=(n)=>t.find((d)=>d.id===s[n])?.defaultModelId??t.find((d)=>d.id===r)?.defaultModelId,a=[Mt,Rt,At].map((n)=>{let d=o(n.id);return{...n,...d?{defaultModelId:d}:{}}}),i=new Set(a.map((n)=>n.id)),c=e.filter((n)=>!i.has(n.name)).map((n)=>{let d=n.model??o("execute");return{id:n.name,name:n.name,description:n.description||`Project subagent from ${n.path}`,instructions:n.instructions,...n.tools?{allowedControllerTools:n.tools}:{},...d?{defaultModelId:d}:{}}});return[...a,...c]}var Jt=new Set(["--sandbox","--harness","--project","--cwd"]),Vt=new Set(["--local"]);function Qt(e){let t=[];for(let s=0;s<e.length;s+=1){let r=e[s];if(Vt.has(r))continue;if(Jt.has(r)){s+=1;continue}t.push(r)}return["node","hlix",...t]}function Zt(e,t,s){return{controller:s.cloud?ce(e.controller):e.controller,session:e.session,...e.hookManager?{hookManager:e.hookManager}:{},...e.mcpManager?{mcpManager:e.mcpManager}:{},...e.pluginManager?{pluginManager:e.pluginManager}:{},...e.knowledgeInspector?{knowledgeInspector:e.knowledgeInspector}:{},...s.cloud?{}:{authStorage:e.authStorage},storageMaintenance:e.storageMaintenance,appName:"Hlix Code",version:t}}async function es(e,t,s,r){let o=Qt(t);if(Tt(o)){let i=Ot(o),n=await $t({controller:e.controller,session:e.session,prompt:i.prompt??"",...i.model?{model:i.model}:{},...i.maxTurns?{maxTurns:i.maxTurns}:{}}).result;if(process.stdout.write(`${n.text}
13
+ `),n.error)process.stderr.write(`${b(n.error.message)}
14
+ `);return n.exitCode}let a=new Et(Zt(e,s,r));return K(a),await a.run(),0}async function cr(e,t={boot:jt,present:es}){let s=Bt(e),r=ke(s.cwd,process.env),o=s.project??r.merged.projectId,a=Se(s.cwd,ve(process.env),{configDir:R}),i,c,n;try{if(c=we({flag:s.sandbox??r.merged.sandbox,flagSource:s.sandbox?"flag":"config",projectId:o,dockerAvailable:()=>be()}),n=qt({requested:Z({...s.harness?{flag:s.harness}:{},...r.merged.harness?{configured:r.merged.harness}:{},...r.sources.harness?{configSource:r.sources.harness}:{}}),sandbox:c.choice,installed:(l)=>te(w[l].command)}),n.refusal)throw new y("invalid_usage",n.refusal);i=Kt(c,{cwd:s.cwd,projectId:o,...c.choice==="docker"?{skills:zt(a,s.cwd)}:{}})}catch(l){return process.stderr.write(`error: ${l instanceof Error?l.message:String(l)}
15
+ `),2}if(n.warning)process.stderr.write(`warning: ${n.warning}
16
+ `);if(c.choice==="cloud"){let l=o?await Yt(s.cwd,o):null;if(l&&s.harness&&s.harness!==l.harness)process.stderr.write(`warning: this project runs ${l.harness}. Run \`/harness ${s.harness}\` to make ${s.harness} the project's setting.
17
+ `);n={...n,harness:l??{harness:"unknown",source:o?"the project's setting could not be read":"no project bound"}}}let d=await ie({cwd:s.cwd,env:process.env});if(d.warning)process.stderr.write(`warning: ${d.warning}
18
+ `);let f=ue({wired:le({cwd:s.cwd,env:process.env,...d.ids?{models:d.ids}:{}}),cloud:c.choice==="cloud",...r.merged.model?{configured:r.merged.model}:{},...r.sources.model?{configuredSource:r.sources.model}:{}});if(f?.notice)process.stderr.write(`warning: ${f.notice}
19
+ `);let T=ye(c);process.stdout.write(`${me(ee(T,n.harness),f)}
20
+ `);let O=He(a);if(O)process.stdout.write(`${O}
21
+ `);let E=o?Dt(await Ut(s.cwd,o)):"";if(E)process.stdout.write(`${E}
22
+ `);J(s.cwd);let N=null,Pe=n.harness.harness==="unknown"?"hlix":n.harness.harness,F=re({sandbox:c.choice,cwd:s.cwd,active:Pe,unavailable:n.unavailable,...i?{workspace:i}:{},...f?{model:f.id}:{}}),je=new Set(Object.keys(_t(s.cwd,R).mcpServers??{})),W=Object.fromEntries(a.mcpServers.filter((l)=>!je.has(l.name)).map((l)=>[l.name,l.config])),L=Ce(a.generatedCommands,s.cwd),D=[...a.commands.map((l)=>l.path),...L?[L]:[]],U=Xt(a),B=de(F,f?.id),q=Gt(a.subagents,B),Y=Ie(a.instructions,s.cwd),{version:_e}=await import("./package-bkxredkn.js"),Ae={configDir:R,cwd:s.cwd,coAuthor:{name:"Hlix Code",email:"noreply@hlix.ai"},hostInstructions:[Nt,Lt,...c.choice==="cloud"?[se(n.harness.harness)]:[],...Y?[Y]:[]].join(`
23
+
24
+ `),...Object.keys(W).length>0?{mcpServers:W}:{},...q?{subagents:q}:{},...D.length>0||U.length>0?{initialState:{pluginCommandPaths:D,pluginSkillPaths:U}}:{},extraTools:{...z({cwd:s.cwd}),hlix_tasks_follow:ne({cwd:s.cwd}),hlix_harness:oe({sandbox:c.choice,sandboxLine:T,available:n.available,modesBuilt:F.length>0,session:()=>N,...o?{setProjectHarness:async(l)=>{await m(process.env,{cwd:s.cwd,flags:{}}).modelConfig.setProjectHarness(o,l)}}:{}})},modes:B,...i?{workspace:i}:{}},C;try{C=await t.boot(Ae)}catch(l){return process.stderr.write(`error: ${b(Wt(l))}
25
+ ${Ft}
26
+ `),2}return N=C.session,t.present(C,e,_e,{cloud:c.choice==="cloud"})}export{Xt as extraSkillPaths,Qt as headlessArgv,Bt as parseHlixCodeArgs,qt as planHarness,cr as runHlixCode,Dt as secretsStatusLine,Gt as standardsSubagents,Zt as tuiOptions,zt as workspaceSkillPaths};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import"./index-y1n35st0.js";var s="@hlix/cli",i="0.4.4",n="SEE LICENSE IN LICENSE",a="Hlix Code and the hlix control-plane CLI.",r=["hlix","cli","agents"],d="https://hlix.ai",p="module",c="./dist/index.js",o={hlix:"./dist/index.js"},l=["dist","skills","LICENSE","THIRD_PARTY_NOTICES"],u={node:">=22.19.0"},b={access:"public"},h={build:"rm -rf dist && bun build src/index.ts --outdir dist --target node --format esm --splitting --packages external --minify --banner '#!/usr/bin/env node'",test:'bun test --isolate src --path-ignore-patterns "**/*.integration.test.ts" --timeout 20000',typecheck:"tsc --noEmit",prepublishOnly:"bun run typecheck && bun run build && bun run test","test:integration":"NODE_ENV=test bun run ../../apps/backend/scripts/with-aimock.ts -- bun run ../../apps/backend/scripts/with-test-db.ts -- bun test --isolate --preload ../../apps/backend/test/helpers/pool-lifecycle.ts --timeout 60000 .integration.test.ts"},m={"@mastra/acp":"^0.4.1","@mastra/code-sdk":"1.7.1","@mastra/core":"1.66.0","@mastra/docker":"^0.7.0",ignore:"7.0.8",mastracode:"0.39.1","openapi-fetch":"^0.17.0",zod:"4.5.4"},g={"@hlix/sdk":"^0.2.0","@types/bun":"latest",typescript:"^7.0.2"},k={name:s,version:i,license:n,description:a,keywords:r,homepage:d,type:p,main:c,bin:o,files:l,engines:u,publishConfig:b,scripts:h,dependencies:m,devDependencies:g};export{o as bin,k as default,m as dependencies,a as description,g as devDependencies,u as engines,l as files,d as homepage,r as keywords,n as license,c as main,s as name,b as publishConfig,h as scripts,p as type,i as version};
2
+ import"./index-y1n35st0.js";var s="@hlix/cli",i="0.4.5",n="SEE LICENSE IN LICENSE",a="Hlix Code and the hlix control-plane CLI.",r=["hlix","cli","agents"],d="https://hlix.ai",p="module",c="./dist/index.js",o={hlix:"./dist/index.js"},l=["dist","skills","LICENSE","THIRD_PARTY_NOTICES"],u={node:">=22.19.0"},b={access:"public"},h={build:"rm -rf dist && bun build src/index.ts --outdir dist --target node --format esm --splitting --packages external --minify --banner '#!/usr/bin/env node'",test:'bun test --isolate src --path-ignore-patterns "**/*.integration.test.ts" --timeout 20000',typecheck:"tsc --noEmit",prepublishOnly:"bun run typecheck && bun run build && bun run test","test:integration":"NODE_ENV=test bun run ../../apps/backend/scripts/with-aimock.ts -- bun run ../../apps/backend/scripts/with-test-db.ts -- bun test --isolate --preload ../../apps/backend/test/helpers/pool-lifecycle.ts --timeout 60000 .integration.test.ts"},m={"@mastra/acp":"^0.4.1","@mastra/code-sdk":"1.7.1","@mastra/core":"1.66.0","@mastra/docker":"^0.7.0",ignore:"7.0.8",mastracode:"0.39.1","openapi-fetch":"^0.17.0",zod:"4.5.4"},g={"@hlix/sdk":"^0.2.0","@types/bun":"latest",typescript:"^7.0.2"},k={name:s,version:i,license:n,description:a,keywords:r,homepage:d,type:p,main:c,bin:o,files:l,engines:u,publishConfig:b,scripts:h,dependencies:m,devDependencies:g};export{o as bin,k as default,m as dependencies,a as description,g as devDependencies,u as engines,l as files,d as homepage,r as keywords,n as license,c as main,s as name,b as publishConfig,h as scripts,p as type,i as version};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hlix/cli",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "Hlix Code and the hlix control-plane CLI.",
6
6
  "keywords": [
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
- import{a as w,d as re,e as h,f as U,g as I,h as f,i as C,j as we,k as b}from"./index-5wxt3qe0.js";import{l as ye,m as be,n as ke,o as ve,p as Se}from"./index-rraz48fm.js";import{r as wt}from"./index-y1n35st0.js";import{relative as yt,resolve as bt}from"node:path";import{parseArgs as kt}from"node:util";import{createMastraCode as vt}from"mastracode";import{loadMcpConfig as St}from"@mastra/code-sdk/mcp/config";import{executeSubagent as Ct}from"@mastra/code-sdk/agents/subagents/execute";import{exploreSubagent as Ht}from"@mastra/code-sdk/agents/subagents/explore";import{planSubagent as It}from"@mastra/code-sdk/agents/subagents/plan";import{hasHeadlessFlag as Pt,parseHeadlessArgs as jt,runMC as _t}from"mastracode/headless";import{MastraTUI as At}from"mastracode/tui";var je=[["You are already on the latest version","Update Hlix Code with npm or brew"],["A new version of Mastra Code is available","Hlix Code updates via npm or brew"],["-g mastracode@","-g @hlix/cli@"],["To use Mastra Code you need at least one API key or OAuth login","Run `hlix auth login`, or add a provider key for your own"],["See https://mastra.ai/models for supported providers and API key env vars.","Your hlix workspace supplies the models; a provider key is optional."],["https://mastra.ai/docs/memory/observational-memory","Observational memory summarizes long threads."],["Manage Mastra Code plugins","Manage Hlix Code plugins"],["Mastra Code","Hlix Code"],["MastraCode","Hlix Code"],["mastracode","hlix"]];function y(e){let t=e;for(let[s,r]of je)t=t.split(s).join(r);return t}function B(e){let s=e.state?.terminal;if(!s||typeof s.write!=="function")throw Error("Hlix Code cannot rebrand this MastraCode TUI: no `state.terminal.write` to wrap.");let r=s.write.bind(s);s.write=(o)=>r(y(o))}import{mkdirSync as Te,writeFileSync as $e}from"node:fs";import{join as Y}from"node:path";import{createTool as _e}from"@mastra/core/tools";import{z as u}from"zod";var v=(e)=>`hlix_${e.split(" ").join("_")}`,Ae=u.object({args:u.array(u.string()).optional().describe("Positional arguments that follow the command name."),flags:u.record(u.string(),u.union([u.string(),u.boolean()])).optional().describe('Options without the leading dashes, e.g. { "yes": true, "name": "api" }.')}),Re=u.object({exitCode:u.number(),stdout:u.string(),stderr:u.string()});function Me(e,t,s){let r=e.name.split(" ").concat(t.args??[]);for(let[o,n]of Object.entries(t.flags??{})){if(n===!1)continue;if(r.push(`--${o}`),typeof n==="string")r.push(n)}if(!t.flags?.cwd)r.push("--cwd",s);if(e.supportsJson&&!t.flags?.json)r.push("--json");return r}async function Oe(e,t,s,r=process.env){let o="",n="";return{exitCode:await U([e],Me(e,t,s),{stdout:(c)=>{o+=c},stderr:(c)=>{n+=c},env:r}),stdout:o,stderr:n}}function q(e){let t={};for(let s of e.commands??b){let r=v(s.name);t[r]=_e({id:r,description:`${s.summary}
3
-
4
- ${s.usage}`,inputSchema:Ae,outputSchema:Re,execute:async(o)=>Oe(s,o,e.cwd,e.env)})}return t}var Ne=(e)=>`${e.split(" ").join("-")}.md`;function Ee(e){return["---",`description: ${e.summary}`,"---","",`Call the tool \`${v(e.name)}\` with the user's arguments: $ARGUMENTS.`,"Show the result.",""].join(`
5
- `)}var Fe={"follow.md":["---","description: Watch a cloud task being coded, live","---","","Call the tool `hlix_tasks_follow` with `taskId` set to $ARGUMENTS. It streams the","coder's text and tool calls into this session. Summarise what it did.",""].join(`
6
- `),"harness.md":["---","description: Show or change the harness — which coder does the work","---","","Call the tool `hlix_harness` with `harness` set to $ARGUMENTS when the user","named one, and with no argument when they did not. Show `message` verbatim.",""].join(`
7
- `)};function K(e,t=b){let s=Y(e,".hlix","commands");Te(s,{recursive:!0});let r=[],o=[...t.map((n)=>[Ne(n.name),Ee(n)]),...Object.entries(Fe)];for(let[n,i]of o){let c=Y(s,n);try{$e(c,i,{flag:"wx"}),r.push(c)}catch(a){if(a.code!=="EEXIST")throw a}}return r}import{execFileSync as We}from"node:child_process";import{createACPTool as Le}from"@mastra/acp";import{createTool as De}from"@mastra/core/tools";import{z as p}from"zod";var x={"claude-code":{harness:"claude-code",label:"Claude Code",command:"claude-agent-acp",args:[],authEnvVars:["ANTHROPIC_API_KEY"],install:"npm i -g @agentclientprotocol/claude-agent-acp"},codex:{harness:"codex",label:"Codex",command:"codex-acp",args:[],authEnvVars:["OPENAI_API_KEY"],env:{NO_BROWSER:"1"},install:"npm i -g @agentclientprotocol/codex-acp"},"cursor-agent":{harness:"cursor-agent",label:"Cursor Agent",command:"cursor-agent",args:["acp"],authEnvVars:["CURSOR_API_KEY"],install:"curl https://cursor.com/install -fsS | bash"}};function G(e){if(e.flag)return{harness:Be(e.flag,"--harness"),source:"flag"};if(e.configured)return{harness:e.configured,source:e.configSource??"project"};return{harness:C,source:"default"}}function Be(e,t){if(f.includes(e))return e;throw Error(`${t} must be one of ${f.join(", ")}; got "${e}".`)}var S="hlix_tasks_follow",Ue=(e)=>`hlix_coder_${e.split("-").join("_")}`;function V(e,t){let s=t.source==="default"?"":` (${t.source==="flag"?"--harness":t.source})`;return`${e} · harness: ${t.harness}${s}`}function J(e,t=3000){try{return We("which",[e],{timeout:t,stdio:"ignore"}),!0}catch{return!1}}var H=(e)=>`harness ${e.harness} needs \`${e.command}\` on PATH. Install it with: ${e.install}`;function qe(e){let t=e.options??[],s=t.find((r)=>r.kind==="allow_once")??t.find((r)=>r.kind==="reject_once");if(!s)return{outcome:{outcome:"cancelled"}};return{outcome:{outcome:"selected",optionId:s.optionId}}}var X=["view","search_content","find_files","file_stat","lsp_inspect"],z=["ask_user","task_write","task_update","task_complete","task_check"],Ye=(e)=>[`harness ${e} runs in the project's Coding Workspace, not on this machine.`,"This session can follow and stream that work, but cannot start it:","which coder the platform uses comes from the project's harness preference,","and this CLI has no command that creates a task."].join(" "),Q=(e)=>[e==="unknown"?"This project's harness could not be read from the server. Do NOT guess which coder it runs — say so, and offer to check with the `hlix_harness` tool.":`This project's harness is ${e}: the platform runs ${e} for the coding work it executes, in the project's Coding Workspace.`,"Change it with the `hlix_harness` tool, which writes the project's setting.","","To do coding work here, dispatch it and then watch it:","1. `hlix_cycles_create` with the project id, a title and a description. That"," is what STARTS work — it enters the project's loop, which plans the cycle,"," creates its tasks and starts the coder. It returns no cycle id.","2. `hlix_tasks_list` with that project to find the tasks planning produced.",`3. \`${S}\` with a task id, which streams that coder's own text and`," tool calls into this session live. Report what it did.","","`hlix_tasks_create` only adds a board row; it does not start anything, and","there is no way to start a single task. Never claim otherwise."].join(`
8
- `),Ke=(e,t)=>[`The user chose the ${e.label} harness. Do not edit files or run commands`,`yourself. Hand the whole task to \`${t}\` as one natural-language brief,`,`then report what it did. ${e.label} reads and writes the same working`,"directory you are in.","",`It authenticates from ${e.authEnvVars.join(" or ")} in this shell's`,"environment. If it reports a credential problem, say so — do not retry."].join(`
9
- `);function Z(e){if(e.sandbox==="cloud"||e.active==="hlix")return[];let t=new Set(e.unavailable??[]),s=e.model?{defaultModelId:e.model}:{},r=[{id:"hlix",name:"Hlix",description:"The hlix agent codes here, with the full toolset.",...s}];for(let o of Object.values(x)){let n=e.active===o.harness,i=Ue(o.harness);r.push({id:o.harness,name:o.label,description:`${o.label} runs on this machine over ACP and edits ${e.cwd}.`,instructions:Ke(o,i),availableTools:t.has(o.harness)?[...X,...z,S]:[i,...X,...z,S],...t.has(o.harness)?{}:{additionalTools:{[i]:Le({id:i,description:`Run a coding task with ${o.label}. Give it one natural-language brief; it reads and writes the working directory and returns its final output.`,command:o.command,args:o.args,cwd:e.cwd,...o.env?{env:o.env}:{},...e.workspace?{workspace:e.workspace}:{},onPermissionRequest:async(c)=>qe(c)})}},...s,...n?{metadata:{default:!0}}:{}})}return r}function Xe(e){let t=[...e.available],s=(o,n="none")=>({harness:e.current,available:t,action:n,message:o});if(!e.requested)return s(`harness: ${e.current}. Available here: ${t.join(", ")}.`);if(!f.includes(e.requested))return s(`/harness must name one of ${f.join(", ")}; got "${e.requested}".`);let r=e.requested;if(e.sandbox==="cloud"){let o=`${e.sandboxLine} · harness: ${r} (project preference)`;return{harness:r,available:t,action:"preference",message:r==="hlix"?o:`${o}. ${Ye(r)}`}}if(!t.includes(r))return s(H(x[r]));if(!e.modesBuilt)return s(`This session runs the hlix coder, so there is no ${r} mode to switch to. Restart with \`hlix --harness ${r}\`, or make it the default with \`hlix config set harness ${r}\`.`,"restart");return{harness:r,available:t,action:"mode",message:`${e.sandboxLine} · harness: ${r}`}}function ee(e){return De({id:"hlix_harness",description:"Show or change the harness — which coder does the work. In a local or docker sandbox it switches this session's coder; in a cloud sandbox it writes the project's harness preference, which is what the platform runs. With no argument it reports the current harness.",inputSchema:p.object({harness:p.string().optional().describe(`One of ${f.join(", ")}. Omit to report the current one.`)}),outputSchema:p.object({harness:p.string(),available:p.array(p.string()),message:p.string()}),execute:async(t)=>{let s=e.session(),r=Xe({...t.harness?{requested:t.harness}:{},current:s?.mode.get()??C,available:e.available,sandbox:e.sandbox,sandboxLine:e.sandboxLine,modesBuilt:e.modesBuilt}),o={harness:r.harness,available:r.available,message:r.message};if(r.action==="mode"&&s)return await s.mode.switch({modeId:r.harness}),o;if(r.action==="preference"){if(!e.setProjectHarness)return{...o,message:"This folder is not bound to a hlix project, so there is no project preference to write. Run `hlix init` or pass --project <id>."};await e.setProjectHarness(r.harness)}return o}})}import{createTool as ze}from"@mastra/core/tools";import{writeToolProgress as Ge}from"mastracode/plugin";import{z as m}from"zod";function Ve(e){switch(e.type){case"on_chat_model_stream":return e.delta?{event:"text",text:e.delta}:null;case"reasoning":return e.delta?{event:"text",text:e.delta}:null;case"on_tool_start":return{event:"tool_start",toolName:e.name,args:e.input};case"on_tool_end":return{event:"tool_end",toolName:e.name,result:e.output,isError:Je(e.output)};case"error":return{event:"finish",isError:!0,result:e.message};case"done":return{event:"finish",isError:!1};default:return null}}function Je(e){return typeof e==="object"&&e!==null&&e.status==="failed"}async function Qe(e,t){let s=[],r=[],o="streamed",n="The coder's turn ended.";for await(let i of e){if(i.type==="idle"){o="idle",n="Nothing is being coded right now. The task is not in build or test.";break}if(i.type==="error")o="error",n=i.message;if(i.type==="on_chat_model_stream")s.push(i.delta);if(i.type==="on_tool_start")r.push(i.name);let c=Ve(i);if(c)await t(c)}return{status:o,text:s.join(""),tools:r,message:n}}function te(e){return ze({id:"hlix_tasks_follow",description:"Watch a hlix task being coded in the cloud, live. Streams the coder's text and tool calls into this session as they happen, and returns what it did. Use it after a task starts building.",inputSchema:m.object({taskId:m.string().describe("The task to follow.")}),outputSchema:m.object({status:m.enum(["streamed","idle","error","unassigned"]),text:m.string(),tools:m.array(m.string()),message:m.string()}),execute:async(t,s)=>{let r=h(e.env??process.env,{cwd:e.cwd,flags:{}}),o=await r.tasks.get(t.taskId);if(!o.agentId)return{status:"unassigned",text:"",tools:[],message:"No agent has picked this task up yet, so there is no coder to watch. Check `hlix_tasks_get` again once it is building."};return Qe(r.projects.observeAgent(o.projectId,o.agentId),(n)=>Ge(s,n))}})}import{buildMode as Ze}from"@mastra/code-sdk/agents/modes/build";import{fastMode as et}from"@mastra/code-sdk/agents/modes/explore";import{planMode as tt}from"@mastra/code-sdk/agents/modes/plan";import{setCustomProvidersSource as st}from"@mastra/code-sdk/agents/model";import{getCustomProviderId as se,loadSettings as rt}from"@mastra/code-sdk/onboarding/settings";var oe="hlix",ne="default",ot=(e)=>`${oe}/${e}`;function nt(e){return{name:oe,url:`${e.baseUrl.replace(/\/+$/,"")}/v1/api/ai/w/${e.workspaceId}`,apiKey:e.apiKey,models:[...new Set([ne,...e.models??[]])]}}function at(e){let t=[Ze,tt,et];return e?t.map((s)=>({...s,defaultModelId:e})):t}function ae(e){let t=re({env:e.env,flags:{},cwd:e.cwd});if(t.conflict||!t.credential||!t.workspaceId)return null;let s=nt({baseUrl:t.baseUrl,workspaceId:t.workspaceId,apiKey:t.credential.apiKey,...e.models?{models:e.models}:{}}),r=se(s.name);return st(()=>[...rt().customProviders.filter((o)=>se(o.name)!==r),s]),{provider:s,modelId:ot(ne)}}var ie=(e,t)=>e.length>0?[...e]:at(t);function ce(e){if(e.configured)return{id:e.configured,source:e.configuredSource??"config"};return e.wired?{id:e.wired.modelId,source:"workspace"}:null}var le=(e,t)=>t?`${e} · model: ${t.id} (${t.source})`:e;import{execFileSync as pt}from"node:child_process";import{DockerSandbox as ht}from"@mastra/docker";import{LocalFilesystem as gt,Workspace as ft}from"@mastra/core/workspace";import{posix as de}from"node:path";import{MastraFilesystem as it,MastraSandbox as ct,Workspace as lt}from"@mastra/core/workspace";var dt=600000,ut=["recursive","overwrite","force","maxDepth","extension"];function g(e){let t=e??{},s={};for(let r of ut)if(t[r]!==void 0)s[r]=t[r];return Object.keys(s).length>0?{options:s}:{}}var ue=(e)=>e instanceof Date?e:new Date(typeof e==="string"||typeof e==="number"?e:0);class me extends it{id;name="RemoteFilesystem";provider="hlix-coding-workspace";basePath;status="ready";client;constructor(e,t){super({name:"RemoteFilesystem"});this.client=e,this.basePath=t.root,this.id=t.id??`hlix-remote-fs:${t.root}`}getInfo(){return{id:this.id,name:this.name,provider:this.provider,status:this.status,metadata:{root:this.basePath}}}resolveAbsolutePath(e){return de.isAbsolute(e)?e:de.join(this.basePath,e)}async call(e){let{result:t}=await this.client.fs({...e,encoding:e.encoding??"utf8",path:this.resolveAbsolutePath(e.path)});return t}async readFile(e,t){let r=await this.call({op:"read",path:e,encoding:"base64"}),o=Buffer.from(r.content,r.encoding);return t?.encoding?o.toString(t.encoding):o}async writeFile(e,t,s){await this.call({op:"write",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64",...g(s)})}async appendFile(e,t){await this.call({op:"append",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64"})}async deleteFile(e,t){await this.call({op:"delete",path:e,...g(t)})}async copyFile(e,t,s){await this.call({op:"copy",path:e,dest:this.resolveAbsolutePath(t),...g(s)})}async moveFile(e,t,s){await this.call({op:"move",path:e,dest:this.resolveAbsolutePath(t),...g(s)})}async mkdir(e,t){await this.call({op:"mkdir",path:e,...g(t)})}async rmdir(e,t){await this.call({op:"rmdir",path:e,...g(t)})}async readdir(e,t){return await this.call({op:"readdir",path:e,...g(t)})??[]}async exists(e){return await this.call({op:"exists",path:e})===!0}async stat(e){let t=await this.call({op:"stat",path:e});return{...t,createdAt:ue(t.createdAt),modifiedAt:ue(t.modifiedAt)}}}var mt=(e)=>`'${e.split("'").join("'\\''")}'`;class pe extends ct{id;name="RemoteSandbox";provider="hlix-coding-workspace";status="ready";client;constructor(e,t){super({name:"RemoteSandbox"});if(this.client=e,this.id=`hlix-remote-sandbox:${t.projectId}`,t.root)this.setWorkingDirectory(t.root)}async start(){}getInfo(){return{id:this.id,name:this.name,provider:this.provider,status:this.status,createdAt:new Date(0)}}async executeCommand(e,t=[],s){let r=[e,...t.map(mt)].join(" "),o=Date.now(),n=s?.cwd??this.workingDirectory,i=await this.client.exec({command:r,...n?{cwd:n}:{},timeoutMs:s?.timeout??dt});return{success:i.exitCode===0,exitCode:i.exitCode,stdout:i.stdout,stderr:i.stderr,executionTimeMs:Date.now()-o,command:e,args:t}}}function he(e,t){let s=t.root??"/workspace";return new lt({id:`hlix-project:${t.projectId}`,name:"Hlix Coding Workspace",filesystem:new me(e,{root:s}),sandbox:new pe(e,{projectId:t.projectId,root:s})})}function xt(e,t){if(I.includes(e))return e;throw new w("invalid_usage",`${t==="flag"?"--sandbox":"sandbox in .hlix/config.json"} must be one of ${I.join(", ")}; got "${e}".`)}function ge(e){if(e.flag){let t=e.flagSource??"flag";return{choice:xt(e.flag,t),reason:t==="flag"?`--sandbox ${e.flag}`:"config"}}if(e.projectId)return{choice:"cloud",reason:`project ${e.projectId}`};if(e.dockerAvailable())return{choice:"docker",reason:"auto"};return{choice:"local",reason:"auto"}}var fe=(e)=>`sandbox: ${e.choice} (${e.reason})`;function xe(e=3000){try{return pt("docker",["info"],{timeout:e,stdio:"ignore"}),!0}catch{return!1}}function P(e,t){if(e.choice==="local")return;if(e.choice==="cloud"){if(!t.remote||!t.projectId)throw new w("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");return he(t.remote,{projectId:t.projectId})}let s="/workspace";return new ft({id:"hlix-code-docker",name:"Hlix Code (Docker)",filesystem:new gt({basePath:t.cwd}),...t.skills&&t.skills.length>0?{skills:t.skills}:{},sandbox:new ht({id:"hlix-code",volumes:{[t.cwd]:s},workingDirectory:s})})}var Rt=["Your name is Hlix Code. You are hlix's coding agent.","An earlier line of these instructions calls you Mastra Code — that is the","name of a framework hlix builds on, not your name. Never introduce yourself","as Mastra Code and never offer it as what the user is running. Naming the","underlying framework is fine when the user asks how hlix is implemented."].join(`
10
- `),Mt=["Hlix Code could not resolve a model.","Run `hlix auth login` to use your workspace's models (no model key of your own needed),","or set your provider's key (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY) to use your own subscription."].join(`
11
- `),Ot=(e)=>e instanceof Error?e.message:String(e),Tt=["You are running inside Hlix Code, the terminal harness for the hlix control plane.","Every `hlix` CLI command is available to you as a tool named `hlix_<command>`,","with spaces replaced by underscores — `hlix_status`, `hlix_tasks_list`, `hlix_push`.","Use those tools instead of running `hlix` through the shell: they resolve the","folder's workspace binding and credential the same way the CLI does, and they","return the CLI's machine-readable output.","Report a non-zero exit code and its stderr to the user verbatim. Never invent a","project, task or workspace id — read one with a tool first.","","This project's secrets live in the hlix secrets store, not in a file in this","folder: `hlix_secrets_list` shows them keyed by (key, source file) with every","value masked, and `hlix_secrets_set` changes one. When the user asks for a",'local env file, call `hlix_secrets_export` with `{ flags: { out: ".env" } }` —',"it writes the rendered file at mode 0600 and refuses a path git tracks. Do not","repeat an exported secret value back into the conversation."].join(`
12
- `);function $t(e){if(!e||e.entries.length===0)return"";let t=e.entries.length,s=new Set(e.entries.map((r)=>r.source)).size;return`secrets: ${t} ${t===1?"entry":"entries"} (${s} ${s===1?"source":"sources"})`}async function Nt(e,t){try{return await h(process.env,{cwd:e,flags:{}}).secrets.listEntries(t)}catch{return null}}function Et(e){let{values:t}=kt({args:e,allowPositionals:!0,strict:!1,options:{local:{type:"boolean"},sandbox:{type:"string"},harness:{type:"string"},project:{type:"string"},cwd:{type:"string"}}}),s=typeof t.sandbox==="string"?t.sandbox:t.local===!0?"local":void 0;return{...s?{sandbox:s,sandboxSource:"flag"}:{},...typeof t.harness==="string"?{harness:t.harness}:{},...typeof t.project==="string"?{project:t.project}:{},cwd:bt(typeof t.cwd==="string"?t.cwd:".")}}function Ft(e){let t=Object.keys(x),r=e.sandbox==="cloud"?t:t.filter((a)=>e.installed(a)),o=["hlix",...r],n=t.filter((a)=>!r.includes(a)),i=e.requested.harness;if(i==="hlix"||r.includes(i))return{harness:e.requested,available:o,unavailable:n,refusal:null,warning:null};let c=H(x[i]);if(e.requested.source==="flag")return{harness:e.requested,available:o,unavailable:n,refusal:c,warning:null};return{harness:{harness:"hlix",source:"default"},available:o,unavailable:n,refusal:null,warning:`${c} Falling back to harness hlix.`}}async function Wt(e,t){try{let r=await h(process.env,{cwd:e,flags:{}}).modelConfig.resolvedProjectHarness(t);return{harness:r.harness,source:r.source}}catch{return null}}function Lt(e,t){let s=t.skills&&t.skills.length>0?{skills:t.skills}:{};if(e.choice!=="cloud")return P(e,{cwd:t.cwd,...s});if(!t.projectId)throw new w("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");let o=h(process.env,{cwd:t.cwd,flags:{}}).projects.workspace(t.projectId);return P(e,{cwd:t.cwd,projectId:t.projectId,remote:o})}var j=".hlix";function Dt(e){return e.skills.filter((t)=>!t.harnessReads).map((t)=>t.path)}function Bt(e,t){return e.skills.filter((s)=>s.scope==="project").map((s)=>yt(t,s.path)).filter((s)=>s!==""&&!s.startsWith(".."))}function Ut(e,t){if(e.length===0)return;let s={explore:"fast",plan:"plan",execute:"build"},r=t.find((a)=>a.metadata?.default===!0)?.id??t.find((a)=>a.id==="build")?.id??t[0]?.id,o=(a)=>t.find((d)=>d.id===s[a])?.defaultModelId??t.find((d)=>d.id===r)?.defaultModelId,n=[Ht,It,Ct].map((a)=>{let d=o(a.id);return{...a,...d?{defaultModelId:d}:{}}}),i=new Set(n.map((a)=>a.id)),c=e.filter((a)=>!i.has(a.name)).map((a)=>{let d=a.model??o("execute");return{id:a.name,name:a.name,description:a.description||`Project subagent from ${a.path}`,instructions:a.instructions,...a.tools?{allowedControllerTools:a.tools}:{},...d?{defaultModelId:d}:{}}});return[...n,...c]}var qt=new Set(["--sandbox","--harness","--project","--cwd"]),Yt=new Set(["--local"]);function Kt(e){let t=[];for(let s=0;s<e.length;s+=1){let r=e[s];if(Yt.has(r))continue;if(qt.has(r)){s+=1;continue}t.push(r)}return["node","hlix",...t]}async function Xt(e,t,s){let r=Kt(t);if(Pt(r)){let n=jt(r),c=await _t({controller:e.controller,session:e.session,prompt:n.prompt??"",...n.model?{model:n.model}:{},...n.maxTurns?{maxTurns:n.maxTurns}:{}}).result;if(process.stdout.write(`${c.text}
13
- `),c.error)process.stderr.write(`${y(c.error.message)}
14
- `);return c.exitCode}let o=new At({controller:e.controller,session:e.session,...e.hookManager?{hookManager:e.hookManager}:{},...e.mcpManager?{mcpManager:e.mcpManager}:{},...e.pluginManager?{pluginManager:e.pluginManager}:{},...e.knowledgeInspector?{knowledgeInspector:e.knowledgeInspector}:{},authStorage:e.authStorage,storageMaintenance:e.storageMaintenance,appName:"Hlix Code",version:s});return B(o),await o.run(),0}async function er(e,t={boot:vt,present:Xt}){let s=Et(e),r=we(s.cwd,process.env),o=s.project??r.merged.projectId,n=be(s.cwd,ye(process.env),{configDir:j}),i,c,a;try{if(c=ge({flag:s.sandbox??r.merged.sandbox,flagSource:s.sandbox?"flag":"config",projectId:o,dockerAvailable:()=>xe()}),a=Ft({requested:G({...s.harness?{flag:s.harness}:{},...r.merged.harness?{configured:r.merged.harness}:{},...r.sources.harness?{configSource:r.sources.harness}:{}}),sandbox:c.choice,installed:(l)=>J(x[l].command)}),a.refusal)throw new w("invalid_usage",a.refusal);i=Lt(c,{cwd:s.cwd,projectId:o,...c.choice==="docker"?{skills:Bt(n,s.cwd)}:{}})}catch(l){return process.stderr.write(`error: ${l instanceof Error?l.message:String(l)}
15
- `),2}if(a.warning)process.stderr.write(`warning: ${a.warning}
16
- `);if(c.choice==="cloud"){let l=o?await Wt(s.cwd,o):null;if(l&&s.harness&&s.harness!==l.harness)process.stderr.write(`warning: this project runs ${l.harness}. Run \`/harness ${s.harness}\` to make ${s.harness} the project's setting.
17
- `);a={...a,harness:l??{harness:"unknown",source:o?"the project's setting could not be read":"no project bound"}}}let d=ce({wired:ae({cwd:s.cwd,env:process.env}),...r.merged.model?{configured:r.merged.model}:{},...r.sources.model?{configuredSource:r.sources.model}:{}}),_=fe(c);process.stdout.write(`${le(V(_,a.harness),d)}
18
- `);let A=Se(n);if(A)process.stdout.write(`${A}
19
- `);let R=o?$t(await Nt(s.cwd,o)):"";if(R)process.stdout.write(`${R}
20
- `);K(s.cwd);let M=null,Ce=a.harness.harness==="unknown"?"hlix":a.harness.harness,O=Z({sandbox:c.choice,cwd:s.cwd,active:Ce,unavailable:a.unavailable,...i?{workspace:i}:{},...d?{model:d.id}:{}}),He=new Set(Object.keys(St(s.cwd,j).mcpServers??{})),T=Object.fromEntries(n.mcpServers.filter((l)=>!He.has(l.name)).map((l)=>[l.name,l.config])),N=ke(n.generatedCommands,s.cwd),E=[...n.commands.map((l)=>l.path),...N?[N]:[]],F=Dt(n),W=ie(O,d?.id),L=Ut(n.subagents,W),D=ve(n.instructions,s.cwd),{version:Ie}=await import("./package-f3wbdpaa.js"),Pe={configDir:j,cwd:s.cwd,coAuthor:{name:"Hlix Code",email:"noreply@hlix.ai"},hostInstructions:[Rt,Tt,...c.choice==="cloud"?[Q(a.harness.harness)]:[],...D?[D]:[]].join(`
21
-
22
- `),...Object.keys(T).length>0?{mcpServers:T}:{},...L?{subagents:L}:{},...E.length>0||F.length>0?{initialState:{pluginCommandPaths:E,pluginSkillPaths:F}}:{},extraTools:{...q({cwd:s.cwd}),hlix_tasks_follow:te({cwd:s.cwd}),hlix_harness:ee({sandbox:c.choice,sandboxLine:_,available:a.available,modesBuilt:O.length>0,session:()=>M,...o?{setProjectHarness:async(l)=>{await h(process.env,{cwd:s.cwd,flags:{}}).modelConfig.setProjectHarness(o,l)}}:{}})},modes:W,...i?{workspace:i}:{}},k;try{k=await t.boot(Pe)}catch(l){return process.stderr.write(`error: ${y(Ot(l))}
23
- ${Mt}
24
- `),2}return M=k.session,t.present(k,e,Ie)}export{Dt as extraSkillPaths,Kt as headlessArgv,Et as parseHlixCodeArgs,Ft as planHarness,er as runHlixCode,$t as secretsStatusLine,Ut as standardsSubagents,Bt as workspaceSkillPaths};