loki-mode 7.7.25 → 7.7.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/assets/lokesh_brand_full.png +0 -0
- package/assets/publisher-icon-128.png +0 -0
- package/assets/welcome/welcome.html +358 -0
- package/autonomy/loki +95 -0
- package/autonomy/run.sh +2 -2
- package/bin/postinstall.js +3 -0
- package/dashboard/__init__.py +1 -1
- package/dashboard/static/index.html +2 -2
- package/docs/INSTALLATION.md +2 -2
- package/docs/WELCOME-OPENER-PLAN.md +106 -0
- package/docs/auto-claude-comparison.md +3 -3
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +2 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-to-product system. Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product via the RARV-C closure loop, with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v7.7.
|
|
6
|
+
# Loki Mode v7.7.27
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -381,4 +381,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
381
381
|
|
|
382
382
|
---
|
|
383
383
|
|
|
384
|
-
**v7.7.
|
|
384
|
+
**v7.7.27 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.7.
|
|
1
|
+
7.7.27
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<meta name="theme-color" content="#553DE9">
|
|
7
|
+
<title>Welcome to Loki Mode</title>
|
|
8
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
|
+
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
11
|
+
<style>
|
|
12
|
+
:root {
|
|
13
|
+
--loki-bg-primary: #FAFAF7;
|
|
14
|
+
--loki-bg-secondary: #F2F0EB;
|
|
15
|
+
--loki-bg-card: rgba(255, 255, 255, 0.72);
|
|
16
|
+
--loki-text-primary: #1A1614;
|
|
17
|
+
--loki-text-secondary: #4A4640;
|
|
18
|
+
--loki-text-muted: #8A857C;
|
|
19
|
+
--loki-accent: #553DE9;
|
|
20
|
+
--loki-accent-hover: #4432c4;
|
|
21
|
+
--loki-accent-glow: rgba(85, 61, 233, 0.15);
|
|
22
|
+
--loki-border: rgba(0, 0, 0, 0.08);
|
|
23
|
+
--loki-success: #1AAF95;
|
|
24
|
+
--loki-glass-bg: rgba(255, 255, 255, 0.55);
|
|
25
|
+
--loki-glass-border: rgba(255, 255, 255, 0.35);
|
|
26
|
+
--loki-glass-shadow: 0 4px 24px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
27
|
+
--loki-transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
28
|
+
}
|
|
29
|
+
@media (prefers-color-scheme: dark) {
|
|
30
|
+
:root {
|
|
31
|
+
--loki-bg-primary: #0F0B1A;
|
|
32
|
+
--loki-bg-secondary: #150F24;
|
|
33
|
+
--loki-bg-card: rgba(30, 21, 51, 0.72);
|
|
34
|
+
--loki-text-primary: #F0ECF8;
|
|
35
|
+
--loki-text-secondary: #B8B0C8;
|
|
36
|
+
--loki-text-muted: #8A82A0;
|
|
37
|
+
--loki-border: rgba(255, 255, 255, 0.10);
|
|
38
|
+
--loki-glass-bg: rgba(30, 21, 51, 0.55);
|
|
39
|
+
--loki-glass-border: rgba(255, 255, 255, 0.10);
|
|
40
|
+
--loki-glass-shadow: 0 4px 24px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
44
|
+
html, body { height: 100%; }
|
|
45
|
+
body {
|
|
46
|
+
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
|
47
|
+
background: var(--loki-bg-primary);
|
|
48
|
+
color: var(--loki-text-primary);
|
|
49
|
+
line-height: 1.55;
|
|
50
|
+
-webkit-font-smoothing: antialiased;
|
|
51
|
+
background-image: radial-gradient(circle at 15% 10%, var(--loki-accent-glow), transparent 40%);
|
|
52
|
+
}
|
|
53
|
+
.wrap { max-width: 880px; margin: 0 auto; padding: 56px 24px 72px; }
|
|
54
|
+
.brand { display: flex; align-items: center; gap: 10px; margin-bottom: 36px; }
|
|
55
|
+
.brand-mark {
|
|
56
|
+
width: 34px; height: 34px; border-radius: 9px;
|
|
57
|
+
background: linear-gradient(135deg, var(--loki-accent), #7B63FF);
|
|
58
|
+
display: flex; align-items: center; justify-content: center;
|
|
59
|
+
color: #fff; font-family: 'DM Serif Display', serif; font-size: 20px;
|
|
60
|
+
}
|
|
61
|
+
.brand-name { font-family: 'DM Serif Display', serif; font-size: 1.25rem; }
|
|
62
|
+
.brand-by { color: var(--loki-text-muted); font-size: 0.8rem; letter-spacing: 0.04em; text-transform: uppercase; }
|
|
63
|
+
h1 { font-family: 'DM Serif Display', Georgia, serif; font-size: 2.6rem; font-weight: 400; line-height: 1.1; margin-bottom: 14px; letter-spacing: -0.01em; }
|
|
64
|
+
.lede { font-size: 1.12rem; color: var(--loki-text-secondary); max-width: 600px; margin-bottom: 8px; }
|
|
65
|
+
.ver { font-family: 'JetBrains Mono', monospace; font-size: 0.8rem; color: var(--loki-text-muted); margin-bottom: 36px; }
|
|
66
|
+
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin-bottom: 40px; }
|
|
67
|
+
.card {
|
|
68
|
+
background: var(--loki-glass-bg);
|
|
69
|
+
border: 1px solid var(--loki-glass-border);
|
|
70
|
+
box-shadow: var(--loki-glass-shadow);
|
|
71
|
+
border-radius: 12px; padding: 18px 18px 20px;
|
|
72
|
+
backdrop-filter: blur(8px);
|
|
73
|
+
}
|
|
74
|
+
.card h3 { font-family: 'DM Serif Display', serif; font-size: 1.05rem; font-weight: 400; margin-bottom: 6px; }
|
|
75
|
+
.card p { font-size: 0.88rem; color: var(--loki-text-secondary); }
|
|
76
|
+
.card .tag { display: inline-block; font-family: 'JetBrains Mono', monospace; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--loki-accent); margin-bottom: 10px; }
|
|
77
|
+
.form-card {
|
|
78
|
+
background: var(--loki-bg-card);
|
|
79
|
+
border: 1px solid var(--loki-border);
|
|
80
|
+
border-radius: 14px; padding: 26px; margin-bottom: 18px;
|
|
81
|
+
box-shadow: var(--loki-glass-shadow);
|
|
82
|
+
}
|
|
83
|
+
.form-card h2 { font-family: 'DM Serif Display', serif; font-weight: 400; font-size: 1.4rem; margin-bottom: 6px; }
|
|
84
|
+
.form-sub { color: var(--loki-text-muted); font-size: 0.9rem; margin-bottom: 22px; }
|
|
85
|
+
.field { margin-bottom: 18px; }
|
|
86
|
+
.field label { display: block; font-size: 0.82rem; font-weight: 500; margin-bottom: 7px; color: var(--loki-text-secondary); }
|
|
87
|
+
select {
|
|
88
|
+
width: 100%; padding: 10px 12px; font-family: inherit; font-size: 0.92rem;
|
|
89
|
+
color: var(--loki-text-primary); background: var(--loki-bg-primary);
|
|
90
|
+
border: 1px solid var(--loki-border); border-radius: 8px; appearance: none;
|
|
91
|
+
cursor: pointer; transition: border-color var(--loki-transition);
|
|
92
|
+
}
|
|
93
|
+
select:focus { outline: none; border-color: var(--loki-accent); box-shadow: 0 0 0 3px var(--loki-accent-glow); }
|
|
94
|
+
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
95
|
+
.chip {
|
|
96
|
+
font-size: 0.84rem; padding: 7px 13px; border-radius: 999px;
|
|
97
|
+
border: 1px solid var(--loki-border); background: var(--loki-bg-primary);
|
|
98
|
+
color: var(--loki-text-secondary); cursor: pointer; user-select: none;
|
|
99
|
+
transition: all var(--loki-transition);
|
|
100
|
+
}
|
|
101
|
+
.chip[aria-pressed="true"] {
|
|
102
|
+
background: var(--loki-accent); color: #fff; border-color: var(--loki-accent);
|
|
103
|
+
}
|
|
104
|
+
.btn {
|
|
105
|
+
width: 100%; padding: 13px; font-family: inherit; font-size: 0.95rem; font-weight: 600;
|
|
106
|
+
color: #fff; background: var(--loki-accent); border: none; border-radius: 9px;
|
|
107
|
+
cursor: pointer; transition: background var(--loki-transition); margin-top: 6px;
|
|
108
|
+
}
|
|
109
|
+
.btn:hover { background: var(--loki-accent-hover); }
|
|
110
|
+
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
|
|
111
|
+
.consent { font-size: 0.76rem; color: var(--loki-text-muted); margin-top: 14px; line-height: 1.5; }
|
|
112
|
+
.consent code { font-family: 'JetBrains Mono', monospace; font-size: 0.72rem; background: var(--loki-bg-secondary); padding: 1px 5px; border-radius: 4px; }
|
|
113
|
+
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
|
|
114
|
+
.cta {
|
|
115
|
+
display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
|
|
116
|
+
font-size: 0.9rem; font-weight: 500; padding: 10px 16px; border-radius: 8px;
|
|
117
|
+
border: 1px solid var(--loki-border); color: var(--loki-text-primary);
|
|
118
|
+
background: var(--loki-bg-card); transition: all var(--loki-transition);
|
|
119
|
+
}
|
|
120
|
+
.cta:hover { border-color: var(--loki-accent); color: var(--loki-accent); }
|
|
121
|
+
.cta.primary { background: var(--loki-accent); color: #fff; border-color: var(--loki-accent); }
|
|
122
|
+
.cta.primary:hover { background: var(--loki-accent-hover); color: #fff; }
|
|
123
|
+
.quickstart {
|
|
124
|
+
font-family: 'JetBrains Mono', monospace; font-size: 0.85rem;
|
|
125
|
+
background: var(--loki-bg-secondary); border: 1px solid var(--loki-border);
|
|
126
|
+
border-radius: 8px; padding: 9px 13px; color: var(--loki-text-primary);
|
|
127
|
+
}
|
|
128
|
+
.research { margin-top: 34px; font-size: 0.76rem; color: var(--loki-text-muted); }
|
|
129
|
+
.research .rchips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
130
|
+
.rchip { font-family: 'JetBrains Mono', monospace; font-size: 0.68rem; padding: 3px 8px; border: 1px solid var(--loki-border); border-radius: 6px; }
|
|
131
|
+
.thanks { display: none; text-align: center; padding: 18px 0; }
|
|
132
|
+
.thanks.show { display: block; }
|
|
133
|
+
.thanks .check { width: 44px; height: 44px; border-radius: 50%; background: var(--loki-success); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 22px; margin-bottom: 12px; }
|
|
134
|
+
.disabled-note { display: none; font-size: 0.85rem; color: var(--loki-text-muted); background: var(--loki-bg-secondary); border: 1px solid var(--loki-border); border-radius: 8px; padding: 12px 14px; }
|
|
135
|
+
.disabled-note.show { display: block; }
|
|
136
|
+
footer { margin-top: 40px; font-size: 0.78rem; color: var(--loki-text-muted); }
|
|
137
|
+
footer a { color: var(--loki-accent); text-decoration: none; }
|
|
138
|
+
</style>
|
|
139
|
+
</head>
|
|
140
|
+
<body>
|
|
141
|
+
<div class="wrap">
|
|
142
|
+
<div class="brand">
|
|
143
|
+
<div class="brand-mark">L</div>
|
|
144
|
+
<div>
|
|
145
|
+
<div class="brand-name">Loki Mode</div>
|
|
146
|
+
<div class="brand-by">Powered by Autonomi</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<h1>Describe it. Walk away.<br>Get working, tested software.</h1>
|
|
151
|
+
<p class="lede">Loki takes a spec (a PRD, a GitHub issue, or a one-line brief) all the way to a deployed product, running its Reason-Act-Reflect-Verify-Close loop until the work is actually done, not just attempted.</p>
|
|
152
|
+
<div class="ver" id="ver">loki-mode</div>
|
|
153
|
+
|
|
154
|
+
<div class="cards">
|
|
155
|
+
<div class="card">
|
|
156
|
+
<span class="tag">Verified, not just generated</span>
|
|
157
|
+
<h3>Closure loop + council</h3>
|
|
158
|
+
<p>Every change passes a RARV-C cycle and a unanimous multi-reviewer council before it counts as done. A quality bar you can audit.</p>
|
|
159
|
+
</div>
|
|
160
|
+
<div class="card">
|
|
161
|
+
<span class="tag">Compounds over time</span>
|
|
162
|
+
<h3>Cross-project memory</h3>
|
|
163
|
+
<p>Lessons learned on one project surface on the next, so your agents stop repeating the same mistakes across your whole codebase.</p>
|
|
164
|
+
</div>
|
|
165
|
+
<div class="card">
|
|
166
|
+
<span class="tag">Yours to run</span>
|
|
167
|
+
<h3>Provider-agnostic and private</h3>
|
|
168
|
+
<p>Runs on Claude, Codex, Cline, or Aider. Your keys, your infrastructure, no vendor lock-in.</p>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<div class="form-card" id="formCard">
|
|
173
|
+
<h2>Tell us who you are</h2>
|
|
174
|
+
<p class="form-sub">Optional, takes 10 seconds, and helps us build the right thing.</p>
|
|
175
|
+
|
|
176
|
+
<div class="field">
|
|
177
|
+
<label for="role">Your role</label>
|
|
178
|
+
<select id="role">
|
|
179
|
+
<option value="">Select...</option>
|
|
180
|
+
<option>Founder / CEO</option>
|
|
181
|
+
<option>Engineering leader</option>
|
|
182
|
+
<option>Software engineer</option>
|
|
183
|
+
<option>Product manager</option>
|
|
184
|
+
<option>Designer</option>
|
|
185
|
+
<option>Student / learner</option>
|
|
186
|
+
<option>Researcher</option>
|
|
187
|
+
<option>Other</option>
|
|
188
|
+
</select>
|
|
189
|
+
</div>
|
|
190
|
+
|
|
191
|
+
<div class="field">
|
|
192
|
+
<label for="company">Company size</label>
|
|
193
|
+
<select id="company">
|
|
194
|
+
<option value="">Select...</option>
|
|
195
|
+
<option>Just me</option>
|
|
196
|
+
<option>2-10</option>
|
|
197
|
+
<option>11-50</option>
|
|
198
|
+
<option>51-200</option>
|
|
199
|
+
<option>201-1000</option>
|
|
200
|
+
<option>1000+</option>
|
|
201
|
+
</select>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<div class="field">
|
|
205
|
+
<label>Tools you use today</label>
|
|
206
|
+
<div class="chips" id="tools">
|
|
207
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">Claude Code</span>
|
|
208
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">Cursor</span>
|
|
209
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">OpenAI Codex</span>
|
|
210
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">GitHub Copilot</span>
|
|
211
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">Cline</span>
|
|
212
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">Aider</span>
|
|
213
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">Replit</span>
|
|
214
|
+
<span class="chip" role="button" tabindex="0" aria-pressed="false">Other</span>
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<button class="btn" id="submitBtn">Send and get started</button>
|
|
219
|
+
<p class="consent">
|
|
220
|
+
Sends <strong>anonymous</strong> usage analytics (your role, company size, and tools)
|
|
221
|
+
to help us improve the product. We <strong>never</strong> collect your prompts, PRDs, or
|
|
222
|
+
code. Opt out anytime with <code>LOKI_TELEMETRY_DISABLED=true</code> or <code>DO_NOT_TRACK=1</code>.
|
|
223
|
+
</p>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<div class="disabled-note" id="disabledNote">
|
|
227
|
+
Analytics are turned off for this session (LOKI_TELEMETRY_DISABLED / DO_NOT_TRACK).
|
|
228
|
+
Nothing will be sent. Welcome aboard regardless.
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<div class="thanks" id="thanks">
|
|
232
|
+
<div class="check">✓</div>
|
|
233
|
+
<h2 style="font-family:'DM Serif Display',serif;font-weight:400;">Thanks, you're all set.</h2>
|
|
234
|
+
<p style="color:var(--loki-text-secondary);margin-top:6px;">Point Loki at a spec and let it run.</p>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
<div class="cta-row">
|
|
238
|
+
<a class="cta primary" href="https://www.autonomi.dev/docs" target="_blank" rel="noopener">Read the docs</a>
|
|
239
|
+
<span class="quickstart">loki start ./prd.md</span>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
<div class="research">
|
|
243
|
+
Built on published research from Anthropic, Google DeepMind, OpenAI, and NVIDIA.
|
|
244
|
+
<div class="rchips">
|
|
245
|
+
<span class="rchip">Constitutional AI</span>
|
|
246
|
+
<span class="rchip">Scalable Oversight via Debate</span>
|
|
247
|
+
<span class="rchip">Agents SDK guardrails</span>
|
|
248
|
+
<span class="rchip">ToolOrchestra efficiency</span>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
<footer>
|
|
253
|
+
Loki Mode by <a href="https://www.autonomi.dev/" target="_blank" rel="noopener">Autonomi</a>.
|
|
254
|
+
Questions? <a href="https://www.autonomi.dev/docs" target="_blank" rel="noopener">autonomi.dev/docs</a>
|
|
255
|
+
</footer>
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<script>
|
|
259
|
+
(function () {
|
|
260
|
+
"use strict";
|
|
261
|
+
var POSTHOG_HOST = "https://us.i.posthog.com";
|
|
262
|
+
var POSTHOG_KEY = "phc_ya0vGBru41AJWtGNfZZ8H9W4yjoZy4KON0nnayS7s87";
|
|
263
|
+
|
|
264
|
+
// Read params the CLI may pass: ?telemetry=off, ?v=<version>, ?key=<override>, ?did=<distinct_id>
|
|
265
|
+
var params = new URLSearchParams(window.location.search);
|
|
266
|
+
var telemetryOff = params.get("telemetry") === "off";
|
|
267
|
+
var version = params.get("v") || "loki-mode";
|
|
268
|
+
if (params.get("key")) { POSTHOG_KEY = params.get("key"); }
|
|
269
|
+
var verEl = document.getElementById("ver");
|
|
270
|
+
if (verEl) { verEl.textContent = version; }
|
|
271
|
+
|
|
272
|
+
// distinct_id: prefer the id the CLI injects (the existing anonymous
|
|
273
|
+
// ~/.loki-telemetry-id), else a browser-local random id. Never an email
|
|
274
|
+
// or real name (the form has no such field).
|
|
275
|
+
function distinctId() {
|
|
276
|
+
var injected = params.get("did");
|
|
277
|
+
if (injected) { return injected; }
|
|
278
|
+
try {
|
|
279
|
+
var k = "loki_welcome_did";
|
|
280
|
+
var v = localStorage.getItem(k);
|
|
281
|
+
if (!v) {
|
|
282
|
+
v = (window.crypto && crypto.randomUUID) ? crypto.randomUUID()
|
|
283
|
+
: "web-" + Date.now() + "-" + Math.random().toString(36).slice(2);
|
|
284
|
+
localStorage.setItem(k, v);
|
|
285
|
+
}
|
|
286
|
+
return v;
|
|
287
|
+
} catch (e) {
|
|
288
|
+
return "web-anon";
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
var formCard = document.getElementById("formCard");
|
|
293
|
+
var disabledNote = document.getElementById("disabledNote");
|
|
294
|
+
var thanks = document.getElementById("thanks");
|
|
295
|
+
var submitBtn = document.getElementById("submitBtn");
|
|
296
|
+
|
|
297
|
+
// Opt-out: hide the form and return before any handler binds, so a
|
|
298
|
+
// capture can never fire. No network call happens on load either.
|
|
299
|
+
if (telemetryOff) {
|
|
300
|
+
if (formCard) { formCard.style.display = "none"; }
|
|
301
|
+
if (disabledNote) { disabledNote.classList.add("show"); }
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Tool chips toggle (local UI state only).
|
|
306
|
+
var toolEls = Array.prototype.slice.call(document.querySelectorAll("#tools .chip"));
|
|
307
|
+
function toggleChip(el) {
|
|
308
|
+
var on = el.getAttribute("aria-pressed") === "true";
|
|
309
|
+
el.setAttribute("aria-pressed", on ? "false" : "true");
|
|
310
|
+
}
|
|
311
|
+
toolEls.forEach(function (el) {
|
|
312
|
+
el.addEventListener("click", function () { toggleChip(el); });
|
|
313
|
+
el.addEventListener("keydown", function (e) {
|
|
314
|
+
if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggleChip(el); }
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// The ONLY network call in the page happens here, on explicit click.
|
|
319
|
+
submitBtn.addEventListener("click", function () {
|
|
320
|
+
var role = document.getElementById("role").value || "unspecified";
|
|
321
|
+
var company = document.getElementById("company").value || "unspecified";
|
|
322
|
+
var tools = toolEls
|
|
323
|
+
.filter(function (el) { return el.getAttribute("aria-pressed") === "true"; })
|
|
324
|
+
.map(function (el) { return el.textContent.trim(); });
|
|
325
|
+
|
|
326
|
+
var payload = {
|
|
327
|
+
api_key: POSTHOG_KEY,
|
|
328
|
+
event: "welcome_profile",
|
|
329
|
+
distinct_id: distinctId(),
|
|
330
|
+
properties: {
|
|
331
|
+
role: role,
|
|
332
|
+
company_size: company,
|
|
333
|
+
tools: tools,
|
|
334
|
+
source: "welcome_opener",
|
|
335
|
+
loki_version: version
|
|
336
|
+
// Deliberately NO prompt, PRD, code, file path, cwd, hostname,
|
|
337
|
+
// project name, email, or real name. Anonymous fields only.
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
submitBtn.disabled = true;
|
|
342
|
+
submitBtn.textContent = "Sending...";
|
|
343
|
+
|
|
344
|
+
fetch(POSTHOG_HOST + "/capture/", {
|
|
345
|
+
method: "POST",
|
|
346
|
+
headers: { "Content-Type": "application/json" },
|
|
347
|
+
body: JSON.stringify(payload),
|
|
348
|
+
keepalive: true
|
|
349
|
+
}).catch(function () { /* fire-and-forget; never block the user */ })
|
|
350
|
+
.finally(function () {
|
|
351
|
+
if (formCard) { formCard.style.display = "none"; }
|
|
352
|
+
if (thanks) { thanks.classList.add("show"); }
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
})();
|
|
356
|
+
</script>
|
|
357
|
+
</body>
|
|
358
|
+
</html>
|
package/autonomy/loki
CHANGED
|
@@ -700,6 +700,10 @@ detect_arg_type() {
|
|
|
700
700
|
|
|
701
701
|
# Start Loki Mode
|
|
702
702
|
cmd_start() {
|
|
703
|
+
# First-run welcome (once): open the branded welcome page on the very
|
|
704
|
+
# first start. Writes ~/.loki/.welcomed and never repeats; non-blocking,
|
|
705
|
+
# and never auto-opens a browser in CI or non-interactive shells.
|
|
706
|
+
cmd_welcome_maybe_firstrun 2>/dev/null || true
|
|
703
707
|
local args=()
|
|
704
708
|
local prd_file=""
|
|
705
709
|
local provider=""
|
|
@@ -3837,6 +3841,94 @@ cmd_dashboard_open() {
|
|
|
3837
3841
|
fi
|
|
3838
3842
|
}
|
|
3839
3843
|
|
|
3844
|
+
# Welcome opener (the "magic opener"). Shows a branded welcome page in the
|
|
3845
|
+
# browser, or a terminal welcome when no browser is available (headless,
|
|
3846
|
+
# Docker, CI). Honors telemetry opt-out (LOKI_TELEMETRY_DISABLED / DO_NOT_TRACK):
|
|
3847
|
+
# when opted out, the page is loaded with ?telemetry=off so its form is
|
|
3848
|
+
# disabled and no analytics are ever sent.
|
|
3849
|
+
WELCOME_MARKER="${HOME}/.loki/.welcomed"
|
|
3850
|
+
|
|
3851
|
+
_loki_telemetry_off() {
|
|
3852
|
+
[ "${LOKI_TELEMETRY_DISABLED:-}" = "true" ] && return 0
|
|
3853
|
+
[ "${DO_NOT_TRACK:-}" = "1" ] && return 0
|
|
3854
|
+
return 1
|
|
3855
|
+
}
|
|
3856
|
+
|
|
3857
|
+
cmd_welcome_terminal() {
|
|
3858
|
+
local ver="${1:-}"
|
|
3859
|
+
echo ""
|
|
3860
|
+
echo -e " ${BOLD}Loki Mode${NC} ${DIM}by Autonomi${NC}${ver:+ ${DIM}v${ver}${NC}}"
|
|
3861
|
+
echo ""
|
|
3862
|
+
echo -e " ${BOLD}Describe it. Walk away. Get working, tested software.${NC}"
|
|
3863
|
+
echo ""
|
|
3864
|
+
echo -e " Loki takes a spec (PRD, GitHub issue, or one-line brief) to a deployed"
|
|
3865
|
+
echo -e " product via the RARV-C closure loop, until the work is actually done."
|
|
3866
|
+
echo ""
|
|
3867
|
+
echo -e " ${CYAN}Closure loop + council${NC} Every change is verified by a unanimous council."
|
|
3868
|
+
echo -e " ${CYAN}Cross-project memory${NC} Lessons compound, so agents stop repeating mistakes."
|
|
3869
|
+
echo -e " ${CYAN}Provider-agnostic${NC} Claude, Codex, Cline, or Aider. Your keys, your infra."
|
|
3870
|
+
echo ""
|
|
3871
|
+
echo -e " Quick start: ${BOLD}loki start ./prd.md${NC}"
|
|
3872
|
+
echo -e " Docs: ${BOLD}https://www.autonomi.dev/docs${NC}"
|
|
3873
|
+
echo ""
|
|
3874
|
+
if _loki_telemetry_off; then
|
|
3875
|
+
echo -e " ${DIM}Analytics are off for this session. Nothing is sent.${NC}"
|
|
3876
|
+
else
|
|
3877
|
+
echo -e " ${DIM}Anonymous usage analytics help us improve the product. We never${NC}"
|
|
3878
|
+
echo -e " ${DIM}collect prompts, PRDs, or code. Opt out: LOKI_TELEMETRY_DISABLED=true${NC}"
|
|
3879
|
+
fi
|
|
3880
|
+
echo ""
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
cmd_welcome() {
|
|
3884
|
+
local ver=""
|
|
3885
|
+
[ -f "${SKILL_DIR}/VERSION" ] && ver="$(cat "${SKILL_DIR}/VERSION" 2>/dev/null | tr -d '[:space:]')"
|
|
3886
|
+
|
|
3887
|
+
local welcome_file="${SKILL_DIR}/assets/welcome/welcome.html"
|
|
3888
|
+
|
|
3889
|
+
# Build the file URL with params: version, opt-out, and the existing
|
|
3890
|
+
# anonymous telemetry distinct-id (so browser + install share one id).
|
|
3891
|
+
local q="v=${ver}"
|
|
3892
|
+
if _loki_telemetry_off; then
|
|
3893
|
+
q="${q}&telemetry=off"
|
|
3894
|
+
else
|
|
3895
|
+
local idfile="${HOME}/.loki-telemetry-id"
|
|
3896
|
+
[ -f "$idfile" ] && q="${q}&did=$(cat "$idfile" 2>/dev/null | tr -d '[:space:]')"
|
|
3897
|
+
fi
|
|
3898
|
+
|
|
3899
|
+
# Headless / Docker / CI / no-browser: print the terminal welcome only.
|
|
3900
|
+
local has_browser=""
|
|
3901
|
+
if command -v open >/dev/null 2>&1; then has_browser="open"
|
|
3902
|
+
elif command -v xdg-open >/dev/null 2>&1; then has_browser="xdg-open"
|
|
3903
|
+
elif command -v start >/dev/null 2>&1; then has_browser="start"
|
|
3904
|
+
fi
|
|
3905
|
+
|
|
3906
|
+
if [ -z "$has_browser" ] || [ ! -f "$welcome_file" ] || [ -n "${CI:-}" ] || [ ! -t 1 ]; then
|
|
3907
|
+
cmd_welcome_terminal "$ver"
|
|
3908
|
+
[ -f "$welcome_file" ] && echo -e " ${DIM}Full welcome page: ${welcome_file}${NC}" && echo ""
|
|
3909
|
+
return 0
|
|
3910
|
+
fi
|
|
3911
|
+
|
|
3912
|
+
echo -e "${GREEN}Opening the Loki Mode welcome page in your browser...${NC}"
|
|
3913
|
+
"$has_browser" "file://${welcome_file}?${q}" >/dev/null 2>&1 || cmd_welcome_terminal "$ver"
|
|
3914
|
+
}
|
|
3915
|
+
|
|
3916
|
+
# First-run hook: open the welcome once, then never again. Browser only when
|
|
3917
|
+
# interactive + not CI + not opted out; otherwise nothing (no noisy auto-print
|
|
3918
|
+
# during a real run). Marker lives at ~/.loki/.welcomed.
|
|
3919
|
+
cmd_welcome_maybe_firstrun() {
|
|
3920
|
+
[ -f "$WELCOME_MARKER" ] && return 0
|
|
3921
|
+
mkdir -p "$(dirname "$WELCOME_MARKER")" 2>/dev/null || true
|
|
3922
|
+
: > "$WELCOME_MARKER" 2>/dev/null || true
|
|
3923
|
+
# Only auto-open on an interactive, non-CI terminal. cmd_welcome itself
|
|
3924
|
+
# re-checks for a browser and falls back to the terminal welcome, so we
|
|
3925
|
+
# gate purely on interactivity + CI here (grouped to avoid &&/|| precedence
|
|
3926
|
+
# ambiguity). Backgrounded so it never delays the start.
|
|
3927
|
+
if [ -t 1 ] && [ -z "${CI:-}" ]; then
|
|
3928
|
+
(cmd_welcome >/dev/null 2>&1 &) || true
|
|
3929
|
+
fi
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3840
3932
|
# Web app management
|
|
3841
3933
|
# Purple Lab -- standalone product web UI for Loki Mode.
|
|
3842
3934
|
# Runs on port 57375 (separate from dashboard at 57374).
|
|
@@ -12505,6 +12597,9 @@ main() {
|
|
|
12505
12597
|
demo)
|
|
12506
12598
|
cmd_demo "$@"
|
|
12507
12599
|
;;
|
|
12600
|
+
welcome)
|
|
12601
|
+
cmd_welcome "$@"
|
|
12602
|
+
;;
|
|
12508
12603
|
init)
|
|
12509
12604
|
cmd_init "$@"
|
|
12510
12605
|
;;
|
package/autonomy/run.sh
CHANGED
|
@@ -4405,7 +4405,7 @@ generate_dashboard() {
|
|
|
4405
4405
|
<body>
|
|
4406
4406
|
<div class="header">
|
|
4407
4407
|
<h1>LOKI MODE</h1>
|
|
4408
|
-
<div class="subtitle">Autonomous
|
|
4408
|
+
<div class="subtitle">Autonomous Spec-to-Product System</div>
|
|
4409
4409
|
<div class="phase" id="phase">Loading...</div>
|
|
4410
4410
|
</div>
|
|
4411
4411
|
<div class="stats">
|
|
@@ -12379,7 +12379,7 @@ main() {
|
|
|
12379
12379
|
echo " ███████╗╚██████╔╝██║ ██╗██║ ██║ ╚═╝ ██║╚██████╔╝██████╔╝███████╗"
|
|
12380
12380
|
echo " ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝"
|
|
12381
12381
|
echo -e "${NC}"
|
|
12382
|
-
echo -e " ${CYAN}Autonomous
|
|
12382
|
+
echo -e " ${CYAN}Autonomous Spec-to-Product System${NC}"
|
|
12383
12383
|
echo -e " ${CYAN}Version: $(cat "$PROJECT_DIR/VERSION" 2>/dev/null || echo "4.x.x")${NC}"
|
|
12384
12384
|
echo ""
|
|
12385
12385
|
|
package/bin/postinstall.js
CHANGED
|
@@ -173,8 +173,11 @@ console.log(' loki start --provider codex Start with OpenAI Codex');
|
|
|
173
173
|
console.log(' loki start --provider gemini Start with Google Gemini');
|
|
174
174
|
console.log(' loki status Check status');
|
|
175
175
|
console.log(' loki doctor Verify installation');
|
|
176
|
+
console.log(' loki welcome Quick tour, docs, and setup');
|
|
176
177
|
console.log(' loki --help Show all commands');
|
|
177
178
|
console.log('');
|
|
179
|
+
console.log('New here? Run `loki welcome` for a 30-second tour.');
|
|
180
|
+
console.log('');
|
|
178
181
|
|
|
179
182
|
// Anonymous install telemetry (fire-and-forget, silent)
|
|
180
183
|
try {
|
package/dashboard/__init__.py
CHANGED
|
@@ -13195,7 +13195,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
13195
13195
|
border-radius: 4px;
|
|
13196
13196
|
}
|
|
13197
13197
|
</style>
|
|
13198
|
-
`,a="";this._loading&&this._items.length===0?a='<div class="esc-empty">Loading escalations...</div>':this._error?a='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?a='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':a='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let i="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",i='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+a+i+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var yt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._pollInterval=setInterval(()=>this._load(),3e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._load()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _load(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._transcripts=[]}finally{this._loading=!1,this.render()}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_truncate(t,e){if(!t)return"";let a=String(t);return a.length>e?a.slice(0,e)+"...":a}_verdictBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':e==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':e==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':e==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':e==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_voterRowHtml(t,e){let a=t.is_contrarian===!0,i=a&&e===!0,s="ct-voter-row";a&&(s+=" ct-voter-contrarian"),i&&(s+=" ct-voter-flipped");let r=this._escapeHtml(t.name||"unknown"),o=this._verdictBadgeHtml(t.verdict),n=this._escapeHtml(this._truncate(t.reasoning,300)),l="",c="";i?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):a&&t.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";a&&Array.isArray(t.challenges)&&t.challenges.length>0&&(p='<ul class="ct-challenges">'+t.challenges.map(m=>"<li>"+this._escapeHtml(String(m))+"</li>").join("")+"</ul>");let u="";return Array.isArray(t.issues)&&t.issues.length>0&&(u='<ul class="ct-issues">'+t.issues.map(m=>{let f=this._escapeHtml(m.severity||""),x=this._escapeHtml(m.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+f.toLowerCase()+'">'+f+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(t){let e=this._escapeHtml(String(t.iteration||"--")),a=this._escapeHtml(this._formatTimestamp(t.timestamp)),i=this._escapeHtml(this._truncate(t.task_or_prd,200)),s=this._outcomeBadgeHtml(t.outcome),r=Array.isArray(t.voters)?t.voters:[],o=r.filter(m=>!m.is_contrarian),n=r.filter(m=>m.is_contrarian),l=o.map(m=>this._voterRowHtml(m,!1)).join(""),c="";t.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,t.contrarian_flipped)).join("")+"</div>");let p=typeof t.approve_count=="number"?t.approve_count:"--",u=typeof t.reject_count=="number"?t.reject_count:"--",b=typeof t.threshold=="number"?t.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+e+'</span><span class="ct-ts">'+a+"</span></div>"+s+"</div>"+(i?'<div class="ct-prd-preview">'+i+"</div>":"")+'<div class="ct-tally">Approve: '+p+" · Reject: "+u+" · Threshold: "+b+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
|
|
13198
|
+
`,a="";this._loading&&this._items.length===0?a='<div class="esc-empty">Loading escalations...</div>':this._error?a='<div class="esc-error">Failed to load escalations: '+this._escapeHtml(this._error)+"</div>":!this._items||this._items.length===0?a='<div class="esc-empty">Escalations: no events yet. Handoff/escalation markdown documents written by the runner under .loki/escalations/ will appear here.</div>':a='<div class="esc-list">'+this._items.map(n=>{let l=this._escapeHtml(n.filename||""),c=this._escapeHtml(this._formatSize(n.size_bytes)),p=this._escapeHtml(this._formatDate(n.modified_at));return'<div class="esc-item" data-filename="'+l+'"><span class="esc-name">'+l+'</span><span class="esc-meta">'+c+" · "+p+"</span></div>"}).join("")+"</div>";let i="";if(this._activeFile){let o=this._escapeHtml(this._activeFile),n;this._activeBodyError?n='<div class="esc-error">Failed to load: '+this._escapeHtml(this._activeBodyError)+"</div>":this._activeBody===null?n='<div class="esc-body">Loading '+o+"...</div>":n='<div class="esc-body">'+this._escapeHtml(this._activeBody)+"</div>",i='<div class="esc-viewer"><div class="esc-viewer-header"><span class="esc-name">'+o+'</span><button class="esc-close-btn" data-action="close">Close</button></div>'+n+"</div>"}t.innerHTML=e+'<div class="esc-wrapper"><div class="esc-explain">Handoff/escalation documents written under .loki/escalations/. Click an entry to view its contents.</div>'+a+i+"</div>",t.querySelectorAll(".esc-item").forEach(o=>{o.addEventListener("click",()=>{let n=o.getAttribute("data-filename");n&&this._openFile(n)})});let r=t.querySelector('.esc-close-btn[data-action="close"]');r&&r.addEventListener("click",()=>this._closeFile())}};typeof customElements<"u"&&!customElements.get("loki-escalations")&&customElements.define("loki-escalations",_t);var yt=class extends h{static get observedAttributes(){return["api-url","theme"]}constructor(){super(),this._transcripts=[],this._hookEvents=[],this._loading=!1,this._error=null,this._api=null,this._pollInterval=null}connectedCallback(){super.connectedCallback(),this._setupApi(),this._load(),this._pollInterval=setInterval(()=>this._load(),3e4)}disconnectedCallback(){super.disconnectedCallback(),this._pollInterval&&(clearInterval(this._pollInterval),this._pollInterval=null)}attributeChangedCallback(t,e,a){e!==a&&(t==="api-url"&&this._api&&(this._api.baseUrl=a,this._load()),t==="theme"&&this._applyTheme())}_setupApi(){let t=this.getAttribute("api-url")||(typeof window<"u"?window.location.origin:"");this._api=g({baseUrl:t})}async _load(){this._loading=!0,this._error=null;try{let t=await this._api.get("/api/council/transcripts?limit=10");this._transcripts=Array.isArray(t&&t.transcripts)?t.transcripts:[]}catch(t){this._error=t&&t.message?t.message:String(t),this._transcripts=[]}try{let t=await this._api.get("/api/council/transcripts?limit=20&type_prefix=claude_hook_");this._hookEvents=Array.isArray(t&&t.hook_events)?t.hook_events:[]}catch{this._hookEvents=[]}finally{this._loading=!1,this.render()}}_escapeHtml(t){return t==null?"":String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}_formatTimestamp(t){if(!t)return"--";try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString()}catch{return t}}_truncate(t,e){if(!t)return"";let a=String(t);return a.length>e?a.slice(0,e)+"...":a}_verdictBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVE"?'<span class="ct-badge ct-badge-approve">APPROVE</span>':e==="REJECT"?'<span class="ct-badge ct-badge-reject">REJECT</span>':e==="CANNOT_VALIDATE"?'<span class="ct-badge ct-badge-cannot">CANNOT_VALIDATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_outcomeBadgeHtml(t){let e=String(t||"").toUpperCase();return e==="APPROVED"?'<span class="ct-badge ct-badge-approve">APPROVED</span>':e==="REJECTED"?'<span class="ct-badge ct-badge-reject">REJECTED</span>':e==="BLOCKED_BY_GATE"?'<span class="ct-badge ct-badge-blocked">BLOCKED BY GATE</span>':'<span class="ct-badge ct-badge-unknown">'+this._escapeHtml(e||"UNKNOWN")+"</span>"}_voterRowHtml(t,e){let a=t.is_contrarian===!0,i=a&&e===!0,s="ct-voter-row";a&&(s+=" ct-voter-contrarian"),i&&(s+=" ct-voter-flipped");let r=this._escapeHtml(t.name||"unknown"),o=this._verdictBadgeHtml(t.verdict),n=this._escapeHtml(this._truncate(t.reasoning,300)),l="",c="";i?(l='<span class="ct-badge ct-badge-override">OVERRIDE</span>',c=`<div class="ct-flip-caption">Devil's Advocate flipped this outcome</div>`):a&&t.triggered&&(l=`<span class="ct-badge ct-badge-da">DEVIL'S ADVOCATE</span>`);let p="";a&&Array.isArray(t.challenges)&&t.challenges.length>0&&(p='<ul class="ct-challenges">'+t.challenges.map(m=>"<li>"+this._escapeHtml(String(m))+"</li>").join("")+"</ul>");let u="";return Array.isArray(t.issues)&&t.issues.length>0&&(u='<ul class="ct-issues">'+t.issues.map(m=>{let f=this._escapeHtml(m.severity||""),x=this._escapeHtml(m.description||"");return'<li><span class="ct-issue-sev ct-issue-sev-'+f.toLowerCase()+'">'+f+"</span> "+x+"</li>"}).join("")+"</ul>"),'<div class="'+s+'"><div class="ct-voter-header"><span class="ct-voter-name">'+r+"</span>"+o+l+"</div>"+(n?'<div class="ct-voter-reason">'+n+"</div>":"")+p+u+c+"</div>"}_transcriptCardHtml(t){let e=this._escapeHtml(String(t.iteration||"--")),a=this._escapeHtml(this._formatTimestamp(t.timestamp)),i=this._escapeHtml(this._truncate(t.task_or_prd,200)),s=this._outcomeBadgeHtml(t.outcome),r=Array.isArray(t.voters)?t.voters:[],o=r.filter(m=>!m.is_contrarian),n=r.filter(m=>m.is_contrarian),l=o.map(m=>this._voterRowHtml(m,!1)).join(""),c="";t.contrarian_triggered&&(c='<div class="ct-contrarian-section"><div class="ct-section-label">Anti-Sycophancy Check</div>'+n.map(f=>this._voterRowHtml(f,t.contrarian_flipped)).join("")+"</div>");let p=typeof t.approve_count=="number"?t.approve_count:"--",u=typeof t.reject_count=="number"?t.reject_count:"--",b=typeof t.threshold=="number"?t.threshold:"--";return'<div class="ct-card"><div class="ct-card-header"><div class="ct-card-meta"><span class="ct-iter-label">Iteration '+e+'</span><span class="ct-ts">'+a+"</span></div>"+s+"</div>"+(i?'<div class="ct-prd-preview">'+i+"</div>":"")+'<div class="ct-tally">Approve: '+p+" · Reject: "+u+" · Threshold: "+b+'</div><div class="ct-voters">'+l+"</div>"+c+"</div>"}render(){let t=this.shadowRoot||this;if(!t)return;let e=`
|
|
13199
13199
|
<style>
|
|
13200
13200
|
:host { display: block; margin-top: 24px; }
|
|
13201
13201
|
.ct-wrapper {
|
|
@@ -13364,7 +13364,7 @@ var LokiDashboard=(()=>{var wt=Object.defineProperty;var ae=Object.getOwnPropert
|
|
|
13364
13364
|
.ct-badge-da { background: #fdf3d4; color: #8a6c0e; }
|
|
13365
13365
|
.ct-badge-unknown { background: var(--bg-secondary, #F8F4F0); color: var(--text-muted, #939084); }
|
|
13366
13366
|
</style>
|
|
13367
|
-
`,a="";this._loading&&this._transcripts.length===0?a='<div class="ct-empty">Loading council transcripts...</div>':this._error?a='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?a='<div class="ct-empty">No council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':a='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+a+"</div>"}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var He="1.4.0";function Re(d={}){return d.theme?_.setTheme(d.theme):d.autoDetectContext!==!1?_.init():R.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:_.getTheme(),context:_.detectContext()}}return le(Be);})();
|
|
13367
|
+
`,a="";this._loading&&this._transcripts.length===0?a='<div class="ct-empty">Loading council transcripts...</div>':this._error?a='<div class="ct-error">Failed to load transcripts: '+this._escapeHtml(this._error)+"</div>":!this._transcripts||this._transcripts.length===0?a='<div class="ct-empty">No council rounds recorded yet -- transcripts appear after the first iteration vote.</div>':a='<div class="ct-list">'+this._transcripts.map(s=>this._transcriptCardHtml(s)).join("")+"</div>",t.innerHTML=e+'<div class="ct-wrapper"><h3 class="ct-heading">Council Transcripts</h3><div class="ct-explain">Per-iteration voting records from .loki/council/transcripts/. Polls every 30 seconds.</div>'+a+this._hookEventsHtml()+"</div>"}_hookEventsHtml(){let t=Array.isArray(this._hookEvents)?this._hookEvents:[],e;return t.length===0?e='<div class="ct-empty">No live tool activity yet -- Claude hook events stream here while a run is active.</div>':e='<div class="ct-voters">'+t.slice(0,20).map(i=>{let s=this._escapeHtml(i.type||i.event||"event"),r=this._escapeHtml(this._formatTimestamp(i.timestamp||i.ts)),o=this._escapeHtml(this._truncate(i.tool||i.message||i.summary||(i.data?JSON.stringify(i.data):""),120));return'<div class="ct-voter-row"><span class="ct-iter-label">'+s+'</span> <span class="ct-ts">'+r+"</span>"+(o?'<div class="ct-prd-preview">'+o+"</div>":"")+"</div>"}).join("")+"</div>",'<h3 class="ct-heading" style="margin-top:24px;">Live Tool Activity</h3><div class="ct-explain">Claude hook events (PreToolUse / PostToolUse / Stop) streamed from .loki/events.jsonl. Lets you watch background tool calls as they run.</div>'+e}};typeof customElements<"u"&&!customElements.get("loki-council-transcripts")&&customElements.define("loki-council-transcripts",yt);var He="1.4.0";function Re(d={}){return d.theme?_.setTheme(d.theme):d.autoDetectContext!==!1?_.init():R.init(),d.apiUrl&&g({baseUrl:d.apiUrl}),{theme:_.getTheme(),context:_.detectContext()}}return le(Be);})();
|
|
13368
13368
|
|
|
13369
13369
|
|
|
13370
13370
|
// Initialize dashboard when DOM is ready
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v7.7.
|
|
5
|
+
**Version:** v7.7.27
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -447,7 +447,7 @@ cat ~/.claude/skills/loki-mode/SKILL.md | head -10
|
|
|
447
447
|
```yaml
|
|
448
448
|
---
|
|
449
449
|
name: loki-mode
|
|
450
|
-
description:
|
|
450
|
+
description: Autonomous Spec-to-Product System (RARV-C closure loop)
|
|
451
451
|
...
|
|
452
452
|
---
|
|
453
453
|
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Welcome Opener Plan (the "magic opener")
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
A polished welcome experience shown when people install the loki CLI or
|
|
5
|
+
run the Docker image. It (1) introduces Loki/Autonomi with the dashboard's
|
|
6
|
+
design language, (2) subtly highlights the research backing + memory
|
|
7
|
+
compounding moat, (3) offers a simple opt-in form collecting anonymous
|
|
8
|
+
role / business / tools, transmitted to PostHog on click, and (4) links to
|
|
9
|
+
autonomi.dev/docs.
|
|
10
|
+
|
|
11
|
+
## Hard constraints (from the user + CLAUDE.md)
|
|
12
|
+
- Anonymous usage analytics for PRODUCT IMPROVEMENT ONLY. NEVER transmit
|
|
13
|
+
prompts, PRDs, code, or any project content. Disclosed, not covert.
|
|
14
|
+
- Reuse the EXISTING PostHog contract already in the codebase:
|
|
15
|
+
- host `https://us.i.posthog.com`, path `/capture/`
|
|
16
|
+
- public ingest key `phc_ya0vGBru41AJWtGNfZZ8H9W4yjoZy4KON0nnayS7s87`
|
|
17
|
+
(same key postinstall.js + autonomy/telemetry.sh already use; public
|
|
18
|
+
ingest keys are safe in client code), overridable by LOKI_POSTHOG_KEY.
|
|
19
|
+
- Honor opt-out: LOKI_TELEMETRY_DISABLED=true and DO_NOT_TRACK=1.
|
|
20
|
+
- Design must match the loki dashboard: accent #553DE9, light bg #FAFAF7 /
|
|
21
|
+
dark #0F0B1A, text #1A1614 / #F0ECF8, fonts DM Serif Display (headings),
|
|
22
|
+
Inter (body), JetBrains Mono (mono). Glass cards. Light + dark.
|
|
23
|
+
- No emojis, no em dashes anywhere.
|
|
24
|
+
|
|
25
|
+
## Components
|
|
26
|
+
|
|
27
|
+
### 1. web-app-less static page: `assets/welcome/welcome.html`
|
|
28
|
+
Self-contained single HTML file (inline CSS + JS, Google Fonts link), so
|
|
29
|
+
it works opened directly from disk OR served. Sections:
|
|
30
|
+
- Hero: "Loki Mode by Autonomi" + tagline "Describe it. Walk away. Get
|
|
31
|
+
working, tested software." + version (templated at serve time or left
|
|
32
|
+
generic).
|
|
33
|
+
- Three subtle highlight cards: (a) RARV-C closure + unanimous council
|
|
34
|
+
("finishes the work, verified"), (b) Cross-project memory that compounds
|
|
35
|
+
("your agents stop repeating mistakes across projects"), (c) Research
|
|
36
|
+
backing (Anthropic Constitutional AI / DeepMind debate / OpenAI Agents
|
|
37
|
+
SDK / NVIDIA ToolOrchestra) shown as small footnote-style chips, not
|
|
38
|
+
loud claims.
|
|
39
|
+
- Opt-in form: role (select), company size (select), primary tools
|
|
40
|
+
(multi-select chips: Claude Code, Cursor, Codex, Copilot, Cline, Aider,
|
|
41
|
+
other). A single "Send + get started" button. Consent line directly
|
|
42
|
+
under it: "Sends anonymous usage analytics (your role, company size,
|
|
43
|
+
tools) to help us improve the product. We never collect your prompts,
|
|
44
|
+
PRDs, or code. Opt out anytime with LOKI_TELEMETRY_DISABLED=true."
|
|
45
|
+
- CTA row: "Read the docs" -> https://www.autonomi.dev/docs ; "Quick
|
|
46
|
+
start" copyable `loki start ./prd.md`.
|
|
47
|
+
- On submit: POST to us.i.posthog.com/capture/ with event
|
|
48
|
+
`welcome_profile`, distinct_id = the existing ~/.loki-telemetry-id (or a
|
|
49
|
+
fresh uuid in browser localStorage if not injected), properties =
|
|
50
|
+
{role, company_size, tools, source:'welcome_opener', loki_version}.
|
|
51
|
+
Then show a thank-you state + the docs link. Submission is the ONLY
|
|
52
|
+
network call; nothing is sent on page load.
|
|
53
|
+
- Respect opt-out: if the page is served with ?telemetry=off (the CLI
|
|
54
|
+
passes this when LOKI_TELEMETRY_DISABLED/DO_NOT_TRACK is set), the form
|
|
55
|
+
is replaced with a "analytics disabled" note and the submit is a no-op.
|
|
56
|
+
|
|
57
|
+
### 2. CLI command: `loki welcome`
|
|
58
|
+
- Mirrors cmd_dashboard_open idiom. Resolves the welcome.html path inside
|
|
59
|
+
the package, opens it with `open`/`xdg-open`. If no browser opener
|
|
60
|
+
(headless/Docker), prints the terminal fallback (see #4) + the file path
|
|
61
|
+
+ the autonomi.dev/docs URL.
|
|
62
|
+
- Passes ?telemetry=off when opt-out env is set.
|
|
63
|
+
- Dispatch: add `welcome) cmd_welcome "$@" ;;` near the `demo)` case
|
|
64
|
+
(~autonomy/loki:12505) and a help line.
|
|
65
|
+
|
|
66
|
+
### 3. First-run auto-open (once)
|
|
67
|
+
- Marker file: `~/.loki/.welcomed`. On first `loki start` (and at end of
|
|
68
|
+
postinstall when a browser is available + not CI + not opt-out), if the
|
|
69
|
+
marker is absent: open the welcome page once, then write the marker.
|
|
70
|
+
Never auto-open again. CI/non-TTY/Docker never auto-open a browser; they
|
|
71
|
+
only print the terminal welcome.
|
|
72
|
+
- postinstall.js already prints an install summary; append a one-line
|
|
73
|
+
"Run `loki welcome` for a quick tour" pointer (no auto browser launch in
|
|
74
|
+
postinstall to avoid surprising npm installs).
|
|
75
|
+
|
|
76
|
+
### 4. Terminal fallback
|
|
77
|
+
- A clean ASCII/ANSI welcome (loki accent color) printed when no browser:
|
|
78
|
+
product one-liner, the 3 highlights as one line each, the docs URL, the
|
|
79
|
+
quick-start command, and the consent/opt-out line. No network call from
|
|
80
|
+
the terminal fallback (the form is browser-only; terminal just informs).
|
|
81
|
+
|
|
82
|
+
## Files
|
|
83
|
+
- ADD `assets/welcome/welcome.html`
|
|
84
|
+
- ADD `assets/welcome/welcome.terminal.sh` (sourced helper that prints the
|
|
85
|
+
terminal welcome) OR inline in cmd_welcome.
|
|
86
|
+
- EDIT `autonomy/loki`: cmd_welcome + dispatch + help + first-run hook in
|
|
87
|
+
cmd_start.
|
|
88
|
+
- EDIT `bin/postinstall.js`: add the "Run `loki welcome`" pointer line.
|
|
89
|
+
- EDIT `package.json` "files": add `assets/`.
|
|
90
|
+
- EDIT `Dockerfile`, `Dockerfile.sandbox`: COPY assets/.
|
|
91
|
+
- ADD `tests/test-welcome-opener.sh`.
|
|
92
|
+
- Version bump 14 locations + CHANGELOG.
|
|
93
|
+
|
|
94
|
+
## Privacy test matrix (must pass)
|
|
95
|
+
- Page load makes ZERO network calls (only submit does).
|
|
96
|
+
- Submit payload contains ONLY {role, company_size, tools, source,
|
|
97
|
+
loki_version, distinct_id}; never any file/prompt/PRD content.
|
|
98
|
+
- LOKI_TELEMETRY_DISABLED=true and DO_NOT_TRACK=1 each => form disabled,
|
|
99
|
+
no capture.
|
|
100
|
+
- `loki welcome` works headless (terminal fallback, no browser error).
|
|
101
|
+
- First-run marker opens once and not again.
|
|
102
|
+
|
|
103
|
+
## Honesty
|
|
104
|
+
Highlights cite real, documented research (already in README Research
|
|
105
|
+
Foundation) and frame the memory moat as "retrieval/compounding," NOT a
|
|
106
|
+
claimed task-success number (consistent with prior honesty fixes).
|
|
@@ -107,7 +107,7 @@ Loki Mode covers:
|
|
|
107
107
|
|
|
108
108
|
**Auto-Claude:** Engineering only. No business/marketing agents.
|
|
109
109
|
|
|
110
|
-
**Verdict: Loki Mode wins** -
|
|
110
|
+
**Verdict: Loki Mode wins** - Full spec-to-product lifecycle vs coding only.
|
|
111
111
|
|
|
112
112
|
### 4. Anti-Sycophancy Measures
|
|
113
113
|
Loki Mode implements CONSENSAGENT (ACL 2025):
|
|
@@ -247,7 +247,7 @@ Loki Mode now incorporates proven patterns from Cursor's large-scale agent deplo
|
|
|
247
247
|
|
|
248
248
|
**Loki Mode is better if you want:**
|
|
249
249
|
- Research-backed architecture
|
|
250
|
-
- Full
|
|
250
|
+
- Full spec-to-product lifecycle (not just coding)
|
|
251
251
|
- 41 specialized agents
|
|
252
252
|
- Anti-sycophancy measures
|
|
253
253
|
- MIT license
|
|
@@ -261,7 +261,7 @@ Auto-Claude has better UX and community. Loki Mode has better architecture and c
|
|
|
261
261
|
Auto-Claude is a polished product. Loki Mode is a research-backed system.
|
|
262
262
|
|
|
263
263
|
For pure coding tasks with GUI preference: **Auto-Claude wins**.
|
|
264
|
-
For full autonomous
|
|
264
|
+
For full autonomous spec-to-product delivery with quality guarantees: **Loki Mode wins**.
|
|
265
265
|
|
|
266
266
|
---
|
|
267
267
|
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var v=(K,$)=>{for(var Q in $)_7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:P7.bind($,Q)})};var R=(K,$)=>()=>(K&&($=K(K=0)),$);var t=import.meta.require;var e1={};v(e1,{lokiDir:()=>P,homeLokiDir:()=>k1,findRepoRootForVersion:()=>N1,REPO_ROOT:()=>p});import{resolve as u,dirname as S1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let Q=S1(K);if(Q===K)break;K=Q}return u(i1,"..","..","..")}function N1(K){let $=K;for(let Q=0;Q<6;Q++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let X=S1($);if(X===$)break;$=X}return u(K,"..","..","..")}function P(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var g=R(()=>{i1=S1(L7(import.meta.url));p=E7()});import{readFileSync as F7}from"fs";import{resolve as w7,dirname as x7}from"path";import{fileURLToPath as S7}from"url";function G1(){if(o!==null)return o;let K="7.7.
|
|
2
|
+
var _7=Object.defineProperty;var I7=(K)=>K;function P7(K,$){this[K]=I7.bind(null,$)}var v=(K,$)=>{for(var Q in $)_7(K,Q,{get:$[Q],enumerable:!0,configurable:!0,set:P7.bind($,Q)})};var R=(K,$)=>()=>(K&&($=K(K=0)),$);var t=import.meta.require;var e1={};v(e1,{lokiDir:()=>P,homeLokiDir:()=>k1,findRepoRootForVersion:()=>N1,REPO_ROOT:()=>p});import{resolve as u,dirname as S1}from"path";import{fileURLToPath as L7}from"url";import{existsSync as J1}from"fs";import{homedir as R7}from"os";function E7(){let K=i1;for(let $=0;$<6;$++){if(J1(u(K,"VERSION"))&&J1(u(K,"autonomy/run.sh")))return K;let Q=S1(K);if(Q===K)break;K=Q}return u(i1,"..","..","..")}function N1(K){let $=K;for(let Q=0;Q<6;Q++){if(J1(u($,"VERSION"))&&J1(u($,"autonomy/run.sh")))return $;let X=S1($);if(X===$)break;$=X}return u(K,"..","..","..")}function P(){return process.env.LOKI_DIR??u(process.cwd(),".loki")}function k1(){return u(R7(),".loki")}var i1,p;var g=R(()=>{i1=S1(L7(import.meta.url));p=E7()});import{readFileSync as F7}from"fs";import{resolve as w7,dirname as x7}from"path";import{fileURLToPath as S7}from"url";function G1(){if(o!==null)return o;let K="7.7.27";if(typeof K==="string"&&K.length>0)return o=K,o;try{let $=x7(S7(import.meta.url)),Q=N1($);o=F7(w7(Q,"VERSION"),"utf-8").trim()}catch{o="unknown"}return o}var o=null;var D1=R(()=>{g()});var $0={};v($0,{runOrThrow:()=>N7,run:()=>k,commandVersion:()=>D7,commandExists:()=>h,ShellError:()=>C1});async function k(K,$={}){let Q=Bun.spawn({cmd:[...K],stdout:"pipe",stderr:"pipe",env:$.env?{...process.env,...$.env}:process.env,cwd:$.cwd}),X,Z;if($.timeoutMs&&$.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},$.timeoutMs);try{let[W,z,q]=await Promise.all([new Response(Q.stdout).text(),new Response(Q.stderr).text(),Q.exited]);return{stdout:W,stderr:z,exitCode:q}}finally{if(X)clearTimeout(X);if(Z)clearTimeout(Z)}}async function N7(K,$={}){let Q=await k(K,$);if(Q.exitCode!==0)throw new C1(`command failed (${Q.exitCode}): ${K.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function h(K){let $=k7(K),Q=await k(["sh","-c",`command -v ${$}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function k7(K){if(!/^[A-Za-z0-9._/-]+$/.test(K))throw Error(`refused to shell-escape suspect token: ${K}`);return K}async function D7(K,$="--version"){if(!await h(K))return null;let X=await k([K,$],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var C1;var n=R(()=>{C1=class C1 extends Error{message;exitCode;stdout;stderr;constructor(K,$,Q,X){super(K);this.message=K;this.exitCode=$;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function c(K){return C7?"":K}var C7,E,b,F,T6,O,D,w,H;var a=R(()=>{C7=(process.env.NO_COLOR??"").length>0;E=c("\x1B[0;31m"),b=c("\x1B[0;32m"),F=c("\x1B[1;33m"),T6=c("\x1B[0;34m"),O=c("\x1B[0;36m"),D=c("\x1B[1m"),w=c("\x1B[2m"),H=c("\x1B[0m")});import{existsSync as c7}from"fs";async function i(){if(X1!==void 0)return X1;let K="/opt/homebrew/bin/python3.12";if(c7(K))return X1=K,K;let $=await h("python3.12");if($)return X1=$,$;let Q=await h("python3");return X1=Q,Q}async function s(K,$={}){let Q=await i();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return k([Q,"-c",K],$)}var X1;var Z1=R(()=>{n()});var G0={};v(G0,{runStatus:()=>Q5});import{existsSync as N,readFileSync as W1,readdirSync as W0,statSync as H0}from"fs";import{resolve as x,basename as a7}from"path";async function r7(){if(await h("jq"))return!0;return process.stdout.write(`${E}Error: jq is required but not installed.${H}
|
|
3
3
|
`),process.stdout.write(`Install with:
|
|
4
4
|
`),process.stdout.write(` brew install jq (macOS)
|
|
5
5
|
`),process.stdout.write(` apt install jq (Debian/Ubuntu)
|
|
@@ -585,4 +585,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
585
585
|
`),2}default:return process.stderr.write(`Unknown command: ${$}
|
|
586
586
|
`),process.stderr.write(j7),2}}process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var X6=await Q6(Bun.argv.slice(2));process.exit(X6);
|
|
587
587
|
|
|
588
|
-
//# debugId=
|
|
588
|
+
//# debugId=007306826576BB8664756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.27",
|
|
4
4
|
"description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 11 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"files": [
|
|
65
65
|
"SKILL.md",
|
|
66
66
|
"VERSION",
|
|
67
|
+
"assets/",
|
|
67
68
|
"tools/",
|
|
68
69
|
"autonomy/",
|
|
69
70
|
"providers/",
|