@sma1lboy/rove 0.9.258-nightly.20261021 → 0.9.259

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 (120) hide show
  1. package/dist/cli/{chunk-8z0w75n6.js → chunk-0z1azqkp.js} +1 -1
  2. package/dist/cli/{chunk-fng64b9g.js → chunk-15jt6k82.js} +1 -1
  3. package/dist/cli/{chunk-76rph0by.js → chunk-1dcb0069.js} +1 -1
  4. package/dist/cli/{chunk-1rjmdg64.js → chunk-1dnyxp0v.js} +1 -1
  5. package/dist/cli/{chunk-ercztxdp.js → chunk-1j4e2jcx.js} +1 -1
  6. package/dist/cli/{chunk-jtpjdmb6.js → chunk-1x6yahf1.js} +1 -1
  7. package/dist/cli/{chunk-tq6pq1ws.js → chunk-2676cb62.js} +1 -1
  8. package/dist/cli/{chunk-2e50k2f8.js → chunk-3n2jn56j.js} +1 -1
  9. package/dist/cli/chunk-3v2hgjb2.js +3 -0
  10. package/dist/cli/{chunk-yktnbb14.js → chunk-3vtpshwx.js} +37 -37
  11. package/dist/cli/{chunk-a52epc2e.js → chunk-3yx6rrgm.js} +3 -3
  12. package/dist/cli/chunk-44ba9qvn.js +2 -0
  13. package/dist/cli/chunk-45yxyx4z.js +70 -0
  14. package/dist/cli/{chunk-9wj14tvj.js → chunk-4abka29v.js} +1 -1
  15. package/dist/cli/{chunk-wnvsxke8.js → chunk-4pmx2q7r.js} +1 -1
  16. package/dist/cli/chunk-4pt3n7cg.js +4 -0
  17. package/dist/cli/{chunk-h42aem5j.js → chunk-59hmb90m.js} +1 -1
  18. package/dist/cli/chunk-5c0dgs7n.js +2 -0
  19. package/dist/cli/{chunk-zam29b9x.js → chunk-5g3s1a2n.js} +1 -1
  20. package/dist/cli/{chunk-ke3t032y.js → chunk-5js4agdd.js} +1 -1
  21. package/dist/cli/{chunk-kszknq8t.js → chunk-5xeywdwg.js} +2 -2
  22. package/dist/cli/{chunk-0aewdrhc.js → chunk-5yv3jzc5.js} +1 -1
  23. package/dist/cli/{chunk-kqf371ff.js → chunk-601dsgex.js} +1 -1
  24. package/dist/cli/chunk-67stdpfn.js +2 -0
  25. package/dist/cli/{chunk-6p9yxt3q.js → chunk-6h12b2k0.js} +1 -1
  26. package/dist/cli/chunk-6q52d0nj.js +7 -0
  27. package/dist/cli/{chunk-6mxy7hxa.js → chunk-6v8rhkr8.js} +1 -1
  28. package/dist/cli/{chunk-enzv63cm.js → chunk-7rfy6zpw.js} +1 -1
  29. package/dist/cli/chunk-8sq09avz.js +2 -0
  30. package/dist/cli/{chunk-3bh6y25s.js → chunk-9ed3gqj9.js} +3 -3
  31. package/dist/cli/{chunk-h176cbnr.js → chunk-9f1xbpxn.js} +1 -1
  32. package/dist/cli/{chunk-20q7dz1d.js → chunk-9ztqf6hb.js} +1 -1
  33. package/dist/cli/{chunk-vqcww6xj.js → chunk-apm5yjkq.js} +1 -1
  34. package/dist/cli/{chunk-mq5a2shk.js → chunk-b41sj385.js} +1 -1
  35. package/dist/cli/chunk-bc4agaf1.js +2 -0
  36. package/dist/cli/{chunk-mc7hpma9.js → chunk-bdwp2k8f.js} +1 -1
  37. package/dist/cli/{chunk-z6h1erah.js → chunk-bkspbk0y.js} +1 -1
  38. package/dist/cli/{chunk-8gnbw6sr.js → chunk-bkt3ktvx.js} +1 -1
  39. package/dist/cli/{chunk-f43z6qax.js → chunk-btygchef.js} +1 -1
  40. package/dist/cli/chunk-c0gvp57p.js +3 -0
  41. package/dist/cli/{chunk-qn04z4zb.js → chunk-cc1mzr8d.js} +1 -1
  42. package/dist/cli/{chunk-95jzkqp2.js → chunk-dc3n6nf7.js} +1 -1
  43. package/dist/cli/{chunk-7vp7kmyg.js → chunk-e6848rj8.js} +1 -1
  44. package/dist/cli/{chunk-jt45r95x.js → chunk-ecngwr1v.js} +1 -1
  45. package/dist/cli/{chunk-jnbfahjs.js → chunk-efjahmtj.js} +1 -1
  46. package/dist/cli/chunk-emtbtym6.js +3 -0
  47. package/dist/cli/chunk-g1rqy0nz.js +2 -0
  48. package/dist/cli/{chunk-h213pdx2.js → chunk-h2vv63bh.js} +2 -2
  49. package/dist/cli/{chunk-xk22erkp.js → chunk-hqkzc8cv.js} +1 -1
  50. package/dist/cli/{chunk-5zzqf9w3.js → chunk-hwbpbp0c.js} +1 -1
  51. package/dist/cli/{chunk-k9v0bjkm.js → chunk-hynv8c2k.js} +1 -1
  52. package/dist/cli/{chunk-kkts9g9r.js → chunk-j5w8n1st.js} +1 -1
  53. package/dist/cli/{chunk-gcsaman1.js → chunk-jbndzrbw.js} +1 -1
  54. package/dist/cli/chunk-jfbnz454.js +2 -0
  55. package/dist/cli/{chunk-97vzk1wc.js → chunk-jj3nbb2g.js} +4 -4
  56. package/dist/cli/{chunk-n927xqjp.js → chunk-jtf8qstz.js} +1 -1
  57. package/dist/cli/{chunk-216scxtw.js → chunk-jzf2d1pj.js} +1 -1
  58. package/dist/cli/{chunk-59vdqeb8.js → chunk-k3b5cnd5.js} +12 -12
  59. package/dist/cli/{chunk-tg6b8rxw.js → chunk-kcefxpn1.js} +1 -1
  60. package/dist/cli/chunk-n3br556t.js +11 -0
  61. package/dist/cli/{chunk-zsrnxaca.js → chunk-ndbxpd01.js} +3 -3
  62. package/dist/cli/{chunk-gb0zp7sb.js → chunk-ngc1n7h3.js} +1 -1
  63. package/dist/cli/{chunk-7cd1epfw.js → chunk-nxdm60xy.js} +1 -1
  64. package/dist/cli/{chunk-08hhcnn5.js → chunk-p27ph0g8.js} +1 -1
  65. package/dist/cli/chunk-pbfehk8q.js +3 -0
  66. package/dist/cli/{chunk-kc1mz9av.js → chunk-pgbsb202.js} +1 -1
  67. package/dist/cli/{chunk-emz4gsxn.js → chunk-pw9teydh.js} +1 -1
  68. package/dist/cli/{chunk-sma961wh.js → chunk-q07r6hf7.js} +1 -1
  69. package/dist/cli/{chunk-b87rv8pt.js → chunk-q2kweazg.js} +8 -7
  70. package/dist/cli/chunk-qpvvc1xz.js +4 -0
  71. package/dist/cli/{chunk-ncft9z07.js → chunk-qtewm0jz.js} +1 -1
  72. package/dist/cli/chunk-r3zkpbf5.js +9 -0
  73. package/dist/cli/{chunk-43axwy2j.js → chunk-rsvh7n8v.js} +1 -1
  74. package/dist/cli/chunk-s83qnstd.js +2 -0
  75. package/dist/cli/{chunk-sshbw3q8.js → chunk-sh5a4djc.js} +1 -1
  76. package/dist/cli/{chunk-9ch2hcdy.js → chunk-smqmpz5c.js} +1 -1
  77. package/dist/cli/chunk-sqks9vyt.js +2 -0
  78. package/dist/cli/{chunk-yjyjg7sk.js → chunk-stng29vp.js} +2 -2
  79. package/dist/cli/{chunk-80zzjcvp.js → chunk-syqbc3a3.js} +1 -1
  80. package/dist/cli/chunk-wg9w0xf4.js +3 -0
  81. package/dist/cli/{chunk-v7prawj1.js → chunk-wqcs5mz0.js} +1 -1
  82. package/dist/cli/chunk-wv6d96t6.js +2 -0
  83. package/dist/cli/{chunk-v0cr4yy4.js → chunk-wv8vfhty.js} +1 -1
  84. package/dist/cli/{chunk-ddsgyhk3.js → chunk-xpr9sf8t.js} +3 -3
  85. package/dist/cli/chunk-ymq20jvp.js +62 -0
  86. package/dist/cli/{chunk-79r3wbhh.js → chunk-ywtsqm67.js} +1 -1
  87. package/dist/cli/chunk-z3qhpthz.js +3 -0
  88. package/dist/cli/{chunk-jetsx9zr.js → chunk-zae59k1j.js} +1 -1
  89. package/dist/cli/index.js +4 -4
  90. package/dist/cli/rove.js +1 -1
  91. package/dist/completions/rove.bash +2 -2
  92. package/dist/completions/rove.fish +2 -2
  93. package/dist/completions/rove.zsh +2 -2
  94. package/dist/skills/rove/SKILL.md +1 -1
  95. package/dist/skills/rove/references/api-flags.md +14 -12
  96. package/dist/web/assets/index-B4sS_af0.js +109 -0
  97. package/dist/web/assets/index-znAxiX5H.css +1 -0
  98. package/dist/web/index.html +2 -2
  99. package/package.json +3 -3
  100. package/dist/cli/chunk-1378mh2w.js +0 -3
  101. package/dist/cli/chunk-1qge84t7.js +0 -3
  102. package/dist/cli/chunk-1vxykwb9.js +0 -3
  103. package/dist/cli/chunk-2yjpqb47.js +0 -3
  104. package/dist/cli/chunk-41wny9cn.js +0 -2
  105. package/dist/cli/chunk-6t5d02s4.js +0 -2
  106. package/dist/cli/chunk-7nr405tr.js +0 -9
  107. package/dist/cli/chunk-80ct34zy.js +0 -3
  108. package/dist/cli/chunk-evz11ctk.js +0 -2
  109. package/dist/cli/chunk-h2q93pzr.js +0 -2
  110. package/dist/cli/chunk-h2z9mbff.js +0 -2
  111. package/dist/cli/chunk-h7qqxsj9.js +0 -11
  112. package/dist/cli/chunk-kmbr7gr8.js +0 -31
  113. package/dist/cli/chunk-kxm5gymn.js +0 -2
  114. package/dist/cli/chunk-n2jbwg6c.js +0 -52
  115. package/dist/cli/chunk-na2r7vyk.js +0 -6
  116. package/dist/cli/chunk-q301ewyq.js +0 -2
  117. package/dist/cli/chunk-q5qbv53n.js +0 -4
  118. package/dist/cli/chunk-x7cv6deh.js +0 -2
  119. package/dist/web/assets/index-BiUiNIOp.css +0 -1
  120. package/dist/web/assets/index-jy27XaL0.js +0 -109
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{REPEAT_SEP,VerbArgs,defaultApiRuntime,findVerb,parseFlags,unknownVerbError,validateAgainstSpec}from"./chunk-b87rv8pt.js";import{ensurePluginEnginesLoaded}from"./chunk-t60qcvcj.js";import{ApiError,cliCaller,splitDaemonCode}from"./chunk-x7r75e3p.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{ROVE_API_VERSION}from"./chunk-278sc87n.js";function toApiError(err){if(err instanceof ApiError)return err;let message=errorMessage(err);if(/task not found/i.test(message))return new ApiError(message,"TASK_NOT_FOUND",{hint:"that task id does not exist (deleted or mistyped) \u2014 list live tasks and retry with a real id",nextCommandArgs:["api","list"]});if(/unknown daemon request:/i.test(message))return versionSkewError(message);let coded=splitDaemonCode(message);if(coded)return new ApiError(coded.rest,coded.code);return new ApiError(message,"RPC_ERROR")}function versionSkewError(message){return new ApiError(message,"DAEMON_VERSION_SKEW",{hint:"the running daemon is a different build than this CLI, so it does not serve this verb \u2014 restart the daemon to pick up this build, then retry (if the verb is gone for good, `rove api schema` lists what this daemon actually serves)",nextCommandArgs:["daemon","restart"]})}function errorBody(err){return{message:err.message,code:err.code,...err.data}}function successEnvelope(result){return{apiVersion:ROVE_API_VERSION,ok:!0,result}}function errorEnvelope(err){return{apiVersion:ROVE_API_VERSION,ok:!1,error:errorBody(toApiError(err))}}function flagText(name,spec,value){let type=spec?.type;if(typeof value==="string")return value;if(spec?.repeatable&&Array.isArray(value)&&value.every((item)=>typeof item==="string"))return value.join(REPEAT_SEP);if(typeof value==="boolean"&&(type==="bool"||type===void 0))return String(value);if(typeof value==="number"&&(type==="int"||type==="uint"||type===void 0))return String(value);if(Array.isArray(value)&&(type==="csv"||type===void 0)){if(!value.every((item)=>typeof item==="string"&&!item.includes(",")))throw new ApiError(`param ${name} must be a list of strings without ","`,"BAD_FLAG");return value.join(",")}throw new ApiError(`param ${name} does not fit its ${type} flag`,"BAD_FLAG")}function paramsToFlags(verb,params){let flags=new Map;for(let[name,value]of Object.entries(params))flags.set(name,flagText(name,verb.flags.find((f)=>f.name===name),value));return flags}function booleanFlagsOf(verb){return new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name))}function repeatableFlagsOf(verb){return new Set(verb.flags.filter((f)=>f.repeatable).map((f)=>f.name))}async function callVerb(verb,flags,deps){let caller=deps.caller??cliCaller();try{return await verb.handler({args:new VerbArgs(verb,flags,caller),caller,client:deps.client,runtime:deps.runtime??defaultApiRuntime})}catch(err){throw toApiError(err)}}async function runVerb(verbName,input,deps){ensurePluginEnginesLoaded();let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);if(verb.cliOnly&&!(deps.caller??cliCaller()).cli)throw new ApiError(`"${verbName}" streams over stdout/stdin, so only \`rove api\` can run it`,"CLI_ONLY_VERB",{hint:"run it as a CLI command on the machine whose daemon you are talking to"});let flags="argv"in input?parseFlags(input.argv,booleanFlagsOf(verb),repeatableFlagsOf(verb)).flags:paramsToFlags(verb,input.params);return validateAgainstSpec(verb,flags),callVerb(verb,flags,deps)}async function executeVerb(verbName,input,deps){try{return successEnvelope(await runVerb(verbName,input,deps))}catch(err){return errorEnvelope(err)}}function argvToParams(verbName,argv){let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);let{flags}=parseFlags(argv,booleanFlagsOf(verb),repeatableFlagsOf(verb));return Object.fromEntries(flags)}
2
+ import{REPEAT_SEP,VerbArgs,defaultApiRuntime,findVerb,parseFlags,unknownVerbError,validateAgainstSpec}from"./chunk-q2kweazg.js";import{ensurePluginEnginesLoaded}from"./chunk-t60qcvcj.js";import{ApiError,cliCaller,splitDaemonCode}from"./chunk-x7r75e3p.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{ROVE_API_VERSION}from"./chunk-278sc87n.js";function toApiError(err){if(err instanceof ApiError)return err;let message=errorMessage(err);if(/task not found/i.test(message))return new ApiError(message,"TASK_NOT_FOUND",{hint:"that task id does not exist (deleted or mistyped) \u2014 list live tasks and retry with a real id",nextCommandArgs:["api","list"]});if(/unknown daemon request:/i.test(message))return versionSkewError(message);let coded=splitDaemonCode(message);if(coded)return new ApiError(coded.rest,coded.code);return new ApiError(message,"RPC_ERROR")}function versionSkewError(message){return new ApiError(message,"DAEMON_VERSION_SKEW",{hint:"the running daemon is a different build than this CLI, so it does not serve this verb \u2014 restart the daemon to pick up this build, then retry (if the verb is gone for good, `rove api schema` lists what this daemon actually serves)",nextCommandArgs:["daemon","restart"]})}function errorBody(err){return{message:err.message,code:err.code,...err.data}}function successEnvelope(result){return{apiVersion:ROVE_API_VERSION,ok:!0,result}}function errorEnvelope(err){return{apiVersion:ROVE_API_VERSION,ok:!1,error:errorBody(toApiError(err))}}function flagText(name,spec,value){let type=spec?.type;if(typeof value==="string")return value;if(spec?.repeatable&&Array.isArray(value)&&value.every((item)=>typeof item==="string"))return value.join(REPEAT_SEP);if(typeof value==="boolean"&&(type==="bool"||type===void 0))return String(value);if(typeof value==="number"&&(type==="int"||type==="uint"||type===void 0))return String(value);if(Array.isArray(value)&&(type==="csv"||type===void 0)){if(!value.every((item)=>typeof item==="string"&&!item.includes(",")))throw new ApiError(`param ${name} must be a list of strings without ","`,"BAD_FLAG");return value.join(",")}throw new ApiError(`param ${name} does not fit its ${type} flag`,"BAD_FLAG")}function paramsToFlags(verb,params){let flags=new Map;for(let[name,value]of Object.entries(params))flags.set(name,flagText(name,verb.flags.find((f)=>f.name===name),value));return flags}function booleanFlagsOf(verb){return new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name))}function repeatableFlagsOf(verb){return new Set(verb.flags.filter((f)=>f.repeatable).map((f)=>f.name))}async function callVerb(verb,flags,deps){let caller=deps.caller??cliCaller();try{return await verb.handler({args:new VerbArgs(verb,flags,caller),caller,client:deps.client,runtime:deps.runtime??defaultApiRuntime})}catch(err){throw toApiError(err)}}async function runVerb(verbName,input,deps){ensurePluginEnginesLoaded();let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);if(verb.cliOnly&&!(deps.caller??cliCaller()).cli)throw new ApiError(`"${verbName}" streams over stdout/stdin, so only \`rove api\` can run it`,"CLI_ONLY_VERB",{hint:"run it as a CLI command on the machine whose daemon you are talking to"});let flags="argv"in input?parseFlags(input.argv,booleanFlagsOf(verb),repeatableFlagsOf(verb)).flags:paramsToFlags(verb,input.params);return validateAgainstSpec(verb,flags),callVerb(verb,flags,deps)}async function executeVerb(verbName,input,deps){try{return successEnvelope(await runVerb(verbName,input,deps))}catch(err){return errorEnvelope(err)}}function argvToParams(verbName,argv){let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);let{flags}=parseFlags(argv,booleanFlagsOf(verb),repeatableFlagsOf(verb));return Object.fromEntries(flags)}
3
3
  export{toApiError,errorBody,successEnvelope,errorEnvelope,paramsToFlags,booleanFlagsOf,repeatableFlagsOf,callVerb,runVerb,executeVerb,argvToParams};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{BREAKING_VERSIONS,CURRENT_VERSION,compareSemver}from"./chunk-xk22erkp.js";import{loadStateFile,patchStateFile}from"./chunk-g4281a0g.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";var LAST_RUN_VERSION_KEY="app.lastRunVersion";function resetGateBlockers(lastRun,current=CURRENT_VERSION,breaking=BREAKING_VERSIONS){if(typeof lastRun!=="string"||lastRun.length===0)return[];let[lo,hi]=compareSemver(lastRun,current)<=0?[lastRun,current]:[current,lastRun];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}function enforceResetGate(){let cliName=ROVE_PRODUCT_NAME,lastRun=loadStateFile()[LAST_RUN_VERSION_KEY],blockers=resetGateBlockers(lastRun);if(blockers.length>0){let from=typeof lastRun==="string"?lastRun:"unknown";console.error([`${cliName} ${CURRENT_VERSION}: cannot start \u2014 version ${blockers.join(", ")} introduced breaking changes`,`(last run: ${from}). Your daemon/session state may be incompatible.`,"","Run:",` ${cliName} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${cliName} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
2
+ import{BREAKING_VERSIONS,CURRENT_VERSION,compareSemver}from"./chunk-hqkzc8cv.js";import{loadStateFile,patchStateFile}from"./chunk-g4281a0g.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";var LAST_RUN_VERSION_KEY="app.lastRunVersion";function resetGateBlockers(lastRun,current=CURRENT_VERSION,breaking=BREAKING_VERSIONS){if(typeof lastRun!=="string"||lastRun.length===0)return[];let[lo,hi]=compareSemver(lastRun,current)<=0?[lastRun,current]:[current,lastRun];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}function enforceResetGate(){let cliName=ROVE_PRODUCT_NAME,lastRun=loadStateFile()[LAST_RUN_VERSION_KEY],blockers=resetGateBlockers(lastRun);if(blockers.length>0){let from=typeof lastRun==="string"?lastRun:"unknown";console.error([`${cliName} ${CURRENT_VERSION}: cannot start \u2014 version ${blockers.join(", ")} introduced breaking changes`,`(last run: ${from}). Your daemon/session state may be incompatible.`,"","Run:",` ${cliName} reset # stop daemon + PTY host + sessions (tasks kept)`,` ${cliName} reset --hard # additionally wipe the task index + UI state`,"","Then relaunch Rove. Worktrees are never touched."].join(`
3
3
  `)),process.exit(1)}if(lastRun!==CURRENT_VERSION)stampResetGate()}function stampResetGate(){try{patchStateFile({[LAST_RUN_VERSION_KEY]:CURRENT_VERSION})}catch{}}
4
4
  export{LAST_RUN_VERSION_KEY,enforceResetGate,stampResetGate};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{closeTab,engineTabArgv,initialTabs,setTabTitle,tabPtyKeyFor,terminalTabsKey}from"./chunk-20q7dz1d.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors,sessionArgvNamesEngine}from"./chunk-43axwy2j.js";import{engineLaunchArgv}from"./chunk-q5qbv53n.js";import{engineProcessIn,parsePsSnapshot,psSnapshot,vendorFromArgv}from"./chunk-mc7hpma9.js";import{ApiError}from"./chunk-x7r75e3p.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-g4281a0g.js";import{basename}from"path";function wireNode(node){if(node.kind==="leaf")return{kind:"leaf",id:node.id,title:node.title??null,own:node.content===null};return{kind:"group",orientation:node.orientation,children:node.children.map(wireNode)}}function wireSplit(tree){return tree?{root:wireNode(tree.root),activeLeafId:tree.activeLeafId}:null}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=tabPtyKeyFor(taskId,t),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,...t.splitTree?{split:wireSplit(t.splitTree)}:{},...t.kind==="engine"&&t.ptyTask?{viewOf:t.ptyTask.id}:{}}});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);updateStateFile((store)=>{let existing=store[key];if(!existing||!Array.isArray(existing.tabs))return!1;store[key]={...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,...sessionId?{sessionId}:{},spawned:!0}:t)};return})}catch{}}function allocateTab(taskId,build,taken=new Set){let key=terminalTabsKey(taskId),out={};if(updateStateFile((store)=>{let existing=store[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;while(taken.has(`tab-${ordinal}`)||state.tabs.some((t)=>t.id===`tab-${ordinal}`))ordinal++;let tab=build(`tab-${ordinal}`,ordinal);out.tab=tab,store[key]={...state,tabs:[...state.tabs,tab],activeId:tab.id,nextOrdinal:ordinal+1};return}),!out.tab)throw Error(`tab allocation for ${taskId} did not run`);return out.tab}function mintCliTab(taskId,vendor,command){try{return allocateTab(taskId,(id,ordinal)=>({kind:"engine",id,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}})).id}catch{return`tab-cli-${Date.now().toString(36)}`}}async function countLiveEngineSessions(sessions,snapshot=psSnapshot){let tabs=sessions.filter((s)=>s.alive&&s.key.split("::").length===2);if(!tabs.length)return 0;let rows;try{if(rows=parsePsSnapshot(await snapshot(tabs.flatMap((s)=>s.pid?[s.pid]:[]))),!rows.length)return tabs.length}catch{return tabs.length}return tabs.filter((s)=>{if(!s.pid)return!0;let root=rows.find((row)=>row.pid===s.pid);if(!root)return!0;if(engineProcessIn(rows,s.pid)||vendorFromArgv(root.args))return!0;let[taskId,tabId]=s.key.split("::"),labelled=readTabsSnapshot(taskId)?.tabs.some((tab)=>tab.id===tabId&&tab.kind==="engine");if(tabId!=="tab-1"&&!labelled&&!sessionArgvNamesEngine(s.command))return!1;let executable=basename(root.args.split(/\s+/)[0]).toLowerCase().replace(/^-/,"").replace(/\.exe$/,"");if(["sh","bash","zsh","fish","dash","ash","ksh","mksh"].includes(executable))return/^\S+\s+-[a-zA-Z]*c\b/.test(root.args);return!0}).length}async function openAdmittedEngine(rpc,spec,opts){let limit=opts.maxLiveEngines;if(limit===void 0)return rpc.request("pty.open",spec);for(let attempt=0;attempt<20;attempt++){let{sessions,admissionToken}=await rpc.request("pty.list",{});if(typeof admissionToken!=="string")throw new ApiError("the PTY host must be updated before enforcing engine.maxLiveSessions","ENGINE_ADMISSION_UNAVAILABLE",{taskId:opts.taskId,hint:"the running PTY host predates atomic admission; update and restart the PTY host before retrying",nextCommandArgs:opts.retryArgs});let live=await countLiveEngineSessions(sessions,opts.snapshot);if(!sessions.some((s)=>s.key===spec.key&&s.alive)&&live>=limit)throw new ApiError(`${live} engine sessions are already running (engine.maxLiveSessions is ${limit})`,"ENGINE_LIMIT",{taskId:opts.taskId,live,limit,hint:"wait for an engine to finish or close a tab, then retry; raise engine.maxLiveSessions in state.json to allow more",nextCommandArgs:opts.retryArgs});let result=await rpc.request("pty.openChecked",{...spec,admissionToken});if(result.kind==="opened")return result.open}throw new ApiError("PTY inventory kept changing during engine admission; retry the send","ENGINE_ADMISSION_BUSY",{taskId:opts.taskId,nextCommandArgs:opts.retryArgs})}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","--plain","--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 openAdmittedEngine(rpc,{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()},{maxLiveEngines:opts?.maxLiveEngines,snapshot:opts?.snapshot,taskId:target.id,retryArgs:opts?.retryArgs??["api","send","--task-id",target.id,...opts?.forceNew?["--tab","new"]:[],"--plain","--prompt",prompt]});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,tabPtyKeyFor,terminalTabsKey}from"./chunk-9ztqf6hb.js";import{awaitEngineProcess,buildEngineSessionLaunch,deliverToHostedKey,enginePresence,ensureHostedSessionHost,findHostedEngineKey,hostedSessionFailureLine,hostedTaskKeys,initMarkerSaysFinished,isHostedTaskKey,killHostedSessions,listHostedSessions,listHostedSessionsOrNull,openHostedSessionHost,pastePromptWhenEngineUp,readPersistedTerminalDefaultColors,sessionArgvNamesEngine}from"./chunk-rsvh7n8v.js";import{engineLaunchArgv}from"./chunk-pbfehk8q.js";import{engineProcessIn,parsePsSnapshot,psSnapshot,vendorFromArgv}from"./chunk-bdwp2k8f.js";import{ApiError}from"./chunk-x7r75e3p.js";import{loadStateFile,patchStateFile,updateStateFile}from"./chunk-g4281a0g.js";import{basename}from"path";function wireNode(node){if(node.kind==="leaf")return{kind:"leaf",id:node.id,title:node.title??null,own:node.content===null};return{kind:"group",orientation:node.orientation,children:node.children.map(wireNode)}}function wireSplit(tree){return tree?{root:wireNode(tree.root),activeLeafId:tree.activeLeafId}:null}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=tabPtyKeyFor(taskId,t),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,...t.splitTree?{split:wireSplit(t.splitTree)}:{},...t.kind==="engine"&&t.ptyTask?{viewOf:t.ptyTask.id}:{}}});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);updateStateFile((store)=>{let existing=store[key];if(!existing||!Array.isArray(existing.tabs))return!1;store[key]={...existing,tabs:existing.tabs.map((t)=>t.id===tabId&&t.kind==="engine"?{...t,...sessionId?{sessionId}:{},spawned:!0}:t)};return})}catch{}}function allocateTab(taskId,build,taken=new Set){let key=terminalTabsKey(taskId),out={};if(updateStateFile((store)=>{let existing=store[key],state=existing&&Array.isArray(existing.tabs)&&existing.tabs.length>0?existing:initialTabs(),ordinal=typeof state.nextOrdinal==="number"&&state.nextOrdinal>1?state.nextOrdinal:2;while(taken.has(`tab-${ordinal}`)||state.tabs.some((t)=>t.id===`tab-${ordinal}`))ordinal++;let tab=build(`tab-${ordinal}`,ordinal);out.tab=tab,store[key]={...state,tabs:[...state.tabs,tab],activeId:tab.id,nextOrdinal:ordinal+1};return}),!out.tab)throw Error(`tab allocation for ${taskId} did not run`);return out.tab}function mintCliTab(taskId,vendor,command){try{return allocateTab(taskId,(id,ordinal)=>({kind:"engine",id,title:null,ordinal,...vendor?{vendor}:{},...command?{engineCommand:command}:{}})).id}catch{return`tab-cli-${Date.now().toString(36)}`}}async function countLiveEngineSessions(sessions,snapshot=psSnapshot){let tabs=sessions.filter((s)=>s.alive&&s.key.split("::").length===2);if(!tabs.length)return 0;let rows;try{if(rows=parsePsSnapshot(await snapshot(tabs.flatMap((s)=>s.pid?[s.pid]:[]))),!rows.length)return tabs.length}catch{return tabs.length}return tabs.filter((s)=>{if(!s.pid)return!0;let root=rows.find((row)=>row.pid===s.pid);if(!root)return!0;if(engineProcessIn(rows,s.pid)||vendorFromArgv(root.args))return!0;let[taskId,tabId]=s.key.split("::"),labelled=readTabsSnapshot(taskId)?.tabs.some((tab)=>tab.id===tabId&&tab.kind==="engine");if(tabId!=="tab-1"&&!labelled&&!sessionArgvNamesEngine(s.command))return!1;let executable=basename(root.args.split(/\s+/)[0]).toLowerCase().replace(/^-/,"").replace(/\.exe$/,"");if(["sh","bash","zsh","fish","dash","ash","ksh","mksh"].includes(executable))return/^\S+\s+-[a-zA-Z]*c\b/.test(root.args);return!0}).length}async function openAdmittedEngine(rpc,spec,opts){let limit=opts.maxLiveEngines;if(limit===void 0)return rpc.request("pty.open",spec);for(let attempt=0;attempt<20;attempt++){let{sessions,admissionToken}=await rpc.request("pty.list",{});if(typeof admissionToken!=="string")throw new ApiError("the PTY host must be updated before enforcing engine.maxLiveSessions","ENGINE_ADMISSION_UNAVAILABLE",{taskId:opts.taskId,hint:"the running PTY host predates atomic admission; update and restart the PTY host before retrying",nextCommandArgs:opts.retryArgs});let live=await countLiveEngineSessions(sessions,opts.snapshot);if(!sessions.some((s)=>s.key===spec.key&&s.alive)&&live>=limit)throw new ApiError(`${live} engine sessions are already running (engine.maxLiveSessions is ${limit})`,"ENGINE_LIMIT",{taskId:opts.taskId,live,limit,hint:"wait for an engine to finish or close a tab, then retry; raise engine.maxLiveSessions in state.json to allow more",nextCommandArgs:opts.retryArgs});let result=await rpc.request("pty.openChecked",{...spec,admissionToken});if(result.kind==="opened")return result.open}throw new ApiError("PTY inventory kept changing during engine admission; retry the send","ENGINE_ADMISSION_BUSY",{taskId:opts.taskId,nextCommandArgs:opts.retryArgs})}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","--plain","--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 openAdmittedEngine(rpc,{key:launch.key,cwd,command:launch.command,defaultColors:readPersistedTerminalDefaultColors()},{maxLiveEngines:opts?.maxLiveEngines,snapshot:opts?.snapshot,taskId:target.id,retryArgs:opts?.retryArgs??["api","send","--task-id",target.id,...opts?.forceNew?["--tab","new"]:[],"--plain","--prompt",prompt]});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{wireSplit,taskEngineArgv,readTabsSnapshot,closeTabsSnapshot,renameTabsSnapshot,unregisteredTabIds,joinTaskTabs,publishCliTabSnapshot,markCliTabSession,allocateTab,mintCliTab,openAdmittedEngine,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{ensureGlobalRoveHooks,readStdinText,readTextWithTimeout,runHookSubcommand}from"./chunk-n927xqjp.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-edsm15ht.js";import"./chunk-jnbfahjs.js";import"./chunk-2tfnscxk.js";import"./chunk-9ecnsh42.js";import"./chunk-w7zv47mp.js";import"./chunk-zsfyj36g.js";import"./chunk-kqf371ff.js";import"./chunk-1vwngrmf.js";import"./chunk-yktnbb14.js";import"./chunk-2brn8e1y.js";import"./chunk-8gnbw6sr.js";import"./chunk-7zyyvc3d.js";import"./chunk-r6k3ve2g.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-tdhk4dz8.js";import"./chunk-22d0yc7m.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-g4281a0g.js";import"./chunk-zh0c8yzw.js";import"./chunk-wqckm0k6.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-s0jbtyd9.js";import"./chunk-278sc87n.js";import"./chunk-gskbzgc3.js";import"./chunk-pn5ygqn6.js";import"./chunk-n0rtj4z7.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{runHookSubcommand,readTextWithTimeout,readStdinText,ensureGlobalRoveHooks};
2
+ import{ensureGlobalRoveHooks,readStdinText,readTextWithTimeout,runHookSubcommand}from"./chunk-jtf8qstz.js";import"./chunk-17e2tgyg.js";import"./chunk-2bgmby1d.js";import"./chunk-edsm15ht.js";import"./chunk-efjahmtj.js";import"./chunk-2tfnscxk.js";import"./chunk-9ecnsh42.js";import"./chunk-w7zv47mp.js";import"./chunk-zsfyj36g.js";import"./chunk-601dsgex.js";import"./chunk-1vwngrmf.js";import"./chunk-3vtpshwx.js";import"./chunk-2brn8e1y.js";import"./chunk-bkt3ktvx.js";import"./chunk-7zyyvc3d.js";import"./chunk-r6k3ve2g.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-7ghwdjdc.js";import"./chunk-tdhk4dz8.js";import"./chunk-22d0yc7m.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-g4281a0g.js";import"./chunk-zh0c8yzw.js";import"./chunk-wqckm0k6.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-s0jbtyd9.js";import"./chunk-278sc87n.js";import"./chunk-gskbzgc3.js";import"./chunk-pn5ygqn6.js";import"./chunk-n0rtj4z7.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{runHookSubcommand,readTextWithTimeout,readStdinText,ensureGlobalRoveHooks};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{execHostForWorktreePath}from"./chunk-ampdybqg.js";import{protocolEntry}from"./chunk-q5qbv53n.js";import{parseNumstatRows}from"./chunk-t7j8g9f6.js";import{parsePorcelainRows,unquoteGitPath}from"./chunk-dmzg9zdc.js";import{readHeadSha,resolveGitDirs}from"./chunk-kg9kmwt9.js";import{READ_ONLY_GIT_ENV}from"./chunk-6xppe9bj.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{isObject}from"./chunk-7ghwdjdc.js";import{getPersistedString,getPersistedValue}from"./chunk-22d0yc7m.js";import{recordSpawn}from"./chunk-40dgv828.js";import{acquireSync,releaseSync}from"./chunk-zh0c8yzw.js";import{secretsPath}from"./chunk-prqeddy7.js";import{t}from"./chunk-tq6pq1ws.js";async function runWorktreeGit(worktreePath,args,options={}){if(!worktreePath)return{stdout:"",stderr:"worktreePath is required",status:-1};let exec=(options.execForPath??execHostForWorktreePath)(worktreePath),controller=options.timeoutMs&&options.timeoutMs>0?new AbortController:null,timedOut=!1,timer=controller?setTimeout(()=>{timedOut=!0,controller.abort()},options.timeoutMs):null,signal=controller&&options.signal?AbortSignal.any([controller.signal,options.signal]):controller?.signal??options.signal,result;try{recordSpawn("worktree.content",["git",...args],worktreePath),result=await exec.run(["git",...args],{cwd:worktreePath,env:READ_ONLY_GIT_ENV,signal})}catch(err){if(timer)clearTimeout(timer);return{stdout:"",stderr:errorMessage(err),status:-1}}if(timer)clearTimeout(timer);if(timedOut&&result.exitCode===-1&&!result.stderr)return{stdout:result.stdout,stderr:`git ${args.join(" ")} timed out after ${options.timeoutMs}ms`,status:-1};return{stdout:result.stdout,stderr:result.stderr,status:result.exitCode}}function readLocalWorktreeHead(worktreePath,deps={}){if(!worktreePath||(deps.execForPath??execHostForWorktreePath)(worktreePath).isRemote)return null;try{let dirs=resolveGitDirs(worktreePath);return dirs?readHeadSha(dirs):null}catch{return null}}function worktreeFilePath(worktreePath,relPath){if(!worktreePath||!relPath)return null;if(/^[/\\]/.test(relPath)||/^[a-zA-Z]:[/\\]/.test(relPath))return null;if(relPath.split(/[/\\]/).some((part)=>part===".."))return null;let parts=relPath.split("/");return`${worktreePath.replace(/\/+$/,"")}/${parts.filter(Boolean).join("/")}`}async function worktreeFileSize(worktreePath,relPath,deps={}){let path=worktreeFilePath(worktreePath,relPath);if(!path)return null;let exec=(deps.execForPath??execHostForWorktreePath)(worktreePath);try{let res=await exec.run(["wc","-c",path]);if(res.exitCode!==0)return null;let n=Number.parseInt(res.stdout.trim().split(/\s+/)[0]??"",10);return Number.isFinite(n)?n:null}catch{return null}}async function readWorktreeFile(worktreePath,relPath,deps={}){let path=worktreeFilePath(worktreePath,relPath);if(!path)return null;let exec=(deps.execForPath??execHostForWorktreePath)(worktreePath);try{return await exec.readFile(path)}catch{return null}}function filetypeOf(relPath){switch(relPath.slice(relPath.lastIndexOf(".")+1).toLowerCase()){case"ts":case"tsx":case"mts":case"cts":return"typescript";case"js":case"jsx":case"mjs":case"cjs":return"javascript";case"md":case"markdown":return"markdown";default:return}}function isCombinedPathspec(relPath){return relPath==="."||relPath.endsWith("/")}function hunklessPatchNote(patch){if(/^@@/m.test(patch))return null;let binary=!1,from,to,renameFrom,renameTo,emptyChange;for(let line of patch.split(`
2
+ import{execHostForWorktreePath}from"./chunk-ampdybqg.js";import{protocolEntry}from"./chunk-pbfehk8q.js";import{parseNumstatRows}from"./chunk-t7j8g9f6.js";import{parsePorcelainRows,unquoteGitPath}from"./chunk-dmzg9zdc.js";import{readHeadSha,resolveGitDirs}from"./chunk-kg9kmwt9.js";import{READ_ONLY_GIT_ENV}from"./chunk-6xppe9bj.js";import{errorMessage}from"./chunk-2brn8e1y.js";import{isObject}from"./chunk-7ghwdjdc.js";import{getPersistedString,getPersistedValue}from"./chunk-22d0yc7m.js";import{recordSpawn}from"./chunk-40dgv828.js";import{acquireSync,releaseSync}from"./chunk-zh0c8yzw.js";import{secretsPath}from"./chunk-prqeddy7.js";import{t}from"./chunk-2676cb62.js";async function runWorktreeGit(worktreePath,args,options={}){if(!worktreePath)return{stdout:"",stderr:"worktreePath is required",status:-1};let exec=(options.execForPath??execHostForWorktreePath)(worktreePath),controller=options.timeoutMs&&options.timeoutMs>0?new AbortController:null,timedOut=!1,timer=controller?setTimeout(()=>{timedOut=!0,controller.abort()},options.timeoutMs):null,signal=controller&&options.signal?AbortSignal.any([controller.signal,options.signal]):controller?.signal??options.signal,result;try{recordSpawn("worktree.content",["git",...args],worktreePath),result=await exec.run(["git",...args],{cwd:worktreePath,env:READ_ONLY_GIT_ENV,signal})}catch(err){if(timer)clearTimeout(timer);return{stdout:"",stderr:errorMessage(err),status:-1}}if(timer)clearTimeout(timer);if(timedOut&&result.exitCode===-1&&!result.stderr)return{stdout:result.stdout,stderr:`git ${args.join(" ")} timed out after ${options.timeoutMs}ms`,status:-1};return{stdout:result.stdout,stderr:result.stderr,status:result.exitCode}}function readLocalWorktreeHead(worktreePath,deps={}){if(!worktreePath||(deps.execForPath??execHostForWorktreePath)(worktreePath).isRemote)return null;try{let dirs=resolveGitDirs(worktreePath);return dirs?readHeadSha(dirs):null}catch{return null}}function worktreeFilePath(worktreePath,relPath){if(!worktreePath||!relPath)return null;if(/^[/\\]/.test(relPath)||/^[a-zA-Z]:[/\\]/.test(relPath))return null;if(relPath.split(/[/\\]/).some((part)=>part===".."))return null;let parts=relPath.split("/");return`${worktreePath.replace(/\/+$/,"")}/${parts.filter(Boolean).join("/")}`}async function worktreeFileSize(worktreePath,relPath,deps={}){let path=worktreeFilePath(worktreePath,relPath);if(!path)return null;let exec=(deps.execForPath??execHostForWorktreePath)(worktreePath);try{let res=await exec.run(["wc","-c",path]);if(res.exitCode!==0)return null;let n=Number.parseInt(res.stdout.trim().split(/\s+/)[0]??"",10);return Number.isFinite(n)?n:null}catch{return null}}async function readWorktreeFile(worktreePath,relPath,deps={}){let path=worktreeFilePath(worktreePath,relPath);if(!path)return null;let exec=(deps.execForPath??execHostForWorktreePath)(worktreePath);try{return await exec.readFile(path)}catch{return null}}function filetypeOf(relPath){switch(relPath.slice(relPath.lastIndexOf(".")+1).toLowerCase()){case"ts":case"tsx":case"mts":case"cts":return"typescript";case"js":case"jsx":case"mjs":case"cjs":return"javascript";case"md":case"markdown":return"markdown";default:return}}function isCombinedPathspec(relPath){return relPath==="."||relPath.endsWith("/")}function hunklessPatchNote(patch){if(/^@@/m.test(patch))return null;let binary=!1,from,to,renameFrom,renameTo,emptyChange;for(let line of patch.split(`
3
3
  `))if(line.startsWith("old mode "))from=line.slice(9).trim();else if(line.startsWith("new mode "))to=line.slice(9).trim();else if(line.startsWith("rename from "))renameFrom=unquoteGitPath(line.slice(12));else if(line.startsWith("rename to "))renameTo=unquoteGitPath(line.slice(10));else if(line.startsWith("new file mode "))emptyChange="added";else if(line.startsWith("deleted file mode "))emptyChange="deleted";else if(line.startsWith("Binary files ")||line.startsWith("GIT binary patch"))binary=!0;if(binary)return{kind:"binary"};if(renameFrom!=null&&renameTo!=null)return{kind:"rename",from:renameFrom,to:renameTo};if(emptyChange)return{kind:"empty-file",change:emptyChange};if(from!=null&&to!=null)return{kind:"mode",from,to};return null}function sidePath(field){let raw=field.replace(/\t[\s\S]*$/,"");if(raw==="/dev/null")return null;let path=unquoteGitPath(raw);return path.startsWith("a/")||path.startsWith("b/")?path.slice(2):path}function headerPath(header){if(header.startsWith('"'))return sidePath(unquoteGitPath(header))??header;for(let i=header.indexOf(" b/");i>=0;i=header.indexOf(" b/",i+1)){let a=sidePath(header.slice(0,i)),b=sidePath(header.slice(i+1));if(a!=null&&a===b)return b}let last=header.lastIndexOf(" b/");return(last>=0?sidePath(header.slice(last+1)):null)??header}function unifiedDiffFiles(text){let files=[],current=null,push=()=>{if(!current)return;let patch=`${current.lines.join(`
4
4
  `)}
5
5
  `,path=current.plus??current.minus??current.path,note=hunklessPatchNote(patch);files.push({path,text:patch,lines:current.rows,...note?{note}:{}})};for(let line of text.split(`
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{currentLang,intlLocale,localeState,registerMessages,setLocaleLang,t,tKeys}from"./chunk-tq6pq1ws.js";import"./chunk-sma961wh.js";import"./chunk-cmp64q4j.js";import"./chunk-91sykzqq.js";export{tKeys,t,setLocaleLang,registerMessages,localeState,intlLocale,currentLang};
2
+ import{currentLang,intlLocale,localeState,registerMessages,setLocaleLang,t,tKeys}from"./chunk-2676cb62.js";import"./chunk-q07r6hf7.js";import"./chunk-cmp64q4j.js";import"./chunk-91sykzqq.js";export{tKeys,t,setLocaleLang,registerMessages,localeState,intlLocale,currentLang};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-sma961wh.js";import{createStateCell}from"./chunk-cmp64q4j.js";function lookup(catalog,key){let node=catalog;for(let part of key.split("."))if(node&&typeof node==="object"&&part in node)node=node[part];else return;return typeof node==="string"?node:void 0}function interpolate(template,params){if(!params)return template;return template.replace(/\{(\w+)\}/g,(whole,name)=>(name in params)?String(params[name]):whole)}function lookupKeys(catalog,group,key){return catalog.keys[group]?.[key]}var langState=createStateCell(DEFAULT_LOCALE);function setLocaleLang(lang){if(CATALOGS[lang])langState.set(lang)}function currentLang(){return langState.get()}function intlLocale(){return LOCALES.find((locale)=>locale.id===langState.get())?.intl??"en-US"}function localeState(){return langState}var pluginNamespaces=new Set;function registerMessages(namespace,messages){let en=CATALOGS.en,zh=CATALOGS.zh;if(namespace in en&&!pluginNamespaces.has(namespace))throw Error(`i18n namespace "${namespace}" belongs to the host`);if(pluginNamespaces.add(namespace),en[namespace]=messages.en,messages.zh)zh[namespace]=messages.zh;else delete zh[namespace]}function t(key,params){let lang=langState.get(),resolved=lookup(CATALOGS[lang],key)??lookup(CATALOGS.en,key)??key;return interpolate(resolved,params)}function tKeys(group,key){let lang=langState.get();return lookupKeys(CATALOGS[lang],group,key)??lookupKeys(CATALOGS.en,group,key)??key}
2
+ import{CATALOGS,DEFAULT_LOCALE,LOCALES}from"./chunk-q07r6hf7.js";import{createStateCell}from"./chunk-cmp64q4j.js";function lookup(catalog,key){let node=catalog;for(let part of key.split("."))if(node&&typeof node==="object"&&part in node)node=node[part];else return;return typeof node==="string"?node:void 0}function interpolate(template,params){if(!params)return template;return template.replace(/\{(\w+)\}/g,(whole,name)=>(name in params)?String(params[name]):whole)}function lookupKeys(catalog,group,key){return catalog.keys[group]?.[key]}var langState=createStateCell(DEFAULT_LOCALE);function setLocaleLang(lang){if(CATALOGS[lang])langState.set(lang)}function currentLang(){return langState.get()}function intlLocale(){return LOCALES.find((locale)=>locale.id===langState.get())?.intl??"en-US"}function localeState(){return langState}var pluginNamespaces=new Set;function registerMessages(namespace,messages){let en=CATALOGS.en,zh=CATALOGS.zh;if(namespace in en&&!pluginNamespaces.has(namespace))throw Error(`i18n namespace "${namespace}" belongs to the host`);if(pluginNamespaces.add(namespace),en[namespace]=messages.en,messages.zh)zh[namespace]=messages.zh;else delete zh[namespace]}function t(key,params){let lang=langState.get(),resolved=lookup(CATALOGS[lang],key)??lookup(CATALOGS.en,key)??key;return interpolate(resolved,params)}function tKeys(group,key){let lang=langState.get();return lookupKeys(CATALOGS[lang],group,key)??lookupKeys(CATALOGS.en,group,key)??key}
3
3
  export{setLocaleLang,currentLang,intlLocale,localeState,registerMessages,t,tKeys};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useT,useTheme}from"./chunk-216scxtw.js";import"./chunk-65v8ga90.js";import"./chunk-vqcww6xj.js";import{$jsx,$jsxs,useRenderer}from"./chunk-29kvfqeh.js";import{require_react_production}from"./chunk-2wd4744g.js";import"./chunk-764bsyb0.js";import"./chunk-emz4gsxn.js";import"./chunk-atn06ncf.js";import"./chunk-jetsx9zr.js";import"./chunk-f5n0tgky.js";import"./chunk-z3zaa155.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-kqf371ff.js";import"./chunk-1vwngrmf.js";import"./chunk-yktnbb14.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import"./chunk-7ghwdjdc.js";import{BREAKING_VERSIONS,CURRENT_VERSION,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries,updateCommandFor}from"./chunk-xk22erkp.js";import"./chunk-40dgv828.js";import"./chunk-g4281a0g.js";import"./chunk-zh0c8yzw.js";import"./chunk-wqckm0k6.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-tq6pq1ws.js";import"./chunk-sma961wh.js";import"./chunk-cmp64q4j.js";import"./chunk-s0jbtyd9.js";import"./chunk-278sc87n.js";import"./chunk-gskbzgc3.js";import"./chunk-pn5ygqn6.js";import"./chunk-n0rtj4z7.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-91sykzqq.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:updateCommandFor(selected.version)})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
2
+ import{ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useT,useTheme}from"./chunk-jzf2d1pj.js";import"./chunk-65v8ga90.js";import{$jsx,$jsxs,useRenderer}from"./chunk-29kvfqeh.js";import"./chunk-apm5yjkq.js";import{require_react_production}from"./chunk-2wd4744g.js";import"./chunk-764bsyb0.js";import"./chunk-pw9teydh.js";import"./chunk-atn06ncf.js";import"./chunk-zae59k1j.js";import"./chunk-f5n0tgky.js";import"./chunk-z3zaa155.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-601dsgex.js";import"./chunk-1vwngrmf.js";import"./chunk-3vtpshwx.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import"./chunk-7ghwdjdc.js";import{BREAKING_VERSIONS,CURRENT_VERSION,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries,updateCommandFor}from"./chunk-hqkzc8cv.js";import"./chunk-40dgv828.js";import"./chunk-g4281a0g.js";import"./chunk-zh0c8yzw.js";import"./chunk-wqckm0k6.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-2676cb62.js";import"./chunk-q07r6hf7.js";import"./chunk-cmp64q4j.js";import"./chunk-s0jbtyd9.js";import"./chunk-278sc87n.js";import"./chunk-gskbzgc3.js";import"./chunk-pn5ygqn6.js";import"./chunk-n0rtj4z7.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-91sykzqq.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:updateCommandFor(selected.version)})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
@@ -0,0 +1,3 @@
1
+ // @bun
2
+ import{findVerb}from"./chunk-q2kweazg.js";import{VERB_GROUP_IDS}from"./chunk-x7r75e3p.js";import{loadStateFile,updateStateFile}from"./chunk-g4281a0g.js";var INBOUND_KEY="machineInbound",INBOUND_CLASSES=[...VERB_GROUP_IDS,"land"],LAND_VERBS=new Set(["land","publish"]);function inboundClassOf(verb){if(LAND_VERBS.has(verb))return"land";return findVerb(verb)?.group??null}function deniedClasses(state=loadStateFile()){let raw=state[INBOUND_KEY],deny=raw&&typeof raw==="object"?raw.deny:void 0;return Array.isArray(deny)?deny.filter((c)=>typeof c==="string"):[]}function inboundRefusal(verb,state){let cls=inboundClassOf(verb);return cls&&deniedClasses(state).includes(cls)?cls:null}function setInbound(cls,allow){let next=[];return updateStateFile((state)=>{let current=new Set(deniedClasses(state));if(allow)current.delete(cls);else current.add(cls);return next=[...current].sort(),state[INBOUND_KEY]={deny:next},!0}),next}
3
+ export{INBOUND_KEY,INBOUND_CLASSES,inboundClassOf,deniedClasses,inboundRefusal,setInbound};
@@ -1,5 +1,40 @@
1
1
  // @bun
2
- import{RoveDaemonClient}from"./chunk-s0jbtyd9.js";import{defaultDaemonSocketPath,defaultPtyHostSocketPath}from"./chunk-n0rtj4z7.js";import{spawn as spawn2}from"child_process";import{appendFileSync,closeSync,mkdirSync,openSync}from"fs";import{dirname}from"path";import{join,resolve}from"path";var PTY_JOB_ENV="ROVE_PTY_JOB",PTY_JOB_OWNER_ENV="ROVE_PTY_JOB_OWNER",PTY_JOB_LAUNCHER_CS=`
2
+ import{RoveDaemonClient}from"./chunk-s0jbtyd9.js";import{defaultDaemonSocketPath,defaultPtyHostSocketPath}from"./chunk-n0rtj4z7.js";import{spawn}from"child_process";import{existsSync}from"fs";import{join}from"path";var LAUNCH_CMD_ENV="ROVE_LAUNCH_CMD",LAUNCH_LOG_ENV="ROVE_LAUNCH_LOG",WIN_DETACHED_LAUNCHER_PS=`
3
+ $ErrorActionPreference = 'Stop'
4
+ $cmd = $env:${LAUNCH_CMD_ENV}
5
+ $log = $env:${LAUNCH_LOG_ENV}
6
+ if (-not $cmd -or -not $log) { [Console]::Error.WriteLine('rove launcher: ${LAUNCH_CMD_ENV}/${LAUNCH_LOG_ENV} not set'); exit 1 }
7
+ Remove-Item Env:${LAUNCH_CMD_ENV}, Env:${LAUNCH_LOG_ENV}
8
+ Add-Type -TypeDefinition @'
9
+ using System;
10
+ using System.Runtime.InteropServices;
11
+ public static class RoveDetachedLaunch {
12
+ [StructLayout(LayoutKind.Sequential)] public struct SA { public int nLength; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; }
13
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct SI { public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; public int dwX, dwY, dwXSize, dwYSize, dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags; public short wShowWindow, cbReserved2; public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError; }
14
+ [StructLayout(LayoutKind.Sequential)] public struct PI { public IntPtr hProcess, hThread; public int dwProcessId, dwThreadId; }
15
+ [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern IntPtr CreateFile(string name, uint access, uint share, ref SA sa, uint disposition, uint flags, IntPtr template);
16
+ [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern bool CreateProcess(string app, string cmd, IntPtr pa, IntPtr ta, bool inherit, uint flags, IntPtr env, string cwd, ref SI si, out PI pi);
17
+ [DllImport("kernel32.dll")] static extern bool CloseHandle(IntPtr h);
18
+ public static int Launch(string cmd, string log) {
19
+ SA sa = new SA(); sa.nLength = Marshal.SizeOf(sa); sa.bInheritHandle = true;
20
+ // FILE_APPEND_DATA | GENERIC_READ, shared read/write, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL
21
+ IntPtr h = CreateFile(log, 0x0004 | 0x80000000, 0x1 | 0x2, ref sa, 4, 0x80, IntPtr.Zero);
22
+ if (h == (IntPtr)(-1)) throw new Exception("CreateFile(" + log + ") failed: " + Marshal.GetLastWin32Error());
23
+ IntPtr nul = CreateFile("NUL", 0x80000000, 0x1 | 0x2, ref sa, 3, 0x80, IntPtr.Zero);
24
+ SI si = new SI(); si.cb = Marshal.SizeOf(si);
25
+ si.dwFlags = 0x100 | 0x1; // STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW
26
+ si.wShowWindow = 0; // SW_HIDE
27
+ si.hStdInput = nul; si.hStdOutput = h; si.hStdError = h;
28
+ PI pi;
29
+ uint flags = 0x00000010 | 0x01000000 | 0x00000200; // CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP
30
+ if (!CreateProcess(null, cmd, IntPtr.Zero, IntPtr.Zero, true, flags, IntPtr.Zero, null, ref si, out pi)) throw new Exception("CreateProcess failed: " + Marshal.GetLastWin32Error());
31
+ CloseHandle(h); CloseHandle(nul); CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
32
+ return pi.dwProcessId;
33
+ }
34
+ }
35
+ '@
36
+ [RoveDetachedLaunch]::Launch($cmd, $log) | Out-Null
37
+ `;function windowsCommandLine(argv){return argv.map(quoteWindowsArg).join(" ")}function quoteWindowsArg(arg){if(arg!==""&&!/[\s"]/.test(arg))return arg;let out='"',backslashes=0;for(let ch of arg){if(ch==="\\"){backslashes++;continue}if(ch==='"'){out+=`${"\\".repeat(backslashes*2+1)}"`,backslashes=0;continue}out+="\\".repeat(backslashes)+ch,backslashes=0}return`${out}${"\\".repeat(backslashes*2)}"`}function windowsPowershellPath(env=process.env,exists=existsSync){let root=env.SystemRoot||env.windir||"C:\\Windows",absolute=join(root,"System32","WindowsPowerShell","v1.0","powershell.exe");return exists(absolute)?absolute:"powershell.exe"}function encodePowershellCommand(script){return Buffer.from(script,"utf16le").toString("base64")}function windowsDetachedLauncherArgs(){return["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand",encodePowershellCommand(WIN_DETACHED_LAUNCHER_PS)]}function spawnWindowsDetached(command,args,env,logPath,spawnImpl=spawn){let child=spawnImpl(windowsPowershellPath(env),windowsDetachedLauncherArgs(),{windowsHide:!0,stdio:"ignore",env:{...env,[LAUNCH_CMD_ENV]:windowsCommandLine([command,...args]),[LAUNCH_LOG_ENV]:logPath}});return child.unref(),child}import{spawn as spawn2}from"child_process";import{appendFileSync,closeSync,mkdirSync,openSync}from"fs";import{dirname}from"path";import{join as join2,resolve}from"path";var PTY_JOB_ENV="ROVE_PTY_JOB",PTY_JOB_OWNER_ENV="ROVE_PTY_JOB_OWNER",PTY_JOB_LAUNCHER_CS=`
3
38
  using System;
4
39
  using System.Runtime.InteropServices;
5
40
  using System.Text;
@@ -56,41 +91,6 @@ static class RovePtyJob {
56
91
  return (int)code;
57
92
  }
58
93
  }
59
- `;function sameSocket(a,b){let norm=(p)=>resolve(p.replace(/\//g,"\\")).toLowerCase();return norm(a)===norm(b)}function withoutPtyJob(env){let out={...env};return delete out[PTY_JOB_ENV],delete out[PTY_JOB_OWNER_ENV],out}function ptyJobLaunch(env,ownDaemonSocket){let job=env[PTY_JOB_ENV],owner=env[PTY_JOB_OWNER_ENV];if(!job||!owner)return null;return{job,mode:sameSocket(owner,ownDaemonSocket)?"escape":"join"}}import{spawn}from"child_process";import{existsSync}from"fs";import{join as join2}from"path";var LAUNCH_CMD_ENV="ROVE_LAUNCH_CMD",LAUNCH_LOG_ENV="ROVE_LAUNCH_LOG",WIN_DETACHED_LAUNCHER_PS=`
60
- $ErrorActionPreference = 'Stop'
61
- $cmd = $env:${LAUNCH_CMD_ENV}
62
- $log = $env:${LAUNCH_LOG_ENV}
63
- if (-not $cmd -or -not $log) { [Console]::Error.WriteLine('rove launcher: ${LAUNCH_CMD_ENV}/${LAUNCH_LOG_ENV} not set'); exit 1 }
64
- Remove-Item Env:${LAUNCH_CMD_ENV}, Env:${LAUNCH_LOG_ENV}
65
- Add-Type -TypeDefinition @'
66
- using System;
67
- using System.Runtime.InteropServices;
68
- public static class RoveDetachedLaunch {
69
- [StructLayout(LayoutKind.Sequential)] public struct SA { public int nLength; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; }
70
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct SI { public int cb; public string lpReserved; public string lpDesktop; public string lpTitle; public int dwX, dwY, dwXSize, dwYSize, dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags; public short wShowWindow, cbReserved2; public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError; }
71
- [StructLayout(LayoutKind.Sequential)] public struct PI { public IntPtr hProcess, hThread; public int dwProcessId, dwThreadId; }
72
- [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern IntPtr CreateFile(string name, uint access, uint share, ref SA sa, uint disposition, uint flags, IntPtr template);
73
- [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern bool CreateProcess(string app, string cmd, IntPtr pa, IntPtr ta, bool inherit, uint flags, IntPtr env, string cwd, ref SI si, out PI pi);
74
- [DllImport("kernel32.dll")] static extern bool CloseHandle(IntPtr h);
75
- public static int Launch(string cmd, string log) {
76
- SA sa = new SA(); sa.nLength = Marshal.SizeOf(sa); sa.bInheritHandle = true;
77
- // FILE_APPEND_DATA | GENERIC_READ, shared read/write, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL
78
- IntPtr h = CreateFile(log, 0x0004 | 0x80000000, 0x1 | 0x2, ref sa, 4, 0x80, IntPtr.Zero);
79
- if (h == (IntPtr)(-1)) throw new Exception("CreateFile(" + log + ") failed: " + Marshal.GetLastWin32Error());
80
- IntPtr nul = CreateFile("NUL", 0x80000000, 0x1 | 0x2, ref sa, 3, 0x80, IntPtr.Zero);
81
- SI si = new SI(); si.cb = Marshal.SizeOf(si);
82
- si.dwFlags = 0x100 | 0x1; // STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW
83
- si.wShowWindow = 0; // SW_HIDE
84
- si.hStdInput = nul; si.hStdOutput = h; si.hStdError = h;
85
- PI pi;
86
- uint flags = 0x00000010 | 0x01000000 | 0x00000200; // CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB | CREATE_NEW_PROCESS_GROUP
87
- if (!CreateProcess(null, cmd, IntPtr.Zero, IntPtr.Zero, true, flags, IntPtr.Zero, null, ref si, out pi)) throw new Exception("CreateProcess failed: " + Marshal.GetLastWin32Error());
88
- CloseHandle(h); CloseHandle(nul); CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
89
- return pi.dwProcessId;
90
- }
91
- }
92
- '@
93
- [RoveDetachedLaunch]::Launch($cmd, $log) | Out-Null
94
- `;function windowsCommandLine(argv){return argv.map(quoteWindowsArg).join(" ")}function quoteWindowsArg(arg){if(arg!==""&&!/[\s"]/.test(arg))return arg;let out='"',backslashes=0;for(let ch of arg){if(ch==="\\"){backslashes++;continue}if(ch==='"'){out+=`${"\\".repeat(backslashes*2+1)}"`,backslashes=0;continue}out+="\\".repeat(backslashes)+ch,backslashes=0}return`${out}${"\\".repeat(backslashes*2)}"`}function windowsPowershellPath(env=process.env,exists=existsSync){let root=env.SystemRoot||env.windir||"C:\\Windows",absolute=join2(root,"System32","WindowsPowerShell","v1.0","powershell.exe");return exists(absolute)?absolute:"powershell.exe"}function encodePowershellCommand(script){return Buffer.from(script,"utf16le").toString("base64")}function windowsDetachedLauncherArgs(){return["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand",encodePowershellCommand(WIN_DETACHED_LAUNCHER_PS)]}function spawnWindowsDetached(command,args,env,logPath,spawnImpl=spawn){let child=spawnImpl(windowsPowershellPath(env),windowsDetachedLauncherArgs(),{windowsHide:!0,stdio:"ignore",env:{...env,[LAUNCH_CMD_ENV]:windowsCommandLine([command,...args]),[LAUNCH_LOG_ENV]:logPath}});return child.unref(),child}var ESCAPE_REQUEST_TIMEOUT_MS=5000;function appendLaunchLog(logPath,line){try{appendFileSync(logPath,`[${new Date().toISOString()}] rove: ${line}
94
+ `;function sameSocket(a,b){let norm=(p)=>resolve(p.replace(/\//g,"\\")).toLowerCase();return norm(a)===norm(b)}function withoutPtyJob(env){let out={...env};return delete out[PTY_JOB_ENV],delete out[PTY_JOB_OWNER_ENV],out}function ptyJobLaunch(env,ownDaemonSocket){let job=env[PTY_JOB_ENV],owner=env[PTY_JOB_OWNER_ENV];if(!job||!owner)return null;return{job,mode:sameSocket(owner,ownDaemonSocket)?"escape":"join"}}var ESCAPE_REQUEST_TIMEOUT_MS=5000;function appendLaunchLog(logPath,line){try{appendFileSync(logPath,`[${new Date().toISOString()}] rove: ${line}
95
95
  `)}catch{}}async function launchViaPtyHost(command,args,env,logPath,socketPath){let client=new RoveDaemonClient(socketPath),timer;try{await Promise.race([client.request("spawn.detached",{command,args:[...args],env,logPath}),new Promise((_,reject)=>{timer=setTimeout(()=>reject(Error("timed out")),ESCAPE_REQUEST_TIMEOUT_MS)})])}finally{if(timer)clearTimeout(timer);client.close()}}function detachOptions(platform=process.platform){return platform==="win32"?{windowsHide:!0}:{detached:!0}}function spawnDetachedDaemon(command,args,env,logPath,platform=process.platform){try{mkdirSync(dirname(logPath),{recursive:!0})}catch{}if(platform==="win32"){if(ptyJobLaunch(env,defaultDaemonSocketPath())?.mode==="escape"){let free=withoutPtyJob(env);launchViaPtyHost(command,args,free,logPath,defaultPtyHostSocketPath()).catch((err)=>{appendLaunchLog(logPath,`PTY host could not launch outside the tab (${err.message}) \u2014 it ends with the tab`),launchWindowsDetached(command,args,free,logPath,platform)});return}launchWindowsDetached(command,args,env,logPath,platform);return}spawnDirect(command,args,env,logPath,platform)}function launchWindowsDetached(command,args,env,logPath,platform){let launcher=spawnWindowsDetached(command,args,env,logPath),fallback=(reason)=>{appendLaunchLog(logPath,`detached launcher ${reason} \u2014 spawning directly; this process will not outlive its parent`),spawnDirect(command,args,env,logPath,platform)};launcher.once("error",(err)=>fallback(`could not start (${err.message})`)),launcher.once("exit",(code,signal)=>{if(code!==0)fallback(`exited ${code??signal}`)})}function spawnDirect(command,args,env,logPath,platform){let stdio="ignore",logFd;try{mkdirSync(dirname(logPath),{recursive:!0}),logFd=openSync(logPath,"a"),stdio=["ignore",logFd,logFd]}catch{stdio="ignore"}if(spawn2(command,[...args],{...detachOptions(platform),stdio,env}).unref(),logFd!==void 0)try{closeSync(logFd)}catch{}}
96
96
  export{withoutPtyJob,windowsPowershellPath,detachOptions,spawnDetachedDaemon};