@mneme-ai/xray 2.154.0 → 2.156.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/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +26 -1
- package/dist/bridge.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +63 -21
package/dist/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AA+CA,wBAAgB,SAAS,CAAC,IAAI,SAAO,GAAG,IAAI,CAsE3C"}
|
package/dist/bridge.js
CHANGED
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* POST /bridge/xray { path } → build local X-Ray → raw-free gate → sign → return
|
|
14
14
|
*/
|
|
15
15
|
import { createServer } from "node:http";
|
|
16
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
16
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
17
17
|
import { dirname, join } from "node:path";
|
|
18
|
+
import { homedir } from "node:os";
|
|
18
19
|
import { fileURLToPath } from "node:url";
|
|
19
20
|
import { buildXRay } from "./engine.js";
|
|
20
21
|
import { sealXRay } from "./sign.js";
|
|
@@ -57,6 +58,30 @@ export function runBridge(port = 7799) {
|
|
|
57
58
|
if (req.method === "GET" && url.pathname === "/bridge/ping") {
|
|
58
59
|
return json(res, 200, { ok: true, agent: "mneme-xray-bridge", version: version() });
|
|
59
60
|
}
|
|
61
|
+
// folder browser — list sub-directories so the website can pick a LOCAL
|
|
62
|
+
// folder by clicking (no path typing). Works for non-git folders too.
|
|
63
|
+
if (req.method === "GET" && url.pathname === "/bridge/ls") {
|
|
64
|
+
try {
|
|
65
|
+
const reqd = url.searchParams.get("path");
|
|
66
|
+
const here = reqd && existsSync(reqd) && statSync(reqd).isDirectory() ? reqd : homedir();
|
|
67
|
+
const entries = readdirSync(here, { withFileTypes: true })
|
|
68
|
+
.filter((e) => { try {
|
|
69
|
+
return e.isDirectory() && !e.name.startsWith(".");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
} })
|
|
74
|
+
.map((e) => join(here, e.name))
|
|
75
|
+
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
76
|
+
.slice(0, 500)
|
|
77
|
+
.map((p) => ({ name: p.slice(here.length).replace(/^[\\/]/, ""), path: p, isRepo: existsSync(join(p, ".git")) || existsSync(join(p, "package.json")) }));
|
|
78
|
+
const parent = dirname(here);
|
|
79
|
+
return json(res, 200, { path: here, parent: parent !== here ? parent : null, isRepo: existsSync(join(here, ".git")) || existsSync(join(here, "package.json")), dirs: entries });
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
return json(res, 400, { error: e.message });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
60
85
|
if (req.method === "POST" && url.pathname === "/bridge/xray") {
|
|
61
86
|
let body = "";
|
|
62
87
|
req.on("data", (c) => (body += c));
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,YAAY,EAAuB,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mneme-ai/xray",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.156.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
|
@@ -28,10 +28,14 @@
|
|
|
28
28
|
h1{font-size:54px;line-height:1.04;font-weight:700;margin:18px 0 14px;letter-spacing:-.035em;color:var(--ink)}
|
|
29
29
|
.lede{color:var(--sub);font-size:19px;line-height:1.55;max-width:500px;margin:0 auto;font-weight:400}
|
|
30
30
|
form{display:flex;gap:10px;margin:38px auto 10px;max-width:600px}
|
|
31
|
-
input{flex:1;padding:0 18px;height:54px;border:
|
|
31
|
+
input{flex:1;padding:0 18px;height:54px;border:1.5px solid #d3d6dd;border-radius:var(--rs);
|
|
32
32
|
font-size:16px;color:var(--ink);outline:none;background:#fff;transition:border-color .18s, box-shadow .18s}
|
|
33
|
-
input::placeholder{color:#
|
|
33
|
+
input::placeholder{color:#aeb2ba}
|
|
34
34
|
input:focus{border-color:var(--a);box-shadow:0 0 0 4px var(--a-soft)}
|
|
35
|
+
.btnhelp{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 26px;margin:14px auto 0;max-width:640px;
|
|
36
|
+
color:var(--sub);font-size:13px;line-height:1.5}
|
|
37
|
+
.btnhelp b{color:var(--ink2);font-weight:600}
|
|
38
|
+
.keyhelp{font-size:12.5px;color:var(--sub);margin:12px 0 0;line-height:1.5;text-align:center}
|
|
35
39
|
button{height:54px;padding:0 24px;border:0;border-radius:var(--rs);background:var(--ink);color:#fff;
|
|
36
40
|
font-size:15.5px;font-weight:560;cursor:pointer;transition:transform .12s, opacity .18s, background .18s;white-space:nowrap}
|
|
37
41
|
button:hover{background:#22232c}
|
|
@@ -126,6 +130,8 @@
|
|
|
126
130
|
.pactions{display:flex;gap:10px;flex-wrap:wrap;padding:16px 30px;background:var(--soft);border-bottom:1px solid var(--line2)}
|
|
127
131
|
.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
132
|
.pwhy{padding:13px 30px;font-size:12.5px;color:var(--sub);background:var(--soft)}
|
|
133
|
+
.paste-hint{align-self:center;font-size:12.5px;color:var(--sub)}
|
|
134
|
+
.paste-hint b{color:var(--ink2);font-weight:560}
|
|
129
135
|
/* local bridge panel */
|
|
130
136
|
.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
137
|
.localbox.on{display:block}
|
|
@@ -135,6 +141,16 @@
|
|
|
135
141
|
.localrow input{flex:1;height:44px;padding:0 14px;border:1px solid var(--line);border-radius:10px;font-size:13.5px;font-family:ui-monospace,Menlo,monospace}
|
|
136
142
|
.localrow button{height:44px;padding:0 16px;border:0;border-radius:10px;background:var(--ink);color:#fff;cursor:pointer;font-size:13.5px}
|
|
137
143
|
.localhint{font-size:12px;color:var(--sub);margin-top:9px}
|
|
144
|
+
.picker{display:none;margin-top:12px;border:1px solid var(--line);border-radius:10px;background:#fff;overflow:hidden}
|
|
145
|
+
.picker.on{display:block}
|
|
146
|
+
.pkbar{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--line2);font-size:12.5px}
|
|
147
|
+
.pkbar .cur{flex:1;min-width:0;font-family:ui-monospace,Menlo,monospace;color:var(--ink2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;text-align:left}
|
|
148
|
+
.pkbar .pick{height:32px;padding:0 12px;border:0;border-radius:8px;background:var(--green);color:#fff;font-size:12.5px;cursor:pointer;width:auto}
|
|
149
|
+
.pklist{max-height:230px;overflow:auto}
|
|
150
|
+
.pkrow{display:flex;align-items:center;gap:9px;padding:9px 12px;border-bottom:1px solid var(--line2);cursor:pointer;font-size:13.5px}
|
|
151
|
+
.pkrow:last-child{border-bottom:0}.pkrow:hover{background:var(--soft)}
|
|
152
|
+
.pkrow .ic{width:18px;text-align:center}
|
|
153
|
+
.pkrow .repobadge{margin-left:auto;font-size:10.5px;color:var(--a);background:var(--a-soft);border-radius:6px;padding:2px 7px;font-weight:600}
|
|
138
154
|
footer{padding:40px 0 70px;text-align:center;color:#aab0b8;font-size:13px}
|
|
139
155
|
.spin{display:inline-block;width:15px;height:15px;border:2px solid currentColor;border-top-color:transparent;
|
|
140
156
|
border-radius:50%;animation:s .7s linear infinite;vertical-align:-2px;margin-right:7px;opacity:.9}
|
|
@@ -171,19 +187,19 @@
|
|
|
171
187
|
<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>
|
|
172
188
|
<form id="f">
|
|
173
189
|
<input id="u" placeholder="https://github.com/owner/repo" autocomplete="off" spellcheck="false" />
|
|
174
|
-
<button id="go" type="submit">X-Ray</button>
|
|
175
|
-
<button id="packgo" type="button" class="ghostbtn" title="
|
|
190
|
+
<button id="go" type="submit" title="Health report: dependencies, secrets, risk, who-to-ask">X-Ray</button>
|
|
191
|
+
<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>
|
|
176
192
|
</form>
|
|
177
|
-
<
|
|
178
|
-
|
|
179
|
-
<span><b
|
|
180
|
-
<span><b>2</b> Get a signed grade in seconds</span>
|
|
181
|
-
<span><b>3</b> Private repo? run <code>npx mneme-xray ./path --publish</code> — source never leaves your machine</span>
|
|
193
|
+
<div class="btnhelp">
|
|
194
|
+
<span><b>X-Ray</b> — instant health report: dependencies, secrets, risk & who-to-ask.</span>
|
|
195
|
+
<span><b>📦 AI Pack</b> — bundle the whole repo into one text to paste into any AI chat.</span>
|
|
182
196
|
</div>
|
|
197
|
+
<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>
|
|
183
198
|
<details class="keybox">
|
|
184
|
-
<summary
|
|
199
|
+
<summary>🔖 Optional — save your reports</summary>
|
|
200
|
+
<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>
|
|
185
201
|
<div class="keyrow">
|
|
186
|
-
<input id="key" placeholder="
|
|
202
|
+
<input id="key" placeholder="make up a password — e.g. my-secret-123" autocomplete="off" />
|
|
187
203
|
<button id="savekey" type="button">Save</button>
|
|
188
204
|
<span id="keystate" class="kstate"></span>
|
|
189
205
|
</div>
|
|
@@ -192,10 +208,12 @@
|
|
|
192
208
|
<div class="lh"><span class="localdot"></span>Local agent detected — scan a folder on <b>this machine</b> (source never leaves it)</div>
|
|
193
209
|
<div class="localrow">
|
|
194
210
|
<input id="localpath" placeholder="/absolute/path/to/your/repo (git or not)" autocomplete="off" spellcheck="false" />
|
|
195
|
-
<button id="
|
|
211
|
+
<button id="localbrowse" type="button" class="ghostbtn">📂 Browse</button>
|
|
212
|
+
<button id="localgo" type="button">Scan</button>
|
|
196
213
|
<button id="localpack" type="button" class="ghostbtn">📦 Pack</button>
|
|
197
214
|
</div>
|
|
198
|
-
<div class="
|
|
215
|
+
<div class="picker" id="picker"></div>
|
|
216
|
+
<div class="localhint">Not on git? No problem — Browse to any folder. It reads locally and shows the signed result here; nothing is uploaded.</div>
|
|
199
217
|
</div>
|
|
200
218
|
<p class="err" id="err" style="display:none"></p>
|
|
201
219
|
</header>
|
|
@@ -208,7 +226,7 @@
|
|
|
208
226
|
<div id="board"></div>
|
|
209
227
|
</div>
|
|
210
228
|
</div>
|
|
211
|
-
<footer>Mneme — the trust & cost layer for code. Deterministic
|
|
229
|
+
<footer>Mneme — the trust & cost layer for code. Deterministic · Signed · Local-first.<br/><span id="copyr">© Mneme</span></footer>
|
|
212
230
|
|
|
213
231
|
<script src="/card.js"></script>
|
|
214
232
|
<script>
|
|
@@ -232,11 +250,13 @@ function mountShare(r){
|
|
|
232
250
|
}
|
|
233
251
|
const badge = `${origin}/badge/${badgeTarget}.svg`;
|
|
234
252
|
const md = `[](${link})`;
|
|
253
|
+
const ogimg = `${origin}/og/${r.fingerprint}.png`;
|
|
235
254
|
el.innerHTML = `
|
|
236
255
|
<img class="badgeimg" src="${badge}" alt="X-Ray badge"/>
|
|
237
|
-
<button class="sbtn" data-copy="${esc(md)}">Copy badge
|
|
238
|
-
<button class="sbtn ghost" data-copy="${esc(link)}">Copy
|
|
239
|
-
<a class="sbtn ghost" href="${link}" target="_blank" rel="noopener">Open ↗</a
|
|
256
|
+
<button class="sbtn" data-copy="${esc(md)}">Copy badge for README</button>
|
|
257
|
+
<button class="sbtn ghost" data-copy="${esc(link)}">Copy share link</button>
|
|
258
|
+
<a class="sbtn ghost" href="${link}" target="_blank" rel="noopener">Open ↗</a>
|
|
259
|
+
<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>`;
|
|
240
260
|
el.querySelectorAll("[data-copy]").forEach(b=>b.addEventListener("click",async()=>{
|
|
241
261
|
try{ await navigator.clipboard.writeText(b.dataset.copy); const t=b.textContent; b.textContent="Copied ✓"; setTimeout(()=>b.textContent=t,1200);}catch{}
|
|
242
262
|
}));
|
|
@@ -352,7 +372,7 @@ document.getElementById("localgo").addEventListener("click", async ()=>{
|
|
|
352
372
|
}catch(ex){ err.textContent="Could not reach the local agent. Run: npx @mneme-ai/xray bridge"; err.style.display="block"; }
|
|
353
373
|
finally{ btn.disabled=false; btn.textContent="Scan local"; }
|
|
354
374
|
});
|
|
355
|
-
// ---- AI CONTEXT PACK (
|
|
375
|
+
// ---- AI CONTEXT PACK (prioritized · budgeted · secret-redacted · fits any model) ----
|
|
356
376
|
function renderPack(p){
|
|
357
377
|
const md = p.markdown || "";
|
|
358
378
|
document.getElementById("packout").innerHTML = `
|
|
@@ -366,13 +386,14 @@ function renderPack(p){
|
|
|
366
386
|
</div>
|
|
367
387
|
</div>
|
|
368
388
|
<div class="pactions">
|
|
369
|
-
<button class="sbtn" id="pcopy"
|
|
389
|
+
<button class="sbtn" id="pcopy">📋 Copy for your AI</button>
|
|
370
390
|
<button class="sbtn ghost" id="pdl">Download .md</button>
|
|
391
|
+
<span class="paste-hint">→ paste into <b>any</b> AI chat (ChatGPT · Claude · Grok · Gemini · Copilot…) so it understands your whole codebase</span>
|
|
371
392
|
</div>
|
|
372
|
-
<div class="pwhy">
|
|
393
|
+
<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>
|
|
373
394
|
<pre class="pre">${esc(md.slice(0,20000))}${md.length>20000?"\n\n… (truncated preview — Copy/Download for the full pack)":""}</pre>
|
|
374
395
|
</div>`;
|
|
375
|
-
document.getElementById("pcopy").addEventListener("click",async e=>{try{await navigator.clipboard.writeText(md);e.target.textContent="Copied ✓";setTimeout(()=>e.target.textContent="Copy for
|
|
396
|
+
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{}});
|
|
376
397
|
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();});
|
|
377
398
|
}
|
|
378
399
|
document.getElementById("packgo").addEventListener("click", async ()=>{
|
|
@@ -389,6 +410,26 @@ document.getElementById("packgo").addEventListener("click", async ()=>{
|
|
|
389
410
|
}catch(ex){ err.textContent=String(ex); err.style.display="block"; }
|
|
390
411
|
finally{ btn.disabled=false; btn.textContent="📦 AI Pack"; }
|
|
391
412
|
});
|
|
413
|
+
// ---- folder browser (pick a LOCAL folder by clicking, even non-git) ----
|
|
414
|
+
let pickerOpen=false;
|
|
415
|
+
async function browseTo(path){
|
|
416
|
+
const pk=document.getElementById("picker");
|
|
417
|
+
try{
|
|
418
|
+
const q = path?("?path="+encodeURIComponent(path)):"";
|
|
419
|
+
const d = await (await fetch(BRIDGE+"/bridge/ls"+q)).json();
|
|
420
|
+
if(d.error){ pk.innerHTML=`<div class="pkrow muted">${esc(d.error)}</div>`; return; }
|
|
421
|
+
const up = d.parent?`<div class="pkrow" data-go="${esc(d.parent)}"><span class="ic">⬆️</span><span>.. up</span></div>`:"";
|
|
422
|
+
const rows = (d.dirs||[]).map(x=>`<div class="pkrow" data-go="${esc(x.path)}"><span class="ic">📁</span><span class="nm" style="flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${esc(x.name)}</span>${x.isRepo?'<span class="repobadge">project</span>':""}</div>`).join("");
|
|
423
|
+
pk.innerHTML=`<div class="pkbar"><span class="cur" title="${esc(d.path)}">${esc(d.path)}</span><button type="button" class="pick" data-pick="${esc(d.path)}">Use this folder</button></div><div class="pklist">${up}${rows||'<div class="pkrow muted">(no sub-folders)</div>'}</div>`;
|
|
424
|
+
pk.querySelectorAll("[data-go]").forEach(n=>n.addEventListener("click",()=>browseTo(n.dataset.go)));
|
|
425
|
+
pk.querySelector("[data-pick]").addEventListener("click",e=>{ document.getElementById("localpath").value=e.target.dataset.pick; pk.classList.remove("on"); pickerOpen=false; });
|
|
426
|
+
}catch{ pk.innerHTML='<div class="pkrow muted">Could not list folders — is the agent running? npx @mneme-ai/xray bridge</div>'; }
|
|
427
|
+
}
|
|
428
|
+
document.getElementById("localbrowse").addEventListener("click",()=>{
|
|
429
|
+
const pk=document.getElementById("picker");
|
|
430
|
+
pickerOpen=!pickerOpen; pk.classList.toggle("on",pickerOpen);
|
|
431
|
+
if(pickerOpen) browseTo(document.getElementById("localpath").value.trim()||"");
|
|
432
|
+
});
|
|
392
433
|
document.getElementById("localpack").addEventListener("click", async ()=>{
|
|
393
434
|
const p=document.getElementById("localpath").value.trim();
|
|
394
435
|
const err=document.getElementById("err"), btn=document.getElementById("localpack");
|
|
@@ -403,6 +444,7 @@ document.getElementById("localpack").addEventListener("click", async ()=>{
|
|
|
403
444
|
}catch(ex){ err.textContent="Could not reach the local agent. Run: npx @mneme-ai/xray bridge"; err.style.display="block"; }
|
|
404
445
|
finally{ btn.disabled=false; btn.textContent="📦 Pack"; }
|
|
405
446
|
});
|
|
447
|
+
document.getElementById("copyr").textContent = "© " + new Date().getFullYear() + " Mneme · MIT";
|
|
406
448
|
detectBridge();
|
|
407
449
|
refreshKeyState();
|
|
408
450
|
loadList();
|