@rel-time/mcp-server 1.2.12 → 1.2.13

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 +56 -12
  2. package/package.json +1 -1
  3. package/server.json +2 -2
package/index.js CHANGED
@@ -56,7 +56,7 @@ let LAST_INVOICE_PACK = null;
56
56
 
57
57
  const SERVER_INFO = {
58
58
  name: "rel-time-mcp-server",
59
- version: "1.2.12",
59
+ version: "1.2.13",
60
60
  };
61
61
 
62
62
  /**
@@ -341,6 +341,30 @@ function injectPngVerifyBuffer(pngBuffer, verifyUrl) {
341
341
  ]);
342
342
  }
343
343
 
344
+ /**
345
+ * Builds an OS-safe filename (<= 240 UTF-8 bytes) so macOS/Linux 255-byte limits
346
+ * (`ENAMETOOLONG`) never fail on long AI-prompt filenames.
347
+ */
348
+ function safeArtifactFilename(prefix, rawName, ext, hashHex = "") {
349
+ const candidate = `${prefix}${rawName}${ext}`;
350
+ if (Buffer.byteLength(candidate, "utf8") <= 240) {
351
+ return candidate;
352
+ }
353
+ const suffixTag = hashHex
354
+ ? `~${String(hashHex).slice(0, 8)}`
355
+ : `~${crypto.createHash("sha256").update(String(rawName), "utf8").digest("hex").slice(0, 8)}`;
356
+ const maxBodyBytes = Math.max(32, 240 - Buffer.byteLength(prefix, "utf8") - Buffer.byteLength(suffixTag, "utf8") - Buffer.byteLength(ext, "utf8"));
357
+ let trimmed = "";
358
+ let usedBytes = 0;
359
+ for (const ch of String(rawName)) {
360
+ const chBytes = Buffer.byteLength(ch, "utf8");
361
+ if (usedBytes + chBytes > maxBodyBytes) break;
362
+ trimmed += ch;
363
+ usedBytes += chBytes;
364
+ }
365
+ return `${prefix}${trimmed.trim()}${suffixTag}${ext}`;
366
+ }
367
+
344
368
  /**
345
369
  * Stamps the Option 1A (+14° Bitcoin Tilt, pure crisp 64-ray Sun-Stamp, 0% glare, no pill) onto a local Image or PDF.
346
370
  * Returns { stamped: true, output_path, format } or { stamped: false, reason }.
@@ -375,7 +399,9 @@ async function stampLocalFileOptionA(filePath, svgContent, customOutputPath = nu
375
399
  .replace(/<\/a>/gi, "");
376
400
 
377
401
  if (isImage) {
378
- const outPath = customOutputPath ? path.resolve(customOutputPath) : path.join(dir, `reltime-stamped-${baseName}.png`);
402
+ const outPath = customOutputPath
403
+ ? path.resolve(customOutputPath)
404
+ : path.join(dir, safeArtifactFilename("reltime-stamped-", baseName, ".png", verifyHash));
379
405
  const img = sharp(filePath);
380
406
  const meta = await img.metadata();
381
407
  const w = (meta.autoOrient && meta.autoOrient.width) || meta.width || 1200;
@@ -410,7 +436,9 @@ async function stampLocalFileOptionA(filePath, svgContent, customOutputPath = nu
410
436
  }
411
437
 
412
438
  if (isPdf) {
413
- const outPath = customOutputPath ? path.resolve(customOutputPath) : path.join(dir, `reltime-stamped-${baseName}.pdf`);
439
+ const outPath = customOutputPath
440
+ ? path.resolve(customOutputPath)
441
+ : path.join(dir, safeArtifactFilename("reltime-stamped-", baseName, ".pdf", verifyHash));
414
442
  const pdfBytes = fs.readFileSync(filePath);
415
443
  const pdfDoc = await PDFDocument.load(pdfBytes, { ignoreEncryption: true });
416
444
  const pages = pdfDoc.getPages();
@@ -2521,7 +2549,10 @@ async function executeTool(name, args = {}) {
2521
2549
  let savedSvgPath = null;
2522
2550
  if (args.save_sun_stamp_svg !== false && svgContent) {
2523
2551
  try {
2524
- savedSvgPath = path.join(path.dirname(filePath), `reltime-stamp-${path.basename(filePath)}.svg`);
2552
+ savedSvgPath = path.join(
2553
+ path.dirname(filePath),
2554
+ safeArtifactFilename("reltime-stamp-", path.basename(filePath), ".svg", clientHash)
2555
+ );
2525
2556
  fs.writeFileSync(savedSvgPath, svgContent, "utf8");
2526
2557
  } catch (e) {
2527
2558
  savedSvgPath = null;
@@ -2531,7 +2562,7 @@ async function executeTool(name, args = {}) {
2531
2562
  // Save initial Doomsday Proof JSON alongside the file
2532
2563
  const savedProofJsonPath = path.join(
2533
2564
  path.dirname(filePath),
2534
- `reltime-doomsday-proof-${path.basename(filePath)}.json`
2565
+ safeArtifactFilename("reltime-doomsday-proof-", path.basename(filePath), ".json", clientHash)
2535
2566
  );
2536
2567
  fs.writeFileSync(
2537
2568
  savedProofJsonPath,
@@ -2593,7 +2624,7 @@ async function executeTool(name, args = {}) {
2593
2624
  });
2594
2625
  savedCertificateHtmlPath = path.join(
2595
2626
  path.dirname(filePath),
2596
- `reltime-certificate-${path.basename(filePath)}.html`
2627
+ safeArtifactFilename("reltime-certificate-", path.basename(filePath), ".html", clientHash)
2597
2628
  );
2598
2629
  fs.writeFileSync(savedCertificateHtmlPath, certHtml, "utf8");
2599
2630
  if (args.open_certificate_in_browser) {
@@ -2705,12 +2736,24 @@ async function executeTool(name, args = {}) {
2705
2736
  for (const fPath of targetFiles) {
2706
2737
  const relPath = path.relative(folderPath, fPath);
2707
2738
  const baseName = path.basename(fPath);
2708
- const sidecarProof = path.join(path.dirname(fPath), `reltime-doomsday-proof-${baseName}.json`);
2709
- const subfolderProof = path.join(proofsDir, `reltime-doomsday-proof-${relPath.replace(/[\\/]/g, "__")}.json`);
2710
- if (existingManifest.anchored_files[relPath] || fs.existsSync(sidecarProof) || fs.existsSync(subfolderProof)) {
2739
+ const sidecarProof = path.join(
2740
+ path.dirname(fPath),
2741
+ safeArtifactFilename("reltime-doomsday-proof-", baseName, ".json")
2742
+ );
2743
+ const legacySidecarProof = path.join(path.dirname(fPath), `reltime-doomsday-proof-${baseName}.json`);
2744
+ const subfolderProof = path.join(
2745
+ proofsDir,
2746
+ safeArtifactFilename("reltime-doomsday-proof-", relPath.replace(/[\\/]/g, "__"), ".json")
2747
+ );
2748
+ if (
2749
+ existingManifest.anchored_files[relPath] ||
2750
+ fs.existsSync(sidecarProof) ||
2751
+ (Buffer.byteLength(`reltime-doomsday-proof-${baseName}.json`, "utf8") <= 255 && fs.existsSync(legacySidecarProof)) ||
2752
+ fs.existsSync(subfolderProof)
2753
+ ) {
2711
2754
  skipped.push(relPath);
2712
2755
  } else {
2713
- toProcess.push({ fPath, relPath, baseName, subfolderProof });
2756
+ toProcess.push({ fPath, relPath, baseName, subfolderProof, sidecarProof });
2714
2757
  }
2715
2758
  }
2716
2759
 
@@ -2779,8 +2822,7 @@ async function executeTool(name, args = {}) {
2779
2822
  if (artifactMode === "proofs_subfolder") {
2780
2823
  fs.writeFileSync(item.subfolderProof, JSON.stringify(proofRecord, null, 2), "utf8");
2781
2824
  } else if (artifactMode === "full") {
2782
- const sidecarPath = path.join(path.dirname(item.fPath), `reltime-doomsday-proof-${item.baseName}.json`);
2783
- fs.writeFileSync(sidecarPath, JSON.stringify(proofRecord, null, 2), "utf8");
2825
+ fs.writeFileSync(item.sidecarProof, JSON.stringify(proofRecord, null, 2), "utf8");
2784
2826
  }
2785
2827
 
2786
2828
  existingManifest.anchored_files[item.relPath] = proofRecord;
@@ -3232,10 +3274,12 @@ async function executeTool(name, args = {}) {
3232
3274
  if (item.startsWith(".")) continue;
3233
3275
  if (
3234
3276
  item.startsWith("reltime-stamp-") ||
3277
+ item.startsWith("reltime-stamped-") ||
3235
3278
  item.startsWith("reltime-doomsday-proof-") ||
3236
3279
  item.startsWith("reltime-proof-") ||
3237
3280
  item.startsWith("reltime-certificate-") ||
3238
3281
  item.startsWith("reltime-audit-report-") ||
3282
+ item.startsWith("reltime-audit-trail-") ||
3239
3283
  item === "reltime-batch-manifest.json" ||
3240
3284
  item === "_reltime_proofs"
3241
3285
  ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rel-time/mcp-server",
3
- "version": "1.2.12",
3
+ "version": "1.2.13",
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.12",
11
+ "version": "1.2.13",
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.12",
17
+ "version": "1.2.13",
18
18
  "transport": {
19
19
  "type": "stdio"
20
20
  }