loki-mode 7.7.6 → 7.7.8

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.7.6
6
+ # Loki Mode v7.7.8
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.7.6 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
384
+ **v7.7.8 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.7.6
1
+ 7.7.8
package/autonomy/loki CHANGED
@@ -14259,20 +14259,25 @@ except Exception as e:
14259
14259
  # .loki/metrics/efficiency/iter-*.json. Unify: prefer the
14260
14260
  # canonical kpis source; fall back to the legacy file for
14261
14261
  # backward compat with pre-v7.6.6 sessions.
14262
+ # v7.7.7 fix: also check iteration-*.json (the canonical filename)
14263
+ # in addition to iter-*.json. Use a portable glob check (no compgen)
14264
+ # so the function works in any POSIX shell, not just bash.
14262
14265
  local _eff_dir=".loki/metrics/efficiency"
14263
14266
  local _legacy_file=".loki/memory/token_economics.json"
14264
14267
  local _have_iters=0
14265
14268
  if [ -d "$_eff_dir" ]; then
14266
- if compgen -G "$_eff_dir/iter-*.json" >/dev/null 2>&1; then
14269
+ if ls "$_eff_dir"/iteration-*.json >/dev/null 2>&1 || ls "$_eff_dir"/iter-*.json >/dev/null 2>&1; then
14267
14270
  _have_iters=1
14268
14271
  fi
14269
14272
  fi
14270
14273
  if [ "$_have_iters" -eq 1 ]; then
14271
14274
  PYTHONPATH="${SKILL_DIR}${PYTHONPATH:+:$PYTHONPATH}" python3 - <<'PYEOF' 2>/dev/null
14272
14275
  import json, glob, os, sys
14273
- files = sorted(glob.glob('.loki/metrics/efficiency/iter-*.json'))
14276
+ # v7.7.7 fix: canonical filename is `iteration-N.json`, NOT `iter-N.json`.
14277
+ # We glob both for compat with any older runs.
14278
+ files = sorted(set(glob.glob('.loki/metrics/efficiency/iteration-*.json') + glob.glob('.loki/metrics/efficiency/iter-*.json')))
14274
14279
  totals = {
14275
- 'source': '.loki/metrics/efficiency/iter-*.json',
14280
+ 'source': '.loki/metrics/efficiency/iteration-*.json',
14276
14281
  'iterations': len(files),
14277
14282
  'total_input_tokens': 0,
14278
14283
  'total_output_tokens': 0,
package/autonomy/run.sh CHANGED
@@ -8826,35 +8826,87 @@ auto_capture_episode() {
8826
8826
  # rolled the new files into HEAD. Now diff against the iteration-start
8827
8827
  # SHA captured at the top of the retry loop. Falls back to HEAD~1 if the
8828
8828
  # start SHA env is unset (older direct callers).
8829
+ # v7.7.7 fix: previously only captured files when target_dir was a git
8830
+ # repo. Real-user test on /tmp/loki-validate (no git init) produced
8831
+ # `files_modified: []` because git rev-parse failed silently and the
8832
+ # fallback also required git. Now: detect git-vs-non-git up front, and
8833
+ # for non-git dirs use a `find` snapshot diff against the timestamp
8834
+ # captured when loki created .loki/ (initialized_at). Skips standard
8835
+ # noise dirs (.loki, node_modules, .git, venv, .venv, dist, build).
8829
8836
  local files_modified=""
8830
8837
  local _diff_base="${_LOKI_ITER_START_SHA:-}"
8831
- if [ -z "$_diff_base" ]; then
8832
- _diff_base=$(cd "$target_dir" && git rev-parse HEAD~1 2>/dev/null || echo "")
8833
- fi
8834
- if [ -n "$_diff_base" ]; then
8835
- files_modified=$(cd "$target_dir" && git diff --name-only "$_diff_base" HEAD 2>/dev/null | head -50 | tr '\n' '|' || true)
8836
- # Also include unstaged changes (in case auto-commit didn't run)
8837
- local _unstaged
8838
- _unstaged=$(cd "$target_dir" && git diff --name-only HEAD 2>/dev/null | head -20 | tr '\n' '|' || true)
8839
- if [ -n "$_unstaged" ]; then
8840
- files_modified="${files_modified}${_unstaged}"
8838
+ local _is_git=0
8839
+ if (cd "$target_dir" && git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
8840
+ _is_git=1
8841
+ fi
8842
+ if [ "$_is_git" -eq 1 ]; then
8843
+ if [ -z "$_diff_base" ]; then
8844
+ _diff_base=$(cd "$target_dir" && git rev-parse HEAD~1 2>/dev/null || echo "")
8845
+ fi
8846
+ if [ -n "$_diff_base" ]; then
8847
+ files_modified=$(cd "$target_dir" && git diff --name-only "$_diff_base" HEAD 2>/dev/null | head -50 | tr '\n' '|' || true)
8848
+ # Also include unstaged changes (in case auto-commit didn't run)
8849
+ local _unstaged
8850
+ _unstaged=$(cd "$target_dir" && git diff --name-only HEAD 2>/dev/null | head -20 | tr '\n' '|' || true)
8851
+ if [ -n "$_unstaged" ]; then
8852
+ files_modified="${files_modified}${_unstaged}"
8853
+ fi
8854
+ else
8855
+ # Git repo but no prior commit (e.g. fresh init) -- list untracked.
8856
+ files_modified=$(cd "$target_dir" && git ls-files --others --exclude-standard 2>/dev/null | head -50 | tr '\n' '|' || true)
8841
8857
  fi
8842
8858
  else
8843
- # No git history yet (initial commit) -- list all tracked + untracked.
8844
- files_modified=$(cd "$target_dir" && git ls-files --others --exclude-standard 2>/dev/null | head -50 | tr '\n' '|' || true)
8859
+ # NOT a git repo: snapshot diff via find. Use .loki/ mtime as the
8860
+ # iteration-start reference (loki creates .loki/ on session start).
8861
+ # `-newer` on directory mtime gives a rough but useful set of files
8862
+ # modified DURING this session. Skip noise dirs.
8863
+ local _ref_file="${target_dir}/.loki/state/orchestrator.json"
8864
+ if [ ! -f "$_ref_file" ]; then
8865
+ _ref_file="${target_dir}/.loki"
8866
+ fi
8867
+ if [ -e "$_ref_file" ]; then
8868
+ files_modified=$(cd "$target_dir" && find . -type f -newer "$_ref_file" \
8869
+ -not -path './.loki/*' \
8870
+ -not -path './node_modules/*' \
8871
+ -not -path './.git/*' \
8872
+ -not -path './venv/*' \
8873
+ -not -path './.venv/*' \
8874
+ -not -path './dist/*' \
8875
+ -not -path './build/*' \
8876
+ 2>/dev/null | head -50 | sed 's|^\./||' | tr '\n' '|' || true)
8877
+ fi
8878
+ # Belt-and-suspenders: if find returned nothing, fall back to a
8879
+ # plain listing of non-noise files (every visible file, capped at 50).
8880
+ if [ -z "$files_modified" ]; then
8881
+ files_modified=$(cd "$target_dir" && find . -maxdepth 3 -type f \
8882
+ -not -path './.loki/*' \
8883
+ -not -path './node_modules/*' \
8884
+ -not -path './.git/*' \
8885
+ 2>/dev/null | head -50 | sed 's|^\./||' | tr '\n' '|' || true)
8886
+ fi
8845
8887
  fi
8846
8888
 
8847
8889
  # Collect last git commit if any
8848
8890
  local git_commit=""
8849
8891
  git_commit=$(cd "$target_dir" && git rev-parse --short HEAD 2>/dev/null || true)
8850
8892
 
8851
- # v7.6.4 B-3a fix: aggregate per-iteration efficiency metrics into the
8852
- # episode so `tokens_used` / `cost_usd` / `input_tokens` / `output_tokens`
8853
- # are no longer always 0. Source: `.loki/metrics/efficiency/iter-N.json`
8854
- # (same source `loki kpis` reads from).
8855
- local _iter_metrics_file="$target_dir/.loki/metrics/efficiency/iter-${iteration}.json"
8893
+ # v7.6.4 B-3a fix + v7.7.7 filename fix: the actual filename is
8894
+ # `iteration-N.json` (not `iter-N.json` as v7.6.4 erroneously assumed).
8895
+ # Real-user test on /tmp/loki-validate showed `iteration-1.json` in
8896
+ # .loki/metrics/efficiency/. We now check both the canonical name and
8897
+ # the legacy `iter-N.json` for backward compat with any older runs.
8898
+ local _iter_metrics_file=""
8899
+ for _candidate in \
8900
+ "$target_dir/.loki/metrics/efficiency/iteration-${iteration}.json" \
8901
+ "$target_dir/.loki/metrics/efficiency/iter-${iteration}.json" \
8902
+ ; do
8903
+ if [ -f "$_candidate" ]; then
8904
+ _iter_metrics_file="$_candidate"
8905
+ break
8906
+ fi
8907
+ done
8856
8908
  local _iter_tokens_in=0 _iter_tokens_out=0 _iter_cost=0
8857
- if [ -f "$_iter_metrics_file" ]; then
8909
+ if [ -n "$_iter_metrics_file" ]; then
8858
8910
  _iter_tokens_in=$(python3 -c "import json; d=json.load(open('$_iter_metrics_file')); print(int(d.get('input_tokens', 0) or 0))" 2>/dev/null || echo 0)
8859
8911
  _iter_tokens_out=$(python3 -c "import json; d=json.load(open('$_iter_metrics_file')); print(int(d.get('output_tokens', 0) or 0))" 2>/dev/null || echo 0)
8860
8912
  _iter_cost=$(python3 -c "import json; d=json.load(open('$_iter_metrics_file')); print(float(d.get('cost_usd', 0) or 0))" 2>/dev/null || echo 0)
@@ -9344,6 +9396,14 @@ build_prompt() {
9344
9396
  # and to the dashboard/Purple Lab UI.
9345
9397
  local usage_doc_instruction="USAGE_DOC_REQUIRED: Before invoking loki_complete_task (or touching .loki/signals/COMPLETION_REQUESTED), write USAGE.md at the project root. Detect the stack from package.json/requirements.txt/Cargo.toml/go.mod/etc. and include these sections: (1) Prerequisites (runtimes, ports, env vars), (2) Install (exact command, e.g. 'npm install' or 'pip install -r requirements.txt'), (3) Start (exact command, e.g. 'npm start' or 'python server.py'), (4) Verify -- 2 to 3 copy-paste commands the user can run to confirm it works (curl examples for APIs with expected output, browser URL for web UIs, command invocation for CLIs), (5) Stop (Ctrl+C or 'lsof -ti:PORT | xargs kill -9' for backgrounded servers). Keep it under 100 lines, plain Markdown, no emojis. If USAGE.md already exists and is accurate, leave it; otherwise create or update it."
9346
9398
 
9399
+ # v7.7.8: LSP grounding instruction. The lsp-proxy MCP server (auto-mounted
9400
+ # when a language server is on PATH) exposes four tools that ground the
9401
+ # agent in real workspace symbols instead of hallucinated names. Before
9402
+ # writing any reference to a symbol the agent has not already read with
9403
+ # the Read tool, prefer mcp__loki-mode-lsp-proxy__lsp_check_exists. This
9404
+ # is the single most leveraged grounding primitive per OpenCode research.
9405
+ local lsp_grounding_instruction="LSP_GROUNDING: When the loki-mode-lsp-proxy MCP server is available, prefer LSP tools for symbol verification BEFORE writing code that references those symbols. Workflow: (1) Need to call \`foo.bar()\` you have not already read? -> mcp__loki-mode-lsp-proxy__lsp_check_exists with symbol='bar' (sub-200ms when cached). If exists:false, do NOT write the call -- use mcp__loki-mode-lsp-proxy__lsp_workspace_symbols with the concept name to find the real symbol, or use Read to see the actual API. (2) Just edited a file? -> mcp__loki-mode-lsp-proxy__lsp_get_diagnostics on that file to see new errors before the next iteration. (3) Need to jump to a definition by name (no file:line known)? -> mcp__loki-mode-lsp-proxy__lsp_find_definition_by_name. Skip these tools silently when the server is not available -- check the tool list, do not retry on errors. Goal: eliminate hallucinated API calls before they ship."
9406
+
9347
9407
  # Load existing context if resuming
9348
9408
  local context_injection=""
9349
9409
  if [ $retry -gt 0 ]; then
@@ -9673,15 +9733,15 @@ except Exception:
9673
9733
  else
9674
9734
  if [ $retry -eq 0 ]; then
9675
9735
  if [ -n "$prd" ]; then
9676
- echo "Loki Mode with PRD at $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $usage_doc_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9736
+ echo "Loki Mode with PRD at $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $usage_doc_instruction $lsp_grounding_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9677
9737
  else
9678
- echo "Loki Mode. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $analysis_instruction $rarv_instruction $memory_instruction $usage_doc_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9738
+ echo "Loki Mode. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $analysis_instruction $rarv_instruction $memory_instruction $usage_doc_instruction $lsp_grounding_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9679
9739
  fi
9680
9740
  else
9681
9741
  if [ -n "$prd" ]; then
9682
- echo "Loki Mode - Resume iteration #$iteration (retry #$retry). PRD: $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $usage_doc_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9742
+ echo "Loki Mode - Resume iteration #$iteration (retry #$retry). PRD: $prd. $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section $rarv_instruction $memory_instruction $usage_doc_instruction $lsp_grounding_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9683
9743
  else
9684
- echo "Loki Mode - Resume iteration #$iteration (retry #$retry). $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section Use .loki/generated-prd.md if exists. $rarv_instruction $memory_instruction $usage_doc_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9744
+ echo "Loki Mode - Resume iteration #$iteration (retry #$retry). $human_directive $gate_failure_context $queue_tasks $bmad_context $openspec_context $mirofish_context $magic_context $checklist_status $app_runner_info $playwright_info $memory_context_section Use .loki/generated-prd.md if exists. $rarv_instruction $memory_instruction $usage_doc_instruction $lsp_grounding_instruction $completion_instruction $sdlc_instruction $autonomous_suffix"
9685
9745
  fi
9686
9746
  fi
9687
9747
  fi
@@ -9723,6 +9783,7 @@ except Exception:
9723
9783
  printf 'You are a coding assistant. Analyze this codebase and suggest improvements. Write working code and commit changes.\n'
9724
9784
  fi
9725
9785
  printf '%s\n' "$usage_doc_instruction"
9786
+ printf '%s\n' "$lsp_grounding_instruction"
9726
9787
  printf '</loki_system>\n'
9727
9788
  printf '[CACHE_BREAKPOINT]\n'
9728
9789
 
@@ -9754,6 +9815,7 @@ except Exception:
9754
9815
  printf '%s\n' "$autonomous_suffix"
9755
9816
  printf '%s\n' "$memory_instruction"
9756
9817
  printf '%s\n' "$usage_doc_instruction"
9818
+ printf '%s\n' "$lsp_grounding_instruction"
9757
9819
  # For codebase-analysis mode (no PRD), analysis_instruction is part of the
9758
9820
  # static prefix so it remains cache-stable.
9759
9821
  if [ -z "$prd" ]; then
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.7.6"
10
+ __version__ = "7.7.8"
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:** v7.7.6
5
+ **Version:** v7.7.8
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 R=(K,$)=>()=>(K&&($=K(K=0)),$);var V1=import.meta.require;var e1={};b(e1,{lokiDir:()=>P,homeLokiDir:()=>k1,findRepoRootForVersion:()=>N1,REPO_ROOT:()=>p});import{resolve as u,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(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let z=S1(K);if(z===K)break;K=z}return u(i1,"..","..","..")}function N1(K){let $=K;for(let z=0;z<6;z++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let Q=S1($);if(Q===$)break;$=Q}return u(K,"..","..","..")}function P(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var y=R(()=>{i1=S1(L7(import.meta.url));p=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(n!==null)return n;let K="7.7.6";if(typeof K==="string"&&K.length>0)return n=K,n;try{let $=w7(S7(import.meta.url)),z=N1($);n=x7(F7(z,"VERSION"),"utf-8").trim()}catch{n="unknown"}return n}var n=null;var D1=R(()=>{y()});var $0={};b($0,{runOrThrow:()=>N7,run:()=>S,commandVersion:()=>D7,commandExists:()=>D,ShellError:()=>C1});async function S(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 S(K,$);if(z.exitCode!==0)throw new C1(`command failed (${z.exitCode}): ${K.join(" ")}`,z.exitCode,z.stdout,z.stderr);return z}async function D(K){let $=k7(K),z=await S(["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 D(K))return null;let Q=await S([K,$],{timeoutMs:5000});if(Q.exitCode!==0)return null;return((Q.stdout||Q.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var C1;var c=R(()=>{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 l(K){return C7?"":K}var C7,E,C,x,O6,O,k,F,W;var a=R(()=>{C7=(process.env.NO_COLOR??"").length>0;E=l("\x1B[0;31m"),C=l("\x1B[0;32m"),x=l("\x1B[1;33m"),O6=l("\x1B[0;34m"),O=l("\x1B[0;36m"),k=l("\x1B[1m"),F=l("\x1B[2m"),W=l("\x1B[0m")});import{existsSync as c7}from"fs";async function t(){if(z1!==void 0)return z1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return z1=K,K;let $=await D("python3.12");if($)return z1=$,$;let z=await D("python3");return z1=z,z}async function s(K,$={}){let z=await t();if(!z)return{stdout:"",stderr:"python3 not found",exitCode:127};return S([z,"-c",K],$)}var z1;var Q1=R(()=>{c()});var G0={};b(G0,{runStatus:()=>z5});import{existsSync as N,readFileSync as Z1,readdirSync as H0,statSync as W0}from"fs";import{resolve as w,basename as a7}from"path";async function r7(){if(await D("jq"))return!0;return process.stdout.write(`${E}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 R=(K,$)=>()=>(K&&($=K(K=0)),$);var V1=import.meta.require;var e1={};b(e1,{lokiDir:()=>P,homeLokiDir:()=>k1,findRepoRootForVersion:()=>N1,REPO_ROOT:()=>p});import{resolve as u,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(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let z=S1(K);if(z===K)break;K=z}return u(i1,"..","..","..")}function N1(K){let $=K;for(let z=0;z<6;z++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let Q=S1($);if(Q===$)break;$=Q}return u(K,"..","..","..")}function P(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var y=R(()=>{i1=S1(L7(import.meta.url));p=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(n!==null)return n;let K="7.7.8";if(typeof K==="string"&&K.length>0)return n=K,n;try{let $=w7(S7(import.meta.url)),z=N1($);n=x7(F7(z,"VERSION"),"utf-8").trim()}catch{n="unknown"}return n}var n=null;var D1=R(()=>{y()});var $0={};b($0,{runOrThrow:()=>N7,run:()=>S,commandVersion:()=>D7,commandExists:()=>D,ShellError:()=>C1});async function S(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 S(K,$);if(z.exitCode!==0)throw new C1(`command failed (${z.exitCode}): ${K.join(" ")}`,z.exitCode,z.stdout,z.stderr);return z}async function D(K){let $=k7(K),z=await S(["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 D(K))return null;let Q=await S([K,$],{timeoutMs:5000});if(Q.exitCode!==0)return null;return((Q.stdout||Q.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var C1;var c=R(()=>{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 l(K){return C7?"":K}var C7,E,C,x,O6,O,k,F,W;var a=R(()=>{C7=(process.env.NO_COLOR??"").length>0;E=l("\x1B[0;31m"),C=l("\x1B[0;32m"),x=l("\x1B[1;33m"),O6=l("\x1B[0;34m"),O=l("\x1B[0;36m"),k=l("\x1B[1m"),F=l("\x1B[2m"),W=l("\x1B[0m")});import{existsSync as c7}from"fs";async function t(){if(z1!==void 0)return z1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return z1=K,K;let $=await D("python3.12");if($)return z1=$,$;let z=await D("python3");return z1=z,z}async function s(K,$={}){let z=await t();if(!z)return{stdout:"",stderr:"python3 not found",exitCode:127};return S([z,"-c",K],$)}var z1;var Q1=R(()=>{c()});var G0={};b(G0,{runStatus:()=>z5});import{existsSync as N,readFileSync as Z1,readdirSync as H0,statSync as W0}from"fs";import{resolve as w,basename as a7}from"path";async function r7(){if(await D("jq"))return!0;return process.stdout.write(`${E}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)
@@ -550,4 +550,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
550
550
  `),2}default:return process.stderr.write(`Unknown command: ${$}
551
551
  `),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);
552
552
 
553
- //# debugId=496D49A157EA8A9064756E2164756E21
553
+ //# debugId=7F5B17C2CD1F8DC264756E2164756E21
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.7.6'
60
+ __version__ = '7.7.8'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "7.7.6",
3
+ "version": "7.7.8",
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",