@sma1lboy/rove 0.9.204 → 0.9.205

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.
Files changed (74) hide show
  1. package/dist/cli/{chunk-6tqg80qs.js → chunk-1x26cb1n.js} +1 -1
  2. package/dist/cli/chunk-25yxj8xf.js +3 -0
  3. package/dist/cli/chunk-28430c3s.js +5 -0
  4. package/dist/cli/{chunk-hagvh4x1.js → chunk-2g3wtj9c.js} +1 -1
  5. package/dist/cli/{chunk-h3y0npdb.js → chunk-2qgs5apg.js} +1 -1
  6. package/dist/cli/{chunk-aydz15es.js → chunk-3g5ahx41.js} +1 -1
  7. package/dist/cli/chunk-3trm92y6.js +5 -0
  8. package/dist/cli/{chunk-ba0ygf1w.js → chunk-401a3x2y.js} +1 -1
  9. package/dist/cli/{chunk-bea5j9gq.js → chunk-475b7v12.js} +2 -2
  10. package/dist/cli/{chunk-8zerm1yt.js → chunk-5gc429h7.js} +2 -2
  11. package/dist/cli/{chunk-p9es0m6n.js → chunk-5q3txq7v.js} +17 -17
  12. package/dist/cli/{chunk-rxpbxrqp.js → chunk-5v8ny8f5.js} +1 -1
  13. package/dist/cli/{chunk-2vtps463.js → chunk-6y8fq52x.js} +2 -2
  14. package/dist/cli/{chunk-qm3x7d6f.js → chunk-6ynwn2d2.js} +1 -1
  15. package/dist/cli/{chunk-v3sapafp.js → chunk-7ekehasa.js} +1 -1
  16. package/dist/cli/{chunk-pe3sfy2w.js → chunk-7vwq5f13.js} +3 -3
  17. package/dist/cli/{chunk-8bbmdkz8.js → chunk-878tdxt2.js} +1 -1
  18. package/dist/cli/chunk-879tjgze.js +3 -0
  19. package/dist/cli/{chunk-7d54wzap.js → chunk-8jsqbw0h.js} +1 -1
  20. package/dist/cli/{chunk-46kxbsdm.js → chunk-8k625ztz.js} +14 -5
  21. package/dist/cli/chunk-95gg6bn6.js +4 -0
  22. package/dist/cli/{chunk-v8e24gbf.js → chunk-ad37b8qf.js} +1 -1
  23. package/dist/cli/{chunk-gmy7cw0c.js → chunk-b85vnsxe.js} +1 -1
  24. package/dist/cli/{chunk-xcxgac4t.js → chunk-bgcxnpg8.js} +2 -2
  25. package/dist/cli/{chunk-153e8g4p.js → chunk-d15mggs9.js} +1 -1
  26. package/dist/cli/{chunk-1zsdsvvb.js → chunk-d3t1e8fs.js} +1 -1
  27. package/dist/cli/{chunk-wahj6696.js → chunk-dkeh3535.js} +1 -1
  28. package/dist/cli/{chunk-8kpxyqjx.js → chunk-dwqyryn2.js} +1 -1
  29. package/dist/cli/{chunk-3aabx1rd.js → chunk-fdf22qjy.js} +1 -1
  30. package/dist/cli/{chunk-6kqbfc0n.js → chunk-gqmcdhqr.js} +1 -1
  31. package/dist/cli/{chunk-bh6mcf55.js → chunk-gwrmzvvj.js} +1 -1
  32. package/dist/cli/{chunk-055hmbbv.js → chunk-jp0bsger.js} +3 -3
  33. package/dist/cli/{chunk-mkc6rmcn.js → chunk-k8vhnebj.js} +1 -1
  34. package/dist/cli/{chunk-ch7sta42.js → chunk-ktnqe29b.js} +1 -1
  35. package/dist/cli/{chunk-cc66fxva.js → chunk-m1fx37qm.js} +1 -1
  36. package/dist/cli/{chunk-tm7sb32d.js → chunk-mxz2p2f6.js} +1 -1
  37. package/dist/cli/{chunk-39ak805c.js → chunk-nagxsbrx.js} +1 -1
  38. package/dist/cli/chunk-p6sbcx9k.js +8 -0
  39. package/dist/cli/{chunk-xa1rtnhk.js → chunk-pzv1w1g7.js} +1 -1
  40. package/dist/cli/{chunk-5p5saavr.js → chunk-q0xp0nm5.js} +1 -1
  41. package/dist/cli/{chunk-p08g04w4.js → chunk-qe6bwkqp.js} +1 -1
  42. package/dist/cli/{chunk-8nw96qrm.js → chunk-qkbasmav.js} +1 -1
  43. package/dist/cli/{chunk-b71td6yh.js → chunk-r7zn6cmk.js} +2 -2
  44. package/dist/cli/{chunk-kr5xvfjf.js → chunk-rjm16y82.js} +1 -1
  45. package/dist/cli/{chunk-9nv53s3m.js → chunk-sma2adev.js} +1 -1
  46. package/dist/cli/{chunk-thrvgwbk.js → chunk-sqzmfnwv.js} +1 -1
  47. package/dist/cli/{chunk-ps4xfv9k.js → chunk-ssm956m3.js} +1 -1
  48. package/dist/cli/chunk-t1cy4kam.js +2 -0
  49. package/dist/cli/chunk-ttf48hbz.js +2 -0
  50. package/dist/cli/{chunk-5gsgv4kv.js → chunk-v3gy856k.js} +1 -1
  51. package/dist/cli/{chunk-0q8pcjgw.js → chunk-vxsds0rg.js} +1 -1
  52. package/dist/cli/{chunk-z7c6nap0.js → chunk-w6fbdxg2.js} +2 -2
  53. package/dist/cli/{chunk-qyh2sf97.js → chunk-xpvjq54p.js} +1 -1
  54. package/dist/cli/chunk-y8srv2kd.js +3 -0
  55. package/dist/cli/chunk-z10thenb.js +3 -0
  56. package/dist/cli/{chunk-me2vvqpe.js → chunk-zh2t6yje.js} +1 -1
  57. package/dist/cli/{chunk-7286gtss.js → chunk-zjfa2sv4.js} +1 -1
  58. package/dist/cli/{chunk-rrymnz5z.js → chunk-zmyd75wm.js} +1 -1
  59. package/dist/cli/{chunk-10r5p67t.js → chunk-zp846pvb.js} +1 -1
  60. package/dist/cli/{chunk-sd7xdnr0.js → chunk-zymhc65d.js} +1 -1
  61. package/dist/cli/index.js +3 -3
  62. package/dist/cli/kobe.js +1 -1
  63. package/dist/cli/rove.js +1 -1
  64. package/package.json +1 -1
  65. package/dist/cli/chunk-0ks58ddm.js +0 -4
  66. package/dist/cli/chunk-4drqykd5.js +0 -8
  67. package/dist/cli/chunk-633j3g6j.js +0 -2
  68. package/dist/cli/chunk-aep7gvh4.js +0 -3
  69. package/dist/cli/chunk-agw0gz3e.js +0 -4
  70. package/dist/cli/chunk-c1qt6xpr.js +0 -2
  71. package/dist/cli/chunk-cykd6rkx.js +0 -3
  72. package/dist/cli/chunk-my20q579.js +0 -3
  73. package/dist/cli/chunk-r1sh08tf.js +0 -5
  74. package/dist/cli/chunk-ta0bgf5z.js +0 -3
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{CONTRIB_ENGINE_IDS,contribEngineEntry,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectKimiAccount,isContribEngine,pluginEngineIds}from"./chunk-0ks58ddm.js";import{TomlError,parse}from"./chunk-w7zv47mp.js";import{spawnCapture}from"./chunk-khj0apc7.js";import{ClaudeHookAdapter,GATED_TOOL_VERBS,JsonHookAdapter,hookCommandQuoting,isObject,kobeHookInvocation,readSharedConfigSync,updateSharedJsonSync}from"./chunk-r1sh08tf.js";import{claudeGlobalConfigPath,copilotConfigPath,isJsonlLineWithinBound,readFirstLineBounded,readTextFileBounded,readTextFileIfRegular,vendorAgentDir,vendorConfigHome,vendorWriteHomeDeps}from"./chunk-aep7gvh4.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-05jej26n.js";import{samePath}from"./chunk-f10n6063.js";var claudeCapabilities={interruptSequence:"\x1B"},claudeIdentity={shortName:"Claude"};import{homedir,userInfo}from"os";import path from"path";var OAUTH_USAGE_URL="https://api.anthropic.com/api/oauth/usage",OAUTH_BETA_HEADER="oauth-2025-04-20",OAUTH_USER_AGENT="claude-cli/2.1.198 (external, cli)",USAGE_TIMEOUT_MS=1e4,KEYCHAIN_SERVICE="Claude Code-credentials";function parseResetsAtMs(value){if(value==null)return null;let numeric=typeof value==="number"?value:/^\d+(?:\.\d+)?$/.test(value.trim())?Number(value):null;if(numeric!=null){if(!Number.isFinite(numeric)||numeric<=0)return null;return numeric<1000000000000?numeric*1000:numeric}let parsed=Date.parse(String(value));return Number.isNaN(parsed)?null:parsed}var clampPercent=(value)=>Math.min(100,Math.max(0,Math.round(value)));function windowLabel(kind,scopeModel){if(kind==="weekly_scoped"&&scopeModel)return scopeModel;return kind.startsWith("weekly")||kind.startsWith("seven_day")?"7d":"5h"}function usageFromClaudePayload(payload,capturedAt){let windows=[];if(payload.limits?.length)for(let limit of payload.limits){if(typeof limit.kind!=="string"||typeof limit.percent!=="number")continue;windows.push({kind:limit.kind,label:windowLabel(limit.kind,limit.scope?.model?.display_name),percent:clampPercent(limit.percent),resetsAt:parseResetsAtMs(limit.resets_at)})}else{if(typeof payload.five_hour?.utilization==="number")windows.push({kind:"session",label:"5h",percent:clampPercent(payload.five_hour.utilization),resetsAt:parseResetsAtMs(payload.five_hour.resets_at)});if(typeof payload.seven_day?.utilization==="number")windows.push({kind:"weekly_all",label:"7d",percent:clampPercent(payload.seven_day.utilization),resetsAt:parseResetsAtMs(payload.seven_day.resets_at)})}return{windows,capturedAt}}function parseCredentials(raw){try{let oauth=JSON.parse(raw)?.claudeAiOauth;if(!oauth||typeof oauth.accessToken!=="string"||!oauth.accessToken)return null;return{accessToken:oauth.accessToken,...typeof oauth.expiresAt==="number"&&Number.isFinite(oauth.expiresAt)?{expiresAt:oauth.expiresAt}:{}}}catch{return null}}var isFresh=(c)=>c.expiresAt===void 0||c.expiresAt>Date.now();async function readFileCredentials(dir){try{return parseCredentials(await readTextFileBounded(path.join(dir,".credentials.json")))}catch{return null}}async function readKeychainCredentials(){if(process.platform!=="darwin")return null;let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),3000);try{let result=await spawnCapture("security",["find-generic-password","-a",userInfo().username,"-w","-s",KEYCHAIN_SERVICE],{cwd:homedir(),signal:controller.signal});return result.status===0?parseCredentials(result.stdout.trim()):null}finally{clearTimeout(timeout)}}async function readAccessToken(){let configDir=process.env.CLAUDE_CONFIG_DIR?.trim();if(configDir){let fromFile=await readFileCredentials(configDir);return fromFile&&isFresh(fromFile)?fromFile.accessToken:null}return[await readKeychainCredentials(),await readFileCredentials(vendorConfigHome("claude"))].find((c)=>c!=null&&isFresh(c))?.accessToken??null}async function fetchClaudeQuotaUsage(now=Date.now){let token=await readAccessToken().catch(()=>null);if(!token)return null;let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),USAGE_TIMEOUT_MS);try{let response=await fetch(OAUTH_USAGE_URL,{headers:{Authorization:`Bearer ${token}`,"Content-Type":"application/json","User-Agent":OAUTH_USER_AGENT,"anthropic-beta":OAUTH_BETA_HEADER},signal:controller.signal});if(!response.ok)return null;return usageFromClaudePayload(await response.json(),now())}catch{return null}finally{clearTimeout(timeout)}}function trustClaudeWorktree(worktreePath,home){let deps=vendorWriteHomeDeps(home);updateSharedJsonSync(claudeGlobalConfigPath(deps.env,deps.home()),(raw)=>{if(raw===void 0)return{};let doc=JSON.parse(raw);if(!isObject(doc))throw Error("Claude trust config must be a JSON object");return doc},(doc)=>{if(doc.projects!==void 0&&!isObject(doc.projects))throw Error("Claude trust projects must be an object");let projects={...doc.projects},existing=Object.hasOwn(projects,worktreePath)?projects[worktreePath]:{};if(!isObject(existing))throw Error("Claude trust project must be an object");if(existing.hasTrustDialogAccepted===!0)return;return projects[worktreePath]={...existing,hasTrustDialogAccepted:!0,hasCompletedProjectOnboarding:!0},JSON.stringify({...doc,projects},null,2)})}function isSyntheticClaudeRecord(record){return record.isMeta===!0||record.isCompactSummary===!0}function isClaudeCommandBreadcrumb(blocks){if(blocks.length===0)return!1;for(let b of blocks){if(b.type!=="text")return!1;let t=b.text.trim();if(!t.startsWith("<command-name>")&&!t.startsWith("<command-message>")&&!t.startsWith("<local-command"))return!1}return!0}function isObject2(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function opensTurn(content){if(typeof content==="string")return content.trim().length>0;if(!Array.isArray(content))return!1;return content.some((b)=>!isObject2(b)||b.type!=="tool_result")}function num(v){return typeof v==="number"&&Number.isFinite(v)?v:0}function readUsage(v){if(!isObject2(v))return;return{input_tokens:num(v.input_tokens),output_tokens:num(v.output_tokens),cache_read_input_tokens:num(v.cache_read_input_tokens),cache_creation_input_tokens:num(v.cache_creation_input_tokens)}}function finish(draft){if(!draft.id)return null;let totals={input_tokens:0,output_tokens:0,cache_read_input_tokens:0,cache_creation_input_tokens:0};for(let u of draft.usageByMessage.values())totals.input_tokens+=u.input_tokens,totals.output_tokens+=u.output_tokens,totals.cache_read_input_tokens+=u.cache_read_input_tokens,totals.cache_creation_input_tokens+=u.cache_creation_input_tokens;return{id:draft.id,sessionId:draft.sessionId,...draft.model?{model:draft.model}:{},startedAt:draft.startedAt,endedAt:draft.endedAt,...draft.usageByMessage.size>0?{usage:totals}:{}}}function parseClaudeTurns(raw,fallbackSessionId=""){let out=[],draft=null;for(let line of raw.split(`
2
+ import{CONTRIB_ENGINE_IDS,contribEngineEntry,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectKimiAccount,isContribEngine,pluginEngineIds}from"./chunk-28430c3s.js";import{TomlError,parse}from"./chunk-w7zv47mp.js";import{spawnCapture}from"./chunk-khj0apc7.js";import{ClaudeHookAdapter}from"./chunk-z10thenb.js";import{GATED_TOOL_VERBS,JsonHookAdapter,ROVE_HOOK_VERSION,claudeGlobalConfigPath,copilotConfigPath,hookCommandQuoting,isJsonlLineWithinBound,isObject,kobeHookInvocation,readFirstLineBounded,readSharedConfigSync,readTextFileBounded,readTextFileIfRegular,roveHookArgs,updateSharedJsonSync,vendorAgentDir,vendorConfigHome,vendorWriteHomeDeps}from"./chunk-3trm92y6.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-05jej26n.js";import{samePath}from"./chunk-f10n6063.js";var claudeCapabilities={interruptSequence:"\x1B"},claudeIdentity={shortName:"Claude"};import{homedir,userInfo}from"os";import path from"path";var OAUTH_USAGE_URL="https://api.anthropic.com/api/oauth/usage",OAUTH_BETA_HEADER="oauth-2025-04-20",OAUTH_USER_AGENT="claude-cli/2.1.198 (external, cli)",USAGE_TIMEOUT_MS=1e4,KEYCHAIN_SERVICE="Claude Code-credentials";function parseResetsAtMs(value){if(value==null)return null;let numeric=typeof value==="number"?value:/^\d+(?:\.\d+)?$/.test(value.trim())?Number(value):null;if(numeric!=null){if(!Number.isFinite(numeric)||numeric<=0)return null;return numeric<1000000000000?numeric*1000:numeric}let parsed=Date.parse(String(value));return Number.isNaN(parsed)?null:parsed}var clampPercent=(value)=>Math.min(100,Math.max(0,Math.round(value)));function windowLabel(kind,scopeModel){if(kind==="weekly_scoped"&&scopeModel)return scopeModel;return kind.startsWith("weekly")||kind.startsWith("seven_day")?"7d":"5h"}function usageFromClaudePayload(payload,capturedAt){let windows=[];if(payload.limits?.length)for(let limit of payload.limits){if(typeof limit.kind!=="string"||typeof limit.percent!=="number")continue;windows.push({kind:limit.kind,label:windowLabel(limit.kind,limit.scope?.model?.display_name),percent:clampPercent(limit.percent),resetsAt:parseResetsAtMs(limit.resets_at)})}else{if(typeof payload.five_hour?.utilization==="number")windows.push({kind:"session",label:"5h",percent:clampPercent(payload.five_hour.utilization),resetsAt:parseResetsAtMs(payload.five_hour.resets_at)});if(typeof payload.seven_day?.utilization==="number")windows.push({kind:"weekly_all",label:"7d",percent:clampPercent(payload.seven_day.utilization),resetsAt:parseResetsAtMs(payload.seven_day.resets_at)})}return{windows,capturedAt}}function parseCredentials(raw){try{let oauth=JSON.parse(raw)?.claudeAiOauth;if(!oauth||typeof oauth.accessToken!=="string"||!oauth.accessToken)return null;return{accessToken:oauth.accessToken,...typeof oauth.expiresAt==="number"&&Number.isFinite(oauth.expiresAt)?{expiresAt:oauth.expiresAt}:{}}}catch{return null}}var isFresh=(c)=>c.expiresAt===void 0||c.expiresAt>Date.now();async function readFileCredentials(dir){try{return parseCredentials(await readTextFileBounded(path.join(dir,".credentials.json")))}catch{return null}}async function readKeychainCredentials(){if(process.platform!=="darwin")return null;let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),3000);try{let result=await spawnCapture("security",["find-generic-password","-a",userInfo().username,"-w","-s",KEYCHAIN_SERVICE],{cwd:homedir(),signal:controller.signal});return result.status===0?parseCredentials(result.stdout.trim()):null}finally{clearTimeout(timeout)}}async function readAccessToken(){let configDir=process.env.CLAUDE_CONFIG_DIR?.trim();if(configDir){let fromFile=await readFileCredentials(configDir);return fromFile&&isFresh(fromFile)?fromFile.accessToken:null}return[await readKeychainCredentials(),await readFileCredentials(vendorConfigHome("claude"))].find((c)=>c!=null&&isFresh(c))?.accessToken??null}async function fetchClaudeQuotaUsage(now=Date.now){let token=await readAccessToken().catch(()=>null);if(!token)return null;let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),USAGE_TIMEOUT_MS);try{let response=await fetch(OAUTH_USAGE_URL,{headers:{Authorization:`Bearer ${token}`,"Content-Type":"application/json","User-Agent":OAUTH_USER_AGENT,"anthropic-beta":OAUTH_BETA_HEADER},signal:controller.signal});if(!response.ok)return null;return usageFromClaudePayload(await response.json(),now())}catch{return null}finally{clearTimeout(timeout)}}function trustClaudeWorktree(worktreePath,home){let deps=vendorWriteHomeDeps(home);updateSharedJsonSync(claudeGlobalConfigPath(deps.env,deps.home()),(raw)=>{if(raw===void 0)return{};let doc=JSON.parse(raw);if(!isObject(doc))throw Error("Claude trust config must be a JSON object");return doc},(doc)=>{if(doc.projects!==void 0&&!isObject(doc.projects))throw Error("Claude trust projects must be an object");let projects={...doc.projects},existing=Object.hasOwn(projects,worktreePath)?projects[worktreePath]:{};if(!isObject(existing))throw Error("Claude trust project must be an object");if(existing.hasTrustDialogAccepted===!0)return;return projects[worktreePath]={...existing,hasTrustDialogAccepted:!0,hasCompletedProjectOnboarding:!0},JSON.stringify({...doc,projects},null,2)})}function isSyntheticClaudeRecord(record){return record.isMeta===!0||record.isCompactSummary===!0}function isClaudeCommandBreadcrumb(blocks){if(blocks.length===0)return!1;for(let b of blocks){if(b.type!=="text")return!1;let t=b.text.trim();if(!t.startsWith("<command-name>")&&!t.startsWith("<command-message>")&&!t.startsWith("<local-command"))return!1}return!0}function isObject2(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function opensTurn(content){if(typeof content==="string")return content.trim().length>0;if(!Array.isArray(content))return!1;return content.some((b)=>!isObject2(b)||b.type!=="tool_result")}function num(v){return typeof v==="number"&&Number.isFinite(v)?v:0}function readUsage(v){if(!isObject2(v))return;return{input_tokens:num(v.input_tokens),output_tokens:num(v.output_tokens),cache_read_input_tokens:num(v.cache_read_input_tokens),cache_creation_input_tokens:num(v.cache_creation_input_tokens)}}function finish(draft){if(!draft.id)return null;let totals={input_tokens:0,output_tokens:0,cache_read_input_tokens:0,cache_creation_input_tokens:0};for(let u of draft.usageByMessage.values())totals.input_tokens+=u.input_tokens,totals.output_tokens+=u.output_tokens,totals.cache_read_input_tokens+=u.cache_read_input_tokens,totals.cache_creation_input_tokens+=u.cache_creation_input_tokens;return{id:draft.id,sessionId:draft.sessionId,...draft.model?{model:draft.model}:{},startedAt:draft.startedAt,endedAt:draft.endedAt,...draft.usageByMessage.size>0?{usage:totals}:{}}}function parseClaudeTurns(raw,fallbackSessionId=""){let out=[],draft=null;for(let line of raw.split(`
3
3
  `)){let trimmed=line.trim();if(!trimmed||!isJsonlLineWithinBound(trimmed))continue;let record;try{record=JSON.parse(trimmed)}catch{continue}if(!isObject2(record)||isSyntheticClaudeRecord(record))continue;let inner=isObject2(record.message)?record.message:record,at=typeof record.timestamp==="string"?Date.parse(record.timestamp):Number.NaN;if(!Number.isFinite(at))continue;let sessionId=typeof record.sessionId==="string"?record.sessionId:fallbackSessionId;if(inner.role==="user"){if(!opensTurn(inner.content))continue;if(draft){let done=finish(draft);if(done)out.push(done)}draft={id:"",sessionId,startedAt:at,endedAt:at,usageByMessage:new Map};continue}if(inner.role!=="assistant"||!draft)continue;if(draft.endedAt=at,typeof inner.model==="string")draft.model=inner.model;let messageId=typeof inner.id==="string"?inner.id:"";if(messageId)draft.id=messageId;let usage=readUsage(inner.usage);if(usage&&messageId)draft.usageByMessage.set(messageId,usage)}if(draft){let done=finish(draft);if(done)out.push(done)}return out}async function readClaudeTurns(transcriptPath){try{let raw=await readTextFileBounded(transcriptPath);return parseClaudeTurns(raw)}catch{return[]}}var HEX_RE=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;function parseHex(value){let match=HEX_RE.exec(value);if(!match)return[0,0,0];return[Number.parseInt(match[1],16),Number.parseInt(match[2],16),Number.parseInt(match[3],16)]}function luminance([red,green,blue]){return(red*0.2126+green*0.7152+blue*0.0722)/255}function blend(from,to,amount){return[Math.round(from[0]+(to[0]-from[0])*amount),Math.round(from[1]+(to[1]-from[1])*amount),Math.round(from[2]+(to[2]-from[2])*amount)]}function codexUserMessageBackground(background){return luminance(background)>0.5?blend(background,[0,0,0],0.04):blend(background,[255,255,255],0.12)}function transcriptRewrite(palette){let foreground=parseHex(palette.foreground),background=parseHex(palette.background),backgroundIsLight=luminance(background)>0.5;return{matchBackground:codexUserMessageBackground(background),foreground:backgroundIsLight?foreground:background,background:backgroundIsLight?background:foreground}}var codexTerminalPresentation={alternateScreenStyleRewrites:(palette)=>[transcriptRewrite(palette)]};var codexCapabilities={preparePromptSubmission:(prompt)=>{return/^[\/!]/.test(prompt.trimStart())?prompt:`${prompt} `},beforePromptSubmit:"\x1B[F",terminalPresentation:codexTerminalPresentation,interruptSequence:"\x1B"},codexIdentity={shortName:"Codex"};import{join}from"path";var EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"}],KOBE_CODEX_HOOK_EVENTS=EVENT_MAP.map((e)=>e.event);function codexHooksPath(){return join(vendorConfigHome("codex"),"hooks.json")}class CodexHookAdapter extends JsonHookAdapter{vendor="codex";eventMap=EVENT_MAP;globalSettingsPath(){return codexHooksPath()}activityDetailFromPayload(kind,payload){if(kind==="tool-pre"||kind==="tool-post")return{tool:{...typeof payload.tool_name==="string"?{name:payload.tool_name}:{}}};if(kind==="pre-compact"||kind==="post-compact")return{compact:{trigger:payload.trigger==="manual"?"manual":"auto"}};return}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}}import{createHash}from"crypto";function createAppendParseCache(opts){let maxFiles=opts.maxFiles??8,cache=new Map;function remember(filePath,entry){if(cache.delete(filePath),cache.set(filePath,entry),cache.size>maxFiles){let oldest=cache.keys().next().value;if(oldest!==void 0)cache.delete(oldest)}}return function(filePath,raw,ctx){let stableLength=raw.lastIndexOf(`
4
4
  `)+1,entry=cache.get(filePath),verifiedLength=Math.min(entry?.prefixLength??0,stableLength),hash=createHash("sha256").update(raw.slice(0,verifiedLength)),unchanged=entry!==void 0&&Object.is(entry.context,ctx)&&entry.prefixLength<=stableLength&&hash.copy().digest("hex")===entry.prefixHash,prefixState;if(unchanged)prefixState=entry.prefixLength<stableLength?opts.parseChunk(raw.slice(entry.prefixLength,stableLength),entry.state,ctx):entry.state;else prefixState=opts.parseChunk(raw.slice(0,stableLength),opts.initial(ctx),ctx);if(!unchanged||entry.prefixLength!==stableLength||entry.state!==prefixState)remember(filePath,{context:ctx,prefixLength:stableLength,prefixHash:hash.update(raw.slice(verifiedLength,stableLength)).digest("hex"),state:prefixState});let tail=raw.slice(stableLength);return tail.trim().length>0?opts.parseChunk(tail,prefixState,ctx):prefixState}}var sortedMessages=new WeakMap;function sortByTimestamp(messages){let hit=sortedMessages.get(messages);if(hit)return hit;let sorted=[...messages].sort((a,b)=>a.timestamp<b.timestamp?-1:a.timestamp>b.timestamp?1:0);return sortedMessages.set(messages,sorted),sorted}function normalizeCodexContent(raw){if(typeof raw==="string")return raw.length>0?[{type:"text",text:raw}]:[];if(!Array.isArray(raw))return[];let blocks=[];for(let item of raw){if(typeof item==="string"){if(item.length>0)blocks.push({type:"text",text:item});continue}if(!isObject3(item))continue;let t=typeof item.type==="string"?item.type:void 0;if(t==="input_text"||t==="output_text"){let text=typeof item.text==="string"?item.text:"";if(text.length>0)blocks.push({type:"text",text});continue}if(t)blocks.push({type:"text",text:`[codex: ${t}]`})}return blocks}function isObject3(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function isSyntheticCodexUserRow(blocks){if(blocks.length===0)return!1;for(let b of blocks){if(b.type!=="text")return!1;let t=(b.text??"").trim();if(!isTagEnvelope(t)&&!isInstructionsEnvelope(t))return!1}return!0}var ENVELOPE_TAGS=["environment_context","recommended_plugins","user_instructions"];function isTagEnvelope(text){return ENVELOPE_TAGS.some((tag)=>text.startsWith(`<${tag}>`)&&text.endsWith(`</${tag}>`))}function isInstructionsEnvelope(text){return text.startsWith("# AGENTS.md instructions")&&text.includes("<INSTRUCTIONS>")}function codexUsageToSnapshot(usage,opts={}){let totalInput=numberOr(usage.input_tokens,0),cachedInput=numberOr(usage.cached_input_tokens,0),output=numberOr(usage.output_tokens,0),nonCachedInput=Math.max(0,totalInput-cachedInput);if(totalInput<=0&&output<=0&&cachedInput<=0)return;return{input_tokens:nonCachedInput,output_tokens:output,...cachedInput>0?{cache_read_input_tokens:cachedInput}:{},...validPositive(opts.contextWindowTokens)?{context_window_tokens:opts.contextWindowTokens}:{}}}function numberOr(v,fallback){return typeof v==="number"&&Number.isFinite(v)?v:fallback}function validPositive(v){return typeof v==="number"&&Number.isFinite(v)&&v>0}var emptyState={messages:[],latestUsage:void 0,latestUsageTimestampMs:null},cache=createAppendParseCache({initial:()=>emptyState,parseChunk:foldRolloutChunk});function parseRolloutRaw(filePath,raw,sessionId){let state=cache(filePath,raw,sessionId);return{messages:sortByTimestamp(state.messages),...state.latestUsage?{usageMetrics:state.latestUsage}:{}}}function foldRolloutChunk(chunk,prev,sessionId){let updatedMessages,writableMessages=()=>{return updatedMessages??=[...prev.messages],updatedMessages},latestUsage=prev.latestUsage,latestUsageTimestampMs=prev.latestUsageTimestampMs;for(let line of chunk.split(`
5
5
  `)){let trimmed=line.trim();if(!trimmed)continue;if(!isJsonlLineWithinBound(trimmed))continue;let parsed;try{parsed=JSON.parse(trimmed)}catch{continue}if(!isObject4(parsed))continue;if(parsed.type==="response_item"){let payload=isObject4(parsed.payload)?parsed.payload:void 0;if(!payload)continue;let ts=typeof parsed.timestamp==="string"?parsed.timestamp:new Date().toISOString(),msg=normalizeCodexResponseItem(payload,ts,sessionId);if(msg)writableMessages().push(msg);continue}let usageFields=codexUsageFields(parsed);if(!usageFields)continue;let base=codexUsageToSnapshot(usageFields.usage,{contextWindowTokens:usageFields.contextWindow});if(!base)continue;let lastPrompt=usageFields.lastUsage?numberOr2(usageFields.lastUsage.input_tokens):0,snapshot={...base,...lastPrompt>0?{context_tokens:lastPrompt}:{}},lastUsage=usageFields.lastUsage&&codexLastUsageToMessageUsage(usageFields.lastUsage);if(lastUsage){let messages=updatedMessages??prev.messages,index=messages.findLastIndex((message2)=>message2.role==="assistant"),message=messages[index];if(message)writableMessages()[index]={...message,usage:lastUsage}}let timestampMs=typeof parsed.timestamp==="string"?parseTimestampMs(parsed.timestamp):null;if(timestampMs!==null&&(latestUsageTimestampMs===null||timestampMs>latestUsageTimestampMs))latestUsageTimestampMs=timestampMs,latestUsage=snapshot;else if(latestUsageTimestampMs===null)latestUsage=snapshot}return{messages:updatedMessages??prev.messages,latestUsage,latestUsageTimestampMs}}function codexUsageFields(parsed){if(parsed.type==="event_msg"){let payload=isObject4(parsed.payload)?parsed.payload:void 0;if(payload?.type!=="token_count")return;let info=isObject4(payload.info)?payload.info:void 0,usage=info&&isObject4(info.total_token_usage)?info.total_token_usage:void 0;if(!usage)return;let lastUsage=info&&isObject4(info.last_token_usage)?info.last_token_usage:void 0,contextWindow=typeof info?.model_context_window==="number"?info.model_context_window:void 0;return{usage,lastUsage,contextWindow}}if(parsed.type==="turn.completed"){let usage=isObject4(parsed.usage)?parsed.usage:void 0;return usage?{usage,lastUsage:usage,contextWindow:void 0}:void 0}return}function codexLastUsageToMessageUsage(usage){let totalInput=numberOr2(usage.input_tokens),cachedInput=numberOr2(usage.cached_input_tokens),output=numberOr2(usage.output_tokens);if(totalInput<=0&&output<=0&&cachedInput<=0)return;return{input_tokens:Math.max(0,totalInput-cachedInput),output_tokens:output,...cachedInput>0?{cache_read_input_tokens:cachedInput}:{}}}function numberOr2(v){return typeof v==="number"&&Number.isFinite(v)?v:0}function normalizeCodexResponseItem(payload,timestamp,sessionId){if(payload.type==="message"){let role=payload.role;if(role!=="user"&&role!=="assistant"&&role!=="system")return;let blocks=normalizeCodexContent(payload.content);if(role==="user"&&isSyntheticCodexUserRow(blocks))return;return{role,blocks,timestamp,sessionId}}if(payload.type==="reasoning")return normalizeCodexReasoning(payload,timestamp,sessionId);if(payload.type==="function_call")return normalizeCodexToolCall(payload,timestamp,sessionId,{name:stringOr(payload.name,"function_call"),input:parseMaybeJson(payload.arguments)});if(payload.type==="custom_tool_call")return normalizeCodexToolCall(payload,timestamp,sessionId,{name:stringOr(payload.name,"custom_tool_call"),input:parseMaybeJson(payload.input)});if(payload.type==="tool_search_call")return normalizeCodexToolCall(payload,timestamp,sessionId,{name:"tool_search_call",input:stripPayload(payload,["type","call_id","status"])});if(payload.type==="function_call_output"||payload.type==="custom_tool_call_output")return normalizeCodexToolResult(payload,timestamp,sessionId,parseMaybeJson(payload.output));if(payload.type==="tool_search_output")return normalizeCodexToolResult(payload,timestamp,sessionId,stripPayload(payload,["type","call_id"]));if(payload.type==="web_search_call"||payload.type==="image_generation_call"||payload.type==="local_shell_call")return normalizeSingleRecordTool(payload,timestamp,sessionId);return}function normalizeCodexReasoning(payload,timestamp,sessionId){let text=reasoningTextFromItem(payload);if(text.length===0)return;return{role:"assistant",blocks:[{type:"thinking",text}],timestamp,sessionId}}function normalizeCodexToolCall(payload,timestamp,sessionId,args){let callId=typeof payload.call_id==="string"?payload.call_id:void 0;if(!callId)return;return{role:"assistant",blocks:[{type:"tool_call",callId,name:args.name,input:args.input}],timestamp,sessionId}}function normalizeCodexToolResult(payload,timestamp,sessionId,output){let callId=typeof payload.call_id==="string"?payload.call_id:void 0;if(!callId)return;return{role:"user",blocks:[{type:"tool_result",callId,output,isError:!1}],timestamp,sessionId}}var CODEX_OK_STATUSES=new Set(["completed","in_progress"]);function normalizeSingleRecordTool(payload,timestamp,sessionId){let type=typeof payload.type==="string"?payload.type:"tool",callId=typeof payload.call_id==="string"&&payload.call_id.length>0?payload.call_id:`${type}:${timestamp}`,name=stringOr(payload.name,type),input=stripPayload(payload,["type","call_id","status"]),output=stripPayload(payload,["type","call_id"]),status=payload.status,isError=typeof status==="string"&&!CODEX_OK_STATUSES.has(status);return{role:"assistant",timestamp,sessionId,blocks:[{type:"tool_call",callId,name,input},{type:"tool_result",callId,output,isError}]}}function reasoningTextFromItem(item){let content=textFromReasoningValue(item.content);if(content.length>0)return content;let text=typeof item.text==="string"?item.text:"";if(text.length>0)return text;return textFromReasoningValue(item.summary)}function textFromReasoningValue(value){if(typeof value==="string")return value;if(!Array.isArray(value))return"";let parts=[];for(let entry of value){if(typeof entry==="string"){parts.push(entry);continue}if(!isObject4(entry))continue;let text=typeof entry.text==="string"?entry.text:"";if(text.length>0)parts.push(text)}return parts.join("")}function stripPayload(payload,keys){let out={};for(let[key,value]of Object.entries(payload))if(!keys.includes(key))out[key]=value;return out}function stringOr(value,fallback){return typeof value==="string"&&value.length>0?value:fallback}function parseMaybeJson(value){if(typeof value!=="string")return value;try{return JSON.parse(value)}catch{return value}}function parseTimestampMs(value){let ms=new Date(value).getTime();return Number.isFinite(ms)?ms:null}function isObject4(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}import{readdir,stat}from"fs/promises";import path2 from"path";var defaultHistoryDeps={sessionsDir:()=>path2.join(vendorConfigHome("codex"),"sessions"),readdir:(p)=>readdir(p),readFile:readTextFileBounded,readHead:readFirstLineBounded,stat},UUID_AT_END=/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i,FULL_UUID=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,IO_CONCURRENCY=8;function sameStamp(a,b){return a.mtimeMs===b.mtimeMs&&a.size===b.size&&a.ctimeMs===b.ctimeMs&&a.ino===b.ino&&a.dev===b.dev}function rolloutCwd(raw){for(let line of raw.split(`
@@ -25,7 +25,7 @@ ${body}
25
25
  `)){let match=rawLine.replace(/\r$/,"").match(/^([A-Za-z_]+):\s*(.*)$/);if(!match)continue;let key=match[1],value=match[2]??"";if(value.startsWith('"')&&value.endsWith('"'))value=value.slice(1,-1).replace(/\\"/g,'"');out[key]=value}return{id:out.id,cwd:out.cwd,name:out.name,updatedAt:out.updated_at,createdAt:out.created_at}}function initialParseState(fallbackSessionId){return{messages:[],sessionId:fallbackSessionId,usageMetrics:void 0,firstUserMessage:null}}var eventsCache=createAppendParseCache({initial:initialParseState,parseChunk:(chunk,prev)=>foldEvents(chunk,prev)});function foldEvents(raw,prev){let updatedMessages,appendMessage=(message)=>{updatedMessages??=[...prev.messages],updatedMessages.push(message)},sessionId=prev.sessionId,usageMetrics=prev.usageMetrics,firstUserMessage=prev.firstUserMessage;for(let line of raw.split(`
26
26
  `)){let trimmed=line.trim();if(!trimmed)continue;if(!isJsonlLineWithinBound(trimmed))continue;let record;try{record=JSON.parse(trimmed)}catch{continue}if(!isObject7(record)||typeof record.type!=="string")continue;let timestamp=typeof record.timestamp==="string"?record.timestamp:new Date().toISOString(),data=isObject7(record.data)?record.data:{};if(record.type==="session.start"){let sid=typeof data.sessionId==="string"?data.sessionId:void 0;if(sid)sessionId=sid;continue}if(record.type==="user.message"){let text=typeof data.content==="string"?data.content:"";if(!text)continue;if(!firstUserMessage)firstUserMessage=Buffer.from(text.slice(0,PREVIEW_CHAR_CAP),"utf8").toString("utf8");appendMessage({role:"user",blocks:[{type:"text",text}],timestamp,sessionId});continue}if(record.type==="assistant.message"){let blocks=[],text=typeof data.content==="string"?data.content:"";if(text)blocks.push({type:"text",text});let toolRequests=Array.isArray(data.toolRequests)?data.toolRequests:[];for(let req of toolRequests){if(!isObject7(req))continue;let callId=typeof req.id==="string"?req.id:typeof req.toolCallId==="string"?req.toolCallId:"tool",name=typeof req.name==="string"?req.name:typeof req.toolName==="string"?req.toolName:"tool";blocks.push({type:"tool_call",callId,name,input:req.arguments??{}})}if(blocks.length>0)appendMessage({role:"assistant",blocks,timestamp,sessionId});continue}if(record.type==="tool.execution_complete"){let callId=typeof data.toolCallId==="string"?data.toolCallId:void 0;if(!callId)continue;let output=data.result??(data.success===!1?{success:!1}:void 0);appendMessage({role:"assistant",blocks:[{type:"tool_result",callId,output,isError:data.success===!1}],timestamp,sessionId});continue}if(record.type==="session.shutdown")usageMetrics=copilotUsageToSnapshot(data)}return{messages:updatedMessages??prev.messages,sessionId,usageMetrics,firstUserMessage}}var PREVIEW_CHAR_CAP=200;function isObject7(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}import{stat as stat4}from"fs/promises";import path6 from"path";var defaultDeps3={kimiDir(){return vendorConfigHome("kimi")},async readFile(p){return await readTextFileBounded(p)},stat:stat4};function parseSessionIndex(raw){let out=[];for(let line of raw.split(`
27
27
  `)){if(!isJsonlLineWithinBound(line)||!line.trim())continue;try{let record=JSON.parse(line);if(typeof record!=="object"||record===null)continue;if(!("sessionId"in record)||!("sessionDir"in record)||!("workDir"in record))continue;let{sessionId,sessionDir,workDir}=record;if(typeof sessionId==="string"&&sessionId&&typeof sessionDir==="string"&&sessionDir&&typeof workDir==="string"&&workDir)out.push({sessionId,sessionDir,workDir})}catch{}}return out}async function sessionIndex(deps){let raw=await deps.readFile(path6.join(deps.kimiDir(),"session_index.jsonl")).catch(()=>"");return parseSessionIndex(raw)}function wirePath(sessionDir){return path6.join(sessionDir,"agents","main","wire.jsonl")}async function worktreeSessionFiles(worktree,deps){if(!worktree)return[];let matches=[];for(let entry of await sessionIndex(deps)){if(!samePath(entry.workDir,worktree))continue;let file=wirePath(entry.sessionDir),info=await deps.stat(file).catch(()=>null);if(info)matches.push({id:entry.sessionId,mtimeMs:info.mtimeMs})}return matches.sort((a,b)=>a.mtimeMs-b.mtimeMs)}async function listSessionIdsForWorktree3(worktree,deps=defaultDeps3){return(await worktreeSessionFiles(worktree,deps)).map((file)=>file.id)}async function latestTranscriptMtimeForWorktree4(worktree,deps=defaultDeps3){return(await worktreeSessionFiles(worktree,deps)).at(-1)?.mtimeMs??0}async function transcriptPath(sessionId,deps=defaultDeps3){if(!sessionId)return null;let entry=(await sessionIndex(deps)).find((e)=>e.sessionId===sessionId);if(!entry)return null;let file=wirePath(entry.sessionDir);return await deps.stat(file).then(()=>file).catch(()=>null)}function normalizePiContent(content){if(typeof content==="string")return content.length>0?[{type:"text",text:content}]:[];if(!Array.isArray(content))return[];let out=[];for(let block of content){if(typeof block==="string"){if(block.length>0)out.push({type:"text",text:block});continue}if(!block||typeof block!=="object")continue;let b=block;if(b.type==="text"&&typeof b.text==="string"){out.push({type:"text",text:b.text});continue}if(b.type==="thinking"&&typeof b.thinking==="string"){out.push({type:"thinking",text:b.thinking});continue}if(b.type==="toolCall"||b.type==="tool_use"){out.push({type:"tool_call",callId:typeof b.id==="string"?b.id:"",name:typeof b.name==="string"?b.name:"",input:b.arguments??b.input});continue}if(b.type==="toolResult"||b.type==="tool_result")out.push({type:"tool_result",callId:typeof b.toolCallId==="string"?b.toolCallId:typeof b.tool_use_id==="string"?b.tool_use_id:"",output:b.content,isError:b.isError===!0||b.is_error===!0})}return out}var ROLE_MAP={user:"user",assistant:"assistant",toolResult:"assistant",system:"system"},emptyState2={messages:[],usage:void 0},cache3=createAppendParseCache({initial:()=>emptyState2,parseChunk:foldChunk});function parsePiSessionRaw(filePath,raw,sessionId){let state=cache3(filePath,raw,sessionId);return{messages:sortByTimestamp(state.messages),...state.usage?{usageMetrics:state.usage}:{}}}function foldChunk(chunk,prev,sessionId){let messages,usage=prev.usage;for(let line of chunk.split(`
28
- `)){let trimmed=line.trim();if(!trimmed||!isJsonlLineWithinBound(trimmed))continue;let record;try{record=JSON.parse(trimmed)}catch{continue}if(!record||typeof record!=="object")continue;let entry=record;if(entry.type!=="message")continue;let message=entry.message;if(!message||typeof message!=="object")continue;let m=message,role=typeof m.role==="string"?ROLE_MAP[m.role]:void 0;if(!role)continue;let blocks=m.role==="toolResult"?[{type:"tool_result",callId:typeof m.toolCallId==="string"?m.toolCallId:"",output:m.content,isError:m.isError===!0}]:normalizePiContent(m.content);if(blocks.length===0)continue;let usageSnapshot=role==="assistant"?usageFromMessage(m):void 0;if(usageSnapshot)usage=usageSnapshot;if(!messages)messages=[...prev.messages];messages.push({role,blocks,timestamp:timestampOf(entry,m),sessionId,...usageSnapshot?{usage:usageSnapshot}:{}})}return messages?{messages,usage}:{messages:prev.messages,usage}}function timestampOf(entry,message){if(typeof entry.timestamp==="string")return entry.timestamp;let ms=typeof message.timestamp==="number"?message.timestamp:void 0;return ms===void 0?new Date(0).toISOString():new Date(ms).toISOString()}function usageFromMessage(message){let usage=message.usage;if(!usage||typeof usage!=="object")return;let u=usage,num3=(v)=>typeof v==="number"&&Number.isFinite(v)?v:0,input=u.input??u.input_tokens,output=u.output??u.output_tokens;if(input===void 0&&output===void 0)return;let cacheRead=u.cacheRead??u.cache_read_input_tokens,cacheWrite=u.cacheWrite??u.cache_creation_input_tokens;return{input_tokens:num3(input),output_tokens:num3(output),...typeof cacheRead==="number"?{cache_read_input_tokens:cacheRead}:{},...typeof cacheWrite==="number"?{cache_creation_input_tokens:cacheWrite}:{}}}import{realpathSync}from"fs";import{readdir as readdir4,stat as stat5}from"fs/promises";import{homedir as homedir3,tmpdir}from"os";import path7 from"path";var defaultPiHistoryDeps={home:()=>homedir3(),env:(name)=>process.env[name],tmpdir:()=>tmpdir(),realpath:(p)=>{try{return realpathSync(p)}catch{return p}},readdir:async(p)=>readdir4(p),stat:async(p)=>{try{let s=await stat5(p);return{mtimeMs:s.mtimeMs,isFile:s.isFile()}}catch{return null}},readFile:(p)=>readTextFileIfRegular(p)};function piSessionsRoot(vendor,deps=defaultPiHistoryDeps){return path7.join(vendorAgentDir(vendor,{env:deps.env,home:deps.home}),"sessions")}function encodeAbsolute(p){return`--${p.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`}function encodeRelative(prefix,relative){let encoded=relative.replace(/[/\\:]/g,"-");if(!encoded)return prefix;return prefix.endsWith("-")?`${prefix}${encoded}`:`${prefix}-${encoded}`}function within(root,p){let rel=path7.relative(root,p);if(rel==="")return"";if(rel.startsWith("..")||path7.isAbsolute(rel))return null;return rel}function sessionDirNamesForWorktree(vendor,worktree,deps=defaultPiHistoryDeps){let resolved=deps.realpath(worktree),names=[],add=(name)=>{if(!names.includes(name))names.push(name)};if(vendor==="omp"){let home=within(deps.realpath(deps.home()),resolved);if(home!==null)add(encodeRelative("-",home));let temp=within(deps.realpath(deps.tmpdir()),resolved);if(temp!==null)add(encodeRelative("-tmp",temp))}return add(encodeAbsolute(resolved)),names}function sessionIdFromFileName(fileName){if(!fileName.endsWith(".jsonl"))return null;let base=fileName.slice(0,-6),separator=base.lastIndexOf("_"),id=separator>=0?base.slice(separator+1):base;return id.length>0?id:null}async function worktreeSessionFiles2(vendor,worktree,deps=defaultPiHistoryDeps){let root=piSessionsRoot(vendor,deps),out=[];for(let dirName of sessionDirNamesForWorktree(vendor,worktree,deps)){let dir=path7.join(root,dirName),entries;try{entries=await deps.readdir(dir)}catch{continue}for(let entry of entries){let sessionId=sessionIdFromFileName(entry);if(!sessionId)continue;let file=path7.join(dir,entry),info=await deps.stat(file);if(!info?.isFile)continue;out.push({sessionId,path:file,mtimeMs:info.mtimeMs})}}return out.sort((a,b)=>a.mtimeMs-b.mtimeMs)}async function listSessionIdsForWorktree4(vendor,worktree,deps=defaultPiHistoryDeps){return(await worktreeSessionFiles2(vendor,worktree,deps)).map((f)=>f.sessionId)}async function latestTranscriptMtimeForWorktree5(vendor,worktree,deps=defaultPiHistoryDeps){return(await worktreeSessionFiles2(vendor,worktree,deps)).at(-1)?.mtimeMs??0}async function transcriptPath2(vendor,sessionId,worktree,deps=defaultPiHistoryDeps){return(await worktreeSessionFiles2(vendor,worktree,deps)).find((f)=>f.sessionId===sessionId)?.path??null}async function findSessionFile(vendor,sessionId,deps=defaultPiHistoryDeps){let root=piSessionsRoot(vendor,deps),dirs;try{dirs=await deps.readdir(root)}catch{return null}for(let dir of dirs){let entries;try{entries=await deps.readdir(path7.join(root,dir))}catch{continue}let match=entries.find((entry)=>sessionIdFromFileName(entry)===sessionId);if(match)return path7.join(root,dir,match)}return null}async function readHistory4(vendor,sessionId,deps=defaultPiHistoryDeps){let file=await findSessionFile(vendor,sessionId,deps);if(!file)return[];let raw=await deps.readFile(file);if(raw===null)return[];return parsePiSessionRaw(file,raw,sessionId).messages}var EMPTY_HISTORY={async listSessionIdsForWorktree(){return[]},async readHistory(){return[]},async transcriptPath(){return null},async latestTranscriptMtimeForWorktree(){return 0}},claudeHistoryReader={async listSessionIdsForWorktree(worktree){return[...await listSessionFilesForWorktree(worktree)].sort((a,b)=>a.mtimeMs-b.mtimeMs).map((f)=>f.sessionId)},readHistory:(sessionId)=>readHistory2(sessionId),readUsageSnapshot:(sessionId)=>readUsageSnapshot(sessionId),async transcriptPath(sessionId,worktree){return(await listSessionFilesForWorktree(worktree)).find((f)=>f.sessionId===sessionId)?.path??null},latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree2(worktree)},codexHistoryReader={listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree(worktree),readHistory:(sessionId)=>readHistory(sessionId),readUsageSnapshot:async(sessionId)=>(await readHistoryWithMetrics(sessionId)).usageMetrics,transcriptPath:async(sessionId)=>await findRolloutFile(sessionId)??null,latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree(worktree)},copilotHistoryReader={listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree2(worktree),readHistory:(sessionId)=>readHistory3(sessionId),readUsageSnapshot:async(sessionId)=>(await readHistoryWithMetrics2(sessionId)).usageMetrics,async transcriptPath(sessionId){let dir=await findSessionDir(sessionId);return dir?path8.join(dir,"events.jsonl"):null},latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree3(worktree)},kimiHistoryReader={listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree3(worktree),readHistory:EMPTY_HISTORY.readHistory,transcriptPath:(sessionId)=>transcriptPath(sessionId),latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree4(worktree)};function piFamilyHistoryReader(vendor){return{listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree4(vendor,worktree),readHistory:(sessionId)=>readHistory4(vendor,sessionId),readUsageSnapshot:async(sessionId)=>{let file=await findSessionFile(vendor,sessionId);if(!file)return;let raw=await readTextFileIfRegular(file);if(raw===null)return;return parsePiSessionRaw(file,raw,sessionId).usageMetrics},transcriptPath:(sessionId,worktree)=>transcriptPath2(vendor,sessionId,worktree),latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree5(vendor,worktree)}}var piHistoryReader=piFamilyHistoryReader("pi"),ompHistoryReader=piFamilyHistoryReader("omp");import{existsSync}from"fs";import{mkdir as mkdir2,readFile,writeFile}from"fs/promises";import{homedir as homedir4}from"os";import{dirname,join as join2}from"path";var KIMI_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"StopFailure",verb:"turn-failed"},{event:"Interrupt",verb:"turn-interrupted"},{event:"PermissionRequest",verb:"awaiting-input"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"},{event:"PostToolUseFailure",verb:"tool-failed"}],KOBE_KIMI_HOOK_EVENTS=[...new Set(KIMI_HOOK_EVENT_MAP.map((e)=>e.event))],BLOCK_BEGIN="# >>> rove hooks",BLOCK_END="# <<< rove hooks",HOOK_TIMEOUT_SECONDS=10;function kimiConfigPath(home=homedir4()){return join2(vendorConfigHome("kimi",{env:(k)=>process.env[k],home:()=>home}),"config.toml")}function renderKimiHookBlock(inv=kobeHookInvocation(),opts={}){let lines=[BLOCK_BEGIN];for(let spec of KIMI_HOOK_EVENT_MAP){if(!opts.toolEvents&&GATED_TOOL_VERBS.has(spec.verb))continue;let command=quoteShellArgv([...inv,"hook",spec.verb,"--engine","kimi"],hookCommandQuoting());if(lines.push("[[hooks]]"),lines.push(`event = ${JSON.stringify(spec.event)}`),spec.matcher)lines.push(`matcher = ${JSON.stringify(spec.matcher)}`);lines.push(`command = ${JSON.stringify(command)}`),lines.push(`timeout = ${HOOK_TIMEOUT_SECONDS}`),lines.push("")}return lines.push(BLOCK_END),lines.join(`
28
+ `)){let trimmed=line.trim();if(!trimmed||!isJsonlLineWithinBound(trimmed))continue;let record;try{record=JSON.parse(trimmed)}catch{continue}if(!record||typeof record!=="object")continue;let entry=record;if(entry.type!=="message")continue;let message=entry.message;if(!message||typeof message!=="object")continue;let m=message,role=typeof m.role==="string"?ROLE_MAP[m.role]:void 0;if(!role)continue;let blocks=m.role==="toolResult"?[{type:"tool_result",callId:typeof m.toolCallId==="string"?m.toolCallId:"",output:m.content,isError:m.isError===!0}]:normalizePiContent(m.content);if(blocks.length===0)continue;let usageSnapshot=role==="assistant"?usageFromMessage(m):void 0;if(usageSnapshot)usage=usageSnapshot;if(!messages)messages=[...prev.messages];messages.push({role,blocks,timestamp:timestampOf(entry,m),sessionId,...usageSnapshot?{usage:usageSnapshot}:{}})}return messages?{messages,usage}:{messages:prev.messages,usage}}function timestampOf(entry,message){if(typeof entry.timestamp==="string")return entry.timestamp;let ms=typeof message.timestamp==="number"?message.timestamp:void 0;return ms===void 0?new Date(0).toISOString():new Date(ms).toISOString()}function usageFromMessage(message){let usage=message.usage;if(!usage||typeof usage!=="object")return;let u=usage,num3=(v)=>typeof v==="number"&&Number.isFinite(v)?v:0,input=u.input??u.input_tokens,output=u.output??u.output_tokens;if(input===void 0&&output===void 0)return;let cacheRead=u.cacheRead??u.cache_read_input_tokens,cacheWrite=u.cacheWrite??u.cache_creation_input_tokens;return{input_tokens:num3(input),output_tokens:num3(output),...typeof cacheRead==="number"?{cache_read_input_tokens:cacheRead}:{},...typeof cacheWrite==="number"?{cache_creation_input_tokens:cacheWrite}:{}}}import{realpathSync}from"fs";import{readdir as readdir4,stat as stat5}from"fs/promises";import{homedir as homedir3,tmpdir}from"os";import path7 from"path";var defaultPiHistoryDeps={home:()=>homedir3(),env:(name)=>process.env[name],tmpdir:()=>tmpdir(),realpath:(p)=>{try{return realpathSync(p)}catch{return p}},readdir:async(p)=>readdir4(p),stat:async(p)=>{try{let s=await stat5(p);return{mtimeMs:s.mtimeMs,isFile:s.isFile()}}catch{return null}},readFile:(p)=>readTextFileIfRegular(p)};function piSessionsRoot(vendor,deps=defaultPiHistoryDeps){return path7.join(vendorAgentDir(vendor,{env:deps.env,home:deps.home}),"sessions")}function encodeAbsolute(p){return`--${p.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`}function encodeRelative(prefix,relative){let encoded=relative.replace(/[/\\:]/g,"-");if(!encoded)return prefix;return prefix.endsWith("-")?`${prefix}${encoded}`:`${prefix}-${encoded}`}function within(root,p){let rel=path7.relative(root,p);if(rel==="")return"";if(rel.startsWith("..")||path7.isAbsolute(rel))return null;return rel}function sessionDirNamesForWorktree(vendor,worktree,deps=defaultPiHistoryDeps){let resolved=deps.realpath(worktree),names=[],add=(name)=>{if(!names.includes(name))names.push(name)};if(vendor==="omp"){let home=within(deps.realpath(deps.home()),resolved);if(home!==null)add(encodeRelative("-",home));let temp=within(deps.realpath(deps.tmpdir()),resolved);if(temp!==null)add(encodeRelative("-tmp",temp))}return add(encodeAbsolute(resolved)),names}function sessionIdFromFileName(fileName){if(!fileName.endsWith(".jsonl"))return null;let base=fileName.slice(0,-6),separator=base.lastIndexOf("_"),id=separator>=0?base.slice(separator+1):base;return id.length>0?id:null}async function worktreeSessionFiles2(vendor,worktree,deps=defaultPiHistoryDeps){let root=piSessionsRoot(vendor,deps),out=[];for(let dirName of sessionDirNamesForWorktree(vendor,worktree,deps)){let dir=path7.join(root,dirName),entries;try{entries=await deps.readdir(dir)}catch{continue}for(let entry of entries){let sessionId=sessionIdFromFileName(entry);if(!sessionId)continue;let file=path7.join(dir,entry),info=await deps.stat(file);if(!info?.isFile)continue;out.push({sessionId,path:file,mtimeMs:info.mtimeMs})}}return out.sort((a,b)=>a.mtimeMs-b.mtimeMs)}async function listSessionIdsForWorktree4(vendor,worktree,deps=defaultPiHistoryDeps){return(await worktreeSessionFiles2(vendor,worktree,deps)).map((f)=>f.sessionId)}async function latestTranscriptMtimeForWorktree5(vendor,worktree,deps=defaultPiHistoryDeps){return(await worktreeSessionFiles2(vendor,worktree,deps)).at(-1)?.mtimeMs??0}async function transcriptPath2(vendor,sessionId,worktree,deps=defaultPiHistoryDeps){return(await worktreeSessionFiles2(vendor,worktree,deps)).find((f)=>f.sessionId===sessionId)?.path??null}async function findSessionFile(vendor,sessionId,deps=defaultPiHistoryDeps){let root=piSessionsRoot(vendor,deps),dirs;try{dirs=await deps.readdir(root)}catch{return null}for(let dir of dirs){let entries;try{entries=await deps.readdir(path7.join(root,dir))}catch{continue}let match=entries.find((entry)=>sessionIdFromFileName(entry)===sessionId);if(match)return path7.join(root,dir,match)}return null}async function readHistory4(vendor,sessionId,deps=defaultPiHistoryDeps){let file=await findSessionFile(vendor,sessionId,deps);if(!file)return[];let raw=await deps.readFile(file);if(raw===null)return[];return parsePiSessionRaw(file,raw,sessionId).messages}var EMPTY_HISTORY={async listSessionIdsForWorktree(){return[]},async readHistory(){return[]},async transcriptPath(){return null},async latestTranscriptMtimeForWorktree(){return 0}},claudeHistoryReader={async listSessionIdsForWorktree(worktree){return[...await listSessionFilesForWorktree(worktree)].sort((a,b)=>a.mtimeMs-b.mtimeMs).map((f)=>f.sessionId)},readHistory:(sessionId)=>readHistory2(sessionId),readUsageSnapshot:(sessionId)=>readUsageSnapshot(sessionId),async transcriptPath(sessionId,worktree){return(await listSessionFilesForWorktree(worktree)).find((f)=>f.sessionId===sessionId)?.path??null},latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree2(worktree)},codexHistoryReader={listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree(worktree),readHistory:(sessionId)=>readHistory(sessionId),readUsageSnapshot:async(sessionId)=>(await readHistoryWithMetrics(sessionId)).usageMetrics,transcriptPath:async(sessionId)=>await findRolloutFile(sessionId)??null,latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree(worktree)},copilotHistoryReader={listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree2(worktree),readHistory:(sessionId)=>readHistory3(sessionId),readUsageSnapshot:async(sessionId)=>(await readHistoryWithMetrics2(sessionId)).usageMetrics,async transcriptPath(sessionId){let dir=await findSessionDir(sessionId);return dir?path8.join(dir,"events.jsonl"):null},latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree3(worktree)},kimiHistoryReader={listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree3(worktree),readHistory:EMPTY_HISTORY.readHistory,transcriptPath:(sessionId)=>transcriptPath(sessionId),latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree4(worktree)};function piFamilyHistoryReader(vendor){return{listSessionIdsForWorktree:(worktree)=>listSessionIdsForWorktree4(vendor,worktree),readHistory:(sessionId)=>readHistory4(vendor,sessionId),readUsageSnapshot:async(sessionId)=>{let file=await findSessionFile(vendor,sessionId);if(!file)return;let raw=await readTextFileIfRegular(file);if(raw===null)return;return parsePiSessionRaw(file,raw,sessionId).usageMetrics},transcriptPath:(sessionId,worktree)=>transcriptPath2(vendor,sessionId,worktree),latestTranscriptMtimeForWorktree:(worktree)=>latestTranscriptMtimeForWorktree5(vendor,worktree)}}var piHistoryReader=piFamilyHistoryReader("pi"),ompHistoryReader=piFamilyHistoryReader("omp");import{existsSync}from"fs";import{mkdir as mkdir2,readFile,writeFile}from"fs/promises";import{homedir as homedir4}from"os";import{dirname,join as join2}from"path";var KIMI_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"StopFailure",verb:"turn-failed"},{event:"Interrupt",verb:"turn-interrupted"},{event:"PermissionRequest",verb:"awaiting-input"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"},{event:"PostToolUseFailure",verb:"tool-failed"}],KOBE_KIMI_HOOK_EVENTS=[...new Set(KIMI_HOOK_EVENT_MAP.map((e)=>e.event))],BLOCK_BEGIN="# >>> rove hooks",BLOCK_END="# <<< rove hooks",HOOK_TIMEOUT_SECONDS=10;function kimiConfigPath(home=homedir4()){return join2(vendorConfigHome("kimi",{env:(k)=>process.env[k],home:()=>home}),"config.toml")}function renderKimiHookBlock(inv=kobeHookInvocation(),opts={}){let lines=[BLOCK_BEGIN];for(let spec of KIMI_HOOK_EVENT_MAP){if(!opts.toolEvents&&GATED_TOOL_VERBS.has(spec.verb))continue;let command=quoteShellArgv([...inv,"hook",spec.verb,...roveHookArgs("kimi")],hookCommandQuoting());if(lines.push("[[hooks]]"),lines.push(`event = ${JSON.stringify(spec.event)}`),spec.matcher)lines.push(`matcher = ${JSON.stringify(spec.matcher)}`);lines.push(`command = ${JSON.stringify(command)}`),lines.push(`timeout = ${HOOK_TIMEOUT_SECONDS}`),lines.push("")}return lines.push(BLOCK_END),lines.join(`
29
29
  `)}function removeKimiHookBlock(content){let lines=content.split(`
30
30
  `),out=[],inBlock=!1;for(let line of lines){if(line.trim()===BLOCK_BEGIN){if(inBlock=!0,out.length>0&&out[out.length-1]==="")out.pop();continue}if(inBlock){if(line.trim()===BLOCK_END)inBlock=!1;continue}out.push(line)}return out.join(`
31
31
  `)}function mergeKimiHooks(content,install,inv=kobeHookInvocation(),opts={}){let base=removeKimiHookBlock(content);if(!install)return base;let trimmed=base.replace(/\n+$/,"");return`${trimmed.length>0?`${trimmed}
@@ -36,8 +36,14 @@ ${body}
36
36
  * launch (${vendor}). Local edits are overwritten; to stop reporting, delete
37
37
  * this file or turn Rove's global hooks off.
38
38
  *
39
+ * ROVE_HOOK_VERSION=${ROVE_HOOK_VERSION}
40
+ *
39
41
  * It subscribes to ${vendor}'s session/agent lifecycle and shells out to
40
- * \`${invocation.join(" ")} hook <verb> --engine ${vendor}\`. Best-effort by
42
+ * \`${invocation.join(" ")} hook <verb> --engine ${vendor}\`. The version line
43
+ * above is how Rove reads back which shape installed this file: unlike the
44
+ * settings-file engines, whose version rides the persisted hook command, this
45
+ * module builds its argv at runtime, so nothing else in the bytes would say.
46
+ * Best-effort by
41
47
  * construction: every report is fire-and-forget (except the final one, which
42
48
  * is awaited so it survives process exit) and every failure is swallowed \u2014
43
49
  * a badge must never break a turn.
@@ -45,6 +51,7 @@ ${body}
45
51
 
46
52
  const ENGINE = ${JSON.stringify(vendor)}
47
53
  const INVOCATION = ${JSON.stringify(invocation)}
54
+ const HOOK_VERSION = ${JSON.stringify(String(ROVE_HOOK_VERSION))}
48
55
 
49
56
  /** Normalize an untrusted field: the CLI's payload types are wider than ours. */
50
57
  function text(value) {
@@ -81,6 +88,8 @@ function emit(pi, verb, ctx, extra, wait) {
81
88
  verb,
82
89
  "--engine",
83
90
  ENGINE,
91
+ "--hook-version",
92
+ HOOK_VERSION,
84
93
  "--payload",
85
94
  JSON.stringify(payload),
86
95
  ])
@@ -151,5 +160,5 @@ ${tool}}
151
160
  `;var ACTIVITY_EXTENSION_FILE="rove-activity.ts";function piExtensionsDir(vendor,deps){return path10.join(vendorAgentDir(vendor,deps),"extensions")}function piActivityExtensionPath(vendor,deps){return path10.join(piExtensionsDir(vendor,deps),ACTIVITY_EXTENSION_FILE)}function piFailureDetail(payload){let raw=typeof payload.error_message==="string"?payload.error_message:"",message=raw.toLowerCase(),note=raw?raw.slice(0,200):void 0;return{failure:(()=>{if(/insufficient|credit|billing|payment required|\b402\b|quota exceeded|out of credits/.test(message))return"billing";if(/rate.?limit|too many requests|\b429\b|overloaded|capacity/.test(message))return"rate_limit";return"other"})(),...note?{note}:{}}}class PiFamilyHookAdapter{family;vendor;constructor(family){this.family=family;this.vendor=family}supportsHooks(){return!0}globalSettingsPath(){return piActivityExtensionPath(this.family)}activityDetailFromPayload(kind,payload){if(kind==="turn-failed")return piFailureDetail(payload);if(kind==="awaiting-input")return{waiting:payload.waiting==="input"?"input":"permission"};if(kind==="tool-pre"||kind==="tool-post"||kind==="tool-failed"){let name=typeof payload.tool_name==="string"?payload.tool_name:void 0;return{tool:{...name?{name}:{}}}}return}sessionFromPayload(payload){let sessionId=typeof payload.session_id==="string"?payload.session_id:void 0;if(!sessionId)return;let transcriptPath3=typeof payload.transcript_path==="string"?payload.transcript_path:void 0;return{sessionId,...transcriptPath3?{transcriptPath:transcriptPath3}:{}}}async installActivityHooks(settingsFilePath,opts={}){let agentDir=path10.dirname(path10.dirname(settingsFilePath));if(!existsSync2(agentDir))return{ok:!0};let source=renderPiExtensionSource({vendor:this.family,invocation:kobeHookInvocation(),toolEvents:opts.toolEvents??!1});return await writeIfChanged(settingsFilePath,source),{ok:!0}}async removeActivityHooks(settingsFilePath){try{await rm2(settingsFilePath,{force:!0})}catch{}}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}async function writeIfChanged(file,content){try{if(await readFile2(file,"utf8").catch(()=>{return})===content)return;await mkdir3(path10.dirname(file),{recursive:!0}),await writeFile2(file,content)}catch{}}var OMP_SCREEN_MANIFEST={rules:[{state:"blocked",all:["allow tool"],any:["approve","deny"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]{1,2}\\s+\\d+s\\s+\xB7"]},{state:"idle",lineRegex:["^\\s*\xB7\\s+\\S+.*\xB7"]}]},PI_SCREEN_MANIFEST={rules:[{state:"blocked",all:["trust project folder?"]},{state:"blocked",all:["\u2191\u2193 navigate","escape/ctrl+c cancel"]},{state:"working",any:["working..."]},{state:"idle",lineRegex:["^\\s*[\u2191\u2193]\\s*\\d"]}]};var OMP_SPINNER_FRAMES=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];var OMP_WORKING_PREFIXES=OMP_SPINNER_FRAMES.map((frame)=>`${"\u03C0"} ${frame}`),OMP_ATTENTION_PREFIXES=[`${"\u03C0"} !`],OMP_STATUS_PREFIXES=[...OMP_WORKING_PREFIXES,...OMP_ATTENTION_PREFIXES,`${"\u03C0"} >`,`${"\u03C0"}:`],PI_STATUS_PREFIXES=[`${"\u03C0"} -`];import{existsSync as existsSync3,mkdirSync as mkdirSync3,readFileSync,realpathSync as realpathSync3,writeFileSync as writeFileSync3}from"fs";import path11 from"path";function canonical(p){try{return realpathSync3(p)}catch{return p}}function piTrustPath(deps){return path11.join(vendorAgentDir("pi",deps),"trust.json")}function trustPiWorktree(worktreePath,deps){let file=piTrustPath(deps);try{let existing={};if(existsSync3(file)){let parsed=JSON.parse(readFileSync(file,"utf8"));if(!parsed||typeof parsed!=="object"||Array.isArray(parsed))return;for(let[key,value]of Object.entries(parsed))existing[key]=value===!0}existing[canonical(worktreePath)]=!0,mkdirSync3(path11.dirname(file),{recursive:!0}),writeFileSync3(file,`${JSON.stringify(existing,null,2)}
152
161
  `)}catch{}}import{stat as stat6}from"fs/promises";class EngineTurnDetector{supportsCompletionMarkers(){return!0}async latestCompletion(worktree){return(await this.latestActivity(worktree)).marker}async latestActivityInFile(_transcriptPath){return null}}function createEngineTurnDetector(vendor){return engineEntry(vendor).createTurnDetector()}var statFile=(path12)=>stat6(path12).catch(()=>null);function completionReader(deps,parse2){let cache4=new Map;return async(path12,knownMtime)=>{let info=deps.statFile?await deps.statFile(path12):null;if(deps.statFile&&!info)return null;let mtimeMs=info?.mtimeMs??knownMtime??await(deps.statMtimeMs??(async(p)=>(await statFile(p))?.mtimeMs??0))(path12);if(!info&&knownMtime===void 0&&mtimeMs===0)return null;let key=info?`${info.dev}:${info.ino}:${info.size}:${info.mtimeMs}:${info.ctimeMs}`:String(mtimeMs),hit=cache4.get(path12);if(mtimeMs>0&&hit?.key===key)return hit.scan;let raw;try{raw=await deps.readFile(path12)}catch{return cache4.delete(path12),null}if(raw===null)return cache4.delete(path12),null;let scan={marker:parse2(raw,path12,mtimeMs),mtimeMs};if(cache4.delete(path12),cache4.set(path12,{key,scan}),cache4.size>8){let oldest=cache4.keys().next().value;if(oldest!==void 0)cache4.delete(oldest)}return scan}}var defaultClaudeDeps={listSessionFiles:(worktree)=>listSessionFilesForWorktree(worktree),readFile:readTextFileIfRegular,statFile};class ClaudeTurnDetector extends EngineTurnDetector{deps;vendor="claude";readCompletion;constructor(deps=defaultClaudeDeps){super();this.deps=deps;this.readCompletion=completionReader(deps,latestClaudeCompletionMarkerFromJsonl)}async latestActivity(worktree){let files=await this.deps.listSessionFiles(worktree),mtimeMs=files[0]?.mtimeMs??0,latest=null;for(let file of files.slice(0,4)){let marker=(await this.readCompletion(file.path,file.mtimeMs))?.marker;if(marker&&(!latest||marker.timestampMs>latest.timestampMs))latest=marker}return{marker:latest,mtimeMs}}latestActivityInFile(transcriptPath3){return this.readCompletion(transcriptPath3)}}var defaultCodexDeps={findLatestRollout:(worktree)=>findLatestRolloutForWorktree(worktree),readFile:readTextFileIfRegular,statFile};class CodexTurnDetector extends EngineTurnDetector{deps;vendor="codex";readCompletion;constructor(deps=defaultCodexDeps){super();this.deps=deps;this.readCompletion=completionReader(deps,latestCodexCompletionMarkerFromJsonl)}latestActivityInFile(transcriptPath3){return this.readCompletion(transcriptPath3)}async latestActivity(worktree){if(!worktree)return{marker:null,mtimeMs:0};let found=await this.deps.findLatestRollout(worktree);return found?await this.readCompletion(found.path,found.mtimeMs)??{marker:null,mtimeMs:0}:{marker:null,mtimeMs:0}}}class UnknownTurnDetector extends EngineTurnDetector{vendor;constructor(vendor){super();this.vendor=vendor}supportsCompletionMarkers(){return!1}async latestActivity(){return{marker:null,mtimeMs:0}}}var CLAUDE_TURN_END_STOP_REASONS=new Set(["end_turn","stop_sequence","max_tokens","refusal"]);function latestClaudeCompletionMarkerFromJsonl(raw,sourceId="claude",fallbackMtimeMs=0){let latest=null,lineNo=0;for(let line of raw.split(`
153
162
  `)){lineNo++;let record=parseJsonLine(line);if(!record)continue;let inner=isObject8(record.message)?record.message:record;if(inner.role!=="assistant")continue;if(typeof inner.stop_reason!=="string")continue;if(!CLAUDE_TURN_END_STOP_REASONS.has(inner.stop_reason))continue;let timestampMs=timestampFromRecord(record,fallbackMtimeMs),marker={id:`claude:${sourceId}:${timestampMs}:${lineNo}`,timestampMs,source:"claude"};if(!latest||marker.timestampMs>=latest.timestampMs)latest=marker}return latest}var CODEX_ROLLOUT_DONE_EVENTS=new Set(["task_complete","turn_complete","turn_aborted"]);function isCodexCompletionRecord(record){if(record.type==="turn.completed")return!0;if(record.type!=="event_msg")return!1;let payload=isObject8(record.payload)?record.payload:void 0;return typeof payload?.type==="string"&&CODEX_ROLLOUT_DONE_EVENTS.has(payload.type)}function latestCodexCompletionMarkerFromJsonl(raw,sourceId="codex"){let latest=null,lineNo=0;for(let line of raw.split(`
154
- `)){lineNo++;let record=parseJsonLine(line);if(!record||!isCodexCompletionRecord(record))continue;let timestampMs=timestampFromRecord(record,0),marker={id:`codex:${sourceId}:${timestampMs}:${lineNo}`,timestampMs,source:"codex"};if(!latest||marker.timestampMs>=latest.timestampMs)latest=marker}return latest}function parseJsonLine(line){if(!isJsonlLineWithinBound(line))return null;let trimmed=line.trim();if(!trimmed)return null;try{let parsed=JSON.parse(trimmed);return isObject8(parsed)?parsed:null}catch{return null}}function timestampFromRecord(record,fallback){let ts=typeof record.timestamp==="string"?Date.parse(record.timestamp):Number.NaN;return Number.isFinite(ts)?ts:fallback}function isObject8(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}var BUILTIN_ENGINES={claude:{vendor:"claude",builtin:!0,displayName:claudeIdentity.shortName,defaultCommand:["claude"],history:claudeHistoryReader,detectAccount:(deps)=>detectClaudeAccount(deps),createHookAdapter:()=>new ClaudeHookAdapter,createTurnDetector:()=>new ClaudeTurnDetector,capabilities:claudeCapabilities,identity:claudeIdentity,trustWorktree:trustClaudeWorktree,terminalTitle:{ownsStatus:!0,statusPrefixes:["\u2733","\u2802","\u2810","\u25D0","\u25D1"],workingPrefixes:["\u2802","\u2810","\u25D0","\u25D1"]},sessionIdentity:{pinFlag:"--session-id",sessionControlFlags:["--session-id","--resume","-r","--continue","-c","--from-pr"],resumeArgv:(base,id)=>[...base,"--resume",id],forkArgv:(base,sourceId,newId)=>{let forked=[...base,"--resume",sourceId,"--fork-session"];return newId?[...forked,"--session-id",newId]:forked}},quotaUsage:()=>fetchClaudeQuotaUsage(),readTurns:readClaudeTurns},codex:{vendor:"codex",builtin:!0,displayName:codexIdentity.shortName,defaultCommand:["codex"],effortLevels:["none","low","medium","high","xhigh","max"],effortArgv:(base,level)=>[...base,"-c",`model_reasoning_effort=${level}`],history:codexHistoryReader,detectAccount:(deps)=>detectCodexAccount(deps),createHookAdapter:()=>new CodexHookAdapter,createTurnDetector:()=>new CodexTurnDetector,capabilities:codexCapabilities,identity:codexIdentity,trustWorktree:trustCodexWorktree,readTurns:readCodexTurns,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"],sessionIdFromTitle:codexSessionIdFromTitle},sessionIdentity:{resumeArgv:(base,id)=>{let[bin,...rest]=base;return bin?[bin,"resume",...rest,id]:base},forkArgv:(base,sourceId)=>{let[bin,...rest]=base;return bin?[bin,"fork",...rest,sourceId]:null}},quotaUsage:()=>fetchCodexQuotaUsage()},copilot:{vendor:"copilot",builtin:!0,displayName:"Copilot",defaultCommand:["copilot"],history:copilotHistoryReader,detectAccount:(deps)=>detectCopilotAccount(deps),createHookAdapter:()=>new NoopHookAdapter("copilot"),createTurnDetector:()=>new UnknownTurnDetector("copilot"),trustWorktree:trustCopilotWorktree,screenManifest:COPILOT_SCREEN_MANIFEST},kimi:{vendor:"kimi",builtin:!0,displayName:"Kimi",defaultCommand:["kimi"],firstMessageDelivery:"paste",processNames:["kimi-co"],trustWorktree:trustKimiWorktree,history:kimiHistoryReader,detectAccount:(deps)=>detectKimiAccount(deps),createHookAdapter:()=>new KimiHookAdapter,createTurnDetector:()=>new UnknownTurnDetector("kimi"),sessionIdentity:{sessionControlFlags:["-S","--session","-c","--continue"],resumeArgv:(base,id)=>[...base,"-S",id]},screenManifest:KIMI_SCREEN_MANIFEST},pi:{vendor:"pi",builtin:!0,displayName:piIdentity.shortName,defaultCommand:["pi"],effortLevels:["off","minimal","low","medium","high","xhigh","max"],effortArgv:(base,level)=>[...base,"--thinking",level],history:piHistoryReader,createHookAdapter:()=>new PiFamilyHookAdapter("pi"),createTurnDetector:()=>new UnknownTurnDetector("pi"),capabilities:piCapabilities,identity:piIdentity,trustWorktree:trustPiWorktree,terminalTitle:{ownsStatus:!1,statusPrefixes:PI_STATUS_PREFIXES},sessionIdentity:{pinFlag:"--session-id",sessionControlFlags:["--session-id","--session","-c","--continue","-r","--resume","--fork"],resumeArgv:(base,id)=>[...base,"--session",id],forkArgv:(base,sourceId)=>[...base,"--fork",sourceId]},screenManifest:PI_SCREEN_MANIFEST},omp:{vendor:"omp",builtin:!0,displayName:ompIdentity.shortName,defaultCommand:["omp"],effortLevels:["off","minimal","low","medium","high","xhigh","max"],effortArgv:(base,level)=>[...base,"--thinking",level],history:ompHistoryReader,createHookAdapter:()=>new PiFamilyHookAdapter("omp"),createTurnDetector:()=>new UnknownTurnDetector("omp"),capabilities:ompCapabilities,identity:ompIdentity,terminalTitle:{ownsStatus:!0,statusPrefixes:OMP_STATUS_PREFIXES,workingPrefixes:OMP_WORKING_PREFIXES,attentionPrefixes:OMP_ATTENTION_PREFIXES},sessionIdentity:{sessionControlFlags:["-c","--continue","-r","--resume"],resumeArgv:(base,id)=>[...base,"-r",id]},screenManifest:OMP_SCREEN_MANIFEST}};function stripStatusPrefix(title,prefixes){for(let prefix of[...prefixes].sort((a,b)=>b.length-a.length)){if(!title.startsWith(prefix))continue;let rest=title.slice(prefix.length).trimStart();if(rest.length===0)return title;return rest}return title}function titleTurnHint(config,title){let working=config?.workingPrefixes;if(config?.ownsStatus!==!0||!working||working.length===0)return null;let trimmed=title.trim();if(trimmed.length===0)return null;if(config.attentionPrefixes?.some((prefix)=>trimmed.startsWith(prefix)))return null;return working.some((prefix)=>trimmed.startsWith(prefix))?"working":"rest"}function titleSessionId(config,title){let trimmed=title.trim();if(!trimmed)return null;return config?.sessionIdFromTitle?.(trimmed)??null}function titleIsPlaceholder(config,title){return titleSessionId(config,title)!==null}function customEngineEntry(vendor){return{vendor,builtin:!1,displayName:vendor,defaultCommand:[vendor],history:EMPTY_HISTORY,createHookAdapter:()=>new NoopHookAdapter(vendor),createTurnDetector:()=>new UnknownTurnDetector(vendor)}}function engineEntry(vendor){if(isBuiltinVendor(vendor))return BUILTIN_ENGINES[vendor];let custom=customEngineEntry(vendor);return isContribEngine(vendor)?contribEngineEntry(vendor,custom):custom}function identifiableEngineIds(){return[...BUILTIN_VENDORS,...CONTRIB_ENGINE_IDS,...pluginEngineIds()]}function supportsStructuredHistory(vendor){return engineEntry(vendor).history.readHistory!==EMPTY_HISTORY.readHistory}var ALL_STATUS_PREFIXES=[...new Set(Object.values(BUILTIN_ENGINES).flatMap((entry)=>entry.terminalTitle?.statusPrefixes??[]))];function engineStatusPrefixes(vendor){let declared=engineEntry(vendor).terminalTitle?.statusPrefixes;return declared&&declared.length>0?declared:ALL_STATUS_PREFIXES}function stripEngineStatusPrefix(title,vendor){return stripStatusPrefix(title,vendor?engineStatusPrefixes(vendor):ALL_STATUS_PREFIXES)}function engineTitleTurnHint(vendor,title){return titleTurnHint(engineEntry(vendor).terminalTitle,title)}function engineSessionIdFromTitle(vendor,title){return titleSessionId(engineEntry(vendor).terminalTitle,title)}function isEnginePlaceholderTitle(title,vendor){return titleIsPlaceholder(engineEntry(vendor).terminalTitle,title)}function getCapabilities(vendor){return engineEntry(vendor).capabilities}function vendorsWithQuotaProbe(){return Object.values(BUILTIN_ENGINES).filter((entry)=>entry.quotaUsage).map((entry)=>entry.vendor)}function vendorsWithTurnReader(){return Object.values(BUILTIN_ENGINES).filter((entry)=>entry.readTurns).map((entry)=>entry.vendor)}function createEngineHookAdapter(vendor){return engineEntry(vendor).createHookAdapter()}class NoopHookAdapter{vendor;constructor(vendor){this.vendor=vendor}supportsHooks(){return!1}globalSettingsPath(){return""}activityDetailFromPayload(){return}sessionFromPayload(){return}async installActivityHooks(){return{ok:!0}}async removeActivityHooks(){}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}
155
- export{createEngineHookAdapter,createEngineTurnDetector,engineEntry,identifiableEngineIds,supportsStructuredHistory,engineStatusPrefixes,stripEngineStatusPrefix,engineTitleTurnHint,engineSessionIdFromTitle,isEnginePlaceholderTitle,getCapabilities,vendorsWithQuotaProbe,vendorsWithTurnReader};
163
+ `)){lineNo++;let record=parseJsonLine(line);if(!record||!isCodexCompletionRecord(record))continue;let timestampMs=timestampFromRecord(record,0),marker={id:`codex:${sourceId}:${timestampMs}:${lineNo}`,timestampMs,source:"codex"};if(!latest||marker.timestampMs>=latest.timestampMs)latest=marker}return latest}function parseJsonLine(line){if(!isJsonlLineWithinBound(line))return null;let trimmed=line.trim();if(!trimmed)return null;try{let parsed=JSON.parse(trimmed);return isObject8(parsed)?parsed:null}catch{return null}}function timestampFromRecord(record,fallback){let ts=typeof record.timestamp==="string"?Date.parse(record.timestamp):Number.NaN;return Number.isFinite(ts)?ts:fallback}function isObject8(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}var BUILTIN_ENGINES={claude:{vendor:"claude",builtin:!0,displayName:claudeIdentity.shortName,defaultCommand:["claude"],history:claudeHistoryReader,detectAccount:(deps)=>detectClaudeAccount(deps),createHookAdapter:()=>new ClaudeHookAdapter,createTurnDetector:()=>new ClaudeTurnDetector,capabilities:claudeCapabilities,identity:claudeIdentity,trustWorktree:trustClaudeWorktree,terminalTitle:{ownsStatus:!0,statusPrefixes:["\u2733","\u2802","\u2810","\u25D0","\u25D1"],workingPrefixes:["\u2802","\u2810","\u25D0","\u25D1"]},sessionIdentity:{pinFlag:"--session-id",sessionControlFlags:["--session-id","--resume","-r","--continue","-c","--from-pr"],resumeArgv:(base,id)=>[...base,"--resume",id],forkArgv:(base,sourceId,newId)=>{let forked=[...base,"--resume",sourceId,"--fork-session"];return newId?[...forked,"--session-id",newId]:forked}},quotaUsage:()=>fetchClaudeQuotaUsage(),readTurns:readClaudeTurns},codex:{vendor:"codex",builtin:!0,displayName:codexIdentity.shortName,defaultCommand:["codex"],effortLevels:["none","low","medium","high","xhigh","max"],effortArgv:(base,level)=>[...base,"-c",`model_reasoning_effort=${level}`],history:codexHistoryReader,detectAccount:(deps)=>detectCodexAccount(deps),createHookAdapter:()=>new CodexHookAdapter,createTurnDetector:()=>new CodexTurnDetector,capabilities:codexCapabilities,identity:codexIdentity,trustWorktree:trustCodexWorktree,readTurns:readCodexTurns,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"],sessionIdFromTitle:codexSessionIdFromTitle},sessionIdentity:{resumeArgv:(base,id)=>{let[bin,...rest]=base;return bin?[bin,"resume",...rest,id]:base},forkArgv:(base,sourceId)=>{let[bin,...rest]=base;return bin?[bin,"fork",...rest,sourceId]:null}},quotaUsage:()=>fetchCodexQuotaUsage()},copilot:{vendor:"copilot",builtin:!0,displayName:"Copilot",defaultCommand:["copilot"],history:copilotHistoryReader,detectAccount:(deps)=>detectCopilotAccount(deps),createHookAdapter:()=>new NoopHookAdapter("copilot"),createTurnDetector:()=>new UnknownTurnDetector("copilot"),trustWorktree:trustCopilotWorktree,screenManifest:COPILOT_SCREEN_MANIFEST},kimi:{vendor:"kimi",builtin:!0,displayName:"Kimi",defaultCommand:["kimi"],firstMessageDelivery:"paste",processNames:["kimi-co"],trustWorktree:trustKimiWorktree,history:kimiHistoryReader,detectAccount:(deps)=>detectKimiAccount(deps),createHookAdapter:()=>new KimiHookAdapter,createTurnDetector:()=>new UnknownTurnDetector("kimi"),sessionIdentity:{sessionControlFlags:["-S","--session","-c","--continue"],resumeArgv:(base,id)=>[...base,"-S",id]},screenManifest:KIMI_SCREEN_MANIFEST},pi:{vendor:"pi",builtin:!0,displayName:piIdentity.shortName,defaultCommand:["pi"],effortLevels:["off","minimal","low","medium","high","xhigh","max"],effortArgv:(base,level)=>[...base,"--thinking",level],history:piHistoryReader,createHookAdapter:()=>new PiFamilyHookAdapter("pi"),createTurnDetector:()=>new UnknownTurnDetector("pi"),capabilities:piCapabilities,identity:piIdentity,trustWorktree:trustPiWorktree,terminalTitle:{ownsStatus:!1,statusPrefixes:PI_STATUS_PREFIXES},sessionIdentity:{pinFlag:"--session-id",sessionControlFlags:["--session-id","--session","-c","--continue","-r","--resume","--fork"],resumeArgv:(base,id)=>[...base,"--session",id],forkArgv:(base,sourceId)=>[...base,"--fork",sourceId]},screenManifest:PI_SCREEN_MANIFEST},omp:{vendor:"omp",builtin:!0,displayName:ompIdentity.shortName,defaultCommand:["omp"],effortLevels:["off","minimal","low","medium","high","xhigh","max"],effortArgv:(base,level)=>[...base,"--thinking",level],history:ompHistoryReader,createHookAdapter:()=>new PiFamilyHookAdapter("omp"),createTurnDetector:()=>new UnknownTurnDetector("omp"),capabilities:ompCapabilities,identity:ompIdentity,terminalTitle:{ownsStatus:!0,statusPrefixes:OMP_STATUS_PREFIXES,workingPrefixes:OMP_WORKING_PREFIXES,attentionPrefixes:OMP_ATTENTION_PREFIXES},sessionIdentity:{sessionControlFlags:["-c","--continue","-r","--resume"],resumeArgv:(base,id)=>[...base,"-r",id]},screenManifest:OMP_SCREEN_MANIFEST}};function stripStatusPrefix(title,prefixes){for(let prefix of[...prefixes].sort((a,b)=>b.length-a.length)){if(!title.startsWith(prefix))continue;let rest=title.slice(prefix.length).trimStart();if(rest.length===0)return title;return rest}return title}function titleTurnHint(config,title){let working=config?.workingPrefixes;if(config?.ownsStatus!==!0||!working||working.length===0)return null;let trimmed=title.trim();if(trimmed.length===0)return null;if(config.attentionPrefixes?.some((prefix)=>trimmed.startsWith(prefix)))return null;return working.some((prefix)=>trimmed.startsWith(prefix))?"working":"rest"}function titleSessionId(config,title){let trimmed=title.trim();if(!trimmed)return null;return config?.sessionIdFromTitle?.(trimmed)??null}function titleIsPlaceholder(config,title){return titleSessionId(config,title)!==null}function customEngineEntry(vendor){return{vendor,builtin:!1,displayName:vendor,defaultCommand:[vendor],history:EMPTY_HISTORY,createHookAdapter:()=>new NoopHookAdapter(vendor),createTurnDetector:()=>new UnknownTurnDetector(vendor)}}function engineEntry(vendor){if(isBuiltinVendor(vendor))return BUILTIN_ENGINES[vendor];let custom=customEngineEntry(vendor);return isContribEngine(vendor)?contribEngineEntry(vendor,custom):custom}function identifiableEngineIds(){return[...BUILTIN_VENDORS,...CONTRIB_ENGINE_IDS,...pluginEngineIds()]}function supportsStructuredHistory(vendor){return engineEntry(vendor).history.readHistory!==EMPTY_HISTORY.readHistory}var ALL_STATUS_PREFIXES=[...new Set(Object.values(BUILTIN_ENGINES).flatMap((entry)=>entry.terminalTitle?.statusPrefixes??[]))];function engineStatusPrefixes(vendor){let declared=engineEntry(vendor).terminalTitle?.statusPrefixes;return declared&&declared.length>0?declared:ALL_STATUS_PREFIXES}function stripEngineStatusPrefix(title,vendor){return stripStatusPrefix(title,vendor?engineStatusPrefixes(vendor):ALL_STATUS_PREFIXES)}function engineTitleTurnHint(vendor,title){return titleTurnHint(engineEntry(vendor).terminalTitle,title)}function engineSessionIdFromTitle(vendor,title){return titleSessionId(engineEntry(vendor).terminalTitle,title)}function isEnginePlaceholderTitle(title,vendor){return titleIsPlaceholder(engineEntry(vendor).terminalTitle,title)}function getCapabilities(vendor){return engineEntry(vendor).capabilities}function vendorsWithQuotaProbe(){return Object.values(BUILTIN_ENGINES).filter((entry)=>entry.quotaUsage).map((entry)=>entry.vendor)}function vendorsWithTurnReader(){return Object.values(BUILTIN_ENGINES).filter((entry)=>entry.readTurns).map((entry)=>entry.vendor)}function createEngineHookAdapter(vendor){return engineEntry(vendor).createHookAdapter()}function activityHookAdapters(){return identifiableEngineIds().map((vendor)=>createEngineHookAdapter(vendor)).filter((adapter)=>adapter.supportsHooks())}class NoopHookAdapter{vendor;constructor(vendor){this.vendor=vendor}supportsHooks(){return!1}globalSettingsPath(){return""}activityDetailFromPayload(){return}sessionFromPayload(){return}async installActivityHooks(){return{ok:!0}}async removeActivityHooks(){}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}
164
+ export{activityHookAdapters,createEngineTurnDetector,engineEntry,identifiableEngineIds,supportsStructuredHistory,engineStatusPrefixes,stripEngineStatusPrefix,engineTitleTurnHint,engineSessionIdFromTitle,isEnginePlaceholderTitle,getCapabilities,vendorsWithQuotaProbe,vendorsWithTurnReader};
@@ -0,0 +1,4 @@
1
+ // @bun
2
+ import{installedSkillDirs}from"./chunk-dkeh3535.js";import{CLAUDE_HOOK_EVENT_MAP,claudeSettingsPath}from"./chunk-z10thenb.js";import{hasKobeActivityHooks,isObject}from"./chunk-3trm92y6.js";import"./chunk-7kysxgbq.js";import"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";import{readFileSync}from"fs";import{homedir}from"os";var PLUGIN_NAME="rove";function readSettings(path){try{let parsed=JSON.parse(readFileSync(path,"utf8"));return isObject(parsed)?parsed:null}catch{return null}}function isRovePluginEnabled(settingsFilePath=claudeSettingsPath()){let settings=readSettings(settingsFilePath);if(!settings||!isObject(settings.enabledPlugins))return!1;return Object.entries(settings.enabledPlugins).some(([key,on])=>on===!0&&key.split("@")[0]===PLUGIN_NAME)}function detectLegacyInstalls(opts={}){let settingsFilePath=opts.settingsFilePath??claudeSettingsPath(),home=opts.home??homedir(),settings=readSettings(settingsFilePath),legacyHooks=settings!==null&&(hasKobeActivityHooks(settings,CLAUDE_HOOK_EVENT_MAP)||settingsHasWorktreeWatch(settings)),legacySkillDirs=installedSkillDirs(home);return{legacyHooks,legacySkillDirs}}function settingsHasWorktreeWatch(settings){let hooks=isObject(settings.hooks)?settings.hooks:{};return Object.values(hooks).some((groups)=>Array.isArray(groups)&&groups.some((g)=>isObject(g)&&Array.isArray(g.hooks)&&g.hooks.some((h)=>isObject(h)&&typeof h.command==="string"&&h.command.includes("worktree-created")&&!h.command.includes("CLAUDE_PLUGIN_ROOT"))))}function migrationHint(findings,cliName){if(!findings.legacyHooks&&findings.legacySkillDirs.length===0)return null;let lines=[`${cliName}: the Rove Claude Code plugin is enabled, but legacy installs remain:`];if(findings.legacyHooks)lines.push(" \u2022 ~/.claude/settings.json still has the settings-managed Rove hooks (every event fires TWICE).",` Run \`${cliName} hook cleanup\` to remove them (only Rove's own entries are touched).`);for(let dir of findings.legacySkillDirs)lines.push(` \u2022 legacy skill copy at ${dir} (the plugin bundles the skill \u2014 two copies double-register).`," Remove that directory to keep the plugin's copy only.");return lines.push(" Reading this inside a session? Just ask your agent to run the cleanup for you."),`${lines.join(`
3
+ `)}
4
+ `}export{migrationHint,isRovePluginEnabled,detectLegacyInstalls};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{defaultEngineCommand,engineCommandKey,engineDisplayName,interactiveEngineCommand,parseEngineCommand,withEngineEffort,withEngineTerminalTitle}from"./chunk-ba0ygf1w.js";import{vendorFromArgv}from"./chunk-qm3x7d6f.js";import{engineEntry}from"./chunk-46kxbsdm.js";import{isContribEngine}from"./chunk-0ks58ddm.js";import{getCustomEngineIds,getPersistedString}from"./chunk-crt11rmj.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-05jej26n.js";import{randomUUID}from"crypto";function hasFlag(argv,flag){return argv.some((a)=>a===flag||a.startsWith(`${flag}=`))}function controlsOwnSession(identity,argv){return(identity?.sessionControlFlags??[]).some((flag)=>hasFlag(argv,flag))}function pinSessionArgv(identity,argv,sessionId){if(!identity?.pinFlag)return argv;if(controlsOwnSession(identity,argv))return argv;return[...argv,identity.pinFlag,sessionId]}function acceptsPinnedSession(identity,argv){return!!identity?.pinFlag&&!controlsOwnSession(identity,argv)}function resumeSessionArgv(identity,base,sessionId){if(!sessionId||!identity?.resumeArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.resumeArgv(base,sessionId)}function pickUnclaimedSessionId(ids,claimed){for(let i=ids.length-1;i>=0;i--){let id=ids[i];if(id&&!claimed.has(id))return id}return null}function forkSessionArgvFor(identity,base,sourceId,newId){if(!sourceId||!identity?.forkArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.forkArgv(base,sourceId,newId)}function acceptsSessionFork(identity){return!!identity?.forkArgv}var GENERIC_PROTOCOL="generic",ENGINE_PROTOCOLS=BUILTIN_VENDORS;function engineProtocolKey(id){return`engineProtocol.${id}`}function getEngineProtocol(id){if(isBuiltinVendor(id)||isContribEngine(id))return id;let raw=getPersistedString(engineProtocolKey(id))?.trim();return raw&&ENGINE_PROTOCOLS.includes(raw)?raw:void 0}function isPresetId(id){return isBuiltinVendor(id)||isContribEngine(id)||getCustomEngineIds().includes(id)}function listPresetIds(){return[...BUILTIN_VENDORS,...getCustomEngineIds()]}function describePreset(id){let command=getPersistedString(engineCommandKey(id))?.trim()||defaultEngineCommand(id).join(" ");return{id,name:engineDisplayName(id),command,protocol:getEngineProtocol(id)??GENERIC_PROTOCOL,builtin:isBuiltinVendor(id)}}function listEnginePresets(){return listPresetIds().map(describePreset)}function resolveCommandProtocol(command){let trimmed=command?.trim();if(!trimmed)return GENERIC_PROTOCOL;if(isPresetId(trimmed))return getEngineProtocol(trimmed)??GENERIC_PROTOCOL;let fromArgv=vendorFromArgv(trimmed);if(fromArgv)return fromArgv;let argv0=parseEngineCommand(trimmed)[0];if(argv0)for(let id of getCustomEngineIds()){let preset=getPersistedString(engineCommandKey(id))?.trim();if(preset&&parseEngineCommand(preset)[0]===argv0)return getEngineProtocol(id)??GENERIC_PROTOCOL}return GENERIC_PROTOCOL}function engineLaunchArgv(spec){let command=spec.command?.trim();if(!command)return interactiveEngineCommand(spec.vendor,spec.effort);let vendor=(isPresetId(command)?getEngineProtocol(command):void 0)??resolveCommandProtocol(command),base=isPresetId(command)?presetBaseArgv(command):(()=>{let argv=parseEngineCommand(command);return argv.length>0?argv:null})();if(!base)return interactiveEngineCommand(spec.vendor,spec.effort);return withEngineTerminalTitle(withEngineEffort(base,vendor,spec.effort),vendor)}function presetBaseArgv(id){let override=getPersistedString(engineCommandKey(id))?.trim();if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(id)}function sessionProtocol(vendor){let id=vendor?.trim();if(!id)return"claude";return getEngineProtocol(id)??id}function protocolEntry(vendor){return engineEntry(sessionProtocol(vendor))}function withPinnedSessionId(argv,vendor,newId=randomUUID){let identity=engineEntry(sessionProtocol(vendor)).sessionIdentity;if(!acceptsPinnedSession(identity,argv))return{argv,sessionId:null};let sessionId=newId();return{argv:pinSessionArgv(identity,argv,sessionId),sessionId}}function engineResumeArgv(base,vendor,sessionId){return resumeSessionArgv(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sessionId)}function engineCanFork(vendor){return acceptsSessionFork(engineEntry(sessionProtocol(vendor)).sessionIdentity)}function engineForkArgv(base,vendor,sourceId,newId){return forkSessionArgvFor(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sourceId,newId)}
2
+ import{defaultEngineCommand,engineCommandKey,engineDisplayName,interactiveEngineCommand,parseEngineCommand,withEngineEffort,withEngineTerminalTitle}from"./chunk-401a3x2y.js";import{vendorFromArgv}from"./chunk-6ynwn2d2.js";import{engineEntry}from"./chunk-8k625ztz.js";import{isContribEngine}from"./chunk-28430c3s.js";import{getCustomEngineIds,getPersistedString}from"./chunk-crt11rmj.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-05jej26n.js";import{randomUUID}from"crypto";function hasFlag(argv,flag){return argv.some((a)=>a===flag||a.startsWith(`${flag}=`))}function controlsOwnSession(identity,argv){return(identity?.sessionControlFlags??[]).some((flag)=>hasFlag(argv,flag))}function pinSessionArgv(identity,argv,sessionId){if(!identity?.pinFlag)return argv;if(controlsOwnSession(identity,argv))return argv;return[...argv,identity.pinFlag,sessionId]}function acceptsPinnedSession(identity,argv){return!!identity?.pinFlag&&!controlsOwnSession(identity,argv)}function resumeSessionArgv(identity,base,sessionId){if(!sessionId||!identity?.resumeArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.resumeArgv(base,sessionId)}function pickUnclaimedSessionId(ids,claimed){for(let i=ids.length-1;i>=0;i--){let id=ids[i];if(id&&!claimed.has(id))return id}return null}function forkSessionArgvFor(identity,base,sourceId,newId){if(!sourceId||!identity?.forkArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.forkArgv(base,sourceId,newId)}function acceptsSessionFork(identity){return!!identity?.forkArgv}var GENERIC_PROTOCOL="generic",ENGINE_PROTOCOLS=BUILTIN_VENDORS;function engineProtocolKey(id){return`engineProtocol.${id}`}function getEngineProtocol(id){if(isBuiltinVendor(id)||isContribEngine(id))return id;let raw=getPersistedString(engineProtocolKey(id))?.trim();return raw&&ENGINE_PROTOCOLS.includes(raw)?raw:void 0}function isPresetId(id){return isBuiltinVendor(id)||isContribEngine(id)||getCustomEngineIds().includes(id)}function listPresetIds(){return[...BUILTIN_VENDORS,...getCustomEngineIds()]}function describePreset(id){let command=getPersistedString(engineCommandKey(id))?.trim()||defaultEngineCommand(id).join(" ");return{id,name:engineDisplayName(id),command,protocol:getEngineProtocol(id)??GENERIC_PROTOCOL,builtin:isBuiltinVendor(id)}}function listEnginePresets(){return listPresetIds().map(describePreset)}function resolveCommandProtocol(command){let trimmed=command?.trim();if(!trimmed)return GENERIC_PROTOCOL;if(isPresetId(trimmed))return getEngineProtocol(trimmed)??GENERIC_PROTOCOL;let fromArgv=vendorFromArgv(trimmed);if(fromArgv)return fromArgv;let argv0=parseEngineCommand(trimmed)[0];if(argv0)for(let id of getCustomEngineIds()){let preset=getPersistedString(engineCommandKey(id))?.trim();if(preset&&parseEngineCommand(preset)[0]===argv0)return getEngineProtocol(id)??GENERIC_PROTOCOL}return GENERIC_PROTOCOL}function engineLaunchArgv(spec){let command=spec.command?.trim();if(!command)return interactiveEngineCommand(spec.vendor,spec.effort);let vendor=(isPresetId(command)?getEngineProtocol(command):void 0)??resolveCommandProtocol(command),base=isPresetId(command)?presetBaseArgv(command):(()=>{let argv=parseEngineCommand(command);return argv.length>0?argv:null})();if(!base)return interactiveEngineCommand(spec.vendor,spec.effort);return withEngineTerminalTitle(withEngineEffort(base,vendor,spec.effort),vendor)}function presetBaseArgv(id){let override=getPersistedString(engineCommandKey(id))?.trim();if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(id)}function sessionProtocol(vendor){let id=vendor?.trim();if(!id)return"claude";return getEngineProtocol(id)??id}function protocolEntry(vendor){return engineEntry(sessionProtocol(vendor))}function withPinnedSessionId(argv,vendor,newId=randomUUID){let identity=engineEntry(sessionProtocol(vendor)).sessionIdentity;if(!acceptsPinnedSession(identity,argv))return{argv,sessionId:null};let sessionId=newId();return{argv:pinSessionArgv(identity,argv,sessionId),sessionId}}function engineResumeArgv(base,vendor,sessionId){return resumeSessionArgv(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sessionId)}function engineCanFork(vendor){return acceptsSessionFork(engineEntry(sessionProtocol(vendor)).sessionIdentity)}function engineForkArgv(base,vendor,sourceId,newId){return forkSessionArgvFor(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sourceId,newId)}
3
3
  export{pickUnclaimedSessionId,GENERIC_PROTOCOL,ENGINE_PROTOCOLS,engineProtocolKey,getEngineProtocol,listPresetIds,describePreset,listEnginePresets,resolveCommandProtocol,engineLaunchArgv,sessionProtocol,protocolEntry,withPinnedSessionId,engineResumeArgv,engineCanFork,engineForkArgv};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{applyOnboardingChoices,detectShell,envReadyForTasks,installCompletions,maybeRunOnboarding}from"./chunk-2vtps463.js";import"./chunk-8kpxyqjx.js";import"./chunk-h3y0npdb.js";import"./chunk-8nw96qrm.js";import"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import"./chunk-v8e24gbf.js";import"./chunk-ba0ygf1w.js";import"./chunk-rrymnz5z.js";import"./chunk-ta0bgf5z.js";import"./chunk-sdyzxayr.js";import"./chunk-qm3x7d6f.js";import"./chunk-46kxbsdm.js";import"./chunk-0ks58ddm.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-10r5p67t.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-wahj6696.js";import"./chunk-r1sh08tf.js";import"./chunk-aep7gvh4.js";import"./chunk-7kysxgbq.js";import"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-pxk2c2vj.js";import"./chunk-wqfp8d9w.js";export{maybeRunOnboarding,installCompletions,envReadyForTasks,detectShell,applyOnboardingChoices};
2
+ import{applyOnboardingChoices,detectShell,envReadyForTasks,installCompletions,maybeRunOnboarding}from"./chunk-6y8fq52x.js";import"./chunk-dwqyryn2.js";import"./chunk-2qgs5apg.js";import"./chunk-qkbasmav.js";import"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import"./chunk-ad37b8qf.js";import"./chunk-401a3x2y.js";import"./chunk-zmyd75wm.js";import"./chunk-879tjgze.js";import"./chunk-sdyzxayr.js";import"./chunk-6ynwn2d2.js";import"./chunk-8k625ztz.js";import"./chunk-28430c3s.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-zp846pvb.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-dkeh3535.js";import"./chunk-z10thenb.js";import"./chunk-3trm92y6.js";import"./chunk-7kysxgbq.js";import"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-pxk2c2vj.js";import"./chunk-wqfp8d9w.js";export{maybeRunOnboarding,installCompletions,envReadyForTasks,detectShell,applyOnboardingChoices};
@@ -4,5 +4,5 @@ import{generateCompletions,isShellKind,mergeSubVerbs,shippedCompletionsPath}from
4
4
 
5
5
  ${usage}`),process.exit(2)};if(rest.some((arg)=>HELP_WORDS.includes(arg))){process.stdout.write(usage);return}let flags=rest.filter((arg)=>arg.startsWith("-")),shells=rest.filter((arg)=>!arg.startsWith("-")),unknownFlag=flags.find((flag)=>flag!=="--path"&&flag!=="--install");if(unknownFlag)fail(`unknown option "${unknownFlag}"`);if(new Set(flags).size>1)fail("--path and --install are different things; pass one");let shell=shells.length===1?shells[0]:void 0;if(!isShellKind(shell))fail(`unknown shell "${shells.join(" ")}"`);let scriptPath=shippedCompletionsPath(shell,cliName,deps.shippedDir),shipped=existsSync(scriptPath)?scriptPath:null;if(flags[0]==="--path"){if(!shipped)fail(`no pre-generated ${shell} script at ${scriptPath}
6
6
  ${cliName} completions ${shell} # print the script to stdout instead`);process.stdout.write(`${shipped}
7
- `);return}if(flags[0]==="--install"){let[{installCompletions},{t}]=await Promise.all([import("./chunk-gmy7cw0c.js"),import("./chunk-bh6mcf55.js")]),completion=installCompletions(shell,deps.home,cliName,shipped),line=completion.installed?"onboarding.appliedCompletions":"onboarding.keptCompletions";process.stdout.write(`${t(line,{path:completion.path})}
8
- `);return}if(shipped){process.stdout.write(readFileSync(shipped,"utf8"));return}let{API_VERBS}=await import("./chunk-v3sapafp.js");process.stdout.write(generateCompletions(shell,cliName,mergeSubVerbs(API_VERBS)))}export{runCompletionsSubcommand};
7
+ `);return}if(flags[0]==="--install"){let[{installCompletions},{t}]=await Promise.all([import("./chunk-b85vnsxe.js"),import("./chunk-gwrmzvvj.js")]),completion=installCompletions(shell,deps.home,cliName,shipped),line=completion.installed?"onboarding.appliedCompletions":"onboarding.keptCompletions";process.stdout.write(`${t(line,{path:completion.path})}
8
+ `);return}if(shipped){process.stdout.write(readFileSync(shipped,"utf8"));return}let{API_VERBS}=await import("./chunk-7ekehasa.js");process.stdout.write(generateCompletions(shell,cliName,mergeSubVerbs(API_VERBS)))}export{runCompletionsSubcommand};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{PLUGIN_MANIFEST_FILENAMES,currentPluginPlatform,loadPluginRegistry,parsePluginManifest,pluginCheckoutDir,pluginConfigDir,pluginManifestPath,pluginStateDir,pluginsRootDir,savePluginRegistry,supportsPlatform,upsertPluginEntry}from"./chunk-bq9shn2d.js";import{CURRENT_VERSION,compareSemver}from"./chunk-10r5p67t.js";import{spawnSync}from"child_process";import{cpSync,existsSync,mkdirSync,readFileSync,renameSync,rmSync}from"fs";import{mkdtempSync}from"fs";import{basename,join,resolve}from"path";import{createInterface}from"readline/promises";var GITHUB_SPEC_RE=/^([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)(\/.+)?$/;class PluginCliError extends Error{}function fail(message){throw new PluginCliError(message)}function readManifestAt(root){let path=pluginManifestPath(root);if(!path)fail(`no ${PLUGIN_MANIFEST_FILENAMES.join(" or ")} found at ${root}`);let source=readFileSync(path,"utf8");return{...parsePluginManifest(source,basename(path)),manifestPath:path,manifestSource:source}}function checkVersionGate(parsed){let min=parsed.manifest.minKobeVersion;if(compareSemver(CURRENT_VERSION,min)<0)fail(`plugin requires Rove >= ${min} (this is ${CURRENT_VERSION}); update Rove first`)}function printPreview(parsed,source){let m=parsed.manifest;console.log(`
2
+ import{PLUGIN_MANIFEST_FILENAMES,currentPluginPlatform,loadPluginRegistry,parsePluginManifest,pluginCheckoutDir,pluginConfigDir,pluginManifestPath,pluginStateDir,pluginsRootDir,savePluginRegistry,supportsPlatform,upsertPluginEntry}from"./chunk-bq9shn2d.js";import{CURRENT_VERSION,compareSemver}from"./chunk-zp846pvb.js";import{spawnSync}from"child_process";import{cpSync,existsSync,mkdirSync,readFileSync,renameSync,rmSync}from"fs";import{mkdtempSync}from"fs";import{basename,join,resolve}from"path";import{createInterface}from"readline/promises";var GITHUB_SPEC_RE=/^([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)(\/.+)?$/;class PluginCliError extends Error{}function fail(message){throw new PluginCliError(message)}function readManifestAt(root){let path=pluginManifestPath(root);if(!path)fail(`no ${PLUGIN_MANIFEST_FILENAMES.join(" or ")} found at ${root}`);let source=readFileSync(path,"utf8");return{...parsePluginManifest(source,basename(path)),manifestPath:path,manifestSource:source}}function checkVersionGate(parsed){let min=parsed.manifest.minKobeVersion;if(compareSemver(CURRENT_VERSION,min)<0)fail(`plugin requires Rove >= ${min} (this is ${CURRENT_VERSION}); update Rove first`)}function printPreview(parsed,source){let m=parsed.manifest;console.log(`
3
3
  ${m.name} (${m.id}) v${m.version} \u2014 ${m.description??"no description"}`),console.log(`source: ${source}`);let show=(label,commands)=>{for(let c of commands)console.log(` ${label}: ${c.command.join(" ")}`)};show("build",m.build),show("startup",m.startup);for(let a of m.actions)console.log(` action ${a.id}: ${a.command.join(" ")}`);for(let e of m.events)console.log(` on ${e.on}: ${e.command.join(" ")}`);for(let w of parsed.warnings)console.log(` warning: ${w}`);console.log("")}async function confirmOrBail(yes){if(yes)return;if(!process.stdin.isTTY)fail("refusing to install without confirmation in a non-interactive terminal; pass --yes");let rl=createInterface({input:process.stdin,output:process.stdout}),answer=(await rl.question("Install this plugin and run its build commands? [y/N] ")).trim().toLowerCase();if(rl.close(),answer!=="y"&&answer!=="yes")fail("aborted")}function git(args,cwd){if(spawnSync("git",args,{cwd,stdio:["ignore","inherit","inherit"]}).status!==0)fail(`git ${args[0]} failed`)}function runBuildCommands(parsed,root){let platform=currentPluginPlatform();for(let[i,step]of parsed.manifest.build.entries()){if(!supportsPlatform(step,parsed.manifest,platform))continue;let[cmd,...args]=step.command;console.log(`build[${i}]: ${step.command.join(" ")}`);let res=spawnSync(cmd,args,{cwd:root,stdio:["ignore","inherit","inherit"]});if(res.status!==0)fail(`build[${i}] failed (exit ${res.status??"spawn error"}); plugin not registered`)}}function makeStagingDir(){let root=pluginsRootDir();return mkdirSync(root,{recursive:!0}),mkdtempSync(join(root,".staging-"))}function movePluginTree(from,to){try{renameSync(from,to)}catch(err){if(err.code!=="EXDEV")throw err;cpSync(from,to,{recursive:!0,verbatimSymlinks:!0}),rmSync(from,{recursive:!0,force:!0})}}function register(entry){savePluginRegistry(upsertPluginEntry(loadPluginRegistry(),entry)),mkdirSync(pluginConfigDir(entry.id),{recursive:!0,mode:448}),mkdirSync(pluginStateDir(entry.id),{recursive:!0,mode:448})}async function installPlugin(spec,opts){let match=spec.match(GITHUB_SPEC_RE);if(!match)fail(`install takes GitHub shorthand (owner/repo[/subdir]), got \`${spec}\``);let[,owner,repo,subdirRaw]=match,subdir=subdirRaw?.replace(/^\//,""),tmp=makeStagingDir();try{let url=`https://github.com/${owner}/${repo}.git`;if(console.log(`cloning ${url}${opts.ref?` @ ${opts.ref}`:""}`),opts.ref)git(["clone","--quiet",url,tmp]),git(["checkout","--quiet",opts.ref],tmp);else git(["clone","--quiet","--depth","1",url,tmp]);let rootInClone=subdir?join(tmp,subdir):tmp,parsed=readManifestAt(rootInClone);checkVersionGate(parsed);let id=parsed.manifest.id,existing=loadPluginRegistry().plugins.find((p)=>p.id===id);if(existing?.source.kind==="link")fail(`\`${id}\` is locally linked at ${existing.root}; unlink it first`);if(!supportsPlatform({},parsed.manifest,currentPluginPlatform()))fail(`plugin declares platforms [${parsed.manifest.platforms?.join(", ")}]; this machine is unsupported`);printPreview(parsed,`github.com/${owner}/${repo}${subdir?`/${subdir}`:""}`),await confirmOrBail(opts.yes),runBuildCommands(parsed,rootInClone);let manifestPath=pluginManifestPath(rootInClone);if(!manifestPath)fail("manifest disappeared during build; aborting");if(manifestPath!==parsed.manifestPath)fail("manifest changed during build; aborting");if(readFileSync(manifestPath,"utf8")!==parsed.manifestSource)fail("manifest changed during build; aborting");let checkout=pluginCheckoutDir(id);return rmSync(checkout,{recursive:!0,force:!0}),mkdirSync(join(checkout,".."),{recursive:!0}),movePluginTree(tmp,checkout),register({id,source:{kind:"github",spec},root:subdir?join(checkout,subdir):checkout,enabled:!0,version:parsed.manifest.version,installedAt:Date.now()}),console.log(`installed ${id} v${parsed.manifest.version}`),id}finally{rmSync(tmp,{recursive:!0,force:!0})}}function linkPlugin(dir){let root=resolve(dir);if(!existsSync(root))fail(`no such directory: ${root}`);let parsed=readManifestAt(root);checkVersionGate(parsed);let id=parsed.manifest.id;if(loadPluginRegistry().plugins.find((p)=>p.id===id)?.source.kind==="github")fail(`\`${id}\` is installed from GitHub; uninstall it before linking a local copy`);for(let w of parsed.warnings)console.log(`warning: ${w}`);if(!supportsPlatform({},parsed.manifest,currentPluginPlatform()))console.log(`warning: declares platforms [${parsed.manifest.platforms?.join(", ")}]; nothing will run on this machine`);register({id,source:{kind:"link"},root,enabled:!0,version:parsed.manifest.version,installedAt:Date.now()}),console.log(`linked ${id} v${parsed.manifest.version} \u2192 ${root}`)}
4
4
  export{PluginCliError,installPlugin,linkPlugin};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{closeTab,engineTabArgv,initialTabs,setTabTitle,terminalTabsKey}from"./chunk-mkc6rmcn.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors}from"./chunk-rxpbxrqp.js";import{ApiError}from"./chunk-f7zjggfv.js";import{engineLaunchArgv}from"./chunk-v8e24gbf.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-katrbape.js";function taskEngineArgv(task){return engineLaunchArgv({command:task.command,vendor:task.vendor})}function readTabsSnapshot(taskId){try{let snap=loadStateFile()[terminalTabsKey(taskId)];return snap&&Array.isArray(snap.tabs)?snap:void 0}catch{return}}function closeTabsSnapshot(taskId,tabId){let closing,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(closing=state.tabs.find((tab)=>tab.id===tabId),!closing)return!1;let{state:next,closedId}=closeTab(state,tabId,{allowEmpty:!0});if(!closedId)return closing=void 0,!1;store[key]=next;return}),closing}function renameTabsSnapshot(taskId,tabId,title){let found=!1,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(!state.tabs.some((tab)=>tab.id===tabId))return!1;found=!0;let next=setTabTitle(state,tabId,title);if(next===state)return!1;store[key]=next;return}),found}var aliveKeysOf=(sessions)=>new Set(sessions.filter((s)=>s.alive).map((s)=>s.key));function unregisteredTabIds(snapshot,taskId,sessions){let known=new Set((snapshot?.tabs??[]).map((t)=>t.id)),prefix=`${taskId}::`,out=[];for(let s of sessions){if(!s.alive||!s.key.startsWith(prefix))continue;let tabId=s.key.slice(prefix.length);if(tabId.includes("::"))continue;if(!known.has(tabId)&&!out.includes(tabId))out.push(tabId)}return out}var abnormalExit=(exit)=>exit&&(exit.code!==0||exit.signal!==null)?exit:null;function joinTaskTabs(snapshot,taskId,sessions,persistedExits={},liveVendors,engineAlive){let unknown=sessions===null,rows0=sessions??[],alive=aliveKeysOf(rows0),sessionExits=new Map(rows0.map((s)=>[s.key,s.exit])),deadExit=(key)=>{let ex=abnormalExit(sessionExits.get(key)??persistedExits[key]);if(!ex)return null;let record=persistedExits[key],sameDeath=record?.at===ex.at,tail=sameDeath?record?.tail:void 0,code=ex.code??(sameDeath?record?.code??null:null),layer=record?.layer??"pty";return{code,signal:ex.signal,at:ex.at,layer,...tail&&tail.length>0?{tail}:{}}},engineExit=(key)=>{let record=persistedExits[`${key}#engine`];if(!record)return null;let{code,signal,at,tail,atApproximate}=record;return{code,signal,at,layer:"engine",...atApproximate?{atApproximate}:{},...tail&&tail.length>0?{tail}:{}}},rows=(snapshot?.tabs??[]).map((t)=>{let key=`${taskId}::${t.id}`,isAlive=unknown?null:alive.has(key),walked=isAlive===!0&&liveVendors?.has(key)===!0?liveVendors.get(key)??null:void 0,engineIsAlive=engineAliveOf(key,isAlive,engineAlive);return{id:t.id,kind:t.kind,title:t.title??null,vendor:t.vendor??null,liveVendor:walked!==void 0?walked:t.liveVendor??null,lastTitle:t.lastTitle??null,autoTitle:t.autoTitle??null,alive:isAlive,engineAlive:engineIsAlive,exit:isAlive===!1?deadExit(key):engineIsAlive===!1?engineExit(key):null}});for(let tabId of unregisteredTabIds(snapshot,taskId,rows0))rows.push({id:tabId,kind:"engine",title:null,vendor:null,liveVendor:null,lastTitle:null,autoTitle:null,alive:!0,engineAlive:engineAliveOf(`${taskId}::${tabId}`,!0,engineAlive),exit:null,unregistered:!0});return rows}function engineAliveOf(key,isAlive,engineAlive){if(isAlive===null)return null;if(!isAlive)return!1;return engineAlive?.has(key)===!0?engineAlive.get(key)??null:null}function publishCliTabSnapshot(taskId,sessionId){if(!taskId)return;try{let key=terminalTabsKey(taskId);if(loadStateFile()[key]!==void 0)return;let seeded=initialTabs();patchStateFile({[key]:sessionId?{...seeded,tabs:seeded.tabs.map((t)=>t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}:seeded})}catch{}}function markCliTabSession(taskId,tabId,sessionId){try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key];if(!existing||!Array.isArray(existing.tabs))return;patchStateFile({[key]:{...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}})}catch{}}function mintCliTab(taskId,vendor,command){let tabId="tab-1";try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;tabId=`tab-${ordinal}`,patchStateFile({[key]:{...state,tabs:[...state.tabs,{kind:"engine",id:tabId,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}}],activeId:tabId,nextOrdinal:ordinal+1}})}catch{tabId=`tab-cli-${Date.now().toString(36)}`}return tabId}function restoredTabsOf(sessions,taskId,exceptKey){let prefix=`${taskId}::`,ids=[];for(let s of sessions){if(s.alive||s.restored!==!0||s.key===exceptKey||!s.key.startsWith(prefix))continue;let tab=s.key.slice(prefix.length);if(tab.includes("::"))continue;if(!ids.includes(tab))ids.push(tab)}let tabs=readTabsSnapshot(taskId)?.tabs??[];return ids.map((tab)=>{let sessionId=tabs.find((t)=>t.id===tab)?.sessionId;return sessionId?{tab,sessionId}:{tab}})}function restoredTabLaunch(task,tabId,worktreePath,shell){let tab=readTabsSnapshot(task.id)?.tabs.find((t)=>t.id===tabId&&t.kind==="engine");if(!tab)return null;let base=engineLaunchArgv({command:tab.engineCommand??(tab.vendor?void 0:task.command),vendor:tab.vendor??task.vendor,effort:task.modelEffort});return buildEngineSessionLaunch({task:{id:task.id,kind:task.kind??"task",vendor:tab.vendor??task.vendor,repo:task.repo},worktreePath,shell,argv:engineTabArgv(tab,base,!1,task.vendor),promptIntent:{kind:"none"},tabId})}var isTaskKey=isHostedTaskKey,findEngineKey=findHostedEngineKey,taskKeys=hostedTaskKeys,openPtyHost=openHostedSessionHost,ensurePtyHost=ensureHostedSessionHost,listSessions=listHostedSessions,listSessionsOrNull=listHostedSessionsOrNull,deliverToKey=deliverToHostedKey,ENGINE_START_PROBE_MS=3000,ENGINE_START_POLL_MS=150,ENGINE_NOT_OBSERVED_REASON=`no engine process appeared in the session within ${ENGINE_START_PROBE_MS}ms`;function outcomeFields(outcome){if(!outcome)return{engineReady:!1,delivered:!1};return{engineReady:outcome.ready,delivered:!0,bytes:outcome.bytes,promptEcho:outcome.confirmed?"confirmed":"unconfirmed"}}async function deliverHostedPrompt(rpc,target,cwd,prompt,launch,opts){let{sessions=[]}=await rpc.request("pty.list",{}),existingKey=opts?.forceNew?null:findEngineKey(sessions,target.id,target.engineBin);if(existingKey){let pid=sessions.find((s)=>s.key===existingKey)?.pid,presence=await enginePresence(pid,target.engineBin,opts?.snapshot);if(presence.kind==="unknown")throw new ApiError(`could not read the process table, so task ${target.id}'s engine tab (${existingKey}) could not be checked for a live engine`,"ENGINE_PROBE_FAILED",{hint:"the `ps` probe failed or timed out; retry, or check the machine's process table",nextCommandArgs:["api","pty-list"]});if(presence.kind!=="engine")throw new ApiError(`task ${target.id}'s engine tab (${existingKey}) has no live engine process \u2014 its engine exited into a plain shell`,"ENGINE_NOT_RUNNING",{hint:"spawn a fresh engine tab for this prompt with --tab new",nextCommandArgs:["api","send","--task-id",target.id,"--tab","new","--prompt",prompt]});let outcome=await deliverToKey(rpc,existingKey,prompt,{vendor:presence.vendor});return{session:existingKey,pane:existingKey,started:!1,...outcomeFields(outcome)}}if(!opts?.forceNew){let aliveTabs=sessions.filter((s)=>s.alive&&isTaskKey(s.key,target.id)).map((s)=>s.key);if(aliveTabs.length>0)throw new ApiError(`task ${target.id} has live tabs (${aliveTabs.join(", ")}) but none resolves as its engine tab \u2014 refusing to spawn a new engine`,"NO_ENGINE_TAB",{hint:"address a live engine tab explicitly with --tab <tab-N> (see pty-list), or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","pty-list"]})}let frozen=restoredTabsOf(sessions,target.id,launch.key),disclose=frozen.length>0?{frozenTabs:frozen}:{},staleCanonical=sessions.find((session)=>session.key===launch.key&&!session.alive);if(staleCanonical&&staleCanonical.restored!==!0)await rpc.request("pty.kill",{key:launch.key});let open=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()});try{if(!open.alive)return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,engineReady:!1,delivered:!1,...disclose};if(launch.firstMessage){let outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs});return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,...outcomeFields(outcome),...disclose}}let started=open.created!==!1||open.respawned===!0;if(open.created===!1&&open.respawned!==!0){let outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,prompt,{snapshot:opts?.snapshot});return{session:launch.key,pane:launch.key,started,...outcomeFields(outcome),...disclose}}let pendingInit={session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!0,reason:"repo init script is still running; the engine has not started yet",...disclose};if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;if(await awaitEngineProcess(rpc,launch.key,target.engineBin,{timeoutMs:ENGINE_START_PROBE_MS,intervalMs:ENGINE_START_POLL_MS,snapshot:opts?.snapshot})===null){if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath)&&(await listSessions(rpc)).some((session)=>session.key===launch.key&&session.alive)&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;return{session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!1,reason:await hostedSessionFailureLine(rpc,launch.key)??ENGINE_NOT_OBSERVED_REASON,...disclose}}return{session:launch.key,pane:launch.key,started,engineReady:!0,delivered:!0,...disclose}}finally{await rpc.request("pty.detach",{key:launch.key}).catch(()=>{})}}var killTaskSessions=killHostedSessions;
2
+ import{closeTab,engineTabArgv,initialTabs,setTabTitle,terminalTabsKey}from"./chunk-k8vhnebj.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors}from"./chunk-5v8ny8f5.js";import{ApiError}from"./chunk-f7zjggfv.js";import{engineLaunchArgv}from"./chunk-ad37b8qf.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-katrbape.js";function taskEngineArgv(task){return engineLaunchArgv({command:task.command,vendor:task.vendor})}function readTabsSnapshot(taskId){try{let snap=loadStateFile()[terminalTabsKey(taskId)];return snap&&Array.isArray(snap.tabs)?snap:void 0}catch{return}}function closeTabsSnapshot(taskId,tabId){let closing,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(closing=state.tabs.find((tab)=>tab.id===tabId),!closing)return!1;let{state:next,closedId}=closeTab(state,tabId,{allowEmpty:!0});if(!closedId)return closing=void 0,!1;store[key]=next;return}),closing}function renameTabsSnapshot(taskId,tabId,title){let found=!1,key=terminalTabsKey(taskId);return updateStateFile((store)=>{let state=store[key];if(!state||!Array.isArray(state.tabs))return!1;if(!state.tabs.some((tab)=>tab.id===tabId))return!1;found=!0;let next=setTabTitle(state,tabId,title);if(next===state)return!1;store[key]=next;return}),found}var aliveKeysOf=(sessions)=>new Set(sessions.filter((s)=>s.alive).map((s)=>s.key));function unregisteredTabIds(snapshot,taskId,sessions){let known=new Set((snapshot?.tabs??[]).map((t)=>t.id)),prefix=`${taskId}::`,out=[];for(let s of sessions){if(!s.alive||!s.key.startsWith(prefix))continue;let tabId=s.key.slice(prefix.length);if(tabId.includes("::"))continue;if(!known.has(tabId)&&!out.includes(tabId))out.push(tabId)}return out}var abnormalExit=(exit)=>exit&&(exit.code!==0||exit.signal!==null)?exit:null;function joinTaskTabs(snapshot,taskId,sessions,persistedExits={},liveVendors,engineAlive){let unknown=sessions===null,rows0=sessions??[],alive=aliveKeysOf(rows0),sessionExits=new Map(rows0.map((s)=>[s.key,s.exit])),deadExit=(key)=>{let ex=abnormalExit(sessionExits.get(key)??persistedExits[key]);if(!ex)return null;let record=persistedExits[key],sameDeath=record?.at===ex.at,tail=sameDeath?record?.tail:void 0,code=ex.code??(sameDeath?record?.code??null:null),layer=record?.layer??"pty";return{code,signal:ex.signal,at:ex.at,layer,...tail&&tail.length>0?{tail}:{}}},engineExit=(key)=>{let record=persistedExits[`${key}#engine`];if(!record)return null;let{code,signal,at,tail,atApproximate}=record;return{code,signal,at,layer:"engine",...atApproximate?{atApproximate}:{},...tail&&tail.length>0?{tail}:{}}},rows=(snapshot?.tabs??[]).map((t)=>{let key=`${taskId}::${t.id}`,isAlive=unknown?null:alive.has(key),walked=isAlive===!0&&liveVendors?.has(key)===!0?liveVendors.get(key)??null:void 0,engineIsAlive=engineAliveOf(key,isAlive,engineAlive);return{id:t.id,kind:t.kind,title:t.title??null,vendor:t.vendor??null,liveVendor:walked!==void 0?walked:t.liveVendor??null,lastTitle:t.lastTitle??null,autoTitle:t.autoTitle??null,alive:isAlive,engineAlive:engineIsAlive,exit:isAlive===!1?deadExit(key):engineIsAlive===!1?engineExit(key):null}});for(let tabId of unregisteredTabIds(snapshot,taskId,rows0))rows.push({id:tabId,kind:"engine",title:null,vendor:null,liveVendor:null,lastTitle:null,autoTitle:null,alive:!0,engineAlive:engineAliveOf(`${taskId}::${tabId}`,!0,engineAlive),exit:null,unregistered:!0});return rows}function engineAliveOf(key,isAlive,engineAlive){if(isAlive===null)return null;if(!isAlive)return!1;return engineAlive?.has(key)===!0?engineAlive.get(key)??null:null}function publishCliTabSnapshot(taskId,sessionId){if(!taskId)return;try{let key=terminalTabsKey(taskId);if(loadStateFile()[key]!==void 0)return;let seeded=initialTabs();patchStateFile({[key]:sessionId?{...seeded,tabs:seeded.tabs.map((t)=>t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}:seeded})}catch{}}function markCliTabSession(taskId,tabId,sessionId){try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key];if(!existing||!Array.isArray(existing.tabs))return;patchStateFile({[key]:{...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,sessionId,spawned:!0}:t)}})}catch{}}function mintCliTab(taskId,vendor,command){let tabId="tab-1";try{let key=terminalTabsKey(taskId),existing=loadStateFile()[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;tabId=`tab-${ordinal}`,patchStateFile({[key]:{...state,tabs:[...state.tabs,{kind:"engine",id:tabId,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}}],activeId:tabId,nextOrdinal:ordinal+1}})}catch{tabId=`tab-cli-${Date.now().toString(36)}`}return tabId}function restoredTabsOf(sessions,taskId,exceptKey){let prefix=`${taskId}::`,ids=[];for(let s of sessions){if(s.alive||s.restored!==!0||s.key===exceptKey||!s.key.startsWith(prefix))continue;let tab=s.key.slice(prefix.length);if(tab.includes("::"))continue;if(!ids.includes(tab))ids.push(tab)}let tabs=readTabsSnapshot(taskId)?.tabs??[];return ids.map((tab)=>{let sessionId=tabs.find((t)=>t.id===tab)?.sessionId;return sessionId?{tab,sessionId}:{tab}})}function restoredTabLaunch(task,tabId,worktreePath,shell){let tab=readTabsSnapshot(task.id)?.tabs.find((t)=>t.id===tabId&&t.kind==="engine");if(!tab)return null;let base=engineLaunchArgv({command:tab.engineCommand??(tab.vendor?void 0:task.command),vendor:tab.vendor??task.vendor,effort:task.modelEffort});return buildEngineSessionLaunch({task:{id:task.id,kind:task.kind??"task",vendor:tab.vendor??task.vendor,repo:task.repo},worktreePath,shell,argv:engineTabArgv(tab,base,!1,task.vendor),promptIntent:{kind:"none"},tabId})}var isTaskKey=isHostedTaskKey,findEngineKey=findHostedEngineKey,taskKeys=hostedTaskKeys,openPtyHost=openHostedSessionHost,ensurePtyHost=ensureHostedSessionHost,listSessions=listHostedSessions,listSessionsOrNull=listHostedSessionsOrNull,deliverToKey=deliverToHostedKey,ENGINE_START_PROBE_MS=3000,ENGINE_START_POLL_MS=150,ENGINE_NOT_OBSERVED_REASON=`no engine process appeared in the session within ${ENGINE_START_PROBE_MS}ms`;function outcomeFields(outcome){if(!outcome)return{engineReady:!1,delivered:!1};return{engineReady:outcome.ready,delivered:!0,bytes:outcome.bytes,promptEcho:outcome.confirmed?"confirmed":"unconfirmed"}}async function deliverHostedPrompt(rpc,target,cwd,prompt,launch,opts){let{sessions=[]}=await rpc.request("pty.list",{}),existingKey=opts?.forceNew?null:findEngineKey(sessions,target.id,target.engineBin);if(existingKey){let pid=sessions.find((s)=>s.key===existingKey)?.pid,presence=await enginePresence(pid,target.engineBin,opts?.snapshot);if(presence.kind==="unknown")throw new ApiError(`could not read the process table, so task ${target.id}'s engine tab (${existingKey}) could not be checked for a live engine`,"ENGINE_PROBE_FAILED",{hint:"the `ps` probe failed or timed out; retry, or check the machine's process table",nextCommandArgs:["api","pty-list"]});if(presence.kind!=="engine")throw new ApiError(`task ${target.id}'s engine tab (${existingKey}) has no live engine process \u2014 its engine exited into a plain shell`,"ENGINE_NOT_RUNNING",{hint:"spawn a fresh engine tab for this prompt with --tab new",nextCommandArgs:["api","send","--task-id",target.id,"--tab","new","--prompt",prompt]});let outcome=await deliverToKey(rpc,existingKey,prompt,{vendor:presence.vendor});return{session:existingKey,pane:existingKey,started:!1,...outcomeFields(outcome)}}if(!opts?.forceNew){let aliveTabs=sessions.filter((s)=>s.alive&&isTaskKey(s.key,target.id)).map((s)=>s.key);if(aliveTabs.length>0)throw new ApiError(`task ${target.id} has live tabs (${aliveTabs.join(", ")}) but none resolves as its engine tab \u2014 refusing to spawn a new engine`,"NO_ENGINE_TAB",{hint:"address a live engine tab explicitly with --tab <tab-N> (see pty-list), or spawn a fresh engine tab with --tab new",nextCommandArgs:["api","pty-list"]})}let frozen=restoredTabsOf(sessions,target.id,launch.key),disclose=frozen.length>0?{frozenTabs:frozen}:{},staleCanonical=sessions.find((session)=>session.key===launch.key&&!session.alive);if(staleCanonical&&staleCanonical.restored!==!0)await rpc.request("pty.kill",{key:launch.key});let open=await rpc.request("pty.open",{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()});try{if(!open.alive)return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,engineReady:!1,delivered:!1,...disclose};if(launch.firstMessage){let outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,launch.firstMessage,{initMarkerPath:launch.initMarkerPath,initTimeoutMs:launch.initTimeoutMs});return{session:launch.key,pane:launch.key,started:open.created!==!1||open.respawned===!0,...outcomeFields(outcome),...disclose}}let started=open.created!==!1||open.respawned===!0;if(open.created===!1&&open.respawned!==!0){let outcome=await pastePromptWhenEngineUp(rpc,launch.key,target.engineBin,prompt,{snapshot:opts?.snapshot});return{session:launch.key,pane:launch.key,started,...outcomeFields(outcome),...disclose}}let pendingInit={session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!0,reason:"repo init script is still running; the engine has not started yet",...disclose};if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;if(await awaitEngineProcess(rpc,launch.key,target.engineBin,{timeoutMs:ENGINE_START_PROBE_MS,intervalMs:ENGINE_START_POLL_MS,snapshot:opts?.snapshot})===null){if(launch.initMarkerPath&&!initMarkerSaysFinished(launch.initMarkerPath)&&(await listSessions(rpc)).some((session)=>session.key===launch.key&&session.alive)&&!initMarkerSaysFinished(launch.initMarkerPath))return pendingInit;return{session:launch.key,pane:launch.key,started,engineReady:!1,delivered:!1,reason:await hostedSessionFailureLine(rpc,launch.key)??ENGINE_NOT_OBSERVED_REASON,...disclose}}return{session:launch.key,pane:launch.key,started,engineReady:!0,delivered:!0,...disclose}}finally{await rpc.request("pty.detach",{key:launch.key}).catch(()=>{})}}var killTaskSessions=killHostedSessions;
3
3
  export{taskEngineArgv,readTabsSnapshot,closeTabsSnapshot,renameTabsSnapshot,unregisteredTabIds,joinTaskTabs,publishCliTabSnapshot,markCliTabSession,mintCliTab,restoredTabLaunch,isTaskKey,findEngineKey,taskKeys,openPtyHost,ensurePtyHost,listSessions,listSessionsOrNull,deliverToKey,ENGINE_START_PROBE_MS,ENGINE_START_POLL_MS,ENGINE_NOT_OBSERVED_REASON,outcomeFields,deliverHostedPrompt,killTaskSessions};
@@ -3,7 +3,7 @@ import{getPersistedString,setPersistedString}from"./chunk-crt11rmj.js";import{ac
3
3
  Install Node.js (https://nodejs.org) and run it again \u2014 the Rove installer only installs Bun and Rove.`}async function runNpxSkillsInstall(agent,global){if(isNpxMissing())return process.stderr.write(`
4
4
  ${npxMissingMessage()}
5
5
 
6
- `),NPX_MISSING_EXIT;return await Bun.spawn(["npx",...npxSkillsArgv({...agent===void 0?{}:{agent},global})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}var HINT_SEEN_KEY="skillHintSeen";function markSkillHintSeen(){setPersistedString(HINT_SEEN_KEY,"1")}function kobeSkillPaths(opts={}){let home=opts.home??homedir(),cwd=opts.cwd??process.cwd();return[home,cwd].flatMap((root)=>SKILL_REL_PATHS.map((rel)=>join(root,rel)))}function parseSkillVersion(content){let m=content.match(/(?:rove|kobe)-skill-version:\s*(\d+)/);return m?Number.parseInt(m[1],10):null}function skillVersionAt(path){try{return parseSkillVersion(readFileSync(path,"utf8"))}catch{return null}}function inodeKey(path){try{let stat=statSync(path);return`${stat.dev}:${stat.ino}`}catch{return path}}function distinctSkillFiles(roots,rels){let seen=new Set,out=[];for(let root of roots)for(let rel of rels){let path=join(root,rel);if(!existsSync(path))continue;let key=inodeKey(path);if(seen.has(key))continue;seen.add(key),out.push(path)}return out}function installedSkillDirs(home=homedir()){return distinctSkillFiles([home],SKILL_REL_PATHS).map((path)=>dirname(path))}function kobeSkillState(opts={}){let roots=[opts.home??homedir(),opts.cwd??process.cwd()],roveCopies=distinctSkillFiles(roots,ROVE_SKILL_REL_PATHS).map((path)=>({path,version:skillVersionAt(path)})),legacy=distinctSkillFiles(roots,LEGACY_SKILL_REL_PATHS).map((path)=>({path,version:skillVersionAt(path)})),best=[...roveCopies].sort((a,b)=>(b.version??-1)-(a.version??-1))[0]??legacy[0];if(!best)return{installed:!1,installedVersion:null,currentVersion:KOBE_SKILL_VERSION,stale:!1,legacyCopies:[],path:null};let stale=best.version===null||best.version<KOBE_SKILL_VERSION;return{installed:!0,installedVersion:best.version,currentVersion:KOBE_SKILL_VERSION,stale,legacyCopies:legacy.filter((copy)=>copy.path!==best.path),path:best.path}}function installedSkillDiffersFromBundled(installedPath){let bundled=bundledSkillDir();if(!bundled)return!1;try{return readFileSync(join(bundled,"SKILL.md"),"utf8")!==readFileSync(installedPath,"utf8")}catch{return!1}}function describeLegacyCopies(copies){return copies.map((c)=>`${c.path}${c.version===null?"":` (v${c.version})`}`).join(", ")}function promptLine(){return new Promise((resolve2)=>{process.stdin.resume(),process.stdin.once("data",(d)=>{process.stdin.pause(),resolve2(String(d))})})}async function maybeHintSkillInstall(io={}){let{isRovePluginEnabled}=await import("./chunk-agw0gz3e.js");if(isRovePluginEnabled())return;let cliName=activeCliName(),installCommand=skillInstallCommand(),state=kobeSkillState();if(!state.installed){if(getPersistedString(HINT_SEEN_KEY)==="1")return;setPersistedString(HINT_SEEN_KEY,"1"),process.stderr.write(`
6
+ `),NPX_MISSING_EXIT;return await Bun.spawn(["npx",...npxSkillsArgv({...agent===void 0?{}:{agent},global})],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}var HINT_SEEN_KEY="skillHintSeen";function markSkillHintSeen(){setPersistedString(HINT_SEEN_KEY,"1")}function kobeSkillPaths(opts={}){let home=opts.home??homedir(),cwd=opts.cwd??process.cwd();return[home,cwd].flatMap((root)=>SKILL_REL_PATHS.map((rel)=>join(root,rel)))}function parseSkillVersion(content){let m=content.match(/(?:rove|kobe)-skill-version:\s*(\d+)/);return m?Number.parseInt(m[1],10):null}function skillVersionAt(path){try{return parseSkillVersion(readFileSync(path,"utf8"))}catch{return null}}function inodeKey(path){try{let stat=statSync(path);return`${stat.dev}:${stat.ino}`}catch{return path}}function distinctSkillFiles(roots,rels){let seen=new Set,out=[];for(let root of roots)for(let rel of rels){let path=join(root,rel);if(!existsSync(path))continue;let key=inodeKey(path);if(seen.has(key))continue;seen.add(key),out.push(path)}return out}function installedSkillDirs(home=homedir()){return distinctSkillFiles([home],SKILL_REL_PATHS).map((path)=>dirname(path))}function kobeSkillState(opts={}){let roots=[opts.home??homedir(),opts.cwd??process.cwd()],roveCopies=distinctSkillFiles(roots,ROVE_SKILL_REL_PATHS).map((path)=>({path,version:skillVersionAt(path)})),legacy=distinctSkillFiles(roots,LEGACY_SKILL_REL_PATHS).map((path)=>({path,version:skillVersionAt(path)})),best=[...roveCopies].sort((a,b)=>(b.version??-1)-(a.version??-1))[0]??legacy[0];if(!best)return{installed:!1,installedVersion:null,currentVersion:KOBE_SKILL_VERSION,stale:!1,legacyCopies:[],path:null};let stale=best.version===null||best.version<KOBE_SKILL_VERSION;return{installed:!0,installedVersion:best.version,currentVersion:KOBE_SKILL_VERSION,stale,legacyCopies:legacy.filter((copy)=>copy.path!==best.path),path:best.path}}function installedSkillDiffersFromBundled(installedPath){let bundled=bundledSkillDir();if(!bundled)return!1;try{return readFileSync(join(bundled,"SKILL.md"),"utf8")!==readFileSync(installedPath,"utf8")}catch{return!1}}function describeLegacyCopies(copies){return copies.map((c)=>`${c.path}${c.version===null?"":` (v${c.version})`}`).join(", ")}function promptLine(){return new Promise((resolve2)=>{process.stdin.resume(),process.stdin.once("data",(d)=>{process.stdin.pause(),resolve2(String(d))})})}async function maybeHintSkillInstall(io={}){let{isRovePluginEnabled}=await import("./chunk-95gg6bn6.js");if(isRovePluginEnabled())return;let cliName=activeCliName(),installCommand=skillInstallCommand(),state=kobeSkillState();if(!state.installed){if(getPersistedString(HINT_SEEN_KEY)==="1")return;setPersistedString(HINT_SEEN_KEY,"1"),process.stderr.write(`
7
7
  ${cliName}: the Rove agent skill isn't installed \u2014 install it so your coding agent can drive Rove via \`${cliName} api\`:
8
8
  ${installCommand}
9
9
  (wraps \`${npxSkillsCommand()}\`; check anytime with \`${cliName} doctor\`)
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-h3y0npdb.js";import{t}from"./chunk-rrymnz5z.js";import{createInterface}from"readline";function daemonRestartFix(cliName,reason){return{kind:"run",id:"daemon-restart",label:t(`doctor.fix.${reason}`),command:[cliName,"daemon","restart"],why:t("doctor.fix.daemonRestartWhy")}}function skillInstallFix(installCommand,stale){return{kind:"run",id:"skill-install",label:t(stale?"doctor.fix.skillStale":"doctor.fix.skillMissing"),command:installCommand.split(" "),why:t("doctor.fix.skillInstallWhy")}}function resetManualFix(cliName,reason){return{kind:"manual",id:`reset:${reason}`,label:t(`doctor.fix.${reason}`),action:`${cliName} reset`,why:t("doctor.fix.resetWhy")}}function killOrphansManualFix(cliName,count){return{kind:"manual",id:"kill-orphans",label:t("doctor.fix.orphans",{count}),action:`${cliName} doctor --kill-orphans`,why:t("doctor.fix.orphansWhy")}}function engineTabsManualFix(){return{kind:"manual",id:"engine-tabs",label:t("doctor.fix.engineTabs"),action:t("doctor.fix.engineTabsAction"),why:t("doctor.fix.engineTabsWhy")}}function reinstallManualFix(){return{kind:"manual",id:"reinstall",label:t("doctor.fix.staleInstall"),action:t("doctor.fix.staleInstallAction"),why:t("doctor.fix.staleInstallWhy")}}function spawnHelperFix(paths){return{kind:"run",id:"spawn-helper-chmod",label:t("doctor.fix.spawnHelper"),command:["chmod","755",...paths],why:t("doctor.fix.spawnHelperWhy")}}function humanOnlyFix(reason,vars){return{kind:"manual",id:reason,label:t(`doctor.fix.${reason}`),action:t(`doctor.fix.${reason}Action`,vars),why:t("doctor.fix.humanOnlyWhy")}}function noEngineFix(signedOut){return signedOut.length>0?humanOnlyFix("noEngineLogin",{list:signedOut.join(", ")}):humanOnlyFix("noEngine")}function noEngineAction(signedOut){return signedOut.length>0?t("doctor.fix.noEngineLoginAction",{list:signedOut.join(", ")}):t("doctor.fix.noEngineAction")}function dedupeFixes(fixes){let seen=new Set;return fixes.filter((fix)=>{if(seen.has(fix.id))return!1;return seen.add(fix.id),!0})}async function applyFixes(collected,rt){let fixes=dedupeFixes(collected);if(fixes.length===0){rt.out(""),rt.out(t("doctor.fix.none"));return}let runnable=fixes.filter((fix)=>fix.kind==="run");if(runnable.length>0){rt.out(""),rt.out(t("doctor.fix.header"));for(let fix of runnable){if(rt.out(` ${fix.label}`),rt.out(` ${t("doctor.fix.willRun",{command:fix.command.join(" ")})}`),rt.out(` ${fix.why}`),!rt.interactive)continue;if(!await rt.confirm(` ${t("doctor.fix.confirmPrompt")}`)){rt.out(` ${t("doctor.fix.skipped")}`);continue}let code=await rt.exec(fix.command);rt.out(code===0?` ${t("doctor.fix.done")}`:` ${t("doctor.fix.failed",{code})}`)}if(!rt.interactive)rt.out(` ${t("doctor.fix.nonInteractive")}`)}let manual=fixes.filter((fix)=>fix.kind==="manual");if(manual.length>0){rt.out(""),rt.out(t("doctor.fix.manualHeader"));for(let fix of manual)rt.out(` ${fix.label}`),rt.out(` \u2192 ${fix.action}`),rt.out(` ${fix.why}`)}}async function confirmTty(question){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(question,resolve));return answer.trim().toLowerCase()==="y"||answer.trim().toLowerCase()==="yes"}finally{readline.close()}}async function execInherited(command){try{return await Bun.spawn([...command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}catch{return 127}}function defaultFixRuntime(){return{confirm:confirmTty,exec:execInherited,out:(line)=>console.log(line),interactive:process.stdin.isTTY===!0}}async function probeGit(){try{let proc=Bun.spawn(["git","--version"],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),text=(await new Response(proc.stdout).text()).trim();if(await proc.exited===0&&text)return{line:`git: \u2713 ${text}`,found:!0}}catch{}return{line:"git: \u2717 not found on PATH",found:!1}}function binaryLabel(binary){return binary.found?`\u2713 ${binary.path}`:`\u2717 ${binary.error}`}async function probeEngines(){let statuses=await detectEngineStatuses(await probeableEngineIds()),lines=["engines:"];for(let status of statuses){let account=describeAccount(status.account),name=`${status.vendor.padEnd(7)} `;if(lines.push(` ${name}${binaryLabel(status.binary)}${status.binary.found?` \u2014 ${account}`:""}`),status.accountError)lines.push(` \u26A0 ${status.accountError}`)}let{usable,signedOut}=summarizeEngines(statuses);return{lines,anyUsable:usable.length>0,signedOut}}async function checkOnboardingEnv(){let[git,engines]=await Promise.all([probeGit(),probeEngines()]);return{git,engines}}
2
+ import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-2qgs5apg.js";import{t}from"./chunk-zmyd75wm.js";import{createInterface}from"readline";function daemonRestartFix(cliName,reason){return{kind:"run",id:"daemon-restart",label:t(`doctor.fix.${reason}`),command:[cliName,"daemon","restart"],why:t("doctor.fix.daemonRestartWhy")}}function skillInstallFix(installCommand,stale){return{kind:"run",id:"skill-install",label:t(stale?"doctor.fix.skillStale":"doctor.fix.skillMissing"),command:installCommand.split(" "),why:t("doctor.fix.skillInstallWhy")}}function resetManualFix(cliName,reason){return{kind:"manual",id:`reset:${reason}`,label:t(`doctor.fix.${reason}`),action:`${cliName} reset`,why:t("doctor.fix.resetWhy")}}function killOrphansManualFix(cliName,count){return{kind:"manual",id:"kill-orphans",label:t("doctor.fix.orphans",{count}),action:`${cliName} doctor --kill-orphans`,why:t("doctor.fix.orphansWhy")}}function engineTabsManualFix(){return{kind:"manual",id:"engine-tabs",label:t("doctor.fix.engineTabs"),action:t("doctor.fix.engineTabsAction"),why:t("doctor.fix.engineTabsWhy")}}function reinstallManualFix(){return{kind:"manual",id:"reinstall",label:t("doctor.fix.staleInstall"),action:t("doctor.fix.staleInstallAction"),why:t("doctor.fix.staleInstallWhy")}}function spawnHelperFix(paths){return{kind:"run",id:"spawn-helper-chmod",label:t("doctor.fix.spawnHelper"),command:["chmod","755",...paths],why:t("doctor.fix.spawnHelperWhy")}}function humanOnlyFix(reason,vars){return{kind:"manual",id:reason,label:t(`doctor.fix.${reason}`),action:t(`doctor.fix.${reason}Action`,vars),why:t("doctor.fix.humanOnlyWhy")}}function noEngineFix(signedOut){return signedOut.length>0?humanOnlyFix("noEngineLogin",{list:signedOut.join(", ")}):humanOnlyFix("noEngine")}function noEngineAction(signedOut){return signedOut.length>0?t("doctor.fix.noEngineLoginAction",{list:signedOut.join(", ")}):t("doctor.fix.noEngineAction")}function dedupeFixes(fixes){let seen=new Set;return fixes.filter((fix)=>{if(seen.has(fix.id))return!1;return seen.add(fix.id),!0})}async function applyFixes(collected,rt){let fixes=dedupeFixes(collected);if(fixes.length===0){rt.out(""),rt.out(t("doctor.fix.none"));return}let runnable=fixes.filter((fix)=>fix.kind==="run");if(runnable.length>0){rt.out(""),rt.out(t("doctor.fix.header"));for(let fix of runnable){if(rt.out(` ${fix.label}`),rt.out(` ${t("doctor.fix.willRun",{command:fix.command.join(" ")})}`),rt.out(` ${fix.why}`),!rt.interactive)continue;if(!await rt.confirm(` ${t("doctor.fix.confirmPrompt")}`)){rt.out(` ${t("doctor.fix.skipped")}`);continue}let code=await rt.exec(fix.command);rt.out(code===0?` ${t("doctor.fix.done")}`:` ${t("doctor.fix.failed",{code})}`)}if(!rt.interactive)rt.out(` ${t("doctor.fix.nonInteractive")}`)}let manual=fixes.filter((fix)=>fix.kind==="manual");if(manual.length>0){rt.out(""),rt.out(t("doctor.fix.manualHeader"));for(let fix of manual)rt.out(` ${fix.label}`),rt.out(` \u2192 ${fix.action}`),rt.out(` ${fix.why}`)}}async function confirmTty(question){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(question,resolve));return answer.trim().toLowerCase()==="y"||answer.trim().toLowerCase()==="yes"}finally{readline.close()}}async function execInherited(command){try{return await Bun.spawn([...command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}catch{return 127}}function defaultFixRuntime(){return{confirm:confirmTty,exec:execInherited,out:(line)=>console.log(line),interactive:process.stdin.isTTY===!0}}async function probeGit(){try{let proc=Bun.spawn(["git","--version"],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),text=(await new Response(proc.stdout).text()).trim();if(await proc.exited===0&&text)return{line:`git: \u2713 ${text}`,found:!0}}catch{}return{line:"git: \u2717 not found on PATH",found:!1}}function binaryLabel(binary){return binary.found?`\u2713 ${binary.path}`:`\u2717 ${binary.error}`}async function probeEngines(){let statuses=await detectEngineStatuses(await probeableEngineIds()),lines=["engines:"];for(let status of statuses){let account=describeAccount(status.account),name=`${status.vendor.padEnd(7)} `;if(lines.push(` ${name}${binaryLabel(status.binary)}${status.binary.found?` \u2014 ${account}`:""}`),status.accountError)lines.push(` \u26A0 ${status.accountError}`)}let{usable,signedOut}=summarizeEngines(statuses);return{lines,anyUsable:usable.length>0,signedOut}}async function checkOnboardingEnv(){let[git,engines]=await Promise.all([probeGit(),probeEngines()]);return{git,engines}}
3
3
  export{daemonRestartFix,skillInstallFix,resetManualFix,killOrphansManualFix,engineTabsManualFix,reinstallManualFix,spawnHelperFix,humanOnlyFix,noEngineFix,noEngineAction,applyFixes,defaultFixRuntime,probeGit,probeEngines,checkOnboardingEnv};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{updaterShell,updaterShellFailureHint}from"./chunk-p08g04w4.js";import{$jsx,$jsxs,pageCloseBindings,useBindings,useRenderer,useT,useTheme}from"./chunk-qyh2sf97.js";import{require_react_production}from"./chunk-a82ec09z.js";import{CURRENT_VERSION,UPDATE_COMMAND,checkLatestVersion,fetchReleaseNotesRange,releasePageUrl}from"./chunk-10r5p67t.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";function waitForKeypress(){if(!process.stdin.isTTY)return Promise.resolve();return new Promise((resolve)=>{let stdin=process.stdin,done=()=>{stdin.off("data",done),stdin.setRawMode?.(!1),stdin.pause(),resolve()};stdin.setRawMode?.(!0),stdin.resume(),stdin.once("data",done)})}async function runShellUpdater(opts){opts.renderer?.destroy(),process.stdout.write(`
2
+ import{updaterShell,updaterShellFailureHint}from"./chunk-qe6bwkqp.js";import{$jsx,$jsxs,pageCloseBindings,useBindings,useRenderer,useT,useTheme}from"./chunk-xpvjq54p.js";import{require_react_production}from"./chunk-a82ec09z.js";import{CURRENT_VERSION,UPDATE_COMMAND,checkLatestVersion,fetchReleaseNotesRange,releasePageUrl}from"./chunk-zp846pvb.js";import{__toESM}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";function waitForKeypress(){if(!process.stdin.isTTY)return Promise.resolve();return new Promise((resolve)=>{let stdin=process.stdin,done=()=>{stdin.off("data",done),stdin.setRawMode?.(!1),stdin.pause(),resolve()};stdin.setRawMode?.(!0),stdin.resume(),stdin.once("data",done)})}async function runShellUpdater(opts){opts.renderer?.destroy(),process.stdout.write(`
3
3
  rove ${CURRENT_VERSION} -> ${opts.targetLabel}
4
4
  `),process.stdout.write(`running: ${opts.command}
5
5
 
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{findBinding,formatChord}from"./chunk-qyh2sf97.js";function capOf(row){return row.hint?.keys??row.keys[0]}function legendCap(id){let row=findBinding(id);if(!row)return null;let cap=capOf(row);return cap&&cap.length>0?cap:null}function directCap(row){if(row.keys.length>0)return row.hint?.keys??row.keys[0]??null;return row.prefixKeys?.length?null:row.hint?.keys??null}function availableOn(row,surface){if(row.scope==="global")return!0;if(surface===null)return!1;if(row.scope===surface)return!0;return surface==="terminal"&&row.scope==="workspace"}function grammarHelpSections(keymap,surface,prefixKey,reachability){let here=[],direct=[],prefix=[],other=new Map;for(let binding of keymap){let cap=directCap(binding),staticallyAvailable=availableOn(binding,surface),directAvailable=reachability?reachability.direct.has(binding.id):staticallyAvailable,prefixAvailable=reachability?reachability.prefix.has(binding.id):staticallyAvailable;if(cap){let row={binding,primary:cap,aliases:binding.keys.filter((key)=>key!==cap)};if(directAvailable&&(staticallyAvailable||binding.presentation==="onePress"))if(binding.presentation==="onePress")direct.push(row);else here.push(row);else if(!staticallyAvailable&&binding.scope!=="global"){let rows=other.get(binding.scope);if(rows)rows.push(row);else other.set(binding.scope,[row])}}if(prefixKey&&prefixAvailable&&binding.prefixKeys?.length)prefix.push({binding,primary:`${prefixKey} + ${binding.prefixKeys[0]}`,aliases:binding.prefixKeys.slice(1).map((key)=>`${prefixKey} + ${key}`)})}let sections=[];if(here.length)sections.push({kind:"here",scope:surface??void 0,rows:here});if(direct.length)sections.push({kind:"direct",rows:direct});if(prefix.length)sections.push({kind:"prefix",rows:prefix});for(let[scope,rows]of other)sections.push({kind:"other",scope,rows});return sections}var SCOPE_CATEGORY={global:"Global",sidebar:"Sidebar",workspace:"Workspace",files:"Files",inbox:"Inbox",terminal:"Terminal"};function scopeCategory(scope){return scope?SCOPE_CATEGORY[scope]:"Global"}function guideCategory(action){if(["kanban.open","automations.open","workItems.open"].includes(action))return"Views";if(action.startsWith("focus."))return"Navigation";if(action.startsWith("inbox.")||action.startsWith("attention."))return"Attention";if(action.startsWith("chat.tab.")||action.startsWith("chat.session."))return"Sessions";if(action.startsWith("chat.fork.")||action.startsWith("task."))return"Tasks";if(action.startsWith("settings.")||action==="workspace.zenToggle")return"Tools";return findBinding(action)?.category??"Global"}var KEY_HINTS_ENABLED_KEY="hints.keyboard.enabled",PANE_HINT_USED_KEYS={sidebar:"hints.sidebar.used",files:"hints.files.used"};function keyHintsEnabled(raw){return raw!==!1}function keyHintsToggleOn(kv){return keyHintsEnabled(kv.get(KEY_HINTS_ENABLED_KEY,!0))}function toggleKeyHints(kv){let next=!keyHintsToggleOn(kv);if(kv.set(KEY_HINTS_ENABLED_KEY,next),next)for(let key of Object.values(PANE_HINT_USED_KEYS))kv.set(key,!1)}function paneHintVisible(enabledRaw,usedRaw){return keyHintsEnabled(enabledRaw)&&usedRaw!==!0}function statusHintTokens(reach,prefixKey){let tokens=[];if(prefixKey!==null&&reach.prefix.size>0)tokens.push({chord:prefixKey,msg:"commands"});else if(reach.inputPassthrough){let cap=reach.direct.has("focus.sidebar")?legendCap("focus.sidebar"):null;if(cap)tokens.push({chord:cap,msg:"sidebar"})}if(reach.direct.has("help.open")){let cap=legendCap("help.open");if(cap)tokens.push({chord:cap,msg:"help"})}return tokens}var PANE_HINT_ROWS={sidebar:[{id:"sidebar.nav",msg:"move"},{id:"sidebar.select",msg:"open"}],files:[{id:"files.nav",msg:"move"},{id:"files.hierarchy",msg:"collapse"},{id:"files.open",msg:"open",always:!0},{id:"files.diff",msg:"diff",always:!0}]};function paneHintTokens(pane,mode){return PANE_HINT_ROWS[pane].flatMap((row)=>{if(mode==="always"&&row.always!==!0)return[];let cap=legendCap(row.id);return cap?[{cap,msg:row.msg}]:[]})}function wizardKeyLines(prefixKey){let lines=[],nav=legendCap("sidebar.nav"),open=legendCap("sidebar.select");if(nav&&open)lines.push({msg:"keysBare",params:{nav:formatChord(nav),open:formatChord(open)}});let newTab=legendCap("chat.tab.new"),focusNext=legendCap("focus.next");if(newTab&&focusNext)lines.push({msg:"keysOnePress",params:{newTab:formatChord(newTab),focusNext:formatChord(focusNext)}});if(prefixKey!==null)lines.push({msg:"keysPrefix",params:{prefix:formatChord(prefixKey)}});let help=legendCap("help.open");if(help)lines.push({msg:"keysHelp",params:{help:formatChord(help)}});return lines}
2
+ import{findBinding,formatChord}from"./chunk-xpvjq54p.js";function capOf(row){return row.hint?.keys??row.keys[0]}function legendCap(id){let row=findBinding(id);if(!row)return null;let cap=capOf(row);return cap&&cap.length>0?cap:null}function directCap(row){if(row.keys.length>0)return row.hint?.keys??row.keys[0]??null;return row.prefixKeys?.length?null:row.hint?.keys??null}function availableOn(row,surface){if(row.scope==="global")return!0;if(surface===null)return!1;if(row.scope===surface)return!0;return surface==="terminal"&&row.scope==="workspace"}function grammarHelpSections(keymap,surface,prefixKey,reachability){let here=[],direct=[],prefix=[],other=new Map;for(let binding of keymap){let cap=directCap(binding),staticallyAvailable=availableOn(binding,surface),directAvailable=reachability?reachability.direct.has(binding.id):staticallyAvailable,prefixAvailable=reachability?reachability.prefix.has(binding.id):staticallyAvailable;if(cap){let row={binding,primary:cap,aliases:binding.keys.filter((key)=>key!==cap)};if(directAvailable&&(staticallyAvailable||binding.presentation==="onePress"))if(binding.presentation==="onePress")direct.push(row);else here.push(row);else if(!staticallyAvailable&&binding.scope!=="global"){let rows=other.get(binding.scope);if(rows)rows.push(row);else other.set(binding.scope,[row])}}if(prefixKey&&prefixAvailable&&binding.prefixKeys?.length)prefix.push({binding,primary:`${prefixKey} + ${binding.prefixKeys[0]}`,aliases:binding.prefixKeys.slice(1).map((key)=>`${prefixKey} + ${key}`)})}let sections=[];if(here.length)sections.push({kind:"here",scope:surface??void 0,rows:here});if(direct.length)sections.push({kind:"direct",rows:direct});if(prefix.length)sections.push({kind:"prefix",rows:prefix});for(let[scope,rows]of other)sections.push({kind:"other",scope,rows});return sections}var SCOPE_CATEGORY={global:"Global",sidebar:"Sidebar",workspace:"Workspace",files:"Files",inbox:"Inbox",terminal:"Terminal"};function scopeCategory(scope){return scope?SCOPE_CATEGORY[scope]:"Global"}function guideCategory(action){if(["kanban.open","automations.open","workItems.open"].includes(action))return"Views";if(action.startsWith("focus."))return"Navigation";if(action.startsWith("inbox.")||action.startsWith("attention."))return"Attention";if(action.startsWith("chat.tab.")||action.startsWith("chat.session."))return"Sessions";if(action.startsWith("chat.fork.")||action.startsWith("task."))return"Tasks";if(action.startsWith("settings.")||action==="workspace.zenToggle")return"Tools";return findBinding(action)?.category??"Global"}var KEY_HINTS_ENABLED_KEY="hints.keyboard.enabled",PANE_HINT_USED_KEYS={sidebar:"hints.sidebar.used",files:"hints.files.used"};function keyHintsEnabled(raw){return raw!==!1}function keyHintsToggleOn(kv){return keyHintsEnabled(kv.get(KEY_HINTS_ENABLED_KEY,!0))}function toggleKeyHints(kv){let next=!keyHintsToggleOn(kv);if(kv.set(KEY_HINTS_ENABLED_KEY,next),next)for(let key of Object.values(PANE_HINT_USED_KEYS))kv.set(key,!1)}function paneHintVisible(enabledRaw,usedRaw){return keyHintsEnabled(enabledRaw)&&usedRaw!==!0}function statusHintTokens(reach,prefixKey){let tokens=[];if(prefixKey!==null&&reach.prefix.size>0)tokens.push({chord:prefixKey,msg:"commands"});else if(reach.inputPassthrough){let cap=reach.direct.has("focus.sidebar")?legendCap("focus.sidebar"):null;if(cap)tokens.push({chord:cap,msg:"sidebar"})}if(reach.direct.has("help.open")){let cap=legendCap("help.open");if(cap)tokens.push({chord:cap,msg:"help"})}return tokens}var PANE_HINT_ROWS={sidebar:[{id:"sidebar.nav",msg:"move"},{id:"sidebar.select",msg:"open"}],files:[{id:"files.nav",msg:"move"},{id:"files.hierarchy",msg:"collapse"},{id:"files.open",msg:"open",always:!0},{id:"files.diff",msg:"diff",always:!0}]};function paneHintTokens(pane,mode){return PANE_HINT_ROWS[pane].flatMap((row)=>{if(mode==="always"&&row.always!==!0)return[];let cap=legendCap(row.id);return cap?[{cap,msg:row.msg}]:[]})}function wizardKeyLines(prefixKey){let lines=[],nav=legendCap("sidebar.nav"),open=legendCap("sidebar.select");if(nav&&open)lines.push({msg:"keysBare",params:{nav:formatChord(nav),open:formatChord(open)}});let newTab=legendCap("chat.tab.new"),focusNext=legendCap("focus.next");if(newTab&&focusNext)lines.push({msg:"keysOnePress",params:{newTab:formatChord(newTab),focusNext:formatChord(focusNext)}});if(prefixKey!==null)lines.push({msg:"keysPrefix",params:{prefix:formatChord(prefixKey)}});let help=legendCap("help.open");if(help)lines.push({msg:"keysHelp",params:{help:formatChord(help)}});return lines}
3
3
  export{legendCap,grammarHelpSections,scopeCategory,guideCategory,KEY_HINTS_ENABLED_KEY,PANE_HINT_USED_KEYS,keyHintsEnabled,keyHintsToggleOn,toggleKeyHints,paneHintVisible,statusHintTokens,paneHintTokens,wizardKeyLines};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{currentLang,intlLocale,localeState,setLocaleLang,t,tKeys}from"./chunk-rrymnz5z.js";import"./chunk-ta0bgf5z.js";import"./chunk-sdyzxayr.js";import"./chunk-wqfp8d9w.js";export{tKeys,t,setLocaleLang,localeState,intlLocale,currentLang};
2
+ import{currentLang,intlLocale,localeState,setLocaleLang,t,tKeys}from"./chunk-zmyd75wm.js";import"./chunk-879tjgze.js";import"./chunk-sdyzxayr.js";import"./chunk-wqfp8d9w.js";export{tKeys,t,setLocaleLang,localeState,intlLocale,currentLang};
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{formatBytes}from"./chunk-my20q579.js";import{inspectLegacyTmux,legacyTmuxDoctorLines}from"./chunk-dqndd97s.js";import"./chunk-107fmq07.js";import"./chunk-9fc0j6ng.js";import"./chunk-xd9kw4hh.js";import"./chunk-rz8zs7j8.js";import"./chunk-xsrcwcjc.js";import"./chunk-vyb5a2rh.js";import"./chunk-r2pztgm6.js";import"./chunk-bq9shn2d.js";import"./chunk-63wmhbqs.js";import{resolveNodeBinary}from"./chunk-1kv9w7xe.js";import{formatDaemonInfo}from"./chunk-rcyasw34.js";import"./chunk-b99tf0jr.js";import"./chunk-g3r1dwy9.js";import"./chunk-w25b7xxz.js";import"./chunk-h4n8ffqy.js";import{isStaleInstallError,resolveKobeSpawn}from"./chunk-965jm56m.js";import"./chunk-g076r59t.js";import{KobeDaemonClient}from"./chunk-yebr932a.js";import{isForeignDaemonHome}from"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import{applyFixes,daemonRestartFix,defaultFixRuntime,engineTabsManualFix,humanOnlyFix,killOrphansManualFix,noEngineFix,probeEngines,probeGit,reinstallManualFix,resetManualFix,skillInstallFix,spawnHelperFix}from"./chunk-8kpxyqjx.js";import"./chunk-h3y0npdb.js";import"./chunk-v8e24gbf.js";import"./chunk-ba0ygf1w.js";import{t}from"./chunk-rrymnz5z.js";import"./chunk-ta0bgf5z.js";import"./chunk-sdyzxayr.js";import"./chunk-qm3x7d6f.js";import{createEngineHookAdapter}from"./chunk-46kxbsdm.js";import"./chunk-0ks58ddm.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import{CURRENT_VERSION,package_default}from"./chunk-10r5p67t.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import{kobeSkillState,skillInstallCommand}from"./chunk-wahj6696.js";import{parseHookSettings}from"./chunk-r1sh08tf.js";import"./chunk-aep7gvh4.js";import"./chunk-7kysxgbq.js";import{readableLegacyIndexPath}from"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import{ALL_VENDORS}from"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import{homeDir,kvStatePath,roveStateDir}from"./chunk-q5jhy3t8.js";import{readPidFile}from"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyHostLogPath,defaultPtyHostPidPath,defaultPtyHostSocketPath}from"./chunk-y8fqdnh3.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import{LEGACY_KOBE_STATE_DIR_BASENAME}from"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-wqfp8d9w.js";import{existsSync,readFileSync as readFileSync3,statSync as statSync2}from"fs";import{join as join2}from"path";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let vendor of ALL_VENDORS){let adapter=createEngineHookAdapter(vendor);if(!adapter.supportsHooks())continue;let file=adapter.globalSettingsPath();if(!file||!file.endsWith(".json"))continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let parsed=parseHookSettings(raw);if(!parsed.ok)issues.push({file,reason:parsed.reason})}return issues}var MIN_BUN_VERSION=package_default.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0";function parseBunVersion(raw){return raw.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function isBunAtLeast(raw,minimum=MIN_BUN_VERSION){let found=parseBunVersion(raw),floor=parseBunVersion(minimum);if(!found||!floor)return!0;let a=found.split(".").map(Number),b=floor.split(".").map(Number);for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(av!==bv)return av>bv}return!0}function classifyHookChannel(input){let total=0,hooked=0;for(let tabs of Object.values(input.tabs))for(let entry of Object.values(tabs))if(total++,entry.source==="hook")hooked++;if(total===0)return{kind:"no-tabs"};if(hooked===0)return{kind:"down",totalTabs:total};return{kind:"live",hookTabs:hooked,totalTabs:total}}function hookChannelDoctorLines(verdict,input,cliName){let configLines=(input.configIssues??[]).flatMap((issue)=>[` \u26A0 hook install skipped: ${issue.file}`,` ${issue.reason} \u2014 fix the file, then relaunch Rove`]);if(verdict.kind==="no-tabs")return["hooks: \u2014 no engine tabs yet (nothing to check)",...configLines];if(verdict.kind==="live")return[`hooks: \u2713 engine hook channel live (${verdict.hookTabs}/${verdict.totalTabs} tab(s) hook-sourced)`,...configLines];let out=[`hooks: \u2717 NO hook events reaching the daemon (0/${verdict.totalTabs} tab(s) hook-sourced)`," badges fall back to a ~10s poll, so activity looks seconds late",` daemon socket: ${input.socketPath}`,...configLines];return out.push(' \u2192 compare with an engine tab\'s own path: `ps eww -p <engine-pid> | tr " " "\\n" | grep DAEMON_SOCKET_PATH`',` \u2192 restart the engine tabs (they may hold a stale socket path), or run \`${cliName} daemon restart\``,` \u2192 debug one hook directly: \`KOBE_HOOK_DEBUG=1 echo '{}' | ${cliName} hook turn-start --engine claude\``),out}import{readdirSync,statSync}from"fs";import{createRequire}from"module";import{dirname,join}from"path";function installedSpawnHelpers(){let pkg;try{pkg=dirname(createRequire(import.meta.url).resolve("node-pty/package.json"))}catch{return[]}let prebuilds=join(pkg,"prebuilds"),arches;try{arches=readdirSync(prebuilds).filter((name)=>name.startsWith("darwin-"))}catch{return[]}let helpers=[];for(let arch of arches){let path=join(prebuilds,arch,"spawn-helper");try{helpers.push({path,executable:(statSync(path).mode&64)!==0})}catch{}}return helpers}function spawnHelperDoctorLines(helpers){let broken=helpers.filter((helper)=>!helper.executable).map((helper)=>helper.path);if(helpers.length===0)return{lines:["node-pty: ? no darwin spawn-helper found next to node-pty"],broken};if(broken.length===0)return{lines:[`node-pty: \u2713 spawn-helper executable (${helpers.length} arch)`],broken};return{lines:["node-pty: \u2717 spawn-helper is not executable \u2014 every node-pty PTY spawn fails",...broken.map((path)=>` ${path}`),` \u2192 chmod 755 ${broken.join(" ")}`],broken}}import{appendFileSync,readFileSync as readFileSync2}from"fs";var PTY_MARKER="KOBE_TERMINAL_PTY=1",run=async(argv)=>{try{let proc=Bun.spawn([...argv],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),[stdout,code]=await Promise.all([new Response(proc.stdout).text().catch(()=>""),proc.exited]);return{code,stdout}}catch{return{code:127,stdout:""}}};function parsePsRows(output){let rows=[];for(let line of output.split(`
3
- `)){let parts=line.trim().split(/\s+/);if(parts.length<6)continue;let[pid,ppid,pgid]=[parts[0],parts[1],parts[2]].map((value)=>Number.parseInt(value??"",10)),rssKb=Number.parseInt(parts[4]??"",10);if(!Number.isFinite(pid)||!Number.isFinite(ppid)||!Number.isFinite(pgid)||!Number.isFinite(rssKb))continue;rows.push({pid,ppid,pgid,etime:parts[3]??"",rssKb,command:parts.slice(5).join(" ")})}return rows}function pidAlive(pid,rows){return rows.some((row)=>row.pid===pid)}function orphanCandidates(rows,selfPgid,liveSessionPids){return rows.filter((row)=>row.ppid===1&&row.pgid!==selfPgid&&!liveSessionPids.has(row.pgid)&&!pidAlive(row.pgid,rows))}async function markedPids(pids,deps={}){let runProbe=deps.run??run,readEnviron=deps.readEnviron??((pid)=>readFileSync2(`/proc/${pid}/environ`,"utf8")),marked=new Set;if(pids.length===0)return{marked,failed:null};if((deps.platform??process.platform)==="linux"){let refused=null;for(let pid of pids)try{if(readEnviron(pid).split("\x00").includes(PTY_MARKER))marked.add(pid)}catch(err){let code=err.code;if(code!=="ENOENT"&&code!=="ESRCH")refused??=`/proc/${pid}/environ: ${code??"unreadable"}`}return{marked,failed:refused}}let result=await runProbe(["ps","eww","-o","pid=,command=","-p",pids.join(",")]);if(result.code!==0)return{marked,failed:`ps eww exited ${result.code}`};let marker=new RegExp(`(^|\\s)${PTY_MARKER}(\\s|$)`);for(let line of result.stdout.split(`
2
+ import{formatBytes,hookConfigIssues}from"./chunk-y8srv2kd.js";import{inspectLegacyTmux,legacyTmuxDoctorLines}from"./chunk-dqndd97s.js";import"./chunk-107fmq07.js";import"./chunk-9fc0j6ng.js";import"./chunk-xd9kw4hh.js";import"./chunk-rz8zs7j8.js";import"./chunk-xsrcwcjc.js";import"./chunk-vyb5a2rh.js";import"./chunk-r2pztgm6.js";import"./chunk-bq9shn2d.js";import"./chunk-63wmhbqs.js";import{resolveNodeBinary}from"./chunk-1kv9w7xe.js";import{formatDaemonInfo}from"./chunk-rcyasw34.js";import"./chunk-b99tf0jr.js";import"./chunk-g3r1dwy9.js";import"./chunk-w25b7xxz.js";import"./chunk-h4n8ffqy.js";import{isStaleInstallError,resolveKobeSpawn}from"./chunk-965jm56m.js";import"./chunk-g076r59t.js";import{KobeDaemonClient}from"./chunk-yebr932a.js";import{isForeignDaemonHome}from"./chunk-re5ke4fz.js";import"./chunk-mnqxgvyb.js";import{applyFixes,daemonRestartFix,defaultFixRuntime,engineTabsManualFix,humanOnlyFix,killOrphansManualFix,noEngineFix,probeEngines,probeGit,reinstallManualFix,resetManualFix,skillInstallFix,spawnHelperFix}from"./chunk-dwqyryn2.js";import"./chunk-2qgs5apg.js";import"./chunk-ad37b8qf.js";import"./chunk-401a3x2y.js";import{t}from"./chunk-zmyd75wm.js";import"./chunk-879tjgze.js";import"./chunk-sdyzxayr.js";import"./chunk-6ynwn2d2.js";import"./chunk-8k625ztz.js";import"./chunk-28430c3s.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import{CURRENT_VERSION,package_default}from"./chunk-zp846pvb.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import{kobeSkillState,skillInstallCommand}from"./chunk-dkeh3535.js";import"./chunk-z10thenb.js";import"./chunk-3trm92y6.js";import"./chunk-7kysxgbq.js";import{readableLegacyIndexPath}from"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import{homeDir,kvStatePath,roveStateDir}from"./chunk-q5jhy3t8.js";import{readPidFile}from"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import{defaultDaemonLogPath,defaultDaemonPidPath,defaultDaemonSocketPath,defaultPtyHostLogPath,defaultPtyHostPidPath,defaultPtyHostSocketPath}from"./chunk-y8fqdnh3.js";import{activeCliName}from"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import{LEGACY_KOBE_STATE_DIR_BASENAME}from"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-wqfp8d9w.js";import{existsSync,readFileSync as readFileSync2,statSync as statSync2}from"fs";import{join as join2}from"path";var MIN_BUN_VERSION=package_default.engines.bun.match(/\d+\.\d+\.\d+/)?.[0]??"0.0.0";function parseBunVersion(raw){return raw.trim().match(/^v?(\d+\.\d+\.\d+)/)?.[1]??null}function isBunAtLeast(raw,minimum=MIN_BUN_VERSION){let found=parseBunVersion(raw),floor=parseBunVersion(minimum);if(!found||!floor)return!0;let a=found.split(".").map(Number),b=floor.split(".").map(Number);for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(av!==bv)return av>bv}return!0}function classifyHookChannel(input){let total=0,hooked=0;for(let tabs of Object.values(input.tabs))for(let entry of Object.values(tabs))if(total++,entry.source==="hook")hooked++;if(total===0)return{kind:"no-tabs"};if(hooked===0)return{kind:"down",totalTabs:total};return{kind:"live",hookTabs:hooked,totalTabs:total}}function hookChannelDoctorLines(verdict,input,cliName){let configLines=(input.configIssues??[]).flatMap((issue)=>[` \u26A0 hook install skipped: ${issue.file}`,` ${issue.reason} \u2014 fix the file, then relaunch Rove`]);if(verdict.kind==="no-tabs")return["hooks: \u2014 no engine tabs yet (nothing to check)",...configLines];if(verdict.kind==="live")return[`hooks: \u2713 engine hook channel live (${verdict.hookTabs}/${verdict.totalTabs} tab(s) hook-sourced)`,...configLines];let out=[`hooks: \u2717 NO hook events reaching the daemon (0/${verdict.totalTabs} tab(s) hook-sourced)`," badges fall back to a ~10s poll, so activity looks seconds late",` daemon socket: ${input.socketPath}`,...configLines];return out.push(' \u2192 compare with an engine tab\'s own path: `ps eww -p <engine-pid> | tr " " "\\n" | grep DAEMON_SOCKET_PATH`',` \u2192 restart the engine tabs (they may hold a stale socket path), or run \`${cliName} daemon restart\``,` \u2192 debug one hook directly: \`KOBE_HOOK_DEBUG=1 echo '{}' | ${cliName} hook turn-start --engine claude\``),out}import{readdirSync,statSync}from"fs";import{createRequire}from"module";import{dirname,join}from"path";function installedSpawnHelpers(){let pkg;try{pkg=dirname(createRequire(import.meta.url).resolve("node-pty/package.json"))}catch{return[]}let prebuilds=join(pkg,"prebuilds"),arches;try{arches=readdirSync(prebuilds).filter((name)=>name.startsWith("darwin-"))}catch{return[]}let helpers=[];for(let arch of arches){let path=join(prebuilds,arch,"spawn-helper");try{helpers.push({path,executable:(statSync(path).mode&64)!==0})}catch{}}return helpers}function spawnHelperDoctorLines(helpers){let broken=helpers.filter((helper)=>!helper.executable).map((helper)=>helper.path);if(helpers.length===0)return{lines:["node-pty: ? no darwin spawn-helper found next to node-pty"],broken};if(broken.length===0)return{lines:[`node-pty: \u2713 spawn-helper executable (${helpers.length} arch)`],broken};return{lines:["node-pty: \u2717 spawn-helper is not executable \u2014 every node-pty PTY spawn fails",...broken.map((path)=>` ${path}`),` \u2192 chmod 755 ${broken.join(" ")}`],broken}}import{appendFileSync,readFileSync}from"fs";var PTY_MARKER="KOBE_TERMINAL_PTY=1",run=async(argv)=>{try{let proc=Bun.spawn([...argv],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),[stdout,code]=await Promise.all([new Response(proc.stdout).text().catch(()=>""),proc.exited]);return{code,stdout}}catch{return{code:127,stdout:""}}};function parsePsRows(output){let rows=[];for(let line of output.split(`
3
+ `)){let parts=line.trim().split(/\s+/);if(parts.length<6)continue;let[pid,ppid,pgid]=[parts[0],parts[1],parts[2]].map((value)=>Number.parseInt(value??"",10)),rssKb=Number.parseInt(parts[4]??"",10);if(!Number.isFinite(pid)||!Number.isFinite(ppid)||!Number.isFinite(pgid)||!Number.isFinite(rssKb))continue;rows.push({pid,ppid,pgid,etime:parts[3]??"",rssKb,command:parts.slice(5).join(" ")})}return rows}function pidAlive(pid,rows){return rows.some((row)=>row.pid===pid)}function orphanCandidates(rows,selfPgid,liveSessionPids){return rows.filter((row)=>row.ppid===1&&row.pgid!==selfPgid&&!liveSessionPids.has(row.pgid)&&!pidAlive(row.pgid,rows))}async function markedPids(pids,deps={}){let runProbe=deps.run??run,readEnviron=deps.readEnviron??((pid)=>readFileSync(`/proc/${pid}/environ`,"utf8")),marked=new Set;if(pids.length===0)return{marked,failed:null};if((deps.platform??process.platform)==="linux"){let refused=null;for(let pid of pids)try{if(readEnviron(pid).split("\x00").includes(PTY_MARKER))marked.add(pid)}catch(err){let code=err.code;if(code!=="ENOENT"&&code!=="ESRCH")refused??=`/proc/${pid}/environ: ${code??"unreadable"}`}return{marked,failed:refused}}let result=await runProbe(["ps","eww","-o","pid=,command=","-p",pids.join(",")]);if(result.code!==0)return{marked,failed:`ps eww exited ${result.code}`};let marker=new RegExp(`(^|\\s)${PTY_MARKER}(\\s|$)`);for(let line of result.stdout.split(`
4
4
  `)){let pid=Number.parseInt(line.trim().split(/\s+/)[0]??"",10);if(Number.isFinite(pid)&&marker.test(line))marked.add(pid)}return{marked,failed:null}}async function ownPgid(runProbe){let result=await runProbe(["ps","-o","pgid=","-p",String(process.pid)]),pgid=Number.parseInt(result.stdout.trim(),10);return Number.isFinite(pgid)?pgid:-1}async function collectOrphans(liveSessionPids,deps={}){let runProbe=deps.run??run;if((deps.platform??process.platform)==="win32")return{orphans:[],error:null};let ps=await runProbe(["ps","-A","-o","pid=,ppid=,pgid=,etime=,rss=,command="]);if(ps.code!==0)return{orphans:[],error:`could not read the process table \u2014 ps exited ${ps.code}`};let rows=parsePsRows(ps.stdout),candidates=orphanCandidates(rows,await ownPgid(runProbe),liveSessionPids),{marked,failed}=await markedPids(candidates.map((row)=>row.pid),deps);if(failed)return{orphans:[],error:`could not read process environments \u2014 ${failed}`};return{orphans:candidates.filter((row)=>marked.has(row.pid)),error:null}}function formatMb(rssKb){return`${(rssKb/1024).toFixed(0)} MB`}function orphanDoctorLines(orphans,error,cliName,killing=!1){if(error)return[`orphans: \u2717 ${error}`];if(orphans.length===0)return["orphans: \u2713 none \u2014 no processes left behind by a dead PTY session"];let totalMb=orphans.reduce((sum,row)=>sum+row.rssKb,0)/1024,lines=[`orphans: \u26A0 ${orphans.length} process(es) outlived the PTY session that spawned them (${totalMb.toFixed(0)} MB RSS)`," each is reparented to init, carries Rove's PTY marker, and its process"," group leader is gone \u2014 no live task owns them"];for(let row of[...orphans].sort((a,b)=>b.rssKb-a.rssKb))lines.push(` pid ${row.pid} (group ${row.pgid}) up ${row.etime}, ${formatMb(row.rssKb)}: ${row.command.slice(0,90)}`);if(!killing)lines.push(` \u2192 \`${cliName} doctor --kill-orphans\` ends those process groups (SIGTERM, then SIGKILL)`," read the list first: something you backgrounded from a Rove terminal and then"," closed the tab on looks exactly like a leak, and doctor cannot tell them apart");return lines}var GROUP_EXIT_GRACE_MS=2000,GROUP_POLL_MS=100;function logOrphanKill(pgid,signal,logPath=defaultDaemonLogPath()){try{appendFileSync(logPath,formatDaemonInfo("doctor-kill-orphans",`${signal} process group ${pgid}`))}catch{}}function groupAlive(pgid){try{return process.kill(-pgid,0),!0}catch(err){return err.code!=="ESRCH"}}async function killOrphanGroups(orphans){let groups=[...new Set(orphans.map((row)=>row.pgid))];for(let pgid of groups)try{process.kill(-pgid,"SIGTERM"),logOrphanKill(pgid,"SIGTERM")}catch{}let deadline=Date.now()+GROUP_EXIT_GRACE_MS,survivors=groups.filter(groupAlive);while(survivors.length>0&&Date.now()<deadline)await new Promise((resolve)=>setTimeout(resolve,GROUP_POLL_MS)),survivors=survivors.filter(groupAlive);for(let pgid of survivors)try{process.kill(-pgid,"SIGKILL"),logOrphanKill(pgid,"SIGKILL")}catch{}return await new Promise((resolve)=>setTimeout(resolve,GROUP_POLL_MS)),{groups,survivors:survivors.filter(groupAlive)}}function multiplexerLabel(env){if(env.TMUX)return"tmux";if(env.ZELLIJ)return"zellij";if(env.STY)return"screen";return"no"}function terminalEnvLines(env){let show=(v)=>v&&v.length>0?v:"(unset)",program=env.TERM_PROGRAM?`${env.TERM_PROGRAM}${env.TERM_PROGRAM_VERSION?` v${env.TERM_PROGRAM_VERSION}`:""}`:"(unset)";return[`terminal: TERM=${show(env.TERM)} TERM_PROGRAM=${program} COLORTERM=${show(env.COLORTERM)}`,` running inside a multiplexer: ${multiplexerLabel(env)}`]}function parseKittyProbeReply(data){let kitty=data.match(/\x1b\[\?(\d+)u/);if(kitty?.[1]!==void 0)return{kind:"supported",flags:Number.parseInt(kitty[1],10)};if(/\x1b\[\?[\d;]*c/.test(data))return{kind:"unsupported"};return null}function kittyProbeLine(result){switch(result.kind){case"supported":return` kitty keyboard protocol: \u2713 answered (flags=${result.flags})`;case"unsupported":return[" kitty keyboard protocol: \u2717 not supported \u2014 legacy key path"," (ctrl+h/ctrl+j arrive as C0 backspace/linefeed bytes; the"," split chords ctrl+\\ and ctrl+= cannot be encoded at all)"].join(`
5
- `);case"no-response":return" kitty keyboard protocol: ? no reply (terminal ignored both the kitty query and DA1)";case"skipped":return` kitty keyboard protocol: skipped (${result.reason})`}}async function probeKittyKeyboard(timeoutMs=300){let stdin=process.stdin;if(!stdin.isTTY||!process.stdout.isTTY)return{kind:"skipped",reason:"not an interactive terminal"};let wasRaw=stdin.isRaw===!0,buffer="";return await new Promise((resolve)=>{let done=!1,finish=(result)=>{if(done)return;if(done=!0,clearTimeout(timer),stdin.off("data",onData),stdin.pause(),!wasRaw)stdin.setRawMode(!1);resolve(result)},onData=(chunk)=>{buffer+=chunk.toString("latin1");let decided=parseKittyProbeReply(buffer);if(decided)finish(decided)},timer=setTimeout(()=>finish({kind:"no-response"}),timeoutMs);stdin.setRawMode(!0),stdin.resume(),stdin.on("data",onData),process.stdout.write("\x1B[?u\x1B[c")})}async function terminalDoctorLines(){return[...terminalEnvLines(process.env),kittyProbeLine(await probeKittyKeyboard())]}var CLI_NAME=activeCliName();function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(err){return err.code==="EPERM"}}async function requestIfReachable(socketPath,name){let client=new KobeDaemonClient(socketPath);try{return await client.request(name,{})}catch{return null}finally{client.close()}}function fmtDuration(ms){let seconds=Math.floor(ms/1000);if(seconds<60)return`${seconds}s`;let minutes=Math.floor(seconds/60);if(minutes<60)return`${minutes}m ${seconds%60}s`;return`${Math.floor(minutes/60)}h ${minutes%60}m`}function describeFile(path){try{let stat=statSync2(path);return`present (${formatBytes(stat.size)}, modified ${stat.mtime.toISOString()})`}catch{return"absent"}}function taskCount(path){try{let parsed=JSON.parse(readFileSync3(path,"utf8"));return Array.isArray(parsed.tasks)?parsed.tasks.length:null}catch{return null}}function tailFile(path,count){try{return readFileSync3(path,"utf8").split(`
5
+ `);case"no-response":return" kitty keyboard protocol: ? no reply (terminal ignored both the kitty query and DA1)";case"skipped":return` kitty keyboard protocol: skipped (${result.reason})`}}async function probeKittyKeyboard(timeoutMs=300){let stdin=process.stdin;if(!stdin.isTTY||!process.stdout.isTTY)return{kind:"skipped",reason:"not an interactive terminal"};let wasRaw=stdin.isRaw===!0,buffer="";return await new Promise((resolve)=>{let done=!1,finish=(result)=>{if(done)return;if(done=!0,clearTimeout(timer),stdin.off("data",onData),stdin.pause(),!wasRaw)stdin.setRawMode(!1);resolve(result)},onData=(chunk)=>{buffer+=chunk.toString("latin1");let decided=parseKittyProbeReply(buffer);if(decided)finish(decided)},timer=setTimeout(()=>finish({kind:"no-response"}),timeoutMs);stdin.setRawMode(!0),stdin.resume(),stdin.on("data",onData),process.stdout.write("\x1B[?u\x1B[c")})}async function terminalDoctorLines(){return[...terminalEnvLines(process.env),kittyProbeLine(await probeKittyKeyboard())]}var CLI_NAME=activeCliName();function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(err){return err.code==="EPERM"}}async function requestIfReachable(socketPath,name){let client=new KobeDaemonClient(socketPath);try{return await client.request(name,{})}catch{return null}finally{client.close()}}function fmtDuration(ms){let seconds=Math.floor(ms/1000);if(seconds<60)return`${seconds}s`;let minutes=Math.floor(seconds/60);if(minutes<60)return`${minutes}m ${seconds%60}s`;return`${Math.floor(minutes/60)}h ${minutes%60}m`}function describeFile(path){try{let stat=statSync2(path);return`present (${formatBytes(stat.size)}, modified ${stat.mtime.toISOString()})`}catch{return"absent"}}function taskCount(path){try{let parsed=JSON.parse(readFileSync2(path,"utf8"));return Array.isArray(parsed.tasks)?parsed.tasks.length:null}catch{return null}}function tailFile(path,count){try{return readFileSync2(path,"utf8").split(`
6
6
  `).filter((line)=>line.trim().length>0).slice(-count).join(`
7
7
  `)}catch{return""}}function describeInstall(){try{let[,entry]=resolveKobeSpawn([]);return{line:`install: \u2713 ${entry??process.execPath}`,ok:!0}}catch(err){if(!isStaleInstallError(err))return{line:`install: ? could not check (${String(err)})`,ok:!0};return{line:["install: \u2717 GONE \u2014 this process is running from an install that no longer exists on disk"," it cannot start a daemon; every reconnect fails the same way until you reinstall"," \u2192 npm install -g @sma1lboy/rove (then relaunch Rove)"].join(`
8
8
  `),ok:!1}}}async function appendUnavailableProcess(out,label,pidPath,socketPath){let pid=await readPidFile(pidPath),wedged=pid!==null&&pid!==void 0&&isProcessAlive(pid);if(wedged)out.push(`${label}: \u2717 WEDGED \u2014 process alive (pid ${pid}) but socket is unreachable`);else if(pid)out.push(`${label}: \u2717 not running (stale pidfile \u2192 pid ${pid} is gone)`);else out.push(`${label}: \u2717 not running (no pidfile)`);if(existsSync(socketPath))out.push(` orphan socket file present: ${socketPath}`);return wedged?"wedged":"down"}async function collectDoctor(){let daemonSocket=defaultDaemonSocketPath(),daemonLog=defaultDaemonLogPath(),ptySocket=defaultPtyHostSocketPath(),ptyLog=defaultPtyHostLogPath(),canonicalTasks=join2(roveStateDir(),"tasks.json"),legacyTasks=join2(homeDir(),LEGACY_KOBE_STATE_DIR_BASENAME,"tasks.json"),readableLegacy=readableLegacyIndexPath(canonicalTasks,legacyTasks),usingLegacyTasks=!existsSync(canonicalTasks)&&readableLegacy!==void 0&&existsSync(readableLegacy),tasksPath=usingLegacyTasks?legacyTasks:canonicalTasks,statePath=kvStatePath(),fixes=[],git=await probeGit();if(!git.found)fixes.push(humanOnlyFix("git"));let engines=await probeEngines();if(!engines.anyUsable)fixes.push(noEngineFix(engines.signedOut));let install=describeInstall();if(!install.ok)fixes.push(reinstallManualFix());let staleBun=!isBunAtLeast(Bun.version);if(staleBun)fixes.push(humanOnlyFix("staleBun"));let out=["Rove doctor",` build: v${CURRENT_VERSION} (${process.platform} ${process.arch}, bun ${Bun.version})`,...staleBun?[` \u26A0 bun ${Bun.version} is below the ${MIN_BUN_VERSION} Rove needs \u2014 terminals will not paint`]:[],` home: ${homeDir()}`,"",...await terminalDoctorLines(),git.line,"",...engines.lines,"",install.line,""],daemon=await requestIfReachable(daemonSocket,"daemon.status");if(daemon){let pid=typeof daemon.daemonPid==="number"?daemon.daemonPid:"?",uptime=typeof daemon.uptimeMs==="number"?fmtDuration(daemon.uptimeMs):"?",tasks=typeof daemon.taskCount==="number"?daemon.taskCount:"?",clients=typeof daemon.attachedClients==="number"?daemon.attachedClients:"?";out.push(`daemon: \u2713 running (pid ${pid}, up ${uptime}, ${tasks} task(s), ${clients} client(s))`);let version=typeof daemon.kobeVersion==="string"?daemon.kobeVersion:void 0;if(version&&version!==CURRENT_VERSION)out.push(` \u26A0 stale build: daemon is v${version}, you launched v${CURRENT_VERSION}`),out.push(` \u2192 run \`${CLI_NAME} daemon restart\`, then relaunch Rove`),fixes.push(daemonRestartFix(CLI_NAME,"daemonStale"));else if(version)out.push(` build: v${version}`);if(isForeignDaemonHome(typeof daemon.homeDir==="string"?daemon.homeDir:void 0,homeDir()))out.push(` \u26A0 foreign home: daemon serves ${String(daemon.homeDir)}, you are reading ${homeDir()}`),out.push(` \u2192 clear ROVE_HOME_DIR/KOBE_HOME_DIR, then \`${CLI_NAME} daemon restart\``);let tabs=(await requestIfReachable(daemonSocket,"debug.inspect"))?.activity?.tabs;if(tabs){let hookInput={socketPath:daemonSocket,configIssues:hookConfigIssues()},verdict=classifyHookChannel({tabs,...hookInput});if(out.push("",...hookChannelDoctorLines(verdict,hookInput,CLI_NAME)),verdict.kind==="down")fixes.push(daemonRestartFix(CLI_NAME,"hooksDown"),engineTabsManualFix())}else out.push("","hooks: ? could not read the daemon's activity registry (debug.inspect unavailable)"),fixes.push(daemonRestartFix(CLI_NAME,"inspectStale"))}else{let state=await appendUnavailableProcess(out,"daemon ",defaultDaemonPidPath(),daemonSocket);fixes.push(state==="wedged"?resetManualFix(CLI_NAME,"resetDaemonWedged"):daemonRestartFix(CLI_NAME,"daemonDown"));let tail=tailFile(daemonLog,8);if(tail){out.push(" last lines of daemon.log:");for(let line of tail.split(`