lastlight 0.16.0 → 0.16.1

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 (385) hide show
  1. package/README.md +71 -692
  2. package/dist/cli-config.js.map +1 -0
  3. package/dist/cli-format.js.map +1 -0
  4. package/dist/{cli/cli-server.d.ts → cli-server.d.ts} +26 -1
  5. package/dist/{cli/cli-server.js → cli-server.js} +40 -5
  6. package/dist/cli-server.js.map +1 -0
  7. package/dist/cli-timeline.js.map +1 -0
  8. package/dist/{cli/cli.js → cli.js} +4 -3
  9. package/dist/cli.js.map +1 -0
  10. package/dist/{cli/fork-cli.d.ts → fork-cli.d.ts} +3 -3
  11. package/dist/{cli/fork-cli.js → fork-cli.js} +28 -27
  12. package/dist/fork-cli.js.map +1 -0
  13. package/dist/{cli/oauth-cli.js → oauth-cli.js} +1 -1
  14. package/dist/oauth-cli.js.map +1 -0
  15. package/dist/{cli/setup.js → setup.js} +10 -4
  16. package/dist/setup.js.map +1 -0
  17. package/dist/{cli/skills-install.d.ts → skills-install.d.ts} +6 -0
  18. package/dist/{cli/skills-install.js → skills-install.js} +6 -2
  19. package/dist/skills-install.js.map +1 -0
  20. package/package.json +20 -65
  21. package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
  22. package/agent-context/rules.md +0 -80
  23. package/agent-context/security.md +0 -69
  24. package/agent-context/soul.md +0 -21
  25. package/config/default.yaml +0 -119
  26. package/deploy/.env.production.example +0 -100
  27. package/deploy/entrypoint.sh +0 -82
  28. package/deploy/native/README.md +0 -160
  29. package/deploy/native/install.sh +0 -110
  30. package/deploy/native/lastlight.env.example +0 -95
  31. package/deploy/native/lastlight.service +0 -50
  32. package/deploy/sandbox-entrypoint.sh +0 -93
  33. package/dist/admin/auth.d.ts +0 -51
  34. package/dist/admin/auth.js +0 -121
  35. package/dist/admin/auth.js.map +0 -1
  36. package/dist/admin/chat-session-reader.d.ts +0 -39
  37. package/dist/admin/chat-session-reader.js +0 -84
  38. package/dist/admin/chat-session-reader.js.map +0 -1
  39. package/dist/admin/docker.d.ts +0 -61
  40. package/dist/admin/docker.js +0 -187
  41. package/dist/admin/docker.js.map +0 -1
  42. package/dist/admin/index.d.ts +0 -9
  43. package/dist/admin/index.js +0 -59
  44. package/dist/admin/index.js.map +0 -1
  45. package/dist/admin/routes.d.ts +0 -81
  46. package/dist/admin/routes.js +0 -1381
  47. package/dist/admin/routes.js.map +0 -1
  48. package/dist/admin/sessions.d.ts +0 -89
  49. package/dist/admin/sessions.js +0 -204
  50. package/dist/admin/sessions.js.map +0 -1
  51. package/dist/admin/tail.d.ts +0 -12
  52. package/dist/admin/tail.js +0 -145
  53. package/dist/admin/tail.js.map +0 -1
  54. package/dist/admin/version.d.ts +0 -22
  55. package/dist/admin/version.js +0 -92
  56. package/dist/admin/version.js.map +0 -1
  57. package/dist/cli/cli-config.js.map +0 -1
  58. package/dist/cli/cli-format.js.map +0 -1
  59. package/dist/cli/cli-server.js.map +0 -1
  60. package/dist/cli/cli-timeline.js.map +0 -1
  61. package/dist/cli/cli.js.map +0 -1
  62. package/dist/cli/fork-cli.js.map +0 -1
  63. package/dist/cli/oauth-cli.js.map +0 -1
  64. package/dist/cli/setup.js.map +0 -1
  65. package/dist/cli/skills-install.js.map +0 -1
  66. package/dist/config/config-resolve.d.ts +0 -28
  67. package/dist/config/config-resolve.js +0 -47
  68. package/dist/config/config-resolve.js.map +0 -1
  69. package/dist/config/config.d.ts +0 -157
  70. package/dist/config/config.js +0 -581
  71. package/dist/config/config.js.map +0 -1
  72. package/dist/config/core-pin.d.ts +0 -16
  73. package/dist/config/core-pin.js +0 -85
  74. package/dist/config/core-pin.js.map +0 -1
  75. package/dist/config/overlay-assets.d.ts +0 -20
  76. package/dist/config/overlay-assets.js +0 -114
  77. package/dist/config/overlay-assets.js.map +0 -1
  78. package/dist/config/overlay-bootstrap.d.ts +0 -44
  79. package/dist/config/overlay-bootstrap.js +0 -304
  80. package/dist/config/overlay-bootstrap.js.map +0 -1
  81. package/dist/connectors/github-webhook.d.ts +0 -45
  82. package/dist/connectors/github-webhook.js +0 -321
  83. package/dist/connectors/github-webhook.js.map +0 -1
  84. package/dist/connectors/index.d.ts +0 -18
  85. package/dist/connectors/index.js +0 -41
  86. package/dist/connectors/index.js.map +0 -1
  87. package/dist/connectors/messaging/base.d.ts +0 -42
  88. package/dist/connectors/messaging/base.js +0 -139
  89. package/dist/connectors/messaging/base.js.map +0 -1
  90. package/dist/connectors/messaging/delivery.d.ts +0 -14
  91. package/dist/connectors/messaging/delivery.js +0 -38
  92. package/dist/connectors/messaging/delivery.js.map +0 -1
  93. package/dist/connectors/messaging/index.d.ts +0 -4
  94. package/dist/connectors/messaging/index.js +0 -4
  95. package/dist/connectors/messaging/index.js.map +0 -1
  96. package/dist/connectors/messaging/session-manager.d.ts +0 -53
  97. package/dist/connectors/messaging/session-manager.js +0 -255
  98. package/dist/connectors/messaging/session-manager.js.map +0 -1
  99. package/dist/connectors/messaging/types.d.ts +0 -58
  100. package/dist/connectors/messaging/types.js +0 -7
  101. package/dist/connectors/messaging/types.js.map +0 -1
  102. package/dist/connectors/slack/connector.d.ts +0 -142
  103. package/dist/connectors/slack/connector.js +0 -494
  104. package/dist/connectors/slack/connector.js.map +0 -1
  105. package/dist/connectors/slack/index.d.ts +0 -2
  106. package/dist/connectors/slack/index.js +0 -3
  107. package/dist/connectors/slack/index.js.map +0 -1
  108. package/dist/connectors/slack/mrkdwn.d.ts +0 -19
  109. package/dist/connectors/slack/mrkdwn.js +0 -240
  110. package/dist/connectors/slack/mrkdwn.js.map +0 -1
  111. package/dist/connectors/types.d.ts +0 -61
  112. package/dist/connectors/types.js +0 -2
  113. package/dist/connectors/types.js.map +0 -1
  114. package/dist/cron/fanout.d.ts +0 -33
  115. package/dist/cron/fanout.js +0 -55
  116. package/dist/cron/fanout.js.map +0 -1
  117. package/dist/cron/jobs.d.ts +0 -18
  118. package/dist/cron/jobs.js +0 -37
  119. package/dist/cron/jobs.js.map +0 -1
  120. package/dist/cron/scheduler.d.ts +0 -45
  121. package/dist/cron/scheduler.js +0 -105
  122. package/dist/cron/scheduler.js.map +0 -1
  123. package/dist/engine/agent-executor.d.ts +0 -34
  124. package/dist/engine/agent-executor.js +0 -246
  125. package/dist/engine/agent-executor.js.map +0 -1
  126. package/dist/engine/chat/chat-runner.d.ts +0 -132
  127. package/dist/engine/chat/chat-runner.js +0 -424
  128. package/dist/engine/chat/chat-runner.js.map +0 -1
  129. package/dist/engine/chat/chat-skills.d.ts +0 -45
  130. package/dist/engine/chat/chat-skills.js +0 -184
  131. package/dist/engine/chat/chat-skills.js.map +0 -1
  132. package/dist/engine/chat/chat.d.ts +0 -54
  133. package/dist/engine/chat/chat.js +0 -316
  134. package/dist/engine/chat/chat.js.map +0 -1
  135. package/dist/engine/chat/message-batcher.d.ts +0 -32
  136. package/dist/engine/chat/message-batcher.js +0 -109
  137. package/dist/engine/chat/message-batcher.js.map +0 -1
  138. package/dist/engine/dispatcher.d.ts +0 -73
  139. package/dist/engine/dispatcher.js +0 -663
  140. package/dist/engine/dispatcher.js.map +0 -1
  141. package/dist/engine/event-shim.d.ts +0 -117
  142. package/dist/engine/event-shim.js +0 -435
  143. package/dist/engine/event-shim.js.map +0 -1
  144. package/dist/engine/executors/orchestrator.d.ts +0 -81
  145. package/dist/engine/executors/orchestrator.js +0 -365
  146. package/dist/engine/executors/orchestrator.js.map +0 -1
  147. package/dist/engine/executors/shared.d.ts +0 -189
  148. package/dist/engine/executors/shared.js +0 -616
  149. package/dist/engine/executors/shared.js.map +0 -1
  150. package/dist/engine/github/git-auth.d.ts +0 -62
  151. package/dist/engine/github/git-auth.js +0 -161
  152. package/dist/engine/github/git-auth.js.map +0 -1
  153. package/dist/engine/github/github-app-client.d.ts +0 -23
  154. package/dist/engine/github/github-app-client.js +0 -33
  155. package/dist/engine/github/github-app-client.js.map +0 -1
  156. package/dist/engine/github/github-tools.d.ts +0 -18
  157. package/dist/engine/github/github-tools.js +0 -263
  158. package/dist/engine/github/github-tools.js.map +0 -1
  159. package/dist/engine/github/github.d.ts +0 -1193
  160. package/dist/engine/github/github.js +0 -357
  161. package/dist/engine/github/github.js.map +0 -1
  162. package/dist/engine/github/profiles.d.ts +0 -279
  163. package/dist/engine/github/profiles.js +0 -42
  164. package/dist/engine/github/profiles.js.map +0 -1
  165. package/dist/engine/github/review-poster.d.ts +0 -98
  166. package/dist/engine/github/review-poster.js +0 -177
  167. package/dist/engine/github/review-poster.js.map +0 -1
  168. package/dist/engine/llm.d.ts +0 -79
  169. package/dist/engine/llm.js +0 -269
  170. package/dist/engine/llm.js.map +0 -1
  171. package/dist/engine/oauth.d.ts +0 -43
  172. package/dist/engine/oauth.js +0 -103
  173. package/dist/engine/oauth.js.map +0 -1
  174. package/dist/engine/router.d.ts +0 -29
  175. package/dist/engine/router.js +0 -680
  176. package/dist/engine/router.js.map +0 -1
  177. package/dist/engine/screen/classifier.d.ts +0 -93
  178. package/dist/engine/screen/classifier.js +0 -215
  179. package/dist/engine/screen/classifier.js.map +0 -1
  180. package/dist/engine/screen/screen.d.ts +0 -41
  181. package/dist/engine/screen/screen.js +0 -93
  182. package/dist/engine/screen/screen.js.map +0 -1
  183. package/dist/evals-api.d.ts +0 -24
  184. package/dist/evals-api.js +0 -22
  185. package/dist/evals-api.js.map +0 -1
  186. package/dist/index.d.ts +0 -1
  187. package/dist/index.js +0 -940
  188. package/dist/index.js.map +0 -1
  189. package/dist/managed-repos.d.ts +0 -30
  190. package/dist/managed-repos.js +0 -72
  191. package/dist/managed-repos.js.map +0 -1
  192. package/dist/notify/blocks.d.ts +0 -23
  193. package/dist/notify/blocks.js +0 -118
  194. package/dist/notify/blocks.js.map +0 -1
  195. package/dist/notify/index.d.ts +0 -17
  196. package/dist/notify/index.js +0 -7
  197. package/dist/notify/index.js.map +0 -1
  198. package/dist/notify/model.d.ts +0 -57
  199. package/dist/notify/model.js +0 -89
  200. package/dist/notify/model.js.map +0 -1
  201. package/dist/notify/notifier.d.ts +0 -18
  202. package/dist/notify/notifier.js +0 -100
  203. package/dist/notify/notifier.js.map +0 -1
  204. package/dist/notify/render.d.ts +0 -21
  205. package/dist/notify/render.js +0 -59
  206. package/dist/notify/render.js.map +0 -1
  207. package/dist/notify/transports/github.d.ts +0 -26
  208. package/dist/notify/transports/github.js +0 -27
  209. package/dist/notify/transports/github.js.map +0 -1
  210. package/dist/notify/transports/slack.d.ts +0 -27
  211. package/dist/notify/transports/slack.js +0 -37
  212. package/dist/notify/transports/slack.js.map +0 -1
  213. package/dist/notify/types.d.ts +0 -119
  214. package/dist/notify/types.js +0 -16
  215. package/dist/notify/types.js.map +0 -1
  216. package/dist/providers.d.ts +0 -125
  217. package/dist/providers.js +0 -279
  218. package/dist/providers.js.map +0 -1
  219. package/dist/sandbox/docker.d.ts +0 -180
  220. package/dist/sandbox/docker.js +0 -517
  221. package/dist/sandbox/docker.js.map +0 -1
  222. package/dist/sandbox/egress-allowlist.d.ts +0 -74
  223. package/dist/sandbox/egress-allowlist.js +0 -164
  224. package/dist/sandbox/egress-allowlist.js.map +0 -1
  225. package/dist/sandbox/egress-firewall-config.d.ts +0 -127
  226. package/dist/sandbox/egress-firewall-config.js +0 -434
  227. package/dist/sandbox/egress-firewall-config.js.map +0 -1
  228. package/dist/sandbox/images.d.ts +0 -23
  229. package/dist/sandbox/images.js +0 -55
  230. package/dist/sandbox/images.js.map +0 -1
  231. package/dist/sandbox/index.d.ts +0 -112
  232. package/dist/sandbox/index.js +0 -332
  233. package/dist/sandbox/index.js.map +0 -1
  234. package/dist/sandbox/sandbox.d.ts +0 -214
  235. package/dist/sandbox/sandbox.js +0 -453
  236. package/dist/sandbox/sandbox.js.map +0 -1
  237. package/dist/sandbox/smol.d.ts +0 -162
  238. package/dist/sandbox/smol.js +0 -485
  239. package/dist/sandbox/smol.js.map +0 -1
  240. package/dist/session-log.d.ts +0 -63
  241. package/dist/session-log.js +0 -290
  242. package/dist/session-log.js.map +0 -1
  243. package/dist/state/approval-store.d.ts +0 -88
  244. package/dist/state/approval-store.js +0 -149
  245. package/dist/state/approval-store.js.map +0 -1
  246. package/dist/state/build-assets.d.ts +0 -50
  247. package/dist/state/build-assets.js +0 -154
  248. package/dist/state/build-assets.js.map +0 -1
  249. package/dist/state/db.d.ts +0 -81
  250. package/dist/state/db.js +0 -155
  251. package/dist/state/db.js.map +0 -1
  252. package/dist/state/execution-store.d.ts +0 -257
  253. package/dist/state/execution-store.js +0 -527
  254. package/dist/state/execution-store.js.map +0 -1
  255. package/dist/state/migrate.d.ts +0 -15
  256. package/dist/state/migrate.js +0 -175
  257. package/dist/state/migrate.js.map +0 -1
  258. package/dist/state/workflow-run-store.d.ts +0 -216
  259. package/dist/state/workflow-run-store.js +0 -403
  260. package/dist/state/workflow-run-store.js.map +0 -1
  261. package/dist/telemetry/index.d.ts +0 -38
  262. package/dist/telemetry/index.js +0 -253
  263. package/dist/telemetry/index.js.map +0 -1
  264. package/dist/telemetry/pi-events.d.ts +0 -12
  265. package/dist/telemetry/pi-events.js +0 -134
  266. package/dist/telemetry/pi-events.js.map +0 -1
  267. package/dist/workflows/dag.d.ts +0 -37
  268. package/dist/workflows/dag.js +0 -118
  269. package/dist/workflows/dag.js.map +0 -1
  270. package/dist/workflows/loader.d.ts +0 -53
  271. package/dist/workflows/loader.js +0 -421
  272. package/dist/workflows/loader.js.map +0 -1
  273. package/dist/workflows/loop-eval.d.ts +0 -28
  274. package/dist/workflows/loop-eval.js +0 -74
  275. package/dist/workflows/loop-eval.js.map +0 -1
  276. package/dist/workflows/phase-executor.d.ts +0 -222
  277. package/dist/workflows/phase-executor.js +0 -1153
  278. package/dist/workflows/phase-executor.js.map +0 -1
  279. package/dist/workflows/phase-ref.d.ts +0 -50
  280. package/dist/workflows/phase-ref.js +0 -91
  281. package/dist/workflows/phase-ref.js.map +0 -1
  282. package/dist/workflows/resume.d.ts +0 -58
  283. package/dist/workflows/resume.js +0 -313
  284. package/dist/workflows/resume.js.map +0 -1
  285. package/dist/workflows/runner.d.ts +0 -63
  286. package/dist/workflows/runner.js +0 -381
  287. package/dist/workflows/runner.js.map +0 -1
  288. package/dist/workflows/schema.d.ts +0 -344
  289. package/dist/workflows/schema.js +0 -460
  290. package/dist/workflows/schema.js.map +0 -1
  291. package/dist/workflows/simple.d.ts +0 -90
  292. package/dist/workflows/simple.js +0 -393
  293. package/dist/workflows/simple.js.map +0 -1
  294. package/dist/workflows/target-policy.d.ts +0 -74
  295. package/dist/workflows/target-policy.js +0 -80
  296. package/dist/workflows/target-policy.js.map +0 -1
  297. package/dist/workflows/templates.d.ts +0 -88
  298. package/dist/workflows/templates.js +0 -127
  299. package/dist/workflows/templates.js.map +0 -1
  300. package/dist/workflows/triggers.d.ts +0 -21
  301. package/dist/workflows/triggers.js +0 -45
  302. package/dist/workflows/triggers.js.map +0 -1
  303. package/dist/workflows/verdict.d.ts +0 -19
  304. package/dist/workflows/verdict.js +0 -30
  305. package/dist/workflows/verdict.js.map +0 -1
  306. package/dist/worktree/manager.d.ts +0 -43
  307. package/dist/worktree/manager.js +0 -127
  308. package/dist/worktree/manager.js.map +0 -1
  309. package/docker-compose.yml +0 -274
  310. package/sandbox.Dockerfile +0 -68
  311. package/skills/README.md +0 -42
  312. package/skills/browser-qa/SKILL.md +0 -208
  313. package/skills/browser-qa/scripts/agent-browser.mjs +0 -531
  314. package/skills/building/SKILL.md +0 -95
  315. package/skills/chat/SKILL.md +0 -36
  316. package/skills/code-review/SKILL.md +0 -82
  317. package/skills/debug-production/SKILL.md +0 -108
  318. package/skills/demo/SKILL.md +0 -228
  319. package/skills/demo/scripts/compose-demo.sh +0 -243
  320. package/skills/issue-answer/SKILL.md +0 -91
  321. package/skills/issue-comment/SKILL.md +0 -49
  322. package/skills/issue-triage/SKILL.md +0 -149
  323. package/skills/issue-triage/references/AGENT-BRIEF.md +0 -65
  324. package/skills/pr-comment/SKILL.md +0 -64
  325. package/skills/pr-review/SKILL.md +0 -148
  326. package/skills/pr-review/references/findings-schema.md +0 -89
  327. package/skills/qa-test/SKILL.md +0 -97
  328. package/skills/repo-health/SKILL.md +0 -67
  329. package/skills/security-feedback/SKILL.md +0 -173
  330. package/skills/security-feedback/references/templates.md +0 -77
  331. package/skills/security-review/SKILL.md +0 -215
  332. package/skills/security-review/references/issue-format.md +0 -302
  333. package/skills/verify/SKILL.md +0 -118
  334. package/workflows/answer.yaml +0 -44
  335. package/workflows/build.yaml +0 -129
  336. package/workflows/cron-health.yaml +0 -6
  337. package/workflows/cron-review.yaml +0 -8
  338. package/workflows/cron-security.yaml +0 -6
  339. package/workflows/cron-triage.yaml +0 -8
  340. package/workflows/demo.yaml +0 -62
  341. package/workflows/examples/bash-smoke.yaml +0 -41
  342. package/workflows/examples/parallel-review.yaml +0 -36
  343. package/workflows/examples/tdd-loop.yaml +0 -17
  344. package/workflows/explore.yaml +0 -80
  345. package/workflows/issue-comment.yaml +0 -15
  346. package/workflows/issue-triage.yaml +0 -22
  347. package/workflows/pr-comment.yaml +0 -16
  348. package/workflows/pr-fix.yaml +0 -17
  349. package/workflows/pr-review.yaml +0 -50
  350. package/workflows/prompts/answer.md +0 -68
  351. package/workflows/prompts/architect.md +0 -44
  352. package/workflows/prompts/classifier.md +0 -60
  353. package/workflows/prompts/classify-adds-info.md +0 -17
  354. package/workflows/prompts/demo.md +0 -125
  355. package/workflows/prompts/executor.md +0 -42
  356. package/workflows/prompts/explore-ask.md +0 -99
  357. package/workflows/prompts/explore-publish.md +0 -31
  358. package/workflows/prompts/explore-read.md +0 -120
  359. package/workflows/prompts/explore-synthesize.md +0 -88
  360. package/workflows/prompts/fix.md +0 -18
  361. package/workflows/prompts/guardrails.md +0 -96
  362. package/workflows/prompts/pr-fix.md +0 -26
  363. package/workflows/prompts/pr.md +0 -39
  364. package/workflows/prompts/qa-browser.md +0 -95
  365. package/workflows/prompts/qa-synth.md +0 -44
  366. package/workflows/prompts/qa-test.md +0 -60
  367. package/workflows/prompts/re-reviewer.md +0 -33
  368. package/workflows/prompts/reviewer.md +0 -60
  369. package/workflows/prompts/verify-browser.md +0 -93
  370. package/workflows/prompts/verify-synth.md +0 -44
  371. package/workflows/prompts/verify.md +0 -63
  372. package/workflows/qa-test.yaml +0 -94
  373. package/workflows/repo-health.yaml +0 -15
  374. package/workflows/security-feedback.yaml +0 -25
  375. package/workflows/security-review.yaml +0 -37
  376. package/workflows/verify.yaml +0 -93
  377. /package/dist/{cli/cli-config.d.ts → cli-config.d.ts} +0 -0
  378. /package/dist/{cli/cli-config.js → cli-config.js} +0 -0
  379. /package/dist/{cli/cli-format.d.ts → cli-format.d.ts} +0 -0
  380. /package/dist/{cli/cli-format.js → cli-format.js} +0 -0
  381. /package/dist/{cli/cli-timeline.d.ts → cli-timeline.d.ts} +0 -0
  382. /package/dist/{cli/cli-timeline.js → cli-timeline.js} +0 -0
  383. /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
  384. /package/dist/{cli/oauth-cli.d.ts → oauth-cli.d.ts} +0 -0
  385. /package/dist/{cli/setup.d.ts → setup.d.ts} +0 -0
@@ -1,240 +0,0 @@
1
- /** A line of dashes/colons separating a GFM table header from its body. */
2
- const TABLE_DELIMITER = /^\s*\|?\s*:?-{1,}:?\s*(?:\|\s*:?-{1,}:?\s*)*\|?\s*$/;
3
- /** A candidate table row — contains at least one unescaped pipe. */
4
- function isTableRow(line) {
5
- return line.includes("|") && line.trim() !== "";
6
- }
7
- /** Strip leading/trailing pipes and split a GFM row into trimmed cells. */
8
- function splitTableCells(line) {
9
- return line
10
- .trim()
11
- .replace(/^\||\|$/g, "")
12
- .split("|")
13
- .map((c) => c.trim());
14
- }
15
- /**
16
- * Reduce inline markdown inside a table cell to plain text — the table is
17
- * rendered in a monospace code block where `*`, `_`, backticks and link
18
- * syntax wouldn't render, so they'd just be noise.
19
- */
20
- function plainCell(cell) {
21
- return cell
22
- .replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1 ($2)") // [text](url) → text (url)
23
- .replace(/\*\*(.+?)\*\*/g, "$1")
24
- .replace(/__(.+?)__/g, "$1")
25
- .replace(/~~(.+?)~~/g, "$1")
26
- .replace(/`([^`]+)`/g, "$1")
27
- .replace(/\*(.+?)\*/g, "$1");
28
- }
29
- /** Sizing caps for the monospace table fallback (Slack has no real tables). */
30
- const MAX_COL_WIDTH = 28; // per-column char cap; longer cells are truncated
31
- const MAX_TABLE_WIDTH = 72; // whole-row char budget (mobile-legible width)
32
- const MAX_TABLE_ROWS = 30; // data rows rendered inline before eliding the rest
33
- const MIN_COL_WIDTH = 3; // floor a column can be shrunk to
34
- const GUTTER = " "; // between-column spacer
35
- /** Truncate a cell to `width`, marking any elision with a trailing ellipsis. */
36
- function truncateCell(cell, width) {
37
- if (cell.length <= width)
38
- return cell;
39
- if (width <= 1)
40
- return "…".slice(0, width);
41
- return cell.slice(0, width - 1) + "…";
42
- }
43
- /**
44
- * Render a 2-column table as a `*label*: value` mrkdwn list. Used when the
45
- * table is too wide for a legible monospace block — a stacked key/value list
46
- * reads better on narrow (mobile) Slack views than a block that overflows the
47
- * viewport. Emits Slack mrkdwn directly; the result is held as a placeholder so
48
- * the `*bold*` is not re-processed by later transforms.
49
- */
50
- function renderTwoColList(rows) {
51
- // rows[0] is the header; the rest are key/value pairs.
52
- return rows
53
- .slice(1)
54
- .map((r) => `*${r[0] ?? ""}*: ${r[1] ?? ""}`.replace(/\s+$/, ""))
55
- .join("\n");
56
- }
57
- /**
58
- * Render a GFM table block (header row, delimiter row, then data rows) as an
59
- * aligned monospace code block. Slack has no table mrkdwn, so a raw GFM table
60
- * shows as a wall of pipes; a fixed-width block keeps columns legible. Columns
61
- * are capped and truncated, the whole row is kept within a mobile-legible
62
- * budget, and very wide 2-column tables fall back to a stacked key/value list.
63
- */
64
- function renderSlackTable(block) {
65
- // Drop the delimiter row (index 1); keep header + data.
66
- const rows = block
67
- .filter((_, idx) => idx !== 1)
68
- .map((line) => splitTableCells(line).map(plainCell));
69
- const colCount = Math.max(...rows.map((r) => r.length));
70
- // Natural (uncapped) column widths + the row width they'd need.
71
- const natural = [];
72
- for (let c = 0; c < colCount; c++) {
73
- natural[c] = Math.max(0, ...rows.map((r) => (r[c] ?? "").length));
74
- }
75
- const naturalWidth = natural.reduce((a, b) => a + b, 0) + GUTTER.length * (colCount - 1);
76
- // A wide 2-column table reads better stacked as a key/value list on mobile
77
- // than as a monospace block that overflows the viewport.
78
- if (colCount === 2 && naturalWidth > MAX_TABLE_WIDTH) {
79
- return renderTwoColList(rows);
80
- }
81
- // Cap each column, then, while the row is still too wide, shrink the widest
82
- // column one char at a time until it fits the budget (or all hit the floor).
83
- const widths = natural.map((w) => Math.min(w, MAX_COL_WIDTH));
84
- const rowWidth = () => widths.reduce((a, b) => a + b, 0) + GUTTER.length * (colCount - 1);
85
- while (rowWidth() > MAX_TABLE_WIDTH) {
86
- let widest = -1;
87
- let widestW = MIN_COL_WIDTH;
88
- for (let c = 0; c < colCount; c++) {
89
- if (widths[c] > widestW) {
90
- widestW = widths[c];
91
- widest = c;
92
- }
93
- }
94
- if (widest === -1)
95
- break; // every column already at the floor
96
- widths[widest] -= 1;
97
- }
98
- const fmtRow = (r) => widths
99
- .map((w, c) => truncateCell(r[c] ?? "", w).padEnd(w))
100
- .join(GUTTER)
101
- .replace(/\s+$/, "");
102
- const dataRows = rows.slice(1);
103
- const lines = [
104
- fmtRow(rows[0]),
105
- widths.map((w) => "-".repeat(w)).join(GUTTER),
106
- ];
107
- for (const r of dataRows.slice(0, MAX_TABLE_ROWS))
108
- lines.push(fmtRow(r));
109
- if (dataRows.length > MAX_TABLE_ROWS) {
110
- lines.push(`… (${dataRows.length - MAX_TABLE_ROWS} more rows)`);
111
- }
112
- return "```\n" + lines.join("\n") + "\n```";
113
- }
114
- /**
115
- * Find GFM tables (a row followed by a dash/colon delimiter line, then zero or
116
- * more rows) and replace each with `render(block)`. Operates line-by-line so
117
- * non-table content is untouched.
118
- */
119
- function convertMarkdownTables(text, render) {
120
- const lines = text.split("\n");
121
- const out = [];
122
- let i = 0;
123
- while (i < lines.length) {
124
- if (i + 1 < lines.length && isTableRow(lines[i]) && TABLE_DELIMITER.test(lines[i + 1])) {
125
- const block = [lines[i], lines[i + 1]];
126
- let j = i + 2;
127
- while (j < lines.length && isTableRow(lines[j]))
128
- block.push(lines[j++]);
129
- out.push(render(block));
130
- i = j;
131
- }
132
- else {
133
- out.push(lines[i]);
134
- i++;
135
- }
136
- }
137
- return out.join("\n");
138
- }
139
- /**
140
- * Convert standard Markdown to Slack's mrkdwn format.
141
- *
142
- * Uses an extract-then-transform pattern: code blocks and inline code
143
- * are pulled into placeholders first so their contents are never modified,
144
- * then restored after all transformations are applied.
145
- */
146
- export function markdownToSlackMrkdwn(text) {
147
- const placeholders = [];
148
- /** Replace a match with a numbered placeholder */
149
- function hold(content) {
150
- const idx = placeholders.length;
151
- placeholders.push(content);
152
- return `\x00PH${idx}\x00`;
153
- }
154
- let out = text;
155
- // 1. Extract fenced code blocks (strip language hints)
156
- out = out.replace(/```[a-zA-Z]*\n([\s\S]*?)```/g, (_m, code) => hold("```\n" + code + "```"));
157
- // 1b. Convert GFM tables to aligned monospace blocks (Slack has no table
158
- // mrkdwn). Runs after fenced-block extraction so pipes inside code are
159
- // left alone, and the result is held so later transforms don't touch it.
160
- out = convertMarkdownTables(out, (block) => hold(renderSlackTable(block)));
161
- // 2. Extract inline code
162
- out = out.replace(/`([^`\n]+)`/g, (_m, code) => hold("`" + code + "`"));
163
- // 3. Headers → bold (Slack has no header mrkdwn)
164
- out = out.replace(/^#{1,6}\s+(.+)$/gm, "*$1*");
165
- // 4. Bold: **text** or __text__ → *text*
166
- out = out.replace(/\*\*(.+?)\*\*/g, "*$1*");
167
- out = out.replace(/__(.+?)__/g, "*$1*");
168
- // 5. Italic: remaining *text* (not preceded/followed by *) → _text_
169
- // Only match single * that aren't part of ** (already converted to single *)
170
- // Skip this — after bold conversion, single * are now bold markers in Slack.
171
- // Markdown _italic_ already works in Slack as italic.
172
- // 6. Strikethrough: ~~text~~ → ~text~
173
- out = out.replace(/~~(.+?)~~/g, "~$1~");
174
- // 7. Images: ![alt](url) → <url|alt> (must come before links)
175
- out = out.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, "<$2|$1>");
176
- // 8. Links: [text](url) → <url|text>
177
- out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "<$2|$1>");
178
- // 9. Horizontal rules → em-dash line
179
- out = out.replace(/^(?:---+|\*\*\*+|___+)\s*$/gm, "———");
180
- // 10. Restore placeholders
181
- out = out.replace(/\x00PH(\d+)\x00/g, (_m, idx) => placeholders[parseInt(idx)]);
182
- return out;
183
- }
184
- // ── Block Kit conversion (inline images) ─────────────────────────────────────
185
- /** Markdown image `![alt](url)`, optional title ignored. Fresh instance per use. */
186
- const imageRegex = () => /!\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
187
- /** Slack section text limit is 3000; batch under it with headroom. */
188
- const MAX_SECTION_CHARS = 2900;
189
- /** Slack caps a message at 50 blocks. */
190
- const MAX_MESSAGE_BLOCKS = 50;
191
- /** True if the text contains at least one markdown image. */
192
- export function hasMarkdownImage(text) {
193
- return imageRegex().test(text);
194
- }
195
- /** Append `raw` (converted to mrkdwn) as one or more section blocks. */
196
- function pushTextSections(blocks, raw) {
197
- const mrkdwn = markdownToSlackMrkdwn(raw).trim();
198
- if (!mrkdwn)
199
- return;
200
- let buf = "";
201
- for (const line of mrkdwn.split("\n")) {
202
- const next = buf ? `${buf}\n${line}` : line;
203
- if (next.length > MAX_SECTION_CHARS && buf) {
204
- blocks.push({ type: "section", text: { type: "mrkdwn", text: buf } });
205
- buf = line;
206
- }
207
- else {
208
- buf = next;
209
- }
210
- }
211
- if (buf)
212
- blocks.push({ type: "section", text: { type: "mrkdwn", text: buf } });
213
- }
214
- /**
215
- * Convert markdown to Slack Block Kit, promoting markdown images to real
216
- * `image` blocks — the mrkdwn text path can only downgrade `![alt](url)` to a
217
- * link. Text between/around images is rendered as `section` mrkdwn blocks via
218
- * {@link markdownToSlackMrkdwn}. A non-`http(s)` image URL is left as text
219
- * (Slack rejects image blocks with an unusable URL).
220
- */
221
- export function markdownToSlackBlocks(markdown) {
222
- const blocks = [];
223
- const re = imageRegex();
224
- let last = 0;
225
- let m;
226
- while ((m = re.exec(markdown)) !== null) {
227
- const [full, alt, url] = m;
228
- pushTextSections(blocks, markdown.slice(last, m.index));
229
- last = m.index + full.length;
230
- if (/^https?:\/\//i.test(url)) {
231
- blocks.push({ type: "image", image_url: url, alt_text: (alt || url).slice(0, 2000) });
232
- }
233
- else {
234
- pushTextSections(blocks, full);
235
- }
236
- }
237
- pushTextSections(blocks, markdown.slice(last));
238
- return blocks.slice(0, MAX_MESSAGE_BLOCKS);
239
- }
240
- //# sourceMappingURL=mrkdwn.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mrkdwn.js","sourceRoot":"","sources":["../../../src/connectors/slack/mrkdwn.ts"],"names":[],"mappings":"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"}
@@ -1,61 +0,0 @@
1
- import { EventEmitter } from "events";
2
- /**
3
- * Normalized event envelope — the core engine only sees these,
4
- * never raw platform payloads. Adding a new connector (Slack, Discord, etc.)
5
- * means mapping platform events into this shape.
6
- */
7
- export interface EventEnvelope {
8
- /** Unique event ID (for deduplication) */
9
- id: string;
10
- /** Source connector name */
11
- source: string;
12
- /** Normalized event type */
13
- type: EventType;
14
- /** Repository in owner/repo format */
15
- repo?: string;
16
- /** Issue or PR number */
17
- issueNumber?: number;
18
- /** PR number (distinct from issue for PR-specific events) */
19
- prNumber?: number;
20
- /** Login/username of the sender */
21
- sender: string;
22
- /** Login of the issue/PR original author (distinct from `sender`, the commenter) */
23
- issueAuthor?: string;
24
- /** Whether sender is a bot */
25
- senderIsBot: boolean;
26
- /** Event body text (issue body, comment body, PR body, etc.) */
27
- body: string;
28
- /** Title (for issues/PRs) */
29
- title?: string;
30
- /** Labels on the issue/PR */
31
- labels?: string[];
32
- /** GitHub author association (OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, NONE) */
33
- authorAssociation?: string;
34
- /** Original platform payload (for connector-specific logic) */
35
- raw: unknown;
36
- /** Reply on the same platform/thread */
37
- reply: (msg: string) => Promise<void>;
38
- /**
39
- * Re-assert a "thinking" indicator for this thread, if the platform has one.
40
- * Called at the start of each turn so a batched burst that drains as multiple
41
- * turns shows the indicator for every turn — the per-arrival show is cleared
42
- * by the first turn's reply. No-op for sources without an indicator (CLI).
43
- */
44
- typing?: () => Promise<void>;
45
- /** Timestamp of the event */
46
- timestamp: Date;
47
- }
48
- export type EventType = "issue.opened" | "issue.reopened" | "issue.closed" | "pr.opened" | "pr.synchronize" | "pr.reopened" | "pr.closed" | "pr.merged" | "comment.created" | "pr_review.submitted" | "pr_review_comment.created" | "message";
49
- /**
50
- * Connector interface — all event sources implement this.
51
- * The core engine registers a handler via on('event', ...) and
52
- * receives EventEnvelopes. It never knows which platform sent them.
53
- */
54
- export interface Connector extends EventEmitter {
55
- /** Connector name (e.g., 'github', 'slack', 'discord') */
56
- readonly name: string;
57
- /** Start listening for events */
58
- start(): Promise<void>;
59
- /** Gracefully stop */
60
- stop(): Promise<void>;
61
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/connectors/types.ts"],"names":[],"mappings":""}
@@ -1,33 +0,0 @@
1
- /**
2
- * Cron fan-out: when a cron job context contains a `repos` array, dispatch
3
- * one workflow run per repo instead of passing the array through to a single
4
- * dispatch that expects `context.repo` (singular).
5
- *
6
- * Each per-repo run gets its own workflow_runs row, taskId, sandbox, and
7
- * trigger id, so failures are isolated and the existing per-run resume
8
- * machinery works unchanged.
9
- *
10
- * Concurrency is bounded so 100 repo scans don't spin 100 concurrent
11
- * sandboxes — default is 3, tunable per call.
12
- */
13
- export type CronDispatcher = (workflow: string, context: Record<string, unknown>) => Promise<{
14
- success: boolean;
15
- error?: string;
16
- paused?: boolean;
17
- }>;
18
- export interface FanOutResult {
19
- /** Number of dispatch calls actually made */
20
- dispatched: number;
21
- /** Number that returned !success and !paused (or threw) */
22
- failures: number;
23
- }
24
- export interface FanOutOptions {
25
- /** Max concurrent dispatches. Default 3. */
26
- concurrency?: number;
27
- }
28
- /**
29
- * Dispatch a cron-scheduled workflow, fanning out over `context.repos` when
30
- * present. When absent, behaves like a single dispatch. Always stamps
31
- * `_triggerType: "cron"` on the outgoing context.
32
- */
33
- export declare function dispatchCronWorkflow(workflowName: string, context: Record<string, unknown>, dispatch: CronDispatcher, options?: FanOutOptions): Promise<FanOutResult>;
@@ -1,55 +0,0 @@
1
- /**
2
- * Cron fan-out: when a cron job context contains a `repos` array, dispatch
3
- * one workflow run per repo instead of passing the array through to a single
4
- * dispatch that expects `context.repo` (singular).
5
- *
6
- * Each per-repo run gets its own workflow_runs row, taskId, sandbox, and
7
- * trigger id, so failures are isolated and the existing per-run resume
8
- * machinery works unchanged.
9
- *
10
- * Concurrency is bounded so 100 repo scans don't spin 100 concurrent
11
- * sandboxes — default is 3, tunable per call.
12
- */
13
- /**
14
- * Dispatch a cron-scheduled workflow, fanning out over `context.repos` when
15
- * present. When absent, behaves like a single dispatch. Always stamps
16
- * `_triggerType: "cron"` on the outgoing context.
17
- */
18
- export async function dispatchCronWorkflow(workflowName, context, dispatch, options = {}) {
19
- const base = { ...context, _triggerType: "cron" };
20
- const rawRepos = base.repos;
21
- if (!Array.isArray(rawRepos)) {
22
- const result = await runOne(dispatch, workflowName, base);
23
- return { dispatched: 1, failures: result ? 0 : 1 };
24
- }
25
- const { repos: _drop, ...rest } = base;
26
- const repos = rawRepos.filter((r) => typeof r === "string" && r.length > 0);
27
- if (repos.length === 0) {
28
- return { dispatched: 0, failures: 0 };
29
- }
30
- const concurrency = Math.max(1, options.concurrency ?? 3);
31
- let dispatched = 0;
32
- let failures = 0;
33
- for (let i = 0; i < repos.length; i += concurrency) {
34
- const batch = repos.slice(i, i + concurrency);
35
- const results = await Promise.allSettled(batch.map((repo) => runOne(dispatch, workflowName, { ...rest, repo })));
36
- for (const r of results) {
37
- dispatched++;
38
- const ok = r.status === "fulfilled" && r.value === true;
39
- if (!ok)
40
- failures++;
41
- }
42
- }
43
- return { dispatched, failures };
44
- }
45
- async function runOne(dispatch, workflowName, context) {
46
- try {
47
- const result = await dispatch(workflowName, context);
48
- return !!(result.success || result.paused);
49
- }
50
- catch (err) {
51
- console.error(`[cron-fanout] ${workflowName} dispatch threw for ${String(context.repo ?? "<no repo>")}:`, err);
52
- return false;
53
- }
54
- }
55
- //# sourceMappingURL=fanout.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fanout.js","sourceRoot":"","sources":["../../src/cron/fanout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAmBH;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,OAAgC,EAChC,QAAwB,EACxB,UAAyB,EAAE;IAE3B,MAAM,IAAI,GAA4B,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;IAE5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAC1D,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IACvC,MAAM,KAAK,GAAI,QAAsB,CAAC,MAAM,CAC1C,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAC1D,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAC1D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CACvE,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC;YACxD,IAAI,CAAC,EAAE;gBAAE,QAAQ,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,QAAwB,EACxB,YAAoB,EACpB,OAAgC;IAEhC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,iBAAiB,YAAY,uBAAuB,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,GAAG,EAC1F,GAAG,CACJ,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1,18 +0,0 @@
1
- import type { CronJob } from "./scheduler.js";
2
- import type { StateDb } from "../state/db.js";
3
- /**
4
- * Get cron jobs based on configuration.
5
- *
6
- * Cron job definitions are loaded from workflows/cron-*.yaml files. Each
7
- * cron YAML references an agent workflow by name (workflows/<name>.yaml)
8
- * which is invoked on each tick. When webhooks are enabled
9
- * (WEBHOOK_SECRET is set), jobs with `condition.unless: webhooksEnabled`
10
- * are filtered out — those are handled in real-time via webhook events.
11
- *
12
- * When `db` is supplied, cron_overrides rows applied: disabled jobs are
13
- * dropped and schedule overrides replace the YAML schedule.
14
- */
15
- export declare function getJobs(opts?: {
16
- webhooksEnabled?: boolean;
17
- db?: StateDb;
18
- }): CronJob[];
package/dist/cron/jobs.js DELETED
@@ -1,37 +0,0 @@
1
- import { getManagedRepos } from "../managed-repos.js";
2
- import { getCronWorkflows } from "../workflows/loader.js";
3
- /**
4
- * Get cron jobs based on configuration.
5
- *
6
- * Cron job definitions are loaded from workflows/cron-*.yaml files. Each
7
- * cron YAML references an agent workflow by name (workflows/<name>.yaml)
8
- * which is invoked on each tick. When webhooks are enabled
9
- * (WEBHOOK_SECRET is set), jobs with `condition.unless: webhooksEnabled`
10
- * are filtered out — those are handled in real-time via webhook events.
11
- *
12
- * When `db` is supplied, cron_overrides rows applied: disabled jobs are
13
- * dropped and schedule overrides replace the YAML schedule.
14
- */
15
- export function getJobs(opts) {
16
- const jobs = [];
17
- let cronDefs = getCronWorkflows();
18
- // Apply conditions
19
- if (opts?.webhooksEnabled) {
20
- cronDefs = cronDefs.filter((def) => def.condition?.unless !== "webhooksEnabled");
21
- }
22
- const overrides = opts?.db?.getAllCronOverrides() ?? new Map();
23
- for (const def of cronDefs) {
24
- const override = overrides.get(def.name);
25
- if (override && !override.enabled)
26
- continue;
27
- jobs.push({
28
- name: def.name,
29
- schedule: override?.schedule || def.schedule,
30
- workflow: def.workflow,
31
- // Merge managed repos into the context the workflow receives
32
- context: { repos: getManagedRepos(), ...def.context },
33
- });
34
- }
35
- return jobs;
36
- }
37
- //# sourceMappingURL=jobs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/cron/jobs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAC,IAAkD;IACxE,MAAM,IAAI,GAAc,EAAE,CAAC;IAE3B,IAAI,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IAElC,mBAAmB;IACnB,IAAI,IAAI,EAAE,eAAe,EAAE,CAAC;QAC1B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,iBAAiB,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,IAAI,GAAG,EAAE,CAAC;IAE/D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO;YAAE,SAAS;QAC5C,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,GAAG,CAAC,QAAQ;YAC5C,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,6DAA6D;YAC7D,OAAO,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;SACtD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,45 +0,0 @@
1
- import type { StateDb } from "../state/db.js";
2
- export interface CronJob {
3
- name: string;
4
- schedule: string;
5
- /** Name of an agent workflow (workflows/<name>.yaml) to invoke on each tick */
6
- workflow: string;
7
- context: Record<string, unknown>;
8
- /** Maximum consecutive failures before alerting */
9
- maxFailures?: number;
10
- }
11
- /** A lightweight direct job — runs a function, not a workflow */
12
- export interface DirectCronJob {
13
- name: string;
14
- schedule: string;
15
- handler: () => Promise<void>;
16
- }
17
- export type WorkflowRunner = (workflow: string, context: Record<string, unknown>) => Promise<void>;
18
- /**
19
- * Cron scheduler with overlap protection and failure tracking.
20
- * Each job runs a workflow via the agent runner, tracked in SQLite.
21
- */
22
- export declare class CronScheduler {
23
- private jobs;
24
- private running;
25
- private db;
26
- private runner;
27
- constructor(db: StateDb, runner: WorkflowRunner);
28
- register(job: CronJob): void;
29
- /** Register a lightweight direct handler (no skill/sandbox overhead) */
30
- registerDirect(job: DirectCronJob): void;
31
- /** Whether a cron with this name is currently registered. */
32
- has(name: string): boolean;
33
- /** Stop and remove a single cron. No-op if not registered. */
34
- unregister(name: string): void;
35
- /** Replace an existing cron with a new schedule/context. Equivalent to unregister + register. */
36
- update(job: CronJob): void;
37
- /** Snapshot of registered jobs with the croner-computed next-run timestamp. */
38
- list(): Array<{
39
- name: string;
40
- schedule: string;
41
- nextRun: Date | null;
42
- }>;
43
- /** Stop all cron jobs */
44
- stopAll(): void;
45
- }
@@ -1,105 +0,0 @@
1
- import { Cron } from "croner";
2
- /**
3
- * Cron scheduler with overlap protection and failure tracking.
4
- * Each job runs a workflow via the agent runner, tracked in SQLite.
5
- */
6
- export class CronScheduler {
7
- jobs = new Map();
8
- running = new Set();
9
- db;
10
- runner;
11
- constructor(db, runner) {
12
- this.db = db;
13
- this.runner = runner;
14
- }
15
- register(job) {
16
- if (this.jobs.has(job.name)) {
17
- throw new Error(`Cron job "${job.name}" already registered`);
18
- }
19
- const cronJob = new Cron(job.schedule, async () => {
20
- // Overlap protection — skip if still running
21
- if (this.running.has(job.name)) {
22
- console.log(`[cron] Skipping ${job.name} — still running from previous tick`);
23
- return;
24
- }
25
- this.running.add(job.name);
26
- console.log(`[cron] Running: ${job.name}`);
27
- try {
28
- await this.runner(job.workflow, job.context);
29
- }
30
- catch (err) {
31
- console.error(`[cron] ${job.name} failed:`, err.message);
32
- // Check consecutive failures (tracked under the workflow name)
33
- const failures = this.db.executions.consecutiveFailures(job.workflow);
34
- const max = job.maxFailures || 3;
35
- if (failures >= max) {
36
- console.error(`[cron] ALERT: ${job.name} has failed ${failures} times consecutively`);
37
- // TODO: send alert (Slack webhook, email, etc.)
38
- }
39
- }
40
- finally {
41
- this.running.delete(job.name);
42
- }
43
- });
44
- this.jobs.set(job.name, cronJob);
45
- console.log(`[cron] Registered: ${job.name} (${job.schedule})`);
46
- }
47
- /** Register a lightweight direct handler (no skill/sandbox overhead) */
48
- registerDirect(job) {
49
- if (this.jobs.has(job.name)) {
50
- throw new Error(`Cron job "${job.name}" already registered`);
51
- }
52
- const cronJob = new Cron(job.schedule, async () => {
53
- if (this.running.has(job.name)) {
54
- return;
55
- }
56
- this.running.add(job.name);
57
- try {
58
- await job.handler();
59
- }
60
- catch (err) {
61
- console.error(`[cron] ${job.name} failed:`, err.message);
62
- }
63
- finally {
64
- this.running.delete(job.name);
65
- }
66
- });
67
- this.jobs.set(job.name, cronJob);
68
- console.log(`[cron] Registered: ${job.name} (${job.schedule})`);
69
- }
70
- /** Whether a cron with this name is currently registered. */
71
- has(name) {
72
- return this.jobs.has(name);
73
- }
74
- /** Stop and remove a single cron. No-op if not registered. */
75
- unregister(name) {
76
- const job = this.jobs.get(name);
77
- if (!job)
78
- return;
79
- job.stop();
80
- this.jobs.delete(name);
81
- console.log(`[cron] Stopped: ${name}`);
82
- }
83
- /** Replace an existing cron with a new schedule/context. Equivalent to unregister + register. */
84
- update(job) {
85
- this.unregister(job.name);
86
- this.register(job);
87
- }
88
- /** Snapshot of registered jobs with the croner-computed next-run timestamp. */
89
- list() {
90
- return Array.from(this.jobs.entries()).map(([name, cronJob]) => ({
91
- name,
92
- schedule: cronJob.getPattern() ?? "",
93
- nextRun: cronJob.nextRun(),
94
- }));
95
- }
96
- /** Stop all cron jobs */
97
- stopAll() {
98
- for (const [name, job] of this.jobs) {
99
- job.stop();
100
- console.log(`[cron] Stopped: ${name}`);
101
- }
102
- this.jobs.clear();
103
- }
104
- }
105
- //# sourceMappingURL=scheduler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/cron/scheduler.ts"],"names":[],"mappings":"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"}