loki-mode 7.28.1 → 7.28.2

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
@@ -43,40 +43,50 @@
43
43
 
44
44
  ## Get Started in 30 Seconds
45
45
 
46
- **Prerequisites**
46
+ ```bash
47
+ bun install -g loki-mode # install (npm/brew/Docker also work, see below)
48
+ loki init my-app --template simple-todo-app # scaffold a starter PRD
49
+ cd my-app && loki start prd.md # autonomous build from the spec
50
+ ```
47
51
 
48
- Loki drives a coding agent CLI and orchestrates real builds, so it needs a few tools on your PATH. `loki doctor` checks all of these and tells you what is missing.
52
+ That is the happy path. One thing to know first: Loki drives a separate coding-agent CLI (Claude Code is the recommended one) and needs it plus a couple of common tools on your PATH. Run `loki doctor` any time and it tells you exactly what is present and what is missing, with a copy-pasteable install command for each gap.
53
+
54
+ ```bash
55
+ loki doctor # check your setup before the first build
56
+ ```
57
+
58
+ <details>
59
+ <summary><strong>What Loki needs (and what loki doctor checks)</strong></summary>
49
60
 
50
61
  Required:
51
62
 
52
- - An agent provider CLI: [Claude Code](https://docs.claude.com/en/docs/claude-code) (`claude`, Tier 1, recommended and E2E-verified - the provider Loki Mode is built for). Codex, Cline, and Aider are supported as experimental providers (wiring in place; not yet E2E-verified by us).
63
+ - An agent provider CLI: [Claude Code](https://docs.claude.com/en/docs/claude-code) (`claude`, Tier 1, recommended and E2E-verified - the provider Loki Mode is built for). Codex, Cline, and Aider are supported as experimental providers (wiring in place; not yet E2E-verified by us). Loki cannot run a build without one of these installed and authenticated.
53
64
  - Python 3.10+ (`python3`) for the dashboard, memory system, and orchestration helpers.
54
65
  - Git 2.x (`git`) for checkpoints and worktrees.
55
66
  - `curl` for installation and network calls.
56
67
 
57
68
  Recommended:
58
69
 
59
- - Bun 1.3.0+ (`bun`) for the fast runtime (the recommended install path below installs it).
70
+ - Bun 1.3.0+ (`bun`) for the fast runtime (the recommended install path above installs it).
60
71
  - Node.js 18+ and npm if you install via npm instead of Bun.
61
72
  - `jq` for nicer JSON handling in shell flows.
62
73
  - Docker if you want Loki's App Runner to run containerized projects, or to run Loki itself from the published image.
63
74
 
64
- You also need credentials for whichever provider you use (for Claude Code, an authenticated `claude` login or `ANTHROPIC_API_KEY`).
75
+ You also need credentials for whichever provider you use (for Claude Code, an authenticated `claude` login or `ANTHROPIC_API_KEY`). `loki doctor` flags a missing or unauthenticated provider as the first thing to fix.
76
+
77
+ </details>
78
+
79
+ If you do not have Bun yet:
80
+
81
+ ```bash
82
+ curl -fsSL https://bun.sh/install | bash # macOS / Linux (or: brew install oven-sh/bun/bun)
83
+ ```
65
84
 
66
- **Recommended (Bun, fastest):**
85
+ Other spec sources work the same way:
67
86
 
68
87
  ```bash
69
- # Install Bun once (skip if you already have it)
70
- curl -fsSL https://bun.sh/install | bash # macOS / Linux
71
- # or: brew install oven-sh/bun/bun
72
-
73
- bun install -g loki-mode
74
- loki doctor # verify environment
75
- loki init my-app --template simple-todo-app
76
- cd my-app
77
- loki start prd.md # autonomous build from a Markdown PRD
78
- loki start owner/repo#123 # ...or a GitHub issue
79
- loki start ./openapi.yaml # ...or an OpenAPI/YAML spec
88
+ loki start owner/repo#123 # a GitHub issue
89
+ loki start ./openapi.yaml # an OpenAPI/YAML spec
80
90
  ```
81
91
 
82
92
  Or skip scaffolding and go straight to a quick task:
@@ -91,7 +101,7 @@ loki quick "build a landing page with a signup form"
91
101
  |--------|---------|-------|
92
102
  | **Bun (recommended)** | `bun install -g loki-mode` | Fastest startup for CLI commands. |
93
103
  | **Homebrew** | `brew tap asklokesh/tap && brew install loki-mode` | Auto-installs Bun as a dep |
94
- | **Docker** | `docker pull asklokesh/loki-mode:7.28.1 && docker run --rm asklokesh/loki-mode:7.28.1 start prd.md` | Bun pre-installed in image |
104
+ | **Docker** | `docker pull asklokesh/loki-mode:7.28.2 && docker run --rm asklokesh/loki-mode:7.28.2 start prd.md` | Bun pre-installed in image |
95
105
  | **npm (compat)** | `npm install -g loki-mode` | Works without Bun (bash fallback). Migrate any time with `loki self-update --to bun`. |
96
106
 
97
107
  **Upgrading:**
@@ -151,7 +161,7 @@ The next major release sunsets the Bash runtime entirely. There is no firm calen
151
161
  | Method | Command |
152
162
  |--------|---------|
153
163
  | **Homebrew** | `brew tap asklokesh/tap && brew install loki-mode` |
154
- | **Docker** | `docker pull asklokesh/loki-mode:7.28.1` |
164
+ | **Docker** | `docker pull asklokesh/loki-mode:7.28.2` |
155
165
  | **Inside Claude Code** | `claude --dangerously-skip-permissions` then type "Loki Mode" |
156
166
  | **Git clone** | `git clone https://github.com/asklokesh/loki-mode.git` |
157
167
 
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.28.1
6
+ # Loki Mode v7.28.2
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -392,4 +392,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
392
392
 
393
393
  ---
394
394
 
395
- **v7.28.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
395
+ **v7.28.2 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.28.1
1
+ 7.28.2
package/autonomy/loki CHANGED
@@ -510,7 +510,7 @@ show_help() {
510
510
  echo "Usage: loki <command> [options]"
511
511
  echo ""
512
512
  echo "New here? Try one of these first:"
513
- echo " loki doctor Check your setup is ready (instant)"
513
+ echo " loki doctor Check your setup is ready (a few seconds)"
514
514
  echo " loki quick \"add a health endpoint\" One small task, start to finish"
515
515
  echo " loki demo Build a sample todo app end to end (real run)"
516
516
  echo " loki start ./prd.md Build from a spec (PRD file, GitHub issue, or no arg)"
@@ -675,6 +675,27 @@ show_help() {
675
675
  echo " See: $RUN_SH (header comments) for full list."
676
676
  }
677
677
 
678
+ # Tight newcomer landing for the bare `loki` invocation (no args).
679
+ # v7.28.x UX: the full 70-command table lives in `loki help`; a no-args run
680
+ # now shows only a calm ~12-line orientation so the "what do I do first"
681
+ # block is never buried under the command wall. `loki help`/`--help` are
682
+ # unchanged (still call show_help).
683
+ show_landing() {
684
+ local version
685
+ version=$(get_version)
686
+ echo -e "${BOLD}Loki Mode v$version${NC} - the spec-driven builder that verifies its own work."
687
+ echo ""
688
+ echo -e "First time here? ${CYAN}loki doctor${NC} checks your setup (an AI provider CLI is required)."
689
+ echo ""
690
+ echo "Get started:"
691
+ echo -e " ${CYAN}loki start ./prd.md${NC} Build from a spec (PRD file, GitHub issue, or no arg)"
692
+ echo -e " ${CYAN}loki demo${NC} Build a sample todo app end to end (real run)"
693
+ echo -e " ${CYAN}loki dashboard start${NC} Start the live run monitor (then: loki dashboard open)"
694
+ echo ""
695
+ echo -e "Need help? ${CYAN}loki help${NC} lists every command."
696
+ echo "Tip: preview cost and scope before building: loki plan <your-prd.md>"
697
+ }
698
+
678
699
  # Detect argument type for unified `loki start` (v6.84.0)
679
700
  # Returns one of: prd | issue | empty | unknown
680
701
  # Logic:
@@ -3369,7 +3390,7 @@ cmd_provider_set() {
3369
3390
  if [ -z "$new_provider" ]; then
3370
3391
  echo -e "${RED}Error: Provider name required${NC}"
3371
3392
  echo "Usage: loki provider set <claude|codex|cline|aider>"
3372
- exit 1
3393
+ exit 2
3373
3394
  fi
3374
3395
 
3375
3396
  # Validate provider
@@ -3923,12 +3944,16 @@ cmd_dashboard_start() {
3923
3944
 
3924
3945
  if kill -0 "$new_pid" 2>/dev/null; then
3925
3946
  local url="${url_scheme}://${host}:${port}"
3926
- echo -e "${GREEN}Dashboard server started${NC}"
3947
+ echo -e "${GREEN}Dashboard (live run monitor) started${NC}"
3927
3948
  echo ""
3928
3949
  echo " PID: $new_pid"
3929
3950
  echo " URL: $url"
3930
3951
  echo " Logs: $log_file"
3931
3952
  echo ""
3953
+ # v7.28.x UX #5: distinguish the two browser UIs up front so a newcomer
3954
+ # who wants to submit a spec does not land on the ops monitor by mistake.
3955
+ echo -e "${DIM}Looking for the project web UI to submit a spec? loki web (:${PURPLE_LAB_DEFAULT_PORT:-57375})${NC}"
3956
+ echo ""
3932
3957
  echo -e "Open in browser: ${CYAN}loki dashboard open${NC}"
3933
3958
  echo -e "Check status: ${CYAN}loki dashboard status${NC}"
3934
3959
  echo -e "Stop server: ${CYAN}loki dashboard stop${NC}"
@@ -4541,12 +4566,15 @@ cmd_web_start() {
4541
4566
  local url="http://${PURPLE_LAB_DEFAULT_HOST}:${port}/lab/"
4542
4567
 
4543
4568
  if [ "$server_ready" = true ]; then
4544
- echo -e "${GREEN}Purple Lab running at: $url${NC} (PID: $pid)"
4569
+ echo -e "${GREEN}Purple Lab (project web UI) running at: $url${NC} (PID: $pid)"
4545
4570
  else
4546
- echo -e "${YELLOW}Purple Lab starting at: $url${NC} (PID: $pid)"
4571
+ echo -e "${YELLOW}Purple Lab (project web UI) starting at: $url${NC} (PID: $pid)"
4547
4572
  echo "Server may still be loading. Refresh the browser if it does not load immediately."
4548
4573
  fi
4549
4574
  echo -e "Logs: $log_file"
4575
+ # v7.28.x UX #5: distinguish the two browser UIs so the ops monitor and the
4576
+ # spec-input web UI are never confused for each other.
4577
+ echo -e "${DIM}Looking for the live run monitor? loki dashboard (:${DASHBOARD_DEFAULT_PORT:-57374})${NC}"
4550
4578
  echo -e "Stop with: ${CYAN}loki web stop${NC}"
4551
4579
 
4552
4580
  # Open browser only after server is confirmed ready
@@ -5133,7 +5161,7 @@ cmd_issue_parse() {
5133
5161
  if [[ -z "$issue_ref" ]]; then
5134
5162
  echo -e "${RED}Error: Issue reference required${NC}"
5135
5163
  echo "Usage: loki issue parse <issue-ref>"
5136
- exit 1
5164
+ exit 2
5137
5165
  fi
5138
5166
 
5139
5167
  # Find and run issue-parser.sh
@@ -5177,7 +5205,7 @@ cmd_issue_view() {
5177
5205
  if [[ -z "$issue_ref" ]]; then
5178
5206
  echo -e "${RED}Error: Issue reference required${NC}"
5179
5207
  echo "Usage: loki issue view <issue-ref>"
5180
- exit 1
5208
+ exit 2
5181
5209
  fi
5182
5210
 
5183
5211
  # Find and run issue-parser.sh
@@ -5515,7 +5543,7 @@ cmd_run() {
5515
5543
  echo " loki run owner/repo#789 # GitHub with specific repo"
5516
5544
  echo ""
5517
5545
  echo "Run 'loki run --help' for full usage."
5518
- exit 1
5546
+ exit 2
5519
5547
  fi
5520
5548
 
5521
5549
  # Source issue provider abstraction
@@ -5994,7 +6022,7 @@ cmd_issue() {
5994
6022
  echo -e "${RED}Error: No issue number specified${NC}"
5995
6023
  echo "Usage: loki issue <number> or loki issue --number <number>"
5996
6024
  echo "Run 'loki issue --help' for full usage."
5997
- exit 1
6025
+ exit 2
5998
6026
  fi
5999
6027
 
6000
6028
  # Auto-detect repo if not specified
@@ -6912,7 +6940,7 @@ cmd_config_set() {
6912
6940
  if [[ -z "$key" || -z "$value" ]]; then
6913
6941
  echo -e "${RED}Usage: loki config set [--global] <key> <value>${NC}"
6914
6942
  echo "Run 'loki config' for list of settable keys."
6915
- return 1
6943
+ return 2
6916
6944
  fi
6917
6945
 
6918
6946
  # Determine config directory: --global writes to ~/.config/loki-mode/
@@ -7059,7 +7087,7 @@ cmd_config_get() {
7059
7087
 
7060
7088
  if [[ -z "$key" ]]; then
7061
7089
  echo -e "${RED}Usage: loki config get <key>${NC}"
7062
- return 1
7090
+ return 2
7063
7091
  fi
7064
7092
 
7065
7093
  local config_store="$LOKI_DIR/config/settings.json"
@@ -8781,7 +8809,7 @@ cmd_notify_send() {
8781
8809
  if [ -z "$message" ]; then
8782
8810
  echo -e "${RED}Error: Message required${NC}"
8783
8811
  echo "Usage: loki notify $channel <message>"
8784
- exit 1
8812
+ exit 2
8785
8813
  fi
8786
8814
 
8787
8815
  case "$channel" in
@@ -9349,7 +9377,7 @@ cmd_quick() {
9349
9377
  echo " loki quick \"fix the login bug in auth.js\""
9350
9378
  echo " loki quick \"add input validation to the signup form\""
9351
9379
  echo " loki quick \"write unit tests for the API endpoints\""
9352
- exit 1
9380
+ exit 2
9353
9381
  fi
9354
9382
 
9355
9383
  local task_desc="$*"
@@ -10692,7 +10720,7 @@ cmd_migrate_start() {
10692
10720
  echo "Specify the migration target (e.g. --target typescript, --target react, --target microservices)"
10693
10721
  echo ""
10694
10722
  echo "Run 'loki migrate --help' for usage."
10695
- return 1
10723
+ return 2
10696
10724
  fi
10697
10725
 
10698
10726
  # Validate compliance preset
@@ -11662,7 +11690,7 @@ for f in data.get('frictions', []):
11662
11690
  if [ -z "$codebase_path" ]; then
11663
11691
  echo -e "${RED}Error: Codebase path is required${NC}"
11664
11692
  echo "Usage: loki heal <path-to-codebase> [options]"
11665
- return 1
11693
+ return 2
11666
11694
  fi
11667
11695
 
11668
11696
  if [[ ! -d "$codebase_path" ]]; then
@@ -12030,7 +12058,7 @@ cmd_migrate() {
12030
12058
  echo "Usage: loki migrate <path-to-codebase> --target <target>"
12031
12059
  echo ""
12032
12060
  echo "Run 'loki migrate --help' for usage."
12033
- return 1
12061
+ return 2
12034
12062
  fi
12035
12063
 
12036
12064
  cmd_migrate_start "$codebase_path" "$target" "$plan_only" "$phase" "$parallel" "$compliance" "$dry_run" "$do_resume" "$multi_repo" "$export_report" "$no_dashboard" "$no_docs"
@@ -13333,7 +13361,7 @@ cmd_plan() {
13333
13361
  if [ -z "$prd_file" ]; then
13334
13362
  echo -e "${RED}Usage: loki plan <PRD file>${NC}"
13335
13363
  echo "Run 'loki plan --help' for usage."
13336
- return 1
13364
+ return 2
13337
13365
  fi
13338
13366
 
13339
13367
  if [ ! -f "$prd_file" ]; then
@@ -13388,7 +13416,9 @@ main() {
13388
13416
  fi
13389
13417
 
13390
13418
  if [ $# -eq 0 ]; then
13391
- show_help
13419
+ # v7.28.x UX: bare `loki` shows a tight newcomer landing, not the full
13420
+ # command wall. `loki help`/`--help` still print show_help unchanged.
13421
+ show_landing
13392
13422
  exit 0
13393
13423
  fi
13394
13424
 
@@ -17722,7 +17752,7 @@ cmd_enterprise() {
17722
17752
  if [ -z "$name" ]; then
17723
17753
  echo -e "${RED}Error: Token name required${NC}"
17724
17754
  echo "Usage: loki enterprise token generate <name> [--scopes '*'] [--expires 30]"
17725
- exit 1
17755
+ exit 2
17726
17756
  fi
17727
17757
 
17728
17758
  # Validate name is not a flag
@@ -17890,7 +17920,7 @@ else:
17890
17920
 
17891
17921
  if [ -z "$identifier" ]; then
17892
17922
  echo -e "${RED}Error: Token ID or name required${NC}"
17893
- exit 1
17923
+ exit 2
17894
17924
  fi
17895
17925
 
17896
17926
  python3 -c "
@@ -17929,7 +17959,7 @@ else:
17929
17959
 
17930
17960
  if [ -z "$identifier" ]; then
17931
17961
  echo -e "${RED}Error: Token ID or name required${NC}"
17932
- exit 1
17962
+ exit 2
17933
17963
  fi
17934
17964
 
17935
17965
  python3 -c "
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.28.1"
10
+ __version__ = "7.28.2"
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.28.1
5
+ **Version:** v7.28.2
6
6
 
7
7
  ---
8
8
 
@@ -1,6 +1,6 @@
1
1
  # Alternative Installation Methods
2
2
 
3
- The recommended installation is via npm or Homebrew (see [README](../README.md#installation)). These alternatives serve specific use cases.
3
+ The recommended installation is via npm or Homebrew (see [README](../README.md#get-started-in-30-seconds)). These alternatives serve specific use cases.
4
4
 
5
5
  ---
6
6
 
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var f8=Object.defineProperty;var u8=($)=>$;function c8($,Q){this[$]=u8.bind(null,Q)}var g=($,Q)=>{for(var Z in Q)f8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:c8.bind(Q,Z)})};var k=($,Q)=>()=>($&&(Q=$($=0)),Q);var X1=import.meta.require;var F$={};g(F$,{lokiDir:()=>P,homeLokiDir:()=>o1,findRepoRootForVersion:()=>d1,REPO_ROOT:()=>f});import{resolve as n,dirname as l1}from"path";import{fileURLToPath as p8}from"url";import{existsSync as L1}from"fs";import{homedir as l8}from"os";function d8(){let $=j$;for(let Q=0;Q<6;Q++){if(L1(n($,"VERSION"))&&L1(n($,"autonomy/run.sh")))return $;let Z=l1($);if(Z===$)break;$=Z}return n(j$,"..","..","..")}function d1($){let Q=$;for(let Z=0;Z<6;Z++){if(L1(n(Q,"VERSION"))&&L1(n(Q,"autonomy/run.sh")))return Q;let z=l1(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o1(){return n(l8(),".loki")}var j$,f;var y=k(()=>{j$=l1(p8(import.meta.url));f=d8()});import{readFileSync as o8}from"fs";import{resolve as n8,dirname as a8}from"path";import{fileURLToPath as s8}from"url";function k1(){if($1!==null)return $1;let $="7.28.1";if(typeof $==="string"&&$.length>0)return $1=$,$1;try{let Q=a8(s8(import.meta.url)),Z=d1(Q);$1=o8(n8(Z,"VERSION"),"utf-8").trim()}catch{$1="unknown"}return $1}var $1=null;var n1=k(()=>{y()});var E$={};g(E$,{runOrThrow:()=>t8,run:()=>j,commandVersion:()=>i8,commandExists:()=>v,ShellError:()=>a1});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,K;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}K=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[H,X,q]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:H,stderr:X,exitCode:q}}finally{if(z)clearTimeout(z);if(K)clearTimeout(K)}}async function t8($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function v($){let Q=r8($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function r8($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function i8($,Q="--version"){if(!await v($))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 a1;var d=k(()=>{a1=class a1 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 e8?"":$}var e8,T,N,_,KZ,A,R,h,J;var c=k(()=>{e8=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),N=a("\x1B[0;32m"),_=a("\x1B[1;33m"),KZ=a("\x1B[0;34m"),A=a("\x1B[0;36m"),R=a("\x1B[1m"),h=a("\x1B[2m"),J=a("\x1B[0m")});import{existsSync as U7}from"fs";async function Q1(){if(B1!==void 0)return B1;let $="/opt/homebrew/bin/python3.12";if(U7($))return B1=$,$;let Q=await v("python3.12");if(Q)return B1=Q,Q;let Z=await v("python3");return B1=Z,Z}async function Z1($,Q={}){let Z=await Q1();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B1;var H1=k(()=>{d()});var d$={};g(d$,{runStatus:()=>N7});import{existsSync as b,readFileSync as q1,readdirSync as v$,statSync as f$}from"fs";import{resolve as D,basename as P7}from"path";import{homedir as L7}from"os";async function j7(){if(await v("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${J}
2
+ var f8=Object.defineProperty;var u8=($)=>$;function c8($,Q){this[$]=u8.bind(null,Q)}var g=($,Q)=>{for(var Z in Q)f8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:c8.bind(Q,Z)})};var k=($,Q)=>()=>($&&(Q=$($=0)),Q);var X1=import.meta.require;var F$={};g(F$,{lokiDir:()=>P,homeLokiDir:()=>o1,findRepoRootForVersion:()=>d1,REPO_ROOT:()=>f});import{resolve as n,dirname as l1}from"path";import{fileURLToPath as p8}from"url";import{existsSync as L1}from"fs";import{homedir as l8}from"os";function d8(){let $=j$;for(let Q=0;Q<6;Q++){if(L1(n($,"VERSION"))&&L1(n($,"autonomy/run.sh")))return $;let Z=l1($);if(Z===$)break;$=Z}return n(j$,"..","..","..")}function d1($){let Q=$;for(let Z=0;Z<6;Z++){if(L1(n(Q,"VERSION"))&&L1(n(Q,"autonomy/run.sh")))return Q;let z=l1(Q);if(z===Q)break;Q=z}return n($,"..","..","..")}function P(){return process.env.LOKI_DIR??n(process.cwd(),".loki")}function o1(){return n(l8(),".loki")}var j$,f;var y=k(()=>{j$=l1(p8(import.meta.url));f=d8()});import{readFileSync as o8}from"fs";import{resolve as n8,dirname as a8}from"path";import{fileURLToPath as s8}from"url";function k1(){if($1!==null)return $1;let $="7.28.2";if(typeof $==="string"&&$.length>0)return $1=$,$1;try{let Q=a8(s8(import.meta.url)),Z=d1(Q);$1=o8(n8(Z,"VERSION"),"utf-8").trim()}catch{$1="unknown"}return $1}var $1=null;var n1=k(()=>{y()});var E$={};g(E$,{runOrThrow:()=>t8,run:()=>j,commandVersion:()=>i8,commandExists:()=>v,ShellError:()=>a1});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,K;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}K=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[H,X,q]=await Promise.all([new Response(Z.stdout).text(),new Response(Z.stderr).text(),Z.exited]);return{stdout:H,stderr:X,exitCode:q}}finally{if(z)clearTimeout(z);if(K)clearTimeout(K)}}async function t8($,Q={}){let Z=await j($,Q);if(Z.exitCode!==0)throw new a1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function v($){let Q=r8($),Z=await j(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function r8($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function i8($,Q="--version"){if(!await v($))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 a1;var d=k(()=>{a1=class a1 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 e8?"":$}var e8,T,N,_,KZ,A,R,h,J;var c=k(()=>{e8=(process.env.NO_COLOR??"").length>0;T=a("\x1B[0;31m"),N=a("\x1B[0;32m"),_=a("\x1B[1;33m"),KZ=a("\x1B[0;34m"),A=a("\x1B[0;36m"),R=a("\x1B[1m"),h=a("\x1B[2m"),J=a("\x1B[0m")});import{existsSync as U7}from"fs";async function Q1(){if(B1!==void 0)return B1;let $="/opt/homebrew/bin/python3.12";if(U7($))return B1=$,$;let Q=await v("python3.12");if(Q)return B1=Q,Q;let Z=await v("python3");return B1=Z,Z}async function Z1($,Q={}){let Z=await Q1();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return j([Z,"-c",$],Q)}var B1;var H1=k(()=>{d()});var d$={};g(d$,{runStatus:()=>N7});import{existsSync as b,readFileSync as q1,readdirSync as v$,statSync as f$}from"fs";import{resolve as D,basename as P7}from"path";import{homedir as L7}from"os";async function j7(){if(await v("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${J}
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)
@@ -787,4 +787,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
787
787
  `),2}default:return process.stderr.write(`Unknown command: ${Q}
788
788
  `),process.stderr.write(v8),2}}g$();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var l3=await p3(Bun.argv.slice(2));process.exit(l3);
789
789
 
790
- //# debugId=07839D2F23465AFE64756E2164756E21
790
+ //# debugId=C842AE10479263E664756E2164756E21
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '7.28.1'
60
+ __version__ = '7.28.2'
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.28.1",
4
+ "version": "7.28.2",
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",
@@ -1,148 +1,17 @@
1
- # PRD: Simple Todo App
1
+ # Simple Todo App
2
2
 
3
- ## Overview
4
- A minimal todo application for testing Loki Mode with a simple, well-defined scope. A single-page app called "Todos" with a React frontend, Express API, and SQLite persistence.
3
+ A tiny single-page todo app built with plain HTML, CSS, and vanilla
4
+ JavaScript in one folder. Todos are saved in the browser via localStorage so
5
+ they survive a page refresh. There is no server and no build step: opening
6
+ index.html in a browser runs the whole app.
5
7
 
6
- ## Target Users
7
- - Individual users who want a simple way to track tasks
8
- - Developers testing Loki Mode's core generation pipeline
8
+ ## What it does
9
9
 
10
- ## Features
10
+ - Add a todo by typing a title and pressing Enter.
11
+ - List every todo with a small checkbox beside it.
12
+ - Toggle a todo done or not done by clicking its checkbox.
13
+ - Remove a todo with a delete button next to it.
14
+ - Show a friendly message when the list is empty.
11
15
 
12
- ### MVP Features
13
- 1. **Add Todo** - Users can add a new todo item with a title
14
- 2. **View Todos** - Display list of all todos with completion status
15
- 3. **Complete Todo** - Mark a todo as done (toggle)
16
- 4. **Delete Todo** - Remove a todo from the list with confirmation
17
-
18
- ### User Flow
19
- 1. User opens app -> sees todo list (or empty state if none)
20
- 2. Types a title in the input field -> presses Enter or clicks Add
21
- 3. New todo appears at the top of the list, input clears
22
- 4. Clicks checkbox to toggle complete -> visual strikethrough
23
- 5. Clicks delete icon -> confirmation prompt -> todo removed
24
- 6. Refreshes page -> all state persists from database
25
-
26
- ## Tech Stack
27
-
28
- ### Frontend
29
- - React 18 with TypeScript
30
- - Vite for bundling
31
- - TailwindCSS for styling
32
-
33
- ### Backend
34
- - Node.js 18+
35
- - Express.js
36
- - SQLite via better-sqlite3
37
- - zod for input validation
38
-
39
- ### Structure
40
- ```
41
- /
42
- ├── frontend/
43
- │ ├── src/
44
- │ │ ├── App.tsx # Main app component
45
- │ │ ├── components/
46
- │ │ │ ├── TodoList.tsx # List of todo items
47
- │ │ │ ├── TodoItem.tsx # Single todo with checkbox/delete
48
- │ │ │ ├── AddTodo.tsx # Input form for new todos
49
- │ │ │ └── EmptyState.tsx # Shown when no todos exist
50
- │ │ ├── hooks/
51
- │ │ │ └── useTodos.ts # API fetch/mutate hook
52
- │ │ ├── types/
53
- │ │ │ └── index.ts # Todo type definition
54
- │ │ └── main.tsx
55
- │ ├── package.json
56
- │ └── vite.config.ts
57
- ├── backend/
58
- │ ├── src/
59
- │ │ ├── index.ts # Express server setup
60
- │ │ ├── routes/
61
- │ │ │ └── todos.ts # CRUD route handlers
62
- │ │ └── db/
63
- │ │ └── index.ts # SQLite connection + init
64
- │ ├── package.json
65
- │ └── tsconfig.json
66
- ├── tests/
67
- │ ├── todos.test.ts # API endpoint tests
68
- │ └── components/
69
- │ └── TodoItem.test.tsx # Component tests
70
- └── README.md
71
- ```
72
-
73
- ## Database Schema
74
-
75
- ```sql
76
- CREATE TABLE todos (
77
- id INTEGER PRIMARY KEY AUTOINCREMENT,
78
- title TEXT NOT NULL,
79
- completed INTEGER DEFAULT 0, -- 0 = false, 1 = true
80
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP
81
- );
82
- ```
83
-
84
- ## API Endpoints
85
-
86
- ### Todos
87
- - `GET /api/todos` - List all todos (ordered by created_at DESC)
88
- - `POST /api/todos` - Create todo (body: `{ title }`, returns created todo)
89
- - `PATCH /api/todos/:id` - Toggle completion (body: `{ completed }`)
90
- - `DELETE /api/todos/:id` - Delete todo (returns 204)
91
-
92
- ### Health
93
- - `GET /health` - Returns `{ status: "ok" }`
94
-
95
- ## Acceptance Criteria
96
-
97
- ### Add Todo
98
- - [ ] Input field for todo title
99
- - [ ] Submit on Enter key or button click
100
- - [ ] New todo appears in list
101
- - [ ] Input clears after submit
102
- - [ ] Empty title is rejected (frontend + backend validation)
103
-
104
- ### View Todos
105
- - [ ] Shows all todos in a list
106
- - [ ] Shows completion status (checkbox)
107
- - [ ] Empty state message when no todos exist
108
-
109
- ### Complete Todo
110
- - [ ] Checkbox toggles complete/incomplete
111
- - [ ] Visual strikethrough for completed items
112
- - [ ] Persists after page refresh
113
-
114
- ### Delete Todo
115
- - [ ] Delete button on each todo
116
- - [ ] Confirmation before delete
117
- - [ ] Removes from list and database
118
-
119
- ## Requirements
120
- - TypeScript throughout
121
- - Input validation on both frontend and backend
122
- - Proper HTTP status codes (201 for create, 204 for delete, 400 for validation errors)
123
- - Loading states during API calls
124
- - Responsive design (usable on mobile)
125
-
126
- ## Testing
127
- - API tests: All 4 CRUD endpoints with valid and invalid input (Vitest + supertest)
128
- - Component tests: TodoItem renders correctly, AddTodo form submission works
129
- - Minimum 6 test cases covering happy path and error cases
130
-
131
- ## Out of Scope
132
- - User authentication
133
- - Due dates
134
- - Categories/tags
135
- - Mobile app
136
- - Cloud deployment
137
-
138
- ## Success Criteria
139
- - All 4 CRUD features functional end-to-end
140
- - All tests pass
141
- - No console errors
142
- - Empty state displays correctly
143
- - Data persists across page refresh
144
- - Input validation rejects empty titles
145
-
146
- ---
147
-
148
- **Purpose:** This PRD is intentionally simple to allow quick testing of Loki Mode's core functionality without waiting for complex builds or deployments. Expect ~15-25 minutes for full execution.
16
+ Keep the whole thing minimal and readable. The goal is a quick end-to-end
17
+ build that finishes fast, not a production system.