indelible-mcp 2.6.0 → 2.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indelible-mcp",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Blockchain-backed memory and code storage for Claude Code. Save AI conversations and source code permanently on BSV.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -220,7 +220,7 @@ Commands:
220
220
 
221
221
  function printHelp() {
222
222
  console.log(`
223
- Indelible MCP — Blockchain memory for Claude Code (v2.6.0)
223
+ Indelible MCP — Blockchain memory for Claude Code (v2.6.1)
224
224
 
225
225
  Setup:
226
226
  indelible-mcp setup --wif=KEY --pin=PIN Import and encrypt your private key
@@ -316,7 +316,7 @@ function readStdin() {
316
316
 
317
317
  const SERVER_INFO = {
318
318
  name: 'indelible',
319
- version: '2.6.0',
319
+ version: '2.6.1',
320
320
  description: 'Blockchain-backed memory and code storage for Claude Code'
321
321
  }
322
322
 
@@ -38,7 +38,7 @@ export async function loadProject(txId, options = {}) {
38
38
 
39
39
  const manifest = JSON.parse(raw.slice(jsonStart))
40
40
 
41
- if (manifest.protocol !== 'indelible.project') {
41
+ if (manifest.protocol !== 'indelible.project' && manifest.protocol !== 'indelible.project-bundle') {
42
42
  return { success: false, error: `Not an indelible.project tx (got: ${manifest.protocol || 'unknown'})` }
43
43
  }
44
44
 
@@ -46,7 +46,7 @@ export async function loadProject(txId, options = {}) {
46
46
  return { success: false, error: 'Manifest has no files array' }
47
47
  }
48
48
 
49
- // Decrypt project name (v2) or use plaintext (v1)
49
+ const isBundle = manifest.protocol === 'indelible.project-bundle'
50
50
  const projectName = manifest.name_enc ? decrypt(manifest.name_enc, wif) : manifest.name
51
51
 
52
52
  const loadedFiles = []
@@ -55,38 +55,64 @@ export async function loadProject(txId, options = {}) {
55
55
  for (let i = 0; i < manifest.files.length; i++) {
56
56
  const fileRef = manifest.files[i]
57
57
 
58
- // Decrypt file path from manifest (v2) or use plaintext (v1)
59
- const filePath = fileRef.path_enc ? decrypt(fileRef.path_enc, wif) : fileRef.path
60
-
61
- try {
62
- const fileResult = await loadFile(fileRef.txid)
63
-
64
- if (!fileResult.success) {
65
- errors.push({ path: filePath, txid: fileRef.txid, error: fileResult.error })
66
- continue
58
+ if (isBundle) {
59
+ // Bundle format: decrypt inline content
60
+ try {
61
+ const filePath = decrypt(fileRef.path_enc, wif)
62
+ const content = decrypt(fileRef.encrypted, wif)
63
+ const verified = fileRef.content_hash
64
+ ? fileRef.content_hash === `sha256:${sha256(content)}`
65
+ : true
66
+
67
+ if (options.outputDir) {
68
+ const outputPath = join(options.outputDir, projectName, filePath)
69
+ const dir = dirname(outputPath)
70
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true })
71
+ writeFileSync(outputPath, content, 'utf-8')
72
+ }
73
+
74
+ loadedFiles.push({
75
+ path: filePath,
76
+ size: fileRef.size,
77
+ verified,
78
+ content: options.outputDir ? '(written to disk)' : content
79
+ })
80
+ } catch (err) {
81
+ errors.push({ path: fileRef.path_enc?.slice(0, 20) + '...', error: err.message })
67
82
  }
68
-
69
- // Optionally write to disk
70
- if (options.outputDir) {
71
- const outputPath = join(options.outputDir, projectName, filePath)
72
- const dir = dirname(outputPath)
73
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true })
74
- writeFileSync(outputPath, fileResult.content, 'utf-8')
83
+ } else {
84
+ // Old manifest format: fetch each file by txid
85
+ const filePath = fileRef.path_enc ? decrypt(fileRef.path_enc, wif) : fileRef.path
86
+
87
+ try {
88
+ const fileResult = await loadFile(fileRef.txid)
89
+
90
+ if (!fileResult.success) {
91
+ errors.push({ path: filePath, txid: fileRef.txid, error: fileResult.error })
92
+ continue
93
+ }
94
+
95
+ if (options.outputDir) {
96
+ const outputPath = join(options.outputDir, projectName, filePath)
97
+ const dir = dirname(outputPath)
98
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true })
99
+ writeFileSync(outputPath, fileResult.content, 'utf-8')
100
+ }
101
+
102
+ loadedFiles.push({
103
+ path: filePath,
104
+ txid: fileRef.txid,
105
+ size: fileRef.size,
106
+ verified: fileResult.verified,
107
+ content: options.outputDir ? '(written to disk)' : fileResult.content
108
+ })
109
+ } catch (fileErr) {
110
+ errors.push({ path: filePath, txid: fileRef.txid, error: fileErr.message })
75
111
  }
76
112
 
77
- loadedFiles.push({
78
- path: filePath,
79
- txid: fileRef.txid,
80
- size: fileRef.size,
81
- verified: fileResult.verified,
82
- content: options.outputDir ? `(written to disk)` : fileResult.content
83
- })
84
- } catch (fileErr) {
85
- errors.push({ path: filePath, txid: fileRef.txid, error: fileErr.message })
86
- }
87
-
88
- if (i < manifest.files.length - 1) {
89
- await new Promise(r => setTimeout(r, 100))
113
+ if (i < manifest.files.length - 1) {
114
+ await new Promise(r => setTimeout(r, 100))
115
+ }
90
116
  }
91
117
  }
92
118