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
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# ── Last Light — Production Environment ──────────────────────────
|
|
2
|
-
# Copy this file to instance/secrets/.env and fill in your values, where
|
|
3
|
-
# instance/ is your private deployment overlay (a separate repo cloned next to
|
|
4
|
-
# docker-compose.yml). The whole instance/ folder is mounted read-only into the
|
|
5
|
-
# container at /app/instance; the entrypoint reads secrets from
|
|
6
|
-
# /app/instance/secrets, and both the agent and caddy services read this file
|
|
7
|
-
# via env_file. No repo-root .env is needed.
|
|
8
|
-
#
|
|
9
|
-
# Overlay config + assets (config.yaml + agent-context/ + workflows/ + skills/)
|
|
10
|
-
# are read at startup — edit and `lastlight server restart agent` to apply, no
|
|
11
|
-
# rebuild. (Removing a var here needs a recreate: `lastlight server start agent`.)
|
|
12
|
-
LASTLIGHT_OVERLAY_DIR=/app/instance
|
|
13
|
-
|
|
14
|
-
# =================================================================
|
|
15
|
-
# GITHUB APP (required)
|
|
16
|
-
# =================================================================
|
|
17
|
-
# Create a GitHub App: https://docs.github.com/en/apps/creating-github-apps
|
|
18
|
-
# Permissions: Issues (R/W), Pull Requests (R/W), Contents (R/W), Metadata (R).
|
|
19
|
-
# Subscribe to issue, issue_comment, pull_request, and pull_request_review events.
|
|
20
|
-
# Drop the App private key at instance/secrets/app.pem (the entrypoint symlinks
|
|
21
|
-
# it to /app/app.pem; GITHUB_APP_PRIVATE_KEY_PATH is resolved relative to /app).
|
|
22
|
-
|
|
23
|
-
GITHUB_APP_ID=
|
|
24
|
-
GITHUB_APP_PRIVATE_KEY_PATH=./app.pem
|
|
25
|
-
GITHUB_APP_INSTALLATION_ID=
|
|
26
|
-
|
|
27
|
-
# =================================================================
|
|
28
|
-
# WEBHOOK (required)
|
|
29
|
-
# =================================================================
|
|
30
|
-
# Must match the webhook secret configured in your GitHub App settings.
|
|
31
|
-
|
|
32
|
-
WEBHOOK_SECRET=change-me-to-a-random-string
|
|
33
|
-
|
|
34
|
-
# =================================================================
|
|
35
|
-
# MODEL + LLM PROVIDER (required — pick one provider key)
|
|
36
|
-
# =================================================================
|
|
37
|
-
# Default model for sandbox + chat. Any provider/model agentic-pi supports:
|
|
38
|
-
# anthropic/…, openai/…, openrouter/<vendor>/<model>, or any pi-ai provider
|
|
39
|
-
# (google/…, mistral/…, groq/…, cerebras/…, xai/…, huggingface/…, moonshotai/…,
|
|
40
|
-
# nvidia/…, fireworks/…, together/…, deepseek/…, zai/…, kimi-coding/…,
|
|
41
|
-
# minimax/…). See src/providers.ts for the registered set.
|
|
42
|
-
LASTLIGHT_MODEL=anthropic/claude-sonnet-4-6
|
|
43
|
-
|
|
44
|
-
# Set whichever key matches LASTLIGHT_MODEL (set more than one if per-task
|
|
45
|
-
# overrides in config.yaml route phases to different providers).
|
|
46
|
-
# ANTHROPIC_API_KEY=sk-ant-...
|
|
47
|
-
# OPENAI_API_KEY=sk-proj-...
|
|
48
|
-
# OPENROUTER_API_KEY=sk-or-...
|
|
49
|
-
# GEMINI_API_KEY=AIza... MISTRAL_API_KEY=... GROQ_API_KEY=gsk_...
|
|
50
|
-
# CEREBRAS_API_KEY=... XAI_API_KEY=... HF_TOKEN=hf_...
|
|
51
|
-
# MOONSHOT_API_KEY=... NVIDIA_API_KEY=... FIREWORKS_API_KEY=...
|
|
52
|
-
# TOGETHER_API_KEY=... DEEPSEEK_API_KEY=... ZAI_API_KEY=...
|
|
53
|
-
# KIMI_API_KEY=... MINIMAX_API_KEY=...
|
|
54
|
-
|
|
55
|
-
# =================================================================
|
|
56
|
-
# DOMAIN (for Caddy TLS)
|
|
57
|
-
# =================================================================
|
|
58
|
-
# Public hostname for automatic Let's Encrypt TLS. Leave "localhost" for local
|
|
59
|
-
# dev (HTTP only). The webhook URL is https://<DOMAIN>/webhook.
|
|
60
|
-
|
|
61
|
-
DOMAIN=localhost
|
|
62
|
-
|
|
63
|
-
# =================================================================
|
|
64
|
-
# ADMIN DASHBOARD
|
|
65
|
-
# =================================================================
|
|
66
|
-
# ADMIN_SECRET signs session tokens (required for login). ADMIN_PASSWORD enables
|
|
67
|
-
# password login; auth is also satisfied by a configured OAuth provider below.
|
|
68
|
-
|
|
69
|
-
ADMIN_SECRET=change-me-to-a-random-string
|
|
70
|
-
# ADMIN_PASSWORD=
|
|
71
|
-
|
|
72
|
-
# =================================================================
|
|
73
|
-
# OPTIONAL: SLACK
|
|
74
|
-
# =================================================================
|
|
75
|
-
# Enables the messaging connector + chat skill (and the chat server).
|
|
76
|
-
# SLACK_BOT_TOKEN=xoxb-...
|
|
77
|
-
# SLACK_APP_TOKEN=xapp-...
|
|
78
|
-
# SLACK_DELIVERY_CHANNEL= # channel id for cron reports
|
|
79
|
-
# SLACK_ALLOWED_USERS= # comma-separated user ids
|
|
80
|
-
#
|
|
81
|
-
# "Login with Slack" on the dashboard (OIDC):
|
|
82
|
-
# SLACK_OAUTH_CLIENT_ID=
|
|
83
|
-
# SLACK_OAUTH_CLIENT_SECRET=
|
|
84
|
-
# SLACK_OAUTH_REDIRECT_URI=https://<DOMAIN>/admin/api/auth/slack/callback
|
|
85
|
-
# SLACK_ALLOWED_WORKSPACE= # restrict login to one team_id / domain
|
|
86
|
-
|
|
87
|
-
# =================================================================
|
|
88
|
-
# OPTIONAL: WEB SEARCH (explore workflow only)
|
|
89
|
-
# =================================================================
|
|
90
|
-
# Set any one to enable agentic-pi's web_search / web_fetch tools for phases
|
|
91
|
-
# that opt in (Tavily > Exa > Brave). Other workflows ignore these keys.
|
|
92
|
-
# TAVILY_API_KEY=tvly-...
|
|
93
|
-
# EXA_API_KEY=...
|
|
94
|
-
# BRAVE_SEARCH_API_KEY=BSA...
|
|
95
|
-
|
|
96
|
-
# =================================================================
|
|
97
|
-
# OPTIONAL: RUNTIME
|
|
98
|
-
# =================================================================
|
|
99
|
-
# PORT=8644 # webhook listener / admin port
|
|
100
|
-
# STATE_DIR=./data # persistent state (mounted as a volume)
|
package/deploy/entrypoint.sh
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Last Light Docker entrypoint
|
|
3
|
-
# Links secrets, ensures state dirs, then starts the harness.
|
|
4
|
-
set -euo pipefail
|
|
5
|
-
|
|
6
|
-
# Secrets live in the consolidated deployment folder (instance/secrets). Fall
|
|
7
|
-
# back to the legacy standalone secrets/ mount for pre-migration deployments.
|
|
8
|
-
SECRETS="/app/instance/secrets"
|
|
9
|
-
[ -d "$SECRETS" ] || SECRETS="/app/secrets"
|
|
10
|
-
APP_DIR="/app"
|
|
11
|
-
STATE_DIR="${STATE_DIR:-/app/data}"
|
|
12
|
-
|
|
13
|
-
# Materialize secrets into the writable /app layer, owned by `lastlight` (mode
|
|
14
|
-
# 600). We COPY rather than symlink: the source lives on a read-only mount owned
|
|
15
|
-
# by whatever uid created it on the host (often 1000), while the harness runs as
|
|
16
|
-
# `lastlight` (uid-pinned 10001) via gosu below. A symlink would leave the
|
|
17
|
-
# unreadable 600 source in place and the harness would EACCES on it. root (this
|
|
18
|
-
# entrypoint, pre-gosu) bypasses the source perms to read+copy; the chown then
|
|
19
|
-
# hands the copy to lastlight. Same pattern as the PEM→state-volume copy below.
|
|
20
|
-
# rm -f first so a stale symlink from an older image isn't written through.
|
|
21
|
-
for f in .env; do
|
|
22
|
-
if [ -f "$SECRETS/$f" ]; then
|
|
23
|
-
rm -f "$APP_DIR/$f"
|
|
24
|
-
cp "$SECRETS/$f" "$APP_DIR/$f"
|
|
25
|
-
chown lastlight:lastlight "$APP_DIR/$f"
|
|
26
|
-
chmod 600 "$APP_DIR/$f"
|
|
27
|
-
echo "Copied $f from secrets volume"
|
|
28
|
-
fi
|
|
29
|
-
done
|
|
30
|
-
|
|
31
|
-
# GitHub App private key(s) — same copy+chown so the in-process Octokit (which
|
|
32
|
-
# also runs as lastlight) can read them.
|
|
33
|
-
for pem in "$SECRETS"/*.pem; do
|
|
34
|
-
if [ -f "$pem" ]; then
|
|
35
|
-
dest="$APP_DIR/$(basename "$pem")"
|
|
36
|
-
rm -f "$dest"
|
|
37
|
-
cp "$pem" "$dest"
|
|
38
|
-
chown lastlight:lastlight "$dest"
|
|
39
|
-
chmod 600 "$dest"
|
|
40
|
-
echo "Copied $(basename "$pem") from secrets volume"
|
|
41
|
-
fi
|
|
42
|
-
done
|
|
43
|
-
|
|
44
|
-
# Ensure state directory structure exists and is owned by lastlight.
|
|
45
|
-
# agent-sessions/ is where agentic-pi's event shim writes JSONL envelopes
|
|
46
|
-
# the dashboard reads (path is set by LASTLIGHT_SESSIONS_DIR).
|
|
47
|
-
mkdir -p "$STATE_DIR"/{logs,sandboxes,secrets,agent-sessions}
|
|
48
|
-
chown -R lastlight:lastlight "$STATE_DIR"
|
|
49
|
-
|
|
50
|
-
# Copy PEM to the data volume so sandbox containers can access it via shared
|
|
51
|
-
# volume (LASTLIGHT_SANDBOX=docker fallback path only — gondolin doesn't go
|
|
52
|
-
# through this). Owner is `lastlight` so the host harness (which exec's via
|
|
53
|
-
# gosu lastlight below) can read it for in-process GitHub API calls.
|
|
54
|
-
# Sandbox-entrypoint runs as root before switching to `agent`, so it can
|
|
55
|
-
# still read this 600 file and materialize an agent-readable copy when
|
|
56
|
-
# ALLOW_APP_PEM=1.
|
|
57
|
-
for pem in "$SECRETS"/*.pem; do
|
|
58
|
-
if [ -f "$pem" ]; then
|
|
59
|
-
cp "$pem" "$STATE_DIR/secrets/app.pem"
|
|
60
|
-
chown lastlight:lastlight "$STATE_DIR/secrets/app.pem"
|
|
61
|
-
chmod 600 "$STATE_DIR/secrets/app.pem"
|
|
62
|
-
echo "Copied PEM to data volume for sandbox access"
|
|
63
|
-
break
|
|
64
|
-
fi
|
|
65
|
-
done
|
|
66
|
-
|
|
67
|
-
# Source .env if available
|
|
68
|
-
if [ -f "$APP_DIR/.env" ]; then
|
|
69
|
-
set -a
|
|
70
|
-
# shellcheck disable=SC1091
|
|
71
|
-
source "$APP_DIR/.env"
|
|
72
|
-
set +a
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
# Fix Docker socket permissions — host GID may differ from container docker group
|
|
76
|
-
if [ -S /var/run/docker.sock ]; then
|
|
77
|
-
chmod 666 /var/run/docker.sock
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
echo "Starting Last Light (state: $STATE_DIR)..."
|
|
81
|
-
# Drop to non-root before exec'ing the harness.
|
|
82
|
-
exec gosu lastlight "$@"
|
package/deploy/native/README.md
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# Native deploy (systemd + gondolin)
|
|
2
|
-
|
|
3
|
-
Production deploy for `lastlight` as a systemd service on a KVM-capable
|
|
4
|
-
Linux host. Replaces the Docker compose deploy; the Dockerfiles in the
|
|
5
|
-
repo root are kept only for local prod-like smoke testing.
|
|
6
|
-
|
|
7
|
-
## Why native
|
|
8
|
-
|
|
9
|
-
`agentic-pi`'s gondolin sandbox needs `/dev/kvm`. Running lastlight inside
|
|
10
|
-
a container loses or complicates KVM access (Docker-in-Docker, nested
|
|
11
|
-
virt, capability juggling). On a bare-metal Linux box you get
|
|
12
|
-
near-native VM performance with no extra moving parts.
|
|
13
|
-
|
|
14
|
-
See `agentic-pi/SPIKE-gondolin.md` for the full analysis.
|
|
15
|
-
|
|
16
|
-
## First-time install
|
|
17
|
-
|
|
18
|
-
On the prod host as root:
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
# 1. Clone the repo to the canonical path.
|
|
22
|
-
git clone https://github.com/nearform/lastlight.git /opt/lastlight
|
|
23
|
-
cd /opt/lastlight
|
|
24
|
-
|
|
25
|
-
# 2. (Optional) Drop the GitHub App PEM in place before the install runs,
|
|
26
|
-
# so install.sh locks it down. Otherwise place it later and re-run.
|
|
27
|
-
install -m 0600 -o root /path/to/your-app.pem /etc/lastlight/app.pem
|
|
28
|
-
|
|
29
|
-
# 3. Provision system + install systemd unit.
|
|
30
|
-
sudo bash deploy/native/install.sh
|
|
31
|
-
|
|
32
|
-
# 4. install.sh scaffolds /etc/lastlight/lastlight.env from the example
|
|
33
|
-
# and refuses to (re)start the service while any CHANGE_ME placeholder
|
|
34
|
-
# remains. Edit it:
|
|
35
|
-
sudo $EDITOR /etc/lastlight/lastlight.env
|
|
36
|
-
|
|
37
|
-
# 5. Re-run install.sh to start the service.
|
|
38
|
-
sudo bash deploy/native/install.sh
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Re-deploying a code change
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
cd /opt/lastlight
|
|
45
|
-
sudo -u lastlight git pull
|
|
46
|
-
sudo bash deploy/native/install.sh # rebuilds + restarts the service
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
The existing `/home/lastlight/deploy.sh` on the prod host should be
|
|
50
|
-
replaced with the two lines above (or wrap them in a script).
|
|
51
|
-
|
|
52
|
-
## What's where
|
|
53
|
-
|
|
54
|
-
| Path | Purpose |
|
|
55
|
-
| --- | --- |
|
|
56
|
-
| `/opt/lastlight` | Source checkout. `node dist/index.js` runs from here. |
|
|
57
|
-
| `/etc/lastlight/lastlight.env` | systemd EnvironmentFile (mode 0640). Holds all secrets. |
|
|
58
|
-
| `/etc/lastlight/app.pem` | GitHub App private key (mode 0640). Optional but typical. |
|
|
59
|
-
| `/var/lib/lastlight/` | Persistent state — SQLite DB, session JSONLs, gondolin image cache. |
|
|
60
|
-
| `/var/lib/lastlight/lastlight.db` | Workflow runs, executions, messaging sessions. |
|
|
61
|
-
| `/var/lib/lastlight/agent-sessions/` | Dashboard's JSONL envelope store. |
|
|
62
|
-
| `/var/lib/lastlight/.cache/agentic-pi/images/` | Downloaded gondolin guest images (~89 MB each). |
|
|
63
|
-
| `/var/log/lastlight/` | LogsDirectory if anything writes to it. |
|
|
64
|
-
| `/etc/systemd/system/lastlight.service` | The unit file (installed by install.sh from `deploy/native/lastlight.service`). |
|
|
65
|
-
|
|
66
|
-
## Operations
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
# Status / logs
|
|
70
|
-
systemctl status lastlight
|
|
71
|
-
journalctl -u lastlight -f # live tail
|
|
72
|
-
journalctl -u lastlight --since '10 min ago' # recent
|
|
73
|
-
|
|
74
|
-
# Restart (e.g. after an env edit that doesn't need a rebuild)
|
|
75
|
-
sudo systemctl restart lastlight
|
|
76
|
-
|
|
77
|
-
# Stop / disable
|
|
78
|
-
sudo systemctl stop lastlight
|
|
79
|
-
sudo systemctl disable lastlight
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## TLS / reverse proxy
|
|
83
|
-
|
|
84
|
-
The harness binds `127.0.0.1:8644` by default (PORT in the env file).
|
|
85
|
-
Front it with Caddy or nginx for TLS.
|
|
86
|
-
|
|
87
|
-
Minimal Caddy setup:
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
sudo apt-get install -y caddy
|
|
91
|
-
sudo tee /etc/caddy/Caddyfile <<'EOF'
|
|
92
|
-
your-domain.example.com {
|
|
93
|
-
reverse_proxy 127.0.0.1:8644
|
|
94
|
-
}
|
|
95
|
-
EOF
|
|
96
|
-
sudo systemctl reload caddy
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Migrating from the Docker compose deploy
|
|
100
|
-
|
|
101
|
-
On the old (Docker compose) box:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# Snapshot the persistent volume.
|
|
105
|
-
docker run --rm -v lastlight_agent-data:/data -v /tmp:/backup busybox \
|
|
106
|
-
tar czf /backup/lastlight-data.tgz -C /data .
|
|
107
|
-
scp /tmp/lastlight-data.tgz root@new-host:/tmp/
|
|
108
|
-
docker compose down
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
On the new (native) host, after running install.sh and editing the env file:
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
sudo systemctl stop lastlight
|
|
115
|
-
sudo tar xzf /tmp/lastlight-data.tgz -C /var/lib/lastlight \
|
|
116
|
-
lastlight.db lastlight.db-shm lastlight.db-wal \
|
|
117
|
-
agent-sessions secrets || true
|
|
118
|
-
# The old volume used these directory names that the new code doesn't read.
|
|
119
|
-
# Safe to skip restoring them: opencode-home/, opencode-serve/, sandboxes/,
|
|
120
|
-
# sandbox-data/, sessions/, claude-home/.
|
|
121
|
-
sudo chown -R lastlight:lastlight /var/lib/lastlight
|
|
122
|
-
sudo systemctl start lastlight
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
The DB schema is unchanged across the migration, so workflow_runs +
|
|
126
|
-
executions history carry over.
|
|
127
|
-
|
|
128
|
-
## Rollback
|
|
129
|
-
|
|
130
|
-
If the new service doesn't come up cleanly:
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
sudo systemctl stop lastlight
|
|
134
|
-
sudo systemctl disable lastlight
|
|
135
|
-
# Restore the docker stack on the same host (or fail over to the old host)
|
|
136
|
-
docker compose up -d
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
State at `/var/lib/lastlight/` and the docker `agent-data` volume are
|
|
140
|
-
independent — neither rollback step touches the other.
|
|
141
|
-
|
|
142
|
-
## Verification
|
|
143
|
-
|
|
144
|
-
After the service is up:
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
# 1. It started cleanly.
|
|
148
|
-
systemctl status lastlight # → active (running)
|
|
149
|
-
|
|
150
|
-
# 2. KVM is reachable from the service's user context.
|
|
151
|
-
sudo -u lastlight ls -l /dev/kvm
|
|
152
|
-
|
|
153
|
-
# 3. The harness is listening.
|
|
154
|
-
curl -sS http://127.0.0.1:8644/admin/ | head -5
|
|
155
|
-
|
|
156
|
-
# 4. (Optional) Trigger a real workflow via a PR comment and watch:
|
|
157
|
-
journalctl -u lastlight -f
|
|
158
|
-
# Then look in the dashboard for the executions row + a JSONL under
|
|
159
|
-
# /var/lib/lastlight/agent-sessions/projects/<slug>/
|
|
160
|
-
```
|
package/deploy/native/install.sh
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Idempotent provision + (re)deploy of lastlight as a systemd service on a
|
|
3
|
-
# KVM-capable Linux host. Run as root from the repo root:
|
|
4
|
-
#
|
|
5
|
-
# sudo bash deploy/native/install.sh
|
|
6
|
-
#
|
|
7
|
-
# On first run: installs system deps, creates the lastlight user, scaffolds
|
|
8
|
-
# /etc/lastlight/lastlight.env from the example, installs and starts the
|
|
9
|
-
# systemd unit. On subsequent runs: re-installs the deps that changed,
|
|
10
|
-
# rebuilds, restarts the service.
|
|
11
|
-
|
|
12
|
-
set -euo pipefail
|
|
13
|
-
|
|
14
|
-
REPO_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
15
|
-
SERVICE_NAME=lastlight
|
|
16
|
-
LASTLIGHT_USER=lastlight
|
|
17
|
-
LASTLIGHT_HOME=/var/lib/lastlight
|
|
18
|
-
ENV_DIR=/etc/lastlight
|
|
19
|
-
ENV_FILE="${ENV_DIR}/lastlight.env"
|
|
20
|
-
PEM_FILE="${ENV_DIR}/app.pem"
|
|
21
|
-
|
|
22
|
-
if [ "$(id -u)" -ne 0 ]; then
|
|
23
|
-
echo "install.sh must run as root (try: sudo $0)" >&2
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
# ── 1. KVM check — gondolin silently hangs without it ──────────────────────
|
|
28
|
-
if [ ! -e /dev/kvm ]; then
|
|
29
|
-
echo "ERROR: /dev/kvm not present on this host." >&2
|
|
30
|
-
echo " gondolin (lastlight's default sandbox) requires KVM. The host must" >&2
|
|
31
|
-
echo " be bare-metal Linux or a VM with nested virtualization enabled." >&2
|
|
32
|
-
echo " See agentic-pi/SPIKE-gondolin.md for the full constraint." >&2
|
|
33
|
-
exit 1
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
# ── 2. System dependencies (Debian/Ubuntu) ─────────────────────────────────
|
|
37
|
-
export DEBIAN_FRONTEND=noninteractive
|
|
38
|
-
apt-get update
|
|
39
|
-
apt-get install -y --no-install-recommends \
|
|
40
|
-
curl ca-certificates git \
|
|
41
|
-
qemu-system-x86 qemu-utils \
|
|
42
|
-
python3 build-essential
|
|
43
|
-
# Use NodeSource for a current Node 22 LTS (Debian's nodejs is too old).
|
|
44
|
-
if ! command -v node >/dev/null 2>&1 || ! node -e 'process.exit(process.versions.node.split(".")[0] >= 20 ? 0 : 1)'; then
|
|
45
|
-
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
|
46
|
-
apt-get install -y --no-install-recommends nodejs
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
# ── 3. User + group ────────────────────────────────────────────────────────
|
|
50
|
-
if ! id "$LASTLIGHT_USER" >/dev/null 2>&1; then
|
|
51
|
-
useradd --system --create-home --home-dir "$LASTLIGHT_HOME" \
|
|
52
|
-
--shell /usr/sbin/nologin "$LASTLIGHT_USER"
|
|
53
|
-
fi
|
|
54
|
-
# `kvm` group exists once qemu is installed; gate the membership add to
|
|
55
|
-
# avoid a usermod warning on hosts where it doesn't.
|
|
56
|
-
if getent group kvm >/dev/null 2>&1; then
|
|
57
|
-
usermod -aG kvm "$LASTLIGHT_USER"
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# ── 4. Repo install + build (as the lastlight user) ────────────────────────
|
|
61
|
-
chown -R "$LASTLIGHT_USER:$LASTLIGHT_USER" "$REPO_DIR"
|
|
62
|
-
sudo -u "$LASTLIGHT_USER" -H bash -c "cd '$REPO_DIR' && npm ci --no-audit --no-fund"
|
|
63
|
-
sudo -u "$LASTLIGHT_USER" -H bash -c "cd '$REPO_DIR' && npm run build && npm run build:dashboard"
|
|
64
|
-
# Prune dev deps to shrink the on-disk footprint of the deployed checkout.
|
|
65
|
-
sudo -u "$LASTLIGHT_USER" -H bash -c "cd '$REPO_DIR' && npm prune --omit=dev"
|
|
66
|
-
|
|
67
|
-
# ── 5. Env file scaffold (don't overwrite an existing config) ──────────────
|
|
68
|
-
mkdir -p "$ENV_DIR"
|
|
69
|
-
chmod 0750 "$ENV_DIR"
|
|
70
|
-
chgrp "$LASTLIGHT_USER" "$ENV_DIR"
|
|
71
|
-
if [ ! -f "$ENV_FILE" ]; then
|
|
72
|
-
install -m 0640 -o root -g "$LASTLIGHT_USER" \
|
|
73
|
-
"$REPO_DIR/deploy/native/lastlight.env.example" "$ENV_FILE"
|
|
74
|
-
echo "" >&2
|
|
75
|
-
echo " NOTE: $ENV_FILE was just created from the example template." >&2
|
|
76
|
-
echo " Edit it to fill in your GitHub App, model API keys, Slack tokens, etc." >&2
|
|
77
|
-
echo " Then re-run this script to start the service." >&2
|
|
78
|
-
echo "" >&2
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
# ── 6. App PEM — referenced by GITHUB_APP_PRIVATE_KEY_PATH in the env file ─
|
|
82
|
-
# If you placed the PEM at /etc/lastlight/app.pem before running install.sh,
|
|
83
|
-
# this section locks down its permissions; otherwise it's a no-op.
|
|
84
|
-
if [ -f "$PEM_FILE" ]; then
|
|
85
|
-
chown root:"$LASTLIGHT_USER" "$PEM_FILE"
|
|
86
|
-
chmod 0640 "$PEM_FILE"
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# ── 7. systemd unit ────────────────────────────────────────────────────────
|
|
90
|
-
install -m 0644 \
|
|
91
|
-
"$REPO_DIR/deploy/native/lastlight.service" \
|
|
92
|
-
"/etc/systemd/system/${SERVICE_NAME}.service"
|
|
93
|
-
systemctl daemon-reload
|
|
94
|
-
|
|
95
|
-
# ── 8. Enable + start ──────────────────────────────────────────────────────
|
|
96
|
-
systemctl enable "${SERVICE_NAME}"
|
|
97
|
-
# Only start/restart if the env file looks configured (the example has the
|
|
98
|
-
# string CHANGE_ME everywhere a value is required).
|
|
99
|
-
if grep -q '^[A-Z].*=CHANGE_ME' "$ENV_FILE"; then
|
|
100
|
-
echo " $ENV_FILE still has CHANGE_ME placeholders — not (re)starting the service." >&2
|
|
101
|
-
echo " Fill in the values and re-run install.sh." >&2
|
|
102
|
-
exit 0
|
|
103
|
-
fi
|
|
104
|
-
systemctl restart "${SERVICE_NAME}"
|
|
105
|
-
|
|
106
|
-
# Brief status read-out so the operator sees if it started cleanly.
|
|
107
|
-
sleep 2
|
|
108
|
-
systemctl status "${SERVICE_NAME}" --no-pager -l | head -20 || true
|
|
109
|
-
echo ""
|
|
110
|
-
echo " Live logs: journalctl -u ${SERVICE_NAME} -f"
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# ── Last Light — Native deploy env (systemd EnvironmentFile) ────────────
|
|
2
|
-
# Path on the host: /etc/lastlight/lastlight.env
|
|
3
|
-
# Mode 0640, owned by root:lastlight.
|
|
4
|
-
#
|
|
5
|
-
# Anything marked CHANGE_ME must be replaced before the service will start
|
|
6
|
-
# (install.sh refuses to start the unit while placeholders are present).
|
|
7
|
-
|
|
8
|
-
# ── GitHub App (required) ─────────────────────────────────────────────────
|
|
9
|
-
GITHUB_APP_ID=CHANGE_ME
|
|
10
|
-
GITHUB_APP_INSTALLATION_ID=CHANGE_ME
|
|
11
|
-
# PEM is read by the harness at boot. install.sh locks down permissions if
|
|
12
|
-
# you place it at /etc/lastlight/app.pem before running.
|
|
13
|
-
GITHUB_APP_PRIVATE_KEY_PATH=/etc/lastlight/app.pem
|
|
14
|
-
|
|
15
|
-
# Webhook receiver
|
|
16
|
-
WEBHOOK_SECRET=CHANGE_ME
|
|
17
|
-
# Listener port — Caddy/Nginx should reverse-proxy 443 → 127.0.0.1:PORT.
|
|
18
|
-
PORT=8644
|
|
19
|
-
|
|
20
|
-
# ── Model + provider API key ─────────────────────────────────────────────
|
|
21
|
-
# pi-ai supports anthropic/…, openai/…, openrouter/<vendor>/<model>.
|
|
22
|
-
LASTLIGHT_MODEL=anthropic/claude-sonnet-4-6
|
|
23
|
-
# Set whichever matches LASTLIGHT_MODEL (or several if LASTLIGHT_MODELS
|
|
24
|
-
# routes different phases to different providers).
|
|
25
|
-
ANTHROPIC_API_KEY=CHANGE_ME
|
|
26
|
-
# OPENAI_API_KEY=
|
|
27
|
-
# OPENROUTER_API_KEY=
|
|
28
|
-
|
|
29
|
-
# ── OpenTelemetry (optional, disabled by default) ────────────────────────
|
|
30
|
-
# LASTLIGHT_OTEL_ENABLED=false
|
|
31
|
-
# LASTLIGHT_OTEL_SERVICE_NAME=lastlight
|
|
32
|
-
# LASTLIGHT_OTEL_INCLUDE_CONTENT=false
|
|
33
|
-
# LASTLIGHT_OTEL_FORWARD_TO_SANDBOX=true
|
|
34
|
-
# LASTLIGHT_OTEL_STRICT=false
|
|
35
|
-
# OTEL_EXPORTER_OTLP_ENDPOINT=https://CHANGE_ME
|
|
36
|
-
# OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer CHANGE_ME
|
|
37
|
-
# docker backend routes sandbox telemetry through an in-network otel-collector
|
|
38
|
-
# (re-exports to the endpoint above; headers stay host-side, any port works).
|
|
39
|
-
# LASTLIGHT_OTEL_COLLECTOR_HOSTS is only used by the gondolin egress allowlist.
|
|
40
|
-
# LASTLIGHT_OTEL_COLLECTOR_HOSTS=CHANGE_ME
|
|
41
|
-
|
|
42
|
-
# Per-task model overrides (optional). JSON keyed by phase/skill name.
|
|
43
|
-
# LASTLIGHT_MODELS={"architect":"openai/gpt-5.5","triage":"anthropic/claude-haiku-4-5-20251001"}
|
|
44
|
-
|
|
45
|
-
# ── Web search (optional, explore workflow only) ─────────────────────────
|
|
46
|
-
# Set any one to enable agentic-pi's `web_search` / `web_fetch` tools for
|
|
47
|
-
# the explore workflow. Provider auto-detected from whichever key is set
|
|
48
|
-
# (Tavily > Exa > Brave). Other workflows ignore these keys.
|
|
49
|
-
# TAVILY_API_KEY=tvly-...
|
|
50
|
-
# BRAVE_SEARCH_API_KEY=BSA...
|
|
51
|
-
# EXA_API_KEY=...
|
|
52
|
-
|
|
53
|
-
# Reasoning-effort default + per-task overrides (optional).
|
|
54
|
-
# Values: off | minimal | low | medium | high | xhigh
|
|
55
|
-
# LASTLIGHT_THINKING=medium
|
|
56
|
-
# LASTLIGHT_THINKINGS={"architect":"high","reviewer":"high"}
|
|
57
|
-
|
|
58
|
-
# ── Sandbox backend ───────────────────────────────────────────────────────
|
|
59
|
-
# gondolin = agentic-pi's QEMU micro-VM (default, requires /dev/kvm).
|
|
60
|
-
# docker = sibling docker containers (requires docker socket access).
|
|
61
|
-
# none = unsandboxed in-process (dev only — agent reads/writes host fs).
|
|
62
|
-
LASTLIGHT_SANDBOX=gondolin
|
|
63
|
-
|
|
64
|
-
# ── State paths ───────────────────────────────────────────────────────────
|
|
65
|
-
# systemd's StateDirectory= grants /var/lib/lastlight with the right mode.
|
|
66
|
-
STATE_DIR=/var/lib/lastlight
|
|
67
|
-
DB_PATH=/var/lib/lastlight/lastlight.db
|
|
68
|
-
LASTLIGHT_SESSIONS_DIR=/var/lib/lastlight/agent-sessions
|
|
69
|
-
|
|
70
|
-
# ── Admin dashboard ───────────────────────────────────────────────────────
|
|
71
|
-
# HMAC secret for session tokens. Generate with: openssl rand -hex 32
|
|
72
|
-
ADMIN_SECRET=CHANGE_ME
|
|
73
|
-
# Optional: require a password for the dashboard. Leave unset to allow
|
|
74
|
-
# anyone who can reach the listener (i.e. anyone past Caddy).
|
|
75
|
-
# ADMIN_PASSWORD=
|
|
76
|
-
|
|
77
|
-
# ── Slack (optional) ──────────────────────────────────────────────────────
|
|
78
|
-
# Setting SLACK_BOT_TOKEN enables the chat skill and the Slack connector.
|
|
79
|
-
# SLACK_BOT_TOKEN=xoxb-…
|
|
80
|
-
# SLACK_APP_TOKEN=xapp-…
|
|
81
|
-
# SLACK_DELIVERY_CHANNEL=C0123456789
|
|
82
|
-
# SLACK_ALLOWED_USERS=U0123,U0456
|
|
83
|
-
|
|
84
|
-
# Slack OAuth for dashboard login (optional)
|
|
85
|
-
# SLACK_OAUTH_CLIENT_ID=
|
|
86
|
-
# SLACK_OAUTH_CLIENT_SECRET=
|
|
87
|
-
# SLACK_OAUTH_REDIRECT_URI=https://your-domain/admin/auth/slack/callback
|
|
88
|
-
# SLACK_ALLOWED_WORKSPACE=
|
|
89
|
-
|
|
90
|
-
# ── Approval gates (optional) ─────────────────────────────────────────────
|
|
91
|
-
# Comma-separated list of gate names that should pause the runner.
|
|
92
|
-
# APPROVAL_GATES=post_architect,post_reviewer
|
|
93
|
-
|
|
94
|
-
# ── Bootstrap label (optional) ────────────────────────────────────────────
|
|
95
|
-
# BOOTSTRAP_LABEL=lastlight:bootstrap
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
[Unit]
|
|
2
|
-
Description=Last Light — GitHub repository maintenance agent
|
|
3
|
-
Documentation=https://github.com/nearform/lastlight
|
|
4
|
-
After=network-online.target
|
|
5
|
-
Wants=network-online.target
|
|
6
|
-
|
|
7
|
-
[Service]
|
|
8
|
-
Type=simple
|
|
9
|
-
User=lastlight
|
|
10
|
-
Group=lastlight
|
|
11
|
-
# gondolin needs /dev/kvm — group `kvm` is the standard accessor on Debian/Ubuntu.
|
|
12
|
-
SupplementaryGroups=kvm
|
|
13
|
-
|
|
14
|
-
WorkingDirectory=/opt/lastlight
|
|
15
|
-
ExecStart=/usr/bin/node /opt/lastlight/dist/index.js
|
|
16
|
-
EnvironmentFile=/etc/lastlight/lastlight.env
|
|
17
|
-
|
|
18
|
-
# HOME drives where agentic-pi caches the gondolin guest image
|
|
19
|
-
# (~/.cache/agentic-pi/images/). Pin it to the StateDirectory so the cache
|
|
20
|
-
# survives redeploys and isn't recomputed on every restart.
|
|
21
|
-
Environment=HOME=/var/lib/lastlight
|
|
22
|
-
Environment=NODE_ENV=production
|
|
23
|
-
|
|
24
|
-
Restart=on-failure
|
|
25
|
-
RestartSec=5s
|
|
26
|
-
LimitNOFILE=65536
|
|
27
|
-
# 2 GB matches the docker-compose limit. Bursts during webhook fan-out +
|
|
28
|
-
# in-process pi-ai chat; per-task gondolin VMs have their own memory budget.
|
|
29
|
-
MemoryMax=2G
|
|
30
|
-
|
|
31
|
-
# /var/lib/lastlight created with mode 0750, owned by lastlight:lastlight
|
|
32
|
-
StateDirectory=lastlight
|
|
33
|
-
StateDirectoryMode=0750
|
|
34
|
-
LogsDirectory=lastlight
|
|
35
|
-
LogsDirectoryMode=0750
|
|
36
|
-
|
|
37
|
-
# Security hardening — the harness only writes to its state dir and logs.
|
|
38
|
-
NoNewPrivileges=true
|
|
39
|
-
PrivateTmp=true
|
|
40
|
-
ProtectSystem=strict
|
|
41
|
-
ProtectHome=true
|
|
42
|
-
ProtectKernelTunables=true
|
|
43
|
-
ProtectKernelModules=true
|
|
44
|
-
ProtectControlGroups=true
|
|
45
|
-
ReadWritePaths=/var/lib/lastlight /var/log/lastlight
|
|
46
|
-
# Explicit /dev/kvm rule — ProtectSystem=strict alone doesn't gate /dev.
|
|
47
|
-
DeviceAllow=/dev/kvm rw
|
|
48
|
-
|
|
49
|
-
[Install]
|
|
50
|
-
WantedBy=multi-user.target
|