@hlix/cli 0.4.5 → 0.5.0
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 +112 -3
- package/THIRD_PARTY_NOTICES +6609 -39
- package/dist/{index-y1n35st0.js → index-11raxarr.js} +1 -1
- package/dist/index-gf6sghpv.js +202 -0
- package/dist/index.js +4 -4
- package/dist/main-90ythqvy.js +58 -0
- package/dist/package-rzs58669.js +2 -0
- package/package.json +6 -3
- package/skills/hlix/SKILL.md +43 -3
- package/dist/harness-settings-9xpgt0fb.js +0 -2
- package/dist/index-benazc7g.js +0 -158
- package/dist/index-rraz48fm.js +0 -29
- package/dist/main-4pat9308.js +0 -26
- package/dist/package-bkxredkn.js +0 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{a as Z,c as Yn,d as je,e as j,f as re,g as fe,h as V,i as U,j as Oe,k as kr,l as Ar,m as Kn,n as Rr,o as Pr,p as Nr,q as Or,r as Mr,s as Lr,t as jr,u as Dr,v as $r,w as pe}from"./index-gf6sghpv.js";import"./index-11raxarr.js";import{realpathSync as Wi}from"node:fs";import{join as Tr,relative as Hr,resolve as Yi}from"node:path";import{parseArgs as Ki}from"node:util";import{execFileSync as Ur}from"node:child_process";import{createACPTool as Fr}from"@mastra/acp";import{createTool as Br}from"@mastra/core/tools";import{z as W}from"zod";var X={"claude-code":{harness:"claude-code",label:"Claude Code",command:"claude-agent-acp",args:[],authEnvVars:["ANTHROPIC_API_KEY"],install:"npm i -g @agentclientprotocol/claude-agent-acp"},codex:{harness:"codex",label:"Codex",command:"codex-acp",args:[],authEnvVars:["OPENAI_API_KEY"],env:{NO_BROWSER:"1"},install:"npm i -g @agentclientprotocol/codex-acp"},"cursor-agent":{harness:"cursor-agent",label:"Cursor Agent",command:"cursor-agent",args:["acp"],authEnvVars:["CURSOR_API_KEY"],install:"curl https://cursor.com/install -fsS | bash"}};function pt(e){if(e.flag)return{harness:Gr(e.flag,"--harness"),source:"flag"};if(e.configured)return{harness:e.configured,source:e.configSource??"project"};return{harness:Oe,source:"default"}}function Gr(e,t){if(U.includes(e))return e;throw Error(`${t} must be one of ${U.join(", ")}; got "${e}".`)}var Ne="hlix_tasks_follow",Wr=(e)=>`hlix_coder_${e.split("-").join("_")}`;function ut(e){if(e.source==="default")return String(e.harness);let t=e.source==="flag"?"--harness":e.source;return`${e.harness} (${t})`}function mt(e,t=3000){try{return Ur("which",[e],{timeout:t,stdio:"ignore"}),!0}catch{return!1}}var Me=(e)=>`harness ${e.harness} needs \`${e.command}\` on PATH. Install it with: ${e.install}`;function Yr(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 dt=["ask_user","task_write","task_update","task_complete","task_check"],Kr=(e)=>[`harness ${e} runs in the project's Coding Workspace, not on this machine.`,"This session can follow and stream that work, but cannot start it:","which coder the platform uses comes from the project's harness preference,","and this CLI has no command that creates a task."].join(" "),gt=(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. \`${Ne}\` 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
|
+
`),Vr=(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 ft(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(X)){let s=e.active===o.harness,l=Wr(o.harness);r.push({id:o.harness,name:o.label,description:`${o.label} runs on this machine over ACP and edits ${e.cwd}.`,instructions:Vr(o,l),availableTools:t.has(o.harness)?[...e.readTools,...dt,Ne]:[l,...e.readTools,...dt,Ne],...t.has(o.harness)?{}:{additionalTools:{[l]:Fr({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)=>Yr(i)})}},...n,...s?{metadata:{default:!0}}:{}})}return r}function Le(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(!U.includes(e.requested))return n(`/harness must name one of ${U.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}. ${Kr(r)}`}}if(!t.includes(r))return n(Me(X[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 ht(e){return Br({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:W.object({harness:W.string().optional().describe(`One of ${U.join(", ")}. Omit to report the current one.`)}),outputSchema:W.object({harness:W.string(),available:W.array(W.string()),message:W.string()}),execute:async(t)=>{let n=e.session(),r=Le({...t.harness?{requested:t.harness}:{},current:n?.mode.get()??Oe,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 qr}from"@mastra/core/tools";import{z as A}from"zod";var zr=(e)=>`hlix_${e.split(" ").join("_")}`,Xr=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" }.')}),Jr=A.object({exitCode:A.number(),stdout:A.string(),stderr:A.string()});function Zr(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 Qr(e,t,n,r=process.env){let o="",s="";return{exitCode:await re([e],Zr(e,t,n),{stdout:(i)=>{o+=i},stderr:(i)=>{s+=i},env:r}),stdout:o,stderr:s}}function yt(e){let t={};for(let n of e.commands??pe){let r=zr(n.name);t[r]=qr({id:r,description:`${n.summary}
|
|
5
|
+
|
|
6
|
+
${n.usage}`,inputSchema:Xr,outputSchema:Jr,execute:async(o)=>Qr(n,o,e.cwd,e.env)})}return t}import{createTool as eo}from"@mastra/core/tools";async function bt(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 F}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:no(e.output)};case"error":return{event:"finish",isError:!0,result:e.message};case"done":return{event:"finish",isError:!1};default:return null}}function no(e){return typeof e==="object"&&e!==null&&e.status==="failed"}async function ro(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 xt(e){return eo({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:F.object({taskId:F.string().describe("The task to follow.")}),outputSchema:F.object({status:F.enum(["streamed","idle","error","unassigned"]),text:F.string(),tools:F.array(F.string()),message:F.string()}),execute:async(t,n)=>{let r=j(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 ro(r.projects.observeAgent(o.projectId,o.agentId),(s)=>bt(n,s))}})}import{Memory as io}from"@mastra/memory";var B="hlix",Y="default",oe=(e)=>`${B}/${e}`,St=(e)=>e.startsWith(`${B}/`)&&e.length>B.length+1;function oo(e){return{name:B,url:`${e.baseUrl.replace(/\/+$/,"")}/v1/api/ai/w/${e.workspaceId}`,apiKey:e.apiKey,models:[...new Set([Y,...e.models??[]])]}}function vt(e){let t=je({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{...oo({baseUrl:t.baseUrl,workspaceId:t.workspaceId,apiKey:n,...e.models?{models:e.models}:{}}),workspaceId:t.workspaceId,...r?{projectId:r}:{}}}var so=3000;async function Et(e){let t=je({env:e.env,flags:{},cwd:e.cwd});if(t.conflict||!t.credential||!t.workspaceId)return{};try{return{served:(await j(e.env,{cwd:e.cwd,flags:{}}).ai.models(t.workspaceId,{signal:AbortSignal.timeout(e.timeoutMs??so)})).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 wt(e){if(e.configured){let t=e.configuredSource??"config";if(!e.cloud||!e.endpoint||St(e.configured))return{id:e.configured,source:t};return{id:oe(Y),source:"workspace",notice:`model ${e.configured} from ${t} is not available on the cloud sandbox; using hlix default`}}return e.endpoint?{id:oe(Y),source:"workspace"}:null}var ue=200000;function me(e){let t=Math.round(e*3/7);return{observationThreshold:t,reflectionThreshold:e-t}}var _t=(e,t)=>`${e} · memory: ${Math.round((t.observationThreshold+t.reflectionThreshold)/1000)}k`;function It(e){return new io({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 yo}from"node:child_process";import{DockerSandbox as bo}from"@mastra/docker";import{LocalFilesystem as Ot,LocalSandbox as xo,Workspace as Mt}from"@mastra/core/workspace";var ao=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,Ct=/^(\s*name\s*:\s*)(.+?)\s*$/;function lo(e,t){if(!ao.test(t))return e;let n=e.indexOf(`
|
|
7
|
+
---`,3);if(!e.startsWith("---")||n<0)return e;let o=e.slice(0,n).split(`
|
|
8
|
+
`),s=o.findIndex((c)=>Ct.test(c));if(s<0)return e;let l=Ct.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(`
|
|
9
|
+
`)}${e.slice(n)}`}function co(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 Tt(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=co(n);if(o===null)return r;let s=typeof r==="string"?r:r.toString("utf8");return lo(s,o)}};if(e.realpath)t.realpath=(n)=>e.realpath?.(n);return t}import{WORKSPACE_TOOLS as I}from"@mastra/core/workspace";var J={[I.FILESYSTEM.READ_FILE]:"view",[I.FILESYSTEM.WRITE_FILE]:"write_file",[I.FILESYSTEM.EDIT_FILE]:"edit_file",[I.FILESYSTEM.LIST_FILES]:"find_files",[I.FILESYSTEM.DELETE]:"delete_file",[I.FILESYSTEM.FILE_STAT]:"file_stat",[I.FILESYSTEM.MKDIR]:"mkdir",[I.FILESYSTEM.GREP]:"search_content",[I.FILESYSTEM.AST_EDIT]:"ast_edit",[I.SANDBOX.EXECUTE_COMMAND]:"execute_command",[I.SANDBOX.GET_PROCESS_OUTPUT]:"process_output",[I.SANDBOX.KILL_PROCESS]:"kill_process",[I.LSP.LSP_INSPECT]:"lsp_inspect"},se=[I.FILESYSTEM.WRITE_FILE,I.FILESYSTEM.EDIT_FILE,I.FILESYSTEM.DELETE,I.FILESYSTEM.MKDIR,I.FILESYSTEM.AST_EDIT,I.SANDBOX.EXECUTE_COMMAND,I.SANDBOX.KILL_PROCESS].map((e)=>J[e]),ge=Object.values(J).filter((e)=>!se.includes(e)),ie=Object.fromEntries(Object.entries(J).map(([e,t])=>[e,{name:t}]));function R(e){return J[e]??e}import{posix as kt}from"node:path";import{MastraFilesystem as po,MastraSandbox as uo,Workspace as mo}from"@mastra/core/workspace";var go=600000,fo=["recursive","overwrite","force","maxDepth","extension"];function K(e){let t=e??{},n={};for(let r of fo)if(t[r]!==void 0)n[r]=t[r];return Object.keys(n).length>0?{options:n}:{}}var At=(e)=>e instanceof Date?e:new Date(typeof e==="string"||typeof e==="number"?e:0);class Rt extends po{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 kt.isAbsolute(e)?e:kt.join(this.basePath,e)}async call(e){let{result:t}=await this.client.fs({...e,encoding:e.encoding??"utf8",path:this.resolveAbsolutePath(e.path)});return t}async readFile(e,t){let r=await this.call({op:"read",path:e,encoding:"base64"}),o=Buffer.from(r.content,r.encoding);return t?.encoding?o.toString(t.encoding):o}async writeFile(e,t,n){await this.call({op:"write",path:e,content:Buffer.from(t).toString("base64"),encoding:"base64",...K(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,...K(t)})}async copyFile(e,t,n){await this.call({op:"copy",path:e,dest:this.resolveAbsolutePath(t),...K(n)})}async moveFile(e,t,n){await this.call({op:"move",path:e,dest:this.resolveAbsolutePath(t),...K(n)})}async mkdir(e,t){await this.call({op:"mkdir",path:e,...K(t)})}async rmdir(e,t){await this.call({op:"rmdir",path:e,...K(t)})}async readdir(e,t){return await this.call({op:"readdir",path:e,...K(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:At(t.createdAt),modifiedAt:At(t.modifiedAt)}}}var ho=(e)=>`'${e.split("'").join("'\\''")}'`;class Pt extends uo{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(ho)].join(" "),o=Date.now(),s=n?.cwd??this.workingDirectory,l=await this.client.exec({command:r,...s?{cwd:s}:{},timeoutMs:n?.timeout??go});return{success:l.exitCode===0,exitCode:l.exitCode,stdout:l.stdout,stderr:l.stderr,executionTimeMs:Date.now()-o,command:e,args:t}}}function Nt(e,t){let n=t.root??"/workspace";return new mo({id:`hlix-project:${t.projectId}`,name:"Hlix Coding Workspace",filesystem:new Rt(e,{root:n}),sandbox:new Pt(e,{projectId:t.projectId,root:n}),tools:ie})}var jt="node:22-bookworm",So=(e)=>`hlix-code-${e}`;function vo(e,t){if(V.includes(e))return e;throw new Z("invalid_usage",`${t==="flag"?"--sandbox":"sandbox in .hlix/config.json"} must be one of ${V.join(", ")}; got "${e}".`)}function Dt(e){let t=(n)=>n==="docker"?{image:e.dockerImage?.trim()||jt}:{};if(e.flag){let n=e.flagSource??"flag",r=vo(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 $t=(e)=>`sandbox: ${e.choice} (${e.reason}${e.image?`, ${e.image}`:""})`;function Ht(e=3000){try{return yo("docker",["info"],{timeout:e,stdio:"ignore"}),!0}catch{return!1}}function Lt(e,t){if(!e||e.length===0)return{};return{skills:[...e],skillSource:Tt(t)}}function De(e,t){if(e.choice==="local"){let s=new Ot({basePath:t.cwd});return new Mt({id:"hlix-code-local",name:"Hlix Code (this machine)",filesystem:s,...Lt(t.skills,s),sandbox:new xo({workingDirectory:t.cwd}),tools:ie})}if(e.choice==="cloud"){if(!t.remote||!t.projectId)throw new Z("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");return Nt(t.remote,{projectId:t.projectId})}let n="/workspace",r=e.image??jt,o=new Ot({basePath:t.cwd});return new Mt({id:"hlix-code-docker",name:"Hlix Code (Docker)",filesystem:o,...Lt(t.skills,o),tools:ie,sandbox:new bo({id:So(r),image:r,volumes:{[t.cwd]:n},workingDirectory:n})})}import{basename as qo}from"node:path";import{AgentController as zo}from"@mastra/core/agent-controller";import{createCodingAgent as Xo}from"@mastra/core/coding-agent";import{createWorkspaceTools as Jo}from"@mastra/core/workspace";var Eo=["execute_command","kill_process"],wo=["updateWorkingMemory","task_write","task_update","task_complete","task_check","ask_user","submit_plan"];function $e(e){let t=e in J?R(e):e;if(Eo.includes(t))return"execute";if(se.includes(t))return"edit";if(ge.includes(t)||wo.includes(t))return"read";if(t.startsWith("hlix_"))return"other";return null}function Ut(e=[]){let t=new Set(e);return(n)=>t.has(n)?"mcp":$e(n)}function _o(e){return $e(e)!=="read"}var Ft=[{category:"read",policy:"allow"}];function Bt(e){if(e.yolo||!_o(e.toolName))return{decision:"approve"};return{decision:"decline",reason:`Hlix Code is running with -p (no terminal to ask), so ${R(e.toolName)} was not run. Report this to the user: re-run with --yolo to let this session change things.`}}class He{on;constructor(e){this.on=e}get(){return this.on}set(e){this.on=e}}function Gt(e){let t=R(e),n=$e(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 Io,ModelRouterLanguageModel as Co}from"@mastra/core/llm";function To(e,t){let n=[];for(let r of e??[]){if(!r.name||!r.url||r.name===B)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 Wt(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 Yt extends Io{id=`${B}-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=Wt(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===B?"Hlix":t.name,url:t.url,apiKeyEnvVar:[],gateway:this.id,models:t.models.map((n)=>`${t.name}/${n}`)};return e}endpointFor(e){let t=Wt(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 Co({id:`${e.providerId}/${e.modelId}`,url:t.url,apiKey:e.apiKey||t.apiKey,...e.headers?{headers:e.headers}:{}})}}function Kt(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(...To(e.providers,e.env));return new Yt(t)}import{buildBasePrompt as ko}from"@mastra/core/coding-agent";var N="Hlix Code",Ao="Hlix Code",Ro="noreply@hlix.ai";function Po(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 Vt(e){let t=ko({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:Po(e.sandbox),hasSubagents:e.hasSubagents??!1,productName:N,coAuthorName:Ao,coAuthorEmail:Ro});return e.hostInstructions?`${t}
|
|
10
|
+
|
|
11
|
+
${e.hostInstructions}`:t}var q="build",qt="plan",No=[q,qt];function zt(e,t=No){let n=t.indexOf(e);return t[(n+1)%t.length]??t[0]}function Ue(e){let t=new Set(se);return e.filter((n)=>!t.has(n)&&!n.startsWith("hlix_"))}function Oo(e){return[...new Set([...Ue(e),"submit_plan","task_write","task_update","task_check"])]}var Mo=["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(`
|
|
12
|
+
`),Lo=["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(`
|
|
13
|
+
`);function Xt(e){let t=e.modelId?{defaultModelId:e.modelId}:{};return[{id:q,name:"build",description:"Read, write and run. The default.",instructions:Lo,metadata:{default:!0},...t},{id:qt,name:"plan",description:"Read and plan; no edits, no commands.",instructions:Mo,availableTools:Oo(e.registeredTools),transitionsTo:q,...t}]}import{lstatSync as jo,mkdirSync as Do,unlinkSync as $o}from"node:fs";import{homedir as Ho}from"node:os";import{join as Fe}from"node:path";import{LibSQLStore as Uo}from"@mastra/libsql";function Be(e=process.env){return Fe(e.HLIX_CONFIG_HOME??Ho(),".hlix","code")}function Fo(e=process.env){return`file:${Fe(Be(e),"threads.db")}`}var Bo=["auth.json","mastra.db","mastra.db-shm","mastra.db-wal","settings.json"];function Go(e=process.env){let t=Be(e);for(let n of Bo){let r=Fe(t,n);try{if(!jo(r).isFile())continue;$o(r)}catch{}}}function Jt(e=process.env){return Do(Be(e),{recursive:!0}),Go(e),new Uo({id:"hlix-code",url:Fo(e)})}var Zt="explore",Qt="plan",en="execute",Ge=[`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(`
|
|
14
|
+
`),Wo=[Ge,"","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(`
|
|
15
|
+
`),Yo=[Ge,"","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(`
|
|
16
|
+
`),Ko=[Ge,"","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(`
|
|
17
|
+
`);function tn(e){let t=e.modelId?{defaultModelId:e.modelId}:{},n=e.registeredTools.filter((r)=>ge.includes(r));return[{id:Zt,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:Wo,allowedWorkspaceTools:n,...t},{id:Qt,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:Yo,...t},{id:en,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:Ko,...t}]}var Vo=[Zt,Qt,en];function nn(e,t){let n=[],r=[];for(let o of e){if(Vo.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 he extends Error{constructor(){super("No hlix credential for this folder. Run `hlix auth login`.");this.name="NoCredentialError"}}function Zo(e,t){let n=t.startsWith(`${e.name}/`)?t.slice(e.name.length+1):Y;return{id:`${e.name}/${n}`,url:e.url,apiKey:e.apiKey}}async function on(e){if(!e.endpoint)throw new he;let t=e.endpoint,n=e.model?.id??oe(Y),r=Kt({endpoint:t,...e.providers?{providers:e.providers}:{},env:e.env,cloud:e.sandbox==="cloud"}),o=Jt(e.env),s=me(fe(e.memoryTokens)??ue),l=null,i=Zo(t,n),c=It({storage:o,thresholds:s,observerModel:()=>l?.om.observer.resolvedModel()??i,reflectorModel:()=>l?.om.reflector.resolvedModel()??i}),a=e.workspace?await Jo(e.workspace):{},m=e.mcpTools??{},d={...a,...e.extraTools??{},...m},f=Object.keys(d),b=tn({registeredTools:f,modelId:n}),_=nn(e.projectSubagents??[],n),w=[...b,..._.subagents],C=Xo({id:"hlix-coder",name:N,model:i,instructions:Vt({projectPath:e.cwd,projectName:qo(e.cwd),mode:q,modelId:n,sandbox:e.sandbox,hasSubagents:w.length>0,...e.hostInstructions?{hostInstructions:e.hostInstructions}:{}}),tools:d,...e.workspace?{workspace:e.workspace}:{},memory:c}),k=ft({sandbox:e.sandbox,cwd:e.cwd,active:e.harness,readTools:Ue(f),...e.workspace?{workspace:e.workspace}:{},...e.unavailableHarnesses?{unavailable:e.unavailableHarnesses}:{},model:n}),ne=k.length>0?k:Xt({registeredTools:f,modelId:n}),M=new zo({id:"hlix-code",resourceId:t.workspaceId,agent:C,storage:o,memory:c,modes:ne,subagents:w,tools:d,gateways:[r],omConfig:{defaultObserverModelId:n,defaultReflectorModelId:n,defaultObservationThreshold:s.observationThreshold,defaultReflectionThreshold:s.reflectionThreshold},toolCategoryResolver:Ut(Object.keys(m)),...e.workspace?{workspace:e.workspace}:{}});await M.init();let P=await M.createSession({resourceId:t.workspaceId,tags:{projectPath:e.cwd}});if(l=P,n)await P.model.switch({modelId:n});for(let L of Ft)await P.permissions.setForCategory(L);return{controller:M,session:P,gateway:r,store:o,memory:c,harnessModesBuilt:k.length>0,subagentLine:rn(b,_.subagents),subagentsSkipped:_.skipped,dispose:async()=>{await M.destroy().catch(()=>{}),await o.close().catch(()=>{})}}}import{Editor as Ii,ProcessTerminal as Ci,SelectList as yr,Input as Ti,TuiMainScreen as ki,truncateToWidth as ot}from"@earendil-works/pi-tui";import{execFileSync as Qo}from"node:child_process";import{readFileSync as es,statSync as ts}from"node:fs";import{basename as ns,extname as rs,isAbsolute as os,join as ss}from"node:path";import{CombinedAutocompleteProvider as is,Key as ye,matchesKey as as}from"@earendil-works/pi-tui";function ls(e,t=as){if(t(e,ye.shift("tab")))return"cycle-mode";if(t(e,ye.ctrl("c")))return"interrupt";if(t(e,ye.ctrl("o")))return"expand";if(t(e,ye.escape))return"abort";return"text"}var cs=2000;class an{windowMs;armedAt=0;constructor(e=cs){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 ds(e){return[...e.entries()].map(([t,n])=>({name:t,description:n.description})).sort((t,n)=>t.name.localeCompare(n.name))}var We="Press Ctrl-C again to leave Hlix Code.";class ln extends is{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 ps(e=Qo){for(let t of["fd","fdfind"])try{let n=e("which",[t],{timeout:3000,encoding:"utf8"}).trim();if(n)return n.split(`
|
|
18
|
+
`)[0]}catch{continue}return null}function us(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 cn(e){let t=new an;return e.editor.setAutocompleteProvider(new ln(ds(e.commands),e.basePath,ps())),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(ls(n)){case"cycle-mode":return e.handlers.onCycleMode(),{consume:!0};case"interrupt":if(t.press()==="exit")e.handlers.onExit();else e.handlers.onInterruptWarning(We);return{consume:!0};case"expand":return t.disarm(),e.handlers.onExpand(),{consume:!0};case"abort":if(e.editor.isShowingAutocomplete())return;if(us(e.tui,e.editor))return;return t.disarm(),e.handlers.onAbort(),{consume:!0};default:t.disarm();return}})}var ms={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp"},sn=8388608;function dn(e,t,n=es,r=(o)=>ts(o).size){let o=[],s=[],l=new Set;for(let i of e.matchAll(/(?:^|\s)@(\S+)/g)){let c=i[1],a=ms[rs(c).toLowerCase()];if(!a||l.has(c))continue;l.add(c);let m=os(c)?c:ss(t,c);try{let d=r(m);if(d>sn){s.push(`@${c} is ${Math.round(d/1048576)} MB — too large to attach (limit ${sn/1048576} MB).`);continue}o.push({data:`data:${a};base64,${n(m).toString("base64")}`,mediaType:a,filename:ns(c)})}catch{s.push(`@${c} could not be read, so it was not attached.`)}}return{content:e,files:o,notes:s}}import{z as O}from"zod";var z=O.string().trim().min(1),gs=O.discriminatedUnion("kind",[O.object({kind:O.literal("project"),projectId:z}).strict(),O.object({kind:O.literal("cycle"),projectId:z,cycleId:z}).strict(),O.object({kind:O.literal("task"),projectId:z,taskId:z}).strict(),O.object({kind:O.literal("agent"),projectId:z,agentId:z}).strict()]);import{z as p}from"zod";var pn=["github-compare","workspace-artifact"],be=p.enum(["added","removed","modified","renamed","copied","changed","unchanged","unknown"]),un=p.object({path:p.string(),previousPath:p.string().nullable(),status:be,additions:p.number().nullable(),deletions:p.number().nullable(),patch:p.string().nullable(),patchTruncated:p.boolean()}),mn=p.object({status:p.enum(["ahead","behind","identical","diverged","unknown"]),aheadBy:p.number().nullable(),behindBy:p.number().nullable()}),gn=p.object({kind:p.literal("git-archive"),reviewUrl:p.string(),sizeBytes:p.number().nullable(),capturedAt:p.string().nullable()}),fn=p.object({verdict:p.enum(["approved","rejected"]),summary:p.string().nullable(),headSha:p.string().nullable(),observedAt:p.string(),stale:p.boolean()}),fs=p.object({taskId:p.string(),repoId:p.string().nullable(),source:p.enum(pn),observedAt:p.string(),baseRef:p.string().nullable(),baseSha:p.string().nullable(),headRef:p.string().nullable(),headSha:p.string().nullable(),comparison:mn,filesChanged:p.number().nullable(),additions:p.number().nullable(),deletions:p.number().nullable(),commits:p.number().nullable(),files:p.array(un),filesTruncated:p.boolean(),evaluator:fn.nullable(),artifact:gn.nullable()}),hn=["base","head"],Ye=p.enum(hn),yn=["open","resolved"],Ke=p.enum(yn),bn=p.object({pagePath:p.string().min(1).max(2048).regex(/^\/(?!\/)/,"expected a same-origin absolute path").refine((e)=>!/[?#\\]/.test(e),"query, fragment, and backslash are not allowed"),selector:p.string().min(1).max(512),viewport:p.object({width:p.number().int().min(320).max(1920),height:p.number().int().min(320).max(1200),deviceScaleFactor:p.literal(1)}).strict()}).strict(),xn=["previews-disabled","boundary-unavailable","review-head-unavailable","no-live-preview","revision-mismatch","source-not-isolated","unsafe-source"],Sn=p.discriminatedUnion("enabled",[p.object({enabled:p.literal(!0)}),p.object({enabled:p.literal(!1),reasonCode:p.enum(xn),reason:p.string()})]),vn=p.string().regex(/^[0-9a-f]{40}$/i,"expected a commit sha"),En=p.object({id:p.string(),taskId:p.string(),projectId:p.string(),authorId:p.string(),headSha:p.string(),path:p.string().nullable(),side:Ye.nullable(),lineStart:p.number().nullable(),lineEnd:p.number().nullable(),selectedText:p.string().nullable(),body:p.string(),resolution:Ke,resolvedBy:p.string().nullable(),resolvedAt:p.string().nullable(),revisionIteration:p.number().nullable(),createdAt:p.string(),updatedAt:p.string(),stale:p.boolean()}),hs=p.object({taskId:p.string(),headSha:p.string().nullable(),comments:p.array(En),visualContext:Sn.optional()}),ys=p.object({headSha:vn,body:p.string().min(1).max(1e4),path:p.string().min(1).max(1024).nullish(),side:Ye.nullish(),lineStart:p.number().int().positive().nullish(),lineEnd:p.number().int().positive().nullish(),selectedText:p.string().max(1e4).nullish(),visualContext:bn.optional()}).superRefine((e,t)=>{if(e.lineStart!=null&&(e.path==null||e.side==null))t.addIssue({code:p.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:p.ZodIssueCode.custom,path:["lineEnd"],message:"lineEnd must be >= lineStart"});if(e.side!=null&&e.path==null)t.addIssue({code:p.ZodIssueCode.custom,path:["side"],message:"a side needs a path"})}),bs=p.object({resolution:Ke}),xs=p.object({headSha:vn}),Ss=p.object({taskId:p.string(),cycleId:p.string(),headSha:p.string(),commentIds:p.array(p.string()),staleSkipped:p.number(),feedback:p.string(),iteration:p.number(),started:p.boolean(),reason:p.string().nullable()});import{z as h}from"zod";var wn=h.enum(["github","workspace"]),Ve=h.object({path:h.string(),previousPath:h.string().nullable(),status:be,additions:h.number().nullable(),deletions:h.number().nullable(),binary:h.boolean()}),_n=h.object({sha:h.string(),subject:h.string(),at:h.string()}),ae=h.object({ref:h.string(),sha:h.string().nullable()}),In=h.object({repoKey:h.string(),label:h.string(),base:ae,head:ae,files:h.array(Ve),filesTruncated:h.boolean(),filesChanged:h.number(),additions:h.number(),deletions:h.number(),commits:h.array(_n),unavailable:h.enum(["repository_unreachable"]).nullable()}),Cn=h.object({taskId:h.string(),title:h.string(),repoKey:h.string(),files:h.array(Ve),observedAt:h.string()}),vs=h.object({projectId:h.string(),source:wn,environmentState:h.string().nullable(),observedAt:h.string(),repos:h.array(In),inFlight:h.array(Cn)}),Es=h.object({repoKey:h.string(),path:h.string(),patch:h.string().nullable(),patchTruncated:h.boolean(),binary:h.boolean()}),ws=h.object({repoKey:h.string(),ref:ae,paths:h.array(h.string()),truncated:h.boolean()}),_s=h.object({error:h.string(),environmentState:h.string()}),Is=h.object({repoKey:h.string(),path:h.string(),ref:ae,content:h.string().nullable(),truncated:h.boolean(),binary:h.boolean(),size:h.number().nullable()});var xe={"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 Cs=Object.keys(xe);var Ts={"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="◆",ks=(()=>{let e={};for(let t of Object.keys(xe)){let n=xe[t];e[t]=n.displayName,e[Ts[t]]=n.displayName,e[`${n.provider}:${t}`]=n.displayName}return e})();function Se(e){if(!e)return e;let n=ks[e]??e.split(/[/:]/).pop()??e;return`${D} ${n}`}var qe={"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}},ze=Object.keys(qe),ve=Object.values(qe),As=ve.filter(({driverKind:e})=>e==="external-acp").map(({id:e})=>e),Tn=ve.filter(({available:e,driverKind:t})=>e&&t==="external-acp"),Xe=Tn.map(({id:e})=>e),kn=ve.filter(({available:e})=>e),An=kn.map(({id:e})=>e),Je="hlix";var Rn=["chat","kanban","linear","github","api"];var Ze={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 Pn(e){return Rn.filter((t)=>Ze[t].kind===e)}var Ps=Pn("external"),Ns=Pn("native");import{z as u}from"zod";var Nn=u.enum(ze),On=u.enum(Xe),Mn=u.object({node:u.string().optional(),python:u.string().optional(),bun:u.string().optional(),playwright:u.boolean().optional()}).partial(),Ln=u.object({agents:u.array(On).optional(),toolchain:Mn.optional(),aptPackages:u.array(u.string()).optional(),setup:u.string().optional(),hash:u.string().optional(),imageTag:u.string().nullable().optional(),linearProjectId:u.string().optional(),linearTeamId:u.string().optional()}).partial(),Hs=u.object({owner:u.string(),name:u.string(),cloneUrl:u.string(),defaultBranch:u.string()}),jn=u.object({key:u.string(),cloneUrl:u.string().nullable(),owner:u.string().nullable(),name:u.string().nullable(),defaultBranch:u.string(),setupCommand:u.string().nullable().optional(),verifyCommand:u.string().nullable().optional()});var Dn=u.object({name:u.string(),skillSlugs:u.array(u.string()),agentSlugs:u.array(u.string())}),$n=u.object({path:u.string(),content:u.string()}),Hn=u.object({vars:u.record(u.string(),u.string()).default({}),files:u.array($n).optional(),skills:u.array(u.string()).optional(),mcpServers:u.array(u.unknown()).optional(),managedPaths:u.array(u.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()}),Un=u.object({path:u.string(),kind:u.enum(["dotenv","credential","detected-content"]),contentBase64:u.string(),size:u.number().int().nonnegative(),sha256:u.string().regex(/^[0-9a-f]{64}$/)}),Fn=u.object({taskId:u.string(),cycleId:u.string(),threadId:u.string(),organizationId:u.string().optional(),projectId:u.string().optional(),description:u.string(),reviewFeedback:u.string().optional(),iteration:u.number().default(0),operationId:u.string().min(1).optional(),repo:jn.nullable().default(null),verifyCommand:u.string().nullable().optional(),branch:u.string(),baseBranch:u.string(),githubToken:u.string().optional(),snapshotKey:u.string().optional(),aiGatewayUrl:u.string().optional(),secrets:u.record(u.string(),u.string()),packs:u.array(Dn),systemPrompt:u.string().optional(),timeoutSeconds:u.number().default(1800),resultToken:u.string().min(1).optional(),agent:Nn.default(Je),agentEnv:u.record(u.string(),u.string()).optional(),projectRuntime:Ln.optional(),environment:Hn.optional(),protectedFiles:u.array(Un).optional()}),Us=u.enum(["acp"]),Fs=u.enum(["builder","desktop","e2e"]),Bs=u.object({batchId:u.string(),tasks:u.array(Fn).min(1).max(20)}),Bn=u.object({inputTokens:u.number(),outputTokens:u.number(),costUsd:u.number()}),Gs=u.object({taskId:u.string(),token:u.string().optional(),status:u.enum(["success","failed"]),cost:Bn.optional(),model:u.string().optional(),error:u.string().optional()});import{z as T}from"zod";var Ws=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 Ys}from"@earendil-works/pi-tui";var Qe=(e)=>e;function Ee(e){return(t)=>t?`\x1B[${e}m${t}\x1B[0m`:t}var Q={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 we(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 ee=(e,t)=>{if(t==="none")return Qe;if(t==="truecolor")return Ee(`38;2;${e.rgb[0]};${e.rgb[1]};${e.rgb[2]}`);return Ee(`38;5;${e.cube}`)};function _e(e=we()){return{brand:ee(Q.gold,e),muted:e==="none"?Qe:Ee("2"),user:ee(Q.paper,e),alert:ee(Q.vermilion,e),ok:ee(Q.teal,e),added:ee(Q.teal,e),removed:ee(Q.vermilion,e)}}function te(e){return{selectedPrefix:e.brand,selectedText:e.brand,description:e.muted,scrollInfo:e.muted,noMatch:e.muted}}function Gn(e){return{borderColor:e.muted,selectList:te(e)}}function Wn(e,t=we()){let n=(r)=>t==="none"?Qe:Ee(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 Ks=12;function Vs(e){let t=/^(.*?)\(([^()]*)\)\s*$/.exec(e);if(!t)return Se(e);let n=(t[1]??"").trim(),r=Se(t[2]??"").slice(D.length).trim();return n?`${D} ${n} (${r})`:`${D} ${r}`}function et(e){let t=new Set,n=[],r=(o,s)=>{if(t.has(o))return;t.add(o),n.push({id:o,label:Vs(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 Vn(e){let t=Yn(e.cwd)?"project":"global";return Kn({key:"model",value:e.modelId,scope:t,cwd:e.cwd,env:e.env})}function qn(e){let t=e.colors??_e(),n=e.entries.map((i)=>({value:i.id,label:i.label})),r=new Ys(n,Ks,te(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 qs,truncateToWidth as H,wrapTextWithAnsi as tt}from"@earendil-works/pi-tui";function zn(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 Xn(e,t,n={}){let r=n.context??2,o=zn(e.split(`
|
|
19
|
+
`),t.split(`
|
|
20
|
+
`)),s=new Set;o.forEach((a,m)=>{if(a.kind==="same")return;for(let d=m-r;d<=m+r;d+=1)if(d>=0&&d<o.length)s.add(d)});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 Jn(e,t){let n=zn(e.split(`
|
|
21
|
+
`),t.split(`
|
|
22
|
+
`)),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 zs={user:"›",assistant:" ",tool:"⏺",command:"▸",subagent:"↳",notice:"·"},nt=8;function Zn(e,t,n){let r=`┌ ${e} `,o=Math.max(0,t-r.length);return n(H(`${r}${"─".repeat(o)}`,t))}var Xs=(e,t)=>t(H(`└${"─".repeat(Math.max(0,e-1))}`,e));function le(e,t,n,r){let o=Math.max(1,t-2),s=[];for(let l of e){let i=l===""?[""]:tt(l,o);for(let c of i)s.push(H(`${r("│")} ${n(c)}`,t))}return s}function Js(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=Jn(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 Zs(e){switch(e.tool?.state){case"running":return"⏺";case"awaiting":return"?";case"declined":return"⊘";case"error":return"✗";default:return"✓"}}function Qs(e){let t=e.tool;if(!t)return[];let n=t.args??{};if(typeof n.old_string==="string"&&typeof n.new_string==="string")return Xn(n.old_string,n.new_string);let r=(t.result??"").trimEnd();return r===""?[]:r.split(`
|
|
23
|
+
`)}function rt(e,t){let n=e-t;return`… ${n} more line${n===1?"":"s"} — ctrl-o to expand`}function Qn(e,t){let{width:n,colors:r}=t;switch(e.kind){case"assistant":return er(e.text,n,r);case"command":return ti(e,t);case"tool":return ni(e,t);case"subagent":return oi(e,t);default:{let o=e.kind==="user"?r.user:e.error?r.alert:r.muted,s=e.error?"!":zs[e.kind];return ei(e.text,s,n,o)}}}function er(e,t,n){let r=Math.max(8,t-2);return new qs(e,0,0,Wn(n)).render(r).map((s)=>H(` ${s}`,t))}function ei(e,t,n,r){let o=Math.max(1,n-2),s=[];for(let l of e.split(`
|
|
24
|
+
`)){let i=l===""?[""]:tt(l,o);for(let c of i){let a=s.length===0?`${t} `:" ";s.push(H(`${a}${r(c)}`,n))}}return s}function ti(e,t){let{width:n,colors:r}=t,o=e.error?r.alert:r.muted,s=e.text===""?["(no output)"]:e.text.split(`
|
|
25
|
+
`),l=e.expanded===!0?s:s.slice(0,nt*3),i=le(l,n,e.error?r.alert:r.user,o);return[Zn(e.title??"command",n,o),...i,...l.length<s.length?le([rt(s.length,l.length)],n,r.muted,o):[],Xs(n,o)]}function ni(e,t){let{width:n,colors:r}=t,o=e.tool,s=Zs(e),l=e.error?r.alert:o?.state==="running"?r.muted:r.ok,i=Js(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 d=Qs(e);if(d.length===0)return[m];let f=e.expanded===!0?d:d.slice(0,nt);return[m,...ri(f,n,r),...f.length<d.length?le([rt(d.length,f.length)],n,r.muted,r.muted):[]]}function ri(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===""?[""]:tt(s,r))o.push(H(`${n.muted("│")} ${l(i)}`,t))}return o}function oi(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(`
|
|
26
|
+
`),d=e.expanded===!0?m:m.slice(0,nt);if(a.push("",...d),d.length<m.length)a.push(rt(m.length,d.length))}return[c,...le(a,n,r.muted,s)]}function tr(e,t){let{width:n,colors:r}=t,o=e.args??{},s=[o.command,o.path,o.pattern,o.query].find((i)=>typeof i==="string"&&i!==""),l=R(e.toolName);return[Zn(`Approve ${l}`,n,r.alert),...le(s?[s]:["(no arguments)"],n,r.user,r.alert)]}var ce="yolo";function si(e,t){if(t<=0)return`${Math.round(e/1000)}k`;return`${Math.round(e/t*100)}% of ${Math.round(t/1000)}k`}function ii(e){return e>0&&e<0.01?`$${e.toFixed(4)}`:`$${e.toFixed(2)}`}var ai=4,li=["cost","total_cost","costUsd"];function Ie(e){let t=e?.raw;for(let n=0;n<ai&&t&&typeof t==="object";n+=1){for(let r of li){let o=t[r];if(typeof o==="number"&&Number.isFinite(o)&&o>0)return o}t=t.raw}return}var ci=(e)=>e.startsWith(D)?e:`${D} ${e}`;function di(e){let t=[...e.yolo?[ce]:[],e.sandbox,e.harness];if(e.mode)t.push(e.mode);if(e.model)t.push(ci(e.model));if(e.workspace)t.push(e.workspace);if(e.branch)t.push(e.branch);if(e.context)t.push(si(e.context.used,e.context.total));if(e.costUsd!==void 0)t.push(ii(e.costUsd));if(e.memory)t.push(e.memory);if(e.warning)t.push(e.warning);return t}function nr(e,t){let n=di(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 pi="subagent",sr=()=>({entries:[],busy:!1,status:"",approval:null});function Ce(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 rr(e,t){let n=t??{},r=n.path??n.command??n.pattern??n.query;return typeof r==="string"?`${R(e)} ${r}`:R(e)}function or(e){let t=e===void 0?null:/^Exit code: (\d+)$/m.exec(e);return t?Number(t[1]):void 0}function ui(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(`
|
|
27
|
+
`);try{return JSON.stringify(e,null,2)}catch{return String(e)}}var mi={om_observation_start:"remembering…",om_observation_end:"",om_reflection_start:"condensing memory…",om_reflection_end:"",compaction_start:"compacting…",compaction_end:""},gi={thread_created:()=>"New conversation.",info:(e)=>typeof e.message==="string"?e.message:null};function ir(e,t){let n=(i,c)=>{let a=e.entries.findIndex((d)=>d.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=Ce(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===pi)return e;let i=s(t.toolCallId),c=R(t.toolName);return n(i,{kind:"tool",id:i,text:rr(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:rr(t.toolName,t.args),tool:{name:R(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,d=ui(t.result),f=n(i,{...c,error:m||a,tool:{...c.tool,result:d,state:a?"declined":m?"error":"done",...or(d)!==void 0?{exitCode:or(d)}:{}}});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,R(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=mi[t.type];if(i!==void 0)return{...e,status:i};let c=gi[t.type]?.(t);return c===null||c===void 0?e:r({kind:"notice",id:`${t.type}:${e.entries.length}`,text:c})}}}function ar(e){return{kind:"command",id:`cmd:${e.index}`,title:`/${e.name}`,text:e.output,...e.failed?{error:!0}:{}}}import{readdirSync as fi,readFileSync as hi}from"node:fs";import{basename as yi,join as bi}from"node:path";var xi=(e)=>e.split(" ").join("-");function Si(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 lr="Project prompt";function vi(e){let t=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/.exec(e);if(!t)return{description:lr,body:e};return{description:/^description:[ \t]*(.+)$/m.exec(t[1]??"")?.[1]?.trim()||lr,body:e.slice(t[0].length).replace(/^(?:[ \t]*\r?\n)+/,"")}}function Ei(e){let t=new Map;for(let n of e){let r;try{r=fi(n)}catch{continue}for(let o of r){if(!o.endsWith(".md"))continue;try{t.set(yi(o,".md"),vi(hi(bi(n,o),"utf8")))}catch{continue}}}return t}function wi(e,t){let n=t.trim();if(e.includes("$ARGUMENTS"))return e.split("$ARGUMENTS").join(n);return n?`${e.trimEnd()}
|
|
28
|
+
|
|
29
|
+
${n}`:e}function cr(e,t){return async(n,r)=>{let o="",s=(i)=>{o+=i},l=await re([e],Si(e,n,r),{stdout:s,stderr:s,env:t});return{lines:[],output:o.trimEnd()||`exit ${l}`,...l===0?{}:{failed:!0}}}}var Te={lines:["This command needs a live session."]};async function dr(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 re([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(`
|
|
30
|
+
`)}}function mr(e={}){let t=e.env??process.env,n=e.shell,r=new Map,o=(a)=>r.set(a.name,a),s=e.commands??pe;for(let a of s)o({name:xi(a.name),description:a.summary,handler:cr(a,t)});let l=(a,m,d)=>{let f=s.find((b)=>b.name===m);if(f)o({name:a,description:d,handler:cr(f,t)})};for(let[a,m]of Ei(e.promptFiles??[])){if(r.has(a))continue;o({name:a,description:m.description,prompt:(d)=>wi(m.body,d),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 d=n?.facts;if(!d)return{lines:["Sandbox not resolved."]};let f=a.trim(),b=async(_)=>{let w=await dr("sandbox",_,m,t,s);return{lines:[],output:[d.sandboxLine,w.ok?`${w.message} This session keeps ${d.sandbox}; restart to run in ${_}.`:w.message].join(`
|
|
31
|
+
`),...w.ok?{}:{failed:!0}}};if(f){if(!V.includes(f))return{lines:[`/sandbox must name one of ${V.join(", ")}.`]};return b(f)}if(!n?.openPicker)return{lines:[],output:d.sandboxLine};return n.openPicker({title:"Sandbox",current:d.sandbox,choices:V.map((_)=>({value:_,label:_,description:_i[_]})),apply:b}),{lines:[]}}}),o({name:"harness",description:"Show or change which coder does the work",handler:async(a,m)=>{let d=n?.facts;if(!d)return{lines:["Harness not resolved."]};let f=d.harnessModesBuilt?n?.session?.mode.get()??d.harness:d.harness,b=async(w)=>{let C=Le({requested:w,current:f,available:d.availableHarnesses,sandbox:d.sandbox,sandboxLine:d.sandboxLine,modesBuilt:d.harnessModesBuilt});if(C.action==="mode"&&n?.session)await n.session.mode.switch({modeId:C.harness}),n.setFact?.({harness:C.harness,mode:C.harness});if(C.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(C.harness),n.setFact?.({harness:C.harness})}let k=C.action==="restart"?await dr("harness",w,m,t,s):null;return{lines:[],output:k?`${C.message}
|
|
32
|
+
${k.message}`:C.message,...k&&!k.ok?{failed:!0}:{}}},_=a.trim();if(_)return b(_);if(!n?.openPicker)return{lines:[],output:`harness: ${f}`};return n.openPicker({title:"Harness",current:f,choices:U.map((w)=>({value:w,label:w,description:d.availableHarnesses.includes(w)?w==="hlix"?"Our own coder. The default.":"Installed on this machine.":"Not installed here."})),apply:b}),{lines:[]}}}),o({name:"new",description:"Start a new conversation in this folder",handler:async()=>{if(!n?.session)return Te;return await n.session.thread.create(),{lines:[]}}}),o({name:"threads",description:"List this folder's conversations, newest first",handler:async(a)=>{if(!n?.session)return Te;let m=a.trim();if(m)return await n.session.thread.switch({threadId:m}),{lines:[],output:`Switched to thread ${m}.`};let d=pr(await n.session.thread.list());if(d.length===0)return{lines:[],output:"No conversations here yet."};let f=n.session.thread.getId();return{lines:[],output:d.map((b)=>ur(b,f)).join(`
|
|
33
|
+
`)}}}),o({name:"resume",description:"Pick an earlier conversation in this folder and continue it",handler:async()=>{if(!n?.session)return Te;let a=pr(await n.session.thread.list());if(a.length===0)return{lines:[],output:"No conversations here yet."};let m=n.session.thread.getId();if(!n.openPicker)return{lines:[],output:a.map((d)=>ur(d,m)).join(`
|
|
34
|
+
`)};return n.openPicker({title:"Resume",...m?{current:m}:{},choices:a.map((d)=>({value:d.id,label:d.title?.trim()||"(untitled)",description:`${d.id} ${gr(d.updatedAt)}`})),apply:async(d)=>(await n.session?.thread.switch({threadId:d,emitEvent:!0}),{lines:[],output:`Resumed ${d}.`})}),{lines:[]}}}),o({name:"compact",description:"Condense this conversation into memory now",handler:async()=>{if(!n?.compact)return Te;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.
|
|
35
|
+
${n.log.path}`:[...a,"",n.log.path].join(`
|
|
36
|
+
`)}}}),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(),d=m===""?!n.yolo.get():!["off","false","0","no"].includes(m);return n.yolo.set(d),n.setFact?.({yolo:d}),{lines:[],output:d?"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(`
|
|
37
|
+
`)})});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 d=await c.handler(a,m),f=n.mcp?.()??[];if(f.length===0)return d;return{...d,output:[d.output??"","MCP servers (this session)",...f.map((b)=>` ${b}`)].join(`
|
|
38
|
+
`).trim()}}});return r}var _i={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 pr(e){return[...e].sort((t,n)=>(n.updatedAt?.getTime()??0)-(t.updatedAt?.getTime()??0))}function gr(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 ur=(e,t)=>`${e.id===t?"›":" "} ${(e.title?.trim()||"(untitled)").padEnd(40)} ${gr(e.updatedAt)}`;function fr(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 hr(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 br{colors;state=sr();expanded=new Set;constructor(e){this.colors=e}render(e){return this.state.entries.flatMap((t)=>[...Qn(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 xr{colors;text="";constructor(e){this.colors=e}render(e){return this.text===""?[]:[this.colors.muted(ot(`· ${this.text}`,e))]}invalidate(){}}class Sr{colors;facts=null;constructor(e){this.colors=e}render(e){if(!this.facts)return[];let t=nr(this.facts,e);if(this.facts.yolo!==!0||!t.startsWith(ce))return[this.colors.muted(t)];return[`${this.colors.alert(ce)}${this.colors.muted(t.slice(ce.length))}`]}invalidate(){}}class vr{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 Er(e){let t=_e(we(e.env)),n=e.tui??new ki(new Ci),r=new br(t),o=new xr(t),s=new vr,l=new Sr(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()},d=(g)=>{m({kind:"notice",id:`warn:${c++}`,text:g,error:!0})},f=(g)=>{m({kind:"notice",id:`say:${c++}`,text:g})},b=(g,y)=>{for(let x of y.lines)d(x);if(y.output===void 0)return;m(ar({name:g,output:y.output,index:c++,...y.failed?{failed:!0}:{}}))},_=new Ii(n,Gn(t)),w=()=>{s.close(),n.setFocus(_),n.requestRender()},C=(g)=>{let{content:y,files:x,notes:S}=dn(g,e.cwd);m({kind:"user",id:`you:${c++}`,text:g});for(let E of S)d(E);e.session.sendMessage({content:y,...x.length>0?{files:x}:{}}).catch((E)=>{d(E instanceof Error?E.message:String(E))})},k=(g)=>{let y=g.choices.map((S)=>({value:S.value,label:S.value===g.current?`${S.label} (current)`:S.label,...S.description?{description:S.description}:{}})),x=new yr(y,Math.min(y.length,8),te(t));x.onSelect=(S)=>{w(),Promise.resolve(g.apply(S.value)).then((E)=>b(g.title.toLowerCase(),E)).catch((E)=>{d(`${g.title}: ${E instanceof Error?E.message:String(E)}`)})},x.onCancel=w,s.open((S)=>[t.brand(ot(g.title,S))],x),n.setFocus(s),n.requestRender()},ne=(g,y)=>{let x=e.commands.get(g);if(!x){d(`Unknown command /${g}. Try /help.`);return}if(x.prompt){C(x.prompt(y));return}Promise.resolve(x.handler(y,e.cwd)).then((S)=>{if(b(g,S),S.quit)n.stop()}).catch((S)=>{d(`/${g} failed: ${S instanceof Error?S.message:String(S)}`)})},M=()=>{if(e.models.length===0){d("No models to choose from. Run `hlix auth login`.");return}qn({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 y=Vn({modelId:g.id,cwd:e.cwd,env:e.env});i.model=g.label,e.onModelPicked?.(g),f(`Model is ${g.label} — written to ${y}.`)}catch(y){d(`Could not switch model: ${y instanceof Error?y.message:String(y)}`)}})()},onCancel:()=>n.setFocus(_)})},P=(g,y,x)=>{e.session.respondToToolApproval({decision:y,toolCallId:g,...x?{declineContext:{reason:x}}:{}})},L=(g)=>{if(e.yolo?.get()){P(g.toolCallId,"approve");return}let y=Gt(g.toolName),x=new yr(y.map((S)=>({value:S.value,label:S.label,description:S.description})),y.length,te(t));x.onSelect=(S)=>{if(S.value!=="decline"){w(),P(g.toolCallId,S.value);return}let E=new Ti({prompt:"why not? (enter to skip) ",placeholder:"reason"}),v=(Re)=>{w(),P(g.toolCallId,"decline",Re.trim())};E.onSubmit=v,E.onEscape=()=>v(""),s.open(()=>[],E),n.setFocus(s),n.requestRender()},x.onCancel=()=>{w(),P(g.toolCallId,"decline","The user dismissed the approval prompt.")},s.open((S)=>tr({toolCallId:g.toolCallId,toolName:g.toolName,args:g.args},{width:S,colors:t}),x),n.setFocus(s),n.requestRender()};e.session.subscribe((g)=>{if(g.type==="tool_approval_required")L(g);if(g.type==="mode_changed")i.mode=g.modeId;if(g.type==="usage_update"){let x=Ie(g.usage);if(i.context={used:g.usage.totalTokens,total:i.context?.total??0},x!==void 0)i.costUsd=x}let y=ir(r.state,g);if(y!==r.state)r.state=y;o.text=r.state.status,a()});let de=cn({tui:n,editor:_,commands:e.commands,basePath:e.cwd,handlers:{onSubmit:(g)=>{let y=fr(g);if(y.kind==="slash"){let x=hr(y,e.commands);ne(x.name,x.args);return}C(g)},onCycleMode:()=>{let g=zt(e.session.mode.get());e.session.mode.switch({modeId:g}).catch(()=>{d("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(We),onExit:()=>n.stop()}});for(let g of e.notices??[])f(g);if(n.addChild(new class{render(g){return[t.brand(ot(`◆ ${N}`,g)),""]}invalidate(){}}),n.addChild(r),n.addChild(o),n.addChild(s),n.addChild(_),n.addChild(l),n.setFocus(_),a(),e.commands.set("model",{name:"model",description:"Pick the model this session runs on",handler:()=>(M(),{lines:[]})}),e.bindings)e.bindings.openPicker=k,e.bindings.openModelPicker=M,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 y=n.stop.bind(n);n.stop=(x)=>{de(),y(x),g()},n.start()})}var Ai=new Set(["display_state_changed","tool_input_start","tool_input_delta","tool_input_end","om_status"]),Ri=(e)=>!Ai.has(e);function Pi(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=Ce(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=Ie(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 wr(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&&Ri(a.type))t(`${Pi(a)}
|
|
39
|
+
`);if(a.type==="tool_approval_required"){let m=Bt({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=Ce(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}
|
|
40
|
+
`);if(o)n(`${o}
|
|
41
|
+
`);else if(!l)n(`the turn ended ${s}
|
|
42
|
+
`)}return{text:r,exitCode:l?0:1}}import{appendFileSync as Ni,mkdirSync as Oi}from"node:fs";import{homedir as Mi}from"node:os";import{dirname as Li,join as _r}from"node:path";var ji=["log","info","warn","error","debug","trace"];function Di(e=process.env){let t=e.HLIX_CONFIG_HOME??_r(e.HOME??Mi(),".hlix");return _r(t,"code","hlix-code.log")}var $i={log:"notes",info:"notes",debug:"notes",trace:"notes",warn:"warnings",error:"errors"};function Hi(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 st(e=process.env,t=console){let n=Di(e),r=new Set,o=[],s={notes:0,warnings:0,errors:0},l=new Map,i=(a,m)=>{let d=`${new Date().toISOString()} ${a} ${m}`;o.push(d);try{Oi(Li(n),{recursive:!0}),Ni(n,`${d}
|
|
43
|
+
`,"utf8")}catch{}};for(let a of ji)l.set(a,t[a]),t[a]=(...m)=>{let d=m.map(Hi).join(" ");if(r.has(`${a}:${d}`))return;r.add(`${a}:${d}`),s[$i[a]]+=1,i(a,d)};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 Ir(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 Ui}from"@mastra/mcp";var it={tools:{},statusLines:[],summary:"",connected:[],failed:[],stop:async()=>{}};function Fi(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 Bi(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 Ae=(e,t)=>`${e} ${t}${e===1?"":"s"}`;async function at(e){if(e.servers.length===0)return it;let{servers:t,skipped:n}=Fi(e.servers,e.cwd),r=Object.keys(t),o=e.timeoutMs??20000,s=[...n];if(r.length===0)return ke({failed:s});let l;try{l=(e.client??((b)=>new Ui(b)))({id:`hlix-code:${e.cwd}`,servers:t,timeout:o})}catch(f){for(let b of r)s.push({name:b,reason:Cr(f)});return ke({failed:s})}let i={},c={};try{let f=await l.listToolsWithErrors({perServerTimeoutMs:o});i=f.tools,c=f.errors}catch(f){for(let b of r)s.push({name:b,reason:Cr(f)});return await l.disconnect().catch(()=>{}),ke({failed:s})}for(let[f,b]of Object.entries(c))s.push({name:f,reason:b});let a=Bi(Object.keys(i),r),m=r.filter((f)=>!(f in c)).map((f)=>({name:f,tools:a[f]??0})),d=!1;return ke({tools:i,connected:m,failed:s,stop:async()=>{if(d)return;d=!0,await l.disconnect().catch(()=>{})}})}function ke(e){let t=e.connected??[],n=e.failed??[],r=e.tools??{},o=t.length===0?n.length>0?`mcp: ${Ae(n.length,"server")} unreachable`:"":`mcp: ${Ae(t.length,"server")} · ${Ae(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:Gi(t,n),stop:e.stop??(async()=>{})}}var Cr=(e)=>e instanceof Error?e.message:String(e);function Gi(e,t){return[...e.map((n)=>`✓ ${n.name} — ${Ae(n.tools,"tool")}`),...t.map((n)=>`✗ ${n.name} — ${n.reason}`)]}var Vi="run `hlix auth login`",qi=["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(`
|
|
44
|
+
`);function zi(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 Xi(e,t){try{return await j(process.env,{cwd:e,flags:{}}).secrets.listEntries(t)}catch{return null}}function Ji(e){let{values:t,positionals:n}=Ki({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:Yi(typeof t.cwd==="string"?t.cwd:".")}}function Zi(e){let t=Object.keys(X),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=Me(X[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 Qi(e,t){try{let r=await j(process.env,{cwd:e,flags:{}}).modelConfig.resolvedProjectHarness(t);return{harness:r.harness,source:r.source}}catch{return null}}function ea(e,t){let n=t.skills&&t.skills.length>0?{skills:t.skills}:{};if(e.choice!=="cloud")return De(e,{cwd:t.cwd,...n});if(!t.projectId)throw new Z("invalid_usage","The cloud sandbox needs a hlix project. Run `hlix init`, pass --project <id>, or choose --sandbox docker|local.");let o=j(process.env,{cwd:t.cwd,flags:{}}).projects.workspace(t.projectId);return De(e,{cwd:t.cwd,projectId:t.projectId,remote:o})}var lt=".hlix";function ta(e,t,n=(r)=>{try{return Wi(r)}catch{return r}}){let r=new Set,o=[];for(let s of e.skills){if(s.scope!=="project")continue;let l=Hr(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 na(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(`
|
|
45
|
+
`));if(e.project)n.push([`# This project's rules (${Hr(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(`
|
|
46
|
+
`));return n.join(`
|
|
47
|
+
|
|
48
|
+
`)}var ra={boot:on,app:Er,headless:wr,mcp:at,log:st,stdio:{get stdinIsTty(){return process.stdin.isTTY===!0},get stdoutIsTty(){return process.stdout.isTTY===!0}}};function oa(e){if(e.flag===!0)return!0;return Ar(e.configured)===!0}function sa(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 ia(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 nm(e,t=ra){let n=Ji(e),r=sa({print:n.print!==void 0,stdinIsTty:t.stdio?.stdinIsTty??!0,stdoutIsTty:t.stdio?.stdoutIsTty??!0});if(r)return process.stderr.write(`error: ${r}
|
|
49
|
+
`),2;let o=kr(n.cwd,process.env),s=n.project??o.merged.projectId,l=n.print===void 0?(t.log??st)(process.env):null,i=Lr(n.cwd,Rr(process.env),{configDir:lt}),c=Nr({cwd:n.cwd,configDir:lt,env:process.env}),a=new He(oa({...n.yolo!==void 0?{flag:n.yolo}:{},...o.merged.yolo!==void 0?{configured:o.merged.yolo}:{}})),m,d,f;try{if(d=Dt({flag:n.sandbox??o.merged.sandbox,flagSource:n.sandbox?"flag":"config",projectId:s,dockerImage:n.dockerImage??o.merged.dockerImage,dockerAvailable:()=>Ht()}),f=Zi({requested:pt({...n.harness?{flag:n.harness}:{},...o.merged.harness?{configured:o.merged.harness}:{},...o.sources.harness?{configSource:o.sources.harness}:{}}),sandbox:d.choice,installed:(v)=>mt(X[v].command)}),f.refusal)throw new Z("invalid_usage",f.refusal);m=ea(d,{cwd:n.cwd,projectId:s,...d.choice==="cloud"?{}:{skills:ta(i,n.cwd)}})}catch(v){return l?.restore(),process.stderr.write(`error: ${v instanceof Error?v.message:String(v)}
|
|
50
|
+
`),2}if(f.warning)process.stderr.write(`warning: ${f.warning}
|
|
51
|
+
`);if(d.choice==="cloud"){let v=s?await Qi(n.cwd,s):null;if(v&&n.harness&&n.harness!==v.harness)process.stderr.write(`warning: this project runs ${v.harness}. Run \`/harness ${n.harness}\` to make ${n.harness} the project's setting.
|
|
52
|
+
`);f={...f,harness:v??{harness:"unknown",source:s?"the project's setting could not be read":"no project bound"}}}let b=await Et({cwd:n.cwd,env:process.env}),_=vt({cwd:n.cwd,env:process.env,...b.served?{models:b.served.map((v)=>v.id)}:{}}),w=wt({endpoint:_,cloud:d.choice==="cloud",...o.merged.model?{configured:o.merged.model}:{},...o.sources.model?{configuredSource:o.sources.model}:{}});if(w?.notice)process.stderr.write(`warning: ${w.notice}
|
|
53
|
+
`);if(!_)return l?.restore(),process.stderr.write(`error: no hlix credential for this folder — ${Vi}.
|
|
54
|
+
`),2;let C=me(fe(o.merged.memoryTokens)??ue),k=$t(d),ne=$r(i),M=Or(c,n.cwd),P=s?zi(await Xi(n.cwd,s)):"",L=n.print===void 0?await(t.mcp??at)({servers:i.mcpServers,cwd:n.cwd}):it,de=jr(i.generatedCommands,n.cwd),g=Dr(i.instructions,n.cwd),y=na(c,n.cwd),x=[...Pr.flatMap((v)=>[Tr(n.cwd,".claude",v),Tr(n.cwd,lt,v)]),...i.commands.map((v)=>v.path),...de?[de]:[]],S=f.harness.harness==="unknown"?"hlix":f.harness.harness,E;try{E=await t.boot({cwd:n.cwd,env:process.env,sandbox:d.choice,workspace:m,endpoint:_,model:w,harness:S,unavailableHarnesses:f.unavailable,...o.global?.providers?{providers:o.global.providers}:{},...o.merged.memoryTokens?{memoryTokens:o.merged.memoryTokens}:{},hostInstructions:[qi,...d.choice==="cloud"?[gt(f.harness.harness)]:[],...y?[y]:[],...g?[g]:[]].join(`
|
|
55
|
+
|
|
56
|
+
`),mcpTools:L.tools,projectSubagents:i.subagents,extraTools:{...yt({cwd:n.cwd}),hlix_tasks_follow:xt({cwd:n.cwd}),hlix_harness:ht({sandbox:d.choice,sandboxLine:k,available:f.available,modesBuilt:!1,session:()=>null})}})}catch(v){if(l?.restore(),await L.stop(),v instanceof he)return process.stderr.write(`error: ${v.message}
|
|
57
|
+
`),2;return process.stderr.write(`error: ${N} could not start: ${v instanceof Error?v.message:String(v)}
|
|
58
|
+
`),2}try{if(n.print!==void 0)return(await t.headless({session:E.session,prompt:n.print,...n.json?{json:!0}:{},...a.get()?{yolo:!0}:{}})).exitCode;let v={session:E.session,compact:async()=>{let G=E.session.thread.getId();if(!G)return"Nothing to condense yet.";let Pe=await E.memory.omEngine;if(!Pe)return"Observational memory is not running in this session.";return(await Pe.observe({threadId:G,resourceId:_.workspaceId})).observed?"Condensed.":"Nothing new to condense."},facts:{sandbox:d.choice,sandboxLine:k,harness:String(f.harness.harness),availableHarnesses:f.available,harnessModesBuilt:E.harnessModesBuilt},...l?{log:{path:l.path,tail:l.tail}}:{},rules:()=>Mr(c,n.cwd),mcp:()=>L.statusLines,yolo:{get:()=>a.get(),set:(G)=>a.set(G)},...s?{setProjectHarness:async(G)=>{await j(process.env,{cwd:n.cwd,flags:{}}).modelConfig.setProjectHarness(s,G)}}:{}},Re=mr({env:process.env,promptFiles:x,shell:v}),ct=et({...b.served?{served:b.served}:{},userModelIds:E.gateway.modelIds(),providerName:_.name});return await t.app({session:E.session,cwd:n.cwd,env:process.env,commands:Re,models:ct,bindings:v,yolo:a,notices:aa({rules:M,standards:ne,secrets:P,mcp:L.summary,subagents:E.subagentLine,subagentsSkipped:E.subagentsSkipped,log:l?Ir(l):""}),facts:{sandbox:k.replace(/^sandbox: /,""),harness:ut(f.harness),mode:ia(E.session,q),...w?{model:la(w,ct)}:{},workspace:_.workspaceId,context:{used:0,total:0},memory:_t("",C).replace(/^ · /,""),...a.get()?{yolo:!0}:{},...b.warning?{warning:b.warning}:{}}}),0}finally{await L.stop(),await E.dispose(),l?.restore()}}function aa(e){return[e.rules,e.standards,e.mcp,e.subagents,...e.subagentsSkipped.map((t)=>`subagent not loaded: ${t}`),e.secrets,e.log].filter((t)=>t!=="")}function la(e,t){return t.find((n)=>n.id===e.id)?.label??e.id}export{ia as currentMode,Ji as parseHlixCodeArgs,Zi as planHarness,oa as resolveYolo,na as rulesBlock,nm as runHlixCode,zi as secretsStatusLine,aa as startupNotices,sa as terminalRequirement,ta as workspaceSkillPaths};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import"./index-11raxarr.js";var s="@hlix/cli",i="0.5.0",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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hlix/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "Hlix Code and the hlix control-plane CLI.",
|
|
6
6
|
"keywords": [
|
|
@@ -34,17 +34,20 @@
|
|
|
34
34
|
"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"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@earendil-works/pi-tui": "0.85.1",
|
|
37
38
|
"@mastra/acp": "^0.4.1",
|
|
38
|
-
"@mastra/code-sdk": "1.7.1",
|
|
39
39
|
"@mastra/core": "1.66.0",
|
|
40
40
|
"@mastra/docker": "^0.7.0",
|
|
41
|
+
"@mastra/libsql": "1.22.5",
|
|
42
|
+
"@mastra/mcp": "1.17.3",
|
|
43
|
+
"@mastra/memory": "1.29.0",
|
|
41
44
|
"ignore": "7.0.8",
|
|
42
|
-
"mastracode": "0.39.1",
|
|
43
45
|
"openapi-fetch": "^0.17.0",
|
|
44
46
|
"zod": "4.5.4"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
49
|
"@hlix/sdk": "^0.2.0",
|
|
50
|
+
"@hlix/shared": "*",
|
|
48
51
|
"@types/bun": "latest",
|
|
49
52
|
"typescript": "^7.0.2"
|
|
50
53
|
}
|
package/skills/hlix/SKILL.md
CHANGED
|
@@ -69,8 +69,8 @@ decided it.
|
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
hlix config list [--json] # every setting in effect, and which file set it
|
|
72
|
-
hlix config get <harness|model|sandbox> [--json]
|
|
73
|
-
hlix config set <harness|model|sandbox> <value> [--global] [--json]
|
|
72
|
+
hlix config get <dockerImage|harness|memoryTokens|model|sandbox|yolo> [--json]
|
|
73
|
+
hlix config set <dockerImage|harness|memoryTokens|model|sandbox|yolo> <value> [--global] [--json]
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Two files, one shape, and the folder wins per key: the machine-wide
|
|
@@ -83,7 +83,14 @@ file sets it — and where it applies. The stored credential stays at
|
|
|
83
83
|
`cursor-agent`) and applies to the `local` and `docker` sandboxes only — a
|
|
84
84
|
cloud project's coder is the project's own harness setting on the server.
|
|
85
85
|
`model` is the model the hlix agent starts on; `sandbox` is where its files and
|
|
86
|
-
shell live (`cloud`, `docker`, `local`). `
|
|
86
|
+
shell live (`cloud`, `docker`, `local`). `dockerImage` is the container image
|
|
87
|
+
the `docker` sandbox runs (default `node:22-bookworm`, which carries git, node
|
|
88
|
+
and python3 but no bun) and `--docker-image <ref>` sets it for one session.
|
|
89
|
+
`memoryTokens` is how much of a thread the agent's observational memory holds
|
|
90
|
+
before summarizing — the number the session footer counts against, 200000 by
|
|
91
|
+
default. `yolo` is `true` or `false`: `true` runs every tool — writes, shell
|
|
92
|
+
commands, `hlix_*` calls, MCP tools — without asking for approval, and the
|
|
93
|
+
session footer says `yolo` while it is on. `config set` writes this folder unless
|
|
87
94
|
`--global` is given, and leaves every other key in the file untouched. It
|
|
88
95
|
refuses `projectId`, `workspaceId` and `apiUrl` — those bind a folder to a
|
|
89
96
|
tenant and are written by `init` and `import`.
|
|
@@ -170,6 +177,7 @@ key, which only picks the coder Hlix Code spawns on this machine.
|
|
|
170
177
|
```bash
|
|
171
178
|
hlix status [--json] # workspace, binding, local and cloud drift
|
|
172
179
|
hlix standards [--json] # instruction files, skills, commands, MCP servers and subagents other agent tools left in this folder
|
|
180
|
+
hlix rules [--edit] [--global] [--json] # the rules files the coding agent reads; --edit opens one in $EDITOR
|
|
173
181
|
hlix projects list [--json] # projects in the workspace
|
|
174
182
|
hlix projects get [project-id] [--json]
|
|
175
183
|
hlix init [folder] [--project <id>] [--json] # create committed project configuration; --project binds an existing cloud project
|
|
@@ -293,6 +301,38 @@ document. Read it line by line.
|
|
|
293
301
|
| 2 | Usage error — unknown command, bad flags, missing argument |
|
|
294
302
|
| 3 | Authentication or permission failure |
|
|
295
303
|
|
|
304
|
+
## Hlix Code, non-interactively
|
|
305
|
+
|
|
306
|
+
`hlix` with no command opens the interactive shell. For a script, ask for one
|
|
307
|
+
turn instead:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
hlix -p "<prompt>" [--json] [--yolo] [--sandbox cloud|docker|local] [--cwd <dir>]
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
`-p` takes the rest of the line, so quoting is optional. It prints the agent's
|
|
314
|
+
final text and exits `0`; a turn that was aborted, errored or parked exits `1`.
|
|
315
|
+
`--json` replaces that with one JSON object per line — `message_end` carries
|
|
316
|
+
`role` and `text`, `tool_start` / `tool_end` carry the tool and its call id,
|
|
317
|
+
`usage_update` carries `totalTokens` and `costUsd` when the provider reported a
|
|
318
|
+
price, `subagent_start` / `subagent_end` carry the subagent's type, and the last
|
|
319
|
+
line is `agent_end` with a `reason`. The controller's `display_state_changed`
|
|
320
|
+
snapshots are deliberately NOT emitted: one follows every other event and repeats
|
|
321
|
+
what the typed events already said.
|
|
322
|
+
|
|
323
|
+
A tool that CHANGES something is declined in this mode, because there is no
|
|
324
|
+
terminal to approve it, and the refusal tells the model to say so. Pass `--yolo`
|
|
325
|
+
when the turn is meant to edit files or run commands — `--allow-writes` is the
|
|
326
|
+
older spelling of the same flag and still works. Reads are always allowed.
|
|
327
|
+
|
|
328
|
+
A `-p` run starts no MCP server and does not capture library logging: one prompt
|
|
329
|
+
should not pay for a process per registered server, and a script's only clue when
|
|
330
|
+
something is wrong is what its stderr says.
|
|
331
|
+
|
|
332
|
+
It needs a hlix credential: no workspace means no model, and the command exits
|
|
333
|
+
`2` telling you to run `hlix auth login` rather than reaching for a provider key
|
|
334
|
+
of yours.
|
|
335
|
+
|
|
296
336
|
## Not available
|
|
297
337
|
|
|
298
338
|
- **No execution commands** beyond `cycles create`. Starting a single task is
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import{l as s}from"./index-rraz48fm.js";import"./index-y1n35st0.js";import{chmodSync as r,mkdirSync as i}from"node:fs";import{join as a}from"node:path";import{ONBOARDING_VERSION as c}from"@mastra/code-sdk/onboarding/index";import{getSettingsPath as d,loadSettings as m,saveSettings as p}from"@mastra/code-sdk/onboarding/settings";var g=(e=process.env)=>a(s(e),".hlix","code");function A(e,n){let t=Boolean(e.completedAt??e.skippedAt);return{...e,...t?{}:{skippedAt:n},version:Math.max(e.version,c),quietModePreferenceSelected:!0}}function f(e){let n=g(process.env);i(n,{recursive:!0,mode:448}),process.env.MASTRA_APP_DATA_DIR=n,process.env.MASTRACODE_DISABLE_UPDATE_CHECK="1",process.env.MASTRACODE_UPDATE_LATEST_VERSION=e.version;let t=m();t.onboarding=A(t.onboarding,e.now??new Date().toISOString()),p(t);let o=d();return r(n,448),r(o,384),{dataDir:n,settingsPath:o}}export{f as configureHarnessEnvironment,g as harnessDataDir,A as seedOnboarding};
|