@jhizzard/termdeck 0.2.1 → 0.2.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.
package/README.md CHANGED
@@ -26,7 +26,7 @@ Enabling Flashback takes **one additional 15-minute setup step** — see Tier 2
26
26
 
27
27
  ## How Flashback works
28
28
 
29
- When a panel's status transitions to `errored`, the server's output analyzer fires an event. The engram bridge takes the session context (type, project, last command, error tail) and queries your Engram memory store for the top similar match. If it finds one above the relevance threshold, the result is pushed to the panel's WebSocket as a `proactive_memory` message. The client renders it as a toast anchored to the panel, showing the match's project tag, source type, similarity score, and content snippet. You click the toast to expand into the Memory tab of that panel's drawer.
29
+ When a panel's status transitions to `errored`, the server's output analyzer fires an event. The mnestra bridge takes the session context (type, project, last command, error tail) and queries your Mnestra memory store for the top similar match. If it finds one above the relevance threshold, the result is pushed to the panel's WebSocket as a `proactive_memory` message. The client renders it as a toast anchored to the panel, showing the match's project tag, source type, similarity score, and content snippet. You click the toast to expand into the Memory tab of that panel's drawer.
30
30
 
31
31
  Rate-limited to once per 30 seconds per panel. Needs RAG enabled and credentials configured (Tier 2+). Fires on **any** terminal panel — shell, Claude Code, Python server, anything.
32
32
 
@@ -39,8 +39,8 @@ TermDeck is one piece of a three-tier memory stack. Each tier adds capability; e
39
39
  | Tier | Install time | What you get |
40
40
  |---|---|---|
41
41
  | **1 — TermDeck alone** | 90 seconds | Full multiplexer, metadata, layouts, themes, tour, session history, command logging. Flashback silent. |
42
- | **2 — + Engram memory store** | ~15 minutes | Flashback actively fires. Cross-session recall. "Ask about this terminal" queries real memories. Optional Engram-as-MCP for Claude Code / Cursor / Windsurf. |
43
- | **3 — + Rumen async learning** | ~30 minutes | Async learning layer runs on a cron, synthesizes insights across projects, writes them back into Engram. Flashback starts surfacing cross-project patterns, not just direct matches. |
42
+ | **2 — + Mnestra memory store** | ~15 minutes | Flashback actively fires. Cross-session recall. "Ask about this terminal" queries real memories. Optional Mnestra-as-MCP for Claude Code / Cursor / Windsurf. |
43
+ | **3 — + Rumen async learning** | ~30 minutes | Async learning layer runs on a cron, synthesizes insights across projects, writes them back into Mnestra. Flashback starts surfacing cross-project patterns, not just direct matches. |
44
44
 
45
45
  ### Tier 1 — `npx @jhizzard/termdeck` (you're here)
46
46
 
@@ -61,22 +61,22 @@ What's included:
61
61
 
62
62
  What's excluded at this tier: **Flashback is silent**, the "Ask about this terminal" input returns nothing, and no memories are surfaced. All other features work.
63
63
 
64
- ### Tier 2 — Add Engram to light up Flashback
64
+ ### Tier 2 — Add Mnestra to light up Flashback
65
65
 
66
- Engram is a separate npm package — `@jhizzard/engram@0.2.0` — that ships a Postgres-backed persistent memory store with an MCP server, a webhook server, six search tools, and six SQL migrations. It can be consumed by TermDeck (for Flashback), by Claude Code (as an MCP memory layer), or by any tool that speaks the MCP protocol.
66
+ Mnestra is a separate npm package — `@jhizzard/mnestra@0.2.0` — that ships a Postgres-backed persistent memory store with an MCP server, a webhook server, six search tools, and six SQL migrations. It can be consumed by TermDeck (for Flashback), by Claude Code (as an MCP memory layer), or by any tool that speaks the MCP protocol.
67
67
 
68
68
  To enable Flashback in TermDeck:
69
69
 
70
70
  1. **Provision Postgres with pgvector.** Easiest: create a free Supabase project at supabase.com. Copy the **Project URL** and the **service_role key** from Project Settings → API.
71
- 2. **Apply Engram's migrations** to the database. Run each in order via the Supabase SQL Editor, or via `psql`:
71
+ 2. **Apply Mnestra's migrations** to the database. Run each in order via the Supabase SQL Editor, or via `psql`:
72
72
  ```bash
73
- npm install -g @jhizzard/engram
74
- psql "$DATABASE_URL" -f node_modules/@jhizzard/engram/migrations/001_engram_tables.sql
75
- psql "$DATABASE_URL" -f node_modules/@jhizzard/engram/migrations/002_engram_search_function.sql
76
- psql "$DATABASE_URL" -f node_modules/@jhizzard/engram/migrations/003_engram_event_webhook.sql
77
- psql "$DATABASE_URL" -f node_modules/@jhizzard/engram/migrations/004_engram_match_count_cap_and_explain.sql
78
- psql "$DATABASE_URL" -f node_modules/@jhizzard/engram/migrations/005_v0_1_to_v0_2_upgrade.sql
79
- psql "$DATABASE_URL" -f node_modules/@jhizzard/engram/migrations/006_memory_status_rpc.sql
73
+ npm install -g @jhizzard/mnestra
74
+ psql "$DATABASE_URL" -f node_modules/@jhizzard/mnestra/migrations/001_mnestra_tables.sql
75
+ psql "$DATABASE_URL" -f node_modules/@jhizzard/mnestra/migrations/002_mnestra_search_function.sql
76
+ psql "$DATABASE_URL" -f node_modules/@jhizzard/mnestra/migrations/003_mnestra_event_webhook.sql
77
+ psql "$DATABASE_URL" -f node_modules/@jhizzard/mnestra/migrations/004_mnestra_match_count_cap_and_explain.sql
78
+ psql "$DATABASE_URL" -f node_modules/@jhizzard/mnestra/migrations/005_v0_1_to_v0_2_upgrade.sql
79
+ psql "$DATABASE_URL" -f node_modules/@jhizzard/mnestra/migrations/006_memory_status_rpc.sql
80
80
  ```
81
81
  3. **Get an OpenAI API key** (text-embedding-3-large).
82
82
  4. **Create `~/.termdeck/secrets.env`:**
@@ -93,18 +93,18 @@ To enable Flashback in TermDeck:
93
93
  supabaseUrl: ${SUPABASE_URL}
94
94
  supabaseKey: ${SUPABASE_SERVICE_ROLE_KEY}
95
95
  openaiApiKey: ${OPENAI_API_KEY}
96
- engramMode: direct
96
+ mnestraMode: direct
97
97
  ```
98
98
  6. **Restart TermDeck** (`Ctrl+C`, then `npx @jhizzard/termdeck` again).
99
99
 
100
100
  Flashback now fires when panels error. Initially your store is empty, so nothing surfaces. As you use TermDeck day-to-day, the output analyzer captures session events, command history, and error contexts — each one becomes a memory. After a few days of real work, Flashback starts surfacing real hits.
101
101
 
102
- ### Tier 2 bonus — Engram as a Claude Code MCP server
102
+ ### Tier 2 bonus — Mnestra as a Claude Code MCP server
103
103
 
104
- Independently of TermDeck, install Engram as an MCP server so Claude Code (and Cursor / Windsurf / Cline / Continue) have persistent memory across sessions pointing at the same database TermDeck uses:
104
+ Independently of TermDeck, install Mnestra as an MCP server so Claude Code (and Cursor / Windsurf / Cline / Continue) have persistent memory across sessions pointing at the same database TermDeck uses:
105
105
 
106
106
  ```bash
107
- npm install -g @jhizzard/engram
107
+ npm install -g @jhizzard/mnestra
108
108
  ```
109
109
 
110
110
  Edit `~/.claude/mcp.json`:
@@ -112,8 +112,8 @@ Edit `~/.claude/mcp.json`:
112
112
  ```json
113
113
  {
114
114
  "mcpServers": {
115
- "engram": {
116
- "command": "engram",
115
+ "mnestra": {
116
+ "command": "mnestra",
117
117
  "env": {
118
118
  "SUPABASE_URL": "https://your-project.supabase.co",
119
119
  "SUPABASE_SERVICE_ROLE_KEY": "sb_secret_...",
@@ -125,11 +125,11 @@ Edit `~/.claude/mcp.json`:
125
125
  }
126
126
  ```
127
127
 
128
- Restart Claude Code. Six MCP tools appear: `memory_remember`, `memory_recall`, `memory_search`, `memory_forget`, `memory_status`, `memory_summarize_session`. Your AI assistant can now read and write memories that TermDeck's Flashback will later surface automatically. See [github.com/jhizzard/engram](https://github.com/jhizzard/engram) for full MCP reference.
128
+ Restart Claude Code. Six MCP tools appear: `memory_remember`, `memory_recall`, `memory_search`, `memory_forget`, `memory_status`, `memory_summarize_session`. Your AI assistant can now read and write memories that TermDeck's Flashback will later surface automatically. See [github.com/jhizzard/mnestra](https://github.com/jhizzard/mnestra) for full MCP reference.
129
129
 
130
130
  ### Tier 3 — Add Rumen for async learning
131
131
 
132
- Rumen is a separate npm package — `@jhizzard/rumen@0.2.0` — that ships as a Supabase Edge Function designed to run on a 15-minute `pg_cron` schedule. It's the async reflection layer over Engram: it reads recent session memories, cross-references them with your entire historical corpus via hybrid search, synthesizes insights via Claude Haiku, and writes the results back into `rumen_insights` (a new table alongside Engram's `memory_items`). TermDeck's Flashback and Claude Code's `memory_recall` both automatically benefit because insights flow back into the same database.
132
+ Rumen is a separate npm package — `@jhizzard/rumen@0.2.0` — that ships as a Supabase Edge Function designed to run on a 15-minute `pg_cron` schedule. It's the async reflection layer over Mnestra: it reads recent session memories, cross-references them with your entire historical corpus via hybrid search, synthesizes insights via Claude Haiku, and writes the results back into `rumen_insights` (a new table alongside Mnestra's `memory_items`). TermDeck's Flashback and Claude Code's `memory_recall` both automatically benefit because insights flow back into the same database.
133
133
 
134
134
  Rumen v0.2 is the current shipped version. Setup is still manual — Sprint 3 (next) ships a `termdeck init --rumen` one-liner that automates the deploy. For now, follow [github.com/jhizzard/rumen#readme](https://github.com/jhizzard/rumen) to deploy via the Supabase CLI.
135
135
 
@@ -162,12 +162,12 @@ Honest limits, stated upfront so the skeptic has nothing to chase:
162
162
  │ - Express + ws │
163
163
  │ - node-pty per session │
164
164
  │ - SQLite persistence │
165
- │ - Engram bridge (direct/webhook/mcp) │
165
+ │ - Mnestra bridge (direct/webhook/mcp) │
166
166
  └─────────────────┬───────────────────────┘
167
167
  │ hybrid search + embeddings
168
168
 
169
169
  ┌─────────────────────────────────────────┐
170
- Engram
170
+ Mnestra
171
171
  │ - Postgres + pgvector │
172
172
  │ - MCP server (6 tools) │
173
173
  │ - HTTP webhook │
@@ -183,7 +183,7 @@ Honest limits, stated upfront so the skeptic has nothing to chase:
183
183
  └─────────────────────────────────────────┘
184
184
  ```
185
185
 
186
- All three packages are independent. You can use Engram alone as a Claude Code memory layer. You can run Rumen on any pgvector store with compatible schema. You can use TermDeck with zero memory features. The stack is designed to be progressively adopted.
186
+ All three packages are independent. You can use Mnestra alone as a Claude Code memory layer. You can run Rumen on any pgvector store with compatible schema. You can use TermDeck with zero memory features. The stack is designed to be progressively adopted.
187
187
 
188
188
  ---
189
189
 
@@ -201,7 +201,7 @@ For users who want more than `npx` — cloning from source, building a macOS `.a
201
201
 
202
202
  ## Related packages
203
203
 
204
- - **[@jhizzard/engram](https://www.npmjs.com/package/@jhizzard/engram)** — persistent dev memory MCP server. pgvector + hybrid search + 3-layer progressive disclosure. Works standalone with any MCP client.
204
+ - **[@jhizzard/mnestra](https://www.npmjs.com/package/@jhizzard/mnestra)** — persistent dev memory MCP server. pgvector + hybrid search + 3-layer progressive disclosure. Works standalone with any MCP client.
205
205
  - **[@jhizzard/rumen](https://www.npmjs.com/package/@jhizzard/rumen)** — async learning layer. Extract/Relate/Synthesize loop over any pgvector store. Supabase Edge Function + `pg_cron`.
206
206
 
207
207
  ---
@@ -218,7 +218,7 @@ npm run dev
218
218
  The server runs at `http://127.0.0.1:3000` with file-watch reload. Workspace layout:
219
219
 
220
220
  - `packages/cli/src/` — the `termdeck` binary launcher
221
- - `packages/server/src/` — Express + WebSocket + PTY + Engram bridge + session analyzer
221
+ - `packages/server/src/` — Express + WebSocket + PTY + Mnestra bridge + session analyzer
222
222
  - `packages/client/public/` — vanilla-JS dashboard (single HTML file, no build step, loads xterm.js from CDN)
223
223
  - `config/` — example `config.yaml` and `secrets.env.example`
224
224
  - `docs/` — planning documents, launch strategy, install guide, followup items, ship checklist
@@ -258,7 +258,7 @@ MIT © Joshua Izzard. See [LICENSE](LICENSE).
258
258
  - GitHub: [github.com/jhizzard/termdeck](https://github.com/jhizzard/termdeck)
259
259
  - npm: [@jhizzard/termdeck](https://www.npmjs.com/package/@jhizzard/termdeck)
260
260
  - Issues: [github.com/jhizzard/termdeck/issues](https://github.com/jhizzard/termdeck/issues)
261
- - Engram: [github.com/jhizzard/engram](https://github.com/jhizzard/engram) · [npm](https://www.npmjs.com/package/@jhizzard/engram)
261
+ - Mnestra: [github.com/jhizzard/mnestra](https://github.com/jhizzard/mnestra) · [npm](https://www.npmjs.com/package/@jhizzard/mnestra)
262
262
  - Rumen: [github.com/jhizzard/rumen](https://github.com/jhizzard/rumen) · [npm](https://www.npmjs.com/package/@jhizzard/rumen)
263
263
 
264
264
  Built because every LLM starts from zero, and every terminal starts from zero, and I got tired of re-debugging the same CORS error.
@@ -35,20 +35,20 @@ rag:
35
35
  # developerId: your-username (defaults to OS username)
36
36
  syncIntervalMs: 10000
37
37
 
38
- # Engram bridge — how /api/ai/query talks to @jhizzard/engram.
38
+ # Mnestra bridge — how /api/ai/query talks to @jhizzard/mnestra.
39
39
  # direct — server embeds + queries Supabase itself (default, preserves v0.1 behavior)
40
- # webhook — POST to a running `engram serve` HTTP webhook (see engramWebhookUrl)
41
- # mcp — spawn the local `engram` binary and talk JSON-RPC over stdio
42
- engramMode: direct
43
- engramWebhookUrl: http://localhost:37778/engram
44
- # engramBinary: engram # override path to the @jhizzard/engram CLI for mcp mode
40
+ # webhook — POST to a running `mnestra serve` HTTP webhook (see mnestraWebhookUrl)
41
+ # mcp — spawn the local `mnestra` binary and talk JSON-RPC over stdio
42
+ mnestraMode: direct
43
+ mnestraWebhookUrl: http://localhost:37778/mnestra
44
+ # mnestraBinary: mnestra # override path to the @jhizzard/mnestra CLI for mcp mode
45
45
 
46
46
  # Supabase table names (created by config/supabase-migration.sql)
47
47
  tables:
48
- session: engram_session_memory
49
- project: engram_project_memory
50
- developer: engram_developer_memory
51
- commands: engram_commands
48
+ session: mnestra_session_memory
49
+ project: mnestra_project_memory
50
+ developer: mnestra_developer_memory
51
+ commands: mnestra_commands
52
52
 
53
53
  # Per-session markdown logs written to ~/.termdeck/sessions/ on session exit.
54
54
  # Zero-config: works without Supabase / OpenAI. Optional LLM summary requires
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jhizzard/termdeck",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Browser-based terminal multiplexer with metadata overlays, panel flashback memory recall, and AI-aware session management",
5
5
  "bin": {
6
6
  "termdeck": "./packages/cli/src/index.js"
@@ -3,8 +3,13 @@
3
3
  // TermDeck CLI launcher
4
4
  // Usage:
5
5
  // termdeck [--port 3000] [--no-open]
6
- // termdeck init --engram [flags]
7
- // termdeck init --rumen [flags]
6
+ // termdeck init --mnestra [flags] # Tier 2 memory setup (wired to init-mnestra.js)
7
+ // termdeck init --rumen [flags] # Tier 3 async learning deploy
8
+ //
9
+ // Note (Sprint 3): the `--mnestra` flag name matches the current init-mnestra.js
10
+ // filename. When the main orchestrator completes the Mnestra → Ingram rename
11
+ // sweep over this repo, both the flag name and the filename should flip to
12
+ // `--ingram` / `init-ingram.js` together.
8
13
 
9
14
  const path = require('path');
10
15
  const { execSync } = require('child_process');
@@ -12,10 +17,10 @@ const { execSync } = require('child_process');
12
17
  // Parse CLI args
13
18
  const args = process.argv.slice(2);
14
19
 
15
- // Subcommand dispatch — handle `termdeck init --engram|--rumen` before
16
- // falling through to the default launcher's flag parsing. This lives above
17
- // the launcher so `require('./init-*')` is lazy users running the normal
18
- // `termdeck` command never pay the cost of loading pg / supabase helpers.
20
+ // Subcommand dispatch — handle `termdeck init --mnestra|--rumen` before
21
+ // falling through to the default launcher's flag parsing. The `require` of
22
+ // init-*.js is lazy so users running the normal `termdeck` command never pay
23
+ // the cost of loading pg / supabase helpers at startup.
19
24
  if (args[0] === 'init') {
20
25
  const mode = args[1];
21
26
  const rest = args.slice(2);
@@ -23,9 +28,9 @@ if (args[0] === 'init') {
23
28
  const fn = require(modPath);
24
29
  return fn(rest).then((code) => process.exit(code || 0));
25
30
  };
26
- if (mode === '--engram') {
27
- run(path.join(__dirname, 'init-engram.js')).catch((err) => {
28
- console.error('[cli] init --engram failed:', err && err.stack || err);
31
+ if (mode === '--mnestra') {
32
+ run(path.join(__dirname, 'init-mnestra.js')).catch((err) => {
33
+ console.error('[cli] init --mnestra failed:', err && err.stack || err);
29
34
  process.exit(1);
30
35
  });
31
36
  return;
@@ -37,8 +42,8 @@ if (args[0] === 'init') {
37
42
  });
38
43
  return;
39
44
  }
40
- console.error('Usage: termdeck init --engram | --rumen');
41
- console.error(' termdeck init --engram Configure Tier 2 memory (Supabase + Engram)');
45
+ console.error('Usage: termdeck init --mnestra | --rumen');
46
+ console.error(' termdeck init --mnestra Configure Tier 2 memory (Supabase + Ingram)');
42
47
  console.error(' termdeck init --rumen Deploy Tier 3 async learning (Rumen)');
43
48
  process.exit(1);
44
49
  }
@@ -61,7 +66,7 @@ for (let i = 0; i < args.length; i++) {
61
66
  termdeck --port 8080 Start on custom port
62
67
  termdeck --no-open Don't auto-open browser
63
68
  termdeck --session-logs Write per-session markdown logs to ~/.termdeck/sessions/
64
- termdeck init --engram Configure Tier 2 memory (Supabase + Engram)
69
+ termdeck init --mnestra Configure Tier 2 memory (Supabase + Ingram)
65
70
  termdeck init --rumen Deploy Tier 3 async learning (Rumen)
66
71
 
67
72
  Keyboard shortcuts (in browser):
@@ -2,13 +2,13 @@
2
2
 
3
3
  // `termdeck init --rumen` — interactive wizard for deploying Rumen as a
4
4
  // Supabase Edge Function + pg_cron schedule against the same Supabase
5
- // project that holds the Engram store.
5
+ // project that holds the Mnemos store.
6
6
  //
7
7
  // Requirements checked at runtime:
8
8
  // - `supabase` CLI on PATH
9
9
  // - `deno` on PATH
10
10
  // - `~/.termdeck/secrets.env` with SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY +
11
- // DATABASE_URL + ANTHROPIC_API_KEY populated (run `termdeck init --engram` first)
11
+ // DATABASE_URL + ANTHROPIC_API_KEY populated (run `termdeck init --mnemos` first)
12
12
  //
13
13
  // Steps:
14
14
  // 1. Preflight: which supabase, which deno, read secrets.env
@@ -47,7 +47,7 @@ const HELP = [
47
47
  ' --skip-schedule Deploy the function but do not install the pg_cron schedule',
48
48
  '',
49
49
  'Requires: Supabase CLI and Deno already installed.',
50
- 'Requires: `termdeck init --engram` has already run (needs secrets.env).',
50
+ 'Requires: `termdeck init --mnemos` has already run (needs secrets.env).',
51
51
  ''
52
52
  ].join('\n');
53
53
 
@@ -112,14 +112,14 @@ function preflight() {
112
112
  }
113
113
  ok();
114
114
 
115
- step('Reading Engram config from ~/.termdeck/secrets.env...');
115
+ step('Reading Mnemos config from ~/.termdeck/secrets.env...');
116
116
  const secrets = dotenv.readSecrets();
117
117
  const required = ['SUPABASE_URL', 'SUPABASE_SERVICE_ROLE_KEY', 'DATABASE_URL', 'ANTHROPIC_API_KEY'];
118
118
  const missing = required.filter((k) => !secrets[k]);
119
119
  if (missing.length > 0) {
120
120
  fail(`missing keys: ${missing.join(', ')}`);
121
121
  process.stderr.write(
122
- '\nRun `termdeck init --engram` first — it writes the keys this wizard needs.\n'
122
+ '\nRun `termdeck init --mnemos` first — it writes the keys this wizard needs.\n'
123
123
  );
124
124
  return null;
125
125
  }
@@ -363,7 +363,7 @@ Next steps:
363
363
  1. Monitor: psql "$DATABASE_URL" -c "SELECT * FROM rumen_jobs ORDER BY started_at DESC LIMIT 5"
364
364
  2. Store the service_role key in Supabase Vault as \`rumen_service_role_key\`
365
365
  so the cron call in migrations/002_pg_cron_schedule.sql can authenticate.
366
- 3. Rumen insights flow back into Engram's memory_items via rumen_insights.
366
+ 3. Rumen insights flow back into Mnemos's memory_items via rumen_insights.
367
367
  4. TermDeck's Flashback will surface cross-project patterns automatically.
368
368
  `);
369
369
  }
@@ -1901,7 +1901,7 @@
1901
1901
 
1902
1902
  toast.innerHTML = `
1903
1903
  <button class="t-dismiss" aria-label="Dismiss">×</button>
1904
- <div class="t-title">Engram — possible match</div>
1904
+ <div class="t-title">Mnestra — possible match</div>
1905
1905
  <div class="t-body">Found a similar error in <b>${proj}</b>${score ? ` · ${score}` : ''} — click to see.</div>
1906
1906
  <div class="t-meta">${snippet}</div>
1907
1907
  `;
@@ -2596,7 +2596,7 @@
2596
2596
  // Early return if AI queries are not available
2597
2597
  if (!state.config.aiQueryAvailable) {
2598
2598
  entry.terminal.write(
2599
- '\r\n\x1b[33m[engram] AI queries are not available.\x1b[0m\r\n' +
2599
+ '\r\n\x1b[33m[mnestra] AI queries are not available.\x1b[0m\r\n' +
2600
2600
  '\x1b[33mTo enable, add the following to ~/.termdeck/config.yaml:\x1b[0m\r\n' +
2601
2601
  '\x1b[90m rag:\r\n' +
2602
2602
  ' supabaseUrl: https://your-project.supabase.co\r\n' +
@@ -2618,7 +2618,7 @@
2618
2618
  });
2619
2619
 
2620
2620
  if (result.error) {
2621
- entry.terminal.write(`\r\n\x1b[33m[engram] ${result.error}\x1b[0m\r\n`);
2621
+ entry.terminal.write(`\r\n\x1b[33m[mnestra] ${result.error}\x1b[0m\r\n`);
2622
2622
  } else if (result.memories && result.memories.length > 0) {
2623
2623
  // Cache hits for the Memory tab
2624
2624
  if (!entry.memoryHits) entry.memoryHits = [];
@@ -2651,7 +2651,7 @@
2651
2651
  return lines;
2652
2652
  };
2653
2653
 
2654
- entry.terminal.write(`\r\n\x1b[36m━━━ Engram: ${result.total} memories found ━━━\x1b[0m\r\n`);
2654
+ entry.terminal.write(`\r\n\x1b[36m━━━ Mnestra: ${result.total} memories found ━━━\x1b[0m\r\n`);
2655
2655
  for (const m of result.memories) {
2656
2656
  const score = m.similarity ? `${(m.similarity * 100).toFixed(0)}%` : '';
2657
2657
  const proj = m.project ? m.project : '';
@@ -2663,11 +2663,11 @@
2663
2663
  }
2664
2664
  entry.terminal.write(`\r\n\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\r\n\r\n`);
2665
2665
  } else {
2666
- entry.terminal.write(`\r\n\x1b[33m[engram] No relevant memories found.\x1b[0m\r\n`);
2666
+ entry.terminal.write(`\r\n\x1b[33m[mnestra] No relevant memories found.\x1b[0m\r\n`);
2667
2667
  }
2668
2668
  } catch (err) {
2669
2669
  console.error('[client] AI query failed:', err);
2670
- entry.terminal.write(`\r\n\x1b[31m[engram] Query failed: ${err.message}\x1b[0m\r\n`);
2670
+ entry.terminal.write(`\r\n\x1b[31m[mnestra] Query failed: ${err.message}\x1b[0m\r\n`);
2671
2671
  }
2672
2672
 
2673
2673
  inputEl.value = '';
@@ -3073,14 +3073,14 @@
3073
3073
  {
3074
3074
  target: '.ctrl-input',
3075
3075
  title: 'Ask about this terminal',
3076
- body: `Type a question here and TermDeck queries your <strong>Engram memory store</strong> for relevant context — scoped to the current panel's project. Prefix with <kbd>all:</kbd> to search every project. Results render inline in the terminal with similarity scores.`,
3076
+ body: `Type a question here and TermDeck queries your <strong>Mnestra memory store</strong> for relevant context — scoped to the current panel's project. Prefix with <kbd>all:</kbd> to search every project. Results render inline in the terminal with similarity scores.`,
3077
3077
  onEnter: async () => { await openFirstPanelDrawer('overview'); },
3078
3078
  fallback: '#topbarQuickLaunch',
3079
3079
  },
3080
3080
  {
3081
3081
  target: null,
3082
3082
  title: 'Flashback — proactive recall',
3083
- body: `When a panel errors out, TermDeck <strong>automatically</strong> queries Engram for similar past errors and surfaces the top match as a toast. You don't have to ask. Rate-limited to one per 30 seconds per panel. Click the toast to open the Memory tab with the full hit expanded.`,
3083
+ body: `When a panel errors out, TermDeck <strong>automatically</strong> queries Mnestra for similar past errors and surfaces the top match as a toast. You don't have to ask. Rate-limited to one per 30 seconds per panel. Click the toast to open the Memory tab with the full hit expanded.`,
3084
3084
  },
3085
3085
  {
3086
3086
  target: '.prompt-bar',
@@ -141,13 +141,13 @@ function defaultConfig() {
141
141
  anthropicApiKey: null,
142
142
  developerId: os.userInfo().username,
143
143
  syncIntervalMs: 10000,
144
- engramMode: 'direct',
145
- engramWebhookUrl: 'http://localhost:37778/engram',
144
+ mnestraMode: 'direct',
145
+ mnestraWebhookUrl: 'http://localhost:37778/mnestra',
146
146
  tables: {
147
- session: 'engram_session_memory',
148
- project: 'engram_project_memory',
149
- developer: 'engram_developer_memory',
150
- commands: 'engram_commands'
147
+ session: 'mnestra_session_memory',
148
+ project: 'mnestra_project_memory',
149
+ developer: 'mnestra_developer_memory',
150
+ commands: 'mnestra_commands'
151
151
  }
152
152
  },
153
153
  sessionLogs: {
@@ -194,8 +194,8 @@ rag:
194
194
  openaiApiKey: \${OPENAI_API_KEY}
195
195
  anthropicApiKey: \${ANTHROPIC_API_KEY}
196
196
  syncIntervalMs: 10000
197
- engramMode: direct
198
- engramWebhookUrl: http://localhost:37778/engram
197
+ mnestraMode: direct
198
+ mnestraWebhookUrl: http://localhost:37778/mnestra
199
199
 
200
200
  sessionLogs:
201
201
  enabled: false
@@ -17,7 +17,7 @@ try { Database = require('better-sqlite3'); } catch { Database = null; }
17
17
  const { SessionManager } = require('./session');
18
18
  const { initDatabase, logCommand, getSessionHistory, getProjectSessions } = require('./database');
19
19
  const { RAGIntegration } = require('./rag');
20
- const { createBridge } = require('./engram-bridge');
20
+ const { createBridge } = require('./mnestra-bridge');
21
21
  const { writeSessionLog } = require('./session-logger');
22
22
  const { themes, statusColors } = require('./themes');
23
23
  const { loadConfig, addProject } = require('./config');
@@ -54,10 +54,10 @@ function createServer(config) {
54
54
  // Initialize session manager
55
55
  const sessions = new SessionManager(db);
56
56
 
57
- // Initialize RAG + Engram bridge
57
+ // Initialize RAG + Mnestra bridge
58
58
  const rag = new RAGIntegration(config, db);
59
- const engramBridge = createBridge(config);
60
- console.log(`[engram-bridge] mode=${engramBridge.mode}`);
59
+ const mnestraBridge = createBridge(config);
60
+ console.log(`[mnestra-bridge] mode=${mnestraBridge.mode}`);
61
61
 
62
62
  // Wire RAG to session events
63
63
  sessions.on('session:created', (s) => rag.onSessionCreated(s));
@@ -171,11 +171,11 @@ function createServer(config) {
171
171
  rag.onStatusChanged(sess, oldStatus, newStatus);
172
172
  };
173
173
 
174
- // Proactive Engram queries on error — fire-and-forget, respects rag.enabled
174
+ // Proactive Mnestra queries on error — fire-and-forget, respects rag.enabled
175
175
  session.onErrorDetected = (sess, ctx) => {
176
176
  if (!rag.enabled) return;
177
177
  const question = `${sess.meta.type} error ${ctx.lastCommand || ''} ${ctx.tail || ''}`.trim();
178
- engramBridge.queryEngram({
178
+ mnestraBridge.queryMnestra({
179
179
  question,
180
180
  project: sess.meta.project,
181
181
  searchAll: false,
@@ -196,7 +196,7 @@ function createServer(config) {
196
196
  }
197
197
  }
198
198
  }).catch((err) => {
199
- console.warn('[engram-bridge] proactive query failed:', err.message);
199
+ console.warn('[mnestra-bridge] proactive query failed:', err.message);
200
200
  });
201
201
  };
202
202
 
@@ -415,7 +415,7 @@ function createServer(config) {
415
415
  });
416
416
  });
417
417
 
418
- // POST /api/ai/query - query Engram memory via the bridge (direct|webhook|mcp)
418
+ // POST /api/ai/query - query Mnestra memory via the bridge (direct|webhook|mcp)
419
419
  app.post('/api/ai/query', async (req, res) => {
420
420
  let { question, sessionId, project } = req.body;
421
421
  if (!question) return res.status(400).json({ error: 'Missing question' });
@@ -435,7 +435,7 @@ function createServer(config) {
435
435
  } : null;
436
436
 
437
437
  try {
438
- const { memories, total } = await engramBridge.queryEngram({
438
+ const { memories, total } = await mnestraBridge.queryMnestra({
439
439
  question,
440
440
  project,
441
441
  searchAll,
@@ -455,7 +455,7 @@ function createServer(config) {
455
455
  total
456
456
  });
457
457
  } catch (err) {
458
- console.error('[engram-bridge] query failed:', err.message);
458
+ console.error('[mnestra-bridge] query failed:', err.message);
459
459
  // Config-shaped errors are 503, everything else 502
460
460
  const msg = err.message || 'Query failed';
461
461
  const status = /not configured|OPENAI_API_KEY/i.test(msg) ? 503 : 502;
@@ -1,7 +1,7 @@
1
- // Engram bridge — routes TermDeck memory queries through one of three backends:
1
+ // Mnestra bridge — routes TermDeck memory queries through one of three backends:
2
2
  // - direct: talk to Supabase + OpenAI from the server (pre-bridge behavior)
3
- // - webhook: POST to Engram's HTTP webhook server (T3.1) at rag.engramWebhookUrl
4
- // - mcp: spawn the @jhizzard/engram binary and talk JSON-RPC over stdio
3
+ // - webhook: POST to Mnestra's HTTP webhook server (T3.1) at rag.mnestraWebhookUrl
4
+ // - mcp: spawn the @jhizzard/mnestra binary and talk JSON-RPC over stdio
5
5
  //
6
6
  // All three modes return the same shape:
7
7
  // { memories: Array<{ content, source_type, project, similarity, created_at }>, total }
@@ -11,7 +11,7 @@
11
11
  const { spawn } = require('child_process');
12
12
 
13
13
  function createBridge(config) {
14
- const mode = config.rag?.engramMode || 'direct';
14
+ const mode = config.rag?.mnestraMode || 'direct';
15
15
  const state = { mcpChild: null, mcpQueue: [], mcpNextId: 1, mcpBuffer: '' };
16
16
 
17
17
  async function queryDirect({ question, project, searchAll }) {
@@ -40,7 +40,7 @@ function createBridge(config) {
40
40
  });
41
41
  if (!embeddingRes.ok) {
42
42
  const err = await embeddingRes.text();
43
- console.error('[engram-bridge:direct] embedding failed:', err);
43
+ console.error('[mnestra-bridge:direct] embedding failed:', err);
44
44
  throw new Error('Embedding generation failed');
45
45
  }
46
46
  const embeddingData = await embeddingRes.json();
@@ -68,7 +68,7 @@ function createBridge(config) {
68
68
  });
69
69
  if (!searchRes.ok) {
70
70
  const err = await searchRes.text();
71
- console.error('[engram-bridge:direct] supabase search failed:', err);
71
+ console.error('[mnestra-bridge:direct] supabase search failed:', err);
72
72
  throw new Error('Memory search failed');
73
73
  }
74
74
  const rows = await searchRes.json();
@@ -85,7 +85,7 @@ function createBridge(config) {
85
85
  }
86
86
 
87
87
  async function queryWebhook({ question, project, searchAll }) {
88
- const url = config.rag?.engramWebhookUrl || 'http://localhost:37778/engram';
88
+ const url = config.rag?.mnestraWebhookUrl || 'http://localhost:37778/mnestra';
89
89
  const res = await fetch(url, {
90
90
  method: 'POST',
91
91
  headers: { 'Content-Type': 'application/json' },
@@ -98,8 +98,8 @@ function createBridge(config) {
98
98
  });
99
99
  if (!res.ok) {
100
100
  const err = await res.text();
101
- console.error('[engram-bridge:webhook] request failed:', err);
102
- throw new Error(`Engram webhook returned ${res.status}`);
101
+ console.error('[mnestra-bridge:webhook] request failed:', err);
102
+ throw new Error(`Mnestra webhook returned ${res.status}`);
103
103
  }
104
104
  const data = await res.json();
105
105
  const rows = data.memories || [];
@@ -118,7 +118,7 @@ function createBridge(config) {
118
118
  function ensureMcpChild() {
119
119
  if (state.mcpChild && !state.mcpChild.killed) return state.mcpChild;
120
120
 
121
- const bin = config.rag?.engramBinary || 'engram';
121
+ const bin = config.rag?.mnestraBinary || 'mnestra';
122
122
  const child = spawn(bin, ['serve', '--stdio'], { stdio: ['pipe', 'pipe', 'pipe'] });
123
123
  state.mcpChild = child;
124
124
  state.mcpBuffer = '';
@@ -135,24 +135,24 @@ function createBridge(config) {
135
135
  const pending = state.mcpQueue.find((p) => p.id === msg.id);
136
136
  if (pending) {
137
137
  state.mcpQueue = state.mcpQueue.filter((p) => p !== pending);
138
- if (msg.error) pending.reject(new Error(msg.error.message || 'Engram MCP error'));
138
+ if (msg.error) pending.reject(new Error(msg.error.message || 'Mnestra MCP error'));
139
139
  else pending.resolve(msg.result);
140
140
  }
141
141
  } catch (err) {
142
- console.error('[engram-bridge:mcp] parse error:', err.message, line);
142
+ console.error('[mnestra-bridge:mcp] parse error:', err.message, line);
143
143
  }
144
144
  }
145
145
  });
146
146
 
147
147
  child.stderr.on('data', (chunk) => {
148
- console.error('[engram-bridge:mcp]', chunk.toString('utf-8').trim());
148
+ console.error('[mnestra-bridge:mcp]', chunk.toString('utf-8').trim());
149
149
  });
150
150
 
151
151
  child.on('exit', (code, signal) => {
152
- console.warn(`[engram-bridge:mcp] child exited (code=${code}, signal=${signal}); will respawn on next call`);
152
+ console.warn(`[mnestra-bridge:mcp] child exited (code=${code}, signal=${signal}); will respawn on next call`);
153
153
  state.mcpChild = null;
154
154
  for (const pending of state.mcpQueue) {
155
- pending.reject(new Error('Engram MCP child exited'));
155
+ pending.reject(new Error('Mnestra MCP child exited'));
156
156
  }
157
157
  state.mcpQueue = [];
158
158
  });
@@ -177,7 +177,7 @@ function createBridge(config) {
177
177
  const pending = state.mcpQueue.find((p) => p.id === id);
178
178
  if (pending) {
179
179
  state.mcpQueue = state.mcpQueue.filter((p) => p !== pending);
180
- pending.reject(new Error('Engram MCP call timed out'));
180
+ pending.reject(new Error('Mnestra MCP call timed out'));
181
181
  }
182
182
  }, 15000);
183
183
  });
@@ -214,7 +214,7 @@ function createBridge(config) {
214
214
  }
215
215
  }
216
216
 
217
- async function queryEngram({ question, project, searchAll }) {
217
+ async function queryMnestra({ question, project, searchAll }) {
218
218
  switch (mode) {
219
219
  case 'webhook':
220
220
  return queryWebhook({ question, project, searchAll });
@@ -226,7 +226,7 @@ function createBridge(config) {
226
226
  }
227
227
  }
228
228
 
229
- return { mode, queryEngram };
229
+ return { mode, queryMnestra };
230
230
  }
231
231
 
232
232
  module.exports = { createBridge };
@@ -16,10 +16,10 @@ class RAGIntegration {
16
16
 
17
17
  // Table configuration matching Josh's multi-layer schema
18
18
  this.tables = {
19
- sessionMemory: config.rag?.tables?.session || 'engram_session_memory',
20
- projectMemory: config.rag?.tables?.project || 'engram_project_memory',
21
- developerMemory: config.rag?.tables?.developer || 'engram_developer_memory',
22
- commandLog: config.rag?.tables?.commands || 'engram_commands'
19
+ sessionMemory: config.rag?.tables?.session || 'mnestra_session_memory',
20
+ projectMemory: config.rag?.tables?.project || 'mnestra_project_memory',
21
+ developerMemory: config.rag?.tables?.developer || 'mnestra_developer_memory',
22
+ commandLog: config.rag?.tables?.commands || 'mnestra_commands'
23
23
  };
24
24
 
25
25
  if (this.enabled) {
@@ -120,7 +120,7 @@ class RAGIntegration {
120
120
  }
121
121
  } catch (err) {
122
122
  // Will be retried by sync loop
123
- console.error('[engram] Push failed:', err.message);
123
+ console.error('[mnestra] Push failed:', err.message);
124
124
  }
125
125
  }
126
126
 
@@ -163,7 +163,7 @@ class RAGIntegration {
163
163
  markRagEventsSynced(this.db, synced);
164
164
  }
165
165
  } catch (err) {
166
- console.error('[engram] Sync cycle error:', err.message);
166
+ console.error('[mnestra] Sync cycle error:', err.message);
167
167
  }
168
168
  }, this.syncInterval);
169
169
  }