loki-mode 5.28.1 → 5.29.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/README.md CHANGED
@@ -6,6 +6,7 @@
6
6
  [![npm downloads](https://img.shields.io/npm/dw/loki-mode)](https://www.npmjs.com/package/loki-mode)
7
7
  [![GitHub stars](https://img.shields.io/github/stars/asklokesh/loki-mode)](https://github.com/asklokesh/loki-mode)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-Loki%20Mode-purple?logo=github)](https://github.com/marketplace/actions/loki-mode-code-review)
9
10
  [![Claude Code](https://img.shields.io/badge/Claude-Code-orange)](https://claude.ai)
10
11
  [![Agent Types](https://img.shields.io/badge/Agent%20Types-41-blue)]()
11
12
  [![Loki Mode](https://img.shields.io/badge/Loki%20Mode-98.78%25%20Pass%401-blueviolet)](benchmarks/results/)
@@ -55,7 +56,45 @@ claude --dangerously-skip-permissions
55
56
  # Then say: Loki Mode with PRD at ./my-prd.md
56
57
  ```
57
58
 
58
- Also available via **Homebrew**, **Docker**, **VS Code Extension**, and **direct shell script**. See the [Installation Guide](docs/INSTALLATION.md) for all 6 installation methods and detailed instructions.
59
+ ### Option 3: GitHub Action
60
+
61
+ Add automated AI code review to your pull requests:
62
+
63
+ ```yaml
64
+ # .github/workflows/loki-review.yml
65
+ name: Loki Code Review
66
+
67
+ on:
68
+ pull_request:
69
+ types: [opened, synchronize]
70
+
71
+ permissions:
72
+ contents: read
73
+ pull-requests: write
74
+
75
+ jobs:
76
+ review:
77
+ runs-on: ubuntu-latest
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ - uses: asklokesh/loki-mode@v5
81
+ with:
82
+ github_token: ${{ secrets.GITHUB_TOKEN }}
83
+ mode: review # review, fix, or test
84
+ provider: claude # claude, codex, or gemini
85
+ max_iterations: 3 # higher = more thorough
86
+ budget_limit: '5.00' # max cost in USD
87
+ ```
88
+
89
+ **Modes:**
90
+
91
+ | Mode | Description |
92
+ |------|-------------|
93
+ | `review` | Analyze PR diff, post structured review as PR comment |
94
+ | `fix` | Automatically fix issues found in the codebase |
95
+ | `test` | Run autonomous test generation and validation |
96
+
97
+ Also available via **Homebrew**, **Docker**, **VS Code Extension**, and **direct shell script**. See the [Installation Guide](docs/INSTALLATION.md) for all 7 installation methods and detailed instructions.
59
98
 
60
99
  ### Multi-Provider Support (v5.0.0)
61
100
 
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 zero human intervention. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v5.28.1
6
+ # Loki Mode v5.29.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -260,4 +260,4 @@ Auto-detected or force with `LOKI_COMPLEXITY`:
260
260
 
261
261
  ---
262
262
 
263
- **v5.28.1 | Demo, quick mode, init, cost dashboard, 12 templates, GitHub Action | ~270 lines core**
263
+ **v5.29.0 | Demo, quick mode, init, cost dashboard, 12 templates, GitHub Action | ~270 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 5.28.1
1
+ 5.29.0
package/autonomy/loki CHANGED
@@ -506,33 +506,14 @@ cmd_start() {
506
506
  local effective_provider="${provider:-${LOKI_PROVIDER:-claude}}"
507
507
 
508
508
  # Handle sandbox mode - delegate to sandbox.sh
509
- # Skip if we're already inside a container (/.dockerenv exists)
510
- if [[ "${LOKI_SANDBOX_MODE:-}" == "true" ]] && [[ ! -f /.dockerenv ]]; then
509
+ # Skip if we're already inside a sandbox (IS_SANDBOX=1 or /.dockerenv exists)
510
+ if [[ "${LOKI_SANDBOX_MODE:-}" == "true" ]] && [[ "${IS_SANDBOX:-}" != "1" ]] && [[ ! -f /.dockerenv ]]; then
511
511
  if [ ! -f "$SANDBOX_SH" ]; then
512
512
  echo -e "${RED}Error: sandbox.sh not found at $SANDBOX_SH${NC}"
513
513
  exit 1
514
514
  fi
515
515
 
516
- # Check Docker availability
517
- if ! command -v docker &> /dev/null; then
518
- echo -e "${RED}Error: Docker not found${NC}"
519
- echo ""
520
- echo "Docker is required for sandbox mode. Install it:"
521
- echo " macOS: brew install --cask docker"
522
- echo " Linux: curl -fsSL https://get.docker.com | sh"
523
- exit 1
524
- fi
525
-
526
- if ! docker info &> /dev/null 2>&1; then
527
- echo -e "${RED}Error: Docker daemon not running${NC}"
528
- echo ""
529
- echo "Start Docker:"
530
- echo " macOS: Open Docker Desktop app"
531
- echo " Linux: sudo systemctl start docker"
532
- exit 1
533
- fi
534
-
535
- echo -e "${GREEN}Starting Loki Mode in Docker sandbox...${NC}"
516
+ echo -e "${GREEN}Starting Loki Mode in sandbox...${NC}"
536
517
  # Load memory context before sandbox start (errors don't block startup)
537
518
  load_memory_context "$prd_file" || true
538
519
  emit_event session cli start "provider=$effective_provider" "sandbox=true" "prd_path=${prd_file:-}"
@@ -2795,6 +2776,7 @@ broadcast_notification() {
2795
2776
  }
2796
2777
 
2797
2778
  # Sandbox management (delegates to sandbox.sh)
2779
+ # sandbox.sh handles detection: Docker Desktop Sandbox > Docker Container > Worktree
2798
2780
  cmd_sandbox() {
2799
2781
  local subcommand="${1:-help}"
2800
2782
  shift || true
@@ -2805,28 +2787,7 @@ cmd_sandbox() {
2805
2787
  exit 1
2806
2788
  fi
2807
2789
 
2808
- # Check Docker availability
2809
- if ! command -v docker &> /dev/null; then
2810
- echo -e "${RED}Error: Docker not found${NC}"
2811
- echo ""
2812
- echo "Docker is required for sandbox mode. Install it:"
2813
- echo " macOS: brew install --cask docker"
2814
- echo " Linux: curl -fsSL https://get.docker.com | sh"
2815
- echo ""
2816
- echo "After installation, start Docker Desktop or the Docker daemon."
2817
- exit 1
2818
- fi
2819
-
2820
- if ! docker info &> /dev/null 2>&1; then
2821
- echo -e "${RED}Error: Docker daemon not running${NC}"
2822
- echo ""
2823
- echo "Start Docker:"
2824
- echo " macOS: Open Docker Desktop app"
2825
- echo " Linux: sudo systemctl start docker"
2826
- exit 1
2827
- fi
2828
-
2829
- # Delegate to sandbox.sh
2790
+ # Delegate to sandbox.sh (it handles Docker/worktree detection internally)
2830
2791
  exec "$SANDBOX_SH" "$subcommand" "$@"
2831
2792
  }
2832
2793
 
@@ -184,6 +184,11 @@ WORKTREE_PREFIX="loki-sandbox"
184
184
  WORKTREE_BASE="${LOKI_WORKTREE_BASE:-${TMPDIR:-/tmp}}"
185
185
  WORKTREE_STATE_FILE="${PROJECT_DIR}/.loki/sandbox/worktree-state.json"
186
186
 
187
+ # Check if Docker Desktop Sandbox is available (microVM-based isolation)
188
+ is_docker_desktop_sandbox_available() {
189
+ command -v docker &>/dev/null && docker sandbox version &>/dev/null 2>&1
190
+ }
191
+
187
192
  # Check if Docker is available (non-fatal version)
188
193
  is_docker_available() {
189
194
  command -v docker &>/dev/null && docker info &>/dev/null 2>&1
@@ -195,10 +200,19 @@ is_git_available() {
195
200
  }
196
201
 
197
202
  # Detect which sandbox mode to use
203
+ # Priority: docker-desktop > docker > worktree
198
204
  detect_sandbox_mode() {
199
205
  local requested="${1:-auto}"
200
206
 
201
207
  case "$requested" in
208
+ docker-desktop)
209
+ if is_docker_desktop_sandbox_available; then
210
+ echo "docker-desktop"
211
+ else
212
+ log_error "Docker Desktop Sandbox not available (requires Docker Desktop 4.58+)"
213
+ return 1
214
+ fi
215
+ ;;
202
216
  docker)
203
217
  if is_docker_available; then
204
218
  echo "docker"
@@ -216,7 +230,9 @@ detect_sandbox_mode() {
216
230
  fi
217
231
  ;;
218
232
  auto|*)
219
- if is_docker_available; then
233
+ if is_docker_desktop_sandbox_available; then
234
+ echo "docker-desktop"
235
+ elif is_docker_available; then
220
236
  echo "docker"
221
237
  elif is_git_available; then
222
238
  log_warn "Docker not available - using worktree sandbox (soft isolation)"
@@ -514,7 +530,229 @@ cleanup_worktrees() {
514
530
  }
515
531
 
516
532
  #===============================================================================
517
- # Container Management
533
+ # Docker Desktop Sandbox (microVM-based isolation via Docker Desktop 4.58+)
534
+ #===============================================================================
535
+
536
+ # Desktop sandbox name follows same pattern as container name
537
+ DESKTOP_SANDBOX_NAME="$CONTAINER_NAME"
538
+
539
+ # Install provider CLI inside sandbox if not pre-installed
540
+ _desktop_install_provider_cli() {
541
+ local sandbox_name="$1" provider="$2"
542
+ case "$provider" in
543
+ codex)
544
+ if ! docker sandbox exec "$sandbox_name" which codex &>/dev/null 2>&1; then
545
+ log_info "Installing Codex CLI in sandbox (one-time)..."
546
+ docker sandbox exec "$sandbox_name" npm install -g @openai/codex 2>&1 | tail -1
547
+ fi
548
+ ;;
549
+ gemini)
550
+ if ! docker sandbox exec "$sandbox_name" which gemini &>/dev/null 2>&1; then
551
+ log_info "Installing Gemini CLI in sandbox (one-time)..."
552
+ docker sandbox exec "$sandbox_name" npm install -g @google/gemini-cli 2>&1 | tail -1
553
+ fi
554
+ ;;
555
+ # claude is pre-installed in the sandbox template
556
+ esac
557
+ }
558
+
559
+ # Build environment variable args for docker sandbox exec
560
+ _desktop_build_env_args() {
561
+ DESKTOP_ENV_ARGS=()
562
+ [[ -n "${ANTHROPIC_API_KEY:-}" ]] && DESKTOP_ENV_ARGS+=("-e" "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY")
563
+ [[ -n "${OPENAI_API_KEY:-}" ]] && DESKTOP_ENV_ARGS+=("-e" "OPENAI_API_KEY=$OPENAI_API_KEY")
564
+ [[ -n "${GOOGLE_API_KEY:-}" ]] && DESKTOP_ENV_ARGS+=("-e" "GOOGLE_API_KEY=$GOOGLE_API_KEY")
565
+ [[ -n "${GITHUB_TOKEN:-}" ]] && DESKTOP_ENV_ARGS+=("-e" "GITHUB_TOKEN=$GITHUB_TOKEN")
566
+ [[ -n "${GH_TOKEN:-}" ]] && DESKTOP_ENV_ARGS+=("-e" "GH_TOKEN=$GH_TOKEN")
567
+ # Forward all LOKI_* env vars
568
+ local var
569
+ while IFS= read -r var; do
570
+ [[ -n "$var" ]] && DESKTOP_ENV_ARGS+=("-e" "$var=${!var}")
571
+ done < <(compgen -v LOKI_ 2>/dev/null || true)
572
+ }
573
+
574
+ start_docker_desktop_sandbox() {
575
+ local prd_path="${1:-}"
576
+ local provider="${LOKI_PROVIDER:-claude}"
577
+
578
+ validate_project_dir || return 1
579
+ warn_missing_api_keys "$provider"
580
+
581
+ # Check if sandbox already exists
582
+ local sandbox_exists=false
583
+ if docker sandbox ls 2>/dev/null | grep -q "$DESKTOP_SANDBOX_NAME"; then
584
+ sandbox_exists=true
585
+ fi
586
+
587
+ if [[ "$sandbox_exists" == "false" ]]; then
588
+ log_info "Creating Docker Desktop Sandbox (microVM)..."
589
+ log_info " Workspace: $PROJECT_DIR"
590
+ log_info " Agent: claude (provider: $provider)"
591
+ docker sandbox create --name "$DESKTOP_SANDBOX_NAME" claude "$PROJECT_DIR" || {
592
+ log_error "Failed to create Docker Desktop Sandbox"
593
+ log_info "Falling back to Docker container sandbox..."
594
+ start_sandbox "$@"
595
+ return $?
596
+ }
597
+ log_success "Sandbox created: $DESKTOP_SANDBOX_NAME"
598
+ else
599
+ log_info "Using existing sandbox: $DESKTOP_SANDBOX_NAME"
600
+ fi
601
+
602
+ # Install provider CLI if needed (codex/gemini not pre-installed)
603
+ _desktop_install_provider_cli "$DESKTOP_SANDBOX_NAME" "$provider"
604
+
605
+ # Build environment variable args
606
+ _desktop_build_env_args
607
+
608
+ # Build loki command
609
+ local loki_cmd="bash ${PROJECT_DIR}/autonomy/run.sh"
610
+ if [[ -n "$prd_path" ]]; then
611
+ local abs_prd
612
+ abs_prd=$(cd "$(dirname "$prd_path")" && pwd)/$(basename "$prd_path")
613
+ loki_cmd="$loki_cmd $abs_prd"
614
+ fi
615
+ loki_cmd="LOKI_PROVIDER=$provider LOKI_SANDBOX_MODE=true LOKI_DASHBOARD=false $loki_cmd"
616
+
617
+ log_info ""
618
+ log_info "Starting Loki Mode in Docker Desktop Sandbox..."
619
+ log_info " Isolation: microVM (hypervisor-based)"
620
+ log_info " Provider: $provider"
621
+ log_info " Sandbox: $DESKTOP_SANDBOX_NAME"
622
+ log_info " Workspace: $PROJECT_DIR (synced at same path)"
623
+ log_info ""
624
+ log_info " Private Docker daemon available inside sandbox"
625
+ log_info " Dashboard: run 'loki dashboard' on host (reads synced .loki/ files)"
626
+ log_info ""
627
+ log_info "Commands:"
628
+ log_info " loki sandbox status - Check sandbox status"
629
+ log_info " loki sandbox shell - Open shell in sandbox"
630
+ log_info " loki sandbox stop - Stop sandbox"
631
+ log_info ""
632
+
633
+ # Execute loki inside sandbox (use -it only when stdin is a terminal)
634
+ local tty_args="-i"
635
+ if [ -t 0 ]; then
636
+ tty_args="-it"
637
+ fi
638
+ docker sandbox exec $tty_args \
639
+ -w "$PROJECT_DIR" \
640
+ ${DESKTOP_ENV_ARGS[@]+"${DESKTOP_ENV_ARGS[@]}"} \
641
+ "$DESKTOP_SANDBOX_NAME" \
642
+ bash -c "$loki_cmd"
643
+ }
644
+
645
+ stop_docker_desktop_sandbox() {
646
+ local remove="${1:-false}"
647
+
648
+ if ! docker sandbox ls 2>/dev/null | grep -q "$DESKTOP_SANDBOX_NAME"; then
649
+ log_error "Sandbox not found: $DESKTOP_SANDBOX_NAME"
650
+ return 1
651
+ fi
652
+
653
+ # Signal loki to stop gracefully
654
+ docker sandbox exec "$DESKTOP_SANDBOX_NAME" \
655
+ bash -c "touch ${PROJECT_DIR}/.loki/STOP 2>/dev/null" 2>/dev/null || true
656
+
657
+ log_info "Stopping sandbox: $DESKTOP_SANDBOX_NAME"
658
+ docker sandbox stop "$DESKTOP_SANDBOX_NAME" 2>/dev/null || true
659
+
660
+ if [[ "$remove" == "true" ]]; then
661
+ log_info "Removing sandbox: $DESKTOP_SANDBOX_NAME"
662
+ docker sandbox rm "$DESKTOP_SANDBOX_NAME" 2>/dev/null || true
663
+ fi
664
+
665
+ log_success "Sandbox stopped"
666
+ }
667
+
668
+ docker_desktop_sandbox_status() {
669
+ local found=false
670
+ while IFS= read -r line; do
671
+ if echo "$line" | grep -q "$DESKTOP_SANDBOX_NAME"; then
672
+ found=true
673
+ echo "$line"
674
+ fi
675
+ done < <(docker sandbox ls 2>/dev/null)
676
+
677
+ if [[ "$found" == "false" ]]; then
678
+ log_info "No Docker Desktop Sandbox found for this project"
679
+ log_info "Expected name: $DESKTOP_SANDBOX_NAME"
680
+ return 1
681
+ fi
682
+
683
+ # If sandbox is running, get loki status
684
+ if docker sandbox ls 2>/dev/null | grep "$DESKTOP_SANDBOX_NAME" | grep -q "running"; then
685
+ echo ""
686
+ docker sandbox exec -w "$PROJECT_DIR" "$DESKTOP_SANDBOX_NAME" \
687
+ bash -c "bash ${PROJECT_DIR}/autonomy/loki status" 2>/dev/null || true
688
+ fi
689
+ }
690
+
691
+ docker_desktop_sandbox_shell() {
692
+ if ! docker sandbox ls 2>/dev/null | grep "$DESKTOP_SANDBOX_NAME" | grep -q "running"; then
693
+ log_error "Sandbox is not running: $DESKTOP_SANDBOX_NAME"
694
+ log_info "Start it with: loki sandbox start"
695
+ return 1
696
+ fi
697
+
698
+ log_info "Opening shell in Docker Desktop Sandbox..."
699
+ docker sandbox exec -it -w "$PROJECT_DIR" "$DESKTOP_SANDBOX_NAME" bash
700
+ }
701
+
702
+ docker_desktop_sandbox_logs() {
703
+ local lines="${1:-100}"
704
+ if ! docker sandbox ls 2>/dev/null | grep -q "$DESKTOP_SANDBOX_NAME"; then
705
+ log_error "Sandbox not found: $DESKTOP_SANDBOX_NAME"
706
+ return 1
707
+ fi
708
+
709
+ docker sandbox exec -w "$PROJECT_DIR" "$DESKTOP_SANDBOX_NAME" \
710
+ bash -c "cat .loki/logs/*.log 2>/dev/null | tail -${lines}" || \
711
+ log_warn "No logs found in .loki/logs/"
712
+ }
713
+
714
+ docker_desktop_sandbox_prompt() {
715
+ local message="${1:-}"
716
+ if [[ -z "$message" ]]; then
717
+ log_error "Usage: loki sandbox prompt <message>"
718
+ return 1
719
+ fi
720
+
721
+ if ! docker sandbox ls 2>/dev/null | grep "$DESKTOP_SANDBOX_NAME" | grep -q "running"; then
722
+ log_error "Sandbox is not running"
723
+ return 1
724
+ fi
725
+
726
+ _desktop_build_env_args
727
+ docker sandbox exec -w "$PROJECT_DIR" \
728
+ ${DESKTOP_ENV_ARGS[@]+"${DESKTOP_ENV_ARGS[@]}"} \
729
+ "$DESKTOP_SANDBOX_NAME" \
730
+ bash -c "echo '$message' > ${PROJECT_DIR}/.loki/HUMAN_INPUT.md"
731
+
732
+ log_success "Prompt sent to sandbox"
733
+ }
734
+
735
+ docker_desktop_sandbox_run() {
736
+ local cmd="${*}"
737
+ if [[ -z "$cmd" ]]; then
738
+ log_error "Usage: loki sandbox run <command>"
739
+ return 1
740
+ fi
741
+
742
+ if ! docker sandbox ls 2>/dev/null | grep "$DESKTOP_SANDBOX_NAME" | grep -q "running"; then
743
+ log_error "Sandbox is not running"
744
+ return 1
745
+ fi
746
+
747
+ _desktop_build_env_args
748
+ docker sandbox exec -w "$PROJECT_DIR" \
749
+ ${DESKTOP_ENV_ARGS[@]+"${DESKTOP_ENV_ARGS[@]}"} \
750
+ "$DESKTOP_SANDBOX_NAME" \
751
+ bash -c "$cmd"
752
+ }
753
+
754
+ #===============================================================================
755
+ # Docker Container Sandbox (standard Docker - fallback from Docker Desktop)
518
756
  #===============================================================================
519
757
 
520
758
  start_sandbox() {
@@ -1121,15 +1359,18 @@ show_help() {
1121
1359
  echo " expose <port> Show how to expose additional ports"
1122
1360
  echo ""
1123
1361
  echo "Mode Options:"
1124
- echo " --docker Force Docker sandbox (full isolation)"
1362
+ echo " --docker-desktop Force Docker Desktop Sandbox (microVM isolation)"
1363
+ echo " --docker Force Docker container sandbox (seccomp isolation)"
1125
1364
  echo " --worktree Force git worktree sandbox (soft isolation)"
1126
1365
  echo " --auto Auto-detect best mode (default)"
1127
1366
  echo ""
1128
- echo "Sandbox Modes:"
1129
- echo " Docker (default) - Full isolation with seccomp, dropped capabilities,"
1130
- echo " resource limits, network control"
1131
- echo " Worktree - Git worktree isolation (fallback if Docker unavailable)"
1132
- echo " Warning: No filesystem/network/process isolation"
1367
+ echo "Sandbox Modes (priority order):"
1368
+ echo " Docker Desktop - microVM isolation via 'docker sandbox' (Docker Desktop 4.58+)"
1369
+ echo " (default) Hypervisor-based VM, private Docker daemon, pre-installed CLIs"
1370
+ echo " Docker Container - Container isolation with seccomp, dropped capabilities,"
1371
+ echo " (fallback) resource limits, network control (Dockerfile.sandbox)"
1372
+ echo " Worktree - Git worktree isolation (last resort if no Docker)"
1373
+ echo " (last resort) Warning: No filesystem/network/process isolation"
1133
1374
  echo ""
1134
1375
  echo "Environment Variables:"
1135
1376
  echo " LOKI_SANDBOX_IMAGE Docker image (default: loki-mode:sandbox)"
@@ -1150,8 +1391,9 @@ show_help() {
1150
1391
  echo " - Prompt injection DISABLED by default (enterprise security)"
1151
1392
  echo ""
1152
1393
  echo "Examples:"
1153
- echo " loki sandbox start # Start (auto-detect mode)"
1154
- echo " loki sandbox start --docker ./prd.md # Force Docker mode"
1394
+ echo " loki sandbox start # Start (auto-detect: Desktop > Docker > Worktree)"
1395
+ echo " loki sandbox start --docker-desktop ./prd.md # Force Docker Desktop microVM"
1396
+ echo " loki sandbox start --docker ./prd.md # Force Docker container mode"
1155
1397
  echo " loki sandbox start --worktree # Force worktree mode"
1156
1398
  echo " loki sandbox prompt 'start the app and show URL' # Send prompt"
1157
1399
  echo " loki sandbox serve # Start dev server"
@@ -1175,6 +1417,7 @@ main() {
1175
1417
  local args=()
1176
1418
  while [[ $# -gt 0 ]]; do
1177
1419
  case "$1" in
1420
+ --docker-desktop) mode="docker-desktop"; shift ;;
1178
1421
  --docker) mode="docker"; shift ;;
1179
1422
  --worktree) mode="worktree"; shift ;;
1180
1423
  --auto) mode="auto"; shift ;;
@@ -1185,63 +1428,95 @@ main() {
1185
1428
  # Detect sandbox mode for commands that need it
1186
1429
  local sandbox_mode=""
1187
1430
  case "$command" in
1188
- start|stop|status|prompt)
1431
+ start|stop|status|prompt|shell|logs|run|serve|test|phase)
1189
1432
  sandbox_mode=$(detect_sandbox_mode "$mode") || exit 1
1190
1433
  ;;
1191
1434
  esac
1192
1435
 
1193
1436
  case "$command" in
1194
1437
  start)
1195
- if [[ "$sandbox_mode" == "docker" ]]; then
1438
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1439
+ start_docker_desktop_sandbox ${args[@]+"${args[@]}"}
1440
+ elif [[ "$sandbox_mode" == "docker" ]]; then
1196
1441
  start_sandbox ${args[@]+"${args[@]}"}
1197
1442
  else
1198
1443
  start_worktree_sandbox ${args[@]+"${args[@]}"}
1199
1444
  fi
1200
1445
  ;;
1201
1446
  stop)
1202
- if [[ "$sandbox_mode" == "docker" ]]; then
1447
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1448
+ stop_docker_desktop_sandbox
1449
+ elif [[ "$sandbox_mode" == "docker" ]]; then
1203
1450
  stop_sandbox
1204
1451
  else
1205
1452
  stop_worktree_sandbox
1206
1453
  fi
1207
1454
  ;;
1208
1455
  status)
1209
- if [[ "$sandbox_mode" == "docker" ]]; then
1456
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1457
+ docker_desktop_sandbox_status
1458
+ elif [[ "$sandbox_mode" == "docker" ]]; then
1210
1459
  sandbox_status
1211
1460
  else
1212
1461
  worktree_sandbox_status
1213
1462
  fi
1214
1463
  ;;
1215
1464
  logs)
1216
- sandbox_logs ${args[@]+"${args[@]}"}
1465
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1466
+ docker_desktop_sandbox_logs ${args[@]+"${args[@]}"}
1467
+ else
1468
+ sandbox_logs ${args[@]+"${args[@]}"}
1469
+ fi
1217
1470
  ;;
1218
1471
  shell)
1219
- sandbox_shell
1472
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1473
+ docker_desktop_sandbox_shell
1474
+ else
1475
+ sandbox_shell
1476
+ fi
1220
1477
  ;;
1221
1478
  build)
1222
1479
  sandbox_build
1223
1480
  ;;
1224
1481
  prompt)
1225
- if [[ "$sandbox_mode" == "docker" ]]; then
1482
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1483
+ docker_desktop_sandbox_prompt ${args[@]+"${args[@]}"}
1484
+ elif [[ "$sandbox_mode" == "docker" ]]; then
1226
1485
  sandbox_prompt ${args[@]+"${args[@]}"}
1227
1486
  else
1228
1487
  worktree_sandbox_prompt ${args[@]+"${args[@]}"}
1229
1488
  fi
1230
1489
  ;;
1231
1490
  run)
1232
- sandbox_run ${args[@]+"${args[@]}"}
1491
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1492
+ docker_desktop_sandbox_run ${args[@]+"${args[@]}"}
1493
+ else
1494
+ sandbox_run ${args[@]+"${args[@]}"}
1495
+ fi
1233
1496
  ;;
1234
1497
  cleanup)
1235
1498
  cleanup_worktrees
1236
1499
  ;;
1237
1500
  serve)
1238
- sandbox_serve ${args[@]+"${args[@]}"}
1501
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1502
+ docker_desktop_sandbox_run "npm start 2>/dev/null || python3 -m http.server ${args[0]:-3000}"
1503
+ else
1504
+ sandbox_serve ${args[@]+"${args[@]}"}
1505
+ fi
1239
1506
  ;;
1240
1507
  test)
1241
- sandbox_test ${args[@]+"${args[@]}"}
1508
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1509
+ docker_desktop_sandbox_run "npm test 2>/dev/null || python3 -m pytest 2>/dev/null || echo 'No test runner found'"
1510
+ else
1511
+ sandbox_test ${args[@]+"${args[@]}"}
1512
+ fi
1242
1513
  ;;
1243
1514
  phase)
1244
- sandbox_phase
1515
+ if [[ "$sandbox_mode" == "docker-desktop" ]]; then
1516
+ docker_desktop_sandbox_run "bash ${PROJECT_DIR}/autonomy/loki status"
1517
+ else
1518
+ sandbox_phase
1519
+ fi
1245
1520
  ;;
1246
1521
  expose)
1247
1522
  sandbox_expose ${args[@]+"${args[@]}"}
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "5.28.1"
10
+ __version__ = "5.29.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -2,7 +2,7 @@
2
2
 
3
3
  Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v5.28.1
5
+ **Version:** v5.29.0
6
6
 
7
7
  ---
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "5.28.1",
3
+ "version": "5.29.0",
4
4
  "description": "Multi-agent autonomous startup system for Claude Code, Codex CLI, and Gemini CLI",
5
5
  "keywords": [
6
6
  "claude",