indelible-mcp 5.3.1 → 5.3.3

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/CLI_HANDBOOK.md CHANGED
@@ -1,267 +1,293 @@
1
- # Indelible CLI Handbook
2
-
3
- ## Two Pilots (5.2.0)
4
-
5
- Indelible works with Claude Code, with OpenAI's Codex CLI, or with both at once on the same memory.
6
-
7
- - **Claude Code:** `claude mcp add indelible -- indelible-mcp`
8
- - **Codex CLI:** add to `~/.codex/config.toml` and restart Codex:
9
-
10
- ```toml
11
- [mcp_servers.indelible]
12
- command = "indelible-mcp"
13
- ```
14
-
15
- Every save is stamped with its author inside the encrypted record (`Saved by Claude` / `Saved by Codex` in the Context tab on indelible.one). Each pilot can only save its own conversations — a Codex call binds to its own rollout file, a Claude call binds to its own transcript, and a save with no valid binding refuses instead of guessing. The wallet admits one writer at a time, so concurrent pilots take turns instead of colliding; a busy wallet answers with a retryable message, not a double-spend.
16
-
17
- > Name check: the Diary companion below is also named "Codex" by default — that is a chat companion, not the OpenAI coding agent. The author stamps only ever come from the coding hosts.
18
-
19
- Standalone command-line interface for Indelible blockchain memory. Same wallet, same blockchain, same functions as the MCP server — but runnable directly.
20
-
21
- ---
22
-
23
- ## Quick Reference
24
-
25
- ### Save Session
26
- ```bash
27
- node C:/Indelible-main/indelible-cli/src/index.js save --summary "what happened"
28
- ```
29
-
30
- ### Load from Blockchain
31
- ```bash
32
- node C:/Indelible-main/indelible-cli/src/index.js load --sessions=5
33
- ```
34
-
35
- ### Check Status
36
- ```bash
37
- node C:/Indelible-main/indelible-cli/src/index.js status
38
- ```
39
-
40
- ### Save a File
41
- ```bash
42
- node C:/Indelible-main/indelible-cli/src/index.js vault save-file /path/to/file.js
43
- ```
44
-
45
- ### Ask Codex
46
- ```bash
47
- node C:/Indelible-main/indelible-cli/src/index.js diary chat "How should we architect this?"
48
- ```
49
-
50
- ---
51
-
52
- ## All Commands
53
-
54
- ### Sessions
55
- ```
56
- save Save current session to blockchain
57
- save --summary "note" Save with custom summary
58
- load Load context from blockchain (default: 5 sessions)
59
- load --sessions=10 Load N sessions
60
- status Show wallet address, API key, last session
61
- ```
62
-
63
- ### Code Vault
64
- ```
65
- vault save-file <path> Save a file (encrypted, chunked if >50KB)
66
- vault save-project <dir> [--name=NAME] Save a project directory
67
- vault load-file <txid> [--output=path] Load a file from blockchain
68
- vault load-project <txid> [--output-dir=dir] Load a project from blockchain
69
- vault save-style <file> [--name=N] [--desc=D] Save an AI style to blockchain
70
- vault load-style [txid] Load an AI style from blockchain
71
- vault update-index Update on-chain vault index
72
- ```
73
-
74
- ### Diary AI (Dual-Agent)
75
- ```
76
- diary connect --key=SK [--model=MODEL] [--name=NAME] Connect OpenAI companion
77
- diary chat "message" Ask the AI companion
78
- diary save [--summary="..."] Save exchange to blockchain
79
- ```
80
-
81
- ### Setup & Hooks
82
- ```
83
- setup --wif=KEY --pin=PIN Import and encrypt your private key
84
- install-hooks Install auto-save/restore hooks into Claude Code
85
- hook pre-compact Auto-save before compaction (called by hook)
86
- hook post-compact Auto-restore after compaction (called by hook)
87
- ```
88
-
89
- ---
90
-
91
- ## Relationship to MCP
92
-
93
- The CLI and MCP server are the **same codebase**. They import the same tool functions (`saveSession`, `loadContext`, `saveFile`, `diaryChat`, etc.) and use the same wallet at `~/.indelible/config.json`.
94
-
95
- | | CLI | MCP Server |
96
- |---|---|---|
97
- | **Location** | `C:/Indelible-main/indelible-cli/src/` | `C:/bsv-claude-wrapper/mcp-server/` |
98
- | **Config** | Sync (`readFileSync`/`writeFileSync`) | Async (`await loadConfig()`) |
99
- | **Fetch** | Native `fetch` (Node 18+) | `node-fetch` package |
100
- | **Timeout** | `AbortSignal.timeout(ms)` | Manual `AbortController` + `setTimeout` |
101
- | **Entry point** | CLI arg parser in `index.js` | JSON-RPC stdin/stdout in `index.js` |
102
- | **How Claude calls it** | `node src/index.js <command>` | MCP protocol via Claude Code hooks |
103
-
104
- **Sync rule:** Any feature, fix, or change that goes into one MUST go into both. No exceptions. Adapt sync/async config pattern accordingly.
105
-
106
- ---
107
-
108
- ## Testing / Dog-Fooding
109
-
110
- The CLI is a live test harness for the MCP. When you test a CLI command, you're testing the exact same function the MCP calls.
111
-
112
- ### Safe tests (no sats spent)
113
- ```bash
114
- # Config loads correctly
115
- node C:/Indelible-main/indelible-cli/src/index.js status
116
-
117
- # Blockchain read works
118
- node C:/Indelible-main/indelible-cli/src/index.js load --sessions=1
119
-
120
- # Style loads from chain
121
- node C:/Indelible-main/indelible-cli/src/index.js vault load-style
122
- ```
123
-
124
- ### Function-level tests (no sats spent)
125
- ```bash
126
- cd "C:/Indelible-main/indelible-cli" && node --input-type=module -e "
127
- import { checkConfirmation } from './src/lib/spv.js';
128
- const r = await checkConfirmation('TXID_HERE');
129
- console.log(JSON.stringify(r, null, 2));
130
- " 2>&1
131
-
132
- cd "C:/Indelible-main/indelible-cli" && node --input-type=module -e "
133
- import { checkTier } from './src/lib/api-client.js';
134
- import { loadConfig } from './src/lib/config.js';
135
- const config = loadConfig();
136
- const r = await checkTier(config.api_key);
137
- console.log(JSON.stringify(r, null, 2));
138
- " 2>&1
139
-
140
- cd "C:/Indelible-main/indelible-cli" && node --input-type=module -e "
141
- import { verifyRecentSaves } from './src/tools/save_file.js';
142
- const r = await verifyRecentSaves();
143
- console.log(JSON.stringify(r, null, 2));
144
- " 2>&1
145
- ```
146
-
147
- ### Live tests (spends sats)
148
- ```bash
149
- # Session save (delta if prior save exists)
150
- node C:/Indelible-main/indelible-cli/src/index.js save --summary "test save"
151
-
152
- # File save
153
- node C:/Indelible-main/indelible-cli/src/index.js vault save-file /path/to/small/file.txt
154
-
155
- # Style save (auto-prepends core rules via ensureCoreRules)
156
- node C:/Indelible-main/indelible-cli/src/index.js vault save-style /path/to/rules.txt --name=test
157
-
158
- # Diary chat (costs OpenAI tokens, not sats)
159
- node C:/Indelible-main/indelible-cli/src/index.js diary chat "hello"
160
- ```
161
-
162
- ---
163
-
164
- ## Architecture
165
-
166
- ```
167
- indelible-cli/src/
168
- ├── index.js CLI arg parser + MCP JSON-RPC server (dual mode)
169
- ├── lib/
170
- │ ├── config.js Sync config: loadConfig(), saveConfig(), getWif()
171
- │ ├── crypto.js AES-256-GCM encrypt/decrypt, SHA-256, WIF derivation
172
- │ ├── spv.js Multi-bridge SPV client, UTXO chaining, health tracking
173
- │ └── api-client.js commitSession(), getLatestSessions(), checkTier()
174
- ├── tools/
175
- │ ├── save_session.js Parse transcript, delta detect, encrypt, broadcast
176
- │ │ + getRecentPlans() — scans ~/.claude/plans/
177
- │ │ + updateMemory() — MEMORY.md hierarchy enforcement
178
- │ │ + dashboard sync — PATCH to indelible.one
179
- │ ├── load_context.js Fetch + decrypt + merge deltas + smart format
180
- │ ├── setup_wallet.js Generate BSV keypair, encrypt WIF with PIN
181
- │ ├── save_file.js Encrypt + broadcast file (chunked if >50KB)
182
- │ │ + cacheTx() — local backup for re-broadcast
183
- │ │ + verifyRecentSaves() — check confirmations
184
- │ ├── save_project.js Walk dir + save each file + broadcast manifest
185
- │ │ + cacheTx() — local backup for re-broadcast
186
- │ ├── load_file.js Fetch + decrypt file from blockchain
187
- │ ├── load_project.js Fetch manifest + decrypt + restore files
188
- │ ├── save_style.js Encrypt style rules + broadcast
189
- │ │ + ensureCoreRules() — auto-prepend core rules
190
- │ ├── load_style.js Fetch + decrypt style from blockchain
191
- │ ├── update_vault_index.js Update on-chain file/project index
192
- │ ├── diary_connect.js Store OpenAI API key in config
193
- │ ├── diary_chat.js Send message to Codex via OpenAI API
194
- │ │ + blockchain history loading (last 3 sessions)
195
- │ └── diary_save.js Save diary exchange to blockchain
196
- └── dist/
197
- └── indelible.exe Compiled standalone (bun build --compile)
198
- ```
199
-
200
- ### Key Internal Features
201
-
202
- | Feature | What It Does |
203
- |---|---|
204
- | **Bridge health tracking** | Tracks success/failure per SPV bridge, skips unhealthy ones |
205
- | **UTXO chaining** | Back-to-back saves chain change outputs — no mempool conflicts |
206
- | **Delta saves** | Only commits new messages since last save |
207
- | **tx-cache** | Caches broadcast payloads to `~/.indelible/tx-cache/` for re-broadcast |
208
- | **MEMORY.md enforcement** | Strips rules, archives done items, enforces 200-line / 20-line limits |
209
- | **Core rules injection** | `ensureCoreRules()` auto-prepends infrastructure rules to every style |
210
- | **Diary history** | `diary chat` loads last 3 blockchain sessions for conversation continuity |
211
- | **Dashboard sync** | PATCHes indelible.one after every save |
212
-
213
- ---
214
-
215
- ## Rebuild the Executable
216
-
217
- ```bash
218
- cd "C:/Indelible-main/indelible-cli" && bun build --compile src/index.js --outfile dist/indelible.exe
219
- ```
220
-
221
- This creates a standalone `indelible.exe` — no Node.js required on the target machine.
222
-
223
- ---
224
-
225
- ## Common Errors
226
-
227
- | Error | Cause | Fix |
228
- |-------|-------|-----|
229
- | `Wallet not configured` | No config.json or no WIF | Run `setup --wif=KEY --pin=PIN` |
230
- | `No UTXOs available` | Wallet is empty | Send BSV to your address |
231
- | `Broadcast failed on all bridges` | All 4 SPV relays down or rejecting | Check relay health, wait and retry |
232
- | `No new messages since last save` | Already saved this transcript | Nothing to do — this is fine |
233
- | `File not found` | Bad path or backslashes | Use forward slashes: `C:/path/to/file` |
234
- | `Decrypt failed` | Wrong WIF or tampered data | Check `~/.indelible/config.json` has correct WIF |
235
- | `txn-mempool-conflict` | Spending already-spent UTXO | UTXO chaining should prevent this — check code |
236
- | `OpenAI rate limit exceeded` | Too many diary chat calls | Wait a moment and retry |
237
- | `Diary AI not configured` | No OpenAI key | Run `diary connect --key=SK` |
238
-
239
- ---
240
-
241
- ## Config File
242
-
243
- `C:/Users/oorel/.indelible/config.json` — shared with MCP server.
244
-
245
- | Setting | Description |
246
- |---------|-------------|
247
- | `wif` or `wif_encrypted` | BSV private key (plaintext or PIN-encrypted) |
248
- | `address` | BSV address (derived from WIF) |
249
- | `spv_bridges` | Array of `{url, name}` relay objects |
250
- | `api_url` | Indelible web app URL (`https://indelible.one`) |
251
- | `api_key` | API key for authenticated endpoints |
252
- | `auto_delta` | Auto-save every N messages (bool) |
253
- | `auto_delta_interval` | Messages between auto-saves (default: 10) |
254
- | `file_txids` | *(auto)* Index of files saved to chain |
255
- | `project_txids` | *(auto)* Index of projects saved to chain |
256
- | `last_session_id` | *(auto)* Previous session for chaining |
257
- | `last_tx_id` | *(auto)* Last committed tx |
258
- | `diary` | `{ apiKey, model, name }` — OpenAI companion config |
259
-
260
- ---
261
-
262
- ## Wallet
263
-
264
- - **Address:** shown by `indelible-mcp status` (yours is generated at setup and lives in `~/.indelible/config.json` — back that file up)
265
- - **Balance:** `indelible-mcp status`, or look your address up in the Chain Browser at indelible.one/explorer
266
- - **Fund it:** Send BSV to your own address
267
- - **Cost:** ~$0.21/MB at BSV=$16. Session saves are fractions of a cent.
1
+ # Indelible CLI Handbook
2
+
3
+ ## Two Pilots (5.2.0)
4
+
5
+ Indelible works with Claude Code, with OpenAI's Codex CLI, or with both at once on the same memory.
6
+
7
+ - **Claude Code:** `claude mcp add indelible -- indelible-mcp`
8
+ - **Codex CLI:** add to `~/.codex/config.toml` and restart Codex:
9
+
10
+ ```toml
11
+ [mcp_servers.indelible]
12
+ command = "indelible-mcp"
13
+ ```
14
+
15
+ Every save is stamped with its author inside the encrypted record (`Saved by Claude` / `Saved by Codex` in the Context tab on indelible.one). Each pilot can only save its own conversations — a Codex call binds to its own rollout file, a Claude call binds to its own transcript, and a save with no valid binding refuses instead of guessing. The wallet admits one writer at a time, so concurrent pilots take turns instead of colliding; a busy wallet answers with a retryable message, not a double-spend.
16
+
17
+ > Name check: the Diary companion below is also named "Codex" by default — that is a chat companion, not the OpenAI coding agent. The author stamps only ever come from the coding hosts.
18
+
19
+ Standalone command-line interface for Indelible blockchain memory. Same wallet, same blockchain, same functions as the MCP server — but runnable directly.
20
+
21
+ ---
22
+
23
+ ## The Drift Wire (5.3.x)
24
+
25
+ Your two pilots don't just share the memory anymore — they talk to each other through a
26
+ durable wire on your machine, with provable order and a brake only you hold.
27
+
28
+ ```
29
+ indelible-mcp drift read # see their conversation (ids + causal edges)
30
+ indelible-mcp drift post --as=claude "…" # post (--reply-to=<id> cites what it answers)
31
+ indelible-mcp drift wait --from=codex # hold the wire for the next message (instant via the bell)
32
+ indelible-mcp drift loop --as=claude # run a seat's heartbeat
33
+ indelible-mcp drift summon # THE SUMMONER: watches the wire; when a message sits
34
+ # unanswered, spawns a FRESH pilot via its own vendor
35
+ # CLI to read the wire and reply. Both pilots, no setup.
36
+ indelible-mcp drift pause | resume # YOUR brake — freezes everything, works with no wallet
37
+ indelible-mcp drift listen "stop, listen" # freeze both AND hand them your message
38
+ ```
39
+
40
+ Three delivery layers, honestly labeled: the **bell** wakes a seat that is holding the wire
41
+ (measured 185ms against a 20s poll); the **summoner** answers for an idle seat by conjuring a
42
+ fresh instance — the permanent shared memory means it arrives already caught up; and your
43
+ **brake** outranks all of it. Summons cost real usage on your vendor account: the summoner
44
+ carries a per-run cap, a cooldown, one-in-flight per seat, and logs every summon. Full manual:
45
+ indelible.one → Docs → The Drift Wire.
46
+
47
+ **Summoned Sessions in your Context tab.** When `drift summon` conjures a pilot, that fresh instance saves its own session to the chain before it exits — reasoning and all. Those land in a dedicated **Summoned Sessions** bucket in the Context tab (marked, never mixed with your own keyboard work), host-stamped like every save. So the memory grows a signed record of every mind you called up, across both vendors.
48
+
49
+ ## Quick Reference
50
+
51
+ ### Save Session
52
+ ```bash
53
+ node C:/Indelible-main/indelible-cli/src/index.js save --summary "what happened"
54
+ ```
55
+
56
+ ### Load from Blockchain
57
+ ```bash
58
+ node C:/Indelible-main/indelible-cli/src/index.js load --sessions=5
59
+ ```
60
+
61
+ ### Check Status
62
+ ```bash
63
+ node C:/Indelible-main/indelible-cli/src/index.js status
64
+ ```
65
+
66
+ ### Save a File
67
+ ```bash
68
+ node C:/Indelible-main/indelible-cli/src/index.js vault save-file /path/to/file.js
69
+ ```
70
+
71
+ ### Ask Codex
72
+ ```bash
73
+ node C:/Indelible-main/indelible-cli/src/index.js diary chat "How should we architect this?"
74
+ ```
75
+
76
+ ---
77
+
78
+ ## All Commands
79
+
80
+ ### Sessions
81
+ ```
82
+ save Save current session to blockchain
83
+ save --summary "note" Save with custom summary
84
+ load Load context from blockchain (default: 5 sessions)
85
+ load --sessions=10 Load N sessions
86
+ status Show wallet address, API key, last session
87
+ ```
88
+
89
+ ### Code Vault
90
+ ```
91
+ vault save-file <path> Save a file (encrypted, chunked if >50KB)
92
+ vault save-project <dir> [--name=NAME] Save a project directory
93
+ vault load-file <txid> [--output=path] Load a file from blockchain
94
+ vault load-project <txid> [--output-dir=dir] Load a project from blockchain
95
+ vault save-style <file> [--name=N] [--desc=D] Save an AI style to blockchain
96
+ vault load-style [txid] Load an AI style from blockchain
97
+ vault update-index Update on-chain vault index
98
+ ```
99
+
100
+ ### Diary AI (Dual-Agent)
101
+ ```
102
+ diary connect --key=SK [--model=MODEL] [--name=NAME] Connect OpenAI companion
103
+ diary chat "message" Ask the AI companion
104
+ diary save [--summary="..."] Save exchange to blockchain
105
+ ```
106
+
107
+ ### Setup & Hooks
108
+ ```
109
+ setup --wif=KEY --pin=PIN Import and encrypt your private key
110
+ install-hooks Install auto-save/restore hooks into Claude Code
111
+ hook pre-compact Auto-save before compaction (called by hook)
112
+ hook post-compact Auto-restore after compaction (called by hook)
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Relationship to MCP
118
+
119
+ The CLI and MCP server are the **same codebase**. They import the same tool functions (`saveSession`, `loadContext`, `saveFile`, `diaryChat`, etc.) and use the same wallet at `~/.indelible/config.json`.
120
+
121
+ | | CLI | MCP Server |
122
+ |---|---|---|
123
+ | **Location** | `C:/Indelible-main/indelible-cli/src/` | `C:/bsv-claude-wrapper/mcp-server/` |
124
+ | **Config** | Sync (`readFileSync`/`writeFileSync`) | Async (`await loadConfig()`) |
125
+ | **Fetch** | Native `fetch` (Node 18+) | `node-fetch` package |
126
+ | **Timeout** | `AbortSignal.timeout(ms)` | Manual `AbortController` + `setTimeout` |
127
+ | **Entry point** | CLI arg parser in `index.js` | JSON-RPC stdin/stdout in `index.js` |
128
+ | **How Claude calls it** | `node src/index.js <command>` | MCP protocol via Claude Code hooks |
129
+
130
+ **Sync rule:** Any feature, fix, or change that goes into one MUST go into both. No exceptions. Adapt sync/async config pattern accordingly.
131
+
132
+ ---
133
+
134
+ ## Testing / Dog-Fooding
135
+
136
+ The CLI is a live test harness for the MCP. When you test a CLI command, you're testing the exact same function the MCP calls.
137
+
138
+ ### Safe tests (no sats spent)
139
+ ```bash
140
+ # Config loads correctly
141
+ node C:/Indelible-main/indelible-cli/src/index.js status
142
+
143
+ # Blockchain read works
144
+ node C:/Indelible-main/indelible-cli/src/index.js load --sessions=1
145
+
146
+ # Style loads from chain
147
+ node C:/Indelible-main/indelible-cli/src/index.js vault load-style
148
+ ```
149
+
150
+ ### Function-level tests (no sats spent)
151
+ ```bash
152
+ cd "C:/Indelible-main/indelible-cli" && node --input-type=module -e "
153
+ import { checkConfirmation } from './src/lib/spv.js';
154
+ const r = await checkConfirmation('TXID_HERE');
155
+ console.log(JSON.stringify(r, null, 2));
156
+ " 2>&1
157
+
158
+ cd "C:/Indelible-main/indelible-cli" && node --input-type=module -e "
159
+ import { checkTier } from './src/lib/api-client.js';
160
+ import { loadConfig } from './src/lib/config.js';
161
+ const config = loadConfig();
162
+ const r = await checkTier(config.api_key);
163
+ console.log(JSON.stringify(r, null, 2));
164
+ " 2>&1
165
+
166
+ cd "C:/Indelible-main/indelible-cli" && node --input-type=module -e "
167
+ import { verifyRecentSaves } from './src/tools/save_file.js';
168
+ const r = await verifyRecentSaves();
169
+ console.log(JSON.stringify(r, null, 2));
170
+ " 2>&1
171
+ ```
172
+
173
+ ### Live tests (spends sats)
174
+ ```bash
175
+ # Session save (delta if prior save exists)
176
+ node C:/Indelible-main/indelible-cli/src/index.js save --summary "test save"
177
+
178
+ # File save
179
+ node C:/Indelible-main/indelible-cli/src/index.js vault save-file /path/to/small/file.txt
180
+
181
+ # Style save (auto-prepends core rules via ensureCoreRules)
182
+ node C:/Indelible-main/indelible-cli/src/index.js vault save-style /path/to/rules.txt --name=test
183
+
184
+ # Diary chat (costs OpenAI tokens, not sats)
185
+ node C:/Indelible-main/indelible-cli/src/index.js diary chat "hello"
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Architecture
191
+
192
+ ```
193
+ indelible-cli/src/
194
+ ├── index.js CLI arg parser + MCP JSON-RPC server (dual mode)
195
+ ├── lib/
196
+ │ ├── config.js Sync config: loadConfig(), saveConfig(), getWif()
197
+ │ ├── crypto.js AES-256-GCM encrypt/decrypt, SHA-256, WIF derivation
198
+ │ ├── spv.js Multi-bridge SPV client, UTXO chaining, health tracking
199
+ │ └── api-client.js commitSession(), getLatestSessions(), checkTier()
200
+ ├── tools/
201
+ │ ├── save_session.js Parse transcript, delta detect, encrypt, broadcast
202
+ │ │ + getRecentPlans() — scans ~/.claude/plans/
203
+ │ │ + updateMemory() — MEMORY.md hierarchy enforcement
204
+ │ │ + dashboard sync — PATCH to indelible.one
205
+ │ ├── load_context.js Fetch + decrypt + merge deltas + smart format
206
+ │ ├── setup_wallet.js Generate BSV keypair, encrypt WIF with PIN
207
+ │ ├── save_file.js Encrypt + broadcast file (chunked if >50KB)
208
+ │ │ + cacheTx() — local backup for re-broadcast
209
+ │ │ + verifyRecentSaves() — check confirmations
210
+ │ ├── save_project.js Walk dir + save each file + broadcast manifest
211
+ │ │ + cacheTx() — local backup for re-broadcast
212
+ │ ├── load_file.js Fetch + decrypt file from blockchain
213
+ │ ├── load_project.js Fetch manifest + decrypt + restore files
214
+ │ ├── save_style.js Encrypt style rules + broadcast
215
+ │ │ + ensureCoreRules() — auto-prepend core rules
216
+ │ ├── load_style.js Fetch + decrypt style from blockchain
217
+ │ ├── update_vault_index.js Update on-chain file/project index
218
+ │ ├── diary_connect.js Store OpenAI API key in config
219
+ │ ├── diary_chat.js Send message to Codex via OpenAI API
220
+ │ │ + blockchain history loading (last 3 sessions)
221
+ │ └── diary_save.js Save diary exchange to blockchain
222
+ └── dist/
223
+ └── indelible.exe Compiled standalone (bun build --compile)
224
+ ```
225
+
226
+ ### Key Internal Features
227
+
228
+ | Feature | What It Does |
229
+ |---|---|
230
+ | **Bridge health tracking** | Tracks success/failure per SPV bridge, skips unhealthy ones |
231
+ | **UTXO chaining** | Back-to-back saves chain change outputs — no mempool conflicts |
232
+ | **Delta saves** | Only commits new messages since last save |
233
+ | **tx-cache** | Caches broadcast payloads to `~/.indelible/tx-cache/` for re-broadcast |
234
+ | **MEMORY.md enforcement** | Strips rules, archives done items, enforces 200-line / 20-line limits |
235
+ | **Core rules injection** | `ensureCoreRules()` auto-prepends infrastructure rules to every style |
236
+ | **Diary history** | `diary chat` loads last 3 blockchain sessions for conversation continuity |
237
+ | **Dashboard sync** | PATCHes indelible.one after every save |
238
+
239
+ ---
240
+
241
+ ## Rebuild the Executable
242
+
243
+ ```bash
244
+ cd "C:/Indelible-main/indelible-cli" && bun build --compile src/index.js --outfile dist/indelible.exe
245
+ ```
246
+
247
+ This creates a standalone `indelible.exe` — no Node.js required on the target machine.
248
+
249
+ ---
250
+
251
+ ## Common Errors
252
+
253
+ | Error | Cause | Fix |
254
+ |-------|-------|-----|
255
+ | `Wallet not configured` | No config.json or no WIF | Run `setup --wif=KEY --pin=PIN` |
256
+ | `No UTXOs available` | Wallet is empty | Send BSV to your address |
257
+ | `Broadcast failed on all bridges` | All 4 SPV relays down or rejecting | Check relay health, wait and retry |
258
+ | `No new messages since last save` | Already saved this transcript | Nothing to do — this is fine |
259
+ | `File not found` | Bad path or backslashes | Use forward slashes: `C:/path/to/file` |
260
+ | `Decrypt failed` | Wrong WIF or tampered data | Check `~/.indelible/config.json` has correct WIF |
261
+ | `txn-mempool-conflict` | Spending already-spent UTXO | UTXO chaining should prevent this — check code |
262
+ | `OpenAI rate limit exceeded` | Too many diary chat calls | Wait a moment and retry |
263
+ | `Diary AI not configured` | No OpenAI key | Run `diary connect --key=SK` |
264
+
265
+ ---
266
+
267
+ ## Config File
268
+
269
+ `C:/Users/oorel/.indelible/config.json` — shared with MCP server.
270
+
271
+ | Setting | Description |
272
+ |---------|-------------|
273
+ | `wif` or `wif_encrypted` | BSV private key (plaintext or PIN-encrypted) |
274
+ | `address` | BSV address (derived from WIF) |
275
+ | `spv_bridges` | Array of `{url, name}` relay objects |
276
+ | `api_url` | Indelible web app URL (`https://indelible.one`) |
277
+ | `api_key` | API key for authenticated endpoints |
278
+ | `auto_delta` | Auto-save every N messages (bool) |
279
+ | `auto_delta_interval` | Messages between auto-saves (default: 10) |
280
+ | `file_txids` | *(auto)* Index of files saved to chain |
281
+ | `project_txids` | *(auto)* Index of projects saved to chain |
282
+ | `last_session_id` | *(auto)* Previous session for chaining |
283
+ | `last_tx_id` | *(auto)* Last committed tx |
284
+ | `diary` | `{ apiKey, model, name }` — OpenAI companion config |
285
+
286
+ ---
287
+
288
+ ## Wallet
289
+
290
+ - **Address:** shown by `indelible-mcp status` (yours is generated at setup and lives in `~/.indelible/config.json` — back that file up)
291
+ - **Balance:** `indelible-mcp status`, or look your address up in the Chain Browser at indelible.one/explorer
292
+ - **Fund it:** Send BSV to your own address
293
+ - **Cost:** ~$0.21/MB at BSV=$16. Session saves are fractions of a cent.