@code-yeongyu/senpi 2026.9.28-6 → 2026.9.28-7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/bundle/chunks/{app-server-command-5WCSZ4A5.js → app-server-command-OUTRKHMK.js} +8 -8
  3. package/dist/bundle/chunks/{chunk-AWPLVQ4K.js → chunk-56COAYOU.js} +5 -5
  4. package/dist/bundle/chunks/{chunk-4BDFNRBE.js → chunk-B32PXL7U.js} +1 -1
  5. package/dist/bundle/chunks/chunk-CEMOA3TF.js +2 -0
  6. package/dist/bundle/chunks/{chunk-WXN35RD7.js → chunk-DB2X7SOZ.js} +2 -2
  7. package/dist/bundle/chunks/{chunk-DKP4BUY5.js → chunk-F2YU5BZG.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-VGJESQOS.js → chunk-JASECXGC.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-KDZAVHA7.js → chunk-L4OOEWAT.js} +2 -2
  10. package/dist/bundle/chunks/{chunk-DOEV7ITR.js → chunk-LM2UMEX6.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-HS2LJYBI.js → chunk-Y4CH7LYI.js} +1 -1
  12. package/dist/bundle/chunks/chunk-YJUO37UX.js +2 -0
  13. package/dist/bundle/chunks/{cli-main-IBG7ONGV.js → cli-main-26P4V2BK.js} +1 -1
  14. package/dist/bundle/chunks/{help-fast-path-MWSJXPH6.js → help-fast-path-BOMUI7U3.js} +1 -1
  15. package/dist/bundle/chunks/{host-command-MTK5WOPH.js → host-command-ZVXNTXMN.js} +1 -1
  16. package/dist/bundle/chunks/{host-lifecycle-7IJCAHHL.js → host-lifecycle-MPLSJ5NB.js} +1 -1
  17. package/dist/bundle/chunks/host-lifecycle.js +1 -1
  18. package/dist/bundle/chunks/{interactive-host-runtime-FWMZWK6G.js → interactive-host-runtime-Q5EORM6B.js} +1 -1
  19. package/dist/bundle/chunks/{interactive-mode-XUJM4MCN.js → interactive-mode-OVSKUTVC.js} +1 -1
  20. package/dist/bundle/chunks/{list-tips-S4U7TKER.js → list-tips-ARO4HRVK.js} +1 -1
  21. package/dist/bundle/chunks/{multi-session-host-7KCH3HUA.js → multi-session-host-LJNXZRFA.js} +7 -7
  22. package/dist/bundle/chunks/{package-manager-cli-SNVT3VKW.js → package-manager-cli-MJCRY2JU.js} +1 -1
  23. package/dist/bundle/chunks/{rpc-mode-VYB2Q43O.js → rpc-mode-LY4HAZ5G.js} +1 -1
  24. package/dist/bundle/chunks/{schedule-command-JQ65HF2K.js → schedule-command-3ANAEUY6.js} +1 -1
  25. package/dist/bundle/chunks/session-worker.js +30 -30
  26. package/dist/bundle/cli.js +1 -1
  27. package/dist/bundle/index.js +1 -1
  28. package/dist/bundle/rpc-entry.js +1 -1
  29. package/dist/cli/args.js +2 -2
  30. package/dist/cli/args.js.map +1 -1
  31. package/dist/main.d.ts +2 -2
  32. package/dist/main.d.ts.map +1 -1
  33. package/dist/main.js +25 -6
  34. package/dist/main.js.map +1 -1
  35. package/dist/modes/app-server/cli-args.d.ts +3 -0
  36. package/dist/modes/app-server/cli-args.d.ts.map +1 -1
  37. package/dist/modes/app-server/cli-args.js +25 -4
  38. package/dist/modes/app-server/cli-args.js.map +1 -1
  39. package/dist/modes/app-server/daemon/probe.d.ts +1 -0
  40. package/dist/modes/app-server/daemon/probe.d.ts.map +1 -1
  41. package/dist/modes/app-server/daemon/probe.js +4 -1
  42. package/dist/modes/app-server/daemon/probe.js.map +1 -1
  43. package/dist/modes/app-server/daemon/spawn.d.ts +26 -0
  44. package/dist/modes/app-server/daemon/spawn.d.ts.map +1 -0
  45. package/dist/modes/app-server/daemon/spawn.js +112 -0
  46. package/dist/modes/app-server/daemon/spawn.js.map +1 -0
  47. package/dist/modes/app-server/daemon.d.ts.map +1 -1
  48. package/dist/modes/app-server/daemon.js +14 -112
  49. package/dist/modes/app-server/daemon.js.map +1 -1
  50. package/dist/modes/app-server/extension-paths.d.ts +7 -0
  51. package/dist/modes/app-server/extension-paths.d.ts.map +1 -0
  52. package/dist/modes/app-server/extension-paths.js +10 -0
  53. package/dist/modes/app-server/extension-paths.js.map +1 -0
  54. package/dist/modes/app-server/index.d.ts.map +1 -1
  55. package/dist/modes/app-server/index.js +4 -1
  56. package/dist/modes/app-server/index.js.map +1 -1
  57. package/dist/modes/app-server/runtime.d.ts +5 -1
  58. package/dist/modes/app-server/runtime.d.ts.map +1 -1
  59. package/dist/modes/app-server/runtime.js +19 -3
  60. package/dist/modes/app-server/runtime.js.map +1 -1
  61. package/dist/modes/interactive/tips/catalog/computer-tips.js +1 -1
  62. package/dist/modes/interactive/tips/catalog/computer-tips.js.map +1 -1
  63. package/dist/modes/rpc/custom-capability.d.ts +5 -0
  64. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  65. package/dist/modes/rpc/custom-capability.js +5 -0
  66. package/dist/modes/rpc/custom-capability.js.map +1 -1
  67. package/dist/modes/rpc/host-observe-request.d.ts +2 -0
  68. package/dist/modes/rpc/host-observe-request.d.ts.map +1 -1
  69. package/dist/modes/rpc/host-observe-request.js +4 -0
  70. package/dist/modes/rpc/host-observe-request.js.map +1 -1
  71. package/dist/modes/rpc/host-warm.d.ts +57 -0
  72. package/dist/modes/rpc/host-warm.d.ts.map +1 -0
  73. package/dist/modes/rpc/host-warm.js +125 -0
  74. package/dist/modes/rpc/host-warm.js.map +1 -0
  75. package/dist/modes/rpc/rpc-types.d.ts +24 -1
  76. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  77. package/dist/modes/rpc/rpc-types.js +2 -0
  78. package/dist/modes/rpc/rpc-types.js.map +1 -1
  79. package/dist/modes/rpc/session-command-router.d.ts +1 -1
  80. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  81. package/dist/modes/rpc/session-command-router.js +12 -1
  82. package/dist/modes/rpc/session-command-router.js.map +1 -1
  83. package/dist/modes/rpc/session-registry.d.ts +6 -2
  84. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  85. package/dist/modes/rpc/session-registry.js +6 -0
  86. package/dist/modes/rpc/session-registry.js.map +1 -1
  87. package/docs/app-server-daemon.md +1 -1
  88. package/docs/app-server.md +3 -0
  89. package/docs/rpc.md +48 -2
  90. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  91. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  92. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  93. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  94. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  95. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  96. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  97. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  98. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  99. package/package.json +7 -7
  100. package/dist/bundle/chunks/chunk-A4UMPXQF.js +0 -2
  101. package/dist/bundle/chunks/chunk-BTMM2C5X.js +0 -2
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{RUNNER_HEARTBEAT_INTERVAL_MS,RUNNER_HEARTBEAT_STALE_MS,acquireSessionDeliveryLock,cancelScheduledJob,claimOccurrence,formatScheduledMessage,isCancelled,isOwnerAmong,listScheduledJobs,liveRunners,liveSessionHolders,nextRecurringDueAt,ownRunnerIdentity,pruneTombstones,readJobFile,rearmRecurringJob,removeRunnerLease,restoreAbandonedSchedule,restorePending,scheduleDir,settleOccurrence,writeRunnerLease}from"./chunk-FAV4DX74.js";import"./chunk-U5KVIAHJ.js";import{resolveCliMainPath}from"./chunk-HS2LJYBI.js";import"./chunk-E5F5SVZF.js";import{killWindowsProcessTree}from"./chunk-ASAQQ6VM.js";import"./chunk-U3VOXCGP.js";import{APP_NAME,getAgentDir,isBunBinary}from"./chunk-PBWQK23Z.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";import{mkdirSync,watch}from"node:fs";import{join as join2}from"node:path";import{spawn}from"node:child_process";import{existsSync}from"node:fs";async function deferWhileSessionOpen(job){if(job.sessionFile===null||!existsSync(job.sessionFile))return;let holders=await liveSessionHolders(job.sessionFile,job.sessionId);if(holders.length!==0)return`session is open in pid ${holders.map(holder=>holder.pid).join(", ")}; waiting until it closes`}var STDERR_TAIL_CHARS=2e3,POSIX_GATE='IFS= read -r _ <&3 || exit 75; exec 3<&-; exec "$0" "$@"';function killTree(pid){if(process.platform==="win32"){killWindowsProcessTree(pid);return}try{process.kill(-pid,"SIGKILL")}catch{}}function runDeliveryProcess(launch,timeoutMs,context={}){return new Promise(resolve=>{let posix=process.platform!=="win32",child=posix?spawn("/bin/sh",["-c",POSIX_GATE,launch.command,...launch.args],{cwd:launch.cwd,env:launch.env,stdio:["pipe","ignore","pipe","pipe"],detached:!0}):spawn(launch.command,[...launch.args],{cwd:launch.cwd,env:launch.env,stdio:["pipe","ignore","pipe"],windowsHide:!0,windowsVerbatimArguments:launch.windowsVerbatimArguments===!0}),stderr="",failure,timer=setTimeout(()=>{failure??=`delivery timed out after ${Math.round(timeoutMs/1e3)}s`,child.pid!==void 0&&killTree(child.pid)},timeoutMs);child.stderr?.on("data",chunk=>{stderr=(stderr+chunk.toString("utf8")).slice(-STDERR_TAIL_CHARS)}),child.stdin?.on("error",()=>{});let gate=posix?child.stdio[3]:null;gate?.on("error",()=>{}),child.on("error",error=>{failure??=error.message}),child.on("close",(code,signal)=>{if(clearTimeout(timer),failure!==void 0)resolve({ok:!1,error:failure});else if(code===0)resolve({ok:!0});else{let status=code===null?`signal ${signal}`:`exit code ${code}`;resolve({ok:!1,error:stderr.trim()?`${status}: ${stderr.trim()}`:status})}});let pid=child.pid;pid!==void 0&&Promise.resolve(context.onSpawn?.(pid)).then(()=>{gate!=null&&"end"in gate&&gate.end(`go
2
+ import{RUNNER_HEARTBEAT_INTERVAL_MS,RUNNER_HEARTBEAT_STALE_MS,acquireSessionDeliveryLock,cancelScheduledJob,claimOccurrence,formatScheduledMessage,isCancelled,isOwnerAmong,listScheduledJobs,liveRunners,liveSessionHolders,nextRecurringDueAt,ownRunnerIdentity,pruneTombstones,readJobFile,rearmRecurringJob,removeRunnerLease,restoreAbandonedSchedule,restorePending,scheduleDir,settleOccurrence,writeRunnerLease}from"./chunk-FAV4DX74.js";import"./chunk-U5KVIAHJ.js";import{resolveCliMainPath}from"./chunk-Y4CH7LYI.js";import"./chunk-E5F5SVZF.js";import{killWindowsProcessTree}from"./chunk-ASAQQ6VM.js";import"./chunk-U3VOXCGP.js";import{APP_NAME,getAgentDir,isBunBinary}from"./chunk-PBWQK23Z.js";import"./chunk-ATQFN5HI.js";import"./chunk-IKOFCODM.js";import{mkdirSync,watch}from"node:fs";import{join as join2}from"node:path";import{spawn}from"node:child_process";import{existsSync}from"node:fs";async function deferWhileSessionOpen(job){if(job.sessionFile===null||!existsSync(job.sessionFile))return;let holders=await liveSessionHolders(job.sessionFile,job.sessionId);if(holders.length!==0)return`session is open in pid ${holders.map(holder=>holder.pid).join(", ")}; waiting until it closes`}var STDERR_TAIL_CHARS=2e3,POSIX_GATE='IFS= read -r _ <&3 || exit 75; exec 3<&-; exec "$0" "$@"';function killTree(pid){if(process.platform==="win32"){killWindowsProcessTree(pid);return}try{process.kill(-pid,"SIGKILL")}catch{}}function runDeliveryProcess(launch,timeoutMs,context={}){return new Promise(resolve=>{let posix=process.platform!=="win32",child=posix?spawn("/bin/sh",["-c",POSIX_GATE,launch.command,...launch.args],{cwd:launch.cwd,env:launch.env,stdio:["pipe","ignore","pipe","pipe"],detached:!0}):spawn(launch.command,[...launch.args],{cwd:launch.cwd,env:launch.env,stdio:["pipe","ignore","pipe"],windowsHide:!0,windowsVerbatimArguments:launch.windowsVerbatimArguments===!0}),stderr="",failure,timer=setTimeout(()=>{failure??=`delivery timed out after ${Math.round(timeoutMs/1e3)}s`,child.pid!==void 0&&killTree(child.pid)},timeoutMs);child.stderr?.on("data",chunk=>{stderr=(stderr+chunk.toString("utf8")).slice(-STDERR_TAIL_CHARS)}),child.stdin?.on("error",()=>{});let gate=posix?child.stdio[3]:null;gate?.on("error",()=>{}),child.on("error",error=>{failure??=error.message}),child.on("close",(code,signal)=>{if(clearTimeout(timer),failure!==void 0)resolve({ok:!1,error:failure});else if(code===0)resolve({ok:!0});else{let status=code===null?`signal ${signal}`:`exit code ${code}`;resolve({ok:!1,error:stderr.trim()?`${status}: ${stderr.trim()}`:status})}});let pid=child.pid;pid!==void 0&&Promise.resolve(context.onSpawn?.(pid)).then(()=>{gate!=null&&"end"in gate&&gate.end(`go
3
3
  `),child.stdin?.end(launch.stdin??"")},error=>{failure??=`could not register the delivery: ${error instanceof Error?error.message:String(error)}`,killTree(pid)})})}function eventEnv(event){return{...process.env,SENPI_SCHEDULE_ID:event.id,SENPI_SCHEDULE_SESSION_ID:event.sessionId,SENPI_SCHEDULE_SESSION_FILE:event.sessionFile??"",SENPI_SCHEDULE_CWD:event.cwd}}function execHookDelivery(command,timeoutMs){let shell=process.platform==="win32"?{command:process.env.ComSpec??"cmd.exe",args:["/d","/s","/c",`"${command}"`],windowsVerbatimArguments:!0}:{command:"/bin/sh",args:["-c",command]};return(event,context)=>runDeliveryProcess({...shell,env:eventEnv(event),stdin:`${JSON.stringify(event)}
4
4
  `,cwd:process.cwd()},timeoutMs,context)}function sessionResumeDelivery(senpi,timeoutMs){return async(event,context)=>existsSync(event.cwd)?event.sessionFile!==null&&!existsSync(event.sessionFile)?{ok:!1,error:`session file no longer exists: ${event.sessionFile}`}:runDeliveryProcess({command:senpi.command,args:[...senpi.args,"-p","--session",event.sessionFile??event.sessionId,event.message],cwd:event.cwd,env:eventEnv(event)},timeoutMs,context):{ok:!1,error:`working directory no longer exists: ${event.cwd}`}}import{join}from"node:path";var DEFERRED_RETRY_MS=15e3,ABANDONED_OCCURRENCE_ERROR="the runner exited while delivering this occurrence; outcome unknown, not retried";async function recoverAbandoned(options,records){let firing=records.filter(record=>record.state==="firing");if(firing.length===0)return{events:[],restoredDueAt:[]};let runners=await(options.runners??(()=>liveRunners(options.dir)))(),events=[],restoredDueAt=[];for(let record of firing){if(record.owner===void 0||record.occurrence===void 0||record.owner.pid===options.owner.pid&&record.owner.processStartedAtMs===options.owner.processStartedAtMs||isOwnerAmong(record.owner,runners))continue;let restored=await restoreAbandonedSchedule(options.dir,record.job,record.occurrence,options.now());restored!==void 0&&restoredDueAt.push(restored.dueAt),await settleOccurrence(options.dir,record.file,record.job,record.occurrence,{ok:!1,error:ABANDONED_OCCURRENCE_ERROR}),events.push({event:"abandoned",id:record.job.id,sessionId:record.job.sessionId,occurrence:record.occurrence,error:ABANDONED_OCCURRENCE_ERROR})}return{events,restoredDueAt}}async function freshPendingJob(options,id){let job=await readJobFile(join(options.dir,"pending",`${id}.json`),id).catch(error=>{if(!(error instanceof Error&&"code"in error&&error.code==="ENOENT"))throw error});if(!(job===void 0||job.dueAt>options.now()||await isCancelled(options.dir,id)))return job}async function fireOne(options,listed){let lock=await acquireSessionDeliveryLock(options.dir,listed.sessionId,{maxDeliveryMs:options.deliveryTimeoutMs});if(!lock.acquired){let holder=lock.heldByPid===void 0?"another runner":`process ${lock.heldByPid}`;return{event:"deferred",id:listed.id,sessionId:listed.sessionId,reason:`${holder} is delivering to this session`}}try{let job=await freshPendingJob(options,listed.id);if(job===void 0)return;let deferReason=await options.shouldDefer?.(job);return deferReason!==void 0?{event:"deferred",id:job.id,sessionId:job.sessionId,reason:deferReason}:await deliverClaimed(options,job,pid=>lock.attachDelivery(pid))}finally{await lock.release()}}async function deliverClaimed(options,job,onSpawn){let record=await claimOccurrence(options.dir,job,options.owner);if(record===void 0)return;let occurrence=job.fireCount+1,firedAt=options.now(),nextDueAt;if(job.everyMs!==null){nextDueAt=nextRecurringDueAt(job.dueAt,job.everyMs,firedAt);try{await rearmRecurringJob(options.dir,{...job,fireCount:occurrence,lastFiredAt:firedAt,dueAt:nextDueAt})}catch(error){throw await restorePending(options.dir,record,job.id),error}}let result;try{result=await options.deliver({type:"scheduled_prompt",id:job.id,sessionId:job.sessionId,sessionFile:job.sessionFile,cwd:job.cwd,prompt:job.prompt,message:formatScheduledMessage(job,firedAt),dueAt:job.dueAt,firedAt,everyMs:job.everyMs,fireCount:occurrence},{onSpawn})}catch(error){result={ok:!1,error:error instanceof Error?error.message:String(error)}}return await settleOccurrence(options.dir,record,{...job,fireCount:occurrence,lastFiredAt:firedAt},occurrence,result),{event:"fired",id:job.id,sessionId:job.sessionId,occurrence,outcome:result.ok?"delivered":"failed",...result.ok?{}:{error:result.error},firedAt,dueAt:job.dueAt,...nextDueAt===void 0||await isCancelled(options.dir,job.id)?{}:{nextDueAt}}}async function runDueJobs(options){let listing=await listScheduledJobs(options.dir),events=listing.invalid.map(invalid=>({event:"invalid",...invalid})),recovery=await recoverAbandoned(options,listing.jobs);events.push(...recovery.events),await pruneTombstones(options.dir,listing,options.now());let nextDueAt,noteNext=dueAt=>{nextDueAt=nextDueAt===void 0?dueAt:Math.min(nextDueAt,dueAt)};for(let dueAt of recovery.restoredDueAt)noteNext(dueAt);let bySession=new Map;for(let{state,job}of listing.jobs){if(state!=="pending")continue;if(job.dueAt>options.now()){noteNext(job.dueAt);continue}if(await isCancelled(options.dir,job.id))continue;let queue=bySession.get(job.sessionId)??[];queue.push(job),bySession.set(job.sessionId,queue)}let queues=[...bySession.values()],workers=Math.max(1,Math.min(options.concurrency??4,queues.length)),next=0;return await Promise.all(Array.from({length:workers},async()=>{for(;next<queues.length;){let queue=queues[next++]??[];for(let job of queue){let event;try{event=await fireOne(options,job)}catch(error){let message=error instanceof Error?error.message:String(error);events.push({event:"error",id:job.id,sessionId:job.sessionId,error:message}),noteNext(options.now()+DEFERRED_RETRY_MS);break}if(event!==void 0&&(events.push(event),event.event==="fired"&&event.nextDueAt!==void 0&&noteNext(event.nextDueAt),event.event==="deferred")){noteNext(options.now()+DEFERRED_RETRY_MS);break}}}})),{events,nextDueAt}}function writeLine(value){process.stdout.write(`${JSON.stringify(value)}
5
5
  `)}function resolveDelivery(options){let timeoutMs=options.timeoutSeconds*1e3;return options.exec!==void 0?{deliver:execHookDelivery(options.exec,timeoutMs),shouldDefer:void 0}:{deliver:sessionResumeDelivery({command:process.execPath,args:isBunBinary?[]:[...process.execArgv,resolveCliMainPath()]},timeoutMs),shouldDefer:deferWhileSessionOpen}}function reporter(){let deferred=new Map,invalid=new Map;return result=>{let ok=!0,stillInvalid=new Set;for(let event of result.events){if(event.event==="deferred"){if(deferred.get(event.id)===event.reason)continue;deferred.set(event.id,event.reason)}else if(event.event==="invalid"){if(stillInvalid.add(event.file),invalid.get(event.file)===event.error)continue;invalid.set(event.file,event.error)}else event.event==="fired"?(deferred.delete(event.id),event.outcome==="failed"&&(ok=!1)):event.event==="error"&&(ok=!1);writeLine(event)}for(let file of invalid.keys())stillInvalid.has(file)||invalid.delete(file);return ok}}async function guardedPass(pass){try{return await pass()}catch(error){return{events:[{event:"error",error:error instanceof Error?error.message:String(error)}],nextDueAt:void 0}}}async function runPasses(dir,options){let plan=resolveDelivery(options),owner=ownRunnerIdentity(),startedAt=Date.now(),lease=()=>writeRunnerLease(dir,{startedAt,watch:options.watch,exec:options.exec??null},Date.now()),report=reporter(),pass=()=>runDueJobs({dir,now:Date.now,deliver:plan.deliver,owner,concurrency:options.concurrency,deliveryTimeoutMs:options.timeoutSeconds*1e3,shouldDefer:plan.shouldDefer});await lease();let leaseFailing=!1,heartbeat=setInterval(()=>{lease().then(()=>{leaseFailing=!1},error=>{leaseFailing||writeLine({event:"lease_error",error:error instanceof Error?error.message:String(error)}),leaseFailing=!0})},RUNNER_HEARTBEAT_INTERVAL_MS),watcher,stopping=!1,wake,stop=()=>{stopping=!0,wake?.()};try{if(!options.watch)return report(await guardedPass(pass))?0:1;process.on("SIGTERM",stop),process.on("SIGINT",stop);let pendingDir=join2(dir,"pending");for(mkdirSync(pendingDir,{recursive:!0,mode:448}),watcher=watch(pendingDir,()=>wake?.()),writeLine({event:"watching",pid:process.pid,dir,pollSeconds:options.pollSeconds});!stopping;){let rescan=!1,woken=new Promise(resolve=>{wake=()=>{rescan=!0,resolve()}}),result=await guardedPass(pass);if(report(result),stopping)break;if(rescan)continue;let untilDue=result.nextDueAt===void 0?Number.POSITIVE_INFINITY:result.nextDueAt-Date.now(),waitMs=Math.max(0,Math.min(options.pollSeconds*1e3,untilDue)),timer;await Promise.race([woken,new Promise(resolve=>timer=setTimeout(resolve,waitMs))]),clearTimeout(timer)}return writeLine({event:"stopped",pid:process.pid}),0}finally{clearInterval(heartbeat),watcher?.close(),process.off("SIGTERM",stop),process.off("SIGINT",stop),await removeRunnerLease(dir)}}var EXIT_OK=0,EXIT_FAILED=1,EXIT_USAGE=2,DEFAULT_POLL_SECONDS=60,DEFAULT_TIMEOUT_SECONDS=900,DEFAULT_CONCURRENCY=4,USAGE=`usage: ${APP_NAME} schedule <list|cancel|run> [options]