@hlix/cli 0.5.1 → 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 +8 -6
- package/dist/index-mpmj2yxq.js +204 -0
- package/dist/index.js +2 -2
- package/dist/main-jdcfzt1f.js +60 -0
- package/dist/{package-3m9rgs58.js → package-ef5qa8w8.js} +1 -1
- package/package.json +1 -1
- package/skills/hlix/SKILL.md +13 -5
- package/dist/index-mwwmk5q2.js +0 -202
- package/dist/main-n4cj07p6.js +0 -61
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{a as K,c as fe,d as We,e as O,f as ae,g as xe,h as Z,i as G,j as je,k as zr,l as Xr,m as mr,n as Jr,o as Zr,p as Mt,q as Qr,r as eo,s as to,t as no,u as ro,v as oo,w as so,x as ge}from"./index-mpmj2yxq.js";import"./index-f303pf32.js";import{realpathSync as qa}from"node:fs";import{join as Vr,relative as io,resolve as za}from"node:path";import{parseArgs as Xa}from"node:util";import{accessSync as lo,constants as co,statSync as po}from"node:fs";import{delimiter as uo,join as mo}from"node:path";import{createACPTool as go}from"@mastra/acp";import{createTool as fo}from"@mastra/core/tools";import{z as q}from"zod";var ne={"claude-code":{harness:"claude-code",label:"Claude Code",command:"claude-agent-acp",args:[],authEnvVars:["ANTHROPIC_API_KEY"],install:"npm i -g @agentclientprotocol/claude-agent-acp"},codex:{harness:"codex",label:"Codex",command:"codex-acp",args:[],authEnvVars:["OPENAI_API_KEY"],env:{NO_BROWSER:"1"},install:"npm i -g @agentclientprotocol/codex-acp"},"cursor-agent":{harness:"cursor-agent",label:"Cursor Agent",command:"cursor-agent",args:["acp"],authEnvVars:["CURSOR_API_KEY"],install:"curl https://cursor.com/install -fsS | bash"}};function wt(e){if(e.flag)return{harness:ho(e.flag,"--harness"),source:"flag"};if(e.configured)return{harness:e.configured,source:e.configSource??"project"};return{harness:je,source:"default"}}function ho(e,t){if(G.includes(e))return e;throw Error(`${t} must be one of ${G.join(", ")}; got "${e}".`)}var Le="hlix_tasks_follow",yo=(e)=>`hlix_coder_${e.split("-").join("_")}`;function De(e){if(e.source==="default")return String(e.harness);let t=e.source==="flag"?"--harness":e.source;return`${e.harness} (${t})`}function _t(e,t=process.env){return $e(e,t)!==null}function $e(e,t=process.env){if(!e)return null;if(e.includes("/"))return vt(e)?e:null;let n=(t.PATH??"").split(uo).filter(Boolean);for(let r of n){let o=mo(r,e);if(vt(o))return o}return null}function vt(e){if(!e)return!1;try{if(!po(e).isFile())return!1;return lo(e,co.X_OK),!0}catch{return!1}}var He=(e)=>`harness ${e.harness} needs \`${e.command}\` on PATH. Install it with: ${e.install}`;function bo(e){let t=e.options??[],n=t.find((r)=>r.kind==="allow_once")??t.find((r)=>r.kind==="reject_once");if(!n)return{outcome:{outcome:"cancelled"}};return{outcome:{outcome:"selected",optionId:n.optionId}}}var Et=["ask_user","task_write","task_update","task_complete","task_check"],xo=(e)=>[`harness ${e} runs in the project's Coding Workspace, not on this machine.`,"Start work with `hlix cycles create`, find the tasks it plans with","`hlix tasks list`, and watch one live with `/follow <task-id>`.","Nothing runs on this machine, so a local coder binary is not used."].join(" "),It=(e)=>[e==="unknown"?"This project's harness could not be read from the server. Do NOT guess which coder it runs — say so, and offer to check with the `hlix_harness` tool.":`This project's harness is ${e}: the platform runs ${e} for the coding work it executes, in the project's Coding Workspace.`,"Change it with the `hlix_harness` tool, which writes the project's setting.","","To do coding work here, dispatch it and then watch it:","1. `hlix_cycles_create` with the project id, a title and a description. That"," is what STARTS work — it enters the project's loop, which plans the cycle,"," creates its tasks and starts the coder. It returns no cycle id.","2. `hlix_tasks_list` with that project to find the tasks planning produced.",`3. \`${Le}\` with a task id, which streams that coder's own text and`," tool calls into this session live. Report what it did.","","`hlix_tasks_create` only adds a board row; it does not start anything, and","there is no way to start a single task. Never claim otherwise."].join(`
|
|
3
|
+
`),So=(e,t)=>[`The user chose the ${e.label} harness. Do not edit files or run commands`,`yourself. Hand the whole task to \`${t}\` as one natural-language brief,`,`then report what it did. ${e.label} reads and writes the same working`,"directory you are in.","",`It authenticates from ${e.authEnvVars.join(" or ")} in this shell's`,"environment. If it reports a credential problem, say so — do not retry."].join(`
|
|
4
|
+
`);function Rt(e){if(e.sandbox==="cloud"||e.active==="hlix")return[];let t=new Set(e.unavailable??[]),n=e.model?{defaultModelId:e.model}:{},r=[{id:"hlix",name:"Hlix",description:"The hlix agent codes here, with the full toolset.",...n}];for(let o of Object.values(ne)){let s=e.active===o.harness,l=yo(o.harness);r.push({id:o.harness,name:o.label,description:`${o.label} runs on this machine over ACP and edits ${e.cwd}.`,instructions:So(o,l),availableTools:t.has(o.harness)?[...e.readTools,...Et,Le]:[l,...e.readTools,...Et,Le],...t.has(o.harness)?{}:{additionalTools:{[l]:go({id:l,description:`Run a coding task with ${o.label}. Give it one natural-language brief; it reads and writes the working directory and returns its final output.`,command:o.command,args:o.args,cwd:e.cwd,...o.env?{env:o.env}:{},...e.workspace?{workspace:e.workspace}:{},onPermissionRequest:async(i)=>bo(i)})}},...n,...s?{metadata:{default:!0}}:{}})}return r}function Ct(e){if(!e.fromFlag||!e.modesBuilt)return null;return e.current===e.harness?null:e.harness}function Fe(e){let t=[...e.available],n=(o,s="none")=>({harness:e.current,available:t,action:s,message:o});if(!e.requested)return n(`harness: ${e.current}. Available here: ${t.join(", ")}.`);if(!G.includes(e.requested))return n(`/harness must name one of ${G.join(", ")}; got "${e.requested}".`);let r=e.requested;if(e.sandbox==="cloud"){let o=`${e.sandboxLine} · harness: ${r} (project preference)`;return{harness:r,available:t,action:"preference",message:r==="hlix"?o:`${o}. ${xo(r)}`}}if(!t.includes(r))return n(He(ne[r]));if(!e.modesBuilt)return n(`This session runs the hlix coder, so there is no ${r} mode to switch to. Restart with \`hlix --harness ${r}\`, or make it the default with \`hlix config set harness ${r}\`.`,"restart");return{harness:r,available:t,action:"mode",message:`${e.sandboxLine} · harness: ${r}`}}function Tt(e){return fo({id:"hlix_harness",description:"Show or change the harness — which coder does the work. In a local or docker sandbox it switches this session's coder; in a cloud sandbox it writes the project's harness preference, which is what the platform runs. With no argument it reports the current harness.",inputSchema:q.object({harness:q.string().optional().describe(`One of ${G.join(", ")}. Omit to report the current one.`)}),outputSchema:q.object({harness:q.string(),available:q.array(q.string()),message:q.string()}),execute:async(t)=>{let n=e.session(),r=Fe({...t.harness?{requested:t.harness}:{},current:n?.mode.get()??je,available:e.available,sandbox:e.sandbox,sandboxLine:e.sandboxLine,modesBuilt:e.modesBuilt}),o={harness:r.harness,available:r.available,message:r.message};if(r.action==="mode"&&n)return await n.mode.switch({modeId:r.harness}),o;if(r.action==="preference"){if(!e.setProjectHarness)return{...o,message:"This folder is not bound to a hlix project, so there is no project preference to write. Run `hlix init` or pass --project <id>."};await e.setProjectHarness(r.harness)}return o}})}import{createTool as vo}from"@mastra/core/tools";import{z as A}from"zod";var Eo=(e)=>`hlix_${e.split(" ").join("_")}`,wo=A.object({args:A.array(A.string()).optional().describe("Positional arguments that follow the command name."),flags:A.record(A.string(),A.union([A.string(),A.boolean()])).optional().describe('Options without the leading dashes, e.g. { "yes": true, "name": "api" }.')}),_o=A.object({exitCode:A.number(),stdout:A.string(),stderr:A.string()});function Io(e,t,n){let r=e.name.split(" ").concat(t.args??[]);for(let[o,s]of Object.entries(t.flags??{})){if(s===!1)continue;if(r.push(`--${o}`),typeof s==="string")r.push(s)}if(!t.flags?.cwd)r.push("--cwd",n);if(e.supportsJson&&!t.flags?.json)r.push("--json");return r}async function Ro(e,t,n,r=process.env){let o="",s="";return{exitCode:await ae([e],Io(e,t,n),{stdout:(i)=>{o+=i},stderr:(i)=>{s+=i},env:r}),stdout:o,stderr:s}}function kt(e){let t={};for(let n of e.commands??ge){let r=Eo(n.name);t[r]=vo({id:r,description:`${n.summary}
|
|
5
|
+
|
|
6
|
+
${n.usage}`,inputSchema:wo,outputSchema:_o,execute:async(o)=>Ro(n,o,e.cwd,e.env)})}return t}import{createTool as Co}from"@mastra/core/tools";async function At(e,t){let n=e?.agent?.toolCallId;if(!n)return;let r={type:"data-hlix-tool-progress",data:{toolCallId:n,progress:t},transient:!0},o=e?.agent?.outputWriter;if(o){await o(r);return}await e?.writer?.custom?.(r)}import{z as W}from"zod";function To(e){switch(e.type){case"on_chat_model_stream":return e.delta?{event:"text",text:e.delta}:null;case"reasoning":return e.delta?{event:"text",text:e.delta}:null;case"on_tool_start":return{event:"tool_start",toolName:e.name,args:e.input};case"on_tool_end":return{event:"tool_end",toolName:e.name,result:e.output,isError:ko(e.output)};case"error":return{event:"finish",isError:!0,result:e.message};case"done":return{event:"finish",isError:!1};default:return null}}function ko(e){return typeof e==="object"&&e!==null&&e.status==="failed"}async function Ao(e,t){let n=[],r=[],o="streamed",s="The coder's turn ended.";for await(let l of e){if(l.type==="idle"){o="idle",s="Nothing is being coded right now. The task is not in build or test.";break}if(l.type==="error")o="error",s=l.message;if(l.type==="on_chat_model_stream")n.push(l.delta);if(l.type==="on_tool_start")r.push(l.name);let i=To(l);if(i)await t(i)}return{status:o,text:n.join(""),tools:r,message:s}}function Pt(e){return Co({id:"hlix_tasks_follow",description:"Watch a hlix task being coded in the cloud, live. Streams the coder's text and tool calls into this session as they happen, and returns what it did. Use it after a task starts building.",inputSchema:W.object({taskId:W.string().describe("The task to follow.")}),outputSchema:W.object({status:W.enum(["streamed","idle","error","unassigned"]),text:W.string(),tools:W.array(W.string()),message:W.string()}),execute:async(t,n)=>{let r=O(e.env??process.env,{cwd:e.cwd,flags:{}}),o=await r.tasks.get(t.taskId);if(!o.agentId)return{status:"unassigned",text:"",tools:[],message:"No agent has picked this task up yet, so there is no coder to watch. Check `hlix_tasks_get` again once it is building."};return Ao(r.projects.observeAgent(o.projectId,o.agentId),(s)=>At(n,s))}})}import{readFileSync as Po,statSync as Ot}from"node:fs";import{isAbsolute as No,join as Mo,relative as Be,resolve as z}from"node:path";var Oo=["path","file","filePath","target","targetPath","dest","destination"],Ue=8000,Lo=(e)=>{try{return Ot(e).isFile()}catch{return!1}},jo=(e)=>{try{return Ot(e).isDirectory()}catch{return!1}};function Nt(e,t){let n=Be(e,t);return n!==""&&!n.startsWith("..")&&!No(n)}function Do(e){let t=z(e.root),n=z(t,e.touched);if(!Nt(t,n))return null;let r=jo(n)?n:z(n,"..");while(Nt(t,r)){for(let o of Mt){let s=Mo(r,o);if(Lo(s))return s}r=z(r,"..")}return null}function $o(e,t){let n=Be(t,e.path),r=!n||n.startsWith("..")?e.path:n;return[`Rules for ${Be(t,z(e.path,".."))||"."}/ (${r})`,"","This directory keeps its own rules. They apply to everything under it and","take precedence over the project's rules where the two differ.","",e.content].join(`
|
|
7
|
+
`)}function Ho(e){let t=[];for(let n of e){let r=n.content?.parts;if(!Array.isArray(r))continue;for(let o of r){if(o.type!=="tool-invocation")continue;let s=o.toolInvocation;if(!s||s.state!=="result")continue;if(typeof s.toolCallId!=="string"||s.toolCallId==="")continue;let l=Fo(s.args);if(!l)continue;let i=[];for(let c of Oo){let a=l[c];if(typeof a==="string"&&a.trim()!=="")i.push(a)}if(i.length>0)t.push({id:s.toolCallId,paths:i})}}return t}function Fo(e){if(typeof e==="object"&&e!==null)return e;if(typeof e!=="string")return null;try{let t=JSON.parse(e);return typeof t==="object"&&t!==null?t:null}catch{return null}}class Ge{id="hlix-nested-rules";name="Nested rules";description="Adds a subdirectory's own AGENTS.md when the agent first works in it";root;skip;sent=new Map;seenCalls=new Set;constructor(e){this.root=z(e.root),this.skip=new Set((e.already??[]).map((t)=>z(t)))}loaded(){return[...this.sent.values()]}consider(e){let t=Do({touched:e,root:this.root});if(!t||this.skip.has(t)||this.sent.has(t))return null;let n;try{n=Po(t,"utf8").trim()}catch{return null}if(n==="")return null;let r={path:t,content:n.length>Ue?`${n.slice(0,Ue).trimEnd()}
|
|
8
|
+
|
|
9
|
+
[truncated: ${t} is longer than ${Ue} characters]`:n};return this.sent.set(t,r),r}newCalls(e,t){let n=Ho(e.get.all.db()).filter((r)=>!this.seenCalls.has(r.id));for(let r of n)this.seenCalls.add(r.id);return t===0?[]:n}async processInputStep(e){for(let t of this.newCalls(e.messageList,e.stepNumber))for(let n of t.paths){let r=this.consider(n);if(!r)continue;await e.sendSignal?.({type:"reactive",tagName:"system-reminder",contents:$o(r,this.root),attributes:{type:"nested-rules",path:r.path}})}return e.messageList}}import{createHash as Go}from"node:crypto";import{existsSync as Wo,realpathSync as Yo}from"node:fs";import{basename as Ko,dirname as Vo,join as qo,resolve as Ht,sep as Ft}from"node:path";import{Memory as zo}from"@mastra/memory";var Y="hlix",X="default",le=(e)=>`${Y}/${e}`,Lt=(e)=>e.startsWith(`${Y}/`)&&e.length>Y.length+1;function Uo(e){return{name:Y,url:`${e.baseUrl.replace(/\/+$/,"")}/v1/api/ai/w/${e.workspaceId}`,apiKey:e.apiKey,models:[...new Set([X,...e.models??[]])]}}function jt(e){let t=We({env:e.env,flags:{},cwd:e.cwd});if(t.conflict||!t.credential||!t.workspaceId)return null;let n=t.credential.sessionToken||t.credential.apiKey;if(!n)return null;let r=t.binding?.config.projectId;return{...Uo({baseUrl:t.baseUrl,workspaceId:t.workspaceId,apiKey:n,...e.models?{models:e.models}:{}}),workspaceId:t.workspaceId,...r?{projectId:r}:{}}}var Bo=3000;async function Dt(e){let t=We({env:e.env,flags:{},cwd:e.cwd});if(t.conflict||!t.credential||!t.workspaceId)return{};try{return{served:(await O(e.env,{cwd:e.cwd,flags:{}}).ai.models(t.workspaceId,{signal:AbortSignal.timeout(e.timeoutMs??Bo)})).models.map((r)=>({id:r.id,name:r.name}))}}catch(n){return{warning:`could not read your workspace's models (${n instanceof Error?n.message:String(n)}). Offering the workspace default only.`}}}function $t(e){if(e.configured){let t=e.configuredSource??"config";if(!e.cloud||!e.endpoint||Lt(e.configured))return{id:e.configured,source:t};return{id:le(X),source:"workspace",notice:`model ${e.configured} from ${t} is not available on the cloud sandbox; using hlix default`}}return e.endpoint?{id:le(X),source:"workspace"}:null}function Ut(e){try{return Yo(Ht(e))}catch{return Ht(e)}}function Xo(e){let t=Ut(e),n=fe(t);if(n)return Ut(n.root);for(let r=t;;){if(Wo(qo(r,".git")))return r;let o=Vo(r);if(o===r)return t;r=o}}var Jo=(e)=>e.length>8?`${e.slice(0,8)}…`:e;function Bt(e){let t=Xo(e.cwd),n=e.projectId?.trim(),r=n||Go("sha256").update(t).digest("hex").slice(0,16);return{resourceId:`${e.workspaceId}:${r}`,legacyResourceId:e.workspaceId,root:t,label:n?`project ${Jo(n)}`:`folder ${Ko(t)}`}}var Gt=(e,t)=>typeof e==="string"&&(e===t||e.startsWith(t.endsWith(Ft)?t:`${t}${Ft}`)),Wt=(e,t)=>`memory: ${e.label} · ${t} thread${t===1?"":"s"}`,he=200000;function ye(e){let t=Math.round(e*3/7);return{observationThreshold:t,reflectionThreshold:e-t}}var Yt=(e,t)=>`${e} · memory: ${Math.round((t.observationThreshold+t.reflectionThreshold)/1000)}k`;function Kt(e){return new zo({storage:e.storage,vector:!1,options:{semanticRecall:!1,workingMemory:{enabled:!0,scope:"resource"},observationalMemory:{scope:"resource",observation:{model:()=>e.observerModel(),messageTokens:e.thresholds.observationThreshold},reflection:{model:()=>e.reflectorModel(),observationTokens:e.thresholds.reflectionThreshold}}}})}import{execFileSync as hs}from"node:child_process";import{DockerSandbox as ys}from"@mastra/docker";import{LocalFilesystem as en,LocalSandbox as bs,Workspace as tn}from"@mastra/core/workspace";var Zo=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,Vt=/^(\s*name\s*:\s*)(.+?)\s*$/;function Qo(e,t){if(!Zo.test(t))return e;let n=e.indexOf(`
|
|
10
|
+
---`,3);if(!e.startsWith("---")||n<0)return e;let o=e.slice(0,n).split(`
|
|
11
|
+
`),s=o.findIndex((c)=>Vt.test(c));if(s<0)return e;let l=Vt.exec(o[s]);if(!l)return e;let i=l[2].replace(/^["']|["']$/g,"").trim();if(i===t)return e;if(o[s]=`${l[1]}${t}`,!o.some((c)=>/^\s*title\s*:/.test(c)))o.push(`title: ${i}`);return`${o.join(`
|
|
12
|
+
`)}${e.slice(n)}`}function es(e){let t=e.split("/").filter((n)=>n!=="");if(t.length<2||t[t.length-1]!=="SKILL.md")return null;return t[t.length-2]}function qt(e){let t={exists:(n)=>e.exists(n),stat:(n)=>e.stat(n),readdir:(n)=>e.readdir(n),readFile:async(n)=>{let r=await e.readFile(n),o=es(n);if(o===null)return r;let s=typeof r==="string"?r:r.toString("utf8");return Qo(s,o)}};if(e.realpath)t.realpath=(n)=>e.realpath?.(n);return t}import{WORKSPACE_TOOLS as R}from"@mastra/core/workspace";var re={[R.FILESYSTEM.READ_FILE]:"view",[R.FILESYSTEM.WRITE_FILE]:"write_file",[R.FILESYSTEM.EDIT_FILE]:"edit_file",[R.FILESYSTEM.LIST_FILES]:"find_files",[R.FILESYSTEM.DELETE]:"delete_file",[R.FILESYSTEM.FILE_STAT]:"file_stat",[R.FILESYSTEM.MKDIR]:"mkdir",[R.FILESYSTEM.GREP]:"search_content",[R.FILESYSTEM.AST_EDIT]:"ast_edit",[R.SANDBOX.EXECUTE_COMMAND]:"execute_command",[R.SANDBOX.GET_PROCESS_OUTPUT]:"process_output",[R.SANDBOX.KILL_PROCESS]:"kill_process",[R.LSP.LSP_INSPECT]:"lsp_inspect"},ce=[R.FILESYSTEM.WRITE_FILE,R.FILESYSTEM.EDIT_FILE,R.FILESYSTEM.DELETE,R.FILESYSTEM.MKDIR,R.FILESYSTEM.AST_EDIT,R.SANDBOX.EXECUTE_COMMAND,R.SANDBOX.KILL_PROCESS].map((e)=>re[e]),be=Object.values(re).filter((e)=>!ce.includes(e)),de=Object.fromEntries(Object.entries(re).map(([e,t])=>[e,{name:t}]));function P(e){return re[e]??e}import{posix as zt}from"node:path";import{DirectoryNotEmptyError as ts,DirectoryNotFoundError as ns,FileExistsError as rs,FileNotFoundError as os,FilesystemError as ss,IsDirectoryError as is,MastraFilesystem as as,MastraSandbox as ls,NotDirectoryError as cs,PermissionError as ds,Workspace as ps}from"@mastra/core/workspace";var us=600000,ms=["recursive","overwrite","force","maxDepth","extension"];function J(e){let t=e??{},n={};for(let r of ms)if(t[r]!==void 0)n[r]=t[r];return Object.keys(n).length>0?{options:n}:{}}var Xt=(e)=>e instanceof Date?e:new Date(typeof e==="string"||typeof e==="number"?e:0);function gs(e,t,n){let r=e?.status;if(typeof r!=="number")return e;let o=e?.body,s=typeof o?.code==="string"?o.code:"",l=typeof o?.error==="string"?o.error:"",i=(c)=>l.toLowerCase().includes(c);if(r===404)return s==="ENOTDIR"||i("directory not found")?new ns(t):new os(t);if(r===403)return new ds(t,n);if(r===409){if(s==="EEXIST"||i("already exists"))return new rs(t);if(s==="ENOTEMPTY"||i("not empty"))return new ts(t);if(s==="EISDIR"||i("is a directory"))return new is(t);if(s==="ENOTDIR"||i("not a directory"))return new cs(t);return new ss(l||`${n} failed`,s||"ECONFLICT",t)}return e}class Jt extends as{id;name="RemoteFilesystem";provider="hlix-coding-workspace";basePath;status="ready";client;constructor(e,t){super({name:"RemoteFilesystem"});this.client=e,this.basePath=t.root,this.id=t.id??`hlix-remote-fs:${t.root}`}getInfo(){return{id:this.id,name:this.name,provider:this.provider,status:this.status,metadata:{root:this.basePath}}}resolveAbsolutePath(e){return zt.isAbsolute(e)?e:zt.join(this.basePath,e)}async call(e){let t=this.resolveAbsolutePath(e.path);try{let{result:n}=await this.client.fs({...e,encoding:e.encoding??"utf8",path:t});return n}catch(n){throw gs(n,t,e.op)}}async readFile(e,t){let r=await this.call({op:"read",path:e,encoding:"base64"}),o=Buffer.from(r.content,r.encoding);return t?.encoding?o.toString(t.encoding):o}async writeFile(e,t,n){await this.call({op:"write",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64",...J(n)})}async appendFile(e,t){await this.call({op:"append",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64"})}async deleteFile(e,t){await this.call({op:"delete",path:e,...J(t)})}async copyFile(e,t,n){await this.call({op:"copy",path:e,dest:this.resolveAbsolutePath(t),...J(n)})}async moveFile(e,t,n){await this.call({op:"move",path:e,dest:this.resolveAbsolutePath(t),...J(n)})}async mkdir(e,t){await this.call({op:"mkdir",path:e,...J(t)})}async rmdir(e,t){await this.call({op:"rmdir",path:e,...J(t)})}async readdir(e,t){return await this.call({op:"readdir",path:e,...J(t)})??[]}async exists(e){return await this.call({op:"exists",path:e})===!0}async stat(e){let t=await this.call({op:"stat",path:e});return{...t,createdAt:Xt(t.createdAt),modifiedAt:Xt(t.modifiedAt)}}}var fs=(e)=>`'${e.split("'").join("'\\''")}'`;class Zt extends ls{id;name="RemoteSandbox";provider="hlix-coding-workspace";status="ready";client;constructor(e,t){super({name:"RemoteSandbox"});if(this.client=e,this.id=`hlix-remote-sandbox:${t.projectId}`,t.root)this.setWorkingDirectory(t.root)}async start(){}getInfo(){return{id:this.id,name:this.name,provider:this.provider,status:this.status,createdAt:new Date(0)}}async executeCommand(e,t=[],n){let r=[e,...t.map(fs)].join(" "),o=Date.now(),s=n?.cwd??this.workingDirectory,l=await this.client.exec({command:r,...s?{cwd:s}:{},timeoutMs:n?.timeout??us});return{success:l.exitCode===0,exitCode:l.exitCode,stdout:l.stdout,stderr:l.stderr,executionTimeMs:Date.now()-o,command:e,args:t}}}function Qt(e,t){let n=t.root;return new ps({id:`hlix-project:${t.projectId}`,name:"Hlix Coding Workspace",filesystem:new Jt(e,{root:n}),sandbox:new Zt(e,{projectId:t.projectId,root:n}),tools:de})}var rn="node:22-bookworm",xs=(e)=>`hlix-code-${e}`;function Ss(e,t){if(Z.includes(e))return e;throw new K("invalid_usage",`${t==="flag"?"--sandbox":"sandbox in .hlix/config.json"} must be one of ${Z.join(", ")}; got "${e}".`)}function on(e){let t=(n)=>n==="docker"?{image:e.dockerImage?.trim()||rn}:{};if(e.flag){let n=e.flagSource??"flag",r=Ss(e.flag,n);return{choice:r,reason:n==="flag"?`--sandbox ${e.flag}`:"config",...t(r)}}if(e.projectId)return{choice:"cloud",reason:`project ${e.projectId}`};if(e.dockerAvailable())return{choice:"docker",reason:"auto",...t("docker")};return{choice:"local",reason:"auto"}}var sn=(e)=>`sandbox: ${e.choice} (${e.reason}${e.image?`, ${e.image}`:""})`;function an(e=3000){try{return hs("docker",["info"],{timeout:e,stdio:"ignore"}),!0}catch{return!1}}function nn(e,t){if(!e||e.length===0)return{};return{skills:[...e],skillSource:qt(t)}}async function vs(e,t){let n=await e.environment();if(n.state==="absent")throw new K("not_found",`Project ${t} has no Coding Workspace yet, so there is nothing to code in. Run \`hlix import\` from the folder, or run a task in the project, to build one.`);if(!n.repoDir)throw new K("not_found",`This workspace's server did not say where project ${t}'s repository is. Update the server, or run with --sandbox docker|local.`);return n.repoDir}async function Ye(e,t){if(e.choice==="local"){let s=new en({basePath:t.cwd});return new tn({id:"hlix-code-local",name:"Hlix Code (this machine)",filesystem:s,...nn(t.skills,s),sandbox:new bs({workingDirectory:t.cwd}),tools:de})}if(e.choice==="cloud"){if(!t.remote||!t.projectId)throw new K("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");return Qt(t.remote,{projectId:t.projectId,root:await vs(t.remote,t.projectId)})}let n="/workspace",r=e.image??rn,o=new en({basePath:t.cwd});return new tn({id:"hlix-code-docker",name:"Hlix Code (Docker)",filesystem:o,...nn(t.skills,o),tools:de,sandbox:new ys({id:xs(r),image:r,volumes:{[t.cwd]:n},workingDirectory:n})})}import{basename as qs}from"node:path";import{AgentController as zs}from"@mastra/core/agent-controller";import{createCodingAgent as Xs}from"@mastra/core/coding-agent";import{createWorkspaceTools as Js}from"@mastra/core/workspace";var Es=["execute_command","kill_process"],ws=["updateWorkingMemory","task_write","task_update","task_complete","task_check","ask_user","submit_plan"];function Ke(e){let t=e in re?P(e):e;if(Es.includes(t))return"execute";if(ce.includes(t))return"edit";if(be.includes(t)||ws.includes(t))return"read";if(t.startsWith("hlix_"))return"other";return null}function ln(e=[]){let t=new Set(e);return(n)=>t.has(n)?"mcp":Ke(n)}function _s(e){return Ke(e)!=="read"}var cn=[{category:"read",policy:"allow"}];function dn(e){if(e.yolo||!_s(e.toolName))return{decision:"approve"};return{decision:"decline",reason:`Hlix Code is running with -p (no terminal to ask), so ${P(e.toolName)} was not run. Report this to the user: re-run with --yolo to let this session change things.`}}class Ve{on;constructor(e){this.on=e}get(){return this.on}set(e){this.on=e}}function pn(e){let t=P(e),n=Ke(e)??"other";return[{value:"approve",label:"Allow once",description:`Run ${t} this one time`},{value:"decline",label:"Decline",description:"Do not run it; tell the agent why"},{value:"always_allow_category",label:"Always allow",description:`Allow every ${n} tool for the rest of this session`}]}import{MastraModelGateway as Is,ModelRouterLanguageModel as Rs}from"@mastra/core/llm";function Cs(e,t){let n=[];for(let r of e??[]){if(!r.name||!r.url||r.name===Y)continue;let o=r.apiKeyEnv?t[r.apiKeyEnv]:r.apiKey;if(r.apiKeyEnv&&!o)continue;n.push({name:r.name,url:r.url.replace(/\/+$/,""),apiKey:o??"",models:r.models??[]})}return n}function un(e){let t=e.indexOf("/");if(t<=0||t===e.length-1)return null;return{provider:e.slice(0,t),model:e.slice(t+1)}}class mn extends Is{id=`${Y}-gateway`;name="Hlix";byProvider;constructor(e){super();this.byProvider=new Map(e.map((t)=>[t.name,t]))}modelIds(){return[...this.byProvider.values()].flatMap((e)=>e.models.map((t)=>`${e.name}/${t}`))}handlesModel(e){let t=un(e);return t!==null&&this.byProvider.has(t.provider)}shouldEnable(){return this.byProvider.size>0}async fetchProviders(){let e={};for(let t of this.byProvider.values())e[t.name]={name:t.name===Y?"Hlix":t.name,url:t.url,apiKeyEnvVar:[],gateway:this.id,models:t.models.map((n)=>`${t.name}/${n}`)};return e}endpointFor(e){let t=un(e);return t?this.byProvider.get(t.provider):void 0}async buildUrl(e){return this.endpointFor(e)?.url}async getApiKey(e){let t=this.endpointFor(e);if(!t)throw Error(`Hlix Code cannot resolve the model "${e}". Run /model to pick one this workspace serves.`);return t.apiKey}resolveLanguageModel(e){let t=this.byProvider.get(e.providerId);if(!t)throw Error(`Hlix Code has no endpoint for provider "${e.providerId}".`);return new Rs({id:`${e.providerId}/${e.modelId}`,url:t.url,apiKey:e.apiKey||t.apiKey,...e.headers?{headers:e.headers}:{}})}}function gn(e){let t=[];if(e.endpoint)t.push({name:e.endpoint.name,url:e.endpoint.url,apiKey:e.endpoint.apiKey,models:e.endpoint.models});if(!e.cloud)t.push(...Cs(e.providers,e.env));return new mn(t)}import{buildBasePrompt as Ts}from"@mastra/core/coding-agent";var N="Hlix Code",ks="Hlix Code",As="noreply@hlix.ai";function Ps(e){if(e==="cloud")return"Your files and commands run in this project's cloud Coding Workspace, not on the user's machine.";if(e==="docker")return"Your files and commands run in a container on the user's machine, with this folder mounted.";return"Your files and commands run on the user's machine."}function fn(e){return e.sandbox==="cloud"?e.filesystemRoot??e.cwd:e.cwd}function hn(e){let t=Ts({projectPath:e.projectPath,projectName:e.projectName,...e.gitBranch?{gitBranch:e.gitBranch}:{},platform:process.platform,date:new Date().toISOString().slice(0,10),mode:e.mode,...e.modelId?{modelId:e.modelId}:{},toolGuidance:Ps(e.sandbox),hasSubagents:e.hasSubagents??!1,productName:N,coAuthorName:ks,coAuthorEmail:As});return e.hostInstructions?`${t}
|
|
13
|
+
|
|
14
|
+
${e.hostInstructions}`:t}var Q="build",yn="plan",Ns=[Q,yn];function bn(e,t=Ns){let n=t.indexOf(e);return t[(n+1)%t.length]??t[0]}function qe(e){let t=new Set(ce);return e.filter((n)=>!t.has(n)&&!n.startsWith("hlix_"))}function Ms(e){return[...new Set([...qe(e),"submit_plan","task_write","task_update","task_check"])]}var Os=["You are planning, not building. Read whatever you need, then write the plan.","Do not create, edit or delete files and do not run shell commands — those tools are not available here, and asking for them instead of planning wastes the user's turn.","Call submit_plan when the plan is ready. The user approves it and you continue in build, where the writing tools and the hlix commands are available again."].join(`
|
|
15
|
+
`),Ls=["You are building. Make the change, then verify it the way this project verifies things.","Read before you write, and prefer the smallest edit that works."].join(`
|
|
16
|
+
`);function xn(e){let t=e.modelId?{defaultModelId:e.modelId}:{};return[{id:Q,name:"build",description:"Read, write and run. The default.",instructions:Ls,metadata:{default:!0},...t},{id:yn,name:"plan",description:"Read and plan; no edits, no commands.",instructions:Os,availableTools:Ms(e.registeredTools),transitionsTo:Q,...t}]}import{lstatSync as js,mkdirSync as Ds,unlinkSync as $s}from"node:fs";import{homedir as Hs}from"node:os";import{join as ze}from"node:path";import{LibSQLStore as Fs}from"@mastra/libsql";function Xe(e=process.env){return ze(e.HLIX_CONFIG_HOME??Hs(),".hlix","code")}function Us(e=process.env){return`file:${ze(Xe(e),"threads.db")}`}var Bs=["auth.json","mastra.db","mastra.db-shm","mastra.db-wal","settings.json"];function Gs(e=process.env){let t=Xe(e);for(let n of Bs){let r=ze(t,n);try{if(!js(r).isFile())continue;$s(r)}catch{}}}function Sn(e=process.env){return Ds(Xe(e),{recursive:!0}),Gs(e),new Fs({id:"hlix-code",url:Us(e)})}var vn="explore",En="plan",wn="execute",Je=[`You are a subagent of ${N}. You were given one task and you do not`,"see the conversation it came from, so do not guess at wider intent: answer","exactly what was asked.","Your reply is the ONLY thing that reaches the agent that called you, so it must","stand alone — name files by path, quote the lines that matter, and say plainly","when you could not find something rather than filling the gap."].join(`
|
|
17
|
+
`),Ws=[Je,"","You are exploring. Read the code and report what is there. You have no tools","that write, edit, delete or run commands, and that is deliberate — if the task","needs a change, say what change and where, and stop.","Be fast: search before you read, read the parts that matter, and do not walk a","whole tree to answer a question about one file."].join(`
|
|
18
|
+
`),Ys=[Je,"","You are planning. Read whatever you need, then return the plan itself: the","files to change, what changes in each, the order, and how the result is","verified in THIS project (its own test or build command, not a generic one).","Do not make the change. A plan that hides a decision behind 'update as needed'","is not a plan — name the decision or say it is open and why."].join(`
|
|
19
|
+
`),Ks=[Je,"","You are making one self-contained change. Read before you write, make the","smallest edit that works, then verify it the way this project verifies things.","Report what you changed, by path, and what the verification said — including","when it failed. A change reported as done that was never run is the one outcome","worse than a change that failed."].join(`
|
|
20
|
+
`);function _n(e){let t=e.modelId?{defaultModelId:e.modelId}:{},n=e.registeredTools.filter((r)=>be.includes(r));return[{id:vn,name:"Explore",description:"Read-only investigation. Give it a question about the codebase; it searches and reads and reports what it found, without changing anything. Cheapest way to answer 'where is X' or 'how does Y work' without filling this conversation with file contents.",instructions:Ws,allowedWorkspaceTools:n,...t},{id:En,name:"Plan",description:"Works out HOW to make a change and returns the plan: files, edits, order, and how to verify. Makes no changes itself. Use it before a change big enough that the approach is the risky part.",instructions:Ys,...t},{id:wn,name:"Execute",description:"Carries out one self-contained change end to end — edit, then verify with this project's own command — and reports what it did and what the verification said. Use it for work that can be checked independently of this conversation.",instructions:Ks,...t}]}var Vs=[vn,En,wn];function In(e,t){let n=[],r=[];for(let o of e){if(Vs.includes(o.name)){r.push(`${o.name} (reserved by ${N})`);continue}n.push({id:o.name,name:o.name,description:o.description||`The ${o.name} agent defined by this project.`,instructions:o.instructions,...t?{defaultModelId:t}:{}})}return{subagents:n,skipped:r}}function Rn(e,t){if(e.length===0&&t.length===0)return"";let n=e.map((r)=>r.id).join(", ");if(t.length===0)return`subagents: ${n}`;return`subagents: ${n} + ${t.length} from this project`}class Se extends Error{constructor(){super("No hlix credential for this folder. Run `hlix auth login`.");this.name="NoCredentialError"}}function Zs(e,t){let n=t.startsWith(`${e.name}/`)?t.slice(e.name.length+1):X;return{id:`${e.name}/${n}`,url:e.url,apiKey:e.apiKey}}async function Cn(e){if(!e.endpoint)throw new Se;let t=e.endpoint,n=e.model?.id??le(X),r=gn({endpoint:t,...e.providers?{providers:e.providers}:{},env:e.env,cloud:e.sandbox==="cloud"}),o=Bt({workspaceId:t.workspaceId,cwd:e.cwd,...e.projectId?{projectId:e.projectId}:{}}),s=Sn(e.env),l=ye(xe(e.memoryTokens)??he),i=null,c=Zs(t,n),a=Kt({storage:s,thresholds:l,observerModel:()=>i?.om.observer.resolvedModel()??c,reflectorModel:()=>i?.om.reflector.resolvedModel()??c}),m=e.workspace?await Js(e.workspace):{},u=e.mcpTools??{},f={...m,...e.extraTools??{},...u},y=Object.keys(f),v=_n({registeredTools:y,modelId:n}),x=In(e.projectSubagents??[],n),_=[...v,...x.subagents],M=fn({sandbox:e.sandbox,cwd:e.cwd,...e.workspace?.filesystem?.basePath?{filesystemRoot:e.workspace.filesystem.basePath}:{}}),V=Xs({id:"hlix-coder",name:N,model:c,instructions:hn({projectPath:M,projectName:qs(e.cwd),mode:Q,modelId:n,sandbox:e.sandbox,hasSubagents:_.length>0,...e.hostInstructions?{hostInstructions:e.hostInstructions}:{}}),tools:f,...e.workspace?{workspace:e.workspace}:{},...e.nestedRules?{inputProcessors:[e.nestedRules]}:{},memory:a}),j=Rt({sandbox:e.sandbox,cwd:e.cwd,active:e.harness,readTools:qe(y),...e.workspace?{workspace:e.workspace}:{},...e.unavailableHarnesses?{unavailable:e.unavailableHarnesses}:{},model:n}),F=j.length>0?j:xn({registeredTools:y,modelId:n}),U=new zs({id:"hlix-code",resourceId:o.resourceId,agent:V,storage:s,memory:a,modes:F,subagents:_,tools:f,gateways:[r],omConfig:{defaultObserverModelId:n,defaultReflectorModelId:n,defaultObservationThreshold:l.observationThreshold,defaultReflectionThreshold:l.reflectionThreshold},toolCategoryResolver:ln(Object.keys(u)),...e.workspace?{workspace:e.workspace}:{}});await U.init();let k=await U.createSession({resourceId:o.resourceId,tags:{projectPath:o.root}});if(i=k,n)await k.model.switch({modelId:n});let g=Ct({fromFlag:e.harnessFromFlag===!0,harness:e.harness,modesBuilt:j.length>0,current:k.mode.get()});if(g)await k.mode.switch({modeId:g});for(let b of cn)await k.permissions.setForCategory(b);return{controller:U,session:k,gateway:r,store:s,memory:a,scope:o,harnessModesBuilt:j.length>0,subagentLine:Rn(v,x.subagents),subagentsSkipped:x.skipped,dispose:async()=>{await U.destroy().catch(()=>{}),await s.close().catch(()=>{})}}}import{Editor as ka,ProcessTerminal as Aa,SelectList as Dr,Input as Pa,TuiMainScreen as Na,truncateToWidth as ft}from"@earendil-works/pi-tui";import{readFileSync as Qs,statSync as ei}from"node:fs";import{basename as ti,extname as ni,isAbsolute as ri,join as oi}from"node:path";import{CombinedAutocompleteProvider as si,Key as ve,matchesKey as ii}from"@earendil-works/pi-tui";function ai(e,t=ii){if(t(e,ve.shift("tab")))return"cycle-mode";if(t(e,ve.ctrl("c")))return"interrupt";if(t(e,ve.ctrl("o")))return"expand";if(t(e,ve.escape))return"abort";return"text"}var li=2000;class kn{windowMs;armedAt=0;constructor(e=li){this.windowMs=e}press(e=Date.now()){if(this.armedAt!==0&&e-this.armedAt<=this.windowMs)return this.armedAt=0,"exit";return this.armedAt=e,"warn"}disarm(){this.armedAt=0}}function ci(e){return[...e.entries()].map(([t,n])=>({name:t,description:n.description})).sort((t,n)=>t.name.localeCompare(n.name))}var Ze="Press Ctrl-C again to leave Hlix Code.";class An extends si{applyCompletion(e,t,n,r,o){let s=e[t]??"";if(/^\/[^\s/]*$/.test(s.slice(0,n))){let l=[...e];return l[t]=`/${r.value} ${s.slice(n)}`,{lines:l,cursorLine:t,cursorCol:r.value.length+2}}return super.applyCompletion(e,t,n,r,o)}}function di(e=process.env){for(let t of["fd","fdfind"]){let n=$e(t,e);if(n)return n}return null}function pi(e,t){let n=e.getFocusedComponent;if(typeof n!=="function")return!1;let r=n.call(e);return r!==void 0&&r!==null&&r!==t}function Pn(e){let t=new kn;return e.editor.setAutocompleteProvider(new An(ci(e.commands),e.basePath,di())),e.editor.onSubmit=(n)=>{let r=n.trim();if(!r)return;e.editor.addToHistory(r),e.editor.setText(""),e.handlers.onSubmit(r)},e.tui.addInputListener((n)=>{switch(ai(n)){case"cycle-mode":return e.handlers.onCycleMode(),{consume:!0};case"interrupt":if(t.press()==="exit")e.handlers.onExit();else e.handlers.onInterruptWarning(Ze);return{consume:!0};case"expand":return t.disarm(),e.handlers.onExpand(),{consume:!0};case"abort":if(e.editor.isShowingAutocomplete())return;if(pi(e.tui,e.editor))return;return t.disarm(),e.handlers.onAbort(),{consume:!0};default:t.disarm();return}})}var ui={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp"},Tn=8388608;function Nn(e,t,n=Qs,r=(o)=>ei(o).size){let o=[],s=[],l=new Set;for(let i of e.matchAll(/(?:^|\s)@(\S+)/g)){let c=i[1],a=ui[ni(c).toLowerCase()];if(!a||l.has(c))continue;l.add(c);let m=ri(c)?c:oi(t,c);try{let u=r(m);if(u>Tn){s.push(`@${c} is ${Math.round(u/1048576)} MB — too large to attach (limit ${Tn/1048576} MB).`);continue}o.push({data:`data:${a};base64,${n(m).toString("base64")}`,mediaType:a,filename:ti(c)})}catch{s.push(`@${c} could not be read, so it was not attached.`)}}return{content:e,files:o,notes:s}}import{z as L}from"zod";var ee=L.string().trim().min(1),mi=L.discriminatedUnion("kind",[L.object({kind:L.literal("project"),projectId:ee}).strict(),L.object({kind:L.literal("cycle"),projectId:ee,cycleId:ee}).strict(),L.object({kind:L.literal("task"),projectId:ee,taskId:ee}).strict(),L.object({kind:L.literal("agent"),projectId:ee,agentId:ee}).strict()]);import{z as d}from"zod";var Mn=["github-compare","workspace-artifact"],Ee=d.enum(["added","removed","modified","renamed","copied","changed","unchanged","unknown"]),On=d.object({path:d.string(),previousPath:d.string().nullable(),status:Ee,additions:d.number().nullable(),deletions:d.number().nullable(),patch:d.string().nullable(),patchTruncated:d.boolean()}),Ln=d.object({status:d.enum(["ahead","behind","identical","diverged","unknown"]),aheadBy:d.number().nullable(),behindBy:d.number().nullable()}),jn=d.object({kind:d.literal("git-archive"),reviewUrl:d.string(),sizeBytes:d.number().nullable(),capturedAt:d.string().nullable()}),Dn=d.object({verdict:d.enum(["approved","rejected"]),summary:d.string().nullable(),headSha:d.string().nullable(),observedAt:d.string(),stale:d.boolean()}),gi=d.object({taskId:d.string(),repoId:d.string().nullable(),source:d.enum(Mn),observedAt:d.string(),baseRef:d.string().nullable(),baseSha:d.string().nullable(),headRef:d.string().nullable(),headSha:d.string().nullable(),comparison:Ln,filesChanged:d.number().nullable(),additions:d.number().nullable(),deletions:d.number().nullable(),commits:d.number().nullable(),files:d.array(On),filesTruncated:d.boolean(),evaluator:Dn.nullable(),artifact:jn.nullable()}),$n=["base","head"],Qe=d.enum($n),Hn=["open","resolved"],et=d.enum(Hn),Fn=d.object({pagePath:d.string().min(1).max(2048).regex(/^\/(?!\/)/,"expected a same-origin absolute path").refine((e)=>!/[?#\\]/.test(e),"query, fragment, and backslash are not allowed"),selector:d.string().min(1).max(512),viewport:d.object({width:d.number().int().min(320).max(1920),height:d.number().int().min(320).max(1200),deviceScaleFactor:d.literal(1)}).strict()}).strict(),Un=["previews-disabled","boundary-unavailable","review-head-unavailable","no-live-preview","revision-mismatch","source-not-isolated","unsafe-source"],Bn=d.discriminatedUnion("enabled",[d.object({enabled:d.literal(!0)}),d.object({enabled:d.literal(!1),reasonCode:d.enum(Un),reason:d.string()})]),Gn=d.string().regex(/^[0-9a-f]{40}$/i,"expected a commit sha"),Wn=d.object({id:d.string(),taskId:d.string(),projectId:d.string(),authorId:d.string(),headSha:d.string(),path:d.string().nullable(),side:Qe.nullable(),lineStart:d.number().nullable(),lineEnd:d.number().nullable(),selectedText:d.string().nullable(),body:d.string(),resolution:et,resolvedBy:d.string().nullable(),resolvedAt:d.string().nullable(),revisionIteration:d.number().nullable(),createdAt:d.string(),updatedAt:d.string(),stale:d.boolean()}),fi=d.object({taskId:d.string(),headSha:d.string().nullable(),comments:d.array(Wn),visualContext:Bn.optional()}),hi=d.object({headSha:Gn,body:d.string().min(1).max(1e4),path:d.string().min(1).max(1024).nullish(),side:Qe.nullish(),lineStart:d.number().int().positive().nullish(),lineEnd:d.number().int().positive().nullish(),selectedText:d.string().max(1e4).nullish(),visualContext:Fn.optional()}).superRefine((e,t)=>{if(e.lineStart!=null&&(e.path==null||e.side==null))t.addIssue({code:d.ZodIssueCode.custom,path:["lineStart"],message:"a line comment needs both a path and a side"});if(e.lineEnd!=null&&(e.lineStart==null||e.lineEnd<e.lineStart))t.addIssue({code:d.ZodIssueCode.custom,path:["lineEnd"],message:"lineEnd must be >= lineStart"});if(e.side!=null&&e.path==null)t.addIssue({code:d.ZodIssueCode.custom,path:["side"],message:"a side needs a path"})}),yi=d.object({resolution:et}),bi=d.object({headSha:Gn}),xi=d.object({taskId:d.string(),cycleId:d.string(),headSha:d.string(),commentIds:d.array(d.string()),staleSkipped:d.number(),feedback:d.string(),iteration:d.number(),started:d.boolean(),reason:d.string().nullable()});import{z as h}from"zod";var Yn=h.enum(["github","workspace"]),tt=h.object({path:h.string(),previousPath:h.string().nullable(),status:Ee,additions:h.number().nullable(),deletions:h.number().nullable(),binary:h.boolean()}),Kn=h.object({sha:h.string(),subject:h.string(),at:h.string()}),pe=h.object({ref:h.string(),sha:h.string().nullable()}),Vn=h.object({repoKey:h.string(),label:h.string(),base:pe,head:pe,files:h.array(tt),filesTruncated:h.boolean(),filesChanged:h.number(),additions:h.number(),deletions:h.number(),commits:h.array(Kn),unavailable:h.enum(["repository_unreachable"]).nullable()}),qn=h.object({taskId:h.string(),title:h.string(),repoKey:h.string(),files:h.array(tt),observedAt:h.string()}),Si=h.object({projectId:h.string(),source:Yn,environmentState:h.string().nullable(),observedAt:h.string(),repos:h.array(Vn),inFlight:h.array(qn)}),vi=h.object({repoKey:h.string(),path:h.string(),patch:h.string().nullable(),patchTruncated:h.boolean(),binary:h.boolean()}),Ei=h.object({repoKey:h.string(),ref:pe,paths:h.array(h.string()),truncated:h.boolean()}),wi=h.object({error:h.string(),environmentState:h.string()}),_i=h.object({repoKey:h.string(),path:h.string(),ref:pe,content:h.string().nullable(),truncated:h.boolean(),binary:h.boolean(),size:h.number().nullable()});var we={"claude-opus-4-8":{provider:"anthropic",contextWindow:1e6,displayName:"Opus 4.8",tier:"frontier"},"claude-sonnet-5":{provider:"anthropic",contextWindow:1e6,displayName:"Sonnet 5",tier:"primary"},"claude-opus-4-7":{provider:"anthropic",contextWindow:200000,displayName:"Opus 4.7",tier:"frontier",picker:!1},"claude-opus-4-6":{provider:"anthropic",contextWindow:200000,displayName:"Opus 4.6",tier:"frontier",picker:!1},"claude-sonnet-4-6":{provider:"anthropic",contextWindow:200000,displayName:"Sonnet 4.6",tier:"primary",picker:!1},"claude-sonnet-4-5-20250929":{provider:"anthropic",contextWindow:200000,displayName:"Sonnet 4.5",tier:"primary",picker:!1},"claude-haiku-4-5":{provider:"anthropic",contextWindow:200000,displayName:"Haiku 4.5",tier:"fast"},"gpt-5.6-sol":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Sol",tier:"frontier"},"gpt-5.6-terra":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Terra",tier:"primary"},"gpt-5.6-luna":{provider:"openai",contextWindow:1050000,displayName:"GPT-5.6 Luna",tier:"fast"},"gpt-5.5":{provider:"openai",contextWindow:400000,displayName:"GPT-5.5",tier:"frontier",picker:!1},"gpt-5":{provider:"openai",contextWindow:256000,displayName:"GPT-5",tier:"frontier",picker:!1},"gpt-5-mini":{provider:"openai",contextWindow:128000,displayName:"GPT-5 Mini",tier:"fast",picker:!1},"gpt-4.1-mini":{provider:"openai",contextWindow:128000,displayName:"GPT-4.1 Mini",tier:"fast",picker:!1},"gemini-3.8-flash":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini 3.8 Flash",tier:"fast"},"gemini-3.6-flash":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini 3.6 Flash",tier:"fast",picker:!1},"gemini-3.5-flash":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini 3.5 Flash",tier:"fast",picker:!1},"gemini-2.5-pro":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini 2.5 Pro",tier:"primary",picker:!1},"gemini-embedding-2":{provider:"google_genai",contextWindow:8192,displayName:"Gemini Embedding 2",tier:"embedding",picker:!1},"grok-4.5":{provider:"openrouter",contextWindow:500000,displayName:"Grok 4.5",tier:"frontier"},"kimi-k3":{provider:"openrouter",contextWindow:1048576,displayName:"Kimi K3",tier:"primary"},"deepseek-v4-pro":{provider:"openrouter",contextWindow:1048576,displayName:"DeepSeek V4 Pro",tier:"primary"},"glm-5.3":{provider:"openrouter",contextWindow:1048576,displayName:"GLM 5.3",tier:"primary"},"qwen3.8-max":{provider:"openrouter",contextWindow:1e6,displayName:"Qwen 3.8 Max",tier:"primary"},auto:{provider:"openrouter",contextWindow:2000000,displayName:"Auto",tier:"primary"},"pareto-code":{provider:"openrouter",contextWindow:2000000,displayName:"Auto for coding",tier:"primary"},"opus-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Opus (Latest)",tier:"frontier"},"sonnet-latest":{provider:"anthropic",contextWindow:1e6,displayName:"Claude Sonnet (Latest)",tier:"primary"},"gemini-flash-latest":{provider:"google_genai",contextWindow:1048576,displayName:"Gemini Flash (Latest)",tier:"fast"},"gpt-latest":{provider:"openai",contextWindow:1050000,displayName:"GPT (Latest)",tier:"frontier"},"whisper-1":{provider:"openrouter",contextWindow:0,displayName:"Whisper 1 (Speech-to-Text)",tier:"media",picker:!1},"voxtral-mini-tts":{provider:"openrouter",contextWindow:4096,displayName:"Voxtral Mini TTS (Text-to-Speech)",tier:"media",picker:!1},"seedream-4-5":{provider:"openrouter",contextWindow:4096,displayName:"Seedream 4.5 (Image)",tier:"media",picker:!1},"veo-3-1":{provider:"openrouter",contextWindow:0,displayName:"Veo 3.1 (Video)",tier:"media",picker:!1}};var Ii=Object.keys(we);var Ri={"claude-opus-4-8":"openrouter/anthropic/claude-opus-4.8","claude-sonnet-5":"openrouter/anthropic/claude-sonnet-5","claude-opus-4-7":"openrouter/anthropic/claude-opus-4.7","claude-opus-4-6":"openrouter/anthropic/claude-opus-4.6","claude-sonnet-4-6":"openrouter/anthropic/claude-sonnet-4.6","claude-sonnet-4-5-20250929":"openrouter/anthropic/claude-sonnet-4.5","claude-haiku-4-5":"openrouter/anthropic/claude-haiku-4.5","gpt-5.6-sol":"openrouter/openai/gpt-5.6-sol","gpt-5.6-terra":"openrouter/openai/gpt-5.6-terra","gpt-5.6-luna":"openrouter/openai/gpt-5.6-luna","gpt-5.5":"openrouter/openai/gpt-5.5","gpt-5":"openrouter/openai/gpt-5","gpt-5-mini":"openrouter/openai/gpt-5-mini","gpt-4.1-mini":"openrouter/openai/gpt-4.1-mini","gemini-3.8-flash":"openrouter/google/gemini-3.8-flash","gemini-3.6-flash":"openrouter/google/gemini-3.6-flash","gemini-3.5-flash":"openrouter/google/gemini-3.5-flash","gemini-2.5-pro":"openrouter/google/gemini-2.5-pro","gemini-embedding-2":"direct:google/gemini-embedding-2","grok-4.5":"openrouter/x-ai/grok-4.5","kimi-k3":"openrouter/moonshotai/kimi-k3","deepseek-v4-pro":"openrouter/deepseek/deepseek-v4-pro","glm-5.3":"openrouter/z-ai/glm-5.3","qwen3.8-max":"openrouter/qwen/qwen3.8-max",auto:"openrouter/openrouter/auto","pareto-code":"openrouter/openrouter/pareto-code","opus-latest":"openrouter/~anthropic/claude-opus-latest","sonnet-latest":"openrouter/~anthropic/claude-sonnet-latest","gemini-flash-latest":"openrouter/~google/gemini-flash-latest","gpt-latest":"openrouter/~openai/gpt-latest","whisper-1":"openrouter/openai/whisper-1","voxtral-mini-tts":"openrouter/mistralai/voxtral-mini-tts-2603","seedream-4-5":"openrouter/bytedance-seed/seedream-4.5","veo-3-1":"openrouter/google/veo-3.1"};var D="◆",Ci=(()=>{let e={};for(let t of Object.keys(we)){let n=we[t];e[t]=n.displayName,e[Ri[t]]=n.displayName,e[`${n.provider}:${t}`]=n.displayName}return e})();function _e(e){if(!e)return e;let n=Ci[e]??e.split(/[/:]/).pop()??e;return`${D} ${n}`}var nt={"claude-code":{id:"claude-code",displayName:"Claude Code",description:"Anthropic coding CLI. Flagship, always installed.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:["ANTHROPIC_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0},"openai-agents":{id:"openai-agents",displayName:"OpenAI Agents SDK",description:"Model-agnostic agent SDK. Not yet available for running tasks.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:[],anyOf:["OPENAI_API_KEY","ANTHROPIC_API_KEY","GOOGLE_API_KEY","OPENROUTER_API_KEY"]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1},codex:{id:"codex",displayName:"Codex",description:"OpenAI coding CLI. Installed on demand.",driverKind:"external-acp",capabilities:["structured-result","usage-report","model-select"],credentials:{required:["OPENAI_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!0},aider:{id:"aider",displayName:"Aider",description:"Model-agnostic coding CLI. Not yet available for running tasks.",driverKind:"external-acp",capabilities:["structured-result","model-select"],credentials:{required:[],anyOf:["OPENAI_API_KEY","ANTHROPIC_API_KEY","GOOGLE_API_KEY","OPENROUTER_API_KEY"]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"runtime",effort:!1},available:!1},"cursor-agent":{id:"cursor-agent",displayName:"Cursor Agent",description:"Cursor headless coding CLI. Installed on demand.",driverKind:"external-acp",capabilities:["structured-result","usage-report"],credentials:{required:["CURSOR_API_KEY"],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"hlix-result-line",version:1},modelSupport:{selection:"none",effort:!1},available:!0},hlix:{id:"hlix",displayName:"Hlix",description:"Our own coding agent, built into hlix and run by the platform.",driverKind:"native",capabilities:["structured-result"],credentials:{required:[],anyOf:[]},supportedPlatforms:["linux"],resultProtocol:{kind:"native-runner",version:1},modelSupport:{selection:"orchestration",effort:!1},available:!0}},rt=Object.keys(nt),Ie=Object.values(nt),Ti=Ie.filter(({driverKind:e})=>e==="external-acp").map(({id:e})=>e),zn=Ie.filter(({available:e,driverKind:t})=>e&&t==="external-acp"),ot=zn.map(({id:e})=>e),Xn=Ie.filter(({available:e})=>e),Jn=Xn.map(({id:e})=>e),st="hlix";var Zn=["chat","kanban","linear","github","api"];var it={chat:{enabledByDefault:!0,triage:!0,kind:"native",label:"Chat"},kanban:{enabledByDefault:!0,triage:!0,kind:"native",label:"Board"},linear:{enabledByDefault:!0,triage:!0,kind:"external",label:"Linear"},github:{enabledByDefault:!0,triage:!0,kind:"external",label:"GitHub issues"},api:{enabledByDefault:!0,triage:!0,kind:"native",label:"API"}};function Qn(e){return Zn.filter((t)=>it[t].kind===e)}var Ai=Qn("external"),Pi=Qn("native");import{z as p}from"zod";var er=p.enum(rt),tr=p.enum(ot),nr=p.object({node:p.string().optional(),python:p.string().optional(),bun:p.string().optional(),playwright:p.boolean().optional()}).partial(),rr=p.object({agents:p.array(tr).optional(),toolchain:nr.optional(),aptPackages:p.array(p.string()).optional(),setup:p.string().optional(),hash:p.string().optional(),imageTag:p.string().nullable().optional(),linearProjectId:p.string().optional(),linearTeamId:p.string().optional()}).partial(),$i=p.object({owner:p.string(),name:p.string(),cloneUrl:p.string(),defaultBranch:p.string()}),or=p.object({key:p.string(),cloneUrl:p.string().nullable(),owner:p.string().nullable(),name:p.string().nullable(),defaultBranch:p.string(),setupCommand:p.string().nullable().optional(),verifyCommand:p.string().nullable().optional()});var sr=p.object({name:p.string(),skillSlugs:p.array(p.string()),agentSlugs:p.array(p.string())}),ir=p.object({path:p.string(),content:p.string()}),ar=p.object({vars:p.record(p.string(),p.string()).default({}),files:p.array(ir).optional(),skills:p.array(p.string()).optional(),mcpServers:p.array(p.unknown()).optional(),managedPaths:p.array(p.string().refine((e)=>e.length>0&&e===e.normalize("NFC")&&!e.startsWith("/")&&!e.includes("\\")&&!/[\u0000-\u001f\u007f]/.test(e)&&e.split("/").every((t)=>t&&t!=="."&&t!==".."),"managed path must be a canonical project-relative path")).optional()}),lr=p.object({path:p.string(),kind:p.enum(["dotenv","credential","detected-content"]),contentBase64:p.string(),size:p.number().int().nonnegative(),sha256:p.string().regex(/^[0-9a-f]{64}$/)}),cr=p.object({taskId:p.string(),cycleId:p.string(),threadId:p.string(),organizationId:p.string().optional(),projectId:p.string().optional(),description:p.string(),reviewFeedback:p.string().optional(),iteration:p.number().default(0),operationId:p.string().min(1).optional(),repo:or.nullable().default(null),verifyCommand:p.string().nullable().optional(),branch:p.string(),baseBranch:p.string(),githubToken:p.string().optional(),snapshotKey:p.string().optional(),aiGatewayUrl:p.string().optional(),secrets:p.record(p.string(),p.string()),packs:p.array(sr),systemPrompt:p.string().optional(),timeoutSeconds:p.number().default(1800),resultToken:p.string().min(1).optional(),agent:er.default(st),agentEnv:p.record(p.string(),p.string()).optional(),projectRuntime:rr.optional(),environment:ar.optional(),protectedFiles:p.array(lr).optional()}),Hi=p.enum(["acp"]),Fi=p.enum(["builder","desktop","e2e"]),Ui=p.object({batchId:p.string(),tasks:p.array(cr).min(1).max(20)}),dr=p.object({inputTokens:p.number(),outputTokens:p.number(),costUsd:p.number()}),Bi=p.object({taskId:p.string(),token:p.string().optional(),status:p.enum(["success","failed"]),cost:dr.optional(),model:p.string().optional(),error:p.string().optional()});import{z as T}from"zod";var Gi=T.discriminatedUnion("type",[T.object({type:T.literal("text"),text:T.string()}),T.object({type:T.literal("reasoning"),text:T.string()}),T.object({type:T.literal("tool"),toolCallId:T.string().min(1),toolName:T.string().min(1),state:T.enum(["pending","done","error"]),input:T.unknown().optional(),output:T.unknown().optional(),error:T.string().optional()})]);import{SelectList as Wi}from"@earendil-works/pi-tui";var at=(e)=>e;function Re(e){return(t)=>t?`\x1B[${e}m${t}\x1B[0m`:t}var oe={gold:{rgb:[255,204,0],cube:220},vermilion:{rgb:[230,0,23],cube:160},teal:{rgb:[54,145,119],cube:66},paper:{rgb:[229,230,232],cube:188},slate:{rgb:[151,153,157],cube:103}};function Ce(e=process.env,t=process.stdout.isTTY===!0){if(e.NO_COLOR!==void 0&&e.NO_COLOR!=="")return"none";let n=e.FORCE_COLOR!==void 0&&e.FORCE_COLOR!=="";if(!t&&!n)return"none";let r=(e.COLORTERM??"").toLowerCase();if(r==="truecolor"||r==="24bit")return"truecolor";if(/-direct\b/.test(e.TERM??""))return"truecolor";return"ansi256"}var se=(e,t)=>{if(t==="none")return at;if(t==="truecolor")return Re(`38;2;${e.rgb[0]};${e.rgb[1]};${e.rgb[2]}`);return Re(`38;5;${e.cube}`)};function Te(e=Ce()){return{brand:se(oe.gold,e),muted:e==="none"?at:Re("2"),user:se(oe.paper,e),alert:se(oe.vermilion,e),ok:se(oe.teal,e),added:se(oe.teal,e),removed:se(oe.vermilion,e)}}function ie(e){return{selectedPrefix:e.brand,selectedText:e.brand,description:e.muted,scrollInfo:e.muted,noMatch:e.muted}}function pr(e){return{borderColor:e.muted,selectList:ie(e)}}function ur(e,t=Ce()){let n=(r)=>t==="none"?at:Re(r);return{heading:e.brand,link:e.ok,linkUrl:e.muted,code:e.brand,codeBlock:e.user,codeBlockBorder:e.muted,quote:e.muted,quoteBorder:e.muted,hr:e.muted,listBullet:e.brand,bold:n("1"),italic:n("3"),strikethrough:n("9"),underline:n("4")}}var Yi=12;function Ki(e){let t=/^(.*?)\(([^()]*)\)\s*$/.exec(e);if(!t)return _e(e);let n=(t[1]??"").trim(),r=_e(t[2]??"").slice(D.length).trim();return n?`${D} ${n} (${r})`:`${D} ${r}`}function lt(e){let t=new Set,n=[],r=(o,s)=>{if(t.has(o))return;t.add(o),n.push({id:o,label:Ki(s)})};for(let o of e.served??[])r(`${e.providerName}/${o.id}`,o.name);for(let o of e.userModelIds??[]){if(o.startsWith(`${e.providerName}/`))continue;r(o,o)}return n}function gr(e){let t=fe(e.cwd)?"project":"global";return mr({key:"model",value:e.modelId,scope:t,cwd:e.cwd,env:e.env})}function fr(e){let t=e.colors??Te(),n=e.entries.map((i)=>({value:i.id,label:i.label})),r=new Wi(n,Yi,ie(t)),o=e.entries.findIndex((i)=>i.id===e.current);if(o>=0)r.setSelectedIndex(o);let s=e.tui.showOverlay(r,{width:"60%",maxHeight:"60%"}),l=()=>{s.hide(),e.tui.requestRender()};r.onSelect=(i)=>{l();let c=e.entries.find((a)=>a.id===i.value);if(c)e.onPick(c)},r.onCancel=()=>{l(),e.onCancel?.()},s.focus()}import{Markdown as Vi,truncateToWidth as H,wrapTextWithAnsi as ct}from"@earendil-works/pi-tui";function hr(e,t){if(e.length>600||t.length>600)return[...e.map((c)=>({kind:"del",text:c})),...t.map((c)=>({kind:"add",text:c}))];let n=e.length,r=t.length,o=Array.from({length:n+1},()=>Array(r+1).fill(0));for(let c=n-1;c>=0;c-=1)for(let a=r-1;a>=0;a-=1)o[c][a]=e[c]===t[a]?o[c+1][a+1]+1:Math.max(o[c+1][a],o[c][a+1]);let s=[],l=0,i=0;while(l<n&&i<r)if(e[l]===t[i])s.push({kind:"same",text:e[l]}),l+=1,i+=1;else if(o[l+1][i]>=o[l][i+1])s.push({kind:"del",text:e[l]}),l+=1;else s.push({kind:"add",text:t[i]}),i+=1;while(l<n)s.push({kind:"del",text:e[l++]});while(i<r)s.push({kind:"add",text:t[i++]});return s}function yr(e,t,n={}){let r=n.context??2,o=hr(e.split(`
|
|
21
|
+
`),t.split(`
|
|
22
|
+
`)),s=new Set;o.forEach((a,m)=>{if(a.kind==="same")return;for(let u=m-r;u<=m+r;u+=1)if(u>=0&&u<o.length)s.add(u)});let l=[],i=0,c=()=>{if(i===0)return;l.push(` … ${i} unchanged line${i===1?"":"s"}`),i=0};return o.forEach((a,m)=>{if(!s.has(m)){i+=1;return}c(),l.push(`${a.kind==="add"?"+":a.kind==="del"?"-":" "} ${a.text}`)}),c(),l}function br(e,t){let n=hr(e.split(`
|
|
23
|
+
`),t.split(`
|
|
24
|
+
`)),r=n.filter((s)=>s.kind==="add").length,o=n.filter((s)=>s.kind==="del").length;if(r===0&&o===0)return"";return[r>0?`+${r}`:"",o>0?`−${o}`:""].filter(Boolean).join(" ")}var qi={user:"›",assistant:" ",tool:"⏺",command:"▸",subagent:"↳",notice:"·"},dt=8;function xr(e,t,n){let r=`┌ ${e} `,o=Math.max(0,t-r.length);return n(H(`${r}${"─".repeat(o)}`,t))}var zi=(e,t)=>t(H(`└${"─".repeat(Math.max(0,e-1))}`,e));function ue(e,t,n,r){let o=Math.max(1,t-2),s=[];for(let l of e){let i=l===""?[""]:ct(l,o);for(let c of i)s.push(H(`${r("│")} ${n(c)}`,t))}return s}function Xi(e){let t=e.tool;if(!t)return"";let n=[],r=t.args??{};if(typeof r.old_string==="string"&&typeof r.new_string==="string"){let o=br(r.old_string,r.new_string);if(o)n.push(o)}if(t.durationMs!==void 0)n.push(`${(t.durationMs/1000).toFixed(1)}s`);if(t.exitCode!==void 0&&t.exitCode!==0)n.push(`exit ${t.exitCode}`);return n.join(" · ")}function Ji(e){switch(e.tool?.state){case"running":return"⏺";case"awaiting":return"?";case"declined":return"⊘";case"error":return"✗";default:return"✓"}}function Zi(e){let t=e.tool;if(!t)return[];let n=t.args??{};if(typeof n.old_string==="string"&&typeof n.new_string==="string")return yr(n.old_string,n.new_string);let r=(t.result??"").trimEnd();return r===""?[]:r.split(`
|
|
25
|
+
`)}function pt(e,t){let n=e-t;return`… ${n} more line${n===1?"":"s"} — ctrl-o to expand`}function Sr(e,t){let{width:n,colors:r}=t;switch(e.kind){case"assistant":return vr(e.text,n,r);case"command":return ea(e,t);case"tool":return ta(e,t);case"subagent":return ra(e,t);default:{let o=e.kind==="user"?r.user:e.error?r.alert:r.muted,s=e.error?"!":qi[e.kind];return Qi(e.text,s,n,o)}}}function vr(e,t,n){let r=Math.max(8,t-2);return new Vi(e,0,0,ur(n)).render(r).map((s)=>H(` ${s}`,t))}function Qi(e,t,n,r){let o=Math.max(1,n-2),s=[];for(let l of e.split(`
|
|
26
|
+
`)){let i=l===""?[""]:ct(l,o);for(let c of i){let a=s.length===0?`${t} `:" ";s.push(H(`${a}${r(c)}`,n))}}return s}function ea(e,t){let{width:n,colors:r}=t,o=e.error?r.alert:r.muted,s=e.text===""?["(no output)"]:e.text.split(`
|
|
27
|
+
`),l=e.expanded===!0?s:s.slice(0,dt*3),i=ue(l,n,e.error?r.alert:r.user,o);return[xr(e.title??"command",n,o),...i,...l.length<s.length?ue([pt(s.length,l.length)],n,r.muted,o):[],zi(n,o)]}function ta(e,t){let{width:n,colors:r}=t,o=e.tool,s=Ji(e),l=e.error?r.alert:o?.state==="running"?r.muted:r.ok,i=Xi(e),c=`${s} ${e.text}`,a=n-c.length-i.length-1,m=i&&a>0?H(`${l(c)}${" ".repeat(a)}${r.muted(i)}`,n):H(l(c),n);if(o?.state==="running"||o?.state==="awaiting")return[m];let u=Zi(e);if(u.length===0)return[m];let f=e.expanded===!0?u:u.slice(0,dt);return[m,...na(f,n,r),...f.length<u.length?ue([pt(u.length,f.length)],n,r.muted,r.muted):[]]}function na(e,t,n){let r=Math.max(1,t-2),o=[];for(let s of e){let l=s.startsWith("+")?n.added:s.startsWith("-")?n.removed:n.muted;for(let i of s===""?[""]:ct(s,r))o.push(H(`${n.muted("│")} ${l(i)}`,t))}return o}function ra(e,t){let{width:n,colors:r}=t,o=e.subagent;if(!o)return[];let s=e.error?r.alert:r.muted,l=o.state==="running"?"↳":e.error?"✗":"✓",i=o.durationMs!==void 0?` · ${(o.durationMs/1000).toFixed(1)}s`:"",c=H(`${(e.error?r.alert:r.brand)(`${l} ${o.agentType}`)}${r.muted(`${i}${o.tools.length>0?` · ${o.tools.length} tool calls`:""}`)}`,n),a=[o.task];if(o.tools.length>0)a.push(`tools: ${[...new Set(o.tools)].join(", ")}`);if(o.state!=="running"&&o.result){let m=o.result.split(`
|
|
28
|
+
`),u=e.expanded===!0?m:m.slice(0,dt);if(a.push("",...u),u.length<m.length)a.push(pt(m.length,u.length))}return[c,...ue(a,n,r.muted,s)]}function Er(e,t){let{width:n,colors:r}=t,o=e.args??{},s=[o.command,o.path,o.pattern,o.query,o.task].find((i)=>typeof i==="string"&&i!==""),l=P(e.toolName);return[xr(`Approve ${l}`,n,r.alert),...ue(s?[s]:["(no arguments)"],n,r.user,r.alert)]}var me="yolo";function oa(e,t){if(t<=0)return`${Math.round(e/1000)}k`;return`${Math.round(e/t*100)}% of ${Math.round(t/1000)}k`}function sa(e){return e>0&&e<0.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}var ia=4,aa=["cost","total_cost","costUsd"];function ke(e){let t=e?.raw;for(let n=0;n<ia&&t&&typeof t==="object";n+=1){for(let r of aa){let o=t[r];if(typeof o==="number"&&Number.isFinite(o)&&o>0)return o}t=t.raw}return}var la=(e)=>e.startsWith(D)?e:`${D} ${e}`,ca=(e)=>e.split(" (")[0];function da(e){let t=[...e.yolo?[me]:[],e.sandbox,e.harness];if(e.mode&&e.mode!==ca(e.harness))t.push(e.mode);if(e.model)t.push(la(e.model));if(e.workspace)t.push(e.workspace);if(e.branch)t.push(e.branch);if(e.context)t.push(oa(e.context.used,e.context.total));if(e.costUsd!==void 0)t.push(sa(e.costUsd));if(e.memory)t.push(e.memory);if(e.warning)t.push(e.warning);return t}function wr(e,t){let n=da(e).join(" · ");if(t===void 0||t<=0||n.length<=t)return n;return t<=1?n.slice(0,t):`${n.slice(0,t-1)}…`}var pa="subagent",Rr=()=>({entries:[],busy:!1,status:"",approval:null});function Ae(e){let t=e?.content,n=t?.parts;if(!Array.isArray(n)){let r=t?.content;return typeof r==="string"?r:""}return n.filter((r)=>{let o=r;return o.type==="text"&&typeof o.text==="string"}).map((r)=>r.text).join("")}function _r(e,t){let n=t??{},r=n.path??n.command??n.pattern??n.query;return typeof r==="string"?`${P(e)} ${r}`:P(e)}function Ir(e){let t=e===void 0?null:/^Exit code: (\d+)$/m.exec(e);return t?Number(t[1]):void 0}function ua(e){if(typeof e==="string")return e;if(e===void 0||e===null)return"";let t=e.content;if(Array.isArray(t))return t.map((n)=>{let r=n;return r.type==="text"&&typeof r.text==="string"?r.text:""}).filter((n)=>n!=="").join(`
|
|
29
|
+
`);try{return JSON.stringify(e,null,2)}catch{return String(e)}}var ma={om_observation_start:"remembering…",om_observation_end:"",om_reflection_start:"condensing memory…",om_reflection_end:"",compaction_start:"compacting…",compaction_end:""},ga={thread_created:()=>"New conversation.",info:(e)=>typeof e.message==="string"?e.message:null};function Cr(e,t){let n=(i,c)=>{let a=e.entries.findIndex((u)=>u.id===i),m=[...e.entries];if(a<0)m.push(c);else m[a]=c;return{...e,entries:m}},r=(i)=>({...e,entries:[...e.entries,i]}),o=(i)=>e.entries.find((c)=>c.id===i),s=(i)=>`tool:${String(i)}`,l=(i)=>`sub:${String(i)}`;switch(t.type){case"agent_start":return{...e,busy:!0};case"agent_end":return{...e,busy:!1,status:""};case"message_start":case"message_update":case"message_end":{let i=t.message;if(!i?.id)return e;let c=Ae(i);if(!c)return e;let a=`msg:${i.id}`;if(o(a)?.text===c)return e;return n(a,{kind:i.role==="user"?"user":"assistant",id:a,text:c})}case"tool_start":{if(t.toolName===pa)return e;let i=s(t.toolCallId),c=P(t.toolName);return n(i,{kind:"tool",id:i,text:_r(t.toolName,t.args),tool:{name:c,args:t.args,state:"running"}})}case"tool_approval_required":{let i=s(t.toolCallId),c=o(i),a={toolCallId:String(t.toolCallId),toolName:t.toolName,args:t.args},m=c?.tool?{...c,tool:{...c.tool,state:"awaiting"}}:{kind:"tool",id:i,text:_r(t.toolName,t.args),tool:{name:P(t.toolName),args:t.args,state:"awaiting"}};return{...n(i,m),approval:a}}case"tool_end":{let i=s(t.toolCallId),c=o(i);if(!c?.tool)return e;let a=t.denied===!0,m=t.isError===!0,u=ua(t.result),f=n(i,{...c,error:m||a,tool:{...c.tool,result:u,state:a?"declined":m?"error":"done",...Ir(u)!==void 0?{exitCode:Ir(u)}:{}}});return e.approval?.toolCallId===String(t.toolCallId)?{...f,approval:null}:f}case"subagent_start":{let i=l(t.toolCallId);return n(i,{kind:"subagent",id:i,title:String(t.agentType),text:String(t.task??""),subagent:{agentType:String(t.agentType),task:String(t.task??""),tools:[],state:"running"}})}case"subagent_tool_start":{let i=l(t.toolCallId),c=o(i);if(!c?.subagent)return e;return n(i,{...c,subagent:{...c.subagent,tools:[...c.subagent.tools,P(t.subToolName)]}})}case"subagent_end":{let i=l(t.toolCallId),c=o(i);if(!c?.subagent)return e;let a=t.isError===!0;return n(i,{...c,error:a,subagent:{...c.subagent,state:a?"error":"done",result:String(t.result??""),...typeof t.durationMs==="number"?{durationMs:t.durationMs}:{}}})}case"error":{let i=t.error;return r({kind:"notice",id:`error:${e.entries.length}`,text:i?.message??"The turn failed.",error:!0})}default:{let i=ma[t.type];if(i!==void 0)return{...e,status:i};let c=ga[t.type]?.(t);return c===null||c===void 0?e:r({kind:"notice",id:`${t.type}:${e.entries.length}`,text:c})}}}function Tr(e){return{kind:"command",id:`cmd:${e.index}`,title:`/${e.name}`,text:e.output,...e.failed?{error:!0}:{}}}import{readdirSync as fa,readFileSync as ha}from"node:fs";import{basename as ya,join as ba}from"node:path";var xa=(e)=>e.split(" ").join("-");function Sa(e,t,n){let r=e.name.split(" "),o=t.trim();if(o)r.push(...o.split(/\s+/));return r.push("--cwd",n),r}var kr="Project prompt";function va(e){let t=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(e);if(!t)return{description:kr,body:e};return{description:/^description:[ \t]*(.+)$/m.exec(t[1]??"")?.[1]?.trim()||kr,body:e.slice(t[0].length).replace(/^(?:[ \t]*\r?\n)+/,"")}}function Ea(e){let t=new Map;for(let n of e){let r;try{r=fa(n)}catch{continue}for(let o of r){if(!o.endsWith(".md"))continue;try{t.set(ya(o,".md"),va(ha(ba(n,o),"utf8")))}catch{continue}}}return t}function wa(e,t){let n=t.trim();if(e.includes("$ARGUMENTS"))return e.split("$ARGUMENTS").join(n);return n?`${e.trimEnd()}
|
|
30
|
+
|
|
31
|
+
${n}`:e}function Ar(e,t){return async(n,r)=>{let o="",s=(i)=>{o+=i},l=await ae([e],Sa(e,n,r),{stdout:s,stderr:s,env:t});return{lines:[],output:o.trimEnd()||`exit ${l}`,...l===0?{}:{failed:!0}}}}var Pe={lines:["This command needs a live session."]};async function Pr(e,t,n,r,o){let s=o.find((m)=>m.name==="config set");if(!s)return{ok:!1,message:`This build has no \`config set\`, so ${e} was not written.`};let l="",i=(m)=>{l+=m},c=await ae([s],["config","set",e,t,"--cwd",n],{stdout:i,stderr:i,env:r}),a=l.trim();if(c===0)return{ok:!0,message:a||`${e} is ${t}.`};return{ok:!1,message:[`${e} was NOT written: ${a.replace(/^error:\s*/,"")||"config set failed."}`,`To set it for every project: \`hlix config set ${e} ${t} --global\`.`].join(`
|
|
32
|
+
`)}}function Or(e={}){let t=e.env??process.env,n=e.shell,r=new Map,o=(a)=>r.set(a.name,a),s=e.commands??ge;for(let a of s)o({name:xa(a.name),description:a.summary,handler:Ar(a,t)});let l=(a,m,u)=>{let f=s.find((y)=>y.name===m);if(f)o({name:a,description:u,handler:Ar(f,t)})};for(let[a,m]of Ea(e.promptFiles??[])){if(r.has(a))continue;o({name:a,description:m.description,prompt:(u)=>wa(m.body,u),handler:()=>({lines:[]})})}l("config","config list","Show this folder's settings and where each came from"),l("secrets","secrets list","List this project's stored secrets, masked"),l("follow","tasks watch","Watch a task the platform is running"),o({name:"model",description:"Pick the model this session runs on",handler:()=>(n?.openModelPicker?.(),{lines:n?.openModelPicker?[]:["No model picker in this mode."]})}),o({name:"sandbox",description:"Where this session's files and commands run",handler:async(a,m)=>{let u=n?.facts;if(!u)return{lines:["Sandbox not resolved."]};let f=a.trim(),y=async(v)=>{let x=await Pr("sandbox",v,m,t,s);return{lines:[],output:[u.sandboxLine,x.ok?`${x.message} This session keeps ${u.sandbox}; restart to run in ${v}.`:x.message].join(`
|
|
33
|
+
`),...x.ok?{}:{failed:!0}}};if(f){if(!Z.includes(f))return{lines:[`/sandbox must name one of ${Z.join(", ")}.`]};return y(f)}if(!n?.openPicker)return{lines:[],output:u.sandboxLine};return n.openPicker({title:"Sandbox",current:u.sandbox,choices:Z.map((v)=>({value:v,label:v,description:_a[v]})),apply:y}),{lines:[]}}}),o({name:"harness",description:"Show or change which coder does the work (`clear` un-pins the project)",handler:async(a,m)=>{let u=n?.facts;if(!u)return{lines:["Harness not resolved."]};let f=u.harnessModesBuilt?n?.session?.mode.get()??u.harness:u.harness,y=async(x)=>{let _=Fe({requested:x,current:f,available:u.availableHarnesses,sandbox:u.sandbox,sandboxLine:u.sandboxLine,modesBuilt:u.harnessModesBuilt});if(_.action==="mode"&&n?.session)await n.session.mode.switch({modeId:_.harness}),n.setFact?.({harness:_.harness,mode:_.harness});if(_.action==="preference"){if(!n?.setProjectHarness)return{lines:["This folder is not bound to a hlix project, so there is no project preference to write. Run `hlix init` or pass --project <id>."]};await n.setProjectHarness(_.harness),n.setFact?.({harness:_.harness})}let M=_.action==="restart"?await Pr("harness",x,m,t,s):null;return{lines:[],output:M?`${_.message}
|
|
34
|
+
${M.message}`:_.message,...M&&!M.ok?{failed:!0}:{}}},v=a.trim();if(v==="clear"){if(!n?.clearProjectHarness)return{lines:["This folder is not bound to a hlix project, so there is no project preference to clear. Run `hlix init` or pass --project <id>."]};let x=await n.clearProjectHarness();if(x)n.setFact?.({harness:x});return{lines:[],output:x?`Project harness preference cleared. Now: ${x}.`:"Project harness preference cleared. Run `/harness` for what runs now."}}if(v)return y(v);if(!n?.openPicker)return{lines:[],output:`harness: ${f}`};return n.openPicker({title:"Harness",current:f,choices:G.map((x)=>({value:x,label:x,description:u.availableHarnesses.includes(x)?x==="hlix"?"Our own coder. The default.":"Installed on this machine.":"Not installed here."})),apply:y}),{lines:[]}}}),o({name:"new",description:"Start a new conversation in this folder",handler:async()=>{if(!n?.session)return Pe;return await n.session.thread.create(),{lines:[]}}}),o({name:"threads",description:"List this project's conversations, newest first",handler:async(a)=>{if(!n?.session)return Pe;let m=a.trim();if(m&&m!=="--all")return{lines:[],output:await Mr(n,m)};let u=Ne(await n.session.thread.list()),f=Ne(await gt(n)),y=n.session.thread.getId();if(u.length===0&&f.length===0)return{lines:[],output:"No conversations here yet."};let v=u.map((x)=>mt(x,y));if(m==="--all")v.push(...Nr(f));else if(f.length>0)v.push(Ca(f.length));return{lines:[],output:v.join(`
|
|
35
|
+
`)}}}),o({name:"resume",description:"Pick an earlier conversation in this project and continue it",handler:async()=>{if(!n?.session)return Pe;let a=Ne(await n.session.thread.list()),m=Ne(await gt(n));if(a.length===0&&m.length===0)return{lines:[],output:"No conversations here yet."};let u=n.session.thread.getId();if(!n.openPicker)return{lines:[],output:[...a.map((f)=>mt(f,u)),...Nr(m)].join(`
|
|
36
|
+
`)};return n.openPicker({title:"Resume",...u?{current:u}:{},choices:[...a.map((f)=>({value:f.id,label:f.title?.trim()||"(untitled)",description:`${f.id} ${ut(f.updatedAt)}`})),...m.map((f)=>({value:f.id,label:f.title?.trim()||"(untitled)",description:`${f.id} ${ut(f.updatedAt)} ${Ia}`}))],apply:async(f)=>({lines:[],output:await Mr(n,f)})}),{lines:[]}}}),o({name:"compact",description:"Condense this conversation into memory now",handler:async()=>{if(!n?.compact)return Pe;return{lines:[],output:await n.compact()}}}),o({name:"log",description:"Show what this session's libraries logged",handler:()=>{if(!n?.log)return{lines:["No log in this mode."]};let a=n.log.tail(200);return{lines:[],output:a.length===0?`Nothing logged this session.
|
|
37
|
+
${n.log.path}`:[...a,"",n.log.path].join(`
|
|
38
|
+
`)}}}),o({name:"rules",description:"Show the user and project rules this session loaded",handler:()=>{if(!n?.rules)return{lines:["Rules not resolved."]};return{lines:[],output:n.rules()}}}),o({name:"yolo",description:"Run without asking for approval — toggles",handler:(a)=>{if(!n?.yolo)return{lines:["Approvals are not resolved in this mode."]};let m=a.trim().toLowerCase(),u=m===""?!n.yolo.get():!["off","false","0","no"].includes(m);return n.yolo.set(u),n.setFact?.({yolo:u}),{lines:[],output:u?"yolo is ON — every tool runs without asking, including writes, commands and hlix calls. /yolo again to turn it off.":"yolo is off. Writes, commands and hlix calls ask again."}}}),o({name:"help",description:"List the commands this terminal knows",handler:()=>({lines:[],output:[...r.values()].map((a)=>`/${a.name.padEnd(22)} ${a.description}`).sort().join(`
|
|
39
|
+
`)})});let i={name:"exit",description:"Leave Hlix Code",handler:()=>({lines:[],quit:!0})};o(i),o({...i,name:"quit"});let c=r.get("standards");if(c&&n?.mcp)o({...c,handler:async(a,m)=>{let u=await c.handler(a,m),f=n.mcp?.()??[];if(f.length===0)return u;return{...u,output:[u.output??"","MCP servers (this session)",...f.map((y)=>` ${y}`)].join(`
|
|
40
|
+
`).trim()}}});return r}var _a={cloud:"The project's own Coding Workspace. Shared with your team.",docker:"A container on this machine, with this folder mounted.",local:"Directly on this machine."};function Ne(e){return[...e].sort((t,n)=>(n.updatedAt?.getTime()??0)-(t.updatedAt?.getTime()??0))}function ut(e,t=new Date){if(!e)return"no activity";let n=Math.floor((t.getTime()-e.getTime())/60000);if(n<1)return"just now";if(n<60)return`${n}m ago`;let r=Math.floor(n/60);if(r<24)return`${r}h ago`;if(r<48)return"yesterday";return e.toISOString().slice(0,10)}var mt=(e,t)=>`${e.id===t?"›":" "} ${(e.title?.trim()||"(untitled)").padEnd(40)} ${ut(e.updatedAt)}`,Ia="· older";function Ra(e,t){return e.filter((n)=>n.resourceId===t.legacyResourceId&&Gt(n.metadata?.projectPath,t.root))}async function gt(e){if(!e.session||!e.memory)return[];return Ra(await e.session.thread.list({allResources:!0}),e.memory)}var Ca=(e)=>`${e} older thread${e===1?"":"s"} from before per-project memory — /threads --all to see them`,Nr=(e)=>e.length===0?[]:["","before per-project memory (resuming one copies it into this project):",...e.map((t)=>mt(t,null))];async function Mr(e,t){let n=e.session;if(!n)return"No session.";try{return await n.thread.switch({threadId:t,emitEvent:!0}),`Resumed ${t}.`}catch(r){let o=await Ta(e,t);if(!o)throw r;return`Resumed ${t} as ${o} — copied into this project's memory.`}}async function Ta(e,t){let n=e.session?.thread,r=e.memory;if(!n?.cloneToCurrentResource||!r)return null;let s=(await gt(e)).find((i)=>i.id===t)?.metadata?.projectPath;if(typeof s!=="string")return null;return(await n.cloneToCurrentResource({threadId:t,expectedResourceId:r.legacyResourceId,expectedProjectPath:s})).id}function Lr(e){if(!e.startsWith("/"))return{kind:"prompt",name:"",args:e};let t=e.slice(1),n=t.indexOf(" ");return n<0?{kind:"slash",name:t,args:""}:{kind:"slash",name:t.slice(0,n),args:t.slice(n+1)}}function jr(e,t){let n=e.args.trimStart(),r=n.indexOf(" "),o=r<0?n:n.slice(0,r);if(o==="")return e;let s=`${e.name}-${o}`;if(!t.has(s))return e;return{kind:e.kind,name:s,args:r<0?"":n.slice(r+1)}}class $r{colors;state=Rr();expanded=new Set;constructor(e){this.colors=e}render(e){return this.state.entries.flatMap((t)=>[...Sr(this.expanded.has(t.id)?{...t,expanded:!0}:t,{width:e,colors:this.colors}),""])}lastCollapsible(){return[...this.state.entries].reverse().find((e)=>e.kind==="tool"||e.kind==="command"||e.kind==="subagent")}invalidate(){}}class Hr{colors;text="";constructor(e){this.colors=e}render(e){return this.text===""?[]:[this.colors.muted(ft(`· ${this.text}`,e))]}invalidate(){}}class Fr{colors;facts=null;constructor(e){this.colors=e}render(e){if(!this.facts)return[];let t=wr(this.facts,e);if(this.facts.yolo!==!0||!t.startsWith(me))return[this.colors.muted(t)];return[`${this.colors.alert(me)}${this.colors.muted(t.slice(me.length))}`]}invalidate(){}}class Ur{header=()=>[];body=null;open(e,t){this.header=e,this.body=t}close(){this.header=()=>[],this.body=null}render(e){if(!this.body)return[];return[...this.header(e),...this.body.render(e),""]}handleInput(e){this.body?.handleInput?.(e)}invalidate(){this.body?.invalidate()}}async function Br(e){let t=Te(Ce(e.env)),n=e.tui??new Na(new Aa),r=new $r(t),o=new Hr(t),s=new Ur,l=new Fr(t),i={...e.facts};l.facts=i;let c=0,a=()=>n.requestRender(),m=(g)=>{r.state={...r.state,entries:[...r.state.entries,g]},a()},u=(g)=>{m({kind:"notice",id:`warn:${c++}`,text:g,error:!0})},f=(g)=>{m({kind:"notice",id:`say:${c++}`,text:g})},y=(g,b)=>{for(let S of b.lines)u(S);if(b.output===void 0)return;m(Tr({name:g,output:b.output,index:c++,...b.failed?{failed:!0}:{}}))},v=new ka(n,pr(t)),x=()=>{s.close(),n.setFocus(v),n.requestRender()},_=(g)=>{let{content:b,files:S,notes:E}=Nn(g,e.cwd);m({kind:"user",id:`you:${c++}`,text:g});for(let C of E)u(C);e.session.sendMessage({content:b,...S.length>0?{files:S}:{}}).catch((C)=>{u(C instanceof Error?C.message:String(C))})},M=(g)=>{let b=g.choices.map((E)=>({value:E.value,label:E.value===g.current?`${E.label} (current)`:E.label,...E.description?{description:E.description}:{}})),S=new Dr(b,Math.min(b.length,8),ie(t));S.onSelect=(E)=>{x(),Promise.resolve(g.apply(E.value)).then((C)=>y(g.title.toLowerCase(),C)).catch((C)=>{u(`${g.title}: ${C instanceof Error?C.message:String(C)}`)})},S.onCancel=x,s.open((E)=>[t.brand(ft(g.title,E))],S),n.setFocus(s),n.requestRender()},V=(g,b)=>{let S=e.commands.get(g);if(!S){u(`Unknown command /${g}. Try /help.`);return}if(S.prompt){_(S.prompt(b));return}Promise.resolve(S.handler(b,e.cwd)).then((E)=>{if(y(g,E),E.quit)n.stop()}).catch((E)=>{u(`/${g} failed: ${E instanceof Error?E.message:String(E)}`)})},j=()=>{if(e.models.length===0){u("No models to choose from. Run `hlix auth login`.");return}fr({tui:n,entries:e.models,...i.model?{current:i.model}:{},colors:t,onPick:(g)=>{(async()=>{try{await e.session.model.switch({modelId:g.id});let b=gr({modelId:g.id,cwd:e.cwd,env:e.env});i.model=g.label,e.onModelPicked?.(g),f(`Model is ${g.label} — written to ${b}.`)}catch(b){u(`Could not switch model: ${b instanceof Error?b.message:String(b)}`)}})()},onCancel:()=>n.setFocus(v)})},F=(g,b,S)=>{e.session.respondToToolApproval({decision:b,toolCallId:g,...S?{declineContext:{reason:S}}:{}})},U=(g)=>{if(e.yolo?.get()){F(g.toolCallId,"approve");return}let b=pn(g.toolName),S=new Dr(b.map((E)=>({value:E.value,label:E.label,description:E.description})),b.length,ie(t));S.onSelect=(E)=>{if(E.value!=="decline"){x(),F(g.toolCallId,E.value);return}let C=new Pa({prompt:"why not? (enter to skip) ",placeholder:"reason"}),I=(w)=>{x(),F(g.toolCallId,"decline",w.trim())};C.onSubmit=I,C.onEscape=()=>I(""),s.open(()=>[],C),n.setFocus(s),n.requestRender()},S.onCancel=()=>{x(),F(g.toolCallId,"decline","The user dismissed the approval prompt.")},s.open((E)=>Er({toolCallId:g.toolCallId,toolName:g.toolName,args:g.args},{width:E,colors:t}),S),n.setFocus(s),n.requestRender()};e.session.subscribe((g)=>{if(g.type==="tool_approval_required")U(g);if(g.type==="mode_changed")i.mode=g.modeId;if(g.type==="usage_update"){let S=ke(g.usage);if(i.context={used:g.usage.totalTokens,total:i.context?.total??0},S!==void 0)i.costUsd=S}let b=Cr(r.state,g);if(b!==r.state)r.state=b;o.text=r.state.status,a()});let k=Pn({tui:n,editor:v,commands:e.commands,basePath:e.cwd,handlers:{onSubmit:(g)=>{let b=Lr(g);if(b.kind==="slash"){let S=jr(b,e.commands);V(S.name,S.args);return}_(g)},onCycleMode:()=>{let g=bn(e.session.mode.get());e.session.mode.switch({modeId:g}).catch(()=>{u("This session's harness has no build/plan modes. Try /harness.")})},onAbort:()=>{if(!r.state.busy)return;e.session.abort(),f("Aborted.")},onExpand:()=>{let g=r.lastCollapsible();if(!g)return;if(r.expanded.has(g.id))r.expanded.delete(g.id);else r.expanded.add(g.id);n.requestRender()},onInterruptWarning:()=>f(Ze),onExit:()=>n.stop()}});for(let g of e.notices??[])f(g);if(n.addChild(new class{render(g){return[t.brand(ft(`◆ ${N}`,g)),""]}invalidate(){}}),n.addChild(r),n.addChild(o),n.addChild(s),n.addChild(v),n.addChild(l),n.setFocus(v),a(),e.commands.set("model",{name:"model",description:"Pick the model this session runs on",handler:()=>(j(),{lines:[]})}),e.bindings)e.bindings.openPicker=M,e.bindings.openModelPicker=j,e.bindings.setFact=(g)=>{if(g.harness!==void 0)i.harness=g.harness;if(g.mode!==void 0)i.mode=g.mode;if(g.yolo!==void 0)i.yolo=g.yolo;a()};await new Promise((g)=>{let b=n.stop.bind(n);n.stop=(S)=>{k(),b(S),g()},n.start()})}var Ma=new Set(["display_state_changed","tool_input_start","tool_input_delta","tool_input_end","om_status"]),Oa=(e)=>!Ma.has(e);function La(e){let t={type:e.type};switch(e.type){case"message_start":case"message_update":case"message_end":t.role=e.message.role,t.text=Ae(e.message);break;case"tool_start":case"tool_approval_required":t.tool=e.toolName,t.toolCallId=e.toolCallId;break;case"tool_end":if(t.toolCallId=e.toolCallId,t.isError=e.isError,e.denied===!0)t.denied=!0;break;case"usage_update":{t.totalTokens=e.usage.totalTokens;let n=ke(e.usage);if(n!==void 0)t.costUsd=n;break}case"subagent_start":t.agentType=e.agentType,t.task=e.task;break;case"subagent_end":t.agentType=e.agentType,t.isError=e.isError,t.durationMs=e.durationMs;break;case"agent_end":t.reason=e.reason??"complete";break;case"error":t.message=e.error?.message??String(e.error);break;default:break}return JSON.stringify(t)}async function Gr(e){let t=e.write??((i)=>process.stdout.write(i)),n=e.writeError??((i)=>process.stderr.write(i)),r="",o=null,s="complete";await new Promise((i)=>{let c=e.session.subscribe((a)=>{if(e.json&&Oa(a.type))t(`${La(a)}
|
|
41
|
+
`);if(a.type==="tool_approval_required"){let m=dn({toolName:a.toolName,yolo:e.yolo===!0});e.session.respondToToolApproval({decision:m.decision,toolCallId:a.toolCallId,...m.reason?{declineContext:{reason:m.reason}}:{}});return}if(a.type==="message_end"){if(a.message.role!=="user")r=Ae(a.message);return}if(a.type==="error"){o=a.error?.message??String(a.error);return}if(a.type==="agent_end")s=a.reason??"complete",c(),i()});e.session.sendMessage({content:e.prompt}).catch((a)=>{o=a instanceof Error?a.message:String(a),c(),i()})});let l=s==="complete"&&o===null;if(!e.json){if(r)t(`${r}
|
|
42
|
+
`);if(o)n(`${o}
|
|
43
|
+
`);else if(!l)n(`the turn ended ${s}
|
|
44
|
+
`)}return{text:r,exitCode:l?0:1}}import{appendFileSync as ja,mkdirSync as Da}from"node:fs";import{homedir as $a}from"node:os";import{dirname as Ha,join as Wr}from"node:path";var Fa=["log","info","warn","error","debug","trace"];function Ua(e=process.env){let t=e.HLIX_CONFIG_HOME??Wr(e.HOME??$a(),".hlix");return Wr(t,"code","hlix-code.log")}var Ba={log:"notes",info:"notes",debug:"notes",trace:"notes",warn:"warnings",error:"errors"};function Ga(e){if(typeof e==="string")return e;if(e instanceof Error)return e.stack??e.message;try{return JSON.stringify(e)}catch{return String(e)}}function ht(e=process.env,t=console){let n=Ua(e),r=new Set,o=[],s={notes:0,warnings:0,errors:0},l=new Map,i=(a,m)=>{let u=`${new Date().toISOString()} ${a} ${m}`;o.push(u);try{Da(Ha(n),{recursive:!0}),ja(n,`${u}
|
|
45
|
+
`,"utf8")}catch{}};for(let a of Fa)l.set(a,t[a]),t[a]=(...m)=>{let u=m.map(Ga).join(" ");if(r.has(`${a}:${u}`))return;r.add(`${a}:${u}`),s[Ba[a]]+=1,i(a,u)};let c=!1;return{path:n,counts:s,note:(a)=>i("hlix",a),tail:(a)=>o.slice(Math.max(0,o.length-a)),restore:()=>{if(c)return;c=!0;for(let[a,m]of l)t[a]=m}}}function Yr(e){let t=[];if(e.counts.errors>0)t.push(`${e.counts.errors} error${e.counts.errors===1?"":"s"}`);if(e.counts.warnings>0)t.push(`${e.counts.warnings} warning${e.counts.warnings===1?"":"s"}`);if(e.counts.notes>0)t.push(`${e.counts.notes} note${e.counts.notes===1?"":"s"}`);if(t.length===0)return"";return`log: ${t.join(" · ")} from this session's libraries — /log to read them`}import{MCPClient as Wa}from"@mastra/mcp";var yt={tools:{},statusLines:[],summary:"",connected:[],failed:[],stop:async()=>{}};function Ya(e,t){let n={},r=[];for(let o of e){if("command"in o.config){n[o.name]={command:o.config.command,...o.config.args?{args:o.config.args}:{},...o.config.env?{env:o.config.env}:{},stderr:"ignore",cwd:t};continue}try{n[o.name]={url:new URL(o.config.url),...o.config.headers?{requestInit:{headers:o.config.headers}}:{}}}catch{r.push({name:o.name,reason:"not a valid url"})}}return{servers:n,skipped:r}}function Ka(e,t){let n={};for(let r of t)n[r]=0;for(let r of e){let o=t.filter((s)=>r.startsWith(`${s}_`)).sort((s,l)=>l.length-s.length)[0];if(o)n[o]=(n[o]??0)+1}return n}var Oe=(e,t)=>`${e} ${t}${e===1?"":"s"}`;async function bt(e){if(e.servers.length===0)return yt;let{servers:t,skipped:n}=Ya(e.servers,e.cwd),r=Object.keys(t),o=e.timeoutMs??20000,s=[...n];if(r.length===0)return Me({failed:s});let l;try{l=(e.client??((y)=>new Wa(y)))({id:`hlix-code:${e.cwd}`,servers:t,timeout:o})}catch(f){for(let y of r)s.push({name:y,reason:Kr(f)});return Me({failed:s})}let i={},c={};try{let f=await l.listToolsWithErrors({perServerTimeoutMs:o});i=f.tools,c=f.errors}catch(f){for(let y of r)s.push({name:y,reason:Kr(f)});return await l.disconnect().catch(()=>{}),Me({failed:s})}for(let[f,y]of Object.entries(c))s.push({name:f,reason:y});let a=Ka(Object.keys(i),r),m=r.filter((f)=>!(f in c)).map((f)=>({name:f,tools:a[f]??0})),u=!1;return Me({tools:i,connected:m,failed:s,stop:async()=>{if(u)return;u=!0,await l.disconnect().catch(()=>{})}})}function Me(e){let t=e.connected??[],n=e.failed??[],r=e.tools??{},o=t.length===0?n.length>0?`mcp: ${Oe(n.length,"server")} unreachable`:"":`mcp: ${Oe(t.length,"server")} · ${Oe(t.reduce((s,l)=>s+l.tools,0),"tool")}${n.length>0?` · ${n.length} unreachable`:""}`;return{tools:r,connected:t,failed:n,summary:o,statusLines:Va(t,n),stop:e.stop??(async()=>{})}}var Kr=(e)=>e instanceof Error?e.message:String(e);function Va(e,t){return[...e.map((n)=>`✓ ${n.name} — ${Oe(n.tools,"tool")}`),...t.map((n)=>`✗ ${n.name} — ${n.reason}`)]}var Ja="run `hlix auth login`",Za=["You are running inside Hlix Code, the terminal shell for the hlix control plane.","Every `hlix` CLI command is available to you as a tool named `hlix_<command>`,","with spaces replaced by underscores — `hlix_status`, `hlix_tasks_list`, `hlix_push`.","Use those tools instead of running `hlix` through the shell: they resolve the","folder's workspace binding and credential the same way the CLI does, and they","return the CLI's machine-readable output.","Report a non-zero exit code and its stderr to the user verbatim. Never invent a","project, task or workspace id — read one with a tool first.","","Do not create, write or modify any file the user's request did not ask for.","You do not need to probe whether you can write: if a write is refused you will","be told, with a reason. A scratch file nobody asked for is a change the user has","to notice and undo.","","This project's secrets live in the hlix secrets store, not in a file in this","folder: `hlix_secrets_list` shows them keyed by (key, source file) with every","value masked, and `hlix_secrets_set` changes one. When the user asks for a",'local env file, call `hlix_secrets_export` with `{ flags: { out: ".env" } }` —',"it writes the rendered file at mode 0600 and refuses a path git tracks. Do not","repeat an exported secret value back into the conversation."].join(`
|
|
46
|
+
`);function Qa(e){if(!e||e.entries.length===0)return"";let t=e.entries.length,n=new Set(e.entries.map((r)=>r.source)).size;return`secrets: ${t} ${t===1?"entry":"entries"} (${n} ${n===1?"source":"sources"})`}async function el(e,t){try{return await O(process.env,{cwd:e,flags:{}}).secrets.listEntries(t)}catch{return null}}function tl(e){let{values:t,positionals:n}=Xa({args:e,allowPositionals:!0,strict:!1,options:{local:{type:"boolean"},sandbox:{type:"string"},"docker-image":{type:"string"},harness:{type:"string"},project:{type:"string"},cwd:{type:"string"},print:{type:"string",short:"p"},json:{type:"boolean"},yolo:{type:"boolean"},"allow-writes":{type:"boolean"}}}),r=typeof t.sandbox==="string"?t.sandbox:t.local===!0?"local":void 0,o=typeof t.print==="string"?t.print:void 0,s=o===void 0?void 0:[o,...n].filter((l)=>l!=="").join(" ");return{...r?{sandbox:r,sandboxSource:"flag"}:{},...typeof t["docker-image"]==="string"?{dockerImage:t["docker-image"]}:{},...typeof t.harness==="string"?{harness:t.harness}:{},...typeof t.project==="string"?{project:t.project}:{},...s!==void 0?{print:s}:{},...t.json===!0?{json:!0}:{},...t.yolo===!0||t["allow-writes"]===!0?{yolo:!0}:{},cwd:za(typeof t.cwd==="string"?t.cwd:".")}}function nl(e){let t=Object.keys(ne),r=e.sandbox==="cloud"?t:t.filter((c)=>e.installed(c)),o=["hlix",...r],s=t.filter((c)=>!r.includes(c)),l=e.requested.harness;if(l==="hlix"||r.includes(l))return{harness:e.requested,available:o,unavailable:s,refusal:null,warning:null};let i=He(ne[l]);if(e.requested.source==="flag")return{harness:e.requested,available:o,unavailable:s,refusal:i,warning:null};return{harness:{harness:"hlix",source:"default"},available:o,unavailable:s,refusal:null,warning:`${i} Falling back to harness hlix.`}}async function qr(e,t){try{let r=await O(process.env,{cwd:e,flags:{}}).modelConfig.resolvedProjectHarness(t);return{harness:r.harness,source:r.source}}catch{return null}}async function rl(e,t){let n=t.skills&&t.skills.length>0?{skills:t.skills}:{};if(e.choice!=="cloud")return Ye(e,{cwd:t.cwd,...n});if(!t.projectId)throw new K("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");let o=O(process.env,{cwd:t.cwd,flags:{}}).projects.workspace(t.projectId);return Ye(e,{cwd:t.cwd,projectId:t.projectId,remote:o})}var xt=".hlix";function ol(e,t,n=(r)=>{try{return qa(r)}catch{return r}}){let r=new Set,o=[];for(let s of e.skills){if(s.scope!=="project")continue;let l=io(t,s.path);if(l===""||l.startsWith(".."))continue;let i=n(s.path);if(r.has(i))continue;r.add(i),o.push(l)}return o}function sl(e,t){let n=[];if(e.global)n.push(["# Your user's own rules","","Written by the person you are working with, for every project they open.","Follow them unless this project's rules below say otherwise.","",e.global.content].join(`
|
|
47
|
+
`));if(e.project)n.push([`# This project's rules (${io(t,e.project.path)||e.project.path})`,"","Written for whichever coding agent opens this repository. They are the","project's own rules and they take precedence over the user rules above.","",e.project.content].join(`
|
|
48
|
+
`));return n.join(`
|
|
49
|
+
|
|
50
|
+
`)}var il={boot:Cn,app:Br,headless:Gr,mcp:bt,log:ht,stdio:{get stdinIsTty(){return process.stdin.isTTY===!0},get stdoutIsTty(){return process.stdout.isTTY===!0}}};function al(e){if(e.flag===!0)return!0;return Xr(e.configured)===!0}function ll(e){if(e.print)return null;if(e.stdinIsTty&&e.stdoutIsTty)return null;return`${N} needs a terminal. Run \`hlix -p "<prompt>"\` for one turn without a screen, or start \`hlix\` in a terminal.`}function cl(e,t){let n=e?.mode?.get;if(typeof n!=="function")return t;let r=n.call(e.mode);return typeof r==="string"&&r!==""?r:t}async function hg(e,t=il){let n=tl(e),r=ll({print:n.print!==void 0,stdinIsTty:t.stdio?.stdinIsTty??!0,stdoutIsTty:t.stdio?.stdoutIsTty??!0});if(r)return process.stderr.write(`error: ${r}
|
|
51
|
+
`),2;let o=zr(n.cwd,process.env),s=n.project??o.merged.projectId,l=n.print===void 0?(t.log??ht)(process.env):null,i=no(n.cwd,Jr(process.env),{configDir:xt}),c=Qr({cwd:n.cwd,configDir:xt,env:process.env}),a=new Ge({root:n.cwd,already:[c.project?.path,c.global?.path].filter((w)=>w!==void 0)}),m=new Ve(al({...n.yolo!==void 0?{flag:n.yolo}:{},...o.merged.yolo!==void 0?{configured:o.merged.yolo}:{}})),u,f,y;try{if(f=on({flag:n.sandbox??o.merged.sandbox,flagSource:n.sandbox?"flag":"config",projectId:s,dockerImage:n.dockerImage??o.merged.dockerImage,dockerAvailable:()=>an()}),y=nl({requested:wt({...n.harness?{flag:n.harness}:{},...o.merged.harness?{configured:o.merged.harness}:{},...o.sources.harness?{configSource:o.sources.harness}:{}}),sandbox:f.choice,installed:(w)=>_t(ne[w].command)}),y.refusal)throw new K("invalid_usage",y.refusal);u=await rl(f,{cwd:n.cwd,projectId:s,...f.choice==="cloud"?{}:{skills:ol(i,n.cwd)}})}catch(w){return l?.restore(),process.stderr.write(`error: ${w instanceof Error?w.message:String(w)}
|
|
52
|
+
`),2}if(y.warning)process.stderr.write(`warning: ${y.warning}
|
|
53
|
+
`);if(f.choice==="cloud"){let w=s?await qr(n.cwd,s):null;if(w&&n.harness&&n.harness!==w.harness)process.stderr.write(`warning: this project runs ${w.harness}. Run \`/harness ${n.harness}\` to make ${n.harness} the project's setting.
|
|
54
|
+
`);y={...y,harness:w??{harness:"unknown",source:s?"the project's setting could not be read":"no project bound"}}}let v=await Dt({cwd:n.cwd,env:process.env}),x=jt({cwd:n.cwd,env:process.env,...v.served?{models:v.served.map((w)=>w.id)}:{}}),_=$t({endpoint:x,cloud:f.choice==="cloud",...o.merged.model?{configured:o.merged.model}:{},...o.sources.model?{configuredSource:o.sources.model}:{}});if(_?.notice)process.stderr.write(`warning: ${_.notice}
|
|
55
|
+
`);if(!x)return l?.restore(),process.stderr.write(`error: no hlix credential for this folder — ${Ja}.
|
|
56
|
+
`),2;let M=ye(xe(o.merged.memoryTokens)??he),V=sn(f),j=so(i),F=eo(c,n.cwd),U=s?Qa(await el(n.cwd,s)):"",k=n.print===void 0?await(t.mcp??bt)({servers:i.mcpServers,cwd:n.cwd}):yt,g=ro(i.generatedCommands,n.cwd),b=oo(i.instructions,n.cwd),S=sl(c,n.cwd),E=[...Zr.flatMap((w)=>[Vr(n.cwd,".claude",w),Vr(n.cwd,xt,w)]),...i.commands.map((w)=>w.path),...g?[g]:[]],C=y.harness.harness==="unknown"?"hlix":y.harness.harness,I;try{I=await t.boot({cwd:n.cwd,env:process.env,sandbox:f.choice,workspace:u,endpoint:x,...s?{projectId:s}:{},model:_,harness:C,harnessFromFlag:y.harness.source==="flag",unavailableHarnesses:y.unavailable,...o.global?.providers?{providers:o.global.providers}:{},...o.merged.memoryTokens?{memoryTokens:o.merged.memoryTokens}:{},hostInstructions:[Za,...f.choice==="cloud"?[It(y.harness.harness)]:[],...S?[S]:[],...b?[b]:[]].join(`
|
|
57
|
+
|
|
58
|
+
`),mcpTools:k.tools,projectSubagents:i.subagents,nestedRules:a,extraTools:{...kt({cwd:n.cwd}),hlix_tasks_follow:Pt({cwd:n.cwd}),hlix_harness:Tt({sandbox:f.choice,sandboxLine:V,available:y.available,modesBuilt:!1,session:()=>null})}})}catch(w){if(l?.restore(),await k.stop(),w instanceof Se)return process.stderr.write(`error: ${w.message}
|
|
59
|
+
`),2;return process.stderr.write(`error: ${N} could not start: ${w instanceof Error?w.message:String(w)}
|
|
60
|
+
`),2}try{if(n.print!==void 0)return(await t.headless({session:I.session,prompt:n.print,...n.json?{json:!0}:{},...m.get()?{yolo:!0}:{}})).exitCode;let w={session:I.session,compact:async()=>{let B=I.session.thread.getId();if(!B)return"Nothing to condense yet.";let te=await I.memory.omEngine;if(!te)return"Observational memory is not running in this session.";return(await te.observe({threadId:B,resourceId:I.scope.resourceId})).observed?"Condensed.":"Nothing new to condense."},facts:{sandbox:f.choice,sandboxLine:V,harness:String(y.harness.harness),availableHarnesses:y.available,harnessModesBuilt:I.harnessModesBuilt},memory:{legacyResourceId:I.scope.legacyResourceId,root:I.scope.root},...l?{log:{path:l.path,tail:l.tail}}:{},rules:()=>to(c,n.cwd,process.env,a.loaded()),mcp:()=>k.statusLines,yolo:{get:()=>m.get(),set:(B)=>m.set(B)},...s?{setProjectHarness:async(B)=>{await O(process.env,{cwd:n.cwd,flags:{}}).modelConfig.setProjectHarness(s,B)},clearProjectHarness:async()=>{await O(process.env,{cwd:n.cwd,flags:{}}).modelConfig.clearProjectHarness(s);let te=await qr(n.cwd,s);return te?De(te):null}}:{}},ao=Or({env:process.env,promptFiles:E,shell:w}),St=lt({...v.served?{served:v.served}:{},userModelIds:I.gateway.modelIds(),providerName:x.name});return await t.app({session:I.session,cwd:n.cwd,env:process.env,commands:ao,models:St,bindings:w,yolo:m,notices:dl({rules:F,standards:j,memory:Wt(I.scope,(await I.session.thread.list().catch(()=>[])).length),secrets:U,mcp:k.summary,subagents:I.subagentLine,subagentsSkipped:I.subagentsSkipped,log:l?Yr(l):""}),facts:{sandbox:V.replace(/^sandbox: /,""),harness:De(y.harness),mode:cl(I.session,Q),..._?{model:pl(_,St)}:{},workspace:x.workspaceId,context:{used:0,total:0},memory:Yt("",M).replace(/^ · /,""),...m.get()?{yolo:!0}:{},...v.warning?{warning:v.warning}:{}}}),0}finally{await k.stop(),await I.dispose(),l?.restore()}}function dl(e){return[e.rules,e.standards,e.memory,e.mcp,e.subagents,...e.subagentsSkipped.map((t)=>`subagent not loaded: ${t}`),e.secrets,e.log].filter((t)=>t!=="")}function pl(e,t){return t.find((n)=>n.id===e.id)?.label??e.id}export{cl as currentMode,tl as parseHlixCodeArgs,nl as planHarness,al as resolveYolo,sl as rulesBlock,hg as runHlixCode,Qa as secretsStatusLine,dl as startupNotices,ll as terminalRequirement,ol as workspaceSkillPaths};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import"./index-f303pf32.js";var s="@hlix/cli",i="0.5.
|
|
2
|
+
import"./index-f303pf32.js";var s="@hlix/cli",i="0.5.3",n="SEE LICENSE IN LICENSE",a="Hlix Code and the hlix control-plane CLI.",r=["hlix","cli","agents"],l="https://hlix.ai",p="module",d="./dist/index.js",o={hlix:"./dist/index.js"},c=["dist","skills","LICENSE","THIRD_PARTY_NOTICES"],u={node:">=22.19.0"},b={access:"public"},m={build:"rm -rf dist && bun build src/index.ts --outdir dist --target node --format esm --splitting --packages external --minify --banner '#!/usr/bin/env node'",test:'bun test --isolate src --path-ignore-patterns "**/*.integration.test.ts" --timeout 20000',typecheck:"tsc --noEmit",prepublishOnly:"bun run typecheck && bun run build && bun run test","test:integration":"NODE_ENV=test bun run ../../apps/backend/scripts/with-aimock.ts -- bun run ../../apps/backend/scripts/with-test-db.ts -- bun test --isolate --preload ../../apps/backend/test/helpers/pool-lifecycle.ts --timeout 60000 .integration.test.ts"},h={"@earendil-works/pi-tui":"0.85.1","@mastra/acp":"^0.4.1","@mastra/core":"1.66.0","@mastra/docker":"^0.7.0","@mastra/libsql":"1.22.5","@mastra/mcp":"1.17.3","@mastra/memory":"1.29.0",ignore:"7.0.8","openapi-fetch":"^0.17.0",zod:"4.5.4"},g={"@hlix/sdk":"^0.2.0","@hlix/shared":"*","@types/bun":"latest",typescript:"^7.0.2"},k={name:s,version:i,license:n,description:a,keywords:r,homepage:l,type:p,main:d,bin:o,files:c,engines:u,publishConfig:b,scripts:m,dependencies:h,devDependencies:g};export{o as bin,k as default,h as dependencies,a as description,g as devDependencies,u as engines,c as files,l as homepage,r as keywords,n as license,d as main,s as name,b as publishConfig,m as scripts,p as type,i as version};
|
package/package.json
CHANGED
package/skills/hlix/SKILL.md
CHANGED
|
@@ -158,6 +158,7 @@ hlix cycles create <project-id> --title <t> --description <d> [--json]
|
|
|
158
158
|
hlix tasks create <project-id> --description <d> [--title <t>] [--json]
|
|
159
159
|
hlix harness get [project-id] [--json]
|
|
160
160
|
hlix harness set <hlix|claude-code|codex|cursor-agent> [project-id] [--org] [--json]
|
|
161
|
+
hlix harness clear [project-id] [--org] [--json]
|
|
161
162
|
```
|
|
162
163
|
|
|
163
164
|
`cycles create` is the command that STARTS work. The proposal enters the
|
|
@@ -171,10 +172,12 @@ the roadmap owns cycles — so find the resulting tasks with `hlix tasks list
|
|
|
171
172
|
execution is not implemented server-side and answers `501` by design, so there
|
|
172
173
|
is no flag here that would call it.
|
|
173
174
|
|
|
174
|
-
`harness get`/`harness set` are the coder the PLATFORM runs,
|
|
175
|
-
server and audited: a project preference with a project id, the
|
|
176
|
-
one with `--org`.
|
|
177
|
-
|
|
175
|
+
`harness get`/`harness set`/`harness clear` are the coder the PLATFORM runs,
|
|
176
|
+
stored on the server and audited: a project preference with a project id, the
|
|
177
|
+
workspace-wide one with `--org`. `harness clear` removes that scope's
|
|
178
|
+
preference so the one below it decides again, and answers `not_found` when
|
|
179
|
+
there was nothing set. That is a different setting from the local `harness`
|
|
180
|
+
config key, which only picks the coder Hlix Code spawns on this machine.
|
|
178
181
|
|
|
179
182
|
## Commands
|
|
180
183
|
|
|
@@ -220,7 +223,12 @@ Hlix collects every project-local dotenv and credential file. It applies the
|
|
|
220
223
|
standard development dotenv precedence automatically and preserves every other
|
|
221
224
|
profile encrypted; `--env-file` is an explicit override.
|
|
222
225
|
The default history policy aborts on possible historical secrets. Explicit
|
|
223
|
-
`--history preserve` keeps the full Git history after showing the risk.
|
|
226
|
+
`--history preserve` keeps the full Git history after showing the risk. An
|
|
227
|
+
example file (`.env.example` and its family) is never a finding, and a registry
|
|
228
|
+
config such as `.npmrc` is one only when the committed blob held a real value
|
|
229
|
+
rather than a `${VAR}` placeholder. A pattern matched inside a test, fixture or
|
|
230
|
+
snapshot file is listed as a warning and does not block, so `--history preserve`
|
|
231
|
+
is not the answer to it.
|
|
224
232
|
Current environment values are sent only in the authenticated finalization
|
|
225
233
|
request and stored encrypted; they are never placed in the Git bundle.
|
|
226
234
|
|