bitfolk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -180,7 +180,7 @@ stops if the agent's worktree has uncommitted changes unless you add `--force`.
|
|
|
180
180
|
| `--max-usd` | 1 | Hard spend cap per run (Claude Code's `--max-budget-usd`); approximate for ACP tools |
|
|
181
181
|
| `--max-runs` | 6 | Most runs per rolling hour |
|
|
182
182
|
| `--timeout` | 45 | Minutes before a run is stopped |
|
|
183
|
-
| `--permission` |
|
|
183
|
+
| `--permission` | auto | `auto`: the runtime's auto mode. `safe`: edits in its worktree, `bitfolk-api`, read-mostly git, no curl. `bypass`: no prompts (only on a machine you'd hand over) |
|
|
184
184
|
|
|
185
185
|
Bitfolk's own approval rules (`POST /v1/actions`) apply on top, wherever the agent runs.
|
|
186
186
|
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Bitfolk CLI. Copyright (c) 2026 NQB8. All rights reserved. Use is subject to the LICENSE file in this package.
|
|
2
2
|
import{createRequire as e}from"node:module";import{execFileSync as t,spawn as n}from"node:child_process";import{basename as r,delimiter as i,dirname as a,isAbsolute as o,join as s,relative as c,resolve as l,sep as u}from"node:path";import{parseArgs as d}from"node:util";import{accessSync as f,appendFileSync as p,chmodSync as m,constants as h,copyFileSync as g,existsSync as _,lstatSync as v,mkdirSync as y,mkdtempSync as b,readFileSync as x,readdirSync as ee,realpathSync as te,renameSync as ne,rmSync as re,statSync as ie,writeFileSync as ae}from"node:fs";import{homedir as oe,hostname as se,tmpdir as ce}from"node:os";import{createInterface as le}from"node:readline";import{createHash as ue,randomBytes as de,randomUUID as fe}from"node:crypto";import{createServer as pe}from"node:http";import{connect as S}from"node:net";const C=/[\\/]_npx[\\/]/.test(process.argv[1]??``)?`npx bitfolk`:`bitfolk`,me=C!==`bitfolk`;function he(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 ge=()=>({sessionId:null,inputTokens:0,outputTokens:0,costMicros:null,isError:!1,overBudget:!1,summary:null,error:null,model:null}),w=`[redacted]`,_e=[[/\bbf[a-z]{0,2}_[A-Za-z0-9]{8,}/g,w],[/\bsk-[A-Za-z0-9_-]{8,}/g,w],[/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{8,}/g,w],[/\bgh[pousr]_[A-Za-z0-9]{8,}/g,w],[/\bgithub_pat_[A-Za-z0-9_]{20,}/g,w],[/\bxox[a-z]-[A-Za-z0-9-]{8,}/g,w],[/\beyJ[\w-]{10,}\.[\w-]{10,}\.[\w-]+/g,w],[/\bAKIA[0-9A-Z]{16}\b/g,w],[/\bsb_(?:secret|publishable)_[A-Za-z0-9_-]{8,}/g,w],[/\bAIza[0-9A-Za-z_-]{30,}/g,w],[/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*/g,w],[/\b(bearer|basic)(\s+)[A-Za-z0-9._~+/=-]{8,}/gi,`$1$2${w}`],[/\b([A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PWD|PASS|AUTH|CREDENTIALS?)[A-Z0-9_]*)(\s*[=:]\s*)("[^"]*"|'[^']*'|\S+)/g,`$1$2${w}`],[/(--?(?:password|passwd|token|secret|api-?key|auth)(?:=|\s+))("[^"]*"|'[^']*'|\S+)/gi,`$1${w}`],[/(\bmysql\b.*?\s-p)(\S+)/g,`$1${w}`],[/(\b[a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:)[^\s@/]+@/gi,`$1${w}@`]];function T(e){let t=e;for(let[e,n]of _e)t=t.replace(e,n);return t}function E(e){if(typeof e!=`string`)return null;let t=e.split(`
|
|
3
|
-
`).map(e=>e.trim()).find(Boolean);if(!t)return null;let n=T(t.replace(/\s+/g,` `));return n.length>200?n.slice(0,199)+`…`:n}function D(e,t){if(typeof e!=`string`||!e)return`a file`;if(t&&o(e)){let n=c(t,e);if(n&&!n.startsWith(`..`)&&!o(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 T((n?n[2]:t).trim().replace(/\s+/g,` `)).slice(0,80)}function ye(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 ${D(i,n)}`:r===`read`?`Reading ${D(i,n)}`:r===`bash`?`Running ${ve(t.command)}`:r===`grep`||r===`glob`?`Searching ${T(String(t.pattern??``)).slice(0,80)}`.trim():`Using ${String(e??`a tool`)}`}const be=[`Bash(bitfolk-api:*)`,`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 O(e){let t=e.trim();if(!t.startsWith(`{`))return null;try{return JSON.parse(t)}catch{return null}}const k=(e,t=280)=>typeof e==`string`&&e.trim()?e.trim().replace(/\s+/g,` `).slice(0,t):null,A=e=>k(typeof e==`string`?e.trim().split(`
|
|
3
|
+
`).map(e=>e.trim()).find(Boolean);if(!t)return null;let n=T(t.replace(/\s+/g,` `));return n.length>200?n.slice(0,199)+`…`:n}function D(e,t){if(typeof e!=`string`||!e)return`a file`;if(t&&o(e)){let n=c(t,e);if(n&&!n.startsWith(`..`)&&!o(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 T((n?n[2]:t).trim().replace(/\s+/g,` `)).slice(0,80)}function ye(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 ${D(i,n)}`:r===`read`?`Reading ${D(i,n)}`:r===`bash`?`Running ${ve(t.command)}`:r===`grep`||r===`glob`?`Searching ${T(String(t.pattern??``)).slice(0,80)}`.trim():`Using ${String(e??`a tool`)}`}const be=[`Bash(bitfolk-api:*)`,`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 O(e){let t=e.trim();if(!t.startsWith(`{`))return null;try{return JSON.parse(t)}catch{return null}}const k=(e,t=280)=>typeof e==`string`&&e.trim()?e.trim().replace(/\s+/g,` `).slice(0,t):null,A=e=>k(typeof e==`string`?e.trim().split(`
|
|
4
4
|
`).filter(Boolean).at(-1):null);function xe(e){return e===`bypass`?[`--permission-mode`,`bypassPermissions`]:e===`auto`?[`--permission-mode`,`auto`]:[`--permission-mode`,`acceptEdits`,`--allowedTools`,...be]}const Se={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]:[],...xe(e.permission)],stdin:t}},parse(e,t){let n=O(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);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=he(n.result)??(typeof n.subtype==`string`?n.subtype:null)),t.overBudget=typeof n.subtype==`string`&&n.subtype.includes(`budget`),t.summary=A(n.result)??t.summary}},activity(e,t){let n=O(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 E(i?ye(i.name,i.input??{},t):r.find(e=>e?.type===`text`)?.text)}};function Ce(e){return e===`bypass`?[`--dangerously-bypass-approvals-and-sandbox`]:[`-c`,`sandbox_mode="workspace-write"`,`-c`,`sandbox_workspace_write.network_access=true`]}const we={claude_code:Se,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`,...Ce(e.permission),...e.model?[`-m`,e.model]:[],`-`],stdin:t}},parse(e,t){let n=O(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=he(n.error??n.message)??t.error),n.type===`item.completed`&&n.item?.type===`agent_message`&&(t.summary=A(n.item.text)??t.summary))},activity(e,t){let n=O(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`?E(`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=>D(e?.path,t));return e.length?E(`Editing ${e[0]}${e.length>1?` and ${e.length-1} more`:``}`):null}return r.type===`agent_message`?E(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=O(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=A(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=he(n.error?.data?.message??n.error?.message??n.error)??t.error)},activity(e,t){let n=O(e),r=n?.part??{};return n?.type===`tool_use`&&r.tool?E(ye(r.tool,r.state?.input??{},t)):n?.type===`text`?E(r.text):null}},hermes:{runtime:`hermes`,bin:()=>`hermes`,resumes:!1,launch(e,t){let n=s(ce(),`bitfolk-hermes-${fe()}.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=k(e)??t.summary},activity:e=>E(e),afterExit(e,t){if(e.usageFile)try{let n=JSON.parse(x(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{re(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=O(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=k(n.summary))):t.summary=k(e)??t.summary},activity(e){return E(O(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 Te(e){return e===`claude_code`||e===`codex`||e===`opencode`||e===`hermes`?e:null}const Ee=2e4;var De=class extends Error{code;data;constructor(e,t,n){super(t),this.code=e,this.data=n}};const Oe=e=>new De(-32601,`${e} isn't supported by this client`);var ke=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})`))),le({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})+`
|
|
5
|
-
`),!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: ${T(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 De(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 De?t:new De(-32603,t.message);this.#a({id:e,error:{code:n.code,message:n.message}})}}};const Ae=/[$`\\\n\r]/,je=/[;&|<>(){}[\]*?~]/,Me=/[$`;&|<>\\*?~\n\r(){}[\]]/;function Ne(e){if(typeof e!=`string`||Ae.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(je.test(a))return null;else n+=a,r=!0;return i?null:(r&&t.push(n),t)}function Pe(e){let t=Ne(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 Fe(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 Ie=e=>/^(?:\/(?:usr\/)?bin\/)?(?:ba|z|da)?sh$/.test(e);function Le(e){let t;if(typeof e==`string`)t=Ne(e);else{if(!e.every(e=>typeof e==`string`))return null;if(e.length===3&&Ie(e[0])&&/^-l?c$/.test(e[1]))return Ne(e[2]);t=e.some(e=>Me.test(e))?null:e.slice()}return!t||t.length===0?null:t.length===3&&Ie(t[0])&&/^-l?c$/.test(t[1])?Ne(t[2]):t}const Re=new Set([`status`,`diff`,`log`,`show`,`add`,`commit`,`switch`,`branch`]),ze=/^(?:-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 Be(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===`git`){if(!n||!Re.has(n))return`that git command isn't on the safe list`;for(let e of r){if(ze.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 and read-mostly git run in safe mode`}const Ve=new Set([`curl`,`wget`,`nc`,`ncat`,`netcat`,`ssh`,`scp`,`sftp`,`telnet`,`ftp`,`socat`,`rsync`,`http`,`https`,`xh`]),He=new Set([`env`,`printenv`]);function Ue(e,t){let n=(Array.isArray(e)?e.join(` `):e).replace(/['"\\]/g,``),r=[t,qe(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=oe(),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=qe(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=>Ve.has(e))?`it uses a network tool`:s.some(e=>He.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 We(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 Ge=/^(?: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 Ke(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(Ge.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 qe(e){try{return te(e)}catch{let t=a(e);return t===e?e:s(qe(t),r(e))}}const Je=(e,t)=>e===t||e.startsWith(t.endsWith(u)?t:t+u),Ye=new Set([`.claude`,`.opencode`,`.gemini`,`.cursor`,`.kilocode`,`.codex`,`.qwen`,`.cline`,`.kimi`]),Xe=new Set([`opencode.json`,`opencode.jsonc`]),Ze=new Set([`.husky`,`.githooks`,`.lefthook`,`.git-hooks`,`git-hooks`]),Qe=/^(?:\.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 $e(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(!o(e))return`a relative path`;if(e.split(/[\\/]/).includes(`..`))return`a path with ..`;let n=qe(t.cwd),r=qe(e);if(!Je(r,n))return Je(r,qe(t.home))?`a path in the Bitfolk folder`:`a path outside its worktree`;if(t.write){let e=c(n,r).split(u).filter(Boolean).map($e);if(e.includes(`.git`))return`git's own files`;if(e.some(e=>Ye.has(e)||e.startsWith(`.goose`)||Xe.has(e)))return`an agent settings file`;if(e.some(e=>Ze.has(e)||Qe.test(e)))return`a git hook setup`}return null}function tt(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=o(r)?r:s(e,r)}catch{return!1}try{return ee(n).some(e=>{if(e.endsWith(`.sample`))return!1;try{let t=ie(s(n,e));return t.isFile()&&!!(t.mode&73)}catch{return!1}})}catch{return!1}}function nt(e,t){if(typeof e!=`string`||!e)return`a file`;let n=D(e,t);if(n!==e)return n;let r=oe();return r&&r!==`/`&&(e===r||e.startsWith(r+u))?`~`+e.slice(r.length):e}function rt(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=Ke(e)[0]??e.locations?.find(e=>typeof e?.path==`string`)?.path,a=e=>i?`${e} ${nt(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=Fe(n);return E(`Running ${e?ve(e):r??`a command`}`)}case`edit`:return E(a(`Editing`));case`delete`:return E(a(`Deleting`));case`move`:return E(a(`Moving`));case`read`:return E(a(`Reading`));case`search`:return E(`Searching ${T(o(n.pattern)??o(n.query)??r??``).slice(0,80)}`.trim());case`fetch`:return E(`Fetching ${o(n.url)??r??`a web page`}`);case`think`:return null;case`switch_mode`:return E(`Switching mode${r?`: ${r}`:``}`);default:return E(r?`Using ${r}`:`Using a tool`)}}const it=new Set([`read`,`search`,`edit`,`delete`,`move`]),at=new Set([`edit`,`delete`,`move`]);function ot(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=rt(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=Ke(t);for(let e of l){let t=et(e,{cwd:r,home:i,write:at.has(c)});if(t)return s(!1,`${t}: ${nt(e,r)}`)}if(it.has(c))return l.length===0?s(!1,`no file path in the request`):s(!0,at.has(c)?`a change inside its worktree`:`inside its worktree`);if(c===`execute`){let a=Fe(t.rawInput);if(!a)return s(!1,`the command isn't in a shape the runner can check`);if(n===`safe`){let t=Le(a);if(!t)return s(!1,`the command uses shell features (safe mode allows a plain command only)`);let n=Be(t);return n?s(!1,n):t[0]===`git`&&(t[1]===`commit`||t[1]===`switch`)&&(e.gitHooks??tt(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=Ue(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 st={opencode:{safe:`build`,auto:`build`,bypass:`build`},gemini:{safe:`default`,auto:`default`,bypass:`yolo`},cursor_agent:{safe:`agent`,auto:`agent`,bypass:`agent`}};function ct(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 lt={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 ut=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 ke(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>Ee?`[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>Ee?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 De)&&/exited|stopped reading/.test(e.message)&&(n.exited=!0),this.#v({event:`turn`,error:n.error})}return e.tally.summary=A(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&<[e])??`the agent stopped (${e??`no reason given`})`}#b(e){if(this.#a===`policy`&&this.#o)return this.#o;if(e instanceof De){if(e.code===-32e3)return this.#x();let t=e.data;return he(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=st[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&&ct(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`&&!st[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(E(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}),Oe(e)}#T(e){if(this.#a)return{outcome:{outcome:`cancelled`}};let t=typeof e?.toolCall?.toolCallId==`string`?e.toolCall.toolCallId:null,n=We(t?this.#c.get(t):void 0,e?.toolCall);t&&this.#c.set(t,n);let r=ot({toolCall:n,options:e?.options??[],permission:this.#e.agent.permission,cwd:this.#e.cwd,home:this.#e.home});if(!r.allow&&n.kind===`execute`&&!Fe(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(E(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:T(r.reason),option:i}),this.#e.activity(E(`${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=We(t,n);if(e&&this.#c.set(e,r),n.sessionUpdate===`tool_call`||!t){let e=rt(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(E(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(E(`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 dt(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 ke(r.stdin,r.stdout,{request:e=>{throw Oe(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 j=e(import.meta.url)(`../package.json`).version,ft=`https://bitfolk.ai`;var M=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}},pt=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/${j}`,...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 M(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 M(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}))}},mt=class{#e;constructor(e,t){this.#e=new pt(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){return this.#e.request(`POST`,`/v1/machine/tools`,{runtimes: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}`)}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 M&&(e.status===404||e.status===405)?`not_found`:`error`}}}};const ht=[`claude_code`,`codex`,`opencode`,`hermes`,`command`],gt=[`safe`,`auto`,`bypass`],_t={maxUsdPerRun:1,maxRunsPerHour:6,timeoutMin:45,permission:`safe`};function N(){return process.env.BITFOLK_HOME||s(oe(),`.bitfolk`)}function vt(){let e=N();return _(e)||y(e,{recursive:!0,mode:448}),e}function yt(e,t){if(!_(e))return t;try{return JSON.parse(x(e,`utf8`))}catch{throw Error(`${e} is not valid JSON. Fix or delete it.`)}}function bt(e,t){vt();let n=`${e}.${process.pid}.tmp`;ae(n,JSON.stringify(t,null,2)+`
|
|
5
|
+
`),!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: ${T(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 De(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 De?t:new De(-32603,t.message);this.#a({id:e,error:{code:n.code,message:n.message}})}}};const Ae=/[$`\\\n\r]/,je=/[;&|<>(){}[\]*?~]/,Me=/[$`;&|<>\\*?~\n\r(){}[\]]/;function Ne(e){if(typeof e!=`string`||Ae.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(je.test(a))return null;else n+=a,r=!0;return i?null:(r&&t.push(n),t)}function Pe(e){let t=Ne(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 Fe(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 Ie=e=>/^(?:\/(?:usr\/)?bin\/)?(?:ba|z|da)?sh$/.test(e);function Le(e){let t;if(typeof e==`string`)t=Ne(e);else{if(!e.every(e=>typeof e==`string`))return null;if(e.length===3&&Ie(e[0])&&/^-l?c$/.test(e[1]))return Ne(e[2]);t=e.some(e=>Me.test(e))?null:e.slice()}return!t||t.length===0?null:t.length===3&&Ie(t[0])&&/^-l?c$/.test(t[1])?Ne(t[2]):t}const Re=new Set([`status`,`diff`,`log`,`show`,`add`,`commit`,`switch`,`branch`]),ze=/^(?:-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 Be(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||!Re.has(n))return`that git command isn't on the safe list`;for(let e of r){if(ze.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 Ve=new Set([`curl`,`wget`,`nc`,`ncat`,`netcat`,`ssh`,`scp`,`sftp`,`telnet`,`ftp`,`socat`,`rsync`,`http`,`https`,`xh`]),He=new Set([`env`,`printenv`]);function Ue(e,t){let n=(Array.isArray(e)?e.join(` `):e).replace(/['"\\]/g,``),r=[t,qe(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=oe(),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=qe(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=>Ve.has(e))?`it uses a network tool`:s.some(e=>He.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 We(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 Ge=/^(?: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 Ke(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(Ge.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 qe(e){try{return te(e)}catch{let t=a(e);return t===e?e:s(qe(t),r(e))}}const Je=(e,t)=>e===t||e.startsWith(t.endsWith(u)?t:t+u),Ye=new Set([`.claude`,`.opencode`,`.gemini`,`.cursor`,`.kilocode`,`.codex`,`.qwen`,`.cline`,`.kimi`]),Xe=new Set([`opencode.json`,`opencode.jsonc`]),Ze=new Set([`.husky`,`.githooks`,`.lefthook`,`.git-hooks`,`git-hooks`]),Qe=/^(?:\.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 $e(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(!o(e))return`a relative path`;if(e.split(/[\\/]/).includes(`..`))return`a path with ..`;let n=qe(t.cwd),r=qe(e);if(!Je(r,n))return Je(r,qe(t.home))?`a path in the Bitfolk folder`:`a path outside its worktree`;if(t.write){let e=c(n,r).split(u).filter(Boolean).map($e);if(e.includes(`.git`))return`git's own files`;if(e.some(e=>Ye.has(e)||e.startsWith(`.goose`)||Xe.has(e)))return`an agent settings file`;if(e.some(e=>Ze.has(e)||Qe.test(e)))return`a git hook setup`}return null}function tt(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=o(r)?r:s(e,r)}catch{return!1}try{return ee(n).some(e=>{if(e.endsWith(`.sample`))return!1;try{let t=ie(s(n,e));return t.isFile()&&!!(t.mode&73)}catch{return!1}})}catch{return!1}}function nt(e,t){if(typeof e!=`string`||!e)return`a file`;let n=D(e,t);if(n!==e)return n;let r=oe();return r&&r!==`/`&&(e===r||e.startsWith(r+u))?`~`+e.slice(r.length):e}function rt(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=Ke(e)[0]??e.locations?.find(e=>typeof e?.path==`string`)?.path,a=e=>i?`${e} ${nt(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=Fe(n);return E(`Running ${e?ve(e):r??`a command`}`)}case`edit`:return E(a(`Editing`));case`delete`:return E(a(`Deleting`));case`move`:return E(a(`Moving`));case`read`:return E(a(`Reading`));case`search`:return E(`Searching ${T(o(n.pattern)??o(n.query)??r??``).slice(0,80)}`.trim());case`fetch`:return E(`Fetching ${o(n.url)??r??`a web page`}`);case`think`:return null;case`switch_mode`:return E(`Switching mode${r?`: ${r}`:``}`);default:return E(r?`Using ${r}`:`Using a tool`)}}const it=new Set([`read`,`search`,`edit`,`delete`,`move`]),at=new Set([`edit`,`delete`,`move`]);function ot(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=rt(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=Ke(t);for(let e of l){let t=et(e,{cwd:r,home:i,write:at.has(c)});if(t)return s(!1,`${t}: ${nt(e,r)}`)}if(it.has(c))return l.length===0?s(!1,`no file path in the request`):s(!0,at.has(c)?`a change inside its worktree`:`inside its worktree`);if(c===`execute`){let a=Fe(t.rawInput);if(!a)return s(!1,`the command isn't in a shape the runner can check`);if(n===`safe`){let t=Le(a);if(!t)return s(!1,`the command uses shell features (safe mode allows a plain command only)`);let n=Be(t);return n?s(!1,n):t[0]===`git`&&(t[1]===`commit`||t[1]===`switch`)&&(e.gitHooks??tt(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=Ue(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 st={opencode:{safe:`build`,auto:`build`,bypass:`build`},gemini:{safe:`default`,auto:`default`,bypass:`yolo`},cursor_agent:{safe:`agent`,auto:`agent`,bypass:`agent`}};function ct(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 lt={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 ut=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 ke(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>Ee?`[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>Ee?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 De)&&/exited|stopped reading/.test(e.message)&&(n.exited=!0),this.#v({event:`turn`,error:n.error})}return e.tally.summary=A(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&<[e])??`the agent stopped (${e??`no reason given`})`}#b(e){if(this.#a===`policy`&&this.#o)return this.#o;if(e instanceof De){if(e.code===-32e3)return this.#x();let t=e.data;return he(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=st[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&&ct(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`&&!st[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(E(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}),Oe(e)}#T(e){if(this.#a)return{outcome:{outcome:`cancelled`}};let t=typeof e?.toolCall?.toolCallId==`string`?e.toolCall.toolCallId:null,n=We(t?this.#c.get(t):void 0,e?.toolCall);t&&this.#c.set(t,n);let r=ot({toolCall:n,options:e?.options??[],permission:this.#e.agent.permission,cwd:this.#e.cwd,home:this.#e.home});if(!r.allow&&n.kind===`execute`&&!Fe(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(E(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:T(r.reason),option:i}),this.#e.activity(E(`${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=We(t,n);if(e&&this.#c.set(e,r),n.sessionUpdate===`tool_call`||!t){let e=rt(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(E(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(E(`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 dt(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 ke(r.stdin,r.stdout,{request:e=>{throw Oe(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 j=e(import.meta.url)(`../package.json`).version,ft=`https://bitfolk.ai`;var M=class extends Error{status;code;constructor(e,t,n){super(n),this.status=e,this.code=t}},pt=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/${j}`,...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 M(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 M(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}))}},mt=class{#e;constructor(e,t){this.#e=new pt(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){return this.#e.request(`POST`,`/v1/machine/tools`,{runtimes: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}`)}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 M&&(e.status===404||e.status===405)?`not_found`:`error`}}}};const ht=[`claude_code`,`codex`,`opencode`,`hermes`,`command`],gt=[`safe`,`auto`,`bypass`],_t={maxUsdPerRun:1,maxRunsPerHour:6,timeoutMin:45,permission:`auto`};function N(){return process.env.BITFOLK_HOME||s(oe(),`.bitfolk`)}function vt(){let e=N();return _(e)||y(e,{recursive:!0,mode:448}),e}function yt(e,t){if(!_(e))return t;try{return JSON.parse(x(e,`utf8`))}catch{throw Error(`${e} is not valid JSON. Fix or delete it.`)}}function bt(e,t){vt();let n=`${e}.${process.pid}.tmp`;ae(n,JSON.stringify(t,null,2)+`
|
|
6
6
|
`,{mode:384}),ne(n,e),m(e,384)}const xt=()=>s(N(),`config.json`),St=()=>s(N(),`state.json`);function P(){let e=yt(xt(),{version:1,maxConcurrent:2,agents:[]});return e.agents=e.agents.map(e=>({..._t,...e})),e.machine&&={..._t,...e.machine},e}const F=e=>bt(xt(),e),Ct=()=>yt(St(),{agents:{}}),wt=e=>bt(St(),e);function Tt(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 Et(e,t){let n=t.toLowerCase();return e.agents.find(e=>e.slug===n||e.name.toLowerCase()===n||e.id.startsWith(n))}function Dt(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=P();return t.machine?.id===e.id?(t.machine={...t.machine,workspace:n,name:r},F(t),t.machine):e}catch{return{...e,workspace:n,name:r}}}const I={coral:`#f25c3b`,coralDark:`#c8432a`,grass:`#6fae4b`,grassDark:`#4c8a35`,gold:`#f2c14e`,sky:`#d7ecf7`,ink:`#0e0f11`},Ot={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`},kt=[`#.....#..#.....##.......#..#....`,`#........#....#.........#..#....`,`####..#.####.####..###..#..#..#.`,`#...#.#..#....#...#...#.#..#.#..`,`#...#.#..#....#...#...#.#..##...`,`#...#.#..#....#...#...#.#..#.#..`,`####..#...##..#....###...#.#..#.`],L={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...`]},At={claude_code:{palette:{A:`#3a302c`,B:`#5f3b2c`,C:`#503428`,D:`#48332a`,E:`#c8c8d0`,F:`#d3b196`,G:`#f8d0b0`,H:`#3a3640`,I:`#373337`,J:`#36363e`,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.`,`ACCEFFDGGGGGDFFEDA.`,`.ACEFGHHGGGHHGFEA..`,`.ACIHHJJHHHJJHHDA..`,`.ACCIHGGHGHGGHFDA..`,`.ADDDFGGGFGGGFDDA..`,`..ADDDFGKKKGFDDA...`,`.....ILILLLILI.IIII`,`...IILLMNONMLLIIPPI`,`..ILLMLNLOLNLMLIPPI`,`.IGGIMLLNONLLMIIIII`,`.IFGILLLLOLLLLIEEEE`,`..IIQQQQQRQQQQQII..`,`....ISSTI.ITSSI....`,`....IUUVI.IVUUI....`,`.....III...III.....`],walk:[[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEDDDDDDDA.`,`.IHHHGGFFEDDDDDDDA.`,`IGGJHHHHFDDDDDDDDA.`,`IGJGHGGFGDDDDDDDDA.`,`.IKKGGGFFDDDDDDDA..`,`..IIGGFFADDDDDDA...`,`..IIIIILLILLI......`,`..IPPILLMLLLI......`,`..IPPILMLLLLI......`,`..IIIIGFILLLI......`,`..EEEEFILLLLI......`,`......IQQQQQI......`,`.......ISSTI.......`,`......IUUUVI.......`,`.......IIII........`],[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEDDDDDDDA.`,`.IHHHGGFFEDDDDDDDA.`,`IGGJHHHHFDDDDDDDDA.`,`IGJGHGGFGDDDDDDDDA.`,`.IKKGGGFFDDDDDDDA..`,`..IIGGFFADDDDDDA...`,`..IIIIILLILLI......`,`..IPPILLMLLLI......`,`..IPPILMLLLLI......`,`..IIIIGFILLLI......`,`..EEEEFILLLLI......`,`......IQQQQQI......`,`.....ISTI.ISTI.....`,`....IUUVI.IUUVI....`,`.....III...III.....`],[`.......AAAAA.......`,`.....AABBBBBAA.....`,`...AABBBBBBCCCA....`,`..ABBBBBBCDCCDCA...`,`..ABBBBBDCCCCCCCA..`,`.ABBBBCCCCDCDCCCCA.`,`.ABBCCCBCCCDCCDDDA.`,`.ACCCCBCCCCCCDDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFEDDDDDDDA.`,`.IHHHGGFFEDDDDDDDA.`,`IGGJHHHHFDDDDDDDDA.`,`IGJGHGGFGDDDDDDDDA.`,`.IKKGGGFFDDDDDDDA..`,`..IIGGFFADDDDDDA...`,`..IIIIILLILLI......`,`..IPPILLMLLLI......`,`..IPPILMLLLLI......`,`..IIIIGFILLLI......`,`..EEEEFILLLLI......`,`......IQQQQQI......`,`......ISSTI........`,`......IUUUVI.......`,`.......IIII........`]]},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.GGG.`,`...GGLLMNONMLLGGPLG`,`..GLLMLNLOLNLMLGPLG`,`.GFFGMLNNONNLMGGPLG`,`.GEFGLLLLOLLLLGGGG.`,`..GGQQQQQRQQQQQGG..`,`....GSSTG.GTSSG....`,`....GUUVG.GVUUG....`,`.....GGG...GGG.....`],walk:[[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`..GGG.GLLGLLG......`,`..GPLGLLMLLLG......`,`..GPLGLMLLLLG......`,`..GPLGFEGLLLG......`,`..GGGGEGLLLLG......`,`......GQQQQQG......`,`.......GSSTG.......`,`......GUUUVG.......`,`.......GGGG........`],[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`..GGG.GLLGLLG......`,`..GPLGLLMLLLG......`,`..GPLGLMLLLLG......`,`..GPLGFEGLLLG......`,`..GGGGEGLLLLG......`,`......GQQQQQG......`,`.....GSTG.GSTG.....`,`....GUUVG.GUUVG....`,`.....GGG...GGG.....`],[`.....A.AAAAA.A.....`,`....ABABBBCBADA....`,`...ABBBBBBDDDDDA...`,`..ABBBBBDDDBDDDAA..`,`.ABBCBDDCDDDCDDDCA.`,`.ABBBDDDDDDDDDDCCA.`,`.ABDDBDDDBDDDCCCCA.`,`.ACCCCCCCDCCCCCCCA.`,`..ACFFCEECCCCCCAA..`,`.GHHHFFEECCCCAA....`,`GFIJHHHHEEFCA......`,`GFIIHFFEFEWA.......`,`.GFKFFFEEEG........`,`..GGFFEEGG.........`,`..GGG.GLLGLLG......`,`..GPLGLLMLLLG......`,`..GPLGLMLLLLG......`,`..GPLGFEGLLLG......`,`..GGGGEGLLLLG......`,`......GQQQQQG......`,`......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...`,`.ABBBBBCCCCBCCCCA..`,`.EEBBBDCDCCCCCCDEE.`,`ABEBCCCCCCCCCCDDEA.`,`ABCCCCCCCCCCCDDDDA.`,`ACBDDDDDDDDDDDDDDA.`,`ACCDCCCCCCCDDFDDDA.`,`.ACCDDDDGGGGGGFDA..`,`..ACFGHHGGGHHGFDA..`,`..ACFHGGHGHGGHFA...`,`...AIFGGGFGGGFI....`,`.....IFGGJGGFI.....`,`.....IKIKKKIKI.....`,`...IIKKLMMMLKKINNNN`,`..IKKLKMMKMMKLKNIIN`,`.IGGILKMMMMMKLINNNN`,`.IFGIKKLKKKLKKIGFI.`,`..IIOOOOOPOOOOOII..`,`....IQQRI.IRQQI....`,`....ISSTI.ITSSI....`,`.....III...III.....`],walk:[[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA..`,`.ABBBBCCCCDCDCCCEE.`,`.ABBCCCCCCCDCCDCEA.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`..NNNNKKLKKKI......`,`..NIINKLKKKKI......`,`..NNNNGFIKKKI......`,`.....IFIKKKLI......`,`......IOOOOOI......`,`.......IQQRI.......`,`......ISSSTI.......`,`.......IIII........`],[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA..`,`.ABBBBCCCCDCDCCCEE.`,`.ABBCCCCCCCDCCDCEA.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`..NNNNKKLKKKI......`,`..NIINKLKKKKI......`,`..NNNNGFIKKKI......`,`.....IFIKKKLI......`,`......IOOOOOI......`,`.....IQRI.IQRI.....`,`....ISSTI.ISSTI....`,`.....III...III.....`],[`.......AAAA........`,`.....AABBBBAAA.....`,`....ABBBBBBCCCA....`,`...ABBBBBBDCCDCA...`,`..ABBBBBDBCCCCCCA..`,`.ABBBBCCCCDCDCCCEE.`,`.ABBCCCCCCCDCCDCEA.`,`.ACCCCCCCCCCDCDDDA.`,`.ADDDDDDDCCCDDDDDA.`,`..ADGGDFFCDDDDDDDA.`,`.IGGGGGFFDDDDDDDDA.`,`IGGHGGGFFFGDDDDDA..`,`IGHGHGGFGFUDDDDA...`,`.IGJGGGFFFDDAAA....`,`..IIGGFFIIAA.......`,`......IKKIKKI......`,`..NNNNKKLKKKI......`,`..NIINKLKKKKI......`,`..NNNNGFIKKKI......`,`.....IFIKKKLI......`,`......IOOOOOI......`,`......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:`#ffffff`,M:`#353539`,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..`,`..ACEEIIEFEIIEEJ...`,`...AJEFFFEFFFEJJJ..`,`.....JEFFKFFEJ.JLJ.`,`.....JMJMMMJMJ.JLLJ`,`...JJMMNMOMNMMJJLJJ`,`..JMMNMLLOMMMNMJJ..`,`.JFFJNMLLOMMMNJFFJ.`,`.JEFJMMLLOMMMMJFEJ.`,`..JJPPPPPQPPPPPJJ..`,`....JRRSJ.JSRRJ....`,`....JTTUJ.JUTTJ....`,`.....JJJ...JJJ.....`],walk:[[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFJIGFFEFEVDDDDA...`,`.JJJFFFEEEDDAAA....`,`..JLJFEEJJAA.......`,`..JLLJJMMJMMJ......`,`..JLJJMMNMMMJ......`,`..JJ.JMNMMMMJ......`,`.....JFEJMMMJ......`,`.....JEJMMMMJ......`,`......JPPPPPJ......`,`.......JRRSJ.......`,`......JTTTUJ.......`,`.......JJJJ........`],[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFJIGFFEFEVDDDDA...`,`.JJJFFFEEEDDAAA....`,`..JLJFEEJJAA.......`,`..JLLJJMMJMMJ......`,`..JLJJMMNMMMJ......`,`..JJ.JMNMMMMJ......`,`.....JFEJMMMJ......`,`.....JEJMMMMJ......`,`......JPPPPPJ......`,`.....JRSJ.JRSJ.....`,`....JTTUJ.JTTUJ....`,`.....JJJ...JJJ.....`],[`......AAAAAAA......`,`....AABBBBBBBAA....`,`...ABBBBBBBCCCCA...`,`..ABBBBBBBCCCDCCA..`,`.ABBBBBBCCCCCCCCA..`,`.ABBBCCCCCDCDCCCCA.`,`.ABBDDCCCCCCCCDDDA.`,`ABCCCBCCCCCCCDDDDA.`,`ADDDDDDDDCCCDDDDDA.`,`.AADFFDEECDDDDDDDA.`,`.JGGGFFEEDDDDDDDDA.`,`JFIIGGGGEEFDDDDDA..`,`JFJIGFFEFEVDDDDA...`,`.JJJFFFEEEDDAAA....`,`..JLJFEEJJAA.......`,`..JLLJJMMJMMJ......`,`..JLJJMMNMMMJ......`,`..JJ.JMNMMMMJ......`,`.....JFEJMMMJ......`,`.....JEJMMMMJ......`,`......JPPPPPJ......`,`......JRRSJ........`,`......JTTTUJ.......`,`.......JJJJ........`]]},gemini_cli:{palette:{A:`#343132`,B:`#b9c8ff`,C:`#40363b`,D:`#3d3539`,E:`#393336`,F:`#a77553`,G:`#c48a62`,H:`#36363e`,I:`#f2c14e`,J:`#373337`,K:`#7a4232`,L:`#6c8cf5`,M:`#bebebb`,N:`#ffffff`,O:`#44362e`,P:`#e8c040`,Q:`#4a6eb0`,R:`#385384`,S:`#c03850`,T:`#f8f8f8`},down:[`.AAA..BBBBBBB..AAA.`,`ACCCA.AAAAAA..ADDDA`,`CCCCCACCCCCCAADCDDE`,`CCCCCCCCCCDDDEDDDED`,`ACCCCCCCDDDCDDDDDDA`,`.ACCCCCDDDDDEDDDEA.`,`ACCCCCDDDDDDDDDDEA.`,`ACCDDDEDDDDDDEEEEA.`,`ADDEEEEEEEEEEEEEEA.`,`ADDDFFEGGEGGEFFEEA.`,`.AEDFGGGGGGGGGFEA..`,`.ADDFGHHGGGHHGFEI..`,`..ADFHGGHGHGGHFIII.`,`...AJFGGGFGGGFJ.I..`,`.....JFGKKKGFJ..J..`,`.....JLJLLLJLJ..J..`,`...JJLLMLLLMLLJJJ..`,`..JLLMLLNNNLLMLLJ..`,`.JGGJMLLLMLLLMJGGJ.`,`.JFGJLLLLLLLLLJGFJ.`,`..JJOOOOOPOOOOOJJ..`,`....JQQRJ.JRQQJ....`,`....JSSTJ.JTSSJ....`,`.....JJJ...JJJ.....`],walk:[[`........BBBB.AAA...`,`......AAAAAAACCDA..`,`....AACCCCCCCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.JGGGGGFFEEEEEEEEA.`,`JGGIGGGFFEEEEEEEA..`,`JGIIIGGFGEEEEEEA...`,`.JKIGGGFFEEEEEA....`,`..JJGGFFAEEAAA.....`,`...J..JLLJLLJ......`,`...J.JLLMLLLJ......`,`...J.JLMLLLLJ......`,`.....JGFJLLMJ......`,`.....JFJLLLLJ......`,`......JOOOOOJ......`,`.......JQQRJ.......`,`......JSSSTJ.......`,`.......JJJJ........`],[`........BBBB.AAA...`,`......AAAAAAACCDA..`,`....AACCCCCCCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.JGGGGGFFEEEEEEEEA.`,`JGGIGGGFFEEEEEEEA..`,`JGIIIGGFGEEEEEEA...`,`.JKIGGGFFEEEEEA....`,`..JJGGFFAEEAAA.....`,`...J..JLLJLLJ......`,`...J.JLLMLLLJ......`,`...J.JLMLLLLJ......`,`.....JGFJLLMJ......`,`.....JFJLLLLJ......`,`......JOOOOOJ......`,`.....JQRJ.JQRJ.....`,`....JSSTJ.JSSTJ....`,`.....JJJ...JJJ.....`],[`........BBBB.AAA...`,`......AAAAAAACCDA..`,`....AACCCCCCCDDDDA.`,`...ACCCCCCCDDDDDDA.`,`..ACCCCCCCDDDEDDDA.`,`.ACCCCCCDDDDDDDDA..`,`.ACCCCDDCDDDDDDEEA.`,`.ACEDDDDDDDDDEDEEA.`,`.AEEEEEEEDDDDEEEEA.`,`..AEGGEFFDDEEEEEEA.`,`.JGGGGGFFEEEEEEEEA.`,`JGGIGGGFFEEEEEEEA..`,`JGIIIGGFGEEEEEEA...`,`.JKIGGGFFEEEEEA....`,`..JJGGFFAEEAAA.....`,`...J..JLLJLLJ......`,`...J.JLLMLLLJ......`,`...J.JLMLLLLJ......`,`.....JGFJLLMJ......`,`.....JFJLLLLJ......`,`......JOOOOOJ......`,`......JQQRJ........`,`......JSSSTJ.......`,`.......JJJJ........`]]}},jt={claude_code:`#d97757`,codex:`#10a37f`,hermes:`#c9a227`,cursor:`#1b1b1f`,gemini_cli:`#6c8cf5`},Mt={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.`,`...HHJJMJLJMJJHH.KH`,`..HJJMMJJLJJNMJJHKK`,`.HFFHMMJJLJJMMHFFHK`,`.HEFHJMMJLJMMJHFEHH`,`..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........`]]},Nt=[{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........`]]}],Pt=[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........`]]}],Ft={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`}]]},It={hair:21,hairColor:12,skin:8,eyes:5,glasses:4,face:6,hat:5,shirt:14,sleeves:14,outfit:6,pants:10,shoes:6},Lt={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]},Rt=new Set([`iTerm.app`,`WezTerm`,`vscode`,`ghostty`,`Hyper`,`Tabby`,`rio`]),zt=new Set([`iTerm.app`,`WezTerm`,`vscode`,`ghostty`,`Hyper`,`Tabby`,`rio`]);function Bt({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`||Rt.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 Vt(e,t){return e.FORCE_HYPERLINK===void 0?!t||e.TMUX||/^screen/.test(e.TERM??``)?!1:zt.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 Ht(e={}){let t=e.env??process.env,n=e.isTTY??!!process.stdout.isTTY,r=Bt({...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=n&&a?Math.max(40,a):void 0,s=o??Math.max(40,Number(t.COLUMNS)||80);return{depth:r,tty:n,fancy:i,links:Vt(t,i),columns:o,layout:s,live:n&&e.columns===void 0}}let R=Ht();function Ut(e){return R=`depth`in e||`fancy`in e?{...R,...e}:Ht(e),R}const Wt=()=>R.live&&process.stdout.columns?Math.max(40,process.stdout.columns):R.columns,Gt=()=>Wt()??R.layout,Kt=()=>Wt()??1/0,qt=e=>{let t=parseInt(e.replace(`#`,``),16);return[t>>16&255,t>>8&255,t&255]};function Jt([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 Yt=(e,t,n)=>n>=3?`38;2;${qt(e).join(`;`)}`:n===2?`38;5;${Jt(qt(e))}`:String(t),Xt=(e,t)=>t>=3?`48;2;${qt(e).join(`;`)}`:`48;5;${Jt(qt(e))}`;function Zt(e,t,n){if(R.depth===0||n===``)return n;let r=`[${e}m`,i=`[${t}m`;return r+n.split(i).join(i+r)+i}const Qt=(e,t=39)=>n=>Zt(Yt(e,t,R.depth),`39`,n),z=e=>Zt(`1`,`22`,e),B=e=>Zt(`2`,`22`,e),$t=e=>Zt(`4`,`24`,e),V={ok:Qt(`#4f9a3a`,32),warn:Qt(`#c98a12`,33),err:Qt(`#e0483a`,31),accent:Qt(I.coral,91),tool:Qt(`#5f7fe8`,94),money:Qt(`#c98a12`,33),sky:Qt(`#3d8fd0`,36),dim:B,bold:z},en=[[`#d4733f`,33],[`#9b5cd6`,95],[`#1f9e8f`,36],[`#c94f7c`,35],[`#7f9a1f`,32],[`#b07a2a`,93]];function tn(e){let t=0;for(let n of e)t=t*31+n.codePointAt(0)>>>0;let[n,r]=en[t%en.length];return e=>z(Qt(n,r)(e))}const H={ok:`✓`,fail:`✗`,skip:`·`,dot:`●`,idle:`○`,arrow:`›`,warn:`!`},nn=/\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g,rn=e=>e.replace(nn,``),an=e=>e.replace(/[\t\n\r]+/g,` `).replace(/[\x00-\x1f\x7f-\x9f]/g,``),on=e=>e.replace(/\x1b\[[0-9;]*m|[\x00-\x1f\x7f-\x9f]/g,e=>e.length>1&&R.depth>0?e:e===`
|
|
7
7
|
`||e===` `?` `:``),sn=e=>e.replace(/ /g,`\xA0`),cn=e=>e.replace(/\u00a0/g,` `),ln=e=>e>=768&&e<=879||e>=8203&&e<=8207||e>=8400&&e<=8447||e>=65024&&e<=65039||e===8205,un=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,dn=e=>{let t=e.codePointAt(0);return t<32||t>=127&&t<160||ln(t)?0:un(t)?2:1};function U(e){let t=0;for(let n of rn(e))t+=dn(n);return t}function fn(e){let t=[],n=0;for(let r of e.matchAll(nn)){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 W(e,t){if(U(e)<=t)return e;if(t<=0)return``;let n=``,r=0,i=!1;for(let a of fn(e)){if(a.esc){n+=a.text,i=!0;continue}let e=dn(a.text);if(r+e>t-1)break;n+=a.text,r+=e}return n+`…`+(i?`\x1B[0m`:``)}const pn=(e,t)=>e+` `.repeat(Math.max(0,t-U(e))),mn=(e,t)=>` `.repeat(Math.max(0,t-U(e)))+e;function G(e,t,n=0){if(!Number.isFinite(t)||U(e)<=t)return[cn(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=U(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(cn)}function hn(e,t={}){return gn(e,t).flat()}function gn(e,t={}){let n=` `.repeat(t.indent??0),r=t.gap??2,i=t.max??Kt(),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=>U(e[n])))),s=[];for(let t of e){let e=[];s.push(e);let a=n+t.slice(0,-1).map((e,t)=>pn(e,o[t]+r)).join(``),c=t[t.length-1]??``,l=U(a);if(l+U(c)<=i)e.push((a+c).replace(/ +$/,``));else if(i-l<20){let t=U(n)+4;e.push(...G(a.replace(/ +$/,``),i,U(n)+2));for(let n of G(c,i-t,0))e.push(` `.repeat(t)+n)}else{let t=G(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(cn))}const _n=(e,t=0,n)=>hn(e.map(([e,t])=>[B(e),t]),{indent:t,gap:2,max:n});function vn(e,t={}){let n=Math.max(20,t.max??Gt()),r=t.title?` ${t.title} `:``,i=Math.min(n-4,Math.max(U(r)+2,...e.map(U))),a=e=>B(e);return[a(`╭─`)+(r?z(W(r,i)):``)+a(`─`.repeat(Math.max(0,i-U(W(r,i))))+`─╮`),...e.map(e=>{let t=W(e,i);return a(`│ `)+pn(t,i)+a(` │`)}),a(`╰`+`─`.repeat(i+2)+`╯`)]}function yn(e,t,n=2,r=0){let i=Math.max(0,...e.map(U)),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]??``:pn(e[o]??``,i+n)+s}).map(e=>e.replace(/ +$/,``))}function bn(e,t=e){let n=t===e?e:`${t} (${e})`;return R.links?`\x1b]8;;${e}\x1b\\${$t(V.sky(t))}\x1b]8;;\x1b\\${t===e?``:B(` (${e})`)}`:R.depth?$t(V.sky(n)):n}const K=e=>V.accent(e),xn=e=>`${V.ok(H.ok)} ${e}`,Sn=e=>`${V.warn(H.warn)} ${V.warn(e)}`;function Cn(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`${V.err(H.fail)} ${V.err(t+a)}${o?` `+wn(o):``}`}function wn(e){return e.split(/((?:npx )?bitfolk(?: (?:--?)?[a-z][\w-]*| <[^>]+>)+)/).map((e,t)=>e===``?``:t%2?K(e):B(e)).join(``)}const Tn=(e,t=2)=>G(e,Kt(),t).join(`
|
|
8
8
|
`),En=(e,t=process.stderr,n=process.env)=>!t.isTTY&&n.FORCE_COLOR===void 0?rn(e):e,Dn=[`·`,`✢`,`✳`,`✶`,`✻`,`✽`,`✻`,`✶`,`✳`,`✢`],On=[`Listening for your team`,`Watering the flowers`,`Sweeping the square`,`Checking the mailbox`,`Tidying the workshop`,`Lighting the lamps`],kn=(e=process.env)=>R.fancy&&!e.BITFOLK_NO_ANIMATION&&!(e.CI&&e.CI!==`0`&&e.CI!==`false`);function An(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 jn=(e,t,n)=>{let[r,i]=[qt(e),qt(t)];return`#`+r.map((e,t)=>Math.round(e+(i[t]-e)*n).toString(16).padStart(2,`0`)).join(``)},Mn=[I.coral,jn(I.coral,I.gold,.45),jn(I.coral,I.gold,.8),jn(I.gold,`#fff3c4`,.5)];function Nn(e,t,n=R.depth){let r=[...rn(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?`[1;93m${o}[22;39m`:`[91m${o}[39m`:`[${Yt(Mn[s],39,n)}m${o}[39m`,``)};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 Pn=(e,t)=>e%(t+8)-3;function Fn(e,t=R.depth,n=Dn){let r=n[(e%n.length+n.length)%n.length];return t===0?r:r===`✽`?`[${Yt(I.gold,93,t)}m${r}[39m`:`[${Yt(I.coral,91,t)}m${r}[39m`}function In(e){let t=e.depth??R.depth,n=rn(e.text).replace(/(\.\.\.|…)$/,``),r=[e.elapsedMs>=(e.timeAfterMs??2e3)?An(e.elapsedMs):null,e.hint].filter(Boolean).join(` · `),i=e=>t?`[2m${e}[22m`:e,a=`${Fn(e.frame,t)} ${Nn(n+`…`,Pn(e.frame,[...n].length),t)}${e.detail?` `+i(e.detail):``}${r?` `+i(`(${r})`):``}`;return e.max?W(a,e.max):a}const Ln=`\x1B[?25l`,Rn=`\r\x1B[2K`,zn=[[`SIGINT`,130],[`SIGTERM`,143],[`SIGHUP`,129]];function Bn(e,t={}){let n=t.out??process.stdout,r=t.animate??(kn()&&!!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+`
|
|
@@ -19,7 +19,7 @@ import{createRequire as e}from"node:module";import{execFileSync as t,spawn as n}
|
|
|
19
19
|
`)+`
|
|
20
20
|
`);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(`
|
|
21
21
|
`)+`
|
|
22
|
-
`)}finally{c(),process.removeListener(`exit`,c),process.removeListener(`SIGINT`,l),process.removeListener(`SIGTERM`,l)}}function si(e,t=R.depth){return qn(Pr(e),``,t)}const ci=[[`login`,`Link this computer to your team`],[`up`,`Run the sessions your team starts, until Ctrl-C`],[`status`,`This computer, its team, 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>`,`Give sessions a git repo; change limits`],[`share <port>`,`Share an app running here at a link`],[`check`,`Check sign-in, tools and repo`],[`bug "<what>"`,`Tell the Bitfolk team about a bug`],[`logout`,`Unlink this computer`]],li=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).`],[`--model <m>`,`Model to pass to the tool.`],[`--permission <p>`,`
|
|
22
|
+
`)}finally{c(),process.removeListener(`exit`,c),process.removeListener(`SIGINT`,l),process.removeListener(`SIGTERM`,l)}}function si(e,t=R.depth){return qn(Pr(e),``,t)}const ci=[[`login`,`Link this computer to your team`],[`up`,`Run the sessions your team starts, until Ctrl-C`],[`status`,`This computer, its team, 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>`,`Give sessions a git repo; change limits`],[`share <port>`,`Share an app running here at a link`],[`check`,`Check sign-in, tools and repo`],[`bug "<what>"`,`Tell the Bitfolk team about a bug`],[`logout`,`Unlink this computer`]],li=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).`],[`--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 ui(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.`],options:[[`--no-browser`,`Print the link instead of opening a browser, to open on any device.`],...li(e),[`--api <url>`,`Bitfolk API (default ${t}).`]]},logout:{usage:[`logout`],about:[`Unlinks this computer from your team and forgets its sign-in here.`]},up:{usage:[`up [--once] [--let-sleep]`,`up <agent>`],about:[`Takes the sessions your team starts on this computer (press Run on a goal, 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.`],options:[[`--once`,`Check once, run what's waiting, then stop.`],[`--let-sleep`,`Don't keep the Mac awake.`],[`<agent>`,`Run just one agent you added.`]]},status:{usage:[`status`,`(or just bitfolk)`],about:[`This computer, its team, 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.`]},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 team 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 team) 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).`],...li(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 repo and limits for sessions on this computer, or for one agent you added.`],options:[...li(e),[`--runtime <r>`,`Agents only: claude_code, codex or command.`],[`--command <cmd>`,`Agents only, for runtime command.`]]},share:{usage:[`share <port> [--name <name>] [--public]`],about:[`Shares an app running here at a link, while the command runs. Needs the ngrok program installed (no ngrok account).`],options:[[`--name <name>`,`What the app is called on your team and in its link.`],[`--public`,`Anyone with the link can open it. Without it, only team members, signed in with Google.`]]},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 the Bitfolk team, 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 team'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 team, read-mostly git. No curl.`],[`bypass`,`No prompts at all. Only on a machine or container you'd hand over to it.`]]}}}function di(e){if(e.startsWith(`(`))return B(e);let t=e.split(/(?<=^\S+) /),[n,r]=[t[0],t.slice(1).join(` `)],i=r.replace(/(<[^>]+>|\[[^\]]+\]|"[^"]*")/g,e=>B(e));return`${B(C)} ${z(K(n))}${r?` `+i:``}`}function fi(e){let t=Kt(),n=e=>G(e,Math.min(t,100)).join(`
|
|
23
23
|
`),r=e.rows===void 0||e.rows>=30?ri({version:e.version,tagline:`Coding sessions for your team`,url:`bitfolk.ai`}):[],i=[];return i.push(r.length?r.join(`
|
|
24
24
|
`):n(`${z(V.accent(`bitfolk`))} ${e.version}: lets your Bitfolk team start coding sessions on this computer.`)),i.push(``),i.push(...mi(ci,t)),i.push(``),i.push(n(`${K(`bitfolk`)} ${B(`alone shows where things stand.`)} ${K(`bitfolk help <command>`)} ${B(`for options.`)}`)),i.push(n(`${B(`Short name:`)} ${K(`bf`)}${B(`, as in`)} ${K(`bf up`)}${B(`.`)}`)),i.push(n(B(`Try it with npx bitfolk, or install it with npm i -g bitfolk. Node 20+, macOS or Linux.`))),i.join(`
|
|
25
25
|
`)}function pi(e,t){let n=ui(t.defaults,t.api)[e];if(!n)return;let r=Kt(),i=[];for(let e of n.usage)i.push(...G(di(e),r,4));for(let e of n.about)i.push(``,...G(e.replace(/\bbitfolk (help \w+|\w+)/g,e=>K(e)),Math.min(r,100)));return n.options?.length&&(i.push(``,_i(e===`permissions`?`Levels`:`Options`)),i.push(...hn(n.options.map(([e,t])=>[V.tool(e),t]),{indent:2,gap:2,max:r}))),n.agentOptions?.length&&(i.push(``,_i(`For agents`)),i.push(...hn(n.agentOptions.map(([e,t])=>[V.tool(e),t]),{indent:2,gap:2,max:r}))),i.join(`
|
|
@@ -63,16 +63,16 @@ if [ $# -ge 3 ]; then
|
|
|
63
63
|
-H "user-agent: bitfolk-api" --data-binary "$data" "$url"
|
|
64
64
|
fi
|
|
65
65
|
exec curl -sS --max-time 30 -X "$method" -H "Authorization: Bearer $BITFOLK_TOKEN" -H "user-agent: bitfolk-api" "$url"
|
|
66
|
-
`,{mode:493}),m(t,493),e}const na={setup_actions:`your join checklist has unfinished steps (GET /v1/setup lists them)`,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`,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`};function ra(e,t){let n=e.reasons.map(e=>`- ${na[e]??e}`).join(`
|
|
67
|
-
`),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
|
|
68
|
-
`).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):`:`Their note for this session:`;r.push(``,t,...n(e.note))}}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.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 team.`),r.join(`
|
|
66
|
+
`,{mode:493}),m(t,493),e}const na={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`,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`};function ra(e,t){let n=e.reasons.map(e=>`- ${na[e]??e}`).join(`
|
|
67
|
+
`),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 Mayor 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 leave the team when it ends, so finish what you claim or report it blocked.`,e.task?`They asked for this task: "${e.task}". Claim it first (it's on the board), then do it.`:`Pick the most useful open task on the board, claim it, and do it.`);let n=e=>e.trim().split(`
|
|
68
|
+
`).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))}}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.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 team.`),r.join(`
|
|
69
69
|
`)}function X(e,n,r){return t(`git`,[`-C`,e,...n],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],env:r}).trim()}function Z(e,t,n){return X(e,[`-c`,`core.fsmonitor=false`,`-c`,`core.hooksPath=/dev/null`,...t],n)}function ia(e,t){let n=s(e,`.git`),r;try{r=v(n)}catch{throw Error(`the worktree's .git is gone`)}let i=te(l(t,X(t,[`rev-parse`,`--git-common-dir`]))),a;if(r.isFile()){let t=/^gitdir:\s*(.+?)\s*$/m.exec(x(n,`utf8`));if(!t)throw Error(`the worktree's .git file was changed`);a=l(e,t[1])}else if(r.isDirectory())a=n;else throw Error(`the worktree's .git was changed`);let o;try{o=te(a)}catch{throw Error(`the worktree's .git points nowhere`)}if(o!==i&&!o.startsWith(s(i,`worktrees`)+u))throw Error(`the worktree's .git no longer points into its repo`)}function aa(e){try{return X(l(e),[`rev-parse`,`--show-toplevel`])}catch{return null}}const oa=e=>`bitfolk/${e.slug}`;function sa(e,t){try{return X(e,[`rev-parse`,`--verify`,`--quiet`,`refs/heads/${t}`]),!0}catch{return!1}}function ca(e){if(!e.repo){let t=s(N(),`agents`,e.slug),n=!_(t);return n&&y(t,{recursive:!0,mode:448}),{dir:t,created:n}}let t=s(N(),`worktrees`,e.slug),n=oa(e);if(_(s(t,`.git`)))return{dir:t,branch:n,created:!1};if(!aa(e.repo))throw Error(`${e.repo} is no longer a git repository`);return y(s(N(),`worktrees`),{recursive:!0,mode:448}),X(e.repo,[`worktree`,`prune`]),sa(e.repo,n)?X(e.repo,[`worktree`,`add`,t,n]):X(e.repo,[`worktree`,`add`,`-b`,n,t,e.base??`HEAD`]),{dir:t,branch:n,created:!0}}function la(e,t){return Z(e,[`status`,`--porcelain`])?(Z(e,[`add`,`-A`]),Z(e,[`commit`,`-q`,`--no-verify`,`-m`,t]),Z(e,[`rev-parse`,`--short`,`HEAD`])):null}function ua(e){if(!e.repo)return null;let t=s(N(),`worktrees`,e.slug);if(!_(t))return null;try{return{dir:t,changed:X(t,[`status`,`--porcelain`]).split(`
|
|
70
70
|
`).filter(Boolean).length}}catch{return{dir:t,changed:0}}}function da(e){if(!e.repo)return;let t=s(N(),`worktrees`,e.slug);if(_(t))try{X(e.repo,[`worktree`,`remove`,`--force`,t])}catch{}}function fa(e){try{return Z(e,[`rev-parse`,`HEAD`])}catch{return null}}function pa(e,t,n){let r=`refs/heads/${n}`,i=Z(e,[`log`,`--format=%h%x09%s`,`-n`,`50`,`${t}..${r}`]).split(`
|
|
71
71
|
`).filter(Boolean).map(e=>{let[t=``,...n]=e.split(` `);return{sha:t,subject:n.join(` `).slice(0,200)}}),a=Z(e,[`diff`,`--no-ext-diff`,`--no-textconv`,`--shortstat`,t,r]),o=e=>Number(e.exec(a)?.[1]??0);return{commits:i,commit_count:Number(Z(e,[`rev-list`,`--count`,`${t}..${r}`]))||i.length,files_changed:o(/(\d+) files? changed/),insertions:o(/(\d+) insertions?/),deletions:o(/(\d+) deletions?/)}}const ma=e=>`refs/bitfolk/checkpoints/${e}`,ha={GIT_AUTHOR_NAME:`Bitfolk checkpoint`,GIT_AUTHOR_EMAIL:`checkpoint@bitfolk.invalid`,GIT_COMMITTER_NAME:`Bitfolk checkpoint`,GIT_COMMITTER_EMAIL:`checkpoint@bitfolk.invalid`};function ga(e,t){let n;try{n=Z(e,[`rev-parse`,`HEAD`])}catch{return null}let r=b(s(ce(),`bitfolk-checkpoint-`));try{let i=s(r,`index`),a=l(e,Z(e,[`rev-parse`,`--git-path`,`index`]));_(a)&&g(a,i);let o={...process.env,...ha,GIT_INDEX_FILE:i};Z(e,[`add`,`-A`],o);let c=Z(e,[`write-tree`],o),u=ma(t),d=null;try{let[t=``,n=``]=Z(e,[`log`,`-1`,`--format=%T %P`,u]).split(` `);d={tree:t,parent:n}}catch{}if(d&&d.tree===c&&d.parent===n)return{head:n,checkpoint:Z(e,[`rev-parse`,u]),changed:!1};let f=Z(e,[`commit-tree`,c,`-p`,n,`-m`,`Bitfolk checkpoint of session ${t}`],o);return Z(e,[`update-ref`,u,f]),{head:n,checkpoint:f,changed:!0}}finally{re(r,{recursive:!0,force:!0})}}function _a(e,t){if(!/^[0-9a-f]{7,64}$/.test(t))return!1;try{let n=Z(e,[`rev-parse`,`HEAD`]),[r=``,i=``]=Z(e,[`log`,`-1`,`--format=%T %P`,t]).split(` `);return i!==n||r===Z(e,[`rev-parse`,`HEAD^{tree}`])?!1:(Z(e,[`restore`,`--source=${t}`,`--worktree`,`--`,`.`]),!0)}catch{return!1}}function va(e,t=30,n=Date.now()){let r=0;try{let i=n/1e3-t*86400;for(let t of X(e,[`for-each-ref`,`--format=%(refname) %(committerdate:unix)`,`refs/bitfolk/checkpoints/`]).split(`
|
|
72
72
|
`)){let[n,a]=t.split(` `);n&&Number(a)<i&&(X(e,[`update-ref`,`-d`,n]),r++)}}catch{}return r}const ya=36e5,ba=process.env.BITFOLK_FAST_POLL===`1`,xa=ba?3e3:3e4,Sa=ba?3e4:6e5,Ca=ba?2e3:15e3,wa=ba?5e3:6e4,Ta=ba?1e3:5e3,Ea={session_requested:`a session you asked for`,claimable_tasks:`tasks to claim`,my_tasks:`its tasks`,new_messages:`new messages`,review_waiting:`a review`,briefing_due:`a briefing`,setup_actions:`setup`,watch_fired:`a watch`},Da=e=>e.map(e=>Ea[e]??e.replace(/_/g,` `)).join(`, `)||`new work`;function Oa(e,t){if(e){if(e.pid)try{process.kill(-e.pid,t);return}catch{}e.kill(t)}}const ka=new WeakSet;function Aa(e,t=1e4){Oa(e,`SIGTERM`),setTimeout(()=>{e&&!ka.has(e)&&Oa(e,`SIGKILL`)},t).unref()}function ja(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 Ma(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 Na={info:[()=>B(H.skip),e=>e],idle:[()=>B(H.idle),B],start:[()=>V.accent(H.dot),e=>e],ok:[()=>V.ok(H.ok),e=>e],fail:[()=>V.err(H.fail),V.err],warn:[()=>V.warn(H.warn),V.warn],progress:[()=>B(H.arrow),B]};function Pa(e,t,n){let r=(t.runStarts??[]).filter(e=>e>n-ya).sort((e,t)=>e-t),i=e.maxRunsPerHour-r.length;return{left:i,freesAt:i>0?n:(r[0]??n)+ya}}function Fa(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(`the team asked for ${t.slice(7)}, which isn't set up here (${C} add)`);return n.protocol===`acp`?{runtime:`acp`,acp:{...Pe(n.command),agent:t}}:{runtime:`command`,command:n.command}}let n=Te(t);if(n)return{runtime:n};let r=pr(t);if(r)return{runtime:`acp`,acp:r};throw Error(`this runner can't start ${t}`)}function Ia(e,t){let n=t.session.retry,r=n?.mode===`fix`&&n.branch?.startsWith(`bitfolk/builder-`)?n.branch.slice(8):null;return{id:t.builder.id,name:t.builder.name,slug:r&&Tt(r)===r?r:Tt(`builder-${t.session.id.slice(-8)}`),...Fa(e,t.session.runtime),api:e.api,token:t.builder.token,repo:e.repo,base:(n?.mode===`redo`&&/^[0-9a-f]{7,64}$/.test(n.base_sha??``)?n.base_sha:null)??e.base,maxUsdPerRun:e.maxUsdPerRun,maxRunsPerHour:e.maxRunsPerHour,timeoutMin:e.timeoutMin,permission:e.permission,model:e.model}}const Q=`machine`;function La(e=process.env){return Object.fromEntries(Object.entries(e).filter(([e])=>!/^npm_[a-z]/.test(e)&&e!==`INIT_CWD`&&e!==`NODE`))}function Ra(e=process.env,t=me){let n=(e.PATH??``).split(i).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 za=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=null;#f=0;#p=null;#m=0;#h=!1;#g;#_=null;#v=new Map;#y=0;#b=null;#x=null;#S={day:``,done:0,failed:0,stopped:0,costMicros:0,durationMs:0};constructor(e,t={}){this.config=e,this.state=Ct(),this.#i=t.out??(e=>process.stdout.write(e+`
|
|
73
73
|
`)),this.#a=t.now??Date.now,this.#o=t.progressMs??1e4,this.#s=t.checkpointMs??18e4,this.#c=t.acpCancelGraceMs,this.#g=!!t.liveFooter}#C(e){return this.state.agents[e.id]??={}}#w(e){let t=this.#r.get(e.id);return t||this.#r.set(e.id,t=new pt(e.api,e.oauth?()=>ar(e,{now:this.#a}):e.token)),t}#T(e,t,n=`info`,r){let i=new Date(this.#a()).toTimeString().slice(0,8),[a,o]=Na[n],s=r?()=>r:a,c=e?e.name:``,l=c?tn(c)(c):``,u=Kt(),d=on(o(t));if(u<60){this.#i(G(`${B(i)} ${s()} ${l}${l?` `:``}${d}`,u,4).join(`
|
|
74
74
|
`));return}let f=`${B(i)} ${s()} ${l}${` `.repeat(Math.max(0,12-U(c)))} `;this.#i(G(f+d,u,U(f)).join(`
|
|
75
|
-
`))}#E(){wt(this.state)}#D(e,t){this.#t.set(e.id,this.#a()+Math.max(1e3,t))}#O(e){let t=(this.#n.get(e.id)??0)+1;return this.#n.set(e.id,t),Math.min(Sa,Ca*2**(t-1))}stop(){if(!this.#l){this.#l=!0;for(let e of this.#e.values())this.#k(e,`owner`);this.#p?.()}}#k(e,t){if(e.cancel){let n=e.cancel(t);return n&&t===`owner`&&(e.stopped=!0),n}return t===`owner`&&(e.stopped=!0),Aa(e.child),!0}killAll(){for(let e of this.#e.values())e.stopped=!0,Oa(e.child,`SIGKILL`)}async#A(){if([...this.#e.values()].some(e=>e.sessionId&&!e.stopped))try{let e=await this.#z()?.peek();e&&this.#P(Q);for(let t of e?.cancel??[])this.#j(t)}catch{}}#j(e){for(let[t,n]of this.#e)if(!(n.sessionId!==e||n.stopped))return this.#T({id:t,name:`Builder`},`canceled from your team; stopping it`,`warn`),this.#k(n,`owner`),!0;return!1}#M(e,t){let n=[],r=null,i=JSON.stringify([null,null,null]),a=!1,o=!1,s=async()=>{let r=this.#z();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.#j(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!==Q||!this.#d).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.#h||this.#m||!r.length?null:Math.min(...r),checking:this.#m>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.#y,waitingFor:this.#y?this.#b:null,capFreesAt:this.#x,lastCheckAt:this.#_,checkFailure:[...this.#v.values()].sort((e,t)=>e.since-t.since)[0]??null,signedOut:this.#d,runsThisHour:this.config.machine?this.config.machine.maxRunsPerHour-Pa(this.config.machine,this.state.agents[Q]??{},this.#a()).left:null,today:this.#N()}}#N(){let e=new Date(this.#a()).toDateString();return this.#S.day!==e&&(this.#S={day:e,done:0,failed:0,stopped:0,costMicros:0,durationMs:0}),this.#S}#P(e){this.#_=this.#a(),this.#v.delete(e)}#F(e,t,n){let r=this.#a(),i=t.message;this.#v.set(e,{message:i,since:this.#v.get(e)?.since??r,retryAt:r+n})}async#I(e){this.#m++;try{return await e()}finally{this.#m--}}async check(e){let t=this.#C(e);if(t.disabledReason||this.#e.has(e.id))return null;let{left:n,freesAt:r}=Pa(e,t,this.#a());if(n<=0)return this.#T(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.#I(()=>this.#w(e).peek(t.etag))}catch(n){if(n instanceof q&&n.ended)return t.disabledReason=`its sign-in ended (unlinked on your team, or unused for 90 days)`,this.#T(e,`stopped: ${t.disabledReason}. Copy a new token from its page on your team and run \`${C} add <token>\`.`,`fail`),this.#E(),null;if(n instanceof M&&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.#T(e,r?`stopped: ${t.disabledReason}. Run \`${C} rm "${e.name}"\` to forget it.`:`stopped: ${t.disabledReason}. Copy a new token from its page on your team and run \`${C} add <token>\` (it keeps your options).`,`fail`),this.#E(),null}let r=this.#O(e);return this.#T(e,`peek failed (${n.message}); retrying in ${ja(r)}`,`warn`),this.#D(e,r),this.#F(e.id,n,Math.max(1e3,r)),null}return this.#n.delete(e.id),this.#P(e.id),i?(t.etag=i.etag,t.pollMs=i.next_poll_after_s*1e3,this.#E(),i.tier===`silent`||!i.has_work?(this.#D(e,i.next_poll_after_s*1e3),null):{done:this.#L(e,i)}):(this.#D(e,t.pollMs??wa),null)}#L(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:an(n?n.session.task?.title??n.session.goal?.title??`a goal`:`woke for ${Da(t.reasons)}`),joinedAt:this.#a()},i=this.#V(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.#T(e,`couldn't pick up the earlier conversation; starting fresh on the same branch`,`warn`),this.#V(e,t,r,n,{fresh:!0})))),r.done=(n?i.then(t=>this.#B(e,n,t)):i).finally(()=>{this.#e.delete(e.id),this.#p?.()}),this.#e.set(e.id,r),r.done}#R(e,t,n,r){let i=``,a=null,o=()=>a??=(async()=>{let a=this.#z();if(!a)return;let o=null;try{o=ga(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)}}#z(){let e=this.config.machine;return!e||this.#d?null:this.#u??=new mt(e.api,()=>ar(e,{now:this.#a}))}async checkMachine(){let e=this.config.machine,t=this.#z();if(!e||!t)return[];let n=this.state.agents[Q]??={},r={id:Q,name:e.name},i;try{i=await this.#I(()=>t.peek())}catch(e){if(e instanceof q&&e.ended||e instanceof M&&e.status===401)return this.#d=`this machine was unlinked, or its sign-in ended`,this.#T(r,`stopped: ${this.#d}. Run \`${C} login\` to link it again.`,`fail`),[];let t=this.#O(r);return this.#T(r,`check-in failed (${e.message}); retrying in ${ja(t)}`,`warn`),this.#t.set(Q,this.#a()+t),this.#F(Q,e,t),[]}this.#n.delete(r.id),this.#P(Q);for(let e of i.cancel??[])this.#j(e);let a=Math.max(1e3,i.next_poll_after_s*1e3);this.#t.set(Q,this.#a()+a);let o=()=>{[...this.#e.values()].some(e=>e.sessionId&&!e.stopped)&&this.#t.set(Q,Math.min(this.#t.get(Q)??1/0,this.#a()+Ta))},s=[],c=i.queued;for(this.#b=null,this.#x=null;c>0&&!this.#l;c--){if(this.#e.size>=this.config.maxConcurrent){this.#b=`slot`;break}let{left:i,freesAt:a}=Pa(e,n,this.#a());if(i<=0){this.#b=`cap`,this.#x=a,this.#f!==a&&(this.#f=a,this.#T(r,`hit ${e.maxRunsPerHour} sessions this hour; the rest wait until ${new Date(a).toTimeString().slice(0,5)}`,`warn`)),this.#t.set(Q,a);break}let o;try{o=await this.#I(()=>t.claim({runtimes:e.runtimes,timeout_min:e.timeoutMin}))}catch(e){this.#T(r,`couldn't take a session (${e.message})`,`warn`);break}if(!o){c=0;break}this.#y=Math.max(0,this.#y-1),n.runStarts=[...(n.runStarts??[]).filter(e=>e>this.#a()-ya),this.#a()],this.#E();let l;try{l=Ia(e,o)}catch(e){this.#T(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=an(o.session.task?.title??o.session.goal?.title??`a goal`);this.#T(l,`joined for a session: ${V.bold(u)} ${B(`·`)} ${V.tool(sn(J(o.session.runtime)))}`,`start`,si(o.session.runtime));let d=await new pt(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.#L(l,f,o)})}return this.#y=this.#b?Math.max(0,c):0,o(),s}async#B(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&&ia(n.work.dir,e.repo),r=pa(n.work.dir,t,n.work.branch)}catch{}i={base:t?.slice(0,12)??null,...r,duration_ms:n.durationMs}}try{await this.#z()?.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.#T(e,`left ${V.bold(`${i.commit_count} commit${i.commit_count===1?``:`s`}`)} on ${V.tool(n.work.branch)} ${B(`(${i.files_changed} files)`)}`,`ok`)}catch(t){this.#T(e,`couldn't report the session's end (${t.message}); Bitfolk times it out`,`warn`)}return this.#T(e,`left the team`,`idle`),da(e),e.repo&&va(e.repo),delete this.state.agents[e.id],this.#E(),n}async#V(e,t,r,a,o={}){let c=this.#C(e),l=this.#w(e),u=we[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=ca(e)}catch(t){return c.etag=void 0,this.#T(e,`can't prepare its workspace: ${t.message}`,`fail`),this.#D(e,this.#O(e)),null}let h=m.branch?fa(m.dir):null,g=a?.session.retry??null,_=!!(g?.mode===`fix`&&m.created&&m.branch&&g.checkpoint_sha&&_a(m.dir,g.checkpoint_sha));_&&this.#T(e,`put back the earlier session's uncommitted work on ${V.tool(String(m.branch))}`,`ok`);let v=null;try{v=await l.runStart({client_run_id:fe(),host:se(),runtime:d?d.agent:e.runtime,reasons:t.reasons,tier:t.tier})}catch(n){if(n instanceof M&&n.status===409)return this.#T(e,`is paused by its owner; not starting`,`idle`),this.#D(e,t.next_poll_after_s*1e3||(ba?wa:6e5)),null;this.#T(e,`couldn't record the run start (${n.message}); running anyway`,`warn`)}v||await l.status(`working`).catch(()=>{});let b=o.fresh?null:g?.mode===`fix`?u.resumes!==!1&&g.tool_session_id?g.tool_session_id:null:u.resumes!==!1&&!m.created&&c.sessionId&&c.sessionAt&&f-c.sessionAt<432e5?c.sessionId:null,x=!!m.branch&&!!u.runnerCommits?.(e),ee=ra(t,{agentName:e.name,api:e.api,branch:m.branch,runnerCommits:x,resumed:!!b,session:a?{goal:a.session.goal?.title??null,task:a.session.task?.title??null,note:a.session.note,goalDone:a.session.goal?.done_definition??null,taskSpec:a.session.task?.spec??null,asks:a.session.asks??[],requestedBy:a.session.requested_by??`owner`,retry:g?{mode:g.mode,branch:g.branch,summary:g.summary,error:g.error,status:g.status,restored:_}:void 0}:void 0}),te=u.launch(e,ee,b);c.runStarts=[...(c.runStarts??[]).filter(e=>e>f-ya),f],this.#E(),this.#T(e,`woke ${B(`for ${Da(t.reasons)}`)} → ${V.tool(sn(d?`${J(d.agent)} over ACP`:e.runtime))}${b?B(`, resuming`):``}`,`start`);let ne=s(N(),`logs`,e.slug);y(ne,{recursive:!0,mode:448});let ie=s(ne,`${new Date(f).toISOString().replace(/[:.]/g,`-`)}.jsonl`),ae=new Set([e.token]),oe=e=>[...ae].reduce((e,t)=>e.split(t).join(`[token]`),e),ce=(e,t)=>p(ie,JSON.stringify({t:this.#a(),stream:e,line:oe(t)})+`
|
|
75
|
+
`))}#E(){wt(this.state)}#D(e,t){let n=this.#a()+Math.max(1e3,t);return this.#t.set(e.id,n),n}#O(e){let t=(this.#n.get(e.id)??0)+1;return this.#n.set(e.id,t),Math.min(Sa,Ca*2**(t-1))}stop(){if(!this.#l){this.#l=!0;for(let e of this.#e.values())this.#k(e,`owner`);this.#p?.()}}#k(e,t){if(e.cancel){let n=e.cancel(t);return n&&t===`owner`&&(e.stopped=!0),n}return t===`owner`&&(e.stopped=!0),Aa(e.child),!0}killAll(){for(let e of this.#e.values())e.stopped=!0,Oa(e.child,`SIGKILL`)}async#A(){if([...this.#e.values()].some(e=>e.sessionId&&!e.stopped))try{let e=await this.#z()?.peek();e&&this.#P(Q);for(let t of e?.cancel??[])this.#j(t)}catch{}}#j(e){for(let[t,n]of this.#e)if(!(n.sessionId!==e||n.stopped))return this.#T({id:t,name:`Builder`},`canceled from your team; stopping it`,`warn`),this.#k(n,`owner`),!0;return!1}#M(e,t){let n=[],r=null,i=JSON.stringify([null,null,null]),a=!1,o=!1,s=async()=>{let r=this.#z();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.#j(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!==Q||!this.#d).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.#h||this.#m||!r.length?null:Math.min(...r),checking:this.#m>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.#y,waitingFor:this.#y?this.#b:null,capFreesAt:this.#x,lastCheckAt:this.#_,checkFailure:[...this.#v.values()].sort((e,t)=>e.since-t.since)[0]??null,signedOut:this.#d,runsThisHour:this.config.machine?this.config.machine.maxRunsPerHour-Pa(this.config.machine,this.state.agents[Q]??{},this.#a()).left:null,today:this.#N()}}#N(){let e=new Date(this.#a()).toDateString();return this.#S.day!==e&&(this.#S={day:e,done:0,failed:0,stopped:0,costMicros:0,durationMs:0}),this.#S}#P(e){this.#_=this.#a(),this.#v.delete(e)}#F(e,t,n){let r=t.message;this.#v.set(e,{message:r,since:this.#v.get(e)?.since??this.#a(),retryAt:n})}async#I(e){this.#m++;try{return await e()}finally{this.#m--}}async check(e){let t=this.#C(e);if(t.disabledReason||this.#e.has(e.id))return null;let{left:n,freesAt:r}=Pa(e,t,this.#a());if(n<=0)return this.#T(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.#I(()=>this.#w(e).peek(t.etag))}catch(n){if(n instanceof q&&n.ended)return t.disabledReason=`its sign-in ended (unlinked on your team, or unused for 90 days)`,this.#T(e,`stopped: ${t.disabledReason}. Copy a new token from its page on your team and run \`${C} add <token>\`.`,`fail`),this.#E(),null;if(n instanceof M&&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.#T(e,r?`stopped: ${t.disabledReason}. Run \`${C} rm "${e.name}"\` to forget it.`:`stopped: ${t.disabledReason}. Copy a new token from its page on your team and run \`${C} add <token>\` (it keeps your options).`,`fail`),this.#E(),null}let r=this.#O(e);return this.#T(e,`peek failed (${n.message}); retrying in ${ja(r)}`,`warn`),this.#F(e.id,n,this.#D(e,r)),null}return this.#n.delete(e.id),this.#P(e.id),i?(t.etag=i.etag,t.pollMs=i.next_poll_after_s*1e3,this.#E(),i.tier===`silent`||!i.has_work?(this.#D(e,i.next_poll_after_s*1e3),null):{done:this.#L(e,i)}):(this.#D(e,t.pollMs??wa),null)}#L(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:an(n?n.session.task?.title??n.session.goal?.title??`a goal`:`woke for ${Da(t.reasons)}`),joinedAt:this.#a()},i=this.#V(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.#T(e,`couldn't pick up the earlier conversation; starting fresh on the same branch`,`warn`),this.#V(e,t,r,n,{fresh:!0})))),r.done=(n?i.then(t=>this.#B(e,n,t)):i).finally(()=>{this.#e.delete(e.id),this.#p?.()}),this.#e.set(e.id,r),r.done}#R(e,t,n,r){let i=``,a=null,o=()=>a??=(async()=>{let a=this.#z();if(!a)return;let o=null;try{o=ga(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)}}#z(){let e=this.config.machine;return!e||this.#d?null:this.#u??=new mt(e.api,()=>ar(e,{now:this.#a}))}async checkMachine(){let e=this.config.machine,t=this.#z();if(!e||!t)return[];let n=this.state.agents[Q]??={},r={id:Q,name:e.name},i;try{i=await this.#I(()=>t.peek())}catch(e){if(e instanceof q&&e.ended||e instanceof M&&e.status===401)return this.#d=`this machine was unlinked, or its sign-in ended`,this.#T(r,`stopped: ${this.#d}. Run \`${C} login\` to link it again.`,`fail`),[];let t=this.#O(r);this.#T(r,`check-in failed (${e.message}); retrying in ${ja(t)}`,`warn`);let n=this.#a()+t;return this.#t.set(Q,n),this.#F(Q,e,n),[]}this.#n.delete(r.id),this.#P(Q);for(let e of i.cancel??[])this.#j(e);let a=Math.max(1e3,i.next_poll_after_s*1e3);this.#t.set(Q,this.#a()+a);let o=()=>{[...this.#e.values()].some(e=>e.sessionId&&!e.stopped)&&this.#t.set(Q,Math.min(this.#t.get(Q)??1/0,this.#a()+Ta))},s=[],c=i.queued;for(this.#b=null,this.#x=null;c>0&&!this.#l;c--){if(this.#e.size>=this.config.maxConcurrent){this.#b=`slot`;break}let{left:i,freesAt:a}=Pa(e,n,this.#a());if(i<=0){this.#b=`cap`,this.#x=a,this.#f!==a&&(this.#f=a,this.#T(r,`hit ${e.maxRunsPerHour} sessions this hour; the rest wait until ${new Date(a).toTimeString().slice(0,5)}`,`warn`)),this.#t.set(Q,a);break}let o;try{o=await this.#I(()=>t.claim({runtimes:e.runtimes,timeout_min:e.timeoutMin}))}catch(e){this.#T(r,`couldn't take a session (${e.message})`,`warn`);break}if(!o){c=0;break}this.#y=Math.max(0,this.#y-1),n.runStarts=[...(n.runStarts??[]).filter(e=>e>this.#a()-ya),this.#a()],this.#E();let l;try{l=Ia(e,o)}catch(e){this.#T(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=an(o.session.task?.title??o.session.goal?.title??`a goal`);this.#T(l,`joined for a session: ${V.bold(u)} ${B(`·`)} ${V.tool(sn(J(o.session.runtime)))}`,`start`,si(o.session.runtime));let d=await new pt(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.#L(l,f,o)})}return this.#y=this.#b?Math.max(0,c):0,o(),s}async#B(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&&ia(n.work.dir,e.repo),r=pa(n.work.dir,t,n.work.branch)}catch{}i={base:t?.slice(0,12)??null,...r,duration_ms:n.durationMs}}try{await this.#z()?.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.#T(e,`left ${V.bold(`${i.commit_count} commit${i.commit_count===1?``:`s`}`)} on ${V.tool(n.work.branch)} ${B(`(${i.files_changed} files)`)}`,`ok`)}catch(t){this.#T(e,`couldn't report the session's end (${t.message}); Bitfolk times it out`,`warn`)}return this.#T(e,`left the team`,`idle`),da(e),e.repo&&va(e.repo),delete this.state.agents[e.id],this.#E(),n}async#V(e,t,r,a,o={}){let c=this.#C(e),l=this.#w(e),u=we[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=ca(e)}catch(t){return c.etag=void 0,this.#T(e,`can't prepare its workspace: ${t.message}`,`fail`),this.#D(e,this.#O(e)),null}let h=m.branch?fa(m.dir):null,g=a?.session.retry??null,_=!!(g?.mode===`fix`&&m.created&&m.branch&&g.checkpoint_sha&&_a(m.dir,g.checkpoint_sha));_&&this.#T(e,`put back the earlier session's uncommitted work on ${V.tool(String(m.branch))}`,`ok`);let v=null;try{v=await l.runStart({client_run_id:fe(),host:se(),runtime:d?d.agent:e.runtime,reasons:t.reasons,tier:t.tier})}catch(n){if(n instanceof M&&n.status===409)return this.#T(e,`is paused by its owner; not starting`,`idle`),this.#D(e,t.next_poll_after_s*1e3||(ba?wa:6e5)),null;this.#T(e,`couldn't record the run start (${n.message}); running anyway`,`warn`)}v||await l.status(`working`).catch(()=>{});let b=o.fresh?null:g?.mode===`fix`?u.resumes!==!1&&g.tool_session_id?g.tool_session_id:null:u.resumes!==!1&&!m.created&&c.sessionId&&c.sessionAt&&f-c.sessionAt<432e5?c.sessionId:null,x=!!m.branch&&!!u.runnerCommits?.(e),ee=ra(t,{agentName:e.name,api:e.api,branch:m.branch,runnerCommits:x,resumed:!!b,session:a?{goal:a.session.goal?.title??null,task:a.session.task?.title??null,note:a.session.note,goalDone:a.session.goal?.done_definition??null,taskSpec:a.session.task?.spec??null,asks:a.session.asks??[],requestedBy:a.session.requested_by??`owner`,requestedByAgent:a.session.requested_by_agent??null,retry:g?{mode:g.mode,branch:g.branch,summary:g.summary,error:g.error,status:g.status,restored:_}:void 0}:void 0}),te=u.launch(e,ee,b);c.runStarts=[...(c.runStarts??[]).filter(e=>e>f-ya),f],this.#E(),this.#T(e,`woke ${B(`for ${Da(t.reasons)}`)} → ${V.tool(sn(d?`${J(d.agent)} over ACP`:e.runtime))}${b?B(`, resuming`):``}`,`start`);let ne=s(N(),`logs`,e.slug);y(ne,{recursive:!0,mode:448});let ie=s(ne,`${new Date(f).toISOString().replace(/[:.]/g,`-`)}.jsonl`),ae=new Set([e.token]),oe=e=>[...ae].reduce((e,t)=>e.split(t).join(`[token]`),e),ce=(e,t)=>p(ie,JSON.stringify({t:this.#a(),stream:e,line:oe(t)})+`
|
|
76
76
|
`,{mode:384}),ue=ta(),de=or(e),pe=e.oauth?setInterval(()=>{e.oauth.expiresAt-this.#a()>6e5||ar(e,{now:this.#a}).then(()=>{ae.add(e.token),or(e)}).catch(t=>this.#T(e,`couldn't renew its sign-in mid-run: ${t.message}`,`warn`))},6e4):null,S=ge();r.tally=S,r.startedAt=this.#a();let C={...La(),PATH:[ue,...Ra(),...lr()].join(i),...d?{NO_BROWSER:`1`}:{BITFOLK_TOKEN:e.token},BITFOLK_TOKEN_FILE:de,BITFOLK_API:e.api.replace(/\/+$/,``),BITFOLK_AGENT:e.name,...v?{BITFOLK_RUN_ID:v.id}:{}};d&&delete C.BITFOLK_TOKEN;for(let[e,t]of Object.entries(C))t&&t.length>=12&&/KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH/i.test(e)&&e!==`BITFOLK_TOKEN_FILE`&&ae.add(t);let me=a?this.#M(a.session.id,S):null,he=a&&m.branch?this.#R(a.session.id,m,h,S):null,w=null,_e=t=>{let n=t&&an(oe(t)).trim();me?.add(n),n&&n!==w&&(w=n,r.activity=n,r.activityAt=this.#a(),this.#T(e,n,`progress`))},T=null,E=null,D=!1,ve,ye=null;try{ve=await new Promise(t=>{let i=n(te.bin,te.args,{cwd:m.dir,env:C,stdio:[`pipe`,`pipe`,`pipe`],detached:!0});if(r.child=i,i.stdin.on(`error`,()=>{}),d){let t=new ut({stdin:i.stdin,stdout:i.stdout,agent:{...e,acp:d},label:J(d.agent),cwd:m.dir,home:N(),packet:ee,tally:S,clientVersion:j,log:ce,activity:_e,kill:()=>{ka.has(i)||Aa(i)},cancelGraceMs:this.#c});r.cancel=e=>t.cancel(e),ye=t.run()}else i.stdin.end(te.stdin),le({input:i.stdout}).on(`line`,e=>{ce(`out`,e),u.parse(e,S),u.activity&&_e(u.activity(e,m.dir))});(this.#l||r.stopped)&&this.#k(r,`owner`),le({input:i.stderr}).on(`line`,e=>{ce(`err`,e),e.trim()&&(E=oe(e.trim()).slice(0,300))});let a=setTimeout(()=>{D=!0,this.#k(r,`timeout`)||(D=!1)},e.timeoutMin*6e4);i.on(`error`,e=>{T=e.code===`ENOENT`?`${te.bin} isn't installed or isn't on PATH`:e.message}),i.on(`close`,e=>{ka.add(i),clearTimeout(a),t({code:e})})})}finally{me?.stop(),he?.stop(),pe&&clearInterval(pe)}let be=ye?await ye:null;r.cancel=void 0,u.afterExit?.(te,S),re(de,{force:!0});let O=this.#a()-f,k,A;if(be?(k=r.stopped?`interrupted`:S.overBudget?`over_budget`:T||D||!be.ok?`failed`:`succeeded`,A=T??(k===`over_budget`?S.error:D&&k===`failed`?`stopped after ${e.timeoutMin} minutes`:k===`failed`?be.exited?E??`${be.error??`the tool exited`}${ve.code===null?``:` (exit ${ve.code})`}`:be.error??E??`the turn failed`:null),k===`failed`&&(S.error=A)):(k=r.stopped?`interrupted`:S.overBudget?`over_budget`:T||D||ve.code!==0||S.isError?`failed`:`succeeded`,A=T??(D?`stopped after ${e.timeoutMin} minutes`:k===`failed`?S.error??E??`exit ${ve.code}`:null)),k===`failed`&&!S.error&&(S.error=A),x&&!T){let t=`${e.name}: ${S.summary??`work from a Bitfolk run`}`,n=`Bitfolk run${v?` ${v.id}`:``}, ${k}.`;try{e.repo&&m.branch&&ia(m.dir,e.repo);let r=la(m.dir,`${t.length>72?t.slice(0,71)+`…`:t}\n\n${n}`);r&&this.#T(e,`committed its changes as ${V.bold(r)} on ${V.tool(String(m.branch))}`,`ok`)}catch(t){this.#T(e,`couldn't commit its changes: ${t.message.split(`
|
|
77
77
|
`)[0]}`,`warn`)}}await he?.final().catch(()=>{}),k===`failed`&&b&&O<2e4?(c.sessionId=void 0,c.etag=void 0):S.sessionId&&(c.sessionId=S.sessionId,c.sessionAt=this.#a()),(k===`failed`||k===`interrupted`)&&(c.etag=void 0),this.#E();let xe={status:k,exit_code:be?be.ok&&k===`succeeded`?0:null:ve.code,session_id:S.sessionId,input_tokens:S.inputTokens,output_tokens:S.outputTokens,cost_micros:S.costMicros,summary:S.summary,error:A};v?await l.runFinish(v.id,xe).catch(async()=>{await new Promise(e=>setTimeout(e,2e3)),await l.runFinish(v.id,xe).catch(t=>this.#T(e,`couldn't record the run end: ${t.message}`,`warn`))}):await l.status(`idle`).catch(()=>{});let Se=this.#N();k===`succeeded`?Se.done++:k===`interrupted`?Se.stopped++:Se.failed++,Se.costMicros+=S.costMicros??0,Se.durationMs+=O;let Ce=Ma(S),Te=k===`succeeded`?V.ok(V.bold(k)):k===`failed`?V.err(V.bold(k)):V.warn(V.bold(k));return this.#T(e,[`${Te} in ${ja(O)}`,...Ce?Ce.split(`, `).map(e=>e.startsWith(`$`)?V.money(e):e):[]].join(` ${B(`·`)} `)+`${A?` ${V.err(`(${an(A)})`)}`:``}${S.summary?` ${B(`—`)} ${an(S.summary)}`:``}`,k===`succeeded`?`ok`:k===`failed`?`fail`:`warn`),k===`failed`?this.#D(e,this.#O(e)):(this.#n.delete(e.id),this.#D(e,xa)),{agent:e.name,status:k,tally:S,durationMs:O,work:{dir:m.dir,branch:m.branch,startSha:h},resumed:!!b}}async run(e={}){this.#h=!!e.once;let t=this.config.agents.filter(e=>!this.#C(e).disabledReason);for(let e of this.config.agents){let t=this.#C(e).disabledReason;t&&this.#T(e,`skipped: ${t}`,`idle`)}let n=this.config.machine;if(t.length===0&&!n)return this.#T(null,`nothing to run. Link this computer with \`${C} login\`.`,`warn`),[];if(e.once){let e=[];if(n){let t=await this.checkMachine();t.length===0&&!this.#d&&this.#T({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.#T(n,`nothing to do`,`idle`)}let r=n?setInterval(()=>void this.#A(),Ta):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.#T(null,`watching ${V.bold(i)} ${B(`(up to ${this.config.maxConcurrent} at once).${this.#g?``:` Ctrl-C to stop.`}`)}`,`start`);!this.#l;){let e=this.#a();if(n&&!this.#d&&(this.#t.get(Q)??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.#C(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.#d?this.#t.get(Q)??e:1/0),a=Math.max(1e3,Math.min(6e4,i-this.#a()));await new Promise(e=>{let t=setTimeout(e,a);this.#p=()=>{clearTimeout(t),e()}}),this.#p=null}return await Promise.all([...this.#e.values()].map(e=>e.done)),r}};const Ba=e=>Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e);function Va(e){for(let t=0;t<20;t++){let t;try{t=x(e,`utf8`).trim()}catch{return null}if(t)return Number(t)||0;Ba(25)}return 0}function Ha(e){if(!e||e===process.pid)return!1;try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function Ua(){let e=Va(s(N(),`runner.pid`));return e&&Ha(e)?e:null}function Wa(){let e=s(N(),`runner.pid`);y(N(),{recursive:!0,mode:448});let t=String(process.pid),n=()=>{try{x(e,`utf8`).trim()===t&&re(e,{force:!0})}catch{}};for(let r=0;r<3;r++){try{return ae(e,t,{mode:384,flag:`wx`}),n}catch(e){if(e.code!==`EEXIST`)throw e}let r=Va(e);if(r===null)continue;if(Ha(r))throw Error(`a runner is already going (pid ${r}). Stop it first, or see \`${C} status\`.`);let i=`${e}.${process.pid}.tmp`;if(ae(i,t,{mode:384}),ne(i,e),Ba(25),Va(e)===process.pid)return n}throw Error(`another runner is starting at the same moment. Try again, or see \`${C} status\`.`)}function Ga(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:String(n??t.msg??`ngrok failed`).replace(/\s+/g,` `).replace(/\bERR_NGROK_\d+\b.*$/,``).trim().slice(0,240)||`ngrok failed`}:null}function Ka(e,t=`127.0.0.1`){return new Promise(n=>{let r=S({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 qa={stopped_in_town:`Someone stopped it from the team's Settings.`,replaced:`It was shared again from this computer.`,machine_unlinked:`This computer was unlinked from the team.`,went_quiet:`This computer stopped checking in for a few minutes.`};async function Ja(e,t,r){let i=dr(`ngrok`);if(!i)throw Error(`sharing uses the ngrok program. Install it (brew install ngrok, or https://ngrok.com/download) and run this again. You don't need an ngrok account: your team provides the tunnel.`);if(!await Ka(t))throw Error(`nothing is running on 127.0.0.1:${t}. Start your app first, then share it.`);let a=new mt(e.api,()=>ar(e)),o=Bn(`Opening a link for 127.0.0.1:${t}`,{quiet:!0}),c;try{c=await a.openApp({name:r.name??``,port:t,access:r.public?`public`:`town`})}finally{o.stop()}let l=s(N(),`share`);y(l,{recursive:!0,mode:448});let u=s(l,`${c.app_id}.yml`);ae(u,`version: "3"
|
|
78
78
|
agent:
|
package/package.json
CHANGED