@sma1lboy/kobe 0.8.88 → 0.8.89
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 +1 -1
- package/dist/cli/kobe.js +1 -1
- package/dist/cli/rove.js +1 -1
- package/package.json +4 -4
package/dist/cli/index.js
CHANGED
|
@@ -282,7 +282,7 @@ ${z}`,Z);this.line=J,this.column=X,this.codeblock=z}}});function JL($,Z){let J=$
|
|
|
282
282
|
`)){if(!J.trim())continue;try{let{sessionId:X,sessionDir:z,workDir:Y}=JSON.parse(J);if(X&&z&&Y)Z.push({sessionId:X,sessionDir:z,workDir:Y})}catch{}}return Z}async function sb($){let Z=await $.readFile(DL.join($.kimiDir(),"session_index.jsonl")).catch(()=>"");return BZ0(Z)}function tb($){return DL.join($,"agents","main","wire.jsonl")}async function pP($,Z=lP){if(!$)return[];let J=[];for(let X of await sb(Z)){if(X.workDir!==$)continue;let z=await Z.stat(tb(X.sessionDir)).then((Y)=>Y.mtimeMs).catch(()=>null);if(z===null)continue;J.push({id:X.sessionId,mtimeMs:z})}return J.sort((X,z)=>X.mtimeMs-z.mtimeMs).map((X)=>X.id)}async function eb($,Z=lP){return await Z.stat($).then((J)=>J.mtimeMs).catch(()=>0)}async function nP($,Z=lP){if(!$)return null;let J=(await sb(Z)).find((z)=>z.sessionId===$);if(!J)return null;let X=tb(J.sessionDir);return await Z.stat(X).then(()=>X).catch(()=>null)}var lP;var $k=a(()=>{LQ();lP={kimiDir(){return process.env.KIMI_CODE_HOME?.trim()||DL.join(UZ0(),".kimi-code")},async readFile($){return await NQ($)},stat:qZ0}});import FZ0 from"path";var PL,Zk,Jk,Xk,Qk;var zk=a(()=>{mP();VL();rb();$k();PL={async listSessionIdsForWorktree(){return[]},async readHistory(){return[]},async transcriptPath(){return null},async latestTranscriptMtimeForWorktree(){return 0}},Zk={async listSessionIdsForWorktree($){return[...await wH($)].sort((J,X)=>J.mtimeMs-X.mtimeMs).map((J)=>J.sessionId)},readHistory:($)=>lb($),async transcriptPath($,Z){return(await wH(Z)).find((X)=>X.sessionId===$)?.path??null},latestTranscriptMtimeForWorktree:($)=>db($)},Jk={listSessionIdsForWorktree:($)=>Eb($),readHistory:($)=>xb($),transcriptPath:async($)=>await yP($)??null,latestTranscriptMtimeForWorktree:($)=>wb($)},Xk={listSessionIdsForWorktree:($)=>ib($),readHistory:($)=>ab($),async transcriptPath($){let Z=await cP($);return Z?FZ0.join(Z,"events.jsonl"):null},latestTranscriptMtimeForWorktree:($)=>ob($)},Qk={listSessionIdsForWorktree:($)=>pP($),readHistory:PL.readHistory,transcriptPath:($)=>nP($),async latestTranscriptMtimeForWorktree($){let J=(await pP($)).at(-1);if(!J)return 0;let X=await nP(J);return X?await eb(X):0}}});var RL,Gk,Yk;var TL=a(()=>{RL=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Gk=["\xB7","\u2722","\u2731","\u2736","\u273B","\u273D"],Yk=[...Gk,...[...Gk].reverse()]});import{readFile as Hk,stat as MZ0}from"fs/promises";class SL{supportsCompletionMarkers(){return!0}async latestCompletion($){return(await this.latestActivity($)).marker}async latestActivityInFile($){return null}}function qk($){return E$($).createTurnDetector()}function Wk($,Z="claude",J=0){let X=null,z=0;for(let Y of $.split(`
|
|
283
283
|
`)){z++;let W=Bk(Y);if(!W)continue;let H=aP(W.message)?W.message:W;if(H.role!=="assistant")continue;if(!("content"in H))continue;let U=Kk(W,J),K={id:`claude:${Z}:${U}:${z}`,timestampMs:U,source:"claude"};if(!X||K.timestampMs>=X.timestampMs)X=K}return X}function jZ0($){if($.type==="turn.completed")return!0;if($.type!=="event_msg")return!1;let Z=aP($.payload)?$.payload:void 0;return typeof Z?.type==="string"&&LZ0.has(Z.type)}function VZ0($,Z="codex"){let J=null,X=0;for(let z of $.split(`
|
|
284
284
|
`)){X++;let Y=Bk(z);if(!Y||!jZ0(Y))continue;let W=Kk(Y,0),H={id:`codex:${Z}:${W}:${X}`,timestampMs:W,source:"codex"};if(!J||H.timestampMs>=J.timestampMs)J=H}return J}function Bk($){let Z=$.trim();if(!Z)return null;try{let J=JSON.parse(Z);return aP(J)?J:null}catch{return null}}function Kk($,Z){let J=typeof $.timestamp==="string"?Date.parse($.timestamp):Number.NaN;return Number.isFinite(J)?J:Z}function aP($){return typeof $==="object"&&$!==null&&!Array.isArray($)}var Uk=($)=>MZ0($).then((Z)=>Z.mtimeMs,()=>0),OZ0,iP,NZ0,oP,EK,LZ0;var rP=a(()=>{mP();VL();c7();OZ0={listSessionFiles:($)=>wH($),readFile:($)=>Hk($,"utf8"),statMtimeMs:Uk};iP=class iP extends SL{deps;vendor="claude";cache=new Map;constructor($=OZ0){super();this.deps=$}async latestActivity($){let Z=await this.deps.listSessionFiles($),J=Z[0]?.mtimeMs??0,X=null,z=new Map;for(let Y of Z.slice(0,4)){let W=this.cache.get(Y.path),H;if(W&&Y.mtimeMs>0&&W.mtimeMs===Y.mtimeMs)H=W.marker;else{let U=await this.deps.readFile(Y.path).catch(()=>"");H=Wk(U,Y.path,Y.mtimeMs)}if(z.set(Y.path,{mtimeMs:Y.mtimeMs,marker:H}),H&&(!X||H.timestampMs>X.timestampMs))X=H}return this.cache=z,{marker:X,mtimeMs:J}}async latestActivityInFile($){let Z=await(this.deps.statMtimeMs??Uk)($);if(Z===0)return null;let J=await this.deps.readFile($).catch(()=>"");return{marker:Wk(J,$,Z),mtimeMs:Z}}};NZ0={findLatestRollout:($)=>bP($),readFile:($)=>Hk($,"utf8")};oP=class oP extends SL{deps;vendor="codex";cache=null;constructor($=NZ0){super();this.deps=$}async latestActivity($){if(!$)return{marker:null,mtimeMs:0};let Z=await this.deps.findLatestRollout($);if(!Z)return{marker:null,mtimeMs:0};if(this.cache&&this.cache.path===Z.path&&Z.mtimeMs>0&&this.cache.mtimeMs===Z.mtimeMs)return{marker:this.cache.marker,mtimeMs:Z.mtimeMs};let J=await this.deps.readFile(Z.path).catch(()=>"");if(!J)return{marker:null,mtimeMs:Z.mtimeMs};let X=VZ0(J,Z.path);return this.cache={path:Z.path,mtimeMs:Z.mtimeMs,marker:X},{marker:X,mtimeMs:Z.mtimeMs}}};EK=class EK extends SL{vendor;constructor($){super();this.vendor=$}supportsCompletionMarkers(){return!1}async latestActivity(){return{marker:null,mtimeMs:0}}};LZ0=new Set(["task_complete","turn_complete","turn_aborted"])});function _Z0($){return{vendor:$,builtin:!1,displayName:$,defaultCommand:[$],history:PL,detectAccount:async()=>({binary:{found:!1,error:"custom engine: Rove has no account detector for it"},account:{kind:"none"}}),createHookAdapter:()=>new wK($),createTurnDetector:()=>new EK($)}}function E$($){return k7($)?sP[$]:_Z0($)}function Fk($){return E$($).history.readHistory!==PL.readHistory}function tP($){let Z=E$($).terminalTitle?.statusPrefixes;return Z&&Z.length>0?Z:Mk}function xH($,Z){let J=Z?tP(Z):Mk;for(let X of[...J].sort((z,Y)=>Y.length-z.length)){if(!$.startsWith(X))continue;let z=$.slice(X.length).trimStart();if(z.length===0)return $;return z}return $}function IL($,Z){let J=E$($).terminalTitle,X=J?.workingPrefixes;if(J?.ownsStatus!==!0||!X||X.length===0)return null;let z=Z.trim();if(z.length===0)return null;return X.some((Y)=>z.startsWith(Y))?"working":"rest"}function Ok(){return Object.values(sP).filter(($)=>$.quotaUsage).map(($)=>$.vendor)}var sP,Mk;var c7=a(()=>{v7();_J();$b();Yb();Kb();Ob();Lb();bb();zk();eP();TL();rP();sP={claude:{vendor:"claude",builtin:!0,displayName:"Claude",defaultCommand:["claude"],history:Zk,detectAccount:($)=>DH($),createHookAdapter:()=>new AP,createTurnDetector:()=>new iP,capabilities:ty,identity:ey,spinnerFrames:Yk,terminalTitle:{ownsStatus:!0,statusPrefixes:["\u2733","\u2802","\u2810","\u25D0","\u25D1"],workingPrefixes:["\u2802","\u2810","\u25D0","\u25D1"]},quotaUsage:()=>Bb()},codex:{vendor:"codex",builtin:!0,displayName:"Codex",defaultCommand:["codex"],effortLevels:["none","low","medium","high","xhigh"],history:Jk,detectAccount:($)=>PH($),createHookAdapter:()=>new TP,createTurnDetector:()=>new oP,capabilities:Fb,identity:Mb,terminalTitle:{ownsStatus:!0,launchArgs:["-c",'tui.terminal_title=["activity","thread-title"]'],statusPrefixes:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],workingPrefixes:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"]},quotaUsage:()=>yb()},copilot:{vendor:"copilot",builtin:!0,displayName:"Copilot",defaultCommand:["copilot"],history:Xk,detectAccount:($)=>RH($),createHookAdapter:()=>new wK("copilot"),createTurnDetector:()=>new EK("copilot")},kimi:{vendor:"kimi",builtin:!0,displayName:"Kimi",defaultCommand:["kimi"],history:Qk,detectAccount:($)=>FL($),createHookAdapter:()=>new wK("kimi"),createTurnDetector:()=>new EK("kimi")}};Mk=[...new Set(Object.values(sP).flatMap(($)=>$.terminalTitle?.statusPrefixes??[]))]});function $R($){return E$($).createHookAdapter()}class wK{vendor;constructor($){this.vendor=$}supportsHooks(){return!1}globalSettingsPath(){return""}activityDetailFromPayload(){return}sessionFromPayload(){return}async installActivityHooks(){}async removeActivityHooks(){}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async installWorktreeWatchHook(){}async removeWorktreeWatchHook(){}}var eP=a(()=>{c7()});function EL($){return CZ0.includes($)}function Nk($){return AZ0.includes($)}var CZ0,AZ0;var ZR=a(()=>{CZ0=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end","tool-pre","tool-post","tool-failed","pre-compact","post-compact","subagent-start","subagent-stop"];AZ0=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end"]});var Sk={};g$(Sk,{runHookSubcommand:()=>EZ0,readTextWithTimeout:()=>Vk,parseWorktreeRemovePath:()=>Dk,parseWorktreeAddPath:()=>Ak,ensureGlobalKobeHooks:()=>QR});import{readFileSync as DZ0}from"fs";import{homedir as PZ0}from"os";import{join as XR,resolve as JR}from"path";async function Vk($,Z=RZ0){let J;try{return await Promise.race([$(),new Promise((X)=>{J=setTimeout(()=>X(""),Z)})])}finally{if(J!==void 0)clearTimeout(J)}}async function _k(){try{let $=await Vk(()=>Bun.stdin.text());if(!$.trim())return{};let Z=JSON.parse($);return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:{}}catch{return{}}}function Lk($,Z){for(let J=0;J<$.length;J++){if($[J]===Z)return $[J+1];if($[J].startsWith(`${Z}=`))return $[J].slice(Z.length+1)}return}function SZ0($){return!!$&&typeof $==="object"&&!Array.isArray($)}function Ck($){let Z=[],J=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=J.exec($))!==null)Z.push(X[1]??X[2]??X[3]??"");return Z}function Ak($){let Z=Ck($),J=new Set(["-b","-B","--reason"]);for(let X=0;X+1<Z.length;X++){if(Z[X]!=="worktree"||Z[X+1]!=="add")continue;let z=X+2;while(z<Z.length){let Y=Z[z];if(Y==="&&"||Y==="||"||Y===";"||Y==="|"||Y===">"||Y===">>")break;if(Y.startsWith("-")){z+=J.has(Y)?2:1;continue}return Y}}return}function Dk($){let Z=Ck($);for(let J=0;J+1<Z.length;J++){if(Z[J]!=="worktree"||Z[J+1]!=="remove")continue;let X=J+2;while(X<Z.length){let z=Z[X];if(z==="&&"||z==="||"||z===";"||z==="|"||z===">"||z===">>")break;if(z.startsWith("-")){X+=1;continue}return z}}return}async function IZ0(){let $=await _k(),Z=SZ0($.tool_input)?$.tool_input:{},J=typeof Z.command==="string"?Z.command:"";if(!J.includes("worktree"))return;let X=typeof $.cwd==="string"&&$.cwd?$.cwd:process.cwd(),z=Ak(J),Y=z?void 0:Dk(J);if(!z&&!Y)return;let W=await GQ();if(!W)return;try{if(z)await W.request("worktree.reconcile",{cwd:X,worktreePath:JR(X,z)});else if(Y)await W.request("worktree.archiveRemoved",{worktreePath:JR(X,Y)})}finally{W.close()}}async function EZ0($){let[Z,...J]=$;if(Z==="setup"){await gZ0(J);return}if(Z===TZ0){try{await IZ0()}catch{}return}try{if(!Z||!EL(Z))return;let X=await _k(),z=Lk(J,"--task-id"),Y=typeof X.cwd==="string"&&X.cwd?X.cwd:process.cwd(),W=process.env.KOBE_TASK_ID,H=process.env.KOBE_TAB_ID,U=Lk(J,"--engine"),K=Pk().filter((_)=>!U||_.vendor===U),O;for(let _ of K)if(O=_.activityDetailFromPayload(Z,X),O)break;let L;for(let _ of K)if(L=_.sessionFromPayload(X),L)break;let M=await GQ();if(!M)return;try{let _=z??W;await M.request("engine.reportEvent",{..._?{taskId:_}:{cwd:Y},kind:Z,...U?{engine:U}:{},...H?{tabId:H}:{},...O?{detail:O}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{M.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[rove hook] ${Z} failed:`,X instanceof Error?X.message:String(X))}}function wZ0(){return I8.map(($)=>$R($)).filter(($)=>$.supportsWorktreeSync())}function Pk(){return I8.map(($)=>$R($)).filter(($)=>$.supportsHooks())}function Rk(){return XR(PZ0(),".claude","settings.json")}function xZ0($){if(!$||$==="off")return;if($==="global")return Rk();if($.startsWith("repo:"))return XR(JR($.slice(5)),".claude","settings.json");return $}async function QR(){try{let $=fZ0();for(let Z of Pk()){let J=Z.globalSettingsPath();if(!J)continue;await Z.installActivityHooks(J,{toolEvents:$}),await Z.installWorktreeWatchHook(J)}await Tk()}catch{}}function fZ0(){try{for(let $ of V5().plugins){if(!$.enabled)continue;try{let Z=DZ0(XR($.root,R2),"utf8");if(r2(Z).manifest.events.some((J)=>J.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function Tk(){let $=wZ0();if($.length===0)return;let Z=u7(jk),J=new Set([Rk()]),X=xZ0(Z);if(X)J.add(X);for(let z of $)for(let Y of J)await z.removeWorktreeSyncHook(Y);if(Z!=="off")n3(jk,"off")}async function gZ0($){await Tk(),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(`
|
|
285
|
-
`))}var RZ0=500,TZ0="worktree-created",jk="externalWorktreeSync";var zR=a(()=>{C2();KQ();jJ();eP();ZR();h4();v7()});var wL;var Ik=a(()=>{wL={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.
|
|
285
|
+
`))}var RZ0=500,TZ0="worktree-created",jk="externalWorktreeSync";var zR=a(()=>{C2();KQ();jJ();eP();ZR();h4();v7()});var wL;var Ik=a(()=>{wL={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.89",description:"Rove \u2014 the terminal-native agent multiplexer",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:"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:rove":"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.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.12","@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 wk={};g$(wk,{repoSlug:()=>KG,releasePageUrl:()=>UR,recommendedGlobalInstallCommand:()=>WR,isNewerSemver:()=>GR,fetchReleaseSummaries:()=>fK,fetchReleaseNotesRange:()=>qR,fetchReleaseNotes:()=>HR,compareSemver:()=>K3,checkLatestVersion:()=>FG,breakingVersionsCrossed:()=>xK,UPDATE_SCRIPT_URL:()=>xL,UPDATE_COMMAND:()=>QZ,PACKAGE_NAME:()=>YR,CURRENT_VERSION:()=>C$,BREAKING_VERSIONS:()=>AJ});function KG(){let $=wL.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function WR(){return`npm install -g ${YR}@latest`}function xK($,Z,J=AJ){let[X,z]=K3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>K3(Y,X)>0&&K3(Y,z)<=0)}async function bZ0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),fL);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 Y=await z.json();if(typeof Y.version!=="string")return null;return Y.version}catch{return null}finally{clearTimeout(J)}}function GR($,Z){return K3($,Z)>0}function K3($,Z){let J=(Y)=>Y.split("-")[0]??Y,X=J($).split(".").map((Y)=>Number.parseInt(Y,10)),z=J(Z).split(".").map((Y)=>Number.parseInt(Y,10));for(let Y=0;Y<3;Y++){let W=X[Y]??0,H=z[Y]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function FG($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:C$,latest:Z,hasUpdate:GR(Z,C$)};if(XH()&&!$.force)return null;let J=await bZ0(YR);if(!J)return null;return{current:C$,latest:J,hasUpdate:GR(J,C$)}}function Ek($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function HR($){let Z=KG();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),fL);try{let Y=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(!Y.ok)return null;let W=await Y.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 qR($){let Z=KG();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),fL);try{let Y=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(!Y.ok)return[];let W=await Y.json();if(!Array.isArray(W))return[];return W.map((H)=>{let U=Ek(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(K3(U,$.current)<=0)return null;if(K3(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 fK($=12){let Z=KG();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),fL);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 Y=await z.json();if(!Array.isArray(Y))return[];return Y.map((W)=>{let H=Ek(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 UR($){let Z=KG();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var C$,YR,xL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",QZ,AJ,fL=3000;var f8=a(()=>{Ik();j5();C$=wL.version,YR=wL.name;QZ=`curl -fsSL ${xL} | sh`;AJ=[]});var fk={};g$(fk,{stampResetGate:()=>gL,resetGateBlockers:()=>xk,enforceResetGate:()=>KR,LAST_RUN_VERSION_KEY:()=>BR});function xk($,Z=C$,J=AJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=K3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>K3(Y,X)>0&&K3(Y,z)<=0)}function KR(){let $=X$(),Z=C4()[BR],J=xk(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${C$}: 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(`
|
|
286
286
|
`)),process.exit(1)}if(Z!==C$)gL()}function gL(){try{i2({[BR]:C$})}catch{}}var BR="app.lastRunVersion";var yL=a(()=>{A2();f8();a4()});import{existsSync as yk,readFileSync as kZ0}from"fs";import{homedir as vZ0}from"os";import{join as bk,resolve as gk}from"path";import{fileURLToPath as mZ0}from"url";function OR($=process.env){return`${X$($)} skill install`}function bL(){let $=mZ0(import.meta.url);return[gk($,"../../../../../.agents/skills/kobe"),gk($,"../../skills/kobe")].find((J)=>yk(bk(J,"SKILL.md")))??null}function kL($={}){let Z=$.source!==void 0?$.source:bL(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??uZ0,"--skill",T8,...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function MG($={}){return`npx ${kL($).join(" ")}`}async function NR($,Z){return await Bun.spawn(["npx",...kL({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function vL($={}){let Z=$.home??vZ0(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>hZ0.map((z)=>bk(X,z)))}function cZ0($){let Z=$.match(/kobe-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function gK($){let Z=vL($).find((z)=>yk(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:FR,stale:!1};let J=null;try{J=cZ0(kZ0(Z,"utf8"))}catch{J=null}let X=J===null||J<FR;return{installed:!0,installedVersion:J,currentVersion:FR,stale:X}}function dZ0(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function kk($={}){let Z=X$(),J=OR(),X=gK();if(!X.installed){if(u7(MR)==="1")return;n3(MR,"1"),process.stderr.write(`
|
|
287
287
|
${Z}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${Z} api\`:
|
|
288
288
|
${J}
|
package/dist/cli/kobe.js
CHANGED
|
@@ -282,7 +282,7 @@ ${z}`,Z);this.line=J,this.column=X,this.codeblock=z}}});function XL($,Z){let J=$
|
|
|
282
282
|
`)){if(!J.trim())continue;try{let{sessionId:X,sessionDir:z,workDir:Y}=JSON.parse(J);if(X&&z&&Y)Z.push({sessionId:X,sessionDir:z,workDir:Y})}catch{}}return Z}async function tb($){let Z=await $.readFile(PL.join($.kimiDir(),"session_index.jsonl")).catch(()=>"");return FZ0(Z)}function eb($){return PL.join($,"agents","main","wire.jsonl")}async function nP($,Z=pP){if(!$)return[];let J=[];for(let X of await tb(Z)){if(X.workDir!==$)continue;let z=await Z.stat(eb(X.sessionDir)).then((Y)=>Y.mtimeMs).catch(()=>null);if(z===null)continue;J.push({id:X.sessionId,mtimeMs:z})}return J.sort((X,z)=>X.mtimeMs-z.mtimeMs).map((X)=>X.id)}async function $k($,Z=pP){return await Z.stat($).then((J)=>J.mtimeMs).catch(()=>0)}async function iP($,Z=pP){if(!$)return null;let J=(await tb(Z)).find((z)=>z.sessionId===$);if(!J)return null;let X=eb(J.sessionDir);return await Z.stat(X).then(()=>X).catch(()=>null)}var pP;var Zk=a(()=>{LQ();pP={kimiDir(){return process.env.KIMI_CODE_HOME?.trim()||PL.join(KZ0(),".kimi-code")},async readFile($){return await NQ($)},stat:BZ0}});import OZ0 from"path";var RL,Jk,Xk,Qk,zk;var Gk=a(()=>{hP();_L();sb();Zk();RL={async listSessionIdsForWorktree(){return[]},async readHistory(){return[]},async transcriptPath(){return null},async latestTranscriptMtimeForWorktree(){return 0}},Jk={async listSessionIdsForWorktree($){return[...await wH($)].sort((J,X)=>J.mtimeMs-X.mtimeMs).map((J)=>J.sessionId)},readHistory:($)=>pb($),async transcriptPath($,Z){return(await wH(Z)).find((X)=>X.sessionId===$)?.path??null},latestTranscriptMtimeForWorktree:($)=>lb($)},Xk={listSessionIdsForWorktree:($)=>wb($),readHistory:($)=>fb($),transcriptPath:async($)=>await bP($)??null,latestTranscriptMtimeForWorktree:($)=>xb($)},Qk={listSessionIdsForWorktree:($)=>ob($),readHistory:($)=>rb($),async transcriptPath($){let Z=await dP($);return Z?OZ0.join(Z,"events.jsonl"):null},latestTranscriptMtimeForWorktree:($)=>ab($)},zk={listSessionIdsForWorktree:($)=>nP($),readHistory:RL.readHistory,transcriptPath:($)=>iP($),async latestTranscriptMtimeForWorktree($){let J=(await nP($)).at(-1);if(!J)return 0;let X=await iP(J);return X?await $k(X):0}}});var TL,Yk,Wk;var SL=a(()=>{TL=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Yk=["\xB7","\u2722","\u2731","\u2736","\u273B","\u273D"],Wk=[...Yk,...[...Yk].reverse()]});import{readFile as qk,stat as NZ0}from"fs/promises";class IL{supportsCompletionMarkers(){return!0}async latestCompletion($){return(await this.latestActivity($)).marker}async latestActivityInFile($){return null}}function Uk($){return E$($).createTurnDetector()}function Hk($,Z="claude",J=0){let X=null,z=0;for(let Y of $.split(`
|
|
283
283
|
`)){z++;let W=Kk(Y);if(!W)continue;let H=rP(W.message)?W.message:W;if(H.role!=="assistant")continue;if(!("content"in H))continue;let U=Fk(W,J),K={id:`claude:${Z}:${U}:${z}`,timestampMs:U,source:"claude"};if(!X||K.timestampMs>=X.timestampMs)X=K}return X}function _Z0($){if($.type==="turn.completed")return!0;if($.type!=="event_msg")return!1;let Z=rP($.payload)?$.payload:void 0;return typeof Z?.type==="string"&&VZ0.has(Z.type)}function CZ0($,Z="codex"){let J=null,X=0;for(let z of $.split(`
|
|
284
284
|
`)){X++;let Y=Kk(z);if(!Y||!_Z0(Y))continue;let W=Fk(Y,0),H={id:`codex:${Z}:${W}:${X}`,timestampMs:W,source:"codex"};if(!J||H.timestampMs>=J.timestampMs)J=H}return J}function Kk($){let Z=$.trim();if(!Z)return null;try{let J=JSON.parse(Z);return rP(J)?J:null}catch{return null}}function Fk($,Z){let J=typeof $.timestamp==="string"?Date.parse($.timestamp):Number.NaN;return Number.isFinite(J)?J:Z}function rP($){return typeof $==="object"&&$!==null&&!Array.isArray($)}var Bk=($)=>NZ0($).then((Z)=>Z.mtimeMs,()=>0),LZ0,oP,jZ0,aP,EK,VZ0;var sP=a(()=>{hP();_L();c7();LZ0={listSessionFiles:($)=>wH($),readFile:($)=>qk($,"utf8"),statMtimeMs:Bk};oP=class oP extends IL{deps;vendor="claude";cache=new Map;constructor($=LZ0){super();this.deps=$}async latestActivity($){let Z=await this.deps.listSessionFiles($),J=Z[0]?.mtimeMs??0,X=null,z=new Map;for(let Y of Z.slice(0,4)){let W=this.cache.get(Y.path),H;if(W&&Y.mtimeMs>0&&W.mtimeMs===Y.mtimeMs)H=W.marker;else{let U=await this.deps.readFile(Y.path).catch(()=>"");H=Hk(U,Y.path,Y.mtimeMs)}if(z.set(Y.path,{mtimeMs:Y.mtimeMs,marker:H}),H&&(!X||H.timestampMs>X.timestampMs))X=H}return this.cache=z,{marker:X,mtimeMs:J}}async latestActivityInFile($){let Z=await(this.deps.statMtimeMs??Bk)($);if(Z===0)return null;let J=await this.deps.readFile($).catch(()=>"");return{marker:Hk(J,$,Z),mtimeMs:Z}}};jZ0={findLatestRollout:($)=>kP($),readFile:($)=>qk($,"utf8")};aP=class aP extends IL{deps;vendor="codex";cache=null;constructor($=jZ0){super();this.deps=$}async latestActivity($){if(!$)return{marker:null,mtimeMs:0};let Z=await this.deps.findLatestRollout($);if(!Z)return{marker:null,mtimeMs:0};if(this.cache&&this.cache.path===Z.path&&Z.mtimeMs>0&&this.cache.mtimeMs===Z.mtimeMs)return{marker:this.cache.marker,mtimeMs:Z.mtimeMs};let J=await this.deps.readFile(Z.path).catch(()=>"");if(!J)return{marker:null,mtimeMs:Z.mtimeMs};let X=CZ0(J,Z.path);return this.cache={path:Z.path,mtimeMs:Z.mtimeMs,marker:X},{marker:X,mtimeMs:Z.mtimeMs}}};EK=class EK extends IL{vendor;constructor($){super();this.vendor=$}supportsCompletionMarkers(){return!1}async latestActivity(){return{marker:null,mtimeMs:0}}};VZ0=new Set(["task_complete","turn_complete","turn_aborted"])});function AZ0($){return{vendor:$,builtin:!1,displayName:$,defaultCommand:[$],history:RL,detectAccount:async()=>({binary:{found:!1,error:"custom engine: Rove has no account detector for it"},account:{kind:"none"}}),createHookAdapter:()=>new wK($),createTurnDetector:()=>new EK($)}}function E$($){return k7($)?tP[$]:AZ0($)}function Mk($){return E$($).history.readHistory!==RL.readHistory}function eP($){let Z=E$($).terminalTitle?.statusPrefixes;return Z&&Z.length>0?Z:Ok}function xH($,Z){let J=Z?eP(Z):Ok;for(let X of[...J].sort((z,Y)=>Y.length-z.length)){if(!$.startsWith(X))continue;let z=$.slice(X.length).trimStart();if(z.length===0)return $;return z}return $}function EL($,Z){let J=E$($).terminalTitle,X=J?.workingPrefixes;if(J?.ownsStatus!==!0||!X||X.length===0)return null;let z=Z.trim();if(z.length===0)return null;return X.some((Y)=>z.startsWith(Y))?"working":"rest"}function Nk(){return Object.values(tP).filter(($)=>$.quotaUsage).map(($)=>$.vendor)}var tP,Ok;var c7=a(()=>{v7();_J();Zb();Wb();Fb();Nb();jb();kb();Gk();$R();SL();sP();tP={claude:{vendor:"claude",builtin:!0,displayName:"Claude",defaultCommand:["claude"],history:Jk,detectAccount:($)=>DH($),createHookAdapter:()=>new DP,createTurnDetector:()=>new oP,capabilities:ey,identity:$b,spinnerFrames:Wk,terminalTitle:{ownsStatus:!0,statusPrefixes:["\u2733","\u2802","\u2810","\u25D0","\u25D1"],workingPrefixes:["\u2802","\u2810","\u25D0","\u25D1"]},quotaUsage:()=>Kb()},codex:{vendor:"codex",builtin:!0,displayName:"Codex",defaultCommand:["codex"],effortLevels:["none","low","medium","high","xhigh"],history:Xk,detectAccount:($)=>PH($),createHookAdapter:()=>new SP,createTurnDetector:()=>new aP,capabilities:Mb,identity:Ob,terminalTitle:{ownsStatus:!0,launchArgs:["-c",'tui.terminal_title=["activity","thread-title"]'],statusPrefixes:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],workingPrefixes:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"]},quotaUsage:()=>bb()},copilot:{vendor:"copilot",builtin:!0,displayName:"Copilot",defaultCommand:["copilot"],history:Qk,detectAccount:($)=>RH($),createHookAdapter:()=>new wK("copilot"),createTurnDetector:()=>new EK("copilot")},kimi:{vendor:"kimi",builtin:!0,displayName:"Kimi",defaultCommand:["kimi"],history:zk,detectAccount:($)=>ML($),createHookAdapter:()=>new wK("kimi"),createTurnDetector:()=>new EK("kimi")}};Ok=[...new Set(Object.values(tP).flatMap(($)=>$.terminalTitle?.statusPrefixes??[]))]});function ZR($){return E$($).createHookAdapter()}class wK{vendor;constructor($){this.vendor=$}supportsHooks(){return!1}globalSettingsPath(){return""}activityDetailFromPayload(){return}sessionFromPayload(){return}async installActivityHooks(){}async removeActivityHooks(){}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async installWorktreeWatchHook(){}async removeWorktreeWatchHook(){}}var $R=a(()=>{c7()});function wL($){return DZ0.includes($)}function Lk($){return PZ0.includes($)}var DZ0,PZ0;var JR=a(()=>{DZ0=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end","tool-pre","tool-post","tool-failed","pre-compact","post-compact","subagent-start","subagent-stop"];PZ0=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end"]});var Ik={};g$(Ik,{runHookSubcommand:()=>xZ0,readTextWithTimeout:()=>_k,parseWorktreeRemovePath:()=>Pk,parseWorktreeAddPath:()=>Dk,ensureGlobalKobeHooks:()=>zR});import{readFileSync as RZ0}from"fs";import{homedir as TZ0}from"os";import{join as QR,resolve as XR}from"path";async function _k($,Z=SZ0){let J;try{return await Promise.race([$(),new Promise((X)=>{J=setTimeout(()=>X(""),Z)})])}finally{if(J!==void 0)clearTimeout(J)}}async function Ck(){try{let $=await _k(()=>Bun.stdin.text());if(!$.trim())return{};let Z=JSON.parse($);return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:{}}catch{return{}}}function jk($,Z){for(let J=0;J<$.length;J++){if($[J]===Z)return $[J+1];if($[J].startsWith(`${Z}=`))return $[J].slice(Z.length+1)}return}function EZ0($){return!!$&&typeof $==="object"&&!Array.isArray($)}function Ak($){let Z=[],J=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=J.exec($))!==null)Z.push(X[1]??X[2]??X[3]??"");return Z}function Dk($){let Z=Ak($),J=new Set(["-b","-B","--reason"]);for(let X=0;X+1<Z.length;X++){if(Z[X]!=="worktree"||Z[X+1]!=="add")continue;let z=X+2;while(z<Z.length){let Y=Z[z];if(Y==="&&"||Y==="||"||Y===";"||Y==="|"||Y===">"||Y===">>")break;if(Y.startsWith("-")){z+=J.has(Y)?2:1;continue}return Y}}return}function Pk($){let Z=Ak($);for(let J=0;J+1<Z.length;J++){if(Z[J]!=="worktree"||Z[J+1]!=="remove")continue;let X=J+2;while(X<Z.length){let z=Z[X];if(z==="&&"||z==="||"||z===";"||z==="|"||z===">"||z===">>")break;if(z.startsWith("-")){X+=1;continue}return z}}return}async function wZ0(){let $=await Ck(),Z=EZ0($.tool_input)?$.tool_input:{},J=typeof Z.command==="string"?Z.command:"";if(!J.includes("worktree"))return;let X=typeof $.cwd==="string"&&$.cwd?$.cwd:process.cwd(),z=Dk(J),Y=z?void 0:Pk(J);if(!z&&!Y)return;let W=await GQ();if(!W)return;try{if(z)await W.request("worktree.reconcile",{cwd:X,worktreePath:XR(X,z)});else if(Y)await W.request("worktree.archiveRemoved",{worktreePath:XR(X,Y)})}finally{W.close()}}async function xZ0($){let[Z,...J]=$;if(Z==="setup"){await bZ0(J);return}if(Z===IZ0){try{await wZ0()}catch{}return}try{if(!Z||!wL(Z))return;let X=await Ck(),z=jk(J,"--task-id"),Y=typeof X.cwd==="string"&&X.cwd?X.cwd:process.cwd(),W=process.env.KOBE_TASK_ID,H=process.env.KOBE_TAB_ID,U=jk(J,"--engine"),K=Rk().filter((_)=>!U||_.vendor===U),O;for(let _ of K)if(O=_.activityDetailFromPayload(Z,X),O)break;let L;for(let _ of K)if(L=_.sessionFromPayload(X),L)break;let M=await GQ();if(!M)return;try{let _=z??W;await M.request("engine.reportEvent",{..._?{taskId:_}:{cwd:Y},kind:Z,...U?{engine:U}:{},...H?{tabId:H}:{},...O?{detail:O}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{M.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[rove hook] ${Z} failed:`,X instanceof Error?X.message:String(X))}}function fZ0(){return I8.map(($)=>ZR($)).filter(($)=>$.supportsWorktreeSync())}function Rk(){return I8.map(($)=>ZR($)).filter(($)=>$.supportsHooks())}function Tk(){return QR(TZ0(),".claude","settings.json")}function gZ0($){if(!$||$==="off")return;if($==="global")return Tk();if($.startsWith("repo:"))return QR(XR($.slice(5)),".claude","settings.json");return $}async function zR(){try{let $=yZ0();for(let Z of Rk()){let J=Z.globalSettingsPath();if(!J)continue;await Z.installActivityHooks(J,{toolEvents:$}),await Z.installWorktreeWatchHook(J)}await Sk()}catch{}}function yZ0(){try{for(let $ of V5().plugins){if(!$.enabled)continue;try{let Z=RZ0(QR($.root,R2),"utf8");if(r2(Z).manifest.events.some((J)=>J.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function Sk(){let $=fZ0();if($.length===0)return;let Z=u7(Vk),J=new Set([Tk()]),X=gZ0(Z);if(X)J.add(X);for(let z of $)for(let Y of J)await z.removeWorktreeSyncHook(Y);if(Z!=="off")n3(Vk,"off")}async function bZ0($){await Sk(),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(`
|
|
285
|
-
`))}var SZ0=500,IZ0="worktree-created",Vk="externalWorktreeSync";var GR=a(()=>{C2();KQ();jJ();$R();JR();u4();v7()});var xL;var Ek=a(()=>{xL={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.
|
|
285
|
+
`))}var SZ0=500,IZ0="worktree-created",Vk="externalWorktreeSync";var GR=a(()=>{C2();KQ();jJ();$R();JR();u4();v7()});var xL;var Ek=a(()=>{xL={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.89",description:"Rove \u2014 the terminal-native agent multiplexer",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:"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:rove":"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.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.12","@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 xk={};g$(xk,{repoSlug:()=>KG,releasePageUrl:()=>BR,recommendedGlobalInstallCommand:()=>HR,isNewerSemver:()=>YR,fetchReleaseSummaries:()=>fK,fetchReleaseNotesRange:()=>UR,fetchReleaseNotes:()=>qR,compareSemver:()=>K3,checkLatestVersion:()=>FG,breakingVersionsCrossed:()=>xK,UPDATE_SCRIPT_URL:()=>fL,UPDATE_COMMAND:()=>QZ,PACKAGE_NAME:()=>WR,CURRENT_VERSION:()=>C$,BREAKING_VERSIONS:()=>AJ});function KG(){let $=xL.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function HR(){return`npm install -g ${WR}@latest`}function xK($,Z,J=AJ){let[X,z]=K3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>K3(Y,X)>0&&K3(Y,z)<=0)}async function vZ0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),gL);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 Y=await z.json();if(typeof Y.version!=="string")return null;return Y.version}catch{return null}finally{clearTimeout(J)}}function YR($,Z){return K3($,Z)>0}function K3($,Z){let J=(Y)=>Y.split("-")[0]??Y,X=J($).split(".").map((Y)=>Number.parseInt(Y,10)),z=J(Z).split(".").map((Y)=>Number.parseInt(Y,10));for(let Y=0;Y<3;Y++){let W=X[Y]??0,H=z[Y]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function FG($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:C$,latest:Z,hasUpdate:YR(Z,C$)};if(XH()&&!$.force)return null;let J=await vZ0(WR);if(!J)return null;return{current:C$,latest:J,hasUpdate:YR(J,C$)}}function wk($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function qR($){let Z=KG();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),gL);try{let Y=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(!Y.ok)return null;let W=await Y.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 UR($){let Z=KG();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),gL);try{let Y=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(!Y.ok)return[];let W=await Y.json();if(!Array.isArray(W))return[];return W.map((H)=>{let U=wk(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(K3(U,$.current)<=0)return null;if(K3(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 fK($=12){let Z=KG();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),gL);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 Y=await z.json();if(!Array.isArray(Y))return[];return Y.map((W)=>{let H=wk(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 BR($){let Z=KG();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var C$,WR,fL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",QZ,AJ,gL=3000;var f8=a(()=>{Ek();j5();C$=xL.version,WR=xL.name;QZ=`curl -fsSL ${fL} | sh`;AJ=[]});var gk={};g$(gk,{stampResetGate:()=>yL,resetGateBlockers:()=>fk,enforceResetGate:()=>FR,LAST_RUN_VERSION_KEY:()=>KR});function fk($,Z=C$,J=AJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=K3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>K3(Y,X)>0&&K3(Y,z)<=0)}function FR(){let $=X$(),Z=C4()[KR],J=fk(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${C$}: 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(`
|
|
286
286
|
`)),process.exit(1)}if(Z!==C$)yL()}function yL(){try{i2({[KR]:C$})}catch{}}var KR="app.lastRunVersion";var bL=a(()=>{A2();f8();h4()});import{existsSync as bk,readFileSync as mZ0}from"fs";import{homedir as hZ0}from"os";import{join as kk,resolve as yk}from"path";import{fileURLToPath as uZ0}from"url";function NR($=process.env){return`${X$($)} skill install`}function kL(){let $=uZ0(import.meta.url);return[yk($,"../../../../../.agents/skills/kobe"),yk($,"../../skills/kobe")].find((J)=>bk(kk(J,"SKILL.md")))??null}function vL($={}){let Z=$.source!==void 0?$.source:kL(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??dZ0,"--skill",T8,...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function MG($={}){return`npx ${vL($).join(" ")}`}async function LR($,Z){return await Bun.spawn(["npx",...vL({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function mL($={}){let Z=$.home??hZ0(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>cZ0.map((z)=>kk(X,z)))}function lZ0($){let Z=$.match(/kobe-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function gK($){let Z=mL($).find((z)=>bk(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:MR,stale:!1};let J=null;try{J=lZ0(mZ0(Z,"utf8"))}catch{J=null}let X=J===null||J<MR;return{installed:!0,installedVersion:J,currentVersion:MR,stale:X}}function pZ0(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function vk($={}){let Z=X$(),J=NR(),X=gK();if(!X.installed){if(u7(OR)==="1")return;n3(OR,"1"),process.stderr.write(`
|
|
287
287
|
${Z}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${Z} api\`:
|
|
288
288
|
${J}
|
package/dist/cli/rove.js
CHANGED
|
@@ -282,7 +282,7 @@ ${z}`,Z);this.line=J,this.column=X,this.codeblock=z}}});function XL($,Z){let J=$
|
|
|
282
282
|
`)){if(!J.trim())continue;try{let{sessionId:X,sessionDir:z,workDir:Y}=JSON.parse(J);if(X&&z&&Y)Z.push({sessionId:X,sessionDir:z,workDir:Y})}catch{}}return Z}async function tb($){let Z=await $.readFile(PL.join($.kimiDir(),"session_index.jsonl")).catch(()=>"");return FZ0(Z)}function eb($){return PL.join($,"agents","main","wire.jsonl")}async function nP($,Z=pP){if(!$)return[];let J=[];for(let X of await tb(Z)){if(X.workDir!==$)continue;let z=await Z.stat(eb(X.sessionDir)).then((Y)=>Y.mtimeMs).catch(()=>null);if(z===null)continue;J.push({id:X.sessionId,mtimeMs:z})}return J.sort((X,z)=>X.mtimeMs-z.mtimeMs).map((X)=>X.id)}async function $k($,Z=pP){return await Z.stat($).then((J)=>J.mtimeMs).catch(()=>0)}async function iP($,Z=pP){if(!$)return null;let J=(await tb(Z)).find((z)=>z.sessionId===$);if(!J)return null;let X=eb(J.sessionDir);return await Z.stat(X).then(()=>X).catch(()=>null)}var pP;var Zk=a(()=>{LQ();pP={kimiDir(){return process.env.KIMI_CODE_HOME?.trim()||PL.join(KZ0(),".kimi-code")},async readFile($){return await NQ($)},stat:BZ0}});import OZ0 from"path";var RL,Jk,Xk,Qk,zk;var Gk=a(()=>{hP();_L();sb();Zk();RL={async listSessionIdsForWorktree(){return[]},async readHistory(){return[]},async transcriptPath(){return null},async latestTranscriptMtimeForWorktree(){return 0}},Jk={async listSessionIdsForWorktree($){return[...await wH($)].sort((J,X)=>J.mtimeMs-X.mtimeMs).map((J)=>J.sessionId)},readHistory:($)=>pb($),async transcriptPath($,Z){return(await wH(Z)).find((X)=>X.sessionId===$)?.path??null},latestTranscriptMtimeForWorktree:($)=>lb($)},Xk={listSessionIdsForWorktree:($)=>wb($),readHistory:($)=>fb($),transcriptPath:async($)=>await bP($)??null,latestTranscriptMtimeForWorktree:($)=>xb($)},Qk={listSessionIdsForWorktree:($)=>ob($),readHistory:($)=>rb($),async transcriptPath($){let Z=await dP($);return Z?OZ0.join(Z,"events.jsonl"):null},latestTranscriptMtimeForWorktree:($)=>ab($)},zk={listSessionIdsForWorktree:($)=>nP($),readHistory:RL.readHistory,transcriptPath:($)=>iP($),async latestTranscriptMtimeForWorktree($){let J=(await nP($)).at(-1);if(!J)return 0;let X=await iP(J);return X?await $k(X):0}}});var TL,Yk,Wk;var SL=a(()=>{TL=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Yk=["\xB7","\u2722","\u2731","\u2736","\u273B","\u273D"],Wk=[...Yk,...[...Yk].reverse()]});import{readFile as qk,stat as NZ0}from"fs/promises";class IL{supportsCompletionMarkers(){return!0}async latestCompletion($){return(await this.latestActivity($)).marker}async latestActivityInFile($){return null}}function Uk($){return E$($).createTurnDetector()}function Hk($,Z="claude",J=0){let X=null,z=0;for(let Y of $.split(`
|
|
283
283
|
`)){z++;let W=Kk(Y);if(!W)continue;let H=rP(W.message)?W.message:W;if(H.role!=="assistant")continue;if(!("content"in H))continue;let U=Fk(W,J),K={id:`claude:${Z}:${U}:${z}`,timestampMs:U,source:"claude"};if(!X||K.timestampMs>=X.timestampMs)X=K}return X}function _Z0($){if($.type==="turn.completed")return!0;if($.type!=="event_msg")return!1;let Z=rP($.payload)?$.payload:void 0;return typeof Z?.type==="string"&&VZ0.has(Z.type)}function CZ0($,Z="codex"){let J=null,X=0;for(let z of $.split(`
|
|
284
284
|
`)){X++;let Y=Kk(z);if(!Y||!_Z0(Y))continue;let W=Fk(Y,0),H={id:`codex:${Z}:${W}:${X}`,timestampMs:W,source:"codex"};if(!J||H.timestampMs>=J.timestampMs)J=H}return J}function Kk($){let Z=$.trim();if(!Z)return null;try{let J=JSON.parse(Z);return rP(J)?J:null}catch{return null}}function Fk($,Z){let J=typeof $.timestamp==="string"?Date.parse($.timestamp):Number.NaN;return Number.isFinite(J)?J:Z}function rP($){return typeof $==="object"&&$!==null&&!Array.isArray($)}var Bk=($)=>NZ0($).then((Z)=>Z.mtimeMs,()=>0),LZ0,oP,jZ0,aP,EK,VZ0;var sP=a(()=>{hP();_L();c7();LZ0={listSessionFiles:($)=>wH($),readFile:($)=>qk($,"utf8"),statMtimeMs:Bk};oP=class oP extends IL{deps;vendor="claude";cache=new Map;constructor($=LZ0){super();this.deps=$}async latestActivity($){let Z=await this.deps.listSessionFiles($),J=Z[0]?.mtimeMs??0,X=null,z=new Map;for(let Y of Z.slice(0,4)){let W=this.cache.get(Y.path),H;if(W&&Y.mtimeMs>0&&W.mtimeMs===Y.mtimeMs)H=W.marker;else{let U=await this.deps.readFile(Y.path).catch(()=>"");H=Hk(U,Y.path,Y.mtimeMs)}if(z.set(Y.path,{mtimeMs:Y.mtimeMs,marker:H}),H&&(!X||H.timestampMs>X.timestampMs))X=H}return this.cache=z,{marker:X,mtimeMs:J}}async latestActivityInFile($){let Z=await(this.deps.statMtimeMs??Bk)($);if(Z===0)return null;let J=await this.deps.readFile($).catch(()=>"");return{marker:Hk(J,$,Z),mtimeMs:Z}}};jZ0={findLatestRollout:($)=>kP($),readFile:($)=>qk($,"utf8")};aP=class aP extends IL{deps;vendor="codex";cache=null;constructor($=jZ0){super();this.deps=$}async latestActivity($){if(!$)return{marker:null,mtimeMs:0};let Z=await this.deps.findLatestRollout($);if(!Z)return{marker:null,mtimeMs:0};if(this.cache&&this.cache.path===Z.path&&Z.mtimeMs>0&&this.cache.mtimeMs===Z.mtimeMs)return{marker:this.cache.marker,mtimeMs:Z.mtimeMs};let J=await this.deps.readFile(Z.path).catch(()=>"");if(!J)return{marker:null,mtimeMs:Z.mtimeMs};let X=CZ0(J,Z.path);return this.cache={path:Z.path,mtimeMs:Z.mtimeMs,marker:X},{marker:X,mtimeMs:Z.mtimeMs}}};EK=class EK extends IL{vendor;constructor($){super();this.vendor=$}supportsCompletionMarkers(){return!1}async latestActivity(){return{marker:null,mtimeMs:0}}};VZ0=new Set(["task_complete","turn_complete","turn_aborted"])});function AZ0($){return{vendor:$,builtin:!1,displayName:$,defaultCommand:[$],history:RL,detectAccount:async()=>({binary:{found:!1,error:"custom engine: Rove has no account detector for it"},account:{kind:"none"}}),createHookAdapter:()=>new wK($),createTurnDetector:()=>new EK($)}}function E$($){return k7($)?tP[$]:AZ0($)}function Mk($){return E$($).history.readHistory!==RL.readHistory}function eP($){let Z=E$($).terminalTitle?.statusPrefixes;return Z&&Z.length>0?Z:Ok}function xH($,Z){let J=Z?eP(Z):Ok;for(let X of[...J].sort((z,Y)=>Y.length-z.length)){if(!$.startsWith(X))continue;let z=$.slice(X.length).trimStart();if(z.length===0)return $;return z}return $}function EL($,Z){let J=E$($).terminalTitle,X=J?.workingPrefixes;if(J?.ownsStatus!==!0||!X||X.length===0)return null;let z=Z.trim();if(z.length===0)return null;return X.some((Y)=>z.startsWith(Y))?"working":"rest"}function Nk(){return Object.values(tP).filter(($)=>$.quotaUsage).map(($)=>$.vendor)}var tP,Ok;var c7=a(()=>{v7();_J();Zb();Wb();Fb();Nb();jb();kb();Gk();$R();SL();sP();tP={claude:{vendor:"claude",builtin:!0,displayName:"Claude",defaultCommand:["claude"],history:Jk,detectAccount:($)=>DH($),createHookAdapter:()=>new DP,createTurnDetector:()=>new oP,capabilities:ey,identity:$b,spinnerFrames:Wk,terminalTitle:{ownsStatus:!0,statusPrefixes:["\u2733","\u2802","\u2810","\u25D0","\u25D1"],workingPrefixes:["\u2802","\u2810","\u25D0","\u25D1"]},quotaUsage:()=>Kb()},codex:{vendor:"codex",builtin:!0,displayName:"Codex",defaultCommand:["codex"],effortLevels:["none","low","medium","high","xhigh"],history:Xk,detectAccount:($)=>PH($),createHookAdapter:()=>new SP,createTurnDetector:()=>new aP,capabilities:Mb,identity:Ob,terminalTitle:{ownsStatus:!0,launchArgs:["-c",'tui.terminal_title=["activity","thread-title"]'],statusPrefixes:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],workingPrefixes:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"]},quotaUsage:()=>bb()},copilot:{vendor:"copilot",builtin:!0,displayName:"Copilot",defaultCommand:["copilot"],history:Qk,detectAccount:($)=>RH($),createHookAdapter:()=>new wK("copilot"),createTurnDetector:()=>new EK("copilot")},kimi:{vendor:"kimi",builtin:!0,displayName:"Kimi",defaultCommand:["kimi"],history:zk,detectAccount:($)=>ML($),createHookAdapter:()=>new wK("kimi"),createTurnDetector:()=>new EK("kimi")}};Ok=[...new Set(Object.values(tP).flatMap(($)=>$.terminalTitle?.statusPrefixes??[]))]});function ZR($){return E$($).createHookAdapter()}class wK{vendor;constructor($){this.vendor=$}supportsHooks(){return!1}globalSettingsPath(){return""}activityDetailFromPayload(){return}sessionFromPayload(){return}async installActivityHooks(){}async removeActivityHooks(){}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async installWorktreeWatchHook(){}async removeWorktreeWatchHook(){}}var $R=a(()=>{c7()});function wL($){return DZ0.includes($)}function Lk($){return PZ0.includes($)}var DZ0,PZ0;var JR=a(()=>{DZ0=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end","tool-pre","tool-post","tool-failed","pre-compact","post-compact","subagent-start","subagent-stop"];PZ0=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end"]});var Ik={};g$(Ik,{runHookSubcommand:()=>xZ0,readTextWithTimeout:()=>_k,parseWorktreeRemovePath:()=>Pk,parseWorktreeAddPath:()=>Dk,ensureGlobalKobeHooks:()=>zR});import{readFileSync as RZ0}from"fs";import{homedir as TZ0}from"os";import{join as QR,resolve as XR}from"path";async function _k($,Z=SZ0){let J;try{return await Promise.race([$(),new Promise((X)=>{J=setTimeout(()=>X(""),Z)})])}finally{if(J!==void 0)clearTimeout(J)}}async function Ck(){try{let $=await _k(()=>Bun.stdin.text());if(!$.trim())return{};let Z=JSON.parse($);return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:{}}catch{return{}}}function jk($,Z){for(let J=0;J<$.length;J++){if($[J]===Z)return $[J+1];if($[J].startsWith(`${Z}=`))return $[J].slice(Z.length+1)}return}function EZ0($){return!!$&&typeof $==="object"&&!Array.isArray($)}function Ak($){let Z=[],J=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=J.exec($))!==null)Z.push(X[1]??X[2]??X[3]??"");return Z}function Dk($){let Z=Ak($),J=new Set(["-b","-B","--reason"]);for(let X=0;X+1<Z.length;X++){if(Z[X]!=="worktree"||Z[X+1]!=="add")continue;let z=X+2;while(z<Z.length){let Y=Z[z];if(Y==="&&"||Y==="||"||Y===";"||Y==="|"||Y===">"||Y===">>")break;if(Y.startsWith("-")){z+=J.has(Y)?2:1;continue}return Y}}return}function Pk($){let Z=Ak($);for(let J=0;J+1<Z.length;J++){if(Z[J]!=="worktree"||Z[J+1]!=="remove")continue;let X=J+2;while(X<Z.length){let z=Z[X];if(z==="&&"||z==="||"||z===";"||z==="|"||z===">"||z===">>")break;if(z.startsWith("-")){X+=1;continue}return z}}return}async function wZ0(){let $=await Ck(),Z=EZ0($.tool_input)?$.tool_input:{},J=typeof Z.command==="string"?Z.command:"";if(!J.includes("worktree"))return;let X=typeof $.cwd==="string"&&$.cwd?$.cwd:process.cwd(),z=Dk(J),Y=z?void 0:Pk(J);if(!z&&!Y)return;let W=await GQ();if(!W)return;try{if(z)await W.request("worktree.reconcile",{cwd:X,worktreePath:XR(X,z)});else if(Y)await W.request("worktree.archiveRemoved",{worktreePath:XR(X,Y)})}finally{W.close()}}async function xZ0($){let[Z,...J]=$;if(Z==="setup"){await bZ0(J);return}if(Z===IZ0){try{await wZ0()}catch{}return}try{if(!Z||!wL(Z))return;let X=await Ck(),z=jk(J,"--task-id"),Y=typeof X.cwd==="string"&&X.cwd?X.cwd:process.cwd(),W=process.env.KOBE_TASK_ID,H=process.env.KOBE_TAB_ID,U=jk(J,"--engine"),K=Rk().filter((_)=>!U||_.vendor===U),O;for(let _ of K)if(O=_.activityDetailFromPayload(Z,X),O)break;let L;for(let _ of K)if(L=_.sessionFromPayload(X),L)break;let M=await GQ();if(!M)return;try{let _=z??W;await M.request("engine.reportEvent",{..._?{taskId:_}:{cwd:Y},kind:Z,...U?{engine:U}:{},...H?{tabId:H}:{},...O?{detail:O}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{M.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[rove hook] ${Z} failed:`,X instanceof Error?X.message:String(X))}}function fZ0(){return I8.map(($)=>ZR($)).filter(($)=>$.supportsWorktreeSync())}function Rk(){return I8.map(($)=>ZR($)).filter(($)=>$.supportsHooks())}function Tk(){return QR(TZ0(),".claude","settings.json")}function gZ0($){if(!$||$==="off")return;if($==="global")return Tk();if($.startsWith("repo:"))return QR(XR($.slice(5)),".claude","settings.json");return $}async function zR(){try{let $=yZ0();for(let Z of Rk()){let J=Z.globalSettingsPath();if(!J)continue;await Z.installActivityHooks(J,{toolEvents:$}),await Z.installWorktreeWatchHook(J)}await Sk()}catch{}}function yZ0(){try{for(let $ of V5().plugins){if(!$.enabled)continue;try{let Z=RZ0(QR($.root,R2),"utf8");if(r2(Z).manifest.events.some((J)=>J.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function Sk(){let $=fZ0();if($.length===0)return;let Z=u7(Vk),J=new Set([Tk()]),X=gZ0(Z);if(X)J.add(X);for(let z of $)for(let Y of J)await z.removeWorktreeSyncHook(Y);if(Z!=="off")n3(Vk,"off")}async function bZ0($){await Sk(),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(`
|
|
285
|
-
`))}var SZ0=500,IZ0="worktree-created",Vk="externalWorktreeSync";var GR=a(()=>{C2();KQ();jJ();$R();JR();u4();v7()});var xL;var Ek=a(()=>{xL={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.
|
|
285
|
+
`))}var SZ0=500,IZ0="worktree-created",Vk="externalWorktreeSync";var GR=a(()=>{C2();KQ();jJ();$R();JR();u4();v7()});var xL;var Ek=a(()=>{xL={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.89",description:"Rove \u2014 the terminal-native agent multiplexer",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:"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:rove":"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.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.12","@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 xk={};g$(xk,{repoSlug:()=>KG,releasePageUrl:()=>BR,recommendedGlobalInstallCommand:()=>HR,isNewerSemver:()=>YR,fetchReleaseSummaries:()=>fK,fetchReleaseNotesRange:()=>UR,fetchReleaseNotes:()=>qR,compareSemver:()=>K3,checkLatestVersion:()=>FG,breakingVersionsCrossed:()=>xK,UPDATE_SCRIPT_URL:()=>fL,UPDATE_COMMAND:()=>QZ,PACKAGE_NAME:()=>WR,CURRENT_VERSION:()=>C$,BREAKING_VERSIONS:()=>AJ});function KG(){let $=xL.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function HR(){return`npm install -g ${WR}@latest`}function xK($,Z,J=AJ){let[X,z]=K3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>K3(Y,X)>0&&K3(Y,z)<=0)}async function vZ0($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),gL);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 Y=await z.json();if(typeof Y.version!=="string")return null;return Y.version}catch{return null}finally{clearTimeout(J)}}function YR($,Z){return K3($,Z)>0}function K3($,Z){let J=(Y)=>Y.split("-")[0]??Y,X=J($).split(".").map((Y)=>Number.parseInt(Y,10)),z=J(Z).split(".").map((Y)=>Number.parseInt(Y,10));for(let Y=0;Y<3;Y++){let W=X[Y]??0,H=z[Y]??0;if(Number.isNaN(W)||Number.isNaN(H))return 0;if(W>H)return 1;if(W<H)return-1}return 0}async function FG($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:C$,latest:Z,hasUpdate:YR(Z,C$)};if(XH()&&!$.force)return null;let J=await vZ0(WR);if(!J)return null;return{current:C$,latest:J,hasUpdate:YR(J,C$)}}function wk($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function qR($){let Z=KG();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),gL);try{let Y=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(!Y.ok)return null;let W=await Y.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 UR($){let Z=KG();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),gL);try{let Y=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(!Y.ok)return[];let W=await Y.json();if(!Array.isArray(W))return[];return W.map((H)=>{let U=wk(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(K3(U,$.current)<=0)return null;if(K3(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 fK($=12){let Z=KG();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),gL);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 Y=await z.json();if(!Array.isArray(Y))return[];return Y.map((W)=>{let H=wk(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 BR($){let Z=KG();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var C$,WR,fL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",QZ,AJ,gL=3000;var f8=a(()=>{Ek();j5();C$=xL.version,WR=xL.name;QZ=`curl -fsSL ${fL} | sh`;AJ=[]});var gk={};g$(gk,{stampResetGate:()=>yL,resetGateBlockers:()=>fk,enforceResetGate:()=>FR,LAST_RUN_VERSION_KEY:()=>KR});function fk($,Z=C$,J=AJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=K3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>K3(Y,X)>0&&K3(Y,z)<=0)}function FR(){let $=X$(),Z=C4()[KR],J=fk(Z);if(J.length>0){let X=typeof Z==="string"?Z:"unknown";console.error([`${$} ${C$}: 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(`
|
|
286
286
|
`)),process.exit(1)}if(Z!==C$)yL()}function yL(){try{i2({[KR]:C$})}catch{}}var KR="app.lastRunVersion";var bL=a(()=>{A2();f8();h4()});import{existsSync as bk,readFileSync as mZ0}from"fs";import{homedir as hZ0}from"os";import{join as kk,resolve as yk}from"path";import{fileURLToPath as uZ0}from"url";function NR($=process.env){return`${X$($)} skill install`}function kL(){let $=uZ0(import.meta.url);return[yk($,"../../../../../.agents/skills/kobe"),yk($,"../../skills/kobe")].find((J)=>bk(kk(J,"SKILL.md")))??null}function vL($={}){let Z=$.source!==void 0?$.source:kL(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??dZ0,"--skill",T8,...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function MG($={}){return`npx ${vL($).join(" ")}`}async function LR($,Z){return await Bun.spawn(["npx",...vL({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function mL($={}){let Z=$.home??hZ0(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>cZ0.map((z)=>kk(X,z)))}function lZ0($){let Z=$.match(/kobe-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function gK($){let Z=mL($).find((z)=>bk(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:MR,stale:!1};let J=null;try{J=lZ0(mZ0(Z,"utf8"))}catch{J=null}let X=J===null||J<MR;return{installed:!0,installedVersion:J,currentVersion:MR,stale:X}}function pZ0(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function vk($={}){let Z=X$(),J=NR(),X=gK();if(!X.installed){if(u7(OR)==="1")return;n3(OR,"1"),process.stderr.write(`
|
|
287
287
|
${Z}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${Z} api\`:
|
|
288
288
|
${J}
|
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.
|
|
4
|
+
"version": "0.8.89",
|
|
5
5
|
"description": "Rove — the terminal-native agent multiplexer",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"packageManager": "bun@1.3.13",
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "git+https://github.com/Sma1lboy/
|
|
18
|
+
"url": "git+https://github.com/Sma1lboy/rove.git"
|
|
19
19
|
},
|
|
20
|
-
"homepage": "https://github.com/Sma1lboy/
|
|
20
|
+
"homepage": "https://github.com/Sma1lboy/rove#readme",
|
|
21
21
|
"bugs": {
|
|
22
|
-
"url": "https://github.com/Sma1lboy/
|
|
22
|
+
"url": "https://github.com/Sma1lboy/rove/issues"
|
|
23
23
|
},
|
|
24
24
|
"engines": {
|
|
25
25
|
"bun": ">=1.3.11"
|