@crouton-kit/crouter 0.3.58 → 0.3.60
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/dist/clients/attach/attach-cmd.js +3 -3
- package/dist/commands/memory/read.js +8 -1
- package/dist/core/canvas/paths.d.ts +10 -0
- package/dist/core/canvas/paths.js +14 -0
- package/dist/core/substrate/render.js +7 -2
- package/dist/web-client/assets/index-72YQdji_.js +77 -0
- package/dist/web-client/assets/index-bDhImjJy.css +2 -0
- package/dist/web-client/index.html +2 -2
- package/package.json +1 -1
- package/dist/web-client/assets/index-BOlkXTJY.js +0 -77
- package/dist/web-client/assets/index-CllMPSPq.css +0 -2
|
@@ -1667,9 +1667,9 @@ CREATE TABLE IF NOT EXISTS canvas_meta (
|
|
|
1667
1667
|
`)};return{error:(n,o)=>r("error",n,o),warn:(n,o)=>r("warn",n,o),info:(n,o)=>r("info",n,o),debug:(n,o)=>r("debug",n,o)}}var For=5*6e4,J_o=500,X_o="generation turn",Z_o="fault.log";function YBe(e){return HBe(fu(e),"fault")}function KBe(e){return HBe(fu(e),"error-stall")}function Uor(e){return HBe(fu(e),Z_o)}function eyo(e){return e.slice(0,J_o)}function Lor(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}function tyo(e,t,r=!1){try{let n=JSON.parse(e),o=n.kind,s=typeof n.message=="string"?n.message:void 0,i=typeof n.since=="string"?n.since:void 0;if(o===void 0||s===void 0||i===void 0)return null;let a=n.link??(r?"pi\u2192provider":void 0),l=n.retry??{},u={disposition:l.disposition==="auto"||l.disposition==="manual"||l.disposition==="fatal"?l.disposition:r?"auto":"manual",...l.by==="sdk"||l.by==="daemon"||l.by==="client"?{by:l.by}:r?{by:"daemon"}:{},...typeof l.attempt=="number"?{attempt:l.attempt}:{},...typeof l.max=="number"?{max:l.max}:{},...typeof l.nextAt=="string"?{nextAt:l.nextAt}:{}};return{link:a??"pi\u2192provider",op:typeof n.op=="string"&&n.op!==""?n.op:X_o,kind:o,retry:u,message:s,since:i,logPath:typeof n.logPath=="string"&&n.logPath!==""?n.logPath:Uor(t),...typeof n.anchorEntryId=="string"&&n.anchorEntryId!==""?{anchorEntryId:n.anchorEntryId}:{}}}catch{return null}}function Bor(e,t,r=!1){try{return tyo(Y_o(e,"utf8"),t,r)}catch{return null}}function JBe(e){return Bor(YBe(e),e)??Bor(KBe(e),e,!0)}function ryo(e,t){try{H_o(fu(e),{recursive:!0}),K_o(YBe(e),JSON.stringify(t)),jBe(KBe(e),{force:!0})}catch{}}function nyo(e,t){let r=JBe(e);if(r!==null){if(r.link===t.link&&r.kind===t.kind){let n={...r.retry,...t.retry};t.retry.disposition==="fatal"&&!("nextAt"in t.retry)&&delete n.nextAt,t={...t,since:r.since,anchorEntryId:r.anchorEntryId??t.anchorEntryId,retry:n}}else if(Lor(r)>Lor(t))return}ryo(e,t)}function oyo(e){let t=WBe(e.retry.disposition==="fatal"?"warn":"info","fault",e.message,{link:e.link,op:e.op,kind:e.kind,retry:e.retry,since:e.since,logPath:e.logPath,anchorEntryId:e.anchorEntryId});Mor(e.logPath,t)}function Cre(e,t){let r={link:t.link,op:t.op,kind:t.kind,retry:t.retry,message:eyo(t.message),since:t.since??new Date().toISOString(),logPath:t.logPath??Uor(e),...typeof t.anchorEntryId=="string"&&t.anchorEntryId!==""?{anchorEntryId:t.anchorEntryId}:{}};oyo(r),nyo(e,r)}function zQ(e,t){try{let r=JBe(e);return r!==null&&t?.link!==void 0&&r.link!==t.link?!1:(jBe(YBe(e),{force:!0}),jBe(KBe(e),{force:!0}),r!==null)}catch{return!1}}function QQ(e){return JBe(e)}var syo={active:"\u25CF",idle:"\u25CB",done:"\u2713",dead:"\u2717",canceled:"\u2298"},iyo={active:32,idle:33,done:36,dead:31,canceled:90},ayo="\u27F3",cyo=92,lyo="\u26A0",uyo=33;function $or(e){switch(e){case"rate-limit":return"rate-limited";case"overloaded":return"overloaded";case"connection":return"down";case"auth":return"auth";case"protocol":return"protocol";case"wedged":return"wedged";default:return"other"}}function XBe(e,t){return t.hanging!=null?{glyph:lyo,color:uyo,word:$or(t.hanging.kind),bold:!0}:t.streaming===!0?{glyph:ayo,color:cyo,word:"live",bold:!0}:{glyph:syo[e]??"?",color:iyo[e]}}function pyo(e,t){let r=Date.parse(e);if(Number.isNaN(r))return"now";let n=r-t;return n<=0?"now":n>=6e4?`${Math.max(1,Math.round(n/6e4))}m`:`${Math.max(1,Math.ceil(n/1e3))}s`}function dyo(e){return e.retry.disposition!=="auto"}function myo(e,t=Date.now()){let r=e.retry;if(!dyo(e)){if(r.by==="client")return"redialing";let n=typeof r.attempt=="number"&&typeof r.max=="number"?`auto-retry ${r.attempt}/${r.max}`:"auto-retrying";return r.nextAt?`${n}, next ${pyo(r.nextAt,t)}`:n}return"needs you"}function ZBe(e,t=Date.now()){return`${e.link} ${$or(e.kind)} \xB7 ${myo(e,t)}`}function eFe(e,t){return t===null||t.link==="pi\u2192provider"&&t.retry.by==="daemon"&&t.retry.disposition==="auto"&&!Sp(e.pi_pid)?null:t}function Qor(e){if(e==null||e==="")return!1;let t;try{if(!zor(e))return!1;t=fyo(e,"utf8").split(`
|
|
1668
1668
|
`)}catch{return!1}for(let r of t){if(r===""||r.indexOf('"role":"assistant"')===-1&&r.indexOf('"role": "assistant"')===-1)continue;let n;try{n=JSON.parse(r)}catch{continue}if(!(n.type!=="message"||n.message?.role!=="assistant")&&gyo(n.message.content))return!0}return!1}function gyo(e){if(typeof e=="string")return e.trim()!=="";if(!Array.isArray(e))return!1;for(let t of e){if(t===null||typeof t!="object")continue;let r=t,n=(r.type??"").toLowerCase();if(n==="text"){if(typeof r.text=="string"&&r.text.trim()!=="")return!0}else if(n==="thinking"){if(typeof r.thinking=="string"&&r.thinking.trim()!=="")return!0}else return!0}return!1}function qor(e){return _yo(e,Hi(e)?.pi_pid??null)}function _yo(e,t){if(!Sp(t))return!1;try{return zor(hyo(fu(e),"busy"))}catch{return!1}}import{spawn as jSo}from"node:child_process";import{mkdirSync as mar,writeFileSync as HSo,readFileSync as YSo,existsSync as pUe,unlinkSync as KSo,openSync as JSo,closeSync as XSo}from"node:fs";import{dirname as ZSo,join as dUe,resolve as eTo,isAbsolute as tTo}from"node:path";import{fileURLToPath as far}from"node:url";import{connect as rTo}from"node:net";import{StringDecoder as yyo}from"node:string_decoder";function kv(e){return JSON.stringify(e)+`
|
|
1669
1669
|
`}var Nv=class extends Error{constructor(r,n,o){super(`frame decoder overflow (${r}): ${n} bytes exceeds cap ${o}`);this.kind=r;this.bytes=n;this.cap=o;this.name="FrameOverflowError"}kind;bytes;cap},Ire={maxLineBytes:256*1024*1024,maxTotalBytes:256*1024*1024},Gor={maxLineBytes:24*1024*1024,maxTotalBytes:48*1024*1024},GM=class{constructor(t){this.caps=t}caps;parts=[];partBytes=0;utf8=new yyo("utf8");push(t){let r=typeof t=="string"?t:this.utf8.write(t),n=Buffer.byteLength(r);if(this.partBytes+n>this.caps.maxTotalBytes)throw new Nv("total",this.partBytes+n,this.caps.maxTotalBytes);let o=[],s=0,i;for(;(i=r.indexOf(`
|
|
1670
|
-
`,s))>=0;){let a=r.slice(s,i),l=(this.parts.length>0?this.parts.join("")+a:a).trim();if(this.parts.length=0,this.partBytes=0,s=i+1,l!=="")try{o.push(JSON.parse(l))}catch{}}if(s<r.length){let a=s===0?r:r.slice(s);this.parts.push(a),this.partBytes+=s===0?n:Buffer.byteLength(a)}if(this.partBytes>this.caps.maxLineBytes)throw new Nv("line",this.partBytes,this.caps.maxLineBytes);return o}};import{existsSync as Yor,mkdirSync as wYa,readdirSync as wyo,readFileSync as Ryo,realpathSync as RYa,renameSync as NYa,rmSync as kYa,statSync as OYa,writeFileSync as PYa}from"node:fs";import{dirname as MYa,join as Kor,resolve as LYa,sep as BYa}from"node:path";import{homedir as Eyo}from"node:os";import{existsSync as byo,statSync as Syo}from"node:fs";import{join as Wor,resolve as jor,dirname as Tyo}from"node:path";var Vor=new Map;function xyo(e,t){return`${e}\0${t??""}`}function qQ(){return Wor(Eyo(),ay)}function Cyo(e,t){if(e===t||!byo(e))return!1;try{return Syo(e).isDirectory()}catch{return!1}}function Iyo(e=process.cwd()){return Hor(e)[0]??null}function vyo(e,t){let r=[],n=jor(e);for(;;){let o=Wor(n,ay);Cyo(o,t)&&r.push(o);let s=Tyo(n);if(s===n)return r;n=s}}function Hor(e=process.cwd(),t=process.env.CRTR_PROFILE_ID||null){let r=jor(e),n=xyo(r,t),o=Vor.get(n);if(o!==void 0)return o;let s=qQ(),i=[r];if(t!==null&&t!=="")try{let{manifest:u}=Ov(t);i.push(...u.projects)}catch{}let a=new Set,l=[];for(let u of i)for(let c of vyo(u,s))a.has(c)||(a.add(c),l.push(c));return Vor.set(n,l),l}function vre(e){return Iyo(e)}function tFe(e){return e==="builtin"?null:e==="user"?qQ():vre()}var Jor=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/;function Nyo(){return Kor(qQ(),hor)}function kyo(e){if(!Yor(e))return null;try{return JSON.parse(Ryo(e,"utf8"))}catch{return null}}function Xor(){let e=Nyo();if(!Yor(e))return[];let t=[];for(let r of wyo(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let n=r.name;if(!Jor.test(n))continue;let o=kyo(Kor(e,n,"profile.json"));o!==null&&t.push({profileId:n,manifest:o})}return t}function Ov(e){let t=Xor();if(Jor.test(e)){let n=t.find(o=>o.profileId===e);if(n!==void 0)return n}let r=t.filter(n=>n.manifest.name===e);if(r.length===1)return r[0];if(r.length>1){let n=r.map(o=>o.profileId);throw OBe(`profile name "${e}" matches ${n.length} profiles: ${n.join(", ")}`,{received:e,candidates:n,next:`Re-run with one exact profile id: ${n.join(", ")}.`})}throw kBe(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles, or `crtr profile new --name <name>` to create one."})}import{createInterface as rKa}from"node:readline/promises";var oE={reset:"\x1B[0m",dim:"\x1B[2m",bold:"\x1B[1m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",cyan:"\x1B[36m",gray:"\x1B[90m"};function Pyo(e){return process.env.NO_COLOR?!1:process.env.FORCE_COLOR?!0:!!e.isTTY}function gx(e,t,r){return Pyo(e)?`${t}${r}${oE.reset}`:r}var wre={dim:e=>gx(process.stdout,oE.dim,e),bold:e=>gx(process.stdout,oE.bold,e),red:e=>gx(process.stdout,oE.red,e),green:e=>gx(process.stdout,oE.green,e),yellow:e=>gx(process.stdout,oE.yellow,e),blue:e=>gx(process.stdout,oE.blue,e),cyan:e=>gx(process.stdout,oE.cyan,e),gray:e=>gx(process.stdout,oE.gray,e)};var iKa=wre.dim,aKa=wre.bold,cKa=wre.cyan;import{existsSync as Gyo,mkdirSync as CKa,writeFileSync as IKa}from"node:fs";import{dirname as Vyo,join as rsr}from"node:path";import{fileURLToPath as Wyo}from"node:url";import{join as Dyo}from"node:path";function Myo(e){return Dyo(e,wBe)}function rFe(e){let t=tFe(e);if(!t)return yre();let r=FQ(Myo(t));return r?qyo(r):yre()}function Lyo(e){return typeof e=="string"&&e!==""?{desc:e}:{}}function Byo(e){if(e===null||typeof e!="object")return null;let t=e,r=typeof t.key=="string"&&t.key!==""?t.key:null,n=typeof t.desc=="string"&&t.desc!==""?t.desc:null,o=tsr(t.action);if(r===null||n===null||o===null)return null;let s={key:r,desc:n,action:o};return t.confirm===!0&&(s.confirm=!0),s}function tsr(e){if(e===null||typeof e!="object")return null;let t=e,r=Lyo(t.desc),n=t.confirm===!0?{confirm:!0}:{};if(typeof t.run=="string"){if(t.run==="__graph__")return{kind:"keys",keys:"/graph",...r};if(t.run==="__issue__")return{kind:"menu",items:[{key:"i",desc:"idea",action:{kind:"popup",run:"canvas issue new --type idea"}},{key:"b",desc:"bug",action:{kind:"popup",run:"canvas issue new --type bug"}}],...r}}if(t.kind==="keys"&&typeof t.keys=="string")return{kind:"keys",keys:t.keys,...r};if(t.kind==="popup"&&typeof t.run=="string")return{kind:"popup",run:t.run,...r};if(t.kind==="menu"&&Array.isArray(t.items)){let o=t.items.map(Byo).filter(s=>s!==null);return o.length!==t.items.length?null:{kind:"menu",items:o,...r}}return(t.kind===void 0||t.kind==="crtr")&&typeof t.run=="string"?{kind:"crtr",run:t.run,...n,...r}:t.kind===void 0&&typeof t.keys=="string"?{kind:"keys",keys:t.keys,...r}:null}function Fyo(e){if(e===null||typeof e!="object")return null;let t=e;return typeof t.run!="string"?null:{run:t.run,...t.confirm===!0?{confirm:!0}:{},...typeof t.desc=="string"&&t.desc!==""?{desc:t.desc}:{}}}function Zor(e,t,r){let n={...e};if(t!==null&&typeof t=="object")for(let[o,s]of Object.entries(t)){let i=r(s);i!==null&&(n[o]=i)}return n}function Uyo(e){let t=DQ();if(e===null||typeof e!="object")return t;let r=e;return{prefixKey:typeof r.prefixKey=="string"&&r.prefixKey.trim()!==""?r.prefixKey:t.prefixKey,prefixBinds:Zor(t.prefixBinds,r.prefixBinds,tsr),graphBinds:Zor(t.graphBinds,r.graphBinds,Fyo)}}function $yo(e,t=NBe()){let r=t;if(e===null||typeof e!="object")return r;let n=e,o={anthropic:{...r.anthropic},openai:{...r.openai},...r.defaultProvider!==void 0?{defaultProvider:r.defaultProvider}:{}};(n.defaultProvider==="anthropic"||n.defaultProvider==="openai")&&(o.defaultProvider=n.defaultProvider);for(let s of["anthropic","openai"]){let i=n[s];if(!(i===null||typeof i!="object"))for(let[a,l]of Object.entries(i))(a==="ultra"||a==="strong"||a==="medium"||a==="light")&&typeof l=="string"&&(o[s][a]=l)}return o}function zyo(e){if(e===null||typeof e!="object")return null;let t=e;if(typeof t.whenToUse!="string"||t.whenToUse.trim()==="")return null;let r={whenToUse:t.whenToUse};typeof t.model=="string"&&t.model.trim()!==""&&(r.model=t.model),typeof t.orchestratorModel=="string"&&t.orchestratorModel.trim()!==""&&(r.orchestratorModel=t.orchestratorModel);let n=o=>Array.isArray(o)&&o.every(s=>typeof s=="string");return n(t.tools)&&(r.tools=t.tools),n(t.extensions)&&(r.extensions=t.extensions),n(t.availableTo)&&(r.availableTo=t.availableTo),r}function Qyo(e,t=RBe()){let r={...t};if(e!==null&&typeof e=="object")for(let[n,o]of Object.entries(e)){let s=zyo(o);s!==null&&(r[n]=s)}return r}function esr(e,t){return e===!0?"notify":e===!1?!1:e==="notify"||e==="apply"?e:t}function qyo(e){let t=yre(),r=t.schema_version,n=e.marketplaces===void 0?{}:e.marketplaces,o=e.plugins===void 0?{}:e.plugins,s=e.auto_update,i=s&&typeof s.interval_hours=="number"?s.interval_hours:void 0,a=i!==void 0&&Number.isFinite(i)&&i>=0?i:t.auto_update.interval_hours,l={crtr:esr(s?.crtr,t.auto_update.crtr),content:esr(s?.content,t.auto_update.content),interval_hours:a},u=e.max_panes_per_window,c=typeof u=="number"&&Number.isFinite(u)&&u>=1?Math.floor(u):t.max_panes_per_window,p=Uyo(e.canvasNav),d=$yo(e.modelLadders),f=Qyo(e.kinds);return{schema_version:r,marketplaces:n,plugins:o,auto_update:l,max_panes_per_window:c,canvasNav:p,modelLadders:d,kinds:f}}function sE(e){let t=Vyo(Wyo(import.meta.url)),r=[rsr(t,"..","..","pi-extensions",`${e}.js`),rsr(t,"..","..","pi-extensions",`${e}.ts`)];return r.find(n=>Gyo(n))??r[0]}var PKa=sE("canvas-stophook"),DKa=sE("canvas-inbox-watcher"),MKa=sE("canvas-nav"),LKa=sE("canvas-recap"),BKa=sE("canvas-goal-capture"),FKa=sE("canvas-passive-context"),UKa=sE("canvas-context-intro"),$Ka=sE("canvas-doc-substrate"),zKa=sE("canvas-structured-output");var Nbo=ni(Gir(),1);var ear="Each %s below shows either its full content (indented beneath its name), a `# read when:` line telling you when to read the full document, or simply its name.",_Ja="Preferences are how the user wants you to behave \u2014 standing directives and corrections. To read a preference, run `crtr memory read <name>`. "+ear.replace("%s","preference");var yJa="Knowledge documents are what you consult \u2014 playbooks and techniques for how to do things, and references on the user, projects, and this node. They are aggregated from your memory stores: user-global (`~/.crouter/memory/`), every ancestor project store (`<dir>/.crouter/memory/`) from the cwd upward, the selected profile's memory store (when one is selected), and node-local (this node's `context/memory/`). To read one, run `crtr memory read <name>`. Each doc exists to prevent a specific mistake you would make without it, so when your task matches one \u2014 by its name or its `# read when:` line \u2014 read it before you act; consulting it only after the work is done forfeits the entire reason it exists. "+ear.replace("%s","document");import{spawnSync as Hbo}from"node:child_process";var Wbo=Symbol.for("@earendil-works/pi-coding-agent:theme");function tar(){return globalThis[Wbo]??void 0}function rar(){let e=tar();if(e===void 0)throw new Error("surfaceBgAnsi: pi theme not initialized in this process");return e.getBgAnsi("selectedBg")}function jbo(){let e=tar();if(e===void 0)return;let t=e.getBgAnsi("selectedBg"),r=/48;2;(\d+);(\d+);(\d+)/.exec(t);if(r!==null){let o=s=>Number(s).toString(16).padStart(2,"0");return`#${o(r[1])}${o(r[2])}${o(r[3])}`}let n=/48;5;(\d+)/.exec(t);if(n!==null)return`colour${n[1]}`}function ane(){let e=jbo();return e===void 0?[]:["-b","rounded","-s",`bg=${e}`,"-S",`bg=${e}`]}function $v(e){return`'${e.replace(/'/g,"'\\''")}'`}function eq(e){let t=Hbo("tmux",e,{encoding:"utf8"});return{ok:t.status===0,stdout:(t.stdout??"").trim(),stderr:(t.stderr??"").trim()}}function tq(){return process.env.TMUX!==void 0&&process.env.TMUX!==""}function rq(){if(!tq())return null;let e=eq(["display-message","-p","#{session_name} #{window_id} #{pane_id}"]);if(!e.ok)return null;let[t,r,n]=e.stdout.split(" ");return{session:t,window:r,pane:n}}function rUe(e){return eq(["kill-pane","-t",e]).ok}function cne(e){let t=eq(["display-message","-p","-t",e,"#{pane_id}"]);return t.ok&&t.stdout===e}function lne(e,t,r){return eq(["set-option","-p","-t",e,t,r]).ok}function Uv(e){return e.replace(/#/g,"##")}function Ybo(e){return`run-shell ${$v(e)}`}function Kbo(e){return e.map($v).join(" ")}function Jbo(e){return Ybo(`crtr canvas chord --pane '#{pane_id}' --run ${$v(Uv(e))} >/dev/null 2>&1`)}function Xbo(e){return`display-popup -E -w 60% -h 50% -d "#{pane_current_path}" ${$v(`crtr canvas chord --pane '#{pane_id}' --run ${$v(Uv(e))} --interactive`)}`}function Zbo(e){return`send-keys -t '#{pane_id}' ${$v(Uv(e))} Enter`}function nar(e,t){let r=Uv(e),n=["display-menu","-T",`#[align=centre]${r}`,...ane()],o=Math.max(r.length,...t.map(a=>Uv(a.desc).length))+6;n.push("-x",`#{e|-:#{pane_right},${o+1}}`,"-y","#{e|+:#{pane_top},3}");for(let a of t)n.push(Uv(a.desc),Uv(a.key),eSo(a.action,a.desc));return n.push("-esc / q to close","",""),n}function eSo(e,t){let r=e.kind??"crtr";switch(r){case"keys":return Zbo(e.keys);case"popup":return Xbo(e.run);case"menu":return Kbo(nar(t,e.items));case"crtr":return Jbo(e.run);default:throw new Error(`unknown canvas action kind: ${r}`)}}function nq(){let e;try{e=rFe("user").canvasNav.prefixBinds}catch{e=DQ().prefixBinds}let t=[];for(let[r,n]of Object.entries(e)){if(r.length!==1)continue;let o=n.desc??`chord ${r}`;t.push({key:r,desc:o,action:n})}return eq(["bind-key","-n","M-c",...nar(" crtr ",t)]).ok}import{copyFileSync as oSo,mkdirSync as sSo,existsSync as une,readFileSync as iSo,writeFileSync as aSo,chmodSync as cSo,readdirSync as lSo,renameSync as uSo,realpathSync as oar,unlinkSync as pSo}from"node:fs";import{homedir as dSo}from"node:os";import{dirname as mSo,join as lE}from"node:path";import{spawnSync as nUe}from"node:child_process";var fSo="crouter";function zv(){return lE(dSo(),ay,"host")}function hSo(){return lE(zv(),fSo)}function aar(){return lE(zv(),".source.json")}function gSo(e){let t=mSo(e);for(let r of[t,lE(t,"..","lib")]){if(!une(r))continue;let n=lSo(r).find(o=>o.startsWith("libnode.")&&o.endsWith(".dylib"));if(n!==void 0)return lE(r,n)}return null}function sar(e,t,r){let n=`${t}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`;oSo(e,n),r!==void 0&&cSo(n,r),uSo(n,t)}function _So(){try{return JSON.parse(iSo(aar(),"utf8"))}catch{return null}}function ySo(e={}){let t=e.configured?.trim();return t?[t]:[e.discovered?.trim()||"-"]}function ASo(){if(process.platform!=="darwin")return null;let e=nUe("security",["find-identity","-v","-p","codesigning"],{stdio:["pipe","pipe","pipe"]});if(e.status!==0)return null;let r=(e.stdout??"").toString().split(`
|
|
1670
|
+
`,s))>=0;){let a=r.slice(s,i),l=(this.parts.length>0?this.parts.join("")+a:a).trim();if(this.parts.length=0,this.partBytes=0,s=i+1,l!=="")try{o.push(JSON.parse(l))}catch{}}if(s<r.length){let a=s===0?r:r.slice(s);this.parts.push(a),this.partBytes+=s===0?n:Buffer.byteLength(a)}if(this.partBytes>this.caps.maxLineBytes)throw new Nv("line",this.partBytes,this.caps.maxLineBytes);return o}};import{existsSync as Yor,mkdirSync as wYa,readdirSync as wyo,readFileSync as Ryo,realpathSync as RYa,renameSync as NYa,rmSync as kYa,statSync as OYa,writeFileSync as PYa}from"node:fs";import{dirname as MYa,join as Kor,resolve as LYa,sep as BYa}from"node:path";import{homedir as Eyo}from"node:os";import{existsSync as byo,statSync as Syo}from"node:fs";import{join as Wor,resolve as jor,dirname as Tyo}from"node:path";var Vor=new Map;function xyo(e,t){return`${e}\0${t??""}`}function qQ(){return Wor(Eyo(),ay)}function Cyo(e,t){if(e===t||!byo(e))return!1;try{return Syo(e).isDirectory()}catch{return!1}}function Iyo(e=process.cwd()){return Hor(e)[0]??null}function vyo(e,t){let r=[],n=jor(e);for(;;){let o=Wor(n,ay);Cyo(o,t)&&r.push(o);let s=Tyo(n);if(s===n)return r;n=s}}function Hor(e=process.cwd(),t=process.env.CRTR_PROFILE_ID||null){let r=jor(e),n=xyo(r,t),o=Vor.get(n);if(o!==void 0)return o;let s=qQ(),i=[r];if(t!==null&&t!=="")try{let{manifest:u}=Ov(t);i.push(...u.projects)}catch{}let a=new Set,l=[];for(let u of i)for(let c of vyo(u,s))a.has(c)||(a.add(c),l.push(c));return Vor.set(n,l),l}function vre(e){return Iyo(e)}function tFe(e){return e==="builtin"?null:e==="user"?qQ():vre()}var Jor=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/;function Nyo(){return Kor(qQ(),hor)}function kyo(e){if(!Yor(e))return null;try{return JSON.parse(Ryo(e,"utf8"))}catch{return null}}function Xor(){let e=Nyo();if(!Yor(e))return[];let t=[];for(let r of wyo(e,{withFileTypes:!0})){if(!r.isDirectory())continue;let n=r.name;if(!Jor.test(n))continue;let o=kyo(Kor(e,n,"profile.json"));o!==null&&t.push({profileId:n,manifest:o})}return t}function Ov(e){let t=Xor();if(Jor.test(e)){let n=t.find(o=>o.profileId===e);if(n!==void 0)return n}let r=t.filter(n=>n.manifest.name===e);if(r.length===1)return r[0];if(r.length>1){let n=r.map(o=>o.profileId);throw OBe(`profile name "${e}" matches ${n.length} profiles: ${n.join(", ")}`,{received:e,candidates:n,next:`Re-run with one exact profile id: ${n.join(", ")}.`})}throw kBe(`profile not found: ${e}`,{received:e,next:"Run `crtr profile list` to see available profiles, or `crtr profile new --name <name>` to create one."})}import{createInterface as rKa}from"node:readline/promises";var oE={reset:"\x1B[0m",dim:"\x1B[2m",bold:"\x1B[1m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",cyan:"\x1B[36m",gray:"\x1B[90m"};function Pyo(e){return process.env.NO_COLOR?!1:process.env.FORCE_COLOR?!0:!!e.isTTY}function gx(e,t,r){return Pyo(e)?`${t}${r}${oE.reset}`:r}var wre={dim:e=>gx(process.stdout,oE.dim,e),bold:e=>gx(process.stdout,oE.bold,e),red:e=>gx(process.stdout,oE.red,e),green:e=>gx(process.stdout,oE.green,e),yellow:e=>gx(process.stdout,oE.yellow,e),blue:e=>gx(process.stdout,oE.blue,e),cyan:e=>gx(process.stdout,oE.cyan,e),gray:e=>gx(process.stdout,oE.gray,e)};var iKa=wre.dim,aKa=wre.bold,cKa=wre.cyan;import{existsSync as Gyo,mkdirSync as CKa,writeFileSync as IKa}from"node:fs";import{dirname as Vyo,join as rsr}from"node:path";import{fileURLToPath as Wyo}from"node:url";import{join as Dyo}from"node:path";function Myo(e){return Dyo(e,wBe)}function rFe(e){let t=tFe(e);if(!t)return yre();let r=FQ(Myo(t));return r?qyo(r):yre()}function Lyo(e){return typeof e=="string"&&e!==""?{desc:e}:{}}function Byo(e){if(e===null||typeof e!="object")return null;let t=e,r=typeof t.key=="string"&&t.key!==""?t.key:null,n=typeof t.desc=="string"&&t.desc!==""?t.desc:null,o=tsr(t.action);if(r===null||n===null||o===null)return null;let s={key:r,desc:n,action:o};return t.confirm===!0&&(s.confirm=!0),s}function tsr(e){if(e===null||typeof e!="object")return null;let t=e,r=Lyo(t.desc),n=t.confirm===!0?{confirm:!0}:{};if(typeof t.run=="string"){if(t.run==="__graph__")return{kind:"keys",keys:"/graph",...r};if(t.run==="__issue__")return{kind:"menu",items:[{key:"i",desc:"idea",action:{kind:"popup",run:"canvas issue new --type idea"}},{key:"b",desc:"bug",action:{kind:"popup",run:"canvas issue new --type bug"}}],...r}}if(t.kind==="keys"&&typeof t.keys=="string")return{kind:"keys",keys:t.keys,...r};if(t.kind==="popup"&&typeof t.run=="string")return{kind:"popup",run:t.run,...r};if(t.kind==="menu"&&Array.isArray(t.items)){let o=t.items.map(Byo).filter(s=>s!==null);return o.length!==t.items.length?null:{kind:"menu",items:o,...r}}return(t.kind===void 0||t.kind==="crtr")&&typeof t.run=="string"?{kind:"crtr",run:t.run,...n,...r}:t.kind===void 0&&typeof t.keys=="string"?{kind:"keys",keys:t.keys,...r}:null}function Fyo(e){if(e===null||typeof e!="object")return null;let t=e;return typeof t.run!="string"?null:{run:t.run,...t.confirm===!0?{confirm:!0}:{},...typeof t.desc=="string"&&t.desc!==""?{desc:t.desc}:{}}}function Zor(e,t,r){let n={...e};if(t!==null&&typeof t=="object")for(let[o,s]of Object.entries(t)){let i=r(s);i!==null&&(n[o]=i)}return n}function Uyo(e){let t=DQ();if(e===null||typeof e!="object")return t;let r=e;return{prefixKey:typeof r.prefixKey=="string"&&r.prefixKey.trim()!==""?r.prefixKey:t.prefixKey,prefixBinds:Zor(t.prefixBinds,r.prefixBinds,tsr),graphBinds:Zor(t.graphBinds,r.graphBinds,Fyo)}}function $yo(e,t=NBe()){let r=t;if(e===null||typeof e!="object")return r;let n=e,o={anthropic:{...r.anthropic},openai:{...r.openai},...r.defaultProvider!==void 0?{defaultProvider:r.defaultProvider}:{}};(n.defaultProvider==="anthropic"||n.defaultProvider==="openai")&&(o.defaultProvider=n.defaultProvider);for(let s of["anthropic","openai"]){let i=n[s];if(!(i===null||typeof i!="object"))for(let[a,l]of Object.entries(i))(a==="ultra"||a==="strong"||a==="medium"||a==="light")&&typeof l=="string"&&(o[s][a]=l)}return o}function zyo(e){if(e===null||typeof e!="object")return null;let t=e;if(typeof t.whenToUse!="string"||t.whenToUse.trim()==="")return null;let r={whenToUse:t.whenToUse};typeof t.model=="string"&&t.model.trim()!==""&&(r.model=t.model),typeof t.orchestratorModel=="string"&&t.orchestratorModel.trim()!==""&&(r.orchestratorModel=t.orchestratorModel);let n=o=>Array.isArray(o)&&o.every(s=>typeof s=="string");return n(t.tools)&&(r.tools=t.tools),n(t.extensions)&&(r.extensions=t.extensions),n(t.availableTo)&&(r.availableTo=t.availableTo),r}function Qyo(e,t=RBe()){let r={...t};if(e!==null&&typeof e=="object")for(let[n,o]of Object.entries(e)){let s=zyo(o);s!==null&&(r[n]=s)}return r}function esr(e,t){return e===!0?"notify":e===!1?!1:e==="notify"||e==="apply"?e:t}function qyo(e){let t=yre(),r=t.schema_version,n=e.marketplaces===void 0?{}:e.marketplaces,o=e.plugins===void 0?{}:e.plugins,s=e.auto_update,i=s&&typeof s.interval_hours=="number"?s.interval_hours:void 0,a=i!==void 0&&Number.isFinite(i)&&i>=0?i:t.auto_update.interval_hours,l={crtr:esr(s?.crtr,t.auto_update.crtr),content:esr(s?.content,t.auto_update.content),interval_hours:a},u=e.max_panes_per_window,c=typeof u=="number"&&Number.isFinite(u)&&u>=1?Math.floor(u):t.max_panes_per_window,p=Uyo(e.canvasNav),d=$yo(e.modelLadders),f=Qyo(e.kinds);return{schema_version:r,marketplaces:n,plugins:o,auto_update:l,max_panes_per_window:c,canvasNav:p,modelLadders:d,kinds:f}}function sE(e){let t=Vyo(Wyo(import.meta.url)),r=[rsr(t,"..","..","pi-extensions",`${e}.js`),rsr(t,"..","..","pi-extensions",`${e}.ts`)];return r.find(n=>Gyo(n))??r[0]}var PKa=sE("canvas-stophook"),DKa=sE("canvas-inbox-watcher"),MKa=sE("canvas-nav"),LKa=sE("canvas-recap"),BKa=sE("canvas-goal-capture"),FKa=sE("canvas-passive-context"),UKa=sE("canvas-context-intro"),$Ka=sE("canvas-doc-substrate"),zKa=sE("canvas-structured-output");var Nbo=ni(Gir(),1);var ear="Each %s below shows either its full content (indented beneath its name), a `# read when:` line telling you when to read the full document, or simply its name.",AJa="Preferences are how the user wants you to behave \u2014 standing directives and corrections. To read a preference, run `crtr memory read <name>`. "+ear.replace("%s","preference");var EJa="Knowledge documents are what you consult \u2014 playbooks and techniques for how to do things, and references on the user, projects, and this node. They are aggregated from your memory stores: user-global (`~/.crouter/memory/`), every ancestor project store (`<dir>/.crouter/memory/`) from the cwd upward, the selected profile's memory store (when one is selected), and node-local (this node's `context/memory/`). To read one, run `crtr memory read <name>`. Each doc exists to prevent a specific mistake you would make without it, so when your task matches one \u2014 by its name or its `# read when:` line \u2014 read it before you act; consulting it only after the work is done forfeits the entire reason it exists. "+ear.replace("%s","document");import{spawnSync as Hbo}from"node:child_process";var Wbo=Symbol.for("@earendil-works/pi-coding-agent:theme");function tar(){return globalThis[Wbo]??void 0}function rar(){let e=tar();if(e===void 0)throw new Error("surfaceBgAnsi: pi theme not initialized in this process");return e.getBgAnsi("selectedBg")}function jbo(){let e=tar();if(e===void 0)return;let t=e.getBgAnsi("selectedBg"),r=/48;2;(\d+);(\d+);(\d+)/.exec(t);if(r!==null){let o=s=>Number(s).toString(16).padStart(2,"0");return`#${o(r[1])}${o(r[2])}${o(r[3])}`}let n=/48;5;(\d+)/.exec(t);if(n!==null)return`colour${n[1]}`}function ane(){let e=jbo();return e===void 0?[]:["-b","rounded","-s",`bg=${e}`,"-S",`bg=${e}`]}function $v(e){return`'${e.replace(/'/g,"'\\''")}'`}function eq(e){let t=Hbo("tmux",e,{encoding:"utf8"});return{ok:t.status===0,stdout:(t.stdout??"").trim(),stderr:(t.stderr??"").trim()}}function tq(){return process.env.TMUX!==void 0&&process.env.TMUX!==""}function rq(){if(!tq())return null;let e=eq(["display-message","-p","#{session_name} #{window_id} #{pane_id}"]);if(!e.ok)return null;let[t,r,n]=e.stdout.split(" ");return{session:t,window:r,pane:n}}function rUe(e){return eq(["kill-pane","-t",e]).ok}function cne(e){let t=eq(["display-message","-p","-t",e,"#{pane_id}"]);return t.ok&&t.stdout===e}function lne(e,t,r){return eq(["set-option","-p","-t",e,t,r]).ok}function Uv(e){return e.replace(/#/g,"##")}function Ybo(e){return`run-shell ${$v(e)}`}function Kbo(e){return e.map($v).join(" ")}function Jbo(e){return Ybo(`crtr canvas chord --pane '#{pane_id}' --run ${$v(Uv(e))} >/dev/null 2>&1`)}function Xbo(e){return`display-popup -E -w 60% -h 50% -d "#{pane_current_path}" ${$v(`crtr canvas chord --pane '#{pane_id}' --run ${$v(Uv(e))} --interactive`)}`}function Zbo(e){return`send-keys -t '#{pane_id}' ${$v(Uv(e))} Enter`}function nar(e,t){let r=Uv(e),n=["display-menu","-T",`#[align=centre]${r}`,...ane()],o=Math.max(r.length,...t.map(a=>Uv(a.desc).length))+6;n.push("-x",`#{e|-:#{pane_right},${o+1}}`,"-y","#{e|+:#{pane_top},3}");for(let a of t)n.push(Uv(a.desc),Uv(a.key),eSo(a.action,a.desc));return n.push("-esc / q to close","",""),n}function eSo(e,t){let r=e.kind??"crtr";switch(r){case"keys":return Zbo(e.keys);case"popup":return Xbo(e.run);case"menu":return Kbo(nar(t,e.items));case"crtr":return Jbo(e.run);default:throw new Error(`unknown canvas action kind: ${r}`)}}function nq(){let e;try{e=rFe("user").canvasNav.prefixBinds}catch{e=DQ().prefixBinds}let t=[];for(let[r,n]of Object.entries(e)){if(r.length!==1)continue;let o=n.desc??`chord ${r}`;t.push({key:r,desc:o,action:n})}return eq(["bind-key","-n","M-c",...nar(" crtr ",t)]).ok}import{copyFileSync as oSo,mkdirSync as sSo,existsSync as une,readFileSync as iSo,writeFileSync as aSo,chmodSync as cSo,readdirSync as lSo,renameSync as uSo,realpathSync as oar,unlinkSync as pSo}from"node:fs";import{homedir as dSo}from"node:os";import{dirname as mSo,join as lE}from"node:path";import{spawnSync as nUe}from"node:child_process";var fSo="crouter";function zv(){return lE(dSo(),ay,"host")}function hSo(){return lE(zv(),fSo)}function aar(){return lE(zv(),".source.json")}function gSo(e){let t=mSo(e);for(let r of[t,lE(t,"..","lib")]){if(!une(r))continue;let n=lSo(r).find(o=>o.startsWith("libnode.")&&o.endsWith(".dylib"));if(n!==void 0)return lE(r,n)}return null}function sar(e,t,r){let n=`${t}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`;oSo(e,n),r!==void 0&&cSo(n,r),uSo(n,t)}function _So(){try{return JSON.parse(iSo(aar(),"utf8"))}catch{return null}}function ySo(e={}){let t=e.configured?.trim();return t?[t]:[e.discovered?.trim()||"-"]}function ASo(){if(process.platform!=="darwin")return null;let e=nUe("security",["find-identity","-v","-p","codesigning"],{stdio:["pipe","pipe","pipe"]});if(e.status!==0)return null;let r=(e.stdout??"").toString().split(`
|
|
1671
1671
|
`).map(n=>n.match(/\)\s+[A-Fa-f0-9]{40}\s+"([^"]+)"/)?.[1]??null).filter(n=>n!==null);return r.find(n=>n.startsWith("Apple Development:"))??r.find(n=>n.startsWith("Developer ID Application:"))??r[0]??null}function ESo(e,t){let r=nUe("codesign",["-s",t,"--deep","--force",e],{stdio:["pipe","pipe","pipe"]});return{ok:r.status===0,stderr:(r.stderr??"").toString().trim()}}function bSo(e){if(process.platform==="darwin")try{let t=ySo({configured:process.env.CRTR_CODESIGN_IDENTITY,discovered:ASo()}),r="";for(let n of t){let o=ESo(e,n);if(o.ok)return;r=o.stderr}r&&!r.includes("valid on disk")&&console.debug(`[crouter] codesign failed (expected on some systems): ${r}`)}catch{}}function SSo(e,t,r=bSo){t!==null&&r(t),r(e)}var iar=!1;function TSo(e){try{return nUe(e,["-e",""],{stdio:"ignore",timeout:2e3}).status===0}catch{return!1}}function xSo(e){if(!iar){iar=!0;try{process.stderr.write(`[crouter] branded host ${e} failed its startup check; using ${process.execPath} for broker/daemon processes.
|
|
1672
|
-
`)}catch{}}}function CSo(){let e=hSo(),t=oar(process.execPath);if(une(e)&&oar(e)===t)return e;let r=_So(),n=gSo(t),o=n!==null?n.split("/").pop():null;if(une(e)&&r!==null&&r.version===2&&r.source===t&&r.libnode===o&&(o===null||une(lE(zv(),o))))return e;if(sSo(zv(),{recursive:!0}),r?.libnode!=null&&r.libnode!==o)try{pSo(lE(zv(),r.libnode))}catch{}return n!==null&&o!==null&&sar(n,lE(zv(),o)),sar(t,e,493),SSo(e,o!==null?lE(zv(),o):null),aSo(aar(),JSON.stringify({version:2,source:t,libnode:o})),e}function oUe(){if(process.env.CRTR_BRANDED_HOST==="0"||process.platform!=="darwin"||import.meta.url.endsWith(".ts"))return process.execPath;let e=CSo();return TSo(e)?e:(xSo(e),process.execPath)}import{existsSync as ISo,writeFileSync as z8a,rmSync as Q8a,mkdirSync as q8a,statSync as G8a}from"node:fs";import{join as vSo}from"node:path";function wSo(e){return vSo(fu(e),"busy")}function sUe(e){return ISo(wSo(e))}function cUe(e){return typeof e=="object"&&e!==null}function lUe(e){return typeof e=="string"?e:""}function lar(e){let t=e??"";return/rate.?limit|\b429\b|too many requests|quota/i.test(t)?"rate-limit":/overloaded|\b529\b|\b503\b|capacity|server.{0,3}busy|temporarily unavailable/i.test(t)?"overloaded":/invalid_grant|refresh token|unauthori[sz]ed|invalid.?api.?key|authentication failed|\b401\b|\b403\b/i.test(t)?"auth":/connection|econnreset|etimedout|enotfound|econnrefused|network|fetch failed|socket hang|timed? out|timeout/i.test(t)?"connection":"other"}function DSo(e){let t=lUe(e.code)||lUe(e.errno);return t===""?null:/^(ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOENT|ENOTFOUND|EAI_AGAIN|EPIPE|EHOSTUNREACH|ENETUNREACH)$/i.test(t)?"connection":null}function MSo(e){let t=typeof e.status=="number"?e.status:null;return t===null?null:t===401||t===403?"auth":t===429?"rate-limit":t===503||t===529||t>=500&&t<=599?"overloaded":t>=400&&t<=499?"protocol":null}function LSo(e){let t=typeof e.code=="number"?e.code:null;if(t===null)return null;if(t===1008)return"protocol";if(t===1006)return"connection";if(t===1011){let r=lUe(e.reason);return/no running broker/i.test(r)||lar(r)==="connection"?"connection":"other"}return null}function dne(e,t){return t==="auth"||t==="protocol"?"fatal":e==="pi\u2192provider"?t==="connection"||t==="rate-limit"||t==="overloaded"?"auto":"fatal":"manual"}function BSo(e){if(typeof e=="string")return e;if(!cUe(e))return"";let t=[e.message,e.errorMessage,e.reason,e.body,e.statusText];for(let n of t)if(typeof n=="string"&&n!=="")return n;let r=e.error;if(cUe(r)){let n=r.message;if(typeof n=="string"&&n!=="")return n;let o=r.reason;if(typeof o=="string"&&o!=="")return o}return""}function uUe(e,t){if(cUe(t)){let n=DSo(t);if(n!==null)return{kind:n,disposition:dne(e,n)};let o=MSo(t);if(o!==null)return{kind:o,disposition:dne(e,o)};let s=LSo(t);if(s!==null)return{kind:s,disposition:dne(e,s)}}let r=lar(BSo(t));return{kind:r,disposition:dne(e,r)}}import{randomUUID as zSo}from"node:crypto";var Z9a=16*1024,e7a=4*1024;var t7a=zSo();var L7a=3600*1e3,B7a=Number.NEGATIVE_INFINITY,F7a=xre("crtrd");var U7a=10*6e4;var $7a=3*6e4;var z7a=20*6e4;var Q7a=10*6e4;var uar="CRTR_FRONT_DOOR";function har(){let e=ZSo(far(import.meta.url));return dUe(e,"broker-cli.js")}var nTo="@earendil-works/pi-coding-agent";function par(e){return e.includes("/")||e.endsWith(".jsonl")}function oTo(e,t){return tTo(e)?e:eTo(t,e)}function sTo(e,t,r,n){if(r==="--session"&&!par(n))throw new Error(`[broker] refusing to launch ${e}: launch recipe passes bare --session id '${n}' \u2014 the broker fatally rejects bare ids; pass the .jsonl path instead.`);if(!par(n))return;let o=oTo(n,t);if(!pUe(o)){let s=r==="--session"?"session file":"fork source";throw new Error(`[broker] refusing to launch ${e}: launch recipe references missing ${s} '${n}' (${o})`)}}function iTo(e,t,r){let n=cy(e);mar(n,{recursive:!0});let o=dUe(n,"broker-launch.json");HSo(o,JSON.stringify(t));let s=YSo(o,"utf8"),i=JSON.parse(s);if(!Array.isArray(i.argv))throw new Error(`[broker] refusing to launch ${e}: broker-launch.json is missing the argv array`);let a=t.env.CRTR_BROKER_ENGINE??process.env.CRTR_BROKER_ENGINE??nTo;try{let u=import.meta.resolve(a);if(u.startsWith("file:")&&!pUe(far(u)))throw new Error(`resolved to missing file ${u}`)}catch(u){throw new Error(`[broker] refusing to launch ${e}: cannot resolve broker engine '${a}' from ${har()} \u2014 ${u.message}`)}let l=i.argv;for(let u=0;u<l.length;u++){let c=l[u];if(c!=="--session"&&c!=="--fork")continue;let p=l[++u];p!==void 0&&sTo(e,r,c,p)}}var aTo=2e3,cTo=2e3,lTo=150;function gar(e,t,r,n=t+5e3){let o=Date.now(),s=!1,i=()=>{if(!e())return;let a=Date.now()-o;!s&&a>=t&&(s=!0,r()),!(a>=n)&&setTimeout(i,lTo)};i()}function dar(e,t){BBe(e,"SIGTERM",t),gar(()=>FBe(e),cTo,()=>BBe(e,"SIGKILL",t))}var oq={launch(e,t,r){iTo(e,t,r.cwd);let n=fu(e);mar(n,{recursive:!0});let o=JSo(dUe(n,"broker.log"),"a"),s=jSo(oUe(),[har(),e],{cwd:r.cwd,detached:!0,stdio:["ignore",o,o],env:{...process.env,...t.env,[uar]:"1"}});XSo(o);let i=new Promise(a=>{let l=!1,u=c=>{l||(l=!0,a(c))};s.once("exit",(c,p)=>u({code:c,signal:p})),s.once("error",()=>u({code:null,signal:null}))});return s.unref(),{pid:s.pid??null,exited:i}},isAlive(e){return Sp((typeof e=="string"?Hi(e):e)?.pi_pid)},teardown(e){let t=Hi(e),r=t?.pi_pid,n=r!=null?Tor(r,t?.pi_pid_identity??null):null;n?.reused===!0&&xre("host").warn("refusing to signal a reused pid \u2014 launch-time identity mismatch",{nodeId:e,pid:r});let o=n?.tree??[],s=n?.identities??null,i=wv(e),a=()=>{try{pUe(i)&&KSo(i)}catch{}},l=rTo(i),u=!1;l.on("error",()=>{u||(o.length>0&&dar(o,s),a())}),l.once("connect",()=>{u=!0;try{l.write(kv({type:"shutdown"}))}catch{}l.end(),a(),o.length>0&&gar(()=>FBe(o),aTo,()=>dar(o,s))})},signal(e,t){let r=Hi(e)?.pi_pid;if(r!=null)try{process.kill(r,t)}catch{}}};function ATo(e){return e===null?null:e.pane!==null&&!cne(e.pane)?(Sre(e.focus_id),null):e}function ETo(e){return ATo(vor(e))}function iUe(e){let t=ETo(e);t!==null&&(t.pane!==null&&cne(t.pane)&&rUe(t.pane),Sre(t.focus_id))}function bTo(e){let t=Hi(e);return t===null||qor(e)?!1:!Qor(t.pi_session_file)}function aUe(e){return bTo(e)?(oq.teardown(e),iUe(e),xor(e),!0):!1}import{existsSync as Aar,readFileSync as Ear}from"node:fs";import{join as bar}from"node:path";var Sar=30,Tg="\x1B[",Aa=`${Tg}0m`,fne=`${Tg}1m`,fd=`${Tg}2m`,STo=`${Tg}7m`,TTo=`${Tg}48;5;22m`,xTo=`${Tg}32m`,_Za=`${Tg}31m`,sq=`${Tg}33m`,yZa=`${Tg}36m`,AZa=`${Tg}90m`;function CTo(e){return eFe(e,QQ(e.node_id))}function ITo(e){return e.status!=="active"&&e.status!=="idle"||!Sp(e.pi_pid)?!1:sUe(e.node_id)}function _Ue(e){if(e===null)return"?";let t=XBe(e.status,{streaming:ITo(e),hanging:CTo(e)});return`${Tg}${t.color}m${t.glyph}${Aa}`}var vTo=/\x1b\[[0-9;]*m/g;function xx(e){return e.replace(vTo,"").length}function hne(e,t=mUe()){if(xx(e)<=t)return e;let r="",n=0,o=0;for(;o<e.length&&n<t-1;){if(e[o]==="\x1B"){let s=/^\x1b\[[0-9;]*m/.exec(e.slice(o));if(s){r+=s[0],o+=s[0].length;continue}}r+=e[o],n++,o++}return`${r}\u2026${Aa}`}function mUe(){return Math.max(20,Math.min((process.stdout.columns??80)-2,180))}function _ar(e,t,r){let n=hne(e,t),o=n.replace(/\x1b\[0m/g,`${Aa}${r}`),s=Math.max(0,t-xx(n));return`${r}${o}${" ".repeat(s)}${Aa}`}var mne=new Map,fUe=new Map,hUe=new Map,gUe=new Map;function gne(){mne.clear(),fUe.clear(),hUe.clear(),gUe.clear()}function py(e){if(mne.has(e))return mne.get(e)??null;let t=Hi(e);return mne.set(e,t),t}function wTo(e){let t=hUe.get(e);if(t!==void 0)return t;let r;try{r=QM(e)}catch{r=[]}return hUe.set(e,r),r}function RTo(e){let t=gUe.get(e);if(t!==void 0)return t;let r;try{r=Rv(e)}catch{r=[]}return gUe.set(e,r),r}function Tar(e){let t=fUe.get(e);if(t!==void 0)return t;let r;try{let n=bar(fu(e),"telemetry.json");r=Aar(n)?JSON.parse(Ear(n,"utf8")):{}}catch{r={}}return fUe.set(e,r),r}function NTo(e){return e<1e3?`${e}`:`${Math.round(e/1e3)}k`}function yUe(e){return NTo(Tar(e).context_tokens??0)}function AUe(e,t){if(t?.status!=="active")return"";let r=(Tar(e).last_activity??"").trim();return r===""?"":` ${fd}\xB7 ${r}${Aa}`}function EUe(e){let t=e?.cycles??0;return t>0?` ${fd}\u27F3${t}${Aa}`:""}function _ne(e,t){if(e===null)return yne(t);let r=e.name&&e.name!==e.kind?e.name:"";if(r!=="")return r;let n=(e.description??"").trim();return n!==""?n:e.name}function yne(e){return e.slice(0,8)}function xar(){try{return new Set($Q().map(e=>e.node_id))}catch{return new Set}}function kTo(e,t,r){if(r.has(e))return!0;if(t?.status!=="active")return!1;try{let n=bar(fu(e),"attach.json");if(!Aar(n))return!1;let o=JSON.parse(Ear(n,"utf8"));return typeof o.viewers=="number"&&o.viewers>0}catch{return!1}}function tL(e){return RTo(e)[0]?.node_id}function OTo(e){return py(e)?.kind==="human"}function Ane(e){return wTo(e).map(t=>t.node_id).filter(t=>!OTo(t))}function Car(e){return Ane(e).filter(t=>{let r=py(t)?.status;return r==="active"||r==="idle"})}function Iar(e){return Ane(e).length}function Qv(e){let t=e,r=new Set([t]);for(;;){let n=tL(t);if(n===void 0||r.has(n))break;r.add(n),t=n}return t}function bUe(e){if(e===null||e.mode!=="orchestrator")return"";let t=Iar(e.node_id);return t>0?` ${fd}\u2933${t}${Aa}`:""}function SUe(e,t){let r=t[e]??0;return r>0?` ${sq}\u2691${r}${Aa}`:""}function TUe(e,t){if(e===null||e.status==="active")return"";let r=t.get(e.node_id)??0;return r>0?` ${xTo}\u21E3${r}${Aa}`:""}function yar(e){switch(py(e)?.status){case"active":return 0;case"idle":return 1;case"done":return 2;case"canceled":return 3;case"dead":return 4;default:return 5}}function xUe(e){return Ane(e).sort((t,r)=>yar(t)-yar(r))}function iq(e,t){let r=new Set,n=new Map,o=new Set,s=i=>{let a=py(i)?.status==="active";if(o.has(i))return{active:a?1:0,reveal:a||i===t};o.add(i);let l=0,u=!1;for(let c of Ane(i)){let p=s(c);l+=p.active,p.reveal&&(u=!0)}return n.set(i,l),u&&r.add(i),{active:l+(a?1:0),reveal:u||a||i===t}};return s(e),{expand:r,activeBelow:n}}function PTo(e,t){return iq(e,t).expand}function CUe(e,t,r){let n=Qv(e),o=r??PTo(n,e),s=u=>t.userExpanded.has(u)?!1:t.userCollapsed.has(u)?!0:!o.has(u),i=[],a=new Set,l=(u,c,p,d)=>{if(a.has(u)){let E=p?"":d?"\u2514\u2500 ":"\u251C\u2500 ";i.push({id:u,hasKids:!1,isSelf:u===e,branch:c+E,cycle:!0,collapsed:!1});return}a.add(u);let f=xUe(u),m=s(u),h=p?"":d?"\u2514\u2500 ":"\u251C\u2500 ";if(i.push({id:u,hasKids:f.length>0,isSelf:u===e,branch:c+h,cycle:!1,collapsed:m}),m)return;let g=p?"":c+(d?" ":"\u2502 ");for(let E=0;E<f.length;E++)l(f[E],g,!1,E===f.length-1)};return l(n,"",!0,!0),i}function war(e,t,r,n,o){let s=(y,A)=>t?_ar(y,mUe(),STo):A?_ar(y,mUe(),TTo):hne(y);if(e.cycle){let y=`${e.branch} ${fd}\u21BA ${yne(e.id)}${Aa}`;return s(y,!1)}let i=py(e.id),a=_Ue(i),l=_ne(i,e.id),u=e.isSelf?`${fne}${l}${Aa}`:l,c=`${fd}${i?.kind??""}${Aa}`,p=`${fd}${yUe(e.id)}${Aa}`,d=e.hasKids&&e.collapsed,f=!t&&d?`${fd}\u25B8${Aa} `:" ",m=d?` ${fd}[+${Iar(e.id)}]${Aa}`:"",h=i!==null?eFe(i,QQ(e.id)):null,g=h!==null?` \xB7 ${ZBe(h)}`:"",E=`${e.branch}${f}${a} ${u} ${c} ${p}${EUe(i)}${bUe(i)}${TUe(i,n)}${m}${SUe(e.id,o)}${AUe(e.id,i)}${g}`;return s(E,kTo(e.id,i,r))}var EZa=`${fd}jk move \xB7 hl fold \xB7 \u21B5 focus \xB7 e expand \xB7 x kill \xB7 m mgr \xB7 esc${Aa}`;var Rar="crtr context";function DTo(e,t){if(e==="")return[""];let r=[],n="";for(let o of e)n!==""&&dn(n+o)>t?(r.push(n),n=o):n+=o;return n!==""&&r.push(n),r}var Ene=class{constructor(t,r,n,o){this.body=t;this.dim=n;this.label=o;this.expanded=r}body;dim;label;expanded;setExpanded(t){this.expanded=t}render(t){let r=t>0?t:80;if(!this.expanded){let o=`[${Rar}]`,s=" orienting bearings \u2014 ctrl+o to expand",i=dn(o);return i>=r?[this.label(Xn(o,r,"\u2026"))]:[this.label(o)+this.dim(Xn(s,r-i,"\u2026"))]}let n=[this.label(Xn(`[${Rar}]`,r,"\u2026")),""];for(let o of this.body.split(`
|
|
1672
|
+
`)}catch{}}}function CSo(){let e=hSo(),t=oar(process.execPath);if(une(e)&&oar(e)===t)return e;let r=_So(),n=gSo(t),o=n!==null?n.split("/").pop():null;if(une(e)&&r!==null&&r.version===2&&r.source===t&&r.libnode===o&&(o===null||une(lE(zv(),o))))return e;if(sSo(zv(),{recursive:!0}),r?.libnode!=null&&r.libnode!==o)try{pSo(lE(zv(),r.libnode))}catch{}return n!==null&&o!==null&&sar(n,lE(zv(),o)),sar(t,e,493),SSo(e,o!==null?lE(zv(),o):null),aSo(aar(),JSON.stringify({version:2,source:t,libnode:o})),e}function oUe(){if(process.env.CRTR_BRANDED_HOST==="0"||process.platform!=="darwin"||import.meta.url.endsWith(".ts"))return process.execPath;let e=CSo();return TSo(e)?e:(xSo(e),process.execPath)}import{existsSync as ISo,writeFileSync as q8a,rmSync as G8a,mkdirSync as V8a,statSync as W8a}from"node:fs";import{join as vSo}from"node:path";function wSo(e){return vSo(fu(e),"busy")}function sUe(e){return ISo(wSo(e))}function cUe(e){return typeof e=="object"&&e!==null}function lUe(e){return typeof e=="string"?e:""}function lar(e){let t=e??"";return/rate.?limit|\b429\b|too many requests|quota/i.test(t)?"rate-limit":/overloaded|\b529\b|\b503\b|capacity|server.{0,3}busy|temporarily unavailable/i.test(t)?"overloaded":/invalid_grant|refresh token|unauthori[sz]ed|invalid.?api.?key|authentication failed|\b401\b|\b403\b/i.test(t)?"auth":/connection|econnreset|etimedout|enotfound|econnrefused|network|fetch failed|socket hang|timed? out|timeout/i.test(t)?"connection":"other"}function DSo(e){let t=lUe(e.code)||lUe(e.errno);return t===""?null:/^(ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOENT|ENOTFOUND|EAI_AGAIN|EPIPE|EHOSTUNREACH|ENETUNREACH)$/i.test(t)?"connection":null}function MSo(e){let t=typeof e.status=="number"?e.status:null;return t===null?null:t===401||t===403?"auth":t===429?"rate-limit":t===503||t===529||t>=500&&t<=599?"overloaded":t>=400&&t<=499?"protocol":null}function LSo(e){let t=typeof e.code=="number"?e.code:null;if(t===null)return null;if(t===1008)return"protocol";if(t===1006)return"connection";if(t===1011){let r=lUe(e.reason);return/no running broker/i.test(r)||lar(r)==="connection"?"connection":"other"}return null}function dne(e,t){return t==="auth"||t==="protocol"?"fatal":e==="pi\u2192provider"?t==="connection"||t==="rate-limit"||t==="overloaded"?"auto":"fatal":"manual"}function BSo(e){if(typeof e=="string")return e;if(!cUe(e))return"";let t=[e.message,e.errorMessage,e.reason,e.body,e.statusText];for(let n of t)if(typeof n=="string"&&n!=="")return n;let r=e.error;if(cUe(r)){let n=r.message;if(typeof n=="string"&&n!=="")return n;let o=r.reason;if(typeof o=="string"&&o!=="")return o}return""}function uUe(e,t){if(cUe(t)){let n=DSo(t);if(n!==null)return{kind:n,disposition:dne(e,n)};let o=MSo(t);if(o!==null)return{kind:o,disposition:dne(e,o)};let s=LSo(t);if(s!==null)return{kind:s,disposition:dne(e,s)}}let r=lar(BSo(t));return{kind:r,disposition:dne(e,r)}}import{randomUUID as zSo}from"node:crypto";var t7a=16*1024,r7a=4*1024;var n7a=zSo();var F7a=3600*1e3,U7a=Number.NEGATIVE_INFINITY,$7a=xre("crtrd");var z7a=10*6e4;var Q7a=3*6e4;var q7a=20*6e4;var G7a=10*6e4;var uar="CRTR_FRONT_DOOR";function har(){let e=ZSo(far(import.meta.url));return dUe(e,"broker-cli.js")}var nTo="@earendil-works/pi-coding-agent";function par(e){return e.includes("/")||e.endsWith(".jsonl")}function oTo(e,t){return tTo(e)?e:eTo(t,e)}function sTo(e,t,r,n){if(r==="--session"&&!par(n))throw new Error(`[broker] refusing to launch ${e}: launch recipe passes bare --session id '${n}' \u2014 the broker fatally rejects bare ids; pass the .jsonl path instead.`);if(!par(n))return;let o=oTo(n,t);if(!pUe(o)){let s=r==="--session"?"session file":"fork source";throw new Error(`[broker] refusing to launch ${e}: launch recipe references missing ${s} '${n}' (${o})`)}}function iTo(e,t,r){let n=cy(e);mar(n,{recursive:!0});let o=dUe(n,"broker-launch.json");HSo(o,JSON.stringify(t));let s=YSo(o,"utf8"),i=JSON.parse(s);if(!Array.isArray(i.argv))throw new Error(`[broker] refusing to launch ${e}: broker-launch.json is missing the argv array`);let a=t.env.CRTR_BROKER_ENGINE??process.env.CRTR_BROKER_ENGINE??nTo;try{let u=import.meta.resolve(a);if(u.startsWith("file:")&&!pUe(far(u)))throw new Error(`resolved to missing file ${u}`)}catch(u){throw new Error(`[broker] refusing to launch ${e}: cannot resolve broker engine '${a}' from ${har()} \u2014 ${u.message}`)}let l=i.argv;for(let u=0;u<l.length;u++){let c=l[u];if(c!=="--session"&&c!=="--fork")continue;let p=l[++u];p!==void 0&&sTo(e,r,c,p)}}var aTo=2e3,cTo=2e3,lTo=150;function gar(e,t,r,n=t+5e3){let o=Date.now(),s=!1,i=()=>{if(!e())return;let a=Date.now()-o;!s&&a>=t&&(s=!0,r()),!(a>=n)&&setTimeout(i,lTo)};i()}function dar(e,t){BBe(e,"SIGTERM",t),gar(()=>FBe(e),cTo,()=>BBe(e,"SIGKILL",t))}var oq={launch(e,t,r){iTo(e,t,r.cwd);let n=fu(e);mar(n,{recursive:!0});let o=JSo(dUe(n,"broker.log"),"a"),s=jSo(oUe(),[har(),e],{cwd:r.cwd,detached:!0,stdio:["ignore",o,o],env:{...process.env,...t.env,[uar]:"1"}});XSo(o);let i=new Promise(a=>{let l=!1,u=c=>{l||(l=!0,a(c))};s.once("exit",(c,p)=>u({code:c,signal:p})),s.once("error",()=>u({code:null,signal:null}))});return s.unref(),{pid:s.pid??null,exited:i}},isAlive(e){return Sp((typeof e=="string"?Hi(e):e)?.pi_pid)},teardown(e){let t=Hi(e),r=t?.pi_pid,n=r!=null?Tor(r,t?.pi_pid_identity??null):null;n?.reused===!0&&xre("host").warn("refusing to signal a reused pid \u2014 launch-time identity mismatch",{nodeId:e,pid:r});let o=n?.tree??[],s=n?.identities??null,i=wv(e),a=()=>{try{pUe(i)&&KSo(i)}catch{}},l=rTo(i),u=!1;l.on("error",()=>{u||(o.length>0&&dar(o,s),a())}),l.once("connect",()=>{u=!0;try{l.write(kv({type:"shutdown"}))}catch{}l.end(),a(),o.length>0&&gar(()=>FBe(o),aTo,()=>dar(o,s))})},signal(e,t){let r=Hi(e)?.pi_pid;if(r!=null)try{process.kill(r,t)}catch{}}};function ATo(e){return e===null?null:e.pane!==null&&!cne(e.pane)?(Sre(e.focus_id),null):e}function ETo(e){return ATo(vor(e))}function iUe(e){let t=ETo(e);t!==null&&(t.pane!==null&&cne(t.pane)&&rUe(t.pane),Sre(t.focus_id))}function bTo(e){let t=Hi(e);return t===null||qor(e)?!1:!Qor(t.pi_session_file)}function aUe(e){return bTo(e)?(oq.teardown(e),iUe(e),xor(e),!0):!1}import{existsSync as Aar,readFileSync as Ear}from"node:fs";import{join as bar}from"node:path";var Sar=30,Tg="\x1B[",Aa=`${Tg}0m`,fne=`${Tg}1m`,fd=`${Tg}2m`,STo=`${Tg}7m`,TTo=`${Tg}48;5;22m`,xTo=`${Tg}32m`,AZa=`${Tg}31m`,sq=`${Tg}33m`,EZa=`${Tg}36m`,bZa=`${Tg}90m`;function CTo(e){return eFe(e,QQ(e.node_id))}function ITo(e){return e.status!=="active"&&e.status!=="idle"||!Sp(e.pi_pid)?!1:sUe(e.node_id)}function _Ue(e){if(e===null)return"?";let t=XBe(e.status,{streaming:ITo(e),hanging:CTo(e)});return`${Tg}${t.color}m${t.glyph}${Aa}`}var vTo=/\x1b\[[0-9;]*m/g;function xx(e){return e.replace(vTo,"").length}function hne(e,t=mUe()){if(xx(e)<=t)return e;let r="",n=0,o=0;for(;o<e.length&&n<t-1;){if(e[o]==="\x1B"){let s=/^\x1b\[[0-9;]*m/.exec(e.slice(o));if(s){r+=s[0],o+=s[0].length;continue}}r+=e[o],n++,o++}return`${r}\u2026${Aa}`}function mUe(){return Math.max(20,Math.min((process.stdout.columns??80)-2,180))}function _ar(e,t,r){let n=hne(e,t),o=n.replace(/\x1b\[0m/g,`${Aa}${r}`),s=Math.max(0,t-xx(n));return`${r}${o}${" ".repeat(s)}${Aa}`}var mne=new Map,fUe=new Map,hUe=new Map,gUe=new Map;function gne(){mne.clear(),fUe.clear(),hUe.clear(),gUe.clear()}function py(e){if(mne.has(e))return mne.get(e)??null;let t=Hi(e);return mne.set(e,t),t}function wTo(e){let t=hUe.get(e);if(t!==void 0)return t;let r;try{r=QM(e)}catch{r=[]}return hUe.set(e,r),r}function RTo(e){let t=gUe.get(e);if(t!==void 0)return t;let r;try{r=Rv(e)}catch{r=[]}return gUe.set(e,r),r}function Tar(e){let t=fUe.get(e);if(t!==void 0)return t;let r;try{let n=bar(fu(e),"telemetry.json");r=Aar(n)?JSON.parse(Ear(n,"utf8")):{}}catch{r={}}return fUe.set(e,r),r}function NTo(e){return e<1e3?`${e}`:`${Math.round(e/1e3)}k`}function yUe(e){return NTo(Tar(e).context_tokens??0)}function AUe(e,t){if(t?.status!=="active")return"";let r=(Tar(e).last_activity??"").trim();return r===""?"":` ${fd}\xB7 ${r}${Aa}`}function EUe(e){let t=e?.cycles??0;return t>0?` ${fd}\u27F3${t}${Aa}`:""}function _ne(e,t){if(e===null)return yne(t);let r=e.name&&e.name!==e.kind?e.name:"";if(r!=="")return r;let n=(e.description??"").trim();return n!==""?n:e.name}function yne(e){return e.slice(0,8)}function xar(){try{return new Set($Q().map(e=>e.node_id))}catch{return new Set}}function kTo(e,t,r){if(r.has(e))return!0;if(t?.status!=="active")return!1;try{let n=bar(fu(e),"attach.json");if(!Aar(n))return!1;let o=JSON.parse(Ear(n,"utf8"));return typeof o.viewers=="number"&&o.viewers>0}catch{return!1}}function tL(e){return RTo(e)[0]?.node_id}function OTo(e){return py(e)?.kind==="human"}function Ane(e){return wTo(e).map(t=>t.node_id).filter(t=>!OTo(t))}function Car(e){return Ane(e).filter(t=>{let r=py(t)?.status;return r==="active"||r==="idle"})}function Iar(e){return Ane(e).length}function Qv(e){let t=e,r=new Set([t]);for(;;){let n=tL(t);if(n===void 0||r.has(n))break;r.add(n),t=n}return t}function bUe(e){if(e===null||e.mode!=="orchestrator")return"";let t=Iar(e.node_id);return t>0?` ${fd}\u2933${t}${Aa}`:""}function SUe(e,t){let r=t[e]??0;return r>0?` ${sq}\u2691${r}${Aa}`:""}function TUe(e,t){if(e===null||e.status==="active")return"";let r=t.get(e.node_id)??0;return r>0?` ${xTo}\u21E3${r}${Aa}`:""}function yar(e){switch(py(e)?.status){case"active":return 0;case"idle":return 1;case"done":return 2;case"canceled":return 3;case"dead":return 4;default:return 5}}function xUe(e){return Ane(e).sort((t,r)=>yar(t)-yar(r))}function iq(e,t){let r=new Set,n=new Map,o=new Set,s=i=>{let a=py(i)?.status==="active";if(o.has(i))return{active:a?1:0,reveal:a||i===t};o.add(i);let l=0,u=!1;for(let c of Ane(i)){let p=s(c);l+=p.active,p.reveal&&(u=!0)}return n.set(i,l),u&&r.add(i),{active:l+(a?1:0),reveal:u||a||i===t}};return s(e),{expand:r,activeBelow:n}}function PTo(e,t){return iq(e,t).expand}function CUe(e,t,r){let n=Qv(e),o=r??PTo(n,e),s=u=>t.userExpanded.has(u)?!1:t.userCollapsed.has(u)?!0:!o.has(u),i=[],a=new Set,l=(u,c,p,d)=>{if(a.has(u)){let E=p?"":d?"\u2514\u2500 ":"\u251C\u2500 ";i.push({id:u,hasKids:!1,isSelf:u===e,branch:c+E,cycle:!0,collapsed:!1});return}a.add(u);let f=xUe(u),m=s(u),h=p?"":d?"\u2514\u2500 ":"\u251C\u2500 ";if(i.push({id:u,hasKids:f.length>0,isSelf:u===e,branch:c+h,cycle:!1,collapsed:m}),m)return;let g=p?"":c+(d?" ":"\u2502 ");for(let E=0;E<f.length;E++)l(f[E],g,!1,E===f.length-1)};return l(n,"",!0,!0),i}function war(e,t,r,n,o){let s=(y,A)=>t?_ar(y,mUe(),STo):A?_ar(y,mUe(),TTo):hne(y);if(e.cycle){let y=`${e.branch} ${fd}\u21BA ${yne(e.id)}${Aa}`;return s(y,!1)}let i=py(e.id),a=_Ue(i),l=_ne(i,e.id),u=e.isSelf?`${fne}${l}${Aa}`:l,c=`${fd}${i?.kind??""}${Aa}`,p=`${fd}${yUe(e.id)}${Aa}`,d=e.hasKids&&e.collapsed,f=!t&&d?`${fd}\u25B8${Aa} `:" ",m=d?` ${fd}[+${Iar(e.id)}]${Aa}`:"",h=i!==null?eFe(i,QQ(e.id)):null,g=h!==null?` \xB7 ${ZBe(h)}`:"",E=`${e.branch}${f}${a} ${u} ${c} ${p}${EUe(i)}${bUe(i)}${TUe(i,n)}${m}${SUe(e.id,o)}${AUe(e.id,i)}${g}`;return s(E,kTo(e.id,i,r))}var SZa=`${fd}jk move \xB7 hl fold \xB7 \u21B5 focus \xB7 e expand \xB7 x kill \xB7 m mgr \xB7 esc${Aa}`;var Rar="crtr context";function DTo(e,t){if(e==="")return[""];let r=[],n="";for(let o of e)n!==""&&dn(n+o)>t?(r.push(n),n=o):n+=o;return n!==""&&r.push(n),r}var Ene=class{constructor(t,r,n,o){this.body=t;this.dim=n;this.label=o;this.expanded=r}body;dim;label;expanded;setExpanded(t){this.expanded=t}render(t){let r=t>0?t:80;if(!this.expanded){let o=`[${Rar}]`,s=" orienting bearings \u2014 ctrl+o to expand",i=dn(o);return i>=r?[this.label(Xn(o,r,"\u2026"))]:[this.label(o)+this.dim(Xn(s,r-i,"\u2026"))]}let n=[this.label(Xn(`[${Rar}]`,r,"\u2026")),""];for(let o of this.body.split(`
|
|
1673
1673
|
`))for(let s of DTo(o,r))n.push(s);return n}invalidate(){}};var MTo=new Set(["canvas snapshot","node inspect snapshot","node inspect show","sys sysprompt"]);function kar(e){for(let t of MTo){let r=t.split(" ");if(r.length<=e.length&&r.every((n,o)=>e[o]===n))return!0}return!1}var LTo=61529,Oar=String.fromCodePoint(LTo),BTo={canvas:61672,human:61447,memory:61485,node:61842,pkg:61874,push:61678,search:61442,surface:61704,sys:61459},FTo={"canvas dashboard":61668,"canvas snapshot":61488,"canvas browse":61774,"canvas attention count":62098,"canvas attention list":61498,"canvas attention map":62073,"canvas revive":61473,"node lifecycle revive":61473,"canvas history search":61442,"canvas history read":61485,"node inspect artifacts":61914,"sys daemon start":61515,"sys daemon status":61713,"sys daemon stop":61517,"canvas chord":61441,"surface tmux-spread":61449,"canvas issue new":61832,"canvas prune":61636,"canvas rebuild-index":61613,"human ask":61529,"human review":61508,"human notify":61683,"human show":61704,"human cancel":61453,"human inbox":61468,"human list":61498,"human deck":61659,"human resolve":61452,"memory list":61498,"memory read":61485,"memory find":61442,"memory write":61504,"memory origin":61883,"memory lint":61770,"node new":61543,"node msg":61664,"node subscribe":61683,"node unsubscribe":61942,"node promote":61698,"node yield":62093,"node focus":61531,"node cycle":61473,"node inspect list":61498,"node inspect show":61550,"node inspect snapshot":61488,"node inspect context":61564,"node lifecycle recycle":61880,"node lifecycle close":61453,"node lifecycle demote":61699,"node config":61459,"node triggers list":61463,"node triggers cancel":61534,"pkg plugin install":61465,"pkg plugin remove":61460,"pkg plugin enable":61452,"pkg plugin disable":61534,"pkg plugin update":61473,"pkg plugin list":61498,"pkg plugin show":61550,"pkg market add":61543,"pkg market remove":61460,"pkg market update":61473,"pkg market list":61498,"pkg market browse":61774,"push update":61587,"push urgent":61671,"push final":61726,"search web":61612,"search answer":61557,"search contents":61686,"surface view list":61498,"surface view run":61515,"surface view cycle":61473,"surface view new":61543,"surface attach to":61926,"surface workspace enter":61728,"surface web serve":61612,"sys config get":61465,"sys config set":61504,"sys config path":61563,"sys settings":61918,"sys setup":61613,"sys doctor":61681,"sys sysprompt":61788,"sys prompt-review":61442,"sys promptstudio":61448,"sys feedback":61557,"sys update":61473,"sys version":61483,"sys sync":61561};function Par(e){let t;for(let[n,o]of Object.entries(FTo)){let s=n.split(" ");s.length<=e.length&&s.every((i,a)=>e[a]===i)&&(t===void 0||s.length>t.words)&&(t={words:s.length,cp:o})}if(t!==void 0)return String.fromCodePoint(t.cp);let r=e.length>0?BTo[e[0]]:void 0;return r!==void 0?String.fromCodePoint(r):"\u25C6"}var rL=3;function UTo(e){let t=l=>new RegExp(`^-\\s+${l}:\\s*(.+)$`,"m").exec(e)?.[1].trim()??"",r=[t("name"),t("kind"),t("scope")].filter(l=>l!=="").join(" \xB7 "),n=/\*\*content:\*\*\s*([\s\S]*?)(?:\n\s*\*\*follow_up:\*\*|$)/.exec(e);if(r===""&&n===null)return null;let o=(n?.[1]??"").replace(/^\s+/,"").replace(/\s+$/,"").split(`
|
|
1674
1674
|
`),s=o.slice(0,rL);o.slice(rL).some(l=>l.trim()!=="")&&s.push("\u2026");let a=[{text:r}];if(s.some(l=>l.trim()!=="")){a.push({text:""});for(let l of s)a.push({text:l})}return a}var Nar=8;function $To(e){let t=/^- checked:\s*(\d+)\s*$/m.exec(e),r=/(\d+)\s+findings\.\s*$/.exec(e.trimEnd());if(t&&r){let o=t[1],s=Number(r[1]);return s===0?[{text:"PASS",tone:"success"},{text:`${o} docs checked`,tone:"muted"}]:[{text:`${s} findings`,tone:"error"},{text:`${o} docs checked`,tone:"muted"}]}let n=/(\d+)\s+finding\(s\)\s+across\s+(\d+)\s+files/.exec(e);if(n){let o=Number(n[1]),s=n[2],i=[{text:`${o} findings`,tone:"error"}],a=[...e.matchAll(/^crtr: memory lint: (.+)$/gm)].map(u=>u[1]);for(let u of a.slice(0,Nar))i.push({text:u,tone:"warning"});let l=a.length-Nar;return l>0&&i.push({text:`\u2026 ${l} more`,tone:"muted"}),i.push({text:`${s} docs checked`,tone:"muted"}),i}return null}function Xf(e){let t=e.trim();if(!t.startsWith("|")||!t.endsWith("|"))return null;let r=t.slice(1,-1),n=[],o="",s=0;for(;s<r.length;){let i=r[s];if(i==="\\"&&r[s+1]==="|"){o+="|",s+=2;continue}if(i==="|"){n.push(o.trim()),o="",s++;continue}o+=i,s++}return n.push(o.trim()),n}function ym(e,t){let r=e.split(`
|
|
1675
1675
|
`);for(let n=0;n<r.length;n++){let o=r[n].trim();if(o===`0 ${t}.`)return[];if(!/^\d+ /.test(o)||!o.endsWith(`${t}:`))continue;let s=n+1;for(;s<r.length&&r[s].trim()==="";)s++;if(s+1>=r.length)return null;let i=Xf(r[s]),a=Xf(r[s+1]);if(i===null||a===null||i.length===0||a.length!==i.length||a.some(u=>!/^-+$/.test(u)))return null;let l=[];for(s+=2;s<r.length&&r[s].trim()!=="";){let u=Xf(r[s]);if(u===null||u.length!==i.length)return null;let c={};for(let p=0;p<i.length;p++)c[i[p]]=u[p];l.push(c),s++}for(;s<r.length&&r[s].trim()==="";)s++;return s===r.length?l:null}return null}function qv(e,t){let r=new RegExp(`^-\\s+${t}:\\s*(\\d+)\\s*$`,"m").exec(e);return r===null?null:Number(r[1])}function zTo(e){return e>=1e3?`${Math.round(e/1e3)}k`:String(e)}function Cx(e){let t=e.replace(/[\\/]+$/,""),r=Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"));return r===-1?t:t.slice(r+1)}function Dar(e,t){let r=new Set(t),n=[];for(let s of t){let i=e.get(s)??0;i>0&&n.push(`${i} ${s}`)}let o=[...e.entries()].filter(([s,i])=>i>0&&!r.has(s)).sort(([s],[i])=>s.localeCompare(i));for(let[s,i]of o)n.push(`${i} ${s}`);return n.join(" \xB7 ")}function aq(e,t,r){let n=[...e.entries()].filter(([,i])=>i>0).sort((i,a)=>a[1]-i[1]||i[0].localeCompare(a[0])),o=n.slice(0,t).map(([i,a])=>r(i,a)),s=n.length-o.length;return s>0&&o.push(`\u2026 ${s} more`),o.join(", ")}function QTo(e){let t=ym(e,"rows");if(t===null||t.length===0)return null;let r=new Map,n=0,o=0;for(let a of t){let l=a.status,u=Number(a.ctx_tokens),c=Number(a.asks);if(l===void 0||l===""||Number.isNaN(u)||Number.isNaN(c))return null;r.set(l,(r.get(l)??0)+1),n=Math.max(n,u),o+=c}let s=Dar(r,["active","idle","done","dead","canceled"]);if(s==="")return null;let i=[{text:s}];return i.push({text:`largest ctx: ${zTo(n)} tokens`,tone:"muted"}),o>0&&i.push({text:`${o} pending asks`,tone:"warning"}),i}function qTo(e){let t=ym(e,"nodes");if(t===null||t.length===0)return null;let r=new Map,n=new Map;for(let i of t){let a=i.status,l=i.kind;if(a===void 0||a===""||l===void 0||l==="")return null;r.set(a,(r.get(a)??0)+1),n.set(l,(n.get(l)??0)+1)}let o=Dar(r,["active","idle","done","dead","canceled"]),s=aq(n,5,(i,a)=>`${i}\xD7${a}`);return o===""||s===""?null:[{text:o},{text:`kinds: ${s}`,tone:"muted"}]}function GTo(e){let t=qv(e,"count");return t===null?null:t===0?[{text:"PASS \xB7 no pending asks",tone:"success"}]:[{text:`${t} pending asks`,tone:"error"}]}function VTo(e){let t=qv(e,"total"),r=ym(e,"items");if(t===null||r===null)return null;if(t===0||r.length===0)return[{text:"PASS \xB7 no pending asks",tone:"success"}];let n=[];for(let l of r){let u=l.cwd,c=Number(l.count);if(u===void 0||u===""||Number.isNaN(c))return null;n.push({cwd:u,count:c})}let o=n.slice().sort((l,u)=>u.count-l.count||Cx(l.cwd).localeCompare(Cx(u.cwd))||l.cwd.localeCompare(u.cwd)),s=o[0],i=o.slice(1).map(l=>Cx(l.cwd)),a=[{text:`${t} total \xB7 ${r.length} cwds`},{text:`hottest: ${Cx(s.cwd)} (${s.count})`,tone:"warning"}];if(i.length>0){let l=i.slice(0,4),u=i.length-l.length,c=u>0?`${l.join(", ")}, \u2026 ${u} more`:l.join(", ");a.push({text:`other cwds: ${c}`,tone:"muted"})}return a}function WTo(e){let t=/^- counts:\s*(\{.*\})\s*$/m.exec(e);if(t===null)return null;let r;try{r=JSON.parse(t[1])}catch{return null}if(r===null||typeof r!="object")return null;let n=Object.entries(r);if(n.length===0||n.some(([,u])=>typeof u!="number"))return null;let o=n,s=o.reduce((u,[,c])=>u+c,0);if(s===0)return[{text:"PASS \xB7 no pending asks",tone:"success"}];let i=o.filter(([,u])=>u>0),l=i.slice().sort((u,c)=>c[1]-u[1]||u[0].localeCompare(c[0]))[0];return[{text:`${s} asks across ${i.length} node${i.length===1?"":"s"}`},{text:`hottest: ${l[0]} (${l[1]})`,tone:"warning"}]}function jTo(e,t){for(let r=t;r<e.length;r++)if(!e[r].startsWith("--"))return e[r]}function HTo(e,t){if(/^- kicked:\s*true\s*$/m.test(e))return[{text:"kicked \u2014 daemon resumes in ~20s",tone:"warning"}];if(/^- resumed:\s*(true|false)\s*$/m.exec(e)===null)return null;let n=jTo(t,3),o=[{text:n!==void 0?`revived ${n}`:"revived",tone:"success"}],s=/^- ready:\s*(true|false)\s*$/m.exec(e);return s!==null&&s[1]==="false"&&o.push({text:"not yet attachable (socket not ready)",tone:"warning"}),o}function YTo(e){if(/^0 hits\.$/m.test(e))return[{text:"0 hits",tone:"muted"}];let t=/^(\d+) of (\d+) hits:$/m.exec(e);if(t===null)return null;let r=Number(t[1]),n=Number(t[2]),o=e.split(`
|
|
@@ -1748,7 +1748,7 @@ ${S}`,"1"),C=parseInt(v,10)-1;return A.options[C]?.id},signal:E.signal}).then(()
|
|
|
1748
1748
|
`).filter(o=>o.length>0),n={dir:e,dirty:!1,ahead:0,behind:0};for(let o of r)if(o.startsWith("## ")){let s=o.slice(3);if(!s.startsWith("HEAD (no branch)")){let i=s.split(/\.\.\.| /,1)[0];i&&(n.branch=i)}n.ahead=Number(/ahead (\d+)/.exec(s)?.[1]??0),n.behind=Number(/behind (\d+)/.exec(s)?.[1]??0)}else n.dirty=!0;return n}function Qcr(e,t){let r=L0o(e)||e;M0o("git",["-C",e,"status","--porcelain=v1","--branch"],{timeout:2e3,maxBuffer:4*1024*1024},(n,o)=>{if(n){t({dir:r,dirty:!1,ahead:0,behind:0});return}t(B0o(r,o))})}import{EventEmitter as F0o}from"node:events";import{randomUUID as U0o}from"node:crypto";import{createConnection as qcr}from"node:net";var Gcr=1e4;function Vcr(e){return e===null?!0:e.status==="done"||e.status==="dead"||e.status==="canceled"}var mq=class extends Error{constructor(r){super(`node ${r} has no running broker \u2014 focus or revive it first`);this.nodeId=r;this.name="BrokerUnavailableError"}nodeId},kne=class extends F0o{constructor(r){super();this.nodeId=r}nodeId;socket;decoder=new GM(Ire);closeEmitted=!1;pending=new Map;redialFaultRecorded=!1;recordSocketFault(r,n){if(r==="redial"){if(this.redialFaultRecorded)return;this.redialFaultRecorded=!0}let o=uUe("viewer\u2194broker",n);Cre(this.nodeId,{link:"viewer\u2194broker",op:r,kind:o.kind,retry:r==="redial"?{disposition:"auto",by:"client"}:{disposition:"manual"},message:n instanceof Error?n.message:String(n)})}request(r){let n=U0o();return new Promise((o,s)=>{let i=this.socket;if(i===void 0||i.destroyed){s(new Error(`cannot issue '${r.type}': no live broker connection`));return}let a=setTimeout(()=>{this.pending.delete(n),s(new Error(`request '${r.type}' timed out after ${Gcr}ms`))},Gcr);typeof a.unref=="function"&&a.unref(),this.pending.set(n,{resolve:o,reject:s,timer:a}),this.send({...r,id:n})})}rejectAllPending(r){for(let{reject:n,timer:o}of this.pending.values())clearTimeout(o),n(new Error(r));this.pending.clear()}get socketPath(){return wv(this.nodeId)}connect(){let r=qcr(this.socketPath);this.socket=r,r.on("connect",()=>{this.redialFaultRecorded=!1,zQ(this.nodeId,{link:"viewer\u2194broker"}),this.emit("connect")}),r.on("data",n=>this.onData(n)),r.on("error",n=>this.onError(n,"connect")),r.on("close",()=>this.onClose())}redial(){return this.destroy(),this.decoder=new GM(Ire),this.closeEmitted=!1,new Promise((r,n)=>{let o=qcr(this.socketPath);this.socket=o;let s=!1;o.on("connect",()=>{s||(s=!0,this.redialFaultRecorded=!1,zQ(this.nodeId,{link:"viewer\u2194broker"}),this.emit("connect"),r())}),o.on("data",i=>this.onData(i)),o.on("error",i=>{if(s){this.onError(i,"redial");return}s=!0,this.recordSocketFault("redial",i);try{o.destroy()}catch{}n(i)}),o.on("close",()=>this.onClose())})}send(r){let n=this.socket;if(!(n===void 0||n.destroyed))try{n.write(kv(r))}catch{}}close(){this.destroy()}onData(r){let n;try{n=this.decoder.push(r)}catch(o){let s=o instanceof Nv?`broker sent an oversized frame (${o.message}) \u2014 disconnecting`:`failed to decode a broker frame: ${String(o)}`;this.rejectAllPending(s),this.emitError(new Error(s)),this.destroy();return}for(let o of n){let s=o;if(s.type==="data"){let i=typeof s.id=="string"?this.pending.get(s.id):void 0;i&&(this.pending.delete(s.id),clearTimeout(i.timer),i.resolve(s));continue}if(s.type==="error"&&typeof s.id=="string"&&this.pending.has(s.id)){let i=this.pending.get(s.id);this.pending.delete(s.id),clearTimeout(i.timer),i.reject(new Error(s.message||`request failed: ${s.code}`));continue}this.emit("frame",s)}}onError(r,n){this.recordSocketFault(n,r),r.code==="ECONNREFUSED"||r.code==="ENOENT"?this.emitError(new mq(this.nodeId)):this.emitError(new Error(`view socket error: ${r.message}`))}onClose(){this.closeEmitted||(this.closeEmitted=!0,this.rejectAllPending("broker connection closed"),this.emit("close"))}destroy(){let r=this.socket;if(r!==void 0&&!r.destroyed)try{r.destroy()}catch{}}emitError(r){this.listenerCount("error")>0&&this.emit("error",r)}};if(process.env.PI_PACKAGE_DIR===void 0)try{let e=import.meta.resolve("@earendil-works/pi-coding-agent");process.env.PI_PACKAGE_DIR=Wcr(Wcr(V0o(e)))}catch{}function W0o(e,t){$0o("crtr",["canvas","attention","map","--view",e,"--json"],{timeout:2500,maxBuffer:4*1024*1024},(r,n)=>{if(!r)try{let o=JSON.parse(n.trim());t(o.counts??{})}catch{}})}var One=["normal","spec","plan"];function FUe(e,t){return Pne(GBe(e),"mode-switch",t)}function j0o(e,t){return Pne(FUe(e,t),"request.json")}function H0o(e,t){return Pne(FUe(e,t),"current")}function Y0o(e,t){try{let r=Q0o(H0o(e,t),"utf8").trim();return One.includes(r)?r:void 0}catch{return}}function K0o(e,t,r){let n=FUe(e,t);z0o(n,{recursive:!0});let o=jcr(),s=Pne(n,`request.${o}.tmp`);G0o(s,`${JSON.stringify({mode:r,token:o,source:"attach"})}
|
|
1749
1749
|
`),q0o(s,j0o(e,t))}function J0o(e){let t=One.indexOf(e);return One[(t+1)%One.length]}function X0o(e){return e==="spec"?t=>`\x1B[44m\x1B[97m\x1B[1m ${t} \x1B[0m`:e==="plan"?t=>`\x1B[48;2;228;152;68m\x1B[30m\x1B[1m ${t} \x1B[0m`:t=>t}function Z0o(e){let t=e.trimStart();return t.startsWith("!!")?2:t.startsWith("!")?1:0}function eIo(e,t,r){return e===2?{borderColor:r.bashModeAlt,titleStyle:n=>`\x1B[102m\x1B[30m\x1B[1m ${n} \x1B[0m`}:e===1?{borderColor:r.bashMode,titleStyle:n=>`\x1B[42m\x1B[97m\x1B[1m ${n} \x1B[0m`}:{borderColor:$cr(t,r.border),titleStyle:zcr(t,Rne)}}function tIo(e,t,r,n=(o,s,i)=>new rw([...o],s,i)){return n([...hcr(r)],e,t)}async function rIo(e,t){let r=Hi(e);if(r===null)throw new Cv({error:"not_found",message:`no node: ${e}`,received:e,next:"List nodes with `crtr node inspect list`."});let n=new kne(e);await new Promise((Ge,St)=>{let or=()=>{zr(),Ge()},Mr=an=>{zr(),St(an)},zr=()=>{n.off("connect",or),n.off("error",Mr)};n.on("connect",or),n.on("error",Mr),n.connect()}).catch(Ge=>{throw Ge instanceof mq?new Cv({error:"no_broker",message:Ge.message,received:e,next:"Focus or revive the node first \u2014 attach needs a running headless broker."}):new Cv({error:"socket_error",message:`could not attach to node ${e}: ${String(Ge?.message??Ge)}`,received:e,next:"Check the node has a running headless broker."})});let o=process.env.TMUX_PANE??rq()?.pane;if(o!==void 0&&o!=="")try{lne(o,"@crtr_node",e)}catch{}let s=()=>{if(o!==void 0&&o!=="")try{lne(o,"@crtr_node","")}catch{}};kcr({cwd:r.cwd});let i=Ocr(),a=Icr();await wcr(a);let l=await Ncr();if(tq())try{nq()}catch{}let u=new vE,c=new xE(u),p=new In,d=new In,f=new In,m=new In,h=new In,g=new In,E=new In;d.addChild(new Fo(i.border));let y={borderColor:i.border,selectList:Zd()},A=new Nne(c,y,a,{paddingX:1}),S=Y0o(r.cwd,e)??"normal",v=Ge=>{A.setAutocompleteProvider(tIo(r.cwd,l,Ge))},C=()=>{A.mode=S==="normal"?"":S,A.modeStyle=X0o(S)};v(),C();let I=new xne(c,p,{cwd:r.cwd,palette:i,hideThinking:!0}),R=jcr(),N=t?"observer":"controller",F,j,V=0,q="",ae,be=Ge=>Ge>=1e3?`${(Ge/1e3).toFixed(Ge>=1e4?0:1)}k`:`${Ge}`,ye=()=>{let Ge=[];N!=="controller"&&Ge.push(i.muted("\u25CB read-only")),V===2?Ge.unshift(i.bashModeAlt("\u25CF bash \u2014 output hidden from agent")):V===1&&Ge.unshift(i.bashMode("\u25CF bash \u2014 output added to context")),j?.model&&Ge.push(i.info(j.model)),j?.isStreaming&&Ge.push(i.active("\u27F3")),ae!==void 0&&Ge.push(i.muted(`${be(ae)} ctx`)),j&&j.pendingMessageCount>0&&Ge.push(i.muted(`queued ${j.pendingMessageCount}`));let St=Ge.join(i.muted(" \xB7 ")),or=q?i.warning(`\u26A0 ${q}`):"",Mr=Math.max(1,(process.stdout.columns??80)-2),zr=xx(or),an=or?Math.max(0,Mr-zr-1):Mr,ot=xx(St)>an?Xn(St,an,"\u2026"):St,Mt=Math.max(or?1:0,Mr-xx(ot)-zr),Cr=or?ot+" ".repeat(Mt)+or:ot;E.clear(),E.addChild(new Dr(Cr,1,0)),c.requestRender()},ce=3e3,W,se=(Ge,St)=>{q=Ge,W!==void 0&&(clearTimeout(W),W=void 0),Ge&&!St?.sticky&&(W=setTimeout(()=>{W=void 0,q="",ye()},ce)),ye()},Te={},je=()=>{let{managers:Ge,reports:St}=xcr(e,Te,i);f.clear();for(let or of Ge)f.addChild(new Dr(or,1,0));m.clear();for(let or of St)m.addChild(new Dr(or,1,0));c.requestRender()},Ye=new vne(c,e,()=>Te,i),Le=()=>{je(),Ye.refresh()},oe=Ge=>{let St=[i.muted(Ge.dir)];Ge.branch&&St.push(i.info(`\u2387 ${Ge.branch}`));let or=[];Ge.dirty&&or.push(i.warning("\u25CF")),Ge.ahead>0&&or.push(i.active(`\u21E1${Ge.ahead}`)),Ge.behind>0&&or.push(i.active(`\u21E3${Ge.behind}`)),or.length>0&&St.push(or.join("")),A.info=` ${St.join(i.muted(" \xB7 "))} `,c.requestRender()},de=()=>Qcr(r.cwd,oe),ie=[],ee=()=>{if(h.clear(),ie.length>0){let Ge=Math.max(1,(process.stdout.columns??80)-4);h.addChild(new Dr(i.muted(`queued (${ie.length}):`),1,0));for(let St of ie){let or=St.replace(/\s+/g," ").trim();h.addChild(new Dr(i.faint(` \u22EF ${Xn(or,Ge,"\u2026")}`),1,0))}}c.requestRender()},ne=new Ine(c,A,a,{onCommand:Ge=>n.send(Ge),onDialogResponse:Ge=>n.send(Ge),onNotice:Ge=>se(Ge),nodeId:e,onGraph:()=>Ye.toggle(),onQuit:()=>rt("detach"),onCopy:()=>H(),onToggleToolsExpand:()=>se(I.toggleToolsExpanded()?"Tool output: expanded":"Tool output: collapsed"),onToggleThinking:()=>se(I.toggleThinking()?"Thinking blocks: hidden":"Thinking blocks: visible"),onRequest:Ge=>n.request(Ge),onMountPicker:Ge=>{g.addChild(Ge),c.requestRender()},onUnmountPicker:()=>{g.clear(),c.requestRender()},openLoginPicker:()=>{let Ge=F??oL();ne.openAuthPicker(St=>Bcr(c,Ge,()=>n.send({type:"reload_auth"}),or=>se(or),St))},openLogoutPicker:()=>{let Ge=F??oL();ne.openAuthPicker(St=>Fcr(Ge,()=>n.send({type:"reload_auth"}),or=>se(or),St.close))}}),H=()=>{let Ge=I.getLastAssistantText();if(!Ge){se("Nothing to copy \u2014 no assistant message yet");return}se(MUe(Ge)?"Copied last message to clipboard":"Copy failed \u2014 no clipboard tool found")},te=()=>{let Ge=eIo(V,j?.thinkingLevel,i);A.borderColor=Ge.borderColor,A.titleStyle=Ge.titleStyle};A.onChange=Ge=>{let St=Z0o(Ge);St!==V&&(V=St,te(),ye(),c.requestRender())};let me=Ge=>{j=Ge,ne.setState(Ge),A.title=Ge.sessionName?Ge.sessionName:"",te(),ye(),Le()},Ie=Ge=>{j!==void 0&&me({...j,...Ge})},ve=Ge=>{switch(Ge.type){case"welcome":{N=Ge.role,F=Ge.agentDir,I.applySnapshot(Ge.snapshot);let St=Ge.snapshot.stats.contextUsage;St&&St.tokens!=null&&(ae=St.tokens),me(Ge.snapshot.state),n.send({type:"get_commands"}),Ge.pending_dialog!=null&&ne.attachDialog(Ge.pending_dialog);break}case"control_changed":{N=Ge.controller_id===R?"controller":"observer",ye();break}case"model_changed":{Ie({model:Ge.model});break}case"error":{Ge.code==="not_controller"?se("read-only \u2014 another viewer is the controller"):se(`error: ${Ge.message}`);break}case"ack":{if(Ge.for==="get_commands"&&Ge.ok&&Ge.detail){try{let St=JSON.parse(Ge.detail);v(St)}catch{}break}if(Ge.for==="navigate_tree"&&Ge.ok){Ge.detail&&(A.setText(Ge.detail),c.requestRender());break}if(Ge.for==="share"){Ge.ok&&Ge.detail?(se(`Shared: ${Ge.detail}`),MUe(Ge.detail)):Ge.ok||se(`share failed: ${Ge.detail??"unknown error"}`);break}if(Ge.for==="clone"&&!Ge.ok){se(`clone failed: ${Ge.detail??"unknown error"}`);break}if(!Ge.ok){se(`command failed: ${Ge.for}${Ge.detail?` \u2014 ${Ge.detail}`:""}`);break}Ge.for==="reload"&&se("Reloaded keybindings, extensions, skills, prompts, and themes");break}case"extension_ui_request":{ne.attachDialog(Ge);break}case"bash_start":I.bashStart(Ge.command,Ge.excludeFromContext);break;case"bash_output":I.bashOutput(Ge.chunk);break;case"bash_end":I.bashEnd(Ge);break;default:{let St=Ge;if(I.handleEvent(St),St.type==="message_end"&&St.message.role==="assistant"){let or=St.message.usage;ae=or.input+or.cacheRead+or.cacheWrite,ye()}St.type==="agent_start"?Ie({isStreaming:!0}):St.type==="agent_end"?Ie({isStreaming:!1}):St.type==="session_info_changed"?Ie({sessionName:St.name}):St.type==="thinking_level_changed"?(Ie({thinkingLevel:St.level}),se(`Thinking level: ${St.level}`)):St.type==="queue_update"&&(ie=[...St.steering,...St.followUp],ee(),Ie({pendingMessageCount:ie.length}));break}}},he=!1,Se=()=>{if(!he){he=!0;try{c.stop()}catch{}}};process.once("exit",Se);let Re=!1,Ce,ke,xe=new Promise(Ge=>{ke=Ge}),J,rt=Ge=>{if(!Re){Re=!0,J!==void 0&&clearInterval(J),W!==void 0&&clearTimeout(W),Ye.close(),s(),Ar(),Ge==="detach"&&n.send({type:"bye"});try{I.dispose()}catch{}if(n.close(),Se(),Ge==="detach")try{aUe(e)}catch{}if(Ge==="broker-gone"){let St=Ce??`broker gone \u2014 node ${e} is no longer running its engine. Re-focus to reattach.`;process.stderr.write(`
|
|
1750
1750
|
${St}
|
|
1751
|
-
`)}ke()}},st=()=>{n.send({type:"hello",role:N,client_id:R,term:{cols:process.stdout.columns??80,rows:process.stdout.rows??24}})},Lt=1e3,kt=3e3,dt=Ge=>new Promise(St=>setTimeout(St,Ge)),Et=!1,er=async()=>{Et=!0,se("\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!0});let Ge=200;try{for(;!Re;){let St;try{St=BQ(e)}catch{St=void 0}if(St!==void 0&&Vcr(St))break;let or=St?.status==="idle"||St?.intent==="idle-release";se(or?"\u25CC node dormant \u2014 the viewer reconnects on its next wake \xB7 ctrl+c to detach":"\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!0});try{await n.redial(),st(),se("");return}catch{await dt(or?kt:Math.min(Ge,Lt)),Ge*=2}}}finally{Et=!1}Re||rt("broker-gone")};n.on("frame",ve),n.on("error",Ge=>{Ce=Ge.message}),n.on("close",()=>{Re||Et||er()});let Or=1e3,hr=0,Ar=c.addInputListener(Ge=>{if(yi(Ge,"ctrl+d"))return rt("detach"),{consume:!0};if(yi(Ge,"ctrl+c")){let St=Date.now();return St-hr<Or?(hr=0,rt("detach"),{consume:!0}):(hr=St,A.setText(""),se("Editor cleared \u2014 press Ctrl+C again to detach"),c.requestRender(),{consume:!0})}if(yi(Ge,"alt+m")){let St=J0o(S);return K0o(r.cwd,e,St),S=St,C(),c.requestRender(),{consume:!0}}if(yi(Ge,"alt+g"))return Ye.toggle(),{consume:!0}}),ur=()=>rt("signal");process.once("SIGTERM",ur),process.once("SIGHUP",ur),process.once("SIGINT",ur),c.addChild(p),c.addChild(d),c.addChild(f),c.addChild(h),c.addChild(A),c.addChild(g),c.addChild(m),c.addChild(E),c.setFocus(A),ye(),je(),ee(),de(),c.start(),Rcr(u.kittyProtocolActive),st();let ht=5e3,Ve=()=>{Le(),de(),W0o(Qv(e),Ge=>{JSON.stringify(Ge)!==JSON.stringify(Te)&&(Te=Ge,Le())})};Ve(),J=setInterval(Ve,ht),typeof J.unref=="function"&&J.unref(),await xe}var nIo=gor({name:"to",description:"attach an interactive terminal viewer to a node's running broker",whenToUse:"you want to WATCH or DRIVE a headless node live in this pane \u2014 it connects over the node's unix socket to the broker that is already hosting the engine and renders the same chat stream, letting you type prompts (as the controller) or follow read-only (as an observer). It does NOT start the engine: the node must already have a running headless broker (focus or revive it first). One controller drives; extra viewers are read-only. ctrl+c / ctrl+d detaches and leaves the engine running",help:{name:"attach to",summary:"attach a terminal viewer to a headless node's running broker (controller by default, --observer for read-only); detach with ctrl+c/ctrl+d, the engine runs on",params:[{kind:"positional",name:"node",required:!0,constraint:"Node id to attach to. Must already have a running headless broker."},{kind:"flag",name:"observer",type:"bool",required:!1,default:!1,constraint:"Attach READ-ONLY: never claim control even if it is free. Default: drive (claim control if available, else fall back to read-only)."}],output:[{name:"note",type:"string",required:!1,constraint:"Only set on the non-TTY/piped path (a static notice); the interactive path returns nothing."}],outputKind:"object",effects:["Takes over the current pane in raw mode and renders the node's live engine stream until you detach (ctrl+c/ctrl+d) or the broker exits.","As controller: sends prompts/steers/dialog answers to the engine over the socket. As observer: read-only.","NEVER spawns pi and NEVER writes the session \u2014 it holds only a socket to the existing broker.","Outside a TTY (piped): prints a short notice and exits 0 \u2014 attach is an interactive program, not a pipe stage."]},run:async e=>{let t=e.node,r=e.observer??!1;if(!process.stdout.isTTY)return{note:`crtr surface attach is an interactive terminal viewer \u2014 run it in a tmux pane (a TTY), not a pipe. Node: ${t}`};await rIo(t,r)},render:e=>e.note!==void 0?String(e.note):""});function
|
|
1751
|
+
`)}ke()}},st=()=>{n.send({type:"hello",role:N,client_id:R,term:{cols:process.stdout.columns??80,rows:process.stdout.rows??24}})},Lt=1e3,kt=3e3,dt=Ge=>new Promise(St=>setTimeout(St,Ge)),Et=!1,er=async()=>{Et=!0,se("\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!0});let Ge=200;try{for(;!Re;){let St;try{St=BQ(e)}catch{St=void 0}if(St!==void 0&&Vcr(St))break;let or=St?.status==="idle"||St?.intent==="idle-release";se(or?"\u25CC node dormant \u2014 the viewer reconnects on its next wake \xB7 ctrl+c to detach":"\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!0});try{await n.redial(),st(),se("");return}catch{await dt(or?kt:Math.min(Ge,Lt)),Ge*=2}}}finally{Et=!1}Re||rt("broker-gone")};n.on("frame",ve),n.on("error",Ge=>{Ce=Ge.message}),n.on("close",()=>{Re||Et||er()});let Or=1e3,hr=0,Ar=c.addInputListener(Ge=>{if(yi(Ge,"ctrl+d"))return rt("detach"),{consume:!0};if(yi(Ge,"ctrl+c")){let St=Date.now();return St-hr<Or?(hr=0,rt("detach"),{consume:!0}):(hr=St,A.setText(""),se("Editor cleared \u2014 press Ctrl+C again to detach"),c.requestRender(),{consume:!0})}if(yi(Ge,"alt+m")){let St=J0o(S);return K0o(r.cwd,e,St),S=St,C(),c.requestRender(),{consume:!0}}if(yi(Ge,"alt+g"))return Ye.toggle(),{consume:!0}}),ur=()=>rt("signal");process.once("SIGTERM",ur),process.once("SIGHUP",ur),process.once("SIGINT",ur),c.addChild(p),c.addChild(d),c.addChild(f),c.addChild(h),c.addChild(A),c.addChild(g),c.addChild(m),c.addChild(E),c.setFocus(A),ye(),je(),ee(),de(),c.start(),Rcr(u.kittyProtocolActive),st();let ht=5e3,Ve=()=>{Le(),de(),W0o(Qv(e),Ge=>{JSON.stringify(Ge)!==JSON.stringify(Te)&&(Te=Ge,Le())})};Ve(),J=setInterval(Ve,ht),typeof J.unref=="function"&&J.unref(),await xe}var nIo=gor({name:"to",description:"attach an interactive terminal viewer to a node's running broker",whenToUse:"you want to WATCH or DRIVE a headless node live in this pane \u2014 it connects over the node's unix socket to the broker that is already hosting the engine and renders the same chat stream, letting you type prompts (as the controller) or follow read-only (as an observer). It does NOT start the engine: the node must already have a running headless broker (focus or revive it first). One controller drives; extra viewers are read-only. ctrl+c / ctrl+d detaches and leaves the engine running",help:{name:"attach to",summary:"attach a terminal viewer to a headless node's running broker (controller by default, --observer for read-only); detach with ctrl+c/ctrl+d, the engine runs on",params:[{kind:"positional",name:"node",required:!0,constraint:"Node id to attach to. Must already have a running headless broker."},{kind:"flag",name:"observer",type:"bool",required:!1,default:!1,constraint:"Attach READ-ONLY: never claim control even if it is free. Default: drive (claim control if available, else fall back to read-only)."}],output:[{name:"note",type:"string",required:!1,constraint:"Only set on the non-TTY/piped path (a static notice); the interactive path returns nothing."}],outputKind:"object",effects:["Takes over the current pane in raw mode and renders the node's live engine stream until you detach (ctrl+c/ctrl+d) or the broker exits.","As controller: sends prompts/steers/dialog answers to the engine over the socket. As observer: read-only.","NEVER spawns pi and NEVER writes the session \u2014 it holds only a socket to the existing broker.","Outside a TTY (piped): prints a short notice and exits 0 \u2014 attach is an interactive program, not a pipe stage."]},run:async e=>{let t=e.node,r=e.observer??!1;if(!process.stdout.isTTY)return{note:`crtr surface attach is an interactive terminal viewer \u2014 run it in a tmux pane (a TTY), not a pipe. Node: ${t}`};await rIo(t,r)},render:e=>e.note!==void 0?String(e.note):""});function Stc(){return _or({name:"attach",rootEntry:{concept:"a terminal viewer for a headless node \u2014 connect over its socket and drive (or watch) the live engine",desc:"attach a terminal viewer to a headless node",useWhen:"you want to open a headless node live in this pane \u2014 watch its engine stream and drive it by typing, without the node ever running pi in your window. The node must already have a running headless broker; attach connects to it over a unix socket and never starts the engine itself. Detach (ctrl+c/ctrl+d) and the engine keeps running."},help:{name:"attach",summary:"attach a terminal viewer to a headless node's running broker",model:'The branch opens a viewer in the current pane. A TTY is required; piped invocation prints a notice and exits. By default it claims control and drives the engine; --observer follows read-only. One controller plus any number of observers may watch a node. ctrl+c / ctrl+d detaches cleanly and the engine runs on. If the broker exits, the viewer holds the pane and auto-reconnects \u2014 through a yield/refresh relaunch, and across dormancy until the node wakes again \u2014 reporting "broker gone" and exiting only when the node is terminal (done/dead/canceled) or deleted. attach NEVER spawns pi or writes the session \u2014 it holds only a socket to the broker, which must already be running.'},children:[nIo]})}export{tIo as buildAttachAutocompleteProvider,Z0o as deriveBashMode,Stc as registerAttach,eIo as resolveEditorFrameStyles};
|
|
1752
1752
|
/*! Bundled license information:
|
|
1753
1753
|
|
|
1754
1754
|
web-streams-polyfill/dist/ponyfill.es2018.js:
|
|
@@ -2,6 +2,7 @@ import { defineLeaf } from '../../core/command.js';
|
|
|
2
2
|
import { CrtrError, notFound } from '../../core/errors.js';
|
|
3
3
|
import { resolveMemoryDoc } from '../../core/memory-resolver.js';
|
|
4
4
|
import { parseSubstrateDoc } from '../../core/substrate/index.js';
|
|
5
|
+
import { interpolateNodePaths } from '../../core/canvas/paths.js';
|
|
5
6
|
import { readText } from '../../core/fs-utils.js';
|
|
6
7
|
import { MEMORY_KINDS } from './shared.js';
|
|
7
8
|
export const readLeaf = defineLeaf({
|
|
@@ -51,7 +52,13 @@ export const readLeaf = defineLeaf({
|
|
|
51
52
|
: 'knowledge';
|
|
52
53
|
// --kind asserts the resolved kind; a mismatch falls through to not-found.
|
|
53
54
|
if (kindFilter === undefined || kind === kindFilter) {
|
|
54
|
-
const
|
|
55
|
+
const raw = includeFrontmatter ? readText(doc.path) : doc.body;
|
|
56
|
+
// In-node reads (CRTR_NODE_ID set) get the literal `$CRTR_CONTEXT_DIR`
|
|
57
|
+
// token swapped for this node's real absolute path, so agents don't
|
|
58
|
+
// paste it into the non-expanding Write tool. A human/contributor
|
|
59
|
+
// reading generically (env unset) keeps the token literal.
|
|
60
|
+
const nodeId = process.env['CRTR_NODE_ID'];
|
|
61
|
+
const content = nodeId ? interpolateNodePaths(raw, nodeId) : raw;
|
|
55
62
|
return {
|
|
56
63
|
name: doc.name,
|
|
57
64
|
kind,
|
|
@@ -25,6 +25,16 @@ export declare function viewSocketPath(nodeId: string): string;
|
|
|
25
25
|
export declare function nodesRoot(): string;
|
|
26
26
|
export declare function nodeDir(nodeId: string): string;
|
|
27
27
|
export declare function contextDir(nodeId: string): string;
|
|
28
|
+
/** Replace the literal env-var tokens `$CRTR_CONTEXT_DIR` / `$CRTR_NODE_ID` in
|
|
29
|
+
* agent-facing doc text with the node's real values, so a doc surfaced INTO a
|
|
30
|
+
* node hands it a concrete absolute path instead of a shell-only string. The
|
|
31
|
+
* env vars only expand in bash; an agent that pastes `$CRTR_CONTEXT_DIR/x.md`
|
|
32
|
+
* into the (non-expanding) Write tool creates a literal `$CRTR_CONTEXT_DIR/`
|
|
33
|
+
* dir under the project repo. The resolved absolute path works in both bash and
|
|
34
|
+
* Write, so this substitution is strictly safer. Callers must only apply it
|
|
35
|
+
* when they have a concrete node to render for (never on generic, node-less
|
|
36
|
+
* output). Pure string work — no I/O. */
|
|
37
|
+
export declare function interpolateNodePaths(text: string, nodeId: string): string;
|
|
28
38
|
export declare function jobDir(nodeId: string): string;
|
|
29
39
|
export declare function reportsDir(nodeId: string): string;
|
|
30
40
|
/** Overflow store for inbox entries whose inline body exceeds the digest's
|
|
@@ -69,6 +69,20 @@ export function nodeDir(nodeId) {
|
|
|
69
69
|
export function contextDir(nodeId) {
|
|
70
70
|
return join(nodeDir(nodeId), 'context');
|
|
71
71
|
}
|
|
72
|
+
/** Replace the literal env-var tokens `$CRTR_CONTEXT_DIR` / `$CRTR_NODE_ID` in
|
|
73
|
+
* agent-facing doc text with the node's real values, so a doc surfaced INTO a
|
|
74
|
+
* node hands it a concrete absolute path instead of a shell-only string. The
|
|
75
|
+
* env vars only expand in bash; an agent that pastes `$CRTR_CONTEXT_DIR/x.md`
|
|
76
|
+
* into the (non-expanding) Write tool creates a literal `$CRTR_CONTEXT_DIR/`
|
|
77
|
+
* dir under the project repo. The resolved absolute path works in both bash and
|
|
78
|
+
* Write, so this substitution is strictly safer. Callers must only apply it
|
|
79
|
+
* when they have a concrete node to render for (never on generic, node-less
|
|
80
|
+
* output). Pure string work — no I/O. */
|
|
81
|
+
export function interpolateNodePaths(text, nodeId) {
|
|
82
|
+
return text
|
|
83
|
+
.replaceAll('$CRTR_CONTEXT_DIR', contextDir(nodeId))
|
|
84
|
+
.replaceAll('$CRTR_NODE_ID', nodeId);
|
|
85
|
+
}
|
|
72
86
|
export function jobDir(nodeId) {
|
|
73
87
|
return join(nodeDir(nodeId), 'job');
|
|
74
88
|
}
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
// (parseSubstrateDoc returns null for a non-substrate doc; per-file node-local
|
|
49
49
|
// loads are wrapped), and tree construction is pure string work.
|
|
50
50
|
import { relative, sep } from 'node:path';
|
|
51
|
+
import { interpolateNodePaths } from '../canvas/paths.js';
|
|
51
52
|
import { listAllMemoryDocs, resolveMemoryDoc } from '../memory-resolver.js';
|
|
52
53
|
import { subKindsAvailableTo } from '../config.js';
|
|
53
54
|
import { parseFrontmatterGeneric } from '../frontmatter.js';
|
|
@@ -504,7 +505,10 @@ function buildPreferencesBlock(subject) {
|
|
|
504
505
|
}
|
|
505
506
|
export function renderPreferencesSection(nodeId) {
|
|
506
507
|
const subject = cachedNodeSubject(nodeId, assembleNodeSubject);
|
|
507
|
-
|
|
508
|
+
// Surfaced INTO this node: swap the literal `$CRTR_CONTEXT_DIR` env-var token
|
|
509
|
+
// for the node's real absolute path so agents don't paste it into the
|
|
510
|
+
// non-expanding Write tool (see interpolateNodePaths).
|
|
511
|
+
return interpolateNodePaths(buildPreferencesBlock(subject).block, nodeId);
|
|
508
512
|
}
|
|
509
513
|
export function renderPreferencesForSubject(subject) {
|
|
510
514
|
return buildPreferencesBlock(subject);
|
|
@@ -543,5 +547,6 @@ export function renderKnowledgeBlock(nodeId) {
|
|
|
543
547
|
if (tree !== '')
|
|
544
548
|
out += `\n\n${tree}`;
|
|
545
549
|
out += `\n\n${KNOWLEDGE_OUTRO}`;
|
|
546
|
-
|
|
550
|
+
// Surfaced INTO this node: swap literal `$CRTR_CONTEXT_DIR` for the real path.
|
|
551
|
+
return interpolateNodePaths(`<memory kind="knowledge">\n${out}\n</memory>`, nodeId);
|
|
547
552
|
}
|