@enigmax/dashboard 0.1.107 → 0.1.108

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.
Files changed (2) hide show
  1. package/assets/index.html +37 -1
  2. package/package.json +1 -1
package/assets/index.html CHANGED
@@ -1339,7 +1339,7 @@
1339
1339
  <div class="page-head" style="display:flex;align-items:flex-start;gap:16px">
1340
1340
  <div style="flex:1">
1341
1341
  <h1>Code graph</h1>
1342
- <p>Structural memory of your codebase - a native knowledge graph of the symbols each file defines, the modules it imports and cross-file references. Enabling it exposes enigma's code-graph tools to your agents over MCP. Complements <a href="#/recall">Recall</a> (session memory).</p>
1342
+ <p>Structural memory of your codebase - a native knowledge graph of the symbols each file defines, what imports what, and which symbol calls which. Your agents query it over MCP to find code, trace a change's blast radius and read a file's API surface without opening it. Complements <a href="#/recall">Recall</a> (session memory).</p>
1343
1343
  </div>
1344
1344
  <button id="cgToggle" type="button" class="toggle" data-kind="bool" role="switch" aria-checked="false" aria-label="Code graph">Off</button>
1345
1345
  <button id="cgRefresh" type="button" class="iconbtn" title="Refresh" aria-label="Refresh"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M23 4v6h-6"/><path d="M1 20v-6h6"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg></button>
@@ -1350,6 +1350,12 @@
1350
1350
  <div class="set-hint" style="padding:4px 0">Build the graph for a codebase. Leave the path empty to index enigma's own working directory.</div>
1351
1351
  <div class="ladd" style="gap:8px;flex-wrap:wrap"><input id="cgRoot" class="linput" placeholder="absolute project path (optional)" style="flex:1;min-width:240px"><button id="cgIndex" type="button" class="toggle on">Index</button></div>
1352
1352
  </div>
1353
+ <div class="panel">
1354
+ <div class="set-cat-h">Ask the graph</div>
1355
+ <div class="set-hint" style="padding:4px 0">Describe a task and get the symbols and files it concerns, ranked, with exact line numbers. The same answer your agents get from the MCP tools.</div>
1356
+ <div class="ladd" style="gap:8px;flex-wrap:wrap"><input id="cgQuery" class="linput" placeholder="where is the session token refreshed?" style="flex:1;min-width:240px"><button id="cgAsk" type="button" class="toggle on">Ask</button></div>
1357
+ <div id="cgAskOut"></div>
1358
+ </div>
1353
1359
  <div id="cgBody"><div class="empty" style="padding:12px 0">Loading...</div></div>
1354
1360
  </section>
1355
1361
 
@@ -5580,9 +5586,25 @@ export {
5580
5586
  }).join("")
5581
5587
  : '<div class="empty" style="padding:12px 0">No projects indexed yet. Use "Index a project" above.</div>';
5582
5588
  let html = '<div class="panel"><div class="set-cat-h">Indexed projects <small>' + projects.length + "</small></div>" + projHtml + "</div>";
5589
+ // Drift is stated, not hidden: a graph that has fallen behind the code answers
5590
+ // confidently and wrongly, and the only cue would otherwise be a stale line number.
5591
+ const fresh = view.freshness;
5592
+ if (fresh) {
5593
+ const stale = fresh.stale || 0;
5594
+ html += '<div class="panel"><div class="set-cat-h">Freshness</div><div class="set-row"><div class="set-meta"><div class="set-name">'
5595
+ + (stale === 0 ? "Up to date" : stale + " file" + (stale === 1 ? "" : "s") + " changed since indexing")
5596
+ + '</div><div class="set-hint">' + esc("indexed " + new Date(fresh.indexedAt).toLocaleString()
5597
+ + (fresh.truncated ? " · incomplete: the scan hit a limit, so some files were never indexed" : "")) + "</div></div>"
5598
+ + (stale === 0 ? "" : '<div class="set-ctl"><button type="button" class="toggle on" data-cg-reindex="' + esc(fresh.root) + '">Re-index</button></div>')
5599
+ + "</div></div>";
5600
+ }
5583
5601
  if (view.architecture) html += cgSection("Architecture" + (view.selected ? " - " + view.selected : ""), view.architecture);
5584
5602
  if (view.schema) html += cgSection("Graph schema", view.schema);
5585
5603
  $("cgBody").innerHTML = html;
5604
+ const ask = view.ask;
5605
+ $("cgAskOut").innerHTML = ask
5606
+ ? '<pre style="white-space:pre-wrap;overflow-x:auto;margin:10px 0 0;font-size:12px">' + esc(ask.report) + "</pre>"
5607
+ : "";
5586
5608
  }
5587
5609
  async function loadCodeGraph() {
5588
5610
  $("cgNote").textContent = "";
@@ -5609,11 +5631,25 @@ export {
5609
5631
  const out = await cgPost({ op: "index", root: root || undefined }, "Indexing...");
5610
5632
  if (out) { if (out.view && out.view.selected) cgProject = out.view.selected; setNote("cgNote", out.ok ? "Indexed." : (out.error || "Indexing failed."), out.ok ? "ok" : "err"); }
5611
5633
  }
5634
+ async function cgAskAction() {
5635
+ const query = $("cgQuery").value.trim();
5636
+ if (!query) { setNote("cgNote", "Type a question first.", "err"); return; }
5637
+ const out = await cgPost({ op: "ask", query, project: cgProject || undefined }, "Searching...");
5638
+ if (out) setNote("cgNote", out.ok ? "" : (out.error || "Query failed."), out.ok ? "ok" : "err");
5639
+ }
5612
5640
  function wireCodeGraph() {
5613
5641
  $("cgRefresh").addEventListener("click", loadCodeGraph);
5614
5642
  $("cgToggle").addEventListener("click", cgToggleAction);
5615
5643
  $("cgIndex").addEventListener("click", cgIndexAction);
5644
+ $("cgAsk").addEventListener("click", cgAskAction);
5645
+ $("cgQuery").addEventListener("keydown", (e) => { if (e.key === "Enter") cgAskAction(); });
5616
5646
  $("view-codegraph").addEventListener("click", (e) => {
5647
+ const reindex = e.target.closest("button[data-cg-reindex]");
5648
+ if (reindex) {
5649
+ cgPost({ op: "index", root: reindex.dataset.cgReindex }, "Re-indexing...")
5650
+ .then((out) => { if (out) setNote("cgNote", out.ok ? "Re-indexed." : (out.error || "Indexing failed."), out.ok ? "ok" : "err"); });
5651
+ return;
5652
+ }
5617
5653
  const b = e.target.closest("button[data-cg-project]");
5618
5654
  if (!b) return;
5619
5655
  cgProject = b.dataset.cgProject;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enigmax/dashboard",
3
- "version": "0.1.107",
3
+ "version": "0.1.108",
4
4
  "description": "Local browser dashboard UI for enigma: the static page and chart assets enigma serves on its loopback dashboard (savings, real tool usage, in-browser settings). Installed on demand by enigma-cli; not a runtime dependency.",
5
5
  "type": "module",
6
6
  "files": [