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.
- package/README.md +71 -692
- package/dist/cli-config.js.map +1 -0
- package/dist/cli-format.js.map +1 -0
- package/dist/{cli/cli-server.d.ts → cli-server.d.ts} +39 -1
- package/dist/{cli/cli-server.js → cli-server.js} +105 -5
- package/dist/cli-server.js.map +1 -0
- package/dist/cli-timeline.js.map +1 -0
- package/dist/{cli/cli.js → cli.js} +9 -7
- package/dist/cli.js.map +1 -0
- package/dist/{cli/fork-cli.d.ts → fork-cli.d.ts} +3 -3
- package/dist/{cli/fork-cli.js → fork-cli.js} +28 -27
- package/dist/fork-cli.js.map +1 -0
- package/dist/{cli/oauth-cli.js → oauth-cli.js} +1 -1
- package/dist/oauth-cli.js.map +1 -0
- package/dist/{cli/setup.js → setup.js} +10 -4
- package/dist/setup.js.map +1 -0
- package/dist/{cli/skills-install.d.ts → skills-install.d.ts} +6 -0
- package/dist/{cli/skills-install.js → skills-install.js} +6 -2
- package/dist/skills-install.js.map +1 -0
- package/package.json +20 -65
- package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
- package/agent-context/rules.md +0 -80
- package/agent-context/security.md +0 -69
- package/agent-context/soul.md +0 -21
- package/config/default.yaml +0 -119
- package/deploy/.env.production.example +0 -100
- package/deploy/entrypoint.sh +0 -82
- package/deploy/native/README.md +0 -160
- package/deploy/native/install.sh +0 -110
- package/deploy/native/lastlight.env.example +0 -95
- package/deploy/native/lastlight.service +0 -50
- package/deploy/sandbox-entrypoint.sh +0 -93
- package/dist/admin/auth.d.ts +0 -51
- package/dist/admin/auth.js +0 -121
- package/dist/admin/auth.js.map +0 -1
- package/dist/admin/chat-session-reader.d.ts +0 -39
- package/dist/admin/chat-session-reader.js +0 -84
- package/dist/admin/chat-session-reader.js.map +0 -1
- package/dist/admin/docker.d.ts +0 -61
- package/dist/admin/docker.js +0 -187
- package/dist/admin/docker.js.map +0 -1
- package/dist/admin/index.d.ts +0 -9
- package/dist/admin/index.js +0 -59
- package/dist/admin/index.js.map +0 -1
- package/dist/admin/routes.d.ts +0 -81
- package/dist/admin/routes.js +0 -1381
- package/dist/admin/routes.js.map +0 -1
- package/dist/admin/sessions.d.ts +0 -89
- package/dist/admin/sessions.js +0 -204
- package/dist/admin/sessions.js.map +0 -1
- package/dist/admin/tail.d.ts +0 -12
- package/dist/admin/tail.js +0 -145
- package/dist/admin/tail.js.map +0 -1
- package/dist/admin/version.d.ts +0 -22
- package/dist/admin/version.js +0 -92
- package/dist/admin/version.js.map +0 -1
- package/dist/cli/cli-config.js.map +0 -1
- package/dist/cli/cli-format.js.map +0 -1
- package/dist/cli/cli-server.js.map +0 -1
- package/dist/cli/cli-timeline.js.map +0 -1
- package/dist/cli/cli.js.map +0 -1
- package/dist/cli/fork-cli.js.map +0 -1
- package/dist/cli/oauth-cli.js.map +0 -1
- package/dist/cli/setup.js.map +0 -1
- package/dist/cli/skills-install.js.map +0 -1
- package/dist/config/config-resolve.d.ts +0 -28
- package/dist/config/config-resolve.js +0 -47
- package/dist/config/config-resolve.js.map +0 -1
- package/dist/config/config.d.ts +0 -157
- package/dist/config/config.js +0 -581
- package/dist/config/config.js.map +0 -1
- package/dist/config/core-pin.d.ts +0 -16
- package/dist/config/core-pin.js +0 -85
- package/dist/config/core-pin.js.map +0 -1
- package/dist/config/overlay-assets.d.ts +0 -20
- package/dist/config/overlay-assets.js +0 -114
- package/dist/config/overlay-assets.js.map +0 -1
- package/dist/config/overlay-bootstrap.d.ts +0 -44
- package/dist/config/overlay-bootstrap.js +0 -304
- package/dist/config/overlay-bootstrap.js.map +0 -1
- package/dist/connectors/github-webhook.d.ts +0 -45
- package/dist/connectors/github-webhook.js +0 -321
- package/dist/connectors/github-webhook.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -18
- package/dist/connectors/index.js +0 -41
- package/dist/connectors/index.js.map +0 -1
- package/dist/connectors/messaging/base.d.ts +0 -42
- package/dist/connectors/messaging/base.js +0 -139
- package/dist/connectors/messaging/base.js.map +0 -1
- package/dist/connectors/messaging/delivery.d.ts +0 -14
- package/dist/connectors/messaging/delivery.js +0 -38
- package/dist/connectors/messaging/delivery.js.map +0 -1
- package/dist/connectors/messaging/index.d.ts +0 -4
- package/dist/connectors/messaging/index.js +0 -4
- package/dist/connectors/messaging/index.js.map +0 -1
- package/dist/connectors/messaging/session-manager.d.ts +0 -53
- package/dist/connectors/messaging/session-manager.js +0 -255
- package/dist/connectors/messaging/session-manager.js.map +0 -1
- package/dist/connectors/messaging/types.d.ts +0 -58
- package/dist/connectors/messaging/types.js +0 -7
- package/dist/connectors/messaging/types.js.map +0 -1
- package/dist/connectors/slack/connector.d.ts +0 -142
- package/dist/connectors/slack/connector.js +0 -494
- package/dist/connectors/slack/connector.js.map +0 -1
- package/dist/connectors/slack/index.d.ts +0 -2
- package/dist/connectors/slack/index.js +0 -3
- package/dist/connectors/slack/index.js.map +0 -1
- package/dist/connectors/slack/mrkdwn.d.ts +0 -19
- package/dist/connectors/slack/mrkdwn.js +0 -240
- package/dist/connectors/slack/mrkdwn.js.map +0 -1
- package/dist/connectors/types.d.ts +0 -61
- package/dist/connectors/types.js +0 -2
- package/dist/connectors/types.js.map +0 -1
- package/dist/cron/fanout.d.ts +0 -33
- package/dist/cron/fanout.js +0 -55
- package/dist/cron/fanout.js.map +0 -1
- package/dist/cron/jobs.d.ts +0 -18
- package/dist/cron/jobs.js +0 -37
- package/dist/cron/jobs.js.map +0 -1
- package/dist/cron/scheduler.d.ts +0 -45
- package/dist/cron/scheduler.js +0 -105
- package/dist/cron/scheduler.js.map +0 -1
- package/dist/engine/agent-executor.d.ts +0 -34
- package/dist/engine/agent-executor.js +0 -246
- package/dist/engine/agent-executor.js.map +0 -1
- package/dist/engine/chat/chat-runner.d.ts +0 -132
- package/dist/engine/chat/chat-runner.js +0 -424
- package/dist/engine/chat/chat-runner.js.map +0 -1
- package/dist/engine/chat/chat-skills.d.ts +0 -45
- package/dist/engine/chat/chat-skills.js +0 -184
- package/dist/engine/chat/chat-skills.js.map +0 -1
- package/dist/engine/chat/chat.d.ts +0 -54
- package/dist/engine/chat/chat.js +0 -316
- package/dist/engine/chat/chat.js.map +0 -1
- package/dist/engine/chat/message-batcher.d.ts +0 -32
- package/dist/engine/chat/message-batcher.js +0 -109
- package/dist/engine/chat/message-batcher.js.map +0 -1
- package/dist/engine/dispatcher.d.ts +0 -73
- package/dist/engine/dispatcher.js +0 -663
- package/dist/engine/dispatcher.js.map +0 -1
- package/dist/engine/event-shim.d.ts +0 -117
- package/dist/engine/event-shim.js +0 -435
- package/dist/engine/event-shim.js.map +0 -1
- package/dist/engine/executors/orchestrator.d.ts +0 -81
- package/dist/engine/executors/orchestrator.js +0 -365
- package/dist/engine/executors/orchestrator.js.map +0 -1
- package/dist/engine/executors/shared.d.ts +0 -189
- package/dist/engine/executors/shared.js +0 -616
- package/dist/engine/executors/shared.js.map +0 -1
- package/dist/engine/github/git-auth.d.ts +0 -62
- package/dist/engine/github/git-auth.js +0 -161
- package/dist/engine/github/git-auth.js.map +0 -1
- package/dist/engine/github/github-app-client.d.ts +0 -23
- package/dist/engine/github/github-app-client.js +0 -33
- package/dist/engine/github/github-app-client.js.map +0 -1
- package/dist/engine/github/github-tools.d.ts +0 -18
- package/dist/engine/github/github-tools.js +0 -263
- package/dist/engine/github/github-tools.js.map +0 -1
- package/dist/engine/github/github.d.ts +0 -1193
- package/dist/engine/github/github.js +0 -357
- package/dist/engine/github/github.js.map +0 -1
- package/dist/engine/github/profiles.d.ts +0 -279
- package/dist/engine/github/profiles.js +0 -42
- package/dist/engine/github/profiles.js.map +0 -1
- package/dist/engine/github/review-poster.d.ts +0 -98
- package/dist/engine/github/review-poster.js +0 -177
- package/dist/engine/github/review-poster.js.map +0 -1
- package/dist/engine/llm.d.ts +0 -79
- package/dist/engine/llm.js +0 -269
- package/dist/engine/llm.js.map +0 -1
- package/dist/engine/oauth.d.ts +0 -43
- package/dist/engine/oauth.js +0 -103
- package/dist/engine/oauth.js.map +0 -1
- package/dist/engine/router.d.ts +0 -29
- package/dist/engine/router.js +0 -680
- package/dist/engine/router.js.map +0 -1
- package/dist/engine/screen/classifier.d.ts +0 -93
- package/dist/engine/screen/classifier.js +0 -215
- package/dist/engine/screen/classifier.js.map +0 -1
- package/dist/engine/screen/screen.d.ts +0 -41
- package/dist/engine/screen/screen.js +0 -93
- package/dist/engine/screen/screen.js.map +0 -1
- package/dist/evals-api.d.ts +0 -24
- package/dist/evals-api.js +0 -22
- package/dist/evals-api.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -940
- package/dist/index.js.map +0 -1
- package/dist/managed-repos.d.ts +0 -30
- package/dist/managed-repos.js +0 -72
- package/dist/managed-repos.js.map +0 -1
- package/dist/notify/blocks.d.ts +0 -23
- package/dist/notify/blocks.js +0 -118
- package/dist/notify/blocks.js.map +0 -1
- package/dist/notify/index.d.ts +0 -17
- package/dist/notify/index.js +0 -7
- package/dist/notify/index.js.map +0 -1
- package/dist/notify/model.d.ts +0 -57
- package/dist/notify/model.js +0 -89
- package/dist/notify/model.js.map +0 -1
- package/dist/notify/notifier.d.ts +0 -18
- package/dist/notify/notifier.js +0 -100
- package/dist/notify/notifier.js.map +0 -1
- package/dist/notify/render.d.ts +0 -21
- package/dist/notify/render.js +0 -59
- package/dist/notify/render.js.map +0 -1
- package/dist/notify/transports/github.d.ts +0 -26
- package/dist/notify/transports/github.js +0 -27
- package/dist/notify/transports/github.js.map +0 -1
- package/dist/notify/transports/slack.d.ts +0 -27
- package/dist/notify/transports/slack.js +0 -37
- package/dist/notify/transports/slack.js.map +0 -1
- package/dist/notify/types.d.ts +0 -119
- package/dist/notify/types.js +0 -16
- package/dist/notify/types.js.map +0 -1
- package/dist/providers.d.ts +0 -125
- package/dist/providers.js +0 -279
- package/dist/providers.js.map +0 -1
- package/dist/sandbox/docker.d.ts +0 -180
- package/dist/sandbox/docker.js +0 -517
- package/dist/sandbox/docker.js.map +0 -1
- package/dist/sandbox/egress-allowlist.d.ts +0 -74
- package/dist/sandbox/egress-allowlist.js +0 -164
- package/dist/sandbox/egress-allowlist.js.map +0 -1
- package/dist/sandbox/egress-firewall-config.d.ts +0 -127
- package/dist/sandbox/egress-firewall-config.js +0 -434
- package/dist/sandbox/egress-firewall-config.js.map +0 -1
- package/dist/sandbox/images.d.ts +0 -23
- package/dist/sandbox/images.js +0 -55
- package/dist/sandbox/images.js.map +0 -1
- package/dist/sandbox/index.d.ts +0 -112
- package/dist/sandbox/index.js +0 -332
- package/dist/sandbox/index.js.map +0 -1
- package/dist/sandbox/sandbox.d.ts +0 -214
- package/dist/sandbox/sandbox.js +0 -453
- package/dist/sandbox/sandbox.js.map +0 -1
- package/dist/sandbox/smol.d.ts +0 -162
- package/dist/sandbox/smol.js +0 -485
- package/dist/sandbox/smol.js.map +0 -1
- package/dist/session-log.d.ts +0 -63
- package/dist/session-log.js +0 -290
- package/dist/session-log.js.map +0 -1
- package/dist/state/approval-store.d.ts +0 -88
- package/dist/state/approval-store.js +0 -149
- package/dist/state/approval-store.js.map +0 -1
- package/dist/state/build-assets.d.ts +0 -50
- package/dist/state/build-assets.js +0 -154
- package/dist/state/build-assets.js.map +0 -1
- package/dist/state/db.d.ts +0 -81
- package/dist/state/db.js +0 -155
- package/dist/state/db.js.map +0 -1
- package/dist/state/execution-store.d.ts +0 -257
- package/dist/state/execution-store.js +0 -527
- package/dist/state/execution-store.js.map +0 -1
- package/dist/state/migrate.d.ts +0 -15
- package/dist/state/migrate.js +0 -175
- package/dist/state/migrate.js.map +0 -1
- package/dist/state/workflow-run-store.d.ts +0 -216
- package/dist/state/workflow-run-store.js +0 -403
- package/dist/state/workflow-run-store.js.map +0 -1
- package/dist/telemetry/index.d.ts +0 -38
- package/dist/telemetry/index.js +0 -253
- package/dist/telemetry/index.js.map +0 -1
- package/dist/telemetry/pi-events.d.ts +0 -12
- package/dist/telemetry/pi-events.js +0 -134
- package/dist/telemetry/pi-events.js.map +0 -1
- package/dist/workflows/dag.d.ts +0 -37
- package/dist/workflows/dag.js +0 -118
- package/dist/workflows/dag.js.map +0 -1
- package/dist/workflows/loader.d.ts +0 -53
- package/dist/workflows/loader.js +0 -421
- package/dist/workflows/loader.js.map +0 -1
- package/dist/workflows/loop-eval.d.ts +0 -28
- package/dist/workflows/loop-eval.js +0 -74
- package/dist/workflows/loop-eval.js.map +0 -1
- package/dist/workflows/phase-executor.d.ts +0 -222
- package/dist/workflows/phase-executor.js +0 -1153
- package/dist/workflows/phase-executor.js.map +0 -1
- package/dist/workflows/phase-ref.d.ts +0 -50
- package/dist/workflows/phase-ref.js +0 -91
- package/dist/workflows/phase-ref.js.map +0 -1
- package/dist/workflows/resume.d.ts +0 -58
- package/dist/workflows/resume.js +0 -313
- package/dist/workflows/resume.js.map +0 -1
- package/dist/workflows/runner.d.ts +0 -63
- package/dist/workflows/runner.js +0 -381
- package/dist/workflows/runner.js.map +0 -1
- package/dist/workflows/schema.d.ts +0 -344
- package/dist/workflows/schema.js +0 -460
- package/dist/workflows/schema.js.map +0 -1
- package/dist/workflows/simple.d.ts +0 -90
- package/dist/workflows/simple.js +0 -393
- package/dist/workflows/simple.js.map +0 -1
- package/dist/workflows/target-policy.d.ts +0 -74
- package/dist/workflows/target-policy.js +0 -80
- package/dist/workflows/target-policy.js.map +0 -1
- package/dist/workflows/templates.d.ts +0 -88
- package/dist/workflows/templates.js +0 -127
- package/dist/workflows/templates.js.map +0 -1
- package/dist/workflows/triggers.d.ts +0 -21
- package/dist/workflows/triggers.js +0 -45
- package/dist/workflows/triggers.js.map +0 -1
- package/dist/workflows/verdict.d.ts +0 -19
- package/dist/workflows/verdict.js +0 -30
- package/dist/workflows/verdict.js.map +0 -1
- package/dist/worktree/manager.d.ts +0 -43
- package/dist/worktree/manager.js +0 -127
- package/dist/worktree/manager.js.map +0 -1
- package/docker-compose.yml +0 -274
- package/sandbox.Dockerfile +0 -68
- package/skills/README.md +0 -42
- package/skills/browser-qa/SKILL.md +0 -208
- package/skills/browser-qa/scripts/agent-browser.mjs +0 -531
- package/skills/building/SKILL.md +0 -95
- package/skills/chat/SKILL.md +0 -36
- package/skills/code-review/SKILL.md +0 -82
- package/skills/debug-production/SKILL.md +0 -108
- package/skills/demo/SKILL.md +0 -228
- package/skills/demo/scripts/compose-demo.sh +0 -243
- package/skills/issue-answer/SKILL.md +0 -91
- package/skills/issue-comment/SKILL.md +0 -49
- package/skills/issue-triage/SKILL.md +0 -149
- package/skills/issue-triage/references/AGENT-BRIEF.md +0 -65
- package/skills/pr-comment/SKILL.md +0 -64
- package/skills/pr-review/SKILL.md +0 -148
- package/skills/pr-review/references/findings-schema.md +0 -89
- package/skills/qa-test/SKILL.md +0 -97
- package/skills/repo-health/SKILL.md +0 -67
- package/skills/security-feedback/SKILL.md +0 -173
- package/skills/security-feedback/references/templates.md +0 -77
- package/skills/security-review/SKILL.md +0 -215
- package/skills/security-review/references/issue-format.md +0 -302
- package/skills/verify/SKILL.md +0 -118
- package/workflows/answer.yaml +0 -44
- package/workflows/build.yaml +0 -129
- package/workflows/cron-health.yaml +0 -6
- package/workflows/cron-review.yaml +0 -8
- package/workflows/cron-security.yaml +0 -6
- package/workflows/cron-triage.yaml +0 -8
- package/workflows/demo.yaml +0 -62
- package/workflows/examples/bash-smoke.yaml +0 -41
- package/workflows/examples/parallel-review.yaml +0 -36
- package/workflows/examples/tdd-loop.yaml +0 -17
- package/workflows/explore.yaml +0 -80
- package/workflows/issue-comment.yaml +0 -15
- package/workflows/issue-triage.yaml +0 -22
- package/workflows/pr-comment.yaml +0 -16
- package/workflows/pr-fix.yaml +0 -17
- package/workflows/pr-review.yaml +0 -50
- package/workflows/prompts/answer.md +0 -68
- package/workflows/prompts/architect.md +0 -44
- package/workflows/prompts/classifier.md +0 -60
- package/workflows/prompts/classify-adds-info.md +0 -17
- package/workflows/prompts/demo.md +0 -125
- package/workflows/prompts/executor.md +0 -42
- package/workflows/prompts/explore-ask.md +0 -99
- package/workflows/prompts/explore-publish.md +0 -31
- package/workflows/prompts/explore-read.md +0 -120
- package/workflows/prompts/explore-synthesize.md +0 -88
- package/workflows/prompts/fix.md +0 -18
- package/workflows/prompts/guardrails.md +0 -96
- package/workflows/prompts/pr-fix.md +0 -26
- package/workflows/prompts/pr.md +0 -39
- package/workflows/prompts/qa-browser.md +0 -95
- package/workflows/prompts/qa-synth.md +0 -44
- package/workflows/prompts/qa-test.md +0 -60
- package/workflows/prompts/re-reviewer.md +0 -33
- package/workflows/prompts/reviewer.md +0 -60
- package/workflows/prompts/verify-browser.md +0 -93
- package/workflows/prompts/verify-synth.md +0 -44
- package/workflows/prompts/verify.md +0 -63
- package/workflows/qa-test.yaml +0 -94
- package/workflows/repo-health.yaml +0 -15
- package/workflows/security-feedback.yaml +0 -25
- package/workflows/security-review.yaml +0 -37
- package/workflows/verify.yaml +0 -93
- /package/dist/{cli/cli-config.d.ts → cli-config.d.ts} +0 -0
- /package/dist/{cli/cli-config.js → cli-config.js} +0 -0
- /package/dist/{cli/cli-format.d.ts → cli-format.d.ts} +0 -0
- /package/dist/{cli/cli-format.js → cli-format.js} +0 -0
- /package/dist/{cli/cli-timeline.d.ts → cli-timeline.d.ts} +0 -0
- /package/dist/{cli/cli-timeline.js → cli-timeline.js} +0 -0
- /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
- /package/dist/{cli/oauth-cli.d.ts → oauth-cli.d.ts} +0 -0
- /package/dist/{cli/setup.d.ts → setup.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,731 +1,110 @@
|
|
|
1
|
-
|
|
2
|
-
<img src="transparent_clean.png" alt="Last Light" width="200" />
|
|
3
|
-
</p>
|
|
1
|
+
# lastlight
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
The command-line interface for [**Last Light**](https://lastlight.dev) — an AI
|
|
4
|
+
agent that triages, reviews, and fixes your GitHub repos.
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
<strong>GitHub Repository Maintenance Agent</strong><br/>
|
|
9
|
-
<a href="https://lastlight.dev">lastlight.dev</a> · <a href="https://github.com/users/cliftonc/projects/4">Roadmap</a>
|
|
10
|
-
</p>
|
|
6
|
+
`lastlight` is a **lean global CLI**. It does three things:
|
|
11
7
|
|
|
12
|
-
|
|
8
|
+
1. **A thin client** to a running Last Light server — it POSTs triggers and
|
|
9
|
+
reads the instance's admin API over HTTP. It does not run the agent itself.
|
|
10
|
+
2. **Host-local `server` lifecycle** commands — scaffold, build, start, update,
|
|
11
|
+
and inspect the Docker Compose stack on the machine that hosts an instance.
|
|
12
|
+
3. **The Claude Code plugin installer** — install the bundled Last Light skills
|
|
13
|
+
into a local Claude Code (`lastlight skills install`).
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
The heavy runtime (the harness, workflow engine, sandbox stack) lives in the
|
|
16
|
+
`lastlight-core` package; this CLI stays lean and has no native dependencies,
|
|
17
|
+
so `npm i -g lastlight` is fast.
|
|
15
18
|
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
The fastest way to go from a bare server to a running Last Light instance:
|
|
19
|
+
## Install
|
|
19
20
|
|
|
20
21
|
```bash
|
|
21
|
-
|
|
22
|
+
npm i -g lastlight
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
1. **GitHub App** — enter your App ID, Installation ID, and PEM key path
|
|
27
|
-
2. **Domain & TLS** — optional Caddy config for automatic HTTPS
|
|
28
|
-
3. **Managed repositories** — the `owner/repo` list the bot operates on
|
|
29
|
-
4. **Model provider + API key** — pick from any of pi-ai's 15+ supported
|
|
30
|
-
providers (Anthropic, OpenAI, Google Gemini, Mistral, Groq, Cerebras, xAI,
|
|
31
|
-
Hugging Face, Moonshot, NVIDIA, Fireworks, Together, DeepSeek, Z.AI,
|
|
32
|
-
Kimi for Coding, MiniMax, OpenRouter), then enter the model id and the
|
|
33
|
-
matching API key. See `src/providers.ts` for the full registry.
|
|
34
|
-
5. **Webhook secret** — auto-generated if you don't have one
|
|
35
|
-
6. **Slack** — optional bot token and app token for Slack integration
|
|
36
|
-
7. **Admin dashboard** — optional password protection
|
|
37
|
-
|
|
38
|
-
It scaffolds your private **deployment overlay** at `instance/` — writing
|
|
39
|
-
`instance/config.yaml` (your managed repos), `instance/secrets/.env`, and copying
|
|
40
|
-
your PEM to `instance/secrets/app.pem` (mode 600) — then offers to build and start
|
|
41
|
-
the Docker stack. When it's done you have a running instance ready to receive
|
|
42
|
-
webhooks. Everything deployment-specific lives in `instance/`, which is mounted
|
|
43
|
-
read-only and never baked into the image; edit it and `docker compose restart agent`
|
|
44
|
-
to apply (no rebuild). See [Deployment overlay](#deployment-overlay) for the model.
|
|
45
|
-
|
|
46
|
-
> **Requires:** Node.js 20+, Docker, and a GitHub App already created
|
|
47
|
-
> (see [Create a GitHub App](#1-create-a-github-app) below).
|
|
48
|
-
|
|
49
|
-
For a Docker-free production install (systemd unit, gondolin sandbox), see [Native deploy](#native-systemd-deploy) below.
|
|
50
|
-
|
|
51
|
-
---
|
|
25
|
+
## Connect to an instance
|
|
52
26
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- Node.js 20+
|
|
58
|
-
- Docker Desktop (or compatible) — only needed for `LASTLIGHT_SANDBOX=docker`; gondolin runs without it on macOS/Linux
|
|
59
|
-
- A GitHub App (see [Create a GitHub App](#1-create-a-github-app) below)
|
|
60
|
-
- An API key for whichever provider your chosen `LASTLIGHT_MODEL` uses.
|
|
61
|
-
The wizard surfaces pi-ai's 15+ providers — see `src/providers.ts` for the
|
|
62
|
-
full registry (e.g. `ANTHROPIC_API_KEY` for anthropic/…, `OPENAI_API_KEY`
|
|
63
|
-
for openai/…, `GROQ_API_KEY` for groq/…, `GEMINI_API_KEY` for google/…,
|
|
64
|
-
`OPENROUTER_API_KEY` for the openrouter/… aggregator).
|
|
65
|
-
|
|
66
|
-
### Setup
|
|
27
|
+
The target instance URL + token resolve from `--url` / `--token` flags →
|
|
28
|
+
`LASTLIGHT_URL` / `LASTLIGHT_TOKEN` env → `~/.lastlight/config.json` (written by
|
|
29
|
+
`login`) → `http://localhost:8644`.
|
|
67
30
|
|
|
68
31
|
```bash
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
32
|
+
lastlight login [url] # browser hand-off auth, saves the token to ~/.lastlight
|
|
33
|
+
lastlight login <url> --password # headless fallback (POST /admin/api/login)
|
|
34
|
+
lastlight logout # forget the saved instance + token
|
|
35
|
+
lastlight status # instance URL, server health, token validity
|
|
36
|
+
lastlight setup # first-run wizard (client login or server stack)
|
|
72
37
|
```
|
|
73
38
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
cp .env.example .env
|
|
78
|
-
```
|
|
39
|
+
## Trigger work
|
|
79
40
|
|
|
80
|
-
|
|
41
|
+
Point the bot at an issue, PR, or repo. These POST `/api/run` / `/api/build` on
|
|
42
|
+
the connected instance.
|
|
81
43
|
|
|
82
44
|
```bash
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# Model + provider — the wizard surfaces pi-ai's 15+ providers. The
|
|
92
|
-
# registry lives in src/providers.ts; pick any `provider/model` it lists.
|
|
93
|
-
LASTLIGHT_MODEL=anthropic/claude-sonnet-4-6
|
|
94
|
-
ANTHROPIC_API_KEY=sk-ant-...
|
|
95
|
-
# OPENAI_API_KEY=sk-...
|
|
96
|
-
# OPENROUTER_API_KEY=sk-or-...
|
|
97
|
-
# GROQ_API_KEY=gsk_... GEMINI_API_KEY=AIza... HF_TOKEN=hf_...
|
|
98
|
-
# XAI_API_KEY=...
|
|
99
|
-
# ZAI_API_KEY=... MISTRAL_API_KEY=... FIREWORKS_API_KEY=...
|
|
100
|
-
|
|
101
|
-
# Sandbox backend (default: gondolin; alternatives: docker, none)
|
|
102
|
-
# LASTLIGHT_SANDBOX=gondolin
|
|
45
|
+
lastlight <github-url> # default: triage the issue (cheap)
|
|
46
|
+
lastlight owner/repo#N # shorthand for the same
|
|
47
|
+
lastlight build owner/repo#N # the FULL build cycle (architect → executor → reviewer → PR)
|
|
48
|
+
lastlight triage owner/repo[#N] # repo-wide scan, or a single issue
|
|
49
|
+
lastlight review owner/repo[#N] # repo-wide PR scan, or a single PR
|
|
50
|
+
lastlight health owner/repo # repo health report
|
|
51
|
+
lastlight security owner/repo # security review
|
|
52
|
+
lastlight chat [message] # chat with the bot (REPL if no message)
|
|
103
53
|
```
|
|
104
54
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
`npm run dev` runs the harness on your host. Sandbox mode is selected by `LASTLIGHT_SANDBOX`:
|
|
108
|
-
|
|
109
|
-
- **`gondolin`** (default) — agentic-pi spawns a per-phase QEMU micro-VM in-process. Uses HVF on macOS, KVM on Linux. No Docker needed.
|
|
110
|
-
- **`docker`** — agentic-pi runs inside a per-phase sibling Docker container (the `lastlight-sandbox:latest` image). Requires Docker. Useful for prod-like smoke testing.
|
|
111
|
-
- **`none`** — agent runs in-process on your host with no isolation. Dev only — never in production.
|
|
112
|
-
|
|
113
|
-
The dev script is explicitly safe with your personal config:
|
|
114
|
-
|
|
115
|
-
| | Touched? |
|
|
116
|
-
|---|---|
|
|
117
|
-
| `~/.gitconfig` (your identity, credential helper) | ❌ skipped (`LASTLIGHT_LOCAL_DEV=1`) |
|
|
118
|
-
| `./data/agent-sessions/` | ✅ project-local; shim envelope jsonls for the dashboard live here |
|
|
119
|
-
| `./data/sandbox-data/` | ✅ project-local bind-mount when using `LASTLIGHT_SANDBOX=docker` |
|
|
120
|
-
| `./data/lastlight.db`, `./data/sandboxes/`, `./data/logs/` | ✅ project-local state, gitignored |
|
|
121
|
-
|
|
122
|
-
If you want the Docker sandbox mode locally, build the image once first:
|
|
55
|
+
## Inspect & debug (read the admin API, no SSH)
|
|
123
56
|
|
|
124
57
|
```bash
|
|
125
|
-
|
|
126
|
-
|
|
58
|
+
lastlight workflow list [--status s] [--workflow name] [--limit n]
|
|
59
|
+
lastlight workflow log <id> [--follow]
|
|
60
|
+
lastlight workflow retry <id> # re-run a failed run from the phase that failed
|
|
61
|
+
lastlight session list | log <id> [--follow]
|
|
62
|
+
lastlight logs search "<text>" [--scope errors|messages|all]
|
|
63
|
+
lastlight approvals list | approve <id> | reject <id> [--reason "..."]
|
|
64
|
+
lastlight stats [--daily n | --hourly n]
|
|
127
65
|
```
|
|
128
66
|
|
|
129
|
-
|
|
67
|
+
Most commands accept `--json` for scripting.
|
|
130
68
|
|
|
131
|
-
|
|
132
|
-
npm run dev # both server and dashboard, concurrent
|
|
133
|
-
npm run dev:server # server only
|
|
134
|
-
npm run dev:dashboard # dashboard only
|
|
135
|
-
```
|
|
69
|
+
## Server lifecycle (host-local)
|
|
136
70
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- Sets `LASTLIGHT_LOCAL_DEV=1`, `STATE_DIR=./data`, `LASTLIGHT_SESSIONS_DIR=./data/agent-sessions`
|
|
141
|
-
- Starts the harness with `tsx watch src/index.ts`
|
|
142
|
-
|
|
143
|
-
#### Triggering work via the CLI
|
|
144
|
-
|
|
145
|
-
The CLI talks to the running server — it does not execute agents directly. Start the server first, then in another terminal:
|
|
71
|
+
Run these **on the host** that runs the instance. They operate on a working
|
|
72
|
+
directory (a full checkout + `instance/` overlay) resolved from `--home` →
|
|
73
|
+
`LASTLIGHT_HOME` → `~/.lastlight` `serverHome` → `~/lastlight`.
|
|
146
74
|
|
|
147
75
|
```bash
|
|
148
|
-
#
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
# Expensive, opt-in — full Architect → Executor → Reviewer → PR cycle
|
|
157
|
-
npx tsx src/cli.ts build owner/repo#42
|
|
158
|
-
npx tsx src/cli.ts build https://github.com/owner/repo/issues/42
|
|
76
|
+
lastlight server setup # scaffold/adopt the working dir; create or clone the overlay
|
|
77
|
+
lastlight server build # build the docker images from source
|
|
78
|
+
lastlight server start | stop | restart [service]
|
|
79
|
+
lastlight server update # pull core + overlay, fetch prebuilt images, recreate, restart sidecars
|
|
80
|
+
lastlight server status # compose state + core/overlay version drift
|
|
81
|
+
lastlight server list # the lastlight-* containers
|
|
82
|
+
lastlight server logs [service] [--tail n] [--since 10m] [--follow]
|
|
159
83
|
```
|
|
160
84
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
### Authentication
|
|
164
|
-
|
|
165
|
-
pi-ai picks credentials from the provider env vars the harness forwards (the full listed set lives in `src/providers.ts` — Anthropic / OpenAI / OpenRouter / Google / Mistral / Groq / Cerebras / xAI / HuggingFace / Moonshot / NVIDIA / Fireworks / Together / DeepSeek / Z.AI / Kimi / MiniMax). The harness forwards them into each sandbox container (or VM) so workflow runs can reach the API.
|
|
166
|
-
|
|
167
|
-
#### Subscription logins (OAuth) — Codex, Claude Pro, Copilot
|
|
85
|
+
## Subscription logins (OAuth)
|
|
168
86
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
and refreshes the token for you. In this from-source checkout the CLI runs via
|
|
172
|
-
`tsx` (there's no globally-installed `lastlight` binary yet — that's what a
|
|
173
|
-
published `npm i -g lastlight` gives you):
|
|
87
|
+
Log in to ChatGPT/Codex, Claude Pro/Max, or GitHub Copilot instead of using a
|
|
88
|
+
static API key. Host-local; restart the agent to apply.
|
|
174
89
|
|
|
175
90
|
```bash
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
npx tsx src/cli/cli.ts oauth test openai-codex # verify a stored login refreshes
|
|
182
|
-
npx tsx src/cli/cli.ts oauth logout [provider] # remove one (or all)
|
|
91
|
+
lastlight oauth login [provider] # openai-codex | anthropic | github-copilot
|
|
92
|
+
lastlight oauth list # providers + login status
|
|
93
|
+
lastlight oauth status # store path + token expiry
|
|
94
|
+
lastlight oauth test <provider> # force a refresh to verify the login
|
|
95
|
+
lastlight oauth logout [provider] # remove one (or all)
|
|
183
96
|
```
|
|
184
97
|
|
|
185
|
-
|
|
186
|
-
> subcommands are identical.
|
|
187
|
-
|
|
188
|
-
Then point the model at that provider and restart the agent:
|
|
98
|
+
## Fork built-in assets & install skills
|
|
189
99
|
|
|
190
100
|
```bash
|
|
191
|
-
|
|
101
|
+
lastlight fork [workflow|agent-context [file]|classifier] # copy built-ins into the instance/ overlay
|
|
102
|
+
lastlight skills install [--scope project] [--no-marketplace] # install the Claude Code skills
|
|
103
|
+
lastlight skills list | uninstall
|
|
192
104
|
```
|
|
193
105
|
|
|
194
|
-
|
|
195
|
-
`npx @earendil-works/pi-ai login` writes; override with `LASTLIGHT_AUTH_FILE`).
|
|
196
|
-
It's **host-local** — the browser OAuth flow runs where you type the command,
|
|
197
|
-
so run it on the machine that runs the agent, then restart (`npm run dev:server`
|
|
198
|
-
from source, or `lastlight server restart agent` for the installed deploy) to
|
|
199
|
-
pick it up. Note `tsx watch` does **not** reload on `.env` changes — restart
|
|
200
|
-
after switching `LASTLIGHT_MODEL`.
|
|
201
|
-
|
|
202
|
-
**Reach differs by execution path.** The in-process **chat** path passes the
|
|
203
|
-
token as a per-call key, so all three providers work there. The **sandbox**
|
|
204
|
-
(agentic-pi workflow phases) resolves credentials from env only —
|
|
205
|
-
`ANTHROPIC_OAUTH_TOKEN` / `COPILOT_GITHUB_TOKEN` cover Anthropic and Copilot,
|
|
206
|
-
but **Codex has no env-token route and therefore can't run sandbox workflows**
|
|
207
|
-
(it's chat-only). Use an API-key provider for build/triage/review workflows if
|
|
208
|
-
you only have a Codex subscription.
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## Docker Deployment
|
|
213
|
-
|
|
214
|
-
The docker-compose stack is useful when you want a single `docker compose up -d` deploy. For gondolin (and a smaller deployment surface area), prefer the [native systemd deploy](#native-systemd-deploy) instead.
|
|
215
|
-
|
|
216
|
-
### Build and Run
|
|
217
|
-
|
|
218
|
-
Build both the harness image **and** the sandbox image. The sandbox image is what the harness spawns per phase when `LASTLIGHT_SANDBOX=docker`. The sandbox service is under the `build-only` profile so it is never started — it is only built.
|
|
219
|
-
|
|
220
|
-
```bash
|
|
221
|
-
docker compose build agent
|
|
222
|
-
docker compose --profile build-only build sandbox-base # shared base first
|
|
223
|
-
docker compose --profile build-only build sandbox
|
|
224
|
-
docker compose up -d agent
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
Set `LASTLIGHT_SANDBOX=docker` in your `.env`. (Inside the harness container, gondolin's QEMU path isn't available unless you do the nested-virt setup yourself — the docker-sandbox path is the practical default for Docker deployments.)
|
|
228
|
-
|
|
229
|
-
### Deployment overlay
|
|
230
|
-
|
|
231
|
-
Everything specific to your deployment — managed repos, model/route/approval
|
|
232
|
-
overrides, agent-context, secrets — lives in a single **`instance/`** folder
|
|
233
|
-
next to `docker-compose.yml`. It's mounted read-only at `/app/instance`
|
|
234
|
-
(`LASTLIGHT_OVERLAY_DIR=/app/instance`) and is **never committed to the public
|
|
235
|
-
repo or baked into the image**, so it's the natural home for a private config
|
|
236
|
-
repo.
|
|
237
|
-
|
|
238
|
-
```text
|
|
239
|
-
instance/
|
|
240
|
-
config.yaml # overlay config — merged over the public config/default.yaml
|
|
241
|
-
agent-context/*.md # (optional) persona/rules overrides, merged by filename
|
|
242
|
-
workflows/*.yaml # (optional) add or replace workflows by logical name
|
|
243
|
-
skills/<name>/SKILL.md # (optional) skill overrides
|
|
244
|
-
secrets/ # host-only, gitignored: .env + GitHub App *.pem
|
|
245
|
-
.env
|
|
246
|
-
app.pem
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
Both `npx lastlight setup` (the config wizard) and `lastlight server setup`
|
|
250
|
-
scaffold this for you and then offer to **version it as a private repo** —
|
|
251
|
-
`git init` + an initial commit, then `gh repo create … --private --push` when
|
|
252
|
-
the GitHub CLI is authenticated, or the exact git/GitHub commands to run by hand
|
|
253
|
-
otherwise. `server setup` also lets you point at an existing overlay repo to
|
|
254
|
-
clone instead. To do it fully by hand:
|
|
255
|
-
|
|
256
|
-
```bash
|
|
257
|
-
mkdir -p instance/secrets
|
|
258
|
-
cp deploy/.env.production.example instance/secrets/.env # then fill it in
|
|
259
|
-
cp your-app.private-key.pem instance/secrets/app.pem
|
|
260
|
-
chmod 600 instance/secrets/.env instance/secrets/app.pem
|
|
261
|
-
# instance/config.yaml — at minimum your managed repos:
|
|
262
|
-
printf 'managedRepos:\n - your-org/repo-one\n' > instance/config.yaml
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Both the `agent` and `caddy` services read `instance/secrets/.env` via
|
|
266
|
-
`env_file`, and the entrypoint also sources it inside the container — so **no
|
|
267
|
-
repo-root `.env` is needed**. Merge rules: maps (`models`, `variants`, `routes`,
|
|
268
|
-
`approval`) deep-merge over the public defaults; arrays (`managedRepos`,
|
|
269
|
-
`disabled.*`) replace; environment variables override both. Overlay files are
|
|
270
|
-
read at startup — edit and `docker compose restart agent` to apply, no rebuild.
|
|
271
|
-
The dashboard **Config** tab shows Default / Overlay / Merged (non-secret) config
|
|
272
|
-
(secret-looking keys are redacted, so a stray secret in `config.yaml` won't leak).
|
|
273
|
-
|
|
274
|
-
Startup is **fail-fast**: if `LASTLIGHT_OVERLAY_DIR` is set but the folder is
|
|
275
|
-
missing or empty (the common "forgot to populate `instance/`" case), or a cron
|
|
276
|
-
targets a missing workflow, or a phase's prompt/skill can't resolve, the harness
|
|
277
|
-
exits `78` with a clear message instead of booting a broken instance.
|
|
278
|
-
|
|
279
|
-
### Expose Webhooks
|
|
280
|
-
|
|
281
|
-
To receive GitHub webhooks, the server needs to be publicly reachable. The included Caddy config handles HTTPS — set `DOMAIN` in `instance/secrets/.env`:
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
# In instance/secrets/.env:
|
|
285
|
-
# DOMAIN=lastlight.example.com
|
|
286
|
-
|
|
287
|
-
# Start both agent and caddy
|
|
288
|
-
docker compose up -d
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Or use [ngrok](https://ngrok.com) / [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) for testing.
|
|
292
|
-
|
|
293
|
-
### State & Monitoring
|
|
294
|
-
|
|
295
|
-
All persistent state lives in a single Docker volume (`agent-data`), mounted at `/app/data`:
|
|
296
|
-
|
|
297
|
-
```
|
|
298
|
-
data/
|
|
299
|
-
lastlight.db # SQLite: executions, workflow_runs, approvals, messaging sessions
|
|
300
|
-
agent-sessions/ # Dashboard JSONL envelope store (written by event-shim.ts)
|
|
301
|
-
projects/-app/*.jsonl # Chat sessions (one per Slack thread)
|
|
302
|
-
projects/-home-agent-workspace/*.jsonl # Sandbox-mode workflow sessions
|
|
303
|
-
sandboxes/ # Cloned repos per task (gondolin or docker)
|
|
304
|
-
sandbox-data/ # Shared volume mounted into docker-mode sandboxes
|
|
305
|
-
logs/ # Structured logs
|
|
306
|
-
secrets/app.pem # GitHub App PEM (mode 600) for sandbox access
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
Mount this volume or bind-mount the directory for monitoring tools to access session logs and the execution database.
|
|
310
|
-
|
|
311
|
-
### Trigger Work via CLI
|
|
312
|
-
|
|
313
|
-
With the container running:
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
# Health check
|
|
317
|
-
curl http://localhost:8644/health
|
|
318
|
-
|
|
319
|
-
# Trigger a build cycle
|
|
320
|
-
npx tsx src/cli.ts https://github.com/owner/repo/issues/42
|
|
321
|
-
|
|
322
|
-
# Trigger triage
|
|
323
|
-
npx tsx src/cli.ts triage owner/repo
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Native (systemd) Deploy
|
|
329
|
-
|
|
330
|
-
For a Linux production host with KVM available (`/dev/kvm`), the native deploy runs the harness directly under systemd and uses gondolin for sandboxing — no Docker required.
|
|
331
|
-
|
|
332
|
-
See [deploy/native/README.md](deploy/native/README.md) for the full runbook. The short version:
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
git clone https://github.com/nearform/lastlight.git /opt/lastlight
|
|
336
|
-
cd /opt/lastlight
|
|
337
|
-
# (optional) install -m 0600 -o root /path/to/app.pem /etc/lastlight/app.pem
|
|
338
|
-
sudo bash deploy/native/install.sh # scaffolds /etc/lastlight/lastlight.env
|
|
339
|
-
sudo $EDITOR /etc/lastlight/lastlight.env # fill in secrets
|
|
340
|
-
sudo bash deploy/native/install.sh # second run: starts the service
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
Re-deploys: `git pull && sudo bash deploy/native/install.sh` (idempotent — rebuilds and restarts the service).
|
|
344
|
-
|
|
345
|
-
**Required:** the host kernel must expose `/dev/kvm` (bare-metal Linux or KVM-enabled VM). Hetzner Cloud, Cloud Run, Fly Machines (without `--vm-cpu-class shared`), and most managed container hosts do **not** expose nested virt — see `agentic-pi`'s `SPIKE-gondolin.md` for the full constraint matrix.
|
|
346
|
-
|
|
347
|
-
If KVM isn't available, fall back to the Docker deploy above with `LASTLIGHT_SANDBOX=docker`.
|
|
348
|
-
|
|
349
|
-
---
|
|
350
|
-
|
|
351
|
-
## Setup Details
|
|
352
|
-
|
|
353
|
-
### 1. Create a GitHub App
|
|
354
|
-
|
|
355
|
-
1. Go to **https://github.com/settings/apps/new**
|
|
356
|
-
2. Fill in:
|
|
357
|
-
- **Name**: your bot name (appears on comments/PRs with a `[bot]` badge)
|
|
358
|
-
- **Homepage URL**: your repo URL
|
|
359
|
-
- **Webhook URL**: `https://your-domain:8644/webhooks/github` (or leave blank for now)
|
|
360
|
-
- **Webhook Secret**: a random string (same as `WEBHOOK_SECRET` in `.env`)
|
|
361
|
-
3. Set **permissions**:
|
|
362
|
-
- **Issues**: Read & Write
|
|
363
|
-
- **Pull Requests**: Read & Write
|
|
364
|
-
- **Contents**: Read & Write
|
|
365
|
-
- **Checks**: Read & Write (post the `last-light/review` check; receive its "Re-run" requests)
|
|
366
|
-
- **Metadata**: Read
|
|
367
|
-
4. Subscribe to **events**: `Issues`, `Pull request`, `Issue comment`, `Check run`, `Check suite` (the last two enable the GitHub "Re-run checks" buttons to re-trigger a review)
|
|
368
|
-
5. Click **Create GitHub App**
|
|
369
|
-
6. Click **Generate a private key** — save the `.pem` file into the project directory
|
|
370
|
-
7. Note the **App ID** from the app settings page
|
|
371
|
-
8. Click **Install App** → install on your repos
|
|
372
|
-
9. Note the **Installation ID** from the URL: `github.com/settings/installations/{ID}`
|
|
373
|
-
|
|
374
|
-
### 2. Environment Variables
|
|
375
|
-
|
|
376
|
-
Legacy `OPENCODE_*` names are still read as fallbacks for the corresponding `LASTLIGHT_*` names, so existing `.env` files from the OpenCode era keep working.
|
|
106
|
+
## Links
|
|
377
107
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
| `GITHUB_APP_PRIVATE_KEY_PATH` | Yes | Path to `.pem` file |
|
|
382
|
-
| `GITHUB_APP_INSTALLATION_ID` | Yes | Installation ID |
|
|
383
|
-
| `WEBHOOK_SECRET` | Yes | GitHub webhook signature secret |
|
|
384
|
-
| `OPENAI_API_KEY` | One of | API key for an `openai/…` model |
|
|
385
|
-
| `ANTHROPIC_API_KEY` | One of | API key for an `anthropic/…` model |
|
|
386
|
-
| `OPENROUTER_API_KEY` | One of | API key for the `openrouter/…` aggregator |
|
|
387
|
-
| `GEMINI_API_KEY` | One of | API key for a `google/…` model |
|
|
388
|
-
| `MISTRAL_API_KEY` | One of | API key for `mistral/…` |
|
|
389
|
-
| `GROQ_API_KEY` | One of | API key for `groq/…` |
|
|
390
|
-
| `CEREBRAS_API_KEY` | One of | API key for `cerebras/…` |
|
|
391
|
-
| `XAI_API_KEY` | One of | API key for `xai/…` (Grok) |
|
|
392
|
-
| `HF_TOKEN` | One of | API key for `huggingface/…` |
|
|
393
|
-
| `MOONSHOT_API_KEY` | One of | API key for `moonshotai/…` (Kimi) |
|
|
394
|
-
| `NVIDIA_API_KEY` | One of | API key for `nvidia/…` |
|
|
395
|
-
| `FIREWORKS_API_KEY` | One of | API key for `fireworks/…` |
|
|
396
|
-
| `TOGETHER_API_KEY` | One of | API key for `together/…` |
|
|
397
|
-
| `DEEPSEEK_API_KEY` | One of | API key for `deepseek/…` |
|
|
398
|
-
| `ZAI_API_KEY` | One of | API key for `zai/…` (GLM) |
|
|
399
|
-
| `KIMI_API_KEY` | One of | API key for `kimi-coding/…` |
|
|
400
|
-
| `MINIMAX_API_KEY` | One of | API key for `minimax/…` |
|
|
401
|
-
| _… or any other `provider/model` whose key is forwarded by `src/providers.ts`_ | | The wizard surfaces the registered set; see `src/providers.ts` for the full list. |
|
|
402
|
-
| `LASTLIGHT_OVERLAY_DIR` | No | Trusted deployment overlay directory (the docker-compose stack mounts `instance/` here as `/app/instance`). Startup loads `config/default.yaml`, optional `$LASTLIGHT_OVERLAY_DIR/config.yaml`, then env overrides; overlay assets under `workflows/`, `workflows/prompts/`, `skills/`, and `agent-context/` replace built-ins. Secrets live in `$LASTLIGHT_OVERLAY_DIR/secrets/`. Restart required after changes. See [Deployment overlay](#deployment-overlay). |
|
|
403
|
-
| `LASTLIGHT_MODEL` | No | Default model (default: `anthropic/claude-sonnet-4-6`). Legacy: `OPENCODE_MODEL`. |
|
|
404
|
-
| `LASTLIGHT_MODELS` | No | Per-task model overrides as JSON, e.g. `{"chat":"openai/gpt-5.1-mini","architect":"openai/gpt-5.5"}`. Legacy: `OPENCODE_MODELS`. |
|
|
405
|
-
| `LASTLIGHT_THINKING` | No | Reasoning-effort default (`off` \| `minimal` \| `low` \| `medium` \| `high` \| `xhigh`). pi-ai translates per-provider. Legacy: `OPENCODE_VARIANT`. |
|
|
406
|
-
| `LASTLIGHT_THINKINGS` | No | Per-task thinking-level overrides as JSON, e.g. `{"architect":"high","reviewer":"high","triage":"minimal"}`. Legacy: `OPENCODE_VARIANTS`. |
|
|
407
|
-
| `LASTLIGHT_SANDBOX` | No | Workflow sandbox backend: `gondolin` (default) \| `docker` \| `none`. |
|
|
408
|
-
| `LASTLIGHT_OTEL_ENABLED` | No | Enable OpenTelemetry export (default: `false`). Standard `OTEL_*` env vars alone do not enable telemetry. |
|
|
409
|
-
| `LASTLIGHT_OTEL_SERVICE_NAME` | No | OTEL service name (default: `lastlight`; falls back to `OTEL_SERVICE_NAME`). |
|
|
410
|
-
| `LASTLIGHT_OTEL_INCLUDE_CONTENT` | No | Include prompts/message/tool-result content in telemetry (default: `false`; sensitive, use carefully). |
|
|
411
|
-
| `LASTLIGHT_OTEL_FORWARD_TO_SANDBOX` | No | Forward sandbox telemetry to the backend (default: `true`). On the `docker` backend this routes through an in-network OTEL collector; on `gondolin`/`none` it forwards allowlisted `OTEL_*` env vars directly. |
|
|
412
|
-
| `LASTLIGHT_OTEL_STRICT` | No | Throw on OTEL initialization/export setup failure instead of warn-and-continue (default: `false`). |
|
|
413
|
-
| `LASTLIGHT_OTEL_COLLECTOR_HOSTS` | No | Comma-separated collector hostnames added to the strict sandbox egress allowlist. Used only by the `gondolin` backend (the `docker` backend reaches its collector internally and ignores this). |
|
|
414
|
-
| `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_*_ENDPOINT` | No | Standard OTLP HTTP collector endpoints. Used by the harness directly, and by the in-network collector as its re-export target on the `docker` backend. |
|
|
415
|
-
| `OTEL_EXPORTER_OTLP_HEADERS`, `OTEL_EXPORTER_OTLP_*_HEADERS` | No | Standard OTLP headers; secret/env-only and never shown in public config. |
|
|
416
|
-
| `OTEL_SERVICE_NAME`, `OTEL_RESOURCE_ATTRIBUTES` | No | Standard OTEL resource configuration. |
|
|
417
|
-
| `LASTLIGHT_SESSIONS_DIR` | No | Where the dashboard reads sessions (default: `$STATE_DIR/agent-sessions`). |
|
|
418
|
-
| `PORT` / `WEBHOOK_PORT` | No | Webhook listener port (default: `8644`) |
|
|
419
|
-
| `STATE_DIR` | No | Persistent state directory (default: `./data`) |
|
|
420
|
-
| `DB_PATH` | No | SQLite path (default: `$STATE_DIR/lastlight.db`) |
|
|
421
|
-
| `MAX_TURNS` | No | Reserved (kept for API stability) |
|
|
422
|
-
| `BOT_LOGIN` | No | Bot login name for self-event filtering (default: `last-light[bot]`) |
|
|
423
|
-
| `LASTLIGHT_LOCAL_DEV` | No | Set to `1` on dev machines to skip `git config --global` writes from `git-auth.ts`. The installation token still reaches sandboxes via `GIT_TOKEN`. |
|
|
424
|
-
| `SANDBOX_DATA_VOLUME` | No | Used only when `LASTLIGHT_SANDBOX=docker`. Either a Docker named volume (default: `lastlight_agent-data`) or a host path (`/`, `./`, `../`, `~`) to bind-mount as `/data` inside each sandbox. Local dev uses `./data/sandbox-data`. |
|
|
425
|
-
|
|
426
|
-
### OpenTelemetry export
|
|
427
|
-
|
|
428
|
-
OpenTelemetry is disabled by default. Set `LASTLIGHT_OTEL_ENABLED=true` and configure standard OTEL exporter env vars such as `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_HEADERS`, and `OTEL_RESOURCE_ATTRIBUTES` to export harness spans/metrics for workflow runs, phases, agent executions, PI event streams, and chat turns.
|
|
429
|
-
|
|
430
|
-
By default Last Light exports metadata only: workflow/phase names, repo, sandbox backend, model, success/stop reason, timing, tokens, and cost. Prompt text, message content, tool arguments, and tool outputs are redacted unless `LASTLIGHT_OTEL_INCLUDE_CONTENT=true`; that opt-in can export sensitive data and should only be used with a trusted collector.
|
|
431
|
-
|
|
432
|
-
When `LASTLIGHT_OTEL_FORWARD_TO_SANDBOX=true` (default), `agentic-pi` workflow sandboxes emit their own telemetry too. How it reaches the backend depends on the sandbox backend:
|
|
433
|
-
|
|
434
|
-
- **`docker` (production):** sandboxes export OTLP to an **in-network OTEL collector** (a `otel-collector` compose service on the `sandbox-egress` network, reached by a fixed internal IP). That collector re-exports to your real backend over its own outbound network leg. This means the sandbox only ever dials one fixed internal endpoint — collectors on any port or scheme (e.g. `https://collector:4318`) work without special egress rules, and the backend endpoint and auth headers (`OTEL_EXPORTER_OTLP_HEADERS`) stay host-side and are **never** forwarded into the untrusted sandbox. The collector cannot be redirected by sandbox traffic, so it adds no SSRF/exfil surface.
|
|
435
|
-
- **`gondolin` / `none`:** `agentic-pi` runs in the harness process and already inherits the harness OTEL SDK. Allowlisted `OTEL_*` env vars are forwarded into the sandbox shell env directly; `gondolin` adds collector hosts (parsed from `OTEL_EXPORTER_OTLP_ENDPOINT`, signal-specific endpoint env vars, and `LASTLIGHT_OTEL_COLLECTOR_HOSTS`) to its egress allowlist. Private/internal metadata hosts remain blocked.
|
|
436
|
-
|
|
437
|
-
Set `LASTLIGHT_OTEL_FORWARD_TO_SANDBOX=false` to disable sandbox telemetry entirely and keep collector endpoints/headers in the harness only.
|
|
438
|
-
|
|
439
|
-
### 3. Managed Repositories
|
|
440
|
-
|
|
441
|
-
The public `config/default.yaml` ships an **empty** `managedRepos` list — set
|
|
442
|
-
yours in the overlay (`instance/config.yaml`), which replaces the list wholesale:
|
|
443
|
-
|
|
444
|
-
```yaml
|
|
445
|
-
managedRepos:
|
|
446
|
-
- your-org/repo-one
|
|
447
|
-
- your-org/repo-two
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
Webhooks for repos not in this list are filtered at the connector level; Slack/CLI
|
|
451
|
-
commands targeting unmanaged repos are rejected. Install the GitHub App on each.
|
|
452
|
-
|
|
453
|
-
### 4. Customize Behaviour
|
|
454
|
-
|
|
455
|
-
Put deployment-specific changes in your overlay (`instance/`) instead of editing
|
|
456
|
-
packaged files — that keeps your config out of the public repo and applies on a
|
|
457
|
-
restart (no rebuild). See [Deployment overlay](#deployment-overlay) for the full
|
|
458
|
-
model and layout.
|
|
459
|
-
|
|
460
|
-
```text
|
|
461
|
-
instance/
|
|
462
|
-
config.yaml # non-secret config overrides only
|
|
463
|
-
workflows/*.yaml # add/replace workflows by logical `name`
|
|
464
|
-
workflows/prompts/*.md # prompt overrides/fallbacks
|
|
465
|
-
skills/<name>/SKILL.md # skill overrides/fallbacks
|
|
466
|
-
agent-context/*.md # merged by filename; overlay replaces built-ins
|
|
467
|
-
secrets/ # host-only, gitignored: .env + *.pem
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
The dashboard Config tab shows Default / Overlay / Merged non-secret config.
|
|
471
|
-
Overlay files are read at startup only; `docker compose restart agent` after changes.
|
|
472
|
-
|
|
473
|
-
| What | Where |
|
|
474
|
-
|------|-------|
|
|
475
|
-
| Managed repos, routes, models, variants, approvals, disables | overlay `instance/config.yaml` (over `config/default.yaml`) |
|
|
476
|
-
| Bot personality & communication style | `agent-context/soul.md` or overlay `instance/agent-context/` |
|
|
477
|
-
| Operational rules, review guidelines, triage rules | `agent-context/rules.md` or overlay `instance/agent-context/` |
|
|
478
|
-
| Skill definitions | `skills/*/SKILL.md` or overlay `instance/skills/` |
|
|
479
|
-
| Workflow phases (Architect/Executor/Reviewer/PR) | `workflows/*.yaml` + `workflows/prompts/` or overlay equivalents |
|
|
480
|
-
| Cron job schedules | `workflows/cron-*.yaml` or overlay workflows |
|
|
481
|
-
|
|
482
|
-
---
|
|
483
|
-
|
|
484
|
-
## Claude Code skills
|
|
485
|
-
|
|
486
|
-
Last Light ships a [Claude Code](https://docs.claude.com/en/docs/claude-code)
|
|
487
|
-
**plugin** that teaches Claude Code how to install, configure and operate Last
|
|
488
|
-
Light for you. Install the skills, then in a Claude Code session just ask — e.g.
|
|
489
|
-
*"set up a Last Light server"*, *"connect my CLI to my server"*, *"fork the build
|
|
490
|
-
workflow into my overlay"*, or *"scaffold a Last Light evals workspace"*.
|
|
491
|
-
|
|
492
|
-
| Skill | Use it when you want to… |
|
|
493
|
-
|-------|--------------------------|
|
|
494
|
-
| `lastlight-server` | Install & configure a Last Light server (agent + docker stack). |
|
|
495
|
-
| `lastlight-client` | Point the `lastlight` CLI at a server and log in. |
|
|
496
|
-
| `lastlight-overlay` | Create a deployment overlay and fork workflows/prompts/skills/persona. |
|
|
497
|
-
| `lastlight-evals` | Scaffold & run a Last Light Evals workspace (datasets, models, comparisons). |
|
|
498
|
-
|
|
499
|
-
Install them with the CLI (version-matched to the installed `lastlight`, works
|
|
500
|
-
offline — uses the `claude` plugin marketplace when present, else copies the
|
|
501
|
-
skills into `~/.claude/skills`):
|
|
502
|
-
|
|
503
|
-
```bash
|
|
504
|
-
lastlight skills install # → ~/.claude/skills (user scope)
|
|
505
|
-
lastlight skills install --scope project # → ./.claude/skills (this repo only)
|
|
506
|
-
lastlight skills list # show bundled skills + where they're installed
|
|
507
|
-
lastlight skills uninstall
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
Or register the marketplace directly from a checkout of this repo:
|
|
511
|
-
|
|
512
|
-
```bash
|
|
513
|
-
claude plugin marketplace add ./
|
|
514
|
-
claude plugin install lastlight@lastlight-skills
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
The skills live under `plugins/lastlight/` (manifest in `.claude-plugin/`). These
|
|
518
|
-
are *Claude Code* skills — distinct from Last Light's internal sandbox skills in
|
|
519
|
-
the top-level `skills/` dir.
|
|
520
|
-
|
|
521
|
-
---
|
|
522
|
-
|
|
523
|
-
## Architecture
|
|
524
|
-
|
|
525
|
-
```
|
|
526
|
-
┌─────────────────────────────────────────┐
|
|
527
|
-
│ Connector Layer │
|
|
528
|
-
│ GitHub Webhook │ Slack Socket Mode │
|
|
529
|
-
│ ↓ │ ↓ │
|
|
530
|
-
│ Event Normalizer (EventEnvelope) │
|
|
531
|
-
└────────────────┬────────────────────────┘
|
|
532
|
-
↓
|
|
533
|
-
┌─────────────────────────────────────────┐
|
|
534
|
-
│ Core Engine │
|
|
535
|
-
│ Event Router (deterministic) │
|
|
536
|
-
│ ↓ │
|
|
537
|
-
│ Workflow Runner (YAML phases) │
|
|
538
|
-
│ - Sandbox: `agentic-pi run` per phase │
|
|
539
|
-
│ in a gondolin VM or docker container │
|
|
540
|
-
│ - Chat: in-process pi-ai loop │
|
|
541
|
-
│ one session per messaging thread │
|
|
542
|
-
│ ↓ │
|
|
543
|
-
│ Sandboxes (git clone per task) │
|
|
544
|
-
│ Cron Scheduler (health reports) │
|
|
545
|
-
│ State DB (SQLite execution log) │
|
|
546
|
-
└─────────────────────────────────────────┘
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
### How Events Flow
|
|
550
|
-
|
|
551
|
-
1. **GitHub webhook** → connector verifies signature, filters noise (bot events, edits, labels), normalizes to `EventEnvelope`
|
|
552
|
-
2. **Router** maps event type to skill deterministically (no LLM in the routing loop):
|
|
553
|
-
- `issue.opened` → `issue-triage`
|
|
554
|
-
- `pr.opened` → `pr-review`
|
|
555
|
-
- `comment.created` with `@last-light` from a maintainer → routed by intent classifier (build / explore / question / triage / review / security / verify / qa-test / demo)
|
|
556
|
-
3. **Workflow runner** loads the matching YAML, dispatches each phase to `executeAgent` (`src/engine/agent-executor.ts`, which invokes agentic-pi) or, for chat, `ChatRunner` (`src/engine/chat-runner.ts`, in-process pi-ai)
|
|
557
|
-
4. **Build workflow** runs a multi-phase cycle:
|
|
558
|
-
- Phase 1: **Architect** — read-only analysis, writes plan to `.lastlight/issue-N/architect-plan.md`
|
|
559
|
-
- Phase 2: **Executor** — TDD implementation following the plan
|
|
560
|
-
- Phase 3: **Reviewer** — independent verification (no shared context with executor)
|
|
561
|
-
- Phase 4: **Fix loop** (up to 2 cycles if reviewer requests changes)
|
|
562
|
-
- Phase 5: **Create PR**
|
|
563
|
-
|
|
564
|
-
### Cron
|
|
565
|
-
|
|
566
|
-
When webhooks are enabled, only the weekly reports (health + security) run on cron (issue/PR events arrive in real-time via webhooks). Without webhooks, triage and PR review also run on cron.
|
|
567
|
-
|
|
568
|
-
| Job | Schedule | Condition |
|
|
569
|
-
|-----|----------|-----------|
|
|
570
|
-
| Triage new issues | Every 15 min | Only without webhooks |
|
|
571
|
-
| Check PRs for review | Every 30 min | Only without webhooks |
|
|
572
|
-
| Weekly health report | Mondays 9am | Always |
|
|
573
|
-
| Weekly security scan | Mondays 10am | Always |
|
|
574
|
-
|
|
575
|
-
---
|
|
576
|
-
|
|
577
|
-
## Project Structure
|
|
578
|
-
|
|
579
|
-
```
|
|
580
|
-
lastlight/
|
|
581
|
-
src/
|
|
582
|
-
index.ts # Server entry point
|
|
583
|
-
cli.ts # CLI client (talks to server)
|
|
584
|
-
config.ts # Config loader (.env)
|
|
585
|
-
connectors/
|
|
586
|
-
types.ts # Connector + EventEnvelope interfaces
|
|
587
|
-
github-webhook.ts # GitHub webhook connector (Hono)
|
|
588
|
-
index.ts # Connector registry
|
|
589
|
-
engine/
|
|
590
|
-
router.ts # Deterministic event → skill routing
|
|
591
|
-
agent-executor.ts # Workflow phase runner: invokes agentic-pi
|
|
592
|
-
# (gondolin / docker / none backends)
|
|
593
|
-
chat-runner.ts # In-process pi-ai chat loop; one session per
|
|
594
|
-
# Slack/Discord thread, rehydrated from DB
|
|
595
|
-
chat.ts # Chat skill (delegates to ChatRunner)
|
|
596
|
-
github-tools.ts # Read-only GitHub tools surfaced to chat
|
|
597
|
-
event-shim.ts # Translates agentic-pi events → Claude-SDK
|
|
598
|
-
# envelope jsonl for the dashboard reader
|
|
599
|
-
profiles.ts # ExecutorConfig / ExecutionResult types +
|
|
600
|
-
# GITHUB_PERMISSION_PROFILES + loadAgentContext
|
|
601
|
-
llm.ts # One-shot LLM helper for screen + classifier
|
|
602
|
-
screen.ts # Prompt-injection screener
|
|
603
|
-
classifier.ts # Intent classifier (build / explore / triage / …)
|
|
604
|
-
git-auth.ts # GitHub App git credential setup
|
|
605
|
-
github.ts # Harness-side Octokit client (comments, etc.)
|
|
606
|
-
workflows/ # YAML workflow runner (see src/workflows/CLAUDE.md)
|
|
607
|
-
sandbox/ # Per-task workspace + docker-sandbox lifecycle
|
|
608
|
-
cron/
|
|
609
|
-
scheduler.ts # Cron with overlap protection
|
|
610
|
-
jobs.ts # Cron job registry
|
|
611
|
-
admin/ # Dashboard API (Hono) + session readers
|
|
612
|
-
state/
|
|
613
|
-
db.ts # SQLite execution tracking
|
|
614
|
-
|
|
615
|
-
agent-context/
|
|
616
|
-
soul.md # Bot personality, principles, communication style
|
|
617
|
-
rules.md # Operational rules, managed repos, review guidelines
|
|
618
|
-
|
|
619
|
-
skills/
|
|
620
|
-
github-orchestrator/ # Central build cycle coordinator
|
|
621
|
-
issue-triage/ # Issue labeling and triage
|
|
622
|
-
pr-review/ # Structured PR review
|
|
623
|
-
repo-health/ # Health reports
|
|
624
|
-
github/ # GitHub API workflow skills
|
|
625
|
-
software-development/ # Dev skills (architect, TDD, debugging)
|
|
626
|
-
|
|
627
|
-
workflows/ # YAML workflow definitions
|
|
628
|
-
build.yaml # Architect → Executor → Reviewer → PR
|
|
629
|
-
issue-triage.yaml # Label/triage an issue
|
|
630
|
-
issue-comment.yaml # Handle an @mention on an issue
|
|
631
|
-
pr-review.yaml # Structured PR review
|
|
632
|
-
pr-fix.yaml # Apply review feedback to a PR
|
|
633
|
-
pr-comment.yaml # Handle an @mention on a PR
|
|
634
|
-
explore.yaml # Shape an idea into a spec (web search)
|
|
635
|
-
answer.yaml # Research and answer a question
|
|
636
|
-
verify.yaml # Confirm/refute a claim by running code
|
|
637
|
-
qa-test.yaml # Browser/QA test pass
|
|
638
|
-
security-review.yaml # Security scan
|
|
639
|
-
security-feedback.yaml # Apply security review feedback
|
|
640
|
-
repo-health.yaml # Health report
|
|
641
|
-
demo.yaml # Recorded demo run
|
|
642
|
-
cron-*.yaml # Cron-kind triggers (triage, review, health, security)
|
|
643
|
-
prompts/ # Per-phase prompt templates
|
|
644
|
-
|
|
645
|
-
deploy/
|
|
646
|
-
entrypoint.sh # Docker entrypoint (harness container)
|
|
647
|
-
sandbox-entrypoint.sh # Sandbox container entrypoint (docker-sandbox mode)
|
|
648
|
-
native/ # Native (systemd) deploy artifacts
|
|
649
|
-
lastlight.service # systemd unit
|
|
650
|
-
install.sh # Idempotent provision + redeploy script
|
|
651
|
-
lastlight.env.example # Env template for /etc/lastlight/lastlight.env
|
|
652
|
-
README.md # Native-deploy operator runbook
|
|
653
|
-
Dockerfile # Harness image (test-only; prod uses native deploy)
|
|
654
|
-
sandbox.Dockerfile # Sandbox image for LASTLIGHT_SANDBOX=docker
|
|
655
|
-
docker-compose.yml
|
|
656
|
-
Caddyfile # Reverse proxy for HTTPS
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
## Troubleshooting
|
|
660
|
-
|
|
661
|
-
### `npm i -g lastlight` prints deprecation warnings
|
|
662
|
-
|
|
663
|
-
```
|
|
664
|
-
npm warn deprecated prebuild-install@7.1.3: No longer maintained …
|
|
665
|
-
npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException …
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
These are harmless **transitive** deprecations, not Last Light deps:
|
|
669
|
-
`prebuild-install` is pulled by `better-sqlite3` (its native-binary fetcher), and
|
|
670
|
-
`node-domexception` by `@google/genai`'s `node-fetch` polyfill chain. They don't
|
|
671
|
-
affect the install — the package works. A future thin-CLI package split (so a
|
|
672
|
-
CLI-only install skips the server's native/AI deps) is the only clean removal.
|
|
673
|
-
|
|
674
|
-
### Server won't start
|
|
675
|
-
|
|
676
|
-
```bash
|
|
677
|
-
# Check .env is loaded
|
|
678
|
-
npm run dev:server
|
|
679
|
-
# Look for "Required environment variable not set" errors
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
### `npm run dev` says the sandbox image is missing (docker-sandbox mode)
|
|
683
|
-
|
|
684
|
-
```bash
|
|
685
|
-
docker compose --profile build-only build sandbox-base # shared base first
|
|
686
|
-
docker compose --profile build-only build sandbox
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
### Workflow run fails with `exit 127: sh: 1: agentic-pi: not found`
|
|
690
|
-
|
|
691
|
-
The sandbox image needs `agentic-pi` baked in. Rebuild it:
|
|
692
|
-
|
|
693
|
-
```bash
|
|
694
|
-
docker compose --profile build-only build sandbox-base # shared base first
|
|
695
|
-
docker compose --profile build-only build sandbox
|
|
696
|
-
```
|
|
697
|
-
|
|
698
|
-
If you're on an old `lastlight-sandbox:latest`, this picks up the install step that the current `sandbox.Dockerfile` performs.
|
|
699
|
-
|
|
700
|
-
### Workflow hangs forever with no output (gondolin mode on a host without KVM)
|
|
701
|
-
|
|
702
|
-
Gondolin requires `/dev/kvm` on Linux or HVF on macOS. Inside a container with no nested virt, `VM.create()` succeeds but the first `vm.exec()` hangs. Symptoms: phase shows "running" indefinitely with no JSONL events after `sandbox_status`.
|
|
703
|
-
|
|
704
|
-
Either switch to `LASTLIGHT_SANDBOX=docker` (sibling containers via socket) or move the harness to a KVM-capable host. Full analysis: `agentic-pi/SPIKE-gondolin.md`.
|
|
705
|
-
|
|
706
|
-
### Agent run fails with a quota / billing error
|
|
707
|
-
|
|
708
|
-
The runtime surfaces upstream errors as `error_api` with the verbatim provider message in the executions row:
|
|
709
|
-
|
|
710
|
-
- OpenAI: "Quota exceeded. Check your plan and billing details." → top up at https://platform.openai.com/account/billing
|
|
711
|
-
- Anthropic: "Credit balance is too low" → top up at https://console.anthropic.com
|
|
712
|
-
|
|
713
|
-
### Chat replies fail with `error_error`
|
|
714
|
-
|
|
715
|
-
Check the agent logs for the underlying error — common causes:
|
|
716
|
-
|
|
717
|
-
- **Wrong key for the chat model.** `LASTLIGHT_MODELS={"chat":"anthropic/…"}` but no `ANTHROPIC_API_KEY` set. Fix the override or add the key.
|
|
718
|
-
- **Model id typo.** Watch for `[config] Model: …` in startup logs to confirm what's actually loaded.
|
|
719
|
-
|
|
720
|
-
### Webhooks not arriving
|
|
721
|
-
|
|
722
|
-
```bash
|
|
723
|
-
# Check health endpoint
|
|
724
|
-
curl http://localhost:8644/health
|
|
725
|
-
|
|
726
|
-
# Test with a fake POST (should return 401 — invalid signature)
|
|
727
|
-
curl -X POST http://localhost:8644/webhooks/github -d '{}'
|
|
728
|
-
|
|
729
|
-
# Check Docker port mapping
|
|
730
|
-
docker compose ps
|
|
731
|
-
```
|
|
108
|
+
- Website & docs: <https://lastlight.dev>
|
|
109
|
+
- Monorepo: <https://github.com/nearform/lastlight> (this package is at
|
|
110
|
+
`packages/cli/`; the harness is `lastlight-core` at `apps/server/`)
|