@sma1lboy/rove 0.9.204 → 0.9.206
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-00k1523r.js +8 -0
- package/dist/cli/{chunk-055hmbbv.js → chunk-018378sh.js} +3 -3
- package/dist/cli/chunk-03prm12e.js +2 -0
- package/dist/cli/{chunk-0q8pcjgw.js → chunk-07nn1ab2.js} +1 -1
- package/dist/cli/chunk-0m9b3mpe.js +2 -0
- package/dist/cli/{chunk-mkc6rmcn.js → chunk-0ra81t6k.js} +1 -1
- package/dist/cli/chunk-0zcr89a6.js +4 -0
- package/dist/cli/{chunk-bea5j9gq.js → chunk-1egpgqfv.js} +3 -3
- package/dist/cli/{chunk-1kv9w7xe.js → chunk-23kja9zv.js} +1 -1
- package/dist/cli/chunk-28430c3s.js +5 -0
- package/dist/cli/{chunk-2vtps463.js → chunk-2c4acn6h.js} +2 -2
- package/dist/cli/{chunk-y6xptp71.js → chunk-2pv36cqe.js} +1 -1
- package/dist/cli/{chunk-h3y0npdb.js → chunk-2qgs5apg.js} +1 -1
- package/dist/cli/{chunk-1zsdsvvb.js → chunk-2zezgeh8.js} +1 -1
- package/dist/cli/{chunk-kr5xvfjf.js → chunk-2zmkxegq.js} +1 -1
- package/dist/cli/{chunk-cc66fxva.js → chunk-382dy4yn.js} +1 -1
- package/dist/cli/{chunk-hagvh4x1.js → chunk-3e7sa63g.js} +1 -1
- package/dist/cli/{chunk-pe3sfy2w.js → chunk-3kr76178.js} +3 -3
- package/dist/cli/{chunk-10r5p67t.js → chunk-3n8kzdwy.js} +1 -1
- package/dist/cli/chunk-3trm92y6.js +5 -0
- package/dist/cli/{chunk-ba0ygf1w.js → chunk-401a3x2y.js} +1 -1
- package/dist/cli/{chunk-5gsgv4kv.js → chunk-4fdpg04x.js} +1 -1
- package/dist/cli/{chunk-b71td6yh.js → chunk-4sxf8gam.js} +2 -2
- package/dist/cli/{chunk-fgn4qk9p.js → chunk-58k4dd30.js} +1 -1
- package/dist/cli/{chunk-mnqxgvyb.js → chunk-5ysn2pzt.js} +1 -1
- package/dist/cli/{chunk-qm3x7d6f.js → chunk-6ynwn2d2.js} +1 -1
- package/dist/cli/{chunk-wahj6696.js → chunk-75p0wzqc.js} +2 -2
- package/dist/cli/{chunk-p08g04w4.js → chunk-77hqdh31.js} +1 -1
- package/dist/cli/{chunk-bq9shn2d.js → chunk-7g48tbk2.js} +1 -1
- package/dist/cli/{chunk-8bbmdkz8.js → chunk-878tdxt2.js} +1 -1
- package/dist/cli/{chunk-46kxbsdm.js → chunk-8k625ztz.js} +14 -5
- package/dist/cli/{chunk-sd7xdnr0.js → chunk-94ympa4z.js} +1 -1
- package/dist/cli/{chunk-qyh2sf97.js → chunk-9pb9mjem.js} +2 -2
- package/dist/cli/{chunk-v8e24gbf.js → chunk-ad37b8qf.js} +1 -1
- package/dist/cli/{chunk-g076r59t.js → chunk-b0z6s0w6.js} +1 -1
- package/dist/cli/{chunk-6kqbfc0n.js → chunk-b2zjabv6.js} +1 -1
- package/dist/cli/{chunk-8zerm1yt.js → chunk-bgp4msba.js} +2 -2
- package/dist/cli/{chunk-rrymnz5z.js → chunk-cy5rkf7y.js} +1 -1
- package/dist/cli/{chunk-7286gtss.js → chunk-d2e1991k.js} +1 -1
- package/dist/cli/{chunk-7d54wzap.js → chunk-djay2pg0.js} +1 -1
- package/dist/cli/{chunk-39ak805c.js → chunk-dthn9z4w.js} +1 -1
- package/dist/cli/chunk-e6jqk80f.js +3 -0
- package/dist/cli/{chunk-cckrwr2v.js → chunk-egn8kp0g.js} +1 -1
- package/dist/cli/{chunk-8nw96qrm.js → chunk-fw3ry6ej.js} +1 -1
- package/dist/cli/{chunk-6tqg80qs.js → chunk-gjs8919n.js} +1 -1
- package/dist/cli/{chunk-gmy7cw0c.js → chunk-jpc974e5.js} +1 -1
- package/dist/cli/{chunk-5p5saavr.js → chunk-jy5jemha.js} +1 -1
- package/dist/cli/chunk-k0gvapp4.js +2 -0
- package/dist/cli/{chunk-me2vvqpe.js → chunk-k7t5dkhg.js} +1 -1
- package/dist/cli/{chunk-rxpbxrqp.js → chunk-kfnqws7s.js} +1 -1
- package/dist/cli/{chunk-p9es0m6n.js → chunk-kqvqtw69.js} +22 -21
- package/dist/cli/{chunk-ch7sta42.js → chunk-ktnqe29b.js} +1 -1
- package/dist/cli/{chunk-bh6mcf55.js → chunk-mq572mj3.js} +1 -1
- package/dist/cli/chunk-mtaqg8p9.js +3 -0
- package/dist/cli/{chunk-9fc0j6ng.js → chunk-mtkd49cn.js} +1 -1
- package/dist/cli/{chunk-xd9kw4hh.js → chunk-n5n3y9rb.js} +1 -1
- package/dist/cli/{chunk-8kpxyqjx.js → chunk-p1v74v3r.js} +1 -1
- package/dist/cli/{chunk-xa1rtnhk.js → chunk-pzv1w1g7.js} +1 -1
- package/dist/cli/{chunk-tm7sb32d.js → chunk-q1nj5rzk.js} +1 -1
- package/dist/cli/{chunk-re5ke4fz.js → chunk-qrmcta3a.js} +1 -1
- package/dist/cli/{chunk-ps4xfv9k.js → chunk-r2hnt9vz.js} +2 -2
- package/dist/cli/chunk-rgw6ddre.js +2 -0
- package/dist/cli/{chunk-107fmq07.js → chunk-rxr3ph8g.js} +5 -5
- package/dist/cli/{chunk-965jm56m.js → chunk-scx2qchs.js} +1 -1
- package/dist/cli/{chunk-9nv53s3m.js → chunk-sma2adev.js} +1 -1
- package/dist/cli/{chunk-nkembqfr.js → chunk-ss5fda1x.js} +1 -1
- package/dist/cli/{chunk-s9qcp61a.js → chunk-sx8qg4ez.js} +1 -1
- package/dist/cli/{chunk-qd0b1cv4.js → chunk-t8qqwqve.js} +1 -1
- package/dist/cli/{chunk-yebr932a.js → chunk-tshpk67m.js} +1 -1
- package/dist/cli/{chunk-z7c6nap0.js → chunk-w6fbdxg2.js} +2 -2
- package/dist/cli/chunk-xbmj1a8w.js +5 -0
- package/dist/cli/{chunk-3aabx1rd.js → chunk-xdz4adem.js} +1 -1
- package/dist/cli/chunk-xtjw8vfj.js +3 -0
- package/dist/cli/chunk-xxfjm39n.js +2 -0
- package/dist/cli/chunk-y83efjyh.js +4 -0
- package/dist/cli/chunk-y8srv2kd.js +3 -0
- package/dist/cli/{chunk-thrvgwbk.js → chunk-ykxmf42d.js} +1 -1
- package/dist/cli/{chunk-xcxgac4t.js → chunk-z05k9zk3.js} +2 -2
- package/dist/cli/chunk-z10thenb.js +3 -0
- package/dist/cli/index.js +3 -3
- package/dist/cli/kobe.js +1 -1
- package/dist/cli/pty-host-node.mjs +2 -1
- package/dist/cli/rove.js +1 -1
- package/dist/completions/kobe.bash +1 -1
- package/dist/completions/kobe.fish +1 -1
- package/dist/completions/kobe.zsh +1 -1
- package/dist/completions/rove.bash +1 -1
- package/dist/completions/rove.fish +1 -1
- package/dist/completions/rove.zsh +1 -1
- package/dist/skills/rove/SKILL.md +1 -1
- package/dist/skills/rove/references/api-flags.md +1 -0
- package/package.json +1 -1
- package/dist/cli/chunk-0ks58ddm.js +0 -4
- package/dist/cli/chunk-153e8g4p.js +0 -4
- package/dist/cli/chunk-4drqykd5.js +0 -8
- package/dist/cli/chunk-633j3g6j.js +0 -2
- package/dist/cli/chunk-9xkc34rf.js +0 -3
- package/dist/cli/chunk-aep7gvh4.js +0 -3
- package/dist/cli/chunk-agw0gz3e.js +0 -4
- package/dist/cli/chunk-aydz15es.js +0 -3
- package/dist/cli/chunk-c1qt6xpr.js +0 -2
- package/dist/cli/chunk-cykd6rkx.js +0 -3
- package/dist/cli/chunk-ja2kd7gc.js +0 -2
- package/dist/cli/chunk-my20q579.js +0 -3
- package/dist/cli/chunk-r1sh08tf.js +0 -5
- package/dist/cli/chunk-ta0bgf5z.js +0 -3
- package/dist/cli/chunk-v3sapafp.js +0 -2
|
@@ -4,4 +4,4 @@ import{expandTilde}from"./chunk-fczqwtmq.js";import{SUBCOMMAND_VERBS}from"./chun
|
|
|
4
4
|
|
|
5
5
|
${REPO_USAGE}
|
|
6
6
|
`),process.exit(2)}function readArgFile(path){try{return readFileSync(resolve(process.cwd(),expandTilde(path)),"utf8")}catch(err){usageError(`cannot read ${path}: ${errorMessage(err)}`)}}function parseRepoArgs(args){let out={};for(let i=0;i<args.length;i++){let a=args[i],need=()=>{let v=args[++i];if(v===void 0)usageError(`${a} requires a value`);return v};if(a==="--init-script")out.initScript=need();else if(a==="--init-script-file")out.initScript=readArgFile(need());else if(a==="--init-prompt")out.initPrompt=need();else if(a==="--init-prompt-file")out.initPrompt=readArgFile(need());else if(a.startsWith("-"))usageError(`unknown flag "${a}"`);else if(out.path===void 0)out.path=a;else usageError(`unexpected argument "${a}"`)}return out}function parseUnsetArgs(args){let path,clearScript=!1,clearPrompt=!1;for(let a of args)if(a==="--init-script")clearScript=!0;else if(a==="--init-prompt")clearPrompt=!0;else if(a.startsWith("-"))usageError(`unknown flag "${a}"`);else if(path===void 0)path=a;else usageError(`unexpected argument "${a}"`);if(!clearScript&&!clearPrompt)clearScript=!0,clearPrompt=!0;return{path,clearScript,clearPrompt}}async function runRepoSubcommand(args){let[verb,...rest]=args;if(verb===void 0||verb==="--help"||verb==="-h"||verb==="help"){process.stdout.write(`${REPO_USAGE}
|
|
7
|
-
`);return}if(!SUBCOMMAND_VERBS.repo.includes(verb))usageError(`unknown verb "${verb}"`);let{getRepoInitOverride,setRepoInitOverride,resolveRepoRoot}=await import("./chunk-4er2k3kp.js");if(verb==="show"){let[pathArg]=rest.filter((a)=>!a.startsWith("-")),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(pathArg??"."))),override=getRepoInitOverride(repo),{describeRepoInitSources}=await import("./chunk-
|
|
7
|
+
`);return}if(!SUBCOMMAND_VERBS.repo.includes(verb))usageError(`unknown verb "${verb}"`);let{getRepoInitOverride,setRepoInitOverride,resolveRepoRoot}=await import("./chunk-4er2k3kp.js");if(verb==="show"){let[pathArg]=rest.filter((a)=>!a.startsWith("-")),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(pathArg??"."))),override=getRepoInitOverride(repo),{describeRepoInitSources}=await import("./chunk-878tdxt2.js"),sources=describeRepoInitSources(repo);console.log(`repo: ${repo}`);for(let group of[sources.script,sources.prompt])group.forEach((source,index)=>{console.log(` ${`${source.rel}:`.padEnd(22)}${describeSource(group,index)}`)});console.log(` override initScript: ${override.initScript?quotePreview(override.initScript):"(unset)"}`),console.log(` override initPrompt: ${override.initPrompt?quotePreview(override.initPrompt):"(unset)"}`);return}if(verb==="set"){let flags=parseRepoArgs(rest);if(flags.initScript===void 0&&flags.initPrompt===void 0)usageError("set needs at least one of --init-script(-file) / --init-prompt(-file)");let repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(flags.path??"."))),next=setRepoInitOverride(repo,{...flags.initScript!==void 0?{initScript:flags.initScript}:{},...flags.initPrompt!==void 0?{initPrompt:flags.initPrompt}:{}});console.log(`updated override for ${repo}`),console.log(` initScript: ${next.initScript?quotePreview(next.initScript):"(unset)"}`),console.log(` initPrompt: ${next.initPrompt?quotePreview(next.initPrompt):"(unset)"}`);return}if(verb==="unset"){let{path,clearScript,clearPrompt}=parseUnsetArgs(rest),repo=resolveRepoRoot(resolve(process.cwd(),expandTilde(path??"."))),next=setRepoInitOverride(repo,{...clearScript?{initScript:""}:{},...clearPrompt?{initPrompt:""}:{}});console.log(`cleared override for ${repo}`),console.log(` initScript: ${next.initScript?quotePreview(next.initScript):"(unset)"}`),console.log(` initPrompt: ${next.initPrompt?quotePreview(next.initPrompt):"(unset)"}`);return}usageError(`unknown verb "${verb}"`)}function describeSource(group,index){let source=group[index];if(!source)return"absent";if(source.effective)return"present (wins)";if(!source.present)return"absent";return group.slice(0,index).some((earlier)=>earlier.effective)?"present (shadowed)":"present but empty (ignored)"}function quotePreview(value){let oneLine=value.replace(/\s+/g," ").trim();return oneLine.length>60?`"${oneLine.slice(0,57)}\u2026"`:`"${oneLine}"`}export{runRepoSubcommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{currentLang,intlLocale,localeState,setLocaleLang,t,tKeys}from"./chunk-
|
|
2
|
+
import{currentLang,intlLocale,localeState,setLocaleLang,t,tKeys}from"./chunk-cy5rkf7y.js";import"./chunk-xtjw8vfj.js";import"./chunk-sdyzxayr.js";import"./chunk-wqfp8d9w.js";export{tKeys,t,setLocaleLang,localeState,intlLocale,currentLang};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{sameWorktreeChanges}from"./chunk-k6nxyxyh.js";import{ensureDaemonReachable,isStaleInstallError}from"./chunk-scx2qchs.js";import{DAEMON_PROTOCOL_VERSION,MIN_COMPATIBLE_PROTOCOL_VERSION,isAttentionInboxState,isDaemonVersionStale,isForeignDaemonHome,isProtocolCompatible,parseDaemonStopReason}from"./chunk-qrmcta3a.js";import{createStateCell,mapReadableState}from"./chunk-sdyzxayr.js";import{CURRENT_VERSION}from"./chunk-3n8kzdwy.js";import{toTaskId}from"./chunk-xy8be792.js";import{logClient,logClientError}from"./chunk-3es6spp4.js";import{homeDir}from"./chunk-q5jhy3t8.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 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,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:"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,groupId:s.groupId,observedLanguage:s.observedLanguage,deletion:s.deletion,quotaResume:s.quotaResume,linkedWorkItem:s.linkedWorkItem,dispatcher:s.dispatcher,prompt:s.prompt,baseRef:s.baseRef,worktreeName:s.worktreeName,report:s.report,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 / KOBE_DAEMON_SOCKET_PATH before starting it.`);if(signals.setDaemonVersionSig(typeof hello.kobeVersion==="string"?hello.kobeVersion: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,kobeVersion:typeof hello.kobeVersion==="string"?hello.kobeVersion:""}),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 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?.kobeVersion==="string")signals.setDaemonVersionSig(p.kobeVersion);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&&p.state==="routine_failed")&&(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==="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(name==="usage.snapshot"){let next=parseUsageSnapshotPayload(payload);if(!next){logClientError("orch",`dropped usage.snapshot event: malformed usage payload (${describePayload(payload)})`);return}let current=signals.usageSnapshotAcc();if(current&&sameUsageSnapshotMap(current,next))return;signals.setUsageSnapshotSig(next);return}if(name==="usage.context"){let next=parseContextUsagePayload(payload);if(!next){logClientError("orch",`dropped usage.context event: malformed context payload (${describePayload(payload)})`);return}let current=signals.contextUsageAcc();if(current&&sameContextUsageMap(current,next))return;signals.setContextUsageSig(next);return}if(name==="worktree.changes"){let next=parseWorktreeChangesPayload(payload);if(!next){logClientError("orch",`dropped worktree.changes event: malformed changes payload (${describePayload(payload)})`);return}let current=signals.worktreeChangesAcc();if(current&&sameWorktreeChangesMap(current,next))return;signals.setWorktreeChangesSig(next);return}if(name==="transcript.activity"){let next=parseTranscriptActivityPayload(payload);if(!next){logClientError("orch",`dropped transcript.activity event: malformed activity payload (${describePayload(payload)})`);return}let current=signals.transcriptActivityAcc();if(current&&sameTranscriptActivityMap(current,next))return;signals.setTranscriptActivitySig(next);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==="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)}})}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){await client.request("task.setVendor",{taskId:String(id),vendor,...effort!==void 0?{effort}:{}})}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 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){return(await client.request("attention.dismiss",{taskId:String(taskId),...tabId!==null?{tabId}:{},at})).deleted}async function dismissRoutineAttentionOp(client,automationId){return(await client.request("attention.dismissRoutine",{automationId})).deleted}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 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(()=>{})}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([]);taskJobsAcc=createStateCell(new Map);worktreeChangesAcc=createStateCell(null);usageSnapshotAcc=createStateCell(null);contextUsageAcc=createStateCell(null);transcriptActivityAcc=createStateCell(null);noticeAcc=createStateCell(null);tabOpenAcc=createStateCell(null);tabCloseAcc=createStateCell(null);tabRenameAcc=createStateCell(null);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.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,taskJobsAcc:this.taskJobsAcc,setTaskJobsSig:this.taskJobsAcc.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,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}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;taskJobsSignal=()=>this.taskJobsAcc;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;rpc={request:(name,payload)=>this.client.request(name,payload)};replyTerminalTabClose=(requestId,closed)=>replyTabCloseOp(this.client,requestId,closed);uiPromptStore=()=>this.uiPromptAcc;replyPrompt=(promptId,value)=>void this.client.request("ui.promptReply",{promptId,...value!==void 0?{value}:{}}).catch(()=>{});engineLifecycleSignal=()=>this.engineLifecycleAcc;recentTaskEvents(id){return this.client.request("task.recentEvents",{taskId:String(id)})}reportUiEvent=(kind,taskId,detail)=>void this.client.request("ui.reportEvent",{kind,...taskId?{taskId}:{},...detail?{detail}:{}}).catch(()=>{});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)=>setVendorOp(this.client,id,vendor,effort);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);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)=>dismissAttentionOp(this.client,taskId,tabId,at);dismissRoutineAttention=(automationId)=>dismissRoutineAttentionOp(this.client,automationId);markAttentionRead=(taskId,tabId,at)=>markAttentionReadOp(this.client,taskId,tabId,at);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);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
|
+
export{RemoteOrchestrator};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{serialized,writeJsonAtomic}from"./chunk-xsrcwcjc.js";import{loadPluginRegistry,pluginConfigDir,pluginDataDir,pluginLogPath,pluginRegistryPath,pluginStateDir,pluginsRootDir}from"./chunk-bq9shn2d.js";import{logDaemonError}from"./chunk-rcyasw34.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE}from"./chunk-9prawccj.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import{chmodSync}from"fs";function tighten(path,mode){try{chmodSync(path,mode)}catch{}}function tightenPluginPermissions(id,homeDir){tighten(pluginDataDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginConfigDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginStateDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(`${pluginConfigDir(id,homeDir)}/.env`,OWNER_ONLY_FILE_MODE),tighten(pluginLogPath(id,homeDir),OWNER_ONLY_FILE_MODE)}function tightenInstalledPluginPermissions(homeDir){tighten(pluginsRootDir(homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginRegistryPath(homeDir),OWNER_ONLY_FILE_MODE);for(let entry of loadPluginRegistry(homeDir).plugins)tightenPluginPermissions(entry.id,homeDir)}import{execFile as execFile2}from"child_process";import{readFile}from"fs/promises";import{homedir}from"os";import{join,resolve as resolve2}from"path";import{promisify as promisify2}from"util";import{execFile}from"child_process";import{realpath,stat}from"fs/promises";import{isAbsolute,resolve}from"path";import{promisify}from"util";var execFileAsync=promisify(execFile);async function gitCommonDir(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--git-common-dir"]),dir=stdout.trim();return realpath(isAbsolute(dir)?dir:resolve(path,dir))}async function gitMainWorktree(path){let{stdout}=await execFileAsync("git",["-C",path,"worktree","list","--porcelain"]),first=stdout.split(/\r?\n/).find((line)=>line.startsWith("worktree "))?.slice(9).trim();return first?await realpath(first):null}async function gitTopLevel(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--show-toplevel"]);return stdout.trim()}async function resolveRepoRoot(raw){let absolute=resolve(raw);if(!(await stat(absolute).catch(()=>null))?.isDirectory())throw Error("repoRoot does not exist");let[repoRoot,repoKey]=await Promise.all([gitMainWorktree(absolute),gitCommonDir(absolute)]);return{repoRoot,repoKey}}var execFileAsync2=promisify2(execFile2),ISSUE_STATUSES=["open","doing","hold","done"],ISSUE_NOT_FOUND_CODE="ISSUE_NOT_FOUND",ISSUE_STORE_UNREADABLE_CODE="ISSUE_STORE_UNREADABLE";function isGitNotRepositoryError(err){return(err instanceof Error?err.message:String(err)).includes("not a git repository")}function defaultIssuesStorePath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"issues.json")}function isValidStatus(value){return typeof value==="string"&&ISSUE_STATUSES.includes(value)}function normalizeIssue(entry){if(entry===null||typeof entry!=="object"||Array.isArray(entry))return null;let raw=entry;if(typeof raw.id!=="number")return null;return{id:raw.id,title:typeof raw.title==="string"?raw.title:"(untitled)",status:isValidStatus(raw.status)?raw.status:"open",created:typeof raw.created==="string"?raw.created:"",body:typeof raw.body==="string"?raw.body:"",taskId:typeof raw.taskId==="string"?raw.taskId:void 0}}function emptyStore(){return{version:1,repos:{}}}function nextIdFallback(entries){let max=0;for(let entry of entries){let id=Number(entry?.id);if(Number.isFinite(id)&&id>max)max=Math.trunc(id)}return max+1}function todayStamp(){let pinned=process.env.KOBE_ISSUES_TODAY;if(pinned&&/^\d{4}-\d{2}-\d{2}$/.test(pinned))return pinned;let d=new Date,mm=String(d.getMonth()+1).padStart(2,"0"),dd=String(d.getDate()).padStart(2,"0");return`${d.getFullYear()}-${mm}-${dd}`}async function resolveRepo(raw){if(typeof raw!=="string"||raw.length===0)throw Error("repoRoot is required");try{let{repoRoot,repoKey}=await resolveRepoRoot(raw);return{repoRoot:repoRoot??await gitTopLevel(resolve2(raw)),repoKey}}catch(err){if(isGitNotRepositoryError(err))throw Error("repoRoot is not a git repository");throw err}}function unreadableCount(raw){if(raw!==null&&typeof raw==="object"&&!Array.isArray(raw))return Math.max(1,Object.keys(raw).length);return 1}function readRecord(value){let record=value,base={repoRoot:typeof record.repoRoot==="string"?record.repoRoot:"",nextId:typeof record.nextId==="number"?record.nextId:1};if(record.issues!==void 0&&!Array.isArray(record.issues))return{record:{...base,issues:[],unusable:[],unreadable:{raw:value}},dropped:unreadableCount(record.issues)};let entries=Array.isArray(record.issues)?record.issues:[],issues=entries.map(normalizeIssue).filter((issue)=>issue!==null),unusable=entries.filter((entry)=>normalizeIssue(entry)===null);return{record:{repoRoot:base.repoRoot,nextId:typeof record.nextId==="number"?record.nextId:nextIdFallback(entries),issues,unusable},dropped:unusable.length}}async function readStore(path){try{let raw=JSON.parse(await readFile(path,"utf8")),repos={},skipped=new Map;if(raw.repos&&typeof raw.repos==="object")for(let[key,value]of Object.entries(raw.repos)){if(!value||typeof value!=="object")continue;let{record,dropped}=readRecord(value);if(dropped>0){skipped.set(key,dropped);let why=record.unreadable?'"issues" is not an array':"id is not a number";logDaemonError("issues-store-read",Error(`${key}: dropped ${dropped} unreadable issue entr${dropped===1?"y":"ies"} (${why})`))}repos[key]=record}return{file:{version:1,repos},skipped}}catch(err){if(err.code==="ENOENT")return{file:emptyStore(),skipped:new Map};throw Error(`${path}: ${err instanceof Error?err.message:String(err)}`)}}function serializeRecord(record){if(record.unreadable)return record.unreadable.raw;return{repoRoot:record.repoRoot,nextId:record.nextId,issues:[...record.issues,...record.unusable]}}async function writeStore(path,store){let repos={};for(let[key,record]of Object.entries(store.repos))repos[key]=serializeRecord(record);await writeJsonAtomic(path,{version:store.version,repos})}function response(repoRoot,record,skipped=0){return{repoRoot,exists:record!==null,nextId:record?.nextId??1,issues:record?.issues??[],skipped}}class IssuesStore{path;constructor(path=defaultIssuesStorePath()){this.path=path}async list(repo){let{repoRoot,repoKey}=await resolveRepo(repo);return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey]??null;if(record&&!record.unreadable&&record.repoRoot!==repoRoot)record.repoRoot=repoRoot,await writeStore(this.path,store);return response(repoRoot,record,skipped.get(repoKey)??0)})}async repos(){return serialized(this.path,async()=>{let{file}=await readStore(this.path);return Object.values(file.repos).map((record)=>record.repoRoot).filter((root)=>root.length>0)})}async mirrorTaskDone(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue||issue.status==="done")return null;return issue.status="done",record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async unlinkTask(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue)return null;return issue.taskId=void 0,record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async mutate(repo,op){let{repoRoot,repoKey}=await resolveRepo(repo);if(!op||typeof op!=="object"||Array.isArray(op)||typeof op.type!=="string")throw Error("missing op");return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)record={repoRoot,nextId:1,issues:[],unusable:[]},store.repos[repoKey]=record;if(record.unreadable)throw Error(`${ISSUE_STORE_UNREADABLE_CODE}: ${repoRoot}'s record in ${this.path} has a non-array "issues" \u2014 refusing to write over stories this build cannot read`);record.repoRoot=repoRoot;let typed=op;if(typed.type==="create"){if(typeof typed.title!=="string"||typed.title.trim().length===0)throw Error("create requires a non-empty title");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");record.issues=[{id:record.nextId,title:typed.title,status:"open",created:todayStamp(),body:typeof typed.body==="string"?typed.body:""},...record.issues],record.nextId+=1}else if(typed.type==="setStatus"){if(typeof typed.id!=="number")throw Error("setStatus requires a numeric id");if(!isValidStatus(typed.status))throw Error(`invalid status: must be one of ${ISSUE_STATUSES.join(", ")}`);let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.status=typed.status}else if(typed.type==="update"){if(typeof typed.id!=="number")throw Error("update requires a numeric id");if(typed.title!==void 0&&(typeof typed.title!=="string"||typed.title.trim().length===0))throw Error("title must be a non-empty string");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");if(typed.taskId!==void 0&&typed.taskId!==null&&(typeof typed.taskId!=="string"||typed.taskId.length===0))throw Error("taskId must be a non-empty string or null");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);if(typeof typed.title==="string")issue.title=typed.title;if(typeof typed.body==="string")issue.body=typed.body;if(typed.taskId!==void 0)issue.taskId=typed.taskId===null?void 0:typed.taskId}else if(typed.type==="link"){if(typeof typed.id!=="number")throw Error("link requires a numeric id");if(typeof typed.taskId!=="string"||typed.taskId.length===0)throw Error("link requires a non-empty taskId");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=typed.taskId}else if(typed.type==="unlink"){if(typeof typed.id!=="number")throw Error("unlink requires a numeric id");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=void 0}else if(typed.type==="delete"){if(typeof typed.id!=="number")throw Error("delete requires a numeric id");let nextIssues=record.issues.filter((i)=>i.id!==typed.id);if(nextIssues.length===record.issues.length)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);record.issues=nextIssues}else throw Error(`unknown op type: ${typed.type}`);return await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}}var MONTH_NAMES=new Map([["JAN",1],["FEB",2],["MAR",3],["APR",4],["MAY",5],["JUN",6],["JUL",7],["AUG",8],["SEP",9],["OCT",10],["NOV",11],["DEC",12]]),DAY_NAMES=new Map([["SUN",0],["MON",1],["TUE",2],["WED",3],["THU",4],["FRI",5],["SAT",6]]);function fieldNumber(raw,names,field){let token=raw.toUpperCase(),named=names?.get(token);if(named!==void 0)return named;if(!/^\d+$/.test(token))throw Error(`invalid cron ${field}: ${raw}`);return Number(token)}function parseField(args){let out=new Set;for(let part of args.value.split(",")){if(part.length===0)throw Error(`invalid cron ${args.field}: ${args.value}`);let[spec,stepRaw,...extra]=part.split("/");if(extra.length>0||spec===void 0)throw Error(`invalid cron ${args.field}: ${part}`);let step=1;if(stepRaw!==void 0){if(!/^\d+$/.test(stepRaw))throw Error(`invalid cron ${args.field} step: ${part}`);if(step=Number(stepRaw),step<1)throw Error(`invalid cron ${args.field} step: ${part}`)}let lo,hi;if(spec==="*")lo=args.min,hi=args.max;else if(spec.includes("-")){let[loRaw,hiRaw,...rest]=spec.split("-");if(rest.length>0||loRaw===void 0||hiRaw===void 0)throw Error(`invalid cron ${args.field} range: ${part}`);lo=fieldNumber(loRaw,args.names,args.field),hi=fieldNumber(hiRaw,args.names,args.field)}else lo=fieldNumber(spec,args.names,args.field),hi=stepRaw===void 0?lo:args.max;if(lo<args.min||hi>args.max||lo>hi)throw Error(`cron ${args.field} out of range: ${part}`);for(let v=lo;v<=hi;v+=step)out.add(args.normalize?args.normalize(v):v)}return out}function parseCron(expression){if(expression.length>256)throw Error("cron expression is too long");let fields=expression.trim().split(/\s+/).filter(Boolean);if(fields.length!==5)throw Error(`cron expression needs 5 fields (minute hour day month weekday), got ${fields.length}`);let[minute,hour,dayOfMonth,month,dayOfWeek]=fields;return{minutes:parseField({value:minute,min:0,max:59,field:"minute"}),hours:parseField({value:hour,min:0,max:23,field:"hour"}),daysOfMonth:parseField({value:dayOfMonth,min:1,max:31,field:"day-of-month"}),months:parseField({value:month,min:1,max:12,field:"month",names:MONTH_NAMES}),daysOfWeek:parseField({value:dayOfWeek,min:0,max:7,field:"weekday",names:DAY_NAMES,normalize:(v)=>v%7}),dayOfMonthRestricted:dayOfMonth!=="*",dayOfWeekRestricted:dayOfWeek!=="*"}}function isValidCron(expression){try{return parseCron(expression),!0}catch{return!1}}function instantOf(d,hour,minute){return new Date(d.year,d.month-1,d.day,hour,minute,0,0).getTime()}function localDayOf(ms){let d=new Date(ms);return{year:d.getFullYear(),month:d.getMonth()+1,day:d.getDate()}}function shiftDay(d,delta){return localDayOf(new Date(d.year,d.month-1,d.day+delta,12,0,0,0).getTime())}function dayMatches(rule,d){if(!rule.months.has(d.month))return!1;let domMatch=rule.daysOfMonth.has(d.day),dowMatch=rule.daysOfWeek.has(new Date(d.year,d.month-1,d.day).getDay());if(rule.dayOfMonthRestricted&&rule.dayOfWeekRestricted)return domMatch||dowMatch;if(rule.dayOfMonthRestricted)return domMatch;if(rule.dayOfWeekRestricted)return dowMatch;return!0}function floorToMinute(ms){return ms-ms%60000}function sorted(values,direction){return[...values].sort((a,b)=>(a-b)*direction)}function nextCronAfter(expression,afterMs){let rule=parseCron(expression),hours=sorted(rule.hours,1),minutes=sorted(rule.minutes,1),from=new Date(floorToMinute(afterMs)+60000),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(dayMatches(rule,day))for(let hour of hours){if(hour<fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute<fromMinute)continue;let at=instantOf(day,hour,minute);if(at>afterMs)return at}}day=shiftDay(day,1),fromHour=0,fromMinute=0}throw Error(`cron expression never matches: ${expression}`)}function latestCronAtOrBefore(expression,nowMs,notBeforeMs){if(nowMs<notBeforeMs)return null;let rule=parseCron(expression),hours=sorted(rule.hours,-1),minutes=sorted(rule.minutes,-1),from=new Date(floorToMinute(nowMs)),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(instantOf(day,23,59)<notBeforeMs)return null;if(dayMatches(rule,day))for(let hour of hours){if(hour>fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute>fromMinute)continue;let at=instantOf(day,hour,minute);if(at>nowMs)continue;return at>=notBeforeMs?at:null}}day=shiftDay(day,-1),fromHour=23,fromMinute=59}return null}function countCronBetween(expression,fromMs,beforeMs,cap=500){if(!(fromMs<beforeMs))return 0;let count=0,cursor=fromMs-1;while(count<cap){let at;try{at=nextCronAfter(expression,cursor)}catch{return count}if(at>=beforeMs)return count;count+=1,cursor=at}return count}
|
|
2
|
+
import{serialized,writeJsonAtomic}from"./chunk-xsrcwcjc.js";import{loadPluginRegistry,pluginConfigDir,pluginDataDir,pluginLogPath,pluginRegistryPath,pluginStateDir,pluginsRootDir}from"./chunk-7g48tbk2.js";import{logDaemonError}from"./chunk-rcyasw34.js";import{OWNER_ONLY_DIR_MODE,OWNER_ONLY_FILE_MODE}from"./chunk-9prawccj.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-hq4b3fca.js";import{chmodSync}from"fs";function tighten(path,mode){try{chmodSync(path,mode)}catch{}}function tightenPluginPermissions(id,homeDir){tighten(pluginDataDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginConfigDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginStateDir(id,homeDir),OWNER_ONLY_DIR_MODE),tighten(`${pluginConfigDir(id,homeDir)}/.env`,OWNER_ONLY_FILE_MODE),tighten(pluginLogPath(id,homeDir),OWNER_ONLY_FILE_MODE)}function tightenInstalledPluginPermissions(homeDir){tighten(pluginsRootDir(homeDir),OWNER_ONLY_DIR_MODE),tighten(pluginRegistryPath(homeDir),OWNER_ONLY_FILE_MODE);for(let entry of loadPluginRegistry(homeDir).plugins)tightenPluginPermissions(entry.id,homeDir)}import{execFile as execFile2}from"child_process";import{readFile}from"fs/promises";import{homedir}from"os";import{join,resolve as resolve2}from"path";import{promisify as promisify2}from"util";import{execFile}from"child_process";import{realpath,stat}from"fs/promises";import{isAbsolute,resolve}from"path";import{promisify}from"util";var execFileAsync=promisify(execFile);async function gitCommonDir(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--git-common-dir"]),dir=stdout.trim();return realpath(isAbsolute(dir)?dir:resolve(path,dir))}async function gitMainWorktree(path){let{stdout}=await execFileAsync("git",["-C",path,"worktree","list","--porcelain"]),first=stdout.split(/\r?\n/).find((line)=>line.startsWith("worktree "))?.slice(9).trim();return first?await realpath(first):null}async function gitTopLevel(path){let{stdout}=await execFileAsync("git",["-C",path,"rev-parse","--show-toplevel"]);return stdout.trim()}async function resolveRepoRoot(raw){let absolute=resolve(raw);if(!(await stat(absolute).catch(()=>null))?.isDirectory())throw Error("repoRoot does not exist");let[repoRoot,repoKey]=await Promise.all([gitMainWorktree(absolute),gitCommonDir(absolute)]);return{repoRoot,repoKey}}var execFileAsync2=promisify2(execFile2),ISSUE_STATUSES=["open","doing","hold","done"],ISSUE_NOT_FOUND_CODE="ISSUE_NOT_FOUND",ISSUE_STORE_UNREADABLE_CODE="ISSUE_STORE_UNREADABLE";function isGitNotRepositoryError(err){return(err instanceof Error?err.message:String(err)).includes("not a git repository")}function defaultIssuesStorePath(homeDir=readRoveHomeDirEnv()??homedir()){return join(homeDir,ROVE_STATE_DIR_BASENAME,"issues.json")}function isValidStatus(value){return typeof value==="string"&&ISSUE_STATUSES.includes(value)}function normalizeIssue(entry){if(entry===null||typeof entry!=="object"||Array.isArray(entry))return null;let raw=entry;if(typeof raw.id!=="number")return null;return{id:raw.id,title:typeof raw.title==="string"?raw.title:"(untitled)",status:isValidStatus(raw.status)?raw.status:"open",created:typeof raw.created==="string"?raw.created:"",body:typeof raw.body==="string"?raw.body:"",taskId:typeof raw.taskId==="string"?raw.taskId:void 0}}function emptyStore(){return{version:1,repos:{}}}function nextIdFallback(entries){let max=0;for(let entry of entries){let id=Number(entry?.id);if(Number.isFinite(id)&&id>max)max=Math.trunc(id)}return max+1}function todayStamp(){let pinned=process.env.KOBE_ISSUES_TODAY;if(pinned&&/^\d{4}-\d{2}-\d{2}$/.test(pinned))return pinned;let d=new Date,mm=String(d.getMonth()+1).padStart(2,"0"),dd=String(d.getDate()).padStart(2,"0");return`${d.getFullYear()}-${mm}-${dd}`}async function resolveRepo(raw){if(typeof raw!=="string"||raw.length===0)throw Error("repoRoot is required");try{let{repoRoot,repoKey}=await resolveRepoRoot(raw);return{repoRoot:repoRoot??await gitTopLevel(resolve2(raw)),repoKey}}catch(err){if(isGitNotRepositoryError(err))throw Error("repoRoot is not a git repository");throw err}}function unreadableCount(raw){if(raw!==null&&typeof raw==="object"&&!Array.isArray(raw))return Math.max(1,Object.keys(raw).length);return 1}function readRecord(value){let record=value,base={repoRoot:typeof record.repoRoot==="string"?record.repoRoot:"",nextId:typeof record.nextId==="number"?record.nextId:1};if(record.issues!==void 0&&!Array.isArray(record.issues))return{record:{...base,issues:[],unusable:[],unreadable:{raw:value}},dropped:unreadableCount(record.issues)};let entries=Array.isArray(record.issues)?record.issues:[],issues=entries.map(normalizeIssue).filter((issue)=>issue!==null),unusable=entries.filter((entry)=>normalizeIssue(entry)===null);return{record:{repoRoot:base.repoRoot,nextId:typeof record.nextId==="number"?record.nextId:nextIdFallback(entries),issues,unusable},dropped:unusable.length}}async function readStore(path){try{let raw=JSON.parse(await readFile(path,"utf8")),repos={},skipped=new Map;if(raw.repos&&typeof raw.repos==="object")for(let[key,value]of Object.entries(raw.repos)){if(!value||typeof value!=="object")continue;let{record,dropped}=readRecord(value);if(dropped>0){skipped.set(key,dropped);let why=record.unreadable?'"issues" is not an array':"id is not a number";logDaemonError("issues-store-read",Error(`${key}: dropped ${dropped} unreadable issue entr${dropped===1?"y":"ies"} (${why})`))}repos[key]=record}return{file:{version:1,repos},skipped}}catch(err){if(err.code==="ENOENT")return{file:emptyStore(),skipped:new Map};throw Error(`${path}: ${err instanceof Error?err.message:String(err)}`)}}function serializeRecord(record){if(record.unreadable)return record.unreadable.raw;return{repoRoot:record.repoRoot,nextId:record.nextId,issues:[...record.issues,...record.unusable]}}async function writeStore(path,store){let repos={};for(let[key,record]of Object.entries(store.repos))repos[key]=serializeRecord(record);await writeJsonAtomic(path,{version:store.version,repos})}function response(repoRoot,record,skipped=0){return{repoRoot,exists:record!==null,nextId:record?.nextId??1,issues:record?.issues??[],skipped}}class IssuesStore{path;constructor(path=defaultIssuesStorePath()){this.path=path}async list(repo){let{repoRoot,repoKey}=await resolveRepo(repo);return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey]??null;if(record&&!record.unreadable&&record.repoRoot!==repoRoot)record.repoRoot=repoRoot,await writeStore(this.path,store);return response(repoRoot,record,skipped.get(repoKey)??0)})}async repos(){return serialized(this.path,async()=>{let{file}=await readStore(this.path);return Object.values(file.repos).map((record)=>record.repoRoot).filter((root)=>root.length>0)})}async mirrorTaskDone(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue||issue.status==="done")return null;return issue.status="done",record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async unlinkTask(repo,taskId){let{repoRoot,repoKey}=await resolveRepo(repo);if(!taskId)return null;return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)return null;let issue=record.issues.find((i)=>i.taskId===taskId);if(!issue)return null;return issue.taskId=void 0,record.repoRoot=repoRoot,await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}async mutate(repo,op){let{repoRoot,repoKey}=await resolveRepo(repo);if(!op||typeof op!=="object"||Array.isArray(op)||typeof op.type!=="string")throw Error("missing op");return serialized(this.path,async()=>{let{file:store,skipped}=await readStore(this.path),record=store.repos[repoKey];if(!record)record={repoRoot,nextId:1,issues:[],unusable:[]},store.repos[repoKey]=record;if(record.unreadable)throw Error(`${ISSUE_STORE_UNREADABLE_CODE}: ${repoRoot}'s record in ${this.path} has a non-array "issues" \u2014 refusing to write over stories this build cannot read`);record.repoRoot=repoRoot;let typed=op;if(typed.type==="create"){if(typeof typed.title!=="string"||typed.title.trim().length===0)throw Error("create requires a non-empty title");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");record.issues=[{id:record.nextId,title:typed.title,status:"open",created:todayStamp(),body:typeof typed.body==="string"?typed.body:""},...record.issues],record.nextId+=1}else if(typed.type==="setStatus"){if(typeof typed.id!=="number")throw Error("setStatus requires a numeric id");if(!isValidStatus(typed.status))throw Error(`invalid status: must be one of ${ISSUE_STATUSES.join(", ")}`);let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.status=typed.status}else if(typed.type==="update"){if(typeof typed.id!=="number")throw Error("update requires a numeric id");if(typed.title!==void 0&&(typeof typed.title!=="string"||typed.title.trim().length===0))throw Error("title must be a non-empty string");if(typed.body!==void 0&&typeof typed.body!=="string")throw Error("body must be a string");if(typed.taskId!==void 0&&typed.taskId!==null&&(typeof typed.taskId!=="string"||typed.taskId.length===0))throw Error("taskId must be a non-empty string or null");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);if(typeof typed.title==="string")issue.title=typed.title;if(typeof typed.body==="string")issue.body=typed.body;if(typed.taskId!==void 0)issue.taskId=typed.taskId===null?void 0:typed.taskId}else if(typed.type==="link"){if(typeof typed.id!=="number")throw Error("link requires a numeric id");if(typeof typed.taskId!=="string"||typed.taskId.length===0)throw Error("link requires a non-empty taskId");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=typed.taskId}else if(typed.type==="unlink"){if(typeof typed.id!=="number")throw Error("unlink requires a numeric id");let issue=record.issues.find((i)=>i.id===typed.id);if(!issue)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);issue.taskId=void 0}else if(typed.type==="delete"){if(typeof typed.id!=="number")throw Error("delete requires a numeric id");let nextIssues=record.issues.filter((i)=>i.id!==typed.id);if(nextIssues.length===record.issues.length)throw Error(`${ISSUE_NOT_FOUND_CODE}: no issue #${typed.id}`);record.issues=nextIssues}else throw Error(`unknown op type: ${typed.type}`);return await writeStore(this.path,store),response(repoRoot,record,skipped.get(repoKey)??0)})}}var MONTH_NAMES=new Map([["JAN",1],["FEB",2],["MAR",3],["APR",4],["MAY",5],["JUN",6],["JUL",7],["AUG",8],["SEP",9],["OCT",10],["NOV",11],["DEC",12]]),DAY_NAMES=new Map([["SUN",0],["MON",1],["TUE",2],["WED",3],["THU",4],["FRI",5],["SAT",6]]);function fieldNumber(raw,names,field){let token=raw.toUpperCase(),named=names?.get(token);if(named!==void 0)return named;if(!/^\d+$/.test(token))throw Error(`invalid cron ${field}: ${raw}`);return Number(token)}function parseField(args){let out=new Set;for(let part of args.value.split(",")){if(part.length===0)throw Error(`invalid cron ${args.field}: ${args.value}`);let[spec,stepRaw,...extra]=part.split("/");if(extra.length>0||spec===void 0)throw Error(`invalid cron ${args.field}: ${part}`);let step=1;if(stepRaw!==void 0){if(!/^\d+$/.test(stepRaw))throw Error(`invalid cron ${args.field} step: ${part}`);if(step=Number(stepRaw),step<1)throw Error(`invalid cron ${args.field} step: ${part}`)}let lo,hi;if(spec==="*")lo=args.min,hi=args.max;else if(spec.includes("-")){let[loRaw,hiRaw,...rest]=spec.split("-");if(rest.length>0||loRaw===void 0||hiRaw===void 0)throw Error(`invalid cron ${args.field} range: ${part}`);lo=fieldNumber(loRaw,args.names,args.field),hi=fieldNumber(hiRaw,args.names,args.field)}else lo=fieldNumber(spec,args.names,args.field),hi=stepRaw===void 0?lo:args.max;if(lo<args.min||hi>args.max||lo>hi)throw Error(`cron ${args.field} out of range: ${part}`);for(let v=lo;v<=hi;v+=step)out.add(args.normalize?args.normalize(v):v)}return out}function parseCron(expression){if(expression.length>256)throw Error("cron expression is too long");let fields=expression.trim().split(/\s+/).filter(Boolean);if(fields.length!==5)throw Error(`cron expression needs 5 fields (minute hour day month weekday), got ${fields.length}`);let[minute,hour,dayOfMonth,month,dayOfWeek]=fields;return{minutes:parseField({value:minute,min:0,max:59,field:"minute"}),hours:parseField({value:hour,min:0,max:23,field:"hour"}),daysOfMonth:parseField({value:dayOfMonth,min:1,max:31,field:"day-of-month"}),months:parseField({value:month,min:1,max:12,field:"month",names:MONTH_NAMES}),daysOfWeek:parseField({value:dayOfWeek,min:0,max:7,field:"weekday",names:DAY_NAMES,normalize:(v)=>v%7}),dayOfMonthRestricted:dayOfMonth!=="*",dayOfWeekRestricted:dayOfWeek!=="*"}}function isValidCron(expression){try{return parseCron(expression),!0}catch{return!1}}function instantOf(d,hour,minute){return new Date(d.year,d.month-1,d.day,hour,minute,0,0).getTime()}function localDayOf(ms){let d=new Date(ms);return{year:d.getFullYear(),month:d.getMonth()+1,day:d.getDate()}}function shiftDay(d,delta){return localDayOf(new Date(d.year,d.month-1,d.day+delta,12,0,0,0).getTime())}function dayMatches(rule,d){if(!rule.months.has(d.month))return!1;let domMatch=rule.daysOfMonth.has(d.day),dowMatch=rule.daysOfWeek.has(new Date(d.year,d.month-1,d.day).getDay());if(rule.dayOfMonthRestricted&&rule.dayOfWeekRestricted)return domMatch||dowMatch;if(rule.dayOfMonthRestricted)return domMatch;if(rule.dayOfWeekRestricted)return dowMatch;return!0}function floorToMinute(ms){return ms-ms%60000}function sorted(values,direction){return[...values].sort((a,b)=>(a-b)*direction)}function nextCronAfter(expression,afterMs){let rule=parseCron(expression),hours=sorted(rule.hours,1),minutes=sorted(rule.minutes,1),from=new Date(floorToMinute(afterMs)+60000),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(dayMatches(rule,day))for(let hour of hours){if(hour<fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute<fromMinute)continue;let at=instantOf(day,hour,minute);if(at>afterMs)return at}}day=shiftDay(day,1),fromHour=0,fromMinute=0}throw Error(`cron expression never matches: ${expression}`)}function latestCronAtOrBefore(expression,nowMs,notBeforeMs){if(nowMs<notBeforeMs)return null;let rule=parseCron(expression),hours=sorted(rule.hours,-1),minutes=sorted(rule.minutes,-1),from=new Date(floorToMinute(nowMs)),day=localDayOf(from.getTime()),fromHour=from.getHours(),fromMinute=from.getMinutes();for(let i=0;i<3294;i++){if(instantOf(day,23,59)<notBeforeMs)return null;if(dayMatches(rule,day))for(let hour of hours){if(hour>fromHour)continue;for(let minute of minutes){if(hour===fromHour&&minute>fromMinute)continue;let at=instantOf(day,hour,minute);if(at>nowMs)continue;return at>=notBeforeMs?at:null}}day=shiftDay(day,-1),fromHour=23,fromMinute=59}return null}function countCronBetween(expression,fromMs,beforeMs,cap=500){if(!(fromMs<beforeMs))return 0;let count=0,cursor=fromMs-1;while(count<cap){let at;try{at=nextCronAfter(expression,cursor)}catch{return count}if(at>=beforeMs)return count;count+=1,cursor=at}return count}
|
|
3
3
|
export{tightenPluginPermissions,tightenInstalledPluginPermissions,isValidCron,nextCronAfter,latestCronAtOrBefore,countCronBetween,resolveRepoRoot,ISSUE_STATUSES,defaultIssuesStorePath,IssuesStore};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{pluginConfigDir,pluginStateDir}from"./chunk-
|
|
2
|
+
import{pluginConfigDir,pluginStateDir}from"./chunk-7g48tbk2.js";function buildPluginEnv(opts){let configDir=pluginConfigDir(opts.pluginId,opts.homeDir),stateDir=pluginStateDir(opts.pluginId,opts.homeDir),extra=withPluginEnvAliases(opts.extra??{});return{...process.env,...opts.homeDir?{ROVE_HOME_DIR:opts.homeDir,KOBE_HOME_DIR:opts.homeDir}:{},ROVE_SOCKET_PATH:opts.socketPath,KOBE_SOCKET_PATH:opts.socketPath,ROVE_BIN_PATH:opts.binPath,KOBE_BIN_PATH:opts.binPath,ROVE_PLUGIN_ID:opts.pluginId,KOBE_PLUGIN_ID:opts.pluginId,ROVE_PLUGIN_ROOT:opts.pluginRoot,KOBE_PLUGIN_ROOT:opts.pluginRoot,ROVE_PLUGIN_CONFIG_DIR:configDir,KOBE_PLUGIN_CONFIG_DIR:configDir,ROVE_PLUGIN_STATE_DIR:stateDir,KOBE_PLUGIN_STATE_DIR:stateDir,...extra}}function withPluginEnvAliases(values){let aliases={};for(let[key,value]of Object.entries(values))if(key.startsWith("ROVE_"))aliases[`KOBE_${key.slice(5)}`]=value;else if(key.startsWith("KOBE_"))aliases[`ROVE_${key.slice(5)}`]=value;return{...aliases,...values}}
|
|
3
3
|
export{buildPluginEnv};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-
|
|
2
|
+
import{describeAccount,detectEngineStatuses,probeableEngineIds,summarizeEngines}from"./chunk-2qgs5apg.js";import{t}from"./chunk-cy5rkf7y.js";import{createInterface}from"readline";function daemonRestartFix(cliName,reason){return{kind:"run",id:"daemon-restart",label:t(`doctor.fix.${reason}`),command:[cliName,"daemon","restart"],why:t("doctor.fix.daemonRestartWhy")}}function skillInstallFix(installCommand,stale){return{kind:"run",id:"skill-install",label:t(stale?"doctor.fix.skillStale":"doctor.fix.skillMissing"),command:installCommand.split(" "),why:t("doctor.fix.skillInstallWhy")}}function resetManualFix(cliName,reason){return{kind:"manual",id:`reset:${reason}`,label:t(`doctor.fix.${reason}`),action:`${cliName} reset`,why:t("doctor.fix.resetWhy")}}function killOrphansManualFix(cliName,count){return{kind:"manual",id:"kill-orphans",label:t("doctor.fix.orphans",{count}),action:`${cliName} doctor --kill-orphans`,why:t("doctor.fix.orphansWhy")}}function engineTabsManualFix(){return{kind:"manual",id:"engine-tabs",label:t("doctor.fix.engineTabs"),action:t("doctor.fix.engineTabsAction"),why:t("doctor.fix.engineTabsWhy")}}function reinstallManualFix(){return{kind:"manual",id:"reinstall",label:t("doctor.fix.staleInstall"),action:t("doctor.fix.staleInstallAction"),why:t("doctor.fix.staleInstallWhy")}}function spawnHelperFix(paths){return{kind:"run",id:"spawn-helper-chmod",label:t("doctor.fix.spawnHelper"),command:["chmod","755",...paths],why:t("doctor.fix.spawnHelperWhy")}}function humanOnlyFix(reason,vars){return{kind:"manual",id:reason,label:t(`doctor.fix.${reason}`),action:t(`doctor.fix.${reason}Action`,vars),why:t("doctor.fix.humanOnlyWhy")}}function noEngineFix(signedOut){return signedOut.length>0?humanOnlyFix("noEngineLogin",{list:signedOut.join(", ")}):humanOnlyFix("noEngine")}function noEngineAction(signedOut){return signedOut.length>0?t("doctor.fix.noEngineLoginAction",{list:signedOut.join(", ")}):t("doctor.fix.noEngineAction")}function dedupeFixes(fixes){let seen=new Set;return fixes.filter((fix)=>{if(seen.has(fix.id))return!1;return seen.add(fix.id),!0})}async function applyFixes(collected,rt){let fixes=dedupeFixes(collected);if(fixes.length===0){rt.out(""),rt.out(t("doctor.fix.none"));return}let runnable=fixes.filter((fix)=>fix.kind==="run");if(runnable.length>0){rt.out(""),rt.out(t("doctor.fix.header"));for(let fix of runnable){if(rt.out(` ${fix.label}`),rt.out(` ${t("doctor.fix.willRun",{command:fix.command.join(" ")})}`),rt.out(` ${fix.why}`),!rt.interactive)continue;if(!await rt.confirm(` ${t("doctor.fix.confirmPrompt")}`)){rt.out(` ${t("doctor.fix.skipped")}`);continue}let code=await rt.exec(fix.command);rt.out(code===0?` ${t("doctor.fix.done")}`:` ${t("doctor.fix.failed",{code})}`)}if(!rt.interactive)rt.out(` ${t("doctor.fix.nonInteractive")}`)}let manual=fixes.filter((fix)=>fix.kind==="manual");if(manual.length>0){rt.out(""),rt.out(t("doctor.fix.manualHeader"));for(let fix of manual)rt.out(` ${fix.label}`),rt.out(` \u2192 ${fix.action}`),rt.out(` ${fix.why}`)}}async function confirmTty(question){let readline=createInterface({input:process.stdin,output:process.stdout});try{let answer=await new Promise((resolve)=>readline.question(question,resolve));return answer.trim().toLowerCase()==="y"||answer.trim().toLowerCase()==="yes"}finally{readline.close()}}async function execInherited(command){try{return await Bun.spawn([...command],{stdin:"inherit",stdout:"inherit",stderr:"inherit"}).exited}catch{return 127}}function defaultFixRuntime(){return{confirm:confirmTty,exec:execInherited,out:(line)=>console.log(line),interactive:process.stdin.isTTY===!0}}async function probeGit(){try{let proc=Bun.spawn(["git","--version"],{stdin:"ignore",stdout:"pipe",stderr:"ignore"}),text=(await new Response(proc.stdout).text()).trim();if(await proc.exited===0&&text)return{line:`git: \u2713 ${text}`,found:!0}}catch{}return{line:"git: \u2717 not found on PATH",found:!1}}function binaryLabel(binary){return binary.found?`\u2713 ${binary.path}`:`\u2717 ${binary.error}`}async function probeEngines(){let statuses=await detectEngineStatuses(await probeableEngineIds()),lines=["engines:"];for(let status of statuses){let account=describeAccount(status.account),name=`${status.vendor.padEnd(7)} `;if(lines.push(` ${name}${binaryLabel(status.binary)}${status.binary.found?` \u2014 ${account}`:""}`),status.accountError)lines.push(` \u26A0 ${status.accountError}`)}let{usable,signedOut}=summarizeEngines(statuses);return{lines,anyUsable:usable.length>0,signedOut}}async function checkOnboardingEnv(){let[git,engines]=await Promise.all([probeGit(),probeEngines()]);return{git,engines}}
|
|
3
3
|
export{daemonRestartFix,skillInstallFix,resetManualFix,killOrphansManualFix,engineTabsManualFix,reinstallManualFix,spawnHelperFix,humanOnlyFix,noEngineFix,noEngineAction,applyFixes,defaultFixRuntime,probeGit,probeEngines,checkOnboardingEnv};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{PS_PROBE_TIMEOUT_MS,engineProcessIn,foregroundEngine,foregroundEngineIn,hasAncestor,parsePsSnapshot,psSnapshot,psSnapshotWith,vendorFromArgv}from"./chunk-
|
|
2
|
+
import{PS_PROBE_TIMEOUT_MS,engineProcessIn,foregroundEngine,foregroundEngineIn,hasAncestor,parsePsSnapshot,psSnapshot,psSnapshotWith,vendorFromArgv}from"./chunk-6ynwn2d2.js";import"./chunk-8k625ztz.js";import"./chunk-28430c3s.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-2brn8e1y.js";import"./chunk-z10thenb.js";import"./chunk-3trm92y6.js";import"./chunk-7kysxgbq.js";import"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import"./chunk-wqfp8d9w.js";export{vendorFromArgv,psSnapshotWith,psSnapshot,parsePsSnapshot,hasAncestor,foregroundEngineIn,foregroundEngine,engineProcessIn,PsProbeUnavailableError,PS_PROBE_TIMEOUT_MS};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{discoverMachine}from"./chunk-cyfk0jv0.js";import{startTunnel}from"./chunk-marvv2xy.js";import{dedupeMachines,duplicateAliasOf,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-prhqpps4.js";import{RemoteOrchestrator}from"./chunk-
|
|
2
|
+
import{discoverMachine}from"./chunk-cyfk0jv0.js";import{startTunnel}from"./chunk-marvv2xy.js";import{dedupeMachines,duplicateAliasOf,listMachines,readMachines,setMachineIdentity,updateMachine}from"./chunk-prhqpps4.js";import{RemoteOrchestrator}from"./chunk-mtaqg8p9.js";import"./chunk-k6nxyxyh.js";import"./chunk-h4n8ffqy.js";import"./chunk-6xppe9bj.js";import"./chunk-scx2qchs.js";import"./chunk-b0z6s0w6.js";import{KobeDaemonClient}from"./chunk-tshpk67m.js";import"./chunk-qrmcta3a.js";import"./chunk-5ysn2pzt.js";import{createStateCell}from"./chunk-sdyzxayr.js";import"./chunk-3n8kzdwy.js";import"./chunk-xy8be792.js";import"./chunk-40dgv828.js";import{loadStateFile}from"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import{logClient,logClientError}from"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-q5jhy3t8.js";import"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-wqfp8d9w.js";class MachineHub{local;slots=new Map;machinesAcc=createStateCell([],"machines.status");mergedAcc=createStateCell([],"machines.tasks");localUnsubscribe=null;disposed=!1;constructor(local){this.local=local}machinesSignal(){return this.machinesAcc}tasksSignal(){if(this.slots.size===0)return this.local.tasksSignal();return this.mergedAcc}remoteTaskIds(){let ids=new Set;for(let slot of this.slots.values())for(let task of slot.tasks)ids.add(String(task.id));return ids}attach(){let entries=dedupeMachines(listMachines());if(entries.length===0)return;for(let entry of entries)this.slots.set(entry.alias,{entry,tasks:[]});this.publishStatuses(),this.localUnsubscribe=this.local.tasksSignal().subscribe(()=>this.republishTasks()),this.republishTasks();for(let entry of entries)this.connect(entry)}async connect(entry){let slot=this.slots.get(entry.alias);if(!slot||this.disposed)return;let found=await discoverMachine(entry.alias,entry);if(this.disposed)return;let sockets=found.ok?{daemon:found.status.socketPath,pty:found.status.ptySocketPath}:entry.sockets;if(!sockets){this.setStatus(entry.alias,{state:"offline",error:found.ok?void 0:found.message});return}if(found.ok)updateMachine(entry.alias,{sockets});let tunnel=startTunnel({alias:entry.alias,config:entry,remoteDaemonSocket:sockets.daemon,remotePtySocket:sockets.pty});if(slot.tunnel=tunnel,tunnel.state()==="unsupported"){this.setStatus(entry.alias,{state:"unsupported",error:"SSH unix-socket forwarding is not available on Windows"});return}if(tunnel.onState((state)=>{if(state==="online")this.openOrchestrator(entry,tunnel);else if(state==="offline")this.setStatus(entry.alias,{state:"offline"}),this.republishTasks()}),tunnel.state()==="online")await this.openOrchestrator(entry,tunnel)}async openOrchestrator(entry,tunnel){let slot=this.slots.get(entry.alias);if(!slot||this.disposed||slot.orchestrator)return;let client=new KobeDaemonClient(tunnel.daemonSocketPath),orchestrator=new RemoteOrchestrator(client,{role:"gui",expectForeignHome:!0,onPeerIdentity:(peer)=>this.onPeerIdentity(entry.alias,peer)});slot.orchestrator=orchestrator;try{await orchestrator.init()}catch(err){let message=err instanceof Error?err.message:String(err);this.setStatus(entry.alias,{state:classifyHandshakeFailure(message),error:message}),logClientError("machines",err);return}let stopTasks=orchestrator.tasksSignal().subscribe(()=>{slot.tasks=orchestrator.tasksSignal().get(),this.republishTasks()}),stopConnection=orchestrator.connectionStateSignal().subscribe(()=>{let connected=orchestrator.connectionStateSignal().get()==="online";if(this.slots.get(entry.alias)!==slot)return;this.setStatus(entry.alias,{state:connected?"online":"offline"}),this.republishTasks()});slot.unsubscribe=()=>{stopTasks(),stopConnection()},slot.tasks=orchestrator.tasksSignal().get(),this.setStatus(entry.alias,{state:"online",version:orchestrator.daemonVersionSignal().get()??void 0}),this.republishTasks(),logClient("machines",`${entry.alias} online (${slot.tasks.length} tasks)`)}onPeerIdentity(alias,peer){if(!peer.hostname&&!peer.homeDir)return;let identity={hostname:peer.hostname,homeDir:peer.homeDir,daemonPid:peer.daemonPid};setMachineIdentity(alias,identity);let duplicate=duplicateAliasOf(readMachines(loadStateFile()),alias,identity);this.setStatus(alias,{hostname:peer.hostname||void 0,version:peer.kobeVersion||void 0,...duplicate?{duplicateOf:duplicate}:{}})}setStatus(alias,patch){let next=this.machinesAcc.get().map((row)=>row.alias===alias?{...row,...patch}:row);this.machinesAcc.set(next)}publishStatuses(){this.machinesAcc.set([...this.slots.values()].map((slot)=>({alias:slot.entry.alias,hostLabel:slot.entry.alias,state:"connecting"})))}republishTasks(){let merged=this.local.tasksSignal().get().map((task)=>stampOrigin(task,"local","local"));for(let slot of this.slots.values()){let status=this.machinesAcc.get().find((row)=>row.alias===slot.entry.alias);if(status?.duplicateOf)continue;let hostLabel=status?.hostLabel||slot.entry.alias,stale=status?.state!=="online";for(let task of slot.tasks)merged.push(stampOrigin(task,slot.entry.alias,hostLabel,stale))}this.mergedAcc.set(merged)}dispose(){this.disposed=!0,this.localUnsubscribe?.();for(let slot of this.slots.values())slot.unsubscribe?.(),slot.orchestrator?.dispose(),slot.tunnel?.stop();this.slots.clear()}}function classifyHandshakeFailure(message){return/protocol v\d/i.test(message)?"mismatch":"offline"}function stampOrigin(task,machineId,hostLabel,stale=!1){return{...task,origin:{machineId,hostLabel,...stale?{stale:!0}:{}}}}export{stampOrigin,classifyHandshakeFailure,MachineHub};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{DAEMON_CHANNELS}from"./chunk-
|
|
2
|
+
import{DAEMON_CHANNELS}from"./chunk-5ysn2pzt.js";import{samePath}from"./chunk-f10n6063.js";var DAEMON_PROTOCOL_VERSION=5,MIN_COMPATIBLE_PROTOCOL_VERSION=2;function isProtocolCompatible(args){return args.remoteVersion>=args.localMin&&args.localVersion>=args.remoteMin}function isDaemonVersionStale(daemonVersion,clientVersion){if(!daemonVersion)return!1;return daemonVersion!==clientVersion}function isForeignDaemonHome(daemonHome,clientHome){if(!daemonHome)return!1;return!samePath(daemonHome,clientHome)}function automationRunNeedsAttention(status){return status==="dispatch_failed"||status==="skipped_unavailable"}var ATTENTION_INBOX_STATES=["turn_complete","permission_needed","error","rate_limited","dead","routine_failed"];function isAttentionInboxState(value){return typeof value==="string"&&ATTENTION_INBOX_STATES.includes(value)}function attentionInboxItemKey(item){if(item.state==="routine_failed"&&item.detail?.routine)return`\x00routine\x00${item.detail.routine.automationId}`;return`${item.taskId}\x00${item.tabId??""}`}var CHANNEL_NAMES=DAEMON_CHANNELS;var CHANNEL_NAME_SET=new Set(CHANNEL_NAMES);function isChannelName(value){return typeof value==="string"&&CHANNEL_NAME_SET.has(value)}function normalizeChannelFilter(value){if(!Array.isArray(value))return null;let set=new Set;for(let name of value)if(isChannelName(name))set.add(name);return set.size>0?set:null}var BLOCKING_RPCS=new Set(["ui.prompt","task.land","workitem.start","automation.runNow","task.ensureWorktree","task.ensureMain","worktree.discoverAdoptable","worktree.adopt","worktree.list","worktree.remove"]);function parseDaemonStopReason(value){return value==="restart"||value==="stop"||value==="idle"||value==="socket-lost"?value:void 0}function displayTaskTitle(task){return task.title||task.branch||task.worktreePath||task.repo||"scratch"}function serializeTask(task){return{id:task.id,title:displayTaskTitle(task),repo:task.repo,branch:task.branch,worktreePath:task.worktreePath,kind:task.kind??"task",...task.scratch?{scratch:!0}:{},...task.routine?{routine:task.routine}:{},status:task.status,pinned:task.pinned??!1,vendor:task.vendor,command:task.command,prStatus:task.prStatus,modelEffort:task.modelEffort,groupId:task.groupId,observedLanguage:task.observedLanguage,deletion:task.deletion,quotaResume:task.quotaResume,linkedWorkItem:task.linkedWorkItem,dispatcher:task.dispatcher,prompt:task.prompt,baseRef:task.baseRef,worktreeName:task.worktreeName,report:task.report,createdAt:task.createdAt,updatedAt:task.updatedAt}}function frameToLine(frame){return`${JSON.stringify(frame)}
|
|
3
3
|
`}
|
|
4
4
|
export{automationRunNeedsAttention,isAttentionInboxState,attentionInboxItemKey,CHANNEL_NAMES,normalizeChannelFilter,DAEMON_PROTOCOL_VERSION,MIN_COMPATIBLE_PROTOCOL_VERSION,isProtocolCompatible,isDaemonVersionStale,isForeignDaemonHome,BLOCKING_RPCS,parseDaemonStopReason,displayTaskTitle,serializeTask,frameToLine};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,unknownVerbError,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-
|
|
2
|
+
import{API_SCHEMA_VERSION,API_VERBS,VERBS,VERB_GROUPS,VerbArgs,apiUsage,buildCountPlan,defaultApiRuntime,deliverPrompt,findVerb,fullSchema,parseAgentsSpec,parseFlags,schemaIndex,takeIdentityWarning,unknownVerbError,validateAgainstSpec,verbHelp,verbSchema}from"./chunk-3kr76178.js";import{ensurePluginEnginesLoaded}from"./chunk-d2e1991k.js";import{openDaemonSession}from"./chunk-2pv36cqe.js";import"./chunk-382dy4yn.js";import"./chunk-3e5n28t6.js";import"./chunk-xb9b93ts.js";import"./chunk-ce2hj8b7.js";import"./chunk-r2pztgm6.js";import"./chunk-7g48tbk2.js";import"./chunk-63wmhbqs.js";import"./chunk-qkehg2c1.js";import"./chunk-2zezgeh8.js";import"./chunk-0ra81t6k.js";import"./chunk-kfnqws7s.js";import"./chunk-fc70p4f5.js";import"./chunk-2apszxn2.js";import"./chunk-g2advs8t.js";import"./chunk-23kja9zv.js";import"./chunk-rcyasw34.js";import"./chunk-7q67dz4c.js";import"./chunk-2jj1q7pv.js";import"./chunk-hape5vwj.js";import"./chunk-b99tf0jr.js";import{ApiError,splitDaemonCode}from"./chunk-f7zjggfv.js";import"./chunk-w25b7xxz.js";import"./chunk-6xppe9bj.js";import"./chunk-e6jqk80f.js";import"./chunk-w6fbdxg2.js";import"./chunk-fczqwtmq.js";import"./chunk-scx2qchs.js";import"./chunk-b0z6s0w6.js";import"./chunk-tshpk67m.js";import"./chunk-qrmcta3a.js";import"./chunk-5ysn2pzt.js";import"./chunk-ad37b8qf.js";import"./chunk-401a3x2y.js";import"./chunk-cy5rkf7y.js";import"./chunk-xtjw8vfj.js";import"./chunk-sdyzxayr.js";import"./chunk-6ynwn2d2.js";import"./chunk-8k625ztz.js";import"./chunk-28430c3s.js";import"./chunk-w7zv47mp.js";import"./chunk-khj0apc7.js";import"./chunk-3n8kzdwy.js";import"./chunk-jvxh93nz.js";import{errorMessage}from"./chunk-2brn8e1y.js";import"./chunk-z10thenb.js";import"./chunk-3trm92y6.js";import"./chunk-7kysxgbq.js";import"./chunk-3rfqykw4.js";import"./chunk-xy8be792.js";import"./chunk-crt11rmj.js";import"./chunk-40dgv828.js";import"./chunk-katrbape.js";import"./chunk-hq2n27y1.js";import"./chunk-3es6spp4.js";import"./chunk-pw6yfj10.js";import"./chunk-05jej26n.js";import"./chunk-81p6mm0p.js";import"./chunk-q5jhy3t8.js";import"./chunk-vnpqemb0.js";import"./chunk-f10n6063.js";import"./chunk-9prawccj.js";import"./chunk-y8fqdnh3.js";import"./chunk-00ehck55.js";import"./chunk-fxs82dsx.js";import"./chunk-sb0ns0c7.js";import"./chunk-hq4b3fca.js";import"./chunk-pxk2c2vj.js";import{__require}from"./chunk-wqfp8d9w.js";function emit(value,pretty){let warning=takeIdentityWarning(),payload=warning&&value&&typeof value==="object"&&!Array.isArray(value)?{...value,identityWarning:warning}:value,text=pretty?JSON.stringify(payload,null,2):JSON.stringify(payload);process.stdout.write(`${text}
|
|
3
3
|
`)}function fail(message,code,exitCode=1,data){process.stderr.write(`${JSON.stringify({error:{message,code,...data}})}
|
|
4
4
|
`),process.exit(exitCode)}function makeContext(verb,flags,client,runtime){return{args:new VerbArgs(verb,flags),client,runtime}}var USAGE_ERROR_CODES=new Set(["BAD_VERB","UNKNOWN_VERB","BAD_FLAG","MISSING_FLAG","MISSING_VERB","BAD_DAEMON"]);function toApiError(err){if(err instanceof ApiError)return err;let message=errorMessage(err);if(/task not found/i.test(message))return new ApiError(message,"TASK_NOT_FOUND",{hint:"that task id does not exist (deleted or mistyped) \u2014 list live tasks and retry with a real id",nextCommandArgs:["api","list"]});if(/unknown daemon request:/i.test(message))return versionSkewError(message);let coded=splitDaemonCode(message);if(coded)return new ApiError(coded.rest,coded.code);return new ApiError(message,"RPC_ERROR")}function versionSkewError(message){return new ApiError(message,"DAEMON_VERSION_SKEW",{hint:"the running daemon is a different build than this CLI, so it does not serve this verb \u2014 restart the daemon to pick up this build, then retry (if the verb is gone for good, `rove api schema` lists what this daemon actually serves)",nextCommandArgs:["daemon","restart"]})}async function invokeVerb(verbName,argv,deps){let verb=findVerb(verbName);if(!verb)throw unknownVerbError(verbName);let booleanFlags=new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name)),parsed=parseFlags(argv,booleanFlags);validateAgainstSpec(verb,parsed.flags);try{return await verb.handler(makeContext(verb,parsed.flags,deps.client,deps.runtime??defaultApiRuntime))}catch(err){throw toApiError(err)}}async function runApiSubcommand(argv){let[verbName,...rest]=argv;if(!verbName||verbName==="--help"||verbName==="-h"||verbName==="help"){if(!verbName)fail(apiUsage(),"MISSING_VERB",2);process.stdout.write(`${apiUsage()}
|
|
5
5
|
`);return}ensurePluginEnginesLoaded();let verb=findVerb(verbName);if(!verb){let err=unknownVerbError(verbName);fail(`${err.message}
|
|
6
6
|
${apiUsage()}`,err.code,2,err.data)}let booleanFlags=new Set(verb.flags.filter((f)=>f.type==="bool").map((f)=>f.name)),parsed;try{parsed=parseFlags(rest,booleanFlags)}catch(err){if(err instanceof ApiError)fail(err.message,err.code,2,err.data);fail(errorMessage(err),"BAD_FLAG",2)}if(parsed.help){process.stdout.write(`${verbHelp(verb)}
|
|
7
|
-
`);return}try{validateAgainstSpec(verb,parsed.flags)}catch(err){if(err instanceof ApiError)fail(err.message,err.code,2,err.data);fail(errorMessage(err),"BAD_FLAG",2)}let session=null;if(!verb.offline)try{session=await openDaemonSession()}catch(err){fail(`could not reach or start the Rove daemon: ${errorMessage(err)}`,"BAD_DAEMON",2,{hint:"check whether the daemon is up (and why it is not), then retry the same command",nextCommandArgs:["daemon","status"]})}try{let{assertLocalTask}=await import("./chunk-
|
|
7
|
+
`);return}try{validateAgainstSpec(verb,parsed.flags)}catch(err){if(err instanceof ApiError)fail(err.message,err.code,2,err.data);fail(errorMessage(err),"BAD_FLAG",2)}let session=null;if(!verb.offline)try{session=await openDaemonSession()}catch(err){fail(`could not reach or start the Rove daemon: ${errorMessage(err)}`,"BAD_DAEMON",2,{hint:"check whether the daemon is up (and why it is not), then retry the same command",nextCommandArgs:["daemon","status"]})}try{let{assertLocalTask}=await import("./chunk-sx8qg4ez.js");await assertLocalTask(parsed.flags.get("task-id"));let result=await verb.handler(makeContext(verb,parsed.flags,session?.client??null,defaultApiRuntime));emit(result,parsed.pretty)}catch(err){if(err instanceof ApiError&&err.code==="PARTIAL_FANOUT")emit(err.data,parsed.pretty),session?.close(),process.exit(3);let apiErr=toApiError(err);fail(apiErr.message,apiErr.code,USAGE_ERROR_CODES.has(apiErr.code)?2:1,apiErr.data)}finally{session?.close()}}export{verbSchema,verbHelp,validateAgainstSpec,toApiError,schemaIndex,runApiSubcommand,parseFlags,parseAgentsSpec,invokeVerb,fullSchema,findVerb,deliverPrompt,defaultApiRuntime,buildCountPlan,apiUsage,VerbArgs,VERB_GROUPS,VERBS,ApiError,API_VERBS,API_SCHEMA_VERSION};
|