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.
- package/README.md +265 -118
- package/agent-context/rules.md +62 -9
- package/agent-context/security.md +69 -0
- package/config/default.yaml +89 -0
- package/deploy/.env.production.example +20 -2
- package/deploy/entrypoint.sh +16 -17
- package/deploy/native/README.md +160 -0
- package/deploy/native/install.sh +110 -0
- package/deploy/native/lastlight.env.example +95 -0
- package/deploy/native/lastlight.service +50 -0
- package/deploy/sandbox-entrypoint.sh +59 -42
- package/dist/admin/auth.d.ts +1 -1
- package/dist/admin/auth.js +3 -1
- package/dist/admin/auth.js.map +1 -1
- package/dist/admin/chat-session-reader.d.ts +11 -14
- package/dist/admin/chat-session-reader.js +27 -51
- package/dist/admin/chat-session-reader.js.map +1 -1
- package/dist/admin/docker.d.ts +37 -0
- package/dist/admin/docker.js +86 -1
- package/dist/admin/docker.js.map +1 -1
- package/dist/admin/index.js +38 -3
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/log-search.test.d.ts +1 -0
- package/dist/admin/log-search.test.js +78 -0
- package/dist/admin/log-search.test.js.map +1 -0
- package/dist/admin/routes.d.ts +52 -3
- package/dist/admin/routes.js +780 -63
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/routes.test.js +680 -14
- package/dist/admin/routes.test.js.map +1 -1
- package/dist/admin/server-logs.test.d.ts +1 -0
- package/dist/admin/server-logs.test.js +58 -0
- package/dist/admin/server-logs.test.js.map +1 -0
- package/dist/admin/sessions.d.ts +26 -39
- package/dist/admin/sessions.js +86 -310
- package/dist/admin/sessions.js.map +1 -1
- package/dist/admin/sessions.test.d.ts +1 -0
- package/dist/admin/sessions.test.js +78 -0
- package/dist/admin/sessions.test.js.map +1 -0
- package/dist/admin/version.d.ts +15 -0
- package/dist/admin/version.js +73 -0
- package/dist/admin/version.js.map +1 -0
- package/dist/admin/version.test.d.ts +1 -0
- package/dist/admin/version.test.js +71 -0
- package/dist/admin/version.test.js.map +1 -0
- package/dist/cli-config.d.ts +55 -0
- package/dist/cli-config.js +119 -0
- package/dist/cli-config.js.map +1 -0
- package/dist/cli-config.test.d.ts +1 -0
- package/dist/cli-config.test.js +92 -0
- package/dist/cli-config.test.js.map +1 -0
- package/dist/cli-format.d.ts +19 -0
- package/dist/cli-format.js +107 -0
- package/dist/cli-format.js.map +1 -0
- package/dist/cli-server.d.ts +73 -0
- package/dist/cli-server.js +347 -0
- package/dist/cli-server.js.map +1 -0
- package/dist/cli-server.test.d.ts +1 -0
- package/dist/cli-server.test.js +38 -0
- package/dist/cli-server.test.js.map +1 -0
- package/dist/cli-timeline.d.ts +35 -0
- package/dist/cli-timeline.js +373 -0
- package/dist/cli-timeline.js.map +1 -0
- package/dist/cli-timeline.test.d.ts +1 -0
- package/dist/cli-timeline.test.js +104 -0
- package/dist/cli-timeline.test.js.map +1 -0
- package/dist/cli.d.ts +0 -19
- package/dist/cli.js +910 -194
- package/dist/cli.js.map +1 -1
- package/dist/config-overlay.test.d.ts +1 -0
- package/dist/config-overlay.test.js +112 -0
- package/dist/config-overlay.test.js.map +1 -0
- package/dist/config-resolve.d.ts +28 -0
- package/dist/config-resolve.js +47 -0
- package/dist/config-resolve.js.map +1 -0
- package/dist/config-resolve.test.d.ts +1 -0
- package/dist/config-resolve.test.js +68 -0
- package/dist/config-resolve.test.js.map +1 -0
- package/dist/config.d.ts +62 -49
- package/dist/config.js +452 -76
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +201 -32
- package/dist/config.test.js.map +1 -1
- package/dist/connectors/github-webhook.js +83 -5
- package/dist/connectors/github-webhook.js.map +1 -1
- package/dist/connectors/github-webhook.test.d.ts +1 -0
- package/dist/connectors/github-webhook.test.js +156 -0
- package/dist/connectors/github-webhook.test.js.map +1 -0
- package/dist/connectors/messaging/session-manager.d.ts +18 -0
- package/dist/connectors/messaging/session-manager.js +83 -2
- package/dist/connectors/messaging/session-manager.js.map +1 -1
- package/dist/connectors/messaging/session-manager.test.d.ts +1 -0
- package/dist/connectors/messaging/session-manager.test.js +144 -0
- package/dist/connectors/messaging/session-manager.test.js.map +1 -0
- package/dist/connectors/slack/connector.d.ts +9 -0
- package/dist/connectors/slack/connector.js +15 -0
- package/dist/connectors/slack/connector.js.map +1 -1
- package/dist/connectors/slack/mrkdwn.js +81 -0
- package/dist/connectors/slack/mrkdwn.js.map +1 -1
- package/dist/connectors/slack/mrkdwn.test.js +49 -0
- package/dist/connectors/slack/mrkdwn.test.js.map +1 -1
- package/dist/connectors/types.d.ts +1 -1
- package/dist/cron/fanout.d.ts +33 -0
- package/dist/cron/fanout.js +55 -0
- package/dist/cron/fanout.js.map +1 -0
- package/dist/cron/fanout.test.d.ts +1 -0
- package/dist/cron/fanout.test.js +73 -0
- package/dist/cron/fanout.test.js.map +1 -0
- package/dist/cron/jobs.d.ts +5 -0
- package/dist/cron/jobs.js +10 -3
- package/dist/cron/jobs.js.map +1 -1
- package/dist/cron/scheduler.d.ts +12 -0
- package/dist/cron/scheduler.js +27 -1
- package/dist/cron/scheduler.js.map +1 -1
- package/dist/engine/agent-executor.d.ts +158 -0
- package/dist/engine/agent-executor.js +1140 -0
- package/dist/engine/agent-executor.js.map +1 -0
- package/dist/engine/agent-executor.test.d.ts +1 -0
- package/dist/engine/agent-executor.test.js +395 -0
- package/dist/engine/agent-executor.test.js.map +1 -0
- package/dist/engine/chat-runner.d.ts +123 -0
- package/dist/engine/chat-runner.js +379 -0
- package/dist/engine/chat-runner.js.map +1 -0
- package/dist/engine/chat-runner.test.d.ts +1 -0
- package/dist/engine/chat-runner.test.js +104 -0
- package/dist/engine/chat-runner.test.js.map +1 -0
- package/dist/engine/chat-skills.d.ts +45 -0
- package/dist/engine/chat-skills.js +184 -0
- package/dist/engine/chat-skills.js.map +1 -0
- package/dist/engine/chat-skills.test.d.ts +1 -0
- package/dist/engine/chat-skills.test.js +20 -0
- package/dist/engine/chat-skills.test.js.map +1 -0
- package/dist/engine/chat.d.ts +20 -23
- package/dist/engine/chat.js +251 -155
- package/dist/engine/chat.js.map +1 -1
- package/dist/engine/chat.test.d.ts +1 -0
- package/dist/engine/chat.test.js +42 -0
- package/dist/engine/chat.test.js.map +1 -0
- package/dist/engine/classifier.d.ts +35 -2
- package/dist/engine/classifier.js +170 -31
- package/dist/engine/classifier.js.map +1 -1
- package/dist/engine/classifier.test.d.ts +1 -0
- package/dist/engine/classifier.test.js +115 -0
- package/dist/engine/classifier.test.js.map +1 -0
- package/dist/engine/dispatcher.d.ts +60 -0
- package/dist/engine/dispatcher.js +601 -0
- package/dist/engine/dispatcher.js.map +1 -0
- package/dist/engine/dispatcher.test.d.ts +1 -0
- package/dist/engine/dispatcher.test.js +511 -0
- package/dist/engine/dispatcher.test.js.map +1 -0
- package/dist/engine/event-shim.d.ts +117 -0
- package/dist/engine/event-shim.js +435 -0
- package/dist/engine/event-shim.js.map +1 -0
- package/dist/engine/event-shim.test.d.ts +1 -0
- package/dist/engine/event-shim.test.js +194 -0
- package/dist/engine/event-shim.test.js.map +1 -0
- package/dist/engine/git-auth.d.ts +13 -17
- package/dist/engine/git-auth.js +99 -42
- package/dist/engine/git-auth.js.map +1 -1
- package/dist/engine/git-auth.test.d.ts +1 -0
- package/dist/engine/git-auth.test.js +117 -0
- package/dist/engine/git-auth.test.js.map +1 -0
- package/dist/engine/github-app-client.d.ts +7 -0
- package/dist/engine/github-app-client.js +16 -0
- package/dist/engine/github-app-client.js.map +1 -0
- package/dist/engine/github-app-client.test.d.ts +1 -0
- package/dist/engine/github-app-client.test.js +44 -0
- package/dist/engine/github-app-client.test.js.map +1 -0
- package/dist/engine/github-tools.d.ts +12 -0
- package/dist/engine/github-tools.js +261 -0
- package/dist/engine/github-tools.js.map +1 -0
- package/dist/engine/github.d.ts +1027 -43
- package/dist/engine/github.js +153 -14
- package/dist/engine/github.js.map +1 -1
- package/dist/engine/llm.d.ts +47 -0
- package/dist/engine/llm.js +221 -0
- package/dist/engine/llm.js.map +1 -0
- package/dist/engine/llm.test.d.ts +1 -0
- package/dist/engine/llm.test.js +189 -0
- package/dist/engine/llm.test.js.map +1 -0
- package/dist/engine/profiles.d.ts +249 -0
- package/dist/engine/profiles.js +42 -0
- package/dist/engine/profiles.js.map +1 -0
- package/dist/engine/router.d.ts +12 -6
- package/dist/engine/router.js +339 -81
- package/dist/engine/router.js.map +1 -1
- package/dist/engine/router.test.js +428 -78
- package/dist/engine/router.test.js.map +1 -1
- package/dist/engine/screen.d.ts +41 -0
- package/dist/engine/screen.js +93 -0
- package/dist/engine/screen.js.map +1 -0
- package/dist/engine/screen.test.d.ts +1 -0
- package/dist/engine/screen.test.js +82 -0
- package/dist/engine/screen.test.js.map +1 -0
- package/dist/index.js +377 -432
- package/dist/index.js.map +1 -1
- package/dist/managed-repos.d.ts +7 -9
- package/dist/managed-repos.js +12 -15
- package/dist/managed-repos.js.map +1 -1
- package/dist/managed-repos.test.js +24 -19
- package/dist/managed-repos.test.js.map +1 -1
- package/dist/notify/index.d.ts +15 -0
- package/dist/notify/index.js +6 -0
- package/dist/notify/index.js.map +1 -0
- package/dist/notify/model.d.ts +57 -0
- package/dist/notify/model.js +89 -0
- package/dist/notify/model.js.map +1 -0
- package/dist/notify/model.test.d.ts +1 -0
- package/dist/notify/model.test.js +109 -0
- package/dist/notify/model.test.js.map +1 -0
- package/dist/notify/notifier.d.ts +17 -0
- package/dist/notify/notifier.js +87 -0
- package/dist/notify/notifier.js.map +1 -0
- package/dist/notify/notifier.test.d.ts +1 -0
- package/dist/notify/notifier.test.js +100 -0
- package/dist/notify/notifier.test.js.map +1 -0
- package/dist/notify/render.d.ts +21 -0
- package/dist/notify/render.js +59 -0
- package/dist/notify/render.js.map +1 -0
- package/dist/notify/render.test.d.ts +1 -0
- package/dist/notify/render.test.js +65 -0
- package/dist/notify/render.test.js.map +1 -0
- package/dist/notify/transports/github.d.ts +26 -0
- package/dist/notify/transports/github.js +26 -0
- package/dist/notify/transports/github.js.map +1 -0
- package/dist/notify/transports/slack.d.ts +26 -0
- package/dist/notify/transports/slack.js +28 -0
- package/dist/notify/transports/slack.js.map +1 -0
- package/dist/notify/transports.test.d.ts +1 -0
- package/dist/notify/transports.test.js +71 -0
- package/dist/notify/transports.test.js.map +1 -0
- package/dist/notify/types.d.ts +95 -0
- package/dist/notify/types.js +16 -0
- package/dist/notify/types.js.map +1 -0
- package/dist/sandbox/docker-compose.test.d.ts +1 -0
- package/dist/sandbox/docker-compose.test.js +128 -0
- package/dist/sandbox/docker-compose.test.js.map +1 -0
- package/dist/sandbox/docker.d.ts +97 -9
- package/dist/sandbox/docker.js +192 -41
- package/dist/sandbox/docker.js.map +1 -1
- package/dist/sandbox/docker.test.d.ts +1 -0
- package/dist/sandbox/docker.test.js +137 -0
- package/dist/sandbox/docker.test.js.map +1 -0
- package/dist/sandbox/egress-allowlist.d.ts +69 -0
- package/dist/sandbox/egress-allowlist.js +164 -0
- package/dist/sandbox/egress-allowlist.js.map +1 -0
- package/dist/sandbox/egress-allowlist.test.d.ts +1 -0
- package/dist/sandbox/egress-allowlist.test.js +65 -0
- package/dist/sandbox/egress-allowlist.test.js.map +1 -0
- package/dist/sandbox/egress-firewall-config.d.ts +127 -0
- package/dist/sandbox/egress-firewall-config.js +434 -0
- package/dist/sandbox/egress-firewall-config.js.map +1 -0
- package/dist/sandbox/egress-firewall-config.test.d.ts +1 -0
- package/dist/sandbox/egress-firewall-config.test.js +244 -0
- package/dist/sandbox/egress-firewall-config.test.js.map +1 -0
- package/dist/sandbox/images.d.ts +23 -0
- package/dist/sandbox/images.js +55 -0
- package/dist/sandbox/images.js.map +1 -0
- package/dist/sandbox/index.d.ts +82 -3
- package/dist/sandbox/index.js +223 -93
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/index.test.d.ts +1 -0
- package/dist/sandbox/index.test.js +157 -0
- package/dist/sandbox/index.test.js.map +1 -0
- package/dist/session-log.d.ts +63 -0
- package/dist/session-log.js +290 -0
- package/dist/session-log.js.map +1 -0
- package/dist/session-log.test.d.ts +1 -0
- package/dist/session-log.test.js +85 -0
- package/dist/session-log.test.js.map +1 -0
- package/dist/setup.d.ts +30 -1
- package/dist/setup.js +241 -25
- package/dist/setup.js.map +1 -1
- package/dist/setup.test.js +138 -6
- package/dist/setup.test.js.map +1 -1
- package/dist/state/approval-store.d.ts +86 -0
- package/dist/state/approval-store.js +140 -0
- package/dist/state/approval-store.js.map +1 -0
- package/dist/state/build-assets.d.ts +50 -0
- package/dist/state/build-assets.js +154 -0
- package/dist/state/build-assets.js.map +1 -0
- package/dist/state/build-assets.test.d.ts +1 -0
- package/dist/state/build-assets.test.js +106 -0
- package/dist/state/build-assets.test.js.map +1 -0
- package/dist/state/db.d.ts +65 -333
- package/dist/state/db.js +112 -835
- package/dist/state/db.js.map +1 -1
- package/dist/state/db.test.js +127 -91
- package/dist/state/db.test.js.map +1 -1
- package/dist/state/execution-store.d.ts +257 -0
- package/dist/state/execution-store.js +527 -0
- package/dist/state/execution-store.js.map +1 -0
- package/dist/state/migrate.d.ts +15 -0
- package/dist/state/migrate.js +175 -0
- package/dist/state/migrate.js.map +1 -0
- package/dist/state/workflow-run-store.d.ts +195 -0
- package/dist/state/workflow-run-store.js +363 -0
- package/dist/state/workflow-run-store.js.map +1 -0
- package/dist/state/workflow-run-store.test.d.ts +1 -0
- package/dist/state/workflow-run-store.test.js +264 -0
- package/dist/state/workflow-run-store.test.js.map +1 -0
- package/dist/telemetry/index.d.ts +38 -0
- package/dist/telemetry/index.js +253 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/index.test.d.ts +1 -0
- package/dist/telemetry/index.test.js +73 -0
- package/dist/telemetry/index.test.js.map +1 -0
- package/dist/telemetry/pi-events.d.ts +12 -0
- package/dist/telemetry/pi-events.js +134 -0
- package/dist/telemetry/pi-events.js.map +1 -0
- package/dist/telemetry/pi-events.test.d.ts +1 -0
- package/dist/telemetry/pi-events.test.js +69 -0
- package/dist/telemetry/pi-events.test.js.map +1 -0
- package/dist/workflows/dag.d.ts +13 -1
- package/dist/workflows/dag.js +7 -3
- package/dist/workflows/dag.js.map +1 -1
- package/dist/workflows/dag.test.js +22 -0
- package/dist/workflows/dag.test.js.map +1 -1
- package/dist/workflows/golden-build.test.d.ts +1 -0
- package/dist/workflows/golden-build.test.js +45 -0
- package/dist/workflows/golden-build.test.js.map +1 -0
- package/dist/workflows/loader-overlay.test.d.ts +1 -0
- package/dist/workflows/loader-overlay.test.js +101 -0
- package/dist/workflows/loader-overlay.test.js.map +1 -0
- package/dist/workflows/loader.d.ts +36 -11
- package/dist/workflows/loader.js +311 -87
- package/dist/workflows/loader.js.map +1 -1
- package/dist/workflows/loader.test.js +114 -10
- package/dist/workflows/loader.test.js.map +1 -1
- package/dist/workflows/loop-eval.js +2 -0
- package/dist/workflows/loop-eval.js.map +1 -1
- package/dist/workflows/loop-eval.test.js +14 -0
- package/dist/workflows/loop-eval.test.js.map +1 -1
- package/dist/workflows/phase-executor.d.ts +145 -0
- package/dist/workflows/phase-executor.js +691 -0
- package/dist/workflows/phase-executor.js.map +1 -0
- package/dist/workflows/phase-executor.test.d.ts +1 -0
- package/dist/workflows/phase-executor.test.js +434 -0
- package/dist/workflows/phase-executor.test.js.map +1 -0
- package/dist/workflows/phase-ref.d.ts +44 -0
- package/dist/workflows/phase-ref.js +78 -0
- package/dist/workflows/phase-ref.js.map +1 -0
- package/dist/workflows/phase-ref.test.d.ts +1 -0
- package/dist/workflows/phase-ref.test.js +24 -0
- package/dist/workflows/phase-ref.test.js.map +1 -0
- package/dist/workflows/resume.d.ts +5 -11
- package/dist/workflows/resume.js +88 -7
- package/dist/workflows/resume.js.map +1 -1
- package/dist/workflows/runner.d.ts +34 -27
- package/dist/workflows/runner.js +252 -930
- package/dist/workflows/runner.js.map +1 -1
- package/dist/workflows/runner.test.js +346 -35
- package/dist/workflows/runner.test.js.map +1 -1
- package/dist/workflows/schema.d.ts +52 -10
- package/dist/workflows/schema.js +147 -7
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/simple.d.ts +67 -3
- package/dist/workflows/simple.js +248 -87
- package/dist/workflows/simple.js.map +1 -1
- package/dist/workflows/simple.test.d.ts +1 -0
- package/dist/workflows/simple.test.js +107 -0
- package/dist/workflows/simple.test.js.map +1 -0
- package/dist/workflows/templates.d.ts +29 -0
- package/dist/workflows/templates.js +42 -4
- package/dist/workflows/templates.js.map +1 -1
- package/dist/workflows/templates.test.js +103 -0
- package/dist/workflows/templates.test.js.map +1 -1
- package/dist/workflows/triggers.d.ts +21 -0
- package/dist/workflows/triggers.js +44 -0
- package/dist/workflows/triggers.js.map +1 -0
- package/dist/workflows/verdict.d.ts +19 -0
- package/dist/workflows/verdict.js +30 -0
- package/dist/workflows/verdict.js.map +1 -0
- package/dist/workflows/verdict.test.d.ts +1 -0
- package/dist/workflows/verdict.test.js +44 -0
- package/dist/workflows/verdict.test.js.map +1 -0
- package/dist/worktree/manager.d.ts +1 -1
- package/dist/worktree/manager.js +14 -14
- package/dist/worktree/manager.js.map +1 -1
- package/dist/worktree/manager.test.d.ts +1 -0
- package/dist/worktree/manager.test.js +87 -0
- package/dist/worktree/manager.test.js.map +1 -0
- package/docker-compose.yml +206 -5
- package/package.json +19 -9
- package/sandbox.Dockerfile +97 -18
- package/skills/README.md +40 -0
- package/skills/browser-qa/SKILL.md +193 -0
- package/skills/browser-qa/scripts/agent-browser.mjs +380 -0
- package/skills/building/SKILL.md +95 -0
- package/skills/chat/SKILL.md +30 -11
- package/skills/code-review/SKILL.md +59 -0
- package/skills/debug-production/SKILL.md +108 -0
- package/skills/demo/SKILL.md +194 -0
- package/skills/demo/scripts/compose-demo.sh +205 -0
- package/skills/issue-answer/SKILL.md +90 -0
- package/skills/issue-comment/SKILL.md +38 -24
- package/skills/issue-triage/SKILL.md +103 -37
- package/skills/issue-triage/references/AGENT-BRIEF.md +61 -0
- package/skills/pr-comment/SKILL.md +64 -0
- package/skills/pr-review/SKILL.md +65 -49
- package/skills/qa-test/SKILL.md +97 -0
- package/skills/repo-health/SKILL.md +48 -45
- package/skills/security-feedback/SKILL.md +173 -0
- package/skills/security-feedback/references/templates.md +77 -0
- package/skills/security-review/SKILL.md +213 -0
- package/skills/security-review/references/issue-format.md +302 -0
- package/skills/verify/SKILL.md +118 -0
- package/workflows/answer.yaml +37 -0
- package/workflows/build.yaml +32 -22
- package/workflows/cron-security.yaml +6 -0
- package/workflows/demo.yaml +55 -0
- package/workflows/explore.yaml +9 -0
- package/workflows/pr-comment.yaml +16 -0
- package/workflows/pr-fix.yaml +3 -0
- package/workflows/pr-review.yaml +4 -1
- package/workflows/prompts/answer.md +67 -0
- package/workflows/prompts/architect.md +24 -7
- package/workflows/prompts/demo.md +100 -0
- package/workflows/prompts/executor.md +29 -20
- package/workflows/prompts/explore-ask.md +51 -22
- package/workflows/prompts/explore-publish.md +2 -2
- package/workflows/prompts/explore-read.md +24 -10
- package/workflows/prompts/explore-synthesize.md +15 -8
- package/workflows/prompts/fix.md +9 -10
- package/workflows/prompts/guardrails.md +26 -8
- package/workflows/prompts/pr-fix.md +6 -7
- package/workflows/prompts/pr.md +11 -10
- package/workflows/prompts/qa-browser.md +95 -0
- package/workflows/prompts/qa-synth.md +44 -0
- package/workflows/prompts/qa-test.md +60 -0
- package/workflows/prompts/re-reviewer.md +8 -9
- package/workflows/prompts/reviewer.md +10 -9
- package/workflows/prompts/verify-browser.md +93 -0
- package/workflows/prompts/verify-synth.md +44 -0
- package/workflows/prompts/verify.md +63 -0
- package/workflows/qa-test.yaml +87 -0
- package/workflows/security-feedback.yaml +25 -0
- package/workflows/security-review.yaml +29 -0
- package/workflows/verify.yaml +85 -0
- package/deploy/mcp-config.tmpl.json +0 -14
- package/dist/cron/rate-limits.d.ts +0 -26
- package/dist/cron/rate-limits.js +0 -193
- package/dist/cron/rate-limits.js.map +0 -1
- package/dist/engine/executor.d.ts +0 -75
- package/dist/engine/executor.js +0 -292
- package/dist/engine/executor.js.map +0 -1
- package/mcp-github-app/package.json +0 -18
- package/mcp-github-app/src/auth.js +0 -66
- package/mcp-github-app/src/github.js +0 -371
- package/mcp-github-app/src/index.js +0 -534
- package/skills/devops/webhook-subscriptions/SKILL.md +0 -180
- package/skills/github/DESCRIPTION.md +0 -3
- package/skills/github/codebase-inspection/SKILL.md +0 -115
- package/skills/github/github-auth/SKILL.md +0 -54
- package/skills/github/github-auth/scripts/gh-env.sh +0 -66
- package/skills/github/github-code-review/SKILL.md +0 -480
- package/skills/github/github-code-review/references/review-output-template.md +0 -74
- package/skills/github/github-issues/SKILL.md +0 -369
- package/skills/github/github-issues/templates/bug-report.md +0 -35
- package/skills/github/github-issues/templates/feature-request.md +0 -31
- package/skills/github/github-pr-workflow/SKILL.md +0 -395
- package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +0 -183
- package/skills/github/github-pr-workflow/references/conventional-commits.md +0 -71
- package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +0 -35
- package/skills/github/github-pr-workflow/templates/pr-body-feature.md +0 -33
- package/skills/github/github-repo-management/SKILL.md +0 -515
- package/skills/github/github-repo-management/references/github-api-cheatsheet.md +0 -161
- package/skills/github-orchestrator/SKILL.md +0 -103
- package/skills/mcp/DESCRIPTION.md +0 -3
- package/skills/mcp/mcporter/SKILL.md +0 -122
- package/skills/mcp/native-mcp/SKILL.md +0 -356
- package/skills/software-development/architect/SKILL.md +0 -154
- package/skills/software-development/assure-guardrails/SKILL.md +0 -239
- package/skills/software-development/plan/SKILL.md +0 -64
- package/skills/software-development/requesting-code-review/SKILL.md +0 -291
- package/skills/software-development/subagent-driven-development/SKILL.md +0 -433
- package/skills/software-development/systematic-debugging/SKILL.md +0 -366
- package/skills/software-development/test-driven-development/SKILL.md +0 -342
package/dist/worktree/manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { existsSync, rmSync } from "fs";
|
|
1
|
+
import { execFileSync } from "child_process";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync } from "fs";
|
|
3
3
|
import { join, resolve } from "path";
|
|
4
4
|
const WORKTREE_DIR = ".worktrees";
|
|
5
5
|
/**
|
|
@@ -14,8 +14,8 @@ export class WorktreeManager {
|
|
|
14
14
|
constructor(baseDir) {
|
|
15
15
|
this.baseDir = baseDir || resolve(WORKTREE_DIR);
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
return
|
|
17
|
+
execGit(args, opts) {
|
|
18
|
+
return execFileSync("git", args, { encoding: "utf-8", stdio: "pipe", ...opts });
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Create a new worktree for a task.
|
|
@@ -29,7 +29,7 @@ export class WorktreeManager {
|
|
|
29
29
|
const worktreePath = join(this.baseDir, taskId);
|
|
30
30
|
// Ensure base directory exists
|
|
31
31
|
if (!existsSync(this.baseDir)) {
|
|
32
|
-
|
|
32
|
+
mkdirSync(this.baseDir, { recursive: true });
|
|
33
33
|
}
|
|
34
34
|
// We need a bare/normal repo to create worktrees from.
|
|
35
35
|
// Use a shared bare clone per repo to avoid re-cloning each time.
|
|
@@ -37,11 +37,11 @@ export class WorktreeManager {
|
|
|
37
37
|
const bareDir = join(this.baseDir, `.bare-${repoName}`);
|
|
38
38
|
if (!existsSync(bareDir)) {
|
|
39
39
|
console.log(`[worktree] Bare clone: ${repoUrl}`);
|
|
40
|
-
this.
|
|
40
|
+
this.execGit(["clone", "--bare", repoUrl, bareDir]);
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
43
43
|
// Fetch latest
|
|
44
|
-
this.
|
|
44
|
+
this.execGit(["-C", bareDir, "fetch", "--all", "--prune"]);
|
|
45
45
|
}
|
|
46
46
|
// Create worktree with new branch from base
|
|
47
47
|
const base = baseBranch || "main";
|
|
@@ -49,7 +49,7 @@ export class WorktreeManager {
|
|
|
49
49
|
// Check if branch already exists remotely
|
|
50
50
|
let branchExists = false;
|
|
51
51
|
try {
|
|
52
|
-
this.
|
|
52
|
+
this.execGit(["-C", bareDir, "rev-parse", "--verify", `origin/${branch}`]);
|
|
53
53
|
branchExists = true;
|
|
54
54
|
}
|
|
55
55
|
catch {
|
|
@@ -58,13 +58,13 @@ export class WorktreeManager {
|
|
|
58
58
|
if (branchExists) {
|
|
59
59
|
// Resume existing branch
|
|
60
60
|
console.log(`[worktree] Resuming branch: ${branch}`);
|
|
61
|
-
this.
|
|
62
|
-
this.
|
|
61
|
+
this.execGit(["-C", bareDir, "worktree", "add", worktreePath, `origin/${branch}`]);
|
|
62
|
+
this.execGit(["-C", worktreePath, "checkout", "-B", branch, `origin/${branch}`]);
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
65
|
// Create new branch from base
|
|
66
66
|
console.log(`[worktree] New branch: ${branch} from ${baseRef}`);
|
|
67
|
-
this.
|
|
67
|
+
this.execGit(["-C", bareDir, "worktree", "add", "-b", branch, worktreePath, baseRef]);
|
|
68
68
|
}
|
|
69
69
|
const info = {
|
|
70
70
|
taskId,
|
|
@@ -94,7 +94,7 @@ export class WorktreeManager {
|
|
|
94
94
|
try {
|
|
95
95
|
// Remove worktree
|
|
96
96
|
if (existsSync(info.path)) {
|
|
97
|
-
this.
|
|
97
|
+
this.execGit(["-C", bareDir, "worktree", "remove", "--force", info.path]);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
catch (err) {
|
|
@@ -102,7 +102,7 @@ export class WorktreeManager {
|
|
|
102
102
|
if (existsSync(info.path)) {
|
|
103
103
|
rmSync(info.path, { recursive: true, force: true });
|
|
104
104
|
try {
|
|
105
|
-
this.
|
|
105
|
+
this.execGit(["-C", bareDir, "worktree", "prune"]);
|
|
106
106
|
}
|
|
107
107
|
catch { /* best effort */ }
|
|
108
108
|
}
|
|
@@ -110,7 +110,7 @@ export class WorktreeManager {
|
|
|
110
110
|
// Optionally delete the branch
|
|
111
111
|
if (opts?.deleteBranch) {
|
|
112
112
|
try {
|
|
113
|
-
this.
|
|
113
|
+
this.execGit(["-C", bareDir, "branch", "-D", info.branch]);
|
|
114
114
|
}
|
|
115
115
|
catch { /* branch may not exist locally */ }
|
|
116
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/worktree/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/worktree/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
vi.mock("child_process", () => ({
|
|
3
|
+
execSync: vi.fn(),
|
|
4
|
+
execFileSync: vi.fn().mockReturnValue(""),
|
|
5
|
+
}));
|
|
6
|
+
vi.mock("fs", async (importOriginal) => {
|
|
7
|
+
const actual = await importOriginal();
|
|
8
|
+
return {
|
|
9
|
+
...actual,
|
|
10
|
+
existsSync: vi.fn().mockReturnValue(false),
|
|
11
|
+
mkdirSync: vi.fn(),
|
|
12
|
+
rmSync: vi.fn(),
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
import { execSync, execFileSync } from "child_process";
|
|
16
|
+
import { existsSync, mkdirSync } from "fs";
|
|
17
|
+
import { WorktreeManager } from "./manager.js";
|
|
18
|
+
const mockExecSync = vi.mocked(execSync);
|
|
19
|
+
const mockExecFileSync = vi.mocked(execFileSync);
|
|
20
|
+
const mockExistsSync = vi.mocked(existsSync);
|
|
21
|
+
const mockMkdirSync = vi.mocked(mkdirSync);
|
|
22
|
+
describe("WorktreeManager — no shell injection via execFileSync", () => {
|
|
23
|
+
let manager;
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
vi.clearAllMocks();
|
|
26
|
+
manager = new WorktreeManager("/tmp/test-worktrees");
|
|
27
|
+
// baseDir doesn't exist → triggers mkdir and clone
|
|
28
|
+
mockExistsSync.mockReturnValue(false);
|
|
29
|
+
});
|
|
30
|
+
it("create() does not use execSync", async () => {
|
|
31
|
+
await manager.create({
|
|
32
|
+
taskId: "task-001",
|
|
33
|
+
repoUrl: "https://github.com/cliftonc/lastlight.git",
|
|
34
|
+
branch: "feature/test",
|
|
35
|
+
});
|
|
36
|
+
expect(mockExecSync).not.toHaveBeenCalled();
|
|
37
|
+
});
|
|
38
|
+
it("create() calls execFileSync with 'git' as the command", async () => {
|
|
39
|
+
await manager.create({
|
|
40
|
+
taskId: "task-002",
|
|
41
|
+
repoUrl: "https://github.com/cliftonc/lastlight.git",
|
|
42
|
+
branch: "feature/test",
|
|
43
|
+
});
|
|
44
|
+
expect(mockExecFileSync).toHaveBeenCalled();
|
|
45
|
+
for (const call of mockExecFileSync.mock.calls) {
|
|
46
|
+
expect(call[0]).toBe("git");
|
|
47
|
+
expect(Array.isArray(call[1])).toBe(true);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
it("create() uses mkdirSync instead of execSync for directory creation", async () => {
|
|
51
|
+
await manager.create({
|
|
52
|
+
taskId: "task-003",
|
|
53
|
+
repoUrl: "https://github.com/cliftonc/lastlight.git",
|
|
54
|
+
branch: "feature/test",
|
|
55
|
+
});
|
|
56
|
+
expect(mockMkdirSync).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ recursive: true }));
|
|
57
|
+
// execSync must not have been used for mkdir
|
|
58
|
+
const mkdirCalls = mockExecSync.mock.calls.filter((c) => String(c[0]).includes("mkdir"));
|
|
59
|
+
expect(mkdirCalls).toHaveLength(0);
|
|
60
|
+
});
|
|
61
|
+
it("create() passes repoUrl as a separate argument (not shell-interpolated)", async () => {
|
|
62
|
+
const repoUrl = "https://github.com/cliftonc/lastlight.git";
|
|
63
|
+
await manager.create({
|
|
64
|
+
taskId: "task-004",
|
|
65
|
+
repoUrl,
|
|
66
|
+
branch: "feature/test",
|
|
67
|
+
});
|
|
68
|
+
const cloneCall = mockExecFileSync.mock.calls.find((c) => Array.isArray(c[1]) && c[1].includes("clone"));
|
|
69
|
+
expect(cloneCall).toBeDefined();
|
|
70
|
+
const args = cloneCall[1];
|
|
71
|
+
expect(args).toContain(repoUrl);
|
|
72
|
+
});
|
|
73
|
+
it("cleanup() does not use execSync", async () => {
|
|
74
|
+
// First create so cleanup has something to work with
|
|
75
|
+
mockExistsSync.mockReturnValue(true);
|
|
76
|
+
await manager.create({
|
|
77
|
+
taskId: "task-005",
|
|
78
|
+
repoUrl: "https://github.com/cliftonc/lastlight.git",
|
|
79
|
+
branch: "feature/test",
|
|
80
|
+
});
|
|
81
|
+
vi.clearAllMocks();
|
|
82
|
+
mockExistsSync.mockReturnValue(true);
|
|
83
|
+
await manager.cleanup("task-005", { deleteBranch: true });
|
|
84
|
+
expect(mockExecSync).not.toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.test.js","sourceRoot":"","sources":["../../src/worktree/manager.test.ts"],"names":[],"mappings":"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"}
|
package/docker-compose.yml
CHANGED
|
@@ -8,11 +8,35 @@ services:
|
|
|
8
8
|
- 8.8.8.8
|
|
9
9
|
- 1.1.1.1
|
|
10
10
|
volumes:
|
|
11
|
-
|
|
11
|
+
# Single private deployment folder: overlay config.yaml + asset overrides
|
|
12
|
+
# plus a gitignored secrets/ subdir (.env, *.pem). LASTLIGHT_OVERLAY_DIR
|
|
13
|
+
# points the harness at /app/instance; the entrypoint reads secrets from
|
|
14
|
+
# /app/instance/secrets. This is the only deployment-specific input, and
|
|
15
|
+
# the harness reads it at startup — edit it and `docker compose restart
|
|
16
|
+
# agent` to apply, no image rebuild. Built-in assets (config/, workflows/,
|
|
17
|
+
# skills/, agent-context/) stay baked into the image; they're lastlight
|
|
18
|
+
# source and change via a normal rebuild.
|
|
19
|
+
- ./instance:/app/instance:ro
|
|
12
20
|
- agent-data:/app/data
|
|
13
21
|
- /var/run/docker.sock:/var/run/docker.sock # spawn sandbox containers
|
|
22
|
+
# Env comes from the consolidated overlay (instance/secrets/.env). The
|
|
23
|
+
# entrypoint also sources it inside the container; this env_file is the
|
|
24
|
+
# belt-and-suspenders copy. required: false so a fresh checkout (no
|
|
25
|
+
# instance/ yet) doesn't error. No repo-root .env is needed.
|
|
14
26
|
env_file:
|
|
15
|
-
-
|
|
27
|
+
- path: ./instance/secrets/.env
|
|
28
|
+
required: false
|
|
29
|
+
environment:
|
|
30
|
+
# V8's default old-space cap (~1.5 GB on 64-bit) is well below the 2g
|
|
31
|
+
# cgroup limit, so Node would OOM before docker did. Raise it close to
|
|
32
|
+
# the container limit so transient bursts have somewhere to land.
|
|
33
|
+
- NODE_OPTIONS=--max-old-space-size=1800
|
|
34
|
+
# Steady-state ~150 MB; bursts during webhook fan-out, the in-process
|
|
35
|
+
# chat skill (full Agent SDK), and the dispatch screening call. 2 GB
|
|
36
|
+
# gives headroom for those bursts while still preventing a runaway leak
|
|
37
|
+
# from taking the host down.
|
|
38
|
+
mem_limit: 2g
|
|
39
|
+
memswap_limit: 2g
|
|
16
40
|
networks:
|
|
17
41
|
- internal
|
|
18
42
|
|
|
@@ -25,6 +49,150 @@ services:
|
|
|
25
49
|
profiles:
|
|
26
50
|
- build-only # never started as a service, just built
|
|
27
51
|
|
|
52
|
+
# Build the enriched browser-QA sandbox image (Tier B). Separate + heavier
|
|
53
|
+
# (Playwright + a baked Chromium), built only when QA is enabled. Its FROM
|
|
54
|
+
# depends on lastlight-sandbox:latest existing first, so build in that order:
|
|
55
|
+
# docker compose --profile build-only build sandbox sandbox-qa
|
|
56
|
+
sandbox-qa:
|
|
57
|
+
build:
|
|
58
|
+
context: .
|
|
59
|
+
dockerfile: sandbox-qa.Dockerfile
|
|
60
|
+
image: lastlight-sandbox-qa:latest
|
|
61
|
+
profiles:
|
|
62
|
+
- build-only # never started as a service, just built
|
|
63
|
+
|
|
64
|
+
# ── Egress firewall (replaces the earlier tinyproxy CONNECT-proxy) ────
|
|
65
|
+
#
|
|
66
|
+
# See src/sandbox/egress-firewall-config.ts for the architecture rationale.
|
|
67
|
+
# Two pairs: (coredns-strict + nginx-egress-strict) and
|
|
68
|
+
# (coredns-open + nginx-egress-open). Sandbox containers spawn with
|
|
69
|
+
# `--dns <coredns-ip>` and dial allowlisted hosts directly — coredns
|
|
70
|
+
# resolves the hostname to the nginx IP, nginx peeks SNI and tunnels.
|
|
71
|
+
#
|
|
72
|
+
# The sandbox sees no proxy at all. Works for any SDK regardless of
|
|
73
|
+
# whether it honours HTTP(S)_PROXY env vars.
|
|
74
|
+
|
|
75
|
+
# One-shot init that writes nginx-strict.conf / nginx-open.conf /
|
|
76
|
+
# Corefile.strict / Corefile.open into the agent-data volume before
|
|
77
|
+
# coredns + nginx try to read them. Without this, the firewall
|
|
78
|
+
# services boot first, fail to find the configs, and run with empty
|
|
79
|
+
# state (returning NXDOMAIN for everything) — even after the harness
|
|
80
|
+
# later writes the files, the running processes never re-read them.
|
|
81
|
+
# `condition: service_completed_successfully` on the firewalls below
|
|
82
|
+
# makes them wait for this to exit 0.
|
|
83
|
+
egress-init:
|
|
84
|
+
image: lastlight-agent
|
|
85
|
+
restart: "no"
|
|
86
|
+
# Mounts the same overlay + secrets the agent does and runs the SAME
|
|
87
|
+
# config loader, so the collector config it pre-writes is computed from
|
|
88
|
+
# the effective config (env AND instance/config.yaml) — identical to what
|
|
89
|
+
# the harness writes at boot. This is what keeps the running collector's
|
|
90
|
+
# forwarding gate from diverging from the harness when OTEL is enabled via
|
|
91
|
+
# YAML rather than env.
|
|
92
|
+
env_file:
|
|
93
|
+
- path: ./instance/secrets/.env
|
|
94
|
+
required: false
|
|
95
|
+
volumes:
|
|
96
|
+
- ./instance:/app/instance:ro
|
|
97
|
+
- agent-data:/app/data
|
|
98
|
+
command:
|
|
99
|
+
["node", "-e",
|
|
100
|
+
"const c=require('/app/dist/config.js').loadConfig();const m=require('/app/dist/sandbox/egress-firewall-config.js');const d=c.stateDir;m.writeEgressFirewallConfigs(d);m.writeOtelCollectorConfig(d,{active:c.otel.enabled&&c.otel.forwardToSandbox})"]
|
|
101
|
+
depends_on:
|
|
102
|
+
- agent # ensures the image has been built when init runs
|
|
103
|
+
|
|
104
|
+
coredns-strict:
|
|
105
|
+
image: coredns/coredns:1.11.3
|
|
106
|
+
restart: unless-stopped
|
|
107
|
+
command: ["-conf", "/app/data/proxy/Corefile.strict"]
|
|
108
|
+
volumes:
|
|
109
|
+
- agent-data:/app/data:ro
|
|
110
|
+
depends_on:
|
|
111
|
+
egress-init:
|
|
112
|
+
condition: service_completed_successfully
|
|
113
|
+
networks:
|
|
114
|
+
sandbox-egress:
|
|
115
|
+
ipv4_address: 172.30.0.10
|
|
116
|
+
|
|
117
|
+
coredns-open:
|
|
118
|
+
image: coredns/coredns:1.11.3
|
|
119
|
+
restart: unless-stopped
|
|
120
|
+
command: ["-conf", "/app/data/proxy/Corefile.open"]
|
|
121
|
+
volumes:
|
|
122
|
+
- agent-data:/app/data:ro
|
|
123
|
+
depends_on:
|
|
124
|
+
egress-init:
|
|
125
|
+
condition: service_completed_successfully
|
|
126
|
+
networks:
|
|
127
|
+
sandbox-egress:
|
|
128
|
+
ipv4_address: 172.30.0.11
|
|
129
|
+
|
|
130
|
+
nginx-egress-strict:
|
|
131
|
+
image: nginx:alpine
|
|
132
|
+
restart: unless-stopped
|
|
133
|
+
command:
|
|
134
|
+
["nginx", "-c", "/app/data/proxy/nginx-strict.conf", "-g", "daemon off;"]
|
|
135
|
+
volumes:
|
|
136
|
+
- agent-data:/app/data:ro
|
|
137
|
+
depends_on:
|
|
138
|
+
egress-init:
|
|
139
|
+
condition: service_completed_successfully
|
|
140
|
+
# Deliberately NOT on `internal`. Splitting ingress (sandbox-egress)
|
|
141
|
+
# and egress (proxy-egress) onto separate networks that don't include
|
|
142
|
+
# harness services keeps compose-internal hostnames unresolvable to
|
|
143
|
+
# the firewall — so an `unrestricted_egress` phase can't ask nginx to
|
|
144
|
+
# tunnel to `agent:8644` or similar.
|
|
145
|
+
networks:
|
|
146
|
+
sandbox-egress:
|
|
147
|
+
ipv4_address: 172.30.0.20
|
|
148
|
+
proxy-egress: {}
|
|
149
|
+
|
|
150
|
+
nginx-egress-open:
|
|
151
|
+
image: nginx:alpine
|
|
152
|
+
restart: unless-stopped
|
|
153
|
+
command:
|
|
154
|
+
["nginx", "-c", "/app/data/proxy/nginx-open.conf", "-g", "daemon off;"]
|
|
155
|
+
volumes:
|
|
156
|
+
- agent-data:/app/data:ro
|
|
157
|
+
depends_on:
|
|
158
|
+
egress-init:
|
|
159
|
+
condition: service_completed_successfully
|
|
160
|
+
networks:
|
|
161
|
+
sandbox-egress:
|
|
162
|
+
ipv4_address: 172.30.0.21
|
|
163
|
+
proxy-egress: {}
|
|
164
|
+
|
|
165
|
+
# In-network OTEL collector. Sandboxes export telemetry here (by IP, on
|
|
166
|
+
# sandbox-egress) and it re-exports to the configured backend over
|
|
167
|
+
# proxy-egress. This is why the strict SNI firewall doesn't need to know
|
|
168
|
+
# about collector hosts or non-443 ports: the sandbox only ever dials this
|
|
169
|
+
# fixed internal endpoint, and the backend hop runs from a trusted,
|
|
170
|
+
# harness-controlled service that can use any port/scheme/headers. Backend
|
|
171
|
+
# auth headers live in the generated config (mode 0600 on the host volume)
|
|
172
|
+
# and are never forwarded into a sandbox.
|
|
173
|
+
#
|
|
174
|
+
# Dual-homed like the nginx firewalls — sandbox-egress (ingress) +
|
|
175
|
+
# proxy-egress (outbound). Deliberately NOT on `internal`, so it can't
|
|
176
|
+
# bridge a sandbox into harness services.
|
|
177
|
+
otel-collector:
|
|
178
|
+
image: otel/opentelemetry-collector:0.115.0
|
|
179
|
+
restart: unless-stopped
|
|
180
|
+
# Runs as the image's default non-root UID (10001). The harness `lastlight`
|
|
181
|
+
# user is pinned to that same UID (Dockerfile `useradd -u 10001`), so the
|
|
182
|
+
# collector reads the mode-0600 config the harness writes as its owner —
|
|
183
|
+
# no root, no world-readable secret. The image tag and that pinned UID must
|
|
184
|
+
# move together if a future image changes its user.
|
|
185
|
+
command: ["--config=/app/data/proxy/otel-collector.yaml"]
|
|
186
|
+
volumes:
|
|
187
|
+
- agent-data:/app/data:ro
|
|
188
|
+
depends_on:
|
|
189
|
+
egress-init:
|
|
190
|
+
condition: service_completed_successfully
|
|
191
|
+
networks:
|
|
192
|
+
sandbox-egress:
|
|
193
|
+
ipv4_address: 172.30.0.30
|
|
194
|
+
proxy-egress: {}
|
|
195
|
+
|
|
28
196
|
caddy:
|
|
29
197
|
image: caddy:2-alpine
|
|
30
198
|
restart: unless-stopped
|
|
@@ -35,15 +203,48 @@ services:
|
|
|
35
203
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
36
204
|
- caddy-data:/data
|
|
37
205
|
- caddy-config:/config
|
|
38
|
-
|
|
39
|
-
|
|
206
|
+
# Caddyfile uses `{$DOMAIN:localhost}` (Caddy's own env substitution), so
|
|
207
|
+
# DOMAIN just needs to be in the container env. Read it from the overlay
|
|
208
|
+
# secrets file directly — no repo-root .env / ${DOMAIN} interpolation.
|
|
209
|
+
env_file:
|
|
210
|
+
- path: ./instance/secrets/.env
|
|
211
|
+
required: false
|
|
212
|
+
# Caddy's memory footprint is tiny (typically <50 MB even under load).
|
|
213
|
+
mem_limit: 256m
|
|
214
|
+
memswap_limit: 256m
|
|
40
215
|
networks:
|
|
41
216
|
- internal
|
|
42
217
|
|
|
43
218
|
volumes:
|
|
44
|
-
agent-data: # contains: lastlight.db,
|
|
219
|
+
agent-data: # contains: lastlight.db, agent-sessions/, sandboxes/, secrets/, logs/, proxy/
|
|
220
|
+
# Shared package-manager download cache (npm/pnpm/yarn), mounted at /cache in
|
|
221
|
+
# every dynamically-created sandbox container by src/sandbox/docker.ts so
|
|
222
|
+
# repeated installs reuse already-fetched tarballs (issue #107). Declared
|
|
223
|
+
# here so the stack manages its lifecycle; the agent service does not mount
|
|
224
|
+
# it. Override the name with LASTLIGHT_PKG_CACHE_VOLUME (defaults to the
|
|
225
|
+
# compose-prefixed `lastlight_pkg-cache`).
|
|
226
|
+
pkg-cache:
|
|
45
227
|
caddy-data:
|
|
46
228
|
caddy-config:
|
|
47
229
|
|
|
48
230
|
networks:
|
|
49
231
|
internal:
|
|
232
|
+
# Sandbox containers (created dynamically by src/sandbox/docker.ts) attach
|
|
233
|
+
# to this network only with `--dns 172.30.0.10` (or .11 for open mode).
|
|
234
|
+
# `internal: true` disables direct host egress, so the only path to the
|
|
235
|
+
# public internet is through the nginx firewalls, which receive sandbox
|
|
236
|
+
# traffic on this network. Static subnet so the coredns + nginx IPs
|
|
237
|
+
# baked into the generated configs are stable.
|
|
238
|
+
sandbox-egress:
|
|
239
|
+
internal: true
|
|
240
|
+
ipam:
|
|
241
|
+
config:
|
|
242
|
+
- subnet: 172.30.0.0/24
|
|
243
|
+
# Egress-only network for the nginx firewalls. Regular bridge (has a
|
|
244
|
+
# default route to the host's network, so nginx can reach the public
|
|
245
|
+
# internet). Critically: NO other compose services attach here. That way
|
|
246
|
+
# docker's embedded DNS on this network resolves only public names — the
|
|
247
|
+
# harness service names (`agent`, `caddy`) are not reachable from the
|
|
248
|
+
# firewall's perspective, so an unrestricted sandbox can't ask nginx to
|
|
249
|
+
# bridge into the compose-internal services.
|
|
250
|
+
proxy-egress:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lastlight",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "GitHub repository maintenance agent — Agent SDK harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
+
"config",
|
|
12
13
|
"workflows",
|
|
13
14
|
"skills",
|
|
14
15
|
"agent-context",
|
|
15
|
-
"mcp-github-app/src",
|
|
16
|
-
"mcp-github-app/package.json",
|
|
17
|
-
"mcp-github-app/tsconfig.json",
|
|
18
16
|
"deploy",
|
|
19
17
|
"sandbox.Dockerfile",
|
|
20
18
|
"docker-compose.yml"
|
|
@@ -38,9 +36,9 @@
|
|
|
38
36
|
],
|
|
39
37
|
"scripts": {
|
|
40
38
|
"test": "vitest run",
|
|
41
|
-
"build": "tsc",
|
|
39
|
+
"build": "tsc && node -e \"require('fs').chmodSync('dist/cli.js', 0o755)\"",
|
|
42
40
|
"build:dashboard": "npm run build -w dashboard",
|
|
43
|
-
"build:all": "
|
|
41
|
+
"build:all": "npm run build && npm run build -w dashboard",
|
|
44
42
|
"start": "node dist/index.js",
|
|
45
43
|
"dev": "concurrently -n server,dash -c blue,magenta \"bash scripts/dev-local.sh\" \"npm run dev -w dashboard\"",
|
|
46
44
|
"dev:server": "bash scripts/dev-local.sh",
|
|
@@ -50,15 +48,27 @@
|
|
|
50
48
|
"test:watch": "vitest"
|
|
51
49
|
},
|
|
52
50
|
"dependencies": {
|
|
53
|
-
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
|
|
54
51
|
"@clack/prompts": "^1.2.0",
|
|
55
|
-
"@
|
|
52
|
+
"@earendil-works/pi-ai": "^0.79.8",
|
|
53
|
+
"@hono/node-server": "^1.19.13",
|
|
54
|
+
"@opentelemetry/api": "^1.9.1",
|
|
55
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.219.0",
|
|
56
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.219.0",
|
|
57
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
|
|
58
|
+
"@opentelemetry/resources": "^2.8.0",
|
|
59
|
+
"@opentelemetry/sdk-logs": "^0.219.0",
|
|
60
|
+
"@opentelemetry/sdk-metrics": "^2.8.0",
|
|
61
|
+
"@opentelemetry/sdk-node": "^0.219.0",
|
|
62
|
+
"@opentelemetry/semantic-conventions": "^1.41.1",
|
|
63
|
+
"@sinclair/typebox": "^0.34.49",
|
|
56
64
|
"@slack/bolt": "^4.6.0",
|
|
65
|
+
"agentic-pi": "^0.2.7",
|
|
57
66
|
"arctic": "^3.7.0",
|
|
58
67
|
"better-sqlite3": "^11.0.0",
|
|
59
68
|
"chalk": "^5.6.2",
|
|
69
|
+
"cli-table3": "^0.6.5",
|
|
60
70
|
"croner": "^9.0.0",
|
|
61
|
-
"hono": "^4.
|
|
71
|
+
"hono": "^4.12.14",
|
|
62
72
|
"octokit": "^5.0.5",
|
|
63
73
|
"yaml": "^2.8.3",
|
|
64
74
|
"zod": "^4.3.6"
|