howtofixcli 0.7.15 → 0.7.16

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.
@@ -1 +1 @@
1
- import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h,k as i}from"./chunk-DV2BBBBJ.js";import"./chunk-UTYFLLSM.js";import"./chunk-JMKK26AT.js";import"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";export{b as CLI_REFRESH_SKEW_MS,c as accessTokenIsFresh,g as clearCliCredential,a as cliCredentialsPath,e as readCliCredential,h as refreshCliCredential,d as refreshTokenIsUsable,i as renewCliCredentialIfNeeded,f as writeCliCredential};
1
+ import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h,k as i}from"./chunk-BX5KIC4R.js";import"./chunk-UTYFLLSM.js";import"./chunk-MVTU4M3W.js";import"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";export{b as CLI_REFRESH_SKEW_MS,c as accessTokenIsFresh,g as clearCliCredential,a as cliCredentialsPath,e as readCliCredential,h as refreshCliCredential,d as refreshTokenIsUsable,i as renewCliCredentialIfNeeded,f as writeCliCredential};
@@ -1,2 +1,2 @@
1
- import{b as c,d as l}from"./chunk-27TRKD65.js";import{D as s}from"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import{a as i,b as r}from"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";var d=[["/connect","sign in with your howtofix.id email:password \u2014 no browser needed"],["/model","choose which model answers"],["/help","list every command"],["/quit","leave"]],u=[" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"," \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D"," \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2557 "," \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u255D "," \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u255D \u2588\u2588\u2557\u2588\u2588\u2551 "," \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D "],m=[" _ _ _____ ","| | | | __ __ | ___|","| |_| | \\ \\/ / | |_ ","| _ | > < | _| ","|_| |_| /_/\\_\\ |_| "];function g(){if(process.platform==="win32")return!1;let e=(process.env.LC_ALL||process.env.LC_CTYPE||process.env.LANG||"").toLowerCase();return e===""||e==="c"||e==="posix"||!e.includes("utf-8")&&!e.includes("utf8")?!1:!/ja|ko|zh|_kr|_jp|_cn|_tw|_hk/.test(e)}function h(){return g()?u:m}var _="https://howtofix.id/cli";function p(e){let n=process.env.HOME??"",t=n!==""&&e.startsWith(n)?`~${e.slice(n.length)}`:e,o=t.split("/").filter(Boolean);return o.length>3?`\u2026/${o.slice(-2).join("/")}`:t}function f(e){let n=e.signedIn?d.filter(([t])=>t!=="/connect"):d;return[...h(),"",`${i} ${r} \u2014 a terminal coding agent. Describe the change you want and it reads, edits and runs the code in front of you.`,"",` working in ${p(e.cwd)}`,...e.note?[` session ${e.note}`]:[],"",...e.signedIn?[" already signed in to howtofix.id",""]:[],...n.map(([t,o])=>` ${t.padEnd(11)}${o}`),"",' Or just start typing. Every message goes to the model; anything beginning with "/" stays local.'].join(`
1
+ import{b as c,d as l}from"./chunk-27TRKD65.js";import{D as s}from"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import{a as i,b as r}from"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";var d=[["/connect","sign in with your howtofix.id email:password \u2014 no browser needed"],["/model","choose which model answers"],["/help","list every command"],["/quit","leave"]],u=[" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"," \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D"," \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2557 "," \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u255D "," \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u255D \u2588\u2588\u2557\u2588\u2588\u2551 "," \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D "],m=[" _ _ _____ ","| | | | __ __ | ___|","| |_| | \\ \\/ / | |_ ","| _ | > < | _| ","|_| |_| /_/\\_\\ |_| "];function g(){if(process.platform==="win32")return!1;let e=(process.env.LC_ALL||process.env.LC_CTYPE||process.env.LANG||"").toLowerCase();return e===""||e==="c"||e==="posix"||!e.includes("utf-8")&&!e.includes("utf8")?!1:!/ja|ko|zh|_kr|_jp|_cn|_tw|_hk/.test(e)}function h(){return g()?u:m}var _="https://howtofix.id/cli";function p(e){let n=process.env.HOME??"",t=n!==""&&e.startsWith(n)?`~${e.slice(n.length)}`:e,o=t.split("/").filter(Boolean);return o.length>3?`\u2026/${o.slice(-2).join("/")}`:t}function f(e){let n=e.signedIn?d.filter(([t])=>t!=="/connect"):d;return[...h(),"",`${i} ${r} \u2014 a terminal coding agent. Describe the change you want and it reads, edits and runs the code in front of you.`,"",` working in ${p(e.cwd)}`,...e.note?[` session ${e.note}`]:[],"",...e.signedIn?[" already signed in to howtofix.id",""]:[],...n.map(([t,o])=>` ${t.padEnd(11)}${o}`),"",' Or just start typing. Every message goes to the model; anything beginning with "/" stays local.'].join(`
2
2
  `)}function w(){return[{value:"connect",label:"Sign in to howtofix.id",description:"opens the browser, or paste a key from the panel"},{value:"ready",label:"I have a key \u2014 just give me the prompt",description:"drops you at the prompt; run /connect whenever you like"},{value:"release",label:"What's in this release",description:`opens the ${r} notes in your browser`}]}async function E(e,n,t){c(s).welcomeSeen||(l(s),t(`welcome to ${i}`,f(e)),!e.signedIn&&await new Promise(o=>{n("First run \u2014 how do you want to begin?",w(),a=>{a==="connect"&&e.runSlash("/connect"),a==="release"&&e.openExternal(_),o()},()=>o())}))}export{E as maybeShowWelcome};
@@ -0,0 +1,34 @@
1
+ import{$ as Ne,A as Te,B as $e,D as A,E as G,Ea as Xe,G as M,H as Ee,P as Ae,Pa as Ye,Q as ve,Qa as Ve,R as je,S as Oe,T as Pe,V as Re,W as Ce,Y as De,_ as W,a as C,b as D,ba as Fe,c as ie,ca as Me,d as ae,da as Ie,e as ce,ea as Le,f as le,fa as Ge,g as $,i as de,ia as Ue,j as ue,k as fe,ka as Be,l as me,la as U,m as ge,ma as He,na as We,o as he,p as we,pa as z,q as ye,r as be,s as ke,t as E,ta as ze,u as xe,ua as qe,v as Se,w as L,wa as Ze,x as _e,xa as Ke}from"./chunk-AUDMRGWF.js";import{r as re}from"./chunk-JFYVRWJI.js";import{b as pe}from"./chunk-27TRKD65.js";import{D as k,G as te,r as Q,s as ee}from"./chunk-V656XVXV.js";import{c as ne}from"./chunk-LJEKOS4S.js";import{g as oe,k as se}from"./chunk-BX5KIC4R.js";import"./chunk-UTYFLLSM.js";import"./chunk-MVTU4M3W.js";import{b as I,c as V,d as J}from"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";import{join as _t}from"node:path";import{hostname as Fn}from"node:os";import{createAgentSession as Mn,createCodemodeExtension as In,createMcpExtension as Ln,DefaultResourceLoader as Gn,ProjectTrustStore as Un,SessionManager as B,SettingsManager as Bn}from"@netrodev/hxf-coding-agent";import{existsSync as $t,readFileSync as Et}from"node:fs";import{join as At}from"node:path";var Je=At(k,"APPEND_SYSTEM.md"),vt=["<non-interactive>","This run has no user attached: it was started with --print, and there is nobody to answer a question. Anything that stops and waits for a reply \u2014 `ask`, a confirmation, a skill that resolves a mode by asking which mode to use \u2014 will simply end the run with the task unfinished.","So do not ask. Where an instruction tells you to ask the user and wait, take the default it describes and continue, and say which default you took and why in your final answer. The user reads that answer; they cannot answer mid-run.","Where a skill offers a choice of modes, prefer the one that applies the rules while you work over the one that audits afterwards: this is the mode for building something now, and the audit mode can still be run later by the same person who reads your answer.","</non-interactive>"].join(`
2
+ `),jt=16*1024;function Ot(e){try{if(!$t(e))return;let o=Et(e,"utf8").trim();return!o||Buffer.byteLength(o,"utf8")>jt?void 0:o}catch{return}}function Qe(e,o){let s=[o?e:`${e}
3
+
4
+ ${vt}`],t=Ot(Je);return t&&s.push(`# Standing instructions from ${Je}
5
+ ${t}`),s}function Pt(e){return e.replace(/operating inside hxf, a coding agent harness/gi,"operating as HowToFix, a coding agent harness").replace(/^HowToFix documentation \(read only when the user asks about[^\n]*\):?$/gim,"Harness documentation (internal reference; the user is never told the harness name):").replace(/\bhxf itself\b/gi,"the harness itself").replace(/^- When reading hxf docs or examples/m,"- When reading harness docs or examples").replace(/^- When working on hxf topics/m,"- When working on harness topics").replace(/^- Always read hxf \.md files/m,"- Always read the harness .md files").replace(/\bhxf packages\b/gi,"harness packages").replace(/\bhxf \.md files\b/gi,"harness .md files").replace(/\bhxf docs\b/gi,"harness docs").replace(/^-\s*You can inspect HXF_\* environment variables/m,"- You can inspect the harness's environment variables")}var Rt=["preamble","rules","docs","addendum"];function Ct(e){if(!e)return;let o=!1,s={...e};for(let t of Rt){let n=s[t];if(typeof n!="string")continue;let r=Pt(n);r!==n&&(s[t]=r,o=!0)}return o?s:void 0}function et(){return e=>{e.on("context_with_system",async o=>{let s=o.messages[0];if(!s||s.role!=="system")return;let t=Ct(s.sections);return t?{messages:o.messages.map(r=>r===s?{...s,sections:t}:r)}:void 0})}}var x={hooks:{}},N;function tt(){return e=>{let o=ce(ie);x=o.config,N=void 0,le(),e.on("session_start",async(s,t)=>{for(let a of o.diagnostics)t.ui.notify(`hooks.json: ${a.message}`,"warning");let{outcome:n,ran:r}=await $(x,"SessionStart",{hook_event_name:"SessionStart",cwd:t.cwd},{cwd:t.cwd});n.context&&(N=n.context),n.error&&t.ui.notify(`SessionStart hook: ${n.error}`,"warning"),r&&N&&t.ui.notify(`SessionStart hooks added ${N.length} characters of context`,"info")}),e.on("input",async(s,t)=>{if(!x.hooks.UserPromptSubmit)return;let n={hook_event_name:"UserPromptSubmit",cwd:t.cwd,prompt:s.text},{outcome:r}=await $(x,"UserPromptSubmit",n,{cwd:t.cwd});if(r.error&&t.ui.notify(`UserPromptSubmit hook: ${r.error}`,"warning"),r.block)return t.ui.notify(r.reason??"blocked by a hook","warning"),{action:"handled"};if(r.context)return{action:"transform",text:`${s.text}
6
+
7
+ ${r.context}`}}),e.on("tool_call",async(s,t)=>{if(!x.hooks.PreToolUse)return;let n={hook_event_name:"PreToolUse",cwd:t.cwd,tool_name:s.toolName,tool_input:s.input},{outcome:r}=await $(x,"PreToolUse",n,{cwd:t.cwd});if(r.error&&t.ui.notify(`PreToolUse hook: ${r.error}`,"warning"),r.block)return{block:!0,reason:r.reason??"blocked by a hook"};if(r.updatedInput){let i=e.getAllTools().find(f=>f.name===s.toolName)?.parameters;if(!i)t.ui.notify(`PreToolUse hook rewrote \`${s.toolName}\`, but no schema is known for that tool \u2014 the rewrite was ignored`,"warning");else{let f=ae(i,r.updatedInput);f?t.ui.notify(`PreToolUse hook rewrite ignored \u2014 ${f}`,"warning"):Object.assign(s.input,r.updatedInput)}}}),e.on("tool_result",async(s,t)=>{if(!x.hooks.PostToolUse)return;let n=s.content.map(i=>i.type==="text"?i.text:"").join(`
8
+ `),r={hook_event_name:"PostToolUse",cwd:t.cwd,tool_name:s.toolName,tool_input:s.input,tool_result:n,tool_is_error:s.isError},{outcome:a}=await $(x,"PostToolUse",r,{cwd:t.cwd});if(a.error&&t.ui.notify(`PostToolUse hook: ${a.error}`,"warning"),!!a.context)return{content:[...s.content,{type:"text",text:`
9
+ [hook] ${a.context}`}],structuredContent:s.structuredContent}}),e.on("context_with_system",async s=>{if(!N)return;let t=s.messages[0];if(!t||t.role!=="system")return;let n=`${C(t.content)}
10
+
11
+ ${N}`;return{messages:s.messages.map(a=>a===t?{...t,content:D(t.content,n)}:a)}}),e.on("session_before_compact",async(s,t)=>{if(!x.hooks.PreCompact)return;let{outcome:n}=await $(x,"PreCompact",{hook_event_name:"PreCompact",cwd:t.cwd,compact_reason:s.reason},{cwd:t.cwd});n.error&&t.ui.notify(`PreCompact hook: ${n.error}`,"warning")}),e.on("session_shutdown",async(s,t)=>{if(!x.hooks.SessionEnd)return;let{outcome:n}=await $(x,"SessionEnd",{hook_event_name:"SessionEnd",cwd:t.cwd,reason:s.reason},{cwd:t.cwd});n.error&&t.ui.notify(`SessionEnd hook: ${n.error}`,"warning")}),e.on("agent_settled",async(s,t)=>{if(!x.hooks.Stop)return;let{outcome:n}=await $(x,"Stop",{hook_event_name:"Stop",cwd:t.cwd},{cwd:t.cwd});n.error&&t.ui.notify(`Stop hook: ${n.error}`,"warning")})}}var Dt=new Set(["bash","grep","find","ls","bash_output","powershell"]),Nt=new Set(["bash","bash_output","powershell"]),Ft=40,Mt=12,It=8,ot=6;function Lt(e,o){let s=e.trim();return!!(s===""||/^[-=*_~+#]{3,}$/.test(s)||o!==void 0&&e===o)}function nt(e){return e.replace(/\d+/g,"#").trimEnd()}function Gt(e){let o=[],s=0,t=0;for(;t<e.length;){let n=nt(e[t]);if(n===""||!/\d/.test(e[t])){o.push(e[t]),t+=1;continue}let r=t+1;for(;r<e.length&&nt(e[r])===n&&/\d/.test(e[r]);)r+=1;let a=r-t;if(a>=ot)o.push(e[t]),o.push(` \u2026 ${a-2} more line${a-2===1?"":"s"} of the same shape \u2026`),o.push(e[r-1]),s+=1;else for(let i=t;i<r;i+=1)o.push(e[i]);t=r}return{out:o,collapsed:s}}function Ut(e,o,s={}){if(o?.truncated)return;let t=e.split(`
12
+ `);if(t.length<Ft)return;let n=[],r=0;for(let g=0;g<t.length;g+=1){if(Lt(t[g],n[n.length-1])){if(t[g].trim()===""&&n[n.length-1]?.trim()!==""){n.push("");continue}r+=1;continue}n.push(t[g])}let a=s.toolName===void 0||Nt.has(s.toolName),{out:i,collapsed:f}=a?Gt(n):{out:n,collapsed:0},p=s.head??Mt,u=s.tail??It,c=i,d=0;if(i.length>p+u+ot&&(d=i.length-p-u,c=[...i.slice(0,p),` \u2026 ${d} line${d===1?"":"s"} omitted (${p} kept from the top, ${u} from the end) \u2026`,...i.slice(i.length-u)]),!(r+f===0&&d===0))return{text:c.join(`
13
+ `),stats:{before:t.length,after:c.length,collapsed:f}}}function st(e){return o=>{o.on("tool_result",s=>{if(!e.enabled()||s.isError||!Dt.has(s.toolName))return;let t=s.content.find(i=>i.type==="text");if(!t||t.type!=="text")return;let n=s.details,r=Ut(t.text,n,{toolName:s.toolName});return r?{content:s.content.map(i=>i===t?{type:"text",text:r.text}:i)}:void 0})}}import{readdirSync as Bt,readFileSync as Ht,statSync as Wt}from"node:fs";import{extname as zt,join as rt,relative as qt,resolve as Zt,sep as it}from"node:path";import{Type as P}from"@netrodev/hxf-ai";import{defineTool as Kt}from"@netrodev/hxf-coding-agent";var Xt=new Set(["node_modules",".git","dist","build","out","coverage","vendor","target","__pycache__",".venv","venv",".next",".turbo",".cache"]),v={".ts":{kind:"ts",patterns:[/^\s*export\s+(?:default\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/gm,/^\s*export\s+(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/gm,/^\s*export\s+(?:interface|type)\s+([A-Za-z_$][\w$]*)/gm,/^\s*export\s+const\s+([A-Za-z_$][\w$]*)/gm,/^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/gm,/^\s*(?:export\s+)?class\s+([A-Za-z_$][\w$]*)/gm]},".tsx":{kind:"tsx",patterns:[]},".js":{kind:"js",patterns:[]},".mjs":{kind:"js",patterns:[]},".go":{kind:"go",patterns:[/^func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)/gm,/^type\s+([A-Za-z_]\w*)\s+(?:struct|interface)/gm]},".py":{kind:"py",patterns:[/^(?:async\s+)?def\s+([A-Za-z_]\w*)/gm,/^class\s+([A-Za-z_]\w*)/gm]},".rs":{kind:"rs",patterns:[/^\s*(?:pub\s+)?(?:async\s+)?fn\s+([A-Za-z_]\w*)/gm,/^\s*(?:pub\s+)?(?:struct|enum|trait)\s+([A-Za-z_]\w*)/gm]}};v[".tsx"].patterns=v[".ts"].patterns;v[".js"].patterns=v[".ts"].patterns;v[".mjs"].patterns=v[".ts"].patterns;var Yt=512*1024,Vt=12;function Jt(e,o){let s=v[o];if(!s)return[];let t=new Set,n=[];for(let r of s.patterns){r.lastIndex=0;for(let a of e.matchAll(r)){let i=a[1];i&&!t.has(i)&&(t.add(i),n.push(i))}}return n}function Qt(e,o){let s=new Set,t=n=>{n&&(n.startsWith("./")||n.startsWith("../"))&&s.add(n)};if(o===".ts"||o===".tsx"||o===".js"||o===".mjs"){for(let n of e.matchAll(/(?:from|require\()\s*["']([^"']+)["']/g))t(n[1]);for(let n of e.matchAll(/^\s*import\s+["']([^"']+)["']/gm))t(n[1])}else if(o===".go")for(let n of e.matchAll(/^\s*(?:[\w.]+\s+)?"([^"]+)"/gm))t(n[1]);else if(o===".py")for(let n of e.matchAll(/^\s*from\s+(\.+[\w.]*)\s+import/gm)){let r=n[1].replace(/\./g,"/");t(r.startsWith("/")?`.${r}`:`./${r}`)}else if(o===".rs")for(let n of e.matchAll(/^\s*use\s+(?:crate|super|self)::([\w:]+)/gm))t(`./${n[1].split("::").join("/")}`);return[...s]}function en(e,o,s){let t=e.split("/").slice(0,-1).join("/"),n=rt(t,o).split(it).join("/").replace(/^\.\//,"");return[n,`${n}.ts`,`${n}.tsx`,`${n}.js`,`${n}.mjs`,`${n}.go`,`${n}.py`,`${n}.rs`,`${n}/index.ts`,`${n}/index.tsx`,`${n}/index.js`,`${n}/mod.rs`,`${n}.py`].find(a=>s.has(a))}function tn(e,o="."){let s=[],t=(n,r)=>{if(r>Vt)return;let a;try{a=Bt(n,{withFileTypes:!0})}catch{return}for(let i of a){let f=rt(n,i.name);if(i.isDirectory()){if(Xt.has(i.name)||i.name.startsWith("."))continue;t(f,r+1);continue}let p=zt(i.name);if(v[p])try{if(Wt(f).size>Yt)continue;let u=Ht(f,"utf8"),c=qt(e,f).split(it).join("/");s.push({path:c,symbols:Jt(u,p),imports:Qt(u,p)})}catch{}}};return t(Zt(e,o),0),s}function nn(e,o){if(e.length===0)return[];let s=new Set(e.map(c=>c.path)),t=new Map(e.map((c,d)=>[c.path,d])),n=e.map(()=>[]),r=e.map(()=>[]);e.forEach((c,d)=>{for(let l of c.imports){let g=en(c.path,l,s);if(!g||g===c.path)continue;let b=t.get(g);b!==void 0&&(n[d].push(b),r[b].push(d))}});let a=e.length,i=o?.trim().toLowerCase(),f=e.map(c=>i&&`${c.path} ${c.symbols.join(" ")}`.toLowerCase().includes(i)?4/a:1/a),p=f.reduce((c,d)=>c+d,0),u=e.map((c,d)=>f[d]/p);for(let c=0;c<20;c++){let d=e.map((l,g)=>.15*(f[g]/p));for(let l=0;l<a;l++){if(n[l].length===0){for(let g=0;g<a;g++)d[g]+=.85*u[l]/a;continue}for(let g of n[l])d[g]+=.85*u[l]/n[l].length}u=d}return e.map((c,d)=>({file:c,score:u[d],match:i?`${c.path} ${c.symbols.join(" ")}`.toLowerCase().includes(i):!1})).sort((c,d)=>Number(d.match)-Number(c.match)||d.score-c.score||c.file.path.localeCompare(d.file.path)).map(c=>c.file)}function on(e,o={}){let t=Math.max(200,Math.min(8e3,o.budget??1200))*4,n=nn(e,o.query),r=[],a=0;for(let f of n){let p=f.symbols.slice(0,8).join(", "),u=p?`${f.path}: ${p}`:`${f.path}`;if(a+u.length+1>t)break;r.push(u),a+=u.length+1}if(r.length===0)return"(no source files found)";let i=n.length-r.length;return i>0&&r.push(`\u2026 ${i} more file${i===1?"":"s"} not shown`),r.join(`
14
+ `)}var at;function ct(e){at=e}var lt=Kt({name:"repo_map",label:"repo_map",description:"A ranked outline of the repository: files by importance with their top declarations. Use it to find where something lives before reading files, instead of listing directories.",promptSnippet:"repo_map: ranked file outline of the project",parameters:P.Object({path:P.Optional(P.String({description:"Subdirectory to map, relative to the project root"})),query:P.Optional(P.String({description:"Keyword to bias the ranking, e.g. 'billing'"})),budget:P.Optional(P.Number({description:"Token budget, default 1200"}))}),async execute(e,o){let s=at?.()??process.cwd(),t=tn(s,o.path??".");return{content:[{type:"text",text:on(t,{budget:o.budget,query:o.query})}],details:{files:t.length}}}});function q(){return{consecutiveFailures:0,tripped:!1}}function sn(e,o){return o==="manual"?!1:e.consecutiveFailures>=3}function rn(e,o){if(o)return e;let s=e.consecutiveFailures+1;return{consecutiveFailures:s,tripped:e.tripped||s>=3}}function an(){return q()}function cn(e){return[`Auto-compaction failed ${e.consecutiveFailures} times in a row, so it is switched off for this session.`,"The context is over the limit and compaction cannot recover it. Start a new session, or switch to a model with a larger context window.","Manual /compact is still allowed."].join(" ")}var j=q();function dt(){return e=>{e.on("session_start",async()=>{j=q()}),e.on("session_compact",async()=>{j=an()}),e.on("session_compact_failed",async(o,s)=>{let t=j;j=rn(j,o.aborted),!t.tripped&&j.tripped&&s?.ui&&s.ui.notify(cn(j),"warning")}),e.on("session_before_compact",async o=>{if(sn(j,o.reason))return{cancel:!0}})}}function ln(e){A(M(e))}function pt(e){return`budget exhausted (${e.budget??"default"} continuations)`}function ut(){return e=>{e.on("session_start",async(o,s)=>{ln(s)}),e.on("context_with_system",async(o,s)=>{let t=M(s);if(A(t),!t||t.status!=="active")return;let n=o.messages[0];if(!n||n.role!=="system")return;let r=`${C(n.content)}
15
+
16
+ ${Te(t)}`;return{messages:o.messages.map(i=>i===n?{...n,content:D(n.content,r)}:i)}}),e.on("agent_before_settle",async(o,s)=>{try{let t=M(s);if(A(t),G(t).action==="stop"||!t||o.continue||!o.context.canContinue)return;let n={...t,used:t.used+1};if(e.appendEntry(L,n),A(n),G(n).action==="stop"){let r={...n,status:"done",note:pt(n)};e.appendEntry(L,r),A(r);return}return{entries:[{type:"custom_message",customType:_e,content:$e(n),display:!0}],continue:!0}}catch{return}}),e.on("agent_settled",async(o,s)=>{try{let t=M(s),n=G(t);if(t&&n.action==="stop"&&n.close){let r={...t,status:"done",note:pt(t)};e.appendEntry(L,r),A(r)}else A(t)}catch{return}})}}function dn(e){let o=ee(e);return o.length===0?"":["The user installed the following presets. Their rules apply to this session.","",...o.map(t=>`<preset name="${t.name}">
17
+ ${t.text}
18
+ </preset>`)].join(`
19
+ `)}function ft(e){return o=>{o.on("resources_discover",async()=>{let s=Q(e);return s.length>0?{skillPaths:s}:void 0}),o.on("context_with_system",async s=>{let t=dn(e);if(!t)return;let n=s.messages[0];if(!n||n.role!=="system")return;let r=`${C(n.content)}
20
+
21
+ ${t}`;return{messages:s.messages.map(i=>i===n?{...n,content:D(n.content,r)}:i)}})}}import{Type as w}from"@netrodev/hxf-ai";import{defineTool as pn}from"@netrodev/hxf-coding-agent";function un(){return[...U.values()].map(e=>`${e.name} (${e.description})`).join(", ")}function mt(){return pn({name:"task",label:"task",description:`Spawn subagents. Available: ${un()}. One call can carry tasks[]; each item may set agent, model, effort and isolation. Agents run concurrently, park when done, and can be resumed or messaged with /agents. Pass background: true to return as soon as they start instead of waiting for them. Use architect to design an approach before a large change. Set isolation: "worktree" on every task that writes files.`,promptSnippet:"task: spawn background agents",parameters:w.Object({agent:w.Optional(w.String()),effort:w.Optional(w.String()),model:w.Optional(w.String()),task:w.Optional(w.String()),isolation:w.Optional(w.String()),background:w.Optional(w.Boolean()),tasks:w.Optional(w.Array(w.Object({agent:w.Optional(w.String()),effort:w.Optional(w.String()),model:w.Optional(w.String()),task:w.String(),isolation:w.Optional(w.String())})))}),executionMode:"parallel",async execute(e,o,s,t,n){let r=o.tasks&&o.tasks.length>0?o.tasks.map(l=>({agent:l.agent??o.agent??"task",task:l.task,effort:l.effort??o.effort,model:l.model??o.model,isolation:l.isolation??o.isolation})):[{agent:o.agent??"task",task:o.task??"",effort:o.effort,model:o.model,isolation:o.isolation}],a=r.slice(0,z),i=r.length-a.length,f=!!o.background,p=[],u=[],c=[],d=[];try{for(let m of a){if(!m.task.trim())continue;let _;if(m.isolation==="worktree"){let h=await Xe(n?.cwd??process.cwd(),m.agent);if(h){u.push(h),_=h.path;for(let S of h.skipped)d.push(`${m.agent}:${S}`)}else c.push(m.agent)}p.push(await qe({...m,cwd:n?.cwd,background:f,parentModel:ze(n?.model),worktree:_})),t?.({content:[],details:{agents:p.map(h=>({id:h.id,agent:h.agent,status:h.status}))}})}if(p.length===0)throw new Error("task or tasks is required");let l=i>0?`(only the first ${z} of ${r.length} tasks ran)`:"",g=p.filter(m=>m.worktree).length,b=[l,c.length>0?`isolation: "worktree" was requested but not available for: ${c.join(", ")}. Those agents ran in the shared working tree \u2014 check their edits for collisions before trusting them.`:"",d.length>0?`too large to copy into the isolated worktree, so it was left out: ${d.join(", ")}. An agent that needs it cannot install or build \u2014 treat any "done" from those runs as unverified.`:""].filter(Boolean),y={agents:p.map(m=>({id:m.id,status:m.status,isolated:!!m.worktree}))};if(f){Ze();let m=p.map(_=>`${_.agent}#${_.id}`).join(", ");return{content:[{type:"text",text:`started ${p.length} agent${p.length===1?"":"s"} in the background: ${m}.`+(g>0?` ${g} of them in their own worktree.`:"")+`
22
+ Their results are not part of this turn \u2014 keep working. Read them with /agents, or message one with /agents <id> <text>.`+(b.length>0?`
23
+ ${b.join(`
24
+ `)}`:"")}],details:y}}await Ke(s);let T=p.map(m=>`${We(m)}${m.worktree?" [isolated]":""}
25
+ ${m.result??""}`);return b.length>0&&T.push(b.join(`
26
+ `)),{content:[{type:"text",text:T.join(`
27
+
28
+ `)}],details:y}}finally{for(let l of u)try{await l.remove()}catch{}}}})}import{readFileSync as fn,readdirSync as mn,statSync as gn}from"node:fs";import{dirname as hn,join as Z}from"node:path";import{getAgentDir as wn,parseFrontmatter as yn}from"@netrodev/hxf-coding-agent";var gt=["off","minimal","low","medium","high","xhigh","max"],bn=["name","description","tools","model","effort"],kn=["read","bash","edit","write","grep","find","ls","bash_output","kill_shell","todo","context","goal","task","workflow","web_search","web_fetch","lsp","quality","slop","claim","repo_map"],xn=["read","bash","edit","write","grep","find","ls","context","todo","web_search","web_fetch","lsp","claim"];function Sn(e){let s=(typeof e=="string"?e.split(","):Array.isArray(e)?e:[]).map(t=>String(t).trim().replace(/^["']|["']$/g,"")).filter(Boolean);return s.length>0?s:void 0}function _n(e){try{return gn(e).isDirectory()}catch{return!1}}function Tn(e){let o=e;for(;;){let s=Z(o,".howtofix","agents");if(_n(s))return s;let t=hn(o);if(t===o)return;o=t}}function $n(e){let o=[{scope:"user",dir:Z(wn(),"agents")}],s=Tn(e);return s&&o.push({scope:"project",dir:s}),o}function En(e,o){let s=[],t=[],n=e.replace(/^\uFEFF/,"");if(!/^---\r?\n/.test(n))return{notes:s,problems:[`${o}: no frontmatter \u2014 the file must start with --- and end the block with ---`]};let r={},a="";try{let m=yn(n);r=m.frontmatter??{},a=(m.body??"").trim()}catch(m){return{notes:s,problems:[`${o}: the frontmatter is not readable YAML \u2014 ${m instanceof Error?m.message:String(m)}`]}}for(let m of Object.keys(r))bn.includes(m)||s.push(`${o}: ignoring the unknown frontmatter key '${m}'`);let i=(o.split(/[\\/]/).pop()??o).replace(/\.md$/i,""),f=r.name,p=(typeof f=="string"&&f.trim()?f:i).trim();/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(p)||t.push(`${o}: '${p}' is not a usable agent name \u2014 letters, digits, dot, dash and underscore only`);let u=r.description,c=typeof u=="string"?u.trim():"";c||t.push(`${o}: a description is required \u2014 it is how the model decides to use this agent`),a||t.push(`${o}: no prompt body \u2014 the text below the frontmatter is the agent's standing instruction`);let d=r.effort,l=typeof d=="string"?d.trim().toLowerCase():"";l&&!gt.includes(l)&&t.push(`${o}: effort '${l}' is not one of ${gt.join(", ")}`);let g=Sn(r.tools),b=g??[...xn];if(g){let m=g.filter(_=>!kn.includes(_)&&!_.startsWith("mcp__"));m.length>0&&s.push(`${o}: unknown tool${m.length===1?"":"s"} ${m.join(", ")} \u2014 kept, but nothing registers them yet`)}let y=r.model,T=typeof y=="string"&&y.trim()?y.trim():void 0;return t.length>0?{notes:s,problems:t}:{def:{name:p,description:c,tools:b,prompt:a,effort:l||"medium",model:T,source:o},notes:s,problems:t}}function ht(e,o){let s=[],t=[],n=[],r=[];for(let{scope:a,dir:i}of $n(e)){let f;try{f=mn(i)}catch{continue}for(let p of f.filter(u=>u.toLowerCase().endsWith(".md")).sort()){let u=Z(i,p),c;try{c=fn(u,"utf8")}catch(g){n.push(`${u}: ${g instanceof Error?g.message:String(g)}`);continue}let d=En(c,u);t.push(...d.notes),n.push(...d.problems);let l=d.def;l&&(o.has(l.name)&&t.push(`${u}: replaces ${He.has(l.name)?"the built-in":"an earlier"} '${l.name}'`),o.set(l.name,l),s.push(l),r.includes(a)||r.push(a))}}if(s.length>0){let a=s.filter(i=>o.get(i.name)===i);t.unshift(`loaded ${a.length} subagent definition${a.length===1?"":"s"} (${r.join(" and ")}): ${a.map(i=>i.name).join(", ")}`)}return{loaded:s,notes:t,problems:n}}var An=["grep","find","ls","bash_output","kill_shell"];async function wt(e,{timeoutMs:o=2e3,quietTicks:s=2}={}){let t=Date.now()+o,n=e.getActiveToolNames().length,r=0;for(;Date.now()<t&&r<s;){await new Promise(i=>setTimeout(i,50));let a=e.getActiveToolNames().length;a>n?(n=a,r=0):r+=1}}function yt(e){let o=new Set(e.getActiveToolNames()),s=new Set(e.getAllTools().map(n=>n.name)),t=[];for(let n of An)s.has(n)&&!o.has(n)&&(o.add(n),t.push(n));return t.length>0&&e.setActiveToolsByName([...o]),t}import{spawnSync as vn}from"node:child_process";import{join as jn}from"node:path";import{defineTool as On}from"@netrodev/hxf-coding-agent";var Pn=6e3,bt=On({name:"slop",label:"slop",description:"Check code against the project's slop gate: naming, comments, placeholder values, swallowed errors, and the LLM tells that appear in model-written code. Read-only. Use it before reporting a task finished; it returns each finding as a rule id, a line, and what is wrong, so a claim of clean code becomes something the user can verify. Defaults to the changed files; pass a path to narrow it.",promptSnippet:"slop: naming, comment and placeholder findings for changed code",parameters:E.Object({path:E.Optional(E.String({description:"One file or directory, relative to the project root. Omit to scan the changed set."})),changes:E.Optional(E.Boolean({description:"Scan only files changed against the base ref. Default true when path is omitted."})),base:E.Optional(E.String({description:"Git ref for `changes`. Defaults to HEAD."}))}),async execute(e,o,s,t,n){let r=n.cwd??process.cwd(),i=[jn(r,"scripts","slop.mjs"),"--json"];o.path!==void 0?i.push(o.path):(o.changes??!0)&&i.push("--changes"),o.base!==void 0&&i.push("--base",o.base);let f=vn("node",i,{cwd:r,encoding:"utf8",timeout:12e4}),p;try{p=JSON.parse(f.stdout)}catch{p=void 0}if(!p){let b=(f.stderr||f.stdout||"").trim()||f.error?.message||(f.signal?`killed by ${f.signal} (timed out after 120 s?)`:"no output");return{content:[{type:"text",text:`slop gate produced no report: ${b.slice(0,400)}`}],details:{error:b.slice(0,400)}}}if(p.off)return{content:[{type:"text",text:"slop gate is off"}],details:{off:!0}};let u=p.files??{},c=[],d=0;for(let[b,y]of Object.entries(u)){c.push(`${b}`);for(let T of y)d+=1,c.push(` ${T.rule} L${T.line} ${T.message}`)}if(d===0)return{content:[{type:"text",text:"slop gate: no findings in the scanned files"}],details:{files:Object.keys(u).length,findings:0}};let l=c.join(`
29
+ `).slice(0,Pn),g=l.length<c.join(`
30
+ `).length?`
31
+ \u2026 truncated`:"";return{content:[{type:"text",text:`${d} finding${d===1?"":"s"}:
32
+
33
+ ${l}${g}`}],details:{files:Object.keys(u).length,findings:d}}}});function K(e){return e.extensionRunner.emit({type:"session_shutdown",reason:"quit"}).catch(()=>{}).finally(()=>e.dispose())}import{readdir as kt,rmdir as Rn,stat as Cn,unlink as Dn}from"node:fs/promises";import{dirname as Nn,join as X,resolve as xt}from"node:path";async function St(e={}){let o={removed:[],failed:[],removedDirs:[]},s=X(e.agentDir??k,"sessions"),t=(e.now??Date.now())-Ve*24*60*60*1e3,n=e.keep?xt(e.keep):void 0,r;try{r=await kt(s,{withFileTypes:!0})}catch{return o}for(let a of r){if(!a.isDirectory())continue;let i=X(s,a.name),f;try{f=await kt(i)}catch{continue}let p=f.filter(u=>!u.endsWith(".jsonl"));for(let u of f){if(!u.endsWith(".jsonl"))continue;let c=X(i,u),d;try{n&&xt(c)===n?d=!1:d=(await Cn(c)).mtimeMs<t}catch{d=!1}if(!d){p.push(u);continue}try{await Dn(c),o.removed.push(c)}catch{o.failed.push(c),p.push(u)}}if(p.length===0){if(n&&Nn(n)===i)continue;try{await Rn(i),o.removedDirs.push(i)}catch{}}}return o}var Y="howtofix.build",Ts=["read","repo_map","bash","edit","write","grep","find","ls","bash_output","kill_shell","task","think","ask","claim","sessions","todo","context","goal","enter_plan_mode","exit_plan_mode","workflow","web_search","web_fetch","lsp","quality","compress","slop"],Hn=()=>({exclude:process.platform==="win32"?[]:["powershell"]}),Tt=!1;async function $s(e){let o=new Un(k),s=Bn.create(e.cwd,k,{projectTrusted:o.get(e.cwd)===!0}),t=pe(k).compressToolOutput,n=e.sessionPath?B.open(e.sessionPath):e.noSession?B.inMemory(e.cwd):e.continueSession?B.continueRecent(e.cwd):B.create(e.cwd),r=(()=>{try{let S=n.getEntries().find(F=>F.type==="custom"&&F.customType===Y)?.data?.version;return!S||S===I?void 0:`this session was written by HowToFix ${S}; you are running ${I}`}catch{return}})(),a=new Gn({cwd:e.cwd,agentDir:k,settingsManager:s,appendSystemPrompt:Qe(V,e.interactive??!0),additionalSkillPaths:te(e.cwd),extensionFactories:[Ae(),re(),et(),tt(),Ne(),Pe(),ft(e.cwd),ut(),ve(),dt(),In(),st({enabled:()=>t}),Ln({loadConfig:h=>de({cwd:h.cwd,projectTrusted:h.isProjectTrusted?.()??!1})})]});await a.reload();let i=ht(e.cwd,U),f=mt(),p=n.getSessionId();ct(()=>e.cwd);let u=_t(k,fe);ye({root:()=>e.cwd,holder:()=>`session:${p}`,presenceDir:()=>u,selfId:()=>p});let c=()=>{try{me({dir:u},{id:p,cwd:e.cwd,host:Fn(),pid:process.pid,at:Date.now()})}catch{}};c();let d=setInterval(c,Math.max(5e3,Math.floor(ue/3)));d.unref?.();let l=await Mn({cwd:e.cwd,agentDir:k,settingsManager:s,sessionManager:n,resourceLoader:a,excludeTools:Hn().exclude,customTools:[f,lt,he,we,ke,be,xe,Se,Ee,je,Oe,Ye(),Fe,Me,Le,Ge,bt,Re({state:()=>Ce(W()??"dcp-sessionless"),messages:()=>De(W()??"dcp-sessionless")})],thinkingLevel:e.thinking});await l.session.bindExtensions({mode:"print",onError:()=>{}});let g=oe(k),b=[];if(g){let h=await se(k,g);h.renewed?await l.session.modelRuntime.setRuntimeApiKey("howtofix",h.credential.accessToken):(h.terminal&&h.message||h.message)&&b.push(h.message)}await wt(l.session),yt(l.session);let y=l.session.model;if(e.model){let h=await l.session.modelRuntime.getAvailable(),S=Ue(h,e.model);if(!S)throw await K(l.session),new Error(`unknown model '${e.model}'`);(y?.id!==S.id||y.provider!==S.provider)&&(await l.session.setModel(S),y=l.session.model)}else{let h=await l.session.modelRuntime.getAvailable(),S=new Map,F=[];for(let O of h){let R=S.get(O.provider);R===void 0&&(R=!!(await l.session.modelRuntime.getAuth(O.provider))?.auth?.apiKey,S.set(O.provider,R)),R&&F.push(O)}let H=ne;if(!H.includes(y?.provider??"")){let O=Be(F.filter(R=>H.includes(R.provider)),H);O&&(await l.session.setModel(O),y=l.session.model)}}if(!e.noSession&&n.getEntries().every(h=>h.type!=="custom"||h.customType!==Y))try{n.appendCustomEntry(Y,{version:I})}catch{}Tt||(Tt=!0,St({keep:l.session.sessionFile}).catch(()=>{}));let T=y?`${y.provider}/${y.id}`:"no model",m=!!(y&&y.cost&&(y.cost.input>0||y.cost.output>0)),_=[J(l.modelFallbackMessage),...b,...i.notes,...i.problems].filter(h=>!!h);return y||_.push(`no model configured. run \`howtofix\` and use /login, or edit ${_t(k,"models.json")}`),{session:l.session,dispose:async()=>{Ie(),await K(l.session),clearInterval(d),ge({dir:u},p)},modelLabel:T,priced:m,setCompressToolOutput:h=>{t=h},note:[r,..._].filter(Boolean).join(`
34
+ `)||void 0}}export{Y as BUILD_ENTRY,Ts as MAIN_TOOLS,$s as openSession};
@@ -1,2 +1,2 @@
1
- import{a as x}from"./chunk-UTYFLLSM.js";import{g as P,j as M}from"./chunk-JMKK26AT.js";import{existsSync as z,readFileSync as ye}from"node:fs";import{join as xe}from"node:path";import{createHash as J,randomBytes as G}from"node:crypto";import{createServer as ne}from"node:http";import{execFileSync as X}from"node:child_process";import{createHmac as Q}from"node:crypto";import{readFileSync as ee}from"node:fs";import{arch as N,cpus as $,hostname as O,platform as _,userInfo as H}from"node:os";var te="howtofix-cli-hwid-v1";function v(e){try{let t=ee(e,"utf8").trim();return t.length>0?t:void 0}catch{return}}function F(e,t){try{let r=X(e,t,{encoding:"utf8",timeout:3e3,stdio:["ignore","pipe","ignore"]});return r.trim().length>0?r.trim():void 0}catch{return}}function re(){let e=_();if(e==="linux"){let t=v("/etc/machine-id");if(t)return{value:t,source:"machine-id",strong:!0};let r=v("/var/lib/dbus/machine-id");if(r)return{value:r,source:"dbus-machine-id",strong:!0};let s=v("/sys/class/dmi/id/product_uuid");return s?{value:s,source:"dmi-product-uuid",strong:!0}:void 0}if(e==="win32"){let r=F("reg",["query","HKLM\\SOFTWARE\\Microsoft\\Cryptography","/v","MachineGuid"])?.match(/MachineGuid\s+REG_SZ\s+(\S+)/i);return r?.[1]?{value:r[1],source:"windows-machine-guid",strong:!0}:void 0}if(e==="darwin"){let r=F("ioreg",["-rd1","-c","IOPlatformExpertDevice"])?.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);return r?.[1]?{value:r[1],source:"platform-uuid",strong:!0}:void 0}}function U(){let e=re(),t=e?.value??[O(),_(),N(),H().username].join("\0"),r=e?.source??"hostname";return{id:Q("sha256",te).update(t).digest("hex").slice(0,32),source:r,strong:e?.strong??!1}}function j(e){return[e.id,e.source,O(),_(),N(),H().username,String($().length),$()[0]?.model??""]}var I="https://howtofix.id",se=300*1e3,L=3e3,K="/callback";function A(e){return e.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function oe(){return A(G(32))}function ie(e){return A(J("sha256").update(e).digest())}function ae(){return A(G(16))}var ce="howtofix-cli-",ue="x-howtofix-client",le="cli";function C(e){let t=e??j(U());return ce+J("sha256").update(t.join("\0")).digest("hex").slice(0,32)}function de(){return{"content-type":"application/json",[ue]:le}}var fe=()=>new Promise((e,t)=>{let r=ne();r.once("error",t),r.listen(0,"127.0.0.1",()=>{let{port:s}=r.address();e({port:s,close:()=>r.close(),waitForCode:(o,n)=>new Promise((i,a)=>{let c=(l,m)=>{let h=new URL(l.url??"/","http://127.0.0.1");if(h.pathname!==K){m.writeHead(404).end("not found");return}let y=(V,Z)=>m.writeHead(200,{"content-type":"text/html; charset=utf-8"}).end(`<!doctype html><meta charset="utf-8"><h2>${V}</h2><p>${Z}</p>`),T=h.searchParams.get("error")??"",R=h.searchParams.get("code")??"",Y=h.searchParams.get("state")??"";if(T){y("Sign-in was refused","You can close this tab."),u(new Error(`the browser reported: ${T}`));return}if(!R||Y!==o){y("This callback did not belong to the login","You can close this tab."),u(new Error("the callback carried the wrong state"));return}y("Signed in","You can close this tab and go back to HowToFix."),u(void 0,R)},u=(l,m)=>{r.off("request",c),n?.removeEventListener("abort",f),l?a(l):i(m)},f=()=>u(new Error("cancelled"));n?.addEventListener("abort",f,{once:!0}),r.on("request",c)})})})});function k(e,t){e.onProgress?.(t)}async function g(e,t,r,s){let o=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r),signal:s}),n={};try{n=await o.json()}catch{}let i=Number(o.headers?.get?.("retry-after"));return{status:o.status,body:n,retryAfterSeconds:Number.isFinite(i)&&i>0?i:void 0}}function d(...e){for(let t of e)if(typeof t=="string"&&t.trim()!=="")return t.trim()}function D(...e){for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t;return 0}function me(e){try{let t=new URL(e).searchParams.get("code");return t&&t.trim()!==""?t.trim():void 0}catch{return}}async function pe(e,t,r){let s=await e(t,{headers:de(),signal:r}),o={};try{o=await s.json()}catch{}let n=Number(s.headers?.get?.("retry-after"));return{status:s.status,body:o,retryAfterSeconds:Number.isFinite(n)&&n>0?n:void 0}}function S(e){let t=e.data,r=[e.token,e.api_key,e.apiKey,e.key,t?.token,t?.api_key,t?.apiKey,t?.key];for(let s of r)if(typeof s=="string"&&s.trim().startsWith("sk-"))return s.trim()}function ge(e){let t=e.data,r=d(e.token,t?.token),s=d(e.refresh_token,t?.refresh_token),o=d(e.device_id,t?.device_id);if(!r||!s||!o)return;let n=D(e.access_expires_at,t?.access_expires_at),i=D(e.refresh_expires_at,t?.refresh_expires_at);return{accessToken:r,accessExpiresAt:n,refreshToken:s,deviceId:o,refreshExpiresAt:i}}function p(e,t){let r=e.message??e.error;return typeof r=="string"&&r.trim()?r.trim():t}async function Oe(e){let t=e.fetchImpl??fetch,r=(e.panelUrl??I).replace(/\/+$/,""),s=e.timeoutMs??se,o={...e,panel:r,fetchImpl:t,timeoutMs:s},n=await ke(o);if(n.ok||n.terminal)return n.result;let i=await he(o);if(i.ok||i.terminal)return i.result;let a=await we(o);return a.ok?a:{ok:!1,message:`${n.result.ok?"":n.result.message}; ${i.result.ok?"":i.result.message}; ${a.message}. howtofix.id does not offer a browser login a local client can complete yet \u2014 run /connect and paste a token from ${r}/keys instead.`}}async function he(e){let t=oe(),r=ae(),s;try{s=await(e.loopback??fe)();let o=`http://127.0.0.1:${s.port}${K}`,n=await g(e.fetchImpl,`${e.panel}/api/oauth/device/start`,{redirect_uri:o,code_challenge:ie(t),code_challenge_method:"S256",state:r},e.signal);if(n.status===404)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel has no loopback login endpoint"}};if(n.status>=400)return{ok:!1,terminal:!1,result:{ok:!1,message:p(n.body,`the panel refused the login (${n.status})`)}};let i=typeof n.body.authorize_url=="string"?n.body.authorize_url:"";if(!i)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel did not say where to send the browser"}};k(e,{kind:"browser",url:i});let a=await be(s.waitForCode(r,e.signal),e.timeoutMs),c=await g(e.fetchImpl,`${e.panel}/api/oauth/device/token`,{flow_token:n.body.flow_token,code:a,code_verifier:t},e.signal);if(c.status>=400)return{ok:!1,terminal:!0,result:{ok:!1,message:p(c.body,`the panel refused the exchange (${c.status})`)}};let u=S(c.body);return u?{ok:!0,result:{ok:!0,token:u}}:{ok:!1,terminal:!0,result:{ok:!1,message:"the panel did not return an API key"}}}catch(o){let n=o instanceof Error?o.message:String(o);return{ok:!1,terminal:n==="cancelled",result:{ok:!1,message:n}}}finally{s?.close()}}async function ke(e){let t=e.pollIntervalMs??L,r=e.fingerprintId??C(),s=e.clientInfo??P(),o=M(r,s);try{let n=await g(e.fetchImpl,`${e.panel}/api/auth/cli/code`,{fingerprintId:r,clientInfo:s,...o},e.signal);if(n.status===404)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel has no CLI login endpoint"}};if(n.status===401)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel did not recognise this build as the HowToFix CLI \u2014 update it with `npm install -g howtofixcli@latest`"}};if(n.status===429)return{ok:!1,terminal:!0,result:{ok:!1,message:`too many sign-in attempts from this machine right now.${n.retryAfterSeconds?` Try again in ${Math.ceil(n.retryAfterSeconds/60)} minute(s).`:""}`}};if(n.status>=400)return{ok:!1,terminal:!1,result:{ok:!1,message:p(n.body,`the panel refused the login (${n.status})`)}};let i=n.body.data??{},a=d(n.body.login_url,i.login_url),c=d(n.body.code,i.code)??(a?me(a):void 0),u=d(n.body.secret,i.secret);return!a||!c?{ok:!1,terminal:!1,result:{ok:!1,message:"the panel did not return a login URL"}}:u?(k(e,{kind:"browser",url:a}),await q(e,c,u)):(k(e,{kind:"browser",url:a}),await q(e,c,void 0))}catch(n){let i=n instanceof Error?n.message:String(n);return{ok:!1,terminal:i==="cancelled",result:{ok:!1,message:i}}}}async function q(e,t,r){let s=e.pollIntervalMs??L,o=Date.now()+e.timeoutMs;for(;Date.now()<o;){await w(s,e.signal);let n=new URLSearchParams(r?{code:t,secret:r}:{code:t});n.set("capability","device-refresh");let i=await pe(e.fetchImpl,`${e.panel}/api/auth/cli/status?${n}`,e.signal);if(i.status===404)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel has no CLI login status endpoint"}};if(i.status===403)return{ok:!1,terminal:!0,result:{ok:!1,message:"the panel rejected this poll \u2014 run /connect again"}};if(i.status===429){let u=Math.min(Math.max(i.retryAfterSeconds??5,1)*1e3,3e4);await w(u,e.signal);continue}let a=S(i.body);if(a)return{ok:!0,result:{ok:!0,token:a,credential:ge(i.body)}};if(d(i.body.data?.status,i.body.status)==="expired")return{ok:!1,terminal:!0,result:{ok:!1,message:"the sign-in link expired before it was approved"}};if(i.status>=400)return{ok:!1,terminal:!0,result:{ok:!1,message:p(i.body,`the panel refused the poll (${i.status})`)}}}return{ok:!1,terminal:!0,result:{ok:!1,message:"the sign-in was not approved in time"}}}async function we(e){let t=e.pollIntervalMs??L;try{let r=await g(e.fetchImpl,`${e.panel}/api/oauth/device`,{},e.signal);if(r.status===404)return{ok:!1,message:"the panel has no device-code endpoint"};if(r.status>=400)return{ok:!1,message:p(r.body,`the panel refused the request (${r.status})`)};let s=typeof r.body.device_code=="string"?r.body.device_code:"",o=typeof r.body.user_code=="string"?r.body.user_code:"",n=typeof r.body.verification_uri=="string"?r.body.verification_uri:`${e.panel}/oauth/device`;if(!s||!o)return{ok:!1,message:"the panel did not return a code to show"};k(e,{kind:"code",code:o,url:n});let i=Date.now()+e.timeoutMs;for(;Date.now()<i;){await w(t,e.signal);let a=await g(e.fetchImpl,`${e.panel}/api/oauth/device/poll`,{device_code:s},e.signal);if(a.status===404)return{ok:!1,message:"the panel has no device-code poll endpoint"};let c=typeof a.body.status=="string"?a.body.status:"";if(c==="pending")continue;if(c==="slow_down"){await w(t,e.signal);continue}if(c==="denied")return{ok:!1,message:"the sign-in was refused in the browser"};if(c==="expired")return{ok:!1,message:"the code expired; run /connect again"};let u=S(a.body);if(u)return{ok:!0,token:u};if(a.status>=400)return{ok:!1,message:p(a.body,`the panel refused the poll (${a.status})`)}}return{ok:!1,message:"the code was not approved in time"}}catch(r){return{ok:!1,message:r instanceof Error?r.message:String(r)}}}function be(e,t){return new Promise((r,s)=>{let o=setTimeout(()=>s(new Error("the sign-in was not finished in time")),t);e.then(n=>{clearTimeout(o),r(n)},n=>{clearTimeout(o),s(n)})})}function w(e,t){return new Promise((r,s)=>{let o=setTimeout(r,e);t?.addEventListener("abort",()=>{clearTimeout(o),s(new Error("cancelled"))},{once:!0})})}function b(e){return xe(e,"cli-credentials.json")}var ve=300*1e3;function _e(e,t=Date.now()){return e.accessToken?!Number.isFinite(e.accessExpiresAt)||e.accessExpiresAt<=0?!0:e.accessExpiresAt*1e3-ve>t:!1}function Ie(e,t=Date.now()){return!e.refreshToken||!e.deviceId?!1:!Number.isFinite(e.refreshExpiresAt)||e.refreshExpiresAt<=0?!0:e.refreshExpiresAt*1e3>t}function Je(e){let t=b(e);if(!z(t))return;let r;try{r=JSON.parse(ye(t,"utf8"))}catch{return}if(!r||typeof r!="object"||Array.isArray(r))return;let s=r,o=typeof s.accessToken=="string"?s.accessToken.trim():"",n=typeof s.refreshToken=="string"?s.refreshToken.trim():"",i=typeof s.deviceId=="string"?s.deviceId.trim():"";if(!(!o||!n||!i))return{accessToken:o,accessExpiresAt:W(s.accessExpiresAt),refreshToken:n,deviceId:i,refreshExpiresAt:W(s.refreshExpiresAt)}}function Le(e,t){try{return x(b(e),`${JSON.stringify(t,null,2)}
1
+ import{a as x}from"./chunk-UTYFLLSM.js";import{g as P,j as M}from"./chunk-MVTU4M3W.js";import{existsSync as z,readFileSync as ye}from"node:fs";import{join as xe}from"node:path";import{createHash as J,randomBytes as G}from"node:crypto";import{createServer as ne}from"node:http";import{execFileSync as X}from"node:child_process";import{createHmac as Q}from"node:crypto";import{readFileSync as ee}from"node:fs";import{arch as N,cpus as $,hostname as O,platform as _,userInfo as H}from"node:os";var te="howtofix-cli-hwid-v1";function v(e){try{let t=ee(e,"utf8").trim();return t.length>0?t:void 0}catch{return}}function F(e,t){try{let r=X(e,t,{encoding:"utf8",timeout:3e3,stdio:["ignore","pipe","ignore"]});return r.trim().length>0?r.trim():void 0}catch{return}}function re(){let e=_();if(e==="linux"){let t=v("/etc/machine-id");if(t)return{value:t,source:"machine-id",strong:!0};let r=v("/var/lib/dbus/machine-id");if(r)return{value:r,source:"dbus-machine-id",strong:!0};let s=v("/sys/class/dmi/id/product_uuid");return s?{value:s,source:"dmi-product-uuid",strong:!0}:void 0}if(e==="win32"){let r=F("reg",["query","HKLM\\SOFTWARE\\Microsoft\\Cryptography","/v","MachineGuid"])?.match(/MachineGuid\s+REG_SZ\s+(\S+)/i);return r?.[1]?{value:r[1],source:"windows-machine-guid",strong:!0}:void 0}if(e==="darwin"){let r=F("ioreg",["-rd1","-c","IOPlatformExpertDevice"])?.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);return r?.[1]?{value:r[1],source:"platform-uuid",strong:!0}:void 0}}function U(){let e=re(),t=e?.value??[O(),_(),N(),H().username].join("\0"),r=e?.source??"hostname";return{id:Q("sha256",te).update(t).digest("hex").slice(0,32),source:r,strong:e?.strong??!1}}function j(e){return[e.id,e.source,O(),_(),N(),H().username,String($().length),$()[0]?.model??""]}var I="https://howtofix.id",se=300*1e3,L=3e3,K="/callback";function A(e){return e.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function oe(){return A(G(32))}function ie(e){return A(J("sha256").update(e).digest())}function ae(){return A(G(16))}var ce="howtofix-cli-",ue="x-howtofix-client",le="cli";function C(e){let t=e??j(U());return ce+J("sha256").update(t.join("\0")).digest("hex").slice(0,32)}function de(){return{"content-type":"application/json",[ue]:le}}var fe=()=>new Promise((e,t)=>{let r=ne();r.once("error",t),r.listen(0,"127.0.0.1",()=>{let{port:s}=r.address();e({port:s,close:()=>r.close(),waitForCode:(o,n)=>new Promise((i,a)=>{let c=(l,m)=>{let h=new URL(l.url??"/","http://127.0.0.1");if(h.pathname!==K){m.writeHead(404).end("not found");return}let y=(V,Z)=>m.writeHead(200,{"content-type":"text/html; charset=utf-8"}).end(`<!doctype html><meta charset="utf-8"><h2>${V}</h2><p>${Z}</p>`),T=h.searchParams.get("error")??"",R=h.searchParams.get("code")??"",Y=h.searchParams.get("state")??"";if(T){y("Sign-in was refused","You can close this tab."),u(new Error(`the browser reported: ${T}`));return}if(!R||Y!==o){y("This callback did not belong to the login","You can close this tab."),u(new Error("the callback carried the wrong state"));return}y("Signed in","You can close this tab and go back to HowToFix."),u(void 0,R)},u=(l,m)=>{r.off("request",c),n?.removeEventListener("abort",f),l?a(l):i(m)},f=()=>u(new Error("cancelled"));n?.addEventListener("abort",f,{once:!0}),r.on("request",c)})})})});function k(e,t){e.onProgress?.(t)}async function g(e,t,r,s){let o=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r),signal:s}),n={};try{n=await o.json()}catch{}let i=Number(o.headers?.get?.("retry-after"));return{status:o.status,body:n,retryAfterSeconds:Number.isFinite(i)&&i>0?i:void 0}}function d(...e){for(let t of e)if(typeof t=="string"&&t.trim()!=="")return t.trim()}function D(...e){for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t;return 0}function me(e){try{let t=new URL(e).searchParams.get("code");return t&&t.trim()!==""?t.trim():void 0}catch{return}}async function pe(e,t,r){let s=await e(t,{headers:de(),signal:r}),o={};try{o=await s.json()}catch{}let n=Number(s.headers?.get?.("retry-after"));return{status:s.status,body:o,retryAfterSeconds:Number.isFinite(n)&&n>0?n:void 0}}function S(e){let t=e.data,r=[e.token,e.api_key,e.apiKey,e.key,t?.token,t?.api_key,t?.apiKey,t?.key];for(let s of r)if(typeof s=="string"&&s.trim().startsWith("sk-"))return s.trim()}function ge(e){let t=e.data,r=d(e.token,t?.token),s=d(e.refresh_token,t?.refresh_token),o=d(e.device_id,t?.device_id);if(!r||!s||!o)return;let n=D(e.access_expires_at,t?.access_expires_at),i=D(e.refresh_expires_at,t?.refresh_expires_at);return{accessToken:r,accessExpiresAt:n,refreshToken:s,deviceId:o,refreshExpiresAt:i}}function p(e,t){let r=e.message??e.error;return typeof r=="string"&&r.trim()?r.trim():t}async function Oe(e){let t=e.fetchImpl??fetch,r=(e.panelUrl??I).replace(/\/+$/,""),s=e.timeoutMs??se,o={...e,panel:r,fetchImpl:t,timeoutMs:s},n=await ke(o);if(n.ok||n.terminal)return n.result;let i=await he(o);if(i.ok||i.terminal)return i.result;let a=await we(o);return a.ok?a:{ok:!1,message:`${n.result.ok?"":n.result.message}; ${i.result.ok?"":i.result.message}; ${a.message}. howtofix.id does not offer a browser login a local client can complete yet \u2014 run /connect and paste a token from ${r}/keys instead.`}}async function he(e){let t=oe(),r=ae(),s;try{s=await(e.loopback??fe)();let o=`http://127.0.0.1:${s.port}${K}`,n=await g(e.fetchImpl,`${e.panel}/api/oauth/device/start`,{redirect_uri:o,code_challenge:ie(t),code_challenge_method:"S256",state:r},e.signal);if(n.status===404)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel has no loopback login endpoint"}};if(n.status>=400)return{ok:!1,terminal:!1,result:{ok:!1,message:p(n.body,`the panel refused the login (${n.status})`)}};let i=typeof n.body.authorize_url=="string"?n.body.authorize_url:"";if(!i)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel did not say where to send the browser"}};k(e,{kind:"browser",url:i});let a=await be(s.waitForCode(r,e.signal),e.timeoutMs),c=await g(e.fetchImpl,`${e.panel}/api/oauth/device/token`,{flow_token:n.body.flow_token,code:a,code_verifier:t},e.signal);if(c.status>=400)return{ok:!1,terminal:!0,result:{ok:!1,message:p(c.body,`the panel refused the exchange (${c.status})`)}};let u=S(c.body);return u?{ok:!0,result:{ok:!0,token:u}}:{ok:!1,terminal:!0,result:{ok:!1,message:"the panel did not return an API key"}}}catch(o){let n=o instanceof Error?o.message:String(o);return{ok:!1,terminal:n==="cancelled",result:{ok:!1,message:n}}}finally{s?.close()}}async function ke(e){let t=e.pollIntervalMs??L,r=e.fingerprintId??C(),s=e.clientInfo??P(),o=M(r,s);try{let n=await g(e.fetchImpl,`${e.panel}/api/auth/cli/code`,{fingerprintId:r,clientInfo:s,...o},e.signal);if(n.status===404)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel has no CLI login endpoint"}};if(n.status===401)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel did not recognise this build as the HowToFix CLI \u2014 update it with `npm install -g howtofixcli@latest`"}};if(n.status===429)return{ok:!1,terminal:!0,result:{ok:!1,message:`too many sign-in attempts from this machine right now.${n.retryAfterSeconds?` Try again in ${Math.ceil(n.retryAfterSeconds/60)} minute(s).`:""}`}};if(n.status>=400)return{ok:!1,terminal:!1,result:{ok:!1,message:p(n.body,`the panel refused the login (${n.status})`)}};let i=n.body.data??{},a=d(n.body.login_url,i.login_url),c=d(n.body.code,i.code)??(a?me(a):void 0),u=d(n.body.secret,i.secret);return!a||!c?{ok:!1,terminal:!1,result:{ok:!1,message:"the panel did not return a login URL"}}:u?(k(e,{kind:"browser",url:a}),await q(e,c,u)):(k(e,{kind:"browser",url:a}),await q(e,c,void 0))}catch(n){let i=n instanceof Error?n.message:String(n);return{ok:!1,terminal:i==="cancelled",result:{ok:!1,message:i}}}}async function q(e,t,r){let s=e.pollIntervalMs??L,o=Date.now()+e.timeoutMs;for(;Date.now()<o;){await w(s,e.signal);let n=new URLSearchParams(r?{code:t,secret:r}:{code:t});n.set("capability","device-refresh");let i=await pe(e.fetchImpl,`${e.panel}/api/auth/cli/status?${n}`,e.signal);if(i.status===404)return{ok:!1,terminal:!1,result:{ok:!1,message:"the panel has no CLI login status endpoint"}};if(i.status===403)return{ok:!1,terminal:!0,result:{ok:!1,message:"the panel rejected this poll \u2014 run /connect again"}};if(i.status===429){let u=Math.min(Math.max(i.retryAfterSeconds??5,1)*1e3,3e4);await w(u,e.signal);continue}let a=S(i.body);if(a)return{ok:!0,result:{ok:!0,token:a,credential:ge(i.body)}};if(d(i.body.data?.status,i.body.status)==="expired")return{ok:!1,terminal:!0,result:{ok:!1,message:"the sign-in link expired before it was approved"}};if(i.status>=400)return{ok:!1,terminal:!0,result:{ok:!1,message:p(i.body,`the panel refused the poll (${i.status})`)}}}return{ok:!1,terminal:!0,result:{ok:!1,message:"the sign-in was not approved in time"}}}async function we(e){let t=e.pollIntervalMs??L;try{let r=await g(e.fetchImpl,`${e.panel}/api/oauth/device`,{},e.signal);if(r.status===404)return{ok:!1,message:"the panel has no device-code endpoint"};if(r.status>=400)return{ok:!1,message:p(r.body,`the panel refused the request (${r.status})`)};let s=typeof r.body.device_code=="string"?r.body.device_code:"",o=typeof r.body.user_code=="string"?r.body.user_code:"",n=typeof r.body.verification_uri=="string"?r.body.verification_uri:`${e.panel}/oauth/device`;if(!s||!o)return{ok:!1,message:"the panel did not return a code to show"};k(e,{kind:"code",code:o,url:n});let i=Date.now()+e.timeoutMs;for(;Date.now()<i;){await w(t,e.signal);let a=await g(e.fetchImpl,`${e.panel}/api/oauth/device/poll`,{device_code:s},e.signal);if(a.status===404)return{ok:!1,message:"the panel has no device-code poll endpoint"};let c=typeof a.body.status=="string"?a.body.status:"";if(c==="pending")continue;if(c==="slow_down"){await w(t,e.signal);continue}if(c==="denied")return{ok:!1,message:"the sign-in was refused in the browser"};if(c==="expired")return{ok:!1,message:"the code expired; run /connect again"};let u=S(a.body);if(u)return{ok:!0,token:u};if(a.status>=400)return{ok:!1,message:p(a.body,`the panel refused the poll (${a.status})`)}}return{ok:!1,message:"the code was not approved in time"}}catch(r){return{ok:!1,message:r instanceof Error?r.message:String(r)}}}function be(e,t){return new Promise((r,s)=>{let o=setTimeout(()=>s(new Error("the sign-in was not finished in time")),t);e.then(n=>{clearTimeout(o),r(n)},n=>{clearTimeout(o),s(n)})})}function w(e,t){return new Promise((r,s)=>{let o=setTimeout(r,e);t?.addEventListener("abort",()=>{clearTimeout(o),s(new Error("cancelled"))},{once:!0})})}function b(e){return xe(e,"cli-credentials.json")}var ve=300*1e3;function _e(e,t=Date.now()){return e.accessToken?!Number.isFinite(e.accessExpiresAt)||e.accessExpiresAt<=0?!0:e.accessExpiresAt*1e3-ve>t:!1}function Ie(e,t=Date.now()){return!e.refreshToken||!e.deviceId?!1:!Number.isFinite(e.refreshExpiresAt)||e.refreshExpiresAt<=0?!0:e.refreshExpiresAt*1e3>t}function Je(e){let t=b(e);if(!z(t))return;let r;try{r=JSON.parse(ye(t,"utf8"))}catch{return}if(!r||typeof r!="object"||Array.isArray(r))return;let s=r,o=typeof s.accessToken=="string"?s.accessToken.trim():"",n=typeof s.refreshToken=="string"?s.refreshToken.trim():"",i=typeof s.deviceId=="string"?s.deviceId.trim():"";if(!(!o||!n||!i))return{accessToken:o,accessExpiresAt:W(s.accessExpiresAt),refreshToken:n,deviceId:i,refreshExpiresAt:W(s.refreshExpiresAt)}}function Le(e,t){try{return x(b(e),`${JSON.stringify(t,null,2)}
2
2
  `,{mode:384}),!0}catch{return!1}}function Ae(e){try{let t=b(e);z(t)&&x(t,"",{mode:384})}catch{}}function W(e){return typeof e=="number"&&Number.isFinite(e)?e:0}async function Ce(e,t){let r=(t?.panelUrl??I).replace(/\/+$/,""),s=t?.fetchImpl??fetch,o=t?.timeoutMs??15e3,n=new AbortController,i=setTimeout(()=>n.abort(),o);try{let a=await s(`${r}/api/auth/cli/refresh`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({device_id:e.deviceId,refresh_token:e.refreshToken,fingerprint_id:C()}),signal:n.signal}),c=await a.json().catch(()=>({}));if(a.status===401||a.status===403)return{ok:!1,terminal:!0,message:"this sign-in is no longer valid \u2014 run /connect to sign in again"};if(!a.ok)return{ok:!1,terminal:!1,message:`the panel refused the renewal (${a.status})`};let u=c.data??{},f=E(c.token,u.token),l=E(c.refresh_token,u.refresh_token),m=E(c.device_id,u.device_id)??e.deviceId;return!f||!l?{ok:!1,terminal:!1,message:"the panel did not return a renewed credential"}:{ok:!0,terminal:!1,credential:{accessToken:f,accessExpiresAt:B(c.access_expires_at,u.access_expires_at),refreshToken:l,deviceId:m,refreshExpiresAt:B(c.refresh_expires_at,u.refresh_expires_at)}}}catch(a){return{ok:!1,terminal:!1,message:a instanceof Error&&a.name==="AbortError"?`the panel did not answer within ${Math.round(o/1e3)}s`:"could not reach the panel"}}finally{clearTimeout(i)}}function E(...e){for(let t of e)if(typeof t=="string"&&t.trim())return t.trim()}function B(...e){for(let t of e)if(typeof t=="number"&&Number.isFinite(t))return t;return 0}async function Ge(e,t,r){let s=r?.now??Date.now();if(_e(t,s)||!Ie(t,s))return{credential:t,renewed:!1,terminal:!1};let o=await Ce(t,r);if(!o.ok||!o.credential)return o.terminal&&Ae(e),{credential:t,renewed:!1,terminal:o.terminal,message:o.message};let n=Le(e,o.credential);return{credential:o.credential,renewed:!0,terminal:!1,message:n?void 0:`the renewed sign-in could not be saved to ${b(e)}`}}export{I as a,Oe as b,b as c,ve as d,_e as e,Ie as f,Je as g,Le as h,Ae as i,Ce as j,Ge as k};
@@ -1,4 +1,4 @@
1
- var a="HowToFix",o="0.7.15",n=["You are HowToFix, a coding agent. The user wants the fix, not a tour of the problem.",'NEVER report a check you did not run. NEVER state a version, path, result or capability you have not verified \u2014 if you did not check it, say you are unsure. "Not found" is not "impossible": a tool missing from PATH is often installed anyway, and one that is truly absent can usually be installed. Exhaust the real options before calling anything unavailable; when you do report a limit, say plainly what you tried and what you could not do. Unexercised behaviour is not evidence.',"NEVER mention the underlying harness, its vendor or its project name to the user.","Every tool is `read`, `write` or `exec`, and each approval mode auto-approves every tier up to its own: `suggest` runs `read` only, `auto-edit` adds `write`, `full-auto` adds `exec`. A read-only shell command runs in every mode, so inspecting the tree asks nothing.","NEVER aim a command at the filesystem root, a block device or a system account file, and NEVER shut down the host: those are refused in EVERY mode, `full-auto` included, so proposing one wastes the turn. This is not a list of things to avoid \u2014 it is a list of things that will not run.","Lead with the diagnosis in one or two sentences, then change the code. SHOULD prefer the smallest correct change over a rewrite. Name the file and the reason in a short line; do not narrate tool calls.","Fix the problem that was asked for. NEVER add features, refactors, validation, error handling or dependencies nobody requested.","Something reported broken: reproduce it first, confirm the fix after. Cannot reproduce it? Say so \u2014 NEVER edit code and call it fixed.","Tests describe intended behaviour. A failing test means fix the code, not the test: NEVER delete, skip or loosen an assertion to get green, and NEVER re-pin an expected value to whatever the code happens to print.","Anything you cannot settle by reading \u2014 a page, a layout, a screenshot, a CLI, a service, a failure \u2014 run it and look at the result. For a visual task, find a browser the way a real one does: `$PUPPETEER_EXECUTABLE_PATH`, `$CHROME_PATH`, then `which` for google-chrome, chromium and chromium-browser, then /usr/bin, /snap/bin and /var/lib/flatpak, then the puppeteer and playwright caches under the home directory. Still empty? `npx -y puppeteer browsers install chrome`, or `npm i puppeteer-core` against a chrome the image already ships outside PATH. Then drive the real artifact \u2014 open it, read the DOM, click the controls, measure at the widths that matter \u2014 instead of describing what you assume it does.","Done means the requested behaviour works end to end and every stated requirement is met \u2014 not a scaffold, a narrowed test or a plausible subset. Genuinely out of reach? Finish everything else, then say exactly what is missing and what you tried.","SHOULD plan multi-step work with `todo` before starting it, and mark each step done as you finish. A plan the user can see is worth more than a narration of what you are about to do.","Genuinely ambiguous design: enter plan mode, write the plan to the plan file, then present it with `exit_plan_mode`. Use it when several reasonable approaches exist or when a restructuring would be hard to undo. In plan mode `edit` and `write` are refused for every path except the plan file itself \u2014 that limit is enforced, not advisory, so plan the work rather than starting it. Plan mode needs an interactive session in which the user can approve it; when there is no UI it is unavailable, so design the approach yourself instead of calling it.","Work that is independent and would flood this conversation belongs in `task` subagents. Give each a self-contained assignment, then verify the file it wrote rather than trusting its summary. When that work has a shape you can script \u2014 many items through the same stages, or fan-out whose results must be combined \u2014 `workflow` states the orchestration in one place and runs it deterministically; `task` is for the one-off you cannot describe in advance.","MUST give each subagent a self-contained assignment: a child starts with none of this conversation, so a brief that says 'the file we discussed' reaches it as nothing. Choose the agent by what the work is \u2014 scout looks something up, architect returns a plan, reviewer reports issues with file evidence, task changes files \u2014 and NEVER send work that needs an edit to scout or reviewer, because neither can make one.","SHOULD delegate only work that is genuinely parallel: a subagent costs its own session and its own requests on the same quota as this conversation. A single lookup, a file you can read yourself, or a step whose result decides the next step stays here. MUST keep one call to at most six agents and the session to twelve live or parked ones \u2014 a larger fan-out is refused, and the refusal is a limit rather than a failure to work around.","Record a decision, a file's role, or a fact you would otherwise re-derive with `context`: notes survive compaction and are visible to the other agents on the task.","Look it up instead of recalling it: `web_search` and `web_fetch` for anything outside this repo, `lsp` for a definition, reference or diagnostic. Name the source you checked.","Before calling changed code done, run `quality` and `slop` over it and act on what they report. A metric you did not measure is a claim you cannot make.","A command runs under a two-minute default timeout. MUST pass a longer timeout for anything that legitimately takes more than that \u2014 a recursive directory walk, a package install, a build, a network fetch \u2014 and SHOULD prefer a bounded command to an unbounded one: 'du -sh' with an explicit path beats the whole profile, and on Windows/MSYS a recursive 'du' over a profile directory takes minutes rather than seconds.","When a choice blocks the task, use `ask` instead of guessing; when you need to work something out, use `think`, whose text stays out of the transcript.","Above all: NEVER claim a check you did not run, and NEVER call done on a subset."].join(`
1
+ var a="HowToFix",o="0.7.16",n=["You are HowToFix, a coding agent. The user wants the fix, not a tour of the problem.",'NEVER report a check you did not run. NEVER state a version, path, result or capability you have not verified \u2014 if you did not check it, say you are unsure. "Not found" is not "impossible": a tool missing from PATH is often installed anyway, and one that is truly absent can usually be installed. Exhaust the real options before calling anything unavailable; when you do report a limit, say plainly what you tried and what you could not do. Unexercised behaviour is not evidence.',"NEVER mention the underlying harness, its vendor or its project name to the user.","Every tool is `read`, `write` or `exec`, and each approval mode auto-approves every tier up to its own: `suggest` runs `read` only, `auto-edit` adds `write`, `full-auto` adds `exec`. A read-only shell command runs in every mode, so inspecting the tree asks nothing.","NEVER aim a command at the filesystem root, a block device or a system account file, and NEVER shut down the host: those are refused in EVERY mode, `full-auto` included, so proposing one wastes the turn. This is not a list of things to avoid \u2014 it is a list of things that will not run.","Lead with the diagnosis in one or two sentences, then change the code. SHOULD prefer the smallest correct change over a rewrite. Name the file and the reason in a short line; do not narrate tool calls.","Fix the problem that was asked for. NEVER add features, refactors, validation, error handling or dependencies nobody requested.","Something reported broken: reproduce it first, confirm the fix after. Cannot reproduce it? Say so \u2014 NEVER edit code and call it fixed.","Tests describe intended behaviour. A failing test means fix the code, not the test: NEVER delete, skip or loosen an assertion to get green, and NEVER re-pin an expected value to whatever the code happens to print.","Anything you cannot settle by reading \u2014 a page, a layout, a screenshot, a CLI, a service, a failure \u2014 run it and look at the result. For a visual task, find a browser the way a real one does: `$PUPPETEER_EXECUTABLE_PATH`, `$CHROME_PATH`, then `which` for google-chrome, chromium and chromium-browser, then /usr/bin, /snap/bin and /var/lib/flatpak, then the puppeteer and playwright caches under the home directory. Still empty? `npx -y puppeteer browsers install chrome`, or `npm i puppeteer-core` against a chrome the image already ships outside PATH. Then drive the real artifact \u2014 open it, read the DOM, click the controls, measure at the widths that matter \u2014 instead of describing what you assume it does.","Done means the requested behaviour works end to end and every stated requirement is met \u2014 not a scaffold, a narrowed test or a plausible subset. Genuinely out of reach? Finish everything else, then say exactly what is missing and what you tried.","SHOULD plan multi-step work with `todo` before starting it, and mark each step done as you finish. A plan the user can see is worth more than a narration of what you are about to do.","Genuinely ambiguous design: enter plan mode, write the plan to the plan file, then present it with `exit_plan_mode`. Use it when several reasonable approaches exist or when a restructuring would be hard to undo. In plan mode `edit` and `write` are refused for every path except the plan file itself \u2014 that limit is enforced, not advisory, so plan the work rather than starting it. Plan mode needs an interactive session in which the user can approve it; when there is no UI it is unavailable, so design the approach yourself instead of calling it.","Work that is independent and would flood this conversation belongs in `task` subagents. Give each a self-contained assignment, then verify the file it wrote rather than trusting its summary. When that work has a shape you can script \u2014 many items through the same stages, or fan-out whose results must be combined \u2014 `workflow` states the orchestration in one place and runs it deterministically; `task` is for the one-off you cannot describe in advance.","MUST give each subagent a self-contained assignment: a child starts with none of this conversation, so a brief that says 'the file we discussed' reaches it as nothing. Choose the agent by what the work is \u2014 scout looks something up, architect returns a plan, reviewer reports issues with file evidence, task changes files \u2014 and NEVER send work that needs an edit to scout or reviewer, because neither can make one.","SHOULD delegate only work that is genuinely parallel: a subagent costs its own session and its own requests on the same quota as this conversation. A single lookup, a file you can read yourself, or a step whose result decides the next step stays here. MUST keep one call to at most six agents and the session to twelve live or parked ones \u2014 a larger fan-out is refused, and the refusal is a limit rather than a failure to work around.","Record a decision, a file's role, or a fact you would otherwise re-derive with `context`: notes survive compaction and are visible to the other agents on the task.","Look it up instead of recalling it: `web_search` and `web_fetch` for anything outside this repo, `lsp` for a definition, reference or diagnostic. Name the source you checked.","Before calling changed code done, run `quality` and `slop` over it and act on what they report. A metric you did not measure is a claim you cannot make.","A command runs under a two-minute default timeout. MUST pass a longer timeout for anything that legitimately takes more than that \u2014 a recursive directory walk, a package install, a build, a network fetch \u2014 and SHOULD prefer a bounded command to an unbounded one: 'du -sh' with an explicit path beats the whole profile, and on Windows/MSYS a recursive 'du' over a profile directory takes minutes rather than seconds.","When a choice blocks the task, use `ask` instead of guessing; when you need to work something out, use `think`, whose text stays out of the transcript.","Above all: NEVER claim a check you did not run, and NEVER call done on a subset."].join(`
2
2
  `);function s(e){return e===void 0?void 0:e.replace(/Use \/login to log into a provider[^\n]*/gi,"Connect a provider with /connect or /login:").replace(/^[ \t]*\S*hxf-coding-agent[\\/]docs[\\/][^\n]*$/gim,"").replace(/\bhxf-coding-agent\b/gi,"the harness").replace(/\n{3,}/g,`
3
3
 
4
4
  `).trim()}var i=["# Project notes","","## What this is","","## Commands","- build:","- test:","","## Conventions","-",""].join(`
@@ -1,4 +1,4 @@
1
- import{b as k}from"./chunk-AGGIYXN7.js";import{D as p}from"./chunk-V656XVXV.js";import{a as E}from"./chunk-PCALBZOO.js";import"./chunk-UTYFLLSM.js";import{a as g}from"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";import{spawnSync as A}from"node:child_process";import{readdirSync as j,readFileSync as S,statSync as D,writeFileSync as C,unlinkSync as v}from"node:fs";import{join as m}from"node:path";var x=[22,19];async function J(e="https://api.howtofix.id/api/status"){let s=[],[n,t]=process.versions.node.split(".").map(Number),r=n>x[0]||n===x[0]&&t>=x[1];s.push({name:"node",ok:r,detail:`${process.versions.node} (needs >= ${x[0]}.${x[1]})`});let a=A("git",["--version"],{encoding:"utf8"});s.push({name:"git",ok:a.status===0,detail:a.status===0?a.stdout.trim():"not found on PATH"});let o=E();s.push({name:"sandbox",ok:!!o,detail:o??"no working bubblewrap (Linux) or sandbox-exec (macOS); --sandbox unavailable",optional:!0});let c=!1,i=p;try{let l=m(p,`.doctor-${process.pid}`);C(l,"ok"),v(l),c=!0}catch(l){i=`${p} is not writable: ${l instanceof Error?l.message:String(l)}`}s.push({name:"state dir",ok:c,detail:i});let u=m(p,"auth.json"),f="no auth.json \u2014 run `howtofix` and sign in",h=!1;try{let l=JSON.parse(S(u,"utf8")),d=Object.keys(l).length;h=d>0,f=h?`${d} provider credential${d===1?"":"s"}`:f}catch{}s.push({name:"auth",ok:h,detail:f,optional:!0});try{let l=Date.now(),d=await fetch(e,{signal:AbortSignal.timeout(5e3)});s.push({name:"gateway",ok:d.ok,detail:`${e} \u2192 ${d.status} in ${Date.now()-l}ms`,optional:!0})}catch(l){s.push({name:"gateway",ok:!1,detail:`${e} unreachable: ${l instanceof Error?l.message:String(l)}`,optional:!0})}return s}async function Z(){let e=await J(),s=Math.max(...e.map(t=>t.name.length));for(let t of e){let r=t.ok?"ok ":t.optional?"warn":"FAIL";console.log(` ${r} ${t.name.padEnd(s)} ${t.detail}`)}let n=e.filter(t=>!t.ok&&!t.optional);return n.length>0?(console.log(`
1
+ import{b as k}from"./chunk-AGGIYXN7.js";import{D as p}from"./chunk-V656XVXV.js";import{a as E}from"./chunk-PCALBZOO.js";import"./chunk-UTYFLLSM.js";import{a as g}from"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";import{spawnSync as A}from"node:child_process";import{readdirSync as j,readFileSync as S,statSync as D,writeFileSync as C,unlinkSync as v}from"node:fs";import{join as m}from"node:path";var x=[22,19];async function J(e="https://api.howtofix.id/api/status"){let s=[],[n,t]=process.versions.node.split(".").map(Number),r=n>x[0]||n===x[0]&&t>=x[1];s.push({name:"node",ok:r,detail:`${process.versions.node} (needs >= ${x[0]}.${x[1]})`});let a=A("git",["--version"],{encoding:"utf8"});s.push({name:"git",ok:a.status===0,detail:a.status===0?a.stdout.trim():"not found on PATH"});let o=E();s.push({name:"sandbox",ok:!!o,detail:o??"no working bubblewrap (Linux) or sandbox-exec (macOS); --sandbox unavailable",optional:!0});let c=!1,i=p;try{let l=m(p,`.doctor-${process.pid}`);C(l,"ok"),v(l),c=!0}catch(l){i=`${p} is not writable: ${l instanceof Error?l.message:String(l)}`}s.push({name:"state dir",ok:c,detail:i});let u=m(p,"auth.json"),f="no auth.json \u2014 run `howtofix` and sign in",h=!1;try{let l=JSON.parse(S(u,"utf8")),d=Object.keys(l).length;h=d>0,f=h?`${d} provider credential${d===1?"":"s"}`:f}catch{}s.push({name:"auth",ok:h,detail:f,optional:!0});try{let l=Date.now(),d=await fetch(e,{signal:AbortSignal.timeout(5e3)});s.push({name:"gateway",ok:d.ok,detail:`${e} \u2192 ${d.status} in ${Date.now()-l}ms`,optional:!0})}catch(l){s.push({name:"gateway",ok:!1,detail:`${e} unreachable: ${l instanceof Error?l.message:String(l)}`,optional:!0})}return s}async function Z(){let e=await J(),s=Math.max(...e.map(t=>t.name.length));for(let t of e){let r=t.ok?"ok ":t.optional?"warn":"FAIL";console.log(` ${r} ${t.name.padEnd(s)} ${t.detail}`)}let n=e.filter(t=>!t.ok&&!t.optional);return n.length>0?(console.log(`
2
2
  ${n.length} problem${n.length===1?"":"s"} must be fixed before a session will work.`),1):0}function K(e=p){let s=m(e,"models.json"),n;try{n=S(s,"utf8")}catch(o){return o.code==="ENOENT"?console.log(` no models.json at ${s} \u2014 run \`howtofix /connect\` to pull the catalogue`):k(g,"models",o),1}let t;try{t=JSON.parse(n)}catch(o){return console.error(`${g}: models: ${s} is not valid JSON (${o instanceof Error?o.message:String(o)})`),console.error(" fix the file, or delete it and run `howtofix /connect` to write a new one"),1}let r=t.providers??{},a=0;for(let[o,c]of Object.entries(r)){let i=(c.models??[]).map(u=>u.id).filter(Boolean);a+=i.length,console.log(` ${o} (${i.length})`);for(let u of i)console.log(` ${u}`)}return a===0?(console.log(" no models configured"),1):0}function N(e=15,s=p){let n=m(s,"sessions"),t;try{t=j(n)}catch{return[]}let r=[];for(let a of t){let o=m(n,a),c;try{c=j(o)}catch{continue}for(let i of c){if(!i.endsWith(".jsonl"))continue;let u=m(o,i);try{let f=D(u);r.push({file:u,project:a,modified:f.mtimeMs,bytes:f.size})}catch{}}}return r.sort((a,o)=>o.modified-a.modified).slice(0,e)}function Q(e){let s=e.indexOf("--search");if(s>=0){let o=e[s+1]?.trim();if(!o)return console.error(`${g}: sessions: --search needs a word or phrase`),2;let c=P(o);if(c.length===0)return console.log(` no session mentions "${o}"`),0;for(let i of c){let u=new Date(i.row.modified).toISOString().replace("T"," ").slice(0,16),f=`${i.matches} hit${i.matches===1?"":"s"}`;console.log(` ${u} ${i.row.project} (${f})`),console.log(` ${i.row.file}`),console.log(` ${i.snippet}`)}return 0}let n=e.indexOf("--limit"),t=n>=0&&Number(e[n+1])||15,r=N(t);if(r.length===0)return console.log(` no saved sessions under ${m(p,"sessions")}`),e.includes("--export")?1:0;let a=e.indexOf("--export");if(a>=0){let o=Number(e[a+1]);if(!Number.isInteger(o)||o<1||o>r.length)return console.error(`${g}: sessions: --export needs a number from the list (1-${r.length})`),2;let c=r[o-1];try{console.log(_(c.file))}catch(i){return k(g,"sessions",i),1}return 0}return r.forEach((o,c)=>{let i=new Date(o.modified).toISOString().replace("T"," ").slice(0,16),u=Math.round(o.bytes/1024);console.log(` ${String(c+1).padStart(2)} ${i} ${String(u).padStart(6)}k ${o.project}`),console.log(` ${o.file}`)}),0}function R(e){try{let s=JSON.parse(e),n=s.message?.content??s.content;if(typeof n=="string"&&n.trim())return O(n).replace(/\s+/g," ").trim();if(Array.isArray(n)){let t=O(n.map(r=>r&&typeof r=="object"&&"text"in r?String(r.text):"").join(" ")).replace(/\s+/g," ").trim();if(t)return t}}catch{}return O(e).replace(/\s+/g," ").trim()}function O(e){return e.replace(/\u001b\[[0-9;?]*[ -/]*[@-~]|\u001b\][^\u0007]*\u0007|\u001b[@-Z\\-_]/g,"")}function L(e,s,n=80){let t=e.toLowerCase().indexOf(s);if(t<0)return e.slice(0,n*2).trim();let r=Math.max(0,t-n),a=Math.min(e.length,t+s.length+n);return`${r>0?"\u2026":""}${e.slice(r,a).trim()}${a<e.length?"\u2026":""}`}function P(e,s=10,n=p){let t=e.toLowerCase(),r=new RegExp(`\\b${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\b`,"i"),a=[];for(let o of N(Number.MAX_SAFE_INTEGER,n)){let c;try{c=S(o.file,"utf8")}catch{continue}let i=0,u=0,f=0,h=0,l=!1,d="";for(let y of c.split(`
3
3
  `)){let w=y.toLowerCase(),b=w.indexOf(t);if(b<0)continue;let $=0;for(;b>=0;)$++,b=w.indexOf(t,b+t.length);i+=$;let M=w.includes('"role":"user"'),T=w.includes('"role":"toolresult"')||w.includes('"role":"tool"');M?u+=$:T?h+=$:f+=$,r.test(y)&&(l=!0),d||(d=L(R(y),t))}if(i===0)continue;let I=(u>0?100:0)+(f>0?10:0)+Math.min(h,5)+(l?5:0)+Math.min(i,10)/100;a.push({row:o,matches:i,score:I,snippet:d})}return a.sort((o,c)=>c.score-o.score||c.row.modified-o.row.modified).slice(0,s)}function _(e){let s=[`# Session ${e.split(/[\\/]/).pop()??e}`,""];for(let n of S(e,"utf8").split(`
4
4
  `)){if(!n.trim())continue;let t;try{t=JSON.parse(n)}catch{continue}if(t.type!=="message")continue;let r=R(n);r&&s.push(`## ${t.message?.role??"unknown"}`,"",r,"")}return s.join(`
@@ -1,4 +1,4 @@
1
- import{a as y}from"./chunk-UTYFLLSM.js";import{h as k,i as T}from"./chunk-JMKK26AT.js";import{existsSync as L,mkdirSync as $,readFileSync as b}from"node:fs";import{join as M}from"node:path";var F="https://models.dev/api.json";var O=["anthropic","openai","google","deepseek","zai","xai","moonshotai","minimax","alibaba","xiaomi","meta","tencent","nvidia","venice","openrouter"];function x(n){return n.toLowerCase().replace(/[^a-z0-9]+/g,"")}function S(n){let r=n.split("/");return x(r[r.length-1]??n)}function W(n){let r=new Map,o=new Map;if(!n||typeof n!="object")return r;let t=n,s=i=>{let e=O.indexOf(i);return e===-1?O.length:e};for(let i of Object.keys(t).sort()){let e=t[i]?.models;if(!(!e||typeof e!="object"))for(let a of Object.keys(e)){let c=e[a],u=Number(c?.limit?.context);if(!Number.isFinite(u)||u<=0)continue;let l=x(a),d=s(i),m=o.get(l);if(m!==void 0&&m<=d)continue;let f=Number(c?.limit?.output);r.set(l,{contextWindow:Math.floor(u),maxTokens:Number.isFinite(f)&&f>0?Math.floor(f):void 0,reasoning:c?.reasoning===!0,vision:Array.isArray(c?.modalities?.input)&&c.modalities.input.includes("image")}),o.set(l,d)}}return r}function A(n,r){let o=x(r);if(!o)return;let t=n.get(o);if(t)return t;let s=S(r);for(let[i,e]of n)if(S(i)===s)return e;for(let[i,e]of n)if(i.endsWith(o)||o.endsWith(i))return e}function v(n){return`${n}/models-dev-cache.json`}function N(n){let r={};for(let[o,t]of n)r[o]=[t.contextWindow,t.maxTokens??0,t.reasoning?1:0,t.vision?1:0];return JSON.stringify(r)}function R(n){let r=new Map,o;try{o=JSON.parse(n)}catch{return r}if(!o||typeof o!="object")return r;for(let[t,s]of Object.entries(o)){if(!Array.isArray(s)||s.length<3)continue;let i=Number(s[0]),e=Number(s[1]);!Number.isFinite(i)||i<=0||r.set(t,{contextWindow:Math.floor(i),maxTokens:Number.isFinite(e)&&e>0?Math.floor(e):void 0,reasoning:s[2]===1||s[2]===!0,vision:s[3]===1||s[3]===!0})}return r}async function I(n){let r=n?.url??F,o=n?.fetchImpl??fetch,t=n?.timeoutMs??2e4,s=new AbortController,i=setTimeout(()=>s.abort(),t);try{let e=await o(r,{signal:s.signal,headers:{Accept:"application/json"}});if(!e.ok)return{ok:!1,message:`the model catalogue answered ${e.status}`};let a=W(await e.json());return a.size===0?{ok:!1,message:"the model catalogue was empty or in an unexpected shape"}:{ok:!0,index:a}}catch(e){return{ok:!1,message:e instanceof Error&&e.name==="AbortError"?`the model catalogue did not answer within ${Math.round(t/1e3)}s`:"could not reach the model catalogue"}}finally{clearTimeout(i)}}var _="https://api.howtofix.id/v1",ne="https://howtofix.id/keys",C=["howtofix","howtofix-free"];function re(n){try{let o=JSON.parse(b(M(n,"models.json"),"utf8")).providers;return!o||typeof o!="object"?new Set:new Set(Object.keys(o))}catch{return new Set}}function oe(){return{baseUrl:_,api:"openai-completions",headers:{[k]:T()}}}function se(n){let r=M(n,"models.json"),o;try{o=JSON.parse(b(r,"utf8"))}catch{return 0}let t=o.providers;if(!t||typeof t!="object")return 0;let s=0;for(let i of C){let e=t[i];if(!e||!Array.isArray(e.models))continue;let a=X(e.models),c={...e.headers??{},[k]:T()},u=e.headers?.[k]!==c[k];a.changed===0&&!u||(e.models=a.models,e.headers=c,s+=a.changed===0?1:a.changed)}if(s===0)return 0;try{y(r,`${JSON.stringify(o,null,2)}
1
+ import{a as y}from"./chunk-UTYFLLSM.js";import{h as k,i as T}from"./chunk-MVTU4M3W.js";import{existsSync as L,mkdirSync as $,readFileSync as b}from"node:fs";import{join as M}from"node:path";var F="https://models.dev/api.json";var O=["anthropic","openai","google","deepseek","zai","xai","moonshotai","minimax","alibaba","xiaomi","meta","tencent","nvidia","venice","openrouter"];function x(n){return n.toLowerCase().replace(/[^a-z0-9]+/g,"")}function S(n){let r=n.split("/");return x(r[r.length-1]??n)}function W(n){let r=new Map,o=new Map;if(!n||typeof n!="object")return r;let t=n,s=i=>{let e=O.indexOf(i);return e===-1?O.length:e};for(let i of Object.keys(t).sort()){let e=t[i]?.models;if(!(!e||typeof e!="object"))for(let a of Object.keys(e)){let c=e[a],u=Number(c?.limit?.context);if(!Number.isFinite(u)||u<=0)continue;let l=x(a),d=s(i),m=o.get(l);if(m!==void 0&&m<=d)continue;let f=Number(c?.limit?.output);r.set(l,{contextWindow:Math.floor(u),maxTokens:Number.isFinite(f)&&f>0?Math.floor(f):void 0,reasoning:c?.reasoning===!0,vision:Array.isArray(c?.modalities?.input)&&c.modalities.input.includes("image")}),o.set(l,d)}}return r}function A(n,r){let o=x(r);if(!o)return;let t=n.get(o);if(t)return t;let s=S(r);for(let[i,e]of n)if(S(i)===s)return e;for(let[i,e]of n)if(i.endsWith(o)||o.endsWith(i))return e}function v(n){return`${n}/models-dev-cache.json`}function N(n){let r={};for(let[o,t]of n)r[o]=[t.contextWindow,t.maxTokens??0,t.reasoning?1:0,t.vision?1:0];return JSON.stringify(r)}function R(n){let r=new Map,o;try{o=JSON.parse(n)}catch{return r}if(!o||typeof o!="object")return r;for(let[t,s]of Object.entries(o)){if(!Array.isArray(s)||s.length<3)continue;let i=Number(s[0]),e=Number(s[1]);!Number.isFinite(i)||i<=0||r.set(t,{contextWindow:Math.floor(i),maxTokens:Number.isFinite(e)&&e>0?Math.floor(e):void 0,reasoning:s[2]===1||s[2]===!0,vision:s[3]===1||s[3]===!0})}return r}async function I(n){let r=n?.url??F,o=n?.fetchImpl??fetch,t=n?.timeoutMs??2e4,s=new AbortController,i=setTimeout(()=>s.abort(),t);try{let e=await o(r,{signal:s.signal,headers:{Accept:"application/json"}});if(!e.ok)return{ok:!1,message:`the model catalogue answered ${e.status}`};let a=W(await e.json());return a.size===0?{ok:!1,message:"the model catalogue was empty or in an unexpected shape"}:{ok:!0,index:a}}catch(e){return{ok:!1,message:e instanceof Error&&e.name==="AbortError"?`the model catalogue did not answer within ${Math.round(t/1e3)}s`:"could not reach the model catalogue"}}finally{clearTimeout(i)}}var _="https://api.howtofix.id/v1",ne="https://howtofix.id/keys",C=["howtofix","howtofix-free"];function re(n){try{let o=JSON.parse(b(M(n,"models.json"),"utf8")).providers;return!o||typeof o!="object"?new Set:new Set(Object.keys(o))}catch{return new Set}}function oe(){return{baseUrl:_,api:"openai-completions",headers:{[k]:T()}}}function se(n){let r=M(n,"models.json"),o;try{o=JSON.parse(b(r,"utf8"))}catch{return 0}let t=o.providers;if(!t||typeof t!="object")return 0;let s=0;for(let i of C){let e=t[i];if(!e||!Array.isArray(e.models))continue;let a=X(e.models),c={...e.headers??{},[k]:T()},u=e.headers?.[k]!==c[k];a.changed===0&&!u||(e.models=a.models,e.headers=c,s+=a.changed===0?1:a.changed)}if(s===0)return 0;try{y(r,`${JSON.stringify(o,null,2)}
2
2
  `)}catch{return 0}return s}var D=10080*60*1e3;async function j(n,r){let o=v(n),t=r?.now??Date.now(),s,i=0;try{let c=JSON.parse(b(o,"utf8"));typeof c?.entries=="string"&&(s=R(c.entries),i=Number(c.at)||0)}catch{s=void 0}if(s&&s.size>0&&t-i<D&&!r?.force)return{index:s};let a=await I({fetchImpl:r?.fetchImpl});if(!a.ok)return s&&s.size>0?{index:s,message:a.message}:{index:new Map,message:a.message};try{$(n,{recursive:!0}),y(o,`${JSON.stringify({at:t,entries:N(a.index)})}
3
3
  `)}catch{}return{index:a.index}}async function ie(n,r){let o=M(n,"models.json"),t;try{t=JSON.parse(b(o,"utf8"))}catch{return{changed:0}}let s=t.providers;if(!s||typeof s!="object")return{changed:0};let{index:i,message:e}=await j(n,r);if(i.size===0&&!r?.prices)return{changed:0,message:e};let a=0;for(let c of C){let u=s[c];if(!u||!Array.isArray(u.models))continue;let l=B(u.models,i,r?.prices);l.changed!==0&&(u.models=l.models,a+=l.changed)}if(a>0)try{y(o,`${JSON.stringify(t,null,2)}
4
4
  `)}catch{return{changed:0,message:"the models file could not be written"}}return{changed:a,message:e}}var z=3e5;function ae(n){let r=M(n,"settings.json"),o={};try{let t=b(r,"utf8"),s=JSON.parse(t);s&&typeof s=="object"&&!Array.isArray(s)&&(o=s)}catch{if(L(r))return!1}if("httpIdleTimeoutMs"in o)return!1;o.httpIdleTimeoutMs=z;try{$(n,{recursive:!0}),y(r,`${JSON.stringify(o,null,2)}
@@ -1,2 +1,2 @@
1
- import{b as o}from"./chunk-Y7YM5R75.js";import{createPrivateKey as p,createPublicKey as f,createHash as l,randomBytes as y,sign as m}from"node:crypto";import{arch as s,cpus as I,hostname as d,platform as c}from"node:os";var a="hf-cli-1",x="MC4CAQAwBQYDK2VwBCIEIDmKoNgInS7oDpncee1d1+Mnci1R/q4aE5xxHeCKq4Dc",C="howtofix-cli-auth-v1",i;function u(){return i||(i=p({key:Buffer.from(x,"base64"),format:"der",type:"pkcs8"})),i}function g(){return f(u())}function K(t,e,n,r){return Buffer.from([C,t,e,n,r].join(`
1
+ import{b as o}from"./chunk-DVYH677E.js";import{createPrivateKey as p,createPublicKey as f,createHash as l,randomBytes as y,sign as m}from"node:crypto";import{arch as s,cpus as I,hostname as d,platform as c}from"node:os";var a="hf-cli-1",x="MC4CAQAwBQYDK2VwBCIEIDmKoNgInS7oDpncee1d1+Mnci1R/q4aE5xxHeCKq4Dc",C="howtofix-cli-auth-v1",i;function u(){return i||(i=p({key:Buffer.from(x,"base64"),format:"der",type:"pkcs8"})),i}function g(){return f(u())}function K(t,e,n,r){return Buffer.from([C,t,e,n,r].join(`
2
2
  `),"utf8")}function h(){return y(16).toString("hex")}var E="tQ91uspGl0sw5Y8x+soLYnFNX6a9vEzSzCuuvalzdKk=";function P(){let t=g().export({format:"der",type:"spki"});return t.subarray(t.length-32).toString("base64")===E}function N(){let t=g().export({format:"der",type:"spki"});return l("sha256").update(t).digest("hex").slice(0,16)}function $(){let e=(I()[0]?.model??"").replace(/\s+/g," ").trim(),n=d(),r=e?`${n} (${c()}/${s()}, ${e})`:`${n} (${c()}/${s()})`;return`CLI (${o}, ${r})`}var k="X-HowToFix-Client";function A(){return`CLI (${o})`}function B(t,e){let n=h(),r=m(null,K(a,t,e,n),u());return{keyId:a,nonce:n,signature:r.toString("base64")}}export{a,g as b,K as c,h as d,P as e,N as f,$ as g,k as h,A as i,B as j};
@@ -1 +1 @@
1
- import{b as r}from"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";function a(e){return{prompt:s=>e.session.prompt(s),abort:()=>e.session.abort(),subscribe:s=>e.session.subscribe(n=>s(n)),getLastAssistantText:()=>e.session.getLastAssistantText(),lastStopReason:()=>{let s=e.session.state.messages.at(-1);return s?.role==="assistant"?s.stopReason:void 0},dispose:()=>e.dispose()}}async function u(e,s){let{openSession:n}=await import("./chunk-HT3MFLAV.js"),i=t=>n({cwd:t,model:s.model,thinking:s.thinking,continueSession:!1,noSession:!1,sessionPath:void 0,interactive:!1});if(e==="acp"){let{runAcp:t}=await import("./chunk-DAPXGSGD.js");await t({input:process.stdin,output:process.stdout,version:r,createAgent:async d=>a(await i(d))});return}let{runRpc:p}=await import("./chunk-ONZLNFQ2.js"),{jsonLine:c}=await import("./chunk-DOD7MUGX.js"),o=await i(s.cwd);await p({input:process.stdin,output:process.stdout,agent:a(o),encodeEvent:t=>c(t),state:()=>({sessionId:o.session.sessionId,model:o.modelLabel,cwd:s.cwd})})}export{a as agentFromSession,u as serveProtocol};
1
+ import{b as r}from"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";function a(e){return{prompt:s=>e.session.prompt(s),abort:()=>e.session.abort(),subscribe:s=>e.session.subscribe(n=>s(n)),getLastAssistantText:()=>e.session.getLastAssistantText(),lastStopReason:()=>{let s=e.session.state.messages.at(-1);return s?.role==="assistant"?s.stopReason:void 0},dispose:()=>e.dispose()}}async function u(e,s){let{openSession:n}=await import("./chunk-A5WOL324.js"),i=t=>n({cwd:t,model:s.model,thinking:s.thinking,continueSession:!1,noSession:!1,sessionPath:void 0,interactive:!1});if(e==="acp"){let{runAcp:t}=await import("./chunk-DAPXGSGD.js");await t({input:process.stdin,output:process.stdout,version:r,createAgent:async d=>a(await i(d))});return}let{runRpc:p}=await import("./chunk-ONZLNFQ2.js"),{jsonLine:c}=await import("./chunk-DOD7MUGX.js"),o=await i(s.cwd);await p({input:process.stdin,output:process.stdout,agent:a(o),encodeEvent:t=>c(t),state:()=>({sessionId:o.session.sessionId,model:o.modelLabel,cwd:s.cwd})})}export{a as agentFromSession,u as serveProtocol};
@@ -1 +1 @@
1
- import{A,B,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"./chunk-EYWOVCSS.js";import"./chunk-UTYFLLSM.js";import"./chunk-JMKK26AT.js";import"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";export{g as CATALOG_CACHE_TTL_MS,m as DEFAULT_CONTEXT_WINDOW,a as HOWTOFIX_BASE_URL,b as HOWTOFIX_CONSOLE_URL,l as HOWTOFIX_MODEL_COMPAT,c as HOWTOFIX_PROVIDERS,j as HTTP_IDLE_TIMEOUT_MS,r as UNLIMITED_SENTINEL,v as applyCatalog,w as applyCompat,A as checkAccount,s as checkUsage,d as configuredProviderIds,x as countNewModels,k as ensureGatewaySettings,B as fetchGatewayPrices,z as findLiveModels,q as isHowtofixProvider,h as loadCatalog,o as looksLikeToken,n as maskToken,u as mergeModels,e as newProviderEntry,p as parseModelIds,y as probeModel,f as repairGatewayModels,i as repairModelFacts,t as syncGatewayModelsOnStart};
1
+ import{A,B,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"./chunk-LJEKOS4S.js";import"./chunk-UTYFLLSM.js";import"./chunk-MVTU4M3W.js";import"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";export{g as CATALOG_CACHE_TTL_MS,m as DEFAULT_CONTEXT_WINDOW,a as HOWTOFIX_BASE_URL,b as HOWTOFIX_CONSOLE_URL,l as HOWTOFIX_MODEL_COMPAT,c as HOWTOFIX_PROVIDERS,j as HTTP_IDLE_TIMEOUT_MS,r as UNLIMITED_SENTINEL,v as applyCatalog,w as applyCompat,A as checkAccount,s as checkUsage,d as configuredProviderIds,x as countNewModels,k as ensureGatewaySettings,B as fetchGatewayPrices,z as findLiveModels,q as isHowtofixProvider,h as loadCatalog,o as looksLikeToken,n as maskToken,u as mergeModels,e as newProviderEntry,p as parseModelIds,y as probeModel,f as repairGatewayModels,i as repairModelFacts,t as syncGatewayModelsOnStart};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g,h,i,j}from"./chunk-JMKK26AT.js";import"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";export{h as CLI_CLIENT_HEADER,a as CLI_SIGNING_KEY_ID,i as cliClientHeader,c as cliSignaturePayload,f as cliSigningKeyFingerprint,e as cliSigningKeyMatchesPanel,b as cliSigningPublicKey,d as createNonce,g as describeClient,j as signLoginRequest};
1
+ import{a,b,c,d,e,f,g,h,i,j}from"./chunk-MVTU4M3W.js";import"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";export{h as CLI_CLIENT_HEADER,a as CLI_SIGNING_KEY_ID,i as cliClientHeader,c as cliSignaturePayload,f as cliSigningKeyFingerprint,e as cliSigningKeyMatchesPanel,b as cliSigningPublicKey,d as createNonce,g as describeClient,j as signLoginRequest};
@@ -1,4 +1,4 @@
1
- import{b as kr,c as $r}from"./chunk-WX3V5P7U.js";import{a as vr,b as xr}from"./chunk-MOKUBKE7.js";import{a as He}from"./chunk-LSJC73DG.js";import{a as ft,b as dn,c as un,d as Ti,e as pt}from"./chunk-3FYCFLNK.js";import{u as Mi}from"./chunk-WUPU6LTD.js";import{a as Ri}from"./chunk-ORJ2QZBG.js";import{Aa as or,Ba as ir,C as gt,Ca as rr,D as Ki,Da as sr,F as Hi,Fa as ae,Ga as T,Ha as O,I as Bi,Ia as ar,J as Gi,Ja as lr,K as bt,Ka as cr,L as qi,La as dr,M as Vi,Ma as $n,N as zi,Na as ur,O as bn,Oa as fr,Ra as pr,Sa as mr,Ta as hr,U as We,Ua as gr,Va as br,Wa as wr,X as wn,Xa as yr,Z as yn,aa as Ue,c as _i,e as Oi,g as Li,ga as Yi,h as Ni,ha as Ke,ja as wt,n as Di,na as Xi,oa as Ji,qa as Zi,ra as Qi,sa as er,va as tr,w as Wi,y as gn,ya as kn,z as Ui,za as nr}from"./chunk-AUDMRGWF.js";import{a as Ei,c as mt,d as fn,j as Pi,l as pn,m as mn,n as Ii}from"./chunk-JFYVRWJI.js";import{b as ke,c as De,e as Fi,f as hn,g as ji,h as ht}from"./chunk-27TRKD65.js";import{a as ri,b as si}from"./chunk-6FUWMLWO.js";import{A as rn,B as sn,C as ni,D as P,I as oi,J as ii,b as nn,c as at,d as lt,e as Ho,f as Bo,g as Go,h as qo,i as ct,j as Vo,k as on,l as zo,o as ne,p as Yo,q as Xo,t as Jo,u as Zo,v as Qo,w as ei,x as dt,y as ut,z as ti}from"./chunk-V656XVXV.js";import{A as cn,B as wi,b as an,c as ye,d as ci,e as di,h as ui,n as ln,o as fi,q as ie,s as Ae,u as pi,w as mi,x as hi,y as gi,z as bi}from"./chunk-EYWOVCSS.js";import{a as yi,b as ki,c as $i,e as vi,f as xi,g as Si,h as Ci,k as Ai}from"./chunk-DV2BBBBJ.js";import{a as se}from"./chunk-UTYFLLSM.js";import{h as ai,i as li}from"./chunk-JMKK26AT.js";import{a as tn,b as st,e as Ko}from"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";import{execFile as El}from"node:child_process";import{promisify as Pl}from"node:util";import{appendFileSync as Il,existsSync as Et,mkdirSync as Us,readFileSync as Gn,rmSync as _l,writeFileSync as qn}from"node:fs";import{basename as Ol,join as le,resolve as Ll}from"node:path";function Sr(e){if(e==="")return!0;let t=/^\x1b\[(\d+);(\d+)u$/.exec(e);if(t&&Number(t[1])===99&&(Number(t[2])&5)!==0)return!0;let n=/^\x1b\[27;(\d+);(\d+)~$/.exec(e);return!!(n&&Number(n[2])===99&&(Number(n[1])&5)!==0)}function Cr(e){let t=!1;process.on("SIGINT",()=>{t||(t=!0,e())})}function ma(e){if(!e||typeof e!="object")return;let t=e;if(!(typeof t.input!="number"&&typeof t.cacheRead!="number"&&typeof t.cacheWrite!="number"))return t}function ha(e){let t=e?.input??0,n=e?.cacheRead??0,i=e?.cacheWrite??0;return{input:t,cacheRead:n,cacheWrite:i,prompt:t+n+i}}function ga(e){if(typeof e!="string")return null;let t=Date.parse(e);return Number.isNaN(t)?null:t}function ba(e){if(!e||typeof e!="object")return;let t=e,i=(t.message&&typeof t.message=="object"?t.message:void 0)??t,s=ma(i.usage);if(!s)return;let u=typeof i.provider=="string"?i.provider:"",f=typeof i.model=="string"?i.model:"";return{usage:s,model:[u,f].filter(Boolean).join("/")}}function Ar(e){let t=0,n=0,i=[],s=0,u=null;for(let h of e){let w=ba(h);if(!w)continue;let{input:S,cacheRead:M,cacheWrite:j,prompt:W}=ha(w.usage);if(W===0)continue;t+=M,n+=S+j;let K=ga(h.timestamp),I=u,H=I?I.at:null;if(I!==null&&M===0&&S>=1e3){let L=K!==null&&H!==null?Math.max(0,K-H):0;i.push({missedTokens:S,idleMs:L,modelChanged:w.model!==""&&I.model!==""&&w.model!==I.model}),s+=S}u={prompt:W,at:K??H??null,model:w.model}}let f=t+n;return{cachedTokens:t,billedTokens:n,hitRate:f>0?t/f*100:null,misses:i,missedTokens:s}}function Tr(e){return e.modelChanged?"model changed, so its cache had to be built":e.idleMs>=3e5?`cache expired after ${Math.round(e.idleMs/1e3)}s idle`:e.idleMs>0?"prompt changed too early in the prefix to hit":"reason not recorded"}import{copyToClipboard as Nl,SessionManager as Fl}from"@netrodev/hxf-coding-agent";import{CombinedAutocompleteProvider as Ks,Container as jl,Editor as Dl,matchesKey as Y,ProcessTerminal as Wl,ScrollView as Ul,KeybindingsManager as qs,setKeybindings as Vs,TUI_KEYBINDINGS as zs,SelectList as Kl,TuiAltScreen as Hl,truncateToWidth as Re,VStack as Bl,visibleWidth as It,wrapTextWithAnsi as Gl}from"@netrodev/hxf-tui";import{spawn as wa}from"node:child_process";function ya(e,t,n=2e3){return new Promise(i=>{let s=!1,u,f=S=>{s||(s=!0,u!==void 0&&clearTimeout(u),i(S))},h;try{h=wa(e,[...t],{stdio:["ignore","pipe","ignore"]})}catch{f({ok:!1,stdout:""});return}u=setTimeout(()=>{h.kill("SIGKILL"),f({ok:!1,stdout:""})},n);let w=[];h.stdout?.on("data",S=>w.push(S)),h.on("error",()=>f({ok:!1,stdout:""})),h.on("close",S=>{f({ok:S===0,stdout:Buffer.concat(w).toString("utf8")})})})}function vn(){return process.env.XDG_SESSION_TYPE==="wayland"||(process.env.WAYLAND_DISPLAY?.length??0)>0}async function ka(){let e=[];process.platform==="darwin"?e.push({command:"pbpaste",args:[]}):process.platform==="win32"?e.push({command:"powershell.exe",args:["-NoProfile","-Command","Get-Clipboard -Raw"]}):(vn()&&(e.push({command:"wl-paste",args:["--no-newline","--type","text/plain;charset=utf-8"]}),e.push({command:"wl-paste",args:["--no-newline","--type","text/plain"]}),e.push({command:"wl-paste",args:["--no-newline"]})),((process.env.DISPLAY?.length??0)>0||!vn())&&(e.push({command:"xclip",args:["-selection","clipboard","-o"]}),e.push({command:"xsel",args:["--clipboard","--output"]})),e.push({command:"termux-clipboard-get",args:[]}));for(let t of e){let n=await ya(t.command,t.args);if(n.ok&&n.stdout.length>0)return n.stdout}}async function Mr(){let e;try{let{getNativeClipboard:i}=await import("@netrodev/hxf-tui");e=i()}catch{e=void 0}if(e)try{let i=await e.getText();if(typeof i=="string"&&i.length>0)return{ok:!0,text:i}}catch{}let t=await ka();return t!==void 0?{ok:!0,text:t}:{ok:!1,reason:`no clipboard tool could read it \u2014 ${vn()?"install wl-clipboard (wl-paste)":process.platform==="darwin"?"pbpaste should be present on macOS":process.platform==="win32"?"Get-Clipboard should be present on Windows":"install xclip or xsel, or run under a display"}`}}import{TreeSelectorComponent as ql,initTheme as Vl}from"@netrodev/hxf-coding-agent";import{getKeybindings as Hs}from"@netrodev/hxf-tui";import{mixColors as $a,parseColor as va,styleText as de}from"@netrodev/hxf-tui";var ue=process.env.HOWTOFIX_NO_MOTION!=="1",xa=45,Rr=5,Er=8,xn=1e4,Pr=6e4,Ir=3,_r=4,Sn=e=>e<0?0:e>1?1:e;function fe(e,t,n){let i=Sn(n);return i>=1?t:i<=0?e:$a(e,t,i)}var yt=class{value;velocity=0;last=Date.now();target;constructor(t,n=t){this.value=t,this.target=n}set(t){this.target=t}get moving(){return Math.abs(this.target-this.value)>.15}snap(t){this.value=t,this.target=t,this.velocity=0,this.last=Date.now()}step(t=Date.now()){let n=Math.max(0,t-this.last),i=Math.min(250,n)/1e3;if(this.last=t,!ue)return this.value=this.target,this.velocity=0,this.value;n>250&&(this.velocity=0);let s=150,u=2*Math.sqrt(s),f=Math.max(1,Math.ceil(i/.008)),h=i/f;for(let w=0;w<f;w+=1)this.velocity+=(this.target-this.value)*s*h-this.velocity*u*h,this.value+=this.velocity*h;return this.moving||(this.value=this.target,this.velocity=0),this.value}};function Cn(e,t,n,i){return!ue||e<=xn?t:e>=Pr?i:fe(n,i,(e-xn)/(Pr-xn))}function Or(e,t){return!ue||t<=0||e<0?1:1-(1-Sn(e/t))**3}function Lr(e,t){return ue&&e>=0&&e<t}var An=260,Sa=45;function Tn(e,t,n=Sa,i=400){return!ue||n<=0||e<0||e>=i?t:Math.min(t,Math.floor(e/n)+1)}function Nr(e,t,n=Date.now(),i=1400){if(!ue||i<=0)return e;let s=n%i/i;return fe(e,t,s<.5?s*2:(1-s)*2)}function Fr(e,t,n){let i=de(e,{fg:t.rest},ae);if(!ue||e.length===0)return i;let s=Sn(n);if(s>=1)return i;let u=t.band??1,f=e.length+_r*2,w=Math.min(f-1,Math.floor(s*f))-_r,S=H=>{let L=Math.abs(H-w);return L>u?0:1-L/(u+1)},M="",j=0,W=null,K=0,I=0;for(let H of e){let L=S(I);W===null?W=L:L!==W&&(M+=de(e.slice(j,K),{fg:fe(t.rest,t.lit,W)},ae),j=K,W=L),K+=H.length,I+=1}return M+de(e.slice(j),{fg:fe(t.rest,t.lit,W??0)},ae)}function jr(e,t,n=Date.now(),i=90){let s=t[0]??va("#e6e6e6");if(t.length===0||e.length===0)return de(e,{fg:s},ae);if(!ue||i<=0)return de(e,{fg:t[t.length-1]??s},ae);let u=t.length*i,f=(n%u+u)%u,h="",w=0,S=null,M=0,j=0,W=K=>{let I=(f+K*i)/u%1*t.length,H=Math.floor(I)%t.length,L=(H+1)%t.length;return fe(t[H]??s,t[L]??s,I-Math.floor(I))};for(let K of e){let I=W(j);S===null?S=I:I!==S&&(h+=de(e.slice(w,M),{fg:S},ae),w=M,S=I),M+=K.length,j+=1}return h+de(e.slice(w),{fg:S??s},ae)}function Ca(e,t){let n=Math.abs(e-t);return n>=Rr?0:Math.ceil((1-n/Rr)*Ir)/Ir}function Dr(e,t,n=Date.now()){let i=t.charMs??xa;if(!ue||e.length===0||i<=0)return de(e,{fg:t.base},ae);let s=e.length+Er*2,u=n/i%s-Er,f=(W,K)=>de(W,{fg:fe(t.base,t.bright,K)},ae),h="",w=0,S=null,M=0,j=0;for(let W of e){let K=Ca(j,u);S===null?S=K:K!==S&&(h+=f(e.slice(w,M),S),w=M,S=K),M+=W.length,j+=1}return h+f(e.slice(w),S??0)}import{Markdown as Ha,wrapTextWithAnsi as Ba}from"@netrodev/hxf-tui";import{homedir as Aa}from"node:os";import{isAbsolute as Ta,relative as Ma,resolve as Ra,sep as Wr}from"node:path";var Ea="\u25CF",En="\u2514",$t="\u22EF",Mn=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function qe(e=90){let t=Math.floor(Date.now()/e)%Mn.length;return Mn[t]??Mn[0]}var Pa="\u25B2";var Ia="\u25CB",_a=["create_object","set_properties","delete_object","clone_instance","reparent_instance","set_script_source","edit_script_lines","insert_script_lines","execute_luau","generate_mesh","generate_material","generate_procedural_model"];function Pn(e){return e.includes("__")?e.slice(e.lastIndexOf("__")+2):e}function Br(e){return _a.includes(Pn(e))}function Be(e,t=process.cwd()){if(!e||!Ta(e))return e;let n=Ra(e),i=Ma(t,n);if(i==="")return".";if(i&&!i.startsWith(`..${Wr}`)&&i!=="..")return i;let s=Aa();return s&&(n===s||n.startsWith(s+Wr))?`~${n.slice(s.length)}`:n}function oe(e,t){let n=e.replace(/\s+/g," ").trim();return n.length>t?`${n.slice(0,Math.max(1,t-1))}\u2026`:n}function N(e,t){if(e&&typeof e=="object"){let n=e[t];if(typeof n=="string"&&n.length>0)return n;if(typeof n=="number")return String(n)}}function Oa(e,t=160){if(!e||typeof e!="object")return"";try{let n=JSON.stringify(e);return n&&n!=="{}"?oe(n,t):""}catch{return""}}function La(e,t){switch(e){case"read":{let n=Be(N(t,"path")??""),i=[N(t,"offset"),N(t,"limit")].filter(Boolean);return i.length>0?`${n} ${i.length===1?`offset=${i[0]}`:`offset=${i[0]}, limit=${i[1]}`}`:n}case"edit":case"write":return Be(N(t,"path")??"");case"bash":case"powershell":{let n=N(t,"command")??"";return t?.run_in_background===!0?`${n} [background]`:n}case"bash_output":{let n=N(t,"task_id"),i=N(t,"filter");return n?i?`${n} filter=${i}`:n:"all tasks"}case"kill_shell":return N(t,"task_id")??"";case"compress":{let n=N(t,"topic")??"",i=Array.isArray(t.content)?t.content.length:0;return i>1?`${n} (${i} ranges)`:n}case"grep":{let n=N(t,"pattern")??"",i=N(t,"path");return i?`${n} in ${Be(i)}`:n}case"find":case"glob":{let n=N(t,"pattern")??N(t,"glob")??"",i=N(t,"path");return i?`${n} in ${Be(i)}`:n}case"ls":return Be(N(t,"path")??".");case"task":return N(t,"agent")??"task";case"ask":return N(t,"question")??"";case"web_search":return N(t,"query")??"";case"web_fetch":return N(t,"url")??"";case"lsp":{let n=N(t,"action")??"lsp",i=N(t,"file")??"",s=N(t,"line");return s?`${n} ${i}:${s}`:`${n} ${i}`}case"quality":return N(t,"path")??"changed files";case"think":return"private";case"todo":{let n=N(t,"op")??"view",i=N(t,"task"),s=t?.items;return n==="init"&&Array.isArray(s)?`init ${s.length} task${s.length===1?"":"s"}`:i?`${n} ${i}`:n}case"context":{let n=N(t,"op")??"list",i=N(t,"key");return i?`${n} ${i}`:n}case"workflow":{let n=N(t,"path");if(n)return n;let i=N(t,"code")??"",s=/export\s+const\s+meta\s*=\s*\{[\s\S]*?name\s*:\s*["'`]([^"'`]+)/.exec(i)?.[1];if(s)return s;let u=i.trim().split(`
1
+ import{b as kr,c as $r}from"./chunk-WX3V5P7U.js";import{a as vr,b as xr}from"./chunk-MOKUBKE7.js";import{a as He}from"./chunk-LSJC73DG.js";import{a as ft,b as dn,c as un,d as Ti,e as pt}from"./chunk-3FYCFLNK.js";import{u as Mi}from"./chunk-WUPU6LTD.js";import{a as Ri}from"./chunk-ORJ2QZBG.js";import{Aa as or,Ba as ir,C as gt,Ca as rr,D as Ki,Da as sr,F as Hi,Fa as ae,Ga as T,Ha as O,I as Bi,Ia as ar,J as Gi,Ja as lr,K as bt,Ka as cr,L as qi,La as dr,M as Vi,Ma as $n,N as zi,Na as ur,O as bn,Oa as fr,Ra as pr,Sa as mr,Ta as hr,U as We,Ua as gr,Va as br,Wa as wr,X as wn,Xa as yr,Z as yn,aa as Ue,c as _i,e as Oi,g as Li,ga as Yi,h as Ni,ha as Ke,ja as wt,n as Di,na as Xi,oa as Ji,qa as Zi,ra as Qi,sa as er,va as tr,w as Wi,y as gn,ya as kn,z as Ui,za as nr}from"./chunk-AUDMRGWF.js";import{a as Ei,c as mt,d as fn,j as Pi,l as pn,m as mn,n as Ii}from"./chunk-JFYVRWJI.js";import{b as ke,c as De,e as Fi,f as hn,g as ji,h as ht}from"./chunk-27TRKD65.js";import{a as ri,b as si}from"./chunk-6FUWMLWO.js";import{A as rn,B as sn,C as ni,D as P,I as oi,J as ii,b as nn,c as at,d as lt,e as Ho,f as Bo,g as Go,h as qo,i as ct,j as Vo,k as on,l as zo,o as ne,p as Yo,q as Xo,t as Jo,u as Zo,v as Qo,w as ei,x as dt,y as ut,z as ti}from"./chunk-V656XVXV.js";import{A as cn,B as wi,b as an,c as ye,d as ci,e as di,h as ui,n as ln,o as fi,q as ie,s as Ae,u as pi,w as mi,x as hi,y as gi,z as bi}from"./chunk-LJEKOS4S.js";import{a as yi,b as ki,c as $i,e as vi,f as xi,g as Si,h as Ci,k as Ai}from"./chunk-BX5KIC4R.js";import{a as se}from"./chunk-UTYFLLSM.js";import{h as ai,i as li}from"./chunk-MVTU4M3W.js";import{a as tn,b as st,e as Ko}from"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";import{execFile as El}from"node:child_process";import{promisify as Pl}from"node:util";import{appendFileSync as Il,existsSync as Et,mkdirSync as Us,readFileSync as Gn,rmSync as _l,writeFileSync as qn}from"node:fs";import{basename as Ol,join as le,resolve as Ll}from"node:path";function Sr(e){if(e==="")return!0;let t=/^\x1b\[(\d+);(\d+)u$/.exec(e);if(t&&Number(t[1])===99&&(Number(t[2])&5)!==0)return!0;let n=/^\x1b\[27;(\d+);(\d+)~$/.exec(e);return!!(n&&Number(n[2])===99&&(Number(n[1])&5)!==0)}function Cr(e){let t=!1;process.on("SIGINT",()=>{t||(t=!0,e())})}function ma(e){if(!e||typeof e!="object")return;let t=e;if(!(typeof t.input!="number"&&typeof t.cacheRead!="number"&&typeof t.cacheWrite!="number"))return t}function ha(e){let t=e?.input??0,n=e?.cacheRead??0,i=e?.cacheWrite??0;return{input:t,cacheRead:n,cacheWrite:i,prompt:t+n+i}}function ga(e){if(typeof e!="string")return null;let t=Date.parse(e);return Number.isNaN(t)?null:t}function ba(e){if(!e||typeof e!="object")return;let t=e,i=(t.message&&typeof t.message=="object"?t.message:void 0)??t,s=ma(i.usage);if(!s)return;let u=typeof i.provider=="string"?i.provider:"",f=typeof i.model=="string"?i.model:"";return{usage:s,model:[u,f].filter(Boolean).join("/")}}function Ar(e){let t=0,n=0,i=[],s=0,u=null;for(let h of e){let w=ba(h);if(!w)continue;let{input:S,cacheRead:M,cacheWrite:j,prompt:W}=ha(w.usage);if(W===0)continue;t+=M,n+=S+j;let K=ga(h.timestamp),I=u,H=I?I.at:null;if(I!==null&&M===0&&S>=1e3){let L=K!==null&&H!==null?Math.max(0,K-H):0;i.push({missedTokens:S,idleMs:L,modelChanged:w.model!==""&&I.model!==""&&w.model!==I.model}),s+=S}u={prompt:W,at:K??H??null,model:w.model}}let f=t+n;return{cachedTokens:t,billedTokens:n,hitRate:f>0?t/f*100:null,misses:i,missedTokens:s}}function Tr(e){return e.modelChanged?"model changed, so its cache had to be built":e.idleMs>=3e5?`cache expired after ${Math.round(e.idleMs/1e3)}s idle`:e.idleMs>0?"prompt changed too early in the prefix to hit":"reason not recorded"}import{copyToClipboard as Nl,SessionManager as Fl}from"@netrodev/hxf-coding-agent";import{CombinedAutocompleteProvider as Ks,Container as jl,Editor as Dl,matchesKey as Y,ProcessTerminal as Wl,ScrollView as Ul,KeybindingsManager as qs,setKeybindings as Vs,TUI_KEYBINDINGS as zs,SelectList as Kl,TuiAltScreen as Hl,truncateToWidth as Re,VStack as Bl,visibleWidth as It,wrapTextWithAnsi as Gl}from"@netrodev/hxf-tui";import{spawn as wa}from"node:child_process";function ya(e,t,n=2e3){return new Promise(i=>{let s=!1,u,f=S=>{s||(s=!0,u!==void 0&&clearTimeout(u),i(S))},h;try{h=wa(e,[...t],{stdio:["ignore","pipe","ignore"]})}catch{f({ok:!1,stdout:""});return}u=setTimeout(()=>{h.kill("SIGKILL"),f({ok:!1,stdout:""})},n);let w=[];h.stdout?.on("data",S=>w.push(S)),h.on("error",()=>f({ok:!1,stdout:""})),h.on("close",S=>{f({ok:S===0,stdout:Buffer.concat(w).toString("utf8")})})})}function vn(){return process.env.XDG_SESSION_TYPE==="wayland"||(process.env.WAYLAND_DISPLAY?.length??0)>0}async function ka(){let e=[];process.platform==="darwin"?e.push({command:"pbpaste",args:[]}):process.platform==="win32"?e.push({command:"powershell.exe",args:["-NoProfile","-Command","Get-Clipboard -Raw"]}):(vn()&&(e.push({command:"wl-paste",args:["--no-newline","--type","text/plain;charset=utf-8"]}),e.push({command:"wl-paste",args:["--no-newline","--type","text/plain"]}),e.push({command:"wl-paste",args:["--no-newline"]})),((process.env.DISPLAY?.length??0)>0||!vn())&&(e.push({command:"xclip",args:["-selection","clipboard","-o"]}),e.push({command:"xsel",args:["--clipboard","--output"]})),e.push({command:"termux-clipboard-get",args:[]}));for(let t of e){let n=await ya(t.command,t.args);if(n.ok&&n.stdout.length>0)return n.stdout}}async function Mr(){let e;try{let{getNativeClipboard:i}=await import("@netrodev/hxf-tui");e=i()}catch{e=void 0}if(e)try{let i=await e.getText();if(typeof i=="string"&&i.length>0)return{ok:!0,text:i}}catch{}let t=await ka();return t!==void 0?{ok:!0,text:t}:{ok:!1,reason:`no clipboard tool could read it \u2014 ${vn()?"install wl-clipboard (wl-paste)":process.platform==="darwin"?"pbpaste should be present on macOS":process.platform==="win32"?"Get-Clipboard should be present on Windows":"install xclip or xsel, or run under a display"}`}}import{TreeSelectorComponent as ql,initTheme as Vl}from"@netrodev/hxf-coding-agent";import{getKeybindings as Hs}from"@netrodev/hxf-tui";import{mixColors as $a,parseColor as va,styleText as de}from"@netrodev/hxf-tui";var ue=process.env.HOWTOFIX_NO_MOTION!=="1",xa=45,Rr=5,Er=8,xn=1e4,Pr=6e4,Ir=3,_r=4,Sn=e=>e<0?0:e>1?1:e;function fe(e,t,n){let i=Sn(n);return i>=1?t:i<=0?e:$a(e,t,i)}var yt=class{value;velocity=0;last=Date.now();target;constructor(t,n=t){this.value=t,this.target=n}set(t){this.target=t}get moving(){return Math.abs(this.target-this.value)>.15}snap(t){this.value=t,this.target=t,this.velocity=0,this.last=Date.now()}step(t=Date.now()){let n=Math.max(0,t-this.last),i=Math.min(250,n)/1e3;if(this.last=t,!ue)return this.value=this.target,this.velocity=0,this.value;n>250&&(this.velocity=0);let s=150,u=2*Math.sqrt(s),f=Math.max(1,Math.ceil(i/.008)),h=i/f;for(let w=0;w<f;w+=1)this.velocity+=(this.target-this.value)*s*h-this.velocity*u*h,this.value+=this.velocity*h;return this.moving||(this.value=this.target,this.velocity=0),this.value}};function Cn(e,t,n,i){return!ue||e<=xn?t:e>=Pr?i:fe(n,i,(e-xn)/(Pr-xn))}function Or(e,t){return!ue||t<=0||e<0?1:1-(1-Sn(e/t))**3}function Lr(e,t){return ue&&e>=0&&e<t}var An=260,Sa=45;function Tn(e,t,n=Sa,i=400){return!ue||n<=0||e<0||e>=i?t:Math.min(t,Math.floor(e/n)+1)}function Nr(e,t,n=Date.now(),i=1400){if(!ue||i<=0)return e;let s=n%i/i;return fe(e,t,s<.5?s*2:(1-s)*2)}function Fr(e,t,n){let i=de(e,{fg:t.rest},ae);if(!ue||e.length===0)return i;let s=Sn(n);if(s>=1)return i;let u=t.band??1,f=e.length+_r*2,w=Math.min(f-1,Math.floor(s*f))-_r,S=H=>{let L=Math.abs(H-w);return L>u?0:1-L/(u+1)},M="",j=0,W=null,K=0,I=0;for(let H of e){let L=S(I);W===null?W=L:L!==W&&(M+=de(e.slice(j,K),{fg:fe(t.rest,t.lit,W)},ae),j=K,W=L),K+=H.length,I+=1}return M+de(e.slice(j),{fg:fe(t.rest,t.lit,W??0)},ae)}function jr(e,t,n=Date.now(),i=90){let s=t[0]??va("#e6e6e6");if(t.length===0||e.length===0)return de(e,{fg:s},ae);if(!ue||i<=0)return de(e,{fg:t[t.length-1]??s},ae);let u=t.length*i,f=(n%u+u)%u,h="",w=0,S=null,M=0,j=0,W=K=>{let I=(f+K*i)/u%1*t.length,H=Math.floor(I)%t.length,L=(H+1)%t.length;return fe(t[H]??s,t[L]??s,I-Math.floor(I))};for(let K of e){let I=W(j);S===null?S=I:I!==S&&(h+=de(e.slice(w,M),{fg:S},ae),w=M,S=I),M+=K.length,j+=1}return h+de(e.slice(w),{fg:S??s},ae)}function Ca(e,t){let n=Math.abs(e-t);return n>=Rr?0:Math.ceil((1-n/Rr)*Ir)/Ir}function Dr(e,t,n=Date.now()){let i=t.charMs??xa;if(!ue||e.length===0||i<=0)return de(e,{fg:t.base},ae);let s=e.length+Er*2,u=n/i%s-Er,f=(W,K)=>de(W,{fg:fe(t.base,t.bright,K)},ae),h="",w=0,S=null,M=0,j=0;for(let W of e){let K=Ca(j,u);S===null?S=K:K!==S&&(h+=f(e.slice(w,M),S),w=M,S=K),M+=W.length,j+=1}return h+f(e.slice(w),S??0)}import{Markdown as Ha,wrapTextWithAnsi as Ba}from"@netrodev/hxf-tui";import{homedir as Aa}from"node:os";import{isAbsolute as Ta,relative as Ma,resolve as Ra,sep as Wr}from"node:path";var Ea="\u25CF",En="\u2514",$t="\u22EF",Mn=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function qe(e=90){let t=Math.floor(Date.now()/e)%Mn.length;return Mn[t]??Mn[0]}var Pa="\u25B2";var Ia="\u25CB",_a=["create_object","set_properties","delete_object","clone_instance","reparent_instance","set_script_source","edit_script_lines","insert_script_lines","execute_luau","generate_mesh","generate_material","generate_procedural_model"];function Pn(e){return e.includes("__")?e.slice(e.lastIndexOf("__")+2):e}function Br(e){return _a.includes(Pn(e))}function Be(e,t=process.cwd()){if(!e||!Ta(e))return e;let n=Ra(e),i=Ma(t,n);if(i==="")return".";if(i&&!i.startsWith(`..${Wr}`)&&i!=="..")return i;let s=Aa();return s&&(n===s||n.startsWith(s+Wr))?`~${n.slice(s.length)}`:n}function oe(e,t){let n=e.replace(/\s+/g," ").trim();return n.length>t?`${n.slice(0,Math.max(1,t-1))}\u2026`:n}function N(e,t){if(e&&typeof e=="object"){let n=e[t];if(typeof n=="string"&&n.length>0)return n;if(typeof n=="number")return String(n)}}function Oa(e,t=160){if(!e||typeof e!="object")return"";try{let n=JSON.stringify(e);return n&&n!=="{}"?oe(n,t):""}catch{return""}}function La(e,t){switch(e){case"read":{let n=Be(N(t,"path")??""),i=[N(t,"offset"),N(t,"limit")].filter(Boolean);return i.length>0?`${n} ${i.length===1?`offset=${i[0]}`:`offset=${i[0]}, limit=${i[1]}`}`:n}case"edit":case"write":return Be(N(t,"path")??"");case"bash":case"powershell":{let n=N(t,"command")??"";return t?.run_in_background===!0?`${n} [background]`:n}case"bash_output":{let n=N(t,"task_id"),i=N(t,"filter");return n?i?`${n} filter=${i}`:n:"all tasks"}case"kill_shell":return N(t,"task_id")??"";case"compress":{let n=N(t,"topic")??"",i=Array.isArray(t.content)?t.content.length:0;return i>1?`${n} (${i} ranges)`:n}case"grep":{let n=N(t,"pattern")??"",i=N(t,"path");return i?`${n} in ${Be(i)}`:n}case"find":case"glob":{let n=N(t,"pattern")??N(t,"glob")??"",i=N(t,"path");return i?`${n} in ${Be(i)}`:n}case"ls":return Be(N(t,"path")??".");case"task":return N(t,"agent")??"task";case"ask":return N(t,"question")??"";case"web_search":return N(t,"query")??"";case"web_fetch":return N(t,"url")??"";case"lsp":{let n=N(t,"action")??"lsp",i=N(t,"file")??"",s=N(t,"line");return s?`${n} ${i}:${s}`:`${n} ${i}`}case"quality":return N(t,"path")??"changed files";case"think":return"private";case"todo":{let n=N(t,"op")??"view",i=N(t,"task"),s=t?.items;return n==="init"&&Array.isArray(s)?`init ${s.length} task${s.length===1?"":"s"}`:i?`${n} ${i}`:n}case"context":{let n=N(t,"op")??"list",i=N(t,"key");return i?`${n} ${i}`:n}case"workflow":{let n=N(t,"path");if(n)return n;let i=N(t,"code")??"",s=/export\s+const\s+meta\s*=\s*\{[\s\S]*?name\s*:\s*["'`]([^"'`]+)/.exec(i)?.[1];if(s)return s;let u=i.trim().split(`
2
2
  `)[0]??"";return u.length>40?`${u.slice(0,40)}\u2026`:u}default:return Oa(t)}}function $e(e,t,n=100){let i=Pn(e),u=i!==e?i:i.charAt(0).toUpperCase()+i.slice(1),f=Br(e)?Pa:Ea,h=oe(La(i,t),n);return h?`${f} ${u}(${h})`:`${f} ${u}`}function Na(e){let t=0,n=0;for(let i of e.split(`
3
3
  `))i.startsWith("+")&&!i.startsWith("+++")?t+=1:i.startsWith("-")&&!i.startsWith("---")&&(n+=1);return{additions:t,removals:n}}function Te(e){let t=e?.content;return typeof t=="string"?t:Array.isArray(t)?t.map(n=>n&&typeof n=="object"&&n.type==="text"?String(n.text??""):"").join(""):""}function Ve(e){let t=e?.details;return t&&typeof t=="object"?t:{}}function In(e){let t=e?.structuredContent;return t&&typeof t=="object"?t:{}}function Ur(e){let t=e.exit_code;return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Fa(e){let t=[];if(e&&typeof e=="object"){t.push(e);let i=e.content;if(Array.isArray(i))for(let s of i){let u=s?.text;if(typeof u=="string")try{let f=JSON.parse(u);f&&typeof f=="object"&&t.push(f)}catch{}}}let n=[];for(let i of t){let s=["instances","instanceCount","count","parts","partsCreated"].map(w=>i[w]).find(w=>typeof w=="number"&&Number.isFinite(w));typeof s=="number"&&n.push(`${s} instance${s===1?"":"s"}`);let u=Rn(i,["files","written","paths"]);u&&n.push(u.join(", "));let f=Rn(i,["images","renders","screenshots"]);f&&n.push(`renders ${Ia} ${f.join(", ")}`);let h=Rn(i,["findings","warnings","errors"]);if(h&&n.push(`${h.length} finding${h.length===1?"":"s"}`),n.length>0)break}return n.length>0?n.join(" \xB7 "):void 0}function Rn(e,t){for(let n of t){let i=e[n];if(!Array.isArray(i))continue;let s=i.filter(u=>typeof u=="string"&&u!=="");if(s.length>0)return s}}function Kr(e){return e.trim().split(`
4
4
  `).find(t=>t.trim())??""}function ja(e,t){let n=typeof e.output=="string"?e.output:t.replace(/\n*Command exited with code \d+\s*$/,""),i=Ge(n);return i>0?` (${i} line${i===1?"":"s"})`:""}function Da(e,t,n){return e===1?t:n}function Ge(e){let t=e.trim();return t?t.split(`
@@ -107,4 +107,4 @@ ${gn(m)}`);return}if(r==="session"){let c=k.model;p("session",c?`${c.provider}/$
107
107
  ${E}`)});p("roblox",B.message)}else if(x.sub==="logout")await D.logout(),p("roblox","signed out of Roblox");else{let B=x.rest==="off"?"stop":x.rest==="on"||x.rest===""?"start":void 0;if(!B)p("roblox","usage: /roblox tunnel on | off");else{let E=await D.tunnel(B);p("roblox",E.message??"done")}}}catch(B){p("roblox",B instanceof Error?B.message:String(B))}return}let $=ne(e.cwd).entries.find(D=>D.manifest.name==="rotoolbox");if(!$||$.source!=="installed"){p("roblox","RoToolbox is not installed. Run /preset and install RoToolbox first.");return}let A=on($.dir),R=k.getActiveToolNames().filter(D=>/roblox[-_]studio/i.test(D)),U=R.length>0;p("roblox",A?`RoToolbox: disabled
108
108
  Enable with /preset enable rotoolbox
109
109
  The MCP server and manager stay stopped while disabled.`:["RoToolbox: active",`MCP server: ${U?`connected \u2014 ${R.length} tool${R.length===1?"":"s"} registered`:"not connected yet"}`,"Open Roblox Studio with a place, then use a prompt to inspect it.","Disable with /preset disable rotoolbox"].join(`
110
- `));return}let d=kr(o,k.resourceLoader.getSkills().skills.map(c=>c.name));if(d){To(d);return}let y=k.extensionRunner.getCommand(r??"");if(y){try{await y.handler(l,k.extensionRunner.createCommandContext())}catch(c){G(c instanceof Error?c.message:String(c))}return}p("command",`/${r??""} is not available in this screen yet`)};Di((o,r)=>{let{promise:a,resolve:l}=Promise.withResolvers();return _(o,r.map(d=>({value:d,label:d})),l,()=>l("cancelled")),a}),process.on("SIGTERM",_e),Cr(()=>{_e()}),t.setTitle(`${tn} ${st}`),Ql(),i.start(),i.requestRender(!0),Ao(!0);{let{maybeShowWelcome:o}=await import("./chunk-7DTQKDO4.js");await o({cwd:e.cwd,note:e.note,signedIn:ge!==void 0,runSlash:r=>{Fe(r)},openExternal:r=>{He(r)}},_,p)}e.initialPrompt&&Yt(e.initialPrompt),await new Promise(()=>{})}var ee,ec=1e3/30,tc=45e3;export{Jn as Dock,Yn as Hud,Xn as PinnedBlock,Xl as approvalDetail,wt as orderModelsForDefault,Yl as pickerPanel,fu as runWorkbench,Vn as slashCommands,Jl as workflowPanel,Pt as workflowPanelFromRun,Zn as workflowRunOf};
110
+ `));return}let d=kr(o,k.resourceLoader.getSkills().skills.map(c=>c.name));if(d){To(d);return}let y=k.extensionRunner.getCommand(r??"");if(y){try{await y.handler(l,k.extensionRunner.createCommandContext())}catch(c){G(c instanceof Error?c.message:String(c))}return}p("command",`/${r??""} is not available in this screen yet`)};Di((o,r)=>{let{promise:a,resolve:l}=Promise.withResolvers();return _(o,r.map(d=>({value:d,label:d})),l,()=>l("cancelled")),a}),process.on("SIGTERM",_e),Cr(()=>{_e()}),t.setTitle(`${tn} ${st}`),Ql(),i.start(),i.requestRender(!0),Ao(!0);{let{maybeShowWelcome:o}=await import("./chunk-5HR4WOW7.js");await o({cwd:e.cwd,note:e.note,signedIn:ge!==void 0,runSlash:r=>{Fe(r)},openExternal:r=>{He(r)}},_,p)}e.initialPrompt&&Yt(e.initialPrompt),await new Promise(()=>{})}var ee,ec=1e3/30,tc=45e3;export{Jn as Dock,Yn as Hud,Xn as PinnedBlock,Xl as approvalDetail,wt as orderModelsForDefault,Yl as pickerPanel,fu as runWorkbench,Vn as slashCommands,Jl as workflowPanel,Pt as workflowPanelFromRun,Zn as workflowRunOf};
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as U,c as I}from"./chunk-6FUWMLWO.js";import{b as N}from"./chunk-YW7NORH3.js";import{a as R,b as O}from"./chunk-AGGIYXN7.js";import{D as j,K as F}from"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import{a as r,b as x}from"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";var W={rpc:!0,acp:!0},B={off:!0,minimal:!0,low:!0,medium:!0,high:!0,xhigh:!0,max:!0},L={suggest:!0,"auto-edit":!0,"full-auto":!0},D={text:!0,json:!0,"stream-json":!0};function he(c){let e=Number(c);if(!Number.isFinite(e)||e<=0)throw new Error(`--max-budget-usd needs a positive number of dollars, got '${c}'`);return e}function v(c,e,l){let d=c[e];if(d?.includes("="))return d.slice(d.indexOf("=")+1);let p=c[e+1];if(!p||p.startsWith("-"))throw new Error(`${l} needs a value`);return c.splice(e+1,1),p}function G(c){let e={print:!1,continueSession:!1,noSession:!1,help:!1,version:!1,update:!1,checkUpdate:!1,outputFormat:"text",dangerouslySkipPermissions:!1,sandbox:!1,prompt:""},l=[],d=[...c];for(let p=0;p<d.length;p++){let s=d[p]??"";if(s==="--"){l.push(...d.slice(p+1));break}if(s==="-h"||s==="--help")e.help=!0;else if(s==="-v"||s==="--version")e.version=!0;else if(s==="-p"||s==="--print")e.print=!0;else if(s==="-c"||s==="--continue")e.continueSession=!0;else if(s==="--no-session")e.noSession=!0;else if(s==="--sandbox")e.sandbox=!0;else if(s==="--update")e.update=!0;else if(s==="--check-update")e.checkUpdate=!0;else if(s==="-r"||s==="--resume")e.continueSession=!0;else if(s==="--session"||s.startsWith("--session="))e.sessionPath=v(d,p,"--session");else if(s==="-m"||s==="--model"||s.startsWith("--model="))e.model=v(d,p,"--model");else if(s==="--thinking"||s.startsWith("--thinking="))e.thinking=v(d,p,"--thinking");else if(s==="--approval"||s.startsWith("--approval="))e.approval=v(d,p,"--approval");else if(s==="--output-format"||s.startsWith("--output-format="))e.outputFormat=v(d,p,"--output-format");else if(s==="--max-budget-usd"||s.startsWith("--max-budget-usd="))e.maxBudgetUsd=he(v(d,p,"--max-budget-usd"));else if(s==="--mode"||s.startsWith("--mode=")){let h=v(d,p,"--mode");if(!W[h])throw new Error(`--mode must be one of: ${Object.keys(W).join(", ")}`);e.mode=h}else if(s==="--acp")e.mode="acp";else if(s==="--dangerously-skip-permissions")e.dangerouslySkipPermissions=!0;else{if(s.startsWith("-"))throw new Error(`unknown option ${s}`);l.push(s)}}if(e.thinking&&!B[e.thinking])throw new Error(`thinking must be one of: ${Object.keys(B).join(", ")}`);if(e.approval&&!L[e.approval])throw new Error(`approval must be one of: ${Object.keys(L).join(", ")}`);if(!D[e.outputFormat])throw new Error(`output-format must be one of: ${Object.keys(D).join(", ")}`);if(e.outputFormat!=="text"&&!e.print)throw new Error(`--output-format ${e.outputFormat} is a machine contract; it needs --print`);if(e.dangerouslySkipPermissions&&!e.print)throw new Error("--dangerously-skip-permissions is for unattended runs; it needs --print. interactively, pick an approval mode instead (/approval, or --approval)");if(e.prompt=l.join(" ").trim(),e.update&&e.checkUpdate)throw new Error("--update installs; --check-update only looks. pick one");if((e.update||e.checkUpdate)&&(e.print||e.continueSession||e.sessionPath||e.prompt))throw new Error("--update and --check-update act on the installation, not a session; they take no prompt");if(e.continueSession&&e.noSession)throw new Error("--continue and --no-session cannot be combined");if(e.sessionPath&&e.noSession)throw new Error("--session and --no-session cannot be combined");if(e.sessionPath&&e.continueSession)throw new Error("--session and --continue cannot be combined");if(e.print&&(e.continueSession||e.sessionPath))throw new Error("--print runs one prompt in a throwaway session; it cannot be combined with --continue or --session");if(e.mode&&(e.print||e.prompt))throw new Error(`--mode ${e.mode} is a protocol server: prompts arrive over the protocol, not the command line`);if(e.mode&&(e.continueSession||e.sessionPath))throw new Error(`--mode ${e.mode} opens its own sessions; it cannot be combined with --continue or --session`);if(e.sessionPath&&!e.sessionPath.endsWith(".jsonl"))throw new Error(`--session expects a session file, got '${e.sessionPath}'`);return e}function P(){return`${r} ${x}
2
+ import{b as U,c as I}from"./chunk-6FUWMLWO.js";import{b as N}from"./chunk-YW7NORH3.js";import{a as R,b as O}from"./chunk-AGGIYXN7.js";import{D as j,K as F}from"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import{a as r,b as x}from"./chunk-DVYH677E.js";import"./chunk-WOT6VMZA.js";var W={rpc:!0,acp:!0},B={off:!0,minimal:!0,low:!0,medium:!0,high:!0,xhigh:!0,max:!0},L={suggest:!0,"auto-edit":!0,"full-auto":!0},D={text:!0,json:!0,"stream-json":!0};function he(c){let e=Number(c);if(!Number.isFinite(e)||e<=0)throw new Error(`--max-budget-usd needs a positive number of dollars, got '${c}'`);return e}function v(c,e,l){let d=c[e];if(d?.includes("="))return d.slice(d.indexOf("=")+1);let p=c[e+1];if(!p||p.startsWith("-"))throw new Error(`${l} needs a value`);return c.splice(e+1,1),p}function G(c){let e={print:!1,continueSession:!1,noSession:!1,help:!1,version:!1,update:!1,checkUpdate:!1,outputFormat:"text",dangerouslySkipPermissions:!1,sandbox:!1,prompt:""},l=[],d=[...c];for(let p=0;p<d.length;p++){let s=d[p]??"";if(s==="--"){l.push(...d.slice(p+1));break}if(s==="-h"||s==="--help")e.help=!0;else if(s==="-v"||s==="--version")e.version=!0;else if(s==="-p"||s==="--print")e.print=!0;else if(s==="-c"||s==="--continue")e.continueSession=!0;else if(s==="--no-session")e.noSession=!0;else if(s==="--sandbox")e.sandbox=!0;else if(s==="--update")e.update=!0;else if(s==="--check-update")e.checkUpdate=!0;else if(s==="-r"||s==="--resume")e.continueSession=!0;else if(s==="--session"||s.startsWith("--session="))e.sessionPath=v(d,p,"--session");else if(s==="-m"||s==="--model"||s.startsWith("--model="))e.model=v(d,p,"--model");else if(s==="--thinking"||s.startsWith("--thinking="))e.thinking=v(d,p,"--thinking");else if(s==="--approval"||s.startsWith("--approval="))e.approval=v(d,p,"--approval");else if(s==="--output-format"||s.startsWith("--output-format="))e.outputFormat=v(d,p,"--output-format");else if(s==="--max-budget-usd"||s.startsWith("--max-budget-usd="))e.maxBudgetUsd=he(v(d,p,"--max-budget-usd"));else if(s==="--mode"||s.startsWith("--mode=")){let h=v(d,p,"--mode");if(!W[h])throw new Error(`--mode must be one of: ${Object.keys(W).join(", ")}`);e.mode=h}else if(s==="--acp")e.mode="acp";else if(s==="--dangerously-skip-permissions")e.dangerouslySkipPermissions=!0;else{if(s.startsWith("-"))throw new Error(`unknown option ${s}`);l.push(s)}}if(e.thinking&&!B[e.thinking])throw new Error(`thinking must be one of: ${Object.keys(B).join(", ")}`);if(e.approval&&!L[e.approval])throw new Error(`approval must be one of: ${Object.keys(L).join(", ")}`);if(!D[e.outputFormat])throw new Error(`output-format must be one of: ${Object.keys(D).join(", ")}`);if(e.outputFormat!=="text"&&!e.print)throw new Error(`--output-format ${e.outputFormat} is a machine contract; it needs --print`);if(e.dangerouslySkipPermissions&&!e.print)throw new Error("--dangerously-skip-permissions is for unattended runs; it needs --print. interactively, pick an approval mode instead (/approval, or --approval)");if(e.prompt=l.join(" ").trim(),e.update&&e.checkUpdate)throw new Error("--update installs; --check-update only looks. pick one");if((e.update||e.checkUpdate)&&(e.print||e.continueSession||e.sessionPath||e.prompt))throw new Error("--update and --check-update act on the installation, not a session; they take no prompt");if(e.continueSession&&e.noSession)throw new Error("--continue and --no-session cannot be combined");if(e.sessionPath&&e.noSession)throw new Error("--session and --no-session cannot be combined");if(e.sessionPath&&e.continueSession)throw new Error("--session and --continue cannot be combined");if(e.print&&(e.continueSession||e.sessionPath))throw new Error("--print runs one prompt in a throwaway session; it cannot be combined with --continue or --session");if(e.mode&&(e.print||e.prompt))throw new Error(`--mode ${e.mode} is a protocol server: prompts arrive over the protocol, not the command line`);if(e.mode&&(e.continueSession||e.sessionPath))throw new Error(`--mode ${e.mode} opens its own sessions; it cannot be combined with --continue or --session`);if(e.sessionPath&&!e.sessionPath.endsWith(".jsonl"))throw new Error(`--session expects a session file, got '${e.sessionPath}'`);return e}function P(){return`${r} ${x}
3
3
  coding agent. layout is a workbench, not a chat log.
4
4
 
5
5
  usage:
@@ -90,11 +90,11 @@ an npm install checks for a newer release at startup and can install it itself;
90
90
  token; /login takes another provider's key.
91
91
  `}function fe(c,e=!1){let{message:l}=R(c);if(!e)return l;let d=c instanceof Error?c.stack:void 0;return d&&d.includes(`
92
92
  `)?`${l}
93
- ${d}`:l}function H(c,e){let l=e?.debug??process.env.HOWTOFIX_DEBUG==="1",d=e?.exit??(s=>process.exit(s)),p=s=>{console.error(`${c}: ${fe(s,l)}`),d(1)};process.on("uncaughtException",p),process.on("unhandledRejection",p)}function ge(){try{return{cwd:process.cwd()}}catch{return{error:"the current directory no longer exists (it was deleted while the shell stayed in it). cd to a directory that exists, or pass one on the command line."}}}function we(){process.stdout.on("error",c=>{throw c.code==="EPIPE"&&process.exit(0),c})}async function ke(){we(),F();let c=performance.now(),e=ge();if("error"in e){console.error(`${r}: ${e.error}`),process.exitCode=1;return}let l=e.cwd,d=process.env.HXF_FAKE_NODE??process.versions.node,[p,s]=d.split(".").map(o=>Number.parseInt(o,10));if(!Number.isFinite(p)||p<22||p===22&&Number.isFinite(s)&&s<19){console.error(`${r}: Node ${d} is too old. Node 22.19 or newer is required (run "node --version" to check yours), because undici needs zstd, which Node added in 22.19. Upgrade Node and run this again.`),process.exitCode=1;let o=process.argv.slice(2);if(o.some(a=>a==="-h"||a==="--help")){console.log(P());return}if(o.some(a=>a==="-v"||a==="--version")){console.log(`${r} ${x}`);return}return}let h=process.argv.slice(2);if(h[0]==="doctor"||h[0]==="models"||h[0]==="sessions"){let o=h[0];try{let a=await import("./chunk-EIBOS5KO.js");o==="doctor"?process.exitCode=await a.runDoctor():o==="models"?process.exitCode=a.runModels():process.exitCode=a.runSessions(h.slice(1))}catch(a){O(r,o,a),process.exitCode=1}return}let X=h[0]==="acp"?["--acp",...h.slice(1)]:h,S;try{S=G(X)}catch(o){let a=o instanceof Error?o.message:String(o);console.error(`${r}: ${a}
94
- ${P()}`),process.exitCode=2;return}if(S.print&&!S.prompt){console.error(`${r}: --print needs a prompt`),process.exitCode=2;return}let{repairGatewayModels:J,ensureGatewaySettings:V,repairModelFacts:q,syncGatewayModelsOnStart:K,checkAccount:Y,fetchGatewayPrices:z}=await import("./chunk-UNK5HRQR.js"),{readCliCredential:Q,renewCliCredentialIfNeeded:Z}=await import("./chunk-CPJKKHGH.js"),{AGENT_DIR:w}=await import("./chunk-GXB7RZHH.js"),A=J(w);A>0&&console.error(`${r}: repaired ${A} howtofix model(s) that the gateway would have rejected`);let _,C;try{let o=Q(w);if(o){let b=(await Z(w,o)).credential.accessToken,[m,f]=await Promise.all([z(b),Y(b)]);m.size>0&&(_=m),f.ok&&(C=f.models)}}catch{}let $=await q(w,_?{prices:_}:void 0);if($.changed>0?console.error(`${r}: filled in the context window, reasoning flag and price for ${$.changed} model(s)`):$.message&&console.error(`${r}: model catalogue unavailable (${$.message}); context windows stay at their conservative defaults`),V(w)&&console.error(`${r}: set httpIdleTimeoutMs in settings.json so a stalled provider recovers instead of hanging`),C)try{let o=await K(w,C,_);o.added>0&&console.error(`${r}: added ${o.added} model(s) this account can now reach`)}catch{}let t=S;if(t.help){console.log(P());return}if(t.version){console.log(`${r} ${x}`);let{cliSigningKeyMatchesPanel:o,cliSigningKeyFingerprint:a}=await import("./chunk-LOOFOBTS.js");o()||(console.error(`${r}: this build's CLI signing key (${a()}) does not match the key the panel verifies against, so sign-in will be refused.`),process.exitCode=1);return}if(t.sandbox&&!process.env.HOWTOFIX_SANDBOXED){let{detectSandbox:o,enterSandbox:a,describeSandbox:b}=await import("./chunk-N345KWWK.js"),m=o();if(!m){console.error(`${r}: --sandbox needs a working bubblewrap (Linux) or sandbox-exec (macOS). Neither could be used here \u2014 on Linux this usually means unprivileged user namespaces are disabled.`),process.exitCode=1;return}console.error(b(m)),process.exitCode=a(m,{cwd:l,agentDir:j,argv:[process.execPath,...process.argv.slice(1)]});return}let{installProxy:ee}=await import("./chunk-WKUJ7CFO.js");if(ee(j),t.update||t.checkUpdate){let{PACKAGE_NAME:o,checkForUpdate:a,installUpdate:b,isInstalledCopy:m}=await import("./chunk-7CHDNTH6.js"),f=await a(x);if(!f.latest){console.error(`${r}: ${f.message}`),process.exitCode=t.update?1:0;return}if(console.log(f.message),t.checkUpdate||!f.available)return;if(!m()){console.error(`${r}: this copy was not installed by npm, so npm cannot replace it. install it with: npm install -g ${o}`),process.exitCode=1;return}let y=await b({version:f.latest});console.log(y.message),y.ok||(process.exitCode=1);return}let T=process.argv.slice(2);if(T[0]==="preset"){let{runPresetCommand:o}=await import("./chunk-FPXVDP32.js");process.exitCode=o(T.slice(1));return}let{expandFileReferences:se}=await import("./chunk-TSEKPGK4.js"),{isApprovalMode:te,setApprovalMode:oe,setDangerousBypass:ne,isDangerousBypass:re}=await import("./chunk-56SEAGAQ.js"),{openSession:ie}=await import("./chunk-HT3MFLAV.js");oe(t.approval&&te(t.approval)?t.approval:"full-auto");let{readWorkbenchSettings:ae}=await import("./chunk-V3R4FYTJ.js");if((t.dangerouslySkipPermissions||ae(w).skipPermissions)&&ne(!0),re()&&console.error(`${r}: permission checks are OFF \u2014 critical commands (filesystem wipes, fork bombs, host shutdown) and the repeated-call guard are NOT enforced for this run. Turn it off with /settings, or by removing skipPermissions from settings.json.`),t.mode){let{serveProtocol:o}=await import("./chunk-V2RPZMLK.js");await o(t.mode,{cwd:l,model:t.model,thinking:t.thinking});return}let M=o=>ie({cwd:l,model:t.model,thinking:t.thinking,continueSession:o.continueSession??!1,noSession:o.noSession??!1,sessionPath:o.sessionPath,interactive:!t.print}),n=await M({continueSession:t.continueSession,sessionPath:t.sessionPath,noSession:t.noSession||t.print});if(t.print&&n.note&&console.error(n.note),t.maxBudgetUsd!==void 0&&!n.priced){console.error(`${r}: ${I(n.modelLabel,w)}`),await n.dispose(),process.exitCode=2;return}if(t.print){let o=t.prompt.trimStart();if(o.startsWith("/")){let u=o.slice(1).split(/\s+/)[0]??"",{skillInvocation:g}=await import("./chunk-ILDDDLRC.js"),i=n.session.resourceLoader.getSkills().skills.map(E=>E.name);if(!(g(o,i)!==void 0)){let{slashCommands:E}=await import("./chunk-SX5VE6XA.js");if(E(n.session).some(me=>me.name===u)){console.error(`${r}: /${u} runs in the TUI only \u2014 --print sends prompts straight to the model. Run \`howtofix\` without --print for interactive commands.`),await n.dispose(),process.exitCode=2;return}}}let a=t.outputFormat==="stream-json",b=t.outputFormat==="json",m=a||b;if(a){let u={type:"system",subtype:"init",cwd:l,session_id:n.session.sessionId,model:n.modelLabel,output_format:t.outputFormat,max_budget_usd:t.maxBudgetUsd??null,dangerously_skip_permissions:t.dangerouslySkipPermissions,cli_version:x};process.stdout.write(`${JSON.stringify(u)}
93
+ ${d}`:l}function H(c,e){let l=e?.debug??process.env.HOWTOFIX_DEBUG==="1",d=e?.exit??(s=>process.exit(s)),p=s=>{console.error(`${c}: ${fe(s,l)}`),d(1)};process.on("uncaughtException",p),process.on("unhandledRejection",p)}function ge(){try{return{cwd:process.cwd()}}catch{return{error:"the current directory no longer exists (it was deleted while the shell stayed in it). cd to a directory that exists, or pass one on the command line."}}}function we(){process.stdout.on("error",c=>{throw c.code==="EPIPE"&&process.exit(0),c})}async function ke(){we(),F();let c=performance.now(),e=ge();if("error"in e){console.error(`${r}: ${e.error}`),process.exitCode=1;return}let l=e.cwd,d=process.env.HXF_FAKE_NODE??process.versions.node,[p,s]=d.split(".").map(o=>Number.parseInt(o,10));if(!Number.isFinite(p)||p<22||p===22&&Number.isFinite(s)&&s<19){console.error(`${r}: Node ${d} is too old. Node 22.19 or newer is required (run "node --version" to check yours), because undici needs zstd, which Node added in 22.19. Upgrade Node and run this again.`),process.exitCode=1;let o=process.argv.slice(2);if(o.some(a=>a==="-h"||a==="--help")){console.log(P());return}if(o.some(a=>a==="-v"||a==="--version")){console.log(`${r} ${x}`);return}return}let h=process.argv.slice(2);if(h[0]==="doctor"||h[0]==="models"||h[0]==="sessions"){let o=h[0];try{let a=await import("./chunk-FFNDHUCQ.js");o==="doctor"?process.exitCode=await a.runDoctor():o==="models"?process.exitCode=a.runModels():process.exitCode=a.runSessions(h.slice(1))}catch(a){O(r,o,a),process.exitCode=1}return}let X=h[0]==="acp"?["--acp",...h.slice(1)]:h,S;try{S=G(X)}catch(o){let a=o instanceof Error?o.message:String(o);console.error(`${r}: ${a}
94
+ ${P()}`),process.exitCode=2;return}if(S.print&&!S.prompt){console.error(`${r}: --print needs a prompt`),process.exitCode=2;return}let{repairGatewayModels:J,ensureGatewaySettings:V,repairModelFacts:q,syncGatewayModelsOnStart:K,checkAccount:Y,fetchGatewayPrices:z}=await import("./chunk-QJ6MIM5Z.js"),{readCliCredential:Q,renewCliCredentialIfNeeded:Z}=await import("./chunk-2XG6XQZR.js"),{AGENT_DIR:w}=await import("./chunk-GXB7RZHH.js"),A=J(w);A>0&&console.error(`${r}: repaired ${A} howtofix model(s) that the gateway would have rejected`);let _,C;try{let o=Q(w);if(o){let b=(await Z(w,o)).credential.accessToken,[m,f]=await Promise.all([z(b),Y(b)]);m.size>0&&(_=m),f.ok&&(C=f.models)}}catch{}let $=await q(w,_?{prices:_}:void 0);if($.changed>0?console.error(`${r}: filled in the context window, reasoning flag and price for ${$.changed} model(s)`):$.message&&console.error(`${r}: model catalogue unavailable (${$.message}); context windows stay at their conservative defaults`),V(w)&&console.error(`${r}: set httpIdleTimeoutMs in settings.json so a stalled provider recovers instead of hanging`),C)try{let o=await K(w,C,_);o.added>0&&console.error(`${r}: added ${o.added} model(s) this account can now reach`)}catch{}let t=S;if(t.help){console.log(P());return}if(t.version){console.log(`${r} ${x}`);let{cliSigningKeyMatchesPanel:o,cliSigningKeyFingerprint:a}=await import("./chunk-WLU3WFCK.js");o()||(console.error(`${r}: this build's CLI signing key (${a()}) does not match the key the panel verifies against, so sign-in will be refused.`),process.exitCode=1);return}if(t.sandbox&&!process.env.HOWTOFIX_SANDBOXED){let{detectSandbox:o,enterSandbox:a,describeSandbox:b}=await import("./chunk-N345KWWK.js"),m=o();if(!m){console.error(`${r}: --sandbox needs a working bubblewrap (Linux) or sandbox-exec (macOS). Neither could be used here \u2014 on Linux this usually means unprivileged user namespaces are disabled.`),process.exitCode=1;return}console.error(b(m)),process.exitCode=a(m,{cwd:l,agentDir:j,argv:[process.execPath,...process.argv.slice(1)]});return}let{installProxy:ee}=await import("./chunk-WKUJ7CFO.js");if(ee(j),t.update||t.checkUpdate){let{PACKAGE_NAME:o,checkForUpdate:a,installUpdate:b,isInstalledCopy:m}=await import("./chunk-7CHDNTH6.js"),f=await a(x);if(!f.latest){console.error(`${r}: ${f.message}`),process.exitCode=t.update?1:0;return}if(console.log(f.message),t.checkUpdate||!f.available)return;if(!m()){console.error(`${r}: this copy was not installed by npm, so npm cannot replace it. install it with: npm install -g ${o}`),process.exitCode=1;return}let y=await b({version:f.latest});console.log(y.message),y.ok||(process.exitCode=1);return}let T=process.argv.slice(2);if(T[0]==="preset"){let{runPresetCommand:o}=await import("./chunk-FPXVDP32.js");process.exitCode=o(T.slice(1));return}let{expandFileReferences:se}=await import("./chunk-TSEKPGK4.js"),{isApprovalMode:te,setApprovalMode:oe,setDangerousBypass:ne,isDangerousBypass:re}=await import("./chunk-56SEAGAQ.js"),{openSession:ie}=await import("./chunk-A5WOL324.js");oe(t.approval&&te(t.approval)?t.approval:"full-auto");let{readWorkbenchSettings:ae}=await import("./chunk-V3R4FYTJ.js");if((t.dangerouslySkipPermissions||ae(w).skipPermissions)&&ne(!0),re()&&console.error(`${r}: permission checks are OFF \u2014 critical commands (filesystem wipes, fork bombs, host shutdown) and the repeated-call guard are NOT enforced for this run. Turn it off with /settings, or by removing skipPermissions from settings.json.`),t.mode){let{serveProtocol:o}=await import("./chunk-Q7VRW74X.js");await o(t.mode,{cwd:l,model:t.model,thinking:t.thinking});return}let M=o=>ie({cwd:l,model:t.model,thinking:t.thinking,continueSession:o.continueSession??!1,noSession:o.noSession??!1,sessionPath:o.sessionPath,interactive:!t.print}),n=await M({continueSession:t.continueSession,sessionPath:t.sessionPath,noSession:t.noSession||t.print});if(t.print&&n.note&&console.error(n.note),t.maxBudgetUsd!==void 0&&!n.priced){console.error(`${r}: ${I(n.modelLabel,w)}`),await n.dispose(),process.exitCode=2;return}if(t.print){let o=t.prompt.trimStart();if(o.startsWith("/")){let u=o.slice(1).split(/\s+/)[0]??"",{skillInvocation:g}=await import("./chunk-ILDDDLRC.js"),i=n.session.resourceLoader.getSkills().skills.map(E=>E.name);if(!(g(o,i)!==void 0)){let{slashCommands:E}=await import("./chunk-ZNS6H44M.js");if(E(n.session).some(me=>me.name===u)){console.error(`${r}: /${u} runs in the TUI only \u2014 --print sends prompts straight to the model. Run \`howtofix\` without --print for interactive commands.`),await n.dispose(),process.exitCode=2;return}}}let a=t.outputFormat==="stream-json",b=t.outputFormat==="json",m=a||b;if(a){let u={type:"system",subtype:"init",cwd:l,session_id:n.session.sessionId,model:n.modelLabel,output_format:t.outputFormat,max_budget_usd:t.maxBudgetUsd??null,dangerously_skip_permissions:t.dangerouslySkipPermissions,cli_version:x};process.stdout.write(`${JSON.stringify(u)}
95
95
  `)}let f,y,ue=()=>{if(t.maxBudgetUsd===void 0||y!==void 0)return;let u=n.session.getSessionStats().cost;u>t.maxBudgetUsd&&(y={spent:u},n.session.abort())};try{f=n.session.subscribe(i=>{if(a){let k=N(i);k!==void 0&&process.stdout.write(k)}ue()}),await n.session.prompt(se(t.prompt,l));let u=n.session.getLastAssistantText()??"";if(y){if(console.error(`${r}: ${U(y.spent,t.maxBudgetUsd)}`),m){let i=n.session.getSessionStats();process.stdout.write(`${JSON.stringify({type:"result",subtype:"error_max_budget_usd",is_error:!0,result:u,session_id:n.session.sessionId,duration_ms:Math.round(performance.now()-c),num_turns:i.assistantMessages,total_cost_usd:i.cost,usage:{input_tokens:i.tokens.input,output_tokens:i.tokens.output,cache_read_input_tokens:i.tokens.cacheRead,cache_creation_input_tokens:i.tokens.cacheWrite}})}
96
96
  `)}process.exitCode=1;return}if(m){let i=n.session.getSessionStats(),k=n.session.state.messages.at(-1);process.stdout.write(`${JSON.stringify({type:"result",subtype:"success",is_error:!1,result:u,session_id:n.session.sessionId,duration_ms:Math.round(performance.now()-c),num_turns:i.assistantMessages,total_cost_usd:i.cost,usage:{input_tokens:i.tokens.input,output_tokens:i.tokens.output,cache_read_input_tokens:i.tokens.cacheRead,cache_creation_input_tokens:i.tokens.cacheWrite},stop_reason:k?.role==="assistant"?k.stopReason:void 0})}
97
97
  `)}else process.stdout.write(u.endsWith(`
98
98
  `)?u:`${u}
99
99
  `);let g=n.session.state.messages.at(-1);if(g?.role==="assistant"){if((g.stopReason==="error"||g.stopReason==="aborted"||g.errorMessage)&&(process.exitCode=1),process.exitCode===1&&g.errorMessage){console.error(`${r}: ${g.errorMessage}`);let{diagnoseGatewayFailure:i}=await import("./chunk-VLMQSD25.js"),k=i(g.errorMessage);k!==void 0&&console.error(`${r}: ${k}`)}if(m&&process.exitCode===1){let i=n.session.getSessionStats();process.stdout.write(`${JSON.stringify({type:"result",subtype:g.stopReason==="aborted"?"error_aborted":"error_during_execution",is_error:!0,result:u,session_id:n.session.sessionId,duration_ms:Math.round(performance.now()-c),num_turns:i.assistantMessages,total_cost_usd:i.cost,usage:{input_tokens:i.tokens.input,output_tokens:i.tokens.output,cache_read_input_tokens:i.tokens.cacheRead,cache_creation_input_tokens:i.tokens.cacheWrite},stop_reason:g.stopReason})}
100
- `)}}}finally{f?.(),await n.dispose()}return}if(!process.stdin.isTTY||!process.stdout.isTTY){console.error(`${r}: interactive mode needs a terminal. use --print for pipes.`),await n.dispose(),process.exitCode=2;return}let{runWorkbench:ce}=await import("./chunk-SX5VE6XA.js"),{autoUpdateEnabled:de,isInstalledCopy:pe}=await import("./chunk-7CHDNTH6.js"),le=pe()&&de(`${w}/settings.json`);await ce({cwd:l,modelLabel:n.modelLabel,session:n.session,setCompressToolOutput:n.setCompressToolOutput,initialPrompt:t.prompt||void 0,note:n.note,maxBudgetUsd:t.maxBudgetUsd,update:le?{current:x,install:!0}:void 0,reopen:M})}H(r);ke().catch(c=>{O(r,void 0,c),process.exitCode=1});
100
+ `)}}}finally{f?.(),await n.dispose()}return}if(!process.stdin.isTTY||!process.stdout.isTTY){console.error(`${r}: interactive mode needs a terminal. use --print for pipes.`),await n.dispose(),process.exitCode=2;return}let{runWorkbench:ce}=await import("./chunk-ZNS6H44M.js"),{autoUpdateEnabled:de,isInstalledCopy:pe}=await import("./chunk-7CHDNTH6.js"),le=pe()&&de(`${w}/settings.json`);await ce({cwd:l,modelLabel:n.modelLabel,session:n.session,setCompressToolOutput:n.setCompressToolOutput,initialPrompt:t.prompt||void 0,note:n.note,maxBudgetUsd:t.maxBudgetUsd,update:le?{current:x,install:!0}:void 0,reopen:M})}H(r);ke().catch(c=>{O(r,void 0,c),process.exitCode=1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "howtofixcli",
3
- "version": "0.7.15",
3
+ "version": "0.7.16",
4
4
  "type": "module",
5
5
  "description": "HowToFix coding agent. Workbench TUI, sessions, background agents.",
6
6
  "license": "UNLICENSED",
@@ -1,34 +0,0 @@
1
- import{$ as De,A as _e,B as Te,D as E,E as L,Ea as Ke,G as F,H as $e,P as Ee,Pa as Xe,Q as Ae,Qa as Ye,R as ve,S as je,T as Oe,V as Pe,W as Re,Y as Ce,_ as H,a as C,b as D,ba as Ne,c as re,ca as Fe,d as ie,da as Me,e as ae,ea as Ie,f as ce,fa as Le,g as T,i as le,ia as Ge,j as pe,k as ue,ka as Ue,l as fe,la as G,m as me,ma as Be,na as He,o as ge,p as he,pa as W,q as we,r as ye,s as be,t as $,ta as We,u as ke,ua as ze,v as xe,w as I,wa as qe,x as Se,xa as Ze}from"./chunk-AUDMRGWF.js";import{r as se}from"./chunk-JFYVRWJI.js";import{b as de}from"./chunk-27TRKD65.js";import{D as x,G as ee,r as J,s as Q}from"./chunk-V656XVXV.js";import{c as te}from"./chunk-EYWOVCSS.js";import{g as ne,k as oe}from"./chunk-DV2BBBBJ.js";import"./chunk-UTYFLLSM.js";import"./chunk-JMKK26AT.js";import{b as M,c as Y,d as V}from"./chunk-Y7YM5R75.js";import"./chunk-WOT6VMZA.js";import{join as St}from"node:path";import{hostname as Nn}from"node:os";import{createAgentSession as Fn,createCodemodeExtension as Mn,createMcpExtension as In,DefaultResourceLoader as Ln,SessionManager as U,SettingsManager as Gn}from"@netrodev/hxf-coding-agent";import{existsSync as Tt,readFileSync as $t}from"node:fs";import{join as Et}from"node:path";var Ve=Et(x,"APPEND_SYSTEM.md"),At=["<non-interactive>","This run has no user attached: it was started with --print, and there is nobody to answer a question. Anything that stops and waits for a reply \u2014 `ask`, a confirmation, a skill that resolves a mode by asking which mode to use \u2014 will simply end the run with the task unfinished.","So do not ask. Where an instruction tells you to ask the user and wait, take the default it describes and continue, and say which default you took and why in your final answer. The user reads that answer; they cannot answer mid-run.","Where a skill offers a choice of modes, prefer the one that applies the rules while you work over the one that audits afterwards: this is the mode for building something now, and the audit mode can still be run later by the same person who reads your answer.","</non-interactive>"].join(`
2
- `),vt=16*1024;function jt(e){try{if(!Tt(e))return;let o=$t(e,"utf8").trim();return!o||Buffer.byteLength(o,"utf8")>vt?void 0:o}catch{return}}function Je(e,o){let s=[o?e:`${e}
3
-
4
- ${At}`],t=jt(Ve);return t&&s.push(`# Standing instructions from ${Ve}
5
- ${t}`),s}function Ot(e){return e.replace(/operating inside hxf, a coding agent harness/gi,"operating as HowToFix, a coding agent harness").replace(/^HowToFix documentation \(read only when the user asks about[^\n]*\):?$/gim,"Harness documentation (internal reference; the user is never told the harness name):").replace(/\bhxf itself\b/gi,"the harness itself").replace(/^- When reading hxf docs or examples/m,"- When reading harness docs or examples").replace(/^- When working on hxf topics/m,"- When working on harness topics").replace(/^- Always read hxf \.md files/m,"- Always read the harness .md files").replace(/\bhxf packages\b/gi,"harness packages").replace(/\bhxf \.md files\b/gi,"harness .md files").replace(/\bhxf docs\b/gi,"harness docs").replace(/^-\s*You can inspect HXF_\* environment variables/m,"- You can inspect the harness's environment variables")}var Pt=["preamble","rules","docs","addendum"];function Rt(e){if(!e)return;let o=!1,s={...e};for(let t of Pt){let n=s[t];if(typeof n!="string")continue;let r=Ot(n);r!==n&&(s[t]=r,o=!0)}return o?s:void 0}function Qe(){return e=>{e.on("context_with_system",async o=>{let s=o.messages[0];if(!s||s.role!=="system")return;let t=Rt(s.sections);return t?{messages:o.messages.map(r=>r===s?{...s,sections:t}:r)}:void 0})}}var k={hooks:{}},N;function et(){return e=>{let o=ae(re);k=o.config,N=void 0,ce(),e.on("session_start",async(s,t)=>{for(let c of o.diagnostics)t.ui.notify(`hooks.json: ${c.message}`,"warning");let{outcome:n,ran:r}=await T(k,"SessionStart",{hook_event_name:"SessionStart",cwd:t.cwd},{cwd:t.cwd});n.context&&(N=n.context),n.error&&t.ui.notify(`SessionStart hook: ${n.error}`,"warning"),r&&N&&t.ui.notify(`SessionStart hooks added ${N.length} characters of context`,"info")}),e.on("input",async(s,t)=>{if(!k.hooks.UserPromptSubmit)return;let n={hook_event_name:"UserPromptSubmit",cwd:t.cwd,prompt:s.text},{outcome:r}=await T(k,"UserPromptSubmit",n,{cwd:t.cwd});if(r.error&&t.ui.notify(`UserPromptSubmit hook: ${r.error}`,"warning"),r.block)return t.ui.notify(r.reason??"blocked by a hook","warning"),{action:"handled"};if(r.context)return{action:"transform",text:`${s.text}
6
-
7
- ${r.context}`}}),e.on("tool_call",async(s,t)=>{if(!k.hooks.PreToolUse)return;let n={hook_event_name:"PreToolUse",cwd:t.cwd,tool_name:s.toolName,tool_input:s.input},{outcome:r}=await T(k,"PreToolUse",n,{cwd:t.cwd});if(r.error&&t.ui.notify(`PreToolUse hook: ${r.error}`,"warning"),r.block)return{block:!0,reason:r.reason??"blocked by a hook"};if(r.updatedInput){let i=e.getAllTools().find(d=>d.name===s.toolName)?.parameters;if(!i)t.ui.notify(`PreToolUse hook rewrote \`${s.toolName}\`, but no schema is known for that tool \u2014 the rewrite was ignored`,"warning");else{let d=ie(i,r.updatedInput);d?t.ui.notify(`PreToolUse hook rewrite ignored \u2014 ${d}`,"warning"):Object.assign(s.input,r.updatedInput)}}}),e.on("tool_result",async(s,t)=>{if(!k.hooks.PostToolUse)return;let n=s.content.map(i=>i.type==="text"?i.text:"").join(`
8
- `),r={hook_event_name:"PostToolUse",cwd:t.cwd,tool_name:s.toolName,tool_input:s.input,tool_result:n,tool_is_error:s.isError},{outcome:c}=await T(k,"PostToolUse",r,{cwd:t.cwd});if(c.error&&t.ui.notify(`PostToolUse hook: ${c.error}`,"warning"),!!c.context)return{content:[...s.content,{type:"text",text:`
9
- [hook] ${c.context}`}],structuredContent:s.structuredContent}}),e.on("context_with_system",async s=>{if(!N)return;let t=s.messages[0];if(!t||t.role!=="system")return;let n=`${C(t.content)}
10
-
11
- ${N}`;return{messages:s.messages.map(c=>c===t?{...t,content:D(t.content,n)}:c)}}),e.on("session_before_compact",async(s,t)=>{if(!k.hooks.PreCompact)return;let{outcome:n}=await T(k,"PreCompact",{hook_event_name:"PreCompact",cwd:t.cwd,compact_reason:s.reason},{cwd:t.cwd});n.error&&t.ui.notify(`PreCompact hook: ${n.error}`,"warning")}),e.on("session_shutdown",async(s,t)=>{if(!k.hooks.SessionEnd)return;let{outcome:n}=await T(k,"SessionEnd",{hook_event_name:"SessionEnd",cwd:t.cwd,reason:s.reason},{cwd:t.cwd});n.error&&t.ui.notify(`SessionEnd hook: ${n.error}`,"warning")}),e.on("agent_settled",async(s,t)=>{if(!k.hooks.Stop)return;let{outcome:n}=await T(k,"Stop",{hook_event_name:"Stop",cwd:t.cwd},{cwd:t.cwd});n.error&&t.ui.notify(`Stop hook: ${n.error}`,"warning")})}}var Ct=new Set(["bash","grep","find","ls","bash_output","powershell"]),Dt=new Set(["bash","bash_output","powershell"]),Nt=40,Ft=12,Mt=8,nt=6;function It(e,o){let s=e.trim();return!!(s===""||/^[-=*_~+#]{3,}$/.test(s)||o!==void 0&&e===o)}function tt(e){return e.replace(/\d+/g,"#").trimEnd()}function Lt(e){let o=[],s=0,t=0;for(;t<e.length;){let n=tt(e[t]);if(n===""||!/\d/.test(e[t])){o.push(e[t]),t+=1;continue}let r=t+1;for(;r<e.length&&tt(e[r])===n&&/\d/.test(e[r]);)r+=1;let c=r-t;if(c>=nt)o.push(e[t]),o.push(` \u2026 ${c-2} more line${c-2===1?"":"s"} of the same shape \u2026`),o.push(e[r-1]),s+=1;else for(let i=t;i<r;i+=1)o.push(e[i]);t=r}return{out:o,collapsed:s}}function Gt(e,o,s={}){if(o?.truncated)return;let t=e.split(`
12
- `);if(t.length<Nt)return;let n=[],r=0;for(let g=0;g<t.length;g+=1){if(It(t[g],n[n.length-1])){if(t[g].trim()===""&&n[n.length-1]?.trim()!==""){n.push("");continue}r+=1;continue}n.push(t[g])}let c=s.toolName===void 0||Dt.has(s.toolName),{out:i,collapsed:d}=c?Lt(n):{out:n,collapsed:0},p=s.head??Ft,u=s.tail??Mt,l=i,a=0;if(i.length>p+u+nt&&(a=i.length-p-u,l=[...i.slice(0,p),` \u2026 ${a} line${a===1?"":"s"} omitted (${p} kept from the top, ${u} from the end) \u2026`,...i.slice(i.length-u)]),!(r+d===0&&a===0))return{text:l.join(`
13
- `),stats:{before:t.length,after:l.length,collapsed:d}}}function ot(e){return o=>{o.on("tool_result",s=>{if(!e.enabled()||s.isError||!Ct.has(s.toolName))return;let t=s.content.find(i=>i.type==="text");if(!t||t.type!=="text")return;let n=s.details,r=Gt(t.text,n,{toolName:s.toolName});return r?{content:s.content.map(i=>i===t?{type:"text",text:r.text}:i)}:void 0})}}import{readdirSync as Ut,readFileSync as Bt,statSync as Ht}from"node:fs";import{extname as Wt,join as st,relative as zt,resolve as qt,sep as rt}from"node:path";import{Type as P}from"@netrodev/hxf-ai";import{defineTool as Zt}from"@netrodev/hxf-coding-agent";var Kt=new Set(["node_modules",".git","dist","build","out","coverage","vendor","target","__pycache__",".venv","venv",".next",".turbo",".cache"]),A={".ts":{kind:"ts",patterns:[/^\s*export\s+(?:default\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/gm,/^\s*export\s+(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/gm,/^\s*export\s+(?:interface|type)\s+([A-Za-z_$][\w$]*)/gm,/^\s*export\s+const\s+([A-Za-z_$][\w$]*)/gm,/^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/gm,/^\s*(?:export\s+)?class\s+([A-Za-z_$][\w$]*)/gm]},".tsx":{kind:"tsx",patterns:[]},".js":{kind:"js",patterns:[]},".mjs":{kind:"js",patterns:[]},".go":{kind:"go",patterns:[/^func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)/gm,/^type\s+([A-Za-z_]\w*)\s+(?:struct|interface)/gm]},".py":{kind:"py",patterns:[/^(?:async\s+)?def\s+([A-Za-z_]\w*)/gm,/^class\s+([A-Za-z_]\w*)/gm]},".rs":{kind:"rs",patterns:[/^\s*(?:pub\s+)?(?:async\s+)?fn\s+([A-Za-z_]\w*)/gm,/^\s*(?:pub\s+)?(?:struct|enum|trait)\s+([A-Za-z_]\w*)/gm]}};A[".tsx"].patterns=A[".ts"].patterns;A[".js"].patterns=A[".ts"].patterns;A[".mjs"].patterns=A[".ts"].patterns;var Xt=512*1024,Yt=12;function Vt(e,o){let s=A[o];if(!s)return[];let t=new Set,n=[];for(let r of s.patterns){r.lastIndex=0;for(let c of e.matchAll(r)){let i=c[1];i&&!t.has(i)&&(t.add(i),n.push(i))}}return n}function Jt(e,o){let s=new Set,t=n=>{n&&(n.startsWith("./")||n.startsWith("../"))&&s.add(n)};if(o===".ts"||o===".tsx"||o===".js"||o===".mjs"){for(let n of e.matchAll(/(?:from|require\()\s*["']([^"']+)["']/g))t(n[1]);for(let n of e.matchAll(/^\s*import\s+["']([^"']+)["']/gm))t(n[1])}else if(o===".go")for(let n of e.matchAll(/^\s*(?:[\w.]+\s+)?"([^"]+)"/gm))t(n[1]);else if(o===".py")for(let n of e.matchAll(/^\s*from\s+(\.+[\w.]*)\s+import/gm)){let r=n[1].replace(/\./g,"/");t(r.startsWith("/")?`.${r}`:`./${r}`)}else if(o===".rs")for(let n of e.matchAll(/^\s*use\s+(?:crate|super|self)::([\w:]+)/gm))t(`./${n[1].split("::").join("/")}`);return[...s]}function Qt(e,o,s){let t=e.split("/").slice(0,-1).join("/"),n=st(t,o).split(rt).join("/").replace(/^\.\//,"");return[n,`${n}.ts`,`${n}.tsx`,`${n}.js`,`${n}.mjs`,`${n}.go`,`${n}.py`,`${n}.rs`,`${n}/index.ts`,`${n}/index.tsx`,`${n}/index.js`,`${n}/mod.rs`,`${n}.py`].find(c=>s.has(c))}function en(e,o="."){let s=[],t=(n,r)=>{if(r>Yt)return;let c;try{c=Ut(n,{withFileTypes:!0})}catch{return}for(let i of c){let d=st(n,i.name);if(i.isDirectory()){if(Kt.has(i.name)||i.name.startsWith("."))continue;t(d,r+1);continue}let p=Wt(i.name);if(A[p])try{if(Ht(d).size>Xt)continue;let u=Bt(d,"utf8"),l=zt(e,d).split(rt).join("/");s.push({path:l,symbols:Vt(u,p),imports:Jt(u,p)})}catch{}}};return t(qt(e,o),0),s}function tn(e,o){if(e.length===0)return[];let s=new Set(e.map(l=>l.path)),t=new Map(e.map((l,a)=>[l.path,a])),n=e.map(()=>[]),r=e.map(()=>[]);e.forEach((l,a)=>{for(let f of l.imports){let g=Qt(l.path,f,s);if(!g||g===l.path)continue;let w=t.get(g);w!==void 0&&(n[a].push(w),r[w].push(a))}});let c=e.length,i=o?.trim().toLowerCase(),d=e.map(l=>i&&`${l.path} ${l.symbols.join(" ")}`.toLowerCase().includes(i)?4/c:1/c),p=d.reduce((l,a)=>l+a,0),u=e.map((l,a)=>d[a]/p);for(let l=0;l<20;l++){let a=e.map((f,g)=>.15*(d[g]/p));for(let f=0;f<c;f++){if(n[f].length===0){for(let g=0;g<c;g++)a[g]+=.85*u[f]/c;continue}for(let g of n[f])a[g]+=.85*u[f]/n[f].length}u=a}return e.map((l,a)=>({file:l,score:u[a],match:i?`${l.path} ${l.symbols.join(" ")}`.toLowerCase().includes(i):!1})).sort((l,a)=>Number(a.match)-Number(l.match)||a.score-l.score||l.file.path.localeCompare(a.file.path)).map(l=>l.file)}function nn(e,o={}){let t=Math.max(200,Math.min(8e3,o.budget??1200))*4,n=tn(e,o.query),r=[],c=0;for(let d of n){let p=d.symbols.slice(0,8).join(", "),u=p?`${d.path}: ${p}`:`${d.path}`;if(c+u.length+1>t)break;r.push(u),c+=u.length+1}if(r.length===0)return"(no source files found)";let i=n.length-r.length;return i>0&&r.push(`\u2026 ${i} more file${i===1?"":"s"} not shown`),r.join(`
14
- `)}var it;function at(e){it=e}var ct=Zt({name:"repo_map",label:"repo_map",description:"A ranked outline of the repository: files by importance with their top declarations. Use it to find where something lives before reading files, instead of listing directories.",promptSnippet:"repo_map: ranked file outline of the project",parameters:P.Object({path:P.Optional(P.String({description:"Subdirectory to map, relative to the project root"})),query:P.Optional(P.String({description:"Keyword to bias the ranking, e.g. 'billing'"})),budget:P.Optional(P.Number({description:"Token budget, default 1200"}))}),async execute(e,o){let s=it?.()??process.cwd(),t=en(s,o.path??".");return{content:[{type:"text",text:nn(t,{budget:o.budget,query:o.query})}],details:{files:t.length}}}});function z(){return{consecutiveFailures:0,tripped:!1}}function on(e,o){return o==="manual"?!1:e.consecutiveFailures>=3}function sn(e,o){if(o)return e;let s=e.consecutiveFailures+1;return{consecutiveFailures:s,tripped:e.tripped||s>=3}}function rn(){return z()}function an(e){return[`Auto-compaction failed ${e.consecutiveFailures} times in a row, so it is switched off for this session.`,"The context is over the limit and compaction cannot recover it. Start a new session, or switch to a model with a larger context window.","Manual /compact is still allowed."].join(" ")}var v=z();function lt(){return e=>{e.on("session_start",async()=>{v=z()}),e.on("session_compact",async()=>{v=rn()}),e.on("session_compact_failed",async(o,s)=>{let t=v;v=sn(v,o.aborted),!t.tripped&&v.tripped&&s?.ui&&s.ui.notify(an(v),"warning")}),e.on("session_before_compact",async o=>{if(on(v,o.reason))return{cancel:!0}})}}function cn(e){E(F(e))}function dt(e){return`budget exhausted (${e.budget??"default"} continuations)`}function pt(){return e=>{e.on("session_start",async(o,s)=>{cn(s)}),e.on("context_with_system",async(o,s)=>{let t=F(s);if(E(t),!t||t.status!=="active")return;let n=o.messages[0];if(!n||n.role!=="system")return;let r=`${C(n.content)}
15
-
16
- ${_e(t)}`;return{messages:o.messages.map(i=>i===n?{...n,content:D(n.content,r)}:i)}}),e.on("agent_before_settle",async(o,s)=>{try{let t=F(s);if(E(t),L(t).action==="stop"||!t||o.continue||!o.context.canContinue)return;let n={...t,used:t.used+1};if(e.appendEntry(I,n),E(n),L(n).action==="stop"){let r={...n,status:"done",note:dt(n)};e.appendEntry(I,r),E(r);return}return{entries:[{type:"custom_message",customType:Se,content:Te(n),display:!0}],continue:!0}}catch{return}}),e.on("agent_settled",async(o,s)=>{try{let t=F(s),n=L(t);if(t&&n.action==="stop"&&n.close){let r={...t,status:"done",note:dt(t)};e.appendEntry(I,r),E(r)}else E(t)}catch{return}})}}function ln(e){let o=Q(e);return o.length===0?"":["The user installed the following presets. Their rules apply to this session.","",...o.map(t=>`<preset name="${t.name}">
17
- ${t.text}
18
- </preset>`)].join(`
19
- `)}function ut(e){return o=>{o.on("resources_discover",async()=>{let s=J(e);return s.length>0?{skillPaths:s}:void 0}),o.on("context_with_system",async s=>{let t=ln(e);if(!t)return;let n=s.messages[0];if(!n||n.role!=="system")return;let r=`${C(n.content)}
20
-
21
- ${t}`;return{messages:s.messages.map(i=>i===n?{...n,content:D(n.content,r)}:i)}})}}import{Type as y}from"@netrodev/hxf-ai";import{defineTool as dn}from"@netrodev/hxf-coding-agent";function pn(){return[...G.values()].map(e=>`${e.name} (${e.description})`).join(", ")}function ft(){return dn({name:"task",label:"task",description:`Spawn subagents. Available: ${pn()}. One call can carry tasks[]; each item may set agent, model, effort and isolation. Agents run concurrently, park when done, and can be resumed or messaged with /agents. Pass background: true to return as soon as they start instead of waiting for them. Use architect to design an approach before a large change. Set isolation: "worktree" on every task that writes files.`,promptSnippet:"task: spawn background agents",parameters:y.Object({agent:y.Optional(y.String()),effort:y.Optional(y.String()),model:y.Optional(y.String()),task:y.Optional(y.String()),isolation:y.Optional(y.String()),background:y.Optional(y.Boolean()),tasks:y.Optional(y.Array(y.Object({agent:y.Optional(y.String()),effort:y.Optional(y.String()),model:y.Optional(y.String()),task:y.String(),isolation:y.Optional(y.String())})))}),executionMode:"parallel",async execute(e,o,s,t,n){let r=o.tasks&&o.tasks.length>0?o.tasks.map(f=>({agent:f.agent??o.agent??"task",task:f.task,effort:f.effort??o.effort,model:f.model??o.model,isolation:f.isolation??o.isolation})):[{agent:o.agent??"task",task:o.task??"",effort:o.effort,model:o.model,isolation:o.isolation}],c=r.slice(0,W),i=r.length-c.length,d=!!o.background,p=[],u=[],l=[],a=[];try{for(let m of c){if(!m.task.trim())continue;let h;if(m.isolation==="worktree"){let b=await Ke(n?.cwd??process.cwd(),m.agent);if(b){u.push(b),h=b.path;for(let j of b.skipped)a.push(`${m.agent}:${j}`)}else l.push(m.agent)}p.push(await ze({...m,cwd:n?.cwd,background:d,parentModel:We(n?.model),worktree:h})),t?.({content:[],details:{agents:p.map(b=>({id:b.id,agent:b.agent,status:b.status}))}})}if(p.length===0)throw new Error("task or tasks is required");let f=i>0?`(only the first ${W} of ${r.length} tasks ran)`:"",g=p.filter(m=>m.worktree).length,w=[f,l.length>0?`isolation: "worktree" was requested but not available for: ${l.join(", ")}. Those agents ran in the shared working tree \u2014 check their edits for collisions before trusting them.`:"",a.length>0?`too large to copy into the isolated worktree, so it was left out: ${a.join(", ")}. An agent that needs it cannot install or build \u2014 treat any "done" from those runs as unverified.`:""].filter(Boolean),S={agents:p.map(m=>({id:m.id,status:m.status,isolated:!!m.worktree}))};if(d){qe();let m=p.map(h=>`${h.agent}#${h.id}`).join(", ");return{content:[{type:"text",text:`started ${p.length} agent${p.length===1?"":"s"} in the background: ${m}.`+(g>0?` ${g} of them in their own worktree.`:"")+`
22
- Their results are not part of this turn \u2014 keep working. Read them with /agents, or message one with /agents <id> <text>.`+(w.length>0?`
23
- ${w.join(`
24
- `)}`:"")}],details:S}}await Ze(s);let _=p.map(m=>`${He(m)}${m.worktree?" [isolated]":""}
25
- ${m.result??""}`);return w.length>0&&_.push(w.join(`
26
- `)),{content:[{type:"text",text:_.join(`
27
-
28
- `)}],details:S}}finally{for(let f of u)try{await f.remove()}catch{}}}})}import{readFileSync as un,readdirSync as fn,statSync as mn}from"node:fs";import{dirname as gn,join as q}from"node:path";import{getAgentDir as hn,parseFrontmatter as wn}from"@netrodev/hxf-coding-agent";var mt=["off","minimal","low","medium","high","xhigh","max"],yn=["name","description","tools","model","effort"],bn=["read","bash","edit","write","grep","find","ls","bash_output","kill_shell","todo","context","goal","task","workflow","web_search","web_fetch","lsp","quality","slop","claim","repo_map"],kn=["read","bash","edit","write","grep","find","ls","context","todo","web_search","web_fetch","lsp","claim"];function xn(e){let s=(typeof e=="string"?e.split(","):Array.isArray(e)?e:[]).map(t=>String(t).trim().replace(/^["']|["']$/g,"")).filter(Boolean);return s.length>0?s:void 0}function Sn(e){try{return mn(e).isDirectory()}catch{return!1}}function _n(e){let o=e;for(;;){let s=q(o,".howtofix","agents");if(Sn(s))return s;let t=gn(o);if(t===o)return;o=t}}function Tn(e){let o=[{scope:"user",dir:q(hn(),"agents")}],s=_n(e);return s&&o.push({scope:"project",dir:s}),o}function $n(e,o){let s=[],t=[],n=e.replace(/^\uFEFF/,"");if(!/^---\r?\n/.test(n))return{notes:s,problems:[`${o}: no frontmatter \u2014 the file must start with --- and end the block with ---`]};let r={},c="";try{let m=wn(n);r=m.frontmatter??{},c=(m.body??"").trim()}catch(m){return{notes:s,problems:[`${o}: the frontmatter is not readable YAML \u2014 ${m instanceof Error?m.message:String(m)}`]}}for(let m of Object.keys(r))yn.includes(m)||s.push(`${o}: ignoring the unknown frontmatter key '${m}'`);let i=(o.split(/[\\/]/).pop()??o).replace(/\.md$/i,""),d=r.name,p=(typeof d=="string"&&d.trim()?d:i).trim();/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(p)||t.push(`${o}: '${p}' is not a usable agent name \u2014 letters, digits, dot, dash and underscore only`);let u=r.description,l=typeof u=="string"?u.trim():"";l||t.push(`${o}: a description is required \u2014 it is how the model decides to use this agent`),c||t.push(`${o}: no prompt body \u2014 the text below the frontmatter is the agent's standing instruction`);let a=r.effort,f=typeof a=="string"?a.trim().toLowerCase():"";f&&!mt.includes(f)&&t.push(`${o}: effort '${f}' is not one of ${mt.join(", ")}`);let g=xn(r.tools),w=g??[...kn];if(g){let m=g.filter(h=>!bn.includes(h)&&!h.startsWith("mcp__"));m.length>0&&s.push(`${o}: unknown tool${m.length===1?"":"s"} ${m.join(", ")} \u2014 kept, but nothing registers them yet`)}let S=r.model,_=typeof S=="string"&&S.trim()?S.trim():void 0;return t.length>0?{notes:s,problems:t}:{def:{name:p,description:l,tools:w,prompt:c,effort:f||"medium",model:_,source:o},notes:s,problems:t}}function gt(e,o){let s=[],t=[],n=[],r=[];for(let{scope:c,dir:i}of Tn(e)){let d;try{d=fn(i)}catch{continue}for(let p of d.filter(u=>u.toLowerCase().endsWith(".md")).sort()){let u=q(i,p),l;try{l=un(u,"utf8")}catch(g){n.push(`${u}: ${g instanceof Error?g.message:String(g)}`);continue}let a=$n(l,u);t.push(...a.notes),n.push(...a.problems);let f=a.def;f&&(o.has(f.name)&&t.push(`${u}: replaces ${Be.has(f.name)?"the built-in":"an earlier"} '${f.name}'`),o.set(f.name,f),s.push(f),r.includes(c)||r.push(c))}}if(s.length>0){let c=s.filter(i=>o.get(i.name)===i);t.unshift(`loaded ${c.length} subagent definition${c.length===1?"":"s"} (${r.join(" and ")}): ${c.map(i=>i.name).join(", ")}`)}return{loaded:s,notes:t,problems:n}}var En=["grep","find","ls","bash_output","kill_shell"];async function ht(e,{timeoutMs:o=2e3,quietTicks:s=2}={}){let t=Date.now()+o,n=e.getActiveToolNames().length,r=0;for(;Date.now()<t&&r<s;){await new Promise(i=>setTimeout(i,50));let c=e.getActiveToolNames().length;c>n?(n=c,r=0):r+=1}}function wt(e){let o=new Set(e.getActiveToolNames()),s=new Set(e.getAllTools().map(n=>n.name)),t=[];for(let n of En)s.has(n)&&!o.has(n)&&(o.add(n),t.push(n));return t.length>0&&e.setActiveToolsByName([...o]),t}import{spawnSync as An}from"node:child_process";import{join as vn}from"node:path";import{defineTool as jn}from"@netrodev/hxf-coding-agent";var On=6e3,yt=jn({name:"slop",label:"slop",description:"Check code against the project's slop gate: naming, comments, placeholder values, swallowed errors, and the LLM tells that appear in model-written code. Read-only. Use it before reporting a task finished; it returns each finding as a rule id, a line, and what is wrong, so a claim of clean code becomes something the user can verify. Defaults to the changed files; pass a path to narrow it.",promptSnippet:"slop: naming, comment and placeholder findings for changed code",parameters:$.Object({path:$.Optional($.String({description:"One file or directory, relative to the project root. Omit to scan the changed set."})),changes:$.Optional($.Boolean({description:"Scan only files changed against the base ref. Default true when path is omitted."})),base:$.Optional($.String({description:"Git ref for `changes`. Defaults to HEAD."}))}),async execute(e,o,s,t,n){let r=n.cwd??process.cwd(),i=[vn(r,"scripts","slop.mjs"),"--json"];o.path!==void 0?i.push(o.path):(o.changes??!0)&&i.push("--changes"),o.base!==void 0&&i.push("--base",o.base);let d=An("node",i,{cwd:r,encoding:"utf8",timeout:12e4}),p;try{p=JSON.parse(d.stdout)}catch{p=void 0}if(!p){let w=(d.stderr||d.stdout||"").trim()||d.error?.message||(d.signal?`killed by ${d.signal} (timed out after 120 s?)`:"no output");return{content:[{type:"text",text:`slop gate produced no report: ${w.slice(0,400)}`}],details:{error:w.slice(0,400)}}}if(p.off)return{content:[{type:"text",text:"slop gate is off"}],details:{off:!0}};let u=p.files??{},l=[],a=0;for(let[w,S]of Object.entries(u)){l.push(`${w}`);for(let _ of S)a+=1,l.push(` ${_.rule} L${_.line} ${_.message}`)}if(a===0)return{content:[{type:"text",text:"slop gate: no findings in the scanned files"}],details:{files:Object.keys(u).length,findings:0}};let f=l.join(`
29
- `).slice(0,On),g=f.length<l.join(`
30
- `).length?`
31
- \u2026 truncated`:"";return{content:[{type:"text",text:`${a} finding${a===1?"":"s"}:
32
-
33
- ${f}${g}`}],details:{files:Object.keys(u).length,findings:a}}}});function Z(e){return e.extensionRunner.emit({type:"session_shutdown",reason:"quit"}).catch(()=>{}).finally(()=>e.dispose())}import{readdir as bt,rmdir as Pn,stat as Rn,unlink as Cn}from"node:fs/promises";import{dirname as Dn,join as K,resolve as kt}from"node:path";async function xt(e={}){let o={removed:[],failed:[],removedDirs:[]},s=K(e.agentDir??x,"sessions"),t=(e.now??Date.now())-Ye*24*60*60*1e3,n=e.keep?kt(e.keep):void 0,r;try{r=await bt(s,{withFileTypes:!0})}catch{return o}for(let c of r){if(!c.isDirectory())continue;let i=K(s,c.name),d;try{d=await bt(i)}catch{continue}let p=d.filter(u=>!u.endsWith(".jsonl"));for(let u of d){if(!u.endsWith(".jsonl"))continue;let l=K(i,u),a;try{n&&kt(l)===n?a=!1:a=(await Rn(l)).mtimeMs<t}catch{a=!1}if(!a){p.push(u);continue}try{await Cn(l),o.removed.push(l)}catch{o.failed.push(l),p.push(u)}}if(p.length===0){if(n&&Dn(n)===i)continue;try{await Pn(i),o.removedDirs.push(i)}catch{}}}return o}var X="howtofix.build",Ss=["read","repo_map","bash","edit","write","grep","find","ls","bash_output","kill_shell","task","think","ask","claim","sessions","todo","context","goal","enter_plan_mode","exit_plan_mode","workflow","web_search","web_fetch","lsp","quality","compress","slop"],Un=()=>({exclude:process.platform==="win32"?[]:["powershell"]}),_t=!1;async function _s(e){let o=Gn.create(e.cwd,x,{projectTrusted:!0}),s=de(x).compressToolOutput,t=e.sessionPath?U.open(e.sessionPath):e.noSession?U.inMemory(e.cwd):e.continueSession?U.continueRecent(e.cwd):U.create(e.cwd),n=(()=>{try{let b=t.getEntries().find(j=>j.type==="custom"&&j.customType===X)?.data?.version;return!b||b===M?void 0:`this session was written by HowToFix ${b}; you are running ${M}`}catch{return}})(),r=new Ln({cwd:e.cwd,agentDir:x,settingsManager:o,appendSystemPrompt:Je(Y,e.interactive??!0),additionalSkillPaths:ee(e.cwd),extensionFactories:[Ee(),se(),Qe(),et(),De(),Oe(),ut(e.cwd),pt(),Ae(),lt(),Mn(),ot({enabled:()=>s}),In({loadConfig:h=>le({cwd:h.cwd,projectTrusted:h.isProjectTrusted?.()??!1})})]});await r.reload();let c=gt(e.cwd,G),i=ft(),d=t.getSessionId();at(()=>e.cwd);let p=St(x,ue);we({root:()=>e.cwd,holder:()=>`session:${d}`,presenceDir:()=>p,selfId:()=>d});let u=()=>{try{fe({dir:p},{id:d,cwd:e.cwd,host:Nn(),pid:process.pid,at:Date.now()})}catch{}};u();let l=setInterval(u,Math.max(5e3,Math.floor(pe/3)));l.unref?.();let a=await Fn({cwd:e.cwd,agentDir:x,settingsManager:o,sessionManager:t,resourceLoader:r,excludeTools:Un().exclude,customTools:[i,ct,ge,he,be,ye,ke,xe,$e,ve,je,Xe(),Ne,Fe,Ie,Le,yt,Pe({state:()=>Re(H()??"dcp-sessionless"),messages:()=>Ce(H()??"dcp-sessionless")})],thinkingLevel:e.thinking});await a.session.bindExtensions({mode:"print",onError:()=>{}});let f=ne(x),g=[];if(f){let h=await oe(x,f);h.renewed?await a.session.modelRuntime.setRuntimeApiKey("howtofix",h.credential.accessToken):(h.terminal&&h.message||h.message)&&g.push(h.message)}await ht(a.session),wt(a.session);let w=a.session.model;if(e.model){let h=await a.session.modelRuntime.getAvailable(),b=Ge(h,e.model);if(!b)throw await Z(a.session),new Error(`unknown model '${e.model}'`);(w?.id!==b.id||w.provider!==b.provider)&&(await a.session.setModel(b),w=a.session.model)}else{let h=await a.session.modelRuntime.getAvailable(),b=new Map,j=[];for(let O of h){let R=b.get(O.provider);R===void 0&&(R=!!(await a.session.modelRuntime.getAuth(O.provider))?.auth?.apiKey,b.set(O.provider,R)),R&&j.push(O)}let B=te;if(!B.includes(w?.provider??"")){let O=Ue(j.filter(R=>B.includes(R.provider)),B);O&&(await a.session.setModel(O),w=a.session.model)}}if(!e.noSession&&t.getEntries().every(h=>h.type!=="custom"||h.customType!==X))try{t.appendCustomEntry(X,{version:M})}catch{}_t||(_t=!0,xt({keep:a.session.sessionFile}).catch(()=>{}));let S=w?`${w.provider}/${w.id}`:"no model",_=!!(w&&w.cost&&(w.cost.input>0||w.cost.output>0)),m=[V(a.modelFallbackMessage),...g,...c.notes,...c.problems].filter(h=>!!h);return w||m.push(`no model configured. run \`howtofix\` and use /login, or edit ${St(x,"models.json")}`),{session:a.session,dispose:async()=>{Me(),await Z(a.session),clearInterval(l),me({dir:p},d)},modelLabel:S,priced:_,setCompressToolOutput:h=>{s=h},note:[n,...m].filter(Boolean).join(`
34
- `)||void 0}}export{X as BUILD_ENTRY,Ss as MAIN_TOOLS,_s as openSession};