@hlix/cli 0.5.2 → 0.5.3
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 +2 -2
- package/dist/{index-pz2kee3y.js → index-mpmj2yxq.js} +98 -96
- package/dist/index.js +2 -2
- package/dist/main-jdcfzt1f.js +60 -0
- package/dist/{package-wrjj4t8z.js → package-ef5qa8w8.js} +1 -1
- package/package.json +1 -1
- package/skills/hlix/SKILL.md +7 -4
- package/dist/main-n3qsnq1b.js +0 -61
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{y as
|
|
3
|
-
`}function
|
|
2
|
+
import{y as Co}from"./index-f303pf32.js";class h extends Error{code;constructor(e,t){super(t);this.name="CliError",this.code=e}}var lc=1,S=(e,t)=>({schemaVersion:1,command:e,data:t}),_e=(e,t)=>({schemaVersion:1,command:e,error:t});function k(e){return`${JSON.stringify(e,null,2)}
|
|
3
|
+
`}function A(e){let t=Math.max(0,...e.map(([n])=>n.length));return e.map(([n,r])=>`${n.padEnd(t)} ${r}`).join(`
|
|
4
4
|
`)}function Y(e,t){let n=e.map((o,s)=>Math.max(o.length,...t.map((i)=>(i[s]??"").length))),r=(o)=>o.map((s,i)=>s.padEnd(n[i])).join(" ").trimEnd();return[r(e),r(n.map((o)=>"-".repeat(o))),...t.map(r)].join(`
|
|
5
|
-
`)}import{statSync as
|
|
6
|
-
`,"utf8"),
|
|
7
|
-
`,"utf8"),
|
|
5
|
+
`)}import{statSync as po}from"node:fs";import{dirname as uo,resolve as mo}from"node:path";import{closeSync as Ft,constants as Te,existsSync as dt,fsyncSync as gr,lstatSync as Nt,mkdirSync as Zs,openSync as hr,readFileSync as yr,renameSync as Qs,statSync as wr,unlinkSync as vr,writeFileSync as eo}from"node:fs";import{homedir as to}from"node:os";import{dirname as no,join as Lt}from"node:path";function me(e=process.env){let t=e.HLIX_CONFIG_HOME??e.XDG_CONFIG_HOME??Lt(to(),".config");return Lt(t,"hlix","credentials.json")}function kr(e=process.env){let t=e.HLIX_API_KEY;if(!t&&e.HLIX_SESSION_TOKEN)return{baseUrl:e.HLIX_BASE_URL??"https://server.hlix.ai",apiKey:"",sessionToken:e.HLIX_SESSION_TOKEN,...e.HLIX_WORKSPACE_ID?{organizationId:e.HLIX_WORKSPACE_ID}:{}};if(t)return{baseUrl:e.HLIX_BASE_URL??"https://server.hlix.ai",apiKey:t,...e.HLIX_WORKSPACE_ID?{organizationId:e.HLIX_WORKSPACE_ID}:{}};try{let n=JSON.parse(yr(me(e),"utf8"));return n.apiKey&&n.baseUrl?n:null}catch{return null}}function br(e=process.env){let t=me(e);return dt(t)?t:null}function Ht(e=process.env){let t=me(e);if(!dt(t))return{path:t,removed:!1,reason:"absent"};let n=Nt(t);if(n.isSymbolicLink()||!n.isFile())throw Error("Refusing to remove a credential path that is not a regular file.");let r=process.getuid?.();if(r!==void 0&&wr(t).uid!==r)throw Error("Refusing to remove a credential file owned by another user.");let o;try{o=JSON.parse(yr(t,"utf8"))}catch{o=null}let s=o;if(!s||typeof s.apiKey!=="string"||typeof s.baseUrl!=="string")throw Error(`Refusing to remove ${t}: it is not a credential written by this CLI.`);return vr(t),{path:t,removed:!0,reason:"removed"}}function Sr(e,t=process.env){let n=me(t),r=no(n);if(Zs(r,{recursive:!0,mode:448}),Nt(r).isSymbolicLink())throw Error("Refusing to write credentials through a symlinked directory.");if(dt(n)){let i=Nt(n);if(i.isSymbolicLink()||!i.isFile())throw Error("Refusing to replace a credential path that is not a regular file.");let c=process.getuid?.();if(c!==void 0&&wr(n).uid!==c)throw Error("Refusing to replace a credential file owned by another user.")}let o=Lt(r,`.credentials.${process.pid}.${crypto.randomUUID()}.tmp`),s;try{s=hr(o,Te.O_WRONLY|Te.O_CREAT|Te.O_EXCL|Te.O_NOFOLLOW,384),eo(s,`${JSON.stringify(e,null,2)}
|
|
6
|
+
`,"utf8"),gr(s),Ft(s),s=void 0,Qs(o,n);let i=hr(r,Te.O_RDONLY);try{try{gr(i)}catch(c){let a=c.code;if(a!=="EINVAL"&&a!=="ENOTSUP")throw c}}finally{Ft(i)}}catch(i){if(s!==void 0)Ft(s);if(dt(o))vr(o);throw i}return n}import{constants as pt,existsSync as ut,lstatSync as Er,mkdirSync as ro,openSync as so,closeSync as jr,fsyncSync as oo,readFileSync as $r,renameSync as io,unlinkSync as ao,writeFileSync as Mt}from"node:fs";import{dirname as co,join as Oe,resolve as mt}from"node:path";function lo(e){if(!ut(e))return;let t=Er(e);if(t.isSymbolicLink()||!t.isFile())throw Error(`Refusing to replace a non-regular Hlix file: ${e}`)}function Ae(e,t){let n=co(e);if(ro(n,{recursive:!0,mode:448}),Er(n).isSymbolicLink())throw Error(`Refusing to write through a symlinked Hlix directory: ${n}`);lo(e);let r=Oe(n,`.hlix-${process.pid}-${crypto.randomUUID()}.tmp`),o;try{o=so(r,pt.O_WRONLY|pt.O_CREAT|pt.O_EXCL|pt.O_NOFOLLOW,384),Mt(o,`${JSON.stringify(t,null,2)}
|
|
7
|
+
`,"utf8"),oo(o),jr(o),o=void 0,io(r,e)}catch(s){if(o!==void 0)jr(o);if(ut(r))ao(r);throw s}}function Fe(e){return Oe(mt(e),".hlix","config.json")}function Pr(e){return Oe(mt(e),".hlix","state.json")}function fe(e){try{let t=JSON.parse($r(Fe(e),"utf8"));return t.schemaVersion===1&&t.workspaceId&&t.apiUrl?t:null}catch{return null}}function Ne(e,t){Ae(Fe(e),t);let n=Oe(mt(e),".hlix",".gitignore");if(!ut(n))Mt(n,`state.json
|
|
8
8
|
`,{mode:420,flag:"wx"});let r=Oe(mt(e),".hlixignore");if(!ut(r))Mt(r,`# Additional project-local paths to exclude from Hlix snapshots.
|
|
9
|
-
`,{mode:420,flag:"wx"})}function Le(e,t){Ae(
|
|
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
|
|
9
|
+
`,{mode:420,flag:"wx"})}function Le(e,t){Ae(Pr(e),t)}function ft(e){try{let t=JSON.parse($r(Pr(e),"utf8"));return t.schemaVersion===1&&t.revisionId&&t.generation>0?t:null}catch{return null}}var Ut="https://server.hlix.ai";function ht(e){if(!e.credential)return null;if(e.credentialSource==="session")return"session (desktop)";if(e.credentialSource==="env")return"environment (HLIX_API_KEY)";return`file (${e.credentialPath})`}function N(e){let t=mo(e);for(;;){let n=fe(t);if(n)return{root:t,config:n};let r=uo(t);if(r===t)return null;t=r}}function Ir(e){try{return po(e).isDirectory()}catch{return!1}}function gt(e){if(typeof e!=="string")return;let t=e.trim();return t?t:void 0}var Cr=(e,t)=>e.replace(/\/+$/,"")===t.replace(/\/+$/,"");function J(e){let{env:t,flags:n,cwd:r}=e,o=N(r),s=kr(t),i=s?t.HLIX_API_KEY?"env":t.HLIX_SESSION_TOKEN?"session":"file":null,c=i==="file"?s:null,a=gt(n["base-url"]),l=gt(t.HLIX_BASE_URL),u=gt(n.workspace),d=gt(t.HLIX_WORKSPACE_ID),m=a??l??o?.config.apiUrl??c?.baseUrl??Ut,v=a?"flag":l?"env":o?.config.apiUrl?"project":c?.baseUrl?"credential":"default",f=u??d??o?.config.workspaceId??c?.organizationId??null,p=u?"flag":d?"env":o?.config.workspaceId?"project":c?.organizationId?"credential":null;return{baseUrl:m,baseUrlSource:v,workspaceId:f,workspaceSource:p,credential:s,credentialSource:i,credentialPath:me(t),binding:o,conflict:fo(o,{flagBaseUrl:a,envBaseUrl:l,flagWorkspace:u,envWorkspace:d})}}function fo(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&&!Cr(t.flagBaseUrl,e.config.apiUrl))return`${n} ${e.config.apiUrl}, but --base-url names ${t.flagBaseUrl}. ${r}`;if(t.envBaseUrl&&!Cr(t.envBaseUrl,e.config.apiUrl))return`${n} ${e.config.apiUrl}, but HLIX_BASE_URL names ${t.envBaseUrl}. ${r}`;return null}import{resolve as Io}from"node:path";import{parseArgs as xo}from"node:util";import go from"openapi-fetch";function zt(e){return go({baseUrl:e.baseUrl,headers:e.headers,fetch:e.fetch})}var ge=(e)=>({kind:"apiKey",apiKey:e});var Bt=(e)=>({kind:"bearer",token:e});function ho(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 yo(e){return e?{"X-Organization-Id":e}:{}}function xr(e,t){return{...ho(e),...yo(t)}}function wo(e){if(typeof e!=="object"||e===null)return null;let{error:t}=e;return typeof t==="string"?t:null}class D 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 He extends D{issues;constructor(e,t,n){super(e,t);this.issues=n}}class Me extends D{}class Ue extends D{}class ze extends D{}class Be extends D{}class De extends D{}class Ke extends D{retryAfter;constructor(e,t,n){super(e,t);this.retryAfter=n}}class Je extends D{}class Ge extends D{}class he extends Error{method;url;constructor(e,t){super(e,{cause:t.cause});this.name="HlixTransportError",this.method=t.method,this.url=t.url}}function vo(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 ko(e){let t=e.get("retry-after");if(!t)return null;let n=Number(t);return Number.isFinite(n)&&n>=0?n:null}function ye(e,t,n){let r={status:e.status,body:t,requestId:e.headers.get("x-request-id"),method:n.method,url:n.url},o=wo(t),s=`${n.method} ${n.url} failed with ${e.status}`,i=vo(t);if(i)return new He(`${n.method} ${n.url}: request body failed validation`,r,i);let c=o??s;switch(e.status){case 400:return new Me(c,r);case 401:return new Ue(c,r);case 403:return new ze(c,r);case 404:return new Be(c,r);case 409:return new De(c,r);case 429:return new Ke(c,r,ko(e.headers));case 501:return new Je(c,r);default:return e.status>=500?new Ge(c,r):new D(c,r)}}var Rr=new Set(["GET","HEAD","PUT","DELETE","OPTIONS","TRACE"]);function yt(e){return Rr.has(e.toUpperCase())}var bo=new Set([429,500,502,503,504]);function So(e){return bo.has(e)}var Dt={attempts:3,baseDelayMs:200,maxDelayMs:5000};function Kt(e,t,n,r=Math.random){if(n!==null)return Math.min(n*1000,t.maxDelayMs);let o=Math.min(t.baseDelayMs*2**e,t.maxDelayMs);return Math.round(r()*o)}function Jt(e){if(!yt(e.method))return!1;if(e.attempt+1>=e.policy.attempts)return!1;return e.status===null||So(e.status)}var jo=(e)=>new Promise((t)=>setTimeout(t,e));function Eo(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 _r(e){let{base:t,policy:n}=e,r=e.sleep??jo,o=e.random??Math.random;return async(s)=>{let i=s.method.toUpperCase(),c=yt(i)?s.clone():null;for(let a=0;;a+=1){let l=a===0?s:c.clone(),u;try{u=await t(l)}catch(d){if(!c||!Jt({method:i,attempt:a,policy:n,status:null}))throw new he(`${i} ${s.url}: ${d instanceof Error?d.message:String(d)}`,{method:i,url:s.url,cause:d});await r(Kt(a,n,null,o));continue}if(!Jt({method:i,attempt:a,policy:n,status:u.status}))return u;if(!c)return u;await r(Kt(a,n,Eo(u),o))}}}function j(e,t){if(e.response.ok)return e.data;throw ye(e.response,e.error??e.data,t)}var qe=(e)=>typeof e==="string"?e:"";function Gt(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:qe(n.delta)};case"reasoning":return{type:"reasoning",delta:qe(n.delta)};case"on_tool_start":return{type:"on_tool_start",name:qe(n.name),input:n.input};case"on_tool_end":return{type:"on_tool_end",name:qe(n.name),output:n.output};case"error":return{type:"error",message:qe(n.message)};default:return null}}var qt=(e)=>e.type==="done"||e.type==="idle"||e.type==="error";var $o=()=>({event:null,data:[],id:null,retry:null});function Tr(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 Ar(e){let t=e.data.join(`
|
|
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 Or(e,t){if(t==="")return Ar(e);if(t.startsWith(":"))return null;let n=t.indexOf(":");if(n===-1)return Tr(e,t,""),null;let r=t.slice(0,n),o=t.slice(n+1);if(o.startsWith(" "))o=o.slice(1);return Tr(e,r,o),null}function Po(e){let t=[],n=0;for(let r=0;r<e.length;r+=1){let o=e[r];if(o!==`
|
|
11
11
|
`&&o!=="\r")continue;if(t.push(e.slice(n,r)),o==="\r"&&e[r+1]===`
|
|
12
|
-
`)r+=1;n=r+1}return{lines:t,rest:e.slice(n)}}async function*Wt(e,t){let n=e.getReader(),r=new TextDecoder,o=Eo(),s="",i=()=>void n.cancel().catch(()=>{});t?.addEventListener("abort",i,{once:!0});try{for(;;){let{done:a,value:l}=await n.read();if(a)break;s+=r.decode(l,{stream:!0});let{lines:u,rest:d}=$o(s);s=d;for(let m of u){let v=Tr(o,m);if(v)yield v}if(t?.aborted)return}if(s+=r.decode(),s!==""){let a=Tr(o,s);if(a)yield a}let c=Or(o);if(c)yield c}finally{t?.removeEventListener("abort",i),n.releaseLock()}}class we{raw;baseUrl;headers;fetcher;constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.headers=Ir(e.credential,e.organizationId);let t={...Dt,...e.retry},n=e.fetch??((r)=>globalThis.fetch(r));this.fetcher=Rr({base:n,policy:t}),this.raw=zt({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(e,t){return{method:e,url:`${this.baseUrl}${t}`}}workspaces={list:async()=>b(await this.raw.GET("/v1/api/workspaces"),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>b(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(e)=>b(await this.raw.GET("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}`)),create:async(e)=>b(await this.raw.POST("/v1/api/projects",{body:e}),this.at("POST","/v1/api/projects")),delete:async(e)=>b(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("DELETE",`/v1/api/projects/${e}`)),start:async(e,t)=>b(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)=>b(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)=>b(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)=>({environment:async()=>b(await this.raw.GET("/v1/api/projects/{id}/environment",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/environment`)),fs:async(t)=>b(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)=>b(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)=>b(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)=>b(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)=>b(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)=>b(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}`,o=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(!o.ok)throw ye(o,await o.json().catch(()=>{return}),{method:"POST",url:r});return o.text()}};imports={create:async(e)=>{let t=await this.raw.POST("/v1/api/imports",{body:e});return b(t,this.at("POST","/v1/api/imports"))},get:async(e)=>b(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 b(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 o=e.url.startsWith("/")?`${this.baseUrl}${e.url}`:e.url;if(e.kind==="hlix-stream"){let i=new Request(o,{method:"PUT",headers:{...this.headers,"content-type":"application/x-git-bundle","content-length":String(t.size)},body:t,signal:n.signal}),c=await this.fetcher(i);if(!c.ok)await this.throwUploadError(c,o);n.onProgress?.(t.size,t.size);return}let s=0;while(s<t.size){let i=Math.min(s+r,t.size),c=new Request(o,{method:"PUT",headers:{"content-type":"application/x-git-bundle","content-length":String(i-s),"content-range":`bytes ${s}-${i-1}/${t.size}`},body:t.slice(s,i),signal:n.signal}),a=await this.fetcher(c);if(a.status!==308&&!a.ok)await this.throwUploadError(a,o);let l=a.headers.get("range")?.match(/bytes=0-(\d+)/)?.[1];if(s=l?Number(l)+1:i,!Number.isSafeInteger(s)||s<i||s>t.size)throw Error("Import upload server returned an invalid acknowledged range");n.onProgress?.(s,t.size)}}};revisions={head:async(e)=>b(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)=>b(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 b(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 b(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}),o=await this.fetcher(r);if(!o.ok)await this.throwUploadError(o,`${this.baseUrl}${n}`);return o.blob()}};resources={importSkill:async(e,t)=>b(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)=>b(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)=>b(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 ye(e,n,{method:"PUT",url:t})}tasks={list:async(e)=>b(await this.raw.GET("/v1/api/tasks",{params:{query:e??{}}}),this.at("GET","/v1/api/tasks")),get:async(e)=>b(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}`)),create:async(e)=>b(await this.raw.POST("/v1/api/tasks",{body:e}),this.at("POST","/v1/api/tasks")),update:async(e,t)=>b(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:e}},body:t}),this.at("PATCH",`/v1/api/tasks/${e}`)),listComments:async(e)=>b(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)=>b(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)=>b(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)=>b(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)=>b(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)=>b(await this.raw.PUT("/v1/api/model-config/harness",{body:{harness:e}}),this.at("PUT","/v1/api/model-config/harness")),clearHarness:async()=>b(await this.raw.DELETE("/v1/api/model-config/harness"),this.at("DELETE","/v1/api/model-config/harness")),resolvedHarness:async()=>b(await this.raw.GET("/v1/api/model-config/harness/resolved"),this.at("GET","/v1/api/model-config/harness/resolved")),resolvedProjectHarness:async(e)=>b(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)=>b(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)=>b(await this.raw.GET("/v1/api/cycles",{params:{query:e??{}}}),this.at("GET","/v1/api/cycles")),get:async(e)=>b(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/cycles/${e}`)),propose:async(e)=>b(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)=>b(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:e??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(e)=>b(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)=>b(await this.raw.POST("/v1/api/client-billing/invoices",{body:e}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(e)=>b(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)=>b(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)=>b(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={})=>b(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 o of this.stream(r,n)){let s=Gt(o.data);if(!s)continue;if(yield s,qt(s))return}}async*stream(e,t){let n=`${this.baseUrl}${e}`,r=new Request(n,{headers:{...this.headers,accept:"text/event-stream"},signal:t?.signal}),o=await globalThis.fetch(r);if(!o.ok||!o.body){let s=null;try{s=await o.json()}catch{s=null}throw ye(o,s,{method:"GET",url:n})}yield*Wt(o.body,t?.signal)}}function Yt(e){if(e instanceof y)return{code:e.code,status:null};if(e instanceof He)return{code:"invalid_request",status:400};if(e instanceof Me)return{code:"bad_request",status:400};if(e instanceof Ue)return{code:"unauthenticated",status:401};if(e instanceof ze)return{code:"forbidden",status:403};if(e instanceof Be)return{code:"not_found",status:404};if(e instanceof De)return{code:"conflict",status:409};if(e instanceof Ke)return{code:"rate_limited",status:429};if(e instanceof Je)return{code:"not_implemented",status:501};if(e instanceof Ge)return{code:"server_error",status:e.status};if(e instanceof he)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var Vt=(e)=>e instanceof Error?e.message:String(e);function xo(e,t){let n=J({env:e,flags:t.flags,cwd:t.cwd});if(n.conflict)throw new y("workspace_mismatch",n.conflict);if(!n.credential)throw new y("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");return new we({baseUrl:n.baseUrl,credential:n.credential.sessionToken?Bt(n.credential.sessionToken):ge(n.credential.apiKey),...n.workspaceId?{organizationId:n.workspaceId}:{}})}function Ar(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*Wt(e,t){let n=e.getReader(),r=new TextDecoder,o=$o(),s="",i=()=>void n.cancel().catch(()=>{});t?.addEventListener("abort",i,{once:!0});try{for(;;){let{done:a,value:l}=await n.read();if(a)break;s+=r.decode(l,{stream:!0});let{lines:u,rest:d}=Po(s);s=d;for(let m of u){let v=Or(o,m);if(v)yield v}if(t?.aborted)return}if(s+=r.decode(),s!==""){let a=Or(o,s);if(a)yield a}let c=Ar(o);if(c)yield c}finally{t?.removeEventListener("abort",i),n.releaseLock()}}class we{raw;baseUrl;headers;fetcher;constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.headers=xr(e.credential,e.organizationId);let t={...Dt,...e.retry},n=e.fetch??((r)=>globalThis.fetch(r));this.fetcher=_r({base:n,policy:t}),this.raw=zt({baseUrl:this.baseUrl,headers:this.headers,fetch:this.fetcher})}at(e,t){return{method:e,url:`${this.baseUrl}${t}`}}workspaces={list:async()=>j(await this.raw.GET("/v1/api/workspaces"),this.at("GET","/v1/api/workspaces"))};projects={list:async()=>j(await this.raw.GET("/v1/api/projects"),this.at("GET","/v1/api/projects")),get:async(e)=>j(await this.raw.GET("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}`)),create:async(e)=>j(await this.raw.POST("/v1/api/projects",{body:e}),this.at("POST","/v1/api/projects")),delete:async(e)=>j(await this.raw.DELETE("/v1/api/projects/{id}",{params:{path:{id:e}}}),this.at("DELETE",`/v1/api/projects/${e}`)),start:async(e,t)=>j(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)=>j(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)=>j(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)=>({environment:async()=>j(await this.raw.GET("/v1/api/projects/{id}/environment",{params:{path:{id:e}}}),this.at("GET",`/v1/api/projects/${e}/environment`)),fs:async(t)=>j(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)=>j(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)=>j(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)=>j(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)=>j(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)=>j(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}`,o=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(!o.ok)throw ye(o,await o.json().catch(()=>{return}),{method:"POST",url:r});return o.text()}};imports={create:async(e)=>{let t=await this.raw.POST("/v1/api/imports",{body:e});return j(t,this.at("POST","/v1/api/imports"))},get:async(e)=>j(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 j(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 o=e.url.startsWith("/")?`${this.baseUrl}${e.url}`:e.url;if(e.kind==="hlix-stream"){let i=new Request(o,{method:"PUT",headers:{...this.headers,"content-type":"application/x-git-bundle","content-length":String(t.size)},body:t,signal:n.signal}),c=await this.fetcher(i);if(!c.ok)await this.throwUploadError(c,o);n.onProgress?.(t.size,t.size);return}let s=0;while(s<t.size){let i=Math.min(s+r,t.size),c=new Request(o,{method:"PUT",headers:{"content-type":"application/x-git-bundle","content-length":String(i-s),"content-range":`bytes ${s}-${i-1}/${t.size}`},body:t.slice(s,i),signal:n.signal}),a=await this.fetcher(c);if(a.status!==308&&!a.ok)await this.throwUploadError(a,o);let l=a.headers.get("range")?.match(/bytes=0-(\d+)/)?.[1];if(s=l?Number(l)+1:i,!Number.isSafeInteger(s)||s<i||s>t.size)throw Error("Import upload server returned an invalid acknowledged range");n.onProgress?.(s,t.size)}}};revisions={head:async(e)=>j(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)=>j(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 j(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 j(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}),o=await this.fetcher(r);if(!o.ok)await this.throwUploadError(o,`${this.baseUrl}${n}`);return o.blob()}};resources={importSkill:async(e,t)=>j(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)=>j(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)=>j(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 ye(e,n,{method:"PUT",url:t})}tasks={list:async(e)=>j(await this.raw.GET("/v1/api/tasks",{params:{query:e??{}}}),this.at("GET","/v1/api/tasks")),get:async(e)=>j(await this.raw.GET("/v1/api/tasks/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/tasks/${e}`)),create:async(e)=>j(await this.raw.POST("/v1/api/tasks",{body:e}),this.at("POST","/v1/api/tasks")),update:async(e,t)=>j(await this.raw.PATCH("/v1/api/tasks/{id}",{params:{path:{id:e}},body:t}),this.at("PATCH",`/v1/api/tasks/${e}`)),listComments:async(e)=>j(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)=>j(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)=>j(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)=>j(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)=>j(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)=>j(await this.raw.PUT("/v1/api/model-config/harness",{body:{harness:e}}),this.at("PUT","/v1/api/model-config/harness")),clearHarness:async()=>j(await this.raw.DELETE("/v1/api/model-config/harness"),this.at("DELETE","/v1/api/model-config/harness")),resolvedHarness:async()=>j(await this.raw.GET("/v1/api/model-config/harness/resolved"),this.at("GET","/v1/api/model-config/harness/resolved")),resolvedProjectHarness:async(e)=>j(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)=>j(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)=>j(await this.raw.GET("/v1/api/cycles",{params:{query:e??{}}}),this.at("GET","/v1/api/cycles")),get:async(e)=>j(await this.raw.GET("/v1/api/cycles/{id}",{params:{path:{id:e}}}),this.at("GET",`/v1/api/cycles/${e}`)),propose:async(e)=>j(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)=>j(await this.raw.GET("/v1/api/client-billing/invoices",{params:{query:e??{}}}),this.at("GET","/v1/api/client-billing/invoices")),get:async(e)=>j(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)=>j(await this.raw.POST("/v1/api/client-billing/invoices",{body:e}),this.at("POST","/v1/api/client-billing/invoices")),issue:async(e)=>j(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)=>j(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)=>j(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={})=>j(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 o of this.stream(r,n)){let s=Gt(o.data);if(!s)continue;if(yield s,qt(s))return}}async*stream(e,t){let n=`${this.baseUrl}${e}`,r=new Request(n,{headers:{...this.headers,accept:"text/event-stream"},signal:t?.signal}),o=await globalThis.fetch(r);if(!o.ok||!o.body){let s=null;try{s=await o.json()}catch{s=null}throw ye(o,s,{method:"GET",url:n})}yield*Wt(o.body,t?.signal)}}function Yt(e){if(e instanceof h)return{code:e.code,status:null};if(e instanceof He)return{code:"invalid_request",status:400};if(e instanceof Me)return{code:"bad_request",status:400};if(e instanceof Ue)return{code:"unauthenticated",status:401};if(e instanceof ze)return{code:"forbidden",status:403};if(e instanceof Be)return{code:"not_found",status:404};if(e instanceof De)return{code:"conflict",status:409};if(e instanceof Ke)return{code:"rate_limited",status:429};if(e instanceof Je)return{code:"not_implemented",status:501};if(e instanceof Ge)return{code:"server_error",status:e.status};if(e instanceof he)return{code:"unreachable",status:null};return{code:"unknown",status:null}}var Vt=(e)=>e instanceof Error?e.message:String(e);function Ro(e,t){let n=J({env:e,flags:t.flags,cwd:t.cwd});if(n.conflict)throw new h("workspace_mismatch",n.conflict);if(!n.credential)throw new h("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");return new we({baseUrl:n.baseUrl,credential:n.credential.sessionToken?Bt(n.credential.sessionToken):ge(n.credential.apiKey),...n.workspaceId?{organizationId:n.workspaceId}:{}})}function Fr(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]
|
|
@@ -39,33 +39,33 @@ Hlix Code (hlix with no command):
|
|
|
39
39
|
A command targets the workspace named by, in order: an explicit flag, the
|
|
40
40
|
HLIX_* environment, the nearest .hlix/config.json, then the stored credential.
|
|
41
41
|
Run \`hlix status\` to see which one applied.
|
|
42
|
-
`}function
|
|
43
|
-
Did you mean --${c.name}?`:n}function
|
|
44
|
-
`);return 2}let o=r.values.json===!0,s=r.positionals;if(r.values.version===!0){let{version:
|
|
45
|
-
`),0}if(s.length===0||r.values.help===!0){let
|
|
46
|
-
`:
|
|
47
|
-
Did you mean \`hlix ${O}\`?`:`Unknown command: ${
|
|
42
|
+
`}function Lr(e,t){let n=[...Array(t.length+1).keys()];for(let r=1;r<=e.length;r+=1){let o=[r];for(let s=1;s<=t.length;s+=1)o[s]=Math.min(n[s]+1,o[s-1]+1,n[s-1]+(e[r-1]===t[s-1]?0:1));n=o}return n[t.length]}function _o(e,t,n){let r=/Unknown option '--([^'=]+)/.exec(n)?.[1];if(!r)return n;let o=t.findIndex((a)=>a.startsWith("-")),s=o===-1?t:t.slice(0,o),i=new Set(["json","help","version","cwd","workspace","base-url",...Xt(e,s)?.command.options??[]]),c=null;for(let a of i){let l=Lr(r,a);if(l<=2&&(!c||l<c.distance))c={name:a,distance:l}}return c?`${n}
|
|
43
|
+
Did you mean --${c.name}?`:n}function Nr(e,t){let n=new Set;for(let o of e)n.add(o.name),n.add(o.name.split(" ")[0]);let r=null;for(let o of n){let s=Lr(t,o);if(s<=2&&(!r||s<r.distance))r={name:o,distance:s}}return r?r.name:null}function Xt(e,t){for(let n of[...e].sort((r,o)=>o.name.length-r.name.length)){let r=n.name.split(" ");if(r.every((o,s)=>t[s]===o))return{command:n,rest:t.slice(r.length)}}return null}async function nl(e,t,n){if(t.some((b)=>b==="--api-key"||b.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=xo({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(b){let O=t.includes("--json"),L=_o(e,t,Vt(b));if(O)n.stdout(k(_e("cli",{code:"invalid_usage",message:L,status:null})));else n.stderr(`${L}
|
|
44
|
+
`);return 2}let o=r.values.json===!0,s=r.positionals;if(r.values.version===!0){let{version:b}=await import("./package-ef5qa8w8.js");return n.stdout(`${b}
|
|
45
|
+
`),0}if(s.length===0||r.values.help===!0){let b=Xt(e,s);return n.stdout(b?`${b.command.usage}
|
|
46
|
+
`:Fr(e)),s.length===0&&r.values.help!==!0?1:0}let i=Xt(e,s);if(!i){let b=s.join(" "),O=Nr(e,b)??Nr(e,s[0]),L=O?`Unknown command: ${b}
|
|
47
|
+
Did you mean \`hlix ${O}\`?`:`Unknown command: ${b}`;if(o)n.stdout(k(_e(b,{code:"unknown_command",message:L,status:null})));else n.stderr(`${L}
|
|
48
48
|
|
|
49
|
-
${
|
|
49
|
+
${Fr(e)}`);return 2}let c=new Set(["json","help","version","cwd","workspace","base-url"]),a=new Set(i.command.options??[]),l=Object.entries(r.values).filter(([b,O])=>O!==void 0&&!c.has(b)&&!a.has(b)).map(([b])=>`--${b}`),u=i.command.args??{min:0,max:0},d=i.rest.length<u.min?{code:"missing_argument",message:i.command.usage.split(`
|
|
50
50
|
`)[0]}:i.rest.length>u.max?{code:"invalid_usage",message:i.command.usage.split(`
|
|
51
|
-
`)[0]}:null,m=typeof r.values.cwd==="string"?r.values.cwd:void 0,v=
|
|
51
|
+
`)[0]}:null,m=typeof r.values.cwd==="string"?r.values.cwd:void 0,v=Io(m??"."),f=m!==void 0&&!Ir(v)?{code:"invalid_usage",message:`--cwd is not a directory: ${v}`}:null,p=l.length>0?{code:"invalid_usage",message:`Unsupported option for ${i.command.name}: ${l.join(", ")}`}:f??d;if(p){if(o)n.stdout(k(_e(i.command.name,{...p,status:null})));else{let b=i.command.usage.startsWith(p.message)?i.command.usage:`${p.message}
|
|
52
52
|
|
|
53
|
-
${i.command.usage}`;n.stderr(`error: ${
|
|
54
|
-
`)}return 2}let g=r.values,x={...n,args:i.rest,json:o,flags:g,cwd:v,requireClient:(
|
|
55
|
-
`);return O==="unauthenticated"||O==="forbidden"?3:1}}import{readFileSync as
|
|
53
|
+
${i.command.usage}`;n.stderr(`error: ${b}
|
|
54
|
+
`)}return 2}let g=r.values,x={...n,args:i.rest,json:o,flags:g,cwd:v,requireClient:(b)=>Ro(n.env,{cwd:b??v,flags:g})};try{return await i.command.run(x)}catch(b){let{code:O,status:L}=Yt(b);if(o)n.stdout(k(_e(i.command.name,{code:O,message:Vt(b),status:L})));else n.stderr(`error: ${Vt(b)}
|
|
55
|
+
`);return O==="unauthenticated"||O==="forbidden"?3:1}}import{readFileSync as To}from"node:fs";import{homedir as Oo}from"node:os";import{join as Ao}from"node:path";var Mr=20000;function Fo(e){if(e===void 0)return;let t=typeof e==="number"?e:Number(e.trim());return Number.isInteger(t)&&t>=Mr?t:void 0}var Hr=["cloud","docker","local"],ve=["claude-code","codex","cursor-agent","hlix"],ul="hlix",Ur={dockerImage:"docker sandbox only",harness:"local and docker sandboxes only",memoryTokens:"all sandboxes",model:"local and docker sandboxes only",sandbox:"all sandboxes",yolo:"all sandboxes"},ke=["dockerImage","harness","memoryTokens","model","sandbox","yolo"],Zt=["projectId","workspaceId","apiUrl"];function Qt(e=process.env){return Ao(e.HLIX_CONFIG_HOME??Oo(),".hlix","config.json")}function zr(e=process.env){try{let t=JSON.parse(To(Qt(e),"utf8"));return t.schemaVersion===1?t:null}catch{return null}}function en(e,t=process.env){let n=zr(t),r=N(e),o=r?.root??null,s=r?.config??null,i={},c={},a=(l)=>{let u=s?.[l],d=n?.[l];if(u!==void 0)i[l]=u,c[l]="project";else if(d!==void 0)i[l]=d,c[l]="global"};for(let l of ke)a(l);for(let l of Zt){let u=s?.[l];if(u!==void 0)i[l]=u,c[l]="project"}return{merged:i,sources:c,global:n,project:s,paths:{global:Qt(t),project:o?Fe(o):null}}}function Br(e){return[...ke,...Zt].map((n)=>({key:n,value:e.merged[n]??null,source:e.sources[n]??"default"}))}function No(e,t){if(e==="sandbox"&&!Hr.includes(t))return`sandbox must be one of ${Hr.join(", ")}; got "${t}".`;if(e==="harness"&&!ve.includes(t))return`harness must be one of ${ve.join(", ")}; got "${t}".`;if(e==="model"&&t.trim()==="")return"model must not be empty.";if(e==="memoryTokens"&&Fo(t)===void 0)return`memoryTokens must be a whole number of tokens, at least ${Mr}; got "${t}".`;if(e==="dockerImage"&&t.trim()==="")return"dockerImage must not be empty.";if(e==="yolo"&&Lo(t)===void 0)return`yolo must be true or false; got "${t}".`;return null}function Lo(e){if(e===void 0)return;let t=e.trim().toLowerCase();if(["true","1","yes","on"].includes(t))return!0;if(["false","0","no","off"].includes(t))return!1;return}function tn(e){if(ke.includes(e))return e;let t=Zt.includes(e);throw new h("invalid_usage",t?`${e} is written by \`hlix init\` and \`hlix import\`, not by \`hlix config set\`.`:`Unknown setting: ${e}. Known settings: ${ke.join(", ")}.`)}function Dr(e,t){let n=No(e,t);if(n)throw new h("invalid_usage",n);return t}function Kr(e){if(e.scope==="global"){let r=Qt(e.env),o=zr(e.env)??{schemaVersion:1};return Ae(r,{...o,[e.key]:e.value}),r}let t=N(e.cwd);if(!t)throw new h("not_initialized","This folder is not bound to hlix. Run `hlix init` here, or set it machine-wide with --global.");let n=Fe(t.root);return Ae(n,{...t.config,[e.key]:e.value}),n}import{createHash as Ho}from"node:crypto";import{mkdirSync as Mo,readdirSync as Vr,readFileSync as Uo,rmSync as zo,statSync as Xr,writeFileSync as Bo}from"node:fs";import{homedir as Do,tmpdir as Ko}from"node:os";import{basename as Yr,isAbsolute as Jo,join as I,relative as Go}from"node:path";var wt=(e=process.env)=>e.HOME??e.USERPROFILE??Do();function z(e){try{if(!Xr(e).isFile())return null;return Uo(e,"utf8")}catch{return null}}function qo(e){try{return Xr(e).isDirectory()}catch{return!1}}function Ve(e,t){try{return Vr(e,{withFileTypes:!0}).filter((n)=>n.isFile()&&n.name.endsWith(t)).map((n)=>I(e,n.name)).sort()}catch{return[]}}function Wo(e){try{return Vr(e,{withFileTypes:!0}).filter((t)=>t.isDirectory()||t.isSymbolicLink()).map((t)=>I(e,t.name)).sort()}catch{return[]}}function rn(e){let t=e.replace(/^\uFEFF/,""),n=t.indexOf(`
|
|
56
56
|
`);if(!t.startsWith("---")||n===-1)return{fields:{},body:t.trim()};let r=t.indexOf(`
|
|
57
57
|
---`,n);if(r===-1)return{fields:{},body:t.trim()};let o={};for(let i of t.slice(n+1,r).split(`
|
|
58
58
|
`)){let c=/^([A-Za-z_][\w-]*)\s*:\s*(.*)$/.exec(i);if(!c)continue;o[c[1]]=c[2].trim().replace(/^["']|["']$/g,"")}let s=t.indexOf(`
|
|
59
|
-
`,r+1);return{fields:o,body:s===-1?"":t.slice(s+1).trim()}}function
|
|
60
|
-
`);if(t.startsWith("["))return[...t.matchAll(/"((?:[^"\\]|\\.)*)"|'([^']*)'/g)].map((o)=>o[1]??o[2]??"");if(t.startsWith("{")){let o={};for(let s of t.matchAll(/([A-Za-z0-9_.-]+)\s*=\s*"((?:[^"\\]|\\.)*)"/g))o[s[1]]=s[2].replace(/\\"/g,'"');return o}let r=/^[^\s#]+/.exec(t)?.[0];if(r===void 0)return;if(r==="true"||r==="false")return r==="true";if(/^-?\d+(\.\d+)?$/.test(r))return Number(r);return r}function
|
|
59
|
+
`,r+1);return{fields:o,body:s===-1?"":t.slice(s+1).trim()}}function Vo(e){let t=e.trimStart(),n=/^"((?:[^"\\]|\\.)*)"/.exec(t)??/^'([^']*)'/.exec(t);if(n)return n[1].replace(/\\"/g,'"').replace(/\\n/g,`
|
|
60
|
+
`);if(t.startsWith("["))return[...t.matchAll(/"((?:[^"\\]|\\.)*)"|'([^']*)'/g)].map((o)=>o[1]??o[2]??"");if(t.startsWith("{")){let o={};for(let s of t.matchAll(/([A-Za-z0-9_.-]+)\s*=\s*"((?:[^"\\]|\\.)*)"/g))o[s[1]]=s[2].replace(/\\"/g,'"');return o}let r=/^[^\s#]+/.exec(t)?.[0];if(r===void 0)return;if(r==="true"||r==="false")return r==="true";if(/^-?\d+(\.\d+)?$/.test(r))return Number(r);return r}function Zr(e){let t={"":{}},n="",r=e.split(`
|
|
61
61
|
`);for(let o=0;o<r.length;o+=1){let i=r[o].trim();if(!i||i.startsWith("#"))continue;let c=/^\[\[?([^\]]+)\]\]?$/.exec(i);if(c){n=c[1].trim(),t[n]??={};continue}let a=/^([A-Za-z0-9_.-]+|"[^"]+")\s*=\s*(.*)$/.exec(i);if(!a)continue;let l=a[1].replace(/^"|"$/g,""),u=a[2];if(u.startsWith('"""')){let m=[],v=u.slice(3);if(v.includes('"""'))m.push(v.slice(0,v.indexOf('"""')));else{if(v)m.push(v);while(o+1<r.length){o+=1;let f=r[o],p=f.indexOf('"""');if(p===-1){m.push(f);continue}m.push(f.slice(0,p));break}}t[n][l]=m.join(`
|
|
62
|
-
`).replace(/^\n/,"");continue}let d=
|
|
63
|
-
`)}var
|
|
64
|
-
description: ${
|
|
62
|
+
`).replace(/^\n/,"");continue}let d=Vo(u);if(d!==void 0)t[n][l]=d}return t}function nn(e,t){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(n,r,o)=>{let s=t[r];return s!==void 0&&s!==""?s:o??""})}var Jr=(e,t)=>{let n={};for(let[r,o]of Object.entries(e))if(typeof o==="string")n[r]=nn(o,t);return n},Xo=[{relative:"GEMINI.md",source:"gemini"},{relative:I(".gemini","GEMINI.md"),source:"gemini"},{relative:".cursorrules",source:"cursor"},{relative:".windsurfrules",source:"windsurf"},{relative:I(".github","copilot-instructions.md"),source:"copilot"}],Yo=[{relative:I(".gemini","GEMINI.md"),source:"gemini"}],Zo=[{relative:I(".cursor","rules"),source:"cursor",extension:".mdc"},{relative:I(".windsurf","rules"),source:"windsurf",extension:".md"}];function Qo(e,t){let n=I(e,".clinerules"),r=qo(n)?Ve(n,".md"):[n],o=[];for(let s of r){let i=z(s)?.trim();if(i)o.push({path:s,source:"cline",scope:t,content:i})}return o}function ei(e,t,n){let{fields:r,body:o}=rn(t);if(r.alwaysApply==="false")return{path:e,source:"cursor",scope:n,reason:"alwaysApply: false"};if(!o)return{path:e,source:"cursor",scope:n,reason:"no rule body"};let s=r.globs?.replace(/^\[|\]$/g,"").trim();return{path:e,source:"cursor",scope:n,content:o,...s?{note:`Applies to: ${s}`}:{}}}var ti=["AGENTS.md","CLAUDE.md"],Qr=["",".claude"],wl=["commands"];function ni(e,t){let n=[],r=new Set;for(let o of[...Qr,t])for(let s of ti){let i=I(e,o,s),c=z(i)?.trim();if(!c||r.has(c))continue;r.add(c),n.push({path:i,content:c})}return n}function Gr(e,t){return ni(e,t).map((n)=>n.content)}var sn=["AGENTS.md","CLAUDE.md","GEMINI.md"];function on(e,t){for(let n of sn)for(let r of[...Qr,t]){let o=I(e,r,n),s=z(o)?.trim();if(s)return{path:o,content:s}}return null}var an=(e=process.env)=>I(e.HLIX_CONFIG_HOME??I(wt(e),".hlix"),"AGENTS.md");function es(e){let t=e.env??process.env,n=an(t),r=z(n)?.trim();return{global:r?{path:n,content:r}:null,project:on(e.cwd,e.configDir)}}var qr=(e)=>{let t=Math.round(e.length/4);return t>=1000?`${(t/1000).toFixed(1)}k tokens`:`${t} tokens`};function vl(e,t,n=process.env){let r=[...e.global?[ss(e.global.path,n)]:[],...e.project?[Xe(e.project.path,t)]:[]];return r.length===0?"":`rules: ${r.join(" + ")}`}function ts(e,t,n=process.env,r=[]){let o=(s,i,c)=>i?`${s.padEnd(8)} ${c(i.path)} (${qr(i.content)})`:`${s.padEnd(8)} none`;return[o("user",e.global,(s)=>ss(s,n)),o("project",e.project,(s)=>Xe(s,t)),...r.map((s)=>`${"nested".padEnd(8)} ${Xe(s.path,t)} (${qr(s.content)})`),"","User rules go first, the project's after, so the project wins a conflict.",r.length===0?"A subdirectory's own rules file is added when the agent first works in it.":"A nested file was added when the agent first touched a path under it.","Edit them with `hlix rules --edit` (this project) or `hlix rules --edit --global`."].join(`
|
|
63
|
+
`)}var ri=[{dir:".claude",source:"claude",harnessReads:!0},{dir:".agents",source:"agents",harnessReads:!0},{dir:".hlix",source:"hlix",harnessReads:!0},{dir:".codex",source:"codex",harnessReads:!1}],si=[{relative:I(".cursor","commands"),source:"cursor"},{relative:I(".codex","prompts"),source:"codex"}],oi=[{relative:I(".cursor","mcp.json"),source:"cursor",key:"mcpServers",format:"json"},{relative:I(".windsurf","mcp.json"),source:"windsurf",key:"mcpServers",format:"json"},{relative:I(".gemini","settings.json"),source:"gemini",key:"mcpServers",format:"json"},{relative:I(".vscode","mcp.json"),source:"vscode",key:"servers",format:"json"},{relative:I(".codex","config.toml"),source:"codex",key:"mcp_servers",format:"toml"},{relative:".mcp.json",source:"claude",key:"mcpServers",format:"json"}];function ns(e){return[...oi,{relative:I(e,"mcp.json"),source:"hlix",key:"mcpServers",format:"json"}]}var ii="found, not loaded (machine-wide; enable per project by copying into .hlix/mcp.json)",ai=(e)=>ns(e).filter((t)=>t.source!=="vscode");function ci(e,t){if(!e||typeof e!=="object"||Array.isArray(e))return{reason:"not an object"};let n=e;if(n.enabled===!1||n.disabled===!0)return{reason:"disabled"};let r=typeof n.command==="string"&&n.command!=="",o=typeof n.url==="string"&&n.url!=="";if(r&&o)return{reason:'has both "command" and "url"'};if(r){let a=Array.isArray(n.args)?n.args.filter((u)=>typeof u==="string"):void 0,l=n.env&&typeof n.env==="object"&&!Array.isArray(n.env)?Jr(n.env,t):void 0;return{config:{command:n.command,...a&&a.length>0?{args:a}:{},...l&&Object.keys(l).length>0?{env:l}:{}}}}if(!o)return{reason:'missing "command" or "url"'};let s=n.headers??n.http_headers,i=s&&typeof s==="object"&&!Array.isArray(s)?Jr(s,t):{},c=n.bearer_token_env_var;if(typeof c==="string"&&/^[A-Za-z_][A-Za-z0-9_]*$/.test(c)&&!Object.keys(i).some((a)=>a.toLowerCase()==="authorization"))i.Authorization=`Bearer ${nn(`\${${c}}`,t)}`;return{config:{url:nn(n.url,t),...Object.keys(i).length>0?{headers:i}:{}}}}function Wr(e,t,n,r){let o=z(e),s=[],i=[];if(o===null)return{servers:s,skipped:i};let c=[];if(t.format==="toml"){let a=Zr(o);c=Object.entries(a).filter(([l])=>l.startsWith(`${t.key}.`)).map(([l,u])=>[l.slice(t.key.length+1),u])}else try{let l=JSON.parse(o)?.[t.key];if(l&&typeof l==="object"&&!Array.isArray(l))c=Object.entries(l)}catch{return i.push({path:e,source:t.source,scope:n,reason:"not valid JSON"}),{servers:s,skipped:i}}for(let[a,l]of c){let u=ci(l,r);if("reason"in u){i.push({path:e,source:t.source,scope:n,reason:`${a}: ${u.reason}`});continue}s.push({path:e,source:t.source,scope:n,name:a,config:u.config})}return{servers:s,skipped:i}}function li(e,t,n){let{fields:r,body:o}=rn(t);if(!o)return{path:e,source:"claude",scope:n,reason:"no instructions"};let s=r.tools?.replace(/^\[|\]$/g,"").split(",").map((i)=>i.trim()).filter(Boolean);return{path:e,source:"claude",scope:n,name:r.name||Yr(e,".md"),description:r.description??"",instructions:o,...s&&s.length>0&&s[0]!=="*"?{tools:s}:{},...r.model?{model:r.model}:{}}}function di(e){let t=Zr(e)[""]??{},n=typeof t.prompt==="string"?t.prompt.trim():"";if(!n)return null;return{description:typeof t.description==="string"?t.description:"",body:n}}function rs(e,t,n={}){let r=n.configDir??".hlix",o=n.env??process.env,s={instructions:[],skills:[],commands:[],generatedCommands:[],mcpServers:[],subagents:[],skipped:[]},i=(f)=>{if("reason"in f)s.skipped.push(f);else s.instructions.push(f)};for(let f of Xo){let p=I(e,f.relative),g=z(p)?.trim();if(g)s.instructions.push({path:p,source:f.source,scope:"project",content:g})}for(let f of Zo)for(let p of Ve(I(e,f.relative),f.extension)){let g=z(p);if(g===null)continue;if(f.source==="cursor"){i(ei(p,g,"project"));continue}let{body:x}=rn(g);if(x)s.instructions.push({path:p,source:f.source,scope:"project",content:x})}for(let f of Qo(e,"project"))i(f);let c=Gr(e,r),a=I(e,".codex","AGENTS.md"),l=z(a)?.trim();if(l&&c.includes(l))s.skipped.push({path:a,source:"codex",scope:"project",reason:"same content as the project's AGENTS.md"});else if(l)s.instructions.push({path:a,source:"codex",scope:"project",content:l});for(let f of Yo){let p=I(t,f.relative),g=z(p)?.trim();if(g)s.instructions.push({path:p,source:f.source,scope:"global",content:g})}let u=I(t,".codex","AGENTS.md"),d=z(u)?.trim(),m=Gr(t,r);if(d&&m.includes(d))s.skipped.push({path:u,source:"codex",scope:"global",reason:"same content as the machine's AGENTS.md"});else if(d)s.instructions.push({path:u,source:"codex",scope:"global",content:d});for(let[f,p]of[[e,"project"],[t,"global"]])for(let g of ri){let x=I(f,g.dir===".hlix"?r:g.dir,"skills");if(!Wo(x).some((O)=>z(I(O,"SKILL.md"))!==null))continue;s.skills.push({path:x,source:g.source,scope:p,harnessReads:g.harnessReads})}for(let[f,p]of[[e,"project"],[t,"global"]]){for(let g of si){let x=I(f,g.relative);if(Ve(x,".md").length===0)continue;s.commands.push({path:x,source:g.source,scope:p})}for(let g of Ve(I(f,".gemini","commands"),".toml")){let x=z(g),b=x===null?null:di(x);if(!b){s.skipped.push({path:g,source:"gemini",scope:p,reason:"no prompt field"});continue}s.generatedCommands.push({path:g,source:"gemini",scope:p,name:Yr(g,".toml"),body:`---
|
|
64
|
+
description: ${b.description}
|
|
65
65
|
---
|
|
66
66
|
|
|
67
|
-
${
|
|
68
|
-
`})}}for(let f of
|
|
67
|
+
${b.body}
|
|
68
|
+
`})}}for(let f of ns(r)){let p=Wr(I(e,f.relative),f,"project",o);s.skipped.push(...p.skipped);for(let g of p.servers){let x=s.mcpServers.findIndex((b)=>b.name===g.name);if(x===-1)s.mcpServers.push(g);else s.mcpServers[x]=g}}for(let f of ai(r)){let p=Wr(I(t,f.relative),f,"global",o);for(let g of p.servers)s.skipped.push({path:g.path,source:g.source,scope:"global",reason:`${g.name}: ${ii}`})}let v=[{dir:I(".claude","agents"),source:"claude"},{dir:I(r,"agents"),source:"hlix"}];for(let[f,p]of[[e,"project"],[t,"global"]])for(let g of v.flatMap((x)=>Ve(I(f,x.dir),".md"))){let x=z(g);if(x===null)continue;let b=li(g,x,p);if("reason"in b)s.skipped.push(b);else if(s.subagents.some((O)=>O.name===b.name))s.skipped.push({path:g,source:"claude",scope:p,reason:`a project agent already claims the name ${b.name}`});else s.subagents.push(b)}return s}function kl(e,t){if(e.length===0)return null;let n=I(Ko(),"hlix-standards-commands",Ho("sha256").update(t).digest("hex").slice(0,16));try{zo(n,{recursive:!0,force:!0}),Mo(n,{recursive:!0});for(let r of e)Bo(I(n,`${r.name}.md`),r.body,"utf8");return n}catch{return null}}var pi=60000,Xe=(e,t)=>{let n=Go(t,e);return!n||n.startsWith("..")||Jo(n)?e:n},ss=(e,t=process.env)=>{let n=t.HLIX_CONFIG_HOME;if(n&&e.startsWith(`${n}/`))return`~/.hlix/${e.slice(n.length+1)}`;let r=wt(t);return r&&e.startsWith(`${r}/`)?`~/${e.slice(r.length+1)}`:e};function bl(e,t,n=pi){if(e.length===0)return"";let r=["# Project standards from other agent tools","","These files were written for other coding agents working in this same","project. Treat them as the project's instructions and follow them."].join(`
|
|
69
69
|
`),o=[],s=r.length,i=!1;for(let a of e){let l=`# From ${Xe(a.path,t)} (${a.source})`,u=a.note?`${l}
|
|
70
70
|
${a.note}`:l,d=n-s-u.length-4;if(d<=0){i=!0;break}let m=a.content.length<=d?a.content:`${a.content.slice(0,d)}
|
|
71
71
|
[truncated]`;if(m.length<a.content.length)i=!0;o.push(`${u}
|
|
@@ -76,127 +76,129 @@ ${m}`),s+=u.length+m.length+4}let c=i?`
|
|
|
76
76
|
|
|
77
77
|
${o.join(`
|
|
78
78
|
|
|
79
|
-
`)}${c}`}var We=(e,t,n)=>`${e} ${e===1?t:n}`;function Sl(e){let t=[];if(e.instructions.length>0)t.push(We(e.instructions.length,"instruction file","instruction files"));if(e.skills.length>0)t.push(We(e.skills.length,"skill directory","skill directories"));let n=e.commands.length+e.generatedCommands.length;if(n>0)t.push(We(n,"command source","command sources"));if(e.mcpServers.length>0)t.push(We(e.mcpServers.length,"mcp server","mcp servers"));if(e.subagents.length>0)t.push(We(e.subagents.length,"subagent","subagents"));if(t.length===0)return"";let r=[...new Set([...e.instructions,...e.skills,...e.commands,...e.generatedCommands,...e.mcpServers,...e.subagents].map((o)=>o.source))].sort();return`standards: ${t.join(" · ")} (${r.join(", ")})`}function
|
|
79
|
+
`)}${c}`}var We=(e,t,n)=>`${e} ${e===1?t:n}`;function Sl(e){let t=[];if(e.instructions.length>0)t.push(We(e.instructions.length,"instruction file","instruction files"));if(e.skills.length>0)t.push(We(e.skills.length,"skill directory","skill directories"));let n=e.commands.length+e.generatedCommands.length;if(n>0)t.push(We(n,"command source","command sources"));if(e.mcpServers.length>0)t.push(We(e.mcpServers.length,"mcp server","mcp servers"));if(e.subagents.length>0)t.push(We(e.subagents.length,"subagent","subagents"));if(t.length===0)return"";let r=[...new Set([...e.instructions,...e.skills,...e.commands,...e.generatedCommands,...e.mcpServers,...e.subagents].map((o)=>o.source))].sort();return`standards: ${t.join(" · ")} (${r.join(", ")})`}function os(e,t){let n=[],r=(s,i)=>{if(i.length===0)return;n.push(s,...i.map((c)=>` ${c}`),"")},o=(s)=>`${s.source}${s.scope==="global"?" (global)":""} ${Xe(s.path,t)}`;if(r("Instructions",e.instructions.map((s)=>`${o(s)}${s.note?` — ${s.note}`:""}`)),r("Skills",e.skills.map((s)=>`${o(s)}${s.harnessReads?" — already read by the harness":""}`)),r("Commands",[...e.commands.map(o),...e.generatedCommands.map((s)=>`${o(s)} → /${s.name}`)]),r("MCP servers",e.mcpServers.map((s)=>`${o(s)} → ${s.name} (${"command"in s.config?"stdio":"http"})`)),r("Subagents",e.subagents.map((s)=>`${o(s)} → ${s.name}`)),r("Skipped",e.skipped.map((s)=>`${o(s)} — ${s.reason}`)),n.length===0)return`No standards from other agent tools were found in this folder.
|
|
80
80
|
`;return`${n.join(`
|
|
81
81
|
`).trimEnd()}
|
|
82
|
-
`}async function
|
|
83
|
-
`),o.id;if(e.json||!e.promptChoice)throw new
|
|
82
|
+
`}async function ui(e,t,n){let r=t.map((c)=>c.id);if(n){if(!r.includes(n))throw new h("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 h("workspace_required","This key belongs to a user who is not a member of any workspace. Create or join one first.");let o=t[0];if(o&&t.length===1)return e.stderr(`Using your only workspace: ${o.name} (${o.id})
|
|
83
|
+
`),o.id;if(e.json||!e.promptChoice)throw new h("missing_argument",`--workspace is required here: this key can act in ${t.length} workspaces. Pass one of: ${r.join(", ")}.`);let s=Math.max(...t.map((c)=>c.name.length));e.stderr(`${t.map((c,a)=>` ${a+1}) ${c.name.padEnd(s)} ${c.slug} ${c.role} ${c.id}`).join(`
|
|
84
84
|
`)}
|
|
85
85
|
`);let i=await e.promptChoice(`Workspace [1-${t.length}]: `,t.length);return r[i]}var cn={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(`
|
|
86
|
-
`),supportsJson:!0,options:["base-url","workspace"],async run(e){let t=typeof e.flags.workspace==="string"?e.flags.workspace:e.env.HLIX_WORKSPACE_ID,n=e.env.HLIX_API_KEY??await e.readSecret?.("Hlix API key: ")??"";if(!n)throw new
|
|
86
|
+
`),supportsJson:!0,options:["base-url","workspace"],async run(e){let t=typeof e.flags.workspace==="string"?e.flags.workspace:e.env.HLIX_WORKSPACE_ID,n=e.env.HLIX_API_KEY??await e.readSecret?.("Hlix API key: ")??"";if(!n)throw new h("missing_credential","No API key entered. Run from a terminal or set HLIX_API_KEY for CI.");let r=typeof e.flags["base-url"]==="string"?e.flags["base-url"]:e.env.HLIX_BASE_URL??Ut,o=new URL(r),s=o.hostname==="localhost"||o.hostname==="127.0.0.1"||o.hostname==="::1";if(o.protocol!=="https:"&&!(o.protocol==="http:"&&s))throw new h("invalid_base_url","--base-url must use HTTPS (HTTP is allowed only for localhost).");let i=new we({baseUrl:r,credential:ge(n),retry:{attempts:1}}),c=await ui(e,await i.workspaces.list(),t);await new we({baseUrl:r,credential:ge(n),organizationId:c,retry:{attempts:1}}).projects.list();let l=Sr({baseUrl:r,apiKey:n,organizationId:c},e.env);if(e.json)e.stdout(k(S(cn.name,{baseUrl:r,organizationId:c,credentialPath:l})));else e.stdout(`Signed in to ${r}
|
|
87
87
|
Credential stored at ${l}
|
|
88
88
|
`);return 0}},ln={name:"auth status",summary:"Show which credential is in use, where it came from, and whether it works",usage:["Usage: hlix auth status [--json]","","Names the SOURCE of the credential — the stored file, HLIX_API_KEY, or the","desktop app's own session when hlix was opened from its Terminal tab — and","verifies it against the API. The credential itself is never printed, not even","a prefix: machine output gets piped into logs."].join(`
|
|
89
|
-
`),supportsJson:!0,async run(e){let t=J({env:e.env,flags:e.flags,cwd:e.cwd});if(t.conflict)throw new
|
|
90
|
-
`),r}let n={credentialSource:t.credentialSource,credentialPath:t.credentialSource==="file"?t.credentialPath:null,baseUrl:t.baseUrl,baseUrlSource:t.baseUrlSource,workspaceId:t.workspaceId,workspaceSource:t.workspaceSource,valid:!0};if(e.json)return e.stdout(S(
|
|
91
|
-
`),0}},
|
|
92
|
-
`),supportsJson:!0,options:["yes"],async run(e){let t=J({env:e.env,flags:e.flags,cwd:e.cwd});if(t.credentialSource==="env"||t.credentialSource==="session"){let r=t.credentialSource==="session",o=r?"session":"environment",s=r?"This session belongs to the Hlix desktop app; sign out there to end it.":"HLIX_API_KEY is set in this environment; unset it there to sign out.",i=
|
|
93
|
-
`);return 0}if(e.flags.yes!==!0){let a={removed:!1,reason:o,path:i};if(e.json)e.stdout(S(
|
|
89
|
+
`),supportsJson:!0,async run(e){let t=J({env:e.env,flags:e.flags,cwd:e.cwd});if(t.conflict)throw new h("workspace_mismatch",t.conflict);if(!t.credential)throw new h("unauthenticated","No credential. Run `hlix auth login`, or set HLIX_API_KEY for CI.");try{await e.requireClient().projects.list()}catch(r){throw e.stderr(`credential from ${t.credentialSource}, workspace ${t.workspaceId??"none"}, api ${t.baseUrl}
|
|
90
|
+
`),r}let n={credentialSource:t.credentialSource,credentialPath:t.credentialSource==="file"?t.credentialPath:null,baseUrl:t.baseUrl,baseUrlSource:t.baseUrlSource,workspaceId:t.workspaceId,workspaceSource:t.workspaceSource,valid:!0};if(e.json)return e.stdout(k(S(ln.name,n))),0;return e.stdout(`${A([["credential",ht(t)??"none"],["api",`${t.baseUrl} (from ${t.baseUrlSource})`],["workspace",t.workspaceId?`${t.workspaceId} (from ${t.workspaceSource})`:"none"],["status","valid"]])}
|
|
91
|
+
`),0}},be={name:"auth logout",summary:"Remove the stored credential from this machine",usage:["Usage: hlix auth logout [--yes] [--json]","","Removes ~/.config/hlix/credentials.json after confirming. A credential","supplied through HLIX_API_KEY is not removed — unset it in the shell that","set it — and neither is the desktop app's own session; sign out in the app."].join(`
|
|
92
|
+
`),supportsJson:!0,options:["yes"],async run(e){let t=J({env:e.env,flags:e.flags,cwd:e.cwd});if(t.credentialSource==="env"||t.credentialSource==="session"){let r=t.credentialSource==="session",o=r?"session":"environment",s=r?"This session belongs to the Hlix desktop app; sign out there to end it.":"HLIX_API_KEY is set in this environment; unset it there to sign out.",i=br(e.env);if(!i){let a={removed:!1,reason:o,path:null};if(e.json)e.stdout(k(S(be.name,a)));else e.stdout(`${s}
|
|
93
|
+
`);return 0}if(e.flags.yes!==!0){let a={removed:!1,reason:o,path:i};if(e.json)e.stdout(k(S(be.name,a)));else e.stdout(`${s}
|
|
94
94
|
A stored credential also exists at ${i} — repeat with --yes to remove it.
|
|
95
|
-
`);return 0}let c=Ht(e.env);if(e.json)e.stdout(S(
|
|
95
|
+
`);return 0}let c=Ht(e.env);if(e.json)e.stdout(k(S(be.name,c)));else e.stdout(`Removed ${c.path}
|
|
96
96
|
${r?"The desktop app's session is still in use; sign out there to finish.":"HLIX_API_KEY is still set in this environment; unset it there to finish signing out."}
|
|
97
|
-
`);return 0}if(e.flags.yes!==!0&&t.credential){if(e.json||!e.confirm)throw new
|
|
97
|
+
`);return 0}if(e.flags.yes!==!0&&t.credential){if(e.json||!e.confirm)throw new h("approval_required","Removing the stored credential needs approval. Repeat with `--yes`.");if(!await e.confirm(`Remove the stored credential at ${t.credentialPath}? Signing back in needs the API key again.`))throw new h("cancelled","Logout cancelled.")}let n=Ht(e.env);if(e.json)e.stdout(k(S(be.name,n)));else e.stdout(n.removed?`Removed ${n.path}
|
|
98
98
|
`:`No stored credential at ${n.path}
|
|
99
|
-
`);return 0}};var
|
|
100
|
-
`),supportsJson:!0,async run(e){let t=en(e.cwd,e.env),n=
|
|
99
|
+
`);return 0}};var is=ke.join(" | "),dn={name:"config list",summary:"Show every setting in effect and which file supplied it",usage:["Usage: hlix config list [--cwd <dir>] [--json]","","Merges the machine-wide file with this folder's, per key, and names the","source of each value: project, global, or default (no file names it)."].join(`
|
|
100
|
+
`),supportsJson:!0,async run(e){let t=en(e.cwd,e.env),n=Br(t);if(e.json)return e.stdout(k(S(dn.name,{settings:n,paths:t.paths}))),0;return e.stdout(`${Y(["setting","value","source","applies to"],n.map((r)=>[r.key,r.value??"-",r.source,Ur[r.key]??"this folder's binding"]))}
|
|
101
101
|
`),e.stdout(`
|
|
102
102
|
global ${t.paths.global}
|
|
103
103
|
`),e.stdout(`project ${t.paths.project??"- (this folder is not bound to hlix)"}
|
|
104
|
-
`),0}},pn={name:"config get",summary:"Print one setting's effective value",usage:[`Usage: hlix config get <${
|
|
105
|
-
`),supportsJson:!0,args:{min:1,max:1},async run(e){let t=tn(e.args[0]),n=en(e.cwd,e.env),r=n.merged[t]??null,o=n.sources[t]??"default";if(e.json)return e.stdout(S(
|
|
104
|
+
`),0}},pn={name:"config get",summary:"Print one setting's effective value",usage:[`Usage: hlix config get <${is}> [--cwd <dir>] [--json]`,"","Prints the value the cascade resolves for one key, or exits 1 when no","file names it."].join(`
|
|
105
|
+
`),supportsJson:!0,args:{min:1,max:1},async run(e){let t=tn(e.args[0]),n=en(e.cwd,e.env),r=n.merged[t]??null,o=n.sources[t]??"default";if(e.json)return e.stdout(k(S(pn.name,{key:t,value:r,source:o}))),r===null?1:0;if(r===null)return e.stderr(`${t} is not set. Set it with \`hlix config set ${t} <value>\`.
|
|
106
106
|
`),1;return e.stdout(`${r}
|
|
107
|
-
`),0}},un={name:"config set",summary:"Set one setting for this folder, or for the machine with --global",usage:[`Usage: hlix config set <${
|
|
108
|
-
`),supportsJson:!0,options:["global"],args:{min:2,max:2},async run(e){let t=tn(e.args[0]),n=
|
|
109
|
-
`),0}};function ae(e,t){if(typeof e!=="object"||e===null)return"";let n=e[t];return n===null||n===void 0?"":String(n)}var mn={name:"projects list",summary:"List the projects in your workspace",usage:"Usage: hlix projects list [--json]",supportsJson:!0,async run(e){let t=await e.requireClient().projects.list();if(e.json)return e.stdout(S(
|
|
107
|
+
`),0}},un={name:"config set",summary:"Set one setting for this folder, or for the machine with --global",usage:[`Usage: hlix config set <${is}> <value> [--global] [--cwd <dir>] [--json]`,"","Writes this folder's .hlix/config.json, or the machine-wide file with","--global. Other keys in the file are left untouched. The binding keys","(projectId, workspaceId, apiUrl) are written by init/import and are","refused here."].join(`
|
|
108
|
+
`),supportsJson:!0,options:["global"],args:{min:2,max:2},async run(e){let t=tn(e.args[0]),n=Dr(t,e.args[1]),r=e.flags.global===!0?"global":"project",o=Kr({key:t,value:n,scope:r,cwd:e.cwd,env:e.env});if(e.json)return e.stdout(k(S(un.name,{key:t,value:n,scope:r,path:o}))),0;return e.stdout(`${t} = ${n} (${r}: ${o})
|
|
109
|
+
`),0}};function ae(e,t){if(typeof e!=="object"||e===null)return"";let n=e[t];return n===null||n===void 0?"":String(n)}var mn={name:"projects list",summary:"List the projects in your workspace",usage:"Usage: hlix projects list [--json]",supportsJson:!0,async run(e){let t=await e.requireClient().projects.list();if(e.json)return e.stdout(k(S(mn.name,t))),0;let n=Array.isArray(t)?t:[];if(n.length===0)return e.stdout(`No projects.
|
|
110
110
|
`),0;return e.stdout(`${Y(["ID","NAME","STACK"],n.map((r)=>[ae(r,"id"),ae(r,"name"),ae(r,"stack")]))}
|
|
111
111
|
`),0}},fn={name:"projects get",summary:"Show one project, defaulting to the one this folder is bound to",usage:["Usage: hlix projects get [project-id] [--json]","","With no id, the project this folder is bound to is used."].join(`
|
|
112
|
-
`),supportsJson:!0,args:{min:0,max:1},async run(e){let t=e.args[0]??N(e.cwd)?.config.projectId;if(!t)throw new
|
|
113
|
-
`),0}};function gn(e,t){let n=e.args[0];if(!n)throw new
|
|
114
|
-
`),supportsJson:!0,options:["project","status"],async run(e){let t=
|
|
112
|
+
`),supportsJson:!0,args:{min:0,max:1},async run(e){let t=e.args[0]??N(e.cwd)?.config.projectId;if(!t)throw new h("missing_argument","A project id is required, or run this inside a folder bound to a project.");let n=await e.requireClient().projects.get(t);if(e.json)return e.stdout(k(S(fn.name,n))),0;let r=n.repos;return e.stdout(`${A([["id",ae(n,"id")],["name",ae(n,"name")],["stack",ae(n,"stack")],["status",ae(n,"status")],["repos",Array.isArray(r)?String(r.length):""]].filter(([,o])=>o!==""))}
|
|
113
|
+
`),0}};function gn(e,t){let n=e.args[0];if(!n)throw new h("missing_argument",`A ${t} id is required.`);return n}function as(e,t){let n=e.flags[t];return typeof n==="string"&&n.trim()?n.trim():void 0}function G(e,t){if(typeof e!=="object"||e===null)return"";let n=e[t];return n===null||n===void 0?"":String(n)}var hn={name:"tasks list",summary:"List tasks, defaulting to the project this folder is bound to",usage:["Usage: hlix tasks list [--project <id>] [--status <status>] [--json]","","With no --project, a folder bound to a project lists that project's tasks;","anywhere else it lists the workspace's tasks."].join(`
|
|
114
|
+
`),supportsJson:!0,options:["project","status"],async run(e){let t=as(e,"project")??N(e.cwd)?.config.projectId,n=as(e,"status"),r=await e.requireClient().tasks.list({...t?{projectId:t}:{},...n?{status:n}:{}});if(e.json)return e.stdout(k(S(hn.name,r))),0;let o=Array.isArray(r)?r:[];if(o.length===0)return e.stdout(`No tasks.
|
|
115
115
|
`),0;return e.stdout(`${Y(["ID","STATUS","TITLE"],o.map((s)=>[G(s,"id"),G(s,"status"),G(s,"title")||G(s,"description").split(`
|
|
116
116
|
`)[0]||""]))}
|
|
117
|
-
`),0}},yn={name:"tasks get",summary:"Show one task",usage:"Usage: hlix tasks get <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(e){let t=gn(e,"task"),n=await e.requireClient().tasks.get(t);if(e.json)return e.stdout(S(
|
|
118
|
-
`),0}},wn={name:"tasks review",summary:"Show the verified review evidence for a task",usage:"Usage: hlix tasks review <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(e){let t=gn(e,"task"),n=await e.requireClient().tasks.review(t);if(e.json)return e.stdout(S(
|
|
117
|
+
`),0}},yn={name:"tasks get",summary:"Show one task",usage:"Usage: hlix tasks get <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(e){let t=gn(e,"task"),n=await e.requireClient().tasks.get(t);if(e.json)return e.stdout(k(S(yn.name,n))),0;return e.stdout(`${A([["id",G(n,"id")],["status",G(n,"status")],["title",G(n,"title")],["project",G(n,"projectId")],["description",G(n,"description")]])}
|
|
118
|
+
`),0}},wn={name:"tasks review",summary:"Show the verified review evidence for a task",usage:"Usage: hlix tasks review <task-id> [--json]",supportsJson:!0,args:{min:1,max:1},async run(e){let t=gn(e,"task"),n=await e.requireClient().tasks.review(t);if(e.json)return e.stdout(k(S(wn.name,n))),0;return e.stdout(`${JSON.stringify(n,null,2)}
|
|
119
119
|
`),0}},vn={name:"tasks watch",summary:"Stream a task's status changes until it finishes",usage:["Usage: hlix tasks watch <task-id> [--json]","","Streams the task's server-sent status frames and exits when the task","reaches a terminal status or the server closes the stream.","","With --json, each frame is printed as one envelope per line (JSONL) so a","consumer can read them as they arrive."].join(`
|
|
120
|
-
`),supportsJson:!0,args:{min:1,max:1},async run(e){let t=gn(e,"task"),n=e.requireClient();for await(let r of n.tasks.stream(t)){let o;try{o=JSON.parse(r.data)}catch{o=r.data}if(e.json)e.stdout(`${JSON.stringify(
|
|
120
|
+
`),supportsJson:!0,args:{min:1,max:1},async run(e){let t=gn(e,"task"),n=e.requireClient();for await(let r of n.tasks.stream(t)){let o;try{o=JSON.parse(r.data)}catch{o=r.data}if(e.json)e.stdout(`${JSON.stringify(S(vn.name,o))}
|
|
121
121
|
`);else{let s=G(o,"status"),i=G(o,"error");e.stdout(i?`error: ${i}
|
|
122
122
|
`:`${s||r.data}
|
|
123
|
-
`)}}return 0}};import{realpath as Zi}from"node:fs/promises";import{resolve as Qi}from"node:path";import{createHash as $n}from"node:crypto";import{createReadStream as yi}from"node:fs";import{lstat as vs,readFile as kt,readdir as wi,readlink as vi,realpath as ks,stat as ki}from"node:fs/promises";import{basename as le,join as Ss,relative as us,resolve as ms,sep as Si}from"node:path";import{spawnSync as bi}from"node:child_process";import fs from"ignore";import{readFile as mi}from"node:fs/promises";import{join as fi}from"node:path";function ui(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 as(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=[],o=!1,s=-1;for(let i of t.slice(n+1)){if(!i.trim()||/^\s*#/.test(i))continue;let c=i.length-i.trimStart().length,a=i.match(/^(\s*-(?:\s+|$))(.*)$/);if(a){if(s!==-1&&c>=s)continue;if(r.push({}),s=a[2]?a[1].length:-1,!a[2])continue}else if(c===0)break;else if(r.length===0)continue;else if(s===-1)s=c;else if(c!==s)continue;let l=(a?a[2]:i.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!l)continue;let u=l[1];if(u!=="name"&&u!=="before"&&u!=="init"&&u!=="command")continue;let d=ui(l[2]);if(d===null)o=!0;else r[r.length-1][u]=d}return{tasks:r,partial:o}}async function ce(e,t){try{return await mi(fi(e,...t.split("/")),"utf8")}catch(n){if(n.code==="ENOENT")return null;throw n}}function cs(e){try{let t=e.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(t)}catch{return null}}function oe(e){if(typeof e==="string"&&e.trim())return[e.trim()];if(Array.isArray(e))return e.flatMap(oe);if(e&&typeof e==="object")return Object.values(e).flatMap(oe);return[]}function kn(e){if(!e||typeof e!=="object")return[];return Object.keys(e).filter((t)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))}function gi(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 o of r)for(let s of e.matchAll(o))n.add(s[1]);return[...n]}function hi(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 ls(e){let t=typeof e==="number"?e:Number(e);return Number.isInteger(t)&&t>0&&t<=65535?t:null}function K(e,t,n){if(!e.some((r)=>r.path===t&&r.kind===n))e.push({path:t,kind:n})}async function ds(e,t,n){let r=[],o=[],s=[],i=[],c=new Map,a=new Set,l=new Set,u=[],d={},m=null,v=0,f=await ce(e,".cursor/environment.json");if(f){K(r,".cursor/environment.json","cursor");let w=cs(f);if(!w)u.push("Could not parse .cursor/environment.json; it remains quarantined.");else{o.push(...oe(w.install));let R=oe(w.start);if(R[0])m=R[0];if(Array.isArray(w.terminals))for(let P of w.terminals){if(!P||typeof P!=="object")continue;let _=P;if(typeof _.command!=="string"||!_.command.trim())continue;i.push({name:typeof _.name==="string"&&_.name.trim()?_.name.trim():"Terminal",command:_.command.trim(),...typeof _.cwd==="string"&&_.cwd.trim()?{cwd:_.cwd.trim()}:{}})}}}let p=t.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":t.has("devcontainer.json")?"devcontainer.json":null;if(p){K(r,p,"devcontainer");let w=cs(n.get(p)??await ce(e,p)??"");if(!w)u.push(`Could not parse ${p}; it remains quarantined.`);else{o.push(...oe(w.onCreateCommand),...oe(w.updateContentCommand),...oe(w.postCreateCommand));let R=oe(w.postStartCommand);if(!m&&R[0])m=R[0];for(let P of kn(w.secrets))a.add(P);for(let P of[...kn(w.containerEnv),...kn(w.remoteEnv)])a.add(P);if(Array.isArray(w.forwardPorts))for(let P of w.forwardPorts){let _=ls(P);if(_)c.set(_,{port:_,visibility:"private"})}}}if(t.has(".gitpod.yml")){K(r,".gitpod.yml","gitpod");let w=n.get(".gitpod.yml")??await ce(e,".gitpod.yml");if(w===null)u.push("Could not read .gitpod.yml; its task commands were not imported.");else{let R=as(w);v=R.tasks.filter((P)=>P.before).length;for(let P of R.tasks){if(P.before)o.push(P.before);if(P.init)o.push(P.init);if(!P.command)continue;if(!m)m=P.command;else i.push({name:P.name??"Terminal",command:P.command})}if(R.partial)u.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 w of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(t.has(w))K(r,w,"docker");for(let w of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(t.has(w))K(r,w,"buildpack");for(let w of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(t.has(w))K(r,w,"platform");let g=n.get("package.json")??await ce(e,"package.json");if(g){K(r,"package.json","package");try{let w=JSON.parse(g);if(w.engines?.node)d.node=w.engines.node;let R=hi(t,w.packageManager);if(R&&o.length===v)o.push(R);if(w.scripts?.build&&s.length===0)s.push(`${w.packageManager?.split("@")[0]??(t.has("bun.lock")?"bun":"npm")} run build`);let P=w.scripts?.dev?`${t.has("bun.lock")?"bun":"npm"} run dev`:null,_=w.scripts?.start?`${t.has("bun.lock")?"bun":"npm"} run start`:P;if(!m&&_)m=_}catch{u.push("Could not parse package.json for environment discovery.")}}if(t.has("uv.lock"))o.push("uv sync --frozen");else if(t.has("poetry.lock"))o.push("poetry install --no-interaction");else if(t.has("requirements.txt"))o.push("python -m pip install -r requirements.txt");if(t.has("go.mod"))o.push("go mod download");if(t.has("Procfile")){K(r,"Procfile","procfile");let R=(n.get("Procfile")??"").split(/\r?\n/).find((P)=>/^web\s*:/.test(P));if(R)m=R.replace(/^web\s*:\s*/,"").trim()||m}let x=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[w,R]of x){let P=(n.get(w)??await ce(e,w))?.trim();if(P)d[R]=P,K(r,w,"tool-version")}let k=n.get(".tool-versions")??await ce(e,".tool-versions");if(k){K(r,".tool-versions","tool-version");for(let w of k.split(/\r?\n/)){let[R,P]=w.trim().split(/\s+/,2);if(!P)continue;if(R==="nodejs")d.node=P;else if(R==="python")d.python=P;else if(R==="bun")d.bun=P}}let O=n.get("mise.toml")??await ce(e,"mise.toml");if(O){K(r,"mise.toml","tool-version");for(let w of O.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))d[w[1]]=w[2]}for(let[w,R]of n){let P=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(w)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(w);for(let _ of gi(R,P))l.add(_);for(let _ of R.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let ne=ls(_[1]);if(ne)c.set(ne,{port:ne,visibility:"private"})}}if(r.length===0&&t.size>0)K(r,"repository","detected");let L=(w)=>[...new Set(w.filter(Boolean))],Ee=r.length+o.length+(m?1:0);return{sources:r.sort((w,R)=>w.path.localeCompare(R.path)),toolchain:d,install:L(o),build:L(s),start:m,terminals:i,ports:[...c.values()].sort((w,R)=>w.port-R.port),requiredSecretKeys:[...a].sort(),observedSecretKeys:[...l].sort(),confidence:Ee>=4?"high":Ee>=2?"medium":"low",warnings:u}}var ps=2;var ji=300000,Ei=25000,$i=52428800,Pi=524288000,St=1e4,vt=1048576,Ye=20971520,gs=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store"],Cn="Required project environment value was not found locally: ",Ci=/(^|\/)\.env\.(example|sample|template)$/i,Ii=/(^|\/)\.env(?:\.[^/]+)?$/i,xi=/(^|\/)(?:\.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,Ri=/\.(?:example|sample|template)$/i,_i=/(^|\/)\.(?:npmrc|yarnrc(?:\.yml)?|pypirc)$/i,Ti=/(?:^|\/)(?:__tests__|tests?|fixtures)\/|\.(?:test|spec)\.[^/]+$|\.snap$/i,Oi=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,Ai=/(^|\/)(?:AGENTS\.md|CLAUDE\.md|\.cursorrules|\.github\/copilot-instructions\.md)$/i,Fi=/(^|\/)(?:\.agents|\.claude)\/skills\//i,Ni=/-----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,}/,Li=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,Hi=/(?:^|[,{\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,Ze=new Set(["HLIX_AGENT_RUN_ID","HLIX_API_KEY","HLIX_API_URL","HLIX_BASE_URL","HLIX_PROJECT_ID","HLIX_SESSION_TOKEN","HLIX_WORKSPACE_ID"]),Sn="Your hlix credentials were left out of the project's secrets — the platform provides them.",bn=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]);function Qe(e){return e.split(Si).join("/")}function q(e){if(e>=1048576)return`${(e/1048576).toFixed(1)} MB`;if(e>=1024)return`${(e/1024).toFixed(1)} KB`;return`${e} bytes`}function jn(e,t=5){return[...e].sort((n,r)=>r.size-n.size||n.path.localeCompare(r.path)).slice(0,t).map((n)=>`${n.path} (${q(n.size)})`).join(", ")}function En(e,t=5){let n=new Map;for(let r of e){let o=r.indexOf("/"),s=o===-1?".":r.slice(0,o);n.set(s,(n.get(s)??0)+1)}return[...n].sort((r,o)=>o[1]-r[1]||r[0].localeCompare(o[0])).slice(0,t).map(([r,o])=>`${r}/ (${o} files)`).join(", ")}function Z(e,t,n=10485760){return bi("git",["-C",e,...t],{encoding:"utf8",timeout:ji,maxBuffer:n,stdio:["ignore","pipe","pipe"]})}async function Mi(e){let t=$n("sha256");for await(let n of yi(e))t.update(n);return t.digest("hex")}function Pn(e){if(Array.isArray(e))return`[${e.map(Pn).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${Pn(n)}`).join(",")}}`;return JSON.stringify(e)}function bs(e){let t={};for(let[n,r]of String(e).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let o=r.trim();if(!o||o.startsWith("#"))continue;let i=(o.startsWith("export ")?o.slice(7).trimStart():o).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!i)throw Error(`Invalid dotenv assignment on line ${n+1}`);let c=i[2]??"";if(c.startsWith('"')){if(!c.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${n+1}`);c=c.slice(1,-1).replace(/\\n/g,`
|
|
124
|
-
`).replace(/\\r/g,"\r")}else if(c.startsWith("'")){if(!c.endsWith("'"))throw Error(`Unclosed dotenv quote on line ${n+1}`);c=c.slice(1,-1)}else c=c.replace(/\s+#.*$/,"").trimEnd();t[i[1]]=c}return t}function
|
|
125
|
-
`).filter(Boolean).map((v)=>{let[f,p]=v.split("\x00");return{name:f,oid:p}}).filter(({name:v,oid:f})=>/^refs\/(?:heads|tags)\/.+/.test(v)&&/^[0-9a-f]{40,64}$/.test(f)).sort((v,f)=>v.name.localeCompare(f.name)),a=["log","--all",`--max-count=${
|
|
126
|
-
`))}let
|
|
127
|
-
`),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
|
|
123
|
+
`)}}return 0}};import{realpath as Qi}from"node:fs/promises";import{resolve as ea}from"node:path";import{createHash as $n}from"node:crypto";import{createReadStream as wi}from"node:fs";import{lstat as ks,readFile as kt,readdir as vi,readlink as ki,realpath as bs,stat as bi}from"node:fs/promises";import{basename as le,join as Ss,relative as ms,resolve as fs,sep as Si}from"node:path";import{spawnSync as ji}from"node:child_process";import gs from"ignore";import{readFile as fi}from"node:fs/promises";import{join as gi}from"node:path";function mi(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 cs(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=[],o=!1,s=-1;for(let i of t.slice(n+1)){if(!i.trim()||/^\s*#/.test(i))continue;let c=i.length-i.trimStart().length,a=i.match(/^(\s*-(?:\s+|$))(.*)$/);if(a){if(s!==-1&&c>=s)continue;if(r.push({}),s=a[2]?a[1].length:-1,!a[2])continue}else if(c===0)break;else if(r.length===0)continue;else if(s===-1)s=c;else if(c!==s)continue;let l=(a?a[2]:i.trim()).match(/^([A-Za-z_][A-Za-z0-9_-]*):\s*(.*)$/);if(!l)continue;let u=l[1];if(u!=="name"&&u!=="before"&&u!=="init"&&u!=="command")continue;let d=mi(l[2]);if(d===null)o=!0;else r[r.length-1][u]=d}return{tasks:r,partial:o}}async function ce(e,t){try{return await fi(gi(e,...t.split("/")),"utf8")}catch(n){if(n.code==="ENOENT")return null;throw n}}function ls(e){try{let t=e.replace(/(^|[^:\\])\/\/.*$/gm,"$1").replace(/\/\*[\s\S]*?\*\//g,"").replace(/,\s*([}\]])/g,"$1");return JSON.parse(t)}catch{return null}}function oe(e){if(typeof e==="string"&&e.trim())return[e.trim()];if(Array.isArray(e))return e.flatMap(oe);if(e&&typeof e==="object")return Object.values(e).flatMap(oe);return[]}function kn(e){if(!e||typeof e!=="object")return[];return Object.keys(e).filter((t)=>/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))}function hi(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 o of r)for(let s of e.matchAll(o))n.add(s[1]);return[...n]}function yi(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 ds(e){let t=typeof e==="number"?e:Number(e);return Number.isInteger(t)&&t>0&&t<=65535?t:null}function K(e,t,n){if(!e.some((r)=>r.path===t&&r.kind===n))e.push({path:t,kind:n})}async function ps(e,t,n){let r=[],o=[],s=[],i=[],c=new Map,a=new Set,l=new Set,u=[],d={},m=null,v=0,f=await ce(e,".cursor/environment.json");if(f){K(r,".cursor/environment.json","cursor");let w=ls(f);if(!w)u.push("Could not parse .cursor/environment.json; it remains quarantined.");else{o.push(...oe(w.install));let R=oe(w.start);if(R[0])m=R[0];if(Array.isArray(w.terminals))for(let P of w.terminals){if(!P||typeof P!=="object")continue;let _=P;if(typeof _.command!=="string"||!_.command.trim())continue;i.push({name:typeof _.name==="string"&&_.name.trim()?_.name.trim():"Terminal",command:_.command.trim(),...typeof _.cwd==="string"&&_.cwd.trim()?{cwd:_.cwd.trim()}:{}})}}}let p=t.has(".devcontainer/devcontainer.json")?".devcontainer/devcontainer.json":t.has("devcontainer.json")?"devcontainer.json":null;if(p){K(r,p,"devcontainer");let w=ls(n.get(p)??await ce(e,p)??"");if(!w)u.push(`Could not parse ${p}; it remains quarantined.`);else{o.push(...oe(w.onCreateCommand),...oe(w.updateContentCommand),...oe(w.postCreateCommand));let R=oe(w.postStartCommand);if(!m&&R[0])m=R[0];for(let P of kn(w.secrets))a.add(P);for(let P of[...kn(w.containerEnv),...kn(w.remoteEnv)])a.add(P);if(Array.isArray(w.forwardPorts))for(let P of w.forwardPorts){let _=ds(P);if(_)c.set(_,{port:_,visibility:"private"})}}}if(t.has(".gitpod.yml")){K(r,".gitpod.yml","gitpod");let w=n.get(".gitpod.yml")??await ce(e,".gitpod.yml");if(w===null)u.push("Could not read .gitpod.yml; its task commands were not imported.");else{let R=cs(w);v=R.tasks.filter((P)=>P.before).length;for(let P of R.tasks){if(P.before)o.push(P.before);if(P.init)o.push(P.init);if(!P.command)continue;if(!m)m=P.command;else i.push({name:P.name??"Terminal",command:P.command})}if(R.partial)u.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 w of["Dockerfile","docker-compose.yml","docker-compose.yaml","compose.yml","compose.yaml"])if(t.has(w))K(r,w,"docker");for(let w of["project.toml","nixpacks.toml","railpack.json","Aptfile"])if(t.has(w))K(r,w,"buildpack");for(let w of["fly.toml","railway.json","render.yaml","vercel.json","netlify.toml"])if(t.has(w))K(r,w,"platform");let g=n.get("package.json")??await ce(e,"package.json");if(g){K(r,"package.json","package");try{let w=JSON.parse(g);if(w.engines?.node)d.node=w.engines.node;let R=yi(t,w.packageManager);if(R&&o.length===v)o.push(R);if(w.scripts?.build&&s.length===0)s.push(`${w.packageManager?.split("@")[0]??(t.has("bun.lock")?"bun":"npm")} run build`);let P=w.scripts?.dev?`${t.has("bun.lock")?"bun":"npm"} run dev`:null,_=w.scripts?.start?`${t.has("bun.lock")?"bun":"npm"} run start`:P;if(!m&&_)m=_}catch{u.push("Could not parse package.json for environment discovery.")}}if(t.has("uv.lock"))o.push("uv sync --frozen");else if(t.has("poetry.lock"))o.push("poetry install --no-interaction");else if(t.has("requirements.txt"))o.push("python -m pip install -r requirements.txt");if(t.has("go.mod"))o.push("go mod download");if(t.has("Procfile")){K(r,"Procfile","procfile");let R=(n.get("Procfile")??"").split(/\r?\n/).find((P)=>/^web\s*:/.test(P));if(R)m=R.replace(/^web\s*:\s*/,"").trim()||m}let x=[[".node-version","node"],[".nvmrc","node"],[".python-version","python"]];for(let[w,R]of x){let P=(n.get(w)??await ce(e,w))?.trim();if(P)d[R]=P,K(r,w,"tool-version")}let b=n.get(".tool-versions")??await ce(e,".tool-versions");if(b){K(r,".tool-versions","tool-version");for(let w of b.split(/\r?\n/)){let[R,P]=w.trim().split(/\s+/,2);if(!P)continue;if(R==="nodejs")d.node=P;else if(R==="python")d.python=P;else if(R==="bun")d.bun=P}}let O=n.get("mise.toml")??await ce(e,"mise.toml");if(O){K(r,"mise.toml","tool-version");for(let w of O.matchAll(/^\s*(node|python|bun)\s*=\s*["']([^"']+)["']/gm))d[w[1]]=w[2]}for(let[w,R]of n){let P=/(?:^|\/)(?:Dockerfile|Procfile)$/i.test(w)||/\.(?:jsonc?|ya?ml|toml|ini|conf|config|env|sh|bash|zsh|fish)$/i.test(w);for(let _ of hi(R,P))l.add(_);for(let _ of R.matchAll(/(?:--port(?:=|\s+)|PORT\s*=\s*)(\d{2,5})/g)){let ne=ds(_[1]);if(ne)c.set(ne,{port:ne,visibility:"private"})}}if(r.length===0&&t.size>0)K(r,"repository","detected");let L=(w)=>[...new Set(w.filter(Boolean))],Ee=r.length+o.length+(m?1:0);return{sources:r.sort((w,R)=>w.path.localeCompare(R.path)),toolchain:d,install:L(o),build:L(s),start:m,terminals:i,ports:[...c.values()].sort((w,R)=>w.port-R.port),requiredSecretKeys:[...a].sort(),observedSecretKeys:[...l].sort(),confidence:Ee>=4?"high":Ee>=2?"medium":"low",warnings:u}}var us=2;var Ei=300000,$i=25000,Pi=52428800,Ci=524288000,bt=1e4,vt=1048576,Ye=20971520,hs=[".git/",".hlix/","node_modules/",".next/",".turbo/",".cache/","dist/","build/","coverage/","__pycache__/",".venv/","venv/","target/",".DS_Store"],Cn="Required project environment value was not found locally: ",Ii=/(^|\/)\.env\.(example|sample|template)$/i,xi=/(^|\/)\.env(?:\.[^/]+)?$/i,Ri=/(^|\/)(?:\.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,_i=/\.(?:example|sample|template)$/i,Ti=/(^|\/)\.(?:npmrc|yarnrc(?:\.yml)?|pypirc)$/i,Oi=/(?:^|\/)(?:__tests__|tests?|fixtures)\/|\.(?:test|spec)\.[^/]+$|\.snap$/i,Ai=/(^|\/)(?:\.mcp\.json|mcp\.json|claude_desktop_config\.json)$/i,Fi=/(^|\/)(?:AGENTS\.md|CLAUDE\.md|\.cursorrules|\.github\/copilot-instructions\.md)$/i,Ni=/(^|\/)(?:\.agents|\.claude)\/skills\//i,Li=/-----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,}/,Hi=/\.(?:json|ya?ml|toml|ini|conf|config)$/i,Mi=/(?:^|[,{\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,Ze=new Set(["HLIX_AGENT_RUN_ID","HLIX_API_KEY","HLIX_API_URL","HLIX_BASE_URL","HLIX_PROJECT_ID","HLIX_SESSION_TOKEN","HLIX_WORKSPACE_ID"]),bn="Your hlix credentials were left out of the project's secrets — the platform provides them.",Sn=new Set(["CI","HOME","LANG","LOGNAME","NODE_ENV","OLDPWD","PATH","PORT","PWD","SHELL","SHLVL","TERM","TMPDIR","USER","_"]);function Qe(e){return e.split(Si).join("/")}function q(e){if(e>=1048576)return`${(e/1048576).toFixed(1)} MB`;if(e>=1024)return`${(e/1024).toFixed(1)} KB`;return`${e} bytes`}function jn(e,t=5){return[...e].sort((n,r)=>r.size-n.size||n.path.localeCompare(r.path)).slice(0,t).map((n)=>`${n.path} (${q(n.size)})`).join(", ")}function En(e,t=5){let n=new Map;for(let r of e){let o=r.indexOf("/"),s=o===-1?".":r.slice(0,o);n.set(s,(n.get(s)??0)+1)}return[...n].sort((r,o)=>o[1]-r[1]||r[0].localeCompare(o[0])).slice(0,t).map(([r,o])=>`${r}/ (${o} files)`).join(", ")}function Z(e,t,n=10485760){return ji("git",["-C",e,...t],{encoding:"utf8",timeout:Ei,maxBuffer:n,stdio:["ignore","pipe","pipe"]})}async function Ui(e){let t=$n("sha256");for await(let n of wi(e))t.update(n);return t.digest("hex")}function Pn(e){if(Array.isArray(e))return`[${e.map(Pn).join(",")}]`;if(e&&typeof e==="object")return`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${Pn(n)}`).join(",")}}`;return JSON.stringify(e)}function js(e){let t={};for(let[n,r]of String(e).replace(/^\uFEFF/,"").split(/\r?\n/).entries()){let o=r.trim();if(!o||o.startsWith("#"))continue;let i=(o.startsWith("export ")?o.slice(7).trimStart():o).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!i)throw Error(`Invalid dotenv assignment on line ${n+1}`);let c=i[2]??"";if(c.startsWith('"')){if(!c.endsWith('"'))throw Error(`Unclosed dotenv quote on line ${n+1}`);c=c.slice(1,-1).replace(/\\n/g,`
|
|
124
|
+
`).replace(/\\r/g,"\r")}else if(c.startsWith("'")){if(!c.endsWith("'"))throw Error(`Unclosed dotenv quote on line ${n+1}`);c=c.slice(1,-1)}else c=c.replace(/\s+#.*$/,"").trimEnd();t[i[1]]=c}return t}function zi(e,t){return e.split(/(?<=\n)/).filter((n)=>{let r=n.trim(),s=(r.startsWith("export ")?r.slice(7).trimStart():r).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=/)?.[1];return s===void 0||!t.has(s)}).join("")}function Bi(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 Di(e){let t={},n=new Set,r=new Set;for(let o of String(e).replace(/^\uFEFF/,"").split(/\r?\n/)){let s=o.trim();if(!s||s.startsWith("#"))continue;let c=(s.startsWith("export ")?s.slice(7).trimStart():s).match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);if(!c)continue;let a=c[1],l=c[2]??"";if(n.add(a),Bi(l)){delete t[a],r.add(a);continue}try{let d=js(`${a}=${l}`)[a];if(d===void 0)throw Error("missing literal");t[a]=l.trimStart().startsWith("'")?d:d.replace(/\\\$/g,"$"),r.delete(a)}catch{delete t[a],r.add(a)}}return{values:t,keys:[...n].sort(),dynamicKeys:[...r].sort()}}async function Ki(e){let t=Z(e,["rev-parse","--show-toplevel"]);if(t.status!==0)return!1;try{return await bs(t.stdout.trim())===e}catch{return!1}}function Ji(e,t){if(!t)return new Set;let n=Z(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(Qe))}async function Gi(e){let t=gs().add(hs),n=gs().add(hs),r=[];for(let o of[".gitignore",".hlixignore"])try{let s=Ss(e,o),i=await ks(s);if(i.isFile())n.add(await kt(s,"utf8"));else if(i.isSymbolicLink())r.push(o)}catch(s){if(s.code!=="ENOENT")throw s}return{hardMatcher:t,matcher:n,symlinked:r}}function ys(e){if(Ai.test(e))return"mcp";if(Ni.test(e))return"skill";if(Fi.test(e))return"agent";return null}function ws(e){if(xi.test(e)&&!Ii.test(e))return"dotenv";if(Ri.test(e))return"credential";return null}function qi(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 Wi(e,t){if(t)return[Qe(t)];let n=new Map([[".env",0],[".env.development",1],[".env.local",2],[".env.development.local",3]]),r=e.filter((o)=>n.has(le(o).toLocaleLowerCase("en-US"))).sort((o,s)=>o.slice(0,-le(o).length).localeCompare(s.slice(0,-le(s).length))||n.get(le(o).toLocaleLowerCase("en-US"))-n.get(le(s).toLocaleLowerCase("en-US")));return r.length>0?r:e.length===1?[...e]:[]}function Vi(e,t){try{let n=JSON.parse(t);if(!n.mcpServers||typeof n.mcpServers!=="object")return[];return Object.entries(n.mcpServers).map(([r,o])=>{let s=o&&typeof o==="object"?o:{},i=s.type==="http"||s.type==="sse"||s.type==="stdio"?s.type:typeof s.command==="string"?"stdio":typeof s.url==="string"?"http":"unknown",c=s.env&&typeof s.env==="object"?s.env:{};return{sourcePath:e,name:r,transport:i,...typeof s.command==="string"?{command:s.command}:{},...Array.isArray(s.args)&&s.args.every((a)=>typeof a==="string")?{args:s.args}:{},...typeof s.url==="string"?{url:s.url}:{},envKeys:Object.keys(c).sort(),enabled:!1}})}catch{return[]}}function Xi(e){let t=!1,n=!1;for(let r of e.split(/\r?\n/)){let o=r.trim();if(!o||o.startsWith("#")||o.startsWith(";")||o.startsWith("["))continue;let s=o.indexOf("=");if(s===-1)continue;let i=o.slice(0,s).trim().toLowerCase(),c=o.slice(s+1).trim().replace(/^["']|["']$/g,"");if(!c||/^\$(?:\{[^}]*\}|[A-Za-z_][A-Za-z0-9_]*)$/.test(c))continue;if(i.endsWith("_authtoken")||i.endsWith("_password"))return!0;if(i.endsWith("password"))n=!0;else if(i.endsWith("username"))t=!0}return t&&n}function Yi(e,t,n){if(_i.test(n))return!1;if(!Ti.test(n))return!0;let r=Z(e,["show",`${t}:${n}`]);return r.status===0&&Xi(r.stdout)}function vs(e,t,n){let r=[],o="unknown";for(let s of e.split(/\r?\n/)){if(s.startsWith("@@"))o=s.slice(2);else if(s.trim()){let i=Qe(s.trim());if(n(o,i))r.push({commit:o,path:i,reason:t})}if(r.length>=100)break}return r}function Zi(e,t){if(!t)return{head:null,branch:null,refs:[],commitCount:0,complete:!0,findings:[],blockingFindings:[]};let n=Z(e,["rev-parse","HEAD"]).stdout.trim()||null,r=Z(e,["symbolic-ref","--short","-q","HEAD"]),o=r.status===0?r.stdout.trim()||null:null,s=Number.parseInt(Z(e,["rev-list","--count","--all"]).stdout.trim(),10)||0,i=Z(e,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]),c=i.stdout.split(`
|
|
125
|
+
`).filter(Boolean).map((v)=>{let[f,p]=v.split("\x00");return{name:f,oid:p}}).filter(({name:v,oid:f})=>/^refs\/(?:heads|tags)\/.+/.test(v)&&/^[0-9a-f]{40,64}$/.test(f)).sort((v,f)=>v.name.localeCompare(f.name)),a=["log","--all",`--max-count=${bt}`,"--pretty=format:@@%H","--name-only"],l=Z(e,[...a,"--",".env",".env.*","*.pem","*.key",".npmrc","*.tfvars"]),u=Z(e,["log","--all",`--max-count=${bt}`,"-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 v of[...vs(l.stdout,"sensitive-path",(f,p)=>Yi(e,f,p)),...vs(u.stdout,"secret-pattern",()=>!0)])d.set(`${v.commit}:${v.path}:${v.reason}`,v);let m=[...d.values()].slice(0,100);return{head:n,branch:o,refs:c,commitCount:s,complete:s<=bt&&c.length<=1000&&i.status===0&&l.status===0&&u.status===0,findings:m,blockingFindings:m.filter((v)=>v.reason!=="secret-pattern"||!Oi.test(v.path))}}async function V(e,t={}){let n=await bs(fs(e));if(!(await bi(n)).isDirectory())throw Error("Import target must be a directory.");let r=await Ki(n),o=Ji(n,r),{hardMatcher:s,matcher:i,symlinked:c}=await Gi(n),a=[],l=[],u=[],d=[],m=[],v=[],f=[],p=[],g=t.envFile?Qe(ms(n,fs(n,t.envFile))):void 0,x=g!==void 0&&g!==""&&g!==".."&&!g.startsWith("../");if(t.envFile&&!x)p.push(`Selected environment file must stay inside the project: ${t.envFile}`);let b=new Map,O=new Map,L=new Map,Ee=new Map,w=[],R=[],P=[],_=new Map,ne=t.maxFiles??$i,ir=t.maxFileBytes??Pi,ar=t.maxTotalBytes??Ci,Rt=0,re=0,cr=()=>a.length+l.length+d.length+m.length,lr=async(y)=>{let E=await vi(y,{withFileTypes:!0});E.sort((F,M)=>F.name.localeCompare(M.name));for(let F of E){let M=Ss(y,F.name),C=Qe(ms(n,M));if(F.name===".git"){if(C!==".git")p.push(`Nested Git repository is not supported: ${C}`);continue}let H=await ks(M),mr=F.isDirectory()?`${C}/`:C,At=o.has(C),fr=!At&&i.ignores(mr),Xs=!At&&s.ignores(mr);if(H.isSymbolicLink()){if(fr)continue;if(cr()>=ne){p.push(`Project exceeds the ${ne} file limit, reached at ${C}. Largest folders: ${En(a.map((T)=>T.path))}. Exclude generated folders with .hlixignore.`);return}if(l.push({path:C,target:await ki(M)}),ys(C)||ws(C))u.push(C);continue}if(F.isDirectory()){if(Xs)continue;await lr(M);continue}let Ce=ys(C),Ie=ws(C);if(fr&&!Ce&&!Ie)continue;if(!F.isFile()){f.push({path:C,reason:"non-regular-file"});continue}if(cr()>=ne){p.push(`Project exceeds the ${ne} file limit, reached at ${C}. Largest folders: ${En(a.map((T)=>T.path))}. Exclude generated folders with .hlixignore.`);return}if(H.size>ir){p.push(`File ${C} is ${q(H.size)}, over the ${q(ir)} per-file limit. Exclude it with .hlixignore.`);continue}if(Rt+=H.size,Rt>ar){p.push(`Project files total at least ${q(Rt)}, over the ${q(ar)} limit. Largest so far: ${jn([...a,{path:C,size:H.size}])}. Exclude large files with .hlixignore.`);return}let xe=await Ui(M);if(Ce){if(H.size>vt){p.push(`Protected configuration ${C} is ${q(H.size)}, over the ${q(vt)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let T=await kt(M);if(re+=T.byteLength,P.push({path:C,size:T.byteLength}),re>Ye)continue;if(m.push({path:C,kind:Ce,size:H.size,sha256:xe}),R.push({path:C,kind:Ce,contentBase64:T.toString("base64")}),Ce==="mcp")v.push(...Vi(C,T.toString("utf8")));continue}if(Ie){if(H.size>vt){p.push(`Protected file ${C} is ${q(H.size)}, over the ${q(vt)} per-file limit. Move the large content out of it, or exclude it with .hlixignore.`);continue}let T=await kt(M);if(re+=T.byteLength,P.push({path:C,size:T.byteLength}),re>Ye)continue;let ie=[],Re=new Set;if(Ie==="dotenv")try{let lt=js(T),pe={};for(let[se,ue]of Object.entries(lt)){if(Ze.has(se)){Re.add(se);continue}pe[se]=ue}b.set(C,pe),ie=Object.keys(pe).sort()}catch{p.push(`Could not parse environment file: ${C}`)}else if(le(C)===".envrc"){let lt=Di(T),pe={},se=new Set,ue=[];for(let[U,Ys]of Object.entries(lt.values)){if(Ze.has(U)){Re.add(U);continue}if(Sn.has(U)){w.push(`Ignored ambient runtime assignment in ${C}: ${U}`);continue}se.add(U),pe[U]=Ys}O.set(C,pe);for(let U of lt.dynamicKeys){if(Ze.has(U)){Re.add(U);continue}if(Sn.has(U)){w.push(`Ignored ambient runtime assignment in ${C}: ${U}`);continue}se.add(U),ue.push(U)}if(L.set(C,[...se].sort()),Ee.set(C,ue.sort()),ie=[...se].sort(),ue.length>0)w.push(`Did not execute dynamic .envrc assignments; collect their resolved local values when available: ${ue.join(", ")}`)}if(Re.size>0)w.push(bn),T=Buffer.from(zi(T.toString("utf8"),Re),"utf8"),xe=$n("sha256").update(T).digest("hex");d.push({path:C,kind:Ie,keys:ie,size:T.byteLength,sha256:xe}),R.push({path:C,kind:Ie,contentBase64:T.toString("base64")});continue}if(H.size<=1048576){let T=await kt(M),ie=T.toString("utf8");if(_.set(C,ie),Li.test(ie)||Hi.test(C)&&Mi.test(ie)){if(re+=T.byteLength,P.push({path:C,size:T.byteLength}),re>Ye)continue;d.push({path:C,kind:"detected-content",keys:[],size:H.size,sha256:xe}),R.push({path:C,kind:"detected-content",contentBase64:T.toString("base64")});continue}}a.push({path:C,size:H.size,sha256:xe,tracked:At,executable:(H.mode&73)!==0})}};if(await lr(n),u.length>0){let y=u.slice(0,5).join(", "),E=u.length-5;w.push(`Imported as symlinks, so no content was read or uploaded for them and the cloud recreates the link: ${y}${E>0?`, +${E} more`:""}`)}for(let y of c)p.push(`Ignore file ${y} is a symlink, so its rules were not applied. Replace it with a regular file inside the project.`);if(re>Ye)p.push(`Protected project files total ${q(re)}, over the ${q(Ye)} limit. Largest: ${jn(P)}. Move large assets out of skill and config folders, or add them to .hlixignore.`);if(d.length>2000)p.push(`Project has ${d.length} environment and credential files, over the 2000 limit. Largest: ${jn(d)}. Exclude the ones the cloud project does not need with .hlixignore.`);if(m.length>5000)p.push(`Project has ${m.length} agent, skill and MCP files, over the 5000 limit. Largest folders: ${En(m.map((y)=>y.path))}. Exclude the ones the cloud project does not need with .hlixignore.`);a.sort((y,E)=>y.path.localeCompare(E.path)),l.sort((y,E)=>y.path.localeCompare(E.path)),d.sort((y,E)=>y.path.localeCompare(E.path)),m.sort((y,E)=>y.path.localeCompare(E.path)),v.sort((y,E)=>`${y.sourcePath}:${y.name}`.localeCompare(`${E.sourcePath}:${E.name}`));let _t=Wi([...b.keys()].sort(),x?g:void 0);if(t.envFile&&x&&!b.has(_t[0]))p.push(`Selected environment file was not found or is not a dotenv file: ${t.envFile}`);let $e=new Map;for(let[y,E]of b)for(let F of Object.keys(E))$e.set(F,[...$e.get(F)??[],y]);for(let[y,E]of L)for(let F of E)$e.set(F,[...$e.get(F)??[],y]);let Js=[...$e].filter(([,y])=>y.length>1).map(([y,E])=>({key:y,paths:E.sort()})).sort((y,E)=>y.key.localeCompare(E.key)),X={};for(let y of _t)Object.assign(X,b.get(y)??{});let Gs=[...O.keys()].sort((y,E)=>{if(y===".envrc")return 1;if(E===".envrc")return-1;return y.localeCompare(E)}),Tt=new Set;for(let y of Gs){let E=new Set(Ee.get(y)??[]);for(let F of L.get(y)??[]){if(E.has(F)){delete X[F],Tt.add(F);continue}let M=O.get(y)?.[F];if(M!==void 0)X[F]=M;Tt.delete(F)}}let Ot=t.historyMode??"abort_on_findings",B=Zi(n,r);if(!B.complete&&Ot!=="preserve")p.push(`Git history scan exceeded ${bt} commits or failed; import requires explicit --history preserve.`);let Pe=B.findings.length-B.blockingFindings.length;if(Pe>0)w.push(Pe===1?"1 Git history finding looks like a test fixture rather than a real credential and did not block this import; --history preserve is not needed for it.":`${Pe} Git history findings look like test fixtures rather than real credentials and did not block this import; --history preserve is not needed for them.`);if(B.blockingFindings.length>0&&Ot==="abort_on_findings"){let y=B.blockingFindings.length;p.push([`Potential secrets exist in Git history (${y} finding${y===1?"":"s"}${y>10?", first 10 shown":""}):`,...B.blockingFindings.slice(0,10).map((E)=>` ${E.commit.slice(0,7)} ${E.path} — ${E.reason}`),...Pe>0?[` ${Pe} more look like test fixtures or example files (not blocking)`]:[]," Sanitize the repository, or re-run with --history preserve to import it as it is."].join(`
|
|
126
|
+
`))}let dr=new Set(a.map((y)=>y.path)),qs=await ps(n,dr,_),{observedSecretKeys:Ws,...W}=qs;W.warnings.push(...w);let ct=new Set(W.requiredSecretKeys);for(let y of Tt)ct.add(y);for(let y of v)for(let E of y.envKeys)ct.add(E);for(let y of Ze)if(ct.delete(y))W.warnings.push(bn);W.requiredSecretKeys=[...ct].sort();for(let y of W.requiredSecretKeys){if(X[y]!==void 0)continue;let E=t.environment?.[y];if(E===void 0){p.push(`${Cn}${y}`);continue}X[y]=E}for(let y of Ws){if(Ze.has(y)){W.warnings.push(bn);continue}if(Sn.has(y))continue;if(X[y]!==void 0)continue;let E=t.environment?.[y];if(E===void 0){W.warnings.push(`Observed environment reference has no local value: ${y}`);continue}X[y]=E}W.warnings=[...new Set(W.warnings)].sort();let pr={schemaVersion:us,rootName:t.rootName??le(n),stack:qi(dr),git:{detected:r,head:B.head,branch:B.branch,refs:B.refs,commitCount:B.commitCount,historyScanComplete:B.complete,historyMode:Ot},files:a,symlinks:l,secretFiles:d,activeEnvFiles:_t,secretKeys:Object.keys(X).sort(),envCollisions:Js,quarantinedResources:m,mcpServers:v,historicalSecretFindings:B.findings,skipped:f,environment:W,totals:{files:a.length,bytes:a.reduce((y,E)=>y+E.size,0)}},ur=Pn(pr),Vs=$n("sha256").update(ur).digest("hex");return{root:n,manifest:pr,manifestJson:ur,manifestSha256:Vs,secretValues:X,protectedFiles:R.sort((y,E)=>y.path.localeCompare(E.path)),blocking:[...new Set(p)]}}var In={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(`
|
|
127
|
+
`),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 Qi(ea(e.cwd,e.args[0]??".")),n=J({env:e.env,flags:e.flags,cwd:t});if(n.conflict)throw new h("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 o=fe(t),s=typeof e.flags.project==="string"?e.flags.project:void 0;if(s&&o?.projectId&&o.projectId!==s)throw new h("workspace_mismatch",`This folder is bound to project ${o.projectId}; refusing to rebind it to ${s}.`);if(s)await r.projects.get(s);let i={...o??{schemaVersion:1,workspaceId:n.workspaceId,apiUrl:n.baseUrl},...s?{projectId:s}:{}};Ne(t,i);let c=await V(t,{environment:e.env}),a={root:t,config:i,scan:{files:c.manifest.totals.files,bytes:c.manifest.totals.bytes,secretFiles:c.manifest.secretFiles.map((l)=>l.path),quarantinedResources:c.manifest.quarantinedResources.map((l)=>l.path),blocking:c.blocking}};if(e.json)e.stdout(k(S(In.name,a)));else if(e.stdout(`Initialized ${t}
|
|
128
128
|
Project: ${i.projectId??"not imported yet"}
|
|
129
129
|
Workspace: ${i.workspaceId}
|
|
130
130
|
`),c.blocking.length)e.stdout(`
|
|
131
131
|
Review before import:
|
|
132
132
|
${c.blocking.map((l)=>`- ${l}`).join(`
|
|
133
133
|
`)}
|
|
134
|
-
`);return 0}};import{createHash as
|
|
135
|
-
`).at(-1)??"git command failed";throw Error(r)}return n.stdout.trim()}async function
|
|
134
|
+
`);return 0}};import{createHash as da}from"node:crypto";import{readFile as pa,realpath as ua}from"node:fs/promises";import{basename as ma,resolve as fa}from"node:path";import{createHash as ta}from"node:crypto";import{createReadStream as na}from"node:fs";import{chmod as xn,copyFile as ra,lstat as Es,mkdir as Rn,mkdtemp as sa,readdir as oa,readlink as ia,rm as _n,symlink as aa}from"node:fs/promises";import{tmpdir as ca}from"node:os";import{dirname as $s,join as ee}from"node:path";import{spawnSync as et}from"node:child_process";var tt=300000;function Q(e,t){let n=et("git",["-C",e,...t],{encoding:"utf8",timeout:tt,maxBuffer:20971520,stdio:["ignore","pipe","pipe"]});if(n.status!==0){let r=n.stderr.trim().split(`
|
|
135
|
+
`).at(-1)??"git command failed";throw Error(r)}return n.stdout.trim()}async function Ps(e){let t=ta("sha256");for await(let n of na(e))t.update(n);return t.digest("hex")}async function la(e){for(let t of await oa(e)){if(t===".git")continue;await _n(ee(e,t),{recursive:!0,force:!0})}}async function St(e){if(e.blocking.length>0)throw Error(`Project scan has blocking findings:
|
|
136
136
|
- ${e.blocking.join(`
|
|
137
|
-
- `)}`);let t=await
|
|
138
|
-
`).filter(Boolean).map((f)=>f.split("\x00",2)));for(let f of e.manifest.git.refs)if(m.get(f.name)!==f.oid)throw Error(`Git ref changed after scan: ${f.name}`);let v=et("git",["clone","--no-hardlinks",r,n],{encoding:"utf8",timeout:tt,stdio:["ignore","pipe","pipe"]});if(v.status!==0)throw Error(v.stderr.trim()||"Could not create snapshot clone.");if(!e.manifest.git.head)throw Error("Git repository has no HEAD commit.");Q(n,["checkout","-B","main",e.manifest.git.head])}else await Rn(n,{recursive:!0,mode:448}),Q(n,["init","-b","main"]);await
|
|
137
|
+
- `)}`);let t=await sa(ee(ca(),"hlix-snapshot-"));await xn(t,448);let n=ee(t,"repo"),r=ee(t,"source.git"),o=ee(t,"project.bundle");try{if(e.manifest.git.detected){let d=et("git",["clone","--mirror","--no-hardlinks",e.root,r],{encoding:"utf8",timeout:tt,stdio:["ignore","pipe","pipe"]});if(d.status!==0)throw Error(d.stderr.trim()||"Could not mirror repository.");let m=new Map(Q(r,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/tags"]).split(`
|
|
138
|
+
`).filter(Boolean).map((f)=>f.split("\x00",2)));for(let f of e.manifest.git.refs)if(m.get(f.name)!==f.oid)throw Error(`Git ref changed after scan: ${f.name}`);let v=et("git",["clone","--no-hardlinks",r,n],{encoding:"utf8",timeout:tt,stdio:["ignore","pipe","pipe"]});if(v.status!==0)throw Error(v.stderr.trim()||"Could not create snapshot clone.");if(!e.manifest.git.head)throw Error("Git repository has no HEAD commit.");Q(n,["checkout","-B","main",e.manifest.git.head])}else await Rn(n,{recursive:!0,mode:448}),Q(n,["init","-b","main"]);await la(n);for(let d of e.manifest.files){let m=ee(e.root,...d.path.split("/")),v=await Es(m);if(!v.isFile()||v.isSymbolicLink())throw Error(`Source changed after scan: ${d.path}`);if(v.size!==d.size||await Ps(m)!==d.sha256)throw Error(`Source changed after scan: ${d.path}`);let f=ee(n,...d.path.split("/"));await Rn($s(f),{recursive:!0,mode:493}),await ra(m,f),await xn(f,d.executable?493:420)}for(let d of e.manifest.symlinks){let m=ee(e.root,...d.path.split("/"));if(await ia(m).catch(()=>null)!==d.target)throw Error(`Source changed after scan: ${d.path}`);let v=ee(n,...d.path.split("/"));await Rn($s(v),{recursive:!0,mode:493}),await aa(d.target,v)}Q(n,["config","user.name","Hlix Import"]),Q(n,["config","user.email","import@hlix.ai"]),Q(n,["add","-A"]),Q(n,["commit","--allow-empty","-m","chore(hlix): import snapshot"]);let s=Q(n,["rev-parse","HEAD"]),i=e.manifest.git.refs.filter((d)=>d.name!=="refs/heads/main");if(i.length>0){let d=et("git",["-C",n,"update-ref","--stdin"],{encoding:"utf8",timeout:tt,input:i.map((m)=>`update ${m.name} ${m.oid}`).join(`
|
|
139
139
|
`)+`
|
|
140
140
|
`,stdio:["pipe","pipe","pipe"]});if(d.status!==0)throw Error(d.stderr.trim()||"Could not recreate the approved Git refs.")}let c=i.map((d)=>d.name),a=et("git",["-C",n,"bundle","create",o,"--stdin"],{encoding:"utf8",timeout:tt,input:["refs/heads/main",...c].join(`
|
|
141
141
|
`)+`
|
|
142
|
-
`,stdio:["pipe","pipe","pipe"]});if(a.status!==0)throw Error(a.stderr.trim()||"Could not create the approved Git bundle.");Q(n,["bundle","verify",o]),await xn(o,384);let l=(await
|
|
142
|
+
`,stdio:["pipe","pipe","pipe"]});if(a.status!==0)throw Error(a.stderr.trim()||"Could not create the approved Git bundle.");Q(n,["bundle","verify",o]),await xn(o,384);let l=(await Es(o)).size,u=await Ps(o);return{bundlePath:o,bundleSha256:u,bundleSize:l,commitSha:s,dispose:()=>_n(t,{recursive:!0,force:!0})}}catch(s){throw await _n(t,{recursive:!0,force:!0}),s}}function nt(e,t){let n=e[t];return typeof n==="string"&&n.trim()?n.trim():void 0}function ga(e,t){return da("sha256").update(`project-import-v1\x00${e}\x00${t}`).digest("hex")}function ha(e){let t=e.manifest.environment.install,n=e.manifest.secretFiles.length+e.manifest.quarantinedResources.length;if(t.length===0&&n===0&&e.manifest.secretKeys.length===0)return null;let r=["Hlix will upload this project and encrypted protected files to your selected workspace."];if(t.length>0)r.push("Detected cloud setup commands:",...t.map((o)=>`- ${o}`));if(e.manifest.secretKeys.length>0)r.push("Project secret keys available to cloud tasks:",...e.manifest.secretKeys.map((o)=>`- ${o}`));if(e.manifest.quarantinedResources.length>0)r.push("Quarantined resources (preserved but not activated):",...e.manifest.quarantinedResources.map((o)=>`- ${o.kind}: ${o.path}`));if(e.manifest.environment.warnings.length>0)r.push("Environment warnings:",...e.manifest.environment.warnings.map((o)=>`- ${o}`));return r.push("Setup runs inside the isolated Coding Workspace and may access project secrets."),r.join(`
|
|
143
143
|
`)}var jt={name:"import",summary:"Import a local project into your Hlix workspace",usage:["Usage: hlix import [folder] [options]","","Options:"," --dry-run Scan and report without uploading"," --env-file <path> Override automatic development dotenv precedence"," --history <mode> abort-on-findings (default) or preserve"," --name <name> Cloud project name (defaults to folder name)"," --stack <stack> Override detected stack"," --yes Approve the reviewed upload and cloud setup"," --json Machine-readable output (never contains secret values)"].join(`
|
|
144
|
-
`),supportsJson:!0,options:["dry-run","env-file","history","name","stack","yes"],args:{min:0,max:1},async run(e){if(e.args.length>1)throw Error("import accepts at most one folder.");let t=await
|
|
144
|
+
`),supportsJson:!0,options:["dry-run","env-file","history","name","stack","yes"],args:{min:0,max:1},async run(e){if(e.args.length>1)throw Error("import accepts at most one folder.");let t=await ua(fa(e.cwd,e.args[0]??".")),n=J({env:e.env,flags:e.flags,cwd:t});if(n.conflict)throw new h("workspace_mismatch",n.conflict);if(!n.workspaceId||!n.credential)throw new h("workspace_required","No workspace selected. Run `hlix auth login` first.");let r=fe(t);if(r?.projectId)throw new h("already_imported","This folder is already bound to an Hlix project. Use `hlix push`.");let o=nt(e.flags,"history");if(o&&o!=="preserve"&&o!=="abort-on-findings")throw Error("--history must be `abort-on-findings` or `preserve`.");if(!r&&e.flags["dry-run"]!==!0)Ne(t,{schemaVersion:1,workspaceId:n.workspaceId,apiUrl:n.baseUrl});let s=await V(t,{...nt(e.flags,"env-file")?{envFile:nt(e.flags,"env-file")}:{},environment:e.env,historyMode:o==="preserve"?"preserve":"abort_on_findings"});if(e.flags["dry-run"]!==!0&&s.blocking.length===0){let a=ha(s);if(a&&e.flags.yes!==!0){if(e.json||!e.confirm)throw new h("approval_required","Import needs approval for protected files or cloud setup. Review with `hlix import --dry-run`, then repeat with `--yes`.");if(!await e.confirm(a))throw new h("cancelled","Import cancelled.")}}let i={root:t,name:nt(e.flags,"name")??ma(t),stack:nt(e.flags,"stack")??s.manifest.stack,files:s.manifest.totals.files,bytes:s.manifest.totals.bytes,symlinks:s.manifest.symlinks,activeEnvFiles:s.manifest.activeEnvFiles,secretKeys:s.manifest.secretKeys,protectedFiles:s.manifest.secretFiles.length+s.manifest.quarantinedResources.length,environment:s.manifest.environment,historicalSecretFindings:s.manifest.historicalSecretFindings,quarantinedResources:s.manifest.quarantinedResources,mcpServers:s.manifest.mcpServers,skipped:s.manifest.skipped,blocking:s.blocking,manifestSha256:s.manifestSha256};if(e.flags["dry-run"]===!0){if(e.json)e.stdout(k(S(jt.name,i)));else{let a=[...s.manifest.secretFiles.map((l)=>`${l.kind}: ${l.path}`),...s.manifest.quarantinedResources.map((l)=>`${l.kind}: ${l.path}`)];e.stdout([`Project: ${i.name}`,`Stack: ${i.stack}`,`Files: ${i.files}`,`Bytes: ${i.bytes}`,`Environment confidence: ${i.environment.confidence}`,`History findings: ${i.historicalSecretFindings.length}`,"","Environment evidence:",...i.environment.sources.length?i.environment.sources.map((l)=>`- ${l.kind}: ${l.path}`):["- none detected"],"","Cloud setup commands:",...i.environment.install.length?i.environment.install.map((l)=>`- ${l}`):["- none detected"],"","Required secret keys:",...i.environment.requiredSecretKeys.length?i.environment.requiredSecretKeys.map((l)=>`- ${l}`):["- none detected"],"","Collected secret keys:",...i.secretKeys.length?i.secretKeys.map((l)=>`- ${l}`):["- none detected"],"","Protected and quarantined paths:",...a.length?a.map((l)=>`- ${l}`):["- none"],"","Environment warnings:",...i.environment.warnings.length?i.environment.warnings.map((l)=>`- ${l}`):["- none"],"","Symlinks (stored as links, targets never read):",...i.symlinks.length?i.symlinks.map((l)=>`- ${l.path} -> ${l.target}`):["- none"],"","Skipped paths:",...i.skipped.length?i.skipped.map((l)=>`- ${l.reason}: ${l.path}`):["- none"],...i.blocking.length?["","Blocking findings:",...i.blocking.map((l)=>`- ${l}`)]:[]].join(`
|
|
145
145
|
`)+`
|
|
146
|
-
`)}return s.blocking.length?1:0}if(s.blocking.length)throw new
|
|
146
|
+
`)}return s.blocking.length?1:0}if(s.blocking.length)throw new h("scan_blocked",`Project scan blocked import:
|
|
147
147
|
- ${s.blocking.join(`
|
|
148
|
-
- `)}`);let c=await
|
|
148
|
+
- `)}`);let c=await St(s);try{let a=e.requireClient(t),l=await a.imports.create({idempotencyKey:ga(s.manifestSha256,c.bundleSha256),name:i.name,stack:i.stack,defaultBranch:"main",historyMode:s.manifest.git.historyMode,manifest:s.manifest,manifestSha256:s.manifestSha256,bundleSha256:c.bundleSha256,bundleSize:c.bundleSize,commitSha:c.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 a.imports.uploadBundle(l.upload,new Blob([Uint8Array.from(await pa(c.bundlePath))]),{onProgress:(f,p)=>{if(!e.json)e.stderr(`Uploading ${f}/${p} bytes\r`)}})}let d=(l.import.status==="ready"?{import:l.import}:await a.imports.finalize(l.import.id,{secrets:s.secretValues,protectedFiles:s.protectedFiles})).import,m=d.projectId??d.requestedProjectId;if(!m||!d.revisionId||!d.generation)throw Error("Import completed without project revision metadata.");Ne(t,{schemaVersion:1,projectId:m,workspaceId:n.workspaceId,apiUrl:n.baseUrl}),Le(t,{schemaVersion:1,revisionId:d.revisionId,generation:d.generation,commitSha:c.commitSha,manifestSha256:s.manifestSha256,historyMode:s.manifest.git.historyMode,rootName:s.manifest.rootName});let v={projectId:m,revisionId:d.revisionId,generation:d.generation,commitSha:c.commitSha,files:s.manifest.totals.files,bytes:s.manifest.totals.bytes};if(e.json)e.stdout(k(S(jt.name,v)));else e.stderr(`
|
|
149
149
|
`),e.stdout(`Imported ${i.name}
|
|
150
150
|
Project ID: ${m}
|
|
151
151
|
Revision: ${d.generation}
|
|
152
|
-
`);return 0}finally{await c.dispose()}}};import{spawnSync as
|
|
152
|
+
`);return 0}finally{await c.dispose()}}};import{spawnSync as ya}from"node:child_process";import{existsSync as wa,mkdirSync as va,writeFileSync as ka}from"node:fs";import{dirname as ba}from"node:path";function Sa(e){return e==="global"?["# My rules","","Hlix Code reads this file in every project you open, before the project's","own rules. Write how you want an agent to work with you: the tone, the","things to always do, the things to never do.",""].join(`
|
|
153
153
|
`):["# Project rules","","Hlix Code and every other coding agent that opens this repository read","this file. Write the rules that are true of THIS project: how to run its","tests, its conventions, what not to touch.",""].join(`
|
|
154
|
-
`)}function
|
|
155
|
-
`),supportsJson:!0,options:["edit","global"],async run(e){let t=
|
|
156
|
-
`);let o=
|
|
154
|
+
`)}function ja(e){return e.VISUAL?.trim()||e.EDITOR?.trim()||"vi"}var Tn={name:"rules",summary:"Show or edit the rules files the coding agent reads",usage:["Usage: hlix rules [--edit] [--global] [--cwd <dir>] [--json]","","Without --edit it reports which files Hlix Code loads and how big they are.","","--edit opens one in $EDITOR, creating it with a short header if it does not","exist yet. --global edits your own rules (~/.hlix/AGENTS.md, read in every",`project); without it the project's file (${sn.join(", then ")}).`].join(`
|
|
155
|
+
`),supportsJson:!0,options:["edit","global"],async run(e){let t=es({cwd:e.cwd,configDir:".hlix",env:e.env}),n=e.flags.global===!0;if(e.flags.edit===!0){if(e.json)throw new h("invalid_usage","`hlix rules --edit` opens an editor, so it has no --json form.");let r=n?an(e.env):on(e.cwd,".hlix")?.path??`${e.cwd}/AGENTS.md`;if(!wa(r))va(ba(r),{recursive:!0}),ka(r,Sa(n?"global":"project"),"utf8"),e.stdout(`Created ${r}.
|
|
156
|
+
`);let o=ja(e.env),s=ya(o,[r],{stdio:"inherit"});if(s.error)throw new h("invalid_usage",`Could not run ${o}: ${s.error.message}`);return s.status??0}if(e.json){let r=(o)=>o?{path:o.path,characters:o.content.length}:null;return e.stdout(k(S(Tn.name,{user:r(t.global),project:r(t.project)}))),0}return e.stdout(`${ts(t,e.cwd)}
|
|
157
157
|
`),0}};var On={name:"standards",summary:"Show the standards other agent tools left in this folder",usage:["Usage: hlix standards [--cwd <dir>] [--json]","","Reads the instruction files, skills, slash commands, MCP servers and","subagents this project already carries for Claude Code, Cursor, Windsurf,","Gemini, Codex, Cline, Copilot and VS Code, and shows where each came from.","Hlix Code loads all of it at startup; nothing has to be copied or rewritten.","","Server urls, headers and environment values are never printed."].join(`
|
|
158
|
-
`),supportsJson:!0,async run(e){let t=
|
|
159
|
-
`),supportsJson:!0,async run(e){let t=J({env:e.env,flags:e.flags,cwd:e.cwd}),n=t.binding,r=n?ft(n.root):null,o=n?await
|
|
160
|
-
`),0}};import{spawnSync as
|
|
161
|
-
`),supportsJson:!0,options:["print","web"],args:{min:0,max:1},async run(e){let t=e.args[0]??N(e.cwd)?.config.projectId;if(!t)throw new
|
|
162
|
-
`),0;if(o){if(
|
|
163
|
-
`);return 0}return
|
|
164
|
-
`).at(-1)??"Git command failed");return n.stdout.trim()}function
|
|
165
|
-
`)}function
|
|
158
|
+
`),supportsJson:!0,async run(e){let t=rs(e.cwd,wt(e.env),{env:e.env});if(e.json)return e.stdout(k(S(On.name,{instructions:t.instructions.map((n)=>({path:n.path,source:n.source,scope:n.scope,characters:n.content.length,...n.note?{note:n.note}:{}})),skills:t.skills,commands:[...t.commands.map((n)=>({path:n.path,source:n.source,scope:n.scope})),...t.generatedCommands.map((n)=>({path:n.path,source:n.source,scope:n.scope,command:n.name}))],mcpServers:t.mcpServers.map((n)=>({path:n.path,source:n.source,scope:n.scope,name:n.name,transport:"command"in n.config?"stdio":"http"})),subagents:t.subagents.map((n)=>({path:n.path,source:n.source,scope:n.scope,name:n.name,description:n.description,...n.model?{model:n.model}:{}})),skipped:t.skipped}))),0;return e.stdout(os(t,e.cwd)),0}};var Cs=(e)=>e instanceof Error?e.message:String(e),Ea=(e)=>e.split(/\s*\n\s*/).join(" ").trim();async function $a(e,t,n,r,o){try{let s=await V(t,{historyMode:n,environment:e.env,rootName:r});return{files:s.manifest.totals.files,manifestSha256:s.manifestSha256,changed:o?s.manifestSha256!==o:null,blocking:s.blocking,error:null}}catch(s){return{files:null,manifestSha256:null,changed:null,blocking:[],error:Cs(s)}}}var An={name:"status",summary:"Show the workspace, folder binding, and local-vs-cloud drift",usage:["Usage: hlix status [--cwd <dir>] [--json]","","Reports the resolved workspace and API with the source that decided each,","whether this folder is bound to a project, and whether the working tree or","the cloud head has moved since the last sync. Every finding is a line in","the output, so the command itself always exits 0; only an argument error","(rejected before it runs) exits 2."].join(`
|
|
159
|
+
`),supportsJson:!0,async run(e){let t=J({env:e.env,flags:e.flags,cwd:e.cwd}),n=t.binding,r=n?ft(n.root):null,o=n?await $a(e,n.root,r?.historyMode??"preserve",r?.rootName,r?.manifestSha256):null,s=null;if(n?.config.projectId&&t.credential&&!t.conflict)try{let a=(await e.requireClient().revisions.head(n.config.projectId)).revision;s={revisionId:a.id,generation:a.generation,changed:r?a.id!==r.revisionId||a.generation!==r.generation:null,error:null,errorMessage:null}}catch(a){s={revisionId:"",generation:0,changed:null,error:Yt(a).code,errorMessage:Cs(a)}}let i={cwd:e.cwd,workspace:{id:t.workspaceId,source:t.workspaceSource},api:{baseUrl:t.baseUrl,source:t.baseUrlSource},credential:{present:t.credential!==null,source:t.credentialSource,path:t.credentialPath},conflict:t.conflict,project:n?{root:n.root,projectId:n.config.projectId??null,workspaceId:n.config.workspaceId,apiUrl:n.config.apiUrl}:null,revision:r?{id:r.revisionId,generation:r.generation,commitSha:r.commitSha}:null,local:o,cloud:s};if(e.json)return e.stdout(k(S(An.name,i))),0;let c=[["folder",e.cwd],["workspace",t.workspaceId?`${t.workspaceId} (from ${t.workspaceSource})`:"none — run `hlix auth login --workspace <id>`"],["api",`${t.baseUrl} (from ${t.baseUrlSource})`],["credential",ht(t)??"none — run `hlix auth login`"],["project",n?n.config.projectId??`initialized at ${n.root}, not imported yet`:"none — run `hlix import .` to bind this folder"]];if(r)c.push(["revision",`generation ${r.generation} (${r.revisionId})`]);if(o){if(c.push(["local",o.error?`could not scan: ${o.error}`:o.changed===null?`${o.files} files, no synced base revision`:o.changed?`${o.files} files, modified since the last sync`:`${o.files} files, matches the last sync`]),o.blocking.length>0)c.push(["blocking",o.blocking.join("; ")])}if(s)c.push(["cloud",s.error?`not checked — ${Ea(s.errorMessage??s.error)}`:s.changed?`generation ${s.generation} available — run \`hlix pull\``:`generation ${s.generation}, up to date`]);if(t.conflict)c.push(["conflict",t.conflict]);return e.stdout(`${A(c)}
|
|
160
|
+
`),0}};import{spawnSync as Is}from"node:child_process";var Fn={name:"terminal",summary:"Open a shell into the project's Coding Workspace",usage:["Usage: hlix terminal [project-id] [--print] [--web] [--json]","","With no id, the project this folder is bound to is used."," --print Show the ssh command and browser url instead of connecting"," --web Open the browser terminal instead of ssh"].join(`
|
|
161
|
+
`),supportsJson:!0,options:["print","web"],args:{min:0,max:1},async run(e){let t=e.args[0]??N(e.cwd)?.config.projectId;if(!t)throw new h("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(k(S(Fn.name,n))),n.available?0:1;if(!n.available){let i=n.environmentState?` (environment: ${n.environmentState})`:"";throw new h("not_found",`${n.reason??"Terminal unavailable"}${i}`)}let r=e.flags.print===!0,o=e.flags.web===!0;if(r||o&&!n.webTerminalUrl||!o&&!n.sshCommand)return e.stdout(`${A([["ssh",n.sshCommand??"not available"],["browser",n.webTerminalUrl??"not available"]])}
|
|
162
|
+
`),0;if(o){if(Is(process.platform==="darwin"?"open":"xdg-open",[n.webTerminalUrl],{stdio:"ignore"}).status!==0)e.stdout(`${n.webTerminalUrl}
|
|
163
|
+
`);return 0}return Is("sh",["-c",n.sshCommand],{stdio:"inherit"}).status??1}};import{createHash as Ba}from"node:crypto";import{readFile as Da,realpath as Ka}from"node:fs/promises";import{createHash as Pa}from"node:crypto";import{constants as Et}from"node:fs";import{chmod as xs,copyFile as Ca,lstat as Nn,mkdir as Ia,mkdtemp as xa,open as Ra,realpath as _a,rename as Ta,rm as de,symlink as Oa,writeFile as Aa}from"node:fs/promises";import{tmpdir as Fa}from"node:os";import{dirname as Os,join as te,relative as Na,resolve as La,sep as Rs}from"node:path";import{spawnSync as Ha}from"node:child_process";var Ma=300000;function As(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:{},o=r.historyMode==="preserve"||r.historyMode==="abort_on_findings"?r.historyMode:void 0,s=typeof n.rootName==="string"&&n.rootName.trim()?n.rootName:void 0;return{historyMode:o,rootName:s}}function Fs(e,t){let n=e;if(typeof n==="string")try{n=JSON.parse(n)}catch{return[]}if(!n||typeof n!=="object")return[];let r=n[t];if(!Array.isArray(r))return[];return r.filter((o)=>!!o&&typeof o==="object")}function Ns(e){return Fs(e,"files").flatMap((t)=>typeof t.path==="string"&&typeof t.sha256==="string"?[{path:t.path,sha256:t.sha256}]:[])}function Ln(e){return Fs(e,"symlinks").flatMap((t)=>typeof t.path==="string"&&typeof t.target==="string"?[{path:t.path,target:t.target}]:[])}function rt(e,t){let n=Ha("git",["-C",e,...t],{encoding:"utf8",timeout:Ma,maxBuffer:52428800,stdio:["ignore","pipe","pipe"]});if(n.status!==0)throw Error(n.stderr.trim().split(`
|
|
164
|
+
`).at(-1)??"Git command failed");return n.stdout.trim()}function _s(e){return Pa("sha256").update(e).digest("hex")}async function $t(e,t,n){let r=await _a(e),o=La(r,...t.split("/"));if(o!==r&&!o.startsWith(r+Rs))throw Error(`Protected path escapes the project: ${t}`);let s=Na(r,Os(o)),i=r;for(let c of s.split(Rs).filter(Boolean)){i=te(i,c);try{let a=await Nn(i);if(a.isSymbolicLink()&&n){n.push(i);break}if(!a.isDirectory()||a.isSymbolicLink())throw Error(`Protected path crosses a non-directory: ${t}`)}catch(a){if(a.code!=="ENOENT")throw a;if(!n)await Ia(i,{mode:448})}}return o}async function Ts(e,t,n){let r=await $t(e,t);try{let i=await Nn(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 o=te(Os(r),`.hlix-pull-${crypto.randomUUID()}.tmp`),s=await Ra(o,Et.O_WRONLY|Et.O_CREAT|Et.O_EXCL|Et.O_NOFOLLOW,384);try{await s.writeFile(n),await s.sync()}finally{await s.close()}try{await Ta(o,r)}catch(i){throw await de(o,{force:!0}),i}}async function Ua(e,t,n){let r=n.length,o=await $t(e,t,n);if(n.length>r)return;try{let s=await Nn(o);if(s.isSymbolicLink()){n.push(o);return}if(!s.isFile())throw Error(`Refusing to replace non-regular project file: ${t}`)}catch(s){if(s.code!=="ENOENT")throw s}}async function Ls(e,t,n,r,o){let s=await xa(te(Fa(),"hlix-pull-"));await xs(s,448);let i=te(s,"project.bundle"),c=te(s,"checkout");try{let a=Buffer.from(await r.arrayBuffer());if(a.byteLength!==n.bundleSize||_s(a)!==n.bundleSha256)throw Error("Downloaded revision bundle failed integrity verification.");if(await Aa(i,a,{mode:384}),rt(s,["clone","--no-hardlinks","--branch","main",i,c]),rt(c,["bundle","verify",i]),rt(c,["rev-parse","HEAD"])!==n.commitSha)throw Error("Downloaded revision bundle does not match the cloud commit.");let l=n.manifest,u=new Map;for(let p of[...l.secretFiles,...l.quarantinedResources])u.set(p.path,p);if(o.files.length!==u.size)throw Error("Cloud protected files do not match the revision manifest.");let d=new Map;for(let p of o.files){let g=u.get(p.path),x=Buffer.from(p.contentBase64,"base64");if(x.toString("base64").replace(/=+$/,"")!==p.contentBase64.replace(/=+$/,"")||!g||g.kind!==p.kind||x.byteLength!==g.size||_s(x)!==g.sha256)throw Error(`Cloud protected file failed integrity verification: ${p.path}`);d.set(p.path,x)}let m=Ln(n.manifest),v=new Set([...l.files.map((p)=>p.path),...m.map((p)=>p.path),...t.manifest.secretFiles.map((p)=>p.path),...t.manifest.quarantinedResources.map((p)=>p.path),...d.keys()]),f=[];for(let p of[...v].sort())await Ua(e,p,f);for(let[p,g]of d)await Ts(c,p,g);for(let p of[...new Set(f)].sort())await de(p,{force:!0});if(t.manifest.git.detected){rt(e,["fetch",i,"refs/heads/main"]),rt(e,["reset","--hard","FETCH_HEAD"]);let p=new Set([...l.files.map((g)=>g.path),...m.map((g)=>g.path)]);for(let g of[...t.manifest.files,...t.manifest.symlinks])if(!p.has(g.path))await de(te(e,...g.path.split("/")),{force:!0})}else{for(let p of[...t.manifest.files,...t.manifest.symlinks])await de(te(e,...p.path.split("/")),{force:!0});for(let p of l.files){let g=await $t(e,p.path);await Ca(te(c,...p.path.split("/")),g),await xs(g,p.executable?493:420)}for(let p of m){let g=await $t(e,p.path);await de(g,{force:!0}),await Oa(p.target,g)}}for(let p of[...t.manifest.secretFiles,...t.manifest.quarantinedResources])if(!d.has(p.path))await de(te(e,...p.path.split("/")),{force:!0});for(let[p,g]of d)await Ts(e,p,g)}finally{await de(s,{recursive:!0,force:!0})}}function Se(e,t,n){let r=new Map([...Ns(n.manifest).map((a)=>[a.path,`blob:${a.sha256}`]),...Ln(n.manifest).map((a)=>[a.path,`link:${a.target}`])]),o=new Map([...e.manifest.files.map((a)=>[a.path,`blob:${a.sha256}`]),...e.manifest.symlinks.map((a)=>[a.path,`link:${a.target}`])]),s=0,i=0;for(let[a,l]of o){let u=r.get(a);if(u===void 0)s+=1;else if(u!==l)i+=1}let c=0;for(let a of r.keys())if(!o.has(a))c+=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:o.size,cloud:r.size,localOnly:s,cloudOnly:c,differing:i}}}function Hn(e,t,n){let{localChanged:r,cloudChanged:o}=t;if(e==="push")return o?"conflict":r?"push":"none";if(e==="pull"){if(!o)return"none";return r&&!n?"conflict":"pull"}if(r&&o)return"conflict";return r?"push":o?"pull":"none"}function Mn(e,t,n){return e==="pull"&&t.localChanged&&!n}var za={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 Hs(e,t,n,r){let o=n.files;return[`${e} --dry-run: ${za[e][t]}`,...r?["Requires --yes (or interactive approval) to execute."]:[],"",A([["local",`generation ${n.local.generation} (${n.local.revisionId})${n.localChanged?" — modified":""}`],["cloud",`generation ${n.cloud.generation} (${n.cloud.revisionId})${n.cloudChanged?" — ahead":""}`],["files",`${o.local} local, ${o.cloud} cloud — ${o.localOnly} local-only, ${o.cloudOnly} cloud-only, ${o.differing} differing`]])].join(`
|
|
165
|
+
`)}function Ja(e,t,n){return Ba("sha256").update(`project-push-v1\x00${e}\x00${t}\x00${n}`).digest("hex")}var Ga={schemaVersion:1,revisionId:"",generation:0,commitSha:""};async function je(e,{allowUnsynced:t=!1}={}){let n=N(e);if(!n?.config.projectId)throw new h("not_initialized","This folder is not bound to an imported Hlix project. Run `hlix import .` first.");let r=ft(n.root)??(t?Ga:null);if(!r)throw new h("not_initialized","This folder is bound to a project but has never been pulled. Run `hlix pull` first.");return{root:await Ka(n.root),config:n.config,state:r}}async function st(e,t,n,r){let o=await V(e,{historyMode:n,environment:t,rootName:r});if(o.blocking.length>0)throw new h("scan_blocked",`Project scan blocked sync:
|
|
166
166
|
- ${o.blocking.join(`
|
|
167
|
-
- `)}`);return o}async function Un(e,t,n,r){let{state:o,config:s}=await je(r,{allowUnsynced:n==="pull"}),i=e.requireClient(),[c,a]=await Promise.all([st(r,e.env,o.historyMode??"preserve",o.rootName),i.revisions.head(s.projectId)]),l=
|
|
168
|
-
`);return u==="conflict"?1:0}async function
|
|
169
|
-
`);if(!await e.confirm(n))throw new
|
|
167
|
+
- `)}`);return o}async function Un(e,t,n,r){let{state:o,config:s}=await je(r,{allowUnsynced:n==="pull"}),i=e.requireClient(),[c,a]=await Promise.all([st(r,e.env,o.historyMode??"preserve",o.rootName),i.revisions.head(s.projectId)]),l=Se(c,o,a.revision),u=Hn(n,l,e.flags.force===!0),d=Mn(u,l,e.flags.yes===!0);if(e.json)e.stdout(k(S(t,{dryRun:!0,action:u,approvalRequired:d,...l})));else e.stdout(`${Hs(n,u,l,d)}
|
|
168
|
+
`);return u==="conflict"?1:0}async function qa(e,t){if(e.flags.yes===!0)return;if(e.json||!e.confirm)throw new h("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(`
|
|
169
|
+
`);if(!await e.confirm(n))throw new h("cancelled","Pull cancelled.")}async function Ms(e,t,n,r){let{state:o,config:s}=await je(e),i=t.requireClient(),c=o.historyMode??"preserve",a=n??await st(e,t.env,c,o.rootName),l=r??(await i.revisions.head(s.projectId)).revision;if(l.id!==o.revisionId||l.generation!==o.generation)throw new h("conflict","Cloud changed since the local base. Run `hlix pull` or resolve with `hlix sync`.");if(o.manifestSha256&&a.manifestSha256===o.manifestSha256)return{action:"none",revisionId:o.revisionId,generation:o.generation};let u=await St(a);try{let d=await i.revisions.createUpload(s.projectId,{idempotencyKey:Ja(o.revisionId,a.manifestSha256,u.bundleSha256),expectedRevisionId:o.revisionId,expectedGeneration:o.generation,manifest:a.manifest,manifestSha256:a.manifestSha256,bundleSha256:u.bundleSha256,bundleSize:u.bundleSize,commitSha:u.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 Da(u.bundlePath))]),{onProgress:(v,f)=>{if(!t.json)t.stderr(`Uploading ${v}/${f} bytes\r`)}})}let m=await i.revisions.finalize(s.projectId,d.revisionUpload.id,{secrets:a.secretValues,protectedFiles:a.protectedFiles});if(!m.revision)throw Error("Revision finalized without head metadata.");return Le(e,{schemaVersion:1,revisionId:m.revision.id,generation:m.revision.generation,commitSha:m.revision.commitSha,manifestSha256:m.revision.manifestSha256,historyMode:c,rootName:o.rootName??a.manifest.rootName}),{action:"push",...m.revision}}finally{await u.dispose()}}async function Us(e,t,n,r,o){let{state:s,config:i}=await je(e,{allowUnsynced:!0}),c=t.requireClient(),a=s.historyMode??"preserve",l=r??await st(e,t.env,a,s.rootName),u=o??(await c.revisions.head(i.projectId)).revision;if(u.id===s.revisionId&&u.generation===s.generation)return{action:"none",revisionId:s.revisionId,generation:s.generation};let d=s.manifestSha256?l.manifestSha256!==s.manifestSha256:(()=>{let{files:b}=Se(l,s,u);return b.localOnly+b.differing>0})();if(d&&!n)throw new h("conflict","Local files changed since the last sync. Push them, or use `hlix pull --force` to replace them.");if(d)await qa(t,Se(l,s,u));let[m,v]=await Promise.all([c.revisions.downloadBundle(i.projectId,u.id),c.revisions.protectedFiles(i.projectId)]);await Ls(e,l,u,m,v);let f=As(u.manifest),p=f.historyMode??a,g=f.rootName??s.rootName??l.manifest.rootName,x=await st(e,t.env,p,g);return Le(e,{schemaVersion:1,revisionId:u.id,generation:u.generation,commitSha:u.commitSha,manifestSha256:x.manifestSha256,historyMode:p,rootName:g}),{action:"pull",revisionId:u.id,generation:u.generation,commitSha:u.commitSha}}function zn(e,t,n){if(e.json)e.stdout(k(S(t,n)));else if("action"in n&&n.action==="none")e.stdout(`Already in sync.
|
|
170
170
|
`);else e.stdout(`${String("action"in n?n.action:"sync")} complete.
|
|
171
|
-
`)}var Pt={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 je(e.cwd);if(e.flags["dry-run"]===!0)return Un(e,Pt.name,"push",t);return zn(e,Pt.name,await
|
|
172
|
-
`),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 je(e.cwd,{allowUnsynced:!0});if(e.flags["dry-run"]===!0)return Un(e,Ct.name,"pull",t);return zn(e,Ct.name,await
|
|
173
|
-
`)}var qn={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=Kn(e.cwd),n=Dn(e.cwd,e.args[0]),r=await
|
|
174
|
-
`),supportsJson:!0,options:["project"],async run(e){let{projectId:t}=at(e),n=await e.requireClient().secrets.listEntries(t);if(e.json)return e.stdout(S(
|
|
171
|
+
`)}var Pt={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 je(e.cwd);if(e.flags["dry-run"]===!0)return Un(e,Pt.name,"push",t);return zn(e,Pt.name,await Ms(t,e)),0}},Ct={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(`
|
|
172
|
+
`),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 je(e.cwd,{allowUnsynced:!0});if(e.flags["dry-run"]===!0)return Un(e,Ct.name,"pull",t);return zn(e,Ct.name,await Us(t,e,e.flags.force===!0)),0}},It={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 je(e.cwd);if(e.flags["dry-run"]===!0)return Un(e,It.name,"sync",t);let o=e.requireClient(),[s,i]=await Promise.all([st(t,e.env,n.historyMode??"preserve",n.rootName),o.revisions.head(r.projectId)]),c=i.revision,a=Se(s,n,c);if(a.localChanged&&a.cloudChanged)throw new h("conflict","Both local and cloud changed since the last sync. Pull or push explicitly after reviewing the conflict.");let l=a.localChanged?await Ms(t,e,s,c):a.cloudChanged?await Us(t,e,!1,s,c):{action:"none",revisionId:n.revisionId,generation:n.generation};return zn(e,It.name,l),0}};import{lstat as zs,readFile as Wa,realpath as Va}from"node:fs/promises";import{basename as Bn,dirname as Xa,extname as Ya,join as Za,parse as Bs,resolve as Dn}from"node:path";function ot(e,t){let n=e.flags[t];return typeof n==="string"&&n.trim()?n.trim():void 0}function Kn(e){let t=N(e);if(!t?.config.projectId)throw new h("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 Jn(e,t){let n=await zs(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 Va(e),content:await Wa(e,"utf8")}}function Gn(e,t,n,r){if(e.json)e.stdout(k(S(t,n)));else e.stdout(`${r}
|
|
173
|
+
`)}var qn={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=Kn(e.cwd),n=Dn(e.cwd,e.args[0]),r=await zs(n);if(r.isSymbolicLink())throw Error(`Refusing to import a symlink: ${n}`);let o=r.isDirectory()?Za(n,"SKILL.md"):n,s=await Jn(o,200000),i=r.isDirectory()?Bn(n):Bn(o)==="SKILL.md"?Bn(Xa(o)):Bs(o).name,c=ot(e,"name")??i;if(!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(c))throw Error("Skill name must be a lowercase kebab-case slug.");let a=await e.requireClient().resources.importSkill(t.projectId,{slug:c,content:s.content});return Gn(e,qn.name,a.skill,`Imported skill ${c}`),0}},Wn={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=Kn(e.cwd),n=Dn(e.cwd,e.args[0]);if(![".md",".mdx"].includes(Ya(n).toLowerCase()))throw Error("Agent imports must be Markdown files.");let r=await Jn(n,20000),o=ot(e,"runtime")??"hlix";if(!["claude-code","codex","cursor-agent","hlix"].includes(o))throw Error("--runtime must be claude-code, codex, cursor-agent, or hlix.");let s=ot(e,"duty")??"executor";if(s!=="executor"&&s!=="intake")throw Error("--duty must be executor or intake.");let i=ot(e,"name")??Bs(n).name.replace(/[-_]+/g," "),c=await e.requireClient().resources.importAgent(t.projectId,{name:i,instructions:r.content,runtimeKind:o,duty:s});return Gn(e,Wn.name,c.agent,c.agent.duty==="intake"?`Imported agent ${c.agent.name} as this project's intake agent`:`Imported agent ${c.agent.name}`),0}},Vn={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=Kn(e.cwd),n=await Jn(Dn(e.cwd,e.args[0]),200000),r;try{r=JSON.parse(n.content)}catch{throw Error("MCP config is not valid JSON.")}let o=Object.entries(r.mcpServers??{});if(o.length===0)throw Error("MCP config contains no servers.");let s=ot(e,"server");if(!s&&o.length>1)throw Error("MCP config contains multiple servers; select one with --server <name>.");let i=s?o.find(([p])=>p===s):o[0];if(!i)throw Error(`MCP server not found: ${s}`);let[c,a]=i,l=a.type==="http"||a.type==="sse"?a.type:typeof a.command==="string"?"stdio":typeof a.url==="string"?"http":null;if(!l)throw Error(`MCP server ${c} 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 u=a.env&&typeof a.env==="object"&&!Array.isArray(a.env)?a.env:{},d=a.headers&&typeof a.headers==="object"&&!Array.isArray(a.headers)?a.headers:{};if(Object.values(d).some((p)=>typeof p!=="string"))throw Error(`MCP server ${c} headers must be strings.`);let m=Object.values(d).flatMap((p)=>[...p.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g)].map((g)=>g[1]));if(Object.keys(d).length>0&&m.length===0)throw Error("MCP remote headers must use ${KEY} placeholders; literal credentials are refused.");let v=/^(?:(?:Bearer|Basic|Token) )?\$\{[A-Za-z_][A-Za-z0-9_]*\}$/i;if(Object.values(d).some((p)=>!v.test(p)))throw Error("MCP remote headers must be ${KEY} or an approved auth scheme followed by ${KEY}.");let f=await e.requireClient().resources.importMcp(t.projectId,{name:c,transport:l,...typeof a.command==="string"?{command:a.command}:{},...Array.isArray(a.args)&&a.args.every((p)=>typeof p==="string")?{args:a.args}:{},...typeof a.url==="string"?{url:a.url}:{},...Object.keys(d).length>0?{headers:d}:{},envKeys:[...new Set([...Object.keys(u),...m])].sort()});return Gn(e,Vn.name,f.mcpServer,`Imported MCP server ${c}`),0}};import{spawnSync as Qa}from"node:child_process";import{chmod as ec,realpath as tc,writeFile as nc}from"node:fs/promises";import{basename as rc,dirname as sc,relative as oc,resolve as Ks,sep as ic}from"node:path";var Ds=64;function at(e){let t=N(e.cwd),r=(typeof e.flags.project==="string"?e.flags.project:void 0)??t?.config.projectId;if(!r)throw new h("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 it=(e,t)=>typeof e[t]==="string"?e[t]:void 0,Xn={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(`
|
|
174
|
+
`),supportsJson:!0,options:["project"],async run(e){let{projectId:t}=at(e),n=await e.requireClient().secrets.listEntries(t);if(e.json)return e.stdout(k(S(Xn.name,n))),0;if(n.entries.length===0)e.stdout(`No secrets stored for this project.
|
|
175
175
|
`);else e.stdout(`${Y(["key","source","format","value","updated"],n.entries.map((r)=>[r.key,r.source,r.format||"-",r.maskedValue,r.updatedAt?.slice(0,10)??"-"]))}
|
|
176
176
|
`);for(let r of n.warnings)e.stderr(`warning: ${r}
|
|
177
177
|
`);return 0}},Yn={name:"secrets set",summary:"Create or replace one secret in the store",usage:["Usage: hlix secrets set <KEY> [value] [--from-stdin] [--source <file>] [--project <id>] [--json]",""," --from-stdin Read the value from stdin instead of the argument, so it"," never reaches shell history or `ps`. Use this for real"," credentials: `pbpaste | hlix secrets set API_KEY --from-stdin`."," --source The file the value belongs to, e.g. apps/api/.env.local."," Omitted means the project root .env.","","Exactly one trailing newline is stripped from stdin, so a piped value does","not acquire the shell's."].join(`
|
|
178
|
-
`),supportsJson:!0,options:["from-stdin","source","project"],args:{min:1,max:2},async run(e){let{projectId:t}=at(e),n=e.args[0],r=e.flags["from-stdin"]===!0;if(r&&e.args.length>1)throw new
|
|
178
|
+
`),supportsJson:!0,options:["from-stdin","source","project"],args:{min:1,max:2},async run(e){let{projectId:t}=at(e),n=e.args[0],r=e.flags["from-stdin"]===!0;if(r&&e.args.length>1)throw new h("invalid_usage","Pass the value as an argument or with --from-stdin, not both.");if(!r&&e.args.length<2)throw new h("missing_argument","A value is required. Pass it as an argument, or pipe it with --from-stdin.");let o;if(r){if(!e.readStdin)throw new h("invalid_usage","--from-stdin is not available in this context.");o=(await e.readStdin()).replace(/\r?\n$/,"")}else o=e.args[1];let s=it(e.flags,"source"),i=await e.requireClient().secrets.upsertEntries(t,{entries:[{key:n,value:o,...s?{source:s}:{}}]});if(e.json)return e.stdout(k(S(Yn.name,i))),i.written>0?0:1;if(i.written===0)throw new h("bad_request",`The store refused ${n}: --source must be a project-relative file path.`);return e.stdout(`${A([["key",n],["source",s??".env"]])}
|
|
179
179
|
`),0}},Zn={name:"secrets delete",summary:"Remove one secret from the store",usage:["Usage: hlix secrets delete <KEY> [--source <file>] [--project <id>] [--json]","","Without --source the key is removed from EVERY file that declares it,",'which is what "delete this secret" usually means. Removing nothing exits 1.'].join(`
|
|
180
|
-
`),supportsJson:!0,options:["source","project"],args:{min:1,max:1},async run(e){let{projectId:t}=at(e),n=e.args[0],r=it(e.flags,"source"),o=await e.requireClient().secrets.deleteEntry(t,n,r);if(e.json)return e.stdout(S(
|
|
180
|
+
`),supportsJson:!0,options:["source","project"],args:{min:1,max:1},async run(e){let{projectId:t}=at(e),n=e.args[0],r=it(e.flags,"source"),o=await e.requireClient().secrets.deleteEntry(t,n,r);if(e.json)return e.stdout(k(S(Zn.name,o))),o.removed>0?0:1;if(o.removed===0)return e.stderr(`No stored secret named ${n}${r?` in ${r}`:""}.
|
|
181
181
|
`),1;return e.stdout(`Removed ${o.removed} entr${o.removed===1?"y":"ies"} for ${n}.
|
|
182
182
|
`),0}},xt={name:"secrets import",summary:"Load this folder's secret files into the project secrets store",usage:["Usage: hlix secrets import [file...] [--project <id>] [--json]","","With no arguments, every secret file the project scanner detects. Naming","files narrows it to those; a named file the scanner does not consider a","secret is refused rather than uploaded.","","The files are uploaded as bytes and the server parses them, so every shape","it knows lands here: dotenv and .envrc, Terraform variables, Java","properties, Spring YAML, .NET appsettings, Azure Functions local settings,","npm credentials, Rails database.yml, wrangler/fly TOML and Serverless all","become readable entries under their own path. An opaque credential (a","private key, a keystore, a service-account JSON) is kept byte-exact","instead. A file whose plaintext this platform does not hold — SOPS,","Ansible Vault, git-crypt — and a .env.example are reported as skipped.","","A file that holds key/value pairs REPLACES what the store held for that","path: the file on this machine is the truth."].join(`
|
|
183
|
-
`),supportsJson:!0,options:["project"],args:{min:0,max:64},async run(e){let{projectId:t,root:n}=at(e),r=await V(n,{historyMode:"preserve",environment:e.env}),o=r.blocking.filter((d)=>!d.startsWith(Cn));if(o.length>0)throw new
|
|
183
|
+
`),supportsJson:!0,options:["project"],args:{min:0,max:64},async run(e){let{projectId:t,root:n}=at(e),r=await V(n,{historyMode:"preserve",environment:e.env}),o=r.blocking.filter((d)=>!d.startsWith(Cn));if(o.length>0)throw new h("scan_blocked",`Project scan blocked the import:
|
|
184
184
|
- ${o.join(`
|
|
185
|
-
- `)}`);let s=r.protectedFiles.filter((d)=>d.kind==="dotenv"||d.kind==="credential"),i=await
|
|
186
|
-
`),0;if(l.length>
|
|
185
|
+
- `)}`);let s=r.protectedFiles.filter((d)=>d.kind==="dotenv"||d.kind==="credential"),i=await tc(e.cwd),c=e.args.map((d)=>oc(r.root,Ks(i,d)).split(ic).join("/")),a=c.filter((d)=>!s.some((m)=>m.path===d));if(a.length>0)throw new h("invalid_usage",`Not a secret file in this project: ${a.join(", ")}`);let l=c.length>0?s.filter((d)=>c.includes(d.path)):s;if(l.length===0)return e.stdout(e.json?k(S(xt.name,{imported:[],skipped:[],warnings:[],written:0,rejected:[]})):`No secret files found in this project.
|
|
186
|
+
`),0;if(l.length>Ds)throw new h("invalid_usage",`${l.length} secret files exceeds the ${Ds} the store accepts in one request. Name the files to import, a batch at a time.`);let u=await e.requireClient().secrets.importFiles(t,l.map((d)=>({path:d.path,contentBase64:d.contentBase64})));if(e.json)return e.stdout(k(S(xt.name,u))),0;if(u.imported.length>0)e.stdout(`${Y(["source","format","stored"],u.imported.map((d)=>[d.path,d.format||"-",d.kind==="file"?"as file":`${d.entries} entr${d.entries===1?"y":"ies"}`]))}
|
|
187
187
|
`);e.stdout(`${u.written} value${u.written===1?"":"s"} stored.
|
|
188
188
|
`);for(let d of u.skipped)e.stderr(`skipped ${d.path}: ${d.reason}
|
|
189
189
|
`);for(let d of u.warnings)e.stderr(`warning: ${d}
|
|
190
190
|
`);for(let d of u.rejected)e.stderr(`rejected ${d}: the store refused its source path
|
|
191
|
-
`);return 0}};function
|
|
192
|
-
`),supportsJson:!0,options:["source","format","out","project"],async run(e){let{projectId:t}=at(e),n=it(e.flags,"source"),r=it(e.flags,"format"),o=it(e.flags,"out"),s=o===void 0?void 0:
|
|
193
|
-
`);return 0}};function er(e,t){let n=e[t];if(typeof n!=="string"||n.trim()==="")throw new
|
|
194
|
-
`),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(e){let t=e.args[0],n=er(e.flags,"title"),r=er(e.flags,"description"),o=await e.requireClient().cycles.propose({projectId:t,title:n,description:r});if(e.json)return e.stdout(S(
|
|
191
|
+
`);return 0}};function ac(e){return Qa("git",["-C",sc(e),"ls-files","--error-unmatch","--",rc(e)],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}).status===0}var Qn={name:"secrets export",summary:"Render one source file back out of the store, values in clear",usage:["Usage: hlix secrets export [--source <file>] [--format <id>] [--out <path>] [--project <id>] [--json]",""," --source Which stored file to render. Omitted means the root .env."," --format Re-render it as a different shape (dotenv, tfvars, …)."," Omitted means the shape the values were parsed as."," --out Write it to this path, mode 0600, instead of stdout. A path"," git TRACKS is refused: an exported file carries plaintext and"," must not become a commit.","","This is the one command that returns secret values, and the server writes","an audit row for every call."].join(`
|
|
192
|
+
`),supportsJson:!0,options:["source","format","out","project"],async run(e){let{projectId:t}=at(e),n=it(e.flags,"source"),r=it(e.flags,"format"),o=it(e.flags,"out"),s=o===void 0?void 0:Ks(e.cwd,o);if(s!==void 0&&ac(s))throw new h("invalid_usage",`Refusing to overwrite a git-tracked file with secret values: ${s}`);let i=await e.requireClient().secrets.exportEntries(t,{...n?{source:n}:{},...r?{format:r}:{}});if(s!==void 0)await nc(s,i,{mode:384}),await ec(s,384);if(e.json)return e.stdout(k(S(Qn.name,{source:n??null,format:r??null,out:s??null,bytes:Buffer.byteLength(i),...s===void 0?{content:i}:{}}))),0;if(s===void 0)e.stdout(i);else e.stdout(`${A([["wrote",s],["mode","0600"],["bytes",String(Buffer.byteLength(i))]])}
|
|
193
|
+
`);return 0}};function er(e,t){let n=e[t];if(typeof n!=="string"||n.trim()==="")throw new h("missing_argument",`--${t} is required.`);return n}var tr={name:"cycles create",summary:"Propose a cycle, which starts the project working on it",usage:["Usage: hlix cycles create <project-id> --title <t> --description <d> [--json]","","This is the command that DISPATCHES work. The proposal enters the project's","own loop, which plans the cycle, creates its tasks and starts the coders —","using the project's harness (see `hlix harness get`).","","`adopted` is true when the loop took it on this call, false when it was","recorded and will be planned on the next pass. Neither is an error. The API","returns no cycle id: the roadmap owns cycles, so find it with `hlix tasks","list --project <id>` once planning has run."].join(`
|
|
194
|
+
`),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(e){let t=e.args[0],n=er(e.flags,"title"),r=er(e.flags,"description"),o=await e.requireClient().cycles.propose({projectId:t,title:n,description:r});if(e.json)return e.stdout(k(S(tr.name,o))),0;return e.stdout(`${A([["project",t],["title",n],["status",o.adopted?"adopted — the project is planning it now":"recorded — it will be planned on the next pass"]])}
|
|
195
195
|
`),0}},nr={name:"tasks create",summary:"Add a task to a project's board",usage:["Usage: hlix tasks create <project-id> --description <d> [--title <t>] [--json]","","Creates the task row. It does NOT start it: standalone task execution is","not implemented server-side and answers 501 by design. Work is dispatched","by its cycle — use `hlix cycles create` for that."].join(`
|
|
196
|
-
`),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(e){let t=e.args[0],n=er(e.flags,"description"),r=typeof e.flags.title==="string"?e.flags.title:void 0,o=await e.requireClient().tasks.create({projectId:t,description:n,...r?{title:r}:{}});if(e.json)return e.stdout(S(
|
|
196
|
+
`),supportsJson:!0,options:["title","description"],args:{min:1,max:1},async run(e){let t=e.args[0],n=er(e.flags,"description"),r=typeof e.flags.title==="string"?e.flags.title:void 0,o=await e.requireClient().tasks.create({projectId:t,description:n,...r?{title:r}:{}});if(e.json)return e.stdout(k(S(nr.name,o))),0;return e.stdout(`${A([["task",o.id],["project",t],["status",o.status??"queued"],["note","not started — dispatch with `hlix cycles create`"]])}
|
|
197
197
|
`),0}},rr={name:"harness get",summary:"Show which coder runs, and which setting chose it",usage:["Usage: hlix harness get [project-id] [--json]","","With a project id, what that project would run. Without one, the","workspace-wide answer. `source` names the setting that decided: a project","preference, the workspace preference, or the system default."].join(`
|
|
198
|
-
`),supportsJson:!0,args:{min:0,max:1},async run(e){let t=e.args[0],n=e.requireClient(),r=t?await n.modelConfig.resolvedProjectHarness(t):await n.modelConfig.resolvedHarness();if(e.json)return e.stdout(S(
|
|
198
|
+
`),supportsJson:!0,args:{min:0,max:1},async run(e){let t=e.args[0],n=e.requireClient(),r=t?await n.modelConfig.resolvedProjectHarness(t):await n.modelConfig.resolvedHarness();if(e.json)return e.stdout(k(S(rr.name,r))),0;return e.stdout(`${A([["scope",t?`project ${t}`:"workspace"],["harness",r.harness],["source",r.source]])}
|
|
199
199
|
`),0}},sr={name:"harness set",summary:"Choose the coder a project or the workspace runs",usage:[`Usage: hlix harness set <${ve.join("|")}> [project-id] [--org] [--json]`,"","With a project id, sets that project's preference. With --org, the","workspace-wide one that projects fall back to. This is a PERSISTENT server","setting that every future run on that scope uses, and it is audited.","","It is not the same thing as the local `harness` config key, which only","picks the coder Hlix Code spawns on this machine."].join(`
|
|
200
|
-
`),supportsJson:!0,options:["org"],args:{min:1,max:2},async run(e){let t=e.args[0];if(!ve.includes(t))throw new
|
|
201
|
-
`),0}}
|
|
202
|
-
|
|
200
|
+
`),supportsJson:!0,options:["org"],args:{min:1,max:2},async run(e){let t=e.args[0];if(!ve.includes(t))throw new h("invalid_usage",`harness must be one of ${ve.join(", ")}; got "${t}".`);let n=e.args[1],r=e.flags.org===!0;if(n&&r)throw new h("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!n&&!r)throw new h("invalid_usage","Name the project to set, or pass --org for the whole workspace.");let o=e.requireClient(),s=n?await o.modelConfig.setProjectHarness(n,t):await o.modelConfig.setHarness(t);if(e.json)return e.stdout(k(S(sr.name,s))),0;return e.stdout(`${A([["scope",n?`project ${n}`:"workspace"],["harness",t]])}
|
|
201
|
+
`),0}},or={name:"harness clear",summary:"Remove a harness preference so the scope below it decides",usage:["Usage: hlix harness clear [project-id] [--org] [--json]","","With a project id, drops that project's preference so it inherits the","workspace's answer (or the system default). With --org, drops the","workspace-wide one. Audited, like every write on this setting.","","Answers `not_found` when that scope had no preference to clear — the","setting is already off, and saying so beats reporting a change that was","never made. Check the result with `hlix harness get`."].join(`
|
|
202
|
+
`),supportsJson:!0,options:["org"],args:{min:0,max:1},async run(e){let t=e.args[0],n=e.flags.org===!0;if(t&&n)throw new h("invalid_usage","Name a project or pass --org, not both: they are different scopes.");if(!t&&!n)throw new h("invalid_usage","Name the project to clear, or pass --org for the whole workspace.");let r=e.requireClient(),o=t?await r.modelConfig.clearProjectHarness(t):await r.modelConfig.clearHarness();if(e.json)return e.stdout(k(S(or.name,o))),0;return e.stdout(`${A([["scope",t?`project ${t}`:"workspace"],["harness","cleared — the scope below decides now"]])}
|
|
203
|
+
`),0}};var Wp=[cn,ln,be,An,Fn,On,Tn,dn,pn,un,In,jt,It,Ct,Pt,qn,Wn,Vn,Xn,Yn,Zn,xt,Qn,mn,fn,hn,yn,wn,vn,nr,tr,rr,sr,or];
|
|
204
|
+
export{h as a,lc as b,N as c,J as d,Ro as e,nl as f,Fo as g,Hr as h,ve as i,ul as j,en as k,Lo as l,Kr as m,wt as n,wl as o,sn as p,es as q,vl as r,ts as s,rs as t,kl as u,bl as v,Sl as w,Wp as x};
|