@sma1lboy/kobe 0.8.193 → 0.8.194

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/cli/index.js CHANGED
@@ -79,7 +79,7 @@ You were spawned by Rove task ${Z}. When the work is finished, send your outcome
79
79
  `).split(`
80
80
  `).map((X)=>(X.split("\r").pop()??"").slice(0,bW0));while(Z.length>0&&(Z[Z.length-1]??"").trim()==="")Z.pop();return Z.slice(-yW0)}function AF($=QH()){try{let J=JSON.parse(EW0($,"utf8"));if(J===null||typeof J!=="object"||Array.isArray(J))return{};return J}catch{return{}}}function uT($,J=QH()){if($.key.startsWith("::"))return;if($.exit.code===0&&$.exit.signal===null)return;let Z=AF(J);Z[$.key]={key:$.key,pid:$.pid,code:$.exit.code,signal:$.exit.signal,at:$.exit.at,tail:Yc($.tail)};let X=Object.values(Z).sort((z,G)=>z.at<G.at?1:-1).slice(0,fW0);IW0(xW0(J),{recursive:!0}),wW0(J,JSON.stringify(Object.fromEntries(X.map((z)=>[z.key,z])),null,2),"utf8")}var fW0=50,yW0=40,bW0=500,gW0;var DF=c(()=>{B7();gW0=/\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?|\x1b[@-_]/g});var qc={};A$(qc,{setRepoLastActiveVendor:()=>iZ,setGlobalDefaultVendor:()=>dT,resolvePreferredVendor:()=>F9,getRepoLastActiveVendor:()=>Wc,getGlobalDefaultVendor:()=>ej});function lT($,J){let Z=$?.trim();if(!Z)return;if(n7(Z)||J.includes(Z))return Z;return}function Wc($){return lT(w5(Gc+$),x2())}function iZ($,J){X6(Gc+$,J)}function ej(){let $=x2();return lT(w5("defaultVendor"),$)??lT(w5("lastSelectedVendor"),$)}function dT($){X6("defaultVendor",$)}function F9($){return($?Wc($):void 0)??ej()??H4}var Gc="lastActiveVendor.";var IJ=c(()=>{R7();J7();A4()});function z8($=process.env){return{...$,...pT}}var pT;var oZ=c(()=>{pT={GIT_OPTIONAL_LOCKS:"0"}});function Hc($){return $>="0"&&$<="7"}function Kc($,J){let Z=[],X="",z=()=>{if(X.length>0){for(let W of vW0.encode(X))Z.push(W);X=""}},G=J+1;while(G<$.length){let W=$[G];if(W==='"'){G++;break}if(W==="\\"){let q=$[G+1];if(q===void 0){X+="\\",G++;continue}switch(q){case"a":z(),Z.push(7),G+=2;break;case"b":z(),Z.push(8),G+=2;break;case"t":z(),Z.push(9),G+=2;break;case"n":z(),Z.push(10),G+=2;break;case"v":z(),Z.push(11),G+=2;break;case"f":z(),Z.push(12),G+=2;break;case"r":z(),Z.push(13),G+=2;break;case'"':X+='"',G+=2;break;case"\\":X+="\\",G+=2;break;default:if(Hc(q)){let U="",B=G+1;while(B<$.length&&U.length<3&&Hc($[B]))U+=$[B],B++;z(),Z.push(Number.parseInt(U,8)&255),G=B}else X+=q,G+=2;break}}else X+=W,G++}return z(),{value:kW0.decode(new Uint8Array(Z)),end:G}}function EJ($){if($.length===0||$[0]!=='"')return $;return Kc($,0).value}function Fc($,J){if($[0]==='"'){let X=Kc($,0);if($.startsWith(J,X.end))return{orig:X.value,neu:EJ($.slice(X.end+J.length))};return null}let Z=$.indexOf(J);if(Z<0)return null;return{orig:$.slice(0,Z),neu:EJ($.slice(Z+J.length))}}function Uc($,J,Z){if(J.length===0&&$.endsWith("/")&&Z.startsWith("/"))return $+Z.slice(1);return $+J+Z}function mW0($){let J=$.indexOf("{");if(J>=0){let X=$.indexOf("}",J),z=$.indexOf(" => ",J);if(X>J&&z>=0&&z<X){let G=$.slice(0,J),W=$.slice(J+1,z),q=$.slice(z+4,X),U=$.slice(X+1);return{path:Uc(G,q,U),origPath:Uc(G,W,U)}}}let Z=Fc($," => ");if(Z)return{path:Z.neu,origPath:Z.orig};return{path:EJ($)}}function $V($){let J=[];for(let Z of $.split(`
81
81
  `)){let X=Z.replace(/\r$/,"");if(X.length<4)continue;if(X.startsWith("##"))continue;let z=X[0],G=X[1];if(X[2]!==" ")continue;let W=X.slice(3);if(z==="R"||z==="C"||G==="R"||G==="C"){let q=Fc(W," -> ");if(q){J.push({x:z,y:G,path:q.neu,origPath:q.orig});continue}}J.push({x:z,y:G,path:EJ(W)})}return J}function Bc($){if($==="-")return null;let J=Number.parseInt($,10);return Number.isNaN(J)?null:J}function Mc($){let J=[];for(let Z of $.split(`
82
- `)){let X=Z.replace(/\r$/,"");if(X.length===0)continue;let z=X.indexOf("\t");if(z<0)continue;let G=X.indexOf("\t",z+1);if(G<0)continue;let W=X.slice(G+1);if(W.length===0)continue;let q=mW0(W);if(q.path.length===0)continue;J.push({path:q.path,...q.origPath!==void 0?{origPath:q.origPath}:{},added:Bc(X.slice(0,z)),deleted:Bc(X.slice(z+1,G))})}return J}var vW0,kW0;var JV=c(()=>{vW0=new TextEncoder,kW0=new TextDecoder});var Nc={};A$(Nc,{sameWorktreeChanges:()=>PF,readWorktreeChanges:()=>uW0,pickPushedChanges:()=>nT,parsePorcelain:()=>AH});import{spawnSync as hW0}from"child_process";function PF($,J){return $.added===J.added&&$.deleted===J.deleted}function nT($,J){if(!$)return null;return $.get(J)??ZV}function uW0($){if(!$)return ZV;try{let J=hW0("git",["status","--porcelain=v1"],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});if(J.status!==0||!J.stdout)return ZV;return AH(J.stdout)}catch{return ZV}}function AH($){let J=0,Z=0;for(let{x:X,y:z}of $V($))if(X==="D"||z==="D")Z+=1;else J+=1;return{added:J,deleted:Z}}var ZV;var DH=c(()=>{oZ();JV();ZV={added:0,deleted:0}});var Vc={};A$(Vc,{resolveBaseRef:()=>Oc,readBranchSignals:()=>lW0,parseShortstat:()=>jc});import{spawnSync as cW0}from"child_process";function XV($,J){try{let Z=cW0("git",[...J],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});return Z.status===0?Z.stdout.trim():null}catch{return null}}function Oc($){let J=XV($,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(J)return J;for(let Z of["origin/main","origin/master","main","master"])if(XV($,["rev-parse","--verify","--quiet",Z])!==null)return Z;return null}function jc($){let J=(Z)=>{let X=$.match(Z);return X?Number.parseInt(X[1]??"0",10):0};return{files:J(/(\d+) files? changed/),insertions:J(/(\d+) insertions?\(\+\)/),deletions:J(/(\d+) deletions?\(-\)/)}}function lW0($){if(!$)return Lc;let J=Oc($);if(!J)return Lc;let Z=XV($,["rev-list","--count",`${J}..HEAD`]),X=Z===null?null:Number.parseInt(Z,10),z=XV($,["diff","--shortstat",`${J}...HEAD`]),G=z===null?null:jc(z);return{baseRef:J,ahead:X!==null&&Number.isNaN(X)?null:X,diff:G}}var Lc;var _c=c(()=>{oZ();Lc={baseRef:null,ahead:null,diff:null}});async function dW0($,J,Z){let X;try{X=await NT()}catch(z){throw new K1(`failed to start PTY host for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}try{if($.tab&&$.tab!=="new"){let L=B2({command:$.command,vendor:$.vendor,effort:$.modelEffort})[0];return await jT(X.rpc,$.id,$.tab,J,Z,{engineBin:L})}let z=$.tab==="new"?zc($.id,$.tabVendor,$.tabCommand):void 0,G=$.tabVendor??$.vendor,W=$.tabCommand??($.tabVendor?void 0:$.command),{argv:q,sessionId:U}=nQ(B2({command:W,vendor:G,effort:$.modelEffort}),G);MH(G,J);let B=FH({task:{id:$.id,kind:$.kind,vendor:G,repo:$.repo},worktreePath:J,shell:process.env.SHELL?.trim()||"/bin/zsh",argv:q,promptIntent:$.newTask?{kind:"new-task",prompt:Z,spawnerTaskId:(await UH())?.taskId}:{kind:"explicit",prompt:Z},tabId:z}),M=await OT(X.rpc,{id:$.id,engineBin:q[0]},J,Z,B,{forceNew:z!==void 0});if(M.started&&!M.engineReady)throw new K1(`failed to start hosted engine session for ${$.id}`,"SESSION_FAILED");if(M.started&&U)if(z)Qc($.id,z,U);else mT($.id,U);else if(!z)mT($.id);return M}catch(z){if(z instanceof K1)throw z;throw new K1(`hosted engine session failed for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}finally{X.close()}}async function iT($,J,Z,X=pW0){let z=J.worktreePath;if(!z)z=(await $.request("task.ensureWorktree",{taskId:J.id})).worktreePath;if(!z)throw new K1(`task ${J.id} has no worktree`,"NO_WORKTREE");let G=await X.deliverHosted(J,z,Z);if(!G)throw new K1(`failed to start hosted engine session for ${J.id}`,"SESSION_FAILED");return G}var pW0,RF;var TF=c(()=>{U9();Z7();vj();kj();hj();MF();Dj();hT();$8();pW0={deliverHosted:dW0};RF={isTaskRunning:async($)=>(await RF.taskTabs($)).running,taskTabs:async($)=>{let J=[],Z=await qH();if(Z)try{J=await HH(Z.rpc)}finally{Z.close()}let X;try{let{foregroundEngineIn:W,parsePsSnapshot:q,psSnapshot:U}=await Promise.resolve().then(() => (AJ(),Hj)),B=J.filter((M)=>M.alive&&typeof M.pid==="number"&&M.pid>0);if(B.length>0){let M=q(await U());X=new Map(B.map((L)=>[L.key,W(M,L.pid)?.vendor??null]))}}catch{}let z={};try{z=(await Promise.resolve().then(() => (DF(),cT))).readPtyExitRecords()}catch{}let G=$c($);return{tabs:Zc(G,$,J,z,X),running:Xc(G,$,J)}},deliverPrompt:($,J,Z)=>iT($,J,Z),resolveRepoRoot:async($)=>(await Promise.resolve().then(() => (A4(),lq))).resolveMainRepoRoot($),defaultVendor:async($)=>{let{getGlobalDefaultVendor:J,getRepoLastActiveVendor:Z}=await Promise.resolve().then(() => (IJ(),qc));return($?Z($):void 0)??J()},readWorktreeChanges:async($)=>(await Promise.resolve().then(() => (DH(),Nc))).readWorktreeChanges($),readBranchSignals:async($)=>(await Promise.resolve().then(() => (_c(),Vc))).readBranchSignals($),tearDownSession:async($)=>{let J=await qH();if(J)try{await VT(J.rpc,MT(await HH(J.rpc),$))}catch{}finally{J.close()}}}});var QV;var Cc=c(()=>{QV={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.193",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://github.com/Sma1lboy/rove#readme",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/mock-host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.16","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]}});var Dc={};A$(Dc,{repoSlug:()=>tY,releasePageUrl:()=>eT,recommendedGlobalInstallCommand:()=>rT,isNewerSemver:()=>oT,fetchReleaseSummaries:()=>IF,fetchReleaseNotesRange:()=>tT,fetchReleaseNotes:()=>sT,compareSemver:()=>A3,checkLatestVersion:()=>eY,breakingVersionsCrossed:()=>SF,UPDATE_SCRIPT_URL:()=>zV,UPDATE_COMMAND:()=>wJ,PACKAGE_NAME:()=>aT,CURRENT_VERSION:()=>D$,BREAKING_VERSIONS:()=>aZ});function tY(){let $=QV.repository?.url;if(!$)return null;let J=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!J||!J[1]||!J[2])return null;return`${J[1]}/${J[2]}`}function rT(){return`npm install -g ${aT}@latest`}function SF($,J,Z=aZ){let[X,z]=A3($,J)<=0?[$,J]:[J,$];return Z.filter((G)=>A3(G,X)>0&&A3(G,z)<=0)}async function iW0($){let J=new AbortController,Z=setTimeout(()=>J.abort(),YV);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:J.signal,headers:{accept:"application/json"}});if(!z.ok)return null;let G=await z.json();if(typeof G.version!=="string")return null;return G.version}catch{return null}finally{clearTimeout(Z)}}function oT($,J){return A3($,J)>0}function A3($,J){let Z=(G)=>G.split("-")[0]??G,X=Z($).split(".").map((G)=>Number.parseInt(G,10)),z=Z(J).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,q=z[G]??0;if(Number.isNaN(W)||Number.isNaN(q))return 0;if(W>q)return 1;if(W<q)return-1}return 0}async function eY($={}){let J=process.env.KOBE_FAKE_UPDATE;if(J)return{current:D$,latest:J,hasUpdate:oT(J,D$)};if(kq()&&!$.force)return null;let Z=await iW0(aT);if(!Z)return null;return{current:D$,latest:Z,hasUpdate:oT(Z,D$)}}function Ac($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function sT($){let J=tY();if(!J)return null;let Z=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),YV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases/tags/${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return null;let W=await G.json();if(typeof W.body!=="string"||typeof W.html_url!=="string")return null;return{body:W.body,url:W.html_url,version:$}}catch{return null}finally{clearTimeout(z)}}async function tT($){let J=tY();if(!J)return[];let Z=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),YV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return[];let W=await G.json();if(!Array.isArray(W))return[];return W.map((q)=>{let U=Ac(q.tag_name);if(!U||typeof q.html_url!=="string"||typeof q.body!=="string")return null;if(A3(U,$.current)<=0)return null;if(A3(U,$.latest)>0)return null;return{version:U,url:q.html_url,body:q.body}}).filter((q)=>q!==null)}catch{return[]}finally{clearTimeout(z)}}async function IF($=12){let J=tY();if(!J)return[];let Z=new AbortController,X=setTimeout(()=>Z.abort(),YV);try{let z=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${$}`,{signal:Z.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!z.ok)return[];let G=await z.json();if(!Array.isArray(G))return[];return G.map((W)=>{let q=Ac(W.tag_name);if(!q||typeof W.html_url!=="string")return null;return{version:q,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function eT($){let J=tY();if(!J)return null;return`https://github.com/${J}/releases/tag/v${$}`}var D$,aT,zV="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",wJ,aZ,YV=3000;var d8=c(()=>{Cc();_5();D$=QV.version,aT=QV.name;wJ=`curl -fsSL ${zV} | sh`;aZ=[]});var oW0,sQ;var $S=c(()=>{/*!
82
+ `)){let X=Z.replace(/\r$/,"");if(X.length===0)continue;let z=X.indexOf("\t");if(z<0)continue;let G=X.indexOf("\t",z+1);if(G<0)continue;let W=X.slice(G+1);if(W.length===0)continue;let q=mW0(W);if(q.path.length===0)continue;J.push({path:q.path,...q.origPath!==void 0?{origPath:q.origPath}:{},added:Bc(X.slice(0,z)),deleted:Bc(X.slice(z+1,G))})}return J}var vW0,kW0;var JV=c(()=>{vW0=new TextEncoder,kW0=new TextDecoder});var Nc={};A$(Nc,{sameWorktreeChanges:()=>PF,readWorktreeChanges:()=>uW0,pickPushedChanges:()=>nT,parsePorcelain:()=>AH});import{spawnSync as hW0}from"child_process";function PF($,J){return $.added===J.added&&$.deleted===J.deleted}function nT($,J){if(!$)return null;return $.get(J)??ZV}function uW0($){if(!$)return ZV;try{let J=hW0("git",["status","--porcelain=v1"],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});if(J.status!==0||!J.stdout)return ZV;return AH(J.stdout)}catch{return ZV}}function AH($){let J=0,Z=0;for(let{x:X,y:z}of $V($))if(X==="D"||z==="D")Z+=1;else J+=1;return{added:J,deleted:Z}}var ZV;var DH=c(()=>{oZ();JV();ZV={added:0,deleted:0}});var Vc={};A$(Vc,{resolveBaseRef:()=>Oc,readBranchSignals:()=>lW0,parseShortstat:()=>jc});import{spawnSync as cW0}from"child_process";function XV($,J){try{let Z=cW0("git",[...J],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});return Z.status===0?Z.stdout.trim():null}catch{return null}}function Oc($){let J=XV($,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(J)return J;for(let Z of["origin/main","origin/master","main","master"])if(XV($,["rev-parse","--verify","--quiet",Z])!==null)return Z;return null}function jc($){let J=(Z)=>{let X=$.match(Z);return X?Number.parseInt(X[1]??"0",10):0};return{files:J(/(\d+) files? changed/),insertions:J(/(\d+) insertions?\(\+\)/),deletions:J(/(\d+) deletions?\(-\)/)}}function lW0($){if(!$)return Lc;let J=Oc($);if(!J)return Lc;let Z=XV($,["rev-list","--count",`${J}..HEAD`]),X=Z===null?null:Number.parseInt(Z,10),z=XV($,["diff","--shortstat",`${J}...HEAD`]),G=z===null?null:jc(z);return{baseRef:J,ahead:X!==null&&Number.isNaN(X)?null:X,diff:G}}var Lc;var _c=c(()=>{oZ();Lc={baseRef:null,ahead:null,diff:null}});async function dW0($,J,Z){let X;try{X=await NT()}catch(z){throw new K1(`failed to start PTY host for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}try{if($.tab&&$.tab!=="new"){let L=B2({command:$.command,vendor:$.vendor,effort:$.modelEffort})[0];return await jT(X.rpc,$.id,$.tab,J,Z,{engineBin:L})}let z=$.tab==="new"?zc($.id,$.tabVendor,$.tabCommand):void 0,G=$.tabVendor??$.vendor,W=$.tabCommand??($.tabVendor?void 0:$.command),{argv:q,sessionId:U}=nQ(B2({command:W,vendor:G,effort:$.modelEffort}),G);MH(G,J);let B=FH({task:{id:$.id,kind:$.kind,vendor:G,repo:$.repo},worktreePath:J,shell:process.env.SHELL?.trim()||"/bin/zsh",argv:q,promptIntent:$.newTask?{kind:"new-task",prompt:Z,spawnerTaskId:(await UH())?.taskId}:{kind:"explicit",prompt:Z},tabId:z}),M=await OT(X.rpc,{id:$.id,engineBin:q[0]},J,Z,B,{forceNew:z!==void 0});if(M.started&&!M.engineReady)throw new K1(`failed to start hosted engine session for ${$.id}`,"SESSION_FAILED");if(M.started&&U)if(z)Qc($.id,z,U);else mT($.id,U);else if(!z)mT($.id);return M}catch(z){if(z instanceof K1)throw z;throw new K1(`hosted engine session failed for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}finally{X.close()}}async function iT($,J,Z,X=pW0){let z=J.worktreePath;if(!z)z=(await $.request("task.ensureWorktree",{taskId:J.id})).worktreePath;if(!z)throw new K1(`task ${J.id} has no worktree`,"NO_WORKTREE");let G=await X.deliverHosted(J,z,Z);if(!G)throw new K1(`failed to start hosted engine session for ${J.id}`,"SESSION_FAILED");return G}var pW0,RF;var TF=c(()=>{U9();Z7();vj();kj();hj();MF();Dj();hT();$8();pW0={deliverHosted:dW0};RF={isTaskRunning:async($)=>(await RF.taskTabs($)).running,taskTabs:async($)=>{let J=[],Z=await qH();if(Z)try{J=await HH(Z.rpc)}finally{Z.close()}let X;try{let{foregroundEngineIn:W,parsePsSnapshot:q,psSnapshot:U}=await Promise.resolve().then(() => (AJ(),Hj)),B=J.filter((M)=>M.alive&&typeof M.pid==="number"&&M.pid>0);if(B.length>0){let M=q(await U());X=new Map(B.map((L)=>[L.key,W(M,L.pid)?.vendor??null]))}}catch{}let z={};try{z=(await Promise.resolve().then(() => (DF(),cT))).readPtyExitRecords()}catch{}let G=$c($);return{tabs:Zc(G,$,J,z,X),running:Xc(G,$,J)}},deliverPrompt:($,J,Z)=>iT($,J,Z),resolveRepoRoot:async($)=>(await Promise.resolve().then(() => (A4(),lq))).resolveMainRepoRoot($),defaultVendor:async($)=>{let{getGlobalDefaultVendor:J,getRepoLastActiveVendor:Z}=await Promise.resolve().then(() => (IJ(),qc));return($?Z($):void 0)??J()},readWorktreeChanges:async($)=>(await Promise.resolve().then(() => (DH(),Nc))).readWorktreeChanges($),readBranchSignals:async($)=>(await Promise.resolve().then(() => (_c(),Vc))).readBranchSignals($),tearDownSession:async($)=>{let J=await qH();if(J)try{await VT(J.rpc,MT(await HH(J.rpc),$))}catch{}finally{J.close()}}}});var QV;var Cc=c(()=>{QV={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.194",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://github.com/Sma1lboy/rove#readme",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/mock-host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.16","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]}});var Dc={};A$(Dc,{repoSlug:()=>tY,releasePageUrl:()=>eT,recommendedGlobalInstallCommand:()=>rT,isNewerSemver:()=>oT,fetchReleaseSummaries:()=>IF,fetchReleaseNotesRange:()=>tT,fetchReleaseNotes:()=>sT,compareSemver:()=>A3,checkLatestVersion:()=>eY,breakingVersionsCrossed:()=>SF,UPDATE_SCRIPT_URL:()=>zV,UPDATE_COMMAND:()=>wJ,PACKAGE_NAME:()=>aT,CURRENT_VERSION:()=>D$,BREAKING_VERSIONS:()=>aZ});function tY(){let $=QV.repository?.url;if(!$)return null;let J=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!J||!J[1]||!J[2])return null;return`${J[1]}/${J[2]}`}function rT(){return`npm install -g ${aT}@latest`}function SF($,J,Z=aZ){let[X,z]=A3($,J)<=0?[$,J]:[J,$];return Z.filter((G)=>A3(G,X)>0&&A3(G,z)<=0)}async function iW0($){let J=new AbortController,Z=setTimeout(()=>J.abort(),YV);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:J.signal,headers:{accept:"application/json"}});if(!z.ok)return null;let G=await z.json();if(typeof G.version!=="string")return null;return G.version}catch{return null}finally{clearTimeout(Z)}}function oT($,J){return A3($,J)>0}function A3($,J){let Z=(G)=>G.split("-")[0]??G,X=Z($).split(".").map((G)=>Number.parseInt(G,10)),z=Z(J).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,q=z[G]??0;if(Number.isNaN(W)||Number.isNaN(q))return 0;if(W>q)return 1;if(W<q)return-1}return 0}async function eY($={}){let J=process.env.KOBE_FAKE_UPDATE;if(J)return{current:D$,latest:J,hasUpdate:oT(J,D$)};if(kq()&&!$.force)return null;let Z=await iW0(aT);if(!Z)return null;return{current:D$,latest:Z,hasUpdate:oT(Z,D$)}}function Ac($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function sT($){let J=tY();if(!J)return null;let Z=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),YV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases/tags/${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return null;let W=await G.json();if(typeof W.body!=="string"||typeof W.html_url!=="string")return null;return{body:W.body,url:W.html_url,version:$}}catch{return null}finally{clearTimeout(z)}}async function tT($){let J=tY();if(!J)return[];let Z=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),YV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return[];let W=await G.json();if(!Array.isArray(W))return[];return W.map((q)=>{let U=Ac(q.tag_name);if(!U||typeof q.html_url!=="string"||typeof q.body!=="string")return null;if(A3(U,$.current)<=0)return null;if(A3(U,$.latest)>0)return null;return{version:U,url:q.html_url,body:q.body}}).filter((q)=>q!==null)}catch{return[]}finally{clearTimeout(z)}}async function IF($=12){let J=tY();if(!J)return[];let Z=new AbortController,X=setTimeout(()=>Z.abort(),YV);try{let z=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${$}`,{signal:Z.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!z.ok)return[];let G=await z.json();if(!Array.isArray(G))return[];return G.map((W)=>{let q=Ac(W.tag_name);if(!q||typeof W.html_url!=="string")return null;return{version:q,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function eT($){let J=tY();if(!J)return null;return`https://github.com/${J}/releases/tag/v${$}`}var D$,aT,zV="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",wJ,aZ,YV=3000;var d8=c(()=>{Cc();_5();D$=QV.version,aT=QV.name;wJ=`curl -fsSL ${zV} | sh`;aZ=[]});var oW0,sQ;var $S=c(()=>{/*!
83
83
  * Copyright (c) Squirrel Chat et al., All rights reserved.
84
84
  * SPDX-License-Identifier: BSD-3-Clause
85
85
  *
@@ -753,7 +753,7 @@ ${Z}: your Rove agent skill is out of date (${W}; this Rove wants v${z.currentVe
753
753
  ${Z}: a new version of the Rove agent skill is available (${W} \u2192 v${z.currentVersion}).
754
754
  Update now? [y]es / [n]o / [d]on't notify for this version: `);let U=(await($.ask??Uj0)()).trim().toLowerCase();if(U==="y"||U==="yes"){let B=await($.install??pw)();if(B===0)process.stderr.write(`${Z}: skill updated.
755
755
  `);else process.stderr.write(`${Z}: skill update failed (exit ${B}) \u2014 run \`${X}\` manually.
756
- `)}else if(U.startsWith("d"))X6(G,"1")}var cw=32,Wj0,qj0="Sma1lboy/rove",lw="skillHintSeen";var _M=c(()=>{v4();EQ();A4();Wj0=[".agents/skills/rove/SKILL.md",".claude/skills/rove/SKILL.md",".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});async function t_($){try{let J=Bun.spawn([...$],{stdin:"ignore",stdout:"pipe",stderr:"pipe"}),[Z,X,z]=await Promise.all([new Response(J.stdout).text().catch(()=>""),new Response(J.stderr).text().catch(()=>""),J.exited]);return{code:z,stdout:Z,stderr:X,missing:!1}}catch(J){let Z=J;return{code:127,stdout:"",stderr:J instanceof Error?J.message:String(J),missing:Z.code==="ENOENT"}}}async function nw($,J){return t_(["tmux","-L",$,...J])}function CM($,J){return`${$} failed: ${J.stderr.trim()||`exit ${J.code}`}`}function Bj0($){return/no server running|failed to connect to server|no sessions/i.test(`${$.stdout}
756
+ `)}else if(U.startsWith("d"))X6(G,"1")}var cw=33,Wj0,qj0="Sma1lboy/rove",lw="skillHintSeen";var _M=c(()=>{v4();EQ();A4();Wj0=[".agents/skills/rove/SKILL.md",".claude/skills/rove/SKILL.md",".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});async function t_($){try{let J=Bun.spawn([...$],{stdin:"ignore",stdout:"pipe",stderr:"pipe"}),[Z,X,z]=await Promise.all([new Response(J.stdout).text().catch(()=>""),new Response(J.stderr).text().catch(()=>""),J.exited]);return{code:z,stdout:Z,stderr:X,missing:!1}}catch(J){let Z=J;return{code:127,stdout:"",stderr:J instanceof Error?J.message:String(J),missing:Z.code==="ENOENT"}}}async function nw($,J){return t_(["tmux","-L",$,...J])}function CM($,J){return`${$} failed: ${J.stderr.trim()||`exit ${J.code}`}`}function Bj0($){return/no server running|failed to connect to server|no sessions/i.test(`${$.stdout}
757
757
  ${$.stderr}`)}function Kj0($){return $.split(`
758
758
  `).map((J)=>Number.parseInt(J.trim(),10)).filter((J)=>Number.isFinite(J)&&J>1)}function Fj0($){let J=[];for(let Z of $.split(`
759
759
  `).slice(1)){let X=Z.trim().split(/\s+/);if(X.length<4)continue;let z=Number.parseInt(X[0]??"",10),G=Number.parseInt(X[1]??"",10),W=Number.parseInt(X[2]??"",10);if(!Number.isFinite(z)||!Number.isFinite(G)||!Number.isFinite(W))continue;J.push({pid:z,pgid:G,rssKb:W,command:X.slice(3).join(" ")})}return J}function Mj0($,J){let Z=new Set(J);return $.filter((X)=>Z.has(X.pgid))}function VG($,J,Z=null){return{available:$,version:J,sessions:[],panePids:[],processes:[],error:Z}}async function e_($="kobe"){let J=await t_(["tmux","-V"]);if(J.missing)return VG(!1,null);if(J.code!==0)return VG(!0,null,CM("tmux -V",J));let Z=J.stdout.trim()||null,X=await nw($,["list-sessions","-F","#{session_name}"]);if(X.code!==0){if(Bj0(X))return VG(!0,Z);return VG(!0,Z,CM("tmux list-sessions",X))}let z=X.stdout.split(`
@@ -79,7 +79,7 @@ You were spawned by Rove task ${Z}. When the work is finished, send your outcome
79
79
  `).split(`
80
80
  `).map((X)=>(X.split("\r").pop()??"").slice(0,kW0));while(Z.length>0&&(Z[Z.length-1]??"").trim()==="")Z.pop();return Z.slice(-vW0)}function AF($=QH()){try{let J=JSON.parse(fW0($,"utf8"));if(J===null||typeof J!=="object"||Array.isArray(J))return{};return J}catch{return{}}}function cT($,J=QH()){if($.key.startsWith("::"))return;if($.exit.code===0&&$.exit.signal===null)return;let Z=AF(J);Z[$.key]={key:$.key,pid:$.pid,code:$.exit.code,signal:$.exit.signal,at:$.exit.at,tail:Wc($.tail)};let X=Object.values(Z).sort((z,G)=>z.at<G.at?1:-1).slice(0,gW0);xW0(bW0(J),{recursive:!0}),yW0(J,JSON.stringify(Object.fromEntries(X.map((z)=>[z.key,z])),null,2),"utf8")}var gW0=50,vW0=40,kW0=500,mW0;var DF=c(()=>{B7();mW0=/\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?|\x1b[@-_]/g});var Uc={};A$(Uc,{setRepoLastActiveVendor:()=>iZ,setGlobalDefaultVendor:()=>pT,resolvePreferredVendor:()=>F9,getRepoLastActiveVendor:()=>Hc,getGlobalDefaultVendor:()=>$V});function dT($,J){let Z=$?.trim();if(!Z)return;if(n7(Z)||J.includes(Z))return Z;return}function Hc($){return dT(w5(qc+$),x2())}function iZ($,J){X6(qc+$,J)}function $V(){let $=x2();return dT(w5("defaultVendor"),$)??dT(w5("lastSelectedVendor"),$)}function pT($){X6("defaultVendor",$)}function F9($){return($?Hc($):void 0)??$V()??H4}var qc="lastActiveVendor.";var IJ=c(()=>{R7();J7();A4()});function z8($=process.env){return{...$,...nT}}var nT;var oZ=c(()=>{nT={GIT_OPTIONAL_LOCKS:"0"}});function Bc($){return $>="0"&&$<="7"}function Mc($,J){let Z=[],X="",z=()=>{if(X.length>0){for(let W of hW0.encode(X))Z.push(W);X=""}},G=J+1;while(G<$.length){let W=$[G];if(W==='"'){G++;break}if(W==="\\"){let q=$[G+1];if(q===void 0){X+="\\",G++;continue}switch(q){case"a":z(),Z.push(7),G+=2;break;case"b":z(),Z.push(8),G+=2;break;case"t":z(),Z.push(9),G+=2;break;case"n":z(),Z.push(10),G+=2;break;case"v":z(),Z.push(11),G+=2;break;case"f":z(),Z.push(12),G+=2;break;case"r":z(),Z.push(13),G+=2;break;case'"':X+='"',G+=2;break;case"\\":X+="\\",G+=2;break;default:if(Bc(q)){let U="",B=G+1;while(B<$.length&&U.length<3&&Bc($[B]))U+=$[B],B++;z(),Z.push(Number.parseInt(U,8)&255),G=B}else X+=q,G+=2;break}}else X+=W,G++}return z(),{value:uW0.decode(new Uint8Array(Z)),end:G}}function EJ($){if($.length===0||$[0]!=='"')return $;return Mc($,0).value}function Nc($,J){if($[0]==='"'){let X=Mc($,0);if($.startsWith(J,X.end))return{orig:X.value,neu:EJ($.slice(X.end+J.length))};return null}let Z=$.indexOf(J);if(Z<0)return null;return{orig:$.slice(0,Z),neu:EJ($.slice(Z+J.length))}}function Kc($,J,Z){if(J.length===0&&$.endsWith("/")&&Z.startsWith("/"))return $+Z.slice(1);return $+J+Z}function cW0($){let J=$.indexOf("{");if(J>=0){let X=$.indexOf("}",J),z=$.indexOf(" => ",J);if(X>J&&z>=0&&z<X){let G=$.slice(0,J),W=$.slice(J+1,z),q=$.slice(z+4,X),U=$.slice(X+1);return{path:Kc(G,q,U),origPath:Kc(G,W,U)}}}let Z=Nc($," => ");if(Z)return{path:Z.neu,origPath:Z.orig};return{path:EJ($)}}function JV($){let J=[];for(let Z of $.split(`
81
81
  `)){let X=Z.replace(/\r$/,"");if(X.length<4)continue;if(X.startsWith("##"))continue;let z=X[0],G=X[1];if(X[2]!==" ")continue;let W=X.slice(3);if(z==="R"||z==="C"||G==="R"||G==="C"){let q=Nc(W," -> ");if(q){J.push({x:z,y:G,path:q.neu,origPath:q.orig});continue}}J.push({x:z,y:G,path:EJ(W)})}return J}function Fc($){if($==="-")return null;let J=Number.parseInt($,10);return Number.isNaN(J)?null:J}function Lc($){let J=[];for(let Z of $.split(`
82
- `)){let X=Z.replace(/\r$/,"");if(X.length===0)continue;let z=X.indexOf("\t");if(z<0)continue;let G=X.indexOf("\t",z+1);if(G<0)continue;let W=X.slice(G+1);if(W.length===0)continue;let q=cW0(W);if(q.path.length===0)continue;J.push({path:q.path,...q.origPath!==void 0?{origPath:q.origPath}:{},added:Fc(X.slice(0,z)),deleted:Fc(X.slice(z+1,G))})}return J}var hW0,uW0;var ZV=c(()=>{hW0=new TextEncoder,uW0=new TextDecoder});var Oc={};A$(Oc,{sameWorktreeChanges:()=>PF,readWorktreeChanges:()=>dW0,pickPushedChanges:()=>iT,parsePorcelain:()=>AH});import{spawnSync as lW0}from"child_process";function PF($,J){return $.added===J.added&&$.deleted===J.deleted}function iT($,J){if(!$)return null;return $.get(J)??XV}function dW0($){if(!$)return XV;try{let J=lW0("git",["status","--porcelain=v1"],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});if(J.status!==0||!J.stdout)return XV;return AH(J.stdout)}catch{return XV}}function AH($){let J=0,Z=0;for(let{x:X,y:z}of JV($))if(X==="D"||z==="D")Z+=1;else J+=1;return{added:J,deleted:Z}}var XV;var DH=c(()=>{oZ();ZV();XV={added:0,deleted:0}});var Cc={};A$(Cc,{resolveBaseRef:()=>Vc,readBranchSignals:()=>nW0,parseShortstat:()=>_c});import{spawnSync as pW0}from"child_process";function QV($,J){try{let Z=pW0("git",[...J],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});return Z.status===0?Z.stdout.trim():null}catch{return null}}function Vc($){let J=QV($,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(J)return J;for(let Z of["origin/main","origin/master","main","master"])if(QV($,["rev-parse","--verify","--quiet",Z])!==null)return Z;return null}function _c($){let J=(Z)=>{let X=$.match(Z);return X?Number.parseInt(X[1]??"0",10):0};return{files:J(/(\d+) files? changed/),insertions:J(/(\d+) insertions?\(\+\)/),deletions:J(/(\d+) deletions?\(-\)/)}}function nW0($){if(!$)return jc;let J=Vc($);if(!J)return jc;let Z=QV($,["rev-list","--count",`${J}..HEAD`]),X=Z===null?null:Number.parseInt(Z,10),z=QV($,["diff","--shortstat",`${J}...HEAD`]),G=z===null?null:_c(z);return{baseRef:J,ahead:X!==null&&Number.isNaN(X)?null:X,diff:G}}var jc;var Ac=c(()=>{oZ();jc={baseRef:null,ahead:null,diff:null}});async function iW0($,J,Z){let X;try{X=await LT()}catch(z){throw new K1(`failed to start PTY host for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}try{if($.tab&&$.tab!=="new"){let L=B2({command:$.command,vendor:$.vendor,effort:$.modelEffort})[0];return await VT(X.rpc,$.id,$.tab,J,Z,{engineBin:L})}let z=$.tab==="new"?Gc($.id,$.tabVendor,$.tabCommand):void 0,G=$.tabVendor??$.vendor,W=$.tabCommand??($.tabVendor?void 0:$.command),{argv:q,sessionId:U}=nQ(B2({command:W,vendor:G,effort:$.modelEffort}),G);MH(G,J);let B=FH({task:{id:$.id,kind:$.kind,vendor:G,repo:$.repo},worktreePath:J,shell:process.env.SHELL?.trim()||"/bin/zsh",argv:q,promptIntent:$.newTask?{kind:"new-task",prompt:Z,spawnerTaskId:(await UH())?.taskId}:{kind:"explicit",prompt:Z},tabId:z}),M=await jT(X.rpc,{id:$.id,engineBin:q[0]},J,Z,B,{forceNew:z!==void 0});if(M.started&&!M.engineReady)throw new K1(`failed to start hosted engine session for ${$.id}`,"SESSION_FAILED");if(M.started&&U)if(z)Yc($.id,z,U);else hT($.id,U);else if(!z)hT($.id);return M}catch(z){if(z instanceof K1)throw z;throw new K1(`hosted engine session failed for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}finally{X.close()}}async function oT($,J,Z,X=oW0){let z=J.worktreePath;if(!z)z=(await $.request("task.ensureWorktree",{taskId:J.id})).worktreePath;if(!z)throw new K1(`task ${J.id} has no worktree`,"NO_WORKTREE");let G=await X.deliverHosted(J,z,Z);if(!G)throw new K1(`failed to start hosted engine session for ${J.id}`,"SESSION_FAILED");return G}var oW0,RF;var TF=c(()=>{U9();Z7();kj();mj();uj();MF();Pj();uT();$8();oW0={deliverHosted:iW0};RF={isTaskRunning:async($)=>(await RF.taskTabs($)).running,taskTabs:async($)=>{let J=[],Z=await qH();if(Z)try{J=await HH(Z.rpc)}finally{Z.close()}let X;try{let{foregroundEngineIn:W,parsePsSnapshot:q,psSnapshot:U}=await Promise.resolve().then(() => (AJ(),Uj)),B=J.filter((M)=>M.alive&&typeof M.pid==="number"&&M.pid>0);if(B.length>0){let M=q(await U());X=new Map(B.map((L)=>[L.key,W(M,L.pid)?.vendor??null]))}}catch{}let z={};try{z=(await Promise.resolve().then(() => (DF(),lT))).readPtyExitRecords()}catch{}let G=Zc($);return{tabs:Qc(G,$,J,z,X),running:zc(G,$,J)}},deliverPrompt:($,J,Z)=>oT($,J,Z),resolveRepoRoot:async($)=>(await Promise.resolve().then(() => (A4(),lq))).resolveMainRepoRoot($),defaultVendor:async($)=>{let{getGlobalDefaultVendor:J,getRepoLastActiveVendor:Z}=await Promise.resolve().then(() => (IJ(),Uc));return($?Z($):void 0)??J()},readWorktreeChanges:async($)=>(await Promise.resolve().then(() => (DH(),Oc))).readWorktreeChanges($),readBranchSignals:async($)=>(await Promise.resolve().then(() => (Ac(),Cc))).readBranchSignals($),tearDownSession:async($)=>{let J=await qH();if(J)try{await _T(J.rpc,NT(await HH(J.rpc),$))}catch{}finally{J.close()}}}});var zV;var Dc=c(()=>{zV={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.193",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://github.com/Sma1lboy/rove#readme",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/mock-host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.16","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]}});var Rc={};A$(Rc,{repoSlug:()=>tY,releasePageUrl:()=>$S,recommendedGlobalInstallCommand:()=>sT,isNewerSemver:()=>aT,fetchReleaseSummaries:()=>IF,fetchReleaseNotesRange:()=>eT,fetchReleaseNotes:()=>tT,compareSemver:()=>A3,checkLatestVersion:()=>eY,breakingVersionsCrossed:()=>SF,UPDATE_SCRIPT_URL:()=>YV,UPDATE_COMMAND:()=>wJ,PACKAGE_NAME:()=>rT,CURRENT_VERSION:()=>D$,BREAKING_VERSIONS:()=>aZ});function tY(){let $=zV.repository?.url;if(!$)return null;let J=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!J||!J[1]||!J[2])return null;return`${J[1]}/${J[2]}`}function sT(){return`npm install -g ${rT}@latest`}function SF($,J,Z=aZ){let[X,z]=A3($,J)<=0?[$,J]:[J,$];return Z.filter((G)=>A3(G,X)>0&&A3(G,z)<=0)}async function rW0($){let J=new AbortController,Z=setTimeout(()=>J.abort(),GV);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:J.signal,headers:{accept:"application/json"}});if(!z.ok)return null;let G=await z.json();if(typeof G.version!=="string")return null;return G.version}catch{return null}finally{clearTimeout(Z)}}function aT($,J){return A3($,J)>0}function A3($,J){let Z=(G)=>G.split("-")[0]??G,X=Z($).split(".").map((G)=>Number.parseInt(G,10)),z=Z(J).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,q=z[G]??0;if(Number.isNaN(W)||Number.isNaN(q))return 0;if(W>q)return 1;if(W<q)return-1}return 0}async function eY($={}){let J=process.env.KOBE_FAKE_UPDATE;if(J)return{current:D$,latest:J,hasUpdate:aT(J,D$)};if(kq()&&!$.force)return null;let Z=await rW0(rT);if(!Z)return null;return{current:D$,latest:Z,hasUpdate:aT(Z,D$)}}function Pc($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function tT($){let J=tY();if(!J)return null;let Z=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases/tags/${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return null;let W=await G.json();if(typeof W.body!=="string"||typeof W.html_url!=="string")return null;return{body:W.body,url:W.html_url,version:$}}catch{return null}finally{clearTimeout(z)}}async function eT($){let J=tY();if(!J)return[];let Z=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return[];let W=await G.json();if(!Array.isArray(W))return[];return W.map((q)=>{let U=Pc(q.tag_name);if(!U||typeof q.html_url!=="string"||typeof q.body!=="string")return null;if(A3(U,$.current)<=0)return null;if(A3(U,$.latest)>0)return null;return{version:U,url:q.html_url,body:q.body}}).filter((q)=>q!==null)}catch{return[]}finally{clearTimeout(z)}}async function IF($=12){let J=tY();if(!J)return[];let Z=new AbortController,X=setTimeout(()=>Z.abort(),GV);try{let z=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${$}`,{signal:Z.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!z.ok)return[];let G=await z.json();if(!Array.isArray(G))return[];return G.map((W)=>{let q=Pc(W.tag_name);if(!q||typeof W.html_url!=="string")return null;return{version:q,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function $S($){let J=tY();if(!J)return null;return`https://github.com/${J}/releases/tag/v${$}`}var D$,rT,YV="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",wJ,aZ,GV=3000;var d8=c(()=>{Dc();_5();D$=zV.version,rT=zV.name;wJ=`curl -fsSL ${YV} | sh`;aZ=[]});var sW0,sQ;var JS=c(()=>{/*!
82
+ `)){let X=Z.replace(/\r$/,"");if(X.length===0)continue;let z=X.indexOf("\t");if(z<0)continue;let G=X.indexOf("\t",z+1);if(G<0)continue;let W=X.slice(G+1);if(W.length===0)continue;let q=cW0(W);if(q.path.length===0)continue;J.push({path:q.path,...q.origPath!==void 0?{origPath:q.origPath}:{},added:Fc(X.slice(0,z)),deleted:Fc(X.slice(z+1,G))})}return J}var hW0,uW0;var ZV=c(()=>{hW0=new TextEncoder,uW0=new TextDecoder});var Oc={};A$(Oc,{sameWorktreeChanges:()=>PF,readWorktreeChanges:()=>dW0,pickPushedChanges:()=>iT,parsePorcelain:()=>AH});import{spawnSync as lW0}from"child_process";function PF($,J){return $.added===J.added&&$.deleted===J.deleted}function iT($,J){if(!$)return null;return $.get(J)??XV}function dW0($){if(!$)return XV;try{let J=lW0("git",["status","--porcelain=v1"],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});if(J.status!==0||!J.stdout)return XV;return AH(J.stdout)}catch{return XV}}function AH($){let J=0,Z=0;for(let{x:X,y:z}of JV($))if(X==="D"||z==="D")Z+=1;else J+=1;return{added:J,deleted:Z}}var XV;var DH=c(()=>{oZ();ZV();XV={added:0,deleted:0}});var Cc={};A$(Cc,{resolveBaseRef:()=>Vc,readBranchSignals:()=>nW0,parseShortstat:()=>_c});import{spawnSync as pW0}from"child_process";function QV($,J){try{let Z=pW0("git",[...J],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});return Z.status===0?Z.stdout.trim():null}catch{return null}}function Vc($){let J=QV($,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(J)return J;for(let Z of["origin/main","origin/master","main","master"])if(QV($,["rev-parse","--verify","--quiet",Z])!==null)return Z;return null}function _c($){let J=(Z)=>{let X=$.match(Z);return X?Number.parseInt(X[1]??"0",10):0};return{files:J(/(\d+) files? changed/),insertions:J(/(\d+) insertions?\(\+\)/),deletions:J(/(\d+) deletions?\(-\)/)}}function nW0($){if(!$)return jc;let J=Vc($);if(!J)return jc;let Z=QV($,["rev-list","--count",`${J}..HEAD`]),X=Z===null?null:Number.parseInt(Z,10),z=QV($,["diff","--shortstat",`${J}...HEAD`]),G=z===null?null:_c(z);return{baseRef:J,ahead:X!==null&&Number.isNaN(X)?null:X,diff:G}}var jc;var Ac=c(()=>{oZ();jc={baseRef:null,ahead:null,diff:null}});async function iW0($,J,Z){let X;try{X=await LT()}catch(z){throw new K1(`failed to start PTY host for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}try{if($.tab&&$.tab!=="new"){let L=B2({command:$.command,vendor:$.vendor,effort:$.modelEffort})[0];return await VT(X.rpc,$.id,$.tab,J,Z,{engineBin:L})}let z=$.tab==="new"?Gc($.id,$.tabVendor,$.tabCommand):void 0,G=$.tabVendor??$.vendor,W=$.tabCommand??($.tabVendor?void 0:$.command),{argv:q,sessionId:U}=nQ(B2({command:W,vendor:G,effort:$.modelEffort}),G);MH(G,J);let B=FH({task:{id:$.id,kind:$.kind,vendor:G,repo:$.repo},worktreePath:J,shell:process.env.SHELL?.trim()||"/bin/zsh",argv:q,promptIntent:$.newTask?{kind:"new-task",prompt:Z,spawnerTaskId:(await UH())?.taskId}:{kind:"explicit",prompt:Z},tabId:z}),M=await jT(X.rpc,{id:$.id,engineBin:q[0]},J,Z,B,{forceNew:z!==void 0});if(M.started&&!M.engineReady)throw new K1(`failed to start hosted engine session for ${$.id}`,"SESSION_FAILED");if(M.started&&U)if(z)Yc($.id,z,U);else hT($.id,U);else if(!z)hT($.id);return M}catch(z){if(z instanceof K1)throw z;throw new K1(`hosted engine session failed for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}finally{X.close()}}async function oT($,J,Z,X=oW0){let z=J.worktreePath;if(!z)z=(await $.request("task.ensureWorktree",{taskId:J.id})).worktreePath;if(!z)throw new K1(`task ${J.id} has no worktree`,"NO_WORKTREE");let G=await X.deliverHosted(J,z,Z);if(!G)throw new K1(`failed to start hosted engine session for ${J.id}`,"SESSION_FAILED");return G}var oW0,RF;var TF=c(()=>{U9();Z7();kj();mj();uj();MF();Pj();uT();$8();oW0={deliverHosted:iW0};RF={isTaskRunning:async($)=>(await RF.taskTabs($)).running,taskTabs:async($)=>{let J=[],Z=await qH();if(Z)try{J=await HH(Z.rpc)}finally{Z.close()}let X;try{let{foregroundEngineIn:W,parsePsSnapshot:q,psSnapshot:U}=await Promise.resolve().then(() => (AJ(),Uj)),B=J.filter((M)=>M.alive&&typeof M.pid==="number"&&M.pid>0);if(B.length>0){let M=q(await U());X=new Map(B.map((L)=>[L.key,W(M,L.pid)?.vendor??null]))}}catch{}let z={};try{z=(await Promise.resolve().then(() => (DF(),lT))).readPtyExitRecords()}catch{}let G=Zc($);return{tabs:Qc(G,$,J,z,X),running:zc(G,$,J)}},deliverPrompt:($,J,Z)=>oT($,J,Z),resolveRepoRoot:async($)=>(await Promise.resolve().then(() => (A4(),lq))).resolveMainRepoRoot($),defaultVendor:async($)=>{let{getGlobalDefaultVendor:J,getRepoLastActiveVendor:Z}=await Promise.resolve().then(() => (IJ(),Uc));return($?Z($):void 0)??J()},readWorktreeChanges:async($)=>(await Promise.resolve().then(() => (DH(),Oc))).readWorktreeChanges($),readBranchSignals:async($)=>(await Promise.resolve().then(() => (Ac(),Cc))).readBranchSignals($),tearDownSession:async($)=>{let J=await qH();if(J)try{await _T(J.rpc,NT(await HH(J.rpc),$))}catch{}finally{J.close()}}}});var zV;var Dc=c(()=>{zV={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.194",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://github.com/Sma1lboy/rove#readme",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/mock-host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.16","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]}});var Rc={};A$(Rc,{repoSlug:()=>tY,releasePageUrl:()=>$S,recommendedGlobalInstallCommand:()=>sT,isNewerSemver:()=>aT,fetchReleaseSummaries:()=>IF,fetchReleaseNotesRange:()=>eT,fetchReleaseNotes:()=>tT,compareSemver:()=>A3,checkLatestVersion:()=>eY,breakingVersionsCrossed:()=>SF,UPDATE_SCRIPT_URL:()=>YV,UPDATE_COMMAND:()=>wJ,PACKAGE_NAME:()=>rT,CURRENT_VERSION:()=>D$,BREAKING_VERSIONS:()=>aZ});function tY(){let $=zV.repository?.url;if(!$)return null;let J=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!J||!J[1]||!J[2])return null;return`${J[1]}/${J[2]}`}function sT(){return`npm install -g ${rT}@latest`}function SF($,J,Z=aZ){let[X,z]=A3($,J)<=0?[$,J]:[J,$];return Z.filter((G)=>A3(G,X)>0&&A3(G,z)<=0)}async function rW0($){let J=new AbortController,Z=setTimeout(()=>J.abort(),GV);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:J.signal,headers:{accept:"application/json"}});if(!z.ok)return null;let G=await z.json();if(typeof G.version!=="string")return null;return G.version}catch{return null}finally{clearTimeout(Z)}}function aT($,J){return A3($,J)>0}function A3($,J){let Z=(G)=>G.split("-")[0]??G,X=Z($).split(".").map((G)=>Number.parseInt(G,10)),z=Z(J).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,q=z[G]??0;if(Number.isNaN(W)||Number.isNaN(q))return 0;if(W>q)return 1;if(W<q)return-1}return 0}async function eY($={}){let J=process.env.KOBE_FAKE_UPDATE;if(J)return{current:D$,latest:J,hasUpdate:aT(J,D$)};if(kq()&&!$.force)return null;let Z=await rW0(rT);if(!Z)return null;return{current:D$,latest:Z,hasUpdate:aT(Z,D$)}}function Pc($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function tT($){let J=tY();if(!J)return null;let Z=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases/tags/${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return null;let W=await G.json();if(typeof W.body!=="string"||typeof W.html_url!=="string")return null;return{body:W.body,url:W.html_url,version:$}}catch{return null}finally{clearTimeout(z)}}async function eT($){let J=tY();if(!J)return[];let Z=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return[];let W=await G.json();if(!Array.isArray(W))return[];return W.map((q)=>{let U=Pc(q.tag_name);if(!U||typeof q.html_url!=="string"||typeof q.body!=="string")return null;if(A3(U,$.current)<=0)return null;if(A3(U,$.latest)>0)return null;return{version:U,url:q.html_url,body:q.body}}).filter((q)=>q!==null)}catch{return[]}finally{clearTimeout(z)}}async function IF($=12){let J=tY();if(!J)return[];let Z=new AbortController,X=setTimeout(()=>Z.abort(),GV);try{let z=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${$}`,{signal:Z.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!z.ok)return[];let G=await z.json();if(!Array.isArray(G))return[];return G.map((W)=>{let q=Pc(W.tag_name);if(!q||typeof W.html_url!=="string")return null;return{version:q,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function $S($){let J=tY();if(!J)return null;return`https://github.com/${J}/releases/tag/v${$}`}var D$,rT,YV="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",wJ,aZ,GV=3000;var d8=c(()=>{Dc();_5();D$=zV.version,rT=zV.name;wJ=`curl -fsSL ${YV} | sh`;aZ=[]});var sW0,sQ;var JS=c(()=>{/*!
83
83
  * Copyright (c) Squirrel Chat et al., All rights reserved.
84
84
  * SPDX-License-Identifier: BSD-3-Clause
85
85
  *
@@ -753,7 +753,7 @@ ${Z}: your Rove agent skill is out of date (${W}; this Rove wants v${z.currentVe
753
753
  ${Z}: a new version of the Rove agent skill is available (${W} \u2192 v${z.currentVersion}).
754
754
  Update now? [y]es / [n]o / [d]on't notify for this version: `);let U=(await($.ask??Fj0)()).trim().toLowerCase();if(U==="y"||U==="yes"){let B=await($.install??nw)();if(B===0)process.stderr.write(`${Z}: skill updated.
755
755
  `);else process.stderr.write(`${Z}: skill update failed (exit ${B}) \u2014 run \`${X}\` manually.
756
- `)}else if(U.startsWith("d"))X6(G,"1")}var lw=32,Uj0,Bj0="Sma1lboy/rove",dw="skillHintSeen";var _M=c(()=>{x4();EQ();A4();Uj0=[".agents/skills/rove/SKILL.md",".claude/skills/rove/SKILL.md",".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});async function e_($){try{let J=Bun.spawn([...$],{stdin:"ignore",stdout:"pipe",stderr:"pipe"}),[Z,X,z]=await Promise.all([new Response(J.stdout).text().catch(()=>""),new Response(J.stderr).text().catch(()=>""),J.exited]);return{code:z,stdout:Z,stderr:X,missing:!1}}catch(J){let Z=J;return{code:127,stdout:"",stderr:J instanceof Error?J.message:String(J),missing:Z.code==="ENOENT"}}}async function iw($,J){return e_(["tmux","-L",$,...J])}function CM($,J){return`${$} failed: ${J.stderr.trim()||`exit ${J.code}`}`}function Mj0($){return/no server running|failed to connect to server|no sessions/i.test(`${$.stdout}
756
+ `)}else if(U.startsWith("d"))X6(G,"1")}var lw=33,Uj0,Bj0="Sma1lboy/rove",dw="skillHintSeen";var _M=c(()=>{x4();EQ();A4();Uj0=[".agents/skills/rove/SKILL.md",".claude/skills/rove/SKILL.md",".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});async function e_($){try{let J=Bun.spawn([...$],{stdin:"ignore",stdout:"pipe",stderr:"pipe"}),[Z,X,z]=await Promise.all([new Response(J.stdout).text().catch(()=>""),new Response(J.stderr).text().catch(()=>""),J.exited]);return{code:z,stdout:Z,stderr:X,missing:!1}}catch(J){let Z=J;return{code:127,stdout:"",stderr:J instanceof Error?J.message:String(J),missing:Z.code==="ENOENT"}}}async function iw($,J){return e_(["tmux","-L",$,...J])}function CM($,J){return`${$} failed: ${J.stderr.trim()||`exit ${J.code}`}`}function Mj0($){return/no server running|failed to connect to server|no sessions/i.test(`${$.stdout}
757
757
  ${$.stderr}`)}function Nj0($){return $.split(`
758
758
  `).map((J)=>Number.parseInt(J.trim(),10)).filter((J)=>Number.isFinite(J)&&J>1)}function Lj0($){let J=[];for(let Z of $.split(`
759
759
  `).slice(1)){let X=Z.trim().split(/\s+/);if(X.length<4)continue;let z=Number.parseInt(X[0]??"",10),G=Number.parseInt(X[1]??"",10),W=Number.parseInt(X[2]??"",10);if(!Number.isFinite(z)||!Number.isFinite(G)||!Number.isFinite(W))continue;J.push({pid:z,pgid:G,rssKb:W,command:X.slice(3).join(" ")})}return J}function Oj0($,J){let Z=new Set(J);return $.filter((X)=>Z.has(X.pgid))}function VG($,J,Z=null){return{available:$,version:J,sessions:[],panePids:[],processes:[],error:Z}}async function $C($="kobe"){let J=await e_(["tmux","-V"]);if(J.missing)return VG(!1,null);if(J.code!==0)return VG(!0,null,CM("tmux -V",J));let Z=J.stdout.trim()||null,X=await iw($,["list-sessions","-F","#{session_name}"]);if(X.code!==0){if(Mj0(X))return VG(!0,Z);return VG(!0,Z,CM("tmux list-sessions",X))}let z=X.stdout.split(`
@@ -79,7 +79,7 @@ You were spawned by Rove task ${Z}. When the work is finished, send your outcome
79
79
  `).split(`
80
80
  `).map((X)=>(X.split("\r").pop()??"").slice(0,kW0));while(Z.length>0&&(Z[Z.length-1]??"").trim()==="")Z.pop();return Z.slice(-vW0)}function AF($=QH()){try{let J=JSON.parse(fW0($,"utf8"));if(J===null||typeof J!=="object"||Array.isArray(J))return{};return J}catch{return{}}}function cT($,J=QH()){if($.key.startsWith("::"))return;if($.exit.code===0&&$.exit.signal===null)return;let Z=AF(J);Z[$.key]={key:$.key,pid:$.pid,code:$.exit.code,signal:$.exit.signal,at:$.exit.at,tail:Wc($.tail)};let X=Object.values(Z).sort((z,G)=>z.at<G.at?1:-1).slice(0,gW0);xW0(bW0(J),{recursive:!0}),yW0(J,JSON.stringify(Object.fromEntries(X.map((z)=>[z.key,z])),null,2),"utf8")}var gW0=50,vW0=40,kW0=500,mW0;var DF=c(()=>{B7();mW0=/\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?|\x1b[@-_]/g});var Uc={};A$(Uc,{setRepoLastActiveVendor:()=>iZ,setGlobalDefaultVendor:()=>pT,resolvePreferredVendor:()=>F9,getRepoLastActiveVendor:()=>Hc,getGlobalDefaultVendor:()=>$V});function dT($,J){let Z=$?.trim();if(!Z)return;if(n7(Z)||J.includes(Z))return Z;return}function Hc($){return dT(w5(qc+$),x2())}function iZ($,J){X6(qc+$,J)}function $V(){let $=x2();return dT(w5("defaultVendor"),$)??dT(w5("lastSelectedVendor"),$)}function pT($){X6("defaultVendor",$)}function F9($){return($?Hc($):void 0)??$V()??H4}var qc="lastActiveVendor.";var IJ=c(()=>{R7();J7();A4()});function z8($=process.env){return{...$,...nT}}var nT;var oZ=c(()=>{nT={GIT_OPTIONAL_LOCKS:"0"}});function Bc($){return $>="0"&&$<="7"}function Mc($,J){let Z=[],X="",z=()=>{if(X.length>0){for(let W of hW0.encode(X))Z.push(W);X=""}},G=J+1;while(G<$.length){let W=$[G];if(W==='"'){G++;break}if(W==="\\"){let q=$[G+1];if(q===void 0){X+="\\",G++;continue}switch(q){case"a":z(),Z.push(7),G+=2;break;case"b":z(),Z.push(8),G+=2;break;case"t":z(),Z.push(9),G+=2;break;case"n":z(),Z.push(10),G+=2;break;case"v":z(),Z.push(11),G+=2;break;case"f":z(),Z.push(12),G+=2;break;case"r":z(),Z.push(13),G+=2;break;case'"':X+='"',G+=2;break;case"\\":X+="\\",G+=2;break;default:if(Bc(q)){let U="",B=G+1;while(B<$.length&&U.length<3&&Bc($[B]))U+=$[B],B++;z(),Z.push(Number.parseInt(U,8)&255),G=B}else X+=q,G+=2;break}}else X+=W,G++}return z(),{value:uW0.decode(new Uint8Array(Z)),end:G}}function EJ($){if($.length===0||$[0]!=='"')return $;return Mc($,0).value}function Nc($,J){if($[0]==='"'){let X=Mc($,0);if($.startsWith(J,X.end))return{orig:X.value,neu:EJ($.slice(X.end+J.length))};return null}let Z=$.indexOf(J);if(Z<0)return null;return{orig:$.slice(0,Z),neu:EJ($.slice(Z+J.length))}}function Kc($,J,Z){if(J.length===0&&$.endsWith("/")&&Z.startsWith("/"))return $+Z.slice(1);return $+J+Z}function cW0($){let J=$.indexOf("{");if(J>=0){let X=$.indexOf("}",J),z=$.indexOf(" => ",J);if(X>J&&z>=0&&z<X){let G=$.slice(0,J),W=$.slice(J+1,z),q=$.slice(z+4,X),U=$.slice(X+1);return{path:Kc(G,q,U),origPath:Kc(G,W,U)}}}let Z=Nc($," => ");if(Z)return{path:Z.neu,origPath:Z.orig};return{path:EJ($)}}function JV($){let J=[];for(let Z of $.split(`
81
81
  `)){let X=Z.replace(/\r$/,"");if(X.length<4)continue;if(X.startsWith("##"))continue;let z=X[0],G=X[1];if(X[2]!==" ")continue;let W=X.slice(3);if(z==="R"||z==="C"||G==="R"||G==="C"){let q=Nc(W," -> ");if(q){J.push({x:z,y:G,path:q.neu,origPath:q.orig});continue}}J.push({x:z,y:G,path:EJ(W)})}return J}function Fc($){if($==="-")return null;let J=Number.parseInt($,10);return Number.isNaN(J)?null:J}function Lc($){let J=[];for(let Z of $.split(`
82
- `)){let X=Z.replace(/\r$/,"");if(X.length===0)continue;let z=X.indexOf("\t");if(z<0)continue;let G=X.indexOf("\t",z+1);if(G<0)continue;let W=X.slice(G+1);if(W.length===0)continue;let q=cW0(W);if(q.path.length===0)continue;J.push({path:q.path,...q.origPath!==void 0?{origPath:q.origPath}:{},added:Fc(X.slice(0,z)),deleted:Fc(X.slice(z+1,G))})}return J}var hW0,uW0;var ZV=c(()=>{hW0=new TextEncoder,uW0=new TextDecoder});var Oc={};A$(Oc,{sameWorktreeChanges:()=>PF,readWorktreeChanges:()=>dW0,pickPushedChanges:()=>iT,parsePorcelain:()=>AH});import{spawnSync as lW0}from"child_process";function PF($,J){return $.added===J.added&&$.deleted===J.deleted}function iT($,J){if(!$)return null;return $.get(J)??XV}function dW0($){if(!$)return XV;try{let J=lW0("git",["status","--porcelain=v1"],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});if(J.status!==0||!J.stdout)return XV;return AH(J.stdout)}catch{return XV}}function AH($){let J=0,Z=0;for(let{x:X,y:z}of JV($))if(X==="D"||z==="D")Z+=1;else J+=1;return{added:J,deleted:Z}}var XV;var DH=c(()=>{oZ();ZV();XV={added:0,deleted:0}});var Cc={};A$(Cc,{resolveBaseRef:()=>Vc,readBranchSignals:()=>nW0,parseShortstat:()=>_c});import{spawnSync as pW0}from"child_process";function QV($,J){try{let Z=pW0("git",[...J],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});return Z.status===0?Z.stdout.trim():null}catch{return null}}function Vc($){let J=QV($,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(J)return J;for(let Z of["origin/main","origin/master","main","master"])if(QV($,["rev-parse","--verify","--quiet",Z])!==null)return Z;return null}function _c($){let J=(Z)=>{let X=$.match(Z);return X?Number.parseInt(X[1]??"0",10):0};return{files:J(/(\d+) files? changed/),insertions:J(/(\d+) insertions?\(\+\)/),deletions:J(/(\d+) deletions?\(-\)/)}}function nW0($){if(!$)return jc;let J=Vc($);if(!J)return jc;let Z=QV($,["rev-list","--count",`${J}..HEAD`]),X=Z===null?null:Number.parseInt(Z,10),z=QV($,["diff","--shortstat",`${J}...HEAD`]),G=z===null?null:_c(z);return{baseRef:J,ahead:X!==null&&Number.isNaN(X)?null:X,diff:G}}var jc;var Ac=c(()=>{oZ();jc={baseRef:null,ahead:null,diff:null}});async function iW0($,J,Z){let X;try{X=await LT()}catch(z){throw new K1(`failed to start PTY host for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}try{if($.tab&&$.tab!=="new"){let L=B2({command:$.command,vendor:$.vendor,effort:$.modelEffort})[0];return await VT(X.rpc,$.id,$.tab,J,Z,{engineBin:L})}let z=$.tab==="new"?Gc($.id,$.tabVendor,$.tabCommand):void 0,G=$.tabVendor??$.vendor,W=$.tabCommand??($.tabVendor?void 0:$.command),{argv:q,sessionId:U}=nQ(B2({command:W,vendor:G,effort:$.modelEffort}),G);MH(G,J);let B=FH({task:{id:$.id,kind:$.kind,vendor:G,repo:$.repo},worktreePath:J,shell:process.env.SHELL?.trim()||"/bin/zsh",argv:q,promptIntent:$.newTask?{kind:"new-task",prompt:Z,spawnerTaskId:(await UH())?.taskId}:{kind:"explicit",prompt:Z},tabId:z}),M=await jT(X.rpc,{id:$.id,engineBin:q[0]},J,Z,B,{forceNew:z!==void 0});if(M.started&&!M.engineReady)throw new K1(`failed to start hosted engine session for ${$.id}`,"SESSION_FAILED");if(M.started&&U)if(z)Yc($.id,z,U);else hT($.id,U);else if(!z)hT($.id);return M}catch(z){if(z instanceof K1)throw z;throw new K1(`hosted engine session failed for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}finally{X.close()}}async function oT($,J,Z,X=oW0){let z=J.worktreePath;if(!z)z=(await $.request("task.ensureWorktree",{taskId:J.id})).worktreePath;if(!z)throw new K1(`task ${J.id} has no worktree`,"NO_WORKTREE");let G=await X.deliverHosted(J,z,Z);if(!G)throw new K1(`failed to start hosted engine session for ${J.id}`,"SESSION_FAILED");return G}var oW0,RF;var TF=c(()=>{U9();Z7();kj();mj();uj();MF();Pj();uT();$8();oW0={deliverHosted:iW0};RF={isTaskRunning:async($)=>(await RF.taskTabs($)).running,taskTabs:async($)=>{let J=[],Z=await qH();if(Z)try{J=await HH(Z.rpc)}finally{Z.close()}let X;try{let{foregroundEngineIn:W,parsePsSnapshot:q,psSnapshot:U}=await Promise.resolve().then(() => (AJ(),Uj)),B=J.filter((M)=>M.alive&&typeof M.pid==="number"&&M.pid>0);if(B.length>0){let M=q(await U());X=new Map(B.map((L)=>[L.key,W(M,L.pid)?.vendor??null]))}}catch{}let z={};try{z=(await Promise.resolve().then(() => (DF(),lT))).readPtyExitRecords()}catch{}let G=Zc($);return{tabs:Qc(G,$,J,z,X),running:zc(G,$,J)}},deliverPrompt:($,J,Z)=>oT($,J,Z),resolveRepoRoot:async($)=>(await Promise.resolve().then(() => (A4(),lq))).resolveMainRepoRoot($),defaultVendor:async($)=>{let{getGlobalDefaultVendor:J,getRepoLastActiveVendor:Z}=await Promise.resolve().then(() => (IJ(),Uc));return($?Z($):void 0)??J()},readWorktreeChanges:async($)=>(await Promise.resolve().then(() => (DH(),Oc))).readWorktreeChanges($),readBranchSignals:async($)=>(await Promise.resolve().then(() => (Ac(),Cc))).readBranchSignals($),tearDownSession:async($)=>{let J=await qH();if(J)try{await _T(J.rpc,NT(await HH(J.rpc),$))}catch{}finally{J.close()}}}});var zV;var Dc=c(()=>{zV={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.193",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://github.com/Sma1lboy/rove#readme",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/mock-host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.16","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]}});var Rc={};A$(Rc,{repoSlug:()=>tY,releasePageUrl:()=>$S,recommendedGlobalInstallCommand:()=>sT,isNewerSemver:()=>aT,fetchReleaseSummaries:()=>IF,fetchReleaseNotesRange:()=>eT,fetchReleaseNotes:()=>tT,compareSemver:()=>A3,checkLatestVersion:()=>eY,breakingVersionsCrossed:()=>SF,UPDATE_SCRIPT_URL:()=>YV,UPDATE_COMMAND:()=>wJ,PACKAGE_NAME:()=>rT,CURRENT_VERSION:()=>D$,BREAKING_VERSIONS:()=>aZ});function tY(){let $=zV.repository?.url;if(!$)return null;let J=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!J||!J[1]||!J[2])return null;return`${J[1]}/${J[2]}`}function sT(){return`npm install -g ${rT}@latest`}function SF($,J,Z=aZ){let[X,z]=A3($,J)<=0?[$,J]:[J,$];return Z.filter((G)=>A3(G,X)>0&&A3(G,z)<=0)}async function rW0($){let J=new AbortController,Z=setTimeout(()=>J.abort(),GV);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:J.signal,headers:{accept:"application/json"}});if(!z.ok)return null;let G=await z.json();if(typeof G.version!=="string")return null;return G.version}catch{return null}finally{clearTimeout(Z)}}function aT($,J){return A3($,J)>0}function A3($,J){let Z=(G)=>G.split("-")[0]??G,X=Z($).split(".").map((G)=>Number.parseInt(G,10)),z=Z(J).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,q=z[G]??0;if(Number.isNaN(W)||Number.isNaN(q))return 0;if(W>q)return 1;if(W<q)return-1}return 0}async function eY($={}){let J=process.env.KOBE_FAKE_UPDATE;if(J)return{current:D$,latest:J,hasUpdate:aT(J,D$)};if(kq()&&!$.force)return null;let Z=await rW0(rT);if(!Z)return null;return{current:D$,latest:Z,hasUpdate:aT(Z,D$)}}function Pc($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function tT($){let J=tY();if(!J)return null;let Z=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases/tags/${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return null;let W=await G.json();if(typeof W.body!=="string"||typeof W.html_url!=="string")return null;return{body:W.body,url:W.html_url,version:$}}catch{return null}finally{clearTimeout(z)}}async function eT($){let J=tY();if(!J)return[];let Z=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return[];let W=await G.json();if(!Array.isArray(W))return[];return W.map((q)=>{let U=Pc(q.tag_name);if(!U||typeof q.html_url!=="string"||typeof q.body!=="string")return null;if(A3(U,$.current)<=0)return null;if(A3(U,$.latest)>0)return null;return{version:U,url:q.html_url,body:q.body}}).filter((q)=>q!==null)}catch{return[]}finally{clearTimeout(z)}}async function IF($=12){let J=tY();if(!J)return[];let Z=new AbortController,X=setTimeout(()=>Z.abort(),GV);try{let z=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${$}`,{signal:Z.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!z.ok)return[];let G=await z.json();if(!Array.isArray(G))return[];return G.map((W)=>{let q=Pc(W.tag_name);if(!q||typeof W.html_url!=="string")return null;return{version:q,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function $S($){let J=tY();if(!J)return null;return`https://github.com/${J}/releases/tag/v${$}`}var D$,rT,YV="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",wJ,aZ,GV=3000;var d8=c(()=>{Dc();_5();D$=zV.version,rT=zV.name;wJ=`curl -fsSL ${YV} | sh`;aZ=[]});var sW0,sQ;var JS=c(()=>{/*!
82
+ `)){let X=Z.replace(/\r$/,"");if(X.length===0)continue;let z=X.indexOf("\t");if(z<0)continue;let G=X.indexOf("\t",z+1);if(G<0)continue;let W=X.slice(G+1);if(W.length===0)continue;let q=cW0(W);if(q.path.length===0)continue;J.push({path:q.path,...q.origPath!==void 0?{origPath:q.origPath}:{},added:Fc(X.slice(0,z)),deleted:Fc(X.slice(z+1,G))})}return J}var hW0,uW0;var ZV=c(()=>{hW0=new TextEncoder,uW0=new TextDecoder});var Oc={};A$(Oc,{sameWorktreeChanges:()=>PF,readWorktreeChanges:()=>dW0,pickPushedChanges:()=>iT,parsePorcelain:()=>AH});import{spawnSync as lW0}from"child_process";function PF($,J){return $.added===J.added&&$.deleted===J.deleted}function iT($,J){if(!$)return null;return $.get(J)??XV}function dW0($){if(!$)return XV;try{let J=lW0("git",["status","--porcelain=v1"],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});if(J.status!==0||!J.stdout)return XV;return AH(J.stdout)}catch{return XV}}function AH($){let J=0,Z=0;for(let{x:X,y:z}of JV($))if(X==="D"||z==="D")Z+=1;else J+=1;return{added:J,deleted:Z}}var XV;var DH=c(()=>{oZ();ZV();XV={added:0,deleted:0}});var Cc={};A$(Cc,{resolveBaseRef:()=>Vc,readBranchSignals:()=>nW0,parseShortstat:()=>_c});import{spawnSync as pW0}from"child_process";function QV($,J){try{let Z=pW0("git",[...J],{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"],env:z8()});return Z.status===0?Z.stdout.trim():null}catch{return null}}function Vc($){let J=QV($,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(J)return J;for(let Z of["origin/main","origin/master","main","master"])if(QV($,["rev-parse","--verify","--quiet",Z])!==null)return Z;return null}function _c($){let J=(Z)=>{let X=$.match(Z);return X?Number.parseInt(X[1]??"0",10):0};return{files:J(/(\d+) files? changed/),insertions:J(/(\d+) insertions?\(\+\)/),deletions:J(/(\d+) deletions?\(-\)/)}}function nW0($){if(!$)return jc;let J=Vc($);if(!J)return jc;let Z=QV($,["rev-list","--count",`${J}..HEAD`]),X=Z===null?null:Number.parseInt(Z,10),z=QV($,["diff","--shortstat",`${J}...HEAD`]),G=z===null?null:_c(z);return{baseRef:J,ahead:X!==null&&Number.isNaN(X)?null:X,diff:G}}var jc;var Ac=c(()=>{oZ();jc={baseRef:null,ahead:null,diff:null}});async function iW0($,J,Z){let X;try{X=await LT()}catch(z){throw new K1(`failed to start PTY host for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}try{if($.tab&&$.tab!=="new"){let L=B2({command:$.command,vendor:$.vendor,effort:$.modelEffort})[0];return await VT(X.rpc,$.id,$.tab,J,Z,{engineBin:L})}let z=$.tab==="new"?Gc($.id,$.tabVendor,$.tabCommand):void 0,G=$.tabVendor??$.vendor,W=$.tabCommand??($.tabVendor?void 0:$.command),{argv:q,sessionId:U}=nQ(B2({command:W,vendor:G,effort:$.modelEffort}),G);MH(G,J);let B=FH({task:{id:$.id,kind:$.kind,vendor:G,repo:$.repo},worktreePath:J,shell:process.env.SHELL?.trim()||"/bin/zsh",argv:q,promptIntent:$.newTask?{kind:"new-task",prompt:Z,spawnerTaskId:(await UH())?.taskId}:{kind:"explicit",prompt:Z},tabId:z}),M=await jT(X.rpc,{id:$.id,engineBin:q[0]},J,Z,B,{forceNew:z!==void 0});if(M.started&&!M.engineReady)throw new K1(`failed to start hosted engine session for ${$.id}`,"SESSION_FAILED");if(M.started&&U)if(z)Yc($.id,z,U);else hT($.id,U);else if(!z)hT($.id);return M}catch(z){if(z instanceof K1)throw z;throw new K1(`hosted engine session failed for ${$.id}: ${z instanceof Error?z.message:String(z)}`,"SESSION_FAILED")}finally{X.close()}}async function oT($,J,Z,X=oW0){let z=J.worktreePath;if(!z)z=(await $.request("task.ensureWorktree",{taskId:J.id})).worktreePath;if(!z)throw new K1(`task ${J.id} has no worktree`,"NO_WORKTREE");let G=await X.deliverHosted(J,z,Z);if(!G)throw new K1(`failed to start hosted engine session for ${J.id}`,"SESSION_FAILED");return G}var oW0,RF;var TF=c(()=>{U9();Z7();kj();mj();uj();MF();Pj();uT();$8();oW0={deliverHosted:iW0};RF={isTaskRunning:async($)=>(await RF.taskTabs($)).running,taskTabs:async($)=>{let J=[],Z=await qH();if(Z)try{J=await HH(Z.rpc)}finally{Z.close()}let X;try{let{foregroundEngineIn:W,parsePsSnapshot:q,psSnapshot:U}=await Promise.resolve().then(() => (AJ(),Uj)),B=J.filter((M)=>M.alive&&typeof M.pid==="number"&&M.pid>0);if(B.length>0){let M=q(await U());X=new Map(B.map((L)=>[L.key,W(M,L.pid)?.vendor??null]))}}catch{}let z={};try{z=(await Promise.resolve().then(() => (DF(),lT))).readPtyExitRecords()}catch{}let G=Zc($);return{tabs:Qc(G,$,J,z,X),running:zc(G,$,J)}},deliverPrompt:($,J,Z)=>oT($,J,Z),resolveRepoRoot:async($)=>(await Promise.resolve().then(() => (A4(),lq))).resolveMainRepoRoot($),defaultVendor:async($)=>{let{getGlobalDefaultVendor:J,getRepoLastActiveVendor:Z}=await Promise.resolve().then(() => (IJ(),Uc));return($?Z($):void 0)??J()},readWorktreeChanges:async($)=>(await Promise.resolve().then(() => (DH(),Oc))).readWorktreeChanges($),readBranchSignals:async($)=>(await Promise.resolve().then(() => (Ac(),Cc))).readBranchSignals($),tearDownSession:async($)=>{let J=await qH();if(J)try{await _T(J.rpc,NT(await HH(J.rpc),$))}catch{}finally{J.close()}}}});var zV;var Dc=c(()=>{zV={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.194",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://github.com/Sma1lboy/rove#readme",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:mock-react-task-dialogs":"KOBE_DEV=1 bun ./src/tui-react/component/mock-dialogs-host.tsx","dev:mock-react-filetree":"KOBE_DEV=1 bun ./src/tui-react/panes/filetree/mock-host.tsx","dev:mock-react-sidebar":"KOBE_DEV=1 bun ./src/tui-react/panes/sidebar/mock-host.tsx","dev:mock-react-terminal":"KOBE_DEV=1 bun ./src/tui-react/panes/terminal/mock-host.tsx","dev:mock-react-dialogs":"KOBE_DEV=1 bun ./src/tui-react/mock/dialogs-host.tsx","dev:mock-react-workspace":"KOBE_DEV=1 bun ./src/tui-react/workspace/mock-host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:with-web":"bun run build",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun test test/render --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir=coverage-render",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.16","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","kobe-web":"workspace:*","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]}});var Rc={};A$(Rc,{repoSlug:()=>tY,releasePageUrl:()=>$S,recommendedGlobalInstallCommand:()=>sT,isNewerSemver:()=>aT,fetchReleaseSummaries:()=>IF,fetchReleaseNotesRange:()=>eT,fetchReleaseNotes:()=>tT,compareSemver:()=>A3,checkLatestVersion:()=>eY,breakingVersionsCrossed:()=>SF,UPDATE_SCRIPT_URL:()=>YV,UPDATE_COMMAND:()=>wJ,PACKAGE_NAME:()=>rT,CURRENT_VERSION:()=>D$,BREAKING_VERSIONS:()=>aZ});function tY(){let $=zV.repository?.url;if(!$)return null;let J=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!J||!J[1]||!J[2])return null;return`${J[1]}/${J[2]}`}function sT(){return`npm install -g ${rT}@latest`}function SF($,J,Z=aZ){let[X,z]=A3($,J)<=0?[$,J]:[J,$];return Z.filter((G)=>A3(G,X)>0&&A3(G,z)<=0)}async function rW0($){let J=new AbortController,Z=setTimeout(()=>J.abort(),GV);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:J.signal,headers:{accept:"application/json"}});if(!z.ok)return null;let G=await z.json();if(typeof G.version!=="string")return null;return G.version}catch{return null}finally{clearTimeout(Z)}}function aT($,J){return A3($,J)>0}function A3($,J){let Z=(G)=>G.split("-")[0]??G,X=Z($).split(".").map((G)=>Number.parseInt(G,10)),z=Z(J).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,q=z[G]??0;if(Number.isNaN(W)||Number.isNaN(q))return 0;if(W>q)return 1;if(W<q)return-1}return 0}async function eY($={}){let J=process.env.KOBE_FAKE_UPDATE;if(J)return{current:D$,latest:J,hasUpdate:aT(J,D$)};if(kq()&&!$.force)return null;let Z=await rW0(rT);if(!Z)return null;return{current:D$,latest:Z,hasUpdate:aT(Z,D$)}}function Pc($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function tT($){let J=tY();if(!J)return null;let Z=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases/tags/${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return null;let W=await G.json();if(typeof W.body!=="string"||typeof W.html_url!=="string")return null;return{body:W.body,url:W.html_url,version:$}}catch{return null}finally{clearTimeout(z)}}async function eT($){let J=tY();if(!J)return[];let Z=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),GV);try{let G=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${Z}`,{signal:X.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!G.ok)return[];let W=await G.json();if(!Array.isArray(W))return[];return W.map((q)=>{let U=Pc(q.tag_name);if(!U||typeof q.html_url!=="string"||typeof q.body!=="string")return null;if(A3(U,$.current)<=0)return null;if(A3(U,$.latest)>0)return null;return{version:U,url:q.html_url,body:q.body}}).filter((q)=>q!==null)}catch{return[]}finally{clearTimeout(z)}}async function IF($=12){let J=tY();if(!J)return[];let Z=new AbortController,X=setTimeout(()=>Z.abort(),GV);try{let z=await fetch(`https://api.github.com/repos/${J}/releases?per_page=${$}`,{signal:Z.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!z.ok)return[];let G=await z.json();if(!Array.isArray(G))return[];return G.map((W)=>{let q=Pc(W.tag_name);if(!q||typeof W.html_url!=="string")return null;return{version:q,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function $S($){let J=tY();if(!J)return null;return`https://github.com/${J}/releases/tag/v${$}`}var D$,rT,YV="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",wJ,aZ,GV=3000;var d8=c(()=>{Dc();_5();D$=zV.version,rT=zV.name;wJ=`curl -fsSL ${YV} | sh`;aZ=[]});var sW0,sQ;var JS=c(()=>{/*!
83
83
  * Copyright (c) Squirrel Chat et al., All rights reserved.
84
84
  * SPDX-License-Identifier: BSD-3-Clause
85
85
  *
@@ -753,7 +753,7 @@ ${Z}: your Rove agent skill is out of date (${W}; this Rove wants v${z.currentVe
753
753
  ${Z}: a new version of the Rove agent skill is available (${W} \u2192 v${z.currentVersion}).
754
754
  Update now? [y]es / [n]o / [d]on't notify for this version: `);let U=(await($.ask??Fj0)()).trim().toLowerCase();if(U==="y"||U==="yes"){let B=await($.install??nw)();if(B===0)process.stderr.write(`${Z}: skill updated.
755
755
  `);else process.stderr.write(`${Z}: skill update failed (exit ${B}) \u2014 run \`${X}\` manually.
756
- `)}else if(U.startsWith("d"))X6(G,"1")}var lw=32,Uj0,Bj0="Sma1lboy/rove",dw="skillHintSeen";var _M=c(()=>{x4();EQ();A4();Uj0=[".agents/skills/rove/SKILL.md",".claude/skills/rove/SKILL.md",".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});async function e_($){try{let J=Bun.spawn([...$],{stdin:"ignore",stdout:"pipe",stderr:"pipe"}),[Z,X,z]=await Promise.all([new Response(J.stdout).text().catch(()=>""),new Response(J.stderr).text().catch(()=>""),J.exited]);return{code:z,stdout:Z,stderr:X,missing:!1}}catch(J){let Z=J;return{code:127,stdout:"",stderr:J instanceof Error?J.message:String(J),missing:Z.code==="ENOENT"}}}async function iw($,J){return e_(["tmux","-L",$,...J])}function CM($,J){return`${$} failed: ${J.stderr.trim()||`exit ${J.code}`}`}function Mj0($){return/no server running|failed to connect to server|no sessions/i.test(`${$.stdout}
756
+ `)}else if(U.startsWith("d"))X6(G,"1")}var lw=33,Uj0,Bj0="Sma1lboy/rove",dw="skillHintSeen";var _M=c(()=>{x4();EQ();A4();Uj0=[".agents/skills/rove/SKILL.md",".claude/skills/rove/SKILL.md",".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});async function e_($){try{let J=Bun.spawn([...$],{stdin:"ignore",stdout:"pipe",stderr:"pipe"}),[Z,X,z]=await Promise.all([new Response(J.stdout).text().catch(()=>""),new Response(J.stderr).text().catch(()=>""),J.exited]);return{code:z,stdout:Z,stderr:X,missing:!1}}catch(J){let Z=J;return{code:127,stdout:"",stderr:J instanceof Error?J.message:String(J),missing:Z.code==="ENOENT"}}}async function iw($,J){return e_(["tmux","-L",$,...J])}function CM($,J){return`${$} failed: ${J.stderr.trim()||`exit ${J.code}`}`}function Mj0($){return/no server running|failed to connect to server|no sessions/i.test(`${$.stdout}
757
757
  ${$.stderr}`)}function Nj0($){return $.split(`
758
758
  `).map((J)=>Number.parseInt(J.trim(),10)).filter((J)=>Number.isFinite(J)&&J>1)}function Lj0($){let J=[];for(let Z of $.split(`
759
759
  `).slice(1)){let X=Z.trim().split(/\s+/);if(X.length<4)continue;let z=Number.parseInt(X[0]??"",10),G=Number.parseInt(X[1]??"",10),W=Number.parseInt(X[2]??"",10);if(!Number.isFinite(z)||!Number.isFinite(G)||!Number.isFinite(W))continue;J.push({pid:z,pgid:G,rssKb:W,command:X.slice(3).join(" ")})}return J}function Oj0($,J){let Z=new Set(J);return $.filter((X)=>Z.has(X.pgid))}function VG($,J,Z=null){return{available:$,version:J,sessions:[],panePids:[],processes:[],error:Z}}async function $C($="kobe"){let J=await e_(["tmux","-V"]);if(J.missing)return VG(!1,null);if(J.code!==0)return VG(!0,null,CM("tmux -V",J));let Z=J.stdout.trim()||null,X=await iw($,["list-sessions","-F","#{session_name}"]);if(X.code!==0){if(Mj0(X))return VG(!0,Z);return VG(!0,Z,CM("tmux list-sessions",X))}let z=X.stdout.split(`
@@ -3,7 +3,7 @@ name: rove
3
3
  description: Use when controlling Rove tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell. Also the ONLY channel for messaging another agent session on this machine — `rove api send`, never a peer/MCP side channel.
4
4
  ---
5
5
 
6
- <!-- rove-skill-version: 32 — bump in lockstep with KOBE_SKILL_VERSION (src/lib/skill-install.ts). -->
6
+ <!-- rove-skill-version: 33 — bump in lockstep with KOBE_SKILL_VERSION (src/lib/skill-install.ts). -->
7
7
 
8
8
  # Rove shell control
9
9
 
@@ -208,15 +208,35 @@ build artifacts, nothing a lockfile promises. Two consequences:
208
208
 
209
209
  ## Discover before calling
210
210
 
211
+ Do not guess flags — but do not pay a round-trip for the ones you use every
212
+ turn either. These five carry almost all traffic:
213
+
214
+ ```text
215
+ add --repo(REQ) --prompt --title --command --count --agents --activate
216
+ send --prompt(REQ) --task-id --tab --command --plain
217
+ get-task --task-id(REQ) list (no flags)
218
+ collect --task-ids <csv> | --repo
219
+ ```
220
+
221
+ Four names that have actually been guessed wrong here: `add --vendor` is
222
+ `--command`; `read-output --task` is `--task-id`; `dispatch --text` is
223
+ `--prompt` (`--text` belongs to `note`); `issue-list` has no `--state` at all
224
+ — filter its JSON yourself.
225
+
226
+ **[`references/api-flags.md`](references/api-flags.md) is every verb and flag**,
227
+ including the groups this file leaves out on purpose: `routine-*` (scheduled
228
+ prompts), `workitem-*` (GitHub issues via `gh`), `note`/`note-list` (the repo's
229
+ durable field-note store), `read-output`/`digest`/`agent-turns`/`pty-list`, and
230
+ the error-code table. Read it when you need a verb that is not above; reach for
231
+ `schema` when the binary and that file disagree.
232
+
211
233
  ```bash
212
- rove api schema
213
- rove api schema --verb add
214
- rove api schema --group create
234
+ rove api schema --verb add # or --group create, --all
215
235
  rove api <verb> --help
216
236
  rove api engine-list # what you can launch, and with what command
217
237
  ```
218
238
 
219
- Do not guess flags. Commands emit one JSON object; errors use
239
+ Commands emit one JSON object; errors use
220
240
  `{"error":{"message","code",...}}` on stderr. Common rejections also carry
221
241
  `hint` (what to do) and `nextCommandArgs` (argv for the same `Rove`
222
242
  executable — run `rove <args...>` verbatim to recover, e.g. `["api","list"]`
@@ -267,7 +287,8 @@ auto-start the canonical engine in the task's worktree (`started: true` in
267
287
  the result marks that fresh session). If live tabs exist but none resolves
268
288
  as an engine, it refuses with `NO_ENGINE_TAB` — address one with `--tab
269
289
  tab-N` or spawn one with `--tab new`; it never silently spawns a duplicate
270
- engine.
290
+ engine. Its `hint` names `pty-list` — the live-PTY read (key, alive, pid,
291
+ command); use it when `.tabs[]` and reality disagree.
271
292
 
272
293
  ## Terminal panes
273
294
 
@@ -0,0 +1,223 @@
1
+ # `rove api` flag reference
2
+
3
+ Every verb and flag, so you don't pay a `schema` round-trip to look one up.
4
+ SKILL.md covers the verbs you need for routing and lifecycle; this file is the
5
+ full surface, including the groups SKILL.md deliberately leaves out
6
+ (routines, GitHub work items, telemetry reads, field notes).
7
+
8
+ Authoritative source is still the binary — `rove api schema --verb <name>` or
9
+ `rove api <verb> --help`. Read that when this file and a rejection disagree;
10
+ the CLI is what ships.
11
+
12
+ Global: `--pretty` (readable JSON), `--help` (usage, exit).
13
+ Every `--repo` resolves relative paths against `$PWD` and wants the git toplevel.
14
+
15
+ ## The hot path
16
+
17
+ These five carry almost all traffic. Nothing here should ever need `schema`.
18
+
19
+ ```text
20
+ add --repo(REQ) --prompt --title --command --count --agents
21
+ --branch --base-branch --status --pin --activate
22
+ send --prompt(REQ) --task-id --tab --command --plain
23
+ get-task --task-id(REQ)
24
+ list (no flags)
25
+ collect --task-ids <csv> | --repo
26
+ ```
27
+
28
+ Four flag names that have actually been guessed wrong here, and what they are:
29
+
30
+ | Guessed | Real |
31
+ |---|---|
32
+ | `add --vendor` | `add --command` (engine id or full command line) |
33
+ | `read-output --task` | `read-output --task-id` |
34
+ | `dispatch --text` | `dispatch --prompt` (`--text` belongs to `note`) |
35
+ | `issue-list --state` | none — `issue-list` takes only `--repo`; filter the JSON yourself |
36
+
37
+ `--count`/`--agents` require `--prompt`. `--branch` is single-task only.
38
+ `--tab new` is the only placement that accepts `send --command`.
39
+
40
+ ## Retired — these no longer exist
41
+
42
+ | Gone | Now |
43
+ |---|---|
44
+ | `fan-out` | `add --count N` / `add --agents claude:2,codex:1` |
45
+ | `task-list` | `list` |
46
+ | `send-tab` | `send --tab tab-N` |
47
+ | `$KOBE_TASK_ID` / `$KOBE_TAB_ID` | `$ROVE_TASK_ID` / `$ROVE_TAB_ID` |
48
+
49
+ Seeing one of these in guidance means that guidance predates the rename —
50
+ `rove api schema` is the tiebreak.
51
+
52
+ ## read
53
+
54
+ ```text
55
+ list (none) every task, archived included
56
+ get-task --task-id(REQ) one task + .tabs[] — the read before `send --tab`
57
+ collect --task-ids <csv> --repo comparison snapshot across tasks
58
+ inspect --task-id daemon activity + pty walk + tab snapshots
59
+ pty-list (none) live hosted PTYs: key, alive, pid, command, OSC title
60
+ read-output --task-id --tab --source[auto|history|terminal] --cursor --limit
61
+ digest --repo(REQ) --since-days(7)
62
+ agent-turns --task-id --repo --since-days(7) --limit(200)
63
+ ```
64
+
65
+ `pty-list` is what `NO_ENGINE_TAB`'s hint points at: when `.tabs[]` and reality
66
+ disagree, it is the ground truth for what is actually alive.
67
+
68
+ `read-output --limit` maxes at 50 (default 40). `--tab` is terminal-only —
69
+ it cannot combine with `--source history`. The cursor is pinned to one
70
+ source/session/tab; a moved target returns `SOURCE_CHANGED` rather than
71
+ silently paging something else.
72
+
73
+ `digest` and `agent-turns` are the measurement reads — `digest` aggregates a
74
+ repo's recent task + routine activity, `agent-turns` is per-turn telemetry
75
+ (vendor, model, timings, tokens). Reach for them when a workflow question
76
+ needs numbers, not when you want to know what a task is doing.
77
+
78
+ ## drive
79
+
80
+ ```text
81
+ send --prompt(REQ) --task-id --tab --command --plain
82
+ dispatch --task-id(REQ) --prompt(REQ) --tab
83
+ note --task-id(REQ) --text(REQ)
84
+ note-list --repo(REQ)
85
+ pane-open --command --task-id --tab --direction[right|down] --placement[split|tab] --title
86
+ pane-close --title(REQ) --task-id --tab
87
+ notify --title(REQ) --kind --task-id --source
88
+ prompt --title(REQ) --placeholder --initial --timeout
89
+ set-active --task-id | --none
90
+ ```
91
+
92
+ **`note` is the repo's durable field-note store.** One line, a verified
93
+ conclusion another session could act on — it is appended to the repo's notes
94
+ (every future session on this repo starts with them) AND relayed to the
95
+ dispatcher. Read them back with `note-list --repo`. This is the right home for
96
+ a resolved gotcha; an issue is for work that still needs doing.
97
+
98
+ `notify --kind` styles the toast: `done`, `needs_input`, `error` get severity
99
+ treatment and an unread mark, anything else renders neutrally.
100
+
101
+ `prompt` blocks on a human answering the attached TUI's input dialog —
102
+ `--timeout` defaults to 120000ms, caps at 600000. Returns `{ value }` or
103
+ `{ cancelled, reason }`. No attached TUI means no answer.
104
+
105
+ `pane-open --command` runs through the login shell's `-ilc`, so pipes and
106
+ your rc's PATH work.
107
+
108
+ ## create / edit / lifecycle
109
+
110
+ ```text
111
+ add --repo(REQ) + the hot-path flags above
112
+ rename --task-id(REQ) --title(REQ)
113
+ set-branch --task-id(REQ) --branch(REQ)
114
+ set-command --task-id(REQ) --command(REQ) next launch only
115
+ set-status --task-id(REQ) --status(REQ)[backlog|in_progress|in_review|done|canceled|error]
116
+ archive --task-id(REQ) --archived(true)
117
+ pin --task-id(REQ) --pinned(true)
118
+ land --task-id(REQ) --strategy[merge|squash] --delete-branch --then-archive --remove-worktree
119
+ delete --task-id(REQ) --force --delete-branch
120
+ ```
121
+
122
+ Task `--status` and issue `--status` are DIFFERENT enums — a task is
123
+ `backlog|in_progress|in_review|done|canceled|error`, an issue is
124
+ `open|doing|hold|done`.
125
+
126
+ `land` refuses a dirty base checkout and refuses a branch with zero commits
127
+ ahead (`EMPTY_BRANCH`; `EMPTY_BRANCH_DIRTY_WORKTREE` when the worktree still
128
+ holds the uncommitted work, with a send-back recovery path). Conflict aborts
129
+ cleanly and returns the conflicted files.
130
+
131
+ ## worktree
132
+
133
+ ```text
134
+ ensure-worktree --task-id(REQ)
135
+ discover-adoptable --repo(REQ)
136
+ adopt --repo(REQ) --worktree(REQ) --branch --title --command
137
+ ```
138
+
139
+ ## issues (daemon-owned)
140
+
141
+ ```text
142
+ issue-list --repo(REQ)
143
+ issue-create --repo(REQ) --title(REQ) --body
144
+ issue-update --repo(REQ) --id(REQ,int) --title --body --task
145
+ issue-set-status --repo(REQ) --id(REQ,int) --status(REQ)[open|doing|hold|done]
146
+ ```
147
+
148
+ `--id` is an int, not the ULID a task uses. `issue-update --task <taskId>` is
149
+ the kanban "move to In progress"; `--task none` unlinks. Kanban semantics are
150
+ in SKILL.md — do not move cards with `issue-set-status doing`.
151
+
152
+ ## workitems (GitHub, through `gh`)
153
+
154
+ Read-only against the repo's real GitHub issues; nothing is copied into Rove's
155
+ own store. These are the INBOUND user reports; Rove issues are the backlog.
156
+
157
+ ```text
158
+ workitem-list --repo(REQ) --state[open|closed|all] --limit(20,max 50) --search --assignee --label
159
+ workitem-start --repo(REQ) --number(REQ,int) --vendor --base-branch
160
+ ```
161
+
162
+ `workitem-start` creates a worktree + engine whose first message carries the
163
+ issue title, body, and URL, and keeps a link back to the issue. Note it takes
164
+ `--vendor` (an engine enum), not `--command` — the one place the older
165
+ vocabulary survives.
166
+
167
+ ## routines (scheduled prompts)
168
+
169
+ Each firing creates a FRESH task — worktree, engine, delivered prompt. An
170
+ enabled routine holds the daemon alive so it fires with no TUI attached.
171
+
172
+ ```text
173
+ routine-list (none)
174
+ routine-create --repo(REQ) --name(REQ) --prompt(REQ) --schedule(REQ)
175
+ --vendor --base-branch --precheck --precheck-timeout(120) --grace(60) --disabled
176
+ routine-update --id(REQ) --name --prompt --schedule --vendor --base-branch --precheck --precheck-timeout --grace
177
+ routine-set-enabled --id(REQ) --enabled(REQ,bool)
178
+ routine-delete --id(REQ)
179
+ routine-run-now --id(REQ)
180
+ routine-runs --id(REQ)
181
+ ```
182
+
183
+ `--schedule` is five-field cron in the DAEMON HOST's local time
184
+ (`'0 9 * * MON-FRI'`). `--precheck` is a shell command run in the repo before
185
+ the engine starts — non-zero exit skips the run without spawning an agent,
186
+ which is the cheap way to not burn a turn on "nothing to do". `--grace` is how
187
+ late a missed occurrence may still run after the daemon was down; only the
188
+ most recent missed occurrence ever runs.
189
+
190
+ `routine-update --schedule` re-anchors the next run. `--precheck ''` clears it.
191
+ `routine-run-now` skips the precheck deliberately (asking for it IS the answer)
192
+ and does not shift the schedule. `routine-delete` leaves already-created tasks
193
+ alone.
194
+
195
+ Run statuses from `routine-runs`: `dispatched`, `skipped_precheck` (nothing to
196
+ do), `skipped_missed`, `skipped_unavailable`, `dispatch_failed`.
197
+
198
+ ## discover / feedback
199
+
200
+ ```text
201
+ schema --verb <name> | --group <g> | --all (bare = compact index)
202
+ engine-list (none) ids + RAW launch command + protocol
203
+ feedback --title(REQ) --body(REQ) --category(feedback)
204
+ ```
205
+
206
+ `feedback` opens a GitHub Discussion in the Rove repo through `gh` — Rove's own
207
+ product feedback channel, not a way to file work for another project (that is
208
+ a `send` to their main task; see SKILL.md).
209
+
210
+ ## Error codes
211
+
212
+ Errors go to stderr as `{"error":{"message","code",...}}`. Most carry `hint`
213
+ (what to do) and `nextCommandArgs` (argv for the same executable — run
214
+ `rove <args...>` verbatim).
215
+
216
+ | Code | Means | Recover |
217
+ |---|---|---|
218
+ | `BAD_FLAG` | flag not on that verb | check the table above, then `schema --verb <v>` |
219
+ | `TASK_NOT_FOUND` | id deleted or mistyped | `rove api list` |
220
+ | `NO_ENGINE_TAB` | live tabs exist, none is an engine | `--tab tab-N` from `pty-list`, or `--tab new` |
221
+ | `DISPATCHER_UNREACHABLE` | bare `send` reply, dispatcher gone | nothing alive to reply to — never silently spawns |
222
+ | `SOURCE_CHANGED` | `read-output` cursor's target moved | re-read without the cursor |
223
+ | `EMPTY_BRANCH` | `land` on zero commits ahead | the worker committed nothing |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sma1lboy/kobe",
4
- "version": "0.8.193",
4
+ "version": "0.8.194",
5
5
  "description": "Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.3.13",