choda-deck 0.2.0 โ 0.3.0
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 +296 -230
- package/dist/cli.cjs +36494 -28217
- package/dist/mcp-rules.md +170 -94
- package/dist/mcp-server.cjs +35105 -25993
- package/package.json +81 -78
package/README.md
CHANGED
|
@@ -1,230 +1,296 @@
|
|
|
1
|
-
# choda-deck
|
|
2
|
-
|
|
3
|
-
> **Persistent memory + orchestration layer for [Claude Code](https://docs.claude.com/claude-code).**
|
|
4
|
-
> Tasks, sessions, conversations, decisions, and inbox โ all backed by SQLite, all reachable through MCP tools.
|
|
5
|
-
|
|
6
|
-
[](https://www.npmjs.com/package/choda-deck)
|
|
7
|
-
[](./LICENSE)
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## What is choda-deck?
|
|
12
|
-
|
|
13
|
-
A pure-Node MCP server that turns Claude Code from a stateless chat into a **stateful collaborator**.
|
|
14
|
-
|
|
15
|
-
Claude can:
|
|
16
|
-
- ๐ Track tasks with acceptance criteria, status, and labels
|
|
17
|
-
- ๐งต Bind work sessions to tasks โ checkpoint progress, resume next time with full context
|
|
18
|
-
- ๐ฌ Hold structured conversations with decisions logged
|
|
19
|
-
- ๐ฅ Capture mid-flow ideas to an inbox, research them later, convert to tasks
|
|
20
|
-
- ๐ Maintain a knowledge layer (ADRs / decision logs) with staleness tracking
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
| Lost
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- **
|
|
80
|
-
- **
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
choda-deck
|
|
117
|
-
choda-deck task
|
|
118
|
-
choda-deck
|
|
119
|
-
choda-deck
|
|
120
|
-
choda-deck knowledge
|
|
121
|
-
choda-deck
|
|
122
|
-
choda-deck
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
| **
|
|
139
|
-
| **
|
|
140
|
-
| **
|
|
141
|
-
| **
|
|
142
|
-
| **
|
|
143
|
-
| **
|
|
144
|
-
| **
|
|
145
|
-
| **
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Claude : (
|
|
157
|
-
You :
|
|
158
|
-
Claude : (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
You : "
|
|
177
|
-
Claude : (
|
|
178
|
-
You : "
|
|
179
|
-
Claude : (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
Claude : (
|
|
190
|
-
|
|
191
|
-
Claude : (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
1
|
+
# choda-deck
|
|
2
|
+
|
|
3
|
+
> **Persistent memory + orchestration layer for [Claude Code](https://docs.claude.com/claude-code).**
|
|
4
|
+
> Tasks, sessions, conversations, decisions, and inbox โ all backed by SQLite, all reachable through MCP tools.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/choda-deck)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What is choda-deck?
|
|
12
|
+
|
|
13
|
+
A pure-Node MCP server that turns Claude Code from a stateless chat into a **stateful collaborator**.
|
|
14
|
+
|
|
15
|
+
Claude can:
|
|
16
|
+
- ๐ Track tasks with acceptance criteria, status, and labels
|
|
17
|
+
- ๐งต Bind work sessions to tasks โ checkpoint progress, resume next time with full context
|
|
18
|
+
- ๐ฌ Hold structured conversations with decisions logged
|
|
19
|
+
- ๐ฅ Capture mid-flow ideas to an inbox, research them later, convert to tasks
|
|
20
|
+
- ๐ Maintain a knowledge layer (ADRs / decision logs) with staleness tracking
|
|
21
|
+
- ๐ Trace bugs as structured investigations โ hypotheses, evidence, root cause โ that survive across sessions
|
|
22
|
+
- ๐พ Auto-backup daily, restore on demand
|
|
23
|
+
|
|
24
|
+
Everything lives in a single SQLite file. No cloud, no SaaS, no telemetry.
|
|
25
|
+
|
|
26
|
+
## Why?
|
|
27
|
+
|
|
28
|
+
Working with Claude Code across many days hits the same walls:
|
|
29
|
+
|
|
30
|
+
| Pain | Without choda-deck | With choda-deck |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Lost task list | Scattered across markdown / TODO comments / chat history | One queryable source of truth |
|
|
33
|
+
| Lost context between sessions | Re-explain what you were doing last time | `session_resume` loads task body + AC + last checkpoint |
|
|
34
|
+
| Decisions disappear into chat | Scroll back, hope you find it | `conversation_decide` + `knowledge_create` log decisions next to code |
|
|
35
|
+
| Ideas dropped mid-flow | Forgotten or pile up in scratch files | `inbox_add` โ research/convert/archive later |
|
|
36
|
+
| ADRs drift from code | Manual review, never happens | `knowledge_verify` flags stale ADRs via `refs[]` |
|
|
37
|
+
|
|
38
|
+
choda-deck is the **memory layer** Claude wishes it had built-in.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g choda-deck
|
|
44
|
+
# or run on demand
|
|
45
|
+
npx choda-deck
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Requires Node.js >= 20.
|
|
49
|
+
|
|
50
|
+
## Wire it into your MCP client
|
|
51
|
+
|
|
52
|
+
choda-deck speaks stock MCP stdio โ works with any client that supports the protocol. Pick the one you use:
|
|
53
|
+
|
|
54
|
+
### Claude Code
|
|
55
|
+
|
|
56
|
+
Add to `.claude.json` (user-level) or `.mcp.json` (project-level):
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"choda-tasks": {
|
|
62
|
+
"command": "npx",
|
|
63
|
+
"args": ["-y", "choda-deck"],
|
|
64
|
+
"env": {
|
|
65
|
+
"CHODA_DATA_DIR": "/absolute/path/to/data",
|
|
66
|
+
"CHODA_CONTENT_ROOT": "/absolute/path/to/your/notes-or-vault"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Restart Claude Code โ the `choda-tasks` MCP server is online.
|
|
74
|
+
|
|
75
|
+
### Claude Desktop
|
|
76
|
+
|
|
77
|
+
Edit `claude_desktop_config.json` (same `mcpServers` schema as above):
|
|
78
|
+
|
|
79
|
+
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
80
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
81
|
+
- **Linux:** `~/.config/Claude/claude_desktop_config.json`
|
|
82
|
+
|
|
83
|
+
Quit + reopen Claude Desktop. The hammer icon shows `choda-tasks` connected.
|
|
84
|
+
|
|
85
|
+
### GitHub Copilot (VS Code)
|
|
86
|
+
|
|
87
|
+
Create `.vscode/mcp.json` in your workspace (or add to User Settings):
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"servers": {
|
|
92
|
+
"choda-tasks": {
|
|
93
|
+
"type": "stdio",
|
|
94
|
+
"command": "npx",
|
|
95
|
+
"args": ["-y", "choda-deck"],
|
|
96
|
+
"env": {
|
|
97
|
+
"CHODA_DATA_DIR": "/absolute/path/to/data",
|
|
98
|
+
"CHODA_CONTENT_ROOT": "/absolute/path/to/your/notes-or-vault"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Note: Copilot uses `servers` (not `mcpServers`) and requires `"type": "stdio"`. Reload VS Code window โ tools appear in Copilot Chat under agent mode.
|
|
106
|
+
|
|
107
|
+
### Other clients (Cursor, Continue, Zed, โฆ)
|
|
108
|
+
|
|
109
|
+
Any MCP-compatible client works. Use the `command` / `args` / `env` triple โ drop it into whatever the client calls its MCP config block.
|
|
110
|
+
|
|
111
|
+
## CLI
|
|
112
|
+
|
|
113
|
+
`choda-deck` ships a read-only CLI that talks to the same SQLite store directly โ no AI in the loop, no MCP roundtrip. Use it to verify state, script automations, or pipe to `jq`.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
choda-deck --help # show all subcommands
|
|
117
|
+
choda-deck task list --status TODO --json # script-friendly
|
|
118
|
+
choda-deck task show TASK-669 # body + linked conversations
|
|
119
|
+
choda-deck inbox list --project choda-deck
|
|
120
|
+
choda-deck knowledge list
|
|
121
|
+
choda-deck knowledge show ADR-020-embedding-architecture
|
|
122
|
+
choda-deck project context choda-deck # AI's session_start view
|
|
123
|
+
choda-deck mcp serve # start the MCP stdio server
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Pass `--json` to any read command for machine-readable output. Plain text is the default for humans.
|
|
127
|
+
|
|
128
|
+
### Reading freshness
|
|
129
|
+
|
|
130
|
+
The CLI opens SQLite in WAL mode for shared reads. While the MCP server is actively writing, a CLI read may see a snapshot from a few seconds ago โ re-run after 1-2s if state looks stale. See knowledge entry `sqlite-wal-read-consistency` for details.
|
|
131
|
+
|
|
132
|
+
## Tools
|
|
133
|
+
|
|
134
|
+
All tools are namespaced `mcp__choda-tasks__<name>`. Claude calls them on your behalf โ you never invoke them directly.
|
|
135
|
+
|
|
136
|
+
| Domain | Tools | What it does |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| **Project** | `project_add`, `project_list`, `project_context` | Multi-project setup. Each project has its own task list and metadata. |
|
|
139
|
+
| **Workspace** | `workspace_add`, `workspace_list`, `workspace_archive` | Sub-scope inside a project (e.g. `frontend`, `backend`, `infra`). Knowledge entries can be scoped to a workspace. |
|
|
140
|
+
| **Task** | `task_create`, `task_list`, `task_update`, `task_context` | TODO โ READY โ IN-PROGRESS โ DONE/BLOCKED. Each task has body + acceptance criteria + labels + priority. |
|
|
141
|
+
| **Session** | `session_start`, `session_checkpoint`, `session_end`, `session_resume`, `session_list` | Bind a work session to a task. Checkpoint progress so the next session resumes with full context. |
|
|
142
|
+
| **Conversation** | `conversation_open`, `conversation_add`, `conversation_decide`, `conversation_close`, `conversation_reopen`, `conversation_list`, `conversation_read`, `conversation_poll` | Structured threads (e.g. FE/BE alignment, ADR debate). `decide` logs the resolution. |
|
|
143
|
+
| **Inbox** | `inbox_add`, `inbox_research`, `inbox_convert`, `inbox_ready`, `inbox_archive`, `inbox_list`, `inbox_get`, `inbox_update` | Capture-now, decide-later. Items move `raw` โ `researching` โ `ready` โ `converted` (to a task) or `archived`. |
|
|
144
|
+
| **Knowledge** | `knowledge_create`, `knowledge_list`, `knowledge_get`, `knowledge_search`, `knowledge_update`, `knowledge_verify`, `knowledge_delete` | ADRs / decision logs with frontmatter. `refs[]` tracks implementation files + commit SHAs โ staleness banner when code drifts. |
|
|
145
|
+
| **Investigation** | `investigation_start`, `investigation_add_hypothesis`, `investigation_set_hypothesis_status`, `investigation_add_evidence`, `investigation_resolve`, `investigation_get` | Nonlinear debugging container (ADR-035). Hypotheses (ruled-out branches kept) + typed evidence persist across sessions; `resolve` drafts a knowledge gotcha for reuse. stdio-only. |
|
|
146
|
+
| **Backup** | `backup_create`, `backup_list`, `backup_restore` | Daily auto-backup of the SQLite DB. Manual create + restore when you need to roll back. |
|
|
147
|
+
| **Ops** | `stats_report`, `cleanup_worktree_orphans` | Tool-usage telemetry (per-tool calls / error rate / dead-in-window) + worktree GC. |
|
|
148
|
+
|
|
149
|
+
## Common workflows
|
|
150
|
+
|
|
151
|
+
### 1. Task-driven session
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
You : "Let's work on TASK-123"
|
|
155
|
+
Claude : (task_context TASK-123) โ loads body + AC
|
|
156
|
+
Claude : (session_start TASK-123) โ binds session
|
|
157
|
+
You : (work happens)
|
|
158
|
+
Claude : (session_checkpoint "finished part 1, hit X issue")
|
|
159
|
+
You : "stop here, continue tomorrow"
|
|
160
|
+
Claude : (session_end)
|
|
161
|
+
|
|
162
|
+
โ next day โ
|
|
163
|
+
You : "resume yesterday's work"
|
|
164
|
+
Claude : (session_resume) โ re-reads task body + last checkpoint
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 2. Capture without breaking flow
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
You : "While we're here โ idea: split this module into two"
|
|
171
|
+
Claude : (inbox_add content="split foo module โ two") โ back to current work
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Later:
|
|
175
|
+
```
|
|
176
|
+
You : "show me the inbox"
|
|
177
|
+
Claude : (inbox_list) โ 12 raw items
|
|
178
|
+
You : "research INBOX-008"
|
|
179
|
+
Claude : (inbox_research) โ reads codebase, writes findings, sets status=ready
|
|
180
|
+
You : "convert it"
|
|
181
|
+
Claude : (inbox_convert) โ creates TASK-456 with body from research
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 3. Decision log next to code
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
You : "should we use sqlite-vec or qdrant for embeddings?"
|
|
188
|
+
Claude : (conversation_open "embedding store choice")
|
|
189
|
+
Claude : (analyzes both, posts trade-offs)
|
|
190
|
+
You : "go sqlite-vec for now"
|
|
191
|
+
Claude : (conversation_decide "sqlite-vec โ brute KNN fine at our scale")
|
|
192
|
+
Claude : (knowledge_create ADR-020 with refs to src/embeddings/*.ts)
|
|
193
|
+
Claude : (conversation_close)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Three months later, when you edit `src/embeddings/`:
|
|
197
|
+
```
|
|
198
|
+
Claude : (knowledge_verify) โ flags ADR-020 as potentially stale (refs SHA mismatch)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Configuration
|
|
202
|
+
|
|
203
|
+
| Env var | Default | Purpose |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `CHODA_DATA_DIR` | _required_ | SQLite DB, artifacts, and backups directory. Created on first run. |
|
|
206
|
+
| `CHODA_CONTENT_ROOT` | _optional_ | Root for knowledge / vault content lookup. |
|
|
207
|
+
| `CHODA_BACKEND` | `sqlite` | Storage backend (ADR-030). `sqlite` (local file) or `postgres` (remote, k8s-friendly). |
|
|
208
|
+
| `CHODA_PG_URL` | _required when `CHODA_BACKEND=postgres`_ | Postgres connection string (e.g. `postgres://user:pass@host:5432/db`). |
|
|
209
|
+
| `CHODA_PG_POOL_SIZE` | `10` | Postgres connection pool max size. Tune for concurrent HTTP requests. |
|
|
210
|
+
| `CHODA_EMBEDDING_PROVIDER` | `local` | `local` (transformers.js MiniLM-L6) or `noop` (disable embedding-backed search). |
|
|
211
|
+
|
|
212
|
+
### Data layout (SQLite)
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
$CHODA_DATA_DIR/
|
|
216
|
+
โโโ database/choda-deck.db โ single source of truth
|
|
217
|
+
โโโ artifacts/<sessionId>/ โ per-session scratch
|
|
218
|
+
โโโ backups/choda-deck-<date>.db โ auto daily, retained
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Postgres backend
|
|
222
|
+
|
|
223
|
+
The Postgres adapter is full-feature parity with SQLite โ all `mcp__choda-tasks__*` tools work against either backend. Use Postgres when running the MCP HTTP transport in k8s (ADR-026 + ADR-030).
|
|
224
|
+
|
|
225
|
+
**Local dev** with the shipped `docker-compose.yml`:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
docker compose up -d # boots pgvector/pgvector:pg16 on :5432
|
|
229
|
+
export CHODA_BACKEND=postgres
|
|
230
|
+
export CHODA_PG_URL="postgres://choda:choda@localhost:5432/choda"
|
|
231
|
+
pnpm run mcp:http # schema migrates on first connect
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**k8s** โ minimal `Deployment` + `Secret` shape:
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
apiVersion: v1
|
|
238
|
+
kind: Secret
|
|
239
|
+
metadata: { name: choda-pg }
|
|
240
|
+
type: Opaque
|
|
241
|
+
stringData:
|
|
242
|
+
CHODA_PG_URL: postgres://choda:CHANGEME@choda-pg.default.svc.cluster.local:5432/choda
|
|
243
|
+
MCP_HTTP_TOKEN: REPLACE_WITH_BASE64URL_32_BYTES
|
|
244
|
+
---
|
|
245
|
+
apiVersion: apps/v1
|
|
246
|
+
kind: Deployment
|
|
247
|
+
metadata: { name: choda-deck }
|
|
248
|
+
spec:
|
|
249
|
+
replicas: 1
|
|
250
|
+
template:
|
|
251
|
+
spec:
|
|
252
|
+
containers:
|
|
253
|
+
- name: choda
|
|
254
|
+
image: ghcr.io/your-org/choda-deck:latest
|
|
255
|
+
env:
|
|
256
|
+
- { name: CHODA_BACKEND, value: postgres }
|
|
257
|
+
- { name: MCP_TRANSPORT, value: http }
|
|
258
|
+
- { name: MCP_HTTP_BIND, value: 0.0.0.0 }
|
|
259
|
+
envFrom:
|
|
260
|
+
- secretRef: { name: choda-pg }
|
|
261
|
+
ports:
|
|
262
|
+
- containerPort: 7337
|
|
263
|
+
readinessProbe:
|
|
264
|
+
httpGet: { path: /healthz, port: 7337 }
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Bring your own Postgres (Cloud SQL, RDS, managed) or run a sidecar `StatefulSet` with the `pgvector/pgvector:pg16` image. Migrations and the pgvector extension setup are idempotent โ they run automatically inside `initializeAsync()` on every boot.
|
|
268
|
+
|
|
269
|
+
**Migration from existing SQLite data** โ one-shot script:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
CHODA_PG_URL="postgres://choda:choda@localhost:5432/choda" \
|
|
273
|
+
node scripts/migrate-sqlite-to-postgres.mjs \
|
|
274
|
+
--sqlite $CHODA_DATA_DIR/database/choda-deck.db [--dry-run]
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
The script is idempotent (skips tables that already have rows; pass `--force` to wipe + reload). Embedding vectors are NOT copied โ re-run `scripts/backfill-embeddings.mjs` against the Postgres backend after migration to rebuild them.
|
|
278
|
+
|
|
279
|
+
The cross-device pending-ops sync engine (ADR-030 ยง2) is **not** in this release โ laptop โ remote MCP today is "one backend at a time," not a live sync. Pick `CHODA_BACKEND` per process.
|
|
280
|
+
|
|
281
|
+
## Architecture
|
|
282
|
+
|
|
283
|
+
- **SQLite** (`better-sqlite3`) โ single source of truth, file-based, no daemon
|
|
284
|
+
- **MCP stdio** โ AI interaction layer (Anthropic's [Model Context Protocol](https://modelcontextprotocol.io))
|
|
285
|
+
- **Pure Node runtime** โ no Electron, no PTY, no native deps beyond `better-sqlite3`
|
|
286
|
+
- **Windows-first**, but runs on macOS and Linux
|
|
287
|
+
|
|
288
|
+
See [`docs/architecture.md`](https://github.com/butterngo/choda-deck/blob/main/docs/architecture.md) for the full layout, and ADRs in [`docs/knowledge/`](https://github.com/butterngo/choda-deck/tree/main/docs/knowledge) for design decisions.
|
|
289
|
+
|
|
290
|
+
## Status
|
|
291
|
+
|
|
292
|
+
`0.3.0` โ early, dogfooded daily by the author. API may move before `1.0`. Issues + PRs welcome.
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
MIT โ see [LICENSE](./LICENSE).
|