@mneme-ai/xray 2.155.0 → 2.157.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/package.json +1 -1
- package/public/index.html +77 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mneme-ai/xray",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.157.0",
|
|
4
4
|
"description": "Mneme Repo X-Ray — a signed, raw-free, deterministic X-Ray of any repo. Every number is reproducible from git/AST/metadata and sealed with an offline-verifiable NOTARY receipt. No source code ever leaves the machine; no LLM guesses anything.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/public/index.html
CHANGED
|
@@ -21,17 +21,37 @@
|
|
|
21
21
|
-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
|
|
22
22
|
font-feature-settings:"cv11","ss01";letter-spacing:-0.011em}
|
|
23
23
|
::selection{background:var(--a-soft)}
|
|
24
|
-
.wrap{max-width:720px;margin:0 auto;padding:0 24px}
|
|
24
|
+
.wrap{max-width:720px;margin:0 auto;padding:0 24px;position:relative;z-index:1}
|
|
25
|
+
/* decorative comets — only on wide screens (desktop / iPad landscape) */
|
|
26
|
+
.comet{position:fixed;pointer-events:none;z-index:0;opacity:0;display:none}
|
|
27
|
+
.comet-a{top:9%;right:3.5vw}
|
|
28
|
+
.comet-b{bottom:7%;left:3vw}
|
|
29
|
+
@media (min-width:1180px){
|
|
30
|
+
.comet{display:block;animation:cometIn 1.2s ease .3s forwards}
|
|
31
|
+
.comet-a{animation:cometIn 1.2s ease .3s forwards, driftA 16s ease-in-out 1.5s infinite alternate}
|
|
32
|
+
.comet-b{animation:cometIn 1.2s ease .6s forwards, driftB 19s ease-in-out 2s infinite alternate}
|
|
33
|
+
}
|
|
34
|
+
@keyframes cometIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
|
|
35
|
+
@keyframes driftA{from{transform:translate(0,0) rotate(0deg)}to{transform:translate(-14px,18px) rotate(-3deg)}}
|
|
36
|
+
@keyframes driftB{from{transform:translate(0,0) rotate(0deg)}to{transform:translate(16px,-14px) rotate(3deg)}}
|
|
37
|
+
@media (prefers-reduced-motion:reduce){.comet{animation:none!important;opacity:1!important}}
|
|
25
38
|
/* hero */
|
|
26
39
|
header{padding:96px 0 40px;text-align:center}
|
|
27
40
|
.mark{font-size:12px;letter-spacing:.22em;text-transform:uppercase;color:var(--sub);font-weight:600}
|
|
28
41
|
h1{font-size:54px;line-height:1.04;font-weight:700;margin:18px 0 14px;letter-spacing:-.035em;color:var(--ink)}
|
|
29
42
|
.lede{color:var(--sub);font-size:19px;line-height:1.55;max-width:500px;margin:0 auto;font-weight:400}
|
|
30
43
|
form{display:flex;gap:10px;margin:38px auto 10px;max-width:600px}
|
|
31
|
-
input{flex:1;padding:0 18px;height:54px;border:
|
|
44
|
+
input{flex:1;padding:0 18px;height:54px;border:1.5px solid #d3d6dd;border-radius:var(--rs);
|
|
32
45
|
font-size:16px;color:var(--ink);outline:none;background:#fff;transition:border-color .18s, box-shadow .18s}
|
|
33
|
-
input::placeholder{color:#
|
|
46
|
+
input::placeholder{color:#aeb2ba}
|
|
34
47
|
input:focus{border-color:var(--a);box-shadow:0 0 0 4px var(--a-soft)}
|
|
48
|
+
.btnhelp{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 26px;margin:14px auto 0;max-width:640px;
|
|
49
|
+
color:var(--sub);font-size:13px;line-height:1.5}
|
|
50
|
+
.btnhelp b{color:var(--ink2);font-weight:600}
|
|
51
|
+
.keyhelp{font-size:12.5px;color:var(--sub);margin:12px 0 0;line-height:1.5;text-align:center}
|
|
52
|
+
.keymsg{margin:12px auto 0;max-width:520px;text-align:center;font-size:13px;line-height:1.55;color:#166534;
|
|
53
|
+
background:#f0fdf4;border:1px solid #dcfce7;border-radius:10px;padding:11px 14px}
|
|
54
|
+
.keymsg b{color:#14532d;font-weight:640}
|
|
35
55
|
button{height:54px;padding:0 24px;border:0;border-radius:var(--rs);background:var(--ink);color:#fff;
|
|
36
56
|
font-size:15.5px;font-weight:560;cursor:pointer;transition:transform .12s, opacity .18s, background .18s;white-space:nowrap}
|
|
37
57
|
button:hover{background:#22232c}
|
|
@@ -126,6 +146,8 @@
|
|
|
126
146
|
.pactions{display:flex;gap:10px;flex-wrap:wrap;padding:16px 30px;background:var(--soft);border-bottom:1px solid var(--line2)}
|
|
127
147
|
.pre{max-height:440px;overflow:auto;margin:0;padding:20px 30px;font-family:ui-monospace,Menlo,monospace;font-size:12px;line-height:1.55;white-space:pre-wrap;word-break:break-word;color:#4b5059}
|
|
128
148
|
.pwhy{padding:13px 30px;font-size:12.5px;color:var(--sub);background:var(--soft)}
|
|
149
|
+
.paste-hint{align-self:center;font-size:12.5px;color:var(--sub)}
|
|
150
|
+
.paste-hint b{color:var(--ink2);font-weight:560}
|
|
129
151
|
/* local bridge panel */
|
|
130
152
|
.localbox{max-width:560px;margin:22px auto 0;border:1px solid var(--line);border-radius:var(--rs);padding:18px 20px;background:var(--soft);display:none;text-align:left}
|
|
131
153
|
.localbox.on{display:block}
|
|
@@ -174,6 +196,23 @@
|
|
|
174
196
|
</style>
|
|
175
197
|
</head>
|
|
176
198
|
<body>
|
|
199
|
+
<!-- decorative comets — desktop / iPad only, hidden on narrow screens -->
|
|
200
|
+
<div class="comet comet-a" aria-hidden="true">
|
|
201
|
+
<svg viewBox="0 0 300 300" width="300" height="300"><defs>
|
|
202
|
+
<linearGradient id="ta" x1="1" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#0b0b0f" stop-opacity=".62"/><stop offset="1" stop-color="#0b0b0f" stop-opacity="0"/></linearGradient></defs>
|
|
203
|
+
<path d="M262 44 Q150 118 30 252 Q150 132 252 54 Z" fill="url(#ta)"/>
|
|
204
|
+
<circle cx="262" cy="44" r="15" fill="#0b0b0f" opacity=".12"/>
|
|
205
|
+
<circle cx="262" cy="44" r="7.5" fill="#0b0b0f"/>
|
|
206
|
+
</svg>
|
|
207
|
+
</div>
|
|
208
|
+
<div class="comet comet-b" aria-hidden="true">
|
|
209
|
+
<svg viewBox="0 0 300 300" width="220" height="220"><defs>
|
|
210
|
+
<linearGradient id="tb" x1="0" y1="1" x2="1" y2="0"><stop offset="0" stop-color="#0b0b0f" stop-opacity=".5"/><stop offset="1" stop-color="#0b0b0f" stop-opacity="0"/></linearGradient></defs>
|
|
211
|
+
<path d="M38 256 Q150 182 270 48 Q150 168 48 246 Z" fill="url(#tb)"/>
|
|
212
|
+
<circle cx="38" cy="256" r="12" fill="#0b0b0f" opacity=".12"/>
|
|
213
|
+
<circle cx="38" cy="256" r="6" fill="#0b0b0f"/>
|
|
214
|
+
</svg>
|
|
215
|
+
</div>
|
|
177
216
|
<div class="wrap">
|
|
178
217
|
<header>
|
|
179
218
|
<div class="mark">Mneme · Repo X-Ray</div>
|
|
@@ -181,22 +220,23 @@
|
|
|
181
220
|
<p class="lede">Paste a public repo. Get a signed, reproducible X-Ray — dependencies, secrets, bus factor, vitality, complexity. No source leaves the machine. No AI guesses anything.</p>
|
|
182
221
|
<form id="f">
|
|
183
222
|
<input id="u" placeholder="https://github.com/owner/repo" autocomplete="off" spellcheck="false" />
|
|
184
|
-
<button id="go" type="submit">X-Ray</button>
|
|
185
|
-
<button id="packgo" type="button" class="ghostbtn" title="
|
|
223
|
+
<button id="go" type="submit" title="Health report: dependencies, secrets, risk, who-to-ask">X-Ray</button>
|
|
224
|
+
<button id="packgo" type="button" class="ghostbtn" title="Bundle the whole repo into one AI-ready text you paste into any AI chat">📦 AI Pack</button>
|
|
186
225
|
</form>
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
<span><b
|
|
190
|
-
<span><b>2</b> Get a signed grade in seconds</span>
|
|
191
|
-
<span><b>3</b> Private repo? run <code>npx mneme-xray ./path --publish</code> — source never leaves your machine</span>
|
|
226
|
+
<div class="btnhelp">
|
|
227
|
+
<span><b>X-Ray</b> — instant health report: dependencies, secrets, risk & who-to-ask.</span>
|
|
228
|
+
<span><b>📦 AI Pack</b> — bundle the whole repo into one text to paste into any AI chat.</span>
|
|
192
229
|
</div>
|
|
230
|
+
<p class="hint">Every number is <b>reproducible</b> from git, code & package metadata and sealed with an <b>offline-verifiable</b> signature. <span class="muted">Private folder? run <code>npx @mneme-ai/xray bridge</code> and Browse below.</span></p>
|
|
193
231
|
<details class="keybox">
|
|
194
|
-
<summary
|
|
232
|
+
<summary>🔖 Optional — save your reports</summary>
|
|
233
|
+
<div class="keyhelp">A “key” is simply a password you make up (no sign-up). Use the same one any time to find your reports under <b>My repos</b>.</div>
|
|
195
234
|
<div class="keyrow">
|
|
196
|
-
<input id="key" placeholder="
|
|
235
|
+
<input id="key" placeholder="make up a password — e.g. my-secret-123" autocomplete="off" />
|
|
197
236
|
<button id="savekey" type="button">Save</button>
|
|
198
237
|
<span id="keystate" class="kstate"></span>
|
|
199
238
|
</div>
|
|
239
|
+
<div id="keymsg" class="keymsg" style="display:none"></div>
|
|
200
240
|
</details>
|
|
201
241
|
<div class="localbox" id="localbox">
|
|
202
242
|
<div class="lh"><span class="localdot"></span>Local agent detected — scan a folder on <b>this machine</b> (source never leaves it)</div>
|
|
@@ -220,7 +260,7 @@
|
|
|
220
260
|
<div id="board"></div>
|
|
221
261
|
</div>
|
|
222
262
|
</div>
|
|
223
|
-
<footer>Mneme — the trust & cost layer for code. Deterministic
|
|
263
|
+
<footer>Mneme — the trust & cost layer for code. Deterministic · Signed · Local-first.<br/><span id="copyr">© Mneme</span></footer>
|
|
224
264
|
|
|
225
265
|
<script src="/card.js"></script>
|
|
226
266
|
<script>
|
|
@@ -244,11 +284,13 @@ function mountShare(r){
|
|
|
244
284
|
}
|
|
245
285
|
const badge = `${origin}/badge/${badgeTarget}.svg`;
|
|
246
286
|
const md = `[](${link})`;
|
|
287
|
+
const ogimg = `${origin}/og/${r.fingerprint}.png`;
|
|
247
288
|
el.innerHTML = `
|
|
248
289
|
<img class="badgeimg" src="${badge}" alt="X-Ray badge"/>
|
|
249
|
-
<button class="sbtn" data-copy="${esc(md)}">Copy badge
|
|
250
|
-
<button class="sbtn ghost" data-copy="${esc(link)}">Copy
|
|
251
|
-
<a class="sbtn ghost" href="${link}" target="_blank" rel="noopener">Open ↗</a
|
|
290
|
+
<button class="sbtn" data-copy="${esc(md)}">Copy badge for README</button>
|
|
291
|
+
<button class="sbtn ghost" data-copy="${esc(link)}">Copy share link</button>
|
|
292
|
+
<a class="sbtn ghost" href="${link}" target="_blank" rel="noopener">Open ↗</a>
|
|
293
|
+
<a class="sbtn ghost" href="${ogimg}" target="_blank" rel="noopener" title="The preview image shown when you share the link on X/Slack/LinkedIn">🖼 Preview image</a>`;
|
|
252
294
|
el.querySelectorAll("[data-copy]").forEach(b=>b.addEventListener("click",async()=>{
|
|
253
295
|
try{ await navigator.clipboard.writeText(b.dataset.copy); const t=b.textContent; b.textContent="Copied ✓"; setTimeout(()=>b.textContent=t,1200);}catch{}
|
|
254
296
|
}));
|
|
@@ -263,13 +305,23 @@ async function profileId(token){
|
|
|
263
305
|
function refreshKeyState(){
|
|
264
306
|
const k=getKey(), st=document.getElementById("keystate"), tab=document.getElementById("tabMine");
|
|
265
307
|
document.getElementById("key").value = k;
|
|
266
|
-
st.textContent = k ? "
|
|
308
|
+
st.textContent = k ? "saved ✓" : "";
|
|
267
309
|
tab.style.display = k ? "inline-block" : "none";
|
|
268
310
|
}
|
|
269
311
|
document.getElementById("savekey").addEventListener("click", ()=>{
|
|
270
312
|
const k=document.getElementById("key").value.trim();
|
|
271
|
-
|
|
272
|
-
|
|
313
|
+
const msg=document.getElementById("keymsg");
|
|
314
|
+
if(k){
|
|
315
|
+
localStorage.setItem("xrayKey",k);
|
|
316
|
+
refreshKeyState();
|
|
317
|
+
msg.innerHTML='✓ Saved. From now on, every <b>X-Ray</b> or <b>AI Pack</b> you run is kept under <b>My repos</b> — open it any time with this same key.';
|
|
318
|
+
msg.style.display="block";
|
|
319
|
+
tab="mine"; setTab(document.getElementById("tabMine")); loadList();
|
|
320
|
+
} else {
|
|
321
|
+
localStorage.removeItem("xrayKey"); refreshKeyState();
|
|
322
|
+
msg.innerHTML='Signed out. Reports are no longer saved.'; msg.style.display="block";
|
|
323
|
+
tab="board"; setTab(document.getElementById("tabBoard")); loadList();
|
|
324
|
+
}
|
|
273
325
|
});
|
|
274
326
|
|
|
275
327
|
let tab="board", offset=0, loaded=[];
|
|
@@ -364,7 +416,7 @@ document.getElementById("localgo").addEventListener("click", async ()=>{
|
|
|
364
416
|
}catch(ex){ err.textContent="Could not reach the local agent. Run: npx @mneme-ai/xray bridge"; err.style.display="block"; }
|
|
365
417
|
finally{ btn.disabled=false; btn.textContent="Scan local"; }
|
|
366
418
|
});
|
|
367
|
-
// ---- AI CONTEXT PACK (
|
|
419
|
+
// ---- AI CONTEXT PACK (prioritized · budgeted · secret-redacted · fits any model) ----
|
|
368
420
|
function renderPack(p){
|
|
369
421
|
const md = p.markdown || "";
|
|
370
422
|
document.getElementById("packout").innerHTML = `
|
|
@@ -378,13 +430,14 @@ function renderPack(p){
|
|
|
378
430
|
</div>
|
|
379
431
|
</div>
|
|
380
432
|
<div class="pactions">
|
|
381
|
-
<button class="sbtn" id="pcopy"
|
|
433
|
+
<button class="sbtn" id="pcopy">📋 Copy for your AI</button>
|
|
382
434
|
<button class="sbtn ghost" id="pdl">Download .md</button>
|
|
435
|
+
<span class="paste-hint">→ paste into <b>any</b> AI chat (ChatGPT · Claude · Grok · Gemini · Copilot…) so it understands your whole codebase</span>
|
|
383
436
|
</div>
|
|
384
|
-
<div class="pwhy">
|
|
437
|
+
<div class="pwhy">Smarter than a raw repo dump: prioritized by real signals, secret-redacted, and budgeted so it actually fits the model — not millions of unusable tokens.</div>
|
|
385
438
|
<pre class="pre">${esc(md.slice(0,20000))}${md.length>20000?"\n\n… (truncated preview — Copy/Download for the full pack)":""}</pre>
|
|
386
439
|
</div>`;
|
|
387
|
-
document.getElementById("pcopy").addEventListener("click",async e=>{try{await navigator.clipboard.writeText(md);e.target.textContent="Copied ✓";setTimeout(()=>e.target.textContent="Copy for
|
|
440
|
+
document.getElementById("pcopy").addEventListener("click",async e=>{try{await navigator.clipboard.writeText(md);e.target.textContent="Copied ✓ — paste into any AI";setTimeout(()=>e.target.textContent="📋 Copy for your AI",1600);}catch{}});
|
|
388
441
|
document.getElementById("pdl").addEventListener("click",()=>{const b=new Blob([md],{type:"text/markdown"});const a=document.createElement("a");a.href=URL.createObjectURL(b);a.download=(p.repoName||"repo").replace(/\W+/g,"-")+"-context-pack.md";a.click();});
|
|
389
442
|
}
|
|
390
443
|
document.getElementById("packgo").addEventListener("click", async ()=>{
|
|
@@ -435,6 +488,7 @@ document.getElementById("localpack").addEventListener("click", async ()=>{
|
|
|
435
488
|
}catch(ex){ err.textContent="Could not reach the local agent. Run: npx @mneme-ai/xray bridge"; err.style.display="block"; }
|
|
436
489
|
finally{ btn.disabled=false; btn.textContent="📦 Pack"; }
|
|
437
490
|
});
|
|
491
|
+
document.getElementById("copyr").textContent = "© " + new Date().getFullYear() + " Mneme · MIT";
|
|
438
492
|
detectBridge();
|
|
439
493
|
refreshKeyState();
|
|
440
494
|
loadList();
|