@sma1lboy/rove 0.9.264 → 0.9.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{chunk-ykp6efg0.js → chunk-0sm0wcx9.js} +1 -1
- package/dist/cli/{chunk-md3m1qts.js → chunk-1bmhygwd.js} +1 -1
- package/dist/cli/{chunk-1cmcaarg.js → chunk-1gawhhd0.js} +1 -1
- package/dist/cli/{chunk-2bq6877b.js → chunk-1nrva2m2.js} +2 -2
- package/dist/cli/{chunk-cyq9pwqz.js → chunk-1pg3247n.js} +6 -6
- package/dist/cli/{chunk-nfq1q08c.js → chunk-1vtfzcca.js} +1 -1
- package/dist/cli/{chunk-7y7v9x3n.js → chunk-2gjrfqhs.js} +1 -1
- package/dist/cli/{chunk-x2xk1hpy.js → chunk-2gk96h3f.js} +1 -1
- package/dist/cli/{chunk-8fp47ksq.js → chunk-2vrx0pmv.js} +1 -1
- package/dist/cli/{chunk-yewmtant.js → chunk-30g1bgkg.js} +1 -1
- package/dist/cli/chunk-3126c9x9.js +3 -0
- package/dist/cli/{chunk-c6kw0s9a.js → chunk-31jxjkrq.js} +1 -1
- package/dist/cli/{chunk-hpakh6zr.js → chunk-3zsm2jbm.js} +1 -1
- package/dist/cli/{chunk-s0x0yw8x.js → chunk-4018sjy3.js} +1 -1
- package/dist/cli/chunk-4b9f565d.js +2 -0
- package/dist/cli/chunk-4dsyczce.js +2 -0
- package/dist/cli/chunk-4gngf0mt.js +70 -0
- package/dist/cli/{chunk-gzj9nk7k.js → chunk-4rya4jmx.js} +1 -1
- package/dist/cli/{chunk-y1a673xg.js → chunk-4sj2sqyt.js} +1 -1
- package/dist/cli/{chunk-y5p9wm83.js → chunk-56n0whme.js} +1 -1
- package/dist/cli/{chunk-n7vtv1rw.js → chunk-5srsjs7r.js} +1 -1
- package/dist/cli/{chunk-ws4cg819.js → chunk-625773dm.js} +1 -1
- package/dist/cli/{chunk-2k0f7837.js → chunk-67qa9eca.js} +1 -1
- package/dist/cli/chunk-696sqb6j.js +2 -0
- package/dist/cli/{chunk-3ac75tqw.js → chunk-6a70wv2b.js} +1 -1
- package/dist/cli/{chunk-wch6y5bd.js → chunk-7c4zdjr5.js} +1 -1
- package/dist/cli/{chunk-8gzqcx6x.js → chunk-7nrzkqt5.js} +1 -1
- package/dist/cli/chunk-7wsxppwc.js +55 -0
- package/dist/cli/{chunk-ns2f9b6r.js → chunk-80jqznbm.js} +1 -1
- package/dist/cli/chunk-812et2xk.js +3 -0
- package/dist/cli/{chunk-9ecnsh42.js → chunk-8saxdp88.js} +1 -1
- package/dist/cli/{chunk-j11hzmwy.js → chunk-8sksdq95.js} +1 -1
- package/dist/cli/{chunk-rwx1y497.js → chunk-9g2faw9a.js} +1 -1
- package/dist/cli/chunk-a42j8eek.js +3 -0
- package/dist/cli/{chunk-bmk52w06.js → chunk-aeswyjhk.js} +1 -1
- package/dist/cli/{chunk-e5489crb.js → chunk-agt2sdaw.js} +1 -1
- package/dist/cli/{chunk-n22008wk.js → chunk-amc17enx.js} +1 -1
- package/dist/cli/{chunk-vkbgm18p.js → chunk-b3pm5nvh.js} +1 -1
- package/dist/cli/{chunk-jt994bhe.js → chunk-b4zqkdyq.js} +1 -1
- package/dist/cli/{chunk-17fkjpj8.js → chunk-bav3bh70.js} +1 -1
- package/dist/cli/chunk-bwr6dygx.js +4 -0
- package/dist/cli/{chunk-02f0matw.js → chunk-c47gag5r.js} +1 -1
- package/dist/cli/{chunk-zfyf3fdj.js → chunk-cajrtabt.js} +1 -1
- package/dist/cli/{chunk-mccgj97d.js → chunk-cgxgqc87.js} +1 -1
- package/dist/cli/{chunk-spt9e3zk.js → chunk-chzn3px6.js} +4 -4
- package/dist/cli/{chunk-ytw1twda.js → chunk-cqsc0wmp.js} +1 -1
- package/dist/cli/{chunk-9axe1by1.js → chunk-drt79f2t.js} +1 -1
- package/dist/cli/{chunk-hgf4cz78.js → chunk-dzmfexh8.js} +1 -1
- package/dist/cli/chunk-e69s8s16.js +6 -0
- package/dist/cli/{chunk-bs04j8rh.js → chunk-ejd307we.js} +1 -1
- package/dist/cli/{chunk-mhbc490p.js → chunk-ek6kywem.js} +1 -1
- package/dist/cli/{chunk-r3zkpbf5.js → chunk-g1px1rk6.js} +1 -1
- package/dist/cli/{chunk-27k612fg.js → chunk-gvmgabps.js} +1 -1
- package/dist/cli/{chunk-04zwds1k.js → chunk-hc6qpkpy.js} +2 -2
- package/dist/cli/{chunk-cy1c8jmz.js → chunk-hq3hd8qr.js} +1 -1
- package/dist/cli/{chunk-jjv7xem7.js → chunk-j1fe3j54.js} +1 -1
- package/dist/cli/{chunk-jaqa26ab.js → chunk-jrqtzp35.js} +1 -1
- package/dist/cli/{chunk-s83qnstd.js → chunk-kg8k1rar.js} +1 -1
- package/dist/cli/chunk-kvwqh35r.js +4 -0
- package/dist/cli/{chunk-22d0yc7m.js → chunk-m6pp9gaf.js} +1 -1
- package/dist/cli/chunk-m8shvh3j.js +2 -0
- package/dist/cli/{chunk-3khq4hhf.js → chunk-mb018hfg.js} +3 -3
- package/dist/cli/{chunk-4tb0h00q.js → chunk-me656p3n.js} +2 -2
- package/dist/cli/{chunk-ax5c2qmv.js → chunk-mh2s5ttr.js} +1 -1
- package/dist/cli/chunk-mr0z23fd.js +2 -0
- package/dist/cli/{chunk-65333881.js → chunk-mtw6nce9.js} +1 -1
- package/dist/cli/{chunk-g4281a0g.js → chunk-n3f5sdka.js} +2 -2
- package/dist/cli/chunk-njvz867e.js +2 -0
- package/dist/cli/{chunk-rn3cyff1.js → chunk-nyw4s1pv.js} +1 -1
- package/dist/cli/{chunk-xjvrcx07.js → chunk-p2vagan3.js} +1 -1
- package/dist/cli/chunk-pcqw7r50.js +2 -0
- package/dist/cli/{chunk-b2h6jfrg.js → chunk-qdvtz853.js} +1 -1
- package/dist/cli/{chunk-bqscpzvh.js → chunk-qpr14v8x.js} +1 -1
- package/dist/cli/{chunk-3zjdbdwy.js → chunk-qs0526nj.js} +1 -1
- package/dist/cli/{chunk-dxk134bp.js → chunk-qwz9728j.js} +1 -1
- package/dist/cli/{chunk-z6y4cg73.js → chunk-r4vfng2z.js} +1 -1
- package/dist/cli/{chunk-rtcevh2t.js → chunk-rbr6qapz.js} +1 -1
- package/dist/cli/{chunk-65v8ga90.js → chunk-rtkj4wdw.js} +1 -1
- package/dist/cli/{chunk-vpj3gw8b.js → chunk-rwmxpjrx.js} +1 -1
- package/dist/cli/{chunk-eq0c4ecj.js → chunk-s0gp5b9p.js} +1 -1
- package/dist/cli/{chunk-c0gvp57p.js → chunk-s27a0ckk.js} +1 -1
- package/dist/cli/{chunk-f6tqc1cc.js → chunk-sdya3r5j.js} +1 -1
- package/dist/cli/{chunk-wkv4aw6c.js → chunk-swxq6yak.js} +1 -1
- package/dist/cli/{chunk-fdexrh6h.js → chunk-t6hzyee7.js} +1 -1
- package/dist/cli/{chunk-hv9qjnvj.js → chunk-trhrdby1.js} +1 -1
- package/dist/cli/{chunk-vy6q9m4e.js → chunk-tshbjft4.js} +2 -2
- package/dist/cli/chunk-tvbbnfp2.js +2 -0
- package/dist/cli/{chunk-4kzqv6rq.js → chunk-ve348rmz.js} +1 -1
- package/dist/cli/{chunk-vjew0mqm.js → chunk-vxc90473.js} +1 -1
- package/dist/cli/{chunk-70kj5p5z.js → chunk-w196jkg5.js} +1 -1
- package/dist/cli/chunk-w78n33b8.js +3 -0
- package/dist/cli/{chunk-qy4tma9z.js → chunk-wvaf3d9j.js} +1 -1
- package/dist/cli/{chunk-wv5hvxcd.js → chunk-wyn3zbh4.js} +2 -2
- package/dist/cli/chunk-xgans9wf.js +3 -0
- package/dist/cli/{chunk-b3vz95wb.js → chunk-xh72jz7c.js} +1 -1
- package/dist/cli/chunk-xm7a6swz.js +2 -0
- package/dist/cli/{chunk-9ykm0dcz.js → chunk-y078swzq.js} +1 -1
- package/dist/cli/chunk-y87f04kk.js +2 -0
- package/dist/cli/{chunk-g0kq5ng6.js → chunk-yadx0wc5.js} +1 -1
- package/dist/cli/{chunk-6h9bd4z6.js → chunk-ye4vt96f.js} +3 -3
- package/dist/cli/{chunk-ampdybqg.js → chunk-yk498qwr.js} +1 -1
- package/dist/cli/chunk-ywwm92e5.js +2 -0
- package/dist/cli/chunk-yztr951z.js +3 -0
- package/dist/cli/chunk-z5g3twhn.js +2 -0
- package/dist/cli/{chunk-8021rerp.js → chunk-z72f3d9m.js} +18 -18
- package/dist/cli/{chunk-jwqdhbe9.js → chunk-z80jjarw.js} +1 -1
- package/dist/cli/{chunk-c2cj2bye.js → chunk-z99ynm4r.js} +1 -1
- package/dist/cli/{chunk-7jqd1vht.js → chunk-zprhxt1q.js} +1 -1
- package/dist/cli/index.js +8 -8
- package/dist/cli/rove-run.js +1 -1
- package/dist/cli/rove.js +1 -1
- package/dist/skills/rove/SKILL.md +5 -2
- package/dist/skills/rove/references/api-flags.md +1 -1
- package/dist/web/assets/index-BsbDxm3K.js +109 -0
- package/dist/web/assets/index-DNv-oxrT.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +3 -3
- package/dist/cli/chunk-1gxb0bd3.js +0 -3
- package/dist/cli/chunk-26mf16v9.js +0 -2
- package/dist/cli/chunk-2amvwfah.js +0 -6
- package/dist/cli/chunk-2cbzp9t1.js +0 -2
- package/dist/cli/chunk-59g5tbc7.js +0 -2
- package/dist/cli/chunk-5p8ws3an.js +0 -2
- package/dist/cli/chunk-61nwtmyh.js +0 -2
- package/dist/cli/chunk-69dz852g.js +0 -2
- package/dist/cli/chunk-7hr9k9kg.js +0 -2
- package/dist/cli/chunk-7kwk5kxn.js +0 -3
- package/dist/cli/chunk-a2epp2ad.js +0 -4
- package/dist/cli/chunk-ft6ftksv.js +0 -2
- package/dist/cli/chunk-har2ggte.js +0 -2
- package/dist/cli/chunk-k04s1eb9.js +0 -2
- package/dist/cli/chunk-mn134nhp.js +0 -2
- package/dist/cli/chunk-mtvcw6te.js +0 -55
- package/dist/cli/chunk-nze6pmm7.js +0 -2
- package/dist/cli/chunk-pjae8k74.js +0 -70
- package/dist/cli/chunk-r240tf5j.js +0 -3
- package/dist/cli/chunk-va5mjg68.js +0 -3
- package/dist/cli/chunk-x7r75e3p.js +0 -3
- package/dist/web/assets/index-CWRZWwbL.css +0 -1
- package/dist/web/assets/index-apAwSqkl.js +0 -109
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{binaryAvailable,resolveEditorCommand}from"./chunk-
|
|
2
|
+
import{binaryAvailable,resolveEditorCommand}from"./chunk-8sksdq95.js";import"./chunk-6xppe9bj.js";import"./chunk-7kysxgbq.js";import"./chunk-m6pp9gaf.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-n3f5sdka.js";import"./chunk-zh0c8yzw.js";import"./chunk-wqckm0k6.js";import{kvStatePath}from"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-pn5ygqn6.js";import"./chunk-n0rtj4z7.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";import{existsSync,mkdirSync,writeFileSync}from"fs";import{dirname}from"path";var CLI_NAME=ROVE_PRODUCT_NAME;function printUsage(out){out.write([`Usage: ${CLI_NAME} config [--path]`,"","Open Rove's user config (state.json \u2014 theme, locale, engine + editor prefs)","in your editor. The editor is your configured one (Settings \u2192 General \u2192","Editor); left on Auto it is $VISUAL / $EDITOR, else the first of","nvim / vim / emacs / nano.","Rove re-reads the file on its next launch.","","Options:"," --path Print the config file path and exit (don't open an editor)"," -h, --help Print this help",""].join(`
|
|
3
3
|
`))}async function runConfigSubcommand(argv=[]){if(argv.some((a)=>a==="-h"||a==="--help"||a==="help")){printUsage(process.stdout);return}let path=kvStatePath();if(argv.some((a)=>a==="--path"||a==="path")){console.log(path);return}let unknown=argv.find((a)=>a.length>0);if(unknown!==void 0)process.stderr.write(`${CLI_NAME} config: unexpected argument "${unknown}"
|
|
4
4
|
`),printUsage(process.stderr),process.exit(2);if(!existsSync(path))mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`{}
|
|
5
5
|
`);let resolved=await resolveEditorCommand(path);if(!resolved||!await binaryAvailable(resolved.bin))process.stderr.write(`${CLI_NAME} config: no editor found \u2014 set $EDITOR (or Settings \u2192 General \u2192 Editor), or edit directly:
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{isRowTokenTone}from"./chunk-atn06ncf.js";import{sameWorktreeChanges}from"./chunk-55ajzrj6.js";import{ensureDaemonReachable,isStaleInstallError}from"./chunk-tgfn5ykb.js";import{toTaskId}from"./chunk-xy8be792.js";import{CURRENT_VERSION}from"./chunk-hgf4cz78.js";import{homeDir}from"./chunk-prqeddy7.js";import{createStateCell,mapReadableState}from"./chunk-cmp64q4j.js";import{DAEMON_PROTOCOL_VERSION,MIN_COMPATIBLE_PROTOCOL_VERSION,isAttentionInboxState,isDaemonVersionStale,isForeignDaemonHome,isProtocolCompatible,isRoutineInboxState,parseDaemonStopReason}from"./chunk-kmgheesn.js";import{parseModUiPayload}from"./chunk-szjgjrar.js";import{logClient,logClientError}from"./chunk-gskbzgc3.js";function parseWorktreeChangesPayload(payload){let changes=payload?.changes;if(!changes||typeof changes!=="object"||Array.isArray(changes))return null;let map=new Map;for(let[path,value]of Object.entries(changes)){let counts=value;if(typeof counts?.added!=="number"||typeof counts.deleted!=="number")return null;map.set(path,{added:counts.added,deleted:counts.deleted,...typeof counts.behind==="number"?{behind:counts.behind}:{},...typeof counts.ahead==="number"?{ahead:counts.ahead}:{}})}let unreadable=payload?.unreadable;if(Array.isArray(unreadable)){for(let path of unreadable)if(typeof path==="string"&&path.length>0)map.set(path,null)}return map}function sameWorktreeChangesMap(a,b){if(a.size!==b.size)return!1;for(let[path,counts]of a){if(!b.has(path))return!1;if(!sameWorktreeChanges(counts,b.get(path)??null))return!1}return!0}function parseToken(raw){if(!raw||typeof raw!=="object")return null;let t=raw;if(typeof t.source!=="string"||typeof t.key!=="string")return null;if(typeof t.text!=="string"||t.text.length===0)return null;if(typeof t.expiresAt!=="number"||!Number.isFinite(t.expiresAt))return null;return{source:t.source,key:t.key,text:t.text,...isRowTokenTone(t.tone)?{tone:t.tone}:{},expiresAt:t.expiresAt}}function parseRowTokensPayload(payload){let tokens=payload?.tokens;if(!tokens||typeof tokens!=="object"||Array.isArray(tokens))return null;let out=new Map;for(let[taskId,list]of Object.entries(tokens)){if(!Array.isArray(list))continue;let parsed=list.map(parseToken).filter((token)=>token!==null);if(parsed.length>0)out.set(taskId,parsed)}return out}function sameRowTokenMap(a,b){if(a.size!==b.size)return!1;for(let[taskId,left]of a){let right=b.get(taskId);if(!right||right.length!==left.length)return!1;for(let[i,token]of left.entries()){let other=right[i];if(!other||other.source!==token.source||other.key!==token.key||other.text!==token.text||other.tone!==token.tone||other.expiresAt!==token.expiresAt)return!1}}return!0}function liveRowTokens(map,taskId,now){let tokens=map?.get(taskId);if(!tokens||tokens.length===0)return[];return tokens.filter((token)=>token.expiresAt>now)}function shouldLogReconnectAttempt(attempt){if(attempt>100)return!1;return attempt===1||attempt%10===0}function describePayload(value){if(value===void 0)return"undefined";if(value===null)return"null";let type=Array.isArray(value)?"array":typeof value,text;try{text=typeof value==="string"?value:JSON.stringify(value)}catch{text=String(value)}if(text.length>120)text=`${text.slice(0,120)}\u2026`;return`${type}:${text}`}function decodeUiPrefsPayload(payload){let p=payload;if(!p||typeof p!=="object"||!("theme"in p))return null;if(p.theme!==null&&typeof p.theme!=="string")return null;return{theme:typeof p.theme==="string"&&p.theme.length>0?p.theme:null,..."themeMode"in p?{themeMode:typeof p.themeMode==="string"?p.themeMode:null}:{},transparentBackground:p.transparentBackground!==!1,focusAccent:typeof p.focusAccent==="string"?p.focusAccent:null,locale:typeof p.locale==="string"?p.locale:"",sortMode:p.sortMode==="recent"||p.sortMode==="attention"||p.sortMode==="name"?p.sortMode:"default",keysCollapsed:p.keysCollapsed===!0,projectFilter:typeof p.projectFilter==="string"&&p.projectFilter.length>0?p.projectFilter:null}}var TOKEN_TOTAL_FIELDS=["inputTokens","outputTokens","cacheReadTokens","cacheCreationTokens"];function parseContextUsagePayload(payload){let context=payload?.context;if(!context||typeof context!=="object"||Array.isArray(context))return null;let map=new Map;for(let[key,value]of Object.entries(context)){let v=value;if(typeof v?.contextTokens!=="number")return null;if(v.contextWindowTokens!==void 0&&typeof v.contextWindowTokens!=="number")return null;let totals={};for(let field of TOKEN_TOTAL_FIELDS){let raw=v[field];if(raw===void 0)continue;if(typeof raw!=="number")return null;totals[field]=raw}map.set(key,{contextTokens:v.contextTokens,...typeof v.contextWindowTokens==="number"?{contextWindowTokens:v.contextWindowTokens}:{},...v.approximate===!0?{approximate:!0}:{},...totals})}return map}function sameContextUsageMap(a,b){if(a.size!==b.size)return!1;for(let[key,value]of a){let other=b.get(key);if(!other||other.contextTokens!==value.contextTokens||other.contextWindowTokens!==value.contextWindowTokens||other.approximate!==value.approximate||TOKEN_TOTAL_FIELDS.some((field)=>other[field]!==value[field]))return!1}return!0}function parseUsageSnapshotPayload(payload){let usage=payload?.usage;if(!usage||typeof usage!=="object"||Array.isArray(usage))return null;let map=new Map;for(let[vendor,value]of Object.entries(usage)){let snapshot=value;if(typeof snapshot?.capturedAt!=="number"||!Array.isArray(snapshot.windows))return null;let windows=[];for(let raw of snapshot.windows){let w=raw;if(typeof w?.kind!=="string"||typeof w.label!=="string"||typeof w.percent!=="number")return null;if(w.resetsAt!==null&&typeof w.resetsAt!=="number")return null;windows.push({kind:w.kind,label:w.label,percent:w.percent,resetsAt:w.resetsAt})}map.set(vendor,{windows,capturedAt:snapshot.capturedAt})}return map}function sameUsageSnapshotMap(a,b){if(a.size!==b.size)return!1;for(let[vendor,usage]of a){let other=b.get(vendor);if(!other||other.capturedAt!==usage.capturedAt||other.windows.length!==usage.windows.length)return!1;for(let i=0;i<usage.windows.length;i++){let x=usage.windows[i],y=other.windows[i];if(!x||!y||x.kind!==y.kind||x.label!==y.label||x.percent!==y.percent||x.resetsAt!==y.resetsAt)return!1}}return!0}function parseTranscriptActivityPayload(payload){let activity=payload?.activity;if(!activity||typeof activity!=="object"||Array.isArray(activity))return null;let map=new Map;for(let[path,value]of Object.entries(activity)){let v=value;if(typeof v?.mtimeMs!=="number"||typeof v.completionAt!=="number")return null;if(v.completionId!==null&&typeof v.completionId!=="string")return null;map.set(path,{mtimeMs:v.mtimeMs,completionId:v.completionId,completionAt:v.completionAt})}return map}function sameTranscriptActivityMap(a,b){if(a.size!==b.size)return!1;for(let[path,v]of a){let other=b.get(path);if(!other||other.mtimeMs!==v.mtimeMs||other.completionId!==v.completionId||other.completionAt!==v.completionAt)return!1}return!0}function deserializeTask(s){return{id:toTaskId(s.id),title:s.title,repo:s.repo,branch:s.branch,worktreePath:s.worktreePath,kind:s.kind,...s.scratch?{scratch:!0}:{},...s.routine?{routine:s.routine}:{},status:s.status,pinned:s.pinned,vendor:s.vendor,command:s.command,prStatus:s.prStatus,modelEffort:s.modelEffort,model:s.model,tier:s.tier,groupId:s.groupId,observedLanguage:s.observedLanguage,deletion:s.deletion,quotaResume:s.quotaResume,linkedWorkItem:s.linkedWorkItem,dispatcher:s.dispatcher,requireReport:s.requireReport,prompt:s.prompt,baseRef:s.baseRef,worktreeName:s.worktreeName,report:s.report,...s.repoId?{repoId:s.repoId}:{},createdAt:s.createdAt,updatedAt:s.updatedAt}}async function runReconnectLoop(deps){let delayMs=deps.spawnDaemon?Math.floor(Math.random()*400):500,attempt=0;while(!deps.isDisposed()){if(delayMs>0)await new Promise((r)=>setTimeout(r,delayMs));if(deps.isDisposed())break;attempt++;try{if(deps.spawnDaemon)await deps.ensureReachable();await deps.init(),logClient("orch",`reconnected and re-subscribed after ${attempt} attempt(s) \u2014 task list re-synced`);return}catch(err){if(isStaleInstallError(err)){logClientError("orch-reconnect-fatal",err),deps.onFatal?.(err);return}if(deps.shouldLogAttempt(attempt))logClientError("orch-reconnect",err);delayMs=delayMs===0?500:Math.min(delayMs*2,3000)}}}async function performInit(client,opts,signals){let hello=await client.request("hello",{protocolVersion:DAEMON_PROTOCOL_VERSION,minProtocolVersion:MIN_COMPATIBLE_PROTOCOL_VERSION}),daemonVersion=typeof hello.protocolVersion==="number"?hello.protocolVersion:DAEMON_PROTOCOL_VERSION,daemonMin=typeof hello.minProtocolVersion==="number"?hello.minProtocolVersion:daemonVersion;if(!isProtocolCompatible({localVersion:DAEMON_PROTOCOL_VERSION,localMin:MIN_COMPATIBLE_PROTOCOL_VERSION,remoteVersion:daemonVersion,remoteMin:daemonMin}))throw Error(`Rove daemon is protocol v${daemonVersion} (min v${daemonMin}); this client is v${DAEMON_PROTOCOL_VERSION} (min v${MIN_COMPATIBLE_PROTOCOL_VERSION}). Restart the daemon (\`rove daemon restart\`) or upgrade Rove.`);let clientHome=homeDir();if(!opts.expectForeignHome&&isForeignDaemonHome(hello.homeDir,clientHome))throw Error(`Rove daemon on this socket serves ${hello.homeDir}, but this client uses ${clientHome}. A sandbox or dev daemon has taken the production socket \u2014 stop it (\`rove daemon stop\`), or unset ROVE_DAEMON_SOCKET_PATH / ROVE_DAEMON_SOCKET_PATH before starting it.`);if(signals.setDaemonVersionSig(typeof hello.roveVersion==="string"?hello.roveVersion:null),opts.onPeerIdentity?.({hostname:typeof hello.hostname==="string"?hello.hostname:"",homeDir:typeof hello.homeDir==="string"?hello.homeDir:"",daemonPid:typeof hello.daemonPid==="number"?hello.daemonPid:0,roveVersion:typeof hello.roveVersion==="string"?hello.roveVersion:""}),signals.setDaemonRestartingSig(!1),hello.tasks&&opts.subscribesTasks)signals.setTasks(hello.tasks.map(deserializeTask));if(await client.subscribe({role:opts.role,channels:opts.channels,cellPixelSize:opts.cellPixelSize}),hello.capabilities?.includes("worktree.changes")){if(signals.worktreeChangesAcc()===null)signals.setWorktreeChangesSig(new Map)}else signals.setWorktreeChangesSig(null);if(hello.capabilities?.includes("transcript.activity")){if(signals.transcriptActivityAcc()===null)signals.setTranscriptActivitySig(new Map)}else signals.setTranscriptActivitySig(null);signals.setConnectionState("online"),logClient("orch",`subscribed as ${opts.role} (${signals.tasksAcc().length} tasks)`)}function ordinalOf(tabId,fallback){let match=/^tab-(\d+)$/.exec(tabId);return match?Number(match[1]):fallback}function adoptTabs(state,tabIds){let known=new Set(state.tabs.map((tab)=>tab.id)),fresh=[];for(let id of tabIds){if(known.has(id))continue;known.add(id),fresh.push(id)}if(fresh.length===0)return state;let minted=state.nextOrdinal,adopted=fresh.map((id)=>({kind:"engine",id,title:null,ordinal:ordinalOf(id,minted++),spawned:!0}));adopted.sort((a,b)=>a.ordinal-b.ordinal);let tabs=[...state.tabs,...adopted],maxOrdinal=tabs.reduce((max,tab)=>Math.max(max,tab.ordinal),0);return{tabs,activeId:state.activeId,nextOrdinal:Math.max(state.nextOrdinal,maxOrdinal+1)}}function isAddedTab(raw){if(typeof raw!=="object"||raw===null)return!1;if(!("id"in raw)||typeof raw.id!=="string")return!1;if(!("ordinal"in raw)||typeof raw.ordinal!=="number")return!1;if(!("title"in raw)||raw.title!==null&&typeof raw.title!=="string")return!1;if(!("kind"in raw))return!1;if(raw.kind==="engine")return!0;return raw.kind==="command"&&"command"in raw&&Array.isArray(raw.command)}function absorbTab(state,tab){let nextOrdinal=Math.max(state.nextOrdinal,tab.ordinal+1),known=state.tabs.find((t)=>t.id===tab.id);if(known?.kind===tab.kind){if(Object.entries(tab).every(([key,value])=>JSON.stringify(Reflect.get(known,key))===JSON.stringify(value))&&nextOrdinal===state.nextOrdinal)return state}let merged=known?.kind===tab.kind?{...known,...tab,title:known.title}:tab,tabs=known?state.tabs.map((t)=>t===known?merged:t):[...state.tabs,merged];return{...state,tabs,nextOrdinal}}var MAP_CHANNELS={"usage.snapshot":{what:"usage payload",parse:parseUsageSnapshotPayload,same:sameUsageSnapshotMap,read:(signals)=>signals.usageSnapshotAcc(),write:(signals,next)=>signals.setUsageSnapshotSig(next)},"usage.context":{what:"context payload",parse:parseContextUsagePayload,same:sameContextUsageMap,read:(signals)=>signals.contextUsageAcc(),write:(signals,next)=>signals.setContextUsageSig(next)},"worktree.changes":{what:"changes payload",parse:parseWorktreeChangesPayload,same:sameWorktreeChangesMap,read:(signals)=>signals.worktreeChangesAcc(),write:(signals,next)=>signals.setWorktreeChangesSig(next)},"transcript.activity":{what:"activity payload",parse:parseTranscriptActivityPayload,same:sameTranscriptActivityMap,read:(signals)=>signals.transcriptActivityAcc(),write:(signals,next)=>signals.setTranscriptActivitySig(next)},"mod.ui":{what:"mod pane list",parse:parseModUiPayload,same:(a,b)=>JSON.stringify(a)===JSON.stringify(b),read:(signals)=>signals.modPanesAcc(),write:(signals,next)=>signals.setModPanesSig(next)},"task.tokens":{what:"token map",parse:parseRowTokensPayload,same:sameRowTokenMap,read:(signals)=>signals.rowTokensAcc(),write:(signals,next)=>signals.setRowTokensSig(next)}};function handleMapChannel(name,payload,signals){let channel=MAP_CHANNELS[name];if(!channel)return!1;let next=channel.parse(payload);if(!next)return logClientError("orch",`dropped ${name} event: malformed ${channel.what} (${describePayload(payload)})`),!0;let current=channel.read(signals);if(current&&channel.same(current,next))return!0;return channel.write(signals,next),!0}function writeGraphicsToStdout(data){if(!process.stdout.isTTY)return;process.stdout.write(data)}function pruneEngineState(tasks,signals){let live=new Set(tasks.map((t)=>t.id)),current=signals.engineStateAcc();if(current.size>0){let next=null;for(let key of current.keys()){if(live.has(key))continue;if(!next)next=new Map(current);next.delete(key)}if(next)signals.setEngineStateSig(next)}let tabs=signals.engineTabStateAcc();if(tabs.size>0){let nextTabs=null;for(let key of tabs.keys()){if(live.has(key))continue;if(!nextTabs)nextTabs=new Map(tabs);nextTabs.delete(key)}if(nextTabs)signals.setEngineTabStateSig(nextTabs)}let lifecycle=signals.engineLifecycleAcc();if(lifecycle.size>0){let nextLifecycle=null;for(let key of lifecycle.keys()){if(live.has(key))continue;if(!nextLifecycle)nextLifecycle=new Map(lifecycle);nextLifecycle.delete(key)}if(nextLifecycle)signals.setEngineLifecycleSig(nextLifecycle)}}function pruneTaskJobs(tasks,signals){let current=signals.taskJobsAcc();if(current.size===0)return;let live=new Set(tasks.map((t)=>t.id)),next=null;for(let key of current.keys()){if(live.has(key))continue;if(!next)next=new Map(current);next.delete(key)}if(next)signals.setTaskJobsSig(next)}function handleOrchestratorEvent(name,payload,signals){if(name==="task.snapshot"){let value=payload?.tasks;if(Array.isArray(value))signals.setTasks(value.map(deserializeTask)),pruneEngineState(value,signals),pruneTaskJobs(value,signals);else logClientError("orch",`dropped task.snapshot event: tasks is not an array (got ${describePayload(value)})`);return}if(name==="daemon.stopping"){let p=payload;if(typeof p?.roveVersion==="string")signals.setDaemonVersionSig(p.roveVersion);if(parseDaemonStopReason(p?.reason)==="restart")signals.setDaemonRestartingSig(!0);return}if(name==="active-task"){let id=payload?.taskId;signals.setActiveTaskSig(typeof id==="string"?id:null);return}if(name==="update"){let info=payload?.info;signals.setUpdateSig(info??null);return}if(name==="engine-state"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.state!=="string"){logClientError("orch",`dropped engine-state event: taskId/state must be strings (taskId=${describePayload(p?.taskId)}, state=${describePayload(p?.state)})`);return}let tabId=typeof p.tabId==="string"&&p.tabId?p.tabId:void 0,entry={state:p.state,detail:p.detail,...typeof p.sessionId==="string"&&p.sessionId?{sessionId:p.sessionId}:{},...typeof p.transcriptPath==="string"&&p.transcriptPath?{transcriptPath:p.transcriptPath}:{},...tabId?{tabId}:{},at:typeof p.at==="number"?p.at:0},prevTaskState=signals.engineStateAcc().get(p.taskId)?.state;if(!tabId){let next=new Map(signals.engineStateAcc());if(p.state==="idle")next.delete(p.taskId);else next.set(p.taskId,entry);signals.setEngineStateSig(next)}if((p.state==="idle"||p.state==="turn_complete"||p.state==="error"||p.state==="running"&&prevTaskState!=="running")&&signals.engineLifecycleAcc().has(p.taskId)){let lifecycle=new Map(signals.engineLifecycleAcc());lifecycle.delete(p.taskId),signals.setEngineLifecycleSig(lifecycle)}if(tabId){let nextTabs=new Map(signals.engineTabStateAcc()),tabs=new Map(nextTabs.get(p.taskId)??[]);tabs.set(tabId,entry),nextTabs.set(p.taskId,tabs),signals.setEngineTabStateSig(nextTabs)}return}if(name==="attention.inbox"){let items=payload?.items;if(!Array.isArray(items)){logClientError("orch",`dropped attention.inbox event: items is not an array (${describePayload(items)})`);return}let kept=items.filter((item)=>{if(!item||typeof item!=="object"||Array.isArray(item))return!1;let p=item;return(typeof p.taskId==="string"||p.taskId===null&&isRoutineInboxState(p.state))&&(p.tabId===null||typeof p.tabId==="string")&&isAttentionInboxState(p.state)&&(p.unread===void 0||typeof p.unread==="boolean")&&typeof p.at==="number"});if(kept.length!==items.length)logClientError("orch",`dropped ${items.length-kept.length} malformed attention.inbox item(s) of ${items.length} (${describePayload(items)})`);if(kept.length===0&&items.length>0)return;signals.setAttentionInboxSig(kept.map((item)=>({...item,unread:item.unread!==!1})));return}if(name==="gates"){let gates=payload?.gates;if(!Array.isArray(gates)){logClientError("orch",`dropped gates event: gates is not an array (${describePayload(gates)})`);return}let kept=gates.filter((g)=>{if(!g||typeof g!=="object"||Array.isArray(g))return!1;let p=g;return typeof p.id==="string"&&typeof p.taskId==="string"&&typeof p.question==="string"});if(kept.length===0&&gates.length>0)return;signals.setGatesSig(kept.map((g)=>({...g,options:Array.isArray(g.options)?g.options:[]})));return}if(name==="task.jobs"){let p=payload;if(typeof p?.taskId!=="string"||p.kind!=="ensureWorktree"){logClientError("orch",`dropped task.jobs event: expected string taskId + kind "ensureWorktree" (taskId=${describePayload(p?.taskId)}, kind=${describePayload(p?.kind)})`);return}let current=signals.taskJobsAcc();if(p.phase==="running"){let next=new Map(current);next.set(p.taskId,{kind:p.kind}),signals.setTaskJobsSig(next);return}if((p.phase==="done"||p.phase==="error")&¤t.has(p.taskId)){let next=new Map(current);next.delete(p.taskId),signals.setTaskJobsSig(next)}return}if(handleMapChannel(name,payload,signals))return;if(name==="tab.open"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.at!=="number"||typeof p.title!=="string"||!Array.isArray(p.argv)){logClientError("orch",`dropped tab.open event: malformed payload (${describePayload(payload)})`);return}signals.setTabOpenSig(p);return}if(name==="tab.close"){let p=payload;if(!(p&&"kind"in p&&p.kind==="terminal-tab"?typeof p.taskId==="string"&&typeof p.tabId==="string"&&typeof p.requestId==="string"&&typeof p.at==="number":typeof p?.taskId==="string"&&typeof p.at==="number"&&("title"in p)&&typeof p.title==="string")){logClientError("orch",`dropped tab.close event: malformed payload (${describePayload(payload)})`);return}signals.setTabCloseSig(p);return}if(name==="tab.rename"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.tabId!=="string"||typeof p.title!=="string"||typeof p.at!=="number"){logClientError("orch",`dropped tab.rename event: malformed payload (${describePayload(payload)})`);return}signals.setTabRenameSig(p);return}if(name==="tabs.changed"){let p=payload,state=p?.state;if(typeof p?.taskId!=="string"||typeof p.rev!=="number"||state!==null&&(typeof state!=="object"||!Array.isArray(state?.tabs))){logClientError("orch",`dropped tabs.changed event: malformed payload (${describePayload(payload)})`);return}signals.emitTabsChanged(p);return}if(name==="row.status"){let p=payload;if(typeof p?.rev!=="number"||typeof p.tasks!=="object"||p.tasks===null){logClientError("orch",`dropped row.status event: malformed payload (${describePayload(payload)})`);return}signals.emitRowStatus(p);return}if(name==="tab.add"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.at!=="number"||!isAddedTab(p.tab)){logClientError("orch",`dropped tab.add event: malformed payload (${describePayload(payload)})`);return}signals.setTabAddSig({taskId:p.taskId,tab:p.tab,at:p.at});return}if(name==="ui.prompt"){let p=payload;if(typeof p?.promptId!=="string"||typeof p.title!=="string"||typeof p.at!=="number"){logClientError("orch",`dropped ui.prompt event: malformed payload (${describePayload(payload)})`);return}signals.setUiPromptSig(p);return}if(name==="engine.lifecycle"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.kind!=="string"){logClientError("orch",`dropped engine.lifecycle event: malformed payload (${describePayload(payload)})`);return}let prev=signals.engineLifecycleAcc(),cur=prev.get(p.taskId)??{subagents:0},entry=p.kind==="subagent-start"?{subagents:cur.subagents+1}:p.kind==="subagent-stop"?{subagents:Math.max(0,cur.subagents-1)}:cur;if(entry===cur&&!prev.has(p.taskId))return;let map=new Map(prev);if(entry.subagents===0)map.delete(p.taskId);else map.set(p.taskId,entry);signals.setEngineLifecycleSig(map);return}if(name==="graphics.write"){let p=payload;if(typeof p?.data!=="string"||typeof p.imageId!=="number"||typeof p.at!=="number"){logClientError("orch",`dropped graphics.write event: malformed payload (${describePayload(payload)})`);return}signals.writeGraphics(Buffer.from(p.data,"base64"));return}if(name==="notice.event"){let p=payload;if(typeof p?.title!=="string"||typeof p.at!=="number"||typeof p.kind!=="string"){logClientError("orch",`dropped notice.event: malformed payload (${describePayload(payload)})`);return}signals.setNoticeSig(p);return}if(name==="ui-prefs"){let decoded=decodeUiPrefsPayload(payload);if(!decoded){let theme=payload?.theme;logClientError("orch",`dropped ui-prefs event: theme must be a string (got ${describePayload(theme)})`);return}signals.setUiPrefsSig(decoded);return}if(name==="keybindings"){let p=payload;if(typeof p?.rev!=="number"){logClientError("orch",`dropped keybindings event: rev must be a number (got ${describePayload(p?.rev)})`);return}signals.setKeybindingsRevSig(p.rev)}}function subscribeTasksOp(tasks,listener){try{listener(tasks())}catch(err){console.error("[rove RemoteOrchestrator] task listener threw on subscribe:",err)}return tasks.subscribe(()=>{try{listener(tasks.get())}catch(err){console.error("[rove RemoteOrchestrator] task listener threw:",err)}})}class RowStatusChannel{client;listeners=new Set;constructor(client){this.client=client}emit=(payload)=>{for(let listener of this.listeners)listener(payload)};onChanged=(listener)=>{return this.listeners.add(listener),()=>this.listeners.delete(listener)};list=()=>this.client.request("status.list");viewing=(taskId,tabId)=>this.client.request("ui.viewing",taskId===null?{taskId:null}:{taskId,...tabId?{tabId}:{}});answered=(taskId,tabId)=>this.client.request("activity.answered",{taskId,tabId})}class TabsChannel{client;listeners=new Set;constructor(client){this.client=client}emit=(event)=>{for(let listener of this.listeners)listener(event)};onChanged=(listener)=>{return this.listeners.add(listener),()=>this.listeners.delete(listener)};apply=(taskId,ops)=>this.client.request("tabs.apply",{taskId,ops});list=()=>this.client.request("tabs.list");reserve=(taskId,count)=>this.client.request("tabs.reserve",{taskId,count});release=(taskId,from,to)=>this.client.request("tabs.release",{taskId,from,to})}async function createTaskOp(client,input){let{modelEffort,...rest}=input,res=await client.request("task.create",{...rest,effort:modelEffort});return deserializeTask(res.task)}async function ensureMainTaskOp(client,repo){let res=await client.request("task.ensureMain",{repo});return deserializeTask(res.task)}async function openDirectoryTaskOp(client,input){let res=await client.request("task.openDir",input);return deserializeTask(res.task)}async function adoptScratchRepoOp(client,id,repo){await client.request("task.adoptScratchRepo",{taskId:String(id),repo})}async function ensureWorktreeOp(client,id){return(await client.request("task.ensureWorktree",{taskId:String(id)})).worktreePath}async function forgetProjectOp(client,repo){await client.request("project.forget",{repo})}function reportEngineInterruptOp(client,taskId,tabId){client.request("engine.reportEvent",{kind:"turn-interrupted",taskId,tabId}).catch(()=>{})}async function setTitleOp(client,id,title){await client.request("task.rename",{taskId:String(id),title})}async function setBranchOp(client,id,branch){await client.request("task.setBranch",{taskId:String(id),branch})}async function setVendorOp(client,id,vendor,effort,model){await client.request("task.setVendor",{taskId:String(id),vendor,...effort!==void 0?{effort}:{},...model!==void 0?{model}:{}})}async function setCommandOp(client,id,command,vendor){await client.request("task.setCommand",{taskId:String(id),command,...vendor?{vendor}:{}})}async function setPinnedOp(client,id,pinned){await client.request("task.pin",{taskId:String(id),pinned})}async function moveTaskOp(client,id,delta){await client.request("task.move",{taskId:String(id),direction:delta<0?"up":"down"})}async function moveTaskToTopOp(client,id){await client.request("task.move",{taskId:String(id),direction:"top"})}async function setPromptOp(client,id,prompt){await client.request("task.setPrompt",{taskId:String(id),prompt})}async function setStatusOp(client,id,status){await client.request("task.status",{taskId:String(id),status})}async function deleteTaskOp(client,id,opts){await client.request("task.delete",{taskId:String(id),force:opts?.force,deleteBranch:opts?.deleteBranch})}async function dismissAttentionOp(client,taskId,tabId,at,deliveryId){return(await client.request("attention.dismiss",{taskId:String(taskId),...tabId!==null?{tabId}:{},at,...deliveryId!==void 0?{deliveryId}:{}})).deleted}async function dismissRoutineAttentionOp(client,automationId){return(await client.request("attention.dismissRoutine",{automationId})).deleted}async function answerGateOp(client,gateId,answer){return{delivered:(await client.request("gate.answer",{gateId,...answer,by:"tui"})).delivered}}async function withdrawGateOp(client,gateId){await client.request("gate.withdraw",{gateId})}async function markAttentionReadOp(client,taskId,tabId,at){return(await client.request("attention.read",{taskId:String(taskId),...tabId!==null?{tabId}:{},at})).updated}async function landPreflightOp(client,id){return(await client.request("task.landPreflight",{taskId:String(id)})).result}async function landTaskOp(client,id,opts){return(await client.request("task.land",{taskId:String(id),strategy:opts?.strategy,deleteBranch:opts?.deleteBranch,removeWorktree:opts?.removeWorktree,callerCwd:opts?.callerCwd})).result}async function discoverAdoptableWorktreesOp(client,repo){return(await client.request("worktree.discoverAdoptable",{repo})).worktrees}async function adoptWorktreeOp(client,input){let res=await client.request("worktree.adopt",input);return deserializeTask(res.task)}async function listWorktreesOp(client,opts){return(await client.request("worktree.list",{network:opts?.network!==!1})).projects}async function removeWorktreeOp(client,path,force){return(await client.request("worktree.remove",{path,force})).residue??null}async function syncBaseOp(client,taskId){return(await client.request("task.syncBase",{taskId})).result}async function failingChecksOp(client,taskId){let res=await client.request("pr.failingChecks",{taskId});return{checks:res.checks??[],totalFailing:res.totalFailing??0,...res.unavailable?{unavailable:res.unavailable}:{}}}async function rerunFailedChecksOp(client,taskId){let res=await client.request("pr.rerunFailedChecks",{taskId});return{rerunRuns:res.rerunRuns??0,external:res.external??0,...res.refused?{refused:res.refused}:{},...res.unavailable?{unavailable:res.unavailable}:{}}}async function listIssuesOp(client,repoRoot){return client.request("issue.list",{repoRoot})}async function listIssueReposOp(client){return(await client.request("issue.repos",{})).repos??[]}async function listFieldNotesOp(client,repo){return(await client.request("note.list",{repo})).notes??[]}async function deleteFieldNoteOp(client,repo,id){return(await client.request("note.delete",{repo,id})).deleted===!0}async function mutateIssueOp(client,repoRoot,op){return client.request("issue.mutate",{repoRoot,op})}async function listAutomationsOp(client){return client.request("automation.list",{})}async function createAutomationOp(client,input){return client.request("automation.create",input)}async function automationRunsOp(client,id){return client.request("automation.runs",{id})}async function setAutomationEnabledOp(client,id,enabled){return client.request("automation.update",{id,enabled})}async function runAutomationNowOp(client,id){return client.request("automation.runNow",{id})}async function deleteAutomationOp(client,id){return client.request("automation.delete",{id})}async function listWorkItemsOp(client,args){return client.request("workitem.list",args)}async function startWorkItemOp(client,args){return client.request("workitem.start",args)}async function setActiveTaskOp(client,id){await client.request("task.setActive",{taskId:id===null?null:String(id)})}function replyTabCloseOp(client,requestId,closed){client.request("terminalTab.closeReply",{requestId,closed}).catch(()=>{})}function replyPromptOp(client,promptId,value){client.request("ui.promptReply",{promptId,...value!==void 0?{value}:{}}).catch(()=>{})}function reportUiEventOp(client,kind,taskId,detail){client.request("ui.reportEvent",{kind,...taskId?{taskId}:{},...detail?{detail}:{}}).catch(()=>{})}function recentTaskEventsOp(client,id){return client.request("task.recentEvents",{taskId:String(id)})}class RemoteOrchestrator{client;tasksAcc=createStateCell([],"orchestrator.tasks");activeTaskAcc=createStateCell(null,"orchestrator.active-task");updateAcc=createStateCell(null);daemonVersionAcc=createStateCell(null);daemonRestartingAcc=createStateCell(!1);daemonStaleAcc=mapReadableState(this.daemonVersionAcc,(version)=>isDaemonVersionStale(version??void 0,CURRENT_VERSION));engineStateAcc=createStateCell(new Map);engineTabStateAcc=createStateCell(new Map);attentionInboxAcc=createStateCell([]);gatesAcc=createStateCell([]);taskJobsAcc=createStateCell(new Map);rowTokensAcc=createStateCell(new Map);modPanesAcc=createStateCell([]);worktreeChangesAcc=createStateCell(null);usageSnapshotAcc=createStateCell(null);contextUsageAcc=createStateCell(null);transcriptActivityAcc=createStateCell(null);noticeAcc=createStateCell(null);tabOpenAcc=createStateCell(null);tabCloseAcc=createStateCell(null);tabRenameAcc=createStateCell(null);tabAddAcc=createStateCell(null);tabs;rowStatus;uiPromptAcc=createStateCell(null);engineLifecycleAcc=createStateCell(new Map);uiPrefsAcc=createStateCell(null);keybindingsRevAcc=createStateCell(null);connectionStateAcc=createStateCell("online","orchestrator.connection");staleInstallAcc=createStateCell(null);ensureReachable;role;cellPixelSize;channels;subscribesTasks;expectForeignHome;onPeerIdentity;reconnectTask=null;signals;constructor(client,options={}){this.client=client;this.ensureReachable=options.ensureReachable??ensureDaemonReachable,this.role=options.role??"pane",this.cellPixelSize=options.cellPixelSize??null,this.channels=options.channels,this.subscribesTasks=!options.channels||options.channels.includes("task.snapshot"),this.expectForeignHome=options.expectForeignHome===!0,this.onPeerIdentity=options.onPeerIdentity,this.tabs=new TabsChannel(client),this.rowStatus=new RowStatusChannel(client),this.signals={writeGraphics:options.graphicsOut??(this.role==="gui"?writeGraphicsToStdout:()=>{}),tasksAcc:this.tasksAcc,setTasks:this.tasksAcc.set,setActiveTaskSig:this.activeTaskAcc.set,setUpdateSig:this.updateAcc.set,setDaemonVersionSig:this.daemonVersionAcc.set,setDaemonRestartingSig:this.daemonRestartingAcc.set,engineStateAcc:this.engineStateAcc,setEngineStateSig:this.engineStateAcc.set,engineTabStateAcc:this.engineTabStateAcc,setEngineTabStateSig:this.engineTabStateAcc.set,setAttentionInboxSig:this.attentionInboxAcc.set,setGatesSig:this.gatesAcc.set,taskJobsAcc:this.taskJobsAcc,setTaskJobsSig:this.taskJobsAcc.set,rowTokensAcc:this.rowTokensAcc,setRowTokensSig:this.rowTokensAcc.set,modPanesAcc:this.modPanesAcc,setModPanesSig:this.modPanesAcc.set,worktreeChangesAcc:this.worktreeChangesAcc,setWorktreeChangesSig:this.worktreeChangesAcc.set,usageSnapshotAcc:this.usageSnapshotAcc,setUsageSnapshotSig:this.usageSnapshotAcc.set,contextUsageAcc:this.contextUsageAcc,setContextUsageSig:this.contextUsageAcc.set,transcriptActivityAcc:this.transcriptActivityAcc,setTranscriptActivitySig:this.transcriptActivityAcc.set,setNoticeSig:this.noticeAcc.set,setTabOpenSig:this.tabOpenAcc.set,setTabCloseSig:this.tabCloseAcc.set,setTabRenameSig:this.tabRenameAcc.set,setTabAddSig:this.tabAddAcc.set,emitTabsChanged:this.tabs.emit,emitRowStatus:this.rowStatus.emit,setUiPromptSig:this.uiPromptAcc.set,engineLifecycleAcc:this.engineLifecycleAcc,setEngineLifecycleSig:this.engineLifecycleAcc.set,setUiPrefsSig:this.uiPrefsAcc.set,setKeybindingsRevSig:this.keybindingsRevAcc.set,setConnectionState:this.connectionStateAcc.set},this.client.on("*",(frame)=>handleOrchestratorEvent(frame.name,frame.payload,this.signals)),this.client.onLifecycle("close",()=>{this.connectionStateAcc.set("disconnected");let spawnDaemon=this.role==="gui";logClient("orch",spawnDaemon?"daemon socket closed \u2014 starting silent spawning reconnect loop":"daemon socket closed \u2014 starting non-spawning reconnect loop"),this.reconnectLoop(spawnDaemon)})}reconnectLoop(spawnDaemon){if(this.reconnectTask)return this.reconnectTask;let task=runReconnectLoop({isDisposed:()=>this.client.isDisposed,spawnDaemon,ensureReachable:this.ensureReachable,init:()=>this.init(),shouldLogAttempt:shouldLogReconnectAttempt,onFatal:(err)=>this.staleInstallAcc.set(err instanceof Error?err.message:String(err))});this.reconnectTask=task;let clear=()=>{if(this.reconnectTask===task)this.reconnectTask=null};return task.then(clear,clear),task}writeGraphics(data){this.signals.writeGraphics(data)}async init(){await performInit(this.client,{role:this.role,cellPixelSize:this.cellPixelSize,channels:this.channels,subscribesTasks:this.subscribesTasks,expectForeignHome:this.expectForeignHome,onPeerIdentity:this.onPeerIdentity},this.signals)}connectionStateSignal(){return this.connectionStateAcc}staleInstallSignal(){return this.staleInstallAcc}async manualReconnect(){this.client.forceDisconnect(),await this.reconnectLoop(!0)}dispose(){this.client.close()}tasksSignal=()=>this.tasksAcc;activeTaskSignal=()=>this.activeTaskAcc;updateSignal=()=>this.updateAcc;daemonVersionSignal=()=>this.daemonVersionAcc;daemonStaleSignal=()=>this.daemonStaleAcc;daemonRestartingSignal=()=>this.daemonRestartingAcc;async restartDaemon(){await this.client.request("daemon.stop",{reason:"restart"}).catch(()=>{})}engineStateSignal=()=>this.engineStateAcc;engineTabStatesSignal=()=>this.engineTabStateAcc;attentionInboxSignal=()=>this.attentionInboxAcc;gatesSignal=()=>this.gatesAcc;taskJobsSignal=()=>this.taskJobsAcc;rowTokensSignal=()=>this.rowTokensAcc;modPanesSignal=()=>this.modPanesAcc;pressMod=(plugin,pane,key)=>this.client.request("mod.press",{plugin,pane,key});submitMod=(plugin,pane,key,value)=>this.client.request("mod.submit",{plugin,pane,key,value});worktreeChangesSignal=()=>this.worktreeChangesAcc;usageSnapshotSignal=()=>this.usageSnapshotAcc;contextUsageSignal=()=>this.contextUsageAcc;transcriptActivitySignal=()=>this.transcriptActivityAcc;transcriptActivityStore=()=>this.transcriptActivityAcc;noticeStore=()=>this.noticeAcc;tabOpenStore=()=>this.tabOpenAcc;tabCloseStore=()=>this.tabCloseAcc;tabRenameStore=()=>this.tabRenameAcc;tabAddStore=()=>this.tabAddAcc;rpc={request:(name,payload)=>this.client.request(name,payload)};replyTerminalTabClose=(requestId,closed)=>replyTabCloseOp(this.client,requestId,closed);uiPromptStore=()=>this.uiPromptAcc;replyPrompt=(promptId,value)=>replyPromptOp(this.client,promptId,value);engineLifecycleSignal=()=>this.engineLifecycleAcc;recentTaskEvents(id){return recentTaskEventsOp(this.client,id)}reportUiEvent=(kind,taskId,detail)=>reportUiEventOp(this.client,kind,taskId,detail);reportScreenInput=async(taskId,tabId,blocked)=>{await this.client.request("engine.reportEvent",{source:"screen",taskId,tabId,blocked})};reportEngineInterrupt=(taskId,tabId)=>reportEngineInterruptOp(this.client,String(taskId),tabId);uiPrefsSignal=()=>this.uiPrefsAcc;uiPrefsStore=()=>this.uiPrefsAcc;keybindingsRevSignal=()=>this.keybindingsRevAcc;keybindingsRevStore=()=>this.keybindingsRevAcc;listTasks=()=>this.tasksAcc();getTask=(id)=>this.tasksAcc().find((task)=>task.id===id);subscribeTasks(listener){return subscribeTasksOp(this.tasksAcc,listener)}createTask=(input)=>createTaskOp(this.client,input);ensureMainTask=(repo)=>ensureMainTaskOp(this.client,repo);openDirectoryTask=(input)=>openDirectoryTaskOp(this.client,input);adoptScratchRepo=(id,repo)=>adoptScratchRepoOp(this.client,id,repo);ensureWorktree=(id)=>ensureWorktreeOp(this.client,id);forgetProject=(repo)=>forgetProjectOp(this.client,repo);setTitle=(id,title)=>setTitleOp(this.client,id,title);setBranch=(id,branch)=>setBranchOp(this.client,id,branch);setVendor=(id,vendor,effort,model)=>setVendorOp(this.client,id,vendor,effort,model);setCommand=(id,command,vendor)=>setCommandOp(this.client,id,command,vendor);setPinned=(id,pinned)=>setPinnedOp(this.client,id,pinned);moveTask=(id,delta)=>moveTaskOp(this.client,id,delta);moveTaskToTop=(id)=>moveTaskToTopOp(this.client,id);setStatus=(id,status)=>setStatusOp(this.client,id,status);setPrompt=(id,prompt)=>setPromptOp(this.client,id,prompt);deleteTask=(id,opts)=>deleteTaskOp(this.client,id,opts);dismissAttention=(taskId,tabId,at,deliveryId)=>dismissAttentionOp(this.client,taskId,tabId,at,deliveryId);dismissRoutineAttention=(automationId)=>dismissRoutineAttentionOp(this.client,automationId);markAttentionRead=(taskId,tabId,at)=>markAttentionReadOp(this.client,taskId,tabId,at);answerGate=(gateId,answer)=>answerGateOp(this.client,gateId,answer);withdrawGate=(gateId)=>withdrawGateOp(this.client,gateId);landPreflight(id){return landPreflightOp(this.client,id)}landTask(id,opts){return landTaskOp(this.client,id,opts)}discoverAdoptableWorktrees(repo){return discoverAdoptableWorktreesOp(this.client,repo)}adoptWorktree(input){return adoptWorktreeOp(this.client,input)}listWorktrees(opts){return listWorktreesOp(this.client,opts)}listIssues(repoRoot){return listIssuesOp(this.client,repoRoot)}listIssueRepos(){return listIssueReposOp(this.client)}mutateIssue(repoRoot,op){return mutateIssueOp(this.client,repoRoot,op)}listAutomations=()=>listAutomationsOp(this.client);createAutomation=(i)=>createAutomationOp(this.client,i);automationRuns=(id)=>automationRunsOp(this.client,id);setAutomationEnabled=(id,on)=>setAutomationEnabledOp(this.client,id,on);runAutomationNow=(id)=>runAutomationNowOp(this.client,id);deleteAutomation=(id)=>deleteAutomationOp(this.client,id);listWorkItems=(a)=>listWorkItemsOp(this.client,a);listFieldNotes=(repo)=>listFieldNotesOp(this.client,repo);deleteFieldNote=(repo,id)=>deleteFieldNoteOp(this.client,repo,id);failingChecks=(taskId)=>failingChecksOp(this.client,taskId);rerunFailedChecks=(taskId)=>rerunFailedChecksOp(this.client,taskId);syncBase=(taskId)=>syncBaseOp(this.client,taskId);startWorkItem=(a)=>startWorkItemOp(this.client,a);removeWorktree(path,force){return removeWorktreeOp(this.client,path,force)}setActiveTask(id){return setActiveTaskOp(this.client,id)}}
|
|
2
|
+
import{isRowTokenTone}from"./chunk-atn06ncf.js";import{sameWorktreeChanges}from"./chunk-55ajzrj6.js";import{ensureDaemonReachable,isStaleInstallError}from"./chunk-tgfn5ykb.js";import{toTaskId}from"./chunk-xy8be792.js";import{CURRENT_VERSION}from"./chunk-dzmfexh8.js";import{homeDir}from"./chunk-prqeddy7.js";import{createStateCell,mapReadableState}from"./chunk-cmp64q4j.js";import{DAEMON_PROTOCOL_VERSION,MIN_COMPATIBLE_PROTOCOL_VERSION,isAttentionInboxState,isDaemonVersionStale,isForeignDaemonHome,isProtocolCompatible,isRoutineInboxState,parseDaemonStopReason}from"./chunk-kmgheesn.js";import{parseModUiPayload}from"./chunk-szjgjrar.js";import{logClient,logClientError}from"./chunk-gskbzgc3.js";function parseWorktreeChangesPayload(payload){let changes=payload?.changes;if(!changes||typeof changes!=="object"||Array.isArray(changes))return null;let map=new Map;for(let[path,value]of Object.entries(changes)){let counts=value;if(typeof counts?.added!=="number"||typeof counts.deleted!=="number")return null;map.set(path,{added:counts.added,deleted:counts.deleted,...typeof counts.behind==="number"?{behind:counts.behind}:{},...typeof counts.ahead==="number"?{ahead:counts.ahead}:{}})}let unreadable=payload?.unreadable;if(Array.isArray(unreadable)){for(let path of unreadable)if(typeof path==="string"&&path.length>0)map.set(path,null)}return map}function sameWorktreeChangesMap(a,b){if(a.size!==b.size)return!1;for(let[path,counts]of a){if(!b.has(path))return!1;if(!sameWorktreeChanges(counts,b.get(path)??null))return!1}return!0}function parseToken(raw){if(!raw||typeof raw!=="object")return null;let t=raw;if(typeof t.source!=="string"||typeof t.key!=="string")return null;if(typeof t.text!=="string"||t.text.length===0)return null;if(typeof t.expiresAt!=="number"||!Number.isFinite(t.expiresAt))return null;return{source:t.source,key:t.key,text:t.text,...isRowTokenTone(t.tone)?{tone:t.tone}:{},expiresAt:t.expiresAt}}function parseRowTokensPayload(payload){let tokens=payload?.tokens;if(!tokens||typeof tokens!=="object"||Array.isArray(tokens))return null;let out=new Map;for(let[taskId,list]of Object.entries(tokens)){if(!Array.isArray(list))continue;let parsed=list.map(parseToken).filter((token)=>token!==null);if(parsed.length>0)out.set(taskId,parsed)}return out}function sameRowTokenMap(a,b){if(a.size!==b.size)return!1;for(let[taskId,left]of a){let right=b.get(taskId);if(!right||right.length!==left.length)return!1;for(let[i,token]of left.entries()){let other=right[i];if(!other||other.source!==token.source||other.key!==token.key||other.text!==token.text||other.tone!==token.tone||other.expiresAt!==token.expiresAt)return!1}}return!0}function liveRowTokens(map,taskId,now){let tokens=map?.get(taskId);if(!tokens||tokens.length===0)return[];return tokens.filter((token)=>token.expiresAt>now)}function shouldLogReconnectAttempt(attempt){if(attempt>100)return!1;return attempt===1||attempt%10===0}function describePayload(value){if(value===void 0)return"undefined";if(value===null)return"null";let type=Array.isArray(value)?"array":typeof value,text;try{text=typeof value==="string"?value:JSON.stringify(value)}catch{text=String(value)}if(text.length>120)text=`${text.slice(0,120)}\u2026`;return`${type}:${text}`}function decodeUiPrefsPayload(payload){let p=payload;if(!p||typeof p!=="object"||!("theme"in p))return null;if(p.theme!==null&&typeof p.theme!=="string")return null;return{theme:typeof p.theme==="string"&&p.theme.length>0?p.theme:null,..."themeMode"in p?{themeMode:typeof p.themeMode==="string"?p.themeMode:null}:{},transparentBackground:p.transparentBackground!==!1,focusAccent:typeof p.focusAccent==="string"?p.focusAccent:null,locale:typeof p.locale==="string"?p.locale:"",sortMode:p.sortMode==="recent"||p.sortMode==="attention"||p.sortMode==="name"?p.sortMode:"default",keysCollapsed:p.keysCollapsed===!0,projectFilter:typeof p.projectFilter==="string"&&p.projectFilter.length>0?p.projectFilter:null}}var TOKEN_TOTAL_FIELDS=["inputTokens","outputTokens","cacheReadTokens","cacheCreationTokens"];function parseContextUsagePayload(payload){let context=payload?.context;if(!context||typeof context!=="object"||Array.isArray(context))return null;let map=new Map;for(let[key,value]of Object.entries(context)){let v=value;if(typeof v?.contextTokens!=="number")return null;if(v.contextWindowTokens!==void 0&&typeof v.contextWindowTokens!=="number")return null;let totals={};for(let field of TOKEN_TOTAL_FIELDS){let raw=v[field];if(raw===void 0)continue;if(typeof raw!=="number")return null;totals[field]=raw}map.set(key,{contextTokens:v.contextTokens,...typeof v.contextWindowTokens==="number"?{contextWindowTokens:v.contextWindowTokens}:{},...v.approximate===!0?{approximate:!0}:{},...totals})}return map}function sameContextUsageMap(a,b){if(a.size!==b.size)return!1;for(let[key,value]of a){let other=b.get(key);if(!other||other.contextTokens!==value.contextTokens||other.contextWindowTokens!==value.contextWindowTokens||other.approximate!==value.approximate||TOKEN_TOTAL_FIELDS.some((field)=>other[field]!==value[field]))return!1}return!0}function parseUsageSnapshotPayload(payload){let usage=payload?.usage;if(!usage||typeof usage!=="object"||Array.isArray(usage))return null;let map=new Map;for(let[vendor,value]of Object.entries(usage)){let snapshot=value;if(typeof snapshot?.capturedAt!=="number"||!Array.isArray(snapshot.windows))return null;let windows=[];for(let raw of snapshot.windows){let w=raw;if(typeof w?.kind!=="string"||typeof w.label!=="string"||typeof w.percent!=="number")return null;if(w.resetsAt!==null&&typeof w.resetsAt!=="number")return null;windows.push({kind:w.kind,label:w.label,percent:w.percent,resetsAt:w.resetsAt})}map.set(vendor,{windows,capturedAt:snapshot.capturedAt})}return map}function sameUsageSnapshotMap(a,b){if(a.size!==b.size)return!1;for(let[vendor,usage]of a){let other=b.get(vendor);if(!other||other.capturedAt!==usage.capturedAt||other.windows.length!==usage.windows.length)return!1;for(let i=0;i<usage.windows.length;i++){let x=usage.windows[i],y=other.windows[i];if(!x||!y||x.kind!==y.kind||x.label!==y.label||x.percent!==y.percent||x.resetsAt!==y.resetsAt)return!1}}return!0}function parseTranscriptActivityPayload(payload){let activity=payload?.activity;if(!activity||typeof activity!=="object"||Array.isArray(activity))return null;let map=new Map;for(let[path,value]of Object.entries(activity)){let v=value;if(typeof v?.mtimeMs!=="number"||typeof v.completionAt!=="number")return null;if(v.completionId!==null&&typeof v.completionId!=="string")return null;map.set(path,{mtimeMs:v.mtimeMs,completionId:v.completionId,completionAt:v.completionAt})}return map}function sameTranscriptActivityMap(a,b){if(a.size!==b.size)return!1;for(let[path,v]of a){let other=b.get(path);if(!other||other.mtimeMs!==v.mtimeMs||other.completionId!==v.completionId||other.completionAt!==v.completionAt)return!1}return!0}function deserializeTask(s){return{id:toTaskId(s.id),title:s.title,repo:s.repo,branch:s.branch,worktreePath:s.worktreePath,kind:s.kind,...s.scratch?{scratch:!0}:{},...s.routine?{routine:s.routine}:{},status:s.status,pinned:s.pinned,vendor:s.vendor,command:s.command,prStatus:s.prStatus,modelEffort:s.modelEffort,model:s.model,tier:s.tier,groupId:s.groupId,observedLanguage:s.observedLanguage,deletion:s.deletion,quotaResume:s.quotaResume,linkedWorkItem:s.linkedWorkItem,dispatcher:s.dispatcher,requireReport:s.requireReport,prompt:s.prompt,baseRef:s.baseRef,worktreeName:s.worktreeName,report:s.report,...s.repoId?{repoId:s.repoId}:{},createdAt:s.createdAt,updatedAt:s.updatedAt}}async function runReconnectLoop(deps){let delayMs=deps.spawnDaemon?Math.floor(Math.random()*400):500,attempt=0;while(!deps.isDisposed()){if(delayMs>0)await new Promise((r)=>setTimeout(r,delayMs));if(deps.isDisposed())break;attempt++;try{if(deps.spawnDaemon)await deps.ensureReachable();await deps.init(),logClient("orch",`reconnected and re-subscribed after ${attempt} attempt(s) \u2014 task list re-synced`);return}catch(err){if(isStaleInstallError(err)){logClientError("orch-reconnect-fatal",err),deps.onFatal?.(err);return}if(deps.shouldLogAttempt(attempt))logClientError("orch-reconnect",err);delayMs=delayMs===0?500:Math.min(delayMs*2,3000)}}}async function performInit(client,opts,signals){let hello=await client.request("hello",{protocolVersion:DAEMON_PROTOCOL_VERSION,minProtocolVersion:MIN_COMPATIBLE_PROTOCOL_VERSION}),daemonVersion=typeof hello.protocolVersion==="number"?hello.protocolVersion:DAEMON_PROTOCOL_VERSION,daemonMin=typeof hello.minProtocolVersion==="number"?hello.minProtocolVersion:daemonVersion;if(!isProtocolCompatible({localVersion:DAEMON_PROTOCOL_VERSION,localMin:MIN_COMPATIBLE_PROTOCOL_VERSION,remoteVersion:daemonVersion,remoteMin:daemonMin}))throw Error(`Rove daemon is protocol v${daemonVersion} (min v${daemonMin}); this client is v${DAEMON_PROTOCOL_VERSION} (min v${MIN_COMPATIBLE_PROTOCOL_VERSION}). Restart the daemon (\`rove daemon restart\`) or upgrade Rove.`);let clientHome=homeDir();if(!opts.expectForeignHome&&isForeignDaemonHome(hello.homeDir,clientHome))throw Error(`Rove daemon on this socket serves ${hello.homeDir}, but this client uses ${clientHome}. A sandbox or dev daemon has taken the production socket \u2014 stop it (\`rove daemon stop\`), or unset ROVE_DAEMON_SOCKET_PATH / ROVE_DAEMON_SOCKET_PATH before starting it.`);if(signals.setDaemonVersionSig(typeof hello.roveVersion==="string"?hello.roveVersion:null),opts.onPeerIdentity?.({hostname:typeof hello.hostname==="string"?hello.hostname:"",homeDir:typeof hello.homeDir==="string"?hello.homeDir:"",daemonPid:typeof hello.daemonPid==="number"?hello.daemonPid:0,roveVersion:typeof hello.roveVersion==="string"?hello.roveVersion:""}),signals.setDaemonRestartingSig(!1),hello.tasks&&opts.subscribesTasks)signals.setTasks(hello.tasks.map(deserializeTask));if(await client.subscribe({role:opts.role,channels:opts.channels,cellPixelSize:opts.cellPixelSize}),hello.capabilities?.includes("worktree.changes")){if(signals.worktreeChangesAcc()===null)signals.setWorktreeChangesSig(new Map)}else signals.setWorktreeChangesSig(null);if(hello.capabilities?.includes("transcript.activity")){if(signals.transcriptActivityAcc()===null)signals.setTranscriptActivitySig(new Map)}else signals.setTranscriptActivitySig(null);signals.setConnectionState("online"),logClient("orch",`subscribed as ${opts.role} (${signals.tasksAcc().length} tasks)`)}function ordinalOf(tabId,fallback){let match=/^tab-(\d+)$/.exec(tabId);return match?Number(match[1]):fallback}function adoptTabs(state,tabIds){let known=new Set(state.tabs.map((tab)=>tab.id)),fresh=[];for(let id of tabIds){if(known.has(id))continue;known.add(id),fresh.push(id)}if(fresh.length===0)return state;let minted=state.nextOrdinal,adopted=fresh.map((id)=>({kind:"engine",id,title:null,ordinal:ordinalOf(id,minted++),spawned:!0}));adopted.sort((a,b)=>a.ordinal-b.ordinal);let tabs=[...state.tabs,...adopted],maxOrdinal=tabs.reduce((max,tab)=>Math.max(max,tab.ordinal),0);return{tabs,activeId:state.activeId,nextOrdinal:Math.max(state.nextOrdinal,maxOrdinal+1)}}function isAddedTab(raw){if(typeof raw!=="object"||raw===null)return!1;if(!("id"in raw)||typeof raw.id!=="string")return!1;if(!("ordinal"in raw)||typeof raw.ordinal!=="number")return!1;if(!("title"in raw)||raw.title!==null&&typeof raw.title!=="string")return!1;if(!("kind"in raw))return!1;if(raw.kind==="engine")return!0;return raw.kind==="command"&&"command"in raw&&Array.isArray(raw.command)}function absorbTab(state,tab){let nextOrdinal=Math.max(state.nextOrdinal,tab.ordinal+1),known=state.tabs.find((t)=>t.id===tab.id);if(known?.kind===tab.kind){if(Object.entries(tab).every(([key,value])=>JSON.stringify(Reflect.get(known,key))===JSON.stringify(value))&&nextOrdinal===state.nextOrdinal)return state}let merged=known?.kind===tab.kind?{...known,...tab,title:known.title}:tab,tabs=known?state.tabs.map((t)=>t===known?merged:t):[...state.tabs,merged];return{...state,tabs,nextOrdinal}}var MAP_CHANNELS={"usage.snapshot":{what:"usage payload",parse:parseUsageSnapshotPayload,same:sameUsageSnapshotMap,read:(signals)=>signals.usageSnapshotAcc(),write:(signals,next)=>signals.setUsageSnapshotSig(next)},"usage.context":{what:"context payload",parse:parseContextUsagePayload,same:sameContextUsageMap,read:(signals)=>signals.contextUsageAcc(),write:(signals,next)=>signals.setContextUsageSig(next)},"worktree.changes":{what:"changes payload",parse:parseWorktreeChangesPayload,same:sameWorktreeChangesMap,read:(signals)=>signals.worktreeChangesAcc(),write:(signals,next)=>signals.setWorktreeChangesSig(next)},"transcript.activity":{what:"activity payload",parse:parseTranscriptActivityPayload,same:sameTranscriptActivityMap,read:(signals)=>signals.transcriptActivityAcc(),write:(signals,next)=>signals.setTranscriptActivitySig(next)},"mod.ui":{what:"mod pane list",parse:parseModUiPayload,same:(a,b)=>JSON.stringify(a)===JSON.stringify(b),read:(signals)=>signals.modPanesAcc(),write:(signals,next)=>signals.setModPanesSig(next)},"task.tokens":{what:"token map",parse:parseRowTokensPayload,same:sameRowTokenMap,read:(signals)=>signals.rowTokensAcc(),write:(signals,next)=>signals.setRowTokensSig(next)}};function handleMapChannel(name,payload,signals){let channel=MAP_CHANNELS[name];if(!channel)return!1;let next=channel.parse(payload);if(!next)return logClientError("orch",`dropped ${name} event: malformed ${channel.what} (${describePayload(payload)})`),!0;let current=channel.read(signals);if(current&&channel.same(current,next))return!0;return channel.write(signals,next),!0}function writeGraphicsToStdout(data){if(!process.stdout.isTTY)return;process.stdout.write(data)}function pruneEngineState(tasks,signals){let live=new Set(tasks.map((t)=>t.id)),current=signals.engineStateAcc();if(current.size>0){let next=null;for(let key of current.keys()){if(live.has(key))continue;if(!next)next=new Map(current);next.delete(key)}if(next)signals.setEngineStateSig(next)}let tabs=signals.engineTabStateAcc();if(tabs.size>0){let nextTabs=null;for(let key of tabs.keys()){if(live.has(key))continue;if(!nextTabs)nextTabs=new Map(tabs);nextTabs.delete(key)}if(nextTabs)signals.setEngineTabStateSig(nextTabs)}let lifecycle=signals.engineLifecycleAcc();if(lifecycle.size>0){let nextLifecycle=null;for(let key of lifecycle.keys()){if(live.has(key))continue;if(!nextLifecycle)nextLifecycle=new Map(lifecycle);nextLifecycle.delete(key)}if(nextLifecycle)signals.setEngineLifecycleSig(nextLifecycle)}}function pruneTaskJobs(tasks,signals){let current=signals.taskJobsAcc();if(current.size===0)return;let live=new Set(tasks.map((t)=>t.id)),next=null;for(let key of current.keys()){if(live.has(key))continue;if(!next)next=new Map(current);next.delete(key)}if(next)signals.setTaskJobsSig(next)}function handleOrchestratorEvent(name,payload,signals){if(name==="task.snapshot"){let value=payload?.tasks;if(Array.isArray(value))signals.setTasks(value.map(deserializeTask)),pruneEngineState(value,signals),pruneTaskJobs(value,signals);else logClientError("orch",`dropped task.snapshot event: tasks is not an array (got ${describePayload(value)})`);return}if(name==="daemon.stopping"){let p=payload;if(typeof p?.roveVersion==="string")signals.setDaemonVersionSig(p.roveVersion);if(parseDaemonStopReason(p?.reason)==="restart")signals.setDaemonRestartingSig(!0);return}if(name==="active-task"){let id=payload?.taskId;signals.setActiveTaskSig(typeof id==="string"?id:null);return}if(name==="update"){let info=payload?.info;signals.setUpdateSig(info??null);return}if(name==="engine-state"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.state!=="string"){logClientError("orch",`dropped engine-state event: taskId/state must be strings (taskId=${describePayload(p?.taskId)}, state=${describePayload(p?.state)})`);return}let tabId=typeof p.tabId==="string"&&p.tabId?p.tabId:void 0,entry={state:p.state,detail:p.detail,...typeof p.sessionId==="string"&&p.sessionId?{sessionId:p.sessionId}:{},...typeof p.transcriptPath==="string"&&p.transcriptPath?{transcriptPath:p.transcriptPath}:{},...tabId?{tabId}:{},at:typeof p.at==="number"?p.at:0},prevTaskState=signals.engineStateAcc().get(p.taskId)?.state;if(!tabId){let next=new Map(signals.engineStateAcc());if(p.state==="idle")next.delete(p.taskId);else next.set(p.taskId,entry);signals.setEngineStateSig(next)}if((p.state==="idle"||p.state==="turn_complete"||p.state==="error"||p.state==="running"&&prevTaskState!=="running")&&signals.engineLifecycleAcc().has(p.taskId)){let lifecycle=new Map(signals.engineLifecycleAcc());lifecycle.delete(p.taskId),signals.setEngineLifecycleSig(lifecycle)}if(tabId){let nextTabs=new Map(signals.engineTabStateAcc()),tabs=new Map(nextTabs.get(p.taskId)??[]);tabs.set(tabId,entry),nextTabs.set(p.taskId,tabs),signals.setEngineTabStateSig(nextTabs)}return}if(name==="attention.inbox"){let items=payload?.items;if(!Array.isArray(items)){logClientError("orch",`dropped attention.inbox event: items is not an array (${describePayload(items)})`);return}let kept=items.filter((item)=>{if(!item||typeof item!=="object"||Array.isArray(item))return!1;let p=item;return(typeof p.taskId==="string"||p.taskId===null&&isRoutineInboxState(p.state))&&(p.tabId===null||typeof p.tabId==="string")&&isAttentionInboxState(p.state)&&(p.unread===void 0||typeof p.unread==="boolean")&&typeof p.at==="number"});if(kept.length!==items.length)logClientError("orch",`dropped ${items.length-kept.length} malformed attention.inbox item(s) of ${items.length} (${describePayload(items)})`);if(kept.length===0&&items.length>0)return;signals.setAttentionInboxSig(kept.map((item)=>({...item,unread:item.unread!==!1})));return}if(name==="gates"){let gates=payload?.gates;if(!Array.isArray(gates)){logClientError("orch",`dropped gates event: gates is not an array (${describePayload(gates)})`);return}let kept=gates.filter((g)=>{if(!g||typeof g!=="object"||Array.isArray(g))return!1;let p=g;return typeof p.id==="string"&&typeof p.taskId==="string"&&typeof p.question==="string"});if(kept.length===0&&gates.length>0)return;signals.setGatesSig(kept.map((g)=>({...g,options:Array.isArray(g.options)?g.options:[]})));return}if(name==="task.jobs"){let p=payload;if(typeof p?.taskId!=="string"||p.kind!=="ensureWorktree"){logClientError("orch",`dropped task.jobs event: expected string taskId + kind "ensureWorktree" (taskId=${describePayload(p?.taskId)}, kind=${describePayload(p?.kind)})`);return}let current=signals.taskJobsAcc();if(p.phase==="running"){let next=new Map(current);next.set(p.taskId,{kind:p.kind}),signals.setTaskJobsSig(next);return}if((p.phase==="done"||p.phase==="error")&¤t.has(p.taskId)){let next=new Map(current);next.delete(p.taskId),signals.setTaskJobsSig(next)}return}if(handleMapChannel(name,payload,signals))return;if(name==="tab.open"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.at!=="number"||typeof p.title!=="string"||!Array.isArray(p.argv)){logClientError("orch",`dropped tab.open event: malformed payload (${describePayload(payload)})`);return}signals.setTabOpenSig(p);return}if(name==="tab.close"){let p=payload;if(!(p&&"kind"in p&&p.kind==="terminal-tab"?typeof p.taskId==="string"&&typeof p.tabId==="string"&&typeof p.requestId==="string"&&typeof p.at==="number":typeof p?.taskId==="string"&&typeof p.at==="number"&&("title"in p)&&typeof p.title==="string")){logClientError("orch",`dropped tab.close event: malformed payload (${describePayload(payload)})`);return}signals.setTabCloseSig(p);return}if(name==="tab.rename"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.tabId!=="string"||typeof p.title!=="string"||typeof p.at!=="number"){logClientError("orch",`dropped tab.rename event: malformed payload (${describePayload(payload)})`);return}signals.setTabRenameSig(p);return}if(name==="tabs.changed"){let p=payload,state=p?.state;if(typeof p?.taskId!=="string"||typeof p.rev!=="number"||state!==null&&(typeof state!=="object"||!Array.isArray(state?.tabs))){logClientError("orch",`dropped tabs.changed event: malformed payload (${describePayload(payload)})`);return}signals.emitTabsChanged(p);return}if(name==="row.status"){let p=payload;if(typeof p?.rev!=="number"||typeof p.tasks!=="object"||p.tasks===null){logClientError("orch",`dropped row.status event: malformed payload (${describePayload(payload)})`);return}signals.emitRowStatus(p);return}if(name==="tab.add"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.at!=="number"||!isAddedTab(p.tab)){logClientError("orch",`dropped tab.add event: malformed payload (${describePayload(payload)})`);return}signals.setTabAddSig({taskId:p.taskId,tab:p.tab,at:p.at});return}if(name==="ui.prompt"){let p=payload;if(typeof p?.promptId!=="string"||typeof p.title!=="string"||typeof p.at!=="number"){logClientError("orch",`dropped ui.prompt event: malformed payload (${describePayload(payload)})`);return}signals.setUiPromptSig(p);return}if(name==="engine.lifecycle"){let p=payload;if(typeof p?.taskId!=="string"||typeof p.kind!=="string"){logClientError("orch",`dropped engine.lifecycle event: malformed payload (${describePayload(payload)})`);return}let prev=signals.engineLifecycleAcc(),cur=prev.get(p.taskId)??{subagents:0},entry=p.kind==="subagent-start"?{subagents:cur.subagents+1}:p.kind==="subagent-stop"?{subagents:Math.max(0,cur.subagents-1)}:cur;if(entry===cur&&!prev.has(p.taskId))return;let map=new Map(prev);if(entry.subagents===0)map.delete(p.taskId);else map.set(p.taskId,entry);signals.setEngineLifecycleSig(map);return}if(name==="graphics.write"){let p=payload;if(typeof p?.data!=="string"||typeof p.imageId!=="number"||typeof p.at!=="number"){logClientError("orch",`dropped graphics.write event: malformed payload (${describePayload(payload)})`);return}signals.writeGraphics(Buffer.from(p.data,"base64"));return}if(name==="notice.event"){let p=payload;if(typeof p?.title!=="string"||typeof p.at!=="number"||typeof p.kind!=="string"){logClientError("orch",`dropped notice.event: malformed payload (${describePayload(payload)})`);return}signals.setNoticeSig(p);return}if(name==="ui-prefs"){let decoded=decodeUiPrefsPayload(payload);if(!decoded){let theme=payload?.theme;logClientError("orch",`dropped ui-prefs event: theme must be a string (got ${describePayload(theme)})`);return}signals.setUiPrefsSig(decoded);return}if(name==="keybindings"){let p=payload;if(typeof p?.rev!=="number"){logClientError("orch",`dropped keybindings event: rev must be a number (got ${describePayload(p?.rev)})`);return}signals.setKeybindingsRevSig(p.rev)}}function subscribeTasksOp(tasks,listener){try{listener(tasks())}catch(err){console.error("[rove RemoteOrchestrator] task listener threw on subscribe:",err)}return tasks.subscribe(()=>{try{listener(tasks.get())}catch(err){console.error("[rove RemoteOrchestrator] task listener threw:",err)}})}class RowStatusChannel{client;listeners=new Set;constructor(client){this.client=client}emit=(payload)=>{for(let listener of this.listeners)listener(payload)};onChanged=(listener)=>{return this.listeners.add(listener),()=>this.listeners.delete(listener)};list=()=>this.client.request("status.list");viewing=(taskId,tabId)=>this.client.request("ui.viewing",taskId===null?{taskId:null}:{taskId,...tabId?{tabId}:{}});answered=(taskId,tabId)=>this.client.request("activity.answered",{taskId,tabId})}class TabsChannel{client;listeners=new Set;constructor(client){this.client=client}emit=(event)=>{for(let listener of this.listeners)listener(event)};onChanged=(listener)=>{return this.listeners.add(listener),()=>this.listeners.delete(listener)};apply=(taskId,ops)=>this.client.request("tabs.apply",{taskId,ops});list=()=>this.client.request("tabs.list");reserve=(taskId,count)=>this.client.request("tabs.reserve",{taskId,count});release=(taskId,from,to)=>this.client.request("tabs.release",{taskId,from,to})}async function createTaskOp(client,input){let{modelEffort,...rest}=input,res=await client.request("task.create",{...rest,effort:modelEffort});return deserializeTask(res.task)}async function ensureMainTaskOp(client,repo){let res=await client.request("task.ensureMain",{repo});return deserializeTask(res.task)}async function openDirectoryTaskOp(client,input){let res=await client.request("task.openDir",input);return deserializeTask(res.task)}async function adoptScratchRepoOp(client,id,repo){await client.request("task.adoptScratchRepo",{taskId:String(id),repo})}async function ensureWorktreeOp(client,id){return(await client.request("task.ensureWorktree",{taskId:String(id)})).worktreePath}async function forgetProjectOp(client,repo){await client.request("project.forget",{repo})}function reportEngineInterruptOp(client,taskId,tabId){client.request("engine.reportEvent",{kind:"turn-interrupted",taskId,tabId}).catch(()=>{})}async function setTitleOp(client,id,title){await client.request("task.rename",{taskId:String(id),title})}async function setBranchOp(client,id,branch){await client.request("task.setBranch",{taskId:String(id),branch})}async function setVendorOp(client,id,vendor,effort,model){await client.request("task.setVendor",{taskId:String(id),vendor,...effort!==void 0?{effort}:{},...model!==void 0?{model}:{}})}async function setCommandOp(client,id,command,vendor){await client.request("task.setCommand",{taskId:String(id),command,...vendor?{vendor}:{}})}async function setPinnedOp(client,id,pinned){await client.request("task.pin",{taskId:String(id),pinned})}async function moveTaskOp(client,id,delta){await client.request("task.move",{taskId:String(id),direction:delta<0?"up":"down"})}async function moveTaskToTopOp(client,id){await client.request("task.move",{taskId:String(id),direction:"top"})}async function setPromptOp(client,id,prompt){await client.request("task.setPrompt",{taskId:String(id),prompt})}async function setStatusOp(client,id,status){await client.request("task.status",{taskId:String(id),status})}async function deleteTaskOp(client,id,opts){await client.request("task.delete",{taskId:String(id),force:opts?.force,deleteBranch:opts?.deleteBranch})}async function dismissAttentionOp(client,taskId,tabId,at,deliveryId){return(await client.request("attention.dismiss",{taskId:String(taskId),...tabId!==null?{tabId}:{},at,...deliveryId!==void 0?{deliveryId}:{}})).deleted}async function dismissRoutineAttentionOp(client,automationId){return(await client.request("attention.dismissRoutine",{automationId})).deleted}async function answerGateOp(client,gateId,answer){return{delivered:(await client.request("gate.answer",{gateId,...answer,by:"tui"})).delivered}}async function withdrawGateOp(client,gateId){await client.request("gate.withdraw",{gateId})}async function markAttentionReadOp(client,taskId,tabId,at){return(await client.request("attention.read",{taskId:String(taskId),...tabId!==null?{tabId}:{},at})).updated}async function landPreflightOp(client,id){return(await client.request("task.landPreflight",{taskId:String(id)})).result}async function landTaskOp(client,id,opts){return(await client.request("task.land",{taskId:String(id),strategy:opts?.strategy,deleteBranch:opts?.deleteBranch,removeWorktree:opts?.removeWorktree,callerCwd:opts?.callerCwd})).result}async function discoverAdoptableWorktreesOp(client,repo){return(await client.request("worktree.discoverAdoptable",{repo})).worktrees}async function adoptWorktreeOp(client,input){let res=await client.request("worktree.adopt",input);return deserializeTask(res.task)}async function listWorktreesOp(client,opts){return(await client.request("worktree.list",{network:opts?.network!==!1})).projects}async function removeWorktreeOp(client,path,force){return(await client.request("worktree.remove",{path,force})).residue??null}async function syncBaseOp(client,taskId){return(await client.request("task.syncBase",{taskId})).result}async function failingChecksOp(client,taskId){let res=await client.request("pr.failingChecks",{taskId});return{checks:res.checks??[],totalFailing:res.totalFailing??0,...res.unavailable?{unavailable:res.unavailable}:{}}}async function rerunFailedChecksOp(client,taskId){let res=await client.request("pr.rerunFailedChecks",{taskId});return{rerunRuns:res.rerunRuns??0,external:res.external??0,...res.refused?{refused:res.refused}:{},...res.unavailable?{unavailable:res.unavailable}:{}}}async function listIssuesOp(client,repoRoot){return client.request("issue.list",{repoRoot})}async function listIssueReposOp(client){return(await client.request("issue.repos",{})).repos??[]}async function listFieldNotesOp(client,repo){return(await client.request("note.list",{repo})).notes??[]}async function deleteFieldNoteOp(client,repo,id){return(await client.request("note.delete",{repo,id})).deleted===!0}async function mutateIssueOp(client,repoRoot,op){return client.request("issue.mutate",{repoRoot,op})}async function listAutomationsOp(client){return client.request("automation.list",{})}async function createAutomationOp(client,input){return client.request("automation.create",input)}async function automationRunsOp(client,id){return client.request("automation.runs",{id})}async function setAutomationEnabledOp(client,id,enabled){return client.request("automation.update",{id,enabled})}async function runAutomationNowOp(client,id){return client.request("automation.runNow",{id})}async function deleteAutomationOp(client,id){return client.request("automation.delete",{id})}async function listWorkItemsOp(client,args){return client.request("workitem.list",args)}async function startWorkItemOp(client,args){return client.request("workitem.start",args)}async function setActiveTaskOp(client,id){await client.request("task.setActive",{taskId:id===null?null:String(id)})}function replyTabCloseOp(client,requestId,closed){client.request("terminalTab.closeReply",{requestId,closed}).catch(()=>{})}function replyPromptOp(client,promptId,value){client.request("ui.promptReply",{promptId,...value!==void 0?{value}:{}}).catch(()=>{})}function reportUiEventOp(client,kind,taskId,detail){client.request("ui.reportEvent",{kind,...taskId?{taskId}:{},...detail?{detail}:{}}).catch(()=>{})}function recentTaskEventsOp(client,id){return client.request("task.recentEvents",{taskId:String(id)})}class RemoteOrchestrator{client;tasksAcc=createStateCell([],"orchestrator.tasks");activeTaskAcc=createStateCell(null,"orchestrator.active-task");updateAcc=createStateCell(null);daemonVersionAcc=createStateCell(null);daemonRestartingAcc=createStateCell(!1);daemonStaleAcc=mapReadableState(this.daemonVersionAcc,(version)=>isDaemonVersionStale(version??void 0,CURRENT_VERSION));engineStateAcc=createStateCell(new Map);engineTabStateAcc=createStateCell(new Map);attentionInboxAcc=createStateCell([]);gatesAcc=createStateCell([]);taskJobsAcc=createStateCell(new Map);rowTokensAcc=createStateCell(new Map);modPanesAcc=createStateCell([]);worktreeChangesAcc=createStateCell(null);usageSnapshotAcc=createStateCell(null);contextUsageAcc=createStateCell(null);transcriptActivityAcc=createStateCell(null);noticeAcc=createStateCell(null);tabOpenAcc=createStateCell(null);tabCloseAcc=createStateCell(null);tabRenameAcc=createStateCell(null);tabAddAcc=createStateCell(null);tabs;rowStatus;uiPromptAcc=createStateCell(null);engineLifecycleAcc=createStateCell(new Map);uiPrefsAcc=createStateCell(null);keybindingsRevAcc=createStateCell(null);connectionStateAcc=createStateCell("online","orchestrator.connection");staleInstallAcc=createStateCell(null);ensureReachable;role;cellPixelSize;channels;subscribesTasks;expectForeignHome;onPeerIdentity;reconnectTask=null;signals;constructor(client,options={}){this.client=client;this.ensureReachable=options.ensureReachable??ensureDaemonReachable,this.role=options.role??"pane",this.cellPixelSize=options.cellPixelSize??null,this.channels=options.channels,this.subscribesTasks=!options.channels||options.channels.includes("task.snapshot"),this.expectForeignHome=options.expectForeignHome===!0,this.onPeerIdentity=options.onPeerIdentity,this.tabs=new TabsChannel(client),this.rowStatus=new RowStatusChannel(client),this.signals={writeGraphics:options.graphicsOut??(this.role==="gui"?writeGraphicsToStdout:()=>{}),tasksAcc:this.tasksAcc,setTasks:this.tasksAcc.set,setActiveTaskSig:this.activeTaskAcc.set,setUpdateSig:this.updateAcc.set,setDaemonVersionSig:this.daemonVersionAcc.set,setDaemonRestartingSig:this.daemonRestartingAcc.set,engineStateAcc:this.engineStateAcc,setEngineStateSig:this.engineStateAcc.set,engineTabStateAcc:this.engineTabStateAcc,setEngineTabStateSig:this.engineTabStateAcc.set,setAttentionInboxSig:this.attentionInboxAcc.set,setGatesSig:this.gatesAcc.set,taskJobsAcc:this.taskJobsAcc,setTaskJobsSig:this.taskJobsAcc.set,rowTokensAcc:this.rowTokensAcc,setRowTokensSig:this.rowTokensAcc.set,modPanesAcc:this.modPanesAcc,setModPanesSig:this.modPanesAcc.set,worktreeChangesAcc:this.worktreeChangesAcc,setWorktreeChangesSig:this.worktreeChangesAcc.set,usageSnapshotAcc:this.usageSnapshotAcc,setUsageSnapshotSig:this.usageSnapshotAcc.set,contextUsageAcc:this.contextUsageAcc,setContextUsageSig:this.contextUsageAcc.set,transcriptActivityAcc:this.transcriptActivityAcc,setTranscriptActivitySig:this.transcriptActivityAcc.set,setNoticeSig:this.noticeAcc.set,setTabOpenSig:this.tabOpenAcc.set,setTabCloseSig:this.tabCloseAcc.set,setTabRenameSig:this.tabRenameAcc.set,setTabAddSig:this.tabAddAcc.set,emitTabsChanged:this.tabs.emit,emitRowStatus:this.rowStatus.emit,setUiPromptSig:this.uiPromptAcc.set,engineLifecycleAcc:this.engineLifecycleAcc,setEngineLifecycleSig:this.engineLifecycleAcc.set,setUiPrefsSig:this.uiPrefsAcc.set,setKeybindingsRevSig:this.keybindingsRevAcc.set,setConnectionState:this.connectionStateAcc.set},this.client.on("*",(frame)=>handleOrchestratorEvent(frame.name,frame.payload,this.signals)),this.client.onLifecycle("close",()=>{this.connectionStateAcc.set("disconnected");let spawnDaemon=this.role==="gui";logClient("orch",spawnDaemon?"daemon socket closed \u2014 starting silent spawning reconnect loop":"daemon socket closed \u2014 starting non-spawning reconnect loop"),this.reconnectLoop(spawnDaemon)})}reconnectLoop(spawnDaemon){if(this.reconnectTask)return this.reconnectTask;let task=runReconnectLoop({isDisposed:()=>this.client.isDisposed,spawnDaemon,ensureReachable:this.ensureReachable,init:()=>this.init(),shouldLogAttempt:shouldLogReconnectAttempt,onFatal:(err)=>this.staleInstallAcc.set(err instanceof Error?err.message:String(err))});this.reconnectTask=task;let clear=()=>{if(this.reconnectTask===task)this.reconnectTask=null};return task.then(clear,clear),task}writeGraphics(data){this.signals.writeGraphics(data)}async init(){await performInit(this.client,{role:this.role,cellPixelSize:this.cellPixelSize,channels:this.channels,subscribesTasks:this.subscribesTasks,expectForeignHome:this.expectForeignHome,onPeerIdentity:this.onPeerIdentity},this.signals)}connectionStateSignal(){return this.connectionStateAcc}staleInstallSignal(){return this.staleInstallAcc}async manualReconnect(){this.client.forceDisconnect(),await this.reconnectLoop(!0)}dispose(){this.client.close()}tasksSignal=()=>this.tasksAcc;activeTaskSignal=()=>this.activeTaskAcc;updateSignal=()=>this.updateAcc;daemonVersionSignal=()=>this.daemonVersionAcc;daemonStaleSignal=()=>this.daemonStaleAcc;daemonRestartingSignal=()=>this.daemonRestartingAcc;async restartDaemon(){await this.client.request("daemon.stop",{reason:"restart"}).catch(()=>{})}engineStateSignal=()=>this.engineStateAcc;engineTabStatesSignal=()=>this.engineTabStateAcc;attentionInboxSignal=()=>this.attentionInboxAcc;gatesSignal=()=>this.gatesAcc;taskJobsSignal=()=>this.taskJobsAcc;rowTokensSignal=()=>this.rowTokensAcc;modPanesSignal=()=>this.modPanesAcc;pressMod=(plugin,pane,key)=>this.client.request("mod.press",{plugin,pane,key});submitMod=(plugin,pane,key,value)=>this.client.request("mod.submit",{plugin,pane,key,value});worktreeChangesSignal=()=>this.worktreeChangesAcc;usageSnapshotSignal=()=>this.usageSnapshotAcc;contextUsageSignal=()=>this.contextUsageAcc;transcriptActivitySignal=()=>this.transcriptActivityAcc;transcriptActivityStore=()=>this.transcriptActivityAcc;noticeStore=()=>this.noticeAcc;tabOpenStore=()=>this.tabOpenAcc;tabCloseStore=()=>this.tabCloseAcc;tabRenameStore=()=>this.tabRenameAcc;tabAddStore=()=>this.tabAddAcc;rpc={request:(name,payload)=>this.client.request(name,payload)};replyTerminalTabClose=(requestId,closed)=>replyTabCloseOp(this.client,requestId,closed);uiPromptStore=()=>this.uiPromptAcc;replyPrompt=(promptId,value)=>replyPromptOp(this.client,promptId,value);engineLifecycleSignal=()=>this.engineLifecycleAcc;recentTaskEvents(id){return recentTaskEventsOp(this.client,id)}reportUiEvent=(kind,taskId,detail)=>reportUiEventOp(this.client,kind,taskId,detail);reportScreenInput=async(taskId,tabId,blocked)=>{await this.client.request("engine.reportEvent",{source:"screen",taskId,tabId,blocked})};reportEngineInterrupt=(taskId,tabId)=>reportEngineInterruptOp(this.client,String(taskId),tabId);uiPrefsSignal=()=>this.uiPrefsAcc;uiPrefsStore=()=>this.uiPrefsAcc;keybindingsRevSignal=()=>this.keybindingsRevAcc;keybindingsRevStore=()=>this.keybindingsRevAcc;listTasks=()=>this.tasksAcc();getTask=(id)=>this.tasksAcc().find((task)=>task.id===id);subscribeTasks(listener){return subscribeTasksOp(this.tasksAcc,listener)}createTask=(input)=>createTaskOp(this.client,input);ensureMainTask=(repo)=>ensureMainTaskOp(this.client,repo);openDirectoryTask=(input)=>openDirectoryTaskOp(this.client,input);adoptScratchRepo=(id,repo)=>adoptScratchRepoOp(this.client,id,repo);ensureWorktree=(id)=>ensureWorktreeOp(this.client,id);forgetProject=(repo)=>forgetProjectOp(this.client,repo);setTitle=(id,title)=>setTitleOp(this.client,id,title);setBranch=(id,branch)=>setBranchOp(this.client,id,branch);setVendor=(id,vendor,effort,model)=>setVendorOp(this.client,id,vendor,effort,model);setCommand=(id,command,vendor)=>setCommandOp(this.client,id,command,vendor);setPinned=(id,pinned)=>setPinnedOp(this.client,id,pinned);moveTask=(id,delta)=>moveTaskOp(this.client,id,delta);moveTaskToTop=(id)=>moveTaskToTopOp(this.client,id);setStatus=(id,status)=>setStatusOp(this.client,id,status);setPrompt=(id,prompt)=>setPromptOp(this.client,id,prompt);deleteTask=(id,opts)=>deleteTaskOp(this.client,id,opts);dismissAttention=(taskId,tabId,at,deliveryId)=>dismissAttentionOp(this.client,taskId,tabId,at,deliveryId);dismissRoutineAttention=(automationId)=>dismissRoutineAttentionOp(this.client,automationId);markAttentionRead=(taskId,tabId,at)=>markAttentionReadOp(this.client,taskId,tabId,at);answerGate=(gateId,answer)=>answerGateOp(this.client,gateId,answer);withdrawGate=(gateId)=>withdrawGateOp(this.client,gateId);landPreflight(id){return landPreflightOp(this.client,id)}landTask(id,opts){return landTaskOp(this.client,id,opts)}discoverAdoptableWorktrees(repo){return discoverAdoptableWorktreesOp(this.client,repo)}adoptWorktree(input){return adoptWorktreeOp(this.client,input)}listWorktrees(opts){return listWorktreesOp(this.client,opts)}listIssues(repoRoot){return listIssuesOp(this.client,repoRoot)}listIssueRepos(){return listIssueReposOp(this.client)}mutateIssue(repoRoot,op){return mutateIssueOp(this.client,repoRoot,op)}listAutomations=()=>listAutomationsOp(this.client);createAutomation=(i)=>createAutomationOp(this.client,i);automationRuns=(id)=>automationRunsOp(this.client,id);setAutomationEnabled=(id,on)=>setAutomationEnabledOp(this.client,id,on);runAutomationNow=(id)=>runAutomationNowOp(this.client,id);deleteAutomation=(id)=>deleteAutomationOp(this.client,id);listWorkItems=(a)=>listWorkItemsOp(this.client,a);listFieldNotes=(repo)=>listFieldNotesOp(this.client,repo);deleteFieldNote=(repo,id)=>deleteFieldNoteOp(this.client,repo,id);failingChecks=(taskId)=>failingChecksOp(this.client,taskId);rerunFailedChecks=(taskId)=>rerunFailedChecksOp(this.client,taskId);syncBase=(taskId)=>syncBaseOp(this.client,taskId);startWorkItem=(a)=>startWorkItemOp(this.client,a);removeWorktree(path,force){return removeWorktreeOp(this.client,path,force)}setActiveTask(id){return setActiveTaskOp(this.client,id)}}
|
|
3
3
|
export{liveRowTokens,adoptTabs,absorbTab,RemoteOrchestrator};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{invokeVerb}from"./chunk-me656p3n.js";import"./chunk-yztr951z.js";import{defaultApiRuntime,loadContext}from"./chunk-1pg3247n.js";import"./chunk-4018sjy3.js";import"./chunk-t6hzyee7.js";import{ensurePluginEnginesLoaded}from"./chunk-80jqznbm.js";import"./chunk-qs0526nj.js";import"./chunk-8sksdq95.js";import"./chunk-re15t5r1.js";import"./chunk-17e2tgyg.js";import"./chunk-cbc1h345.js";import"./chunk-j1fe3j54.js";import"./chunk-4hestsjp.js";import"./chunk-6a70wv2b.js";import"./chunk-2bgmby1d.js";import"./chunk-41x1hrqe.js";import"./chunk-5mhvjytn.js";import"./chunk-kvwqh35r.js";import"./chunk-atn06ncf.js";import"./chunk-mtw6nce9.js";import"./chunk-qkehg2c1.js";import"./chunk-4rya4jmx.js";import"./chunk-1gawhhd0.js";import"./chunk-ve348rmz.js";import"./chunk-yk498qwr.js";import"./chunk-sak1tphp.js";import"./chunk-a42j8eek.js";import"./chunk-4250pw6r.js";import"./chunk-bnv1mm5h.js";import"./chunk-rxqdw6s5.js";import"./chunk-z80jjarw.js";import"./chunk-f5n0tgky.js";import"./chunk-z3zaa155.js";import"./chunk-30g1bgkg.js";import"./chunk-hpay0ax8.js";import"./chunk-catrr0z3.js";import"./chunk-b4zqkdyq.js";import"./chunk-rbr6qapz.js";import"./chunk-2tfnscxk.js";import"./chunk-8saxdp88.js";import"./chunk-w7zv47mp.js";import"./chunk-etfh8f4z.js";import"./chunk-9g2faw9a.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-kg9kmwt9.js";import"./chunk-6xppe9bj.js";import"./chunk-qdvtz853.js";import"./chunk-s27a0ckk.js";import"./chunk-g1px1rk6.js";import"./chunk-31jxjkrq.js";import"./chunk-b7xjhgts.js";import{ApiError}from"./chunk-3126c9x9.js";import"./chunk-bwr6dygx.js";import"./chunk-812et2xk.js";import"./chunk-zsfyj36g.js";import{connectIfRunning}from"./chunk-tgfn5ykb.js";import"./chunk-qga9xd2f.js";import"./chunk-5v02t4pz.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xh72jz7c.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{SUBCOMMAND_VERBS}from"./chunk-tjj9bt7n.js";import"./chunk-dzmfexh8.js";import{getSavedRepos}from"./chunk-m6pp9gaf.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-n3f5sdka.js";import"./chunk-zh0c8yzw.js";import"./chunk-wqckm0k6.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-625773dm.js";import"./chunk-xgans9wf.js";import"./chunk-cmp64q4j.js";import{RoveDaemonClient,automationRunNeedsAttention}from"./chunk-kmgheesn.js";import"./chunk-szjgjrar.js";import"./chunk-gskbzgc3.js";import"./chunk-pn5ygqn6.js";import{resolveDaemonHomeDir}from"./chunk-n0rtj4z7.js";import"./chunk-b39sdtt0.js";import{ROVE_STATE_DIR_BASENAME,readRoveEnv}from"./chunk-nc46gddg.js";import"./chunk-pxk2c2vj.js";import{__commonJS,__toESM}from"./chunk-91sykzqq.js";var require_QRMode=__commonJS((exports,module)=>{module.exports={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8}});var require_QR8bitByte=__commonJS((exports,module)=>{var QRMode=require_QRMode();function QR8bitByte(data){this.mode=QRMode.MODE_8BIT_BYTE,this.data=data}QR8bitByte.prototype={getLength:function(){return this.data.length},write:function(buffer){for(var i=0;i<this.data.length;i++)buffer.put(this.data.charCodeAt(i),8)}};module.exports=QR8bitByte});var require_QRMath=__commonJS((exports,module)=>{var QRMath={glog:function(n){if(n<1)throw Error("glog("+n+")");return QRMath.LOG_TABLE[n]},gexp:function(n){while(n<0)n+=255;while(n>=256)n-=255;return QRMath.EXP_TABLE[n]},EXP_TABLE:Array(256),LOG_TABLE:Array(256)};for(i=0;i<8;i++)QRMath.EXP_TABLE[i]=1<<i;var i;for(i=8;i<256;i++)QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];var i;for(i=0;i<255;i++)QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;var i;module.exports=QRMath});var require_QRPolynomial=__commonJS((exports,module)=>{var QRMath=require_QRMath();function QRPolynomial(num,shift){if(num.length===void 0)throw Error(num.length+"/"+shift);var offset=0;while(offset<num.length&&num[offset]===0)offset++;this.num=Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++)this.num[i]=num[i+offset]}QRPolynomial.prototype={get:function(index){return this.num[index]},getLength:function(){return this.num.length},multiply:function(e){var num=Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++)for(var j=0;j<e.getLength();j++)num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));return new QRPolynomial(num,0)},mod:function(e){if(this.getLength()-e.getLength()<0)return this;var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0)),num=Array(this.getLength());for(var i=0;i<this.getLength();i++)num[i]=this.get(i);for(var x=0;x<e.getLength();x++)num[x]^=QRMath.gexp(QRMath.glog(e.get(x))+ratio);return new QRPolynomial(num,0).mod(e)}};module.exports=QRPolynomial});var require_QRMaskPattern=__commonJS((exports,module)=>{module.exports={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7}});var require_QRUtil=__commonJS((exports,module)=>{var QRMode=require_QRMode(),QRPolynomial=require_QRPolynomial(),QRMath=require_QRMath(),QRMaskPattern=require_QRMaskPattern(),QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0)d^=QRUtil.G15<<QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15);return(data<<10|d)^QRUtil.G15_MASK},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0)d^=QRUtil.G18<<QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18);return data<<12|d},getBCHDigit:function(data){var digit=0;while(data!==0)digit++,data>>>=1;return digit},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1]},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2===0;case QRMaskPattern.PATTERN001:return i%2===0;case QRMaskPattern.PATTERN010:return j%3===0;case QRMaskPattern.PATTERN011:return(i+j)%3===0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2===0;case QRMaskPattern.PATTERN101:return i*j%2+i*j%3===0;case QRMaskPattern.PATTERN110:return(i*j%2+i*j%3)%2===0;case QRMaskPattern.PATTERN111:return(i*j%3+(i+j)%2)%2===0;default:throw Error("bad maskPattern:"+maskPattern)}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++)a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));return a},getLengthInBits:function(mode,type){if(1<=type&&type<10)switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw Error("mode:"+mode)}else if(type<27)switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw Error("mode:"+mode)}else if(type<41)switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw Error("mode:"+mode)}else throw Error("type:"+type)},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount(),lostPoint=0,row=0,col=0;for(row=0;row<moduleCount;row++)for(col=0;col<moduleCount;col++){var sameCount=0,dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r)continue;for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c)continue;if(r===0&&c===0)continue;if(dark===qrCode.isDark(row+r,col+c))sameCount++}}if(sameCount>5)lostPoint+=3+sameCount-5}for(row=0;row<moduleCount-1;row++)for(col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count===0||count===4)lostPoint+=3}for(row=0;row<moduleCount;row++)for(col=0;col<moduleCount-6;col++)if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6))lostPoint+=40;for(col=0;col<moduleCount;col++)for(row=0;row<moduleCount-6;row++)if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col))lostPoint+=40;var darkCount=0;for(col=0;col<moduleCount;col++)for(row=0;row<moduleCount;row++)if(qrCode.isDark(row,col))darkCount++;var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;return lostPoint+=ratio*10,lostPoint}};module.exports=QRUtil});var require_QRErrorCorrectLevel=__commonJS((exports,module)=>{module.exports={L:1,M:0,Q:3,H:2}});var require_QRRSBlock=__commonJS((exports,module)=>{var QRErrorCorrectLevel=require_QRErrorCorrectLevel();function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount,this.dataCount=dataCount}QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock===void 0)throw Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);var length=rsBlock.length/3,list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0],totalCount=rsBlock[i*3+1],dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++)list.push(new QRRSBlock(totalCount,dataCount))}return list};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return}};module.exports=QRRSBlock});var require_QRBitBuffer=__commonJS((exports,module)=>{function QRBitBuffer(){this.buffer=[],this.length=0}QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return(this.buffer[bufIndex]>>>7-index%8&1)==1},put:function(num,length){for(var i=0;i<length;i++)this.putBit((num>>>length-i-1&1)==1)},getLengthInBits:function(){return this.length},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex)this.buffer.push(0);if(bit)this.buffer[bufIndex]|=128>>>this.length%8;this.length++}};module.exports=QRBitBuffer});var require_QRCode=__commonJS((exports,module)=>{var QR8bitByte=require_QR8bitByte(),QRUtil=require_QRUtil(),QRPolynomial=require_QRPolynomial(),QRRSBlock=require_QRRSBlock(),QRBitBuffer=require_QRBitBuffer();function QRCode(typeNumber,errorCorrectLevel){this.typeNumber=typeNumber,this.errorCorrectLevel=errorCorrectLevel,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}QRCode.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData),this.dataCache=null},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col)throw Error(row+","+col);return this.modules[row][col]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var typeNumber=1;for(typeNumber=1;typeNumber<40;typeNumber++){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,this.errorCorrectLevel),buffer=new QRBitBuffer,totalDataCount=0;for(var i=0;i<rsBlocks.length;i++)totalDataCount+=rsBlocks[i].dataCount;for(var x=0;x<this.dataList.length;x++){var data=this.dataList[x];buffer.put(data.mode,4),buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber)),data.write(buffer)}if(buffer.getLengthInBits()<=totalDataCount*8)break}this.typeNumber=typeNumber}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17,this.modules=Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++)this.modules[row][col]=null}if(this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(test,maskPattern),this.typeNumber>=7)this.setupTypeNumber(test);if(this.dataCache===null)this.dataCache=QRCode.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);this.mapData(this.dataCache,maskPattern)},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if(0<=r&&r<=6&&(c===0||c===6)||0<=c&&c<=6&&(r===0||r===6)||2<=r&&r<=4&&2<=c&&c<=4)this.modules[row+r][col+c]=!0;else this.modules[row+r][col+c]=!1}}},getBestMaskPattern:function(){var minLostPoint=0,pattern=0;for(var i=0;i<8;i++){this.makeImpl(!0,i);var lostPoint=QRUtil.getLostPoint(this);if(i===0||minLostPoint>lostPoint)minLostPoint=lostPoint,pattern=i}return pattern},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth),cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs,dark=this.modules[row][col];if(dark)qr_mc.beginFill(0,100),qr_mc.moveTo(x,y),qr_mc.lineTo(x+cs,y),qr_mc.lineTo(x+cs,y+cs),qr_mc.lineTo(x,y+cs),qr_mc.endFill()}}return qr_mc},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!==null)continue;this.modules[r][6]=r%2===0}for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!==null)continue;this.modules[6][c]=c%2===0}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++)for(var j=0;j<pos.length;j++){var row=pos[i],col=pos[j];if(this.modules[row][col]!==null)continue;for(var r=-2;r<=2;r++)for(var c=-2;c<=2;c++)if(Math.abs(r)===2||Math.abs(c)===2||r===0&&c===0)this.modules[row+r][col+c]=!0;else this.modules[row+r][col+c]=!1}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber),mod;for(var i=0;i<18;i++)mod=!test&&(bits>>i&1)===1,this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;for(var x=0;x<18;x++)mod=!test&&(bits>>x&1)===1,this.modules[x%3+this.moduleCount-8-3][Math.floor(x/3)]=mod},setupTypeInfo:function(test,maskPattern){var data=this.errorCorrectLevel<<3|maskPattern,bits=QRUtil.getBCHTypeInfo(data),mod;for(var v=0;v<15;v++)if(mod=!test&&(bits>>v&1)===1,v<6)this.modules[v][8]=mod;else if(v<8)this.modules[v+1][8]=mod;else this.modules[this.moduleCount-15+v][8]=mod;for(var h=0;h<15;h++)if(mod=!test&&(bits>>h&1)===1,h<8)this.modules[8][this.moduleCount-h-1]=mod;else if(h<9)this.modules[8][15-h-1+1]=mod;else this.modules[8][15-h-1]=mod;this.modules[this.moduleCount-8][8]=!test},mapData:function(data,maskPattern){var inc=-1,row=this.moduleCount-1,bitIndex=7,byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col===6)col--;while(!0){for(var c=0;c<2;c++)if(this.modules[row][col-c]===null){var dark=!1;if(byteIndex<data.length)dark=(data[byteIndex]>>>bitIndex&1)===1;var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask)dark=!dark;if(this.modules[row][col-c]=dark,bitIndex--,bitIndex===-1)byteIndex++,bitIndex=7}if(row+=inc,row<0||this.moduleCount<=row){row-=inc,inc=-inc;break}}}}};QRCode.PAD0=236;QRCode.PAD1=17;QRCode.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel),buffer=new QRBitBuffer;for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4),buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber)),data.write(buffer)}var totalDataCount=0;for(var x=0;x<rsBlocks.length;x++)totalDataCount+=rsBlocks[x].dataCount;if(buffer.getLengthInBits()>totalDataCount*8)throw Error("code length overflow. ("+buffer.getLengthInBits()+">"+totalDataCount*8+")");if(buffer.getLengthInBits()+4<=totalDataCount*8)buffer.put(0,4);while(buffer.getLengthInBits()%8!==0)buffer.putBit(!1);while(!0){if(buffer.getLengthInBits()>=totalDataCount*8)break;if(buffer.put(QRCode.PAD0,8),buffer.getLengthInBits()>=totalDataCount*8)break;buffer.put(QRCode.PAD1,8)}return QRCode.createBytes(buffer,rsBlocks)};QRCode.createBytes=function(buffer,rsBlocks){var offset=0,maxDcCount=0,maxEcCount=0,dcdata=Array(rsBlocks.length),ecdata=Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount,ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount),maxEcCount=Math.max(maxEcCount,ecCount),dcdata[r]=Array(dcCount);for(var i=0;i<dcdata[r].length;i++)dcdata[r][i]=255&buffer.buffer[i+offset];offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount),rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1),modPoly=rawPoly.mod(rsPoly);ecdata[r]=Array(rsPoly.getLength()-1);for(var x=0;x<ecdata[r].length;x++){var modIndex=x+modPoly.getLength()-ecdata[r].length;ecdata[r][x]=modIndex>=0?modPoly.get(modIndex):0}}var totalCodeCount=0;for(var y=0;y<rsBlocks.length;y++)totalCodeCount+=rsBlocks[y].totalCount;var data=Array(totalCodeCount),index=0;for(var z=0;z<maxDcCount;z++)for(var s=0;s<rsBlocks.length;s++)if(z<dcdata[s].length)data[index++]=dcdata[s][z];for(var xx=0;xx<maxEcCount;xx++)for(var t=0;t<rsBlocks.length;t++)if(xx<ecdata[t].length)data[index++]=ecdata[t][xx];return data};module.exports=QRCode});var require_main=__commonJS((exports,module)=>{var QRCode=require_QRCode(),QRErrorCorrectLevel=require_QRErrorCorrectLevel(),black="\x1B[40m \x1B[0m",white="\x1B[47m \x1B[0m",toCell=function(isBlack){return isBlack?black:white},repeat=function(color){return{times:function(count){return Array(count).join(color)}}},fill=function(length,value){var arr=Array(length);for(var i=0;i<length;i++)arr[i]=value;return arr};module.exports={error:QRErrorCorrectLevel.L,generate:function(input,opts,cb){if(typeof opts==="function")cb=opts,opts={};var qrcode=new QRCode(-1,this.error);qrcode.addData(input),qrcode.make();var output="";if(opts&&opts.small){var BLACK=!0,WHITE=!1,moduleCount=qrcode.getModuleCount(),moduleData=qrcode.modules.slice(),oddRow=moduleCount%2===1;if(oddRow)moduleData.push(fill(moduleCount,WHITE));var platte={WHITE_ALL:"\u2588",WHITE_BLACK:"\u2580",BLACK_WHITE:"\u2584",BLACK_ALL:" "},borderTop=repeat(platte.BLACK_WHITE).times(moduleCount+3),borderBottom=repeat(platte.WHITE_BLACK).times(moduleCount+3);output+=borderTop+`
|
|
3
|
+
`;for(var row=0;row<moduleCount;row+=2){output+=platte.WHITE_ALL;for(var col=0;col<moduleCount;col++)if(moduleData[row][col]===WHITE&&moduleData[row+1][col]===WHITE)output+=platte.WHITE_ALL;else if(moduleData[row][col]===WHITE&&moduleData[row+1][col]===BLACK)output+=platte.WHITE_BLACK;else if(moduleData[row][col]===BLACK&&moduleData[row+1][col]===WHITE)output+=platte.BLACK_WHITE;else output+=platte.BLACK_ALL;output+=platte.WHITE_ALL+`
|
|
4
|
+
`}if(!oddRow)output+=borderBottom}else{var border=repeat(white).times(qrcode.getModuleCount()+3);output+=border+`
|
|
5
|
+
`,qrcode.modules.forEach(function(row2){output+=white,output+=row2.map(toCell).join(""),output+=white+`
|
|
6
|
+
`}),output+=border}if(cb)cb(output);else console.log(output)},setErrorLevel:function(error){this.error=QRErrorCorrectLevel[error]||this.error}}});import{join as join2}from"path";import{setTimeout as delay}from"timers/promises";import{mkdirSync}from"fs";var AGENT_TITLE="WeChat";function agentBrief(cli){return["You are the owner's personal assistant, reached from WeChat through Rove. Each message they send arrives here prefixed with `[WeChat]`.",`The bridge does not read this screen: answer every message with \`${cli} weixin send "<reply>"\` (\`--file <path>\` for long text), short and conclusion-first for a phone, in the language they wrote in.`,`You can do anything they could from a shell on this machine. For Rove itself use the rove skill and \`${cli} api\` (\`${cli} api context\` for what is running and what needs them, \`${cli} api add\` to start a task, \`${cli} api send\` to steer one).`,"Ask on WeChat before anything irreversible or outward-facing: merging, publishing, deleting, messaging other people.","This tab is one conversation; the owner starts a fresh one with /new."].join(`
|
|
7
|
+
`)}function agentPrompt(text){return`[WeChat] ${text}`}function createAgentControl(deps){let cli=deps.cli??"rove";async function open(taskId,firstMessage){let previous=deps.read(),prompt=firstMessage?`${agentBrief(cli)}
|
|
8
|
+
|
|
9
|
+
${agentPrompt(firstMessage)}`:agentBrief(cli),{tab}=await deps.ops.newConversation(taskId,prompt),kept=previous?.taskId===taskId?previous.conversations:[],agent={taskId,tab,conversations:[...kept,{tab,startedAt:deps.now()}]};return deps.write(agent),agent}async function resolveTask(){let override=deps.override(),stored=deps.read();if(override){if(stored?.taskId===override.taskId)return{taskId:override.taskId,existing:stored};if(override.tab){let adopted={taskId:override.taskId,tab:override.tab,conversations:[{tab:override.tab,startedAt:deps.now()}]};return deps.write(adopted),{taskId:override.taskId,existing:adopted}}return{taskId:override.taskId}}let live=stored&&(await deps.ops.tasks()).some((t)=>t.id===stored.taskId);if(stored&&live)return{taskId:stored.taskId,existing:stored};return mkdirSync(deps.dir,{recursive:!0,mode:448}),{taskId:(await deps.ops.openAgentTask(deps.dir,AGENT_TITLE)).taskId}}return{async current(firstMessage){let{taskId,existing}=await resolveTask();if(existing)return{agent:existing,created:!1};return{agent:await open(taskId,firstMessage),created:!0}},async startNew(firstMessage){let{taskId}=await resolveTask();return await open(taskId,firstMessage)}}}import{basename}from"path";function shortId(taskId){return taskId.slice(-6)}function head(text){let match=/^(\S+)\s*([\s\S]*)$/.exec(text.trim());return match?[match[1]??"",match[2]??""]:["",""]}function clip(text,max){let flat=text.replace(/\s+/g," ").trim();return flat.length<=max?flat:`${flat.slice(0,max-1)}\u2026`}function rowDetail(row){let bits=[];if(row.group==="waiting-on-you"&&row.activity)bits.push(row.activity.state.replace(/_/g," "));if(row.pr!==void 0)bits.push(`PR#${row.pr}`);if(row.checkState&&row.checkState!=="none")bits.push(`CI ${row.checkState}`);if(row.report?.summary)bits.push(`\u201C${clip(row.report.summary,48)}\u201D`);return bits.join(" \xB7 ")}function rowLine(row){let detail=rowDetail(row);return`\u2022 ${shortId(row.taskId)} ${clip(row.title||row.branch||"(untitled)",36)}${detail?` \u2014 ${detail}`:""}`}var SECTIONS=[["waiting-on-you","Needs you"],["landing","Ready to merge"],["ready-for-review","To review"],["working","Running"]];function renderStatus(payload){let count=(group)=>payload.tasks.filter((t)=>t.group===group).length,needs=count("waiting-on-you"),merge=count("landing"),review=count("ready-for-review"),running=count("working"),quiet=payload.tasks.length-needs-merge-review-running+(payload.omittedTasks??0);if(payload.tasks.length===0)return"No tasks right now.";let headline=[needs>0?`${needs} need you`:null,merge>0?`${merge} ready to merge`:null,review>0?`${review} to review`:null,`${running} running`,quiet>0?`${quiet} quiet`:null].filter(Boolean).join(" \xB7 "),lines=[needs+merge+review===0?`Nothing needs you. ${headline}`:headline];for(let[group,label]of SECTIONS){let rows=payload.tasks.filter((t)=>t.group===group);if(rows.length===0)continue;lines.push("",`${label}:`);for(let row of rows.slice(0,5))lines.push(rowLine(row));if(rows.length>5)lines.push(` +${rows.length-5} more`)}let unreported=payload.attention.filter((a)=>a.state==="report_missing"&&a.detail?.delivery?.id);if(unreported.length>0){lines.push("","Unreported ticks (reply `clear d-N` to unblock):");for(let item of unreported.slice(0,5)){let row=payload.tasks.find((t)=>t.taskId===item.taskId);lines.push(`\u2022 ${item.detail?.delivery?.id} ${row?shortId(row.taskId):""} ${clip(row?.title??"",36)}`.trimEnd())}}return lines.join(`
|
|
10
|
+
`)}function toBubbles(text){let pieces=text.trim().split(`
|
|
11
|
+
`).flatMap((line)=>line.match(new RegExp("[\\s\\S]{1,1800}","g"))??[""]),bubbles=[],current=null;for(let piece of pieces)if(current!==null&¤t.length+1+piece.length<=1800)current=`${current}
|
|
12
|
+
${piece}`;else{if(current!==null)bubbles.push(current);current=piece}if(current?.trim())bubbles.push(current);if(bubbles.length<=3)return bubbles;let marker=`\u2026(cut, ${bubbles.slice(3).reduce((n,b)=>n+b.split(`
|
|
13
|
+
`).length,0)} more lines)`,kept=bubbles.slice(0,3),last=kept[2]??"";return kept[2]=`${last.slice(0,1800-marker.length-1)}
|
|
14
|
+
${marker}`,kept}var GATES_USAGE="Usage: answer g-12 <key> [note]";function gateLines(gate,titles){let lines=[`${gate.id} ${shortId(gate.taskId)} ${titles.get(gate.taskId)??""}`.trimEnd(),gate.question];for(let o of gate.options){let mark=o.key===gate.recommended?" (recommended)":"";lines.push(` ${o.key}${mark} \u2014 ${o.label}${o.detail?` (${o.detail})`:""}`)}if(gate.options.length===0)lines.push(" free text only");return lines}function renderGates(gates,titles){if(gates.length===0)return"No open decisions.";let lines=[`${gates.length} open decision${gates.length===1?"":"s"}:`];for(let gate of gates)lines.push("",...gateLines(gate,titles));return lines.push("",GATES_USAGE),lines.join(`
|
|
15
|
+
`)}function renderGateArrivals(gates,titles){let lines=["Decision needed:"];for(let gate of gates)lines.push(...gateLines(gate,titles));let first=gates[0];if(first)lines.push(`Reply: answer ${first.id} ${first.options[0]?.key??"<text>"}`);return lines.join(`
|
|
16
|
+
`)}function gateId(ref){let m=/^(?:g-?)?(\d{1,9})$/i.exec(ref);return m?`g-${Number(m[1])}`:null}function parseAnswer(rest,open){let[ref,afterRef]=head(rest);if(!ref||!afterRef.trim())return{ok:!1,reply:GATES_USAGE};let id=gateId(ref),gate=id?open.find((g)=>g.id===id):void 0;if(!gate)return{ok:!1,reply:`No open decision "${ref}". Send "gates" for the list.`};if(gate.options.length===0){let[word2,note2]=head(afterRef),text=(word2==="-"?note2:afterRef).trim();return text?{ok:!0,answer:{gate,text}}:{ok:!1,reply:`Usage: answer ${gate.id} - <text>`}}let[word,note]=head(afterRef);if(word==="-")return note.trim()?{ok:!0,answer:{gate,text:note.trim()}}:{ok:!1,reply:`Usage: answer ${gate.id} - <text>`};let option=gate.options.find((o)=>o.key.toLowerCase()===word.toLowerCase());if(!option)return{ok:!1,reply:`"${word}" is not an option of ${gate.id}. Options: ${gate.options.map((o)=>o.key).join(", ")} (or "answer ${gate.id} - <text>").`};return{ok:!0,answer:{gate,option:option.key,...note.trim()?{text:note.trim()}:{}}}}function answeredReply(answer,delivered){let picked=answer.gate.options.find((o)=>o.key===answer.option),what=picked?`${picked.key} (${picked.label})`:"your text";return`Answered ${answer.gate.id} with ${what}. ${delivered?"Sent to the agent.":"The agent is not running; it gets this with the task's next message."}`}var MIN_ID_CHARS=4,TAB_RE=/^tab-\d+$/,HELP_TEXT=["Rove commands:","status \u2014 what needs you, what's running","status <repo> \u2014 one repo only","send <id> <text> \u2014 message a task's agent","send <id> tab-2 <text> \u2014 a specific tab","add <repo> <prompt> \u2014 start a new task","gates \u2014 open decisions waiting on you","answer g-12 <key> [note] \u2014 answer one","answer g-12 - <text> \u2014 free-text answer","clear d-41 \u2014 dismiss an unreported-tick flag (status lists them)","<id> is the 6-char code from status."].join(`
|
|
17
|
+
`);function resolveTask(tasks,ref){let needle=ref.toLowerCase(),exact=tasks.find((t)=>t.id.toLowerCase()===needle);if(exact)return{ok:!0,value:exact};if(needle.length<MIN_ID_CHARS)return{ok:!1,reply:`"${ref}" is too short \u2014 use the 6-char code from status.`};let hits=tasks.filter((t)=>t.id.toLowerCase().endsWith(needle));if(hits.length===1&&hits[0])return{ok:!0,value:hits[0]};if(hits.length===0)return{ok:!1,reply:`No task ending in "${ref}". Send "status" for the list.`};return{ok:!1,reply:[`"${ref}" matches ${hits.length} tasks:`,...hits.slice(0,5).map((t)=>`\u2022 ${t.id} ${t.title}`)].join(`
|
|
18
|
+
`)}}function resolveRepo(repos,ref){let unique=[...new Set(repos)],exact=unique.find((r)=>r===ref);if(exact)return{ok:!0,value:exact};let hits=unique.filter((r)=>basename(r).toLowerCase()===ref.toLowerCase());if(hits.length===1&&hits[0])return{ok:!0,value:hits[0]};let names=unique.map((r)=>basename(r)).sort();if(hits.length===0)return{ok:!1,reply:names.length>0?`No repo "${ref}". Known: ${names.join(", ")}`:`No repo "${ref}" \u2014 none saved yet.`};return{ok:!1,reply:[`"${ref}" names ${hits.length} repos; use the full path:`,...hits].join(`
|
|
19
|
+
`)}}function failure(err){if(err instanceof ApiError)return`Failed (${err.code}): ${err.message}`;return`Failed: ${err instanceof Error?err.message:String(err)}`}async function handleInbound(text,ops,agent){let trimmed=text.trim();if(!agent)return{reply:await handleCommand(trimmed,ops)};if(trimmed.startsWith("/")){let command=trimmed.slice(1),[word,rest]=head(command);if(word.toLowerCase()!=="new")return{reply:await handleCommand(command,ops,!0)};try{let firstMessage=rest.trim()||void 0,next=await agent.startNew(firstMessage);return{reply:`New conversation (#${next.conversations.length}). Earlier ones stay in Rove's ${AGENT_TITLE} project.`,...firstMessage?{agentTaskId:next.taskId}:{}}}catch(err){return{reply:failure(err)}}}try{let{agent:live,created}=await agent.current(trimmed);if(created)return{reply:"",agentTaskId:live.taskId};return{reply:(await ops.send(live.taskId,live.tab,agentPrompt(trimmed))).started?"The agent was not running; started it again, it will reply here.":"",agentTaskId:live.taskId}}catch(err){return{reply:`${failure(err)}
|
|
20
|
+
Your message did not reach the agent. Send /status for commands.`}}}async function handleCommand(text,ops,agentBound=!1){let[word,rest]=head(text);try{switch(word.toLowerCase()){case"":case"help":case"h":case"?":case"\u5E2E\u52A9":return agentBound?`${HELP_TEXT}
|
|
21
|
+
Put / in front of a command (/status). /new starts a new conversation; anything else goes to your agent.`:HELP_TEXT;case"status":case"s":case"ls":case"\u72B6\u6001":{if(!rest.trim())return renderStatus(await ops.status(null));let repo=resolveRepo(await ops.repos(),rest.trim());return repo.ok?`${basename(repo.value)}: ${renderStatus(await ops.status(repo.value))}`:repo.reply}case"send":{let[ref,afterRef]=head(rest),[tab,prompt]=head(afterRef);if(!TAB_RE.test(tab))prompt=afterRef,tab="";if(!ref||!prompt.trim())return"Usage: send <id> [tab-N] <text>";let task=resolveTask(await ops.tasks(),ref);if(!task.ok)return task.reply;let result=await ops.send(task.value.id,tab||void 0,prompt.trim()),where=result.tab??tab;return`Sent to ${shortId(task.value.id)} ${task.value.title}${where?` (${where})`:""}${result.started?" \u2014 started a new engine":""}.`}case"add":case"new":{let[repoRef,prompt]=head(rest);if(!repoRef||!prompt.trim())return"Usage: add <repo> <prompt>";let repo=resolveRepo(await ops.repos(),repoRef);if(!repo.ok)return repo.reply;let{taskId}=await ops.add(repo.value,prompt.trim());return`Started task ${shortId(taskId)} in ${basename(repo.value)}. I'll message you when it needs you.`}case"gates":case"decisions":case"\u51B3\u5B9A":{let[gates,tasks]=await Promise.all([ops.gates(),ops.tasks()]);return renderGates(gates,new Map(tasks.map((t)=>[t.id,t.title])))}case"answer":case"\u56DE\u7B54":{let parsed=parseAnswer(rest,await ops.gates());if(!parsed.ok)return parsed.reply;let{gate,option,text:text2}=parsed.answer,{delivered}=await ops.answerGate(gate.id,{...option?{option}:{},...text2?{text:text2}:{}});return answeredReply(parsed.answer,delivered)}case"clear":case"\u6E05\u9664":{let[ref]=head(rest);if(!ref||!/^d-\d+$/i.test(ref))return"Usage: clear d-N \u2014 the delivery id from status";return await ops.clearReport(ref.toLowerCase()),`Cleared ${ref.toLowerCase()}. That task can be ticked again.`}default:return`Unknown command "${word}".
|
|
22
|
+
${HELP_TEXT}`}}catch(err){return failure(err)}}import{randomBytes,randomUUID}from"crypto";var ILINK_BASE_URL="https://ilinkai.weixin.qq.com",APP_ID="bot",CHANNEL_VERSION="2.2.0",APP_CLIENT_VERSION=String(131584),BOT_TYPE="3",LONG_POLL_TIMEOUT_MS=35000,API_TIMEOUT_MS=15000,ITEM_TEXT=1,ITEM_VOICE=3,MSG_TYPE_BOT=2,MSG_STATE_FINISH=2,TYPING_ON=1,TYPING_OFF=2,SESSION_EXPIRED=-14,RATE_LIMITED=-2;function resolveIlinkBaseUrl(env=process.env){return(readRoveEnv("WEIXIN_BASE_URL",env)??ILINK_BASE_URL).replace(/\/+$/,"")}function classifyIlink(resp){let ret=resp.ret??0,errcode=resp.errcode??0;if(ret===0&&errcode===0)return"ok";if(ret===SESSION_EXPIRED||errcode===SESSION_EXPIRED)return"session-expired";if(ret===RATE_LIMITED||errcode===RATE_LIMITED){let msg=(resp.errmsg??resp.msg??"").toLowerCase();return msg==="unknown error"||msg==="prepare failed"?"session-expired":"rate-limited"}return"error"}function describeIlink(resp){return`ret=${resp.ret??0} errcode=${resp.errcode??0}${resp.errmsg||resp.msg?` (${resp.errmsg??resp.msg})`:""}`}function messageText(message){let items=message.item_list??[];for(let item of items)if(item.type===ITEM_TEXT)return(item.text_item?.text??"").trim();for(let item of items)if(item.type===ITEM_VOICE&&item.voice_item?.text)return item.voice_item.text.trim();return""}function isDirectUserMessage(message){return!message.room_id&&!message.chat_room_id&&message.message_type!==MSG_TYPE_BOT}async function requestJson(fetchFn,url,init,timeoutMs){let res=await fetchFn(url,{...init,signal:AbortSignal.timeout(timeoutMs)}),raw=await res.text();if(!res.ok)throw Error(`iLink HTTP ${res.status}`);return JSON.parse(raw)}function isTimeout(err){return err instanceof Error&&(err.name==="TimeoutError"||err.name==="AbortError")}function loginHeaders(){return{"iLink-App-Id":APP_ID,"iLink-App-ClientVersion":APP_CLIENT_VERSION}}async function fetchLoginQr(baseUrl,fetchFn=fetch){let resp=await requestJson(fetchFn,`${baseUrl}/ilink/bot/get_bot_qrcode?bot_type=${BOT_TYPE}`,{method:"GET",headers:loginHeaders()},LONG_POLL_TIMEOUT_MS);if(!resp.qrcode)throw Error("iLink returned no QR code");return{qrcode:resp.qrcode,url:resp.qrcode_img_content||resp.qrcode}}async function pollLoginStatus(baseUrl,qrcode,fetchFn=fetch){let resp;try{resp=await requestJson(fetchFn,`${baseUrl}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(qrcode)}`,{method:"GET",headers:loginHeaders()},LONG_POLL_TIMEOUT_MS)}catch(err){if(isTimeout(err))return{status:"wait"};throw err}switch(resp.status){case"scaned":case"expired":return{status:resp.status};case"scaned_but_redirect":return resp.redirect_host?{status:"redirect",baseUrl:`https://${resp.redirect_host}`}:{status:"scaned"};case"confirmed":if(!resp.ilink_bot_id||!resp.bot_token)throw Error("iLink confirmed the login without credentials");return{status:"confirmed",accountId:resp.ilink_bot_id,token:resp.bot_token,baseUrl:(resp.baseurl||baseUrl).replace(/\/+$/,""),userId:resp.ilink_user_id??""};default:return{status:"wait"}}}class IlinkClient{baseUrl;token;fetchFn;constructor(baseUrl,token,fetchFn=fetch){this.baseUrl=baseUrl;this.token=token;this.fetchFn=fetchFn}post(endpoint,payload,timeoutMs){let body=JSON.stringify({...payload,base_info:{channel_version:CHANNEL_VERSION}});return requestJson(this.fetchFn,`${this.baseUrl}/${endpoint}`,{method:"POST",headers:{"Content-Type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${this.token}`,"X-WECHAT-UIN":Buffer.from(String(randomBytes(4).readUInt32BE(0))).toString("base64"),...loginHeaders()},body},timeoutMs)}async getUpdates(syncBuf,timeoutMs=LONG_POLL_TIMEOUT_MS){try{return await this.post("ilink/bot/getupdates",{get_updates_buf:syncBuf},timeoutMs)}catch(err){if(isTimeout(err))return{ret:0,msgs:[],get_updates_buf:syncBuf};throw err}}sendText(to,text,contextToken){return this.post("ilink/bot/sendmessage",{msg:{from_user_id:"",to_user_id:to,client_id:`rove-weixin-${randomUUID()}`,message_type:MSG_TYPE_BOT,message_state:MSG_STATE_FINISH,item_list:[{type:ITEM_TEXT,text_item:{text}}],...contextToken?{context_token:contextToken}:{}}},API_TIMEOUT_MS)}async typingTicket(to,contextToken){let resp=await this.post("ilink/bot/getconfig",{ilink_user_id:to,...contextToken?{context_token:contextToken}:{}},API_TIMEOUT_MS);return classifyIlink(resp)==="ok"?resp.typing_ticket??"":""}sendTyping(to,ticket,typing){return this.post("ilink/bot/sendtyping",{ilink_user_id:to,typing_ticket:ticket,status:typing?TYPING_ON:TYPING_OFF},API_TIMEOUT_MS)}}var PUSH_LABEL={"waiting-on-you":"Needs you",landing:"Ready to merge","ready-for-review":"Ready for review"};class GroupTracker{settled=new Map;pending=new Map;seeded=!1;observe(rows){let arrivals=[],present=new Set;for(let row of rows){if(present.add(row.taskId),!this.seeded){this.settled.set(row.taskId,row.group);continue}if(this.settled.get(row.taskId)===row.group){this.pending.delete(row.taskId);continue}if(this.pending.get(row.taskId)!==row.group){this.pending.set(row.taskId,row.group);continue}if(this.pending.delete(row.taskId),this.settled.set(row.taskId,row.group),PUSH_LABEL[row.group])arrivals.push(row)}this.seeded=!0;for(let id of[...this.settled.keys()])if(!present.has(id))this.settled.delete(id);for(let id of[...this.pending.keys()])if(!present.has(id))this.pending.delete(id);return arrivals}}class GateTracker{seen=new Set;seeded=!1;observe(gates){if(gates===null)return[];let fresh=this.seeded?gates.filter((g)=>!this.seen.has(g.id)):[];this.seeded=!0,this.seen.clear();for(let g of gates)this.seen.add(g.id);return fresh}}function renderArrivals(rows){let lines=[];for(let row of rows)lines.push(`${PUSH_LABEL[row.group]??row.group}:`,rowLine(row));let first=rows[0];if(first?.group==="waiting-on-you")lines.push(`Reply: send ${first.taskId.slice(-6)} <text>`);return lines.join(`
|
|
23
|
+
`)}function awaitingReport(run){return(run.status==="dispatched"||run.status==="revived")&&run.deliveryStatus==="awaiting"}class RoutineTracker{handled=new Set;seeded=!1;observe(routines){let pushes=[],current=new Set;for(let routine of routines)for(let run of routine.runs){if(current.add(run.id),this.handled.has(run.id))continue;if(!this.seeded){this.handled.add(run.id);continue}if(run.response||automationRunNeedsAttention(run.status))pushes.push({name:routine.name,run}),this.handled.add(run.id);else if(!awaitingReport(run))this.handled.add(run.id)}this.seeded=!0;for(let id of this.handled)if(!current.has(id))this.handled.delete(id);return pushes.reverse()}}function renderRoutineRuns(pushes){return pushes.map(({name,run})=>{let failed=automationRunNeedsAttention(run.status),header=`[${name}] #${run.runNumber}${failed?` ${run.status.replace(/_/g," ")}`:""}`,body=[run.response?.text,failed?run.error:void 0].filter(Boolean).join(`
|
|
24
|
+
`);return body?`${header}
|
|
25
|
+
${body}`:header})}var RETRY_MS=2000,BUBBLE_GAP_MS=300;async function sendBubbles(client,to,text,contextToken,sleep){let bubbles=toBubbles(text);for(let i=0;i<bubbles.length;i++){let bubble=bubbles[i]??"",token=contextToken,retried=!1;for(;;){let resp;try{resp=await client.sendText(to,bubble,token)}catch(err){return{ok:!1,reason:`network: ${err instanceof Error?err.message:String(err)}`,rest:bubbles.slice(i).join(`
|
|
26
|
+
`)}}let outcome=classifyIlink(resp);if(outcome==="ok")break;if(!retried&&outcome==="session-expired"&&token){retried=!0,token=null;continue}if(!retried&&outcome==="rate-limited"){retried=!0,await sleep(RETRY_MS);continue}let hint=outcome==="session-expired"?" \u2014 they need to message the bot first":"";return{ok:!1,reason:`iLink refused: ${describeIlink(resp)}${hint}`,rest:bubbles.slice(i).join(`
|
|
27
|
+
`)}}if(i<bubbles.length-1)await sleep(BUBBLE_GAP_MS)}return{ok:!0}}import{appendFileSync,mkdirSync as mkdirSync2,readFileSync,renameSync,rmSync,writeFileSync}from"fs";import{join}from"path";var DIR_MODE=448,FILE_MODE=384,REJECTED_CAP=10;function readAgentState(raw){if(!raw||typeof raw!=="object")return;let a=raw;if(typeof a.taskId!=="string"||!a.taskId||typeof a.tab!=="string"||!a.tab)return;let conversations=Array.isArray(a.conversations)?a.conversations.filter((c)=>c&&typeof c.tab==="string"&&typeof c.startedAt==="number"):[];return{taskId:a.taskId,tab:a.tab,conversations}}function readJson(path){try{return JSON.parse(readFileSync(path,"utf8"))}catch{return null}}function writeJson(path,value){let tmp=`${path}.${process.pid}.tmp`;writeFileSync(tmp,`${JSON.stringify(value,null,2)}
|
|
28
|
+
`,{mode:FILE_MODE}),renameSync(tmp,path)}function ensureDir(dir){mkdirSync2(dir,{recursive:!0,mode:DIR_MODE})}class WeixinStore{dir;constructor(homeDir){this.dir=join(resolveDaemonHomeDir(homeDir),ROVE_STATE_DIR_BASENAME,"weixin")}get accountPath(){return join(this.dir,"account.json")}get statePath(){return join(this.dir,"state.json")}get undeliveredPath(){return join(this.dir,"undelivered.jsonl")}readAccount(){let raw=readJson(this.accountPath);if(!raw||typeof raw.accountId!=="string"||typeof raw.token!=="string"||!raw.accountId||!raw.token)return null;return{accountId:raw.accountId,token:raw.token,baseUrl:typeof raw.baseUrl==="string"&&raw.baseUrl?raw.baseUrl:"",ownerUserId:typeof raw.ownerUserId==="string"?raw.ownerUserId:"",allow:Array.isArray(raw.allow)?raw.allow.filter((id)=>typeof id==="string"):[],savedAt:typeof raw.savedAt==="string"?raw.savedAt:"",...raw.agent&&typeof raw.agent.taskId==="string"&&raw.agent.taskId?{agent:{taskId:raw.agent.taskId,...typeof raw.agent.tab==="string"&&raw.agent.tab?{tab:raw.agent.tab}:{}}}:{}}}writeAccount(account){ensureDir(this.dir),writeJson(this.accountPath,account)}clearAccount(){let had=this.readAccount()!==null;return rmSync(this.accountPath,{force:!0}),rmSync(this.statePath,{force:!0}),had}readState(accountId){let raw=readJson(this.statePath);if(!raw||raw.accountId!==accountId)return{accountId,syncBuf:"",peers:{},rejected:[]};return{accountId,syncBuf:typeof raw.syncBuf==="string"?raw.syncBuf:"",peers:raw.peers&&typeof raw.peers==="object"?raw.peers:{},rejected:Array.isArray(raw.rejected)?raw.rejected:[],...readAgentState(raw.agent)?{agent:readAgentState(raw.agent)}:{}}}writeState(state){ensureDir(this.dir),writeJson(this.statePath,{...state,rejected:state.rejected.slice(0,REJECTED_CAP)})}appendUndelivered(entry){ensureDir(this.dir),appendFileSync(this.undeliveredPath,`${JSON.stringify(entry)}
|
|
29
|
+
`,{mode:FILE_MODE})}readUndelivered(){let text;try{text=readFileSync(this.undeliveredPath,"utf8")}catch{return[]}let entries=[];for(let line of text.split(`
|
|
30
|
+
`)){if(!line.trim())continue;try{entries.push(JSON.parse(line))}catch{}}return entries}}function isAllowedSender(account,userId){return userId!==""&&(userId===account.ownerUserId||account.allow.includes(userId))}var TYPING_TIMINGS={keepaliveMs:5000,warmupMs:30000,maxMs:900000};function startTyping(deps,timings=TYPING_TIMINGS){let stopped=!1,send=(typing)=>deps.send(typing).catch((err)=>deps.log(`typing ${typing?"on":"off"} failed: ${String(err)}`));async function run(){let startedAt=deps.now(),seenRunning=!1;await send(!0);try{while(!stopped){if(await deps.sleep(timings.keepaliveMs),stopped)break;let elapsed=deps.now()-startedAt;if(elapsed>=timings.maxMs)break;if(await deps.isRunning().catch(()=>!1))seenRunning=!0;else if(seenRunning||elapsed>=timings.warmupMs)break;await send(!0)}}finally{await send(!1)}}return{stop:()=>{stopped=!0},done:run()}}var REPLY_WINDOW_MS=86400000,ACCOUNT_RECHECK_MS=5000,RETRY_MS2=2000,BACKOFF_MS=30000,MAX_CONSECUTIVE_FAILURES=3,EXPIRED_PAUSE_MS=600000,DEFAULT_NOTIFY_TICK_MS=20000,SEEN_CAP=256;function redact(id){return id.length>8?`${id.slice(0,8)}\u2026`:id}function startWeixinBridge(deps){let now=deps.now??Date.now,pollTimeoutMs=deps.pollTimeoutMs??LONG_POLL_TIMEOUT_MS,stopped=!1,account=deps.store.readAccount(),client=null,state=null,seen=new Set,tracker=new GroupTracker,gateTracker=new GateTracker,routineTracker=new RoutineTracker,agent=createAgentControl({ops:deps.ops,dir:join2(deps.store.dir,"agent"),override:()=>deps.store.readAccount()?.agent??null,read:()=>state?.agent,write:(next)=>{if(state)saveState({...state,agent:next})},now}),sleep=(ms)=>delay(ms,void 0,{ref:!1});async function pause(ms){let before=account?.token,until=now()+ms;while(!stopped&&now()<until)if(await sleep(Math.min(ACCOUNT_RECHECK_MS,until-now())),deps.store.readAccount()?.token!==before)return}function saveState(next){state=next,deps.store.writeState(next)}function refreshAccount(){let next=deps.store.readAccount();if(!next){let wasBound=account!==null;if(account=null,client=null,state=null,wasBound)deps.log("weixin","unbound \u2014 stopped polling"),deps.onUnbound?.();return!1}if(!client||!account||next.token!==account.token||next.accountId!==account.accountId)client=new IlinkClient(next.baseUrl||ILINK_BASE_URL,next.token,deps.fetch),state=deps.store.readState(next.accountId),deps.log("weixin",`bound to ${redact(next.accountId)} \u2014 polling`);return account=next,!0}function recordUndelivered(to,reason,text){deps.store.appendUndelivered({at:new Date(now()).toISOString(),to,reason,text}),deps.log("weixin",`push to ${redact(to)} not delivered: ${reason}`)}let typing=new Map;function showTyping(to,taskId){if(!client||!state||typing.has(to))return;let ilink=client,contextToken=state.peers[to]?.contextToken??null,ticket=null,handle=startTyping({send:async(on)=>{ticket??=ilink.typingTicket(to,contextToken);let t=await ticket;if(t)await ilink.sendTyping(to,t,on)},isRunning:()=>deps.ops.taskRunning(taskId),sleep,now,log:(message)=>deps.log("weixin",message)},deps.typingTimings);typing.set(to,handle),handle.done.finally(()=>{if(typing.get(to)===handle)typing.delete(to)})}async function deliver(to,text){if(!client||!state)return!1;let result=await sendBubbles(client,to,text,state.peers[to]?.contextToken??null,sleep);if(!result.ok)recordUndelivered(to,result.reason,result.rest);return result.ok}async function handleInbound2(message){if(!account||!state)return;let from=message.from_user_id?.trim()??"";if(!from||from===account.accountId||!isDirectUserMessage(message))return;let id=message.message_id===void 0?"":String(message.message_id);if(id){if(seen.has(id))return;if(seen.add(id),seen.size>SEEN_CAP)seen.delete(seen.values().next().value??"")}if(!isAllowedSender(account,from)){deps.log("weixin",`dropped a message from unlisted sender ${redact(from)}`),saveState({...state,rejected:[{userId:from,at:now()},...state.rejected.filter((r)=>r.userId!==from)]});return}let peer=state.peers[from];saveState({...state,peers:{...state.peers,[from]:{contextToken:message.context_token||peer?.contextToken,lastInboundAt:now()}}});let text=messageText(message),result=text?await handleInbound(text,deps.ops,agent):{reply:"Text messages only. Send /help."};if(result.reply)await deliver(from,result.reply);if(result.agentTaskId)showTyping(from,result.agentTaskId)}async function pollLoop(){let failures=0;while(!stopped){if(!refreshAccount()||!client||!state){await pause(ACCOUNT_RECHECK_MS);continue}let resp;try{resp=await client.getUpdates(state.syncBuf,pollTimeoutMs)}catch(err){if(failures++,deps.log("weixin",`getupdates failed (${failures}): ${err instanceof Error?err.message:String(err)}`),await pause(failures>=MAX_CONSECUTIVE_FAILURES?BACKOFF_MS:RETRY_MS2),failures>=MAX_CONSECUTIVE_FAILURES)failures=0;continue}let outcome=classifyIlink(resp);if(outcome==="session-expired"){deps.log("weixin","binding expired \u2014 run `rove weixin login` again; pausing 10m"),await pause(EXPIRED_PAUSE_MS);continue}if(outcome!=="ok"){if(failures++,deps.log("weixin",`getupdates refused: ${describeIlink(resp)}`),await pause(failures>=MAX_CONSECUTIVE_FAILURES?BACKOFF_MS:RETRY_MS2),failures>=MAX_CONSECUTIVE_FAILURES)failures=0;continue}failures=0;for(let message of resp.msgs??[])try{await handleInbound2(message)}catch(err){deps.log("weixin",`inbound failed: ${err instanceof Error?err.message:String(err)}`)}if(state&&resp.get_updates_buf&&resp.get_updates_buf!==state.syncBuf)saveState({...state,syncBuf:resp.get_updates_buf})}}async function push(text){if(!account||!state)return;let targets=[...new Set([account.ownerUserId,...account.allow].filter(Boolean))];for(let to of targets){let last=state.peers[to]?.lastInboundAt;if(last===void 0||now()-last>REPLY_WINDOW_MS){recordUndelivered(to,last===void 0?"no message from this user yet":"reply window closed (>24h since their last message)",text);continue}await deliver(to,text)}}let notifying=!1;async function notifyTick(){if(notifying||stopped||!account)return;notifying=!0;try{let snapshot=await deps.ops.status(null),arrivals=tracker.observe(snapshot.tasks);if(arrivals.length>0)await push(renderArrivals(arrivals));let decisions=gateTracker.observe(snapshot.gatesUnreadable?null:snapshot.gates);if(decisions.length>0)await push(renderGateArrivals(decisions,new Map(snapshot.tasks.map((t)=>[t.taskId,t.title]))));let runs=routineTracker.observe(await deps.ops.notifyingRoutineRuns());for(let text of renderRoutineRuns(runs))await push(text)}catch(err){deps.log("weixin",`notify tick failed: ${err instanceof Error?err.message:String(err)}`)}finally{notifying=!1}}pollLoop().catch((err)=>deps.log("weixin",`poll loop died: ${err instanceof Error?err.message:String(err)}`));let notifyTimer=setInterval(()=>void notifyTick(),deps.notifyTickMs??DEFAULT_NOTIFY_TICK_MS);return notifyTimer.unref?.(),notifyTick(),{isBound:()=>account!==null,stop:()=>{stopped=!0;for(let handle of typing.values())handle.stop();clearInterval(notifyTimer)}}}var STATUS_TASK_LIMIT=500;function stringField(value,key){if(value&&typeof value==="object"&&key in value){let field=Reflect.get(value,key);if(typeof field==="string")return field}return}async function liveTasks(client){let{tasks}=await client.request("task.list");return tasks.filter((t)=>t.deletion?.phase!=="queued"&&t.deletion?.phase!=="running")}function createRoveOps(client){return{status:async(repo)=>{let{payload,gatesUnreadable}=await loadContext(client,defaultApiRuntime,{repo,limit:STATUS_TASK_LIMIT});return{...payload,gatesUnreadable}},tasks:async()=>(await liveTasks(client)).map((t)=>({id:t.id,title:t.title,repo:t.repo})),repos:async()=>[...new Set([...getSavedRepos(),...(await liveTasks(client)).map((t)=>t.repo)])],send:async(taskId,tab,prompt)=>{let result=await invokeVerb("send",["--task-id",taskId,...tab?["--tab",tab]:[],"--plain","--prompt",prompt],{client}),landedTab=stringField(result,"session")?.split("::")[1],started=Boolean(result&&typeof result==="object"&&Reflect.get(result,"started")===!0);return{...landedTab?{tab:landedTab}:{},started}},gates:async()=>{let{gates}=await client.request("gate.list",{status:"open"});return gates},answerGate:async(gateId2,{option,text})=>{return{delivered:(await client.request("gate.answer",{gateId:gateId2,...option?{option}:{},...text?{text}:{},by:"weixin"})).delivered===!0}},notifyingRoutineRuns:async()=>{let{automations}=await client.request("automation.list");return await Promise.all(automations.filter((a)=>a.notify).map(async(a)=>{let{runs}=await client.request("automation.runs",{id:a.id});return{id:a.id,name:a.name,runs}}))},openAgentTask:async(dir,title)=>{let{taskId}=await client.request("task.openDir",{dir});return await client.request("task.rename",{taskId,title}),await client.request("task.pin",{taskId,pinned:!0}),{taskId}},newConversation:async(taskId,prompt)=>{let result=await invokeVerb("send",["--task-id",taskId,"--tab","new","--plain","--prompt",prompt],{client}),tab=stringField(result,"session")?.split("::")[1];if(!tab)throw Error("send --tab new returned no tab");return{tab}},taskRunning:async(taskId)=>{let{payload}=await loadContext(client,defaultApiRuntime,{repo:null,limit:STATUS_TASK_LIMIT});return payload.tasks.find((t)=>t.taskId===taskId)?.activity?.state==="running"},clearReport:async(deliveryId)=>{await invokeVerb("attention-dismiss",["--delivery",deliveryId],{client})},add:async(repo,prompt)=>{ensurePluginEnginesLoaded();let result=await invokeVerb("add",["--repo",repo,"--prompt",prompt],{client}),taskId=stringField(result,"taskId");if(!taskId)throw Error("add returned no task id");return{taskId}}}}function createWeixinChannel(){let bridge=null;return{async start(ctx){let client=new RoveDaemonClient(ctx.socketPath);try{await client.connect()}catch(err){ctx.log("weixin",`could not reach the daemon socket: ${err instanceof Error?err.message:String(err)}`);return}bridge=startWeixinBridge({store:new WeixinStore,ops:createRoveOps(client),log:(event,message)=>ctx.log(event,message),onUnbound:()=>ctx.keepAliveChanged()})},stop:()=>bridge?.stop(),keepAlive:()=>bridge?.isBound()??!1}}import{readFileSync as readFileSync2}from"fs";import{setTimeout as delay2}from"timers/promises";var import_qrcode_terminal=__toESM(require_main(),1);var MAX_QR_REFRESHES=3,DEFAULT_TIMEOUT_MS=480000,POLL_GAP_MS=1000;async function runQrLogin(store,baseUrl,io,fetchFn=fetch,timeoutMs=DEFAULT_TIMEOUT_MS){let qr=await fetchLoginQr(baseUrl,fetchFn);io.say("Scan with WeChat (\u5FAE\u4FE1 \u2192 \u626B\u4E00\u626B), then confirm on the phone:"),io.showQr(qr.url);let pollBase=baseUrl,refreshes=0,announcedScan=!1,deadline=io.now()+timeoutMs;while(io.now()<deadline){let status=await pollLoginStatus(pollBase,qr.qrcode,fetchFn).catch(()=>({status:"wait"}));switch(status.status){case"scaned":if(!announcedScan)io.say("Scanned \u2014 confirm on your phone\u2026");announcedScan=!0;break;case"redirect":pollBase=status.baseUrl;break;case"expired":if(refreshes++,refreshes>MAX_QR_REFRESHES)return{ok:!1,reason:"the QR code expired too many times"};io.say(`QR expired \u2014 here is a new one (${refreshes}/${MAX_QR_REFRESHES}):`),qr=await fetchLoginQr(baseUrl,fetchFn),pollBase=baseUrl,announcedScan=!1,io.showQr(qr.url);break;case"confirmed":{let previous=store.readAccount(),account={accountId:status.accountId,token:status.token,baseUrl:status.baseUrl,ownerUserId:status.userId,allow:previous?.accountId===status.accountId?previous.allow:[],savedAt:new Date(io.now()).toISOString()};return store.writeAccount(account),{ok:!0,account}}case"wait":break}await io.sleep(POLL_GAP_MS)}return{ok:!1,reason:"timed out waiting for the scan"}}var CLI_NAME=ROVE_PRODUCT_NAME,WEIXIN_USAGE=[`Usage: ${CLI_NAME} weixin <login|logout|status|allow|deny|send|agent>`,"","Talk to Rove from WeChat (\u5FAE\u4FE1): ask for status, message a task's agent,","start a task, and get pinged when a task needs you. The daemon must be","running for messages to flow.","","Commands:"," login Show a QR code; scan it in WeChat to bind (re-run to re-bind)"," logout Remove the binding and its credentials"," status Binding, allowed senders, reply windows, undelivered pushes"," allow <user-id> Let another WeChat user command Rove (ids: see status)"," deny <user-id> Revoke a user added with allow"," send [text] Message the owner (routines, scripts, agents). Text from the"," arguments, --file <path>, or stdin; --subject <line> prepends a header"," agent [<task-id> [tab-N]] Show the WeChat agent and its conversations, or use an"," existing task for it; `agent off` returns to the WeChat project",""].join(`
|
|
31
|
+
`);function usageError(message){process.stderr.write(`${CLI_NAME} weixin: ${message}
|
|
32
|
+
|
|
33
|
+
${WEIXIN_USAGE}
|
|
34
|
+
`),process.exit(2)}function fail(message){process.stderr.write(`${CLI_NAME} weixin: ${message}
|
|
35
|
+
`),process.exit(1)}function age(ms){let m=Math.floor(ms/60000);if(m<60)return`${m}m ago`;let h=Math.floor(m/60);return h<48?`${h}h ago`:`${Math.floor(h/24)}d ago`}async function runWeixinCli(argv){let[verb,arg]=argv;if(!verb||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${WEIXIN_USAGE}
|
|
36
|
+
`);return}if(!SUBCOMMAND_VERBS.weixin.includes(verb))usageError(`unknown verb "${verb}"`);let store=new WeixinStore;switch(verb){case"login":return await login(store);case"logout":process.stdout.write(store.clearAccount()?`WeChat binding removed.
|
|
37
|
+
`:`No WeChat binding to remove.
|
|
38
|
+
`);return;case"status":return await status(store);case"allow":case"deny":return editAllow(store,verb,arg);case"send":return await send(store,argv.slice(1));case"agent":return await bindAgent(store,argv.slice(1));default:usageError(`"${verb}" has no handler`)}}async function login(store){let result=await runQrLogin(store,resolveIlinkBaseUrl(),{showQr:(url)=>{import_qrcode_terminal.default.generate(url,{small:!0},(art)=>process.stdout.write(`${art}
|
|
39
|
+
`)),process.stdout.write(`Or open: ${url}
|
|
40
|
+
`)},say:(line)=>process.stdout.write(`${line}
|
|
41
|
+
`),sleep:(ms)=>delay2(ms),now:Date.now}).catch((err)=>fail(`login failed: ${err instanceof Error?err.message:String(err)}`));if(!result.ok)fail(`login failed: ${result.reason}`);process.stdout.write(["Bound. Send the bot `/help` from WeChat to try it.",`Credentials: ${store.accountPath} (owner-only)`,await daemonRunning()?"The running daemon picks this up within seconds.":`The daemon is not running \u2014 start it with \`${CLI_NAME} daemon start\`.`,""].join(`
|
|
42
|
+
`))}async function daemonRunning(){let client=await connectIfRunning().catch(()=>null);return client?.close(),client!==null}async function status(store){let account=store.readAccount();if(!account){process.stdout.write(`Not bound. Run \`${CLI_NAME} weixin login\`.
|
|
43
|
+
`);return}let state=store.readState(account.accountId),now=Date.now(),lines=[`Bound to bot ${account.accountId} since ${account.savedAt||"unknown"}`,`Daemon: ${await daemonRunning()?"running":`not running \u2014 \`${CLI_NAME} daemon start\``}`,`Owner: ${account.ownerUserId||"(unknown \u2014 re-run login)"}`,`Allowed: ${account.allow.length>0?account.allow.join(", "):"owner only"}`],peers=Object.entries(state.peers);if(peers.length>0){lines.push("Reply windows:");for(let[id,peer]of peers)lines.push(` ${id} last message ${age(now-peer.lastInboundAt)} \u2014 ${now-peer.lastInboundAt<=REPLY_WINDOW_MS?"open":"closed"}`)}if(state.rejected.length>0){lines.push(`Refused senders (\`${CLI_NAME} weixin allow <id>\` to let one in):`);for(let r of state.rejected)lines.push(` ${r.userId} ${age(now-r.at)}`)}let undelivered=store.readUndelivered();if(undelivered.length>0){let last=undelivered[undelivered.length-1];if(lines.push(`Undelivered pushes: ${undelivered.length} (${store.undeliveredPath})`),last)lines.push(` latest ${last.at}: ${last.reason}`)}process.stdout.write(`${lines.join(`
|
|
44
|
+
`)}
|
|
45
|
+
`)}async function readStdin(){let chunks=[];for await(let chunk of process.stdin)chunks.push(typeof chunk==="string"?Buffer.from(chunk):chunk);return Buffer.concat(chunks).toString("utf8")}async function send(store,args){let subject,file,words=[];for(let i=0;i<args.length;i++){let a=args[i]??"";if(a==="--subject"||a==="-s")subject=args[++i];else if(a==="--file"||a==="-f")file=args[++i];else words.push(a)}if(subject===void 0&&args.includes("--subject")||file===void 0&&args.includes("--file"))usageError("--subject and --file need a value");if(file!==void 0&&words.length>0)usageError("pass the text or --file, not both");let body=(file==="-"||file===void 0&&words.length===0?await readStdin():file!==void 0?readFileSync2(file,"utf8"):words.join(" ")).trim();if(!body&&!subject)usageError("nothing to send");let text=subject?body?`${subject}
|
|
46
|
+
${body}`:subject:body,account=store.readAccount();if(!account)fail(`not bound \u2014 run \`${CLI_NAME} weixin login\` first`);let to=account.ownerUserId;if(!to)fail(`the binding has no owner id \u2014 re-run \`${CLI_NAME} weixin login\``);let peer=store.readState(account.accountId).peers[to],now=Date.now();if(!peer||now-peer.lastInboundAt>REPLY_WINDOW_MS){let reason=peer?"reply window closed (>24h since their last message)":"no message from the owner yet";store.appendUndelivered({at:new Date(now).toISOString(),to,reason,text}),fail(`not sent: ${reason}. WeChat only lets the bot write within a day of your last message to it.`)}let client=new IlinkClient(account.baseUrl||ILINK_BASE_URL,account.token),result=await sendBubbles(client,to,text,peer.contextToken??null,(ms)=>delay2(ms));if(!result.ok)store.appendUndelivered({at:new Date().toISOString(),to,reason:result.reason,text:result.rest}),fail(`not sent: ${result.reason}`);process.stdout.write(`Sent.
|
|
47
|
+
`)}async function bindAgent(store,args){let account=store.readAccount();if(!account)fail(`not bound \u2014 run \`${CLI_NAME} weixin login\` first`);let[ref,tab]=args;if(!ref){let live=store.readState(account.accountId).agent,lines=[account.agent?`Using task ${account.agent.taskId}${account.agent.tab?` ${account.agent.tab}`:""} (set with \`agent <task-id>\`).`:"Using the WeChat project Rove creates on the first plain message."];if(live){lines.push(`Live conversation: ${live.taskId} ${live.tab}`,`Conversations (${live.conversations.length}):`);for(let c of live.conversations)lines.push(` ${c.tab} started ${new Date(c.startedAt).toISOString()}`)}process.stdout.write(`${lines.join(`
|
|
48
|
+
`)}
|
|
49
|
+
`);return}if(ref==="off"){let{agent:_dropped,...rest}=account;store.writeAccount(rest),process.stdout.write(account.agent?`Back to the WeChat project Rove manages.
|
|
50
|
+
`:`Already using the WeChat project Rove manages.
|
|
51
|
+
`);return}if(tab!==void 0&&!/^tab-[A-Za-z0-9-]+$/.test(tab))usageError(`expected a tab id like tab-2, got "${tab}"`);let taskId=await resolveTaskId(ref);store.writeAccount({...account,agent:{taskId,...tab?{tab}:{}}}),process.stdout.write(`Plain WeChat messages now go to ${taskId}${tab?` ${tab}`:""}; commands need a leading / (/status), /new opens a new tab.
|
|
52
|
+
`)}async function resolveTaskId(ref){let client=await connectIfRunning().catch(()=>null);if(!client)fail(`the daemon is not running \u2014 start it with \`${CLI_NAME} daemon start\``);try{let{tasks}=await client.request("task.list"),needle=ref.toLowerCase(),hits=tasks.filter((t)=>t.id.toLowerCase()===needle||t.id.toLowerCase().endsWith(needle));if(hits.length===1&&hits[0])return hits[0].id;fail(hits.length===0?`no task matches "${ref}"`:`"${ref}" matches ${hits.length} tasks; use more characters`)}finally{client.close()}}function editAllow(store,verb,userId){if(!userId)usageError(`${verb} needs a WeChat user id (see \`${CLI_NAME} weixin status\`)`);let account=store.readAccount();if(!account)fail(`not bound \u2014 run \`${CLI_NAME} weixin login\` first`);let allow=verb==="allow"?[...new Set([...account.allow,userId])]:account.allow.filter((id)=>id!==userId);store.writeAccount({...account,allow}),process.stdout.write(verb==="allow"?`Allowed ${userId}.
|
|
53
|
+
`:allow.length===account.allow.length?`${userId} was not on the list.
|
|
54
|
+
`:`Removed ${userId}.
|
|
55
|
+
`)}var weixin={id:"weixin",createChannel:createWeixinChannel,runCli:runWeixinCli},src_default=weixin;export{src_default as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{loadPluginRegistry,readPluginManifest}from"./chunk-
|
|
2
|
+
import{loadPluginRegistry,readPluginManifest}from"./chunk-kvwqh35r.js";import{CONTRIB_ENGINE_IDS,clearPluginEngines,registerPluginEngine,resetAvailableVendorsCache}from"./chunk-8saxdp88.js";import{getCustomEngineIds}from"./chunk-m6pp9gaf.js";function loadPluginEngines(homeDir){let registered=[];try{for(let entry of loadPluginRegistry(homeDir).plugins){if(!entry.enabled)continue;try{let{manifest}=readPluginManifest(entry.root);for(let engine of manifest.engines){let identity={shortName:engine.identity?.shortName??engine.name};if(registerPluginEngine(engine.id,{displayName:engine.name,defaultCommand:engine.command,...engine.processNames?{processNames:engine.processNames}:{},screenManifest:{rules:engine.rules},identity,...engine.firstMessageDelivery?{firstMessageDelivery:engine.firstMessageDelivery}:{}}))registered.push(engine.id);else console.warn(`[rove] plugin ${entry.id}: engine id \`${engine.id}\` shadows a built-in or shipped engine \u2014 skipped`)}}catch{}}}catch{}return registered}function reloadPluginEngines(homeDir){clearPluginEngines();let registered=loadPluginEngines(homeDir);return loadedOnce=registered,resetAvailableVendorsCache(),registered}var loadedOnce;function ensurePluginEnginesLoaded(){return loadedOnce??=loadPluginEngines(),loadedOnce}function registeredEngineIds(){return[...new Set([...CONTRIB_ENGINE_IDS,...getCustomEngineIds(),...ensurePluginEnginesLoaded()])]}
|
|
3
3
|
export{loadPluginEngines,reloadPluginEngines,ensurePluginEnginesLoaded,registeredEngineIds};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{preRenameStateDir}from"./chunk-b39sdtt0.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-nc46gddg.js";import{homedir}from"os";import{join}from"path";function stateRoot(homeDir){let home=homeDir??readRoveHomeDirEnv()??homedir();return join(home,ROVE_STATE_DIR_BASENAME)}function pluginRegistryPath(homeDir){return join(stateRoot(homeDir),"plugins.json")}function builtinModsPath(homeDir){return join(stateRoot(homeDir),"builtin-mods.json")}function pluginsRootDir(homeDir){return join(stateRoot(homeDir),"plugins")}function legacyPluginsRootDir(homeDir){let home=homeDir??readRoveHomeDirEnv()??homedir();return join(preRenameStateDir(home),"plugins")}function pluginDataDir(id,homeDir){return join(pluginsRootDir(homeDir),id)}function pluginCheckoutDir(id,homeDir){return join(pluginDataDir(id,homeDir),"checkout")}function pluginConfigDir(id,homeDir){return join(pluginDataDir(id,homeDir),"config")}function pluginStateDir(id,homeDir){return join(pluginDataDir(id,homeDir),"state")}function pluginLogPath(id,homeDir){return join(pluginDataDir(id,homeDir),"log.jsonl")}function pluginsOutdatedCachePath(homeDir){return join(stateRoot(homeDir),"plugins-outdated.json")}
|
|
3
|
+
export{pluginRegistryPath,builtinModsPath,pluginsRootDir,legacyPluginsRootDir,pluginDataDir,pluginCheckoutDir,pluginConfigDir,pluginStateDir,pluginLogPath,pluginsOutdatedCachePath};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{errorMessage}from"./chunk-2brn8e1y.js";import{JsonHookAdapter,ROVE_HOOK_VERSION,bobAuthSecretsPath,claudeGlobalConfigPath,codexAuthPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isRoveHook,kimiCredentialsPath,readTextFileSyncBounded,roveHookArgs,roveHookInvocation,updateSharedJson}from"./chunk-7zyyvc3d.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{isObject}from"./chunk-7ghwdjdc.js";import{getCustomEngineIds,getDisabledEngineIds}from"./chunk-
|
|
2
|
+
import{errorMessage}from"./chunk-2brn8e1y.js";import{JsonHookAdapter,ROVE_HOOK_VERSION,bobAuthSecretsPath,claudeGlobalConfigPath,codexAuthPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isRoveHook,kimiCredentialsPath,readTextFileSyncBounded,roveHookArgs,roveHookInvocation,updateSharedJson}from"./chunk-7zyyvc3d.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{isObject}from"./chunk-7ghwdjdc.js";import{getCustomEngineIds,getDisabledEngineIds}from"./chunk-m6pp9gaf.js";import{__require}from"./chunk-91sykzqq.js";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"]}]},DEVIN={rules:[{state:"blocked",bottomLines:8,all:["do you trust the authors of this directory?","yes, trust "]},{state:"blocked",bottomLines:8,all:["approve once","select","confirm","esc cancel"]},{state:"working",bottomLines:8,all:["running tools","esc to interrupt"]},{state:"working",bottomLines:6,all:["guide devin while it works"]},{state:"working",bottomLines:8,all:["reading shell ","timeout:"]},{state:"idle",bottomLines:8,all:["ask devin to build","features, fix bugs","your code"],lineRegex:["^\\s*\u276D Ask Devin to build"]},{state:"idle",bottomLines:6,all:["context:"],lineRegex:["^\\s*\u276D"]}]},QODERCLI={rules:[{state:"blocked",all:["waiting for user confirmation"],any:["yes","no","allow","reject"]},{state:"blocked",all:["awaiting approval"],any:["allow","reject"]},{state:"blocked",any:["permission required","allow once or always?","asking user","enter your response","review your answers:","shell awaiting input"]},{state:"working",any:["(esc to cancel,"]},{state:"working",lineRegex:["^\\s*[\\u2800-\\u28FF]\\s+.*[A-Za-z]"]}]},HERMES={rules:[{state:"blocked",bottomLines:14,any:["dangerous","approval","allow once","hermes needs your","type your answer","approve once","start a new session","keep going"],lineRegex:["enter\\s+(?:to\\s+)?(?:confirm|send)","press enter","\u2191/\u2193\\s+(?:to\\s+)?select","show full command","type 1/2/3","y/n quick","other \\(type"]},{state:"blocked",bottomLines:14,any:["sudo password","skill setup"]},{state:"blocked",bottomLines:14,all:["\uD83D\uDD11","for "]},{state:"working",bottomLines:5,any:["msg=interrupt","ctrl+c to interrupt","ctrl+c cancel"]}]},KILO={rules:[{state:"blocked",any:["\u25B3 permission required"]},{state:"blocked",all:["esc dismiss"],any:["enter confirm","enter submit","enter toggle"],lineRegex:["\u2191\u2193\\s*select","\u21C6\\s*tab"]},{state:"working",any:["esc interrupt"]}]},MASTRACODE={rules:[]};import{existsSync}from"fs";import{homedir}from"os";import{dirname,join}from"path";function parseFlatHooks(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 mergeFlatHooks(format,current,install,inv=roveHookInvocation()){let verbs=format.eventMap.map((spec)=>spec.verb),{hooks:rawHooks,...rest}=current,hooks=isObject(rawHooks)?{...rawHooks}:{},quoting=hookCommandQuoting();for(let{event,verb}of format.eventMap){let kept=(Array.isArray(hooks[event])?hooks[event]:[]).filter((entry)=>!isRoveHook(entry,verbs));if(install){let command=quoteShellArgv([...inv,"hook",verb,...roveHookArgs(format.vendor)],quoting);kept.push(format.withType?{type:"command",command}:{command})}if(kept.length>0)hooks[event]=kept;else delete hooks[event]}return{version:1,...rest,hooks}}var CURSOR_HOOK_EVENT_MAP=[{event:"sessionStart",verb:"session-start"}],CURSOR_FORMAT={vendor:"cursor",eventMap:CURSOR_HOOK_EVENT_MAP};function cursorHooksPath(home=homedir()){let override=process.env.CURSOR_CONFIG_DIR?.trim();return join(override||join(home,".cursor"),"hooks.json")}function parseCursorHooks(raw){return parseFlatHooks(raw)}function mergeCursorHooks(current,install,inv=roveHookInvocation()){return mergeFlatHooks(CURSOR_FORMAT,current,install,inv)}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
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}import{homedir as homedir2}from"os";import{join as join2}from"path";import{existsSync as existsSync2}from"fs";import{dirname as dirname2}from"path";function sessionStartOnly(matcher){return[{event:"SessionStart",verb:"session-start",...matcher?{matcher}:{}}]}class SessionStartHookAdapter extends JsonHookAdapter{installGuardDir(settingsFilePath){return dirname2(settingsFilePath)}async installActivityHooks(settingsFilePath,opts={}){if(!existsSync2(this.installGuardDir(settingsFilePath)))return{ok:!0};return super.installActivityHooks(settingsFilePath,opts)}async removeActivityHooks(settingsFilePath){if(!existsSync2(settingsFilePath))return;await super.removeActivityHooks(settingsFilePath)}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}}var DEVIN_HOOK_EVENT_MAP=sessionStartOnly();function devinSettingsPath(home=homedir2()){let xdg=process.env.XDG_CONFIG_HOME?.trim();return join2(xdg||join2(home,".config"),"devin","config.json")}class DevinHookAdapter extends SessionStartHookAdapter{vendor="devin";eventMap=DEVIN_HOOK_EVENT_MAP;globalSettingsPath(){return devinSettingsPath()}}import{homedir as homedir3}from"os";import{join as join3}from"path";var DROID_HOOK_EVENT_MAP=sessionStartOnly();function droidSettingsPath(home=homedir3()){return join3(home,".factory","settings.json")}class DroidHookAdapter extends SessionStartHookAdapter{vendor="droid";eventMap=DROID_HOOK_EVENT_MAP;globalSettingsPath(){return droidSettingsPath()}}import{homedir as homedir4}from"os";import{dirname as dirname3,join as join4}from"path";var GROK_HOOK_EVENT_MAP=sessionStartOnly();function grokConfigDir(home=homedir4()){return process.env.GROK_HOME?.trim()||join4(home,".grok")}function grokHooksPath(home=homedir4()){return join4(grokConfigDir(home),"hooks","rove.json")}class GrokHookAdapter extends SessionStartHookAdapter{vendor="grok";eventMap=GROK_HOOK_EVENT_MAP;globalSettingsPath(){return grokHooksPath()}installGuardDir(settingsFilePath){return dirname3(dirname3(settingsFilePath))}sessionFromPayload(payload){let sessionId=firstString2(payload.session_id,payload.sessionId);if(!sessionId)return;let transcriptPath=firstString2(payload.transcript_path,payload.transcriptPath);return{sessionId,...transcriptPath?{transcriptPath}:{}}}}function firstString2(...values){for(let value of values)if(typeof value==="string"&&value)return value;return}import{existsSync as existsSync3}from"fs";import{mkdir,readFile,rm,writeFile}from"fs/promises";import{homedir as homedir5}from"os";import path from"path";var HERMES_PLUGIN_NAME="rove-agent-state";function indentOf(line){if(!line.trim()||line.trim().startsWith("#"))return;let match=/^ */.exec(line),indent=match?match[0].length:0;return line[indent]==="\t"?void 0:indent}function keyAt(line,indent){if(indentOf(line)!==indent)return;return/^ *(["']?)([A-Za-z0-9_.-]+)\1:(?:\s|$)/.exec(line)?.[2]}function inlineValue(line){return(/^ *(["']?)[A-Za-z0-9_.-]+\1:(.*)$/.exec(line)?.[2]??"").trim()}function listItemAt(line,indent){if(indentOf(line)!==indent)return;let match=/^ *- *(.*)$/.exec(line);if(!match)return;return match[1].trim().replace(/^["']|["']$/g,"")}function join5(lines,trailingNewline){return lines.join(`
|
|
4
4
|
`)+(trailingNewline?`
|
|
5
5
|
`:"")}function setHermesPluginEnabled(content,enabled){let trailingNewline=content.endsWith(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{quoteShellArg}from"./chunk-7kysxgbq.js";import{getPersistedString}from"./chunk-
|
|
2
|
+
import{readOnlyGitProcessEnv}from"./chunk-6xppe9bj.js";import{quoteShellArg}from"./chunk-7kysxgbq.js";import{getPersistedString}from"./chunk-m6pp9gaf.js";import{recordSpawn}from"./chunk-40dgv828.js";import{pathSyntax,pathWithin}from"./chunk-pn5ygqn6.js";var EDITOR_KINDS=["auto","vim","nvim","nano","emacs","custom"],AUTO_EDITOR_CANDIDATES=["nvim","vim","emacs","nano"],EDITOR_KIND_KEY="editor.kind",EDITOR_CUSTOM_KEY="editor.customCommand",DEFAULT_EDITOR_KIND="auto";function normalizeEditorKind(value){return EDITOR_KINDS.includes(value)?value:"auto"}var FILE_PLACEHOLDER="{file}",LINE_PLACEHOLDER="{line}",PLUS_LINE_EDITORS=new Set(["vi","vim","nvim","nano","emacs","emacsclient","micro","kak","mg","joe"]),SUFFIX_LINE_EDITORS=new Set(["hx","helix"]);function firstToken(cmd){return cmd.trim().split(/\s+/)[0]??""}function buildEditorCommand(kind,customCommand,absPath,envEditor,line){if(kind==="vim"||kind==="nvim"||kind==="nano"||kind==="emacs")return plainEditorCommand(kind,absPath,line);let tmpl=(customCommand.trim()||(envEditor??"").trim()).trim();if(!tmpl)return null;let bin=firstToken(tmpl);if(!bin)return null;let hasLine=tmpl.includes(LINE_PLACEHOLDER),autoPlusLine=!hasLine&&line!==void 0&&PLUS_LINE_EDITORS.has(bin.split("/").pop()??bin),target=hasLine||autoPlusLine?{arg:quoteShellArg(absPath),atLine:!0}:fileArg(bin,absPath,line),withLine=(autoPlusLine?`${bin} +${line}${tmpl.slice(bin.length)}`:tmpl).split(LINE_PLACEHOLDER).join(String(line??1)),command=withLine.includes(FILE_PLACEHOLDER)?withLine.split(FILE_PLACEHOLDER).join(target.arg):`${withLine} ${target.arg}`;return line===void 0?{bin,command}:{bin,command,atLine:target.atLine}}function plainEditorCommand(bin,absPath,line){let target=fileArg(bin,absPath,line),command=`${bin} ${target.arg}`;return line===void 0?{bin,command}:{bin,command,atLine:target.atLine}}function fileArg(bin,absPath,line){let file=quoteShellArg(absPath);if(line===void 0)return{arg:file,atLine:!1};let name=bin.split("/").pop()??bin;if(PLUS_LINE_EDITORS.has(name))return{arg:`+${line} ${file}`,atLine:!0};if(SUFFIX_LINE_EDITORS.has(name))return{arg:`${file}:${line}`,atLine:!0};return{arg:file,atLine:!1}}function buildNvimDiffCommand(bin,absPath,relPath){let file=quoteShellArg(absPath);return["f=$(mktemp 2>/dev/null)",`if [ -n "$f" ] && git show ${quoteShellArg(`HEAD:./${relPath}`)} > "$f" 2>/dev/null; then`,` ${bin} -d "$f" ${file} -c 'setlocal nomodifiable' -c 'wincmd l'; r=$?`,"else",` ${bin} ${file}; r=$?`,"fi",'rm -f "$f" 2>/dev/null; exit $r'].join(`
|
|
3
3
|
`)}function relativeToWorktree(worktree,absPath){return pathWithin(worktree,absPath)||null}async function resolveEditorCommand(absPath,line){let kind=normalizeEditorKind(getPersistedString(EDITOR_KIND_KEY)),custom=getPersistedString(EDITOR_CUSTOM_KEY)??"",env=(process.env.VISUAL??process.env.EDITOR??"").trim();if(kind!=="auto")return buildEditorCommand(kind,custom,absPath,env,line);if(env)return buildEditorCommand("custom","",absPath,env,line);for(let bin of AUTO_EDITOR_CANDIDATES)if(await binaryAvailable(bin))return plainEditorCommand(bin,absPath,line);return null}async function binaryAvailable(bin){try{return await Bun.spawn(["sh","-c",`command -v ${quoteShellArg(bin)} >/dev/null 2>&1`],{stdin:"ignore",stdout:"ignore",stderr:"ignore"}).exited===0}catch{return!1}}async function fileHasDiff(worktree,relPath){try{return recordSpawn("tui.fileHasDiff",["git","diff","--quiet","HEAD","--",relPath],worktree),await Bun.spawn(["git","diff","--quiet","HEAD","--",relPath],{cwd:worktree,stdin:"ignore",stdout:"ignore",stderr:"ignore",env:readOnlyGitProcessEnv()}).exited===1}catch{return!1}}async function resolveEditorLaunch(worktree,absPath,line){let resolved=await resolveEditorCommand(absPath,line);if(!resolved)return null;if(!await binaryAvailable(resolved.bin))return null;let command=await maybeDiffCommand(resolved,worktree,absPath),label=editorWindowLabel(absPath);return resolved.atLine===void 0?{command,label}:{command,label,atLine:resolved.atLine}}async function maybeDiffCommand(resolved,worktree,absPath){let{bin,command}=resolved;if(bin!=="nvim"&&bin!=="vim")return command;if(command!==`${bin} ${quoteShellArg(absPath)}`)return command;let rel=relativeToWorktree(worktree,absPath);if(!rel)return command;if(!await fileHasDiff(worktree,rel))return command;return buildNvimDiffCommand(bin,absPath,rel)}function editorWindowLabel(absPath){let base=pathSyntax(absPath).basename(absPath).trim();return base.length>0?base:"edit"}
|
|
4
4
|
export{EDITOR_KINDS,EDITOR_KIND_KEY,EDITOR_CUSTOM_KEY,DEFAULT_EDITOR_KIND,normalizeEditorKind,resolveEditorCommand,binaryAvailable,resolveEditorLaunch};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{DEFAULT_TASK_VENDOR}from"./chunk-xy8be792.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{getCustomEngineIds,getDisabledEngineIds,getPersistedString,setPersistedString}from"./chunk-
|
|
2
|
+
import{DEFAULT_TASK_VENDOR}from"./chunk-xy8be792.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{getCustomEngineIds,getDisabledEngineIds,getPersistedString,setPersistedString}from"./chunk-m6pp9gaf.js";var REPO_KEY_PREFIX="lastActiveVendor.";function validVendor(value,customIds){let v=value?.trim();if(!v)return;if(getDisabledEngineIds().includes(v))return;if(isBuiltinVendor(v)||customIds.includes(v))return v;return}function firstEnabledVendor(){let disabled=new Set(getDisabledEngineIds());return[...BUILTIN_VENDORS,...getCustomEngineIds()].find((id)=>!disabled.has(id))??DEFAULT_TASK_VENDOR}function getRepoLastActiveVendor(repo){return validVendor(getPersistedString(REPO_KEY_PREFIX+repo),getCustomEngineIds())}function setRepoLastActiveVendor(repo,vendor){setPersistedString(REPO_KEY_PREFIX+repo,vendor)}function getGlobalDefaultVendor(){let customIds=getCustomEngineIds();return validVendor(getPersistedString("defaultVendor"),customIds)??validVendor(getPersistedString("lastSelectedVendor"),customIds)}function setGlobalDefaultVendor(vendor){setPersistedString("defaultVendor",vendor)}function resolvePreferredVendor(repo){return(repo?getRepoLastActiveVendor(repo):void 0)??getGlobalDefaultVendor()??firstEnabledVendor()}
|
|
3
3
|
export{getRepoLastActiveVendor,setRepoLastActiveVendor,getGlobalDefaultVendor,setGlobalDefaultVendor,resolvePreferredVendor};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{vendorFromArgv}from"./chunk-b4zqkdyq.js";import{engineEntry}from"./chunk-rbr6qapz.js";import{isContribEngine}from"./chunk-8saxdp88.js";import{roveCliInvocation}from"./chunk-7zyyvc3d.js";import{BUILTIN_VENDORS,coerceVendorId,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{getCustomEngineIds,getPersistedString}from"./chunk-m6pp9gaf.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 engineRenamedFrom(vendor,override){let name=override.trim(),base=engineEntry(vendor).displayName;if(!name||name===base||name===humanizeSlug(vendor))return;return base}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 roveApiInvocation(){let quote=(a)=>/^[A-Za-z0-9_/.:=-]+$/.test(a)?a:`'${a.replace(/'/g,"'\\''")}'`;try{return[...roveCliInvocation(),"api"].map(quote).join(" ")}catch{return"rove api"}}import{randomUUID}from"crypto";function hasFlag(argv,flag){return argv.some((a)=>a===flag||a.startsWith(`${flag}=`))}function controlsOwnSession(identity,argv){return(identity?.sessionControlFlags??[]).some((flag)=>hasFlag(argv,flag))}function pinSessionArgv(identity,argv,sessionId){if(!identity?.pinFlag)return argv;if(controlsOwnSession(identity,argv))return argv;return[...argv,identity.pinFlag,sessionId]}function acceptsPinnedSession(identity,argv){return!!identity?.pinFlag&&!controlsOwnSession(identity,argv)}function resumeSessionArgv(identity,base,sessionId){if(!sessionId||!identity?.resumeArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.resumeArgv(base,sessionId)}function pickUnclaimedSessionId(ids,claimed){for(let i=ids.length-1;i>=0;i--){let id=ids[i];if(id&&!claimed.has(id))return id}return null}function forkSessionArgvFor(identity,base,sourceId,newId){if(!sourceId||!identity?.forkArgv)return null;if(controlsOwnSession(identity,base))return null;return identity.forkArgv(base,sourceId,newId)}function acceptsSessionFork(identity){return!!identity?.forkArgv}var GENERIC_PROTOCOL="generic",ENGINE_PROTOCOLS=BUILTIN_VENDORS;function engineProtocolKey(id){return`engineProtocol.${id}`}function getEngineProtocol(id){if(isBuiltinVendor(id)||isContribEngine(id))return id;let raw=getPersistedString(engineProtocolKey(id))?.trim();return raw&&ENGINE_PROTOCOLS.includes(raw)?raw:void 0}function isPresetId(id){return isBuiltinVendor(id)||isContribEngine(id)||getCustomEngineIds().includes(id)}function listPresetIds(){return[...BUILTIN_VENDORS,...getCustomEngineIds()]}function describePreset(id){let command=getPersistedString(engineCommandKey(id))?.trim()||defaultEngineCommand(id).join(" ");return{id,name:engineDisplayName(id),command,protocol:getEngineProtocol(id)??GENERIC_PROTOCOL,builtin:isBuiltinVendor(id)}}function listEnginePresets(){return listPresetIds().map(describePreset)}function resolveCommandProtocol(command){let trimmed=command?.trim();if(!trimmed)return GENERIC_PROTOCOL;if(isPresetId(trimmed))return getEngineProtocol(trimmed)??GENERIC_PROTOCOL;let fromArgv=vendorFromArgv(trimmed);if(fromArgv)return fromArgv;let argv0=parseEngineCommand(trimmed)[0];if(argv0)for(let id of getCustomEngineIds()){let preset=getPersistedString(engineCommandKey(id))?.trim();if(preset&&parseEngineCommand(preset)[0]===argv0)return getEngineProtocol(id)??GENERIC_PROTOCOL}return GENERIC_PROTOCOL}function engineLaunchArgv(spec){let command=spec.command?.trim();if(!command)return interactiveEngineCommand(spec.vendor,spec.effort,spec.model);let vendor=(isPresetId(command)?getEngineProtocol(command):void 0)??resolveCommandProtocol(command),base=isPresetId(command)?presetBaseArgv(command):(()=>{let argv=parseEngineCommand(command);return argv.length>0?argv:null})();if(!base)return interactiveEngineCommand(spec.vendor,spec.effort,spec.model);return withEngineTerminalTitle(withEngineModel(withEngineEffort(base,vendor,spec.effort),vendor,spec.model),vendor)}function presetBaseArgv(id){let override=getPersistedString(engineCommandKey(id))?.trim();if(override){let argv=parseEngineCommand(override);if(argv.length>0)return argv}return defaultEngineCommand(id)}function sessionProtocol(vendor){let id=vendor?.trim();if(!id)return"claude";return getEngineProtocol(id)??id}function protocolEntry(vendor){return engineEntry(sessionProtocol(vendor))}function withPinnedSessionId(argv,vendor,newId=randomUUID){let identity=engineEntry(sessionProtocol(vendor)).sessionIdentity;if(!acceptsPinnedSession(identity,argv))return{argv,sessionId:null};let sessionId=newId();return{argv:pinSessionArgv(identity,argv,sessionId),sessionId}}function engineResumeArgv(base,vendor,sessionId){return resumeSessionArgv(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sessionId)}function engineCanFork(vendor){return acceptsSessionFork(engineEntry(sessionProtocol(vendor)).sessionIdentity)}function engineForkArgv(base,vendor,sourceId,newId){return forkSessionArgvFor(engineEntry(sessionProtocol(vendor)).sessionIdentity,base,sourceId,newId)}var ID_RE=/^tab-(\d+)$/;function tabOrdinalOf(id){let match=ID_RE.exec(id);return match?Number(match[1]):null}var sameValue=(a,b)=>a===b||JSON.stringify(a)===JSON.stringify(b);function insertAfter(tabs,row,after){if(after===null)return[row,...tabs];let i=after===void 0?-1:tabs.findIndex((t)=>t.id===after);return i<0?[...tabs,row]:[...tabs.slice(0,i+1),row,...tabs.slice(i+1)]}function applyTabOps(current,ops,tombstones=new Set){let state=current,changed=!1,opened=[],set=(next)=>{state=next,changed=!0};for(let op of ops)switch(op.op){case"seed":{if(state===null||state.tabs.length===0){let floor=Math.max(op.state.nextOrdinal,maxOrdinal(op.state)+1,state?.nextOrdinal??0);set({...op.state,nextOrdinal:floor})}break}case"forget":{if(state!==null)set(null);break}case"open":{let base=state??{tabs:[],nextOrdinal:1},wanted=op.row.id;if(wanted!==void 0&&(base.tabs.some((t)=>t.id===wanted)||tombstones.has(wanted))){opened.push(null);break}let ordinal=wanted!==void 0?tabOrdinalOf(wanted)??op.row.ordinal??base.nextOrdinal:base.nextOrdinal,id=wanted??`tab-${ordinal}`,row={...op.row,id,ordinal};set({...base,tabs:insertAfter(base.tabs,row,op.after),nextOrdinal:Math.max(base.nextOrdinal,ordinal+1)}),opened.push(id);break}case"patch":{if(!state)break;let i=state.tabs.findIndex((t)=>t.id===op.id),row=state.tabs[i];if(!row)break;let next={...row},rowChanged=!1;for(let[key,value]of Object.entries(op.set??{})){if(key==="id"||key==="ordinal"||sameValue(next[key],value))continue;next[key]=value,rowChanged=!0}for(let key of op.unset??[]){if(key==="id"||key==="ordinal"||key==="kind"||!(key in next))continue;delete next[key],rowChanged=!0}if(!rowChanged)break;let tabs=[...state.tabs];tabs[i]=next,set({...state,tabs});break}case"close":{if(!state||!state.tabs.some((t)=>t.id===op.id))break;tombstones.add(op.id);let tabs=state.tabs.filter((t)=>t.id!==op.id),reopen=tabs.length===0&&op.reopenAs!==void 0?{reopenAs:op.reopenAs}:{},{activeId,...rest}=state;set({...rest,tabs,...activeId!==void 0&&activeId!==op.id?{activeId}:{},...reopen});break}case"order":{if(!state)break;let byId=new Map(state.tabs.map((t)=>[t.id,t])),tabs=[...op.ids.flatMap((id)=>{let row=byId.get(id);if(!row)return[];return byId.delete(id),[row]}),...state.tabs.filter((t)=>byId.has(t.id))];if(tabs.every((t,i)=>t===state?.tabs[i]))break;set({...state,tabs});break}case"focus":{if(!state||state.activeId===op.id||!state.tabs.some((t)=>t.id===op.id))break;set({...state,activeId:op.id});break}case"meta":{if(!state||sameValue(state.reopenAs,op.reopenAs))break;let{reopenAs:_drop,...rest}=state;set(op.reopenAs===void 0?rest:{...rest,reopenAs:op.reopenAs});break}}return{state,changed,opened}}function maxOrdinal(state){return state.tabs.reduce((max,tab)=>Math.max(max,tab.ordinal),0)}function reserveOrdinals(state,count){let base=state??{tabs:[],nextOrdinal:1},from=Math.max(base.nextOrdinal,maxOrdinal(base)+1);return{state:{...base,nextOrdinal:from+count},from}}function releaseOrdinals(state,from,to){if(!state||state.nextOrdinal!==to||from>=to)return state;let floor=Math.max(from,maxOrdinal(state)+1);return floor<state.nextOrdinal?{...state,nextOrdinal:floor}:state}function diffTabs(prev,next){if(prev===null)return[{op:"seed",state:next}];let ops=[],prevById=new Map(prev.tabs.map((t)=>[t.id,t])),nextIds=new Set(next.tabs.map((t)=>t.id));for(let row of prev.tabs){let reopen=next.tabs.length===0&&next.reopenAs!==void 0?{reopenAs:next.reopenAs}:{};if(!nextIds.has(row.id))ops.push({op:"close",id:row.id,...reopen})}next.tabs.forEach((row,i)=>{let before=prevById.get(row.id);if(!before){ops.push({op:"open",row,after:i===0?null:next.tabs[i-1]?.id??null});return}if(before===row)return;let set={},unset=[];for(let[key,value]of Object.entries(row))if(key!=="id"&&key!=="ordinal"&&!sameValue(before[key],value))set[key]=value;for(let key of Object.keys(before))if(!(key in row))unset.push(key);if(Object.keys(set).length>0||unset.length>0)ops.push({op:"patch",id:row.id,...Object.keys(set).length>0?{set}:{},...unset.length>0?{unset}:{}})});let kept=next.tabs.filter((t)=>prevById.has(t.id)).map((t)=>t.id),prevKept=prev.tabs.filter((t)=>nextIds.has(t.id)).map((t)=>t.id);if(kept.some((id,i)=>id!==prevKept[i]))ops.push({op:"order",ids:next.tabs.map((t)=>t.id)});if(!sameValue(prev.reopenAs,next.reopenAs)&&next.tabs.length>0)ops.push({op:"meta",reopenAs:next.reopenAs});return ops}
|
|
3
|
+
export{engineCommandKey,engineNameKey,engineDisplayName,humanizeSlug,engineRenamedFrom,defaultEngineCommand,interactiveEngineCommand,roveApiInvocation,pickUnclaimedSessionId,GENERIC_PROTOCOL,ENGINE_PROTOCOLS,engineProtocolKey,getEngineProtocol,listPresetIds,describePreset,listEnginePresets,resolveCommandProtocol,engineLaunchArgv,sessionProtocol,protocolEntry,withPinnedSessionId,engineResumeArgv,engineCanFork,engineForkArgv,applyTabOps,reserveOrdinals,releaseOrdinals,diffTabs};
|