claude-code-session-manager 0.111.0 → 0.113.0

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 (290) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/dist/assets/{AgentLibrary-rBO1daqM.js → AgentLibrary-wvrcLGGS.js} +2 -2
  3. package/dist/assets/{Button-DsEYRZg0.js → Button-B6h0F0XT.js} +1 -1
  4. package/dist/assets/{DataModel-D8sbvvBC.js → DataModel-C5pW9E3u.js} +1 -1
  5. package/dist/assets/{History-BEHLtxia.js → History-BV4e8YOM.js} +2 -2
  6. package/dist/assets/{Hooks-CKpvlXrg.js → Hooks-CrFSv4x1.js} +3 -3
  7. package/dist/assets/{Library-CeF4qh9d.js → Library-D-GIt3EY.js} +5 -5
  8. package/dist/assets/{ListDetail-DcfmxPFk.js → ListDetail-Bco_wfs6.js} +1 -1
  9. package/dist/assets/{MarkdownEditor-CvK1pyto.js → MarkdownEditor-C-yHSXNV.js} +1 -1
  10. package/dist/assets/{McpServers-D-h2ihzJ.js → McpServers-CfDekadG.js} +2 -2
  11. package/dist/assets/{Memory-BnF89x8v.js → Memory-CGGLexkR.js} +4 -4
  12. package/dist/assets/{Panel-CQY5zano.js → Panel-DGMEuYYG.js} +1 -1
  13. package/dist/assets/{Permissions-DLukmmsz.js → Permissions-Cx2zjtYZ.js} +3 -3
  14. package/dist/assets/{Plugins-0Pf0OZ4l.js → Plugins-Bc_W3IyR.js} +2 -2
  15. package/dist/assets/ProvenanceBadge-DiKAUR1u.js +1 -0
  16. package/dist/assets/RemoteMachines-8_77-WPD.js +3 -0
  17. package/dist/assets/{SaveBar-DjijiUb0.js → SaveBar-Blpzdq1R.js} +1 -1
  18. package/dist/assets/{Scheduler-Cm3EXZvE.js → Scheduler-Bd70AM4X.js} +9 -9
  19. package/dist/assets/{ScopeSwitcher-B-P-kSfq.js → ScopeSwitcher-wxN0h4YW.js} +1 -1
  20. package/dist/assets/Settings-CQ7DA3zW.js +4 -0
  21. package/dist/assets/{SkillReferenceGraph-Epv2GJmj.js → SkillReferenceGraph-DH1NLOiS.js} +1 -1
  22. package/dist/assets/Skills-CmyRyu4_.js +2 -0
  23. package/dist/assets/SystemPrompt-KAc3UMCd.js +1 -0
  24. package/dist/assets/TagLibrary-C8EvHnpg.js +1 -0
  25. package/dist/assets/{TiptapBody-DAMO3DhO.js → TiptapBody-d423mH6D.js} +1 -1
  26. package/dist/assets/{Toggle-Ba_f7q_m.js → Toggle-D1wsGE9S.js} +1 -1
  27. package/dist/assets/{ViewTabs-CGX6MAhc.js → ViewTabs-CjHw3kGY.js} +1 -1
  28. package/dist/assets/{historyTotals-vgfk8EOL.js → historyTotals-DFHzqLt7.js} +1 -1
  29. package/dist/assets/{index-CPieAFsl.js → index-Ci1u018F.js} +266 -266
  30. package/dist/assets/{settingsSchema-D0FxNrTy.js → settingsSchema-Ctf3pZVI.js} +1 -1
  31. package/dist/assets/{useAgentsDirWatch-DCu6BNYN.js → useAgentsDirWatch-B1NBmOAe.js} +1 -1
  32. package/dist/assets/{useRemotePeers-D4cdJDyh.js → useRemotePeers-BHjSJs9D.js} +1 -1
  33. package/dist/index.html +1 -1
  34. package/package.json +3 -2
  35. package/plugins/CLAUDE.md +5 -8
  36. package/plugins/session-manager-dev/.claude-plugin/plugin.json +3 -6
  37. package/plugins/session-manager-dev/skills/builder/1-classify-and-bump/SKILL.md +2 -2
  38. package/plugins/session-manager-dev/skills/builder/SKILL.md +2 -3
  39. package/plugins/session-manager-dev/skills/develop/SKILL.md +1 -1
  40. package/plugins/session-manager-dev/skills/develop/standards.md +3 -3
  41. package/plugins/session-manager-dev/skills/send-feedback/SKILL.md +13 -0
  42. package/scripts/README.md +3 -3
  43. package/scripts/audit-ops-hygiene.cjs +4 -4
  44. package/scripts/hooks/guard-destructive-git.cjs +4 -4
  45. package/scripts/hooks/guard-inline-implementation.cjs +1 -1
  46. package/scripts/hooks/guard-prd-writes.cjs +2 -2
  47. package/scripts/hooks/lib/guard-destructive-git-policy.cjs +1 -1
  48. package/scripts/mint-epic.cjs +2 -2
  49. package/scripts/scheduler-mcp-server.cjs +27 -9
  50. package/src/main/agentLibrary.cjs +5 -5
  51. package/src/main/agentsIpc.cjs +76 -0
  52. package/src/main/build-info.json +4 -4
  53. package/src/main/chatRunner.cjs +30 -13
  54. package/src/main/config.cjs +20 -3
  55. package/src/main/crashDiagnostics.cjs +2 -2
  56. package/src/main/docEdit.cjs +5 -5
  57. package/src/main/files.cjs +2 -2
  58. package/src/main/git.cjs +1 -1
  59. package/src/main/health.cjs +20 -18
  60. package/src/main/heapSnapshot.cjs +1 -1
  61. package/src/main/historyAggregator.cjs +2 -2
  62. package/src/main/index.cjs +50 -132
  63. package/src/main/ipcSchemas.cjs +13 -10
  64. package/src/main/lib/CLAUDE.md +48 -0
  65. package/src/main/lib/activeSessions.cjs +14 -1
  66. package/src/main/lib/classifyPromptTicket.cjs +2 -2
  67. package/src/main/lib/{agentModelResolve.cjs → claude/agentModelResolve.cjs} +7 -7
  68. package/src/main/lib/{claudeBin.cjs → claude/claudeBin.cjs} +4 -4
  69. package/src/main/lib/{effectiveModelInfo.cjs → claude/effectiveModelInfo.cjs} +9 -9
  70. package/src/main/lib/{modelCatalog.cjs → claude/modelCatalog.cjs} +3 -3
  71. package/src/main/lib/claude/rateLimitDetect.cjs +54 -0
  72. package/src/main/lib/{rateLimitWindow.cjs → claude/rateLimitWindow.cjs} +24 -12
  73. package/src/main/lib/{runClaudeP.cjs → claude/runClaudeP.cjs} +1 -1
  74. package/src/main/lib/credentials.cjs +18 -92
  75. package/src/main/lib/cwdClassify.cjs +1 -1
  76. package/src/main/lib/{activeIndexMerge.cjs → epic/activeIndexMerge.cjs} +3 -3
  77. package/src/main/lib/{activeIndexRebuild.cjs → epic/activeIndexRebuild.cjs} +1 -1
  78. package/src/main/lib/{delegationReadiness.cjs → epic/delegationReadiness.cjs} +21 -29
  79. package/src/main/lib/{epicContextDigest.cjs → epic/epicContextDigest.cjs} +1 -1
  80. package/src/main/lib/{epicDelegationStats.cjs → epic/epicDelegationStats.cjs} +2 -2
  81. package/src/main/lib/{epicMint.cjs → epic/epicMint.cjs} +11 -11
  82. package/src/main/lib/{epicSpawnPlan.cjs → epic/epicSpawnPlan.cjs} +3 -3
  83. package/src/main/lib/{epicStatusMirror.cjs → epic/epicStatusMirror.cjs} +2 -2
  84. package/src/main/lib/{epicTranscriptDiagnostic.cjs → epic/epicTranscriptDiagnostic.cjs} +2 -2
  85. package/src/main/lib/{epicTranscriptPath.cjs → epic/epicTranscriptPath.cjs} +2 -2
  86. package/src/main/lib/{epicValidationHook.cjs → epic/epicValidationHook.cjs} +3 -3
  87. package/src/main/lib/{epicWorktreeBoot.cjs → epic/epicWorktreeBoot.cjs} +1 -1
  88. package/src/main/lib/{epicWorktreeMerge.cjs → epic/epicWorktreeMerge.cjs} +3 -3
  89. package/src/main/lib/{epicWorktreeMint.cjs → epic/epicWorktreeMint.cjs} +3 -3
  90. package/src/main/lib/{epicWorktreeProjectConfig.cjs → epic/epicWorktreeProjectConfig.cjs} +4 -4
  91. package/src/main/lib/{promptSessionsCreateEpic.cjs → epic/promptSessionsCreateEpic.cjs} +4 -4
  92. package/src/main/lib/{crossProjectFeedback.cjs → feedback-remote/crossProjectFeedback.cjs} +114 -16
  93. package/src/main/lib/{customerFeedbackClient.cjs → feedback-remote/customerFeedbackClient.cjs} +3 -3
  94. package/src/main/lib/{customerFeedbackInbox.cjs → feedback-remote/customerFeedbackInbox.cjs} +2 -2
  95. package/src/main/lib/{customerFeedbackIpc.cjs → feedback-remote/customerFeedbackIpc.cjs} +1 -1
  96. package/src/main/lib/feedback-remote/humanPromptLedger.cjs +93 -0
  97. package/src/main/lib/{localAdminHttp.cjs → feedback-remote/localAdminHttp.cjs} +2 -2
  98. package/src/main/lib/{macroAdminRoutes.cjs → feedback-remote/macroAdminRoutes.cjs} +1 -1
  99. package/src/main/lib/{projectHomeAdminRoutes.cjs → feedback-remote/projectHomeAdminRoutes.cjs} +4 -4
  100. package/src/main/lib/{relayClientAuth.cjs → feedback-remote/relayClientAuth.cjs} +2 -2
  101. package/src/main/lib/{remoteClientSessions.cjs → feedback-remote/remoteClientSessions.cjs} +1 -1
  102. package/src/main/lib/{gitWorktree.cjs → git/gitWorktree.cjs} +7 -7
  103. package/src/main/lib/historyRollup.cjs +1 -1
  104. package/src/main/lib/importReferences.cjs +1 -1
  105. package/src/main/lib/machineProfile.cjs +1 -1
  106. package/src/main/lib/mcpToolCatalog.cjs +9 -3
  107. package/src/main/lib/openExternalApp.cjs +1 -1
  108. package/src/main/lib/opsOwnership.cjs +3 -3
  109. package/src/main/lib/{agentPersonaSchema.cjs → persona-macro/agentPersonaSchema.cjs} +2 -2
  110. package/src/main/lib/{macroLibrary.cjs → persona-macro/macroLibrary.cjs} +5 -5
  111. package/src/main/lib/{personaMerge.cjs → persona-macro/personaMerge.cjs} +4 -4
  112. package/src/main/lib/{depSlugResolve.cjs → prd/depSlugResolve.cjs} +16 -1
  113. package/src/main/lib/{prdAdminRoutes.cjs → prd/prdAdminRoutes.cjs} +7 -7
  114. package/src/main/lib/{prdAgentType.cjs → prd/prdAgentType.cjs} +3 -3
  115. package/src/main/lib/{prdCreate.cjs → prd/prdCreate.cjs} +12 -12
  116. package/src/main/lib/{prdDeclaredPaths.cjs → prd/prdDeclaredPaths.cjs} +1 -1
  117. package/src/main/lib/{prdGateFiles.cjs → prd/prdGateFiles.cjs} +1 -1
  118. package/src/main/lib/{prdLocations.cjs → prd/prdLocations.cjs} +2 -2
  119. package/src/main/lib/{prdMigration.cjs → prd/prdMigration.cjs} +3 -3
  120. package/src/main/lib/prereqs.cjs +2 -2
  121. package/src/main/lib/{instanceLock.cjs → process/instanceLock.cjs} +4 -11
  122. package/src/main/lib/{pidAlive.cjs → process/pidAlive.cjs} +1 -1
  123. package/src/main/lib/{procName.cjs → process/procName.cjs} +2 -2
  124. package/src/main/lib/{timeoutShim.cjs → process/timeoutShim.cjs} +1 -1
  125. package/src/main/lib/projectRootResolve.cjs +1 -1
  126. package/src/main/lib/promptSessionSchema.cjs +1 -1
  127. package/src/main/lib/{definitionOfDone.cjs → scheduler/definitionOfDone.cjs} +6 -12
  128. package/src/main/lib/scheduler/finalizeReason.cjs +30 -0
  129. package/src/main/lib/{fixChainDepth.cjs → scheduler/fixChainDepth.cjs} +1 -1
  130. package/src/main/lib/scheduler/flatSweepThrottle.cjs +17 -0
  131. package/src/main/lib/{jobDirtFilter.cjs → scheduler/jobDirtFilter.cjs} +1 -1
  132. package/src/main/lib/{jobSupervisorRecord.cjs → scheduler/jobSupervisorRecord.cjs} +1 -1
  133. package/src/main/lib/{launchFailure.cjs → scheduler/launchFailure.cjs} +2 -2
  134. package/src/main/lib/{queueStore.cjs → scheduler/queueStore.cjs} +6 -6
  135. package/src/main/lib/{quietMachineLease.cjs → scheduler/quietMachineLease.cjs} +1 -1
  136. package/src/main/lib/{rcaReport.cjs → scheduler/rcaReport.cjs} +4 -4
  137. package/src/main/lib/{reaperHelpers.cjs → scheduler/reaperHelpers.cjs} +3 -3
  138. package/src/main/lib/{reservationExpiry.cjs → scheduler/reservationExpiry.cjs} +4 -11
  139. package/src/main/lib/{reviewNotice.cjs → scheduler/reviewNotice.cjs} +1 -1
  140. package/src/main/lib/{runLogRetention.cjs → scheduler/runLogRetention.cjs} +34 -13
  141. package/src/main/lib/{scheduleJobTransitions.cjs → scheduler/scheduleJobTransitions.cjs} +3 -3
  142. package/src/main/lib/{schedulerBatch.cjs → scheduler/schedulerBatch.cjs} +9 -13
  143. package/src/main/lib/{schedulerConfig.cjs → scheduler/schedulerConfig.cjs} +1 -1
  144. package/src/main/lib/{schedulerRuntimeState.cjs → scheduler/schedulerRuntimeState.cjs} +1 -1
  145. package/src/main/lib/{sessionSlots.cjs → scheduler/sessionSlots.cjs} +2 -2
  146. package/src/main/lib/{upgradeDrain.cjs → scheduler/upgradeDrain.cjs} +8 -11
  147. package/src/main/lib/{watchdogHelpers.cjs → scheduler/watchdogHelpers.cjs} +5 -19
  148. package/src/main/lib/{auditLog.cjs → telemetry/auditLog.cjs} +1 -1
  149. package/src/main/lib/{opsErrorLog.cjs → telemetry/opsErrorLog.cjs} +4 -4
  150. package/src/main/lib/{telemetryBacklog.cjs → telemetry/telemetryBacklog.cjs} +4 -4
  151. package/src/main/lib/{telemetryBoot.cjs → telemetry/telemetryBoot.cjs} +1 -1
  152. package/src/main/lib/{telemetryClient.cjs → telemetry/telemetryClient.cjs} +12 -8
  153. package/src/main/lib/{telemetrySettings.cjs → telemetry/telemetrySettings.cjs} +1 -1
  154. package/src/main/lib/{atomicFs.cjs → util/atomicFs.cjs} +42 -0
  155. package/src/main/lib/{loopDelay.cjs → util/loopDelay.cjs} +1 -1
  156. package/src/main/logs.cjs +1 -1
  157. package/src/main/mcpStatus.cjs +2 -2
  158. package/src/main/memoryAggregate.cjs +3 -3
  159. package/src/main/memoryTool.cjs +1 -1
  160. package/src/main/otel.cjs +2 -2
  161. package/src/main/pluginInstall.cjs +29 -3
  162. package/src/main/projectBrief.cjs +6 -6
  163. package/src/main/projectPages.cjs +1 -1
  164. package/src/main/promptSessionEvents.cjs +2 -2
  165. package/src/main/pty.cjs +7 -7
  166. package/src/main/queueOps.cjs +6 -6
  167. package/src/main/remoteClient.cjs +4 -4
  168. package/src/main/remoteClientIpc.cjs +1 -1
  169. package/src/main/runVerify.cjs +6 -3
  170. package/src/main/scheduler/CLAUDE.md +26 -0
  171. package/src/main/scheduler/budget.cjs +576 -0
  172. package/src/main/scheduler/gitTreeGuard.cjs +672 -0
  173. package/src/main/scheduler/prdParser.cjs +4 -4
  174. package/src/main/scheduler/prdPaths.cjs +487 -0
  175. package/src/main/scheduler/reviewLadder.cjs +1011 -0
  176. package/src/main/scheduler/starvation.cjs +390 -0
  177. package/src/main/scheduler.cjs +331 -3320
  178. package/src/main/seedAgentPersonas.cjs +5 -5
  179. package/src/main/seedDevPlugin.cjs +70 -3
  180. package/src/main/seedSchedulerMcp.cjs +2 -2
  181. package/src/main/supervisor.cjs +50 -27
  182. package/src/main/telemetryIpc.cjs +51 -0
  183. package/src/main/transcripts.cjs +3 -3
  184. package/src/main/updaterIpc.cjs +1 -1
  185. package/src/main/usage.cjs +1 -1
  186. package/src/main/watchers.cjs +1 -1
  187. package/src/main/webRemote.cjs +22 -7
  188. package/src/preload/api.d.ts +14 -8
  189. package/src/preload/index.cjs +9 -3
  190. package/dist/assets/ProvenanceBadge-vC7Tj-JP.js +0 -1
  191. package/dist/assets/RemoteMachines-CWnKbFHc.js +0 -3
  192. package/dist/assets/Settings-DYDlp2m_.js +0 -4
  193. package/dist/assets/Skills-DHO0N0C2.js +0 -2
  194. package/dist/assets/SystemPrompt-DxeNofL9.js +0 -1
  195. package/dist/assets/TagLibrary-QOAs7ISO.js +0 -1
  196. package/plugins/session-manager-dev/skills/blog-for-project-feature/0-select/SKILL.md +0 -39
  197. package/plugins/session-manager-dev/skills/blog-for-project-feature/1-research/SKILL.md +0 -37
  198. package/plugins/session-manager-dev/skills/blog-for-project-feature/2-storyboard/SKILL.md +0 -64
  199. package/plugins/session-manager-dev/skills/blog-for-project-feature/3-capture/SKILL.md +0 -52
  200. package/plugins/session-manager-dev/skills/blog-for-project-feature/4-draft-copy/SKILL.md +0 -37
  201. package/plugins/session-manager-dev/skills/blog-for-project-feature/5-illustrate/SKILL.md +0 -50
  202. package/plugins/session-manager-dev/skills/blog-for-project-feature/6-compose/SKILL.md +0 -51
  203. package/plugins/session-manager-dev/skills/blog-for-project-feature/7-review/SKILL.md +0 -54
  204. package/plugins/session-manager-dev/skills/blog-for-project-feature/SKILL.md +0 -144
  205. package/plugins/session-manager-dev/skills/blog-for-project-feature/feature.config.yaml +0 -90
  206. package/plugins/session-manager-dev/skills/discover-features/SKILL.md +0 -95
  207. package/plugins/session-manager-dev/skills/explain-to-me/SKILL.md +0 -205
  208. package/plugins/session-manager-dev/skills/explain-to-me/assets/style-reference.html +0 -163
  209. package/plugins/session-manager-dev/skills/find-opportunity/SKILL.md +0 -83
  210. package/plugins/session-manager-dev/skills/issue-address/0-select/0-fetch-pool/SKILL.md +0 -38
  211. package/plugins/session-manager-dev/skills/issue-address/0-select/1-reject-fixed/SKILL.md +0 -64
  212. package/plugins/session-manager-dev/skills/issue-address/0-select/2-reject-claimed/SKILL.md +0 -71
  213. package/plugins/session-manager-dev/skills/issue-address/0-select/3-rank-impact/SKILL.md +0 -39
  214. package/plugins/session-manager-dev/skills/issue-address/0-select/SKILL.md +0 -75
  215. package/plugins/session-manager-dev/skills/issue-address/1-confirm-open/SKILL.md +0 -39
  216. package/plugins/session-manager-dev/skills/issue-address/2-claim/SKILL.md +0 -57
  217. package/plugins/session-manager-dev/skills/issue-address/3-reproduce/SKILL.md +0 -40
  218. package/plugins/session-manager-dev/skills/issue-address/4-fix/SKILL.md +0 -33
  219. package/plugins/session-manager-dev/skills/issue-address/5-verify/SKILL.md +0 -40
  220. package/plugins/session-manager-dev/skills/issue-address/SKILL.md +0 -120
  221. package/plugins/session-manager-dev/skills/local-project-health/SKILL.md +0 -58
  222. package/plugins/session-manager-dev/skills/memory-sanitation/SKILL.md +0 -147
  223. package/plugins/session-manager-dev/skills/ops-sweep/SKILL.md +0 -137
  224. package/plugins/session-manager-dev/skills/pr-review-sweep/0-fetch/SKILL.md +0 -41
  225. package/plugins/session-manager-dev/skills/pr-review-sweep/1-classify/SKILL.md +0 -56
  226. package/plugins/session-manager-dev/skills/pr-review-sweep/2-check-fixed/SKILL.md +0 -49
  227. package/plugins/session-manager-dev/skills/pr-review-sweep/3-queue/SKILL.md +0 -57
  228. package/plugins/session-manager-dev/skills/pr-review-sweep/4-land-and-resolve/SKILL.md +0 -60
  229. package/plugins/session-manager-dev/skills/pr-review-sweep/SKILL.md +0 -124
  230. package/plugins/session-manager-dev/skills/pr-signal/SKILL.md +0 -67
  231. package/plugins/session-manager-dev/skills/project-status/SKILL.md +0 -243
  232. package/plugins/session-manager-dev/skills/requesting-code-review/SKILL.md +0 -98
  233. package/plugins/session-manager-dev/skills/requesting-code-review/code-reviewer.md +0 -146
  234. package/src/main/lib/rateLimitDetect.cjs +0 -35
  235. /package/src/main/lib/{agentEffortResolve.cjs → claude/agentEffortResolve.cjs} +0 -0
  236. /package/src/main/lib/{claudeCliCaps.cjs → claude/claudeCliCaps.cjs} +0 -0
  237. /package/src/main/lib/{usageCircuit.cjs → claude/usageCircuit.cjs} +0 -0
  238. /package/src/main/lib/{epicSpawnCwd.cjs → epic/epicSpawnCwd.cjs} +0 -0
  239. /package/src/main/lib/{customerFeedbackAdminRoutes.cjs → feedback-remote/customerFeedbackAdminRoutes.cjs} +0 -0
  240. /package/src/main/lib/{remoteE2eCrypto.cjs → feedback-remote/remoteE2eCrypto.cjs} +0 -0
  241. /package/src/main/lib/{branchSweep.cjs → git/branchSweep.cjs} +0 -0
  242. /package/src/main/lib/{gitExec.cjs → git/gitExec.cjs} +0 -0
  243. /package/src/main/lib/{jobWorktree.cjs → git/jobWorktree.cjs} +0 -0
  244. /package/src/main/lib/{jobWorktreeBootLive.cjs → git/jobWorktreeBootLive.cjs} +0 -0
  245. /package/src/main/lib/{jobWorktreeTerminalOrphanLive.cjs → git/jobWorktreeTerminalOrphanLive.cjs} +0 -0
  246. /package/src/main/lib/{builtinMacros.cjs → persona-macro/builtinMacros.cjs} +0 -0
  247. /package/src/main/lib/{personaImportHealth.cjs → persona-macro/personaImportHealth.cjs} +0 -0
  248. /package/src/main/lib/{shippedPersonaSeeds.cjs → persona-macro/shippedPersonaSeeds.cjs} +0 -0
  249. /package/src/main/lib/{planValidator.cjs → prd/planValidator.cjs} +0 -0
  250. /package/src/main/lib/{prdAuthoringSeed.cjs → prd/prdAuthoringSeed.cjs} +0 -0
  251. /package/src/main/lib/{prdDisposition.cjs → prd/prdDisposition.cjs} +0 -0
  252. /package/src/main/lib/{prdFrontmatter.cjs → prd/prdFrontmatter.cjs} +0 -0
  253. /package/src/main/lib/{prdSizing.cjs → prd/prdSizing.cjs} +0 -0
  254. /package/src/main/lib/{workTypeLibrary.cjs → prd/workTypeLibrary.cjs} +0 -0
  255. /package/src/main/lib/{childWithLog.cjs → process/childWithLog.cjs} +0 -0
  256. /package/src/main/lib/{cleanEnv.cjs → process/cleanEnv.cjs} +0 -0
  257. /package/src/main/lib/{defaultShell.cjs → process/defaultShell.cjs} +0 -0
  258. /package/src/main/lib/{killTree.cjs → process/killTree.cjs} +0 -0
  259. /package/src/main/lib/{loginShellPath.cjs → process/loginShellPath.cjs} +0 -0
  260. /package/src/main/lib/{procIdentity.cjs → process/procIdentity.cjs} +0 -0
  261. /package/src/main/lib/{singleInstanceGuard.cjs → process/singleInstanceGuard.cjs} +0 -0
  262. /package/src/main/lib/{smProcNames.cjs → process/smProcNames.cjs} +0 -0
  263. /package/src/main/lib/{timeoutShimScript.cjs → process/timeoutShimScript.cjs} +0 -0
  264. /package/src/main/lib/{winSpawn.cjs → process/winSpawn.cjs} +0 -0
  265. /package/src/main/lib/{adoptedRunSupervisor.cjs → scheduler/adoptedRunSupervisor.cjs} +0 -0
  266. /package/src/main/lib/{dispatchLoop.cjs → scheduler/dispatchLoop.cjs} +0 -0
  267. /package/src/main/lib/{dodDrainHook.cjs → scheduler/dodDrainHook.cjs} +0 -0
  268. /package/src/main/lib/{fixPlanSlug.cjs → scheduler/fixPlanSlug.cjs} +0 -0
  269. /package/src/main/lib/{gateAuthority.cjs → scheduler/gateAuthority.cjs} +0 -0
  270. /package/src/main/lib/{landedSinceRun.cjs → scheduler/landedSinceRun.cjs} +0 -0
  271. /package/src/main/lib/{loadGate.cjs → scheduler/loadGate.cjs} +0 -0
  272. /package/src/main/lib/{needsReviewLedger.cjs → scheduler/needsReviewLedger.cjs} +0 -0
  273. /package/src/main/lib/{queueHealth.cjs → scheduler/queueHealth.cjs} +0 -0
  274. /package/src/main/lib/{queueHistory.cjs → scheduler/queueHistory.cjs} +0 -0
  275. /package/src/main/lib/{scheduleJobSchema.cjs → scheduler/scheduleJobSchema.cjs} +0 -0
  276. /package/src/main/lib/{schedulerPaths.cjs → scheduler/schedulerPaths.cjs} +0 -0
  277. /package/src/main/lib/{terminalRunOutcome.cjs → scheduler/terminalRunOutcome.cjs} +0 -0
  278. /package/src/main/lib/{validationSentinels.cjs → scheduler/validationSentinels.cjs} +0 -0
  279. /package/src/main/lib/{crashTelemetry.cjs → telemetry/crashTelemetry.cjs} +0 -0
  280. /package/src/main/lib/{otlpTraceExporter.cjs → telemetry/otlpTraceExporter.cjs} +0 -0
  281. /package/src/main/lib/{telemetryConsent.cjs → telemetry/telemetryConsent.cjs} +0 -0
  282. /package/src/main/lib/{telemetryCounters.cjs → telemetry/telemetryCounters.cjs} +0 -0
  283. /package/src/main/lib/{encodeCwd.cjs → util/encodeCwd.cjs} +0 -0
  284. /package/src/main/lib/{expandHome.cjs → util/expandHome.cjs} +0 -0
  285. /package/src/main/lib/{extractJson.cjs → util/extractJson.cjs} +0 -0
  286. /package/src/main/lib/{fileTail.cjs → util/fileTail.cjs} +0 -0
  287. /package/src/main/lib/{headTailBuffer.cjs → util/headTailBuffer.cjs} +0 -0
  288. /package/src/main/lib/{kebabCase.cjs → util/kebabCase.cjs} +0 -0
  289. /package/src/main/lib/{lruCache.cjs → util/lruCache.cjs} +0 -0
  290. /package/src/main/lib/{withTimeout.cjs → util/withTimeout.cjs} +0 -0
@@ -33,7 +33,7 @@
33
33
  * rather than a second hardcoded literal — this file matches git-porcelain
34
34
  * RELATIVE paths, never builds an fs path, so opsPath() itself doesn't apply.
35
35
  */
36
- const { OPS_ROOT_DIR: OPS_ROOT_SEGMENT } = require('./opsOwnership.cjs');
36
+ const { OPS_ROOT_DIR: OPS_ROOT_SEGMENT } = require('../opsOwnership.cjs');
37
37
 
38
38
  /** True when `p` lives under an app-owned operations root. Pure. */
39
39
  function isAppOwnedChurn(p) {
@@ -20,7 +20,7 @@
20
20
  const fs = require('node:fs');
21
21
  const path = require('node:path');
22
22
  const { writeJsonAtomicSync } = require('./queueStore.cjs');
23
- const { isDifferentProcess } = require('./procIdentity.cjs');
23
+ const { isDifferentProcess } = require('../process/procIdentity.cjs');
24
24
 
25
25
  const SUFFIX = '.supervisor.json';
26
26
  const META_SUFFIX = '.meta.json';
@@ -39,8 +39,8 @@
39
39
 
40
40
  const fs = require('node:fs');
41
41
  const path = require('node:path');
42
- const { readTail } = require('./fileTail.cjs');
43
- const atomicFs = require('./atomicFs.cjs');
42
+ const { readTail } = require('../util/fileTail.cjs');
43
+ const atomicFs = require('../util/atomicFs.cjs');
44
44
 
45
45
  const LAUNCH_FAILURE_KINDS = Object.freeze({
46
46
  /** HTTP 400 naming a thinking/effort/config parameter the model rejects — the issue-#11 signature. */
@@ -32,9 +32,9 @@ const fs = require('node:fs');
32
32
  const fsp = require('node:fs/promises');
33
33
  const path = require('node:path');
34
34
  const crypto = require('node:crypto');
35
- const { allProjectCwds, activeProjectCwds, bustProjectCwdCache } = require('./activeSessions.cjs');
36
- const { classifyCwd } = require('./cwdClassify.cjs');
37
- const { assertOpsWrite, resolveOpsRoot, OPS_ROOT_DIR } = require('./opsOwnership.cjs');
35
+ const { allProjectCwds, activeProjectCwds, bustProjectCwdCache } = require('../activeSessions.cjs');
36
+ const { classifyCwd } = require('../cwdClassify.cjs');
37
+ const { assertOpsWrite, resolveOpsRoot, OPS_ROOT_DIR } = require('../opsOwnership.cjs');
38
38
  const { ScheduleJobSchema } = require('./scheduleJobSchema.cjs');
39
39
  const schedulerPaths = require('./schedulerPaths.cjs');
40
40
 
@@ -238,11 +238,11 @@ function shapeMachine(data) {
238
238
  // classifyQueueStarvation's header for why the two must never merge.
239
239
  lastDispatchAttemptAt: data.lastDispatchAttemptAt ?? null,
240
240
  paused: data.paused ?? null,
241
- // Upgrade-drain state (lib/upgradeDrain.cjs): deliberately NOT part of
241
+ // Upgrade-drain state (lib/scheduler/upgradeDrain.cjs): deliberately NOT part of
242
242
  // `paused`, so a rate-limit pause can neither overwrite it nor have the
243
243
  // manual-clear cooldown swallow it.
244
244
  drain: data.drain && typeof data.drain === 'object' ? data.drain : null,
245
- // Launch circuit breaker (lib/launchFailure.cjs): per-persona blocks and
245
+ // Launch circuit breaker (lib/scheduler/launchFailure.cjs): per-persona blocks and
246
246
  // the degraded-mode env a persona is currently launching with. Machine
247
247
  // state, not per-project: the broken thing is the installed CLI.
248
248
  launchBlocks: data.launchBlocks && typeof data.launchBlocks === 'object' ? data.launchBlocks : {},
@@ -315,7 +315,7 @@ const PAUSED_HINT_RE = /"paused"|resumeAt/;
315
315
 
316
316
  function logMachineStateRecovery({ level, message, meta }) {
317
317
  try {
318
- const { appendError } = require('./opsErrorLog.cjs');
318
+ const { appendError } = require('../telemetry/opsErrorLog.cjs');
319
319
  appendError({ cwd: schedulerPaths.machineStateLogCwd(), scope: 'scheduler', level, message, meta });
320
320
  } catch { /* durable logging must never block recovery */ }
321
321
  console.error(`[queueStore] ${message}`);
@@ -12,7 +12,7 @@
12
12
  */
13
13
  'use strict';
14
14
 
15
- const { appendAuditEvent } = require('./auditLog.cjs');
15
+ const { appendAuditEvent } = require('../telemetry/auditLog.cjs');
16
16
  const { isProvablyDead, DEFAULT_GRACE_MS } = require('./reservationExpiry.cjs');
17
17
 
18
18
  // slug of the job currently holding the lease, or null.
@@ -32,10 +32,10 @@
32
32
 
33
33
  const fs = require('node:fs');
34
34
  const path = require('node:path');
35
- const { splitFrontmatter } = require('./prdFrontmatter.cjs');
36
- const { readTail } = require('./fileTail.cjs');
37
- const { resolvePrdWriteDir } = require('./prdLocations.cjs');
38
- const atomicFs = require('./atomicFs.cjs');
35
+ const { splitFrontmatter } = require('../prd/prdFrontmatter.cjs');
36
+ const { readTail } = require('../util/fileTail.cjs');
37
+ const { resolvePrdWriteDir } = require('../prd/prdLocations.cjs');
38
+ const atomicFs = require('../util/atomicFs.cjs');
39
39
 
40
40
  // ─── VERDICT_LABELS — deliberate duplicate ──────────────────────────────────
41
41
  // Mirrors src/renderer/components/tabs/scheduler/sched-primitives.tsx:123-131.
@@ -9,9 +9,9 @@
9
9
 
10
10
  const fs = require('node:fs');
11
11
  const path = require('node:path');
12
- const { readTail } = require('./fileTail.cjs');
13
- const { detectRateLimitInLog } = require('./rateLimitDetect.cjs');
14
- const { pidAlive } = require('./pidAlive.cjs');
12
+ const { readTail } = require('../util/fileTail.cjs');
13
+ const { detectRateLimitInLog } = require('../claude/rateLimitDetect.cjs');
14
+ const { pidAlive } = require('../process/pidAlive.cjs');
15
15
 
16
16
  /**
17
17
  * Return true if pid is alive AND its cmdline looks like a claude process.
@@ -9,27 +9,20 @@
9
9
  */
10
10
  'use strict';
11
11
 
12
- const { pidAlive } = require('./pidAlive.cjs');
12
+ const { pidAlive } = require('../process/pidAlive.cjs');
13
13
 
14
14
  const DEFAULT_GRACE_MS = 10 * 60 * 1000;
15
15
 
16
- // Thin alias over pidAlive.cjs's shared pidAlive() — kept as its own named
17
- // export (rather than inlining the require at every call site) so existing
18
- // imports of `defaultPidAlive` from this module keep working unchanged.
19
- function defaultPidAlive(pid) {
20
- return pidAlive(pid);
21
- }
22
-
23
16
  /**
24
17
  * @param {{ claimedAt: number, pid: number|null }} res
25
18
  * @param {{ live: boolean, pidAlive?: (pid:number)=>boolean, now: number, graceMs?: number }} ctx
26
19
  */
27
- function isProvablyDead(res, { live, pidAlive = defaultPidAlive, now, graceMs = DEFAULT_GRACE_MS }) {
20
+ function isProvablyDead(res, { live, pidAlive: isAlive = pidAlive, now, graceMs = DEFAULT_GRACE_MS }) {
28
21
  if (live) return false;
29
22
  // Made after the pass began (i.e. this tick) — never expire it.
30
23
  if (!Number.isFinite(res.claimedAt) || res.claimedAt > now) return false;
31
- if (Number.isInteger(res.pid) && res.pid > 0) return !pidAlive(res.pid);
24
+ if (Number.isInteger(res.pid) && res.pid > 0) return !isAlive(res.pid);
32
25
  return now - res.claimedAt > graceMs;
33
26
  }
34
27
 
35
- module.exports = { isProvablyDead, defaultPidAlive, DEFAULT_GRACE_MS };
28
+ module.exports = { isProvablyDead, DEFAULT_GRACE_MS };
@@ -43,7 +43,7 @@ const DEFAULT_HOLD_MINUTES = 240;
43
43
  // `NN-`) — reused here, not reimplemented, so formatReviewNotice's "blocks"
44
44
  // wording can never disagree with what actually holds a dependent `pending`
45
45
  // row in the real queue.
46
- const { bareSlug } = require('./depSlugResolve.cjs');
46
+ const { bareSlug } = require('../prd/depSlugResolve.cjs');
47
47
 
48
48
  /**
49
49
  * buildReviewNotice({ job, report, epicId, now, prior }) → ReviewNotice
@@ -1,8 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * runLogRetention.cjs — computes (and, only when explicitly opted in,
5
- * applies) a retention policy over `scheduled-plans/runs/`.
4
+ * runLogRetention.cjs — computes and applies a retention policy over `scheduled-plans/runs/`.
6
5
  *
7
6
  * That directory is a machine-level Session-Manager runtime artifact store
8
7
  * (execution logs of the scheduler's own `claude -p` runs), not anything
@@ -26,10 +25,10 @@
26
25
  * slug's own files.
27
26
  *
28
27
  * SAFETY MODEL (the point of this module — see the PRD that added it):
29
- * - Nothing is ever deleted unless the caller passes settings with
30
- * `schedulerRunLogRetention.enabled === true` AND a non-empty policy.
31
- * Everywhere else (computeReport, and applyRetention with no opt-in)
32
- * this module only READS the filesystem.
28
+ * - Retention is ON by default (DEFAULT_RUN_LOG_RETENTION) when settings
29
+ * carry no `schedulerRunLogRetention`. An explicit `enabled: false` (or a
30
+ * config with no non-empty policy) opts out: computeReport, and
31
+ * applyRetention when opted out, only READ the filesystem.
33
32
  * - An entry belonging to a job that is currently live — status `pending`
34
33
  * (queued), `running`, `needs_review`, or `investigating` (the exact
35
34
  * literals scheduler.cjs uses; see LIVE_STATUSES) — is never eligible,
@@ -51,6 +50,16 @@ const schedulerPaths = require('./schedulerPaths.cjs');
51
50
  // checks) — 'completed' and 'failed' are the only terminal ones.
52
51
  const LIVE_STATUSES = new Set(['pending', 'running', 'needs_review', 'investigating']);
53
52
 
53
+ /**
54
+ * Built-in policy applied when settings carry no `schedulerRunLogRetention`:
55
+ * drop runs older than 14 days but always keep each slug's newest 3.
56
+ * (Policy keys follow the module's own names: maxAgeDays / keepPerSlug.)
57
+ */
58
+ const DEFAULT_RUN_LOG_RETENTION = Object.freeze({
59
+ enabled: true,
60
+ policy: Object.freeze({ maxAgeDays: 14, keepPerSlug: 3 }),
61
+ });
62
+
54
63
  const META_SUFFIX = '.meta.json';
55
64
  const DAY_MS = 24 * 60 * 60 * 1000;
56
65
 
@@ -259,11 +268,21 @@ function computeReport(runsDir, policy, opts) {
259
268
  }
260
269
 
261
270
  /**
262
- * True only when settings carry an explicit, well-formed opt-in:
263
- * `schedulerRunLogRetention.enabled === true` plus a non-empty policy.
271
+ * The effective retention config: the caller's `schedulerRunLogRetention`
272
+ * when present, else DEFAULT_RUN_LOG_RETENTION.
264
273
  */
265
- function isRetentionEnabled(settings) {
274
+ function resolveRetentionConfig(settings) {
266
275
  const cfg = settings && settings.schedulerRunLogRetention;
276
+ return cfg == null ? DEFAULT_RUN_LOG_RETENTION : cfg;
277
+ }
278
+
279
+ /**
280
+ * True when the effective config (see resolveRetentionConfig) has
281
+ * `enabled === true` plus a non-empty policy. An absent setting resolves to
282
+ * the default (enabled); an explicit `enabled: false` opts out.
283
+ */
284
+ function isRetentionEnabled(settings) {
285
+ const cfg = resolveRetentionConfig(settings);
267
286
  if (!cfg || cfg.enabled !== true) return false;
268
287
  const policy = cfg.policy;
269
288
  return !!policy && (policy.maxAgeDays != null || policy.keepPerSlug != null);
@@ -372,7 +391,7 @@ function sweepOrphanDirs(runsDir, runningRunIds, errors) {
372
391
  * nothing removed.
373
392
  */
374
393
  function applyRetention(runsDir, settings, opts) {
375
- const cfg = (settings && settings.schedulerRunLogRetention) || null;
394
+ const cfg = resolveRetentionConfig(settings);
376
395
  const policy = (cfg && cfg.policy) || {};
377
396
  const enabled = isRetentionEnabled(settings);
378
397
  const liveKeys = resolveLiveKeysForApply(runsDir, opts, enabled);
@@ -381,7 +400,7 @@ function applyRetention(runsDir, settings, opts) {
381
400
  if (!enabled) {
382
401
  return {
383
402
  deleted: false,
384
- reason: 'dry-run: schedulerRunLogRetention.enabled is not true (or has no policy)',
403
+ reason: 'dry-run: schedulerRunLogRetention is disabled (enabled !== true, or has no policy)',
385
404
  report,
386
405
  };
387
406
  }
@@ -424,8 +443,8 @@ function applyRetention(runsDir, settings, opts) {
424
443
  * applyRetention's own internal queueStore fallback (resolveLiveKeysForApply
425
444
  * above), which exists only as a defensive net for callers who forget to
426
445
  * thread live-job info through, not as this module's primary path. Deletion
427
- * still only happens when the read config carries an explicit
428
- * schedulerRunLogRetention.enabled === true (see isRetentionEnabled).
446
+ * happens unless the read config opts out with
447
+ * schedulerRunLogRetention.enabled === false (see isRetentionEnabled).
429
448
  *
430
449
  * Intended to be called once per app boot (see index.cjs's deferred 30s
431
450
  * startup timer, alongside finalizeClosedDays) — never on its own timer.
@@ -438,6 +457,8 @@ function runBootSweep(opts) {
438
457
  }
439
458
 
440
459
  module.exports = {
460
+ DEFAULT_RUN_LOG_RETENTION,
461
+ resolveRetentionConfig,
441
462
  LIVE_STATUSES,
442
463
  isLiveJob,
443
464
  liveKeysFromJobs,
@@ -30,8 +30,8 @@
30
30
  */
31
31
  'use strict';
32
32
 
33
- const { appendAuditEvent } = require('./auditLog.cjs');
34
- const telemetryCounters = require('./telemetryCounters.cjs');
33
+ const { appendAuditEvent } = require('../telemetry/auditLog.cjs');
34
+ const telemetryCounters = require('../telemetry/telemetryCounters.cjs');
35
35
  const queueHistory = require('./queueHistory.cjs');
36
36
  const { buildNeedsReviewEntryLine, buildNeedsReviewResolutionLine } = require('./needsReviewLedger.cjs');
37
37
 
@@ -42,7 +42,7 @@ const { buildNeedsReviewEntryLine, buildNeedsReviewResolutionLine } = require('.
42
42
  const FINISH_STATUSES = new Set(['completed', 'failed', 'skipped', 'needs_review']);
43
43
 
44
44
  // Bounded so queue.json (mutation cost, broadcast payload, pickNextBatch
45
- // scan) stays small — same rationale as lib/queueHistory.cjs's retention
45
+ // scan) stays small — same rationale as lib/scheduler/queueHistory.cjs's retention
46
46
  // window.
47
47
  const STATUS_HISTORY_CAP = 20;
48
48
 
@@ -15,7 +15,7 @@
15
15
  const path = require('node:path');
16
16
  const os = require('node:os');
17
17
  const { projectJobCap, quietMachineWaitMs } = require('./schedulerConfig.cjs');
18
- const { bareSlug } = require('./depSlugResolve.cjs');
18
+ const { bareSlug, isSatisfiedDepRow } = require('../prd/depSlugResolve.cjs');
19
19
 
20
20
  const DEFAULT_PROJECT_CWD = path.join(os.homedir(), 'Projects', 'session-manager');
21
21
 
@@ -127,20 +127,16 @@ function findUnresolvableDepRoots(projectJobs, satisfiedSlugs = new Set()) {
127
127
 
128
128
  function findBlockingDep(job, projectJobs, satisfiedSlugs = new Set()) {
129
129
  const { rowsForDep, isKnownSatisfied } = makeDepResolver(projectJobs, satisfiedSlugs);
130
- // A dep row is blocking unless it's 'completed', OR it's a 'skipped' row
131
- // stamped `needsReviewAutoResolvedSkip` — the bounded needs_review
132
- // auto-resolve terminal decision (scheduler.cjs's
133
- // applyNeedsReviewAutoResolve). That skip is deliberately NOT the
130
+ // A dep row is blocking unless isSatisfiedDepRow — 'completed', or a
131
+ // `needsReviewAutoResolvedSkip` skip. That skip is deliberately NOT the
134
132
  // "PRD source vanished, a human must author a fresh PRD" skip the
135
- // heldBySkippedDep messaging above describes — it already got every
136
- // bounded chance to resolve itself, so treating it as a permanent
137
- // dependsOn block would defeat the whole point of that auto-resolve pass
138
- // (a chain that never drains without an operator).
139
- const isSatisfiedRow = (dep) => dep.status === 'completed'
140
- || (dep.status === 'skipped' && dep.needsReviewAutoResolvedSkip === true);
133
+ // heldBySkippedDep messaging describes — it already got every bounded
134
+ // chance to resolve itself, so treating it as a permanent dependsOn block
135
+ // would defeat the auto-resolve pass. runVerify.checkDeps MUST use the same
136
+ // predicate, or every run of the dependent is downgraded and re-dispatched.
141
137
  return (job.dependsOn ?? []).find((slug) => {
142
138
  const rows = rowsForDep(slug);
143
- if (rows.length > 0) return rows.some((dep) => !isSatisfiedRow(dep));
139
+ if (rows.length > 0) return rows.some((dep) => !isSatisfiedDepRow(dep));
144
140
  return !isKnownSatisfied(slug);
145
141
  });
146
142
  }
@@ -250,7 +246,7 @@ function pickForProject(projectJobs, runningSlugsInProject, slots, heldSlugs = n
250
246
  // (evaluated before this function is ever called) is the only path that
251
247
  // can fire one, since dispatching one is a whole-tick, all-projects
252
248
  // exclusive decision this per-project function can't see.
253
- // Launch-gate holds (lib/launchFailure.cjs, issue #11): a pending row
249
+ // Launch-gate holds (lib/scheduler/launchFailure.cjs, issue #11): a pending row
254
250
  // whose launch persona is circuit-broken is NOT a candidate this tick and
255
251
  // must not shadow a pickable sibling behind it. It still gets a per-row
256
252
  // hold record so the Queue UI says why it is waiting.
@@ -68,7 +68,7 @@ module.exports = {
68
68
  RECONCILE_SLOW_PASS_MS: 2_000,
69
69
  // Terminal (completed/failed) jobs older than this move from queue.json's
70
70
  // hot jobs[] into the append-only history.jsonl sidecar. See
71
- // src/main/lib/queueHistory.cjs.
71
+ // src/main/lib/scheduler/queueHistory.cjs.
72
72
  HISTORY_RETENTION_MS: 7 * 24 * 60 * 60_000,
73
73
  // Cadence for the in-app intraday refresher that keeps TODAY's History
74
74
  // rollup line current (see historyAggregator.cjs's refreshIntradayToday).
@@ -7,7 +7,7 @@
7
7
  */
8
8
  'use strict';
9
9
 
10
- const { appendAuditEvent } = require('./auditLog.cjs');
10
+ const { appendAuditEvent } = require('../telemetry/auditLog.cjs');
11
11
  const { isProvablyDead, DEFAULT_GRACE_MS } = require('./reservationExpiry.cjs');
12
12
 
13
13
  const investigations = new Map(); // slug -> { claimedAt, pid }
@@ -27,8 +27,8 @@ const crypto = require('node:crypto');
27
27
  const fs = require('node:fs');
28
28
  const path = require('node:path');
29
29
  const { sessionSlotsConfigPath } = require('./schedulerPaths.cjs');
30
- const { appendAuditEvent } = require('./auditLog.cjs');
31
- const atomicFs = require('./atomicFs.cjs');
30
+ const { appendAuditEvent } = require('../telemetry/auditLog.cjs');
31
+ const atomicFs = require('../util/atomicFs.cjs');
32
32
  const { isProvablyDead, DEFAULT_GRACE_MS } = require('./reservationExpiry.cjs');
33
33
 
34
34
  const MIN_SLOTS = 0;
@@ -24,7 +24,7 @@
24
24
  const fs = require('node:fs');
25
25
  const path = require('node:path');
26
26
  const schedulerPaths = require('./schedulerPaths.cjs');
27
- const atomicFs = require('./atomicFs.cjs');
27
+ const atomicFs = require('../util/atomicFs.cjs');
28
28
 
29
29
  // Observed max job run is 240 min; 4 h converts a stuck drain to an abort.
30
30
  const DEFAULT_DRAIN_DEADLINE_MS = 4 * 60 * 60_000;
@@ -32,11 +32,8 @@ const DEFAULT_DRAIN_DEADLINE_MS = 4 * 60 * 60_000;
32
32
  // relaunch is picked up by the watchdog again.
33
33
  const RESTARTING_MARKER_TTL_MS = 5 * 60_000;
34
34
 
35
- function writeJsonAtomicSync(file, value) {
36
- atomicFs.writeJsonAtomicSync(file, value);
37
- }
38
-
39
- function readJsonSafe(file) {
35
+ /** Object-or-null view over atomicFs.readJsonOrSync (arrays/scalars → null). */
36
+ function readJsonObject(file) {
40
37
  const v = atomicFs.readJsonOrSync(file, null);
41
38
  return v && typeof v === 'object' ? v : null;
42
39
  }
@@ -44,7 +41,7 @@ function readJsonSafe(file) {
44
41
  // ---------- request file ----------
45
42
 
46
43
  function readRestartRequest(file = schedulerPaths.restartRequestPath()) {
47
- return readJsonSafe(file);
44
+ return readJsonObject(file);
48
45
  }
49
46
 
50
47
  /**
@@ -60,7 +57,7 @@ function requestRestart({ reason, requestedBy } = {}, { file = schedulerPaths.re
60
57
  requestedBy: typeof requestedBy === 'string' && requestedBy ? requestedBy : 'unknown',
61
58
  requestedAt: new Date(now).toISOString(),
62
59
  };
63
- writeJsonAtomicSync(file, request);
60
+ atomicFs.writeJsonAtomicSync(file, request);
64
61
  return request;
65
62
  }
66
63
 
@@ -69,7 +66,7 @@ function stampDrainCompleted(now = Date.now(), file = schedulerPaths.restartRequ
69
66
  const existing = readRestartRequest(file);
70
67
  if (!existing) return null;
71
68
  const stamped = { ...existing, drainCompletedAt: new Date(now).toISOString() };
72
- writeJsonAtomicSync(file, stamped);
69
+ atomicFs.writeJsonAtomicSync(file, stamped);
73
70
  return stamped;
74
71
  }
75
72
 
@@ -151,7 +148,7 @@ function installedBuildDiffers({ running, installed } = {}) {
151
148
  // ---------- restarting marker (watchdog) ----------
152
149
 
153
150
  function markRestarting({ file = schedulerPaths.restartingMarkerPath(), now = Date.now(), ttlMs = RESTARTING_MARKER_TTL_MS } = {}) {
154
- writeJsonAtomicSync(file, { pid: process.pid, at: now, expiresAt: now + ttlMs });
151
+ atomicFs.writeJsonAtomicSync(file, { pid: process.pid, at: now, expiresAt: now + ttlMs });
155
152
  }
156
153
 
157
154
  function clearRestartingMarker(file = schedulerPaths.restartingMarkerPath()) {
@@ -160,7 +157,7 @@ function clearRestartingMarker(file = schedulerPaths.restartingMarkerPath()) {
160
157
 
161
158
  /** True while the marker exists and has not expired (bounded lifetime). */
162
159
  function isRestartingMarkerActive({ file = schedulerPaths.restartingMarkerPath(), now = Date.now() } = {}) {
163
- const m = readJsonSafe(file);
160
+ const m = readJsonObject(file);
164
161
  return Boolean(m) && typeof m.expiresAt === 'number' && now < m.expiresAt;
165
162
  }
166
163
 
@@ -7,9 +7,9 @@ const fs = require('node:fs');
7
7
  const path = require('node:path');
8
8
  const schedulerPaths = require('./schedulerPaths.cjs');
9
9
  const { isRestartingMarkerActive } = require('./upgradeDrain.cjs');
10
- const { pidAlive: pidAliveCore } = require('./pidAlive.cjs');
11
- const atomicFs = require('./atomicFs.cjs');
12
- const { isPackagedApp } = require('./appRuntime.cjs');
10
+ const { pidAlive } = require('../process/pidAlive.cjs');
11
+ const atomicFs = require('../util/atomicFs.cjs');
12
+ const { isPackagedApp } = require('../appRuntime.cjs');
13
13
 
14
14
 
15
15
 
@@ -142,19 +142,6 @@ function evaluateDispatchLiveness(entry, now = Date.now(), { deadMs = DEFAULT_DI
142
142
  return { dead: true, reason: 'dispatch-dead' };
143
143
  }
144
144
 
145
- /**
146
- * isPidAlive(pid) → boolean
147
- *
148
- * Thin alias over pidAlive.cjs's shared pidAlive() — single source of truth
149
- * for the "is this recorded pid still alive" check used by
150
- * checkAppLiveness's defense-in-depth relaunch gate. Kept as a named export
151
- * here (rather than inlining the require at every call site) so existing
152
- * imports of `isPidAlive` from this module keep working unchanged.
153
- */
154
- function isPidAlive(pid) {
155
- return pidAliveCore(pid);
156
- }
157
-
158
145
  // Offline queue.json reconciliation (orphaned 'running' jobs whose pid died
159
146
  // while Electron wasn't running) used to live here as reconcileQueueOffline().
160
147
  // PRD 686 moved that responsibility into src/main/scheduler.cjs's own boot
@@ -188,7 +175,7 @@ function checkAppLiveness({
188
175
  return { alive: true, reason: 'heartbeat-fresh' };
189
176
  }
190
177
  const last = readLastHeartbeat(heartbeatPath);
191
- if (last !== null && typeof last.pid === 'number' && isPidAlive(last.pid)) {
178
+ if (last !== null && typeof last.pid === 'number' && pidAlive(last.pid)) {
192
179
  return { alive: true, reason: 'pid-alive-heartbeat-stale' };
193
180
  }
194
181
  return { alive: false, reason: 'stale-and-dead' };
@@ -408,7 +395,7 @@ function releaseLock(lockPath) {
408
395
  * dependency fails inside maybeFinalizeHistory's try/catch, not at require
409
396
  * time for the whole watchdog script. */
410
397
  function defaultFinalizeClosedDays(opts) {
411
- const { finalizeClosedDays } = require('../historyAggregator.cjs');
398
+ const { finalizeClosedDays } = require('../../historyAggregator.cjs');
412
399
  return finalizeClosedDays(opts);
413
400
  }
414
401
 
@@ -470,7 +457,6 @@ module.exports = {
470
457
  readLastHeartbeatTs,
471
458
  heartbeatFresh,
472
459
  evaluateDispatchLiveness,
473
- isPidAlive,
474
460
  localDateStr,
475
461
  maybeFinalizeHistory,
476
462
  tryAcquireLock,
@@ -18,7 +18,7 @@
18
18
  const fs = require('node:fs');
19
19
  const path = require('node:path');
20
20
 
21
- const { auditLogPath } = require('./schedulerPaths.cjs');
21
+ const { auditLogPath } = require('../scheduler/schedulerPaths.cjs');
22
22
 
23
23
  /**
24
24
  * Best-effort identity of the process making this call — there is no
@@ -14,8 +14,8 @@
14
14
  const fs = require('node:fs');
15
15
  const os = require('node:os');
16
16
  const path = require('node:path');
17
- const { assertOpsWrite } = require('./opsOwnership.cjs');
18
- const { isEphemeralCwd } = require('./ephemeralCwd.cjs');
17
+ const { assertOpsWrite } = require('../opsOwnership.cjs');
18
+ const { isEphemeralCwd } = require('../ephemeralCwd.cjs');
19
19
 
20
20
  // Same redaction policy as logs.cjs's sanitizeMeta — kept independent (not
21
21
  // shared/required) so this module has no dependency on the Electron `app`
@@ -33,7 +33,7 @@ function sanitizeMeta(meta) {
33
33
  }
34
34
 
35
35
  function logsDir(cwd) {
36
- const { opsPath } = require('./opsOwnership.cjs');
36
+ const { opsPath } = require('../opsOwnership.cjs');
37
37
  return opsPath(cwd, 'logs');
38
38
  }
39
39
 
@@ -108,7 +108,7 @@ function writeLocalLine({ cwd, scope, level, tabId, epicId, tags, message, meta
108
108
  function reportToTelemetry({ cwd, scope, level, tabId, epicId, tags, message }) {
109
109
  try {
110
110
  const telemetryClient = require('./telemetryClient.cjs');
111
- const { projectRootOf } = require('./activeSessions.cjs');
111
+ const { projectRootOf } = require('../activeSessions.cjs');
112
112
  const normalizedCwd = projectRootOf(cwd) || cwd;
113
113
  const autoTags = [
114
114
  `scope:${scope || 'unknown'}`,
@@ -70,7 +70,7 @@ const os = require('node:os');
70
70
  const path = require('node:path');
71
71
  const crypto = require('node:crypto');
72
72
 
73
- const config = require('../config.cjs');
73
+ const config = require('../../config.cjs');
74
74
 
75
75
  const DEFAULT_LIMIT = 500;
76
76
  const RETENTION_DAYS = 30;
@@ -97,9 +97,9 @@ function watermarksPath() {
97
97
 
98
98
  function resolveDeps(deps = {}) {
99
99
  return {
100
- sessionsStore: deps.sessionsStore || require('../sessionsStore.cjs'),
101
- isEphemeralCwd: deps.isEphemeralCwd || require('./ephemeralCwd.cjs').isEphemeralCwd,
102
- resolveProjectContext: deps.resolveProjectContext || require('./projectRootResolve.cjs').resolveProjectContext,
100
+ sessionsStore: deps.sessionsStore || require('../../sessionsStore.cjs'),
101
+ isEphemeralCwd: deps.isEphemeralCwd || require('../ephemeralCwd.cjs').isEphemeralCwd,
102
+ resolveProjectContext: deps.resolveProjectContext || require('../projectRootResolve.cjs').resolveProjectContext,
103
103
  telemetryClient: deps.telemetryClient || require('./telemetryClient.cjs'),
104
104
  opsErrorLog: deps.opsErrorLog || require('./opsErrorLog.cjs'),
105
105
  config: deps.config || config,
@@ -22,7 +22,7 @@ function resolveDeps(deps = {}) {
22
22
  return {
23
23
  telemetrySettings: deps.telemetrySettings || require('./telemetrySettings.cjs'),
24
24
  telemetryClient: deps.telemetryClient || require('./telemetryClient.cjs'),
25
- buildMachineProfile: deps.buildMachineProfile || require('./machineProfile.cjs').buildMachineProfile,
25
+ buildMachineProfile: deps.buildMachineProfile || require('../machineProfile.cjs').buildMachineProfile,
26
26
  telemetryCounters: deps.telemetryCounters || require('./telemetryCounters.cjs'),
27
27
  };
28
28
  }
@@ -20,7 +20,7 @@
20
20
  * returned promise resolves once accepted/dropped, but callers are free to
21
21
  * not await it). Telemetry failing must stay invisible to the user.
22
22
  *
23
- * Single-writer precedent (../lib/instanceLock.cjs): this module assumes the
23
+ * Single-writer precedent (../lib/process/instanceLock.cjs): this module assumes the
24
24
  * app's main process is the only writer of the queue/sent-set files for a
25
25
  * given machine. It does not itself arbitrate multiple OS processes.
26
26
  *
@@ -35,9 +35,9 @@ const os = require('node:os');
35
35
  const path = require('node:path');
36
36
  const crypto = require('node:crypto');
37
37
 
38
- const config = require('../config.cjs');
38
+ const config = require('../../config.cjs');
39
39
  const telemetrySettings = require('./telemetrySettings.cjs');
40
- const machineProfile = require('./machineProfile.cjs');
40
+ const machineProfile = require('../machineProfile.cjs');
41
41
 
42
42
  const MAX_BATCH = 50;
43
43
  const QUEUE_CAP_COUNT = 5000;
@@ -104,7 +104,7 @@ const S = {
104
104
  */
105
105
  function logWarn(message, meta) {
106
106
  try {
107
- const fn = S.logger || require('../logs.cjs').writeLine;
107
+ const fn = S.logger || require('../../logs.cjs').writeLine;
108
108
  fn({ scope: 'telemetry', level: 'warn', message, meta });
109
109
  } catch { /* logs unavailable outside an Electron runtime */ }
110
110
  }
@@ -647,18 +647,20 @@ function describeFailureStatus(status) {
647
647
  return status === 0 ? 'network error' : `HTTP ${status}`;
648
648
  }
649
649
 
650
- function applyFailureBackoff(status) {
650
+ function applyFailureBackoff(status, channel) {
651
651
  if (status === 429 || status === 0 || status >= 500) {
652
652
  S.consecutiveFailures += 1;
653
653
  const ms = Math.min(BACKOFF_BASE_MS * (2 ** (S.consecutiveFailures - 1)), BACKOFF_MAX_MS);
654
654
  S.backoffUntil = Date.now() + ms;
655
655
  S.lastError = { status, message: describeFailureStatus(status), at: Date.now() };
656
+ logWarn('telemetry send failed', { channel, status, consecutiveFailures: S.consecutiveFailures, backoffMs: ms });
656
657
  return;
657
658
  }
658
659
  if (status >= 400 && status < 500) {
659
660
  // Malformed-contract circuit breaker (includes 401) — not retried.
660
661
  S.disabledForProcess = true;
661
662
  S.lastError = { status, message: describeFailureStatus(status), at: Date.now() };
663
+ logWarn('telemetry disabled for process', { status });
662
664
  }
663
665
  }
664
666
 
@@ -705,7 +707,7 @@ async function flushImpl(reason) {
705
707
  result.sent.push(r.recordId);
706
708
  } else {
707
709
  result.failed.push(r.recordId);
708
- applyFailureBackoff(res.status);
710
+ applyFailureBackoff(res.status, channel);
709
711
  sawFailure = true;
710
712
  break;
711
713
  }
@@ -726,7 +728,7 @@ async function flushImpl(reason) {
726
728
  }
727
729
  } else {
728
730
  for (const r of batch) result.failed.push(r.recordId);
729
- applyFailureBackoff(res.status);
731
+ applyFailureBackoff(res.status, channel);
730
732
  sawFailure = true;
731
733
  break;
732
734
  }
@@ -739,7 +741,9 @@ async function flushImpl(reason) {
739
741
  if (safeReason === 'daily' && result.failed.length === 0) {
740
742
  S.settings = await telemetrySettings.save({ lastDailyFlushAt: new Date().toISOString() });
741
743
  }
742
- } catch { /* fail-inert */ }
744
+ } catch (e) {
745
+ logWarn('telemetry flush threw', { error: e && e.message ? e.message : String(e) });
746
+ }
743
747
  S.lastFlushAt = Date.now();
744
748
  S.lastFlushReason = safeReason;
745
749
  return result;
@@ -26,7 +26,7 @@ const fsp = require('node:fs/promises');
26
26
  const path = require('node:path');
27
27
  const os = require('node:os');
28
28
  const crypto = require('node:crypto');
29
- const config = require('../config.cjs');
29
+ const config = require('../../config.cjs');
30
30
 
31
31
  const SCHEMA_VERSION = 1;
32
32
  const DAY_MS = 24 * 60 * 60 * 1000;