loki-mode 5.9.0 → 5.13.0
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/VERSION +1 -1
- package/autonomy/NOTIFY_INTEGRATION.md +255 -0
- package/autonomy/issue-parser.sh +636 -0
- package/autonomy/loki +2389 -47
- package/autonomy/notify.sh +308 -0
- package/autonomy/run.sh +224 -20
- package/docs/ACKNOWLEDGEMENTS.md +48 -1
- package/docs/DASHBOARD_V2_CHECKLIST.md +241 -0
- package/docs/architecture/DASHBOARD_V2_ARCHITECTURE.md +891 -0
- package/package.json +1 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.
|
|
1
|
+
5.13.0
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# Notification Integration Guide
|
|
2
|
+
|
|
3
|
+
This document describes how to integrate multi-channel notifications (Slack, Discord, Webhook) into run.sh.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Test notifications
|
|
9
|
+
loki notify test
|
|
10
|
+
|
|
11
|
+
# Check status
|
|
12
|
+
loki notify status
|
|
13
|
+
|
|
14
|
+
# Send to specific channel
|
|
15
|
+
loki notify slack "Build complete"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Environment Variables
|
|
19
|
+
|
|
20
|
+
| Variable | Description | Example |
|
|
21
|
+
|----------|-------------|---------|
|
|
22
|
+
| `LOKI_SLACK_WEBHOOK` | Slack incoming webhook URL | `https://hooks.slack.com/services/...` |
|
|
23
|
+
| `LOKI_DISCORD_WEBHOOK` | Discord webhook URL | `https://discord.com/api/webhooks/...` |
|
|
24
|
+
| `LOKI_WEBHOOK_URL` | Custom webhook URL (POST JSON) | `https://your-server.com/loki-webhook` |
|
|
25
|
+
| `LOKI_NOTIFY_CHANNELS` | Channels to use (comma-separated) | `slack,discord` or `all` |
|
|
26
|
+
|
|
27
|
+
## Integration Points in run.sh
|
|
28
|
+
|
|
29
|
+
### 1. Source the notification functions
|
|
30
|
+
|
|
31
|
+
Add at the top of run.sh (after sourcing providers/loader.sh):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Source notification functions from loki CLI
|
|
35
|
+
LOKI_CLI="$SCRIPT_DIR/loki"
|
|
36
|
+
if [ -f "$LOKI_CLI" ]; then
|
|
37
|
+
# Export functions for use
|
|
38
|
+
source "$LOKI_CLI" --source-only 2>/dev/null || true
|
|
39
|
+
fi
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or add the functions directly (simpler approach - recommended):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
#===============================================================================
|
|
46
|
+
# Multi-Channel Notifications (Slack/Discord/Webhook)
|
|
47
|
+
#===============================================================================
|
|
48
|
+
|
|
49
|
+
# Send notification to Slack
|
|
50
|
+
notify_slack() {
|
|
51
|
+
local message="$1"
|
|
52
|
+
local event_type="${2:-Notification}"
|
|
53
|
+
local webhook_url="${LOKI_SLACK_WEBHOOK:-}"
|
|
54
|
+
|
|
55
|
+
[ -z "$webhook_url" ] && return 0
|
|
56
|
+
|
|
57
|
+
local project_name=$(basename "$(pwd)")
|
|
58
|
+
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
59
|
+
|
|
60
|
+
curl -s -X POST -H 'Content-type: application/json' \
|
|
61
|
+
--data "{\"blocks\":[{\"type\":\"header\",\"text\":{\"type\":\"plain_text\",\"text\":\"Loki Mode: $event_type\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"$message\"}},{\"type\":\"context\",\"elements\":[{\"type\":\"mrkdwn\",\"text\":\"*Project:* $project_name | *Time:* $timestamp\"}]}]}" \
|
|
62
|
+
"$webhook_url" > /dev/null 2>&1 || true
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Send notification to Discord
|
|
66
|
+
notify_discord() {
|
|
67
|
+
local message="$1"
|
|
68
|
+
local event_type="${2:-Notification}"
|
|
69
|
+
local webhook_url="${LOKI_DISCORD_WEBHOOK:-}"
|
|
70
|
+
|
|
71
|
+
[ -z "$webhook_url" ] && return 0
|
|
72
|
+
|
|
73
|
+
local project_name=$(basename "$(pwd)")
|
|
74
|
+
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
75
|
+
|
|
76
|
+
curl -s -X POST -H 'Content-type: application/json' \
|
|
77
|
+
--data "{\"embeds\":[{\"title\":\"Loki Mode: $event_type\",\"description\":\"$message\",\"color\":5814783,\"footer\":{\"text\":\"Project: $project_name | $timestamp\"}}]}" \
|
|
78
|
+
"$webhook_url" > /dev/null 2>&1 || true
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Send notification to custom webhook
|
|
82
|
+
notify_webhook() {
|
|
83
|
+
local message="$1"
|
|
84
|
+
local event_type="${2:-Notification}"
|
|
85
|
+
local webhook_url="${LOKI_WEBHOOK_URL:-}"
|
|
86
|
+
|
|
87
|
+
[ -z "$webhook_url" ] && return 0
|
|
88
|
+
|
|
89
|
+
local project_name=$(basename "$(pwd)")
|
|
90
|
+
local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
91
|
+
|
|
92
|
+
curl -s -X POST -H 'Content-type: application/json' \
|
|
93
|
+
--data "{\"source\":\"loki-mode\",\"event\":\"$event_type\",\"message\":\"$message\",\"project\":\"$project_name\",\"timestamp\":\"$timestamp\"}" \
|
|
94
|
+
"$webhook_url" > /dev/null 2>&1 || true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Broadcast to all configured channels
|
|
98
|
+
notify_channels() {
|
|
99
|
+
local message="$1"
|
|
100
|
+
local event_type="${2:-Notification}"
|
|
101
|
+
local channels="${LOKI_NOTIFY_CHANNELS:-all}"
|
|
102
|
+
|
|
103
|
+
[[ "$channels" == "all" || "$channels" == *"slack"* ]] && notify_slack "$message" "$event_type"
|
|
104
|
+
[[ "$channels" == "all" || "$channels" == *"discord"* ]] && notify_discord "$message" "$event_type"
|
|
105
|
+
[[ "$channels" == "all" || "$channels" == *"webhook"* ]] && notify_webhook "$message" "$event_type"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2. Session Start (after initialization in main())
|
|
110
|
+
|
|
111
|
+
Location: After line ~4826 (after `audit_log "SESSION_START"`)
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Log session start for audit
|
|
115
|
+
audit_log "SESSION_START" "prd=$PRD_PATH,dashboard=$ENABLE_DASHBOARD,staged_autonomy=$STAGED_AUTONOMY,parallel=$PARALLEL_MODE"
|
|
116
|
+
|
|
117
|
+
# === ADD THIS ===
|
|
118
|
+
# Send multi-channel notification for session start
|
|
119
|
+
notify_channels "Session started for $(basename "$(pwd)")" "Session Start"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 3. Session End (before cleanup in main())
|
|
123
|
+
|
|
124
|
+
Location: After line ~4881 (after `audit_log "SESSION_END"`)
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Log session end for audit
|
|
128
|
+
audit_log "SESSION_END" "result=$result,prd=$PRD_PATH"
|
|
129
|
+
|
|
130
|
+
# === ADD THIS ===
|
|
131
|
+
# Send multi-channel notification for session end
|
|
132
|
+
if [ "$result" -eq 0 ]; then
|
|
133
|
+
notify_channels "Session completed successfully ($ITERATION_COUNT iterations)" "Session Complete"
|
|
134
|
+
else
|
|
135
|
+
notify_channels "Session ended with exit code $result after $ITERATION_COUNT iterations" "Session Failed"
|
|
136
|
+
fi
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 4. Task Completion (in run_autonomous function)
|
|
140
|
+
|
|
141
|
+
Location: After successful task completion (~line 4368 where `notify_all_complete` is called)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
log_header "COMPLETION PROMISE FULFILLED: $COMPLETION_PROMISE"
|
|
145
|
+
log_info "Explicit completion promise detected in output."
|
|
146
|
+
notify_all_complete
|
|
147
|
+
|
|
148
|
+
# === ADD THIS ===
|
|
149
|
+
notify_channels "Completion promise fulfilled: $COMPLETION_PROMISE" "Task Complete"
|
|
150
|
+
|
|
151
|
+
save_state $retry "completion_promise_fulfilled" 0
|
|
152
|
+
return 0
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 5. Error Handlers (in run_autonomous function)
|
|
156
|
+
|
|
157
|
+
Location: After error detection (~line 4395 where `notify_rate_limit` is called)
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
log_warn "Rate limit detected! Waiting until reset (~$human_time)..."
|
|
161
|
+
log_info "Rate limit resets at approximately $(date -v+${wait_time}S '+%I:%M %p' 2>/dev/null || date -d "+${wait_time} seconds" '+%I:%M %p' 2>/dev/null || echo 'soon')"
|
|
162
|
+
notify_rate_limit "$wait_time"
|
|
163
|
+
|
|
164
|
+
# === ADD THIS ===
|
|
165
|
+
notify_channels "Rate limited - waiting $human_time before retry" "Rate Limited"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 6. Pause Handler (in check_signals function)
|
|
169
|
+
|
|
170
|
+
Location: After pause detection (~line 4443)
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
if [ -f "$loki_dir/PAUSE" ]; then
|
|
174
|
+
log_warn "PAUSE file detected - pausing execution"
|
|
175
|
+
notify_intervention_needed "Execution paused via PAUSE file"
|
|
176
|
+
|
|
177
|
+
# === ADD THIS ===
|
|
178
|
+
notify_channels "Execution paused - human intervention needed" "Paused"
|
|
179
|
+
|
|
180
|
+
rm -f "$loki_dir/PAUSE"
|
|
181
|
+
handle_pause
|
|
182
|
+
return 1
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 7. Cleanup Handler (in cleanup function)
|
|
186
|
+
|
|
187
|
+
Location: In cleanup() around line 4564
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
cleanup() {
|
|
191
|
+
local current_time=$(date +%s)
|
|
192
|
+
local time_diff=$((current_time - INTERRUPT_LAST_TIME))
|
|
193
|
+
|
|
194
|
+
# If double Ctrl+C within 2 seconds, exit immediately
|
|
195
|
+
if [ "$time_diff" -lt 2 ] && [ "$INTERRUPT_COUNT" -gt 0 ]; then
|
|
196
|
+
echo ""
|
|
197
|
+
log_warn "Double interrupt - stopping immediately"
|
|
198
|
+
|
|
199
|
+
# === ADD THIS ===
|
|
200
|
+
notify_channels "Session interrupted by user" "Interrupted"
|
|
201
|
+
|
|
202
|
+
stop_dashboard
|
|
203
|
+
stop_status_monitor
|
|
204
|
+
save_state ${RETRY_COUNT:-0} "interrupted" 130
|
|
205
|
+
log_info "State saved. Run again to resume."
|
|
206
|
+
exit 130
|
|
207
|
+
fi
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Configuration via config.yaml
|
|
211
|
+
|
|
212
|
+
Add to `.loki/config.yaml`:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
notifications:
|
|
216
|
+
# Desktop notifications (existing)
|
|
217
|
+
enabled: true
|
|
218
|
+
sound: true
|
|
219
|
+
|
|
220
|
+
# Multi-channel notifications (new)
|
|
221
|
+
slack_webhook: YOUR_SLACK_WEBHOOK_URL_HERE
|
|
222
|
+
discord_webhook: https://discord.com/api/webhooks/123456789012345678/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
|
223
|
+
webhook_url: https://your-server.com/loki-webhook
|
|
224
|
+
channels: all # or: slack,discord,webhook
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Webhook Payload Format
|
|
228
|
+
|
|
229
|
+
Custom webhooks receive POST requests with this JSON structure:
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"source": "loki-mode",
|
|
234
|
+
"event": "Session Start|Session Complete|Task Complete|Rate Limited|Paused|Interrupted",
|
|
235
|
+
"message": "Human-readable message",
|
|
236
|
+
"project": "project-name",
|
|
237
|
+
"timestamp": "2025-01-15T10:30:00Z"
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Testing
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Set up webhook (example with Slack)
|
|
245
|
+
export LOKI_SLACK_WEBHOOK="https://hooks.slack.com/services/..."
|
|
246
|
+
|
|
247
|
+
# Test notification
|
|
248
|
+
loki notify test "Hello from Loki Mode!"
|
|
249
|
+
|
|
250
|
+
# Check status
|
|
251
|
+
loki notify status
|
|
252
|
+
|
|
253
|
+
# Send to specific channel
|
|
254
|
+
loki notify slack "Build deployed to production"
|
|
255
|
+
```
|