lastlight 0.1.8 → 0.2.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 (478) hide show
  1. package/README.md +265 -118
  2. package/agent-context/rules.md +62 -9
  3. package/agent-context/security.md +69 -0
  4. package/config/default.yaml +89 -0
  5. package/deploy/.env.production.example +20 -2
  6. package/deploy/entrypoint.sh +16 -17
  7. package/deploy/native/README.md +160 -0
  8. package/deploy/native/install.sh +110 -0
  9. package/deploy/native/lastlight.env.example +95 -0
  10. package/deploy/native/lastlight.service +50 -0
  11. package/deploy/sandbox-entrypoint.sh +59 -42
  12. package/dist/admin/auth.d.ts +1 -1
  13. package/dist/admin/auth.js +3 -1
  14. package/dist/admin/auth.js.map +1 -1
  15. package/dist/admin/chat-session-reader.d.ts +11 -14
  16. package/dist/admin/chat-session-reader.js +27 -51
  17. package/dist/admin/chat-session-reader.js.map +1 -1
  18. package/dist/admin/docker.d.ts +37 -0
  19. package/dist/admin/docker.js +86 -1
  20. package/dist/admin/docker.js.map +1 -1
  21. package/dist/admin/index.js +38 -3
  22. package/dist/admin/index.js.map +1 -1
  23. package/dist/admin/log-search.test.d.ts +1 -0
  24. package/dist/admin/log-search.test.js +78 -0
  25. package/dist/admin/log-search.test.js.map +1 -0
  26. package/dist/admin/routes.d.ts +52 -3
  27. package/dist/admin/routes.js +780 -63
  28. package/dist/admin/routes.js.map +1 -1
  29. package/dist/admin/routes.test.js +680 -14
  30. package/dist/admin/routes.test.js.map +1 -1
  31. package/dist/admin/server-logs.test.d.ts +1 -0
  32. package/dist/admin/server-logs.test.js +58 -0
  33. package/dist/admin/server-logs.test.js.map +1 -0
  34. package/dist/admin/sessions.d.ts +26 -39
  35. package/dist/admin/sessions.js +86 -310
  36. package/dist/admin/sessions.js.map +1 -1
  37. package/dist/admin/sessions.test.d.ts +1 -0
  38. package/dist/admin/sessions.test.js +78 -0
  39. package/dist/admin/sessions.test.js.map +1 -0
  40. package/dist/admin/version.d.ts +15 -0
  41. package/dist/admin/version.js +73 -0
  42. package/dist/admin/version.js.map +1 -0
  43. package/dist/admin/version.test.d.ts +1 -0
  44. package/dist/admin/version.test.js +71 -0
  45. package/dist/admin/version.test.js.map +1 -0
  46. package/dist/cli-config.d.ts +55 -0
  47. package/dist/cli-config.js +119 -0
  48. package/dist/cli-config.js.map +1 -0
  49. package/dist/cli-config.test.d.ts +1 -0
  50. package/dist/cli-config.test.js +92 -0
  51. package/dist/cli-config.test.js.map +1 -0
  52. package/dist/cli-format.d.ts +19 -0
  53. package/dist/cli-format.js +107 -0
  54. package/dist/cli-format.js.map +1 -0
  55. package/dist/cli-server.d.ts +73 -0
  56. package/dist/cli-server.js +347 -0
  57. package/dist/cli-server.js.map +1 -0
  58. package/dist/cli-server.test.d.ts +1 -0
  59. package/dist/cli-server.test.js +38 -0
  60. package/dist/cli-server.test.js.map +1 -0
  61. package/dist/cli-timeline.d.ts +35 -0
  62. package/dist/cli-timeline.js +373 -0
  63. package/dist/cli-timeline.js.map +1 -0
  64. package/dist/cli-timeline.test.d.ts +1 -0
  65. package/dist/cli-timeline.test.js +104 -0
  66. package/dist/cli-timeline.test.js.map +1 -0
  67. package/dist/cli.d.ts +0 -19
  68. package/dist/cli.js +910 -194
  69. package/dist/cli.js.map +1 -1
  70. package/dist/config-overlay.test.d.ts +1 -0
  71. package/dist/config-overlay.test.js +112 -0
  72. package/dist/config-overlay.test.js.map +1 -0
  73. package/dist/config-resolve.d.ts +28 -0
  74. package/dist/config-resolve.js +47 -0
  75. package/dist/config-resolve.js.map +1 -0
  76. package/dist/config-resolve.test.d.ts +1 -0
  77. package/dist/config-resolve.test.js +68 -0
  78. package/dist/config-resolve.test.js.map +1 -0
  79. package/dist/config.d.ts +62 -49
  80. package/dist/config.js +452 -76
  81. package/dist/config.js.map +1 -1
  82. package/dist/config.test.js +201 -32
  83. package/dist/config.test.js.map +1 -1
  84. package/dist/connectors/github-webhook.js +83 -5
  85. package/dist/connectors/github-webhook.js.map +1 -1
  86. package/dist/connectors/github-webhook.test.d.ts +1 -0
  87. package/dist/connectors/github-webhook.test.js +156 -0
  88. package/dist/connectors/github-webhook.test.js.map +1 -0
  89. package/dist/connectors/messaging/session-manager.d.ts +18 -0
  90. package/dist/connectors/messaging/session-manager.js +83 -2
  91. package/dist/connectors/messaging/session-manager.js.map +1 -1
  92. package/dist/connectors/messaging/session-manager.test.d.ts +1 -0
  93. package/dist/connectors/messaging/session-manager.test.js +144 -0
  94. package/dist/connectors/messaging/session-manager.test.js.map +1 -0
  95. package/dist/connectors/slack/connector.d.ts +9 -0
  96. package/dist/connectors/slack/connector.js +15 -0
  97. package/dist/connectors/slack/connector.js.map +1 -1
  98. package/dist/connectors/slack/mrkdwn.js +81 -0
  99. package/dist/connectors/slack/mrkdwn.js.map +1 -1
  100. package/dist/connectors/slack/mrkdwn.test.js +49 -0
  101. package/dist/connectors/slack/mrkdwn.test.js.map +1 -1
  102. package/dist/connectors/types.d.ts +1 -1
  103. package/dist/cron/fanout.d.ts +33 -0
  104. package/dist/cron/fanout.js +55 -0
  105. package/dist/cron/fanout.js.map +1 -0
  106. package/dist/cron/fanout.test.d.ts +1 -0
  107. package/dist/cron/fanout.test.js +73 -0
  108. package/dist/cron/fanout.test.js.map +1 -0
  109. package/dist/cron/jobs.d.ts +5 -0
  110. package/dist/cron/jobs.js +10 -3
  111. package/dist/cron/jobs.js.map +1 -1
  112. package/dist/cron/scheduler.d.ts +12 -0
  113. package/dist/cron/scheduler.js +27 -1
  114. package/dist/cron/scheduler.js.map +1 -1
  115. package/dist/engine/agent-executor.d.ts +158 -0
  116. package/dist/engine/agent-executor.js +1140 -0
  117. package/dist/engine/agent-executor.js.map +1 -0
  118. package/dist/engine/agent-executor.test.d.ts +1 -0
  119. package/dist/engine/agent-executor.test.js +395 -0
  120. package/dist/engine/agent-executor.test.js.map +1 -0
  121. package/dist/engine/chat-runner.d.ts +123 -0
  122. package/dist/engine/chat-runner.js +379 -0
  123. package/dist/engine/chat-runner.js.map +1 -0
  124. package/dist/engine/chat-runner.test.d.ts +1 -0
  125. package/dist/engine/chat-runner.test.js +104 -0
  126. package/dist/engine/chat-runner.test.js.map +1 -0
  127. package/dist/engine/chat-skills.d.ts +45 -0
  128. package/dist/engine/chat-skills.js +184 -0
  129. package/dist/engine/chat-skills.js.map +1 -0
  130. package/dist/engine/chat-skills.test.d.ts +1 -0
  131. package/dist/engine/chat-skills.test.js +20 -0
  132. package/dist/engine/chat-skills.test.js.map +1 -0
  133. package/dist/engine/chat.d.ts +20 -23
  134. package/dist/engine/chat.js +251 -155
  135. package/dist/engine/chat.js.map +1 -1
  136. package/dist/engine/chat.test.d.ts +1 -0
  137. package/dist/engine/chat.test.js +42 -0
  138. package/dist/engine/chat.test.js.map +1 -0
  139. package/dist/engine/classifier.d.ts +35 -2
  140. package/dist/engine/classifier.js +170 -31
  141. package/dist/engine/classifier.js.map +1 -1
  142. package/dist/engine/classifier.test.d.ts +1 -0
  143. package/dist/engine/classifier.test.js +115 -0
  144. package/dist/engine/classifier.test.js.map +1 -0
  145. package/dist/engine/dispatcher.d.ts +60 -0
  146. package/dist/engine/dispatcher.js +601 -0
  147. package/dist/engine/dispatcher.js.map +1 -0
  148. package/dist/engine/dispatcher.test.d.ts +1 -0
  149. package/dist/engine/dispatcher.test.js +511 -0
  150. package/dist/engine/dispatcher.test.js.map +1 -0
  151. package/dist/engine/event-shim.d.ts +117 -0
  152. package/dist/engine/event-shim.js +435 -0
  153. package/dist/engine/event-shim.js.map +1 -0
  154. package/dist/engine/event-shim.test.d.ts +1 -0
  155. package/dist/engine/event-shim.test.js +194 -0
  156. package/dist/engine/event-shim.test.js.map +1 -0
  157. package/dist/engine/git-auth.d.ts +13 -17
  158. package/dist/engine/git-auth.js +99 -42
  159. package/dist/engine/git-auth.js.map +1 -1
  160. package/dist/engine/git-auth.test.d.ts +1 -0
  161. package/dist/engine/git-auth.test.js +117 -0
  162. package/dist/engine/git-auth.test.js.map +1 -0
  163. package/dist/engine/github-app-client.d.ts +7 -0
  164. package/dist/engine/github-app-client.js +16 -0
  165. package/dist/engine/github-app-client.js.map +1 -0
  166. package/dist/engine/github-app-client.test.d.ts +1 -0
  167. package/dist/engine/github-app-client.test.js +44 -0
  168. package/dist/engine/github-app-client.test.js.map +1 -0
  169. package/dist/engine/github-tools.d.ts +12 -0
  170. package/dist/engine/github-tools.js +261 -0
  171. package/dist/engine/github-tools.js.map +1 -0
  172. package/dist/engine/github.d.ts +1027 -43
  173. package/dist/engine/github.js +153 -14
  174. package/dist/engine/github.js.map +1 -1
  175. package/dist/engine/llm.d.ts +47 -0
  176. package/dist/engine/llm.js +221 -0
  177. package/dist/engine/llm.js.map +1 -0
  178. package/dist/engine/llm.test.d.ts +1 -0
  179. package/dist/engine/llm.test.js +189 -0
  180. package/dist/engine/llm.test.js.map +1 -0
  181. package/dist/engine/profiles.d.ts +249 -0
  182. package/dist/engine/profiles.js +42 -0
  183. package/dist/engine/profiles.js.map +1 -0
  184. package/dist/engine/router.d.ts +12 -6
  185. package/dist/engine/router.js +339 -81
  186. package/dist/engine/router.js.map +1 -1
  187. package/dist/engine/router.test.js +428 -78
  188. package/dist/engine/router.test.js.map +1 -1
  189. package/dist/engine/screen.d.ts +41 -0
  190. package/dist/engine/screen.js +93 -0
  191. package/dist/engine/screen.js.map +1 -0
  192. package/dist/engine/screen.test.d.ts +1 -0
  193. package/dist/engine/screen.test.js +82 -0
  194. package/dist/engine/screen.test.js.map +1 -0
  195. package/dist/index.js +423 -437
  196. package/dist/index.js.map +1 -1
  197. package/dist/managed-repos.d.ts +7 -9
  198. package/dist/managed-repos.js +12 -15
  199. package/dist/managed-repos.js.map +1 -1
  200. package/dist/managed-repos.test.js +24 -19
  201. package/dist/managed-repos.test.js.map +1 -1
  202. package/dist/notify/index.d.ts +15 -0
  203. package/dist/notify/index.js +6 -0
  204. package/dist/notify/index.js.map +1 -0
  205. package/dist/notify/model.d.ts +57 -0
  206. package/dist/notify/model.js +89 -0
  207. package/dist/notify/model.js.map +1 -0
  208. package/dist/notify/model.test.d.ts +1 -0
  209. package/dist/notify/model.test.js +109 -0
  210. package/dist/notify/model.test.js.map +1 -0
  211. package/dist/notify/notifier.d.ts +17 -0
  212. package/dist/notify/notifier.js +87 -0
  213. package/dist/notify/notifier.js.map +1 -0
  214. package/dist/notify/notifier.test.d.ts +1 -0
  215. package/dist/notify/notifier.test.js +100 -0
  216. package/dist/notify/notifier.test.js.map +1 -0
  217. package/dist/notify/render.d.ts +21 -0
  218. package/dist/notify/render.js +59 -0
  219. package/dist/notify/render.js.map +1 -0
  220. package/dist/notify/render.test.d.ts +1 -0
  221. package/dist/notify/render.test.js +65 -0
  222. package/dist/notify/render.test.js.map +1 -0
  223. package/dist/notify/transports/github.d.ts +26 -0
  224. package/dist/notify/transports/github.js +26 -0
  225. package/dist/notify/transports/github.js.map +1 -0
  226. package/dist/notify/transports/slack.d.ts +26 -0
  227. package/dist/notify/transports/slack.js +28 -0
  228. package/dist/notify/transports/slack.js.map +1 -0
  229. package/dist/notify/transports.test.d.ts +1 -0
  230. package/dist/notify/transports.test.js +71 -0
  231. package/dist/notify/transports.test.js.map +1 -0
  232. package/dist/notify/types.d.ts +95 -0
  233. package/dist/notify/types.js +16 -0
  234. package/dist/notify/types.js.map +1 -0
  235. package/dist/sandbox/docker-compose.test.d.ts +1 -0
  236. package/dist/sandbox/docker-compose.test.js +128 -0
  237. package/dist/sandbox/docker-compose.test.js.map +1 -0
  238. package/dist/sandbox/docker.d.ts +97 -9
  239. package/dist/sandbox/docker.js +192 -41
  240. package/dist/sandbox/docker.js.map +1 -1
  241. package/dist/sandbox/docker.test.d.ts +1 -0
  242. package/dist/sandbox/docker.test.js +137 -0
  243. package/dist/sandbox/docker.test.js.map +1 -0
  244. package/dist/sandbox/egress-allowlist.d.ts +69 -0
  245. package/dist/sandbox/egress-allowlist.js +164 -0
  246. package/dist/sandbox/egress-allowlist.js.map +1 -0
  247. package/dist/sandbox/egress-allowlist.test.d.ts +1 -0
  248. package/dist/sandbox/egress-allowlist.test.js +65 -0
  249. package/dist/sandbox/egress-allowlist.test.js.map +1 -0
  250. package/dist/sandbox/egress-firewall-config.d.ts +127 -0
  251. package/dist/sandbox/egress-firewall-config.js +434 -0
  252. package/dist/sandbox/egress-firewall-config.js.map +1 -0
  253. package/dist/sandbox/egress-firewall-config.test.d.ts +1 -0
  254. package/dist/sandbox/egress-firewall-config.test.js +244 -0
  255. package/dist/sandbox/egress-firewall-config.test.js.map +1 -0
  256. package/dist/sandbox/images.d.ts +23 -0
  257. package/dist/sandbox/images.js +55 -0
  258. package/dist/sandbox/images.js.map +1 -0
  259. package/dist/sandbox/index.d.ts +82 -3
  260. package/dist/sandbox/index.js +223 -93
  261. package/dist/sandbox/index.js.map +1 -1
  262. package/dist/sandbox/index.test.d.ts +1 -0
  263. package/dist/sandbox/index.test.js +157 -0
  264. package/dist/sandbox/index.test.js.map +1 -0
  265. package/dist/session-log.d.ts +63 -0
  266. package/dist/session-log.js +290 -0
  267. package/dist/session-log.js.map +1 -0
  268. package/dist/session-log.test.d.ts +1 -0
  269. package/dist/session-log.test.js +85 -0
  270. package/dist/session-log.test.js.map +1 -0
  271. package/dist/setup.d.ts +31 -12
  272. package/dist/setup.js +516 -174
  273. package/dist/setup.js.map +1 -1
  274. package/dist/setup.test.js +138 -6
  275. package/dist/setup.test.js.map +1 -1
  276. package/dist/state/approval-store.d.ts +86 -0
  277. package/dist/state/approval-store.js +140 -0
  278. package/dist/state/approval-store.js.map +1 -0
  279. package/dist/state/build-assets.d.ts +50 -0
  280. package/dist/state/build-assets.js +154 -0
  281. package/dist/state/build-assets.js.map +1 -0
  282. package/dist/state/build-assets.test.d.ts +1 -0
  283. package/dist/state/build-assets.test.js +106 -0
  284. package/dist/state/build-assets.test.js.map +1 -0
  285. package/dist/state/db.d.ts +65 -333
  286. package/dist/state/db.js +112 -835
  287. package/dist/state/db.js.map +1 -1
  288. package/dist/state/db.test.js +127 -91
  289. package/dist/state/db.test.js.map +1 -1
  290. package/dist/state/execution-store.d.ts +257 -0
  291. package/dist/state/execution-store.js +527 -0
  292. package/dist/state/execution-store.js.map +1 -0
  293. package/dist/state/migrate.d.ts +15 -0
  294. package/dist/state/migrate.js +175 -0
  295. package/dist/state/migrate.js.map +1 -0
  296. package/dist/state/workflow-run-store.d.ts +195 -0
  297. package/dist/state/workflow-run-store.js +363 -0
  298. package/dist/state/workflow-run-store.js.map +1 -0
  299. package/dist/state/workflow-run-store.test.d.ts +1 -0
  300. package/dist/state/workflow-run-store.test.js +264 -0
  301. package/dist/state/workflow-run-store.test.js.map +1 -0
  302. package/dist/telemetry/index.d.ts +38 -0
  303. package/dist/telemetry/index.js +253 -0
  304. package/dist/telemetry/index.js.map +1 -0
  305. package/dist/telemetry/index.test.d.ts +1 -0
  306. package/dist/telemetry/index.test.js +73 -0
  307. package/dist/telemetry/index.test.js.map +1 -0
  308. package/dist/telemetry/pi-events.d.ts +12 -0
  309. package/dist/telemetry/pi-events.js +134 -0
  310. package/dist/telemetry/pi-events.js.map +1 -0
  311. package/dist/telemetry/pi-events.test.d.ts +1 -0
  312. package/dist/telemetry/pi-events.test.js +69 -0
  313. package/dist/telemetry/pi-events.test.js.map +1 -0
  314. package/dist/workflows/dag.d.ts +13 -1
  315. package/dist/workflows/dag.js +7 -3
  316. package/dist/workflows/dag.js.map +1 -1
  317. package/dist/workflows/dag.test.js +22 -0
  318. package/dist/workflows/dag.test.js.map +1 -1
  319. package/dist/workflows/golden-build.test.d.ts +1 -0
  320. package/dist/workflows/golden-build.test.js +45 -0
  321. package/dist/workflows/golden-build.test.js.map +1 -0
  322. package/dist/workflows/loader-overlay.test.d.ts +1 -0
  323. package/dist/workflows/loader-overlay.test.js +101 -0
  324. package/dist/workflows/loader-overlay.test.js.map +1 -0
  325. package/dist/workflows/loader.d.ts +36 -11
  326. package/dist/workflows/loader.js +311 -87
  327. package/dist/workflows/loader.js.map +1 -1
  328. package/dist/workflows/loader.test.js +114 -10
  329. package/dist/workflows/loader.test.js.map +1 -1
  330. package/dist/workflows/loop-eval.js +2 -0
  331. package/dist/workflows/loop-eval.js.map +1 -1
  332. package/dist/workflows/loop-eval.test.js +14 -0
  333. package/dist/workflows/loop-eval.test.js.map +1 -1
  334. package/dist/workflows/phase-executor.d.ts +145 -0
  335. package/dist/workflows/phase-executor.js +691 -0
  336. package/dist/workflows/phase-executor.js.map +1 -0
  337. package/dist/workflows/phase-executor.test.d.ts +1 -0
  338. package/dist/workflows/phase-executor.test.js +434 -0
  339. package/dist/workflows/phase-executor.test.js.map +1 -0
  340. package/dist/workflows/phase-ref.d.ts +44 -0
  341. package/dist/workflows/phase-ref.js +78 -0
  342. package/dist/workflows/phase-ref.js.map +1 -0
  343. package/dist/workflows/phase-ref.test.d.ts +1 -0
  344. package/dist/workflows/phase-ref.test.js +24 -0
  345. package/dist/workflows/phase-ref.test.js.map +1 -0
  346. package/dist/workflows/resume.d.ts +5 -11
  347. package/dist/workflows/resume.js +88 -7
  348. package/dist/workflows/resume.js.map +1 -1
  349. package/dist/workflows/runner.d.ts +34 -27
  350. package/dist/workflows/runner.js +252 -930
  351. package/dist/workflows/runner.js.map +1 -1
  352. package/dist/workflows/runner.test.js +346 -35
  353. package/dist/workflows/runner.test.js.map +1 -1
  354. package/dist/workflows/schema.d.ts +52 -10
  355. package/dist/workflows/schema.js +147 -7
  356. package/dist/workflows/schema.js.map +1 -1
  357. package/dist/workflows/simple.d.ts +67 -3
  358. package/dist/workflows/simple.js +248 -87
  359. package/dist/workflows/simple.js.map +1 -1
  360. package/dist/workflows/simple.test.d.ts +1 -0
  361. package/dist/workflows/simple.test.js +107 -0
  362. package/dist/workflows/simple.test.js.map +1 -0
  363. package/dist/workflows/templates.d.ts +29 -0
  364. package/dist/workflows/templates.js +42 -4
  365. package/dist/workflows/templates.js.map +1 -1
  366. package/dist/workflows/templates.test.js +103 -0
  367. package/dist/workflows/templates.test.js.map +1 -1
  368. package/dist/workflows/triggers.d.ts +21 -0
  369. package/dist/workflows/triggers.js +44 -0
  370. package/dist/workflows/triggers.js.map +1 -0
  371. package/dist/workflows/verdict.d.ts +19 -0
  372. package/dist/workflows/verdict.js +30 -0
  373. package/dist/workflows/verdict.js.map +1 -0
  374. package/dist/workflows/verdict.test.d.ts +1 -0
  375. package/dist/workflows/verdict.test.js +44 -0
  376. package/dist/workflows/verdict.test.js.map +1 -0
  377. package/dist/worktree/manager.d.ts +1 -1
  378. package/dist/worktree/manager.js +14 -14
  379. package/dist/worktree/manager.js.map +1 -1
  380. package/dist/worktree/manager.test.d.ts +1 -0
  381. package/dist/worktree/manager.test.js +87 -0
  382. package/dist/worktree/manager.test.js.map +1 -0
  383. package/docker-compose.yml +206 -5
  384. package/package.json +19 -7
  385. package/sandbox.Dockerfile +97 -18
  386. package/skills/README.md +40 -0
  387. package/skills/browser-qa/SKILL.md +193 -0
  388. package/skills/browser-qa/scripts/agent-browser.mjs +380 -0
  389. package/skills/building/SKILL.md +95 -0
  390. package/skills/chat/SKILL.md +30 -11
  391. package/skills/code-review/SKILL.md +59 -0
  392. package/skills/debug-production/SKILL.md +108 -0
  393. package/skills/demo/SKILL.md +194 -0
  394. package/skills/demo/scripts/compose-demo.sh +205 -0
  395. package/skills/issue-answer/SKILL.md +90 -0
  396. package/skills/issue-comment/SKILL.md +38 -24
  397. package/skills/issue-triage/SKILL.md +103 -37
  398. package/skills/issue-triage/references/AGENT-BRIEF.md +61 -0
  399. package/skills/pr-comment/SKILL.md +64 -0
  400. package/skills/pr-review/SKILL.md +65 -49
  401. package/skills/qa-test/SKILL.md +97 -0
  402. package/skills/repo-health/SKILL.md +48 -45
  403. package/skills/security-feedback/SKILL.md +173 -0
  404. package/skills/security-feedback/references/templates.md +77 -0
  405. package/skills/security-review/SKILL.md +213 -0
  406. package/skills/security-review/references/issue-format.md +302 -0
  407. package/skills/verify/SKILL.md +118 -0
  408. package/workflows/answer.yaml +37 -0
  409. package/workflows/build.yaml +32 -22
  410. package/workflows/cron-security.yaml +6 -0
  411. package/workflows/demo.yaml +55 -0
  412. package/workflows/explore.yaml +9 -0
  413. package/workflows/pr-comment.yaml +16 -0
  414. package/workflows/pr-fix.yaml +3 -0
  415. package/workflows/pr-review.yaml +4 -1
  416. package/workflows/prompts/answer.md +67 -0
  417. package/workflows/prompts/architect.md +24 -7
  418. package/workflows/prompts/demo.md +100 -0
  419. package/workflows/prompts/executor.md +29 -20
  420. package/workflows/prompts/explore-ask.md +51 -22
  421. package/workflows/prompts/explore-publish.md +2 -2
  422. package/workflows/prompts/explore-read.md +24 -10
  423. package/workflows/prompts/explore-synthesize.md +15 -8
  424. package/workflows/prompts/fix.md +9 -10
  425. package/workflows/prompts/guardrails.md +26 -8
  426. package/workflows/prompts/pr-fix.md +6 -7
  427. package/workflows/prompts/pr.md +11 -10
  428. package/workflows/prompts/qa-browser.md +95 -0
  429. package/workflows/prompts/qa-synth.md +44 -0
  430. package/workflows/prompts/qa-test.md +60 -0
  431. package/workflows/prompts/re-reviewer.md +8 -9
  432. package/workflows/prompts/reviewer.md +10 -9
  433. package/workflows/prompts/verify-browser.md +93 -0
  434. package/workflows/prompts/verify-synth.md +44 -0
  435. package/workflows/prompts/verify.md +63 -0
  436. package/workflows/qa-test.yaml +87 -0
  437. package/workflows/security-feedback.yaml +25 -0
  438. package/workflows/security-review.yaml +29 -0
  439. package/workflows/verify.yaml +85 -0
  440. package/deploy/mcp-config.tmpl.json +0 -14
  441. package/dist/cron/rate-limits.d.ts +0 -26
  442. package/dist/cron/rate-limits.js +0 -193
  443. package/dist/cron/rate-limits.js.map +0 -1
  444. package/dist/engine/executor.d.ts +0 -75
  445. package/dist/engine/executor.js +0 -292
  446. package/dist/engine/executor.js.map +0 -1
  447. package/mcp-github-app/package.json +0 -18
  448. package/mcp-github-app/src/auth.js +0 -66
  449. package/mcp-github-app/src/github.js +0 -371
  450. package/mcp-github-app/src/index.js +0 -534
  451. package/skills/devops/webhook-subscriptions/SKILL.md +0 -180
  452. package/skills/github/DESCRIPTION.md +0 -3
  453. package/skills/github/codebase-inspection/SKILL.md +0 -115
  454. package/skills/github/github-auth/SKILL.md +0 -54
  455. package/skills/github/github-auth/scripts/gh-env.sh +0 -66
  456. package/skills/github/github-code-review/SKILL.md +0 -480
  457. package/skills/github/github-code-review/references/review-output-template.md +0 -74
  458. package/skills/github/github-issues/SKILL.md +0 -369
  459. package/skills/github/github-issues/templates/bug-report.md +0 -35
  460. package/skills/github/github-issues/templates/feature-request.md +0 -31
  461. package/skills/github/github-pr-workflow/SKILL.md +0 -395
  462. package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +0 -183
  463. package/skills/github/github-pr-workflow/references/conventional-commits.md +0 -71
  464. package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +0 -35
  465. package/skills/github/github-pr-workflow/templates/pr-body-feature.md +0 -33
  466. package/skills/github/github-repo-management/SKILL.md +0 -515
  467. package/skills/github/github-repo-management/references/github-api-cheatsheet.md +0 -161
  468. package/skills/github-orchestrator/SKILL.md +0 -103
  469. package/skills/mcp/DESCRIPTION.md +0 -3
  470. package/skills/mcp/mcporter/SKILL.md +0 -122
  471. package/skills/mcp/native-mcp/SKILL.md +0 -356
  472. package/skills/software-development/architect/SKILL.md +0 -154
  473. package/skills/software-development/assure-guardrails/SKILL.md +0 -239
  474. package/skills/software-development/plan/SKILL.md +0 -64
  475. package/skills/software-development/requesting-code-review/SKILL.md +0 -291
  476. package/skills/software-development/subagent-driven-development/SKILL.md +0 -433
  477. package/skills/software-development/systematic-debugging/SKILL.md +0 -366
  478. package/skills/software-development/test-driven-development/SKILL.md +0 -342
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env bash
2
+ # compose-demo.sh — composite a raw browser screen recording into a titled,
3
+ # size-capped demo mp4 using ffmpeg only (NO Remotion, NO headless render).
4
+ #
5
+ # Used by the `/demo` workflow: agent-browser records the session to a .webm,
6
+ # this script turns it into a polished, GitHub-embeddable mp4.
7
+ #
8
+ # Usage:
9
+ # compose-demo.sh --output demo.mp4 --title "PR #42 — Add dark mode" \
10
+ # [--subtitle "..."] [--layout single|side-by-side] \
11
+ # [--labels "BEFORE (main)" "AFTER (PR)"] [--speed 1.5] \
12
+ # [--trim START:END] [--target-size-mb 5] [--width 1280] [--height 720] \
13
+ # [--title-secs 2.5] <clip1.webm> [clip2.webm]
14
+ #
15
+ # What it does:
16
+ # 1. Normalizes each input clip (optional trim, speed-up, scale+pad to the
17
+ # panel size, fps/pixfmt/SAR normalize, optional per-panel label).
18
+ # 2. Lays out the body: a single panel, or two panels side-by-side (hstack).
19
+ # 3. Prepends a title/subtitle card (solid bg + drawtext).
20
+ # 4. Two-pass H.264 encode targeting --target-size-mb so the mp4 lands under
21
+ # GitHub's inline-embed limit; yuv420p + +faststart for web streaming.
22
+ # 5. Prints an ffprobe summary (resolution / duration / size).
23
+ #
24
+ # Prerequisites: ffmpeg, ffprobe (baked into lastlight-sandbox-qa:latest).
25
+ # Runs fully offline.
26
+
27
+ set -euo pipefail
28
+
29
+ die() { echo "compose-demo.sh: error: $*" >&2; exit 1; }
30
+ require_cmd() { command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"; }
31
+ require_cmd ffmpeg
32
+ require_cmd ffprobe
33
+
34
+ # ── Defaults ────────────────────────────────────────────────────────────────
35
+ OUTPUT=""
36
+ TITLE=""
37
+ SUBTITLE=""
38
+ LAYOUT="single"
39
+ LABEL1=""
40
+ LABEL2=""
41
+ SPEED="1"
42
+ TRIM=""
43
+ TARGET_MB="5"
44
+ WIDTH="1280"
45
+ HEIGHT="720"
46
+ TITLE_SECS="2.5"
47
+ CLIPS=()
48
+
49
+ # ── Parse args ──────────────────────────────────────────────────────────────
50
+ while [[ $# -gt 0 ]]; do
51
+ case "$1" in
52
+ --output) OUTPUT="$2"; shift 2;;
53
+ --title) TITLE="$2"; shift 2;;
54
+ --subtitle) SUBTITLE="$2"; shift 2;;
55
+ --layout) LAYOUT="$2"; shift 2;;
56
+ --labels) LABEL1="$2"; LABEL2="$3"; shift 3;;
57
+ --speed) SPEED="$2"; shift 2;;
58
+ --trim) TRIM="$2"; shift 2;;
59
+ --target-size-mb) TARGET_MB="$2"; shift 2;;
60
+ --width) WIDTH="$2"; shift 2;;
61
+ --height) HEIGHT="$2"; shift 2;;
62
+ --title-secs) TITLE_SECS="$2"; shift 2;;
63
+ -*) die "unknown flag: $1";;
64
+ *) CLIPS+=("$1"); shift;;
65
+ esac
66
+ done
67
+
68
+ [[ -n "$OUTPUT" ]] || die "--output is required"
69
+ [[ ${#CLIPS[@]} -ge 1 ]] || die "at least one input clip is required"
70
+ for c in "${CLIPS[@]}"; do [[ -f "$c" ]] || die "clip not found: $c"; done
71
+ if [[ "$LAYOUT" == "side-by-side" ]]; then
72
+ [[ ${#CLIPS[@]} -ge 2 ]] || die "side-by-side layout needs two clips"
73
+ fi
74
+
75
+ WORK="$(mktemp -d "${TMPDIR:-/tmp}/compose-demo-XXXXXX")"
76
+ cleanup() { rm -rf "$WORK"; }
77
+ trap cleanup EXIT
78
+
79
+ # ── Font for drawtext ────────────────────────────────────────────────────────
80
+ # Prefer an explicit fontfile (Liberation ships in the QA image via
81
+ # fonts-liberation); fall back to fontconfig's default Sans family.
82
+ FONT="${DEMO_FONT:-}"
83
+ if [[ -z "$FONT" ]]; then
84
+ for f in \
85
+ /usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf \
86
+ /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf; do
87
+ [[ -f "$f" ]] && FONT="$f" && break
88
+ done
89
+ fi
90
+ if [[ -n "$FONT" ]]; then FONTARG="fontfile=${FONT}"; else FONTARG="font=Sans"; fi
91
+
92
+ # drawtext drives the title card and per-panel labels. The Debian `ffmpeg`
93
+ # package (the QA image) is built with libfreetype so it's present; but degrade
94
+ # gracefully on a build without it (omit text overlays) rather than failing the
95
+ # whole compose — the demo video is still worth shipping.
96
+ HAS_DRAWTEXT=0
97
+ if ffmpeg -hide_banner -filters 2>/dev/null | grep -q 'drawtext'; then
98
+ HAS_DRAWTEXT=1
99
+ else
100
+ echo "compose-demo.sh: warning: this ffmpeg lacks the drawtext filter — title card and labels omitted." >&2
101
+ fi
102
+
103
+ # Panel size: side-by-side splits the width into two equal panels.
104
+ PH="$HEIGHT"
105
+ if [[ "$LAYOUT" == "side-by-side" ]]; then PW=$(( WIDTH / 2 )); else PW="$WIDTH"; fi
106
+
107
+ # ── Stage A: normalize one clip into a body panel ─────────────────────────────
108
+ # Args: <input> <outfile> <label-file-or-empty> <apply-trim:0|1>
109
+ build_panel() {
110
+ local input="$1" outfile="$2" labelfile="$3" apply_trim="$4"
111
+ local trim_args=()
112
+ if [[ "$apply_trim" == "1" && -n "$TRIM" ]]; then
113
+ local start="${TRIM%%:*}" end="${TRIM##*:}"
114
+ [[ -n "$start" ]] && trim_args+=(-ss "$start")
115
+ [[ -n "$end" ]] && trim_args+=(-to "$end")
116
+ fi
117
+ local vf="setpts=PTS/${SPEED}"
118
+ vf+=",scale=${PW}:${PH}:force_original_aspect_ratio=decrease"
119
+ vf+=",pad=${PW}:${PH}:(ow-iw)/2:(oh-ih)/2:color=black"
120
+ vf+=",fps=30,format=yuv420p,setsar=1"
121
+ if [[ -n "$labelfile" && "$HAS_DRAWTEXT" == "1" ]]; then
122
+ vf+=",drawtext=${FONTARG}:textfile=${labelfile}:x=(w-text_w)/2:y=h-th-24"
123
+ vf+=":fontsize=26:fontcolor=white:box=1:boxcolor=black@0.55:boxborderw=12"
124
+ fi
125
+ # `${arr[@]+"${arr[@]}"}` expands to nothing when the array is empty without
126
+ # tripping `set -u` (an empty `"${arr[@]}"` errors on bash < 4.4, e.g. macOS).
127
+ ffmpeg -y -loglevel error ${trim_args[@]+"${trim_args[@]}"} -i "$input" \
128
+ -vf "$vf" -an -c:v libx264 -crf 20 -preset veryfast "$outfile"
129
+ }
130
+
131
+ # Per-panel labels (side-by-side) written to files to avoid drawtext escaping.
132
+ LABELFILE1=""; LABELFILE2=""
133
+ if [[ "$LAYOUT" == "side-by-side" ]]; then
134
+ if [[ -n "$LABEL1" ]]; then LABELFILE1="$WORK/label1.txt"; printf '%s' "$LABEL1" > "$LABELFILE1"; fi
135
+ if [[ -n "$LABEL2" ]]; then LABELFILE2="$WORK/label2.txt"; printf '%s' "$LABEL2" > "$LABELFILE2"; fi
136
+ fi
137
+
138
+ echo "compose-demo.sh: normalizing clips (layout=$LAYOUT, speed=${SPEED}x)…" >&2
139
+ build_panel "${CLIPS[0]}" "$WORK/panel0.mp4" "$LABELFILE1" 1
140
+ BODY="$WORK/body.mp4"
141
+ if [[ "$LAYOUT" == "side-by-side" ]]; then
142
+ build_panel "${CLIPS[1]}" "$WORK/panel1.mp4" "$LABELFILE2" 1
143
+ ffmpeg -y -loglevel error -i "$WORK/panel0.mp4" -i "$WORK/panel1.mp4" \
144
+ -filter_complex "[0:v][1:v]hstack=inputs=2,format=yuv420p,setsar=1[v]" \
145
+ -map "[v]" -an -c:v libx264 -crf 20 -preset veryfast "$BODY"
146
+ else
147
+ BODY="$WORK/panel0.mp4"
148
+ fi
149
+
150
+ # ── Stage B: title card (skipped when drawtext is unavailable) ───────────────
151
+ TITLE_CLIP=""
152
+ TITLE_DUR="0"
153
+ if [[ "$HAS_DRAWTEXT" == "1" ]]; then
154
+ TITLEFILE="$WORK/title.txt"; printf '%s' "${TITLE:-Demo}" > "$TITLEFILE"
155
+ TITLE_VF="drawtext=${FONTARG}:textfile=${TITLEFILE}:x=(w-text_w)/2:y=(h/2)-th-10:fontsize=48:fontcolor=white"
156
+ if [[ -n "$SUBTITLE" ]]; then
157
+ SUBFILE="$WORK/subtitle.txt"; printf '%s' "$SUBTITLE" > "$SUBFILE"
158
+ TITLE_VF+=",drawtext=${FONTARG}:textfile=${SUBFILE}:x=(w-text_w)/2:y=(h/2)+10:fontsize=26:fontcolor=0xb0b0b0"
159
+ fi
160
+ TITLE_VF+=",format=yuv420p"
161
+ ffmpeg -y -loglevel error -f lavfi -i "color=c=0x101418:s=${WIDTH}x${HEIGHT}:d=${TITLE_SECS}:r=30" \
162
+ -vf "$TITLE_VF" -c:v libx264 -crf 20 -preset veryfast "$WORK/title.mp4"
163
+ TITLE_CLIP="$WORK/title.mp4"
164
+ TITLE_DUR="$TITLE_SECS"
165
+ fi
166
+
167
+ # ── Stage C: (concat title +) body, two-pass size cap, faststart ─────────────
168
+ BODY_DUR="$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$BODY" || echo 0)"
169
+ TOTAL_DUR="$(awk -v a="$TITLE_DUR" -v b="$BODY_DUR" 'BEGIN{printf "%.3f", a + b}')"
170
+ # Target video bitrate (kbit/s) = target_bytes * 8 / duration / 1000, with a
171
+ # small headroom factor for the muxer; floored so very short clips still encode.
172
+ BR_K="$(awk -v mb="$TARGET_MB" -v d="$TOTAL_DUR" 'BEGIN{
173
+ if (d <= 0) d = 1;
174
+ br = (mb * 1024 * 1024 * 8) / d / 1000 * 0.92;
175
+ if (br < 200) br = 200;
176
+ printf "%d", br;
177
+ }')"
178
+
179
+ # With a title card: concat it ahead of the body. Without: pass the body
180
+ # through (`null`) so the same two-pass/faststart encode applies either way.
181
+ if [[ -n "$TITLE_CLIP" ]]; then
182
+ IN_ARGS=(-i "$TITLE_CLIP" -i "$BODY")
183
+ FILTER='[0:v][1:v]concat=n=2:v=1:a=0[v]'
184
+ else
185
+ IN_ARGS=(-i "$BODY")
186
+ FILTER='[0:v]null[v]'
187
+ fi
188
+ PASSLOG="$WORK/ff2pass"
189
+ echo "compose-demo.sh: encoding (${TOTAL_DUR}s, target ${TARGET_MB}MB → ${BR_K}kbit/s, two-pass)…" >&2
190
+ ffmpeg -y -loglevel error "${IN_ARGS[@]}" \
191
+ -filter_complex "$FILTER" -map "[v]" -an \
192
+ -c:v libx264 -b:v "${BR_K}k" -pass 1 -passlogfile "$PASSLOG" -preset medium -f mp4 /dev/null
193
+ ffmpeg -y -loglevel error "${IN_ARGS[@]}" \
194
+ -filter_complex "$FILTER" -map "[v]" -an \
195
+ -c:v libx264 -b:v "${BR_K}k" -pass 2 -passlogfile "$PASSLOG" -preset medium \
196
+ -pix_fmt yuv420p -movflags +faststart "$OUTPUT"
197
+
198
+ # ── Stage D: report ───────────────────────────────────────────────────────────
199
+ RES="$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0:s=x "$OUTPUT" || echo '?')"
200
+ DUR="$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$OUTPUT" || echo '?')"
201
+ BYTES="$(wc -c < "$OUTPUT" | tr -d ' ')"
202
+ MB="$(awk -v b="$BYTES" 'BEGIN{printf "%.2f", b/1024/1024}')"
203
+ echo "compose-demo.sh: wrote $OUTPUT (${RES}, ${DUR}s, ${MB}MB)" >&2
204
+ # Machine-readable line for the agent to parse.
205
+ echo "{\"output\":\"${OUTPUT}\",\"resolution\":\"${RES}\",\"duration\":\"${DUR}\",\"size_mb\":${MB}}"
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: issue-answer
3
+ description: Answer a question directly — a sourced, neutral reply to an information/explanation/comparison request, from a GitHub issue or a Slack thread. Research repo docs and the web, output the answer, label `question` (GitHub only), leave open. Never write an agent brief, mark ready-for-agent, or change code.
4
+ version: 1.1.0
5
+ tags: [github, issues, questions]
6
+ ---
7
+
8
+ # Issue Answer
9
+
10
+ A user asked a **question** — they want information, an explanation, or a
11
+ comparison, not a code change. The router already decided this is a question;
12
+ your job is to **answer it well and stop**. Do not re-triage it into a work item.
13
+
14
+ The question reaches you from one of two places, and the prompt tells you which:
15
+ - a **GitHub issue** (an `issueNumber` is set), or
16
+ - a **Slack thread** (no `issueNumber`).
17
+
18
+ ## How your answer is delivered
19
+
20
+ Your **final message is the answer** — the harness posts it for you (as a
21
+ comment on the issue for GitHub-initiated runs, or into the Slack thread for
22
+ Slack-initiated runs). So:
23
+
24
+ - Make your final message the complete, self-contained answer in clean markdown.
25
+ - **Do NOT post the answer yourself** with `github_add_issue_comment` — the
26
+ harness delivers it, and posting it too would double-post.
27
+
28
+ ## Hard caps
29
+
30
+ This skill answers; it never queues work. Per invocation:
31
+
32
+ - Produce **one** answer (your final message).
33
+ - The only GitHub write you make is the `question` **label**, and only when
34
+ answering a GitHub issue.
35
+ - **Never** write an agent brief, apply `ready-for-agent` / `ready-for-human`,
36
+ create branches, push code, or open a PR.
37
+ - **Never** close the issue — leave it open for the human to close once the
38
+ answer satisfies them.
39
+
40
+ If, while reading, you conclude the request is actually a bug or feature request
41
+ (not a pure question), do **not** answer it as one. Make your final message a
42
+ short note saying it looks like work rather than a question and asking a
43
+ maintainer to `@last-light build` (or `explore`) it — let triage own work items.
44
+
45
+ ## Procedure
46
+
47
+ 1. **Understand the question.** Read the question from the prompt — the issue
48
+ title/body (and existing comments, for a GitHub issue) or the Slack message.
49
+ Identify exactly what the user wants to know.
50
+ 2. **Research.**
51
+ - **The repo** — read what's relevant to the answer: `CONTEXT.md`,
52
+ `README`, `docs/`, `spec/`, and code only as needed to ground claims about
53
+ this project. Don't survey the whole codebase; read what the question needs.
54
+ - **The web** — when the question references anything outside this repo
55
+ (another tool, framework, library, standard, or a "X vs Y" comparison),
56
+ use the `web_search` and `web_fetch` tools to consult current,
57
+ authoritative sources. Prefer official docs and primary sources.
58
+ - **Budget your research and converge.** You have a bounded number of tool
59
+ calls before the run ends — research is for grounding the answer, not
60
+ exhaustive coverage. Front-load the searches you need, then stop looking.
61
+ **Critical:** the moment you think *"I have enough"* (or *"let me just
62
+ confirm one more thing"*), do **not** fire another tool call — write the
63
+ answer **now**, in that same turn. Your reply being cut off mid-research
64
+ delivers a useless half-sentence to the user, which is worse than an
65
+ answer that omits a minor detail. If a fact is unverified, state it as
66
+ unverified in the answer rather than spending your last turn chasing it.
67
+ For broad/open-ended questions (e.g. "what's missing vs tool X"), gather a
68
+ representative sample and answer from it — explicitly noting it's a
69
+ sample, not an exhaustive audit — rather than enumerating everything.
70
+ 3. **Label (GitHub issue only).** Apply `question` with `github_add_labels`
71
+ (create it first with `github_create_label`, color `d876e3`; ignore a 422
72
+ "already exists"). If label creation/adding is denied, skip it — the answer
73
+ is the deliverable. For a Slack-initiated question there is no issue to label.
74
+ 4. **Write the answer as your final message** (the harness delivers it — see
75
+ above; do not post it yourself):
76
+ - Direct and structured. Lead with the answer; use short sections or a
77
+ comparison table when it helps.
78
+ - **Neutral and grounded.** Claims about this project come from its docs;
79
+ claims about external things are **cited** with links to the sources you
80
+ used. Don't invent pricing, capabilities, or roadmap.
81
+ - **Honest about uncertainty.** If something is fast-moving or you couldn't
82
+ verify it, say so rather than stating it as fact.
83
+ 5. **Stop.** The answer is the conversation; a human closes the issue when satisfied.
84
+
85
+ ## Tool usage
86
+
87
+ - GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or
88
+ raw HTTP. In chat you have no GitHub write tools beyond labelling; that's
89
+ expected — the answer is delivered as your final message.
90
+ - External research via the `web_search` / `web_fetch` tools only.
@@ -1,33 +1,47 @@
1
1
  ---
2
2
  name: issue-comment
3
- description: Handle non-build maintainer comments on issues and PRs — close, label, answer questions, triage
4
- version: 1.0.0
3
+ description: Handle a non-build maintainer comment on an issue or PR — close, reopen, label, dedupe, answer a brief question, or triage. Action-only; redirect anything that needs code changes to /build.
4
+ version: 2.0.0
5
5
  tags: [github, issues, comments]
6
6
  ---
7
7
 
8
- # Issue Comment Skill
8
+ # Issue Comment
9
9
 
10
- ## When to Use
11
- When a maintainer @mentions last-light on an issue or PR with a request that is NOT asking for code changes. Examples: close an issue, add labels, answer a question, check for duplicates, provide status, triage.
10
+ A maintainer @mentioned the bot on an issue or PR with a request that is **not**
11
+ asking for code changes. Do the one bounded thing they asked, confirm it in one
12
+ short comment, and stop.
13
+
14
+ ## Hard caps
15
+
16
+ This skill is deliberately small. Per invocation: **at most 2 file reads and 1
17
+ outgoing comment.** Never make code changes, create branches, or push.
12
18
 
13
19
  ## Procedure
14
20
 
15
- 1. **Read the comment** carefully to understand what the maintainer is asking
16
- 2. **Read the issue/PR** context — title, body, existing labels, existing comments
17
- 3. **Execute the request**:
18
- - **Close/reopen**: Use `update_issue` to change state
19
- - **Label**: Use `add_labels` or `remove_label`
20
- - **Duplicate check**: Search for similar issues, comment with findings
21
- - **Answer/explain**: Read the relevant code and respond with a comment
22
- - **Triage**: Apply labels and priority based on the issue content
23
- - **Other**: Use best judgment — if unclear, comment asking for clarification
24
- 4. **Respond** with a brief comment confirming what was done
25
-
26
- ## Tool Usage
27
-
28
- **Always use MCP tools** (`mcp_github_*`) for all GitHub operations. Never use `gh` CLI, `curl`, or raw HTTP requests. The MCP server handles authentication.
29
-
30
- ## Pitfalls
31
- - NEVER make code changes, create branches, or push commits this is an action-only skill
32
- - Keep comments concise one short confirmation, not a wall of text
33
- - If the request actually needs code changes, comment suggesting the maintainer ask for a build instead
21
+ 1. **Read the request.** The triggering comment is the job read it, plus the
22
+ issue/PR title, body, existing labels, and existing comments for context.
23
+ 2. **Do the bounded action:**
24
+ - Close / reopen `github_update_issue`
25
+ - Label `github_add_labels` / `github_remove_label` (use the canonical
26
+ triage roles from `docs/agents/triage-labels.md` where relevant)
27
+ - Duplicate check search similar issues, link the original in one comment
28
+ - Answer a direct question ≤5 sentences, ≤2 file reads. Don't survey the
29
+ codebase or compile a report.
30
+ 3. **Confirm** in one short comment what you did. Done.
31
+
32
+ ## Redirect, don't comply
33
+
34
+ The classifier owns intent routing. If a request that needs *building* reached
35
+ you anyway, the correct response is to **redirect, not do it** — even if the
36
+ comment seems to greenlight the work, and even if the issue body describes a
37
+ task. An issue titled "Security Review" asking you to "find and fix issues" is a
38
+ build request: reply asking the maintainer to use `@last-light build` (or
39
+ `@last-light explore`). Do **not** run the audit yourself from this skill.
40
+
41
+ If the request is unclear or out of scope, post one short comment asking them to
42
+ clarify or to use the right command. Do nothing else.
43
+
44
+ ## Tool usage
45
+
46
+ GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or raw
47
+ HTTP.
@@ -1,54 +1,120 @@
1
1
  ---
2
2
  name: issue-triage
3
- description: Triage GitHub issues — label, deduplicate, request info, and manage stale issues
3
+ description: Triage GitHub issues through the canonical state machine classify, label, deduplicate, request missing info, write agent briefs, and manage stale issues. Use on demand or on a triage cron.
4
4
  version: 2.0.0
5
5
  tags: [github, issues, triage]
6
6
  ---
7
7
 
8
- # Issue Triage Skill
8
+ # Issue Triage
9
9
 
10
- ## When to Use
11
- When asked to triage issues, or on a scheduled basis to process new/stale issues.
10
+ Move each issue through a small **state machine**. Every triaged issue carries
11
+ exactly **one category role and one state role**:
12
12
 
13
- ## Procedure
13
+ - **Category:** `bug` (something is broken) · `enhancement` (new feature or improvement)
14
+ - **State:** `needs-triage` (awaiting evaluation) · `needs-info` (waiting on the
15
+ reporter) · `ready-for-agent` (fully specified, an AFK agent can take it) ·
16
+ `ready-for-human` (needs human implementation) · `wontfix` (won't be actioned)
14
17
 
15
- ### For new issues (no labels yet):
18
+ These are canonical role names; the actual label strings for a repo may differ —
19
+ `docs/agents/triage-labels.md` holds the mapping when present. Run **autonomously**:
20
+ there is no maintainer to ask mid-run. Where you'd want direction, either make
21
+ the call and apply the label, or post a comment and stop — the async comment *is*
22
+ the conversation.
16
23
 
17
- 1. **Read the issue** carefully — title, body, and any linked PRs or issues
18
- 2. **Classify** the issue type:
19
- - Bug report → label `bug` + priority label
20
- - Feature request → label `enhancement`
21
- - Question → label `question`
22
- - Documentation → label `documentation`
23
- 3. **Check for duplicates** by searching existing issues with similar keywords
24
- - If duplicate found: comment linking to the original, add `duplicate` label, close
25
- 4. **Assess completeness**:
26
- - Bug without reproduction steps → add `needs-info`, comment asking for steps
27
- - Feature without use case → add `needs-info`, comment asking for context
28
- 5. **Set priority** based on severity and impact:
29
- - `p0-critical`: Security, data loss, service down
30
- - `p1-high`: Major feature broken, affects many users
31
- - `p2-medium`: Minor feature broken, workaround exists
32
- - `p3-low`: Cosmetic, edge case, nice-to-have
33
- 6. **Add helpful labels**: `good first issue` for simple fixes, `help wanted` for community
24
+ ## 0. Ensure the labels exist
34
25
 
35
- ### For stale issues:
26
+ Before applying any label, create the canonical set idempotently with
27
+ `github_create_label` (ignore 422 "already exists"):
36
28
 
37
- 1. **Find issues** labeled `needs-info` with no activity for 14+ days
38
- 2. **Check existing comments** before acting — use `list_issue_comments` to see if the bot has already posted a stale reminder. Look for comments from `last-light[bot]` that contain words like "reminder", "still need", or "closing". **Do NOT post a duplicate reminder.**
39
- 3. **If no bot reminder exists yet**: post a gentle reminder asking if they still need help
40
- 4. **If a bot reminder already exists** and 30+ days have passed with no response since: close with a kind message explaining why, and note they can reopen
41
- 5. **If a bot reminder already exists** and it's been less than 30 days: skip — do nothing
29
+ | Label | Color | Role |
30
+ |-------|-------|------|
31
+ | `bug` | `d73a4a` | category |
32
+ | `enhancement` | `a2eeef` | category |
33
+ | `needs-triage` | `ededed` | state |
34
+ | `needs-info` | `fbca04` | state |
35
+ | `ready-for-agent` | `0e8a16` | state |
36
+ | `ready-for-human` | `1d76db` | state |
37
+ | `wontfix` | `ffffff` | state |
38
+ | `duplicate` | `cfd3d7` | dedupe |
39
+ | `question` | `d876e3` | question |
42
40
 
43
- ## Tool Usage
41
+ If label creation is denied (the token lacks the permission), fall back to using
42
+ only the labels that already exist on the repo and skip the rest. Done when the
43
+ labels you need are present or you've confirmed you can't create them.
44
44
 
45
- **Always use MCP tools** (`mcp_github_*`) for all GitHub operations — listing issues, adding labels, posting comments, closing issues. Never use `gh` CLI, `curl`, or raw HTTP requests. The MCP server handles authentication.
45
+ ## 1. Triage a specific issue
46
+
47
+ 1. **Gather context.** Read the full issue — title, body, comments, existing
48
+ labels, author, dates. Search existing issues for **duplicates** by concept
49
+ (not just keyword). If a `.out-of-scope/` directory exists, read it and note
50
+ any prior rejection this resembles. Done when you know the issue's intent and
51
+ whether it's novel.
52
+ 2. **Classify the category** — `bug` or `enhancement`. But first, check whether
53
+ the issue is a **question** at all (see below) — questions are neither.
54
+ 3. **Decide the state and act** (exactly one applies):
55
+ - **Question** (asks for information, an explanation, or a comparison — wants
56
+ an answer, not a code change) → add `question` and **stop**. Do **not**
57
+ write an agent brief or mark it `ready-for-agent`/`ready-for-human` — a
58
+ pure question is not work. (The router normally sends these to the answer
59
+ path before triage runs; this is the safety net for ones that slip
60
+ through, e.g. reopened issues. If you can answer it briefly and factually
61
+ from the repo itself, do so in one short comment; otherwise just label it
62
+ and leave it for the answer path or a human.)
63
+ - **Duplicate** → comment linking the original, add `duplicate`, close.
64
+ - **Already implemented** → comment pointing to where it lives, add `wontfix`,
65
+ close. (Factual — safe to close autonomously.)
66
+ - **Under-specified** (bug without repro, feature without a use case) → add
67
+ `needs-info`, post the [needs-info template](#needs-info-template), stop.
68
+ - **Fully specified and delegatable** → add `ready-for-agent`, post an agent
69
+ brief ([references/AGENT-BRIEF.md](references/AGENT-BRIEF.md)).
70
+ - **Needs human implementation** (judgment calls, external access, design
71
+ decisions, manual testing) → add `ready-for-human` with a brief noting why
72
+ it can't be delegated.
73
+ - **Looks out of scope** (an enhancement you'd reject) → this is a maintainer
74
+ decision; do **not** auto-close. Add `needs-triage`, post a comment with
75
+ your reasoning (cite any matching `.out-of-scope/` file), and leave it for a
76
+ human.
77
+ 4. **Apply exactly one category + one state.** If the existing labels conflict
78
+ (two state roles), flag it in a comment and don't override — a maintainer may
79
+ have set them deliberately.
80
+
81
+ ## 2. New unlabelled issues (batch / cron)
82
+
83
+ For each issue with no triage labels yet, run §1. Default new issues that need
84
+ evaluation to `needs-triage`.
85
+
86
+ ## 3. Stale `needs-info`
87
+
88
+ 1. Find issues labelled `needs-info` with no activity for **14+ days**.
89
+ 2. **Check for a prior bot reminder** with `github_list_issue_comments` — look
90
+ for a `last-light[bot]` comment containing "reminder" / "still need" /
91
+ "closing". **Never post a duplicate reminder.**
92
+ 3. No reminder yet → post a gentle reminder asking if they still need help.
93
+ 4. Reminder exists and **30+ days** have passed with no reporter response since →
94
+ close kindly, noting they can reopen.
95
+ 5. Reminder exists, **< 30 days** since → do nothing.
96
+
97
+ ## needs-info template
98
+
99
+ ```markdown
100
+ ## Triage Notes
101
+
102
+ **What we've established so far:**
103
+ - point 1
104
+
105
+ **What we still need from you (@reporter):**
106
+ - specific, actionable question 1
107
+ ```
108
+
109
+ Questions must be specific and actionable — not "please provide more info".
110
+
111
+ ## Tool usage
112
+
113
+ GitHub operations via `github_*` MCP tools only — listing, labelling, commenting,
114
+ closing, creating labels. Never `gh` CLI, `curl`, or raw HTTP.
46
115
 
47
116
  ## Pitfalls
48
- - Don't close issues too aggressively — when in doubt, leave open
49
- - Don't change priority on issues already triaged by maintainers
50
- - Don't duplicate labels (check existing labels first)
51
117
 
52
- ## Verification
53
- - List the actions taken (labels added, comments posted, issues closed)
54
- - Confirm each action via the GitHub API response
118
+ - Don't close aggressively — when genuinely in doubt, leave it open as `needs-triage`.
119
+ - Don't change priority or state on issues a maintainer already triaged.
120
+ - Check existing labels before adding don't duplicate.
@@ -0,0 +1,61 @@
1
+ # Writing agent briefs
2
+
3
+ An agent brief is a comment posted when an issue moves to `ready-for-agent`
4
+ (or `ready-for-human`). It is the **contract** an AFK agent will build from — the
5
+ original body and discussion are context; the brief is what gets implemented.
6
+ Post it with `github_add_issue_comment`.
7
+
8
+ ## Principles
9
+
10
+ **Durable.** The issue may sit in `ready-for-agent` for weeks while the codebase
11
+ moves. Describe interfaces, types, and behavioural contracts — name specific
12
+ types, function signatures, or config shapes to look for. **Never** reference
13
+ file paths or line numbers; they go stale. Don't assume today's structure survives.
14
+
15
+ **Behavioural, not procedural.** Say *what* the system should do, not *how* to
16
+ code it — the agent explores fresh and makes its own implementation calls.
17
+ - Good: "`SkillConfig` should accept an optional `schedule: CronExpression`."
18
+ - Bad: "Add a `schedule` field in src/types/skill.ts on line 42."
19
+
20
+ **Complete acceptance criteria.** Every brief lists concrete, independently
21
+ testable criteria so the agent knows when it's done.
22
+ - Good: "`gh issue list --label needs-triage` returns issues that passed initial classification."
23
+ - Bad: "Triage should work correctly."
24
+
25
+ **Explicit scope boundaries.** State what is *out of scope* so the agent doesn't
26
+ gold-plate or wander into adjacent features.
27
+
28
+ ## Template
29
+
30
+ ```markdown
31
+ ## Agent Brief
32
+
33
+ **Category:** bug / enhancement
34
+ **Summary:** one line — what needs to happen
35
+
36
+ **Current behavior:**
37
+ What happens now. For a bug, the broken behaviour. For an enhancement, the
38
+ status quo it builds on.
39
+
40
+ **Desired behavior:**
41
+ What should happen after the work is done. Be specific about edge cases and
42
+ error conditions.
43
+
44
+ **Key interfaces:**
45
+ - `TypeName` — what changes and why
46
+ - `functionName()` — current vs intended return/behaviour
47
+ - Config shape — any new options
48
+
49
+ **Acceptance criteria:**
50
+ - [ ] Specific, testable criterion 1
51
+ - [ ] Specific, testable criterion 2
52
+
53
+ **Out of scope:**
54
+ - Thing that should NOT be changed here
55
+ - Adjacent feature that looks related but is separate
56
+ ```
57
+
58
+ ## `ready-for-human` variant
59
+
60
+ Same structure, plus a leading note on **why it can't be delegated** — judgment
61
+ calls, external access, design decisions, or manual testing the agent can't do.
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: pr-comment
3
+ description: Answer a maintainer's question about an open PR with concrete, code-cited evidence. The PR-side counterpart to issue-comment — for questions tied to the diff, not a full review.
4
+ version: 2.0.0
5
+ tags: [github, pr, comments, qa]
6
+ ---
7
+
8
+ # PR Comment
9
+
10
+ A maintainer @mentioned the bot on a PR with a *question* (not a request to
11
+ write code, and not "review this"). The question is the entire job — answer it
12
+ with evidence, in one comment. Examples: "does this consider X?", "why did we
13
+ change Y?", "is the new function thread-safe?", "regression risk for existing
14
+ callers?".
15
+
16
+ For general issue questions use `issue-comment`; for a full review use
17
+ `pr-review`.
18
+
19
+ ## Procedure
20
+
21
+ ### 1. Read the PR and the question
22
+
23
+ - `github_get_pull_request` → title, body, base, head.
24
+ - The triggering question is in `context.commentBody`. Answer *that* question —
25
+ don't generalise to a review or answer a different one.
26
+
27
+ ### 2. Investigate with the diff in hand
28
+
29
+ Get the diff and read the code needed to answer well — a real answer about
30
+ thread-safety or regression risk needs the surrounding code, not just the hunk.
31
+
32
+ - **Cap: 8 file reads** per invocation.
33
+ - "Does it consider X?" → also check whether tests in the diff cover X.
34
+ - "Regression risk?" → find callers of any function whose signature/behaviour
35
+ changed (`github_search_code`).
36
+ - Don't clone the repo unless a single answer genuinely needs cross-file traces
37
+ no MCP tool can give — most don't. If it truly needs a full audit, say so and
38
+ recommend `@last-light` (which routes to `pr-review`) rather than blowing the cap.
39
+
40
+ ### 3. Reply with one comment
41
+
42
+ `github_add_issue_comment` (PRs accept issue comments here). Keep it tight:
43
+
44
+ - **Lead with the answer** — yes / no / it depends. Don't bury it.
45
+ - **Cite `path:line`** — clickable in the GitHub UI.
46
+ - 3–8 sentences or a short bulleted list. No headings.
47
+ - If it's unanswerable from the PR alone, say so and name the specific
48
+ information you'd need.
49
+
50
+ > Yes — `src/foo.ts:42` checks `X` before calling `bar()`, and
51
+ > `tests/foo.test.ts:118` asserts the rejection path. The only place X isn't
52
+ > validated is the legacy `barLegacy` (`src/foo.ts:67`), which this PR doesn't
53
+ > touch — worth a separate issue if you want it covered.
54
+
55
+ ## Do not
56
+
57
+ - Post a formal review (`github_create_pull_request_review`) — that's
58
+ `pr-review`'s job and would collide with its blocking check.
59
+ - Modify code, push, or add labels. One comment, nothing else.
60
+ - Answer a tangent you noticed — note it in at most one trailing sentence.
61
+
62
+ ## Tool usage
63
+
64
+ GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or raw HTTP.