loki-mode 6.67.3 → 6.68.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/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.67.3
6
+ # Loki Mode v6.68.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -268,4 +268,4 @@ The following features are documented in skill modules but not yet fully automat
268
268
  | Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
269
269
  | Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
270
270
 
271
- **v6.67.3 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
271
+ **v6.68.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 6.67.3
1
+ 6.68.0
package/autonomy/loki CHANGED
@@ -7054,70 +7054,191 @@ QPRDEOF
7054
7054
  cmd_monitor() {
7055
7055
  local project_dir="${1:-.}"
7056
7056
 
7057
+ # Resolve to absolute path
7058
+ if [[ ! "$project_dir" = /* ]]; then
7059
+ project_dir="$(cd "$project_dir" 2>/dev/null && pwd)" || {
7060
+ echo -e "${RED}Error: directory not found: $1${NC}"
7061
+ return 1
7062
+ }
7063
+ fi
7064
+
7057
7065
  if [[ ! -f "$project_dir/docker-compose.yml" ]] && [[ ! -f "$project_dir/docker-compose.yaml" ]]; then
7058
7066
  echo -e "${RED}No docker-compose.yml found in $project_dir${NC}"
7059
7067
  return 1
7060
7068
  fi
7061
7069
 
7062
- echo -e "${CYAN}Monitoring Docker Compose services in $project_dir...${NC}"
7070
+ echo -e "${CYAN}AI-Powered Docker Monitor${NC}"
7071
+ echo -e "Project: ${BOLD}$project_dir${NC}"
7072
+ echo -e "Provider: ${GREEN}${LOKI_PROVIDER:-claude}${NC}"
7063
7073
  echo "Press Ctrl+C to stop."
7064
7074
  echo ""
7065
7075
 
7066
7076
  local fix_count=0
7067
- local max_fixes=10
7077
+ local max_fixes="${LOKI_MONITOR_MAX_FIXES:-10}"
7078
+ local poll_interval="${LOKI_MONITOR_INTERVAL:-10}"
7079
+ local consecutive_healthy=0
7080
+
7081
+ trap 'echo ""; echo -e "${CYAN}Monitor stopped.${NC}"; return 0' INT TERM
7068
7082
 
7069
7083
  while true; do
7070
- # Check service status
7071
- local status
7072
- status=$(cd "$project_dir" && docker compose ps -a --format json 2>/dev/null)
7084
+ # 1. CAPTURE: Get service status (all services including stopped)
7085
+ local ps_output
7086
+ ps_output=$(cd "$project_dir" && docker compose ps -a --format json 2>/dev/null)
7073
7087
 
7074
- if [[ -z "$status" ]]; then
7088
+ if [[ -z "$ps_output" ]]; then
7075
7089
  echo -e "${YELLOW}No services found. Waiting...${NC}"
7076
- sleep 10
7090
+ sleep "$poll_interval"
7077
7091
  continue
7078
7092
  fi
7079
7093
 
7080
- # Parse each service
7081
- local has_failure=false
7094
+ # Parse services and find failures
7095
+ local failed_services=""
7096
+ local all_healthy=true
7097
+ local service_summary=""
7098
+
7082
7099
  while IFS= read -r line; do
7083
7100
  [[ -z "$line" ]] && continue
7084
- local svc_name svc_state
7085
- svc_name=$(echo "$line" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('Service',d.get('Name','')))" 2>/dev/null)
7086
- svc_state=$(echo "$line" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('State',''))" 2>/dev/null)
7101
+ local svc_name svc_state svc_exit
7102
+ svc_name=$(echo "$line" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('Service',d.get('Name','')))" 2>/dev/null || echo "unknown")
7103
+ svc_state=$(echo "$line" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('State','unknown'))" 2>/dev/null || echo "unknown")
7104
+ svc_exit=$(echo "$line" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); print(d.get('ExitCode',0))" 2>/dev/null || echo "0")
7105
+
7106
+ service_summary="${service_summary}${svc_name}=${svc_state} "
7087
7107
 
7088
7108
  if [[ "$svc_state" == "exited" ]] || [[ "$svc_state" == "dead" ]]; then
7089
- has_failure=true
7090
- echo -e "${RED}Service '$svc_name' is $svc_state${NC}"
7109
+ all_healthy=false
7110
+ failed_services="${failed_services} ${svc_name}"
7111
+ fi
7112
+ done <<< "$ps_output"
7091
7113
 
7092
- if [[ $fix_count -lt $max_fixes ]]; then
7093
- # Get logs for the failed service
7094
- local logs
7095
- logs=$(cd "$project_dir" && docker compose logs --tail 30 "$svc_name" 2>/dev/null)
7114
+ if [[ "$all_healthy" == "true" ]]; then
7115
+ consecutive_healthy=$((consecutive_healthy + 1))
7116
+ printf "\r${GREEN}[healthy]${NC} %s (%s) " "$service_summary" "$(date +%H:%M:%S)"
7117
+ sleep "$poll_interval"
7118
+ continue
7119
+ fi
7096
7120
 
7097
- echo -e "${CYAN}Auto-fixing $svc_name...${NC}"
7121
+ consecutive_healthy=0
7098
7122
 
7099
- # Run loki quick with targeted fix
7100
- LOKI_MAX_ITERATIONS=5 LOKI_AUTO_FIX=true \
7101
- loki quick "Fix the '$svc_name' Docker service. It exited with an error. Logs: $logs" \
7102
- 2>&1 | while IFS= read -r fline; do echo " $fline"; done
7123
+ # 2. CAPTURE LOGS and CONTEXT for each failed service, then feed to AI
7124
+ for svc_name in $failed_services; do
7125
+ if [[ $fix_count -ge $max_fixes ]]; then
7126
+ echo -e "\n${RED}Max fix attempts ($max_fixes) reached for this session.${NC}"
7127
+ echo "Manual intervention needed. Check: cd $project_dir && docker compose logs $svc_name"
7128
+ sleep "$poll_interval"
7129
+ continue 2
7130
+ fi
7103
7131
 
7104
- # Rebuild and restart
7105
- echo -e "${CYAN}Rebuilding $svc_name...${NC}"
7106
- (cd "$project_dir" && docker compose up -d --build --no-deps "$svc_name" 2>&1) | while IFS= read -r fline; do echo " $fline"; done
7132
+ echo -e "\n${RED}[FAILURE] $svc_name is down${NC}"
7107
7133
 
7108
- fix_count=$((fix_count + 1))
7109
- echo -e "${GREEN}Fix attempt $fix_count/$max_fixes for $svc_name${NC}"
7110
- else
7111
- echo -e "${YELLOW}Max fix attempts ($max_fixes) reached. Manual intervention needed.${NC}"
7134
+ local logs
7135
+ logs=$(cd "$project_dir" && docker compose logs --tail 50 "$svc_name" 2>/dev/null | head -c 3000)
7136
+
7137
+ # Gather docker-compose.yml for AI context (truncated to avoid ARG_MAX)
7138
+ local compose_content=""
7139
+ if [[ -f "$project_dir/docker-compose.yml" ]]; then
7140
+ compose_content=$(head -c 5000 "$project_dir/docker-compose.yml")
7141
+ elif [[ -f "$project_dir/docker-compose.yaml" ]]; then
7142
+ compose_content=$(head -c 5000 "$project_dir/docker-compose.yaml")
7143
+ fi
7144
+
7145
+ # Gather Dockerfile for the failing service (truncated)
7146
+ local dockerfile_content=""
7147
+ for df_path in "$project_dir/$svc_name/Dockerfile" "$project_dir/Dockerfile" "$project_dir/Dockerfile.$svc_name"; do
7148
+ if [[ -f "$df_path" ]]; then
7149
+ dockerfile_content=$(head -c 3000 "$df_path")
7150
+ break
7112
7151
  fi
7152
+ done
7153
+
7154
+ # 3. FEED TO AI: Construct a rich prompt with all context
7155
+ local ai_prompt="You are debugging a Docker Compose service that has failed.
7156
+
7157
+ SERVICE: $svc_name
7158
+ STATUS: exited/dead
7159
+
7160
+ DOCKER COMPOSE LOGS (last 50 lines):
7161
+ $logs
7162
+
7163
+ DOCKER-COMPOSE.YML:
7164
+ $compose_content"
7165
+
7166
+ if [[ -n "$dockerfile_content" ]]; then
7167
+ ai_prompt="${ai_prompt}
7168
+
7169
+ DOCKERFILE ($svc_name/Dockerfile):
7170
+ $dockerfile_content"
7113
7171
  fi
7114
- done <<< "$status"
7115
7172
 
7116
- if [[ "$has_failure" == "false" ]]; then
7117
- echo -e "\r${GREEN}All services healthy${NC} $(date +%H:%M:%S) \c"
7118
- fi
7173
+ ai_prompt="${ai_prompt}
7174
+
7175
+ INSTRUCTIONS:
7176
+ 1. Analyze the error in the logs above
7177
+ 2. Identify the root cause
7178
+ 3. Fix the issue by editing the necessary files (docker-compose.yml, Dockerfile, source code, package.json, requirements.txt, etc.)
7179
+ 4. Make sure the fix works on any platform (Docker Desktop, Linux, Docker-in-Docker, Kubernetes)
7180
+ 5. Do NOT just restart -- actually fix the underlying code/config problem
7181
+ 6. After fixing, the system will rebuild with 'docker compose up --build'
7182
+ 7. Common issues: named volumes for node_modules (use anonymous), missing dependencies, port conflicts, wrong commands"
7183
+
7184
+ echo -e "${CYAN}[AI] Analyzing $svc_name failure with ${LOKI_PROVIDER:-claude}...${NC}"
7185
+
7186
+ # 4. LET AI FIX: Run loki quick with the AI prompt
7187
+ # The AI provider (claude/codex/gemini/ollama) decides what to fix
7188
+ fix_count=$((fix_count + 1))
7189
+ echo -e "${CYAN}[FIX] Attempt $fix_count/$max_fixes${NC}"
7190
+
7191
+ (
7192
+ cd "$project_dir"
7193
+ LOKI_MAX_ITERATIONS=5 LOKI_AUTO_FIX=true \
7194
+ "$0" quick "$ai_prompt" 2>&1 | while IFS= read -r fline; do
7195
+ echo " $fline"
7196
+ done
7197
+ )
7198
+
7199
+ # 5. REBUILD: Docker compose up --build for the fixed service
7200
+ echo -e "${CYAN}[REBUILD] Rebuilding $svc_name...${NC}"
7201
+ (cd "$project_dir" && docker compose up -d --build --no-deps "$svc_name" 2>&1) | while IFS= read -r fline; do
7202
+ echo " $fline"
7203
+ done
7204
+
7205
+ # 6. VERIFY: Wait and check if the fix worked
7206
+ echo -e "${CYAN}[VERIFY] Waiting 15s for $svc_name to stabilize...${NC}"
7207
+ sleep 15
7208
+
7209
+ local verify_state
7210
+ verify_state=$(cd "$project_dir" && docker compose ps -a --format json 2>/dev/null | VERIFY_SVC="$svc_name" python3 -c "
7211
+ import json, sys, os
7212
+ svc = os.environ['VERIFY_SVC']
7213
+ raw = sys.stdin.read().strip()
7214
+ if not raw:
7215
+ print('unknown')
7216
+ sys.exit(0)
7217
+ # Handle both JSON array (v2.21+) and NDJSON formats
7218
+ try:
7219
+ parsed = json.loads(raw)
7220
+ services = parsed if isinstance(parsed, list) else [parsed]
7221
+ except json.JSONDecodeError:
7222
+ services = []
7223
+ for line in raw.split(chr(10)):
7224
+ try: services.append(json.loads(line))
7225
+ except: pass
7226
+ for s in services:
7227
+ if not isinstance(s, dict): continue
7228
+ if s.get('Service', s.get('Name','')) == svc:
7229
+ print(s.get('State','unknown'))
7230
+ sys.exit(0)
7231
+ print('unknown')
7232
+ " 2>/dev/null || echo "unknown")
7233
+
7234
+ if [[ "$verify_state" == "running" ]]; then
7235
+ echo -e "${GREEN}[SUCCESS] $svc_name is now running!${NC}"
7236
+ else
7237
+ echo -e "${YELLOW}[RETRY] $svc_name still not healthy (state: $verify_state). Will retry on next poll.${NC}"
7238
+ fi
7239
+ done
7119
7240
 
7120
- sleep 10
7241
+ sleep "$poll_interval"
7121
7242
  done
7122
7243
  }
7123
7244
 
package/autonomy/run.sh CHANGED
@@ -630,6 +630,8 @@ if [ -f "$TELEMETRY_SCRIPT" ]; then
630
630
  source "$TELEMETRY_SCRIPT"
631
631
  fi
632
632
 
633
+
634
+
633
635
  # 2026 Research Enhancements (minimal additions)
634
636
  PROMPT_REPETITION=${LOKI_PROMPT_REPETITION:-true}
635
637
  CONFIDENCE_ROUTING=${LOKI_CONFIDENCE_ROUTING:-true}
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "6.67.3"
10
+ __version__ = "6.68.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v6.67.3
5
+ **Version:** v6.68.0
6
6
 
7
7
  ---
8
8
 
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '6.67.3'
60
+ __version__ = '6.68.0'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "6.67.3",
3
+ "version": "6.68.0",
4
4
  "description": "Loki Mode by Autonomi - Multi-agent autonomous startup system for Claude Code, Codex CLI, and Gemini CLI",
5
5
  "keywords": [
6
6
  "agent",
package/web-app/server.py CHANGED
@@ -1481,7 +1481,7 @@ class DevServerManager:
1481
1481
  if framework == "docker":
1482
1482
  await asyncio.to_thread(
1483
1483
  subprocess.run,
1484
- ["docker", "compose", "up", "-d", "--build"],
1484
+ ["docker", "compose", "up", "-d", "--build", "--no-deps"],
1485
1485
  capture_output=True, cwd=str(target), timeout=120
1486
1486
  )
1487
1487
  # Restart the dev server
@@ -1732,17 +1732,17 @@ class DevServerManager:
1732
1732
  was_running = prev.get("status") in ("running", None)
1733
1733
  now_failed = svc["state"] in ("exited", "dead")
1734
1734
 
1735
- # Also detect services that never started (failed on initial docker compose up).
1736
- # On first poll, prev is empty ({}) so prev.get("status") is None, which counts
1737
- # as "was_running" above. But if a service was already "exited" before we ever
1738
- # saw it as "running", the next poll would see prev.status="exited" and skip it.
1739
- # Detect this case: first time we see a service in a failed state with no prior fix.
1740
- first_seen_failed = (
1741
- not prev # No previous health record for this service
1742
- and now_failed
1735
+ # Detect services that need fixing:
1736
+ # 1. was_running and now_failed: service transitioned from running to exited
1737
+ # 2. Persistently failed: service is exited AND has never been successfully fixed
1738
+ # (fix_attempts == 0 or fix_status != "fixed")
1739
+ persistently_failed = (
1740
+ now_failed
1741
+ and prev.get("fix_status") != "fixed"
1742
+ and prev.get("status") in ("exited", "dead", None)
1743
1743
  )
1744
1744
 
1745
- if (was_running and now_failed) or first_seen_failed:
1745
+ if (was_running and now_failed) or persistently_failed:
1746
1746
  svc_health["restarts"] = prev.get("restarts", 0) + 1
1747
1747
  logger.warning("Docker service '%s' failed (exit %s)", name, svc.get("exit_code"))
1748
1748
 
@@ -1766,14 +1766,51 @@ class DevServerManager:
1766
1766
 
1767
1767
  info["_auto_fixing"] = True
1768
1768
  svc_logs = docker_ctx.get("service_logs", {}).get(name, "")
1769
- diagnoses = _diagnose_errors(svc_logs)
1770
- diag_text = "\n".join(f"- {d['diagnosis']}: {d['suggestion']}" for d in diagnoses)
1771
-
1772
- fix_prompt = f"The '{name}' Docker service crashed (exit code {svc.get('exit_code', 1)}).\n"
1773
- if diag_text:
1774
- fix_prompt += f"\nDiagnosis:\n{diag_text}\n"
1775
- fix_prompt += f"\nService logs:\n{svc_logs[:2000]}\n"
1776
- fix_prompt += "\nFix the issue and ensure the service starts correctly."
1769
+
1770
+ # Read compose file for AI context
1771
+ compose_content = ""
1772
+ compose_file = project_dir / "docker-compose.yml"
1773
+ if not compose_file.exists():
1774
+ compose_file = project_dir / "docker-compose.yaml"
1775
+ if compose_file.exists():
1776
+ try:
1777
+ compose_content = compose_file.read_text(errors="replace")[:5000]
1778
+ except OSError:
1779
+ pass
1780
+
1781
+ # Read service Dockerfile for AI context
1782
+ dockerfile_content = ""
1783
+ for df_path in [project_dir / name / "Dockerfile", project_dir / "Dockerfile"]:
1784
+ if df_path.exists():
1785
+ try:
1786
+ dockerfile_content = df_path.read_text(errors="replace")[:3000]
1787
+ break
1788
+ except OSError:
1789
+ pass
1790
+
1791
+ fix_prompt = f"""You are debugging a Docker Compose service that has failed.
1792
+
1793
+ SERVICE: {name}
1794
+ STATUS: exited/dead (exit code {svc.get('exit_code', 1)})
1795
+
1796
+ DOCKER COMPOSE LOGS (last 50 lines):
1797
+ {svc_logs[:3000]}
1798
+
1799
+ DOCKER-COMPOSE.YML:
1800
+ {compose_content}
1801
+ """
1802
+ if dockerfile_content:
1803
+ fix_prompt += f"\nDOCKERFILE ({name}/Dockerfile):\n{dockerfile_content}\n"
1804
+
1805
+ fix_prompt += """
1806
+ INSTRUCTIONS:
1807
+ 1. Analyze the error in the logs above
1808
+ 2. Identify the root cause
1809
+ 3. Fix the issue by editing the necessary files (docker-compose.yml, Dockerfile, source code, package.json, requirements.txt, etc.)
1810
+ 4. Make sure the fix works on any platform (Docker Desktop, Linux, Docker-in-Docker, Kubernetes)
1811
+ 5. Do NOT just restart -- actually fix the underlying code/config problem
1812
+ 6. After fixing, the system will rebuild with 'docker compose up --build'
1813
+ 7. Common issues: named volumes for node_modules (use anonymous), missing dependencies, port conflicts, wrong commands"""
1777
1814
 
1778
1815
  svc_health["fix_attempts"] += 1
1779
1816
  svc_health["fix_timestamps"] = recent_fixes + [now]