loki-mode 7.104.0 → 7.104.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +28 -6
- package/autonomy/run.sh +134 -10
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +132 -129
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
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, 8 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.104.
|
|
6
|
+
# Loki Mode v7.104.2
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -408,4 +408,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
408
408
|
|
|
409
409
|
---
|
|
410
410
|
|
|
411
|
-
**v7.104.
|
|
411
|
+
**v7.104.2 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.104.
|
|
1
|
+
7.104.2
|
package/autonomy/loki
CHANGED
|
@@ -9957,12 +9957,27 @@ cmd_doctor() {
|
|
|
9957
9957
|
echo -e " ${GREEN}PASS${NC} ANTHROPIC_API_KEY is set"
|
|
9958
9958
|
pass_count=$((pass_count + 1))
|
|
9959
9959
|
elif command -v claude &>/dev/null; then
|
|
9960
|
-
# Zero-network check:
|
|
9961
|
-
#
|
|
9962
|
-
#
|
|
9963
|
-
#
|
|
9960
|
+
# Zero-network login check. v7.104.2: prefer the CLI's own local
|
|
9961
|
+
# auth-status (JSON with "loggedIn"), which is authoritative for BOTH the
|
|
9962
|
+
# file-based and the native/Keychain login. This fixes doctor missing a
|
|
9963
|
+
# genuine Keychain login (native install writes NO ~/.claude/.credentials
|
|
9964
|
+
# .json). Fall back to the expiry stamp in the file for older CLIs.
|
|
9965
|
+
_claude_login="$(claude auth status 2>/dev/null | python3 -c "
|
|
9966
|
+
import json, sys
|
|
9967
|
+
try:
|
|
9968
|
+
v = json.load(sys.stdin).get('loggedIn')
|
|
9969
|
+
# Only the explicit booleans are trusted; a missing/renamed field is
|
|
9970
|
+
# inconclusive and falls through to the file-expiry check (never a spurious
|
|
9971
|
+
# 'not logged in' warning). Matches the run.sh helper + bun doctor.
|
|
9972
|
+
if v is True:
|
|
9973
|
+
print('yes')
|
|
9974
|
+
elif v is False:
|
|
9975
|
+
print('no')
|
|
9976
|
+
except Exception:
|
|
9977
|
+
pass
|
|
9978
|
+
" 2>/dev/null)"
|
|
9964
9979
|
_claude_creds="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.credentials.json"
|
|
9965
|
-
|
|
9980
|
+
_claude_expired="$( [ -s "$_claude_creds" ] && python3 -c "
|
|
9966
9981
|
import json, sys, time
|
|
9967
9982
|
try:
|
|
9968
9983
|
d = json.load(open(sys.argv[1]))
|
|
@@ -9970,7 +9985,14 @@ try:
|
|
|
9970
9985
|
print('expired' if isinstance(exp,(int,float)) and exp>0 and (exp/1000.0)<=(time.time()+60) else 'ok')
|
|
9971
9986
|
except Exception:
|
|
9972
9987
|
print('ok')
|
|
9973
|
-
" "$_claude_creds" 2>/dev/null || echo ok)"
|
|
9988
|
+
" "$_claude_creds" 2>/dev/null || echo ok )"
|
|
9989
|
+
if [ "$_claude_login" = "yes" ]; then
|
|
9990
|
+
echo -e " ${GREEN}PASS${NC} Claude CLI is logged in (subscription/OAuth login)"
|
|
9991
|
+
pass_count=$((pass_count + 1))
|
|
9992
|
+
elif [ "$_claude_login" = "no" ]; then
|
|
9993
|
+
echo -e " ${YELLOW}WARN${NC} Claude CLI is NOT logged in -- run 'claude login' before a build (it would otherwise stall)"
|
|
9994
|
+
warn_count=$((warn_count + 1))
|
|
9995
|
+
elif [ "$_claude_expired" = "expired" ]; then
|
|
9974
9996
|
echo -e " ${YELLOW}WARN${NC} Claude login has EXPIRED -- run 'claude login' before a build (it would otherwise stall)"
|
|
9975
9997
|
warn_count=$((warn_count + 1))
|
|
9976
9998
|
else
|
package/autonomy/run.sh
CHANGED
|
@@ -2023,6 +2023,118 @@ _loki_check_git_present() {
|
|
|
2023
2023
|
return 0
|
|
2024
2024
|
}
|
|
2025
2025
|
|
|
2026
|
+
# _loki_claude_login_state: report the Claude Code login state WITHOUT a network
|
|
2027
|
+
# call, printing exactly one of: loggedin | expired | loggedout | unknown.
|
|
2028
|
+
#
|
|
2029
|
+
# v7.104.2: the previous preflight assumed OAuth credentials always live in
|
|
2030
|
+
# ~/.claude/.credentials.json. That is false for the native install (Claude Code
|
|
2031
|
+
# 2.x on macOS), which stores the login in the macOS Keychain under the service
|
|
2032
|
+
# "Claude Code-credentials" and creates NO .credentials.json. A genuinely logged
|
|
2033
|
+
# in subscription user was therefore falsely told "installed but not logged in"
|
|
2034
|
+
# and blocked from every build -- the exact opposite of the zero-friction intent.
|
|
2035
|
+
#
|
|
2036
|
+
# Design: prefer the durable, CLI-owned signal (`claude auth status`, local +
|
|
2037
|
+
# fast + non-interactive, JSON with "loggedIn"), because the credential STORE
|
|
2038
|
+
# location has now moved twice (file -> keychain) and will move again. Fall back
|
|
2039
|
+
# to the file, then the keychain, for older CLIs that lack `auth status`. Crucial
|
|
2040
|
+
# rule (inconclusive-never-false-fails applied to auth): only ever return a hard
|
|
2041
|
+
# "loggedout" on POSITIVE evidence of no login; when we cannot tell, return
|
|
2042
|
+
# "unknown" and let the caller fail OPEN (warn, proceed, let the real call
|
|
2043
|
+
# decide) -- never hard-block a paying user on uncertainty.
|
|
2044
|
+
_loki_claude_login_state() {
|
|
2045
|
+
# 1) Primary: the CLI's own local auth-status (zero-network, ~0.2s). Newer
|
|
2046
|
+
# claude CLIs print JSON with a boolean "loggedIn"; parse defensively.
|
|
2047
|
+
if command -v claude >/dev/null 2>&1; then
|
|
2048
|
+
local _status_json
|
|
2049
|
+
_status_json="$(claude auth status 2>/dev/null)"
|
|
2050
|
+
if [[ -n "$_status_json" ]]; then
|
|
2051
|
+
local _parsed
|
|
2052
|
+
_parsed="$(printf '%s' "$_status_json" | python3 -c "
|
|
2053
|
+
import json, sys
|
|
2054
|
+
try:
|
|
2055
|
+
d = json.load(sys.stdin)
|
|
2056
|
+
v = d.get('loggedIn')
|
|
2057
|
+
# ONLY the two explicit booleans are trusted. Anything else -- a missing
|
|
2058
|
+
# field, a renamed schema, a JSON error object -- is inconclusive and MUST
|
|
2059
|
+
# fall through to the file/keychain checks, never a hard 'loggedout' (that
|
|
2060
|
+
# would block a genuinely logged-in user with a valid creds file, violating
|
|
2061
|
+
# fail-open). Mirrors the bun doctor's === true / === false / else shape.
|
|
2062
|
+
if v is True:
|
|
2063
|
+
print('loggedin')
|
|
2064
|
+
elif v is False:
|
|
2065
|
+
print('loggedout')
|
|
2066
|
+
# else: print nothing -> fall through
|
|
2067
|
+
except Exception:
|
|
2068
|
+
pass # not JSON (older CLI / different output) -> stay silent, fall through
|
|
2069
|
+
" 2>/dev/null)"
|
|
2070
|
+
if [[ "$_parsed" == "loggedin" ]]; then
|
|
2071
|
+
echo "loggedin"; return 0
|
|
2072
|
+
elif [[ "$_parsed" == "loggedout" ]]; then
|
|
2073
|
+
echo "loggedout"; return 0
|
|
2074
|
+
fi
|
|
2075
|
+
# auth status ran but was inconclusive (unparseable, or valid JSON
|
|
2076
|
+
# without an explicit loggedIn boolean) -> do NOT trust it as a
|
|
2077
|
+
# negative; fall through to the credential-store checks below.
|
|
2078
|
+
fi
|
|
2079
|
+
fi
|
|
2080
|
+
|
|
2081
|
+
# 2) Fallback: a VALID (non-expired) OAuth credentials file (older CLIs write
|
|
2082
|
+
# it here). Compute the expiry once; a valid file is a positive login.
|
|
2083
|
+
# IMPORTANT: we do NOT conclude "expired" here yet -- a stale expired file
|
|
2084
|
+
# can sit next to a live macOS-Keychain login (the native install writes
|
|
2085
|
+
# the file once, then rotates only the Keychain). Concluding "expired" off
|
|
2086
|
+
# the file before consulting the Keychain would wrongly block a genuinely
|
|
2087
|
+
# logged-in user -- the exact class of bug this whole change fixes. So the
|
|
2088
|
+
# Keychain (step 3, a POSITIVE signal) is checked BEFORE we ever return
|
|
2089
|
+
# "expired" (step 4). Unknown schema -> treat as valid (fail open).
|
|
2090
|
+
local _creds="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/.credentials.json"
|
|
2091
|
+
local _file_state="" # ""=absent, "valid"=present+fresh, "expired"=present+stale
|
|
2092
|
+
if [[ -s "$_creds" ]]; then
|
|
2093
|
+
_file_state="$(python3 -c "
|
|
2094
|
+
import json, sys, time
|
|
2095
|
+
try:
|
|
2096
|
+
d = json.load(open(sys.argv[1]))
|
|
2097
|
+
exp = d.get('claudeAiOauth', {}).get('expiresAt')
|
|
2098
|
+
if isinstance(exp, (int, float)) and exp > 0 and (exp / 1000.0) <= (time.time() + 60):
|
|
2099
|
+
print('expired')
|
|
2100
|
+
else:
|
|
2101
|
+
print('valid')
|
|
2102
|
+
except Exception:
|
|
2103
|
+
print('valid') # unreadable/unknown -> fail open (treat as valid)
|
|
2104
|
+
" "$_creds" 2>/dev/null || echo valid)"
|
|
2105
|
+
fi
|
|
2106
|
+
if [[ "$_file_state" == "valid" ]]; then
|
|
2107
|
+
echo "loggedin"; return 0
|
|
2108
|
+
fi
|
|
2109
|
+
|
|
2110
|
+
# 3) macOS Keychain (native install stores the login here, often with NO file
|
|
2111
|
+
# at all, or alongside a now-stale file). A present Keychain entry is a
|
|
2112
|
+
# POSITIVE login signal and OVERRIDES an expired file. Existence check
|
|
2113
|
+
# ONLY -- never `-w` (reading the secret can pop a GUI keychain prompt that
|
|
2114
|
+
# would hang a headless/CI build). Guarded to Darwin.
|
|
2115
|
+
if [[ "$(uname 2>/dev/null)" == "Darwin" ]] && command -v security >/dev/null 2>&1; then
|
|
2116
|
+
if security find-generic-password -s "Claude Code-credentials" >/dev/null 2>&1; then
|
|
2117
|
+
echo "loggedin"; return 0
|
|
2118
|
+
fi
|
|
2119
|
+
fi
|
|
2120
|
+
|
|
2121
|
+
# 4) Only now, with no valid file and no Keychain login, is an expired file a
|
|
2122
|
+
# real "expired" state (genuine expiry that would 401 mid-build).
|
|
2123
|
+
if [[ "$_file_state" == "expired" ]]; then
|
|
2124
|
+
echo "expired"; return 0
|
|
2125
|
+
fi
|
|
2126
|
+
|
|
2127
|
+
# 5) No positive login evidence at all. On macOS (where the file AND the
|
|
2128
|
+
# Keychain are the two real stores, both absent) with the CLI present, that
|
|
2129
|
+
# is confident "logged out". Anywhere else we cannot prove absence of a
|
|
2130
|
+
# login (no Keychain to consult), so stay "unknown" and let the caller fail
|
|
2131
|
+
# open.
|
|
2132
|
+
if [[ "$(uname 2>/dev/null)" == "Darwin" ]] && command -v claude >/dev/null 2>&1; then
|
|
2133
|
+
echo "loggedout"; return 0
|
|
2134
|
+
fi
|
|
2135
|
+
echo "unknown"; return 0
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2026
2138
|
# _loki_check_workspace_writable: the build writes state, proofs, and source into
|
|
2027
2139
|
# the working directory and its .loki/ subtree on every iteration. A read-only
|
|
2028
2140
|
# volume, a permission-denied directory, or a full disk would otherwise fail
|
|
@@ -2108,21 +2220,33 @@ validate_api_keys() {
|
|
|
2108
2220
|
|
|
2109
2221
|
# Zero-friction auth preflight for LOCAL runs (must run BEFORE the early
|
|
2110
2222
|
# return below, which exits for non-Docker/K8s envs). When claude is the
|
|
2111
|
-
# provider
|
|
2112
|
-
#
|
|
2113
|
-
#
|
|
2114
|
-
# 401 -- the worst first impression --
|
|
2115
|
-
#
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2223
|
+
# provider and there is no ANTHROPIC_API_KEY, ask the login-state helper
|
|
2224
|
+
# (auth-status -> file -> keychain, all zero-network) whether the user is
|
|
2225
|
+
# actually logged in. A never-logged-in user would otherwise enter the build,
|
|
2226
|
+
# make a failing call, and 401 -- the worst first impression -- so we fail
|
|
2227
|
+
# fast with the one-step fix. But we ONLY hard-block on a confident
|
|
2228
|
+
# "loggedout"; an "expired" login gets its own message; "unknown" (we cannot
|
|
2229
|
+
# prove the login state, e.g. an older CLI on a non-macOS box with no file)
|
|
2230
|
+
# fails OPEN so a genuinely logged-in user is never blocked. This is the
|
|
2231
|
+
# v7.104.2 fix for the native/Keychain login being misread as logged out.
|
|
2232
|
+
# Opt out entirely with LOKI_SKIP_AUTH_PREFLIGHT=1.
|
|
2233
|
+
if [[ "$provider" == "claude" && "${LOKI_SKIP_AUTH_PREFLIGHT:-}" != "1" && -z "${ANTHROPIC_API_KEY:-}" ]]; then
|
|
2234
|
+
local _login_state
|
|
2235
|
+
_login_state="$(_loki_claude_login_state)"
|
|
2236
|
+
if [[ "$_login_state" == "loggedout" ]]; then
|
|
2120
2237
|
log_error "Claude Code is installed but not logged in -- the build would stall instead of running."
|
|
2121
2238
|
log_error "Log in once, then retry:"
|
|
2122
2239
|
log_error " claude login"
|
|
2123
2240
|
log_error "(or set ANTHROPIC_API_KEY, or LOKI_SKIP_AUTH_PREFLIGHT=1 to bypass this check)"
|
|
2124
2241
|
return 1
|
|
2242
|
+
elif [[ "$_login_state" == "expired" ]]; then
|
|
2243
|
+
log_error "Your Claude Code login has expired -- the build would stall instead of running."
|
|
2244
|
+
log_error "Fix it in one step, then retry:"
|
|
2245
|
+
log_error " claude login"
|
|
2246
|
+
log_error "(or set ANTHROPIC_API_KEY, or LOKI_SKIP_AUTH_PREFLIGHT=1 to bypass this check)"
|
|
2247
|
+
return 1
|
|
2125
2248
|
fi
|
|
2249
|
+
# "loggedin" or "unknown" -> proceed (fail open on uncertainty).
|
|
2126
2250
|
fi
|
|
2127
2251
|
|
|
2128
2252
|
# CLI tools (claude, codex, cline, aider) use their own login sessions.
|
|
@@ -19023,7 +19147,7 @@ main() {
|
|
|
19023
19147
|
_handoff_dir="${TARGET_DIR:-.}"
|
|
19024
19148
|
_handoff_md="$_handoff_dir/HANDOFF.md"
|
|
19025
19149
|
_handoff_tmp="$_handoff_dir/.HANDOFF.md.tmp"
|
|
19026
|
-
if python3 "$_own_render" --loki-dir "$LOKI_DIR" --md > "$_handoff_tmp" 2>/dev/null; then
|
|
19150
|
+
if python3 "$_own_render" --loki-dir "${LOKI_DIR:-${TARGET_DIR:-.}/.loki}" --md > "$_handoff_tmp" 2>/dev/null; then
|
|
19027
19151
|
mv -f "$_handoff_tmp" "$_handoff_md" 2>/dev/null || rm -f "$_handoff_tmp" 2>/dev/null || true
|
|
19028
19152
|
else
|
|
19029
19153
|
rm -f "$_handoff_tmp" 2>/dev/null || true
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
|
@@ -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.104.
|
|
5
|
+
**Version:** v7.104.2
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|