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,164 @@
1
+ import { isIP } from "node:net";
2
+ /**
3
+ * Single source of truth for sandbox HTTP egress allowlists.
4
+ *
5
+ * Both sandbox backends consume this list:
6
+ * - gondolin: passed verbatim to `agenticRun({ allowedHttpHosts })` so the
7
+ * QEMU-layer HTTP interceptor 502s anything off-list.
8
+ * - docker: nginx-egress + coredns configs are generated from these hosts
9
+ * at harness boot. Sandbox containers spawn with `--dns <coredns-ip>`;
10
+ * coredns sinkholes allowlisted hostnames to the nginx firewall IP,
11
+ * which peeks SNI and tunnels to the real upstream. See
12
+ * `src/sandbox/egress-firewall-config.ts` for the full architecture.
13
+ *
14
+ * The lists are intentionally split so callers can compose tighter policies
15
+ * (e.g. a read-only profile that doesn't need package registries). The
16
+ * everyday default is `DEFAULT_ALLOWLIST`.
17
+ *
18
+ * ## Convention: every entry matches the apex AND all subdomains
19
+ *
20
+ * `openai.com` → matches openai.com, api.openai.com, platform.openai.com, …
21
+ * `npmjs.org` → matches npmjs.org, registry.npmjs.org, auth.npmjs.org, …
22
+ *
23
+ * Bare hostnames only — no leading dot, no `*.` prefix. The config
24
+ * generator emits the right syntax for each backend (nginx's
25
+ * `.example.com` map form, CoreDNS regex `(^|\.)example\.com\.$`).
26
+ *
27
+ * Exact-only matching isn't currently supported because we haven't
28
+ * needed it — every host in the list is one we want apex+subdomain
29
+ * access to. If we ever do, we'd add an explicit type (e.g. an `exact:`
30
+ * prefix) so the loose-by-default convention stays unambiguous.
31
+ *
32
+ * A workflow phase can declare `unrestricted_egress: true` to bypass the
33
+ * allowlist entirely — see `src/workflows` for the phase schema.
34
+ */
35
+ /** GitHub HTTPS endpoints used by `git`, `gh`, and agentic-pi's github tools. */
36
+ export const GITHUB_HOSTS = [
37
+ // Covers github.com plus api.github.com, codeload.github.com, raw.…, gist.…
38
+ "github.com",
39
+ // *.githubusercontent.com — release artifacts, raw blobs, avatars.
40
+ "githubusercontent.com",
41
+ ];
42
+ /**
43
+ * LLM provider hosts.
44
+ *
45
+ * Required for the docker backend because `agentic-pi run` executes inside
46
+ * the sandbox container there (`src/sandbox/docker.ts` runs `agentic-pi run
47
+ * --sandbox none`), so the LLM HTTP call originates from inside the
48
+ * container. The gondolin backend runs agentic-pi in the harness process,
49
+ * so the call originates from the host and these hosts aren't strictly
50
+ * required inside the VM — they're kept here so a single allowlist can
51
+ * cover both paths without surprises.
52
+ */
53
+ export const PROVIDER_HOSTS = [
54
+ "anthropic.com",
55
+ "openai.com",
56
+ "openrouter.ai",
57
+ // Fireworks — api.fireworks.ai is the inference endpoint.
58
+ "fireworks.ai",
59
+ ];
60
+ /**
61
+ * Public package registries the executor may hit during `npm install`,
62
+ * etc. Apex-plus-subdomain matching covers auth / CDN / mirror
63
+ * subdomains without needing separate entries.
64
+ */
65
+ export const PACKAGE_REGISTRY_HOSTS = [
66
+ // npm / yarn / pnpm
67
+ "npmjs.org",
68
+ "yarnpkg.com",
69
+ // Python — pypi.org + files.pythonhosted.org are the two big ones.
70
+ "pypi.org",
71
+ "pythonhosted.org",
72
+ // Rust — static.crates.io, index.crates.io, crates.io itself.
73
+ "crates.io",
74
+ // Go modules — covers proxy.golang.org, sum.golang.org, plus golang.org.
75
+ "golang.org",
76
+ // Ruby
77
+ "rubygems.org",
78
+ // Alpine apk + Debian apt — apex covers the regional mirror subdomains.
79
+ "alpinelinux.org",
80
+ "debian.org",
81
+ ];
82
+ /**
83
+ * Combined allowlist used by both backends when a phase has not opted into
84
+ * unrestricted egress. Order is preserved across imports so generated
85
+ * configs are stable.
86
+ */
87
+ export const DEFAULT_ALLOWLIST = [
88
+ ...GITHUB_HOSTS,
89
+ ...PROVIDER_HOSTS,
90
+ ...PACKAGE_REGISTRY_HOSTS,
91
+ ];
92
+ /**
93
+ * Sentinel value recognized by agentic-pi/gondolin (post the `"*"` patch)
94
+ * meaning "allow every host". Used when a phase sets `unrestricted_egress`.
95
+ *
96
+ * On the docker backend, unrestricted egress routes through the open
97
+ * nginx-egress + coredns-open pair — this sentinel is for gondolin only.
98
+ */
99
+ export const ALLOW_ALL_SENTINEL = "*";
100
+ const INTERNAL_HOSTNAMES = new Set(["localhost", "metadata.google.internal"]);
101
+ function isPrivateOrInternalIp(host) {
102
+ const ip = host.replace(/^\[|\]$/g, "");
103
+ const family = isIP(ip);
104
+ if (family === 4) {
105
+ const octets = ip.split(".").map((part) => Number(part));
106
+ if (octets.length !== 4 || octets.some((part) => !Number.isInteger(part) || part < 0 || part > 255))
107
+ return true;
108
+ const [a, b] = octets;
109
+ return a === 0
110
+ || a === 10
111
+ || a === 127
112
+ || (a === 169 && b === 254)
113
+ || (a === 172 && b >= 16 && b <= 31)
114
+ || (a === 192 && b === 168);
115
+ }
116
+ if (family === 6) {
117
+ const lower = ip.toLowerCase();
118
+ const mappedIpv4 = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/)?.[1];
119
+ if (mappedIpv4)
120
+ return isPrivateOrInternalIp(mappedIpv4);
121
+ if (lower.startsWith("::ffff:"))
122
+ return true;
123
+ return lower === "::"
124
+ || lower === "::1"
125
+ || lower.startsWith("fe8")
126
+ || lower.startsWith("fe9")
127
+ || lower.startsWith("fea")
128
+ || lower.startsWith("feb")
129
+ || lower.startsWith("fc")
130
+ || lower.startsWith("fd");
131
+ }
132
+ return false;
133
+ }
134
+ export function normalizeAllowlistHost(host) {
135
+ const trimmed = host.trim().toLowerCase();
136
+ if (!trimmed)
137
+ return null;
138
+ let parsed = trimmed;
139
+ try {
140
+ parsed = new URL(trimmed.includes("://") ? trimmed : `https://${trimmed}`).hostname.toLowerCase();
141
+ }
142
+ catch {
143
+ parsed = trimmed.split("/")[0] || "";
144
+ if (!parsed.startsWith("["))
145
+ parsed = parsed.split(":")[0] || "";
146
+ }
147
+ parsed = parsed.replace(/^\.+|\.+$/g, "").replace(/^\[|\]$/g, "");
148
+ if (!parsed || parsed.includes("*") || INTERNAL_HOSTNAMES.has(parsed) || isPrivateOrInternalIp(parsed))
149
+ return null;
150
+ return parsed;
151
+ }
152
+ export function mergeAllowlist(base, extra = []) {
153
+ const out = [];
154
+ const seen = new Set();
155
+ for (const candidate of [...base, ...extra]) {
156
+ const host = normalizeAllowlistHost(candidate);
157
+ if (host && !seen.has(host)) {
158
+ seen.add(host);
159
+ out.push(host);
160
+ }
161
+ }
162
+ return out;
163
+ }
164
+ //# sourceMappingURL=egress-allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"egress-allowlist.js","sourceRoot":"","sources":["../../src/sandbox/egress-allowlist.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,65 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { ALLOW_ALL_SENTINEL, DEFAULT_ALLOWLIST, GITHUB_HOSTS, PACKAGE_REGISTRY_HOSTS, PROVIDER_HOSTS, mergeAllowlist, normalizeAllowlistHost, } from "./egress-allowlist.js";
3
+ describe("egress-allowlist source of truth", () => {
4
+ it("groups are non-empty and disjoint", () => {
5
+ for (const group of [GITHUB_HOSTS, PROVIDER_HOSTS, PACKAGE_REGISTRY_HOSTS]) {
6
+ expect(group.length).toBeGreaterThan(0);
7
+ }
8
+ const all = [...GITHUB_HOSTS, ...PROVIDER_HOSTS, ...PACKAGE_REGISTRY_HOSTS];
9
+ expect(new Set(all).size).toBe(all.length);
10
+ });
11
+ it("DEFAULT_ALLOWLIST is the union of the three groups in declaration order", () => {
12
+ const expected = [...GITHUB_HOSTS, ...PROVIDER_HOSTS, ...PACKAGE_REGISTRY_HOSTS];
13
+ expect([...DEFAULT_ALLOWLIST]).toEqual(expected);
14
+ });
15
+ it("covers the critical host categories the runtime depends on", () => {
16
+ // GitHub apex covers api.github.com, codeload.github.com, raw.…
17
+ expect(GITHUB_HOSTS).toContain("github.com");
18
+ // Provider hosts — the docker backend dials these from inside the
19
+ // sandbox container.
20
+ expect(PROVIDER_HOSTS).toContain("openai.com");
21
+ expect(PROVIDER_HOSTS).toContain("anthropic.com");
22
+ // npm — covers registry.npmjs.org, auth.npmjs.org, www.npmjs.org.
23
+ expect(PACKAGE_REGISTRY_HOSTS).toContain("npmjs.org");
24
+ });
25
+ it("entries are bare hostnames (no leading dot, no wildcard prefix)", () => {
26
+ // Convention is "every entry matches apex+subdomains" — see file
27
+ // docstring. The config generator emits the right syntax for each
28
+ // backend. If someone tries to write `.github.com` or `*.github.com`
29
+ // here, fail fast.
30
+ for (const host of DEFAULT_ALLOWLIST) {
31
+ expect(host).toMatch(/^[A-Za-z0-9][A-Za-z0-9.-]*[A-Za-z0-9]$/);
32
+ expect(host.startsWith(".")).toBe(false);
33
+ expect(host.includes("*")).toBe(false);
34
+ }
35
+ });
36
+ it("ALLOW_ALL_SENTINEL is the wildcard string the gondolin matcher honours", () => {
37
+ expect(ALLOW_ALL_SENTINEL).toBe("*");
38
+ });
39
+ it("normalizes and merges extra allowlist hosts", () => {
40
+ expect(normalizeAllowlistHost("https://Collector.Example.com:4318/v1/traces")).toBe("collector.example.com");
41
+ expect(normalizeAllowlistHost("169.254.169.254")).toBeNull();
42
+ expect(mergeAllowlist(["github.com"], ["GitHub.com", "otel.example.com"])).toEqual([
43
+ "github.com",
44
+ "otel.example.com",
45
+ ]);
46
+ });
47
+ it("rejects private and internal collector endpoints", () => {
48
+ for (const host of [
49
+ "0.0.0.0",
50
+ "127.0.0.1",
51
+ "10.0.0.4",
52
+ "172.16.0.1",
53
+ "192.168.1.10",
54
+ "http://[::1]:4318",
55
+ "http://[fe80::1]:4318",
56
+ "http://[fd00::1]:4318",
57
+ "http://[::ffff:127.0.0.1]:4318",
58
+ "metadata.google.internal",
59
+ "localhost",
60
+ ]) {
61
+ expect(normalizeAllowlistHost(host), host).toBeNull();
62
+ }
63
+ });
64
+ });
65
+ //# sourceMappingURL=egress-allowlist.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"egress-allowlist.test.js","sourceRoot":"","sources":["../../src/sandbox/egress-allowlist.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Egress firewall config generation for the docker sandbox backend.
3
+ *
4
+ * Architecture (replaces the earlier tinyproxy CONNECT-proxy):
5
+ *
6
+ * sandbox-egress (internal: true, subnet 172.30.0.0/24)
7
+ * ├─ sandbox containers (docker run --dns <coredns-ip>)
8
+ * ├─ coredns-strict 172.30.0.10 → returns nginx-strict IP for allowlist hosts, NXDOMAIN otherwise
9
+ * ├─ coredns-open 172.30.0.11 → returns nginx-open IP for ANY hostname (except hard-deny SSRF magnets)
10
+ * ├─ nginx-egress-strict 172.30.0.20 → ssl_preread, SNI must match allowlist; tunnel upstream via proxy-egress
11
+ * └─ nginx-egress-open 172.30.0.21 → tunnel any SNI; client DNS already gated through coredns-open
12
+ *
13
+ * Why this instead of a forward proxy (tinyproxy/smokescreen): clients
14
+ * inside the sandbox (especially the OpenAI/Anthropic SDKs that build
15
+ * their own undici dispatchers) don't honour HTTP_PROXY / HTTPS_PROXY.
16
+ * Forcing them to cooperate is a losing battle. By spoofing DNS and
17
+ * peeking SNI at the network layer, the sandbox sees no proxy at all —
18
+ * it dials `api.openai.com:443` directly. The firewall intercepts the
19
+ * connection by virtue of being the only thing the spoofed DNS pointed
20
+ * at.
21
+ *
22
+ * Inspired by Vercel Sandbox's egress firewall (SNI peeking, no env
23
+ * vars). Their implementation also handles TLS termination for
24
+ * credentials brokering and Postgres STARTTLS — we don't (yet).
25
+ *
26
+ * ## Wildcards
27
+ *
28
+ * Entries in egress-allowlist.ts with a leading dot (`".github.com"`)
29
+ * match the apex plus every subdomain. nginx's `map` directive supports
30
+ * this syntax natively. CoreDNS uses the `template` plugin with an
31
+ * anchored regex to do the same.
32
+ */
33
+ /** Fixed IPs assigned in docker-compose.yml so `--dns` and nginx upstreams can reference them. */
34
+ export declare const COREDNS_STRICT_IP = "172.30.0.10";
35
+ export declare const COREDNS_OPEN_IP = "172.30.0.11";
36
+ export declare const NGINX_STRICT_IP = "172.30.0.20";
37
+ export declare const NGINX_OPEN_IP = "172.30.0.21";
38
+ /**
39
+ * Static IP of the in-network OTEL collector (docker backend). Sandboxes
40
+ * dial it directly by IP — it lives on `sandbox-egress` alongside the
41
+ * firewalls, so no DNS lookup (and therefore no coredns allowlist entry)
42
+ * is involved. The collector is the ONLY OTLP endpoint a sandbox ever
43
+ * sees: it terminates the sandbox's telemetry and re-exports to the real
44
+ * backend over `proxy-egress` using credentials that stay host-side. This
45
+ * is why the strict SNI firewall no longer needs to know about collector
46
+ * hosts or non-443 ports — that hop happens on the trusted outbound leg,
47
+ * not through `ssl_preread`.
48
+ */
49
+ export declare const OTEL_COLLECTOR_IP = "172.30.0.30";
50
+ /** OTLP/HTTP + OTLP/gRPC receiver ports the in-network collector listens on. */
51
+ export declare const OTEL_COLLECTOR_OTLP_HTTP_PORT = 4318;
52
+ export declare const OTEL_COLLECTOR_OTLP_GRPC_PORT = 4317;
53
+ /** Endpoint a docker sandbox is told to export OTLP to (HTTP/protobuf). */
54
+ export declare const OTEL_COLLECTOR_SANDBOX_ENDPOINT = "http://172.30.0.30:4318";
55
+ /**
56
+ * UID the `otel/opentelemetry-collector` image runs as (its Dockerfile
57
+ * `USER`). The collector reads the OTLP config (which can hold backend auth
58
+ * headers) as this non-root user. To let it read a mode-0600 file from the
59
+ * shared volume WITHOUT running as root or making the secret world-readable,
60
+ * the harness's own `lastlight` user is pinned to this same UID (see the
61
+ * Dockerfile `useradd -u`), so the collector reads files it wrote as their
62
+ * owner. The Dockerfile and the collector image tag in docker-compose.yml
63
+ * must move together if a future image bumps the UID — enforced by a test in
64
+ * docker-compose.test.ts.
65
+ */
66
+ export declare const OTEL_COLLECTOR_UID = 10001;
67
+ /** Subnet for sandbox-egress. Compose declares this CIDR so the IPs above are valid. */
68
+ export declare const SANDBOX_EGRESS_SUBNET = "172.30.0.0/24";
69
+ /** Build the strict nginx.conf — ssl_preread + map on SNI allowlist. */
70
+ export declare function renderNginxStrictConf(): string;
71
+ /** Build the open nginx.conf — no SNI allowlist, just tunnel whatever DNS pointed at. */
72
+ export declare function renderNginxOpenConf(): string;
73
+ /** Build the Corefile that returns the strict nginx IP for allowlist hosts. */
74
+ export declare function renderCorefileStrict(): string;
75
+ /** Build the Corefile that returns the open nginx IP for ANY hostname (except hard-denies). */
76
+ export declare function renderCorefileOpen(): string;
77
+ /**
78
+ * Write the four config files under $STATE_DIR/proxy/. Idempotent.
79
+ * Returns the directory path. Compose bind-mounts this dir into the
80
+ * coredns + nginx containers read-only.
81
+ */
82
+ export declare function writeEgressFirewallConfigs(stateDir: string): string;
83
+ /**
84
+ * Render the in-network OTEL collector config (docker backend).
85
+ *
86
+ * `opts.active` gates whether the collector forwards anywhere. It MUST track
87
+ * the harness's effective `otel.enabled && otel.forwardToSandbox` — when
88
+ * false, every pipeline is wired to a `debug` exporter (drops data) and NO
89
+ * backend endpoint or credential is emitted, even if `OTEL_EXPORTER_OTLP_*`
90
+ * env vars are present. This is the security floor: the collector listens on
91
+ * a static IP that sandboxes can reach, so if forwarding weren't gated, a
92
+ * sandbox could POST directly to it and exfil to the real backend regardless
93
+ * of the documented `LASTLIGHT_OTEL_ENABLED` / `FORWARD_TO_SANDBOX` opt-outs.
94
+ *
95
+ * When active, the collector re-exports to the REAL backend — the standard
96
+ * `OTEL_EXPORTER_OTLP_ENDPOINT` / `OTEL_EXPORTER_OTLP_HEADERS` plus their
97
+ * per-signal `OTEL_EXPORTER_OTLP_<SIGNAL>_ENDPOINT` / `_HEADERS` overrides,
98
+ * resolved with the spec's precedence. Each signal gets its own exporter so
99
+ * a split traces/metrics/logs setup is routed correctly rather than all
100
+ * collapsing onto whichever endpoint won a fallback chain. Those credentials
101
+ * live here, in a file on the host mounted read-only into the collector, and
102
+ * are NEVER forwarded into an untrusted sandbox. The sandbox can only
103
+ * influence span *content* sent to the harness's own fixed backend — it
104
+ * cannot redirect where the collector exports, so this adds no SSRF/exfil
105
+ * surface.
106
+ *
107
+ * A signal with no configured endpoint (neither specific nor generic) is
108
+ * likewise wired to `debug` so the collector still boots cleanly and accepts
109
+ * connections — sandboxes simply never send what isn't routed.
110
+ */
111
+ export declare function renderOtelCollectorConfig(opts: {
112
+ active: boolean;
113
+ env?: NodeJS.ProcessEnv;
114
+ }): string;
115
+ /**
116
+ * Write the in-network collector config to $STATE_DIR/proxy/otel-collector.yaml.
117
+ * Mode 0600 — it can contain backend auth headers. Called at harness boot
118
+ * (and by the compose `egress-init` one-shot) so the file exists before the
119
+ * `otel-collector` service reads it. `opts.active` gates forwarding — see
120
+ * `renderOtelCollectorConfig`. The harness passes its parsed
121
+ * `otel.enabled && otel.forwardToSandbox`; the env-only callers compute it
122
+ * via `otelForwardActiveFromEnv`.
123
+ */
124
+ export declare function writeOtelCollectorConfig(stateDir: string, opts: {
125
+ active: boolean;
126
+ env?: NodeJS.ProcessEnv;
127
+ }): string;