bitfolk 0.1.10 → 0.1.12

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 (3) hide show
  1. package/README.md +34 -26
  2. package/dist/cli.js +80 -73
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,19 +1,19 @@
1
1
  // Bitfolk CLI. Copyright (c) 2026 NQB8. All rights reserved. Use is subject to the LICENSE file in this package.
2
- import{createRequire as e}from"node:module";import{execFileSync as t,spawn as n,spawnSync as r}from"node:child_process";import{basename as i,delimiter as a,dirname as o,isAbsolute as s,join as c,relative as l,resolve as u,sep as d}from"node:path";import{parseArgs as f}from"node:util";import{createInterface as p,emitKeypressEvents as m}from"node:readline";import{accessSync as h,appendFileSync as g,chmodSync as _,closeSync as v,constants as y,copyFileSync as b,existsSync as x,lstatSync as ee,mkdirSync as S,mkdtempSync as te,openSync as ne,readFileSync as re,readSync as ie,readdirSync as ae,realpathSync as oe,renameSync as se,rmSync as ce,statSync as le,writeFileSync as ue}from"node:fs";import{homedir as C,hostname as de,tmpdir as fe,userInfo as pe}from"node:os";import{createHash as me,randomBytes as he,randomUUID as ge}from"node:crypto";import{createServer as _e}from"node:http";import{connect as ve}from"node:net";const w=/[\\/]_npx[\\/]/.test(process.argv[1]??``)?`npx bitfolk`:`bitfolk`,ye=w!==`bitfolk`,be=[[`status`,`This computer, its tools and repos, what's waiting`],[`run "<what>"`,`Queue a session here (--in <repo>, --runtime <tool>, --goal <objective>)`],[`sessions`,`Sessions waiting, running and done`],[`logs <id>`,`What a session did`],[`cancel <id>`,`Stop a waiting or running session`],[`approvals`,`What agents wait on you for; approve <id>, deny <id>`],[`chat [<objective>]`,`Read a chat; chat <objective> "<message>" posts`],[`objectives · board <objective> · agents`,`Open objectives, a task board, the agents`],[`tools · repos`,`Coding tools and repos here`],[`help · quit`,`This list · stop up (like Ctrl-C)`]],xe=new Set([`status`,`ls`,`sessions`,`logs`,`log`,`cancel`,`run`,`goals`,`objectives`,`chat`,`say`,`board`,`agents`,`approvals`,`approve`,`deny`,`tools`,`repos`,`repo`,`check`,`doctor`,`version`]);function Se(e){let t=[],n=``,r=!1,i=null;for(let a of e)i?a===i?i=null:n+=a:a===`'`||a===`"`?(i=a,r=!0):/\s/.test(a)?(r&&t.push(n),n=``,r=!1):(n+=a,r=!0);return i?null:(r&&t.push(n),t)}function Ce(e){let t=Se(e.trim());if(!t)return{kind:`error`,message:`a quote isn't closed`};/^(bitfolk|bf)$/.test(t[0]??``)&&t.shift();let[n,...r]=t;return n?n===`help`||n===`?`||n===`-h`||n===`--help`?r.length?{kind:`run`,args:[`help`,...r]}:{kind:`help`}:n===`quit`||n===`exit`||n===`stop`?{kind:`quit`}:xe.has(n)?r.some(e=>e===`--follow`||e===`-f`)?{kind:`error`,message:`--follow doesn't stop by itself; sessions already show in this log as they run`}:n===`run`&&!r.includes(`--detach`)?{kind:`run`,args:[`run`,...r,`--detach`]}:{kind:`run`,args:[n,...r]}:{kind:`error`,message:`${n} isn't available inside up; run it in another tab, or type help for what works here`}:{kind:`none`}}const T=(e=[])=>({text:``,cursor:0,history:e,at:e.length});function we(e,t,n={}){let r=(t,n,r=e.at)=>({state:{...e,text:t,cursor:Math.max(0,Math.min(n,t.length)),at:r}});if(n.ctrl&&n.name===`c`)return{state:e,action:`interrupt`};if(n.ctrl&&n.name===`d`)return e.text?r(e.text.slice(0,e.cursor)+e.text.slice(e.cursor+1),e.cursor):{state:e,action:`eof`};if(n.name===`return`||n.name===`enter`){let t=e.text.trim(),n=t&&e.history[e.history.length-1]!==t?[...e.history,t].slice(-100):e.history;return{state:T(n),action:`submit`,line:t}}if(n.name===`backspace`)return r(e.text.slice(0,Math.max(0,e.cursor-1))+e.text.slice(e.cursor),e.cursor-1);if(n.name===`delete`)return r(e.text.slice(0,e.cursor)+e.text.slice(e.cursor+1),e.cursor);if(n.name===`left`||n.ctrl&&n.name===`b`)return r(e.text,e.cursor-1);if(n.name===`right`||n.ctrl&&n.name===`f`)return r(e.text,e.cursor+1);if(n.name===`home`||n.ctrl&&n.name===`a`)return r(e.text,0);if(n.name===`end`||n.ctrl&&n.name===`e`)return r(e.text,e.text.length);if(n.ctrl&&n.name===`u`)return r(e.text.slice(e.cursor),0);if(n.ctrl&&n.name===`k`)return r(e.text.slice(0,e.cursor),e.cursor);if(n.name===`escape`)return r(``,0,e.history.length);if(n.name===`up`||n.name===`down`){let t=Math.max(0,Math.min(e.history.length,e.at+(n.name===`up`?-1:1))),i=e.history[t]??``;return r(i,i.length,t)}if(n.ctrl||n.meta||!t)return{state:e};let i=t.replace(/[\r\n]+/g,` `).replace(/[\x00-\x1f\x7f]/g,``);return i?r(e.text.slice(0,e.cursor)+i+e.text.slice(e.cursor),e.cursor+i.length):{state:e}}function Te(e,t,r={}){return new Promise(i=>{let a=n(process.execPath,[...process.execArgv,process.argv[1],...e],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,BITFOLK_NO_ANIMATION:`1`,...r.columns?{BITFOLK_COLUMNS:String(r.columns)}:{},...r.colorDepth?{FORCE_COLOR:String(r.colorDepth)}:{}}});for(let e of[a.stdout,a.stderr])p({input:e}).on(`line`,e=>t(` ${e}`));a.on(`error`,e=>{t(` couldn't run it: ${e.message}`),i(1)}),a.on(`close`,e=>i(e??1))})}const Ee=e=>new Date(e<0xe8d4a51000?e*1e3:e).toISOString(),De=e=>typeof e==`number`&&e>0?e%1440==0?`${e/1440}d`:e%60==0?`${e/60}h`:`${e}m`:null;function Oe(e,t,n){let r;try{r=ae(e).sort().reverse()}catch{return null}if(t===0){let t=null;for(let i of r.filter(n).slice(0,50)){let n=c(e,i);try{let e=le(n).mtimeMs;(!t||e>t.mtime)&&(t={path:n,mtime:e})}catch{}}return t?.path??null}for(let i of r.slice(0,3)){let r=Oe(c(e,i),t-1,n);if(r)return r}return null}function ke(e,t=262144){let n=ne(e,`r`);try{let r=le(e).size,i=Math.min(r,t),a=Buffer.alloc(i);return ie(n,a,0,i,r-i),a.toString(`utf8`)}finally{v(n)}}function Ae(e,t,n=0){if(!(!e||typeof e!=`object`||n>6)){if(t in e)return e[t];for(let r of Object.values(e)){let e=Ae(r,t,n+1);if(e!==void 0)return e}}}function je(e,t=Date.now()){let n=[e.primary,e.secondary].filter(e=>!!e&&typeof e==`object`).filter(e=>typeof e.used_percent==`number`&&(typeof e.resets_at!=`number`||e.resets_at*1e3>t)).sort((e,t)=>(t.used_percent??0)-(e.used_percent??0))[0];if(!n)return{at:t};let r=typeof n.resets_at==`number`?Ee(n.resets_at):null,i=!!e.rate_limit_reached_type||(n.used_percent??0)>=100;return{used_percent:Math.round((n.used_percent??0)*10)/10,window:De(n.window_minutes),resets_at:r,limited_until:i?r:null,at:t}}function Me(e=C(),t=Date.now()){let n=c(e,`.codex`,`sessions`);if(!x(n))return null;let r=Oe(n,3,e=>e.endsWith(`.jsonl`));if(!r)return null;let i;try{i=ke(r)}catch{return null}let a=i.split(`
2
+ import{createRequire as e}from"node:module";import{execFileSync as t,spawn as n,spawnSync as r}from"node:child_process";import{basename as i,delimiter as a,dirname as o,isAbsolute as s,join as c,relative as l,resolve as u,sep as d}from"node:path";import{parseArgs as f}from"node:util";import{createInterface as p,emitKeypressEvents as m}from"node:readline";import{accessSync as h,appendFileSync as g,chmodSync as _,closeSync as v,constants as y,copyFileSync as ee,existsSync as b,lstatSync as te,mkdirSync as x,mkdtempSync as ne,openSync as re,readFileSync as ie,readSync as ae,readdirSync as oe,realpathSync as se,renameSync as ce,rmSync as S,statSync as le,writeFileSync as ue}from"node:fs";import{homedir as C,hostname as de,tmpdir as fe,userInfo as pe}from"node:os";import{createHash as me,randomBytes as he,randomUUID as ge}from"node:crypto";import{createServer as _e}from"node:http";import{connect as ve}from"node:net";const w=/[\\/]_npx[\\/]/.test(process.argv[1]??``)?`npx bitfolk`:`bitfolk`,ye=w!==`bitfolk`,be=[[`status`,`This computer, its tools and repos, what's waiting`],[`run "<what>"`,`Queue a session here (--in <repo>, --runtime <tool>, --goal <goal>)`],[`sessions`,`Sessions waiting, running and done`],[`logs <id>`,`What a session did`],[`cancel <id>`,`Stop a waiting or running session`],[`approvals`,`What agents wait on you for; approve <id>, deny <id>`],[`chat [<goal>]`,`Read a chat; chat <goal> "<message>" posts`],[`goals · board <goal> · agents`,`Open goals, a task board, the agents`],[`tools · repos`,`Coding tools and repos here`],[`help · quit`,`This list · stop up (like Ctrl-C)`]],xe=new Set([`status`,`ls`,`sessions`,`logs`,`log`,`cancel`,`run`,`goals`,`objectives`,`chat`,`say`,`board`,`agents`,`approvals`,`approve`,`deny`,`tools`,`repos`,`repo`,`check`,`doctor`,`version`]);function Se(e){let t=[],n=``,r=!1,i=null;for(let a of e)i?a===i?i=null:n+=a:a===`'`||a===`"`?(i=a,r=!0):/\s/.test(a)?(r&&t.push(n),n=``,r=!1):(n+=a,r=!0);return i?null:(r&&t.push(n),t)}function Ce(e){let t=Se(e.trim());if(!t)return{kind:`error`,message:`a quote isn't closed`};/^(bitfolk|bf)$/.test(t[0]??``)&&t.shift();let[n,...r]=t;return n?n===`help`||n===`?`||n===`-h`||n===`--help`?r.length?{kind:`run`,args:[`help`,...r]}:{kind:`help`}:n===`quit`||n===`exit`||n===`stop`?{kind:`quit`}:xe.has(n)?r.some(e=>e===`--follow`||e===`-f`)?{kind:`error`,message:`--follow doesn't stop by itself; sessions already show in this log as they run`}:n===`run`&&!r.includes(`--detach`)?{kind:`run`,args:[`run`,...r,`--detach`]}:{kind:`run`,args:[n,...r]}:{kind:`error`,message:`${n} isn't available inside up; run it in another tab, or type help for what works here`}:{kind:`none`}}const T=(e=[])=>({text:``,cursor:0,history:e,at:e.length});function we(e,t,n={}){let r=(t,n,r=e.at)=>({state:{...e,text:t,cursor:Math.max(0,Math.min(n,t.length)),at:r}});if(n.ctrl&&n.name===`c`)return{state:e,action:`interrupt`};if(n.ctrl&&n.name===`d`)return e.text?r(e.text.slice(0,e.cursor)+e.text.slice(e.cursor+1),e.cursor):{state:e,action:`eof`};if(n.name===`return`||n.name===`enter`){let t=e.text.trim(),n=t&&e.history[e.history.length-1]!==t?[...e.history,t].slice(-100):e.history;return{state:T(n),action:`submit`,line:t}}if(n.name===`backspace`)return r(e.text.slice(0,Math.max(0,e.cursor-1))+e.text.slice(e.cursor),e.cursor-1);if(n.name===`delete`)return r(e.text.slice(0,e.cursor)+e.text.slice(e.cursor+1),e.cursor);if(n.name===`left`||n.ctrl&&n.name===`b`)return r(e.text,e.cursor-1);if(n.name===`right`||n.ctrl&&n.name===`f`)return r(e.text,e.cursor+1);if(n.name===`home`||n.ctrl&&n.name===`a`)return r(e.text,0);if(n.name===`end`||n.ctrl&&n.name===`e`)return r(e.text,e.text.length);if(n.ctrl&&n.name===`u`)return r(e.text.slice(e.cursor),0);if(n.ctrl&&n.name===`k`)return r(e.text.slice(0,e.cursor),e.cursor);if(n.name===`escape`)return r(``,0,e.history.length);if(n.name===`up`||n.name===`down`){let t=Math.max(0,Math.min(e.history.length,e.at+(n.name===`up`?-1:1))),i=e.history[t]??``;return r(i,i.length,t)}if(n.ctrl||n.meta||!t)return{state:e};let i=t.replace(/[\r\n]+/g,` `).replace(/[\x00-\x1f\x7f]/g,``);return i?r(e.text.slice(0,e.cursor)+i+e.text.slice(e.cursor),e.cursor+i.length):{state:e}}function Te(e,t,r={}){return new Promise(i=>{let a=n(process.execPath,[...process.execArgv,process.argv[1],...e],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,BITFOLK_NO_ANIMATION:`1`,...r.columns?{BITFOLK_COLUMNS:String(r.columns)}:{},...r.colorDepth?{FORCE_COLOR:String(r.colorDepth)}:{}}});for(let e of[a.stdout,a.stderr])p({input:e}).on(`line`,e=>t(` ${e}`));a.on(`error`,e=>{t(` couldn't run it: ${e.message}`),i(1)}),a.on(`close`,e=>i(e??1))})}const Ee=e=>new Date(e<0xe8d4a51000?e*1e3:e).toISOString(),De=e=>typeof e==`number`&&e>0?e%1440==0?`${e/1440}d`:e%60==0?`${e/60}h`:`${e}m`:null;function Oe(e,t,n){let r;try{r=oe(e).sort().reverse()}catch{return null}if(t===0){let t=null;for(let i of r.filter(n).slice(0,50)){let n=c(e,i);try{let e=le(n).mtimeMs;(!t||e>t.mtime)&&(t={path:n,mtime:e})}catch{}}return t?.path??null}for(let i of r.slice(0,3)){let r=Oe(c(e,i),t-1,n);if(r)return r}return null}function ke(e,t=262144){let n=re(e,`r`);try{let r=le(e).size,i=Math.min(r,t),a=Buffer.alloc(i);return ae(n,a,0,i,r-i),a.toString(`utf8`)}finally{v(n)}}function Ae(e,t,n=0){if(!(!e||typeof e!=`object`||n>6)){if(t in e)return e[t];for(let r of Object.values(e)){let e=Ae(r,t,n+1);if(e!==void 0)return e}}}function je(e,t=Date.now()){let n=[e.primary,e.secondary].filter(e=>!!e&&typeof e==`object`).filter(e=>typeof e.used_percent==`number`&&(typeof e.resets_at!=`number`||e.resets_at*1e3>t)).sort((e,t)=>(t.used_percent??0)-(e.used_percent??0))[0];if(!n)return{at:t};let r=typeof n.resets_at==`number`?Ee(n.resets_at):null,i=!!e.rate_limit_reached_type||(n.used_percent??0)>=100;return{used_percent:Math.round((n.used_percent??0)*10)/10,window:De(n.window_minutes),resets_at:r,limited_until:i?r:null,at:t}}function Me(e=C(),t=Date.now()){let n=c(e,`.codex`,`sessions`);if(!b(n))return null;let r=Oe(n,3,e=>e.endsWith(`.jsonl`));if(!r)return null;let i;try{i=ke(r)}catch{return null}let a=i.split(`
3
3
  `);for(let e=a.length-1;e>=0;e--)if(a[e].includes(`"rate_limits"`))try{let n=Ae(JSON.parse(a[e]),`rate_limits`);if(n&&typeof n==`object`)return je(n,t)}catch{}return null}function Ne(e,t=Date.now()){let n=typeof e.resetsAt==`number`?Ee(e.resetsAt):null,r=typeof e.utilization==`number`?Math.round(e.utilization*1e3)/10:null,i=typeof e.rateLimitType==`string`?e.rateLimitType:``,a=/five_hour/.test(i)?`5h`:/seven_day|weekly/.test(i)?`7d`:null;return e.status===`rejected`?{used_percent:100,window:a,resets_at:n,limited_until:n??Ee(t+36e5),at:t}:r===null&&e.status!==`allowed_warning`?null:{used_percent:r??80,window:a,resets_at:n,limited_until:null,at:t}}function Pe(e,t=Date.now()){if(!e||!/usage limit|hit your (?:usage )?limit|limit reached|rate limit|quota exceeded|out of credits/i.test(e))return null;let n=/\|(\d{10,13})\b/.exec(e)?.[1],r=Ee(n?Number(n):t+36e5);return{used_percent:100,resets_at:r,limited_until:r,at:t}}function Fe(e,t={},n={}){let r=n.now??Date.now(),i={};for(let a of e){let e=t[a]??null;if(e&&(Date.parse(e.limited_until??e.resets_at??``)||(e.at??0)+864e5)<=r&&(e=null),a===`codex`){let t=Me(n.home,r);t&&(!e?.limited_until||t.limited_until)&&(e=t)}if(e){let{at:t,...n}=e;i[a]=n}}return i}function Ie(e){let t=e;for(let e=0;e<4;e++)if(typeof t==`string`){let e=t.trim();if(!e.startsWith(`{`))return e.slice(0,300)||null;try{t=JSON.parse(e)}catch{return e.slice(0,300)}}else if(t&&typeof t==`object`){let e=t;if(t=e.message??e.error??null,t===null)return null}else return null;return typeof t==`string`?t.slice(0,300):null}const Le=()=>({sessionId:null,inputTokens:0,outputTokens:0,costMicros:null,isError:!1,overBudget:!1,summary:null,error:null,model:null}),E=`[redacted]`,Re=[[/\bbf[a-z]{0,2}_[A-Za-z0-9]{8,}/g,E],[/\bsk-[A-Za-z0-9_-]{8,}/g,E],[/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{8,}/g,E],[/\bgh[pousr]_[A-Za-z0-9]{8,}/g,E],[/\bgithub_pat_[A-Za-z0-9_]{20,}/g,E],[/\bxox[a-z]-[A-Za-z0-9-]{8,}/g,E],[/\beyJ[\w-]{10,}\.[\w-]{10,}\.[\w-]+/g,E],[/\bAKIA[0-9A-Z]{16}\b/g,E],[/\bsb_(?:secret|publishable)_[A-Za-z0-9_-]{8,}/g,E],[/\bAIza[0-9A-Za-z_-]{30,}/g,E],[/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*/g,E],[/\b(bearer|basic)(\s+)[A-Za-z0-9._~+/=-]{8,}/gi,`$1$2${E}`],[/\b([A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PWD|PASS|AUTH|CREDENTIALS?)[A-Z0-9_]*)(\s*[=:]\s*)("[^"]*"|'[^']*'|\S+)/g,`$1$2${E}`],[/(--?(?:password|passwd|token|secret|api-?key|auth)(?:=|\s+))("[^"]*"|'[^']*'|\S+)/gi,`$1${E}`],[/(\bmysql\b.*?\s-p)(\S+)/g,`$1${E}`],[/(\b[a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:)[^\s@/]+@/gi,`$1${E}@`]];function ze(e){let t=e;for(let[e,n]of Re)t=t.replace(e,n);return t}function D(e){if(typeof e!=`string`)return null;let t=e.split(`
4
4
  `).map(e=>e.trim()).find(Boolean);if(!t)return null;let n=ze(t.replace(/\s+/g,` `));return n.length>200?n.slice(0,199)+`…`:n}function Be(e,t){if(typeof e!=`string`||!e)return`a file`;if(t&&s(e)){let n=l(t,e);if(n&&!n.startsWith(`..`)&&!s(n))return n}return e}function Ve(e){let t=Array.isArray(e)?e.length>=3&&/sh$/.test(String(e[0]))&&/^-l?c$/.test(String(e[1]))?String(e.at(-1)):e.join(` `):String(e??``),n=/^(?:\S*\/)?(?:ba|z)?sh\s+-l?c\s+(['"])([\s\S]*)\1$/.exec(t.trim());return ze((n?n[2]:t).trim().replace(/\s+/g,` `)).slice(0,80)}function He(e,t,n){let r=String(e??``).toLowerCase(),i=t.file_path??t.filePath??t.path??t.notebook_path;return[`edit`,`write`,`multiedit`,`notebookedit`,`patch`].includes(r)?`Editing ${Be(i,n)}`:r===`read`?`Reading ${Be(i,n)}`:r===`bash`?`Running ${Ve(t.command)}`:r===`grep`||r===`glob`?`Searching ${ze(String(t.pattern??``)).slice(0,80)}`.trim():`Using ${String(e??`a tool`)}`}const Ue=[`Bash(bitfolk-api:*)`,`Bash(bitfolk share:*)`,`Bash(aside:*)`,`Bash(git status:*)`,`Bash(git diff:*)`,`Bash(git log:*)`,`Bash(git show:*)`,`Bash(git add:*)`,`Bash(git commit:*)`,`Bash(git switch:*)`,`Bash(git branch:*)`];function We(e){let t=e.trim();if(!t.startsWith(`{`))return null;try{return JSON.parse(t)}catch{return null}}const Ge=(e,t=280)=>typeof e==`string`&&e.trim()?e.trim().replace(/\s+/g,` `).slice(0,t):null,Ke=e=>Ge(typeof e==`string`?e.trim().split(`
5
- `).filter(Boolean).at(-1):null);function qe(e){return e===`bypass`?[`--permission-mode`,`bypassPermissions`]:e===`auto`?[`--permission-mode`,`auto`]:[`--permission-mode`,`acceptEdits`,`--allowedTools`,...Ue]}const Je={runtime:`claude_code`,bin:()=>`claude`,launch(e,t,n){return{bin:`claude`,args:[`-p`,`--output-format`,`stream-json`,`--verbose`,`--max-budget-usd`,String(e.maxUsdPerRun),...e.model?[`--model`,e.model]:[],...n?[`--resume`,n]:[],...qe(e.permission)],stdin:t}},parse(e,t){let n=We(e);if(!n)return;typeof n.session_id==`string`&&(t.sessionId=n.session_id),n.type===`system`&&typeof n.model==`string`&&(t.model=n.model),n.type===`rate_limit_event`&&n.rate_limit_info&&typeof n.rate_limit_info==`object`&&(t.limit=Ne(n.rate_limit_info)??t.limit??null);let r=n.message;if(n.type===`assistant`&&r?.usage&&r.id!==t.countedMessage){t.countedMessage=r.id;let e=r.usage;t.inputTokens+=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),t.outputTokens+=e.output_tokens??0}if(n.type===`result`){let e=n.usage??{};t.inputTokens=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),t.outputTokens=e.output_tokens??0,typeof n.total_cost_usd==`number`&&(t.costMicros=Math.round(n.total_cost_usd*1e6)),t.isError=n.is_error===!0||typeof n.subtype==`string`&&n.subtype!==`success`,t.isError&&(t.error=Ie(n.result)??(typeof n.subtype==`string`?n.subtype:null)),t.overBudget=typeof n.subtype==`string`&&n.subtype.includes(`budget`),t.summary=Ke(n.result)??t.summary}},activity(e,t){let n=We(e);if(n?.type!==`assistant`||!Array.isArray(n.message?.content))return null;let r=n.message.content,i=r.find(e=>e?.type===`tool_use`);return D(i?He(i.name,i.input??{},t):r.find(e=>e?.type===`text`)?.text)}};function Ye(e){return e===`bypass`?[`--dangerously-bypass-approvals-and-sandbox`]:[`-c`,`sandbox_mode="workspace-write"`,`-c`,`sandbox_workspace_write.network_access=true`]}const Xe={claude_code:Je,codex:{runtime:`codex`,bin:()=>`codex`,runnerCommits:e=>e.permission!==`bypass`,launch(e,t,n){return{bin:`codex`,args:[`exec`,...n?[`resume`,n]:[],`--json`,`--skip-git-repo-check`,...Ye(e.permission),...e.model?[`-m`,e.model]:[],`-`],stdin:t}},parse(e,t){let n=We(e);n&&(n.type===`thread.started`&&typeof n.thread_id==`string`&&(t.sessionId=n.thread_id),n.type===`turn.completed`&&n.usage&&(t.inputTokens+=n.usage.input_tokens??0,t.outputTokens+=n.usage.output_tokens??0),(n.type===`turn.failed`||n.type===`error`)&&(t.isError=!0,t.error=Ie(n.error??n.message)??t.error),n.type===`item.completed`&&n.item?.type===`agent_message`&&(t.summary=Ke(n.item.text)??t.summary))},activity(e,t){let n=We(e),r=n?.item;if(!r||n.type!==`item.started`&&n.type!==`item.completed`)return null;if(r.type===`command_execution`)return n.type===`item.started`?D(`Running ${Ve(r.command)}`):null;if(n.type!==`item.completed`)return null;if(r.type===`file_change`){let e=(Array.isArray(r.changes)?r.changes:[]).map(e=>Be(e?.path,t));return e.length?D(`Editing ${e[0]}${e.length>1?` and ${e.length-1} more`:``}`):null}return r.type===`agent_message`?D(r.text):null}},opencode:{runtime:`opencode`,bin:()=>`opencode`,launch(e,t,n){return{bin:`opencode`,args:[`run`,`--format`,`json`,...e.model?[`-m`,e.model]:[],...n?[`-s`,n]:[],t],stdin:``}},parse(e,t){let n=We(e);if(!n)return;typeof n.sessionID==`string`&&(t.sessionId=n.sessionID);let r=n.part??{};if(n.type===`text`&&typeof r.text==`string`&&(t.summary=Ke(r.text)??t.summary),n.type===`step_finish`){let e=r.tokens??{};t.inputTokens+=(e.input??0)+(e.cache?.read??0)+(e.cache?.write??0),t.outputTokens+=(e.output??0)+(e.reasoning??0),typeof r.cost==`number`&&(t.costMicros=(t.costMicros??0)+Math.round(r.cost*1e6))}n.type===`error`&&(t.isError=!0,t.error=Ie(n.error?.data?.message??n.error?.message??n.error)??t.error)},activity(e,t){let n=We(e),r=n?.part??{};return n?.type===`tool_use`&&r.tool?D(He(r.tool,r.state?.input??{},t)):n?.type===`text`?D(r.text):null}},hermes:{runtime:`hermes`,bin:()=>`hermes`,resumes:!1,launch(e,t){let n=c(fe(),`bitfolk-hermes-${ge()}.json`);return{bin:`hermes`,args:[`-z`,t,`--usage-file`,n,...e.model?[`-m`,e.model]:[],...e.permission===`safe`?[]:[`--yolo`]],stdin:``,usageFile:n}},parse(e,t){t.summary=Ge(e)??t.summary},activity:e=>D(e),afterExit(e,t){if(e.usageFile)try{let n=JSON.parse(re(e.usageFile,`utf8`)),r=(...e)=>e.map(e=>n[e]??n.usage?.[e]).find(e=>typeof e==`number`);t.inputTokens=r(`input_tokens`,`prompt_tokens`)??t.inputTokens,t.outputTokens=r(`output_tokens`,`completion_tokens`)??t.outputTokens;let i=r(`cost_usd`,`total_cost_usd`,`cost`);i!==void 0&&(t.costMicros=Math.round(i*1e6)),typeof n.session_id==`string`&&(t.sessionId=n.session_id)}catch{}finally{ce(e.usageFile,{force:!0})}}},command:{runtime:`command`,bin:e=>(e.command??``).trim().split(/\s+/)[0]??``,resumes:!1,launch(e,t){if(!e.command)throw Error(`${e.name} has runtime command but no --command`);return{bin:`sh`,args:[`-c`,e.command],stdin:t}},parse(e,t){let n=We(e)?.bitfolk;n&&typeof n==`object`?(typeof n.session_id==`string`&&(t.sessionId=n.session_id),typeof n.input_tokens==`number`&&Number.isFinite(n.input_tokens)&&(t.inputTokens=Math.max(0,Math.round(n.input_tokens))),typeof n.output_tokens==`number`&&Number.isFinite(n.output_tokens)&&(t.outputTokens=Math.max(0,Math.round(n.output_tokens))),typeof n.cost_usd==`number`&&(t.costMicros=Math.round(n.cost_usd*1e6)),typeof n.summary==`string`&&(t.summary=Ge(n.summary))):t.summary=Ge(e)??t.summary},activity(e){return D(We(e)?.bitfolk?.activity)}},acp:{runtime:`acp`,bin:e=>e.acp?.bin??``,resumes:!1,runnerCommits:()=>!0,launch(e){if(!e.acp?.bin)throw Error(`${e.name} has runtime acp but no ACP command`);return{bin:e.acp.bin,args:e.acp.args,stdin:``}},parse(){}}};function Ze(e){return e===`claude_code`||e===`codex`||e===`opencode`||e===`hermes`?e:null}const Qe=2e4;var $e=class extends Error{code;data;constructor(e,t,n){super(t),this.code=e,this.data=n}};const et=e=>new $e(-32601,`${e} isn't supported by this client`);var tt=class{#e=1;#t=new Map;#n;#r;#i=null;constructor(e,t,n){this.#n=e,this.#r=n,e.on(`error`,e=>this.close(Error(`the tool stopped reading its input (${e.code??e.message})`))),p({input:t,crlfDelay:1/0}).on(`line`,e=>this.#o(e)).on(`close`,()=>this.close(Error(`the tool exited before the turn ended`)))}get closed(){return this.#i!==null}close(e){if(!this.#i){this.#i=e;for(let[t,n]of this.#t)n.timer&&clearTimeout(n.timer),this.#t.delete(t),n.reject(e)}}end(){try{this.#n.end()}catch{}}#a(e){if(this.#i||!this.#n.writable)return!1;try{return this.#n.write(JSON.stringify({jsonrpc:`2.0`,...e})+`
6
- `),!0}catch(e){return this.close(Error(`the tool stopped reading its input (${e.message})`)),!1}}request(e,t,n){if(this.#i)return Promise.reject(this.#i);let r=this.#e++;return new Promise((i,a)=>{let o={method:e,resolve:i,reject:a};n&&(o.timer=setTimeout(()=>{this.#t.delete(r),a(Error(`${e} got no answer within ${Math.round(n/1e3)}s`))},n),o.timer.unref?.()),this.#t.set(r,o),this.#a({id:r,method:e,params:t})||(this.#t.delete(r),o.timer&&clearTimeout(o.timer),a(this.#i??Error(`the tool's input is closed`)))})}notify(e,t){this.#a({method:e,params:t})}#o(e){if(this.#i)return;let t=e.trim();if(!t)return;let n;try{n=JSON.parse(t)}catch{n=null}if(!n||typeof n!=`object`||Array.isArray(n)){this.close(Error(`the tool printed something that isn't ACP on stdout: ${ze(t).slice(0,120)}`)),this.#r.protocolError(t);return}let r=n.id!==void 0&&n.id!==null;if(typeof n.method==`string`&&r)return void this.#s(n.id,n.method,n.params);if(typeof n.method==`string`)try{this.#r.notification(n.method,n.params)}catch{}else if(r&&(`result`in n||`error`in n)){let e=this.#t.get(n.id);if(!e)return;if(this.#t.delete(n.id),e.timer&&clearTimeout(e.timer),n.error){let t=n.error;e.reject(new $e(typeof t.code==`number`?t.code:-32603,typeof t.message==`string`?t.message:`error`,t.data))}else e.resolve(n.result)}}async#s(e,t,n){try{let r=await this.#r.request(t,n);this.#a({id:e,result:r??null})}catch(t){let n=t instanceof $e?t:new $e(-32603,t.message);this.#a({id:e,error:{code:n.code,message:n.message}})}}};const nt=/[$`\\\n\r]/,rt=/[;&|<>(){}[\]*?~]/,it=/[$`;&|<>\\*?~\n\r(){}[\]]/;function at(e){if(typeof e!=`string`||nt.test(e))return null;let t=[],n=``,r=!1,i=null;for(let a of e)if(i)a===i?i=null:n+=a;else if(a===`'`||a===`"`)i=a,r=!0;else if(/\s/.test(a))r&&t.push(n),n=``,r=!1;else if(rt.test(a))return null;else n+=a,r=!0;return i?null:(r&&t.push(n),t)}function ot(e){let t=at(e.trim());if(!t)throw Error(`give the command without shell features ($, ~, pipes, ; or backslashes); use a full path instead of ~`);let[n,...r]=t;if(!n)throw Error(`the command is empty`);return{bin:n,args:r}}function st(e){if(!e||typeof e!=`object`)return null;let t=e,n=t.command??t.cmd??t.commandLine,r=e=>Array.isArray(e)&&e.length>0&&e.every(e=>typeof e==`string`);return typeof n==`string`?r(t.args)?[n,...t.args]:n:r(n)?n:null}const ct=e=>/^(?:\/(?:usr\/)?bin\/)?(?:ba|z|da)?sh$/.test(e);function lt(e){let t;if(typeof e==`string`)t=at(e);else{if(!e.every(e=>typeof e==`string`))return null;if(e.length===3&&ct(e[0])&&/^-l?c$/.test(e[1]))return at(e[2]);t=e.some(e=>it.test(e))?null:e.slice()}return!t||t.length===0?null:t.length===3&&ct(t[0])&&/^-l?c$/.test(t[1])?at(t[2]):t}const ut=new Set([`status`,`diff`,`log`,`show`,`add`,`commit`,`switch`,`branch`]),dt=/^(?:-o|-F|-t|--output|--exec-path|--no-index|--file|--template|--git-dir|--work-tree|--namespace|--upload-pack|--receive-pack|--ext-diff|--pathspec-from-file|--config-env|--super-prefix)(?:=|$)/;function ft(e){let[t,n,...r]=e;if(t===`bitfolk-api`)return e.slice(1).some(e=>e.startsWith(`@`))?`it would upload a local file`:null;if(t===`aside`)return null;if(t===`git`){if(!n||!ut.has(n))return`that git command isn't on the safe list`;for(let e of r){if(dt.test(e))return`git ${e.split(`=`)[0]} isn't allowed in safe mode`;if(/^-[A-Za-z]*[Fot]/.test(e)&&!e.startsWith(`--`))return`git ${e} isn't allowed in safe mode`;if(e.startsWith(`/`)||/=\//.test(e)||/^-[A-Za-z]+\//.test(e)||/(?:^|[/=])\.\.(?:\/|$)/.test(e))return`git with a path outside its worktree isn't allowed in safe mode`}return null}return`only bitfolk-api, aside and read-mostly git run in safe mode`}const pt=new Set([`curl`,`wget`,`nc`,`ncat`,`netcat`,`ssh`,`scp`,`sftp`,`telnet`,`ftp`,`socat`,`rsync`,`http`,`https`,`xh`]),mt=new Set([`env`,`printenv`]);function ht(e,t){let n=(Array.isArray(e)?e.join(` `):e).replace(/['"\\]/g,``),r=[t,yt(t)].filter(e=>e&&e!==`/`);if(/\.bitfolk\b/i.test(n)||/bitfolk_/i.test(n)||r.some(e=>n.includes(e)))return`it touches the Bitfolk folder or its variables`;if(/\/proc\/\S*environ/.test(n))return`it reads a process environment`;if(/(?:^|[\s/=:,;&|()<>])\.\.(?:$|[\s/=:,;&|()<>])/.test(n))return`it climbs out of its worktree (..)`;let i=C(),a=i?n.replace(/\$\{HOME\}|\$HOME\b/g,i).replace(/(^|[\s=:,;&|(<>])~(?=\/|$|[\s;&|)<>])/g,`$1${i}`):n,o=r.map(e=>e.toLowerCase());for(let e of a.split(/[\s;&|()<>`{}=:,]+/)){if(!e.startsWith(`/`))continue;let t=e.search(/[*?[]/);if(t>=0){let n=e.slice(0,e.lastIndexOf(`/`,t)+1).toLowerCase();if(o.some(e=>(e+`/`).startsWith(n)))return`it could reach the Bitfolk folder`;continue}let n=yt(e.replace(/\/+$/,``)||`/`).toLowerCase();if(o.some(e=>e===n||e.startsWith(n.endsWith(`/`)?n:n+`/`)))return`it could reach the Bitfolk folder`}let s=n.split(/[\s;&|()<>`${}]+/).filter(Boolean).map(e=>e.split(`/`).pop()??e);return s.some(e=>pt.has(e))?`it uses a network tool`:s.some(e=>mt.has(e))||/(?:^|[;&|(]\s*)(?:set|export|declare|typeset)(?:\s+-p\b|\s*$|\s*[;&|)])/.test(n)||/\bcompgen\s+-[ev]/.test(n)?`it could print the environment`:null}function gt(e,t){let n={...e??{}};if(t&&typeof t==`object`)for(let[e,r]of Object.entries(t))r!=null&&(n[e]=r);return n}const _t=/^(?:paths?|files?|file_?paths?|notebook_?path|absolute_?path|dir_?path|dir|directory|folder|cwd|workdir|working_?directory|source|destination|target|old_?path|new_?path|target_?file|target_?directory)$/i;function vt(e){let t=[],n=(e,r)=>{if(!(!e||typeof e!=`object`||r>3)){if(Array.isArray(e))return e.forEach(e=>n(e,r+1));for(let[i,a]of Object.entries(e)){if(_t.test(i)){if(typeof a==`string`)t.push(a);else if(Array.isArray(a))for(let e of a)typeof e==`string`&&t.push(e)}a&&typeof a==`object`&&n(a,r+1)}}};n(e.rawInput,0);for(let n of Array.isArray(e.content)?e.content:[]){let e=n;e&&e.type===`diff`&&typeof e.path==`string`&&t.push(e.path)}return t}function yt(e){try{return oe(e)}catch{let t=o(e);return t===e?e:c(yt(t),i(e))}}const bt=(e,t)=>e===t||e.startsWith(t.endsWith(d)?t:t+d),xt=new Set([`.claude`,`.opencode`,`.gemini`,`.cursor`,`.kilocode`,`.codex`,`.qwen`,`.cline`,`.kimi`]),St=new Set([`opencode.json`,`opencode.jsonc`]),Ct=new Set([`.husky`,`.githooks`,`.lefthook`,`.git-hooks`,`git-hooks`]),wt=/^(?:\.pre-commit-config\.ya?ml|\.pre-commit-hooks\.ya?ml|\.?lefthook(?:-local)?\.(?:ya?ml|json|toml)|\.overcommit\.ya?ml|\.lintstagedrc(?:\..+)?|lint-staged\.config\..+|\.simple-git-hooks(?:\..+)?|simple-git-hooks\..+)$/;function Tt(e){return e.normalize(`NFC`).replace(/[​-‏‪-‮⁠-]/g,``).toLowerCase()}function Et(e,t){if(typeof e!=`string`||!e||e.includes(`\0`))return`an empty path`;if(!s(e))return`a relative path`;if(e.split(/[\\/]/).includes(`..`))return`a path with ..`;let n=yt(t.cwd),r=yt(e);if(!bt(r,n))return bt(r,yt(t.home))?`a path in the Bitfolk folder`:`a path outside its worktree`;if(t.write){let e=l(n,r).split(d).filter(Boolean).map(Tt);if(e.includes(`.git`))return`git's own files`;if(e.some(e=>xt.has(e)||e.startsWith(`.goose`)||St.has(e)))return`an agent settings file`;if(e.some(e=>Ct.has(e)||wt.test(e)))return`a git hook setup`}return null}function Dt(e){let n;try{let r=t(`git`,[`-C`,e,`-c`,`core.fsmonitor=false`,`rev-parse`,`--git-path`,`hooks`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],timeout:5e3}).trim();if(!r||r===`/dev/null`)return!1;n=s(r)?r:c(e,r)}catch{return!1}try{return ae(n).some(e=>{if(e.endsWith(`.sample`))return!1;try{let t=le(c(n,e));return t.isFile()&&!!(t.mode&73)}catch{return!1}})}catch{return!1}}function Ot(e,t){if(typeof e!=`string`||!e)return`a file`;let n=Be(e,t);if(n!==e)return n;let r=C();return r&&r!==`/`&&(e===r||e.startsWith(r+d))?`~`+e.slice(r.length):e}function kt(e,t){let n=e.rawInput&&typeof e.rawInput==`object`?e.rawInput:{},r=typeof e.title==`string`&&e.title.trim()?e.title.trim():null,i=vt(e)[0]??e.locations?.find(e=>typeof e?.path==`string`)?.path,a=e=>i?`${e} ${Ot(i,t)}`:r?`${e} ${r.replace(RegExp(`^${e}\\s+`,`i`),``)}`:`${e} a file`,o=e=>typeof e==`string`&&e?e:null;switch(e.kind){case`execute`:{let e=st(n);return D(`Running ${e?Ve(e):r??`a command`}`)}case`edit`:return D(a(`Editing`));case`delete`:return D(a(`Deleting`));case`move`:return D(a(`Moving`));case`read`:return D(a(`Reading`));case`search`:return D(`Searching ${ze(o(n.pattern)??o(n.query)??r??``).slice(0,80)}`.trim());case`fetch`:return D(`Fetching ${o(n.url)??r??`a web page`}`);case`think`:return null;case`switch_mode`:return D(`Switching mode${r?`: ${r}`:``}`);default:return D(r?`Using ${r}`:`Using a tool`)}}const At=new Set([`read`,`search`,`edit`,`delete`,`move`]),jt=new Set([`edit`,`delete`,`move`]);function Mt(e){let{toolCall:t,permission:n,cwd:r,home:i}=e,a=Array.isArray(e.options)?e.options.filter(e=>e&&typeof e.optionId==`string`):[],o=kt(t,r)??(t.kind===`think`?`Thinking`:`Using a tool`),s=(e,t)=>{if(e){let n=a.find(e=>e.kind===`allow_once`);if(n)return{allow:e,reason:t,what:o,cancelTurn:!1,outcome:{outcome:{outcome:`selected`,optionId:n.optionId}}};t=`${t}, but the tool offered no allow-once choice`}let n=a.find(e=>e.kind===`reject_once`);return n?{allow:!1,reason:t,what:o,cancelTurn:!1,outcome:{outcome:{outcome:`selected`,optionId:n.optionId}}}:{allow:!1,reason:`${t}; no reject-once choice, so the turn stops`,what:o,cancelTurn:!0,outcome:{outcome:{outcome:`cancelled`}}}},c=t.kind;if(typeof c!=`string`||!c)return s(!1,`the tool didn't say what kind of call this is`);if(n===`bypass`)return s(!0,`bypass mode`);if(n!==`safe`&&n!==`auto`)return s(!1,`unknown permission mode`);if(c===`think`)return s(!0,`thinking`);let l=vt(t);for(let e of l){let t=Et(e,{cwd:r,home:i,write:jt.has(c)});if(t)return s(!1,`${t}: ${Ot(e,r)}`)}if(At.has(c))return l.length===0?s(!1,`no file path in the request`):s(!0,jt.has(c)?`a change inside its worktree`:`inside its worktree`);if(c===`execute`){let a=st(t.rawInput);if(!a)return s(!1,`the command isn't in a shape the runner can check`);if(n===`safe`){let t=lt(a);if(!t)return s(!1,`the command uses shell features (safe mode allows a plain command only)`);let n=ft(t);return n?s(!1,n):t[0]===`git`&&(t[1]===`commit`||t[1]===`switch`)&&(e.gitHooks??Dt(r))?s(!1,`this repo has git hooks, which can run anything; the runner commits the work when the turn ends`):s(!0,`on the safe list`)}let o=ht(a,i);return o?s(!1,o):s(!0,`auto mode`)}return c===`fetch`?n===`auto`?s(!0,`auto mode allows the web`):s(!1,`safe mode doesn't fetch from the web`):c===`switch_mode`?s(!1,`changing the agent's mode needs its owner`):s(!1,`${c===`other`?`tools of kind other (MCP and the like)`:`kind ${c}`} aren't allowed in ${n} mode`)}const Nt={opencode:{safe:`build`,auto:`build`,bypass:`build`},gemini:{safe:`default`,auto:`default`,bypass:`yolo`},cursor_agent:{safe:`agent`,auto:`agent`,bypass:`agent`}};function Pt(e){let t=[];for(let n of Array.isArray(e.options)?e.options:[]){let e=n;if(typeof e?.value==`string`&&t.push(e.value),Array.isArray(e?.options))for(let n of e.options)typeof n?.value==`string`&&t.push(n.value)}return t}const Ft={refusal:`the agent refused to go on (refusal)`,max_tokens:`the agent hit its output token limit (max_tokens)`,max_turn_requests:`the agent hit its limit of model requests for one turn (max_turn_requests)`};var It=class{#e;#t;#n=null;#r=!1;#i=[];#a=null;#o=null;#s=null;#c=new Map;#l=null;#u=null;#d=!1;#f=[];#p=0;#m=0;#h=!1;#g=!1;#_=!1;constructor(e){this.#e=e,this.#t=new tt(e.stdin,e.stdout,{request:(e,t)=>this.#w(e,t),notification:(e,t)=>this.#E(e,t),protocolError:t=>{e.log(`out`,t.length>Qe?`[a ${Math.round(t.length/1e3)} KB line that isn't ACP]`:t),e.kill()}})}get cancelReason(){return this.#a}#v(e){let t=JSON.stringify(e);this.#e.log(`acp`,t.length>Qe?JSON.stringify({note:`skipped a ${Math.round(t.length/1e3)} KB entry`,...`event`in e?{event:e.event}:{}}):t)}cancel(e){return this.#_?!1:this.#a?!0:(this.#a=e,this.#v({event:`cancel`,reason:e}),!this.#n||this.#t.closed?(this.#e.kill(),!0):(this.#t.notify(`session/cancel`,{sessionId:this.#n}),this.#s=setTimeout(()=>this.#e.kill(),this.#e.cancelGraceMs??1e4),this.#s.unref?.(),!0))}async run(){let e=this.#e,t=e.handshakeMs??3e4,n;try{let r=await this.#t.request(`initialize`,{protocolVersion:1,clientCapabilities:{},clientInfo:{name:`bitfolk`,version:e.clientVersion}},t);if(r?.protocolVersion!==1)throw Error(`${e.label} speaks ACP v${String(r?.protocolVersion??`?`)}; this runner speaks v1`);if(this.#r=!!r?.agentCapabilities?.sessionCapabilities?.close,this.#i=Array.isArray(r?.authMethods)?r.authMethods:[],this.#v({event:`initialize`,agent:r?.agentInfo??null,auth:this.#i.map(e=>e?.id),close:this.#r}),this.#a)throw Error(`stopped before the session started`);let i=await this.#t.request(`session/new`,{cwd:e.cwd,mcpServers:[]},t);if(typeof i?.sessionId!=`string`)throw Error(`${e.label} started no session`);if(this.#n=i.sessionId,e.tally.sessionId=i.sessionId,await this.#S(i),this.#a)throw Error(`stopped before the prompt`);e.log(`acp`,JSON.stringify({event:`prompt`,chars:e.packet.length}));let a=await this.#t.request(`session/prompt`,{sessionId:this.#n,prompt:[{type:`text`,text:e.packet}]});this.#O(),this.#A(a?.usage);let o=typeof a?.stopReason==`string`?a.stopReason:null;this.#v({event:`turn`,stopReason:o,usage:a?.usage??null}),n={ok:o===`end_turn`,stopReason:o,exited:!1,error:o===`end_turn`?null:this.#y(o)}}catch(e){this.#O(),n={ok:!1,stopReason:null,exited:!1,error:this.#b(e)},!(e instanceof $e)&&/exited|stopped reading/.test(e.message)&&(n.exited=!0),this.#v({event:`turn`,error:n.error})}return e.tally.summary=Ke(this.#u)??e.tally.summary,n.ok||(e.tally.isError=!0,e.tally.overBudget&&e.tally.error||(e.tally.error=n.error)),await this.#j(),n}#y(e){return e===`cancelled`?this.#a===`policy`?this.#o??`the turn was stopped`:this.#a===`budget`?`went over its $${this.#e.agent.maxUsdPerRun} budget`:this.#a===`owner`?`stopped by its owner`:this.#a===`timeout`?`stopped: out of time`:`the agent cancelled the turn`:(e&&Ft[e])??`the agent stopped (${e??`no reason given`})`}#b(e){if(this.#a===`policy`&&this.#o)return this.#o;if(e instanceof $e){if(e.code===-32e3)return this.#x();let t=e.data;return Ie(t&&typeof t==`object`&&t.details!==void 0?t.details:e.message)??e.message}return e.message}#x(){let e=this.#i.map(e=>e?.description??e?.name).filter(e=>typeof e==`string`&&!!e.trim());return e.length?`sign in to ${this.#e.label} in a terminal on this computer first: ${e.join(`; `)}`.slice(0,300):`sign in to ${this.#e.label} in a terminal on this computer first`}async#S(e){let t=this.#e,n=this.#n,r=t.agent.acp.agent,i=Nt[r]?.[t.agent.permission],a=Array.isArray(e?.configOptions)?e.configOptions.filter(e=>e&&typeof e.id==`string`):[];this.#v({event:`session`,sessionId:n,config:a.map(e=>({id:e.id,category:e.category??null,current:e.currentValue??null})),modes:e?.modes?{current:e.modes.currentModeId??null,available:(e.modes.availableModes??[]).map(e=>e?.id)}:null});let o=async(e,r)=>{let i=await this.#t.request(`session/set_config_option`,{sessionId:n,configId:e.id,value:r},t.handshakeMs??3e4);a=Array.isArray(i?.configOptions)?i.configOptions.filter(e=>e&&typeof e.id==`string`):a.map(t=>t.id===e.id?{...t,currentValue:r}:t)},s=e=>a.find(t=>t.category===e)??a.find(t=>t.id===e);if(a.length){let e=s(`mode`);if(i&&e&&e.currentValue!==i&&Pt(e).includes(i))try{await o(e,i),this.#v({event:`mode`,mode:i})}catch(e){this.#v({event:`mode`,mode:i,error:this.#b(e)})}let n=s(`model`);if(t.agent.model&&n&&n.currentValue!==t.agent.model)try{await o(n,t.agent.model)}catch(e){this.#v({event:`model`,wanted:t.agent.model,error:this.#b(e),using:s(`model`)?.currentValue??null})}else t.agent.model&&!n&&this.#v({event:`model`,wanted:t.agent.model,error:`${t.label} offers no model choice over ACP; it uses its own`})}else if(e?.modes&&Array.isArray(e.modes.availableModes)){let r=e.modes.availableModes.map(e=>e?.id);if(i&&e.modes.currentModeId!==i&&r.includes(i))try{await this.#t.request(`session/set_mode`,{sessionId:n,modeId:i},t.handshakeMs??3e4),this.#v({event:`mode`,mode:i})}catch(e){this.#v({event:`mode`,mode:i,error:this.#b(e)})}t.agent.model&&this.#v({event:`model`,wanted:t.agent.model,error:`${t.label} offers no model choice over ACP; it uses its own`})}if(this.#C(a),!a.some(e=>e.category===`model`||e.id===`model`)&&typeof e?.models?.currentModelId==`string`&&e.models.currentModelId&&(t.tally.model=e.models.currentModelId,t.agent.model&&t.agent.model!==e.models.currentModelId&&this.#v({event:`model`,wanted:t.agent.model,using:e.models.currentModelId,error:`${t.label} can't change its model over ACP`})),t.agent.permission===`safe`&&!Nt[r]){let e=`safe mode is enforced through ${t.label}'s permission requests; its own settings may allow more`;t.log(`acp`,JSON.stringify({event:`note`,note:e})),t.activity(D(e))}}#C(e){if(!Array.isArray(e))return;this.#f=e.filter(e=>e&&typeof e.id==`string`);let t=this.#f.find(e=>e.category===`model`)??this.#f.find(e=>e.id===`model`);typeof t?.currentValue==`string`&&t.currentValue&&(this.#e.tally.model=t.currentValue)}#w(e,t){if(e===`session/request_permission`)return this.#T(t);throw this.#v({event:`unsupported`,method:e}),et(e)}#T(e){if(this.#a)return{outcome:{outcome:`cancelled`}};let t=typeof e?.toolCall?.toolCallId==`string`?e.toolCall.toolCallId:null,n=gt(t?this.#c.get(t):void 0,e?.toolCall);t&&this.#c.set(t,n);let r=Mt({toolCall:n,options:e?.options??[],permission:this.#e.agent.permission,cwd:this.#e.cwd,home:this.#e.home});if(!r.allow&&n.kind===`execute`&&!st(n.rawInput)&&!this.#g){this.#g=!0;let e=`${this.#e.label} doesn't say which command it wants to run, so ${this.#e.agent.permission} mode can't allow shell commands; it can still read and edit files in its worktree`;this.#e.log(`acp`,JSON.stringify({event:`note`,note:e})),this.#e.activity(D(e))}let i=r.outcome.outcome.outcome===`selected`?r.outcome.outcome.optionId:null;return this.#v({event:`permission`,decision:r.allow?`allowed`:`refused`,what:r.what,kind:n.kind??null,reason:ze(r.reason),option:i}),this.#e.activity(D(`${r.allow?`Allowed`:`Refused`}: ${r.what}`)),r.cancelTurn&&(this.#o=`refused ${r.what.charAt(0).toLowerCase()}${r.what.slice(1)}, and ${this.#e.label} offered no way to refuse just that, so the turn was stopped`.slice(0,300),setImmediate(()=>this.cancel(`policy`))),r.outcome}#E(e,t){if(e!==`session/update`)return;let n=t?.update;if(n&&typeof n==`object`&&!(this.#n&&t.sessionId&&t.sessionId!==this.#n))switch(n.sessionUpdate){case`agent_message_chunk`:n.content?.type===`text`&&typeof n.content.text==`string`&&this.#D(n.content.text,typeof n.messageId==`string`?n.messageId:null);return;case`tool_call`:case`tool_call_update`:{let e=typeof n.toolCallId==`string`?n.toolCallId:null,t=e?this.#c.get(e):void 0;n.sessionUpdate!==`tool_call`&&t||(this.#d=!0,this.#l&&!this.#l.id&&this.#O());let r=gt(t,n);if(e&&this.#c.set(e,r),n.sessionUpdate===`tool_call`||!t){let e=kt(r,this.#e.cwd);e&&(this.#e.activity(e),this.#v({event:`tool`,kind:r.kind??null,what:e}))}return}case`usage_update`:return this.#k(n.cost);case`config_option_update`:return this.#C(n.configOptions);case`current_mode_update`:return this.#v({event:`mode`,mode:n.currentModeId??n.modeId??null});default:return}}#D(e,t){let n=this.#l;(!n||(t?n.id!==t:this.#d))&&(this.#O(),this.#l={id:t,text:``}),this.#d=!1,this.#l.text+=e}#O(){let e=this.#l;this.#l=null,e&&e.text.trim()&&(this.#u=e.text,this.#e.log(`acp`,JSON.stringify({event:`message`,text:e.text.slice(0,4e3)})),this.#e.activity(D(e.text)))}#k(e){if(!e||typeof e!=`object`||typeof e.amount!=`number`||!Number.isFinite(e.amount))return;let t=this.#e.tally;if(String(e.currency??``).toUpperCase()!==`USD`){this.#h||(this.#h=!0,this.#v({event:`cost`,note:`cost comes in ${String(e.currency)}, not USD: no spend is recorded and the budget cap is off`})),t.costMicros=null;return}e.amount<this.#m&&(this.#p+=this.#m),this.#m=e.amount;let n=this.#p+e.amount;t.costMicros=Math.round(n*1e6),n>=this.#e.agent.maxUsdPerRun&&!t.overBudget&&(t.overBudget=!0,t.error=`spent $${n.toFixed(2)}, over its $${this.#e.agent.maxUsdPerRun} budget`,this.#e.activity(D(`Stopping: ${t.error}`)),this.cancel(`budget`))}#A(e){if(!e||typeof e!=`object`)return;let t=e=>typeof e==`number`&&Number.isFinite(e)&&e>0?Math.round(e):0,n=t(e.inputTokens),r=t(e.outputTokens),i=t(e.thoughtTokens),a=t(e.cachedReadTokens)+t(e.cachedWriteTokens),o=t(e.totalTokens);if(!n&&!r)return;let s=!o||o===n+r+i+a,c=this.#e.tally;c.inputTokens=s?n+a:n,c.outputTokens=s||o===n+r+i?r+i:r}async#j(){this.#_=!0,this.#s&&clearTimeout(this.#s),this.#n&&this.#r&&!this.#t.closed&&await this.#t.request(`session/close`,{sessionId:this.#n},2e3).catch(()=>{}),this.#s&&clearTimeout(this.#s),this.#t.close(Error(`the turn is over`)),this.#t.end(),this.#e.kill()}};async function Lt(e,t={}){let r=n(e.bin,e.args,{cwd:t.cwd,env:{...t.env??process.env,NO_BROWSER:`1`},stdio:[`pipe`,`pipe`,`ignore`],detached:!0}),i=null;r.on(`error`,t=>{i=t.code===`ENOENT`?Error(`${e.bin} isn't installed or isn't on PATH`):t});let a=new tt(r.stdin,r.stdout,{request:e=>{throw et(e)},notification:()=>{},protocolError:()=>{}});try{let e=await a.request(`initialize`,{protocolVersion:1,clientCapabilities:{},clientInfo:{name:`bitfolk`,version:t.version??`0`}},t.timeoutMs??5e3);return{protocolVersion:e?.protocolVersion,agentInfo:e?.agentInfo&&typeof e.agentInfo==`object`?e.agentInfo:null,authMethods:Array.isArray(e?.authMethods)?e.authMethods:[]}}catch(e){throw i??e}finally{a.close(Error(`done`)),a.end();try{r.pid&&process.kill(-r.pid,`SIGKILL`)}catch{r.kill(`SIGKILL`)}}}const Rt=e(import.meta.url)(`../package.json`).version,zt=`https://bitfolk.ai`;var Bt=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}},Vt=class{base;#e;constructor(e,t){this.base=e,this.#e=t}async call(e,t,n={}){let r=typeof this.#e==`string`?this.#e:await this.#e(),i;try{i=await fetch(`${this.base.replace(/\/+$/,``)}${t}`,{method:e,headers:{authorization:`Bearer ${r}`,"user-agent":`bitfolk-cli/${Rt}`,...n.body===void 0?{}:{"content-type":`application/json`},...n.headers},body:n.body===void 0?void 0:JSON.stringify(n.body),signal:AbortSignal.timeout(2e4)})}catch(e){throw new Bt(0,`network`,`can't reach ${this.base}: ${e.message}`)}return i}async json(e){let t=await e.json().catch(()=>null);if(!e.ok)throw new Bt(e.status,t?.error??`http_error`,t?.error??`HTTP ${e.status}`);return t}async request(e,t,n){return this.json(await this.call(e,t,{body:n}))}async setup(){return this.json(await this.call(`GET`,`/v1/setup`))}async peek(e){let t=await this.call(`GET`,`/v1/peek`,{headers:e?{"if-none-match":`"${e}"`}:{}});return t.status===304?null:this.json(t)}async status(e){await this.json(await this.call(`POST`,`/v1/status`,{body:{activity:e}}))}async runStart(e){let t=await this.call(`POST`,`/v1/runs`,{body:e});return t.status===404||t.status===405?null:this.json(t)}async runFinish(e,t){await this.json(await this.call(`POST`,`/v1/runs/${e}`,{body:t}))}},Ht=class{#e;constructor(e,t){this.#e=new Vt(e,t)}me(){return this.#e.request(`GET`,`/v1/machine`)}peek(){return this.#e.request(`GET`,`/v1/machine/peek`)}claim(e){return this.#e.request(`POST`,`/v1/machine/claim`,e)}setTools(e,t){return this.#e.request(`POST`,`/v1/machine/tools`,t===void 0?{runtimes:e}:{runtimes:e,primary:t??``})}report(e){return this.#e.request(`POST`,`/v1/machine/report`,e)}finish(e,t){return this.#e.request(`POST`,`/v1/machine/sessions/${e}`,t)}openApp(e){return this.#e.request(`POST`,`/v1/machine/apps`,e)}beatApp(e){return this.#e.request(`POST`,`/v1/machine/apps/${e}`)}stopApp(e){return this.#e.request(`DELETE`,`/v1/machine/apps/${e}`)}start(e){return this.#e.request(`POST`,`/v1/machine/sessions`,e)}sessions(e=15){return this.#e.request(`GET`,`/v1/machine/sessions?limit=${e}`)}session(e){return this.#e.request(`GET`,`/v1/machine/sessions/${encodeURIComponent(e)}`)}cancel(e){return this.#e.request(`DELETE`,`/v1/machine/sessions/${encodeURIComponent(e)}`)}goals(){return this.#e.request(`GET`,`/v1/machine/goals`)}chats(){return this.#e.request(`GET`,`/v1/machine/chats`)}chat(e){let t=new URLSearchParams;return e.goal&&t.set(`goal`,e.goal),e.after&&t.set(`after`,e.after),e.limit&&t.set(`limit`,String(e.limit)),this.#e.request(`GET`,`/v1/machine/chat?${t}`)}say(e){return this.#e.request(`POST`,`/v1/machine/chat`,e)}board(e){return this.#e.request(`GET`,`/v1/machine/board?goal=${encodeURIComponent(e)}`)}addTask(e){return this.#e.request(`POST`,`/v1/machine/board`,e)}agents(){return this.#e.request(`GET`,`/v1/machine/agents`)}approvals(e,t=30){return this.#e.request(`GET`,`/v1/machine/approvals?status=${e}&limit=${t}`)}decide(e){return this.#e.request(`POST`,`/v1/machine/approvals`,e)}async checkpoint(e,t){try{return(await this.#e.request(`POST`,`/v1/machine/sessions/${e}/checkpoint`,t))?.saved===!0}catch{return!1}}async progress(e,t){try{let n=await this.#e.request(`POST`,`/v1/machine/sessions/${e}/progress`,t);return{canceled:n?.canceled===!0,status:typeof n?.status==`string`?n.status:`running`}}catch(e){return{canceled:!1,status:e instanceof Bt&&(e.status===404||e.status===405)?`not_found`:`error`}}}};const Ut=[`claude_code`,`codex`,`opencode`,`hermes`,`command`],Wt=[`safe`,`auto`,`bypass`],Gt={maxUsdPerRun:1,maxRunsPerHour:6,timeoutMin:45,permission:`auto`};function O(){return process.env.BITFOLK_HOME||c(C(),`.bitfolk`)}function Kt(){let e=O();return x(e)||S(e,{recursive:!0,mode:448}),e}function qt(e,t){if(!x(e))return t;try{return JSON.parse(re(e,`utf8`))}catch{throw Error(`${e} is not valid JSON. Fix or delete it.`)}}function Jt(e,t){Kt();let n=`${e}.${process.pid}.tmp`;ue(n,JSON.stringify(t,null,2)+`
7
- `,{mode:384}),se(n,e),_(e,384)}const Yt=()=>c(O(),`config.json`),Xt=()=>c(O(),`state.json`);function k(){let e=qt(Yt(),{version:1,maxConcurrent:2,agents:[]});return e.agents=e.agents.map(e=>({...Gt,...e})),e.machine&&={...Gt,...e.machine},e}const Zt=e=>Jt(Yt(),e),Qt=()=>qt(Xt(),{agents:{}}),$t=e=>Jt(Xt(),e);function en(e,t=[]){let n=e.toLowerCase().normalize(`NFKD`).replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,30)||`agent`,r=new Set(t),i=n;for(let e=2;r.has(i);e++)i=`${n}-${e}`;return i}function tn(e,t){let n=t.toLowerCase();return e.agents.find(e=>e.slug===n||e.name.toLowerCase()===n||e.id.startsWith(n))}function nn(e,t){let n=t.workspace?.name??e.workspace,r=t.machine?.name||e.name;if(n===e.workspace&&r===e.name)return e;try{let t=k();return t.machine?.id===e.id?(t.machine={...t.machine,workspace:n,name:r},Zt(t),t.machine):e}catch{return{...e,workspace:n,name:r}}}const rn={coral:`#f25c3b`,coralDark:`#c8432a`,grass:`#6fae4b`,grassDark:`#4c8a35`,gold:`#f2c14e`,sky:`#d7ecf7`,ink:`#0e0f11`},an={0:`#f0d27a`,1:`#d1a74c`,2:`#9c7433`,3:`#a9ab93`,4:`#7b7f6a`,8:`#22573a`,C:`#8a3c2a`,D:`#4b3326`,G:`#6fae4b`,H:`#4c8a35`,J:`#9bd36a`,L:`#fff3c4`,M:`#c99a3a`,O:`#337a4b`,P:`#7d4fc9`,Q:`#35692a`,R:`#c94f33`,V:`#cfc2a8`,W:`#e6dcc8`,Y:`#d79a22`,Z:`#9a9488`,c:`#b5523a`,d:`#5b3a29`,g:`#9fd3ea`,h:`#5fae6a`,j:`#c6ea8a`,k:`#f2c14e`,m:`#f4d58d`,o:`#32343a`,p:`#b06cff`,q:`#e8556d`,t:`#7a5236`,u:`#5b3a29`,w:`#fbf6ec`,y:`#f2c14e`,z:`#c9c2b4`},on=[`#.....#..#.....##.......#..#....`,`#........#....#.........#..#....`,`####..#.####.####..###..#..#..#.`,`#...#.#..#....#...#...#.#..#.#..`,`#...#.#..#....#...#...#.#..##...`,`#...#.#..#....#...#...#.#..#.#..`,`####..#...##..#....###...#.#..#.`],A={cottage:[`..........oooooo.o33o.....`,`.......ooo001122oo33o.....`,`.....oo0000111122223o.....`,`....o0100111211222222o....`,`...o000001111111222222o...`,`...o000001111111222222o...`,`..o10010021121122222222o..`,`.o0000000111111112222222o.`,`.o0000000111111112222222o.`,`o121212121212121212121212o`,`.oddddddddddddddddddddddo.`,`.odwwdwwdwwuuuuwwdWWdWWdo.`,`.odwdwwwdwwttuuwwdWWWdWdo.`,`.oddwwwwdwwttuuwwdWWWWddo.`,`.odddddddddttuudddddddddo.`,`.odwLdLwdwwttukwwdWLdLWdo.`,`.odwdddwdwwttuuwwdWdddWdo.`,`.odwLdLwdwwttuuwwdWLdLWdo.`,`.odwqywpdwwttuuwwdyWqpWdo.`,`o444444444444444444444444o`],cabin:[`..o343o....oo...........`,`..o433o..ootuoo.........`,`..o33DooottDuuDoo.......`,`..o334otttttuuuuuoo.....`,`..o3DttDttDtuDuuDuuoo...`,`.ootttttttttuuuuuuuuuoo.`,`ottDttDttDttDuuDuuDuuDuo`,`omttttttttttttttttttttmo`,`oMuuuuuuuuuuuuuuuuuuuuMo`,`omttttttttttttttttttttmo`,`oMuuLLDLuuuuuuddDDugguMo`,`omttDDDDttttttddDDtggtmo`,`oMuuLLDLuuuuuuddDDuuuuMo`,`omttttttttttttddDDttttmo`,`oMuuuuuuuuuuuudkDDuuuuMo`,`omttttttttttttddDDttttmo`,`oMuuuuuuuuuuuuddDDuuuuMo`,`omttttttttttttddDDttttmo`,`oDDDDDDDDDDDDDDDDDDDDDDo`],roundhouse:[`..........ouuo..........`,`..........ouuo..........`,`.........o0112o.........`,`........o101222o........`,`.......o00111222o.......`,`......o0001111222o......`,`.....o100111212222o.....`,`.....o000011112222o.....`,`....o00001111122222o....`,`...o0010021121122222o...`,`..o000001111111222222o..`,`.o00000011111112222222o.`,`o2121212121212121212121o`,`.oo34333333433334Z44Zoo.`,`..o33334333dd343Z44Z4o..`,`..o43gL333ddDD3344Z44o..`,`..o33LL333ddDD334Z44Zo..`,`..o3333334ddDD33Z44Z4o..`,`..o3343333ddDk3344Z44o..`,`..o3333343ddDD344Z44Zo..`,`ooGJ433333ddDD33Z44ZGqoo`],barn:[`..........oooooo..........`,`........oottttttoo........`,`......oouuuuuDDDDDoo......`,`....oouuuuuuuDDDDDDDoo....`,`...ouuuuuuuwwwwDDDDDDDo...`,`..ouuuuuuuu1110DDDDDDDDo..`,`..ouuuuuuuu1211DDDDDDDDo..`,`.ouuuuuuuuu1111DDDDDDDDDo.`,`ouuuuuuuuuuuuDDDDDDDDDDDDo`,`uuuuuuuuuuuuuDDDDDDDDDDDDD`,`uuuuuuuuuuuuuDDDDDDDDDDDDD`,`oocCcCcCcCcCcCcCcCCRCRCCoo`,`.ocCcCcCcCcCcCcCcCCRCRCCo.`,`.ocCcCcCcwwwwwwwwCCRCRCCo.`,`.ocCgwgCcwwccwcwwCCgwgCCo.`,`.ocCwwwCcwwccwcwwCCwwwCCo.`,`.ocCgwgCcwcwcwwcwCCgwgCCo.`,`.ocCcCcCcwcwcwwcwCCRCRCCo.`,`.ocCcCcCcwccwwccwCCRCRCCo.`,`.ocCcCcCcwccwwccwCCRCRCCo.`,`oocCcCcCcwccwwccwCCRCRCCoo`,`11011111111111111111112111`],oak:[`.....oooo..........`,`....ojjjjoooooo....`,`...ojjjJJjjjjJJo...`,`..ojjjJJGjjjJJJo...`,`..ojJJJGjjJJJGGGo..`,`..oJGGGGJJJGGGGHo..`,`..ojGGHHjGGGHHHQo..`,`.ojJHHHQQGHHHHQGGo.`,`oJJJGGQjjJJJQQQGGGo`,`oJJGGGJJJJJGGGGGGHo`,`oGGGGJJGGGGGHGGHHQo`,`oQGHHHGGGGHHHHHHQQo`,`oQQHQQGGHHHQQQQQQQo`,`.oQQQQQHHQQQQQQQQo.`,`..ooooQQQQQQQoooo..`,`......oQQQQQo......`,`.......otuuo.......`,`.......ottuo.......`,`.......ottuo.......`,`.......otuuo.......`,`......ootuuoo......`,`.....outttuuuo.....`,`.....ooooooooo.....`],elm:[`........ojjjjo.....`,`....oooojjjjJJo....`,`...jjjjJjjJjGGo....`,`..ojjjJGJJGGGHjoo..`,`..ojjJJGJGGGHHJJJo.`,`..oJGGGGHGGjQJJGGo.`,`..oGGHHHQHJJJJGGGGo`,`..oJHHHQQJJJGGGGHHo`,`.ooJJJGGGJJGGHHHHQo`,`ojJJJGGjjJJGGHHJQQo`,`oJJGGGJJJGGGHJJJGo.`,`oGGGHHJGGGHHHGGGHHo`,`oGHHHQGGGHHHQGHHHQo`,`oQQQQQGHHQQQQQHQQQo`,`oQQQQQQQHQQQQQQQQQo`,`..ooooQQQQQQQQQQQo.`,`......ooQQQoo.ooo..`,`.......ottuo.......`,`.......ottuo.......`,`.......otuuo.......`,`......ootuuoo......`,`.....outttuuuo.....`,`.....ooooooooo.....`],pine:[`......oo......`,`.....oh8o.....`,`.....oh8o.....`,`.....hO8o.....`,`.....hO8o.....`,`....ohh88o....`,`....ohOO8o....`,`....ohOO8o....`,`...ohhh888o...`,`...ohhO888o...`,`..o88hOO888o..`,`...8hhOO88o...`,`..ohhOh8888...`,`..ohhhOO888o..`,`.o88hhOO8888o.`,`.oohhOOO888oo.`,`.ohhhOOO8888..`,`.ohhhOOO8888o.`,`o888888888888o`,`.ooooottooooo.`,`.....otto.....`,`.....ouuuo....`,`.....oooo.....`],bush:[`..oooooo..`,`.oJGGGGHo.`,`oJGpGGGqHo`,`oGGGGqGHHo`,`.ooooooooo`],sunflower:[`..oyyo..`,`.oyYYyo.`,`oyYddYyo`,`oyYddYyo`,`.oyYYyo.`,`..oyyo..`,`...oG.o.`,`.o.oGoGo`,`.oGoGo..`,`...oG...`],tulip:[`.o.o.o..`,`opopopo.`,`oPpPpPo.`,`oPPpPPo.`,`.oPPPo..`,`..ooo...`,`...oG.o.`,`.o.oGoGo`,`.oGoGo..`,`...oG...`]},sn={claude_code:{palette:{A:`#3a302c`,B:`#5f3b2c`,C:`#503428`,D:`#48332a`,E:`#c8c8d0`,F:`#d3b196`,G:`#f8d0b0`,H:`#3a3640`,I:`#36363e`,J:`#373337`,K:`#9a5a48`,L:`#d97757`,M:`#bebebb`,N:`#fff4ec`,O:`#f8f8f8`,P:`#9fd3ea`,Q:`#44362e`,R:`#e8c040`,S:`#3a4058`,T:`#35394b`,U:`#f0f0f0`,V:`#b0b0bc`},down:[`.......AAAA........`,`....AAABBBBAAA.....`,`...ABBBBBBBBCDA....`,`..ABBBBBBCCBCCCA...`,`.ABBBBBCCCCCDCCCA..`,`.ABBBCDCCCCCCCCDA..`,`ABBBCCCCCCCCCCCDDA.`,`ABCCCBBCCCCDCDDDDA.`,`ACBDDDDDDDDDDDDDDA.`,`ACEEFFDGGGGGDFFEEA.`,`.AEEFGHHGGGHHGFEE..`,`.AEEHHIIHHHIIHHEE..`,`.ACJFHGGHGHGGHFDA..`,`.ADDJEGGGFGGGFDDA..`,`..ADDDFGKKKGFDDA...`,`.....JLJLLLJLJJJJJJ`,`...JJLLMNONMLMJOPPJ`,`..JLLMLNLOLNLMJPPPJ`,`.JGGJMLLNONLLMJJJJJ`,`.JFGJLLLLOLLLLEEEEE`,`..JJQQQQQRQQQQJJJJJ`,`....JSSTJ.JTSSJ....`,`....JUUVJ.JVUUJ....`,`.....JJJ...JJJ.....`],walk:[[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEEDDDDDDA.`,`.JHHHGGFFEEDDDDDDA.`,`JGGIHHHHFEEDDDDDDA.`,`JGIGHGGFJDDDDDDDDA.`,`.JKKGGEJFDDDDDDDA..`,`..JJGGFFADDDDDDA...`,`..JJJJJLLJLLJ......`,`..JPPOJLMLLLJ......`,`..JPPPJMLLLLJ......`,`..JJJJJMLLLLJ......`,`..EEEEELLLLLJ......`,`..JJJJJQQQQQJ......`,`.......JSSTJ.......`,`......JUUUVJ.......`,`.......JJJJ........`],[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEEDDDDDDA.`,`.JHHHGGFFEEDDDDDDA.`,`JGGIHHHHFEEDDDDDDA.`,`JGIGHGGFJDDDDDDDDA.`,`.JKKGGEJFDDDDDDDA..`,`..JJGGFFADDDDDDA...`,`..JJJJJLLJLLJ......`,`..JPPOJLMLLLJ......`,`..JPPPJMLLLLJ......`,`..JJJJJMLLLLJ......`,`..EEEEELLLLLJ......`,`..JJJJJQQQQQJ......`,`.....JSTJ.JSTJ.....`,`....JUUVJ.JUUVJ....`,`.....JJJ...JJJ.....`],[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEEDDDDDDA.`,`.JHHHGGFFEEDDDDDDA.`,`JGGIHHHHFEEDDDDDDA.`,`JGIGHGGFJDDDDDDDDA.`,`.JKKGGEJFDDDDDDDA..`,`..JJGGFFADDDDDDA...`,`..JJJJJLLJLLJ......`,`..JPPOJLMLLLJ......`,`..JPPPJMLLLLJ......`,`..JJJJJMLLLLJ......`,`..EEEEELLLLLJ......`,`..JJJJJQQQQQJ......`,`......JSSTJ........`,`......JUUUVJ.......`,`.......JJJJ........`]]},codex:{palette:{A:`#313132`,B:`#38353a`,C:`#353336`,D:`#363438`,E:`#b88869`,F:`#d8a07c`,G:`#373337`,H:`#3a3640`,I:`#36363e`,J:`#f0f0f8`,K:`#a0505a`,L:`#10a37f`,M:`#bebebb`,N:`#eafff7`,O:`#f8f8f8`,P:`#f4f4f0`,Q:`#44362e`,R:`#e8c040`,S:`#35373f`,T:`#34353b`,U:`#484848`,V:`#f0f0f0`,W:`#977057`},down:[`....AA.AAAAA.A.....`,`...ABBABBBCBADA....`,`..AABBBBBBDDDDDA...`,`.ABBBBBBDDDBDDDA...`,`.ABBCBDDCDDDCDDDA..`,`.ABBDDDDDDDDDDDCA..`,`.ADDDBDDDBDDDCCCA..`,`.ACCCCCCCCCCCCCCA..`,`..AAECFCFCFCFCEA...`,`...GEHHHHFHHHHEG...`,`...GHHIJHHHJIHHG...`,`...GEHIIHFHIIHEG...`,`....GHHHHEHHHHG....`,`.....GEFFKFFEG.....`,`.....GLGLLLGLG.....`,`...GGLLMNONMLMGGGGG`,`..GLLMLNLOLNLMGLLPG`,`.GFFGMLNNONNLMGLLPG`,`.GEFGLLLLOLLLLGLLPG`,`..GGQQQQQRQQQQGGGGG`,`....GSSTG.GTSSG....`,`....GUUVG.GVUUG....`,`.....GGG...GGG.....`],walk:[[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`......GLLGLLG......`,`..GGGGGLMLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGLLLLLG......`,`..GGGGGQQQQQG......`,`.......GSSTG.......`,`......GUUUVG.......`,`.......GGGG........`],[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`......GLLGLLG......`,`..GGGGGLMLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGLLLLLG......`,`..GGGGGQQQQQG......`,`.....GSTG.GSTG.....`,`....GUUVG.GUUVG....`,`.....GGG...GGG.....`],[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`......GLLGLLG......`,`..GGGGGLMLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGLLLLLG......`,`..GGGGGQQQQQG......`,`......GSSTG........`,`......GUUUVG.......`,`.......GGGG........`]]},hermes:{palette:{A:`#443329`,B:`#8f5c3d`,C:`#704830`,D:`#533524`,E:`#f8f8f8`,F:`#d5beaa`,G:`#fbe0c8`,H:`#36363e`,I:`#373337`,J:`#a0605a`,K:`#f4f1e8`,L:`#bebebb`,M:`#c9a227`,N:`#f4f4f0`,O:`#44362e`,P:`#e8c040`,Q:`#f0ece2`,R:`#b4b1aa`,S:`#f0f0f0`,T:`#b0b0bc`,U:`#b09d8c`},down:[`.......AAAA........`,`....AAABBBBAAA.....`,`...ABBBBBBBCCDA....`,`..ABBBBBBCCBCCCA...`,`EABBBBBCCCCBCCCCA.E`,`EEEBBBDCDCCCCCCDEEE`,`AEEECCCCCCCCCCDEEE.`,`ABCCCCCCCCCCCDDDDA.`,`ACBDDDDDDDDDDDDDDA.`,`ACCDCCCCCCCDDFDDDA.`,`.ACCDDDDGGGGGGFDA..`,`..ACFGHHGGGHHGFDA..`,`..ACFHGGHGHGGHFA...`,`...AIFGGGFGGGFI....`,`.....IFGGJGGFI.....`,`.....IKIKKKIKI.....`,`...IIKKLMMMLKLII...`,`..IKKLKMMKMMKLIIIII`,`.IGGILKMMMMMKLININI`,`.IFGIKKLKKKKLLINNNI`,`..IIOOOOOPOOOOIIIII`,`....IQQRI.IRQQI....`,`....ISSTI.ITSSI....`,`.....III...III.....`],walk:[[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA.E`,`.ABBBBCCCCDCDCCCEEE`,`.ABBCCCCCCCDCCDEEE.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`.....IKKLKKKI......`,`..IIIIILKKKKI......`,`..ININILKKKKI......`,`..INNNIKKKKLI......`,`..IIIIIOOOOOI......`,`.......IQQRI.......`,`......ISSSTI.......`,`.......IIII........`],[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA.E`,`.ABBBBCCCCDCDCCCEEE`,`.ABBCCCCCCCDCCDEEE.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`.....IKKLKKKI......`,`..IIIIILKKKKI......`,`..ININILKKKKI......`,`..INNNIKKKKLI......`,`..IIIIIOOOOOI......`,`.....IQRI.IQRI.....`,`....ISSTI.ISSTI....`,`.....III...III.....`],[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA.E`,`.ABBBBCCCCDCDCCCEEE`,`.ABBCCCCCCCDCCDEEE.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`.....IKKLKKKI......`,`..IIIIILKKKKI......`,`..ININILKKKKI......`,`..INNNIKKKKLI......`,`..IIIIIOOOOOI......`,`......IQQRI........`,`......ISSSTI.......`,`.......IIII........`]]},cursor:{palette:{A:`#5b3918`,B:`#ffae48`,C:`#d88838`,D:`#a06529`,E:`#ccaa88`,F:`#f0c8a0`,G:`#3a3640`,H:`#f0f0f8`,I:`#313745`,J:`#373337`,K:`#9a5a48`,L:`#353539`,M:`#ffffff`,N:`#bebebb`,O:`#f8f8f8`,P:`#44362e`,Q:`#e8c040`,R:`#383840`,S:`#36363c`,T:`#484848`,U:`#f0f0f0`,V:`#a88c70`},down:[`......AAAAAA.......`,`....AABBBBBBAA.....`,`...ABBBBBBCCCDA....`,`..ABBBBBBCCBCCCA...`,`.ABBBBBCCCCCDCCCA..`,`ABBBBCCCCCCCCCCDCA.`,`ABBDDCCCCCCCCCCDDA.`,`ACCCCBCCCCCDCDDDDA.`,`ACCDDDDDDDDDDDDDDA.`,`ACCCEDFDFDFDFDEDDA.`,`.ACCEGGGGFGGGGEDA..`,`..ACGGHIGGGHIGGDA..`,`..ACEEIIEFEIIEEA...`,`...AJEFFFEFFFEJ....`,`.....JEFFKFFEJJJ...`,`.....JLJLLLJLJJMJ..`,`...JJLLNLOLNLNJMMJ.`,`..JLLNLMMOLLLNJMMMJ`,`.JFFJNLMMOLLLNJMMJJ`,`.JEFJLLMMOLLLLJJMJ.`,`..JJPPPPPQPPPPPJJJ.`,`....JRRSJ.JSRRJ....`,`....JTTUJ.JUTTJ....`,`.....JJJ...JJJ.....`],walk:[[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFIIGFFEFEVDDDDA...`,`.JFKFFFEEEDDAAA....`,`..JJFFEEJJAA.......`,`.J....JLLJLLJ......`,`.JJ..JLLNLLLJ......`,`.JMJJJLNLLLLJ......`,`.JMMJFLNLLLLJ......`,`.JMMMJLLLLLLJ......`,`.JMMJJJPPPPPJ......`,`.JJMJ..JRRSJ.......`,`...JJ.JTTTUJ.......`,`.......JJJJ........`],[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFIIGFFEFEVDDDDA...`,`.JFKFFFEEEDDAAA....`,`..JJFFEEJJAA.......`,`.J....JLLJLLJ......`,`.JJ..JLLNLLLJ......`,`.JMJJJLNLLLLJ......`,`.JMMJFLNLLLLJ......`,`.JMMMJLLLLLLJ......`,`.JMMJJJPPPPPJ......`,`.JJMJJRSJ.JRSJ.....`,`...JJTTUJ.JTTUJ....`,`.....JJJ...JJJ.....`],[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFIIGFFEFEVDDDDA...`,`.JFKFFFEEEDDAAA....`,`..JJFFEEJJAA.......`,`.J....JLLJLLJ......`,`.JJ..JLLNLLLJ......`,`.JMJJJLNLLLLJ......`,`.JMMJFLNLLLLJ......`,`.JMMMJLLLLLLJ......`,`.JMMJJJPPPPPJ......`,`.JJMJ.JRRSJ........`,`...JJ.JTTTUJ.......`,`.......JJJJ........`]]},gemini_cli:{palette:{A:`#343132`,B:`#b9c8ff`,C:`#40363b`,D:`#3d3539`,E:`#393336`,F:`#a77553`,G:`#c48a62`,H:`#373337`,I:`#f2c14e`,J:`#36363e`,K:`#f8f8f8`,L:`#7a4232`,M:`#6c8cf5`,N:`#bebebb`,O:`#ffffff`,P:`#44362e`,Q:`#e8c040`,R:`#4a6eb0`,S:`#385384`,T:`#c03850`},down:[`.AAA...BBBBB...AAA.`,`ACCCABBAAAAABBADDDA`,`CCCCCACBBBBBAADCDDE`,`CCCCCCCCCCDDDEDDDED`,`ACCCCCCCDDDCDDDDDDA`,`.ACCCCCDDDDDEDDDEA.`,`ACCCCCDDDDDDDDDDEA.`,`ACCDDDEDDDDDDEEEEA.`,`ADDEEEEEEEEEEEEEEA.`,`ADDDFFEGGEGGEFFEHA.`,`.AEDFGGGGGGGGGFHIH.`,`.ADDFGJJGGGJJGHIKIH`,`..ADFJGGJGJGGJFHIH.`,`...AHFGGGFGGGFH.H..`,`.....HFGLLLGFH..H..`,`.....HMHMMMHMH..H..`,`...HHMMNMMMNMNHHH..`,`..HMMNMMOOOMMNMNH..`,`.HGGHNMMMNMMNNHGFH.`,`.HFGHMMMMMMMMMHGFH.`,`..HHPPPPPQPPPPPHH..`,`....HRRSH.HSRRH....`,`....HTTKH.HKTTH....`,`.....HHH...HHH.....`],walk:[[`........BBBB.AAA...`,`......BBAAAABBCDA..`,`....AACCBBBBCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.HGGGGGFFEEEEEEEEA.`,`HGGJGGGFFEEEEEEEA..`,`HGJGJGGFGEEEEEEA...`,`.HLLGGGFFEEEEEA....`,`HIHHGGFFAEEAAA.....`,`IKI...HMMHMMH......`,`HIH..HMMNMMMH......`,`..HHHHMNMMMMH......`,`...HGGMNMMMNH......`,`....HHMMMMMMH......`,`......HPPPPPH......`,`.......HRRSH.......`,`......HTTTKH.......`,`.......HHHH........`],[`........BBBB.AAA...`,`......BBAAAABBCDA..`,`....AACCBBBBCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.HGGGGGFFEEEEEEEEA.`,`HGGJGGGFFEEEEEEEA..`,`HGJGJGGFGEEEEEEA...`,`.HLLGGGFFEEEEEA....`,`HIHHGGFFAEEAAA.....`,`IKI...HMMHMMH......`,`HIH..HMMNMMMH......`,`..HHHHMNMMMMH......`,`...HGGMNMMMNH......`,`....HHMMMMMMH......`,`......HPPPPPH......`,`.....HRSH.HRSH.....`,`....HTTKH.HTTKH....`,`.....HHH...HHH.....`],[`........BBBB.AAA...`,`......BBAAAABBCDA..`,`....AACCBBBBCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.HGGGGGFFEEEEEEEEA.`,`HGGJGGGFFEEEEEEEA..`,`HGJGJGGFGEEEEEEA...`,`.HLLGGGFFEEEEEA....`,`HIHHGGFFAEEAAA.....`,`IKI...HMMHMMH......`,`HIH..HMMNMMMH......`,`..HHHHMNMMMMH......`,`...HGGMNMMMNH......`,`....HHMMMMMMH......`,`......HPPPPPH......`,`......HRRSH........`,`......HTTTKH.......`,`.......HHHH........`]]}},cn={claude_code:`#d97757`,codex:`#10a37f`,hermes:`#c9a227`,cursor:`#1b1b1f`,gemini_cli:`#6c8cf5`},ln={palette:{A:`#3a302c`,B:`#5f3b2c`,C:`#503428`,D:`#48332a`,E:`#9c6846`,F:`#b87a52`,G:`#36363e`,H:`#373337`,I:`#6e3e30`,J:`#30395a`,K:`#f8f8f8`,L:`#d8432e`,M:`#2f3653`,N:`#9aa0a6`,O:`#32374b`,P:`#313545`,Q:`#343438`,R:`#4a4a56`,S:`#815539`},down:[`........AA.........`,`.....AAABBAAA......`,`...AABBBBBBBCAA....`,`..ABBBBBBCCBCCCA...`,`.ABBBBBCCCCCDCCCA..`,`.ABBBCCCCCCCCCCCA..`,`ABBDDDCCCCCCCDDDDA.`,`ACCDDDDDDDDDDDDDDA.`,`.ACCEDFDCCCCCCCDA..`,`.ADCEFFFFFFDDDDDA..`,`..ACEFEEFFFEEFEDA..`,`..ACEFGGFFFGGFEA...`,`...AHEFDDDDDFEH....`,`.....HEFFIFFEH.....`,`.....HJHKLKHJH...H.`,`...HHJJMJLJMJMHH.KH`,`..HJJMMJJLJJNMJMHKK`,`.HFFHMMJJLJJMMHFEHK`,`.HEFHJMMJLJJMMHFEHH`,`..HHOOOOOOOOOOOHHH.`,`....HOOPH.HPOOH....`,`....HQQRH.HRQQH....`,`.....HHH...HHH.....`],walk:[[`........AAA........`,`.....AAABBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBCDCCDCA...`,`..ABBBBBCCDCCCCCA..`,`.ABBBBCDCCCCCCCDCA.`,`.ABBDDDCCCCCCCCDDA.`,`.ADDDDDDDCCCCDDDDA.`,`..ADFFDEECCDDDDDDA.`,`.HFFFFFEEDDDDDDDDA.`,`HFEEFFFEEEFDDDDDA..`,`HFDDDFFEFESDDDDA...`,`.HFIFFFEEEDDAAA....`,`..HHFFEEHHAA.......`,`...H..HJJHKKH......`,`...KHHJJMJJJH......`,`...KKFJMJJJJH......`,`...KKFFEHJJMH......`,`...KHHEHJJJMH......`,`...H..HOOOOOH......`,`.......HOOPH.......`,`......HQQQRH.......`,`.......HHHH........`],[`........AAA........`,`.....AAABBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBCDCCDCA...`,`..ABBBBBCCDCCCCCA..`,`.ABBBBCDCCCCCCCDCA.`,`.ABBDDDCCCCCCCCDDA.`,`.ADDDDDDDCCCCDDDDA.`,`..ADFFDEECCDDDDDDA.`,`.HFFFFFEEDDDDDDDDA.`,`HFEEFFFEEEFDDDDDA..`,`HFDDDFFEFESDDDDA...`,`.HFIFFFEEEDDAAA....`,`..HHFFEEHHAA.......`,`...H..HJJHKKH......`,`...KHHJJMJJJH......`,`...KKFJMJJJJH......`,`...KKFFEHJJMH......`,`...KHHEHJJJMH......`,`...H..HOOOOOH......`,`.....HOPH.HOPH.....`,`....HQQRH.HQQRH....`,`.....HHH...HHH.....`],[`........AAA........`,`.....AAABBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBCDCCDCA...`,`..ABBBBBCCDCCCCCA..`,`.ABBBBCDCCCCCCCDCA.`,`.ABBDDDCCCCCCCCDDA.`,`.ADDDDDDDCCCCDDDDA.`,`..ADFFDEECCDDDDDDA.`,`.HFFFFFEEDDDDDDDDA.`,`HFEEFFFEEEFDDDDDA..`,`HFDDDFFEFESDDDDA...`,`.HFIFFFEEEDDAAA....`,`..HHFFEEHHAA.......`,`...H..HJJHKKH......`,`...KHHJJMJJJH......`,`...KKFJMJJJJH......`,`...KKFFEHJJMH......`,`...KHHEHJJJMH......`,`...H..HOOOOOH......`,`......HOOPH........`,`......HQQQRH.......`,`.......HHHH........`]]},un=[{down:[`....oo.ooooo.o....`,`...ohhohhhdhoHo...`,`..oohhhhhhHHHHHo..`,`.ohhhhhhHHHhHHHo..`,`.ohhdhHHdHHHdHHHo.`,`.ohhHHHHHHHHHHHdo.`,`.oHHHhHHHhHHHdddo.`,`.oddddddddddddddo.`,`..ooSdsdsdsdsdSo..`,`...kSsssssssssSk..`,`...kSseEsssEesSk..`,`...kSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....o.ooooo.o....`,`....ohohhhdhoHo...`,`...ohhhhhhHHHHHo..`,`..ohhhhhHHHhHHHoo.`,`.ohhdhHHdHHHdHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHhHHHhHHHddddo`,`.odddddddHdddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....o.ooooo.o....`,`....ohohhhdhoHo...`,`...ohhhhhhHHHHHo..`,`..ohhhhhHHHhHHHoo.`,`.ohhdhHHdHHHdHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHhHHHhHHHddddo`,`.odddddddHdddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....o.ooooo.o....`,`....ohohhhdhoHo...`,`...ohhhhhhHHHHHo..`,`..ohhhhhHHHhHHHoo.`,`.ohhdhHHdHHHdHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHhHHHhHHHddddo`,`.odddddddHdddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`...oooohhhhhho.....`,`..ohhhhhhhhhHooo...`,`.oohhhhhhhHHHdHHo..`,`ohhhhhhhHHHhHHHHo..`,`ohhhhhHHHHHHdHHHdo.`,`ohhhhHHHHHHHHHHdddo`,`hhhdddHHHHHHHHHdddo`,`hHHHhHHHHHHHHddddo.`,`HhHdddddddddddddddo`,`oHHHSdssdsdssdSdddo`,`odHHSsssssssssSddo.`,`.ooHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHdHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`oddddddddHHdddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsdddddo..`,`kseesssSsSDddddo...`,`.ksmsssSSSddooo....`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHdHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`oddddddddHHdddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsdddddo..`,`kseesssSsSDddddo...`,`.ksmsssSSSddooo....`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHdHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`oddddddddHHdddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsdddddo..`,`kseesssSsSDddddo...`,`.ksmsssSSSddooo....`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`.....oooooooo.....`,`....ohhhhhhhHo....`,`...ohhhhhhHHHdo...`,`..ohhhhhHHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`ohhhhHHHHHHHHHHddo`,`ohhdddHHHHHHHdHddo`,`oHHXXHHHHHHHHddddo`,`oHHXdddddddddddddo`,`oHHHSdssdsdssdSddo`,`oHHHSsssssssssSddo`,`oHHHSseEsssEesSddo`,`oHHHSseessseesSddo`,`.odddSsssSsssSddo.`,`..odddSssmssSddo..`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`......ooooooo.....`,`....oohhhhhhHoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhhHdHHdHHHHdHo`,`.ohdddHHHHHHHHHddo`,`.oHHHhHHHHHHHXXddo`,`.odddddddHHddXdddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`......ooooooo.....`,`....oohhhhhhHoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhhHdHHdHHHHdHo`,`.ohdddHHHHHHHHHddo`,`.oHHHhHHHHHHHXXddo`,`.odddddddHHddXdddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`......ooooooo.....`,`....oohhhhhhHoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhhHdHHdHHHHdHo`,`.ohdddHHHHHHHHHddo`,`.oHHHhHHHHHHHXXddo`,`.odddddddHHddXdddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......oooo.......`,`....ooohhhhooo....`,`...ohhhhhhhHHdo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHhHHHHo.`,`.ohhhhdHdHHHHHHdo.`,`ohhhHHHHHHHHHHdddo`,`ohHHHHHHHHHHHddddo`,`oHhddddddddddddddo`,`oHHdHHHHHHHddSdddo`,`.oHHddddssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......oooo.......`,`.....oohhhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHHHHHdHHdHdo`,`.oHHHHHHHHHHdHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......oooo.......`,`.....oohhhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHHHHHdHHdHdo`,`.oHHHHHHHHHHdHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......oooo.......`,`.....oohhhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHHHHHdHHdHdo`,`.oHHHHHHHHHHdHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`......ohhhho......`,`.....oohhhhoo.....`,`....ohhhhhhhHo....`,`...ohhhhhhHHHdo...`,`..ohhhhhXXXhHHHo..`,`.ohhhhHHdHHHdHHHo.`,`ohhhHHHdHHHdHHHHdo`,`ohHHHHHHHHHHHHdddo`,`oHHddddddddddddddo`,`oHHdSdssdsdssdSddo`,`.odHSsssssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........ohhhho....`,`......ooohhhho....`,`....oohhhhhhHoo...`,`...ohhhhhhdHHHHo..`,`..ohhhhhhhXXXdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSodoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........ohhhho....`,`......ooohhhho....`,`....oohhhhhhHoo...`,`...ohhhhhhdHHHHo..`,`..ohhhhhhhXXXdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSodoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........ohhhho....`,`......ooohhhho....`,`....oohhhhhhHoo...`,`...ohhhhhhdHHHHo..`,`..ohhhhhhhXXXdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSodoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`........oo........`,`.....ooohhooo.....`,`...oohhhhhhhHoo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`.ohhhHHHHHHHHHHHo.`,`ohhdddHHHHHHHddddo`,`oHHddddddddddddddo`,`.oHHSdsdHHHHHHHdo.`,`.odHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........ooo.......`,`.....ooohhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhHdHHdHo..`,`..ohhhhhHHdHHHHHo.`,`.ohhhhHdHHHHHHHdHo`,`.ohhdddHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........ooo.......`,`.....ooohhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhHdHHdHo..`,`..ohhhhhHHdHHHHHo.`,`.ohhhhHdHHHHHHHdHo`,`.ohhdddHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........ooo.......`,`.....ooohhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhHdHHdHo..`,`..ohhhhhHHdHHHHHo.`,`.ohhhhHdHHHHHHHdHo`,`.ohhdddHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......oooo.......`,`....ooohhhhooo....`,`...ohhhhhhhhHdo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`.ohhhHdHHHHHHHHdo.`,`ohhhHHHHHHHHHHHddo`,`ohHHHhhHHHHdHddddo`,`oHhddddddddddddddo`,`oHHdSSdsssssdSSddo`,`.oHHSsssssssssSdo.`,`.oHHSseEsssEesSdo.`,`.oHHSseessseesSdo.`,`.odddSsssSsssSddo.`,`..odddSssmssSddo..`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......ooooo......`,`.....oohhhhhoo....`,`...oohhhhhhHHHo...`,`..ohhhhhhHdHHdHo..`,`..ohhhhhdHHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......ooooo......`,`.....oohhhhhoo....`,`...oohhhhhhHHHo...`,`..ohhhhhhHdHHdHo..`,`..ohhhhhdHHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......ooooo......`,`.....oohhhhhoo....`,`...oohhhhhhHHHo...`,`..ohhhhhhHdHHdHo..`,`..ohhhhhdHHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......kkkk.......`,`.....kknnnnkk.....`,`....knnnnssssk....`,`...knnnnssssssk...`,`..knnnsssssssssk..`,`.knnssssssssssSSk.`,`.ohHHsssssssSSddo.`,`.oHHHssssssSSSddo.`,`.oHddssssSSSSSddo.`,`..oHSSsssssssSSo..`,`..oHSseEsssEesSk..`,`...oSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......kkkkk......`,`.....kknnnnnkk....`,`....knnnnnssssk...`,`...knnnnsssssssk..`,`..knnnssssssssssk.`,`..knnsssssssssSSk.`,`..ksssssssssHHddo.`,`..kssssssssSddddo.`,`..kssssssSSSddddo.`,`.kodssdSSdddddddo.`,`kseEsssSSddddddo..`,`kseesssSsdddddo...`,`.ksmsssSSddddo....`,`..kkssSSkoooo.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......kkkkk......`,`.....kknnnnnkk....`,`....knnnnnssssk...`,`...knnnnsssssssk..`,`..knnnssssssssssk.`,`..knnsssssssssSSk.`,`..ksssssssssHHddo.`,`..kssssssssSddddo.`,`..kssssssSSSddddo.`,`.kodssdSSdddddddo.`,`kseEsssSSddddddo..`,`kseesssSsdddddo...`,`.ksmsssSSddddo....`,`..kkssSSkoooo.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......kkkkk......`,`.....kknnnnnkk....`,`....knnnnnssssk...`,`...knnnnsssssssk..`,`..knnnssssssssssk.`,`..knnsssssssssSSk.`,`..ksssssssssHHddo.`,`..kssssssssSddddo.`,`..kssssssSSSddddo.`,`.kodssdSSdddddddo.`,`kseEsssSSddddddo..`,`kseesssSsdddddo...`,`.ksmsssSSddddo....`,`..kkssSSkoooo.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`....oooooooooo....`,`...ohhhhhhhhHdo...`,`..ohhhhhhhHhHHHo..`,`.ohhhhhhHHHHdHHHo.`,`.ohhhhdHdHHHHHHdo.`,`.ohhHHHHHHHHHHHdo.`,`.oHHHHhHHHHdHdddo.`,`.ohdddddddddddddo.`,`..ooSdsdsdsdsdSo..`,`...kSsssssssssSk..`,`...kSseEsssEesSk..`,`...kSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....ooooooooo....`,`...oohhhhhhhHdoo..`,`..ohhhhhhhdHHdHHo.`,`..ohhhhhdhdHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhhHHHHHHdHHdddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....ooooooooo....`,`...oohhhhhhhHdoo..`,`..ohhhhhhhdHHdHHo.`,`..ohhhhhdhdHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhhHHHHHHdHHdddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....ooooooooo....`,`...oohhhhhhhHdoo..`,`..ohhhhhhhdHHdHHo.`,`..ohhhhhdhdHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhhHHHHHHdHHdddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`........oo.........`,`.....ooohhooo......`,`...oohhhhhhhHoo....`,`..ohhhhhhHHhHHHo...`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhdHdHHHHHHdo..`,`ohhhHHHHHHHHHHdddo.`,`ohHXXHHHHHHHHddddo.`,`oHhXdddddddddddddo.`,`.oHdSSdssdssdSSdo..`,`.oHHSsssssssssSdo..`,`..oHSseEsssEesSo...`,`...oSseessseesSk...`,`....kSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`........ooo........`,`.....ooohhhooo.....`,`....ohhhhhhhHHo....`,`...ohhhhhhdHHdHo...`,`..ohhhhhdhHHHHHHoo.`,`.ohhhhHHHHdHdHHHHdo`,`.ohhHHHHHHHdHHddddo`,`.oHHHHHHHHHHdXXdddo`,`.odddddddHHHdXddddo`,`..odssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsdddddddo..`,`.ksmsssSSddddooo...`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`........ooo........`,`.....ooohhhooo.....`,`....ohhhhhhhHHo....`,`...ohhhhhhdHHdHo...`,`..ohhhhhdhHHHHHHoo.`,`.ohhhhHHHHdHdHHHHdo`,`.ohhHHHHHHHdHHddddo`,`.oHHHHHHHHHHdXXdddo`,`.odddddddHHHdXddddo`,`..odssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsdddddddo..`,`.ksmsssSSddddooo...`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`........ooo........`,`.....ooohhhooo.....`,`....ohhhhhhhHHo....`,`...ohhhhhhdHHdHo...`,`..ohhhhhdhHHHHHHoo.`,`.ohhhhHHHHdHdHHHHdo`,`.ohhHHHHHHHdHHddddo`,`.oHHHHHHHHHHdXXdddo`,`.odddddddHHHdXddddo`,`..odssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsdddddddo..`,`.ksmsssSSddddooo...`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`......oooooo......`,`...ooohhhhhhooo...`,`..ohhhhhhhhHHdHo..`,`.ohhhhhhhHHhHHHHo.`,`.ohhhhhHHHHHHHHHo.`,`ohhhhHdHHHHHHHHdHo`,`ohhhHHHHHHHHHHdddo`,`ohHHHhhHHHHdHddddo`,`oHhddddddddddddddo`,`oHHHSdsdsdsdsdSddo`,`oHHHSsssssssssSddo`,`oHHHSseEsssEesSddo`,`oHHHSseessseesSddo`,`.ooodSsssSsssSkoo.`,`....okSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhHdHHdHHo.`,`.ohhhhhhdHHHHHHHHo`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsdddddddo.`,`.ksmsssSSdddddoo..`,`..kkssSSkooooo....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhHdHHdHHo.`,`.ohhhhhhdHHHHHHHHo`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsdddddddo.`,`.ksmsssSSdddddoo..`,`..kkssSSkooooo....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhHdHHdHHo.`,`.ohhhhhhdHHHHHHHHo`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsdddddddo.`,`.ksmsssSSdddddoo..`,`..kkssSSkooooo....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`....ohohhhhhooo....`,`..oohhhhhhhHHhHo...`,`.odhhhdhhHdHHHdoo..`,`ohhhhhhHHHHHHHHHHo.`,`ohhhhHHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`hhHHHHHHHHHHHHddddo`,`HhHHHhHHHhHHHdddddo`,`HHddddddddddddddddo`,`oHHHSdssdsdssdSddo.`,`oHHhSsssssssssSddo.`,`.oHHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`....ooohhhhhooo....`,`...ohhhhhhhHHhHo...`,`..oohhdhhHdHHHdoo..`,`.ohhhhhhHHHHHHHHHo.`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHddo`,`ohHHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSdddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`....ooohhhhhooo....`,`...ohhhhhhhHHhHo...`,`..oohhdhhHdHHHdoo..`,`.ohhhhhhHHHHHHHHHo.`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHddo`,`ohHHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSdddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`....ooohhhhhooo....`,`...ohhhhhhhHHhHo...`,`..oohhdhhHdHHHdoo..`,`.ohhhhhhHHHHHHHHHo.`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHddo`,`ohHHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSdddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`.ooo...........ooo.`,`ohhho.oooooo..oHHHo`,`hhhhhohhhhhhooHhHHd`,`hhhhhhhhhhHHHdHHHdH`,`ohhhhhhhHHHhHHHHHHo`,`.ohhhhhHHHHHdHHHdo.`,`ohhhhhHHHHHHHHHHdo.`,`ohhHHHdHHHHHHddddo.`,`oHHddddddddddddddo.`,`oHHHSSdssdssdSSddo.`,`.odHSsssssssssSdo..`,`.oHHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.............ooo...`,`......ooooooohhHo..`,`....oohhhhhhhHHHHo.`,`...ohhhhhhhHHHHHHo.`,`..ohhhhhhhHHHdHHHo.`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhHHhHHHHHHddo.`,`.ohdHHHHHHHHHdHddo.`,`.odddddddHHHHddddo.`,`..odssdSSHHddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSdddddo....`,`..kkssSSoddooo.....`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.............ooo...`,`......ooooooohhHo..`,`....oohhhhhhhHHHHo.`,`...ohhhhhhhHHHHHHo.`,`..ohhhhhhhHHHdHHHo.`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhHHhHHHHHHddo.`,`.ohdHHHHHHHHHdHddo.`,`.odddddddHHHHddddo.`,`..odssdSSHHddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSdddddo....`,`..kkssSSoddooo.....`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.............ooo...`,`......ooooooohhHo..`,`....oohhhhhhhHHHHo.`,`...ohhhhhhhHHHHHHo.`,`..ohhhhhhhHHHdHHHo.`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhHHhHHHHHHddo.`,`.ohdHHHHHHHHHdHddo.`,`.odddddddHHHHddddo.`,`..odssdSSHHddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSdddddo....`,`..kkssSSoddooo.....`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`......oooooo......`,`....oohhhhhhoo....`,`...ohhhhhhHHHdo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`ohhhhHHHHHHHHHHdHo`,`ohhddHHHHHHHHHHddo`,`oHHHHhHHHHHdHddddo`,`oHHddddddddddddddo`,`oHHHSdsdsdsdsdSddo`,`.oHHSsssssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhHHHHHdHdHHHHo`,`.ohhddHHHHHHHHdddo`,`ohHHHhHHHHHHHddddo`,`oddddddddHHHdddddo`,`.oodssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhHHHHHdHdHHHHo`,`.ohhddHHHHHHHHdddo`,`ohHHHhHHHHHHHddddo`,`oddddddddHHHdddddo`,`.oodssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhHHHHHdHdHHHHo`,`.ohhddHHHHHHHHdddo`,`ohHHHhHHHHHHHddddo`,`oddddddddHHHdddddo`,`.oodssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.....o.ooooo.......`,`....ohohhhhhoo.....`,`..oohhdhhhdHHHo....`,`.ohhhhhhHHHHHHHo...`,`.ohhhhhhHHHhHHHoo..`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHddddo.`,`oHdddddddddddddddo.`,`oHHHSdssdsdssdSddo.`,`oHHhSsssssssssSddo.`,`oHHHSseEsssEesSddo.`,`oHHHSseessseesSddo.`,`.oookSsssSsssSkoo..`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.......ooooo.......`,`....ooohhhhhooo....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`.ohhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSddddoo....`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.......ooooo.......`,`....ooohhhhhooo....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`.ohhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSddddoo....`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.......ooooo.......`,`....ooohhhhhooo....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`.ohhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSddddoo....`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`...oooohhhhhho.....`,`..ohhhhhhhhhHHoo...`,`.oohhhhhhhHHHdHHo..`,`ohhhhhhhHHdHHHHHo..`,`ohhhhhHHHHHHdHHHdo.`,`ohhhhHHHHHHHHHHdHdo`,`hhhdddHHHHHHHHHdddo`,`hHHHhHHHHHHHHddddo.`,`HhHdddddddddddddddo`,`oHdHSdsdsssdsdSdddo`,`odHHSsssssssssSddo.`,`oHHHSseEsssEesSddo.`,`oHHHSseessseesSddo.`,`.odddSsssSsssSddo..`,`..odddSssmssSddo...`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHHHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`HddddddddHHHddddddo`,`ooodssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHHHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`HddddddddHHHddddddo`,`ooodssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHHHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`HddddddddHHHddddddo`,`ooodssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`.....oooooooo.....`,`...oohhhhhhhHoo...`,`..ohhhhhhhHhHdHo..`,`.ohhhhhhHHHhHHHHo.`,`.ohhhhHhdHHHdHHHo.`,`ohhhHHHdHHHdHHdHdo`,`ohHHHHHHHHHHdHdddo`,`oHHddddddddddddddo`,`oHHdSSsssssssSSddo`,`.odHSsssssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....oooooooo.....`,`....ohhhhhhhHoo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhHhHHHdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHhHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....oooooooo.....`,`....ohhhhhhhHoo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhHhHHHdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHhHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....oooooooo.....`,`....ohhhhhhhHoo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhHhHHHdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHhHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`......oooooo.......`,`....oohhhhhHoo.....`,`...ohhhhhhHHHHo....`,`..ohhhhhHHHHdHHo...`,`.oohhhdHdHHHHHHooo.`,`ohhhhHhHHHHHHHHdddo`,`ohhHHHHHHHHHHdddddo`,`oXXdddddddddddddXXo`,`ohHHSSddHHHHHHHdddo`,`oHHHSssssssddddoddo`,`oHHHSseEsssEesSoddo`,`.oooSseessseesSkoo.`,`....kSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`......ooooooo......`,`.....ohhhhhhHo.....`,`....ohhhhhdHHHo....`,`...ohhhhdhdhHHHo...`,`..ohhhhHHHdHHHHdo..`,`..ohhHHHHHHdHHdddo.`,`..oHHHHHHHHHdddddo.`,`..oddddddHHHdddXXo.`,`..odssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsdddddoddo.`,`.ksmsssSSddddooddo.`,`..kkssSSkoooo.oddo.`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`......ooooooo......`,`.....ohhhhhhHo.....`,`....ohhhhhdHHHo....`,`...ohhhhdhdhHHHo...`,`..ohhhhHHHdHHHHdo..`,`..ohhHHHHHHdHHdddo.`,`..oHHHHHHHHHdddddo.`,`..oddddddHHHdddXXo.`,`..odssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsdddddoddo.`,`.ksmsssSSddddooddo.`,`..kkssSSkoooo.oddo.`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`......ooooooo......`,`.....ohhhhhhHo.....`,`....ohhhhhdHHHo....`,`...ohhhhdhdhHHHo...`,`..ohhhhHHHdHHHHdo..`,`..ohhHHHHHHdHHdddo.`,`..oHHHHHHHHHdddddo.`,`..oddddddHHHdddXXo.`,`..odssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsdddddoddo.`,`.ksmsssSSddddooddo.`,`..kkssSSkoooo.oddo.`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`......ohhhho......`,`......ohhhHo......`,`.....kohhHHok.....`,`....knsHHHHssk....`,`...knssHHHHsssk...`,`..knsssHHHHssSSk..`,`.ksssssHHHHsSSSSk.`,`.ksssssHHHHSSSSSk.`,`.ksssssHHHdSSSSSk.`,`.ksssssddddSSSSSk.`,`..ksSSsssssssSSk..`,`..ksSseEsssEesSk..`,`...kSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....ohhhhhhHo....`,`....ohhhhhhHHHo...`,`...ohhhhhHHHHHo...`,`..ohhhhhHHHHHHo...`,`..ohhhHHHHHHHHsk..`,`..knssssssssssSSk.`,`..ksssssssssSSSSk.`,`..kssssssssSSSSSk.`,`..kssssssSSSSSSSk.`,`..ksssssSSSSSSSSk.`,`.kodssdSSSSSSSSSk.`,`kseEsssSSSSSSSSk..`,`kseesssSsSSSSSk...`,`.ksmsssSSSSSSk....`,`..kkssSSoddok.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....ohhhhhhHo....`,`....ohhhhhhHHHo...`,`...ohhhhhHHHHHo...`,`..ohhhhhHHHHHHo...`,`..ohhhHHHHHHHHsk..`,`..knssssssssssSSk.`,`..ksssssssssSSSSk.`,`..kssssssssSSSSSk.`,`..kssssssSSSSSSSk.`,`..ksssssSSSSSSSSk.`,`.kodssdSSSSSSSSSk.`,`kseEsssSSSSSSSSk..`,`kseesssSsSSSSSk...`,`.ksmsssSSSSSSk....`,`..kkssSSoddok.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....ohhhhhhHo....`,`....ohhhhhhHHHo...`,`...ohhhhhHHHHHo...`,`..ohhhhhHHHHHHo...`,`..ohhhHHHHHHHHsk..`,`..knssssssssssSSk.`,`..ksssssssssSSSSk.`,`..kssssssssSSSSSk.`,`..kssssssSSSSSSSk.`,`..ksssssSSSSSSSSk.`,`.kodssdSSSSSSSSSk.`,`kseEsssSSSSSSSSk..`,`kseesssSsSSSSSk...`,`.ksmsssSSSSSSk....`,`..kkssSSoddok.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`......ohhhho......`,`.....oohhhhoo.....`,`...oohhhhhhhHoo...`,`..ohhhhhhhHhHHHo..`,`.ohhhhhhXXXhHHHHo.`,`.ohhhhdhdHHHHHHdo.`,`ohhhHHhHHHHHHHdddo`,`ohHHHHHHHHHHdddddo`,`oHhddddddddddddddo`,`oHHdSSdssdssdSSddo`,`.odHSsssssssssSdo.`,`.oHHSseEsssEesSdo.`,`.oHHSseessseesSdo.`,`.odddSsssSsssSddo.`,`..odddSssmssSddo..`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........ohhhho....`,`.....oooohhhho....`,`....ohhhhhhhHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhXXXHHHo.`,`.ohhhhdHHHdHdHHHdo`,`.ohhHHHHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........ohhhho....`,`.....oooohhhho....`,`....ohhhhhhhHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhXXXHHHo.`,`.ohhhhdHHHdHdHHHdo`,`.ohhHHHHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........ohhhho....`,`.....oooohhhho....`,`....ohhhhhhhHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhXXXHHHo.`,`.ohhhhdHHHdHdHHHdo`,`.ohhHHHHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.....o.ooooo.......`,`....ohohhhhhooo....`,`..oohhdhhhdHHHdo...`,`.ohhhhhhHHHHHHHoo..`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHddddo.`,`oHdddddddddddddddo.`,`oHHHSdssdsdssdSddo.`,`oHHhSsssssssssSddo.`,`oHHHSseEsssEesSddo.`,`oHHHSseessseesSddo.`,`.odddSsssSsssSddo..`,`..odddSssmssSddo...`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.....o.ooooo.o.....`,`....ohohhhhhoho....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHdHddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.....o.ooooo.o.....`,`....ohohhhhhoho....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHdHddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.....o.ooooo.o.....`,`....ohohhhhhoho....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHdHddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]}],dn=[null,{down:[`........qq........`,`.....qqqRXqqq.....`,`...qqRRRWWWRRqq...`,`..qRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrq.`,`qhhHHHHHHHHHHHdddq`,`oHHddddddddddddddo`,`.oHHSdsdHHHHHHHdo.`,`.oHHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........qqq.......`,`.....qqqRRXqqq....`,`....qRRRRRRRRRq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrrq`,`.qhhHHHHHHHHHHHddq`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........qqq.......`,`.....qqqRRXqqq....`,`....qRRRRRRRRRq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrrq`,`.qhhHHHHHHHHHHHddq`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........qqq.......`,`.....qqqRRXqqq....`,`....qRRRRRRRRRq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrrq`,`.qhhHHHHHHHHHHHddq`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......qqqq.......`,`....qqqRRRRqqq....`,`...qRRRRRRRRRRq...`,`..qRRRRRRRRRRRRq..`,`.qXXXXXXXXXXXXXXq.`,`.qhhhHHHHHHHHHHHq.`,`ohhHHHHHHHHHHHdddo`,`oHHddddddddddddddo`,`oHHHSdsdHHHHHHHddo`,`.oHHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......qqqq.......`,`....qqqRRRRqqqq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qXXXXXXXXXXXXXXq.`,`.qhhhhHHHHHHHHHHHq`,`.ohhHHHHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......qqqq.......`,`....qqqRRRRqqqq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qXXXXXXXXXXXXXXq.`,`.qhhhhHHHHHHHHHHHq`,`.ohhHHHHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......qqqq.......`,`....qqqRRRRqqqq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qXXXXXXXXXXXXXXq.`,`.qhhhhHHHHHHHHHHHq`,`.ohhHHHHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`..qRRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRrrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHdddddq.`,`.oHdddddddddddddo.`,`.oHHSdsdHHHHHHHdo.`,`.oHHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`..odoSsssSsssSk...`,`...o.kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`..qRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHHddddq.`,`.odddddddHddddddo.`,`..odssdSSdddddddo.`,`.ksssssSSdddddddo.`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`..qRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHHddddq.`,`.odddddddHddddddo.`,`..odssdSSdddddddo.`,`.ksssssSSdddddddo.`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`..qRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHHddddq.`,`.odddddddHddddddo.`,`..odssdSSdddddddo.`,`.ksssssSSdddddddo.`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.....qqqqqqqq......`,`...qqRRRRRRRRqq....`,`..qRRRRRRRRRRRRq...`,`.qRRRRRRRRRRRRRRq..`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHdq.`,`hHHHHHHHHHHHHHddddo`,`HHHdddddddddddddddo`,`oHHHSdsdHHHHHHHddo.`,`oHHHSssssssddddddo.`,`.ooHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.....qqqqqqqqq.....`,`...qqRRRRRRRRRqq...`,`..qRRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRRq.`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHddq`,`ohHHHHHHHHHHHHddddo`,`oddddddddHHHddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSkkoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.....qqqqqqqqq.....`,`...qqRRRRRRRRRqq...`,`..qRRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRRq.`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHddq`,`ohHHHHHHHHHHHHddddo`,`oddddddddHHHddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSkkoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.....qqqqqqqqq.....`,`...qqRRRRRRRRRqq...`,`..qRRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRRq.`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHddq`,`ohHHHHHHHHHHHHddddo`,`oddddddddHHHddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSkkoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]}],fn={base:{k:`#373337`,E:`#f0f0f8`,e:`#36363e`,m:`#a0605a`,q:`#f2a0a0`,s:`#fbe0c8`,S:`#d5beaa`,X:`#9aa0a6`,H:`#363438`,o:`#313132`,J:`#f4f4f0`,L:`#f4f4f0`,c:`#f8f8f8`,P:`#3a4058`,B:`#f0f0f0`,w:`#b0b0bc`,h:`#38353a`,d:`#353336`,W:`#f8f8f8`,D:`#b09d8c`,n:`#fffbe0`,j:`#bebebb`,l:`#bebebb`,p:`#35394b`},hairColor:[{H:`#363438`,o:`#313132`,v:`#333235`,h:`#38353a`,d:`#353336`},{H:`#3d3539`,o:`#343132`,v:`#373335`,h:`#40363b`,d:`#393336`},{H:`#503428`,o:`#3a302c`,v:`#42322c`,h:`#5f3b2c`,d:`#48332a`},{H:`#5c3a26`,o:`#3e312a`,v:`#463328`,h:`#764a31`,d:`#4d3425`},{H:`#704830`,o:`#443329`,v:`#4a3426`,h:`#8f5c3d`,d:`#533524`},{H:`#a04828`,o:`#532e21`,v:`#5e2e1c`,h:`#cd5c33`,d:`#76351e`},{H:`#d88838`,o:`#5b3918`,v:`#774b1f`,h:`#ffae48`,d:`#a06529`},{H:`#f8d070`,o:`#886840`,v:`#88723e`,h:`#ffff8f`,d:`#b89a53`},{H:`#e8e8f0`,o:`#8888a0`,v:`#808084`,h:`#ffffff`,d:`#acacb2`},{H:`#f08ab8`,o:`#8a3a62`,v:`#844c65`,h:`#ffb1ec`,d:`#b26688`},{H:`#5a78d8`,o:`#2a3872`,v:`#324277`,h:`#739aff`,d:`#4359a0`},{H:`#58a878`,o:`#204b33`,v:`#305c42`,h:`#71d79a`,d:`#417c59`}],skin:[{s:`#fbe0c8`,m:`#a0605a`,S:`#d5beaa`,D:`#b09d8c`,n:`#fffbe0`},{s:`#f8d0b0`,m:`#9a5a48`,S:`#d3b196`,D:`#ae927b`,n:`#ffe9c5`},{s:`#f0c8a0`,m:`#9a5a48`,S:`#ccaa88`,D:`#a88c70`,n:`#ffe0b3`},{s:`#d8a07c`,m:`#a0505a`,S:`#b88869`,D:`#977057`,n:`#f2b38b`},{s:`#c48a62`,m:`#7a4232`,S:`#a77553`,D:`#896145`,n:`#dc9b6e`},{s:`#b87a52`,m:`#6e3e30`,S:`#9c6846`,D:`#815539`,n:`#ce895c`},{s:`#94603e`,m:`#5e3226`,S:`#7e5235`,D:`#68432b`,n:`#a66c45`},{s:`#6e4430`,m:`#552f23`,S:`#5e3a29`,D:`#513426`,n:`#7b4c36`}],shirt:[{J:`#f4f4f0`,j:`#bebebb`},{J:`#70b8e0`,j:`#5790af`},{J:`#f08048`,j:`#bb6438`},{J:`#f890a8`,j:`#c17083`},{J:`#f8d040`,j:`#c1a232`},{J:`#9cc0e0`,j:`#7a96af`},{J:`#34446a`,j:`#2f3b59`},{J:`#9a2a48`,j:`#782138`},{J:`#58a878`,j:`#45835e`},{J:`#7d4fc9`,j:`#623e9d`},{J:`#3a3f58`,j:`#35394d`},{J:`#363a47`,j:`#353842`},{J:`#2a3870`,j:`#2c3763`},{J:`#e0823c`,j:`#af652f`}],sleeves:[{L:`#f4f4f0`,l:`#bebebb`},{L:`#70b8e0`,l:`#5790af`},{L:`#f08048`,l:`#bb6438`},{L:`#f890a8`,l:`#c17083`},{L:`#f8d040`,l:`#c1a232`},{L:`#9cc0e0`,l:`#7a96af`},{L:`#34446a`,l:`#2f3b59`},{L:`#9a2a48`,l:`#782138`},{L:`#58a878`,l:`#45835e`},{L:`#7d4fc9`,l:`#623e9d`},{L:`#3a3f58`,l:`#35394d`},{L:`#363a47`,l:`#353842`},{L:`#2a3870`,l:`#2c3763`},{L:`#e0823c`,l:`#af652f`}],pants:[{P:`#3a4058`,p:`#35394b`},{P:`#4060a8`,p:`#30487e`},{P:`#506888`,p:`#3c4e66`},{P:`#605848`,p:`#484236`},{P:`#b8a888`,p:`#8a7e66`},{P:`#4a6eb0`,p:`#385384`},{P:`#383840`,p:`#36363c`},{P:`#6a4a32`,p:`#503826`},{P:`#35373f`,p:`#34353b`},{P:`#f0ece2`,p:`#b4b1aa`}],shoes:[{B:`#f0f0f0`,w:`#b0b0bc`},{B:`#484848`,w:`#f0f0f0`},{B:`#c06838`,w:`#f8f8f8`},{B:`#403838`,w:`#706868`},{B:`#c03850`,w:`#f8f8f8`},{B:`#3d3537`,w:`#5a4a48`}],hat:[[],[{R:`#3f7bd6`,r:`#2d599a`,q:`#243c61`,X:`#9aa0a6`},{R:`#2fa37a`,r:`#227558`,q:`#1b4939`,X:`#9aa0a6`},{R:`#d6604a`,r:`#9a4535`,q:`#5d2d25`,X:`#9aa0a6`},{R:`#7d4fc9`,r:`#5a3991`,q:`#402e5e`,X:`#9aa0a6`},{R:`#e0b23c`,r:`#a1802b`,q:`#5a4718`,X:`#9aa0a6`},{R:`#3a3f58`,r:`#35384a`,q:`#33353f`,X:`#9aa0a6`}],[{R:`#3f7bd6`,r:`#2d599a`,q:`#243c61`,X:`#e8c040`},{R:`#2fa37a`,r:`#227558`,q:`#1b4939`,X:`#e8c040`},{R:`#d6604a`,r:`#9a4535`,q:`#5d2d25`,X:`#e8c040`},{R:`#7d4fc9`,r:`#5a3991`,q:`#402e5e`,X:`#e8c040`},{R:`#e0b23c`,r:`#a1802b`,q:`#5a4718`,X:`#e8c040`},{R:`#3a3f58`,r:`#35384a`,q:`#33353f`,X:`#e8c040`}],[{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`}],[{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`}]]},pn={hair:21,hairColor:12,skin:8,eyes:5,glasses:4,face:6,hat:5,shirt:14,sleeves:14,outfit:6,pants:10,shoes:6},mn={hair:[0,1,2,3,5,6,7,8,9,10,11,13,14,16,20],hairColor:[0,1,2,3,4,5,6,7],skin:[0,1,2,3,4,5,6,7],eyes:[0,1,2,3],glasses:[0,1,2],face:[0,1,2,3,4,5],hat:[0],shirt:[0,1,2,3,4,5,6,7,8,10,11,12],sleeves:[0,1,2,3,4,5,6,7,8,10,11,12],outfit:[0,1,2],pants:[0,1,2,3,4,5,6,7,8,9],shoes:[0,1,2,3,4,5]},hn=new Set([`iTerm.app`,`WezTerm`,`vscode`,`ghostty`,`Hyper`,`Tabby`,`rio`]),gn=new Set([`iTerm.app`,`WezTerm`,`vscode`,`ghostty`,`Hyper`,`Tabby`,`rio`]);function _n({env:e=process.env,argv:t=process.argv,isTTY:n=!!process.stdout.isTTY}={}){if(t.includes(`--no-color`)||t.includes(`--no-colour`)||e.NO_COLOR!==void 0&&e.NO_COLOR!==``)return 0;let r=e.FORCE_COLOR,i;if(r!==void 0){if(r===`0`||r===`false`)return 0;i=r===`2`?2:r===`3`?3:1}if(!n||e.TERM===`dumb`)return i??0;let a=1,o=(e.COLORTERM??``).toLowerCase();return o===`truecolor`||o===`24bit`||hn.has(e.TERM_PROGRAM??``)||/-(truecolor|direct)$|^xterm-(kitty|ghostty)$/.test(e.TERM??``)?a=3:/256(col)?/.test(e.TERM??``)&&(a=2),i!==void 0&&i>a?i:a}function vn(e,t){return e.FORCE_HYPERLINK===void 0?!t||e.TMUX||/^screen/.test(e.TERM??``)?!1:gn.has(e.TERM_PROGRAM??``)||e.WT_SESSION||e.KITTY_WINDOW_ID||/^xterm-(kitty|ghostty)$|^alacritty/.test(e.TERM??``)?!0:Number(e.VTE_VERSION??0)>=5e3:e.FORCE_HYPERLINK!==`0`&&e.FORCE_HYPERLINK!==``&&t}function yn(e={}){let t=e.env??process.env,n=e.isTTY??!!process.stdout.isTTY,r=_n({...e,env:t,isTTY:n}),i=n&&r>0&&t.TERM!==`dumb`,a=e.columns??(n?process.stdout.columns:void 0)??(Number(t.COLUMNS)||void 0),o=Number(t.BITFOLK_COLUMNS)||void 0,s=n&&a?Math.max(40,a):o?Math.max(40,o):void 0,c=s??Math.max(40,Number(t.COLUMNS)||80);return{depth:r,tty:n,fancy:i,links:vn(t,i),columns:s,layout:c,live:n&&e.columns===void 0}}let j=yn();function bn(e){return j=`depth`in e||`fancy`in e?{...j,...e}:yn(e),j}const xn=()=>j.live&&process.stdout.columns?Math.max(40,process.stdout.columns):j.columns,Sn=()=>xn()??j.layout,M=()=>xn()??1/0,Cn=e=>{let t=parseInt(e.replace(`#`,``),16);return[t>>16&255,t>>8&255,t&255]};function wn([e,t,n]){let r=e=>e<48?0:e<115?1:Math.floor((e-35)/40),i=[0,95,135,175,215,255],[a,o,s]=[r(e),r(t),r(n)],c=16+36*a+6*o+s,l=(i[a]-e)**2+(i[o]-t)**2+(i[s]-n)**2,u=(e+t+n)/3,d=u>238?23:Math.max(0,Math.round((u-8)/10)),f=8+d*10;return(f-e)**2+(f-t)**2+(f-n)**2<l?232+d:c}const Tn=(e,t,n)=>n>=3?`38;2;${Cn(e).join(`;`)}`:n===2?`38;5;${wn(Cn(e))}`:String(t),En=(e,t)=>t>=3?`48;2;${Cn(e).join(`;`)}`:`48;5;${wn(Cn(e))}`;function Dn(e,t,n){if(j.depth===0||n===``)return n;let r=`[${e}m`,i=`[${t}m`;return r+n.split(i).join(i+r)+i}const On=(e,t=39)=>n=>Dn(Tn(e,t,j.depth),`39`,n),N=e=>Dn(`1`,`22`,e),P=e=>Dn(`2`,`22`,e),kn=e=>Dn(`4`,`24`,e),F={ok:On(`#4f9a3a`,32),warn:On(`#c98a12`,33),err:On(`#e0483a`,31),accent:On(rn.coral,91),tool:On(`#5f7fe8`,94),money:On(`#c98a12`,33),sky:On(`#3d8fd0`,36),dim:P,bold:N},An=[[`#d4733f`,33],[`#9b5cd6`,95],[`#1f9e8f`,36],[`#c94f7c`,35],[`#7f9a1f`,32],[`#b07a2a`,93]];function jn(e){let t=0;for(let n of e)t=t*31+n.codePointAt(0)>>>0;let[n,r]=An[t%An.length];return e=>N(On(n,r)(e))}const I={ok:`✓`,fail:`✗`,skip:`·`,dot:`●`,idle:`○`,arrow:`›`,warn:`!`},Mn=/\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g,Nn=e=>e.replace(Mn,``),L=e=>e.replace(/[\t\n\r]+/g,` `).replace(/[\x00-\x1f\x7f-\x9f]/g,``),Pn=e=>e.replace(/\x1b\[[0-9;]*m|[\x00-\x1f\x7f-\x9f]/g,e=>e.length>1&&j.depth>0?e:e===`
8
- `||e===` `?` `:``),R=e=>e.replace(/ /g,`\xA0`),Fn=e=>e.replace(/\u00a0/g,` `),In=e=>e>=768&&e<=879||e>=8203&&e<=8207||e>=8400&&e<=8447||e>=65024&&e<=65039||e===8205,Ln=e=>e>=4352&&e<=4447||e>=11904&&e<=12350||e>=12353&&e<=13311||e>=13312&&e<=19903||e>=19968&&e<=40959||e>=40960&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=128591||e>=129280&&e<=129535||e>=131072&&e<=262141,Rn=e=>{let t=e.codePointAt(0);return t<32||t>=127&&t<160||In(t)?0:Ln(t)?2:1};function z(e){let t=0;for(let n of Nn(e))t+=Rn(n);return t}function zn(e){let t=[],n=0;for(let r of e.matchAll(Mn)){for(let i of e.slice(n,r.index))t.push({esc:!1,text:i});t.push({esc:!0,text:r[0]}),n=r.index+r[0].length}for(let r of e.slice(n))t.push({esc:!1,text:r});return t}function B(e,t){if(z(e)<=t)return e;if(t<=0)return``;let n=``,r=0,i=!1;for(let a of zn(e)){if(a.esc){n+=a.text,i=!0;continue}let e=Rn(a.text);if(r+e>t-1)break;n+=a.text,r+=e}return n+`…`+(i?`\x1B[0m`:``)}const Bn=(e,t)=>e+` `.repeat(Math.max(0,t-z(e))),Vn=(e,t)=>` `.repeat(Math.max(0,t-z(e)))+e;function V(e,t,n=0){if(!Number.isFinite(t)||z(e)<=t)return[Fn(e)];let r=` `.repeat(n),i=[],a=``,o=0,s=()=>i.length?t-n:t,c=()=>{i.push((i.length?r:``)+a.replace(/ +$/,``)),a=``,o=0};for(let t of e.split(/( +)/)){if(t===``)continue;let e=z(t);/^ +$/.test(t)?(o||!i.length)&&o+e<=s()&&(a+=t,o+=e):(a.trim()&&o+e>s()&&c(),a+=t,o+=e)}return(a||!i.length)&&c(),i.map(Fn)}function Hn(e,t={}){return Un(e,t).flat()}function Un(e,t={}){let n=` `.repeat(t.indent??0),r=t.gap??2,i=t.max??M(),a=Math.max(0,...e.map(e=>e.length)),o=Array.from({length:a},(t,n)=>Math.max(0,...e.filter(e=>n<e.length-1).map(e=>z(e[n])))),s=[];for(let t of e){let e=[];s.push(e);let a=n+t.slice(0,-1).map((e,t)=>Bn(e,o[t]+r)).join(``),c=t[t.length-1]??``,l=z(a);if(l+z(c)<=i)e.push((a+c).replace(/ +$/,``));else if(i-l<20){let t=z(n)+4;e.push(...V(a.replace(/ +$/,``),i,z(n)+2));for(let n of V(c,i-t,0))e.push(` `.repeat(t)+n)}else{let t=V(c,i-l,0);e.push(a+t[0]);for(let n of t.slice(1))e.push(` `.repeat(l)+n)}}return s.map(e=>e.map(Fn))}const Wn=(e,t=0,n)=>Hn(e.map(([e,t])=>[P(e),t]),{indent:t,gap:2,max:n});function Gn(e,t={}){let n=Math.max(20,t.max??Sn()),r=t.title?` ${t.title} `:``,i=Math.min(n-4,Math.max(z(r)+2,...e.map(z))),a=e=>P(e);return[a(`╭─`)+(r?N(B(r,i)):``)+a(`─`.repeat(Math.max(0,i-z(B(r,i))))+`─╮`),...e.map(e=>{let t=B(e,i);return a(`│ `)+Bn(t,i)+a(` │`)}),a(`╰`+`─`.repeat(i+2)+`╯`)]}function Kn(e,t,n=2,r=0){let i=Math.max(0,...e.map(z)),a=Math.max(e.length,t.length+r);return Array.from({length:a},(a,o)=>{let s=t[o-r];return s===void 0?e[o]??``:Bn(e[o]??``,i+n)+s}).map(e=>e.replace(/ +$/,``))}function qn(e,t=e){let n=t===e?e:`${t} (${e})`;return j.links?`\x1b]8;;${e}\x1b\\${kn(F.sky(t))}\x1b]8;;\x1b\\${t===e?``:P(` (${e})`)}`:j.depth?kn(F.sky(n)):n}const H=e=>F.accent(e),U=e=>`${F.ok(I.ok)} ${e}`,Jn=e=>`${F.warn(I.warn)} ${F.warn(e)}`;function Yn(e,t=``){let n=[...e.matchAll(/[.;:] /g)].map(e=>e.index),r=t=>e.slice(t+2),i=n.find(e=>/^(Try|try|run|Run|press|Press|Copy)\b/.test(r(e)))??n.filter(e=>/\bbitfolk\b/.test(r(e))).pop(),a=i===void 0?e:e.slice(0,i+1),o=i===void 0?``:r(i);return`${F.err(I.fail)} ${F.err(t+a)}${o?` `+Xn(o):``}`}function Xn(e){return e.split(/((?:npx )?bitfolk(?: (?:--?)?[a-z][\w-]*| <[^>]+>)+)/).map((e,t)=>e===``?``:t%2?H(e):P(e)).join(``)}const W=(e,t=2)=>V(e,M(),t).join(`
9
- `),Zn=(e,t=process.stderr,n=process.env)=>!t.isTTY&&n.FORCE_COLOR===void 0?Nn(e):e,Qn=[`·`,`✢`,`✳`,`✶`,`✻`,`✽`,`✻`,`✶`,`✳`,`✢`],$n=[`Waiting for work`,`Ready for new sessions`,`Sessions start when someone asks`,`Checking in uses no model calls`],er=(e=process.env)=>j.fancy&&!e.BITFOLK_NO_ANIMATION&&!(e.CI&&e.CI!==`0`&&e.CI!==`false`);function tr(e){let t=Math.max(0,Math.floor(e/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m ${t%60}s`:`${Math.floor(t/3600)}h ${String(Math.floor(t%3600/60)).padStart(2,`0`)}m`}const nr=(e,t,n)=>{let[r,i]=[Cn(e),Cn(t)];return`#`+r.map((e,t)=>Math.round(e+(i[t]-e)*n).toString(16).padStart(2,`0`)).join(``)},rr=[rn.coral,nr(rn.coral,rn.gold,.45),nr(rn.coral,rn.gold,.8),nr(rn.gold,`#fff3c4`,.5)];function ir(e,t,n=j.depth){let r=[...Nn(e)];if(n===0)return r.join(``);let i=e=>Math.max(0,3-Math.abs(e-t)),a=``,o=``,s=-1,c=()=>{o&&=(a+=n===1?s>=2?`${o}`:`${o}`:`[${Tn(rr[s],39,n)}m${o}`,``)};return r.forEach((e,t)=>{let r=n===1?i(t)>=2?2:0:i(t);r!==s&&c(),s=r,o+=e}),c(),a}const ar=(e,t)=>e%(t+8)-3;function or(e,t=j.depth,n=Qn){let r=n[(e%n.length+n.length)%n.length];return t===0?r:r===`✽`?`[${Tn(rn.gold,93,t)}m${r}`:`[${Tn(rn.coral,91,t)}m${r}`}function sr(e){let t=e.depth??j.depth,n=Nn(e.text).replace(/(\.\.\.|…)$/,``),r=[e.elapsedMs>=(e.timeAfterMs??2e3)?tr(e.elapsedMs):null,e.hint].filter(Boolean).join(` · `),i=e=>t?`${e}`:e,a=`${or(e.frame,t)} ${ir(n+`…`,ar(e.frame,[...n].length),t)}${e.detail?` `+i(e.detail):``}${r?` `+i(`(${r})`):``}`;return e.max?B(a,e.max):a}const cr=`\x1B[?25l`,lr=`\r\x1B[2K`,ur=[[`SIGINT`,130],[`SIGTERM`,143],[`SIGHUP`,129]];function dr(e,t={}){let n=t.out??process.stdout,r=t.animate??(er()&&!!n.isTTY),i=t.now??Date.now,a=t.verbs?.length?[e,...t.verbs.filter(t=>t!==e)]:[e],o=e,s=!1,c=e=>void(e!==void 0&&n.write(e+`
10
- `)),l=e=>({text:e=>{o=e,s=!0},stop:e,ok:t=>e(U(t)),fail:t=>e(`${F.err(I.fail)} ${F.err(t)}`)});if(!r)return t.quiet||n.write(`${e.replace(/(\.\.\.|…)$/,``)}…${t.hint?` (${t.hint})`:``}\n`),l(c);let u=i(),d=0,f=()=>Math.max(1,(n.columns||Sn())-1),p=()=>{let e=i()-u,r=s||a.length===1?o:a[Math.floor(e/(t.rotateMs??4e3))%a.length];n.write(lr+sr({text:r,frame:d++,elapsedMs:e,hint:t.hint,max:f()}))};n.write(cr),p();let m=setInterval(p,100);m.unref();let h=!1,g=()=>void n.write(`\r\x1B[2K\x1B[?25h`),_=e=>{if(!h){h=!0,clearInterval(m);for(let[e,t]of v)process.removeListener(e,t);process.removeListener(`exit`,g),g(),c(e)}},v=[];for(let[e,t]of ur){if(process.listenerCount(e)>0)continue;let n=()=>{_(),process.exit(t)};process.once(e,n),v.push([e,n])}return process.once(`exit`,g),l(_)}async function G(e,t,n={}){let r=dr(e,{quiet:!0,...n});try{return await t()}finally{r.stop()}}const fr=(e,t)=>e.reduce((e,n)=>e+Math.max(1,Math.ceil(z(n)/Math.max(1,t))),0);function pr(e,t={}){let n=t.out??process.stdout,r=(t.animate??er())&&!!n.isTTY;if(!r)return{active:r,log:e=>void n.write(e+`
11
- `),redraw:()=>{},stop:()=>{}};let i=0,a=!1,o=[],s=()=>({columns:n.columns||Sn(),rows:n.rows??(n===process.stdout?process.stdout.rows:void 0)}),c=()=>{let t=s(),n=e(i,t),r=Math.max(1,t.columns-1);return(Array.isArray(n)?n:[n]).map(e=>B(e,r))},l=()=>{let e=fr(o,n.columns||Sn())-1;return e>0?`\r[${e}A`:lr},u=e=>{let t=l()+e.join(`
12
- `);return o=e,e.length>1?`[?2026h${t}[?2026l`:t},d=()=>{a||n.write(u(c()))},f=()=>{i++,d()},p=()=>typeof t.intervalMs==`function`?t.intervalMs():t.intervalMs??100,m,h=()=>{m=setTimeout(()=>{f(),a||h()},p()),m.unref()};n.write(cr),d(),h();let g=()=>d();n.on?.(`resize`,g);let _=()=>{a||(a=!0,clearTimeout(m),n.off?.(`resize`,g),process.removeListener(`exit`,_),n.write(l()+`\x1B[?25h`),o=[])};return process.once(`exit`,_),{active:r,log:e=>{if(a)return void n.write(e+`
5
+ `).filter(Boolean).at(-1):null);function qe(e){return e===`bypass`?[`--permission-mode`,`bypassPermissions`]:e===`auto`?[`--permission-mode`,`auto`]:[`--permission-mode`,`acceptEdits`,`--allowedTools`,...Ue]}const Je={runtime:`claude_code`,bin:()=>`claude`,launch(e,t,n){return{bin:`claude`,args:[`-p`,`--output-format`,`stream-json`,`--verbose`,`--max-budget-usd`,String(e.maxUsdPerRun),...e.model?[`--model`,e.model]:[],...n?[`--resume`,n]:[],...qe(e.permission)],stdin:t}},parse(e,t){let n=We(e);if(!n)return;typeof n.session_id==`string`&&(t.sessionId=n.session_id),n.type===`system`&&typeof n.model==`string`&&(t.model=n.model),n.type===`rate_limit_event`&&n.rate_limit_info&&typeof n.rate_limit_info==`object`&&(t.limit=Ne(n.rate_limit_info)??t.limit??null);let r=n.message;if(n.type===`assistant`&&r?.usage&&r.id!==t.countedMessage){t.countedMessage=r.id;let e=r.usage;t.inputTokens+=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),t.outputTokens+=e.output_tokens??0}if(n.type===`result`){let e=n.usage??{};t.inputTokens=(e.input_tokens??0)+(e.cache_creation_input_tokens??0)+(e.cache_read_input_tokens??0),t.outputTokens=e.output_tokens??0,typeof n.total_cost_usd==`number`&&(t.costMicros=Math.round(n.total_cost_usd*1e6)),t.isError=n.is_error===!0||typeof n.subtype==`string`&&n.subtype!==`success`,t.isError&&(t.error=Ie(n.result)??(typeof n.subtype==`string`?n.subtype:null)),t.overBudget=typeof n.subtype==`string`&&n.subtype.includes(`budget`),t.summary=Ke(n.result)??t.summary}},activity(e,t){let n=We(e);if(n?.type!==`assistant`||!Array.isArray(n.message?.content))return null;let r=n.message.content,i=r.find(e=>e?.type===`tool_use`);return D(i?He(i.name,i.input??{},t):r.find(e=>e?.type===`text`)?.text)}};function Ye(e){return e===`bypass`?[`--dangerously-bypass-approvals-and-sandbox`]:[`-c`,`sandbox_mode="workspace-write"`,`-c`,`sandbox_workspace_write.network_access=true`]}const Xe={claude_code:Je,codex:{runtime:`codex`,bin:()=>`codex`,runnerCommits:e=>e.permission!==`bypass`,launch(e,t,n){return{bin:`codex`,args:[`exec`,...n?[`resume`,n]:[],`--json`,`--skip-git-repo-check`,...Ye(e.permission),...e.model?[`-m`,e.model]:[],`-`],stdin:t}},parse(e,t){let n=We(e);n&&(n.type===`thread.started`&&typeof n.thread_id==`string`&&(t.sessionId=n.thread_id),n.type===`turn.completed`&&n.usage&&(t.inputTokens+=n.usage.input_tokens??0,t.outputTokens+=n.usage.output_tokens??0),(n.type===`turn.failed`||n.type===`error`)&&(t.isError=!0,t.error=Ie(n.error??n.message)??t.error),n.type===`item.completed`&&n.item?.type===`agent_message`&&(t.summary=Ke(n.item.text)??t.summary))},activity(e,t){let n=We(e),r=n?.item;if(!r||n.type!==`item.started`&&n.type!==`item.completed`)return null;if(r.type===`command_execution`)return n.type===`item.started`?D(`Running ${Ve(r.command)}`):null;if(n.type!==`item.completed`)return null;if(r.type===`file_change`){let e=(Array.isArray(r.changes)?r.changes:[]).map(e=>Be(e?.path,t));return e.length?D(`Editing ${e[0]}${e.length>1?` and ${e.length-1} more`:``}`):null}return r.type===`agent_message`?D(r.text):null}},opencode:{runtime:`opencode`,bin:()=>`opencode`,launch(e,t,n){return{bin:`opencode`,args:[`run`,`--format`,`json`,...e.model?[`-m`,e.model]:[],...n?[`-s`,n]:[],t],stdin:``}},parse(e,t){let n=We(e);if(!n)return;typeof n.sessionID==`string`&&(t.sessionId=n.sessionID);let r=n.part??{};if(n.type===`text`&&typeof r.text==`string`&&(t.summary=Ke(r.text)??t.summary),n.type===`step_finish`){let e=r.tokens??{};t.inputTokens+=(e.input??0)+(e.cache?.read??0)+(e.cache?.write??0),t.outputTokens+=(e.output??0)+(e.reasoning??0),typeof r.cost==`number`&&(t.costMicros=(t.costMicros??0)+Math.round(r.cost*1e6))}n.type===`error`&&(t.isError=!0,t.error=Ie(n.error?.data?.message??n.error?.message??n.error)??t.error)},activity(e,t){let n=We(e),r=n?.part??{};return n?.type===`tool_use`&&r.tool?D(He(r.tool,r.state?.input??{},t)):n?.type===`text`?D(r.text):null}},hermes:{runtime:`hermes`,bin:()=>`hermes`,resumes:!1,launch(e,t){let n=c(fe(),`bitfolk-hermes-${ge()}.json`);return{bin:`hermes`,args:[`-z`,t,`--usage-file`,n,...e.model?[`-m`,e.model]:[],...e.permission===`safe`?[]:[`--yolo`]],stdin:``,usageFile:n}},parse(e,t){t.summary=Ge(e)??t.summary},activity:e=>D(e),afterExit(e,t){if(e.usageFile)try{let n=JSON.parse(ie(e.usageFile,`utf8`)),r=(...e)=>e.map(e=>n[e]??n.usage?.[e]).find(e=>typeof e==`number`);t.inputTokens=r(`input_tokens`,`prompt_tokens`)??t.inputTokens,t.outputTokens=r(`output_tokens`,`completion_tokens`)??t.outputTokens;let i=r(`cost_usd`,`total_cost_usd`,`cost`);i!==void 0&&(t.costMicros=Math.round(i*1e6)),typeof n.session_id==`string`&&(t.sessionId=n.session_id)}catch{}finally{S(e.usageFile,{force:!0})}}},command:{runtime:`command`,bin:e=>(e.command??``).trim().split(/\s+/)[0]??``,resumes:!1,launch(e,t){if(!e.command)throw Error(`${e.name} has runtime command but no --command`);return{bin:`sh`,args:[`-c`,e.command],stdin:t}},parse(e,t){let n=We(e)?.bitfolk;n&&typeof n==`object`?(typeof n.session_id==`string`&&(t.sessionId=n.session_id),typeof n.input_tokens==`number`&&Number.isFinite(n.input_tokens)&&(t.inputTokens=Math.max(0,Math.round(n.input_tokens))),typeof n.output_tokens==`number`&&Number.isFinite(n.output_tokens)&&(t.outputTokens=Math.max(0,Math.round(n.output_tokens))),typeof n.cost_usd==`number`&&(t.costMicros=Math.round(n.cost_usd*1e6)),typeof n.summary==`string`&&(t.summary=Ge(n.summary))):t.summary=Ge(e)??t.summary},activity(e){return D(We(e)?.bitfolk?.activity)}},acp:{runtime:`acp`,bin:e=>e.acp?.bin??``,resumes:!1,runnerCommits:()=>!0,launch(e){if(!e.acp?.bin)throw Error(`${e.name} has runtime acp but no ACP command`);return{bin:e.acp.bin,args:e.acp.args,stdin:``}},parse(){}}};function Ze(e){return e===`claude_code`||e===`codex`||e===`opencode`||e===`hermes`?e:null}const Qe=2e4;var $e=class extends Error{code;data;constructor(e,t,n){super(t),this.code=e,this.data=n}};const et=e=>new $e(-32601,`${e} isn't supported by this client`);var tt=class{#e=1;#t=new Map;#n;#r;#i=null;constructor(e,t,n){this.#n=e,this.#r=n,e.on(`error`,e=>this.close(Error(`the tool stopped reading its input (${e.code??e.message})`))),p({input:t,crlfDelay:1/0}).on(`line`,e=>this.#o(e)).on(`close`,()=>this.close(Error(`the tool exited before the turn ended`)))}get closed(){return this.#i!==null}close(e){if(!this.#i){this.#i=e;for(let[t,n]of this.#t)n.timer&&clearTimeout(n.timer),this.#t.delete(t),n.reject(e)}}end(){try{this.#n.end()}catch{}}#a(e){if(this.#i||!this.#n.writable)return!1;try{return this.#n.write(JSON.stringify({jsonrpc:`2.0`,...e})+`
6
+ `),!0}catch(e){return this.close(Error(`the tool stopped reading its input (${e.message})`)),!1}}request(e,t,n){if(this.#i)return Promise.reject(this.#i);let r=this.#e++;return new Promise((i,a)=>{let o={method:e,resolve:i,reject:a};n&&(o.timer=setTimeout(()=>{this.#t.delete(r),a(Error(`${e} got no answer within ${Math.round(n/1e3)}s`))},n),o.timer.unref?.()),this.#t.set(r,o),this.#a({id:r,method:e,params:t})||(this.#t.delete(r),o.timer&&clearTimeout(o.timer),a(this.#i??Error(`the tool's input is closed`)))})}notify(e,t){this.#a({method:e,params:t})}#o(e){if(this.#i)return;let t=e.trim();if(!t)return;let n;try{n=JSON.parse(t)}catch{n=null}if(!n||typeof n!=`object`||Array.isArray(n)){this.close(Error(`the tool printed something that isn't ACP on stdout: ${ze(t).slice(0,120)}`)),this.#r.protocolError(t);return}let r=n.id!==void 0&&n.id!==null;if(typeof n.method==`string`&&r)return void this.#s(n.id,n.method,n.params);if(typeof n.method==`string`)try{this.#r.notification(n.method,n.params)}catch{}else if(r&&(`result`in n||`error`in n)){let e=this.#t.get(n.id);if(!e)return;if(this.#t.delete(n.id),e.timer&&clearTimeout(e.timer),n.error){let t=n.error;e.reject(new $e(typeof t.code==`number`?t.code:-32603,typeof t.message==`string`?t.message:`error`,t.data))}else e.resolve(n.result)}}async#s(e,t,n){try{let r=await this.#r.request(t,n);this.#a({id:e,result:r??null})}catch(t){let n=t instanceof $e?t:new $e(-32603,t.message);this.#a({id:e,error:{code:n.code,message:n.message}})}}};const nt=/[$`\\\n\r]/,rt=/[;&|<>(){}[\]*?~]/,it=/[$`;&|<>\\*?~\n\r(){}[\]]/;function at(e){if(typeof e!=`string`||nt.test(e))return null;let t=[],n=``,r=!1,i=null;for(let a of e)if(i)a===i?i=null:n+=a;else if(a===`'`||a===`"`)i=a,r=!0;else if(/\s/.test(a))r&&t.push(n),n=``,r=!1;else if(rt.test(a))return null;else n+=a,r=!0;return i?null:(r&&t.push(n),t)}function ot(e){let t=at(e.trim());if(!t)throw Error(`give the command without shell features ($, ~, pipes, ; or backslashes); use a full path instead of ~`);let[n,...r]=t;if(!n)throw Error(`the command is empty`);return{bin:n,args:r}}function st(e){if(!e||typeof e!=`object`)return null;let t=e,n=t.command??t.cmd??t.commandLine,r=e=>Array.isArray(e)&&e.length>0&&e.every(e=>typeof e==`string`);return typeof n==`string`?r(t.args)?[n,...t.args]:n:r(n)?n:null}const ct=e=>/^(?:\/(?:usr\/)?bin\/)?(?:ba|z|da)?sh$/.test(e);function lt(e){let t;if(typeof e==`string`)t=at(e);else{if(!e.every(e=>typeof e==`string`))return null;if(e.length===3&&ct(e[0])&&/^-l?c$/.test(e[1]))return at(e[2]);t=e.some(e=>it.test(e))?null:e.slice()}return!t||t.length===0?null:t.length===3&&ct(t[0])&&/^-l?c$/.test(t[1])?at(t[2]):t}const ut=new Set([`status`,`diff`,`log`,`show`,`add`,`commit`,`switch`,`branch`]),dt=/^(?:-o|-F|-t|--output|--exec-path|--no-index|--file|--template|--git-dir|--work-tree|--namespace|--upload-pack|--receive-pack|--ext-diff|--pathspec-from-file|--config-env|--super-prefix)(?:=|$)/;function ft(e){let[t,n,...r]=e;if(t===`bitfolk-api`)return e.slice(1).some(e=>e.startsWith(`@`))?`it would upload a local file`:null;if(t===`aside`)return null;if(t===`git`){if(!n||!ut.has(n))return`that git command isn't on the safe list`;for(let e of r){if(dt.test(e))return`git ${e.split(`=`)[0]} isn't allowed in safe mode`;if(/^-[A-Za-z]*[Fot]/.test(e)&&!e.startsWith(`--`))return`git ${e} isn't allowed in safe mode`;if(e.startsWith(`/`)||/=\//.test(e)||/^-[A-Za-z]+\//.test(e)||/(?:^|[/=])\.\.(?:\/|$)/.test(e))return`git with a path outside its worktree isn't allowed in safe mode`}return null}return`only bitfolk-api, aside and read-mostly git run in safe mode`}const pt=new Set([`curl`,`wget`,`nc`,`ncat`,`netcat`,`ssh`,`scp`,`sftp`,`telnet`,`ftp`,`socat`,`rsync`,`http`,`https`,`xh`]),mt=new Set([`env`,`printenv`]);function ht(e,t){let n=(Array.isArray(e)?e.join(` `):e).replace(/['"\\]/g,``),r=[t,yt(t)].filter(e=>e&&e!==`/`);if(/\.bitfolk\b/i.test(n)||/bitfolk_/i.test(n)||r.some(e=>n.includes(e)))return`it touches the Bitfolk folder or its variables`;if(/\/proc\/\S*environ/.test(n))return`it reads a process environment`;if(/(?:^|[\s/=:,;&|()<>])\.\.(?:$|[\s/=:,;&|()<>])/.test(n))return`it climbs out of its worktree (..)`;let i=C(),a=i?n.replace(/\$\{HOME\}|\$HOME\b/g,i).replace(/(^|[\s=:,;&|(<>])~(?=\/|$|[\s;&|)<>])/g,`$1${i}`):n,o=r.map(e=>e.toLowerCase());for(let e of a.split(/[\s;&|()<>`{}=:,]+/)){if(!e.startsWith(`/`))continue;let t=e.search(/[*?[]/);if(t>=0){let n=e.slice(0,e.lastIndexOf(`/`,t)+1).toLowerCase();if(o.some(e=>(e+`/`).startsWith(n)))return`it could reach the Bitfolk folder`;continue}let n=yt(e.replace(/\/+$/,``)||`/`).toLowerCase();if(o.some(e=>e===n||e.startsWith(n.endsWith(`/`)?n:n+`/`)))return`it could reach the Bitfolk folder`}let s=n.split(/[\s;&|()<>`${}]+/).filter(Boolean).map(e=>e.split(`/`).pop()??e);return s.some(e=>pt.has(e))?`it uses a network tool`:s.some(e=>mt.has(e))||/(?:^|[;&|(]\s*)(?:set|export|declare|typeset)(?:\s+-p\b|\s*$|\s*[;&|)])/.test(n)||/\bcompgen\s+-[ev]/.test(n)?`it could print the environment`:null}function gt(e,t){let n={...e??{}};if(t&&typeof t==`object`)for(let[e,r]of Object.entries(t))r!=null&&(n[e]=r);return n}const _t=/^(?:paths?|files?|file_?paths?|notebook_?path|absolute_?path|dir_?path|dir|directory|folder|cwd|workdir|working_?directory|source|destination|target|old_?path|new_?path|target_?file|target_?directory)$/i;function vt(e){let t=[],n=(e,r)=>{if(!(!e||typeof e!=`object`||r>3)){if(Array.isArray(e))return e.forEach(e=>n(e,r+1));for(let[i,a]of Object.entries(e)){if(_t.test(i)){if(typeof a==`string`)t.push(a);else if(Array.isArray(a))for(let e of a)typeof e==`string`&&t.push(e)}a&&typeof a==`object`&&n(a,r+1)}}};n(e.rawInput,0);for(let n of Array.isArray(e.content)?e.content:[]){let e=n;e&&e.type===`diff`&&typeof e.path==`string`&&t.push(e.path)}return t}function yt(e){try{return se(e)}catch{let t=o(e);return t===e?e:c(yt(t),i(e))}}const bt=(e,t)=>e===t||e.startsWith(t.endsWith(d)?t:t+d),xt=new Set([`.claude`,`.opencode`,`.gemini`,`.cursor`,`.kilocode`,`.codex`,`.qwen`,`.cline`,`.kimi`]),St=new Set([`opencode.json`,`opencode.jsonc`]),Ct=new Set([`.husky`,`.githooks`,`.lefthook`,`.git-hooks`,`git-hooks`]),wt=/^(?:\.pre-commit-config\.ya?ml|\.pre-commit-hooks\.ya?ml|\.?lefthook(?:-local)?\.(?:ya?ml|json|toml)|\.overcommit\.ya?ml|\.lintstagedrc(?:\..+)?|lint-staged\.config\..+|\.simple-git-hooks(?:\..+)?|simple-git-hooks\..+)$/;function Tt(e){return e.normalize(`NFC`).replace(/[​-‏‪-‮⁠-]/g,``).toLowerCase()}function Et(e,t){if(typeof e!=`string`||!e||e.includes(`\0`))return`an empty path`;if(!s(e))return`a relative path`;if(e.split(/[\\/]/).includes(`..`))return`a path with ..`;let n=yt(t.cwd),r=yt(e);if(!bt(r,n))return bt(r,yt(t.home))?`a path in the Bitfolk folder`:`a path outside its worktree`;if(t.write){let e=l(n,r).split(d).filter(Boolean).map(Tt);if(e.includes(`.git`))return`git's own files`;if(e.some(e=>xt.has(e)||e.startsWith(`.goose`)||St.has(e)))return`an agent settings file`;if(e.some(e=>Ct.has(e)||wt.test(e)))return`a git hook setup`}return null}function Dt(e){let n;try{let r=t(`git`,[`-C`,e,`-c`,`core.fsmonitor=false`,`rev-parse`,`--git-path`,`hooks`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],timeout:5e3}).trim();if(!r||r===`/dev/null`)return!1;n=s(r)?r:c(e,r)}catch{return!1}try{return oe(n).some(e=>{if(e.endsWith(`.sample`))return!1;try{let t=le(c(n,e));return t.isFile()&&!!(t.mode&73)}catch{return!1}})}catch{return!1}}function Ot(e,t){if(typeof e!=`string`||!e)return`a file`;let n=Be(e,t);if(n!==e)return n;let r=C();return r&&r!==`/`&&(e===r||e.startsWith(r+d))?`~`+e.slice(r.length):e}function kt(e,t){let n=e.rawInput&&typeof e.rawInput==`object`?e.rawInput:{},r=typeof e.title==`string`&&e.title.trim()?e.title.trim():null,i=vt(e)[0]??e.locations?.find(e=>typeof e?.path==`string`)?.path,a=e=>i?`${e} ${Ot(i,t)}`:r?`${e} ${r.replace(RegExp(`^${e}\\s+`,`i`),``)}`:`${e} a file`,o=e=>typeof e==`string`&&e?e:null;switch(e.kind){case`execute`:{let e=st(n);return D(`Running ${e?Ve(e):r??`a command`}`)}case`edit`:return D(a(`Editing`));case`delete`:return D(a(`Deleting`));case`move`:return D(a(`Moving`));case`read`:return D(a(`Reading`));case`search`:return D(`Searching ${ze(o(n.pattern)??o(n.query)??r??``).slice(0,80)}`.trim());case`fetch`:return D(`Fetching ${o(n.url)??r??`a web page`}`);case`think`:return null;case`switch_mode`:return D(`Switching mode${r?`: ${r}`:``}`);default:return D(r?`Using ${r}`:`Using a tool`)}}const At=new Set([`read`,`search`,`edit`,`delete`,`move`]),jt=new Set([`edit`,`delete`,`move`]);function Mt(e){let{toolCall:t,permission:n,cwd:r,home:i}=e,a=Array.isArray(e.options)?e.options.filter(e=>e&&typeof e.optionId==`string`):[],o=kt(t,r)??(t.kind===`think`?`Thinking`:`Using a tool`),s=(e,t)=>{if(e){let n=a.find(e=>e.kind===`allow_once`);if(n)return{allow:e,reason:t,what:o,cancelTurn:!1,outcome:{outcome:{outcome:`selected`,optionId:n.optionId}}};t=`${t}, but the tool offered no allow-once choice`}let n=a.find(e=>e.kind===`reject_once`);return n?{allow:!1,reason:t,what:o,cancelTurn:!1,outcome:{outcome:{outcome:`selected`,optionId:n.optionId}}}:{allow:!1,reason:`${t}; no reject-once choice, so the turn stops`,what:o,cancelTurn:!0,outcome:{outcome:{outcome:`cancelled`}}}},c=t.kind;if(typeof c!=`string`||!c)return s(!1,`the tool didn't say what kind of call this is`);if(n===`bypass`)return s(!0,`bypass mode`);if(n!==`safe`&&n!==`auto`)return s(!1,`unknown permission mode`);if(c===`think`)return s(!0,`thinking`);let l=vt(t);for(let e of l){let t=Et(e,{cwd:r,home:i,write:jt.has(c)});if(t)return s(!1,`${t}: ${Ot(e,r)}`)}if(At.has(c))return l.length===0?s(!1,`no file path in the request`):s(!0,jt.has(c)?`a change inside its worktree`:`inside its worktree`);if(c===`execute`){let a=st(t.rawInput);if(!a)return s(!1,`the command isn't in a shape the runner can check`);if(n===`safe`){let t=lt(a);if(!t)return s(!1,`the command uses shell features (safe mode allows a plain command only)`);let n=ft(t);return n?s(!1,n):t[0]===`git`&&(t[1]===`commit`||t[1]===`switch`)&&(e.gitHooks??Dt(r))?s(!1,`this repo has git hooks, which can run anything; the runner commits the work when the turn ends`):s(!0,`on the safe list`)}let o=ht(a,i);return o?s(!1,o):s(!0,`auto mode`)}return c===`fetch`?n===`auto`?s(!0,`auto mode allows the web`):s(!1,`safe mode doesn't fetch from the web`):c===`switch_mode`?s(!1,`changing the agent's mode needs its owner`):s(!1,`${c===`other`?`tools of kind other (MCP and the like)`:`kind ${c}`} aren't allowed in ${n} mode`)}const Nt={opencode:{safe:`build`,auto:`build`,bypass:`build`},gemini:{safe:`default`,auto:`default`,bypass:`yolo`},cursor_agent:{safe:`agent`,auto:`agent`,bypass:`agent`}};function Pt(e){let t=[];for(let n of Array.isArray(e.options)?e.options:[]){let e=n;if(typeof e?.value==`string`&&t.push(e.value),Array.isArray(e?.options))for(let n of e.options)typeof n?.value==`string`&&t.push(n.value)}return t}const Ft={refusal:`the agent refused to go on (refusal)`,max_tokens:`the agent hit its output token limit (max_tokens)`,max_turn_requests:`the agent hit its limit of model requests for one turn (max_turn_requests)`};var It=class{#e;#t;#n=null;#r=!1;#i=[];#a=null;#o=null;#s=null;#c=new Map;#l=null;#u=null;#d=!1;#f=[];#p=0;#m=0;#h=!1;#g=!1;#_=!1;constructor(e){this.#e=e,this.#t=new tt(e.stdin,e.stdout,{request:(e,t)=>this.#w(e,t),notification:(e,t)=>this.#E(e,t),protocolError:t=>{e.log(`out`,t.length>Qe?`[a ${Math.round(t.length/1e3)} KB line that isn't ACP]`:t),e.kill()}})}get cancelReason(){return this.#a}#v(e){let t=JSON.stringify(e);this.#e.log(`acp`,t.length>Qe?JSON.stringify({note:`skipped a ${Math.round(t.length/1e3)} KB entry`,...`event`in e?{event:e.event}:{}}):t)}cancel(e){return this.#_?!1:this.#a?!0:(this.#a=e,this.#v({event:`cancel`,reason:e}),!this.#n||this.#t.closed?(this.#e.kill(),!0):(this.#t.notify(`session/cancel`,{sessionId:this.#n}),this.#s=setTimeout(()=>this.#e.kill(),this.#e.cancelGraceMs??1e4),this.#s.unref?.(),!0))}async run(){let e=this.#e,t=e.handshakeMs??3e4,n;try{let r=await this.#t.request(`initialize`,{protocolVersion:1,clientCapabilities:{},clientInfo:{name:`bitfolk`,version:e.clientVersion}},t);if(r?.protocolVersion!==1)throw Error(`${e.label} speaks ACP v${String(r?.protocolVersion??`?`)}; this runner speaks v1`);if(this.#r=!!r?.agentCapabilities?.sessionCapabilities?.close,this.#i=Array.isArray(r?.authMethods)?r.authMethods:[],this.#v({event:`initialize`,agent:r?.agentInfo??null,auth:this.#i.map(e=>e?.id),close:this.#r}),this.#a)throw Error(`stopped before the session started`);let i=await this.#t.request(`session/new`,{cwd:e.cwd,mcpServers:[]},t);if(typeof i?.sessionId!=`string`)throw Error(`${e.label} started no session`);if(this.#n=i.sessionId,e.tally.sessionId=i.sessionId,await this.#S(i),this.#a)throw Error(`stopped before the prompt`);e.log(`acp`,JSON.stringify({event:`prompt`,chars:e.packet.length}));let a=await this.#t.request(`session/prompt`,{sessionId:this.#n,prompt:[{type:`text`,text:e.packet}]});this.#O(),this.#A(a?.usage);let o=typeof a?.stopReason==`string`?a.stopReason:null;this.#v({event:`turn`,stopReason:o,usage:a?.usage??null}),n={ok:o===`end_turn`,stopReason:o,exited:!1,error:o===`end_turn`?null:this.#y(o)}}catch(e){this.#O(),n={ok:!1,stopReason:null,exited:!1,error:this.#b(e)},!(e instanceof $e)&&/exited|stopped reading/.test(e.message)&&(n.exited=!0),this.#v({event:`turn`,error:n.error})}return e.tally.summary=Ke(this.#u)??e.tally.summary,n.ok||(e.tally.isError=!0,e.tally.overBudget&&e.tally.error||(e.tally.error=n.error)),await this.#j(),n}#y(e){return e===`cancelled`?this.#a===`policy`?this.#o??`the turn was stopped`:this.#a===`budget`?`went over its $${this.#e.agent.maxUsdPerRun} budget`:this.#a===`owner`?`stopped by its owner`:this.#a===`timeout`?`stopped: out of time`:`the agent cancelled the turn`:(e&&Ft[e])??`the agent stopped (${e??`no reason given`})`}#b(e){if(this.#a===`policy`&&this.#o)return this.#o;if(e instanceof $e){if(e.code===-32e3)return this.#x();let t=e.data;return Ie(t&&typeof t==`object`&&t.details!==void 0?t.details:e.message)??e.message}return e.message}#x(){let e=this.#i.map(e=>e?.description??e?.name).filter(e=>typeof e==`string`&&!!e.trim());return e.length?`sign in to ${this.#e.label} in a terminal on this computer first: ${e.join(`; `)}`.slice(0,300):`sign in to ${this.#e.label} in a terminal on this computer first`}async#S(e){let t=this.#e,n=this.#n,r=t.agent.acp.agent,i=Nt[r]?.[t.agent.permission],a=Array.isArray(e?.configOptions)?e.configOptions.filter(e=>e&&typeof e.id==`string`):[];this.#v({event:`session`,sessionId:n,config:a.map(e=>({id:e.id,category:e.category??null,current:e.currentValue??null})),modes:e?.modes?{current:e.modes.currentModeId??null,available:(e.modes.availableModes??[]).map(e=>e?.id)}:null});let o=async(e,r)=>{let i=await this.#t.request(`session/set_config_option`,{sessionId:n,configId:e.id,value:r},t.handshakeMs??3e4);a=Array.isArray(i?.configOptions)?i.configOptions.filter(e=>e&&typeof e.id==`string`):a.map(t=>t.id===e.id?{...t,currentValue:r}:t)},s=e=>a.find(t=>t.category===e)??a.find(t=>t.id===e);if(a.length){let e=s(`mode`);if(i&&e&&e.currentValue!==i&&Pt(e).includes(i))try{await o(e,i),this.#v({event:`mode`,mode:i})}catch(e){this.#v({event:`mode`,mode:i,error:this.#b(e)})}let n=s(`model`);if(t.agent.model&&n&&n.currentValue!==t.agent.model)try{await o(n,t.agent.model)}catch(e){this.#v({event:`model`,wanted:t.agent.model,error:this.#b(e),using:s(`model`)?.currentValue??null})}else t.agent.model&&!n&&this.#v({event:`model`,wanted:t.agent.model,error:`${t.label} offers no model choice over ACP; it uses its own`})}else if(e?.modes&&Array.isArray(e.modes.availableModes)){let r=e.modes.availableModes.map(e=>e?.id);if(i&&e.modes.currentModeId!==i&&r.includes(i))try{await this.#t.request(`session/set_mode`,{sessionId:n,modeId:i},t.handshakeMs??3e4),this.#v({event:`mode`,mode:i})}catch(e){this.#v({event:`mode`,mode:i,error:this.#b(e)})}t.agent.model&&this.#v({event:`model`,wanted:t.agent.model,error:`${t.label} offers no model choice over ACP; it uses its own`})}if(this.#C(a),!a.some(e=>e.category===`model`||e.id===`model`)&&typeof e?.models?.currentModelId==`string`&&e.models.currentModelId&&(t.tally.model=e.models.currentModelId,t.agent.model&&t.agent.model!==e.models.currentModelId&&this.#v({event:`model`,wanted:t.agent.model,using:e.models.currentModelId,error:`${t.label} can't change its model over ACP`})),t.agent.permission===`safe`&&!Nt[r]){let e=`safe mode is enforced through ${t.label}'s permission requests; its own settings may allow more`;t.log(`acp`,JSON.stringify({event:`note`,note:e})),t.activity(D(e))}}#C(e){if(!Array.isArray(e))return;this.#f=e.filter(e=>e&&typeof e.id==`string`);let t=this.#f.find(e=>e.category===`model`)??this.#f.find(e=>e.id===`model`);typeof t?.currentValue==`string`&&t.currentValue&&(this.#e.tally.model=t.currentValue)}#w(e,t){if(e===`session/request_permission`)return this.#T(t);throw this.#v({event:`unsupported`,method:e}),et(e)}#T(e){if(this.#a)return{outcome:{outcome:`cancelled`}};let t=typeof e?.toolCall?.toolCallId==`string`?e.toolCall.toolCallId:null,n=gt(t?this.#c.get(t):void 0,e?.toolCall);t&&this.#c.set(t,n);let r=Mt({toolCall:n,options:e?.options??[],permission:this.#e.agent.permission,cwd:this.#e.cwd,home:this.#e.home});if(!r.allow&&n.kind===`execute`&&!st(n.rawInput)&&!this.#g){this.#g=!0;let e=`${this.#e.label} doesn't say which command it wants to run, so ${this.#e.agent.permission} mode can't allow shell commands; it can still read and edit files in its worktree`;this.#e.log(`acp`,JSON.stringify({event:`note`,note:e})),this.#e.activity(D(e))}let i=r.outcome.outcome.outcome===`selected`?r.outcome.outcome.optionId:null;return this.#v({event:`permission`,decision:r.allow?`allowed`:`refused`,what:r.what,kind:n.kind??null,reason:ze(r.reason),option:i}),this.#e.activity(D(`${r.allow?`Allowed`:`Refused`}: ${r.what}`)),r.cancelTurn&&(this.#o=`refused ${r.what.charAt(0).toLowerCase()}${r.what.slice(1)}, and ${this.#e.label} offered no way to refuse just that, so the turn was stopped`.slice(0,300),setImmediate(()=>this.cancel(`policy`))),r.outcome}#E(e,t){if(e!==`session/update`)return;let n=t?.update;if(n&&typeof n==`object`&&!(this.#n&&t.sessionId&&t.sessionId!==this.#n))switch(n.sessionUpdate){case`agent_message_chunk`:n.content?.type===`text`&&typeof n.content.text==`string`&&this.#D(n.content.text,typeof n.messageId==`string`?n.messageId:null);return;case`tool_call`:case`tool_call_update`:{let e=typeof n.toolCallId==`string`?n.toolCallId:null,t=e?this.#c.get(e):void 0;n.sessionUpdate!==`tool_call`&&t||(this.#d=!0,this.#l&&!this.#l.id&&this.#O());let r=gt(t,n);if(e&&this.#c.set(e,r),n.sessionUpdate===`tool_call`||!t){let e=kt(r,this.#e.cwd);e&&(this.#e.activity(e),this.#v({event:`tool`,kind:r.kind??null,what:e}))}return}case`usage_update`:return this.#k(n.cost);case`config_option_update`:return this.#C(n.configOptions);case`current_mode_update`:return this.#v({event:`mode`,mode:n.currentModeId??n.modeId??null});default:return}}#D(e,t){let n=this.#l;(!n||(t?n.id!==t:this.#d))&&(this.#O(),this.#l={id:t,text:``}),this.#d=!1,this.#l.text+=e}#O(){let e=this.#l;this.#l=null,e&&e.text.trim()&&(this.#u=e.text,this.#e.log(`acp`,JSON.stringify({event:`message`,text:e.text.slice(0,4e3)})),this.#e.activity(D(e.text)))}#k(e){if(!e||typeof e!=`object`||typeof e.amount!=`number`||!Number.isFinite(e.amount))return;let t=this.#e.tally;if(String(e.currency??``).toUpperCase()!==`USD`){this.#h||(this.#h=!0,this.#v({event:`cost`,note:`cost comes in ${String(e.currency)}, not USD: no spend is recorded and the budget cap is off`})),t.costMicros=null;return}e.amount<this.#m&&(this.#p+=this.#m),this.#m=e.amount;let n=this.#p+e.amount;t.costMicros=Math.round(n*1e6),n>=this.#e.agent.maxUsdPerRun&&!t.overBudget&&(t.overBudget=!0,t.error=`spent $${n.toFixed(2)}, over its $${this.#e.agent.maxUsdPerRun} budget`,this.#e.activity(D(`Stopping: ${t.error}`)),this.cancel(`budget`))}#A(e){if(!e||typeof e!=`object`)return;let t=e=>typeof e==`number`&&Number.isFinite(e)&&e>0?Math.round(e):0,n=t(e.inputTokens),r=t(e.outputTokens),i=t(e.thoughtTokens),a=t(e.cachedReadTokens)+t(e.cachedWriteTokens),o=t(e.totalTokens);if(!n&&!r)return;let s=!o||o===n+r+i+a,c=this.#e.tally;c.inputTokens=s?n+a:n,c.outputTokens=s||o===n+r+i?r+i:r}async#j(){this.#_=!0,this.#s&&clearTimeout(this.#s),this.#n&&this.#r&&!this.#t.closed&&await this.#t.request(`session/close`,{sessionId:this.#n},2e3).catch(()=>{}),this.#s&&clearTimeout(this.#s),this.#t.close(Error(`the turn is over`)),this.#t.end(),this.#e.kill()}};async function Lt(e,t={}){let r=n(e.bin,e.args,{cwd:t.cwd,env:{...t.env??process.env,NO_BROWSER:`1`},stdio:[`pipe`,`pipe`,`ignore`],detached:!0}),i=null;r.on(`error`,t=>{i=t.code===`ENOENT`?Error(`${e.bin} isn't installed or isn't on PATH`):t});let a=new tt(r.stdin,r.stdout,{request:e=>{throw et(e)},notification:()=>{},protocolError:()=>{}});try{let e=await a.request(`initialize`,{protocolVersion:1,clientCapabilities:{},clientInfo:{name:`bitfolk`,version:t.version??`0`}},t.timeoutMs??5e3);return{protocolVersion:e?.protocolVersion,agentInfo:e?.agentInfo&&typeof e.agentInfo==`object`?e.agentInfo:null,authMethods:Array.isArray(e?.authMethods)?e.authMethods:[]}}catch(e){throw i??e}finally{a.close(Error(`done`)),a.end();try{r.pid&&process.kill(-r.pid,`SIGKILL`)}catch{r.kill(`SIGKILL`)}}}const Rt=e(import.meta.url)(`../package.json`).version,zt=`https://bitfolk.ai`,Bt=[`queued`,`running`],Vt=e=>Bt.includes(e);var O=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}};function Ht(e,t){let n=AbortSignal.timeout(e);return t&&typeof AbortSignal.any==`function`?AbortSignal.any([t,n]):n}var Ut=class{base;#e;constructor(e,t){this.base=e,this.#e=t}async call(e,t,n={}){let r=typeof this.#e==`string`?this.#e:await this.#e(),i;try{i=await fetch(`${this.base.replace(/\/+$/,``)}${t}`,{method:e,headers:{authorization:`Bearer ${r}`,"user-agent":`bitfolk-cli/${Rt}`,...n.body===void 0?{}:{"content-type":`application/json`},...n.headers},body:n.body===void 0?void 0:JSON.stringify(n.body),signal:Ht(n.timeoutMs??2e4,n.signal)})}catch(e){throw new O(0,`network`,`can't reach ${this.base}: ${e.message}`)}return i}async json(e){let t=await e.json().catch(()=>null);if(!e.ok)throw new O(e.status,t?.error??`http_error`,t?.error??`HTTP ${e.status}`);return t}async wake(e,t,n,r=`/v1/wake`){let i=new URLSearchParams({wait:String(t)});e!==void 0&&i.set(`after`,e??``);let a=await this.call(`GET`,`${r}?${i}`,{timeoutMs:(t+20)*1e3,signal:n});return a.status===404||a.status===405?null:this.json(a)}async request(e,t,n){return this.json(await this.call(e,t,{body:n}))}async setup(){return this.json(await this.call(`GET`,`/v1/setup`))}async peek(e){let t=await this.call(`GET`,`/v1/peek`,{headers:e?{"if-none-match":`"${e}"`}:{}});return t.status===304?null:this.json(t)}async status(e){await this.json(await this.call(`POST`,`/v1/status`,{body:{activity:e}}))}async runStart(e){let t=await this.call(`POST`,`/v1/runs`,{body:e});return t.status===404||t.status===405?null:this.json(t)}async runFinish(e,t){await this.json(await this.call(`POST`,`/v1/runs/${e}`,{body:t}))}},Wt=class{#e;constructor(e,t){this.#e=new Ut(e,t)}me(){return this.#e.request(`GET`,`/v1/machine`)}peek(){return this.#e.request(`GET`,`/v1/machine/peek`)}wake(e,t,n){return this.#e.wake(e,t,n,`/v1/machine/wake`)}claim(e){return this.#e.request(`POST`,`/v1/machine/claim`,e)}setTools(e,t){return this.#e.request(`POST`,`/v1/machine/tools`,t===void 0?{runtimes:e}:{runtimes:e,primary:t??``})}report(e){return this.#e.request(`POST`,`/v1/machine/report`,e)}finish(e,t){return this.#e.request(`POST`,`/v1/machine/sessions/${e}`,t)}openApp(e){return this.#e.request(`POST`,`/v1/machine/apps`,e)}beatApp(e){return this.#e.request(`POST`,`/v1/machine/apps/${e}`)}stopApp(e){return this.#e.request(`DELETE`,`/v1/machine/apps/${e}`)}start(e){return this.#e.request(`POST`,`/v1/machine/sessions`,e)}sessions(e=15){return this.#e.request(`GET`,`/v1/machine/sessions?limit=${e}`)}session(e){return this.#e.request(`GET`,`/v1/machine/sessions/${encodeURIComponent(e)}`)}cancel(e){return this.#e.request(`DELETE`,`/v1/machine/sessions/${encodeURIComponent(e)}`)}goals(){return this.#e.request(`GET`,`/v1/machine/goals`)}chats(){return this.#e.request(`GET`,`/v1/machine/chats`)}chat(e){let t=new URLSearchParams;return e.goal&&t.set(`goal`,e.goal),e.after&&t.set(`after`,e.after),e.limit&&t.set(`limit`,String(e.limit)),this.#e.request(`GET`,`/v1/machine/chat?${t}`)}say(e){return this.#e.request(`POST`,`/v1/machine/chat`,e)}board(e){return this.#e.request(`GET`,`/v1/machine/board?goal=${encodeURIComponent(e)}`)}addTask(e){return this.#e.request(`POST`,`/v1/machine/board`,e)}agents(){return this.#e.request(`GET`,`/v1/machine/agents`)}approvals(e,t=30){return this.#e.request(`GET`,`/v1/machine/approvals?status=${e}&limit=${t}`)}decide(e){return this.#e.request(`POST`,`/v1/machine/approvals`,e)}async checkpoint(e,t){try{return(await this.#e.request(`POST`,`/v1/machine/sessions/${e}/checkpoint`,t))?.saved===!0}catch{return!1}}async progress(e,t){try{let n=await this.#e.request(`POST`,`/v1/machine/sessions/${e}/progress`,t);return{canceled:n?.canceled===!0,status:typeof n?.status==`string`?n.status:`running`}}catch(e){return{canceled:!1,status:e instanceof O&&(e.status===404||e.status===405)?`not_found`:`error`}}}};const Gt=[`claude_code`,`codex`,`opencode`,`hermes`,`command`],Kt=[`safe`,`auto`,`bypass`],qt={maxUsdPerRun:1,maxRunsPerHour:6,timeoutMin:45,permission:`auto`};function k(){return process.env.BITFOLK_HOME||c(C(),`.bitfolk`)}function Jt(){let e=k();return b(e)||x(e,{recursive:!0,mode:448}),e}function Yt(e,t){if(!b(e))return t;try{return JSON.parse(ie(e,`utf8`))}catch{throw Error(`${e} is not valid JSON. Fix or delete it.`)}}function Xt(e,t){Jt();let n=`${e}.${process.pid}.tmp`;ue(n,JSON.stringify(t,null,2)+`
7
+ `,{mode:384}),ce(n,e),_(e,384)}const Zt=()=>c(k(),`config.json`),Qt=()=>c(k(),`state.json`);function A(){let e=Yt(Zt(),{version:1,maxConcurrent:2,agents:[]});return e.agents=e.agents.map(e=>({...qt,...e})),e.machine&&={...qt,...e.machine},e}const $t=e=>Xt(Zt(),e),en=()=>Yt(Qt(),{agents:{}}),tn=e=>Xt(Qt(),e);function nn(e,t=[]){let n=e.toLowerCase().normalize(`NFKD`).replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,30)||`agent`,r=new Set(t),i=n;for(let e=2;r.has(i);e++)i=`${n}-${e}`;return i}function rn(e,t){let n=t.toLowerCase();return e.agents.find(e=>e.slug===n||e.name.toLowerCase()===n||e.id.startsWith(n))}function an(e,t){let n=t.workspace?.name??e.workspace,r=t.machine?.name||e.name;if(n===e.workspace&&r===e.name)return e;try{let t=A();return t.machine?.id===e.id?(t.machine={...t.machine,workspace:n,name:r},$t(t),t.machine):e}catch{return{...e,workspace:n,name:r}}}const on={coral:`#f25c3b`,coralDark:`#c8432a`,grass:`#6fae4b`,grassDark:`#4c8a35`,gold:`#f2c14e`,sky:`#d7ecf7`,ink:`#0e0f11`},sn={0:`#f0d27a`,1:`#d1a74c`,2:`#9c7433`,3:`#a9ab93`,4:`#7b7f6a`,8:`#22573a`,C:`#8a3c2a`,D:`#4b3326`,G:`#6fae4b`,H:`#4c8a35`,J:`#9bd36a`,L:`#fff3c4`,M:`#c99a3a`,O:`#337a4b`,P:`#7d4fc9`,Q:`#35692a`,R:`#c94f33`,V:`#cfc2a8`,W:`#e6dcc8`,Y:`#d79a22`,Z:`#9a9488`,c:`#b5523a`,d:`#5b3a29`,g:`#9fd3ea`,h:`#5fae6a`,j:`#c6ea8a`,k:`#f2c14e`,m:`#f4d58d`,o:`#32343a`,p:`#b06cff`,q:`#e8556d`,t:`#7a5236`,u:`#5b3a29`,w:`#fbf6ec`,y:`#f2c14e`,z:`#c9c2b4`},cn=[`#.....#..#.....##.......#..#....`,`#........#....#.........#..#....`,`####..#.####.####..###..#..#..#.`,`#...#.#..#....#...#...#.#..#.#..`,`#...#.#..#....#...#...#.#..##...`,`#...#.#..#....#...#...#.#..#.#..`,`####..#...##..#....###...#.#..#.`],j={cottage:[`..........oooooo.o33o.....`,`.......ooo001122oo33o.....`,`.....oo0000111122223o.....`,`....o0100111211222222o....`,`...o000001111111222222o...`,`...o000001111111222222o...`,`..o10010021121122222222o..`,`.o0000000111111112222222o.`,`.o0000000111111112222222o.`,`o121212121212121212121212o`,`.oddddddddddddddddddddddo.`,`.odwwdwwdwwuuuuwwdWWdWWdo.`,`.odwdwwwdwwttuuwwdWWWdWdo.`,`.oddwwwwdwwttuuwwdWWWWddo.`,`.odddddddddttuudddddddddo.`,`.odwLdLwdwwttukwwdWLdLWdo.`,`.odwdddwdwwttuuwwdWdddWdo.`,`.odwLdLwdwwttuuwwdWLdLWdo.`,`.odwqywpdwwttuuwwdyWqpWdo.`,`o444444444444444444444444o`],cabin:[`..o343o....oo...........`,`..o433o..ootuoo.........`,`..o33DooottDuuDoo.......`,`..o334otttttuuuuuoo.....`,`..o3DttDttDtuDuuDuuoo...`,`.ootttttttttuuuuuuuuuoo.`,`ottDttDttDttDuuDuuDuuDuo`,`omttttttttttttttttttttmo`,`oMuuuuuuuuuuuuuuuuuuuuMo`,`omttttttttttttttttttttmo`,`oMuuLLDLuuuuuuddDDugguMo`,`omttDDDDttttttddDDtggtmo`,`oMuuLLDLuuuuuuddDDuuuuMo`,`omttttttttttttddDDttttmo`,`oMuuuuuuuuuuuudkDDuuuuMo`,`omttttttttttttddDDttttmo`,`oMuuuuuuuuuuuuddDDuuuuMo`,`omttttttttttttddDDttttmo`,`oDDDDDDDDDDDDDDDDDDDDDDo`],roundhouse:[`..........ouuo..........`,`..........ouuo..........`,`.........o0112o.........`,`........o101222o........`,`.......o00111222o.......`,`......o0001111222o......`,`.....o100111212222o.....`,`.....o000011112222o.....`,`....o00001111122222o....`,`...o0010021121122222o...`,`..o000001111111222222o..`,`.o00000011111112222222o.`,`o2121212121212121212121o`,`.oo34333333433334Z44Zoo.`,`..o33334333dd343Z44Z4o..`,`..o43gL333ddDD3344Z44o..`,`..o33LL333ddDD334Z44Zo..`,`..o3333334ddDD33Z44Z4o..`,`..o3343333ddDk3344Z44o..`,`..o3333343ddDD344Z44Zo..`,`ooGJ433333ddDD33Z44ZGqoo`],barn:[`..........oooooo..........`,`........oottttttoo........`,`......oouuuuuDDDDDoo......`,`....oouuuuuuuDDDDDDDoo....`,`...ouuuuuuuwwwwDDDDDDDo...`,`..ouuuuuuuu1110DDDDDDDDo..`,`..ouuuuuuuu1211DDDDDDDDo..`,`.ouuuuuuuuu1111DDDDDDDDDo.`,`ouuuuuuuuuuuuDDDDDDDDDDDDo`,`uuuuuuuuuuuuuDDDDDDDDDDDDD`,`uuuuuuuuuuuuuDDDDDDDDDDDDD`,`oocCcCcCcCcCcCcCcCCRCRCCoo`,`.ocCcCcCcCcCcCcCcCCRCRCCo.`,`.ocCcCcCcwwwwwwwwCCRCRCCo.`,`.ocCgwgCcwwccwcwwCCgwgCCo.`,`.ocCwwwCcwwccwcwwCCwwwCCo.`,`.ocCgwgCcwcwcwwcwCCgwgCCo.`,`.ocCcCcCcwcwcwwcwCCRCRCCo.`,`.ocCcCcCcwccwwccwCCRCRCCo.`,`.ocCcCcCcwccwwccwCCRCRCCo.`,`oocCcCcCcwccwwccwCCRCRCCoo`,`11011111111111111111112111`],oak:[`.....oooo..........`,`....ojjjjoooooo....`,`...ojjjJJjjjjJJo...`,`..ojjjJJGjjjJJJo...`,`..ojJJJGjjJJJGGGo..`,`..oJGGGGJJJGGGGHo..`,`..ojGGHHjGGGHHHQo..`,`.ojJHHHQQGHHHHQGGo.`,`oJJJGGQjjJJJQQQGGGo`,`oJJGGGJJJJJGGGGGGHo`,`oGGGGJJGGGGGHGGHHQo`,`oQGHHHGGGGHHHHHHQQo`,`oQQHQQGGHHHQQQQQQQo`,`.oQQQQQHHQQQQQQQQo.`,`..ooooQQQQQQQoooo..`,`......oQQQQQo......`,`.......otuuo.......`,`.......ottuo.......`,`.......ottuo.......`,`.......otuuo.......`,`......ootuuoo......`,`.....outttuuuo.....`,`.....ooooooooo.....`],elm:[`........ojjjjo.....`,`....oooojjjjJJo....`,`...jjjjJjjJjGGo....`,`..ojjjJGJJGGGHjoo..`,`..ojjJJGJGGGHHJJJo.`,`..oJGGGGHGGjQJJGGo.`,`..oGGHHHQHJJJJGGGGo`,`..oJHHHQQJJJGGGGHHo`,`.ooJJJGGGJJGGHHHHQo`,`ojJJJGGjjJJGGHHJQQo`,`oJJGGGJJJGGGHJJJGo.`,`oGGGHHJGGGHHHGGGHHo`,`oGHHHQGGGHHHQGHHHQo`,`oQQQQQGHHQQQQQHQQQo`,`oQQQQQQQHQQQQQQQQQo`,`..ooooQQQQQQQQQQQo.`,`......ooQQQoo.ooo..`,`.......ottuo.......`,`.......ottuo.......`,`.......otuuo.......`,`......ootuuoo......`,`.....outttuuuo.....`,`.....ooooooooo.....`],pine:[`......oo......`,`.....oh8o.....`,`.....oh8o.....`,`.....hO8o.....`,`.....hO8o.....`,`....ohh88o....`,`....ohOO8o....`,`....ohOO8o....`,`...ohhh888o...`,`...ohhO888o...`,`..o88hOO888o..`,`...8hhOO88o...`,`..ohhOh8888...`,`..ohhhOO888o..`,`.o88hhOO8888o.`,`.oohhOOO888oo.`,`.ohhhOOO8888..`,`.ohhhOOO8888o.`,`o888888888888o`,`.ooooottooooo.`,`.....otto.....`,`.....ouuuo....`,`.....oooo.....`],bush:[`..oooooo..`,`.oJGGGGHo.`,`oJGpGGGqHo`,`oGGGGqGHHo`,`.ooooooooo`],sunflower:[`..oyyo..`,`.oyYYyo.`,`oyYddYyo`,`oyYddYyo`,`.oyYYyo.`,`..oyyo..`,`...oG.o.`,`.o.oGoGo`,`.oGoGo..`,`...oG...`],tulip:[`.o.o.o..`,`opopopo.`,`oPpPpPo.`,`oPPpPPo.`,`.oPPPo..`,`..ooo...`,`...oG.o.`,`.o.oGoGo`,`.oGoGo..`,`...oG...`]},ln={claude_code:{palette:{A:`#3a302c`,B:`#5f3b2c`,C:`#503428`,D:`#48332a`,E:`#c8c8d0`,F:`#d3b196`,G:`#f8d0b0`,H:`#3a3640`,I:`#36363e`,J:`#373337`,K:`#9a5a48`,L:`#d97757`,M:`#bebebb`,N:`#fff4ec`,O:`#f8f8f8`,P:`#9fd3ea`,Q:`#44362e`,R:`#e8c040`,S:`#3a4058`,T:`#35394b`,U:`#f0f0f0`,V:`#b0b0bc`},down:[`.......AAAA........`,`....AAABBBBAAA.....`,`...ABBBBBBBBCDA....`,`..ABBBBBBCCBCCCA...`,`.ABBBBBCCCCCDCCCA..`,`.ABBBCDCCCCCCCCDA..`,`ABBBCCCCCCCCCCCDDA.`,`ABCCCBBCCCCDCDDDDA.`,`ACBDDDDDDDDDDDDDDA.`,`ACEEFFDGGGGGDFFEEA.`,`.AEEFGHHGGGHHGFEE..`,`.AEEHHIIHHHIIHHEE..`,`.ACJFHGGHGHGGHFDA..`,`.ADDJEGGGFGGGFDDA..`,`..ADDDFGKKKGFDDA...`,`.....JLJLLLJLJJJJJJ`,`...JJLLMNONMLMJOPPJ`,`..JLLMLNLOLNLMJPPPJ`,`.JGGJMLLNONLLMJJJJJ`,`.JFGJLLLLOLLLLEEEEE`,`..JJQQQQQRQQQQJJJJJ`,`....JSSTJ.JTSSJ....`,`....JUUVJ.JVUUJ....`,`.....JJJ...JJJ.....`],walk:[[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEEDDDDDDA.`,`.JHHHGGFFEEDDDDDDA.`,`JGGIHHHHFEEDDDDDDA.`,`JGIGHGGFJDDDDDDDDA.`,`.JKKGGEJFDDDDDDDA..`,`..JJGGFFADDDDDDA...`,`..JJJJJLLJLLJ......`,`..JPPOJLMLLLJ......`,`..JPPPJMLLLLJ......`,`..JJJJJMLLLLJ......`,`..EEEEELLLLLJ......`,`..JJJJJQQQQQJ......`,`.......JSSTJ.......`,`......JUUUVJ.......`,`.......JJJJ........`],[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEEDDDDDDA.`,`.JHHHGGFFEEDDDDDDA.`,`JGGIHHHHFEEDDDDDDA.`,`JGIGHGGFJDDDDDDDDA.`,`.JKKGGEJFDDDDDDDA..`,`..JJGGFFADDDDDDA...`,`..JJJJJLLJLLJ......`,`..JPPOJLMLLLJ......`,`..JPPPJMLLLLJ......`,`..JJJJJMLLLLJ......`,`..EEEEELLLLLJ......`,`..JJJJJQQQQQJ......`,`.....JSTJ.JSTJ.....`,`....JUUVJ.JUUVJ....`,`.....JJJ...JJJ.....`],[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEEDDDDDDA.`,`.JHHHGGFFEEDDDDDDA.`,`JGGIHHHHFEEDDDDDDA.`,`JGIGHGGFJDDDDDDDDA.`,`.JKKGGEJFDDDDDDDA..`,`..JJGGFFADDDDDDA...`,`..JJJJJLLJLLJ......`,`..JPPOJLMLLLJ......`,`..JPPPJMLLLLJ......`,`..JJJJJMLLLLJ......`,`..EEEEELLLLLJ......`,`..JJJJJQQQQQJ......`,`......JSSTJ........`,`......JUUUVJ.......`,`.......JJJJ........`]]},codex:{palette:{A:`#313132`,B:`#38353a`,C:`#353336`,D:`#363438`,E:`#b88869`,F:`#d8a07c`,G:`#373337`,H:`#3a3640`,I:`#36363e`,J:`#f0f0f8`,K:`#a0505a`,L:`#10a37f`,M:`#bebebb`,N:`#eafff7`,O:`#f8f8f8`,P:`#f4f4f0`,Q:`#44362e`,R:`#e8c040`,S:`#35373f`,T:`#34353b`,U:`#484848`,V:`#f0f0f0`,W:`#977057`},down:[`....AA.AAAAA.A.....`,`...ABBABBBCBADA....`,`..AABBBBBBDDDDDA...`,`.ABBBBBBDDDBDDDA...`,`.ABBCBDDCDDDCDDDA..`,`.ABBDDDDDDDDDDDCA..`,`.ADDDBDDDBDDDCCCA..`,`.ACCCCCCCCCCCCCCA..`,`..AAECFCFCFCFCEA...`,`...GEHHHHFHHHHEG...`,`...GHHIJHHHJIHHG...`,`...GEHIIHFHIIHEG...`,`....GHHHHEHHHHG....`,`.....GEFFKFFEG.....`,`.....GLGLLLGLG.....`,`...GGLLMNONMLMGGGGG`,`..GLLMLNLOLNLMGLLPG`,`.GFFGMLNNONNLMGLLPG`,`.GEFGLLLLOLLLLGLLPG`,`..GGQQQQQRQQQQGGGGG`,`....GSSTG.GTSSG....`,`....GUUVG.GVUUG....`,`.....GGG...GGG.....`],walk:[[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`......GLLGLLG......`,`..GGGGGLMLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGLLLLLG......`,`..GGGGGQQQQQG......`,`.......GSSTG.......`,`......GUUUVG.......`,`.......GGGG........`],[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`......GLLGLLG......`,`..GGGGGLMLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGLLLLLG......`,`..GGGGGQQQQQG......`,`.....GSTG.GSTG.....`,`....GUUVG.GUUVG....`,`.....GGG...GGG.....`],[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`......GLLGLLG......`,`..GGGGGLMLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGMLLLLG......`,`..GPLLGLLLLLG......`,`..GGGGGQQQQQG......`,`......GSSTG........`,`......GUUUVG.......`,`.......GGGG........`]]},hermes:{palette:{A:`#443329`,B:`#8f5c3d`,C:`#704830`,D:`#533524`,E:`#f8f8f8`,F:`#d5beaa`,G:`#fbe0c8`,H:`#36363e`,I:`#373337`,J:`#a0605a`,K:`#f4f1e8`,L:`#bebebb`,M:`#c9a227`,N:`#f4f4f0`,O:`#44362e`,P:`#e8c040`,Q:`#f0ece2`,R:`#b4b1aa`,S:`#f0f0f0`,T:`#b0b0bc`,U:`#b09d8c`},down:[`.......AAAA........`,`....AAABBBBAAA.....`,`...ABBBBBBBCCDA....`,`..ABBBBBBCCBCCCA...`,`EABBBBBCCCCBCCCCA.E`,`EEEBBBDCDCCCCCCDEEE`,`AEEECCCCCCCCCCDEEE.`,`ABCCCCCCCCCCCDDDDA.`,`ACBDDDDDDDDDDDDDDA.`,`ACCDCCCCCCCDDFDDDA.`,`.ACCDDDDGGGGGGFDA..`,`..ACFGHHGGGHHGFDA..`,`..ACFHGGHGHGGHFA...`,`...AIFGGGFGGGFI....`,`.....IFGGJGGFI.....`,`.....IKIKKKIKI.....`,`...IIKKLMMMLKLII...`,`..IKKLKMMKMMKLIIIII`,`.IGGILKMMMMMKLININI`,`.IFGIKKLKKKKLLINNNI`,`..IIOOOOOPOOOOIIIII`,`....IQQRI.IRQQI....`,`....ISSTI.ITSSI....`,`.....III...III.....`],walk:[[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA.E`,`.ABBBBCCCCDCDCCCEEE`,`.ABBCCCCCCCDCCDEEE.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`.....IKKLKKKI......`,`..IIIIILKKKKI......`,`..ININILKKKKI......`,`..INNNIKKKKLI......`,`..IIIIIOOOOOI......`,`.......IQQRI.......`,`......ISSSTI.......`,`.......IIII........`],[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA.E`,`.ABBBBCCCCDCDCCCEEE`,`.ABBCCCCCCCDCCDEEE.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`.....IKKLKKKI......`,`..IIIIILKKKKI......`,`..ININILKKKKI......`,`..INNNIKKKKLI......`,`..IIIIIOOOOOI......`,`.....IQRI.IQRI.....`,`....ISSTI.ISSTI....`,`.....III...III.....`],[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA.E`,`.ABBBBCCCCDCDCCCEEE`,`.ABBCCCCCCCDCCDEEE.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`.....IKKLKKKI......`,`..IIIIILKKKKI......`,`..ININILKKKKI......`,`..INNNIKKKKLI......`,`..IIIIIOOOOOI......`,`......IQQRI........`,`......ISSSTI.......`,`.......IIII........`]]},cursor:{palette:{A:`#5b3918`,B:`#ffae48`,C:`#d88838`,D:`#a06529`,E:`#ccaa88`,F:`#f0c8a0`,G:`#3a3640`,H:`#f0f0f8`,I:`#313745`,J:`#373337`,K:`#9a5a48`,L:`#353539`,M:`#ffffff`,N:`#bebebb`,O:`#f8f8f8`,P:`#44362e`,Q:`#e8c040`,R:`#383840`,S:`#36363c`,T:`#484848`,U:`#f0f0f0`,V:`#a88c70`},down:[`......AAAAAA.......`,`....AABBBBBBAA.....`,`...ABBBBBBCCCDA....`,`..ABBBBBBCCBCCCA...`,`.ABBBBBCCCCCDCCCA..`,`ABBBBCCCCCCCCCCDCA.`,`ABBDDCCCCCCCCCCDDA.`,`ACCCCBCCCCCDCDDDDA.`,`ACCDDDDDDDDDDDDDDA.`,`ACCCEDFDFDFDFDEDDA.`,`.ACCEGGGGFGGGGEDA..`,`..ACGGHIGGGHIGGDA..`,`..ACEEIIEFEIIEEA...`,`...AJEFFFEFFFEJ....`,`.....JEFFKFFEJJJ...`,`.....JLJLLLJLJJMJ..`,`...JJLLNLOLNLNJMMJ.`,`..JLLNLMMOLLLNJMMMJ`,`.JFFJNLMMOLLLNJMMJJ`,`.JEFJLLMMOLLLLJJMJ.`,`..JJPPPPPQPPPPPJJJ.`,`....JRRSJ.JSRRJ....`,`....JTTUJ.JUTTJ....`,`.....JJJ...JJJ.....`],walk:[[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFIIGFFEFEVDDDDA...`,`.JFKFFFEEEDDAAA....`,`..JJFFEEJJAA.......`,`.J....JLLJLLJ......`,`.JJ..JLLNLLLJ......`,`.JMJJJLNLLLLJ......`,`.JMMJFLNLLLLJ......`,`.JMMMJLLLLLLJ......`,`.JMMJJJPPPPPJ......`,`.JJMJ..JRRSJ.......`,`...JJ.JTTTUJ.......`,`.......JJJJ........`],[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFIIGFFEFEVDDDDA...`,`.JFKFFFEEEDDAAA....`,`..JJFFEEJJAA.......`,`.J....JLLJLLJ......`,`.JJ..JLLNLLLJ......`,`.JMJJJLNLLLLJ......`,`.JMMJFLNLLLLJ......`,`.JMMMJLLLLLLJ......`,`.JMMJJJPPPPPJ......`,`.JJMJJRSJ.JRSJ.....`,`...JJTTUJ.JTTUJ....`,`.....JJJ...JJJ.....`],[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFIIGFFEFEVDDDDA...`,`.JFKFFFEEEDDAAA....`,`..JJFFEEJJAA.......`,`.J....JLLJLLJ......`,`.JJ..JLLNLLLJ......`,`.JMJJJLNLLLLJ......`,`.JMMJFLNLLLLJ......`,`.JMMMJLLLLLLJ......`,`.JMMJJJPPPPPJ......`,`.JJMJ.JRRSJ........`,`...JJ.JTTTUJ.......`,`.......JJJJ........`]]},gemini_cli:{palette:{A:`#343132`,B:`#b9c8ff`,C:`#40363b`,D:`#3d3539`,E:`#393336`,F:`#a77553`,G:`#c48a62`,H:`#373337`,I:`#f2c14e`,J:`#36363e`,K:`#f8f8f8`,L:`#7a4232`,M:`#6c8cf5`,N:`#bebebb`,O:`#ffffff`,P:`#44362e`,Q:`#e8c040`,R:`#4a6eb0`,S:`#385384`,T:`#c03850`},down:[`.AAA...BBBBB...AAA.`,`ACCCABBAAAAABBADDDA`,`CCCCCACBBBBBAADCDDE`,`CCCCCCCCCCDDDEDDDED`,`ACCCCCCCDDDCDDDDDDA`,`.ACCCCCDDDDDEDDDEA.`,`ACCCCCDDDDDDDDDDEA.`,`ACCDDDEDDDDDDEEEEA.`,`ADDEEEEEEEEEEEEEEA.`,`ADDDFFEGGEGGEFFEHA.`,`.AEDFGGGGGGGGGFHIH.`,`.ADDFGJJGGGJJGHIKIH`,`..ADFJGGJGJGGJFHIH.`,`...AHFGGGFGGGFH.H..`,`.....HFGLLLGFH..H..`,`.....HMHMMMHMH..H..`,`...HHMMNMMMNMNHHH..`,`..HMMNMMOOOMMNMNH..`,`.HGGHNMMMNMMNNHGFH.`,`.HFGHMMMMMMMMMHGFH.`,`..HHPPPPPQPPPPPHH..`,`....HRRSH.HSRRH....`,`....HTTKH.HKTTH....`,`.....HHH...HHH.....`],walk:[[`........BBBB.AAA...`,`......BBAAAABBCDA..`,`....AACCBBBBCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.HGGGGGFFEEEEEEEEA.`,`HGGJGGGFFEEEEEEEA..`,`HGJGJGGFGEEEEEEA...`,`.HLLGGGFFEEEEEA....`,`HIHHGGFFAEEAAA.....`,`IKI...HMMHMMH......`,`HIH..HMMNMMMH......`,`..HHHHMNMMMMH......`,`...HGGMNMMMNH......`,`....HHMMMMMMH......`,`......HPPPPPH......`,`.......HRRSH.......`,`......HTTTKH.......`,`.......HHHH........`],[`........BBBB.AAA...`,`......BBAAAABBCDA..`,`....AACCBBBBCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.HGGGGGFFEEEEEEEEA.`,`HGGJGGGFFEEEEEEEA..`,`HGJGJGGFGEEEEEEA...`,`.HLLGGGFFEEEEEA....`,`HIHHGGFFAEEAAA.....`,`IKI...HMMHMMH......`,`HIH..HMMNMMMH......`,`..HHHHMNMMMMH......`,`...HGGMNMMMNH......`,`....HHMMMMMMH......`,`......HPPPPPH......`,`.....HRSH.HRSH.....`,`....HTTKH.HTTKH....`,`.....HHH...HHH.....`],[`........BBBB.AAA...`,`......BBAAAABBCDA..`,`....AACCBBBBCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.HGGGGGFFEEEEEEEEA.`,`HGGJGGGFFEEEEEEEA..`,`HGJGJGGFGEEEEEEA...`,`.HLLGGGFFEEEEEA....`,`HIHHGGFFAEEAAA.....`,`IKI...HMMHMMH......`,`HIH..HMMNMMMH......`,`..HHHHMNMMMMH......`,`...HGGMNMMMNH......`,`....HHMMMMMMH......`,`......HPPPPPH......`,`......HRRSH........`,`......HTTTKH.......`,`.......HHHH........`]]}},un={claude_code:`#d97757`,codex:`#10a37f`,hermes:`#c9a227`,cursor:`#1b1b1f`,gemini_cli:`#6c8cf5`},dn={palette:{A:`#3a302c`,B:`#5f3b2c`,C:`#503428`,D:`#48332a`,E:`#9c6846`,F:`#b87a52`,G:`#36363e`,H:`#373337`,I:`#6e3e30`,J:`#30395a`,K:`#f8f8f8`,L:`#d8432e`,M:`#2f3653`,N:`#9aa0a6`,O:`#32374b`,P:`#313545`,Q:`#343438`,R:`#4a4a56`,S:`#815539`},down:[`........AA.........`,`.....AAABBAAA......`,`...AABBBBBBBCAA....`,`..ABBBBBBCCBCCCA...`,`.ABBBBBCCCCCDCCCA..`,`.ABBBCCCCCCCCCCCA..`,`ABBDDDCCCCCCCDDDDA.`,`ACCDDDDDDDDDDDDDDA.`,`.ACCEDFDCCCCCCCDA..`,`.ADCEFFFFFFDDDDDA..`,`..ACEFEEFFFEEFEDA..`,`..ACEFGGFFFGGFEA...`,`...AHEFDDDDDFEH....`,`.....HEFFIFFEH.....`,`.....HJHKLKHJH...H.`,`...HHJJMJLJMJMHH.KH`,`..HJJMMJJLJJNMJMHKK`,`.HFFHMMJJLJJMMHFEHK`,`.HEFHJMMJLJJMMHFEHH`,`..HHOOOOOOOOOOOHHH.`,`....HOOPH.HPOOH....`,`....HQQRH.HRQQH....`,`.....HHH...HHH.....`],walk:[[`........AAA........`,`.....AAABBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBCDCCDCA...`,`..ABBBBBCCDCCCCCA..`,`.ABBBBCDCCCCCCCDCA.`,`.ABBDDDCCCCCCCCDDA.`,`.ADDDDDDDCCCCDDDDA.`,`..ADFFDEECCDDDDDDA.`,`.HFFFFFEEDDDDDDDDA.`,`HFEEFFFEEEFDDDDDA..`,`HFDDDFFEFESDDDDA...`,`.HFIFFFEEEDDAAA....`,`..HHFFEEHHAA.......`,`...H..HJJHKKH......`,`...KHHJJMJJJH......`,`...KKFJMJJJJH......`,`...KKFFEHJJMH......`,`...KHHEHJJJMH......`,`...H..HOOOOOH......`,`.......HOOPH.......`,`......HQQQRH.......`,`.......HHHH........`],[`........AAA........`,`.....AAABBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBCDCCDCA...`,`..ABBBBBCCDCCCCCA..`,`.ABBBBCDCCCCCCCDCA.`,`.ABBDDDCCCCCCCCDDA.`,`.ADDDDDDDCCCCDDDDA.`,`..ADFFDEECCDDDDDDA.`,`.HFFFFFEEDDDDDDDDA.`,`HFEEFFFEEEFDDDDDA..`,`HFDDDFFEFESDDDDA...`,`.HFIFFFEEEDDAAA....`,`..HHFFEEHHAA.......`,`...H..HJJHKKH......`,`...KHHJJMJJJH......`,`...KKFJMJJJJH......`,`...KKFFEHJJMH......`,`...KHHEHJJJMH......`,`...H..HOOOOOH......`,`.....HOPH.HOPH.....`,`....HQQRH.HQQRH....`,`.....HHH...HHH.....`],[`........AAA........`,`.....AAABBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBCDCCDCA...`,`..ABBBBBCCDCCCCCA..`,`.ABBBBCDCCCCCCCDCA.`,`.ABBDDDCCCCCCCCDDA.`,`.ADDDDDDDCCCCDDDDA.`,`..ADFFDEECCDDDDDDA.`,`.HFFFFFEEDDDDDDDDA.`,`HFEEFFFEEEFDDDDDA..`,`HFDDDFFEFESDDDDA...`,`.HFIFFFEEEDDAAA....`,`..HHFFEEHHAA.......`,`...H..HJJHKKH......`,`...KHHJJMJJJH......`,`...KKFJMJJJJH......`,`...KKFFEHJJMH......`,`...KHHEHJJJMH......`,`...H..HOOOOOH......`,`......HOOPH........`,`......HQQQRH.......`,`.......HHHH........`]]},fn=[{down:[`....oo.ooooo.o....`,`...ohhohhhdhoHo...`,`..oohhhhhhHHHHHo..`,`.ohhhhhhHHHhHHHo..`,`.ohhdhHHdHHHdHHHo.`,`.ohhHHHHHHHHHHHdo.`,`.oHHHhHHHhHHHdddo.`,`.oddddddddddddddo.`,`..ooSdsdsdsdsdSo..`,`...kSsssssssssSk..`,`...kSseEsssEesSk..`,`...kSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....o.ooooo.o....`,`....ohohhhdhoHo...`,`...ohhhhhhHHHHHo..`,`..ohhhhhHHHhHHHoo.`,`.ohhdhHHdHHHdHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHhHHHhHHHddddo`,`.odddddddHdddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....o.ooooo.o....`,`....ohohhhdhoHo...`,`...ohhhhhhHHHHHo..`,`..ohhhhhHHHhHHHoo.`,`.ohhdhHHdHHHdHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHhHHHhHHHddddo`,`.odddddddHdddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....o.ooooo.o....`,`....ohohhhdhoHo...`,`...ohhhhhhHHHHHo..`,`..ohhhhhHHHhHHHoo.`,`.ohhdhHHdHHHdHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHhHHHhHHHddddo`,`.odddddddHdddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`...oooohhhhhho.....`,`..ohhhhhhhhhHooo...`,`.oohhhhhhhHHHdHHo..`,`ohhhhhhhHHHhHHHHo..`,`ohhhhhHHHHHHdHHHdo.`,`ohhhhHHHHHHHHHHdddo`,`hhhdddHHHHHHHHHdddo`,`hHHHhHHHHHHHHddddo.`,`HhHdddddddddddddddo`,`oHHHSdssdsdssdSdddo`,`odHHSsssssssssSddo.`,`.ooHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHdHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`oddddddddHHdddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsdddddo..`,`kseesssSsSDddddo...`,`.ksmsssSSSddooo....`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHdHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`oddddddddHHdddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsdddddo..`,`kseesssSsSDddddo...`,`.ksmsssSSSddooo....`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHdHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`oddddddddHHdddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsdddddo..`,`kseesssSsSDddddo...`,`.ksmsssSSSddooo....`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`.....oooooooo.....`,`....ohhhhhhhHo....`,`...ohhhhhhHHHdo...`,`..ohhhhhHHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`ohhhhHHHHHHHHHHddo`,`ohhdddHHHHHHHdHddo`,`oHHXXHHHHHHHHddddo`,`oHHXdddddddddddddo`,`oHHHSdssdsdssdSddo`,`oHHHSsssssssssSddo`,`oHHHSseEsssEesSddo`,`oHHHSseessseesSddo`,`.odddSsssSsssSddo.`,`..odddSssmssSddo..`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`......ooooooo.....`,`....oohhhhhhHoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhhHdHHdHHHHdHo`,`.ohdddHHHHHHHHHddo`,`.oHHHhHHHHHHHXXddo`,`.odddddddHHddXdddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`......ooooooo.....`,`....oohhhhhhHoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhhHdHHdHHHHdHo`,`.ohdddHHHHHHHHHddo`,`.oHHHhHHHHHHHXXddo`,`.odddddddHHddXdddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`......ooooooo.....`,`....oohhhhhhHoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhhHdHHdHHHHdHo`,`.ohdddHHHHHHHHHddo`,`.oHHHhHHHHHHHXXddo`,`.odddddddHHddXdddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......oooo.......`,`....ooohhhhooo....`,`...ohhhhhhhHHdo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHhHHHHo.`,`.ohhhhdHdHHHHHHdo.`,`ohhhHHHHHHHHHHdddo`,`ohHHHHHHHHHHHddddo`,`oHhddddddddddddddo`,`oHHdHHHHHHHddSdddo`,`.oHHddddssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......oooo.......`,`.....oohhhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHHHHHdHHdHdo`,`.oHHHHHHHHHHdHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......oooo.......`,`.....oohhhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHHHHHdHHdHdo`,`.oHHHHHHHHHHdHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......oooo.......`,`.....oohhhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHHHHHdHHdHdo`,`.oHHHHHHHHHHdHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`......ohhhho......`,`.....oohhhhoo.....`,`....ohhhhhhhHo....`,`...ohhhhhhHHHdo...`,`..ohhhhhXXXhHHHo..`,`.ohhhhHHdHHHdHHHo.`,`ohhhHHHdHHHdHHHHdo`,`ohHHHHHHHHHHHHdddo`,`oHHddddddddddddddo`,`oHHdSdssdsdssdSddo`,`.odHSsssssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........ohhhho....`,`......ooohhhho....`,`....oohhhhhhHoo...`,`...ohhhhhhdHHHHo..`,`..ohhhhhhhXXXdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSodoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........ohhhho....`,`......ooohhhho....`,`....oohhhhhhHoo...`,`...ohhhhhhdHHHHo..`,`..ohhhhhhhXXXdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSodoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........ohhhho....`,`......ooohhhho....`,`....oohhhhhhHoo...`,`...ohhhhhhdHHHHo..`,`..ohhhhhhhXXXdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHHHHHHHHHHddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSodoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`........oo........`,`.....ooohhooo.....`,`...oohhhhhhhHoo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`.ohhhHHHHHHHHHHHo.`,`ohhdddHHHHHHHddddo`,`oHHddddddddddddddo`,`.oHHSdsdHHHHHHHdo.`,`.odHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........ooo.......`,`.....ooohhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhHdHHdHo..`,`..ohhhhhHHdHHHHHo.`,`.ohhhhHdHHHHHHHdHo`,`.ohhdddHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........ooo.......`,`.....ooohhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhHdHHdHo..`,`..ohhhhhHHdHHHHHo.`,`.ohhhhHdHHHHHHHdHo`,`.ohhdddHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........ooo.......`,`.....ooohhhooo....`,`....ohhhhhhHHHo...`,`...ohhhhhHdHHdHo..`,`..ohhhhhHHdHHHHHo.`,`.ohhhhHdHHHHHHHdHo`,`.ohhdddHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......oooo.......`,`....ooohhhhooo....`,`...ohhhhhhhhHdo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`.ohhhHdHHHHHHHHdo.`,`ohhhHHHHHHHHHHHddo`,`ohHHHhhHHHHdHddddo`,`oHhddddddddddddddo`,`oHHdSSdsssssdSSddo`,`.oHHSsssssssssSdo.`,`.oHHSseEsssEesSdo.`,`.oHHSseessseesSdo.`,`.odddSsssSsssSddo.`,`..odddSssmssSddo..`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......ooooo......`,`.....oohhhhhoo....`,`...oohhhhhhHHHo...`,`..ohhhhhhHdHHdHo..`,`..ohhhhhdHHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......ooooo......`,`.....oohhhhhoo....`,`...oohhhhhhHHHo...`,`..ohhhhhhHdHHdHo..`,`..ohhhhhdHHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......ooooo......`,`.....oohhhhhoo....`,`...oohhhhhhHHHo...`,`..ohhhhhhHdHHdHo..`,`..ohhhhhdHHHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHddddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......kkkk.......`,`.....kknnnnkk.....`,`....knnnnssssk....`,`...knnnnssssssk...`,`..knnnsssssssssk..`,`.knnssssssssssSSk.`,`.ohHHsssssssSSddo.`,`.oHHHssssssSSSddo.`,`.oHddssssSSSSSddo.`,`..oHSSsssssssSSo..`,`..oHSseEsssEesSk..`,`...oSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......kkkkk......`,`.....kknnnnnkk....`,`....knnnnnssssk...`,`...knnnnsssssssk..`,`..knnnssssssssssk.`,`..knnsssssssssSSk.`,`..ksssssssssHHddo.`,`..kssssssssSddddo.`,`..kssssssSSSddddo.`,`.kodssdSSdddddddo.`,`kseEsssSSddddddo..`,`kseesssSsdddddo...`,`.ksmsssSSddddo....`,`..kkssSSkoooo.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......kkkkk......`,`.....kknnnnnkk....`,`....knnnnnssssk...`,`...knnnnsssssssk..`,`..knnnssssssssssk.`,`..knnsssssssssSSk.`,`..ksssssssssHHddo.`,`..kssssssssSddddo.`,`..kssssssSSSddddo.`,`.kodssdSSdddddddo.`,`kseEsssSSddddddo..`,`kseesssSsdddddo...`,`.ksmsssSSddddo....`,`..kkssSSkoooo.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......kkkkk......`,`.....kknnnnnkk....`,`....knnnnnssssk...`,`...knnnnsssssssk..`,`..knnnssssssssssk.`,`..knnsssssssssSSk.`,`..ksssssssssHHddo.`,`..kssssssssSddddo.`,`..kssssssSSSddddo.`,`.kodssdSSdddddddo.`,`kseEsssSSddddddo..`,`kseesssSsdddddo...`,`.ksmsssSSddddo....`,`..kkssSSkoooo.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`....oooooooooo....`,`...ohhhhhhhhHdo...`,`..ohhhhhhhHhHHHo..`,`.ohhhhhhHHHHdHHHo.`,`.ohhhhdHdHHHHHHdo.`,`.ohhHHHHHHHHHHHdo.`,`.oHHHHhHHHHdHdddo.`,`.ohdddddddddddddo.`,`..ooSdsdsdsdsdSo..`,`...kSsssssssssSk..`,`...kSseEsssEesSk..`,`...kSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....ooooooooo....`,`...oohhhhhhhHdoo..`,`..ohhhhhhhdHHdHHo.`,`..ohhhhhdhdHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhhHHHHHHdHHdddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....ooooooooo....`,`...oohhhhhhhHdoo..`,`..ohhhhhhhdHHdHHo.`,`..ohhhhhdhdHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhhHHHHHHdHHdddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....ooooooooo....`,`...oohhhhhhhHdoo..`,`..ohhhhhhhdHHdHHo.`,`..ohhhhhdhdHHHHHo.`,`.ohhhhHHHHdHdHHHHo`,`.ohhhHHHHHHdHHdddo`,`.ohHHHHHHHHHHddddo`,`.odddddddHHddddddo`,`..odssdSSddddddoo.`,`.ksssssSSddddoo...`,`kseEsssSSSsdo.....`,`kseesssSsSDo......`,`.ksmsssSSSk.......`,`..kkssSSkk........`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`........oo.........`,`.....ooohhooo......`,`...oohhhhhhhHoo....`,`..ohhhhhhHHhHHHo...`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhdHdHHHHHHdo..`,`ohhhHHHHHHHHHHdddo.`,`ohHXXHHHHHHHHddddo.`,`oHhXdddddddddddddo.`,`.oHdSSdssdssdSSdo..`,`.oHHSsssssssssSdo..`,`..oHSseEsssEesSo...`,`...oSseessseesSk...`,`....kSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`........ooo........`,`.....ooohhhooo.....`,`....ohhhhhhhHHo....`,`...ohhhhhhdHHdHo...`,`..ohhhhhdhHHHHHHoo.`,`.ohhhhHHHHdHdHHHHdo`,`.ohhHHHHHHHdHHddddo`,`.oHHHHHHHHHHdXXdddo`,`.odddddddHHHdXddddo`,`..odssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsdddddddo..`,`.ksmsssSSddddooo...`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`........ooo........`,`.....ooohhhooo.....`,`....ohhhhhhhHHo....`,`...ohhhhhhdHHdHo...`,`..ohhhhhdhHHHHHHoo.`,`.ohhhhHHHHdHdHHHHdo`,`.ohhHHHHHHHdHHddddo`,`.oHHHHHHHHHHdXXdddo`,`.odddddddHHHdXddddo`,`..odssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsdddddddo..`,`.ksmsssSSddddooo...`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`........ooo........`,`.....ooohhhooo.....`,`....ohhhhhhhHHo....`,`...ohhhhhhdHHdHo...`,`..ohhhhhdhHHHHHHoo.`,`.ohhhhHHHHdHdHHHHdo`,`.ohhHHHHHHHdHHddddo`,`.oHHHHHHHHHHdXXdddo`,`.odddddddHHHdXddddo`,`..odssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsdddddddo..`,`.ksmsssSSddddooo...`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`......oooooo......`,`...ooohhhhhhooo...`,`..ohhhhhhhhHHdHo..`,`.ohhhhhhhHHhHHHHo.`,`.ohhhhhHHHHHHHHHo.`,`ohhhhHdHHHHHHHHdHo`,`ohhhHHHHHHHHHHdddo`,`ohHHHhhHHHHdHddddo`,`oHhddddddddddddddo`,`oHHHSdsdsdsdsdSddo`,`oHHHSsssssssssSddo`,`oHHHSseEsssEesSddo`,`oHHHSseessseesSddo`,`.ooodSsssSsssSkoo.`,`....okSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhHdHHdHHo.`,`.ohhhhhhdHHHHHHHHo`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsdddddddo.`,`.ksmsssSSdddddoo..`,`..kkssSSkooooo....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhHdHHdHHo.`,`.ohhhhhhdHHHHHHHHo`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsdddddddo.`,`.ksmsssSSdddddoo..`,`..kkssSSkooooo....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhHdHHdHHo.`,`.ohhhhhhdHHHHHHHHo`,`.ohhhhHHHHdHdHHHHo`,`.ohhHHHhHHHdHHdddo`,`.oHHHHhHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsdddddddo.`,`.ksmsssSSdddddoo..`,`..kkssSSkooooo....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`....ohohhhhhooo....`,`..oohhhhhhhHHhHo...`,`.odhhhdhhHdHHHdoo..`,`ohhhhhhHHHHHHHHHHo.`,`ohhhhHHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`hhHHHHHHHHHHHHddddo`,`HhHHHhHHHhHHHdddddo`,`HHddddddddddddddddo`,`oHHHSdssdsdssdSddo.`,`oHHhSsssssssssSddo.`,`.oHHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`....ooohhhhhooo....`,`...ohhhhhhhHHhHo...`,`..oohhdhhHdHHHdoo..`,`.ohhhhhhHHHHHHHHHo.`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHddo`,`ohHHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSdddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`....ooohhhhhooo....`,`...ohhhhhhhHHhHo...`,`..oohhdhhHdHHHdoo..`,`.ohhhhhhHHHHHHHHHo.`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHddo`,`ohHHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSdddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`....ooohhhhhooo....`,`...ohhhhhhhHHhHo...`,`..oohhdhhHdHHHdoo..`,`.ohhhhhhHHHHHHHHHo.`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHddo`,`ohHHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSdddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSodoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`.ooo...........ooo.`,`ohhho.oooooo..oHHHo`,`hhhhhohhhhhhooHhHHd`,`hhhhhhhhhhHHHdHHHdH`,`ohhhhhhhHHHhHHHHHHo`,`.ohhhhhHHHHHdHHHdo.`,`ohhhhhHHHHHHHHHHdo.`,`ohhHHHdHHHHHHddddo.`,`oHHddddddddddddddo.`,`oHHHSSdssdssdSSddo.`,`.odHSsssssssssSdo..`,`.oHHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.............ooo...`,`......ooooooohhHo..`,`....oohhhhhhhHHHHo.`,`...ohhhhhhhHHHHHHo.`,`..ohhhhhhhHHHdHHHo.`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhHHhHHHHHHddo.`,`.ohdHHHHHHHHHdHddo.`,`.odddddddHHHHddddo.`,`..odssdSSHHddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSdddddo....`,`..kkssSSoddooo.....`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.............ooo...`,`......ooooooohhHo..`,`....oohhhhhhhHHHHo.`,`...ohhhhhhhHHHHHHo.`,`..ohhhhhhhHHHdHHHo.`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhHHhHHHHHHddo.`,`.ohdHHHHHHHHHdHddo.`,`.odddddddHHHHddddo.`,`..odssdSSHHddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSdddddo....`,`..kkssSSoddooo.....`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.............ooo...`,`......ooooooohhHo..`,`....oohhhhhhhHHHHo.`,`...ohhhhhhhHHHHHHo.`,`..ohhhhhhhHHHdHHHo.`,`.ohhhhhhHHHHHHHHo..`,`.ohhhhHHhHHHHHHddo.`,`.ohdHHHHHHHHHdHddo.`,`.odddddddHHHHddddo.`,`..odssdSSHHddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSdddddo....`,`..kkssSSoddooo.....`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`......oooooo......`,`....oohhhhhhoo....`,`...ohhhhhhHHHdo...`,`..ohhhhhhHHhHHHo..`,`.ohhhhhHHHHHdHHHo.`,`ohhhhHHHHHHHHHHdHo`,`ohhddHHHHHHHHHHddo`,`oHHHHhHHHHHdHddddo`,`oHHddddddddddddddo`,`oHHHSdsdsdsdsdSddo`,`.oHHSsssssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhHHHHHdHdHHHHo`,`.ohhddHHHHHHHHdddo`,`ohHHHhHHHHHHHddddo`,`oddddddddHHHdddddo`,`.oodssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhHHHHHdHdHHHHo`,`.ohhddHHHHHHHHdddo`,`ohHHHhHHHHHHHddddo`,`oddddddddHHHdddddo`,`.oodssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`......ooooooo.....`,`....oohhhhhhhoo...`,`...ohhhhhhhHHHHo..`,`..ohhhhhhhHHHdHHo.`,`.ohhhhhhHHHHHHHHo.`,`.ohhhHHHHHdHdHHHHo`,`.ohhddHHHHHHHHdddo`,`ohHHHhHHHHHHHddddo`,`oddddddddHHHdddddo`,`.oodssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.....o.ooooo.......`,`....ohohhhhhoo.....`,`..oohhdhhhdHHHo....`,`.ohhhhhhHHHHHHHo...`,`.ohhhhhhHHHhHHHoo..`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHddddo.`,`oHdddddddddddddddo.`,`oHHHSdssdsdssdSddo.`,`oHHhSsssssssssSddo.`,`oHHHSseEsssEesSddo.`,`oHHHSseessseesSddo.`,`.oookSsssSsssSkoo..`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.......ooooo.......`,`....ooohhhhhooo....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`.ohhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSddddoo....`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.......ooooo.......`,`....ooohhhhhooo....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`.ohhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSddddoo....`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.......ooooo.......`,`....ooohhhhhooo....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`.ohhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHdddddo`,`oddddddddHddddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSdddddddo..`,`kseesssSsddddddo...`,`.ksmsssSSddddoo....`,`..kkssSSkoooo......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`...oooohhhhhho.....`,`..ohhhhhhhhhHHoo...`,`.oohhhhhhhHHHdHHo..`,`ohhhhhhhHHdHHHHHo..`,`ohhhhhHHHHHHdHHHdo.`,`ohhhhHHHHHHHHHHdHdo`,`hhhdddHHHHHHHHHdddo`,`hHHHhHHHHHHHHddddo.`,`HhHdddddddddddddddo`,`oHdHSdsdsssdsdSdddo`,`odHHSsssssssssSddo.`,`oHHHSseEsssEesSddo.`,`oHHHSseessseesSddo.`,`.odddSsssSsssSddo..`,`..odddSssmssSddo...`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHHHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`HddddddddHHHddddddo`,`ooodssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHHHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`HddddddddHHHddddddo`,`ooodssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`....ooohhhohho.....`,`...ohhhhhhhhHHoo...`,`..ohhhhhhhdHHHHHo..`,`.ohhhhhhhhHHHdHHHo.`,`ohhhhhhhHHHHHHHHHo.`,`ohhhhhHdHHdHHHHHHdo`,`ohhdddHHHHHHHHddddo`,`hHHHhHHHHHHHHdddddo`,`HddddddddHHHddddddo`,`ooodssdSSHddddddddo`,`.ksssssSSdddddddddo`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`.....oooooooo.....`,`...oohhhhhhhHoo...`,`..ohhhhhhhHhHdHo..`,`.ohhhhhhHHHhHHHHo.`,`.ohhhhHhdHHHdHHHo.`,`ohhhHHHdHHHdHHdHdo`,`ohHHHHHHHHHHdHdddo`,`oHHddddddddddddddo`,`oHHdSSsssssssSSddo`,`.odHSsssssssssSdo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....oooooooo.....`,`....ohhhhhhhHoo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhHhHHHdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHhHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....oooooooo.....`,`....ohhhhhhhHoo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhHhHHHdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHhHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....oooooooo.....`,`....ohhhhhhhHoo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhHhHHHdHHo.`,`.ohhhhhHHHdhHHHHdo`,`.ohhhHhHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`......oooooo.......`,`....oohhhhhHoo.....`,`...ohhhhhhHHHHo....`,`..ohhhhhHHHHdHHo...`,`.oohhhdHdHHHHHHooo.`,`ohhhhHhHHHHHHHHdddo`,`ohhHHHHHHHHHHdddddo`,`oXXdddddddddddddXXo`,`ohHHSSddHHHHHHHdddo`,`oHHHSssssssddddoddo`,`oHHHSseEsssEesSoddo`,`.oooSseessseesSkoo.`,`....kSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`......ooooooo......`,`.....ohhhhhhHo.....`,`....ohhhhhdHHHo....`,`...ohhhhdhdhHHHo...`,`..ohhhhHHHdHHHHdo..`,`..ohhHHHHHHdHHdddo.`,`..oHHHHHHHHHdddddo.`,`..oddddddHHHdddXXo.`,`..odssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsdddddoddo.`,`.ksmsssSSddddooddo.`,`..kkssSSkoooo.oddo.`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`......ooooooo......`,`.....ohhhhhhHo.....`,`....ohhhhhdHHHo....`,`...ohhhhdhdhHHHo...`,`..ohhhhHHHdHHHHdo..`,`..ohhHHHHHHdHHdddo.`,`..oHHHHHHHHHdddddo.`,`..oddddddHHHdddXXo.`,`..odssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsdddddoddo.`,`.ksmsssSSddddooddo.`,`..kkssSSkoooo.oddo.`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`......ooooooo......`,`.....ohhhhhhHo.....`,`....ohhhhhdHHHo....`,`...ohhhhdhdhHHHo...`,`..ohhhhHHHdHHHHdo..`,`..ohhHHHHHHdHHdddo.`,`..oHHHHHHHHHdddddo.`,`..oddddddHHHdddXXo.`,`..odssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsdddddoddo.`,`.ksmsssSSddddooddo.`,`..kkssSSkoooo.oddo.`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]},{down:[`......ohhhho......`,`......ohhhHo......`,`.....kohhHHok.....`,`....knsHHHHssk....`,`...knssHHHHsssk...`,`..knsssHHHHssSSk..`,`.ksssssHHHHsSSSSk.`,`.ksssssHHHHSSSSSk.`,`.ksssssHHHdSSSSSk.`,`.ksssssddddSSSSSk.`,`..ksSSsssssssSSk..`,`..ksSseEsssEesSk..`,`...kSseessseesSk..`,`....kSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.....ohhhhhhHo....`,`....ohhhhhhHHHo...`,`...ohhhhhHHHHHo...`,`..ohhhhhHHHHHHo...`,`..ohhhHHHHHHHHsk..`,`..knssssssssssSSk.`,`..ksssssssssSSSSk.`,`..kssssssssSSSSSk.`,`..kssssssSSSSSSSk.`,`..ksssssSSSSSSSSk.`,`.kodssdSSSSSSSSSk.`,`kseEsssSSSSSSSSk..`,`kseesssSsSSSSSk...`,`.ksmsssSSSSSSk....`,`..kkssSSoddok.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.....ohhhhhhHo....`,`....ohhhhhhHHHo...`,`...ohhhhhHHHHHo...`,`..ohhhhhHHHHHHo...`,`..ohhhHHHHHHHHsk..`,`..knssssssssssSSk.`,`..ksssssssssSSSSk.`,`..kssssssssSSSSSk.`,`..kssssssSSSSSSSk.`,`..ksssssSSSSSSSSk.`,`.kodssdSSSSSSSSSk.`,`kseEsssSSSSSSSSk..`,`kseesssSsSSSSSk...`,`.ksmsssSSSSSSk....`,`..kkssSSoddok.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.....ohhhhhhHo....`,`....ohhhhhhHHHo...`,`...ohhhhhHHHHHo...`,`..ohhhhhHHHHHHo...`,`..ohhhHHHHHHHHsk..`,`..knssssssssssSSk.`,`..ksssssssssSSSSk.`,`..kssssssssSSSSSk.`,`..kssssssSSSSSSSk.`,`..ksssssSSSSSSSSk.`,`.kodssdSSSSSSSSSk.`,`kseEsssSSSSSSSSk..`,`kseesssSsSSSSSk...`,`.ksmsssSSSSSSk....`,`..kkssSSoddok.....`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`......ohhhho......`,`.....oohhhhoo.....`,`...oohhhhhhhHoo...`,`..ohhhhhhhHhHHHo..`,`.ohhhhhhXXXhHHHHo.`,`.ohhhhdhdHHHHHHdo.`,`ohhhHHhHHHHHHHdddo`,`ohHHHHHHHHHHdddddo`,`oHhddddddddddddddo`,`oHHdSSdssdssdSSddo`,`.odHSsssssssssSdo.`,`.oHHSseEsssEesSdo.`,`.oHHSseessseesSdo.`,`.odddSsssSsssSddo.`,`..odddSssmssSddo..`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........ohhhho....`,`.....oooohhhho....`,`....ohhhhhhhHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhXXXHHHo.`,`.ohhhhdHHHdHdHHHdo`,`.ohhHHHHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........ohhhho....`,`.....oooohhhho....`,`....ohhhhhhhHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhXXXHHHo.`,`.ohhhhdHHHdHdHHHdo`,`.ohhHHHHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........ohhhho....`,`.....oooohhhho....`,`....ohhhhhhhHHo...`,`...ohhhhhhdHHdHo..`,`..ohhhhhdhXXXHHHo.`,`.ohhhhdHHHdHdHHHdo`,`.ohhHHHHHHHHHHHHdo`,`.ohHHHHHHHHHHHdddo`,`.odddddddHHHdddddo`,`..odssdSSHdddddddo`,`.ksssssSSddddddddo`,`kseEsssSSddddddddo`,`kseesssSsddddddddo`,`.ksmsssSSdddddddo.`,`..kkssSSoddddddo..`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.....o.ooooo.......`,`....ohohhhhhooo....`,`..oohhdhhhdHHHdo...`,`.ohhhhhhHHHHHHHoo..`,`ohhhhhHhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHddo.`,`ohHHHhHHHhHHHddddo.`,`oHdddddddddddddddo.`,`oHHHSdssdsdssdSddo.`,`oHHhSsssssssssSddo.`,`oHHHSseEsssEesSddo.`,`oHHHSseessseesSddo.`,`.odddSsssSsssSddo..`,`..odddSssmssSddo...`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.....o.ooooo.o.....`,`....ohohhhhhoho....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHdHddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.....o.ooooo.o.....`,`....ohohhhhhoho....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHdHddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.....o.ooooo.o.....`,`....ohohhhhhoho....`,`...ohhdhhhdHHHdo...`,`..oohhhhhHHHHHHoo..`,`.ohhhhhhHHHhHHHhHo.`,`ohhhdHHHdHHHdHHHdo.`,`ohhHHHHHHHHHHHHdddo`,`ohHHHhHHHhHHHdddddo`,`oddddddddHdHddddddo`,`.oodssdSSHdddddddo.`,`.ksssssSSddddddddo.`,`kseEsssSSddddddddo.`,`kseesssSsddddddddo.`,`.ksmsssSSdddddddo..`,`..kkssSSoddddddo...`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]}],pn=[null,{down:[`........qq........`,`.....qqqRXqqq.....`,`...qqRRRWWWRRqq...`,`..qRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrq.`,`qhhHHHHHHHHHHHdddq`,`oHHddddddddddddddo`,`.oHHSdsdHHHHHHHdo.`,`.oHHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`........qqq.......`,`.....qqqRRXqqq....`,`....qRRRRRRRRRq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrrq`,`.qhhHHHHHHHHHHHddq`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`........qqq.......`,`.....qqqRRXqqq....`,`....qRRRRRRRRRq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrrq`,`.qhhHHHHHHHHHHHddq`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`........qqq.......`,`.....qqqRRXqqq....`,`....qRRRRRRRRRq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qrrrrrrrrrrrrrrrq`,`.qhhHHHHHHHHHHHddq`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDddddo..`,`.ksmsssSSSddooo...`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.......qqqq.......`,`....qqqRRRRqqq....`,`...qRRRRRRRRRRq...`,`..qRRRRRRRRRRRRq..`,`.qXXXXXXXXXXXXXXq.`,`.qhhhHHHHHHHHHHHq.`,`ohhHHHHHHHHHHHdddo`,`oHHddddddddddddddo`,`oHHHSdsdHHHHHHHddo`,`.oHHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`...okSsssSsssSk...`,`.....kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`.......qqqq.......`,`....qqqRRRRqqqq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qXXXXXXXXXXXXXXq.`,`.qhhhhHHHHHHHHHHHq`,`.ohhHHHHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`.......qqqq.......`,`....qqqRRRRqqqq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qXXXXXXXXXXXXXXq.`,`.qhhhhHHHHHHHHHHHq`,`.ohhHHHHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`.......qqqq.......`,`....qqqRRRRqqqq...`,`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`.qXXXXXXXXXXXXXXq.`,`.qhhhhHHHHHHHHHHHq`,`.ohhHHHHHHHHHHHddo`,`.odddddddHHHHddddo`,`..odssdSSHHddddddo`,`.ksssssSSddddddddo`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`..qRRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRrrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHdddddq.`,`.oHdddddddddddddo.`,`.oHHSdsdHHHHHHHdo.`,`.oHHSssssssdddddo.`,`..oHSseEsssEesSdo.`,`..oHSseessseesSo..`,`..odoSsssSsssSk...`,`...o.kSssmssSk....`,`.....kLkccckLk....`,`...kkLLlJJJlLlkk..`,`..kLLlJJJJJJjlLlk.`,`.kssklJJJjJJjlksSk`,`.kSskJJjJJJJjjksSk`,`..kkPPPPPPPPPPPkk.`,`....kPPpk.kpPPk...`,`....kBBwk.kwBBk...`,`.....kkk...kkk....`],walk:[[`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`..qRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHHddddq.`,`.odddddddHddddddo.`,`..odssdSSdddddddo.`,`.ksssssSSdddddddo.`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.......kPPpk......`,`......kBBBwk......`,`.......kkkk.......`],[`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`..qRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHHddddq.`,`.odddddddHddddddo.`,`..odssdSSdddddddo.`,`.ksssssSSdddddddo.`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`.....kPpk.kPpk....`,`....kBBwk.kBBwk...`,`.....kkk...kkk....`],[`...qRRRRRRRRRRRq..`,`..qRRRRRRRRRRRRRq.`,`..qRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRRq.`,`.qRRRRRRRRRRRRRrq.`,`.qXXXXXXXXXXXXXXq.`,`.qHHHHHHHHHHddddq.`,`.odddddddHddddddo.`,`..odssdSSdddddddo.`,`.ksssssSSdddddddo.`,`kseEsssSSSsdddddo.`,`kseesssSsSDdddddo.`,`.ksmsssSSSddoooo..`,`..kkssSSkkoo......`,`......kLLkcck.....`,`.....kLLlJJJk.....`,`.....kLlJJJJk.....`,`.....ksSkJJjk.....`,`.....kSkJJJjk.....`,`......kPPPPPk.....`,`......kPPpk.......`,`......kBBBwk......`,`.......kkkk.......`]]},{down:[`.....qqqqqqqq......`,`...qqRRRRRRRRqq....`,`..qRRRRRRRRRRRRq...`,`.qRRRRRRRRRRRRRRq..`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHdq.`,`hHHHHHHHHHHHHHddddo`,`HHHdddddddddddddddo`,`oHHHSdsdHHHHHHHddo.`,`oHHHSssssssddddddo.`,`.ooHSseEsssEesSdo..`,`..oHSseessseesSo...`,`...okSsssSsssSk....`,`.....kSssmssSk.....`,`.....kLkccckLk.....`,`...kkLLlJJJlLlkk...`,`..kLLlJJJJJJjlLlk..`,`.kssklJJJjJJjlksSk.`,`.kSskJJjJJJJjjksSk.`,`..kkPPPPPPPPPPPkk..`,`....kPPpk.kpPPk....`,`....kBBwk.kwBBk....`,`.....kkk...kkk.....`],walk:[[`.....qqqqqqqqq.....`,`...qqRRRRRRRRRqq...`,`..qRRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRRq.`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHddq`,`ohHHHHHHHHHHHHddddo`,`oddddddddHHHddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSkkoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.......kPPpk.......`,`......kBBBwk.......`,`.......kkkk........`],[`.....qqqqqqqqq.....`,`...qqRRRRRRRRRqq...`,`..qRRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRRq.`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHddq`,`ohHHHHHHHHHHHHddddo`,`oddddddddHHHddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSkkoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`.....kPpk.kPpk.....`,`....kBBwk.kBBwk....`,`.....kkk...kkk.....`],[`.....qqqqqqqqq.....`,`...qqRRRRRRRRRqq...`,`..qRRRRRRRRRRRRRq..`,`.qRRRRRRRRRRRRRRRq.`,`qXXXXXXXXXXXXXXXXq.`,`qhhhHHHHHHHHHHHHddq`,`ohHHHHHHHHHHHHddddo`,`oddddddddHHHddddddo`,`.oodssdSSHddddddddo`,`.ksssssSSddddddddo.`,`kseEsssSSSsddddddo.`,`kseesssSsSDdddddo..`,`.ksmsssSSSddoooo...`,`..kkssSSkkoo.......`,`......kLLkcck......`,`.....kLLlJJJk......`,`.....kLlJJJJk......`,`.....ksSkJJjk......`,`.....kSkJJJjk......`,`......kPPPPPk......`,`......kPPpk........`,`......kBBBwk.......`,`.......kkkk........`]]}],mn={base:{k:`#373337`,E:`#f0f0f8`,e:`#36363e`,m:`#a0605a`,q:`#f2a0a0`,s:`#fbe0c8`,S:`#d5beaa`,X:`#9aa0a6`,H:`#363438`,o:`#313132`,J:`#f4f4f0`,L:`#f4f4f0`,c:`#f8f8f8`,P:`#3a4058`,B:`#f0f0f0`,w:`#b0b0bc`,h:`#38353a`,d:`#353336`,W:`#f8f8f8`,D:`#b09d8c`,n:`#fffbe0`,j:`#bebebb`,l:`#bebebb`,p:`#35394b`},hairColor:[{H:`#363438`,o:`#313132`,v:`#333235`,h:`#38353a`,d:`#353336`},{H:`#3d3539`,o:`#343132`,v:`#373335`,h:`#40363b`,d:`#393336`},{H:`#503428`,o:`#3a302c`,v:`#42322c`,h:`#5f3b2c`,d:`#48332a`},{H:`#5c3a26`,o:`#3e312a`,v:`#463328`,h:`#764a31`,d:`#4d3425`},{H:`#704830`,o:`#443329`,v:`#4a3426`,h:`#8f5c3d`,d:`#533524`},{H:`#a04828`,o:`#532e21`,v:`#5e2e1c`,h:`#cd5c33`,d:`#76351e`},{H:`#d88838`,o:`#5b3918`,v:`#774b1f`,h:`#ffae48`,d:`#a06529`},{H:`#f8d070`,o:`#886840`,v:`#88723e`,h:`#ffff8f`,d:`#b89a53`},{H:`#e8e8f0`,o:`#8888a0`,v:`#808084`,h:`#ffffff`,d:`#acacb2`},{H:`#f08ab8`,o:`#8a3a62`,v:`#844c65`,h:`#ffb1ec`,d:`#b26688`},{H:`#5a78d8`,o:`#2a3872`,v:`#324277`,h:`#739aff`,d:`#4359a0`},{H:`#58a878`,o:`#204b33`,v:`#305c42`,h:`#71d79a`,d:`#417c59`}],skin:[{s:`#fbe0c8`,m:`#a0605a`,S:`#d5beaa`,D:`#b09d8c`,n:`#fffbe0`},{s:`#f8d0b0`,m:`#9a5a48`,S:`#d3b196`,D:`#ae927b`,n:`#ffe9c5`},{s:`#f0c8a0`,m:`#9a5a48`,S:`#ccaa88`,D:`#a88c70`,n:`#ffe0b3`},{s:`#d8a07c`,m:`#a0505a`,S:`#b88869`,D:`#977057`,n:`#f2b38b`},{s:`#c48a62`,m:`#7a4232`,S:`#a77553`,D:`#896145`,n:`#dc9b6e`},{s:`#b87a52`,m:`#6e3e30`,S:`#9c6846`,D:`#815539`,n:`#ce895c`},{s:`#94603e`,m:`#5e3226`,S:`#7e5235`,D:`#68432b`,n:`#a66c45`},{s:`#6e4430`,m:`#552f23`,S:`#5e3a29`,D:`#513426`,n:`#7b4c36`}],shirt:[{J:`#f4f4f0`,j:`#bebebb`},{J:`#70b8e0`,j:`#5790af`},{J:`#f08048`,j:`#bb6438`},{J:`#f890a8`,j:`#c17083`},{J:`#f8d040`,j:`#c1a232`},{J:`#9cc0e0`,j:`#7a96af`},{J:`#34446a`,j:`#2f3b59`},{J:`#9a2a48`,j:`#782138`},{J:`#58a878`,j:`#45835e`},{J:`#7d4fc9`,j:`#623e9d`},{J:`#3a3f58`,j:`#35394d`},{J:`#363a47`,j:`#353842`},{J:`#2a3870`,j:`#2c3763`},{J:`#e0823c`,j:`#af652f`}],sleeves:[{L:`#f4f4f0`,l:`#bebebb`},{L:`#70b8e0`,l:`#5790af`},{L:`#f08048`,l:`#bb6438`},{L:`#f890a8`,l:`#c17083`},{L:`#f8d040`,l:`#c1a232`},{L:`#9cc0e0`,l:`#7a96af`},{L:`#34446a`,l:`#2f3b59`},{L:`#9a2a48`,l:`#782138`},{L:`#58a878`,l:`#45835e`},{L:`#7d4fc9`,l:`#623e9d`},{L:`#3a3f58`,l:`#35394d`},{L:`#363a47`,l:`#353842`},{L:`#2a3870`,l:`#2c3763`},{L:`#e0823c`,l:`#af652f`}],pants:[{P:`#3a4058`,p:`#35394b`},{P:`#4060a8`,p:`#30487e`},{P:`#506888`,p:`#3c4e66`},{P:`#605848`,p:`#484236`},{P:`#b8a888`,p:`#8a7e66`},{P:`#4a6eb0`,p:`#385384`},{P:`#383840`,p:`#36363c`},{P:`#6a4a32`,p:`#503826`},{P:`#35373f`,p:`#34353b`},{P:`#f0ece2`,p:`#b4b1aa`}],shoes:[{B:`#f0f0f0`,w:`#b0b0bc`},{B:`#484848`,w:`#f0f0f0`},{B:`#c06838`,w:`#f8f8f8`},{B:`#403838`,w:`#706868`},{B:`#c03850`,w:`#f8f8f8`},{B:`#3d3537`,w:`#5a4a48`}],hat:[[],[{R:`#3f7bd6`,r:`#2d599a`,q:`#243c61`,X:`#9aa0a6`},{R:`#2fa37a`,r:`#227558`,q:`#1b4939`,X:`#9aa0a6`},{R:`#d6604a`,r:`#9a4535`,q:`#5d2d25`,X:`#9aa0a6`},{R:`#7d4fc9`,r:`#5a3991`,q:`#402e5e`,X:`#9aa0a6`},{R:`#e0b23c`,r:`#a1802b`,q:`#5a4718`,X:`#9aa0a6`},{R:`#3a3f58`,r:`#35384a`,q:`#33353f`,X:`#9aa0a6`}],[{R:`#3f7bd6`,r:`#2d599a`,q:`#243c61`,X:`#e8c040`},{R:`#2fa37a`,r:`#227558`,q:`#1b4939`,X:`#e8c040`},{R:`#d6604a`,r:`#9a4535`,q:`#5d2d25`,X:`#e8c040`},{R:`#7d4fc9`,r:`#5a3991`,q:`#402e5e`,X:`#e8c040`},{R:`#e0b23c`,r:`#a1802b`,q:`#5a4718`,X:`#e8c040`},{R:`#3a3f58`,r:`#35384a`,q:`#33353f`,X:`#e8c040`}],[{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`},{R:`#38373e`,r:`#35353a`,q:`#333336`,X:`#f25c3b`}],[{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`},{R:`#2b3868`,r:`#2c3658`,q:`#2d3346`,X:`#e8c040`}]]},hn={hair:21,hairColor:12,skin:8,eyes:5,glasses:4,face:6,hat:5,shirt:14,sleeves:14,outfit:6,pants:10,shoes:6},gn={hair:[0,1,2,3,5,6,7,8,9,10,11,13,14,16,20],hairColor:[0,1,2,3,4,5,6,7],skin:[0,1,2,3,4,5,6,7],eyes:[0,1,2,3],glasses:[0,1,2],face:[0,1,2,3,4,5],hat:[0],shirt:[0,1,2,3,4,5,6,7,8,10,11,12],sleeves:[0,1,2,3,4,5,6,7,8,10,11,12],outfit:[0,1,2],pants:[0,1,2,3,4,5,6,7,8,9],shoes:[0,1,2,3,4,5]},_n=new Set([`iTerm.app`,`WezTerm`,`vscode`,`ghostty`,`Hyper`,`Tabby`,`rio`]),vn=new Set([`iTerm.app`,`WezTerm`,`vscode`,`ghostty`,`Hyper`,`Tabby`,`rio`]);function yn({env:e=process.env,argv:t=process.argv,isTTY:n=!!process.stdout.isTTY}={}){if(t.includes(`--no-color`)||t.includes(`--no-colour`)||e.NO_COLOR!==void 0&&e.NO_COLOR!==``)return 0;let r=e.FORCE_COLOR,i;if(r!==void 0){if(r===`0`||r===`false`)return 0;i=r===`2`?2:r===`3`?3:1}if(!n||e.TERM===`dumb`)return i??0;let a=1,o=(e.COLORTERM??``).toLowerCase();return o===`truecolor`||o===`24bit`||_n.has(e.TERM_PROGRAM??``)||/-(truecolor|direct)$|^xterm-(kitty|ghostty)$/.test(e.TERM??``)?a=3:/256(col)?/.test(e.TERM??``)&&(a=2),i!==void 0&&i>a?i:a}function bn(e,t){return e.FORCE_HYPERLINK===void 0?!t||e.TMUX||/^screen/.test(e.TERM??``)?!1:vn.has(e.TERM_PROGRAM??``)||e.WT_SESSION||e.KITTY_WINDOW_ID||/^xterm-(kitty|ghostty)$|^alacritty/.test(e.TERM??``)?!0:Number(e.VTE_VERSION??0)>=5e3:e.FORCE_HYPERLINK!==`0`&&e.FORCE_HYPERLINK!==``&&t}function xn(e={}){let t=e.env??process.env,n=e.isTTY??!!process.stdout.isTTY,r=yn({...e,env:t,isTTY:n}),i=n&&r>0&&t.TERM!==`dumb`,a=e.columns??(n?process.stdout.columns:void 0)??(Number(t.COLUMNS)||void 0),o=Number(t.BITFOLK_COLUMNS)||void 0,s=n&&a?Math.max(40,a):o?Math.max(40,o):void 0,c=s??Math.max(40,Number(t.COLUMNS)||80);return{depth:r,tty:n,fancy:i,links:bn(t,i),columns:s,layout:c,live:n&&e.columns===void 0}}let M=xn();function Sn(e){return M=`depth`in e||`fancy`in e?{...M,...e}:xn(e),M}const Cn=()=>M.live&&process.stdout.columns?Math.max(40,process.stdout.columns):M.columns,wn=()=>Cn()??M.layout,N=()=>Cn()??1/0,Tn=e=>{let t=parseInt(e.replace(`#`,``),16);return[t>>16&255,t>>8&255,t&255]};function En([e,t,n]){let r=e=>e<48?0:e<115?1:Math.floor((e-35)/40),i=[0,95,135,175,215,255],[a,o,s]=[r(e),r(t),r(n)],c=16+36*a+6*o+s,l=(i[a]-e)**2+(i[o]-t)**2+(i[s]-n)**2,u=(e+t+n)/3,d=u>238?23:Math.max(0,Math.round((u-8)/10)),f=8+d*10;return(f-e)**2+(f-t)**2+(f-n)**2<l?232+d:c}const Dn=(e,t,n)=>n>=3?`38;2;${Tn(e).join(`;`)}`:n===2?`38;5;${En(Tn(e))}`:String(t),On=(e,t)=>t>=3?`48;2;${Tn(e).join(`;`)}`:`48;5;${En(Tn(e))}`;function kn(e,t,n){if(M.depth===0||n===``)return n;let r=`[${e}m`,i=`[${t}m`;return r+n.split(i).join(i+r)+i}const An=(e,t=39)=>n=>kn(Dn(e,t,M.depth),`39`,n),P=e=>kn(`1`,`22`,e),F=e=>kn(`2`,`22`,e),jn=e=>kn(`4`,`24`,e),I={ok:An(`#4f9a3a`,32),warn:An(`#c98a12`,33),err:An(`#e0483a`,31),accent:An(on.coral,91),tool:An(`#5f7fe8`,94),money:An(`#c98a12`,33),sky:An(`#3d8fd0`,36),dim:F,bold:P},Mn=[[`#d4733f`,33],[`#9b5cd6`,95],[`#1f9e8f`,36],[`#c94f7c`,35],[`#7f9a1f`,32],[`#b07a2a`,93]];function Nn(e){let t=0;for(let n of e)t=t*31+n.codePointAt(0)>>>0;let[n,r]=Mn[t%Mn.length];return e=>P(An(n,r)(e))}const L={ok:`✓`,fail:`✗`,skip:`·`,dot:`●`,idle:`○`,arrow:`›`,warn:`!`},Pn=/\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g,Fn=e=>e.replace(Pn,``),R=e=>e.replace(/[\t\n\r]+/g,` `).replace(/[\x00-\x1f\x7f-\x9f]/g,``),In=e=>e.replace(/\x1b\[[0-9;]*m|[\x00-\x1f\x7f-\x9f]/g,e=>e.length>1&&M.depth>0?e:e===`
8
+ `||e===` `?` `:``),z=e=>e.replace(/ /g,`\xA0`),Ln=e=>e.replace(/\u00a0/g,` `),Rn=e=>e>=768&&e<=879||e>=8203&&e<=8207||e>=8400&&e<=8447||e>=65024&&e<=65039||e===8205,zn=e=>e>=4352&&e<=4447||e>=11904&&e<=12350||e>=12353&&e<=13311||e>=13312&&e<=19903||e>=19968&&e<=40959||e>=40960&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=127744&&e<=128591||e>=129280&&e<=129535||e>=131072&&e<=262141,Bn=e=>{let t=e.codePointAt(0);return t<32||t>=127&&t<160||Rn(t)?0:zn(t)?2:1};function B(e){let t=0;for(let n of Fn(e))t+=Bn(n);return t}function Vn(e){let t=[],n=0;for(let r of e.matchAll(Pn)){for(let i of e.slice(n,r.index))t.push({esc:!1,text:i});t.push({esc:!0,text:r[0]}),n=r.index+r[0].length}for(let r of e.slice(n))t.push({esc:!1,text:r});return t}function V(e,t){if(B(e)<=t)return e;if(t<=0)return``;let n=``,r=0,i=!1;for(let a of Vn(e)){if(a.esc){n+=a.text,i=!0;continue}let e=Bn(a.text);if(r+e>t-1)break;n+=a.text,r+=e}return n+`…`+(i?`\x1B[0m`:``)}const Hn=(e,t)=>e+` `.repeat(Math.max(0,t-B(e))),Un=(e,t)=>` `.repeat(Math.max(0,t-B(e)))+e;function H(e,t,n=0){if(!Number.isFinite(t)||B(e)<=t)return[Ln(e)];let r=` `.repeat(n),i=[],a=``,o=0,s=()=>i.length?t-n:t,c=()=>{i.push((i.length?r:``)+a.replace(/ +$/,``)),a=``,o=0};for(let t of e.split(/( +)/)){if(t===``)continue;let e=B(t);/^ +$/.test(t)?(o||!i.length)&&o+e<=s()&&(a+=t,o+=e):(a.trim()&&o+e>s()&&c(),a+=t,o+=e)}return(a||!i.length)&&c(),i.map(Ln)}function Wn(e,t={}){return Gn(e,t).flat()}function Gn(e,t={}){let n=` `.repeat(t.indent??0),r=t.gap??2,i=t.max??N(),a=Math.max(0,...e.map(e=>e.length)),o=Array.from({length:a},(t,n)=>Math.max(0,...e.filter(e=>n<e.length-1).map(e=>B(e[n])))),s=[];for(let t of e){let e=[];s.push(e);let a=n+t.slice(0,-1).map((e,t)=>Hn(e,o[t]+r)).join(``),c=t[t.length-1]??``,l=B(a);if(l+B(c)<=i)e.push((a+c).replace(/ +$/,``));else if(i-l<20){let t=B(n)+4;e.push(...H(a.replace(/ +$/,``),i,B(n)+2));for(let n of H(c,i-t,0))e.push(` `.repeat(t)+n)}else{let t=H(c,i-l,0);e.push(a+t[0]);for(let n of t.slice(1))e.push(` `.repeat(l)+n)}}return s.map(e=>e.map(Ln))}const Kn=(e,t=0,n)=>Wn(e.map(([e,t])=>[F(e),t]),{indent:t,gap:2,max:n});function qn(e,t={}){let n=Math.max(20,t.max??wn()),r=t.title?` ${t.title} `:``,i=Math.min(n-4,Math.max(B(r)+2,...e.map(B))),a=e=>F(e);return[a(`╭─`)+(r?P(V(r,i)):``)+a(`─`.repeat(Math.max(0,i-B(V(r,i))))+`─╮`),...e.map(e=>{let t=V(e,i);return a(`│ `)+Hn(t,i)+a(` │`)}),a(`╰`+`─`.repeat(i+2)+`╯`)]}function Jn(e,t,n=2,r=0){let i=Math.max(0,...e.map(B)),a=Math.max(e.length,t.length+r);return Array.from({length:a},(a,o)=>{let s=t[o-r];return s===void 0?e[o]??``:Hn(e[o]??``,i+n)+s}).map(e=>e.replace(/ +$/,``))}function Yn(e,t=e){let n=t===e?e:`${t} (${e})`;return M.links?`\x1b]8;;${e}\x1b\\${jn(I.sky(t))}\x1b]8;;\x1b\\${t===e?``:F(` (${e})`)}`:M.depth?jn(I.sky(n)):n}const U=e=>I.accent(e),W=e=>`${I.ok(L.ok)} ${e}`,Xn=e=>`${I.warn(L.warn)} ${I.warn(e)}`;function Zn(e,t=``){let n=[...e.matchAll(/[.;:] /g)].map(e=>e.index),r=t=>e.slice(t+2),i=n.find(e=>/^(Try|try|run|Run|press|Press|Copy)\b/.test(r(e)))??n.filter(e=>/\bbitfolk\b/.test(r(e))).pop(),a=i===void 0?e:e.slice(0,i+1),o=i===void 0?``:r(i);return`${I.err(L.fail)} ${I.err(t+a)}${o?` `+Qn(o):``}`}function Qn(e){return e.split(/((?:npx )?bitfolk(?: (?:--?)?[a-z][\w-]*| <[^>]+>)+)/).map((e,t)=>e===``?``:t%2?U(e):F(e)).join(``)}const G=(e,t=2)=>H(e,N(),t).join(`
9
+ `),$n=(e,t=process.stderr,n=process.env)=>!t.isTTY&&n.FORCE_COLOR===void 0?Fn(e):e,er=[`·`,`✢`,`✳`,`✶`,`✻`,`✽`,`✻`,`✶`,`✳`,`✢`],tr=[`Waiting for work`,`Ready for new sessions`,`Sessions start when someone asks`,`Checking in uses no model calls`],nr=(e=process.env)=>M.fancy&&!e.BITFOLK_NO_ANIMATION&&!(e.CI&&e.CI!==`0`&&e.CI!==`false`);function rr(e){let t=Math.max(0,Math.floor(e/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m ${t%60}s`:`${Math.floor(t/3600)}h ${String(Math.floor(t%3600/60)).padStart(2,`0`)}m`}const ir=(e,t,n)=>{let[r,i]=[Tn(e),Tn(t)];return`#`+r.map((e,t)=>Math.round(e+(i[t]-e)*n).toString(16).padStart(2,`0`)).join(``)},ar=[on.coral,ir(on.coral,on.gold,.45),ir(on.coral,on.gold,.8),ir(on.gold,`#fff3c4`,.5)];function or(e,t,n=M.depth){let r=[...Fn(e)];if(n===0)return r.join(``);let i=e=>Math.max(0,3-Math.abs(e-t)),a=``,o=``,s=-1,c=()=>{o&&=(a+=n===1?s>=2?`${o}`:`${o}`:`[${Dn(ar[s],39,n)}m${o}`,``)};return r.forEach((e,t)=>{let r=n===1?i(t)>=2?2:0:i(t);r!==s&&c(),s=r,o+=e}),c(),a}const sr=(e,t)=>e%(t+8)-3;function cr(e,t=M.depth,n=er){let r=n[(e%n.length+n.length)%n.length];return t===0?r:r===`✽`?`[${Dn(on.gold,93,t)}m${r}`:`[${Dn(on.coral,91,t)}m${r}`}function lr(e){let t=e.depth??M.depth,n=Fn(e.text).replace(/(\.\.\.|…)$/,``),r=[e.elapsedMs>=(e.timeAfterMs??2e3)?rr(e.elapsedMs):null,e.hint].filter(Boolean).join(` · `),i=e=>t?`${e}`:e,a=`${cr(e.frame,t)} ${or(n+`…`,sr(e.frame,[...n].length),t)}${e.detail?` `+i(e.detail):``}${r?` `+i(`(${r})`):``}`;return e.max?V(a,e.max):a}const ur=`\x1B[?25l`,dr=`\r\x1B[2K`,fr=[[`SIGINT`,130],[`SIGTERM`,143],[`SIGHUP`,129]];function pr(e,t={}){let n=t.out??process.stdout,r=t.animate??(nr()&&!!n.isTTY),i=t.now??Date.now,a=t.verbs?.length?[e,...t.verbs.filter(t=>t!==e)]:[e],o=e,s=!1,c=e=>void(e!==void 0&&n.write(e+`
10
+ `)),l=e=>({text:e=>{o=e,s=!0},stop:e,ok:t=>e(W(t)),fail:t=>e(`${I.err(L.fail)} ${I.err(t)}`)});if(!r)return t.quiet||n.write(`${e.replace(/(\.\.\.|…)$/,``)}…${t.hint?` (${t.hint})`:``}\n`),l(c);let u=i(),d=0,f=()=>Math.max(1,(n.columns||wn())-1),p=()=>{let e=i()-u,r=s||a.length===1?o:a[Math.floor(e/(t.rotateMs??4e3))%a.length];n.write(dr+lr({text:r,frame:d++,elapsedMs:e,hint:t.hint,max:f()}))};n.write(ur),p();let m=setInterval(p,100);m.unref();let h=!1,g=()=>void n.write(`\r\x1B[2K\x1B[?25h`),_=e=>{if(!h){h=!0,clearInterval(m);for(let[e,t]of v)process.removeListener(e,t);process.removeListener(`exit`,g),g(),c(e)}},v=[];for(let[e,t]of fr){if(process.listenerCount(e)>0)continue;let n=()=>{_(),process.exit(t)};process.once(e,n),v.push([e,n])}return process.once(`exit`,g),l(_)}async function K(e,t,n={}){let r=pr(e,{quiet:!0,...n});try{return await t()}finally{r.stop()}}const mr=(e,t)=>e.reduce((e,n)=>e+Math.max(1,Math.ceil(B(n)/Math.max(1,t))),0);function hr(e,t={}){let n=t.out??process.stdout,r=(t.animate??nr())&&!!n.isTTY;if(!r)return{active:r,log:e=>void n.write(e+`
11
+ `),redraw:()=>{},stop:()=>{}};let i=0,a=!1,o=[],s=()=>({columns:n.columns||wn(),rows:n.rows??(n===process.stdout?process.stdout.rows:void 0)}),c=()=>{let t=s(),n=e(i,t),r=Math.max(1,t.columns-1);return(Array.isArray(n)?n:[n]).map(e=>V(e,r))},l=()=>{let e=mr(o,n.columns||wn())-1;return e>0?`\r[${e}A`:dr},u=e=>{let t=l()+e.join(`
12
+ `);return o=e,e.length>1?`[?2026h${t}[?2026l`:t},d=()=>{a||n.write(u(c()))},f=()=>{i++,d()},p=()=>typeof t.intervalMs==`function`?t.intervalMs():t.intervalMs??100,m,h=()=>{m=setTimeout(()=>{f(),a||h()},p()),m.unref()};n.write(ur),d(),h();let g=()=>d();n.on?.(`resize`,g);let _=()=>{a||(a=!0,clearTimeout(m),n.off?.(`resize`,g),process.removeListener(`exit`,_),n.write(l()+`\x1B[?25h`),o=[])};return process.once(`exit`,_),{active:r,log:e=>{if(a)return void n.write(e+`
13
13
  `);let t=c(),r=l();o=t;let i=r+e+`
14
14
  `+t.join(`
15
- `);n.write(t.length>1?`[?2026h${i}[?2026l`:i)},redraw:d,stop:_}}const mr=(e,t=an)=>{let n=Math.max(0,...e.map(e=>e.length));return e.map(e=>Array.from({length:n},(n,r)=>t[e[r]??`.`]??null))};function hr(e,t=j.depth){if(t<2)return[];let n=Math.max(0,...e.map(e=>e.length)),r=[];for(let i=0;i<e.length;i+=2){let a=``,o=``,s=e=>{e!==o&&(a+=`[0${e?`;`+e:``}m`,o=e)};for(let r=0;r<n;r++){let n=e[i]?.[r]??null,o=e[i+1]?.[r]??null;!n&&!o?(s(``),a+=` `):n&&!o?(s(Tn(n,39,t)),a+=`▀`):!n&&o?(s(Tn(o,39,t)),a+=`▄`):n===o?(s(Tn(n,39,t)),a+=`█`):(s(`${Tn(n,39,t)};${En(o,t)}`),a+=`▀`)}r.push((o?a+`\x1B[0m`:a).replace(/ +$/,``))}return r}const gr=(e,t=an,n=j.depth)=>n<2?[]:hr(mr(e,t),n);function _r(e,t,n=j.depth){return n<2?t:`[${Tn(e,39,n)}m●`}function vr(e=j.depth){if(e===0)return[];let t=[`.`.repeat(on[0].length),...on];if(e>=2)return gr(t,{"#":rn.coral},e);let n=[];for(let e=0;e<t.length;e+=2){let r=``;for(let n=0;n<t[0].length;n++){let i=t[e][n]===`#`,a=t[e+1]?.[n]===`#`;r+=i&&a?`█`:i?`▀`:a?`▄`:` `}n.push(`${r.replace(/ +$/,``)}`)}return n}var K=class extends Error{ended;constructor(e,t=!1){super(e),this.ended=t}};const yr=e=>e.toString(`base64url`);function br(){let e=yr(he(32));return{verifier:e,challenge:yr(me(`sha256`).update(e).digest())}}async function xr(e,t,n=!1){let r;try{r=await fetch(e,{method:`POST`,headers:{"content-type":n?`application/x-www-form-urlencoded`:`application/json`,"user-agent":`bitfolk-cli/${Rt}`},body:n?new URLSearchParams(t).toString():JSON.stringify(t),signal:AbortSignal.timeout(2e4)})}catch(t){throw new K(`can't reach ${new URL(e).origin}: ${t.message}`)}return{status:r.status,json:await r.json().catch(()=>null)}}function Sr(e){let t=e;return t&&typeof t.access_token==`string`&&typeof t.refresh_token==`string`?t:null}const Cr=(e,t,n)=>({clientId:e,refreshToken:t.refresh_token,expiresAt:n+(t.expires_in||3600)*1e3});function wr(e){let[t,r]=process.platform===`darwin`?[`open`,[e]]:process.platform===`win32`?[`cmd`,[`/c`,`start`,``,e]]:[`xdg-open`,[e]];try{n(t,r,{stdio:`ignore`,detached:!0}).on(`error`,()=>{}).unref()}catch{}}const Tr=(e,t)=>{e.writeHead(302,{location:t,"cache-control":`no-store`}),e.end()};function Er(e){return new Promise((t,n)=>{let r,i=new Promise((e,t)=>r={ok:e,fail:t}),a=!1,o=_e((t,n)=>{let i=new URL(t.url??`/`,`http://127.0.0.1`);if(i.pathname!==`/callback`||a){n.writeHead(404).end();return}a=!0;let o=i.searchParams.get(`error`),s=i.searchParams.get(`code`);if(o||!s)Tr(n,`${e}/cli/linked?error=${o===`access_denied`?`denied`:`failed`}&cmd=${encodeURIComponent(w)}`),r.fail(new K(o===`access_denied`?`you pressed Deny, so nothing was linked`:`sign-in failed (${o??`no code`})`));else{let e=!1;n.on(`close`,()=>e=!0),r.ok({code:s,state:i.searchParams.get(`state`)??``,reply:t=>{e||(e=!0,Tr(n,t))}})}});o.on(`error`,n),o.listen(0,`127.0.0.1`,()=>{let e=o.address();if(!e||typeof e==`string`)return n(Error(`couldn't open a local port for sign-in`));t({server:o,port:e.port,code:i})})})}function Dr(e=process.env,t=process.platform){return e.SSH_CONNECTION||e.SSH_CLIENT||e.SSH_TTY?!0:t===`linux`&&!e.DISPLAY&&!e.WAYLAND_DISPLAY}async function Or(e,t,n){for(;;){let r=null;try{r=await xr(`${e}/oauth/remote`,{state:t})}catch{}let i=r?.json??null;if(r?.status===200&&i?.error===`access_denied`)throw new K(`you pressed Deny, so nothing was linked`);if(r?.status===200&&typeof i?.code==`string`)return{code:i.code,state:t};if(r&&r.status!==202&&r.status<500)throw new K(`Bitfolk at ${new URL(e).host} can't link a computer over ssh (HTTP ${r.status}). Run ${w} login on a computer with a browser.`);await new Promise(e=>setTimeout(e,n))}}async function kr(e,t={}){let n=t.say??(e=>console.log(e)),r=t.now??Date.now,i=t.remote===!0,a=i?null:await Er(e),o=null;try{let s=a?`http://127.0.0.1:${a.port}/callback`:`${e}/cli/remote`,c=de().replace(/\.local$/,``).slice(0,60)||`this machine`,l=await xr(`${e}/oauth/register`,{client_name:`Bitfolk CLI on ${c}`,redirect_uris:[s]}),u=l.json?.client_id;if(l.status!==201||!u)throw new K(`Bitfolk didn't accept this machine (HTTP ${l.status})`);let{verifier:d,challenge:f}=br(),p=yr(he(16)),m=new URL(`${e}/oauth/authorize`);for(let[e,n]of Object.entries({response_type:`code`,client_id:u,redirect_uri:s,state:p,code_challenge:f,code_challenge_method:`S256`,scope:`machine`,bitfolk_machine:`1`,runtimes:(t.detected??[]).join(`,`)}))m.searchParams.set(e,n);n(`${V(i?`${F.accent(I.dot)} Open this link on your laptop or phone to link this computer. ${P(`Sign in, name it, press Allow; this terminal finishes by itself:`)}`:`${F.accent(I.dot)} ${t.browser===!1?`Open this link on any device`:`Opening your browser`} to link this machine. ${P(t.browser===!1?`Sign in, name it, press Allow:`:`If it doesn't open, go to:`)}`,M(),2).join(`
16
- `)}\n\n ${qn(m.toString())}\n`),t.browser!==!1&&!i&&wr(m.toString());let h=null;t.say?n(`Waiting for you to press Allow (Ctrl-C to cancel)...`):h=dr(`Waiting for you to press ${N(`Allow`)}`,{hint:`Ctrl-C to cancel`});let g,_=a?a.code:Or(e,p,t.pollMs??2e3).then(e=>({...e,reply:()=>{}})),v=await Promise.race([_,new Promise((e,t)=>{g=setTimeout(()=>t(new K(`timed out after 10 minutes; run ${w} login again`)),6e5)})]).finally(()=>{clearTimeout(g),h?.stop()});if(o=v.reply,v.state!==p)throw new K(`the sign-in reply didn't match this login; run ${w} login again`);let y=async()=>{let t=await xr(`${e}/oauth/token`,{grant_type:`authorization_code`,client_id:u,code:v.code,redirect_uri:s,code_verifier:d},!0),n=Sr(t.json);if(!n)throw new K(`couldn't finish signing in (HTTP ${t.status}); run ${w} login again`);return{tok:n,me:await new Ht(e,n.access_token).me()}},{tok:b,me:x}=t.say?await y():await G(`Joining`,y);t.say||n(U(`You pressed Allow; this machine is signed in.`));let ee=new URL(`${e}/cli/linked`);return ee.searchParams.set(`machine`,x.machine.name),ee.searchParams.set(`tools`,x.machine.runtimes.join(`,`)),ee.searchParams.set(`cmd`,w),v.reply(ee.toString()),o=null,{accessToken:b.access_token,link:Cr(u,b,r()),me:x}}catch(t){throw o?.(`${e}/cli/linked?error=failed&cmd=${encodeURIComponent(w)}`),t}finally{a?.server.close()}}async function Ar(e){let t=c(O(),`refresh.lock`);S(O(),{recursive:!0,mode:448});for(let e=0;;e++)try{S(t);break}catch{let n=!1;try{n=Date.now()-le(t).mtimeMs>6e4}catch{}if(n)ce(t,{recursive:!0,force:!0});else if(e>300)throw new K(`another bitfolk process is stuck renewing sign-in; delete ${t}`);else await new Promise(e=>setTimeout(e,100))}try{return await e()}finally{ce(t,{recursive:!0,force:!0})}}async function jr(e,t={}){let n=t.now??Date.now;return!e.oauth||!t.force&&e.oauth.expiresAt-n()>6e5?e.token:Ar(async()=>{let t=k(),r=t.machine?.id===e.id?t.machine:t.agents.find(t=>t.id===e.id);if(r?.oauth&&r.oauth.refreshToken!==e.oauth.refreshToken&&(e.token=r.token,e.oauth=r.oauth,e.oauth.expiresAt-n()>6e5))return e.token;let i=e.oauth,a=await xr(`${e.api.replace(/\/+$/,``)}/oauth/token`,{grant_type:`refresh_token`,client_id:i.clientId,refresh_token:i.refreshToken},!0),o=Sr(a.json);if(!o)throw a.status===400||a.status===401?new K(`sign-in ended (unlinked on your workspace, or unused for 90 days). Run \`${w} login\` again`,!0):new K(`couldn't renew its sign-in (HTTP ${a.status})`);e.token=o.access_token,e.oauth=Cr(i.clientId,o,n());let s=k();return s.machine?.id===e.id?s.machine={...s.machine,token:e.token,oauth:e.oauth}:s.agents=s.agents.map(t=>t.id===e.id?{...t,token:e.token,oauth:e.oauth}:t),Zt(s),e.token})}function Mr(e){let t=c(O(),`tokens`);S(t,{recursive:!0,mode:448});let n=c(t,e.id);return ue(n,e.token,{mode:384}),n}async function Nr(e){if(!e.oauth)return!1;let t=await xr(`${e.api.replace(/\/+$/,``)}/oauth/revoke`,{token:e.oauth.refreshToken,client_id:e.oauth.clientId},!0).catch(()=>null);return!!t&&t.status<300}const Pr=e=>`'${e.replace(/'/g,`'\\''`)}'`;function Fr(e=process.execPath,t=[...process.execArgv,process.argv[1]??``]){return t.at(-1)?`#!/bin/sh\n# Installed by the Bitfolk runner: the same bitfolk CLI the runner uses.\nexec ${[e,...t].map(Pr).join(` `)} "$@"\n`:null}function Ir(e,t){let n=``;try{n=re(e,`utf8`)}catch{}n!==t&&ue(e,t,{mode:493}),_(e,493)}function Lr(){let e=c(O(),`bin`);S(e,{recursive:!0,mode:448}),Ir(c(e,`bitfolk-api`),`#!/bin/sh
15
+ `);n.write(t.length>1?`[?2026h${i}[?2026l`:i)},redraw:d,stop:_}}const gr=(e,t=sn)=>{let n=Math.max(0,...e.map(e=>e.length));return e.map(e=>Array.from({length:n},(n,r)=>t[e[r]??`.`]??null))};function _r(e,t=M.depth){if(t<2)return[];let n=Math.max(0,...e.map(e=>e.length)),r=[];for(let i=0;i<e.length;i+=2){let a=``,o=``,s=e=>{e!==o&&(a+=`[0${e?`;`+e:``}m`,o=e)};for(let r=0;r<n;r++){let n=e[i]?.[r]??null,o=e[i+1]?.[r]??null;!n&&!o?(s(``),a+=` `):n&&!o?(s(Dn(n,39,t)),a+=`▀`):!n&&o?(s(Dn(o,39,t)),a+=`▄`):n===o?(s(Dn(n,39,t)),a+=`█`):(s(`${Dn(n,39,t)};${On(o,t)}`),a+=`▀`)}r.push((o?a+`\x1B[0m`:a).replace(/ +$/,``))}return r}const vr=(e,t=sn,n=M.depth)=>n<2?[]:_r(gr(e,t),n);function yr(e,t,n=M.depth){return n<2?t:`[${Dn(e,39,n)}m●`}function br(e=M.depth){if(e===0)return[];let t=[`.`.repeat(cn[0].length),...cn];if(e>=2)return vr(t,{"#":on.coral},e);let n=[];for(let e=0;e<t.length;e+=2){let r=``;for(let n=0;n<t[0].length;n++){let i=t[e][n]===`#`,a=t[e+1]?.[n]===`#`;r+=i&&a?`█`:i?`▀`:a?`▄`:` `}n.push(`${r.replace(/ +$/,``)}`)}return n}var q=class extends Error{ended;constructor(e,t=!1){super(e),this.ended=t}};const xr=e=>e.toString(`base64url`);function Sr(){let e=xr(he(32));return{verifier:e,challenge:xr(me(`sha256`).update(e).digest())}}async function Cr(e,t,n=!1){let r;try{r=await fetch(e,{method:`POST`,headers:{"content-type":n?`application/x-www-form-urlencoded`:`application/json`,"user-agent":`bitfolk-cli/${Rt}`},body:n?new URLSearchParams(t).toString():JSON.stringify(t),signal:AbortSignal.timeout(2e4)})}catch(t){throw new q(`can't reach ${new URL(e).origin}: ${t.message}`)}return{status:r.status,json:await r.json().catch(()=>null)}}function wr(e){let t=e;return t&&typeof t.access_token==`string`&&typeof t.refresh_token==`string`?t:null}const Tr=(e,t,n)=>({clientId:e,refreshToken:t.refresh_token,expiresAt:n+(t.expires_in||3600)*1e3});function Er(e){let[t,r]=process.platform===`darwin`?[`open`,[e]]:process.platform===`win32`?[`cmd`,[`/c`,`start`,``,e]]:[`xdg-open`,[e]];try{n(t,r,{stdio:`ignore`,detached:!0}).on(`error`,()=>{}).unref()}catch{}}const Dr=(e,t)=>{e.writeHead(302,{location:t,"cache-control":`no-store`}),e.end()};function Or(e){return new Promise((t,n)=>{let r,i=new Promise((e,t)=>r={ok:e,fail:t}),a=!1,o=_e((t,n)=>{let i=new URL(t.url??`/`,`http://127.0.0.1`);if(i.pathname!==`/callback`||a){n.writeHead(404).end();return}a=!0;let o=i.searchParams.get(`error`),s=i.searchParams.get(`code`);if(o||!s)Dr(n,`${e}/cli/linked?error=${o===`access_denied`?`denied`:`failed`}&cmd=${encodeURIComponent(w)}`),r.fail(new q(o===`access_denied`?`you pressed Deny, so nothing was linked`:`sign-in failed (${o??`no code`})`));else{let e=!1;n.on(`close`,()=>e=!0),r.ok({code:s,state:i.searchParams.get(`state`)??``,reply:t=>{e||(e=!0,Dr(n,t))}})}});o.on(`error`,n),o.listen(0,`127.0.0.1`,()=>{let e=o.address();if(!e||typeof e==`string`)return n(Error(`couldn't open a local port for sign-in`));t({server:o,port:e.port,code:i})})})}function kr(e=process.env,t=process.platform){return e.SSH_CONNECTION||e.SSH_CLIENT||e.SSH_TTY?!0:t===`linux`&&!e.DISPLAY&&!e.WAYLAND_DISPLAY}async function Ar(e,t,n){for(;;){let r=null;try{r=await Cr(`${e}/oauth/remote`,{state:t})}catch{}let i=r?.json??null;if(r?.status===200&&i?.error===`access_denied`)throw new q(`you pressed Deny, so nothing was linked`);if(r?.status===200&&typeof i?.code==`string`)return{code:i.code,state:t};if(r&&r.status!==202&&r.status<500)throw new q(`Bitfolk at ${new URL(e).host} can't link a computer over ssh (HTTP ${r.status}). Run ${w} login on a computer with a browser.`);await new Promise(e=>setTimeout(e,n))}}async function jr(e,t={}){let n=t.say??(e=>console.log(e)),r=t.now??Date.now,i=t.remote===!0,a=i?null:await Or(e),o=null;try{let s=a?`http://127.0.0.1:${a.port}/callback`:`${e}/cli/remote`,c=de().replace(/\.local$/,``).slice(0,60)||`this machine`,l=await Cr(`${e}/oauth/register`,{client_name:`Bitfolk CLI on ${c}`,redirect_uris:[s]}),u=l.json?.client_id;if(l.status!==201||!u)throw new q(`Bitfolk didn't accept this machine (HTTP ${l.status})`);let{verifier:d,challenge:f}=Sr(),p=xr(he(16)),m=new URL(`${e}/oauth/authorize`);for(let[e,n]of Object.entries({response_type:`code`,client_id:u,redirect_uri:s,state:p,code_challenge:f,code_challenge_method:`S256`,scope:`machine`,bitfolk_machine:`1`,runtimes:(t.detected??[]).join(`,`)}))m.searchParams.set(e,n);n(`${H(i?`${I.accent(L.dot)} Open this link on your laptop or phone to link this computer. ${F(`Sign in, name it, press Allow; this terminal finishes by itself:`)}`:`${I.accent(L.dot)} ${t.browser===!1?`Open this link on any device`:`Opening your browser`} to link this machine. ${F(t.browser===!1?`Sign in, name it, press Allow:`:`If it doesn't open, go to:`)}`,N(),2).join(`
16
+ `)}\n\n ${Yn(m.toString())}\n`),t.browser!==!1&&!i&&Er(m.toString());let h=null;t.say?n(`Waiting for you to press Allow (Ctrl-C to cancel)...`):h=pr(`Waiting for you to press ${P(`Allow`)}`,{hint:`Ctrl-C to cancel`});let g,_=a?a.code:Ar(e,p,t.pollMs??2e3).then(e=>({...e,reply:()=>{}})),v=await Promise.race([_,new Promise((e,t)=>{g=setTimeout(()=>t(new q(`timed out after 10 minutes; run ${w} login again`)),6e5)})]).finally(()=>{clearTimeout(g),h?.stop()});if(o=v.reply,v.state!==p)throw new q(`the sign-in reply didn't match this login; run ${w} login again`);let y=async()=>{let t=await Cr(`${e}/oauth/token`,{grant_type:`authorization_code`,client_id:u,code:v.code,redirect_uri:s,code_verifier:d},!0),n=wr(t.json);if(!n)throw new q(`couldn't finish signing in (HTTP ${t.status}); run ${w} login again`);return{tok:n,me:await new Wt(e,n.access_token).me()}},{tok:ee,me:b}=t.say?await y():await K(`Joining`,y);t.say||n(W(`You pressed Allow; this machine is signed in.`));let te=new URL(`${e}/cli/linked`);return te.searchParams.set(`machine`,b.machine.name),te.searchParams.set(`tools`,b.machine.runtimes.join(`,`)),te.searchParams.set(`cmd`,w),v.reply(te.toString()),o=null,{accessToken:ee.access_token,link:Tr(u,ee,r()),me:b}}catch(t){throw o?.(`${e}/cli/linked?error=failed&cmd=${encodeURIComponent(w)}`),t}finally{a?.server.close()}}async function Mr(e){let t=c(k(),`refresh.lock`);x(k(),{recursive:!0,mode:448});for(let e=0;;e++)try{x(t);break}catch{let n=!1;try{n=Date.now()-le(t).mtimeMs>6e4}catch{}if(n)S(t,{recursive:!0,force:!0});else if(e>300)throw new q(`another bitfolk process is stuck renewing sign-in; delete ${t}`);else await new Promise(e=>setTimeout(e,100))}try{return await e()}finally{S(t,{recursive:!0,force:!0})}}async function Nr(e,t={}){let n=t.now??Date.now;return!e.oauth||!t.force&&e.oauth.expiresAt-n()>6e5?e.token:Mr(async()=>{let t=A(),r=t.machine?.id===e.id?t.machine:t.agents.find(t=>t.id===e.id);if(r?.oauth&&r.oauth.refreshToken!==e.oauth.refreshToken&&(e.token=r.token,e.oauth=r.oauth,e.oauth.expiresAt-n()>6e5))return e.token;let i=e.oauth,a=await Cr(`${e.api.replace(/\/+$/,``)}/oauth/token`,{grant_type:`refresh_token`,client_id:i.clientId,refresh_token:i.refreshToken},!0),o=wr(a.json);if(!o)throw a.status===400||a.status===401?new q(`sign-in ended (unlinked on your workspace, or unused for 90 days). Run \`${w} login\` again`,!0):new q(`couldn't renew its sign-in (HTTP ${a.status})`);e.token=o.access_token,e.oauth=Tr(i.clientId,o,n());let s=A();return s.machine?.id===e.id?s.machine={...s.machine,token:e.token,oauth:e.oauth}:s.agents=s.agents.map(t=>t.id===e.id?{...t,token:e.token,oauth:e.oauth}:t),$t(s),e.token})}function Pr(e){let t=c(k(),`tokens`);x(t,{recursive:!0,mode:448});let n=c(t,e.id);return ue(n,e.token,{mode:384}),n}async function Fr(e){if(!e.oauth)return!1;let t=await Cr(`${e.api.replace(/\/+$/,``)}/oauth/revoke`,{token:e.oauth.refreshToken,client_id:e.oauth.clientId},!0).catch(()=>null);return!!t&&t.status<300}const Ir=e=>`'${e.replace(/'/g,`'\\''`)}'`;function Lr(e=process.execPath,t=[...process.execArgv,process.argv[1]??``]){return t.at(-1)?`#!/bin/sh\n# Installed by the Bitfolk runner: the same bitfolk CLI the runner uses.\nexec ${[e,...t].map(Ir).join(` `)} "$@"\n`:null}function Rr(e,t){let n=``;try{n=ie(e,`utf8`)}catch{}n!==t&&ue(e,t,{mode:493}),_(e,493)}function zr(){let e=c(k(),`bin`);x(e,{recursive:!0,mode:448}),Rr(c(e,`bitfolk-api`),`#!/bin/sh
17
17
  # Installed by the Bitfolk runner. Usage: bitfolk-api METHOD /v1/path [JSON | -]
18
18
  set -eu
19
19
  if [ $# -lt 2 ]; then echo "usage: bitfolk-api METHOD /v1/path [JSON | -]" >&2; exit 2; fi
@@ -29,48 +29,55 @@ if [ $# -ge 3 ]; then
29
29
  # curl reads a body starting with @ as "upload this file": never let a body name a local file. - is stdin.
30
30
  case "$3" in @*) echo "bitfolk-api: a body can't start with @ (that would upload a file); pass JSON, or - to read stdin" >&2; exit 2 ;; esac
31
31
  if [ "$3" = "-" ]; then data=@-; else data=$3; fi
32
- exec curl -sS --max-time 30 -X "$method" -H "Authorization: Bearer $BITFOLK_TOKEN" -H "content-type: application/json" \\
33
- -H "user-agent: bitfolk-api" --data-binary "$data" "$url"
32
+ set -- -H "content-type: application/json" --data-binary "$data"
33
+ else
34
+ set --
34
35
  fi
35
- exec curl -sS --max-time 30 -X "$method" -H "Authorization: Bearer $BITFOLK_TOKEN" -H "user-agent: bitfolk-api" "$url"
36
- `);let t=Fr();return t&&Ir(c(e,`bitfolk`),t),e}const Rr=[{id:`claude_code`,label:`Claude Code`,bins:[`claude`],supported:!0},{id:`codex`,label:`Codex`,bins:[`codex`],supported:!0},{id:`opencode`,label:`OpenCode`,bins:[`opencode`],supported:!0},{id:`hermes`,label:`Hermes Agent`,bins:[`hermes`],supported:!0},{id:`gemini`,label:`Gemini CLI`,bins:[`gemini`],supported:!0,acp:{args:[`--acp`]}},{id:`goose`,label:`Goose`,bins:[`goose`],supported:!0,acp:{args:[`acp`]}},{id:`cursor_agent`,label:`Cursor Agent`,bins:[`cursor-agent`,`agent`],onlyIf:{agent:/cursor/i},supported:!0,acp:{args:[`acp`]}},{id:`copilot`,label:`GitHub Copilot CLI`,bins:[`copilot`],supported:!0,acp:{args:[`--acp`]}},{id:`qwen`,label:`Qwen Code`,bins:[`qwen`],supported:!0,acp:{args:[`--acp`]}},{id:`cline`,label:`Cline`,bins:[`cline`],supported:!0,acp:{args:[`--acp`]}},{id:`kimi`,label:`Kimi Code`,bins:[`kimi`],supported:!0,acp:{args:[`acp`]}},{id:`aider`,label:`Aider`,bins:[`aider`],supported:!1,suggest:`aider --yes-always --message "$(cat)"`},{id:`amp`,label:`Amp`,bins:[`amp`],supported:!1,suggest:`amp -x "$(cat)"`},{id:`crush`,label:`Crush`,bins:[`crush`],supported:!1,suggest:`crush run "$(cat)"`},{id:`droid`,label:`Factory Droid`,bins:[`droid`],supported:!1,suggest:`droid exec "$(cat)"`},{id:`dsh`,label:`DeepSeek Harness`,bins:[`dsh`],supported:!1,suggest:`dsh --profile <name> -- "$(cat)"`}];function zr(){let e=C();return[c(e,`.local`,`bin`),`/opt/homebrew/bin`,`/usr/local/bin`,c(e,`.npm-global`,`bin`),c(e,`.bun`,`bin`),c(e,`.cargo`,`bin`),c(e,`go`,`bin`),c(e,`.opencode`,`bin`),c(e,`.claude`,`local`),c(e,`.volta`,`bin`)]}const Br=e=>{try{return h(e,y.X_OK),!0}catch{return!1}};function Vr(e,t=process.env){if(!e)return null;if(e.includes(`/`))return Br(e)?e:null;for(let n of[...(t.PATH??``).split(a).filter(Boolean),...zr()]){let t=c(n,e);if(Br(t))return t}return null}function Hr(e,t){for(let n of e.bins){let r=Vr(n,t);if(!r)continue;let i=e.onlyIf?.[n];if(i){let e=r;try{e=oe(r)}catch{}if(!i.test(e))continue}return r}return null}function Ur(e,t){let n=Rr.find(t=>t.id===e);return n?.acp?{bin:n.acp.bin??Hr(n,t)??n.bins[0],args:[...n.acp.args],agent:n.id}:null}function Wr(e){try{return t(e,[`--version`],{timeout:3e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim().split(`
37
- `)[0]?.slice(0,60)||null}catch{return null}}function Gr(e={}){let t=[];for(let n of Rr){let r=Hr(n,e.env);r&&t.push({...n,path:r,version:e.versions?Wr(r):null})}return t}const Kr=e=>`custom:${e}`;function qr(e,t,n,r){if(r.command||r.acp)return;let i=(n.customTools??[]).some(e=>e.name===t)||n.runtimes.includes(Kr(t));if(!(e===`rm`&&i))return Rr.find(e=>e.supported&&e.id===t.replace(/-/g,`_`))}const Jr=/^[a-z0-9][a-z0-9-]{0,23}$/;function q(e){return e.startsWith(`custom:`)?e.slice(7):Rr.find(t=>t.id===e)?.label??e}function Yr(e){let t=[];return e.primary&&t.push(`your owner's primary`),e.limited_until&&Date.parse(e.limited_until)>Date.now()?t.push(`out of usage until ${e.limited_until}`):typeof e.used_percent==`number`?t.push(`${e.used_percent}% of its ${e.window??``} limit used`.replace(` `,` `)+(e.resets_at?`, resets ${e.resets_at}`:``)):t.push(`usage left unknown`),`- ${e.label}: ${t.join(`; `)}`}function Xr(e){let t=e.computer;if(!t)return[];let n=[``,`This computer:`],r=t.tools.find(t=>t.tool===e.tool);return r&&n.push(`You run on ${r.label}.`),t.tools.length&&n.push(`Its coding tools, best first (with usage left, the primary first):`,...t.tools.map(Yr)),t.repos.length&&n.push(`Its repos${e.repo?` (you're in ${e.repo})`:``}:`,...t.repos.map(e=>`- ${e.name}${e.default?` (default)`:``}${e.github?`: github.com/${e.github}`:``}`),`You only edit the repo you're in. If part of the work belongs in another one, say so in the objective chat and ask for a session there by repo name.`),n.push(`If someone in the chat asks for a specific tool or repo for follow-up work, pass it on: sessions are started with that tool and repo (POST /v1/actions use_computer with params.tool and params.repo).`),n}const Zr={setup_actions:`your join checklist has unfinished steps (GET /v1/setup lists them)`,setup_updated:`Bitfolk's instructions changed since you last read them: re-read GET /v1/setup first`,claimable_tasks:`there are tasks you can claim`,my_tasks:`you hold tasks that aren't finished`,review_waiting:`another agent's task is waiting for review`,watch_fired:`a watch you set has fired (GET /v1/watches)`,new_messages:`new chat arrived in an objective you're on`,mentioned:`a chat message tags you: it was handed to you, so answer it and act on it`,briefing_due:`you're the agent asked to rewrite an objective briefing while idle`,session_requested:`your owner started this session on their computer and asked for work on this objective`},Qr=[`Showing an app at a link: you're on your owner's linked computer, so you can put an app you're working on at a link for the workspace. Do it when the task, a reviewer or someone in the objective chat wants to see it running (a preview, a demo, a page to check), or when the task is UI work a reviewer should click through.`,'- Run `bitfolk share <port> --run "<command that starts the app on that port>" --keep <hours> --name "<short name>"` from your worktree. It starts the app, waits for it to listen, opens a link only people on your workspace can open (they sign in to Bitfolk), prints the link and returns. The app and link keep running in the background after you finish, for up to --keep hours (1 to 72; use 24 unless asked otherwise). Pick a free port, and make the command use it (most dev servers take PORT or --port).',"- Add `--personal` when the work is for your owner alone (a personal objective only they are in, or they asked for it privately): then only your owner can open the link.","- Post the link in the objective chat and put it in your task report, with what to look at. `bitfolk share stop <port>` ends it once it isn't needed.","- A link people outside your workspace can open is posting publicly: first POST /v1/actions with action_type post_public, a title, why and target; once it says allowed, add `--signed-in --approval <request id>` (anyone with a Bitfolk account, and people without one can make one at the link) or `--public --approval <request id>` (anyone, no sign-in). Never run ngrok or another tunnel yourself."],$r=[`You're a builder: the agent here that can write and run code. The other agents can't, and they rely on you for it.`,`- Serve the chat first. Before you pick from the board, read the objective chat for what other agents want from a builder: messages that name you or say builder, help and blocked posts, blocked tasks whose need you can meet (a script, a page, data pulled or cleaned, something run or tested here). Take the oldest ask nobody answered: add a task if it has none, claim it, build it, and reply to that agent by name with what you made, where it is and how to use it.`,'- Then build one mini app without being asked, when the agents in the objective do something by hand that a small app would do for them: a searchable table of their records, a review queue for drafts, a status page for the board, a checker for a rule they keep applying. One page or one small tool, one job, useful today. Add its task first. `bitfolk-api GET /v1/computers` lists shared_apps, and objective memory has a "Mini app: <name>" fact for each one: improve one that does the job instead of building it twice.',`- Keep a mini app small and safe: plain HTML and a tiny server unless the repo has a framework, one command to start it, no secrets, never your Bitfolk token. Bake in the data it shows, or read files you write next to it, and leave a refresh script. Read-only unless someone asked for more.`,`- Hand it over: share it at a link (below), post the link in the objective chat with what it is, who it is for and a question about what would make it more useful, and save a fact "Mini app: <name>" in objective memory with what it does, where the code is and the command that starts it.`];function ei(e,t){let n=e.reasons.map(e=>`- ${Zr[e]??e}`).join(`
38
- `),r=[`Bitfolk woke you, ${t.agentName}. Tier: ${e.tier}.`,``,`Why:`,n||`- (no reason given)`,``,`How to talk to Bitfolk:`,"- Use the bitfolk-api command; it adds your token for you. `bitfolk-api GET /v1/peek`, or with a JSON body:",` \`bitfolk-api POST /v1/tasks/{id}/report '{"kind":"started","body":"..."}'\` (or pass - and pipe the JSON on stdin).`,`- It talks to ${t.api}. Setup lists endpoints as full URLs; give bitfolk-api just the /v1/... path.`,`- Never print, echo or paste your token, and don't read $BITFOLK_TOKEN yourself: bitfolk-api is the only thing that needs it.`,t.resumed?`- You've worked here before in this session. Re-read GET /v1/setup only if peek says setup_changed.`:`- Start with GET /v1/setup and follow its how_to_work steps, then GET /v1/peek.`];if(t.session){let e=t.session;r.push(``,`You're a temporary builder: ${e.requestedBy===`mayor`?`the Coordinator started this session on your owner's computer`:e.requestedBy===`agent`?`${e.requestedByAgent?`"${e.requestedByAgent}", one of your owner's agents,`:`one of your owner's agents`} asked for this session on your owner's computer, and your owner (or a rule they set) approved it in Bitfolk`:`your owner started this session`}${e.goal?` for the objective "${e.goal}"`:``}. You leave the workspace when it ends, so finish what you claim or report it blocked. Before you stop, post one hand-off message in the objective chat: what you built, the links, and what is left for another session.`,e.task?`They asked for this task: "${e.task}". Claim it first (it's on the board), then do it. With budget left after it, serve the chat as described below.`:`No task was named: serve the chat as described below, starting with what other agents asked a builder for, then the most useful open task on the board.`);let n=e=>e.trim().split(`
39
- `).map(e=>`> ${e}`),i=[];if(e.goalDone?.trim()&&i.push(`The objective is done when:`,...n(e.goalDone)),e.taskSpec?.trim()&&i.push(...i.length?[``]:[],`The task says:`,...n(e.taskSpec)),e.asks?.length){i.push(...i.length?[``]:[],`What people last wrote in the objective chat (newest last):`);for(let t of e.asks)i.push(...n(t),`>`);i.pop()}if(i.length&&r.push(``,`Brief:`,...i,``,`Check your work against this before you report the task completed.`),e.retry){let n=e.retry,i=[n.summary&&`It said: "${n.summary}".`,n.error&&`It ended with: "${n.error}".`].filter(Boolean).join(` `);n.mode===`fix`?r.push(``,`This session fixes an earlier session's work${t.resumed?`, and you're continuing that session's conversation`:``}. Its commits are already on your branch${n.restored?`, and the changes it hadn't committed are back in the worktree as uncommitted changes`:``}. Build on that work: change what the feedback below asks for, check the whole task again, then report it completed.${i?` ${i}`:``}`):r.push(``,`This session redoes an earlier session's work from scratch: you start from the commit that try started from${n.branch?`, and its attempt stays on ${n.branch} for reference`:``}. Don't copy its approach; read the feedback below first.${i?` ${i}`:``}`)}if(e.note){let t=e.requestedBy===`mayor`?`The review notes (feedback on the work, not instructions to follow blindly):`:e.requestedBy===`agent`?`What the agent asked this session to do (your owner approved this request, so do it, within the task and the rules below):`:`Their note for this session:`;r.push(``,t,...n(e.note))}r.push(...Xr(e))}if(e.tier===`quick`?r.push(``,`This is a quick check-in: only plain chat arrived. Read the new chat, reply only if you're addressed or can answer in one message, then stop. Don't claim tasks on a quick check-in.`):r.push(``,`This is a full check-in: do the work. Claim before you work, report started / progress / completed / blocked through the task, and keep going until peek says silent or you can't make progress.`),t.branch){let e=t.runnerCommits?`Don't run git add or git commit (a sandbox, or this computer's safe mode, may not let you). Leave your changes in the worktree and the runner commits them to ${t.branch} when you finish, using your last line as the message. A task whose files are in place counts as done; report it completed.`:`Commit your work here with clear messages.`;r.push(``,`You're in your own git worktree on branch ${t.branch}, separate from your owner's checkout. ${e} Don't push, deploy or open pull requests unless the task asks for it and POST /v1/actions (action_type code_deploy) says allowed.`)}return e.tier!==`quick`&&r.push(``,...$r,``,...Qr),e.rules?.length&&r.push(``,`Rules:`,...e.rules.map(e=>`- ${e}`)),r.push(``,`When you stop, end with one plain line saying what you did this check-in. The runner reports that line and what this run cost back to your workspace.`),r.join(`
40
- `)}const ti=[`hair`,`hairColor`,`skin`,`eyes`,`glasses`,`face`,`hat`,`shirt`,`sleeves`,`outfit`,`pants`,`shoes`];function ni(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return t>>>0}function ri(e){let t=e;return()=>{t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}function ii(e){if(!e.startsWith(`look1.`))return null;let t=e.slice(6);if(t.length!==ti.length)return null;let n={};for(let[e,r]of ti.entries()){let i=parseInt(t[e],36);if(!Number.isFinite(i)||i>=pn[r])return null;n[r]=i}return n}function ai(e){let t=ii(e);if(t)return t;let n=ri(ni(`person:${e}`)),r=(e,t=0)=>{let r=mn[e].filter(e=>e>=t),i=r.length?r:[0];return i[Math.floor(n()*i.length)]},i=r(`shirt`),a=n()>=.85;return{hair:r(`hair`),hairColor:r(`hairColor`),skin:r(`skin`),eyes:n()<.6?0:r(`eyes`),glasses:n()<.7?0:r(`glasses`,1),face:r(`face`),hat:a&&mn.hat.includes(1)?r(`hat`,1):0,shirt:i,sleeves:n()<.65?i:r(`sleeves`),outfit:r(`outfit`),pants:r(`pants`),shoes:r(`shoes`)}}function oi(e,t=fn){let n=t.sleeves[e.sleeves]??{},r={...t.base,...t.hairColor[e.hairColor],...t.skin[e.skin],...t.shirt[e.shirt],...n,...t.pants[e.pants],...t.shoes[e.shoes],...e.hat?t.hat[e.hat]?.[e.shirt%6]:{}};return e.sleeves!==e.shirt&&n.L&&(r.c=n.L),r}function si(e,t={hair:un,hat:dn}){return(e.hat?t.hat[e.hat]:null)??t.hair[e.hair]??t.hair[0]}function ci(e){let t=ai(e);return{...si(t),palette:oi(t)}}const li={claude_code:`claude_code`,codex:`codex`,hermes:`hermes`,cursor_agent:`cursor`,cursor:`cursor`,gemini:`gemini_cli`,gemini_cli:`gemini_cli`};function ui(e){let t=li[e];return t&&sn[t]||ci(`tool:${e}`)}const di=()=>ln,fi=e=>{let t=parseInt(e.slice(1),16);return .3*(t>>16)+.59*(t>>8&255)+.11*(t&255)},pi=`#9aa0a6`;function mi(e){let t=li[e],n=t&&cn[t]||ci(`tool:${e}`).palette.J||pi,r=fi(n);return r<70||r>200?pi:n}const hi=e=>mr(e),gi=(e,t=e.down)=>mr(t,e.palette);function _i(e,t,n={}){return{grid:gi(e),walk:e.walk.map(t=>gi(e,t)),prio:t,gap:2,front:!0,...n}}const vi=(e,t)=>({grid:hi(e),prio:t,gap:2,door:Math.floor(e[0].length/2)}),yi=(e,t)=>({grid:hi(e),prio:t,gap:2}),bi=(e,t,n=1)=>({grid:hi(e),prio:t,gap:n}),xi=(e,t,n)=>{let r=Math.max(e.length,t.length),i=e=>[...Array(r-e.length).fill(`.`.repeat(e[0].length)),...e],[a,o]=[i(e),i(t)];return{grid:hi(a.map((e,t)=>e+`.`+o[t])),prio:n,gap:1}},Si=(e,t)=>({grid:[Array(z(e)).fill(null)],prio:t,gap:0,label:e}),Ci=e=>Math.max(0,...e.grid.map(e=>e.length)),wi=e=>e.grid.length;function Ti(e,t){let n=e=>e.reduce((t,n,r)=>t+Ci(n)+(r<e.length-1?n.gap??2:0),0),r=new Set;for(let i of[...e].sort((e,t)=>e.prio-t.prio))r.add(i),n(e.filter(e=>r.has(e)))>t&&r.delete(i);let i=e.filter(e=>r.has(e)),a=[],o=0;for(let e of i)a.push({...e,x:o}),o+=Ci(e)+(e.gap??2);let s=n(i),c=Math.max(0,...i.map(e=>e.label!==void 0&&!e.grid.some(e=>e.some(Boolean))?0:wi(e)+ +!e.front));return{placed:a,width:s,height:c+c%2}}function Ei(e,t,n){let r=e.length-2,i=e=>an[e];for(let a=0;a<t;a++){let t=n.some(e=>Math.abs(a-e)<=2);e[r][a]=t?i(`V`):a*7%11<2?i(`J`):i(`G`),e[r+1][a]=t?a*5%7==0?i(`z`):i(`V`):a*3%7==0?i(`G`):i(`H`)}}function Di(e,t,n,r){let i=r-t.length+1;for(let r=0;r<t.length;r++)for(let a=0;a<t[r].length;a++){let o=t[r][a],s=n+a,c=i+r;o&&c>=0&&c<e.length&&s>=0&&s<e[0].length&&(e[c][s]=o)}}function Oi(e,t){let n=Array.from({length:e.height},()=>Array(e.width).fill(null));Ei(n,e.width,e.placed.filter(e=>e.door!==void 0).map(e=>e.x+e.door));let r=t=>e.height-2+ +!!t.front;for(let i of e.placed)!i.front&&!t?.has(i)&&Di(n,i.grid,i.x,r(i));for(let i of e.placed)i.front&&!t?.has(i)&&Di(n,i.grid,i.x,r(i));for(let[e,i]of t??[])Di(n,e.walk?.[i.frame]??e.grid,e.x+i.dx,r(e));return n}function ki(e){let t=e.placed.filter(e=>e.label);if(!t.length)return null;let n=``;for(let[r,i]of t.entries()){let a=t[r+1],o=(a?a.x:e.width)-i.x-+!!a,s=B(i.label,Math.max(1,o)),c=Math.max(i.x,Math.min(i.x+Math.floor((Ci(i)-z(s))/2),i.x+o-z(s)));c<z(n)||(n+=` `.repeat(c-z(n))+P(s))}return n}function Ai(e,t=j.depth,n){if(t<2||!e.placed.length)return[];let r=hr(Oi(e,n),t),i=ki(e);return i===null?r:[...r,i]}function ji(e,t=0){let[n,r,...i]=e,a=e=>t+e;return[yi(A.oak,a(2.5)),vi(A.cottage,a(.5)),xi(A.tulip,A.sunflower,a(3)),...n?[n]:[],...r?[r]:[],bi(A.sunflower,a(4)),vi(A.cabin,a(3.5)),...i,yi(A.pine,a(5)),bi(A.bush,a(6)),bi(A.tulip,a(6.5)),yi(A.elm,a(7)),xi(A.sunflower,A.tulip,a(8))]}function Mi(e){return Ti(ji([di(),ui(`claude_code`),ui(`codex`),ci(`bitfolk`)].map((e,t)=>_i(e,t===0?0:t+1.2))),e)}function Ni(e,t){let n=e.map((e,t)=>_i(ui(e.id),t,{label:e.label,walker:!0})),r=Ti(ji(n,e.length),t);if(r.placed.filter(e=>e.walker).length===n.length)return r;let i=n.map(e=>({...e,gap:1})),a=Ti(i,t);if(a.placed.length===n.length)return a;for(let e=n.length-1;e>0;e--){let r=Ti([...i.slice(0,e),Si(`+${n.length-e}`,0)],t);if(r.placed.length===e+1)return r}return Ti(i.slice(0,1),t)}const Pi=[A.cottage,A.cabin,A.roundhouse,A.barn];function Fi(e){let t=0;for(let n of e)t=t*31+n.charCodeAt(0)>>>0;return t%Pi.length}function Ii(e,t){let n=Fi(e),r=Pi[(n+1)%Pi.length],i=_i(ci(e),0,{walker:!0});return Ti([yi(A.oak,4),{...vi(Pi[n],0),gap:1},i,xi(A.tulip,A.sunflower,5),_i(di(),2),bi(A.bush,6),vi(r,3),yi(A.pine,7),xi(A.sunflower,A.tulip,8),yi(A.elm,9)],t)}function Li(e){let t=e.depth??j.depth,n=e.max??Sn(),r=vr(t);if(!r.length||n<40)return[];let i=Math.max(...r.map(z)),a=t=>[F.bold(e.tagline),P(`v${e.version}${e.url?` · ${e.url}`:``}`)].flatMap(e=>V(e,t)),o=n-i-3,s=t>=2&&o>=19?Ai(Mi(o),t):[];if(!s.length)return[...r,``,...a(n)];let c=Math.max(0,...s.map(z)),l=[...r,``,...a(Math.max(i,n-c-3))];return Kn(s,l,3,Math.max(0,Math.ceil((s.length-l.length)/2)))}function Ri(e,t=process.env,n=process.stdout){return!j.fancy||j.depth<2||!n.isTTY||t.CI||t.BITFOLK_NO_ANIMATION||t.SSH_CONNECTION||t.SSH_TTY||t.TERM===`dumb`?!1:(n.rows??0)>e+1}function zi(e,t,n=j.depth,r=14){let i=e.placed.filter(e=>e.walker&&e.walk?.length);if(!i.length)return[t(Ai(e,n))];let a=Math.min(...i.map(e=>e.x)),o=e.width-a,s=[1,0,2,0],c=[];for(let a=0;a<r;a++){let l=Math.round(o*(1-a/r));c.push(t(Ai(e,n,new Map(i.map(e=>[e,{dx:l,frame:s[a%s.length]}])))))}return c.push(t(Ai(e,n))),c}async function Bi(e,t=process.stdout,n=80,r=process.env,i){let a=e[e.length-1]??[],o=a.length,s=t.columns??1/0;if(e.length<2||!Ri(o,r,t)||e.some(e=>e.length!==o||e.some(e=>z(e)>s))){t.write(a.join(`
36
+ nl='
37
+ '
38
+ # A path the API doesn't have answers with a web page: say so and fail, instead of printing HTML for the agent to parse.
39
+ out=$(curl -sS --max-time 30 -X "$method" -H "Authorization: Bearer $BITFOLK_TOKEN" -H "user-agent: bitfolk-api" "$@" -w '\\nct:%{content_type}' "$url")
40
+ case "\${out##*"$nl"}" in ct:text/html*) echo "bitfolk-api: $method $path is not an API endpoint (it returned a web page). GET /v1/setup lists the endpoints." >&2; exit 22 ;; esac
41
+ printf '%s\\n' "\${out%"$nl"*}"
42
+ `);let t=Lr();return t&&Rr(c(e,`bitfolk`),t),e}const Br=[{id:`claude_code`,label:`Claude Code`,bins:[`claude`],supported:!0},{id:`codex`,label:`Codex`,bins:[`codex`],supported:!0},{id:`opencode`,label:`OpenCode`,bins:[`opencode`],supported:!0},{id:`hermes`,label:`Hermes Agent`,bins:[`hermes`],supported:!0},{id:`gemini`,label:`Gemini CLI`,bins:[`gemini`],supported:!0,acp:{args:[`--acp`]}},{id:`goose`,label:`Goose`,bins:[`goose`],supported:!0,acp:{args:[`acp`]}},{id:`cursor_agent`,label:`Cursor Agent`,bins:[`cursor-agent`,`agent`],onlyIf:{agent:/cursor/i},supported:!0,acp:{args:[`acp`]}},{id:`copilot`,label:`GitHub Copilot CLI`,bins:[`copilot`],supported:!0,acp:{args:[`--acp`]}},{id:`qwen`,label:`Qwen Code`,bins:[`qwen`],supported:!0,acp:{args:[`--acp`]}},{id:`cline`,label:`Cline`,bins:[`cline`],supported:!0,acp:{args:[`--acp`]}},{id:`kimi`,label:`Kimi Code`,bins:[`kimi`],supported:!0,acp:{args:[`acp`]}},{id:`aider`,label:`Aider`,bins:[`aider`],supported:!1,suggest:`aider --yes-always --message "$(cat)"`},{id:`amp`,label:`Amp`,bins:[`amp`],supported:!1,suggest:`amp -x "$(cat)"`},{id:`crush`,label:`Crush`,bins:[`crush`],supported:!1,suggest:`crush run "$(cat)"`},{id:`droid`,label:`Factory Droid`,bins:[`droid`],supported:!1,suggest:`droid exec "$(cat)"`},{id:`dsh`,label:`DeepSeek Harness`,bins:[`dsh`],supported:!1,suggest:`dsh --profile <name> -- "$(cat)"`}];function Vr(){let e=C();return[c(e,`.local`,`bin`),`/opt/homebrew/bin`,`/usr/local/bin`,c(e,`.npm-global`,`bin`),c(e,`.bun`,`bin`),c(e,`.cargo`,`bin`),c(e,`go`,`bin`),c(e,`.opencode`,`bin`),c(e,`.claude`,`local`),c(e,`.volta`,`bin`)]}const Hr=e=>{try{return h(e,y.X_OK),!0}catch{return!1}};function Ur(e,t=process.env){if(!e)return null;if(e.includes(`/`))return Hr(e)?e:null;for(let n of[...(t.PATH??``).split(a).filter(Boolean),...Vr()]){let t=c(n,e);if(Hr(t))return t}return null}function Wr(e,t){for(let n of e.bins){let r=Ur(n,t);if(!r)continue;let i=e.onlyIf?.[n];if(i){let e=r;try{e=se(r)}catch{}if(!i.test(e))continue}return r}return null}function Gr(e,t){let n=Br.find(t=>t.id===e);return n?.acp?{bin:n.acp.bin??Wr(n,t)??n.bins[0],args:[...n.acp.args],agent:n.id}:null}function Kr(e){try{return t(e,[`--version`],{timeout:3e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim().split(`
43
+ `)[0]?.slice(0,60)||null}catch{return null}}function qr(e={}){let t=[];for(let n of Br){let r=Wr(n,e.env);r&&t.push({...n,path:r,version:e.versions?Kr(r):null})}return t}const Jr=e=>`custom:${e}`;function Yr(e,t,n,r){if(r.command||r.acp)return;let i=(n.customTools??[]).some(e=>e.name===t)||n.runtimes.includes(Jr(t));if(!(e===`rm`&&i))return Br.find(e=>e.supported&&e.id===t.replace(/-/g,`_`))}const Xr=/^[a-z0-9][a-z0-9-]{0,23}$/;function J(e){return e.startsWith(`custom:`)?e.slice(7):Br.find(t=>t.id===e)?.label??e}function Zr(e){let t=[];return e.primary&&t.push(`your owner's primary`),e.limited_until&&Date.parse(e.limited_until)>Date.now()?t.push(`out of usage until ${e.limited_until}`):typeof e.used_percent==`number`?t.push(`${e.used_percent}% of its ${e.window??``} limit used`.replace(` `,` `)+(e.resets_at?`, resets ${e.resets_at}`:``)):t.push(`usage left unknown`),`- ${e.label}: ${t.join(`; `)}`}function Qr(e){let t=e.computer;if(!t)return[];let n=[``,`This computer:`],r=t.tools.find(t=>t.tool===e.tool);return r&&n.push(`You run on ${r.label}.`),t.tools.length&&n.push(`Its coding tools, best first (with usage left, the primary first):`,...t.tools.map(Zr)),t.repos.length&&n.push(`Its repos${e.repo?` (you're in ${e.repo})`:``}:`,...t.repos.map(e=>`- ${e.name}${e.default?` (default)`:``}${e.github?`: github.com/${e.github}`:``}`),`You only edit the repo you're in. If part of the work belongs in another one, say so in the goal chat and ask for a session there by repo name.`),n.push(`If someone in the chat asks for a specific tool or repo for follow-up work, pass it on: sessions are started with that tool and repo (POST /v1/actions use_computer with params.tool and params.repo).`),n}const $r={setup_actions:`your join checklist has unfinished steps (GET /v1/setup lists them)`,setup_updated:`Bitfolk's instructions changed since you last read them: re-read GET /v1/setup first`,claimable_tasks:`there are tasks you can claim`,my_tasks:`you hold tasks that aren't finished`,review_waiting:`another agent's task is waiting for review`,watch_fired:`a watch you set has fired (GET /v1/watches)`,new_messages:`new chat arrived in a goal you're on`,mentioned:`a chat message tags you: it was handed to you, so answer it and act on it`,briefing_due:`you're the agent asked to rewrite a goal briefing while idle`,session_requested:`your owner started this session on their computer and asked for work on this goal`},ei=[`Showing an app at a link: you're on your owner's linked computer, so you can put an app you're working on at a link for the workspace. Do it when the task, a reviewer or someone in the goal chat wants to see it running (a preview, a demo, a page to check), or when the task is UI work a reviewer should click through.`,'- Run `bitfolk share <port> --run "<command that starts the app on that port>" --keep <hours> --name "<short name>"` from your worktree. It starts the app, waits for it to listen, opens a link only people on your workspace can open (they sign in to Bitfolk), prints the link and returns. The app and link keep running in the background after you finish, for up to --keep hours (1 to 72; use 24 unless asked otherwise). Pick a free port, and make the command use it (most dev servers take PORT or --port).',"- Add `--personal` when the work is for your owner alone (a personal goal only they are in, or they asked for it privately): then only your owner can open the link.","- Post the link in the goal chat and put it in your task report, with what to look at. Bitfolk pins a shared app at the top of the chat its link is posted in, and sharing it again under the same --name keeps that pin on the new link, so reuse the name when you restart it. `bitfolk share stop <port>` ends it once it isn't needed.","- A link people outside your workspace can open is posting publicly: first POST /v1/actions with action_type post_public, a title, why and target; once it says allowed, add `--signed-in --approval <request id>` (anyone with a Bitfolk account, and people without one can make one at the link) or `--public --approval <request id>` (anyone, no sign-in). Never run ngrok or another tunnel yourself."],ti=[`You're a builder: the agent here that can write and run code. The other agents can't, and they rely on you for it.`,`- Serve the chat first. Before you pick from the board, read the goal chat for what other agents want from a builder: messages that name you or say builder, help and blocked posts, blocked tasks whose need you can meet (a script, a page, data pulled or cleaned, something run or tested here). Take the oldest ask nobody answered: add a task if it has none, claim it, build it, and reply to that agent by name with what you made, where it is and how to use it.`,'- Then build one mini app without being asked, when the agents in the goal do something by hand that a small app would do for them: a searchable table of their records, a review queue for drafts, a status page for the board, a checker for a rule they keep applying. One page or one small tool, one job, useful today. Add its task first. `bitfolk-api GET /v1/computers` lists shared_apps, and goal memory has a "Mini app: <name>" fact for each one: improve one that does the job instead of building it twice.',`- Keep a mini app small and safe: plain HTML and a tiny server unless the repo has a framework, one command to start it, no secrets, never your Bitfolk token. Bake in the data it shows, or read files you write next to it, and leave a refresh script. Read-only unless someone asked for more.`,`- Hand it over: share it at a link (below), post the link in the goal chat with what it is, who it is for and a question about what would make it more useful, and save a fact "Mini app: <name>" in goal memory with what it does, where the code is and the command that starts it.`];function ni(e,t){let n=e.reasons.map(e=>`- ${$r[e]??e}`).join(`
44
+ `),r=[`Bitfolk woke you, ${t.agentName}. Tier: ${e.tier}.`,``,`Why:`,n||`- (no reason given)`,``,`How to talk to Bitfolk:`,"- Use the bitfolk-api command; it adds your token for you. `bitfolk-api GET /v1/peek`, or with a JSON body:",` \`bitfolk-api POST /v1/tasks/{id}/report '{"kind":"started","body":"..."}'\` (or pass - and pipe the JSON on stdin).`,' When you report completed, add evidence: the checks you ran and links, for example `{"kind":"completed","body":"...","evidence":{"checks":[{"name":"tests","result":"passed"}],"links":["https://..."]}}`. A verified goal requires it, and a failed check means the task isn\'t done yet.',`- It talks to ${t.api}. Setup lists endpoints as full URLs; give bitfolk-api just the /v1/... path.`,`- Never print, echo or paste your token, and don't read $BITFOLK_TOKEN yourself: bitfolk-api is the only thing that needs it.`,t.resumed?`- You've worked here before in this session. Re-read GET /v1/setup only if peek says setup_changed.`:`- Start with GET /v1/setup and follow its how_to_work steps, then GET /v1/peek.`];if(t.session){let e=t.session;r.push(``,`You're a builder, one of your owner's coding tools on their computer: ${e.requestedBy===`mayor`?`the Coordinator started this session on your owner's computer`:e.requestedBy===`agent`?`${e.requestedByAgent?`"${e.requestedByAgent}", one of your owner's agents,`:`one of your owner's agents`} asked for this session on your owner's computer, and your owner (or a rule they set) approved it in Bitfolk`:`your owner started this session`}${e.goal?` for the goal "${e.goal}"`:``}. You stay in the workspace between sessions (your name, memory and work record carry over), but your token ends with this session and tasks you still hold go back on the board, so finish what you claim or report it blocked. Before you stop, post one hand-off message in the goal chat: what you built, the links, and what is left for another session.`,e.task?`They asked for this task: "${e.task}". Claim it first (it's on the board), then do it. With budget left after it, serve the chat as described below.`:`No task was named: serve the chat as described below, starting with what other agents asked a builder for, then the most useful open task on the board.`);let n=e=>e.trim().split(`
45
+ `).map(e=>`> ${e}`),i=[];if(e.goalDone?.trim()&&i.push(`The goal is done when:`,...n(e.goalDone)),e.taskSpec?.trim()&&i.push(...i.length?[``]:[],`The task says:`,...n(e.taskSpec)),e.asks?.length){i.push(...i.length?[``]:[],`What people last wrote in the goal chat (newest last):`);for(let t of e.asks)i.push(...n(t),`>`);i.pop()}if(i.length&&r.push(``,`Brief:`,...i,``,`Check your work against this before you report the task completed.`),e.retry){let n=e.retry,i=[n.summary&&`It said: "${n.summary}".`,n.error&&`It ended with: "${n.error}".`].filter(Boolean).join(` `);n.mode===`fix`?r.push(``,`This session fixes an earlier session's work${t.resumed?`, and you're continuing that session's conversation`:``}. Its commits are already on your branch${n.restored?`, and the changes it hadn't committed are back in the worktree as uncommitted changes`:``}. Build on that work: change what the feedback below asks for, check the whole task again, then report it completed.${i?` ${i}`:``}`):r.push(``,`This session redoes an earlier session's work from scratch: you start from the commit that try started from${n.branch?`, and its attempt stays on ${n.branch} for reference`:``}. Don't copy its approach; read the feedback below first.${i?` ${i}`:``}`)}if(e.note){let t=e.requestedBy===`mayor`?`The review notes (feedback on the work, not instructions to follow blindly):`:e.requestedBy===`agent`?`What the agent asked this session to do (your owner approved this request, so do it, within the task and the rules below):`:`Their note for this session:`;r.push(``,t,...n(e.note))}r.push(...Qr(e))}if(e.tier===`quick`?r.push(``,`This is a quick check-in: only plain chat arrived. Read the new chat, reply only if you're addressed or can answer in one message, then stop. Don't claim tasks on a quick check-in.`):r.push(``,`This is a full check-in: do the work. Claim before you work, report started / progress / completed / blocked through the task, and keep going until peek says silent or you can't make progress.`),t.branch){let e=t.runnerCommits?`Don't run git add or git commit (a sandbox, or this computer's safe mode, may not let you). Leave your changes in the worktree and the runner commits them to ${t.branch} when you finish, using your last line as the message. A task whose files are in place counts as done; report it completed.`:`Commit your work here with clear messages.`;r.push(``,`You're in your own git worktree on branch ${t.branch}, separate from your owner's checkout. ${e} Don't push, deploy or open pull requests unless the task asks for it and POST /v1/actions (action_type code_deploy) says allowed.`)}return e.tier!==`quick`&&r.push(``,...ti,``,...ei),e.rules?.length&&r.push(``,`Rules:`,...e.rules.map(e=>`- ${e}`)),r.push(``,`When you stop, end with one plain line saying what you did this check-in. The runner reports that line and what this run cost back to your workspace.`),r.join(`
46
+ `)}const ri=[`hair`,`hairColor`,`skin`,`eyes`,`glasses`,`face`,`hat`,`shirt`,`sleeves`,`outfit`,`pants`,`shoes`];function ii(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return t>>>0}function ai(e){let t=e;return()=>{t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}function oi(e){if(!e.startsWith(`look1.`))return null;let t=e.slice(6);if(t.length!==ri.length)return null;let n={};for(let[e,r]of ri.entries()){let i=parseInt(t[e],36);if(!Number.isFinite(i)||i>=hn[r])return null;n[r]=i}return n}function si(e){let t=oi(e);if(t)return t;let n=ai(ii(`person:${e}`)),r=(e,t=0)=>{let r=gn[e].filter(e=>e>=t),i=r.length?r:[0];return i[Math.floor(n()*i.length)]},i=r(`shirt`),a=n()>=.85;return{hair:r(`hair`),hairColor:r(`hairColor`),skin:r(`skin`),eyes:n()<.6?0:r(`eyes`),glasses:n()<.7?0:r(`glasses`,1),face:r(`face`),hat:a&&gn.hat.includes(1)?r(`hat`,1):0,shirt:i,sleeves:n()<.65?i:r(`sleeves`),outfit:r(`outfit`),pants:r(`pants`),shoes:r(`shoes`)}}function ci(e,t=mn){let n=t.sleeves[e.sleeves]??{},r={...t.base,...t.hairColor[e.hairColor],...t.skin[e.skin],...t.shirt[e.shirt],...n,...t.pants[e.pants],...t.shoes[e.shoes],...e.hat?t.hat[e.hat]?.[e.shirt%6]:{}};return e.sleeves!==e.shirt&&n.L&&(r.c=n.L),r}function li(e,t={hair:fn,hat:pn}){return(e.hat?t.hat[e.hat]:null)??t.hair[e.hair]??t.hair[0]}function ui(e){let t=si(e);return{...li(t),palette:ci(t)}}const di={claude_code:`claude_code`,codex:`codex`,hermes:`hermes`,cursor_agent:`cursor`,cursor:`cursor`,gemini:`gemini_cli`,gemini_cli:`gemini_cli`};function fi(e){let t=di[e];return t&&ln[t]||ui(`tool:${e}`)}const pi=()=>dn,mi=e=>{let t=parseInt(e.slice(1),16);return .3*(t>>16)+.59*(t>>8&255)+.11*(t&255)},hi=`#9aa0a6`;function gi(e){let t=di[e],n=t&&un[t]||ui(`tool:${e}`).palette.J||hi,r=mi(n);return r<70||r>200?hi:n}const _i=e=>gr(e),vi=(e,t=e.down)=>gr(t,e.palette);function yi(e,t,n={}){return{grid:vi(e),walk:e.walk.map(t=>vi(e,t)),prio:t,gap:2,front:!0,...n}}const bi=(e,t)=>({grid:_i(e),prio:t,gap:2,door:Math.floor(e[0].length/2)}),xi=(e,t)=>({grid:_i(e),prio:t,gap:2}),Si=(e,t,n=1)=>({grid:_i(e),prio:t,gap:n}),Ci=(e,t,n)=>{let r=Math.max(e.length,t.length),i=e=>[...Array(r-e.length).fill(`.`.repeat(e[0].length)),...e],[a,o]=[i(e),i(t)];return{grid:_i(a.map((e,t)=>e+`.`+o[t])),prio:n,gap:1}},wi=(e,t)=>({grid:[Array(B(e)).fill(null)],prio:t,gap:0,label:e}),Ti=e=>Math.max(0,...e.grid.map(e=>e.length)),Ei=e=>e.grid.length;function Di(e,t){let n=e=>e.reduce((t,n,r)=>t+Ti(n)+(r<e.length-1?n.gap??2:0),0),r=new Set;for(let i of[...e].sort((e,t)=>e.prio-t.prio))r.add(i),n(e.filter(e=>r.has(e)))>t&&r.delete(i);let i=e.filter(e=>r.has(e)),a=[],o=0;for(let e of i)a.push({...e,x:o}),o+=Ti(e)+(e.gap??2);let s=n(i),c=Math.max(0,...i.map(e=>e.label!==void 0&&!e.grid.some(e=>e.some(Boolean))?0:Ei(e)+ +!e.front));return{placed:a,width:s,height:c+c%2}}function Oi(e,t,n){let r=e.length-2,i=e=>sn[e];for(let a=0;a<t;a++){let t=n.some(e=>Math.abs(a-e)<=2);e[r][a]=t?i(`V`):a*7%11<2?i(`J`):i(`G`),e[r+1][a]=t?a*5%7==0?i(`z`):i(`V`):a*3%7==0?i(`G`):i(`H`)}}function ki(e,t,n,r){let i=r-t.length+1;for(let r=0;r<t.length;r++)for(let a=0;a<t[r].length;a++){let o=t[r][a],s=n+a,c=i+r;o&&c>=0&&c<e.length&&s>=0&&s<e[0].length&&(e[c][s]=o)}}function Ai(e,t){let n=Array.from({length:e.height},()=>Array(e.width).fill(null));Oi(n,e.width,e.placed.filter(e=>e.door!==void 0).map(e=>e.x+e.door));let r=t=>e.height-2+ +!!t.front;for(let i of e.placed)!i.front&&!t?.has(i)&&ki(n,i.grid,i.x,r(i));for(let i of e.placed)i.front&&!t?.has(i)&&ki(n,i.grid,i.x,r(i));for(let[e,i]of t??[])ki(n,e.walk?.[i.frame]??e.grid,e.x+i.dx,r(e));return n}function ji(e){let t=e.placed.filter(e=>e.label);if(!t.length)return null;let n=``;for(let[r,i]of t.entries()){let a=t[r+1],o=(a?a.x:e.width)-i.x-+!!a,s=V(i.label,Math.max(1,o)),c=Math.max(i.x,Math.min(i.x+Math.floor((Ti(i)-B(s))/2),i.x+o-B(s)));c<B(n)||(n+=` `.repeat(c-B(n))+F(s))}return n}function Mi(e,t=M.depth,n){if(t<2||!e.placed.length)return[];let r=_r(Ai(e,n),t),i=ji(e);return i===null?r:[...r,i]}function Ni(e,t=0){let[n,r,...i]=e,a=e=>t+e;return[xi(j.oak,a(2.5)),bi(j.cottage,a(.5)),Ci(j.tulip,j.sunflower,a(3)),...n?[n]:[],...r?[r]:[],Si(j.sunflower,a(4)),bi(j.cabin,a(3.5)),...i,xi(j.pine,a(5)),Si(j.bush,a(6)),Si(j.tulip,a(6.5)),xi(j.elm,a(7)),Ci(j.sunflower,j.tulip,a(8))]}function Pi(e){return Di(Ni([pi(),fi(`claude_code`),fi(`codex`),ui(`bitfolk`)].map((e,t)=>yi(e,t===0?0:t+1.2))),e)}function Fi(e,t){let n=e.map((e,t)=>yi(fi(e.id),t,{label:e.label,walker:!0})),r=Di(Ni(n,e.length),t);if(r.placed.filter(e=>e.walker).length===n.length)return r;let i=n.map(e=>({...e,gap:1})),a=Di(i,t);if(a.placed.length===n.length)return a;for(let e=n.length-1;e>0;e--){let r=Di([...i.slice(0,e),wi(`+${n.length-e}`,0)],t);if(r.placed.length===e+1)return r}return Di(i.slice(0,1),t)}const Ii=[j.cottage,j.cabin,j.roundhouse,j.barn];function Li(e){let t=0;for(let n of e)t=t*31+n.charCodeAt(0)>>>0;return t%Ii.length}function Ri(e,t){let n=Li(e),r=Ii[(n+1)%Ii.length],i=yi(ui(e),0,{walker:!0});return Di([xi(j.oak,4),{...bi(Ii[n],0),gap:1},i,Ci(j.tulip,j.sunflower,5),yi(pi(),2),Si(j.bush,6),bi(r,3),xi(j.pine,7),Ci(j.sunflower,j.tulip,8),xi(j.elm,9)],t)}function zi(e){let t=e.depth??M.depth,n=e.max??wn(),r=br(t);if(!r.length||n<40)return[];let i=Math.max(...r.map(B)),a=t=>[I.bold(e.tagline),F(`v${e.version}${e.url?` · ${e.url}`:``}`)].flatMap(e=>H(e,t)),o=n-i-3,s=t>=2&&o>=19?Mi(Pi(o),t):[];if(!s.length)return[...r,``,...a(n)];let c=Math.max(0,...s.map(B)),l=[...r,``,...a(Math.max(i,n-c-3))];return Jn(s,l,3,Math.max(0,Math.ceil((s.length-l.length)/2)))}function Bi(e,t=process.env,n=process.stdout){return!M.fancy||M.depth<2||!n.isTTY||t.CI||t.BITFOLK_NO_ANIMATION||t.SSH_CONNECTION||t.SSH_TTY||t.TERM===`dumb`?!1:(n.rows??0)>e+1}function Vi(e,t,n=M.depth,r=14){let i=e.placed.filter(e=>e.walker&&e.walk?.length);if(!i.length)return[t(Mi(e,n))];let a=Math.min(...i.map(e=>e.x)),o=e.width-a,s=[1,0,2,0],c=[];for(let a=0;a<r;a++){let l=Math.round(o*(1-a/r));c.push(t(Mi(e,n,new Map(i.map(e=>[e,{dx:l,frame:s[a%s.length]}])))))}return c.push(t(Mi(e,n))),c}async function Hi(e,t=process.stdout,n=80,r=process.env,i){let a=e[e.length-1]??[],o=a.length,s=t.columns??1/0;if(e.length<2||!Bi(o,r,t)||e.some(e=>e.length!==o||e.some(e=>B(e)>s))){t.write(a.join(`
41
47
  `)+`
42
48
  `);return}let c=()=>t.write(`\x1B[?25h`),l=e=>{c(),i?.(),process.exit(e===`SIGINT`?130:143)};process.once(`exit`,c),process.once(`SIGINT`,l),process.once(`SIGTERM`,l),t.write(`\x1B[?25l`);try{t.write(e[0].join(`
43
49
  `)+`
44
50
  `);for(let r of e.slice(1))await new Promise(e=>setTimeout(e,n)),t.write(`\x1b[${o}A`+r.map(e=>`\r\x1b[2K${e}`).join(`
45
51
  `)+`
46
- `)}finally{c(),process.removeListener(`exit`,c),process.removeListener(`SIGINT`,l),process.removeListener(`SIGTERM`,l)}}function Vi(e,t=j.depth){return _r(mi(e),``,t)}function J(e,n,r){return t(`git`,[`-C`,e,...n],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],env:r}).trim()}function Y(e,t,n){return J(e,[`-c`,`core.fsmonitor=false`,`-c`,`core.hooksPath=/dev/null`,...t],n)}function Hi(e,t){let n=c(e,`.git`),r;try{r=ee(n)}catch{throw Error(`the worktree's .git is gone`)}let i=oe(u(t,J(t,[`rev-parse`,`--git-common-dir`]))),a;if(r.isFile()){let t=/^gitdir:\s*(.+?)\s*$/m.exec(re(n,`utf8`));if(!t)throw Error(`the worktree's .git file was changed`);a=u(e,t[1])}else if(r.isDirectory())a=n;else throw Error(`the worktree's .git was changed`);let o;try{o=oe(a)}catch{throw Error(`the worktree's .git points nowhere`)}if(o!==i&&!o.startsWith(c(i,`worktrees`)+d))throw Error(`the worktree's .git no longer points into its repo`)}function Ui(e){try{return J(u(e),[`rev-parse`,`--show-toplevel`])}catch{return null}}const Wi=e=>`bitfolk/${e.slug}`;function Gi(e,t){try{return J(e,[`rev-parse`,`--verify`,`--quiet`,`refs/heads/${t}`]),!0}catch{return!1}}function Ki(e){if(!e.repo){let t=c(O(),`agents`,e.slug),n=!x(t);return n&&S(t,{recursive:!0,mode:448}),{dir:t,created:n}}let t=c(O(),`worktrees`,e.slug),n=Wi(e);if(x(c(t,`.git`)))return{dir:t,branch:n,created:!1};if(!Ui(e.repo))throw Error(`${e.repo} is no longer a git repository`);return S(c(O(),`worktrees`),{recursive:!0,mode:448}),J(e.repo,[`worktree`,`prune`]),Gi(e.repo,n)?J(e.repo,[`worktree`,`add`,t,n]):J(e.repo,[`worktree`,`add`,`-b`,n,t,e.base??`HEAD`]),{dir:t,branch:n,created:!0}}function qi(e,t){return Y(e,[`status`,`--porcelain`])?(Y(e,[`add`,`-A`]),Y(e,[`commit`,`-q`,`--no-verify`,`-m`,t]),Y(e,[`rev-parse`,`--short`,`HEAD`])):null}function Ji(e){if(!e.repo)return null;let t=c(O(),`worktrees`,e.slug);if(!x(t))return null;try{return{dir:t,changed:J(t,[`status`,`--porcelain`]).split(`
47
- `).filter(Boolean).length}}catch{return{dir:t,changed:0}}}function Yi(e){if(!e.repo)return;let t=c(O(),`worktrees`,e.slug);if(x(t))try{J(e.repo,[`worktree`,`remove`,`--force`,t])}catch{}}function Xi(e){try{return Y(e,[`rev-parse`,`HEAD`])}catch{return null}}function Zi(e,t,n){let r=`refs/heads/${n}`,i=Y(e,[`log`,`--format=%h%x09%s`,`-n`,`50`,`${t}..${r}`]).split(`
48
- `).filter(Boolean).map(e=>{let[t=``,...n]=e.split(` `);return{sha:t,subject:n.join(` `).slice(0,200)}}),a=Y(e,[`diff`,`--no-ext-diff`,`--no-textconv`,`--shortstat`,t,r]),o=e=>Number(e.exec(a)?.[1]??0);return{commits:i,commit_count:Number(Y(e,[`rev-list`,`--count`,`${t}..${r}`]))||i.length,files_changed:o(/(\d+) files? changed/),insertions:o(/(\d+) insertions?/),deletions:o(/(\d+) deletions?/)}}function Qi(e){let t=/^(?:https:\/\/(?:[^@/]+@)?github\.com\/|ssh:\/\/git@github\.com(?::\d+)?\/|git@github\.com:)([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?\/?$/.exec(e.trim());return t?`${t[1]}/${t[2]}`:null}const $i=/^(?!-)(?!.*\.\.)[A-Za-z0-9._/-]{1,200}$/;function ea(e,t){let n=t?.replace(/^(?:refs\/heads\/|refs\/remotes\/origin\/|origin\/)/,``);if(n&&$i.test(n)&&!/^[0-9a-f]{7,64}$/.test(n)&&n!==`HEAD`)return n;try{let t=J(e,[`symbolic-ref`,`--quiet`,`--short`,`refs/remotes/origin/HEAD`]).replace(/^origin\//,``);if($i.test(t))return t}catch{}return`main`}function ta(e,n){if(!$i.test(n))return null;try{return t(`git`,[`-C`,e,`-c`,`core.hooksPath=/dev/null`,`fetch`,`--quiet`,`--no-tags`,`origin`,`+refs/heads/${n}:refs/remotes/origin/${n}`],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GCM_INTERACTIVE:`never`},timeout:6e4}),J(e,[`rev-parse`,`--verify`,`refs/remotes/origin/${n}^{commit}`])}catch{return null}}function na(e,n,r){if(!/^bitfolk\/[A-Za-z0-9._-]+$/.test(n))return{error:`not a builder branch`};let i;try{i=J(e,[`config`,`--get`,`remote.origin.url`])}catch{return{error:`the repo has no origin remote`}}let a=Qi(i);if(!a)return{error:`origin isn't a GitHub repository`};let o;try{o=Y(e,[`rev-parse`,`--verify`,`refs/heads/${n}`])}catch{return{error:`${n} is gone`}}try{t(`git`,[`-C`,e,`-c`,`core.hooksPath=/dev/null`,`push`,`--quiet`,`--no-verify`,`origin`,`refs/heads/${n}:refs/heads/${n}`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GCM_INTERACTIVE:`never`},timeout:12e4})}catch(e){let t=e;return{error:((t.stderr||t.message||`push failed`).trim().split(`
49
- `).filter(Boolean).pop()??`push failed`).slice(0,300)}}return{repo:a,branch:n,base:ea(e,r),head_sha:o}}const ra=e=>`refs/bitfolk/checkpoints/${e}`,ia={GIT_AUTHOR_NAME:`Bitfolk checkpoint`,GIT_AUTHOR_EMAIL:`checkpoint@bitfolk.invalid`,GIT_COMMITTER_NAME:`Bitfolk checkpoint`,GIT_COMMITTER_EMAIL:`checkpoint@bitfolk.invalid`};function aa(e,t){let n;try{n=Y(e,[`rev-parse`,`HEAD`])}catch{return null}let r=te(c(fe(),`bitfolk-checkpoint-`));try{let i=c(r,`index`),a=u(e,Y(e,[`rev-parse`,`--git-path`,`index`]));x(a)&&b(a,i);let o={...process.env,...ia,GIT_INDEX_FILE:i};Y(e,[`add`,`-A`],o);let s=Y(e,[`write-tree`],o),l=ra(t),d=null;try{let[t=``,n=``]=Y(e,[`log`,`-1`,`--format=%T %P`,l]).split(` `);d={tree:t,parent:n}}catch{}if(d&&d.tree===s&&d.parent===n)return{head:n,checkpoint:Y(e,[`rev-parse`,l]),changed:!1};let f=Y(e,[`commit-tree`,s,`-p`,n,`-m`,`Bitfolk checkpoint of session ${t}`],o);return Y(e,[`update-ref`,l,f]),{head:n,checkpoint:f,changed:!0}}finally{ce(r,{recursive:!0,force:!0})}}function oa(e,t){if(!/^[0-9a-f]{7,64}$/.test(t))return!1;try{let n=Y(e,[`rev-parse`,`HEAD`]),[r=``,i=``]=Y(e,[`log`,`-1`,`--format=%T %P`,t]).split(` `);return i!==n||r===Y(e,[`rev-parse`,`HEAD^{tree}`])?!1:(Y(e,[`restore`,`--source=${t}`,`--worktree`,`--`,`.`]),!0)}catch{return!1}}function sa(e,t=30,n=Date.now()){let r=0;try{let i=n/1e3-t*86400;for(let t of J(e,[`for-each-ref`,`--format=%(refname) %(committerdate:unix)`,`refs/bitfolk/checkpoints/`]).split(`
50
- `)){let[n,a]=t.split(` `);n&&Number(a)<i&&(J(e,[`update-ref`,`-d`,n]),r++)}}catch{}return r}const ca=/^[a-z0-9][a-z0-9._-]{0,39}$/;function la(e){return i(e).toLowerCase().replace(/[^a-z0-9._-]+/g,`-`).replace(/^[^a-z0-9]+/,``).slice(0,40).replace(/[-.]+$/,``)||`repo`}function X(e){let t=e.repos?.length?e.repos:e.repo?[{name:la(e.repo),path:e.repo}]:[],n=t.find(t=>t.path===e.repo);return n?[n,...t.filter(e=>e!==n)]:t}const ua=e=>X(e)[0]??null;function da(e,t){if(!t)return ua(e);let n=X(e).find(e=>e.name===t.toLowerCase());if(!n)throw Error(`this computer has no repo named ${t} (it has: ${X(e).map(e=>e.name).join(`, `)||`none`})`);return n}function fa(e){try{return t(`git`,[`-C`,e,`config`,`--get`,`remote.origin.url`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{return null}}function pa(e){return X(e).map((e,t)=>{let n=fa(e.path);return{name:e.name,default:t===0,github:n?Qi(n):null}})}function ma(e,t,n,r=!1){let i=(n??X(e).find(e=>e.path===t)?.name??la(t)).toLowerCase();if(!ca.test(i))throw Error(`a repo name is 1 to 40 lowercase letters, digits, dots, dashes or underscores`);let a=X(e).filter(e=>e.path!==t);if(a.some(e=>e.name===i))throw Error(`there's already a repo named ${i}; pick another with --name`);if(a.length>=20)throw Error(`a computer can have at most 20 repos`);return{repos:[...a,{name:i,path:t}],repo:r||!e.repo||!a.length?t:e.repo}}function ha(e,t){let n=X(e),r=n.find(e=>e.name===t.toLowerCase());if(!r)throw Error(`no repo named ${t} here (it has: ${n.map(e=>e.name).join(`, `)||`none`})`);let i=n.filter(e=>e!==r);return{repos:i,repo:e.repo===r.path?i[0]?.path:e.repo}}const ga=36e5,_a=process.env.BITFOLK_FAST_POLL===`1`,va=_a?3e3:3e4,ya=_a?3e4:6e5,ba=_a?2e3:15e3,xa=_a?5e3:6e4,Sa=_a?1e3:5e3,Ca={session_requested:`a session you asked for`,claimable_tasks:`tasks to claim`,my_tasks:`its tasks`,new_messages:`new messages`,mentioned:`a message that tags it`,review_waiting:`a review`,briefing_due:`a briefing`,setup_actions:`setup`,watch_fired:`a watch`},wa=e=>e.map(e=>Ca[e]??e.replace(/_/g,` `)).join(`, `)||`new work`;function Ta(e,t){if(e){if(e.pid)try{process.kill(-e.pid,t);return}catch{}e.kill(t)}}const Ea=new WeakSet;function Da(e,t=1e4){Ta(e,`SIGTERM`),setTimeout(()=>{e&&!Ea.has(e)&&Ta(e,`SIGKILL`)},t).unref()}function Oa(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m${String(t%60).padStart(2,`0`)}s`}function ka(e){let t=[];e.costMicros!==null&&t.push(`$${(e.costMicros/1e6).toFixed(e.costMicros>0&&e.costMicros<1e4?4:2)}`);let n=e.inputTokens+e.outputTokens;return n&&t.push(n>=1e3?`${Math.round(n/1e3)}k tokens`:`${n} tokens`),t.join(`, `)}const Aa={info:[()=>P(I.skip),e=>e],idle:[()=>P(I.idle),P],start:[()=>F.accent(I.dot),e=>e],ok:[()=>F.ok(I.ok),e=>e],fail:[()=>F.err(I.fail),F.err],warn:[()=>F.warn(I.warn),F.warn],progress:[()=>P(I.arrow),P]};function ja(e,t,n){let r=(t.runStarts??[]).filter(e=>e>n-ga).sort((e,t)=>e-t),i=e.maxRunsPerHour-r.length;return{left:i,freesAt:i>0?n:(r[0]??n)+ga}}function Ma(e,t){if(e.command)return{runtime:`command`,command:e.command};if(t.startsWith(`custom:`)){let n=e.customTools?.find(e=>`custom:${e.name}`===t);if(!n)throw Error(`your workspace asked for ${t.slice(7)}, which isn't set up here (${w} add)`);return n.protocol===`acp`?{runtime:`acp`,acp:{...ot(n.command),agent:t}}:{runtime:`command`,command:n.command}}let n=Ze(t);if(n)return{runtime:n};let r=Ur(t);if(r)return{runtime:`acp`,acp:r};throw Error(`this runner can't start ${t}`)}function Na(e,t){let n=t.session.retry,r=n?.mode===`fix`&&n.branch?.startsWith(`bitfolk/builder-`)?n.branch.slice(8):null,i=da(e,t.session.repo)?.path,a=e.pullRequests&&i&&!n?ta(i,ea(i,e.base)):null;return{id:t.builder.id,name:t.builder.name,slug:r&&en(r)===r?r:en(`builder-${t.session.id.slice(-8)}`),...Ma(e,t.session.runtime),api:e.api,token:t.builder.token,repo:i,base:(n?.mode===`redo`&&/^[0-9a-f]{7,64}$/.test(n.base_sha??``)?n.base_sha:null)??a??e.base,maxUsdPerRun:e.maxUsdPerRun,maxRunsPerHour:e.maxRunsPerHour,timeoutMin:e.timeoutMin,permission:e.permission,model:e.model,pullRequests:e.pullRequests}}const Z=`machine`;function Pa(e=process.env){return Object.fromEntries(Object.entries(e).filter(([e])=>!/^npm_[a-z]/.test(e)&&e!==`INIT_CWD`&&e!==`NODE`))}function Fa(e=process.env,t=ye){let n=(e.PATH??``).split(a).filter(Boolean);if(!t)return n;let r=n.findIndex(e=>/[\\/]node-gyp-bin$/.test(e));return(r>=0?n.slice(r+1):n).filter(e=>!/[\\/]_npx[\\/]/.test(e))}var Ia=class{config;state;#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i;#a;#o;#s;#c;#l=!1;#u=null;#d=0;#f=null;#p=0;#m=null;#h=0;#g=!1;#_;#v=null;#y=new Map;#b=0;#x=null;#S=null;#C={day:``,done:0,failed:0,stopped:0,costMicros:0,durationMs:0};constructor(e,t={}){this.config=e,this.state=Qt(),this.#i=t.out??(e=>process.stdout.write(e+`
51
- `)),this.#a=t.now??Date.now,this.#o=t.progressMs??1e4,this.#s=t.checkpointMs??18e4,this.#c=t.acpCancelGraceMs,this.#_=!!t.liveFooter}#w(e){return this.state.agents[e.id]??={}}#T(e){let t=this.#r.get(e.id);return t||this.#r.set(e.id,t=new Vt(e.api,e.oauth?()=>jr(e,{now:this.#a}):e.token)),t}#E(e,t,n=`info`,r){let i=new Date(this.#a()).toTimeString().slice(0,8),[a,o]=Aa[n],s=r?()=>r:a,c=e?e.name:``,l=c?jn(c)(c):``,u=M(),d=Pn(o(t));if(u<60){this.#i(V(`${P(i)} ${s()} ${l}${l?` `:``}${d}`,u,4).join(`
52
- `));return}let f=`${P(i)} ${s()} ${l}${` `.repeat(Math.max(0,12-z(c)))} `;this.#i(V(f+d,u,z(f)).join(`
53
- `))}#D(){$t(this.state)}#O(e,t){let n=this.#a()+Math.max(1e3,t);return this.#t.set(e.id,n),n}#k(e){let t=(this.#n.get(e.id)??0)+1;return this.#n.set(e.id,t),Math.min(ya,ba*2**(t-1))}stop(){if(!this.#l){this.#l=!0;for(let e of this.#e.values())this.#A(e,`owner`);this.#m?.()}}#A(e,t){if(e.cancel){let n=e.cancel(t);return n&&t===`owner`&&(e.stopped=!0),n}return t===`owner`&&(e.stopped=!0),Da(e.child),!0}killAll(){for(let e of this.#e.values())e.stopped=!0,Ta(e.child,`SIGKILL`)}async#j(){if([...this.#e.values()].some(e=>e.sessionId&&!e.stopped))try{let e=await this.#V()?.peek();e&&this.#F(Z);for(let t of e?.cancel??[])this.#M(t)}catch{}}#M(e){for(let[t,n]of this.#e)if(!(n.sessionId!==e||n.stopped))return this.#E({id:t,name:`Builder`},`canceled from your workspace; stopping it`,`warn`),this.#A(n,`owner`),!0;return!1}#N(e,t){let n=[],r=null,i=JSON.stringify([null,null,null]),a=!1,o=!1,s=async()=>{let r=this.#V();if(a||o||!r)return;let s={input_tokens:t.inputTokens||null,output_tokens:t.outputTokens||null,cost_micros:t.costMicros},c=JSON.stringify(Object.values(s));if(n.length||c!==i){a=!0;try{let t=n.slice(),a=await r.progress(e,{lines:t,...s});if(a.status!==`error`){i=c;let e=new Set(t);for(;n.length&&e.has(n[0]);)n.shift()}a.status===`not_found`&&(o=!0),a.canceled&&!o&&this.#M(e)}finally{a=!1}}},c=setInterval(()=>void s(),this.#o);return{add(e){e&&e!==r&&(r=e,n.push(e),n.length>5&&n.shift())},stop(){o=!0,clearInterval(c)}}}get running(){return this.#e.size}status(){let e=[...this.#e.values()],t=e.map(e=>e.tally?.costMicros).filter(e=>typeof e==`number`),n=e.map(e=>e.startedAt).filter(e=>typeof e==`number`),r=[...this.#t.entries()].filter(([e])=>e!==Z||!this.#f).map(([,e])=>e);return{running:e.length,since:n.length?Math.min(...n):null,costMicros:t.length?t.reduce((e,t)=>e+t,0):null,nextCheckAt:this.#g||this.#h||!r.length?null:Math.min(...r),checking:this.#h>0,stopping:this.#l,sessions:e.map(e=>({name:e.name??``,tool:e.tool??``,title:e.title??``,startedAt:e.startedAt??e.joinedAt??this.#a(),costMicros:e.tally?.costMicros??null,activity:e.activity??null,activityAt:e.activityAt??null,stopping:e.stopped})).sort((e,t)=>e.startedAt-t.startedAt),queued:this.#b,waitingFor:this.#b?this.#x:null,capFreesAt:this.#S,lastCheckAt:this.#v,checkFailure:[...this.#y.values()].sort((e,t)=>e.since-t.since)[0]??null,signedOut:this.#f,runsThisHour:this.config.machine?this.config.machine.maxRunsPerHour-ja(this.config.machine,this.state.agents[Z]??{},this.#a()).left:null,today:this.#P()}}#P(){let e=new Date(this.#a()).toDateString();return this.#C.day!==e&&(this.#C={day:e,done:0,failed:0,stopped:0,costMicros:0,durationMs:0}),this.#C}#F(e){this.#v=this.#a(),this.#y.delete(e)}#I(e,t,n){let r=t.message;this.#y.set(e,{message:r,since:this.#y.get(e)?.since??this.#a(),retryAt:n})}async#L(e){this.#h++;try{return await e()}finally{this.#h--}}async check(e){let t=this.#w(e);if(t.disabledReason||this.#e.has(e.id))return null;let{left:n,freesAt:r}=ja(e,t,this.#a());if(n<=0)return this.#E(e,`hit ${e.maxRunsPerHour} runs this hour; next check at ${new Date(r).toTimeString().slice(0,5)}`,`warn`),this.#t.set(e.id,r),null;let i;try{i=await this.#L(()=>this.#T(e).peek(t.etag))}catch(n){if(n instanceof K&&n.ended)return t.disabledReason=`its sign-in ended (unlinked on your workspace, or unused for 90 days)`,this.#E(e,`stopped: ${t.disabledReason}. Copy a new token from its page on your workspace and run \`${w} add <token>\`.`,`fail`),this.#D(),null;if(n instanceof Bt&&n.status===401){let r=n.code===`agent_removed`;return t.disabledReason=r?`its owner removed it from Bitfolk`:`token rejected (revoked, or the agent was archived)`,this.#E(e,r?`stopped: ${t.disabledReason}. Run \`${w} rm "${e.name}"\` to forget it.`:`stopped: ${t.disabledReason}. Copy a new token from its page on your workspace and run \`${w} add <token>\` (it keeps your options).`,`fail`),this.#D(),null}let r=this.#k(e);return this.#E(e,`peek failed (${n.message}); retrying in ${Oa(r)}`,`warn`),this.#I(e.id,n,this.#O(e,r)),null}return this.#n.delete(e.id),this.#F(e.id),i?(t.etag=i.etag,t.pollMs=i.next_poll_after_s*1e3,this.#D(),i.tier===`silent`||!i.has_work?(this.#O(e,i.next_poll_after_s*1e3),null):{done:this.#R(e,i)}):(this.#O(e,t.pollMs??xa),null)}#R(e,t,n){let r={child:null,done:Promise.resolve(null),stopped:!1,sessionId:n?.session.id,name:e.name,tool:n?.session.runtime??e.acp?.agent??e.runtime,title:L(n?n.session.task?.title??n.session.goal?.title??`an objective`:`woke for ${wa(t.reasons)}`),joinedAt:this.#a()},i=this.#U(e,t,r,n);return n?.session.retry?.mode===`fix`&&(i=i.then(i=>!i?.resumed||i.status!==`failed`||i.durationMs>=2e4||r.stopped||this.#l?i:(this.#E(e,`couldn't pick up the earlier conversation; starting fresh on the same branch`,`warn`),this.#U(e,t,r,n,{fresh:!0})))),r.done=(n?i.then(t=>this.#H(e,n,t)):i).finally(()=>{this.#e.delete(e.id),this.#m?.()}),this.#e.set(e.id,r),r.done}#z(e,t,n,r){let i=``,a=null,o=()=>a??=(async()=>{let a=this.#V();if(!a)return;let o=null;try{o=aa(t.dir,e)}catch{}let s={branch:t.branch??null,base_sha:n,head_sha:o?.head??null,checkpoint_sha:o?.checkpoint??null,tool_session_id:r.sessionId??null},c=JSON.stringify(s);c!==i&&await a.checkpoint(e,s)&&(i=c)})().finally(()=>{a=null}),s=setInterval(()=>void o(),this.#s);return o(),{async final(){clearInterval(s),await a,await o()},stop:()=>clearInterval(s)}}async#B(e=!1){let t=this.config.machine,n=this.#V();if(!(!t||!n||!e&&this.#d&&this.#a()-this.#d<6e5)){this.#d=this.#a();try{await n.report({usage:Fe(t.runtimes,this.state.usage,{now:this.#a()}),repos:pa(t)})}catch{}}}#V(){let e=this.config.machine;return!e||this.#f?null:this.#u??=new Ht(e.api,()=>jr(e,{now:this.#a}))}async checkMachine(){let e=this.config.machine,t=this.#V();if(!e||!t)return[];let n=this.state.agents[Z]??={},r={id:Z,name:e.name},i;try{i=await this.#L(()=>t.peek())}catch(e){if(e instanceof K&&e.ended||e instanceof Bt&&e.status===401)return this.#f=`this machine was unlinked, or its sign-in ended`,this.#E(r,`stopped: ${this.#f}. Run \`${w} login\` to link it again.`,`fail`),[];let t=this.#k(r);this.#E(r,`check-in failed (${e.message}); retrying in ${Oa(t)}`,`warn`);let n=this.#a()+t;return this.#t.set(Z,n),this.#I(Z,e,n),[]}this.#n.delete(r.id),this.#F(Z),await this.#B();for(let e of i.cancel??[])this.#M(e);let a=Math.max(1e3,i.next_poll_after_s*1e3);this.#t.set(Z,this.#a()+a);let o=()=>{[...this.#e.values()].some(e=>e.sessionId&&!e.stopped)&&this.#t.set(Z,Math.min(this.#t.get(Z)??1/0,this.#a()+Sa))},s=[],c=i.queued;for(this.#x=null,this.#S=null;c>0&&!this.#l;c--){if(this.#e.size>=this.config.maxConcurrent){this.#x=`slot`;break}let{left:i,freesAt:a}=ja(e,n,this.#a());if(i<=0){this.#x=`cap`,this.#S=a,this.#p!==a&&(this.#p=a,this.#E(r,`hit ${e.maxRunsPerHour} sessions this hour; the rest wait until ${new Date(a).toTimeString().slice(0,5)}`,`warn`)),this.#t.set(Z,a);break}let o;try{o=await this.#L(()=>t.claim({runtimes:e.runtimes,timeout_min:e.timeoutMin}))}catch(e){this.#E(r,`couldn't take a session (${e.message})`,`warn`);break}if(!o){c=0;break}this.#b=Math.max(0,this.#b-1),n.runStarts=[...(n.runStarts??[]).filter(e=>e>this.#a()-ga),this.#a()],this.#D();let l;try{l=Na(e,o)}catch(e){this.#E(r,`can't run a session: ${e.message}`,`fail`),await t.finish(o.session.id,{status:`failed`,summary:null,error:e.message}).catch(()=>{});continue}let u=L(o.session.task?.title??o.session.goal?.title??`an objective`);this.#E(l,`joined for a session: ${F.bold(u)} ${P(`·`)} ${F.tool(R(q(o.session.runtime)))}`,`start`,Vi(o.session.runtime));let d=await new Vt(l.api,l.token).peek().catch(()=>null),f={has_work:!0,tier:`full`,reasons:[`session_requested`,...(d?.reasons??[]).filter(e=>e!==`setup_actions`)],briefing_goal_id:o.session.goal?.id??null,etag:d?.etag??``,next_poll_after_s:60,rules:d?.rules};s.push({done:this.#R(l,f,o)})}return this.#b=this.#x?Math.max(0,c):0,o(),s}async#H(e,t,n){let r=n?.status===`succeeded`?`succeeded`:n?.status===`interrupted`?`canceled`:`failed`,i=null;if(n){let t=n.work?.startSha??null,r={commits:[],commit_count:0,files_changed:0,insertions:0,deletions:0};if(n.work?.branch&&t)try{e.repo&&Hi(n.work.dir,e.repo),r=Zi(n.work.dir,t,n.work.branch)}catch{}if(i={base:t?.slice(0,12)??null,...r,duration_ms:n.durationMs},e.pullRequests&&e.repo&&n.status===`succeeded`&&r.commit_count>0&&n.work?.branch){let t=na(e.repo,n.work.branch,e.base);`error`in t?(i.push_error=t.error,this.#E(e,`couldn't push ${F.tool(n.work.branch)} (${t.error}); it stays here for you`,`warn`)):(i.push=t,this.#E(e,`pushed ${F.tool(n.work.branch)} to ${t.repo}; a pull request into ${t.base} waits for your approval`,`ok`))}}try{await this.#V()?.finish(t.session.id,{status:r,summary:n?.tally.summary??null,error:n?n.status===`succeeded`?null:n.tally.error??n.status:`the session couldn't start on this machine`,branch:n?.work?.branch??null,result:i,input_tokens:n?n.tally.inputTokens:null,output_tokens:n?n.tally.outputTokens:null,cost_micros:n?.tally.costMicros??null,model:((e.runtime===`acp`?n?.tally.model??e.model:e.model??n?.tally.model)??null)?.slice(0,100)??null}),i?.commit_count&&this.#E(e,`left ${F.bold(`${i.commit_count} commit${i.commit_count===1?``:`s`}`)} on ${F.tool(n.work.branch)} ${P(`(${i.files_changed} files)`)}`,`ok`)}catch(t){this.#E(e,`couldn't report the session's end (${t.message}); Bitfolk times it out`,`warn`)}let a=n?n.tally.limit??Pe(n.tally.error,this.#a()):null;return a&&(this.state.usage={...this.state.usage,[t.session.runtime]:{...a,at:this.#a()}},a.limited_until&&this.#E(e,`${q(t.session.runtime)} hit its usage limit; sessions go to another tool until ${new Date(a.limited_until).toTimeString().slice(0,5)}`,`warn`)),this.#B(!0),this.#E(e,`left the workspace`,`idle`),Yi(e),e.repo&&sa(e.repo),delete this.state.agents[e.id],this.#D(),n}async#U(e,t,r,i,o={}){let s=this.#w(e),l=this.#T(e),u=Xe[e.runtime],d=e.runtime===`acp`?e.acp:void 0;if(e.runtime===`acp`&&!d)throw Error(`${e.name} has runtime acp but no ACP command`);let f=this.#a(),m;try{m=Ki(e)}catch(t){return s.etag=void 0,this.#E(e,`can't prepare its workspace: ${t.message}`,`fail`),this.#O(e,this.#k(e)),null}let h=m.branch?Xi(m.dir):null,_=i?.session.retry??null,v=!!(_?.mode===`fix`&&m.created&&m.branch&&_.checkpoint_sha&&oa(m.dir,_.checkpoint_sha));v&&this.#E(e,`put back the earlier session's uncommitted work on ${F.tool(String(m.branch))}`,`ok`);let y=null;try{y=await l.runStart({client_run_id:ge(),host:de(),runtime:d?d.agent:e.runtime,reasons:t.reasons,tier:t.tier})}catch(n){if(n instanceof Bt&&n.status===409)return this.#E(e,`is paused by its owner; not starting`,`idle`),this.#O(e,t.next_poll_after_s*1e3||(_a?xa:6e5)),null;this.#E(e,`couldn't record the run start (${n.message}); running anyway`,`warn`)}y||await l.status(`working`).catch(()=>{});let b=o.fresh?null:_?.mode===`fix`?u.resumes!==!1&&_.tool_session_id?_.tool_session_id:null:u.resumes!==!1&&!m.created&&s.sessionId&&s.sessionAt&&f-s.sessionAt<432e5?s.sessionId:null,x=!!m.branch&&!!u.runnerCommits?.(e),ee=ei(t,{agentName:e.name,api:e.api,branch:m.branch,runnerCommits:x,resumed:!!b,session:i?{goal:i.session.goal?.title??null,task:i.session.task?.title??null,note:i.session.note,goalDone:i.session.goal?.done_definition??null,taskSpec:i.session.task?.spec??null,asks:i.session.asks??[],requestedBy:i.session.requested_by??`owner`,requestedByAgent:i.session.requested_by_agent??null,retry:_?{mode:_.mode,branch:_.branch,summary:_.summary,error:_.error,status:_.status,restored:v}:void 0,tool:i.session.runtime,repo:this.config.machine?X(this.config.machine).find(t=>t.path===e.repo)?.name??null:null,computer:i.session.computer??null}:void 0}),te=u.launch(e,ee,b);s.runStarts=[...(s.runStarts??[]).filter(e=>e>f-ga),f],this.#D(),this.#E(e,`woke ${P(`for ${wa(t.reasons)}`)} → ${F.tool(R(d?`${q(d.agent)} over ACP`:e.runtime))}${b?P(`, resuming`):``}`,`start`);let ne=c(O(),`logs`,e.slug);S(ne,{recursive:!0,mode:448});let re=c(ne,`${new Date(f).toISOString().replace(/[:.]/g,`-`)}.jsonl`),ie=new Set([e.token]),ae=e=>[...ie].reduce((e,t)=>e.split(t).join(`[token]`),e),oe=(e,t)=>g(re,JSON.stringify({t:this.#a(),stream:e,line:ae(t)})+`
54
- `,{mode:384}),se=Lr(),le=Mr(e),ue=e.oauth?setInterval(()=>{e.oauth.expiresAt-this.#a()>6e5||jr(e,{now:this.#a}).then(()=>{ie.add(e.token),Mr(e)}).catch(t=>this.#E(e,`couldn't renew its sign-in mid-run: ${t.message}`,`warn`))},6e4):null,C=Le();r.tally=C,r.startedAt=this.#a();let fe={...Pa(),PATH:[se,...Fa(),...zr()].join(a),...d?{NO_BROWSER:`1`}:{BITFOLK_TOKEN:e.token},BITFOLK_TOKEN_FILE:le,BITFOLK_API:e.api.replace(/\/+$/,``),BITFOLK_AGENT:e.name,...y?{BITFOLK_RUN_ID:y.id}:{},...i?{BITFOLK_SESSION_ID:i.session.id}:{}};d&&delete fe.BITFOLK_TOKEN;for(let[e,t]of Object.entries(fe))t&&t.length>=12&&/KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH/i.test(e)&&e!==`BITFOLK_TOKEN_FILE`&&ie.add(t);let pe=i?this.#N(i.session.id,C):null,me=i&&m.branch?this.#z(i.session.id,m,h,C):null,he=null,_e=t=>{let n=t&&L(ae(t)).trim();pe?.add(n),n&&n!==he&&(he=n,r.activity=n,r.activityAt=this.#a(),this.#E(e,n,`progress`))},ve=null,w=null,ye=!1,be,xe=null;try{be=await new Promise(t=>{let i=n(te.bin,te.args,{cwd:m.dir,env:fe,stdio:[`pipe`,`pipe`,`pipe`],detached:!0});if(r.child=i,i.stdin.on(`error`,()=>{}),d){let t=new It({stdin:i.stdin,stdout:i.stdout,agent:{...e,acp:d},label:q(d.agent),cwd:m.dir,home:O(),packet:ee,tally:C,clientVersion:Rt,log:oe,activity:_e,kill:()=>{Ea.has(i)||Da(i)},cancelGraceMs:this.#c});r.cancel=e=>t.cancel(e),xe=t.run()}else i.stdin.end(te.stdin),p({input:i.stdout}).on(`line`,e=>{oe(`out`,e),u.parse(e,C),u.activity&&_e(u.activity(e,m.dir))});(this.#l||r.stopped)&&this.#A(r,`owner`),p({input:i.stderr}).on(`line`,e=>{oe(`err`,e),e.trim()&&(w=ae(e.trim()).slice(0,300))});let a=setTimeout(()=>{ye=!0,this.#A(r,`timeout`)||(ye=!1)},e.timeoutMin*6e4);i.on(`error`,e=>{ve=e.code===`ENOENT`?`${te.bin} isn't installed or isn't on PATH`:e.message}),i.on(`close`,e=>{Ea.add(i),clearTimeout(a),t({code:e})})})}finally{pe?.stop(),me?.stop(),ue&&clearInterval(ue)}let Se=xe?await xe:null;r.cancel=void 0,u.afterExit?.(te,C),ce(le,{force:!0});let Ce=this.#a()-f,T,we;if(Se?(T=r.stopped?`interrupted`:C.overBudget?`over_budget`:ve||ye||!Se.ok?`failed`:`succeeded`,we=ve??(T===`over_budget`?C.error:ye&&T===`failed`?`stopped after ${e.timeoutMin} minutes`:T===`failed`?Se.exited?w??`${Se.error??`the tool exited`}${be.code===null?``:` (exit ${be.code})`}`:Se.error??w??`the turn failed`:null),T===`failed`&&(C.error=we)):(T=r.stopped?`interrupted`:C.overBudget?`over_budget`:ve||ye||be.code!==0||C.isError?`failed`:`succeeded`,we=ve??(ye?`stopped after ${e.timeoutMin} minutes`:T===`failed`?C.error??w??`exit ${be.code}`:null)),T===`failed`&&!C.error&&(C.error=we),x&&!ve){let t=`${e.name}: ${C.summary??`work from a Bitfolk run`}`,n=`Bitfolk run${y?` ${y.id}`:``}, ${T}.`;try{e.repo&&m.branch&&Hi(m.dir,e.repo);let r=qi(m.dir,`${t.length>72?t.slice(0,71)+`…`:t}\n\n${n}`);r&&this.#E(e,`committed its changes as ${F.bold(r)} on ${F.tool(String(m.branch))}`,`ok`)}catch(t){this.#E(e,`couldn't commit its changes: ${t.message.split(`
55
- `)[0]}`,`warn`)}}await me?.final().catch(()=>{}),T===`failed`&&b&&Ce<2e4?(s.sessionId=void 0,s.etag=void 0):C.sessionId&&(s.sessionId=C.sessionId,s.sessionAt=this.#a()),(T===`failed`||T===`interrupted`)&&(s.etag=void 0),this.#D();let Te={status:T,exit_code:Se?Se.ok&&T===`succeeded`?0:null:be.code,session_id:C.sessionId,input_tokens:C.inputTokens,output_tokens:C.outputTokens,cost_micros:C.costMicros,summary:C.summary,error:we};y?await l.runFinish(y.id,Te).catch(async()=>{await new Promise(e=>setTimeout(e,2e3)),await l.runFinish(y.id,Te).catch(t=>this.#E(e,`couldn't record the run end: ${t.message}`,`warn`))}):await l.status(`idle`).catch(()=>{});let Ee=this.#P();T===`succeeded`?Ee.done++:T===`interrupted`?Ee.stopped++:Ee.failed++,Ee.costMicros+=C.costMicros??0,Ee.durationMs+=Ce;let De=ka(C),Oe=T===`succeeded`?F.ok(F.bold(T)):T===`failed`?F.err(F.bold(T)):F.warn(F.bold(T));return this.#E(e,[`${Oe} in ${Oa(Ce)}`,...De?De.split(`, `).map(e=>e.startsWith(`$`)?F.money(e):e):[]].join(` ${P(`·`)} `)+`${we?` ${F.err(`(${L(we)})`)}`:``}${C.summary?` ${P(`—`)} ${L(C.summary)}`:``}`,T===`succeeded`?`ok`:T===`failed`?`fail`:`warn`),T===`failed`?this.#O(e,this.#k(e)):(this.#n.delete(e.id),this.#O(e,va)),{agent:e.name,status:T,tally:C,durationMs:Ce,work:{dir:m.dir,branch:m.branch,startSha:h},resumed:!!b}}async run(e={}){this.#g=!!e.once;let t=this.config.agents.filter(e=>!this.#w(e).disabledReason);for(let e of this.config.agents){let t=this.#w(e).disabledReason;t&&this.#E(e,`skipped: ${t}`,`idle`)}let n=this.config.machine;if(t.length===0&&!n)return this.#E(null,`nothing to run. Link this computer with \`${w} login\`.`,`warn`),[];if(e.once){let e=[];if(n){let t=await this.checkMachine();t.length===0&&!this.#f&&this.#E({name:n.name},`no sessions waiting`,`idle`),e.push(...t.map(e=>e.done))}for(let n of t){for(;this.#e.size>=this.config.maxConcurrent;)await Promise.race([...this.#e.values()].map(e=>e.done));let t=await this.check(n);t?e.push(t.done):this.#e.has(n.id)||this.#E(n,`nothing to do`,`idle`)}let r=n?setInterval(()=>void this.#j(),Sa):null;try{return(await Promise.all(e)).filter(e=>e!==null)}finally{r&&clearInterval(r)}}let r=[],i=[n?`${n.name} for sessions`:null,t.length?`${t.length} agent${t.length===1?``:`s`}`:null].filter(Boolean).join(` and `);for(this.#E(null,`watching ${F.bold(i)} ${P(`(up to ${this.config.maxConcurrent} at once).${this.#_?``:` Ctrl-C to stop.`}`)}`,`start`);!this.#l;){let e=this.#a();if(n&&!this.#f&&(this.#t.get(Z)??0)<=e)for(let e of await this.checkMachine())e.done.then(e=>e&&r.push(e));for(let n of t){if(this.#l||this.#e.size>=this.config.maxConcurrent)break;this.#e.has(n.id)||this.#w(n).disabledReason||(this.#t.get(n.id)??0)>e||(await this.check(n))?.done.then(e=>e&&r.push(e))}let i=Math.min(...t.map(t=>this.#t.get(t.id)??e),n&&!this.#f?this.#t.get(Z)??e:1/0),a=Math.max(1e3,Math.min(6e4,i-this.#a()));await new Promise(e=>{let t=setTimeout(e,a);this.#m=()=>{clearTimeout(t),e()}}),this.#m=null}return await Promise.all([...this.#e.values()].map(e=>e.done)),r}};const La=e=>Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e);function Ra(e){for(let t=0;t<20;t++){let t;try{t=re(e,`utf8`).trim()}catch{return null}if(t)return Number(t)||0;La(25)}return 0}function za(e){if(!e||e===process.pid)return!1;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function Ba(){let e=Ra(c(O(),`runner.pid`));return e&&za(e)?e:null}function Va(){let e=c(O(),`runner.pid`);S(O(),{recursive:!0,mode:448});let t=String(process.pid),n=()=>{try{re(e,`utf8`).trim()===t&&ce(e,{force:!0})}catch{}};for(let r=0;r<3;r++){try{return ue(e,t,{mode:384,flag:`wx`}),n}catch(e){if(e.code!==`EEXIST`)throw e}let r=Ra(e);if(r===null)continue;if(za(r))throw Error(`a runner is already going (pid ${r}). Stop it first, or see \`${w} status\`.`);let i=`${e}.${process.pid}.tmp`;if(ue(i,t,{mode:384}),se(i,e),La(25),Ra(e)===process.pid)return n}throw Error(`another runner is starting at the same moment. Try again, or see \`${w} status\`.`)}var Q=class extends Error{};const $=e=>e.slice(-8);function Ha(e){let t=e.trim(),n=t.split(/\r?\n/)[0].trim();if(n===t&&n.length<=200)return{title:n,note:``};let r=n;if(r.length>200){let e=r.slice(0,199),t=e.lastIndexOf(` `);r=`${(t>80?e.slice(0,t):e).trimEnd()}…`}return{title:r,note:t.slice(0,2e3)}}function Ua(e,t){if(!e)return;let n=e.trim().toLowerCase();for(let e of[n,n.replace(/-/g,`_`),Kr(n)])if(t.runtimes.includes(e))return e;throw new Q(`${e} isn't on for this computer (on: ${t.runtimes.map(e=>e.startsWith(`custom:`)?e.slice(7):e.replace(/_/g,`-`)).join(`, `)}). Turn it on with bitfolk add ${e}`)}const Wa=e=>e===null?null:`$${(e/1e6).toFixed(e>0&&e<1e4?4:2)}`,Ga={queued:e=>P(`${I.idle} ${e}`),running:e=>F.sky(`${I.dot} ${e}`),succeeded:e=>F.ok(`${I.ok} ${e}`),failed:e=>F.err(`${I.fail} ${e}`),canceled:e=>P(`${I.skip} ${e}`)},Ka=e=>(Ga[e]??(e=>e))(e===`succeeded`?`done`:e);function qa(e,t=Date.now()){if(!e)return``;let n=Math.max(0,Math.round((t-Date.parse(e))/1e3));return n<60?`just now`:n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:`${Math.floor(n/86400)}d ago`}function Ja(e,t=Date.now()){return e.started_at?tr((e.finished_at?Date.parse(e.finished_at):t)-Date.parse(e.started_at)):null}const Ya=e=>L(e.task?.title??e.goal?.title??`an objective`);function Xa(e,t=Date.now()){if(!e.length)return[W(`${P(I.idle)} No sessions on this computer yet. Start one with ${H(`${w} run "<what to do>"`)}.`)];let n=M();return Hn(e.map(e=>{let r=Wa(e.cost_micros),i=e.status===`running`?`${Ja(e,t)??``}`:e.status===`queued`?qa(e.created_at,t):qa(e.finished_at??e.created_at,t),a=e.status===`running`&&e.last?e.last:e.status===`failed`&&e.error?e.error:!e.task&&e.note?e.note:null,o=a?P(` · ${L(a)}`):``;return[F.tool($(e.id)),Ka(e.status),P(R(q(e.runtime))),B(`${N(Ya(e))}${o}`,Math.max(20,n-52)),P(R([i,r].filter(Boolean).join(` · `)))]}),{indent:2,gap:2,max:n})}function Za(e,t={}){let n=t.now??Date.now(),r=[];r.push(W(`${F.tool($(e.id))} ${Ka(e.status)} ${N(Ya(e))}`));let i=[];e.task&&e.goal&&i.push([`objective`,L(e.goal.title)]),i.push([`tool`,q(e.runtime)+(e.model?P(` · ${L(e.model)}`):``)]),e.note&&i.push([`note`,L(e.note)]),e.retry_mode&&i.push([`retry`,`${e.retry_mode} of ${$(e.retry_of??``)}`]);let a=Ja(e,n);i.push([`started`,e.started_at?`${qa(e.started_at,n)}${a?P(` · ran ${a}`):``}`:P(`waiting since ${qa(e.created_at,n)}`)]);let o=(e.input_tokens??0)+(e.output_tokens??0),s=Wa(e.cost_micros);(s||o)&&i.push([`spent`,[s?F.money(s):null,o?P(`${Math.round(o/1e3)}k tokens`):null].filter(Boolean).join(P(` · `))]),e.repo&&i.push([`repo`,L(e.repo)]),e.branch&&i.push([`branch`,F.tool(e.branch)]);let c=e.result?.pull_request;if(c?.url){let e=c.state===`merged`?F.ok(`merged`):c.state===`failed`?F.err(`merge failed: ${L(c.error??``)}`):P(`waits for your approval to merge`);i.push([`pull request`,`${L(c.url)} ${e}`])}else e.result?.push?i.push([`pull request`,P(`pushed to ${L(e.result.push.repo)}; opening one needs GitHub connected in Bitfolk`)]):e.result?.push_error&&i.push([`pull request`,F.warn(`not pushed: ${L(e.result.push_error)}`)]);r.push(...Wn(i,2));let l=e.progress??[];if(l.length){r.push(``);for(let e of l)r.push(W(` ${P(Qa(e.at))} ${L(e.text)}`,12))}let u=e.result?.commits??[];if(u.length){r.push(``,` ${N(`${e.result.commit_count} commit${e.result.commit_count===1?``:`s`}`)}${P(`, ${e.result.files_changed} files, +${e.result.insertions} -${e.result.deletions}`)}`);for(let e of u.slice(0,10))r.push(W(` ${F.tool(e.sha.slice(0,7))} ${L(e.subject)}`,10))}return e.summary&&r.push(``,W(U(L(e.summary)))),e.error&&e.status!==`succeeded`&&r.push(``,W(`${F.err(I.fail)} ${L(e.error)}`)),t.localLog&&r.push(``,W(P(`The tool's full output on this computer: ${t.localLog}`))),r}const Qa=e=>new Date(e).toTimeString().slice(0,8);function $a(e){return e.length?Hn(e.map(e=>[F.tool($(e.id)),N(L(e.name??e.title)),P(R(e.tasks?`${e.open_tasks} of ${e.tasks} tasks open`:`no tasks yet`)),e.status===`paused`?F.warn(`paused`):``]),{indent:2,gap:2,max:M()}):[W(`${P(I.idle)} No open objectives. ${H(`${w} run "<what to do>"`)} starts one.`)]}function eo(e){let t=c(O(),`logs`,`builder-${$(e)}`);return x(t)?t:null}function to(e){let t=e.trim().toLowerCase();if(!/^[0-9a-f-]{4,36}$/.test(t))throw new Q(`"${e}" isn't a session id. Give one, or its last 4 or more characters, as ${w} sessions lists them`);return t}function no(e){if(!e)throw new Q(`link this computer first: ${w} login`);return{m:e,api:new Ht(e.api,()=>jr(e))}}function ro(e){throw e instanceof Bt&&[400,404,429].includes(e.status)&&e.message!==`invalid_body`?new Q(e.message):e}async function io(e,t,n,r){let{m:i,api:a}=no(e),o=t.join(` `).trim();if(!o&&!n.goal)throw new Q(`say what to do: ${w} run "fix the flaky login test", or name an objective with --goal`);if(n.task&&!n.goal)throw new Q(`--task goes with --goal: ${w} run --goal <objective> --task <task>`);let s=Ua(n.runtime,i)??null,c=n.in?da(i,n.in).name:null,l=n.goal?{goal:n.goal,task:n.task??null,note:o.slice(0,2e3)}:{...Ha(o),goal:null},u=await G(n.goal?`Starting a session`:`Starting an objective`,()=>a.start({...l,runtime:s,repo:c})).catch(ro),d=u.session,f=L(d.goal?.title??``);if(console.log(W(U(`${u.goal_created?`New objective`:`Objective`} ${N(f)} ${P(`(${$(d.goal?.id??``)})`)}`))),console.log(W(`${F.ok(I.ok)} Session ${F.tool($(d.id))} ${P(`on`)} ${q(d.runtime)}${d.repo?P(` in ${L(d.repo)}`):``}${d.task?P(` for ${L(d.task.title)}`):``}${u.ahead?P(` · ${u.ahead} waiting before it`):``}`)),n.detach)console.log(W(P(r.upRunning?`${w} up takes it here. Follow it with ${w} logs ${$(d.id)} --follow.`:`It waits until ${w} up runs on this computer.`)));else if(r.upRunning)console.log(W(P(`${w} up on this computer takes it. Following along; Ctrl-C stops following, not the session.`))+`
56
- `),await ao(a,d.id);else{u.ahead&&console.log(W(Jn(`${u.ahead} older session${u.ahead===1?``:`s`} waiting here run${u.ahead===1?`s`:``} first.`))),console.log(W(P(`Running it here, since ${w} up isn't. Ctrl-C stops it.`))+`
52
+ `)}finally{c(),process.removeListener(`exit`,c),process.removeListener(`SIGINT`,l),process.removeListener(`SIGTERM`,l)}}function Ui(e,t=M.depth){return yr(gi(e),``,t)}function Wi(e,n,r){return t(`git`,[`-C`,e,...n],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],env:r}).trim()}function Y(e,t,n){return Wi(e,[`-c`,`core.fsmonitor=false`,`-c`,`core.hooksPath=/dev/null`,...t],n)}function Gi(e,t){let n=c(e,`.git`),r;try{r=te(n)}catch{throw Error(`the worktree's .git is gone`)}let i=se(u(t,Wi(t,[`rev-parse`,`--git-common-dir`]))),a;if(r.isFile()){let t=/^gitdir:\s*(.+?)\s*$/m.exec(ie(n,`utf8`));if(!t)throw Error(`the worktree's .git file was changed`);a=u(e,t[1])}else if(r.isDirectory())a=n;else throw Error(`the worktree's .git was changed`);let o;try{o=se(a)}catch{throw Error(`the worktree's .git points nowhere`)}if(o!==i&&!o.startsWith(c(i,`worktrees`)+d))throw Error(`the worktree's .git no longer points into its repo`)}function Ki(e){try{return Wi(u(e),[`rev-parse`,`--show-toplevel`])}catch{return null}}const qi=e=>`bitfolk/${e.slug}`;function Ji(e,t){try{return Wi(e,[`rev-parse`,`--verify`,`--quiet`,`refs/heads/${t}`]),!0}catch{return!1}}function Yi(e){if(!e.repo){let t=c(k(),`agents`,e.slug),n=!b(t);return n&&x(t,{recursive:!0,mode:448}),{dir:t,created:n}}let t=c(k(),`worktrees`,e.slug),n=qi(e);if(b(c(t,`.git`)))return{dir:t,branch:n,created:!1};if(!Ki(e.repo))throw Error(`${e.repo} is no longer a git repository`);return x(c(k(),`worktrees`),{recursive:!0,mode:448}),Wi(e.repo,[`worktree`,`prune`]),Ji(e.repo,n)?Wi(e.repo,[`worktree`,`add`,t,n]):Wi(e.repo,[`worktree`,`add`,`-b`,n,t,e.base??`HEAD`]),{dir:t,branch:n,created:!0}}function Xi(e,t){return Y(e,[`status`,`--porcelain`])?(Y(e,[`add`,`-A`]),Y(e,[`commit`,`-q`,`--no-verify`,`-m`,t]),Y(e,[`rev-parse`,`--short`,`HEAD`])):null}function Zi(e){if(!e.repo)return null;let t=c(k(),`worktrees`,e.slug);if(!b(t))return null;try{return{dir:t,changed:Wi(t,[`status`,`--porcelain`]).split(`
53
+ `).filter(Boolean).length}}catch{return{dir:t,changed:0}}}function Qi(e){if(!e.repo)return;let t=c(k(),`worktrees`,e.slug);if(b(t))try{Wi(e.repo,[`worktree`,`remove`,`--force`,t])}catch{}}function $i(e){try{return Y(e,[`rev-parse`,`HEAD`])}catch{return null}}function ea(e,t,n){let r=`refs/heads/${n}`,i=Y(e,[`log`,`--format=%h%x09%s`,`-n`,`50`,`${t}..${r}`]).split(`
54
+ `).filter(Boolean).map(e=>{let[t=``,...n]=e.split(` `);return{sha:t,subject:n.join(` `).slice(0,200)}}),a=Y(e,[`diff`,`--no-ext-diff`,`--no-textconv`,`--shortstat`,t,r]),o=e=>Number(e.exec(a)?.[1]??0);return{commits:i,commit_count:Number(Y(e,[`rev-list`,`--count`,`${t}..${r}`]))||i.length,files_changed:o(/(\d+) files? changed/),insertions:o(/(\d+) insertions?/),deletions:o(/(\d+) deletions?/)}}function ta(e){let t=/^(?:https:\/\/(?:[^@/]+@)?github\.com\/|ssh:\/\/git@github\.com(?::\d+)?\/|git@github\.com:)([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?\/?$/.exec(e.trim());return t?`${t[1]}/${t[2]}`:null}const na=/^(?!-)(?!.*\.\.)[A-Za-z0-9._/-]{1,200}$/;function ra(e,t){let n=t?.replace(/^(?:refs\/heads\/|refs\/remotes\/origin\/|origin\/)/,``);if(n&&na.test(n)&&!/^[0-9a-f]{7,64}$/.test(n)&&n!==`HEAD`)return n;try{let t=Wi(e,[`symbolic-ref`,`--quiet`,`--short`,`refs/remotes/origin/HEAD`]).replace(/^origin\//,``);if(na.test(t))return t}catch{}return`main`}function ia(e,n){if(!na.test(n))return null;try{return t(`git`,[`-C`,e,`-c`,`core.hooksPath=/dev/null`,`fetch`,`--quiet`,`--no-tags`,`origin`,`+refs/heads/${n}:refs/remotes/origin/${n}`],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GCM_INTERACTIVE:`never`},timeout:6e4}),Wi(e,[`rev-parse`,`--verify`,`refs/remotes/origin/${n}^{commit}`])}catch{return null}}function aa(e,n,r){if(!/^bitfolk\/[A-Za-z0-9._-]+$/.test(n))return{error:`not a builder branch`};let i;try{i=Wi(e,[`config`,`--get`,`remote.origin.url`])}catch{return{error:`the repo has no origin remote`}}let a=ta(i);if(!a)return{error:`origin isn't a GitHub repository`};let o;try{o=Y(e,[`rev-parse`,`--verify`,`refs/heads/${n}`])}catch{return{error:`${n} is gone`}}try{t(`git`,[`-C`,e,`-c`,`core.hooksPath=/dev/null`,`push`,`--quiet`,`--no-verify`,`origin`,`refs/heads/${n}:refs/heads/${n}`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GCM_INTERACTIVE:`never`},timeout:12e4})}catch(e){let t=e;return{error:((t.stderr||t.message||`push failed`).trim().split(`
55
+ `).filter(Boolean).pop()??`push failed`).slice(0,300)}}return{repo:a,branch:n,base:ra(e,r),head_sha:o}}const oa=e=>`refs/bitfolk/checkpoints/${e}`,sa={GIT_AUTHOR_NAME:`Bitfolk checkpoint`,GIT_AUTHOR_EMAIL:`checkpoint@bitfolk.invalid`,GIT_COMMITTER_NAME:`Bitfolk checkpoint`,GIT_COMMITTER_EMAIL:`checkpoint@bitfolk.invalid`};function ca(e,t){let n;try{n=Y(e,[`rev-parse`,`HEAD`])}catch{return null}let r=ne(c(fe(),`bitfolk-checkpoint-`));try{let i=c(r,`index`),a=u(e,Y(e,[`rev-parse`,`--git-path`,`index`]));b(a)&&ee(a,i);let o={...process.env,...sa,GIT_INDEX_FILE:i};Y(e,[`add`,`-A`],o);let s=Y(e,[`write-tree`],o),l=oa(t),d=null;try{let[t=``,n=``]=Y(e,[`log`,`-1`,`--format=%T %P`,l]).split(` `);d={tree:t,parent:n}}catch{}if(d&&d.tree===s&&d.parent===n)return{head:n,checkpoint:Y(e,[`rev-parse`,l]),changed:!1};let f=Y(e,[`commit-tree`,s,`-p`,n,`-m`,`Bitfolk checkpoint of session ${t}`],o);return Y(e,[`update-ref`,l,f]),{head:n,checkpoint:f,changed:!0}}finally{S(r,{recursive:!0,force:!0})}}function la(e,t){if(!/^[0-9a-f]{7,64}$/.test(t))return!1;try{let n=Y(e,[`rev-parse`,`HEAD`]),[r=``,i=``]=Y(e,[`log`,`-1`,`--format=%T %P`,t]).split(` `);return i!==n||r===Y(e,[`rev-parse`,`HEAD^{tree}`])?!1:(Y(e,[`restore`,`--source=${t}`,`--worktree`,`--`,`.`]),!0)}catch{return!1}}function ua(e,t=30,n=Date.now()){let r=0;try{let i=n/1e3-t*86400;for(let t of Wi(e,[`for-each-ref`,`--format=%(refname) %(committerdate:unix)`,`refs/bitfolk/checkpoints/`]).split(`
56
+ `)){let[n,a]=t.split(` `);n&&Number(a)<i&&(Wi(e,[`update-ref`,`-d`,n]),r++)}}catch{}return r}const da=/^[a-z0-9][a-z0-9._-]{0,39}$/;function fa(e){return i(e).toLowerCase().replace(/[^a-z0-9._-]+/g,`-`).replace(/^[^a-z0-9]+/,``).slice(0,40).replace(/[-.]+$/,``)||`repo`}function X(e){let t=e.repos?.length?e.repos:e.repo?[{name:fa(e.repo),path:e.repo}]:[],n=t.find(t=>t.path===e.repo);return n?[n,...t.filter(e=>e!==n)]:t}const pa=e=>X(e)[0]??null;function ma(e,t){if(!t)return pa(e);let n=X(e).find(e=>e.name===t.toLowerCase());if(!n)throw Error(`this computer has no repo named ${t} (it has: ${X(e).map(e=>e.name).join(`, `)||`none`})`);return n}function ha(e){try{return t(`git`,[`-C`,e,`config`,`--get`,`remote.origin.url`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{return null}}function ga(e){return X(e).map((e,t)=>{let n=ha(e.path);return{name:e.name,default:t===0,github:n?ta(n):null}})}function _a(e,t,n,r=!1){let i=(n??X(e).find(e=>e.path===t)?.name??fa(t)).toLowerCase();if(!da.test(i))throw Error(`a repo name is 1 to 40 lowercase letters, digits, dots, dashes or underscores`);let a=X(e).filter(e=>e.path!==t);if(a.some(e=>e.name===i))throw Error(`there's already a repo named ${i}; pick another with --name`);if(a.length>=20)throw Error(`a computer can have at most 20 repos`);return{repos:[...a,{name:i,path:t}],repo:r||!e.repo||!a.length?t:e.repo}}function va(e,t){let n=X(e),r=n.find(e=>e.name===t.toLowerCase());if(!r)throw Error(`no repo named ${t} here (it has: ${n.map(e=>e.name).join(`, `)||`none`})`);let i=n.filter(e=>e!==r);return{repos:i,repo:e.repo===r.path?i[0]?.path:e.repo}}const ya=(e,t)=>new Promise(n=>{if(t.aborted)return n();let r=setTimeout(i,e);r.unref?.(),t.addEventListener(`abort`,i,{once:!0});function i(){clearTimeout(r),t.removeEventListener(`abort`,i),n()}});var ba=class{#e;#t=new AbortController;done;constructor(e){this.#e=e,this.done=this.#n()}stop(){this.#t.abort()}async#n(){let e=this.#t.signal,t=this.#e.sleep??ya,n,r=0;for(;!e.aborted;){let i;try{i=await this.#e.ask(n,n===void 0?0:25,e)}catch(n){if(e.aborted)return;if(n instanceof q&&n.ended||n instanceof O&&(n.status===401||n.status===403)){this.#e.onEnd?.(`signed_out`);return}r++,await t(Math.min(3e5,5e3*2**(r-1)),e);continue}if(i===null){this.#e.onEnd?.(`unsupported`);return}r=0,i.wake&&n!==void 0&&!e.aborted&&this.#e.onWake(),n=i.signature}}};const xa=36e5,Sa=process.env.BITFOLK_FAST_POLL===`1`,Ca=Sa?3e3:3e4,wa=Sa?3e4:6e5,Ta=Sa?2e3:15e3,Ea=Sa?5e3:6e4,Da=Sa?1e3:5e3,Oa={session_requested:`a session you asked for`,claimable_tasks:`tasks to claim`,my_tasks:`its tasks`,new_messages:`new messages`,mentioned:`a message that tags it`,review_waiting:`a review`,briefing_due:`a briefing`,setup_actions:`setup`,watch_fired:`a watch`},ka=e=>e.map(e=>Oa[e]??e.replace(/_/g,` `)).join(`, `)||`new work`;function Aa(e,t){if(e){if(e.pid)try{process.kill(-e.pid,t);return}catch{}e.kill(t)}}const ja=new WeakSet;function Ma(e,t=1e4){Aa(e,`SIGTERM`),setTimeout(()=>{e&&!ja.has(e)&&Aa(e,`SIGKILL`)},t).unref()}function Na(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m${String(t%60).padStart(2,`0`)}s`}function Pa(e){let t=[];e.costMicros!==null&&t.push(`$${(e.costMicros/1e6).toFixed(e.costMicros>0&&e.costMicros<1e4?4:2)}`);let n=e.inputTokens+e.outputTokens;return n&&t.push(n>=1e3?`${Math.round(n/1e3)}k tokens`:`${n} tokens`),t.join(`, `)}const Fa={info:[()=>F(L.skip),e=>e],idle:[()=>F(L.idle),F],start:[()=>I.accent(L.dot),e=>e],ok:[()=>I.ok(L.ok),e=>e],fail:[()=>I.err(L.fail),I.err],warn:[()=>I.warn(L.warn),I.warn],progress:[()=>F(L.arrow),F]};function Ia(e,t,n){let r=(t.runStarts??[]).filter(e=>e>n-xa).sort((e,t)=>e-t),i=e.maxRunsPerHour-r.length;return{left:i,freesAt:i>0?n:(r[0]??n)+xa}}function La(e,t){if(e.command)return{runtime:`command`,command:e.command};if(t.startsWith(`custom:`)){let n=e.customTools?.find(e=>`custom:${e.name}`===t);if(!n)throw Error(`your workspace asked for ${t.slice(7)}, which isn't set up here (${w} add)`);return n.protocol===`acp`?{runtime:`acp`,acp:{...ot(n.command),agent:t}}:{runtime:`command`,command:n.command}}let n=Ze(t);if(n)return{runtime:n};let r=Gr(t);if(r)return{runtime:`acp`,acp:r};throw Error(`this runner can't start ${t}`)}function Ra(e,t){let n=t.session.retry,r=n?.mode===`fix`&&n.branch?.startsWith(`bitfolk/builder-`)?n.branch.slice(8):null,i=ma(e,t.session.repo)?.path,a=e.pullRequests&&i&&!n?ia(i,ra(i,e.base)):null;return{id:t.builder.id,name:t.builder.name,slug:r&&nn(r)===r?r:nn(`builder-${t.session.id.slice(-8)}`),...La(e,t.session.runtime),api:e.api,token:t.builder.token,repo:i,base:(n?.mode===`redo`&&/^[0-9a-f]{7,64}$/.test(n.base_sha??``)?n.base_sha:null)??a??e.base,maxUsdPerRun:e.maxUsdPerRun,maxRunsPerHour:e.maxRunsPerHour,timeoutMin:e.timeoutMin,permission:e.permission,model:e.model,pullRequests:e.pullRequests}}const Z=`machine`;function za(e=process.env){return Object.fromEntries(Object.entries(e).filter(([e])=>!/^npm_[a-z]/.test(e)&&e!==`INIT_CWD`&&e!==`NODE`))}function Ba(e=process.env,t=ye){let n=(e.PATH??``).split(a).filter(Boolean);if(!t)return n;let r=n.findIndex(e=>/[\\/]node-gyp-bin$/.test(e));return(r>=0?n.slice(r+1):n).filter(e=>!/[\\/]_npx[\\/]/.test(e))}var Va=class{config;state;#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i;#a;#o;#s;#c;#l=!1;#u=null;#d=0;#f=null;#p=0;#m=null;#h=0;#g=!1;#_;#v=null;#y=new Map;#b=0;#x=null;#S=null;#C={day:``,done:0,failed:0,stopped:0,costMicros:0,durationMs:0};constructor(e,t={}){this.config=e,this.state=en(),this.#i=t.out??(e=>process.stdout.write(e+`
57
+ `)),this.#a=t.now??Date.now,this.#o=t.progressMs??1e4,this.#s=t.checkpointMs??18e4,this.#c=t.acpCancelGraceMs,this.#_=!!t.liveFooter}#w(e){return this.state.agents[e.id]??={}}#T(e){let t=this.#r.get(e.id);return t||this.#r.set(e.id,t=new Ut(e.api,e.oauth?()=>Nr(e,{now:this.#a}):e.token)),t}#E(e,t,n=`info`,r){let i=new Date(this.#a()).toTimeString().slice(0,8),[a,o]=Fa[n],s=r?()=>r:a,c=e?e.name:``,l=c?Nn(c)(c):``,u=N(),d=In(o(t));if(u<60){this.#i(H(`${F(i)} ${s()} ${l}${l?` `:``}${d}`,u,4).join(`
58
+ `));return}let f=`${F(i)} ${s()} ${l}${` `.repeat(Math.max(0,12-B(c)))} `;this.#i(H(f+d,u,B(f)).join(`
59
+ `))}#D(){tn(this.state)}#O(e,t){let n=this.#a()+Math.max(1e3,t);return this.#t.set(e.id,n),n}#k(e){let t=(this.#n.get(e.id)??0)+1;return this.#n.set(e.id,t),Math.min(wa,Ta*2**(t-1))}stop(){if(!this.#l){this.#l=!0;for(let e of this.#e.values())this.#A(e,`owner`);this.#m?.()}}#A(e,t){if(e.cancel){let n=e.cancel(t);return n&&t===`owner`&&(e.stopped=!0),n}return t===`owner`&&(e.stopped=!0),Ma(e.child),!0}killAll(){for(let e of this.#e.values())e.stopped=!0,Aa(e.child,`SIGKILL`)}#j(e,t){let n=e=>{this.#l||this.#e.has(e)||(this.#t.set(e,Math.min(this.#t.get(e)??1/0,this.#a())),this.#m?.())},r=e.map(e=>new ba({ask:(t,n,r)=>this.#T(e).wake(t,n,r),onWake:()=>n(e.id)})),i=t?this.#W():null;return i&&r.push(new ba({ask:(e,t,n)=>i.wake(e,t,n),onWake:()=>n(Z)})),r}async#M(){if([...this.#e.values()].some(e=>e.sessionId&&!e.stopped))try{let e=await this.#W()?.peek();e&&this.#I(Z);for(let t of e?.cancel??[])this.#N(t)}catch{}}#N(e){for(let[t,n]of this.#e)if(!(n.sessionId!==e||n.stopped))return this.#E({id:t,name:`Builder`},`canceled from your workspace; stopping it`,`warn`),this.#A(n,`owner`),!0;return!1}#P(e,t){let n=[],r=null,i=JSON.stringify([null,null,null]),a=!1,o=!1,s=async()=>{let r=this.#W();if(a||o||!r)return;let s={input_tokens:t.inputTokens||null,output_tokens:t.outputTokens||null,cost_micros:t.costMicros},c=JSON.stringify(Object.values(s));if(n.length||c!==i){a=!0;try{let t=n.slice(),a=await r.progress(e,{lines:t,...s});if(a.status!==`error`){i=c;let e=new Set(t);for(;n.length&&e.has(n[0]);)n.shift()}a.status===`not_found`&&(o=!0),a.canceled&&!o&&this.#N(e)}finally{a=!1}}},c=setInterval(()=>void s(),this.#o);return{add(e){e&&e!==r&&(r=e,n.push(e),n.length>5&&n.shift())},stop(){o=!0,clearInterval(c)}}}get running(){return this.#e.size}status(){let e=[...this.#e.values()],t=e.map(e=>e.tally?.costMicros).filter(e=>typeof e==`number`),n=e.map(e=>e.startedAt).filter(e=>typeof e==`number`),r=[...this.#t.entries()].filter(([e])=>e!==Z||!this.#f).map(([,e])=>e);return{running:e.length,since:n.length?Math.min(...n):null,costMicros:t.length?t.reduce((e,t)=>e+t,0):null,nextCheckAt:this.#g||this.#h||!r.length?null:Math.min(...r),checking:this.#h>0,stopping:this.#l,sessions:e.map(e=>({name:e.name??``,tool:e.tool??``,title:e.title??``,startedAt:e.startedAt??e.joinedAt??this.#a(),costMicros:e.tally?.costMicros??null,activity:e.activity??null,activityAt:e.activityAt??null,stopping:e.stopped})).sort((e,t)=>e.startedAt-t.startedAt),queued:this.#b,waitingFor:this.#b?this.#x:null,capFreesAt:this.#S,lastCheckAt:this.#v,checkFailure:[...this.#y.values()].sort((e,t)=>e.since-t.since)[0]??null,signedOut:this.#f,runsThisHour:this.config.machine?this.config.machine.maxRunsPerHour-Ia(this.config.machine,this.state.agents[Z]??{},this.#a()).left:null,today:this.#F()}}#F(){let e=new Date(this.#a()).toDateString();return this.#C.day!==e&&(this.#C={day:e,done:0,failed:0,stopped:0,costMicros:0,durationMs:0}),this.#C}#I(e){this.#v=this.#a(),this.#y.delete(e)}#L(e,t,n){let r=t.message;this.#y.set(e,{message:r,since:this.#y.get(e)?.since??this.#a(),retryAt:n})}async#R(e){this.#h++;try{return await e()}finally{this.#h--}}async check(e){let t=this.#w(e);if(t.disabledReason||this.#e.has(e.id))return null;let{left:n,freesAt:r}=Ia(e,t,this.#a());if(n<=0)return this.#E(e,`hit ${e.maxRunsPerHour} runs this hour; next check at ${new Date(r).toTimeString().slice(0,5)}`,`warn`),this.#t.set(e.id,r),null;let i;try{i=await this.#R(()=>this.#T(e).peek(t.etag))}catch(n){if(n instanceof q&&n.ended)return t.disabledReason=`its sign-in ended (unlinked on your workspace, or unused for 90 days)`,this.#E(e,`stopped: ${t.disabledReason}. Copy a new token from its page on your workspace and run \`${w} add <token>\`.`,`fail`),this.#z(e),null;if(n instanceof O&&n.status===401){let r=n.code===`agent_removed`;return t.disabledReason=r?`its owner removed it from Bitfolk`:`token rejected (revoked, or the agent was archived)`,this.#E(e,r?`stopped: ${t.disabledReason}. Run \`${w} rm "${e.name}"\` to forget it.`:`stopped: ${t.disabledReason}. Copy a new token from its page on your workspace and run \`${w} add <token>\` (it keeps your options).`,`fail`),this.#z(e),null}let r=this.#k(e);return this.#E(e,`peek failed (${n.message}); retrying in ${Na(r)}`,`warn`),this.#L(e.id,n,this.#O(e,r)),null}return this.#n.delete(e.id),this.#I(e.id),i?(t.etag=i.etag,t.pollMs=i.next_poll_after_s*1e3,this.#D(),i.tier===`silent`||!i.has_work?(this.#O(e,i.next_poll_after_s*1e3),null):{done:this.#V(e,i)}):(this.#O(e,t.pollMs??Ea),null)}#z(e){this.#t.delete(e.id),this.#n.delete(e.id),this.#y.delete(e.id),this.#D()}#B(e,t,n,r,i={}){return this.#K(e,t,n,r,i).catch(t=>(n.child&&!ja.has(n.child)&&Ma(n.child),n.cancel=void 0,this.#E(e,`couldn't start its run: ${R(t?.message??String(t)).split(`
60
+ `)[0]}`,`fail`),this.#w(e).etag=void 0,this.#O(e,this.#k(e)),null))}#V(e,t,n){let r={child:null,done:Promise.resolve(null),stopped:!1,sessionId:n?.session.id,name:e.name,tool:n?.session.runtime??e.acp?.agent??e.runtime,title:R(n?n.session.task?.title??n.session.goal?.title??`a goal`:`woke for ${ka(t.reasons)}`),joinedAt:this.#a()},i=this.#B(e,t,r,n);return n?.session.retry?.mode===`fix`&&(i=i.then(i=>!i?.resumed||i.status!==`failed`||i.durationMs>=2e4||r.stopped||this.#l?i:(this.#E(e,`couldn't pick up the earlier conversation; starting fresh on the same branch`,`warn`),this.#B(e,t,r,n,{fresh:!0})))),r.done=(n?i.then(t=>this.#G(e,n,t)):i).finally(()=>{this.#e.delete(e.id),this.#m?.()}),this.#e.set(e.id,r),r.done}#H(e,t,n,r){let i=``,a=null,o=()=>a??=(async()=>{let a=this.#W();if(!a)return;let o=null;try{o=ca(t.dir,e)}catch{}let s={branch:t.branch??null,base_sha:n,head_sha:o?.head??null,checkpoint_sha:o?.checkpoint??null,tool_session_id:r.sessionId??null},c=JSON.stringify(s);c!==i&&await a.checkpoint(e,s)&&(i=c)})().finally(()=>{a=null}),s=setInterval(()=>void o(),this.#s);return o(),{async final(){clearInterval(s),await a,await o()},stop:()=>clearInterval(s)}}async#U(e=!1){let t=this.config.machine,n=this.#W();if(!(!t||!n||!e&&this.#d&&this.#a()-this.#d<6e5)){this.#d=this.#a();try{await n.report({usage:Fe(t.runtimes,this.state.usage,{now:this.#a()}),repos:ga(t)})}catch{}}}#W(){let e=this.config.machine;return!e||this.#f?null:this.#u??=new Wt(e.api,()=>Nr(e,{now:this.#a}))}async checkMachine(){let e=this.config.machine,t=this.#W();if(!e||!t)return[];let n=this.state.agents[Z]??={},r={id:Z,name:e.name},i;try{i=await this.#R(()=>t.peek())}catch(e){if(e instanceof q&&e.ended||e instanceof O&&e.status===401)return this.#f=`this machine was unlinked, or its sign-in ended`,this.#E(r,`stopped: ${this.#f}. Run \`${w} login\` to link it again.`,`fail`),[];let t=this.#k(r);this.#E(r,`check-in failed (${e.message}); retrying in ${Na(t)}`,`warn`);let n=this.#a()+t;return this.#t.set(Z,n),this.#L(Z,e,n),[]}this.#n.delete(r.id),this.#I(Z),await this.#U();for(let e of i.cancel??[])this.#N(e);let a=Math.max(1e3,i.next_poll_after_s*1e3);this.#t.set(Z,this.#a()+a);let o=()=>{[...this.#e.values()].some(e=>e.sessionId&&!e.stopped)&&this.#t.set(Z,Math.min(this.#t.get(Z)??1/0,this.#a()+Da))},s=[],c=i.queued;for(this.#x=null,this.#S=null;c>0&&!this.#l;c--){if(this.#e.size>=this.config.maxConcurrent){this.#x=`slot`;break}let{left:i,freesAt:a}=Ia(e,n,this.#a());if(i<=0){this.#x=`cap`,this.#S=a,this.#p!==a&&(this.#p=a,this.#E(r,`hit ${e.maxRunsPerHour} sessions this hour; the rest wait until ${new Date(a).toTimeString().slice(0,5)}`,`warn`)),this.#t.set(Z,a);break}let o;try{o=await this.#R(()=>t.claim({runtimes:e.runtimes,timeout_min:e.timeoutMin}))}catch(e){this.#E(r,`couldn't take a session (${e.message})`,`warn`);break}if(!o){c=0;break}this.#b=Math.max(0,this.#b-1),n.runStarts=[...(n.runStarts??[]).filter(e=>e>this.#a()-xa),this.#a()],this.#D();let l;try{l=Ra(e,o)}catch(e){this.#E(r,`can't run a session: ${e.message}`,`fail`),await t.finish(o.session.id,{status:`failed`,summary:null,error:e.message}).catch(()=>{});continue}let u=R(o.session.task?.title??o.session.goal?.title??`a goal`);this.#E(l,`started a session: ${I.bold(u)} ${F(`·`)} ${I.tool(z(J(o.session.runtime)))}`,`start`,Ui(o.session.runtime));let d=await new Ut(l.api,l.token).peek().catch(()=>null),f={has_work:!0,tier:`full`,reasons:[`session_requested`,...(d?.reasons??[]).filter(e=>e!==`setup_actions`)],briefing_goal_id:o.session.goal?.id??null,etag:d?.etag??``,next_poll_after_s:60,rules:d?.rules};s.push({done:this.#V(l,f,o)})}return this.#b=this.#x?Math.max(0,c):0,o(),s}async#G(e,t,n){let r=n?.status===`succeeded`?`succeeded`:n?.status===`interrupted`?`canceled`:`failed`,i=null;if(n){let t=n.work?.startSha??null,r={commits:[],commit_count:0,files_changed:0,insertions:0,deletions:0};if(n.work?.branch&&t)try{e.repo&&Gi(n.work.dir,e.repo),r=ea(n.work.dir,t,n.work.branch)}catch{}if(i={base:t?.slice(0,12)??null,...r,duration_ms:n.durationMs},e.pullRequests&&e.repo&&n.status===`succeeded`&&r.commit_count>0&&n.work?.branch){let t=aa(e.repo,n.work.branch,e.base);`error`in t?(i.push_error=t.error,this.#E(e,`couldn't push ${I.tool(n.work.branch)} (${t.error}); it stays here for you`,`warn`)):(i.push=t,this.#E(e,`pushed ${I.tool(n.work.branch)} to ${t.repo}; a pull request into ${t.base} waits for your approval`,`ok`))}}try{await this.#W()?.finish(t.session.id,{status:r,summary:n?.tally.summary??null,error:n?n.status===`succeeded`?null:n.tally.error??n.status:`the session couldn't start on this machine`,branch:n?.work?.branch??null,result:i,input_tokens:n?n.tally.inputTokens:null,output_tokens:n?n.tally.outputTokens:null,cost_micros:n?.tally.costMicros??null,model:((e.runtime===`acp`?n?.tally.model??e.model:e.model??n?.tally.model)??null)?.slice(0,100)??null}),i?.commit_count&&this.#E(e,`left ${I.bold(`${i.commit_count} commit${i.commit_count===1?``:`s`}`)} on ${I.tool(n.work.branch)} ${F(`(${i.files_changed} files)`)}`,`ok`)}catch(t){this.#E(e,`couldn't report the session's end (${t.message}); Bitfolk times it out`,`warn`)}let a=n?n.tally.limit??Pe(n.tally.error,this.#a()):null;return a&&(this.state.usage={...this.state.usage,[t.session.runtime]:{...a,at:this.#a()}},a.limited_until&&this.#E(e,`${J(t.session.runtime)} hit its usage limit; sessions go to another tool until ${new Date(a.limited_until).toTimeString().slice(0,5)}`,`warn`)),this.#U(!0),this.#E(e,`session ended`,`idle`),Qi(e),e.repo&&ua(e.repo),delete this.state.agents[e.id],this.#D(),n}async#K(e,t,r,i,o={}){let s=this.#w(e),l=this.#T(e),u=Xe[e.runtime],d=e.runtime===`acp`?e.acp:void 0;if(e.runtime===`acp`&&!d)throw Error(`${e.name} has runtime acp but no ACP command`);let f=this.#a(),m;try{m=Yi(e)}catch(t){return s.etag=void 0,this.#E(e,`can't prepare its workspace: ${t.message}`,`fail`),this.#O(e,this.#k(e)),null}let h=m.branch?$i(m.dir):null,_=i?.session.retry??null,v=!!(_?.mode===`fix`&&m.created&&m.branch&&_.checkpoint_sha&&la(m.dir,_.checkpoint_sha));v&&this.#E(e,`put back the earlier session's uncommitted work on ${I.tool(String(m.branch))}`,`ok`);let y=null;try{y=await l.runStart({client_run_id:ge(),host:de(),runtime:d?d.agent:e.runtime,reasons:t.reasons,tier:t.tier})}catch(n){if(n instanceof O&&n.status===409)return this.#E(e,`is paused by its owner; not starting`,`idle`),this.#O(e,t.next_poll_after_s*1e3||(Sa?Ea:6e5)),null;this.#E(e,`couldn't record the run start (${n.message}); running anyway`,`warn`)}y||await l.status(`working`).catch(()=>{});let ee=o.fresh?null:_?.mode===`fix`?u.resumes!==!1&&_.tool_session_id?_.tool_session_id:null:u.resumes!==!1&&!m.created&&s.sessionId&&s.sessionAt&&f-s.sessionAt<432e5?s.sessionId:null,b=!!m.branch&&!!u.runnerCommits?.(e),te=ni(t,{agentName:e.name,api:e.api,branch:m.branch,runnerCommits:b,resumed:!!ee,session:i?{goal:i.session.goal?.title??null,task:i.session.task?.title??null,note:i.session.note,goalDone:i.session.goal?.done_definition??null,taskSpec:i.session.task?.spec??null,asks:i.session.asks??[],requestedBy:i.session.requested_by??`owner`,requestedByAgent:i.session.requested_by_agent??null,retry:_?{mode:_.mode,branch:_.branch,summary:_.summary,error:_.error,status:_.status,restored:v}:void 0,tool:i.session.runtime,repo:this.config.machine?X(this.config.machine).find(t=>t.path===e.repo)?.name??null:null,computer:i.session.computer??null}:void 0}),ne=u.launch(e,te,ee);s.runStarts=[...(s.runStarts??[]).filter(e=>e>f-xa),f],this.#D(),this.#E(e,`woke ${F(`for ${ka(t.reasons)}`)} → ${I.tool(z(d?`${J(d.agent)} over ACP`:e.runtime))}${ee?F(`, resuming`):``}`,`start`);let re=c(k(),`logs`,e.slug);x(re,{recursive:!0,mode:448});let ie=c(re,`${new Date(f).toISOString().replace(/[:.]/g,`-`)}.jsonl`),ae=new Set([e.token]),oe=e=>[...ae].reduce((e,t)=>e.split(t).join(`[token]`),e),se=(e,t)=>g(ie,JSON.stringify({t:this.#a(),stream:e,line:oe(t)})+`
61
+ `,{mode:384}),ce=zr(),le=Pr(e),ue=e.oauth?setInterval(()=>{e.oauth.expiresAt-this.#a()>6e5||Nr(e,{now:this.#a}).then(()=>{ae.add(e.token),Pr(e)}).catch(t=>this.#E(e,`couldn't renew its sign-in mid-run: ${t.message}`,`warn`))},6e4):null,C=Le();r.tally=C,r.startedAt=this.#a();let fe={...za(),PATH:[ce,...Ba(),...Vr()].join(a),...d?{NO_BROWSER:`1`}:{BITFOLK_TOKEN:e.token},BITFOLK_TOKEN_FILE:le,BITFOLK_API:e.api.replace(/\/+$/,``),BITFOLK_AGENT:e.name,...y?{BITFOLK_RUN_ID:y.id}:{},...i?{BITFOLK_SESSION_ID:i.session.id}:{}};d&&delete fe.BITFOLK_TOKEN;for(let[e,t]of Object.entries(fe))t&&t.length>=12&&/KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH/i.test(e)&&e!==`BITFOLK_TOKEN_FILE`&&ae.add(t);let pe=i?this.#P(i.session.id,C):null,me=i&&m.branch?this.#H(i.session.id,m,h,C):null,he=null,_e=t=>{let n=t&&R(oe(t)).trim();pe?.add(n),n&&n!==he&&(he=n,r.activity=n,r.activityAt=this.#a(),this.#E(e,n,`progress`))},ve=null,w=null,ye=!1,be,xe=null;try{be=await new Promise(t=>{let i=n(ne.bin,ne.args,{cwd:m.dir,env:fe,stdio:[`pipe`,`pipe`,`pipe`],detached:!0});if(r.child=i,i.stdin.on(`error`,()=>{}),d){let t=new It({stdin:i.stdin,stdout:i.stdout,agent:{...e,acp:d},label:J(d.agent),cwd:m.dir,home:k(),packet:te,tally:C,clientVersion:Rt,log:se,activity:_e,kill:()=>{ja.has(i)||Ma(i)},cancelGraceMs:this.#c});r.cancel=e=>t.cancel(e),xe=t.run()}else i.stdin.end(ne.stdin),p({input:i.stdout}).on(`line`,e=>{se(`out`,e),u.parse(e,C),u.activity&&_e(u.activity(e,m.dir))});(this.#l||r.stopped)&&this.#A(r,`owner`),p({input:i.stderr}).on(`line`,e=>{se(`err`,e),e.trim()&&(w=oe(e.trim()).slice(0,300))});let a=setTimeout(()=>{ye=!0,this.#A(r,`timeout`)||(ye=!1)},e.timeoutMin*6e4);i.on(`error`,e=>{ve=e.code===`ENOENT`?`${ne.bin} isn't installed or isn't on PATH`:e.message}),i.on(`close`,e=>{ja.add(i),clearTimeout(a),t({code:e})})})}finally{pe?.stop(),me?.stop(),ue&&clearInterval(ue),S(le,{force:!0})}let Se=xe?await xe:null;r.cancel=void 0,u.afterExit?.(ne,C),S(le,{force:!0});let Ce=this.#a()-f,T,we;if(Se?(T=r.stopped?`interrupted`:C.overBudget?`over_budget`:ve||ye||!Se.ok?`failed`:`succeeded`,we=ve??(T===`over_budget`?C.error:ye&&T===`failed`?`stopped after ${e.timeoutMin} minutes`:T===`failed`?Se.exited?w??`${Se.error??`the tool exited`}${be.code===null?``:` (exit ${be.code})`}`:Se.error??w??`the turn failed`:null),T===`failed`&&(C.error=we)):(T=r.stopped?`interrupted`:C.overBudget?`over_budget`:ve||ye||be.code!==0||C.isError?`failed`:`succeeded`,we=ve??(ye?`stopped after ${e.timeoutMin} minutes`:T===`failed`?C.error??w??`exit ${be.code}`:null)),T===`failed`&&!C.error&&(C.error=we),b&&!ve){let t=`${e.name}: ${C.summary??`work from a Bitfolk run`}`,n=`Bitfolk run${y?` ${y.id}`:``}, ${T}.`;try{e.repo&&m.branch&&Gi(m.dir,e.repo);let r=Xi(m.dir,`${t.length>72?t.slice(0,71)+`…`:t}\n\n${n}`);r&&this.#E(e,`committed its changes as ${I.bold(r)} on ${I.tool(String(m.branch))}`,`ok`)}catch(t){this.#E(e,`couldn't commit its changes: ${t.message.split(`
62
+ `)[0]}`,`warn`)}}await me?.final().catch(()=>{}),T===`failed`&&ee&&Ce<2e4?(s.sessionId=void 0,s.etag=void 0):C.sessionId&&(s.sessionId=C.sessionId,s.sessionAt=this.#a()),(T===`failed`||T===`interrupted`)&&(s.etag=void 0),this.#D();let Te={status:T,exit_code:Se?Se.ok&&T===`succeeded`?0:null:be.code,session_id:C.sessionId,input_tokens:C.inputTokens,output_tokens:C.outputTokens,cost_micros:C.costMicros,summary:C.summary,error:we};y?await l.runFinish(y.id,Te).catch(async()=>{await new Promise(e=>setTimeout(e,2e3)),await l.runFinish(y.id,Te).catch(t=>this.#E(e,`couldn't record the run end: ${t.message}`,`warn`))}):await l.status(`idle`).catch(()=>{});let Ee=this.#F();T===`succeeded`?Ee.done++:T===`interrupted`?Ee.stopped++:Ee.failed++,Ee.costMicros+=C.costMicros??0,Ee.durationMs+=Ce;let De=Pa(C),Oe=T===`succeeded`?I.ok(I.bold(T)):T===`failed`?I.err(I.bold(T)):I.warn(I.bold(T));return this.#E(e,[`${Oe} in ${Na(Ce)}`,...De?De.split(`, `).map(e=>e.startsWith(`$`)?I.money(e):e):[]].join(` ${F(`·`)} `)+`${we?` ${I.err(`(${R(we)})`)}`:``}${C.summary?` ${F(`—`)} ${R(C.summary)}`:``}`,T===`succeeded`?`ok`:T===`failed`?`fail`:`warn`),T===`failed`?this.#O(e,this.#k(e)):(this.#n.delete(e.id),this.#O(e,Ca)),{agent:e.name,status:T,tally:C,durationMs:Ce,work:{dir:m.dir,branch:m.branch,startSha:h},resumed:!!ee}}async run(e={}){this.#g=!!e.once;let t=this.config.agents.filter(e=>!this.#w(e).disabledReason);for(let e of this.config.agents){let t=this.#w(e).disabledReason;t&&this.#E(e,`skipped: ${t}`,`idle`)}let n=this.config.machine;if(t.length===0&&!n)return this.#E(null,`nothing to run. Link this computer with \`${w} login\`.`,`warn`),[];if(e.once){let e=[];if(n){let t=await this.checkMachine();t.length===0&&!this.#f&&this.#E({name:n.name},`no sessions waiting`,`idle`),e.push(...t.map(e=>e.done))}for(let n of t){for(;this.#e.size>=this.config.maxConcurrent;)await Promise.race([...this.#e.values()].map(e=>e.done));let t=await this.check(n);t?e.push(t.done):this.#e.has(n.id)||this.#E(n,`nothing to do`,`idle`)}let r=n?setInterval(()=>void this.#M(),Da):null;try{return(await Promise.all(e)).filter(e=>e!==null)}finally{r&&clearInterval(r)}}let r=[],i=[n?`${n.name} for sessions`:null,t.length?`${t.length} agent${t.length===1?``:`s`}`:null].filter(Boolean).join(` and `);this.#E(null,`watching ${I.bold(i)} ${F(`(up to ${this.config.maxConcurrent} at once).${this.#_?``:` Ctrl-C to stop.`}`)}`,`start`);let a=this.#j(t,!!n);for(;!this.#l;){let e=this.#a();if(n&&!this.#f&&(this.#t.get(Z)??0)<=e)for(let e of await this.checkMachine())e.done.then(e=>e&&r.push(e));for(let n of t){if(this.#l||this.#e.size>=this.config.maxConcurrent)break;this.#e.has(n.id)||this.#w(n).disabledReason||(this.#t.get(n.id)??0)>e||(await this.check(n))?.done.then(e=>e&&r.push(e))}let i=Math.min(...t.filter(e=>!this.#w(e).disabledReason).map(t=>this.#t.get(t.id)??e),n&&!this.#f?this.#t.get(Z)??e:1/0),a=Math.max(1e3,Math.min(6e4,i-this.#a()));await new Promise(e=>{let t=setTimeout(e,a);this.#m=()=>{clearTimeout(t),e()}}),this.#m=null}for(let e of a)e.stop();return await Promise.all([...this.#e.values()].map(e=>e.done)),r}};const Ha=e=>Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e);function Ua(e){for(let t=0;t<20;t++){let t;try{t=ie(e,`utf8`).trim()}catch{return null}if(t)return Number(t)||0;Ha(25)}return 0}function Wa(e){if(!e||e===process.pid)return!1;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function Ga(){let e=Ua(c(k(),`runner.pid`));return e&&Wa(e)?e:null}function Ka(){let e=c(k(),`runner.pid`);x(k(),{recursive:!0,mode:448});let t=String(process.pid),n=()=>{try{ie(e,`utf8`).trim()===t&&S(e,{force:!0})}catch{}};for(let r=0;r<3;r++){try{return ue(e,t,{mode:384,flag:`wx`}),n}catch(e){if(e.code!==`EEXIST`)throw e}let r=Ua(e);if(r===null)continue;if(Wa(r))throw Error(`a runner is already going (pid ${r}). Stop it first, or see \`${w} status\`.`);let i=`${e}.${process.pid}.tmp`;if(ue(i,t,{mode:384}),ce(i,e),Ha(25),Ua(e)===process.pid)return n}throw Error(`another runner is starting at the same moment. Try again, or see \`${w} status\`.`)}var Q=class extends Error{};const $=e=>e.slice(-8);function qa(e){let t=e.trim(),n=t.split(/\r?\n/)[0].trim();if(n===t&&n.length<=200)return{title:n,note:``};let r=n;if(r.length>200){let e=r.slice(0,199),t=e.lastIndexOf(` `);r=`${(t>80?e.slice(0,t):e).trimEnd()}…`}return{title:r,note:t.slice(0,2e3)}}function Ja(e,t){if(!e)return;let n=e.trim().toLowerCase();for(let e of[n,n.replace(/-/g,`_`),Jr(n)])if(t.runtimes.includes(e))return e;throw new Q(`${e} isn't on for this computer (on: ${t.runtimes.map(e=>e.startsWith(`custom:`)?e.slice(7):e.replace(/_/g,`-`)).join(`, `)}). Turn it on with bitfolk add ${e}`)}const Ya=e=>e===null?null:`$${(e/1e6).toFixed(e>0&&e<1e4?4:2)}`,Xa={queued:e=>F(`${L.idle} ${e}`),running:e=>I.sky(`${L.dot} ${e}`),succeeded:e=>I.ok(`${L.ok} ${e}`),failed:e=>I.err(`${L.fail} ${e}`),canceled:e=>F(`${L.skip} ${e}`)},Za=e=>(Xa[e]??(e=>e))(e===`succeeded`?`done`:e);function Qa(e,t=Date.now()){if(!e)return``;let n=Math.max(0,Math.round((t-Date.parse(e))/1e3));return n<60?`just now`:n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:`${Math.floor(n/86400)}d ago`}function $a(e,t=Date.now()){return e.started_at?rr((e.finished_at?Date.parse(e.finished_at):t)-Date.parse(e.started_at)):null}const eo=e=>R(e.task?.title??e.goal?.title??`a goal`);function to(e,t=Date.now()){if(!e.length)return[G(`${F(L.idle)} No sessions on this computer yet. Start one with ${U(`${w} run "<what to do>"`)}.`)];let n=N();return Wn(e.map(e=>{let r=Ya(e.cost_micros),i=e.status===`running`?`${$a(e,t)??``}`:e.status===`queued`?Qa(e.created_at,t):Qa(e.finished_at??e.created_at,t),a=e.status===`running`&&e.last?e.last:e.status===`failed`&&e.error?e.error:!e.task&&e.note?e.note:null,o=a?F(` · ${R(a)}`):``;return[I.tool($(e.id)),Za(e.status),F(z(J(e.runtime))),V(`${P(eo(e))}${o}`,Math.max(20,n-52)),F(z([i,r].filter(Boolean).join(` · `)))]}),{indent:2,gap:2,max:n})}function no(e,t={}){let n=t.now??Date.now(),r=[];r.push(G(`${I.tool($(e.id))} ${Za(e.status)} ${P(eo(e))}`));let i=[];e.task&&e.goal&&i.push([`goal`,R(e.goal.title)]),i.push([`tool`,J(e.runtime)+(e.model?F(` · ${R(e.model)}`):``)]),e.note&&i.push([`note`,R(e.note)]),e.retry_mode&&i.push([`retry`,`${e.retry_mode} of ${$(e.retry_of??``)}`]);let a=$a(e,n);i.push([`started`,e.started_at?`${Qa(e.started_at,n)}${a?F(` · ran ${a}`):``}`:F(`waiting since ${Qa(e.created_at,n)}`)]);let o=(e.input_tokens??0)+(e.output_tokens??0),s=Ya(e.cost_micros);(s||o)&&i.push([`spent`,[s?I.money(s):null,o?F(`${Math.round(o/1e3)}k tokens`):null].filter(Boolean).join(F(` · `))]),e.repo&&i.push([`repo`,R(e.repo)]),e.branch&&i.push([`branch`,I.tool(e.branch)]);let c=e.result?.pull_request;if(c?.url){let e=c.state===`merged`?I.ok(`merged`):c.state===`failed`?I.err(`merge failed: ${R(c.error??``)}`):F(`waits for your approval to merge`);i.push([`pull request`,`${R(c.url)} ${e}`])}else e.result?.push?i.push([`pull request`,F(`pushed to ${R(e.result.push.repo)}; opening one needs GitHub connected in Bitfolk`)]):e.result?.push_error&&i.push([`pull request`,I.warn(`not pushed: ${R(e.result.push_error)}`)]);r.push(...Kn(i,2));let l=e.progress??[];if(l.length){r.push(``);for(let e of l)r.push(G(` ${F(ro(e.at))} ${R(e.text)}`,12))}let u=e.result?.commits??[];if(u.length){r.push(``,` ${P(`${e.result.commit_count} commit${e.result.commit_count===1?``:`s`}`)}${F(`, ${e.result.files_changed} files, +${e.result.insertions} -${e.result.deletions}`)}`);for(let e of u.slice(0,10))r.push(G(` ${I.tool(e.sha.slice(0,7))} ${R(e.subject)}`,10))}return e.summary&&r.push(``,G(W(R(e.summary)))),e.error&&e.status!==`succeeded`&&r.push(``,G(`${I.err(L.fail)} ${R(e.error)}`)),t.localLog&&r.push(``,G(F(`The tool's full output on this computer: ${t.localLog}`))),r}const ro=e=>new Date(e).toTimeString().slice(0,8);function io(e){return e.length?Wn(e.map(e=>[I.tool($(e.id)),P(R(e.name??e.title)),F(z(e.tasks?`${e.open_tasks} of ${e.tasks} tasks open`:`no tasks yet`)),e.status===`paused`?I.warn(`paused`):``]),{indent:2,gap:2,max:N()}):[G(`${F(L.idle)} No open goals. ${U(`${w} run "<what to do>"`)} starts one.`)]}function ao(e){let t=c(k(),`logs`,`builder-${$(e)}`);return b(t)?t:null}function oo(e){let t=e.trim().toLowerCase();if(!/^[0-9a-f-]{4,36}$/.test(t))throw new Q(`"${e}" isn't a session id. Give one, or its last 4 or more characters, as ${w} sessions lists them`);return t}function so(e){if(!e)throw new Q(`link this computer first: ${w} login`);return{m:e,api:new Wt(e.api,()=>Nr(e))}}function co(e){throw e instanceof O&&[400,404,429].includes(e.status)&&e.message!==`invalid_body`?new Q(e.message):e}async function lo(e,t,n,r){let{m:i,api:a}=so(e),o=t.join(` `).trim();if(!o&&!n.goal)throw new Q(`say what to do: ${w} run "fix the flaky login test", or name a goal with --goal`);if(n.task&&!n.goal)throw new Q(`--task goes with --goal: ${w} run --goal <goal> --task <task>`);let s=Ja(n.runtime,i)??null,c=n.in?ma(i,n.in).name:null,l=n.goal?{goal:n.goal,task:n.task??null,note:o.slice(0,2e3)}:{...qa(o),goal:null},u=await K(n.goal?`Starting a session`:`Starting a goal`,()=>a.start({...l,runtime:s,repo:c})).catch(co),d=u.session,f=R(d.goal?.title??``);if(console.log(G(W(`${u.goal_created?`New goal`:`Goal`} ${P(f)} ${F(`(${$(d.goal?.id??``)})`)}`))),console.log(G(`${I.ok(L.ok)} Session ${I.tool($(d.id))} ${F(`on`)} ${J(d.runtime)}${d.repo?F(` in ${R(d.repo)}`):``}${d.task?F(` for ${R(d.task.title)}`):``}${u.ahead?F(` · ${u.ahead} waiting before it`):``}`)),n.detach)console.log(G(F(r.upRunning?`${w} up takes it here. Follow it with ${w} logs ${$(d.id)} --follow.`:`It waits until ${w} up runs on this computer.`)));else if(r.upRunning)console.log(G(F(`${w} up on this computer takes it. Following along; Ctrl-C stops following, not the session.`))+`
63
+ `),await uo(a,d.id);else{u.ahead&&console.log(G(Xn(`${u.ahead} older session${u.ahead===1?``:`s`} waiting here run${u.ahead===1?`s`:``} first.`))),console.log(G(F(`Running it here, since ${w} up isn't. Ctrl-C stops it.`))+`
57
64
  `),await r.runHere();let e=await a.session(d.id).catch(()=>null);e&&console.log(`
58
- `+Za(e,{localLog:eo(e.id)}).join(`
59
- `))}}async function ao(e,t,n={}){let r=n.seen??new Set,i=!1,a=()=>{i=!0,console.log(`\n${P(`Stopped following. The session carries on: ${w} logs ${$(t)} --follow, or ${w} cancel ${$(t)}.`)}`),process.exit(0)};process.once(`SIGINT`,a);let o=null,s=0;try{for(;!i;){try{o=await e.session(t),s=0}catch(e){if(++s>=5)throw e}if(o){for(let e of o.progress??[]){let t=`${e.at}|${e.text}`;r.has(t)||(r.add(t),console.log(W(` ${P(Qa(e.at))} ${L(e.text)}`,12)))}if(![`queued`,`running`].includes(o.status))break}await new Promise(e=>setTimeout(e,3e3))}}finally{process.removeListener(`SIGINT`,a)}if(o){console.log(``);let e=Za({...o,progress:[]},{localLog:eo(o.id)});console.log(e.join(`
60
- `)),o.status===`failed`&&(process.exitCode=1)}}async function oo(e){let{api:t}=no(e),n=await G(`Asking your workspace`,()=>t.sessions(15));console.log(Xa(n).join(`
65
+ `+no(e,{localLog:ao(e.id)}).join(`
66
+ `))}}async function uo(e,t,n={}){let r=n.seen??new Set,i=!1,a=()=>{i=!0,console.log(`\n${F(`Stopped following. The session carries on: ${w} logs ${$(t)} --follow, or ${w} cancel ${$(t)}.`)}`),process.exit(0)};process.once(`SIGINT`,a);let o=null,s=0;try{for(;!i;){try{o=await e.session(t),s=0}catch(e){if(++s>=5)throw e}if(o){for(let e of o.progress??[]){let t=`${e.at}|${e.text}`;r.has(t)||(r.add(t),console.log(G(` ${F(ro(e.at))} ${R(e.text)}`,12)))}if(!Vt(o.status))break}await new Promise(e=>setTimeout(e,3e3))}}finally{process.removeListener(`SIGINT`,a)}if(o){console.log(``);let e=no({...o,progress:[]},{localLog:ao(o.id)});console.log(e.join(`
67
+ `)),o.status===`failed`&&(process.exitCode=1)}}async function fo(e){let{api:t}=so(e),n=await K(`Asking your workspace`,()=>t.sessions(15));console.log(to(n).join(`
61
68
  `)),n.length&&console.log(`
62
- `+W(P(`${w} logs <id> for one session · ${w} cancel <id> to stop one`)))}async function so(e,t,n){let{api:r}=no(e),i=t===void 0?void 0:to(t);if(!i){let e=(await G(`Asking your workspace`,()=>r.sessions(1)))[0];if(!e)throw new Q(`no sessions on this computer yet. Start one with ${w} run "<what to do>"`);i=e.id}let a=await G(`Asking your workspace`,()=>r.session(i)).catch(ro);if(n.follow&&[`queued`,`running`].includes(a.status))return console.log(Za({...a,progress:[],summary:null},{}).join(`
69
+ `+G(F(`${w} logs <id> for one session · ${w} cancel <id> to stop one`)))}async function po(e,t,n){let{api:r}=so(e),i=t===void 0?void 0:oo(t);if(!i){let e=(await K(`Asking your workspace`,()=>r.sessions(1)))[0];if(!e)throw new Q(`no sessions on this computer yet. Start one with ${w} run "<what to do>"`);i=e.id}let a=await K(`Asking your workspace`,()=>r.session(i)).catch(co);if(n.follow&&Vt(a.status))return console.log(no({...a,progress:[],summary:null},{}).join(`
63
70
  `)+`
64
- `),ao(r,a.id);console.log(Za(a,{localLog:eo(a.id)}).join(`
65
- `))}async function co(e,t){let{api:n}=no(e);if(t!==void 0&&(t=to(t)),!t){let e=(await G(`Asking your workspace`,()=>n.sessions(15))).filter(e=>e.status===`queued`||e.status===`running`);if(!e.length)throw new Q(`nothing is waiting or running on this computer`);if(e.length>1)throw new Q(`${e.length} sessions are waiting or running (${e.map(e=>$(e.id)).join(`, `)}). Say which: ${w} cancel <id>`);t=e[0].id}let r=await G(`Canceling`,()=>n.cancel(t)).catch(ro);r.was===`queued`?console.log(U(`Canceled ${F.tool($(r.id))}. It won't start.`)):r.was===`running`?console.log(U(`Canceled ${F.tool($(r.id))}. ${w} up stops it within seconds; its branch stays.`)):console.log(W(`${P(I.idle)} ${F.tool($(r.id))} had already ${r.was===`succeeded`?`finished`:r.was}. Nothing to cancel.`))}async function lo(e){let{api:t}=no(e),n=await G(`Asking your workspace`,()=>t.goals());console.log($a(n).join(`
71
+ `),uo(r,a.id);console.log(no(a,{localLog:ao(a.id)}).join(`
72
+ `))}async function mo(e,t){let{api:n}=so(e);if(t!==void 0&&(t=oo(t)),!t){let e=(await K(`Asking your workspace`,()=>n.sessions(15))).filter(e=>Vt(e.status));if(!e.length)throw new Q(`nothing is waiting or running on this computer`);if(e.length>1)throw new Q(`${e.length} sessions are waiting or running (${e.map(e=>$(e.id)).join(`, `)}). Say which: ${w} cancel <id>`);t=e[0].id}let r=await K(`Canceling`,()=>n.cancel(t)).catch(co);r.was===`queued`?console.log(W(`Canceled ${I.tool($(r.id))}. It won't start.`)):r.was===`running`?console.log(W(`Canceled ${I.tool($(r.id))}. ${w} up stops it within seconds; its branch stays.`)):console.log(G(`${F(L.idle)} ${I.tool($(r.id))} had already ${r.was===`succeeded`?`finished`:r.was}. Nothing to cancel.`))}async function ho(e){let{api:t}=so(e),n=await K(`Asking your workspace`,()=>t.goals());console.log(io(n).join(`
66
73
  `)),n.length&&console.log(`
67
- `+W(P(`${w} run --goal <id or words> "<what to do>" starts a session on one`)))}const uo=`ai.bitfolk.up`,fo=`bitfolk-up.service`,po=[`on`,`off`,`status`,`restart`],mo=e=>`'${e.replace(/'/g,`'\\''`)}'`,ho=e=>e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);function go(e){let t=`exec ${mo(e.node)} ${mo(e.script)} up --no-color`,n=e.shell.split(`/`).pop()??``;return n===`zsh`||n===`bash`?[e.shell,`-lic`,t]:[`/bin/sh`,`-lc`,t]}function _o(e){let t=go(e).map(e=>` <string>${ho(e)}</string>`).join(`
74
+ `+G(F(`${w} run --goal <id or words> "<what to do>" starts a session on one`)))}const go=`ai.bitfolk.up`,_o=`bitfolk-up.service`,vo=[`on`,`off`,`status`,`restart`],yo=e=>`'${e.replace(/'/g,`'\\''`)}'`,bo=e=>e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);function xo(e){let t=`exec ${yo(e.node)} ${yo(e.script)} up --no-color`,n=e.shell.split(`/`).pop()??``;return n===`zsh`||n===`bash`?[e.shell,`-lic`,t]:[`/bin/sh`,`-lc`,t]}function So(e){let t=xo(e).map(e=>` <string>${bo(e)}</string>`).join(`
68
75
  `);return`<?xml version="1.0" encoding="UTF-8"?>
69
76
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
70
77
  <plist version="1.0">
71
78
  <dict>
72
79
  <key>Label</key>
73
- <string>${uo}</string>
80
+ <string>${go}</string>
74
81
  <!-- bitfolk up, kept running. Made by: bitfolk up --service on. Remove with: bitfolk up --service off. -->
75
82
  <key>ProgramArguments</key>
76
83
  <array>
@@ -79,10 +86,10 @@ ${t}
79
86
  <key>EnvironmentVariables</key>
80
87
  <dict>
81
88
  <key>PATH</key>
82
- <string>${ho(e.path)}</string>
89
+ <string>${bo(e.path)}</string>
83
90
  </dict>
84
91
  <key>WorkingDirectory</key>
85
- <string>${ho(e.cwd)}</string>
92
+ <string>${bo(e.cwd)}</string>
86
93
  <key>RunAtLoad</key>
87
94
  <true/>
88
95
  <key>KeepAlive</key>
@@ -90,19 +97,19 @@ ${t}
90
97
  <key>ThrottleInterval</key>
91
98
  <integer>30</integer>
92
99
  <key>StandardOutPath</key>
93
- <string>${ho(e.log)}</string>
100
+ <string>${bo(e.log)}</string>
94
101
  <key>StandardErrorPath</key>
95
- <string>${ho(e.log)}</string>
102
+ <string>${bo(e.log)}</string>
96
103
  </dict>
97
104
  </plist>
98
- `}function vo(e){return`# bitfolk up, kept running. Made by: bitfolk up --service on. Remove with: bitfolk up --service off.
105
+ `}function Co(e){return`# bitfolk up, kept running. Made by: bitfolk up --service on. Remove with: bitfolk up --service off.
99
106
  [Unit]
100
107
  Description=Bitfolk runner (bitfolk up)
101
108
  After=network-online.target
102
109
  Wants=network-online.target
103
110
 
104
111
  [Service]
105
- ExecStart=${go(e).map(e=>`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/%/g,`%%`).replace(/\$/g,`$$$$`)}"`).join(` `)}
112
+ ExecStart=${xo(e).map(e=>`"${e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/%/g,`%%`).replace(/\$/g,`$$$$`)}"`).join(` `)}
106
113
  WorkingDirectory=${e.cwd}
107
114
  Environment=PATH=${e.path}
108
115
  Restart=always
@@ -112,41 +119,41 @@ StandardError=append:${e.log}
112
119
 
113
120
  [Install]
114
121
  WantedBy=default.target
115
- `}const yo=()=>c(C(),`Library`,`LaunchAgents`,`${uo}.plist`),bo=()=>c(process.env.XDG_CONFIG_HOME||c(C(),`.config`),`systemd`,`user`,fo),xo=()=>c(O(),`logs`,`up.log`),So=()=>process.platform===`darwin`?yo():bo(),Co=()=>x(So()),wo=(e,t)=>{let n=r(e,t,{encoding:`utf8`});return{ok:n.status===0,out:`${n.stdout??``}${n.stderr??``}`.trim()}},To=()=>`gui/${pe().uid}`;function Eo(){if(ye)throw new Q(`a service needs bitfolk installed, not run through npx. Run: npm i -g bitfolk then: bitfolk up --service on`);let e=process.argv[1]??``;try{e=oe(e)}catch{}return{node:process.execPath,script:e,shell:process.env.SHELL||pe().shell||`/bin/sh`,path:process.env.PATH||`/usr/local/bin:/usr/bin:/bin`,log:xo(),cwd:C()}}async function Do(){process.platform===`darwin`?wo(`launchctl`,[`bootout`,`${To()}/${uo}`]):wo(`systemctl`,[`--user`,`disable`,`--now`,fo]);for(let e=0;e<40&&Ba();e++)await new Promise(e=>setTimeout(e,250))}async function Oo(e){let t=Date.now()+e;for(;Date.now()<t;){let e=Ba();if(e)return e;await new Promise(e=>setTimeout(e,300))}return null}async function ko(){if(process.platform!==`darwin`&&process.platform!==`linux`)throw new Q(`a service is for macOS and Linux`);let e=Eo();Co()&&await Do();let t=Ba();if(t)throw new Q(`${w} up is already running here (pid ${t}). Stop it first (Ctrl-C in its terminal), then run this again.`);S(o(e.log),{recursive:!0,mode:448});let n=So();S(o(n),{recursive:!0}),ue(n,process.platform===`darwin`?_o(e):vo(e),{mode:420});let r,i=[];if(process.platform===`darwin`)r=wo(`launchctl`,[`bootstrap`,To(),n]),i.push(`Starts when you log in to this Mac. For it to come back after a restart with nobody there, turn on automatic login in System Settings, Users & Groups.`);else{wo(`systemctl`,[`--user`,`daemon-reload`]),r=wo(`systemctl`,[`--user`,`enable`,`--now`,fo]);let e=wo(`loginctl`,[`enable-linger`,pe().username]);i.push(e.ok?`Starts at boot, logged in or not.`:`To start it at boot with nobody logged in, run once: sudo loginctl enable-linger ${pe().username}`)}let a=r.ok?await Oo(2e4):null,s=a?U(`${N(`bitfolk up`)} is running as a service (pid ${a})`):Jn(r.ok?`The service is installed but hasn't started yet. See the log below.`:`The service is installed, but couldn't start now: ${r.out.split(`
116
- `)[0]||`no reason given`}. It starts at your next login.`);console.log([s,...Gn(Wn([[`keeps`,`running after you close ssh; restarts if it stops`],[`log`,e.log],[`file`,n]])),...i.map(e=>P(` ${e}`)),P(` ${w} up --service status · restart · off`)].join(`
117
- `))}async function Ao(){if(!Co())return console.log(`${P(I.idle)} No service is installed here.`);await Do(),ce(So(),{force:!0}),process.platform===`linux`&&wo(`systemctl`,[`--user`,`daemon-reload`]),console.log(`${P(I.idle)} Removed the service. ${N(`bitfolk up`)} no longer runs by itself; sessions wait until you run it.`)}function jo(){if(!Co())return console.log(`${P(I.idle)} No service is installed here. Keep ${w} up running with: ${w} up --service on`);let e=Ba();console.log([e?U(`${N(`bitfolk up`)} is running as a service (pid ${e})`):Jn(`The service is installed but bitfolk up isn't running right now.`),...Gn(Wn([[`log`,xo()],[`file`,So()]])),P(` ${w} up --service restart · off`)].join(`
118
- `))}async function Mo(){if(!Co())throw new Q(`no service is installed here. Start one with: ${w} up --service on`);if(!(process.platform===`darwin`?wo(`launchctl`,[`kickstart`,`-k`,`${To()}/ai.bitfolk.up`]):wo(`systemctl`,[`--user`,`restart`,`bitfolk-up.service`])).ok)return ko();await new Promise(e=>setTimeout(e,1500));let e=await Oo(2e4);console.log(e?U(`Restarted ${N(`bitfolk up`)} (pid ${e}).`):Jn(`Asked it to restart, but it isn't running yet. Log: ${xo()}`))}async function No(e){switch(e){case`on`:return ko();case`off`:return Ao();case`status`:return jo();case`restart`:return Mo();default:throw new Q(`${w} up --service ${po.join(` | `)}`)}}function Po(e){return e.platform===`darwin`&&e.linked&&!e.letSleep}function Fo(e=process.pid){let t=Vr(`caffeinate`);if(!t)return null;let r;try{r=n(t,[`-i`,`-w`,String(e)],{detached:!1,stdio:`ignore`})}catch{return null}return r.on(`error`,()=>{}),r.unref(),()=>{r.exitCode===null&&!r.killed&&r.kill()}}const Io=[[`login`,`Link this computer to your workspace`],[`up`,`Run the sessions your workspace starts, until Ctrl-C`],[`run "<what>"`,`Start a session here now, on a new objective or --goal`],[`sessions`,`This computer's sessions, waiting, running and done`],[`logs [<id>]`,`What a session did; --follow to watch it`],[`cancel <id>`,`Stop a waiting or running session`],[`chat [<objective>]`,`Read or post in your chats (also: board, agents)`],[`approvals`,`What agents wait on you for; approve <id>, deny <id>`],[`status`,`This computer, its workspace, its tools, what's waiting`],[`add <tool>`,`Turn a tool on, or add your own (see bitfolk tools)`],[`rm <tool>`,`Turn a tool off, or remove an agent`],[`set --repo <path>`,`Repos, primary tool (--primary), limits`],[`share <port>`,`Share an app running here at a link`],[`check`,`Check sign-in, tools and repo`],[`bug "<what>"`,`Report a bug to Bitfolk`],[`logout`,`Unlink this computer`]],Lo=e=>[[`--repo <path>`,`Work in this git repo: each session gets its own worktree on a bitfolk/... branch.`],[`--base <branch>`,`Branch the worktree starts from (default: the repo's current HEAD).`],[`--primary <tool>`,`The coding tool sessions use while it has usage left; when it runs low, the tool with the most left (none clears it).`],[`--pull-requests on|off`,`After a session with commits, push its branch to GitHub and open a pull request that merges once you approve it (needs GitHub connected in Bitfolk).`],[`--model <m>`,`Model to pass to the tool.`],[`--permission <p>`,`auto (default), safe or bypass. See bitfolk help permissions.`],[`--max-usd <n>`,`Spend cap per session, where the tool reports cost (default ${e.maxUsdPerRun}).`],[`--max-runs <n>`,`Most sessions per hour (default ${e.maxRunsPerHour}).`],[`--timeout <minutes>`,`Stop a session after this long (default ${e.timeoutMin}).`]];function Ro(e,t){return{login:{usage:[`login [options]`],about:[`Opens your browser to link this computer: sign in, name it, tick its coding tools, press Allow. No token to copy, and sign-in renews by itself. Then run bitfolk up.`,`On a computer you reach over ssh (a server, a Mac Studio), it prints a link instead: open it on your laptop or phone and press Allow, and the terminal finishes by itself. Sessions there use that computer's own Claude Code or Codex sign-in.`],options:[[`--no-browser`,`Print the link instead of opening a browser, to open on any device. Automatic over ssh.`],...Lo(e),[`--api <url>`,`Bitfolk API (default ${t}).`]]},logout:{usage:[`logout`],about:[`Unlinks this computer from your workspace and forgets its sign-in here.`]},up:{usage:[`up [--once] [--let-sleep]`,`up <agent>`,`up --service on | off | status | restart`],about:[`Takes the sessions your workspace starts on this computer (press Run on an objective, from any device), and runs any agents you added, until Ctrl-C. Checking in calls no model, so nothing runs until you ask.`,`On a Mac it keeps the computer awake while it runs. Also: bitfolk start.`,`On a server, or any computer that should always take sessions, run bitfolk up --service on: it keeps running after you close the terminal or ssh, restarts if it stops, and starts again with the computer.`],options:[[`--once`,`Check once, run what's waiting, then stop.`],[`--let-sleep`,`Don't keep the Mac awake.`],[`--service <on|off|status|restart>`,`Run it as a background service (launchd on macOS, systemd on Linux; no sudo).`],[`<agent>`,`Run just one agent you added.`]]},run:{usage:[`run "<what to do>" [options]`,`run --goal <objective> [--task <task>] ["<note>"]`],about:[`Starts a session on this computer from the terminal. With words alone it starts a new objective titled with them (a long text keeps its first line as the title and the rest as the session's note). With --goal it works on an open objective instead, and the words are the note.`,`If bitfolk up is running here, it takes the session within seconds and this command follows along; Ctrl-C stops following, not the session. If not, the session runs in this terminal. The session works like one started from the web: its own worktree and branch, your limits, your workspace's approval rules.`,`An objective or task can be named by its id, the end of its id (bitfolk objectives lists them), or words in its title. Words that match more than one are refused, never guessed.`],options:[[`--goal <objective>`,`Work on this open objective instead of starting a new one.`],[`--task <task>`,`One task on that objective.`],[`--runtime <tool>`,`The coding tool to use: claude-code, codex, or another one on here (default: the one with usage left, your primary first).`],[`--in <repo>`,`Work in this repo, by name (bitfolk repos lists them; default: the default repo).`],[`--detach`,`Only queue it, and return. bitfolk up takes it.`]]},sessions:{usage:[`sessions`],about:[`This computer's sessions, newest first: everything waiting or running, then the latest ones that ended, with their tool, time and cost. The id column is what bitfolk logs and bitfolk cancel take.`]},logs:{usage:[`logs [<id>] [--follow]`],about:[`What one session did: its objective and task, tool, time, spend, branch, every progress line, its commits, and how it ended. Without an id, the newest session. An id can be the end of one, 4 characters or more.`,`The tool's full output stays on this computer, under ~/.bitfolk/logs, and is never sent to your workspace.`],options:[[`--follow, -f`,`Keep printing new lines until the session ends.`]]},cancel:{usage:[`cancel [<id>]`],about:[`Cancels a waiting or running session on this computer, as Cancel does on the web: a waiting one never starts, a running one stops within seconds and its branch stays. Without an id, the one session waiting or running, if there's just one.`]},goals:{usage:[`objectives`,`(or bitfolk goals)`],about:[`The open objectives you can see in this computer's workspace, with their short ids and open tasks, to start work on with bitfolk run --goal <id>.`]},chat:{usage:[`chat`,`chat <objective> [--follow]`,`chat <objective> "<message>"`,`chat workspace "<message>"`],about:[`Your workspace's chats from the terminal, as you. Alone, it lists the workspace chat and every open objective chat, with what waits on you. With a chat, it prints the newest messages; --follow keeps printing new ones until Ctrl-C. With words after the chat, it posts them: agents read what you write as your instruction, the same as a message typed in the app.`,`A chat is named like an objective in bitfolk run: its id, the end of its id, or words in its title. workspace is the chat every member and agent shares. A message of - is read from stdin.`,`It works in a second terminal while bitfolk up runs. A message posted here is never taken as your answer to an approval request: use bitfolk approve for that.`],options:[[`--follow, -f`,`Keep printing new messages until Ctrl-C.`],[`--limit <n>`,`How many of the newest messages to print (default 30, up to 200).`],[`--goal <objective>`,`Name the chat with a flag instead: bitfolk chat --goal <objective> "<message>".`],[`--json`,`Print JSON instead: the reply as one object, or one message per line with --follow.`]]},board:{usage:[`board <objective>`,`board <objective> --add "<title>" [--spec "<what done looks like>"]`],about:[`An objective's task board: each task's short id, status, who holds it, and what a blocked one needs. With --add it puts a task on the board for the agents to pick up. Also: bitfolk tasks.`],options:[[`--add <title>`,`Add a task with this title.`],[`--spec <text>`,`With --add: what done looks like, and anything the taker needs.`],[`--json`,`Print JSON instead.`]]},agents:{usage:[`agents`],about:[`The agents in this computer's workspace, yours first: the tool each runs, whether it is a builder, its health, what it is doing and when it last checked in.`],options:[[`--json`,`Print JSON instead.`]]},approvals:{usage:[`approvals [--all]`],about:[`What your agents are waiting on you for in this workspace: each request's short id, who asks, what for, why and what it touches. Answer one with bitfolk approve <id> or bitfolk deny <id>.`],options:[[`--all`,`Also the requests already answered or expired.`],[`--limit <n>`,`How many to list (default 30, up to 100).`],[`--json`,`Print JSON instead.`]]},approve:{usage:[`approve <id> [--note "<text>"]`,`deny <id> [--note "<text>"]`],about:[`Your answer to one request, by its id or the last 4 or more characters of it, as bitfolk approvals lists them. It counts as your own yes or no, the same as answering in the app, and is recorded as answered from the CLI. An approved session on a computer is queued at once.`,`One kind is refused here: a request sent by a session running on this same computer. Answer that one in the Bitfolk app, so a session can never approve itself.`],options:[[`--note <text>`,`A note the agent reads with your answer.`],[`--json`,`Print JSON instead.`]]},status:{usage:[`status`,`(or just bitfolk)`],about:[`This computer, its workspace, which tools are on, how many sessions wait, and whether bitfolk up is running. Also: bitfolk ls.`]},tools:{usage:[`tools`],about:[`Lists the coding tools found here (Claude Code, Codex, OpenCode, Hermes and more), which are on, and how to turn one on. bitfolk set --primary <tool> picks the one sessions use while it has usage left.`]},repos:{usage:[`repos`,`repos add <path> [--name <name>]`,`repos rm <name>`,`repos default <name>`],about:[`The git repos builders may work in on this computer. Each has a short name (the folder's, unless you give --name); your workspace, its agents and the Run picker see the names and GitHub repos, never the paths.`,`Sessions work in the default repo unless they name another: bitfolk run --in <name>, the Run picker, an agent's request, or a message asking for builders that names the repo. Every session gets its own worktree and branch, so your checkouts stay as they are.`,`Only git repos: for a folder without git, run git init there first.`],options:[[`--name <name>`,`With add: the repo's name (lowercase letters, digits, dot, dash, underscore).`]]},add:{usage:[`add <tool>`,`add <name> --command "<cmd>"`,`add <name> --acp "<cmd>"`,`add bfa_... [options]`],about:[`Turns on a coding tool found here, so your workspace can start it: claude-code, codex, opencode, hermes, and the others bitfolk tools lists.`,`Any other tool: give it a short name and the command to run. With --command it gets the work packet on stdin; with --acp it speaks the Agent Client Protocol on stdio.`,`An agent token (bfa_..., from the agent's page on your workspace) adds a long-lived agent that runs here too.`],options:[[`--command <cmd>`,`A shell command that reads the work packet on stdin.`],[`--acp <cmd>`,`A command that speaks ACP on stdio (runs without a shell).`]],agentOptions:[[`--agent`,`Treat the argument as an agent token.`],[`--runtime <r>`,`claude_code, codex or command (default: from the agent in Bitfolk).`],...Lo(e).slice(0,1)]},tool:{usage:[`add <tool>`,`rm <tool>`],about:[`bitfolk tool add and bitfolk tool rm are the older names for these, and still work. See bitfolk help add and bitfolk help rm.`]},rm:{usage:[`rm <tool>`,`rm <agent>`],about:[`Turns a tool off, or removes one you added. Given an agent's exact name, removes that agent from this computer (its branch and commits stay). When a name is both, add --tool or --agent.`,`If the agent's worktree has changes not yet committed, it stops and says so; add --force to remove it anyway.`],options:[[`--tool`,`It's a coding tool.`],[`--agent`,`It's an agent added here (its name, or the start of its id).`],[`--force`,`Remove an agent even with uncommitted changes in its worktree.`]]},set:{usage:[`set [options]`,`set <agent> [options]`],about:[`Changes the default repo, the primary tool and the limits for sessions on this computer, or for one agent you added. --repo adds the folder to bitfolk repos and makes it the default.`],options:[...Lo(e),[`--runtime <r>`,`Agents only: claude_code, codex or command.`],[`--command <cmd>`,`Agents only, for runtime command.`]]},share:{usage:[`share <port> [--name <name>] [--run <command>] [--keep <hours>] [--personal | --signed-in | --public]`,`share stop <port>`],about:[`Shares an app running here at a link, while the command runs. Bitfolk provides the tunnel: nothing else to install, no ngrok account.`,`Who can open it: workspace members by default (they sign in to Bitfolk), only you with --personal, anyone with a Bitfolk account with --signed-in, or anyone with --public.`,`Coding sessions use --run and --keep, so the app and its link stay up for the workspace after the session ends.`],options:[[`--name <name>`,`What the app is called on your workspace and in its link.`],[`--run <command>`,`Starts the app with this command in this folder, and stops it when sharing stops.`],[`--keep <hours>`,`Shares in the background for up to this many hours, then prints the link and returns.`],[`--personal`,`Only you can open it, signed in to Bitfolk.`],[`--signed-in`,`Anyone with a Bitfolk account can open it. People without one can make one at the link.`],[`--public`,`Anyone with the link can open it, no sign-in.`],[`--approval <id>`,`In a Bitfolk session, --public and --signed-in need an allowed post_public request; give its id.`]]},check:{usage:[`check`],about:[`Checks sign-in, each coding tool, and the repo, and says what to fix. Also: bitfolk doctor.`]},bug:{usage:[`bug "<what happened>" [--email <you@...>]`],about:[`Sends a bug report to Bitfolk, with the CLI version and platform (or pipe the text in).`]},permissions:{usage:[`set --permission <auto|safe|bypass>`],about:[`What a session's tool may do on this computer. Your workspace's approval rules still apply on top.`],options:[[`auto`,`The default. The tool's own auto mode decides.`],[`safe`,`Edits inside its own worktree, bitfolk-api to the workspace, read-mostly git. No curl.`],[`bypass`,`No prompts at all. Only on a machine or container you'd hand over to it.`]]}}}function zo(e){if(e.startsWith(`(`))return P(e);let t=e.split(/(?<=^\S+) /),[n,r]=[t[0],t.slice(1).join(` `)],i=r.replace(/(<[^>]+>|\[[^\]]+\]|"[^"]*")/g,e=>P(e));return`${P(w)} ${N(H(n))}${r?` `+i:``}`}function Bo(e){let t=M(),n=e=>V(e,Math.min(t,100)).join(`
119
- `),r=e.rows===void 0||e.rows>=36?Li({version:e.version,tagline:`Coding sessions for your workspace`,url:`bitfolk.ai`}):[],i=[];return i.push(r.length?r.join(`
120
- `):n(`${N(F.accent(`bitfolk`))} ${e.version}: lets your Bitfolk workspace start coding sessions on this computer.`)),i.push(``),i.push(...Ho(Io,t)),i.push(``),i.push(n(`${H(`bitfolk`)} ${P(`alone shows where things stand.`)} ${H(`bitfolk help <command>`)} ${P(`for options.`)}`)),i.push(n(`${P(`Short name:`)} ${H(`bf`)}${P(`, as in`)} ${H(`bf up`)}${P(`.`)}`)),i.push(n(P(`Try it with npx bitfolk, or install it with npm i -g bitfolk. Node 20+, macOS or Linux.`))),i.join(`
121
- `)}function Vo(e,t){let n=Ro(t.defaults,t.api)[e];if(!n)return;let r=M(),i=[];for(let e of n.usage)i.push(...V(zo(e),r,4));for(let e of n.about)i.push(``,...V(e.replace(/\bbitfolk (help \w+|\w+)/g,e=>H(e)),Math.min(r,100)));return n.options?.length&&(i.push(``,Go(e===`permissions`?`Levels`:`Options`)),i.push(...Hn(n.options.map(([e,t])=>[F.tool(e),t]),{indent:2,gap:2,max:r}))),n.agentOptions?.length&&(i.push(``,Go(`For agents`)),i.push(...Hn(n.agentOptions.map(([e,t])=>[F.tool(e),t]),{indent:2,gap:2,max:r}))),i.join(`
122
- `)}function Ho(e,t){let n=Math.max(...e.map(([e])=>z(zo(e))).filter(e=>e<=Uo)),r=[];for(let[i,a]of e)if(z(zo(i))<=n)r.push(...Hn([[Wo(zo(i),n),a]],{indent:2,gap:2,max:t}));else{let e=t-(n+4)<20?6:n+4;r.push(...V(` `+zo(i),t,4),...V(` `.repeat(e)+a,t,e))}return r}const Uo=26,Wo=(e,t)=>e+` `.repeat(Math.max(0,t-z(e))),Go=e=>N(F.accent(e)),Ko=e=>e.map(e=>R((Vi(e)?Vi(e)+` `:``)+F.tool(q(e)))).join(P(` + `))||P(`no tools`),qo=(e,t)=>F.money(`$${e}`)+P(`/${t}`),Jo=e=>e===`bypass`?F.err(e):e===`auto`?F.warn(e):F.ok(e);function Yo(e){return[N(e.name),Ko(e.runtimes),Jo(e.permission),qo(e.maxUsdPerRun,`session`),`${e.maxRunsPerHour}${P(`/h`)}`,e.repo??P(`no repo`)]}function Xo(e,t,n){let r=[N(e.name),F.tool(e.runtime),Jo(e.permission),qo(e.maxUsdPerRun,`run`),`${e.maxRunsPerHour}${P(`/h`)}`,t];return n&&(r[r.length-1]+=` `+F.err(`STOPPED: ${n}`)),r}const Zo=(e,t=0)=>Un(e,{indent:t,gap:2}),Qo=(e,t)=>[qo(e.maxUsdPerRun,t),`${e.maxRunsPerHour}${P(`/h`)}`,R(`${e.timeoutMin} ${P(`min`)}`),Jo(e.permission)].join(P(` · `));function $o(e,t,n){let r=Sn(),i=n.gap??3,a=r-Math.max(0,...t.map(z))-i,o=a>=n.min&&(!n.fits||n.fits(e(a))),s=e(o?a:r);if(!Ai(s).length)return[t];let c=e=>o?Kn(e,t,i,Math.max(0,Math.ceil((e.length-t.length)/2))):[...e,``,...t];return n.animate?zi(s,c):[c(Ai(s))]}function es(e,t,n=!0){let r=Sn();return $o(t=>Ii(e.id||e.name,t),[...V(`${N(F.accent(e.name))} joined ${N(t)}`,r,2),...V(U(`Linked. Sign-in renews by itself.`),r,2),``,...Wn([[`tools`,Ko(e.runtimes)],[`limits`,Qo(e,`session`)],[`repo`,e.repo??P(`none yet`)]],0,r)],{min:50,animate:n,fits:e=>e.placed.length>=3})}function ts(e,t=!0){let n=e.machine,r=[];n&&(r.push([`machine`,N(n.name)+P(` · ${R(`up to ${e.maxConcurrent} at once`)}`)]),r.push([`workspace`,n.workspace??`your workspace`]),r.push([`tools`,Ko(n.runtimes)]),r.push([`limits`,Qo(n,`session`)]),r.push([`repos`,as(n)?as(n)+(n.pullRequests?P(` · opens pull requests`):``):P(`none: builders work in plain folders`)]),n.primary&&r.push([`primary`,`${q(n.primary)} ${P(`while it has usage left`)}`])),e.agents.length&&r.push([`agents`,e.agents.map(e=>N(e.name)).join(P(`, `))]),n||r.push([`at once`,`up to ${e.maxConcurrent}`]),e.awake===`on`?r.push([`awake`,`${F.ok(`on`)} ${P(R(`(--let-sleep to turn off)`))}`]):e.awake===`off`&&r.push([`awake`,`${P(`off (--let-sleep)`)}`]);let i=Gn(Wn(r,0,Sn()-4),{title:`bitfolk up · v${e.version}`}),a=[...new Set([...n?.runtimes??[],...e.agents.map(e=>e.runtime)])];if(!a.length)return[i];let o=a.map(e=>({id:e,label:q(e)}));return $o(e=>Ni(o,e),i,{min:44,animate:t,fits:e=>e.placed.filter(e=>e.walker).length===o.length})}function ns(e,t,n,r=Date.now()){let i=e.status(),a=t.machine?.runtimes.length??0,o=t.machine?`${a} tool${a===1?``:`s`}`:`${t.agents.length} agent${t.agents.length===1?``:`s`}`,s=(e,t,r)=>sr({text:e,frame:n,elapsedMs:0,timeAfterMs:1/0,detail:t.filter(Boolean).join(` · `),hint:r});if(i.stopping)return s(`Wrapping up`,[i.running?`${i.running} still finishing`:``],`Ctrl-C again to quit now`);if(i.running){let e=t.machine?`builder${i.running===1?``:`s`}`:`run${i.running===1?``:`s`}`,n=i.costMicros===null?``:`$${(i.costMicros/1e6).toFixed(2)}`;return s(`${i.running} ${e} working`,[i.since===null?``:`for ${tr(r-i.since)}`,n],`Ctrl-C to stop`)}if(i.checking)return s(`Checking in with your workspace`,[o],`Ctrl-C to stop`);let c=rs[Math.floor(r/is)%rs.length],l=i.nextCheckAt===null?``:`next check in ${Math.max(1,Math.ceil((i.nextCheckAt-r)/1e3))}s`;return s($n[0],[o,l,c],`Ctrl-C to stop`)}const rs=$n.slice(1).map(e=>e[0].toLowerCase()+e.slice(1)),is=3e4;function as(e){let t=X(e);return t.length?t.length===1?`${t[0].name} ${P(us(t[0].path))}`:t.map((e,t)=>t===0?`${e.name} ${P(`(default)`)}`:e.name).join(P(`, `)):null}function os(e,t,n){return n.rows!==void 0&&n.rows<15?ns(e,t,n.frame,n.now):ms(e.status(),t,n)}const ss=e=>`$${(e/1e6).toFixed(2)}`,cs=e=>e<1500?`just now`:`${tr(e)} ago`,ls=e=>e<1e3?`now`:`in ${tr(e+999)}`,us=e=>{let t=C();return t&&(e===t||e.startsWith(t+`/`))?`~`+e.slice(t.length):e},ds=e=>_r(mi(e),F.tool(I.dot)),fs=e=>On(mi(e),94)(q(e)),ps=()=>P(` · `);function ms(e,t,n){let r=n.now??Date.now(),i=Math.max(20,n.columns-1),a=i-4,o=(n.rows===void 0?10:n.rows>=40?12:n.rows>=24?10:8)-3,s=e.sessions??[],c=t.machine,l=!e.signedOut&&e.checkFailure?e.checkFailure:null,u=_s(e,t,r,l,a),d=bs(e,t,s.length>0),f=e.queued?ys(e,t,r):null,p=[u];if(s.length){let e=o-2-!!f;p.push(...xs(s,a,e,n.frame,r))}else{p.push(vs(e,t,n.frame,r,l));let i=[];c?(i.push(hs(`tools`)+(c.runtimes.map(e=>`${ds(e)} ${fs(e)}`).join(` `)||P(`none on`))+gs(t.awake)),i.push(hs(`limits`)+[F.money(`$${c.maxUsdPerRun}`)+P(`/session`),`${e.runsThisHour??0}${P(`/${c.maxRunsPerHour} this hour`)}`,`${c.timeoutMin}${P(` min each`)}`,`${P(`up to`)} ${t.maxConcurrent} ${P(`at once`)}`].join(ps())),i.push(hs(`repos`)+(as(c)??P(`none: builders work in plain folders`))+(c.primary?P(` · primary ${q(c.primary)}`):``))):i.push(hs(`agents`)+(t.agents.map(e=>N(e.name)).join(P(`, `))||P(`none`))+gs(t.awake)),p.push(...i.slice(0,Math.max(0,o-3-!!f)))}f&&p.push(f),p.push(d);let m=e.signedOut?F.err:l?F.warn:P,h=` ${N(F.accent(`bitfolk up`))} `,g=P(` v${t.version} `),_=Math.max(0,i-3-z(h)-z(g)-1),v=m(`╭─`)+h+m(`─`.repeat(_))+g+m(`─╮`),y=p.slice(0,o).map(e=>m(`│ `)+Bn(B(e,a),a)+m(` │`)),b=m(`╰`+`─`.repeat(i-2)+`╯`),x=e.stopping?[` ${F.warn(`Wrapping up`)}${P(`: letting sessions finish · `)}${F.warn(`Ctrl-C again to quit now`)}`,` ${F.warn(`Ctrl-C again to quit now`)}`]:t.typing?[P(` Type a command below (help lists them) · Ctrl-C to stop`),P(` help · Ctrl-C to stop`)]:[P(` Ctrl-C to stop · ${w} status in another tab`),P(` Ctrl-C to stop`)];return[v,...y,b,B(x.find(e=>z(e)<=i)??x[1],i)]}const hs=e=>P(Bn(e,7)),gs=e=>e===`on`?P(` awake `)+F.ok(`on`):e===`off`?P(` awake off (--let-sleep)`):``;function _s(e,t,n,r,i){let a=t.machine,o=e.lastCheckAt??null,s=(e,t,n=e)=>z(n)<=i?e:t;if(e.signedOut){let t=`${F.err(I.fail)} ${F.err(`Sign-in ended`)}${P(` · run `)}${H(`${w} login`)}${P(` to link it again`)}`;return s(`${t}${P(` · ${e.signedOut}`)}`,`${F.err(I.fail)} ${F.err(`Sign-in ended`)}${P(` · `)}${H(`${w} login`)}`,t)}if(r){let t=F.warn(e.checking?`retrying now`:`retrying ${ls(r.retryAt-n)}`),i=P(o===null?`no check-in yet`:`last check-in ${cs(n-o)}`),a=P(`(${L(r.message)})`),c=`${F.warn(I.warn)} ${F.warn(`Can't reach Bitfolk`)}${ps()}${t}${ps()}${i}`,l=F.warn(e.checking?`now`:ls(r.retryAt-n));return s(`${c} ${a}`,`${F.warn(I.warn)} ${F.warn(`Can't reach Bitfolk`)}${ps()}${l}`,c)}let c=e.checking?F.sky(`checking in now`):P(o===null?`connecting`:`checked in ${cs(n-o)}`),l=!e.checking&&e.nextCheckAt!==null?P(`next ${ls(e.nextCheckAt-n)}`):``,u=e.checking?F.sky(`checking in`):P(o===null?`connecting`:cs(n-o)),d=e=>[e,l].filter(Boolean).join(ps());if(!a)return`${F.ok(I.dot)} ${P(`Watching`)} ${N(`${t.agents.length} agent${t.agents.length===1?``:`s`}`)}${ps()}${d(c)}`;let f=N(a.workspace??`your workspace`),p=`${F.ok(I.dot)} ${P(`Linked to`)} ${f} ${P(`as`)} ${N(a.name)}${ps()}${c}`;return s(`${F.ok(I.dot)} ${P(`Linked to`)} ${f} ${P(`as`)} ${N(a.name)}${ps()}${d(c)}`,`${F.ok(I.dot)} ${f}${ps()}${N(a.name)}${ps()}${d(u)}`,p)}function vs(e,t,n,r,i){if(e.signedOut)return`${P(I.idle)} ${P(`Not checking in, so no new sessions start here`)}`;let a=e.stopping?`Wrapping up`:e.checking?`Checking in with your workspace`:i?`Trying your workspace again`:$n[0],o=e.stopping||e.checking||i?``:P(` ${rs[Math.floor(r/is)%rs.length]}`);return`${or(n)} ${ir(a+`…`,ar(n,[...a].length))}${o}`}function ys(e,t,n){let r=e.queued??0,i=`${P(I.idle)} ${F.accent(`${r} waiting`)}`;if(e.waitingFor===`cap`&&t.machine){let n=e.capFreesAt?new Date(e.capFreesAt).toTimeString().slice(0,5):``;return`${i} ${P(`· hit ${t.machine.maxRunsPerHour} sessions this hour${n?`; next starts at ${n}`:``}`)}`}return`${i} ${P(`for a slot · up to ${t.maxConcurrent} at once`)}`}function bs(e,t,n){let r=e.today??{done:0,failed:0,stopped:0,costMicros:0,durationMs:0},i=[];return r.done+r.failed+r.stopped===0?i.push(P(`nothing finished yet`)):(i.push(`${F.ok(I.ok)} ${r.done} ${P(`done`)}`),r.failed&&i.push(`${F.err(I.fail)} ${r.failed} ${P(`failed`)}`),r.stopped&&i.push(`${F.warn(I.idle)} ${r.stopped} ${P(`stopped`)}`),r.costMicros&&i.push(F.money(ss(r.costMicros))),i.push(P(tr(r.durationMs)))),n&&t.machine&&i.push(`${e.runsThisHour??0}${P(`/${t.machine.maxRunsPerHour} this hour`)}`),hs(`today`)+i.join(ps())}function xs(e,t,n,r,i){let a=e.reduce((e,t)=>t.activityAt!==null&&(!e||t.activityAt>(e.activityAt??-1))?t:e,null)??e[0],o=t<70,s=e=>o&&e===a&&e.activity?2:1,c=e.slice(),l=()=>c.reduce((e,t)=>e+s(t),0)+ +(c.length<e.length);for(;c.length>1&&l()>Math.max(1,n);){let e=[...c].reverse().find(e=>e!==a);c=c.filter(t=>t!==e)}let u=Math.min(12,Math.max(...c.map(e=>z(q(e.tool))))),d=e=>e.costMicros===null?`—`:ss(e.costMicros),f=Math.max(...c.map(e=>z(tr(i-e.startedAt)))),p=Math.max(...c.map(e=>z(d(e)))),m=t-(4+u+2+2+f+2+p+2),h=Math.min(Math.max(...c.map(e=>z(e.title))),Math.max(12,Math.floor(m/2))),g=[];return c.forEach((e,n)=>{let c=e.stopping?F.warn(I.idle):or(r+n*3),l=Vn(tr(i-e.startedAt),f),d=e.costMicros===null?P(Vn(`—`,p)):F.money(Vn(ss(e.costMicros),p)),_=e.stopping?`stopping…`:e.activity?`${I.arrow} ${e.activity}`:`starting…`,v=(t,n)=>{let i=B(t,n);return e===a&&!e.stopping?ir(i,ar(r,[...i].length)):P(i)};if(!o){let t=Math.max(0,m-h);g.push(`${c} ${ds(e.tool)} ${Bn(fs(e.tool),u)} ${Bn(N(B(e.title,h)),h)} ${P(l)} ${d} ${v(_,t)}`);return}let y=`${P(l)} ${d}`,b=t>=50?`${fs(e.tool)}${P(` · `)}`:``,x=t-4-z(y)-2,ee=B(`${b}${N(e.title)}`,x);g.push(`${c} ${ds(e.tool)} ${Bn(ee,x)} ${y}`),s(e)===2&&g.push(` ${v(_,t-4)}`)}),c.length<e.length&&g.push(P(` +${e.length-c.length} more running`)),g}const Ss={start:`up`,ls:`status`,objectives:`goals`,list:`status`,doctor:`check`,remove:`rm`,log:`logs`,chats:`chat`,say:`chat`,tasks:`board`,approval:`approvals`,deny:`approve`},Cs=[`login`,`up`,`run`,`sessions`,`logs`,`cancel`,`goals`,`chat`,`board`,`agents`,`approvals`,`approve`,`status`,`tools`,`add`,`rm`,`set`,`share`,`check`,`bug`,`logout`],ws=e=>Ss[e]??e,Ts=[...Cs,`help`,`version`,`tool`,...Object.keys(Ss)];function Es(e,t){let n=Array.from({length:e.length+1},(e,n)=>Array.from({length:t.length+1},(e,t)=>n?t?0:n:t));for(let r=1;r<=e.length;r++)for(let i=1;i<=t.length;i++)n[r][i]=Math.min(n[r-1][i]+1,n[r][i-1]+1,n[r-1][i-1]+(e[r-1]===t[i-1]?0:1)),r>1&&i>1&&e[r-1]===t[i-2]&&e[r-2]===t[i-1]&&(n[r][i]=Math.min(n[r][i],n[r-2][i-2]+1));return n[e.length][t.length]}function Ds(e){let t=e.toLowerCase(),n,r=1/0;for(let e of Ts){let i=e.startsWith(t)&&t.length>=2?.5:Es(t,e);i<r&&([n,r]=[e,i])}if(!(n===void 0||r>(t.length<=3?1:2)))return n===`tool`?`add`:ws(n)}function Os(e){let[t,n]=e;if(t)return t===`tool`?n===`rm`||n===`add`?n:`tool`:t}const ks=e=>!!e&&/^bfa_/.test(e);function As(e,t,n){let[r,i,...a]=e;if(t.version||r===`version`)return{kind:`version`};if(r===`help`)return{kind:`help`,topic:Os(e.slice(1))};if(t.help)return{kind:`help`,topic:Os(e)};if(!r)return{kind:`status`};switch(r){case`login`:return{kind:`login`};case`logout`:return{kind:`logout`};case`up`:case`start`:return{kind:`up`,agent:i};case`run`:return!i&&!t.goal?{kind:`up`,agent:void 0}:i&&a.length===0&&!t.goal&&n.isAgent(i)?{kind:`up`,agent:i}:{kind:`start`,words:e.slice(1)};case`sessions`:return{kind:`sessions`};case`logs`:case`log`:return{kind:`logs`,session:i};case`cancel`:return{kind:`cancel`,session:i};case`goals`:case`objectives`:return{kind:`goals`};case`chat`:return t.goal?{kind:`chat`,chat:t.goal,words:e.slice(1)}:{kind:`chat`,chat:i,words:a};case`chats`:return{kind:`chat`,chat:void 0,words:[]};case`say`:return i?{kind:`chat`,chat:t.goal??`workspace`,words:e.slice(1)}:{kind:`usage`,message:`what to say? bitfolk say "<message>" [--goal <objective>]`};case`board`:case`tasks`:return{kind:`board`,goal:i??t.goal};case`agents`:return{kind:`agents`};case`approvals`:case`approval`:return{kind:`approvals`};case`approve`:case`deny`:return{kind:`decide`,decision:r,request:i};case`status`:case`ls`:case`list`:return{kind:`status`};case`tools`:return{kind:`tools`};case`tool`:return i!==`add`&&i!==`rm`?{kind:`usage`,message:`tool needs add or rm, as in bitfolk add <tool> or bitfolk rm <tool>`}:{kind:`tool`,action:i,name:a[0]};case`add`:return t.tool&&t.agent?{kind:`usage`,message:`give --agent or --tool, not both`}:ks(i)||t.agent&&!t.tool?{kind:`agent-add`,token:i}:!i&&ks(n.envToken)&&!t.tool?{kind:`agent-add`,token:void 0}:i?{kind:`tool`,action:`add`,name:i}:{kind:`usage`,message:`what to add? bitfolk add <tool> (see bitfolk tools), or bitfolk add bfa_... for an agent`};case`rm`:case`remove`:{if(!i)return{kind:`usage`,message:`what to remove? bitfolk rm <tool>, or bitfolk rm <agent>`};if(t.tool&&t.agent)return{kind:`usage`,message:`give --agent or --tool, not both`};if(t.agent)return{kind:`agent-rm`,key:i};if(t.tool)return{kind:`tool`,action:`rm`,name:i};let e=n.isAgent(i),r=n.isTool(i);return e&&r?{kind:`usage`,message:`${i} is both a coding tool and an agent here. Say which: bitfolk rm ${i} --tool, or bitfolk rm ${i} --agent`}:e?{kind:`agent-rm`,key:i}:r?{kind:`tool`,action:`rm`,name:i}:{kind:`usage`,message:`no tool or agent called ${i} here. See bitfolk status`}}case`repos`:case`repo`:return!i||i===`ls`||i===`list`?{kind:`repos`}:i!==`add`&&i!==`rm`&&i!==`remove`&&i!=="default"?{kind:`usage`,message:`bitfolk repos [add <path> [--name <name>] | rm <name> | default <name>]`}:a[0]?{kind:`repos`,action:i===`remove`?`rm`:i,arg:a[0]}:{kind:`usage`,message:i===`add`?`which folder? bitfolk repos add <path> [--name <name>]`:`which repo? bitfolk repos ${i} <name>`};case`set`:return!i||i===`machine`?{kind:`set-machine`}:{kind:`set-agent`,key:i};case`share`:return i===`stop`?{kind:`share-stop`,port:a[0]}:{kind:`share`,port:i};case`check`:case`doctor`:return{kind:`check`};case`bug`:return{kind:`bug`,words:e.slice(1)};default:return{kind:`unknown`,command:r}}}const js=new Set([`workspace`,`all`,`.`]),Ms=e=>!e||js.has(e.trim().toLowerCase())?null:e.trim();function Ns(e,t=Date.now()){if(!e)return``;let n=Math.max(0,Math.round((t-new Date(e).getTime())/1e3));return n<60?`now`:n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:`${Math.floor(n/86400)}d ago`}function Ps(e,t=Date.now()){let n=Math.round((new Date(e).getTime()-t)/1e3);return n<60?`now`:n<3600?`in ${Math.floor(n/60)}m`:n<86400?`in ${Math.floor(n/3600)}h`:`in ${Math.floor(n/86400)}d`}const Fs=e=>{let t=new Date(e);return`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`},Is=new Set([`started`,`progress`,`completed`,`review`,`joined`,`left`]),Ls={help:`asking for help`,blocked:`blocked`};function Rs(e,t=M()){let n=e.mine?`You`:L(e.sender_name),r=L(e.body);if(Is.has(e.kind))return V(P(`${Fs(e.created_at)} ${n} ${e.kind===`joined`||e.kind===`left`?r:`· ${r}`}`),t,7);let i=[e.sender_type===`leader`?`Coordinator`:null,e.sender_type===`agent`&&e.runtime?q(e.runtime):null,e.builder?`Builder`:null,Ls[e.kind]??null].filter(Boolean),a=e.mine?N(n):jn(n)(N(n));return[`${P(Fs(e.created_at))} ${a}${i.length?P(` ${i.join(` · `)}`):``}`,...e.body.split(/\r?\n/).flatMap(e=>V(` ${L(e)}`,t,7))]}function zs(e,t=M()){let n=e.chat.kind===`workspace`?`${L(e.chat.title)} · workspace chat`:L(e.chat.name??e.chat.title),r=[N(n),``];if(!e.messages.length)return[...r,P(` Quiet so far.`)];for(let n of e.messages)r.push(...Rs(n,t));return r}function Bs(e,t=Date.now()){let n=[[F.tool(`workspace`),N(`${L(e.workspace.name)} · workspace chat`),``,P(Ns(e.workspace.last_message_at,t))]];for(let r of e.objectives){let e=[`${r.agents} agent${r.agents===1?``:`s`}`,r.open_tasks?`${r.open_tasks} open task${r.open_tasks===1?``:`s`}`:null,r.status===`paused`?`paused`:null].filter(Boolean);n.push([F.tool($(r.id)),N(B(L(r.name??r.title),56)),r.waiting_on_you?F.warn(R(`${r.waiting_on_you} waiting on you`)):P(R(e.join(` · `))),P(Ns(r.last_message_at,t))])}return Hn(n,{indent:2,gap:2,max:M()})}const Vs={open:P,claimed:F.sky,in_progress:F.sky,blocked:F.warn,in_review:F.accent,done:F.ok};function Hs(e){let t=[N(L(e.objective.name??e.objective.title)),``];if(!e.tasks.length)return[...t,W(`${P(I.idle)} No tasks yet. ${H(`${w} board ${$(e.objective.id)} --add "<title>"`)} adds one.`)];let n=e.tasks.map(e=>[F.tool($(e.id)),(Vs[e.status]??P)(R(e.status.replace(/_/g,` `))),`${e.parent_task_id?P(`↳ `):``}${L(e.title)}`,P(R(e.assignee?L(e.assignee):``)),e.status===`blocked`&&e.blocked_need?F.warn(`needs: ${L(e.blocked_need)}`):``]);return[...t,...Hn(n,{indent:2,gap:2,max:M()})]}const Us={healthy:F.ok,new:F.sky,late:F.warn,silent:F.warn,paused:P,abandoned:F.err};function Ws(e,t=Date.now()){return e.length?Hn(e.map(e=>[N(L(e.name)),P(R(`${q(e.runtime)}${e.builder?` · builder`:``}`)),(Us[e.health]??P)(e.health),P(R(e.doing?L(e.doing):e.activity.replace(/_/g,` `))),P(e.last_seen_at?Ns(e.last_seen_at,t):`never checked in`)]),{indent:2,gap:2,max:M()}):[W(`${P(I.idle)} No agents in this workspace yet. Add one from the Agents page.`)]}const Gs={message_external:`message outside`,post_public:`post publicly`,spend_money:`spend money`,delete:`delete`,code_deploy:`deploy`,schema_change:`change a schema`,use_computer:`use a computer`,practice:`practice`},Ks={pending:F.warn,deferred:F.warn,approved:F.ok,denied:F.err,expired:P};function qs(e,t=Date.now(),n=M()){if(!e.length)return[W(`${F.ok(I.ok)} Nothing is waiting on you.`)];let r=[];for(let i of e){let e=i.status===`pending`||i.status===`deferred`,a=(Ks[i.status]??P)(e?`waiting`:i.status);r.push(...V(`${F.tool($(i.id))} ${a} ${N(L(i.title))}`,n,10));let o=[L(i.agent),Gs[i.action_type]??i.action_type.replace(/_/g,` `),i.risk?`${i.risk} risk`:null,i.objective?L(i.objective):null,e&&i.expires_at?`expires ${Ps(i.expires_at,t)}`:null,!e&&i.decided_via?`answered ${i.decided_via===`cli`?`from the CLI`:`via ${i.decided_via.replace(/_/g,` `)}`}`:null].filter(Boolean);if(r.push(...V(` ${P(o.join(` · `))}`,n,10)),e&&i.why&&r.push(...V(` ${P(`why:`)} ${L(i.why)}`,n,10)),e&&i.target&&r.push(...V(` ${P(`touches:`)} ${L(i.target)}`,n,10)),e&&i.preview?.trim()){let e=i.preview.trim().split(/\r?\n/).slice(0,6);r.push(...V(` ${P(`preview:`)} ${L(e[0])}`,n,10));for(let t of e.slice(1))r.push(...V(` ${L(t)}`,n,10));i.preview.trim().split(/\r?\n/).length>e.length&&r.push(` ${P(`…`)}`)}e&&i.tainted&&r.push(...V(` ${F.warn(`The agent read outside content before asking. Read the request closely.`)}`,n,10)),r.push(``)}return r.pop(),r}function Js(e){if(!e)throw new Q(`link this computer first: ${w} login`);return{m:e,api:new Ht(e.api,()=>jr(e))}}function Ys(e){throw e instanceof Bt&&[400,403,404,429].includes(e.status)&&e.message!==`invalid_body`?new Q(e.message):e}const Xs=(e,t)=>(e.json?t():G(`Asking your workspace`,t)).catch(Ys),Zs=e=>console.log(JSON.stringify(e,null,2));function Qs(e,t){if(e.limit===void 0)return t;let n=Number(e.limit);if(!Number.isInteger(n)||n<1||n>200)throw new Q(`--limit must be a whole number from 1 to 200`);return n}async function $s(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf8`).trim()}async function ec(e,t,n,r,i={}){let{api:a}=Js(e);if(t===void 0){let e=await Xs(r,()=>a.chats());return r.json?Zs(e):(console.log(Bs(e).join(`
122
+ `}const wo=()=>c(C(),`Library`,`LaunchAgents`,`${go}.plist`),To=()=>c(process.env.XDG_CONFIG_HOME||c(C(),`.config`),`systemd`,`user`,_o),Eo=()=>c(k(),`logs`,`up.log`),Do=()=>process.platform===`darwin`?wo():To(),Oo=()=>b(Do()),ko=(e,t)=>{let n=r(e,t,{encoding:`utf8`});return{ok:n.status===0,out:`${n.stdout??``}${n.stderr??``}`.trim()}},Ao=()=>`gui/${pe().uid}`;function jo(){if(ye)throw new Q(`a service needs bitfolk installed, not run through npx. Run: npm i -g bitfolk then: bitfolk up --service on`);let e=process.argv[1]??``;try{e=se(e)}catch{}return{node:process.execPath,script:e,shell:process.env.SHELL||pe().shell||`/bin/sh`,path:process.env.PATH||`/usr/local/bin:/usr/bin:/bin`,log:Eo(),cwd:C()}}async function Mo(){process.platform===`darwin`?ko(`launchctl`,[`bootout`,`${Ao()}/${go}`]):ko(`systemctl`,[`--user`,`disable`,`--now`,_o]);for(let e=0;e<40&&Ga();e++)await new Promise(e=>setTimeout(e,250))}async function No(e){let t=Date.now()+e;for(;Date.now()<t;){let e=Ga();if(e)return e;await new Promise(e=>setTimeout(e,300))}return null}async function Po(){if(process.platform!==`darwin`&&process.platform!==`linux`)throw new Q(`a service is for macOS and Linux`);let e=jo();Oo()&&await Mo();let t=Ga();if(t)throw new Q(`${w} up is already running here (pid ${t}). Stop it first (Ctrl-C in its terminal), then run this again.`);x(o(e.log),{recursive:!0,mode:448});let n=Do();x(o(n),{recursive:!0}),ue(n,process.platform===`darwin`?So(e):Co(e),{mode:420});let r,i=[];if(process.platform===`darwin`)r=ko(`launchctl`,[`bootstrap`,Ao(),n]),i.push(`Starts when you log in to this Mac. For it to come back after a restart with nobody there, turn on automatic login in System Settings, Users & Groups.`);else{ko(`systemctl`,[`--user`,`daemon-reload`]),r=ko(`systemctl`,[`--user`,`enable`,`--now`,_o]);let e=ko(`loginctl`,[`enable-linger`,pe().username]);i.push(e.ok?`Starts at boot, logged in or not.`:`To start it at boot with nobody logged in, run once: sudo loginctl enable-linger ${pe().username}`)}let a=r.ok?await No(2e4):null,s=a?W(`${P(`bitfolk up`)} is running as a service (pid ${a})`):Xn(r.ok?`The service is installed but hasn't started yet. See the log below.`:`The service is installed, but couldn't start now: ${r.out.split(`
123
+ `)[0]||`no reason given`}. It starts at your next login.`);console.log([s,...qn(Kn([[`keeps`,`running after you close ssh; restarts if it stops`],[`log`,e.log],[`file`,n]])),...i.map(e=>F(` ${e}`)),F(` ${w} up --service status · restart · off`)].join(`
124
+ `))}async function Fo(){if(!Oo())return console.log(`${F(L.idle)} No service is installed here.`);await Mo(),S(Do(),{force:!0}),process.platform===`linux`&&ko(`systemctl`,[`--user`,`daemon-reload`]),console.log(`${F(L.idle)} Removed the service. ${P(`bitfolk up`)} no longer runs by itself; sessions wait until you run it.`)}function Io(){if(!Oo())return console.log(`${F(L.idle)} No service is installed here. Keep ${w} up running with: ${w} up --service on`);let e=Ga();console.log([e?W(`${P(`bitfolk up`)} is running as a service (pid ${e})`):Xn(`The service is installed but bitfolk up isn't running right now.`),...qn(Kn([[`log`,Eo()],[`file`,Do()]])),F(` ${w} up --service restart · off`)].join(`
125
+ `))}async function Lo(){if(!Oo())throw new Q(`no service is installed here. Start one with: ${w} up --service on`);if(!(process.platform===`darwin`?ko(`launchctl`,[`kickstart`,`-k`,`${Ao()}/ai.bitfolk.up`]):ko(`systemctl`,[`--user`,`restart`,`bitfolk-up.service`])).ok)return Po();await new Promise(e=>setTimeout(e,1500));let e=await No(2e4);console.log(e?W(`Restarted ${P(`bitfolk up`)} (pid ${e}).`):Xn(`Asked it to restart, but it isn't running yet. Log: ${Eo()}`))}async function Ro(e){switch(e){case`on`:return Po();case`off`:return Fo();case`status`:return Io();case`restart`:return Lo();default:throw new Q(`${w} up --service ${vo.join(` | `)}`)}}function zo(e){return e.platform===`darwin`&&e.linked&&!e.letSleep}function Bo(e=process.pid){let t=Ur(`caffeinate`);if(!t)return null;let r;try{r=n(t,[`-i`,`-w`,String(e)],{detached:!1,stdio:`ignore`})}catch{return null}return r.on(`error`,()=>{}),r.unref(),()=>{r.exitCode===null&&!r.killed&&r.kill()}}const Vo=[[`login`,`Link this computer to your workspace`],[`up`,`Link this computer if needed, and take sessions until Ctrl-C`],[`run "<what>"`,`Start a session here now, on a new goal or --goal`],[`sessions`,`This computer's sessions, waiting, running and done`],[`logs [<id>]`,`What a session did; --follow to watch it`],[`cancel <id>`,`Stop a waiting or running session`],[`chat [<goal>]`,`Read or post in your chats (also: board, agents)`],[`approvals`,`What agents wait on you for; approve <id>, deny <id>`],[`status`,`This computer, its workspace, its tools, what's waiting`],[`add <tool>`,`Turn a tool on, or add your own (see bitfolk tools)`],[`rm <tool>`,`Turn a tool off, or remove an agent`],[`set --repo <path>`,`Repos, primary tool (--primary), limits`],[`share <port>`,`Share an app running here at a link`],[`check`,`Check sign-in, tools and repo`],[`bug "<what>"`,`Report a bug to Bitfolk`],[`logout`,`Unlink this computer`]],Ho=e=>[[`--repo <path>`,`Work in this git repo: each session gets its own worktree on a bitfolk/... branch.`],[`--base <branch>`,`Branch the worktree starts from (default: the repo's current HEAD).`],[`--primary <tool>`,`The coding tool sessions use while it has usage left; when it runs low, the tool with the most left (none clears it).`],[`--pull-requests on|off`,`After a session with commits, push its branch to GitHub and open a pull request that merges once you approve it (needs GitHub connected in Bitfolk).`],[`--model <m>`,`Model to pass to the tool.`],[`--permission <p>`,`auto (default), safe or bypass. See bitfolk help permissions.`],[`--max-usd <n>`,`Spend cap per session, where the tool reports cost (default ${e.maxUsdPerRun}).`],[`--max-runs <n>`,`Most sessions per hour (default ${e.maxRunsPerHour}).`],[`--timeout <minutes>`,`Stop a session after this long (default ${e.timeoutMin}).`]];function Uo(e,t){return{login:{usage:[`login [options]`],about:[`Opens your browser to link this computer: sign in, name it, tick its coding tools, press Allow. No token to copy, and sign-in renews by itself. Each coding tool you tick becomes a builder in your workspace. Then run bitfolk up (or just run bitfolk up: it links the computer first when it isn't linked).`,`Run it inside a git repo and, unless you set one already, builders work in that repo, each session in its own worktree and branch.`,`On a computer you reach over ssh (a server, a Mac Studio), it prints a link instead: open it on your laptop or phone and press Allow, and the terminal finishes by itself. Sessions there use that computer's own Claude Code or Codex sign-in.`],options:[[`--no-browser`,`Print the link instead of opening a browser, to open on any device. Automatic over ssh.`],[`--no-repo`,`Don't make the git repo you're in the one builders work in.`],...Ho(e),[`--api <url>`,`Bitfolk API (default ${t}).`]]},logout:{usage:[`logout`],about:[`Unlinks this computer from your workspace and forgets its sign-in here.`]},up:{usage:[`up [--once] [--let-sleep]`,`up <agent>`,`up --service on | off | status | restart`],about:[`Takes the sessions your workspace starts on this computer (press Run on a goal, or mention a builder like @Claude Code in a goal chat, from any device), and runs any agents you added, until Ctrl-C. Checking in calls no model, so nothing runs until you ask.`,`On a computer that isn't linked yet it runs bitfolk login first, so one command sets a computer up: npx bitfolk@latest up.`,`On a Mac it keeps the computer awake while it runs. Also: bitfolk start.`,`On a server, or any computer that should always take sessions, run bitfolk up --service on: it keeps running after you close the terminal or ssh, restarts if it stops, and starts again with the computer.`],options:[[`--once`,`Check once, run what's waiting, then stop.`],[`--let-sleep`,`Don't keep the Mac awake.`],[`--service <on|off|status|restart>`,`Run it as a background service (launchd on macOS, systemd on Linux; no sudo).`],[`<agent>`,`Run just one agent you added.`]]},run:{usage:[`run "<what to do>" [options]`,`run --goal <goal> [--task <task>] ["<note>"]`],about:[`Starts a session on this computer from the terminal. With words alone it starts a new goal titled with them (a long text keeps its first line as the title and the rest as the session's note). With --goal it works on an open goal instead, and the words are the note.`,`If bitfolk up is running here, it takes the session within seconds and this command follows along; Ctrl-C stops following, not the session. If not, the session runs in this terminal. The session works like one started from the web: its own worktree and branch, your limits, your workspace's approval rules.`,`A goal or task can be named by its id, the end of its id (bitfolk objectives lists them), or words in its title. Words that match more than one are refused, never guessed.`],options:[[`--goal <goal>`,`Work on this open goal instead of starting a new one.`],[`--task <task>`,`One task on that goal.`],[`--runtime <tool>`,`The coding tool to use: claude-code, codex, or another one on here (default: the one with usage left, your primary first).`],[`--in <repo>`,`Work in this repo, by name (bitfolk repos lists them; default: the default repo).`],[`--detach`,`Only queue it, and return. bitfolk up takes it.`]]},sessions:{usage:[`sessions`],about:[`This computer's sessions, newest first: everything waiting or running, then the latest ones that ended, with their tool, time and cost. The id column is what bitfolk logs and bitfolk cancel take.`]},logs:{usage:[`logs [<id>] [--follow]`],about:[`What one session did: its goal and task, tool, time, spend, branch, every progress line, its commits, and how it ended. Without an id, the newest session. An id can be the end of one, 4 characters or more.`,`The tool's full output stays on this computer, under ~/.bitfolk/logs, and is never sent to your workspace.`],options:[[`--follow, -f`,`Keep printing new lines until the session ends.`]]},cancel:{usage:[`cancel [<id>]`],about:[`Cancels a waiting or running session on this computer, as Cancel does on the web: a waiting one never starts, a running one stops within seconds and its branch stays. Without an id, the one session waiting or running, if there's just one.`]},goals:{usage:[`objectives`,`(or bitfolk goals)`],about:[`The open goals you can see in this computer's workspace, with their short ids and open tasks, to start work on with bitfolk run --goal <id>.`]},chat:{usage:[`chat`,`chat <goal> [--follow]`,`chat <goal> "<message>"`,`chat workspace "<message>"`],about:[`Your workspace's chats from the terminal, as you. Alone, it lists the workspace chat and every open goal chat, with what waits on you. With a chat, it prints the newest messages; --follow keeps printing new ones until Ctrl-C. With words after the chat, it posts them: agents read what you write as your instruction, the same as a message typed in the app.`,`A chat is named like a goal in bitfolk run: its id, the end of its id, or words in its title. workspace is the chat every member and agent shares. A message of - is read from stdin.`,`It works in a second terminal while bitfolk up runs. A message posted here is never taken as your answer to an approval request: use bitfolk approve for that.`],options:[[`--follow, -f`,`Keep printing new messages until Ctrl-C.`],[`--limit <n>`,`How many of the newest messages to print (default 30, up to 200).`],[`--goal <goal>`,`Name the chat with a flag instead: bitfolk chat --goal <goal> "<message>".`],[`--json`,`Print JSON instead: the reply as one object, or one message per line with --follow.`]]},board:{usage:[`board <goal>`,`board <goal> --add "<title>" [--spec "<what done looks like>"]`],about:[`A goal's task board: each task's short id, status, who holds it, and what a blocked one needs. With --add it puts a task on the board for the agents to pick up. Also: bitfolk tasks.`],options:[[`--add <title>`,`Add a task with this title.`],[`--spec <text>`,`With --add: what done looks like, and anything the taker needs.`],[`--json`,`Print JSON instead.`]]},agents:{usage:[`agents`],about:[`The agents in this computer's workspace, yours first: the tool each runs, whether it is a builder, its health, what it is doing and when it last checked in.`],options:[[`--json`,`Print JSON instead.`]]},approvals:{usage:[`approvals [--all]`],about:[`What your agents are waiting on you for in this workspace: each request's short id, who asks, what for, why and what it touches. Answer one with bitfolk approve <id> or bitfolk deny <id>.`],options:[[`--all`,`Also the requests already answered or expired.`],[`--limit <n>`,`How many to list (default 30, up to 100).`],[`--json`,`Print JSON instead.`]]},approve:{usage:[`approve <id> [--note "<text>"]`,`deny <id> [--note "<text>"]`],about:[`Your answer to one request, by its id or the last 4 or more characters of it, as bitfolk approvals lists them. It counts as your own yes or no, the same as answering in the app, and is recorded as answered from the CLI. An approved session on a computer is queued at once.`,`One kind is refused here: a request sent by a session running on this same computer. Answer that one in the Bitfolk app, so a session can never approve itself.`],options:[[`--note <text>`,`A note the agent reads with your answer.`],[`--json`,`Print JSON instead.`]]},status:{usage:[`status`,`(or just bitfolk)`],about:[`This computer, its workspace, which tools are on, how many sessions wait, and whether bitfolk up is running. Also: bitfolk ls.`]},tools:{usage:[`tools`],about:[`Lists the coding tools found here (Claude Code, Codex, OpenCode, Hermes and more), which are on, and how to turn one on. bitfolk set --primary <tool> picks the one sessions use while it has usage left.`]},repos:{usage:[`repos`,`repos add <path> [--name <name>]`,`repos rm <name>`,`repos default <name>`],about:[`The git repos builders may work in on this computer. Each has a short name (the folder's, unless you give --name); your workspace, its agents and the Run picker see the names and GitHub repos, never the paths.`,`Sessions work in the default repo unless they name another: bitfolk run --in <name>, the Run picker, an agent's request, or a message asking for builders that names the repo. Every session gets its own worktree and branch, so your checkouts stay as they are.`,`Only git repos: for a folder without git, run git init there first.`],options:[[`--name <name>`,`With add: the repo's name (lowercase letters, digits, dot, dash, underscore).`]]},add:{usage:[`add <tool>`,`add <name> --command "<cmd>"`,`add <name> --acp "<cmd>"`,`add bfa_... [options]`],about:[`Turns on a coding tool found here, so your workspace can start it: claude-code, codex, opencode, hermes, and the others bitfolk tools lists.`,`Any other tool: give it a short name and the command to run. With --command it gets the work packet on stdin; with --acp it speaks the Agent Client Protocol on stdio.`,`An agent token (bfa_..., from the agent's page on your workspace) adds a long-lived agent that runs here too.`],options:[[`--command <cmd>`,`A shell command that reads the work packet on stdin.`],[`--acp <cmd>`,`A command that speaks ACP on stdio (runs without a shell).`]],agentOptions:[[`--agent`,`Treat the argument as an agent token.`],[`--runtime <r>`,`claude_code, codex or command (default: from the agent in Bitfolk).`],...Ho(e).slice(0,1)]},tool:{usage:[`add <tool>`,`rm <tool>`],about:[`bitfolk tool add and bitfolk tool rm are the older names for these, and still work. See bitfolk help add and bitfolk help rm.`]},rm:{usage:[`rm <tool>`,`rm <agent>`],about:[`Turns a tool off, or removes one you added. Given an agent's exact name, removes that agent from this computer (its branch and commits stay). When a name is both, add --tool or --agent.`,`If the agent's worktree has changes not yet committed, it stops and says so; add --force to remove it anyway.`],options:[[`--tool`,`It's a coding tool.`],[`--agent`,`It's an agent added here (its name, or the start of its id).`],[`--force`,`Remove an agent even with uncommitted changes in its worktree.`]]},set:{usage:[`set [options]`,`set <agent> [options]`],about:[`Changes the default repo, the primary tool and the limits for sessions on this computer, or for one agent you added. --repo adds the folder to bitfolk repos and makes it the default.`],options:[...Ho(e),[`--runtime <r>`,`Agents only: claude_code, codex or command.`],[`--command <cmd>`,`Agents only, for runtime command.`]]},share:{usage:[`share <port> [--name <name>] [--run <command>] [--keep <hours>] [--personal | --signed-in | --public]`,`share stop <port>`],about:[`Shares an app running here at a link, while the command runs. Bitfolk provides the tunnel: nothing else to install, no ngrok account.`,`Who can open it: workspace members by default (they sign in to Bitfolk), only you with --personal, anyone with a Bitfolk account with --signed-in, or anyone with --public.`,`Coding sessions use --run and --keep, so the app and its link stay up for the workspace after the session ends.`],options:[[`--name <name>`,`What the app is called on your workspace and in its link.`],[`--run <command>`,`Starts the app with this command in this folder, and stops it when sharing stops.`],[`--keep <hours>`,`Shares in the background for up to this many hours, then prints the link and returns.`],[`--personal`,`Only you can open it, signed in to Bitfolk.`],[`--signed-in`,`Anyone with a Bitfolk account can open it. People without one can make one at the link.`],[`--public`,`Anyone with the link can open it, no sign-in.`],[`--approval <id>`,`In a Bitfolk session, --public and --signed-in need an allowed post_public request; give its id.`]]},check:{usage:[`check`],about:[`Checks sign-in, each coding tool, and the repo, and says what to fix. Also: bitfolk doctor.`]},bug:{usage:[`bug "<what happened>" [--email <you@...>]`],about:[`Sends a bug report to Bitfolk, with the CLI version and platform (or pipe the text in).`]},permissions:{usage:[`set --permission <auto|safe|bypass>`],about:[`What a session's tool may do on this computer. Your workspace's approval rules still apply on top.`],options:[[`auto`,`The default. The tool's own auto mode decides.`],[`safe`,`Edits inside its own worktree, bitfolk-api to the workspace, read-mostly git. No curl.`],[`bypass`,`No prompts at all. Only on a machine or container you'd hand over to it.`]]}}}function Wo(e){if(e.startsWith(`(`))return F(e);let t=e.split(/(?<=^\S+) /),[n,r]=[t[0],t.slice(1).join(` `)],i=r.replace(/(<[^>]+>|\[[^\]]+\]|"[^"]*")/g,e=>F(e));return`${F(w)} ${P(U(n))}${r?` `+i:``}`}function Go(e){let t=N(),n=e=>H(e,Math.min(t,100)).join(`
126
+ `),r=e.rows===void 0||e.rows>=36?zi({version:e.version,tagline:`Coding sessions for your workspace`,url:`bitfolk.ai`}):[],i=[];return i.push(r.length?r.join(`
127
+ `):n(`${P(I.accent(`bitfolk`))} ${e.version}: lets your Bitfolk workspace start coding sessions on this computer.`)),i.push(``),i.push(...qo(Vo,t)),i.push(``),i.push(n(`${U(`bitfolk`)} ${F(`alone shows where things stand.`)} ${U(`bitfolk help <command>`)} ${F(`for options.`)}`)),i.push(n(`${F(`Short name:`)} ${U(`bf`)}${F(`, as in`)} ${U(`bf up`)}${F(`.`)}`)),i.push(n(F(`Try it with npx bitfolk, or install it with npm i -g bitfolk. Node 20+, macOS or Linux.`))),i.join(`
128
+ `)}function Ko(e,t){let n=Uo(t.defaults,t.api)[e];if(!n)return;let r=N(),i=[];for(let e of n.usage)i.push(...H(Wo(e),r,4));for(let e of n.about)i.push(``,...H(e.replace(/\bbitfolk (help \w+|\w+)/g,e=>U(e)),Math.min(r,100)));return n.options?.length&&(i.push(``,Xo(e===`permissions`?`Levels`:`Options`)),i.push(...Wn(n.options.map(([e,t])=>[I.tool(e),t]),{indent:2,gap:2,max:r}))),n.agentOptions?.length&&(i.push(``,Xo(`For agents`)),i.push(...Wn(n.agentOptions.map(([e,t])=>[I.tool(e),t]),{indent:2,gap:2,max:r}))),i.join(`
129
+ `)}function qo(e,t){let n=Math.max(...e.map(([e])=>B(Wo(e))).filter(e=>e<=Jo)),r=[];for(let[i,a]of e)if(B(Wo(i))<=n)r.push(...Wn([[Yo(Wo(i),n),a]],{indent:2,gap:2,max:t}));else{let e=t-(n+4)<20?6:n+4;r.push(...H(` `+Wo(i),t,4),...H(` `.repeat(e)+a,t,e))}return r}const Jo=26,Yo=(e,t)=>e+` `.repeat(Math.max(0,t-B(e))),Xo=e=>P(I.accent(e)),Zo=e=>e.map(e=>z((Ui(e)?Ui(e)+` `:``)+I.tool(J(e)))).join(F(` + `))||F(`no tools`),Qo=(e,t)=>I.money(`$${e}`)+F(`/${t}`),$o=e=>e===`bypass`?I.err(e):e===`auto`?I.warn(e):I.ok(e);function es(e){return[P(e.name),Zo(e.runtimes),$o(e.permission),Qo(e.maxUsdPerRun,`session`),`${e.maxRunsPerHour}${F(`/h`)}`,e.repo??F(`no repo`)]}function ts(e,t,n){let r=[P(e.name),I.tool(e.runtime),$o(e.permission),Qo(e.maxUsdPerRun,`run`),`${e.maxRunsPerHour}${F(`/h`)}`,t];return n&&(r[r.length-1]+=` `+I.err(`STOPPED: ${n}`)),r}const ns=(e,t=0)=>Gn(e,{indent:t,gap:2}),rs=(e,t)=>[Qo(e.maxUsdPerRun,t),`${e.maxRunsPerHour}${F(`/h`)}`,z(`${e.timeoutMin} ${F(`min`)}`),$o(e.permission)].join(F(` · `));function is(e,t,n){let r=wn(),i=n.gap??3,a=r-Math.max(0,...t.map(B))-i,o=a>=n.min&&(!n.fits||n.fits(e(a))),s=e(o?a:r);if(!Mi(s).length)return[t];let c=e=>o?Jn(e,t,i,Math.max(0,Math.ceil((e.length-t.length)/2))):[...e,``,...t];return n.animate?Vi(s,c):[c(Mi(s))]}function as(e,t,n=!0){let r=wn();return is(t=>Ri(e.id||e.name,t),[...H(`${P(I.accent(e.name))} joined ${P(t)}`,r,2),...H(W(`Linked. Sign-in renews by itself.`),r,2),``,...Kn([[`tools`,Zo(e.runtimes)],[`limits`,rs(e,`session`)],[`repo`,e.repo??F(`none yet`)]],0,r)],{min:50,animate:n,fits:e=>e.placed.length>=3})}function os(e,t=!0){let n=e.machine,r=[];n&&(r.push([`machine`,P(n.name)+F(` · ${z(`up to ${e.maxConcurrent} at once`)}`)]),r.push([`workspace`,n.workspace??`your workspace`]),r.push([`tools`,Zo(n.runtimes)]),r.push([`limits`,rs(n,`session`)]),r.push([`repos`,ds(n)?ds(n)+(n.pullRequests?F(` · opens pull requests`):``):F(`none: builders work in plain folders`)]),n.primary&&r.push([`primary`,`${J(n.primary)} ${F(`while it has usage left`)}`])),e.agents.length&&r.push([`agents`,e.agents.map(e=>P(e.name)).join(F(`, `))]),n||r.push([`at once`,`up to ${e.maxConcurrent}`]),e.awake===`on`?r.push([`awake`,`${I.ok(`on`)} ${F(z(`(--let-sleep to turn off)`))}`]):e.awake===`off`&&r.push([`awake`,`${F(`off (--let-sleep)`)}`]);let i=qn(Kn(r,0,wn()-4),{title:`bitfolk up · v${e.version}`}),a=[...new Set([...n?.runtimes??[],...e.agents.map(e=>e.runtime)])];if(!a.length)return[i];let o=a.map(e=>({id:e,label:J(e)}));return is(e=>Fi(o,e),i,{min:44,animate:t,fits:e=>e.placed.filter(e=>e.walker).length===o.length})}function ss(e){return e.stopping?`stopping`:e.running?`running`:e.signedOut?`signed_out`:e.checking?`checking`:e.checkFailure?`failing`:`idle`}function cs(e,t,n,r=Date.now()){let i=e.status(),a=t.machine?.runtimes.length??0,o=t.machine?`${a} tool${a===1?``:`s`}`:`${t.agents.length} agent${t.agents.length===1?``:`s`}`,s=(e,t,r)=>lr({text:e,frame:n,elapsedMs:0,timeAfterMs:1/0,detail:t.filter(Boolean).join(` · `),hint:r}),c=ss(i);if(c===`stopping`)return s(`Wrapping up`,[i.running?`${i.running} still finishing`:``],`Ctrl-C again to quit now`);if(c===`running`){let e=t.machine?`builder${i.running===1?``:`s`}`:`run${i.running===1?``:`s`}`,n=i.costMicros===null?``:`$${(i.costMicros/1e6).toFixed(2)}`;return s(`${i.running} ${e} working`,[i.since===null?``:`for ${rr(r-i.since)}`,n],`Ctrl-C to stop`)}if(c===`signed_out`)return s(`Not checking in`,[`no new sessions start here`],`Ctrl-C to stop`);if(c===`checking`)return s(`Checking in with your workspace`,[o],`Ctrl-C to stop`);if(c===`failing`)return s(`Trying your workspace again`,[i.checkFailure?`next try in ${Math.max(1,Math.ceil((i.checkFailure.retryAt-r)/1e3))}s`:``],`Ctrl-C to stop`);let l=ls[Math.floor(r/us)%ls.length],u=i.nextCheckAt===null?``:`next check in ${Math.max(1,Math.ceil((i.nextCheckAt-r)/1e3))}s`;return s(tr[0],[o,u,l],`Ctrl-C to stop`)}const ls=tr.slice(1).map(e=>e[0].toLowerCase()+e.slice(1)),us=3e4;function ds(e){let t=X(e);return t.length?t.length===1?`${t[0].name} ${F(gs(t[0].path))}`:t.map((e,t)=>t===0?`${e.name} ${F(`(default)`)}`:e.name).join(F(`, `)):null}function fs(e,t,n){return n.rows!==void 0&&n.rows<15?cs(e,t,n.frame,n.now):bs(e.status(),t,n)}const ps=e=>`$${(e/1e6).toFixed(2)}`,ms=e=>e<1500?`just now`:`${rr(e)} ago`,hs=e=>e<1e3?`now`:`in ${rr(e+999)}`,gs=e=>{let t=C();return t&&(e===t||e.startsWith(t+`/`))?`~`+e.slice(t.length):e},_s=e=>yr(gi(e),I.tool(L.dot)),vs=e=>An(gi(e),94)(J(e)),ys=()=>F(` · `);function bs(e,t,n){let r=n.now??Date.now(),i=Math.max(20,n.columns-1),a=i-4,o=(n.rows===void 0?10:n.rows>=40?12:n.rows>=24?10:8)-3,s=e.sessions??[],c=t.machine,l=!e.signedOut&&e.checkFailure?e.checkFailure:null,u=Cs(e,t,r,l,a),d=Es(e,t,s.length>0),f=e.queued?Ts(e,t,r):null,p=[u];if(s.length){let e=o-2-!!f;p.push(...Ds(s,a,e,n.frame,r))}else{p.push(ws(e,t,n.frame,r,l));let i=[];c?(i.push(xs(`tools`)+(c.runtimes.map(e=>`${_s(e)} ${vs(e)}`).join(` `)||F(`none on`))+Ss(t.awake)),i.push(xs(`limits`)+[I.money(`$${c.maxUsdPerRun}`)+F(`/session`),`${e.runsThisHour??0}${F(`/${c.maxRunsPerHour} this hour`)}`,`${c.timeoutMin}${F(` min each`)}`,`${F(`up to`)} ${t.maxConcurrent} ${F(`at once`)}`].join(ys())),i.push(xs(`repos`)+(ds(c)??F(`none: builders work in plain folders`))+(c.primary?F(` · primary ${J(c.primary)}`):``))):i.push(xs(`agents`)+(t.agents.map(e=>P(e.name)).join(F(`, `))||F(`none`))+Ss(t.awake)),p.push(...i.slice(0,Math.max(0,o-3-!!f)))}f&&p.push(f),p.push(d);let m=e.signedOut?I.err:l?I.warn:F,h=` ${P(I.accent(`bitfolk up`))} `,g=F(` v${t.version} `),_=Math.max(0,i-3-B(h)-B(g)-1),v=m(`╭─`)+h+m(`─`.repeat(_))+g+m(`─╮`),y=p.slice(0,o).map(e=>m(`│ `)+Hn(V(e,a),a)+m(` │`)),ee=m(`╰`+`─`.repeat(i-2)+`╯`),b=e.stopping?[` ${I.warn(`Wrapping up`)}${F(`: letting sessions finish · `)}${I.warn(`Ctrl-C again to quit now`)}`,` ${I.warn(`Ctrl-C again to quit now`)}`]:t.typing?[F(` Type a command below (help lists them) · Ctrl-C to stop`),F(` help · Ctrl-C to stop`)]:[F(` Ctrl-C to stop · ${w} status in another tab`),F(` Ctrl-C to stop`)];return[v,...y,ee,V(b.find(e=>B(e)<=i)??b[1],i)]}const xs=e=>F(Hn(e,7)),Ss=e=>e===`on`?F(` awake `)+I.ok(`on`):e===`off`?F(` awake off (--let-sleep)`):``;function Cs(e,t,n,r,i){let a=t.machine,o=e.lastCheckAt??null,s=(e,t,n=e)=>B(n)<=i?e:t;if(e.signedOut){let t=`${I.err(L.fail)} ${I.err(`Sign-in ended`)}${F(` · run `)}${U(`${w} login`)}${F(` to link it again`)}`;return s(`${t}${F(` · ${e.signedOut}`)}`,`${I.err(L.fail)} ${I.err(`Sign-in ended`)}${F(` · `)}${U(`${w} login`)}`,t)}if(r){let t=I.warn(e.checking?`retrying now`:`retrying ${hs(r.retryAt-n)}`),i=F(o===null?`no check-in yet`:`last check-in ${ms(n-o)}`),a=F(`(${R(r.message)})`),c=`${I.warn(L.warn)} ${I.warn(`Can't reach Bitfolk`)}${ys()}${t}${ys()}${i}`,l=I.warn(e.checking?`now`:hs(r.retryAt-n));return s(`${c} ${a}`,`${I.warn(L.warn)} ${I.warn(`Can't reach Bitfolk`)}${ys()}${l}`,c)}let c=e.checking?I.sky(`checking in now`):F(o===null?`connecting`:`checked in ${ms(n-o)}`),l=!e.checking&&e.nextCheckAt!==null?F(`next ${hs(e.nextCheckAt-n)}`):``,u=e.checking?I.sky(`checking in`):F(o===null?`connecting`:ms(n-o)),d=e=>[e,l].filter(Boolean).join(ys());if(!a)return`${I.ok(L.dot)} ${F(`Watching`)} ${P(`${t.agents.length} agent${t.agents.length===1?``:`s`}`)}${ys()}${d(c)}`;let f=P(a.workspace??`your workspace`),p=`${I.ok(L.dot)} ${F(`Linked to`)} ${f} ${F(`as`)} ${P(a.name)}${ys()}${c}`;return s(`${I.ok(L.dot)} ${F(`Linked to`)} ${f} ${F(`as`)} ${P(a.name)}${ys()}${d(c)}`,`${I.ok(L.dot)} ${f}${ys()}${P(a.name)}${ys()}${d(u)}`,p)}function ws(e,t,n,r,i){let a=ss({...e,running:0,checkFailure:i});if(a===`signed_out`)return`${F(L.idle)} ${F(`Not checking in, so no new sessions start here`)}`;let o=a===`stopping`?`Wrapping up`:a===`checking`?`Checking in with your workspace`:a===`failing`?`Trying your workspace again`:tr[0],s=a===`idle`?F(` ${ls[Math.floor(r/us)%ls.length]}`):``;return`${cr(n)} ${or(o+`…`,sr(n,[...o].length))}${s}`}function Ts(e,t,n){let r=e.queued??0,i=`${F(L.idle)} ${I.accent(`${r} waiting`)}`;if(e.waitingFor===`cap`&&t.machine){let n=e.capFreesAt?new Date(e.capFreesAt).toTimeString().slice(0,5):``;return`${i} ${F(`· hit ${t.machine.maxRunsPerHour} sessions this hour${n?`; next starts at ${n}`:``}`)}`}return`${i} ${F(`for a slot · up to ${t.maxConcurrent} at once`)}`}function Es(e,t,n){let r=e.today??{done:0,failed:0,stopped:0,costMicros:0,durationMs:0},i=[];return r.done+r.failed+r.stopped===0?i.push(F(`nothing finished yet`)):(i.push(`${I.ok(L.ok)} ${r.done} ${F(`done`)}`),r.failed&&i.push(`${I.err(L.fail)} ${r.failed} ${F(`failed`)}`),r.stopped&&i.push(`${I.warn(L.idle)} ${r.stopped} ${F(`stopped`)}`),r.costMicros&&i.push(I.money(ps(r.costMicros))),i.push(F(rr(r.durationMs)))),n&&t.machine&&i.push(`${e.runsThisHour??0}${F(`/${t.machine.maxRunsPerHour} this hour`)}`),xs(`today`)+i.join(ys())}function Ds(e,t,n,r,i){let a=e.reduce((e,t)=>t.activityAt!==null&&(!e||t.activityAt>(e.activityAt??-1))?t:e,null)??e[0],o=t<70,s=e=>o&&e===a&&e.activity?2:1,c=e.slice(),l=()=>c.reduce((e,t)=>e+s(t),0)+ +(c.length<e.length);for(;c.length>1&&l()>Math.max(1,n);){let e=[...c].reverse().find(e=>e!==a);c=c.filter(t=>t!==e)}let u=Math.min(12,Math.max(...c.map(e=>B(J(e.tool))))),d=e=>e.costMicros===null?`—`:ps(e.costMicros),f=Math.max(...c.map(e=>B(rr(i-e.startedAt)))),p=Math.max(...c.map(e=>B(d(e)))),m=t-(4+u+2+2+f+2+p+2),h=Math.min(Math.max(...c.map(e=>B(e.title))),Math.max(12,Math.floor(m/2))),g=[];return c.forEach((e,n)=>{let c=e.stopping?I.warn(L.idle):cr(r+n*3),l=Un(rr(i-e.startedAt),f),d=e.costMicros===null?F(Un(`—`,p)):I.money(Un(ps(e.costMicros),p)),_=e.stopping?`stopping…`:e.activity?`${L.arrow} ${e.activity}`:`starting…`,v=(t,n)=>{let i=V(t,n);return e===a&&!e.stopping?or(i,sr(r,[...i].length)):F(i)};if(!o){let t=Math.max(0,m-h);g.push(`${c} ${_s(e.tool)} ${Hn(vs(e.tool),u)} ${Hn(P(V(e.title,h)),h)} ${F(l)} ${d} ${v(_,t)}`);return}let y=`${F(l)} ${d}`,ee=t>=50?`${vs(e.tool)}${F(` · `)}`:``,b=t-4-B(y)-2,te=V(`${ee}${P(e.title)}`,b);g.push(`${c} ${_s(e.tool)} ${Hn(te,b)} ${y}`),s(e)===2&&g.push(` ${v(_,t-4)}`)}),c.length<e.length&&g.push(F(` +${e.length-c.length} more running`)),g}const Os={start:`up`,ls:`status`,objectives:`goals`,list:`status`,doctor:`check`,remove:`rm`,log:`logs`,chats:`chat`,say:`chat`,tasks:`board`,approval:`approvals`,deny:`approve`},ks=[`login`,`up`,`run`,`sessions`,`logs`,`cancel`,`goals`,`chat`,`board`,`agents`,`approvals`,`approve`,`status`,`tools`,`add`,`rm`,`set`,`share`,`check`,`bug`,`logout`],As=e=>Os[e]??e,js=[...ks,`help`,`version`,`tool`,...Object.keys(Os)];function Ms(e,t){let n=Array.from({length:e.length+1},(e,n)=>Array.from({length:t.length+1},(e,t)=>n?t?0:n:t));for(let r=1;r<=e.length;r++)for(let i=1;i<=t.length;i++)n[r][i]=Math.min(n[r-1][i]+1,n[r][i-1]+1,n[r-1][i-1]+(e[r-1]===t[i-1]?0:1)),r>1&&i>1&&e[r-1]===t[i-2]&&e[r-2]===t[i-1]&&(n[r][i]=Math.min(n[r][i],n[r-2][i-2]+1));return n[e.length][t.length]}function Ns(e){let t=e.toLowerCase(),n,r=1/0;for(let e of js){let i=e.startsWith(t)&&t.length>=2?.5:Ms(t,e);i<r&&([n,r]=[e,i])}if(!(n===void 0||r>(t.length<=3?1:2)))return n===`tool`?`add`:As(n)}function Ps(e){let[t,n]=e;if(t)return t===`tool`?n===`rm`||n===`add`?n:`tool`:t}const Fs=e=>!!e&&/^bfa_/.test(e);function Is(e,t,n){let[r,i,...a]=e;if(t.version||r===`version`)return{kind:`version`};if(r===`help`)return{kind:`help`,topic:Ps(e.slice(1))};if(t.help)return{kind:`help`,topic:Ps(e)};if(!r)return{kind:`status`};switch(r){case`login`:return{kind:`login`};case`logout`:return{kind:`logout`};case`up`:case`start`:return{kind:`up`,agent:i};case`run`:return!i&&!t.goal?{kind:`up`,agent:void 0}:i&&a.length===0&&!t.goal&&n.isAgent(i)?{kind:`up`,agent:i}:{kind:`start`,words:e.slice(1)};case`sessions`:return{kind:`sessions`};case`logs`:case`log`:return{kind:`logs`,session:i};case`cancel`:return{kind:`cancel`,session:i};case`goals`:case`objectives`:return{kind:`goals`};case`chat`:return t.goal?{kind:`chat`,chat:t.goal,words:e.slice(1)}:{kind:`chat`,chat:i,words:a};case`chats`:return{kind:`chat`,chat:void 0,words:[]};case`say`:return i?{kind:`chat`,chat:t.goal??`workspace`,words:e.slice(1)}:{kind:`usage`,message:`what to say? bitfolk say "<message>" [--goal <goal>]`};case`board`:case`tasks`:return{kind:`board`,goal:i??t.goal};case`agents`:return{kind:`agents`};case`approvals`:case`approval`:return{kind:`approvals`};case`approve`:case`deny`:return{kind:`decide`,decision:r,request:i};case`status`:case`ls`:case`list`:return{kind:`status`};case`tools`:return{kind:`tools`};case`tool`:return i!==`add`&&i!==`rm`?{kind:`usage`,message:`tool needs add or rm, as in bitfolk add <tool> or bitfolk rm <tool>`}:{kind:`tool`,action:i,name:a[0]};case`add`:return t.tool&&t.agent?{kind:`usage`,message:`give --agent or --tool, not both`}:Fs(i)||t.agent&&!t.tool?{kind:`agent-add`,token:i}:!i&&Fs(n.envToken)&&!t.tool?{kind:`agent-add`,token:void 0}:i?{kind:`tool`,action:`add`,name:i}:{kind:`usage`,message:`what to add? bitfolk add <tool> (see bitfolk tools), or bitfolk add bfa_... for an agent`};case`rm`:case`remove`:{if(!i)return{kind:`usage`,message:`what to remove? bitfolk rm <tool>, or bitfolk rm <agent>`};if(t.tool&&t.agent)return{kind:`usage`,message:`give --agent or --tool, not both`};if(t.agent)return{kind:`agent-rm`,key:i};if(t.tool)return{kind:`tool`,action:`rm`,name:i};let e=n.isAgent(i),r=n.isTool(i);return e&&r?{kind:`usage`,message:`${i} is both a coding tool and an agent here. Say which: bitfolk rm ${i} --tool, or bitfolk rm ${i} --agent`}:e?{kind:`agent-rm`,key:i}:r?{kind:`tool`,action:`rm`,name:i}:{kind:`usage`,message:`no tool or agent called ${i} here. See bitfolk status`}}case`repos`:case`repo`:return!i||i===`ls`||i===`list`?{kind:`repos`}:i!==`add`&&i!==`rm`&&i!==`remove`&&i!=="default"?{kind:`usage`,message:`bitfolk repos [add <path> [--name <name>] | rm <name> | default <name>]`}:a[0]?{kind:`repos`,action:i===`remove`?`rm`:i,arg:a[0]}:{kind:`usage`,message:i===`add`?`which folder? bitfolk repos add <path> [--name <name>]`:`which repo? bitfolk repos ${i} <name>`};case`set`:return!i||i===`machine`?{kind:`set-machine`}:{kind:`set-agent`,key:i};case`share`:return i===`stop`?{kind:`share-stop`,port:a[0]}:{kind:`share`,port:i};case`check`:case`doctor`:return{kind:`check`};case`bug`:return{kind:`bug`,words:e.slice(1)};default:return{kind:`unknown`,command:r}}}const Ls=new Set([`workspace`,`all`,`.`]),Rs=e=>!e||Ls.has(e.trim().toLowerCase())?null:e.trim();function zs(e,t=Date.now()){if(!e)return``;let n=Math.max(0,Math.round((t-new Date(e).getTime())/1e3));return n<60?`now`:n<3600?`${Math.floor(n/60)}m ago`:n<86400?`${Math.floor(n/3600)}h ago`:`${Math.floor(n/86400)}d ago`}function Bs(e,t=Date.now()){let n=Math.round((new Date(e).getTime()-t)/1e3);return n<60?`now`:n<3600?`in ${Math.floor(n/60)}m`:n<86400?`in ${Math.floor(n/3600)}h`:`in ${Math.floor(n/86400)}d`}const Vs=e=>{let t=new Date(e);return`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`},Hs=new Set([`started`,`progress`,`completed`,`review`,`joined`,`left`]),Us={help:`asking for help`,blocked:`blocked`};function Ws(e,t=N()){let n=e.mine?`You`:R(e.sender_name),r=R(e.body);if(Hs.has(e.kind))return H(F(`${Vs(e.created_at)} ${n} ${e.kind===`joined`||e.kind===`left`?r:`· ${r}`}`),t,7);let i=[e.sender_type===`leader`?`Coordinator`:null,e.sender_type===`agent`&&e.runtime?J(e.runtime):null,e.builder?`Builder`:null,Us[e.kind]??null].filter(Boolean),a=e.mine?P(n):Nn(n)(P(n));return[`${F(Vs(e.created_at))} ${a}${i.length?F(` ${i.join(` · `)}`):``}`,...e.body.split(/\r?\n/).flatMap(e=>H(` ${R(e)}`,t,7))]}function Gs(e,t=N()){let n=e.chat.kind===`workspace`?`${R(e.chat.title)} · workspace chat`:R(e.chat.name??e.chat.title),r=[P(n),``];if(!e.messages.length)return[...r,F(` Quiet so far.`)];for(let n of e.messages)r.push(...Ws(n,t));return r}function Ks(e,t=Date.now()){let n=[[I.tool(`workspace`),P(`${R(e.workspace.name)} · workspace chat`),``,F(zs(e.workspace.last_message_at,t))]];for(let r of e.objectives){let e=[`${r.agents} agent${r.agents===1?``:`s`}`,r.open_tasks?`${r.open_tasks} open task${r.open_tasks===1?``:`s`}`:null,r.status===`paused`?`paused`:null].filter(Boolean);n.push([I.tool($(r.id)),P(V(R(r.name??r.title),56)),r.waiting_on_you?I.warn(z(`${r.waiting_on_you} waiting on you`)):F(z(e.join(` · `))),F(zs(r.last_message_at,t))])}return Wn(n,{indent:2,gap:2,max:N()})}const qs={open:F,claimed:I.sky,in_progress:I.sky,blocked:I.warn,in_review:I.accent,done:I.ok};function Js(e){let t=[P(R(e.objective.name??e.objective.title)),``];if(!e.tasks.length)return[...t,G(`${F(L.idle)} No tasks yet. ${U(`${w} board ${$(e.objective.id)} --add "<title>"`)} adds one.`)];let n=e.tasks.map(e=>[I.tool($(e.id)),(qs[e.status]??F)(z(e.status.replace(/_/g,` `))),`${e.parent_task_id?F(`↳ `):``}${R(e.title)}`,F(z(e.assignee?R(e.assignee):``)),e.status===`blocked`&&e.blocked_need?I.warn(`needs: ${R(e.blocked_need)}`):``]);return[...t,...Wn(n,{indent:2,gap:2,max:N()})]}const Ys={healthy:I.ok,new:I.sky,late:I.warn,silent:I.warn,paused:F,abandoned:I.err};function Xs(e,t=Date.now()){return e.length?Wn(e.map(e=>[P(R(e.name)),F(z(`${J(e.runtime)}${e.builder?` · builder`:``}`)),(Ys[e.health]??F)(e.health),F(z(e.doing?R(e.doing):e.activity.replace(/_/g,` `))),F(e.last_seen_at?zs(e.last_seen_at,t):`never checked in`)]),{indent:2,gap:2,max:N()}):[G(`${F(L.idle)} No agents in this workspace yet. Add one from the Agents page.`)]}const Zs={message_external:`message outside`,post_public:`post publicly`,spend_money:`spend money`,delete:`delete`,code_deploy:`deploy`,schema_change:`change a schema`,use_computer:`use a computer`,practice:`practice`},Qs={pending:I.warn,deferred:I.warn,approved:I.ok,denied:I.err,expired:F};function $s(e,t=Date.now(),n=N()){if(!e.length)return[G(`${I.ok(L.ok)} Nothing is waiting on you.`)];let r=[];for(let i of e){let e=i.status===`pending`||i.status===`deferred`,a=(Qs[i.status]??F)(e?`waiting`:i.status);r.push(...H(`${I.tool($(i.id))} ${a} ${P(R(i.title))}`,n,10));let o=[R(i.agent),Zs[i.action_type]??i.action_type.replace(/_/g,` `),i.risk?`${i.risk} risk`:null,i.workspace?R(i.workspace):null,i.objective?R(i.objective):null,e&&i.expires_at?`expires ${Bs(i.expires_at,t)}`:null,!e&&i.decided_via?`answered ${i.decided_via===`cli`?`from the CLI`:`via ${i.decided_via.replace(/_/g,` `)}`}`:null].filter(Boolean);if(r.push(...H(` ${F(o.join(` · `))}`,n,10)),e&&i.why&&r.push(...H(` ${F(`why:`)} ${R(i.why)}`,n,10)),e&&i.target&&r.push(...H(` ${F(`touches:`)} ${R(i.target)}`,n,10)),e&&i.preview?.trim()){let e=i.preview.trim().split(/\r?\n/).slice(0,6);r.push(...H(` ${F(`preview:`)} ${R(e[0])}`,n,10));for(let t of e.slice(1))r.push(...H(` ${R(t)}`,n,10));i.preview.trim().split(/\r?\n/).length>e.length&&r.push(` ${F(`…`)}`)}e&&i.tainted&&r.push(...H(` ${I.warn(`The agent read outside content before asking. Read the request closely.`)}`,n,10)),r.push(``)}return r.pop(),r}function ec(e){if(!e)throw new Q(`link this computer first: ${w} login`);return{m:e,api:new Wt(e.api,()=>Nr(e))}}function tc(e){throw e instanceof O&&[400,403,404,429].includes(e.status)&&e.message!==`invalid_body`?new Q(e.message):e}const nc=(e,t)=>(e.json?t():K(`Asking your workspace`,t)).catch(tc),rc=e=>console.log(JSON.stringify(e,null,2));function ic(e,t){if(e.limit===void 0)return t;let n=Number(e.limit);if(!Number.isInteger(n)||n<1||n>200)throw new Q(`--limit must be a whole number from 1 to 200`);return n}async function ac(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf8`).trim()}async function oc(e,t,n,r,i={}){let{api:a}=ec(e);if(t===void 0){let e=await nc(r,()=>a.chats());return r.json?rc(e):(console.log(Ks(e).join(`
123
130
  `)),console.log(`
124
- `+W(P(`${w} chat <id or words> shows one; add "<message>" to post in it; ${w} chat workspace is the workspace chat.`))))}let o=Ms(t),s=n.join(` `).trim();if(s===`-`&&(s=await $s()),s){if(s.length>4e3)throw new Q(`a message is at most 4000 characters`);let e=await Xs(r,()=>a.say({goal:o,content:s,client_message_id:ge()}));return r.json?Zs(e):console.log(U(`Posted in ${N(L(e.chat))}. ${P(`Agents read it as your instruction on their next check-in.`)}`))}let c=await Xs(r,()=>a.chat({goal:o,limit:Qs(r,30)}));if(r.json&&!r.follow)return Zs(c);if(r.json)for(let e of c.messages)console.log(JSON.stringify(e));else console.log(zs(c).join(`
131
+ `+G(F(`${w} chat <id or words> shows one; add "<message>" to post in it; ${w} chat workspace is the workspace chat.`))))}let o=Rs(t),s=n.join(` `).trim();if(s===`-`&&(s=await ac()),s){if(s.length>4e3)throw new Q(`a message is at most 4000 characters`);let e=await nc(r,()=>a.say({goal:o,content:s,client_message_id:ge()}));return r.json?rc(e):console.log(W(`Posted in ${P(R(e.chat))}. ${F(`Agents read it as your instruction on their next check-in.`)}`))}let c=await nc(r,()=>a.chat({goal:o,limit:ic(r,30)}));if(r.json&&!r.follow)return rc(c);if(r.json)for(let e of c.messages)console.log(JSON.stringify(e));else console.log(Gs(c).join(`
125
132
  `));if(!r.follow){c.chat.kind===`objective`&&c.chat.goal_id&&console.log(`
126
- `+W(P(`${w} chat ${$(c.chat.goal_id)} "<message>" posts here; --follow keeps watching.`)));return}let l=c.messages.at(-1)?.id??null,u=!1,d=()=>{u=!0};process.once(`SIGINT`,d);try{for(;!u&&(await new Promise(e=>setTimeout(e,i.pollMs??(process.env.BITFOLK_FAST_POLL?1e3:3e3))),!u);){let e=await a.chat({goal:o,after:l,limit:100}).catch(e=>e instanceof Bt&&e.status<500?Ys(e):null);if(e?.messages.length){for(let t of e.messages)console.log(r.json?JSON.stringify(t):Rs(t).join(`
127
- `));l=e.messages.at(-1).id}}}finally{process.removeListener(`SIGINT`,d)}}async function tc(e,t,n){let{api:r}=Js(e);if(!t?.trim())throw new Q(`which objective? ${w} board <id or words> (${w} chat lists them)`);if(n.add!==void 0){let e=n.add.trim();if(!e||e.length>200)throw new Q(`a task title is 1 to 200 characters`);let i=await Xs(n,()=>r.addTask({goal:t.trim(),title:e,spec:n.spec?.trim()??``}));return n.json?Zs(i):console.log(U(`Added ${N(L(i.title))} ${P(`(${$(i.id)})`)}. Agents see it on their next check-in.`))}let i=await Xs(n,()=>r.board(t.trim()));if(n.json)return Zs(i);console.log(Hs(i).join(`
128
- `))}async function nc(e,t){let{api:n}=Js(e),r=await Xs(t,()=>n.agents());if(t.json)return Zs(r);console.log(Ws(r).join(`
129
- `))}async function rc(e,t){let{api:n}=Js(e),r=await Xs(t,()=>n.approvals(t.all?`all`:`pending`,Qs(t,30)));if(t.json)return Zs(r);console.log(qs(r).join(`
133
+ `+G(F(`${w} chat ${$(c.chat.goal_id)} "<message>" posts here; --follow keeps watching.`)));return}let l=c.messages.at(-1)?.id??null,u=!1,d=()=>{u=!0};process.once(`SIGINT`,d);try{for(;!u&&(await new Promise(e=>setTimeout(e,i.pollMs??(process.env.BITFOLK_FAST_POLL?1e3:3e3))),!u);){let e=await a.chat({goal:o,after:l,limit:100}).catch(e=>e instanceof O&&e.status<500?tc(e):null);if(e?.messages.length){for(let t of e.messages)console.log(r.json?JSON.stringify(t):Ws(t).join(`
134
+ `));l=e.messages.at(-1).id}}}finally{process.removeListener(`SIGINT`,d)}}async function sc(e,t,n){let{api:r}=ec(e);if(!t?.trim())throw new Q(`which goal? ${w} board <id or words> (${w} chat lists them)`);if(n.add!==void 0){let e=n.add.trim();if(!e||e.length>200)throw new Q(`a task title is 1 to 200 characters`);let i=await nc(n,()=>r.addTask({goal:t.trim(),title:e,spec:n.spec?.trim()??``}));return n.json?rc(i):console.log(W(`Added ${P(R(i.title))} ${F(`(${$(i.id)})`)}. Agents see it on their next check-in.`))}let i=await nc(n,()=>r.board(t.trim()));if(n.json)return rc(i);console.log(Js(i).join(`
135
+ `))}async function cc(e,t){let{api:n}=ec(e),r=await nc(t,()=>n.agents());if(t.json)return rc(r);console.log(Xs(r).join(`
136
+ `))}async function lc(e,t){let{api:n}=ec(e),r=await nc(t,()=>n.approvals(t.all?`all`:`pending`,ic(t,30)));if(t.json)return rc(r);console.log($s(r).join(`
130
137
  `)),r.some(e=>e.status===`pending`||e.status===`deferred`)&&console.log(`
131
- `+W(P(`${w} approve <id> or ${w} deny <id> answers one; --note "<why>" adds a note the agent reads.`)))}async function ic(e,t,n,r){let{api:i}=Js(e),a=n?.trim().toLowerCase()??``;if(!/^[0-9a-f-]{4,36}$/.test(a))throw new Q(`which request? ${w} ${t} <id>, or its last 4 or more characters, as ${w} approvals lists them`);let o=r.note?.trim()||null;if(o&&o.length>1e3)throw new Q(`a note is at most 1000 characters`);let s=await Xs(r,()=>i.decide({request:a,decision:t,note:o}));if(r.json)return Zs(s);let c=t===`approve`?F.ok(`Approved`):F.err(`Denied`);console.log(`${c} ${N(L(s.title))} ${P(`(${L(s.agent)}, ${$(s.id)})`)}`),t===`approve`&&s.action_type===`use_computer`&&console.log(W(P(`The session is queued; ${w} up takes it, and ${w} sessions shows it.`)))}function ac(e,t,n){return e===`public`?F.warn(`anyone with the link, no sign-in`):e===`personal`?`only you, signed in to Bitfolk`:e===`account`?F.warn(`anyone with a Bitfolk account, sign-in needed`):`${t} only, Bitfolk sign-in${n===void 0?``:` (${n} email${n===1?``:`s`} let in)`}`}const oc=e=>e===`personal`?`your Settings, Shared apps (only you see it)`:`your workspace, Settings, Shared apps`;function sc(e){let t;try{t=JSON.parse(e)}catch{return null}if(t.msg===`started tunnel`)return{kind:`started`};let n=typeof t.err==`string`&&t.err!==`<nil>`?t.err:null;return t.lvl===`crit`||t.lvl===`eror`&&n?{kind:`error`,message:cc(String(n??t.msg??``))}:null}function cc(e){return e.replace(/\s+/g,` `).replace(/\bERR_NGROK_\d+\b.*$/,``).trim().slice(0,240)||`ngrok failed`}async function lc(){try{let e=await import(`@ngrok/ngrok`),t=e.default??e;return typeof t.forward==`function`?t:null}catch{return null}}async function uc(e,t=1e4,n=fetch){let r=Date.now()+t;for(;Date.now()<r;){try{if((await n(e,{method:`HEAD`,redirect:`manual`,signal:AbortSignal.timeout(3e3)})).status!==404)return!0}catch{}await new Promise(e=>setTimeout(e,500))}return!1}async function dc(e,t){let r=await lc();if(r){let n=!1,i,a=await Promise.race([r.forward({addr:`127.0.0.1:${e.port}`,authtoken:e.authtoken,domain:new URL(e.internalUrl).host,binding:`internal`,onStatusChange:e=>{n&&(e===`closed`&&t.lost(),e===`connected`&&t.back())}}),new Promise((e,t)=>i=setTimeout(()=>t(Error(`the tunnel took too long to open`)),3e4))]).catch(e=>{throw Error(cc(e instanceof Error?e.message:String(e)))}).finally(()=>clearTimeout(i));return n=!0,{closed:new Promise(()=>{}),close:()=>void a.close().catch(()=>null)}}let i=Vr(`ngrok`);if(!i)throw Error(`the tunnel library that comes with bitfolk isn't installed for this computer. Reinstall with npm i -g bitfolk (without --omit=optional), or install the ngrok program (https://ngrok.com/download). No ngrok account is needed.`);ue(e.cfgFile,`version: "3"
138
+ `+G(F(`${w} approve <id> or ${w} deny <id> answers one; --note "<why>" adds a note the agent reads.`)))}async function uc(e,t,n,r){let{api:i}=ec(e),a=n?.trim().toLowerCase()??``;if(!/^[0-9a-f-]{4,36}$/.test(a))throw new Q(`which request? ${w} ${t} <id>, or its last 4 or more characters, as ${w} approvals lists them`);let o=r.note?.trim()||null;if(o&&o.length>1e3)throw new Q(`a note is at most 1000 characters`);let s=await nc(r,()=>i.decide({request:a,decision:t,note:o}));if(r.json)return rc(s);let c=t===`approve`?I.ok(`Approved`):I.err(`Denied`);console.log(`${c} ${P(R(s.title))} ${F(`(${R(s.agent)}, ${$(s.id)})`)}`),t===`approve`&&s.action_type===`use_computer`&&console.log(G(F(`The session is queued; ${w} up takes it, and ${w} sessions shows it.`)))}function dc(e,t,n){return e===`public`?I.warn(`anyone with the link, no sign-in`):e===`personal`?`only you, signed in to Bitfolk`:e===`account`?I.warn(`anyone with a Bitfolk account, sign-in needed`):`${t} only, Bitfolk sign-in${n===void 0?``:` (${n} email${n===1?``:`s`} let in)`}`}const fc=(e,t=!1)=>(e===`personal`?`your Settings, Shared apps (only you see it)`:`your workspace, Settings, Shared apps`)+(t?`, and pinned in the objective chat`:``);function pc(e){let t;try{t=JSON.parse(e)}catch{return null}if(t.msg===`started tunnel`)return{kind:`started`};let n=typeof t.err==`string`&&t.err!==`<nil>`?t.err:null;return t.lvl===`crit`||t.lvl===`eror`&&n?{kind:`error`,message:mc(String(n??t.msg??``))}:null}function mc(e){return e.replace(/\s+/g,` `).replace(/\bERR_NGROK_\d+\b.*$/,``).trim().slice(0,240)||`ngrok failed`}async function hc(){try{let e=await import(`@ngrok/ngrok`),t=e.default??e;return typeof t.forward==`function`?t:null}catch{return null}}async function gc(e,t=1e4,n=fetch){let r=Date.now()+t;for(;Date.now()<r;){try{if((await n(e,{method:`HEAD`,redirect:`manual`,signal:AbortSignal.timeout(3e3)})).status!==404)return!0}catch{}await new Promise(e=>setTimeout(e,500))}return!1}async function _c(e,t){let r=await hc();if(r){let n=!1,i,a=await Promise.race([r.forward({addr:`127.0.0.1:${e.port}`,authtoken:e.authtoken,domain:new URL(e.internalUrl).host,binding:`internal`,onStatusChange:e=>{n&&(e===`closed`&&t.lost(),e===`connected`&&t.back())}}),new Promise((e,t)=>i=setTimeout(()=>t(Error(`the tunnel took too long to open`)),3e4))]).catch(e=>{throw Error(mc(e instanceof Error?e.message:String(e)))}).finally(()=>clearTimeout(i));return n=!0,{closed:new Promise(()=>{}),close:()=>void a.close().catch(()=>null)}}let i=Ur(`ngrok`);if(!i)throw Error(`the tunnel library that comes with bitfolk isn't installed for this computer. Reinstall with npm i -g bitfolk (without --omit=optional), or install the ngrok program (https://ngrok.com/download). No ngrok account is needed.`);ue(e.cfgFile,`version: "3"
132
139
  agent:
133
140
  web_addr: false
134
141
  update_check: false
135
- `,{mode:384});let a=n(i,[`http`,String(e.port),`--url`,e.internalUrl,`--config`,e.cfgFile,`--log`,`stdout`,`--log-format`,`json`],{env:{...process.env,NGROK_AUTHTOKEN:e.authtoken,NGROK_API_KEY:``,NGROK_CONFIG:``},stdio:[`ignore`,`pipe`,`pipe`]}),o=()=>{a.kill(`SIGTERM`),ce(e.cfgFile,{force:!0})},s=await new Promise(e=>{let t=``,n=n=>{t+=n.toString();let r=t.split(`
136
- `);t=r.pop()??``;for(let t of r){let n=sc(t);n?.kind===`started`&&e(null),n?.kind===`error`&&e(n.message)}};a.stdout.on(`data`,n),a.stderr.on(`data`,n),a.once(`exit`,()=>e(`ngrok stopped before the tunnel opened`)),setTimeout(()=>e(`ngrok took too long to open the tunnel`),3e4)});if(s)throw o(),Error(s);return{closed:new Promise(e=>a.once(`exit`,()=>e(`ngrok stopped`))),close:o}}function fc(e,t=`127.0.0.1`){return new Promise(n=>{let r=ve({port:e,host:t}),i=e=>{r.destroy(),n(e)};r.setTimeout(1500,()=>i(!1)),r.once(`connect`,()=>i(!0)),r.once(`error`,()=>i(!1))})}const pc={stopped_in_town:`Someone stopped it from the workspace's Settings.`,replaced:`It was shared again from this computer.`,machine_unlinked:`This computer was unlinked from the workspace.`,went_quiet:`This computer stopped checking in for a few minutes.`},mc=`BITFOLK_SHARE_READY`,hc=()=>c(O(),`share`),gc=e=>c(hc(),`port-${e}.json`);function _c(e=process.env){let t=e.BITFOLK_SESSION_ID??``;return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)?{session:t}:{}}const vc=(e=process.env)=>!!(e.BITFOLK_RUN_ID||e.BITFOLK_TOKEN_FILE);async function yc(e,t=process.env,n=fetch,r=`--public`){let i=`A link anyone can open needs your owner's yes first: bitfolk-api POST /v1/actions with action_type post_public, a title, why, and target "<the app> at a public link". Once it says allowed, run this again with --approval <request id>. A members-only link (no ${r}) needs no approval.`;if(!e)return i;if(!/^[0-9a-f-]{36}$/i.test(e))return`--approval takes the request id (a uuid) from POST /v1/actions.`;let a=t.BITFOLK_TOKEN??``;try{t.BITFOLK_TOKEN_FILE&&(a=re(t.BITFOLK_TOKEN_FILE,`utf8`).trim())}catch{}let o=(t.BITFOLK_API??``).replace(/\/+$/,``);if(!a||!o)return`can't check the approval: this session has no Bitfolk token. `+i;let s;try{let t=await n(`${o}/v1/actions/${e}`,{headers:{authorization:`Bearer ${a}`,"user-agent":`bitfolk-share`}});if(!t.ok)return`can't read approval ${e} (HTTP ${t.status}). Use the id of a request you sent.`;s=await t.json()}catch(t){return`can't reach Bitfolk to check approval ${e}: ${t.message}`}return s.action_type===`post_public`?s.status===`allowed`?null:`approval ${e} is ${s.status??`not decided`}, not allowed. Wait for it, or share without ${r}.`:`approval ${e} is for ${s.action_type??`something else`}, not post_public. ${i}`}function bc(e,t){if(e)try{process.kill(-e,t)}catch{try{process.kill(e,t)}catch{}}}async function xc(e,t,n){let r;t?.once(`exit`,e=>r=e);let i=Date.now()+n;for(;Date.now()<i;){if(await fc(e))return null;if(r!==void 0)return`the app stopped (exit ${r}) before anything listened on 127.0.0.1:${e}`;await new Promise(e=>setTimeout(e,500))}return`nothing listened on 127.0.0.1:${e} within ${Math.round(n/1e3)}s`}async function Sc(e){let t;try{t=JSON.parse(re(gc(e),`utf8`))}catch{throw Error(`nothing here is shared in the background on port ${e}. A share in a terminal stops with Ctrl-C there.`)}try{process.kill(t.pid,`SIGTERM`)}catch{ce(gc(e),{force:!0}),console.log(`${P(I.idle)} ${N(t.name)} had already stopped sharing.`);return}for(let t=0;t<20&&x(gc(e));t++)await new Promise(e=>setTimeout(e,250));console.log(`${P(I.idle)} Stopped sharing ${N(t.name)}. The link no longer works.`)}async function Cc(e,t){S(hc(),{recursive:!0,mode:448});let r=c(hc(),`ready-${e}-${process.pid}.json`),i=c(hc(),`port-${e}.log`);ce(r,{force:!0});let a=ne(i,`w`,384),o=n(process.execPath,[...process.execArgv,process.argv[1],...process.argv.slice(2),`--no-color`],{cwd:process.cwd(),env:{...process.env,[mc]:r},detached:!0,stdio:[`ignore`,a,a]});o.unref();let s=dr(`Opening a link for 127.0.0.1:${e}`,{quiet:!0}),l=Date.now()+(t.run?18e4:6e4),u=null;for(;!u&&Date.now()<l;){await new Promise(e=>setTimeout(e,400));try{u=JSON.parse(re(r,`utf8`))}catch{o.exitCode!==null&&(u={ok:!1,error:`sharing stopped before the link opened. Log: ${i}`})}}if(s.stop(),ce(r,{force:!0}),!u)throw bc(o.pid,`SIGTERM`),Error(`the link didn't open in time. Log: ${i}`);if(!u.ok)throw Error(u.error);let d=ac(u.access,u.town);console.log([U(`${N(u.name)} is shared for up to ${t.keep} hour${t.keep===1?``:`s`}`),...Gn([qn(u.url),``,...Wn([[`who`,d],[`from`,`127.0.0.1:${e}${t.run?`, started with ${t.run}`:``}`],[`listed`,oc(u.access)],[`log`,i]])]),P(` Running in the background. Stop it with: bitfolk share stop ${e}`)].join(`
137
- `))}async function wc(e,t,r){if(!await lc()&&!Vr(`ngrok`))throw Error(`the tunnel library that comes with bitfolk isn't installed for this computer. Reinstall with npm i -g bitfolk (without --omit=optional), or install the ngrok program (https://ngrok.com/download). No ngrok account is needed.`);let i=process.env[mc],a=e=>i&&ue(i,JSON.stringify(e),{mode:384}),o=e=>{throw a({ok:!1,error:e}),Error(e)};if((r.public||r.signedIn)&&vc()){let e=await yc(r.approval,process.env,fetch,r.public?`--public`:`--signed-in`);e&&o(e)}if(r.keep&&!i)return Cc(t,r);!r.run&&!await fc(t)&&o(`nothing is running on 127.0.0.1:${t}. Start your app first, or pass --run "<command>".`),r.run&&await fc(t)&&o(`something already listens on 127.0.0.1:${t}. Pick a free port for --run, or share that app without --run.`);let s=null;if(r.run){S(hc(),{recursive:!0,mode:448});let e=ne(c(hc(),`port-${t}.app.log`),`w`,384);s=n(`sh`,[`-c`,r.run],{cwd:process.cwd(),env:{...process.env,PORT:String(t)},detached:!0,stdio:[`ignore`,e,e]});let i=dr(`Starting ${r.run}`,{quiet:!0}),a=await xc(t,s,15e4);i.stop(),a&&(bc(s.pid,`SIGTERM`),o(`${a}. App log: ${c(hc(),`port-${t}.app.log`)}`))}let l=new Ht(e.api,()=>jr(e)),u=dr(`Opening a link for 127.0.0.1:${t}`,{quiet:!0}),d;try{d=await l.openApp({name:r.name??``,port:t,access:r.public?`public`:r.signedIn?`account`:r.personal?`personal`:`town`,..._c()})}catch(e){return bc(s?.pid,`SIGTERM`),o(e.message)}finally{u.stop()}let f=hc();S(f,{recursive:!0,mode:448});let p=c(f,`${d.app_id}.yml`),m=null,h=null,g=!1,_=null,v=async(e,n)=>{if(!g){if(g=!0,_?.stop(),h&&clearInterval(h),m?.close(),bc(s?.pid,`SIGTERM`),ce(p,{force:!0}),i)try{JSON.parse(re(gc(t),`utf8`)).pid===process.pid&&ce(gc(t),{force:!0})}catch{}await l.stopApp(d.app_id).catch(()=>null),console.log(n),process.exit(e)}};process.on(`SIGINT`,()=>v(0,`\n${P(I.idle)} Stopped sharing ${N(d.name)}. The link no longer works.`)),process.on(`SIGTERM`,()=>v(0,`${P(I.idle)} Stopped sharing ${N(d.name)}.`)),process.on(`SIGHUP`,()=>v(0,`${P(I.idle)} Stopped sharing ${N(d.name)}.`)),_=dr(`Connecting the tunnel`,{quiet:!0,hint:`Ctrl-C to cancel`});try{m=await dc({port:t,internalUrl:d.internal_url,authtoken:d.authtoken,cfgFile:p},{lost:()=>console.log(Jn(`Lost the tunnel connection; reconnecting.`)),back:()=>console.log(U(`Tunnel reconnected.`))})}catch(e){_.stop();let t=e.message;return a({ok:!1,error:`couldn't share ${d.name}: ${t}`}),v(1,Yn(`couldn't share ${d.name}: ${t}`,`bitfolk: `))}if(await uc(d.url),_.stop(),m.closed.then(e=>v(1,Yn(`${e}, so ${d.name} is no longer shared.`))),s?.once(`exit`,e=>v(1,Yn(`the app stopped (exit ${e}), so ${d.name} is no longer shared.`))),i){let e=r.keep?new Date(Date.now()+r.keep*36e5).toISOString():null,n={pid:process.pid,port:t,app_id:d.app_id,name:d.name,url:d.url,until:e};ue(gc(t),JSON.stringify(n),{mode:384}),r.keep&&setTimeout(()=>v(0,`Shared ${d.name} for ${r.keep} hours; stopped.`),r.keep*36e5).unref(),a({ok:!0,url:d.url,name:d.name,access:d.access,town:d.town})}let y=ac(d.access,d.town,d.members);console.log([U(`${N(d.name)} is shared`),...Gn([qn(d.url),``,...Wn([[`who`,y],[`from`,`127.0.0.1:${t}`],[`listed`,oc(d.access)]])]),P(i?` In the background. Stop it with: bitfolk share stop ${t}`:` Keep this running to stay shared. Ctrl-C stops it.`)].join(`
138
- `));let b=0;h=setInterval(async()=>{try{let e=await l.beatApp(d.app_id);b=0,e.status===`stopped`&&await v(0,`Stopped sharing ${d.name}. ${pc[e.stop_reason??``]??``}`.trim())}catch{++b===2&&console.log(Jn(`Can't reach your workspace right now; the link keeps working for a few minutes while this retries.`))}},Math.max(15,d.beat_s)*1e3)}const Tc={repo:{type:`string`},base:{type:`string`},runtime:{type:`string`},command:{type:`string`},acp:{type:`string`},model:{type:`string`},permission:{type:`string`},"max-usd":{type:`string`},"max-runs":{type:`string`},"pull-requests":{type:`string`},primary:{type:`string`},in:{type:`string`},timeout:{type:`string`},api:{type:`string`},email:{type:`string`},name:{type:`string`},public:{type:`boolean`},personal:{type:`boolean`},"signed-in":{type:`boolean`},run:{type:`string`},keep:{type:`string`},approval:{type:`string`},once:{type:`boolean`},goal:{type:`string`},task:{type:`string`},detach:{type:`boolean`},follow:{type:`boolean`,short:`f`},json:{type:`boolean`},all:{type:`boolean`},limit:{type:`string`},add:{type:`string`},spec:{type:`string`},note:{type:`string`},"let-sleep":{type:`boolean`},"no-browser":{type:`boolean`},service:{type:`string`},"no-color":{type:`boolean`},agent:{type:`boolean`},tool:{type:`boolean`},force:{type:`boolean`},help:{type:`boolean`,short:`h`},version:{type:`boolean`,short:`v`}};function Ec(e,t,n,r){if(e===void 0)return;let i=Number(e);if(!Number.isFinite(i)||i<n||i>r)throw new Q(`--${t} must be a number from ${n} to ${r}`);return i}function Dc(e){if(!e)return!1;try{return t(`sh`,[`-c`,`command -v "$1"`,`sh`,e],{stdio:`ignore`}),!0}catch{return!1}}function Oc(e,t){let n={...e};if(t.runtime!==void 0){if(!Ut.includes(t.runtime))throw new Q(`--runtime must be one of ${Ut.join(`, `)}`);n.runtime=t.runtime}if(t.command!==void 0&&(n.command=t.command),n.runtime===`command`&&!n.command)throw new Q(`runtime command needs --command "..."`);if(t.permission!==void 0){if(!Wt.includes(t.permission))throw new Q(`--permission must be one of ${Wt.join(`, `)}`);n.permission=t.permission}if(t.repo!==void 0){let e=Ui(u(t.repo));if(!e)throw new Q(`${t.repo} isn't inside a git repository`);n.repo=e}return t.base!==void 0&&(n.base=t.base),t.model!==void 0&&(n.model=t.model||void 0),n.maxUsdPerRun=Ec(t[`max-usd`],`max-usd`,.01,100)??n.maxUsdPerRun,n.maxRunsPerHour=Ec(t[`max-runs`],`max-runs`,1,60)??n.maxRunsPerHour,n.timeoutMin=Ec(t.timeout,`timeout`,1,600)??n.timeoutMin,n}function kc(e){return Xo(e,e.repo?`${e.repo} ${P(`(branch ${Wi(e)})`)}`:P(`no repo`),Qt().agents[e.id]?.disabledReason)}const Ac=e=>Zo([kc(e)])[0].join(`
139
- `),jc=e=>(e.api??process.env.BITFOLK_API??`https://bitfolk.ai`).replace(/\/+$/,``);async function Mc(e,t){if(e??=process.env.BITFOLK_TOKEN,!e||!/^bfa_[A-Za-z0-9]{20,}$/.test(e))throw new Q(`give the agent's token from its page on your workspace: ${w} add bfa_... (to link this computer instead, run ${w} login)`);let n=jc(t),r=await G(`Asking your workspace about this agent`,()=>new Vt(n,e).setup());await qc(n,e,r,t,void 0)}const Nc=(e=[])=>[...Gr().filter(e=>e.supported).map(e=>e.id),...e.map(e=>Kr(e.name))];function Pc(){let e=Gr().filter(e=>!e.supported);e.length!==0&&(console.log(`\n ${N(`Also found`)} ${P(`(not built in yet; add one with ${w} add, then check the command works headless):`)}`),console.log(Hn(e.map(e=>[e.label,H(`${w} add ${e.id.replace(/_/g,`-`)} --command '${e.suggest}'`)]),{indent:4}).join(`
140
- `)))}async function Fc(e){let t=jc(e),n=k().machine,r=!!e[`no-browser`]||Dr(),{accessToken:i,link:a,me:o}=await kr(t,{browser:!r,remote:r,detected:Nc(n?.customTools)});n&&n.id!==o.machine.id&&await Nr(n);let s=Ic({...Gt,...n??{},id:o.machine.id,name:o.machine.name,api:t,token:i,oauth:a,runtimes:o.machine.runtimes,customTools:n?.customTools,workspace:o.workspace?.name},e),c=k();c.machine=s,Zt(c),console.log(``),await Bi(es(s,o.workspace?.name??`your workspace`)),console.log(``);for(let e of s.runtimes){let t=Rr.find(t=>t.id===e);t&&!Hr(t)&&console.log(` ${Jn(`warning: ${t.label} isn't installed here yet; install it and sign in before sessions start.`)}`)}Pc(),s.repo||console.log(` ${P(`no repo yet: builders work in plain folders. Give them one with:`)} ${H(`${w} set --repo <path>`)}`),console.log(`\nKeep it running with: ${N(H(`${w} up`))}`),ye&&console.log(P(`To keep the command around, install it once: ${H(`npm i -g bitfolk`)} (then use bitfolk up).`))}function Ic(e,t){let n=Oc({...e,slug:`machine`,runtime:`claude_code`},{...t,runtime:void 0,command:void 0}),r=e.pullRequests;if(t[`pull-requests`]!==void 0){let e=t[`pull-requests`].toLowerCase();if(![`on`,`off`].includes(e))throw new Q(`--pull-requests must be on or off`);if(r=e===`on`,r&&!n.repo)throw new Q(`pull requests need a repo: ${w} set --repo <path> --pull-requests on`)}let i=t.repo!==void 0&&n.repo?ma(e,n.repo,void 0,!0):{repos:e.repos,repo:n.repo};return{...e,repo:i.repo,repos:i.repos,base:n.base,pullRequests:r,model:n.model,permission:n.permission,maxUsdPerRun:n.maxUsdPerRun,maxRunsPerHour:n.maxRunsPerHour,timeoutMin:n.timeoutMin}}const Lc=e=>Zo([Yo(e)])[0].join(`
141
- `);function Rc(){let e=Gr({versions:!0}),t=k().machine;if(e.length===0&&!t?.customTools?.length){console.log(Yn(`No coding tools found. Install Claude Code, Codex, OpenCode or Hermes, then run ${w} login.`));return}console.log(N(F.accent(`Coding tools on this computer`)));let n=e=>`${F.ok(I.dot)} ${F.ok(e)}`,r=e=>`${P(I.idle)} ${P(e)}`,i=[],a=M()<60,o=e=>a||!Vi(e)?``:Vi(e)+` `;for(let s of e){let e=s.acp?` via ACP`:``,c=s.supported?t?t.runtimes.includes(s.id)?n(`on${e}`):`${r(`off${e}`)} ${P(`(`)}${H(`${w} add ${s.id.replace(/_/g,`-`)}`)}${P(`)`)}`:n(`supported${e}`):`${F.warn(I.skip)} ${F.warn(`not built in`)} ${P(`(${w} add ${s.id.replace(/_/g,`-`)} --command ...)`)}`,l=P(B(zc(s.version,s.label),16));a?i.push([F.tool(N(s.label))],[` ${l}${s.version?P(` · `):``}${c}`],[` ${P(s.path)}`]):(i.push([o(s.id)+F.tool(N(s.label)),l,c]),i.push([``,P(s.path)]))}for(let e of t?.customTools??[]){let s=e.protocol===`acp`?`custom, via ACP`:`custom`;i.push([(a?``:o(Kr(e.name)))+F.tool(N(e.name)),P(s),`${t.runtimes.includes(Kr(e.name))?n(`on`):r(`off`)}${P(`:`)} ${e.command}`])}console.log(Hn(i,{indent:2,gap:2}).join(`
142
- `)),(e.some(e=>e.supported&&e.acp)||t?.customTools?.some(e=>e.protocol===`acp`))&&console.log(P(`
142
+ `,{mode:384});let a=n(i,[`http`,String(e.port),`--url`,e.internalUrl,`--config`,e.cfgFile,`--log`,`stdout`,`--log-format`,`json`],{env:{...process.env,NGROK_AUTHTOKEN:e.authtoken,NGROK_API_KEY:``,NGROK_CONFIG:``},stdio:[`ignore`,`pipe`,`pipe`]}),o=()=>{a.kill(`SIGTERM`),S(e.cfgFile,{force:!0})},s=await new Promise(e=>{let t=``,n=n=>{t+=n.toString();let r=t.split(`
143
+ `);t=r.pop()??``;for(let t of r){let n=pc(t);n?.kind===`started`&&e(null),n?.kind===`error`&&e(n.message)}};a.stdout.on(`data`,n),a.stderr.on(`data`,n),a.once(`exit`,()=>e(`ngrok stopped before the tunnel opened`)),setTimeout(()=>e(`ngrok took too long to open the tunnel`),3e4)});if(s)throw o(),Error(s);return{closed:new Promise(e=>a.once(`exit`,()=>e(`ngrok stopped`))),close:o}}function vc(e,t=`127.0.0.1`){return new Promise(n=>{let r=ve({port:e,host:t}),i=e=>{r.destroy(),n(e)};r.setTimeout(1500,()=>i(!1)),r.once(`connect`,()=>i(!0)),r.once(`error`,()=>i(!1))})}const yc={stopped_in_town:`Someone stopped it from the workspace's Settings.`,replaced:`It was shared again from this computer.`,machine_unlinked:`This computer was unlinked from the workspace.`,went_quiet:`This computer stopped checking in for a few minutes.`},bc=`BITFOLK_SHARE_READY`;function xc(e=process.env,t=k(),n=fe()){if(e.BITFOLK_SHARE_DIR)return[e.BITFOLK_SHARE_DIR];let r=typeof process.getuid==`function`?String(process.getuid()):e.USER??`user`;return[c(t,`share`),c(n,`bitfolk-share-${r}`)]}function Sc(e){try{x(e,{recursive:!0,mode:448});let t=c(e,`.probe-${process.pid}`);return ue(t,``,{mode:384}),S(t,{force:!0}),!0}catch{return!1}}let Cc=null;const wc=()=>{if(Cc)return Cc;let e=xc();return Cc=e.find(Sc)??e[0],Cc},Tc=e=>c(wc(),`port-${e}.json`),Ec=e=>xc().map(t=>c(t,`port-${e}.json`)).find(e=>b(e))??Tc(e);function Dc(e=process.env){let t=e.BITFOLK_SESSION_ID??``;return/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)?{session:t}:{}}const Oc=(e=process.env)=>!!(e.BITFOLK_RUN_ID||e.BITFOLK_TOKEN_FILE);async function kc(e,t=process.env,n=fetch,r=`--public`){let i=`A link anyone can open needs your owner's yes first: bitfolk-api POST /v1/actions with action_type post_public, a title, why, and target "<the app> at a public link". Once it says allowed, run this again with --approval <request id>. A members-only link (no ${r}) needs no approval.`;if(!e)return i;if(!/^[0-9a-f-]{36}$/i.test(e))return`--approval takes the request id (a uuid) from POST /v1/actions.`;let a=t.BITFOLK_TOKEN??``;try{t.BITFOLK_TOKEN_FILE&&(a=ie(t.BITFOLK_TOKEN_FILE,`utf8`).trim())}catch{}let o=(t.BITFOLK_API??``).replace(/\/+$/,``);if(!a||!o)return`can't check the approval: this session has no Bitfolk token. `+i;let s;try{let t=await n(`${o}/v1/actions/${e}`,{headers:{authorization:`Bearer ${a}`,"user-agent":`bitfolk-share`}});if(!t.ok)return`can't read approval ${e} (HTTP ${t.status}). Use the id of a request you sent.`;s=await t.json()}catch(t){return`can't reach Bitfolk to check approval ${e}: ${t.message}`}return s.action_type===`post_public`?s.status===`allowed`?null:`approval ${e} is ${s.status??`not decided`}, not allowed. Wait for it, or share without ${r}.`:`approval ${e} is for ${s.action_type??`something else`}, not post_public. ${i}`}function Ac(e,t){if(e)try{process.kill(-e,t)}catch{try{process.kill(e,t)}catch{}}}async function jc(e,t,n){let r;t?.once(`exit`,e=>r=e);let i=Date.now()+n;for(;Date.now()<i;){if(await vc(e))return null;if(r!==void 0)return`the app stopped (exit ${r}) before anything listened on 127.0.0.1:${e}`;await new Promise(e=>setTimeout(e,500))}return`nothing listened on 127.0.0.1:${e} within ${Math.round(n/1e3)}s`}async function Mc(e){let t=Ec(e),n;try{n=JSON.parse(ie(t,`utf8`))}catch{throw Error(`nothing here is shared in the background on port ${e}. A share in a terminal stops with Ctrl-C there.`)}try{process.kill(n.pid,`SIGTERM`)}catch{S(t,{force:!0}),console.log(`${F(L.idle)} ${P(n.name)} had already stopped sharing.`);return}for(let e=0;e<20&&b(t);e++)await new Promise(e=>setTimeout(e,250));console.log(`${F(L.idle)} Stopped sharing ${P(n.name)}. The link no longer works.`)}async function Nc(e,t){x(wc(),{recursive:!0,mode:448});let r=c(wc(),`ready-${e}-${process.pid}.json`),i=c(wc(),`port-${e}.log`);S(r,{force:!0});let a=re(i,`w`,384),o=n(process.execPath,[...process.execArgv,process.argv[1],...process.argv.slice(2),`--no-color`],{cwd:process.cwd(),env:{...process.env,[bc]:r},detached:!0,stdio:[`ignore`,a,a]});o.unref();let s=pr(`Opening a link for 127.0.0.1:${e}`,{quiet:!0}),l=Date.now()+(t.run?18e4:6e4),u=null;for(;!u&&Date.now()<l;){await new Promise(e=>setTimeout(e,400));try{u=JSON.parse(ie(r,`utf8`))}catch{o.exitCode!==null&&(u={ok:!1,error:`sharing stopped before the link opened. Log: ${i}`})}}if(s.stop(),S(r,{force:!0}),!u)throw Ac(o.pid,`SIGTERM`),Error(`the link didn't open in time. Log: ${i}`);if(!u.ok)throw Error(u.error);let d=dc(u.access,u.town);console.log([W(`${P(u.name)} is shared for up to ${t.keep} hour${t.keep===1?``:`s`}`),...qn([Yn(u.url),``,...Kn([[`who`,d],[`from`,`127.0.0.1:${e}${t.run?`, started with ${t.run}`:``}`],[`listed`,fc(u.access,!!Dc().session)],[`log`,i]])]),F(` Running in the background. Stop it with: bitfolk share stop ${e}`)].join(`
144
+ `))}async function Pc(e,t,r){if(!await hc()&&!Ur(`ngrok`))throw Error(`the tunnel library that comes with bitfolk isn't installed for this computer. Reinstall with npm i -g bitfolk (without --omit=optional), or install the ngrok program (https://ngrok.com/download). No ngrok account is needed.`);let i=process.env[bc],a=e=>i&&ue(i,JSON.stringify(e),{mode:384}),o=e=>{throw a({ok:!1,error:e}),Error(e)};if((r.public||r.signedIn)&&Oc()){let e=await kc(r.approval,process.env,fetch,r.public?`--public`:`--signed-in`);e&&o(e)}if(r.keep&&!i)return Nc(t,r);!r.run&&!await vc(t)&&o(`nothing is running on 127.0.0.1:${t}. Start your app first, or pass --run "<command>".`),r.run&&await vc(t)&&o(`something already listens on 127.0.0.1:${t}. Pick a free port for --run, or share that app without --run.`);let s=null;if(r.run){x(wc(),{recursive:!0,mode:448});let e=re(c(wc(),`port-${t}.app.log`),`w`,384);s=n(`sh`,[`-c`,r.run],{cwd:process.cwd(),env:{...process.env,PORT:String(t)},detached:!0,stdio:[`ignore`,e,e]});let i=pr(`Starting ${r.run}`,{quiet:!0}),a=await jc(t,s,15e4);i.stop(),a&&(Ac(s.pid,`SIGTERM`),o(`${a}. App log: ${c(wc(),`port-${t}.app.log`)}`))}let l=new Wt(e.api,()=>Nr(e)),u=pr(`Opening a link for 127.0.0.1:${t}`,{quiet:!0}),d;try{d=await l.openApp({name:r.name??``,port:t,access:r.public?`public`:r.signedIn?`account`:r.personal?`personal`:`town`,...Dc()})}catch(e){return Ac(s?.pid,`SIGTERM`),o(e.message)}finally{u.stop()}let f=wc();x(f,{recursive:!0,mode:448});let p=c(f,`${d.app_id}.yml`),m=null,h=null,g=!1,_=null,v=async(e,n)=>{if(!g){if(g=!0,_?.stop(),h&&clearInterval(h),m?.close(),Ac(s?.pid,`SIGTERM`),S(p,{force:!0}),i)try{JSON.parse(ie(Tc(t),`utf8`)).pid===process.pid&&S(Tc(t),{force:!0})}catch{}await l.stopApp(d.app_id).catch(()=>null),console.log(n),process.exit(e)}};process.on(`SIGINT`,()=>v(0,`\n${F(L.idle)} Stopped sharing ${P(d.name)}. The link no longer works.`)),process.on(`SIGTERM`,()=>v(0,`${F(L.idle)} Stopped sharing ${P(d.name)}.`)),process.on(`SIGHUP`,()=>v(0,`${F(L.idle)} Stopped sharing ${P(d.name)}.`)),_=pr(`Connecting the tunnel`,{quiet:!0,hint:`Ctrl-C to cancel`});try{m=await _c({port:t,internalUrl:d.internal_url,authtoken:d.authtoken,cfgFile:p},{lost:()=>console.log(Xn(`Lost the tunnel connection; reconnecting.`)),back:()=>console.log(W(`Tunnel reconnected.`))})}catch(e){_.stop();let t=e.message;return a({ok:!1,error:`couldn't share ${d.name}: ${t}`}),v(1,Zn(`couldn't share ${d.name}: ${t}`,`bitfolk: `))}if(await gc(d.url),_.stop(),m.closed.then(e=>v(1,Zn(`${e}, so ${d.name} is no longer shared.`))),s?.once(`exit`,e=>v(1,Zn(`the app stopped (exit ${e}), so ${d.name} is no longer shared.`))),i){let e=r.keep?new Date(Date.now()+r.keep*36e5).toISOString():null,n={pid:process.pid,port:t,app_id:d.app_id,name:d.name,url:d.url,until:e};ue(Tc(t),JSON.stringify(n),{mode:384}),r.keep&&setTimeout(()=>v(0,`Shared ${d.name} for ${r.keep} hours; stopped.`),r.keep*36e5).unref(),a({ok:!0,url:d.url,name:d.name,access:d.access,town:d.town})}let y=dc(d.access,d.town,d.members);console.log([W(`${P(d.name)} is shared`),...qn([Yn(d.url),``,...Kn([[`who`,y],[`from`,`127.0.0.1:${t}`],[`listed`,fc(d.access,!!Dc().session)]])]),F(i?` In the background. Stop it with: bitfolk share stop ${t}`:` Keep this running to stay shared. Ctrl-C stops it.`)].join(`
145
+ `));let ee=0;h=setInterval(async()=>{try{let e=await l.beatApp(d.app_id);ee=0,e.status===`stopped`&&await v(0,`Stopped sharing ${d.name}. ${yc[e.stop_reason??``]??``}`.trim())}catch{++ee===2&&console.log(Xn(`Can't reach your workspace right now; the link keeps working for a few minutes while this retries.`))}},Math.max(15,d.beat_s)*1e3)}const Fc={repo:{type:`string`},base:{type:`string`},runtime:{type:`string`},command:{type:`string`},acp:{type:`string`},model:{type:`string`},permission:{type:`string`},"max-usd":{type:`string`},"max-runs":{type:`string`},"pull-requests":{type:`string`},primary:{type:`string`},in:{type:`string`},timeout:{type:`string`},api:{type:`string`},email:{type:`string`},name:{type:`string`},public:{type:`boolean`},personal:{type:`boolean`},"signed-in":{type:`boolean`},run:{type:`string`},keep:{type:`string`},approval:{type:`string`},once:{type:`boolean`},goal:{type:`string`},task:{type:`string`},detach:{type:`boolean`},follow:{type:`boolean`,short:`f`},json:{type:`boolean`},all:{type:`boolean`},limit:{type:`string`},add:{type:`string`},spec:{type:`string`},note:{type:`string`},"let-sleep":{type:`boolean`},"no-browser":{type:`boolean`},"no-repo":{type:`boolean`},service:{type:`string`},"no-color":{type:`boolean`},agent:{type:`boolean`},tool:{type:`boolean`},force:{type:`boolean`},help:{type:`boolean`,short:`h`},version:{type:`boolean`,short:`v`}};function Ic(e,t,n,r){if(e===void 0)return;let i=Number(e);if(!Number.isFinite(i)||i<n||i>r)throw new Q(`--${t} must be a number from ${n} to ${r}`);return i}function Lc(e){if(!e)return!1;try{return t(`sh`,[`-c`,`command -v "$1"`,`sh`,e],{stdio:`ignore`}),!0}catch{return!1}}function Rc(e,t){let n={...e};if(t.runtime!==void 0){if(!Gt.includes(t.runtime))throw new Q(`--runtime must be one of ${Gt.join(`, `)}`);n.runtime=t.runtime}if(t.command!==void 0&&(n.command=t.command),n.runtime===`command`&&!n.command)throw new Q(`runtime command needs --command "..."`);if(t.permission!==void 0){if(!Kt.includes(t.permission))throw new Q(`--permission must be one of ${Kt.join(`, `)}`);n.permission=t.permission}if(t.repo!==void 0){let e=Ki(u(t.repo));if(!e)throw new Q(`${t.repo} isn't inside a git repository`);n.repo=e}return t.base!==void 0&&(n.base=t.base),t.model!==void 0&&(n.model=t.model||void 0),n.maxUsdPerRun=Ic(t[`max-usd`],`max-usd`,.01,100)??n.maxUsdPerRun,n.maxRunsPerHour=Ic(t[`max-runs`],`max-runs`,1,60)??n.maxRunsPerHour,n.timeoutMin=Ic(t.timeout,`timeout`,1,600)??n.timeoutMin,n}function zc(e){return ts(e,e.repo?`${e.repo} ${F(`(branch ${qi(e)})`)}`:F(`no repo`),en().agents[e.id]?.disabledReason)}const Bc=e=>ns([zc(e)])[0].join(`
146
+ `),Vc=e=>(e.api??process.env.BITFOLK_API??`https://bitfolk.ai`).replace(/\/+$/,``);async function Hc(e,t){if(e??=process.env.BITFOLK_TOKEN,!e||!/^bfa_[A-Za-z0-9]{20,}$/.test(e))throw new Q(`give the agent's token from its page on your workspace: ${w} add bfa_... (to link this computer instead, run ${w} login)`);let n=Vc(t),r=await K(`Asking your workspace about this agent`,()=>new Ut(n,e).setup());await il(n,e,r,t,void 0)}const Uc=(e=[])=>[...qr().filter(e=>e.supported).map(e=>e.id),...e.map(e=>Jr(e.name))];function Wc(){let e=qr().filter(e=>!e.supported);e.length!==0&&(console.log(`\n ${P(`Also found`)} ${F(`(not built in yet; add one with ${w} add, then check the command works headless):`)}`),console.log(Wn(e.map(e=>[e.label,U(`${w} add ${e.id.replace(/_/g,`-`)} --command '${e.suggest}'`)]),{indent:4}).join(`
147
+ `)))}async function Gc(e,t=`done`){let n=Vc(e),r=A().machine,i=!!e[`no-browser`]||kr(),{accessToken:a,link:o,me:s}=await jr(n,{browser:!i,remote:i,detected:Uc(r?.customTools)});r&&r.id!==s.machine.id&&await Fr(r);let c=qc({...qt,...r??{},id:s.machine.id,name:s.machine.name,api:n,token:a,oauth:o,runtimes:s.machine.runtimes,customTools:r?.customTools,workspace:s.workspace?.name},e),l=null;if(e.repo===void 0&&!c.repo&&!(c.repos??[]).length&&!e[`no-repo`]){let e=Ki(process.cwd());if(e){let t=_a(c,e,void 0,!0);c.repos=t.repos,c.repo=t.repo,l=e}}let u=A();u.machine=c,$t(u),c.repo&&await $c(c),console.log(``),await Hi(as(c,s.workspace?.name??`your workspace`)),console.log(``);for(let e of c.runtimes){let t=Br.find(t=>t.id===e);t&&!Wr(t)&&console.log(` ${Xn(`warning: ${t.label} isn't installed here yet; install it and sign in before sessions start.`)}`)}let d=c.runtimes.map(J);if(d.length?(console.log(` ${W(`${Kc(d)} ${d.length===1?`is a builder`:`are builders`} in ${s.workspace?.name??`your workspace`} now.`)}`),console.log(` ${F(`Mention one in a goal chat (@${d[0]}) or press Run on a goal, and a session starts here.`)}`)):console.log(` ${Xn(`no coding tools on yet: turn one on with ${w} add claude-code (or codex, opencode, ...)`)}`),Wc(),l?console.log(` ${F(`builders work in`)} ${l} ${F(`(each session in its own worktree and branch). Change it with ${w} repos.`)}`):c.repo||console.log(` ${F(`no repo yet: builders work in plain folders. Give them one with:`)} ${U(`${w} set --repo <path>`)}`),t===`up`)return void console.log(``);console.log(`\nKeep it running with: ${P(U(`${w} up`))}`),ye&&console.log(F(`To keep the command around, install it once: ${U(`npm i -g bitfolk`)} (then use bitfolk up).`))}const Kc=e=>e.length<2?e.join(``):`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`;function qc(e,t){let n=Rc({...e,slug:`machine`,runtime:`claude_code`},{...t,runtime:void 0,command:void 0}),r=e.pullRequests;if(t[`pull-requests`]!==void 0){let e=t[`pull-requests`].toLowerCase();if(![`on`,`off`].includes(e))throw new Q(`--pull-requests must be on or off`);if(r=e===`on`,r&&!n.repo)throw new Q(`pull requests need a repo: ${w} set --repo <path> --pull-requests on`)}let i=t.repo!==void 0&&n.repo?_a(e,n.repo,void 0,!0):{repos:e.repos,repo:n.repo};return{...e,repo:i.repo,repos:i.repos,base:n.base,pullRequests:r,model:n.model,permission:n.permission,maxUsdPerRun:n.maxUsdPerRun,maxRunsPerHour:n.maxRunsPerHour,timeoutMin:n.timeoutMin}}const Jc=e=>ns([es(e)])[0].join(`
148
+ `);function Yc(){let e=qr({versions:!0}),t=A().machine;if(e.length===0&&!t?.customTools?.length){console.log(Zn(`No coding tools found. Install Claude Code, Codex, OpenCode or Hermes, then run ${w} login.`));return}console.log(P(I.accent(`Coding tools on this computer`)));let n=e=>`${I.ok(L.dot)} ${I.ok(e)}`,r=e=>`${F(L.idle)} ${F(e)}`,i=[],a=N()<60,o=e=>a||!Ui(e)?``:Ui(e)+` `;for(let s of e){let e=s.acp?` via ACP`:``,c=s.supported?t?t.runtimes.includes(s.id)?n(`on${e}`):`${r(`off${e}`)} ${F(`(`)}${U(`${w} add ${s.id.replace(/_/g,`-`)}`)}${F(`)`)}`:n(`supported${e}`):`${I.warn(L.skip)} ${I.warn(`not built in`)} ${F(`(${w} add ${s.id.replace(/_/g,`-`)} --command ...)`)}`,l=F(V(Xc(s.version,s.label),16));a?i.push([I.tool(P(s.label))],[` ${l}${s.version?F(` · `):``}${c}`],[` ${F(s.path)}`]):(i.push([o(s.id)+I.tool(P(s.label)),l,c]),i.push([``,F(s.path)]))}for(let e of t?.customTools??[]){let s=e.protocol===`acp`?`custom, via ACP`:`custom`;i.push([(a?``:o(Jr(e.name)))+I.tool(P(e.name)),F(s),`${t.runtimes.includes(Jr(e.name))?n(`on`):r(`off`)}${F(`:`)} ${e.command}`])}console.log(Wn(i,{indent:2,gap:2}).join(`
149
+ `)),(e.some(e=>e.supported&&e.acp)||t?.customTools?.some(e=>e.protocol===`acp`))&&console.log(F(`
143
150
  Via ACP: sign in to each tool in a terminal first. Safe mode is enforced through the tool's permission requests
144
151
  (its own settings may allow more), and --max-usd stops a session once its reported cost passes the cap.`)),t||console.log(`
145
- `+W(`Link this computer with ${H(`${w} login`)} to let your workspace start them.`,0))}function zc(e,t){let n=(e??``).replace(/\(.*$/,``).replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),`ig`),``).trim().split(/\s+/),r=n.findIndex(e=>/\d/.test(e));return(r>=0?n.slice(r):n).join(` `).trim()}const Bc=(e,t,n)=>G(`Telling your workspace`,()=>new Ht(e.api,()=>jr(e)).setTools(t,n));async function Vc(e){let t=k().machine;if(!t)throw new Q(`link this computer first: ${w} login`);let n=[`none`,`off`,``].includes(e.trim().toLowerCase())?null:Ua(e,t),r=await Bc(t,t.runtimes,n),i=k();i.machine={...i.machine,runtimes:r.runtimes,primary:r.primary??void 0},Zt(i),console.log(U(n?`${F.tool(q(n))} is your primary. Sessions use it while it has usage left, and another tool when it runs low.`:`No primary tool: sessions use whichever tool has the most usage left.`))}async function Hc(e){await new Ht(e.api,()=>jr(e)).report({repos:pa(e)}).catch(()=>null)}async function Uc(e,t,n){let r=k(),i=r.machine;if(!i)throw new Q(`link this computer first: ${w} login`);if(e){let a;try{if(e===`add`){let e=Ui(u(t));if(!e)throw Error(`${t} isn't inside a git repository. Builders work in git repos only: run git init there first`);a=ma(i,e,n.name)}else if(e===`rm`)a=ha(i,t);else{let e=X(i).find(e=>e.name===t.toLowerCase());if(!e)throw Error(`no repo named ${t} here (it has: ${X(i).map(e=>e.name).join(`, `)||`none`})`);a={repos:X(i),repo:e.path}}}catch(e){throw new Q(e.message)}r.machine={...i,repos:a.repos,repo:a.repo},a.repo||(r.machine.pullRequests=!1),Zt(r),await G(`Telling your workspace`,()=>Hc(r.machine))}let a=X(r.machine);if(!a.length){console.log(`${P(`No repos yet: builders work in plain folders. Add one with`)} ${H(`${w} repos add <path>`)}`);return}console.log(N(F.accent(`Repos builders may work in`)));let o=ua(r.machine);console.log(Wn(a.map(e=>[e.name,`${e.path}${e===o?P(` · default`):``}`]),2).join(`
146
- `)),console.log(P(`\nSessions use the default unless they name another: ${w} run --in <name> "...", the Run picker, or an agent's request.`))}async function Wc(e,t,n){let r=k().machine;if(!r)throw new Q(`link this computer first: ${w} login`);if(!t||!Jr.test(t))throw new Q(`give the tool a short name: lowercase letters, numbers and dashes. See ${w} tools`);if(n.command!==void 0&&n.acp!==void 0)throw new Q(`give --command or --acp, not both`);let i=qr(e,t,r,n);if(i){e===`add`&&!Hr(i)&&console.log(Jn(`warning: ${i.label} isn't installed here yet.`));let t=e===`add`?[...new Set([...r.runtimes,i.id])]:r.runtimes.filter(e=>e!==i.id);if(t.length===0)throw new Q(`that's the last tool on this computer; keep at least one, or run ${w} logout`);let n=await Bc(r,t),a=k();return a.machine={...a.machine,runtimes:n.runtimes,primary:n.primary===void 0?a.machine.primary:n.primary??void 0},Zt(a),console.log(U(e===`add`?`Turned on ${F.tool(i.label)}. Your workspace can start it now: pick it on Run.`:`Turned off ${F.tool(i.label)}.`)),console.log(` ${Lc(a.machine)}`)}let a=Kr(t),o=(r.customTools??[]).filter(e=>e.name!==t),s=r.runtimes.filter(e=>e!==a);if(e===`rm`&&!(r.customTools??[]).some(e=>e.name===t)&&!r.runtimes.includes(a))throw new Q(`no tool or agent called ${t} here. See ${w} status`);if(e===`add`){let e=Gc(t,n),r=e.protocol===`acp`?ot(e.command).bin:e.command.split(/\s+/)[0]??``;Vr(r)||console.log(Jn(`warning: ${r} isn't installed here yet.`)),o=[...o,e],s=[...s,a]}let c=await Bc(r,s),l=k();l.machine={...l.machine,customTools:o,runtimes:c.runtimes},Zt(l),console.log(U(e===`add`?`Added ${F.tool(t)}. Your workspace can start it now: pick it on Run.`:`Removed ${F.tool(t)}.`)),console.log(` ${Lc(l.machine)}`)}function Gc(e,t){if(t.acp!==void 0){let n=t.acp.trim();if(!n)throw new Q(`${w} add ${e} --acp "<cmd>" (a command that speaks ACP on stdio)`);try{ot(n)}catch(e){throw new Q(`--acp: ${e.message}`)}return{name:e,command:n,protocol:`acp`}}let n=t.command?.trim();if(!n)throw new Q(Rr.some(t=>t.id===e.replace(/-/g,`_`))?`${e} isn't built in yet; give the command to run: ${w} add ${e} --command "<cmd>" (it gets the work packet on stdin)`:`${e} isn't a coding tool bitfolk knows; to add your own: ${w} add ${e} --command "<cmd>" (see ${w} tools)`);return{name:e,command:n}}async function Kc(){let e=k();if(!e.machine)return console.log(`${P(I.idle)} This computer isn't linked.`);let t=e.machine,n=await G(`Unlinking from your workspace`,()=>Nr(t)),r=e.machine.name;delete e.machine,Zt(e),console.log(n?U(`Unlinked ${N(r)} from your workspace.`):Jn(`Forgot ${r} here, but couldn't reach Bitfolk: press Unlink in Settings, Machines.`))}async function qc(e,t,n,r,i){let a=k(),o=a.agents.find(e=>e.id===n.agent.id),s=r.runtime??o?.runtime??Ze(n.agent.runtime);if(!s)throw new Q(`${n.agent.name} is a ${n.agent.runtime} agent, which this runner can't start by itself. Add --runtime claude_code, --runtime codex, or --runtime command --command "..."`);o?.oauth&&o.oauth.refreshToken!==i?.refreshToken&&await Nr(o);let c=o?{...o,token:t,oauth:i,api:e,name:n.agent.name}:{id:n.agent.id,name:n.agent.name,slug:en(n.agent.name,a.agents.map(e=>e.slug)),runtime:s,api:e,token:t,oauth:i,...Gt};c.oauth||delete c.oauth;let l=Oc(c,{...r,runtime:s}),u=Xe[l.runtime].bin(l);a.agents=[...a.agents.filter(e=>e.id!==l.id),l],Zt(a);let d=Qt();d.agents[l.id]?.disabledReason&&(delete d.agents[l.id].disabledReason,$t(d)),console.log(U(`${o?`Updated`:`Added`} ${N(l.name)} ${P(`(${n.workspace?.name??`workspace`}, owner ${n.owner?.name??`?`})`)}`)),console.log(Wn([[`objectives`,n.goals.map(e=>e.title).join(`; `)||P(`none yet`)]],2).join(`
147
- `)),console.log(` ${Ac(l)}`),i&&console.log(P(` signed in through your browser; sign-in renews by itself`)),l.repo||console.log(` ${P(`no repo yet: it works in a plain folder. Point it at one with:`)} ${H(`${w} set ${l.slug} --repo <path>`)}`),Dc(u)||console.log(` ${Jn(`warning: \`${u}\` isn't on PATH yet; install it and sign in before \`${w} up\`.`)}`),console.log(`\nStart it with: ${N(H(`${w} up`))}`)}function Jc(e,t){let n=k();if(!e){if(!n.machine)throw new Q(`this computer isn't linked yet: run ${w} login`);if(!Object.keys(t).filter(e=>![`no-color`,`help`,`version`,`agent`,`tool`,`force`].includes(e)).length)throw new Q(`what to change? ${w} set --repo <path>, or ${w} set --max-usd 2. See ${w} help set`);return n.machine=Ic(n.machine,t),Zt(n),console.log(Lc(n.machine))}let r=tn(n,e);if(!r)throw new Q(`no agent called ${e} on this machine`);let i=Oc(r,t);n.agents=n.agents.map(e=>e.id===r.id?i:e),Zt(n),console.log(Ac(i))}async function Yc(e,t){if(!e)throw new Q(`which agent? ${w} rm <agent>`);let n=k(),r=tn(n,e);if(!r)throw new Q(`no agent called ${e} on this machine`);let i=Ji(r);if(i?.changed&&!t.force)throw new Q(`${r.name} has ${i.changed} uncommitted change${i.changed===1?``:`s`} in ${i.dir}. Commit or copy ${i.changed===1?`it`:`them`} first, or run ${w} rm "${r.name}" --agent --force to remove it anyway`);Yi(r);let a=await G(`Removing ${r.name}`,()=>Nr(r));n.agents=n.agents.filter(e=>e.id!==r.id),Zt(n);let o=Qt();delete o.agents[r.id],$t(o);let s=r.repo&&Gi(r.repo,Wi(r));console.log(U(`Removed ${N(r.name)} from this machine.${s?P(` Its branch ${Wi(r)} is still in ${r.repo}.`):``}`)),console.log(r.oauth?a?P(` This machine is unlinked from it on your workspace too.`):` ${Jn(`Couldn't reach Bitfolk to unlink it; press Unlink on its page on your workspace.`)}`:P(` Its token still works; revoke it on your workspace if you're done with this agent.`))}function Xc(e,t,n){if(!e)return[[`login`,`link this computer to your workspace`],[`tools`,`see the coding tools found here`],[`help`,`all commands`]];let r=[];return t||r.push([`up`,`take sessions your workspace starts here`]),n[0]&&r.push([`add ${n[0]}`,`turn on another tool`]),e.repo||r.push([`set --repo <path>`,`give sessions a git repo`]),r.push([`check`,`check sign-in and tools`]),r.push([`help`,`all commands`]),r.slice(0,4)}async function Zc(){let e=k(),t=e.machine,n=Ba(),r=e=>{console.log(``),console.log(Hn(e.map(([e,t])=>[zo(e),P(t)]),{indent:2,gap:2}).join(`
148
- `))};if(!t&&e.agents.length===0){let e=Li({version:Rt,tagline:`Coding sessions for your workspace`,url:`bitfolk.ai`});return e.length&&console.log(e.join(`
152
+ `+G(`Link this computer with ${U(`${w} login`)} to let your workspace start them.`,0))}function Xc(e,t){let n=(e??``).replace(/\(.*$/,``).replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),`ig`),``).trim().split(/\s+/),r=n.findIndex(e=>/\d/.test(e));return(r>=0?n.slice(r):n).join(` `).trim()}const Zc=(e,t,n)=>K(`Telling your workspace`,()=>new Wt(e.api,()=>Nr(e)).setTools(t,n));async function Qc(e){let t=A().machine;if(!t)throw new Q(`link this computer first: ${w} login`);let n=[`none`,`off`,``].includes(e.trim().toLowerCase())?null:Ja(e,t),r=await Zc(t,t.runtimes,n),i=A();i.machine={...i.machine,runtimes:r.runtimes,primary:r.primary??void 0},$t(i),console.log(W(n?`${I.tool(J(n))} is your primary. Sessions use it while it has usage left, and another tool when it runs low.`:`No primary tool: sessions use whichever tool has the most usage left.`))}async function $c(e){await new Wt(e.api,()=>Nr(e)).report({repos:ga(e)}).catch(()=>null)}async function el(e,t,n){let r=A(),i=r.machine;if(!i)throw new Q(`link this computer first: ${w} login`);if(e){let a;try{if(e===`add`){let e=Ki(u(t));if(!e)throw Error(`${t} isn't inside a git repository. Builders work in git repos only: run git init there first`);a=_a(i,e,n.name)}else if(e===`rm`)a=va(i,t);else{let e=X(i).find(e=>e.name===t.toLowerCase());if(!e)throw Error(`no repo named ${t} here (it has: ${X(i).map(e=>e.name).join(`, `)||`none`})`);a={repos:X(i),repo:e.path}}}catch(e){throw new Q(e.message)}r.machine={...i,repos:a.repos,repo:a.repo},a.repo||(r.machine.pullRequests=!1),$t(r),await K(`Telling your workspace`,()=>$c(r.machine))}let a=X(r.machine);if(!a.length){console.log(`${F(`No repos yet: builders work in plain folders. Add one with`)} ${U(`${w} repos add <path>`)}`);return}console.log(P(I.accent(`Repos builders may work in`)));let o=pa(r.machine);console.log(Kn(a.map(e=>[e.name,`${e.path}${e===o?F(` · default`):``}`]),2).join(`
153
+ `)),console.log(F(`\nSessions use the default unless they name another: ${w} run --in <name> "...", the Run picker, or an agent's request.`))}async function tl(e,t,n){let r=A().machine;if(!r)throw new Q(`link this computer first: ${w} login`);if(!t||!Xr.test(t))throw new Q(`give the tool a short name: lowercase letters, numbers and dashes. See ${w} tools`);if(n.command!==void 0&&n.acp!==void 0)throw new Q(`give --command or --acp, not both`);let i=Yr(e,t,r,n);if(i){e===`add`&&!Wr(i)&&console.log(Xn(`warning: ${i.label} isn't installed here yet.`));let t=e===`add`?[...new Set([...r.runtimes,i.id])]:r.runtimes.filter(e=>e!==i.id);if(t.length===0)throw new Q(`that's the last tool on this computer; keep at least one, or run ${w} logout`);let n=await Zc(r,t),a=A();return a.machine={...a.machine,runtimes:n.runtimes,primary:n.primary===void 0?a.machine.primary:n.primary??void 0},$t(a),console.log(W(e===`add`?`Turned on ${I.tool(i.label)}. It's a builder in your workspace now: mention @${i.label} in a goal chat, or pick it on Run.`:`Turned off ${I.tool(i.label)}. Its builder leaves your workspace; turn it on again and it comes back with its record.`)),console.log(` ${Jc(a.machine)}`)}let a=Jr(t),o=(r.customTools??[]).filter(e=>e.name!==t),s=r.runtimes.filter(e=>e!==a);if(e===`rm`&&!(r.customTools??[]).some(e=>e.name===t)&&!r.runtimes.includes(a))throw new Q(`no tool or agent called ${t} here. See ${w} status`);if(e===`add`){let e=nl(t,n),r=e.protocol===`acp`?ot(e.command).bin:e.command.split(/\s+/)[0]??``;Ur(r)||console.log(Xn(`warning: ${r} isn't installed here yet.`)),o=[...o,e],s=[...s,a]}let c=await Zc(r,s),l=A();l.machine={...l.machine,customTools:o,runtimes:c.runtimes},$t(l),console.log(W(e===`add`?`Added ${I.tool(t)}. It's a builder in your workspace now: mention @${t} in a goal chat, or pick it on Run.`:`Removed ${I.tool(t)}. Its builder leaves your workspace.`)),console.log(` ${Jc(l.machine)}`)}function nl(e,t){if(t.acp!==void 0){let n=t.acp.trim();if(!n)throw new Q(`${w} add ${e} --acp "<cmd>" (a command that speaks ACP on stdio)`);try{ot(n)}catch(e){throw new Q(`--acp: ${e.message}`)}return{name:e,command:n,protocol:`acp`}}let n=t.command?.trim();if(!n)throw new Q(Br.some(t=>t.id===e.replace(/-/g,`_`))?`${e} isn't built in yet; give the command to run: ${w} add ${e} --command "<cmd>" (it gets the work packet on stdin)`:`${e} isn't a coding tool bitfolk knows; to add your own: ${w} add ${e} --command "<cmd>" (see ${w} tools)`);return{name:e,command:n}}async function rl(){let e=A();if(!e.machine)return console.log(`${F(L.idle)} This computer isn't linked.`);let t=e.machine,n=await K(`Unlinking from your workspace`,()=>Fr(t)),r=e.machine.name;delete e.machine,$t(e),console.log(n?W(`Unlinked ${P(r)} from your workspace.`):Xn(`Forgot ${r} here, but couldn't reach Bitfolk: press Unlink in Settings, Machines.`))}async function il(e,t,n,r,i){let a=A(),o=a.agents.find(e=>e.id===n.agent.id),s=r.runtime??o?.runtime??Ze(n.agent.runtime);if(!s)throw new Q(`${n.agent.name} is a ${n.agent.runtime} agent, which this runner can't start by itself. Add --runtime claude_code, --runtime codex, or --runtime command --command "..."`);o?.oauth&&o.oauth.refreshToken!==i?.refreshToken&&await Fr(o);let c=o?{...o,token:t,oauth:i,api:e,name:n.agent.name}:{id:n.agent.id,name:n.agent.name,slug:nn(n.agent.name,a.agents.map(e=>e.slug)),runtime:s,api:e,token:t,oauth:i,...qt};c.oauth||delete c.oauth;let l=Rc(c,{...r,runtime:s}),u=Xe[l.runtime].bin(l);a.agents=[...a.agents.filter(e=>e.id!==l.id),l],$t(a);let d=en();d.agents[l.id]?.disabledReason&&(delete d.agents[l.id].disabledReason,tn(d)),console.log(W(`${o?`Updated`:`Added`} ${P(l.name)} ${F(`(${n.workspace?.name??`workspace`}, owner ${n.owner?.name??`?`})`)}`)),console.log(Kn([[`goals`,n.goals.map(e=>e.title).join(`; `)||F(`none yet`)]],2).join(`
154
+ `)),console.log(` ${Bc(l)}`),i&&console.log(F(` signed in through your browser; sign-in renews by itself`)),l.repo||console.log(` ${F(`no repo yet: it works in a plain folder. Point it at one with:`)} ${U(`${w} set ${l.slug} --repo <path>`)}`),Lc(u)||console.log(` ${Xn(`warning: \`${u}\` isn't on PATH yet; install it and sign in before \`${w} up\`.`)}`),console.log(`\nStart it with: ${P(U(`${w} up`))}`)}function al(e,t){let n=A();if(!e){if(!n.machine)throw new Q(`this computer isn't linked yet: run ${w} login`);if(!Object.keys(t).filter(e=>![`no-color`,`help`,`version`,`agent`,`tool`,`force`].includes(e)).length)throw new Q(`what to change? ${w} set --repo <path>, or ${w} set --max-usd 2. See ${w} help set`);return n.machine=qc(n.machine,t),$t(n),console.log(Jc(n.machine))}let r=rn(n,e);if(!r)throw new Q(`no agent called ${e} on this machine`);let i=Rc(r,t);n.agents=n.agents.map(e=>e.id===r.id?i:e),$t(n),console.log(Bc(i))}async function ol(e,t){if(!e)throw new Q(`which agent? ${w} rm <agent>`);let n=A(),r=rn(n,e);if(!r)throw new Q(`no agent called ${e} on this machine`);let i=Zi(r);if(i?.changed&&!t.force)throw new Q(`${r.name} has ${i.changed} uncommitted change${i.changed===1?``:`s`} in ${i.dir}. Commit or copy ${i.changed===1?`it`:`them`} first, or run ${w} rm "${r.name}" --agent --force to remove it anyway`);Qi(r);let a=await K(`Removing ${r.name}`,()=>Fr(r));n.agents=n.agents.filter(e=>e.id!==r.id),$t(n);let o=en();delete o.agents[r.id],tn(o);let s=r.repo&&Ji(r.repo,qi(r));console.log(W(`Removed ${P(r.name)} from this machine.${s?F(` Its branch ${qi(r)} is still in ${r.repo}.`):``}`)),console.log(r.oauth?a?F(` This machine is unlinked from it on your workspace too.`):` ${Xn(`Couldn't reach Bitfolk to unlink it; press Unlink on its page on your workspace.`)}`:F(` Its token still works; revoke it on your workspace if you're done with this agent.`))}function sl(e,t,n){if(!e)return[[`login`,`link this computer to your workspace`],[`tools`,`see the coding tools found here`],[`help`,`all commands`]];let r=[];return t||r.push([`up`,`take sessions your workspace starts here`]),n[0]&&r.push([`add ${n[0]}`,`turn on another tool`]),e.repo||r.push([`set --repo <path>`,`give sessions a git repo`]),r.push([`check`,`check sign-in and tools`]),r.push([`help`,`all commands`]),r.slice(0,4)}async function cl(){let e=A(),t=e.machine,n=Ga(),r=e=>{console.log(``),console.log(Wn(e.map(([e,t])=>[Wo(e),F(t)]),{indent:2,gap:2}).join(`
155
+ `))};if(!t&&e.agents.length===0){let e=zi({version:Rt,tagline:`Coding sessions for your workspace`,url:`bitfolk.ai`});return e.length&&console.log(e.join(`
149
156
  `)+`
150
- `),console.log(W(`${P(I.idle)} Not linked yet. Run ${H(`${w} login`)} to link this computer to your workspace, then ${H(`${w} up`)}.`)),r(Xc(void 0,!1,[]))}let i=t?Gr().filter(e=>e.supported&&!t.runtimes.includes(e.id)).map(e=>e.id.replace(/_/g,`-`)):[],a=[];if(t){let e;try{let r=await G(`Asking your workspace`,()=>Promise.race([new Ht(t.api,()=>jr(t)).me(),new Promise((e,t)=>setTimeout(()=>t(Error(`no answer`)),8e3).unref())]));Object.assign(t,nn(t,r)),e=r.queued?F.accent(`${r.queued} waiting`)+(n?``:P(` · run ${w} up to take them`)):P(`none waiting`)}catch(t){e=t instanceof K&&t.ended?F.err(`sign-in ended; run ${w} login`):t instanceof Bt&&t.status===401?F.err(`unlinked; run ${w} login`):F.warn(`couldn't reach your workspace (${w} check)`)}console.log(W(`${N(F.accent(t.name))} ${P(`on`)} ${N(t.workspace??`your workspace`)}`)),a.push([`tools`,Ko(t.runtimes)+(i.length?P(` ${R(`off: ${i.join(`, `)}`)}`):``)]),a.push([`sessions`,e]),a.push([`up`,n?`${F.ok(I.dot)} ${F.ok(`running`)} ${P(`(pid ${n})`)}`:`${P(I.idle)} ${P(`not running`)}`]),a.push([`limits`,`${F.money(`$${t.maxUsdPerRun}`)}${P(`/session · `)}${t.maxRunsPerHour}${P(`/h · `)}${t.timeoutMin}${P(` min · `)}${t.permission}`]);let r=X(t);a.push([`repos`,r.length?r.map((e,t)=>t===0?`${e.name} ${P(`(default)`)}`:e.name).join(P(`, `))+(t.pullRequests?P(` · opens pull requests`):``):P(`none: builders work in plain folders`)]),t.primary&&a.push([`primary`,`${q(t.primary)} ${P(`while it has usage left`)}`]),console.log(Wn(a,2).join(`
151
- `))}else console.log(W(`${P(I.idle)} This computer isn't linked. ${P(`Agents added here still run with`)} ${H(`${w} up`)}${P(`.`)}`));e.agents.length&&(console.log(`\n${N(F.accent(`Agents added here`))}${P(`:`)}`),console.log(Zo(e.agents.map(kc),2).flat().join(`
152
- `))),r(Xc(t,!!n,i))}async function Qc(){let e=k(),t=0,n=0,r=null,i=``,a=e=>{r?.stop(),r=null,console.log(W(i+e,i.length+2))},o=(e,r)=>{e?t++:n++,a(e?`${F.ok(I.ok)} ${r}`:`${F.err(I.fail)} ${F.err(r)}`)},s=e=>a(`${P(I.skip)} ${P(e)}`),c=e=>{r?.stop(),r=null,i=``,console.log(`\n${N(e)}`),i=` `},l=e=>{r&&r.stop(),r=dr(e.replace(/\.\.\.$/,``),{quiet:!0})};console.log(W(`${N(F.accent(`bitfolk check`))} ${P(`· v${Rt} · node ${process.version}`)}`)),console.log(W(P(`config ${Yt()}`))),o(!!Vr(`git`),`git ${Vr(`git`)?`found`:`not found (needed for repos and worktrees)`}`);let u=Gr(),d=[];for(let e of Rr.filter(e=>e.supported)){let t=u.find(t=>t.id===e.id);t?o(!0,`${F.tool(e.label)} found ${P(`(${t.path})`)}`):d.push(e.label)}d.length&&s(`not found: ${d.join(`, `)}`),(process.env.HTTPS_PROXY||process.env.https_proxy||process.env.HTTP_PROXY)&&!process.env.NODE_USE_ENV_PROXY&&s(`HTTPS_PROXY is set, but Node ignores it unless NODE_USE_ENV_PROXY=1 (Node 22.21+). Set it if bitfolk can't connect.`);let f=e.machine?.api??process.env.BITFOLK_API;f&&f.replace(/\/+$/,``)!==`https://bitfolk.ai`&&s(`talking to ${f}, not ${zt}`);let p=e.machine;if(!p)s(`this computer isn't linked (${w} login)`);else{c(p.name),l(`checking ${p.name}'s link to your workspace...`);try{let e=await new Ht(p.api,()=>jr(p)).me();nn(p,e),o(!0,`linked to ${N(e.workspace?.name??`your workspace`)}, ${e.queued} session${e.queued===1?``:`s`} waiting`)}catch(e){o(!1,e instanceof K&&e.ended?`sign-in ended; run ${w} login`:e instanceof Bt&&e.status===401?`unlinked; run ${w} login`:e.message)}for(let e of p.runtimes){let t;try{t=Ma({...p,command:void 0},e).acp}catch{}if(e.startsWith(`custom:`)){let n=p.customTools?.find(t=>Kr(t.name)===e),r=t?.bin??n?.command.trim().split(/\s+/)[0]??``;o(!!n&&!!Vr(r),`${F.tool(q(e))} sessions run \`${n?.command??`(not set up here)`}\`${t?` over ACP`:``}`)}else{let t=Rr.find(t=>t.id===e),n=t?Hr(t):null;if(o(!!n,`${F.tool(q(e))} sessions${n?P(` (${n}${t?.acp?`, via ACP`:``})`):` need it installed`}`),!n)continue}let n=t&&!p.command?Vr(t.bin):null;t&&n&&(l(`asking ${q(e)} to say hello over ACP...`),await $c(q(e),{...t,bin:n},o))}p.repo&&o(!!Ui(p.repo),`repo ${p.repo}`),process.platform===`darwin`&&s(`${w} up keeps this Mac awake, but closing the lid on battery still sleeps it and pauses sessions.`)}for(let t of e.agents){c(t.name),l(`checking ${t.name}...`);try{let e=await new Vt(t.api,t.oauth?()=>jr(t):t.token).setup();o(!0,`${t.oauth?`signed in`:`token works`} (${e.goals.length} objective${e.goals.length===1?``:`s`})`)}catch(e){o(!1,e instanceof K&&e.ended?`sign-in ended; add it again with ${w} add <token from its page>`:e instanceof Bt&&e.status===401?`token rejected`:e.message)}let e=Xe[t.runtime].bin(t);o(Dc(e),`runtime ${F.tool(t.runtime)} ${P(`(${e||`no command`})`)}`),t.repo&&o(!!Ui(t.repo),`repo ${t.repo}`)}r?.stop(),i=``;let m=`${t} check${t===1?``:`s`} passed`;console.log(n?`\n${F.err(I.fail)} ${F.err(N(`${n} problem${n===1?``:`s`}`))}${P(`, ${m}`)}`:`\n${F.ok(I.ok)} ${F.ok(N(`All good`))}${P(`: ${m}`)}`),n&&(process.exitCode=1)}async function $c(e,t,n){try{let r=await Lt(t,{timeoutMs:5e3,version:Rt}),i=[r.agentInfo?.name,r.agentInfo?.version].filter(Boolean).join(` `)||`an unnamed agent`;if(r.protocolVersion!==1)return n(!1,`${e} speaks ACP v${String(r.protocolVersion)}; this runner speaks v1`);let a=r.authMethods.map(e=>e.description??e.name??e.id).filter(Boolean);n(!0,`${F.tool(e)} answers over ACP v1 ${P(`(${i})${a.length?`; sign-in: ${a.join(`; `)}`:``}`)}`)}catch(t){n(!1,`${e} didn't answer ACP initialize: ${t.message}`)}}const el=(e,t,n)=>e?`on`:process.platform===`darwin`&&n.machine&&t[`let-sleep`]?`off`:void 0;async function tl(e,t,n={}){let r=k();if(n.sessionsOnly&&(r.agents=[]),e){let t=tn(r,e);if(!t)throw new Q(`no agent called ${e}. See ${w} status`);r.agents=[t]}let i=Va(),a=null,o=e=>a?a.log(e):console.log(e),s=new Ia(r,{out:o,liveFooter:er()&&!!process.stdout.isTTY}),c=Po({platform:process.platform,linked:!!r.machine,letSleep:t[`let-sleep`]})?Fo():null;if(r.machine){let e=r.machine,t=await Promise.race([new Ht(e.api,()=>jr(e)).me().catch(()=>null),new Promise(e=>setTimeout(()=>e(null),3e3).unref())]);t&&(r.machine=nn(e,t))}(r.machine||r.agents.length)&&(await Bi(ts({version:Rt,machine:r.machine,agents:r.agents,maxConcurrent:r.maxConcurrent,awake:el(c,t,r)}),void 0,void 0,void 0,()=>{c?.(),i()}),console.log(``));let l=er()&&!!process.stdout.isTTY&&!!process.stdin.isTTY&&!n.sessionsOnly&&!t.once,u=T(),d=null,f=e=>{if(d)return`${F.accent(I.dot)} ${P(`running ${d}…`)}`;if(!u.text)return`${F.accent(`›`)} ${P(`type a command, or help`)}`;let t=u.text[u.cursor]??` `,n=`${u.text.slice(0,u.cursor)}\x1b[7m${t}\x1b[27m${u.text.slice(u.cursor+1)}`;return B(`${F.accent(`›`)} ${n}`,Math.max(10,e-1))},p={machine:r.machine,agents:r.agents,maxConcurrent:r.maxConcurrent,awake:el(c,t,r),version:Rt,typing:l};a=pr((e,t)=>{let n=os(s,p,{frame:e,...t});return l?[...Array.isArray(n)?n:[n],f(t.columns)]:n},{intervalMs:()=>{let e=s.status();return e.running||e.stopping||e.checking?100:250}});let h=()=>{if(l){process.stdin.off(`keypress`,x);try{process.stdin.setRawMode(!1)}catch{}process.stdin.pause()}},g=()=>{h(),a?.stop(),s.killAll(),c?.()},_=0,v=null,y=e=>{let t=Date.now();_&&t-_<1e3||(_&&(g(),i(),process.exit(e===`SIGTERM`?143:130)),_=t,v=e,o(s.running?`\n${F.warn(I.idle)} ${F.warn(`Stopping:`)} letting running sessions wrap up and reporting them as interrupted. ${P(`Ctrl-C again to quit now.`)}`:`\n${F.warn(I.idle)} ${F.warn(`Stopping.`)}`),s.stop())};process.on(`SIGINT`,y),process.on(`SIGTERM`,y);let b=async e=>{if(!e)return;if(d)return o(P(` ${d} is still running; wait for it to finish`));o(`${F.accent(`›`)} ${e}`);let t=Ce(e);if(t.kind===`help`){o(P(` Commands you can type here (each is bitfolk <command>):`));for(let e of Wn(be.map(([e,t])=>[e,P(t)]),4))o(e)}else{if(t.kind===`quit`)return y(`SIGINT`);if(t.kind===`error`)return o(` ${Jn(t.message)}`);if(t.kind===`run`){d=e,a?.redraw();try{await Te(t.args,o,{columns:Math.max(40,(process.stdout.columns||80)-2),colorDepth:j.depth})}finally{d=null,a?.redraw()}}}};function x(e,t){let n=we(u,e,t??{});u=n.state,n.action===`interrupt`||n.action===`eof`?y(`SIGINT`):n.action===`submit`&&b(n.line??``),a?.redraw()}l&&(m(process.stdin),process.stdin.setRawMode(!0),process.stdin.on(`keypress`,x),process.stdin.resume()),process.on(`SIGHUP`,()=>{g(),i(),process.exit(129)}),process.on(`exit`,g);try{let e=await s.run({once:t.once});if(a.stop(),t.once&&e.length){let t=e.reduce((e,t)=>e+t.durationMs,0);console.log(`${F.ok(I.ok)} ${N(`${e.length} run${e.length===1?``:`s`}`)}${P(`, ${Oa(t)} in all.`)}`)}}finally{h(),a.stop(),c?.(),i(),v&&(process.exitCode=v===`SIGINT`?130:143)}}async function nl(e,t){let n=e.join(` `).trim();if(!n&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);n=Buffer.concat(e).toString(`utf8`).trim()}if(n.length<3)throw new Q(`describe the bug: ${w} bug "what you did and what happened"`);let r=await G(`Sending your report`,()=>fetch(new URL(`/api/bugs`,jc(t)),{method:`POST`,headers:{"content-type":`application/json`,"user-agent":`bitfolk-cli/${Rt}`},body:JSON.stringify({platform:`cli`,body:n.slice(0,5e3),email:t.email,app_version:`bitfolk-cli ${Rt}`,device:`${process.platform} ${process.arch}, node ${process.version}`})})),i=await r.json().catch(()=>({}));if(!r.ok)throw Error(i.error??`report failed (${r.status})`);console.log(U(`Thanks. The bug is on our list, and we read every report.`))}const rl=e=>w===`bitfolk`?e:e.replace(/(?<!npx )\bbitfolk (?=[a-z<-])/g,`${w} `);function il(){let e=k(),t=e.machine;return{isAgent:t=>e.agents.some(e=>e.slug===t.toLowerCase()||e.name.toLowerCase()===t.toLowerCase()),isTool:e=>Rr.some(t=>t.id===e.replace(/-/g,`_`))||!!t?.customTools?.some(t=>t.name===e)||!!t?.runtimes.includes(Kr(e)),envToken:process.env.BITFOLK_TOKEN}}async function al(e){let{values:t,positionals:n}=f({args:e,options:Tc,allowPositionals:!0,strict:!0}),r=t;r[`no-color`]&&bn({depth:0,fancy:!1,links:!1});let i=As(n,r,il());switch(i.kind){case`version`:return console.log(Rt);case`help`:{let e={version:Rt,defaults:Gt,api:zt};if(!i.topic)return console.log(rl(Bo({...e,rows:process.stdout.isTTY?process.stdout.rows:void 0})));let t=Vo(ws(i.topic),e);if(!t)throw new Q(`no help for "${i.topic}". Try ${w} --help`);return console.log(rl(t))}case`status`:return Zc();case`login`:return Fc(r);case`logout`:return Kc();case`up`:if(r.service!==void 0){if(!k().machine&&r.service===`on`)throw new Q(`link this computer first: ${w} login`);return No(r.service)}return tl(i.agent,r);case`start`:return io(k().machine,i.words,r,{upRunning:!!Ba(),runHere:()=>tl(void 0,{...r,once:!0},{sessionsOnly:!0})});case`sessions`:return oo(k().machine);case`logs`:return so(k().machine,i.session,r);case`cancel`:return co(k().machine,i.session);case`goals`:return lo(k().machine);case`chat`:return ec(k().machine,i.chat,i.words,r);case`board`:return tc(k().machine,i.goal,r);case`agents`:return nc(k().machine,r);case`approvals`:return rc(k().machine,r);case`decide`:return ic(k().machine,i.decision,i.request,r);case`tools`:return Rc();case`repos`:return Uc(i.action,i.arg,r);case`tool`:return Wc(i.action,i.name,r);case`agent-add`:return Mc(i.token,r);case`agent-rm`:return Yc(i.key,r);case`set-machine`:{let{primary:e,...t}=r,n=Object.keys(t).filter(e=>![`no-color`,`help`,`version`,`agent`,`tool`,`force`].includes(e));e!==void 0&&await Vc(e),(n.length||e===void 0)&&Jc(void 0,t),r.repo!==void 0&&k().machine&&await Hc(k().machine);return}case`set-agent`:return Jc(i.key,r);case`share`:{let e=k().machine;if(!e)throw new Q(`link this computer first: ${w} login`);let t=Ec(i.port,`port`,1,65535);if(!t||!Number.isInteger(t))throw new Q(`${w} share <port> [--name "Deal radar"] [--run "<command>"] [--keep <hours>] [--personal | --signed-in | --public]`);let n=Ec(r.keep,`keep`,1,72);if(r.approval&&!r.public&&!r[`signed-in`])throw new Q(`--approval goes with --public or --signed-in`);if([r.personal,r[`signed-in`],r.public].filter(Boolean).length>1)throw new Q(`pick one: --personal (only you), --signed-in (anyone with a Bitfolk account) or --public (anyone with the link)`);return wc(e,t,{name:r.name,public:r.public,personal:r.personal,signedIn:r[`signed-in`],run:r.run,keep:n,approval:r.approval})}case`share-stop`:{let e=Ec(i.port,`port`,1,65535);if(!e||!Number.isInteger(e))throw new Q(`${w} share stop <port>`);return Sc(e)}case`check`:return Qc();case`bug`:return nl(i.words,r);case`usage`:throw new Q(rl(i.message));case`unknown`:{let e=Ds(i.command);throw new Q(e?`unknown command "${i.command}". Did you mean ${w} ${e}?`:`unknown command "${i.command}". Try ${w} --help`)}}}const ol=(e,t)=>{console.error(Zn(W(Yn(e,`bitfolk: `)))),process.exit(t)};al(process.argv.slice(2)).catch(e=>{let t=e.code;if(t===`ERR_PARSE_ARGS_UNKNOWN_OPTION`){let t=/'([^']+)'/.exec(e.message)?.[1]??`that option`;ol(`unknown option ${t}. Try ${w} --help`,2)}(t===`ERR_PARSE_ARGS_INVALID_OPTION_VALUE`||t===`ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL`)&&ol(`${e.message.split(`.`)[0]}. Try ${w} --help`,2),e instanceof Q&&ol(e.message,2),e instanceof Bt&&ol(e.status===401?`that token was rejected (revoked, or the agent was archived)`:e.message,1),ol(e.message,1)});export{};
157
+ `),console.log(G(`${F(L.idle)} Not linked yet. Run ${U(`${w} login`)} to link this computer to your workspace, then ${U(`${w} up`)}.`)),r(sl(void 0,!1,[]))}let i=t?qr().filter(e=>e.supported&&!t.runtimes.includes(e.id)).map(e=>e.id.replace(/_/g,`-`)):[],a=[];if(t){let e;try{let r=await K(`Asking your workspace`,()=>Promise.race([new Wt(t.api,()=>Nr(t)).me(),new Promise((e,t)=>setTimeout(()=>t(Error(`no answer`)),8e3).unref())]));Object.assign(t,an(t,r)),e=r.queued?I.accent(`${r.queued} waiting`)+(n?``:F(` · run ${w} up to take them`)):F(`none waiting`)}catch(t){e=t instanceof q&&t.ended?I.err(`sign-in ended; run ${w} login`):t instanceof O&&t.status===401?I.err(`unlinked; run ${w} login`):I.warn(`couldn't reach your workspace (${w} check)`)}console.log(G(`${P(I.accent(t.name))} ${F(`on`)} ${P(t.workspace??`your workspace`)}`)),a.push([`tools`,Zo(t.runtimes)+(i.length?F(` ${z(`off: ${i.join(`, `)}`)}`):``)]),a.push([`sessions`,e]),a.push([`up`,n?`${I.ok(L.dot)} ${I.ok(`running`)} ${F(`(pid ${n})`)}`:`${F(L.idle)} ${F(`not running`)}`]),a.push([`limits`,`${I.money(`$${t.maxUsdPerRun}`)}${F(`/session · `)}${t.maxRunsPerHour}${F(`/h · `)}${t.timeoutMin}${F(` min · `)}${t.permission}`]);let r=X(t);a.push([`repos`,r.length?r.map((e,t)=>t===0?`${e.name} ${F(`(default)`)}`:e.name).join(F(`, `))+(t.pullRequests?F(` · opens pull requests`):``):F(`none: builders work in plain folders`)]),t.primary&&a.push([`primary`,`${J(t.primary)} ${F(`while it has usage left`)}`]),console.log(Kn(a,2).join(`
158
+ `))}else console.log(G(`${F(L.idle)} This computer isn't linked. ${F(`Agents added here still run with`)} ${U(`${w} up`)}${F(`.`)}`));e.agents.length&&(console.log(`\n${P(I.accent(`Agents added here`))}${F(`:`)}`),console.log(ns(e.agents.map(zc),2).flat().join(`
159
+ `))),r(sl(t,!!n,i))}async function ll(){let e=A(),t=0,n=0,r=null,i=``,a=e=>{r?.stop(),r=null,console.log(G(i+e,i.length+2))},o=(e,r)=>{e?t++:n++,a(e?`${I.ok(L.ok)} ${r}`:`${I.err(L.fail)} ${I.err(r)}`)},s=e=>a(`${F(L.skip)} ${F(e)}`),c=e=>{r?.stop(),r=null,i=``,console.log(`\n${P(e)}`),i=` `},l=e=>{r&&r.stop(),r=pr(e.replace(/\.\.\.$/,``),{quiet:!0})};console.log(G(`${P(I.accent(`bitfolk check`))} ${F(`· v${Rt} · node ${process.version}`)}`)),console.log(G(F(`config ${Zt()}`))),o(!!Ur(`git`),`git ${Ur(`git`)?`found`:`not found (needed for repos and worktrees)`}`);let u=qr(),d=[];for(let e of Br.filter(e=>e.supported)){let t=u.find(t=>t.id===e.id);t?o(!0,`${I.tool(e.label)} found ${F(`(${t.path})`)}`):d.push(e.label)}d.length&&s(`not found: ${d.join(`, `)}`),(process.env.HTTPS_PROXY||process.env.https_proxy||process.env.HTTP_PROXY)&&!process.env.NODE_USE_ENV_PROXY&&s(`HTTPS_PROXY is set, but Node ignores it unless NODE_USE_ENV_PROXY=1 (Node 22.21+). Set it if bitfolk can't connect.`);let f=e.machine?.api??process.env.BITFOLK_API;f&&f.replace(/\/+$/,``)!==`https://bitfolk.ai`&&s(`talking to ${f}, not ${zt}`);let p=e.machine;if(!p)s(`this computer isn't linked (${w} login)`);else{c(p.name),l(`checking ${p.name}'s link to your workspace...`);try{let e=await new Wt(p.api,()=>Nr(p)).me();an(p,e),o(!0,`linked to ${P(e.workspace?.name??`your workspace`)}, ${e.queued} session${e.queued===1?``:`s`} waiting`)}catch(e){o(!1,e instanceof q&&e.ended?`sign-in ended; run ${w} login`:e instanceof O&&e.status===401?`unlinked; run ${w} login`:e.message)}for(let e of p.runtimes){let t;try{t=La({...p,command:void 0},e).acp}catch{}if(e.startsWith(`custom:`)){let n=p.customTools?.find(t=>Jr(t.name)===e),r=t?.bin??n?.command.trim().split(/\s+/)[0]??``;o(!!n&&!!Ur(r),`${I.tool(J(e))} sessions run \`${n?.command??`(not set up here)`}\`${t?` over ACP`:``}`)}else{let t=Br.find(t=>t.id===e),n=t?Wr(t):null;if(o(!!n,`${I.tool(J(e))} sessions${n?F(` (${n}${t?.acp?`, via ACP`:``})`):` need it installed`}`),!n)continue}let n=t&&!p.command?Ur(t.bin):null;t&&n&&(l(`asking ${J(e)} to say hello over ACP...`),await ul(J(e),{...t,bin:n},o))}p.repo&&o(!!Ki(p.repo),`repo ${p.repo}`),process.platform===`darwin`&&s(`${w} up keeps this Mac awake, but closing the lid on battery still sleeps it and pauses sessions.`)}for(let t of e.agents){c(t.name),l(`checking ${t.name}...`);try{let e=await new Ut(t.api,t.oauth?()=>Nr(t):t.token).setup();o(!0,`${t.oauth?`signed in`:`token works`} (${e.goals.length} goal${e.goals.length===1?``:`s`})`)}catch(e){o(!1,e instanceof q&&e.ended?`sign-in ended; add it again with ${w} add <token from its page>`:e instanceof O&&e.status===401?`token rejected`:e.message)}let e=Xe[t.runtime].bin(t);o(Lc(e),`runtime ${I.tool(t.runtime)} ${F(`(${e||`no command`})`)}`),t.repo&&o(!!Ki(t.repo),`repo ${t.repo}`)}r?.stop(),i=``;let m=`${t} check${t===1?``:`s`} passed`;console.log(n?`\n${I.err(L.fail)} ${I.err(P(`${n} problem${n===1?``:`s`}`))}${F(`, ${m}`)}`:`\n${I.ok(L.ok)} ${I.ok(P(`All good`))}${F(`: ${m}`)}`),n&&(process.exitCode=1)}async function ul(e,t,n){try{let r=await Lt(t,{timeoutMs:5e3,version:Rt}),i=[r.agentInfo?.name,r.agentInfo?.version].filter(Boolean).join(` `)||`an unnamed agent`;if(r.protocolVersion!==1)return n(!1,`${e} speaks ACP v${String(r.protocolVersion)}; this runner speaks v1`);let a=r.authMethods.map(e=>e.description??e.name??e.id).filter(Boolean);n(!0,`${I.tool(e)} answers over ACP v1 ${F(`(${i})${a.length?`; sign-in: ${a.join(`; `)}`:``}`)}`)}catch(t){n(!1,`${e} didn't answer ACP initialize: ${t.message}`)}}const dl=(e,t,n)=>e?`on`:process.platform===`darwin`&&n.machine&&t[`let-sleep`]?`off`:void 0;async function fl(e,t,n={}){let r=A();if(n.sessionsOnly&&(r.agents=[]),e){let t=rn(r,e);if(!t)throw new Q(`no agent called ${e}. See ${w} status`);r.agents=[t]}let i=Ka(),a=null,o=e=>a?a.log(e):console.log(e),s=new Va(r,{out:o,liveFooter:nr()&&!!process.stdout.isTTY}),c=zo({platform:process.platform,linked:!!r.machine,letSleep:t[`let-sleep`]})?Bo():null;if(r.machine){let e=r.machine,t=await Promise.race([new Wt(e.api,()=>Nr(e)).me().catch(()=>null),new Promise(e=>setTimeout(()=>e(null),3e3).unref())]);t&&(r.machine=an(e,t))}(r.machine||r.agents.length)&&(await Hi(os({version:Rt,machine:r.machine,agents:r.agents,maxConcurrent:r.maxConcurrent,awake:dl(c,t,r)}),void 0,void 0,void 0,()=>{c?.(),i()}),console.log(``));let l=nr()&&!!process.stdout.isTTY&&!!process.stdin.isTTY&&!n.sessionsOnly&&!t.once,u=T(),d=null,f=e=>{if(d)return`${I.accent(L.dot)} ${F(`running ${d}…`)}`;if(!u.text)return`${I.accent(`›`)} ${F(`type a command, or help`)}`;let t=u.text[u.cursor]??` `,n=`${u.text.slice(0,u.cursor)}\x1b[7m${t}\x1b[27m${u.text.slice(u.cursor+1)}`;return V(`${I.accent(`›`)} ${n}`,Math.max(10,e-1))},p={machine:r.machine,agents:r.agents,maxConcurrent:r.maxConcurrent,awake:dl(c,t,r),version:Rt,typing:l};a=hr((e,t)=>{let n=fs(s,p,{frame:e,...t});return l?[...Array.isArray(n)?n:[n],f(t.columns)]:n},{intervalMs:()=>{let e=s.status();return e.running||e.stopping||e.checking?100:250}});let h=()=>{if(l){process.stdin.off(`keypress`,b);try{process.stdin.setRawMode(!1)}catch{}process.stdin.pause()}},g=()=>{h(),a?.stop(),s.killAll(),c?.()},_=0,v=null,y=e=>{let t=Date.now();_&&t-_<1e3||(_&&(g(),i(),process.exit(e===`SIGTERM`?143:130)),_=t,v=e,o(s.running?`\n${I.warn(L.idle)} ${I.warn(`Stopping:`)} letting running sessions wrap up and reporting them as interrupted. ${F(`Ctrl-C again to quit now.`)}`:`\n${I.warn(L.idle)} ${I.warn(`Stopping.`)}`),s.stop())};process.on(`SIGINT`,y),process.on(`SIGTERM`,y);let ee=async e=>{if(!e)return;if(d)return o(F(` ${d} is still running; wait for it to finish`));o(`${I.accent(`›`)} ${e}`);let t=Ce(e);if(t.kind===`help`){o(F(` Commands you can type here (each is bitfolk <command>):`));for(let e of Kn(be.map(([e,t])=>[e,F(t)]),4))o(e)}else{if(t.kind===`quit`)return y(`SIGINT`);if(t.kind===`error`)return o(` ${Xn(t.message)}`);if(t.kind===`run`){d=e,a?.redraw();try{await Te(t.args,o,{columns:Math.max(40,(process.stdout.columns||80)-2),colorDepth:M.depth})}finally{d=null,a?.redraw()}}}};function b(e,t){let n=we(u,e,t??{});u=n.state,n.action===`interrupt`||n.action===`eof`?y(`SIGINT`):n.action===`submit`&&ee(n.line??``),a?.redraw()}l&&(m(process.stdin),process.stdin.setRawMode(!0),process.stdin.on(`keypress`,b),process.stdin.resume()),process.on(`SIGHUP`,()=>{g(),i(),process.exit(129)}),process.on(`exit`,g);try{let e=await s.run({once:t.once});if(a.stop(),t.once&&e.length){let t=e.reduce((e,t)=>e+t.durationMs,0);console.log(`${I.ok(L.ok)} ${P(`${e.length} run${e.length===1?``:`s`}`)}${F(`, ${Na(t)} in all.`)}`)}}finally{h(),a.stop(),c?.(),i(),v&&(process.exitCode=v===`SIGINT`?130:143)}}async function pl(e,t){let n=e.join(` `).trim();if(!n&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);n=Buffer.concat(e).toString(`utf8`).trim()}if(n.length<3)throw new Q(`describe the bug: ${w} bug "what you did and what happened"`);let r=await K(`Sending your report`,()=>fetch(new URL(`/api/bugs`,Vc(t)),{method:`POST`,headers:{"content-type":`application/json`,"user-agent":`bitfolk-cli/${Rt}`},body:JSON.stringify({platform:`cli`,body:n.slice(0,5e3),email:t.email,app_version:`bitfolk-cli ${Rt}`,device:`${process.platform} ${process.arch}, node ${process.version}`})})),i=await r.json().catch(()=>({}));if(!r.ok)throw Error(i.error??`report failed (${r.status})`);console.log(W(`Thanks. The bug is on our list, and we read every report.`))}const ml=e=>w===`bitfolk`?e:e.replace(/(?<!npx )\bbitfolk (?=[a-z<-])/g,`${w} `);function hl(){let e=A(),t=e.machine;return{isAgent:t=>e.agents.some(e=>e.slug===t.toLowerCase()||e.name.toLowerCase()===t.toLowerCase()),isTool:e=>Br.some(t=>t.id===e.replace(/-/g,`_`))||!!t?.customTools?.some(t=>t.name===e)||!!t?.runtimes.includes(Jr(e)),envToken:process.env.BITFOLK_TOKEN}}async function gl(e){let{values:t,positionals:n}=f({args:e,options:Fc,allowPositionals:!0,strict:!0}),r=t;r[`no-color`]&&Sn({depth:0,fancy:!1,links:!1});let i=Is(n,r,hl());switch(i.kind){case`version`:return console.log(Rt);case`help`:{let e={version:Rt,defaults:qt,api:zt};if(!i.topic)return console.log(ml(Go({...e,rows:process.stdout.isTTY?process.stdout.rows:void 0})));let t=Ko(As(i.topic),e);if(!t)throw new Q(`no help for "${i.topic}". Try ${w} --help`);return console.log(ml(t))}case`status`:return cl();case`login`:return Gc(r);case`logout`:return rl();case`up`:if(r.service!==void 0){if(!A().machine&&r.service===`on`)throw new Q(`link this computer first: ${w} login`);return Ro(r.service)}return i.agent||A().machine||A().agents.length!==0||r.once||(console.log(`${P(`This computer isn't linked yet.`)} ${F(`Opening your browser to link it; sessions start once you press Allow.`)}\n`),await Gc(r,`up`)),fl(i.agent,r);case`start`:return lo(A().machine,i.words,r,{upRunning:!!Ga(),runHere:()=>fl(void 0,{...r,once:!0},{sessionsOnly:!0})});case`sessions`:return fo(A().machine);case`logs`:return po(A().machine,i.session,r);case`cancel`:return mo(A().machine,i.session);case`goals`:return ho(A().machine);case`chat`:return oc(A().machine,i.chat,i.words,r);case`board`:return sc(A().machine,i.goal,r);case`agents`:return cc(A().machine,r);case`approvals`:return lc(A().machine,r);case`decide`:return uc(A().machine,i.decision,i.request,r);case`tools`:return Yc();case`repos`:return el(i.action,i.arg,r);case`tool`:return tl(i.action,i.name,r);case`agent-add`:return Hc(i.token,r);case`agent-rm`:return ol(i.key,r);case`set-machine`:{let{primary:e,...t}=r,n=Object.keys(t).filter(e=>![`no-color`,`help`,`version`,`agent`,`tool`,`force`].includes(e));e!==void 0&&await Qc(e),(n.length||e===void 0)&&al(void 0,t),r.repo!==void 0&&A().machine&&await $c(A().machine);return}case`set-agent`:return al(i.key,r);case`share`:{let e=A().machine;if(!e)throw new Q(`link this computer first: ${w} login`);let t=Ic(i.port,`port`,1,65535);if(!t||!Number.isInteger(t))throw new Q(`${w} share <port> [--name "Deal radar"] [--run "<command>"] [--keep <hours>] [--personal | --signed-in | --public]`);let n=Ic(r.keep,`keep`,1,72);if(r.approval&&!r.public&&!r[`signed-in`])throw new Q(`--approval goes with --public or --signed-in`);if([r.personal,r[`signed-in`],r.public].filter(Boolean).length>1)throw new Q(`pick one: --personal (only you), --signed-in (anyone with a Bitfolk account) or --public (anyone with the link)`);return Pc(e,t,{name:r.name,public:r.public,personal:r.personal,signedIn:r[`signed-in`],run:r.run,keep:n,approval:r.approval})}case`share-stop`:{let e=Ic(i.port,`port`,1,65535);if(!e||!Number.isInteger(e))throw new Q(`${w} share stop <port>`);return Mc(e)}case`check`:return ll();case`bug`:return pl(i.words,r);case`usage`:throw new Q(ml(i.message));case`unknown`:{let e=Ns(i.command);throw new Q(e?`unknown command "${i.command}". Did you mean ${w} ${e}?`:`unknown command "${i.command}". Try ${w} --help`)}}}const _l=(e,t)=>{console.error($n(G(Zn(e,`bitfolk: `)))),process.exit(t)};gl(process.argv.slice(2)).catch(e=>{let t=e.code;if(t===`ERR_PARSE_ARGS_UNKNOWN_OPTION`){let t=/'([^']+)'/.exec(e.message)?.[1]??`that option`;_l(`unknown option ${t}. Try ${w} --help`,2)}(t===`ERR_PARSE_ARGS_INVALID_OPTION_VALUE`||t===`ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL`)&&_l(`${e.message.split(`.`)[0]}. Try ${w} --help`,2),e instanceof Q&&_l(e.message,2),e instanceof O&&_l(e.status===401?`that token was rejected (revoked, or the agent was archived)`:e.message,1),_l(e.message,1)});export{};