@sma1lboy/rove 0.9.209 → 0.9.211

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 (63) hide show
  1. package/dist/cli/{chunk-71ckz687.js → chunk-11z0gvxp.js} +2 -2
  2. package/dist/cli/{chunk-64jfgj4a.js → chunk-1seen4k4.js} +1 -1
  3. package/dist/cli/{chunk-km99frjx.js → chunk-26m6m9v1.js} +1 -1
  4. package/dist/cli/{chunk-s0yhjfvw.js → chunk-2d8bq2a2.js} +16 -16
  5. package/dist/cli/{chunk-3cx92j5n.js → chunk-38n756dh.js} +1 -1
  6. package/dist/cli/{chunk-72b8g3hs.js → chunk-3j7j0egr.js} +1 -1
  7. package/dist/cli/{chunk-hm32s0y8.js → chunk-60fmp80z.js} +1 -1
  8. package/dist/cli/{chunk-jgdjfsdk.js → chunk-6cc1e9pz.js} +1 -1
  9. package/dist/cli/{chunk-91tkz0vv.js → chunk-6knm7sgz.js} +2 -2
  10. package/dist/cli/{chunk-ff4va5ft.js → chunk-6xesn42r.js} +1 -1
  11. package/dist/cli/{chunk-67w5x6ng.js → chunk-7pwzz75n.js} +1 -1
  12. package/dist/cli/{chunk-1j8xkxqc.js → chunk-8m6f3myf.js} +1 -1
  13. package/dist/cli/{chunk-xsp0xqgd.js → chunk-94k3x9s4.js} +1 -1
  14. package/dist/cli/{chunk-4m57n1t2.js → chunk-9wg9snjs.js} +1 -1
  15. package/dist/cli/{chunk-g2wk0es7.js → chunk-arj1d3vp.js} +1 -1
  16. package/dist/cli/{chunk-v4bg25ks.js → chunk-bapcjjpn.js} +1 -1
  17. package/dist/cli/{chunk-mnk8ch7r.js → chunk-bhmerr46.js} +1 -1
  18. package/dist/cli/{chunk-v8yagax5.js → chunk-bw6qkdac.js} +1 -1
  19. package/dist/cli/{chunk-jbvjdpbv.js → chunk-bzha4s5k.js} +1 -1
  20. package/dist/cli/{chunk-tmxtr4x6.js → chunk-c5jvfep2.js} +1 -1
  21. package/dist/cli/{chunk-g9xb8jh5.js → chunk-dp37sv5k.js} +1 -1
  22. package/dist/cli/{chunk-qbcf37hk.js → chunk-en33n4tg.js} +1 -1
  23. package/dist/cli/{chunk-x9www3mg.js → chunk-f7n1stv7.js} +1 -1
  24. package/dist/cli/{chunk-f1nxnwkn.js → chunk-fbg2zn64.js} +1 -1
  25. package/dist/cli/{chunk-8knqwbqw.js → chunk-fs44z8vj.js} +3 -3
  26. package/dist/cli/{chunk-j5hmspf4.js → chunk-gbmz90yt.js} +1 -1
  27. package/dist/cli/{chunk-sk759pn7.js → chunk-gqq2yq9r.js} +1 -1
  28. package/dist/cli/{chunk-yfjpddf3.js → chunk-j4kr3mn5.js} +1 -1
  29. package/dist/cli/{chunk-417b1cwv.js → chunk-jkddy77a.js} +2 -2
  30. package/dist/cli/{chunk-7rw5nym1.js → chunk-jr3403fm.js} +1 -1
  31. package/dist/cli/{chunk-62qkyz5j.js → chunk-k437p7qv.js} +1 -1
  32. package/dist/cli/{chunk-eb41f3rv.js → chunk-kc13hzqs.js} +1 -1
  33. package/dist/cli/{chunk-kx2j56dv.js → chunk-kghvc2x8.js} +1 -1
  34. package/dist/cli/chunk-ktkmr7y1.js +14 -0
  35. package/dist/cli/{chunk-j38kagw2.js → chunk-kx5gzpmt.js} +1 -1
  36. package/dist/cli/{chunk-e7fv37ab.js → chunk-m2t0etdn.js} +1 -1
  37. package/dist/cli/{chunk-5y3d3sk3.js → chunk-mv0c5tqb.js} +1 -1
  38. package/dist/cli/{chunk-c8e76j2n.js → chunk-mzyr470r.js} +1 -1
  39. package/dist/cli/{chunk-103d5h4q.js → chunk-nvb8qsms.js} +1 -1
  40. package/dist/cli/{chunk-6t8rz52b.js → chunk-nxfqz3ez.js} +1 -1
  41. package/dist/cli/{chunk-ekmwvws5.js → chunk-pwp22zq3.js} +1 -1
  42. package/dist/cli/{chunk-6ebzs5pv.js → chunk-qtwbzz0t.js} +1 -1
  43. package/dist/cli/{chunk-9jnjnkqf.js → chunk-r0kczw2t.js} +1 -1
  44. package/dist/cli/{chunk-qgfwebxj.js → chunk-r83qrttp.js} +1 -1
  45. package/dist/cli/{chunk-s5dfv5zg.js → chunk-rrt4z9at.js} +1 -1
  46. package/dist/cli/{chunk-b23mvges.js → chunk-sa7yam4k.js} +1 -1
  47. package/dist/cli/{chunk-kaxn7r55.js → chunk-t6311mnm.js} +1 -1
  48. package/dist/cli/{chunk-cnv8hke8.js → chunk-t8sv7x3q.js} +1 -1
  49. package/dist/cli/{chunk-xpwaf5v6.js → chunk-vcsxd84r.js} +1 -1
  50. package/dist/cli/{chunk-m3vwrgen.js → chunk-x190hqtb.js} +1 -1
  51. package/dist/cli/{chunk-eyccnzck.js → chunk-x67ebsrg.js} +1 -1
  52. package/dist/cli/{chunk-45kjd17g.js → chunk-ygadamzf.js} +2 -2
  53. package/dist/cli/{chunk-tqr77st4.js → chunk-z2f0y7jw.js} +1 -1
  54. package/dist/cli/chunk-zd46ghvd.js +4 -0
  55. package/dist/cli/chunk-zq98c5ra.js +2 -0
  56. package/dist/cli/{chunk-wrafvgdr.js → chunk-zqzjbd5x.js} +1 -1
  57. package/dist/cli/index.js +3 -3
  58. package/dist/cli/kobe.js +1 -1
  59. package/dist/cli/rove.js +1 -1
  60. package/package.json +1 -1
  61. package/dist/cli/chunk-1b99brwq.js +0 -2
  62. package/dist/cli/chunk-1p5334mv.js +0 -4
  63. package/dist/cli/chunk-4jdmtv12.js +0 -15
@@ -1,5 +1,5 @@
1
1
  // @bun
2
2
  import{errorMessage}from"./chunk-2brn8e1y.js";import{claudeGlobalConfigPath,codexAuthPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isObject,isRoveHook,kimiCredentialsPath,kobeHookInvocation,readTextFileSyncBounded,roveHookArgs}from"./chunk-wc0tmpd7.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{getCustomEngineIds,getDisabledEngineIds}from"./chunk-crt11rmj.js";import{__require}from"./chunk-wqfp8d9w.js";import{existsSync}from"fs";import{homedir}from"os";import{dirname,join}from"path";var CURSOR_HOOK_EVENT_MAP=[{event:"sessionStart",verb:"session-start"}],CURSOR_VERBS=CURSOR_HOOK_EVENT_MAP.map((spec)=>spec.verb);function cursorHooksPath(home=homedir()){let override=process.env.CURSOR_CONFIG_DIR?.trim();return join(override||join(home,".cursor"),"hooks.json")}function parseCursorHooks(raw){if(raw===void 0)return{ok:!0,doc:{}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{ok:!1,reason:`not valid JSON (${err instanceof Error?err.message:String(err)})`}}if(!isObject(parsed))return{ok:!1,reason:"top level is not a JSON object"};if(parsed.hooks===void 0)return{ok:!0,doc:parsed};if(!isObject(parsed.hooks))return{ok:!1,reason:'"hooks" is not an object'};for(let[event,entries]of Object.entries(parsed.hooks))if(!Array.isArray(entries))return{ok:!1,reason:`"hooks.${event}" is not an array`};return{ok:!0,doc:parsed}}function mergeCursorHooks(current,install,inv=kobeHookInvocation()){let{hooks:rawHooks,...rest}=current,hooks=isObject(rawHooks)?{...rawHooks}:{};for(let{event,verb}of CURSOR_HOOK_EVENT_MAP){let kept=(Array.isArray(hooks[event])?hooks[event]:[]).filter((entry)=>!isRoveHook(entry,CURSOR_VERBS));if(install)kept.push({command:quoteShellArgv([...inv,"hook",verb,...roveHookArgs("cursor")],hookCommandQuoting())});if(kept.length>0)hooks[event]=kept;else delete hooks[event]}return{version:1,...rest,hooks}}class CursorHookAdapter{vendor="cursor";supportsHooks(){return!0}globalSettingsPath(){return cursorHooksPath()}activityDetailFromPayload(){return}cwdFromPayload(payload){let roots=payload.workspace_roots;return Array.isArray(roots)?firstString(...roots):void 0}sessionFromPayload(payload){let sessionId=firstString(payload.session_id,payload.conversation_id);if(!sessionId)return;let transcriptPath=firstString(payload.transcript_path);return{sessionId,...transcriptPath?{transcriptPath}:{}}}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync(dirname(settingsFilePath)))return{ok:!0};let outcome=await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!0),parseCursorHooks);if(!outcome.ok&&!opts.quiet)process.stderr.write(`[rove hooks] cursor: skipped ${outcome.file}: ${outcome.reason}
3
- `);return outcome}async removeActivityHooks(settingsFilePath){if(!existsSync(settingsFilePath))return;await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!1),parseCursorHooks)}hookConfigRefusal(raw){let parsed=parseCursorHooks(raw);return parsed.ok?void 0:parsed.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}function firstString(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}var pluginEngines=new Map;function registerPluginEngine(id,spec){if(Object.hasOwn(CONTRIB_ENGINES,id))return!1;return pluginEngines.set(id,spec),!0}function clearPluginEngines(){pluginEngines.clear()}function pluginEngineIds(){return[...pluginEngines.keys()]}var GEMINI={rules:[{state:"blocked",any:["\u2502 apply this change","\u2502 allow execution","waiting for user confirmation"]},{state:"blocked",all:["do you want to proceed"],any:["yes"]},{state:"working",any:["esc to cancel"]}]},OPENCODE={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"]},{state:"working",any:["esc interrupt","esc to interrupt","ctrl+c to interrupt","esc again to interrupt"]},{state:"idle",any:["enter send"]}]},CURSOR={rules:[{state:"blocked",any:["press any key to log in"]},{state:"blocked",all:["proceed (y)"]},{state:"blocked",any:["run this command?","waiting for approval","skip (esc or n)","(y) (enter)"]},{state:"working",any:["esc to cancel","ctrl+c to stop"]}]},GROK={rules:[{state:"blocked",any:["\u26A0 action required","ctrl+o:yolo"]},{state:"blocked",all:["\u2503"],lineRegex:["^\\s*\u2503\\s+\\S+\\s+\\(\u25CB\\)"]},{state:"working",any:["[stop]"],lineRegex:["^\\s*[\\u2800-\\u28FF]"]}]},DROID={rules:[{state:"blocked",all:["enter to select","esc to cancel"],any:["> yes, allow","> no, cancel"]},{state:"blocked",all:["enter select","esc cancel"]},{state:"working",any:["esc to stop"]}]},AMP={rules:[{state:"blocked",any:["waiting for approval","run this command?","allow editing file:","allow creating file:","confirm tool call"]},{state:"working",lineRegex:["^\\s*\u2570\\s+\\S+\\s+(thinking|streaming|running tools|waiting)\\s+\u2500"]}]},CONTRIB_ENGINES={gemini:{displayName:"Gemini CLI",defaultCommand:["gemini"],screenManifest:GEMINI},opencode:{displayName:"OpenCode",defaultCommand:["opencode"],screenManifest:OPENCODE,firstMessageDelivery:"paste"},cursor:{displayName:"Cursor Agent",defaultCommand:["cursor-agent"],screenManifest:CURSOR,createHookAdapter:()=>new CursorHookAdapter},grok:{displayName:"Grok CLI",defaultCommand:["grok"],screenManifest:GROK},droid:{displayName:"Droid",defaultCommand:["droid"],screenManifest:DROID},amp:{displayName:"Amp",defaultCommand:["amp"],screenManifest:AMP}};function isContribEngine(id){return Object.hasOwn(CONTRIB_ENGINES,id)||pluginEngines.has(id)}var CONTRIB_ENGINE_IDS=Object.keys(CONTRIB_ENGINES);function contribEngineEntry(id,base){let spec=CONTRIB_ENGINES[id]??pluginEngines.get(id);if(!spec)return base;return{...base,displayName:spec.displayName,defaultCommand:spec.defaultCommand,...spec.processNames?{processNames:spec.processNames}:{},screenManifest:spec.screenManifest,...spec.identity?{identity:spec.identity}:{},...spec.firstMessageDelivery?{firstMessageDelivery:spec.firstMessageDelivery}:{},...spec.createHookAdapter?{createHookAdapter:spec.createHookAdapter}:{}}}import{homedir as homedir3}from"os";import{spawnSync}from"child_process";import{existsSync as existsSync2,statSync}from"fs";import{homedir as homedir2}from"os";var defaultBinaryDeps={fileExists(p){try{return statSync(p).isFile()}catch{return!1}},env(name){return process.env[name]},home(){return homedir2()},which(name){let cmd=process.platform==="win32"?"where":"which",out=spawnSync(cmd,[name],{encoding:"utf8"});if(out.status!==0)return;let first=out.stdout.split(`
3
+ `);return outcome}async removeActivityHooks(settingsFilePath){if(!existsSync(settingsFilePath))return;await editJsonSettings(settingsFilePath,(cur)=>mergeCursorHooks(cur,!1),parseCursorHooks)}hookConfigRefusal(raw){let parsed=parseCursorHooks(raw);return parsed.ok?void 0:parsed.reason}supportsWorktreeSync(){return!1}async removeWorktreeSyncHook(){}async removeWorktreeWatchHook(){}}function firstString(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}var pluginEngines=new Map;function registerPluginEngine(id,spec){if(Object.hasOwn(CONTRIB_ENGINES,id))return!1;return pluginEngines.set(id,spec),!0}function clearPluginEngines(){pluginEngines.clear()}function pluginEngineIds(){return[...pluginEngines.keys()]}var GEMINI={rules:[{state:"blocked",any:["\u2502 apply this change","\u2502 allow execution","waiting for user confirmation"]},{state:"blocked",all:["do you want to proceed"],any:["yes"]},{state:"working",any:["esc to cancel"]}]},OPENCODE={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"]},{state:"working",any:["esc interrupt","esc to interrupt","ctrl+c to interrupt","esc again to interrupt"]},{state:"idle",any:["enter send"]}]},CURSOR={rules:[{state:"blocked",any:["press any key to log in"]},{state:"blocked",all:["proceed (y)"]},{state:"blocked",any:["run this command?","waiting for approval","skip (esc or n)","(y) (enter)"]},{state:"working",any:["esc to cancel","ctrl+c to stop"]}]},GROK={rules:[{state:"blocked",any:["\u26A0 action required","ctrl+o:yolo"]},{state:"blocked",all:["\u2503"],lineRegex:["^\\s*\u2503\\s+\\S+\\s+\\(\u25CB\\)"]},{state:"working",any:["[stop]"],lineRegex:["^\\s*[\\u2800-\\u28FF]"]}]},DROID={rules:[{state:"blocked",all:["enter to select","esc to cancel"],any:["> yes, allow","> no, cancel"]},{state:"blocked",all:["enter select","esc cancel"]},{state:"working",any:["esc to stop"]}]},AMP={rules:[{state:"blocked",any:["waiting for approval","run this command?","allow editing file:","allow creating file:","confirm tool call"]},{state:"working",lineRegex:["^\\s*\u2570\\s+\\S+\\s+(thinking|streaming|running tools|waiting)\\s+\u2500"]}]},CLINE={rules:[{state:"blocked",any:["let cline use this tool"]},{state:"blocked",all:["execute command?","yes"],any:["[act mode]","[plan mode]"]},{state:"blocked",all:["use this tool?","yes"],any:["[act mode]","[plan mode]"]}]},KIRO={rules:[{state:"blocked",all:["requires approval"],any:["yes, single permission","trust, always allow","no (tab to edit)","esc to close"]},{state:"blocked",all:["pending from subagents","tool approval"],any:["approve all pending","configure individually","exit (cancel subagents)"]},{state:"working",any:["kiro is working"]},{state:"working",all:["esc to cancel"],lineRegex:["^\\s*[\u25D4\u25D1\u25D5\u25CF]\\s+[A-Za-z]"]}]},MAKI={rules:[{state:"blocked",all:["permission required","y allow","n deny"]},{state:"blocked",all:["permission required"],any:["confirm allow","confirm deny"]},{state:"blocked",all:["permission required","enter deny","esc cancel"]},{state:"blocked",all:["plan complete","enter confirm"],any:["space toggle parallel","edit plan"]},{state:"working",bottomLines:1,lineRegex:["^( [\\u2800-\\u28FF]){1,2} \\[(BUILD|PLAN|BASH)\\]"]},{state:"idle",bottomLines:1,lineRegex:["^ \\[(BUILD|PLAN|BASH)\\]"]}]},ANTIGRAVITY={rules:[{state:"blocked",all:["requesting permission for:","do you want to proceed?"]},{state:"blocked",all:["requesting permission for:","tab amend","edit command"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]+\\s+[A-Za-z]+\\w*ing\\b"]},{state:"working",bottomLines:5,lineRegex:["\xB7\\s*[1-9][0-9]*\\s+task"]}]},CONTRIB_ENGINES={gemini:{displayName:"Gemini CLI",defaultCommand:["gemini"],screenManifest:GEMINI},opencode:{displayName:"OpenCode",defaultCommand:["opencode"],screenManifest:OPENCODE,firstMessageDelivery:"paste"},cursor:{displayName:"Cursor Agent",defaultCommand:["cursor-agent"],screenManifest:CURSOR,createHookAdapter:()=>new CursorHookAdapter},grok:{displayName:"Grok CLI",defaultCommand:["grok"],screenManifest:GROK},droid:{displayName:"Droid",defaultCommand:["droid"],screenManifest:DROID},amp:{displayName:"Amp",defaultCommand:["amp"],screenManifest:AMP},cline:{displayName:"Cline",defaultCommand:["cline"],screenManifest:CLINE},kiro:{displayName:"Kiro CLI",defaultCommand:["kiro-cli"],processNames:["kiro"],screenManifest:KIRO},maki:{displayName:"Maki",defaultCommand:["maki"],screenManifest:MAKI},antigravity:{displayName:"Antigravity",defaultCommand:["agy"],processNames:["antigravity","antigravity-cli"],screenManifest:ANTIGRAVITY}};function isContribEngine(id){return Object.hasOwn(CONTRIB_ENGINES,id)||pluginEngines.has(id)}var CONTRIB_ENGINE_IDS=Object.keys(CONTRIB_ENGINES);function contribEngineEntry(id,base){let spec=CONTRIB_ENGINES[id]??pluginEngines.get(id);if(!spec)return base;return{...base,displayName:spec.displayName,defaultCommand:spec.defaultCommand,...spec.processNames?{processNames:spec.processNames}:{},screenManifest:spec.screenManifest,...spec.identity?{identity:spec.identity}:{},...spec.firstMessageDelivery?{firstMessageDelivery:spec.firstMessageDelivery}:{},...spec.createHookAdapter?{createHookAdapter:spec.createHookAdapter}:{}}}import{homedir as homedir3}from"os";import{spawnSync}from"child_process";import{existsSync as existsSync2,statSync}from"fs";import{homedir as homedir2}from"os";var defaultBinaryDeps={fileExists(p){try{return statSync(p).isFile()}catch{return!1}},env(name){return process.env[name]},home(){return homedir2()},which(name){let cmd=process.platform==="win32"?"where":"which",out=spawnSync(cmd,[name],{encoding:"utf8"});if(out.status!==0)return;let first=out.stdout.split(`
4
4
  `).map((l)=>l.trim()).filter(Boolean)[0];if(!first)return;if(first.startsWith(`${name}:`)&&first.includes("aliased to")){let aliasTarget=first.split("aliased to")[1]?.trim();return aliasTarget&&existsSync2(aliasTarget)?aliasTarget:void 0}return first},readdir(p){try{return __require("fs").readdirSync(p)}catch{return[]}}};class BinaryNotFoundError extends Error{checkedPaths;constructor(label,hint,checkedPaths){super(`${label} not found. Checked: ${checkedPaths.join(", ")}. ${hint}`);this.name="BinaryNotFoundError",this.checkedPaths=checkedPaths}}function createBinaryFinder(spec){return async function(deps=defaultBinaryDeps){let checked=[],whichResult=deps.which(spec.name);if(whichResult){if(checked.push(`which:${whichResult}`),deps.fileExists(whichResult))return whichResult}for(let candidate of spec.candidates({deps,home:deps.home()}))if(checked.push(candidate),deps.fileExists(candidate))return candidate;throw spec.notFound(checked)}}import path from"path";class ClaudeBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Claude Code binary","Ensure 'claude' is on PATH, or install at ~/.claude/local/claude.",checkedPaths);this.name="ClaudeBinaryNotFoundError"}}var findClaudeBinary=createBinaryFinder({name:"claude",candidates({deps,home}){let out=[path.join(home,".claude","local","claude")],nvmBin=deps.env("NVM_BIN");if(nvmBin)out.push(path.join(nvmBin,"claude"));let nvmRoot=path.join(home,".nvm","versions","node"),versions=(deps.readdir?.(nvmRoot)??[]).sort((a,b)=>b.localeCompare(a,void 0,{numeric:!0}));for(let v of versions)out.push(path.join(nvmRoot,v,"bin","claude"));out.push("/opt/homebrew/bin/claude","/usr/local/bin/claude","/usr/bin/claude","/bin/claude");for(let rel of[".local/bin",".npm-global/bin",".yarn/bin",".bun/bin","bin"])out.push(path.join(home,rel,"claude"));return out},notFound:(checked)=>new ClaudeBinaryNotFoundError(checked)});import path2 from"path";class CodexBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Codex CLI binary","Ensure 'codex' is on PATH (e.g. `brew install codex` or the official installer).",checkedPaths);this.name="CodexBinaryNotFoundError"}}var findCodexBinary=createBinaryFinder({name:"codex",candidates({deps,home}){let out=["/opt/homebrew/bin/codex","/usr/local/bin/codex","/usr/bin/codex","/bin/codex"],nvmBin=deps.env("NVM_BIN");if(nvmBin)out.push(path2.join(nvmBin,"codex"));for(let rel of[".local/bin",".bun/bin","bin"])out.push(path2.join(home,rel,"codex"));return out},notFound:(checked)=>new CodexBinaryNotFoundError(checked)});import path3 from"path";class CopilotBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("GitHub Copilot CLI binary","Ensure 'copilot' is on PATH (for example `npm install -g @github/copilot` or `brew install copilot-cli`).",checkedPaths);this.name="CopilotBinaryNotFoundError"}}var findCopilotBinary=createBinaryFinder({name:"copilot",candidates({deps,home}){let win32=(deps.platform?.()??process.platform)==="win32",names=win32?["copilot.exe","copilot.cmd","copilot"]:["copilot"],dirs=["/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"],nvmBin=deps.env("NVM_BIN");if(nvmBin)dirs.push(nvmBin);let homeDirs=[path3.join(home,".npm-global/bin"),path3.join(home,".local/bin"),path3.join(home,".bun/bin"),path3.join(home,"bin")];if(win32){let appData=deps.env("APPDATA"),localAppData=deps.env("LOCALAPPDATA");if(homeDirs.unshift(path3.join(home,"AppData/Roaming/npm")),appData)homeDirs.unshift(path3.join(appData,"npm"));if(localAppData)homeDirs.unshift(path3.join(localAppData,"npm"))}return[...dirs,...homeDirs].flatMap((dir)=>names.map((name)=>path3.join(dir,name)))},notFound:(checked)=>new CopilotBinaryNotFoundError(checked)});import path4 from"path";class KimiBinaryNotFoundError extends BinaryNotFoundError{constructor(checkedPaths){super("Kimi Code CLI binary","Ensure 'kimi' is on PATH or installed at ~/.kimi-code/bin/kimi.",checkedPaths);this.name="KimiBinaryNotFoundError"}}var findKimiBinary=createBinaryFinder({name:"kimi",candidates:({home})=>[path4.join(home,".kimi-code/bin"),path4.join(home,".local/bin"),path4.join(home,"bin"),"/opt/homebrew/bin","/usr/local/bin"].map((dir)=>path4.join(dir,"kimi")),notFound:(checked)=>new KimiBinaryNotFoundError(checked)});import path5 from"path";class PiFamilyBinaryNotFoundError extends BinaryNotFoundError{constructor(name,checkedPaths){super(`${name} CLI binary`,`Ensure '${name}' is on PATH (e.g. \`brew install ${name}\`, or \`npm i -g ${name==="omp"?"@oh-my-pi/pi-coding-agent":"@earendil-works/pi-coding-agent"}\`).`,checkedPaths);this.name="PiFamilyBinaryNotFoundError"}}function candidatesFor(name,home){let out=[...["/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"],path5.join(home,".local/bin"),path5.join(home,".bun/bin"),path5.join(home,"bin")].map((dir)=>path5.join(dir,name)),packageName=name==="omp"?"@oh-my-pi/pi-coding-agent":"@earendil-works/pi-coding-agent";for(let prefix of[path5.join(home,".npm-global"),"/usr/local","/opt/homebrew"])out.push(path5.join(prefix,"bin",name)),out.push(path5.join(prefix,"lib/node_modules",packageName,"dist","cli.js"));return out}var findPiBinary=createBinaryFinder({name:"pi",candidates:({home})=>candidatesFor("pi",home),notFound:(checked)=>new PiFamilyBinaryNotFoundError("pi",checked)}),findOmpBinary=createBinaryFinder({name:"omp",candidates:({home})=>candidatesFor("omp",home),notFound:(checked)=>new PiFamilyBinaryNotFoundError("omp",checked)});var defaultDeps={readFile(p){return readTextFileSyncBounded(p)},env(name){return process.env[name]},home(){return homedir3()},findClaudeBinary(){return findClaudeBinary()},findCodexBinary(){return findCodexBinary()},findCopilotBinary(){return findCopilotBinary()},findKimiBinary(){return findKimiBinary()},findPiBinary(){return findPiBinary()},findOmpBinary(){return findOmpBinary()}};function decodeJwtPayload(jwt){let parts=jwt.split(".");if(parts.length!==3)return null;let payload=parts[1];if(!payload)return null;let b64=payload.replace(/-/g,"+").replace(/_/g,"/"),padded=b64+"=".repeat((4-b64.length%4)%4);try{let json=Buffer.from(padded,"base64").toString("utf8"),obj=JSON.parse(json);return typeof obj==="object"&&obj!==null?obj:null}catch{return null}}async function probeBinary(probe){try{return{found:!0,path:await probe()}}catch(err){if(err instanceof BinaryNotFoundError)return{found:!1,error:"not found on PATH"};return{found:!1,error:errorMessage(err)}}}var cachedDefaultVendors=null;async function probeAvailableVendors(deps){return(await Promise.all([["claude",()=>deps.findClaudeBinary()],["codex",()=>deps.findCodexBinary()],["copilot",()=>deps.findCopilotBinary()],["kimi",()=>deps.findKimiBinary()],["pi",()=>deps.findPiBinary()],["omp",()=>deps.findOmpBinary()]].map(async([vendor,probe])=>(await probeBinary(probe)).found?vendor:null))).filter((v)=>v!==null)}function detectAvailableVendors(deps=defaultDeps){if(deps!==defaultDeps)return probeAvailableVendors(deps);if(cachedDefaultVendors)return cachedDefaultVendors;let pending=probeAvailableVendors(deps).catch((err)=>{throw cachedDefaultVendors=null,err});return cachedDefaultVendors=pending,pending}function resetAvailableVendorsCache(){cachedDefaultVendors=null,cachedContribEngines=null}async function installedEngineIds(deps=defaultDeps){let builtins=await detectAvailableVendors(deps),contrib=await detectContribEngines();return[...new Set([...builtins,...getCustomEngineIds(),...contrib])]}async function availableEngineIds(deps=defaultDeps){let disabled=new Set(getDisabledEngineIds());return(await installedEngineIds(deps)).filter((id)=>!disabled.has(id))}var cachedContribEngines=null;function detectContribEngines(){if(cachedContribEngines)return cachedContribEngines;let which=globalThis.Bun?.which;return cachedContribEngines=Promise.resolve([...which?CONTRIB_ENGINE_IDS.filter((id)=>{let bin=CONTRIB_ENGINES[id]?.defaultCommand[0];return bin?which(bin)!==null:!1}):[],...pluginEngineIds()]),cachedContribEngines}async function detectClaudeAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findClaudeBinary()),configPath=claudeGlobalConfigPath(deps.env,deps.home()),raw;try{raw=deps.readFile(configPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${configPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${configPath}: ${errorMessage(err)}`}}let oauth=parsed?.oauthAccount;if(!oauth||typeof oauth!=="object")return{binary,account:{kind:"none"}};let o=oauth,email=typeof o.emailAddress==="string"?o.emailAddress:void 0;if(!email)return{binary,account:{kind:"none"}};return{binary,account:{kind:"oauth",email,organization:typeof o.organizationName==="string"?o.organizationName:void 0,displayName:typeof o.displayName==="string"?o.displayName:void 0,billingType:typeof o.billingType==="string"?o.billingType:void 0}}}async function detectCodexAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findCodexBinary()),authPath=codexAuthPath(deps.env,deps.home()),raw;try{raw=deps.readFile(authPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${authPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${authPath}: ${errorMessage(err)}`}}let obj=parsed??{},tokens=obj.tokens,idToken=typeof tokens?.id_token==="string"?tokens.id_token:void 0;if(idToken){let payload=decodeJwtPayload(idToken);if(!payload)return{binary,account:{kind:"none"},accountError:"codex id_token: malformed JWT"};let email=typeof payload.email==="string"?payload.email:void 0,authClaimRaw=payload["https://api.openai.com/auth"],authClaim=typeof authClaimRaw==="object"&&authClaimRaw!==null&&!Array.isArray(authClaimRaw)?authClaimRaw:void 0,plan=typeof authClaim?.chatgpt_plan_type==="string"?authClaim.chatgpt_plan_type:void 0;if(email)return{binary,account:{kind:"chatgpt",email,plan}};return{binary,account:{kind:"none"},accountError:"codex id_token: no email claim"}}let apiKey=obj.OPENAI_API_KEY;if(typeof apiKey==="string"&&apiKey.length>0)return{binary,account:{kind:"apikey"}};return{binary,account:{kind:"none"}}}async function detectCopilotAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findCopilotBinary());for(let source of["COPILOT_GITHUB_TOKEN","GH_TOKEN","GITHUB_TOKEN"])if(deps.env(source)?.trim())return{binary,account:{kind:"token",source}};let configPath=copilotConfigPath(deps.env,deps.home()),raw;try{raw=deps.readFile(configPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${configPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${configPath}: ${errorMessage(err)}`}}if(!isRecord(parsed))return{binary,account:{kind:"none"}};if(hasStringDeep(parsed,["github_token","oauth_token","access_token","token","selectedUser","currentUser","user"]))return{binary,account:{kind:"oauth"}};return{binary,account:{kind:"none"}}}async function detectKimiAccount(deps=defaultDeps){let binary=await probeBinary(()=>deps.findKimiBinary()),credPath=kimiCredentialsPath(deps.env,deps.home()),raw;try{raw=deps.readFile(credPath)}catch(err){return{binary,account:{kind:"none"},accountError:`read ${credPath}: ${errorMessage(err)}`}}if(raw===null)return{binary,account:{kind:"none"}};let parsed;try{parsed=JSON.parse(raw)}catch(err){return{binary,account:{kind:"none"},accountError:`parse ${credPath}: ${errorMessage(err)}`}}if(!isRecord(parsed))return{binary,account:{kind:"none"}};let token=parsed.access_token;if(typeof token==="string"&&token.length>0)return{binary,account:{kind:"oauth"}};return{binary,account:{kind:"none"}}}function isRecord(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function hasStringDeep(value,interestingKeys,depth=0){if(depth>4||!isRecord(value))return!1;for(let[key,entry]of Object.entries(value)){if(interestingKeys.includes(key)&&typeof entry==="string"&&entry.length>0)return!0;if(isRecord(entry)&&hasStringDeep(entry,interestingKeys,depth+1))return!0}return!1}
5
5
  export{registerPluginEngine,clearPluginEngines,pluginEngineIds,isContribEngine,CONTRIB_ENGINE_IDS,contribEngineEntry,resetAvailableVendorsCache,installedEngineIds,availableEngineIds,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectKimiAccount};
@@ -4,4 +4,4 @@ import{expandTilde}from"./chunk-fczqwtmq.js";import{SUBCOMMAND_VERBS}from"./chun
4
4
 
5
5
  ${REPO_USAGE}
6
6
  `),process.exit(2)}function readArgFile(path){try{return readFileSync(resolve(process.cwd(),expandTilde(path)),"utf8")}catch(err){usageError(`cannot read ${path}: ${errorMessage(err)}`)}}function parseRepoArgs(args){let out={};for(let i=0;i<args.length;i++){let a=args[i],need=()=>{let v=args[++i];if(v===void 0)usageError(`${a} requires a value`);return v};if(a==="--init-script")out.initScript=need();else if(a==="--init-script-file")out.initScript=readArgFile(need());else if(a==="--init-prompt")out.initPrompt=need();else if(a==="--init-prompt-file")out.initPrompt=readArgFile(need());else if(a.startsWith("-"))usageError(`unknown flag "${a}"`);else if(out.path===void 0)out.path=a;else usageError(`unexpected argument "${a}"`)}return out}function parseUnsetArgs(args){let path,clearScript=!1,clearPrompt=!1;for(let a of args)if(a==="--init-script")clearScript=!0;else if(a==="--init-prompt")clearPrompt=!0;else if(a.startsWith("-"))usageError(`unknown flag "${a}"`);else if(path===void 0)path=a;else usageError(`unexpected argument "${a}"`);if(!clearScript&&!clearPrompt)clearScript=!0,clearPrompt=!0;return{path,clearScript,clearPrompt}}async function runRepoSubcommand(args){let[verb,...rest]=args;if(verb===void 0||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${REPO_USAGE}
7
- `);return}if(!SUBCOMMAND_VERBS.repo.includes(verb))usageError(`unknown verb "${verb}"`);let{getRepoInitOverride,setRepoInitOverride,resolveRepoRoot}=await import("./chunk-4er2k3kp.js");if(verb==="show"){let[pathArg]=rest.filter((a)=>!a.startsWith("-")),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(pathArg??"."))),override=getRepoInitOverride(repo),{describeRepoInitSources}=await import("./chunk-6ebzs5pv.js"),sources=describeRepoInitSources(repo);console.log(`repo: ${repo}`);for(let group of[sources.script,sources.prompt])group.forEach((source,index)=>{console.log(` ${`${source.rel}:`.padEnd(22)}${describeSource(group,index)}`)});console.log(` override initScript: ${override.initScript?quotePreview(override.initScript):"(unset)"}`),console.log(` override initPrompt: ${override.initPrompt?quotePreview(override.initPrompt):"(unset)"}`);return}if(verb==="set"){let flags=parseRepoArgs(rest);if(flags.initScript===void 0&&flags.initPrompt===void 0)usageError("set needs at least one of --init-script(-file) / --init-prompt(-file)");let repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(flags.path??"."))),next=setRepoInitOverride(repo,{...flags.initScript!==void 0?{initScript:flags.initScript}:{},...flags.initPrompt!==void 0?{initPrompt:flags.initPrompt}:{}});console.log(`updated override for ${repo}`),console.log(` initScript: ${next.initScript?quotePreview(next.initScript):"(unset)"}`),console.log(` initPrompt: ${next.initPrompt?quotePreview(next.initPrompt):"(unset)"}`);return}if(verb==="unset"){let{path,clearScript,clearPrompt}=parseUnsetArgs(rest),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(path??"."))),next=setRepoInitOverride(repo,{...clearScript?{initScript:""}:{},...clearPrompt?{initPrompt:""}:{}});console.log(`cleared override for ${repo}`),console.log(` initScript: ${next.initScript?quotePreview(next.initScript):"(unset)"}`),console.log(` initPrompt: ${next.initPrompt?quotePreview(next.initPrompt):"(unset)"}`);return}usageError(`unknown verb "${verb}"`)}function describeSource(group,index){let source=group[index];if(!source)return"absent";if(source.effective)return"present (wins)";if(!source.present)return"absent";return group.slice(0,index).some((earlier)=>earlier.effective)?"present (shadowed)":"present but empty (ignored)"}function quotePreview(value){let oneLine=value.replace(/\s+/g," ").trim();return oneLine.length>60?`"${oneLine.slice(0,57)}\u2026"`:`"${oneLine}"`}export{runRepoSubcommand};
7
+ `);return}if(!SUBCOMMAND_VERBS.repo.includes(verb))usageError(`unknown verb "${verb}"`);let{getRepoInitOverride,setRepoInitOverride,resolveRepoRoot}=await import("./chunk-4er2k3kp.js");if(verb==="show"){let[pathArg]=rest.filter((a)=>!a.startsWith("-")),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(pathArg??"."))),override=getRepoInitOverride(repo),{describeRepoInitSources}=await import("./chunk-qtwbzz0t.js"),sources=describeRepoInitSources(repo);console.log(`repo: ${repo}`);for(let group of[sources.script,sources.prompt])group.forEach((source,index)=>{console.log(` ${`${source.rel}:`.padEnd(22)}${describeSource(group,index)}`)});console.log(` override initScript: ${override.initScript?quotePreview(override.initScript):"(unset)"}`),console.log(` override initPrompt: ${override.initPrompt?quotePreview(override.initPrompt):"(unset)"}`);return}if(verb==="set"){let flags=parseRepoArgs(rest);if(flags.initScript===void 0&&flags.initPrompt===void 0)usageError("set needs at least one of --init-script(-file) / --init-prompt(-file)");let repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(flags.path??"."))),next=setRepoInitOverride(repo,{...flags.initScript!==void 0?{initScript:flags.initScript}:{},...flags.initPrompt!==void 0?{initPrompt:flags.initPrompt}:{}});console.log(`updated override for ${repo}`),console.log(` initScript: ${next.initScript?quotePreview(next.initScript):"(unset)"}`),console.log(` initPrompt: ${next.initPrompt?quotePreview(next.initPrompt):"(unset)"}`);return}if(verb==="unset"){let{path,clearScript,clearPrompt}=parseUnsetArgs(rest),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(path??"."))),next=setRepoInitOverride(repo,{...clearScript?{initScript:""}:{},...clearPrompt?{initPrompt:""}:{}});console.log(`cleared override for ${repo}`),console.log(` initScript: ${next.initScript?quotePreview(next.initScript):"(unset)"}`),console.log(` initPrompt: ${next.initPrompt?quotePreview(next.initPrompt):"(unset)"}`);return}usageError(`unknown verb "${verb}"`)}function describeSource(group,index){let source=group[index];if(!source)return"absent";if(source.effective)return"present (wins)";if(!source.present)return"absent";return group.slice(0,index).some((earlier)=>earlier.effective)?"present (shadowed)":"present but empty (ignored)"}function quotePreview(value){let oneLine=value.replace(/\s+/g," ").trim();return oneLine.length>60?`"${oneLine.slice(0,57)}\u2026"`:`"${oneLine}"`}export{runRepoSubcommand};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{ensureGlobalKobeHooks,readStdinText,readTextWithTimeout,runHookSubcommand}from"./chunk-ekmwvws5.js";import"./chunk-17e2tgyg.js";import"./chunk-r2pztgm6.js";import"./chunk-1p5334mv.js";import"./chunk-yv44tdjq.js";import"./chunk-c42pwcvw.js";import"./chunk-mjdt28x6.js";import"./chunk-p1zab1sy.js";import"./chunk-hqbmzz4t.js";import"./chunk-4m57n1t2.js";import"./chunk-j38kagw2.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-cdy4v61w.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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";export{runHookSubcommand,readTextWithTimeout,readStdinText,ensureGlobalKobeHooks};
2
+ import{ensureGlobalKobeHooks,readStdinText,readTextWithTimeout,runHookSubcommand}from"./chunk-pwp22zq3.js";import"./chunk-17e2tgyg.js";import"./chunk-r2pztgm6.js";import"./chunk-zd46ghvd.js";import"./chunk-yv44tdjq.js";import"./chunk-c42pwcvw.js";import"./chunk-mjdt28x6.js";import"./chunk-p1zab1sy.js";import"./chunk-hqbmzz4t.js";import"./chunk-9wg9snjs.js";import"./chunk-kx5gzpmt.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-cdy4v61w.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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";export{runHookSubcommand,readTextWithTimeout,readStdinText,ensureGlobalKobeHooks};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{ensurePluginEnginesLoaded,loadPluginEngines,registeredEngineIds,reloadPluginEngines}from"./chunk-3cx92j5n.js";import"./chunk-1p5334mv.js";import"./chunk-hqbmzz4t.js";import"./chunk-j38kagw2.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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";export{reloadPluginEngines,registeredEngineIds,loadPluginEngines,ensurePluginEnginesLoaded};
2
+ import{ensurePluginEnginesLoaded,loadPluginEngines,registeredEngineIds,reloadPluginEngines}from"./chunk-38n756dh.js";import"./chunk-zd46ghvd.js";import"./chunk-hqbmzz4t.js";import"./chunk-kx5gzpmt.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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";export{reloadPluginEngines,registeredEngineIds,loadPluginEngines,ensurePluginEnginesLoaded};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{protocolEntry}from"./chunk-g2wk0es7.js";import{getPersistedString}from"./chunk-crt11rmj.js";var AUTO_EFFORT_TIERS=["swift","standard","deep"];function isAutoEffortTier(value){return AUTO_EFFORT_TIERS.includes(value??"")}var DEFAULT_AUTO_EFFORT={swift:{engine:"claude",model:"sonnet"},standard:{engine:"claude",model:"opus"},deep:{engine:"claude",model:"fable"}};function autoEffortKey(tier,field){return`autoEffort.${tier}.${field}`}function stringAt(get,key){let raw=get(key);return typeof raw==="string"?raw:void 0}function readAutoEffortTable(get=getPersistedString){let table={};for(let tier of AUTO_EFFORT_TIERS){let base=DEFAULT_AUTO_EFFORT[tier],engine=stringAt(get,autoEffortKey(tier,"engine"));if(engine!==void 0&&!engine.trim())return null;let model=stringAt(get,autoEffortKey(tier,"model")),effort=stringAt(get,autoEffortKey(tier,"effort")),resolvedModel=model===void 0?base.model:model.trim()||void 0,resolvedEffort=effort===void 0?base.effort:effort.trim()||void 0;table[tier]={engine:engine?.trim()||base.engine,...resolvedModel?{model:resolvedModel}:{},...resolvedEffort?{effort:resolvedEffort}:{}}}return table}function tierBlock(target,deps){let{engine}=target;if(!deps.engineIds.has(engine))return{kind:"engine",engine};if(deps.accountKind(engine)==="none")return{kind:"account",engine};let entry=protocolEntry(engine);if(target.model&&!entry.modelArgv)return{kind:"model",engine,model:target.model};if(target.effort){let levels=entry.effortLevels??[];if(!levels.includes(target.effort))return{kind:"effort",engine,effort:target.effort,levels}}return null}function describeTierBlock(block){switch(block.kind){case"engine":return`engine ${block.engine} is not one engine-list names`;case"account":return`engine ${block.engine} is not logged in`;case"model":return`engine ${block.engine} declares no model flag, so model ${JSON.stringify(block.model)} cannot be passed`;case"effort":return block.levels.length===0?`engine ${block.engine} declares no reasoning effort levels`:`engine ${block.engine} does not accept effort ${JSON.stringify(block.effort)} \u2014 it declares ${block.levels.join(", ")}`}}var TASK_GROUPS=["waiting-on-you","landing","ready-for-review","working","idle","unknown"];function taskGroupRank(group){return TASK_GROUPS.indexOf(group)}var ERROR_SETTLE_MS=20000,DEAD_SETTLE_MS=60000;function actedOn(task){if(task.status==="done"||task.status==="canceled")return!0;let lifecycle=task.prStatus?.lifecycle;return lifecycle==="merged"||lifecycle==="closed"}function autoResumes(task,now){let at=task.quotaResume?.resumeAt;if(!at)return!1;let ms=Date.parse(at);return!Number.isNaN(ms)&&ms>now}function deriveTaskGroup(input){let{task,now}=input,activity=input.activity??null,state=activity?.state,age=activity?Math.max(0,now-activity.at):0;if(task.deletion?.phase==="error")return"waiting-on-you";if(state==="permission_needed")return"waiting-on-you";if(state==="rate_limited"&&!autoResumes(task,now))return"waiting-on-you";if(state==="error"&&age>=ERROR_SETTLE_MS)return"waiting-on-you";if(activity&&!task.report&&age>=DEAD_SETTLE_MS&&(state==="dead"||input.tabAlive===!1))return"waiting-on-you";if(state==="running"&&input.tabAlive!==!1)return"working";if(state==="rate_limited")return"working";let pr=task.prStatus;if((pr?.lifecycle==="open"||pr?.lifecycle==="ready_to_merge")&&(pr.reviewDecision??"").toUpperCase()==="APPROVED")return"landing";if((task.report!==void 0||state==="turn_complete")&&!actedOn(task))return"ready-for-review";return activity?"idle":"unknown"}function taskGroupOf(input){let group=deriveTaskGroup(input);return{group,rank:taskGroupRank(group)}}
2
+ import{protocolEntry}from"./chunk-arj1d3vp.js";import{getPersistedString}from"./chunk-crt11rmj.js";var AUTO_EFFORT_TIERS=["swift","standard","deep"];function isAutoEffortTier(value){return AUTO_EFFORT_TIERS.includes(value??"")}var DEFAULT_AUTO_EFFORT={swift:{engine:"claude",model:"sonnet"},standard:{engine:"claude",model:"opus"},deep:{engine:"claude",model:"fable"}};function autoEffortKey(tier,field){return`autoEffort.${tier}.${field}`}function stringAt(get,key){let raw=get(key);return typeof raw==="string"?raw:void 0}function readAutoEffortTable(get=getPersistedString){let table={};for(let tier of AUTO_EFFORT_TIERS){let base=DEFAULT_AUTO_EFFORT[tier],engine=stringAt(get,autoEffortKey(tier,"engine"));if(engine!==void 0&&!engine.trim())return null;let model=stringAt(get,autoEffortKey(tier,"model")),effort=stringAt(get,autoEffortKey(tier,"effort")),resolvedModel=model===void 0?base.model:model.trim()||void 0,resolvedEffort=effort===void 0?base.effort:effort.trim()||void 0;table[tier]={engine:engine?.trim()||base.engine,...resolvedModel?{model:resolvedModel}:{},...resolvedEffort?{effort:resolvedEffort}:{}}}return table}function tierBlock(target,deps){let{engine}=target;if(!deps.engineIds.has(engine))return{kind:"engine",engine};if(deps.accountKind(engine)==="none")return{kind:"account",engine};let entry=protocolEntry(engine);if(target.model&&!entry.modelArgv)return{kind:"model",engine,model:target.model};if(target.effort){let levels=entry.effortLevels??[];if(!levels.includes(target.effort))return{kind:"effort",engine,effort:target.effort,levels}}return null}function describeTierBlock(block){switch(block.kind){case"engine":return`engine ${block.engine} is not one engine-list names`;case"account":return`engine ${block.engine} is not logged in`;case"model":return`engine ${block.engine} declares no model flag, so model ${JSON.stringify(block.model)} cannot be passed`;case"effort":return block.levels.length===0?`engine ${block.engine} declares no reasoning effort levels`:`engine ${block.engine} does not accept effort ${JSON.stringify(block.effort)} \u2014 it declares ${block.levels.join(", ")}`}}var TASK_GROUPS=["waiting-on-you","landing","ready-for-review","working","idle","unknown"];function taskGroupRank(group){return TASK_GROUPS.indexOf(group)}var ERROR_SETTLE_MS=20000,DEAD_SETTLE_MS=60000;function actedOn(task){if(task.status==="done"||task.status==="canceled")return!0;let lifecycle=task.prStatus?.lifecycle;return lifecycle==="merged"||lifecycle==="closed"}function autoResumes(task,now){let at=task.quotaResume?.resumeAt;if(!at)return!1;let ms=Date.parse(at);return!Number.isNaN(ms)&&ms>now}function deriveTaskGroup(input){let{task,now}=input,activity=input.activity??null,state=activity?.state,age=activity?Math.max(0,now-activity.at):0;if(task.deletion?.phase==="error")return"waiting-on-you";if(state==="permission_needed")return"waiting-on-you";if(state==="rate_limited"&&!autoResumes(task,now))return"waiting-on-you";if(state==="error"&&age>=ERROR_SETTLE_MS)return"waiting-on-you";if(activity&&!task.report&&age>=DEAD_SETTLE_MS&&(state==="dead"||input.tabAlive===!1))return"waiting-on-you";if(state==="running"&&input.tabAlive!==!1)return"working";if(state==="rate_limited")return"working";let pr=task.prStatus;if((pr?.lifecycle==="open"||pr?.lifecycle==="ready_to_merge")&&(pr.reviewDecision??"").toUpperCase()==="APPROVED")return"landing";if((task.report!==void 0||state==="turn_complete")&&!actedOn(task))return"ready-for-review";return activity?"idle":"unknown"}function taskGroupOf(input){let group=deriveTaskGroup(input);return{group,rank:taskGroupRank(group)}}
3
3
  export{AUTO_EFFORT_TIERS,isAutoEffortTier,autoEffortKey,readAutoEffortTable,tierBlock,describeTierBlock,taskGroupRank,deriveTaskGroup,taskGroupOf};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{activityHookAdapters}from"./chunk-4m57n1t2.js";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let adapter of activityHookAdapters()){if(!adapter.hookConfigRefusal)continue;let file=adapter.globalSettingsPath();if(!file)continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let reason=adapter.hookConfigRefusal(raw);if(reason)issues.push({file,reason})}return issues}function formatBytes(n){if(n<1024)return`${n} B`;let units=["KB","MB","GB","TB"],v=n/1024,i=0;while(v>=1023.5&&i<units.length-1)v/=1024,i++;let oneDecimal=v.toFixed(1);return`${Number(oneDecimal)>=100?Math.round(v):oneDecimal} ${units[i]}`}
2
+ import{activityHookAdapters}from"./chunk-9wg9snjs.js";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let adapter of activityHookAdapters()){if(!adapter.hookConfigRefusal)continue;let file=adapter.globalSettingsPath();if(!file)continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let reason=adapter.hookConfigRefusal(raw);if(reason)issues.push({file,reason})}return issues}function formatBytes(n){if(n<1024)return`${n} B`;let units=["KB","MB","GB","TB"],v=n/1024,i=0;while(v>=1023.5&&i<units.length-1)v/=1024,i++;let oneDecimal=v.toFixed(1);return`${Number(oneDecimal)>=100?Math.round(v):oneDecimal} ${units[i]}`}
3
3
  export{hookConfigIssues,formatBytes};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{isEngineActivityKind}from"./chunk-17e2tgyg.js";import{loadPluginRegistry,readPluginManifest}from"./chunk-1p5334mv.js";import{connectIfRunning}from"./chunk-yv44tdjq.js";import{activityHookAdapters}from"./chunk-4m57n1t2.js";import{flagValue}from"./chunk-jvxh93nz.js";import{getPersistedString,setPersistedString}from"./chunk-crt11rmj.js";import{activeCliName}from"./chunk-00ehck55.js";import{readRoveEnv}from"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{join,resolve}from"path";var STDIN_READ_TIMEOUT_MS=500;async function readTextWithTimeout(read,timeoutMs=STDIN_READ_TIMEOUT_MS){let raceTimer;try{return await Promise.race([read(),new Promise((resolve2)=>{raceTimer=setTimeout(()=>resolve2(""),timeoutMs)})])}finally{if(raceTimer!==void 0)clearTimeout(raceTimer)}}async function readStdinText(){let bun=globalThis.Bun;if(bun)return bun.stdin.text();if(process.stdin.isTTY)return"";let chunks=[];try{for await(let chunk of process.stdin)chunks.push(chunk)}finally{process.stdin.destroy()}return Buffer.concat(chunks).toString("utf8")}async function readStdinPayload(){try{let text=await readTextWithTimeout(readStdinText);if(!text.trim())return{};let parsed=JSON.parse(text);return parsed&&typeof parsed==="object"&&!Array.isArray(parsed)?parsed:{}}catch{return{}}}async function runHookSubcommand(argv){let[verb,...rest]=argv;if(verb==="setup"){await runHookSetup(rest);return}if(verb==="cleanup"){await runHookCleanup();return}try{if(!verb||!isEngineActivityKind(verb))return;let payload=await readStdinPayload(),payloadFlag=flagValue(rest,"--payload");if(payloadFlag)try{let extra=JSON.parse(payloadFlag);if(extra&&typeof extra==="object"&&!Array.isArray(extra))Object.assign(payload,extra)}catch{}let taskId=flagValue(rest,"--task-id"),envTaskId=process.env.KOBE_TASK_ID,envTabId=process.env.KOBE_TAB_ID,engine=flagValue(rest,"--engine"),adapters=activityHookAdapters().filter((a)=>!engine||a.vendor===engine);if(!taskId&&adapters.some((a)=>a.isUnattendedSession?.(process.env)===!0))return;let cwd=typeof payload.cwd==="string"&&payload.cwd?payload.cwd:void 0;for(let adapter of adapters){if(cwd)break;cwd=adapter.cwdFromPayload?.(payload)}cwd||=process.cwd();let detail;for(let adapter of adapters)if(detail=adapter.activityDetailFromPayload(verb,payload),detail)break;let session;for(let adapter of adapters)if(session=adapter.sessionFromPayload(payload),session)break;let client=await connectIfRunning();if(!client)return;try{let effectiveTaskId=taskId??envTaskId;await client.request("engine.reportEvent",{...effectiveTaskId?{taskId:effectiveTaskId}:{cwd},kind:verb,...engine?{engine}:{},...envTabId?{tabId:envTabId}:{},...detail?{detail}:{},...session?{sessionId:session.sessionId}:{},...session?.transcriptPath?{transcriptPath:session.transcriptPath}:{}})}finally{client.close()}}catch(err){if(readRoveEnv("HOOK_DEBUG"))console.error(`[rove hook] ${verb} failed:`,err instanceof Error?err.message:String(err))}}var SYNC_SETTING_KEY="externalWorktreeSync";function worktreeSyncAdapters(){return activityHookAdapters().filter((a)=>a.supportsWorktreeSync())}function globalSettingsPath(){return worktreeSyncAdapters()[0]?.globalSettingsPath()}function persistedSyncPath(stored){if(!stored||stored==="off")return;if(stored==="global")return globalSettingsPath();if(stored.startsWith("repo:"))return join(resolve(stored.slice(5)),".claude","settings.json");return stored}async function ensureGlobalKobeHooks(opts={}){try{let{isRovePluginEnabled,detectLegacyInstalls,migrationHint}=await import("./chunk-xf09hgzv.js"),pluginMode=isRovePluginEnabled();if(pluginMode){let hint=migrationHint(detectLegacyInstalls(),activeCliName());if(hint)process.stderr.write(`
2
+ import{isEngineActivityKind}from"./chunk-17e2tgyg.js";import{loadPluginRegistry,readPluginManifest}from"./chunk-zd46ghvd.js";import{connectIfRunning}from"./chunk-yv44tdjq.js";import{activityHookAdapters}from"./chunk-9wg9snjs.js";import{flagValue}from"./chunk-jvxh93nz.js";import{getPersistedString,setPersistedString}from"./chunk-crt11rmj.js";import{activeCliName}from"./chunk-00ehck55.js";import{readRoveEnv}from"./chunk-hq4b3fca.js";import{__require}from"./chunk-wqfp8d9w.js";import{join,resolve}from"path";var STDIN_READ_TIMEOUT_MS=500;async function readTextWithTimeout(read,timeoutMs=STDIN_READ_TIMEOUT_MS){let raceTimer;try{return await Promise.race([read(),new Promise((resolve2)=>{raceTimer=setTimeout(()=>resolve2(""),timeoutMs)})])}finally{if(raceTimer!==void 0)clearTimeout(raceTimer)}}async function readStdinText(){let bun=globalThis.Bun;if(bun)return bun.stdin.text();if(process.stdin.isTTY)return"";let chunks=[];try{for await(let chunk of process.stdin)chunks.push(chunk)}finally{process.stdin.destroy()}return Buffer.concat(chunks).toString("utf8")}async function readStdinPayload(){try{let text=await readTextWithTimeout(readStdinText);if(!text.trim())return{};let parsed=JSON.parse(text);return parsed&&typeof parsed==="object"&&!Array.isArray(parsed)?parsed:{}}catch{return{}}}async function runHookSubcommand(argv){let[verb,...rest]=argv;if(verb==="setup"){await runHookSetup(rest);return}if(verb==="cleanup"){await runHookCleanup();return}try{if(!verb||!isEngineActivityKind(verb))return;let payload=await readStdinPayload(),payloadFlag=flagValue(rest,"--payload");if(payloadFlag)try{let extra=JSON.parse(payloadFlag);if(extra&&typeof extra==="object"&&!Array.isArray(extra))Object.assign(payload,extra)}catch{}let taskId=flagValue(rest,"--task-id"),envTaskId=process.env.KOBE_TASK_ID,envTabId=process.env.KOBE_TAB_ID,engine=flagValue(rest,"--engine"),adapters=activityHookAdapters().filter((a)=>!engine||a.vendor===engine);if(!taskId&&adapters.some((a)=>a.isUnattendedSession?.(process.env)===!0))return;let cwd=typeof payload.cwd==="string"&&payload.cwd?payload.cwd:void 0;for(let adapter of adapters){if(cwd)break;cwd=adapter.cwdFromPayload?.(payload)}cwd||=process.cwd();let detail;for(let adapter of adapters)if(detail=adapter.activityDetailFromPayload(verb,payload),detail)break;let session;for(let adapter of adapters)if(session=adapter.sessionFromPayload(payload),session)break;let client=await connectIfRunning();if(!client)return;try{let effectiveTaskId=taskId??envTaskId;await client.request("engine.reportEvent",{...effectiveTaskId?{taskId:effectiveTaskId}:{cwd},kind:verb,...engine?{engine}:{},...envTabId?{tabId:envTabId}:{},...detail?{detail}:{},...session?{sessionId:session.sessionId}:{},...session?.transcriptPath?{transcriptPath:session.transcriptPath}:{}})}finally{client.close()}}catch(err){if(readRoveEnv("HOOK_DEBUG"))console.error(`[rove hook] ${verb} failed:`,err instanceof Error?err.message:String(err))}}var SYNC_SETTING_KEY="externalWorktreeSync";function worktreeSyncAdapters(){return activityHookAdapters().filter((a)=>a.supportsWorktreeSync())}function globalSettingsPath(){return worktreeSyncAdapters()[0]?.globalSettingsPath()}function persistedSyncPath(stored){if(!stored||stored==="off")return;if(stored==="global")return globalSettingsPath();if(stored.startsWith("repo:"))return join(resolve(stored.slice(5)),".claude","settings.json");return stored}async function ensureGlobalKobeHooks(opts={}){try{let{isRovePluginEnabled,detectLegacyInstalls,migrationHint}=await import("./chunk-xf09hgzv.js"),pluginMode=isRovePluginEnabled();if(pluginMode){let hint=migrationHint(detectLegacyInstalls(),activeCliName());if(hint)process.stderr.write(`
3
3
  ${hint}
4
4
  `)}let toolEvents=pluginsWantToolEvents();for(let a of activityHookAdapters()){if(pluginMode&&a.vendor==="claude")continue;let enginePath=a.globalSettingsPath();if(!enginePath)continue;await a.installActivityHooks(enginePath,{toolEvents,quiet:opts.quiet}),await a.removeWorktreeWatchHook(enginePath)}await cleanupWorktreeSyncHook()}catch{}}function pluginsWantToolEvents(){try{for(let entry of loadPluginRegistry().plugins){if(!entry.enabled)continue;try{if(readPluginManifest(entry.root).manifest.events.some((e)=>e.on.startsWith("tool.")))return!0}catch{}}}catch{}return!1}async function cleanupWorktreeSyncHook(){let adapters=worktreeSyncAdapters();if(adapters.length===0)return;let stored=getPersistedString(SYNC_SETTING_KEY),paths=new Set;for(let adapter of adapters){let file=adapter.globalSettingsPath();if(file)paths.add(file)}let prev=persistedSyncPath(stored);if(prev)paths.add(prev);for(let a of adapters)for(let p of paths)await a.removeWorktreeSyncHook(p);if(stored!=="off")setPersistedString(SYNC_SETTING_KEY,"off")}async function runHookCleanup(){let claude=activityHookAdapters().find((a)=>a.vendor==="claude"),path=claude?.globalSettingsPath();if(!claude||!path){process.stdout.write(`rove hook cleanup: no Claude hook adapter \u2014 nothing to do.
5
5
  `);return}await claude.removeActivityHooks(path),await claude.removeWorktreeWatchHook(path),process.stdout.write([`rove hook cleanup: removed Rove's settings-managed hooks from ${path}.`,"Only Rove's own entries were touched; your other hooks are intact.","The Claude Code plugin's hooks.json now carries these events (if the plugin","is not installed, the next Rove launch reinstalls the settings-managed set).",""].join(`
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{INIT_PROMPT_FILENAME,INIT_SCRIPT_FILENAME,describeRepoInitSources,missingDependenciesCoda,resolveEngineLaunchInit,resolveRepoInit}from"./chunk-2jj1q7pv.js";import"./chunk-hape5vwj.js";import"./chunk-s5dfv5zg.js";import"./chunk-4m57n1t2.js";import"./chunk-j38kagw2.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-cdy4v61w.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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";export{resolveRepoInit,resolveEngineLaunchInit,missingDependenciesCoda,describeRepoInitSources,INIT_SCRIPT_FILENAME,INIT_PROMPT_FILENAME};
2
+ import{INIT_PROMPT_FILENAME,INIT_SCRIPT_FILENAME,describeRepoInitSources,missingDependenciesCoda,resolveEngineLaunchInit,resolveRepoInit}from"./chunk-2jj1q7pv.js";import"./chunk-hape5vwj.js";import"./chunk-rrt4z9at.js";import"./chunk-9wg9snjs.js";import"./chunk-kx5gzpmt.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-cdy4v61w.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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";export{resolveRepoInit,resolveEngineLaunchInit,missingDependenciesCoda,describeRepoInitSources,INIT_SCRIPT_FILENAME,INIT_PROMPT_FILENAME};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{pluginConfigDir,pluginStateDir}from"./chunk-1p5334mv.js";function buildPluginEnv(opts){let configDir=pluginConfigDir(opts.pluginId,opts.homeDir),stateDir=pluginStateDir(opts.pluginId,opts.homeDir),extra=withPluginEnvAliases(opts.extra??{});return{...process.env,...opts.homeDir?{ROVE_HOME_DIR:opts.homeDir,KOBE_HOME_DIR:opts.homeDir}:{},ROVE_SOCKET_PATH:opts.socketPath,KOBE_SOCKET_PATH:opts.socketPath,ROVE_BIN_PATH:opts.binPath,KOBE_BIN_PATH:opts.binPath,ROVE_PLUGIN_ID:opts.pluginId,KOBE_PLUGIN_ID:opts.pluginId,ROVE_PLUGIN_ROOT:opts.pluginRoot,KOBE_PLUGIN_ROOT:opts.pluginRoot,ROVE_PLUGIN_CONFIG_DIR:configDir,KOBE_PLUGIN_CONFIG_DIR:configDir,ROVE_PLUGIN_STATE_DIR:stateDir,KOBE_PLUGIN_STATE_DIR:stateDir,...extra}}function withPluginEnvAliases(values){let aliases={};for(let[key,value]of Object.entries(values))if(key.startsWith("ROVE_"))aliases[`KOBE_${key.slice(5)}`]=value;else if(key.startsWith("KOBE_"))aliases[`ROVE_${key.slice(5)}`]=value;return{...aliases,...values}}
2
+ import{pluginConfigDir,pluginStateDir}from"./chunk-zd46ghvd.js";function buildPluginEnv(opts){let configDir=pluginConfigDir(opts.pluginId,opts.homeDir),stateDir=pluginStateDir(opts.pluginId,opts.homeDir),extra=withPluginEnvAliases(opts.extra??{});return{...process.env,...opts.homeDir?{ROVE_HOME_DIR:opts.homeDir,KOBE_HOME_DIR:opts.homeDir}:{},ROVE_SOCKET_PATH:opts.socketPath,KOBE_SOCKET_PATH:opts.socketPath,ROVE_BIN_PATH:opts.binPath,KOBE_BIN_PATH:opts.binPath,ROVE_PLUGIN_ID:opts.pluginId,KOBE_PLUGIN_ID:opts.pluginId,ROVE_PLUGIN_ROOT:opts.pluginRoot,KOBE_PLUGIN_ROOT:opts.pluginRoot,ROVE_PLUGIN_CONFIG_DIR:configDir,KOBE_PLUGIN_CONFIG_DIR:configDir,ROVE_PLUGIN_STATE_DIR:stateDir,KOBE_PLUGIN_STATE_DIR:stateDir,...extra}}function withPluginEnvAliases(values){let aliases={};for(let[key,value]of Object.entries(values))if(key.startsWith("ROVE_"))aliases[`KOBE_${key.slice(5)}`]=value;else if(key.startsWith("KOBE_"))aliases[`ROVE_${key.slice(5)}`]=value;return{...aliases,...values}}
3
3
  export{buildPluginEnv};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-1j8xkxqc.js";import{t}from"./chunk-2cnzaw88.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-8m6f3myf.js";import{t}from"./chunk-2cnzaw88.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,3 +1,3 @@
1
1
  // @bun
2
- import{engineEntry}from"./chunk-4m57n1t2.js";import{roveCliInvocation}from"./chunk-wc0tmpd7.js";import{getPersistedString}from"./chunk-crt11rmj.js";import{coerceVendorId}from"./chunk-05jej26n.js";function engineCommandKey(vendor){return`engineCommand.${vendor}`}function engineNameKey(vendor){return`engineName.${vendor}`}function engineDisplayName(vendor){return getPersistedString(engineNameKey(vendor))?.trim()||engineEntry(vendor).displayName}function humanizeSlug(id){return id.split(/[-_]+/).filter((word)=>word.length>0).map((word)=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function defaultEngineCommand(vendor){return engineEntry(coerceVendorId(vendor)).defaultCommand}function parseEngineCommand(command){let out=[],token="",hasToken=!1,quote=null;for(let ch of command){if(quote){if(ch===quote)quote=null;else token+=ch;continue}if(ch==='"'||ch==="'"){quote=ch,hasToken=!0;continue}if(/\s/.test(ch)){if(hasToken)out.push(token),token="",hasToken=!1;continue}token+=ch,hasToken=!0}if(hasToken)out.push(token);return out}function interactiveEngineCommand(vendor,effort,model){let v=coerceVendorId(vendor),override=getPersistedString(engineCommandKey(v))?.trim(),base=(()=>{if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(v)})();return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,v,effort),v,model),v)}function withEngineTerminalTitle(argv,vendor){let args=engineEntry(coerceVendorId(vendor)).terminalTitle?.launchArgs;return args&&args.length>0?[...argv,...args]:argv}function withEngineEffort(argv,vendor,effort){let trimmed=effort?.trim();if(!trimmed)return argv;let entry=engineEntry(coerceVendorId(vendor));if(!entry.effortLevels?.includes(trimmed))return argv;return entry.effortArgv?.(argv,trimmed)??argv}function withEngineModel(argv,vendor,model){let trimmed=model?.trim();if(!trimmed)return argv;return engineEntry(coerceVendorId(vendor)).modelArgv?.(argv,trimmed)??argv}function kobeApiInvocation(){let quote=(a)=>/^[A-Za-z0-9_/.:=-]+$/.test(a)?a:`'${a.replace(/'/g,"'\\''")}'`;try{return[...roveCliInvocation(),"api"].map(quote).join(" ")}catch{return"rove api"}}
2
+ import{engineEntry}from"./chunk-9wg9snjs.js";import{roveCliInvocation}from"./chunk-wc0tmpd7.js";import{getPersistedString}from"./chunk-crt11rmj.js";import{coerceVendorId}from"./chunk-05jej26n.js";function engineCommandKey(vendor){return`engineCommand.${vendor}`}function engineNameKey(vendor){return`engineName.${vendor}`}function engineDisplayName(vendor){return getPersistedString(engineNameKey(vendor))?.trim()||engineEntry(vendor).displayName}function humanizeSlug(id){return id.split(/[-_]+/).filter((word)=>word.length>0).map((word)=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ")}function defaultEngineCommand(vendor){return engineEntry(coerceVendorId(vendor)).defaultCommand}function parseEngineCommand(command){let out=[],token="",hasToken=!1,quote=null;for(let ch of command){if(quote){if(ch===quote)quote=null;else token+=ch;continue}if(ch==='"'||ch==="'"){quote=ch,hasToken=!0;continue}if(/\s/.test(ch)){if(hasToken)out.push(token),token="",hasToken=!1;continue}token+=ch,hasToken=!0}if(hasToken)out.push(token);return out}function interactiveEngineCommand(vendor,effort,model){let v=coerceVendorId(vendor),override=getPersistedString(engineCommandKey(v))?.trim(),base=(()=>{if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(v)})();return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,v,effort),v,model),v)}function withEngineTerminalTitle(argv,vendor){let args=engineEntry(coerceVendorId(vendor)).terminalTitle?.launchArgs;return args&&args.length>0?[...argv,...args]:argv}function withEngineEffort(argv,vendor,effort){let trimmed=effort?.trim();if(!trimmed)return argv;let entry=engineEntry(coerceVendorId(vendor));if(!entry.effortLevels?.includes(trimmed))return argv;return entry.effortArgv?.(argv,trimmed)??argv}function withEngineModel(argv,vendor,model){let trimmed=model?.trim();if(!trimmed)return argv;return engineEntry(coerceVendorId(vendor)).modelArgv?.(argv,trimmed)??argv}function kobeApiInvocation(){let quote=(a)=>/^[A-Za-z0-9_/.:=-]+$/.test(a)?a:`'${a.replace(/'/g,"'\\''")}'`;try{return[...roveCliInvocation(),"api"].map(quote).join(" ")}catch{return"rove api"}}
3
3
  export{engineCommandKey,engineNameKey,engineDisplayName,humanizeSlug,defaultEngineCommand,parseEngineCommand,interactiveEngineCommand,withEngineTerminalTitle,withEngineEffort,withEngineModel,kobeApiInvocation};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{isDev}from"./chunk-q5jhy3t8.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.209",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.KOBE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
2
+ import{isDev}from"./chunk-q5jhy3t8.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.211",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{kobe:"dist/cli/kobe.js",rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:kobe":"KOBE_DEV=1 bun --conditions=browser ./src/cli/kobe.ts","dev:mock":"KOBE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"KOBE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"KOBE_INCLUDE_SOCKET=1 KOBE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"KOBE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.18.0"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/kobe-daemon":"0.7.19","@tsconfig/bun":"1.0.10","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.KOBE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
3
3
  export{package_default,CURRENT_VERSION,PACKAGE_NAME,repoSlug,UPDATE_SCRIPT_URL,UPDATE_COMMAND,owningNpmPrefix,recommendedGlobalInstallCommand,BREAKING_VERSIONS,breakingVersionsCrossed,RELEASE_CHANNELS,DEFAULT_RELEASE_CHANNEL,channelOf,isNewerSemver,compareSemver,checkLatestVersion,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,releasePageUrl};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{CURRENT_VERSION,repoSlug}from"./chunk-b23mvges.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
2
+ import{CURRENT_VERSION,repoSlug}from"./chunk-sa7yam4k.js";import{spawnSync}from"child_process";var DEFAULT_FEEDBACK_CATEGORY_SLUG="feedback",DISCUSSION_CATEGORY_QUERY=`
3
3
  query($owner: String!, $name: String!) {
4
4
  repository(owner: $owner, name: $name) {
5
5
  id
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{resolveLoginShell}from"./chunk-b99tf0jr.js";import{recommendedGlobalInstallCommand}from"./chunk-b23mvges.js";function updaterShell(deps={}){let platform=deps.platform??process.platform;if(platform!=="win32")return"sh";return resolveLoginShell({fallback:"/bin/sh",platform,env:deps.env,exists:deps.exists})}function updaterShellFailureHint(deps={}){if((deps.platform??process.platform)!=="win32")return null;return["The update script is POSIX shell. Rove runs it through Git for Windows'","bash \u2014 the same shell every engine and terminal tab launches through.","Install Git for Windows (https://git-scm.com/download/win), or update","by hand:",` ${recommendedGlobalInstallCommand()}`,""].join(`
2
+ import{resolveLoginShell}from"./chunk-b99tf0jr.js";import{recommendedGlobalInstallCommand}from"./chunk-sa7yam4k.js";function updaterShell(deps={}){let platform=deps.platform??process.platform;if(platform!=="win32")return"sh";return resolveLoginShell({fallback:"/bin/sh",platform,env:deps.env,exists:deps.exists})}function updaterShellFailureHint(deps={}){if((deps.platform??process.platform)!=="win32")return null;return["The update script is POSIX shell. Rove runs it through Git for Windows'","bash \u2014 the same shell every engine and terminal tab launches through.","Install Git for Windows (https://git-scm.com/download/win), or update","by hand:",` ${recommendedGlobalInstallCommand()}`,""].join(`
3
3
  `)}
4
4
  export{updaterShell,updaterShellFailureHint};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{closeTab,engineTabArgv,initialTabs,setTabTitle,terminalTabsKey}from"./chunk-jgdjfsdk.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors}from"./chunk-72b8g3hs.js";import{ApiError}from"./chunk-f7zjggfv.js";import{engineLaunchArgv}from"./chunk-g2wk0es7.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,model:tab.engineCommand||tab.vendor?void 0:task.model});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-6cc1e9pz.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors}from"./chunk-3j7j0egr.js";import{ApiError}from"./chunk-f7zjggfv.js";import{engineLaunchArgv}from"./chunk-arj1d3vp.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,model:tab.engineCommand||tab.vendor?void 0:task.model});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};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,PACKAGE_NAME,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,compareSemver,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,isNewerSemver,owningNpmPrefix,recommendedGlobalInstallCommand,releasePageUrl,repoSlug}from"./chunk-b23mvges.js";import"./chunk-q5jhy3t8.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{repoSlug,releasePageUrl,recommendedGlobalInstallCommand,owningNpmPrefix,isNewerSemver,fetchReleaseSummaries,fetchReleaseNotesRange,fetchReleaseNotes,compareSemver,checkLatestVersion,channelOf,breakingVersionsCrossed,UPDATE_SCRIPT_URL,UPDATE_COMMAND,RELEASE_CHANNELS,PACKAGE_NAME,DEFAULT_RELEASE_CHANNEL,CURRENT_VERSION,BREAKING_VERSIONS};
2
+ import{BREAKING_VERSIONS,CURRENT_VERSION,DEFAULT_RELEASE_CHANNEL,PACKAGE_NAME,RELEASE_CHANNELS,UPDATE_COMMAND,UPDATE_SCRIPT_URL,breakingVersionsCrossed,channelOf,checkLatestVersion,compareSemver,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,isNewerSemver,owningNpmPrefix,recommendedGlobalInstallCommand,releasePageUrl,repoSlug}from"./chunk-sa7yam4k.js";import"./chunk-q5jhy3t8.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";export{repoSlug,releasePageUrl,recommendedGlobalInstallCommand,owningNpmPrefix,isNewerSemver,fetchReleaseSummaries,fetchReleaseNotesRange,fetchReleaseNotes,compareSemver,checkLatestVersion,channelOf,breakingVersionsCrossed,UPDATE_SCRIPT_URL,UPDATE_COMMAND,RELEASE_CHANNELS,PACKAGE_NAME,DEFAULT_RELEASE_CHANNEL,CURRENT_VERSION,BREAKING_VERSIONS};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{wizardKeyLines}from"./chunk-hm32s0y8.js";import{$Fragment,$jsx,$jsxs,bootPaneHost,currentPrefixConfiguration,pageCloseBindings,useBindings,useRenderer,useT,useTheme}from"./chunk-kx2j56dv.js";import"./chunk-sk759pn7.js";import{require_react_production}from"./chunk-a82ec09z.js";import"./chunk-k6nxyxyh.js";import"./chunk-h4n8ffqy.js";import"./chunk-59xc6m1q.js";import"./chunk-6xppe9bj.js";import"./chunk-gnncrk3w.js";import"./chunk-w6fbdxg2.js";import"./chunk-fczqwtmq.js";import"./chunk-yv44tdjq.js";import"./chunk-c42pwcvw.js";import"./chunk-mjdt28x6.js";import"./chunk-p1zab1sy.js";import"./chunk-hqbmzz4t.js";import"./chunk-764bsyb0.js";import{envReadyForTasks}from"./chunk-45kjd17g.js";import"./chunk-qgfwebxj.js";import"./chunk-v4bg25ks.js";import"./chunk-1j8xkxqc.js";import"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import"./chunk-g2wk0es7.js";import"./chunk-s5dfv5zg.js";import"./chunk-2cnzaw88.js";import"./chunk-gqqnp8fp.js";import"./chunk-sdyzxayr.js";import"./chunk-v8yagax5.js";import"./chunk-4m57n1t2.js";import"./chunk-j38kagw2.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-b23mvges.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-w0aw0mdw.js";import"./chunk-cdy4v61w.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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{__toESM}from"./chunk-wqfp8d9w.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);function inlineRowsFor(env){return 17+env.engines.lines.length+envActionKeys(env).length}function envActionKeys(env){let keys=[];if(!env.engines.anyUsable)keys.push("doctor.fix.noEngineAction");if(!env.git.found)keys.push("doctor.fix.gitAction");return keys}function WizardPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),steps=(props.mode??"full")==="primer"?[]:props.shell===null?["skill"]:["completions","skill"],[stepIndex,setStepIndex]=import_react2.useState(0),[yes,setYes]=import_react2.useState(!0),[answers,setAnswers]=import_react2.useState({}),[page,setPage]=import_react2.useState(steps.length===0?"env":"questions"),step=steps[stepIndex];function finish(finalAnswers){renderer?.destroy(),props.onDone({completions:finalAnswers.completions??!1,skill:finalAnswers.skill??!1})}function confirm(choice=yes){if(page==="env"){setPage("keys");return}if(page==="keys"){finish(answers);return}let next={...answers,[step]:choice};if(setAnswers(next),stepIndex+1>=steps.length){setPage("env");return}setStepIndex(stepIndex+1),setYes(!0)}useBindings(()=>({bindings:[{key:"up",cmd:()=>setYes(!0)},{key:"k",cmd:()=>setYes(!0)},{key:"down",cmd:()=>setYes(!1)},{key:"j",cmd:()=>setYes(!1)},{key:"return",cmd:()=>confirm()},...pageCloseBindings(()=>finish(answers))]}));function questionFor(s){return s==="completions"?t("onboarding.completionsQuestion",{shell:props.shell??""}):t("onboarding.skillQuestion")}let explain=step==="completions"?t("onboarding.completionsExplain"):t("onboarding.skillExplain"),ready=envReadyForTasks(props.env);return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsx("text",{fg:theme.primary,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("onboarding.title")}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("onboarding.subtitle")}),$jsxs("box",{flexDirection:"column",paddingTop:1,children:[steps.slice(0,page==="questions"?stepIndex:steps.length).map((answered)=>$jsxs("box",{flexDirection:"row",gap:1,children:[$jsx("text",{fg:theme.success,wrapMode:"none",children:"\u2713"}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:questionFor(answered)}),$jsx("text",{fg:theme.text,wrapMode:"none",children:answers[answered]?t("onboarding.optionYes"):t("onboarding.optionNo")})]},answered)),page==="env"?$jsxs("box",{flexDirection:"column",onMouseUp:()=>confirm(),children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"word",children:t("onboarding.envTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("onboarding.envExplain")}),$jsxs("box",{flexDirection:"column",paddingTop:1,children:[$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:props.env.git.line}),props.env.engines.lines.map((line)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:line},line))]}),$jsxs("box",{paddingTop:1,flexDirection:"column",children:[$jsx("text",{fg:ready?theme.success:theme.error,wrapMode:"word",children:ready?t("onboarding.envReady"):t("onboarding.envNotReady")}),envActionKeys(props.env).map((key)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:`\u2192 ${t(key)}`},key))]})]}):null,page==="keys"?$jsxs("box",{flexDirection:"column",onMouseUp:()=>confirm(),children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"word",children:t("onboarding.keysTitle")}),wizardKeyLines(currentPrefixConfiguration().key).map((line)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t(`onboarding.${line.msg}`,line.params)},line.msg)),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("onboarding.keysNext")})]}):null,page==="questions"?$jsxs($Fragment,{children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"word",children:questionFor(step)}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:explain}),[!0,!1].map((option)=>{let active=yes===option;return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,onMouseUp:()=>confirm(option),children:[$jsx("text",{fg:active?theme.primary:theme.textMuted,wrapMode:"none",children:active?"\u276F":" "}),$jsx("text",{fg:active?theme.primary:theme.textMuted,attributes:active?TextAttributes.BOLD:void 0,wrapMode:"none",children:option?t("onboarding.optionYes"):t("onboarding.optionNo")})]},String(option))})]}):null]}),$jsx("box",{paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t(page==="keys"?"onboarding.keysLegend":page==="env"?"onboarding.envLegend":"onboarding.legend")})})]})}async function runOnboardingWizard(shell,env,mode){return await new Promise((resolve)=>{bootPaneHost({inlineRows:inlineRowsFor(env),setup:()=>({root:()=>$jsx(WizardPage,{shell,env,mode,onDone:resolve})})})})}export{runOnboardingWizard,WizardPage};
2
+ import{wizardKeyLines}from"./chunk-60fmp80z.js";import{$Fragment,$jsx,$jsxs,bootPaneHost,currentPrefixConfiguration,pageCloseBindings,useBindings,useRenderer,useT,useTheme}from"./chunk-kghvc2x8.js";import"./chunk-gqq2yq9r.js";import{require_react_production}from"./chunk-a82ec09z.js";import"./chunk-k6nxyxyh.js";import"./chunk-h4n8ffqy.js";import"./chunk-59xc6m1q.js";import"./chunk-6xppe9bj.js";import"./chunk-gnncrk3w.js";import"./chunk-w6fbdxg2.js";import"./chunk-fczqwtmq.js";import"./chunk-yv44tdjq.js";import"./chunk-c42pwcvw.js";import"./chunk-mjdt28x6.js";import"./chunk-p1zab1sy.js";import"./chunk-hqbmzz4t.js";import"./chunk-764bsyb0.js";import{envReadyForTasks}from"./chunk-ygadamzf.js";import"./chunk-r83qrttp.js";import"./chunk-bapcjjpn.js";import"./chunk-8m6f3myf.js";import"./chunk-yybpg7fh.js";import"./chunk-fhch0x0q.js";import"./chunk-arj1d3vp.js";import"./chunk-rrt4z9at.js";import"./chunk-2cnzaw88.js";import"./chunk-gqqnp8fp.js";import"./chunk-sdyzxayr.js";import"./chunk-bw6qkdac.js";import"./chunk-9wg9snjs.js";import"./chunk-kx5gzpmt.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-sa7yam4k.js";import"./chunk-jvxh93nz.js";import"./chunk-2brn8e1y.js";import"./chunk-w0aw0mdw.js";import"./chunk-cdy4v61w.js";import"./chunk-wc0tmpd7.js";import"./chunk-7kysxgbq.js";import"./chunk-b7vvsyeg.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{__toESM}from"./chunk-wqfp8d9w.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);function inlineRowsFor(env){return 17+env.engines.lines.length+envActionKeys(env).length}function envActionKeys(env){let keys=[];if(!env.engines.anyUsable)keys.push("doctor.fix.noEngineAction");if(!env.git.found)keys.push("doctor.fix.gitAction");return keys}function WizardPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),steps=(props.mode??"full")==="primer"?[]:props.shell===null?["skill"]:["completions","skill"],[stepIndex,setStepIndex]=import_react2.useState(0),[yes,setYes]=import_react2.useState(!0),[answers,setAnswers]=import_react2.useState({}),[page,setPage]=import_react2.useState(steps.length===0?"env":"questions"),step=steps[stepIndex];function finish(finalAnswers){renderer?.destroy(),props.onDone({completions:finalAnswers.completions??!1,skill:finalAnswers.skill??!1})}function confirm(choice=yes){if(page==="env"){setPage("keys");return}if(page==="keys"){finish(answers);return}let next={...answers,[step]:choice};if(setAnswers(next),stepIndex+1>=steps.length){setPage("env");return}setStepIndex(stepIndex+1),setYes(!0)}useBindings(()=>({bindings:[{key:"up",cmd:()=>setYes(!0)},{key:"k",cmd:()=>setYes(!0)},{key:"down",cmd:()=>setYes(!1)},{key:"j",cmd:()=>setYes(!1)},{key:"return",cmd:()=>confirm()},...pageCloseBindings(()=>finish(answers))]}));function questionFor(s){return s==="completions"?t("onboarding.completionsQuestion",{shell:props.shell??""}):t("onboarding.skillQuestion")}let explain=step==="completions"?t("onboarding.completionsExplain"):t("onboarding.skillExplain"),ready=envReadyForTasks(props.env);return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsx("text",{fg:theme.primary,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("onboarding.title")}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("onboarding.subtitle")}),$jsxs("box",{flexDirection:"column",paddingTop:1,children:[steps.slice(0,page==="questions"?stepIndex:steps.length).map((answered)=>$jsxs("box",{flexDirection:"row",gap:1,children:[$jsx("text",{fg:theme.success,wrapMode:"none",children:"\u2713"}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",children:questionFor(answered)}),$jsx("text",{fg:theme.text,wrapMode:"none",children:answers[answered]?t("onboarding.optionYes"):t("onboarding.optionNo")})]},answered)),page==="env"?$jsxs("box",{flexDirection:"column",onMouseUp:()=>confirm(),children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"word",children:t("onboarding.envTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("onboarding.envExplain")}),$jsxs("box",{flexDirection:"column",paddingTop:1,children:[$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:props.env.git.line}),props.env.engines.lines.map((line)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:line},line))]}),$jsxs("box",{paddingTop:1,flexDirection:"column",children:[$jsx("text",{fg:ready?theme.success:theme.error,wrapMode:"word",children:ready?t("onboarding.envReady"):t("onboarding.envNotReady")}),envActionKeys(props.env).map((key)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:`\u2192 ${t(key)}`},key))]})]}):null,page==="keys"?$jsxs("box",{flexDirection:"column",onMouseUp:()=>confirm(),children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"word",children:t("onboarding.keysTitle")}),wizardKeyLines(currentPrefixConfiguration().key).map((line)=>$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t(`onboarding.${line.msg}`,line.params)},line.msg)),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("onboarding.keysNext")})]}):null,page==="questions"?$jsxs($Fragment,{children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"word",children:questionFor(step)}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:explain}),[!0,!1].map((option)=>{let active=yes===option;return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,onMouseUp:()=>confirm(option),children:[$jsx("text",{fg:active?theme.primary:theme.textMuted,wrapMode:"none",children:active?"\u276F":" "}),$jsx("text",{fg:active?theme.primary:theme.textMuted,attributes:active?TextAttributes.BOLD:void 0,wrapMode:"none",children:option?t("onboarding.optionYes"):t("onboarding.optionNo")})]},String(option))})]}):null]}),$jsx("box",{paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t(page==="keys"?"onboarding.keysLegend":page==="env"?"onboarding.envLegend":"onboarding.legend")})})]})}async function runOnboardingWizard(shell,env,mode){return await new Promise((resolve)=>{bootPaneHost({inlineRows:inlineRowsFor(env),setup:()=>({root:()=>$jsx(WizardPage,{shell,env,mode,onDone:resolve})})})})}export{runOnboardingWizard,WizardPage};
@@ -1,8 +1,8 @@
1
1
  // @bun
2
- import{checkOnboardingEnv,noEngineAction}from"./chunk-qgfwebxj.js";import{LAST_RUN_VERSION_KEY}from"./chunk-v4bg25ks.js";import{shippedCompletionsPath}from"./chunk-yybpg7fh.js";import{t}from"./chunk-2cnzaw88.js";import{isNpxMissing,markSkillHintSeen,npxSkillsArgv,npxSkillsCommand}from"./chunk-w0aw0mdw.js";import{getPersistedBool,loadStateFile,setPersistedBool}from"./chunk-katrbape.js";import{activeCliName}from"./chunk-00ehck55.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";import{appendFileSync,existsSync,mkdirSync,readFileSync,writeFileSync}from"fs";import{homedir}from"os";import{basename,join}from"path";var ONBOARDED_KEY="onboarded",PRIMER_KEY="onboardedPrimer";function detectShell(env=process.env){let shell=basename(env.SHELL??"");return shell==="zsh"||shell==="bash"||shell==="fish"?shell:null}function completionHook(shell,cli,shipped){if(shipped===null)return legacyCompletionHook(shell,cli);return shell==="fish"?`test -f "${shipped}"; and source "${shipped}"`:`[ -f "${shipped}" ] && source "${shipped}"`}function legacyCompletionHook(shell,cli){return shell==="fish"?`${cli} completions fish | source`:`command -v ${cli} >/dev/null && source <(${cli} completions ${shell})`}function shippedScriptFor(shell,cli){let path=shippedCompletionsPath(shell,cli);return existsSync(path)?path:null}function installCompletions(shell,home=homedir(),cli=activeCliName(),shipped=shippedScriptFor(shell,cli)){let hook=completionHook(shell,cli,shipped);if(shell==="fish"){let dir=join(home,".config","fish","completions"),path=join(dir,`${cli}.fish`);return mkdirSync(dir,{recursive:!0}),writeFileSync(path,`${hook}
2
+ import{checkOnboardingEnv,noEngineAction}from"./chunk-r83qrttp.js";import{LAST_RUN_VERSION_KEY}from"./chunk-bapcjjpn.js";import{shippedCompletionsPath}from"./chunk-yybpg7fh.js";import{t}from"./chunk-2cnzaw88.js";import{isNpxMissing,markSkillHintSeen,npxSkillsArgv,npxSkillsCommand}from"./chunk-w0aw0mdw.js";import{getPersistedBool,loadStateFile,setPersistedBool}from"./chunk-katrbape.js";import{activeCliName}from"./chunk-00ehck55.js";import{__require}from"./chunk-wqfp8d9w.js";import{spawnSync}from"child_process";import{appendFileSync,existsSync,mkdirSync,readFileSync,writeFileSync}from"fs";import{homedir}from"os";import{basename,join}from"path";var ONBOARDED_KEY="onboarded",PRIMER_KEY="onboardedPrimer";function detectShell(env=process.env){let shell=basename(env.SHELL??"");return shell==="zsh"||shell==="bash"||shell==="fish"?shell:null}function completionHook(shell,cli,shipped){if(shipped===null)return legacyCompletionHook(shell,cli);return shell==="fish"?`test -f "${shipped}"; and source "${shipped}"`:`[ -f "${shipped}" ] && source "${shipped}"`}function legacyCompletionHook(shell,cli){return shell==="fish"?`${cli} completions fish | source`:`command -v ${cli} >/dev/null && source <(${cli} completions ${shell})`}function shippedScriptFor(shell,cli){let path=shippedCompletionsPath(shell,cli);return existsSync(path)?path:null}function installCompletions(shell,home=homedir(),cli=activeCliName(),shipped=shippedScriptFor(shell,cli)){let hook=completionHook(shell,cli,shipped);if(shell==="fish"){let dir=join(home,".config","fish","completions"),path=join(dir,`${cli}.fish`);return mkdirSync(dir,{recursive:!0}),writeFileSync(path,`${hook}
3
3
  `),{path,installed:!0}}let rc=join(home,shell==="zsh"?".zshrc":".bashrc"),existing=existsSync(rc)?readFileSync(rc,"utf8"):"";if(existing.includes(hook))return{path:rc,installed:!1};let legacy=legacyCompletionHook(shell,cli);if(existing.includes(legacy))return writeFileSync(rc,existing.replace(legacy,hook)),{path:rc,installed:!0};if(existing.includes(`${cli} completions`))return{path:rc,installed:!1};return appendFileSync(rc,`
4
4
  # ${cli} completions
5
5
  ${hook}
6
6
  `),{path:rc,installed:!0}}function isOnboarded(){return getPersistedBool(ONBOARDED_KEY,!1)}function markOnboarded(){setPersistedBool(ONBOARDED_KEY,!0)}function isPrimerDone(){return getPersistedBool(PRIMER_KEY,!1)}function markPrimerDone(){setPersistedBool(PRIMER_KEY,!0)}function backfillPrimerForExistingUsers(){if(typeof loadStateFile()[LAST_RUN_VERSION_KEY]!=="string")return!1;return markPrimerDone(),!0}function envReadyForTasks(env){return env.engines.anyUsable&&env.git.found}function applyOnboardingChoices(choices,shell,env){let cli=activeCliName(),completionsHelp=`${cli} completions --help`,skillInstall=`${cli} skill install`,out=(line)=>process.stdout.write(`${line}
7
- `);if(shell!==null)if(choices.completions){let completion=installCompletions(shell);out(t(completion.installed?"onboarding.appliedCompletions":"onboarding.keptCompletions",{path:completion.path}))}else out(t("onboarding.skippedCompletions",{command:completionsHelp}));if(choices.skill){if(isNpxMissing())out(t("onboarding.skillNeedsNode",{command:skillInstall}));else if(out(t("onboarding.installingSkill",{command:npxSkillsCommand()})),spawnSync("npx",npxSkillsArgv(),{stdio:"inherit"}).status!==0)out(t("onboarding.skillFailed",{command:skillInstall}))}else out(t("onboarding.skippedSkill",{command:skillInstall})),markSkillHintSeen();out(""),out(env.git.line);for(let line of env.engines.lines)out(line);if(out(""),envReadyForTasks(env))out(t("onboarding.ready")),out(t("onboarding.readyHint",{command:cli}));else{if(out(t("onboarding.notReadyHeader")),!env.engines.anyUsable)out(` \u2192 ${noEngineAction(env.engines.signedOut)}`);if(!env.git.found)out(` \u2192 ${t("doctor.fix.gitAction")}`)}}async function maybeRunOnboarding(){if(!process.stdout.isTTY||!process.stdin.isTTY)return!1;let seen=isOnboarded();if(seen&&(isPrimerDone()||backfillPrimerForExistingUsers()))return!1;markOnboarded();let shell=detectShell(),env=await checkOnboardingEnv(),{runOnboardingWizard}=await import("./chunk-eyccnzck.js"),choices=await runOnboardingWizard(shell,env,seen?"primer":"full");return markPrimerDone(),applyOnboardingChoices(choices,shell,env),!0}
7
+ `);if(shell!==null)if(choices.completions){let completion=installCompletions(shell);out(t(completion.installed?"onboarding.appliedCompletions":"onboarding.keptCompletions",{path:completion.path}))}else out(t("onboarding.skippedCompletions",{command:completionsHelp}));if(choices.skill){if(isNpxMissing())out(t("onboarding.skillNeedsNode",{command:skillInstall}));else if(out(t("onboarding.installingSkill",{command:npxSkillsCommand()})),spawnSync("npx",npxSkillsArgv(),{stdio:"inherit"}).status!==0)out(t("onboarding.skillFailed",{command:skillInstall}))}else out(t("onboarding.skippedSkill",{command:skillInstall})),markSkillHintSeen();out(""),out(env.git.line);for(let line of env.engines.lines)out(line);if(out(""),envReadyForTasks(env))out(t("onboarding.ready")),out(t("onboarding.readyHint",{command:cli}));else{if(out(t("onboarding.notReadyHeader")),!env.engines.anyUsable)out(` \u2192 ${noEngineAction(env.engines.signedOut)}`);if(!env.git.found)out(` \u2192 ${t("doctor.fix.gitAction")}`)}}async function maybeRunOnboarding(){if(!process.stdout.isTTY||!process.stdin.isTTY)return!1;let seen=isOnboarded();if(seen&&(isPrimerDone()||backfillPrimerForExistingUsers()))return!1;markOnboarded();let shell=detectShell(),env=await checkOnboardingEnv(),{runOnboardingWizard}=await import("./chunk-x67ebsrg.js"),choices=await runOnboardingWizard(shell,env,seen?"primer":"full");return markPrimerDone(),applyOnboardingChoices(choices,shell,env),!0}
8
8
  export{detectShell,installCompletions,envReadyForTasks,applyOnboardingChoices,maybeRunOnboarding};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{serialized,writeJsonAtomic}from"./chunk-xsrcwcjc.js";import{loadPluginRegistry,pluginConfigDir,pluginDataDir,pluginLogPath,pluginRegistryPath,pluginStateDir,pluginsRootDir}from"./chunk-1p5334mv.js";import{logDaemonError}from"./chunk-rcyasw34.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE}from"./chunk-9prawccj.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import{chmodSync}from"fs";function tighten(path,mode){try{chmodSync(path,mode)}catch{}}function tightenPluginPermissions(id,homeDir){tighten(pluginDataDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginConfigDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginStateDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(`${pluginConfigDir(id,homeDir)}/.env`,OWNER_ONLY_FILE_MODE),tighten(pluginLogPath(id,homeDir),OWNER_ONLY_FILE_MODE)}function tightenInstalledPluginPermissions(homeDir){tighten(pluginsRootDir(homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginRegistryPath(homeDir),OWNER_ONLY_FILE_MODE);for(let entry of loadPluginRegistry(homeDir).plugins)tightenPluginPermissions(entry.id,homeDir)}import{execFile as execFile2}from"child_process";import{readFile}from"fs/promises";import{homedir}from"os";import{join,resolve as resolve2}from"path";import{promisify as promisify2}from"util";import{execFile}from"child_process";import{realpath,stat}from"fs/promises";import{isAbsolute,resolve}from"path";import{promisify}from"util";var execFileAsync=promisify(execFile);async function gitCommonDir(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--git-common-dir"]),dir=stdout.trim();return realpath(isAbsolute(dir)?dir:resolve(path,dir))}async function gitMainWorktree(path){let{stdout}=await execFileAsync("git",["-C",path,"worktree","list","--porcelain"]),first=stdout.split(/\r?\n/).find((line)=>line.startsWith("worktree "))?.slice(9).trim();return first?await realpath(first):null}async function gitTopLevel(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--show-toplevel"]);return stdout.trim()}async function resolveRepoRoot(raw){let absolute=resolve(raw);if(!(await stat(absolute).catch(()=>null))?.isDirectory())throw Error("repoRoot does not exist");let[repoRoot,repoKey]=await Promise.all([gitMainWorktree(absolute),gitCommonDir(absolute)]);return{repoRoot,repoKey}}var execFileAsync2=promisify2(execFile2),ISSUE_STATUSES=["open","doing","hold","done"],ISSUE_NOT_FOUND_CODE="ISSUE_NOT_FOUND",ISSUE_STORE_UNREADABLE_CODE="ISSUE_STORE_UNREADABLE";function isGitNotRepositoryError(err){return(err instanceof Error?err.message:String(err)).includes("not a git repository")}function defaultIssuesStorePath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"issues.json")}function isValidStatus(value){return typeof value==="string"&&ISSUE_STATUSES.includes(value)}function normalizeIssue(entry){if(entry===null||typeof entry!=="object"||Array.isArray(entry))return null;let raw=entry;if(typeof raw.id!=="number")return null;return{id:raw.id,title:typeof raw.title==="string"?raw.title:"(untitled)",status:isValidStatus(raw.status)?raw.status:"open",created:typeof raw.created==="string"?raw.created:"",body:typeof raw.body==="string"?raw.body:"",taskId:typeof raw.taskId==="string"?raw.taskId:void 0}}function emptyStore(){return{version:1,repos:{}}}function nextIdFallback(entries){let max=0;for(let entry of entries){let id=Number(entry?.id);if(Number.isFinite(id)&&id>max)max=Math.trunc(id)}return max+1}function todayStamp(){let pinned=process.env.KOBE_ISSUES_TODAY;if(pinned&&/^\d{4}-\d{2}-\d{2}$/.test(pinned))return pinned;let d=new Date,mm=String(d.getMonth()+1).padStart(2,"0"),dd=String(d.getDate()).padStart(2,"0");return`${d.getFullYear()}-${mm}-${dd}`}async function resolveRepo(raw){if(typeof raw!=="string"||raw.length===0)throw Error("repoRoot is required");try{let{repoRoot,repoKey}=await resolveRepoRoot(raw);return{repoRoot:repoRoot??await gitTopLevel(resolve2(raw)),repoKey}}catch(err){if(isGitNotRepositoryError(err))throw Error("repoRoot is not a git repository");throw err}}function unreadableCount(raw){if(raw!==null&&typeof raw==="object"&&!Array.isArray(raw))return Math.max(1,Object.keys(raw).length);return 1}function readRecord(value){let record=value,base={repoRoot:typeof record.repoRoot==="string"?record.repoRoot:"",nextId:typeof record.nextId==="number"?record.nextId:1};if(record.issues!==void 0&&!Array.isArray(record.issues))return{record:{...base,issues:[],unusable:[],unreadable:{raw:value}},dropped:unreadableCount(record.issues)};let entries=Array.isArray(record.issues)?record.issues:[],issues=entries.map(normalizeIssue).filter((issue)=>issue!==null),unusable=entries.filter((entry)=>normalizeIssue(entry)===null);return{record:{repoRoot:base.repoRoot,nextId:typeof record.nextId==="number"?record.nextId:nextIdFallback(entries),issues,unusable},dropped:unusable.length}}async function readStore(path){try{let raw=JSON.parse(await readFile(path,"utf8")),repos={},skipped=new Map;if(raw.repos&&typeof raw.repos==="object")for(let[key,value]of Object.entries(raw.repos)){if(!value||typeof value!=="object")continue;let{record,dropped}=readRecord(value);if(dropped>0){skipped.set(key,dropped);let why=record.unreadable?'"issues" is not an array':"id is not a number";logDaemonError("issues-store-read",Error(`${key}: dropped ${dropped} unreadable issue entr${dropped===1?"y":"ies"} (${why})`))}repos[key]=record}return{file:{version:1,repos},skipped}}catch(err){if(err.code==="ENOENT")return{file:emptyStore(),skipped:new Map};throw Error(`${path}: ${err instanceof Error?err.message:String(err)}`)}}function serializeRecord(record){if(record.unreadable)return record.unreadable.raw;return{repoRoot:record.repoRoot,nextId:record.nextId,issues:[...record.issues,...record.unusable]}}async function writeStore(path,store){let repos={};for(let[key,record]of Object.entries(store.repos))repos[key]=serializeRecord(record);await writeJsonAtomic(path,{version:store.version,repos})}function response(repoRoot,record,skipped=0){return{repoRoot,exists:record!==null,nextId:record?.nextId??1,issues:record?.issues??[],skipped}}class IssuesStore{path;constructor(path=defaultIssuesStorePath()){this.path=path}async list(repo){let{repoRoot,repoKey}=await resolveRepo(repo);return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey]??null;if(record&&!record.unreadable&&record.repoRoot!==repoRoot)record.repoRoot=repoRoot,await writeStore(this.path,store);return response(repoRoot,record,skipped.get(repoKey)??0)})}async repos(){return serialized(this.path,async()=>{let{file}=await readStore(this.path);return Object.values(file.repos).map((record)=>record.repoRoot).filter((root)=>root.length>0)})}async mirrorTaskDone(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue||issue.status==="done")return null;return issue.status="done",record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async unlinkTask(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue)return null;return issue.taskId=void 0,record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async mutate(repo,op){let{repoRoot,repoKey}=await resolveRepo(repo);if(!op||typeof op!=="object"||Array.isArray(op)||typeof op.type!=="string")throw Error("missing op");return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)record={repoRoot,nextId:1,issues:[],unusable:[]},store.repos[repoKey]=record;if(record.unreadable)throw Error(`${ISSUE_STORE_UNREADABLE_CODE}: ${repoRoot}'s record in ${this.path} has a non-array "issues" \u2014 refusing to write over stories this build cannot read`);record.repoRoot=repoRoot;let typed=op;if(typed.type==="create"){if(typeof typed.title!=="string"||typed.title.trim().length===0)throw Error("create requires a non-empty title");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");record.issues=[{id:record.nextId,title:typed.title,status:"open",created:todayStamp(),body:typeof typed.body==="string"?typed.body:""},...record.issues],record.nextId+=1}else if(typed.type==="setStatus"){if(typeof typed.id!=="number")throw Error("setStatus requires a numeric id");if(!isValidStatus(typed.status))throw Error(`invalid status: must be one of ${ISSUE_STATUSES.join(", ")}`);let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.status=typed.status}else if(typed.type==="update"){if(typeof typed.id!=="number")throw Error("update requires a numeric id");if(typed.title!==void 0&&(typeof typed.title!=="string"||typed.title.trim().length===0))throw Error("title must be a non-empty string");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");if(typed.taskId!==void 0&&typed.taskId!==null&&(typeof typed.taskId!=="string"||typed.taskId.length===0))throw Error("taskId must be a non-empty string or null");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);if(typeof typed.title==="string")issue.title=typed.title;if(typeof typed.body==="string")issue.body=typed.body;if(typed.taskId!==void 0)issue.taskId=typed.taskId===null?void 0:typed.taskId}else if(typed.type==="link"){if(typeof typed.id!=="number")throw Error("link requires a numeric id");if(typeof typed.taskId!=="string"||typed.taskId.length===0)throw Error("link requires a non-empty taskId");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=typed.taskId}else if(typed.type==="unlink"){if(typeof typed.id!=="number")throw Error("unlink requires a numeric id");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=void 0}else if(typed.type==="delete"){if(typeof typed.id!=="number")throw Error("delete requires a numeric id");let nextIssues=record.issues.filter((i)=>i.id!==typed.id);if(nextIssues.length===record.issues.length)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);record.issues=nextIssues}else throw Error(`unknown op type: ${typed.type}`);return await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}}var MONTH_NAMES=new Map([["JAN",1],["FEB",2],["MAR",3],["APR",4],["MAY",5],["JUN",6],["JUL",7],["AUG",8],["SEP",9],["OCT",10],["NOV",11],["DEC",12]]),DAY_NAMES=new Map([["SUN",0],["MON",1],["TUE",2],["WED",3],["THU",4],["FRI",5],["SAT",6]]);function fieldNumber(raw,names,field){let token=raw.toUpperCase(),named=names?.get(token);if(named!==void 0)return named;if(!/^\d+$/.test(token))throw Error(`invalid cron ${field}: ${raw}`);return Number(token)}function parseField(args){let out=new Set;for(let part of args.value.split(",")){if(part.length===0)throw Error(`invalid cron ${args.field}: ${args.value}`);let[spec,stepRaw,...extra]=part.split("/");if(extra.length>0||spec===void 0)throw Error(`invalid cron ${args.field}: ${part}`);let step=1;if(stepRaw!==void 0){if(!/^\d+$/.test(stepRaw))throw Error(`invalid cron ${args.field} step: ${part}`);if(step=Number(stepRaw),step<1)throw Error(`invalid cron ${args.field} step: ${part}`)}let lo,hi;if(spec==="*")lo=args.min,hi=args.max;else if(spec.includes("-")){let[loRaw,hiRaw,...rest]=spec.split("-");if(rest.length>0||loRaw===void 0||hiRaw===void 0)throw Error(`invalid cron ${args.field} range: ${part}`);lo=fieldNumber(loRaw,args.names,args.field),hi=fieldNumber(hiRaw,args.names,args.field)}else lo=fieldNumber(spec,args.names,args.field),hi=stepRaw===void 0?lo:args.max;if(lo<args.min||hi>args.max||lo>hi)throw Error(`cron ${args.field} out of range: ${part}`);for(let v=lo;v<=hi;v+=step)out.add(args.normalize?args.normalize(v):v)}return out}function parseCron(expression){if(expression.length>256)throw Error("cron expression is too long");let fields=expression.trim().split(/\s+/).filter(Boolean);if(fields.length!==5)throw Error(`cron expression needs 5 fields (minute hour day month weekday), got ${fields.length}`);let[minute,hour,dayOfMonth,month,dayOfWeek]=fields;return{minutes:parseField({value:minute,min:0,max:59,field:"minute"}),hours:parseField({value:hour,min:0,max:23,field:"hour"}),daysOfMonth:parseField({value:dayOfMonth,min:1,max:31,field:"day-of-month"}),months:parseField({value:month,min:1,max:12,field:"month",names:MONTH_NAMES}),daysOfWeek:parseField({value:dayOfWeek,min:0,max:7,field:"weekday",names:DAY_NAMES,normalize:(v)=>v%7}),dayOfMonthRestricted:dayOfMonth!=="*",dayOfWeekRestricted:dayOfWeek!=="*"}}function isValidCron(expression){try{return parseCron(expression),!0}catch{return!1}}function instantOf(d,hour,minute){return new Date(d.year,d.month-1,d.day,hour,minute,0,0).getTime()}function localDayOf(ms){let d=new Date(ms);return{year:d.getFullYear(),month:d.getMonth()+1,day:d.getDate()}}function shiftDay(d,delta){return localDayOf(new Date(d.year,d.month-1,d.day+delta,12,0,0,0).getTime())}function dayMatches(rule,d){if(!rule.months.has(d.month))return!1;let domMatch=rule.daysOfMonth.has(d.day),dowMatch=rule.daysOfWeek.has(new Date(d.year,d.month-1,d.day).getDay());if(rule.dayOfMonthRestricted&&rule.dayOfWeekRestricted)return domMatch||dowMatch;if(rule.dayOfMonthRestricted)return domMatch;if(rule.dayOfWeekRestricted)return dowMatch;return!0}function floorToMinute(ms){return ms-ms%60000}function sorted(values,direction){return[...values].sort((a,b)=>(a-b)*direction)}function nextCronAfter(expression,afterMs){let rule=parseCron(expression),hours=sorted(rule.hours,1),minutes=sorted(rule.minutes,1),from=new Date(floorToMinute(afterMs)+60000),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(dayMatches(rule,day))for(let hour of hours){if(hour<fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute<fromMinute)continue;let at=instantOf(day,hour,minute);if(at>afterMs)return at}}day=shiftDay(day,1),fromHour=0,fromMinute=0}throw Error(`cron expression never matches: ${expression}`)}function latestCronAtOrBefore(expression,nowMs,notBeforeMs){if(nowMs<notBeforeMs)return null;let rule=parseCron(expression),hours=sorted(rule.hours,-1),minutes=sorted(rule.minutes,-1),from=new Date(floorToMinute(nowMs)),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(instantOf(day,23,59)<notBeforeMs)return null;if(dayMatches(rule,day))for(let hour of hours){if(hour>fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute>fromMinute)continue;let at=instantOf(day,hour,minute);if(at>nowMs)continue;return at>=notBeforeMs?at:null}}day=shiftDay(day,-1),fromHour=23,fromMinute=59}return null}function countCronBetween(expression,fromMs,beforeMs,cap=500){if(!(fromMs<beforeMs))return 0;let count=0,cursor=fromMs-1;while(count<cap){let at;try{at=nextCronAfter(expression,cursor)}catch{return count}if(at>=beforeMs)return count;count+=1,cursor=at}return count}
2
+ import{serialized,writeJsonAtomic}from"./chunk-xsrcwcjc.js";import{loadPluginRegistry,pluginConfigDir,pluginDataDir,pluginLogPath,pluginRegistryPath,pluginStateDir,pluginsRootDir}from"./chunk-zd46ghvd.js";import{logDaemonError}from"./chunk-rcyasw34.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE}from"./chunk-9prawccj.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import{chmodSync}from"fs";function tighten(path,mode){try{chmodSync(path,mode)}catch{}}function tightenPluginPermissions(id,homeDir){tighten(pluginDataDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginConfigDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginStateDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(`${pluginConfigDir(id,homeDir)}/.env`,OWNER_ONLY_FILE_MODE),tighten(pluginLogPath(id,homeDir),OWNER_ONLY_FILE_MODE)}function tightenInstalledPluginPermissions(homeDir){tighten(pluginsRootDir(homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginRegistryPath(homeDir),OWNER_ONLY_FILE_MODE);for(let entry of loadPluginRegistry(homeDir).plugins)tightenPluginPermissions(entry.id,homeDir)}import{execFile as execFile2}from"child_process";import{readFile}from"fs/promises";import{homedir}from"os";import{join,resolve as resolve2}from"path";import{promisify as promisify2}from"util";import{execFile}from"child_process";import{realpath,stat}from"fs/promises";import{isAbsolute,resolve}from"path";import{promisify}from"util";var execFileAsync=promisify(execFile);async function gitCommonDir(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--git-common-dir"]),dir=stdout.trim();return realpath(isAbsolute(dir)?dir:resolve(path,dir))}async function gitMainWorktree(path){let{stdout}=await execFileAsync("git",["-C",path,"worktree","list","--porcelain"]),first=stdout.split(/\r?\n/).find((line)=>line.startsWith("worktree "))?.slice(9).trim();return first?await realpath(first):null}async function gitTopLevel(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--show-toplevel"]);return stdout.trim()}async function resolveRepoRoot(raw){let absolute=resolve(raw);if(!(await stat(absolute).catch(()=>null))?.isDirectory())throw Error("repoRoot does not exist");let[repoRoot,repoKey]=await Promise.all([gitMainWorktree(absolute),gitCommonDir(absolute)]);return{repoRoot,repoKey}}var execFileAsync2=promisify2(execFile2),ISSUE_STATUSES=["open","doing","hold","done"],ISSUE_NOT_FOUND_CODE="ISSUE_NOT_FOUND",ISSUE_STORE_UNREADABLE_CODE="ISSUE_STORE_UNREADABLE";function isGitNotRepositoryError(err){return(err instanceof Error?err.message:String(err)).includes("not a git repository")}function defaultIssuesStorePath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"issues.json")}function isValidStatus(value){return typeof value==="string"&&ISSUE_STATUSES.includes(value)}function normalizeIssue(entry){if(entry===null||typeof entry!=="object"||Array.isArray(entry))return null;let raw=entry;if(typeof raw.id!=="number")return null;return{id:raw.id,title:typeof raw.title==="string"?raw.title:"(untitled)",status:isValidStatus(raw.status)?raw.status:"open",created:typeof raw.created==="string"?raw.created:"",body:typeof raw.body==="string"?raw.body:"",taskId:typeof raw.taskId==="string"?raw.taskId:void 0}}function emptyStore(){return{version:1,repos:{}}}function nextIdFallback(entries){let max=0;for(let entry of entries){let id=Number(entry?.id);if(Number.isFinite(id)&&id>max)max=Math.trunc(id)}return max+1}function todayStamp(){let pinned=process.env.KOBE_ISSUES_TODAY;if(pinned&&/^\d{4}-\d{2}-\d{2}$/.test(pinned))return pinned;let d=new Date,mm=String(d.getMonth()+1).padStart(2,"0"),dd=String(d.getDate()).padStart(2,"0");return`${d.getFullYear()}-${mm}-${dd}`}async function resolveRepo(raw){if(typeof raw!=="string"||raw.length===0)throw Error("repoRoot is required");try{let{repoRoot,repoKey}=await resolveRepoRoot(raw);return{repoRoot:repoRoot??await gitTopLevel(resolve2(raw)),repoKey}}catch(err){if(isGitNotRepositoryError(err))throw Error("repoRoot is not a git repository");throw err}}function unreadableCount(raw){if(raw!==null&&typeof raw==="object"&&!Array.isArray(raw))return Math.max(1,Object.keys(raw).length);return 1}function readRecord(value){let record=value,base={repoRoot:typeof record.repoRoot==="string"?record.repoRoot:"",nextId:typeof record.nextId==="number"?record.nextId:1};if(record.issues!==void 0&&!Array.isArray(record.issues))return{record:{...base,issues:[],unusable:[],unreadable:{raw:value}},dropped:unreadableCount(record.issues)};let entries=Array.isArray(record.issues)?record.issues:[],issues=entries.map(normalizeIssue).filter((issue)=>issue!==null),unusable=entries.filter((entry)=>normalizeIssue(entry)===null);return{record:{repoRoot:base.repoRoot,nextId:typeof record.nextId==="number"?record.nextId:nextIdFallback(entries),issues,unusable},dropped:unusable.length}}async function readStore(path){try{let raw=JSON.parse(await readFile(path,"utf8")),repos={},skipped=new Map;if(raw.repos&&typeof raw.repos==="object")for(let[key,value]of Object.entries(raw.repos)){if(!value||typeof value!=="object")continue;let{record,dropped}=readRecord(value);if(dropped>0){skipped.set(key,dropped);let why=record.unreadable?'"issues" is not an array':"id is not a number";logDaemonError("issues-store-read",Error(`${key}: dropped ${dropped} unreadable issue entr${dropped===1?"y":"ies"} (${why})`))}repos[key]=record}return{file:{version:1,repos},skipped}}catch(err){if(err.code==="ENOENT")return{file:emptyStore(),skipped:new Map};throw Error(`${path}: ${err instanceof Error?err.message:String(err)}`)}}function serializeRecord(record){if(record.unreadable)return record.unreadable.raw;return{repoRoot:record.repoRoot,nextId:record.nextId,issues:[...record.issues,...record.unusable]}}async function writeStore(path,store){let repos={};for(let[key,record]of Object.entries(store.repos))repos[key]=serializeRecord(record);await writeJsonAtomic(path,{version:store.version,repos})}function response(repoRoot,record,skipped=0){return{repoRoot,exists:record!==null,nextId:record?.nextId??1,issues:record?.issues??[],skipped}}class IssuesStore{path;constructor(path=defaultIssuesStorePath()){this.path=path}async list(repo){let{repoRoot,repoKey}=await resolveRepo(repo);return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey]??null;if(record&&!record.unreadable&&record.repoRoot!==repoRoot)record.repoRoot=repoRoot,await writeStore(this.path,store);return response(repoRoot,record,skipped.get(repoKey)??0)})}async repos(){return serialized(this.path,async()=>{let{file}=await readStore(this.path);return Object.values(file.repos).map((record)=>record.repoRoot).filter((root)=>root.length>0)})}async mirrorTaskDone(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue||issue.status==="done")return null;return issue.status="done",record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async unlinkTask(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue)return null;return issue.taskId=void 0,record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async mutate(repo,op){let{repoRoot,repoKey}=await resolveRepo(repo);if(!op||typeof op!=="object"||Array.isArray(op)||typeof op.type!=="string")throw Error("missing op");return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)record={repoRoot,nextId:1,issues:[],unusable:[]},store.repos[repoKey]=record;if(record.unreadable)throw Error(`${ISSUE_STORE_UNREADABLE_CODE}: ${repoRoot}'s record in ${this.path} has a non-array "issues" \u2014 refusing to write over stories this build cannot read`);record.repoRoot=repoRoot;let typed=op;if(typed.type==="create"){if(typeof typed.title!=="string"||typed.title.trim().length===0)throw Error("create requires a non-empty title");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");record.issues=[{id:record.nextId,title:typed.title,status:"open",created:todayStamp(),body:typeof typed.body==="string"?typed.body:""},...record.issues],record.nextId+=1}else if(typed.type==="setStatus"){if(typeof typed.id!=="number")throw Error("setStatus requires a numeric id");if(!isValidStatus(typed.status))throw Error(`invalid status: must be one of ${ISSUE_STATUSES.join(", ")}`);let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.status=typed.status}else if(typed.type==="update"){if(typeof typed.id!=="number")throw Error("update requires a numeric id");if(typed.title!==void 0&&(typeof typed.title!=="string"||typed.title.trim().length===0))throw Error("title must be a non-empty string");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");if(typed.taskId!==void 0&&typed.taskId!==null&&(typeof typed.taskId!=="string"||typed.taskId.length===0))throw Error("taskId must be a non-empty string or null");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);if(typeof typed.title==="string")issue.title=typed.title;if(typeof typed.body==="string")issue.body=typed.body;if(typed.taskId!==void 0)issue.taskId=typed.taskId===null?void 0:typed.taskId}else if(typed.type==="link"){if(typeof typed.id!=="number")throw Error("link requires a numeric id");if(typeof typed.taskId!=="string"||typed.taskId.length===0)throw Error("link requires a non-empty taskId");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=typed.taskId}else if(typed.type==="unlink"){if(typeof typed.id!=="number")throw Error("unlink requires a numeric id");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=void 0}else if(typed.type==="delete"){if(typeof typed.id!=="number")throw Error("delete requires a numeric id");let nextIssues=record.issues.filter((i)=>i.id!==typed.id);if(nextIssues.length===record.issues.length)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);record.issues=nextIssues}else throw Error(`unknown op type: ${typed.type}`);return await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}}var MONTH_NAMES=new Map([["JAN",1],["FEB",2],["MAR",3],["APR",4],["MAY",5],["JUN",6],["JUL",7],["AUG",8],["SEP",9],["OCT",10],["NOV",11],["DEC",12]]),DAY_NAMES=new Map([["SUN",0],["MON",1],["TUE",2],["WED",3],["THU",4],["FRI",5],["SAT",6]]);function fieldNumber(raw,names,field){let token=raw.toUpperCase(),named=names?.get(token);if(named!==void 0)return named;if(!/^\d+$/.test(token))throw Error(`invalid cron ${field}: ${raw}`);return Number(token)}function parseField(args){let out=new Set;for(let part of args.value.split(",")){if(part.length===0)throw Error(`invalid cron ${args.field}: ${args.value}`);let[spec,stepRaw,...extra]=part.split("/");if(extra.length>0||spec===void 0)throw Error(`invalid cron ${args.field}: ${part}`);let step=1;if(stepRaw!==void 0){if(!/^\d+$/.test(stepRaw))throw Error(`invalid cron ${args.field} step: ${part}`);if(step=Number(stepRaw),step<1)throw Error(`invalid cron ${args.field} step: ${part}`)}let lo,hi;if(spec==="*")lo=args.min,hi=args.max;else if(spec.includes("-")){let[loRaw,hiRaw,...rest]=spec.split("-");if(rest.length>0||loRaw===void 0||hiRaw===void 0)throw Error(`invalid cron ${args.field} range: ${part}`);lo=fieldNumber(loRaw,args.names,args.field),hi=fieldNumber(hiRaw,args.names,args.field)}else lo=fieldNumber(spec,args.names,args.field),hi=stepRaw===void 0?lo:args.max;if(lo<args.min||hi>args.max||lo>hi)throw Error(`cron ${args.field} out of range: ${part}`);for(let v=lo;v<=hi;v+=step)out.add(args.normalize?args.normalize(v):v)}return out}function parseCron(expression){if(expression.length>256)throw Error("cron expression is too long");let fields=expression.trim().split(/\s+/).filter(Boolean);if(fields.length!==5)throw Error(`cron expression needs 5 fields (minute hour day month weekday), got ${fields.length}`);let[minute,hour,dayOfMonth,month,dayOfWeek]=fields;return{minutes:parseField({value:minute,min:0,max:59,field:"minute"}),hours:parseField({value:hour,min:0,max:23,field:"hour"}),daysOfMonth:parseField({value:dayOfMonth,min:1,max:31,field:"day-of-month"}),months:parseField({value:month,min:1,max:12,field:"month",names:MONTH_NAMES}),daysOfWeek:parseField({value:dayOfWeek,min:0,max:7,field:"weekday",names:DAY_NAMES,normalize:(v)=>v%7}),dayOfMonthRestricted:dayOfMonth!=="*",dayOfWeekRestricted:dayOfWeek!=="*"}}function isValidCron(expression){try{return parseCron(expression),!0}catch{return!1}}function instantOf(d,hour,minute){return new Date(d.year,d.month-1,d.day,hour,minute,0,0).getTime()}function localDayOf(ms){let d=new Date(ms);return{year:d.getFullYear(),month:d.getMonth()+1,day:d.getDate()}}function shiftDay(d,delta){return localDayOf(new Date(d.year,d.month-1,d.day+delta,12,0,0,0).getTime())}function dayMatches(rule,d){if(!rule.months.has(d.month))return!1;let domMatch=rule.daysOfMonth.has(d.day),dowMatch=rule.daysOfWeek.has(new Date(d.year,d.month-1,d.day).getDay());if(rule.dayOfMonthRestricted&&rule.dayOfWeekRestricted)return domMatch||dowMatch;if(rule.dayOfMonthRestricted)return domMatch;if(rule.dayOfWeekRestricted)return dowMatch;return!0}function floorToMinute(ms){return ms-ms%60000}function sorted(values,direction){return[...values].sort((a,b)=>(a-b)*direction)}function nextCronAfter(expression,afterMs){let rule=parseCron(expression),hours=sorted(rule.hours,1),minutes=sorted(rule.minutes,1),from=new Date(floorToMinute(afterMs)+60000),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(dayMatches(rule,day))for(let hour of hours){if(hour<fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute<fromMinute)continue;let at=instantOf(day,hour,minute);if(at>afterMs)return at}}day=shiftDay(day,1),fromHour=0,fromMinute=0}throw Error(`cron expression never matches: ${expression}`)}function latestCronAtOrBefore(expression,nowMs,notBeforeMs){if(nowMs<notBeforeMs)return null;let rule=parseCron(expression),hours=sorted(rule.hours,-1),minutes=sorted(rule.minutes,-1),from=new Date(floorToMinute(nowMs)),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(instantOf(day,23,59)<notBeforeMs)return null;if(dayMatches(rule,day))for(let hour of hours){if(hour>fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute>fromMinute)continue;let at=instantOf(day,hour,minute);if(at>nowMs)continue;return at>=notBeforeMs?at:null}}day=shiftDay(day,-1),fromHour=23,fromMinute=59}return null}function countCronBetween(expression,fromMs,beforeMs,cap=500){if(!(fromMs<beforeMs))return 0;let count=0,cursor=fromMs-1;while(count<cap){let at;try{at=nextCronAfter(expression,cursor)}catch{return count}if(at>=beforeMs)return count;count+=1,cursor=at}return count}
3
3
  export{tightenPluginPermissions,tightenInstalledPluginPermissions,isValidCron,nextCronAfter,latestCronAtOrBefore,countCronBetween,resolveRepoRoot,ISSUE_STATUSES,defaultIssuesStorePath,IssuesStore};