@sma1lboy/kobe 0.8.142 → 0.8.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -303,7 +303,7 @@ ${G}
303
303
  `)}let z=CY0();for(let G of RT()){if(X&&G.vendor==="claude")continue;let W=G.globalSettingsPath();if(!W)continue;await G.installActivityHooks(W,{toolEvents:z}),await G.installWorktreeWatchHook(W)}await rm()}catch{}}function CY0(){try{for(let $ of V5().plugins){if(!$.enabled)continue;try{if(KZ($.root).manifest.events.some((Z)=>Z.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function rm(){let $=VY0();if($.length===0)return;let Z=x5(cm),J=new Set([am()]),X=_Y0(Z);if(X)J.add(X);for(let z of $)for(let G of J)await z.removeWorktreeSyncHook(G);if(Z!=="off")X6(cm,"off")}async function DY0(){let $=RT().find((J)=>J.vendor==="claude"),Z=$?.globalSettingsPath();if(!$||!Z){process.stdout.write(`rove hook cleanup: no Claude hook adapter \u2014 nothing to do.
304
304
  `);return}await $.removeActivityHooks(Z),await $.removeWorktreeWatchHook(Z),process.stdout.write([`rove hook cleanup: removed Rove's settings-managed hooks from ${Z}.`,"Only Rove's own entries were touched; your other hooks are intact.","The Claude Code plugin's hooks.json now carries these events (if the plugin","is not installed, the next Rove launch reinstalls the settings-managed set).",""].join(`
305
305
  `))}async function AY0($){await rm(),process.stdout.write(["rove hook setup is deprecated and now a no-op (cleanup only).","","The old external-worktree sync used a global WorktreeCreate hook, which is","a VCS provider hook \u2014 its presence broke `claude --worktree` / EnterWorktree","in every repo. Any hook Rove previously installed has been removed.","","Sync is now automatic: a `claude --worktree` (or any session) started in a","worktree under a repo Rove already tracks is adopted as a task on launch.","To adopt existing worktrees on demand, use the New Task dialog or `rove adopt`.",""].join(`
306
- `))}var MY0=500,NY0="worktree-created",cm="externalWorktreeSync";var ST=l(()=>{T7();xQ();mJ();CT();AT();C4();D2();u4()});var jj;var tm=l(()=>{jj={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.142",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"},"//":"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.14","@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 $h={};P$($h,{repoSlug:()=>yY,releasePageUrl:()=>yT,recommendedGlobalInstallCommand:()=>wT,isNewerSemver:()=>IT,fetchReleaseSummaries:()=>YF,fetchReleaseNotesRange:()=>fT,fetchReleaseNotes:()=>xT,compareSemver:()=>V3,checkLatestVersion:()=>gY,breakingVersionsCrossed:()=>zF,UPDATE_SCRIPT_URL:()=>Vj,UPDATE_COMMAND:()=>jZ,PACKAGE_NAME:()=>ET,CURRENT_VERSION:()=>R$,BREAKING_VERSIONS:()=>dJ});function yY(){let $=jj.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function wT(){return`npm install -g ${ET}@latest`}function zF($,Z,J=dJ){let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}async function RY0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),_j);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:Z.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(J)}}function IT($,Z){return V3($,Z)>0}function V3($,Z){let J=(G)=>G.split("-")[0]??G,X=J($).split(".").map((G)=>Number.parseInt(G,10)),z=J(Z).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,H=z[G]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function gY($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:R$,latest:Z,hasUpdate:IT(Z,R$)};if(RH()&&!$.force)return null;let J=await RY0(ET);if(!J)return null;return{current:R$,latest:J,hasUpdate:IT(J,R$)}}function em($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function xT($){let Z=yY();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),_j);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases/tags/${J}`,{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 fT($){let Z=yY();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),_j);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${J}`,{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((H)=>{let U=em(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(V3(U,$.current)<=0)return null;if(V3(U,$.latest)>0)return null;return{version:U,url:H.html_url,body:H.body}}).filter((H)=>H!==null)}catch{return[]}finally{clearTimeout(z)}}async function YF($=12){let Z=yY();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),_j);try{let z=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${$}`,{signal:J.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 H=em(W.tag_name);if(!H||typeof W.html_url!=="string")return null;return{version:H,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function yT($){let Z=yY();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var R$,ET,Vj="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",jZ,dJ,_j=3000;var d8=l(()=>{tm();j5();R$=jj.version,ET=jj.name;jZ=`curl -fsSL ${Vj} | sh`;dJ=[]});var Jh={};P$(Jh,{stampResetGate:()=>Cj,resetGateBlockers:()=>Zh,enforceResetGate:()=>bT,LAST_RUN_VERSION_KEY:()=>gT});function Zh($,Z=R$,J=dJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}function bT(){let $=$$(),Z=N4()[gT],J=Zh(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${R$}: cannot start \u2014 version ${J.join(", ")} introduced breaking changes`,`(last run: ${X}). Your daemon/session state may be incompatible.`,"","Run:",` ${$} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${$} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
306
+ `))}var MY0=500,NY0="worktree-created",cm="externalWorktreeSync";var ST=l(()=>{T7();xQ();mJ();CT();AT();C4();D2();u4()});var jj;var tm=l(()=>{jj={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.143",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"},"//":"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.14","@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 $h={};P$($h,{repoSlug:()=>yY,releasePageUrl:()=>yT,recommendedGlobalInstallCommand:()=>wT,isNewerSemver:()=>IT,fetchReleaseSummaries:()=>YF,fetchReleaseNotesRange:()=>fT,fetchReleaseNotes:()=>xT,compareSemver:()=>V3,checkLatestVersion:()=>gY,breakingVersionsCrossed:()=>zF,UPDATE_SCRIPT_URL:()=>Vj,UPDATE_COMMAND:()=>jZ,PACKAGE_NAME:()=>ET,CURRENT_VERSION:()=>R$,BREAKING_VERSIONS:()=>dJ});function yY(){let $=jj.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function wT(){return`npm install -g ${ET}@latest`}function zF($,Z,J=dJ){let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}async function RY0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),_j);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:Z.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(J)}}function IT($,Z){return V3($,Z)>0}function V3($,Z){let J=(G)=>G.split("-")[0]??G,X=J($).split(".").map((G)=>Number.parseInt(G,10)),z=J(Z).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,H=z[G]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function gY($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:R$,latest:Z,hasUpdate:IT(Z,R$)};if(RH()&&!$.force)return null;let J=await RY0(ET);if(!J)return null;return{current:R$,latest:J,hasUpdate:IT(J,R$)}}function em($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function xT($){let Z=yY();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),_j);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases/tags/${J}`,{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 fT($){let Z=yY();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),_j);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${J}`,{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((H)=>{let U=em(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(V3(U,$.current)<=0)return null;if(V3(U,$.latest)>0)return null;return{version:U,url:H.html_url,body:H.body}}).filter((H)=>H!==null)}catch{return[]}finally{clearTimeout(z)}}async function YF($=12){let Z=yY();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),_j);try{let z=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${$}`,{signal:J.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 H=em(W.tag_name);if(!H||typeof W.html_url!=="string")return null;return{version:H,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function yT($){let Z=yY();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var R$,ET,Vj="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",jZ,dJ,_j=3000;var d8=l(()=>{tm();j5();R$=jj.version,ET=jj.name;jZ=`curl -fsSL ${Vj} | sh`;dJ=[]});var Jh={};P$(Jh,{stampResetGate:()=>Cj,resetGateBlockers:()=>Zh,enforceResetGate:()=>bT,LAST_RUN_VERSION_KEY:()=>gT});function Zh($,Z=R$,J=dJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}function bT(){let $=$$(),Z=N4()[gT],J=Zh(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${R$}: cannot start \u2014 version ${J.join(", ")} introduced breaking changes`,`(last run: ${X}). Your daemon/session state may be incompatible.`,"","Run:",` ${$} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${$} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
307
307
  `)),process.exit(1)}if(Z!==R$)Cj()}function Cj(){try{S7({[gT]:R$})}catch{}}var gT="app.lastRunVersion";var Dj=l(()=>{I7();d8();u4()});import{existsSync as Qh,readFileSync as TY0}from"fs";import{homedir as SY0}from"os";import{join as zh,resolve as Xh}from"path";import{fileURLToPath as IY0}from"url";function mT($=process.env){return`${$$($)} skill install`}function Aj(){let $=IY0(import.meta.url);return[Xh($,"../../../../../.agents/skills/kobe"),Xh($,"../../skills/rove")].find((J)=>Qh(zh(J,"SKILL.md")))??null}function Pj($={}){let Z=$.source!==void 0?$.source:Aj(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??wY0,"--skill",e3,...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function bY($={}){return`npx ${Pj($).join(" ")}`}async function hT($,Z){return await Bun.spawn(["npx",...Pj({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function Rj($={}){let Z=$.home??SY0(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>EY0.map((z)=>zh(X,z)))}function xY0($){let Z=$.match(/(?:rove|kobe)-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function GF($){let Z=Rj($).find((z)=>Qh(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:vT,stale:!1};let J=null;try{J=xY0(TY0(Z,"utf8"))}catch{J=null}let X=J===null||J<vT;return{installed:!0,installedVersion:J,currentVersion:vT,stale:X}}function fY0(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function Yh($={}){let{isRovePluginEnabled:Z}=await Promise.resolve().then(() => (Oj(),Lj));if(Z())return;let J=$$(),X=mT(),z=GF();if(!z.installed){if(x5(kT)==="1")return;X6(kT,"1"),process.stderr.write(`
308
308
  ${J}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${J} api\`:
309
309
  ${X}
@@ -879,7 +879,7 @@ ${O50}
879
879
  `)});function D50($){if($ instanceof Error)return $;let Z;try{Z=typeof $==="string"?$:JSON.stringify($)}catch{Z=String($)}return Error(Z)}function C50($,Z,J=new Date){let X=D50(Z);return`[${J.toISOString()}] daemon ${$}: ${X.stack??`${X.name}: ${X.message}`}
880
880
  `}function pO0($,Z,J=new Date){let X=D50(Z);return`[${J.toISOString()}] daemon error [${$}]: ${X.stack??`${X.name}: ${X.message}`}
881
881
  `}function d1($,Z){process.stderr.write(pO0($,Z))}function nO0($,Z,J=new Date){return`[${J.toISOString()}] daemon [${$}]: ${Z}
882
- `}function A5($,Z){process.stderr.write(nO0($,Z))}function pC($=(Z)=>process.stderr.write(Z)){if(cx||dx)return;cx=(Z)=>$(C50("unhandledRejection",Z)),dx=(Z)=>$(C50("uncaughtException",Z)),process.on("unhandledRejection",cx),process.on("uncaughtException",dx)}var cx,dx;function A50($,Z){switch($){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return Z?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}function VM($){if(!$)return;let{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}=$;return{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}}class lx{tasks;agentState=new Map;now;constructor($=Date.now){this.now=$}contextFor($){return VM(this.tasks?.get($))}reduce($){switch($.channel){case"task.snapshot":return this.reduceTasks($.payload.tasks);case"task.jobs":return this.reduceJobs($.payload);case"engine-state":return this.reduceEngine($.payload);default:return[]}}reduceTasks($){let Z=new Map($.map((G)=>[G.id,G])),J=this.tasks;if(this.tasks=Z,!J)return[];let X=this.now(),z=[];for(let[G,W]of Z)if(!J.has(G))z.push({event:"task.created",taskId:G,task:VM(W),at:X});for(let[G,W]of J)if(!Z.has(G))z.push({event:"task.deleted",taskId:G,task:VM(W),at:X});return z}reduceJobs($){if($.kind!=="ensureWorktree"||$.phase!=="done")return[];return[{event:"worktree.created",taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}reduceEngine($){let Z=`${$.taskId}\x00${$.tabId??""}`,J=this.agentState.get(Z);if(this.agentState.set(Z,$.state),J===$.state)return[];let X=iO0[$.state];if(!X)return[];return[{event:X,taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}}var iO0;var P50=l(()=>{iO0={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"}});import{spawn as oO0}from"child_process";import{appendFileSync as aO0,mkdirSync as px,watch as rO0}from"fs";import{dirname as R50}from"path";function tO0($,Z){let J=new S50(Z);return $.onPublish((X)=>J.handleChannel(X)),J.start(),J}function T50($,Z,J,X){if(!Z.plugins)return null;return tO0($,{homeDir:Z.homeDir,socketPath:J,binPath:Z.plugins.binPath,log:X})}class S50{opts;reducer=new lx;plugins=[];watcher;reloadTimer;stopped=!1;constructor($){this.opts=$}start(){this.plugins=this.loadPlugins();for(let $ of this.plugins)for(let[Z,J]of $.manifest.startup.entries()){if(!FZ(J,$.manifest,vJ()))continue;this.run($,J,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${Z}]`)}this.watchRegistry()}stop(){if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);this.watcher?.close()}handleChannel($){if(this.stopped)return;for(let Z of this.reducer.reduce($))this.dispatch(Z)}handleUiReport($){if(this.stopped)return;this.dispatch({event:$.kind,...$.taskId?{taskId:$.taskId,task:this.reducer.contextFor($.taskId)}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}handleEngineReport($){if(this.stopped)return;let Z=A50($.kind,$.detail);if(!Z)return;this.dispatch({event:Z,taskId:$.taskId,task:this.reducer.contextFor($.taskId),...$.vendor?{vendor:$.vendor}:{},...$.tabId?{tabId:$.tabId}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}dispatch($){let Z=vJ();for(let J of this.plugins)for(let X of J.manifest.events){if(X.on!==$.event)continue;if(!FZ(X,J.manifest,Z))continue;this.run(J,X,"event",{ROVE_PLUGIN_EVENT:$.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify($),...$.taskId?{ROVE_PLUGIN_TASK_ID:$.taskId}:{},...$.task?.title?{ROVE_PLUGIN_TASK_TITLE:$.task.title}:{}},X.on)}}loadPlugins(){let $=V5(this.opts.homeDir),Z=vJ(),J=[];for(let X of $.plugins){if(!X.enabled)continue;let z;try{z=KZ(X.root).manifest}catch(G){this.opts.log?.(`plugin ${X.id}: manifest unreadable, skipping \u2014 ${String(G)}`);continue}if(!FZ({},z,Z))continue;J.push({manifest:z,root:X.root})}return J}watchRegistry(){let $=sK(this.opts.homeDir);try{px(R50($),{recursive:!0}),this.watcher=rO0(R50($),(Z,J)=>{if(J&&J!=="plugins.json")return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`)},sO0)})}catch(Z){this.opts.log?.(`plugin registry watch failed \u2014 ${String(Z)}`)}}async run($,Z,J,X,z){let G=$.manifest.id,W=Date.now();px(j3(G,this.opts.homeDir),{recursive:!0}),px(fQ(G,this.opts.homeDir),{recursive:!0});let H=null,U="",B="",M;await new Promise((N)=>{let[j,...P]=Z.command,C=oO0(j,P,{cwd:$.root,env:qU({homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,pluginId:$.manifest.id,pluginRoot:$.root,extra:X}),stdio:["ignore","pipe","pipe"]});C.stdout.on("data",(_)=>{if(U.length<nC)U+=_.toString().slice(0,nC-U.length)}),C.stderr.on("data",(_)=>{if(B.length<nC)B+=_.toString().slice(0,nC-B.length)}),C.on("error",(_)=>{M=String(_),N()}),C.on("close",(_)=>{H=_,N()})});let O={at:W,kind:J,label:z,command:Z.command,exitCode:H,durationMs:Date.now()-W,...U?{stdout:U}:{},...B?{stderr:B}:{},...M?{spawnError:M}:{}};try{aO0(nH(G,this.opts.homeDir),`${JSON.stringify(O)}
882
+ `}function A5($,Z){process.stderr.write(nO0($,Z))}function pC($=(Z)=>process.stderr.write(Z)){if(cx||dx)return;cx=(Z)=>$(C50("unhandledRejection",Z)),dx=(Z)=>$(C50("uncaughtException",Z)),process.on("unhandledRejection",cx),process.on("uncaughtException",dx)}var cx,dx;function A50($,Z){switch($){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return Z?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}function VM($){if(!$)return;let{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}=$;return{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}}class lx{tasks;agentState=new Map;now;constructor($=Date.now){this.now=$}contextFor($){return VM(this.tasks?.get($))}reduce($){switch($.channel){case"task.snapshot":return this.reduceTasks($.payload.tasks);case"task.jobs":return this.reduceJobs($.payload);case"engine-state":return this.reduceEngine($.payload);default:return[]}}reduceTasks($){let Z=new Map($.map((G)=>[G.id,G])),J=this.tasks;if(this.tasks=Z,!J)return[];let X=this.now(),z=[];for(let[G,W]of Z)if(!J.has(G))z.push({event:"task.created",taskId:G,task:VM(W),at:X});for(let[G,W]of J)if(!Z.has(G))z.push({event:"task.deleted",taskId:G,task:VM(W),at:X});return z}reduceJobs($){if($.kind!=="ensureWorktree"||$.phase!=="done")return[];return[{event:"worktree.created",taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}reduceEngine($){let Z=`${$.taskId}\x00${$.tabId??""}`,J=this.agentState.get(Z);if(this.agentState.set(Z,$.state),J===$.state)return[];let X=iO0[$.state];if(!X)return[];return[{event:X,taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),...$.tabId?{tabId:$.tabId}:{},at:this.now()}]}}var iO0;var P50=l(()=>{iO0={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"}});import{spawn as oO0}from"child_process";import{appendFileSync as aO0,mkdirSync as px,watch as rO0}from"fs";import{dirname as R50}from"path";function tO0($,Z){let J=new S50(Z);return $.onPublish((X)=>J.handleChannel(X)),J.start(),J}function T50($,Z,J,X){if(!Z.plugins)return null;return tO0($,{homeDir:Z.homeDir,socketPath:J,binPath:Z.plugins.binPath,log:X})}class S50{opts;reducer=new lx;plugins=[];watcher;reloadTimer;stopped=!1;constructor($){this.opts=$}start(){this.plugins=this.loadPlugins();for(let $ of this.plugins)for(let[Z,J]of $.manifest.startup.entries()){if(!FZ(J,$.manifest,vJ()))continue;this.run($,J,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${Z}]`)}this.watchRegistry()}stop(){if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);this.watcher?.close()}handleChannel($){if(this.stopped)return;for(let Z of this.reducer.reduce($))this.dispatch(Z)}handleUiReport($){if(this.stopped)return;this.dispatch({event:$.kind,...$.taskId?{taskId:$.taskId,task:this.reducer.contextFor($.taskId)}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}handleEngineReport($){if(this.stopped)return;let Z=A50($.kind,$.detail);if(!Z)return;this.dispatch({event:Z,taskId:$.taskId,task:this.reducer.contextFor($.taskId),...$.vendor?{vendor:$.vendor}:{},...$.tabId?{tabId:$.tabId}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}dispatch($){let Z=vJ();for(let J of this.plugins)for(let X of J.manifest.events){if(X.on!==$.event)continue;if(!FZ(X,J.manifest,Z))continue;this.run(J,X,"event",{ROVE_PLUGIN_EVENT:$.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify($),...$.taskId?{ROVE_PLUGIN_TASK_ID:$.taskId}:{},...$.task?.title?{ROVE_PLUGIN_TASK_TITLE:$.task.title}:{}},X.on)}}loadPlugins(){let $=V5(this.opts.homeDir),Z=vJ(),J=[];for(let X of $.plugins){if(!X.enabled)continue;let z;try{z=KZ(X.root).manifest}catch(G){this.opts.log?.(`plugin ${X.id}: manifest unreadable, skipping \u2014 ${String(G)}`);continue}if(!FZ({},z,Z))continue;J.push({manifest:z,root:X.root})}return J}watchRegistry(){let $=sK(this.opts.homeDir);try{px(R50($),{recursive:!0}),this.watcher=rO0(R50($),(Z,J)=>{if(J&&J!=="plugins.json")return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`)},sO0)})}catch(Z){this.opts.log?.(`plugin registry watch failed \u2014 ${String(Z)}`)}}async run($,Z,J,X,z){let G=$.manifest.id,W=Date.now();px(j3(G,this.opts.homeDir),{recursive:!0}),px(fQ(G,this.opts.homeDir),{recursive:!0});let H=null,U="",B="",M;await new Promise((N)=>{let[j,...P]=Z.command,C=oO0(j,P,{cwd:$.root,env:qU({homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,pluginId:$.manifest.id,pluginRoot:$.root,extra:X}),stdio:["ignore","pipe","pipe"]});C.stdout.on("data",(_)=>{if(U.length<nC)U+=_.toString().slice(0,nC-U.length)}),C.stderr.on("data",(_)=>{if(B.length<nC)B+=_.toString().slice(0,nC-B.length)}),C.on("error",(_)=>{M=String(_),N()}),C.on("close",(_)=>{H=_,N()})});let O={at:W,kind:J,label:z,command:Z.command,exitCode:H,durationMs:Date.now()-W,...U?{stdout:U}:{},...B?{stderr:B}:{},...M?{spawnError:M}:{}};try{aO0(nH(G,this.opts.homeDir),`${JSON.stringify(O)}
883
883
  `)}catch{}if(M||H!==null&&H!==0)this.opts.log?.(`plugin ${G} ${z}: ${M??`exit ${H}`}`)}}var nC=8192,sO0=150;var I50=l(()=>{WC();P50();xQ();MZ();mJ()});async function E50($,Z,J,X,z){let G=$.getTask(J);if(!G?.worktreePath)return;let W=X??G.vendor??Z.defaultTaskVendor,H=Z.createEngineTurnDetector(W);if(!H?.supportsCompletionMarkers()){let O=await Z.latestTranscriptMtime(W,G.worktreePath);return O>0?{mtimeMs:O}:{}}let U=z?await H.latestActivityInFile(z):null,{marker:B,mtimeMs:M}=U??await H.latestActivity(G.worktreePath);return{...M>0?{mtimeMs:M}:{},...B?{completedAt:B.timestampMs}:{}}}function w50($,Z,J){switch(Z){case"session-start":case"session-end":case"turn-interrupted":return"idle";case"turn-start":return"running";case"turn-complete":return $==="running"||$==="permission_needed"||$===void 0?"turn_complete":$;case"turn-failed":return J?.failure==="rate_limit"||J?.failure==="billing"?"rate_limited":"error";case"awaiting-input":return"permission_needed";default:return $??"idle"}}function ix(){let $=process.env.KOBE_ENGINE_STATE_TTL_MS;if($===void 0)return nx;let Z=Number($);return Number.isFinite(Z)&&Z>0?Z:nx}var nx=600000,_M;var iC=l(()=>{_M=new Set(["turn_complete","permission_needed","error","rate_limited"])});function x50($){return{state:$.state,at:$.at,source:"hook",...$.detail?{detail:$.detail}:{},...$.vendor?{vendor:$.vendor}:{},...$.session?{session:$.session}:{}}}function f50($,Z){return{state:$.state,at:$.at,source:"observed",...$.vendor??Z?.vendor?{vendor:$.vendor??Z?.vendor}:{},...$.session??Z?.session?{session:$.session??Z?.session}:{}}}function ox($,Z,J=Number.POSITIVE_INFINITY){let{hook:X,observed:z}=$;if(X){if(_M.has(X.state))return x50(X);if(X.state==="running"&&z?.state==="idle"&&z.at>=X.at&&Z-X.at>=J)return f50(z,X);return x50(X)}if(z)return f50(z);return}var ax=l(()=>{iC()});class rx{bus;staleMs;now;livenessAt;activity=new Map;tabActivity=new Map;constructor($,Z=ix(),J=()=>Date.now(),X=()=>Promise.resolve(void 0)){this.bus=$;this.staleMs=Z;this.now=J;this.livenessAt=X}report($,Z,J,X,z,G){let W=this.activity.get($);if(W?.lapse)clearTimeout(W.lapse);let H=w50(W?.state,Z,J),U=this.now(),B={state:H,detail:J,at:U,session:z??W?.session,vendor:G??W?.vendor};if(H!=="idle"&&!_M.has(H))B.lapse=this.armLapse($,U);this.activity.set($,B);let M=B;if(X){let O=this.tabActivity.get($)??new Map,N=O.get(X);if(N?.hook?.lapse)clearTimeout(N.hook.lapse);let j=z??N?.hook?.session,P=G??N?.hook?.vendor;if(M={state:H,detail:J,at:U,session:j},H==="idle")O.delete(X);else{let C={state:H,detail:J,at:U,session:j,vendor:P};if(!_M.has(H))C.lapse=this.armTabLapse($,X,U);O.set(X,{hook:C,effective:{state:H,at:U,source:"hook",...J?{detail:J}:{},...P?{vendor:P}:{},...j?{session:j}:{}}})}if(O.size>0)this.tabActivity.set($,O);else this.tabActivity.delete($)}this.bus.publish("engine-state",this.payload($,M,X))}async probe($,Z,J){try{return await this.livenessAt($,Z,J)}catch{return}}stillWorking($,Z){if(!$)return!1;if($.completedAt!==void 0&&$.completedAt>=Z)return!1;return $.mtimeMs!==void 0&&$.mtimeMs>this.now()-this.staleMs}armLapse($,Z){let J=setTimeout(()=>{this.handleLapse($,Z)},this.staleMs);return J.unref?.(),J}armTabLapse($,Z,J){let X=setTimeout(()=>{this.handleTabLapse($,Z,J)},this.staleMs);return X.unref?.(),X}async handleTabLapse($,Z,J){let X=this.tabActivity.get($)?.get(Z)?.hook;if(!X||X.at!==J)return;let z=await this.probe($,X.vendor,X.session?.transcriptPath),G=this.tabActivity.get($),W=G?.get(Z)?.hook;if(!G||!W||W.at!==J)return;if(this.stillWorking(z,J)){W.lapse=this.armTabLapse($,Z,J);return}if(G.delete(Z),G.size===0)this.tabActivity.delete($);this.bus.publish("engine-state",{taskId:$,tabId:Z,state:"idle",at:this.now()})}async handleLapse($,Z){let J=this.activity.get($);if(!J||J.at!==Z)return;let X=await this.probe($,J.vendor,J.session?.transcriptPath),z=this.activity.get($);if(!z||z.at!==Z)return;if(this.stillWorking(X,Z)){z.lapse=this.armLapse($,Z);return}this.publishIdle($)}observeTab($,Z,J,X={}){let z=this.tabActivity.get($)??new Map,G=z.get(Z),W=G?.effective,H={state:J==="working"?"running":"idle",at:this.now(),vendor:X.vendor??G?.observed?.vendor??G?.hook?.vendor,session:G?.observed?.session??G?.hook?.session},U=ox({hook:G?.hook,observed:H},H.at,X.correctHookRunningAfterMs??Number.POSITIVE_INFINITY);if(!U)return"noop";let B=U.source==="observed"?void 0:G?.hook;if(G&&B===G.hook&&W&&W.state===U.state&&W.source===U.source)return G.observed=H,"noop";if(B===void 0&&G?.hook?.lapse)clearTimeout(G.hook.lapse);if(z.set(Z,{...B?{hook:B}:{},observed:H,effective:U}),this.tabActivity.set($,z),this.bus.publish("engine-state",this.payload($,U,Z)),U.source==="hook")return"noop";if(U.state==="running")return"observed-running";return W?.source==="hook"?"corrected-hook-running":"observed-idle"}clearTask($){let Z=this.activity.get($);if(Z?.lapse)clearTimeout(Z.lapse);this.activity.delete($);let J=this.tabActivity.get($);if(this.tabActivity.delete($),J)for(let[X,z]of J){if(z.hook?.lapse)clearTimeout(z.hook.lapse);this.bus.publish("engine-state",{taskId:$,tabId:X,state:"idle",at:this.now()})}if(Z)this.bus.publish("engine-state",{taskId:$,state:"idle",at:this.now()})}snapshotByTask(){let $={};for(let[Z,J]of this.activity)$[Z]=this.payload(Z,J);return $}currentNonIdle(){let $=[];for(let[Z,J]of this.activity)if(J.state!=="idle")$.push(this.payload(Z,J));for(let[Z,J]of this.tabActivity)for(let[X,z]of J)$.push(this.payload(Z,z.effective,X));return $}debugSnapshot(){let $=(z)=>({state:z.state,at:z.at,...z.vendor?{vendor:z.vendor}:{},lapseArmed:z.lapse!==void 0}),Z=(z)=>({state:z.effective.state,at:z.effective.at,...z.effective.vendor?{vendor:z.effective.vendor}:{},...z.effective.source==="observed"?{observed:!0}:{},lapseArmed:z.hook?.lapse!==void 0,source:z.effective.source}),J={};for(let[z,G]of this.activity)J[z]=$(G);let X={};for(let[z,G]of this.tabActivity){let W={};for(let[H,U]of G)W[H]=Z(U);X[z]=W}return{tasks:J,tabs:X}}close(){for(let $ of this.activity.values())if($.lapse)clearTimeout($.lapse);for(let $ of this.tabActivity.values())for(let Z of $.values())if(Z.hook?.lapse)clearTimeout(Z.hook.lapse);this.activity.clear(),this.tabActivity.clear()}publishIdle($){let Z={state:"idle",at:this.now()};this.activity.set($,Z),this.bus.publish("engine-state",this.payload($,Z))}payload($,Z,J){return{taskId:$,...J?{tabId:J}:{},state:Z.state,...Z.detail?{detail:Z.detail}:{},...Z.session?{sessionId:Z.session.id}:{},...Z.session?.transcriptPath?{transcriptPath:Z.session.transcriptPath}:{},at:Z.at}}}var y50=l(()=>{ax();iC();iC();ax()});import{randomUUID as eO0}from"crypto";import{mkdir as $j0,readFile as Zj0,rename as Jj0,writeFile as Xj0}from"fs/promises";import{homedir as Qj0}from"os";import{dirname as zj0,join as Yj0}from"path";function v50($=L$("HOME_DIR")??Qj0()){return Yj0($,X2,"agent-turns.json")}function g50($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.id!=="string"||Z.id.length===0)return null;if(typeof Z.taskId!=="string"||Z.taskId.length===0)return null;if(typeof Z.startedAt!=="number"||!Number.isFinite(Z.startedAt))return null;if(typeof Z.endedAt!=="number"||!Number.isFinite(Z.endedAt))return null;return{id:Z.id,taskId:Z.taskId,...typeof Z.tabId==="string"&&Z.tabId?{tabId:Z.tabId}:{},...typeof Z.vendor==="string"&&Z.vendor?{vendor:Z.vendor}:{},...typeof Z.sessionId==="string"&&Z.sessionId?{sessionId:Z.sessionId}:{},...typeof Z.model==="string"&&Z.model?{model:Z.model}:{},...typeof Z.repo==="string"&&Z.repo?{repo:Z.repo}:{},startedAt:Z.startedAt,endedAt:Z.endedAt,...Z.usage&&typeof Z.usage==="object"?{usage:Z.usage}:{}}}function b50($){return`${$.taskId}\x00${$.id}`}class sx{path;turns=new Map;tail=Promise.resolve();constructor($){this.path=$}async init(){await this.enqueue(async()=>{this.turns.clear();for(let $ of await this.read())this.turns.set(b50($),$)})}async record($){return await this.enqueue(async()=>{let Z=0;for(let J of $){let X=g50(J);if(!X)continue;let z=b50(X);if(!this.turns.has(z))Z++;this.turns.delete(z),this.turns.set(z,X)}if(Z===0)return 0;while(this.turns.size>Gj0){let J=this.turns.keys().next().value;if(J===void 0)break;this.turns.delete(J)}return await this.write(),Z})}list($={}){let Z=$.limit&&$.limit>0?$.limit:200,J=[];for(let X of this.turns.values()){if($.taskId&&X.taskId!==$.taskId)continue;if($.repo&&X.repo!==$.repo)continue;if($.since!==void 0&&X.endedAt<$.since)continue;J.push(X)}return J.sort((X,z)=>z.endedAt-X.endedAt),J.slice(0,Z)}async deleteTask($){await this.enqueue(async()=>{let Z=!1;for(let[J,X]of this.turns){if(X.taskId!==$)continue;this.turns.delete(J),Z=!0}if(Z)await this.write()})}async read(){try{let $=JSON.parse(await Zj0(this.path,"utf8"));if(!Array.isArray($.turns))return[];return $.turns.map(g50).filter((Z)=>Z!==null)}catch($){if($.code==="ENOENT")return[];return d1("agent-turns-load",$),[]}}async write(){let $={version:1,turns:[...this.turns.values()]},Z=`${this.path}.tmp-${process.pid}-${eO0()}`;try{await $j0(zj0(this.path),{recursive:!0}),await Xj0(Z,`${JSON.stringify($)}
884
884
  `,"utf8"),await Jj0(Z,this.path)}catch(J){d1("agent-turns-write",J)}}enqueue($){let Z=this.tail.then($,$);return this.tail=Z.then(()=>{return},()=>{return}),Z}}var Gj0=1e4;var k50=()=>{};import{randomUUID as Wj0}from"crypto";import{mkdir as Hj0,readFile as qj0,rename as Uj0,writeFile as Bj0}from"fs/promises";import{homedir as Kj0}from"os";import{dirname as Fj0,join as Mj0}from"path";function h50($=L$("HOME_DIR")??Kj0()){return Mj0($,X2,"attention-inbox.json")}function Nj0($,Z){if($==="turn-complete")return"turn_complete";if($==="awaiting-input")return"permission_needed";if($!=="turn-failed")return null;return Z?.failure==="rate_limit"?"rate_limited":"error"}function Lj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.taskId!=="string"||Z.taskId.length===0)return null;if(Z.tabId!==null&&typeof Z.tabId!=="string")return null;if(!mK(Z.state))return null;if(typeof Z.at!=="number"||!Number.isFinite(Z.at))return null;return{taskId:Z.taskId,tabId:Z.tabId,state:Z.state,...Z.detail?{detail:Z.detail}:{},unread:Z.unread!==!1,at:Z.at}}async function Oj0($){try{let Z=JSON.parse(await qj0($,"utf8"));if(!Array.isArray(Z.items))return[];return Z.items.map(Lj0).filter((J)=>J!==null)}catch(Z){if(Z.code==="ENOENT")return[];return d1("attention-inbox-load",Z),[]}}async function jj0($,Z){await Hj0(Fj0($),{recursive:!0});let J=`${$}.tmp-${process.pid}-${Wj0()}`,X={version:1,items:[...Z]};await Bj0(J,`${JSON.stringify(X,null,2)}
885
885
  `,"utf8"),await Uj0(J,$)}class tx{path;bus;now;items=new Map;tail=Promise.resolve();constructor($,Z,J=()=>Date.now()){this.path=$;this.bus=Z;this.now=J}async init(){await this.enqueue(async()=>{this.items.clear();for(let $ of await Oj0(this.path))this.items.set(L3($),$);this.publish()})}snapshot(){return[...this.items.values()].sort(m50)}async record($,Z,J,X){let z=X===null||X.length===0?null:X;await this.enqueue(async()=>{let G=L3({taskId:$,tabId:z}),W=new Map(this.items);if(Z==="turn-start"){if(!W.delete(G))return}else{let H=Nj0(Z,J);if(!H)return;W.delete(G),W.set(G,{taskId:$,tabId:z,state:H,...J?{detail:J}:{},unread:!0,at:this.now()})}await this.commit(W)})}async markRead($,Z,J){return await this.deleteEpisode($,Z,J)}async deleteEpisode($,Z,J){return await this.enqueue(async()=>{let X=L3({taskId:$,tabId:Z}),z=this.items.get(X);if(!z||J!==void 0&&z.at!==J)return!1;let G=new Map(this.items);return G.delete(X),await this.commit(G),!0})}async deleteTask($){await this.enqueue(async()=>{let Z=new Map(this.items),J=!1;for(let[X,z]of Z){if(z.taskId!==$)continue;Z.delete(X),J=!0}if(J)await this.commit(Z)})}async deleteTaskBestEffort($){await this.deleteTask($).catch((Z)=>d1("attention-inbox-task-delete",Z))}enqueue($){let Z=this.tail.then($);return this.tail=Z.then(()=>{return},()=>{return}),Z}async commit($){let Z=[...$.values()].sort(m50);await jj0(this.path,Z),this.items.clear();for(let J of Z)this.items.set(L3(J),J);this.bus.publish("attention.inbox",{items:Z})}publish(){this.bus.publish("attention.inbox",{items:this.snapshot()})}}function m50($,Z){return $.at-Z.at||$.taskId.localeCompare(Z.taskId)||($.tabId??"").localeCompare(Z.tabId??"")}var u50=l(()=>{WP()});import{randomUUID as ex}from"crypto";import{mkdir as Vj0,readFile as _j0,rename as Cj0,writeFile as Dj0}from"fs/promises";import{homedir as Aj0}from"os";import{dirname as Pj0,join as Rj0}from"path";function d50($=L$("HOME_DIR")??Aj0()){return Rj0($,X2,"automations.json")}function F7($){return typeof $==="string"&&$.length>0?$:void 0}function Tj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$,J=F7(Z.id),X=F7(Z.name),z=F7(Z.repo),G=F7(Z.prompt),W=F7(Z.schedule),H=F7(Z.nextRunAt);if(!J||!X||!z||!G||!W||!H)return null;if(!Number.isFinite(Date.parse(H)))return null;let U=F7(Z.precheck?.command),B=Z.missedRunGraceMinutes,M=new Date().toISOString();return{id:J,name:X,repo:z,prompt:G,schedule:W,nextRunAt:H,enabled:Z.enabled!==!1,missedRunGraceMinutes:typeof B==="number"&&Number.isFinite(B)&&B>=0?B:60,...Z.vendor?{vendor:Z.vendor}:{},...U?{precheck:{command:U,timeoutSeconds:typeof Z.precheck?.timeoutSeconds==="number"&&Z.precheck.timeoutSeconds>0?Z.precheck.timeoutSeconds:120}}:{},...F7(Z.baseRef)?{baseRef:Z.baseRef}:{},...F7(Z.lastRunAt)?{lastRunAt:Z.lastRunAt}:{},createdAt:F7(Z.createdAt)??M,updatedAt:F7(Z.updatedAt)??M}}function Sj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$,J=F7(Z.id),X=F7(Z.automationId),z=F7(Z.scheduledFor),G=F7(Z.at);if(!J||!X||!z||!G)return null;if(Z.status!=="dispatched"&&Z.status!=="skipped_precheck"&&Z.status!=="skipped_missed"&&Z.status!=="skipped_unavailable"&&Z.status!=="dispatch_failed")return null;return{id:J,automationId:X,runNumber:typeof Z.runNumber==="number"&&Z.runNumber>0?Z.runNumber:1,scheduledFor:z,status:Z.status,trigger:Z.trigger==="manual"?"manual":"scheduled",...F7(Z.taskId)?{taskId:Z.taskId}:{},...Z.precheckResult?{precheckResult:Z.precheckResult}:{},...F7(Z.error)?{error:Z.error}:{},at:G}}async function Ij0($){try{let Z=JSON.parse(await _j0($,"utf8")),J=Array.isArray(Z.automations)?Z.automations.map(Tj0).filter((z)=>z!==null):[],X=Array.isArray(Z.runs)?Z.runs.map(Sj0).filter((z)=>z!==null):[];return{automations:J,runs:X}}catch(Z){if(Z.code==="ENOENT")return{automations:[],runs:[]};return d1("automations-load",Z),{automations:[],runs:[]}}}async function Ej0($,Z,J){await Vj0(Pj0($),{recursive:!0});let X=`${$}.tmp-${process.pid}-${ex()}`,z={version:1,automations:[...Z],runs:[...J]};await Dj0(X,`${JSON.stringify(z,null,2)}
@@ -303,7 +303,7 @@ ${G}
303
303
  `)}let z=PY0();for(let G of TT()){if(X&&G.vendor==="claude")continue;let W=G.globalSettingsPath();if(!W)continue;await G.installActivityHooks(W,{toolEvents:z}),await G.installWorktreeWatchHook(W)}await tm()}catch{}}function PY0(){try{for(let $ of V5().plugins){if(!$.enabled)continue;try{if(KZ($.root).manifest.events.some((Z)=>Z.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function tm(){let $=DY0();if($.length===0)return;let Z=x5(lm),J=new Set([sm()]),X=AY0(Z);if(X)J.add(X);for(let z of $)for(let G of J)await z.removeWorktreeSyncHook(G);if(Z!=="off")X6(lm,"off")}async function RY0(){let $=TT().find((J)=>J.vendor==="claude"),Z=$?.globalSettingsPath();if(!$||!Z){process.stdout.write(`rove hook cleanup: no Claude hook adapter \u2014 nothing to do.
304
304
  `);return}await $.removeActivityHooks(Z),await $.removeWorktreeWatchHook(Z),process.stdout.write([`rove hook cleanup: removed Rove's settings-managed hooks from ${Z}.`,"Only Rove's own entries were touched; your other hooks are intact.","The Claude Code plugin's hooks.json now carries these events (if the plugin","is not installed, the next Rove launch reinstalls the settings-managed set).",""].join(`
305
305
  `))}async function TY0($){await tm(),process.stdout.write(["rove hook setup is deprecated and now a no-op (cleanup only).","","The old external-worktree sync used a global WorktreeCreate hook, which is","a VCS provider hook \u2014 its presence broke `claude --worktree` / EnterWorktree","in every repo. Any hook Rove previously installed has been removed.","","Sync is now automatic: a `claude --worktree` (or any session) started in a","worktree under a repo Rove already tracks is adopted as a task on launch.","To adopt existing worktrees on demand, use the New Task dialog or `rove adopt`.",""].join(`
306
- `))}var OY0=500,jY0="worktree-created",lm="externalWorktreeSync";var IT=l(()=>{T7();xQ();mJ();DT();PT();C4();D2();b4()});var Vj;var $h=l(()=>{Vj={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.142",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"},"//":"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.14","@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 Jh={};P$(Jh,{repoSlug:()=>yY,releasePageUrl:()=>gT,recommendedGlobalInstallCommand:()=>xT,isNewerSemver:()=>ET,fetchReleaseSummaries:()=>YF,fetchReleaseNotesRange:()=>yT,fetchReleaseNotes:()=>fT,compareSemver:()=>V3,checkLatestVersion:()=>gY,breakingVersionsCrossed:()=>zF,UPDATE_SCRIPT_URL:()=>_j,UPDATE_COMMAND:()=>jZ,PACKAGE_NAME:()=>wT,CURRENT_VERSION:()=>R$,BREAKING_VERSIONS:()=>dJ});function yY(){let $=Vj.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function xT(){return`npm install -g ${wT}@latest`}function zF($,Z,J=dJ){let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}async function IY0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),Cj);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:Z.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(J)}}function ET($,Z){return V3($,Z)>0}function V3($,Z){let J=(G)=>G.split("-")[0]??G,X=J($).split(".").map((G)=>Number.parseInt(G,10)),z=J(Z).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,H=z[G]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function gY($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:R$,latest:Z,hasUpdate:ET(Z,R$)};if(RH()&&!$.force)return null;let J=await IY0(wT);if(!J)return null;return{current:R$,latest:J,hasUpdate:ET(J,R$)}}function Zh($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fT($){let Z=yY();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases/tags/${J}`,{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 yT($){let Z=yY();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${J}`,{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((H)=>{let U=Zh(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(V3(U,$.current)<=0)return null;if(V3(U,$.latest)>0)return null;return{version:U,url:H.html_url,body:H.body}}).filter((H)=>H!==null)}catch{return[]}finally{clearTimeout(z)}}async function YF($=12){let Z=yY();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),Cj);try{let z=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${$}`,{signal:J.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 H=Zh(W.tag_name);if(!H||typeof W.html_url!=="string")return null;return{version:H,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function gT($){let Z=yY();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var R$,wT,_j="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",jZ,dJ,Cj=3000;var d8=l(()=>{$h();j5();R$=Vj.version,wT=Vj.name;jZ=`curl -fsSL ${_j} | sh`;dJ=[]});var Qh={};P$(Qh,{stampResetGate:()=>Dj,resetGateBlockers:()=>Xh,enforceResetGate:()=>vT,LAST_RUN_VERSION_KEY:()=>bT});function Xh($,Z=R$,J=dJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}function vT(){let $=$$(),Z=N4()[bT],J=Xh(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${R$}: cannot start \u2014 version ${J.join(", ")} introduced breaking changes`,`(last run: ${X}). Your daemon/session state may be incompatible.`,"","Run:",` ${$} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${$} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
306
+ `))}var OY0=500,jY0="worktree-created",lm="externalWorktreeSync";var IT=l(()=>{T7();xQ();mJ();DT();PT();C4();D2();b4()});var Vj;var $h=l(()=>{Vj={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.143",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"},"//":"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.14","@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 Jh={};P$(Jh,{repoSlug:()=>yY,releasePageUrl:()=>gT,recommendedGlobalInstallCommand:()=>xT,isNewerSemver:()=>ET,fetchReleaseSummaries:()=>YF,fetchReleaseNotesRange:()=>yT,fetchReleaseNotes:()=>fT,compareSemver:()=>V3,checkLatestVersion:()=>gY,breakingVersionsCrossed:()=>zF,UPDATE_SCRIPT_URL:()=>_j,UPDATE_COMMAND:()=>jZ,PACKAGE_NAME:()=>wT,CURRENT_VERSION:()=>R$,BREAKING_VERSIONS:()=>dJ});function yY(){let $=Vj.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function xT(){return`npm install -g ${wT}@latest`}function zF($,Z,J=dJ){let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}async function IY0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),Cj);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:Z.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(J)}}function ET($,Z){return V3($,Z)>0}function V3($,Z){let J=(G)=>G.split("-")[0]??G,X=J($).split(".").map((G)=>Number.parseInt(G,10)),z=J(Z).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,H=z[G]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function gY($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:R$,latest:Z,hasUpdate:ET(Z,R$)};if(RH()&&!$.force)return null;let J=await IY0(wT);if(!J)return null;return{current:R$,latest:J,hasUpdate:ET(J,R$)}}function Zh($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fT($){let Z=yY();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases/tags/${J}`,{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 yT($){let Z=yY();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${J}`,{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((H)=>{let U=Zh(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(V3(U,$.current)<=0)return null;if(V3(U,$.latest)>0)return null;return{version:U,url:H.html_url,body:H.body}}).filter((H)=>H!==null)}catch{return[]}finally{clearTimeout(z)}}async function YF($=12){let Z=yY();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),Cj);try{let z=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${$}`,{signal:J.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 H=Zh(W.tag_name);if(!H||typeof W.html_url!=="string")return null;return{version:H,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function gT($){let Z=yY();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var R$,wT,_j="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",jZ,dJ,Cj=3000;var d8=l(()=>{$h();j5();R$=Vj.version,wT=Vj.name;jZ=`curl -fsSL ${_j} | sh`;dJ=[]});var Qh={};P$(Qh,{stampResetGate:()=>Dj,resetGateBlockers:()=>Xh,enforceResetGate:()=>vT,LAST_RUN_VERSION_KEY:()=>bT});function Xh($,Z=R$,J=dJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}function vT(){let $=$$(),Z=N4()[bT],J=Xh(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${R$}: cannot start \u2014 version ${J.join(", ")} introduced breaking changes`,`(last run: ${X}). Your daemon/session state may be incompatible.`,"","Run:",` ${$} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${$} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
307
307
  `)),process.exit(1)}if(Z!==R$)Dj()}function Dj(){try{S7({[bT]:R$})}catch{}}var bT="app.lastRunVersion";var Aj=l(()=>{I7();d8();b4()});import{existsSync as Yh,readFileSync as EY0}from"fs";import{homedir as wY0}from"os";import{join as Gh,resolve as zh}from"path";import{fileURLToPath as xY0}from"url";function hT($=process.env){return`${$$($)} skill install`}function Pj(){let $=xY0(import.meta.url);return[zh($,"../../../../../.agents/skills/kobe"),zh($,"../../skills/rove")].find((J)=>Yh(Gh(J,"SKILL.md")))??null}function Rj($={}){let Z=$.source!==void 0?$.source:Pj(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??yY0,"--skill",e3,...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function bY($={}){return`npx ${Rj($).join(" ")}`}async function uT($,Z){return await Bun.spawn(["npx",...Rj({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function Tj($={}){let Z=$.home??wY0(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>fY0.map((z)=>Gh(X,z)))}function gY0($){let Z=$.match(/(?:rove|kobe)-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function GF($){let Z=Tj($).find((z)=>Yh(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:kT,stale:!1};let J=null;try{J=gY0(EY0(Z,"utf8"))}catch{J=null}let X=J===null||J<kT;return{installed:!0,installedVersion:J,currentVersion:kT,stale:X}}function bY0(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function Wh($={}){let{isRovePluginEnabled:Z}=await Promise.resolve().then(() => (jj(),Oj));if(Z())return;let J=$$(),X=hT(),z=GF();if(!z.installed){if(x5(mT)==="1")return;X6(mT,"1"),process.stderr.write(`
308
308
  ${J}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${J} api\`:
309
309
  ${X}
@@ -879,7 +879,7 @@ ${V50}
879
879
  `)});function P50($){if($ instanceof Error)return $;let Z;try{Z=typeof $==="string"?$:JSON.stringify($)}catch{Z=String($)}return Error(Z)}function A50($,Z,J=new Date){let X=P50(Z);return`[${J.toISOString()}] daemon ${$}: ${X.stack??`${X.name}: ${X.message}`}
880
880
  `}function oO0($,Z,J=new Date){let X=P50(Z);return`[${J.toISOString()}] daemon error [${$}]: ${X.stack??`${X.name}: ${X.message}`}
881
881
  `}function d1($,Z){process.stderr.write(oO0($,Z))}function aO0($,Z,J=new Date){return`[${J.toISOString()}] daemon [${$}]: ${Z}
882
- `}function A5($,Z){process.stderr.write(aO0($,Z))}function nC($=(Z)=>process.stderr.write(Z)){if(dx||lx)return;dx=(Z)=>$(A50("unhandledRejection",Z)),lx=(Z)=>$(A50("uncaughtException",Z)),process.on("unhandledRejection",dx),process.on("uncaughtException",lx)}var dx,lx;function R50($,Z){switch($){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return Z?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}function VM($){if(!$)return;let{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}=$;return{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}}class px{tasks;agentState=new Map;now;constructor($=Date.now){this.now=$}contextFor($){return VM(this.tasks?.get($))}reduce($){switch($.channel){case"task.snapshot":return this.reduceTasks($.payload.tasks);case"task.jobs":return this.reduceJobs($.payload);case"engine-state":return this.reduceEngine($.payload);default:return[]}}reduceTasks($){let Z=new Map($.map((G)=>[G.id,G])),J=this.tasks;if(this.tasks=Z,!J)return[];let X=this.now(),z=[];for(let[G,W]of Z)if(!J.has(G))z.push({event:"task.created",taskId:G,task:VM(W),at:X});for(let[G,W]of J)if(!Z.has(G))z.push({event:"task.deleted",taskId:G,task:VM(W),at:X});return z}reduceJobs($){if($.kind!=="ensureWorktree"||$.phase!=="done")return[];return[{event:"worktree.created",taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}reduceEngine($){let Z=`${$.taskId}\x00${$.tabId??""}`,J=this.agentState.get(Z);if(this.agentState.set(Z,$.state),J===$.state)return[];let X=rO0[$.state];if(!X)return[];return[{event:X,taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}}var rO0;var T50=l(()=>{rO0={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"}});import{spawn as sO0}from"child_process";import{appendFileSync as tO0,mkdirSync as nx,watch as eO0}from"fs";import{dirname as S50}from"path";function Zj0($,Z){let J=new E50(Z);return $.onPublish((X)=>J.handleChannel(X)),J.start(),J}function I50($,Z,J,X){if(!Z.plugins)return null;return Zj0($,{homeDir:Z.homeDir,socketPath:J,binPath:Z.plugins.binPath,log:X})}class E50{opts;reducer=new px;plugins=[];watcher;reloadTimer;stopped=!1;constructor($){this.opts=$}start(){this.plugins=this.loadPlugins();for(let $ of this.plugins)for(let[Z,J]of $.manifest.startup.entries()){if(!FZ(J,$.manifest,vJ()))continue;this.run($,J,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${Z}]`)}this.watchRegistry()}stop(){if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);this.watcher?.close()}handleChannel($){if(this.stopped)return;for(let Z of this.reducer.reduce($))this.dispatch(Z)}handleUiReport($){if(this.stopped)return;this.dispatch({event:$.kind,...$.taskId?{taskId:$.taskId,task:this.reducer.contextFor($.taskId)}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}handleEngineReport($){if(this.stopped)return;let Z=R50($.kind,$.detail);if(!Z)return;this.dispatch({event:Z,taskId:$.taskId,task:this.reducer.contextFor($.taskId),...$.vendor?{vendor:$.vendor}:{},...$.tabId?{tabId:$.tabId}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}dispatch($){let Z=vJ();for(let J of this.plugins)for(let X of J.manifest.events){if(X.on!==$.event)continue;if(!FZ(X,J.manifest,Z))continue;this.run(J,X,"event",{ROVE_PLUGIN_EVENT:$.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify($),...$.taskId?{ROVE_PLUGIN_TASK_ID:$.taskId}:{},...$.task?.title?{ROVE_PLUGIN_TASK_TITLE:$.task.title}:{}},X.on)}}loadPlugins(){let $=V5(this.opts.homeDir),Z=vJ(),J=[];for(let X of $.plugins){if(!X.enabled)continue;let z;try{z=KZ(X.root).manifest}catch(G){this.opts.log?.(`plugin ${X.id}: manifest unreadable, skipping \u2014 ${String(G)}`);continue}if(!FZ({},z,Z))continue;J.push({manifest:z,root:X.root})}return J}watchRegistry(){let $=sK(this.opts.homeDir);try{nx(S50($),{recursive:!0}),this.watcher=eO0(S50($),(Z,J)=>{if(J&&J!=="plugins.json")return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`)},$j0)})}catch(Z){this.opts.log?.(`plugin registry watch failed \u2014 ${String(Z)}`)}}async run($,Z,J,X,z){let G=$.manifest.id,W=Date.now();nx(j3(G,this.opts.homeDir),{recursive:!0}),nx(fQ(G,this.opts.homeDir),{recursive:!0});let H=null,U="",B="",M;await new Promise((N)=>{let[j,...P]=Z.command,C=sO0(j,P,{cwd:$.root,env:qU({homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,pluginId:$.manifest.id,pluginRoot:$.root,extra:X}),stdio:["ignore","pipe","pipe"]});C.stdout.on("data",(_)=>{if(U.length<iC)U+=_.toString().slice(0,iC-U.length)}),C.stderr.on("data",(_)=>{if(B.length<iC)B+=_.toString().slice(0,iC-B.length)}),C.on("error",(_)=>{M=String(_),N()}),C.on("close",(_)=>{H=_,N()})});let O={at:W,kind:J,label:z,command:Z.command,exitCode:H,durationMs:Date.now()-W,...U?{stdout:U}:{},...B?{stderr:B}:{},...M?{spawnError:M}:{}};try{tO0(nH(G,this.opts.homeDir),`${JSON.stringify(O)}
882
+ `}function A5($,Z){process.stderr.write(aO0($,Z))}function nC($=(Z)=>process.stderr.write(Z)){if(dx||lx)return;dx=(Z)=>$(A50("unhandledRejection",Z)),lx=(Z)=>$(A50("uncaughtException",Z)),process.on("unhandledRejection",dx),process.on("uncaughtException",lx)}var dx,lx;function R50($,Z){switch($){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return Z?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}function VM($){if(!$)return;let{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}=$;return{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}}class px{tasks;agentState=new Map;now;constructor($=Date.now){this.now=$}contextFor($){return VM(this.tasks?.get($))}reduce($){switch($.channel){case"task.snapshot":return this.reduceTasks($.payload.tasks);case"task.jobs":return this.reduceJobs($.payload);case"engine-state":return this.reduceEngine($.payload);default:return[]}}reduceTasks($){let Z=new Map($.map((G)=>[G.id,G])),J=this.tasks;if(this.tasks=Z,!J)return[];let X=this.now(),z=[];for(let[G,W]of Z)if(!J.has(G))z.push({event:"task.created",taskId:G,task:VM(W),at:X});for(let[G,W]of J)if(!Z.has(G))z.push({event:"task.deleted",taskId:G,task:VM(W),at:X});return z}reduceJobs($){if($.kind!=="ensureWorktree"||$.phase!=="done")return[];return[{event:"worktree.created",taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}reduceEngine($){let Z=`${$.taskId}\x00${$.tabId??""}`,J=this.agentState.get(Z);if(this.agentState.set(Z,$.state),J===$.state)return[];let X=rO0[$.state];if(!X)return[];return[{event:X,taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),...$.tabId?{tabId:$.tabId}:{},at:this.now()}]}}var rO0;var T50=l(()=>{rO0={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"}});import{spawn as sO0}from"child_process";import{appendFileSync as tO0,mkdirSync as nx,watch as eO0}from"fs";import{dirname as S50}from"path";function Zj0($,Z){let J=new E50(Z);return $.onPublish((X)=>J.handleChannel(X)),J.start(),J}function I50($,Z,J,X){if(!Z.plugins)return null;return Zj0($,{homeDir:Z.homeDir,socketPath:J,binPath:Z.plugins.binPath,log:X})}class E50{opts;reducer=new px;plugins=[];watcher;reloadTimer;stopped=!1;constructor($){this.opts=$}start(){this.plugins=this.loadPlugins();for(let $ of this.plugins)for(let[Z,J]of $.manifest.startup.entries()){if(!FZ(J,$.manifest,vJ()))continue;this.run($,J,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${Z}]`)}this.watchRegistry()}stop(){if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);this.watcher?.close()}handleChannel($){if(this.stopped)return;for(let Z of this.reducer.reduce($))this.dispatch(Z)}handleUiReport($){if(this.stopped)return;this.dispatch({event:$.kind,...$.taskId?{taskId:$.taskId,task:this.reducer.contextFor($.taskId)}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}handleEngineReport($){if(this.stopped)return;let Z=R50($.kind,$.detail);if(!Z)return;this.dispatch({event:Z,taskId:$.taskId,task:this.reducer.contextFor($.taskId),...$.vendor?{vendor:$.vendor}:{},...$.tabId?{tabId:$.tabId}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}dispatch($){let Z=vJ();for(let J of this.plugins)for(let X of J.manifest.events){if(X.on!==$.event)continue;if(!FZ(X,J.manifest,Z))continue;this.run(J,X,"event",{ROVE_PLUGIN_EVENT:$.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify($),...$.taskId?{ROVE_PLUGIN_TASK_ID:$.taskId}:{},...$.task?.title?{ROVE_PLUGIN_TASK_TITLE:$.task.title}:{}},X.on)}}loadPlugins(){let $=V5(this.opts.homeDir),Z=vJ(),J=[];for(let X of $.plugins){if(!X.enabled)continue;let z;try{z=KZ(X.root).manifest}catch(G){this.opts.log?.(`plugin ${X.id}: manifest unreadable, skipping \u2014 ${String(G)}`);continue}if(!FZ({},z,Z))continue;J.push({manifest:z,root:X.root})}return J}watchRegistry(){let $=sK(this.opts.homeDir);try{nx(S50($),{recursive:!0}),this.watcher=eO0(S50($),(Z,J)=>{if(J&&J!=="plugins.json")return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`)},$j0)})}catch(Z){this.opts.log?.(`plugin registry watch failed \u2014 ${String(Z)}`)}}async run($,Z,J,X,z){let G=$.manifest.id,W=Date.now();nx(j3(G,this.opts.homeDir),{recursive:!0}),nx(fQ(G,this.opts.homeDir),{recursive:!0});let H=null,U="",B="",M;await new Promise((N)=>{let[j,...P]=Z.command,C=sO0(j,P,{cwd:$.root,env:qU({homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,pluginId:$.manifest.id,pluginRoot:$.root,extra:X}),stdio:["ignore","pipe","pipe"]});C.stdout.on("data",(_)=>{if(U.length<iC)U+=_.toString().slice(0,iC-U.length)}),C.stderr.on("data",(_)=>{if(B.length<iC)B+=_.toString().slice(0,iC-B.length)}),C.on("error",(_)=>{M=String(_),N()}),C.on("close",(_)=>{H=_,N()})});let O={at:W,kind:J,label:z,command:Z.command,exitCode:H,durationMs:Date.now()-W,...U?{stdout:U}:{},...B?{stderr:B}:{},...M?{spawnError:M}:{}};try{tO0(nH(G,this.opts.homeDir),`${JSON.stringify(O)}
883
883
  `)}catch{}if(M||H!==null&&H!==0)this.opts.log?.(`plugin ${G} ${z}: ${M??`exit ${H}`}`)}}var iC=8192,$j0=150;var w50=l(()=>{HC();T50();xQ();MZ();mJ()});async function x50($,Z,J,X,z){let G=$.getTask(J);if(!G?.worktreePath)return;let W=X??G.vendor??Z.defaultTaskVendor,H=Z.createEngineTurnDetector(W);if(!H?.supportsCompletionMarkers()){let O=await Z.latestTranscriptMtime(W,G.worktreePath);return O>0?{mtimeMs:O}:{}}let U=z?await H.latestActivityInFile(z):null,{marker:B,mtimeMs:M}=U??await H.latestActivity(G.worktreePath);return{...M>0?{mtimeMs:M}:{},...B?{completedAt:B.timestampMs}:{}}}function f50($,Z,J){switch(Z){case"session-start":case"session-end":case"turn-interrupted":return"idle";case"turn-start":return"running";case"turn-complete":return $==="running"||$==="permission_needed"||$===void 0?"turn_complete":$;case"turn-failed":return J?.failure==="rate_limit"||J?.failure==="billing"?"rate_limited":"error";case"awaiting-input":return"permission_needed";default:return $??"idle"}}function ox(){let $=process.env.KOBE_ENGINE_STATE_TTL_MS;if($===void 0)return ix;let Z=Number($);return Number.isFinite(Z)&&Z>0?Z:ix}var ix=600000,_M;var oC=l(()=>{_M=new Set(["turn_complete","permission_needed","error","rate_limited"])});function y50($){return{state:$.state,at:$.at,source:"hook",...$.detail?{detail:$.detail}:{},...$.vendor?{vendor:$.vendor}:{},...$.session?{session:$.session}:{}}}function g50($,Z){return{state:$.state,at:$.at,source:"observed",...$.vendor??Z?.vendor?{vendor:$.vendor??Z?.vendor}:{},...$.session??Z?.session?{session:$.session??Z?.session}:{}}}function ax($,Z,J=Number.POSITIVE_INFINITY){let{hook:X,observed:z}=$;if(X){if(_M.has(X.state))return y50(X);if(X.state==="running"&&z?.state==="idle"&&z.at>=X.at&&Z-X.at>=J)return g50(z,X);return y50(X)}if(z)return g50(z);return}var rx=l(()=>{oC()});class sx{bus;staleMs;now;livenessAt;activity=new Map;tabActivity=new Map;constructor($,Z=ox(),J=()=>Date.now(),X=()=>Promise.resolve(void 0)){this.bus=$;this.staleMs=Z;this.now=J;this.livenessAt=X}report($,Z,J,X,z,G){let W=this.activity.get($);if(W?.lapse)clearTimeout(W.lapse);let H=f50(W?.state,Z,J),U=this.now(),B={state:H,detail:J,at:U,session:z??W?.session,vendor:G??W?.vendor};if(H!=="idle"&&!_M.has(H))B.lapse=this.armLapse($,U);this.activity.set($,B);let M=B;if(X){let O=this.tabActivity.get($)??new Map,N=O.get(X);if(N?.hook?.lapse)clearTimeout(N.hook.lapse);let j=z??N?.hook?.session,P=G??N?.hook?.vendor;if(M={state:H,detail:J,at:U,session:j},H==="idle")O.delete(X);else{let C={state:H,detail:J,at:U,session:j,vendor:P};if(!_M.has(H))C.lapse=this.armTabLapse($,X,U);O.set(X,{hook:C,effective:{state:H,at:U,source:"hook",...J?{detail:J}:{},...P?{vendor:P}:{},...j?{session:j}:{}}})}if(O.size>0)this.tabActivity.set($,O);else this.tabActivity.delete($)}this.bus.publish("engine-state",this.payload($,M,X))}async probe($,Z,J){try{return await this.livenessAt($,Z,J)}catch{return}}stillWorking($,Z){if(!$)return!1;if($.completedAt!==void 0&&$.completedAt>=Z)return!1;return $.mtimeMs!==void 0&&$.mtimeMs>this.now()-this.staleMs}armLapse($,Z){let J=setTimeout(()=>{this.handleLapse($,Z)},this.staleMs);return J.unref?.(),J}armTabLapse($,Z,J){let X=setTimeout(()=>{this.handleTabLapse($,Z,J)},this.staleMs);return X.unref?.(),X}async handleTabLapse($,Z,J){let X=this.tabActivity.get($)?.get(Z)?.hook;if(!X||X.at!==J)return;let z=await this.probe($,X.vendor,X.session?.transcriptPath),G=this.tabActivity.get($),W=G?.get(Z)?.hook;if(!G||!W||W.at!==J)return;if(this.stillWorking(z,J)){W.lapse=this.armTabLapse($,Z,J);return}if(G.delete(Z),G.size===0)this.tabActivity.delete($);this.bus.publish("engine-state",{taskId:$,tabId:Z,state:"idle",at:this.now()})}async handleLapse($,Z){let J=this.activity.get($);if(!J||J.at!==Z)return;let X=await this.probe($,J.vendor,J.session?.transcriptPath),z=this.activity.get($);if(!z||z.at!==Z)return;if(this.stillWorking(X,Z)){z.lapse=this.armLapse($,Z);return}this.publishIdle($)}observeTab($,Z,J,X={}){let z=this.tabActivity.get($)??new Map,G=z.get(Z),W=G?.effective,H={state:J==="working"?"running":"idle",at:this.now(),vendor:X.vendor??G?.observed?.vendor??G?.hook?.vendor,session:G?.observed?.session??G?.hook?.session},U=ax({hook:G?.hook,observed:H},H.at,X.correctHookRunningAfterMs??Number.POSITIVE_INFINITY);if(!U)return"noop";let B=U.source==="observed"?void 0:G?.hook;if(G&&B===G.hook&&W&&W.state===U.state&&W.source===U.source)return G.observed=H,"noop";if(B===void 0&&G?.hook?.lapse)clearTimeout(G.hook.lapse);if(z.set(Z,{...B?{hook:B}:{},observed:H,effective:U}),this.tabActivity.set($,z),this.bus.publish("engine-state",this.payload($,U,Z)),U.source==="hook")return"noop";if(U.state==="running")return"observed-running";return W?.source==="hook"?"corrected-hook-running":"observed-idle"}clearTask($){let Z=this.activity.get($);if(Z?.lapse)clearTimeout(Z.lapse);this.activity.delete($);let J=this.tabActivity.get($);if(this.tabActivity.delete($),J)for(let[X,z]of J){if(z.hook?.lapse)clearTimeout(z.hook.lapse);this.bus.publish("engine-state",{taskId:$,tabId:X,state:"idle",at:this.now()})}if(Z)this.bus.publish("engine-state",{taskId:$,state:"idle",at:this.now()})}snapshotByTask(){let $={};for(let[Z,J]of this.activity)$[Z]=this.payload(Z,J);return $}currentNonIdle(){let $=[];for(let[Z,J]of this.activity)if(J.state!=="idle")$.push(this.payload(Z,J));for(let[Z,J]of this.tabActivity)for(let[X,z]of J)$.push(this.payload(Z,z.effective,X));return $}debugSnapshot(){let $=(z)=>({state:z.state,at:z.at,...z.vendor?{vendor:z.vendor}:{},lapseArmed:z.lapse!==void 0}),Z=(z)=>({state:z.effective.state,at:z.effective.at,...z.effective.vendor?{vendor:z.effective.vendor}:{},...z.effective.source==="observed"?{observed:!0}:{},lapseArmed:z.hook?.lapse!==void 0,source:z.effective.source}),J={};for(let[z,G]of this.activity)J[z]=$(G);let X={};for(let[z,G]of this.tabActivity){let W={};for(let[H,U]of G)W[H]=Z(U);X[z]=W}return{tasks:J,tabs:X}}close(){for(let $ of this.activity.values())if($.lapse)clearTimeout($.lapse);for(let $ of this.tabActivity.values())for(let Z of $.values())if(Z.hook?.lapse)clearTimeout(Z.hook.lapse);this.activity.clear(),this.tabActivity.clear()}publishIdle($){let Z={state:"idle",at:this.now()};this.activity.set($,Z),this.bus.publish("engine-state",this.payload($,Z))}payload($,Z,J){return{taskId:$,...J?{tabId:J}:{},state:Z.state,...Z.detail?{detail:Z.detail}:{},...Z.session?{sessionId:Z.session.id}:{},...Z.session?.transcriptPath?{transcriptPath:Z.session.transcriptPath}:{},at:Z.at}}}var b50=l(()=>{rx();oC();oC();rx()});import{randomUUID as Jj0}from"crypto";import{mkdir as Xj0,readFile as Qj0,rename as zj0,writeFile as Yj0}from"fs/promises";import{homedir as Gj0}from"os";import{dirname as Wj0,join as Hj0}from"path";function m50($=L$("HOME_DIR")??Gj0()){return Hj0($,X2,"agent-turns.json")}function v50($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.id!=="string"||Z.id.length===0)return null;if(typeof Z.taskId!=="string"||Z.taskId.length===0)return null;if(typeof Z.startedAt!=="number"||!Number.isFinite(Z.startedAt))return null;if(typeof Z.endedAt!=="number"||!Number.isFinite(Z.endedAt))return null;return{id:Z.id,taskId:Z.taskId,...typeof Z.tabId==="string"&&Z.tabId?{tabId:Z.tabId}:{},...typeof Z.vendor==="string"&&Z.vendor?{vendor:Z.vendor}:{},...typeof Z.sessionId==="string"&&Z.sessionId?{sessionId:Z.sessionId}:{},...typeof Z.model==="string"&&Z.model?{model:Z.model}:{},...typeof Z.repo==="string"&&Z.repo?{repo:Z.repo}:{},startedAt:Z.startedAt,endedAt:Z.endedAt,...Z.usage&&typeof Z.usage==="object"?{usage:Z.usage}:{}}}function k50($){return`${$.taskId}\x00${$.id}`}class tx{path;turns=new Map;tail=Promise.resolve();constructor($){this.path=$}async init(){await this.enqueue(async()=>{this.turns.clear();for(let $ of await this.read())this.turns.set(k50($),$)})}async record($){return await this.enqueue(async()=>{let Z=0;for(let J of $){let X=v50(J);if(!X)continue;let z=k50(X);if(!this.turns.has(z))Z++;this.turns.delete(z),this.turns.set(z,X)}if(Z===0)return 0;while(this.turns.size>qj0){let J=this.turns.keys().next().value;if(J===void 0)break;this.turns.delete(J)}return await this.write(),Z})}list($={}){let Z=$.limit&&$.limit>0?$.limit:200,J=[];for(let X of this.turns.values()){if($.taskId&&X.taskId!==$.taskId)continue;if($.repo&&X.repo!==$.repo)continue;if($.since!==void 0&&X.endedAt<$.since)continue;J.push(X)}return J.sort((X,z)=>z.endedAt-X.endedAt),J.slice(0,Z)}async deleteTask($){await this.enqueue(async()=>{let Z=!1;for(let[J,X]of this.turns){if(X.taskId!==$)continue;this.turns.delete(J),Z=!0}if(Z)await this.write()})}async read(){try{let $=JSON.parse(await Qj0(this.path,"utf8"));if(!Array.isArray($.turns))return[];return $.turns.map(v50).filter((Z)=>Z!==null)}catch($){if($.code==="ENOENT")return[];return d1("agent-turns-load",$),[]}}async write(){let $={version:1,turns:[...this.turns.values()]},Z=`${this.path}.tmp-${process.pid}-${Jj0()}`;try{await Xj0(Wj0(this.path),{recursive:!0}),await Yj0(Z,`${JSON.stringify($)}
884
884
  `,"utf8"),await zj0(Z,this.path)}catch(J){d1("agent-turns-write",J)}}enqueue($){let Z=this.tail.then($,$);return this.tail=Z.then(()=>{return},()=>{return}),Z}}var qj0=1e4;var h50=()=>{};import{randomUUID as Uj0}from"crypto";import{mkdir as Bj0,readFile as Kj0,rename as Fj0,writeFile as Mj0}from"fs/promises";import{homedir as Nj0}from"os";import{dirname as Lj0,join as Oj0}from"path";function c50($=L$("HOME_DIR")??Nj0()){return Oj0($,X2,"attention-inbox.json")}function jj0($,Z){if($==="turn-complete")return"turn_complete";if($==="awaiting-input")return"permission_needed";if($!=="turn-failed")return null;return Z?.failure==="rate_limit"?"rate_limited":"error"}function Vj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.taskId!=="string"||Z.taskId.length===0)return null;if(Z.tabId!==null&&typeof Z.tabId!=="string")return null;if(!mK(Z.state))return null;if(typeof Z.at!=="number"||!Number.isFinite(Z.at))return null;return{taskId:Z.taskId,tabId:Z.tabId,state:Z.state,...Z.detail?{detail:Z.detail}:{},unread:Z.unread!==!1,at:Z.at}}async function _j0($){try{let Z=JSON.parse(await Kj0($,"utf8"));if(!Array.isArray(Z.items))return[];return Z.items.map(Vj0).filter((J)=>J!==null)}catch(Z){if(Z.code==="ENOENT")return[];return d1("attention-inbox-load",Z),[]}}async function Cj0($,Z){await Bj0(Lj0($),{recursive:!0});let J=`${$}.tmp-${process.pid}-${Uj0()}`,X={version:1,items:[...Z]};await Mj0(J,`${JSON.stringify(X,null,2)}
885
885
  `,"utf8"),await Fj0(J,$)}class ex{path;bus;now;items=new Map;tail=Promise.resolve();constructor($,Z,J=()=>Date.now()){this.path=$;this.bus=Z;this.now=J}async init(){await this.enqueue(async()=>{this.items.clear();for(let $ of await _j0(this.path))this.items.set(L3($),$);this.publish()})}snapshot(){return[...this.items.values()].sort(u50)}async record($,Z,J,X){let z=X===null||X.length===0?null:X;await this.enqueue(async()=>{let G=L3({taskId:$,tabId:z}),W=new Map(this.items);if(Z==="turn-start"){if(!W.delete(G))return}else{let H=jj0(Z,J);if(!H)return;W.delete(G),W.set(G,{taskId:$,tabId:z,state:H,...J?{detail:J}:{},unread:!0,at:this.now()})}await this.commit(W)})}async markRead($,Z,J){return await this.deleteEpisode($,Z,J)}async deleteEpisode($,Z,J){return await this.enqueue(async()=>{let X=L3({taskId:$,tabId:Z}),z=this.items.get(X);if(!z||J!==void 0&&z.at!==J)return!1;let G=new Map(this.items);return G.delete(X),await this.commit(G),!0})}async deleteTask($){await this.enqueue(async()=>{let Z=new Map(this.items),J=!1;for(let[X,z]of Z){if(z.taskId!==$)continue;Z.delete(X),J=!0}if(J)await this.commit(Z)})}async deleteTaskBestEffort($){await this.deleteTask($).catch((Z)=>d1("attention-inbox-task-delete",Z))}enqueue($){let Z=this.tail.then($);return this.tail=Z.then(()=>{return},()=>{return}),Z}async commit($){let Z=[...$.values()].sort(u50);await Cj0(this.path,Z),this.items.clear();for(let J of Z)this.items.set(L3(J),J);this.bus.publish("attention.inbox",{items:Z})}publish(){this.bus.publish("attention.inbox",{items:this.snapshot()})}}function u50($,Z){return $.at-Z.at||$.taskId.localeCompare(Z.taskId)||($.tabId??"").localeCompare(Z.tabId??"")}var d50=l(()=>{HP()});import{randomUUID as $f}from"crypto";import{mkdir as Dj0,readFile as Aj0,rename as Pj0,writeFile as Rj0}from"fs/promises";import{homedir as Tj0}from"os";import{dirname as Sj0,join as Ij0}from"path";function p50($=L$("HOME_DIR")??Tj0()){return Ij0($,X2,"automations.json")}function F7($){return typeof $==="string"&&$.length>0?$:void 0}function Ej0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$,J=F7(Z.id),X=F7(Z.name),z=F7(Z.repo),G=F7(Z.prompt),W=F7(Z.schedule),H=F7(Z.nextRunAt);if(!J||!X||!z||!G||!W||!H)return null;if(!Number.isFinite(Date.parse(H)))return null;let U=F7(Z.precheck?.command),B=Z.missedRunGraceMinutes,M=new Date().toISOString();return{id:J,name:X,repo:z,prompt:G,schedule:W,nextRunAt:H,enabled:Z.enabled!==!1,missedRunGraceMinutes:typeof B==="number"&&Number.isFinite(B)&&B>=0?B:60,...Z.vendor?{vendor:Z.vendor}:{},...U?{precheck:{command:U,timeoutSeconds:typeof Z.precheck?.timeoutSeconds==="number"&&Z.precheck.timeoutSeconds>0?Z.precheck.timeoutSeconds:120}}:{},...F7(Z.baseRef)?{baseRef:Z.baseRef}:{},...F7(Z.lastRunAt)?{lastRunAt:Z.lastRunAt}:{},createdAt:F7(Z.createdAt)??M,updatedAt:F7(Z.updatedAt)??M}}function wj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$,J=F7(Z.id),X=F7(Z.automationId),z=F7(Z.scheduledFor),G=F7(Z.at);if(!J||!X||!z||!G)return null;if(Z.status!=="dispatched"&&Z.status!=="skipped_precheck"&&Z.status!=="skipped_missed"&&Z.status!=="skipped_unavailable"&&Z.status!=="dispatch_failed")return null;return{id:J,automationId:X,runNumber:typeof Z.runNumber==="number"&&Z.runNumber>0?Z.runNumber:1,scheduledFor:z,status:Z.status,trigger:Z.trigger==="manual"?"manual":"scheduled",...F7(Z.taskId)?{taskId:Z.taskId}:{},...Z.precheckResult?{precheckResult:Z.precheckResult}:{},...F7(Z.error)?{error:Z.error}:{},at:G}}async function xj0($){try{let Z=JSON.parse(await Aj0($,"utf8")),J=Array.isArray(Z.automations)?Z.automations.map(Ej0).filter((z)=>z!==null):[],X=Array.isArray(Z.runs)?Z.runs.map(wj0).filter((z)=>z!==null):[];return{automations:J,runs:X}}catch(Z){if(Z.code==="ENOENT")return{automations:[],runs:[]};return d1("automations-load",Z),{automations:[],runs:[]}}}async function fj0($,Z,J){await Dj0(Sj0($),{recursive:!0});let X=`${$}.tmp-${process.pid}-${$f()}`,z={version:1,automations:[...Z],runs:[...J]};await Rj0(X,`${JSON.stringify(z,null,2)}
@@ -303,7 +303,7 @@ ${G}
303
303
  `)}let z=PY0();for(let G of TT()){if(X&&G.vendor==="claude")continue;let W=G.globalSettingsPath();if(!W)continue;await G.installActivityHooks(W,{toolEvents:z}),await G.installWorktreeWatchHook(W)}await tm()}catch{}}function PY0(){try{for(let $ of V5().plugins){if(!$.enabled)continue;try{if(KZ($.root).manifest.events.some((Z)=>Z.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function tm(){let $=DY0();if($.length===0)return;let Z=x5(lm),J=new Set([sm()]),X=AY0(Z);if(X)J.add(X);for(let z of $)for(let G of J)await z.removeWorktreeSyncHook(G);if(Z!=="off")X6(lm,"off")}async function RY0(){let $=TT().find((J)=>J.vendor==="claude"),Z=$?.globalSettingsPath();if(!$||!Z){process.stdout.write(`rove hook cleanup: no Claude hook adapter \u2014 nothing to do.
304
304
  `);return}await $.removeActivityHooks(Z),await $.removeWorktreeWatchHook(Z),process.stdout.write([`rove hook cleanup: removed Rove's settings-managed hooks from ${Z}.`,"Only Rove's own entries were touched; your other hooks are intact.","The Claude Code plugin's hooks.json now carries these events (if the plugin","is not installed, the next Rove launch reinstalls the settings-managed set).",""].join(`
305
305
  `))}async function TY0($){await tm(),process.stdout.write(["rove hook setup is deprecated and now a no-op (cleanup only).","","The old external-worktree sync used a global WorktreeCreate hook, which is","a VCS provider hook \u2014 its presence broke `claude --worktree` / EnterWorktree","in every repo. Any hook Rove previously installed has been removed.","","Sync is now automatic: a `claude --worktree` (or any session) started in a","worktree under a repo Rove already tracks is adopted as a task on launch.","To adopt existing worktrees on demand, use the New Task dialog or `rove adopt`.",""].join(`
306
- `))}var OY0=500,jY0="worktree-created",lm="externalWorktreeSync";var IT=l(()=>{T7();xQ();mJ();DT();PT();C4();D2();b4()});var Vj;var $h=l(()=>{Vj={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.142",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"},"//":"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.14","@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 Jh={};P$(Jh,{repoSlug:()=>yY,releasePageUrl:()=>gT,recommendedGlobalInstallCommand:()=>xT,isNewerSemver:()=>ET,fetchReleaseSummaries:()=>YF,fetchReleaseNotesRange:()=>yT,fetchReleaseNotes:()=>fT,compareSemver:()=>V3,checkLatestVersion:()=>gY,breakingVersionsCrossed:()=>zF,UPDATE_SCRIPT_URL:()=>_j,UPDATE_COMMAND:()=>jZ,PACKAGE_NAME:()=>wT,CURRENT_VERSION:()=>R$,BREAKING_VERSIONS:()=>dJ});function yY(){let $=Vj.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function xT(){return`npm install -g ${wT}@latest`}function zF($,Z,J=dJ){let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}async function IY0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),Cj);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:Z.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(J)}}function ET($,Z){return V3($,Z)>0}function V3($,Z){let J=(G)=>G.split("-")[0]??G,X=J($).split(".").map((G)=>Number.parseInt(G,10)),z=J(Z).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,H=z[G]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function gY($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:R$,latest:Z,hasUpdate:ET(Z,R$)};if(RH()&&!$.force)return null;let J=await IY0(wT);if(!J)return null;return{current:R$,latest:J,hasUpdate:ET(J,R$)}}function Zh($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fT($){let Z=yY();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases/tags/${J}`,{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 yT($){let Z=yY();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${J}`,{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((H)=>{let U=Zh(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(V3(U,$.current)<=0)return null;if(V3(U,$.latest)>0)return null;return{version:U,url:H.html_url,body:H.body}}).filter((H)=>H!==null)}catch{return[]}finally{clearTimeout(z)}}async function YF($=12){let Z=yY();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),Cj);try{let z=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${$}`,{signal:J.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 H=Zh(W.tag_name);if(!H||typeof W.html_url!=="string")return null;return{version:H,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function gT($){let Z=yY();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var R$,wT,_j="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",jZ,dJ,Cj=3000;var d8=l(()=>{$h();j5();R$=Vj.version,wT=Vj.name;jZ=`curl -fsSL ${_j} | sh`;dJ=[]});var Qh={};P$(Qh,{stampResetGate:()=>Dj,resetGateBlockers:()=>Xh,enforceResetGate:()=>vT,LAST_RUN_VERSION_KEY:()=>bT});function Xh($,Z=R$,J=dJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}function vT(){let $=$$(),Z=N4()[bT],J=Xh(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${R$}: cannot start \u2014 version ${J.join(", ")} introduced breaking changes`,`(last run: ${X}). Your daemon/session state may be incompatible.`,"","Run:",` ${$} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${$} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
306
+ `))}var OY0=500,jY0="worktree-created",lm="externalWorktreeSync";var IT=l(()=>{T7();xQ();mJ();DT();PT();C4();D2();b4()});var Vj;var $h=l(()=>{Vj={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.8.143",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"},"//":"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.14","@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 Jh={};P$(Jh,{repoSlug:()=>yY,releasePageUrl:()=>gT,recommendedGlobalInstallCommand:()=>xT,isNewerSemver:()=>ET,fetchReleaseSummaries:()=>YF,fetchReleaseNotesRange:()=>yT,fetchReleaseNotes:()=>fT,compareSemver:()=>V3,checkLatestVersion:()=>gY,breakingVersionsCrossed:()=>zF,UPDATE_SCRIPT_URL:()=>_j,UPDATE_COMMAND:()=>jZ,PACKAGE_NAME:()=>wT,CURRENT_VERSION:()=>R$,BREAKING_VERSIONS:()=>dJ});function yY(){let $=Vj.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function xT(){return`npm install -g ${wT}@latest`}function zF($,Z,J=dJ){let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}async function IY0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),Cj);try{let X=$.replace("/","%2F"),z=await fetch(`https://registry.npmjs.org/${X}/latest`,{signal:Z.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(J)}}function ET($,Z){return V3($,Z)>0}function V3($,Z){let J=(G)=>G.split("-")[0]??G,X=J($).split(".").map((G)=>Number.parseInt(G,10)),z=J(Z).split(".").map((G)=>Number.parseInt(G,10));for(let G=0;G<3;G++){let W=X[G]??0,H=z[G]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function gY($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:R$,latest:Z,hasUpdate:ET(Z,R$)};if(RH()&&!$.force)return null;let J=await IY0(wT);if(!J)return null;return{current:R$,latest:J,hasUpdate:ET(J,R$)}}function Zh($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fT($){let Z=yY();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases/tags/${J}`,{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 yT($){let Z=yY();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),Cj);try{let G=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${J}`,{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((H)=>{let U=Zh(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(V3(U,$.current)<=0)return null;if(V3(U,$.latest)>0)return null;return{version:U,url:H.html_url,body:H.body}}).filter((H)=>H!==null)}catch{return[]}finally{clearTimeout(z)}}async function YF($=12){let Z=yY();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),Cj);try{let z=await fetch(`https://api.github.com/repos/${Z}/releases?per_page=${$}`,{signal:J.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 H=Zh(W.tag_name);if(!H||typeof W.html_url!=="string")return null;return{version:H,url:W.html_url}}).filter((W)=>W!==null)}catch{return[]}finally{clearTimeout(X)}}function gT($){let Z=yY();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var R$,wT,_j="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",jZ,dJ,Cj=3000;var d8=l(()=>{$h();j5();R$=Vj.version,wT=Vj.name;jZ=`curl -fsSL ${_j} | sh`;dJ=[]});var Qh={};P$(Qh,{stampResetGate:()=>Dj,resetGateBlockers:()=>Xh,enforceResetGate:()=>vT,LAST_RUN_VERSION_KEY:()=>bT});function Xh($,Z=R$,J=dJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=V3($,Z)<=0?[$,Z]:[Z,$];return J.filter((G)=>V3(G,X)>0&&V3(G,z)<=0)}function vT(){let $=$$(),Z=N4()[bT],J=Xh(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${R$}: cannot start \u2014 version ${J.join(", ")} introduced breaking changes`,`(last run: ${X}). Your daemon/session state may be incompatible.`,"","Run:",` ${$} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${$} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
307
307
  `)),process.exit(1)}if(Z!==R$)Dj()}function Dj(){try{S7({[bT]:R$})}catch{}}var bT="app.lastRunVersion";var Aj=l(()=>{I7();d8();b4()});import{existsSync as Yh,readFileSync as EY0}from"fs";import{homedir as wY0}from"os";import{join as Gh,resolve as zh}from"path";import{fileURLToPath as xY0}from"url";function hT($=process.env){return`${$$($)} skill install`}function Pj(){let $=xY0(import.meta.url);return[zh($,"../../../../../.agents/skills/kobe"),zh($,"../../skills/rove")].find((J)=>Yh(Gh(J,"SKILL.md")))??null}function Rj($={}){let Z=$.source!==void 0?$.source:Pj(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??yY0,"--skill",e3,...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function bY($={}){return`npx ${Rj($).join(" ")}`}async function uT($,Z){return await Bun.spawn(["npx",...Rj({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function Tj($={}){let Z=$.home??wY0(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>fY0.map((z)=>Gh(X,z)))}function gY0($){let Z=$.match(/(?:rove|kobe)-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function GF($){let Z=Tj($).find((z)=>Yh(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:kT,stale:!1};let J=null;try{J=gY0(EY0(Z,"utf8"))}catch{J=null}let X=J===null||J<kT;return{installed:!0,installedVersion:J,currentVersion:kT,stale:X}}function bY0(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function Wh($={}){let{isRovePluginEnabled:Z}=await Promise.resolve().then(() => (jj(),Oj));if(Z())return;let J=$$(),X=hT(),z=GF();if(!z.installed){if(x5(mT)==="1")return;X6(mT,"1"),process.stderr.write(`
308
308
  ${J}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${J} api\`:
309
309
  ${X}
@@ -879,7 +879,7 @@ ${V50}
879
879
  `)});function P50($){if($ instanceof Error)return $;let Z;try{Z=typeof $==="string"?$:JSON.stringify($)}catch{Z=String($)}return Error(Z)}function A50($,Z,J=new Date){let X=P50(Z);return`[${J.toISOString()}] daemon ${$}: ${X.stack??`${X.name}: ${X.message}`}
880
880
  `}function oO0($,Z,J=new Date){let X=P50(Z);return`[${J.toISOString()}] daemon error [${$}]: ${X.stack??`${X.name}: ${X.message}`}
881
881
  `}function d1($,Z){process.stderr.write(oO0($,Z))}function aO0($,Z,J=new Date){return`[${J.toISOString()}] daemon [${$}]: ${Z}
882
- `}function A5($,Z){process.stderr.write(aO0($,Z))}function nC($=(Z)=>process.stderr.write(Z)){if(dx||lx)return;dx=(Z)=>$(A50("unhandledRejection",Z)),lx=(Z)=>$(A50("uncaughtException",Z)),process.on("unhandledRejection",dx),process.on("uncaughtException",lx)}var dx,lx;function R50($,Z){switch($){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return Z?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}function VM($){if(!$)return;let{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}=$;return{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}}class px{tasks;agentState=new Map;now;constructor($=Date.now){this.now=$}contextFor($){return VM(this.tasks?.get($))}reduce($){switch($.channel){case"task.snapshot":return this.reduceTasks($.payload.tasks);case"task.jobs":return this.reduceJobs($.payload);case"engine-state":return this.reduceEngine($.payload);default:return[]}}reduceTasks($){let Z=new Map($.map((G)=>[G.id,G])),J=this.tasks;if(this.tasks=Z,!J)return[];let X=this.now(),z=[];for(let[G,W]of Z)if(!J.has(G))z.push({event:"task.created",taskId:G,task:VM(W),at:X});for(let[G,W]of J)if(!Z.has(G))z.push({event:"task.deleted",taskId:G,task:VM(W),at:X});return z}reduceJobs($){if($.kind!=="ensureWorktree"||$.phase!=="done")return[];return[{event:"worktree.created",taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}reduceEngine($){let Z=`${$.taskId}\x00${$.tabId??""}`,J=this.agentState.get(Z);if(this.agentState.set(Z,$.state),J===$.state)return[];let X=rO0[$.state];if(!X)return[];return[{event:X,taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}}var rO0;var T50=l(()=>{rO0={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"}});import{spawn as sO0}from"child_process";import{appendFileSync as tO0,mkdirSync as nx,watch as eO0}from"fs";import{dirname as S50}from"path";function Zj0($,Z){let J=new E50(Z);return $.onPublish((X)=>J.handleChannel(X)),J.start(),J}function I50($,Z,J,X){if(!Z.plugins)return null;return Zj0($,{homeDir:Z.homeDir,socketPath:J,binPath:Z.plugins.binPath,log:X})}class E50{opts;reducer=new px;plugins=[];watcher;reloadTimer;stopped=!1;constructor($){this.opts=$}start(){this.plugins=this.loadPlugins();for(let $ of this.plugins)for(let[Z,J]of $.manifest.startup.entries()){if(!FZ(J,$.manifest,vJ()))continue;this.run($,J,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${Z}]`)}this.watchRegistry()}stop(){if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);this.watcher?.close()}handleChannel($){if(this.stopped)return;for(let Z of this.reducer.reduce($))this.dispatch(Z)}handleUiReport($){if(this.stopped)return;this.dispatch({event:$.kind,...$.taskId?{taskId:$.taskId,task:this.reducer.contextFor($.taskId)}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}handleEngineReport($){if(this.stopped)return;let Z=R50($.kind,$.detail);if(!Z)return;this.dispatch({event:Z,taskId:$.taskId,task:this.reducer.contextFor($.taskId),...$.vendor?{vendor:$.vendor}:{},...$.tabId?{tabId:$.tabId}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}dispatch($){let Z=vJ();for(let J of this.plugins)for(let X of J.manifest.events){if(X.on!==$.event)continue;if(!FZ(X,J.manifest,Z))continue;this.run(J,X,"event",{ROVE_PLUGIN_EVENT:$.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify($),...$.taskId?{ROVE_PLUGIN_TASK_ID:$.taskId}:{},...$.task?.title?{ROVE_PLUGIN_TASK_TITLE:$.task.title}:{}},X.on)}}loadPlugins(){let $=V5(this.opts.homeDir),Z=vJ(),J=[];for(let X of $.plugins){if(!X.enabled)continue;let z;try{z=KZ(X.root).manifest}catch(G){this.opts.log?.(`plugin ${X.id}: manifest unreadable, skipping \u2014 ${String(G)}`);continue}if(!FZ({},z,Z))continue;J.push({manifest:z,root:X.root})}return J}watchRegistry(){let $=sK(this.opts.homeDir);try{nx(S50($),{recursive:!0}),this.watcher=eO0(S50($),(Z,J)=>{if(J&&J!=="plugins.json")return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`)},$j0)})}catch(Z){this.opts.log?.(`plugin registry watch failed \u2014 ${String(Z)}`)}}async run($,Z,J,X,z){let G=$.manifest.id,W=Date.now();nx(j3(G,this.opts.homeDir),{recursive:!0}),nx(fQ(G,this.opts.homeDir),{recursive:!0});let H=null,U="",B="",M;await new Promise((N)=>{let[j,...P]=Z.command,C=sO0(j,P,{cwd:$.root,env:qU({homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,pluginId:$.manifest.id,pluginRoot:$.root,extra:X}),stdio:["ignore","pipe","pipe"]});C.stdout.on("data",(_)=>{if(U.length<iC)U+=_.toString().slice(0,iC-U.length)}),C.stderr.on("data",(_)=>{if(B.length<iC)B+=_.toString().slice(0,iC-B.length)}),C.on("error",(_)=>{M=String(_),N()}),C.on("close",(_)=>{H=_,N()})});let O={at:W,kind:J,label:z,command:Z.command,exitCode:H,durationMs:Date.now()-W,...U?{stdout:U}:{},...B?{stderr:B}:{},...M?{spawnError:M}:{}};try{tO0(nH(G,this.opts.homeDir),`${JSON.stringify(O)}
882
+ `}function A5($,Z){process.stderr.write(aO0($,Z))}function nC($=(Z)=>process.stderr.write(Z)){if(dx||lx)return;dx=(Z)=>$(A50("unhandledRejection",Z)),lx=(Z)=>$(A50("uncaughtException",Z)),process.on("unhandledRejection",dx),process.on("uncaughtException",lx)}var dx,lx;function R50($,Z){switch($){case"session-start":return"session.start";case"session-end":return"session.end";case"turn-start":return"turn.prompt";case"turn-complete":return"turn.complete";case"turn-failed":return"turn.failed";case"turn-interrupted":return"turn.interrupted";case"awaiting-input":return Z?.waiting==="input"?"attention.question":"attention.permission";case"tool-pre":return"tool.pre";case"tool-post":return"tool.post";case"tool-failed":return"tool.failed";case"pre-compact":return"context.pre-compact";case"post-compact":return"context.post-compact";case"subagent-start":return"subagent.start";case"subagent-stop":return"subagent.stop";default:return}}function VM($){if(!$)return;let{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}=$;return{id:Z,title:J,repo:X,branch:z,worktreePath:G,vendor:W,status:H}}class px{tasks;agentState=new Map;now;constructor($=Date.now){this.now=$}contextFor($){return VM(this.tasks?.get($))}reduce($){switch($.channel){case"task.snapshot":return this.reduceTasks($.payload.tasks);case"task.jobs":return this.reduceJobs($.payload);case"engine-state":return this.reduceEngine($.payload);default:return[]}}reduceTasks($){let Z=new Map($.map((G)=>[G.id,G])),J=this.tasks;if(this.tasks=Z,!J)return[];let X=this.now(),z=[];for(let[G,W]of Z)if(!J.has(G))z.push({event:"task.created",taskId:G,task:VM(W),at:X});for(let[G,W]of J)if(!Z.has(G))z.push({event:"task.deleted",taskId:G,task:VM(W),at:X});return z}reduceJobs($){if($.kind!=="ensureWorktree"||$.phase!=="done")return[];return[{event:"worktree.created",taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),at:this.now()}]}reduceEngine($){let Z=`${$.taskId}\x00${$.tabId??""}`,J=this.agentState.get(Z);if(this.agentState.set(Z,$.state),J===$.state)return[];let X=rO0[$.state];if(!X)return[];return[{event:X,taskId:$.taskId,task:VM(this.tasks?.get($.taskId)),...$.tabId?{tabId:$.tabId}:{},at:this.now()}]}}var rO0;var T50=l(()=>{rO0={turn_complete:"agent.turn-complete",permission_needed:"agent.permission-needed",rate_limited:"agent.rate-limited",error:"agent.error",running:"agent.running",idle:"agent.idle"}});import{spawn as sO0}from"child_process";import{appendFileSync as tO0,mkdirSync as nx,watch as eO0}from"fs";import{dirname as S50}from"path";function Zj0($,Z){let J=new E50(Z);return $.onPublish((X)=>J.handleChannel(X)),J.start(),J}function I50($,Z,J,X){if(!Z.plugins)return null;return Zj0($,{homeDir:Z.homeDir,socketPath:J,binPath:Z.plugins.binPath,log:X})}class E50{opts;reducer=new px;plugins=[];watcher;reloadTimer;stopped=!1;constructor($){this.opts=$}start(){this.plugins=this.loadPlugins();for(let $ of this.plugins)for(let[Z,J]of $.manifest.startup.entries()){if(!FZ(J,$.manifest,vJ()))continue;this.run($,J,"startup",{ROVE_PLUGIN_EVENT:"startup"},`startup[${Z}]`)}this.watchRegistry()}stop(){if(this.stopped=!0,this.reloadTimer)clearTimeout(this.reloadTimer);this.watcher?.close()}handleChannel($){if(this.stopped)return;for(let Z of this.reducer.reduce($))this.dispatch(Z)}handleUiReport($){if(this.stopped)return;this.dispatch({event:$.kind,...$.taskId?{taskId:$.taskId,task:this.reducer.contextFor($.taskId)}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}handleEngineReport($){if(this.stopped)return;let Z=R50($.kind,$.detail);if(!Z)return;this.dispatch({event:Z,taskId:$.taskId,task:this.reducer.contextFor($.taskId),...$.vendor?{vendor:$.vendor}:{},...$.tabId?{tabId:$.tabId}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.detail?{detail:$.detail}:{},at:Date.now()})}dispatch($){let Z=vJ();for(let J of this.plugins)for(let X of J.manifest.events){if(X.on!==$.event)continue;if(!FZ(X,J.manifest,Z))continue;this.run(J,X,"event",{ROVE_PLUGIN_EVENT:$.event,ROVE_PLUGIN_EVENT_JSON:JSON.stringify($),...$.taskId?{ROVE_PLUGIN_TASK_ID:$.taskId}:{},...$.task?.title?{ROVE_PLUGIN_TASK_TITLE:$.task.title}:{}},X.on)}}loadPlugins(){let $=V5(this.opts.homeDir),Z=vJ(),J=[];for(let X of $.plugins){if(!X.enabled)continue;let z;try{z=KZ(X.root).manifest}catch(G){this.opts.log?.(`plugin ${X.id}: manifest unreadable, skipping \u2014 ${String(G)}`);continue}if(!FZ({},z,Z))continue;J.push({manifest:z,root:X.root})}return J}watchRegistry(){let $=sK(this.opts.homeDir);try{nx(S50($),{recursive:!0}),this.watcher=eO0(S50($),(Z,J)=>{if(J&&J!=="plugins.json")return;if(this.reloadTimer)clearTimeout(this.reloadTimer);this.reloadTimer=setTimeout(()=>{if(this.stopped)return;this.plugins=this.loadPlugins(),this.opts.log?.(`plugin registry reloaded (${this.plugins.length} enabled)`)},$j0)})}catch(Z){this.opts.log?.(`plugin registry watch failed \u2014 ${String(Z)}`)}}async run($,Z,J,X,z){let G=$.manifest.id,W=Date.now();nx(j3(G,this.opts.homeDir),{recursive:!0}),nx(fQ(G,this.opts.homeDir),{recursive:!0});let H=null,U="",B="",M;await new Promise((N)=>{let[j,...P]=Z.command,C=sO0(j,P,{cwd:$.root,env:qU({homeDir:this.opts.homeDir,socketPath:this.opts.socketPath,binPath:this.opts.binPath,pluginId:$.manifest.id,pluginRoot:$.root,extra:X}),stdio:["ignore","pipe","pipe"]});C.stdout.on("data",(_)=>{if(U.length<iC)U+=_.toString().slice(0,iC-U.length)}),C.stderr.on("data",(_)=>{if(B.length<iC)B+=_.toString().slice(0,iC-B.length)}),C.on("error",(_)=>{M=String(_),N()}),C.on("close",(_)=>{H=_,N()})});let O={at:W,kind:J,label:z,command:Z.command,exitCode:H,durationMs:Date.now()-W,...U?{stdout:U}:{},...B?{stderr:B}:{},...M?{spawnError:M}:{}};try{tO0(nH(G,this.opts.homeDir),`${JSON.stringify(O)}
883
883
  `)}catch{}if(M||H!==null&&H!==0)this.opts.log?.(`plugin ${G} ${z}: ${M??`exit ${H}`}`)}}var iC=8192,$j0=150;var w50=l(()=>{HC();T50();xQ();MZ();mJ()});async function x50($,Z,J,X,z){let G=$.getTask(J);if(!G?.worktreePath)return;let W=X??G.vendor??Z.defaultTaskVendor,H=Z.createEngineTurnDetector(W);if(!H?.supportsCompletionMarkers()){let O=await Z.latestTranscriptMtime(W,G.worktreePath);return O>0?{mtimeMs:O}:{}}let U=z?await H.latestActivityInFile(z):null,{marker:B,mtimeMs:M}=U??await H.latestActivity(G.worktreePath);return{...M>0?{mtimeMs:M}:{},...B?{completedAt:B.timestampMs}:{}}}function f50($,Z,J){switch(Z){case"session-start":case"session-end":case"turn-interrupted":return"idle";case"turn-start":return"running";case"turn-complete":return $==="running"||$==="permission_needed"||$===void 0?"turn_complete":$;case"turn-failed":return J?.failure==="rate_limit"||J?.failure==="billing"?"rate_limited":"error";case"awaiting-input":return"permission_needed";default:return $??"idle"}}function ox(){let $=process.env.KOBE_ENGINE_STATE_TTL_MS;if($===void 0)return ix;let Z=Number($);return Number.isFinite(Z)&&Z>0?Z:ix}var ix=600000,_M;var oC=l(()=>{_M=new Set(["turn_complete","permission_needed","error","rate_limited"])});function y50($){return{state:$.state,at:$.at,source:"hook",...$.detail?{detail:$.detail}:{},...$.vendor?{vendor:$.vendor}:{},...$.session?{session:$.session}:{}}}function g50($,Z){return{state:$.state,at:$.at,source:"observed",...$.vendor??Z?.vendor?{vendor:$.vendor??Z?.vendor}:{},...$.session??Z?.session?{session:$.session??Z?.session}:{}}}function ax($,Z,J=Number.POSITIVE_INFINITY){let{hook:X,observed:z}=$;if(X){if(_M.has(X.state))return y50(X);if(X.state==="running"&&z?.state==="idle"&&z.at>=X.at&&Z-X.at>=J)return g50(z,X);return y50(X)}if(z)return g50(z);return}var rx=l(()=>{oC()});class sx{bus;staleMs;now;livenessAt;activity=new Map;tabActivity=new Map;constructor($,Z=ox(),J=()=>Date.now(),X=()=>Promise.resolve(void 0)){this.bus=$;this.staleMs=Z;this.now=J;this.livenessAt=X}report($,Z,J,X,z,G){let W=this.activity.get($);if(W?.lapse)clearTimeout(W.lapse);let H=f50(W?.state,Z,J),U=this.now(),B={state:H,detail:J,at:U,session:z??W?.session,vendor:G??W?.vendor};if(H!=="idle"&&!_M.has(H))B.lapse=this.armLapse($,U);this.activity.set($,B);let M=B;if(X){let O=this.tabActivity.get($)??new Map,N=O.get(X);if(N?.hook?.lapse)clearTimeout(N.hook.lapse);let j=z??N?.hook?.session,P=G??N?.hook?.vendor;if(M={state:H,detail:J,at:U,session:j},H==="idle")O.delete(X);else{let C={state:H,detail:J,at:U,session:j,vendor:P};if(!_M.has(H))C.lapse=this.armTabLapse($,X,U);O.set(X,{hook:C,effective:{state:H,at:U,source:"hook",...J?{detail:J}:{},...P?{vendor:P}:{},...j?{session:j}:{}}})}if(O.size>0)this.tabActivity.set($,O);else this.tabActivity.delete($)}this.bus.publish("engine-state",this.payload($,M,X))}async probe($,Z,J){try{return await this.livenessAt($,Z,J)}catch{return}}stillWorking($,Z){if(!$)return!1;if($.completedAt!==void 0&&$.completedAt>=Z)return!1;return $.mtimeMs!==void 0&&$.mtimeMs>this.now()-this.staleMs}armLapse($,Z){let J=setTimeout(()=>{this.handleLapse($,Z)},this.staleMs);return J.unref?.(),J}armTabLapse($,Z,J){let X=setTimeout(()=>{this.handleTabLapse($,Z,J)},this.staleMs);return X.unref?.(),X}async handleTabLapse($,Z,J){let X=this.tabActivity.get($)?.get(Z)?.hook;if(!X||X.at!==J)return;let z=await this.probe($,X.vendor,X.session?.transcriptPath),G=this.tabActivity.get($),W=G?.get(Z)?.hook;if(!G||!W||W.at!==J)return;if(this.stillWorking(z,J)){W.lapse=this.armTabLapse($,Z,J);return}if(G.delete(Z),G.size===0)this.tabActivity.delete($);this.bus.publish("engine-state",{taskId:$,tabId:Z,state:"idle",at:this.now()})}async handleLapse($,Z){let J=this.activity.get($);if(!J||J.at!==Z)return;let X=await this.probe($,J.vendor,J.session?.transcriptPath),z=this.activity.get($);if(!z||z.at!==Z)return;if(this.stillWorking(X,Z)){z.lapse=this.armLapse($,Z);return}this.publishIdle($)}observeTab($,Z,J,X={}){let z=this.tabActivity.get($)??new Map,G=z.get(Z),W=G?.effective,H={state:J==="working"?"running":"idle",at:this.now(),vendor:X.vendor??G?.observed?.vendor??G?.hook?.vendor,session:G?.observed?.session??G?.hook?.session},U=ax({hook:G?.hook,observed:H},H.at,X.correctHookRunningAfterMs??Number.POSITIVE_INFINITY);if(!U)return"noop";let B=U.source==="observed"?void 0:G?.hook;if(G&&B===G.hook&&W&&W.state===U.state&&W.source===U.source)return G.observed=H,"noop";if(B===void 0&&G?.hook?.lapse)clearTimeout(G.hook.lapse);if(z.set(Z,{...B?{hook:B}:{},observed:H,effective:U}),this.tabActivity.set($,z),this.bus.publish("engine-state",this.payload($,U,Z)),U.source==="hook")return"noop";if(U.state==="running")return"observed-running";return W?.source==="hook"?"corrected-hook-running":"observed-idle"}clearTask($){let Z=this.activity.get($);if(Z?.lapse)clearTimeout(Z.lapse);this.activity.delete($);let J=this.tabActivity.get($);if(this.tabActivity.delete($),J)for(let[X,z]of J){if(z.hook?.lapse)clearTimeout(z.hook.lapse);this.bus.publish("engine-state",{taskId:$,tabId:X,state:"idle",at:this.now()})}if(Z)this.bus.publish("engine-state",{taskId:$,state:"idle",at:this.now()})}snapshotByTask(){let $={};for(let[Z,J]of this.activity)$[Z]=this.payload(Z,J);return $}currentNonIdle(){let $=[];for(let[Z,J]of this.activity)if(J.state!=="idle")$.push(this.payload(Z,J));for(let[Z,J]of this.tabActivity)for(let[X,z]of J)$.push(this.payload(Z,z.effective,X));return $}debugSnapshot(){let $=(z)=>({state:z.state,at:z.at,...z.vendor?{vendor:z.vendor}:{},lapseArmed:z.lapse!==void 0}),Z=(z)=>({state:z.effective.state,at:z.effective.at,...z.effective.vendor?{vendor:z.effective.vendor}:{},...z.effective.source==="observed"?{observed:!0}:{},lapseArmed:z.hook?.lapse!==void 0,source:z.effective.source}),J={};for(let[z,G]of this.activity)J[z]=$(G);let X={};for(let[z,G]of this.tabActivity){let W={};for(let[H,U]of G)W[H]=Z(U);X[z]=W}return{tasks:J,tabs:X}}close(){for(let $ of this.activity.values())if($.lapse)clearTimeout($.lapse);for(let $ of this.tabActivity.values())for(let Z of $.values())if(Z.hook?.lapse)clearTimeout(Z.hook.lapse);this.activity.clear(),this.tabActivity.clear()}publishIdle($){let Z={state:"idle",at:this.now()};this.activity.set($,Z),this.bus.publish("engine-state",this.payload($,Z))}payload($,Z,J){return{taskId:$,...J?{tabId:J}:{},state:Z.state,...Z.detail?{detail:Z.detail}:{},...Z.session?{sessionId:Z.session.id}:{},...Z.session?.transcriptPath?{transcriptPath:Z.session.transcriptPath}:{},at:Z.at}}}var b50=l(()=>{rx();oC();oC();rx()});import{randomUUID as Jj0}from"crypto";import{mkdir as Xj0,readFile as Qj0,rename as zj0,writeFile as Yj0}from"fs/promises";import{homedir as Gj0}from"os";import{dirname as Wj0,join as Hj0}from"path";function m50($=L$("HOME_DIR")??Gj0()){return Hj0($,X2,"agent-turns.json")}function v50($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.id!=="string"||Z.id.length===0)return null;if(typeof Z.taskId!=="string"||Z.taskId.length===0)return null;if(typeof Z.startedAt!=="number"||!Number.isFinite(Z.startedAt))return null;if(typeof Z.endedAt!=="number"||!Number.isFinite(Z.endedAt))return null;return{id:Z.id,taskId:Z.taskId,...typeof Z.tabId==="string"&&Z.tabId?{tabId:Z.tabId}:{},...typeof Z.vendor==="string"&&Z.vendor?{vendor:Z.vendor}:{},...typeof Z.sessionId==="string"&&Z.sessionId?{sessionId:Z.sessionId}:{},...typeof Z.model==="string"&&Z.model?{model:Z.model}:{},...typeof Z.repo==="string"&&Z.repo?{repo:Z.repo}:{},startedAt:Z.startedAt,endedAt:Z.endedAt,...Z.usage&&typeof Z.usage==="object"?{usage:Z.usage}:{}}}function k50($){return`${$.taskId}\x00${$.id}`}class tx{path;turns=new Map;tail=Promise.resolve();constructor($){this.path=$}async init(){await this.enqueue(async()=>{this.turns.clear();for(let $ of await this.read())this.turns.set(k50($),$)})}async record($){return await this.enqueue(async()=>{let Z=0;for(let J of $){let X=v50(J);if(!X)continue;let z=k50(X);if(!this.turns.has(z))Z++;this.turns.delete(z),this.turns.set(z,X)}if(Z===0)return 0;while(this.turns.size>qj0){let J=this.turns.keys().next().value;if(J===void 0)break;this.turns.delete(J)}return await this.write(),Z})}list($={}){let Z=$.limit&&$.limit>0?$.limit:200,J=[];for(let X of this.turns.values()){if($.taskId&&X.taskId!==$.taskId)continue;if($.repo&&X.repo!==$.repo)continue;if($.since!==void 0&&X.endedAt<$.since)continue;J.push(X)}return J.sort((X,z)=>z.endedAt-X.endedAt),J.slice(0,Z)}async deleteTask($){await this.enqueue(async()=>{let Z=!1;for(let[J,X]of this.turns){if(X.taskId!==$)continue;this.turns.delete(J),Z=!0}if(Z)await this.write()})}async read(){try{let $=JSON.parse(await Qj0(this.path,"utf8"));if(!Array.isArray($.turns))return[];return $.turns.map(v50).filter((Z)=>Z!==null)}catch($){if($.code==="ENOENT")return[];return d1("agent-turns-load",$),[]}}async write(){let $={version:1,turns:[...this.turns.values()]},Z=`${this.path}.tmp-${process.pid}-${Jj0()}`;try{await Xj0(Wj0(this.path),{recursive:!0}),await Yj0(Z,`${JSON.stringify($)}
884
884
  `,"utf8"),await zj0(Z,this.path)}catch(J){d1("agent-turns-write",J)}}enqueue($){let Z=this.tail.then($,$);return this.tail=Z.then(()=>{return},()=>{return}),Z}}var qj0=1e4;var h50=()=>{};import{randomUUID as Uj0}from"crypto";import{mkdir as Bj0,readFile as Kj0,rename as Fj0,writeFile as Mj0}from"fs/promises";import{homedir as Nj0}from"os";import{dirname as Lj0,join as Oj0}from"path";function c50($=L$("HOME_DIR")??Nj0()){return Oj0($,X2,"attention-inbox.json")}function jj0($,Z){if($==="turn-complete")return"turn_complete";if($==="awaiting-input")return"permission_needed";if($!=="turn-failed")return null;return Z?.failure==="rate_limit"?"rate_limited":"error"}function Vj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.taskId!=="string"||Z.taskId.length===0)return null;if(Z.tabId!==null&&typeof Z.tabId!=="string")return null;if(!mK(Z.state))return null;if(typeof Z.at!=="number"||!Number.isFinite(Z.at))return null;return{taskId:Z.taskId,tabId:Z.tabId,state:Z.state,...Z.detail?{detail:Z.detail}:{},unread:Z.unread!==!1,at:Z.at}}async function _j0($){try{let Z=JSON.parse(await Kj0($,"utf8"));if(!Array.isArray(Z.items))return[];return Z.items.map(Vj0).filter((J)=>J!==null)}catch(Z){if(Z.code==="ENOENT")return[];return d1("attention-inbox-load",Z),[]}}async function Cj0($,Z){await Bj0(Lj0($),{recursive:!0});let J=`${$}.tmp-${process.pid}-${Uj0()}`,X={version:1,items:[...Z]};await Mj0(J,`${JSON.stringify(X,null,2)}
885
885
  `,"utf8"),await Fj0(J,$)}class ex{path;bus;now;items=new Map;tail=Promise.resolve();constructor($,Z,J=()=>Date.now()){this.path=$;this.bus=Z;this.now=J}async init(){await this.enqueue(async()=>{this.items.clear();for(let $ of await _j0(this.path))this.items.set(L3($),$);this.publish()})}snapshot(){return[...this.items.values()].sort(u50)}async record($,Z,J,X){let z=X===null||X.length===0?null:X;await this.enqueue(async()=>{let G=L3({taskId:$,tabId:z}),W=new Map(this.items);if(Z==="turn-start"){if(!W.delete(G))return}else{let H=jj0(Z,J);if(!H)return;W.delete(G),W.set(G,{taskId:$,tabId:z,state:H,...J?{detail:J}:{},unread:!0,at:this.now()})}await this.commit(W)})}async markRead($,Z,J){return await this.deleteEpisode($,Z,J)}async deleteEpisode($,Z,J){return await this.enqueue(async()=>{let X=L3({taskId:$,tabId:Z}),z=this.items.get(X);if(!z||J!==void 0&&z.at!==J)return!1;let G=new Map(this.items);return G.delete(X),await this.commit(G),!0})}async deleteTask($){await this.enqueue(async()=>{let Z=new Map(this.items),J=!1;for(let[X,z]of Z){if(z.taskId!==$)continue;Z.delete(X),J=!0}if(J)await this.commit(Z)})}async deleteTaskBestEffort($){await this.deleteTask($).catch((Z)=>d1("attention-inbox-task-delete",Z))}enqueue($){let Z=this.tail.then($);return this.tail=Z.then(()=>{return},()=>{return}),Z}async commit($){let Z=[...$.values()].sort(u50);await Cj0(this.path,Z),this.items.clear();for(let J of Z)this.items.set(L3(J),J);this.bus.publish("attention.inbox",{items:Z})}publish(){this.bus.publish("attention.inbox",{items:this.snapshot()})}}function u50($,Z){return $.at-Z.at||$.taskId.localeCompare(Z.taskId)||($.tabId??"").localeCompare(Z.tabId??"")}var d50=l(()=>{HP()});import{randomUUID as $f}from"crypto";import{mkdir as Dj0,readFile as Aj0,rename as Pj0,writeFile as Rj0}from"fs/promises";import{homedir as Tj0}from"os";import{dirname as Sj0,join as Ij0}from"path";function p50($=L$("HOME_DIR")??Tj0()){return Ij0($,X2,"automations.json")}function F7($){return typeof $==="string"&&$.length>0?$:void 0}function Ej0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$,J=F7(Z.id),X=F7(Z.name),z=F7(Z.repo),G=F7(Z.prompt),W=F7(Z.schedule),H=F7(Z.nextRunAt);if(!J||!X||!z||!G||!W||!H)return null;if(!Number.isFinite(Date.parse(H)))return null;let U=F7(Z.precheck?.command),B=Z.missedRunGraceMinutes,M=new Date().toISOString();return{id:J,name:X,repo:z,prompt:G,schedule:W,nextRunAt:H,enabled:Z.enabled!==!1,missedRunGraceMinutes:typeof B==="number"&&Number.isFinite(B)&&B>=0?B:60,...Z.vendor?{vendor:Z.vendor}:{},...U?{precheck:{command:U,timeoutSeconds:typeof Z.precheck?.timeoutSeconds==="number"&&Z.precheck.timeoutSeconds>0?Z.precheck.timeoutSeconds:120}}:{},...F7(Z.baseRef)?{baseRef:Z.baseRef}:{},...F7(Z.lastRunAt)?{lastRunAt:Z.lastRunAt}:{},createdAt:F7(Z.createdAt)??M,updatedAt:F7(Z.updatedAt)??M}}function wj0($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$,J=F7(Z.id),X=F7(Z.automationId),z=F7(Z.scheduledFor),G=F7(Z.at);if(!J||!X||!z||!G)return null;if(Z.status!=="dispatched"&&Z.status!=="skipped_precheck"&&Z.status!=="skipped_missed"&&Z.status!=="skipped_unavailable"&&Z.status!=="dispatch_failed")return null;return{id:J,automationId:X,runNumber:typeof Z.runNumber==="number"&&Z.runNumber>0?Z.runNumber:1,scheduledFor:z,status:Z.status,trigger:Z.trigger==="manual"?"manual":"scheduled",...F7(Z.taskId)?{taskId:Z.taskId}:{},...Z.precheckResult?{precheckResult:Z.precheckResult}:{},...F7(Z.error)?{error:Z.error}:{},at:G}}async function xj0($){try{let Z=JSON.parse(await Aj0($,"utf8")),J=Array.isArray(Z.automations)?Z.automations.map(Ej0).filter((z)=>z!==null):[],X=Array.isArray(Z.runs)?Z.runs.map(wj0).filter((z)=>z!==null):[];return{automations:J,runs:X}}catch(Z){if(Z.code==="ENOENT")return{automations:[],runs:[]};return d1("automations-load",Z),{automations:[],runs:[]}}}async function fj0($,Z,J){await Dj0(Sj0($),{recursive:!0});let X=`${$}.tmp-${process.pid}-${$f()}`,z={version:1,automations:[...Z],runs:[...J]};await Rj0(X,`${JSON.stringify(z,null,2)}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@sma1lboy/kobe",
4
- "version": "0.8.142",
4
+ "version": "0.8.143",
5
5
  "description": "Rove — the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.3.13",