howtofixcli 0.7.13 → 0.7.15

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.
Files changed (161) hide show
  1. package/dist/chunk-27TRKD65.js +2 -0
  2. package/dist/chunk-3FYCFLNK.js +1 -0
  3. package/dist/chunk-56SEAGAQ.js +1 -0
  4. package/dist/chunk-6FUWMLWO.js +1 -0
  5. package/dist/chunk-7CHDNTH6.js +1 -0
  6. package/dist/chunk-7DTQKDO4.js +2 -0
  7. package/dist/chunk-AGGIYXN7.js +2 -0
  8. package/dist/chunk-AUDMRGWF.js +189 -0
  9. package/dist/chunk-CPJKKHGH.js +1 -0
  10. package/dist/chunk-DAPXGSGD.js +12 -0
  11. package/dist/chunk-DOD7MUGX.js +1 -0
  12. package/dist/chunk-DV2BBBBJ.js +2 -0
  13. package/dist/chunk-EIBOS5KO.js +5 -0
  14. package/dist/chunk-EYWOVCSS.js +6 -0
  15. package/dist/chunk-FPXVDP32.js +8 -0
  16. package/dist/chunk-GXB7RZHH.js +1 -0
  17. package/dist/chunk-HT3MFLAV.js +34 -0
  18. package/dist/chunk-ILDDDLRC.js +1 -0
  19. package/dist/chunk-JFYVRWJI.js +2 -0
  20. package/dist/chunk-JMKK26AT.js +2 -0
  21. package/dist/chunk-LAHVHRCS.js +2 -0
  22. package/dist/chunk-LOOFOBTS.js +1 -0
  23. package/dist/chunk-LSJC73DG.js +1 -0
  24. package/dist/chunk-MOKUBKE7.js +1 -0
  25. package/dist/chunk-N345KWWK.js +1 -0
  26. package/dist/chunk-ONZLNFQ2.js +3 -0
  27. package/dist/chunk-ORJ2QZBG.js +3 -0
  28. package/dist/chunk-PCALBZOO.js +2 -0
  29. package/dist/chunk-SX5VE6XA.js +110 -0
  30. package/dist/chunk-TSEKPGK4.js +1 -0
  31. package/dist/chunk-UNK5HRQR.js +1 -0
  32. package/dist/chunk-UTYFLLSM.js +1 -0
  33. package/dist/chunk-V2RPZMLK.js +1 -0
  34. package/dist/chunk-V3R4FYTJ.js +1 -0
  35. package/dist/chunk-V656XVXV.js +8 -0
  36. package/dist/chunk-VLMQSD25.js +1 -0
  37. package/dist/chunk-WKUJ7CFO.js +1 -0
  38. package/dist/chunk-WOT6VMZA.js +1 -0
  39. package/dist/chunk-WUPU6LTD.js +4 -0
  40. package/dist/chunk-WX3V5P7U.js +5 -0
  41. package/dist/chunk-Y7YM5R75.js +5 -0
  42. package/dist/chunk-YW7NORH3.js +2 -0
  43. package/dist/main.js +99 -540
  44. package/package.json +17 -64
  45. package/dist/account-credential.js +0 -136
  46. package/dist/account-credential.test.js +0 -38
  47. package/dist/activity.js +0 -124
  48. package/dist/agent-defs.js +0 -237
  49. package/dist/agent-limiter.js +0 -68
  50. package/dist/agents.js +0 -554
  51. package/dist/anim.js +0 -361
  52. package/dist/args.js +0 -228
  53. package/dist/at-file.js +0 -28
  54. package/dist/brand-extension.js +0 -87
  55. package/dist/brand.js +0 -76
  56. package/dist/browser.js +0 -58
  57. package/dist/cache-report.js +0 -139
  58. package/dist/checkpoint.js +0 -437
  59. package/dist/claims.js +0 -167
  60. package/dist/cli-auth.js +0 -142
  61. package/dist/cli-checkin.js +0 -120
  62. package/dist/cli-credentials.js +0 -254
  63. package/dist/clipboard.js +0 -149
  64. package/dist/collapse.js +0 -129
  65. package/dist/commands.js +0 -294
  66. package/dist/compaction-guard.js +0 -81
  67. package/dist/context-extension.js +0 -17
  68. package/dist/dcp/commands.js +0 -172
  69. package/dist/dcp/compress-state.js +0 -139
  70. package/dist/dcp/compress.js +0 -329
  71. package/dist/dcp/dcp-extension.js +0 -295
  72. package/dist/dcp/dedup.js +0 -93
  73. package/dist/dcp/ids.js +0 -189
  74. package/dist/dcp/index.js +0 -25
  75. package/dist/dcp/middle-prune.js +0 -76
  76. package/dist/dcp/prompts.js +0 -68
  77. package/dist/dcp/protected-content.js +0 -221
  78. package/dist/dcp/protected.js +0 -161
  79. package/dist/dcp/prune.js +0 -418
  80. package/dist/dcp/state.js +0 -176
  81. package/dist/device-id.js +0 -90
  82. package/dist/device-id.test.js +0 -23
  83. package/dist/errors.js +0 -63
  84. package/dist/extensions.js +0 -48
  85. package/dist/fatal.js +0 -35
  86. package/dist/feed.js +0 -498
  87. package/dist/fs-atomic.js +0 -54
  88. package/dist/gateway-errors.js +0 -90
  89. package/dist/git.js +0 -230
  90. package/dist/goal-extension.js +0 -88
  91. package/dist/goal.js +0 -222
  92. package/dist/hooks-extension.js +0 -176
  93. package/dist/hooks.js +0 -443
  94. package/dist/howtofix-account.js +0 -735
  95. package/dist/hud-line.js +0 -153
  96. package/dist/hwid.js +0 -130
  97. package/dist/interrupt.js +0 -60
  98. package/dist/json-events.js +0 -50
  99. package/dist/level-style.js +0 -112
  100. package/dist/loop-guard.js +0 -95
  101. package/dist/lsp-tools.js +0 -32
  102. package/dist/lsp.js +0 -429
  103. package/dist/mcp-config.js +0 -85
  104. package/dist/mcp-lifecycle.js +0 -147
  105. package/dist/model-catalog.js +0 -217
  106. package/dist/model-facts.js +0 -35
  107. package/dist/model-resolve.js +0 -65
  108. package/dist/notes.js +0 -78
  109. package/dist/oauth-login.js +0 -568
  110. package/dist/paths.js +0 -61
  111. package/dist/permissions.js +0 -298
  112. package/dist/plan-mode.js +0 -363
  113. package/dist/preset-command.js +0 -227
  114. package/dist/preset-extension.js +0 -35
  115. package/dist/preset-mcp.js +0 -292
  116. package/dist/presets.js +0 -727
  117. package/dist/prompt-files.js +0 -103
  118. package/dist/prompt-text.js +0 -41
  119. package/dist/proxy.js +0 -137
  120. package/dist/quality/ast.js +0 -196
  121. package/dist/quality/cognitive.js +0 -83
  122. package/dist/quality/cyclomatic.js +0 -30
  123. package/dist/quality/halstead.js +0 -83
  124. package/dist/quality/index.js +0 -18
  125. package/dist/quality/length.js +0 -3
  126. package/dist/quality/maintainability.js +0 -15
  127. package/dist/quality/nesting.js +0 -57
  128. package/dist/quality/report.js +0 -803
  129. package/dist/quality/smells.js +0 -67
  130. package/dist/quality-tool.js +0 -63
  131. package/dist/read-only-commands.js +0 -597
  132. package/dist/repo-map.js +0 -292
  133. package/dist/rtk.js +0 -193
  134. package/dist/sandbox.js +0 -105
  135. package/dist/schema.js +0 -214
  136. package/dist/session-lifecycle.js +0 -19
  137. package/dist/session-retention.js +0 -111
  138. package/dist/session.js +0 -447
  139. package/dist/sessions.js +0 -100
  140. package/dist/settings.js +0 -148
  141. package/dist/skills.js +0 -35
  142. package/dist/slop-tool.js +0 -96
  143. package/dist/spend-cap.js +0 -43
  144. package/dist/subagent.js +0 -171
  145. package/dist/tar.js +0 -146
  146. package/dist/theme.js +0 -79
  147. package/dist/thinking.js +0 -45
  148. package/dist/todo.js +0 -114
  149. package/dist/tool-loadout.js +0 -97
  150. package/dist/tool-render.js +0 -769
  151. package/dist/tools.js +0 -176
  152. package/dist/ui.js +0 -4778
  153. package/dist/update.js +0 -551
  154. package/dist/usage-segment.js +0 -69
  155. package/dist/web-tools.js +0 -46
  156. package/dist/web.js +0 -265
  157. package/dist/welcome.js +0 -179
  158. package/dist/workflow-engine.js +0 -246
  159. package/dist/workflow-progress.js +0 -446
  160. package/dist/workflow-view.js +0 -195
  161. package/dist/workflow.js +0 -349
@@ -0,0 +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};
@@ -0,0 +1,12 @@
1
+ import"./chunk-WOT6VMZA.js";import{createInterface as A}from"node:readline";var k=1;function v(e){if(!e||Object.keys(e).length===0)return"";let d=c=>JSON.stringify(c).replace(/</g,"\\u003c"),a=[];e.place&&a.push(`place: ${d(e.place)}`),e.selection&&e.selection.length>0&&a.push(`selection: ${d(e.selection)}`),e.connected&&a.push(`connected: ${d(e.connected)}`);for(let[c,f]of Object.entries(e))c==="place"||c==="selection"||c==="connected"||a.push(`${c.replace(/[^\w.-]/g,"_")}: ${d(f)}`);return`<session_context>
2
+ ${a.join(`
3
+ `)}
4
+ </session_context>
5
+
6
+ `}function I(e){return/^(get_|list_|read_|snapshot|diff_|audit|datastore_get|datastore_list|roblox_status)/.test(e)?"read":/^(search|grep|find)/.test(e)?"search":/(execute|run_|luau)/.test(e)?"execute":/^(set_|create_|delete_|clone_|reparent_|edit_|insert_|send_|publish_|upload_|generate_|datastore_set|datastore_delete)/.test(e)?"edit":"other"}function C(e){if(typeof e=="string")return e;let d=e?.content;return Array.isArray(d)?d.map(a=>a.type==="text"?a.text??"":`[${a.type??"?"}]`).join(`
7
+ `):JSON.stringify(e??null)}function O(e){let d=new Map,a=new Map,c=0,f=t=>{e.output.write(`${JSON.stringify({jsonrpc:"2.0",...t})}
8
+ `)},m=(t,i)=>f({id:t,result:i}),l=(t,i,p)=>f({id:t,error:{code:i,message:p}}),y=(t,i)=>f({method:"session/update",params:{sessionId:t,update:i}});async function x(t){let i=t.params??{},p=t.id===void 0;switch(t.method){case"initialize":return m(t.id,{protocolVersion:k,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!1,audio:!1,embeddedContext:!0}},authMethods:[],agentInfo:{name:e.name??"howtofix",title:"HowToFix",version:e.version}});case"session/new":{let s=typeof i.cwd=="string"?i.cwd:process.cwd();try{let r=await e.createAgent(s);c+=1;let u=`sess_${Date.now().toString(36)}_${c}`;return d.set(u,r),m(t.id,{sessionId:u})}catch(r){return l(t.id,-32e3,r instanceof Error?r.message:String(r))}}case"session/prompt":{let s=String(i.sessionId??""),r=d.get(s);if(!r)return l(t.id,-32602,`unknown session ${s}`);if(a.has(s))return l(t.id,-32e3,"a prompt is already running in this session");let g=(Array.isArray(i.prompt)?i.prompt:[]).map(n=>n.type==="text"?n.text??"":n.type==="resource"&&n.resource?.text!==void 0?`<file uri=${JSON.stringify(n.resource.uri??"")}>
9
+ ${n.resource.text}
10
+ </file>`:"").filter(n=>n!=="").join(`
11
+
12
+ `);if(g==="")return l(t.id,-32602,"the prompt has no text");let w=i._meta,b=v(w?.howtofix?.context)+g,_=!1,R=r.subscribe(n=>{if(n.type==="message_update"){let o=n.assistantMessageEvent;o?.type==="text_delta"&&o.delta?y(s,{sessionUpdate:"agent_message_chunk",content:{type:"text",text:o.delta}}):o?.type==="thinking_delta"&&o.delta&&y(s,{sessionUpdate:"agent_thought_chunk",content:{type:"text",text:o.delta}})}else if(n.type==="tool_execution_start"){let o=n;y(s,{sessionUpdate:"tool_call",toolCallId:o.toolCallId,title:o.toolName,kind:I(o.toolName),status:"in_progress",rawInput:o.args??{}})}else if(n.type==="tool_execution_end"){let o=n;y(s,{sessionUpdate:"tool_call_update",toolCallId:o.toolCallId,status:o.isError?"failed":"completed",content:[{type:"content",content:{type:"text",text:C(o.result)}}]})}}),S=r.prompt(b).then(()=>{let n=r.lastStopReason?.(),o=_||n==="aborted"?"cancelled":n==="length"?"max_tokens":"end_turn";m(t.id,{stopReason:o})}).catch(n=>{_?m(t.id,{stopReason:"cancelled"}):l(t.id,-32e3,n instanceof Error?n.message:String(n))}).finally(()=>{R(),a.delete(s)});a.set(s,S),h.set(s,()=>{_=!0});return}case"session/cancel":{let s=String(i.sessionId??"");h.get(s)?.(),await d.get(s)?.abort();return}default:p||l(t.id,-32601,`method not found: ${t.method}`)}}let h=new Map;return new Promise(t=>{let i=A({input:e.input}),p=new Set;i.on("line",s=>{if(s.trim()==="")return;let r;try{r=JSON.parse(s)}catch{l(null,-32700,"parse error");return}let u=x(r).catch(g=>{r.id!==void 0&&l(r.id,-32603,g instanceof Error?g.message:String(g))}).finally(()=>p.delete(u));p.add(u)}),i.on("close",()=>{Promise.allSettled([...p,...a.values()]).then(async()=>{await Promise.allSettled([...d.values()].map(s=>s.dispose())),t()})})})}export{k as ACP_PROTOCOL_VERSION,v as renderSessionContext,O as runAcp};
@@ -0,0 +1 @@
1
+ import{a,b}from"./chunk-YW7NORH3.js";import"./chunk-WOT6VMZA.js";export{b as jsonLine,a as toJsonEvent};
@@ -0,0 +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)}
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};
@@ -0,0 +1,5 @@
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(`
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
+ `)){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
+ `)){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(`
5
+ `).trimEnd()}export{J as collectChecks,_ as exportSessionMarkdown,N as listSessionFiles,Z as runDoctor,K as runModels,Q as runSessions,P as searchSessions};
@@ -0,0 +1,6 @@
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)}
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
+ `)}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
+ `)}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)}
5
+ `)}catch{return!1}return!0}var U={supportsDeveloperRole:!1},P=128e3;function ce(n){let r=n.trim();return r.length<=10?"***":`${r.slice(0,6)}\u2026${r.slice(-4)}`}function ue(n){return/^sk-[A-Za-z0-9_-]{8,}$/.test(n.trim())}function J(n){let r=(()=>{if(Array.isArray(n))return n;if(n&&typeof n=="object"){let t=n;if(Array.isArray(t.data))return t.data;if(Array.isArray(t.models))return t.models}return[]})(),o=[];for(let t of r){let s=typeof t=="string"?t:t&&typeof t=="object"&&typeof t.id=="string"?t.id:void 0;s&&!o.includes(s)&&o.push(s)}return o}function le(n){return C.includes(n)}var H=1e8;async function G(n,r){let o=await n(r,{headers:{Accept:"application/json"}});if(!o.ok)return"USD";let s=(await o.json())?.data?.quota_display_type;return typeof s=="string"&&s.trim()?s.trim().toUpperCase():"USD"}async function de(n,r){let o=(r?.baseUrl??_).replace(/\/+$/,""),t=r?.fetchImpl??fetch,s=r?.timeoutMs??15e3,i=n.trim();if(!i)return{ok:!1,unlimited:!1,unit:"USD",message:"no token given"};let e=`${o.replace(/\/v1$/,"")}/api/status`,a=await G(t,e).catch(()=>"USD"),c=new AbortController,u=setTimeout(()=>c.abort(),s),l={Authorization:`Bearer ${i}`};try{let[d,m]=await Promise.all([t(`${o}/dashboard/billing/subscription`,{headers:l,signal:c.signal}),t(`${o}/dashboard/billing/usage`,{headers:l,signal:c.signal})]);if(d.status===401||d.status===403)return{ok:!1,unlimited:!1,unit:a,message:"the gateway rejected that token when asking for the balance"};if(!d.ok)return{ok:!1,unlimited:!1,unit:a,message:`the balance endpoint answered ${d.status}`};let f=await d.json();if(f.error?.message)return{ok:!1,unlimited:!1,unit:a,message:f.error.message};let p=Number(f.hard_limit_usd??f.soft_limit_usd??0);if(p>=H)return{ok:!0,unlimited:!0,unit:a,message:"this token has no quota limit"};let g=0;if(m.ok){let w=await m.json();g=Number(w.total_usage??0)/100}let h=Math.max(0,p-g);return{ok:!0,unlimited:!1,limit:p,used:g,remaining:h,unit:a,message:`${h.toFixed(2)} ${a} left of ${p.toFixed(2)} (${g.toFixed(2)} used)`}}catch(d){let m=d instanceof Error&&d.name==="AbortError";return{ok:!1,unlimited:!1,unit:a,message:m?`the gateway did not answer within ${Math.round(s/1e3)}s`:"could not reach the gateway"}}finally{clearTimeout(u)}}async function me(n,r,o){let t=M(n,"models.json"),s;try{s=JSON.parse(b(t,"utf8"))}catch{return{added:0,touched:0}}let i=s.providers;if(!i||typeof i!="object")return{added:0,touched:0};let{index:e}=await j(n).catch(()=>({index:new Map})),a=0,c=0;for(let u of C){let l=i[u];if(!l||!Array.isArray(l.models))continue;let d=l.models.length;l.models=q(l.models,r,e,o),a+=l.models.length-d,c++}if(a===0)return{added:0,touched:c};try{y(t,`${JSON.stringify(s,null,2)}
6
+ `)}catch{return{added:0,touched:c}}return{added:a,touched:c}}function q(n,r,o,t){let s=new Set(n.map(e=>e.id)),i=[...n];for(let e of r){if(s.has(e))continue;s.add(e);let a=o?.get(x(e))??(o?A(o,e):void 0);i.push({id:e,contextWindow:a?.contextWindow??P,...a?.maxTokens?{maxTokens:a.maxTokens}:{},...a?{reasoning:a.reasoning}:{},...a?.vision?{input:["text","image"]}:{},...t?.get(e)?{cost:t.get(e)}:{},compat:{...U}})}return i}function B(n,r,o){let t=0;return{models:n.map(i=>{let e=A(r,i.id);if(!e){let l=o?.get(i.id);return!l||i.cost?i:(t++,{...i,cost:l})}let a={...i},c=!1;e.contextWindow&&i.contextWindow===P&&(a.contextWindow=e.contextWindow,c=!0),e.maxTokens&&!i.maxTokens&&(a.maxTokens=e.maxTokens,c=!0),i.reasoning===void 0&&(a.reasoning=e.reasoning,c=!0),e.vision&&!(i.input??[]).includes("image")&&(a.input=[...(i.input??["text"]).filter(l=>l!=="image"),"image"],c=!0);let u=o?.get(i.id);return u&&!i.cost&&(a.cost=u,c=!0),c?(t++,a):i}),changed:t}}function X(n){let r=0;return{models:n.map(t=>t.compat?.supportsDeveloperRole===!1?t:(r++,{...t,compat:{...t.compat,...U}})),changed:r}}function fe(n,r){let o=new Set(n.map(t=>t.id));return r.filter(t=>!o.has(t)).length}async function V(n,r,o){let t=(o?.baseUrl??_).replace(/\/+$/,""),s=o?.fetchImpl??fetch,i=o?.timeoutMs??1e4,e=new AbortController,a=setTimeout(()=>e.abort(),i);try{let c=await s(`${t}/chat/completions`,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({model:n,messages:[{role:"user",content:"hi"}],max_tokens:1}),signal:e.signal});if(c.ok)return{ok:!0,detail:"ok"};let u=await c.text().catch(()=>"");return{ok:!1,detail:/"message"\s*:\s*"([^"]{0,80})/.exec(u)?.[1]??`HTTP ${c.status}`}}catch(c){return{ok:!1,detail:c instanceof Error&&c.name==="AbortError"?"timed out":"unreachable"}}finally{clearTimeout(a)}}async function ge(n,r,o){let t=Math.max(0,o?.limit??4),s=[...new Set(n)].filter(e=>e!==o?.exclude).slice(0,t),i=await Promise.all(s.map(e=>V(e,r,o)));return{live:s.filter((e,a)=>i[a]?.ok),probed:s}}async function pe(n,r){let o=(r?.baseUrl??_).replace(/\/+$/,""),t=r?.fetchImpl??fetch,s=r?.timeoutMs??15e3,i=n.trim();if(!i)return{ok:!1,models:[],message:"no token given"};let e=new AbortController,a=setTimeout(()=>e.abort(),s);try{let c=await t(`${o}/models`,{headers:{Authorization:`Bearer ${i}`},signal:e.signal});if(c.status===401)return{ok:!1,models:[],message:"the gateway rejected that token (401). Check it in the Console, or make a new one."};if(c.status===403)return{ok:!1,models:[],message:"that token is not allowed to list models (403). The Console shows what a token may call."};if(!c.ok)return{ok:!1,models:[],message:`the gateway answered ${c.status}`};let u=J(await c.json());return u.length===0?{ok:!1,models:[],message:"the token works but the gateway listed no models"}:{ok:!0,models:u,message:`${u.length} models available to this token`}}catch(c){let u=c instanceof Error&&c.name==="AbortError";return{ok:!1,models:[],message:u?`the gateway did not answer within ${Math.round(s/1e3)}s`:"could not reach the gateway"}}finally{clearTimeout(a)}}async function he(n,r){let t=`${(r?.baseUrl??_).replace(/\/+$/,"").replace(/\/v1$/,"")}/api/pricing`,s=r?.fetchImpl??fetch,i=r?.timeoutMs??15e3,e=new Map,a=n.trim();if(!a)return e;let c=new AbortController,u=setTimeout(()=>c.abort(),i);try{let l=await s(t,{headers:{Authorization:`Bearer ${a}`},signal:c.signal});if(!l.ok)return e;let d=await l.json();if(!Array.isArray(d?.data))return e;for(let m of d.data){let f=typeof m?.model_name=="string"?m.model_name:"";if(!f||Number(m.quota_type??0)!==0)continue;let p=Number(m.model_ratio);if(!Number.isFinite(p)||p<0)continue;let g=p*2,h=Number(m.completion_ratio),w=Number(m.cache_ratio),E=Number(m.create_cache_ratio);e.set(f,{input:g,output:Number.isFinite(h)&&h>=0?g*h:0,cacheRead:Number.isFinite(w)&&w>=0?g*w:0,cacheWrite:Number.isFinite(E)&&E>=0?g*E:0})}}catch{}finally{clearTimeout(u)}return e}export{_ as a,ne as b,C as c,re as d,oe as e,se as f,D as g,j as h,ie as i,z as j,ae as k,U as l,P as m,ce as n,ue as o,J as p,le as q,H as r,de as s,me as t,q as u,B as v,X as w,fe as x,V as y,ge as z,pe as A,he as B};
@@ -0,0 +1,8 @@
1
+ import{m as p,n as d}from"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import"./chunk-WOT6VMZA.js";import{execFileSync as v}from"node:child_process";import{existsSync as m,mkdirSync as x,readFileSync as S,readdirSync as j,statSync as $,writeFileSync as z}from"node:fs";import{join as r,relative as b,resolve as u}from"node:path";function F(o){let e=o.replace(/-/g," ").replace(/\b\w/g,t=>t.toUpperCase());return[{path:"preset.json",body:`${JSON.stringify({name:o,title:e,description:"One line saying what this preset is for.",category:"engineering",version:"1.0.0",skills:[`${o}-skill`]},null,2)}
2
+ `},{path:"prompt.md",body:["Rules the model should follow while this preset is active.","","This text is appended to the system prompt, never substituted for it, so it","adds to the agent's own rules rather than replacing them. Delete this file if","the preset only needs skills.",""].join(`
3
+ `)},{path:r("skills",`${o}-skill`,"SKILL.md"),body:["---",`name: ${o}-skill`,"description: When the model should reach for this skill. This line is what"," the model reads when deciding, so say when to use it, not what it contains.","---","",`# ${e}`,"","What the model should do, as instructions. A skill is read on demand: only the","frontmatter above is in every request, so the body costs nothing until used.","","Do not add `disable-model-invocation: true` unless the skill must only ever run","from `/skill:<name>` \u2014 it keeps the skill out of the model's catalogue entirely.",""].join(`
4
+ `)}]}function g(){return["usage:"," howtofix preset new <name> [dir] write a preset skeleton"," howtofix preset check [dir] validate a preset with the installer's rules"," howtofix preset pack [dir] build <name>-<version>.tar.gz for publishing","","A preset is a directory holding preset.json, an optional prompt.md, and a","skills/ tree. `check` runs the same validation the installer runs, so a preset","that passes here will not be refused at install."].join(`
5
+ `)}function w(o){let e=[],t=s=>{for(let l of j(s,{withFileTypes:!0}).sort((n,i)=>n.name.localeCompare(i.name))){let n=r(s,l.name);l.isDirectory()?t(n):e.push(b(o,n).split("\\").join("/"))}};return t(o),e}function C(o){let{manifest:e,problems:t}=d(o);if(!e){console.log(`not installable: ${o}`);for(let a of t)console.log(` - ${a}`);return!1}let s=p(o,e);if(s.length>0){console.log(`not installable: ${o}`);for(let a of s)console.log(` - ${a}`);return!1}let l=e.skills??[],n=0,i=0;for(let a of l){let f=r(o,"skills",a,"SKILL.md"),k=m(f)?/^---\r?\n([\s\S]*?)\r?\n---/.exec(S(f,"utf8")):null,y=k&&/^disable-model-invocation:\s*(.*)$/m.exec(k[1]);y&&y[1].trim().replace(/^["']|["']$/g,"").toLowerCase()==="true"?i+=1:n+=1}let h=w(o),c=h.reduce((a,f)=>a+$(r(o,f)).size,0);return console.log(`installable: ${e.name} ${e.version??""}`.trim()),console.log(` ${h.length} files, ${(c/1024).toFixed(1)} KB`),console.log(` ${l.length} skill(s): ${n} the model can choose`),i>0&&console.log(` ${i} invoke-only \u2014 reachable only as /skill:<name>`),!0}function L(o){let{manifest:e,problems:t}=d(o);if(!e){console.log(`cannot pack: ${o}`);for(let c of t)console.log(` - ${c}`);return!1}let s=p(o,e);if(s.length>0){console.log("cannot pack: the preset does not validate");for(let c of s)console.log(` - ${c}`);return!1}let l=e.version??"1.0.0",n=u(`${e.name}-${l}.tar.gz`),i=w(o);v("tar",["-czf",n,"-C",o,...i]);let h=$(n).size;return console.log(`packed ${n}`),console.log(` ${i.length} files, ${(h/1024).toFixed(1)} KB`),console.log(""),console.log("to offer it to the community registry, open a pull request adding an entry"),console.log("that names the repo, a pinned commit, and the skill directory inside it."),!0}function A(o){let[e,t]=o;if(!e||e==="--help"||e==="-h")return console.log(g()),e?0:2;if(e==="new"){if(!t)return console.log(`preset new: a name is required
6
+ `),console.log(g()),2;if(!/^[a-z0-9][a-z0-9-]*$/.test(t))return console.log(`preset new: "${t}" is not a usable name.`),console.log(" lower-case letters, digits and hyphens; must start with a letter or digit."),console.log(" The installer refuses anything else, and it refuses at install time."),2;let s=o[2]?u(o[2]):u("."),l=r(s,t);if(m(l))return console.log(`preset new: ${l} already exists.`),1;for(let n of F(t)){let i=r(l,n.path);x(r(i,".."),{recursive:!0}),z(i,n.body),console.log(` wrote ${b(l,i)}`)}return console.log(`
7
+ wrote ${l}`),console.log(` edit preset.json and the skill, then: howtofix preset check ${t}`),0}if(e==="check"||e==="pack"){let s=u(t??".");return m(r(s,"preset.json"))?(e==="check"?C(s):L(s))?0:1:(console.log(`${e}: no preset.json in ${s}`),2)}return console.log(`preset: unknown subcommand "${e}"
8
+ `),console.log(g()),2}export{A as runPresetCommand};
@@ -0,0 +1 @@
1
+ import{D as a,E as b,F as c,G as d,H as e,I as f,J as g,K as h}from"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import"./chunk-WOT6VMZA.js";export{e as AGENTS_STORE_DIR,a as AGENT_DIR,f as USAGE_CACHE_PATH,b as USER_SKILLS_DIR,g as WORKFLOWS_DIR,d as additionalSkillPaths,h as pinAgentDir,c as projectSkillsDir};
@@ -0,0 +1,34 @@
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};
@@ -0,0 +1 @@
1
+ import{a,b,c}from"./chunk-WX3V5P7U.js";import"./chunk-V656XVXV.js";import"./chunk-UTYFLLSM.js";import"./chunk-WOT6VMZA.js";export{c as formatSkillList,b as skillInvocation,a as skillSearchPaths};
@@ -0,0 +1,2 @@
1
+ var C=new Set(["think"]),l;function E(n){let t=new WeakSet,o=e=>{if(e===null||typeof e!="object")return e;if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e))return e.map(o);let r=e,s={};for(let i of Object.keys(r).sort())s[i]=o(r[i]);return s};try{return JSON.stringify(o(n))??""}catch{return""}}function x(n,t){if(C.has(n))return;let o=`${n}\0${E(t)}`,e=l&&l.signature===o?l.count+1:1;return l={signature:o,count:e},e>=3?{repeats:e}:void 0}function Q(){l=void 0}function v(n,t){return`Refused: ${n} has been called ${t} times in a row with identical arguments, so the last attempt cannot have changed anything. Do not repeat it. Either use different arguments, use a different tool, or stop and report what you found and what is blocking you.`}var $=/^-[a-zA-Z0-9_-]/;function h(n,t){switch(t){case"number":return/^\d+$/.test(n);case"string":return!0;default:return!1}}function O(n,t){if(!/^-[^-]/.test(n)||n.includes("="))return!1;for(let o=1;o<n.length;o++){let e=t[`-${n[o]}`];if(!e)return!1;if(e!=="none")return h(n.slice(o+1),e)}return!0}function L(n,t,o){let e=t;for(;e<n.length;){let r=n[e];if(!r){e++;continue}if(r==="--")break;if($.test(r)){if(/^-\d+$/.test(r)&&o.safeFlags["-n"]){e++;continue}let s=r.includes("="),[i="",...c]=r.split("="),a=o.safeFlags[i];if(!a){if(!O(r,o.safeFlags))return!1;e++;continue}if(a==="none"){if(s)return!1;e++;continue}if(a==="optional"){e++;continue}if(s){if(!h(c.join("="),a))return!1;e++;continue}let y=n[e+1];if(y===void 0||!h(y,a))return!1;e+=2;continue}if(o.allowPositional===!1)return!1;e++}return!0}var M={"--all":"none","--branches":"none","--tags":"none","--remotes":"none"},u={"--oneline":"none","--graph":"none","--decorate":"none","--no-decorate":"none","--date":"string","--relative-date":"none"},g={"--max-count":"number","-n":"number"},p={"--stat":"none","--numstat":"none","--shortstat":"none","--name-only":"none","--name-status":"none"},d={"--color":"none","--no-color":"none"},m={"--patch":"none","-p":"none","--no-patch":"none","--no-ext-diff":"none","-s":"none"},A={"--author":"string","--committer":"string","--grep":"string"},I={"-l":"none","--list":"none","-a":"none","-r":"none","-v":"none","-vv":"none","-i":"none"},F={"git status":{safeFlags:{"-s":"none","--short":"none","-b":"none","--branch":"none","-u":"optional","--untracked-files":"optional","--porcelain":"optional","--ignored":"none","--long":"none","--no-renames":"none",...d}},"git diff":{safeFlags:{...p,...d,...m,"--cached":"none","--staged":"none","--word-diff":"none","--check":"none","--quiet":"none","--exit-code":"none","--no-renames":"none","--diff-filter":"string","--relative":"string","--full-index":"none","--binary":"none","--abbrev":"number","--unified":"number","-U":"number","--ignore-all-space":"none","--ignore-space-change":"none","--ignore-blank-lines":"none"}},"git log":{safeFlags:{...u,...g,...p,...d,...m,...A,...M,"--since":"string","--after":"string","--until":"string","--before":"string","--follow":"none","--no-merges":"none","--merges":"none","--first-parent":"none","--reverse":"none","--skip":"number","--all":"none","--format":"string","--pretty":"string","--abbrev-commit":"none","--no-abbrev-commit":"none","--left-right":"none"}},"git show":{safeFlags:{...p,...d,...m,...u,"--format":"string","--pretty":"string","--abbrev-commit":"none","--no-patch":"none","-q":"none"}},"git shortlog":{safeFlags:{...g,"-s":"none","--summary":"none","-n":"none","--numbered":"none","-e":"none","--email":"none","-sn":"none","-ns":"none","--all":"none"}},"git reflog":{safeFlags:{...g,...u,...A,"--all":"none","--date":"string"}},"git blame":{safeFlags:{"-L":"string","-w":"none","-c":"none","-n":"none","-s":"none","-e":"none","-p":"none","--porcelain":"none","--line-porcelain":"none","--date":"string","--since":"string","-C":"none","-M":"none"}},"git ls-files":{safeFlags:{"-m":"none","--modified":"none","-o":"none","--others":"none","-i":"none","--ignored":"none","-s":"none","--stage":"none","-d":"none","--deleted":"none","-c":"none","--cached":"none","-u":"none","--unmerged":"none","--exclude-standard":"none","--error-unmatch":"none","-z":"none"}},"git ls-remote":{safeFlags:{"--heads":"none","--tags":"none","--refs":"none","--symref":"none"}},"git rev-parse":{safeFlags:{"--short":"optional","--abbrev-ref":"none","--verify":"none","--quiet":"none","--git-dir":"none","--show-toplevel":"none","--show-cdup":"none","--is-inside-work-tree":"none","--is-bare-repository":"none","--symbolic-full-name":"none","--abbrev":"optional"}},"git rev-list":{safeFlags:{...g,"--count":"none","--all":"none","--objects":"none","--reverse":"none","--max-parents":"number","--min-parents":"number","--no-merges":"none","--first-parent":"none","--abbrev-commit":"none"}},"git describe":{safeFlags:{"--tags":"none","--all":"none","--long":"none","--always":"none","--dirty":"none","--abbrev":"number","--match":"string","--exclude":"string","--first-parent":"none"}},"git cat-file":{safeFlags:{"-p":"none","-t":"none","-s":"none","-e":"none","--batch-check":"none"}},"git for-each-ref":{safeFlags:{"--format":"string","--count":"number","--sort":"string","--points-at":"string","--merged":"string","--no-merged":"string"}},"git grep":{safeFlags:{"-n":"none","--line-number":"none","-i":"none","--ignore-case":"none","-l":"none","--files-with-matches":"none","-c":"none","--count":"none","-w":"none","--word-regexp":"none","-E":"none","--extended-regexp":"none","-F":"none","--fixed-strings":"none","--cached":"none","--untracked":"none","-e":"string","--and":"none","--or":"none","--not":"none"}},"git merge-base":{safeFlags:{"--all":"none","--is-ancestor":"none","--fork-point":"none","--octopus":"none"}},"git stash list":{safeFlags:{...u}},"git worktree list":{safeFlags:{"--porcelain":"none","-v":"none","--verbose":"none","-z":"none"}},"git branch":{safeFlags:{...I,"--merged":"string","--no-merged":"string","--contains":"string","--no-contains":"string","--sort":"string","--format":"string","--points-at":"string","--column":"none","--show-current":"none"},dangerous:n=>{let t=new Set(["--merged","--no-merged","--contains","--no-contains","--sort","--format","--points-at"]),o=!1;for(let e of n){if(o){o=!1;continue}if(t.has(e)){o=!0;continue}if(!e.startsWith("-"))return!0}return!1}},"git tag":{safeFlags:{"-l":"none","--list":"none","-n":"number","--contains":"string","--no-contains":"string","--merged":"string","--sort":"string","--points-at":"string","--column":"none"},dangerous:n=>{let t=new Set(["--contains","--no-contains","--merged","--sort","--points-at"]),o=!1;for(let e of n){if(o){o=!1;continue}if(t.has(e)){o=!0;continue}if(!e.startsWith("-"))return!0}return!1}},"git remote":{safeFlags:{"-v":"none","--verbose":"none"},dangerous:n=>n.some(t=>!t.startsWith("-"))},"git config --get":{safeFlags:{"--local":"none","--global":"none","--system":"none","--get-all":"none","--get-regexp":"none","--list":"none","-l":"none","--show-origin":"none","--null":"none","-z":"none"}}},S=["ls","pwd","cat","head","tail","wc","which","whoami","date","echo","sleep","true","false","type","test","seq","basename","dirname","realpath","stat","file","du","df","tree","uname","hostname","id","groups","tty","cal","uptime","free","locale","printf","grep","rg","fd","jq","bat","column","paste","nl","expand","fold","fmt","md5sum","sha1sum","sha256sum","sha512sum","b2sum","cksum","diff","cmp"],P={find:{safeFlags:{"-name":"string","-iname":"string","-type":"string","-maxdepth":"number","-mindepth":"number","-newer":"string","-path":"string","-not":"none","-print":"none","-print0":"none","-empty":"none","-size":"string","-mtime":"number","-atime":"number","-perm":"string","-L":"none","-H":"none","-P":"none"},dangerous:n=>n.some(t=>/^-(delete|exec|execdir|ok|okdir|fprint0?|fls|fprintf)$/.test(t))},sort:{safeFlags:{"-n":"none","-r":"none","-u":"none","-k":"string","-t":"string","-f":"none","-h":"none","-V":"none","-s":"none","-c":"none","-m":"none","-b":"none","-z":"none"}},uniq:{safeFlags:{"-c":"none","-d":"none","-u":"none","-i":"none","-f":"number","-s":"number","-w":"number"}},cut:{safeFlags:{"-d":"string","-f":"string","-c":"string","-b":"string","-s":"none","--complement":"none","-z":"none"}},tr:{safeFlags:{"-d":"none","-s":"none","-c":"none"}},node:{safeFlags:{"-v":"none","--version":"none"},allowPositional:!1},python:{safeFlags:{"--version":"none"},allowPositional:!1},python3:{safeFlags:{"--version":"none"},allowPositional:!1},npm:{safeFlags:{"--version":"none","-v":"none"},allowPositional:!1},sed:{safeFlags:{"-n":"none","--quiet":"none","-e":"string","-E":"none","-r":"none","--regexp-extended":"none","-s":"none","-u":"none","-z":"none","--posix":"none"},dangerous:n=>n.some(t=>/^-i|^--in-place/.test(t)||/\b[we]\s/.test(t)||/^[we]$/.test(t))},awk:{safeFlags:{"-F":"string","-v":"string","-f":"string"},dangerous:n=>n.some(t=>/\bsystem\s*\(|\|\s*"|>\s*"/.test(t))},xxd:{safeFlags:{"-l":"number","-s":"string","-c":"number","-g":"number","-p":"none","-i":"none","-u":"none","-b":"none","-e":"none","-o":"number"},dangerous:n=>n.some(t=>t==="-r"||/^-[a-z]*r/.test(t))}},k={"npm ls":{safeFlags:{"--depth":"number","--json":"none","--long":"none","--parseable":"none","--all":"none","--prod":"none","--dev":"none","--omit":"string","--link":"none","--global":"none","-g":"none","--silent":"none"}},"npm view":{safeFlags:{"--json":"none","--registry":"string"}},"docker ps":{safeFlags:{"-a":"none","--all":"none","-q":"none","--quiet":"none","--no-trunc":"none","--format":"string","-n":"number","--last":"number","-s":"none","--size":"none","--filter":"string"}},"docker images":{safeFlags:{"-a":"none","--all":"none","-q":"none","--quiet":"none","--no-trunc":"none","--format":"string","--filter":"string","--digests":"none"}},"docker inspect":{safeFlags:{"--format":"string","-f":"string","-s":"none","--size":"none","--type":"string"}},"kubectl get":{safeFlags:{"-o":"string","--output":"string","-n":"string","--namespace":"string","-A":"none","--all-namespaces":"none","--no-headers":"none","-l":"string","--selector":"string","--show-labels":"none","-w":"none","--watch":"none","--sort-by":"string"}},"kubectl describe":{safeFlags:{"-n":"string","--namespace":"string","-l":"string","--selector":"string"}},"cargo tree":{safeFlags:{"--depth":"number","-e":"string","--edges":"string","--no-dev-dependencies":"none","--prefix":"string","-i":"string","--invert":"string","-p":"string","--package":"string"}},"go version":{safeFlags:{}}},z=["cd","alias","history","arch","ip addr","ifconfig"];function G(n){if(!/\$\(|`|\$\{|>|</.test(n)&&!/(?<!&)&(?!&)/.test(n))return n.split(/\|\||&&|;|\|/).map(t=>t.trim()).filter(t=>t.length>0)}function D(n){let t=n.some(e=>/^cd\b/.test(e)),o=n.some(e=>/^git\b/.test(e));return t&&o}function q(n){let t=[],o=/'[^']*'|"[^"]*"|\S+/g;for(let e of n.match(o)??[])t.push(e.length>=2&&/^['"]/.test(e)?e.slice(1,-1):e);return t}function N(n){if(n.length===0)return;let[t="",o=""]=n,e=`${t} ${o}`;if(t==="git"&&o==="config"){let r=n[2];return r==="--get"||r==="--get-all"||r==="--get-regexp"||r==="-l"||r==="--list"?{name:"git config --get",rest:n.slice(3)}:void 0}return t==="git"&&o==="stash"?n[2]==="list"?{name:"git stash list",rest:n.slice(3)}:void 0:t==="git"&&o==="worktree"?n[2]==="list"?{name:"git worktree list",rest:n.slice(3)}:void 0:t==="git"&&F[`git ${o}`]?{name:`git ${o}`,rest:n.slice(2)}:k[e]?{name:e,rest:n.slice(2)}:{name:t,rest:n.slice(1)}}var j=new Set(["echo","printf"]);function U(n){let t=q(n),o=N(t);if(!o)return!1;let{name:e,rest:r}=o;if(j.has(e)&&r.some(i=>i.includes("$")||i.includes("`")))return!1;let s=F[e]??P[e]??k[e];return s?s.dangerous?.(r)?!1:L(r,0,s):!!(S.includes(e)||z.includes(e))}function b(n){let t=G(n);return!t||t.length===0||D(t)?!1:t.every(U)}var W=["suggest","auto-edit","full-auto"],rn={suggest:"suggest: ask before every edit and command","auto-edit":"auto-edit: edits run, commands ask","full-auto":"full-auto: nothing asks"};function sn(n){return W.includes(n)}var T={read:0,write:1,exec:2},H={suggest:"read","auto-edit":"write","full-auto":"exec"},B={read:"read",grep:"read",find:"read",ls:"read",think:"read",ask:"read",todo:"read",context:"read",web_search:"read",web_fetch:"read",lsp:"read",quality:"read",workflow:"exec",goal:"read",enter_plan_mode:"read",exit_plan_mode:"read",edit:"write",write:"write",bash:"exec",powershell:"exec",task:"exec"};function R(n){let t=B[n];return t||(n.startsWith("mcp__")?"write":"exec")}var V=new Set(["sudo","doas","env","nohup","time","exec","command","nice","setsid","stdbuf"]),Z=new Set(["-u","-g","-p","-C","-S","-U","--user","--group","--prompt","--close-from","--chdir","--setenv","--unset"]);function Y(n){let t=(n.match(/"[^"]*"|'[^']*'|\S+/g)??[]).map(s=>s.replace(/^['"]|['"]$/g,"")),o=0;for(;o<t.length;){let s=t[o]??"";if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(s)||V.has(s)){o++;continue}if(s.startsWith("-")){o+=Z.has(s)?2:1;continue}break}let e=t[o];if(e===void 0)return;let r=e.split("/").pop()??e;if(r==="rm"){let s=t.slice(o+1),i=s.some(a=>/^-[a-zA-Z]*r[a-zA-Z]*$/i.test(a)||a==="--recursive"),c=s.find(a=>!a.startsWith("-"));return i&&(c===void 0||/^(?:\/|\/\*|~|~\/\*|\$HOME|\$HOME\/\*|\*)$/.test(c))?"recursive delete of the filesystem root or home":void 0}if(r==="dd")return t.slice(o+1).some(s=>/^of=\/dev\/(?:sd|nvme|hd|vd)/.test(s))?"raw write to a block device":void 0;if(/^mkfs(?:\.[a-z0-9]+)?$/.test(r))return"filesystem format";if(/:\(\)\s*\{.*\}\s*;:/.test(n))return"fork bomb";if(/^(?:shutdown|reboot|halt|poweroff)$/.test(r))return"host shutdown";if(/>\s*\/etc\/(?:passwd|shadow|sudoers)/.test(n))return"overwrite of a system account file"}var w="full-auto",_=async()=>!1,f=!1;function an(n){w=n}function ln(){return w}function cn(n){f=n}function un(){return f}function gn(n){_=n}function J(n,t,o){if(f)return{action:"run"};let e=typeof o?.command=="string"?o.command:"";if(t==="bash"||t==="powershell"){let s=Y(e);if(s)return{action:"deny",reason:`Refused in every mode: ${s}.`};if(b(e))return{action:"run"}}let r=R(t);return T[r]<=T[H[n]]?{action:"run"}:{action:"prompt",reason:`this is a ${r}-tier tool`}}function K(n,t){if(t&&typeof t=="object"){let o=t;if((n==="bash"||n==="powershell")&&typeof o.command=="string")return o.command;if((n==="edit"||n==="write")&&typeof o.path=="string"){let e=Array.isArray(o.edits)?` (${o.edits.length} edits)`:"";return`${o.path}${e}`}try{let e=JSON.stringify(o);if(e&&e!=="{}")return e.length>300?`${e.slice(0,297)}...`:e}catch{}}return n}function X(n,t,o){let e=[`Allow tool: ${n}`];n.startsWith("mcp__")&&e.push("Origin: MCP server tool"),e.push(`Reason: ${o}`);let r=K(n,t);return r!==n&&e.push(r),e.join(`
2
+ `)}function dn(n={}){return t=>{t.on("tool_call",async o=>{if(f)return;let e=x(o.toolName,o.input);if(e)return{block:!0,reason:v(o.toolName,e.repeats)};let r=w,s=J(r,o.toolName,o.input);if(s.action==="run")return;if(s.action==="deny")return{block:!0,reason:s.reason};if(n.interactive===!1)return{block:!0,reason:`Blocked: this is a ${R(o.toolName)}-tier tool and no UI can approve it here (approval mode: ${r}).`};if(!await _(`${o.toolName} wants to run`,X(o.toolName,o.input,s.reason)))return{block:!0,reason:`Blocked by the user (approval mode: ${r}).`}})}}export{Q as a,b,W as c,rn as d,sn as e,T as f,H as g,R as h,Y as i,an as j,ln as k,cn as l,un as m,gn as n,J as o,K as p,X as q,dn as r};
@@ -0,0 +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(`
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};
@@ -0,0 +1,2 @@
1
+ import{a}from"./chunk-LSJC73DG.js";import"./chunk-WOT6VMZA.js";import{readFileSync as p}from"node:fs";import{join as g}from"node:path";function f(o){try{let e=JSON.parse(p(g(o,"roblox-bridge.json"),"utf8"));if(typeof e.port=="number"&&typeof e.token=="string")return{port:e.port,token:e.token}}catch{}}var i="the Roblox bridge is not running. Install RoToolbox with /preset, restart, and it starts with the agent.",u=class{constructor(e,n=fetch,t=r=>a(r)){this.endpoint=e;this.fetcher=n;this.open=t}endpoint;fetcher;open;base(){if(!this.endpoint)throw new Error(i);return`http://127.0.0.1:${this.endpoint.port}`}async get(e){let n=await this.fetcher(`${this.base()}${e}`),t=await n.json().catch(()=>({}));if(!n.ok)throw new Error(t.error??`the bridge answered ${n.status}`);return t}async status(){return this.get("/roblox/status")}async login(e={}){if(!(await this.status()).oauth.configured)throw new Error("no Roblox OAuth app is configured. Set HOWTOFIX_ROBLOX_CLIENT_ID (or use ROBLOX_API_KEY for an API key).");let{url:t}=await this.get("/oauth/start");e.onUrl?.(t);let r=await this.open(t),l=Date.now()+(e.timeoutMs??5*6e4);for(;Date.now()<l;){await new Promise(d=>setTimeout(d,e.pollMs??1e3));let s=await this.status();if(s.oauth.signedIn)return{ok:!0,message:`signed in${s.oauth.userName?` as ${s.oauth.userName}`:""}`,url:t}}return{ok:!1,message:r?"timed out waiting for the Roblox consent screen":"could not open a browser; open the URL yourself, then run /roblox status",url:t}}async logout(){if(!this.endpoint)throw new Error(i);await this.get(`/oauth/logout?token=${encodeURIComponent(this.endpoint.token)}`)}async tunnel(e){if(!this.endpoint)throw new Error(i);let n=await this.fetcher(`${this.base()}/tunnel`,{method:"POST",headers:{"content-type":"application/json","x-howtofix-token":this.endpoint.token},body:JSON.stringify({action:e})}),t=await n.json().catch(()=>({}));if(!n.ok)throw new Error(t.error??`the bridge answered ${n.status}`);return t}};function w(o,e){let n=[];return o.oauth.signedIn?(n.push(`Roblox: signed in${o.oauth.userName?` as ${o.oauth.userName}`:""}`),n.push(o.oauth.universeIds.length>0?`experiences: ${o.oauth.universeIds.join(", ")}`:"experiences: none granted yet (sign in again and tick one)")):o.openCloud?n.push("Roblox: using an API key (ROBLOX_API_KEY)"):n.push(`Roblox: not signed in${o.oauth.configured?" \u2014 run /roblox login":" \u2014 set HOWTOFIX_ROBLOX_CLIENT_ID to enable sign-in"}`),n.push(`virtual places: ${o.places.join(", ")||"none"} (answer tools when Studio is closed)`),e&&n.push(`workspace tunnel: ${e.open?"connected":e.running?"connecting":"off"}`),n.join(`
2
+ `)}function m(o){let[e="",...n]=o.trim().split(/\s+/);if(e==="login"||e==="logout"||e==="status"||e==="tunnel")return{sub:e,rest:n.join(" ")}}export{u as RobloxConnect,w as describeStatus,m as parseRobloxSubcommand,f as readBridgeEndpoint};
@@ -0,0 +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};
@@ -0,0 +1 @@
1
+ import{spawn as t}from"node:child_process";function s(n){switch(n){case"darwin":return{command:"open",args:[]};case"win32":return{command:"cmd",args:["/c","start",""]};case"linux":return{command:"xdg-open",args:[]};default:return}}async function d(n,a=process.platform){let r=s(a);return r?new Promise(e=>{try{let o=t(r.command,[...r.args,n],{detached:!0,stdio:"ignore"});o.once("error",()=>e(!1)),o.once("spawn",()=>{o.unref(),e(!0)})}catch{e(!1)}}):!1}export{d as a};
@@ -0,0 +1 @@
1
+ var i=/no available channel for model\s+([^\s"',)\]]+)/i;function r(t){let e=t??"";if(e.trim())return i.exec(e)?.[1]}function a(t){let e=t??"";if(!e.trim())return;let n=r(e);if(n)return`the gateway has no live channel for ${n} right now \u2014 /model lists the models that answer; pick another.`;if(/\bmissing api key\b|\bauthenticationerror\b|\bauth\s*error\b/i.test(e))return"no key for this model yet \u2014 /connect signs you in and pulls the model list.";if(/\bunknown model\b/i.test(e))return"/connect pulls the current model list from the gateway.";if(/\bcode 11128\b|\billegal api invocation\b/i.test(e))return"the gateway refused the request shape (code 11128) \u2014 /connect re-syncs each model's compatibility flags.";if(/\binsufficient (?:balance|quota|credit)\b|\bexceeded your current quota\b|http\s*402/i.test(e))return"the account is out of credit \u2014 /usage shows what is left.";if(/\bserver error\b|http\s*5\d\d/i.test(e))return"the gateway's channel is failing, not the CLI \u2014 /model lists what your account can reach; pick another.";if(/\brate.?limit|\b429\b/i.test(e))return"the gateway is rate-limiting this token \u2014 wait a moment, then resend the prompt.";if(/\bupstream api error\b/i.test(e))return"the gateway refused the request \u2014 run /connect again to re-sync your models."}export{r as a,a as b};
@@ -0,0 +1 @@
1
+ import{a,b,c,d}from"./chunk-PCALBZOO.js";import"./chunk-WOT6VMZA.js";export{c as describeSandbox,a as detectSandbox,d as enterSandbox,b as sandboxArgv};
@@ -0,0 +1,3 @@
1
+ import"./chunk-WOT6VMZA.js";import{createInterface as l}from"node:readline";function f(n){let{agent:i}=n,p=e=>n.output.write(`${JSON.stringify(e)}
2
+ `),t=(e,r,d,a={})=>p({...e!==void 0?{id:e}:{},type:"response",command:r,success:d,...a}),c=i.subscribe(e=>{let r=n.encodeEvent?n.encodeEvent(e):`${JSON.stringify(e)}
3
+ `;r!==void 0&&n.output.write(r)}),u=null;return new Promise(e=>{let r=l({input:n.input});r.on("line",d=>{if(d.trim()==="")return;let a;try{a=JSON.parse(d)}catch{t(void 0,"parse",!1,{error:"a command must be one JSON object per line"});return}let{id:s,type:o}=a;if(o==="prompt"){if(typeof a.message!="string"||a.message.trim()===""){t(s,"prompt",!1,{error:"prompt needs a message"});return}if(u){t(s,"prompt",!1,{error:"a prompt is already running; abort it or wait"});return}t(s,"prompt",!0),u=i.prompt(a.message).catch(m=>{p({type:"error",message:m instanceof Error?m.message:String(m)})}).finally(()=>{u=null});return}if(o==="abort"){i.abort().then(()=>t(s,"abort",!0));return}if(o==="get_state"){t(s,"get_state",!0,{data:{running:u!==null,...n.state?.()??{}}});return}if(o==="get_last_assistant_text"){t(s,"get_last_assistant_text",!0,{data:{text:i.getLastAssistantText()??null}});return}t(s,String(o??"unknown"),!1,{error:`unknown command ${String(o)}`})}),r.on("close",()=>{(u??Promise.resolve()).then(async()=>{c(),await i.dispose(),e()})})})}export{f as runRpc};
@@ -0,0 +1,3 @@
1
+ import{readFileSync as f,statSync as u}from"node:fs";import{isAbsolute as a,resolve as p}from"node:path";var $=64*1024;function S(o,c){return o.replace(/(^|\s)@([^\s]+)/g,(e,l,i)=>{let t=i.replace(/[),.;:]+$/,""),g=i.slice(t.length),n=a(t)?t:p(c,t);try{let r=u(n);if(!r.isFile()||r.size===0||r.size>$)return e;let s=f(n);return s.includes(0)?e:`${l}<file name="${n}">
2
+ ${s.toString("utf8").trimEnd()}
3
+ </file>${g}`}catch{return e}})}export{S as a};
@@ -0,0 +1,2 @@
1
+ import{spawnSync as s}from"node:child_process";import{accessSync as d,constants as b}from"node:fs";import{join as l}from"node:path";function c(r){try{return d(r,b.X_OK),!0}catch{return!1}}function w(r=process.platform,e=process.env.PATH??""){let n=e.split(":").filter(Boolean),o=t=>n.map(i=>l(i,t)).find(c);if(r==="linux"){let t=o("bwrap");return t&&s(t,["--ro-bind","/","/","--","true"],{stdio:"ignore",timeout:3e3}).status===0?"bubblewrap":void 0}if(r==="darwin")return o("sandbox-exec")?"seatbelt":void 0}function a(r,e){return r==="bubblewrap"?["bwrap","--die-with-parent","--new-session","--ro-bind","/","/","--dev","/dev","--proc","/proc","--tmpfs","/tmp","--bind",e.cwd,e.cwd,"--bind",e.agentDir,e.agentDir,"--chdir",e.cwd,"--",...e.argv]:["sandbox-exec","-p",["(version 1)","(deny default)","(allow process*)","(allow signal)","(allow sysctl-read)","(allow mach-lookup)","(allow network*)","(allow file-read*)",`(allow file-write* (subpath "${e.cwd}") (subpath "${e.agentDir}") (subpath "/tmp") (subpath "/private/tmp") (subpath "/private/var/folders"))`,""].join(`
2
+ `),...e.argv]}function x(r){return r==="bubblewrap"?"sandbox: bubblewrap \u2014 project writable, rest of the filesystem read-only":"sandbox: seatbelt \u2014 project writable, rest of the filesystem read-only"}function g(r,e){let n=s(a(r,e)[0],a(r,e).slice(1),{stdio:"inherit",env:{...process.env,HOWTOFIX_SANDBOXED:"1"}});return n.error?(console.error(`sandbox: could not start ${r}: ${n.error.message}`),1):n.status??1}export{w as a,a as b,x as c,g as d};