@rel-time/mcp-server 1.2.13 → 1.2.15
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/index.js +306 -22
- package/package.json +1 -1
- package/server.json +2 -2
package/index.js
CHANGED
|
@@ -56,9 +56,26 @@ let LAST_INVOICE_PACK = null;
|
|
|
56
56
|
|
|
57
57
|
const SERVER_INFO = {
|
|
58
58
|
name: "rel-time-mcp-server",
|
|
59
|
-
version: "1.2.
|
|
59
|
+
version: "1.2.15",
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Redacts the local OS user home directory prefix (e.g., /Users/Name, /home/name, C:\Users\Name)
|
|
64
|
+
* to `~` so exported audit reports and payloads never leak local machine usernames.
|
|
65
|
+
*/
|
|
66
|
+
function redactHomePath(rawPath) {
|
|
67
|
+
if (!rawPath || typeof rawPath !== "string") return "";
|
|
68
|
+
const home = os.homedir();
|
|
69
|
+
if (home) {
|
|
70
|
+
const escapedHome = home.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
71
|
+
const homeRegex = new RegExp(`^${escapedHome}(?=[/\\\\]|$)`, "i");
|
|
72
|
+
if (homeRegex.test(rawPath)) {
|
|
73
|
+
return rawPath.replace(homeRegex, "~");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return rawPath.replace(/^(\/Users\/[^/]+|\/home\/[^/]+|[A-Za-z]:\\Users\\[^\\]+)(?=[/\\]|$)/, "~");
|
|
77
|
+
}
|
|
78
|
+
|
|
62
79
|
/**
|
|
63
80
|
* Resolves a local file path, automatically matching macOS screenshot filenames
|
|
64
81
|
* that contain Narrow No-Break Spaces (U+202F) or Non-Breaking Spaces (U+00A0)
|
|
@@ -651,7 +668,7 @@ function generateAuditReportHtml(audit) {
|
|
|
651
668
|
<div class="section-index">SECTION 01 // ZERO-KNOWLEDGE LOCAL FILE INTEGRITY MATRIX</div>
|
|
652
669
|
<h2>Local Directory Cross-Reference</h2>
|
|
653
670
|
<p class="section-sub">Target Path: <span class="mono" style="color:var(--text-secondary)">${escapeHtml(
|
|
654
|
-
localCheck.target_path
|
|
671
|
+
redactHomePath(localCheck.target_path)
|
|
655
672
|
)}</span> · 0 Bytes Uploaded · Local SHA-256 vs. Bitcoin Ledger</p>
|
|
656
673
|
</div>
|
|
657
674
|
<div class="status-pill ${
|
|
@@ -667,6 +684,15 @@ function generateAuditReportHtml(audit) {
|
|
|
667
684
|
}</span>
|
|
668
685
|
</div>
|
|
669
686
|
</div>
|
|
687
|
+
<div class="filter-bar no-print">
|
|
688
|
+
<div class="tab-group" id="localTabGroup">
|
|
689
|
+
<button class="filter-tab local-filter-tab active" onclick="setLocalPill(this, 'all')">All (${localCheck.summary.total_files_scanned})</button>
|
|
690
|
+
<button class="filter-tab local-filter-tab" onclick="setLocalPill(this, 'local-settled')">Settled (${localCheck.summary.verified_settled_count})</button>
|
|
691
|
+
<button class="filter-tab local-filter-tab" onclick="setLocalPill(this, 'local-pending')">Pending (${localCheck.summary.verified_pending_count})</button>
|
|
692
|
+
<button class="filter-tab local-filter-tab" onclick="setLocalPill(this, 'local-alert')">Unanchored / Modified (${localCheck.summary.unanchored_or_modified_count})</button>
|
|
693
|
+
</div>
|
|
694
|
+
<input id="localSearchInput" class="search-input" type="text" placeholder="QUERY FILE NAME / SHA-256 / PASSKEY / BLOCK..." oninput="resetAndFilterLocal()" />
|
|
695
|
+
</div>
|
|
670
696
|
<div class="table-wrap">
|
|
671
697
|
<table>
|
|
672
698
|
<thead>
|
|
@@ -681,9 +707,16 @@ function generateAuditReportHtml(audit) {
|
|
|
681
707
|
<th style="text-align:right">Receipt</th>
|
|
682
708
|
</tr>
|
|
683
709
|
</thead>
|
|
684
|
-
<tbody>
|
|
710
|
+
<tbody id="localVerifyBody">
|
|
685
711
|
${localCheck.files
|
|
686
712
|
.map((f, idx) => {
|
|
713
|
+
const localRowClass =
|
|
714
|
+
f.integrity_status === "VERIFIED_SETTLED"
|
|
715
|
+
? "local-settled"
|
|
716
|
+
: f.integrity_status === "VERIFIED_PENDING"
|
|
717
|
+
? "local-pending"
|
|
718
|
+
: "local-alert";
|
|
719
|
+
|
|
687
720
|
const statusTag =
|
|
688
721
|
f.integrity_status === "VERIFIED_SETTLED"
|
|
689
722
|
? `<span class="status-cell"><span class="dot dot-settled"></span><span class="mono" style="color:var(--text)">VERIFIED · SETTLED</span></span>`
|
|
@@ -710,7 +743,9 @@ function generateAuditReportHtml(audit) {
|
|
|
710
743
|
: `<span class="mono muted">—</span>`;
|
|
711
744
|
|
|
712
745
|
return `
|
|
713
|
-
<tr
|
|
746
|
+
<tr class="local-row ${localRowClass}" data-search="${escapeHtml(
|
|
747
|
+
`${f.file_name} ${f.local_sha256} ${f.signer_public_key || ""} ${f.block_height || ""} ${f.anchor_mode || ""}`.toLowerCase()
|
|
748
|
+
)}">
|
|
714
749
|
<td class="mono muted">${String(idx + 1).padStart(2, "0")}</td>
|
|
715
750
|
<td>
|
|
716
751
|
<span style="font-weight:600;color:var(--text)">${escapeHtml(f.file_name)}</span>
|
|
@@ -730,6 +765,26 @@ function generateAuditReportHtml(audit) {
|
|
|
730
765
|
</tbody>
|
|
731
766
|
</table>
|
|
732
767
|
</div>
|
|
768
|
+
<div class="pagination-bar no-print" id="localPaginationBar">
|
|
769
|
+
<div class="pagination-info mono">
|
|
770
|
+
<span id="localRangeLabel">SHOWING 1–25</span>
|
|
771
|
+
<span class="muted">·</span>
|
|
772
|
+
<label class="mono muted" for="localPageSizeSelect">ROWS:</label>
|
|
773
|
+
<select id="localPageSizeSelect" class="page-size-select mono" onchange="changeLocalPageSize(this.value)">
|
|
774
|
+
<option value="25" selected>25 / PAGE</option>
|
|
775
|
+
<option value="50">50 / PAGE</option>
|
|
776
|
+
<option value="100">100 / PAGE</option>
|
|
777
|
+
<option value="0">ALL (FULL LIST)</option>
|
|
778
|
+
</select>
|
|
779
|
+
</div>
|
|
780
|
+
<div class="pagination-controls">
|
|
781
|
+
<button type="button" class="page-btn mono" id="localFirstBtn" onclick="goLocalPage(1)">[ ⟪ FIRST ]</button>
|
|
782
|
+
<button type="button" class="page-btn mono" id="localPrevBtn" onclick="stepLocalPage(-1)">[ ‹ PREV ]</button>
|
|
783
|
+
<span class="page-indicator mono" id="localPageIndicator">PAGE 1 OF 1</span>
|
|
784
|
+
<button type="button" class="page-btn mono" id="localNextBtn" onclick="stepLocalPage(1)">[ NEXT › ]</button>
|
|
785
|
+
<button type="button" class="page-btn mono" id="localLastBtn" onclick="goLocalLastPage()">[ LAST ⟫ ]</button>
|
|
786
|
+
</div>
|
|
787
|
+
</div>
|
|
733
788
|
</section>`
|
|
734
789
|
: "";
|
|
735
790
|
|
|
@@ -1322,9 +1377,68 @@ function generateAuditReportHtml(audit) {
|
|
|
1322
1377
|
font-family: "JetBrains Mono", "SF Mono", Menlo, monospace;
|
|
1323
1378
|
font-size: 11.5px;
|
|
1324
1379
|
}
|
|
1380
|
+
.pagination-bar {
|
|
1381
|
+
display: flex;
|
|
1382
|
+
justify-content: space-between;
|
|
1383
|
+
align-items: center;
|
|
1384
|
+
flex-wrap: wrap;
|
|
1385
|
+
gap: 12px;
|
|
1386
|
+
margin-top: 14px;
|
|
1387
|
+
padding-top: 12px;
|
|
1388
|
+
border-top: 1px solid var(--border);
|
|
1389
|
+
}
|
|
1390
|
+
.pagination-info {
|
|
1391
|
+
display: flex;
|
|
1392
|
+
align-items: center;
|
|
1393
|
+
gap: 8px;
|
|
1394
|
+
font-size: 11px;
|
|
1395
|
+
color: var(--text-secondary);
|
|
1396
|
+
}
|
|
1397
|
+
.page-size-select {
|
|
1398
|
+
background: var(--bg);
|
|
1399
|
+
color: var(--text);
|
|
1400
|
+
border: 1px solid var(--border-strong);
|
|
1401
|
+
padding: 4px 8px;
|
|
1402
|
+
font-size: 10.5px;
|
|
1403
|
+
cursor: pointer;
|
|
1404
|
+
}
|
|
1405
|
+
.pagination-controls {
|
|
1406
|
+
display: flex;
|
|
1407
|
+
align-items: center;
|
|
1408
|
+
gap: 6px;
|
|
1409
|
+
}
|
|
1410
|
+
.page-btn {
|
|
1411
|
+
background: var(--bg);
|
|
1412
|
+
color: var(--text-secondary);
|
|
1413
|
+
border: 1px solid var(--border-strong);
|
|
1414
|
+
padding: 5px 10px;
|
|
1415
|
+
font-size: 10.5px;
|
|
1416
|
+
font-weight: 600;
|
|
1417
|
+
cursor: pointer;
|
|
1418
|
+
transition: all 0.12s ease;
|
|
1419
|
+
}
|
|
1420
|
+
.page-btn:hover:not(:disabled) {
|
|
1421
|
+
border-color: var(--amber);
|
|
1422
|
+
color: var(--amber);
|
|
1423
|
+
}
|
|
1424
|
+
.page-btn:disabled {
|
|
1425
|
+
opacity: 0.35;
|
|
1426
|
+
cursor: not-allowed;
|
|
1427
|
+
}
|
|
1428
|
+
.page-indicator {
|
|
1429
|
+
font-size: 11px;
|
|
1430
|
+
font-weight: 600;
|
|
1431
|
+
color: var(--text);
|
|
1432
|
+
padding: 0 8px;
|
|
1433
|
+
}
|
|
1434
|
+
tr.filter-hidden,
|
|
1435
|
+
tr.page-hidden {
|
|
1436
|
+
display: none;
|
|
1437
|
+
}
|
|
1325
1438
|
@media print {
|
|
1326
1439
|
body { background: var(--bg) !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; padding: 10px; }
|
|
1327
1440
|
.no-print { display: none !important; }
|
|
1441
|
+
tr.page-hidden { display: table-row !important; }
|
|
1328
1442
|
}
|
|
1329
1443
|
</style>
|
|
1330
1444
|
</head>
|
|
@@ -1480,15 +1594,15 @@ function generateAuditReportHtml(audit) {
|
|
|
1480
1594
|
</div>
|
|
1481
1595
|
</div>
|
|
1482
1596
|
<div class="filter-bar no-print">
|
|
1483
|
-
<div class="tab-group">
|
|
1484
|
-
<button class="filter-tab active" onclick="setPill(this, 'all')">All (${entries.length})</button>
|
|
1485
|
-
<button class="filter-tab" onclick="setPill(this, 'status-settled')">Settled (${settledCount})</button>
|
|
1486
|
-
<button class="filter-tab" onclick="setPill(this, 'status-pending')">Pending (${pendingCount})</button>
|
|
1487
|
-
<button class="filter-tab" onclick="setPill(this, 'mode-biometric')">Passkey (${biometricCount})</button>
|
|
1488
|
-
<button class="filter-tab" onclick="setPill(this, 'mode-temporal')">Temporal VDF (${temporalCount})</button>
|
|
1489
|
-
<button class="filter-tab" onclick="setPill(this, 'mode-standard')">Standard (${standardCount})</button>
|
|
1597
|
+
<div class="tab-group" id="ledgerTabGroup">
|
|
1598
|
+
<button class="filter-tab ledger-filter-tab active" onclick="setPill(this, 'all')">All (${entries.length})</button>
|
|
1599
|
+
<button class="filter-tab ledger-filter-tab" onclick="setPill(this, 'status-settled')">Settled (${settledCount})</button>
|
|
1600
|
+
<button class="filter-tab ledger-filter-tab" onclick="setPill(this, 'status-pending')">Pending (${pendingCount})</button>
|
|
1601
|
+
<button class="filter-tab ledger-filter-tab" onclick="setPill(this, 'mode-biometric')">Passkey (${biometricCount})</button>
|
|
1602
|
+
<button class="filter-tab ledger-filter-tab" onclick="setPill(this, 'mode-temporal')">Temporal VDF (${temporalCount})</button>
|
|
1603
|
+
<button class="filter-tab ledger-filter-tab" onclick="setPill(this, 'mode-standard')">Standard (${standardCount})</button>
|
|
1490
1604
|
</div>
|
|
1491
|
-
<input id="searchInput" class="search-input" type="text" placeholder="QUERY SHA-256 / T_INDEX / PASSKEY / TXID / BLOCK..." oninput="
|
|
1605
|
+
<input id="searchInput" class="search-input" type="text" placeholder="QUERY SHA-256 / T_INDEX / PASSKEY / TXID / BLOCK..." oninput="resetAndFilterLedger()" />
|
|
1492
1606
|
</div>
|
|
1493
1607
|
<div class="table-wrap">
|
|
1494
1608
|
<table>
|
|
@@ -1509,11 +1623,40 @@ function generateAuditReportHtml(audit) {
|
|
|
1509
1623
|
</tbody>
|
|
1510
1624
|
</table>
|
|
1511
1625
|
</div>
|
|
1626
|
+
<div class="pagination-bar no-print" id="ledgerPaginationBar">
|
|
1627
|
+
<div class="pagination-info mono">
|
|
1628
|
+
<span id="ledgerRangeLabel">SHOWING 1–25</span>
|
|
1629
|
+
<span class="muted">·</span>
|
|
1630
|
+
<label class="mono muted" for="ledgerPageSizeSelect">ROWS:</label>
|
|
1631
|
+
<select id="ledgerPageSizeSelect" class="page-size-select mono" onchange="changeLedgerPageSize(this.value)">
|
|
1632
|
+
<option value="25" selected>25 / PAGE</option>
|
|
1633
|
+
<option value="50">50 / PAGE</option>
|
|
1634
|
+
<option value="100">100 / PAGE</option>
|
|
1635
|
+
<option value="0">ALL (FULL LIST)</option>
|
|
1636
|
+
</select>
|
|
1637
|
+
</div>
|
|
1638
|
+
<div class="pagination-controls">
|
|
1639
|
+
<button type="button" class="page-btn mono" id="ledgerFirstBtn" onclick="goLedgerPage(1)">[ ⟪ FIRST ]</button>
|
|
1640
|
+
<button type="button" class="page-btn mono" id="ledgerPrevBtn" onclick="stepLedgerPage(-1)">[ ‹ PREV ]</button>
|
|
1641
|
+
<span class="page-indicator mono" id="ledgerPageIndicator">PAGE 1 OF 1</span>
|
|
1642
|
+
<button type="button" class="page-btn mono" id="ledgerNextBtn" onclick="stepLedgerPage(1)">[ NEXT › ]</button>
|
|
1643
|
+
<button type="button" class="page-btn mono" id="ledgerLastBtn" onclick="goLedgerLastPage()">[ LAST ⟫ ]</button>
|
|
1644
|
+
</div>
|
|
1645
|
+
</div>
|
|
1512
1646
|
</section>
|
|
1513
1647
|
</div>
|
|
1514
1648
|
|
|
1515
1649
|
<script>
|
|
1516
1650
|
let currentFilter = 'all';
|
|
1651
|
+
let ledgerPage = 1;
|
|
1652
|
+
let ledgerPageSize = 25;
|
|
1653
|
+
let ledgerTotalPages = 1;
|
|
1654
|
+
|
|
1655
|
+
let currentLocalFilter = 'all';
|
|
1656
|
+
let localPage = 1;
|
|
1657
|
+
let localPageSize = 25;
|
|
1658
|
+
let localTotalPages = 1;
|
|
1659
|
+
|
|
1517
1660
|
function applyTheme(theme) {
|
|
1518
1661
|
const root = document.documentElement;
|
|
1519
1662
|
const btn = document.getElementById('themeToggleBtn');
|
|
@@ -1536,20 +1679,158 @@ function generateAuditReportHtml(audit) {
|
|
|
1536
1679
|
if (saved === 'light' || saved === 'dark') applyTheme(saved);
|
|
1537
1680
|
} catch (e) {}
|
|
1538
1681
|
})();
|
|
1682
|
+
|
|
1683
|
+
// Section 01: Local Directory Cross-Reference Pagination & Filtering
|
|
1684
|
+
function setLocalPill(btn, filter) {
|
|
1685
|
+
currentLocalFilter = filter;
|
|
1686
|
+
document.querySelectorAll('.local-filter-tab').forEach(el => el.classList.remove('active'));
|
|
1687
|
+
btn.classList.add('active');
|
|
1688
|
+
localPage = 1;
|
|
1689
|
+
filterLocalTable();
|
|
1690
|
+
}
|
|
1691
|
+
function resetAndFilterLocal() {
|
|
1692
|
+
localPage = 1;
|
|
1693
|
+
filterLocalTable();
|
|
1694
|
+
}
|
|
1695
|
+
function changeLocalPageSize(val) {
|
|
1696
|
+
localPageSize = Number(val) || 0;
|
|
1697
|
+
localPage = 1;
|
|
1698
|
+
filterLocalTable();
|
|
1699
|
+
}
|
|
1700
|
+
function goLocalPage(p) {
|
|
1701
|
+
localPage = Math.max(1, Math.min(localTotalPages, p));
|
|
1702
|
+
filterLocalTable();
|
|
1703
|
+
}
|
|
1704
|
+
function stepLocalPage(delta) {
|
|
1705
|
+
goLocalPage(localPage + delta);
|
|
1706
|
+
}
|
|
1707
|
+
function goLocalLastPage() {
|
|
1708
|
+
goLocalPage(localTotalPages);
|
|
1709
|
+
}
|
|
1710
|
+
function filterLocalTable() {
|
|
1711
|
+
const rows = Array.from(document.querySelectorAll('.local-row'));
|
|
1712
|
+
if (!rows.length) return;
|
|
1713
|
+
const qEl = document.getElementById('localSearchInput');
|
|
1714
|
+
const q = (qEl ? qEl.value : '').trim().toLowerCase();
|
|
1715
|
+
const matched = [];
|
|
1716
|
+
rows.forEach(row => {
|
|
1717
|
+
const matchesFilter = currentLocalFilter === 'all' || row.classList.contains(currentLocalFilter);
|
|
1718
|
+
const matchesQuery = !q || (row.getAttribute('data-search') || '').includes(q);
|
|
1719
|
+
if (matchesFilter && matchesQuery) {
|
|
1720
|
+
row.classList.remove('filter-hidden');
|
|
1721
|
+
matched.push(row);
|
|
1722
|
+
} else {
|
|
1723
|
+
row.classList.add('filter-hidden');
|
|
1724
|
+
row.classList.remove('page-hidden');
|
|
1725
|
+
}
|
|
1726
|
+
});
|
|
1727
|
+
|
|
1728
|
+
const total = matched.length;
|
|
1729
|
+
localTotalPages = localPageSize > 0 ? Math.max(1, Math.ceil(total / localPageSize)) : 1;
|
|
1730
|
+
if (localPage > localTotalPages) localPage = localTotalPages;
|
|
1731
|
+
const startIdx = localPageSize > 0 ? (localPage - 1) * localPageSize : 0;
|
|
1732
|
+
const endIdx = localPageSize > 0 ? Math.min(total, startIdx + localPageSize) : total;
|
|
1733
|
+
|
|
1734
|
+
matched.forEach((row, idx) => {
|
|
1735
|
+
if (localPageSize > 0 && (idx < startIdx || idx >= endIdx)) {
|
|
1736
|
+
row.classList.add('page-hidden');
|
|
1737
|
+
} else {
|
|
1738
|
+
row.classList.remove('page-hidden');
|
|
1739
|
+
}
|
|
1740
|
+
});
|
|
1741
|
+
|
|
1742
|
+
const rangeEl = document.getElementById('localRangeLabel');
|
|
1743
|
+
if (rangeEl) {
|
|
1744
|
+
rangeEl.textContent = total === 0 ? 'SHOWING 0 OF 0 FILES' : 'SHOWING ' + (startIdx + 1) + '–' + endIdx + ' OF ' + total.toLocaleString() + ' FILES';
|
|
1745
|
+
}
|
|
1746
|
+
const indEl = document.getElementById('localPageIndicator');
|
|
1747
|
+
if (indEl) indEl.textContent = 'PAGE ' + localPage + ' OF ' + localTotalPages;
|
|
1748
|
+
const firstBtn = document.getElementById('localFirstBtn');
|
|
1749
|
+
const prevBtn = document.getElementById('localPrevBtn');
|
|
1750
|
+
const nextBtn = document.getElementById('localNextBtn');
|
|
1751
|
+
const lastBtn = document.getElementById('localLastBtn');
|
|
1752
|
+
if (firstBtn) firstBtn.disabled = localPage <= 1;
|
|
1753
|
+
if (prevBtn) prevBtn.disabled = localPage <= 1;
|
|
1754
|
+
if (nextBtn) nextBtn.disabled = localPage >= localTotalPages;
|
|
1755
|
+
if (lastBtn) lastBtn.disabled = localPage >= localTotalPages;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
// Section 03: Chronological Timechain Ledger Pagination & Filtering
|
|
1539
1759
|
function setPill(btn, filter) {
|
|
1540
1760
|
currentFilter = filter;
|
|
1541
|
-
document.querySelectorAll('.filter-tab').forEach(el => el.classList.remove('active'));
|
|
1761
|
+
document.querySelectorAll('.ledger-filter-tab').forEach(el => el.classList.remove('active'));
|
|
1542
1762
|
btn.classList.add('active');
|
|
1763
|
+
ledgerPage = 1;
|
|
1764
|
+
filterLedger();
|
|
1765
|
+
}
|
|
1766
|
+
function resetAndFilterLedger() {
|
|
1767
|
+
ledgerPage = 1;
|
|
1768
|
+
filterLedger();
|
|
1769
|
+
}
|
|
1770
|
+
function changeLedgerPageSize(val) {
|
|
1771
|
+
ledgerPageSize = Number(val) || 0;
|
|
1772
|
+
ledgerPage = 1;
|
|
1543
1773
|
filterLedger();
|
|
1544
1774
|
}
|
|
1775
|
+
function goLedgerPage(p) {
|
|
1776
|
+
ledgerPage = Math.max(1, Math.min(ledgerTotalPages, p));
|
|
1777
|
+
filterLedger();
|
|
1778
|
+
}
|
|
1779
|
+
function stepLedgerPage(delta) {
|
|
1780
|
+
goLedgerPage(ledgerPage + delta);
|
|
1781
|
+
}
|
|
1782
|
+
function goLedgerLastPage() {
|
|
1783
|
+
goLedgerPage(ledgerTotalPages);
|
|
1784
|
+
}
|
|
1545
1785
|
function filterLedger() {
|
|
1546
|
-
const
|
|
1547
|
-
document.
|
|
1786
|
+
const rows = Array.from(document.querySelectorAll('.ledger-row'));
|
|
1787
|
+
const qEl = document.getElementById('searchInput');
|
|
1788
|
+
const q = (qEl ? qEl.value : '').trim().toLowerCase();
|
|
1789
|
+
const matched = [];
|
|
1790
|
+
rows.forEach(row => {
|
|
1548
1791
|
const matchesFilter = currentFilter === 'all' || row.classList.contains(currentFilter);
|
|
1549
1792
|
const matchesQuery = !q || (row.getAttribute('data-search') || '').includes(q);
|
|
1550
|
-
|
|
1793
|
+
if (matchesFilter && matchesQuery) {
|
|
1794
|
+
row.classList.remove('filter-hidden');
|
|
1795
|
+
matched.push(row);
|
|
1796
|
+
} else {
|
|
1797
|
+
row.classList.add('filter-hidden');
|
|
1798
|
+
row.classList.remove('page-hidden');
|
|
1799
|
+
}
|
|
1551
1800
|
});
|
|
1552
|
-
|
|
1801
|
+
|
|
1802
|
+
const total = matched.length;
|
|
1803
|
+
ledgerTotalPages = ledgerPageSize > 0 ? Math.max(1, Math.ceil(total / ledgerPageSize)) : 1;
|
|
1804
|
+
if (ledgerPage > ledgerTotalPages) ledgerPage = ledgerTotalPages;
|
|
1805
|
+
const startIdx = ledgerPageSize > 0 ? (ledgerPage - 1) * ledgerPageSize : 0;
|
|
1806
|
+
const endIdx = ledgerPageSize > 0 ? Math.min(total, startIdx + ledgerPageSize) : total;
|
|
1807
|
+
|
|
1808
|
+
matched.forEach((row, idx) => {
|
|
1809
|
+
if (ledgerPageSize > 0 && (idx < startIdx || idx >= endIdx)) {
|
|
1810
|
+
row.classList.add('page-hidden');
|
|
1811
|
+
} else {
|
|
1812
|
+
row.classList.remove('page-hidden');
|
|
1813
|
+
}
|
|
1814
|
+
});
|
|
1815
|
+
|
|
1816
|
+
const rangeEl = document.getElementById('ledgerRangeLabel');
|
|
1817
|
+
if (rangeEl) {
|
|
1818
|
+
rangeEl.textContent = total === 0 ? 'SHOWING 0 OF 0 RECORDS' : 'SHOWING ' + (startIdx + 1) + '–' + endIdx + ' OF ' + total.toLocaleString() + ' RECORDS';
|
|
1819
|
+
}
|
|
1820
|
+
const indEl = document.getElementById('ledgerPageIndicator');
|
|
1821
|
+
if (indEl) indEl.textContent = 'PAGE ' + ledgerPage + ' OF ' + ledgerTotalPages;
|
|
1822
|
+
const firstBtn = document.getElementById('ledgerFirstBtn');
|
|
1823
|
+
const prevBtn = document.getElementById('ledgerPrevBtn');
|
|
1824
|
+
const nextBtn = document.getElementById('ledgerNextBtn');
|
|
1825
|
+
const lastBtn = document.getElementById('ledgerLastBtn');
|
|
1826
|
+
if (firstBtn) firstBtn.disabled = ledgerPage <= 1;
|
|
1827
|
+
if (prevBtn) prevBtn.disabled = ledgerPage <= 1;
|
|
1828
|
+
if (nextBtn) nextBtn.disabled = ledgerPage >= ledgerTotalPages;
|
|
1829
|
+
if (lastBtn) lastBtn.disabled = ledgerPage >= ledgerTotalPages;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
filterLocalTable();
|
|
1833
|
+
filterLedger();
|
|
1553
1834
|
</script>
|
|
1554
1835
|
</body>
|
|
1555
1836
|
</html>`;
|
|
@@ -3259,8 +3540,10 @@ async function executeTool(name, args = {}) {
|
|
|
3259
3540
|
|
|
3260
3541
|
// Optional Zero-Knowledge Local File / Folder Integrity Verification
|
|
3261
3542
|
let localPathVerification = null;
|
|
3543
|
+
let resolvedVerifyTargetPath = null;
|
|
3262
3544
|
if (args.verify_local_path) {
|
|
3263
3545
|
const targetPath = resolveLocalFilePath(args.verify_local_path);
|
|
3546
|
+
resolvedVerifyTargetPath = targetPath;
|
|
3264
3547
|
if (!fs.existsSync(targetPath)) {
|
|
3265
3548
|
throw new Error(`verify_local_path not found: ${targetPath}`);
|
|
3266
3549
|
}
|
|
@@ -3373,7 +3656,7 @@ async function executeTool(name, args = {}) {
|
|
|
3373
3656
|
|
|
3374
3657
|
fileAuditResults.push({
|
|
3375
3658
|
file_name: fName,
|
|
3376
|
-
file_path: fPath,
|
|
3659
|
+
file_path: redactHomePath(fPath),
|
|
3377
3660
|
size_bytes: bytes,
|
|
3378
3661
|
size_human: sizeHuman,
|
|
3379
3662
|
local_sha256: embeddedHash || rawSha256,
|
|
@@ -3391,7 +3674,7 @@ async function executeTool(name, args = {}) {
|
|
|
3391
3674
|
}
|
|
3392
3675
|
|
|
3393
3676
|
localPathVerification = {
|
|
3394
|
-
target_path: targetPath,
|
|
3677
|
+
target_path: redactHomePath(targetPath),
|
|
3395
3678
|
summary: {
|
|
3396
3679
|
total_files_scanned: fileAuditResults.length,
|
|
3397
3680
|
verified_settled_count: vSettled,
|
|
@@ -3443,9 +3726,10 @@ async function executeTool(name, args = {}) {
|
|
|
3443
3726
|
let reportDir = path.join(PASSKEY_CONFIG_DIR, "audits");
|
|
3444
3727
|
if (args.output_dir) {
|
|
3445
3728
|
reportDir = resolveLocalFilePath(args.output_dir);
|
|
3446
|
-
} else if (
|
|
3447
|
-
|
|
3448
|
-
|
|
3729
|
+
} else if (resolvedVerifyTargetPath) {
|
|
3730
|
+
reportDir = fs.statSync(resolvedVerifyTargetPath).isDirectory()
|
|
3731
|
+
? resolvedVerifyTargetPath
|
|
3732
|
+
: path.dirname(resolvedVerifyTargetPath);
|
|
3449
3733
|
}
|
|
3450
3734
|
if (!fs.existsSync(reportDir)) {
|
|
3451
3735
|
fs.mkdirSync(reportDir, { recursive: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rel-time/mcp-server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.15",
|
|
4
4
|
"mcpName": "io.github.relsun369-dev/rel-time",
|
|
5
5
|
"description": "Official Model Context Protocol (MCP) server for Rel-Time (rel-time.com) — Zero-Knowledge Bitcoin & VDF Provenance, Local File Hashing, and Sun-Stamp Generation for Claude, Cursor, Windsurf, and Antigravity.",
|
|
6
6
|
"main": "index.js",
|
package/server.json
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"url": "https://github.com/relsun369-dev/reltime-mcp",
|
|
9
9
|
"source": "github"
|
|
10
10
|
},
|
|
11
|
-
"version": "1.2.
|
|
11
|
+
"version": "1.2.15",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "@rel-time/mcp-server",
|
|
17
|
-
"version": "1.2.
|
|
17
|
+
"version": "1.2.15",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
}
|