@jhizzard/termdeck 0.2.0 → 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 +191 -169
- package/config/config.example.yaml +10 -10
- package/package.json +7 -6
- package/packages/cli/src/index.js +44 -1
- package/packages/cli/src/init-engram.js +344 -0
- package/packages/cli/src/init-rumen.js +425 -0
- package/packages/client/public/index.html +10 -10
- package/packages/server/src/config.js +8 -8
- package/packages/server/src/index.js +10 -10
- package/packages/server/src/{engram-bridge → mnestra-bridge}/index.js +18 -18
- package/packages/server/src/rag.js +6 -6
- package/packages/server/src/setup/dotenv-io.js +116 -0
- package/packages/server/src/setup/engram-migrations/001_engram_tables.sql +116 -0
- package/packages/server/src/setup/engram-migrations/002_engram_search_function.sql +141 -0
- package/packages/server/src/setup/engram-migrations/003_engram_event_webhook.sql +28 -0
- package/packages/server/src/setup/engram-migrations/004_engram_match_count_cap_and_explain.sql +176 -0
- package/packages/server/src/setup/engram-migrations/005_v0_1_to_v0_2_upgrade.sql +23 -0
- package/packages/server/src/setup/engram-migrations/006_memory_status_rpc.sql +58 -0
- package/packages/server/src/setup/index.js +14 -0
- package/packages/server/src/setup/migrations.js +80 -0
- package/packages/server/src/setup/pg-runner.js +113 -0
- package/packages/server/src/setup/prompts.js +177 -0
- package/packages/server/src/setup/rumen/functions/rumen-tick/index.ts +85 -0
- package/packages/server/src/setup/rumen/functions/rumen-tick/tsconfig.json +14 -0
- package/packages/server/src/setup/rumen/migrations/001_rumen_tables.sql +91 -0
- package/packages/server/src/setup/rumen/migrations/002_pg_cron_schedule.sql +40 -0
- package/packages/server/src/setup/supabase-url.js +114 -0
- package/packages/server/src/setup/yaml-io.js +99 -0
package/README.md
CHANGED
|
@@ -1,242 +1,264 @@
|
|
|
1
1
|
# TermDeck
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **The terminal that remembers what you fixed last month.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A browser-based terminal multiplexer with an onboarding tour, rich per-panel metadata, and **Flashback** — automatic recall of similar past errors, surfaced the moment a panel hits a problem. No asking, no querying, no manual search. TermDeck notices you're stuck and offers the memory.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+

|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
*(A fresh hero screenshot with a live Flashback toast is coming in v0.2.1 — see [docs/FOLLOWUP.md](docs/FOLLOWUP.md).)*
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## One command to try it
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
16
|
npx @jhizzard/termdeck
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
Ninety seconds, one command. Node 18+ is all you need — prebuilt binaries mean no C++ toolchain. Your browser opens automatically at `http://127.0.0.1:3000`, an onboarding tour walks you through every button, and you're launching real PTY shells, Claude Code, Python servers, or anything else a normal terminal can run.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
This is **Tier 1**. Works immediately, fully local, no accounts, no credentials, no database. You get the full dashboard — 7 grid layouts, 8 themes, per-panel metadata overlays, terminal switcher, reply button, status logs, session history in local SQLite. **Flashback is silent at this tier** because there's no memory store to query.
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
git clone https://github.com/jhizzard/termdeck.git
|
|
23
|
-
cd termdeck
|
|
24
|
-
npm install
|
|
25
|
-
npm run dev
|
|
26
|
-
```
|
|
23
|
+
Enabling Flashback takes **one additional 15-minute setup step** — see Tier 2 below. The rest of this README explains what you get, how it works, and how to go deeper.
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
---
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
## How Flashback works
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
- **Windows**: Install [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) with the "Desktop development with C++" workload
|
|
34
|
-
- **Linux (Debian/Ubuntu)**: `sudo apt install build-essential python3`
|
|
35
|
-
- **Linux (Fedora)**: `sudo dnf groupinstall "Development Tools"`
|
|
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.
|
|
36
30
|
|
|
37
|
-
|
|
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.
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm run install:app
|
|
42
|
-
# Creates ~/Applications/TermDeck.app — double-click to launch, drag to Dock
|
|
43
|
-
```
|
|
33
|
+
---
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
```cmd
|
|
47
|
-
install.bat
|
|
48
|
-
# Creates Start Menu + Desktop shortcuts
|
|
49
|
-
```
|
|
35
|
+
## The three-tier stack
|
|
50
36
|
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
npm run dev
|
|
54
|
-
# Or: node packages/cli/src/index.js
|
|
55
|
-
```
|
|
37
|
+
TermDeck is one piece of a three-tier memory stack. Each tier adds capability; each tier is optional.
|
|
56
38
|
|
|
57
|
-
|
|
39
|
+
| Tier | Install time | What you get |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| **1 — TermDeck alone** | 90 seconds | Full multiplexer, metadata, layouts, themes, tour, session history, command logging. Flashback silent. |
|
|
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. |
|
|
58
44
|
|
|
59
|
-
|
|
45
|
+
### Tier 1 — `npx @jhizzard/termdeck` (you're here)
|
|
60
46
|
|
|
61
|
-
|
|
47
|
+
What's included:
|
|
62
48
|
|
|
63
|
-
|
|
49
|
+
- Real PTY shells in the browser via `@homebridge/node-pty-prebuilt-multiarch`
|
|
50
|
+
- 7 grid layouts (`1x1`, `2x1`, `2x2`, `3x2`, `2x4`, `4x2`, control-room feed)
|
|
51
|
+
- 8 curated xterm.js themes (Tokyo Night, Catppuccin Mocha, Rosé Pine Dawn, Dracula, Nord, Gruvbox Dark, Solarized Dark, GitHub Light) — per-panel, switchable live
|
|
52
|
+
- Rich panel metadata: project tag, session type, status dot, detected port, last command, request count, `#N` suffix for same-project duplicates
|
|
53
|
+
- Per-panel drawer with four tabs: Overview, Commands (history), Memory (Flashback hits), Status log
|
|
54
|
+
- Reply button to route text from one panel to another
|
|
55
|
+
- Terminal switcher (`Option+1..9` on macOS, `Alt+1..9` elsewhere)
|
|
56
|
+
- Layout keyboard shortcuts (`Cmd+Shift+1..6` on macOS)
|
|
57
|
+
- Interactive onboarding tour (13 steps, auto-fires on first visit, replayable from the `how this works` button)
|
|
58
|
+
- Add-project modal — create a new project entry from the UI without hand-editing yaml
|
|
59
|
+
- Local SQLite persistence for sessions, command history, and RAG events
|
|
60
|
+
- Optional session log markdown files on PTY exit (enable with `--session-logs`)
|
|
64
61
|
|
|
65
|
-
|
|
66
|
-
- **Type detection** — automatically identifies Claude Code, Gemini CLI, Python servers, or plain shells
|
|
67
|
-
- **Project tag** — color-coded project association
|
|
68
|
-
- **Metadata strip** — when opened, why, last commands, detected ports, request counts
|
|
69
|
-
- **Individual controls** — theme selector, focus/half/close, AI question input
|
|
70
|
-
- **Per-terminal theming** — Tokyo Night, Rose Pine Dawn, Catppuccin, Dracula, Nord, and more
|
|
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.
|
|
71
63
|
|
|
72
|
-
|
|
64
|
+
### Tier 2 — Add Mnestra to light up Flashback
|
|
73
65
|
|
|
74
|
-
|
|
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.
|
|
75
67
|
|
|
76
|
-
|
|
77
|
-
|------|------|----------|
|
|
78
|
-
| 1x1 | Single terminal | Deep work with one AI agent |
|
|
79
|
-
| 2x1 | Two columns | Half-screen split |
|
|
80
|
-
| 2x2 | 2x2 grid | Four terminals at comfortable size |
|
|
81
|
-
| 3x2 | 3x2 grid | Six terminals, monitoring mode |
|
|
82
|
-
| 2x4 | 2x4 grid | Eight terminals, tall vertical pairs |
|
|
83
|
-
| 4x2 | 4x2 grid | Eight terminals, control room |
|
|
84
|
-
| Focus | One expanded | Temporarily expand any panel |
|
|
85
|
-
| Half | One large + stack | One primary + secondary panels |
|
|
68
|
+
To enable Flashback in TermDeck:
|
|
86
69
|
|
|
87
|
-
|
|
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 Mnestra's migrations** to the database. Run each in order via the Supabase SQL Editor, or via `psql`:
|
|
72
|
+
```bash
|
|
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
|
+
```
|
|
81
|
+
3. **Get an OpenAI API key** (text-embedding-3-large).
|
|
82
|
+
4. **Create `~/.termdeck/secrets.env`:**
|
|
83
|
+
```
|
|
84
|
+
SUPABASE_URL=https://your-project.supabase.co
|
|
85
|
+
SUPABASE_SERVICE_ROLE_KEY=sb_secret_...
|
|
86
|
+
OPENAI_API_KEY=sk-proj-...
|
|
87
|
+
ANTHROPIC_API_KEY=sk-ant-... # optional — enables Haiku session summaries
|
|
88
|
+
```
|
|
89
|
+
5. **Enable RAG in `~/.termdeck/config.yaml`:**
|
|
90
|
+
```yaml
|
|
91
|
+
rag:
|
|
92
|
+
enabled: true
|
|
93
|
+
supabaseUrl: ${SUPABASE_URL}
|
|
94
|
+
supabaseKey: ${SUPABASE_SERVICE_ROLE_KEY}
|
|
95
|
+
openaiApiKey: ${OPENAI_API_KEY}
|
|
96
|
+
mnestraMode: direct
|
|
97
|
+
```
|
|
98
|
+
6. **Restart TermDeck** (`Ctrl+C`, then `npx @jhizzard/termdeck` again).
|
|
88
99
|
|
|
89
|
-
|
|
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.
|
|
90
101
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
> npx vitest run # One-shot command
|
|
102
|
+
### Tier 2 bonus — Mnestra as a Claude Code MCP server
|
|
103
|
+
|
|
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
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm install -g @jhizzard/mnestra
|
|
98
108
|
```
|
|
99
109
|
|
|
100
|
-
|
|
110
|
+
Edit `~/.claude/mcp.json`:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"mcpServers": {
|
|
115
|
+
"mnestra": {
|
|
116
|
+
"command": "mnestra",
|
|
117
|
+
"env": {
|
|
118
|
+
"SUPABASE_URL": "https://your-project.supabase.co",
|
|
119
|
+
"SUPABASE_SERVICE_ROLE_KEY": "sb_secret_...",
|
|
120
|
+
"OPENAI_API_KEY": "sk-proj-...",
|
|
121
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
101
127
|
|
|
102
|
-
|
|
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.
|
|
103
129
|
|
|
104
|
-
|
|
130
|
+
### Tier 3 — Add Rumen for async learning
|
|
105
131
|
|
|
106
|
-
|
|
107
|
-
port: 3000
|
|
108
|
-
shell: /bin/zsh
|
|
109
|
-
defaultTheme: tokyo-night
|
|
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.
|
|
110
133
|
|
|
111
|
-
|
|
112
|
-
my-project:
|
|
113
|
-
path: ~/code/my-project
|
|
114
|
-
defaultTheme: catppuccin-mocha
|
|
115
|
-
defaultCommand: claude
|
|
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.
|
|
116
135
|
|
|
117
|
-
|
|
118
|
-
enabled: false
|
|
119
|
-
supabaseUrl: https://your-project.supabase.co
|
|
120
|
-
supabaseKey: your-anon-key
|
|
121
|
-
```
|
|
136
|
+
**Why you'd want Rumen:** without it, Flashback only surfaces memories that structurally match the current context (same project, similar error). With Rumen, Flashback can surface **cross-project patterns** that Haiku synthesized while you were away — "the CORS fix you applied in Project A probably solves this error in Project B." That's the moat.
|
|
122
137
|
|
|
123
|
-
|
|
138
|
+
---
|
|
124
139
|
|
|
125
|
-
|
|
140
|
+
## What Flashback is NOT
|
|
126
141
|
|
|
127
|
-
|
|
128
|
-
2. **Project memory** — commands, file edits, and patterns shared across sessions within a project
|
|
129
|
-
3. **Developer memory** — cross-project patterns (your habits, common workflows, error resolutions)
|
|
142
|
+
Honest limits, stated upfront so the skeptic has nothing to chase:
|
|
130
143
|
|
|
131
|
-
|
|
144
|
+
- **Not magic.** It fires on pattern-matched status transitions from the PTY output analyzer (non-zero exits, `Error:` / `Traceback` / `panic:` / `command not found` / similar). If the analyzer misses your error class, no Flashback. Pattern tuning is an ongoing process.
|
|
145
|
+
- **Not a replacement for reading docs.** It's the shortest path to a memory you already wrote. If the memory isn't there, the feature does nothing.
|
|
146
|
+
- **Not fully local by default.** Tier 2+ reaches out to Supabase for storage and OpenAI for embeddings. Tier 1 is fully local. A fully-local Tier 2 (local Postgres + local embeddings) is on the Sprint 3 roadmap.
|
|
147
|
+
- **Not free forever.** Tier 2+ pays OpenAI fractions of a cent per memory for embeddings. Self-hosted embeddings via Ollama are on the roadmap.
|
|
148
|
+
- **Not proven at scale.** v0.2, validated against 3,400+ memories in one developer's production store. No multi-user data yet. Bug reports and issues welcome.
|
|
132
149
|
|
|
133
|
-
|
|
150
|
+
---
|
|
134
151
|
|
|
135
|
-
|
|
136
|
-
|----------|--------|
|
|
137
|
-
| Ctrl+Shift+N | Focus prompt bar |
|
|
138
|
-
| Ctrl+Shift+1 | Layout: 1x1 |
|
|
139
|
-
| Ctrl+Shift+2 | Layout: 2x1 |
|
|
140
|
-
| Ctrl+Shift+3 | Layout: 2x2 |
|
|
141
|
-
| Ctrl+Shift+4 | Layout: 3x2 |
|
|
142
|
-
| Ctrl+Shift+5 | Layout: 2x4 |
|
|
143
|
-
| Ctrl+Shift+6 | Layout: 4x2 |
|
|
144
|
-
| Ctrl+Shift+] | Next terminal |
|
|
145
|
-
| Ctrl+Shift+[ | Previous terminal |
|
|
146
|
-
| Escape | Exit focus/half mode |
|
|
147
|
-
|
|
148
|
-
## Architecture
|
|
152
|
+
## Architecture at a glance
|
|
149
153
|
|
|
150
154
|
```
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
155
|
+
┌─────────────────────────────────────────┐
|
|
156
|
+
│ Browser: dashboard + xterm.js panels │
|
|
157
|
+
└─────────────────┬───────────────────────┘
|
|
158
|
+
│ WebSocket + REST
|
|
159
|
+
▼
|
|
160
|
+
┌─────────────────────────────────────────┐
|
|
161
|
+
│ TermDeck server │
|
|
162
|
+
│ - Express + ws │
|
|
163
|
+
│ - node-pty per session │
|
|
164
|
+
│ - SQLite persistence │
|
|
165
|
+
│ - Mnestra bridge (direct/webhook/mcp) │
|
|
166
|
+
└─────────────────┬───────────────────────┘
|
|
167
|
+
│ hybrid search + embeddings
|
|
168
|
+
▼
|
|
169
|
+
┌─────────────────────────────────────────┐
|
|
170
|
+
│ Mnestra │
|
|
171
|
+
│ - Postgres + pgvector │
|
|
172
|
+
│ - MCP server (6 tools) │
|
|
173
|
+
│ - HTTP webhook │
|
|
174
|
+
│ - 3-layer progressive search │
|
|
175
|
+
└─────────────────┬───────────────────────┘
|
|
176
|
+
│ cron loop reads + writes
|
|
177
|
+
▼
|
|
178
|
+
┌─────────────────────────────────────────┐
|
|
179
|
+
│ Rumen │
|
|
180
|
+
│ - Supabase Edge Function │
|
|
181
|
+
│ - Extract → Relate → Synthesize │
|
|
182
|
+
│ - Claude Haiku insights │
|
|
183
|
+
└─────────────────────────────────────────┘
|
|
168
184
|
```
|
|
169
185
|
|
|
170
|
-
|
|
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.
|
|
171
187
|
|
|
172
|
-
|
|
188
|
+
---
|
|
173
189
|
|
|
174
|
-
|
|
190
|
+
## Full install options
|
|
175
191
|
|
|
176
|
-
|
|
192
|
+
For users who want more than `npx` — cloning from source, building a macOS `.app` bundle, or running from a downloaded ZIP — see **[docs/INSTALL.md](docs/INSTALL.md)** for the complete decision tree and troubleshooting.
|
|
177
193
|
|
|
178
|
-
|
|
179
|
-
- **Client**: xterm.js, xterm-addon-fit, vanilla JS (no build step)
|
|
180
|
-
- **Storage**: SQLite (local), Supabase/PostgreSQL (RAG)
|
|
181
|
-
- **Themes**: 8 curated terminal color schemes
|
|
182
|
-
- **Launch**: macOS .app bundle (no terminal needed)
|
|
194
|
+
### Alternative install paths
|
|
183
195
|
|
|
184
|
-
|
|
196
|
+
- **Permanent global install:** `npm install -g @jhizzard/termdeck` then `termdeck` from anywhere
|
|
197
|
+
- **macOS native app:** `git clone && cd && ./install.sh` — creates `~/Applications/TermDeck.app`
|
|
198
|
+
- **From source:** `git clone && npm install && npm run dev`
|
|
185
199
|
|
|
186
|
-
|
|
200
|
+
---
|
|
187
201
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
7. **Metadata** — Run commands and verify "last command" updates in the metadata strip.
|
|
195
|
-
8. **Port detection** — Run `python3 -m http.server 8888`. Verify port shows in metadata and type changes to "Python Server".
|
|
196
|
-
9. **Themes** — Change themes on two terminals independently via the dropdown.
|
|
197
|
-
10. **Projects** — Select a project from the dropdown, launch a terminal. Verify it cd's to the right directory.
|
|
198
|
-
11. **Terminal exit** — Type `exit` in a terminal. Panel should dim with "Exited (0)".
|
|
199
|
-
12. **Persistence** — Restart the server. Old sessions should be marked as exited in the DB.
|
|
200
|
-
13. **Command history** — Check `GET http://localhost:3000/api/sessions/:id/history`.
|
|
201
|
-
14. **RAG events** — Check `GET http://localhost:3000/api/rag/events` to see recorded events.
|
|
202
|
+
## Related packages
|
|
203
|
+
|
|
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
|
+
- **[@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
|
+
|
|
207
|
+
---
|
|
202
208
|
|
|
203
209
|
## Development
|
|
204
210
|
|
|
205
211
|
```bash
|
|
206
|
-
|
|
212
|
+
git clone https://github.com/jhizzard/termdeck.git
|
|
213
|
+
cd termdeck
|
|
207
214
|
npm install
|
|
208
|
-
|
|
209
|
-
# Run server directly
|
|
210
|
-
npm run server
|
|
211
|
-
|
|
212
|
-
# Run via CLI (opens browser)
|
|
213
215
|
npm run dev
|
|
214
|
-
|
|
215
|
-
# The client is served as static files from packages/client/public/
|
|
216
216
|
```
|
|
217
217
|
|
|
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 + Mnestra bridge + session analyzer
|
|
222
|
+
- `packages/client/public/` — vanilla-JS dashboard (single HTML file, no build step, loads xterm.js from CDN)
|
|
223
|
+
- `config/` — example `config.yaml` and `secrets.env.example`
|
|
224
|
+
- `docs/` — planning documents, launch strategy, install guide, followup items, ship checklist
|
|
221
225
|
|
|
222
|
-
|
|
226
|
+
Submit PRs at https://github.com/jhizzard/termdeck/pulls.
|
|
223
227
|
|
|
224
|
-
|
|
225
|
-
npm cache clean --force
|
|
226
|
-
rm -rf node_modules package-lock.json
|
|
227
|
-
npm install
|
|
228
|
-
```
|
|
228
|
+
---
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
## Keyboard shortcuts
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
| Key | Action |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `Ctrl+Shift+N` | Focus the prompt bar |
|
|
235
|
+
| `Cmd+Shift+1..6` / `Ctrl+Shift+1..6` | Switch grid layout |
|
|
236
|
+
| `Ctrl+Shift+]` / `Ctrl+Shift+[` | Cycle to next / previous panel |
|
|
237
|
+
| `Option+1..9` / `Alt+1..9` | Jump focus to panel N directly |
|
|
238
|
+
| `Escape` | Exit focus / half mode |
|
|
239
|
+
| `/` (not in an input) | Focus prompt bar |
|
|
240
|
+
| `how this works` button | Replay the onboarding tour |
|
|
233
241
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Configuration
|
|
237
245
|
|
|
238
|
-
|
|
246
|
+
Config lives at `~/.termdeck/config.yaml`. Secrets (API keys) belong in `~/.termdeck/secrets.env` using dotenv format — use `${VAR}` substitution in `config.yaml` to reference them. Template files are bundled in the published package at `config/config.example.yaml` and `config/secrets.env.example`.
|
|
247
|
+
|
|
248
|
+
---
|
|
239
249
|
|
|
240
250
|
## License
|
|
241
251
|
|
|
242
|
-
MIT
|
|
252
|
+
MIT © Joshua Izzard. See [LICENSE](LICENSE).
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Links
|
|
257
|
+
|
|
258
|
+
- GitHub: [github.com/jhizzard/termdeck](https://github.com/jhizzard/termdeck)
|
|
259
|
+
- npm: [@jhizzard/termdeck](https://www.npmjs.com/package/@jhizzard/termdeck)
|
|
260
|
+
- Issues: [github.com/jhizzard/termdeck/issues](https://github.com/jhizzard/termdeck/issues)
|
|
261
|
+
- Mnestra: [github.com/jhizzard/mnestra](https://github.com/jhizzard/mnestra) · [npm](https://www.npmjs.com/package/@jhizzard/mnestra)
|
|
262
|
+
- Rumen: [github.com/jhizzard/rumen](https://github.com/jhizzard/rumen) · [npm](https://www.npmjs.com/package/@jhizzard/rumen)
|
|
263
|
+
|
|
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
|
-
#
|
|
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 `
|
|
41
|
-
# mcp — spawn the local `
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
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:
|
|
49
|
-
project:
|
|
50
|
-
developer:
|
|
51
|
-
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.
|
|
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"
|
|
@@ -27,14 +27,15 @@
|
|
|
27
27
|
"install:app": "bash install.sh"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"express": "^4.18.2",
|
|
31
|
-
"ws": "^8.16.0",
|
|
32
30
|
"@homebridge/node-pty-prebuilt-multiarch": "^0.13.1",
|
|
33
31
|
"better-sqlite3": "^12.9.0",
|
|
34
|
-
"uuid": "^9.0.0",
|
|
35
|
-
"yaml": "^2.3.4",
|
|
36
32
|
"chalk": "^5.3.0",
|
|
37
|
-
"
|
|
33
|
+
"express": "^4.18.2",
|
|
34
|
+
"open": "^10.0.0",
|
|
35
|
+
"pg": "^8.20.0",
|
|
36
|
+
"uuid": "^9.0.0",
|
|
37
|
+
"ws": "^8.16.0",
|
|
38
|
+
"yaml": "^2.3.4"
|
|
38
39
|
},
|
|
39
40
|
"keywords": [
|
|
40
41
|
"terminal",
|
|
@@ -1,13 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// TermDeck CLI launcher
|
|
4
|
-
// Usage:
|
|
4
|
+
// Usage:
|
|
5
|
+
// termdeck [--port 3000] [--no-open]
|
|
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.
|
|
5
13
|
|
|
6
14
|
const path = require('path');
|
|
7
15
|
const { execSync } = require('child_process');
|
|
8
16
|
|
|
9
17
|
// Parse CLI args
|
|
10
18
|
const args = process.argv.slice(2);
|
|
19
|
+
|
|
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.
|
|
24
|
+
if (args[0] === 'init') {
|
|
25
|
+
const mode = args[1];
|
|
26
|
+
const rest = args.slice(2);
|
|
27
|
+
const run = (modPath) => {
|
|
28
|
+
const fn = require(modPath);
|
|
29
|
+
return fn(rest).then((code) => process.exit(code || 0));
|
|
30
|
+
};
|
|
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);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (mode === '--rumen') {
|
|
39
|
+
run(path.join(__dirname, 'init-rumen.js')).catch((err) => {
|
|
40
|
+
console.error('[cli] init --rumen failed:', err && err.stack || err);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
console.error('Usage: termdeck init --mnestra | --rumen');
|
|
46
|
+
console.error(' termdeck init --mnestra Configure Tier 2 memory (Supabase + Ingram)');
|
|
47
|
+
console.error(' termdeck init --rumen Deploy Tier 3 async learning (Rumen)');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
11
51
|
const flags = {};
|
|
12
52
|
for (let i = 0; i < args.length; i++) {
|
|
13
53
|
if (args[i] === '--port' && args[i + 1]) {
|
|
@@ -26,6 +66,8 @@ for (let i = 0; i < args.length; i++) {
|
|
|
26
66
|
termdeck --port 8080 Start on custom port
|
|
27
67
|
termdeck --no-open Don't auto-open browser
|
|
28
68
|
termdeck --session-logs Write per-session markdown logs to ~/.termdeck/sessions/
|
|
69
|
+
termdeck init --mnestra Configure Tier 2 memory (Supabase + Ingram)
|
|
70
|
+
termdeck init --rumen Deploy Tier 3 async learning (Rumen)
|
|
29
71
|
|
|
30
72
|
Keyboard shortcuts (in browser):
|
|
31
73
|
Ctrl+Shift+N Focus prompt bar
|
|
@@ -35,6 +77,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
35
77
|
|
|
36
78
|
Config:
|
|
37
79
|
~/.termdeck/config.yaml Server + project + RAG configuration
|
|
80
|
+
~/.termdeck/secrets.env API keys (OpenAI, Anthropic, Supabase)
|
|
38
81
|
~/.termdeck/termdeck.db Session history (SQLite)
|
|
39
82
|
`);
|
|
40
83
|
process.exit(0);
|