loki-mode 11.3.8 → 11.4.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 +34 -18
- package/SKILL.md +3 -3
- package/VERSION +1 -1
- package/agents/custom_agents.py +280 -0
- package/autonomy/council-v2.sh +22 -1
- package/autonomy/edit.sh +242 -0
- package/autonomy/lib/chat.sh +312 -0
- package/autonomy/lib/help-core.sh +164 -0
- package/autonomy/lib/json-output.sh +38 -0
- package/autonomy/lib/run-summary.sh +96 -0
- package/autonomy/loki +105 -10
- package/autonomy/route.sh +270 -0
- package/autonomy/run.sh +6 -0
- package/autonomy/setup-wizard.sh +161 -0
- package/autonomy/verify.sh +22 -2
- package/bin/loki +73 -18
- package/completions/_loki +55 -0
- package/completions/loki.bash +49 -3
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-CORE-VERBS.md +112 -0
- package/docs/CLI-REFERENCE.md +7 -1
- package/docs/COMPARE-OPENCODE.md +94 -0
- package/docs/COMPONENTS.md +1 -0
- package/docs/INSTALLATION.md +56 -12
- package/docs/KNOWN-ISSUES.md +2 -12
- package/docs/QUICKSTART.md +108 -0
- package/docs/environment-variables.md +9 -2
- package/docs/exit-codes.md +29 -12
- package/docs/v10/CLI-MODERN.md +10 -4
- package/docs/v10/FAILURE-CLASSES.md +2 -2
- package/docs/v10/GUIDE.md +270 -44
- package/docs/v10/METRICS.md +6 -0
- package/docs/v10/OPENCODE-PARITY-PLAN.md +84 -0
- package/docs/v10/PROGRESS.md +7 -0
- package/loki-ts/dist/loki.js +968 -933
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +198 -86
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/providers/claude.sh +16 -2
- package/providers/model_route_exec.sh +22 -0
- package/providers/model_routes.sh +188 -0
- package/skills/providers.md +13 -0
- package/templates/agents/planner.md +10 -0
- package/templates/agents/reviewer.md +10 -0
- package/templates/agents/tester.md +10 -0
- package/web-app/dist/assets/{AdminPage-D1jlQGeE.js → AdminPage-CYJ2BWRC.js} +1 -1
- package/web-app/dist/assets/{Avatar-QUX_aJfQ.js → Avatar-DdK4wynI.js} +1 -1
- package/web-app/dist/assets/{Badge-pysXUR6J.js → Badge-CrX3MI7J.js} +1 -1
- package/web-app/dist/assets/{Button-CWzlTw9P.js → Button-709-wwGM.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DLCoLdyF.js → CockpitPage-BapdTInO.js} +1 -1
- package/web-app/dist/assets/{ComparePage-CCENGIti.js → ComparePage-DT99pGvA.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-BssCcbgv.js → ErrorBoundary-B0uJSys8.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-CwmAqJ90.js → EvidenceReceiptPanel-BtMFgElP.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-DuSw8shb.js → GitHubIssuesPanel-DjJuU941.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-CGvLbDjh.js → GitHubPRsPanel-HXfEX1BC.js} +1 -1
- package/web-app/dist/assets/{HomePage-BrBX5Gn2.js → HomePage-Cqyves-S.js} +2 -2
- package/web-app/dist/assets/{LoginPage-DPjr7QHU.js → LoginPage-jUbtC7_Y.js} +1 -1
- package/web-app/dist/assets/{MagicPage-Dxd7FWF2.js → MagicPage-DHRsqjgR.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-BP47Urni.js → MetricsPage-B-pED05R.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-D7_07YoB.js → NotFoundPage-CsbUs21R.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-SQ183efy.js → ProjectPage-BtlLEQwB.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Cgr1K2Ae.js → ProjectsPage-DaRbRjSp.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-kyYOSDt0.js → SettingsPage-DALrtP3F.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-CRd-H1A4.js → ShowcasePage-CoPHSNP0.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-BHBdGXod.js → SystemSettingsPage-kOuSN50O.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-CI3Wdbjw.js → TeamsPage-DGWK0LMp.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DfhCgP6i.js → TemplatesPage-C-_10CwA.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-Cs87YXLJ.js → TerminalOutput-Cz_vPbXL.js} +1 -1
- package/web-app/dist/assets/{activity-CrQx5SbK.js → activity-icIsXJVa.js} +1 -1
- package/web-app/dist/assets/{bell-Dde5IbnI.js → bell-DbPR2_4r.js} +1 -1
- package/web-app/dist/assets/{bot-trRuIJT6.js → bot-DvjP3Yh5.js} +1 -1
- package/web-app/dist/assets/{check-DmsthR-3.js → check-D1OBxHeU.js} +1 -1
- package/web-app/dist/assets/{chevron-left-C5wZb7mg.js → chevron-left-D09jDZ29.js} +1 -1
- package/web-app/dist/assets/{circle-alert-BCb173fK.js → circle-alert-DyZMLOcC.js} +1 -1
- package/web-app/dist/assets/{clock-CvcqL3Ma.js → clock-CdpdJTId.js} +1 -1
- package/web-app/dist/assets/{cloud-CW1r3-AN.js → cloud-CoLTlmoj.js} +1 -1
- package/web-app/dist/assets/{code-xml-uxBTXAfZ.js → code-xml-DrkE2ZZY.js} +1 -1
- package/web-app/dist/assets/{database-DBrvW0o1.js → database-CMQQuM2R.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-WrOyoDcN.js → dollar-sign-CuioDaOG.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-8JC8TI2_.js → file-code-corner-Cx9j9K1S.js} +1 -1
- package/web-app/dist/assets/{file-plus-CgUdOr2u.js → file-plus-CYD2zaaI.js} +1 -1
- package/web-app/dist/assets/{globe-w-0x46nt.js → globe-6w-hnQkL.js} +1 -1
- package/web-app/dist/assets/{hammer-Civ6_wQq.js → hammer-BpqtautL.js} +1 -1
- package/web-app/dist/assets/{index-wvGJotyF.js → index-Dzs-9EgJ.js} +3 -3
- package/web-app/dist/assets/{layers-Cc3wLG39.js → layers-D5hd7jb7.js} +1 -1
- package/web-app/dist/assets/{loader-circle-BedHqfS4.js → loader-circle-C6Y9x_7H.js} +1 -1
- package/web-app/dist/assets/{lock-CRyzk3QG.js → lock-D51L7rYh.js} +1 -1
- package/web-app/dist/assets/{package-DCT1v7W2.js → package-BJF8hkP8.js} +1 -1
- package/web-app/dist/assets/{plus-C7eerOb_.js → plus-D5kUQ79n.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-DO753Y_B.js → refresh-cw-BKdlCa7F.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-ptlyGV4I.js → rotate-ccw-_bd_YI1e.js} +1 -1
- package/web-app/dist/assets/{scroll-text-CqPwk4yI.js → scroll-text-DbkegIxF.js} +1 -1
- package/web-app/dist/assets/{server-BP_VvY9m.js → server-DAwqFIsq.js} +1 -1
- package/web-app/dist/assets/{shield-alert-Bf0waB0a.js → shield-alert-BuR1tPHu.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-p1roSIsw.js → thumbs-up-BF6p3mRd.js} +1 -1
- package/web-app/dist/assets/{trash-2-BrMaXAxl.js → trash-2-BVpnkqqz.js} +1 -1
- package/web-app/dist/assets/{trending-down-DaGcCn2W.js → trending-down-DpsDvRwW.js} +1 -1
- package/web-app/dist/assets/{trending-up-CKPupOSE.js → trending-up-mFogTjt3.js} +1 -1
- package/web-app/dist/assets/{upload-CR0gzibW.js → upload-4T8zpBsi.js} +1 -1
- package/web-app/dist/assets/{usePolling-kKzJRjFw.js → usePolling-DPXQv8WO.js} +1 -1
- package/web-app/dist/assets/{user-CPOXPTtD.js → user-BYGIFaTm.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "loki-mode",
|
|
4
4
|
"displayName": "Loki Mode",
|
|
5
|
-
"version": "11.
|
|
5
|
+
"version": "11.4.2",
|
|
6
6
|
"description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Autonomi",
|
package/providers/claude.sh
CHANGED
|
@@ -151,6 +151,11 @@ unset _loki_dap_root
|
|
|
151
151
|
|
|
152
152
|
# Source the v7.5.22 Phase D mcp-config helper (idempotent).
|
|
153
153
|
# shellcheck source=../autonomy/lib/mcp-config.sh
|
|
154
|
+
# OC-MODELS: model routes (openrouter/ollama/... over the Claude harness).
|
|
155
|
+
_loki_model_routes_helper="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/model_routes.sh"
|
|
156
|
+
# shellcheck disable=SC1090
|
|
157
|
+
[ -f "$_loki_model_routes_helper" ] && . "$_loki_model_routes_helper"
|
|
158
|
+
|
|
154
159
|
_loki_mcp_config_helper="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/autonomy/lib/mcp-config.sh"
|
|
155
160
|
if [ -f "$_loki_mcp_config_helper" ]; then
|
|
156
161
|
# shellcheck disable=SC1090
|
|
@@ -385,7 +390,8 @@ provider_invoke() {
|
|
|
385
390
|
# array is empty, and a bare "${arr[@]}" under `set -u` aborts with "unbound
|
|
386
391
|
# variable" on bash 3.2 (stock macOS /bin/bash). ${arr[@]+...} expands to
|
|
387
392
|
# nothing when unset/empty and preserves spaced elements otherwise.
|
|
388
|
-
|
|
393
|
+
loki_model_route_prefix
|
|
394
|
+
"${_LOKI_ROUTE_EXEC[@]+"${_LOKI_ROUTE_EXEC[@]}"}" claude --dangerously-skip-permissions "${_LOKI_CLAUDE_AUTO_FLAGS[@]+"${_LOKI_CLAUDE_AUTO_FLAGS[@]}"}" -p "$prompt" "$@" < /dev/null
|
|
389
395
|
}
|
|
390
396
|
|
|
391
397
|
# provider_invoke_argv <tier> <prompt> -- populate _LOKI_INVOKE_ARGV with the
|
|
@@ -427,7 +433,9 @@ provider_invoke_argv() {
|
|
|
427
433
|
# silently unenforced on exactly the timeout-safe seam. resolve_model_for_tier
|
|
428
434
|
# is base -> route -> clamp -> alt-provider in one call; keep both paths on it.
|
|
429
435
|
model="$(resolve_model_for_tier "$tier" 2>/dev/null || provider_get_tier_param "$tier")"
|
|
436
|
+
loki_model_route_prefix
|
|
430
437
|
_LOKI_INVOKE_ARGV=(
|
|
438
|
+
"${_LOKI_ROUTE_EXEC[@]+"${_LOKI_ROUTE_EXEC[@]}"}"
|
|
431
439
|
claude --dangerously-skip-permissions
|
|
432
440
|
"${_LOKI_CLAUDE_AUTO_FLAGS[@]+"${_LOKI_CLAUDE_AUTO_FLAGS[@]}"}"
|
|
433
441
|
)
|
|
@@ -638,6 +646,11 @@ resolve_model_for_tier() {
|
|
|
638
646
|
model="$LOKI_MODEL_OVERRIDE"
|
|
639
647
|
fi
|
|
640
648
|
|
|
649
|
+
# OC-MODELS: an active model route (openrouter/ollama/...) wins; plain ids unchanged.
|
|
650
|
+
local _route_model
|
|
651
|
+
_route_model="$(loki_model_route_model 2>/dev/null || true)"
|
|
652
|
+
[ -n "$_route_model" ] && model="$_route_model"
|
|
653
|
+
|
|
641
654
|
echo "$model"
|
|
642
655
|
}
|
|
643
656
|
|
|
@@ -656,5 +669,6 @@ provider_invoke_with_tier() {
|
|
|
656
669
|
# Guard empty auto-flag array under `set -u` on bash 3.2 (stock macOS): a bare
|
|
657
670
|
# "${arr[@]}" on an empty array aborts with "unbound variable". ${arr[@]+...}
|
|
658
671
|
# expands to nothing when empty and preserves spaced elements otherwise.
|
|
659
|
-
|
|
672
|
+
loki_model_route_prefix
|
|
673
|
+
"${_LOKI_ROUTE_EXEC[@]+"${_LOKI_ROUTE_EXEC[@]}"}" claude --dangerously-skip-permissions --model "$model" "${_LOKI_CLAUDE_AUTO_FLAGS[@]+"${_LOKI_CLAUDE_AUTO_FLAGS[@]}"}" -p "$prompt" "$@" < /dev/null
|
|
660
674
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Exec a command (the claude CLI) with the active model route applied to ITS env
|
|
3
|
+
# only. The token is read from the already-inherited env here, so it never
|
|
4
|
+
# appears on any command line and is never printed.
|
|
5
|
+
# Usage: bash model_route_exec.sh claude [args...]
|
|
6
|
+
_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
7
|
+
# shellcheck source=model_routes.sh
|
|
8
|
+
. "$_dir/model_routes.sh"
|
|
9
|
+
|
|
10
|
+
spec="$(loki_model_route_spec)"
|
|
11
|
+
if [ -n "$spec" ] && loki_model_route_parse "$spec"; then
|
|
12
|
+
token=""
|
|
13
|
+
if [ -n "$LOKI_ROUTE_TOKEN_VAR" ]; then
|
|
14
|
+
token="${!LOKI_ROUTE_TOKEN_VAR:-}"
|
|
15
|
+
fi
|
|
16
|
+
export ANTHROPIC_BASE_URL="$LOKI_ROUTE_BASE"
|
|
17
|
+
export ANTHROPIC_MODEL="$LOKI_ROUTE_MODEL"
|
|
18
|
+
export ANTHROPIC_SMALL_FAST_MODEL="$LOKI_ROUTE_MODEL"
|
|
19
|
+
export ANTHROPIC_AUTH_TOKEN="${token:-loki-local-route}"
|
|
20
|
+
export ANTHROPIC_API_KEY=""
|
|
21
|
+
fi
|
|
22
|
+
exec "$@"
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Model routes: run non-Anthropic models through the Tier-1 Claude harness.
|
|
3
|
+
#
|
|
4
|
+
# Claude Code honors ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN and ANTHROPIC_MODEL,
|
|
5
|
+
# so any Anthropic-compatible endpoint keeps every Loki control (cost, kill
|
|
6
|
+
# blocking, receipts). Mirror of loki-ts/src/providers/model_routes.ts.
|
|
7
|
+
#
|
|
8
|
+
# Spec forms (env LOKI_MODEL_ROUTE, or LOKI_MODEL_OVERRIDE when it is a route):
|
|
9
|
+
# openrouter/<id> https://openrouter.ai/api token: OPENROUTER_API_KEY
|
|
10
|
+
# ollama/<id> http://localhost:11434
|
|
11
|
+
# lmstudio/<id> http://localhost:1234
|
|
12
|
+
# llamacpp/<id> http://localhost:8080
|
|
13
|
+
# vllm/<id> http://localhost:8000
|
|
14
|
+
# custom/<id> LOKI_MODEL_BASE_URL (+ optional LOKI_MODEL_API_KEY)
|
|
15
|
+
# Plain Claude ids (opus, sonnet, claude-*) are not routes: behavior unchanged.
|
|
16
|
+
#
|
|
17
|
+
# The env is applied only inside providers/model_route_exec.sh, which execs the
|
|
18
|
+
# claude child. It is never exported into the parent shell, and the token is
|
|
19
|
+
# never placed on a command line or logged.
|
|
20
|
+
|
|
21
|
+
# kind -> "base_url|token_var"
|
|
22
|
+
loki_model_route_table() {
|
|
23
|
+
case "$1" in
|
|
24
|
+
openrouter) echo "https://openrouter.ai/api|OPENROUTER_API_KEY" ;;
|
|
25
|
+
ollama) echo "http://localhost:11434|" ;;
|
|
26
|
+
lmstudio) echo "http://localhost:1234|" ;;
|
|
27
|
+
llamacpp) echo "http://localhost:8080|" ;;
|
|
28
|
+
vllm) echo "http://localhost:8000|" ;;
|
|
29
|
+
custom) echo "${LOKI_MODEL_BASE_URL:-}|LOKI_MODEL_API_KEY" ;;
|
|
30
|
+
*) return 1 ;;
|
|
31
|
+
esac
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Echo the active route spec, or nothing when none is configured.
|
|
35
|
+
loki_model_route_spec() {
|
|
36
|
+
local s="${LOKI_MODEL_ROUTE:-}"
|
|
37
|
+
if [ -z "$s" ]; then
|
|
38
|
+
s="${LOKI_MODEL_OVERRIDE:-}"
|
|
39
|
+
case "$s" in
|
|
40
|
+
*/*) loki_model_route_table "${s%%/*}" >/dev/null 2>&1 || s="" ;;
|
|
41
|
+
*) s="" ;;
|
|
42
|
+
esac
|
|
43
|
+
fi
|
|
44
|
+
[ -n "$s" ] && printf '%s\n' "$s"
|
|
45
|
+
return 0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Parse a spec. Sets LOKI_ROUTE_KIND, LOKI_ROUTE_MODEL, LOKI_ROUTE_BASE, LOKI_ROUTE_TOKEN_VAR.
|
|
49
|
+
# Returns 1 when the spec is not a usable route.
|
|
50
|
+
loki_model_route_parse() {
|
|
51
|
+
local spec="${1:-}" kind model entry
|
|
52
|
+
case "$spec" in */*) ;; *) return 1 ;; esac
|
|
53
|
+
kind="${spec%%/*}"
|
|
54
|
+
model="${spec#*/}"
|
|
55
|
+
[ -n "$model" ] || return 1
|
|
56
|
+
entry="$(loki_model_route_table "$kind")" || return 1
|
|
57
|
+
LOKI_ROUTE_KIND="$kind"
|
|
58
|
+
LOKI_ROUTE_MODEL="$model"
|
|
59
|
+
LOKI_ROUTE_BASE="${entry%%|*}"
|
|
60
|
+
LOKI_ROUTE_TOKEN_VAR="${entry#*|}"
|
|
61
|
+
[ -n "$LOKI_ROUTE_BASE" ] || return 1
|
|
62
|
+
return 0
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Echo the model id served by the active route (empty when none).
|
|
66
|
+
loki_model_route_model() {
|
|
67
|
+
local spec
|
|
68
|
+
spec="$(loki_model_route_spec)"
|
|
69
|
+
[ -n "$spec" ] || return 0
|
|
70
|
+
loki_model_route_parse "$spec" && printf '%s\n' "$LOKI_ROUTE_MODEL"
|
|
71
|
+
return 0
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Populate _LOKI_ROUTE_EXEC with a command prefix for the claude child. Empty
|
|
75
|
+
# array when no route is active, so callers expand it with ${arr[@]+...}.
|
|
76
|
+
loki_model_route_prefix() {
|
|
77
|
+
_LOKI_ROUTE_EXEC=()
|
|
78
|
+
local spec dir
|
|
79
|
+
spec="$(loki_model_route_spec)"
|
|
80
|
+
[ -n "$spec" ] || return 0
|
|
81
|
+
loki_model_route_parse "$spec" || return 0
|
|
82
|
+
dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" 2>/dev/null && pwd)"
|
|
83
|
+
_LOKI_ROUTE_EXEC=(bash "$dir/model_route_exec.sh")
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Local runtime probe: print "<runtime>\t<model id>" per discovered model.
|
|
87
|
+
# 1s timeouts. Uses python3 only to parse JSON.
|
|
88
|
+
loki_models_probe_local() {
|
|
89
|
+
local rt url path body
|
|
90
|
+
for rt in "ollama|http://localhost:11434|/api/tags" \
|
|
91
|
+
"lmstudio|http://localhost:1234|/v1/models" \
|
|
92
|
+
"llamacpp|http://localhost:8080|/v1/models" \
|
|
93
|
+
"vllm|http://localhost:8000|/v1/models"; do
|
|
94
|
+
IFS='|' read -r name url path <<EOF
|
|
95
|
+
$rt
|
|
96
|
+
EOF
|
|
97
|
+
body="$(curl -s --connect-timeout 1 --max-time 1 "${url}${path}" 2>/dev/null)" || continue
|
|
98
|
+
[ -n "$body" ] || continue
|
|
99
|
+
printf '%s' "$body" | python3 -c '
|
|
100
|
+
import json, sys
|
|
101
|
+
name = sys.argv[1]
|
|
102
|
+
try:
|
|
103
|
+
d = json.load(sys.stdin)
|
|
104
|
+
except Exception:
|
|
105
|
+
sys.exit(0)
|
|
106
|
+
items = d.get("models") if isinstance(d, dict) and "models" in d else d.get("data", []) if isinstance(d, dict) else []
|
|
107
|
+
for m in items or []:
|
|
108
|
+
mid = (m.get("name") or m.get("model") or m.get("id")) if isinstance(m, dict) else None
|
|
109
|
+
if mid:
|
|
110
|
+
print(name + "\t" + mid)
|
|
111
|
+
' "$name"
|
|
112
|
+
done
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# loki models [--routes] [--local] [--json]
|
|
116
|
+
loki_models_cmd() {
|
|
117
|
+
local want_local=0 json=0 arg
|
|
118
|
+
for arg in "$@"; do
|
|
119
|
+
case "$arg" in
|
|
120
|
+
--local) want_local=1 ;;
|
|
121
|
+
--json) json=1 ;;
|
|
122
|
+
--routes) ;;
|
|
123
|
+
-h|--help)
|
|
124
|
+
echo "Usage: loki models [--local] [--json]"
|
|
125
|
+
echo ""
|
|
126
|
+
echo " (default) List model routes usable as --model / LOKI_MODEL_ROUTE values"
|
|
127
|
+
echo " --local Probe local runtimes (ollama, lmstudio, llamacpp, vllm) for models"
|
|
128
|
+
echo " --json Machine-readable output"
|
|
129
|
+
echo ""
|
|
130
|
+
echo "Route env: LOKI_MODEL_ROUTE=openrouter/<id> | ollama/<id> | lmstudio/<id> |"
|
|
131
|
+
echo " llamacpp/<id> | vllm/<id> | custom/<id> (needs LOKI_MODEL_BASE_URL)"
|
|
132
|
+
return 0
|
|
133
|
+
;;
|
|
134
|
+
*) echo "loki models: unknown option: $arg" >&2; return 2 ;;
|
|
135
|
+
esac
|
|
136
|
+
done
|
|
137
|
+
|
|
138
|
+
local kinds="openrouter ollama lmstudio llamacpp vllm custom" k entry base tvar
|
|
139
|
+
if [ "$want_local" = "1" ]; then
|
|
140
|
+
local found
|
|
141
|
+
found="$(loki_models_probe_local)"
|
|
142
|
+
if [ "$json" = "1" ]; then
|
|
143
|
+
printf '%s' "$found" | python3 -c '
|
|
144
|
+
import json, sys
|
|
145
|
+
out = []
|
|
146
|
+
for line in sys.stdin.read().splitlines():
|
|
147
|
+
rt, _, mid = line.partition("\t")
|
|
148
|
+
out.append({"runtime": rt, "id": mid, "model": rt + "/" + mid})
|
|
149
|
+
print(json.dumps({"local": out}, indent=2))
|
|
150
|
+
'
|
|
151
|
+
elif [ -z "$found" ]; then
|
|
152
|
+
echo "No local runtimes responded (probed :11434 ollama, :1234 lmstudio, :8080 llamacpp, :8000 vllm)."
|
|
153
|
+
else
|
|
154
|
+
echo "Discovered local models (paste as LOKI_MODEL_ROUTE=<value>):"
|
|
155
|
+
printf '%s\n' "$found" | while IFS="$(printf '\t')" read -r rt mid; do
|
|
156
|
+
echo " $rt/$mid"
|
|
157
|
+
done
|
|
158
|
+
fi
|
|
159
|
+
return 0
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
if [ "$json" = "1" ]; then
|
|
163
|
+
local sep="" first=1
|
|
164
|
+
printf '{"routes": ['
|
|
165
|
+
for k in $kinds; do
|
|
166
|
+
entry="$(loki_model_route_table "$k")"; base="${entry%%|*}"; tvar="${entry#*|}"
|
|
167
|
+
[ "$first" = "1" ] || printf ','
|
|
168
|
+
first=0
|
|
169
|
+
printf '{"kind":"%s","base_url":"%s","token_env":"%s","example":"%s/<model-id>"}' "$k" "$base" "$tvar" "$k"
|
|
170
|
+
done
|
|
171
|
+
printf ']}\n'
|
|
172
|
+
return 0
|
|
173
|
+
fi
|
|
174
|
+
echo "Model routes (run any Anthropic-compatible endpoint through the Claude harness):"
|
|
175
|
+
for k in $kinds; do
|
|
176
|
+
entry="$(loki_model_route_table "$k")"; base="${entry%%|*}"; tvar="${entry#*|}"
|
|
177
|
+
[ "$k" = "custom" ] && base="\$LOKI_MODEL_BASE_URL"
|
|
178
|
+
printf ' %-11s %-28s %s\n' "$k/<id>" "$base" "${tvar:+token: \$$tvar}"
|
|
179
|
+
done
|
|
180
|
+
echo ""
|
|
181
|
+
echo "Use: LOKI_MODEL_ROUTE=ollama/qwen3-coder loki start ./prd.md"
|
|
182
|
+
echo "Discover local models: loki models --local"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# Allow direct execution: bash providers/model_routes.sh [args]
|
|
186
|
+
if [ "${BASH_SOURCE[0]:-}" = "$0" ]; then
|
|
187
|
+
loki_models_cmd "$@"
|
|
188
|
+
fi
|
package/skills/providers.md
CHANGED
|
@@ -19,6 +19,7 @@ Loki Mode supports five AI providers for autonomous execution.
|
|
|
19
19
|
| **Model Tiers** | 3 (opus/sonnet/haiku) | 1 (effort param) | 1 (external) | 1 (external) | 1 (external) |
|
|
20
20
|
| **Multi-Provider** | Claude only | OpenAI only | 12+ providers | 18+ providers | 75+ providers + custom endpoints |
|
|
21
21
|
| **Skill Directory** | ~/.claude/skills | None | None | None | ~/.config/opencode |
|
|
22
|
+
| **Guardrails (engine10)** | Native hooks + permission flags | Timeout + budget kill, diff scan, sandbox flag | Timeout + budget kill, diff scan | Timeout + budget kill, diff scan, no-auto-commits | Timeout + budget kill, diff scan |
|
|
22
23
|
|
|
23
24
|
## Provider Selection
|
|
24
25
|
|
|
@@ -396,3 +397,15 @@ PROVIDER_DEGRADED=false
|
|
|
396
397
|
| Local models (Ollama, free) | opencode, Aider, or Cline |
|
|
397
398
|
| Architect mode (dual model) | Aider |
|
|
398
399
|
| Sequential-only is acceptable | Codex or Aider |
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Guardrail Parity (engine10)
|
|
404
|
+
|
|
405
|
+
Claude blocks destructive commands inline through its hooks and permission flags. For codex, cline, aider and opencode, engine10 applies `loki-ts/src/providers/provider_guard.ts` around every session:
|
|
406
|
+
|
|
407
|
+
1. Wall-clock timeout (`limitS`) and a budget-stop poll (`BUDGET_LIMIT`) kill the whole process group.
|
|
408
|
+
2. After each session a diff scan fails the iteration and reverts: mass deletion of tracked files, `.git/config` edits, new git hooks, symlinks or paths that point outside the project.
|
|
409
|
+
3. Native CLI flags are used where they exist: codex `--sandbox workspace-write`, aider `--no-auto-commits`. Cline and opencode have no filesystem sandbox flag.
|
|
410
|
+
|
|
411
|
+
The scan is post-hoc, not inline, so the receipt still lists `kill blocking not enforced` for non-Claude providers. Violations emit a `guard.violation` event.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: planner
|
|
3
|
+
description: Breaks a goal into small ordered tasks with acceptance checks
|
|
4
|
+
model: opus
|
|
5
|
+
provider: claude
|
|
6
|
+
permission: plan
|
|
7
|
+
tools: [Read, Grep, Glob]
|
|
8
|
+
deny: [Edit, Write, Bash]
|
|
9
|
+
---
|
|
10
|
+
You are a planning agent. Read the repository and split the goal into small, independently verifiable tasks. For each task give: goal, files likely touched, acceptance check, and risk. Order tasks by dependency. Do not write code.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: Skeptical code reviewer for correctness, tests and maintainability
|
|
4
|
+
model: sonnet
|
|
5
|
+
provider: claude
|
|
6
|
+
permission: plan
|
|
7
|
+
tools: [Read, Grep, Glob]
|
|
8
|
+
deny: [Edit, Write]
|
|
9
|
+
---
|
|
10
|
+
You are a senior code reviewer. Review the supplied evidence for correctness bugs, missing tests, security problems and maintainability issues. Cite file and line for every finding. Do not modify files. Report APPROVE only when you found no blocking issue.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tester
|
|
3
|
+
description: Writes and runs focused tests for a change, reports gaps
|
|
4
|
+
model: sonnet
|
|
5
|
+
provider: claude
|
|
6
|
+
permission: edit
|
|
7
|
+
tools: [Read, Grep, Glob, Edit, Write, Bash]
|
|
8
|
+
deny: []
|
|
9
|
+
---
|
|
10
|
+
You are a test engineer. For the given change, add the smallest set of tests that fail before the change and pass after. Run them and report exact commands and results. Do not alter production code; report any production bug you find instead.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-
|
|
1
|
+
import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-Dzs-9EgJ.js";import{B as C}from"./Button-709-wwGM.js";import{T as $e}from"./trending-up-mFogTjt3.js";import{C as z}from"./clock-CdpdJTId.js";import{A as Be,U as ue,M as De}from"./Avatar-DdK4wynI.js";import{A as J}from"./activity-icIsXJVa.js";import{R as pe}from"./refresh-cw-BKdlCa7F.js";import{G as ze}from"./globe-6w-hnQkL.js";import{C as Le}from"./chevron-left-D09jDZ29.js";import{C as je}from"./check-D1OBxHeU.js";import{D as Y}from"./dollar-sign-CuioDaOG.js";import{U as Te}from"./user-BYGIFaTm.js";import{D as Me}from"./database-CMQQuM2R.js";import{L as Ue}from"./lock-D51L7rYh.js";import{S as Re}from"./scroll-text-DbkegIxF.js";import{S as Ie}from"./shield-alert-BuR1tPHu.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./index-
|
|
1
|
+
import{j as e}from"./index-Dzs-9EgJ.js";import{C as r}from"./clock-CdpdJTId.js";import{C as a}from"./circle-alert-DyZMLOcC.js";import{C as l}from"./check-D1OBxHeU.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as p,j as t}from"./index-
|
|
1
|
+
import{r as p,j as t}from"./index-Dzs-9EgJ.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-
|
|
1
|
+
import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-Dzs-9EgJ.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-B0uJSys8.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-BF6p3mRd.js";import{C as oe}from"./check-D1OBxHeU.js";import{C as Ye}from"./clock-CdpdJTId.js";import{D as Xe}from"./dollar-sign-CuioDaOG.js";import{U as Ze}from"./upload-4T8zpBsi.js";import{L as V}from"./loader-circle-C6Y9x_7H.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as o,j as e}from"./index-wvGJotyF.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
|
|
1
|
+
import{r as o,j as e}from"./index-Dzs-9EgJ.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
|
package/web-app/dist/assets/{EvidenceReceiptPanel-CwmAqJ90.js → EvidenceReceiptPanel-BtMFgElP.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as l,a as x,j as e}from"./index-
|
|
1
|
+
import{r as l,a as x,j as e}from"./index-Dzs-9EgJ.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-
|
|
1
|
+
import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-Dzs-9EgJ.js";import{B as N}from"./Button-709-wwGM.js";import{C as y}from"./thumbs-up-BF6p3mRd.js";import{R as S}from"./refresh-cw-BKdlCa7F.js";import{C as z}from"./circle-alert-DyZMLOcC.js";import{U as D}from"./user-BYGIFaTm.js";import{L as G}from"./loader-circle-C6Y9x_7H.js";import{R as T}from"./rotate-ccw-_bd_YI1e.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-
|
|
1
|
+
import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-Dzs-9EgJ.js";import{B as y}from"./Button-709-wwGM.js";import{C as ge}from"./chevron-left-D09jDZ29.js";import{G as P}from"./thumbs-up-BF6p3mRd.js";import{R as $}from"./refresh-cw-BKdlCa7F.js";import{C as Ne}from"./circle-alert-DyZMLOcC.js";import{L as Q,S as je}from"./ProjectPage-BtlLEQwB.js";import{S as se}from"./shield-alert-BuR1tPHu.js";import{F as ye}from"./file-code-corner-Cx9j9K1S.js";import{C as V}from"./clock-CdpdJTId.js";import{C as re}from"./check-D1OBxHeU.js";import"./ErrorBoundary-B0uJSys8.js";import"./TerminalOutput-Cz_vPbXL.js";import"./lock-D51L7rYh.js";import"./package-BJF8hkP8.js";import"./file-plus-CYD2zaaI.js";import"./activity-icIsXJVa.js";import"./scroll-text-DbkegIxF.js";import"./bot-DvjP3Yh5.js";import"./loader-circle-C6Y9x_7H.js";import"./hammer-BpqtautL.js";import"./dollar-sign-CuioDaOG.js";import"./globe-6w-hnQkL.js";import"./trash-2-BVpnkqqz.js";import"./upload-4T8zpBsi.js";import"./plus-D5kUQ79n.js";import"./rotate-ccw-_bd_YI1e.js";import"./code-xml-DrkE2ZZY.js";import"./trending-up-mFogTjt3.js";import"./layers-D5hd7jb7.js";import"./trending-down-DpsDvRwW.js";import"./server-DAwqFIsq.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|