loki-mode 11.48.0 → 11.49.1

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.
Files changed (72) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/completion-council.sh +2 -2
  4. package/autonomy/council-v2.sh +15 -0
  5. package/autonomy/lib/claude-flags.sh +14 -1
  6. package/autonomy/lib/claude_permissions.py +23 -3
  7. package/dashboard/__init__.py +1 -1
  8. package/docs/CLI-REFERENCE.md +1 -1
  9. package/docs/INSTALLATION.md +1 -1
  10. package/docs/environment-variables.md +28 -0
  11. package/loki-ts/dist/loki.js +1019 -1019
  12. package/mcp/__init__.py +1 -1
  13. package/package.json +2 -2
  14. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  15. package/src/policies/claude_permissions.js +68 -1
  16. package/web-app/dist/assets/{AdminPage-CQvCk-IW.js → AdminPage-B1x_9e2j.js} +1 -1
  17. package/web-app/dist/assets/{Avatar-CthBrW7x.js → Avatar-je0Qd3do.js} +1 -1
  18. package/web-app/dist/assets/{Badge-DHDosxpl.js → Badge-DekgP35C.js} +1 -1
  19. package/web-app/dist/assets/{Button-CPY96VjZ.js → Button-Dsm0EiV-.js} +1 -1
  20. package/web-app/dist/assets/{CockpitPage-DKD8U1JK.js → CockpitPage-BGHGpbh7.js} +1 -1
  21. package/web-app/dist/assets/{ComparePage-D_WHKhBm.js → ComparePage-Bz-8297E.js} +1 -1
  22. package/web-app/dist/assets/{ErrorBoundary-V2z_sEe8.js → ErrorBoundary-Cgr91NGO.js} +1 -1
  23. package/web-app/dist/assets/{EvidenceReceiptPanel-DNLVV9D8.js → EvidenceReceiptPanel-DVO1YDRi.js} +1 -1
  24. package/web-app/dist/assets/{GitHubIssuesPanel-ffsL9Ykm.js → GitHubIssuesPanel-Cux5i4yY.js} +1 -1
  25. package/web-app/dist/assets/{GitHubPRsPanel-CDQ9BYFh.js → GitHubPRsPanel-Chn4wGzi.js} +1 -1
  26. package/web-app/dist/assets/{HomePage-CBa-Qw8X.js → HomePage-Dk16kk98.js} +2 -2
  27. package/web-app/dist/assets/{LoginPage-DtNcnxOe.js → LoginPage-wahOK-Le.js} +1 -1
  28. package/web-app/dist/assets/{MagicPage-DQjGzlAu.js → MagicPage-74PchSIA.js} +1 -1
  29. package/web-app/dist/assets/{MetricsPage--nrHd4Fm.js → MetricsPage-QxHs-DHu.js} +1 -1
  30. package/web-app/dist/assets/{NotFoundPage-DWcwX0zD.js → NotFoundPage-Ds9Z2O3u.js} +1 -1
  31. package/web-app/dist/assets/{ProjectPage-DiNuw52T.js → ProjectPage-MFgXvjCX.js} +3 -3
  32. package/web-app/dist/assets/{ProjectsPage-DqdEi4P2.js → ProjectsPage-4MvZd8gp.js} +1 -1
  33. package/web-app/dist/assets/{SettingsPage-Cz_N-yDC.js → SettingsPage-CQROsktw.js} +1 -1
  34. package/web-app/dist/assets/{ShowcasePage-CN33uUQQ.js → ShowcasePage-C9O-LnEr.js} +1 -1
  35. package/web-app/dist/assets/{SystemSettingsPage-xy1ZInN6.js → SystemSettingsPage-phjqUnyz.js} +1 -1
  36. package/web-app/dist/assets/{TeamsPage-BE4LBDX0.js → TeamsPage-BjafTGjl.js} +1 -1
  37. package/web-app/dist/assets/{TemplatesPage-DRLsFVsm.js → TemplatesPage-Cv1-JSoY.js} +1 -1
  38. package/web-app/dist/assets/{TerminalOutput-053BH7J5.js → TerminalOutput-N6lyOFmy.js} +1 -1
  39. package/web-app/dist/assets/{activity-SWV8QSMY.js → activity-ByexUS4E.js} +1 -1
  40. package/web-app/dist/assets/{bell-CdaXawBj.js → bell-Dr1dnkVd.js} +1 -1
  41. package/web-app/dist/assets/{bot-DowFzcbb.js → bot-CX1Jypgr.js} +1 -1
  42. package/web-app/dist/assets/{check-CQfGN99n.js → check-COSgcXfR.js} +1 -1
  43. package/web-app/dist/assets/{chevron-left-DNKR9mbx.js → chevron-left-B6AhgSEs.js} +1 -1
  44. package/web-app/dist/assets/{circle-alert-DC72t-OS.js → circle-alert-BA6wAu9U.js} +1 -1
  45. package/web-app/dist/assets/{clock-Dg1lWJQP.js → clock-DMAyuaTE.js} +1 -1
  46. package/web-app/dist/assets/{cloud-C70NH4sp.js → cloud-iLAZpo0L.js} +1 -1
  47. package/web-app/dist/assets/{code-xml-BpS3Ll8C.js → code-xml-CssePOwe.js} +1 -1
  48. package/web-app/dist/assets/{database-CnuyaKvf.js → database-DwqPI1QS.js} +1 -1
  49. package/web-app/dist/assets/{dollar-sign-CSYYhLol.js → dollar-sign-CXNtpzR0.js} +1 -1
  50. package/web-app/dist/assets/{file-code-corner-E5JXdQiO.js → file-code-corner-CoYtyE9P.js} +1 -1
  51. package/web-app/dist/assets/{file-plus-C1XNP0Bx.js → file-plus-BdYB6wxs.js} +1 -1
  52. package/web-app/dist/assets/{globe-4U9PAMLC.js → globe-waHnz5SI.js} +1 -1
  53. package/web-app/dist/assets/{hammer-BlVJ212r.js → hammer-CU7GF2h6.js} +1 -1
  54. package/web-app/dist/assets/{index-BYxG62kK.js → index-BG5TGqVC.js} +3 -3
  55. package/web-app/dist/assets/{layers-qYS53Ds0.js → layers-CddOD0DM.js} +1 -1
  56. package/web-app/dist/assets/{loader-circle-DZHCmLaQ.js → loader-circle-BW-z1MeG.js} +1 -1
  57. package/web-app/dist/assets/{lock-a64g10hN.js → lock-C5LY_Chs.js} +1 -1
  58. package/web-app/dist/assets/{package-DyiSktDn.js → package-CAeZd7Qc.js} +1 -1
  59. package/web-app/dist/assets/{plus-Cr5QsWCN.js → plus-3H0JefQR.js} +1 -1
  60. package/web-app/dist/assets/{refresh-cw-B2wxlCc4.js → refresh-cw-DA6KGHba.js} +1 -1
  61. package/web-app/dist/assets/{rotate-ccw-BynX7Uax.js → rotate-ccw-D0IEFSQh.js} +1 -1
  62. package/web-app/dist/assets/{scroll-text-SU8nqxyP.js → scroll-text-C6OSRQvj.js} +1 -1
  63. package/web-app/dist/assets/{server-267I9zdB.js → server-BFxFyigJ.js} +1 -1
  64. package/web-app/dist/assets/{shield-alert-Bwu7O78S.js → shield-alert-ygUxeDWd.js} +1 -1
  65. package/web-app/dist/assets/{thumbs-up-CldaTDSN.js → thumbs-up-CULMXay2.js} +1 -1
  66. package/web-app/dist/assets/{trash-2-H30AE3QT.js → trash-2-Bf3WT8E9.js} +1 -1
  67. package/web-app/dist/assets/{trending-down-C73ltOoX.js → trending-down-DBnMH7jy.js} +1 -1
  68. package/web-app/dist/assets/{trending-up-BzcwNutU.js → trending-up-Dp3prDVB.js} +1 -1
  69. package/web-app/dist/assets/{upload-123P3QLE.js → upload-DbL_lwCw.js} +1 -1
  70. package/web-app/dist/assets/{usePolling-CqmlVr8x.js → usePolling-LLMFK0D9.js} +1 -1
  71. package/web-app/dist/assets/{user-mmncF9L1.js → user-g2ep_OP2.js} +1 -1
  72. package/web-app/dist/index.html +1 -1
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Runs an autonomous software factory that knows what it is supposed to deliver and proves it did, with a signed receipt. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
4
4
  ---
5
5
 
6
- # Loki Mode v11.48.0
6
+ # Loki Mode v11.49.1
7
7
 
8
8
  **Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the previous bash loop. PRD-file starts (`loki start ./prd.md`) and the opencode provider still run on it until FC38-SWEEP ports them; the legacy-engine command and the LOKI_ENGINE switch remain removed. Prefer `loki owner/repo#N` for issues.
9
9
 
@@ -476,4 +476,4 @@ Implemented, planned and deprecated items, with the version each landed in: `ski
476
476
 
477
477
  ---
478
478
 
479
- **v11.48.0 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
479
+ **v11.49.1 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 11.48.0
1
+ 11.49.1
@@ -3196,7 +3196,7 @@ INSTRUCTIONS:
3196
3196
 
3197
3197
  Output format:
3198
3198
  VOTE:APPROVE or VOTE:REJECT or VOTE:CANNOT_VALIDATE
3199
- REASON: your reasoning here
3199
+ REASON: one-line justification citing path:line evidence
3200
3200
  ISSUES: CRITICAL:description (optional, one per line per issue)"
3201
3201
 
3202
3202
  local verdict_file="$vote_dir/member-${member_id}.txt"
@@ -3428,7 +3428,7 @@ If you find ANY legitimate concern, output VOTE:REJECT.
3428
3428
  Only output VOTE:APPROVE if you genuinely cannot find a single issue.
3429
3429
 
3430
3430
  VOTE:APPROVE or VOTE:REJECT
3431
- REASON: your reasoning"
3431
+ REASON: one-line justification citing path:line evidence"
3432
3432
 
3433
3433
  local verdict=""
3434
3434
  case "${PROVIDER_NAME:-claude}" in
@@ -596,5 +596,20 @@ print(json.dumps({
596
596
  extracted='{"verdict":"INCONCLUSIVE","justification":"failed to parse review output (no verdict obtained; NOT a rejection)","issues":[]}'
597
597
  fi
598
598
 
599
+ # READ-COMPAT: a reviewer that still answers with the legacy reasoning key
600
+ # (an older prompt, a custom agent, a non-schema provider) is stored under
601
+ # "justification", the only key any writer emits. Verdict and issues pass
602
+ # through untouched; on any failure the original text is kept as-is.
603
+ local _c2_norm
604
+ _c2_norm="$(printf '%s' "$extracted" | _LOKI_LEGACY_KEY=reasoning "$_c2_py" -I -S -c 'import sys; sys.path[:] = [p for p in sys.path if p not in ("", ".")]; import json, os
605
+ d = json.load(sys.stdin)
606
+ k = os.environ["_LOKI_LEGACY_KEY"]
607
+ if isinstance(d, dict) and k in d:
608
+ old = d.pop(k)
609
+ d.setdefault("justification", old)
610
+ sys.stdout.write(json.dumps(d))
611
+ else:
612
+ sys.exit(1)' 2>/dev/null)" && [ -n "$_c2_norm" ] && extracted="$_c2_norm"
613
+
599
614
  echo "$extracted" > "$output_file"
600
615
  }
@@ -1138,9 +1138,22 @@ loki_permission_policy_banner() {
1138
1138
  _loki_claude_permission_argv() {
1139
1139
  _LOKI_PERM_ARGV=(--dangerously-skip-permissions)
1140
1140
  _loki_permission_warn_unknown_once
1141
- [ "$(_loki_permission_policy_mode)" = "legacy" ] && return 0
1142
1141
  local _helper _out _a
1143
1142
  _helper="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/src/policies/claude_permissions.js"
1143
+ if [ "$(_loki_permission_policy_mode)" = "legacy" ]; then
1144
+ # w2-07: legacy keeps bypass but carries the default web/credential deny rules (same js source).
1145
+ # Unusable compiler or helper failure fails closed to plan, like compiled mode and the TS route.
1146
+ _LOKI_PERM_ARGV=(--permission-mode plan)
1147
+ if ! command -v node >/dev/null 2>&1 || [ ! -f "$_helper" ]; then
1148
+ echo "[loki] WARNING: legacy permission policy: compiler unavailable; using most restrictive mode (plan)" >&2
1149
+ return 0
1150
+ fi
1151
+ _out="$(node "$_helper" --legacy-args)" || return 0
1152
+ [ -n "$_out" ] || return 0
1153
+ _LOKI_PERM_ARGV=()
1154
+ while IFS= read -r _a; do _LOKI_PERM_ARGV+=("$_a"); done <<< "$_out"
1155
+ return 0
1156
+ fi
1144
1157
  _LOKI_PERM_ARGV=(--permission-mode plan)
1145
1158
  if ! command -v node >/dev/null 2>&1 || [ ! -f "$_helper" ]; then
1146
1159
  echo "[loki] WARNING: compiled permission policy: compiler unavailable; using most restrictive mode (plan)" >&2
@@ -14,7 +14,6 @@ import subprocess
14
14
  import sys
15
15
  from pathlib import Path
16
16
 
17
- _LEGACY = ["--dangerously-skip-permissions"]
18
17
  _FAIL_CLOSED = ["--permission-mode", "plan"]
19
18
  _unknown_warned = False
20
19
 
@@ -30,16 +29,37 @@ def _has_operator_policy(node: str | None, helper: Path, env: dict) -> bool:
30
29
  return done.stdout.strip() == "1"
31
30
 
32
31
 
32
+ def _legacy_argv(env: dict) -> list:
33
+ """Legacy bypass flag plus the default web/credential deny rules (w2-07), from the same js helper.
34
+
35
+ An unusable compiler fails closed to plan with a warning, like compiled mode and the TS route.
36
+ """
37
+ helper = Path(__file__).resolve().parents[2] / "src" / "policies" / "claude_permissions.js"
38
+ node = shutil.which("node")
39
+ if node is None or not helper.is_file():
40
+ print("[loki] WARNING: legacy permission policy: compiler unavailable; using most restrictive mode (plan)", file=sys.stderr)
41
+ return list(_FAIL_CLOSED)
42
+ try:
43
+ done = subprocess.run([node, str(helper), "--legacy-args"], capture_output=True, text=True,
44
+ timeout=30, env=dict(env), check=False)
45
+ except (OSError, subprocess.SubprocessError):
46
+ return list(_FAIL_CLOSED)
47
+ if done.stderr:
48
+ sys.stderr.write(done.stderr)
49
+ args = [a for a in done.stdout.split("\n") if a]
50
+ return args if done.returncode == 0 and args else list(_FAIL_CLOSED)
51
+
52
+
33
53
  def claude_permission_argv(project_dir: str | None = None, env: dict | None = None) -> list:
34
54
  env = os.environ if env is None else env
35
55
  mode = env.get("LOKI_PERMISSION_POLICY", "")
36
56
  if mode == "legacy":
37
- return list(_LEGACY)
57
+ return _legacy_argv(env)
38
58
  global _unknown_warned
39
59
  helper = Path(__file__).resolve().parents[2] / "src" / "policies" / "claude_permissions.js"
40
60
  node = shutil.which("node")
41
61
  if mode == "" and not _has_operator_policy(node, helper, env):
42
- return list(_LEGACY)
62
+ return _legacy_argv(env)
43
63
  if mode not in ("", "compiled") and not _unknown_warned:
44
64
  _unknown_warned = True
45
65
  print(f"[loki] WARNING: LOKI_PERMISSION_POLICY={mode}: unknown value; using compiled", file=sys.stderr)
@@ -7,6 +7,6 @@ Modules:
7
7
  control: Session control helpers (status, atomic writes, origin check)
8
8
  """
9
9
 
10
- __version__ = "11.48.0"
10
+ __version__ = "11.49.1"
11
11
 
12
12
  __all__ = ["__version__"]
@@ -1,6 +1,6 @@
1
1
  # CLI reference
2
2
 
3
- Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.48.0. Do not edit by hand.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.49.1. Do not edit by hand.
4
4
  Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
4
4
 
5
- **Version:** v11.48.0
5
+ **Version:** v11.49.1
6
6
 
7
7
  **Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
8
8
 
@@ -95,6 +95,34 @@ model sees a countdown across the whole loop and wraps up instead of running out
95
95
  It is advisory only; `LOKI_BUDGET_LIMIT` is the enforcing cap. Unset, zero or a
96
96
  non-integer sends nothing.
97
97
 
98
+ ### Web access is now off by default
99
+
100
+ Claude workers can no longer search or fetch from the web, and cannot read secret
101
+ files, unless you opt in. This is intended, not a bug. A worker that follows a
102
+ prompt-injected instruction in a web page or a file could otherwise send your
103
+ credentials to an outside site, so the default denies the tools that make that
104
+ possible:
105
+
106
+ - `WebFetch` and `WebSearch` are denied.
107
+ - `Read` of anything matching `.env*` (so `.env`, `.env.local`, `.envrc`, `.env.prod`, `.env.keys`, and the templates `.env.example`, `.env.sample`, `.env.template`), `*.pem`, and anything under `.aws/` or `.ssh/` is denied, anywhere on disk. The templates are blocked too: a deny beats any allow, so they cannot be carved out of the glob without missing secret names.
108
+
109
+ This applies to every Claude route (shell, TypeScript and Python launch sites),
110
+ whether `LOKI_PERMISSION_POLICY` is `compiled` or `legacy`. If the policy cannot
111
+ be compiled (invalid `LOKI_WEB_ALLOW_DOMAINS`, or Node missing), Loki prints a
112
+ warning and runs in `plan` mode instead of skipping the rules. Punycode (`xn--`)
113
+ domains are rejected the same way.
114
+
115
+ This is not complete secret-file protection: `Read` denies do not stop
116
+ `Bash(cat .env)` under `--dangerously-skip-permissions`.
117
+
118
+ To turn web access back on:
119
+
120
+ | Setting | Effect |
121
+ |---|---|
122
+ | `LOKI_WEB_ALLOW_DOMAINS=docs.python.org,*.example.com` | Allows `WebFetch` for those hostnames only (comma list, ASCII hostnames). `WebSearch` stays denied. Enforced with `LOKI_PERMISSION_POLICY=compiled`; the legacy route keeps both web tools denied and warns. |
123
+ | `allow` entry for `WebFetch` or `WebSearch` in your `claude_permissions` policy | Keeps that tool enabled. |
124
+ | `LOKI_WEB_POLICY=off` | Disables this policy entirely: no web or credential deny rules, the previous behavior. |
125
+
98
126
  ## Steering the loop
99
127
 
100
128
  These control how the engine decides what to do next. Every one is on by