@sma1lboy/kobe 0.8.78 → 0.8.79

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
@@ -281,7 +281,7 @@ ${z}`,Z);this.line=J,this.column=X,this.codeblock=z}}});function cO($,Z){let J=$
281
281
  `)){let U=H.trim();if(!U)continue;if(!UJ(U))continue;let K;try{K=JSON.parse(U)}catch{continue}if(!LP(K)||typeof K.type!=="string")continue;let F=typeof K.timestamp==="string"?K.timestamp:new Date().toISOString(),L=LP(K.data)?K.data:{};if(K.type==="session.start"){let M=typeof L.sessionId==="string"?L.sessionId:void 0;if(M)z=M;continue}if(K.type==="user.message"){let M=typeof L.content==="string"?L.content:"";if(!M)continue;if(!W)W=Buffer.from(M.slice(0,B90),"utf8").toString("utf8");J.push({role:"user",blocks:[{type:"text",text:M}],timestamp:F,sessionId:z});continue}if(K.type==="assistant.message"){let M=[],_=typeof L.content==="string"?L.content:"";if(_)M.push({type:"text",text:_});let R=Array.isArray(L.toolRequests)?L.toolRequests:[];for(let V of R){if(!LP(V))continue;let C=typeof V.id==="string"?V.id:typeof V.toolCallId==="string"?V.toolCallId:"tool",f=typeof V.name==="string"?V.name:typeof V.toolName==="string"?V.toolName:"tool";M.push({type:"tool_call",callId:C,name:f,input:V.arguments??{}})}if(M.length>0)J.push({role:"assistant",blocks:M,timestamp:F,sessionId:z});continue}if(K.type==="tool.execution_start"){let M=typeof L.toolCallId==="string"?L.toolCallId:void 0,_=typeof L.toolName==="string"?L.toolName:"tool";if(M)X.set(M,_);continue}if(K.type==="tool.execution_complete"){let M=typeof L.toolCallId==="string"?L.toolCallId:void 0;if(!M)continue;let _=X.get(M)??(typeof L.toolName==="string"?L.toolName:"tool"),R=L.result??(L.success===!1?{success:!1}:void 0);J.push({role:"assistant",blocks:[{type:"tool_result",callId:M,output:R,isError:L.success===!1}],timestamp:F,sessionId:z});continue}if(K.type==="session.shutdown")Y=Kb(L)}return{messages:J,toolNameById:X,sessionId:z,usageMetrics:Y,firstUserMessage:W}}function LP($){return typeof $==="object"&&$!==null&&!Array.isArray($)}var tz,q90,B90=200;var Ob=a(()=>{az();JL();tz={copilotDir(){let $=process.env.COPILOT_HOME?.trim();if($)return $;return GQ.join(z90(),".copilot")},async readdir($){try{return await J90($)}catch{return[]}},async readFile($){return await qH($)},stat:Q90,async rm($){await X90($,{recursive:!0,force:!0})}};q90=MH({initial:H90,parseChunk:($,Z)=>U90($,Z)})});var qL,Lb,jb;var UL=a(()=>{qL=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],Lb=["\xB7","\u2722","\u2731","\u2736","\u273B","\u273D"],jb=[...Lb,...[...Lb].reverse()]});import{readFile as Vb,stat as N90}from"fs/promises";class BL{supportsCompletionMarkers(){return!0}async latestCompletion($){return(await this.latestActivity($)).marker}async latestActivityInFile($){return null}}function Cb($){return S4($).createTurnDetector()}function _b($,Z="claude",J=0){let X=null,z=0;for(let Y of $.split(`
282
282
  `)){z++;let W=Db(Y);if(!W)continue;let H=AP(W.message)?W.message:W;if(H.role!=="assistant")continue;if(!("content"in H))continue;let U=Pb(W,J),K={id:`claude:${Z}:${U}:${z}`,timestampMs:U,source:"claude"};if(!X||K.timestampMs>=X.timestampMs)X=K}return X}function L90($){if($.type==="turn.completed")return!0;if($.type!=="event_msg")return!1;let Z=AP($.payload)?$.payload:void 0;return typeof Z?.type==="string"&&O90.has(Z.type)}function j90($,Z="codex"){let J=null,X=0;for(let z of $.split(`
283
283
  `)){X++;let Y=Db(z);if(!Y||!L90(Y))continue;let W=Pb(Y,0),H={id:`codex:${Z}:${W}:${X}`,timestampMs:W,source:"codex"};if(!J||H.timestampMs>=J.timestampMs)J=H}return J}function Db($){let Z=$.trim();if(!Z)return null;try{let J=JSON.parse(Z);return AP(J)?J:null}catch{return null}}function Pb($,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 Ab=($)=>N90($).then((Z)=>Z.mtimeMs,()=>0),M90,VP,F90,CP,FK,O90;var DP=a(()=>{ZP();YL();k7();M90={listSessionFiles:($)=>FH($),readFile:($)=>Vb($,"utf8"),statMtimeMs:Ab};VP=class VP extends BL{deps;vendor="claude";cache=new Map;constructor($=M90){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=_b(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??Ab)($);if(Z===0)return null;let J=await this.deps.readFile($).catch(()=>"");return{marker:_b(J,$,Z),mtimeMs:Z}}};F90={findLatestRollout:($)=>FP($),readFile:($)=>Vb($,"utf8")};CP=class CP extends BL{deps;vendor="codex";cache=null;constructor($=F90){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=j90(J,Z.path);return this.cache={path:Z.path,mtimeMs:Z.mtimeMs,marker:X},{marker:X,mtimeMs:Z.mtimeMs}}};FK=class FK extends BL{vendor;constructor($){super();this.vendor=$}supportsCompletionMarkers(){return!1}async latestActivity(){return{marker:null,mtimeMs:0}}};O90=new Set(["task_complete","turn_complete","turn_aborted"])});function A90($){return{vendor:$,builtin:!1,displayName:$,defaultCommand:[$],history:PP,detectAccount:async()=>({binary:{found:!1,error:"custom engine: kobe has no account detector for it"},account:{kind:"none"}}),createHookAdapter:()=>new OK($),createTurnDetector:()=>new FK($)}}function S4($){return f7($)?RP[$]:A90($)}function Rb($){return S4($).history!==PP}function TP($){let Z=S4($).terminalTitle?.statusPrefixes;return Z&&Z.length>0?Z:Tb}function LH($,Z){let J=Z?TP(Z):Tb;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 KL($,Z){let J=S4($).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 Sb(){return Object.values(RP).filter(($)=>$.quotaUsage).map(($)=>$.vendor)}var PP,_90,V90,C90,RP,Tb;var k7=a(()=>{g7();BJ();Cy();ZP();vy();dy();ny();YL();Hb();Bb();Ob();SP();UL();DP();PP={async listSessionIdsForWorktree(){return[]},async readHistory(){return[]},async transcriptPath(){return null},async latestTranscriptMtimeForWorktree(){return 0}},_90={async listSessionIdsForWorktree($){return[...await FH($)].sort((J,X)=>J.mtimeMs-X.mtimeMs).map((J)=>J.sessionId)},readHistory:($)=>Ey($),async transcriptPath($,Z){return(await FH(Z)).find((X)=>X.sessionId===$)?.path??null},latestTranscriptMtimeForWorktree:($)=>Iy($)},V90={listSessionIdsForWorktree:($)=>Qb($),readHistory:($)=>Gb($),transcriptPath:async($)=>await MP($)??null,latestTranscriptMtimeForWorktree:($)=>zb($)},C90={listSessionIdsForWorktree:($)=>Nb($),readHistory:($)=>Fb($),transcriptPath:async()=>null,latestTranscriptMtimeForWorktree:($)=>Mb($)},RP={claude:{vendor:"claude",builtin:!0,displayName:"Claude",defaultCommand:["claude"],history:_90,detectAccount:($)=>UH($),createHookAdapter:()=>new QP,createTurnDetector:()=>new VP,capabilities:_y,identity:Vy,spinnerFrames:jb,terminalTitle:{ownsStatus:!0,statusPrefixes:["\u2733","\u2802","\u2810","\u25D0","\u25D1"],workingPrefixes:["\u2802","\u2810","\u25D0","\u25D1"]},quotaUsage:()=>cy()},codex:{vendor:"codex",builtin:!0,displayName:"Codex",defaultCommand:["codex"],effortLevels:["none","low","medium","high","xhigh"],history:V90,detectAccount:($)=>BH($),createHookAdapter:()=>new OP,createTurnDetector:()=>new CP,capabilities:ly,identity:py,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:()=>Ub()},copilot:{vendor:"copilot",builtin:!0,displayName:"Copilot",defaultCommand:["copilot"],history:C90,detectAccount:($)=>KH($),createHookAdapter:()=>new OK("copilot"),createTurnDetector:()=>new FK("copilot")},kimi:{vendor:"kimi",builtin:!0,displayName:"Kimi",defaultCommand:["kimi"],history:PP,detectAccount:($)=>$L($),createHookAdapter:()=>new OK("kimi"),createTurnDetector:()=>new FK("kimi")}};Tb=[...new Set(Object.values(RP).flatMap(($)=>$.terminalTitle?.statusPrefixes??[]))]});function IP($){return S4($).createHookAdapter()}class OK{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 SP=a(()=>{k7()});function NL($){return D90.includes($)}function Ib($){return P90.includes($)}var D90,P90;var EP=a(()=>{D90=["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"];P90=["session-start","turn-start","turn-complete","turn-failed","turn-interrupted","awaiting-input","session-end"]});var hb={};x4(hb,{runHookSubcommand:()=>x90,readTextWithTimeout:()=>xb,parseWorktreeRemovePath:()=>bb,parseWorktreeAddPath:()=>yb,ensureGlobalKobeHooks:()=>fP});import{readFileSync as R90}from"fs";import{homedir as T90}from"os";import{join as xP,resolve as wP}from"path";async function xb($,Z=S90){let J;try{return await Promise.race([$(),new Promise((X)=>{J=setTimeout(()=>X(""),Z)})])}finally{if(J!==void 0)clearTimeout(J)}}async function fb(){try{let $=await xb(()=>Bun.stdin.text());if(!$.trim())return{};let Z=JSON.parse($);return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:{}}catch{return{}}}function Eb($,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 E90($){return!!$&&typeof $==="object"&&!Array.isArray($)}function gb($){let Z=[],J=/"([^"]*)"|'([^']*)'|(\S+)/g,X;while((X=J.exec($))!==null)Z.push(X[1]??X[2]??X[3]??"");return Z}function yb($){let Z=gb($),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 bb($){let Z=gb($);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 w90(){let $=await fb(),Z=E90($.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=yb(J),Y=z?void 0:bb(J);if(!z&&!Y)return;let W=await iX();if(!W)return;try{if(z)await W.request("worktree.reconcile",{cwd:X,worktreePath:wP(X,z)});else if(Y)await W.request("worktree.archiveRemoved",{worktreePath:wP(X,Y)})}finally{W.close()}}async function x90($){let[Z,...J]=$;if(Z==="setup"){await b90(J);return}if(Z===I90){try{await w90()}catch{}return}try{if(!Z||!NL(Z))return;let X=await fb(),z=Eb(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=Eb(J,"--engine"),K=vb().filter((_)=>!U||_.vendor===U),F;for(let _ of K)if(F=_.activityDetailFromPayload(Z,X),F)break;let L;for(let _ of K)if(L=_.sessionFromPayload(X),L)break;let M=await iX();if(!M)return;try{let _=z??W;await M.request("engine.reportEvent",{..._?{taskId:_}:{cwd:Y},kind:Z,...U?{engine:U}:{},...H?{tabId:H}:{},...F?{detail:F}:{},...L?{sessionId:L.sessionId}:{},...L?.transcriptPath?{transcriptPath:L.transcriptPath}:{}})}finally{M.close()}}catch(X){if(process.env.KOBE_HOOK_DEBUG)console.error(`[kobe hook] ${Z} failed:`,X instanceof Error?X.message:String(X))}}function f90(){return C8.map(($)=>IP($)).filter(($)=>$.supportsWorktreeSync())}function vb(){return C8.map(($)=>IP($)).filter(($)=>$.supportsHooks())}function kb(){return xP(T90(),".claude","settings.json")}function g90($){if(!$||$==="off")return;if($==="global")return kb();if($.startsWith("repo:"))return xP(wP($.slice(5)),".claude","settings.json");return $}async function fP(){try{let $=y90();for(let Z of vb()){let J=Z.globalSettingsPath();if(!J)continue;await Z.installActivityHooks(J,{toolEvents:$}),await Z.installWorktreeWatchHook(J)}await mb()}catch{}}function y90(){try{for(let $ of M5().plugins){if(!$.enabled)continue;try{let Z=R90(xP($.root,C2),"utf8");if(n2(Z).manifest.events.some((J)=>J.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function mb(){let $=f90();if($.length===0)return;let Z=v7(wb),J=new Set([kb()]),X=g90(Z);if(X)J.add(X);for(let z of $)for(let Y of J)await z.removeWorktreeSyncHook(Y);if(Z!=="off")m3(wb,"off")}async function b90($){await mb(),process.stdout.write(["kobe 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 kobe previously installed has been removed.","","Sync is now automatic: a `claude --worktree` (or any session) started in a","worktree under a repo kobe already tracks is adopted as a task on launch.","To adopt existing worktrees on demand, use the New Task dialog or `kobe adopt`.",""].join(`
284
- `))}var S90=500,I90="worktree-created",wb="externalWorktreeSync";var gP=a(()=>{L2();$Q();qJ();SP();EP();v$();g7()});var ML;var ub=a(()=>{ML={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.78",description:"TUI orchestrator for Claude Code (codename)",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/index.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/kobe.git"},homepage:"https://github.com/Sma1lboy/kobe#readme",bugs:{url:"https://github.com/Sma1lboy/kobe/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"KOBE_DEV=1 bun --conditions=browser ./src/cli/index.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 db={};x4(db,{repoSlug:()=>ez,releasePageUrl:()=>hP,recommendedGlobalInstallCommand:()=>vP,isNewerSemver:()=>yP,fetchReleaseSummaries:()=>jK,fetchReleaseNotesRange:()=>mP,fetchReleaseNotes:()=>kP,compareSemver:()=>z3,checkLatestVersion:()=>$G,breakingVersionsCrossed:()=>LK,UPDATE_SCRIPT_URL:()=>FL,UPDATE_COMMAND:()=>o9,PACKAGE_NAME:()=>bP,CURRENT_VERSION:()=>V4,BREAKING_VERSIONS:()=>NJ});function ez(){let $=ML.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function vP(){return`npm install -g ${bP}@latest`}function LK($,Z,J=NJ){let[X,z]=z3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>z3(Y,X)>0&&z3(Y,z)<=0)}async function k90($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),OL);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 yP($,Z){return z3($,Z)>0}function z3($,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 $G($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:V4,latest:Z,hasUpdate:yP(Z,V4)};if(lW()&&!$.force)return null;let J=await k90(bP);if(!J)return null;return{current:V4,latest:J,hasUpdate:yP(J,V4)}}function cb($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function kP($){let Z=ez();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),OL);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 mP($){let Z=ez();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),OL);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=cb(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(z3(U,$.current)<=0)return null;if(z3(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 jK($=12){let Z=ez();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),OL);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=cb(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 hP($){let Z=ez();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var V4,bP,FL="https://raw.githubusercontent.com/Sma1lboy/kobe/main/scripts/update.sh",o9,NJ,OL=3000;var R8=a(()=>{ub();R5();V4=ML.version,bP=ML.name;o9=`curl -fsSL ${FL} | sh`;NJ=[]});var pb={};x4(pb,{stampResetGate:()=>LL,resetGateBlockers:()=>lb,enforceResetGate:()=>cP,LAST_RUN_VERSION_KEY:()=>uP});function lb($,Z=V4,J=NJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=z3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>z3(Y,X)>0&&z3(Y,z)<=0)}function cP(){let $=j$()[uP],Z=lb($);if(Z.length>0){let J=typeof $==="string"?$:"unknown";console.error([`kobe ${V4}: cannot start \u2014 version ${Z.join(", ")} introduced breaking changes`,`(last run: ${J}). Your daemon/session state may be incompatible.`,"","Run:"," kobe reset # stop daemon + PTY host + sessions (tasks kept)"," kobe reset --hard # additionally wipe the task index + UI state","","Then relaunch kobe. Worktrees are never touched."].join(`
284
+ `))}var S90=500,I90="worktree-created",wb="externalWorktreeSync";var gP=a(()=>{L2();$Q();qJ();SP();EP();v$();g7()});var ML;var ub=a(()=>{ML={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/kobe",version:"0.8.79",description:"TUI orchestrator for Claude Code (codename)",type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/index.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/kobe.git"},homepage:"https://github.com/Sma1lboy/kobe#readme",bugs:{url:"https://github.com/Sma1lboy/kobe/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"KOBE_DEV=1 bun --conditions=browser ./src/cli/index.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 db={};x4(db,{repoSlug:()=>ez,releasePageUrl:()=>hP,recommendedGlobalInstallCommand:()=>vP,isNewerSemver:()=>yP,fetchReleaseSummaries:()=>jK,fetchReleaseNotesRange:()=>mP,fetchReleaseNotes:()=>kP,compareSemver:()=>z3,checkLatestVersion:()=>$G,breakingVersionsCrossed:()=>LK,UPDATE_SCRIPT_URL:()=>FL,UPDATE_COMMAND:()=>o9,PACKAGE_NAME:()=>bP,CURRENT_VERSION:()=>V4,BREAKING_VERSIONS:()=>NJ});function ez(){let $=ML.repository?.url;if(!$)return null;let Z=$.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!Z||!Z[1]||!Z[2])return null;return`${Z[1]}/${Z[2]}`}function vP(){return`npm install -g ${bP}@latest`}function LK($,Z,J=NJ){let[X,z]=z3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>z3(Y,X)>0&&z3(Y,z)<=0)}async function k90($){let Z=new AbortController,J=setTimeout(()=>Z.abort(),OL);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 yP($,Z){return z3($,Z)>0}function z3($,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 $G($={}){let Z=process.env.KOBE_FAKE_UPDATE;if(Z)return{current:V4,latest:Z,hasUpdate:yP(Z,V4)};if(lW()&&!$.force)return null;let J=await k90(bP);if(!J)return null;return{current:V4,latest:J,hasUpdate:yP(J,V4)}}function cb($){if(typeof $!=="string")return null;return $.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function kP($){let Z=ez();if(!Z)return null;let J=`v${$}`,X=new AbortController,z=setTimeout(()=>X.abort(),OL);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 mP($){let Z=ez();if(!Z)return[];let J=$.limit??100,X=new AbortController,z=setTimeout(()=>X.abort(),OL);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=cb(H.tag_name);if(!U||typeof H.html_url!=="string"||typeof H.body!=="string")return null;if(z3(U,$.current)<=0)return null;if(z3(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 jK($=12){let Z=ez();if(!Z)return[];let J=new AbortController,X=setTimeout(()=>J.abort(),OL);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=cb(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 hP($){let Z=ez();if(!Z)return null;return`https://github.com/${Z}/releases/tag/v${$}`}var V4,bP,FL="https://raw.githubusercontent.com/Sma1lboy/kobe/main/scripts/update.sh",o9,NJ,OL=3000;var R8=a(()=>{ub();R5();V4=ML.version,bP=ML.name;o9=`curl -fsSL ${FL} | sh`;NJ=[]});var pb={};x4(pb,{stampResetGate:()=>LL,resetGateBlockers:()=>lb,enforceResetGate:()=>cP,LAST_RUN_VERSION_KEY:()=>uP});function lb($,Z=V4,J=NJ){if(typeof $!=="string"||$.length===0)return[];let[X,z]=z3($,Z)<=0?[$,Z]:[Z,$];return J.filter((Y)=>z3(Y,X)>0&&z3(Y,z)<=0)}function cP(){let $=j$()[uP],Z=lb($);if(Z.length>0){let J=typeof $==="string"?$:"unknown";console.error([`kobe ${V4}: cannot start \u2014 version ${Z.join(", ")} introduced breaking changes`,`(last run: ${J}). Your daemon/session state may be incompatible.`,"","Run:"," kobe reset # stop daemon + PTY host + sessions (tasks kept)"," kobe reset --hard # additionally wipe the task index + UI state","","Then relaunch kobe. Worktrees are never touched."].join(`
285
285
  `)),process.exit(1)}if($!==V4)LL()}function LL(){try{d2({[uP]:V4})}catch{}}var uP="app.lastRunVersion";var jL=a(()=>{j2();R8()});import{existsSync as ib,readFileSync as m90}from"fs";import{homedir as h90}from"os";import{join as ob,resolve as nb}from"path";import{fileURLToPath as u90}from"url";function _L(){let $=u90(import.meta.url);return[nb($,"../../../../../.agents/skills/kobe"),nb($,"../../skills/kobe")].find((J)=>ib(ob(J,"SKILL.md")))??null}function VL($={}){let Z=$.source!==void 0?$.source:_L(),J=$.agent===void 0?[]:typeof $.agent==="string"?[$.agent]:$.agent;return["skills","add",Z??d90,"--skill","kobe",...$.global===!1?[]:["--global"],...J.flatMap((X)=>["--agent",X])]}function ZG($={}){return`npx ${VL($).join(" ")}`}async function pP($,Z){return await Bun.spawn(["npx",...VL({...$===void 0?{}:{agent:$},global:Z})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}function CL($={}){let Z=$.home??h90(),J=$.cwd??process.cwd();return[Z,J].flatMap((X)=>c90.map((z)=>ob(X,z)))}function l90($){let Z=$.match(/kobe-skill-version:\s*(\d+)/);return Z?Number.parseInt(Z[1],10):null}function _K($){let Z=CL($).find((z)=>ib(z));if(!Z)return{installed:!1,installedVersion:null,currentVersion:dP,stale:!1};let J=null;try{J=l90(m90(Z,"utf8"))}catch{J=null}let X=J===null||J<dP;return{installed:!0,installedVersion:J,currentVersion:dP,stale:X}}function p90(){return new Promise(($)=>{process.stdin.resume(),process.stdin.once("data",(Z)=>{process.stdin.pause(),$(String(Z))})})}async function ab($={}){let Z=_K();if(!Z.installed){if(v7(lP)==="1")return;m3(lP,"1"),process.stderr.write(`
286
286
  kobe: the kobe agent skill isn't installed \u2014 install it so your coding agent can drive kobe via \`kobe api\`:
287
287
  ${jH}
@@ -295,7 +295,7 @@ kobe: your kobe agent skill is out of date (${X}; this kobe wants v${Z.currentVe
295
295
  kobe: a new version of the kobe agent skill is available (${X} \u2192 v${Z.currentVersion}).
296
296
  Update now? [y]es / [n]o / [d]on't notify for this version: `);let Y=(await($.ask??p90)()).trim().toLowerCase();if(Y==="y"||Y==="yes"){let W=await($.install??pP)();if(W===0)process.stderr.write(`kobe: skill updated.
297
297
  `);else process.stderr.write(`kobe: skill update failed (exit ${W}) \u2014 run \`${jH}\` manually.
298
- `)}else if(Y.startsWith("d"))m3(J,"1")}var dP=17,c90,jH="kobe skill install",d90="Sma1lboy/kobe",lP="skillHintSeen";var VK=a(()=>{v$();c90=[".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});var AL=()=>{};var q1=vz((n90,DL)=>{(function(){function $(J0,S0){Object.defineProperty(X.prototype,J0,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",S0[0],S0[1])}})}function Z(J0){if(J0===null||typeof J0!=="object")return null;return J0=P0&&J0[P0]||J0["@@iterator"],typeof J0==="function"?J0:null}function J(J0,S0){J0=(J0=J0.constructor)&&(J0.displayName||J0.name)||"ReactClass";var e0=J0+"."+S0;u0[e0]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",S0,J0),u0[e0]=!0)}function X(J0,S0,e0){this.props=J0,this.context=S0,this.refs=G1,this.updater=e0||L0}function z(){}function Y(J0,S0,e0){this.props=J0,this.context=S0,this.refs=G1,this.updater=e0||L0}function W(){}function H(J0){return""+J0}function U(J0){try{H(J0);var S0=!1}catch(l1){S0=!0}if(S0){S0=console;var e0=S0.error,U1=typeof Symbol==="function"&&Symbol.toStringTag&&J0[Symbol.toStringTag]||J0.constructor.name||"Object";return e0.call(S0,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",U1),H(J0)}}function K(J0){if(J0==null)return null;if(typeof J0==="function")return J0.$$typeof===c0?null:J0.displayName||J0.name||null;if(typeof J0==="string")return J0;switch(J0){case l:return"Fragment";case n:return"Profiler";case d:return"StrictMode";case Q0:return"Suspense";case C0:return"SuspenseList";case k0:return"Activity"}if(typeof J0==="object")switch(typeof J0.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),J0.$$typeof){case v:return"Portal";case t:return J0.displayName||"Context";case Z0:return(J0._context.displayName||"Context")+".Consumer";case r:var S0=J0.render;return J0=J0.displayName,J0||(J0=S0.displayName||S0.name||"",J0=J0!==""?"ForwardRef("+J0+")":"ForwardRef"),J0;case z0:return S0=J0.displayName||null,S0!==null?S0:K(J0.type)||"Memo";case x0:S0=J0._payload,J0=J0._init;try{return K(J0(S0))}catch(e0){}}return null}function F(J0){if(J0===l)return"<>";if(typeof J0==="object"&&J0!==null&&J0.$$typeof===x0)return"<...>";try{var S0=K(J0);return S0?"<"+S0+">":"<...>"}catch(e0){return"<...>"}}function L(){var J0=J1.A;return J0===null?null:J0.getOwner()}function M(){return Error("react-stack-top-frame")}function _(J0){if(u1.call(J0,"key")){var S0=Object.getOwnPropertyDescriptor(J0,"key").get;if(S0&&S0.isReactWarning)return!1}return J0.key!==void 0}function R(J0,S0){function e0(){H4||(H4=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",S0))}e0.isReactWarning=!0,Object.defineProperty(J0,"key",{get:e0,configurable:!0})}function V(){var J0=K(this.type);return d5[J0]||(d5[J0]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),J0=this.props.ref,J0!==void 0?J0:null}function C(J0,S0,e0,U1,l1,I4){var _4=e0.ref;return J0={$$typeof:H0,type:J0,key:S0,props:e0,_owner:U1},(_4!==void 0?_4:null)!==null?Object.defineProperty(J0,"ref",{enumerable:!1,get:V}):Object.defineProperty(J0,"ref",{enumerable:!1,value:null}),J0._store={},Object.defineProperty(J0._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(J0,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(J0,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:l1}),Object.defineProperty(J0,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:I4}),Object.freeze&&(Object.freeze(J0.props),Object.freeze(J0)),J0}function f(J0,S0){return S0=C(J0.type,S0,J0.props,J0._owner,J0._debugStack,J0._debugTask),J0._store&&(S0._store.validated=J0._store.validated),S0}function T(J0){I(J0)?J0._store&&(J0._store.validated=1):typeof J0==="object"&&J0!==null&&J0.$$typeof===x0&&(J0._payload.status==="fulfilled"?I(J0._payload.value)&&J0._payload.value._store&&(J0._payload.value._store.validated=1):J0._store&&(J0._store.validated=1))}function I(J0){return typeof J0==="object"&&J0!==null&&J0.$$typeof===H0}function S(J0){var S0={"=":"=0",":":"=2"};return"$"+J0.replace(/[=:]/g,function(e0){return S0[e0]})}function x(J0,S0){return typeof J0==="object"&&J0!==null&&J0.key!=null?(U(J0.key),S(""+J0.key)):S0.toString(36)}function b(J0){switch(J0.status){case"fulfilled":return J0.value;case"rejected":throw J0.reason;default:switch(typeof J0.status==="string"?J0.then(W,W):(J0.status="pending",J0.then(function(S0){J0.status==="pending"&&(J0.status="fulfilled",J0.value=S0)},function(S0){J0.status==="pending"&&(J0.status="rejected",J0.reason=S0)})),J0.status){case"fulfilled":return J0.value;case"rejected":throw J0.reason}}throw J0}function k(J0,S0,e0,U1,l1){var I4=typeof J0;if(I4==="undefined"||I4==="boolean")J0=null;var _4=!1;if(J0===null)_4=!0;else switch(I4){case"bigint":case"string":case"number":_4=!0;break;case"object":switch(J0.$$typeof){case H0:case v:_4=!0;break;case x0:return _4=J0._init,k(_4(J0._payload),S0,e0,U1,l1)}}if(_4){_4=J0,l1=l1(_4);var U$=U1===""?"."+x(_4,0):U1;return F0(l1)?(e0="",U$!=null&&(e0=U$.replace(nJ,"$&/")+"/"),k(l1,S0,e0,"",function(j7){return j7})):l1!=null&&(I(l1)&&(l1.key!=null&&(_4&&_4.key===l1.key||U(l1.key)),e0=f(l1,e0+(l1.key==null||_4&&_4.key===l1.key?"":(""+l1.key).replace(nJ,"$&/")+"/")+U$),U1!==""&&_4!=null&&I(_4)&&_4.key==null&&_4._store&&!_4._store.validated&&(e0._store.validated=2),l1=e0),S0.push(l1)),1}if(_4=0,U$=U1===""?".":U1+":",F0(J0))for(var f4=0;f4<J0.length;f4++)U1=J0[f4],I4=U$+x(U1,f4),_4+=k(U1,S0,e0,I4,l1);else if(f4=Z(J0),typeof f4==="function")for(f4===J0.entries&&(y8||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),y8=!0),J0=f4.call(J0),f4=0;!(U1=J0.next()).done;)U1=U1.value,I4=U$+x(U1,f4++),_4+=k(U1,S0,e0,I4,l1);else if(I4==="object"){if(typeof J0.then==="function")return k(b(J0),S0,e0,U1,l1);throw S0=String(J0),Error("Objects are not valid as a React child (found: "+(S0==="[object Object]"?"object with keys {"+Object.keys(J0).join(", ")+"}":S0)+"). If you meant to render a collection of children, use an array instead.")}return _4}function u(J0,S0,e0){if(J0==null)return J0;var U1=[],l1=0;return k(J0,U1,"","",function(I4){return S0.call(e0,I4,l1++)}),U1}function o(J0){if(J0._status===-1){var S0=J0._ioInfo;S0!=null&&(S0.start=S0.end=performance.now()),S0=J0._result;var e0=S0();if(e0.then(function(l1){if(J0._status===0||J0._status===-1){J0._status=1,J0._result=l1;var I4=J0._ioInfo;I4!=null&&(I4.end=performance.now()),e0.status===void 0&&(e0.status="fulfilled",e0.value=l1)}},function(l1){if(J0._status===0||J0._status===-1){J0._status=2,J0._result=l1;var I4=J0._ioInfo;I4!=null&&(I4.end=performance.now()),e0.status===void 0&&(e0.status="rejected",e0.reason=l1)}}),S0=J0._ioInfo,S0!=null){S0.value=e0;var U1=e0.displayName;typeof U1==="string"&&(S0.name=U1)}J0._status===-1&&(J0._status=0,J0._result=e0)}if(J0._status===1)return S0=J0._result,S0===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
298
+ `)}else if(Y.startsWith("d"))m3(J,"1")}var dP=18,c90,jH="kobe skill install",d90="Sma1lboy/kobe",lP="skillHintSeen";var VK=a(()=>{v$();c90=[".agents/skills/kobe/SKILL.md",".claude/skills/kobe/SKILL.md"]});var AL=()=>{};var q1=vz((n90,DL)=>{(function(){function $(J0,S0){Object.defineProperty(X.prototype,J0,{get:function(){console.warn("%s(...) is deprecated in plain JavaScript React classes. %s",S0[0],S0[1])}})}function Z(J0){if(J0===null||typeof J0!=="object")return null;return J0=P0&&J0[P0]||J0["@@iterator"],typeof J0==="function"?J0:null}function J(J0,S0){J0=(J0=J0.constructor)&&(J0.displayName||J0.name)||"ReactClass";var e0=J0+"."+S0;u0[e0]||(console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",S0,J0),u0[e0]=!0)}function X(J0,S0,e0){this.props=J0,this.context=S0,this.refs=G1,this.updater=e0||L0}function z(){}function Y(J0,S0,e0){this.props=J0,this.context=S0,this.refs=G1,this.updater=e0||L0}function W(){}function H(J0){return""+J0}function U(J0){try{H(J0);var S0=!1}catch(l1){S0=!0}if(S0){S0=console;var e0=S0.error,U1=typeof Symbol==="function"&&Symbol.toStringTag&&J0[Symbol.toStringTag]||J0.constructor.name||"Object";return e0.call(S0,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",U1),H(J0)}}function K(J0){if(J0==null)return null;if(typeof J0==="function")return J0.$$typeof===c0?null:J0.displayName||J0.name||null;if(typeof J0==="string")return J0;switch(J0){case l:return"Fragment";case n:return"Profiler";case d:return"StrictMode";case Q0:return"Suspense";case C0:return"SuspenseList";case k0:return"Activity"}if(typeof J0==="object")switch(typeof J0.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),J0.$$typeof){case v:return"Portal";case t:return J0.displayName||"Context";case Z0:return(J0._context.displayName||"Context")+".Consumer";case r:var S0=J0.render;return J0=J0.displayName,J0||(J0=S0.displayName||S0.name||"",J0=J0!==""?"ForwardRef("+J0+")":"ForwardRef"),J0;case z0:return S0=J0.displayName||null,S0!==null?S0:K(J0.type)||"Memo";case x0:S0=J0._payload,J0=J0._init;try{return K(J0(S0))}catch(e0){}}return null}function F(J0){if(J0===l)return"<>";if(typeof J0==="object"&&J0!==null&&J0.$$typeof===x0)return"<...>";try{var S0=K(J0);return S0?"<"+S0+">":"<...>"}catch(e0){return"<...>"}}function L(){var J0=J1.A;return J0===null?null:J0.getOwner()}function M(){return Error("react-stack-top-frame")}function _(J0){if(u1.call(J0,"key")){var S0=Object.getOwnPropertyDescriptor(J0,"key").get;if(S0&&S0.isReactWarning)return!1}return J0.key!==void 0}function R(J0,S0){function e0(){H4||(H4=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",S0))}e0.isReactWarning=!0,Object.defineProperty(J0,"key",{get:e0,configurable:!0})}function V(){var J0=K(this.type);return d5[J0]||(d5[J0]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),J0=this.props.ref,J0!==void 0?J0:null}function C(J0,S0,e0,U1,l1,I4){var _4=e0.ref;return J0={$$typeof:H0,type:J0,key:S0,props:e0,_owner:U1},(_4!==void 0?_4:null)!==null?Object.defineProperty(J0,"ref",{enumerable:!1,get:V}):Object.defineProperty(J0,"ref",{enumerable:!1,value:null}),J0._store={},Object.defineProperty(J0._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(J0,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(J0,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:l1}),Object.defineProperty(J0,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:I4}),Object.freeze&&(Object.freeze(J0.props),Object.freeze(J0)),J0}function f(J0,S0){return S0=C(J0.type,S0,J0.props,J0._owner,J0._debugStack,J0._debugTask),J0._store&&(S0._store.validated=J0._store.validated),S0}function T(J0){I(J0)?J0._store&&(J0._store.validated=1):typeof J0==="object"&&J0!==null&&J0.$$typeof===x0&&(J0._payload.status==="fulfilled"?I(J0._payload.value)&&J0._payload.value._store&&(J0._payload.value._store.validated=1):J0._store&&(J0._store.validated=1))}function I(J0){return typeof J0==="object"&&J0!==null&&J0.$$typeof===H0}function S(J0){var S0={"=":"=0",":":"=2"};return"$"+J0.replace(/[=:]/g,function(e0){return S0[e0]})}function x(J0,S0){return typeof J0==="object"&&J0!==null&&J0.key!=null?(U(J0.key),S(""+J0.key)):S0.toString(36)}function b(J0){switch(J0.status){case"fulfilled":return J0.value;case"rejected":throw J0.reason;default:switch(typeof J0.status==="string"?J0.then(W,W):(J0.status="pending",J0.then(function(S0){J0.status==="pending"&&(J0.status="fulfilled",J0.value=S0)},function(S0){J0.status==="pending"&&(J0.status="rejected",J0.reason=S0)})),J0.status){case"fulfilled":return J0.value;case"rejected":throw J0.reason}}throw J0}function k(J0,S0,e0,U1,l1){var I4=typeof J0;if(I4==="undefined"||I4==="boolean")J0=null;var _4=!1;if(J0===null)_4=!0;else switch(I4){case"bigint":case"string":case"number":_4=!0;break;case"object":switch(J0.$$typeof){case H0:case v:_4=!0;break;case x0:return _4=J0._init,k(_4(J0._payload),S0,e0,U1,l1)}}if(_4){_4=J0,l1=l1(_4);var U$=U1===""?"."+x(_4,0):U1;return F0(l1)?(e0="",U$!=null&&(e0=U$.replace(nJ,"$&/")+"/"),k(l1,S0,e0,"",function(j7){return j7})):l1!=null&&(I(l1)&&(l1.key!=null&&(_4&&_4.key===l1.key||U(l1.key)),e0=f(l1,e0+(l1.key==null||_4&&_4.key===l1.key?"":(""+l1.key).replace(nJ,"$&/")+"/")+U$),U1!==""&&_4!=null&&I(_4)&&_4.key==null&&_4._store&&!_4._store.validated&&(e0._store.validated=2),l1=e0),S0.push(l1)),1}if(_4=0,U$=U1===""?".":U1+":",F0(J0))for(var f4=0;f4<J0.length;f4++)U1=J0[f4],I4=U$+x(U1,f4),_4+=k(U1,S0,e0,I4,l1);else if(f4=Z(J0),typeof f4==="function")for(f4===J0.entries&&(y8||console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."),y8=!0),J0=f4.call(J0),f4=0;!(U1=J0.next()).done;)U1=U1.value,I4=U$+x(U1,f4++),_4+=k(U1,S0,e0,I4,l1);else if(I4==="object"){if(typeof J0.then==="function")return k(b(J0),S0,e0,U1,l1);throw S0=String(J0),Error("Objects are not valid as a React child (found: "+(S0==="[object Object]"?"object with keys {"+Object.keys(J0).join(", ")+"}":S0)+"). If you meant to render a collection of children, use an array instead.")}return _4}function u(J0,S0,e0){if(J0==null)return J0;var U1=[],l1=0;return k(J0,U1,"","",function(I4){return S0.call(e0,I4,l1++)}),U1}function o(J0){if(J0._status===-1){var S0=J0._ioInfo;S0!=null&&(S0.start=S0.end=performance.now()),S0=J0._result;var e0=S0();if(e0.then(function(l1){if(J0._status===0||J0._status===-1){J0._status=1,J0._result=l1;var I4=J0._ioInfo;I4!=null&&(I4.end=performance.now()),e0.status===void 0&&(e0.status="fulfilled",e0.value=l1)}},function(l1){if(J0._status===0||J0._status===-1){J0._status=2,J0._result=l1;var I4=J0._ioInfo;I4!=null&&(I4.end=performance.now()),e0.status===void 0&&(e0.status="rejected",e0.reason=l1)}}),S0=J0._ioInfo,S0!=null){S0.value=e0;var U1=e0.displayName;typeof U1==="string"&&(S0.name=U1)}J0._status===-1&&(J0._status=0,J0._result=e0)}if(J0._status===1)return S0=J0._result,S0===void 0&&console.error(`lazy: Expected the result of a dynamic import() call. Instead received: %s
299
299
 
300
300
  Your code should look like:
301
301
  const MyComponent = lazy(() => import('./MyComponent'))
@@ -3,7 +3,7 @@ name: kobe
3
3
  description: Use when controlling kobe tasks, parallel coding attempts, hosted agent sessions, task lifecycle, or the daemon-owned issue tracker from a shell.
4
4
  ---
5
5
 
6
- <!-- kobe-skill-version: 17 — bump in lockstep with KOBE_SKILL_VERSION (src/lib/skill-install.ts). -->
6
+ <!-- kobe-skill-version: 18 — bump in lockstep with KOBE_SKILL_VERSION (src/lib/skill-install.ts). -->
7
7
 
8
8
  # kobe shell control
9
9
 
@@ -61,6 +61,79 @@ in a kobe task. Do not recursively fan out from a spawned task.
61
61
  When the check fails, none of this applies — use `kobe api` only if the
62
62
  user asks for kobe by name.
63
63
 
64
+ ## Vocabulary — what the user's words map to
65
+
66
+ | Term | What it is | Isolation it gives | Users also say |
67
+ |---|---|---|---|
68
+ | **Task** | one Worktree + branch + the Terminal Tabs inside it — one sidebar row | its own files AND its own branch | "a task", "a new one", "a separate attempt" |
69
+ | **Worktree** | that task's file tree on disk (`.task.worktreePath`) | — | "workspace", "this checkout", "this branch", "here" |
70
+ | **Terminal Tab** | one engine session inside a task | its own conversation, SAME files | "tab", "chattab", "another chat", "a second agent on this" |
71
+ | **Split** | the tree that divides ONE Terminal Tab into several regions (the `pane-open` verb's unit; a leaf is not called a pane) | none — same session's screen, same files | "split it", "side by side", "put the logs next to it" |
72
+
73
+ Two of those colloquialisms are traps, so read them as INTENT, not as
74
+ product terms: in kobe's own vocabulary **Workspace** is the center Terminal
75
+ Tab region of the UI (CONTEXT.md), not a checkout, and **ChatTab** is
76
+ retired vocabulary for Terminal Tab. A user saying "in this workspace" means
77
+ the worktree they are looking at — answer the intent, keep writing the real
78
+ term.
79
+
80
+ They nest — **Task ⊃ Terminal Tab ⊃ Split** — and isolation drops at every
81
+ level down:
82
+
83
+ ```text
84
+ new Task → own worktree + own branch (parallel work can't collide)
85
+ new Tab → own engine session, SAME files (a helper in the same checkout)
86
+ new Split → same session's screen, one tab divided (a monitor beside the work)
87
+ ```
88
+
89
+ The distinction that decides every routing call: **a new tab shares the
90
+ worktree and branch; only a new task gets its own.** Two tabs in one task
91
+ edit the same files, so they can collide — that is a feature when the user
92
+ wants a helper in the same checkout, and a bug when they wanted parallel
93
+ attempts. A split isolates nothing at all: it is a layout, for watching
94
+ something (logs, `btop`, a test loop) next to the work — never the answer to
95
+ "do this work".
96
+
97
+ ### Where does this work land?
98
+
99
+ Inside a kobe session (`$KOBE_TASK_ID` non-empty — check first: it is what
100
+ makes the tab/split rows addressable at all), match top to bottom and take
101
+ the first row that fits:
102
+
103
+ | The user says | Lands in | Command |
104
+ |---|---|---|
105
+ | "you do it", "just fix it", "change X to Y" | you, right here | no kobe verb — edit the files yourself |
106
+ | "try it N ways", "compare approaches" | N new tasks | `kobe api fan-out --repo "$PWD" --count N --prompt "…"` |
107
+ | "split", "side by side", "keep an eye on X while…" | a new region in the CURRENT tab | `kobe api pane-open --command "…"` |
108
+ | names a tab: "tell the agent in tab 3" | that exact tab | `kobe api send --task-id <id> --tab tab-3 --prompt "…"` |
109
+ | a LOCATION word: "in this workspace/worktree/checkout", "on this branch", "here", "same task" | THIS task, a NEW Terminal Tab | `kobe api send --task-id "$KOBE_TASK_ID" --tab new --prompt "…"` |
110
+ | **anything else — no row above matched** | a NEW task — new worktree + branch | `kobe api add --repo "$PWD" --prompt "…"` |
111
+
112
+ Order is the tiebreak: a count ("3 ways in this workspace") beats a location
113
+ word, and delegation language loses to "you do it" — the user asking YOU is
114
+ not asking for a fleet. Two more rules the table can't show:
115
+
116
+ - No location word at all ⇒ new task. It is the only routing whose isolation
117
+ cannot corrupt work-in-progress, so it is the safe default.
118
+ - "this repo" / "this project" are NOT location words — they name the repo,
119
+ not the checkout. Only worktree-scoped words route to a tab.
120
+
121
+ Outside a kobe session none of this applies: there is no "this task" to add
122
+ a tab to, so `add` / `fan-out` are the only routings available.
123
+
124
+ ### Know where you are before you route
125
+
126
+ ```bash
127
+ echo "$KOBE_TASK_ID / $KOBE_TAB_ID" # who you are (empty = not a kobe session)
128
+ kobe api get-task --task-id "$KOBE_TASK_ID" # .task.worktreePath, .task.branch, .running, .tabs[]
129
+ ```
130
+
131
+ `get-task` is the per-task read that answers "what is my worktree, my
132
+ branch, and which sibling tabs exist" — `.tabs[]` carries each tab's `id`, `kind`,
133
+ `vendor`, `lastTitle` and `alive`, which is exactly the target list for
134
+ `send --tab`. A tab flagged `unregistered: true` is a live session the tab
135
+ snapshot lost; it is addressable like any other.
136
+
64
137
  ## Discover before calling
65
138
 
66
139
  ```bash
@@ -95,8 +168,9 @@ kobe api send --task-id <id> --prompt "<complete next turn>"
95
168
  # Reply home: no --task-id inside a dispatched task = the dispatcher's tab.
96
169
  kobe api send --prompt "succeeded: <one line> (branch <final branch>)"
97
170
 
98
- # A task can hold several chat tabs. Enumerate them first (inspect's .tabs is
99
- # the sidebar's tab snapshot: id, kind, vendor, lastTitle), then address one:
171
+ # A task can hold several Terminal Tabs. `get-task` lists ONE task's tabs (the
172
+ # usual read before addressing one); `inspect` is the wider diagnostic — every
173
+ # task's snapshot plus daemon activity and live pty sessions.
100
174
  kobe api inspect --task-id <id>
101
175
  kobe api send --task-id <id> --tab tab-3 --prompt "<turn>" # exact alive tab
102
176
  kobe api send --task-id <id> --tab new --prompt "<turn>" # fresh engine tab
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.78",
4
+ "version": "0.8.79",
5
5
  "description": "TUI orchestrator for Claude Code (codename)",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.3.13",