indelible-mcp 5.7.1 → 5.7.2

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/LICENSE +1 -1
  2. package/package.json +1 -1
  3. package/src/index.js +43 -17
package/LICENSE CHANGED
@@ -11,7 +11,7 @@ Additional Use Grant: You may make use of the Licensed Work for personal,
11
11
  commercial blockchain storage, session saving, or
12
12
  encrypted vault service without written permission
13
13
  from the Licensor.
14
- Change Date: August 13, 2030
14
+ Change Date: August 14, 2030
15
15
  Change License: MIT License
16
16
 
17
17
  Terms
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indelible-mcp",
3
- "version": "5.7.1",
3
+ "version": "5.7.2",
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
@@ -3122,7 +3122,12 @@ function appendReceipt(receipt, meta = {}) {
3122
3122
  // has the IDE shown this entry yet?
3123
3123
  };
3124
3124
  appendFileSync(LOG, JSON.stringify(entry) + "\n");
3125
- } catch {
3125
+ } catch (e) {
3126
+ try {
3127
+ process.stderr.write(`[save-log] \u26A0\uFE0F could not record receipt for ${String(receipt.txid).slice(0, 12)}\u2026 (${e.message}) \u2014 the save is on chain, but this receipt is not in the local ledger; reconciliation by content may be needed later
3128
+ `);
3129
+ } catch {
3130
+ }
3126
3131
  }
3127
3132
  }
3128
3133
  var DIR2, LOG;
@@ -9098,7 +9103,7 @@ function makeHeartbeat(cfg2) {
9098
9103
  }
9099
9104
  return set;
9100
9105
  };
9101
- const emit = async (kind, payload2, parents, entryEpoch) => {
9106
+ const emit2 = async (kind, payload2, parents, entryEpoch) => {
9102
9107
  const ikBasis = digest2(DIGEST_DOMAINS.event, canonicalize2({ me, kind, payload: payload2, parents }));
9103
9108
  const ev = makeEvent({
9104
9109
  event_kind: kind,
@@ -9148,7 +9153,7 @@ function makeHeartbeat(cfg2) {
9148
9153
  for (const pe of peerEvents) {
9149
9154
  const reply = cfg2.respond?.(pe);
9150
9155
  if (reply) {
9151
- const r = await emit(reply.kind, reply.payload, [pe.event_id], epoch);
9156
+ const r = await emit2(reply.kind, reply.payload, [pe.event_id], epoch);
9152
9157
  if (r.published) {
9153
9158
  cfg2.onLine?.(`[${me}] \u2192 ${reply.line ?? reply.kind} (answering ${pe.actor.host})`);
9154
9159
  reacted = { to: pe.event_id, emitted: r.event_id };
@@ -9166,7 +9171,7 @@ function makeHeartbeat(cfg2) {
9166
9171
  if (!reacted) {
9167
9172
  const move = cfg2.generate?.();
9168
9173
  if (move) {
9169
- const r = await emit(move.kind, move.payload, [], epoch);
9174
+ const r = await emit2(move.kind, move.payload, [], epoch);
9170
9175
  if (r.published) {
9171
9176
  cfg2.onLine?.(`[${me}] \u270E ${move.line ?? move.kind}`);
9172
9177
  generated = r.event_id;
@@ -11028,14 +11033,18 @@ async function saveFile(filePath, options = {}) {
11028
11033
  timestamp
11029
11034
  });
11030
11035
  await saveConfig({ ...config2, file_txids: files });
11036
+ let indexed = false;
11031
11037
  try {
11032
11038
  const apiUrl = config2.api_url || "https://indelible.one";
11033
- await fetch(`${apiUrl}/api/files/index`, {
11039
+ const ir = await fetch(`${apiUrl}/api/files/index`, {
11034
11040
  method: "POST",
11035
11041
  headers: { "Content-Type": "application/json" },
11036
- body: JSON.stringify({ address: config2.address, txId: masterTxId, filename, path: relativePath, size: fileSize, contentHash: `sha256:${contentHash}`, timestamp })
11042
+ body: JSON.stringify({ address: config2.address, txId: masterTxId, filename, path: relativePath, size: fileSize, contentHash: `sha256:${contentHash}`, timestamp }),
11043
+ signal: AbortSignal.timeout(5e3)
11037
11044
  });
11045
+ indexed = !!(ir && ir.ok);
11038
11046
  } catch {
11047
+ indexed = false;
11039
11048
  }
11040
11049
  const chunkCount = encrypted.length <= MAX_CHUNK_SIZE ? 1 : Math.ceil(encrypted.length / MAX_CHUNK_SIZE);
11041
11050
  const receipt = buildReceipt(_finalWrite, { txId: masterTxId, fee: _saveFee, txSize: _finalSize });
@@ -11049,6 +11058,8 @@ async function saveFile(filePath, options = {}) {
11049
11058
  contentHash: `sha256:${contentHash}`,
11050
11059
  chunks: chunkCount,
11051
11060
  changeUtxos: finalChangeUtxos,
11061
+ indexed,
11062
+ // QA 94701: file-save receipts now report index state, like session saves already do
11052
11063
  receipt,
11053
11064
  message: `File "${filename}" saved to blockchain.${chunkCount > 1 ? ` (${chunkCount} chunks)` : ""}
11054
11065
 
@@ -14176,7 +14187,7 @@ var err5 = (code, msg) => {
14176
14187
  return e;
14177
14188
  };
14178
14189
  var ROLES = ["propose", "attack", "arbitrate"];
14179
- async function conveneChamber({ scope, seats, task, context = "", provider = "anthropic", model, client, chamber_id, emit = true } = {}) {
14190
+ async function conveneChamber({ scope, seats, task, context = "", provider = "anthropic", model, client, chamber_id, emit: emit2 = true } = {}) {
14180
14191
  if (!task || typeof task !== "string") throw err5("CHAMBER_ARGS", "task is required");
14181
14192
  if (!Array.isArray(seats) || seats.length !== 3) throw err5("CHAMBER_SEATS", "a chamber seats exactly three: propose, attack, arbitrate");
14182
14193
  const byRole = {};
@@ -14196,7 +14207,7 @@ async function conveneChamber({ scope, seats, task, context = "", provider = "an
14196
14207
  }
14197
14208
  const idSeed = `${task}|${byRole.propose},${byRole.attack},${byRole.arbitrate}`;
14198
14209
  const id = chamber_id || `chamber-${Math.abs([...idSeed].reduce((h, c) => h * 31 + c.charCodeAt(0) | 0, 7))}`;
14199
- const court = emit ? beginCourt({ court_id: id, domain: "chamber", mode: "single", label: task.slice(0, 100) }) : null;
14210
+ const court = emit2 ? beginCourt({ court_id: id, domain: "chamber", mode: "single", label: task.slice(0, 100) }) : null;
14200
14211
  const rounds = [];
14201
14212
  const run = (name, roundTask, roundContext) => runCustomAgent({ scope, name, task: roundTask, context: roundContext, provider, model, client });
14202
14213
  const p = await run(byRole.propose, task, context);
@@ -15083,6 +15094,11 @@ function runPreToolUseGuard() {
15083
15094
  }
15084
15095
  process.exit(code);
15085
15096
  }
15097
+ function emit(result) {
15098
+ console.log(JSON.stringify(result, null, 2));
15099
+ if (result && result.success === false) process.exitCode = 1;
15100
+ return result;
15101
+ }
15086
15102
  async function runCli(args2) {
15087
15103
  const command = args2[0];
15088
15104
  switch (command) {
@@ -15149,7 +15165,7 @@ async function runCli(args2) {
15149
15165
  const summaryIdx = args2.indexOf("--summary");
15150
15166
  const summary = summaryIdx !== -1 ? args2.slice(summaryIdx + 1).join(" ") : void 0;
15151
15167
  const result = await saveSession(CONTEXT_FILE2, summary);
15152
- console.log(JSON.stringify(result, null, 2));
15168
+ emit(result);
15153
15169
  break;
15154
15170
  }
15155
15171
  case "load": {
@@ -15185,20 +15201,22 @@ async function runCli(args2) {
15185
15201
  const filePath = args2[2];
15186
15202
  if (!filePath) {
15187
15203
  console.error("Usage: indelible-mcp vault save-file <path>");
15204
+ process.exitCode = 1;
15188
15205
  break;
15189
15206
  }
15190
15207
  const result = await saveFile(filePath);
15191
- console.log(JSON.stringify(result, null, 2));
15208
+ emit(result);
15192
15209
  } else if (subCmd === "save-project") {
15193
15210
  const dirPath = args2[2];
15194
15211
  if (!dirPath) {
15195
15212
  console.error("Usage: indelible-mcp vault save-project <dir>");
15213
+ process.exitCode = 1;
15196
15214
  break;
15197
15215
  }
15198
15216
  const nameArg = args2.find((a) => a.startsWith("--name="));
15199
15217
  const name = nameArg ? nameArg.split("=")[1] : void 0;
15200
15218
  const result = await saveProject(dirPath, { name });
15201
- console.log(JSON.stringify(result, null, 2));
15219
+ emit(result);
15202
15220
  } else if (subCmd === "load-file") {
15203
15221
  const txId = args2[2];
15204
15222
  if (!txId) {
@@ -15208,7 +15226,7 @@ async function runCli(args2) {
15208
15226
  const outArg = args2.find((a) => a.startsWith("--output="));
15209
15227
  const outputPath = outArg ? outArg.split("=")[1] : void 0;
15210
15228
  const result = await loadFile(txId, { outputPath });
15211
- console.log(JSON.stringify(result, null, 2));
15229
+ emit(result);
15212
15230
  } else if (subCmd === "load-project") {
15213
15231
  const txId = args2[2];
15214
15232
  if (!txId) {
@@ -15218,7 +15236,7 @@ async function runCli(args2) {
15218
15236
  const outArg = args2.find((a) => a.startsWith("--output-dir="));
15219
15237
  const outputDir = outArg ? outArg.split("=")[1] : void 0;
15220
15238
  const result = await loadProject(txId, { outputDir });
15221
- console.log(JSON.stringify(result, null, 2));
15239
+ emit(result);
15222
15240
  } else if (subCmd === "save-style") {
15223
15241
  const filePath = args2[2];
15224
15242
  const nameArg = args2.find((a) => a.startsWith("--name="));
@@ -15232,14 +15250,14 @@ async function runCli(args2) {
15232
15250
  console.error("Usage: indelible-mcp vault save-style <file> [--name=NAME] [--desc=DESC]");
15233
15251
  break;
15234
15252
  }
15235
- console.log(JSON.stringify(result, null, 2));
15253
+ emit(result);
15236
15254
  } else if (subCmd === "load-style") {
15237
15255
  const txId = args2[2];
15238
15256
  const result = await loadStyle(txId);
15239
15257
  console.log(JSON.stringify(result, null, 2));
15240
15258
  } else if (subCmd === "update-index") {
15241
15259
  const result = await updateVaultIndex();
15242
- console.log(JSON.stringify(result, null, 2));
15260
+ emit(result);
15243
15261
  } else {
15244
15262
  console.log(`
15245
15263
  Code Vault \u2014 Encrypted code storage on BSV blockchain
@@ -16114,13 +16132,21 @@ Answer THAT message and nothing else \u2014 the wire also carries unrelated conv
16114
16132
  drift ledger [--n=20] THE BOOKS: every summoned mind \u2014 when, who, why, how it ended`);
16115
16133
  break;
16116
16134
  }
16135
+ case "version":
16136
+ case "--version":
16137
+ case "-v":
16138
+ console.log(SERVER_INFO.version);
16139
+ break;
16117
16140
  default:
16141
+ if (command) console.error(`\u2717 unknown command: ${command}
16142
+ `);
16118
16143
  printHelp();
16144
+ if (command) process.exitCode = 1;
16119
16145
  }
16120
16146
  }
16121
16147
  function printHelp() {
16122
16148
  console.log(`
16123
- Indelible MCP \u2014 Blockchain memory for Claude Code (v5.7.1)
16149
+ Indelible MCP \u2014 Blockchain memory for Claude Code (v5.7.2)
16124
16150
 
16125
16151
  Setup:
16126
16152
  indelible-mcp setup --wif=KEY --pin=PIN Import and encrypt your private key
@@ -16447,7 +16473,7 @@ function readStdin() {
16447
16473
  }
16448
16474
  var SERVER_INFO = {
16449
16475
  name: "indelible",
16450
- version: "5.7.1",
16476
+ version: "5.7.2",
16451
16477
  description: "Blockchain-backed memory and code storage for Claude Code"
16452
16478
  };
16453
16479
  var TOOLS = [