claude-code-session-manager 0.98.0 → 0.100.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 (431) hide show
  1. package/README.md +3 -3
  2. package/bin/cli.cjs +16 -4
  3. package/bin/node-floor.cjs +41 -0
  4. package/dist/assets/{DataModel-DCEgMTjH.js → DataModel-HdR0AxFq.js} +1 -1
  5. package/dist/assets/{History-Bfdoywlh.js → History-Dr4Jr_5z.js} +2 -2
  6. package/dist/assets/{Hooks-CKDJjTJV.js → Hooks-NhrvH3JP.js} +3 -3
  7. package/dist/assets/{Library-7akfgy67.js → Library-Dv_EtIMr.js} +1 -1
  8. package/dist/assets/{MarkdownEditor-DDesiqet.js → MarkdownEditor-DTKDWV_n.js} +1 -1
  9. package/dist/assets/{McpServers-D4lZtXof.js → McpServers-M034G9B3.js} +2 -2
  10. package/dist/assets/{Memory-CeI8G1w5.js → Memory-DzF1B4gx.js} +6 -6
  11. package/dist/assets/{Permissions-BGleLja4.js → Permissions-DrgbSGWl.js} +3 -3
  12. package/dist/assets/{Plugins-P4eCXy_S.js → Plugins-Bd3ef35w.js} +2 -2
  13. package/dist/assets/{ProvenanceBadge-BFczzI1B.js → ProvenanceBadge-DcBHT1Iy.js} +1 -1
  14. package/dist/assets/{SaveBar-l9jnEMES.js → SaveBar-rimJem-Y.js} +1 -1
  15. package/dist/assets/Scheduler-DjgFJl2w.js +16 -0
  16. package/dist/assets/{ScopeSwitcher-CjJi8ST5.js → ScopeSwitcher-CnAzTBrl.js} +1 -1
  17. package/dist/assets/Settings-Dc1F_sSg.js +3 -0
  18. package/dist/assets/{SkillReferenceGraph-CjbO01Sg.js → SkillReferenceGraph-B9aZDecM.js} +1 -1
  19. package/dist/assets/{Skills-BxZ9_fCR.js → Skills-DRXd18gu.js} +2 -2
  20. package/dist/assets/{SystemPrompt-D8vfFb8b.js → SystemPrompt-ahy5-Fwe.js} +1 -1
  21. package/dist/assets/{TagLibrary-2vzUo7YL.js → TagLibrary-C_tToDeL.js} +1 -1
  22. package/dist/assets/{TiptapBody-B8ZfbK90.js → TiptapBody-DvdefS6K.js} +1 -1
  23. package/dist/assets/{Toggle-BbW4nGGf.js → Toggle-6Jl5Njc6.js} +1 -1
  24. package/dist/assets/{index-CKH5Uxik.css → index-Bta-hwud.css} +1 -1
  25. package/dist/assets/{index-Cd98Q1lD.js → index-vx8O73l8.js} +497 -502
  26. package/dist/assets/{settingsSchema-IhUfucCF.js → settingsSchema-D6iRguNV.js} +1 -1
  27. package/dist/index.html +2 -2
  28. package/package.json +25 -29
  29. package/plugins/CLAUDE.md +6 -6
  30. package/plugins/session-manager-dev/skills/builder/4-manual/SKILL.md +21 -19
  31. package/plugins/session-manager-dev/skills/builder/SKILL.md +3 -3
  32. package/plugins/session-manager-dev/skills/develop/SKILL.md +254 -510
  33. package/plugins/session-manager-dev/skills/develop/standards.md +17 -22
  34. package/scripts/README.md +3 -11
  35. package/scripts/audit-ops-hygiene.cjs +3 -3
  36. package/scripts/hooks/lib/guard-prd-writes-policy.cjs +1 -1
  37. package/scripts/hooks/lib/guard-self-schedule-policy.cjs +1 -1
  38. package/scripts/mint-epic.cjs +2 -3
  39. package/scripts/scheduler-mcp-server.cjs +36 -7
  40. package/src/main/agentLibrary.cjs +22 -2
  41. package/src/main/build-info.json +4 -4
  42. package/src/main/config.cjs +41 -38
  43. package/src/main/docEdit.cjs +4 -1
  44. package/src/main/files.cjs +2 -5
  45. package/src/main/health.cjs +1 -1
  46. package/src/main/index.cjs +23 -10
  47. package/src/main/ipcSchemas.cjs +28 -35
  48. package/src/main/lib/agentPersonaSchema.cjs +13 -2
  49. package/src/main/lib/atomicFs.cjs +116 -0
  50. package/src/main/lib/branchSweep.cjs +13 -12
  51. package/src/main/lib/buildTarget.cjs +3 -3
  52. package/src/main/lib/claudeCliCaps.cjs +129 -0
  53. package/src/main/lib/credentials.cjs +2 -4
  54. package/src/main/lib/crossProjectFeedback.cjs +3 -3
  55. package/src/main/lib/cwdClassify.cjs +15 -3
  56. package/src/main/lib/definitionOfDone.cjs +207 -125
  57. package/src/main/lib/dodDrainHook.cjs +11 -5
  58. package/src/main/lib/epicMint.cjs +2 -4
  59. package/src/main/lib/epicStatusMirror.cjs +8 -10
  60. package/src/main/lib/epicWorktreeProjectConfig.cjs +2 -4
  61. package/src/main/lib/gateAuthority.cjs +96 -0
  62. package/src/main/lib/gitExec.cjs +69 -0
  63. package/src/main/lib/gitWorktree.cjs +656 -92
  64. package/src/main/lib/instanceLock.cjs +5 -8
  65. package/src/main/lib/launchFailure.cjs +2 -3
  66. package/src/main/lib/macroLibrary.cjs +386 -0
  67. package/src/main/lib/mcpToolCatalog.cjs +26 -17
  68. package/src/main/lib/needsReviewLedger.cjs +1 -1
  69. package/src/main/lib/opsErrorLog.cjs +11 -1
  70. package/src/main/lib/opsOwnership.cjs +0 -5
  71. package/src/main/lib/pidAlive.cjs +32 -0
  72. package/src/main/lib/prdCreate.cjs +121 -12
  73. package/src/main/lib/prdDisposition.cjs +2 -2
  74. package/src/main/lib/prdGateFiles.cjs +284 -0
  75. package/src/main/lib/prdLocations.cjs +61 -0
  76. package/src/main/lib/prdMigration.cjs +2 -3
  77. package/src/main/lib/prdSizing.cjs +2 -1
  78. package/src/main/lib/promptSessionSchema.cjs +10 -2
  79. package/src/main/lib/rcaReport.cjs +4 -6
  80. package/src/main/lib/reaperHelpers.cjs +8 -1
  81. package/src/main/lib/reservationExpiry.cjs +6 -1
  82. package/src/main/lib/reviewNotice.cjs +263 -0
  83. package/src/main/lib/runClaudeP.cjs +4 -1
  84. package/src/main/lib/schedulerPaths.cjs +22 -2
  85. package/src/main/lib/sessionSlots.cjs +2 -4
  86. package/src/main/lib/shippedPersonaSeeds.cjs +179 -0
  87. package/src/main/lib/timeoutShim.cjs +123 -0
  88. package/src/main/lib/timeoutShimScript.cjs +275 -0
  89. package/src/main/lib/upgradeDrain.cjs +4 -10
  90. package/src/main/lib/watchdogHelpers.cjs +12 -25
  91. package/src/main/lib/workTypeLibrary.cjs +7 -1
  92. package/src/main/promptSessionEvents.cjs +37 -13
  93. package/src/main/scheduler.cjs +910 -198
  94. package/src/main/seedAgentPersonas.cjs +278 -23
  95. package/src/main/supervisor.cjs +4 -1
  96. package/src/main/templates/PRD_AUTHORING.md +126 -406
  97. package/src/preload/__tests__/preload-surface.test.cjs +68 -0
  98. package/src/preload/api.d.ts +41 -94
  99. package/src/preload/index.cjs +14 -9
  100. package/src/seed/agents/architect.md +1 -0
  101. package/src/seed/agents/dev-lead.md +17 -18
  102. package/src/seed/agents/project-home-builder.md +1 -0
  103. package/src/seed/agents/validator.md +10 -4
  104. package/dist/assets/HostBilko-CDVHE0hT.js +0 -1
  105. package/dist/assets/Scheduler-C_phpeUS.js +0 -16
  106. package/dist/assets/Settings-BIwZ3FGQ.js +0 -3
  107. package/src/main/__tests__/activeIndexMerge.test.cjs +0 -235
  108. package/src/main/__tests__/agentEffortResolve.test.cjs +0 -117
  109. package/src/main/__tests__/agentLibrary.test.cjs +0 -276
  110. package/src/main/__tests__/agentModelResolve.test.cjs +0 -311
  111. package/src/main/__tests__/agentOverlayWrite.test.cjs +0 -95
  112. package/src/main/__tests__/bilkoHost-deriveSlug.test.cjs +0 -26
  113. package/src/main/__tests__/bilkoHost-integration.test.cjs +0 -118
  114. package/src/main/__tests__/bilkoHostCore.test.cjs +0 -72
  115. package/src/main/__tests__/broadcastCoalescer.test.cjs +0 -122
  116. package/src/main/__tests__/chat-cancel-terminal.test.cjs +0 -120
  117. package/src/main/__tests__/chat-dead-channels.test.cjs +0 -63
  118. package/src/main/__tests__/chat-exit-close-race.test.cjs +0 -146
  119. package/src/main/__tests__/chat-mcp-consent-notice.test.cjs +0 -139
  120. package/src/main/__tests__/chat-preamble-anchors.test.cjs +0 -100
  121. package/src/main/__tests__/chat-queue.test.cjs +0 -97
  122. package/src/main/__tests__/chat-stop-signal.test.cjs +0 -89
  123. package/src/main/__tests__/chatRunner-epic-worktree-execcwd.test.cjs +0 -125
  124. package/src/main/__tests__/chatRunner-session-flag-retry.test.cjs +0 -252
  125. package/src/main/__tests__/classifyPromptTicket.test.cjs +0 -101
  126. package/src/main/__tests__/classifyTranscriptLine.test.cjs +0 -201
  127. package/src/main/__tests__/computeDepHistorySatisfaction.test.cjs +0 -66
  128. package/src/main/__tests__/config-readText-bounded.test.cjs +0 -84
  129. package/src/main/__tests__/configWriteBoundaryOwners.test.cjs +0 -59
  130. package/src/main/__tests__/crossProjectFeedback.test.cjs +0 -334
  131. package/src/main/__tests__/crossProjectFeedbackRoutes.test.cjs +0 -161
  132. package/src/main/__tests__/dep-orphan-archive-health.test.cjs +0 -77
  133. package/src/main/__tests__/develop-skill-failure-modes.test.cjs +0 -70
  134. package/src/main/__tests__/docEdit.test.cjs +0 -244
  135. package/src/main/__tests__/dod-batchkey.test.cjs +0 -183
  136. package/src/main/__tests__/dod-drain-hook.test.cjs +0 -302
  137. package/src/main/__tests__/dod-report.test.cjs +0 -304
  138. package/src/main/__tests__/dod-reverify.test.cjs +0 -285
  139. package/src/main/__tests__/epicContextDigest.test.cjs +0 -174
  140. package/src/main/__tests__/epicMint.test.cjs +0 -332
  141. package/src/main/__tests__/epicMintTelemetryTap.test.cjs +0 -64
  142. package/src/main/__tests__/epicStatusMirror.test.cjs +0 -110
  143. package/src/main/__tests__/epicValidationHook.test.cjs +0 -291
  144. package/src/main/__tests__/exchanges.test.cjs +0 -122
  145. package/src/main/__tests__/exchangesPromptId.test.cjs +0 -61
  146. package/src/main/__tests__/extractJson.test.cjs +0 -51
  147. package/src/main/__tests__/files-reject-credentials.test.cjs +0 -40
  148. package/src/main/__tests__/fixtures/1218-fo-01-move-scripts-lib-into-src-main-lib.log +0 -556
  149. package/src/main/__tests__/flatPrdTickSweep.test.cjs +0 -110
  150. package/src/main/__tests__/health-build-freshness.test.cjs +0 -39
  151. package/src/main/__tests__/health-claude-md-budget.test.cjs +0 -57
  152. package/src/main/__tests__/health-credentials.test.cjs +0 -81
  153. package/src/main/__tests__/health-delegation-chain.test.cjs +0 -124
  154. package/src/main/__tests__/health-per-project-stall.test.cjs +0 -84
  155. package/src/main/__tests__/health-prd-migration.test.cjs +0 -37
  156. package/src/main/__tests__/health-queue-dispatch.test.cjs +0 -135
  157. package/src/main/__tests__/health-starve-escalation.test.cjs +0 -94
  158. package/src/main/__tests__/health-tick-liveness.test.cjs +0 -179
  159. package/src/main/__tests__/health-usage-poller.test.cjs +0 -144
  160. package/src/main/__tests__/health-worktree-cap-blocked.test.cjs +0 -65
  161. package/src/main/__tests__/heapSnapshot.test.cjs +0 -121
  162. package/src/main/__tests__/historyAggregatorIntraday.test.cjs +0 -313
  163. package/src/main/__tests__/historyDashboard.test.cjs +0 -163
  164. package/src/main/__tests__/historyRollup.test.cjs +0 -333
  165. package/src/main/__tests__/intradayRefresh.test.cjs +0 -39
  166. package/src/main/__tests__/ipcSchemas-dependsOn.test.cjs +0 -39
  167. package/src/main/__tests__/kg-augment.test.cjs +0 -195
  168. package/src/main/__tests__/loadGateDetailTick.test.cjs +0 -31
  169. package/src/main/__tests__/machineProfile.test.cjs +0 -152
  170. package/src/main/__tests__/mcpStatus.test.cjs +0 -61
  171. package/src/main/__tests__/memoryAggregate.test.cjs +0 -109
  172. package/src/main/__tests__/memoryStale.test.cjs +0 -88
  173. package/src/main/__tests__/needsReviewLedger.test.cjs +0 -162
  174. package/src/main/__tests__/openExternalApp-spawn-error.test.cjs +0 -25
  175. package/src/main/__tests__/opsErrorLog.test.cjs +0 -109
  176. package/src/main/__tests__/opsErrorLogTelemetryTap.test.cjs +0 -173
  177. package/src/main/__tests__/personaMerge.test.cjs +0 -169
  178. package/src/main/__tests__/planValidator.test.cjs +0 -125
  179. package/src/main/__tests__/pollLoop-dispatch-on-failure.test.cjs +0 -176
  180. package/src/main/__tests__/prd-group-allocator.test.cjs +0 -119
  181. package/src/main/__tests__/prdAdminRouteParity.test.cjs +0 -70
  182. package/src/main/__tests__/prdAdminRoutes.test.cjs +0 -718
  183. package/src/main/__tests__/prdAgentType.test.cjs +0 -103
  184. package/src/main/__tests__/prdAuthoringSeed.test.cjs +0 -39
  185. package/src/main/__tests__/prdCreate.test.cjs +0 -979
  186. package/src/main/__tests__/prdCreateAdoption.test.cjs +0 -205
  187. package/src/main/__tests__/prdCreateDisposition.test.cjs +0 -201
  188. package/src/main/__tests__/prdCreatePlanId.test.cjs +0 -132
  189. package/src/main/__tests__/prdFrontmatterAgentType.test.cjs +0 -117
  190. package/src/main/__tests__/prdFrontmatterDependsOn.test.cjs +0 -136
  191. package/src/main/__tests__/prdFrontmatterDisposition.test.cjs +0 -125
  192. package/src/main/__tests__/prdFrontmatterQuietMachine.test.cjs +0 -108
  193. package/src/main/__tests__/prdLocations.test.cjs +0 -195
  194. package/src/main/__tests__/prdLocationsArchived.test.cjs +0 -201
  195. package/src/main/__tests__/prdMigration.test.cjs +0 -349
  196. package/src/main/__tests__/prdMigrationLegacyAdopt.test.cjs +0 -91
  197. package/src/main/__tests__/prdParserHighWater.test.cjs +0 -74
  198. package/src/main/__tests__/prdParserSourcePromptId.test.cjs +0 -65
  199. package/src/main/__tests__/prdSetDisposition.test.cjs +0 -222
  200. package/src/main/__tests__/prdSizing.test.cjs +0 -106
  201. package/src/main/__tests__/prdSourcePromptIdBackfill.test.cjs +0 -118
  202. package/src/main/__tests__/prdUpdateDependsOn.test.cjs +0 -160
  203. package/src/main/__tests__/proc-role-env.test.cjs +0 -125
  204. package/src/main/__tests__/procname-claude-spawn-sites.test.cjs +0 -304
  205. package/src/main/__tests__/procname-sm-processes.test.cjs +0 -127
  206. package/src/main/__tests__/projectHomeAdminRoutes.test.cjs +0 -177
  207. package/src/main/__tests__/projectPages.test.cjs +0 -137
  208. package/src/main/__tests__/promptSessionEvents.test.cjs +0 -234
  209. package/src/main/__tests__/promptSessionSchema.test.cjs +0 -101
  210. package/src/main/__tests__/promptSessionTranscript.test.cjs +0 -0
  211. package/src/main/__tests__/promptSessionsCreateEpicHandler.test.cjs +0 -159
  212. package/src/main/__tests__/pty-epic-worktree-spawn-cwd.test.cjs +0 -282
  213. package/src/main/__tests__/pty-session-open-telemetry.test.cjs +0 -96
  214. package/src/main/__tests__/pty-write-result.test.cjs +0 -46
  215. package/src/main/__tests__/queue-health-verdict.test.cjs +0 -170
  216. package/src/main/__tests__/queue-starvation-dispatch-driver.test.cjs +0 -286
  217. package/src/main/__tests__/queue-starvation-per-project.test.cjs +0 -147
  218. package/src/main/__tests__/queueHistory.test.cjs +0 -355
  219. package/src/main/__tests__/queueOps-interactive-ac-lint.test.cjs +0 -65
  220. package/src/main/__tests__/queueOpsArchiveDestination.test.cjs +0 -65
  221. package/src/main/__tests__/queueOpsAutoArchive.test.cjs +0 -211
  222. package/src/main/__tests__/rateLimitPollerStreak.test.cjs +0 -128
  223. package/src/main/__tests__/rcaReport.test.cjs +0 -266
  224. package/src/main/__tests__/reconcileFlatPrdSweep.test.cjs +0 -119
  225. package/src/main/__tests__/reconcileTiming.test.cjs +0 -135
  226. package/src/main/__tests__/runLogRetention.test.cjs +0 -489
  227. package/src/main/__tests__/runVerify-atomic-verdicts.test.cjs +0 -26
  228. package/src/main/__tests__/runVerify-blocked-by-foreign-wip.test.cjs +0 -58
  229. package/src/main/__tests__/runVerify-landed-commit-outranks.test.cjs +0 -191
  230. package/src/main/__tests__/runVerify-policy-denial.test.cjs +0 -89
  231. package/src/main/__tests__/runVerify-transcript-commit-evidence.test.cjs +0 -225
  232. package/src/main/__tests__/runVerify.test.cjs +0 -1784
  233. package/src/main/__tests__/scheduleJobSchema.test.cjs +0 -127
  234. package/src/main/__tests__/scheduleJobStatusDrift.test.cjs +0 -65
  235. package/src/main/__tests__/scheduleJobTransitions.test.cjs +0 -277
  236. package/src/main/__tests__/scheduleJobTransitionsGrep.test.cjs +0 -59
  237. package/src/main/__tests__/scheduleJobTransitionsTelemetryTap.test.cjs +0 -72
  238. package/src/main/__tests__/scheduler-admin-routes.test.cjs +0 -199
  239. package/src/main/__tests__/scheduler-adopted-run-supervision.test.cjs +0 -143
  240. package/src/main/__tests__/scheduler-already-satisfied-on-main.test.cjs +0 -105
  241. package/src/main/__tests__/scheduler-archive-completed-prd.test.cjs +0 -102
  242. package/src/main/__tests__/scheduler-archived-twin-guard.test.cjs +0 -155
  243. package/src/main/__tests__/scheduler-autofix-outcome.test.cjs +0 -188
  244. package/src/main/__tests__/scheduler-autofix-select.test.cjs +0 -439
  245. package/src/main/__tests__/scheduler-autopromote.test.cjs +0 -51
  246. package/src/main/__tests__/scheduler-bash-timeout-env.test.cjs +0 -101
  247. package/src/main/__tests__/scheduler-blocked-by-foreign-wip.test.cjs +0 -107
  248. package/src/main/__tests__/scheduler-boot-orphans.test.cjs +0 -153
  249. package/src/main/__tests__/scheduler-broadcast-reconcile.test.cjs +0 -121
  250. package/src/main/__tests__/scheduler-clear-queue-history.test.cjs +0 -134
  251. package/src/main/__tests__/scheduler-commit-guard-noop.test.cjs +0 -244
  252. package/src/main/__tests__/scheduler-committed-in-window.test.cjs +0 -182
  253. package/src/main/__tests__/scheduler-cross-project-batch.test.cjs +0 -43
  254. package/src/main/__tests__/scheduler-default-eligible-heal.test.cjs +0 -168
  255. package/src/main/__tests__/scheduler-dispatch-loop.test.cjs +0 -58
  256. package/src/main/__tests__/scheduler-effective-concurrency.test.cjs +0 -81
  257. package/src/main/__tests__/scheduler-epic-digest.test.cjs +0 -227
  258. package/src/main/__tests__/scheduler-failed-autoreset.test.cjs +0 -121
  259. package/src/main/__tests__/scheduler-finalize-dispatch-guards.test.cjs +0 -229
  260. package/src/main/__tests__/scheduler-find-prd-dir.test.cjs +0 -75
  261. package/src/main/__tests__/scheduler-fix-plan-path.test.cjs +0 -119
  262. package/src/main/__tests__/scheduler-force-tick-outcome.test.cjs +0 -46
  263. package/src/main/__tests__/scheduler-foreign-wip-manifest.test.cjs +0 -78
  264. package/src/main/__tests__/scheduler-gate-shadow.test.cjs +0 -119
  265. package/src/main/__tests__/scheduler-guard-verdict-autoresolve.test.cjs +0 -390
  266. package/src/main/__tests__/scheduler-heal-refusal.test.cjs +0 -61
  267. package/src/main/__tests__/scheduler-heartbeat-payload.test.cjs +0 -80
  268. package/src/main/__tests__/scheduler-inplace-salvage.test.cjs +0 -323
  269. package/src/main/__tests__/scheduler-integration-failure-stamp.test.cjs +0 -41
  270. package/src/main/__tests__/scheduler-investigation-clean-skip.test.cjs +0 -63
  271. package/src/main/__tests__/scheduler-investigation-prompt.test.cjs +0 -123
  272. package/src/main/__tests__/scheduler-job-budget.test.cjs +0 -172
  273. package/src/main/__tests__/scheduler-job-overrun.test.cjs +0 -175
  274. package/src/main/__tests__/scheduler-launch-failure.test.cjs +0 -199
  275. package/src/main/__tests__/scheduler-leftover-fields.test.cjs +0 -52
  276. package/src/main/__tests__/scheduler-leftover-quarantine.test.cjs +0 -199
  277. package/src/main/__tests__/scheduler-looks-done.test.cjs +0 -537
  278. package/src/main/__tests__/scheduler-manual-pause.test.cjs +0 -118
  279. package/src/main/__tests__/scheduler-mechanical-recovery.test.cjs +0 -245
  280. package/src/main/__tests__/scheduler-meta-code-sha.test.cjs +0 -46
  281. package/src/main/__tests__/scheduler-mutate-reentrancy.test.cjs +0 -117
  282. package/src/main/__tests__/scheduler-needs-review-autoresolve.test.cjs +0 -197
  283. package/src/main/__tests__/scheduler-never-stop.test.cjs +0 -157
  284. package/src/main/__tests__/scheduler-no-dead-end-status.test.cjs +0 -152
  285. package/src/main/__tests__/scheduler-no-orphan-run-dir.test.cjs +0 -81
  286. package/src/main/__tests__/scheduler-notify-originating-tab-transcript.test.cjs +0 -87
  287. package/src/main/__tests__/scheduler-notify-originating-tab.test.cjs +0 -343
  288. package/src/main/__tests__/scheduler-periodic-reverify-guard.test.cjs +0 -217
  289. package/src/main/__tests__/scheduler-porcelain-rename.test.cjs +0 -164
  290. package/src/main/__tests__/scheduler-prd-missing-skip.test.cjs +0 -161
  291. package/src/main/__tests__/scheduler-prd-persona-spawn.test.cjs +0 -178
  292. package/src/main/__tests__/scheduler-quarantine-autoresolve.test.cjs +0 -165
  293. package/src/main/__tests__/scheduler-quiet-machine-lease.test.cjs +0 -257
  294. package/src/main/__tests__/scheduler-rate-limit-cooldown-freshness.test.cjs +0 -123
  295. package/src/main/__tests__/scheduler-rate-limit-pause.test.cjs +0 -152
  296. package/src/main/__tests__/scheduler-rate-limit-spin-guard.test.cjs +0 -156
  297. package/src/main/__tests__/scheduler-reap-dead-running-jobs.test.cjs +0 -754
  298. package/src/main/__tests__/scheduler-reaper-helpers-basics.test.cjs +0 -87
  299. package/src/main/__tests__/scheduler-reconcile-cwd-preserve.test.cjs +0 -100
  300. package/src/main/__tests__/scheduler-reconcile-history-backfill.test.cjs +0 -105
  301. package/src/main/__tests__/scheduler-reconcile-invalid-repair.test.cjs +0 -203
  302. package/src/main/__tests__/scheduler-reconcile-quarantine.test.cjs +0 -247
  303. package/src/main/__tests__/scheduler-reset-job-fields-guard.test.cjs +0 -77
  304. package/src/main/__tests__/scheduler-resume-recovery.test.cjs +0 -254
  305. package/src/main/__tests__/scheduler-shard-quarantine.test.cjs +0 -115
  306. package/src/main/__tests__/scheduler-shared-tree-guard.test.cjs +0 -380
  307. package/src/main/__tests__/scheduler-sigterm-commit.test.cjs +0 -43
  308. package/src/main/__tests__/scheduler-stall-per-project.test.cjs +0 -126
  309. package/src/main/__tests__/scheduler-starve-escalation.test.cjs +0 -154
  310. package/src/main/__tests__/scheduler-stranded-autofix-park.test.cjs +0 -252
  311. package/src/main/__tests__/scheduler-stranded-investigation.test.cjs +0 -185
  312. package/src/main/__tests__/scheduler-stuck-failed-escalation.test.cjs +0 -136
  313. package/src/main/__tests__/scheduler-supervisor-record.test.cjs +0 -81
  314. package/src/main/__tests__/scheduler-tick-cancel-token.test.cjs +0 -54
  315. package/src/main/__tests__/scheduler-tick-wedge.test.cjs +0 -172
  316. package/src/main/__tests__/scheduler-transient-failure.test.cjs +0 -141
  317. package/src/main/__tests__/scheduler-unreadable-queue-guard.test.cjs +0 -62
  318. package/src/main/__tests__/scheduler-utilization-hold.test.cjs +0 -89
  319. package/src/main/__tests__/scheduler-verify-prd-path.test.cjs +0 -109
  320. package/src/main/__tests__/scheduler-worktree-cap-defer.test.cjs +0 -234
  321. package/src/main/__tests__/scheduler-worktree-exec-cwd.test.cjs +0 -120
  322. package/src/main/__tests__/scheduler-writeprd-epic-rollback.test.cjs +0 -105
  323. package/src/main/__tests__/schedulerBatchRootBlocker.test.cjs +0 -117
  324. package/src/main/__tests__/schedulerStateSidecarRestore.test.cjs +0 -110
  325. package/src/main/__tests__/seedAgentPersonas.test.cjs +0 -184
  326. package/src/main/__tests__/seedSchedulerMcp.test.cjs +0 -211
  327. package/src/main/__tests__/seedStatus.test.cjs +0 -100
  328. package/src/main/__tests__/seedValidatorPersona.test.cjs +0 -116
  329. package/src/main/__tests__/stop-signal-anchor.test.cjs +0 -75
  330. package/src/main/__tests__/telemetryClient.test.cjs +0 -1055
  331. package/src/main/__tests__/telemetryContract.test.cjs +0 -930
  332. package/src/main/__tests__/telemetrySettings.test.cjs +0 -210
  333. package/src/main/__tests__/transcripts-batch-flush.test.cjs +0 -249
  334. package/src/main/__tests__/transcripts-doFlush-array.test.cjs +0 -124
  335. package/src/main/__tests__/transcripts-paged-reads.test.cjs +0 -241
  336. package/src/main/__tests__/transcripts-worktree-epic-path.test.cjs +0 -154
  337. package/src/main/__tests__/transcriptsUsageFor.test.cjs +0 -206
  338. package/src/main/__tests__/uniquePrdNumbers.test.cjs +0 -153
  339. package/src/main/__tests__/usageSingleFlight.test.cjs +0 -169
  340. package/src/main/__tests__/validationSentinels.test.cjs +0 -84
  341. package/src/main/__tests__/workTypeLibrary.test.cjs +0 -89
  342. package/src/main/bilkoHost.cjs +0 -314
  343. package/src/main/bilkoHostCore.cjs +0 -89
  344. package/src/main/lib/__tests__/active-sessions.test.cjs +0 -251
  345. package/src/main/lib/__tests__/activeIndexRebuild.test.cjs +0 -179
  346. package/src/main/lib/__tests__/agentPersonaSchema.test.cjs +0 -67
  347. package/src/main/lib/__tests__/auditLog.test.cjs +0 -38
  348. package/src/main/lib/__tests__/bootSelfHeal.test.cjs +0 -107
  349. package/src/main/lib/__tests__/branchSweep.test.cjs +0 -164
  350. package/src/main/lib/__tests__/buildIdentity.test.cjs +0 -121
  351. package/src/main/lib/__tests__/buildTarget.test.cjs +0 -52
  352. package/src/main/lib/__tests__/childWithLog.test.cjs +0 -321
  353. package/src/main/lib/__tests__/coldBootPromptSessionsWrite.test.cjs +0 -87
  354. package/src/main/lib/__tests__/crashTelemetry.test.cjs +0 -103
  355. package/src/main/lib/__tests__/credentials-futile-refresh.test.cjs +0 -115
  356. package/src/main/lib/__tests__/cwdClassify.test.cjs +0 -111
  357. package/src/main/lib/__tests__/definitionOfDoneSequence.test.cjs +0 -95
  358. package/src/main/lib/__tests__/delegationReadiness.test.cjs +0 -1175
  359. package/src/main/lib/__tests__/dispatchLoop.test.cjs +0 -63
  360. package/src/main/lib/__tests__/effectiveModelInfo.test.cjs +0 -244
  361. package/src/main/lib/__tests__/ephemeralCwd.test.cjs +0 -91
  362. package/src/main/lib/__tests__/epicDelegationStats.test.cjs +0 -137
  363. package/src/main/lib/__tests__/epicSpawnCwd.test.cjs +0 -283
  364. package/src/main/lib/__tests__/epicSpawnPlan.test.cjs +0 -196
  365. package/src/main/lib/__tests__/epicTranscriptPath.test.cjs +0 -163
  366. package/src/main/lib/__tests__/epicWorktreeBoot.test.cjs +0 -136
  367. package/src/main/lib/__tests__/epicWorktreeMerge.test.cjs +0 -130
  368. package/src/main/lib/__tests__/epicWorktreeMint.test.cjs +0 -117
  369. package/src/main/lib/__tests__/epicWorktreeProjectConfig.test.cjs +0 -137
  370. package/src/main/lib/__tests__/fixChainDepth.test.cjs +0 -40
  371. package/src/main/lib/__tests__/fixtures/204-mercury-steam-horse.log.txt +0 -13
  372. package/src/main/lib/__tests__/fixtures/scheduler-machine.json.corrupt-1789147548 +0 -34
  373. package/src/main/lib/__tests__/gateFixtures.json +0 -20
  374. package/src/main/lib/__tests__/gitCacheBound.test.cjs +0 -69
  375. package/src/main/lib/__tests__/gitWorktree.test.cjs +0 -1478
  376. package/src/main/lib/__tests__/gitWorktreeSalvage.test.cjs +0 -107
  377. package/src/main/lib/__tests__/gitWorktreeSalvageDelta.test.cjs +0 -153
  378. package/src/main/lib/__tests__/guardShims.test.cjs +0 -158
  379. package/src/main/lib/__tests__/importReferences.spec.cjs +0 -56
  380. package/src/main/lib/__tests__/instanceLock.test.cjs +0 -173
  381. package/src/main/lib/__tests__/jobSupervisorRecord.test.cjs +0 -78
  382. package/src/main/lib/__tests__/jobWorktree.test.cjs +0 -199
  383. package/src/main/lib/__tests__/jobWorktreeBootLive.test.cjs +0 -82
  384. package/src/main/lib/__tests__/landedSinceRun.test.cjs +0 -133
  385. package/src/main/lib/__tests__/launchFailure.test.cjs +0 -220
  386. package/src/main/lib/__tests__/loadGate.test.cjs +0 -303
  387. package/src/main/lib/__tests__/localAdminHttp.test.cjs +0 -214
  388. package/src/main/lib/__tests__/loopDelay.test.cjs +0 -68
  389. package/src/main/lib/__tests__/mcpToolCatalog.test.cjs +0 -107
  390. package/src/main/lib/__tests__/modelCatalog.test.cjs +0 -202
  391. package/src/main/lib/__tests__/opsOwnership.test.cjs +0 -113
  392. package/src/main/lib/__tests__/opsRootAbsoluteCwd.test.cjs +0 -328
  393. package/src/main/lib/__tests__/opsRootNestedWrite.test.cjs +0 -51
  394. package/src/main/lib/__tests__/opsRootResolve.test.cjs +0 -149
  395. package/src/main/lib/__tests__/prdDeclaredPaths.test.cjs +0 -82
  396. package/src/main/lib/__tests__/prdDisposition.test.cjs +0 -224
  397. package/src/main/lib/__tests__/procIdentity.test.cjs +0 -119
  398. package/src/main/lib/__tests__/procName.test.cjs +0 -92
  399. package/src/main/lib/__tests__/projectBriefCore.test.cjs +0 -216
  400. package/src/main/lib/__tests__/projectRootResolve.test.cjs +0 -148
  401. package/src/main/lib/__tests__/queueHealth.test.cjs +0 -58
  402. package/src/main/lib/__tests__/queueStoreAtomicWrite.test.cjs +0 -88
  403. package/src/main/lib/__tests__/queueStoreMachineStateRecovery.test.cjs +0 -190
  404. package/src/main/lib/__tests__/quietMachineLease.test.cjs +0 -39
  405. package/src/main/lib/__tests__/rateLimitWindow.test.cjs +0 -88
  406. package/src/main/lib/__tests__/reaperHelpers.test.cjs +0 -577
  407. package/src/main/lib/__tests__/schedulerBatchDepends.test.cjs +0 -312
  408. package/src/main/lib/__tests__/schedulerBatchFairness.test.cjs +0 -213
  409. package/src/main/lib/__tests__/schedulerBatchLaunchHold.test.cjs +0 -125
  410. package/src/main/lib/__tests__/schedulerBatchProjectCap.test.cjs +0 -127
  411. package/src/main/lib/__tests__/schedulerBatchQuietMachine.test.cjs +0 -109
  412. package/src/main/lib/__tests__/schedulerMcpServerHeadlessRefusal.test.cjs +0 -71
  413. package/src/main/lib/__tests__/schedulerMcpServerHelp.test.cjs +0 -216
  414. package/src/main/lib/__tests__/schedulerMcpServerProjectHome.test.cjs +0 -183
  415. package/src/main/lib/__tests__/schedulerPaths.test.cjs +0 -226
  416. package/src/main/lib/__tests__/schedulerPathsWorktree.test.cjs +0 -133
  417. package/src/main/lib/__tests__/schedulerRuntimeState.test.cjs +0 -56
  418. package/src/main/lib/__tests__/sessionSlots.test.cjs +0 -144
  419. package/src/main/lib/__tests__/telemetryBacklog.test.cjs +0 -626
  420. package/src/main/lib/__tests__/telemetryBoot.test.cjs +0 -134
  421. package/src/main/lib/__tests__/telemetryConsent.test.cjs +0 -136
  422. package/src/main/lib/__tests__/telemetryCounters.test.cjs +0 -57
  423. package/src/main/lib/__tests__/telemetryCountersMetadataColumn.test.cjs +0 -98
  424. package/src/main/lib/__tests__/terminalRunOutcome.test.cjs +0 -200
  425. package/src/main/lib/__tests__/toolUseClassify.test.cjs +0 -53
  426. package/src/main/lib/__tests__/updateCheck.test.cjs +0 -63
  427. package/src/main/lib/__tests__/upgradeDrain.test.cjs +0 -130
  428. package/src/main/lib/__tests__/usageCircuit.test.cjs +0 -354
  429. package/src/main/lib/__tests__/watchdog-helpers.test.cjs +0 -441
  430. package/src/main/lib/__tests__/watchdog-relaunch.test.cjs +0 -266
  431. package/src/main/lib/kgExchangePairing.cjs +0 -75
@@ -42,6 +42,7 @@ const epicWorktreeMint = require('./lib/epicWorktreeMint.cjs');
42
42
  const epicWorktreeMerge = require('./lib/epicWorktreeMerge.cjs');
43
43
  const epicWorktreeProjectConfig = require('./lib/epicWorktreeProjectConfig.cjs');
44
44
  const agentLibrary = require('./agentLibrary.cjs');
45
+ const macroLibrary = require('./lib/macroLibrary.cjs');
45
46
  const agentModelResolve = require('./lib/agentModelResolve.cjs');
46
47
  const agentEffortResolve = require('./lib/agentEffortResolve.cjs');
47
48
  const { resolveEffectiveModelInfo } = require('./lib/effectiveModelInfo.cjs');
@@ -52,7 +53,6 @@ const upgradeDrain = require('./lib/upgradeDrain.cjs');
52
53
  const { writeGuardShims } = require('./lib/guardShims.cjs');
53
54
  const { MCP_TOOL_CATALOG, MCP_RECIPES } = require('./lib/mcpToolCatalog.cjs');
54
55
  const { sendIfAlive } = require('./lib/sendToRenderer.cjs');
55
- const { resolveBuildTarget } = require('./lib/buildTarget.cjs');
56
56
  const crossProjectFeedback = require('./lib/crossProjectFeedback.cjs');
57
57
  const adminHttp = createAdminHttp();
58
58
  scheduler.registerAdminRoutes(adminHttp);
@@ -88,7 +88,6 @@ const memoryTool = require('./memoryTool.cjs');
88
88
  const { registerMemoryAggregateIpc } = require('./memoryAggregate.cjs');
89
89
  const { registerProjectBriefIpc } = require('./projectBrief.cjs');
90
90
  const { registerProjectPagesIpc, attachWindow: attachProjectPagesWindow, closeAllOutputWatchers: closeAllProjectPagesWatchers } = require('./projectPages.cjs');
91
- const { registerBilkoHostIpc } = require('./bilkoHost.cjs');
92
91
  const promptSessionTranscript = require('./promptSessionTranscript.cjs');
93
92
  const { computeEpicDelegationStats } = require('./lib/epicDelegationStats.cjs');
94
93
  const agentMemory = require('./agentMemory.cjs');
@@ -551,6 +550,28 @@ ipcMain.handle('agents:remove-override', async (_e, payload) => {
551
550
  broadcastAgentsChanged();
552
551
  return result;
553
552
  });
553
+ // Macro library (macroLibrary.cjs): global machine-local one-click sidebar
554
+ // macros (agent + tag + prompt). Store path is fixed in-module; the renderer
555
+ // never supplies it. Mutations broadcast `macros:changed`.
556
+ function broadcastMacrosChanged() {
557
+ sendIfAlive(mainWindow, 'macros:changed', {});
558
+ }
559
+ ipcMain.handle('macros:list', () => macroLibrary.listMacros());
560
+ ipcMain.handle('macros:save', validated(schemas.macrosSave, async (payload) => {
561
+ const macro = await macroLibrary.saveMacro(payload);
562
+ broadcastMacrosChanged();
563
+ return macro;
564
+ }));
565
+ ipcMain.handle('macros:delete', validated(schemas.macrosDelete, async (payload) => {
566
+ const result = await macroLibrary.deleteMacro(payload);
567
+ broadcastMacrosChanged();
568
+ return result;
569
+ }));
570
+ ipcMain.handle('macros:set-project', validated(schemas.macrosSetProject, async (payload) => {
571
+ const result = await macroLibrary.setMacroProject(payload);
572
+ if (result.ok) broadcastMacrosChanged();
573
+ return result;
574
+ }));
554
575
  // New Epic AIM composer (epicIntake.ts's `agentBody`/`agentPath`): unlike
555
576
  // list-personas above (global dir only), this honors the project-overlay-
556
577
  // then-global precedence so an Epic's opening prompt carries the persona
@@ -877,13 +898,6 @@ ipcMain.handle('app:git-branch', validated(schemas.appGitBranch, async ({ cwd })
877
898
  });
878
899
  }));
879
900
 
880
- // Resolves a project's publish target for 'build'-tagged Epics — see
881
- // lib/buildTarget.cjs. Null means the Build toolbar button should be disabled
882
- // (no explicit config, no auto-discoverable publishable package.json).
883
- ipcMain.handle('build:resolve-target', validated(schemas.buildResolveTarget, ({ cwd }) => {
884
- return resolveBuildTarget(cwd);
885
- }));
886
-
887
901
  // Containment check for the open-in-{editor,finder,terminal} handlers lives
888
902
  // in lib/insideHome.cjs — single chokepoint for the /home/bilkoEVIL prefix-trap.
889
903
  // Editor / finder / terminal logic lives in lib/openExternalApp.cjs.
@@ -983,7 +997,6 @@ epicWorktreeProjectConfig.registerEpicWorktreeProjectConfigHandlers();
983
997
  registerMemoryAggregateIpc();
984
998
  registerProjectBriefIpc();
985
999
  registerProjectPagesIpc();
986
- registerBilkoHostIpc();
987
1000
  ipcMain.handle('promptSessionTranscript:append', validated(schemas.promptSessionTranscriptAppend, async ({ cwd, epicId, role, text, at, eventId }) => {
988
1001
  const ok = await promptSessionTranscript.appendTurn(cwd, epicId, { role, text, at, eventId });
989
1002
  return { ok };
@@ -13,6 +13,7 @@ const { PromptSessionSchema, EpicTagSchema, EpicSourceSchema, EpicIntakeSectionS
13
13
  const { PrdWorkTypeSchema } = require('./lib/workTypeLibrary.cjs');
14
14
  const { PERSONA_NAME_RE } = require('./agentLibrary.cjs');
15
15
  const { AgentPersonaSaveSchema } = require('./lib/agentPersonaSchema.cjs');
16
+ const { MacroSaveSchema, MacroDeleteSchema, MacroSetProjectSchema } = require('./lib/macroLibrary.cjs');
16
17
 
17
18
  // ──────────────────────────────────────────── PTY
18
19
  const ptySpawn = z.object({
@@ -282,6 +283,15 @@ const scheduleSlug = z.object({
282
283
  slug: z.string().regex(SCHEDULE_SLUG_RE),
283
284
  });
284
285
 
286
+ // reset-job: slug + optional cwd — narrows the match to one project's job
287
+ // row so two different projects' slugs that happen to collide (slugs carry
288
+ // no cwd salt) don't cross-reset. Mirrors remote.resetJob's own cwd filter
289
+ // in scheduler.cjs.
290
+ const scheduleResetJob = z.object({
291
+ slug: z.string().regex(SCHEDULE_SLUG_RE),
292
+ cwd: z.string().min(1).max(4096).optional(),
293
+ });
294
+
285
295
  const scheduleReadLog = z.object({
286
296
  slug: z.string().regex(SCHEDULE_SLUG_RE),
287
297
  runId: z.string().regex(SCHEDULE_RUN_ID_RE),
@@ -409,6 +419,17 @@ const schedulerCreatePrd = z.object({
409
419
  // invalidate. See prdCreate.cjs's buildPrdBody and schedulerBatch.cjs's
410
420
  // pickNextBatch.
411
421
  quietMachine: z.boolean().optional(),
422
+ // Commands that prove this PRD is done (gate-and-files-in-PRD-body unit) —
423
+ // rendered verbatim as the `# Gate` body section's ```gate fence and read
424
+ // back by definitionOfDone.cjs's resolveGate/parseChain. ['none'] opts out
425
+ // for docs/config PRDs with no runnable check. Shape-validated (length,
426
+ // chars, no-shell, none-is-alone) by prdGateFiles.cjs's validateGate, not
427
+ // here — this schema only bounds array size and element type.
428
+ gate: z.array(z.string()).min(1).max(10).optional(),
429
+ // Repo-relative files/folders this PRD may change — rendered verbatim as
430
+ // the `# Files` body section. Validated (repo-relative, no .., no globs)
431
+ // by prdGateFiles.cjs's validateFiles, not here.
432
+ files: z.array(z.string()).min(1).max(50).optional(),
412
433
  });
413
434
 
414
435
  // Renderer-facing counterpart to adminPrdFrontmatterPatch's dependsOn/
@@ -588,6 +609,9 @@ const setSessionSlotsSchema = z.object({
588
609
  // Full field-level rules live in lib/agentPersonaSchema.cjs, mirroring
589
610
  // AgentPersonaSaveInput (src/preload/api.d.ts) field-for-field.
590
611
  const agentsSavePersona = AgentPersonaSaveSchema;
612
+ const macrosSave = MacroSaveSchema;
613
+ const macrosDelete = MacroDeleteSchema;
614
+ const macrosSetProject = MacroSetProjectSchema;
591
615
 
592
616
  // ──────────────────────────────────────────── Memory tool (Bundle C, cycle 3)
593
617
  // Workspace-scoped markdown store at ~/.claude/projects/<ws>/memory/.
@@ -706,30 +730,6 @@ const projectHomeAdminWriteBody = z.object({
706
730
  html: z.string(),
707
731
  }).strict();
708
732
 
709
- // ──────────────────────────────────────────── Host on Bilko.run
710
- // Same validation split: real path validation is config.cjs's validatePath
711
- // at first fs access in bilkoHost.cjs — these schemas only bound wire shape.
712
- const bilkoHostCwd = z.object({
713
- cwd: z.string().min(1).max(4096),
714
- }).strict();
715
- const bilkoHostPrepareBundle = z.object({
716
- cwd: z.string().min(1).max(4096),
717
- slug: z.string().min(1).max(64).regex(/^[a-z0-9-]+$/, 'slug must be lowercase kebab-case'),
718
- }).strict();
719
- const BILKO_HOST_DOCUMENT_SOURCE = z.union([
720
- z.object({ kind: z.literal('project-page-lens'), lens: z.enum(['home', 'marketing', 'feature', 'architecture']) }).strict(),
721
- z.object({ kind: z.literal('file'), path: z.string().min(1).max(4096) }).strict(),
722
- ]);
723
- const bilkoHostAddDocument = z.object({
724
- cwd: z.string().min(1).max(4096),
725
- subpath: z.string().min(1).max(200),
726
- title: z.string().min(1).max(200),
727
- source: BILKO_HOST_DOCUMENT_SOURCE,
728
- }).strict();
729
- const bilkoHostRemoveDocument = z.object({
730
- cwd: z.string().min(1).max(4096),
731
- id: z.string().min(1).max(200),
732
- }).strict();
733
733
  const projectBriefSetPin = z.object({
734
734
  cwd: z.string().min(1).max(4096),
735
735
  block: PROJECT_BRIEF_BLOCK,
@@ -993,12 +993,6 @@ const appGitBranch = z.object({
993
993
  cwd: z.string().min(1).max(4096),
994
994
  }).passthrough();
995
995
 
996
- // build:resolve-target — see src/main/lib/buildTarget.cjs. cwd is a trusted
997
- // TAB cwd, not validatePath'd here (same invariant as appGitBranch above).
998
- const buildResolveTarget = z.object({
999
- cwd: z.string().min(1).max(4096),
1000
- }).passthrough();
1001
-
1002
996
  // git:status / git:file-status — see src/main/git.cjs. cwd is validatePath'd
1003
997
  // inside the handler (allowedRoots = home), so the schema only enforces shape.
1004
998
  const gitStatus = z.object({
@@ -1100,6 +1094,7 @@ module.exports = {
1100
1094
  sessionsPayload,
1101
1095
  layoutEnvelope,
1102
1096
  scheduleSlug,
1097
+ scheduleResetJob,
1103
1098
  scheduleReadLog,
1104
1099
  scheduleWritePrd,
1105
1100
  schedulerCreatePrd,
@@ -1122,7 +1117,6 @@ module.exports = {
1122
1117
  voiceSetRecording,
1123
1118
  appTestFireHook,
1124
1119
  appGitBranch,
1125
- buildResolveTarget,
1126
1120
  gitStatus,
1127
1121
  gitFileStatus,
1128
1122
  repoAnalyze,
@@ -1138,10 +1132,6 @@ module.exports = {
1138
1132
  projectBriefCwd,
1139
1133
  projectPagesCwd,
1140
1134
  projectHomeAdminWriteBody,
1141
- bilkoHostCwd,
1142
- bilkoHostPrepareBundle,
1143
- bilkoHostAddDocument,
1144
- bilkoHostRemoveDocument,
1145
1135
  projectBriefSetPin,
1146
1136
  projectBriefUpdate,
1147
1137
  promptSessionTranscriptAppend,
@@ -1172,6 +1162,9 @@ module.exports = {
1172
1162
  chatExternalSend,
1173
1163
  exchangesList,
1174
1164
  agentsSavePersona,
1165
+ macrosSave,
1166
+ macrosDelete,
1167
+ macrosSetProject,
1175
1168
  agentsGetPersonaBody,
1176
1169
  agentsResolveModelInfo,
1177
1170
  modelsCatalog,
@@ -23,7 +23,7 @@
23
23
  'use strict';
24
24
 
25
25
  const { z } = require('zod');
26
- const { WorkTypeSchema } = require('./workTypeLibrary.cjs');
26
+ const { WorkTypeSchema, LEGACY_WORK_TYPES } = require('./workTypeLibrary.cjs');
27
27
  const { PERSONA_NAME_RE, ALL_PROJECTS } = require('../agentLibrary.cjs');
28
28
 
29
29
  // Bounded free-text fields — generous for legitimate persona authoring while
@@ -53,13 +53,24 @@ const AgentPersonaSaveSchema = z.object({
53
53
  model: BoundedString,
54
54
  effort: BoundedString.optional(),
55
55
  color: BoundedString,
56
- tags: z.array(WorkTypeSchema),
56
+ // A legacy tag value (e.g. the retired 'bilko-host-publisher') must keep
57
+ // loading on an old on-disk persona — dropped silently, never thrown. Any
58
+ // other unknown value still fails via WorkTypeSchema.
59
+ tags: z.preprocess(
60
+ (v) => (Array.isArray(v) ? v.filter((t) => !(typeof t === 'string' && LEGACY_WORK_TYPES.includes(t))) : v),
61
+ z.array(WorkTypeSchema),
62
+ ),
57
63
  projects: z.array(ProjectEntrySchema).optional(),
58
64
  action: z.string().max(20000).optional(),
59
65
  actionLabel: BoundedString.optional(),
60
66
  title: BoundedString.optional(),
61
67
  // Set = write this project's frontmatter-only override (model/effort only) instead of the global file.
62
68
  projectName: BoundedString.optional(),
69
+ // Bundled-persona version stamp (seedAgentPersonas.cjs). Omit to carry over
70
+ // the existing file's stamp unchanged — see agentLibrary.cjs's savePersona.
71
+ // Without this field zod's default "strip unknown keys" behavior would
72
+ // silently drop it from a save payload that did carry one.
73
+ seedVersion: z.number().int().optional(),
63
74
  // Unbounded — a persona's body is arbitrary system-prompt prose.
64
75
  body: z.string(),
65
76
  });
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * atomicFs.cjs — canonical tmp+rename file-IO primitives, extracted out of
5
+ * config.cjs so non-Electron modules (lib/*.cjs) can reuse the exact same
6
+ * atomic-write recipe without importing config.cjs's electron-adjacent
7
+ * validation layer. NO electron import here, intentionally — this module is
8
+ * pure Node and must stay requirable from any process.
9
+ *
10
+ * Recipe (unchanged from the original config.cjs copies this consolidates):
11
+ * write to `<file>.tmp-<pid>-<ts>-<rand>` in the SAME directory, then rename
12
+ * over the real path. mkdir -p the parent first. On write/rename failure,
13
+ * best-effort unlink the tmp file before rethrowing.
14
+ */
15
+
16
+ const fs = require('node:fs');
17
+ const fsp = require('node:fs/promises');
18
+ const path = require('node:path');
19
+
20
+ function tmpPathFor(file) {
21
+ return `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
22
+ }
23
+
24
+ /**
25
+ * opts.mode: optional POSIX permission bits applied to the tmp file before
26
+ * rename (chmod'd explicitly too — some platforms ignore the mode arg on
27
+ * writeFile when the file pre-exists).
28
+ * opts.fsync: fsync the tmp file's fd before rename (durability for callers
29
+ * that need the write to survive a crash immediately after it returns).
30
+ */
31
+ async function writeTextAtomic(file, text, opts = {}) {
32
+ const dir = path.dirname(file);
33
+ await fsp.mkdir(dir, { recursive: true });
34
+ const tmp = tmpPathFor(file);
35
+ try {
36
+ const handle = await fsp.open(tmp, 'w', opts.mode);
37
+ try {
38
+ await handle.writeFile(text, 'utf8');
39
+ if (opts.mode) {
40
+ try { await handle.chmod(opts.mode); } catch { /* umask may have already applied it */ }
41
+ }
42
+ if (opts.fsync) await handle.sync();
43
+ } finally {
44
+ await handle.close();
45
+ }
46
+ await fsp.rename(tmp, file);
47
+ } catch (e) {
48
+ try { await fsp.unlink(tmp); } catch { /* tmp never created or already gone */ }
49
+ throw e;
50
+ }
51
+ }
52
+
53
+ function writeTextAtomicSync(file, text, opts = {}) {
54
+ const dir = path.dirname(file);
55
+ fs.mkdirSync(dir, { recursive: true });
56
+ const tmp = tmpPathFor(file);
57
+ try {
58
+ const fd = fs.openSync(tmp, 'w', opts.mode);
59
+ try {
60
+ fs.writeSync(fd, text, null, 'utf8');
61
+ if (opts.mode) {
62
+ try { fs.chmodSync(tmp, opts.mode); } catch { /* umask may have already applied it */ }
63
+ }
64
+ if (opts.fsync) fs.fsyncSync(fd);
65
+ } finally {
66
+ fs.closeSync(fd);
67
+ }
68
+ fs.renameSync(tmp, file);
69
+ } catch (e) {
70
+ try { fs.unlinkSync(tmp); } catch { /* tmp never created or already gone */ }
71
+ throw e;
72
+ }
73
+ }
74
+
75
+ function serializeJson(obj, { space = 2, newline = true } = {}) {
76
+ const json = JSON.stringify(obj, null, space);
77
+ return newline ? `${json}\n` : json;
78
+ }
79
+
80
+ async function writeJsonAtomic(file, obj, opts = {}) {
81
+ await writeTextAtomic(file, serializeJson(obj, opts), opts);
82
+ }
83
+
84
+ function writeJsonAtomicSync(file, obj, opts = {}) {
85
+ writeTextAtomicSync(file, serializeJson(obj, opts), opts);
86
+ }
87
+
88
+ async function readJsonOr(file, fallback) {
89
+ try {
90
+ const raw = await fsp.readFile(file, 'utf8');
91
+ if (raw.trim() === '') return fallback;
92
+ return JSON.parse(raw);
93
+ } catch {
94
+ return fallback;
95
+ }
96
+ }
97
+
98
+ function readJsonOrSync(file, fallback) {
99
+ try {
100
+ const raw = fs.readFileSync(file, 'utf8');
101
+ if (raw.trim() === '') return fallback;
102
+ return JSON.parse(raw);
103
+ } catch {
104
+ return fallback;
105
+ }
106
+ }
107
+
108
+ module.exports = {
109
+ tmpPathFor,
110
+ writeTextAtomic,
111
+ writeTextAtomicSync,
112
+ writeJsonAtomic,
113
+ writeJsonAtomicSync,
114
+ readJsonOr,
115
+ readJsonOrSync,
116
+ };
@@ -19,20 +19,13 @@
19
19
  */
20
20
  'use strict';
21
21
 
22
- const { execFile } = require('node:child_process');
23
22
  const gitWorktree = require('./gitWorktree.cjs');
23
+ const { execGit: sharedExecGit } = require('./gitExec.cjs');
24
24
 
25
+ // Thin re-shape over the shared gitExec.execGit — kept so call sites below
26
+ // (positional `timeout`, no `-C` prefix needed) don't all need touching.
25
27
  function execGit(cwd, args, timeout = 20_000) {
26
- return new Promise((resolve, reject) => {
27
- execFile('git', ['-C', cwd, ...args], { timeout, windowsHide: true, encoding: 'utf8' }, (err, stdout, stderr) => {
28
- if (err) {
29
- err.stderrText = stderr;
30
- reject(err);
31
- return;
32
- }
33
- resolve(stdout || '');
34
- });
35
- });
28
+ return sharedExecGit(cwd, args, { timeout });
36
29
  }
37
30
 
38
31
  /** List every local branch under `refs/heads/sm-job/*`. Never throws. */
@@ -114,7 +107,15 @@ async function sweepStrandedJobBranches({ cwd, jobs, attemptedBranches }) {
114
107
  continue;
115
108
  }
116
109
  attempted.add(attemptKey);
117
- const integration = await gitWorktree.integrateJobBranch({ cwd, branch, slug: slug || branch });
110
+ // baseBranch: read off the job row when one still exists (the crash-between-
111
+ // commit-and-integrate case this sweep exists for) so integration targets the
112
+ // SAME branch the checkout was actually on when the worktree was created —
113
+ // not whatever cwd happens to sit on during this sweep pass. A fully orphaned
114
+ // branch (no row at all) has nothing to read, so it falls back to
115
+ // resolveDefaultBranch(cwd), same as before.
116
+ const integration = await gitWorktree.integrateJobBranch({
117
+ cwd, branch, slug: slug || branch, baseBranch: (row && row.worktreeBaseBranch) || null,
118
+ });
118
119
  results.push({ branch, slug, action: integration.ok ? 'integrated' : 'conflict', integration });
119
120
  }
120
121
  return { results };
@@ -21,9 +21,9 @@
21
21
  * daemon whose "release" is bump VERSION, write the changelog, tag, and flag
22
22
  * that the live server needs a restart. That requires reading CLAUDE.md and
23
23
  * git history and exercising judgment, so discovery lives in the agent: a
24
- * `null` here means **not configured yet**, and the UI turns it into a
25
- * "Set Up Build" bootstrap session (`src/renderer/lib/buildAction.ts`) that
26
- * probes the project and writes the config, rather than a disabled button.
24
+ * `null` here means **not configured yet**; the builder skill probes the
25
+ * project and writes the config. No IPC or UI calls this resolver today;
26
+ * builds start from a user-created Macro (e.g. agent `builder`, tag `build`).
27
27
  */
28
28
  'use strict';
29
29
 
@@ -0,0 +1,129 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * claudeCliCaps.cjs — probes the installed `claude` CLI for
5
+ * `--permission-prompts` support once per process, caches the result.
6
+ *
7
+ * Headless spawns (scheduler/supervisor/docEdit/runClaudeP) have no human
8
+ * attached, so a tool that waits on AskUserQuestion or a permission prompt
9
+ * would stall the job forever. `--permission-prompts none` (CLI v2.1.285+)
10
+ * auto-denies those prompts and removes human-requiring tools. Older CLIs
11
+ * don't recognize the flag, so it's only appended when `claude --help`
12
+ * confirms support.
13
+ *
14
+ * Only a SUCCESSFUL probe (a real supported/unsupported determination from
15
+ * actual `--help` text) is cached for the rest of the process — an error
16
+ * (ENOENT, timeout, a throw) is never cached: this call returns [] (the safe
17
+ * default: omit the flag) but a LATER call re-probes, subject to a
18
+ * once-per-60s backoff so a persistently broken binary doesn't turn every
19
+ * headless spawn attempt into a fresh probe.
20
+ *
21
+ * The probe spawns the SAME binary/spawn target every real headless spawn
22
+ * site uses — `claudeSpawnTarget('aux', ...)` from claudeBin.cjs — not a raw
23
+ * `resolveClaudeBin()` result, so what gets probed is provably what later
24
+ * gets spawned (aliasing/argv0 labeling included).
25
+ */
26
+
27
+ const claudeBinLib = require('./claudeBin.cjs');
28
+
29
+ const PROBE_TIMEOUT_MS = 10_000;
30
+ const FLAG_ARGS = ['--permission-prompts', 'none'];
31
+ const DEFAULT_REPROBE_AFTER_ERROR_MS = 60_000;
32
+
33
+ let _execFile = require('node:child_process').execFile;
34
+
35
+ /** Test hook — inject a stub execFile(file, args, opts, cb) instead of spawning the real CLI. */
36
+ function _setExecFileForTest(fn) {
37
+ _execFile = fn || require('node:child_process').execFile;
38
+ }
39
+
40
+ /** Test hook — forget the cached probe result and any error backoff so the next call re-probes immediately. */
41
+ function _resetForTest() {
42
+ cachedArgs = null;
43
+ inflight = null;
44
+ lastErrorAt = 0;
45
+ reprobeAfterErrorMs = DEFAULT_REPROBE_AFTER_ERROR_MS;
46
+ }
47
+
48
+ /** Test hook — shrink the once-per-60s error backoff so a re-probe-after-error test doesn't need to sleep 60s. */
49
+ function _setReprobeBackoffMsForTest(ms) {
50
+ reprobeAfterErrorMs = typeof ms === 'number' && ms >= 0 ? ms : DEFAULT_REPROBE_AFTER_ERROR_MS;
51
+ }
52
+
53
+ let cachedArgs = null; // set ONLY by a successful probe — never by an error path
54
+ let inflight = null;
55
+ let lastErrorAt = 0;
56
+ let reprobeAfterErrorMs = DEFAULT_REPROBE_AFTER_ERROR_MS;
57
+
58
+ /**
59
+ * Probes `claude --help` once per process (successful result only); every
60
+ * call (including concurrent/later ones) resolves the same cached arg array
61
+ * once a successful probe has landed. A probe error is never cached — this
62
+ * call still resolves [] for the caller, but the NEXT call re-probes for
63
+ * real once `reprobeAfterErrorMs` has elapsed since the last error.
64
+ */
65
+ function ensureCliCapsProbed() {
66
+ if (cachedArgs) return Promise.resolve(cachedArgs);
67
+ if (inflight) return inflight;
68
+ if (lastErrorAt && Date.now() - lastErrorAt < reprobeAfterErrorMs) {
69
+ return Promise.resolve([]);
70
+ }
71
+
72
+ let bin;
73
+ try { bin = claudeBinLib.resolveClaudeBin(); } catch { bin = 'claude'; }
74
+ let target;
75
+ try { target = claudeBinLib.claudeSpawnTarget('aux', 'cli-caps-probe', bin); } catch { target = { command: bin }; }
76
+
77
+ // NOTE: `inflight` is cleared via `.finally()` below, never directly
78
+ // inside this executor. A real `execFile` callback is always async, but a
79
+ // TEST stub firing its callback synchronously would otherwise run
80
+ // `succeed`/`fail` (and their `inflight = null`) to completion BEFORE the
81
+ // `inflight = promise` assignment two lines down ever runs — leaving
82
+ // `inflight` wedged at a stale, already-settled promise forever, so this
83
+ // function would never re-probe again regardless of the cache/backoff
84
+ // state. `.finally()` callbacks always run as a microtask, strictly after
85
+ // the synchronous assignment below, so this ordering hazard can't recur.
86
+ const promise = new Promise((resolve) => {
87
+ const succeed = (args) => {
88
+ cachedArgs = args;
89
+ resolve(args);
90
+ };
91
+ const fail = () => {
92
+ lastErrorAt = Date.now();
93
+ resolve([]);
94
+ };
95
+ try {
96
+ const execOpts = { timeout: PROBE_TIMEOUT_MS, windowsHide: true };
97
+ if (target.argv0) execOpts.argv0 = target.argv0;
98
+ _execFile(target.command, ['--help'], execOpts, (err, stdout) => {
99
+ if (err) {
100
+ console.warn('[claudeCliCaps] claude --help probe failed; headless spawns will omit --permission-prompts:', err?.message || err);
101
+ fail();
102
+ return;
103
+ }
104
+ succeed(String(stdout || '').includes('--permission-prompts') ? FLAG_ARGS.slice() : []);
105
+ });
106
+ } catch (e) {
107
+ console.warn('[claudeCliCaps] claude --help probe threw; headless spawns will omit --permission-prompts:', e?.message || e);
108
+ fail();
109
+ }
110
+ });
111
+ inflight = promise;
112
+ promise.finally(() => {
113
+ if (inflight === promise) inflight = null;
114
+ });
115
+ return promise;
116
+ }
117
+
118
+ /** Sync accessor for the cached probe result — [] until ensureCliCapsProbed() has resolved successfully at least once. */
119
+ function headlessPermissionArgs() {
120
+ return cachedArgs ? cachedArgs.slice() : [];
121
+ }
122
+
123
+ module.exports = {
124
+ headlessPermissionArgs,
125
+ ensureCliCapsProbed,
126
+ _setExecFileForTest,
127
+ _resetForTest,
128
+ _setReprobeBackoffMsForTest,
129
+ };
@@ -6,6 +6,7 @@ const path = require('node:path');
6
6
  const os = require('node:os');
7
7
  const { spawn, execFileSync } = require('node:child_process');
8
8
  const { cleanChildEnv, pathWithUserBins } = require('./cleanEnv.cjs');
9
+ const atomicFs = require('./atomicFs.cjs');
9
10
  const { resolveClaudeBin, claudeSpawnTarget } = require('./claudeBin.cjs');
10
11
 
11
12
  const CREDS_PATH = path.join(os.homedir(), '.claude', '.credentials.json');
@@ -160,10 +161,7 @@ async function writeCredentials(rawData, freshOauth, source = 'file') {
160
161
  writeKeychainRaw(JSON.stringify(next));
161
162
  return;
162
163
  }
163
- const tmp = `${CREDS_PATH}.${process.pid}.${Date.now()}.tmp`;
164
- await fsp.writeFile(tmp, JSON.stringify(next, null, 2), { encoding: 'utf8', mode: 0o600 });
165
- try { await fsp.chmod(tmp, 0o600); } catch { /* umask may have already set it */ }
166
- await fsp.rename(tmp, CREDS_PATH);
164
+ await atomicFs.writeJsonAtomic(CREDS_PATH, next, { mode: 0o600, newline: false });
167
165
  }
168
166
 
169
167
  function appendRefreshLog(entry) {
@@ -69,9 +69,9 @@ const { OPS_ROOT_DIR } = require('./opsOwnership.cjs');
69
69
  const { resolveProjectContext } = require('./projectRootResolve.cjs');
70
70
 
71
71
  /** Only these three Epic tags make sense for an inbound report — they are
72
- * exactly the tags that route through /develop (tagLibrary.ts). 'build',
73
- * 'project-home-builder' and 'bilko-host-publisher' name dedicated local
74
- * pipelines and are meaningless as a request from another project. */
72
+ * exactly the tags that route through /develop (tagLibrary.ts). 'build' and
73
+ * 'project-home-builder' name dedicated local pipelines and are meaningless
74
+ * as a request from another project. */
75
75
  const FEEDBACK_TAGS = Object.freeze(['bug', 'feature', 'discussion']);
76
76
  const DEFAULT_FEEDBACK_TAG = 'discussion';
77
77
 
@@ -115,7 +115,9 @@ function inspectGit(start) {
115
115
  } catch {
116
116
  return { shape: 'unknown', dir: entry.dir, mainRoot: null, reason: `worktree admin back-reference missing (${adminGitdirFile})` };
117
117
  }
118
- if (path.resolve(backRef) !== path.resolve(gitPath)) {
118
+ // git records realpaths, so compare canonical spellings (macOS /var -> /private/var).
119
+ const canon = (q) => { try { return fs.realpathSync(q); } catch { return path.resolve(q); } };
120
+ if (path.resolve(backRef) !== path.resolve(gitPath) && canon(backRef) !== canon(gitPath)) {
119
121
  return { shape: 'unknown', dir: entry.dir, mainRoot: null, reason: `worktree admin back-reference points elsewhere (${adminGitdirFile})` };
120
122
  }
121
123
  return { shape: 'worktree', dir: entry.dir, mainRoot: candidateMain, reason: 'linked worktree, back-reference verified' };
@@ -133,12 +135,22 @@ function worktreeMainRootOf(cwd) {
133
135
  return null;
134
136
  }
135
137
 
138
+ // A root may be a symlink (macOS os.tmpdir() is /var -> /private/var) while callers hand us
139
+ // either spelling (config.validatePath returns realpaths). Match on both the raw and the
140
+ // canonical spelling of the root.
141
+ function rootSpellings(root) {
142
+ const abs = path.resolve(root);
143
+ let real = abs;
144
+ try { real = fs.realpathSync(abs); } catch { /* root not created yet — raw spelling only */ }
145
+ return real === abs ? [abs] : [abs, real];
146
+ }
147
+
136
148
  function isExactlyTmpdir(absCwd) {
137
- return absCwd === path.resolve(os.tmpdir());
149
+ return rootSpellings(os.tmpdir()).includes(absCwd);
138
150
  }
139
151
 
140
152
  function isUnderManagedWorktreeRoot(absCwd) {
141
- return ['job', 'epic'].map((k) => path.resolve(schedulerPaths.worktreeRoot(k))).some((root) => {
153
+ return ['job', 'epic'].flatMap((k) => rootSpellings(schedulerPaths.worktreeRoot(k))).some((root) => {
142
154
  const rel = path.relative(root, absCwd);
143
155
  return rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));
144
156
  });