loki-mode 7.37.1 → 7.38.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: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 11 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v7.37.1
6
+ # Loki Mode v7.38.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -398,4 +398,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
398
398
 
399
399
  ---
400
400
 
401
- **v7.37.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
401
+ **v7.38.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.37.1
1
+ 7.38.0
@@ -379,6 +379,105 @@ loki_ultrareview_enabled() {
379
379
  [ "${LOKI_ULTRAREVIEW:-0}" = "1" ]
380
380
  }
381
381
 
382
+ # ---------- v7.38.0 Dynamic Workflows (ultracode) gates ----------
383
+ # Claude Code "Dynamic Workflows" are JS orchestration scripts Claude writes that
384
+ # fan out into many background subagents. They are triggered by the `ultracode`
385
+ # keyword in a prompt and fire under `claude -p` (verified empirically: a headless
386
+ # workflow returned "The workflow finished"). They are:
387
+ # - Claude-PROVIDER-ONLY (no Codex/Cline/Aider equivalent),
388
+ # - require claude CLI >= 2.1.154,
389
+ # - cost meaningfully MORE than a normal run (a trivial workflow observed at
390
+ # ~$0.71 vs ~$0.01 for a plain read; there is NO price API so we never quote
391
+ # a dollar figure -- we disclose the cost CLASS only),
392
+ # - disablable via CLAUDE_CODE_DISABLE_WORKFLOWS=1 or the `disableWorkflows`
393
+ # setting in any Claude settings.json.
394
+ #
395
+ # These predicates mirror loki_ultrareview_supported/enabled exactly: read-only,
396
+ # side-effect free, the ONLY policy surface for the optional `loki ultracode`
397
+ # passthrough and the Phase 2 opt-in analysis dispatch. The user typing
398
+ # `loki ultracode` (or setting LOKI_USE_CLAUDE_WORKFLOWS=1) IS the consent signal.
399
+
400
+ # Minimum claude CLI version that ships Dynamic Workflows.
401
+ LOKI_WORKFLOWS_MIN_VERSION="${LOKI_WORKFLOWS_MIN_VERSION:-2.1.154}"
402
+
403
+ # Parse the installed claude CLI semantic version (e.g. "2.1.177") to stdout, or
404
+ # empty on any failure. Mirrors the `claude --version | sed` pattern already used
405
+ # at autonomy/loki:7888. Cached per-process so we do not shell out repeatedly.
406
+ _loki_claude_version() {
407
+ if [ -z "${__LOKI_CLAUDE_VERSION_CACHE:-}" ]; then
408
+ if command -v claude >/dev/null 2>&1; then
409
+ __LOKI_CLAUDE_VERSION_CACHE="$(claude --version 2>/dev/null | head -1 | sed 's/[^0-9.]//g' | head -1)"
410
+ fi
411
+ # Sentinel so an empty real result does not re-shell every call.
412
+ __LOKI_CLAUDE_VERSION_CACHE="${__LOKI_CLAUDE_VERSION_CACHE:-__none__}"
413
+ export __LOKI_CLAUDE_VERSION_CACHE
414
+ fi
415
+ [ "$__LOKI_CLAUDE_VERSION_CACHE" = "__none__" ] && return 0
416
+ printf '%s' "$__LOKI_CLAUDE_VERSION_CACHE"
417
+ }
418
+
419
+ # Dotted-version >= compare: returns 0 when $1 >= $2, 1 otherwise. Pure, no
420
+ # external tools beyond awk (always present). Pads missing components with 0.
421
+ _loki_version_ge() {
422
+ local have="${1:-}" want="${2:-}"
423
+ [ -z "$have" ] && return 1
424
+ [ -z "$want" ] && return 0
425
+ awk -v a="$have" -v b="$want" '
426
+ function cmp(x, y, na, nb, i, n, xi, yi) {
427
+ na = split(x, A, ".")
428
+ nb = split(y, B, ".")
429
+ n = (na > nb) ? na : nb
430
+ for (i = 1; i <= n; i++) {
431
+ xi = (i <= na) ? A[i] + 0 : 0
432
+ yi = (i <= nb) ? B[i] + 0 : 0
433
+ if (xi > yi) return 1
434
+ if (xi < yi) return -1
435
+ }
436
+ return 0
437
+ }
438
+ BEGIN { exit (cmp(a, b) >= 0) ? 0 : 1 }
439
+ '
440
+ }
441
+
442
+ # True when CLAUDE_CODE_DISABLE_WORKFLOWS=1 OR a `disableWorkflows` setting is
443
+ # active in any Claude settings source. Best-effort, read-only (not a full JSON
444
+ # parse, but rejects the obvious cases). Returns 0 (disabled) / 1 (not disabled).
445
+ _loki_workflows_disabled() {
446
+ [ "${CLAUDE_CODE_DISABLE_WORKFLOWS:-0}" = "1" ] && return 0
447
+ local f
448
+ for f in "$HOME/.claude/settings.json" "$HOME/.config/claude/settings.json" \
449
+ "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/settings.json" \
450
+ "$PWD/.claude/settings.json" "$PWD/.claude/settings.local.json"; do
451
+ [ -f "$f" ] || continue
452
+ # Match "disableWorkflows": true (tolerating whitespace around the colon).
453
+ grep -Eq '"disableWorkflows"[[:space:]]*:[[:space:]]*true' "$f" 2>/dev/null && return 0
454
+ done
455
+ return 1
456
+ }
457
+
458
+ # Capability gate: is the active provider Claude AND the claude CLI present AND
459
+ # version >= the workflows minimum AND workflows not disabled? Returns 0 when
460
+ # workflows can run, 1 otherwise (so callers emit an honest message + clean exit).
461
+ loki_workflows_supported() {
462
+ # Provider must be Claude (Tier 1). Workflows are Claude-only.
463
+ [ "${LOKI_PROVIDER:-claude}" = "claude" ] || return 1
464
+ command -v claude >/dev/null 2>&1 || return 1
465
+ _loki_workflows_disabled && return 1
466
+ local ver
467
+ ver="$(_loki_claude_version)"
468
+ _loki_version_ge "$ver" "$LOKI_WORKFLOWS_MIN_VERSION" || return 1
469
+ return 0
470
+ }
471
+
472
+ # Non-interactive opt-in: is LOKI_USE_CLAUDE_WORKFLOWS=1 set? This is the env knob
473
+ # that turns ON the Phase 2 read-only-analysis workflow dispatch. Default OFF. Any
474
+ # value other than the exact "1" returns 1 so only an explicit opt-in counts. This
475
+ # is independent of the `loki ultracode` passthrough (which is itself an explicit
476
+ # user invocation and does not require this flag).
477
+ loki_workflows_enabled() {
478
+ [ "${LOKI_USE_CLAUDE_WORKFLOWS:-0}" = "1" ]
479
+ }
480
+
382
481
  # ---------------------------------------------------------------------------
383
482
  # Session-continuity Phase 2 (GitHub #165) -- LOKI_RESUME_SESSION recovery resume
384
483
  #
package/autonomy/loki CHANGED
@@ -668,6 +668,7 @@ show_help() {
668
668
  echo "Verify / trust:"
669
669
  echo " verify [base] Deterministic PR verification (CI-gate exit codes)"
670
670
  echo " review [opts] Standalone code review with quality gates"
671
+ echo " ultracode \"task\" Run a task as a native Claude Code Dynamic Workflow (opt-in, Claude-only)"
671
672
  echo " trust [cmd] Visible trust trajectory; 'trust detail' for metrics"
672
673
  echo ""
673
674
  echo "Observe:"
@@ -14354,6 +14355,9 @@ main() {
14354
14355
  review)
14355
14356
  cmd_review "$@"
14356
14357
  ;;
14358
+ ultracode)
14359
+ cmd_ultracode "$@"
14360
+ ;;
14357
14361
  optimize)
14358
14362
  cmd_optimize "$@"
14359
14363
  ;;
@@ -14638,6 +14642,182 @@ _review_ultra() {
14638
14642
  return $?
14639
14643
  }
14640
14644
 
14645
+ # v7.38.0: optional native Claude Code Dynamic Workflow passthrough
14646
+ # (`loki ultracode "<task>"`). Structurally identical to _review_ultra (issue
14647
+ # #168): opt-in, capability-gated, cost-class disclosed, Claude-provider-only,
14648
+ # clean exit on any unsupported path. PURE passthrough -- Loki adds NO
14649
+ # orchestration of its own; it prepends the `ultracode` keyword to the prompt and
14650
+ # routes through `claude -p`, which fires the workflow runtime.
14651
+ #
14652
+ # Consent model (mirrors _review_ultra):
14653
+ # - The cost-CLASS disclosure ALWAYS prints. There is NO price API, so we never
14654
+ # quote a dollar figure (that would be a lie).
14655
+ # - Interactive TTY without --yes: prompt, default NO.
14656
+ # - Non-TTY/CI without --yes (and no LOKI_USE_CLAUDE_WORKFLOWS=1): REFUSE with
14657
+ # exit 2 and ZERO workflow invocation (the no-silent-bill guard).
14658
+ # - --yes or LOKI_USE_CLAUDE_WORKFLOWS=1 proceeds without prompting.
14659
+ # Args: <assume_yes> <task...>
14660
+ _run_ultracode() {
14661
+ local assume_yes="${1:-false}"
14662
+ shift || true
14663
+ local task="$*"
14664
+
14665
+ if [ -z "$task" ]; then
14666
+ echo -e "${RED}Error: loki ultracode requires a task description.${NC}" >&2
14667
+ echo "Usage: loki ultracode \"<task>\" [--yes]" >&2
14668
+ return 1
14669
+ fi
14670
+
14671
+ # Make the workflow gate predicates available even though autonomy/loki does
14672
+ # not source claude-flags.sh globally (same on-demand pattern as
14673
+ # _review_ultra). Degrade honestly if the lib is missing.
14674
+ if ! declare -F loki_workflows_supported >/dev/null 2>&1; then
14675
+ local _wf_lib=""
14676
+ if [ -f "${_LOKI_SCRIPT_DIR}/lib/claude-flags.sh" ]; then
14677
+ _wf_lib="${_LOKI_SCRIPT_DIR}/lib/claude-flags.sh"
14678
+ elif [ -f "$(dirname "$0")/lib/claude-flags.sh" ]; then
14679
+ _wf_lib="$(dirname "$0")/lib/claude-flags.sh"
14680
+ fi
14681
+ if [ -n "$_wf_lib" ]; then
14682
+ # shellcheck source=autonomy/lib/claude-flags.sh
14683
+ . "$_wf_lib" 2>/dev/null || true
14684
+ fi
14685
+ fi
14686
+
14687
+ # 1. Provider gate: workflows are Claude-only. On Codex/Cline/Aider, print the
14688
+ # honest message and exit CLEANLY (0) with ZERO invocation. Never break the
14689
+ # other providers.
14690
+ local _provider="${LOKI_PROVIDER:-claude}"
14691
+ if [ "$_provider" != "claude" ]; then
14692
+ echo -e "${YELLOW}loki ultracode: Claude provider only.${NC}" >&2
14693
+ echo "Workflows need the Claude provider and claude CLI >= 2.1.154." >&2
14694
+ echo "Active provider is '${_provider}'; nothing was run." >&2
14695
+ return 0
14696
+ fi
14697
+
14698
+ # 2. claude CLI present at all?
14699
+ if ! command -v claude >/dev/null 2>&1; then
14700
+ echo -e "${RED}Error: 'claude' CLI not found on PATH.${NC}" >&2
14701
+ echo "Workflows need the Claude provider and claude CLI >= 2.1.154." >&2
14702
+ return 1
14703
+ fi
14704
+
14705
+ # 3. Capability gate: provider==claude AND CLI present AND version >= 2.1.154
14706
+ # AND workflows not disabled. Honest message + clean exit if unsupported.
14707
+ if ! declare -F loki_workflows_supported >/dev/null 2>&1 \
14708
+ || ! loki_workflows_supported; then
14709
+ echo -e "${YELLOW}loki ultracode: workflows unavailable on this setup.${NC}" >&2
14710
+ echo "Workflows need the Claude provider and claude CLI >= 2.1.154" >&2
14711
+ echo "(and must not be disabled via CLAUDE_CODE_DISABLE_WORKFLOWS or the" >&2
14712
+ echo "disableWorkflows setting). Nothing was run." >&2
14713
+ return 0
14714
+ fi
14715
+
14716
+ # 4. Cost-CLASS disclosure -- ALWAYS printed, even with --yes, so spend is
14717
+ # never hidden. NO dollar figure (there is no price API); cost-CLASS only.
14718
+ echo -e "${BOLD}loki ultracode${NC} - native Claude Code Dynamic Workflow (optional)" >&2
14719
+ echo "" >&2
14720
+ echo -e "${YELLOW}Workflows spawn many agents and cost meaningfully more than a normal${NC}" >&2
14721
+ echo -e "${YELLOW}run; this is a Claude Code feature billed as normal usage.${NC}" >&2
14722
+ echo "" >&2
14723
+
14724
+ # 5. Consent. LOKI_USE_CLAUDE_WORKFLOWS=1 is the non-interactive opt-in
14725
+ # equivalent of --yes for THIS command.
14726
+ local proceed=false
14727
+ if [ "$assume_yes" = true ]; then
14728
+ proceed=true
14729
+ elif declare -F loki_workflows_enabled >/dev/null 2>&1 && loki_workflows_enabled; then
14730
+ proceed=true
14731
+ else
14732
+ local uc_interactive=true
14733
+ if [ ! -t 0 ] || [ -n "${CI:-}" ]; then
14734
+ uc_interactive=false
14735
+ fi
14736
+ if [ "$uc_interactive" = true ]; then
14737
+ local ans=""
14738
+ echo -n "Run the workflow now? [y/N] " >&2
14739
+ read -r ans </dev/tty 2>/dev/null || ans=""
14740
+ if [[ "$ans" =~ ^[Yy] ]]; then
14741
+ proceed=true
14742
+ else
14743
+ echo "Cancelled. Nothing was spent." >&2
14744
+ return 0
14745
+ fi
14746
+ else
14747
+ # Non-TTY/CI without --yes: never hang; refuse with exit 2 and make
14748
+ # ZERO workflow calls (the no-silent-bill guard).
14749
+ echo "workflows need confirmation; re-run with --yes (or set LOKI_USE_CLAUDE_WORKFLOWS=1) to proceed non-interactively" >&2
14750
+ return 2
14751
+ fi
14752
+ fi
14753
+
14754
+ [ "$proceed" = true ] || { echo "Cancelled. Nothing was spent." >&2; return 0; }
14755
+
14756
+ # 6. Invoke the Claude provider once with the prompt PREFIXED by "ultracode: "
14757
+ # so the workflow runtime fires. ALWAYS opus per project policy (planning-
14758
+ # grade fan-out). The keyword prefix is the only supported, stable trigger;
14759
+ # Loki never authors a workflow script itself.
14760
+ local uc_prompt="ultracode: ${task}"
14761
+ local uc_argv=("-p" "$uc_prompt" "--model" "opus")
14762
+
14763
+ echo -e "${DIM}Running: claude -p \"ultracode: ...\" --model opus${NC}" >&2
14764
+ echo "" >&2
14765
+ claude "${uc_argv[@]}"
14766
+ return $?
14767
+ }
14768
+
14769
+ # v7.38.0: `loki ultracode "<task>"` command. Thin opt-in surface that routes a
14770
+ # task through a native Claude Code Dynamic Workflow. See _run_ultracode.
14771
+ cmd_ultracode() {
14772
+ local uc_assume_yes=false
14773
+ local uc_args=()
14774
+ while [[ $# -gt 0 ]]; do
14775
+ case "$1" in
14776
+ --help|-h)
14777
+ echo -e "${BOLD}loki ultracode${NC} - run a task as a native Claude Code Dynamic Workflow"
14778
+ echo ""
14779
+ echo "Usage: loki ultracode \"<task>\" [--yes]"
14780
+ echo ""
14781
+ echo "Prepends the 'ultracode' keyword to your task and routes it through"
14782
+ echo "the Claude provider, firing Claude Code's Dynamic Workflow runtime"
14783
+ echo "(many background subagents fanning out on a read/research/audit task)."
14784
+ echo ""
14785
+ echo "This is a PASSTHROUGH: Loki adds no orchestration of its own. It is"
14786
+ echo "OPT-IN, default OFF, and Claude-provider-only. The council, the 11"
14787
+ echo "quality gates, the evidence gate, and the RARV loop are untouched."
14788
+ echo ""
14789
+ echo "Requirements:"
14790
+ echo " - Active provider is Claude (Tier 1)"
14791
+ echo " - claude CLI >= 2.1.154"
14792
+ echo " - Workflows not disabled (CLAUDE_CODE_DISABLE_WORKFLOWS / disableWorkflows)"
14793
+ echo "On any unmet requirement: an honest message prints and nothing runs."
14794
+ echo ""
14795
+ echo "Cost: workflows spawn many agents and cost meaningfully more than a"
14796
+ echo "normal run; this is a Claude Code feature billed as normal usage."
14797
+ echo "There is no price API, so no dollar figure is shown."
14798
+ echo ""
14799
+ echo "Options:"
14800
+ echo " --yes, -y Skip the confirmation prompt (consent to the cost)"
14801
+ echo " --help, -h Show this help"
14802
+ echo ""
14803
+ echo "Environment:"
14804
+ echo " LOKI_USE_CLAUDE_WORKFLOWS=1 Non-interactive opt-in (like --yes)"
14805
+ echo " CLAUDE_CODE_DISABLE_WORKFLOWS=1 Disable workflows entirely"
14806
+ echo ""
14807
+ echo "Examples:"
14808
+ echo " loki ultracode \"audit this repo for dead code\""
14809
+ echo " loki ultracode \"research the top 5 auth libraries for Node\" --yes"
14810
+ return 0
14811
+ ;;
14812
+ --yes|-y) uc_assume_yes=true; shift ;;
14813
+ --) shift; while [[ $# -gt 0 ]]; do uc_args+=("$1"); shift; done ;;
14814
+ *) uc_args+=("$1"); shift ;;
14815
+ esac
14816
+ done
14817
+ _run_ultracode "$uc_assume_yes" "${uc_args[@]}"
14818
+ return $?
14819
+ }
14820
+
14641
14821
  # Standalone code review - diff-based quality gates (v6.20.0)
14642
14822
  cmd_review() {
14643
14823
  local review_staged=false
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.37.1"
10
+ __version__ = "7.38.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/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v7.37.1
5
+ **Version:** v7.38.0
6
6
 
7
7
  ---
8
8
 
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.37.1";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=QQ(ZQ(import.meta.url)),Z=d$(Q);$$=e6($Q(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var n$=L(()=>{C()});var C1={};h(C1,{runOrThrow:()=>zQ,run:()=>j,commandVersion:()=>KQ,commandExists:()=>f,ShellError:()=>a$});async function j($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[W,K,U]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:W,stderr:K,exitCode:U}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function zQ($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=XQ($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function XQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function KQ($,Q="--version"){if(!await f($))return null;let z=await j([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var a$;var d=L(()=>{a$=class a$ extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function a($){return WQ?"":$}var WQ,T,S,I,TZ,w,R,y,q;var c=L(()=>{WQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),I=a("\x1B[1;33m"),TZ=a("\x1B[0;34m"),w=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),q=a("\x1B[0m")});import{existsSync as TQ}from"fs";async function Q$(){if(B$!==void 0)return B$;let $="/opt/homebrew/bin/python3.12";if(TQ($))return B$=$,$;let Q=await f("python3.12");if(Q)return B$=Q,Q;let Z=await f("python3");return B$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B$;var W$=L(()=>{d()});var t1={};h(t1,{runStatus:()=>gQ});import{existsSync as v,readFileSync as U$,readdirSync as l1,statSync as d1}from"fs";import{resolve as D,basename as xQ}from"path";import{homedir as NQ}from"os";async function DQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${q}
2
+ var n6=Object.defineProperty;var a6=($)=>$;function s6($,Q){this[$]=a6.bind(null,Q)}var h=($,Q)=>{for(var Z in Q)n6($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:s6.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var K$=import.meta.require;var S1={};h(S1,{lokiDir:()=>P,homeLokiDir:()=>o$,findRepoRootForVersion:()=>d$,REPO_ROOT:()=>m});import{resolve as n,dirname as l$}from"path";import{fileURLToPath as t6}from"url";import{existsSync as P$}from"fs";import{homedir as r6}from"os";function i6(){let $=N1;for(let Q=0;Q<6;Q++){if(P$(n($,"VERSION"))&&P$(n($,"autonomy/run.sh")))return $;let Z=l$($);if(Z===$)break;$=Z}return n(N1,"..","..","..")}function d$($){let Q=$;for(let Z=0;Z<6;Z++){if(P$(n(Q,"VERSION"))&&P$(n(Q,"autonomy/run.sh")))return Q;let z=l$(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o$(){return n(r6(),".loki")}var N1,m;var C=L(()=>{N1=l$(t6(import.meta.url));m=i6()});import{readFileSync as e6}from"fs";import{resolve as $Q,dirname as QQ}from"path";import{fileURLToPath as ZQ}from"url";function F$(){if($$!==null)return $$;let $="7.38.0";if(typeof $==="string"&&$.length>0)return $$=$,$$;try{let Q=QQ(ZQ(import.meta.url)),Z=d$(Q);$$=e6($Q(Z,"VERSION"),"utf-8").trim()}catch{$$="unknown"}return $$}var $$=null;var n$=L(()=>{C()});var C1={};h(C1,{runOrThrow:()=>zQ,run:()=>j,commandVersion:()=>KQ,commandExists:()=>f,ShellError:()=>a$});async function j($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[W,K,U]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:W,stderr:K,exitCode:U}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function zQ($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a$(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=XQ($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function XQ($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function KQ($,Q="--version"){if(!await f($))return null;let z=await j([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var a$;var d=L(()=>{a$=class a$ extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function a($){return WQ?"":$}var WQ,T,S,I,TZ,w,R,y,q;var c=L(()=>{WQ=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),S=a("\x1B[0;32m"),I=a("\x1B[1;33m"),TZ=a("\x1B[0;34m"),w=a("\x1B[0;36m"),R=a("\x1B[1m"),y=a("\x1B[2m"),q=a("\x1B[0m")});import{existsSync as TQ}from"fs";async function Q$(){if(B$!==void 0)return B$;let $="/opt/homebrew/bin/python3.12";if(TQ($))return B$=$,$;let Q=await f("python3.12");if(Q)return B$=Q,Q;let Z=await f("python3");return B$=Z,Z}async function Z$($,Q={}){let Z=await Q$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B$;var W$=L(()=>{d()});var t1={};h(t1,{runStatus:()=>gQ});import{existsSync as v,readFileSync as U$,readdirSync as l1,statSync as d1}from"fs";import{resolve as D,basename as xQ}from"path";import{homedir as NQ}from"os";async function DQ(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${q}
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)
@@ -789,4 +789,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
789
789
  `),2}default:return process.stderr.write(`Unknown command: ${Q}
790
790
  `),process.stderr.write(o6),2}}p1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var ZZ=await QZ(Bun.argv.slice(2));process.exit(ZZ);
791
791
 
792
- //# debugId=4D62C09E1CA3E64A64756E2164756E21
792
+ //# debugId=CD214D71C449250864756E2164756E21
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.37.1'
60
+ __version__ = '7.38.0'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "7.37.1",
4
+ "version": "7.38.0",
5
5
  "description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 11 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
6
6
  "keywords": [
7
7
  "agent",