loki-mode 9.54.0 → 9.55.0
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 +1 -1
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +120 -35
- package/autonomy/crash.sh +6 -6
- package/autonomy/lib/done-recognition.sh +7 -0
- package/autonomy/lib/prd-enrich.sh +7 -0
- package/autonomy/lib/proof-generator.py +36 -5
- package/autonomy/lib/proof-verify.py +93 -21
- package/autonomy/lib/voter-agents.sh +7 -0
- package/autonomy/loki +404 -119
- package/autonomy/quickstart.sh +7 -0
- package/autonomy/run.sh +836 -58
- package/autonomy/verify.sh +114 -8
- package/bin/loki +12 -0
- package/dashboard/__init__.py +1 -1
- package/dashboard/api_v2.py +4 -0
- package/dashboard/audit.py +9 -1
- package/dashboard/auth.py +16 -4
- package/dashboard/registry.py +34 -12
- package/dashboard/rigour_integration.py +25 -17
- package/dashboard/server.py +252 -104
- package/dashboard/static/cost.html +55 -26
- package/dashboard/static/index.html +475 -1544
- package/dashboard/static/proofs.html +1 -1
- package/docs/INSTALLATION.md +7 -6
- package/docs/air-gapped.md +38 -11
- package/docs/enterprise/security.md +10 -13
- package/docs/environment-variables.md +1 -0
- package/docs/exit-codes.md +76 -2
- package/docs/image-provenance.md +4 -2
- package/docs/v10/BACKLOG.md +64 -2
- package/docs/v10/BOARD.md +134 -0
- package/docs/v10/CONTROL.md +36 -0
- package/docs/v10/DECISIONS.md +102 -0
- package/docs/v10/METRICS.md +78 -1
- package/docs/v10/PROGRESS.md +240 -0
- package/docs/v10/SWARM-PROMPT.md +98 -0
- package/docs/v10/SWARM.md +237 -0
- package/loki-ts/dist/loki.js +7 -4
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/providers/aider.sh +8 -0
- package/providers/cline.sh +8 -0
- package/providers/codex.sh +9 -0
- package/providers/loader.sh +10 -0
- package/providers/opencode.sh +9 -0
- package/tools/receipt-attest.py +1 -1
- package/web-app/dist/assets/AdminPage-CZrBkzRF.js +32 -0
- package/web-app/dist/assets/Avatar-gQIp6FBI.js +11 -0
- package/web-app/dist/assets/{Badge-BF3mhT57.js → Badge-D2_fBTFY.js} +1 -1
- package/web-app/dist/assets/{Button-BDp9aJ9q.js → Button-D5qDd2ef.js} +1 -1
- package/web-app/dist/assets/CockpitPage-DVMk2RUK.js +47 -0
- package/web-app/dist/assets/ComparePage-NMLyE1xL.js +1 -0
- package/web-app/dist/assets/{ErrorBoundary-ut3wrUmu.js → ErrorBoundary-BRABI-BT.js} +1 -1
- package/web-app/dist/assets/EvidenceReceiptPanel-D2LNKqUx.js +1 -0
- package/web-app/dist/assets/GitHubIssuesPanel-BC5GzKUN.js +7 -0
- package/web-app/dist/assets/{GitHubPRsPanel-DurZgSaj.js → GitHubPRsPanel-BSlmoVTS.js} +3 -3
- package/web-app/dist/assets/HomePage-D_CDMoen.js +12 -0
- package/web-app/dist/assets/{LoginPage-HeRGJeZy.js → LoginPage-BBNA_N9t.js} +1 -1
- package/web-app/dist/assets/{MagicPage-CUKrqsZs.js → MagicPage-CnFRZCMx.js} +1 -1
- package/web-app/dist/assets/MetricsPage-CPfLMRlh.js +6 -0
- package/web-app/dist/assets/{NotFoundPage-BZDZ-B77.js → NotFoundPage-lA0XSGTz.js} +1 -1
- package/web-app/dist/assets/ProjectPage-CNAPbr9z.js +256 -0
- package/web-app/dist/assets/ProjectsPage-CMtm8goN.js +6 -0
- package/web-app/dist/assets/SettingsPage-BhIjVMYE.js +10 -0
- package/web-app/dist/assets/{ShowcasePage-BGS2jTGH.js → ShowcasePage-BndtGeYo.js} +1 -1
- package/web-app/dist/assets/SystemSettingsPage-euXI-KXE.js +1 -0
- package/web-app/dist/assets/TeamsPage-ClUKecun.js +11 -0
- package/web-app/dist/assets/TemplatesPage-BWHWVk0L.js +29 -0
- package/web-app/dist/assets/{TerminalOutput-togzv9Zl.js → TerminalOutput-Cv3N3Szf.js} +1 -1
- package/web-app/dist/assets/{activity-Dreyb_Kr.js → activity-dEhz-bXR.js} +1 -1
- package/web-app/dist/assets/{bell-DWH0drES.js → bell-B3XUMq1t.js} +1 -1
- package/web-app/dist/assets/{bot-78MoCuDl.js → bot-X-ssNlwR.js} +1 -1
- package/web-app/dist/assets/{check-ikfylPst.js → check-C_9Nx7kb.js} +1 -1
- package/web-app/dist/assets/{chevron-left-DXUqkd8J.js → chevron-left-tvNswo3A.js} +1 -1
- package/web-app/dist/assets/{circle-alert-Da74VO8P.js → circle-alert-CSB88nEs.js} +1 -1
- package/web-app/dist/assets/{clock-mlGCFq8l.js → clock-C8p2e4NI.js} +1 -1
- package/web-app/dist/assets/{cloud-B_Y5ZrIO.js → cloud-CKp2ZvhG.js} +1 -1
- package/web-app/dist/assets/{code-xml-Bbom7YWV.js → code-xml-dY70LCHD.js} +1 -1
- package/web-app/dist/assets/{database-CLcofiVp.js → database-DObn5fmn.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-C5mkjXIM.js → dollar-sign-DSu6n3K3.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-CVrkaOQP.js → file-code-corner-DpCnS73z.js} +1 -1
- package/web-app/dist/assets/{file-plus-BV9240gX.js → file-plus-D3IPKCf1.js} +1 -1
- package/web-app/dist/assets/{globe-aZ0Zso4I.js → globe-C9QXkgH_.js} +1 -1
- package/web-app/dist/assets/{hammer-EgOQNukG.js → hammer-D_FtWe1y.js} +1 -1
- package/web-app/dist/assets/index-CI54rara.css +1 -0
- package/web-app/dist/assets/{index-DvZ0Kk2x.js → index-Cz7q1bvC.js} +2 -2
- package/web-app/dist/assets/{layers-BOVKmepE.js → layers-DsW7jnJX.js} +1 -1
- package/web-app/dist/assets/{loader-circle-0K8yLgHl.js → loader-circle-B3HspjKR.js} +1 -1
- package/web-app/dist/assets/{lock-XzlDMy8M.js → lock-DSI29pct.js} +1 -1
- package/web-app/dist/assets/{package-BtXTKusI.js → package-CLNxtA2x.js} +1 -1
- package/web-app/dist/assets/{plus-PxeiD8ju.js → plus-DyI4WC4_.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-CjqzYczt.js → refresh-cw-D2dv0xA0.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-CY0os4DH.js → rotate-ccw-CBvihA-a.js} +1 -1
- package/web-app/dist/assets/scroll-text-DvoOvAl_.js +6 -0
- package/web-app/dist/assets/{server-pIIs9vNp.js → server-DenWvSUt.js} +1 -1
- package/web-app/dist/assets/{shield-alert-CsDqKXwA.js → shield-alert-40cX_FvG.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-CAh3HVzH.js → thumbs-up-BrjZ6QuV.js} +12 -7
- package/web-app/dist/assets/trash-2-C6evwkEH.js +16 -0
- package/web-app/dist/assets/{trending-down-DrtBd_C9.js → trending-down-CfbZis3O.js} +1 -1
- package/web-app/dist/assets/{trending-up-D-DbCHXm.js → trending-up-DWuEK3WC.js} +1 -1
- package/web-app/dist/assets/{upload-D4l6DCOt.js → upload-B9DFBcPG.js} +1 -1
- package/web-app/dist/assets/{usePolling-D0aoTX80.js → usePolling-BryVC-T1.js} +1 -1
- package/web-app/dist/assets/{user-BQf_XJO_.js → user-DMRXwZiw.js} +1 -1
- package/web-app/dist/index.html +2 -2
- package/web-app/server.py +122 -47
- package/web-app/dist/assets/AdminPage-y6_b2Xo4.js +0 -32
- package/web-app/dist/assets/Avatar-BFPkXhIJ.js +0 -6
- package/web-app/dist/assets/CockpitPage-5TKICCoA.js +0 -47
- package/web-app/dist/assets/ComparePage-BSuNsUHy.js +0 -1
- package/web-app/dist/assets/EvidenceReceiptPanel-CcaBwEI-.js +0 -1
- package/web-app/dist/assets/GitHubIssuesPanel-DJeYgzAa.js +0 -12
- package/web-app/dist/assets/HomePage-Bs451LAy.js +0 -28
- package/web-app/dist/assets/MetricsPage-DvY1csgz.js +0 -6
- package/web-app/dist/assets/ProjectPage-CqHkEZkl.js +0 -257
- package/web-app/dist/assets/ProjectsPage-CLvCK1Y8.js +0 -6
- package/web-app/dist/assets/SettingsPage-DP7OmdwP.js +0 -10
- package/web-app/dist/assets/SystemSettingsPage-P_rlLh0x.js +0 -1
- package/web-app/dist/assets/TeamsPage-DxtBDcBC.js +0 -11
- package/web-app/dist/assets/TemplatesPage-5e-faH3W.js +0 -29
- package/web-app/dist/assets/folder-open-D_6yV78G.js +0 -11
- package/web-app/dist/assets/index-BSgmPwC0.css +0 -1
- package/web-app/dist/assets/lightbulb-DdASgqOG.js +0 -6
- package/web-app/dist/assets/mail-COu670_W.js +0 -6
- package/web-app/dist/assets/minus-bQpUt9ff.js +0 -6
- package/web-app/dist/assets/save-v8qep5cY.js +0 -6
- package/web-app/dist/assets/trash-2-Dt6urTyY.js +0 -6
|
@@ -136,6 +136,17 @@
|
|
|
136
136
|
else if (s.split(".")[1].length === 1) s += "0";
|
|
137
137
|
return "$" + s;
|
|
138
138
|
}
|
|
139
|
+
// A total over runs where only some recorded a cost is a lower bound.
|
|
140
|
+
function projectTotal(d) {
|
|
141
|
+
return fmtUsd(d.project_total_usd) + (d.project_total_partial && d.project_total_usd != null ? " (partial)" : "");
|
|
142
|
+
}
|
|
143
|
+
// Same rule for a sum over iterations where only some recorded a cost.
|
|
144
|
+
function partialUsd(n, partial) {
|
|
145
|
+
return fmtUsd(n) + (partial && n !== null && n !== undefined ? " (partial)" : "");
|
|
146
|
+
}
|
|
147
|
+
function orNotRecorded(v) {
|
|
148
|
+
return (v === null || v === undefined) ? "not recorded" : esc(v);
|
|
149
|
+
}
|
|
139
150
|
function badgeClass(v) {
|
|
140
151
|
v = String(v || "").toUpperCase();
|
|
141
152
|
if (v.indexOf("APPROVE") === 0 || v === "PASS" || v === "PASSED") return "b-approve";
|
|
@@ -143,10 +154,13 @@
|
|
|
143
154
|
if (v.indexOf("CONCERN") === 0) return "b-concern";
|
|
144
155
|
return "";
|
|
145
156
|
}
|
|
146
|
-
function statusText(st) {
|
|
157
|
+
function statusText(st, partial) {
|
|
158
|
+
if (st === "ok" && partial) return "Within budget so far, but some iterations recorded no cost, so true spend may be higher.";
|
|
147
159
|
if (st === "exceeded") return "Budget cap reached. The run is paused to prevent a surprise bill.";
|
|
148
160
|
if (st === "warn") return "Approaching budget cap (80% or more used). Warning only, the run continues.";
|
|
149
161
|
if (st === "ok") return "Within budget.";
|
|
162
|
+
// A cap is set but no spend was measured: unknown, never "within budget".
|
|
163
|
+
if (st === "unknown") return "Spend not recorded yet, so budget use is unknown.";
|
|
150
164
|
return "No budget cap set. Set LOKI_BUDGET_LIMIT to cap spend.";
|
|
151
165
|
}
|
|
152
166
|
|
|
@@ -158,16 +172,19 @@
|
|
|
158
172
|
'<div class="cap-note">When a cap is set, Loki warns at 80% and hard-stops at 100%.</div></div>';
|
|
159
173
|
return html;
|
|
160
174
|
}
|
|
161
|
-
|
|
162
|
-
var
|
|
163
|
-
var
|
|
175
|
+
// Unknown use is not 0% used: no fill and no percentage are drawn for it.
|
|
176
|
+
var pct = (b.percent_used === null || b.percent_used === undefined) ? NaN : Number(b.percent_used);
|
|
177
|
+
var known = isFinite(pct);
|
|
178
|
+
var fillPct = known ? Math.max(0, Math.min(100, pct)) : 0;
|
|
179
|
+
var st = esc(b.status || "unknown");
|
|
180
|
+
var part = b.partial === true;
|
|
164
181
|
html += '<div class="gauge">' +
|
|
165
|
-
'<div class="top"><span class="muted">' +
|
|
166
|
-
'<span class="pct">' + pct.toFixed(1) + '
|
|
182
|
+
'<div class="top"><span class="muted">' + partialUsd(b.used, part) + ' of ' + fmtUsd(b.limit) + ' used</span>' +
|
|
183
|
+
'<span class="pct">' + (known ? pct.toFixed(1) + '%' + (part ? ' (partial)' : '') : 'not recorded') + '</span></div>' +
|
|
167
184
|
'<div class="bar"><div class="fill ' + st + '" style="width:' + fillPct + '%"></div>' +
|
|
168
185
|
'<div class="warnline" title="80% warn threshold"></div></div>' +
|
|
169
|
-
'<div class="status ' + st + '">' + statusText(b.status) + '</div>' +
|
|
170
|
-
'<div class="cap-note">Remaining: ' + fmtUsd(b.remaining) +
|
|
186
|
+
'<div class="status ' + st + '">' + statusText(b.status, part) + '</div>' +
|
|
187
|
+
'<div class="cap-note">Remaining: ' + (part && b.remaining != null ? 'at most ' : '') + fmtUsd(b.remaining) +
|
|
171
188
|
'. Warns at ' + esc(b.warn_threshold_percent) + '%, hard-stops at 100%.</div>' +
|
|
172
189
|
'</div>';
|
|
173
190
|
return html;
|
|
@@ -210,37 +227,49 @@
|
|
|
210
227
|
return html;
|
|
211
228
|
}
|
|
212
229
|
var its = cr.iterations;
|
|
213
|
-
// Inline SVG cumulative line.
|
|
230
|
+
// Inline SVG cumulative line. An iteration with no recorded cost is SKIPPED,
|
|
231
|
+
// never plotted at the floor as a measured zero; x keeps its index so the
|
|
232
|
+
// gap stays visible.
|
|
214
233
|
var W = 900, H = 140, pad = 8;
|
|
234
|
+
var measured = [];
|
|
215
235
|
var maxCum = 0;
|
|
216
236
|
for (var i = 0; i < its.length; i++) {
|
|
217
|
-
var
|
|
237
|
+
var raw = its[i].cumulative_usd;
|
|
238
|
+
var cv = (raw === null || raw === undefined) ? NaN : Number(raw);
|
|
239
|
+
if (!isFinite(cv)) continue;
|
|
240
|
+
measured.push([i, cv]);
|
|
218
241
|
if (cv > maxCum) maxCum = cv;
|
|
219
242
|
}
|
|
220
243
|
if (maxCum <= 0) maxCum = 1;
|
|
221
244
|
var pts = [];
|
|
222
|
-
for (var j = 0; j <
|
|
223
|
-
var
|
|
224
|
-
var
|
|
245
|
+
for (var j = 0; j < measured.length; j++) {
|
|
246
|
+
var idx = measured[j][0];
|
|
247
|
+
var x = its.length === 1 ? W / 2 : pad + (idx / (its.length - 1)) * (W - 2 * pad);
|
|
248
|
+
var y = H - pad - (measured[j][1] / maxCum) * (H - 2 * pad);
|
|
225
249
|
pts.push(x.toFixed(1) + "," + y.toFixed(1));
|
|
226
250
|
}
|
|
227
|
-
var poly =
|
|
228
|
-
'<
|
|
229
|
-
'
|
|
251
|
+
var poly = pts.length === 0
|
|
252
|
+
? '<div class="empty">No iteration in this run recorded a cost, so there is nothing to plot.</div>'
|
|
253
|
+
: '<svg viewBox="0 0 ' + W + ' ' + H + '" preserveAspectRatio="none">' +
|
|
254
|
+
'<polyline fill="none" stroke="#6f7bf7" stroke-width="2" points="' + pts.join(" ") + '"/>' +
|
|
255
|
+
'</svg>';
|
|
230
256
|
html += '<div class="panel"><div class="muted" style="font-size:13px;margin-bottom:6px;">' +
|
|
231
|
-
'Cumulative spend this run: <span class="mono">' +
|
|
257
|
+
'Cumulative spend this run: <span class="mono">' + partialUsd(cr.total_usd, cr.partial) + '</span></div>' +
|
|
232
258
|
poly + '</div>';
|
|
233
259
|
// Per-iteration table.
|
|
234
260
|
var rows = "";
|
|
261
|
+
// Once an iteration went unmeasured, every later running total skips it.
|
|
262
|
+
var gap = false;
|
|
235
263
|
for (var r = 0; r < its.length; r++) {
|
|
236
264
|
var it = its[r];
|
|
265
|
+
if (it.cost_usd === null || it.cost_usd === undefined) gap = true;
|
|
237
266
|
rows += '<tr><td class="num mono">' + esc(it.iteration) + '</td>' +
|
|
238
|
-
'<td class="mono">' +
|
|
267
|
+
'<td class="mono">' + orNotRecorded(it.model) + '</td>' +
|
|
239
268
|
'<td>' + esc(it.phase) + '</td>' +
|
|
240
|
-
'<td class="num">' +
|
|
241
|
-
'<td class="num">' +
|
|
269
|
+
'<td class="num">' + orNotRecorded(it.input_tokens) + '</td>' +
|
|
270
|
+
'<td class="num">' + orNotRecorded(it.output_tokens) + '</td>' +
|
|
242
271
|
'<td class="num mono">' + fmtUsd(it.cost_usd) + '</td>' +
|
|
243
|
-
'<td class="num mono">' +
|
|
272
|
+
'<td class="num mono">' + partialUsd(it.cumulative_usd, gap) + '</td></tr>';
|
|
244
273
|
}
|
|
245
274
|
html += '<table style="margin-top:14px;"><thead><tr>' +
|
|
246
275
|
'<th class="num">Iter</th><th>Model</th><th>Phase</th>' +
|
|
@@ -271,7 +300,7 @@
|
|
|
271
300
|
}
|
|
272
301
|
html += '<table><thead><tr>' +
|
|
273
302
|
'<th>Run</th><th>When</th><th>Model</th><th class="num">Files</th>' +
|
|
274
|
-
'<th>
|
|
303
|
+
'<th>Council vote</th><th class="num">Cost</th>' +
|
|
275
304
|
'</tr></thead><tbody>' + rows + '</tbody></table>';
|
|
276
305
|
return html;
|
|
277
306
|
}
|
|
@@ -281,14 +310,14 @@
|
|
|
281
310
|
var b = d.budget || {};
|
|
282
311
|
var cards = '<div class="cards">' +
|
|
283
312
|
'<div class="card"><div class="label">Project total</div>' +
|
|
284
|
-
'<div class="val">' +
|
|
313
|
+
'<div class="val">' + projectTotal(d) + '</div>' +
|
|
285
314
|
'<div class="note">' + esc(d.runs_count) + ' run(s) recorded</div></div>' +
|
|
286
315
|
'<div class="card"><div class="label">Current run</div>' +
|
|
287
|
-
'<div class="val">' +
|
|
316
|
+
'<div class="val">' + (d.current_run ? partialUsd(d.current_run.total_usd, d.current_run.partial) : fmtUsd(null)) + '</div>' +
|
|
288
317
|
'<div class="note">' + (d.current_run && d.current_run.iterations ? d.current_run.iterations.length : 0) + ' iteration(s)</div></div>' +
|
|
289
318
|
'<div class="card"><div class="label">Budget status</div>' +
|
|
290
|
-
'<div class="val ' + esc(b.status || "none") + '" style="font-size:20px;text-transform:capitalize;">' + esc(b.status || "none") + '</div>' +
|
|
291
|
-
'<div class="note">' + (b.limit ?
|
|
319
|
+
'<div class="val ' + esc(b.status || "none") + '" style="font-size:20px;text-transform:capitalize;">' + esc(b.status || "none") + (b.partial ? ' (partial)' : '') + '</div>' +
|
|
320
|
+
'<div class="note">' + (b.limit ? partialUsd(b.used, b.partial) + ' / ' + fmtUsd(b.limit) : "no cap set") + '</div></div>' +
|
|
292
321
|
'</div>';
|
|
293
322
|
c.innerHTML = cards +
|
|
294
323
|
renderBudget(d.budget) +
|