loki-mode 7.6.1 → 7.6.3

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 a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v7.6.1
6
+ # Loki Mode v7.6.3
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -381,4 +381,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
381
381
 
382
382
  ---
383
383
 
384
- **v7.6.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
384
+ **v7.6.3 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.6.1
1
+ 7.6.3
package/autonomy/loki CHANGED
@@ -1869,6 +1869,23 @@ except (json.JSONDecodeError, OSError): pass
1869
1869
 
1870
1870
  # Kill orphaned processes from crashed sessions
1871
1871
  cmd_cleanup() {
1872
+ # v7.6.2 B-13 fix: --help must print help, not run cleanup as a side effect.
1873
+ case "${1:-}" in
1874
+ --help|-h|help)
1875
+ echo -e "${BOLD}Loki Mode -- cleanup orphaned processes${NC}"
1876
+ echo ""
1877
+ echo "Usage: loki cleanup [options]"
1878
+ echo ""
1879
+ echo "Scans \$LOKI_DIR/pids/ for stale PID registrations from prior runs"
1880
+ echo "and kills processes whose PID file points at a dead process."
1881
+ echo ""
1882
+ echo "Options:"
1883
+ echo " --help, -h Show this help and exit"
1884
+ echo ""
1885
+ echo "Side effects: kills processes registered under .loki/pids/."
1886
+ return 0
1887
+ ;;
1888
+ esac
1872
1889
  local pids_dir="$LOKI_DIR/pids"
1873
1890
  local killed=0
1874
1891
  local stale=0
@@ -1949,6 +1966,23 @@ cmd_cleanup() {
1949
1966
 
1950
1967
  # Pause after current session
1951
1968
  cmd_pause() {
1969
+ # v7.6.2 B-13 fix: --help must print help, not act on session state.
1970
+ case "${1:-}" in
1971
+ --help|-h|help)
1972
+ echo -e "${BOLD}Loki Mode -- pause active session${NC}"
1973
+ echo ""
1974
+ echo "Usage: loki pause [options]"
1975
+ echo ""
1976
+ echo "Marks the active session as paused. The runner detects this on"
1977
+ echo "the next iteration boundary and halts cleanly until 'loki resume'."
1978
+ echo ""
1979
+ echo "Options:"
1980
+ echo " --help, -h Show this help and exit"
1981
+ echo ""
1982
+ echo "See also: loki resume, loki stop"
1983
+ return 0
1984
+ ;;
1985
+ esac
1952
1986
  if [ ! -d "$LOKI_DIR" ]; then
1953
1987
  echo -e "${YELLOW}No .loki directory found.${NC}"
1954
1988
  echo "No active session to pause."
@@ -1990,6 +2024,23 @@ cmd_pause() {
1990
2024
 
1991
2025
  # Resume paused execution
1992
2026
  cmd_resume() {
2027
+ # v7.6.2 B-13 fix: --help must print help, not act on session state.
2028
+ case "${1:-}" in
2029
+ --help|-h|help)
2030
+ echo -e "${BOLD}Loki Mode -- resume paused session${NC}"
2031
+ echo ""
2032
+ echo "Usage: loki resume [options]"
2033
+ echo ""
2034
+ echo "Clears the paused flag and lets the autonomous runner continue"
2035
+ echo "from where 'loki pause' stopped it."
2036
+ echo ""
2037
+ echo "Options:"
2038
+ echo " --help, -h Show this help and exit"
2039
+ echo ""
2040
+ echo "See also: loki pause, loki start"
2041
+ return 0
2042
+ ;;
2043
+ esac
1993
2044
  if [ ! -d "$LOKI_DIR" ]; then
1994
2045
  echo -e "${YELLOW}No .loki directory found.${NC}"
1995
2046
  echo "No session to resume. Start a session with: loki start"
@@ -2428,6 +2479,25 @@ print(json.dumps(result, indent=2))
2428
2479
 
2429
2480
  # Session statistics
2430
2481
  cmd_stats() {
2482
+ # v7.6.2 B-13 fix: --help must print help, not render the stats panel.
2483
+ case "${1:-}" in
2484
+ --help|-h|help)
2485
+ echo -e "${BOLD}Loki Mode -- session statistics${NC}"
2486
+ echo ""
2487
+ echo "Usage: loki stats [options]"
2488
+ echo ""
2489
+ echo "Prints session-level statistics: tasks completed, iterations,"
2490
+ echo "tokens used, cost, council votes, gate verdicts."
2491
+ echo ""
2492
+ echo "Options:"
2493
+ echo " --json JSON output (machine-readable)"
2494
+ echo " --efficiency Include cost/token efficiency breakdown"
2495
+ echo " --help, -h Show this help and exit"
2496
+ echo ""
2497
+ echo "See also: loki kpis, loki status"
2498
+ return 0
2499
+ ;;
2500
+ esac
2431
2501
  local show_json=false
2432
2502
  local show_efficiency=false
2433
2503
 
@@ -4083,6 +4153,23 @@ cmd_web_status() {
4083
4153
 
4084
4154
  # Import GitHub issues
4085
4155
  cmd_import() {
4156
+ # v7.6.2 B-13 fix: --help must print help, not start an import.
4157
+ case "${1:-}" in
4158
+ --help|-h|help)
4159
+ echo -e "${BOLD}Loki Mode -- import GitHub issues into the queue${NC}"
4160
+ echo ""
4161
+ echo "Usage: loki import [options]"
4162
+ echo ""
4163
+ echo "Imports issues from the current repo's GitHub project into"
4164
+ echo ".loki/queue/ so loki start picks them up as tasks."
4165
+ echo ""
4166
+ echo "Options:"
4167
+ echo " --help, -h Show this help and exit"
4168
+ echo ""
4169
+ echo "Side effects: makes GitHub API calls, writes to .loki/queue/."
4170
+ return 0
4171
+ ;;
4172
+ esac
4086
4173
  if [ ! -d "$LOKI_DIR" ]; then
4087
4174
  mkdir -p "$LOKI_DIR/queue"
4088
4175
  fi
@@ -6289,6 +6376,23 @@ cmd_config_path() {
6289
6376
 
6290
6377
  # Set up skill symlinks for all providers
6291
6378
  cmd_setup_skill() {
6379
+ # v7.6.2 B-13 fix: --help must print help, not install skills.
6380
+ case "${1:-}" in
6381
+ --help|-h|help)
6382
+ echo -e "${BOLD}Loki Mode -- install Loki skill into provider CLIs${NC}"
6383
+ echo ""
6384
+ echo "Usage: loki setup-skill [options]"
6385
+ echo ""
6386
+ echo "Installs the Loki Mode skill into each detected provider CLI's"
6387
+ echo "skills directory: ~/.claude/skills/, ~/.codex/skills/, etc."
6388
+ echo ""
6389
+ echo "Options:"
6390
+ echo " --help, -h Show this help and exit"
6391
+ echo ""
6392
+ echo "Side effects: writes symlinks/files under ~/.<provider>/skills/loki-mode/."
6393
+ return 0
6394
+ ;;
6395
+ esac
6292
6396
  echo -e "${BOLD}Loki Mode Skill Setup${NC}"
6293
6397
  echo ""
6294
6398
 
@@ -7231,6 +7335,18 @@ SENTRUX_RULES_EOF
7231
7335
 
7232
7336
  # Show version
7233
7337
  cmd_version() {
7338
+ # v7.6.2 B-13 fix: --help prints help; bare invocation prints version.
7339
+ case "${1:-}" in
7340
+ --help|-h|help)
7341
+ echo -e "${BOLD}Loki Mode -- print version${NC}"
7342
+ echo ""
7343
+ echo "Usage: loki version"
7344
+ echo ""
7345
+ echo "Prints 'Loki Mode vX.Y.Z' from the VERSION file shipped with"
7346
+ echo "the package. Equivalent to 'loki --version' and 'loki -v'."
7347
+ return 0
7348
+ ;;
7349
+ esac
7234
7350
  echo "Loki Mode v$(get_version)"
7235
7351
  }
7236
7352
 
@@ -8131,6 +8247,33 @@ cmd_demo() {
8131
8247
 
8132
8248
  # Quick mode - lightweight single-task execution
8133
8249
  cmd_quick() {
8250
+ # v7.6.3 B-11 fix: --help previously fell through to provider invocation
8251
+ # (task_desc="--help") which hung the CLI for 10+ seconds. Explicit guard.
8252
+ case "${1:-}" in
8253
+ --help|-h|help)
8254
+ echo -e "${BOLD}Loki Mode -- quick lightweight execution${NC}"
8255
+ echo ""
8256
+ echo "Usage: loki quick \"description of what to do\""
8257
+ echo ""
8258
+ echo "Runs Loki with a lightweight execution profile: 3 iterations max,"
8259
+ echo "no quality council, no completion gate. Best for tiny tasks."
8260
+ echo ""
8261
+ echo "Examples:"
8262
+ echo " loki quick \"add dark mode to this React app\""
8263
+ echo " loki quick \"fix the login bug in auth.js\""
8264
+ echo " loki quick \"add input validation to the signup form\""
8265
+ echo " loki quick \"write unit tests for the API endpoints\""
8266
+ echo ""
8267
+ echo "Options:"
8268
+ echo " --help, -h Show this help and exit"
8269
+ echo ""
8270
+ echo "Environment:"
8271
+ echo " LOKI_MAX_ITERATIONS Override the default 3-iteration cap"
8272
+ echo ""
8273
+ echo "See also: loki start (full RARV cycle), loki run (alias for start)"
8274
+ return 0
8275
+ ;;
8276
+ esac
8134
8277
  if [ $# -eq 0 ]; then
8135
8278
  echo -e "${RED}Error: No task description provided${NC}"
8136
8279
  echo ""
@@ -12135,10 +12278,10 @@ main() {
12135
12278
  cmd_cleanup "$@"
12136
12279
  ;;
12137
12280
  pause)
12138
- cmd_pause
12281
+ cmd_pause "$@"
12139
12282
  ;;
12140
12283
  resume)
12141
- cmd_resume
12284
+ cmd_resume "$@"
12142
12285
  ;;
12143
12286
  status)
12144
12287
  cmd_status "$@"
@@ -12156,6 +12299,27 @@ main() {
12156
12299
  cmd_logs "$@"
12157
12300
  ;;
12158
12301
  serve)
12302
+ # v7.6.2 B-12 fix: 'serve --help' previously routed to 'cmd_api start --help'
12303
+ # which started the dashboard as a side effect instead of printing help.
12304
+ case "${1:-}" in
12305
+ --help|-h|help)
12306
+ echo -e "${BOLD}Loki Mode -- start dashboard API server${NC}"
12307
+ echo ""
12308
+ echo "Usage: loki serve [options]"
12309
+ echo ""
12310
+ echo "Alias for 'loki api start'. Starts the dashboard HTTP API"
12311
+ echo "server (FastAPI, port 57374 by default)."
12312
+ echo ""
12313
+ echo "Options:"
12314
+ echo " --host HOST Bind host (default: 127.0.0.1)"
12315
+ echo " --port PORT Bind port (default: 57374)"
12316
+ echo " --help, -h Show this help and exit"
12317
+ echo ""
12318
+ echo "Side effects: starts a long-running HTTP server bound to a TCP port."
12319
+ echo "Stop with: loki dashboard stop"
12320
+ return 0
12321
+ ;;
12322
+ esac
12159
12323
  cmd_api start "$@"
12160
12324
  ;;
12161
12325
  api)
@@ -12168,7 +12332,7 @@ main() {
12168
12332
  cmd_notify "$@"
12169
12333
  ;;
12170
12334
  import)
12171
- cmd_import
12335
+ cmd_import "$@"
12172
12336
  ;;
12173
12337
  github)
12174
12338
  cmd_github "$@"
@@ -12313,7 +12477,7 @@ main() {
12313
12477
  cmd_code "$@"
12314
12478
  ;;
12315
12479
  version|--version|-v)
12316
- cmd_version
12480
+ cmd_version "$@"
12317
12481
  ;;
12318
12482
  completions)
12319
12483
  cmd_completions "$@"
package/autonomy/run.sh CHANGED
@@ -5634,13 +5634,29 @@ enforce_static_analysis() {
5634
5634
  if [ "$_ts_project_mode" -eq 1 ]; then
5635
5635
  continue
5636
5636
  fi
5637
+ # v7.6.2 B-18 fix: previously skipped TS/TSX files when
5638
+ # tsc wasn't on PATH, leaving them silently unchecked.
5639
+ # Now fall back to `npx --yes -p typescript@latest tsc`
5640
+ # (uses the cached npm install), then to `bun tsc`
5641
+ # (Bun has built-in TypeScript), before giving up.
5637
5642
  if command -v tsc &>/dev/null; then
5638
5643
  tsc --noEmit --allowJs --jsx preserve --target esnext "$f" 2>&1 || {
5639
5644
  findings=$((findings + 1))
5640
5645
  details="${details}TS syntax error: $f. "
5641
5646
  }
5647
+ elif command -v bun &>/dev/null; then
5648
+ # Bun has built-in TypeScript via `bun --check`.
5649
+ bun --check "$f" 2>&1 || {
5650
+ findings=$((findings + 1))
5651
+ details="${details}TS syntax error (bun --check): $f. "
5652
+ }
5653
+ elif command -v npx &>/dev/null; then
5654
+ npx --yes -p typescript@latest tsc --noEmit --allowJs --jsx preserve --target esnext "$f" 2>&1 || {
5655
+ findings=$((findings + 1))
5656
+ details="${details}TS syntax error (npx tsc): $f. "
5657
+ }
5642
5658
  else
5643
- log_info "Static analysis: skipping $f (tsc not on PATH; node --check cannot parse .ts/.tsx)"
5659
+ log_info "Static analysis: skipping $f (no tsc, bun, or npx available)"
5644
5660
  fi
5645
5661
  ;;
5646
5662
  *)
@@ -11439,7 +11455,22 @@ if __name__ == "__main__":
11439
11455
  # promise text appears in the iteration output.
11440
11456
  # The check_completion_promise() helper encapsulates both.
11441
11457
  # BUG-RUN-001: Use per-iteration output, not stale daily log.
11442
- if check_completion_promise "$iter_output"; then
11458
+ #
11459
+ # v7.6.2 B-17 fix: completion was firing even when code review
11460
+ # BLOCKED the iteration with Critical/High findings. That's a false
11461
+ # success signal -- review-blocked iterations cannot be considered
11462
+ # complete. Check the gate_failures accumulator for code_review and
11463
+ # refuse completion until the review passes.
11464
+ local _gate_block_for_completion=""
11465
+ case "${gate_failures:-}" in
11466
+ *code_review,*|*code_review_ESCALATED*) _gate_block_for_completion="code_review" ;;
11467
+ esac
11468
+ if [ -n "$_gate_block_for_completion" ] && check_completion_promise "$iter_output"; then
11469
+ log_warn "Completion claim rejected: code review is BLOCKED for this iteration (Critical/High findings). Fix review issues before completion."
11470
+ log_warn " Review details under .loki/quality/reviews/ ; gate_failures=${gate_failures}"
11471
+ _gate_block_for_completion=""
11472
+ # Fall through; the gate-failed loop continues normally
11473
+ elif check_completion_promise "$iter_output"; then
11443
11474
  echo ""
11444
11475
  if [ -n "$COMPLETION_PROMISE" ]; then
11445
11476
  log_header "COMPLETION PROMISE FULFILLED: $COMPLETION_PROMISE"
@@ -11551,13 +11582,57 @@ LOKI_PROVIDER_ACTIVE=0
11551
11582
  # v7.5.12: Kill provider pipeline children with SIGTERM, then SIGKILL escalation.
11552
11583
  # Uses pkill -P $$ to target direct children only (the pipeline subshells).
11553
11584
  # Returns 0 if anything was killed, 1 if no children present.
11585
+ #
11586
+ # v7.6.2 B-15 fix: previously `pkill -P $$` was indiscriminate -- it caught
11587
+ # the dashboard server (started via nohup but still parented to this shell
11588
+ # until the OS reparents it). The dashboard PID 29716 was killed mid-session
11589
+ # after "Aggregating verdicts", breaking the browser UI. Now we explicitly
11590
+ # exclude any PID registered in .loki/pids/ (dashboard, app-runner, etc.).
11554
11591
  kill_provider_child() {
11555
11592
  local killed=0
11556
- # First pass: SIGTERM to direct children of this shell. Pipeline subshells
11557
- # for `claude -p | tee | python` are direct children of $$.
11558
- if pkill -TERM -P $$ 2>/dev/null; then
11559
- killed=1
11593
+ local protected_pids=""
11594
+ # Build list of PIDs that MUST survive a provider kill (dashboard, app-runner,
11595
+ # status monitor, resource monitor). These are recorded as PID files when
11596
+ # cmd_dashboard_start / cmd_api_start spawn them.
11597
+ local pid_root="${TARGET_DIR:-.}/.loki/pids"
11598
+ if [ -d "$pid_root" ]; then
11599
+ local pid_file pid
11600
+ for pid_file in "$pid_root"/*.pid; do
11601
+ [ -f "$pid_file" ] || continue
11602
+ pid=$(cat "$pid_file" 2>/dev/null | head -1 | tr -d '[:space:]')
11603
+ if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
11604
+ protected_pids="${protected_pids} ${pid}"
11605
+ fi
11606
+ done
11607
+ fi
11608
+ # Also protect the dashboard PID file at .loki/dashboard/dashboard.pid (older path).
11609
+ local dash_pid_file="${TARGET_DIR:-.}/.loki/dashboard/dashboard.pid"
11610
+ if [ -f "$dash_pid_file" ]; then
11611
+ local dpid
11612
+ dpid=$(cat "$dash_pid_file" 2>/dev/null | head -1 | tr -d '[:space:]')
11613
+ if [ -n "$dpid" ] && kill -0 "$dpid" 2>/dev/null; then
11614
+ protected_pids="${protected_pids} ${dpid}"
11615
+ fi
11560
11616
  fi
11617
+
11618
+ # Helper: returns 0 if $1 is in protected_pids list.
11619
+ _is_protected() {
11620
+ local target="$1"
11621
+ local p
11622
+ for p in $protected_pids; do
11623
+ [ "$p" = "$target" ] && return 0
11624
+ done
11625
+ return 1
11626
+ }
11627
+
11628
+ # First pass: SIGTERM each direct child individually so we can skip protected PIDs.
11629
+ local child_pid
11630
+ for child_pid in $(pgrep -P $$ 2>/dev/null); do
11631
+ if _is_protected "$child_pid"; then
11632
+ continue
11633
+ fi
11634
+ kill -TERM "$child_pid" 2>/dev/null && killed=1
11635
+ done
11561
11636
  # Also kill provider leaf processes by name in case they were reparented.
11562
11637
  local proc
11563
11638
  for proc in claude codex aider cline; do
@@ -11567,18 +11642,27 @@ kill_provider_child() {
11567
11642
  # Brief wait for graceful exit (max ~2s).
11568
11643
  local i=0
11569
11644
  while [ $i -lt 20 ]; do
11570
- if ! pgrep -P $$ >/dev/null 2>&1; then
11645
+ local survivors=""
11646
+ for child_pid in $(pgrep -P $$ 2>/dev/null); do
11647
+ if ! _is_protected "$child_pid"; then
11648
+ survivors="${survivors} ${child_pid}"
11649
+ fi
11650
+ done
11651
+ if [ -z "$survivors" ]; then
11571
11652
  break
11572
11653
  fi
11573
11654
  sleep 0.1
11574
11655
  i=$((i + 1))
11575
11656
  done
11576
11657
 
11577
- # Escalate to SIGKILL for any survivors.
11578
- if pgrep -P $$ >/dev/null 2>&1; then
11579
- pkill -KILL -P $$ 2>/dev/null || true
11658
+ # Escalate to SIGKILL for unprotected survivors only.
11659
+ for child_pid in $(pgrep -P $$ 2>/dev/null); do
11660
+ if _is_protected "$child_pid"; then
11661
+ continue
11662
+ fi
11663
+ kill -KILL "$child_pid" 2>/dev/null
11580
11664
  killed=1
11581
- fi
11665
+ done
11582
11666
 
11583
11667
  LOKI_PROVIDER_ACTIVE=0
11584
11668
  if [ $killed -eq 1 ]; then
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.6.1"
10
+ __version__ = "7.6.3"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -1339,14 +1339,22 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
1339
1339
  <div class="card-label">App Runner</div>
1340
1340
  <div class="card-value small-text">${this._data.status==="running"||this._data.status==="autonomous"?"Waiting...":"Not started"}</div>
1341
1341
  </div>
1342
- `;let a={running:"var(--loki-green, #22c55e)",starting:"var(--loki-yellow, #f59e0b)",crashed:"var(--loki-red, #ef4444)",stopped:"var(--loki-text-muted, #a1a1aa)"}[t.status]||"var(--loki-text-muted)",i=t.status==="running"?"active":t.status==="crashed"?"error":"offline",s=(t.status||"unknown").toUpperCase(),r=t.port?`:${t.port}`:"";return`
1342
+ `;let a={running:"var(--loki-green, #22c55e)",starting:"var(--loki-yellow, #f59e0b)",crashed:"var(--loki-red, #ef4444)",stopped:"var(--loki-text-muted, #a1a1aa)"}[t.status]||"var(--loki-text-muted)",i=t.status==="running"?"active":t.status==="crashed"?"error":"offline",s=(t.status||"unknown").toUpperCase(),r=t.port?`:${t.port}`:"",o=t.url&&typeof t.url=="string"?t.url:null;!o&&t.port&&t.status==="running"&&(o=`http://localhost:${t.port}`);let n=`
1343
+ <div class="card-label">App Runner${o?' <span style="font-size:10px;color:var(--loki-text-muted);">(click to open)</span>':""}</div>
1344
+ <div class="card-value small-text">
1345
+ <span class="status-dot ${i}"></span>
1346
+ ${s}${r}
1347
+ </div>
1348
+ ${t.method?`<div style="font-size:10px;color:var(--loki-text-muted);margin-top:2px;">${this._escapeHtml(t.method)}</div>`:""}
1349
+ `;return o?`
1350
+ <a class="overview-card overview-card-link" href="${this._escapeHtml(o)}" target="_blank" rel="noopener noreferrer"
1351
+ style="text-decoration:none;color:inherit;display:block;cursor:pointer;"
1352
+ title="Open ${this._escapeHtml(o)} in new tab">
1353
+ ${n}
1354
+ </a>
1355
+ `:`
1343
1356
  <div class="overview-card">
1344
- <div class="card-label">App Runner</div>
1345
- <div class="card-value small-text">
1346
- <span class="status-dot ${i}"></span>
1347
- ${s}${r}
1348
- </div>
1349
- ${t.method?`<div style="font-size:10px;color:var(--loki-text-muted);margin-top:2px;">${this._escapeHtml(t.method)}</div>`:""}
1357
+ ${n}
1350
1358
  </div>
1351
1359
  `}_renderPlaywrightCard(){let t=this._playwrightResults;if(!t||t==="null"||!t.verified_at)return`
1352
1360
  <div class="overview-card">
@@ -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:** v7.6.1
5
+ **Version:** v7.6.3
6
6
 
7
7
  ---
8
8
 
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var b=(K,$)=>{for(var z in $)_7(K,z,{get:$[z],enumerable:!0,configurable:!0,set:P7.bind($,z)})};var L=(K,$)=>()=>(K&&($=K(K=0)),$);var V1=import.meta.require;var e1={};b(e1,{lokiDir:()=>P,homeLokiDir:()=>k1,findRepoRootForVersion:()=>N1,REPO_ROOT:()=>u});import{resolve as f,dirname as S1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(f(K,"VERSION"))&&J1(f(K,"autonomy/run.sh")))return K;let z=S1(K);if(z===K)break;K=z}return f(i1,"..","..","..")}function N1(K){let $=K;for(let z=0;z<6;z++){if(J1(f($,"VERSION"))&&J1(f($,"autonomy/run.sh")))return $;let Q=S1($);if(Q===$)break;$=Q}return f(K,"..","..","..")}function P(){return process.env.LOKI_DIR??f(process.cwd(),".loki")}function k1(){return f(R7(),".loki")}var i1,u;var y=L(()=>{i1=S1(L7(import.meta.url));u=E7()});import{readFileSync as x7}from"fs";import{resolve as F7,dirname as w7}from"path";import{fileURLToPath as S7}from"url";function G1(){if(o!==null)return o;let K="7.6.1";if(typeof K==="string"&&K.length>0)return o=K,o;try{let $=w7(S7(import.meta.url)),z=N1($);o=x7(F7(z,"VERSION"),"utf-8").trim()}catch{o="unknown"}return o}var o=null;var D1=L(()=>{y()});var $0={};b($0,{runOrThrow:()=>N7,run:()=>w,commandVersion:()=>D7,commandExists:()=>h,ShellError:()=>C1});async function w(K,$={}){let z=Bun.spawn({cmd:[...K],stdout:"pipe",stderr:"pipe",env:$.env?{...process.env,...$.env}:process.env,cwd:$.cwd}),Q,X;if($.timeoutMs&&$.timeoutMs>0)Q=setTimeout(()=>{try{z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{z.kill("SIGKILL")}catch{}},2000)},$.timeoutMs);try{let[H,Z,q]=await Promise.all([new Response(z.stdout).text(),new Response(z.stderr).text(),z.exited]);return{stdout:H,stderr:Z,exitCode:q}}finally{if(Q)clearTimeout(Q);if(X)clearTimeout(X)}}async function N7(K,$={}){let z=await w(K,$);if(z.exitCode!==0)throw new C1(`command failed (${z.exitCode}): ${K.join(" ")}`,z.exitCode,z.stdout,z.stderr);return z}async function h(K){let $=k7(K),z=await w(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(z.exitCode===0)return z.stdout.trim()||null;return null}function k7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function D7(K,$="--version"){if(!await h(K))return null;let Q=await w([K,$],{timeoutMs:5000});if(Q.exitCode!==0)return null;return((Q.stdout||Q.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var C1;var p=L(()=>{C1=class C1 extends Error{message;exitCode;stdout;stderr;constructor(K,$,z,Q){super(K);this.message=K;this.exitCode=$;this.stdout=z;this.stderr=Q;this.name="ShellError"}}});function c(K){return C7?"":K}var C7,R,D,E,O6,O,k,x,W;var n=L(()=>{C7=(process.env.NO_COLOR??"").length>0;R=c("\x1B[0;31m"),D=c("\x1B[0;32m"),E=c("\x1B[1;33m"),O6=c("\x1B[0;34m"),O=c("\x1B[0;36m"),k=c("\x1B[1m"),x=c("\x1B[2m"),W=c("\x1B[0m")});import{existsSync as c7}from"fs";async function r(){if(z1!==void 0)return z1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return z1=K,K;let $=await h("python3.12");if($)return z1=$,$;let z=await h("python3");return z1=z,z}async function a(K,$={}){let z=await r();if(!z)return{stdout:"",stderr:"python3 not found",exitCode:127};return w([z,"-c",K],$)}var z1;var Q1=L(()=>{p()});var G0={};b(G0,{runStatus:()=>z5});import{existsSync as S,readFileSync as Z1,readdirSync as H0,statSync as W0}from"fs";import{resolve as F,basename as a7}from"path";async function r7(){if(await h("jq"))return!0;return process.stdout.write(`${R}Error: jq is required but not installed.${W}
2
+ var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var b=(K,$)=>{for(var z in $)_7(K,z,{get:$[z],enumerable:!0,configurable:!0,set:P7.bind($,z)})};var L=(K,$)=>()=>(K&&($=K(K=0)),$);var V1=import.meta.require;var e1={};b(e1,{lokiDir:()=>P,homeLokiDir:()=>k1,findRepoRootForVersion:()=>N1,REPO_ROOT:()=>u});import{resolve as f,dirname as S1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(f(K,"VERSION"))&&J1(f(K,"autonomy/run.sh")))return K;let z=S1(K);if(z===K)break;K=z}return f(i1,"..","..","..")}function N1(K){let $=K;for(let z=0;z<6;z++){if(J1(f($,"VERSION"))&&J1(f($,"autonomy/run.sh")))return $;let Q=S1($);if(Q===$)break;$=Q}return f(K,"..","..","..")}function P(){return process.env.LOKI_DIR??f(process.cwd(),".loki")}function k1(){return f(R7(),".loki")}var i1,u;var y=L(()=>{i1=S1(L7(import.meta.url));u=E7()});import{readFileSync as x7}from"fs";import{resolve as F7,dirname as w7}from"path";import{fileURLToPath as S7}from"url";function G1(){if(o!==null)return o;let K="7.6.3";if(typeof K==="string"&&K.length>0)return o=K,o;try{let $=w7(S7(import.meta.url)),z=N1($);o=x7(F7(z,"VERSION"),"utf-8").trim()}catch{o="unknown"}return o}var o=null;var D1=L(()=>{y()});var $0={};b($0,{runOrThrow:()=>N7,run:()=>w,commandVersion:()=>D7,commandExists:()=>h,ShellError:()=>C1});async function w(K,$={}){let z=Bun.spawn({cmd:[...K],stdout:"pipe",stderr:"pipe",env:$.env?{...process.env,...$.env}:process.env,cwd:$.cwd}),Q,X;if($.timeoutMs&&$.timeoutMs>0)Q=setTimeout(()=>{try{z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{z.kill("SIGKILL")}catch{}},2000)},$.timeoutMs);try{let[H,Z,q]=await Promise.all([new Response(z.stdout).text(),new Response(z.stderr).text(),z.exited]);return{stdout:H,stderr:Z,exitCode:q}}finally{if(Q)clearTimeout(Q);if(X)clearTimeout(X)}}async function N7(K,$={}){let z=await w(K,$);if(z.exitCode!==0)throw new C1(`command failed (${z.exitCode}): ${K.join(" ")}`,z.exitCode,z.stdout,z.stderr);return z}async function h(K){let $=k7(K),z=await w(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(z.exitCode===0)return z.stdout.trim()||null;return null}function k7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function D7(K,$="--version"){if(!await h(K))return null;let Q=await w([K,$],{timeoutMs:5000});if(Q.exitCode!==0)return null;return((Q.stdout||Q.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var C1;var p=L(()=>{C1=class C1 extends Error{message;exitCode;stdout;stderr;constructor(K,$,z,Q){super(K);this.message=K;this.exitCode=$;this.stdout=z;this.stderr=Q;this.name="ShellError"}}});function c(K){return C7?"":K}var C7,R,D,E,O6,O,k,x,W;var n=L(()=>{C7=(process.env.NO_COLOR??"").length>0;R=c("\x1B[0;31m"),D=c("\x1B[0;32m"),E=c("\x1B[1;33m"),O6=c("\x1B[0;34m"),O=c("\x1B[0;36m"),k=c("\x1B[1m"),x=c("\x1B[2m"),W=c("\x1B[0m")});import{existsSync as c7}from"fs";async function r(){if(z1!==void 0)return z1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return z1=K,K;let $=await h("python3.12");if($)return z1=$,$;let z=await h("python3");return z1=z,z}async function a(K,$={}){let z=await r();if(!z)return{stdout:"",stderr:"python3 not found",exitCode:127};return w([z,"-c",K],$)}var z1;var Q1=L(()=>{p()});var G0={};b(G0,{runStatus:()=>z5});import{existsSync as S,readFileSync as Z1,readdirSync as H0,statSync as W0}from"fs";import{resolve as F,basename as a7}from"path";async function r7(){if(await h("jq"))return!0;return process.stdout.write(`${R}Error: jq is required but not installed.${W}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
@@ -534,4 +534,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
534
534
  `),2}default:return process.stderr.write(`Unknown command: ${$}
535
535
  `),process.stderr.write(j7),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var z6=await $6(Bun.argv.slice(2));process.exit(z6);
536
536
 
537
- //# debugId=F0683D8581DBAEE664756E2164756E21
537
+ //# debugId=EA52FD3F3F640F2E64756E2164756E21
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.6.1'
60
+ __version__ = '7.6.3'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "7.6.1",
3
+ "version": "7.6.3",
4
4
  "description": "Loki Mode by Autonomi. Multi-agent autonomous SDLC framework. Spec to deployed app: PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief. 4 AI providers (Claude Code, OpenAI Codex, Cline, Aider). 11 quality gates.",
5
5
  "keywords": [
6
6
  "agent",