Docs
Slack integration
Slack integration is optional but recommended. Last Light uses two independent Slack features that you can enable one at a time.
- Chat — the bot listens for messages and
@mentions, classifies intent, and runs an in-process
@earendil-works/pi-aichat loop to reply. Every Slack thread becomes a growing, DB-backed conversation; the harness rehydrates the message history from themessaging_messagesSQLite table on every turn, so context stays coherent across hours or days. Events arrive over the HTTP Events API by default (reliable, retried delivery); Socket Mode is available as a dev fallback. - OAuth dashboard login — the admin dashboard offers "Login with Slack" via OpenID Connect. You can restrict login to one workspace so only your team can see execution history.
Create the Slack app
Go to api.slack.com/apps and click Create New App → From scratch.
Enable chat (HTTP Events API)
In the app's settings, do the following:
- OAuth & Permissions → add Bot Token Scopes:
app_mentions:readchat:writeim:history,im:read,im:writechannels:history,groups:historycommands(if you want/approve,/rejectslash commands)
- Install to Workspace. After install, copy the Bot User OAuth Token (
xoxb-...) — that'sSLACK_BOT_TOKEN. - Basic Information → copy the Signing Secret — that's
SLACK_SIGNING_SECRET. Deploy the harness with this set first (the Request URL below must already answer). - Event Subscriptions → enable, set the Request URL to
https://your-host/webhooks/slack(Slack verifies it with a one-time challenge), then subscribe to bot events:message.im— direct messagesapp_mention— @mentions in channels
message.channels— a channel @mention would then arrive twice, as both amessageand anapp_mention.) - Slash Commands (optional) → create
/approve,/reject,/status,/resetpointing athttps://your-host/....
Add the tokens to .env (or instance/secrets/.env in production):
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=... # enables webhook mode (the default) Socket Mode (dev fallback). Without a public URL, set
SLACK_MODE=socket and enable Socket Mode in the app (App-Level Token with
connections:write → SLACK_APP_TOKEN=xapp-...). Mode is auto-detected
when SLACK_MODE is unset: webhook if SLACK_SIGNING_SECRET is present,
otherwise socket. Socket Mode is at-most-once and can drop messages under bursts, so
prefer webhooks in production.
Optional restrictions and routing:
SLACK_ALLOWED_USERS=U01ABC,U02DEF # Comma-separated user IDs allowed to interact
SLACK_DELIVERY_CHANNEL=C01XYZ # Channel for cron health reports
Restart the harness. You should see a [slack] Connected log line,
and DM'ing the bot should get a reply. Every conversation shows up on the
dashboard's Chat Sessions tab.
chat skill is intentionally not overridden with a small/cheap
model in LASTLIGHT_MODELS — small models tend to refuse tool
calls on the assumption they lack permission, creating false "I can't do that"
replies. Leave it on the default mid/large-tier model.
Enable OAuth dashboard login
The dashboard can optionally let your team log in with Slack via OpenID Connect. Back in the Slack app settings:
- OAuth & Permissions → User Token Scopes → add
openid,email,profile. (These are user scopes, separate from the bot scopes above.) - Redirect URLs → add exactly:
https://your-host/admin/api/oauth/slack/callback(orhttp://localhost:8644/...for local dev). - Basic Information → copy the Client ID and Client Secret.
Add the following to .env:
SLACK_OAUTH_CLIENT_ID=...
SLACK_OAUTH_CLIENT_SECRET=...
SLACK_OAUTH_REDIRECT_URI=https://your-host/admin/api/oauth/slack/callback
SLACK_ALLOWED_WORKSPACE=T01ABCDEF # Optional: restrict to one team_id or domain
With these set, the dashboard login page shows a "Login with Slack" button
alongside the password login (or instead of it, if you don't set
ADMIN_PASSWORD).