loki-mode 11.3.9 → 11.5.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.
- 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 +315 -0
- package/autonomy/lib/engine10-push.sh +19 -1
- package/autonomy/lib/help-core.sh +164 -0
- package/autonomy/lib/json-output.sh +38 -0
- package/autonomy/lib/proof-generator.py +23 -5
- package/autonomy/lib/proof-verify.py +607 -5
- package/autonomy/lib/run-summary.sh +112 -0
- package/autonomy/lib/setup-requirements.json +35 -0
- package/autonomy/loki +337 -46
- package/autonomy/provider-offer.sh +95 -47
- package/autonomy/route.sh +302 -0
- package/autonomy/run.sh +48 -14
- package/autonomy/setup-wizard.sh +170 -0
- package/autonomy/verify.sh +62 -3
- package/bin/loki +73 -18
- package/completions/_loki +58 -1
- package/completions/loki.bash +57 -5
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-CORE-VERBS.md +112 -0
- package/docs/CLI-REFERENCE.md +9 -1
- package/docs/COMPARE-OPENCODE.md +94 -0
- package/docs/COMPONENTS.md +1 -0
- package/docs/EVALUATING.md +27 -0
- package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
- package/docs/INSTALLATION.md +56 -12
- package/docs/KNOWN-ISSUES.md +8 -9
- package/docs/PROOF-PASSPORT.md +114 -0
- package/docs/QUICKSTART.md +108 -0
- package/docs/alternative-installations.md +103 -0
- package/docs/cost-controls.md +139 -0
- package/docs/environment-variables.md +45 -2
- package/docs/exit-codes.md +129 -12
- package/docs/spec-first-intent.md +29 -0
- package/docs/v10/CLI-MODERN.md +11 -5
- package/docs/v10/ENGINE.md +32 -0
- package/docs/v10/GUIDE.md +270 -44
- package/docs/v10/OPENCODE-PARITY-PLAN.md +84 -0
- package/loki-ts/data/model-pricing.json +1 -0
- package/loki-ts/dist/loki.js +1065 -978
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +1829 -715
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/plugins/loki-mode/README.md +41 -1
- package/plugins/loki-mode/commands/handoff.md +12 -0
- package/plugins/loki-mode/commands/loki-verify.md +9 -2
- package/plugins/loki-mode/commands/start.md +20 -0
- package/plugins/loki-mode/hooks/hooks.json +11 -0
- package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
- 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-QK-i_x-O.js → AdminPage-Cbu3pXL8.js} +1 -1
- package/web-app/dist/assets/{Avatar-DblkLNjB.js → Avatar-DGqGGcGx.js} +1 -1
- package/web-app/dist/assets/{Badge-DIV2ny5H.js → Badge-Bhlipt6v.js} +1 -1
- package/web-app/dist/assets/{Button--rePJOlQ.js → Button-CpN2sO61.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BZlKxpGy.js → CockpitPage-BqeDJwdL.js} +1 -1
- package/web-app/dist/assets/{ComparePage-3_INSVux.js → ComparePage-DUieA2ba.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DHG63CNr.js → ErrorBoundary-DTWsYrOm.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-DFsBnLlO.js → EvidenceReceiptPanel-BU_B9X19.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-phPGah98.js → GitHubIssuesPanel-DEZoLOsP.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-T7KQqJmx.js → GitHubPRsPanel-BEsnrq7Y.js} +1 -1
- package/web-app/dist/assets/{HomePage-DFjGUF5I.js → HomePage-BoUVuq7h.js} +2 -2
- package/web-app/dist/assets/{LoginPage-CorUid_5.js → LoginPage-CmOED7vb.js} +1 -1
- package/web-app/dist/assets/{MagicPage-DofbSxKD.js → MagicPage-DATZitrZ.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-qzrhhfLC.js → MetricsPage-DGL1v0I-.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-BAZR0mMb.js → NotFoundPage-C2WgOjZd.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BOSUzG9J.js → ProjectPage-BMi1tepj.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Ba0YLtzD.js → ProjectsPage-vc3y5YPh.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-Cr10Ue2K.js → SettingsPage-kbq0Ftvi.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Czn655fe.js → ShowcasePage-Bn6Q8Kbg.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Dwjnw6Ob.js → SystemSettingsPage-Basmhs_b.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-D8nc69Be.js → TeamsPage-BTqOc4TR.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DHsaCDGv.js → TemplatesPage-2P9002VL.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DBejni2a.js → TerminalOutput-CAoSPBrg.js} +1 -1
- package/web-app/dist/assets/{activity-B2VsBl1C.js → activity-BcWVWCqU.js} +1 -1
- package/web-app/dist/assets/{bell-CT77Fq2H.js → bell-CYRqqgZ6.js} +1 -1
- package/web-app/dist/assets/{bot-DfaWgF4H.js → bot-CU7gdn3g.js} +1 -1
- package/web-app/dist/assets/{check-D1yp7Ndv.js → check-DLlCpz9V.js} +1 -1
- package/web-app/dist/assets/{chevron-left-B6Pa8IOX.js → chevron-left-CE9Cb30C.js} +1 -1
- package/web-app/dist/assets/{circle-alert-D5jrL_Y7.js → circle-alert-uou4bjua.js} +1 -1
- package/web-app/dist/assets/{clock-DIsY_fa_.js → clock-C_dSJcDX.js} +1 -1
- package/web-app/dist/assets/{cloud-eGwLh1As.js → cloud-DZ22ITF6.js} +1 -1
- package/web-app/dist/assets/{code-xml-CGDIcZ3m.js → code-xml-BrJS0hhS.js} +1 -1
- package/web-app/dist/assets/{database-CWpdaykI.js → database-D2HOmxtl.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DZEuTCs6.js → dollar-sign-CQ1vK_6q.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BHBW6m9v.js → file-code-corner-w2vpGm5d.js} +1 -1
- package/web-app/dist/assets/{file-plus-D4h1jZSR.js → file-plus-DlF6wjkD.js} +1 -1
- package/web-app/dist/assets/{globe-CXdqKgwd.js → globe-Dy3lBJg1.js} +1 -1
- package/web-app/dist/assets/{hammer-B3YuuYI_.js → hammer-C3xIiRXN.js} +1 -1
- package/web-app/dist/assets/{index-BLEnboSv.js → index-4t-_IW2y.js} +3 -3
- package/web-app/dist/assets/{layers-Dvp5nFtw.js → layers-Y8Fs8qXI.js} +1 -1
- package/web-app/dist/assets/{loader-circle-DodDmIZ3.js → loader-circle-CxgN1v4m.js} +1 -1
- package/web-app/dist/assets/{lock-EiuaH1Ep.js → lock-DFFNbXDs.js} +1 -1
- package/web-app/dist/assets/{package-Cx4m2hFg.js → package-5e6qCTUg.js} +1 -1
- package/web-app/dist/assets/{plus-D-Sd5rpH.js → plus-C0Go_ytj.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-C0w1cdmF.js → refresh-cw-D4i-NW3o.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-C_qk6MTT.js → rotate-ccw-YlKkiUW6.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DSxiFtkc.js → scroll-text-4qXOHTap.js} +1 -1
- package/web-app/dist/assets/{server-NTJt7I8M.js → server-BB6zXNp9.js} +1 -1
- package/web-app/dist/assets/{shield-alert-HBxMQOvH.js → shield-alert-D4tzjB1H.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-DEgsHzSD.js → thumbs-up-DZiRwdFj.js} +1 -1
- package/web-app/dist/assets/{trash-2-px46FnTD.js → trash-2-Dv_LkRIK.js} +1 -1
- package/web-app/dist/assets/{trending-down-CBosVGKa.js → trending-down-BJYp9PQe.js} +1 -1
- package/web-app/dist/assets/{trending-up-Dbd7zrQj.js → trending-up-BTcXLklK.js} +1 -1
- package/web-app/dist/assets/{upload-nhdFKAs1.js → upload-fcHqwOxr.js} +1 -1
- package/web-app/dist/assets/{usePolling-BgaGdinh.js → usePolling-BeJYw_4L.js} +1 -1
- package/web-app/dist/assets/{user-CzIihUy9.js → user-BcDwUCsO.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.5.1",
|
|
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",
|
|
@@ -35,7 +35,14 @@ Slash commands (namespaced as `loki-mode:<command>`):
|
|
|
35
35
|
- `loki-mode:loki-spec-status` - check whether the spec has drifted from its
|
|
36
36
|
lock using deterministic living-spec drift detection.
|
|
37
37
|
- `loki-mode:loki-verify` - run Loki's deterministic PR verification on the
|
|
38
|
-
current change and summarize the evidence verdict.
|
|
38
|
+
current change and summarize the evidence verdict. `--fast [base]` runs
|
|
39
|
+
`loki verify --fast --diff-base ${base:-HEAD}` instead: deterministic, no
|
|
40
|
+
model or network call (exit 0 PASS, 1 FAIL, 3 INCONCLUSIVE).
|
|
41
|
+
- `loki-mode:start <task or file>` - hand a task to Loki (`loki start --bg`).
|
|
42
|
+
Free-text tasks are written to `.loki/handoff-task.md` first. Claude Code
|
|
43
|
+
does not build it; Loki owns provider setup, budget and routing.
|
|
44
|
+
- `loki-mode:handoff` - print `.loki/review/HANDOFF.md`, else `./HANDOFF.md`,
|
|
45
|
+
else `loki own`. Never invents text.
|
|
39
46
|
|
|
40
47
|
MCP server (`loki-mode`): exposes Loki's tools (memory, task queue, code
|
|
41
48
|
search, build management) to Claude Code.
|
|
@@ -82,6 +89,39 @@ runs before:
|
|
|
82
89
|
With `LOKI_GUARD` unset the hook always allows the command through, so it never
|
|
83
90
|
interferes unless you ask it to.
|
|
84
91
|
|
|
92
|
+
## Optional Stop hook: fast verifier gate (off by default)
|
|
93
|
+
|
|
94
|
+
The plugin ships a `Stop` hook (`scripts/loki-stop-verify.sh`, hook timeout
|
|
95
|
+
30 s) that is a no-op unless `LOKI_STOP_VERIFY=1` (environment or Claude Code
|
|
96
|
+
settings `env`) or the plugin option `CLAUDE_PLUGIN_OPTION_STOP_VERIFY` is set.
|
|
97
|
+
It blocks completion only when `loki verify --fast --diff-base HEAD` exits 1
|
|
98
|
+
(FAIL: at least one high-severity finding), emitting
|
|
99
|
+
`{"decision":"block","reason":"..."}` with the first 15 verifier lines.
|
|
100
|
+
|
|
101
|
+
It allows the stop (fail-open) when: not opted in; the event has
|
|
102
|
+
`stop_hook_active: true` (never loops after one block); `loki`, `git` or a git
|
|
103
|
+
work tree is absent; no tracked file has uncommitted changes; the verifier
|
|
104
|
+
times out (`LOKI_STOP_VERIFY_TIMEOUT`, default 20 s); or it exits with anything
|
|
105
|
+
other than 1 (INCONCLUSIVE is not a block). Untracked new files are outside the
|
|
106
|
+
diff scope, and the fast verifier covers its detector set, not your test suite.
|
|
107
|
+
|
|
108
|
+
## Configure Claude Code from the CLI
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
loki setup-skill --claude-code [--print] [--project] [--stop-hook] [--settings FILE]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Merges `extraKnownMarketplaces.loki-mode`, `enabledPlugins["loki-mode@loki-mode"]`
|
|
115
|
+
and, with `--stop-hook`, `env.LOKI_STOP_VERIFY` into `~/.claude/settings.json`
|
|
116
|
+
(`--project`: `./.claude/settings.json`). Existing keys are kept as you set them
|
|
117
|
+
(even `false`), invalid JSON is refused (exit 3) with the file untouched,
|
|
118
|
+
writes are atomic, and a second run reports `UNCHANGED`. `--print` prints the
|
|
119
|
+
snippet and writes nothing. Then run `/reload-plugins` in Claude Code.
|
|
120
|
+
|
|
121
|
+
Claude Code keeps tool permissions, the Stop-hook protocol, plugin
|
|
122
|
+
install/update and the session itself; the plugin adds no model loop,
|
|
123
|
+
permission system or sandbox.
|
|
124
|
+
|
|
85
125
|
## License
|
|
86
126
|
|
|
87
127
|
SEE LICENSE IN LICENSE (BUSL-1.1, source-available). See the LICENSE file at the
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Print Loki's review handoff (.loki/review/HANDOFF.md) for the last run.
|
|
3
|
+
allowed-tools: Read, Bash(ls:*), Bash(loki own:*)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Show the user what Loki handed off, verbatim.
|
|
7
|
+
|
|
8
|
+
1. If `.loki/review/HANDOFF.md` exists, Read it and print it unchanged.
|
|
9
|
+
2. Else if `HANDOFF.md` exists at the project root, Read and print that.
|
|
10
|
+
3. Else run `loki own` and print its output.
|
|
11
|
+
4. If none yields content, say no handoff exists yet and suggest
|
|
12
|
+
`/loki-mode:start <task>`. Do not invent a summary.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Run Loki's deterministic PR verification on the current change and summarize the evidence verdict.
|
|
3
|
-
argument-hint: "[base-ref] (default: main)"
|
|
4
|
-
allowed-tools: Bash(loki verify:*), Read
|
|
3
|
+
argument-hint: "[--fast] [base-ref] (default: main; --fast defaults to HEAD, the uncommitted changes)"
|
|
4
|
+
allowed-tools: Bash(loki verify:*), Bash(command -v:*), Read
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
Run Loki's Autonomi Verify on the current working tree and report the verdict
|
|
@@ -9,6 +9,13 @@ with its evidence, not just an opinion in chat. The differentiator is the
|
|
|
9
9
|
auditable artifact: a verdict that refuses to silently pass on inconclusive
|
|
10
10
|
evidence.
|
|
11
11
|
|
|
12
|
+
Fast mode: if $ARGUMENTS starts with `--fast`, check `command -v loki` (stop if
|
|
13
|
+
missing) and run `loki verify --fast --diff-base <ref>` (ref defaults to
|
|
14
|
+
`HEAD`). It is deterministic, with no model or network call. Exit codes: 0 PASS,
|
|
15
|
+
1 FAIL, 3 INCONCLUSIVE. Print the verdict line and each finding as
|
|
16
|
+
`severity rule path:line`, say which findings block (severity high), and never
|
|
17
|
+
describe INCONCLUSIVE as a pass. Skip the steps below.
|
|
18
|
+
|
|
12
19
|
Steps:
|
|
13
20
|
|
|
14
21
|
1. Run the verifier against the base ref ($ARGUMENTS, or `main` if empty):
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Hand the current task to Loki (loki start) in the background and report where the handoff will land.
|
|
3
|
+
argument-hint: "<task description or path to a PRD/spec file>"
|
|
4
|
+
allowed-tools: Bash(loki start:*), Bash(loki status:*), Bash(command -v:*), Bash(ls:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Delegate the task in $ARGUMENTS to Loki Mode so it runs autonomously while the
|
|
8
|
+
user does something else. Do not start building the task yourself.
|
|
9
|
+
|
|
10
|
+
1. Confirm the CLI exists: `command -v loki`. If missing, say
|
|
11
|
+
`npm install -g loki-mode` is required and stop.
|
|
12
|
+
2. If $ARGUMENTS is an existing file path, run `loki start --bg <path>`.
|
|
13
|
+
Otherwise write the text to `.loki/handoff-task.md` (create `.loki/` if
|
|
14
|
+
needed) and run `loki start --bg .loki/handoff-task.md`. Do not pass any
|
|
15
|
+
permission-bypass flags of your own; `loki start` owns its provider setup.
|
|
16
|
+
3. Report in at most five lines: that the run started in the background, the
|
|
17
|
+
command to check progress (`loki status`), and where results land:
|
|
18
|
+
`.loki/review/HANDOFF.md` (read it with `/loki-mode:handoff`) and the
|
|
19
|
+
evidence verdict (`/loki-mode:loki-verify --fast`).
|
|
20
|
+
4. If `loki start` exits non-zero, show its first error line verbatim and stop.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Loki Stop hook: run the fast deterministic verifier on the working tree and
|
|
3
|
+
# block completion when the uncommitted change carries a blocking finding.
|
|
4
|
+
#
|
|
5
|
+
# Opt-in. No-op unless LOKI_STOP_VERIFY is truthy (or the plugin option
|
|
6
|
+
# CLAUDE_PLUGIN_OPTION_STOP_VERIFY is). Fail-open: every uncertain path
|
|
7
|
+
# (loki missing, not a git repo, clean tree, timeout, verifier error,
|
|
8
|
+
# INCONCLUSIVE, stop_hook_active) allows the stop. Only an explicit verifier
|
|
9
|
+
# exit 1 (FAIL, a high-severity finding) blocks.
|
|
10
|
+
#
|
|
11
|
+
# Block contract: print {"decision":"block","reason":...} on stdout, exit 0.
|
|
12
|
+
|
|
13
|
+
set -u
|
|
14
|
+
|
|
15
|
+
allow() { exit 0; }
|
|
16
|
+
|
|
17
|
+
truthy() {
|
|
18
|
+
case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in
|
|
19
|
+
1 | true | yes | on | y) return 0 ;;
|
|
20
|
+
*) return 1 ;;
|
|
21
|
+
esac
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if ! truthy "${LOKI_STOP_VERIFY:-}" && ! truthy "${CLAUDE_PLUGIN_OPTION_STOP_VERIFY:-}"; then
|
|
25
|
+
allow
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
event="$(cat 2>/dev/null || true)"
|
|
29
|
+
|
|
30
|
+
# A previous block already re-entered the model once: never loop.
|
|
31
|
+
case "$event" in
|
|
32
|
+
*'"stop_hook_active": true'* | *'"stop_hook_active":true'*) allow ;;
|
|
33
|
+
esac
|
|
34
|
+
|
|
35
|
+
command -v loki >/dev/null 2>&1 || allow
|
|
36
|
+
command -v git >/dev/null 2>&1 || allow
|
|
37
|
+
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || allow
|
|
38
|
+
|
|
39
|
+
# Nothing changed: nothing the agent could have broken.
|
|
40
|
+
[ -n "$(git status --porcelain --untracked-files=no 2>/dev/null)" ] || allow
|
|
41
|
+
|
|
42
|
+
limit="${LOKI_STOP_VERIFY_TIMEOUT:-20}"
|
|
43
|
+
out_file="$(mktemp "${TMPDIR:-/tmp}/loki-stop-verify.XXXXXX")" || allow
|
|
44
|
+
trap 'rm -f "$out_file"' EXIT
|
|
45
|
+
|
|
46
|
+
run_verifier() { loki verify --fast --diff-base HEAD >"$out_file" 2>/dev/null; }
|
|
47
|
+
|
|
48
|
+
if command -v timeout >/dev/null 2>&1; then
|
|
49
|
+
timeout -k 2 "$limit" loki verify --fast --diff-base HEAD >"$out_file" 2>/dev/null
|
|
50
|
+
rc=$?
|
|
51
|
+
elif command -v gtimeout >/dev/null 2>&1; then
|
|
52
|
+
gtimeout -k 2 "$limit" loki verify --fast --diff-base HEAD >"$out_file" 2>/dev/null
|
|
53
|
+
rc=$?
|
|
54
|
+
else
|
|
55
|
+
# No timeout binary (stock macOS): watchdog on the recorded child PID only.
|
|
56
|
+
run_verifier &
|
|
57
|
+
child=$!
|
|
58
|
+
( sleep "$limit"; kill "$child" 2>/dev/null ) >/dev/null 2>&1 &
|
|
59
|
+
watchdog=$!
|
|
60
|
+
wait "$child" 2>/dev/null
|
|
61
|
+
rc=$?
|
|
62
|
+
kill "$watchdog" 2>/dev/null
|
|
63
|
+
wait "$watchdog" 2>/dev/null
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Only an explicit FAIL blocks. 0, 2, 3, 64, 124, 137 and anything else allow.
|
|
67
|
+
[ "$rc" -eq 1 ] || allow
|
|
68
|
+
|
|
69
|
+
summary="$(head -n 15 "$out_file" 2>/dev/null)"
|
|
70
|
+
reason="Loki fast verify found blocking problems in your uncommitted change. Fix them before finishing:
|
|
71
|
+
${summary}
|
|
72
|
+
Re-run: loki verify --fast --diff-base HEAD"
|
|
73
|
+
|
|
74
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
75
|
+
printf '%s' "$reason" | python3 -c '
|
|
76
|
+
import sys, json
|
|
77
|
+
print(json.dumps({"decision": "block", "reason": sys.stdin.read()}))
|
|
78
|
+
'
|
|
79
|
+
else
|
|
80
|
+
# No python3: single-line fallback with minimal escaping.
|
|
81
|
+
esc="$(printf '%s' "$reason" | tr '\n' ' ' | sed 's/\\/\\\\/g; s/"/\\"/g')"
|
|
82
|
+
printf '{"decision":"block","reason":"%s"}\n' "$esc"
|
|
83
|
+
fi
|
|
84
|
+
exit 0
|
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-4t-_IW2y.js";import{B as C}from"./Button-CpN2sO61.js";import{T as $e}from"./trending-up-BTcXLklK.js";import{C as z}from"./clock-C_dSJcDX.js";import{A as Be,U as ue,M as De}from"./Avatar-DGqGGcGx.js";import{A as J}from"./activity-BcWVWCqU.js";import{R as pe}from"./refresh-cw-D4i-NW3o.js";import{G as ze}from"./globe-Dy3lBJg1.js";import{C as Le}from"./chevron-left-CE9Cb30C.js";import{C as je}from"./check-DLlCpz9V.js";import{D as Y}from"./dollar-sign-CQ1vK_6q.js";import{U as Te}from"./user-BcDwUCsO.js";import{D as Me}from"./database-D2HOmxtl.js";import{L as Ue}from"./lock-DFFNbXDs.js";import{S as Re}from"./scroll-text-4qXOHTap.js";import{S as Ie}from"./shield-alert-D4tzjB1H.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-4t-_IW2y.js";import{C as r}from"./clock-C_dSJcDX.js";import{C as a}from"./circle-alert-uou4bjua.js";import{C as l}from"./check-DLlCpz9V.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-4t-_IW2y.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-4t-_IW2y.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DTWsYrOm.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-DZiRwdFj.js";import{C as oe}from"./check-DLlCpz9V.js";import{C as Ye}from"./clock-C_dSJcDX.js";import{D as Xe}from"./dollar-sign-CQ1vK_6q.js";import{U as Ze}from"./upload-fcHqwOxr.js";import{L as V}from"./loader-circle-CxgN1v4m.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|