choda-deck 0.2.0 โ†’ 0.2.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/README.md CHANGED
@@ -1,230 +1,294 @@
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
- [![npm version](https://img.shields.io/npm/v/choda-deck.svg)](https://www.npmjs.com/package/choda-deck)
7
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./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
- - ๐Ÿ’พ Auto-backup daily, restore on demand
22
-
23
- Everything lives in a single SQLite file. No cloud, no SaaS, no telemetry.
24
-
25
- ## Why?
26
-
27
- Working with Claude Code across many days hits the same walls:
28
-
29
- | Pain | Without choda-deck | With choda-deck |
30
- |---|---|---|
31
- | Lost task list | Scattered across markdown / TODO comments / chat history | One queryable source of truth |
32
- | Lost context between sessions | Re-explain what you were doing last time | `session_resume` loads task body + AC + last checkpoint |
33
- | Decisions disappear into chat | Scroll back, hope you find it | `conversation_decide` + `knowledge_create` log decisions next to code |
34
- | Ideas dropped mid-flow | Forgotten or pile up in scratch files | `inbox_add` โ€” research/convert/archive later |
35
- | ADRs drift from code | Manual review, never happens | `knowledge_verify` flags stale ADRs via `refs[]` |
36
-
37
- choda-deck is the **memory layer** Claude wishes it had built-in.
38
-
39
- ## Install
40
-
41
- ```bash
42
- npm install -g choda-deck
43
- # or run on demand
44
- npx choda-deck
45
- ```
46
-
47
- Requires Node.js >= 20.
48
-
49
- ## Wire it into your MCP client
50
-
51
- choda-deck speaks stock MCP stdio โ€” works with any client that supports the protocol. Pick the one you use:
52
-
53
- ### Claude Code
54
-
55
- Add to `.claude.json` (user-level) or `.mcp.json` (project-level):
56
-
57
- ```json
58
- {
59
- "mcpServers": {
60
- "choda-tasks": {
61
- "command": "npx",
62
- "args": ["-y", "choda-deck"],
63
- "env": {
64
- "CHODA_DATA_DIR": "/absolute/path/to/data",
65
- "CHODA_CONTENT_ROOT": "/absolute/path/to/your/notes-or-vault"
66
- }
67
- }
68
- }
69
- }
70
- ```
71
-
72
- Restart Claude Code โ†’ the `choda-tasks` MCP server is online.
73
-
74
- ### Claude Desktop
75
-
76
- Edit `claude_desktop_config.json` (same `mcpServers` schema as above):
77
-
78
- - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
79
- - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
80
- - **Linux:** `~/.config/Claude/claude_desktop_config.json`
81
-
82
- Quit + reopen Claude Desktop. The hammer icon shows `choda-tasks` connected.
83
-
84
- ### GitHub Copilot (VS Code)
85
-
86
- Create `.vscode/mcp.json` in your workspace (or add to User Settings):
87
-
88
- ```json
89
- {
90
- "servers": {
91
- "choda-tasks": {
92
- "type": "stdio",
93
- "command": "npx",
94
- "args": ["-y", "choda-deck"],
95
- "env": {
96
- "CHODA_DATA_DIR": "/absolute/path/to/data",
97
- "CHODA_CONTENT_ROOT": "/absolute/path/to/your/notes-or-vault"
98
- }
99
- }
100
- }
101
- }
102
- ```
103
-
104
- Note: Copilot uses `servers` (not `mcpServers`) and requires `"type": "stdio"`. Reload VS Code window โ†’ tools appear in Copilot Chat under agent mode.
105
-
106
- ### Other clients (Cursor, Continue, Zed, โ€ฆ)
107
-
108
- Any MCP-compatible client works. Use the `command` / `args` / `env` triple โ€” drop it into whatever the client calls its MCP config block.
109
-
110
- ## CLI
111
-
112
- `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`.
113
-
114
- ```bash
115
- choda-deck --help # show all subcommands
116
- choda-deck task list --status TODO --json # script-friendly
117
- choda-deck task show TASK-669 # body + linked conversations
118
- choda-deck inbox list --project choda-deck
119
- choda-deck knowledge list
120
- choda-deck knowledge show ADR-020-embedding-architecture
121
- choda-deck project context choda-deck # AI's session_start view
122
- choda-deck mcp serve # start the MCP stdio server
123
- ```
124
-
125
- Pass `--json` to any read command for machine-readable output. Plain text is the default for humans.
126
-
127
- ### Reading freshness
128
-
129
- 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.
130
-
131
- ## Tools
132
-
133
- All tools are namespaced `mcp__choda-tasks__<name>`. Claude calls them on your behalf โ€” you never invoke them directly.
134
-
135
- | Domain | Tools | What it does |
136
- |---|---|---|
137
- | **Project** | `project_add`, `project_list`, `project_context` | Multi-project setup. Each project has its own task list and metadata. |
138
- | **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. |
139
- | **Task** | `task_create`, `task_list`, `task_update`, `task_context` | TODO โ†’ READY โ†’ IN-PROGRESS โ†’ DONE/BLOCKED. Each task has body + acceptance criteria + labels + priority. |
140
- | **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. |
141
- | **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. |
142
- | **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`. |
143
- | **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. |
144
- | **Backup** | `backup_create`, `backup_list`, `backup_restore` | Daily auto-backup of the SQLite DB. Manual create + restore when you need to roll back. |
145
- | **Ops** | `stats_report`, `cleanup_worktree_orphans` | Tool-usage telemetry (per-tool calls / error rate / dead-in-window) + worktree GC. |
146
-
147
- ## Common workflows
148
-
149
- ### 1. Task-driven session
150
-
151
- ```
152
- You : "Let's work on TASK-123"
153
- Claude : (task_context TASK-123) โ†’ loads body + AC
154
- Claude : (session_start TASK-123) โ†’ binds session
155
- You : (work happens)
156
- Claude : (session_checkpoint "finished part 1, hit X issue")
157
- You : "stop here, continue tomorrow"
158
- Claude : (session_end)
159
-
160
- โ€” next day โ€”
161
- You : "resume yesterday's work"
162
- Claude : (session_resume) โ†’ re-reads task body + last checkpoint
163
- ```
164
-
165
- ### 2. Capture without breaking flow
166
-
167
- ```
168
- You : "While we're here โ€” idea: split this module into two"
169
- Claude : (inbox_add content="split foo module โ†’ two") โ€” back to current work
170
- ```
171
-
172
- Later:
173
- ```
174
- You : "show me the inbox"
175
- Claude : (inbox_list) โ†’ 12 raw items
176
- You : "research INBOX-008"
177
- Claude : (inbox_research) โ†’ reads codebase, writes findings, sets status=ready
178
- You : "convert it"
179
- Claude : (inbox_convert) โ†’ creates TASK-456 with body from research
180
- ```
181
-
182
- ### 3. Decision log next to code
183
-
184
- ```
185
- You : "should we use sqlite-vec or qdrant for embeddings?"
186
- Claude : (conversation_open "embedding store choice")
187
- Claude : (analyzes both, posts trade-offs)
188
- You : "go sqlite-vec for now"
189
- Claude : (conversation_decide "sqlite-vec โ€” brute KNN fine at our scale")
190
- Claude : (knowledge_create ADR-020 with refs to src/embeddings/*.ts)
191
- Claude : (conversation_close)
192
- ```
193
-
194
- Three months later, when you edit `src/embeddings/`:
195
- ```
196
- Claude : (knowledge_verify) โ†’ flags ADR-020 as potentially stale (refs SHA mismatch)
197
- ```
198
-
199
- ## Configuration
200
-
201
- | Env var | Default | Purpose |
202
- |---|---|---|
203
- | `CHODA_DATA_DIR` | _required_ | SQLite DB, artifacts, and backups directory. Created on first run. |
204
- | `CHODA_CONTENT_ROOT` | _optional_ | Root for knowledge / vault content lookup. |
205
-
206
- ### Data layout
207
-
208
- ```
209
- $CHODA_DATA_DIR/
210
- โ”œโ”€โ”€ database/choda-deck.db โ† single source of truth
211
- โ”œโ”€โ”€ artifacts/<sessionId>/ โ† per-session scratch
212
- โ””โ”€โ”€ backups/choda-deck-<date>.db โ† auto daily, retained
213
- ```
214
-
215
- ## Architecture
216
-
217
- - **SQLite** (`better-sqlite3`) โ€” single source of truth, file-based, no daemon
218
- - **MCP stdio** โ€” AI interaction layer (Anthropic's [Model Context Protocol](https://modelcontextprotocol.io))
219
- - **Pure Node runtime** โ€” no Electron, no PTY, no native deps beyond `better-sqlite3`
220
- - **Windows-first**, but runs on macOS and Linux
221
-
222
- 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.
223
-
224
- ## Status
225
-
226
- `0.2.0` โ€” early, dogfooded daily by the author. API may move before `1.0`. Issues + PRs welcome.
227
-
228
- ## License
229
-
230
- MIT โ€” see [LICENSE](./LICENSE).
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
+ [![npm version](https://img.shields.io/npm/v/choda-deck.svg)](https://www.npmjs.com/package/choda-deck)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./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
+ - ๐Ÿ’พ Auto-backup daily, restore on demand
22
+
23
+ Everything lives in a single SQLite file. No cloud, no SaaS, no telemetry.
24
+
25
+ ## Why?
26
+
27
+ Working with Claude Code across many days hits the same walls:
28
+
29
+ | Pain | Without choda-deck | With choda-deck |
30
+ |---|---|---|
31
+ | Lost task list | Scattered across markdown / TODO comments / chat history | One queryable source of truth |
32
+ | Lost context between sessions | Re-explain what you were doing last time | `session_resume` loads task body + AC + last checkpoint |
33
+ | Decisions disappear into chat | Scroll back, hope you find it | `conversation_decide` + `knowledge_create` log decisions next to code |
34
+ | Ideas dropped mid-flow | Forgotten or pile up in scratch files | `inbox_add` โ€” research/convert/archive later |
35
+ | ADRs drift from code | Manual review, never happens | `knowledge_verify` flags stale ADRs via `refs[]` |
36
+
37
+ choda-deck is the **memory layer** Claude wishes it had built-in.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ npm install -g choda-deck
43
+ # or run on demand
44
+ npx choda-deck
45
+ ```
46
+
47
+ Requires Node.js >= 20.
48
+
49
+ ## Wire it into your MCP client
50
+
51
+ choda-deck speaks stock MCP stdio โ€” works with any client that supports the protocol. Pick the one you use:
52
+
53
+ ### Claude Code
54
+
55
+ Add to `.claude.json` (user-level) or `.mcp.json` (project-level):
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "choda-tasks": {
61
+ "command": "npx",
62
+ "args": ["-y", "choda-deck"],
63
+ "env": {
64
+ "CHODA_DATA_DIR": "/absolute/path/to/data",
65
+ "CHODA_CONTENT_ROOT": "/absolute/path/to/your/notes-or-vault"
66
+ }
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ Restart Claude Code โ†’ the `choda-tasks` MCP server is online.
73
+
74
+ ### Claude Desktop
75
+
76
+ Edit `claude_desktop_config.json` (same `mcpServers` schema as above):
77
+
78
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
79
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
80
+ - **Linux:** `~/.config/Claude/claude_desktop_config.json`
81
+
82
+ Quit + reopen Claude Desktop. The hammer icon shows `choda-tasks` connected.
83
+
84
+ ### GitHub Copilot (VS Code)
85
+
86
+ Create `.vscode/mcp.json` in your workspace (or add to User Settings):
87
+
88
+ ```json
89
+ {
90
+ "servers": {
91
+ "choda-tasks": {
92
+ "type": "stdio",
93
+ "command": "npx",
94
+ "args": ["-y", "choda-deck"],
95
+ "env": {
96
+ "CHODA_DATA_DIR": "/absolute/path/to/data",
97
+ "CHODA_CONTENT_ROOT": "/absolute/path/to/your/notes-or-vault"
98
+ }
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ Note: Copilot uses `servers` (not `mcpServers`) and requires `"type": "stdio"`. Reload VS Code window โ†’ tools appear in Copilot Chat under agent mode.
105
+
106
+ ### Other clients (Cursor, Continue, Zed, โ€ฆ)
107
+
108
+ Any MCP-compatible client works. Use the `command` / `args` / `env` triple โ€” drop it into whatever the client calls its MCP config block.
109
+
110
+ ## CLI
111
+
112
+ `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`.
113
+
114
+ ```bash
115
+ choda-deck --help # show all subcommands
116
+ choda-deck task list --status TODO --json # script-friendly
117
+ choda-deck task show TASK-669 # body + linked conversations
118
+ choda-deck inbox list --project choda-deck
119
+ choda-deck knowledge list
120
+ choda-deck knowledge show ADR-020-embedding-architecture
121
+ choda-deck project context choda-deck # AI's session_start view
122
+ choda-deck mcp serve # start the MCP stdio server
123
+ ```
124
+
125
+ Pass `--json` to any read command for machine-readable output. Plain text is the default for humans.
126
+
127
+ ### Reading freshness
128
+
129
+ 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.
130
+
131
+ ## Tools
132
+
133
+ All tools are namespaced `mcp__choda-tasks__<name>`. Claude calls them on your behalf โ€” you never invoke them directly.
134
+
135
+ | Domain | Tools | What it does |
136
+ |---|---|---|
137
+ | **Project** | `project_add`, `project_list`, `project_context` | Multi-project setup. Each project has its own task list and metadata. |
138
+ | **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. |
139
+ | **Task** | `task_create`, `task_list`, `task_update`, `task_context` | TODO โ†’ READY โ†’ IN-PROGRESS โ†’ DONE/BLOCKED. Each task has body + acceptance criteria + labels + priority. |
140
+ | **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. |
141
+ | **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. |
142
+ | **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`. |
143
+ | **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. |
144
+ | **Backup** | `backup_create`, `backup_list`, `backup_restore` | Daily auto-backup of the SQLite DB. Manual create + restore when you need to roll back. |
145
+ | **Ops** | `stats_report`, `cleanup_worktree_orphans` | Tool-usage telemetry (per-tool calls / error rate / dead-in-window) + worktree GC. |
146
+
147
+ ## Common workflows
148
+
149
+ ### 1. Task-driven session
150
+
151
+ ```
152
+ You : "Let's work on TASK-123"
153
+ Claude : (task_context TASK-123) โ†’ loads body + AC
154
+ Claude : (session_start TASK-123) โ†’ binds session
155
+ You : (work happens)
156
+ Claude : (session_checkpoint "finished part 1, hit X issue")
157
+ You : "stop here, continue tomorrow"
158
+ Claude : (session_end)
159
+
160
+ โ€” next day โ€”
161
+ You : "resume yesterday's work"
162
+ Claude : (session_resume) โ†’ re-reads task body + last checkpoint
163
+ ```
164
+
165
+ ### 2. Capture without breaking flow
166
+
167
+ ```
168
+ You : "While we're here โ€” idea: split this module into two"
169
+ Claude : (inbox_add content="split foo module โ†’ two") โ€” back to current work
170
+ ```
171
+
172
+ Later:
173
+ ```
174
+ You : "show me the inbox"
175
+ Claude : (inbox_list) โ†’ 12 raw items
176
+ You : "research INBOX-008"
177
+ Claude : (inbox_research) โ†’ reads codebase, writes findings, sets status=ready
178
+ You : "convert it"
179
+ Claude : (inbox_convert) โ†’ creates TASK-456 with body from research
180
+ ```
181
+
182
+ ### 3. Decision log next to code
183
+
184
+ ```
185
+ You : "should we use sqlite-vec or qdrant for embeddings?"
186
+ Claude : (conversation_open "embedding store choice")
187
+ Claude : (analyzes both, posts trade-offs)
188
+ You : "go sqlite-vec for now"
189
+ Claude : (conversation_decide "sqlite-vec โ€” brute KNN fine at our scale")
190
+ Claude : (knowledge_create ADR-020 with refs to src/embeddings/*.ts)
191
+ Claude : (conversation_close)
192
+ ```
193
+
194
+ Three months later, when you edit `src/embeddings/`:
195
+ ```
196
+ Claude : (knowledge_verify) โ†’ flags ADR-020 as potentially stale (refs SHA mismatch)
197
+ ```
198
+
199
+ ## Configuration
200
+
201
+ | Env var | Default | Purpose |
202
+ |---|---|---|
203
+ | `CHODA_DATA_DIR` | _required_ | SQLite DB, artifacts, and backups directory. Created on first run. |
204
+ | `CHODA_CONTENT_ROOT` | _optional_ | Root for knowledge / vault content lookup. |
205
+ | `CHODA_BACKEND` | `sqlite` | Storage backend (ADR-030). `sqlite` (local file) or `postgres` (remote, k8s-friendly). |
206
+ | `CHODA_PG_URL` | _required when `CHODA_BACKEND=postgres`_ | Postgres connection string (e.g. `postgres://user:pass@host:5432/db`). |
207
+ | `CHODA_PG_POOL_SIZE` | `10` | Postgres connection pool max size. Tune for concurrent HTTP requests. |
208
+ | `CHODA_EMBEDDING_PROVIDER` | `local` | `local` (transformers.js MiniLM-L6) or `noop` (disable embedding-backed search). |
209
+
210
+ ### Data layout (SQLite)
211
+
212
+ ```
213
+ $CHODA_DATA_DIR/
214
+ โ”œโ”€โ”€ database/choda-deck.db โ† single source of truth
215
+ โ”œโ”€โ”€ artifacts/<sessionId>/ โ† per-session scratch
216
+ โ””โ”€โ”€ backups/choda-deck-<date>.db โ† auto daily, retained
217
+ ```
218
+
219
+ ### Postgres backend
220
+
221
+ 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).
222
+
223
+ **Local dev** with the shipped `docker-compose.yml`:
224
+
225
+ ```bash
226
+ docker compose up -d # boots pgvector/pgvector:pg16 on :5432
227
+ export CHODA_BACKEND=postgres
228
+ export CHODA_PG_URL="postgres://choda:choda@localhost:5432/choda"
229
+ pnpm run mcp:http # schema migrates on first connect
230
+ ```
231
+
232
+ **k8s** โ€” minimal `Deployment` + `Secret` shape:
233
+
234
+ ```yaml
235
+ apiVersion: v1
236
+ kind: Secret
237
+ metadata: { name: choda-pg }
238
+ type: Opaque
239
+ stringData:
240
+ CHODA_PG_URL: postgres://choda:CHANGEME@choda-pg.default.svc.cluster.local:5432/choda
241
+ MCP_HTTP_TOKEN: REPLACE_WITH_BASE64URL_32_BYTES
242
+ ---
243
+ apiVersion: apps/v1
244
+ kind: Deployment
245
+ metadata: { name: choda-deck }
246
+ spec:
247
+ replicas: 1
248
+ template:
249
+ spec:
250
+ containers:
251
+ - name: choda
252
+ image: ghcr.io/your-org/choda-deck:latest
253
+ env:
254
+ - { name: CHODA_BACKEND, value: postgres }
255
+ - { name: MCP_TRANSPORT, value: http }
256
+ - { name: MCP_HTTP_BIND, value: 0.0.0.0 }
257
+ envFrom:
258
+ - secretRef: { name: choda-pg }
259
+ ports:
260
+ - containerPort: 7337
261
+ readinessProbe:
262
+ httpGet: { path: /healthz, port: 7337 }
263
+ ```
264
+
265
+ 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.
266
+
267
+ **Migration from existing SQLite data** โ€” one-shot script:
268
+
269
+ ```bash
270
+ CHODA_PG_URL="postgres://choda:choda@localhost:5432/choda" \
271
+ node scripts/migrate-sqlite-to-postgres.mjs \
272
+ --sqlite $CHODA_DATA_DIR/database/choda-deck.db [--dry-run]
273
+ ```
274
+
275
+ 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.
276
+
277
+ 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.
278
+
279
+ ## Architecture
280
+
281
+ - **SQLite** (`better-sqlite3`) โ€” single source of truth, file-based, no daemon
282
+ - **MCP stdio** โ€” AI interaction layer (Anthropic's [Model Context Protocol](https://modelcontextprotocol.io))
283
+ - **Pure Node runtime** โ€” no Electron, no PTY, no native deps beyond `better-sqlite3`
284
+ - **Windows-first**, but runs on macOS and Linux
285
+
286
+ 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.
287
+
288
+ ## Status
289
+
290
+ `0.2.0` โ€” early, dogfooded daily by the author. API may move before `1.0`. Issues + PRs welcome.
291
+
292
+ ## License
293
+
294
+ MIT โ€” see [LICENSE](./LICENSE).