lastlight 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/README.md +71 -692
  2. package/dist/cli-config.js.map +1 -0
  3. package/dist/cli-format.js.map +1 -0
  4. package/dist/{cli/cli-server.d.ts → cli-server.d.ts} +39 -1
  5. package/dist/{cli/cli-server.js → cli-server.js} +105 -5
  6. package/dist/cli-server.js.map +1 -0
  7. package/dist/cli-timeline.js.map +1 -0
  8. package/dist/{cli/cli.js → cli.js} +9 -7
  9. package/dist/cli.js.map +1 -0
  10. package/dist/{cli/fork-cli.d.ts → fork-cli.d.ts} +3 -3
  11. package/dist/{cli/fork-cli.js → fork-cli.js} +28 -27
  12. package/dist/fork-cli.js.map +1 -0
  13. package/dist/{cli/oauth-cli.js → oauth-cli.js} +1 -1
  14. package/dist/oauth-cli.js.map +1 -0
  15. package/dist/{cli/setup.js → setup.js} +10 -4
  16. package/dist/setup.js.map +1 -0
  17. package/dist/{cli/skills-install.d.ts → skills-install.d.ts} +6 -0
  18. package/dist/{cli/skills-install.js → skills-install.js} +6 -2
  19. package/dist/skills-install.js.map +1 -0
  20. package/package.json +20 -65
  21. package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
  22. package/agent-context/rules.md +0 -80
  23. package/agent-context/security.md +0 -69
  24. package/agent-context/soul.md +0 -21
  25. package/config/default.yaml +0 -119
  26. package/deploy/.env.production.example +0 -100
  27. package/deploy/entrypoint.sh +0 -82
  28. package/deploy/native/README.md +0 -160
  29. package/deploy/native/install.sh +0 -110
  30. package/deploy/native/lastlight.env.example +0 -95
  31. package/deploy/native/lastlight.service +0 -50
  32. package/deploy/sandbox-entrypoint.sh +0 -93
  33. package/dist/admin/auth.d.ts +0 -51
  34. package/dist/admin/auth.js +0 -121
  35. package/dist/admin/auth.js.map +0 -1
  36. package/dist/admin/chat-session-reader.d.ts +0 -39
  37. package/dist/admin/chat-session-reader.js +0 -84
  38. package/dist/admin/chat-session-reader.js.map +0 -1
  39. package/dist/admin/docker.d.ts +0 -61
  40. package/dist/admin/docker.js +0 -187
  41. package/dist/admin/docker.js.map +0 -1
  42. package/dist/admin/index.d.ts +0 -9
  43. package/dist/admin/index.js +0 -59
  44. package/dist/admin/index.js.map +0 -1
  45. package/dist/admin/routes.d.ts +0 -81
  46. package/dist/admin/routes.js +0 -1381
  47. package/dist/admin/routes.js.map +0 -1
  48. package/dist/admin/sessions.d.ts +0 -89
  49. package/dist/admin/sessions.js +0 -204
  50. package/dist/admin/sessions.js.map +0 -1
  51. package/dist/admin/tail.d.ts +0 -12
  52. package/dist/admin/tail.js +0 -145
  53. package/dist/admin/tail.js.map +0 -1
  54. package/dist/admin/version.d.ts +0 -22
  55. package/dist/admin/version.js +0 -92
  56. package/dist/admin/version.js.map +0 -1
  57. package/dist/cli/cli-config.js.map +0 -1
  58. package/dist/cli/cli-format.js.map +0 -1
  59. package/dist/cli/cli-server.js.map +0 -1
  60. package/dist/cli/cli-timeline.js.map +0 -1
  61. package/dist/cli/cli.js.map +0 -1
  62. package/dist/cli/fork-cli.js.map +0 -1
  63. package/dist/cli/oauth-cli.js.map +0 -1
  64. package/dist/cli/setup.js.map +0 -1
  65. package/dist/cli/skills-install.js.map +0 -1
  66. package/dist/config/config-resolve.d.ts +0 -28
  67. package/dist/config/config-resolve.js +0 -47
  68. package/dist/config/config-resolve.js.map +0 -1
  69. package/dist/config/config.d.ts +0 -157
  70. package/dist/config/config.js +0 -581
  71. package/dist/config/config.js.map +0 -1
  72. package/dist/config/core-pin.d.ts +0 -16
  73. package/dist/config/core-pin.js +0 -85
  74. package/dist/config/core-pin.js.map +0 -1
  75. package/dist/config/overlay-assets.d.ts +0 -20
  76. package/dist/config/overlay-assets.js +0 -114
  77. package/dist/config/overlay-assets.js.map +0 -1
  78. package/dist/config/overlay-bootstrap.d.ts +0 -44
  79. package/dist/config/overlay-bootstrap.js +0 -304
  80. package/dist/config/overlay-bootstrap.js.map +0 -1
  81. package/dist/connectors/github-webhook.d.ts +0 -45
  82. package/dist/connectors/github-webhook.js +0 -321
  83. package/dist/connectors/github-webhook.js.map +0 -1
  84. package/dist/connectors/index.d.ts +0 -18
  85. package/dist/connectors/index.js +0 -41
  86. package/dist/connectors/index.js.map +0 -1
  87. package/dist/connectors/messaging/base.d.ts +0 -42
  88. package/dist/connectors/messaging/base.js +0 -139
  89. package/dist/connectors/messaging/base.js.map +0 -1
  90. package/dist/connectors/messaging/delivery.d.ts +0 -14
  91. package/dist/connectors/messaging/delivery.js +0 -38
  92. package/dist/connectors/messaging/delivery.js.map +0 -1
  93. package/dist/connectors/messaging/index.d.ts +0 -4
  94. package/dist/connectors/messaging/index.js +0 -4
  95. package/dist/connectors/messaging/index.js.map +0 -1
  96. package/dist/connectors/messaging/session-manager.d.ts +0 -53
  97. package/dist/connectors/messaging/session-manager.js +0 -255
  98. package/dist/connectors/messaging/session-manager.js.map +0 -1
  99. package/dist/connectors/messaging/types.d.ts +0 -58
  100. package/dist/connectors/messaging/types.js +0 -7
  101. package/dist/connectors/messaging/types.js.map +0 -1
  102. package/dist/connectors/slack/connector.d.ts +0 -142
  103. package/dist/connectors/slack/connector.js +0 -494
  104. package/dist/connectors/slack/connector.js.map +0 -1
  105. package/dist/connectors/slack/index.d.ts +0 -2
  106. package/dist/connectors/slack/index.js +0 -3
  107. package/dist/connectors/slack/index.js.map +0 -1
  108. package/dist/connectors/slack/mrkdwn.d.ts +0 -19
  109. package/dist/connectors/slack/mrkdwn.js +0 -240
  110. package/dist/connectors/slack/mrkdwn.js.map +0 -1
  111. package/dist/connectors/types.d.ts +0 -61
  112. package/dist/connectors/types.js +0 -2
  113. package/dist/connectors/types.js.map +0 -1
  114. package/dist/cron/fanout.d.ts +0 -33
  115. package/dist/cron/fanout.js +0 -55
  116. package/dist/cron/fanout.js.map +0 -1
  117. package/dist/cron/jobs.d.ts +0 -18
  118. package/dist/cron/jobs.js +0 -37
  119. package/dist/cron/jobs.js.map +0 -1
  120. package/dist/cron/scheduler.d.ts +0 -45
  121. package/dist/cron/scheduler.js +0 -105
  122. package/dist/cron/scheduler.js.map +0 -1
  123. package/dist/engine/agent-executor.d.ts +0 -34
  124. package/dist/engine/agent-executor.js +0 -246
  125. package/dist/engine/agent-executor.js.map +0 -1
  126. package/dist/engine/chat/chat-runner.d.ts +0 -132
  127. package/dist/engine/chat/chat-runner.js +0 -424
  128. package/dist/engine/chat/chat-runner.js.map +0 -1
  129. package/dist/engine/chat/chat-skills.d.ts +0 -45
  130. package/dist/engine/chat/chat-skills.js +0 -184
  131. package/dist/engine/chat/chat-skills.js.map +0 -1
  132. package/dist/engine/chat/chat.d.ts +0 -54
  133. package/dist/engine/chat/chat.js +0 -316
  134. package/dist/engine/chat/chat.js.map +0 -1
  135. package/dist/engine/chat/message-batcher.d.ts +0 -32
  136. package/dist/engine/chat/message-batcher.js +0 -109
  137. package/dist/engine/chat/message-batcher.js.map +0 -1
  138. package/dist/engine/dispatcher.d.ts +0 -73
  139. package/dist/engine/dispatcher.js +0 -663
  140. package/dist/engine/dispatcher.js.map +0 -1
  141. package/dist/engine/event-shim.d.ts +0 -117
  142. package/dist/engine/event-shim.js +0 -435
  143. package/dist/engine/event-shim.js.map +0 -1
  144. package/dist/engine/executors/orchestrator.d.ts +0 -81
  145. package/dist/engine/executors/orchestrator.js +0 -365
  146. package/dist/engine/executors/orchestrator.js.map +0 -1
  147. package/dist/engine/executors/shared.d.ts +0 -189
  148. package/dist/engine/executors/shared.js +0 -616
  149. package/dist/engine/executors/shared.js.map +0 -1
  150. package/dist/engine/github/git-auth.d.ts +0 -62
  151. package/dist/engine/github/git-auth.js +0 -161
  152. package/dist/engine/github/git-auth.js.map +0 -1
  153. package/dist/engine/github/github-app-client.d.ts +0 -23
  154. package/dist/engine/github/github-app-client.js +0 -33
  155. package/dist/engine/github/github-app-client.js.map +0 -1
  156. package/dist/engine/github/github-tools.d.ts +0 -18
  157. package/dist/engine/github/github-tools.js +0 -263
  158. package/dist/engine/github/github-tools.js.map +0 -1
  159. package/dist/engine/github/github.d.ts +0 -1193
  160. package/dist/engine/github/github.js +0 -357
  161. package/dist/engine/github/github.js.map +0 -1
  162. package/dist/engine/github/profiles.d.ts +0 -279
  163. package/dist/engine/github/profiles.js +0 -42
  164. package/dist/engine/github/profiles.js.map +0 -1
  165. package/dist/engine/github/review-poster.d.ts +0 -98
  166. package/dist/engine/github/review-poster.js +0 -177
  167. package/dist/engine/github/review-poster.js.map +0 -1
  168. package/dist/engine/llm.d.ts +0 -79
  169. package/dist/engine/llm.js +0 -269
  170. package/dist/engine/llm.js.map +0 -1
  171. package/dist/engine/oauth.d.ts +0 -43
  172. package/dist/engine/oauth.js +0 -103
  173. package/dist/engine/oauth.js.map +0 -1
  174. package/dist/engine/router.d.ts +0 -29
  175. package/dist/engine/router.js +0 -680
  176. package/dist/engine/router.js.map +0 -1
  177. package/dist/engine/screen/classifier.d.ts +0 -93
  178. package/dist/engine/screen/classifier.js +0 -215
  179. package/dist/engine/screen/classifier.js.map +0 -1
  180. package/dist/engine/screen/screen.d.ts +0 -41
  181. package/dist/engine/screen/screen.js +0 -93
  182. package/dist/engine/screen/screen.js.map +0 -1
  183. package/dist/evals-api.d.ts +0 -24
  184. package/dist/evals-api.js +0 -22
  185. package/dist/evals-api.js.map +0 -1
  186. package/dist/index.d.ts +0 -1
  187. package/dist/index.js +0 -940
  188. package/dist/index.js.map +0 -1
  189. package/dist/managed-repos.d.ts +0 -30
  190. package/dist/managed-repos.js +0 -72
  191. package/dist/managed-repos.js.map +0 -1
  192. package/dist/notify/blocks.d.ts +0 -23
  193. package/dist/notify/blocks.js +0 -118
  194. package/dist/notify/blocks.js.map +0 -1
  195. package/dist/notify/index.d.ts +0 -17
  196. package/dist/notify/index.js +0 -7
  197. package/dist/notify/index.js.map +0 -1
  198. package/dist/notify/model.d.ts +0 -57
  199. package/dist/notify/model.js +0 -89
  200. package/dist/notify/model.js.map +0 -1
  201. package/dist/notify/notifier.d.ts +0 -18
  202. package/dist/notify/notifier.js +0 -100
  203. package/dist/notify/notifier.js.map +0 -1
  204. package/dist/notify/render.d.ts +0 -21
  205. package/dist/notify/render.js +0 -59
  206. package/dist/notify/render.js.map +0 -1
  207. package/dist/notify/transports/github.d.ts +0 -26
  208. package/dist/notify/transports/github.js +0 -27
  209. package/dist/notify/transports/github.js.map +0 -1
  210. package/dist/notify/transports/slack.d.ts +0 -27
  211. package/dist/notify/transports/slack.js +0 -37
  212. package/dist/notify/transports/slack.js.map +0 -1
  213. package/dist/notify/types.d.ts +0 -119
  214. package/dist/notify/types.js +0 -16
  215. package/dist/notify/types.js.map +0 -1
  216. package/dist/providers.d.ts +0 -125
  217. package/dist/providers.js +0 -279
  218. package/dist/providers.js.map +0 -1
  219. package/dist/sandbox/docker.d.ts +0 -180
  220. package/dist/sandbox/docker.js +0 -517
  221. package/dist/sandbox/docker.js.map +0 -1
  222. package/dist/sandbox/egress-allowlist.d.ts +0 -74
  223. package/dist/sandbox/egress-allowlist.js +0 -164
  224. package/dist/sandbox/egress-allowlist.js.map +0 -1
  225. package/dist/sandbox/egress-firewall-config.d.ts +0 -127
  226. package/dist/sandbox/egress-firewall-config.js +0 -434
  227. package/dist/sandbox/egress-firewall-config.js.map +0 -1
  228. package/dist/sandbox/images.d.ts +0 -23
  229. package/dist/sandbox/images.js +0 -55
  230. package/dist/sandbox/images.js.map +0 -1
  231. package/dist/sandbox/index.d.ts +0 -112
  232. package/dist/sandbox/index.js +0 -332
  233. package/dist/sandbox/index.js.map +0 -1
  234. package/dist/sandbox/sandbox.d.ts +0 -214
  235. package/dist/sandbox/sandbox.js +0 -453
  236. package/dist/sandbox/sandbox.js.map +0 -1
  237. package/dist/sandbox/smol.d.ts +0 -162
  238. package/dist/sandbox/smol.js +0 -485
  239. package/dist/sandbox/smol.js.map +0 -1
  240. package/dist/session-log.d.ts +0 -63
  241. package/dist/session-log.js +0 -290
  242. package/dist/session-log.js.map +0 -1
  243. package/dist/state/approval-store.d.ts +0 -88
  244. package/dist/state/approval-store.js +0 -149
  245. package/dist/state/approval-store.js.map +0 -1
  246. package/dist/state/build-assets.d.ts +0 -50
  247. package/dist/state/build-assets.js +0 -154
  248. package/dist/state/build-assets.js.map +0 -1
  249. package/dist/state/db.d.ts +0 -81
  250. package/dist/state/db.js +0 -155
  251. package/dist/state/db.js.map +0 -1
  252. package/dist/state/execution-store.d.ts +0 -257
  253. package/dist/state/execution-store.js +0 -527
  254. package/dist/state/execution-store.js.map +0 -1
  255. package/dist/state/migrate.d.ts +0 -15
  256. package/dist/state/migrate.js +0 -175
  257. package/dist/state/migrate.js.map +0 -1
  258. package/dist/state/workflow-run-store.d.ts +0 -216
  259. package/dist/state/workflow-run-store.js +0 -403
  260. package/dist/state/workflow-run-store.js.map +0 -1
  261. package/dist/telemetry/index.d.ts +0 -38
  262. package/dist/telemetry/index.js +0 -253
  263. package/dist/telemetry/index.js.map +0 -1
  264. package/dist/telemetry/pi-events.d.ts +0 -12
  265. package/dist/telemetry/pi-events.js +0 -134
  266. package/dist/telemetry/pi-events.js.map +0 -1
  267. package/dist/workflows/dag.d.ts +0 -37
  268. package/dist/workflows/dag.js +0 -118
  269. package/dist/workflows/dag.js.map +0 -1
  270. package/dist/workflows/loader.d.ts +0 -53
  271. package/dist/workflows/loader.js +0 -421
  272. package/dist/workflows/loader.js.map +0 -1
  273. package/dist/workflows/loop-eval.d.ts +0 -28
  274. package/dist/workflows/loop-eval.js +0 -74
  275. package/dist/workflows/loop-eval.js.map +0 -1
  276. package/dist/workflows/phase-executor.d.ts +0 -222
  277. package/dist/workflows/phase-executor.js +0 -1153
  278. package/dist/workflows/phase-executor.js.map +0 -1
  279. package/dist/workflows/phase-ref.d.ts +0 -50
  280. package/dist/workflows/phase-ref.js +0 -91
  281. package/dist/workflows/phase-ref.js.map +0 -1
  282. package/dist/workflows/resume.d.ts +0 -58
  283. package/dist/workflows/resume.js +0 -313
  284. package/dist/workflows/resume.js.map +0 -1
  285. package/dist/workflows/runner.d.ts +0 -63
  286. package/dist/workflows/runner.js +0 -381
  287. package/dist/workflows/runner.js.map +0 -1
  288. package/dist/workflows/schema.d.ts +0 -344
  289. package/dist/workflows/schema.js +0 -460
  290. package/dist/workflows/schema.js.map +0 -1
  291. package/dist/workflows/simple.d.ts +0 -90
  292. package/dist/workflows/simple.js +0 -393
  293. package/dist/workflows/simple.js.map +0 -1
  294. package/dist/workflows/target-policy.d.ts +0 -74
  295. package/dist/workflows/target-policy.js +0 -80
  296. package/dist/workflows/target-policy.js.map +0 -1
  297. package/dist/workflows/templates.d.ts +0 -88
  298. package/dist/workflows/templates.js +0 -127
  299. package/dist/workflows/templates.js.map +0 -1
  300. package/dist/workflows/triggers.d.ts +0 -21
  301. package/dist/workflows/triggers.js +0 -45
  302. package/dist/workflows/triggers.js.map +0 -1
  303. package/dist/workflows/verdict.d.ts +0 -19
  304. package/dist/workflows/verdict.js +0 -30
  305. package/dist/workflows/verdict.js.map +0 -1
  306. package/dist/worktree/manager.d.ts +0 -43
  307. package/dist/worktree/manager.js +0 -127
  308. package/dist/worktree/manager.js.map +0 -1
  309. package/docker-compose.yml +0 -274
  310. package/sandbox.Dockerfile +0 -68
  311. package/skills/README.md +0 -42
  312. package/skills/browser-qa/SKILL.md +0 -208
  313. package/skills/browser-qa/scripts/agent-browser.mjs +0 -531
  314. package/skills/building/SKILL.md +0 -95
  315. package/skills/chat/SKILL.md +0 -36
  316. package/skills/code-review/SKILL.md +0 -82
  317. package/skills/debug-production/SKILL.md +0 -108
  318. package/skills/demo/SKILL.md +0 -228
  319. package/skills/demo/scripts/compose-demo.sh +0 -243
  320. package/skills/issue-answer/SKILL.md +0 -91
  321. package/skills/issue-comment/SKILL.md +0 -49
  322. package/skills/issue-triage/SKILL.md +0 -149
  323. package/skills/issue-triage/references/AGENT-BRIEF.md +0 -65
  324. package/skills/pr-comment/SKILL.md +0 -64
  325. package/skills/pr-review/SKILL.md +0 -148
  326. package/skills/pr-review/references/findings-schema.md +0 -89
  327. package/skills/qa-test/SKILL.md +0 -97
  328. package/skills/repo-health/SKILL.md +0 -67
  329. package/skills/security-feedback/SKILL.md +0 -173
  330. package/skills/security-feedback/references/templates.md +0 -77
  331. package/skills/security-review/SKILL.md +0 -215
  332. package/skills/security-review/references/issue-format.md +0 -302
  333. package/skills/verify/SKILL.md +0 -118
  334. package/workflows/answer.yaml +0 -44
  335. package/workflows/build.yaml +0 -129
  336. package/workflows/cron-health.yaml +0 -6
  337. package/workflows/cron-review.yaml +0 -8
  338. package/workflows/cron-security.yaml +0 -6
  339. package/workflows/cron-triage.yaml +0 -8
  340. package/workflows/demo.yaml +0 -62
  341. package/workflows/examples/bash-smoke.yaml +0 -41
  342. package/workflows/examples/parallel-review.yaml +0 -36
  343. package/workflows/examples/tdd-loop.yaml +0 -17
  344. package/workflows/explore.yaml +0 -80
  345. package/workflows/issue-comment.yaml +0 -15
  346. package/workflows/issue-triage.yaml +0 -22
  347. package/workflows/pr-comment.yaml +0 -16
  348. package/workflows/pr-fix.yaml +0 -17
  349. package/workflows/pr-review.yaml +0 -50
  350. package/workflows/prompts/answer.md +0 -68
  351. package/workflows/prompts/architect.md +0 -44
  352. package/workflows/prompts/classifier.md +0 -60
  353. package/workflows/prompts/classify-adds-info.md +0 -17
  354. package/workflows/prompts/demo.md +0 -125
  355. package/workflows/prompts/executor.md +0 -42
  356. package/workflows/prompts/explore-ask.md +0 -99
  357. package/workflows/prompts/explore-publish.md +0 -31
  358. package/workflows/prompts/explore-read.md +0 -120
  359. package/workflows/prompts/explore-synthesize.md +0 -88
  360. package/workflows/prompts/fix.md +0 -18
  361. package/workflows/prompts/guardrails.md +0 -96
  362. package/workflows/prompts/pr-fix.md +0 -26
  363. package/workflows/prompts/pr.md +0 -39
  364. package/workflows/prompts/qa-browser.md +0 -95
  365. package/workflows/prompts/qa-synth.md +0 -44
  366. package/workflows/prompts/qa-test.md +0 -60
  367. package/workflows/prompts/re-reviewer.md +0 -33
  368. package/workflows/prompts/reviewer.md +0 -60
  369. package/workflows/prompts/verify-browser.md +0 -93
  370. package/workflows/prompts/verify-synth.md +0 -44
  371. package/workflows/prompts/verify.md +0 -63
  372. package/workflows/qa-test.yaml +0 -94
  373. package/workflows/repo-health.yaml +0 -15
  374. package/workflows/security-feedback.yaml +0 -25
  375. package/workflows/security-review.yaml +0 -37
  376. package/workflows/verify.yaml +0 -93
  377. /package/dist/{cli/cli-config.d.ts → cli-config.d.ts} +0 -0
  378. /package/dist/{cli/cli-config.js → cli-config.js} +0 -0
  379. /package/dist/{cli/cli-format.d.ts → cli-format.d.ts} +0 -0
  380. /package/dist/{cli/cli-format.js → cli-format.js} +0 -0
  381. /package/dist/{cli/cli-timeline.d.ts → cli-timeline.d.ts} +0 -0
  382. /package/dist/{cli/cli-timeline.js → cli-timeline.js} +0 -0
  383. /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
  384. /package/dist/{cli/oauth-cli.d.ts → oauth-cli.d.ts} +0 -0
  385. /package/dist/{cli/setup.d.ts → setup.d.ts} +0 -0
@@ -1,93 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Sandbox container entrypoint — runs as root after volumes are mounted.
3
- # Used only when LASTLIGHT_SANDBOX=docker (the gondolin sandbox runs in
4
- # process and doesn't go through this script). Fixes permissions, writes
5
- # AGENTS.md, sets up git identity, then drops to the agent user via gosu.
6
- set -euo pipefail
7
-
8
- AGENT_HOME="/home/agent"
9
- WORKSPACE="$AGENT_HOME/workspace"
10
- # LASTLIGHT_WORKSPACE and LASTLIGHT_GIT_CREDENTIALS are set as image-level
11
- # ENV in sandbox.Dockerfile so they're visible to every `docker exec` call
12
- # the harness makes (not just the entrypoint's PID-1 tree). They show up in
13
- # this shell's env via that mechanism; no export needed here.
14
-
15
- # ── Fix workspace ownership (bind-mounts may be root-owned on macOS) ──
16
- chown -R agent:agent "$WORKSPACE" 2>/dev/null || true
17
- chown agent:agent "$AGENT_HOME"
18
-
19
- # Ensure ~/.config exists and is agent-owned before any root-side mkdir
20
- # below claims it (some tools write here at startup).
21
- mkdir -p "$AGENT_HOME/.config"
22
- chown agent:agent "$AGENT_HOME/.config"
23
-
24
- # ── Shared package-manager cache (issue #107) ──
25
- # /cache is a Docker named volume shared across every sandbox so npm / pnpm /
26
- # yarn reuse already-downloaded tarballs. A freshly-created volume is root-owned,
27
- # and a cache seeded by an older image (when `agent` had a different UID) leaves
28
- # children owned by the wrong UID — which blocks npm/pnpm/yarn writes (e.g.
29
- # /cache/npm/_logs). Self-heal: if the subdir OR any immediate child isn't
30
- # agent-owned, chown -R it. The recursive pass runs only when something is
31
- # actually wrong, so a warm, correctly-owned cache stays cheap.
32
- if [ -d /cache ]; then
33
- for sub in npm pnpm yarn uv; do
34
- mkdir -p "/cache/$sub"
35
- if [ -n "$(find "/cache/$sub" -maxdepth 1 ! -user agent -print -quit 2>/dev/null)" ]; then
36
- chown -R agent:agent "/cache/$sub" 2>/dev/null || true
37
- fi
38
- done
39
- fi
40
-
41
- # ── App PEM: keep shared copy unreadable by the agent by default ──
42
- if [ -f /data/secrets/app.pem ]; then
43
- chmod 600 /data/secrets/app.pem 2>/dev/null || true
44
- fi
45
-
46
- # Optionally materialize an agent-readable PEM for high-trust runs only.
47
- # The harness forwards GITHUB_APP_PRIVATE_KEY_PATH into the sandbox env so
48
- # any tool inside that needs the App key can find it.
49
- if [ "${ALLOW_APP_PEM:-0}" = "1" ] && [ -f /data/secrets/app.pem ]; then
50
- cp /data/secrets/app.pem "$AGENT_HOME/.config/app.pem"
51
- chown agent:agent "$AGENT_HOME/.config/app.pem"
52
- chmod 600 "$AGENT_HOME/.config/app.pem"
53
- export GITHUB_APP_PRIVATE_KEY_PATH="$AGENT_HOME/.config/app.pem"
54
- else
55
- export GITHUB_APP_PRIVATE_KEY_PATH=""
56
- fi
57
-
58
- # ── AGENTS.md — agentic-pi auto-loads this from cwd as the agent's
59
- # system context (same convention as CLAUDE.md). ──
60
- if [ ! -f "$WORKSPACE/AGENTS.md" ]; then
61
- cat /app/agent-context/*.md > "$WORKSPACE/AGENTS.md" 2>/dev/null || true
62
- fi
63
- chown agent:agent "$WORKSPACE/AGENTS.md" 2>/dev/null || true
64
-
65
- # ── Git identity and auth (system-wide so it applies regardless of exec user) ──
66
- git config --system user.name "last-light[bot]"
67
- git config --system user.email "last-light[bot]@users.noreply.github.com"
68
-
69
- if [ -n "${GIT_TOKEN:-}" ]; then
70
- # Reject tokens containing characters that would break the URL line in
71
- # the credentials file (newline, '@', ':', '/', whitespace). Real GitHub
72
- # tokens are alphanumeric + underscore — the wider charset here is
73
- # defensive against future format changes.
74
- if ! printf %s "$GIT_TOKEN" | grep -Eq '^[A-Za-z0-9_-]+$'; then
75
- echo "ERROR: GIT_TOKEN contains characters outside [A-Za-z0-9_-]; refusing to write credentials file" >&2
76
- exit 1
77
- fi
78
- # Write the file as the agent user (mode 600) so the helper can read it
79
- # after the entrypoint drops privileges. Path is set by us above; the
80
- # `store --file=<path>` value goes into git's config as argv-split (no
81
- # shell), so the only constraint is no-whitespace in the path.
82
- install -m 600 -o agent -g agent /dev/null "$LASTLIGHT_GIT_CREDENTIALS"
83
- printf 'https://x-access-token:%s@github.com\n' "$GIT_TOKEN" > "$LASTLIGHT_GIT_CREDENTIALS"
84
- chown agent:agent "$LASTLIGHT_GIT_CREDENTIALS"
85
- git config --system credential.helper "store --file=$LASTLIGHT_GIT_CREDENTIALS"
86
- fi
87
-
88
- # ── Sentinel for harness waitForReady() ──
89
- touch "$WORKSPACE/.ready"
90
- chown agent:agent "$WORKSPACE/.ready"
91
-
92
- # ── Drop to agent user ──
93
- exec gosu agent "$@"
@@ -1,51 +0,0 @@
1
- import type { Context, Next } from "hono";
2
- /**
3
- * Grace window past `exp` in which a token can still be *refreshed* (but not
4
- * used to authenticate a normal request). Lets an active user whose token
5
- * lapsed briefly slide their session forward via the refresh route instead of
6
- * being bounced back through a full login. Beyond this, they must re-login.
7
- */
8
- export declare const REFRESH_GRACE_SECONDS: number;
9
- export declare function createToken(secret: string, method?: "password" | "slack" | "github"): string;
10
- export declare function verifyToken(token: string, secret: string): boolean;
11
- /**
12
- * Like `verifyToken`, but also accepts a token that expired within the last
13
- * `REFRESH_GRACE_SECONDS`. Used ONLY by the refresh route so a briefly-lapsed
14
- * session can be renewed. The signature must still be valid (we minted it), so
15
- * this can't be forged.
16
- */
17
- export declare function verifyTokenForRefresh(token: string, secret: string): boolean;
18
- export interface TokenPayload {
19
- exp: number;
20
- method?: "password" | "slack" | "github";
21
- }
22
- /**
23
- * Decode a token's payload WITHOUT verifying its signature or expiry — used to
24
- * carry the login `method` across a refresh. Callers that need authenticity
25
- * must still gate on `verifyToken` (the refresh route runs behind
26
- * `authMiddleware`, which does exactly that). Returns null if unparseable.
27
- */
28
- export declare function decodeToken(token: string): TokenPayload | null;
29
- /**
30
- * Whether any login method is configured — an admin password OR a working OAuth
31
- * provider. The single source of truth for "is auth on", shared by the admin
32
- * dashboard and the `/api/*` trigger routes so they can't drift. The GitHub
33
- * gate, like the OAuth route, also requires an allowed-org to be set.
34
- */
35
- export declare function authIsEnabled(opts: {
36
- adminPassword?: string;
37
- slackOAuthClientId?: string;
38
- slackOAuthClientSecret?: string;
39
- githubOAuthClientId?: string;
40
- githubOAuthClientSecret?: string;
41
- githubAllowedOrg?: string;
42
- }): boolean;
43
- /**
44
- * Gate the admin API. `enabled` should be true when ANY login method is
45
- * configured — an admin password OR a working OAuth provider. Gating only on
46
- * the password (the old behaviour) left the dashboard fully open whenever the
47
- * password was cleared, even with Slack/GitHub OAuth set up.
48
- */
49
- export declare function authMiddleware(enabled: boolean, secret: string): (c: Context, next: Next) => Promise<void | (Response & import("hono").TypedResponse<{
50
- error: string;
51
- }, 401, "json">)>;
@@ -1,121 +0,0 @@
1
- import crypto from "node:crypto";
2
- const TOKEN_TTL_SECONDS = 60 * 60 * 24 * 30; // 30 days
3
- /**
4
- * Grace window past `exp` in which a token can still be *refreshed* (but not
5
- * used to authenticate a normal request). Lets an active user whose token
6
- * lapsed briefly slide their session forward via the refresh route instead of
7
- * being bounced back through a full login. Beyond this, they must re-login.
8
- */
9
- export const REFRESH_GRACE_SECONDS = 60 * 60 * 24 * 7; // 7 days
10
- export function createToken(secret, method) {
11
- const payload = { exp: Math.floor(Date.now() / 1000) + TOKEN_TTL_SECONDS };
12
- if (method)
13
- payload.method = method;
14
- const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
15
- const sig = crypto.createHmac("sha256", secret).update(payloadB64).digest("base64url");
16
- return `${payloadB64}.${sig}`;
17
- }
18
- /**
19
- * Verify the HMAC signature and return the decoded payload, or null if the
20
- * signature is invalid / the payload is unparseable. Does NOT check expiry —
21
- * that's the caller's job (strict for auth, lenient for refresh).
22
- */
23
- function verifySignature(token, secret) {
24
- const parts = token.split(".");
25
- if (parts.length !== 2)
26
- return null;
27
- const [payloadB64, sig] = parts;
28
- const expectedSig = crypto.createHmac("sha256", secret).update(payloadB64).digest("base64url");
29
- if (expectedSig.length !== sig.length ||
30
- !crypto.timingSafeEqual(Buffer.from(expectedSig), Buffer.from(sig))) {
31
- return null;
32
- }
33
- return decodeToken(token);
34
- }
35
- export function verifyToken(token, secret) {
36
- const payload = verifySignature(token, secret);
37
- if (!payload)
38
- return false;
39
- return Math.floor(Date.now() / 1000) < payload.exp;
40
- }
41
- /**
42
- * Like `verifyToken`, but also accepts a token that expired within the last
43
- * `REFRESH_GRACE_SECONDS`. Used ONLY by the refresh route so a briefly-lapsed
44
- * session can be renewed. The signature must still be valid (we minted it), so
45
- * this can't be forged.
46
- */
47
- export function verifyTokenForRefresh(token, secret) {
48
- const payload = verifySignature(token, secret);
49
- if (!payload)
50
- return false;
51
- return Math.floor(Date.now() / 1000) < payload.exp + REFRESH_GRACE_SECONDS;
52
- }
53
- /**
54
- * Decode a token's payload WITHOUT verifying its signature or expiry — used to
55
- * carry the login `method` across a refresh. Callers that need authenticity
56
- * must still gate on `verifyToken` (the refresh route runs behind
57
- * `authMiddleware`, which does exactly that). Returns null if unparseable.
58
- */
59
- export function decodeToken(token) {
60
- const parts = token.split(".");
61
- if (parts.length !== 2)
62
- return null;
63
- try {
64
- const payload = JSON.parse(Buffer.from(parts[0], "base64url").toString("utf8"));
65
- if (typeof payload.exp !== "number")
66
- return null;
67
- const method = payload.method;
68
- return {
69
- exp: payload.exp,
70
- method: method === "password" || method === "slack" || method === "github" ? method : undefined,
71
- };
72
- }
73
- catch {
74
- return null;
75
- }
76
- }
77
- /**
78
- * Whether any login method is configured — an admin password OR a working OAuth
79
- * provider. The single source of truth for "is auth on", shared by the admin
80
- * dashboard and the `/api/*` trigger routes so they can't drift. The GitHub
81
- * gate, like the OAuth route, also requires an allowed-org to be set.
82
- */
83
- export function authIsEnabled(opts) {
84
- const slack = Boolean(opts.slackOAuthClientId && opts.slackOAuthClientSecret);
85
- const github = Boolean(opts.githubOAuthClientId && opts.githubOAuthClientSecret && opts.githubAllowedOrg);
86
- return Boolean(opts.adminPassword) || slack || github;
87
- }
88
- /**
89
- * Gate the admin API. `enabled` should be true when ANY login method is
90
- * configured — an admin password OR a working OAuth provider. Gating only on
91
- * the password (the old behaviour) left the dashboard fully open whenever the
92
- * password was cleared, even with Slack/GitHub OAuth set up.
93
- */
94
- export function authMiddleware(enabled, secret) {
95
- return async (c, next) => {
96
- if (!enabled)
97
- return next();
98
- const path = new URL(c.req.url).pathname;
99
- // Let login + health + OAuth routes through
100
- if (path.endsWith("/login") ||
101
- path.endsWith("/token/refresh") ||
102
- path.endsWith("/health") ||
103
- path.endsWith("/auth-required") ||
104
- path.endsWith("/oauth/slack/authorize") ||
105
- path.endsWith("/oauth/slack/callback") ||
106
- path.endsWith("/oauth/github/authorize") ||
107
- path.endsWith("/oauth/github/callback")) {
108
- return next();
109
- }
110
- const header = c.req.header("Authorization");
111
- let token = header?.startsWith("Bearer ") ? header.slice(7) : undefined;
112
- // EventSource can't set headers — allow token via query param
113
- if (!token)
114
- token = c.req.query("token") ?? undefined;
115
- if (!token || !verifyToken(token, secret)) {
116
- return c.json({ error: "unauthorized" }, 401);
117
- }
118
- return next();
119
- };
120
- }
121
- //# sourceMappingURL=auth.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/admin/auth.ts"],"names":[],"mappings":"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"}
@@ -1,39 +0,0 @@
1
- import type { StateDb } from "../state/db.js";
2
- import { SessionLog, type JsonlMessage } from "../session-log.js";
3
- import type { SessionSource, SessionMeta } from "./sessions.js";
4
- /**
5
- * DB-backed chat-session reader. Drop-in replacement for SessionReader on
6
- * the chat path: same public surface (`mountSessionRoutes` works against it
7
- * unchanged), but listing comes from the executions table grouped by Slack
8
- * thread, and message reads target the single jsonl file owned by that
9
- * thread's pi-ai session id. SessionLog owns the on-disk CHAT_PROJECT_SLUG
10
- * path resolution, so this reader does not scan unrelated `agent-*.jsonl`
11
- * sidechain files from other in-process Agent SDK runs.
12
- *
13
- * Conceptual mapping:
14
- * - SessionMeta.id ← messaging_session.id (= Slack thread / executions.trigger_id)
15
- * - jsonl on disk ← SessionLog CHAT_PROJECT_SLUG file for
16
- * messaging_sessions.agent_session_id
17
- */
18
- export declare class ChatSessionReader implements SessionSource {
19
- private db;
20
- private sessionLog;
21
- constructor(db: StateDb, sessionsHomeDir: string);
22
- constructor(db: StateDb, sessionLog: SessionLog);
23
- /** All chat thread ids (= Slack threads) that have at least one chat execution. */
24
- listSessionIds(): string[];
25
- exists(id: string): boolean;
26
- getSessionMeta(id: string): Promise<SessionMeta | null>;
27
- read(id: string): Promise<Array<{
28
- index: number;
29
- msg: JsonlMessage;
30
- }>>;
31
- /**
32
- * Resolve a thread id to its on-disk Agent SDK jsonl. Returns null if
33
- * the thread has no agent_session_id yet (pre-resume) or the jsonl file
34
- * doesn't exist on disk (deleted, rotated, or written by a different
35
- * Agent SDK installation).
36
- */
37
- getFilePath(id: string): string | null;
38
- normalizeRawLine(raw: Record<string, unknown>): JsonlMessage[];
39
- }
@@ -1,84 +0,0 @@
1
- import { CHAT_PROJECT_SLUG, SessionLog, } from "../session-log.js";
2
- /**
3
- * DB-backed chat-session reader. Drop-in replacement for SessionReader on
4
- * the chat path: same public surface (`mountSessionRoutes` works against it
5
- * unchanged), but listing comes from the executions table grouped by Slack
6
- * thread, and message reads target the single jsonl file owned by that
7
- * thread's pi-ai session id. SessionLog owns the on-disk CHAT_PROJECT_SLUG
8
- * path resolution, so this reader does not scan unrelated `agent-*.jsonl`
9
- * sidechain files from other in-process Agent SDK runs.
10
- *
11
- * Conceptual mapping:
12
- * - SessionMeta.id ← messaging_session.id (= Slack thread / executions.trigger_id)
13
- * - jsonl on disk ← SessionLog CHAT_PROJECT_SLUG file for
14
- * messaging_sessions.agent_session_id
15
- */
16
- export class ChatSessionReader {
17
- db;
18
- sessionLog;
19
- constructor(db, sessionsHomeDirOrLog) {
20
- this.db = db;
21
- this.sessionLog = typeof sessionsHomeDirOrLog === "string"
22
- ? new SessionLog(sessionsHomeDirOrLog)
23
- : sessionsHomeDirOrLog;
24
- }
25
- /** All chat thread ids (= Slack threads) that have at least one chat execution. */
26
- listSessionIds() {
27
- // Soft cap at 500 — anything older than that almost certainly won't be
28
- // surfaced after the dashboard's per-tab filters anyway.
29
- return this.db.executions.listChatThreads(500).map((t) => t.triggerId);
30
- }
31
- exists(id) {
32
- return this.db.executions.getChatThread(id) !== null;
33
- }
34
- async getSessionMeta(id) {
35
- const t = this.db.executions.getChatThread(id);
36
- if (!t)
37
- return null;
38
- const startedAt = new Date(t.firstStartedAt).getTime() / 1000;
39
- const lastMessageAt = new Date(t.lastActivityAt).getTime() / 1000;
40
- // sessionType "chat" lets the dashboard SessionFilters show a chat
41
- // chip and gives the user a meaningful label.
42
- return {
43
- id,
44
- source: "chat",
45
- sessionType: "chat",
46
- model: null,
47
- started_at: Number.isNaN(startedAt) ? Date.now() / 1000 : startedAt,
48
- last_message_at: Number.isNaN(lastMessageAt) ? null : lastMessageAt,
49
- message_count: t.turnCount,
50
- tool_call_count: 0,
51
- conversation_message_count: t.turnCount,
52
- last_assistant_content: t.lastAssistantContent,
53
- agentIds: [],
54
- platform: t.platform,
55
- };
56
- }
57
- async read(id) {
58
- const thread = this.db.executions.getChatThread(id);
59
- if (!thread?.agentSessionId)
60
- return [];
61
- return this.sessionLog.readNormalizedSession("chat", thread.agentSessionId, {
62
- includeAgents: false,
63
- skipEmptySystem: true,
64
- });
65
- }
66
- /**
67
- * Resolve a thread id to its on-disk Agent SDK jsonl. Returns null if
68
- * the thread has no agent_session_id yet (pre-resume) or the jsonl file
69
- * doesn't exist on disk (deleted, rotated, or written by a different
70
- * Agent SDK installation).
71
- */
72
- getFilePath(id) {
73
- const thread = this.db.executions.getChatThread(id);
74
- if (!thread || !thread.agentSessionId)
75
- return null;
76
- return this.sessionLog.pathForProject(CHAT_PROJECT_SLUG, thread.agentSessionId, {
77
- requireExists: true,
78
- });
79
- }
80
- normalizeRawLine(raw) {
81
- return this.sessionLog.normalizeLine(raw);
82
- }
83
- }
84
- //# sourceMappingURL=chat-session-reader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-session-reader.js","sourceRoot":"","sources":["../../src/admin/chat-session-reader.ts"],"names":[],"mappings":"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"}
@@ -1,61 +0,0 @@
1
- export interface ContainerInfo {
2
- id: string;
3
- name: string;
4
- status: string;
5
- created: string;
6
- taskId: string | null;
7
- image: string;
8
- }
9
- export interface ContainerStats {
10
- name: string;
11
- cpuPercent: number;
12
- memUsageBytes: number;
13
- memLimitBytes: number;
14
- memPercent: number;
15
- }
16
- export declare function killContainer(containerName: string): Promise<void>;
17
- /**
18
- * Snapshot CPU/memory for every container whose name starts with `lastlight-`
19
- * (the agent itself plus any active sandboxes). Uses `docker stats --no-stream`
20
- * so each call is one read of cgroup counters — slower than a metadata lookup
21
- * but still ~sub-second on a small fleet.
22
- */
23
- export declare function getContainerStats(): Promise<ContainerStats[]>;
24
- export declare function listRunningContainers(): Promise<ContainerInfo[]>;
25
- export interface ServerContainer {
26
- name: string;
27
- /** Short label derived from the compose name: lastlight-<service>-<n>. */
28
- service: string;
29
- status: string;
30
- image: string;
31
- }
32
- /**
33
- * Every `lastlight-*` container (the agent plus the egress sidecars,
34
- * otel-collector, dozzle, and any live sandboxes) — running or stopped. Used
35
- * by the server-logs endpoints so an operator can read the harness/docker logs
36
- * over the admin API instead of SSHing to the host.
37
- */
38
- export declare function listServerContainers(): Promise<ServerContainer[]>;
39
- /**
40
- * Resolve a requested container (by full name OR short service label) to a real
41
- * `lastlight-*` container name, validated against the live list. Returns null
42
- * if nothing matches — callers reject the request, so an arbitrary container
43
- * name can never reach `docker logs`. With no request, defaults to the agent.
44
- */
45
- export declare function resolveServerContainer(requested?: string): Promise<string | null>;
46
- /**
47
- * One-shot `docker logs` for a container, newest `tail` lines. `--timestamps`
48
- * lets us interleave the container's stdout and stderr (captured on separate
49
- * fds) back into chronological order — RFC3339 prefixes sort lexically.
50
- */
51
- export declare function getContainerLogs(name: string, opts?: {
52
- tail?: number;
53
- since?: string;
54
- }): Promise<string[]>;
55
- /**
56
- * Follow `docker logs -f` for a container, invoking `onLine` per line from both
57
- * stdout and stderr. Returns a stop function that kills the child process.
58
- */
59
- export declare function streamContainerLogs(name: string, opts: {
60
- tail?: number;
61
- }, onLine: (line: string) => void): () => void;
@@ -1,187 +0,0 @@
1
- import { execFile, spawn } from "node:child_process";
2
- import { promisify } from "node:util";
3
- const exec = promisify(execFile);
4
- export async function killContainer(containerName) {
5
- await exec("docker", ["rm", "-f", containerName]);
6
- }
7
- /**
8
- * Snapshot CPU/memory for every container whose name starts with `lastlight-`
9
- * (the agent itself plus any active sandboxes). Uses `docker stats --no-stream`
10
- * so each call is one read of cgroup counters — slower than a metadata lookup
11
- * but still ~sub-second on a small fleet.
12
- */
13
- export async function getContainerStats() {
14
- try {
15
- const { stdout } = await exec("docker", [
16
- "stats",
17
- "--no-stream",
18
- "--format", "{{json .}}",
19
- ]);
20
- if (!stdout.trim())
21
- return [];
22
- return stdout
23
- .trim()
24
- .split("\n")
25
- .map((line) => JSON.parse(line))
26
- .filter((c) => (c.Name ?? "").startsWith("lastlight"))
27
- .map((c) => {
28
- const name = c.Name ?? "";
29
- const cpuPercent = parsePercent(c.CPUPerc);
30
- const memPercent = parsePercent(c.MemPerc);
31
- const [usage, limit] = parseMemUsage(c.MemUsage);
32
- return {
33
- name,
34
- cpuPercent,
35
- memUsageBytes: usage,
36
- memLimitBytes: limit,
37
- memPercent,
38
- };
39
- });
40
- }
41
- catch {
42
- return [];
43
- }
44
- }
45
- function parsePercent(raw) {
46
- if (!raw)
47
- return 0;
48
- const n = parseFloat(raw.replace("%", "").trim());
49
- return Number.isFinite(n) ? n : 0;
50
- }
51
- // Docker formats memory like "123.4MiB / 7.7GiB" — convert each side to bytes.
52
- function parseMemUsage(raw) {
53
- if (!raw)
54
- return [0, 0];
55
- const parts = raw.split("/").map((p) => p.trim());
56
- return [parseSize(parts[0] ?? ""), parseSize(parts[1] ?? "")];
57
- }
58
- function parseSize(raw) {
59
- const m = raw.match(/^([\d.]+)\s*([KMGT]?i?B)$/i);
60
- if (!m)
61
- return 0;
62
- const value = parseFloat(m[1]);
63
- const unit = m[2].toLowerCase();
64
- const multipliers = {
65
- b: 1,
66
- kb: 1e3, mb: 1e6, gb: 1e9, tb: 1e12,
67
- kib: 1024, mib: 1024 ** 2, gib: 1024 ** 3, tib: 1024 ** 4,
68
- };
69
- return value * (multipliers[unit] ?? 1);
70
- }
71
- export async function listRunningContainers() {
72
- try {
73
- const { stdout } = await exec("docker", [
74
- "ps",
75
- "--filter", "name=lastlight-sandbox",
76
- "--format", "{{json .}}",
77
- ]);
78
- if (!stdout.trim())
79
- return [];
80
- return stdout
81
- .trim()
82
- .split("\n")
83
- .map((line) => {
84
- const c = JSON.parse(line);
85
- const name = c.Names ?? c.Name ?? "";
86
- // Parse taskId from: lastlight-sandbox-{taskId}-{uuid}
87
- const match = name.match(/^lastlight-sandbox-(.+?)-[a-f0-9]{8}$/);
88
- return {
89
- id: c.ID ?? "",
90
- name,
91
- status: c.Status ?? "",
92
- created: c.CreatedAt ?? c.RunningFor ?? "",
93
- taskId: match?.[1] ?? null,
94
- image: c.Image ?? "",
95
- };
96
- });
97
- }
98
- catch {
99
- return [];
100
- }
101
- }
102
- /**
103
- * Every `lastlight-*` container (the agent plus the egress sidecars,
104
- * otel-collector, dozzle, and any live sandboxes) — running or stopped. Used
105
- * by the server-logs endpoints so an operator can read the harness/docker logs
106
- * over the admin API instead of SSHing to the host.
107
- */
108
- export async function listServerContainers() {
109
- try {
110
- const { stdout } = await exec("docker", [
111
- "ps", "-a",
112
- "--filter", "name=lastlight-",
113
- "--format", "{{json .}}",
114
- ]);
115
- if (!stdout.trim())
116
- return [];
117
- return stdout.trim().split("\n").map((line) => {
118
- const c = JSON.parse(line);
119
- const name = c.Names ?? c.Name ?? "";
120
- return {
121
- name,
122
- service: name.replace(/^lastlight-/, "").replace(/-\d+$/, ""),
123
- status: c.Status ?? "",
124
- image: c.Image ?? "",
125
- };
126
- });
127
- }
128
- catch {
129
- return [];
130
- }
131
- }
132
- /**
133
- * Resolve a requested container (by full name OR short service label) to a real
134
- * `lastlight-*` container name, validated against the live list. Returns null
135
- * if nothing matches — callers reject the request, so an arbitrary container
136
- * name can never reach `docker logs`. With no request, defaults to the agent.
137
- */
138
- export async function resolveServerContainer(requested) {
139
- const containers = await listServerContainers();
140
- if (requested) {
141
- const hit = containers.find((c) => c.name === requested || c.service === requested);
142
- return hit?.name ?? null;
143
- }
144
- const agent = containers.find((c) => c.service === "agent" || c.name.includes("-agent-"));
145
- return agent?.name ?? containers[0]?.name ?? null;
146
- }
147
- /**
148
- * One-shot `docker logs` for a container, newest `tail` lines. `--timestamps`
149
- * lets us interleave the container's stdout and stderr (captured on separate
150
- * fds) back into chronological order — RFC3339 prefixes sort lexically.
151
- */
152
- export async function getContainerLogs(name, opts = {}) {
153
- const args = ["logs", "--timestamps", "--tail", String(opts.tail ?? 200)];
154
- if (opts.since)
155
- args.push("--since", opts.since);
156
- args.push(name);
157
- const { stdout, stderr } = await exec("docker", args, { maxBuffer: 32 * 1024 * 1024 });
158
- const lines = [
159
- ...(stdout ? stdout.split("\n") : []),
160
- ...(stderr ? stderr.split("\n") : []),
161
- ].filter((l) => l.length > 0);
162
- lines.sort((a, b) => a.slice(0, 30).localeCompare(b.slice(0, 30)));
163
- return lines;
164
- }
165
- /**
166
- * Follow `docker logs -f` for a container, invoking `onLine` per line from both
167
- * stdout and stderr. Returns a stop function that kills the child process.
168
- */
169
- export function streamContainerLogs(name, opts, onLine) {
170
- const child = spawn("docker", [
171
- "logs", "-f", "--timestamps", "--tail", String(opts.tail ?? 200), name,
172
- ]);
173
- const handle = (buf) => {
174
- for (const line of buf.toString().split("\n"))
175
- if (line)
176
- onLine(line);
177
- };
178
- child.stdout?.on("data", handle);
179
- child.stderr?.on("data", handle);
180
- return () => {
181
- try {
182
- child.kill("SIGKILL");
183
- }
184
- catch { /* already dead */ }
185
- };
186
- }
187
- //# sourceMappingURL=docker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/admin/docker.ts"],"names":[],"mappings":"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"}