indelible-mcp 2.7.0 → 2.8.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 +1 -1
- package/src/index.js +2 -2
- package/src/lib/spv.js +5 -4
- package/src/tools/load_context.js +17 -0
- package/src/tools/save_session.js +48 -2
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -223,7 +223,7 @@ Commands:
|
|
|
223
223
|
|
|
224
224
|
function printHelp() {
|
|
225
225
|
console.log(`
|
|
226
|
-
Indelible MCP — Blockchain memory for Claude Code (v2.
|
|
226
|
+
Indelible MCP — Blockchain memory for Claude Code (v2.8.1)
|
|
227
227
|
|
|
228
228
|
Setup:
|
|
229
229
|
indelible-mcp setup --wif=KEY --pin=PIN Import and encrypt your private key
|
|
@@ -324,7 +324,7 @@ function readStdin() {
|
|
|
324
324
|
|
|
325
325
|
const SERVER_INFO = {
|
|
326
326
|
name: 'indelible',
|
|
327
|
-
version: '2.
|
|
327
|
+
version: '2.8.1',
|
|
328
328
|
description: 'Blockchain-backed memory and code storage for Claude Code'
|
|
329
329
|
}
|
|
330
330
|
|
package/src/lib/spv.js
CHANGED
|
@@ -11,10 +11,11 @@ import { Transaction, P2PKH, PrivateKey, SatoshisPerKilobyte, LockingScript, OP
|
|
|
11
11
|
import { loadConfig } from './config.js'
|
|
12
12
|
|
|
13
13
|
const DEFAULT_SPV_BRIDGES = [
|
|
14
|
-
{ url: 'http://45.76.19.199:8080', name: 'SPV
|
|
15
|
-
{ url: 'http://144.202.50.135:8080', name: 'SPV
|
|
16
|
-
{ url: 'http://155.138.254.224:8080', name: '
|
|
17
|
-
{ url: 'http://107.191.49.18:8080', name: '
|
|
14
|
+
{ url: 'http://45.76.19.199:8080', name: 'SPV Relay 1' },
|
|
15
|
+
{ url: 'http://144.202.50.135:8080', name: 'SPV Relay 2' },
|
|
16
|
+
{ url: 'http://155.138.254.224:8080', name: 'SPV Relay 3' },
|
|
17
|
+
{ url: 'http://107.191.49.18:8080', name: 'SPV Relay 4' },
|
|
18
|
+
{ url: 'http://155.138.216.126:8080', name: 'SPV Relay 5' },
|
|
18
19
|
]
|
|
19
20
|
|
|
20
21
|
function getBridges() {
|
|
@@ -30,6 +30,7 @@ function mergeDeltaSessions(sessions) {
|
|
|
30
30
|
parent.summary = session.summary
|
|
31
31
|
parent.created_at = session.created_at
|
|
32
32
|
parent.id = session.id
|
|
33
|
+
parent.structured_context = session.structured_context || parent.structured_context
|
|
33
34
|
} else {
|
|
34
35
|
merged.push({ ...session })
|
|
35
36
|
}
|
|
@@ -56,6 +57,22 @@ function formatCurrentConversation(session) {
|
|
|
56
57
|
lines.push(`Last saved: ${session.created_at ? new Date(session.created_at).toLocaleString() : 'Unknown'}`)
|
|
57
58
|
lines.push('')
|
|
58
59
|
|
|
60
|
+
// Render structured context if present (todos, plan, git branch)
|
|
61
|
+
if (session.structured_context) {
|
|
62
|
+
const sc = session.structured_context
|
|
63
|
+
if (sc.git_branch) lines.push(`Git branch: \`${sc.git_branch}\``)
|
|
64
|
+
if (sc.plan_slug) lines.push(`Active plan: \`${sc.plan_slug}\``)
|
|
65
|
+
if (sc.todos && sc.todos.length > 0) {
|
|
66
|
+
lines.push('')
|
|
67
|
+
lines.push('### Active Tasks (at time of save):')
|
|
68
|
+
for (const t of sc.todos) {
|
|
69
|
+
const icon = t.status === 'completed' ? '[x]' : t.status === 'in_progress' ? '[~]' : '[ ]'
|
|
70
|
+
lines.push(`- ${icon} ${t.content}`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
lines.push('')
|
|
74
|
+
}
|
|
75
|
+
|
|
59
76
|
if (total === 0) return lines.join('\n')
|
|
60
77
|
|
|
61
78
|
const recentStart = Math.max(0, total - RECENT_MESSAGES_FULL)
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* 9. Local backups (LOCAL)
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { readFileSync, writeFileSync, existsSync, statSync, mkdirSync } from 'node:fs'
|
|
17
|
-
import { dirname } from 'node:path'
|
|
16
|
+
import { readFileSync, writeFileSync, existsSync, statSync, mkdirSync, readdirSync } from 'node:fs'
|
|
17
|
+
import { dirname, join } from 'node:path'
|
|
18
|
+
import { homedir } from 'node:os'
|
|
18
19
|
import { loadConfig, saveConfig, getWif } from '../lib/config.js'
|
|
19
20
|
import { encrypt, sha256 } from '../lib/crypto.js'
|
|
20
21
|
import { findCurrentTranscript, parseTranscript } from '../lib/transcript.js'
|
|
@@ -65,6 +66,43 @@ function ensureJsonlBackup(path, messages) {
|
|
|
65
66
|
} catch { /* don't block */ }
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Extract structured context (todos, plan slug, git branch) from transcript.
|
|
71
|
+
*/
|
|
72
|
+
function getStructuredContext(transcriptPath) {
|
|
73
|
+
const ctx = { todos: null, plan_slug: null, git_branch: null, session_id: null }
|
|
74
|
+
try {
|
|
75
|
+
const content = readFileSync(transcriptPath, 'utf-8')
|
|
76
|
+
const lines = content.trim().split('\n')
|
|
77
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
78
|
+
try {
|
|
79
|
+
const entry = JSON.parse(lines[i])
|
|
80
|
+
if (entry.sessionId) {
|
|
81
|
+
ctx.session_id = entry.sessionId
|
|
82
|
+
ctx.git_branch = entry.gitBranch || null
|
|
83
|
+
ctx.plan_slug = entry.slug || null
|
|
84
|
+
break
|
|
85
|
+
}
|
|
86
|
+
} catch {}
|
|
87
|
+
}
|
|
88
|
+
} catch {}
|
|
89
|
+
|
|
90
|
+
const todosDir = join(homedir(), '.claude', 'todos')
|
|
91
|
+
if (ctx.session_id && existsSync(todosDir)) {
|
|
92
|
+
try {
|
|
93
|
+
const files = readdirSync(todosDir)
|
|
94
|
+
const match = files.find(f => f.startsWith(ctx.session_id))
|
|
95
|
+
if (match) {
|
|
96
|
+
const todos = JSON.parse(readFileSync(join(todosDir, match), 'utf-8'))
|
|
97
|
+
if (Array.isArray(todos) && todos.length > 0) {
|
|
98
|
+
ctx.todos = todos
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch {}
|
|
102
|
+
}
|
|
103
|
+
return ctx
|
|
104
|
+
}
|
|
105
|
+
|
|
68
106
|
/**
|
|
69
107
|
* Save current session to blockchain.
|
|
70
108
|
* Builds + signs transaction locally, broadcasts via SPV bridge.
|
|
@@ -133,6 +171,14 @@ export async function saveSession(transcriptPath, summary) {
|
|
|
133
171
|
messages: messagesToCommit
|
|
134
172
|
}
|
|
135
173
|
|
|
174
|
+
// Attach structured context (todos, active plan, git branch)
|
|
175
|
+
try {
|
|
176
|
+
const structuredCtx = getStructuredContext(actualPath)
|
|
177
|
+
if (structuredCtx.todos || structuredCtx.plan_slug) {
|
|
178
|
+
session.structured_context = structuredCtx
|
|
179
|
+
}
|
|
180
|
+
} catch { /* don't block save on structured context failure */ }
|
|
181
|
+
|
|
136
182
|
// Local backups (fire-and-forget)
|
|
137
183
|
if (config.diary_path) updateDiary(config.diary_path, session.summary, session.created_at)
|
|
138
184
|
if (transcriptPath) ensureJsonlBackup(transcriptPath, allMessages)
|