loki-mode 6.37.4 → 6.37.6
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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +3 -2
- package/autonomy/loki +51 -12
- package/autonomy/run.sh +16 -3
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Multi-agent autonomous startup system. Triggers on "Loki Mode". Takes PRD to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v6.37.
|
|
6
|
+
# Loki Mode v6.37.6
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -267,4 +267,4 @@ The following features are documented in skill modules but not yet fully automat
|
|
|
267
267
|
| Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
|
|
268
268
|
| Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
|
|
269
269
|
|
|
270
|
-
**v6.37.
|
|
270
|
+
**v6.37.6 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
6.37.
|
|
1
|
+
6.37.6
|
|
@@ -42,8 +42,9 @@ COUNCIL_ENABLED=${LOKI_COUNCIL_ENABLED:-true}
|
|
|
42
42
|
COUNCIL_SIZE=${LOKI_COUNCIL_SIZE:-3}
|
|
43
43
|
COUNCIL_THRESHOLD=${LOKI_COUNCIL_THRESHOLD:-2}
|
|
44
44
|
COUNCIL_CHECK_INTERVAL=${LOKI_COUNCIL_CHECK_INTERVAL:-5}
|
|
45
|
-
# Guard against
|
|
46
|
-
if [ "$COUNCIL_CHECK_INTERVAL" -
|
|
45
|
+
# Guard against invalid interval (must be positive integer)
|
|
46
|
+
if ! [[ "$COUNCIL_CHECK_INTERVAL" =~ ^[1-9][0-9]*$ ]]; then
|
|
47
|
+
echo "Warning: invalid COUNCIL_CHECK_INTERVAL '$COUNCIL_CHECK_INTERVAL', using default 5" >&2
|
|
47
48
|
COUNCIL_CHECK_INTERVAL=5
|
|
48
49
|
fi
|
|
49
50
|
COUNCIL_MIN_ITERATIONS=${LOKI_COUNCIL_MIN_ITERATIONS:-3}
|
package/autonomy/loki
CHANGED
|
@@ -1144,8 +1144,9 @@ cmd_stop() {
|
|
|
1144
1144
|
if [ -n "$target_session" ]; then
|
|
1145
1145
|
if is_session_running "$target_session"; then
|
|
1146
1146
|
_stop_session_by_id "$target_session"
|
|
1147
|
+
echo "Stopped session: $target_session"
|
|
1147
1148
|
else
|
|
1148
|
-
echo
|
|
1149
|
+
echo "No active session found"
|
|
1149
1150
|
fi
|
|
1150
1151
|
return 0
|
|
1151
1152
|
fi
|
|
@@ -1365,6 +1366,15 @@ cmd_pause() {
|
|
|
1365
1366
|
fi
|
|
1366
1367
|
|
|
1367
1368
|
if is_session_running; then
|
|
1369
|
+
# Warn if running in perpetual mode where PAUSE is auto-cleared (#84)
|
|
1370
|
+
local current_mode="${LOKI_AUTONOMY_MODE:-perpetual}"
|
|
1371
|
+
local perpetual_flag="${LOKI_PERPETUAL_MODE:-false}"
|
|
1372
|
+
if [ "$current_mode" = "perpetual" ] || [ "$perpetual_flag" = "true" ]; then
|
|
1373
|
+
echo -e "${YELLOW}Warning: Session is running in perpetual mode.${NC}"
|
|
1374
|
+
echo -e "${YELLOW}PAUSE signals are auto-cleared in perpetual mode and will be ignored.${NC}"
|
|
1375
|
+
echo -e "Use ${CYAN}loki stop${NC} to halt a perpetual session, or switch autonomy mode first:"
|
|
1376
|
+
echo -e " ${DIM}loki config set autonomy_mode checkpoint${NC}"
|
|
1377
|
+
fi
|
|
1368
1378
|
touch "$LOKI_DIR/PAUSE"
|
|
1369
1379
|
# Emit session pause event
|
|
1370
1380
|
emit_event session cli pause "reason=user_requested"
|
|
@@ -3026,6 +3036,10 @@ cmd_web_start() {
|
|
|
3026
3036
|
echo -e "${RED}Error: Port must be between 1 and 65535, got $port${NC}"
|
|
3027
3037
|
exit 1
|
|
3028
3038
|
fi
|
|
3039
|
+
if lsof -Pi :"$port" -sTCP:LISTEN -t >/dev/null 2>&1; then
|
|
3040
|
+
echo -e "${RED}Error: Port $port is already in use${NC}"
|
|
3041
|
+
exit 1
|
|
3042
|
+
fi
|
|
3029
3043
|
|
|
3030
3044
|
# Validate --prd file if provided
|
|
3031
3045
|
if [ -n "$prd_file" ]; then
|
|
@@ -4440,12 +4454,12 @@ cmd_watch() {
|
|
|
4440
4454
|
esac
|
|
4441
4455
|
done
|
|
4442
4456
|
|
|
4443
|
-
# Validate numeric arguments
|
|
4444
|
-
if ! [[ "$poll_interval" =~ ^[0-9]
|
|
4457
|
+
# Validate numeric arguments (no leading zeros, no decimals, positive integers only)
|
|
4458
|
+
if ! [[ "$poll_interval" =~ ^[1-9][0-9]*$ ]]; then
|
|
4445
4459
|
echo -e "${RED}Invalid --interval: $poll_interval (expected positive integer)${NC}"
|
|
4446
4460
|
return 1
|
|
4447
4461
|
fi
|
|
4448
|
-
if ! [[ "$debounce" =~ ^[0-9]
|
|
4462
|
+
if ! [[ "$debounce" =~ ^[1-9][0-9]*$ ]] && [ "$debounce" != "0" ]; then
|
|
4449
4463
|
echo -e "${RED}Invalid --debounce: $debounce (expected non-negative integer)${NC}"
|
|
4450
4464
|
return 1
|
|
4451
4465
|
fi
|
|
@@ -4476,6 +4490,13 @@ cmd_watch() {
|
|
|
4476
4490
|
return 1
|
|
4477
4491
|
fi
|
|
4478
4492
|
|
|
4493
|
+
# Verify the PRD file is readable (#67)
|
|
4494
|
+
if [ ! -r "$prd_path" ]; then
|
|
4495
|
+
echo -e "${RED}PRD file is not readable: $prd_path${NC}"
|
|
4496
|
+
echo "Check file permissions: ls -la $prd_path"
|
|
4497
|
+
return 1
|
|
4498
|
+
fi
|
|
4499
|
+
|
|
4479
4500
|
# Resolve to absolute path
|
|
4480
4501
|
prd_path="$(cd "$(dirname "$prd_path")" && pwd)/$(basename "$prd_path")"
|
|
4481
4502
|
local prd_basename
|
|
@@ -5001,7 +5022,11 @@ cmd_config_set() {
|
|
|
5001
5022
|
;;
|
|
5002
5023
|
budget)
|
|
5003
5024
|
if ! echo "$value" | grep -qE '^[0-9]+(\.[0-9]+)?$'; then
|
|
5004
|
-
echo -e "${RED}Invalid budget: $value (expected: numeric USD amount)${NC}"; return 1
|
|
5025
|
+
echo -e "${RED}Invalid budget: $value (expected: positive numeric USD amount)${NC}"; return 1
|
|
5026
|
+
fi
|
|
5027
|
+
# Reject zero and negative values (#68)
|
|
5028
|
+
if echo "$value" | grep -qE '^0+(\.0+)?$'; then
|
|
5029
|
+
echo -e "${RED}Invalid budget: $value (must be greater than 0)${NC}"; return 1
|
|
5005
5030
|
fi
|
|
5006
5031
|
;;
|
|
5007
5032
|
model.planning|model.development|model.fast)
|
|
@@ -13960,6 +13985,13 @@ cmd_remote() {
|
|
|
13960
13985
|
# Emit event
|
|
13961
13986
|
emit_event session cli remote_start "prd=${prd_abs:-none}"
|
|
13962
13987
|
|
|
13988
|
+
# Check SSH directory exists (needed for remote connections)
|
|
13989
|
+
if [ ! -d "$HOME/.ssh" ]; then
|
|
13990
|
+
echo -e "${RED}Error: ~/.ssh directory not found${NC}"
|
|
13991
|
+
echo "Create it with: mkdir -p ~/.ssh && chmod 700 ~/.ssh"
|
|
13992
|
+
return 1
|
|
13993
|
+
fi
|
|
13994
|
+
|
|
13963
13995
|
# Always use bypassPermissions so Loki Mode can operate autonomously
|
|
13964
13996
|
rc_flags+=("--permission-mode" "bypassPermissions")
|
|
13965
13997
|
|
|
@@ -14717,33 +14749,40 @@ for a in agents:
|
|
|
14717
14749
|
echo -e "${DIM}Persona: ${persona:0:80}...${NC}"
|
|
14718
14750
|
echo ""
|
|
14719
14751
|
|
|
14720
|
-
# Invoke current provider
|
|
14752
|
+
# Invoke current provider and capture exit code (#72)
|
|
14721
14753
|
local provider="${LOKI_PROVIDER:-claude}"
|
|
14722
14754
|
if [ -f ".loki/state/provider" ]; then
|
|
14723
14755
|
provider=$(cat ".loki/state/provider" 2>/dev/null)
|
|
14724
14756
|
fi
|
|
14725
14757
|
|
|
14758
|
+
local agent_exit=0
|
|
14726
14759
|
case "$provider" in
|
|
14727
14760
|
claude)
|
|
14728
|
-
claude -p "$full_prompt" 2>&1
|
|
14761
|
+
claude -p "$full_prompt" 2>&1 || agent_exit=$?
|
|
14729
14762
|
;;
|
|
14730
14763
|
codex)
|
|
14731
|
-
codex exec --full-auto "$full_prompt" 2>&1
|
|
14764
|
+
codex exec --full-auto "$full_prompt" 2>&1 || agent_exit=$?
|
|
14732
14765
|
;;
|
|
14733
14766
|
gemini)
|
|
14734
|
-
gemini --approval-mode=yolo "$full_prompt" 2>&1
|
|
14767
|
+
gemini --approval-mode=yolo "$full_prompt" 2>&1 || agent_exit=$?
|
|
14735
14768
|
;;
|
|
14736
14769
|
cline)
|
|
14737
|
-
cline -y "$full_prompt" 2>&1
|
|
14770
|
+
cline -y "$full_prompt" 2>&1 || agent_exit=$?
|
|
14738
14771
|
;;
|
|
14739
14772
|
aider)
|
|
14740
|
-
aider --message "$full_prompt" --yes-always --no-auto-commits < /dev/null 2>&1
|
|
14773
|
+
aider --message "$full_prompt" --yes-always --no-auto-commits < /dev/null 2>&1 || agent_exit=$?
|
|
14741
14774
|
;;
|
|
14742
14775
|
*)
|
|
14743
14776
|
echo -e "${RED}Unknown provider: $provider${NC}"
|
|
14744
14777
|
return 1
|
|
14745
14778
|
;;
|
|
14746
14779
|
esac
|
|
14780
|
+
|
|
14781
|
+
if [ "$agent_exit" -ne 0 ]; then
|
|
14782
|
+
echo ""
|
|
14783
|
+
echo -e "${RED}Agent exited with code $agent_exit${NC}"
|
|
14784
|
+
return "$agent_exit"
|
|
14785
|
+
fi
|
|
14747
14786
|
;;
|
|
14748
14787
|
|
|
14749
14788
|
start)
|
|
@@ -15730,7 +15769,7 @@ cmd_explain() {
|
|
|
15730
15769
|
|
|
15731
15770
|
while [[ $# -gt 0 ]]; do
|
|
15732
15771
|
case "$1" in
|
|
15733
|
-
--json) output_json=true; shift ;;
|
|
15772
|
+
--json) output_json=true; require_jq || return 1; shift ;;
|
|
15734
15773
|
--brief) output_brief=true; shift ;;
|
|
15735
15774
|
--save) output_save=true; shift ;;
|
|
15736
15775
|
--help|-h)
|
package/autonomy/run.sh
CHANGED
|
@@ -1243,6 +1243,7 @@ detect_complexity() {
|
|
|
1243
1243
|
if [ -n "$prd_path" ] && [ -f "$prd_path" ]; then
|
|
1244
1244
|
local prd_words=$(wc -w < "$prd_path" | tr -d ' ')
|
|
1245
1245
|
local feature_count=0
|
|
1246
|
+
local prd_lines=$(wc -l < "$prd_path" | tr -d ' ')
|
|
1246
1247
|
|
|
1247
1248
|
# Detect PRD format and count features accordingly
|
|
1248
1249
|
if [[ "$prd_path" == *.json ]]; then
|
|
@@ -1262,14 +1263,23 @@ detect_complexity() {
|
|
|
1262
1263
|
feature_count=$(grep -c "^##\|^- \[" "$prd_path" 2>/dev/null || echo "0")
|
|
1263
1264
|
fi
|
|
1264
1265
|
|
|
1265
|
-
|
|
1266
|
+
# Count distinct sections (h2/h3 headers) for structural complexity (#74)
|
|
1267
|
+
local section_count=0
|
|
1268
|
+
if [[ "$prd_path" != *.json ]]; then
|
|
1269
|
+
section_count=$(grep -c "^##\|^###" "$prd_path" 2>/dev/null || echo "0")
|
|
1270
|
+
fi
|
|
1271
|
+
|
|
1272
|
+
# PRD complexity uses content length, feature count, AND structural depth (#74)
|
|
1273
|
+
# A PRD with multiple sections or substantial content is not "simple" even with few project files
|
|
1274
|
+
if [ "$prd_words" -lt 200 ] && [ "$feature_count" -lt 5 ] && [ "$section_count" -lt 3 ]; then
|
|
1266
1275
|
prd_complexity="simple"
|
|
1267
|
-
elif [ "$prd_words" -gt 1000 ] || [ "$feature_count" -gt 15 ]; then
|
|
1276
|
+
elif [ "$prd_words" -gt 1000 ] || [ "$feature_count" -gt 15 ] || [ "$section_count" -gt 10 ]; then
|
|
1268
1277
|
prd_complexity="complex"
|
|
1269
1278
|
fi
|
|
1270
1279
|
fi
|
|
1271
1280
|
|
|
1272
1281
|
# Determine final complexity
|
|
1282
|
+
# A non-simple PRD always prevents "simple" classification regardless of file count (#74)
|
|
1273
1283
|
if [ "$file_count" -le 5 ] && [ "$prd_complexity" = "simple" ] && \
|
|
1274
1284
|
[ "$has_external" = "false" ] && [ "$has_microservices" = "false" ]; then
|
|
1275
1285
|
DETECTED_COMPLEXITY="simple"
|
|
@@ -1280,7 +1290,7 @@ detect_complexity() {
|
|
|
1280
1290
|
DETECTED_COMPLEXITY="standard"
|
|
1281
1291
|
fi
|
|
1282
1292
|
|
|
1283
|
-
log_info "Detected complexity: $DETECTED_COMPLEXITY (files: $file_count, external: $has_external, microservices: $has_microservices)"
|
|
1293
|
+
log_info "Detected complexity: $DETECTED_COMPLEXITY (files: $file_count, prd: $prd_complexity, external: $has_external, microservices: $has_microservices)"
|
|
1284
1294
|
}
|
|
1285
1295
|
|
|
1286
1296
|
# Get phases based on complexity tier
|
|
@@ -2824,6 +2834,9 @@ init_loki_dir() {
|
|
|
2824
2834
|
mkdir -p .loki/artifacts/{releases,reports,backups}
|
|
2825
2835
|
mkdir -p .loki/memory/{ledgers,handoffs,learnings,episodic,semantic,skills}
|
|
2826
2836
|
mkdir -p .loki/metrics/{efficiency,rewards}
|
|
2837
|
+
# Clear stale metrics from previous sessions so loki metrics shows current run data (#75)
|
|
2838
|
+
rm -f .loki/metrics/efficiency/iteration-*.json 2>/dev/null || true
|
|
2839
|
+
rm -f .loki/metrics/rewards/*.json 2>/dev/null || true
|
|
2827
2840
|
mkdir -p .loki/rules
|
|
2828
2841
|
mkdir -p .loki/signals
|
|
2829
2842
|
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
package/mcp/__init__.py
CHANGED