loki-mode 5.30.0 → 5.32.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 +100 -2
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +552 -14
- package/autonomy/run.sh +16 -3
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +12 -1
- package/dashboard/static/favicon.svg +5 -0
- package/dashboard/static/index.html +260 -7
- package/docs/INSTALLATION.md +110 -8
- package/package.json +1 -1
- package/templates/README.md +2 -1
- package/templates/rest-api-auth.md +252 -0
package/autonomy/run.sh
CHANGED
|
@@ -712,15 +712,28 @@ emit_learning_signal() {
|
|
|
712
712
|
|
|
713
713
|
# Track iteration timing for efficiency signals
|
|
714
714
|
ITERATION_START_MS=""
|
|
715
|
+
|
|
716
|
+
# Get current time in milliseconds (portable: works on macOS BSD date and GNU date)
|
|
717
|
+
_now_ms() {
|
|
718
|
+
local ms
|
|
719
|
+
ms=$(date +%s%3N 2>/dev/null)
|
|
720
|
+
# macOS BSD date doesn't support %N -- outputs literal "N" or "%3N"
|
|
721
|
+
# Detect non-numeric output and fall back to seconds * 1000
|
|
722
|
+
case "$ms" in
|
|
723
|
+
*[!0-9]*) echo $(( $(date +%s) * 1000 )) ;;
|
|
724
|
+
*) echo "$ms" ;;
|
|
725
|
+
esac
|
|
726
|
+
}
|
|
727
|
+
|
|
715
728
|
record_iteration_start() {
|
|
716
|
-
ITERATION_START_MS=$(
|
|
729
|
+
ITERATION_START_MS=$(_now_ms)
|
|
717
730
|
}
|
|
718
731
|
|
|
719
732
|
# Get iteration duration in milliseconds
|
|
720
733
|
get_iteration_duration_ms() {
|
|
721
734
|
if [ -n "$ITERATION_START_MS" ]; then
|
|
722
735
|
local end_ms
|
|
723
|
-
end_ms=$(
|
|
736
|
+
end_ms=$(_now_ms)
|
|
724
737
|
echo $((end_ms - ITERATION_START_MS))
|
|
725
738
|
else
|
|
726
739
|
echo "0"
|
|
@@ -2577,7 +2590,7 @@ track_iteration_complete() {
|
|
|
2577
2590
|
elif [ "${PROVIDER_NAME:-claude}" = "gemini" ]; then
|
|
2578
2591
|
model_tier="gemini-3-pro"
|
|
2579
2592
|
fi
|
|
2580
|
-
local phase="$
|
|
2593
|
+
local phase="${LAST_KNOWN_PHASE:-}"
|
|
2581
2594
|
[ -z "$phase" ] && phase=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('currentPhase', 'unknown'))" 2>/dev/null || echo "unknown")
|
|
2582
2595
|
cat > ".loki/metrics/efficiency/iteration-${iteration}.json" << EFF_EOF
|
|
2583
2596
|
{
|
package/dashboard/__init__.py
CHANGED
package/dashboard/server.py
CHANGED
|
@@ -2200,7 +2200,7 @@ except ImportError as e:
|
|
|
2200
2200
|
# =============================================================================
|
|
2201
2201
|
# Must be configured AFTER all API routes to avoid conflicts
|
|
2202
2202
|
|
|
2203
|
-
from fastapi.responses import FileResponse, HTMLResponse
|
|
2203
|
+
from fastapi.responses import FileResponse, HTMLResponse, Response
|
|
2204
2204
|
|
|
2205
2205
|
# Find static files in multiple possible locations
|
|
2206
2206
|
DASHBOARD_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
@@ -2240,6 +2240,17 @@ if STATIC_DIR:
|
|
|
2240
2240
|
if os.path.isdir(ASSETS_DIR):
|
|
2241
2241
|
app.mount("/assets", StaticFiles(directory=ASSETS_DIR), name="assets")
|
|
2242
2242
|
|
|
2243
|
+
# Serve favicon.svg from static directory
|
|
2244
|
+
@app.get("/favicon.svg", include_in_schema=False)
|
|
2245
|
+
async def serve_favicon():
|
|
2246
|
+
"""Serve the dashboard favicon."""
|
|
2247
|
+
if STATIC_DIR:
|
|
2248
|
+
favicon_path = os.path.join(STATIC_DIR, "favicon.svg")
|
|
2249
|
+
if os.path.isfile(favicon_path):
|
|
2250
|
+
return FileResponse(favicon_path, media_type="image/svg+xml")
|
|
2251
|
+
return Response(status_code=404)
|
|
2252
|
+
|
|
2253
|
+
|
|
2243
2254
|
# Serve index.html or standalone HTML for root
|
|
2244
2255
|
@app.get("/", include_in_schema=False)
|
|
2245
2256
|
async def serve_index():
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
|
|
2
|
+
<path d="M16 6C8 6 2 16 2 16s6 10 14 10 14-10 14-10S24 6 16 6z" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<circle cx="16" cy="16" r="5" fill="#7c3aed"/>
|
|
4
|
+
<circle cx="16" cy="16" r="2" fill="#fff"/>
|
|
5
|
+
</svg>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<meta name="description" content="Loki Mode Dashboard - Self-contained autonomous AI system monitor">
|
|
7
7
|
<meta name="theme-color" content="#8b5cf6">
|
|
8
8
|
<title>Loki Mode Dashboard</title>
|
|
9
|
-
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0
|
|
9
|
+
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' width='32' height='32'><path d='M16 6C8 6 2 16 2 16s6 10 14 10 14-10 14-10S24 6 16 6z' fill='none' stroke='%237c3aed' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/><circle cx='16' cy='16' r='5' fill='%237c3aed'/><circle cx='16' cy='16' r='2' fill='%23fff'/></svg>">
|
|
10
10
|
<style>
|
|
11
11
|
/* CSS Reset and Base Styles */
|
|
12
12
|
:root {
|
|
@@ -351,6 +351,105 @@
|
|
|
351
351
|
::-webkit-scrollbar-track { background: transparent; }
|
|
352
352
|
::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.1); border-radius: 3px; }
|
|
353
353
|
::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.2); }
|
|
354
|
+
|
|
355
|
+
/* Keyboard Shortcuts Help Overlay */
|
|
356
|
+
.shortcuts-overlay {
|
|
357
|
+
display: none;
|
|
358
|
+
position: fixed;
|
|
359
|
+
inset: 0;
|
|
360
|
+
background: rgba(0, 0, 0, 0.6);
|
|
361
|
+
z-index: 1000;
|
|
362
|
+
align-items: center;
|
|
363
|
+
justify-content: center;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.shortcuts-overlay.visible {
|
|
367
|
+
display: flex;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.shortcuts-dialog {
|
|
371
|
+
background: var(--loki-bg-card);
|
|
372
|
+
border: 1px solid var(--loki-border);
|
|
373
|
+
border-radius: 12px;
|
|
374
|
+
padding: 24px;
|
|
375
|
+
max-width: 480px;
|
|
376
|
+
width: 90%;
|
|
377
|
+
max-height: 80vh;
|
|
378
|
+
overflow-y: auto;
|
|
379
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.shortcuts-header {
|
|
383
|
+
display: flex;
|
|
384
|
+
justify-content: space-between;
|
|
385
|
+
align-items: center;
|
|
386
|
+
margin-bottom: 16px;
|
|
387
|
+
padding-bottom: 12px;
|
|
388
|
+
border-bottom: 1px solid var(--loki-border);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.shortcuts-title {
|
|
392
|
+
font-size: 16px;
|
|
393
|
+
font-weight: 600;
|
|
394
|
+
color: var(--loki-text-primary);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.shortcuts-close {
|
|
398
|
+
background: none;
|
|
399
|
+
border: none;
|
|
400
|
+
color: var(--loki-text-muted);
|
|
401
|
+
cursor: pointer;
|
|
402
|
+
padding: 4px;
|
|
403
|
+
font-size: 18px;
|
|
404
|
+
line-height: 1;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.shortcuts-close:hover {
|
|
408
|
+
color: var(--loki-text-primary);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.shortcuts-group {
|
|
412
|
+
margin-bottom: 16px;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.shortcuts-group-title {
|
|
416
|
+
font-size: 11px;
|
|
417
|
+
font-weight: 600;
|
|
418
|
+
text-transform: uppercase;
|
|
419
|
+
letter-spacing: 0.5px;
|
|
420
|
+
color: var(--loki-text-muted);
|
|
421
|
+
margin-bottom: 8px;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.shortcut-row {
|
|
425
|
+
display: flex;
|
|
426
|
+
justify-content: space-between;
|
|
427
|
+
align-items: center;
|
|
428
|
+
padding: 4px 0;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.shortcut-keys {
|
|
432
|
+
display: flex;
|
|
433
|
+
gap: 4px;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.shortcut-key {
|
|
437
|
+
display: inline-block;
|
|
438
|
+
padding: 2px 8px;
|
|
439
|
+
background: var(--loki-bg-tertiary);
|
|
440
|
+
border: 1px solid var(--loki-border);
|
|
441
|
+
border-radius: 4px;
|
|
442
|
+
font-size: 12px;
|
|
443
|
+
font-family: 'JetBrains Mono', monospace;
|
|
444
|
+
color: var(--loki-text-primary);
|
|
445
|
+
min-width: 24px;
|
|
446
|
+
text-align: center;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.shortcut-desc {
|
|
450
|
+
font-size: 13px;
|
|
451
|
+
color: var(--loki-text-secondary);
|
|
452
|
+
}
|
|
354
453
|
</style>
|
|
355
454
|
</head>
|
|
356
455
|
<body>
|
|
@@ -411,7 +510,9 @@
|
|
|
411
510
|
<div class="sidebar-controls">
|
|
412
511
|
<input type="text" class="api-url-input" id="api-url" placeholder="API URL">
|
|
413
512
|
<button class="api-btn" id="connect-btn">Go</button>
|
|
414
|
-
<button class="theme-toggle" id="theme-toggle">
|
|
513
|
+
<button class="theme-toggle" id="theme-toggle" title="Toggle theme (T)">
|
|
514
|
+
<svg id="theme-icon-sun" width="14" height="14" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" style="display:none"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
|
515
|
+
<svg id="theme-icon-moon" width="14" height="14" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" fill="none" style="display:none"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
|
|
415
516
|
<span id="theme-label">Dark</span>
|
|
416
517
|
</button>
|
|
417
518
|
</div>
|
|
@@ -475,6 +576,39 @@
|
|
|
475
576
|
</main>
|
|
476
577
|
</div>
|
|
477
578
|
|
|
579
|
+
<!-- Keyboard Shortcuts Help Overlay -->
|
|
580
|
+
<div class="shortcuts-overlay" id="shortcuts-overlay">
|
|
581
|
+
<div class="shortcuts-dialog">
|
|
582
|
+
<div class="shortcuts-header">
|
|
583
|
+
<span class="shortcuts-title">Keyboard Shortcuts</span>
|
|
584
|
+
<button class="shortcuts-close" id="shortcuts-close" aria-label="Close">×</button>
|
|
585
|
+
</div>
|
|
586
|
+
<div class="shortcuts-group">
|
|
587
|
+
<div class="shortcuts-group-title">Navigation</div>
|
|
588
|
+
<div class="shortcut-row"><span class="shortcut-desc">Overview</span><span class="shortcut-keys"><kbd class="shortcut-key">1</kbd></span></div>
|
|
589
|
+
<div class="shortcut-row"><span class="shortcut-desc">Tasks</span><span class="shortcut-keys"><kbd class="shortcut-key">2</kbd></span></div>
|
|
590
|
+
<div class="shortcut-row"><span class="shortcut-desc">Logs</span><span class="shortcut-keys"><kbd class="shortcut-key">3</kbd></span></div>
|
|
591
|
+
<div class="shortcut-row"><span class="shortcut-desc">Memory</span><span class="shortcut-keys"><kbd class="shortcut-key">4</kbd></span></div>
|
|
592
|
+
<div class="shortcut-row"><span class="shortcut-desc">Learning</span><span class="shortcut-keys"><kbd class="shortcut-key">5</kbd></span></div>
|
|
593
|
+
<div class="shortcut-row"><span class="shortcut-desc">Council</span><span class="shortcut-keys"><kbd class="shortcut-key">6</kbd></span></div>
|
|
594
|
+
<div class="shortcut-row"><span class="shortcut-desc">Cost</span><span class="shortcut-keys"><kbd class="shortcut-key">7</kbd></span></div>
|
|
595
|
+
</div>
|
|
596
|
+
<div class="shortcuts-group">
|
|
597
|
+
<div class="shortcuts-group-title">Session</div>
|
|
598
|
+
<div class="shortcut-row"><span class="shortcut-desc">Pause session</span><span class="shortcut-keys"><kbd class="shortcut-key">p</kbd></span></div>
|
|
599
|
+
<div class="shortcut-row"><span class="shortcut-desc">Resume session</span><span class="shortcut-keys"><kbd class="shortcut-key">r</kbd></span></div>
|
|
600
|
+
<div class="shortcut-row"><span class="shortcut-desc">Stop session</span><span class="shortcut-keys"><kbd class="shortcut-key">s</kbd></span></div>
|
|
601
|
+
</div>
|
|
602
|
+
<div class="shortcuts-group">
|
|
603
|
+
<div class="shortcuts-group-title">General</div>
|
|
604
|
+
<div class="shortcut-row"><span class="shortcut-desc">Toggle theme</span><span class="shortcut-keys"><kbd class="shortcut-key">t</kbd></span></div>
|
|
605
|
+
<div class="shortcut-row"><span class="shortcut-desc">Focus API URL</span><span class="shortcut-keys"><kbd class="shortcut-key">/</kbd></span></div>
|
|
606
|
+
<div class="shortcut-row"><span class="shortcut-desc">Show shortcuts</span><span class="shortcut-keys"><kbd class="shortcut-key">?</kbd></span></div>
|
|
607
|
+
<div class="shortcut-row"><span class="shortcut-desc">Close overlay</span><span class="shortcut-keys"><kbd class="shortcut-key">Esc</kbd></span></div>
|
|
608
|
+
</div>
|
|
609
|
+
</div>
|
|
610
|
+
</div>
|
|
611
|
+
|
|
478
612
|
<!-- Inlined JavaScript Bundle -->
|
|
479
613
|
<script>
|
|
480
614
|
var LokiDashboard=(()=>{var N=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var re=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var ne=(l,e,t)=>e in l?N(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var le=(l,e)=>{for(var t in e)N(l,t,{get:e[t],enumerable:!0})},de=(l,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of re(e))!oe.call(l,i)&&i!==t&&N(l,i,{get:()=>e[i],enumerable:!(a=se(e,i))||a.enumerable});return l};var ce=l=>de(N({},"__esModule",{value:!0}),l);var k=(l,e,t)=>ne(l,typeof e!="symbol"?e+"":e,t);var _e={};le(_e,{ANIMATION:()=>w,ARIA_PATTERNS:()=>G,ApiEvents:()=>o,BASE_STYLES:()=>I,BREAKPOINTS:()=>q,COMMON_STYLES:()=>X,KEYBOARD_SHORTCUTS:()=>K,KeyboardHandler:()=>A,LokiApiClient:()=>L,LokiCostDashboard:()=>F,LokiCouncilDashboard:()=>O,LokiElement:()=>c,LokiLearningDashboard:()=>H,LokiLogStream:()=>B,LokiMemoryBrowser:()=>U,LokiOverview:()=>M,LokiSessionControl:()=>j,LokiState:()=>R,LokiTaskBoard:()=>z,LokiTheme:()=>T,RADIUS:()=>y,SPACING:()=>_,STATE_CHANGE_EVENT:()=>Y,THEMES:()=>b,THEME_VARIABLES:()=>V,TYPOGRAPHY:()=>v,UnifiedThemeManager:()=>h,VERSION:()=>ke,Z_INDEX:()=>$,createApiClient:()=>ee,createStore:()=>te,generateThemeCSS:()=>m,generateTokensCSS:()=>P,getApiClient:()=>g,getState:()=>C,init:()=>fe});var b={light:{"--loki-bg-primary":"#fafafa","--loki-bg-secondary":"#f4f4f5","--loki-bg-tertiary":"#e4e4e7","--loki-bg-card":"#ffffff","--loki-bg-hover":"#f0f0f3","--loki-bg-active":"#e8e8ec","--loki-bg-overlay":"rgba(0, 0, 0, 0.5)","--loki-accent":"#7c3aed","--loki-accent-hover":"#6d28d9","--loki-accent-active":"#5b21b6","--loki-accent-light":"#8b5cf6","--loki-accent-muted":"rgba(124, 58, 237, 0.12)","--loki-text-primary":"#18181b","--loki-text-secondary":"#52525b","--loki-text-muted":"#a1a1aa","--loki-text-disabled":"#d4d4d8","--loki-text-inverse":"#ffffff","--loki-border":"#e4e4e7","--loki-border-light":"#d4d4d8","--loki-border-focus":"#7c3aed","--loki-success":"#16a34a","--loki-success-muted":"rgba(22, 163, 74, 0.12)","--loki-warning":"#ca8a04","--loki-warning-muted":"rgba(202, 138, 4, 0.12)","--loki-error":"#dc2626","--loki-error-muted":"rgba(220, 38, 38, 0.12)","--loki-info":"#2563eb","--loki-info-muted":"rgba(37, 99, 235, 0.12)","--loki-green":"#16a34a","--loki-green-muted":"rgba(22, 163, 74, 0.12)","--loki-yellow":"#ca8a04","--loki-yellow-muted":"rgba(202, 138, 4, 0.12)","--loki-red":"#dc2626","--loki-red-muted":"rgba(220, 38, 38, 0.12)","--loki-blue":"#2563eb","--loki-blue-muted":"rgba(37, 99, 235, 0.12)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.12)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 4px 6px rgba(0, 0, 0, 0.07)","--loki-shadow-lg":"0 10px 15px rgba(0, 0, 0, 0.1)","--loki-shadow-focus":"0 0 0 3px rgba(124, 58, 237, 0.3)"},dark:{"--loki-bg-primary":"#09090b","--loki-bg-secondary":"#0c0c0f","--loki-bg-tertiary":"#111114","--loki-bg-card":"#18181b","--loki-bg-hover":"#1f1f23","--loki-bg-active":"#27272a","--loki-bg-overlay":"rgba(0, 0, 0, 0.8)","--loki-accent":"#8b5cf6","--loki-accent-hover":"#a78bfa","--loki-accent-active":"#7c3aed","--loki-accent-light":"#a78bfa","--loki-accent-muted":"rgba(139, 92, 246, 0.15)","--loki-text-primary":"#fafafa","--loki-text-secondary":"#a1a1aa","--loki-text-muted":"#52525b","--loki-text-disabled":"#3f3f46","--loki-text-inverse":"#09090b","--loki-border":"rgba(255, 255, 255, 0.06)","--loki-border-light":"rgba(255, 255, 255, 0.1)","--loki-border-focus":"#8b5cf6","--loki-success":"#22c55e","--loki-success-muted":"rgba(34, 197, 94, 0.15)","--loki-warning":"#eab308","--loki-warning-muted":"rgba(234, 179, 8, 0.15)","--loki-error":"#ef4444","--loki-error-muted":"rgba(239, 68, 68, 0.15)","--loki-info":"#3b82f6","--loki-info-muted":"rgba(59, 130, 246, 0.15)","--loki-green":"#22c55e","--loki-green-muted":"rgba(34, 197, 94, 0.15)","--loki-yellow":"#eab308","--loki-yellow-muted":"rgba(234, 179, 8, 0.15)","--loki-red":"#ef4444","--loki-red-muted":"rgba(239, 68, 68, 0.15)","--loki-blue":"#3b82f6","--loki-blue-muted":"rgba(59, 130, 246, 0.15)","--loki-purple":"#a78bfa","--loki-purple-muted":"rgba(167, 139, 250, 0.15)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.4)","--loki-shadow-md":"0 4px 12px rgba(0, 0, 0, 0.5)","--loki-shadow-lg":"0 10px 25px rgba(0, 0, 0, 0.6)","--loki-shadow-focus":"0 0 0 3px rgba(139, 92, 246, 0.25)"},"high-contrast":{"--loki-bg-primary":"#000000","--loki-bg-secondary":"#0a0a0a","--loki-bg-tertiary":"#141414","--loki-bg-card":"#0a0a0a","--loki-bg-hover":"#1a1a1a","--loki-bg-active":"#242424","--loki-bg-overlay":"rgba(0, 0, 0, 0.9)","--loki-accent":"#c084fc","--loki-accent-hover":"#d8b4fe","--loki-accent-active":"#e9d5ff","--loki-accent-light":"#d8b4fe","--loki-accent-muted":"rgba(192, 132, 252, 0.25)","--loki-text-primary":"#ffffff","--loki-text-secondary":"#e0e0e0","--loki-text-muted":"#b0b0b0","--loki-text-disabled":"#666666","--loki-text-inverse":"#000000","--loki-border":"#ffffff","--loki-border-light":"#cccccc","--loki-border-focus":"#c084fc","--loki-success":"#4ade80","--loki-success-muted":"rgba(74, 222, 128, 0.25)","--loki-warning":"#fde047","--loki-warning-muted":"rgba(253, 224, 71, 0.25)","--loki-error":"#f87171","--loki-error-muted":"rgba(248, 113, 113, 0.25)","--loki-info":"#60a5fa","--loki-info-muted":"rgba(96, 165, 250, 0.25)","--loki-green":"#4ade80","--loki-green-muted":"rgba(74, 222, 128, 0.25)","--loki-yellow":"#fde047","--loki-yellow-muted":"rgba(253, 224, 71, 0.25)","--loki-red":"#f87171","--loki-red-muted":"rgba(248, 113, 113, 0.25)","--loki-blue":"#60a5fa","--loki-blue-muted":"rgba(96, 165, 250, 0.25)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.25)","--loki-opus":"#fbbf24","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"none","--loki-shadow-md":"none","--loki-shadow-lg":"none","--loki-shadow-focus":"0 0 0 3px #c084fc"},"vscode-light":{"--loki-bg-primary":"var(--vscode-editor-background, #ffffff)","--loki-bg-secondary":"var(--vscode-sideBar-background, #f3f3f3)","--loki-bg-tertiary":"var(--vscode-input-background, #ffffff)","--loki-bg-card":"var(--vscode-editor-background, #ffffff)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #e8e8e8)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #0060c0)","--loki-bg-overlay":"rgba(0, 0, 0, 0.4)","--loki-accent":"var(--vscode-focusBorder, #0066cc)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #0055aa)","--loki-accent-active":"var(--vscode-button-background, #007acc)","--loki-accent-light":"var(--vscode-focusBorder, #0066cc)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 102, 204, 0.2))","--loki-text-primary":"var(--vscode-foreground, #333333)","--loki-text-secondary":"var(--vscode-descriptionForeground, #717171)","--loki-text-muted":"var(--vscode-disabledForeground, #a0a0a0)","--loki-text-disabled":"var(--vscode-disabledForeground, #cccccc)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #c8c8c8)","--loki-border-light":"var(--vscode-widget-border, #e0e0e0)","--loki-border-focus":"var(--vscode-focusBorder, #0066cc)","--loki-success":"var(--vscode-testing-iconPassed, #388a34)","--loki-success-muted":"rgba(56, 138, 52, 0.15)","--loki-warning":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-warning-muted":"rgba(191, 136, 3, 0.15)","--loki-error":"var(--vscode-errorForeground, #e51400)","--loki-error-muted":"rgba(229, 20, 0, 0.15)","--loki-info":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-info-muted":"rgba(26, 133, 255, 0.15)","--loki-green":"var(--vscode-testing-iconPassed, #388a34)","--loki-green-muted":"rgba(56, 138, 52, 0.15)","--loki-yellow":"var(--vscode-editorWarning-foreground, #bf8803)","--loki-yellow-muted":"rgba(191, 136, 3, 0.15)","--loki-red":"var(--vscode-errorForeground, #e51400)","--loki-red-muted":"rgba(229, 20, 0, 0.15)","--loki-blue":"var(--vscode-editorInfo-foreground, #1a85ff)","--loki-blue-muted":"rgba(26, 133, 255, 0.15)","--loki-purple":"#9333ea","--loki-purple-muted":"rgba(147, 51, 234, 0.15)","--loki-opus":"#d97706","--loki-sonnet":"#4f46e5","--loki-haiku":"#059669","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.05)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.1)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.15)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #0066cc)"},"vscode-dark":{"--loki-bg-primary":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-secondary":"var(--vscode-sideBar-background, #252526)","--loki-bg-tertiary":"var(--vscode-input-background, #3c3c3c)","--loki-bg-card":"var(--vscode-editor-background, #1e1e1e)","--loki-bg-hover":"var(--vscode-list-hoverBackground, #2a2d2e)","--loki-bg-active":"var(--vscode-list-activeSelectionBackground, #094771)","--loki-bg-overlay":"rgba(0, 0, 0, 0.6)","--loki-accent":"var(--vscode-focusBorder, #007fd4)","--loki-accent-hover":"var(--vscode-button-hoverBackground, #1177bb)","--loki-accent-active":"var(--vscode-button-background, #0e639c)","--loki-accent-light":"var(--vscode-focusBorder, #007fd4)","--loki-accent-muted":"var(--vscode-editor-selectionBackground, rgba(0, 127, 212, 0.25))","--loki-text-primary":"var(--vscode-foreground, #cccccc)","--loki-text-secondary":"var(--vscode-descriptionForeground, #9d9d9d)","--loki-text-muted":"var(--vscode-disabledForeground, #6b6b6b)","--loki-text-disabled":"var(--vscode-disabledForeground, #4d4d4d)","--loki-text-inverse":"var(--vscode-button-foreground, #ffffff)","--loki-border":"var(--vscode-widget-border, #454545)","--loki-border-light":"var(--vscode-widget-border, #5a5a5a)","--loki-border-focus":"var(--vscode-focusBorder, #007fd4)","--loki-success":"var(--vscode-testing-iconPassed, #89d185)","--loki-success-muted":"rgba(137, 209, 133, 0.2)","--loki-warning":"var(--vscode-editorWarning-foreground, #cca700)","--loki-warning-muted":"rgba(204, 167, 0, 0.2)","--loki-error":"var(--vscode-errorForeground, #f48771)","--loki-error-muted":"rgba(244, 135, 113, 0.2)","--loki-info":"var(--vscode-editorInfo-foreground, #75beff)","--loki-info-muted":"rgba(117, 190, 255, 0.2)","--loki-green":"var(--vscode-testing-iconPassed, #89d185)","--loki-green-muted":"rgba(137, 209, 133, 0.2)","--loki-yellow":"var(--vscode-editorWarning-foreground, #cca700)","--loki-yellow-muted":"rgba(204, 167, 0, 0.2)","--loki-red":"var(--vscode-errorForeground, #f48771)","--loki-red-muted":"rgba(244, 135, 113, 0.2)","--loki-blue":"var(--vscode-editorInfo-foreground, #75beff)","--loki-blue-muted":"rgba(117, 190, 255, 0.2)","--loki-purple":"#c084fc","--loki-purple-muted":"rgba(192, 132, 252, 0.2)","--loki-opus":"#f59e0b","--loki-sonnet":"#818cf8","--loki-haiku":"#34d399","--loki-shadow-sm":"0 1px 2px rgba(0, 0, 0, 0.3)","--loki-shadow-md":"0 2px 4px rgba(0, 0, 0, 0.4)","--loki-shadow-lg":"0 4px 8px rgba(0, 0, 0, 0.5)","--loki-shadow-focus":"0 0 0 2px var(--vscode-focusBorder, #007fd4)"}},_={xs:"4px",sm:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"32px","3xl":"48px"},y={none:"0",sm:"4px",md:"6px",lg:"8px",xl:"10px",full:"9999px"},v={fontFamily:{sans:"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",mono:"'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace"},fontSize:{xs:"10px",sm:"11px",base:"12px",md:"13px",lg:"14px",xl:"16px","2xl":"18px","3xl":"24px"},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:"1.25",normal:"1.5",relaxed:"1.75"}},w={duration:{fast:"100ms",normal:"200ms",slow:"300ms",slower:"500ms"},easing:{default:"cubic-bezier(0.4, 0, 0.2, 1)",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)",bounce:"cubic-bezier(0.68, -0.55, 0.265, 1.55)"}},q={sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},$={base:"0",dropdown:"100",sticky:"200",modal:"300",popover:"400",tooltip:"500",toast:"600"},K={"navigation.nextItem":{key:"ArrowDown",modifiers:[]},"navigation.prevItem":{key:"ArrowUp",modifiers:[]},"navigation.nextSection":{key:"Tab",modifiers:[]},"navigation.prevSection":{key:"Tab",modifiers:["Shift"]},"navigation.confirm":{key:"Enter",modifiers:[]},"navigation.cancel":{key:"Escape",modifiers:[]},"action.refresh":{key:"r",modifiers:["Meta"]},"action.search":{key:"k",modifiers:["Meta"]},"action.save":{key:"s",modifiers:["Meta"]},"action.close":{key:"w",modifiers:["Meta"]},"theme.toggle":{key:"d",modifiers:["Meta","Shift"]},"task.create":{key:"n",modifiers:["Meta"]},"task.complete":{key:"Enter",modifiers:["Meta"]},"view.toggleLogs":{key:"l",modifiers:["Meta","Shift"]},"view.toggleMemory":{key:"m",modifiers:["Meta","Shift"]}},G={button:{role:"button",tabIndex:0},tablist:{role:"tablist"},tab:{role:"tab",ariaSelected:!1,tabIndex:-1},tabpanel:{role:"tabpanel",tabIndex:0},list:{role:"list"},listitem:{role:"listitem"},livePolite:{ariaLive:"polite",ariaAtomic:!0},liveAssertive:{ariaLive:"assertive",ariaAtomic:!0},dialog:{role:"dialog",ariaModal:!0},alertdialog:{role:"alertdialog",ariaModal:!0},status:{role:"status",ariaLive:"polite"},alert:{role:"alert",ariaLive:"assertive"},log:{role:"log",ariaLive:"polite",ariaRelevant:"additions"}};function m(l){let e=b[l];return e?Object.entries(e).map(([t,a])=>`${t}: ${a};`).join(`
|
|
@@ -4613,18 +4747,27 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
4613
4747
|
var themeToggle = document.getElementById('theme-toggle');
|
|
4614
4748
|
var themeLabel = document.getElementById('theme-label');
|
|
4615
4749
|
|
|
4616
|
-
|
|
4750
|
+
var sunIcon = document.getElementById('theme-icon-sun');
|
|
4751
|
+
var moonIcon = document.getElementById('theme-icon-moon');
|
|
4752
|
+
|
|
4753
|
+
function updateThemeUI() {
|
|
4617
4754
|
var theme = LokiDashboard.UnifiedThemeManager.getTheme();
|
|
4618
|
-
|
|
4755
|
+
var isDark = theme.includes('dark') || theme === 'high-contrast';
|
|
4756
|
+
themeLabel.textContent = isDark ? 'Light' : 'Dark';
|
|
4757
|
+
if (sunIcon) sunIcon.style.display = isDark ? 'inline' : 'none';
|
|
4758
|
+
if (moonIcon) moonIcon.style.display = isDark ? 'none' : 'inline';
|
|
4619
4759
|
}
|
|
4620
4760
|
|
|
4621
4761
|
themeToggle.addEventListener('click', function() {
|
|
4622
4762
|
LokiDashboard.UnifiedThemeManager.toggle();
|
|
4623
|
-
|
|
4763
|
+
updateThemeUI();
|
|
4624
4764
|
});
|
|
4625
4765
|
|
|
4626
|
-
|
|
4627
|
-
|
|
4766
|
+
window.addEventListener('loki-theme-change', function() {
|
|
4767
|
+
updateThemeUI();
|
|
4768
|
+
});
|
|
4769
|
+
|
|
4770
|
+
updateThemeUI();
|
|
4628
4771
|
|
|
4629
4772
|
// API URL configuration - auto-detect from current server
|
|
4630
4773
|
var apiUrlInput = document.getElementById('api-url');
|
|
@@ -4736,6 +4879,116 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
4736
4879
|
}
|
|
4737
4880
|
});
|
|
4738
4881
|
|
|
4882
|
+
// --- Keyboard Shortcuts (Issue #18) ---
|
|
4883
|
+
var shortcutsOverlay = document.getElementById('shortcuts-overlay');
|
|
4884
|
+
var shortcutsClose = document.getElementById('shortcuts-close');
|
|
4885
|
+
|
|
4886
|
+
function toggleShortcutsOverlay() {
|
|
4887
|
+
shortcutsOverlay.classList.toggle('visible');
|
|
4888
|
+
}
|
|
4889
|
+
|
|
4890
|
+
function closeShortcutsOverlay() {
|
|
4891
|
+
shortcutsOverlay.classList.remove('visible');
|
|
4892
|
+
}
|
|
4893
|
+
|
|
4894
|
+
shortcutsClose.addEventListener('click', closeShortcutsOverlay);
|
|
4895
|
+
|
|
4896
|
+
// Close overlay when clicking outside the dialog
|
|
4897
|
+
shortcutsOverlay.addEventListener('click', function(e) {
|
|
4898
|
+
if (e.target === shortcutsOverlay) {
|
|
4899
|
+
closeShortcutsOverlay();
|
|
4900
|
+
}
|
|
4901
|
+
});
|
|
4902
|
+
|
|
4903
|
+
document.addEventListener('keydown', function(e) {
|
|
4904
|
+
// Skip shortcuts when typing in input, textarea, or select elements
|
|
4905
|
+
var tag = (e.target.tagName || '').toLowerCase();
|
|
4906
|
+
if (tag === 'input' || tag === 'textarea' || tag === 'select' || e.target.isContentEditable) {
|
|
4907
|
+
// Allow Escape to blur input fields
|
|
4908
|
+
if (e.key === 'Escape') {
|
|
4909
|
+
e.target.blur();
|
|
4910
|
+
}
|
|
4911
|
+
return;
|
|
4912
|
+
}
|
|
4913
|
+
|
|
4914
|
+
// Skip if modifier keys are held (let browser defaults work)
|
|
4915
|
+
if (e.metaKey || e.ctrlKey || e.altKey) return;
|
|
4916
|
+
|
|
4917
|
+
var sections = ['overview', 'tasks', 'logs', 'memory', 'learning', 'council', 'cost'];
|
|
4918
|
+
|
|
4919
|
+
switch (e.key) {
|
|
4920
|
+
// Section navigation: 1-7
|
|
4921
|
+
case '1': case '2': case '3': case '4': case '5': case '6': case '7':
|
|
4922
|
+
e.preventDefault();
|
|
4923
|
+
switchSection(sections[parseInt(e.key) - 1]);
|
|
4924
|
+
break;
|
|
4925
|
+
|
|
4926
|
+
// Help overlay
|
|
4927
|
+
case '?':
|
|
4928
|
+
e.preventDefault();
|
|
4929
|
+
toggleShortcutsOverlay();
|
|
4930
|
+
break;
|
|
4931
|
+
|
|
4932
|
+
// Close overlays
|
|
4933
|
+
case 'Escape':
|
|
4934
|
+
if (shortcutsOverlay.classList.contains('visible')) {
|
|
4935
|
+
e.preventDefault();
|
|
4936
|
+
closeShortcutsOverlay();
|
|
4937
|
+
}
|
|
4938
|
+
break;
|
|
4939
|
+
|
|
4940
|
+
// Focus API URL input
|
|
4941
|
+
case '/':
|
|
4942
|
+
e.preventDefault();
|
|
4943
|
+
apiUrlInput.focus();
|
|
4944
|
+
apiUrlInput.select();
|
|
4945
|
+
break;
|
|
4946
|
+
|
|
4947
|
+
// Theme toggle
|
|
4948
|
+
case 't':
|
|
4949
|
+
e.preventDefault();
|
|
4950
|
+
LokiDashboard.UnifiedThemeManager.toggle();
|
|
4951
|
+
updateThemeLabel();
|
|
4952
|
+
break;
|
|
4953
|
+
|
|
4954
|
+
// Session controls
|
|
4955
|
+
case 'p':
|
|
4956
|
+
e.preventDefault();
|
|
4957
|
+
var sessionCtrl = document.getElementById('session-control');
|
|
4958
|
+
if (sessionCtrl) {
|
|
4959
|
+
var pauseBtn = sessionCtrl.shadowRoot && sessionCtrl.shadowRoot.getElementById('pause-btn');
|
|
4960
|
+
if (pauseBtn && !pauseBtn.disabled) {
|
|
4961
|
+
pauseBtn.click();
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
break;
|
|
4965
|
+
|
|
4966
|
+
case 'r':
|
|
4967
|
+
e.preventDefault();
|
|
4968
|
+
var sessionCtrl2 = document.getElementById('session-control');
|
|
4969
|
+
if (sessionCtrl2) {
|
|
4970
|
+
var resumeBtn = sessionCtrl2.shadowRoot && sessionCtrl2.shadowRoot.getElementById('resume-btn');
|
|
4971
|
+
if (resumeBtn) {
|
|
4972
|
+
resumeBtn.click();
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
break;
|
|
4976
|
+
|
|
4977
|
+
case 's':
|
|
4978
|
+
e.preventDefault();
|
|
4979
|
+
var sessionCtrl3 = document.getElementById('session-control');
|
|
4980
|
+
if (sessionCtrl3) {
|
|
4981
|
+
var stopBtn = sessionCtrl3.shadowRoot && sessionCtrl3.shadowRoot.getElementById('stop-btn');
|
|
4982
|
+
if (stopBtn && !stopBtn.disabled) {
|
|
4983
|
+
if (window.confirm('Are you sure you want to stop the session?')) {
|
|
4984
|
+
stopBtn.click();
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
break;
|
|
4989
|
+
}
|
|
4990
|
+
});
|
|
4991
|
+
|
|
4739
4992
|
// Restore last section from localStorage
|
|
4740
4993
|
var savedSection = localStorage.getItem('loki-active-section');
|
|
4741
4994
|
if (savedSection) {
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v5.
|
|
5
|
+
**Version:** v5.32.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -20,6 +20,7 @@ Complete installation instructions for all platforms and use cases.
|
|
|
20
20
|
- [Anthropic API Console](#anthropic-api-console)
|
|
21
21
|
- [Verify Installation](#verify-installation)
|
|
22
22
|
- [Ports](#ports)
|
|
23
|
+
- [Shell Completions](#shell-completions)
|
|
23
24
|
- [Troubleshooting](#troubleshooting)
|
|
24
25
|
|
|
25
26
|
---
|
|
@@ -36,7 +37,7 @@ npm install -g loki-mode
|
|
|
36
37
|
brew tap asklokesh/tap && brew install loki-mode
|
|
37
38
|
|
|
38
39
|
# Option C: Docker
|
|
39
|
-
docker pull asklokesh/loki-mode:5.
|
|
40
|
+
docker pull asklokesh/loki-mode:5.32.0
|
|
40
41
|
|
|
41
42
|
# Option D: Git clone
|
|
42
43
|
git clone https://github.com/asklokesh/loki-mode.git ~/.claude/skills/loki-mode
|
|
@@ -227,7 +228,7 @@ Run Loki Mode in a container for isolated execution.
|
|
|
227
228
|
|
|
228
229
|
```bash
|
|
229
230
|
# Pull the image
|
|
230
|
-
docker pull asklokesh/loki-mode:5.
|
|
231
|
+
docker pull asklokesh/loki-mode:5.32.0
|
|
231
232
|
|
|
232
233
|
# Or use docker-compose
|
|
233
234
|
curl -o docker-compose.yml https://raw.githubusercontent.com/asklokesh/loki-mode/main/docker-compose.yml
|
|
@@ -237,10 +238,10 @@ curl -o docker-compose.yml https://raw.githubusercontent.com/asklokesh/loki-mode
|
|
|
237
238
|
|
|
238
239
|
```bash
|
|
239
240
|
# Run with a PRD file
|
|
240
|
-
docker run -v $(pwd):/workspace -w /workspace asklokesh/loki-mode:5.
|
|
241
|
+
docker run -v $(pwd):/workspace -w /workspace asklokesh/loki-mode:5.32.0 start ./my-prd.md
|
|
241
242
|
|
|
242
243
|
# Interactive mode
|
|
243
|
-
docker run -it -v $(pwd):/workspace -w /workspace asklokesh/loki-mode:5.
|
|
244
|
+
docker run -it -v $(pwd):/workspace -w /workspace asklokesh/loki-mode:5.32.0
|
|
244
245
|
|
|
245
246
|
# Using docker-compose
|
|
246
247
|
docker-compose run loki start ./my-prd.md
|
|
@@ -253,7 +254,7 @@ Pass your configuration via environment variables:
|
|
|
253
254
|
```bash
|
|
254
255
|
docker run -e LOKI_MAX_RETRIES=100 -e LOKI_BASE_WAIT=120 \
|
|
255
256
|
-v $(pwd):/workspace -w /workspace \
|
|
256
|
-
asklokesh/loki-mode:5.
|
|
257
|
+
asklokesh/loki-mode:5.32.0 start ./my-prd.md
|
|
257
258
|
```
|
|
258
259
|
|
|
259
260
|
### Updating
|
|
@@ -369,12 +370,12 @@ Pass the provider as an environment variable:
|
|
|
369
370
|
# Use Codex with Docker
|
|
370
371
|
docker run -e LOKI_PROVIDER=codex \
|
|
371
372
|
-v $(pwd):/workspace -w /workspace \
|
|
372
|
-
asklokesh/loki-mode:5.
|
|
373
|
+
asklokesh/loki-mode:5.32.0 start ./my-prd.md
|
|
373
374
|
|
|
374
375
|
# Use Gemini with Docker
|
|
375
376
|
docker run -e LOKI_PROVIDER=gemini \
|
|
376
377
|
-v $(pwd):/workspace -w /workspace \
|
|
377
|
-
asklokesh/loki-mode:5.
|
|
378
|
+
asklokesh/loki-mode:5.32.0 start ./my-prd.md
|
|
378
379
|
```
|
|
379
380
|
|
|
380
381
|
### Degraded Mode
|
|
@@ -611,6 +612,107 @@ CORS_ALLOWED_ORIGINS="http://localhost:3000,https://my-dashboard.example.com" lo
|
|
|
611
612
|
|
|
612
613
|
---
|
|
613
614
|
|
|
615
|
+
## Shell Completions
|
|
616
|
+
|
|
617
|
+
Enable tab completion for the `loki` CLI to support subcommands, flags, and file arguments.
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## Bash Setup
|
|
622
|
+
|
|
623
|
+
### Option 1: Permanent Setup (Recommended)
|
|
624
|
+
|
|
625
|
+
Add the source command to your startup file so completions load every time you open a terminal.
|
|
626
|
+
|
|
627
|
+
Add this line to your `~/.bashrc` (Linux) or `~/.bash_profile` (macOS):
|
|
628
|
+
|
|
629
|
+
```bash
|
|
630
|
+
source /path/to/loki/completions/loki.bash
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
---
|
|
634
|
+
|
|
635
|
+
### Option 2: Manual Sourcing (Temporary)
|
|
636
|
+
|
|
637
|
+
If you only want to enable completions for your current terminal session (for example, for testing), run:
|
|
638
|
+
|
|
639
|
+
```bash
|
|
640
|
+
source completions/loki.bash
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
---
|
|
644
|
+
|
|
645
|
+
### Optional: Smoother Bash Experience
|
|
646
|
+
|
|
647
|
+
By default, Bash requires two **TAB** presses to show the completion menu. To make it instant (similar to Zsh) and cycle through options more easily, add the following lines to your `~/.inputrc` file:
|
|
648
|
+
|
|
649
|
+
```bash
|
|
650
|
+
# Show menu immediately on first TAB
|
|
651
|
+
set show-all-if-ambiguous on
|
|
652
|
+
|
|
653
|
+
# Case-insensitive completion (optional)
|
|
654
|
+
set completion-ignore-case on
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
> **Note:** You will need to restart your terminal for `~/.inputrc` changes to take effect.
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## Zsh Setup
|
|
662
|
+
|
|
663
|
+
Zsh completions require the script to be located in a directory listed in your `$fpath`.
|
|
664
|
+
|
|
665
|
+
### Permanent Setup
|
|
666
|
+
|
|
667
|
+
Add the `loki` completions directory to your `$fpath` in `~/.zshrc` **before** initializing completions:
|
|
668
|
+
|
|
669
|
+
```bash
|
|
670
|
+
# 1. Add the completions directory to fpath
|
|
671
|
+
fpath=(/path/to/loki/completions $fpath)
|
|
672
|
+
|
|
673
|
+
# 2. Initialize completions
|
|
674
|
+
autoload -Uz compinit && compinit
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## Testing Completions
|
|
680
|
+
|
|
681
|
+
After installation, restart your shell or source your configuration file, then verify:
|
|
682
|
+
|
|
683
|
+
### Bash
|
|
684
|
+
|
|
685
|
+
```bash
|
|
686
|
+
loki <TAB> # Should immediately list subcommands
|
|
687
|
+
loki start -<TAB> # Should list flags (--provider, --parallel, etc.)
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Zsh
|
|
691
|
+
|
|
692
|
+
```bash
|
|
693
|
+
loki <TAB> # Should show subcommands with descriptions
|
|
694
|
+
loki start --pro<TAB> # Should autocomplete to --provider
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
## Completion Features
|
|
700
|
+
|
|
701
|
+
The completion scripts support:
|
|
702
|
+
|
|
703
|
+
* **Subcommands**
|
|
704
|
+
`start`, `stop`, `pause`, `resume`, `status`, `dashboard`, `import`, `council`, `memory`, `provider`, `config`, `help`, `completions`
|
|
705
|
+
|
|
706
|
+
* **Smart Context**
|
|
707
|
+
|
|
708
|
+
* `loki start --provider <TAB>` shows only installed providers (`claude`, `codex`, `gemini`).
|
|
709
|
+
* `loki start <TAB>` defaults to file completion for PRD templates.
|
|
710
|
+
|
|
711
|
+
* **Nested Commands**
|
|
712
|
+
Handles specific subcommands for `council`, `memory`, and `config`.
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
614
716
|
## Troubleshooting
|
|
615
717
|
|
|
616
718
|
### Skill Not Found
|
package/package.json
CHANGED
package/templates/README.md
CHANGED
|
@@ -27,6 +27,7 @@ claude --dangerously-skip-permissions
|
|
|
27
27
|
|
|
28
28
|
| Template | Description | Tech Stack | Est. Time |
|
|
29
29
|
|----------|-------------|------------|-----------|
|
|
30
|
+
| [rest-api-auth.md](rest-api-auth.md) | REST API with JWT auth, registration, login, refresh, rate limiting | Express/FastAPI, PostgreSQL, JWT, bcrypt | 30-45 min |
|
|
30
31
|
| [full-stack-demo.md](full-stack-demo.md) | Bookmark manager with tags, search, and filtering | React, Express, SQLite, TailwindCSS | 30-60 min |
|
|
31
32
|
| [cli-tool.md](cli-tool.md) | File organizer CLI with subcommands, config, watch mode, undo | Node.js, Commander.js, chalk, chokidar | 30-45 min |
|
|
32
33
|
| [discord-bot.md](discord-bot.md) | Moderation bot with slash commands, auto-mod, reaction roles | discord.js, SQLite, node-cron | 45-60 min |
|
|
@@ -69,7 +70,7 @@ Every template follows a consistent structure:
|
|
|
69
70
|
|
|
70
71
|
**Testing specific agent types:**
|
|
71
72
|
- Frontend agent: `static-landing-page.md`, `chrome-extension.md`
|
|
72
|
-
- Backend agent: `api-only.md`, `discord-bot.md`
|
|
73
|
+
- Backend agent: `api-only.md`, `rest-api-auth.md`, `discord-bot.md`
|
|
73
74
|
- Full-stack agent: `full-stack-demo.md`, `blog-platform.md`
|
|
74
75
|
- DevOps/CLI agent: `cli-tool.md`
|
|
75
76
|
- Mobile agent: `mobile-app.md`
|