@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.
Files changed (3) hide show
  1. package/index.js +306 -22
  2. package/package.json +1 -1
  3. 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.13",
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="filterLedger()" />
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 q = (document.getElementById('searchInput').value || '').trim().toLowerCase();
1547
- document.querySelectorAll('.ledger-row').forEach(row => {
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
- row.style.display = (matchesFilter && matchesQuery) ? '' : 'none';
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 (localPathVerification) {
3447
- const tp = localPathVerification.target_path;
3448
- reportDir = fs.statSync(tp).isDirectory() ? tp : path.dirname(tp);
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.13",
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.13",
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.13",
17
+ "version": "1.2.15",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  }