@sma1lboy/kobe 0.8.194 → 0.8.195

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,7 @@ The published Rove CLI and PureTUI package.
5
5
  Install it any of these ways:
6
6
 
7
7
  ```bash
8
- curl -fsSL https://rove.sma1lboy.me/install.sh | sh # installs Bun if needed, then Rove
8
+ curl -fsSL https://rove.run/install.sh | sh # installs Bun if needed, then Rove
9
9
  npm install -g @sma1lboy/rove # npm
10
10
  bun install -g @sma1lboy/rove # bun
11
11
  npx @sma1lboy/rove # no install
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.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(()=>{/*!
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.195",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],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://rove.run",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
  *
@@ -830,7 +830,7 @@ You can run it yourself: ${jG({agent:X,global:z})}
830
830
  `),process.exit(W||1);process.stdout.write(`${B8} skill: installed.
831
831
  `)}var B8,yV0;var zx=c(()=>{_M();v4();B8=a1(),yV0=["install","status","command","print"]});function b00($){return`'${$.replace(/'/g,"'\\''")}'`}function Yx($,J,Z,X){let z=dH({homeDir:X.homeDir,socketPath:X.socketPath,binPath:X.binPath,pluginId:$,pluginRoot:J,extra:{ROVE_PLUGIN_ENTRYPOINT_ID:Z.id}}),G=Object.entries(z).filter(([U])=>U.startsWith("ROVE_")||U.startsWith("KOBE_")),W=Z.command.map((U)=>U.replace(/\$\{?(?:ROVE|KOBE)_PLUGIN_ROOT\}?/g,J)),q=`exec env ${G.map(([U,B])=>b00(`${U}=${B}`)).join(" ")} ${W.map(b00).join(" ")}`;return[b2(),"-ilc",q]}function g00($){let J=M9(),Z=[];for(let X of o4($.homeDir).plugins){if(!X.enabled)continue;try{let{manifest:z}=G6(X.root);if(!W6({},z,J))continue;for(let G of z.panes){if(!W6(G,z,J))continue;Z.push({pluginId:X.id,paneId:G.id,title:G.title,placement:G.placement,argv:Yx(X.id,X.root,G,$)})}}catch{}}return Z}var Gx=c(()=>{dZ();z_();rZ();gJ()});import{spawnSync as v00}from"child_process";import{cpSync as gV0,existsSync as vV0,mkdirSync as UC,readFileSync as k00,renameSync as kV0,rmSync as qx}from"fs";import{mkdtempSync as mV0}from"fs";import{basename as hV0,join as HC,resolve as uV0}from"path";import{createInterface as cV0}from"readline/promises";function p8($){throw new s4($)}function m00($){let J=RH($);if(!J)p8(`no ${UV.join(" or ")} found at ${$}`);let Z=k00(J,"utf8");return{...xF(Z,hV0(J)),manifestPath:J,manifestSource:Z}}function h00($){let J=$.manifest.minKobeVersion;if(A3(D$,J)<0)p8(`plugin requires Rove >= ${J} (this is ${D$}); update Rove first`)}function dV0($,J){let Z=$.manifest;console.log(`
832
832
  ${Z.name} (${Z.id}) v${Z.version} \u2014 ${Z.description??"no description"}`),console.log(`source: ${J}`);let X=(z,G)=>{for(let W of G)console.log(` ${z}: ${W.command.join(" ")}`)};X("build",Z.build),X("startup",Z.startup);for(let z of Z.actions)console.log(` action ${z.id}: ${z.command.join(" ")}`);for(let z of Z.events)console.log(` on ${z.on}: ${z.command.join(" ")}`);for(let z of $.warnings)console.log(` warning: ${z}`);console.log("")}async function pV0($){if($)return;if(!process.stdin.isTTY)p8("refusing to install without confirmation in a non-interactive terminal; pass --yes");let J=cV0({input:process.stdin,output:process.stdout}),Z=(await J.question("Install this plugin and run its build commands? [y/N] ")).trim().toLowerCase();if(J.close(),Z!=="y"&&Z!=="yes")p8("aborted")}function Wx($,J){if(v00("git",$,{cwd:J,stdio:["ignore","inherit","inherit"]}).status!==0)p8(`git ${$[0]} failed`)}function nV0($,J){let Z=M9();for(let[X,z]of $.manifest.build.entries()){if(!W6(z,$.manifest,Z))continue;let[G,...W]=z.command;console.log(`build[${X}]: ${z.command.join(" ")}`);let q=v00(G,W,{cwd:J,stdio:["ignore","inherit","inherit"]});if(q.status!==0)p8(`build[${X}] failed (exit ${q.status??"spawn error"}); plugin not registered`)}}function iV0(){let $=WS();return UC($,{recursive:!0}),mV0(HC($,".staging-"))}function oV0($,J){try{kV0($,J)}catch(Z){if(Z.code!=="EXDEV")throw Z;gV0($,J,{recursive:!0,verbatimSymlinks:!0}),qx($,{recursive:!0,force:!0})}}function u00($){bJ(bc(o4(),$)),UC(D3($.id),{recursive:!0}),UC(eQ($.id),{recursive:!0})}async function BC($,J){let Z=$.match(lV0);if(!Z)p8(`install takes GitHub shorthand (owner/repo[/subdir]), got \`${$}\``);let[,X,z,G]=Z,W=G?.replace(/^\//,""),q=iV0();try{let U=`https://github.com/${X}/${z}.git`;if(console.log(`cloning ${U}${J.ref?` @ ${J.ref}`:""}`),J.ref)Wx(["clone","--quiet",U,q]),Wx(["checkout","--quiet",J.ref],q);else Wx(["clone","--quiet","--depth","1",U,q]);let B=W?HC(q,W):q,M=m00(B);h00(M);let L=M.manifest.id,N=o4().plugins.find((_)=>_.id===L);if(N?.source.kind==="link")p8(`\`${L}\` is locally linked at ${N.root}; unlink it first`);if(!W6({},M.manifest,M9()))p8(`plugin declares platforms [${M.manifest.platforms?.join(", ")}]; this machine is unsupported`);dV0(M,`github.com/${X}/${z}${W?`/${W}`:""}`),await pV0(J.yes),nV0(M,B);let j=RH(B);if(!j)p8("manifest disappeared during build; aborting");if(j!==M.manifestPath)p8("manifest changed during build; aborting");if(k00(j,"utf8")!==M.manifestSource)p8("manifest changed during build; aborting");let C=SH(L);return qx(C,{recursive:!0,force:!0}),UC(HC(C,".."),{recursive:!0}),oV0(q,C),u00({id:L,source:{kind:"github",spec:$},root:W?HC(C,W):C,enabled:!0,version:M.manifest.version,installedAt:Date.now()}),console.log(`installed ${L} v${M.manifest.version}`),L}finally{qx(q,{recursive:!0,force:!0})}}function c00($){let J=uV0($);if(!vV0(J))p8(`no such directory: ${J}`);let Z=m00(J);h00(Z);let X=Z.manifest.id;if(o4().plugins.find((G)=>G.id===X)?.source.kind==="github")p8(`\`${X}\` is installed from GitHub; uninstall it before linking a local copy`);for(let G of Z.warnings)console.log(`warning: ${G}`);u00({id:X,source:{kind:"link"},root:J,enabled:!0,version:Z.manifest.version,installedAt:Date.now()}),console.log(`linked ${X} v${Z.manifest.version} \u2192 ${J}`)}var lV0,s4;var Hx=c(()=>{rZ();yJ();gJ();d8();lV0=/^([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)(\/.+)?$/;s4=class s4 extends Error{}});var d00={};A$(d00,{searchMarketplace:()=>tV0});async function l00($,J){let Z=encodeURIComponent(`topic:${$}${J?` ${J}`:""}`),X=new AbortController,z=setTimeout(()=>X.abort(),aV0);try{let G=await fetch(`https://api.github.com/search/repositories?q=${Z}&sort=stars&order=desc&per_page=50`,{signal:X.signal,headers:{accept:"application/vnd.github+json"}});if(!G.ok)return null;let W=await G.json();if(!Array.isArray(W.items))return null;return W.items.filter((q)=>typeof q.full_name==="string").map((q)=>({ref:q.full_name,desc:q.description??"",stars:q.stargazers_count}))}catch{return null}finally{clearTimeout(z)}}async function tV0($){let J=await Promise.all([l00("rove-plugin",$),l00("kobe-plugin",$)]),Z=$?.toLowerCase(),X=sV0.filter((W)=>!Z||`${W.ref} ${W.desc}`.toLowerCase().includes(Z)).map((W)=>({...W,firstParty:!0})),z=eV0([...X,...J.flatMap((W)=>W??[])]);if(J.every((W)=>W===null))console.error("(GitHub search unreachable \u2014 showing first-party plugins only)");if(z.length===0){console.log($?`no plugins match \`${$}\``:"no plugins found");return}let G=Math.min(48,Math.max(...z.map((W)=>W.ref.length))+2);for(let W of z){let q=W.stars!==void 0?`\u2605${W.stars}`:W.firstParty?"first-party":"";console.log(`${W.ref.padEnd(G)}${q.padEnd(12)}${W.desc}`)}console.log(`
833
- install: ${rV0} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.sma1lboy.me/plugins`)}function eV0($){let J=new Set;return $.filter((Z)=>{let X=Z.ref.toLowerCase();if(J.has(X))return!1;return J.add(X),!0})}var aV0=5000,rV0,sV0;var p00=c(()=>{v4();rV0=a1(),sV0=[{ref:"Sma1lboy/kobe-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/kobe-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/kobe-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/kobe-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/kobe-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/kobe-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}]});import{readFileSync as $_0,writeFileSync as J_0}from"fs";function n00($,J){let Z={checkedAt:Date.now(),outdated:$};try{J_0(qS(J),`${JSON.stringify(Z,null,2)}
833
+ install: ${rV0} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.run/plugins`)}function eV0($){let J=new Set;return $.filter((Z)=>{let X=Z.ref.toLowerCase();if(J.has(X))return!1;return J.add(X),!0})}var aV0=5000,rV0,sV0;var p00=c(()=>{v4();rV0=a1(),sV0=[{ref:"Sma1lboy/kobe-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/kobe-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/kobe-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/kobe-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/kobe-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/kobe-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}]});import{readFileSync as $_0,writeFileSync as J_0}from"fs";function n00($,J){let Z={checkedAt:Date.now(),outdated:$};try{J_0(qS(J),`${JSON.stringify(Z,null,2)}
834
834
  `)}catch{}}function i00($){try{let J=JSON.parse($_0(qS($),"utf8"));if(typeof J.checkedAt!=="number"||!Array.isArray(J.outdated))return[];if(Date.now()-J.checkedAt>Z_0)return[];return J.outdated.filter((Z)=>typeof Z==="string")}catch{return[]}}var Z_0=86400000;var Ux=c(()=>{yJ()});var Kx={};A$(Kx,{updatePlugins:()=>H_0,printOutdated:()=>W_0,listOutdated:()=>KC});import{execFileSync as X_0}from"child_process";import{existsSync as o00,mkdirSync as Q_0,readdirSync as z_0,renameSync as Y_0}from"fs";import{join as Bx}from"path";function a00($,J){try{return X_0("git",$,{cwd:J,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function G_0($){let J=$.source.spec.split("/").slice(0,2).join("/"),Z=a00(["rev-parse","HEAD"],SH($.id)),X=a00(["ls-remote",`https://github.com/${J}.git`,"HEAD"]),z=X?X.split(/\s+/)[0]??null:null;return{id:$.id,spec:$.source.spec,version:$.version,localSha:Z,remoteSha:z,behind:Boolean(Z&&z&&Z!==z)}}function KC(){let $=o4().plugins.filter((J)=>J.source.kind==="github").map(G_0);return n00($.filter((J)=>J.behind).map((J)=>J.id)),$}function W_0(){let $=KC();if($.length===0){console.log("no GitHub-installed plugins.");return}for(let J of $){let Z=J.behind?"update available":J.remoteSha===null?"remote unreachable":J.localSha===null?"local sha unreadable":"up to date";console.log(`${J.id} v${J.version} ${Z}`)}}function q_0($,J){for(let Z of[D3,eQ]){let X=Z($),z=Z(J);if(!o00(X))continue;Q_0(z,{recursive:!0});for(let G of z_0(X)){if(o00(Bx(z,G)))continue;Y_0(Bx(X,G),Bx(z,G))}}bJ(yF(o4(),$)),console.log(`renamed ${$} \u2192 ${J}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${TH($)}`)}async function H_0($,J){let Z=KC(),X;if(J.all){if(X=Z.filter((z)=>z.behind),X.length===0){console.log("all plugins up to date.");return}}else{if($.length===0)throw new s4("update takes plugin ids or --all");X=$.map((z)=>{let G=Z.find((W)=>W.id===z);if(!G)throw new s4(`\`${z}\` is not a GitHub-installed plugin; see \`${a1()} plugin list\``);return G})}for(let z of X){if(!z.behind&&!$.includes(z.id))continue;console.log(`updating ${z.id} (${z.spec})\u2026`);let G=await BC(z.spec,{yes:J.yes});if(G!==z.id)q_0(z.id,G)}KC()}var Fx=c(()=>{Ux();yJ();gJ();Hx();v4()});var s00={};A$(s00,{runPluginSubcommand:()=>A_0});import{spawnSync as U_0}from"child_process";import{readFileSync as B_0,rmSync as K_0}from"fs";function Mx($){$.write([`usage: ${HX} plugin <command>`,""," install <owner/repo[/subdir]> [--yes] [--ref <rev>] clone from GitHub, preview, build, register"," link <dir> register a local plugin directory (dev)"," list installed + linked plugins"," search [query] browse the marketplace (GitHub topic rove-plugin)"," outdated check GitHub-installed plugins against upstream"," update <id\u2026> | --all [--yes] reinstall stale plugins from GitHub"," enable <id> | disable <id> toggle a plugin without unregistering it"," unlink <id> unregister a linked plugin (files untouched)"," uninstall <id-or-spec> unregister + remove the managed checkout"," config-dir <id> print the plugin's config directory"," log <id> [-n <count>] tail the plugin's command-run log"," action list [--plugin <id>] declared actions"," action invoke <plugin-id.action-id> run an action now"," pane open --plugin <id> --entrypoint <pane-id> open a plugin pane as a terminal tab","","Marketplace: https://github.com/topics/rove-plugin (legacy kobe-plugin is included)",""].join(`
835
835
  `))}function FC(){return o4().plugins.map(($)=>{try{return{entry:$,manifest:G6($.root).manifest}}catch{return{entry:$,manifest:void 0}}})}function MC($){let J=o4().plugins.find((Z)=>Z.id===$);if(!J)throw new s4(`no plugin registered as \`${$}\`; see \`${HX} plugin list\``);return J}function F_0(){let $=FC();if($.length===0){console.log(`no plugins installed. Try: ${HX} plugin install <owner/repo> \u2014 browse the \`rove-plugin\` GitHub topic.`);return}for(let{entry:J,manifest:Z}of $){let X=J.enabled?"enabled":"disabled",z=J.source.kind==="link"?`linked ${J.root}`:J.source.spec,G=Z?"":" [manifest unreadable]";console.log(`${J.id} v${J.version} ${X} (${z})${G}`)}}function M_0($,J){let Z=MC($),X=o4();bJ({plugins:X.plugins.map((z)=>z.id===$?{...Z,enabled:J}:z)}),console.log(`${J?"enabled":"disabled"} ${$}`)}function N_0($){let J=MC($);if(J.source.kind!=="link")throw new s4(`\`${$}\` is a GitHub install; use uninstall`);bJ(yF(o4(),$)),console.log(`unlinked ${$} (files untouched at ${J.root})`)}function L_0($){let J=o4(),Z=J.plugins.find((X)=>X.id===$||X.source.kind==="github"&&X.source.spec===$);if(!Z)throw new s4(`no plugin registered as \`${$}\``);if(Z.source.kind==="link")throw new s4(`\`${Z.id}\` is linked; use unlink`);bJ(yF(J,Z.id)),K_0(SH(Z.id),{recursive:!0,force:!0}),console.log(`uninstalled ${Z.id} (config/state kept under ~/.kobe/plugins/${Z.id}/)`)}function O_0($){for(let{entry:J,manifest:Z}of FC()){if(!Z||$&&J.id!==$)continue;for(let X of Z.actions)console.log(`${BV(J.id,X.id)} ${X.title}`)}}function r00($,J,Z){for(let{entry:X,manifest:z}of FC().filter(({entry:G,manifest:W})=>Boolean(W&&(!J.enabledOnly||G.enabled)&&$.startsWith(`${G.id}.`))).sort((G,W)=>W.entry.id.length-G.entry.id.length)){let G=Z(z,$.slice(X.id.length+1));if(G!==void 0)return{entry:X,item:G}}return}function j_0($,J){let Z=r00($,{enabledOnly:!0},(q,U)=>q.actions.find((B)=>B.id===U));if(!Z)throw new s4(`no action \`${$}\`; see \`${HX} plugin action list\``);let X=Z.item,[z,...G]=[...X.command,...J],W=U_0(z,G,{cwd:Z.entry.root,stdio:"inherit",env:dH({socketPath:U2(),binPath:HX,pluginId:Z.entry.id,pluginRoot:Z.entry.root,extra:{ROVE_PLUGIN_ACTION_ID:X.id,ROVE_PLUGIN_INVOKE_CWD:process.cwd()}})});process.exit(W.status??1)}function V_0($){let J=r00($,{enabledOnly:!1},(Z,X)=>Z.panes.find((z)=>z.id===X));if(!J)throw new s4(`no pane \`${$}\`; see \`${HX} plugin list\``);return{pluginId:J.entry.id,entrypoint:J.item.id}}async function __0($,J,Z){let X=FC().find(({entry:B})=>B.id===$);if(!X?.manifest)throw new s4(`no plugin \`${$}\` (or its manifest is unreadable)`);if(!X.entry.enabled)throw new s4(`\`${$}\` is disabled`);let z=X.manifest.panes.find((B)=>B.id===J);if(!z)throw new s4(`no pane \`${J}\` in \`${$}\`; declare it under [[panes]]`);let G=Yx(X.entry.id,X.entry.root,z,{socketPath:U2(),binPath:HX}),{openDaemonSession:W,resolveActiveTaskId:q}=await Promise.resolve().then(() => (hj(),Dh)),U=await W({mode:"start"});try{let B=Z??await q(U.client);if(!B)throw new s4("no active task; pass --task <id>");await U.client.request("tab.open",{taskId:B,argv:G,title:z.title,placement:z.placement}),console.log(`opened pane ${$}.${z.id} in task ${B}`)}finally{U.close()}}function C_0($,J){MC($);let Z;try{Z=B_0(IH($),"utf8")}catch{console.log("(no runs logged yet)");return}let X=Z.trimEnd().split(`
836
836
  `);for(let z of X.slice(-J))console.log(z)}function _G($,J){let Z=$.indexOf(J);return Z>=0?$[Z+1]:void 0}async function A_0($){let[J,...Z]=$;try{switch(J){case"install":{let X=Z.find((z)=>!z.startsWith("-"));if(!X)throw new s4("install needs <owner/repo[/subdir]>");await BC(X,{yes:Z.includes("--yes"),ref:_G(Z,"--ref")});return}case"link":{if(!Z[0])throw new s4("link needs a directory");c00(Z[0]);return}case"list":F_0();return;case"search":{let{searchMarketplace:X}=await Promise.resolve().then(() => (p00(),d00));await X(Z.find((z)=>!z.startsWith("-")));return}case"outdated":{let{printOutdated:X}=await Promise.resolve().then(() => (Fx(),Kx));X();return}case"update":{let{updatePlugins:X}=await Promise.resolve().then(() => (Fx(),Kx));await X(Z.filter((z)=>!z.startsWith("-")),{all:Z.includes("--all"),yes:Z.includes("--yes")});return}case"enable":case"disable":{if(!Z[0])throw new s4(`${J} needs a plugin id`);M_0(Z[0],J==="enable");return}case"unlink":{if(!Z[0])throw new s4("unlink needs a plugin id");N_0(Z[0]);return}case"uninstall":{if(!Z[0])throw new s4("uninstall needs a plugin id or owner/repo spec");L_0(Z[0]);return}case"config-dir":{if(!Z[0])throw new s4("config-dir needs a plugin id");MC(Z[0]),console.log(D3(Z[0]));return}case"log":{if(!Z[0])throw new s4("log needs a plugin id");C_0(Z[0],Number.parseInt(_G(Z,"-n")??"20",10)||20);return}case"pane":{let[X,...z]=Z;if(X==="open"){let G=z.find((U)=>!U.startsWith("-")&&U!==_G(z,"--task")),W=_G(z,"--plugin"),q=_G(z,"--entrypoint");if(!W||!q){if(!G)throw new s4("pane open needs <plugin-id.pane-id> (or --plugin <id> --entrypoint <pane-id>) [--task <task-id>]");({pluginId:W,entrypoint:q}=V_0(G))}await __0(W,q,_G(z,"--task"));return}Mx(process.stderr),process.exit(2);return}case"action":{let[X,...z]=Z;if(X==="list"){O_0(_G(z,"--plugin"));return}if(X==="invoke"){if(!z[0])throw new s4("action invoke needs <plugin-id.action-id>");j_0(z[0],z.slice(1));return}Mx(process.stderr),process.exit(2);return}default:{let X=J===void 0||J==="help"||J==="--help"||J==="-h";if(Mx(X?process.stdout:process.stderr),!X)process.exit(2);return}}}catch(X){if(X instanceof s4)console.error(`${HX} plugin: ${X.message}`),process.exit(1);console.error(`${HX} plugin: ${M1(X)}`),process.exit(1)}}var HX;var t00=c(()=>{B7();z_();rZ();Gx();yJ();gJ();Hx();v4();HX=a1()});var W10={};A$(W10,{runHookSubcommand:()=>E_0,readTextWithTimeout:()=>X10,parseWorktreeRemovePath:()=>z10,ensureGlobalKobeHooks:()=>Lx});import{homedir as D_0}from"os";import{join as J10,resolve as Z10}from"path";async function X10($,J=P_0){let Z;try{return await Promise.race([$(),new Promise((X)=>{Z=setTimeout(()=>X(""),J)})])}finally{if(Z!==void 0)clearTimeout(Z)}}async function Q10(){try{let $=await X10(()=>Bun.stdin.text());if(!$.trim())return{};let J=JSON.parse($);return J&&typeof J==="object"&&!Array.isArray(J)?J:{}}catch{return{}}}function e00($,J){for(let Z=0;Z<$.length;Z++){if($[Z]===J)return $[Z+1];if($[Z].startsWith(`${J}=`))return $[Z].slice(J.length+1)}return}function T_0($){return!!$&&typeof $==="object"&&!Array.isArray($)}function S_0($){let J=[],Z=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=Z.exec($))!==null)J.push(X[1]??X[2]??X[3]??"");return J}function z10($){let J=S_0($);for(let Z=0;Z+1<J.length;Z++){if(J[Z]!=="worktree"||J[Z+1]!=="remove")continue;let X=Z+2;while(X<J.length){let z=J[X];if(z==="&&"||z==="||"||z===";"||z==="|"||z===">"||z===">>")break;if(z.startsWith("-")){X+=1;continue}return z}}return}async function I_0(){let $=await Q10(),J=T_0($.tool_input)?$.tool_input:{},Z=typeof J.command==="string"?J.command:"";if(!Z.includes("worktree"))return;let X=typeof $.cwd==="string"&&$.cwd?$.cwd:process.cwd(),z=z10(Z);if(!z)return;let G=await DJ();if(!G)return;try{await G.request("worktree.archiveRemoved",{worktreePath:Z10(X,z)})}finally{G.close()}}async function E_0($){let[J,...Z]=$;if(J==="setup"){await b_0(Z);return}if(J==="cleanup"){await y_0();return}if(J===R_0){try{await I_0()}catch{}return}try{if(!J||!A_(J))return;let X=await Q10(),z=e00(Z,"--task-id"),G=typeof X.cwd==="string"&&X.cwd?X.cwd:process.cwd(),W=process.env.KOBE_TASK_ID,q=process.env.KOBE_TAB_ID,U=e00(Z,"--engine"),B=Nx().filter((j)=>!U||j.vendor===U),M;for(let j of B)if(M=j.activityDetailFromPayload(J,X),M)break;let L;for(let j of B)if(L=j.sessionFromPayload(X),L)break;let N=await DJ();if(!N)return;try{let j=z??W;await N.request("engine.reportEvent",{...j?{taskId:j}:{cwd:G},kind:J,...U?{engine:U}:{},...q?{tabId:q}:{},...M?{detail:M}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{N.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[rove hook] ${J} failed:`,X instanceof Error?X.message:String(X))}}function w_0(){return h8.map(($)=>yR($)).filter(($)=>$.supportsWorktreeSync())}function Nx(){return h8.map(($)=>yR($)).filter(($)=>$.supportsHooks())}function Y10(){return J10(D_0(),".claude","settings.json")}function x_0($){if(!$||$==="off")return;if($==="global")return Y10();if($.startsWith("repo:"))return J10(Z10($.slice(5)),".claude","settings.json");return $}async function Lx(){try{let{isRovePluginEnabled:$,detectLegacyInstalls:J,migrationHint:Z}=await Promise.resolve().then(() => (o_(),i_)),X=$();if(X){let G=Z(J(),a1());if(G)process.stderr.write(`
@@ -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.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(()=>{/*!
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.195",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],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://rove.run",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
  *
@@ -830,7 +830,7 @@ You can run it yourself: ${jG({agent:X,global:z})}
830
830
  `),process.exit(W||1);process.stdout.write(`${B8} skill: installed.
831
831
  `)}var B8,vV0;var Yx=c(()=>{_M();x4();B8=a1(),vV0=["install","status","command","print"]});function v00($){return`'${$.replace(/'/g,"'\\''")}'`}function Gx($,J,Z,X){let z=dH({homeDir:X.homeDir,socketPath:X.socketPath,binPath:X.binPath,pluginId:$,pluginRoot:J,extra:{ROVE_PLUGIN_ENTRYPOINT_ID:Z.id}}),G=Object.entries(z).filter(([U])=>U.startsWith("ROVE_")||U.startsWith("KOBE_")),W=Z.command.map((U)=>U.replace(/\$\{?(?:ROVE|KOBE)_PLUGIN_ROOT\}?/g,J)),q=`exec env ${G.map(([U,B])=>v00(`${U}=${B}`)).join(" ")} ${W.map(v00).join(" ")}`;return[b2(),"-ilc",q]}function k00($){let J=M9(),Z=[];for(let X of o4($.homeDir).plugins){if(!X.enabled)continue;try{let{manifest:z}=G6(X.root);if(!W6({},z,J))continue;for(let G of z.panes){if(!W6(G,z,J))continue;Z.push({pluginId:X.id,paneId:G.id,title:G.title,placement:G.placement,argv:Gx(X.id,X.root,G,$)})}}catch{}}return Z}var Wx=c(()=>{dZ();Y_();rZ();gJ()});import{spawnSync as m00}from"child_process";import{cpSync as mV0,existsSync as hV0,mkdirSync as BC,readFileSync as h00,renameSync as uV0,rmSync as Hx}from"fs";import{mkdtempSync as cV0}from"fs";import{basename as lV0,join as UC,resolve as dV0}from"path";import{createInterface as pV0}from"readline/promises";function p8($){throw new s4($)}function u00($){let J=RH($);if(!J)p8(`no ${BV.join(" or ")} found at ${$}`);let Z=h00(J,"utf8");return{...xF(Z,lV0(J)),manifestPath:J,manifestSource:Z}}function c00($){let J=$.manifest.minKobeVersion;if(A3(D$,J)<0)p8(`plugin requires Rove >= ${J} (this is ${D$}); update Rove first`)}function iV0($,J){let Z=$.manifest;console.log(`
832
832
  ${Z.name} (${Z.id}) v${Z.version} \u2014 ${Z.description??"no description"}`),console.log(`source: ${J}`);let X=(z,G)=>{for(let W of G)console.log(` ${z}: ${W.command.join(" ")}`)};X("build",Z.build),X("startup",Z.startup);for(let z of Z.actions)console.log(` action ${z.id}: ${z.command.join(" ")}`);for(let z of Z.events)console.log(` on ${z.on}: ${z.command.join(" ")}`);for(let z of $.warnings)console.log(` warning: ${z}`);console.log("")}async function oV0($){if($)return;if(!process.stdin.isTTY)p8("refusing to install without confirmation in a non-interactive terminal; pass --yes");let J=pV0({input:process.stdin,output:process.stdout}),Z=(await J.question("Install this plugin and run its build commands? [y/N] ")).trim().toLowerCase();if(J.close(),Z!=="y"&&Z!=="yes")p8("aborted")}function qx($,J){if(m00("git",$,{cwd:J,stdio:["ignore","inherit","inherit"]}).status!==0)p8(`git ${$[0]} failed`)}function aV0($,J){let Z=M9();for(let[X,z]of $.manifest.build.entries()){if(!W6(z,$.manifest,Z))continue;let[G,...W]=z.command;console.log(`build[${X}]: ${z.command.join(" ")}`);let q=m00(G,W,{cwd:J,stdio:["ignore","inherit","inherit"]});if(q.status!==0)p8(`build[${X}] failed (exit ${q.status??"spawn error"}); plugin not registered`)}}function rV0(){let $=qS();return BC($,{recursive:!0}),cV0(UC($,".staging-"))}function sV0($,J){try{uV0($,J)}catch(Z){if(Z.code!=="EXDEV")throw Z;mV0($,J,{recursive:!0,verbatimSymlinks:!0}),Hx($,{recursive:!0,force:!0})}}function l00($){bJ(vc(o4(),$)),BC(D3($.id),{recursive:!0}),BC(eQ($.id),{recursive:!0})}async function KC($,J){let Z=$.match(nV0);if(!Z)p8(`install takes GitHub shorthand (owner/repo[/subdir]), got \`${$}\``);let[,X,z,G]=Z,W=G?.replace(/^\//,""),q=rV0();try{let U=`https://github.com/${X}/${z}.git`;if(console.log(`cloning ${U}${J.ref?` @ ${J.ref}`:""}`),J.ref)qx(["clone","--quiet",U,q]),qx(["checkout","--quiet",J.ref],q);else qx(["clone","--quiet","--depth","1",U,q]);let B=W?UC(q,W):q,M=u00(B);c00(M);let L=M.manifest.id,N=o4().plugins.find((_)=>_.id===L);if(N?.source.kind==="link")p8(`\`${L}\` is locally linked at ${N.root}; unlink it first`);if(!W6({},M.manifest,M9()))p8(`plugin declares platforms [${M.manifest.platforms?.join(", ")}]; this machine is unsupported`);iV0(M,`github.com/${X}/${z}${W?`/${W}`:""}`),await oV0(J.yes),aV0(M,B);let j=RH(B);if(!j)p8("manifest disappeared during build; aborting");if(j!==M.manifestPath)p8("manifest changed during build; aborting");if(h00(j,"utf8")!==M.manifestSource)p8("manifest changed during build; aborting");let C=SH(L);return Hx(C,{recursive:!0,force:!0}),BC(UC(C,".."),{recursive:!0}),sV0(q,C),l00({id:L,source:{kind:"github",spec:$},root:W?UC(C,W):C,enabled:!0,version:M.manifest.version,installedAt:Date.now()}),console.log(`installed ${L} v${M.manifest.version}`),L}finally{Hx(q,{recursive:!0,force:!0})}}function d00($){let J=dV0($);if(!hV0(J))p8(`no such directory: ${J}`);let Z=u00(J);c00(Z);let X=Z.manifest.id;if(o4().plugins.find((G)=>G.id===X)?.source.kind==="github")p8(`\`${X}\` is installed from GitHub; uninstall it before linking a local copy`);for(let G of Z.warnings)console.log(`warning: ${G}`);l00({id:X,source:{kind:"link"},root:J,enabled:!0,version:Z.manifest.version,installedAt:Date.now()}),console.log(`linked ${X} v${Z.manifest.version} \u2192 ${J}`)}var nV0,s4;var Ux=c(()=>{rZ();yJ();gJ();d8();nV0=/^([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)(\/.+)?$/;s4=class s4 extends Error{}});var n00={};A$(n00,{searchMarketplace:()=>J_0});async function p00($,J){let Z=encodeURIComponent(`topic:${$}${J?` ${J}`:""}`),X=new AbortController,z=setTimeout(()=>X.abort(),tV0);try{let G=await fetch(`https://api.github.com/search/repositories?q=${Z}&sort=stars&order=desc&per_page=50`,{signal:X.signal,headers:{accept:"application/vnd.github+json"}});if(!G.ok)return null;let W=await G.json();if(!Array.isArray(W.items))return null;return W.items.filter((q)=>typeof q.full_name==="string").map((q)=>({ref:q.full_name,desc:q.description??"",stars:q.stargazers_count}))}catch{return null}finally{clearTimeout(z)}}async function J_0($){let J=await Promise.all([p00("rove-plugin",$),p00("kobe-plugin",$)]),Z=$?.toLowerCase(),X=$_0.filter((W)=>!Z||`${W.ref} ${W.desc}`.toLowerCase().includes(Z)).map((W)=>({...W,firstParty:!0})),z=Z_0([...X,...J.flatMap((W)=>W??[])]);if(J.every((W)=>W===null))console.error("(GitHub search unreachable \u2014 showing first-party plugins only)");if(z.length===0){console.log($?`no plugins match \`${$}\``:"no plugins found");return}let G=Math.min(48,Math.max(...z.map((W)=>W.ref.length))+2);for(let W of z){let q=W.stars!==void 0?`\u2605${W.stars}`:W.firstParty?"first-party":"";console.log(`${W.ref.padEnd(G)}${q.padEnd(12)}${W.desc}`)}console.log(`
833
- install: ${eV0} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.sma1lboy.me/plugins`)}function Z_0($){let J=new Set;return $.filter((Z)=>{let X=Z.ref.toLowerCase();if(J.has(X))return!1;return J.add(X),!0})}var tV0=5000,eV0,$_0;var i00=c(()=>{x4();eV0=a1(),$_0=[{ref:"Sma1lboy/kobe-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/kobe-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/kobe-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/kobe-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/kobe-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/kobe-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}]});import{readFileSync as X_0,writeFileSync as Q_0}from"fs";function o00($,J){let Z={checkedAt:Date.now(),outdated:$};try{Q_0(HS(J),`${JSON.stringify(Z,null,2)}
833
+ install: ${eV0} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.run/plugins`)}function Z_0($){let J=new Set;return $.filter((Z)=>{let X=Z.ref.toLowerCase();if(J.has(X))return!1;return J.add(X),!0})}var tV0=5000,eV0,$_0;var i00=c(()=>{x4();eV0=a1(),$_0=[{ref:"Sma1lboy/kobe-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/kobe-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/kobe-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/kobe-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/kobe-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/kobe-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}]});import{readFileSync as X_0,writeFileSync as Q_0}from"fs";function o00($,J){let Z={checkedAt:Date.now(),outdated:$};try{Q_0(HS(J),`${JSON.stringify(Z,null,2)}
834
834
  `)}catch{}}function a00($){try{let J=JSON.parse(X_0(HS($),"utf8"));if(typeof J.checkedAt!=="number"||!Array.isArray(J.outdated))return[];if(Date.now()-J.checkedAt>z_0)return[];return J.outdated.filter((Z)=>typeof Z==="string")}catch{return[]}}var z_0=86400000;var Bx=c(()=>{yJ()});var Fx={};A$(Fx,{updatePlugins:()=>K_0,printOutdated:()=>U_0,listOutdated:()=>FC});import{execFileSync as Y_0}from"child_process";import{existsSync as r00,mkdirSync as G_0,readdirSync as W_0,renameSync as q_0}from"fs";import{join as Kx}from"path";function s00($,J){try{return Y_0("git",$,{cwd:J,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function H_0($){let J=$.source.spec.split("/").slice(0,2).join("/"),Z=s00(["rev-parse","HEAD"],SH($.id)),X=s00(["ls-remote",`https://github.com/${J}.git`,"HEAD"]),z=X?X.split(/\s+/)[0]??null:null;return{id:$.id,spec:$.source.spec,version:$.version,localSha:Z,remoteSha:z,behind:Boolean(Z&&z&&Z!==z)}}function FC(){let $=o4().plugins.filter((J)=>J.source.kind==="github").map(H_0);return o00($.filter((J)=>J.behind).map((J)=>J.id)),$}function U_0(){let $=FC();if($.length===0){console.log("no GitHub-installed plugins.");return}for(let J of $){let Z=J.behind?"update available":J.remoteSha===null?"remote unreachable":J.localSha===null?"local sha unreadable":"up to date";console.log(`${J.id} v${J.version} ${Z}`)}}function B_0($,J){for(let Z of[D3,eQ]){let X=Z($),z=Z(J);if(!r00(X))continue;G_0(z,{recursive:!0});for(let G of W_0(X)){if(r00(Kx(z,G)))continue;q_0(Kx(X,G),Kx(z,G))}}bJ(yF(o4(),$)),console.log(`renamed ${$} \u2192 ${J}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${TH($)}`)}async function K_0($,J){let Z=FC(),X;if(J.all){if(X=Z.filter((z)=>z.behind),X.length===0){console.log("all plugins up to date.");return}}else{if($.length===0)throw new s4("update takes plugin ids or --all");X=$.map((z)=>{let G=Z.find((W)=>W.id===z);if(!G)throw new s4(`\`${z}\` is not a GitHub-installed plugin; see \`${a1()} plugin list\``);return G})}for(let z of X){if(!z.behind&&!$.includes(z.id))continue;console.log(`updating ${z.id} (${z.spec})\u2026`);let G=await KC(z.spec,{yes:J.yes});if(G!==z.id)B_0(z.id,G)}FC()}var Mx=c(()=>{Bx();yJ();gJ();Ux();x4()});var e00={};A$(e00,{runPluginSubcommand:()=>R_0});import{spawnSync as F_0}from"child_process";import{readFileSync as M_0,rmSync as N_0}from"fs";function Nx($){$.write([`usage: ${HX} plugin <command>`,""," install <owner/repo[/subdir]> [--yes] [--ref <rev>] clone from GitHub, preview, build, register"," link <dir> register a local plugin directory (dev)"," list installed + linked plugins"," search [query] browse the marketplace (GitHub topic rove-plugin)"," outdated check GitHub-installed plugins against upstream"," update <id\u2026> | --all [--yes] reinstall stale plugins from GitHub"," enable <id> | disable <id> toggle a plugin without unregistering it"," unlink <id> unregister a linked plugin (files untouched)"," uninstall <id-or-spec> unregister + remove the managed checkout"," config-dir <id> print the plugin's config directory"," log <id> [-n <count>] tail the plugin's command-run log"," action list [--plugin <id>] declared actions"," action invoke <plugin-id.action-id> run an action now"," pane open --plugin <id> --entrypoint <pane-id> open a plugin pane as a terminal tab","","Marketplace: https://github.com/topics/rove-plugin (legacy kobe-plugin is included)",""].join(`
835
835
  `))}function MC(){return o4().plugins.map(($)=>{try{return{entry:$,manifest:G6($.root).manifest}}catch{return{entry:$,manifest:void 0}}})}function NC($){let J=o4().plugins.find((Z)=>Z.id===$);if(!J)throw new s4(`no plugin registered as \`${$}\`; see \`${HX} plugin list\``);return J}function L_0(){let $=MC();if($.length===0){console.log(`no plugins installed. Try: ${HX} plugin install <owner/repo> \u2014 browse the \`rove-plugin\` GitHub topic.`);return}for(let{entry:J,manifest:Z}of $){let X=J.enabled?"enabled":"disabled",z=J.source.kind==="link"?`linked ${J.root}`:J.source.spec,G=Z?"":" [manifest unreadable]";console.log(`${J.id} v${J.version} ${X} (${z})${G}`)}}function O_0($,J){let Z=NC($),X=o4();bJ({plugins:X.plugins.map((z)=>z.id===$?{...Z,enabled:J}:z)}),console.log(`${J?"enabled":"disabled"} ${$}`)}function j_0($){let J=NC($);if(J.source.kind!=="link")throw new s4(`\`${$}\` is a GitHub install; use uninstall`);bJ(yF(o4(),$)),console.log(`unlinked ${$} (files untouched at ${J.root})`)}function V_0($){let J=o4(),Z=J.plugins.find((X)=>X.id===$||X.source.kind==="github"&&X.source.spec===$);if(!Z)throw new s4(`no plugin registered as \`${$}\``);if(Z.source.kind==="link")throw new s4(`\`${Z.id}\` is linked; use unlink`);bJ(yF(J,Z.id)),N_0(SH(Z.id),{recursive:!0,force:!0}),console.log(`uninstalled ${Z.id} (config/state kept under ~/.kobe/plugins/${Z.id}/)`)}function __0($){for(let{entry:J,manifest:Z}of MC()){if(!Z||$&&J.id!==$)continue;for(let X of Z.actions)console.log(`${KV(J.id,X.id)} ${X.title}`)}}function t00($,J,Z){for(let{entry:X,manifest:z}of MC().filter(({entry:G,manifest:W})=>Boolean(W&&(!J.enabledOnly||G.enabled)&&$.startsWith(`${G.id}.`))).sort((G,W)=>W.entry.id.length-G.entry.id.length)){let G=Z(z,$.slice(X.id.length+1));if(G!==void 0)return{entry:X,item:G}}return}function C_0($,J){let Z=t00($,{enabledOnly:!0},(q,U)=>q.actions.find((B)=>B.id===U));if(!Z)throw new s4(`no action \`${$}\`; see \`${HX} plugin action list\``);let X=Z.item,[z,...G]=[...X.command,...J],W=F_0(z,G,{cwd:Z.entry.root,stdio:"inherit",env:dH({socketPath:U2(),binPath:HX,pluginId:Z.entry.id,pluginRoot:Z.entry.root,extra:{ROVE_PLUGIN_ACTION_ID:X.id,ROVE_PLUGIN_INVOKE_CWD:process.cwd()}})});process.exit(W.status??1)}function A_0($){let J=t00($,{enabledOnly:!1},(Z,X)=>Z.panes.find((z)=>z.id===X));if(!J)throw new s4(`no pane \`${$}\`; see \`${HX} plugin list\``);return{pluginId:J.entry.id,entrypoint:J.item.id}}async function D_0($,J,Z){let X=MC().find(({entry:B})=>B.id===$);if(!X?.manifest)throw new s4(`no plugin \`${$}\` (or its manifest is unreadable)`);if(!X.entry.enabled)throw new s4(`\`${$}\` is disabled`);let z=X.manifest.panes.find((B)=>B.id===J);if(!z)throw new s4(`no pane \`${J}\` in \`${$}\`; declare it under [[panes]]`);let G=Gx(X.entry.id,X.entry.root,z,{socketPath:U2(),binPath:HX}),{openDaemonSession:W,resolveActiveTaskId:q}=await Promise.resolve().then(() => (uj(),Rh)),U=await W({mode:"start"});try{let B=Z??await q(U.client);if(!B)throw new s4("no active task; pass --task <id>");await U.client.request("tab.open",{taskId:B,argv:G,title:z.title,placement:z.placement}),console.log(`opened pane ${$}.${z.id} in task ${B}`)}finally{U.close()}}function P_0($,J){NC($);let Z;try{Z=M_0(IH($),"utf8")}catch{console.log("(no runs logged yet)");return}let X=Z.trimEnd().split(`
836
836
  `);for(let z of X.slice(-J))console.log(z)}function _G($,J){let Z=$.indexOf(J);return Z>=0?$[Z+1]:void 0}async function R_0($){let[J,...Z]=$;try{switch(J){case"install":{let X=Z.find((z)=>!z.startsWith("-"));if(!X)throw new s4("install needs <owner/repo[/subdir]>");await KC(X,{yes:Z.includes("--yes"),ref:_G(Z,"--ref")});return}case"link":{if(!Z[0])throw new s4("link needs a directory");d00(Z[0]);return}case"list":L_0();return;case"search":{let{searchMarketplace:X}=await Promise.resolve().then(() => (i00(),n00));await X(Z.find((z)=>!z.startsWith("-")));return}case"outdated":{let{printOutdated:X}=await Promise.resolve().then(() => (Mx(),Fx));X();return}case"update":{let{updatePlugins:X}=await Promise.resolve().then(() => (Mx(),Fx));await X(Z.filter((z)=>!z.startsWith("-")),{all:Z.includes("--all"),yes:Z.includes("--yes")});return}case"enable":case"disable":{if(!Z[0])throw new s4(`${J} needs a plugin id`);O_0(Z[0],J==="enable");return}case"unlink":{if(!Z[0])throw new s4("unlink needs a plugin id");j_0(Z[0]);return}case"uninstall":{if(!Z[0])throw new s4("uninstall needs a plugin id or owner/repo spec");V_0(Z[0]);return}case"config-dir":{if(!Z[0])throw new s4("config-dir needs a plugin id");NC(Z[0]),console.log(D3(Z[0]));return}case"log":{if(!Z[0])throw new s4("log needs a plugin id");P_0(Z[0],Number.parseInt(_G(Z,"-n")??"20",10)||20);return}case"pane":{let[X,...z]=Z;if(X==="open"){let G=z.find((U)=>!U.startsWith("-")&&U!==_G(z,"--task")),W=_G(z,"--plugin"),q=_G(z,"--entrypoint");if(!W||!q){if(!G)throw new s4("pane open needs <plugin-id.pane-id> (or --plugin <id> --entrypoint <pane-id>) [--task <task-id>]");({pluginId:W,entrypoint:q}=A_0(G))}await D_0(W,q,_G(z,"--task"));return}Nx(process.stderr),process.exit(2);return}case"action":{let[X,...z]=Z;if(X==="list"){__0(_G(z,"--plugin"));return}if(X==="invoke"){if(!z[0])throw new s4("action invoke needs <plugin-id.action-id>");C_0(z[0],z.slice(1));return}Nx(process.stderr),process.exit(2);return}default:{let X=J===void 0||J==="help"||J==="--help"||J==="-h";if(Nx(X?process.stdout:process.stderr),!X)process.exit(2);return}}}catch(X){if(X instanceof s4)console.error(`${HX} plugin: ${X.message}`),process.exit(1);console.error(`${HX} plugin: ${M1(X)}`),process.exit(1)}}var HX;var $10=c(()=>{B7();Y_();rZ();Wx();yJ();gJ();Ux();x4();HX=a1()});var H10={};A$(H10,{runHookSubcommand:()=>f_0,readTextWithTimeout:()=>z10,parseWorktreeRemovePath:()=>G10,ensureGlobalKobeHooks:()=>Ox});import{homedir as T_0}from"os";import{join as X10,resolve as Q10}from"path";async function z10($,J=S_0){let Z;try{return await Promise.race([$(),new Promise((X)=>{Z=setTimeout(()=>X(""),J)})])}finally{if(Z!==void 0)clearTimeout(Z)}}async function Y10(){try{let $=await z10(()=>Bun.stdin.text());if(!$.trim())return{};let J=JSON.parse($);return J&&typeof J==="object"&&!Array.isArray(J)?J:{}}catch{return{}}}function J10($,J){for(let Z=0;Z<$.length;Z++){if($[Z]===J)return $[Z+1];if($[Z].startsWith(`${J}=`))return $[Z].slice(J.length+1)}return}function E_0($){return!!$&&typeof $==="object"&&!Array.isArray($)}function w_0($){let J=[],Z=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=Z.exec($))!==null)J.push(X[1]??X[2]??X[3]??"");return J}function G10($){let J=w_0($);for(let Z=0;Z+1<J.length;Z++){if(J[Z]!=="worktree"||J[Z+1]!=="remove")continue;let X=Z+2;while(X<J.length){let z=J[X];if(z==="&&"||z==="||"||z===";"||z==="|"||z===">"||z===">>")break;if(z.startsWith("-")){X+=1;continue}return z}}return}async function x_0(){let $=await Y10(),J=E_0($.tool_input)?$.tool_input:{},Z=typeof J.command==="string"?J.command:"";if(!Z.includes("worktree"))return;let X=typeof $.cwd==="string"&&$.cwd?$.cwd:process.cwd(),z=G10(Z);if(!z)return;let G=await DJ();if(!G)return;try{await G.request("worktree.archiveRemoved",{worktreePath:Q10(X,z)})}finally{G.close()}}async function f_0($){let[J,...Z]=$;if(J==="setup"){await k_0(Z);return}if(J==="cleanup"){await v_0();return}if(J===I_0){try{await x_0()}catch{}return}try{if(!J||!D_(J))return;let X=await Y10(),z=J10(Z,"--task-id"),G=typeof X.cwd==="string"&&X.cwd?X.cwd:process.cwd(),W=process.env.KOBE_TASK_ID,q=process.env.KOBE_TAB_ID,U=J10(Z,"--engine"),B=Lx().filter((j)=>!U||j.vendor===U),M;for(let j of B)if(M=j.activityDetailFromPayload(J,X),M)break;let L;for(let j of B)if(L=j.sessionFromPayload(X),L)break;let N=await DJ();if(!N)return;try{let j=z??W;await N.request("engine.reportEvent",{...j?{taskId:j}:{cwd:G},kind:J,...U?{engine:U}:{},...q?{tabId:q}:{},...M?{detail:M}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{N.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[rove hook] ${J} failed:`,X instanceof Error?X.message:String(X))}}function y_0(){return h8.map(($)=>bR($)).filter(($)=>$.supportsWorktreeSync())}function Lx(){return h8.map(($)=>bR($)).filter(($)=>$.supportsHooks())}function W10(){return X10(T_0(),".claude","settings.json")}function b_0($){if(!$||$==="off")return;if($==="global")return W10();if($.startsWith("repo:"))return X10(Q10($.slice(5)),".claude","settings.json");return $}async function Ox(){try{let{isRovePluginEnabled:$,detectLegacyInstalls:J,migrationHint:Z}=await Promise.resolve().then(() => (a_(),o_)),X=$();if(X){let G=Z(J(),a1());if(G)process.stderr.write(`
package/dist/cli/kobe.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import{join as l}from"node:path";import{createInterface as s}from"node:readline/promises";import{pathToFileURL as o}from"node:url";import{spawnSync as U}from"node:child_process";import{constants as f,accessSync as A}from"node:fs";import{homedir as y}from"node:os";import{basename as S,delimiter as _,dirname as p,join as $}from"node:path";import{fileURLToPath as w}from"node:url";var W="rove",Y="kobe";var N="ROVE_INVOKED_AS";function K(z=process.env){return z[N]===W?W:Y}var x="ROVE_BUN",v="ROVE_NO_BUN_BOOTSTRAP",E=(z)=>{try{return A(z,f.X_OK),!0}catch{return!1}},d=(z)=>z==="win32"?"bun.exe":"bun";function m(z={}){let H=z.env??process.env,J=z.platform??process.platform,Z=z.home??H.HOME??H.USERPROFILE??y(),Q=d(J),X=[],G=H[x]?.trim();if(G)X.push(G);for(let L of(H.PATH??H.Path??"").split(_))if(L)X.push($(L,Q));let V=H.BUN_INSTALL?.trim();if(V)X.push($(V,"bin",Q));if(Z)X.push($(Z,".bun","bin",Q));let q=z.launcherDir;if(q)X.push($(q,"..","..","node_modules","bun","bin",Q)),X.push($(q,"..","..","..","bun","bin",Q));return X}function F(z={}){let H=z.isExecutable??E;return m(z).find((J)=>H(J))??null}function b(z){return p(w(z))}function B(z){return S(w(z)).replace(/\.[cm]?[jt]s$/,"")}function c(z=process.platform){return z==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(z=K(),H=process.platform){let J=H==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${z}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${J}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.sma1lboy.me/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${x}=/path/to/bun`,""].join(`
2
+ import{join as l}from"node:path";import{createInterface as s}from"node:readline/promises";import{pathToFileURL as o}from"node:url";import{spawnSync as U}from"node:child_process";import{constants as f,accessSync as A}from"node:fs";import{homedir as y}from"node:os";import{basename as S,delimiter as _,dirname as p,join as $}from"node:path";import{fileURLToPath as w}from"node:url";var W="rove",Y="kobe";var N="ROVE_INVOKED_AS";function K(z=process.env){return z[N]===W?W:Y}var x="ROVE_BUN",v="ROVE_NO_BUN_BOOTSTRAP",E=(z)=>{try{return A(z,f.X_OK),!0}catch{return!1}},d=(z)=>z==="win32"?"bun.exe":"bun";function m(z={}){let H=z.env??process.env,J=z.platform??process.platform,Z=z.home??H.HOME??H.USERPROFILE??y(),Q=d(J),X=[],G=H[x]?.trim();if(G)X.push(G);for(let L of(H.PATH??H.Path??"").split(_))if(L)X.push($(L,Q));let V=H.BUN_INSTALL?.trim();if(V)X.push($(V,"bin",Q));if(Z)X.push($(Z,".bun","bin",Q));let q=z.launcherDir;if(q)X.push($(q,"..","..","node_modules","bun","bin",Q)),X.push($(q,"..","..","..","bun","bin",Q));return X}function F(z={}){let H=z.isExecutable??E;return m(z).find((J)=>H(J))??null}function b(z){return p(w(z))}function B(z){return S(w(z)).replace(/\.[cm]?[jt]s$/,"")}function c(z=process.platform){return z==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(z=K(),H=process.platform){let J=H==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${z}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${J}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.run/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${x}=/path/to/bun`,""].join(`
3
3
  `)}function C(z=process.env,H=process.stdin,J=process.stdout){if(z[v]==="1")return!1;if(z.CI==="true"||z.CI==="1")return!1;return Boolean(H.isTTY&&J.isTTY)}function M(z={},H=U){let J=z.platform??process.platform,[Z,...Q]=c(J);if(!Z)return null;let X=H(Z,Q,{stdio:"inherit"});if(X.error||X.status!==0)return null;return F(z)}function u(z){if(typeof z.status==="number")return z.status;if(z.signal)return 128+(Object.hasOwn(j,z.signal)?j[z.signal]:0);return 1}var j={SIGINT:2,SIGQUIT:3,SIGKILL:9,SIGTERM:15};function k(z,H,J,Z=U){let Q=Z(z,[H,...J],{stdio:"inherit"});if(Q.error)return process.stderr.write(`rove: could not start Bun at ${z}: ${Q.error.message}
4
4
  `),1;return u(Q)}var O=b(import.meta.url),P=B(import.meta.url),T=l(O,`${P}-run.js`);async function i(z){let H=s({input:process.stdin,output:process.stdout});try{let J=(await H.question(z)).trim().toLowerCase();return J===""||J==="y"||J==="yes"}finally{H.close()}}async function a(){let z={launcherDir:O},H=F(z);if(H)return H;if(!C())return null;let J=`${P}: Rove runs on the Bun runtime, and none is installed. Install Bun now? [Y/n] `;if(!await i(J))return null;return M(z)}if(typeof globalThis.Bun<"u")await import(o(T).href);else{let z=await a();if(!z)process.stderr.write(D(P)),process.exit(1);process.exit(k(z,T,process.argv.slice(2)))}
@@ -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.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(()=>{/*!
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.195",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],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://rove.run",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
  *
@@ -830,7 +830,7 @@ You can run it yourself: ${jG({agent:X,global:z})}
830
830
  `),process.exit(W||1);process.stdout.write(`${B8} skill: installed.
831
831
  `)}var B8,vV0;var Yx=c(()=>{_M();x4();B8=a1(),vV0=["install","status","command","print"]});function v00($){return`'${$.replace(/'/g,"'\\''")}'`}function Gx($,J,Z,X){let z=dH({homeDir:X.homeDir,socketPath:X.socketPath,binPath:X.binPath,pluginId:$,pluginRoot:J,extra:{ROVE_PLUGIN_ENTRYPOINT_ID:Z.id}}),G=Object.entries(z).filter(([U])=>U.startsWith("ROVE_")||U.startsWith("KOBE_")),W=Z.command.map((U)=>U.replace(/\$\{?(?:ROVE|KOBE)_PLUGIN_ROOT\}?/g,J)),q=`exec env ${G.map(([U,B])=>v00(`${U}=${B}`)).join(" ")} ${W.map(v00).join(" ")}`;return[b2(),"-ilc",q]}function k00($){let J=M9(),Z=[];for(let X of o4($.homeDir).plugins){if(!X.enabled)continue;try{let{manifest:z}=G6(X.root);if(!W6({},z,J))continue;for(let G of z.panes){if(!W6(G,z,J))continue;Z.push({pluginId:X.id,paneId:G.id,title:G.title,placement:G.placement,argv:Gx(X.id,X.root,G,$)})}}catch{}}return Z}var Wx=c(()=>{dZ();Y_();rZ();gJ()});import{spawnSync as m00}from"child_process";import{cpSync as mV0,existsSync as hV0,mkdirSync as BC,readFileSync as h00,renameSync as uV0,rmSync as Hx}from"fs";import{mkdtempSync as cV0}from"fs";import{basename as lV0,join as UC,resolve as dV0}from"path";import{createInterface as pV0}from"readline/promises";function p8($){throw new s4($)}function u00($){let J=RH($);if(!J)p8(`no ${BV.join(" or ")} found at ${$}`);let Z=h00(J,"utf8");return{...xF(Z,lV0(J)),manifestPath:J,manifestSource:Z}}function c00($){let J=$.manifest.minKobeVersion;if(A3(D$,J)<0)p8(`plugin requires Rove >= ${J} (this is ${D$}); update Rove first`)}function iV0($,J){let Z=$.manifest;console.log(`
832
832
  ${Z.name} (${Z.id}) v${Z.version} \u2014 ${Z.description??"no description"}`),console.log(`source: ${J}`);let X=(z,G)=>{for(let W of G)console.log(` ${z}: ${W.command.join(" ")}`)};X("build",Z.build),X("startup",Z.startup);for(let z of Z.actions)console.log(` action ${z.id}: ${z.command.join(" ")}`);for(let z of Z.events)console.log(` on ${z.on}: ${z.command.join(" ")}`);for(let z of $.warnings)console.log(` warning: ${z}`);console.log("")}async function oV0($){if($)return;if(!process.stdin.isTTY)p8("refusing to install without confirmation in a non-interactive terminal; pass --yes");let J=pV0({input:process.stdin,output:process.stdout}),Z=(await J.question("Install this plugin and run its build commands? [y/N] ")).trim().toLowerCase();if(J.close(),Z!=="y"&&Z!=="yes")p8("aborted")}function qx($,J){if(m00("git",$,{cwd:J,stdio:["ignore","inherit","inherit"]}).status!==0)p8(`git ${$[0]} failed`)}function aV0($,J){let Z=M9();for(let[X,z]of $.manifest.build.entries()){if(!W6(z,$.manifest,Z))continue;let[G,...W]=z.command;console.log(`build[${X}]: ${z.command.join(" ")}`);let q=m00(G,W,{cwd:J,stdio:["ignore","inherit","inherit"]});if(q.status!==0)p8(`build[${X}] failed (exit ${q.status??"spawn error"}); plugin not registered`)}}function rV0(){let $=qS();return BC($,{recursive:!0}),cV0(UC($,".staging-"))}function sV0($,J){try{uV0($,J)}catch(Z){if(Z.code!=="EXDEV")throw Z;mV0($,J,{recursive:!0,verbatimSymlinks:!0}),Hx($,{recursive:!0,force:!0})}}function l00($){bJ(vc(o4(),$)),BC(D3($.id),{recursive:!0}),BC(eQ($.id),{recursive:!0})}async function KC($,J){let Z=$.match(nV0);if(!Z)p8(`install takes GitHub shorthand (owner/repo[/subdir]), got \`${$}\``);let[,X,z,G]=Z,W=G?.replace(/^\//,""),q=rV0();try{let U=`https://github.com/${X}/${z}.git`;if(console.log(`cloning ${U}${J.ref?` @ ${J.ref}`:""}`),J.ref)qx(["clone","--quiet",U,q]),qx(["checkout","--quiet",J.ref],q);else qx(["clone","--quiet","--depth","1",U,q]);let B=W?UC(q,W):q,M=u00(B);c00(M);let L=M.manifest.id,N=o4().plugins.find((_)=>_.id===L);if(N?.source.kind==="link")p8(`\`${L}\` is locally linked at ${N.root}; unlink it first`);if(!W6({},M.manifest,M9()))p8(`plugin declares platforms [${M.manifest.platforms?.join(", ")}]; this machine is unsupported`);iV0(M,`github.com/${X}/${z}${W?`/${W}`:""}`),await oV0(J.yes),aV0(M,B);let j=RH(B);if(!j)p8("manifest disappeared during build; aborting");if(j!==M.manifestPath)p8("manifest changed during build; aborting");if(h00(j,"utf8")!==M.manifestSource)p8("manifest changed during build; aborting");let C=SH(L);return Hx(C,{recursive:!0,force:!0}),BC(UC(C,".."),{recursive:!0}),sV0(q,C),l00({id:L,source:{kind:"github",spec:$},root:W?UC(C,W):C,enabled:!0,version:M.manifest.version,installedAt:Date.now()}),console.log(`installed ${L} v${M.manifest.version}`),L}finally{Hx(q,{recursive:!0,force:!0})}}function d00($){let J=dV0($);if(!hV0(J))p8(`no such directory: ${J}`);let Z=u00(J);c00(Z);let X=Z.manifest.id;if(o4().plugins.find((G)=>G.id===X)?.source.kind==="github")p8(`\`${X}\` is installed from GitHub; uninstall it before linking a local copy`);for(let G of Z.warnings)console.log(`warning: ${G}`);l00({id:X,source:{kind:"link"},root:J,enabled:!0,version:Z.manifest.version,installedAt:Date.now()}),console.log(`linked ${X} v${Z.manifest.version} \u2192 ${J}`)}var nV0,s4;var Ux=c(()=>{rZ();yJ();gJ();d8();nV0=/^([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)(\/.+)?$/;s4=class s4 extends Error{}});var n00={};A$(n00,{searchMarketplace:()=>J_0});async function p00($,J){let Z=encodeURIComponent(`topic:${$}${J?` ${J}`:""}`),X=new AbortController,z=setTimeout(()=>X.abort(),tV0);try{let G=await fetch(`https://api.github.com/search/repositories?q=${Z}&sort=stars&order=desc&per_page=50`,{signal:X.signal,headers:{accept:"application/vnd.github+json"}});if(!G.ok)return null;let W=await G.json();if(!Array.isArray(W.items))return null;return W.items.filter((q)=>typeof q.full_name==="string").map((q)=>({ref:q.full_name,desc:q.description??"",stars:q.stargazers_count}))}catch{return null}finally{clearTimeout(z)}}async function J_0($){let J=await Promise.all([p00("rove-plugin",$),p00("kobe-plugin",$)]),Z=$?.toLowerCase(),X=$_0.filter((W)=>!Z||`${W.ref} ${W.desc}`.toLowerCase().includes(Z)).map((W)=>({...W,firstParty:!0})),z=Z_0([...X,...J.flatMap((W)=>W??[])]);if(J.every((W)=>W===null))console.error("(GitHub search unreachable \u2014 showing first-party plugins only)");if(z.length===0){console.log($?`no plugins match \`${$}\``:"no plugins found");return}let G=Math.min(48,Math.max(...z.map((W)=>W.ref.length))+2);for(let W of z){let q=W.stars!==void 0?`\u2605${W.stars}`:W.firstParty?"first-party":"";console.log(`${W.ref.padEnd(G)}${q.padEnd(12)}${W.desc}`)}console.log(`
833
- install: ${eV0} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.sma1lboy.me/plugins`)}function Z_0($){let J=new Set;return $.filter((Z)=>{let X=Z.ref.toLowerCase();if(J.has(X))return!1;return J.add(X),!0})}var tV0=5000,eV0,$_0;var i00=c(()=>{x4();eV0=a1(),$_0=[{ref:"Sma1lboy/kobe-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/kobe-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/kobe-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/kobe-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/kobe-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/kobe-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}]});import{readFileSync as X_0,writeFileSync as Q_0}from"fs";function o00($,J){let Z={checkedAt:Date.now(),outdated:$};try{Q_0(HS(J),`${JSON.stringify(Z,null,2)}
833
+ install: ${eV0} plugin install <owner/repo[/subdir]> \u2014 browse: https://rove.run/plugins`)}function Z_0($){let J=new Set;return $.filter((Z)=>{let X=Z.ref.toLowerCase();if(J.has(X))return!1;return J.add(X),!0})}var tV0=5000,eV0,$_0;var i00=c(()=>{x4();eV0=a1(),$_0=[{ref:"Sma1lboy/kobe-plugins/notify",desc:"Desktop/ntfy notifications when an agent finishes or needs input"},{ref:"Sma1lboy/kobe-plugins/github-start",desc:"Start a Rove task from a GitHub issue or PR"},{ref:"Sma1lboy/kobe-plugins/worktree-include",desc:"Copy .worktreeinclude-matched files into new worktrees"},{ref:"Sma1lboy/kobe-plugins/linear-start",desc:"Pick a Linear issue (fzf) and start a task on its branch"},{ref:"Sma1lboy/kobe-plugins/lazygit",desc:"lazygit on the task worktree, as a pane tab"},{ref:"Sma1lboy/kobe-plugins/browser",desc:"Chromium rendered as terminal cells (carbonyl) in a pane tab"}]});import{readFileSync as X_0,writeFileSync as Q_0}from"fs";function o00($,J){let Z={checkedAt:Date.now(),outdated:$};try{Q_0(HS(J),`${JSON.stringify(Z,null,2)}
834
834
  `)}catch{}}function a00($){try{let J=JSON.parse(X_0(HS($),"utf8"));if(typeof J.checkedAt!=="number"||!Array.isArray(J.outdated))return[];if(Date.now()-J.checkedAt>z_0)return[];return J.outdated.filter((Z)=>typeof Z==="string")}catch{return[]}}var z_0=86400000;var Bx=c(()=>{yJ()});var Fx={};A$(Fx,{updatePlugins:()=>K_0,printOutdated:()=>U_0,listOutdated:()=>FC});import{execFileSync as Y_0}from"child_process";import{existsSync as r00,mkdirSync as G_0,readdirSync as W_0,renameSync as q_0}from"fs";import{join as Kx}from"path";function s00($,J){try{return Y_0("git",$,{cwd:J,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()}catch{return null}}function H_0($){let J=$.source.spec.split("/").slice(0,2).join("/"),Z=s00(["rev-parse","HEAD"],SH($.id)),X=s00(["ls-remote",`https://github.com/${J}.git`,"HEAD"]),z=X?X.split(/\s+/)[0]??null:null;return{id:$.id,spec:$.source.spec,version:$.version,localSha:Z,remoteSha:z,behind:Boolean(Z&&z&&Z!==z)}}function FC(){let $=o4().plugins.filter((J)=>J.source.kind==="github").map(H_0);return o00($.filter((J)=>J.behind).map((J)=>J.id)),$}function U_0(){let $=FC();if($.length===0){console.log("no GitHub-installed plugins.");return}for(let J of $){let Z=J.behind?"update available":J.remoteSha===null?"remote unreachable":J.localSha===null?"local sha unreadable":"up to date";console.log(`${J.id} v${J.version} ${Z}`)}}function B_0($,J){for(let Z of[D3,eQ]){let X=Z($),z=Z(J);if(!r00(X))continue;G_0(z,{recursive:!0});for(let G of W_0(X)){if(r00(Kx(z,G)))continue;q_0(Kx(X,G),Kx(z,G))}}bJ(yF(o4(),$)),console.log(`renamed ${$} \u2192 ${J}: settings and state carried over, old entry unregistered`),console.log(` leftover checkout (safe to remove): ${TH($)}`)}async function K_0($,J){let Z=FC(),X;if(J.all){if(X=Z.filter((z)=>z.behind),X.length===0){console.log("all plugins up to date.");return}}else{if($.length===0)throw new s4("update takes plugin ids or --all");X=$.map((z)=>{let G=Z.find((W)=>W.id===z);if(!G)throw new s4(`\`${z}\` is not a GitHub-installed plugin; see \`${a1()} plugin list\``);return G})}for(let z of X){if(!z.behind&&!$.includes(z.id))continue;console.log(`updating ${z.id} (${z.spec})\u2026`);let G=await KC(z.spec,{yes:J.yes});if(G!==z.id)B_0(z.id,G)}FC()}var Mx=c(()=>{Bx();yJ();gJ();Ux();x4()});var e00={};A$(e00,{runPluginSubcommand:()=>R_0});import{spawnSync as F_0}from"child_process";import{readFileSync as M_0,rmSync as N_0}from"fs";function Nx($){$.write([`usage: ${HX} plugin <command>`,""," install <owner/repo[/subdir]> [--yes] [--ref <rev>] clone from GitHub, preview, build, register"," link <dir> register a local plugin directory (dev)"," list installed + linked plugins"," search [query] browse the marketplace (GitHub topic rove-plugin)"," outdated check GitHub-installed plugins against upstream"," update <id\u2026> | --all [--yes] reinstall stale plugins from GitHub"," enable <id> | disable <id> toggle a plugin without unregistering it"," unlink <id> unregister a linked plugin (files untouched)"," uninstall <id-or-spec> unregister + remove the managed checkout"," config-dir <id> print the plugin's config directory"," log <id> [-n <count>] tail the plugin's command-run log"," action list [--plugin <id>] declared actions"," action invoke <plugin-id.action-id> run an action now"," pane open --plugin <id> --entrypoint <pane-id> open a plugin pane as a terminal tab","","Marketplace: https://github.com/topics/rove-plugin (legacy kobe-plugin is included)",""].join(`
835
835
  `))}function MC(){return o4().plugins.map(($)=>{try{return{entry:$,manifest:G6($.root).manifest}}catch{return{entry:$,manifest:void 0}}})}function NC($){let J=o4().plugins.find((Z)=>Z.id===$);if(!J)throw new s4(`no plugin registered as \`${$}\`; see \`${HX} plugin list\``);return J}function L_0(){let $=MC();if($.length===0){console.log(`no plugins installed. Try: ${HX} plugin install <owner/repo> \u2014 browse the \`rove-plugin\` GitHub topic.`);return}for(let{entry:J,manifest:Z}of $){let X=J.enabled?"enabled":"disabled",z=J.source.kind==="link"?`linked ${J.root}`:J.source.spec,G=Z?"":" [manifest unreadable]";console.log(`${J.id} v${J.version} ${X} (${z})${G}`)}}function O_0($,J){let Z=NC($),X=o4();bJ({plugins:X.plugins.map((z)=>z.id===$?{...Z,enabled:J}:z)}),console.log(`${J?"enabled":"disabled"} ${$}`)}function j_0($){let J=NC($);if(J.source.kind!=="link")throw new s4(`\`${$}\` is a GitHub install; use uninstall`);bJ(yF(o4(),$)),console.log(`unlinked ${$} (files untouched at ${J.root})`)}function V_0($){let J=o4(),Z=J.plugins.find((X)=>X.id===$||X.source.kind==="github"&&X.source.spec===$);if(!Z)throw new s4(`no plugin registered as \`${$}\``);if(Z.source.kind==="link")throw new s4(`\`${Z.id}\` is linked; use unlink`);bJ(yF(J,Z.id)),N_0(SH(Z.id),{recursive:!0,force:!0}),console.log(`uninstalled ${Z.id} (config/state kept under ~/.kobe/plugins/${Z.id}/)`)}function __0($){for(let{entry:J,manifest:Z}of MC()){if(!Z||$&&J.id!==$)continue;for(let X of Z.actions)console.log(`${KV(J.id,X.id)} ${X.title}`)}}function t00($,J,Z){for(let{entry:X,manifest:z}of MC().filter(({entry:G,manifest:W})=>Boolean(W&&(!J.enabledOnly||G.enabled)&&$.startsWith(`${G.id}.`))).sort((G,W)=>W.entry.id.length-G.entry.id.length)){let G=Z(z,$.slice(X.id.length+1));if(G!==void 0)return{entry:X,item:G}}return}function C_0($,J){let Z=t00($,{enabledOnly:!0},(q,U)=>q.actions.find((B)=>B.id===U));if(!Z)throw new s4(`no action \`${$}\`; see \`${HX} plugin action list\``);let X=Z.item,[z,...G]=[...X.command,...J],W=F_0(z,G,{cwd:Z.entry.root,stdio:"inherit",env:dH({socketPath:U2(),binPath:HX,pluginId:Z.entry.id,pluginRoot:Z.entry.root,extra:{ROVE_PLUGIN_ACTION_ID:X.id,ROVE_PLUGIN_INVOKE_CWD:process.cwd()}})});process.exit(W.status??1)}function A_0($){let J=t00($,{enabledOnly:!1},(Z,X)=>Z.panes.find((z)=>z.id===X));if(!J)throw new s4(`no pane \`${$}\`; see \`${HX} plugin list\``);return{pluginId:J.entry.id,entrypoint:J.item.id}}async function D_0($,J,Z){let X=MC().find(({entry:B})=>B.id===$);if(!X?.manifest)throw new s4(`no plugin \`${$}\` (or its manifest is unreadable)`);if(!X.entry.enabled)throw new s4(`\`${$}\` is disabled`);let z=X.manifest.panes.find((B)=>B.id===J);if(!z)throw new s4(`no pane \`${J}\` in \`${$}\`; declare it under [[panes]]`);let G=Gx(X.entry.id,X.entry.root,z,{socketPath:U2(),binPath:HX}),{openDaemonSession:W,resolveActiveTaskId:q}=await Promise.resolve().then(() => (uj(),Rh)),U=await W({mode:"start"});try{let B=Z??await q(U.client);if(!B)throw new s4("no active task; pass --task <id>");await U.client.request("tab.open",{taskId:B,argv:G,title:z.title,placement:z.placement}),console.log(`opened pane ${$}.${z.id} in task ${B}`)}finally{U.close()}}function P_0($,J){NC($);let Z;try{Z=M_0(IH($),"utf8")}catch{console.log("(no runs logged yet)");return}let X=Z.trimEnd().split(`
836
836
  `);for(let z of X.slice(-J))console.log(z)}function _G($,J){let Z=$.indexOf(J);return Z>=0?$[Z+1]:void 0}async function R_0($){let[J,...Z]=$;try{switch(J){case"install":{let X=Z.find((z)=>!z.startsWith("-"));if(!X)throw new s4("install needs <owner/repo[/subdir]>");await KC(X,{yes:Z.includes("--yes"),ref:_G(Z,"--ref")});return}case"link":{if(!Z[0])throw new s4("link needs a directory");d00(Z[0]);return}case"list":L_0();return;case"search":{let{searchMarketplace:X}=await Promise.resolve().then(() => (i00(),n00));await X(Z.find((z)=>!z.startsWith("-")));return}case"outdated":{let{printOutdated:X}=await Promise.resolve().then(() => (Mx(),Fx));X();return}case"update":{let{updatePlugins:X}=await Promise.resolve().then(() => (Mx(),Fx));await X(Z.filter((z)=>!z.startsWith("-")),{all:Z.includes("--all"),yes:Z.includes("--yes")});return}case"enable":case"disable":{if(!Z[0])throw new s4(`${J} needs a plugin id`);O_0(Z[0],J==="enable");return}case"unlink":{if(!Z[0])throw new s4("unlink needs a plugin id");j_0(Z[0]);return}case"uninstall":{if(!Z[0])throw new s4("uninstall needs a plugin id or owner/repo spec");V_0(Z[0]);return}case"config-dir":{if(!Z[0])throw new s4("config-dir needs a plugin id");NC(Z[0]),console.log(D3(Z[0]));return}case"log":{if(!Z[0])throw new s4("log needs a plugin id");P_0(Z[0],Number.parseInt(_G(Z,"-n")??"20",10)||20);return}case"pane":{let[X,...z]=Z;if(X==="open"){let G=z.find((U)=>!U.startsWith("-")&&U!==_G(z,"--task")),W=_G(z,"--plugin"),q=_G(z,"--entrypoint");if(!W||!q){if(!G)throw new s4("pane open needs <plugin-id.pane-id> (or --plugin <id> --entrypoint <pane-id>) [--task <task-id>]");({pluginId:W,entrypoint:q}=A_0(G))}await D_0(W,q,_G(z,"--task"));return}Nx(process.stderr),process.exit(2);return}case"action":{let[X,...z]=Z;if(X==="list"){__0(_G(z,"--plugin"));return}if(X==="invoke"){if(!z[0])throw new s4("action invoke needs <plugin-id.action-id>");C_0(z[0],z.slice(1));return}Nx(process.stderr),process.exit(2);return}default:{let X=J===void 0||J==="help"||J==="--help"||J==="-h";if(Nx(X?process.stdout:process.stderr),!X)process.exit(2);return}}}catch(X){if(X instanceof s4)console.error(`${HX} plugin: ${X.message}`),process.exit(1);console.error(`${HX} plugin: ${M1(X)}`),process.exit(1)}}var HX;var $10=c(()=>{B7();Y_();rZ();Wx();yJ();gJ();Ux();x4();HX=a1()});var H10={};A$(H10,{runHookSubcommand:()=>f_0,readTextWithTimeout:()=>z10,parseWorktreeRemovePath:()=>G10,ensureGlobalKobeHooks:()=>Ox});import{homedir as T_0}from"os";import{join as X10,resolve as Q10}from"path";async function z10($,J=S_0){let Z;try{return await Promise.race([$(),new Promise((X)=>{Z=setTimeout(()=>X(""),J)})])}finally{if(Z!==void 0)clearTimeout(Z)}}async function Y10(){try{let $=await z10(()=>Bun.stdin.text());if(!$.trim())return{};let J=JSON.parse($);return J&&typeof J==="object"&&!Array.isArray(J)?J:{}}catch{return{}}}function J10($,J){for(let Z=0;Z<$.length;Z++){if($[Z]===J)return $[Z+1];if($[Z].startsWith(`${J}=`))return $[Z].slice(J.length+1)}return}function E_0($){return!!$&&typeof $==="object"&&!Array.isArray($)}function w_0($){let J=[],Z=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=Z.exec($))!==null)J.push(X[1]??X[2]??X[3]??"");return J}function G10($){let J=w_0($);for(let Z=0;Z+1<J.length;Z++){if(J[Z]!=="worktree"||J[Z+1]!=="remove")continue;let X=Z+2;while(X<J.length){let z=J[X];if(z==="&&"||z==="||"||z===";"||z==="|"||z===">"||z===">>")break;if(z.startsWith("-")){X+=1;continue}return z}}return}async function x_0(){let $=await Y10(),J=E_0($.tool_input)?$.tool_input:{},Z=typeof J.command==="string"?J.command:"";if(!Z.includes("worktree"))return;let X=typeof $.cwd==="string"&&$.cwd?$.cwd:process.cwd(),z=G10(Z);if(!z)return;let G=await DJ();if(!G)return;try{await G.request("worktree.archiveRemoved",{worktreePath:Q10(X,z)})}finally{G.close()}}async function f_0($){let[J,...Z]=$;if(J==="setup"){await k_0(Z);return}if(J==="cleanup"){await v_0();return}if(J===I_0){try{await x_0()}catch{}return}try{if(!J||!D_(J))return;let X=await Y10(),z=J10(Z,"--task-id"),G=typeof X.cwd==="string"&&X.cwd?X.cwd:process.cwd(),W=process.env.KOBE_TASK_ID,q=process.env.KOBE_TAB_ID,U=J10(Z,"--engine"),B=Lx().filter((j)=>!U||j.vendor===U),M;for(let j of B)if(M=j.activityDetailFromPayload(J,X),M)break;let L;for(let j of B)if(L=j.sessionFromPayload(X),L)break;let N=await DJ();if(!N)return;try{let j=z??W;await N.request("engine.reportEvent",{...j?{taskId:j}:{cwd:G},kind:J,...U?{engine:U}:{},...q?{tabId:q}:{},...M?{detail:M}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{N.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[rove hook] ${J} failed:`,X instanceof Error?X.message:String(X))}}function y_0(){return h8.map(($)=>bR($)).filter(($)=>$.supportsWorktreeSync())}function Lx(){return h8.map(($)=>bR($)).filter(($)=>$.supportsHooks())}function W10(){return X10(T_0(),".claude","settings.json")}function b_0($){if(!$||$==="off")return;if($==="global")return W10();if($.startsWith("repo:"))return X10(Q10($.slice(5)),".claude","settings.json");return $}async function Ox(){try{let{isRovePluginEnabled:$,detectLegacyInstalls:J,migrationHint:Z}=await Promise.resolve().then(() => (a_(),o_)),X=$();if(X){let G=Z(J(),a1());if(G)process.stderr.write(`
package/dist/cli/rove.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import{join as l}from"node:path";import{createInterface as s}from"node:readline/promises";import{pathToFileURL as o}from"node:url";import{spawnSync as U}from"node:child_process";import{constants as f,accessSync as A}from"node:fs";import{homedir as y}from"node:os";import{basename as S,delimiter as _,dirname as p,join as $}from"node:path";import{fileURLToPath as w}from"node:url";var W="rove",Y="kobe";var N="ROVE_INVOKED_AS";function K(z=process.env){return z[N]===W?W:Y}var x="ROVE_BUN",v="ROVE_NO_BUN_BOOTSTRAP",E=(z)=>{try{return A(z,f.X_OK),!0}catch{return!1}},d=(z)=>z==="win32"?"bun.exe":"bun";function m(z={}){let H=z.env??process.env,J=z.platform??process.platform,Z=z.home??H.HOME??H.USERPROFILE??y(),Q=d(J),X=[],G=H[x]?.trim();if(G)X.push(G);for(let L of(H.PATH??H.Path??"").split(_))if(L)X.push($(L,Q));let V=H.BUN_INSTALL?.trim();if(V)X.push($(V,"bin",Q));if(Z)X.push($(Z,".bun","bin",Q));let q=z.launcherDir;if(q)X.push($(q,"..","..","node_modules","bun","bin",Q)),X.push($(q,"..","..","..","bun","bin",Q));return X}function F(z={}){let H=z.isExecutable??E;return m(z).find((J)=>H(J))??null}function b(z){return p(w(z))}function B(z){return S(w(z)).replace(/\.[cm]?[jt]s$/,"")}function c(z=process.platform){return z==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(z=K(),H=process.platform){let J=H==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${z}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${J}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.sma1lboy.me/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${x}=/path/to/bun`,""].join(`
2
+ import{join as l}from"node:path";import{createInterface as s}from"node:readline/promises";import{pathToFileURL as o}from"node:url";import{spawnSync as U}from"node:child_process";import{constants as f,accessSync as A}from"node:fs";import{homedir as y}from"node:os";import{basename as S,delimiter as _,dirname as p,join as $}from"node:path";import{fileURLToPath as w}from"node:url";var W="rove",Y="kobe";var N="ROVE_INVOKED_AS";function K(z=process.env){return z[N]===W?W:Y}var x="ROVE_BUN",v="ROVE_NO_BUN_BOOTSTRAP",E=(z)=>{try{return A(z,f.X_OK),!0}catch{return!1}},d=(z)=>z==="win32"?"bun.exe":"bun";function m(z={}){let H=z.env??process.env,J=z.platform??process.platform,Z=z.home??H.HOME??H.USERPROFILE??y(),Q=d(J),X=[],G=H[x]?.trim();if(G)X.push(G);for(let L of(H.PATH??H.Path??"").split(_))if(L)X.push($(L,Q));let V=H.BUN_INSTALL?.trim();if(V)X.push($(V,"bin",Q));if(Z)X.push($(Z,".bun","bin",Q));let q=z.launcherDir;if(q)X.push($(q,"..","..","node_modules","bun","bin",Q)),X.push($(q,"..","..","..","bun","bin",Q));return X}function F(z={}){let H=z.isExecutable??E;return m(z).find((J)=>H(J))??null}function b(z){return p(w(z))}function B(z){return S(w(z)).replace(/\.[cm]?[jt]s$/,"")}function c(z=process.platform){return z==="win32"?["powershell","-NoProfile","-Command","irm bun.sh/install.ps1 | iex"]:["bash","-c","curl -fsSL https://bun.sh/install | bash"]}function D(z=K(),H=process.platform){let J=H==="win32"?'powershell -c "irm bun.sh/install.ps1 | iex"':"curl -fsSL https://bun.sh/install | bash";return[`${z}: Rove runs on the Bun runtime, and no Bun was found on this machine.`,"","Install Bun, then run this command again:",` ${J}`," npm install -g bun # any platform, if you already have npm","","Or install Bun and Rove together in one step:"," curl -fsSL https://rove.run/install.sh | sh","",`Already have Bun somewhere unusual? Point Rove at it: ${x}=/path/to/bun`,""].join(`
3
3
  `)}function C(z=process.env,H=process.stdin,J=process.stdout){if(z[v]==="1")return!1;if(z.CI==="true"||z.CI==="1")return!1;return Boolean(H.isTTY&&J.isTTY)}function M(z={},H=U){let J=z.platform??process.platform,[Z,...Q]=c(J);if(!Z)return null;let X=H(Z,Q,{stdio:"inherit"});if(X.error||X.status!==0)return null;return F(z)}function u(z){if(typeof z.status==="number")return z.status;if(z.signal)return 128+(Object.hasOwn(j,z.signal)?j[z.signal]:0);return 1}var j={SIGINT:2,SIGQUIT:3,SIGKILL:9,SIGTERM:15};function k(z,H,J,Z=U){let Q=Z(z,[H,...J],{stdio:"inherit"});if(Q.error)return process.stderr.write(`rove: could not start Bun at ${z}: ${Q.error.message}
4
4
  `),1;return u(Q)}var O=b(import.meta.url),P=B(import.meta.url),T=l(O,`${P}-run.js`);async function i(z){let H=s({input:process.stdin,output:process.stdout});try{let J=(await H.question(z)).trim().toLowerCase();return J===""||J==="y"||J==="yes"}finally{H.close()}}async function a(){let z={launcherDir:O},H=F(z);if(H)return H;if(!C())return null;let J=`${P}: Rove runs on the Bun runtime, and none is installed. Install Bun now? [Y/n] `;if(!await i(J))return null;return M(z)}if(typeof globalThis.Bun<"u")await import(o(T).href);else{let z=await a();if(!z)process.stderr.write(D(P)),process.exit(1);process.exit(k(z,T,process.argv.slice(2)))}
package/package.json CHANGED
@@ -1,8 +1,24 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sma1lboy/kobe",
4
- "version": "0.8.194",
4
+ "version": "0.8.195",
5
5
  "description": "Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",
6
+ "keywords": [
7
+ "terminal",
8
+ "tui",
9
+ "cli",
10
+ "multiplexer",
11
+ "ai-agents",
12
+ "coding-agent",
13
+ "ai-coding-assistant",
14
+ "agentic-ai",
15
+ "parallel-agents",
16
+ "git-worktree",
17
+ "claude-code",
18
+ "codex",
19
+ "llm",
20
+ "developer-tools"
21
+ ],
6
22
  "type": "module",
7
23
  "packageManager": "bun@1.3.13",
8
24
  "bin": {
@@ -24,7 +40,7 @@
24
40
  "type": "git",
25
41
  "url": "git+https://github.com/Sma1lboy/rove.git"
26
42
  },
27
- "homepage": "https://github.com/Sma1lboy/rove#readme",
43
+ "homepage": "https://rove.run",
28
44
  "bugs": {
29
45
  "url": "https://github.com/Sma1lboy/rove/issues"
30
46
  },