@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.
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AA8CA,wBAAgB,SAAS,CAAC,IAAI,SAAO,GAAG,IAAI,CAoD3C"}
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));
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
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.154.0",
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:1px solid var(--line);border-radius:var(--rs);
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:#b7bbc2}
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="Build a prioritized, secret-redacted, token-budgeted context pack to paste into ChatGPT/Claude">📦 AI Pack</button>
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
- <p class="hint">Every number is <b>reproducible</b> from git / AST / npm metadata and sealed with an <b>offline-verifiable</b> signature.</p>
178
- <div class="steps">
179
- <span><b>1</b> Paste a public repo URL</span>
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 &amp; 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 &amp; 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>Have an X-Ray key? Sign in to keep your reports</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="your key (any secret string you choose)" autocomplete="off" />
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="localgo" type="button">Scan local</button>
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="localhint">Private code? This reads it locally and shows the signed result here — nothing is uploaded.</div>
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 &amp; cost layer for code. Deterministic. Signed. Local-first.</footer>
229
+ <footer>Mneme — the trust &amp; 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 = `[![Mneme X-Ray](${badge})](${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 markdown</button>
238
- <button class="sbtn ghost" data-copy="${esc(link)}">Copy permalink</button>
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 (beats gitingest: prioritized · budgeted · secret-redacted) ----
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">Copy for ChatGPT / Claude</button>
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">Unlike a raw dump (gitingest): prioritized by real signals, secret-redacted, and budgeted so it actually fits the model — not millions of unusable tokens.</div>
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 ChatGPT / Claude",1400);}catch{}});
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();