lastlight 0.1.15 → 0.2.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 (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 +377 -432
  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 +30 -1
  272. package/dist/setup.js +241 -25
  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 -9
  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
@@ -1,36 +1,108 @@
1
- # Sandbox image for Last Light agent tasks.
1
+ # Sandbox image for Last Light agent tasks (LASTLIGHT_SANDBOX=docker
2
+ # fallback only — the default production sandbox is gondolin, invoked
3
+ # in-process by agentic-pi without docker).
4
+ #
2
5
  # Immutable assets baked at /app/. Entrypoint wires them into the workspace
3
6
  # after volumes are mounted, then drops to the runtime user.
4
7
  FROM node:20-slim
5
8
 
6
9
  RUN apt-get update && apt-get install -y --no-install-recommends \
7
10
  git ripgrep curl jq ca-certificates gettext-base gosu \
11
+ build-essential pkg-config python3 unzip \
8
12
  && rm -rf /var/lib/apt/lists/*
9
13
 
10
- # Create non-root agent user
11
- RUN useradd -m -s /bin/bash agent
14
+ # fnm + multiple Node versions so repos pinning a specific Node via .nvmrc /
15
+ # package.json#engines just work. System node from the base image stays at
16
+ # /usr/local/bin; fnm-managed versions are pre-installed under FNM_DIR and
17
+ # selected per-shell by the bashrc hook below.
18
+ ENV FNM_DIR=/usr/local/share/fnm
19
+ ENV PATH=$FNM_DIR/aliases/default/bin:$PATH
20
+ RUN curl -fsSL https://fnm.vercel.app/install \
21
+ | bash -s -- --install-dir "$FNM_DIR" --skip-shell \
22
+ && ln -s "$FNM_DIR/fnm" /usr/local/bin/fnm \
23
+ && fnm install 22 \
24
+ && fnm install 24 \
25
+ && fnm default 22 \
26
+ && chmod -R a+rX "$FNM_DIR" \
27
+ && mkdir -p "$FNM_DIR/multishells" \
28
+ && chmod 1777 "$FNM_DIR/multishells"
12
29
 
13
- # Install Claude Code CLI (binary goes to ~/.local/bin/)
14
- # Remove ~/.claude/ after installentrypoint recreates it at runtime.
15
- USER agent
16
- RUN curl -fsSL https://claude.ai/install.sh | bash && rm -rf /home/agent/.claude
17
- USER root
18
- ENV PATH="/home/agent/.local/bin:${PATH}"
30
+ # Source fnm in every bash invocation (interactive or not). BASH_ENV makes
31
+ # non-interactive `bash -c` read this file that's how opencode's bash tool
32
+ # inherits the right node version when it runs `npm ci` inside a repo with
33
+ # an .nvmrc pinning Node 24.
34
+ RUN printf '%s\n' \
35
+ 'export FNM_DIR=/usr/local/share/fnm' \
36
+ 'export PATH="$FNM_DIR:$PATH"' \
37
+ '# --shell bash is required: when sourced via BASH_ENV the parent process' \
38
+ '# is not a shell so fnm cannot auto-detect.' \
39
+ 'eval "$(fnm env --shell bash --use-on-cd --version-file-strategy=recursive)"' \
40
+ '# The cd hook fires only on cd. Tools often launch `bash -c "..."` with' \
41
+ '# cwd already set via the spawn options — no cd happens — so also' \
42
+ '# auto-switch on shell start when the cwd has a version file.' \
43
+ 'if [ -f "$PWD/.nvmrc" ] || [ -f "$PWD/.node-version" ]; then' \
44
+ ' fnm use --silent-if-unchanged 2>/dev/null \' \
45
+ ' || { fnm install 2>/dev/null && fnm use --silent-if-unchanged 2>/dev/null; } \' \
46
+ ' || true' \
47
+ 'fi' \
48
+ > /etc/bash.bashrc.fnm \
49
+ && printf '\n[ -r /etc/bash.bashrc.fnm ] && . /etc/bash.bashrc.fnm\n' >> /etc/bash.bashrc \
50
+ && ln -s /etc/bash.bashrc.fnm /etc/profile.d/fnm.sh
51
+ # Source the fnm file directly — Debian's /etc/bash.bashrc bails early on
52
+ # non-interactive shells (`[ -z "$PS1" ] && return`), so pointing BASH_ENV
53
+ # at it would skip our setup for `bash -c` invocations (which is the path
54
+ # the agent's bash tool uses).
55
+ ENV BASH_ENV=/etc/bash.bashrc.fnm
19
56
 
20
- # MCP server (baked at /app/)
21
- COPY mcp-github-app/package.json /app/mcp-github-app/package.json
22
- RUN cd /app/mcp-github-app && npm install --prefer-offline --no-audit && npm cache clean --force
23
- COPY mcp-github-app/ /app/mcp-github-app/
57
+ RUN apt-get update && apt-get install -y --no-install-recommends \
58
+ python3 python3-pip pipx \
59
+ && PIPX_HOME=/opt/pipx PIPX_BIN_DIR=/usr/local/bin pipx install semgrep \
60
+ && curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz \
61
+ | tar -xz -C /usr/local/bin gitleaks \
62
+ && apt-get purge -y python3-pip \
63
+ && rm -rf /var/lib/apt/lists/*
24
64
 
25
- # Skills (baked at /app/ entrypoint symlinks into ~/.claude/skills/)
26
- COPY skills/ /app/skills/
65
+ # Create non-root agent user, UID/GID pinned to 10001 to MATCH the harness
66
+ # `lastlight` user (see Dockerfile: `useradd -u 10001 lastlight`). The
67
+ # entrypoint chowns the bind-mounted workspace to `agent`; per-PR workspaces
68
+ # are persistent and reused across runs (issue #107), so the harness re-stages
69
+ # AGENTS.md + skills into them on the next run. If `agent` lands on the default
70
+ # uid (1001) those files become unwritable by the harness (10001) on reuse —
71
+ # EACCES, and the review silently runs with no skill/AGENTS.md. Sharing the uid
72
+ # keeps the reused workspace mutually writable by both the agent (in-container)
73
+ # and the harness (host). Also self-heals dirs left at 1001 by older images:
74
+ # the entrypoint's `chown -R agent:agent` re-owns them to 10001 on next reuse.
75
+ RUN groupadd -g 10001 agent && useradd -m -s /bin/bash -u 10001 -g 10001 agent
27
76
 
28
- # Agent context (baked at /app/ entrypoint cats into workspace/CLAUDE.md)
77
+ # Install agentic-pi globally so the harness can `docker exec ...
78
+ # agentic-pi run ...` against this container. The version + integrity
79
+ # come straight from lastlight's `package-lock.json` so `npm i agentic-pi@…`
80
+ # in the harness automatically flows into the sandbox image — no
81
+ # manual Dockerfile bumps. `npm install -g <tarball>` itself doesn't
82
+ # consult a lockfile, hence the explicit integrity verification.
83
+ COPY package-lock.json /tmp/lastlight-lock.json
84
+ RUN node -e "const p=require('/tmp/lastlight-lock.json').packages['node_modules/agentic-pi']; \
85
+ if(!p) throw new Error('agentic-pi missing from lockfile'); \
86
+ process.stdout.write(p.version + '\n' + p.integrity + '\n')" > /tmp/agentic-pi.pin \
87
+ && version=$(sed -n '1p' /tmp/agentic-pi.pin) \
88
+ && expected=$(sed -n '2p' /tmp/agentic-pi.pin) \
89
+ && echo "Installing agentic-pi@${version} (${expected})" \
90
+ && curl -fsSL "https://registry.npmjs.org/agentic-pi/-/agentic-pi-${version}.tgz" -o /tmp/agentic-pi.tgz \
91
+ && actual="sha512-$(node -e "const c=require('crypto'),f=require('fs');process.stdout.write(c.createHash('sha512').update(f.readFileSync('/tmp/agentic-pi.tgz')).digest('base64'))")" \
92
+ && if [ "$actual" != "$expected" ]; then \
93
+ echo "agentic-pi tarball integrity mismatch:" >&2; \
94
+ echo " expected: $expected" >&2; \
95
+ echo " actual: $actual" >&2; \
96
+ exit 1; \
97
+ fi \
98
+ && npm install -g --no-audit --no-fund /tmp/agentic-pi.tgz \
99
+ && rm /tmp/agentic-pi.tgz /tmp/agentic-pi.pin /tmp/lastlight-lock.json
100
+
101
+ # Agent context (baked at /app/ — entrypoint cats into workspace/AGENTS.md)
29
102
  COPY agent-context/ /app/agent-context/
30
103
 
31
- # Entrypoint + MCP config template
104
+ # Entrypoint
32
105
  COPY deploy/sandbox-entrypoint.sh /app/sandbox-entrypoint.sh
33
- COPY deploy/mcp-config.tmpl.json /app/mcp-config.tmpl.json
34
106
  RUN chmod +x /app/sandbox-entrypoint.sh
35
107
 
36
108
  # Own app dir for agent user
@@ -38,6 +110,13 @@ RUN chown -R agent:agent /app /home/agent
38
110
 
39
111
  WORKDIR /home/agent/workspace
40
112
 
113
+ # Image-level env so every `docker exec` (the entrypoint just runs once at
114
+ # container start) sees these. Exporting them in sandbox-entrypoint.sh only
115
+ # affects PID 1 — subsequent `docker exec agentic-pi run …` calls get a
116
+ # fresh environment and would otherwise miss these paths.
117
+ ENV LASTLIGHT_WORKSPACE=/home/agent/workspace
118
+ ENV LASTLIGHT_GIT_CREDENTIALS=/home/agent/.lastlight-git-credentials
119
+
41
120
  # Entrypoint runs as root, fixes permissions, then drops to agent via gosu
42
121
  ENTRYPOINT ["/app/sandbox-entrypoint.sh"]
43
122
  CMD ["sleep", "infinity"]
@@ -0,0 +1,40 @@
1
+ # Skills
2
+
3
+ Skill directories staged into the sandbox per workflow phase (and a subset into
4
+ chat). A phase declares `skill: <name>` / `skills: [<name>, …]`; the runner
5
+ stages the whole directory into `<agentCwd>/.agents/skills/<name>/` and
6
+ pi-coding-agent surfaces `name` + `description` in the system prompt. The agent
7
+ reads SKILL.md (and any `references/`) on demand via its `read` tool.
8
+
9
+ **Authoring guide:** [`docs/agents/writing-skills.md`](../docs/agents/writing-skills.md)
10
+ — the loading contract, the craft, and house conventions. Read it before adding
11
+ or editing a skill.
12
+
13
+ ## Skills
14
+
15
+ | Skill | Used by | Purpose |
16
+ |-------|---------|---------|
17
+ | [`chat`](chat/) | chat | Conversational assistant for Slack/Discord threads — answer repo/PR/issue questions, guide to natural-language triggers. |
18
+ | [`issue-triage`](issue-triage/) | `issue-triage.yaml`, chat | Move issues through the canonical triage state machine — categorise, label, dedupe, manage stale, write agent briefs. |
19
+ | [`issue-comment`](issue-comment/) | `issue-comment.yaml` | Handle non-build maintainer comments on issues/PRs — close, label, answer briefly, redirect build requests. |
20
+ | [`pr-review`](pr-review/) | `pr-review.yaml`, chat | Review a PR with structured, tiered feedback; build and test from the local checkout; post a formal review. |
21
+ | [`pr-comment`](pr-comment/) | `pr-comment.yaml` | Answer a maintainer's question about an open PR with concrete, code-cited evidence (not a full review). |
22
+ | [`repo-health`](repo-health/) | `repo-health.yaml`, chat | Generate a repository health report — open issues, PR backlog, CI status, action items. |
23
+ | [`security-review`](security-review/) | `security-review.yaml` | Diff-scoped SDLC security review; file one dated summary issue with a task-list of findings. |
24
+ | [`security-feedback`](security-feedback/) | `security-feedback.yaml` | Process a maintainer's comment on a security scan summary — break findings into issues or record suppressions. |
25
+ | [`building`](building/) | build (executor, reviewer), `pr-fix.yaml`, `pr-review.yaml` | Shared craft: install-first + package-manager detection, the test/lint/typecheck gate, and TDD discipline in the sandbox. |
26
+ | [`code-review`](code-review/) | build (reviewer), `pr-review.yaml` | Shared rubric: finding tiers (Critical/Important/Suggestions/Nits) and what-to-check. Referenced by both the branch-diff reviewer and the PR reviewer. |
27
+ | [`verify`](verify/) | `verify.yaml` | Test a behaviour claim as an investigator — CONFIRMED / REFUTED / INCONCLUSIVE with bash-captured evidence. |
28
+ | [`qa-test`](qa-test/) | `qa-test.yaml` | Run an automated QA flow against a CLI or locally-served app and report step-level pass/fail with evidence. |
29
+ | [`browser-qa`](browser-qa/) | `verify.yaml`, `qa-test.yaml`, `demo.yaml` | Drive a real headless browser against a locally-served web UI and capture screenshot (and, for `demo`, video) evidence. Gated to the docker QA image. |
30
+ | [`demo`](demo/) | `demo.yaml` | Record a short demo VIDEO of a PR/feature — drive the web UI, screen-record, and composite a titled, size-capped mp4 with ffmpeg. Gated to the docker QA image. |
31
+
32
+ `building` and `code-review` are **shared building blocks** — referenced by the
33
+ build-cycle prompts (`workflows/prompts/*.md`) and the PR skills so the install
34
+ gate and review rubric live in one place. They're staged alongside the phase's
35
+ primary skill/prompt and read on demand.
36
+
37
+ The live set is enforced at startup: `validateAssets()` (`src/workflows/loader.ts`)
38
+ resolves every workflow `skill:` reference and `CHAT_SKILL_NAMES`
39
+ (`src/engine/chat-skills.ts`). Adding a skill here does nothing until a phase or
40
+ the chat list references it.
@@ -0,0 +1,193 @@
1
+ ---
2
+ name: browser-qa
3
+ description: Drive a real headless browser against a locally-served web UI and capture screenshot evidence, reporting step-level PASS/FAIL/BLOCKED with extracted DOM text and console errors. Use when a phase on the docker QA image must exercise a rendered UI and attach screenshots — it complements the text-evidence verify/qa-test skills.
4
+ version: 1.0.0
5
+ tags: [browser, qa, screenshots, evidence]
6
+ ---
7
+
8
+ # Browser QA
9
+
10
+ Drive a web UI with a real headless Chromium and report **step-level
11
+ pass/fail with evidence**: extracted DOM text, assertion results, console
12
+ errors, and screenshot files. The deliverable is a QA report — partial
13
+ coverage with documented failures is the expected output.
14
+
15
+ This skill is the **browser/screenshot path** that `verify` and `qa-test`
16
+ scope out to "a separate docker-gated capability". It only works on the
17
+ `lastlight-sandbox-qa:latest` docker image, which bakes in Playwright +
18
+ Chromium. You have bash + file tools but **no vision** — you reason over the
19
+ driver's JSON stdout (extracted text, assertion results, console errors).
20
+ The PNG screenshots are **human evidence only**; you never see them.
21
+
22
+ This skill uses the **building** skill for installing dependencies and
23
+ starting the repo's dev-server.
24
+
25
+ ## When this applies
26
+
27
+ A phase running on the docker QA image whose target is a **web app** the
28
+ repo serves on `localhost` and where rendered-UI behaviour or visual
29
+ evidence matters. For a CLI or a curl-able API, use `qa-test`/`verify`
30
+ instead — don't launch a browser you don't need.
31
+
32
+ ## FIRST — probe for a browser
33
+
34
+ The driver lives in this skill's bundle at
35
+ `<skill-dir>/scripts/agent-browser.mjs`. Resolve `<skill-dir>` from the
36
+ available-skills catalogue (it gives the absolute staged path of this
37
+ skill); do not assume a relative path from `$PWD` — the agent's cwd is the
38
+ checked-out repo, the bundle is a sibling.
39
+
40
+ Run the runtime probe before anything else:
41
+
42
+ ```bash
43
+ node <skill-dir>/scripts/agent-browser.mjs doctor
44
+ ```
45
+
46
+ - Exit 0 with `{"ok":true,"chromium":"..."}` → Chromium is available; proceed.
47
+ - Exit non-zero (e.g. `playwright not available …`, or no Chromium — the lean
48
+ default image, or a gondolin run) → **DO NOT attempt browser QA.** Fall back
49
+ to the text path (`verify`/`qa-test` style: curl the dev-server, capture
50
+ stdout) and **say in your report that the browser path was unavailable** and
51
+ you used the text path.
52
+
53
+ ## Start the app
54
+
55
+ Follow the **building** skill to install dependencies, then start the repo's
56
+ dev-server **in the background** and wait until it is listening on
57
+ `localhost:PORT` (poll with `curl` until it answers). Note the port — you
58
+ pass it as `--base-url`.
59
+
60
+ ## Author a flow
61
+
62
+ Write a `flow.json` describing the QA flow. Shape:
63
+
64
+ ```json
65
+ {
66
+ "baseUrl": "http://localhost:3000",
67
+ "viewport": { "width": 1280, "height": 800 },
68
+ "steps": [
69
+ { "name": "home", "goto": "/" },
70
+ { "click": "text=Login" },
71
+ { "fill": ["#email", "a@b.com"] },
72
+ { "type": ["#password", "hunter2"] },
73
+ { "press": "Enter" },
74
+ { "waitFor": "#dashboard" },
75
+ { "assertText": "Welcome" },
76
+ { "text": "h1" },
77
+ { "screenshot": "after-login" }
78
+ ]
79
+ }
80
+ ```
81
+
82
+ Step keys (a step may combine an action **plus** a trailing `screenshot`):
83
+
84
+ | Key | Value | Effect |
85
+ |--------------|----------------------|------------------------------------------------------------------|
86
+ | `goto` | path or URL | Navigate (resolved against `baseUrl`). **Failure is fatal.** |
87
+ | `click` | selector | Click the element. |
88
+ | `fill` | `[selector, value]` | Set an input's value. |
89
+ | `type` | `[selector, value]` | Type key-by-key into an input. |
90
+ | `press` | key (e.g. `Enter`) | Press a keyboard key. |
91
+ | `waitFor` | selector | Wait until the element is visible (~10s timeout). |
92
+ | `assertText` | string | Pass if the text is visible anywhere on the page; else step FAIL.|
93
+ | `text` | selector | Extract `textContent` into the step result (for you to read). |
94
+ | `screenshot` | basename | Write `<out-dir>/<basename>.png` (full page). |
95
+
96
+ The whole flow runs in **one Chromium session** — login state, cookies, and
97
+ navigation persist across steps.
98
+
99
+ ## Run the flow
100
+
101
+ ```bash
102
+ node <skill-dir>/scripts/agent-browser.mjs run flow.json \
103
+ --base-url http://localhost:PORT \
104
+ --out-dir <artifact-dir>
105
+ ```
106
+
107
+ The driver prints a single JSON report:
108
+
109
+ ```json
110
+ { "ok": false,
111
+ "baseUrl": "http://localhost:3000",
112
+ "steps": [
113
+ { "index": 0, "action": "goto", "ok": true, "ms": 412 },
114
+ { "index": 6, "action": "assertText", "ok": false, "ms": 10003,
115
+ "error": "assertText not found: \"Welcome\"" },
116
+ { "index": 7, "action": "text", "ok": true, "ms": 5, "text": "Dashboard" },
117
+ { "index": 8, "action": "screenshot", "ok": true, "ms": 88,
118
+ "screenshot": "/…/after-login.png" }
119
+ ],
120
+ "consoleErrors": ["Uncaught TypeError: …"],
121
+ "screenshots": ["/…/after-login.png"] }
122
+ ```
123
+
124
+ - A step error (selector not found, assertion miss, timeout) is recorded
125
+ `ok:false` and the run **continues** — best-effort coverage. The exception
126
+ is a `goto` that fails: that is fatal and the remaining steps are skipped.
127
+ - `ok` at the top level is true only when **every** step passed. The process
128
+ exits 0 even when steps failed — judge from the JSON, not the exit code.
129
+ A non-zero exit means a fatal harness error (bad flow file, launch failure).
130
+
131
+ ## Screenshots & artifacts
132
+
133
+ Pass `--out-dir <artifact-dir>` pointing at the run's artifact directory the
134
+ **prompt provides** (commonly the run's `.lastlight/<issueKey>/` dir,
135
+ referenced as the template variable the prompt passes in). Saving there lets
136
+ the harness **harvest** the PNGs into the dashboard Artifacts view. Reference
137
+ each screenshot path in your report.
138
+
139
+ Screenshot delivery requires **server-mode build-assets**. If the PNGs can't
140
+ be persisted (no artifact dir was provided, or build-assets is repo-mode),
141
+ still report the text/DOM observations and console errors, and say the
142
+ screenshots were **not retained**.
143
+
144
+ ## Evidence rules
145
+
146
+ Mirror `verify`/`qa-test` — you are an investigator, not an advocate:
147
+
148
+ - **Never fake a pass.** Don't hardcode expected text or edit the code under
149
+ test to force a green step.
150
+ - **Report real failures.** A step that genuinely fails is a finding — record
151
+ it `FAIL` with the assertion/selector and the driver's error, and don't bury
152
+ it.
153
+ - **Treat `consoleErrors` and page errors as findings**, even if the visible
154
+ flow "worked" — surface them in the report.
155
+ - If the browser is unavailable (probe failed), fall back to text and say so —
156
+ don't pretend a UI step ran.
157
+
158
+ ## Report
159
+
160
+ Produce your report as your **final message** — the workflow posts it for you
161
+ (don't `github_add_issue_comment` yourself; that would double-post).
162
+
163
+ **Be concise, and stay in the browser.** The deliverable is short: a one-line
164
+ environment summary, the results table, the screenshots, console errors, and a
165
+ one-line coverage note. Do **not** read or analyse the repo's source code (the
166
+ text pass already did) and do **not** narrate every step or dump extracted DOM
167
+ text — surface a `text`/assertion value only when it's the actual evidence for a
168
+ row (e.g. a FAIL).
169
+
170
+ ```
171
+ ## Browser QA: <target>
172
+
173
+ **Environment:** <branch / commit, package manager, how served, Chromium version>
174
+
175
+ ### Results
176
+ | Step | Status | Evidence |
177
+ |------|--------|----------|
178
+ | <step description> | PASS / FAIL / BLOCKED | <terse evidence + inline screenshot if any> |
179
+
180
+ ### Console errors
181
+ - <each consoleErrors / pageerror entry, or "none observed">
182
+
183
+ ### Coverage
184
+ <one or two lines: what was driven, and anything not tested and why>
185
+ ```
186
+
187
+ Reference screenshots **inline** as raw Markdown images when the prompt gives
188
+ you a public artifact base URL — write `![caption](<base>/<name>.png)` directly
189
+ in the report body (or table cell), **never** wrapped in backticks or a code
190
+ fence (inside a code span it renders as literal text, not an image). Otherwise
191
+ reference them by filename. Every step in the flow must
192
+ have a row and a result. Never report a flow as "passed" with steps you didn't
193
+ actually run — list them as untested instead.