@tekmidian/pai 0.1.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.
Files changed (66) hide show
  1. package/ARCHITECTURE.md +567 -0
  2. package/FEATURE.md +108 -0
  3. package/LICENSE +21 -0
  4. package/README.md +101 -0
  5. package/dist/auto-route-D7W6RE06.mjs +86 -0
  6. package/dist/auto-route-D7W6RE06.mjs.map +1 -0
  7. package/dist/cli/index.d.mts +1 -0
  8. package/dist/cli/index.mjs +5927 -0
  9. package/dist/cli/index.mjs.map +1 -0
  10. package/dist/config-DBh1bYM2.mjs +151 -0
  11. package/dist/config-DBh1bYM2.mjs.map +1 -0
  12. package/dist/daemon/index.d.mts +1 -0
  13. package/dist/daemon/index.mjs +56 -0
  14. package/dist/daemon/index.mjs.map +1 -0
  15. package/dist/daemon-mcp/index.d.mts +1 -0
  16. package/dist/daemon-mcp/index.mjs +185 -0
  17. package/dist/daemon-mcp/index.mjs.map +1 -0
  18. package/dist/daemon-v5O897D4.mjs +773 -0
  19. package/dist/daemon-v5O897D4.mjs.map +1 -0
  20. package/dist/db-4lSqLFb8.mjs +199 -0
  21. package/dist/db-4lSqLFb8.mjs.map +1 -0
  22. package/dist/db-BcDxXVBu.mjs +110 -0
  23. package/dist/db-BcDxXVBu.mjs.map +1 -0
  24. package/dist/detect-BHqYcjJ1.mjs +86 -0
  25. package/dist/detect-BHqYcjJ1.mjs.map +1 -0
  26. package/dist/detector-DKA83aTZ.mjs +74 -0
  27. package/dist/detector-DKA83aTZ.mjs.map +1 -0
  28. package/dist/embeddings-mfqv-jFu.mjs +91 -0
  29. package/dist/embeddings-mfqv-jFu.mjs.map +1 -0
  30. package/dist/factory-BDAiKtYR.mjs +42 -0
  31. package/dist/factory-BDAiKtYR.mjs.map +1 -0
  32. package/dist/index.d.mts +307 -0
  33. package/dist/index.d.mts.map +1 -0
  34. package/dist/index.mjs +11 -0
  35. package/dist/indexer-B20bPHL-.mjs +677 -0
  36. package/dist/indexer-B20bPHL-.mjs.map +1 -0
  37. package/dist/indexer-backend-BXaocO5r.mjs +360 -0
  38. package/dist/indexer-backend-BXaocO5r.mjs.map +1 -0
  39. package/dist/ipc-client-DPy7s3iu.mjs +156 -0
  40. package/dist/ipc-client-DPy7s3iu.mjs.map +1 -0
  41. package/dist/mcp/index.d.mts +1 -0
  42. package/dist/mcp/index.mjs +373 -0
  43. package/dist/mcp/index.mjs.map +1 -0
  44. package/dist/migrate-Bwj7qPaE.mjs +241 -0
  45. package/dist/migrate-Bwj7qPaE.mjs.map +1 -0
  46. package/dist/pai-marker-DX_mFLum.mjs +186 -0
  47. package/dist/pai-marker-DX_mFLum.mjs.map +1 -0
  48. package/dist/postgres-Ccvpc6fC.mjs +335 -0
  49. package/dist/postgres-Ccvpc6fC.mjs.map +1 -0
  50. package/dist/rolldown-runtime-95iHPtFO.mjs +18 -0
  51. package/dist/schemas-DjdwzIQ8.mjs +3405 -0
  52. package/dist/schemas-DjdwzIQ8.mjs.map +1 -0
  53. package/dist/search-PjftDxxs.mjs +282 -0
  54. package/dist/search-PjftDxxs.mjs.map +1 -0
  55. package/dist/sqlite-CHUrNtbI.mjs +90 -0
  56. package/dist/sqlite-CHUrNtbI.mjs.map +1 -0
  57. package/dist/tools-CLK4080-.mjs +805 -0
  58. package/dist/tools-CLK4080-.mjs.map +1 -0
  59. package/dist/utils-DEWdIFQ0.mjs +160 -0
  60. package/dist/utils-DEWdIFQ0.mjs.map +1 -0
  61. package/package.json +72 -0
  62. package/templates/README.md +181 -0
  63. package/templates/agent-prefs.example.md +362 -0
  64. package/templates/claude-md.template.md +733 -0
  65. package/templates/pai-project.template.md +13 -0
  66. package/templates/voices.example.json +251 -0
@@ -0,0 +1,567 @@
1
+ # PAI Knowledge OS — Architecture
2
+
3
+ Technical reference for PAI's architecture, database schema, CLI commands, and development setup.
4
+
5
+ For user-facing documentation, see [README.md](README.md) and [MANUAL.md](MANUAL.md).
6
+
7
+ ---
8
+
9
+ ## Architecture
10
+
11
+ ```
12
+ Claude Code Session
13
+
14
+ ├── MCP Shim (stdio)
15
+ │ ↓ NDJSON over /tmp/pai.sock
16
+
17
+ ├── PAI Daemon (com.pai.pai-daemon)
18
+ │ ├── Scheduler: index every 5 min
19
+ │ ├── Async embedding (Snowflake Arctic, 768-dim)
20
+ │ └── Storage Backend (pluggable)
21
+ │ ↓
22
+ │ PostgreSQL + pgvector
23
+ │ (chunks, embeddings, files, FTS)
24
+
25
+ ├── Registry (SQLite)
26
+ │ ~/.pai/registry.db
27
+ │ Projects, sessions, tags, aliases, links
28
+
29
+ └── CLI (pai)
30
+ project, session, registry, memory,
31
+ daemon, obsidian, backup, restore, setup
32
+ ```
33
+
34
+ ### Key Components
35
+
36
+ **Daemon (`com.pai.pai-daemon`)** — A persistent launchd service that owns the indexing lifecycle. It exposes a Unix socket at `/tmp/pai.sock` and speaks NDJSON. The MCP shim connects to this socket rather than to the database directly, which means multiple Claude Code sessions can share a single daemon without connection contention.
37
+
38
+ **Storage** — Two databases serve different roles:
39
+
40
+ - **PostgreSQL + pgvector** (`pai` database, Docker): Stores text chunks, vector embeddings (768-dim, Snowflake Arctic), and file metadata. HNSW indexes for fast approximate nearest-neighbor search. GIN indexes for full-text search.
41
+ - **SQLite registry** (`~/.pai/registry.db`): Lightweight metadata store for projects, sessions, tags, aliases, and cross-references.
42
+
43
+ **Embeddings** — Snowflake Arctic Embed produces 768-dimensional embeddings. The daemon generates embeddings asynchronously in the background after initial text indexing, so keyword search is available immediately and semantic search follows within minutes.
44
+
45
+ ---
46
+
47
+ ## Quick Start
48
+
49
+ ### Prerequisites
50
+
51
+ - [Bun](https://bun.sh) (JavaScript runtime and package manager)
52
+ - [Docker](https://docs.docker.com/get-docker/) (for the PostgreSQL + pgvector container)
53
+ - [Claude Code](https://claude.ai/code) (the CLI this integrates with)
54
+
55
+ ### 1. Clone and Build
56
+
57
+ ```bash
58
+ git clone https://github.com/mnott/PAI.git
59
+ cd PAI
60
+ bun install
61
+ bun run build
62
+ ```
63
+
64
+ The build uses `tsdown` to compile TypeScript. Link the CLI globally:
65
+
66
+ ```bash
67
+ npm link # or: ln -s $(pwd)/dist/cli/index.mjs /usr/local/bin/pai
68
+ ```
69
+
70
+ ### 2. Start PostgreSQL with pgvector
71
+
72
+ ```bash
73
+ docker run -d \
74
+ --name pai-postgres \
75
+ -e POSTGRES_USER=pai \
76
+ -e POSTGRES_PASSWORD=pai \
77
+ -e POSTGRES_DB=pai \
78
+ -p 127.0.0.1:5432:5432 \
79
+ pgvector/pgvector:pg17
80
+ ```
81
+
82
+ ### 3. Run the Setup Wizard
83
+
84
+ ```bash
85
+ pai setup
86
+ ```
87
+
88
+ The interactive wizard walks through seven steps:
89
+
90
+ 1. PostgreSQL connection (host, port, credentials)
91
+ 2. Embedding model selection (Snowflake Arctic recommended)
92
+ 3. Indexing interval (default: 5 minutes)
93
+ 4. CLAUDE.md template installation
94
+ 5. Projects root directory
95
+ 6. Obsidian vault location (optional)
96
+ 7. MCP server registration with Claude Code
97
+
98
+ ### 4. Install the Daemon
99
+
100
+ ```bash
101
+ pai daemon install
102
+ ```
103
+
104
+ This registers `com.pai.pai-daemon` as a launchd service and adds the PAI MCP server to your Claude Code configuration (`~/.claude.json`). The daemon starts immediately and begins indexing.
105
+
106
+ ### 5. Verify
107
+
108
+ ```bash
109
+ pai daemon status # Confirm the daemon is running
110
+ pai memory status # Check index stats (files, chunks, embeddings)
111
+ ```
112
+
113
+ If both commands return healthy output, PAI is running. Open a new Claude Code session — the MCP tools will be available immediately.
114
+
115
+ ### Directory Layout After Setup
116
+
117
+ ```
118
+ ~/.pai/
119
+ registry.db # SQLite project registry
120
+ obsidian-vault/ # Symlinked Obsidian vault (if configured)
121
+ backups/ # Timestamped backups from `pai backup`
122
+
123
+ ~/.config/pai/
124
+ config.json # Daemon runtime configuration
125
+ voices.json # Voice TTS configuration (optional)
126
+
127
+ /tmp/
128
+ pai.sock # Unix socket (daemon)
129
+ pai-daemon.log # Daemon log
130
+ ```
131
+
132
+ ---
133
+
134
+ ## MCP Server
135
+
136
+ PAI exposes 7 tools to Claude Code via a daemon-backed MCP shim. The shim speaks stdio (what Claude Code expects) and proxies each request to the background daemon over NDJSON on a Unix socket.
137
+
138
+ ```
139
+ Claude Code (stdio)
140
+ └── PAI MCP shim (dist/daemon-mcp/index.mjs)
141
+ └── NDJSON over /tmp/pai.sock
142
+ └── PAI daemon (com.pai.pai-daemon)
143
+ └── PostgreSQL + pgvector
144
+ ```
145
+
146
+ ### Available Tools
147
+
148
+ | Tool | Description |
149
+ |------|-------------|
150
+ | `memory_search` | Search indexed memory across projects |
151
+ | `memory_get` | Retrieve full content of a specific file |
152
+ | `project_info` | Look up a project by slug, alias, or number |
153
+ | `project_list` | List all registered projects |
154
+ | `session_list` | List session notes, optionally filtered by project |
155
+ | `registry_search` | Search project metadata (names, paths, tags) |
156
+ | `project_detect` | Identify which project a given path belongs to |
157
+
158
+ ### Tool Reference
159
+
160
+ **`memory_search(query, mode?, project?, limit?)`** — Search the indexed knowledge base. Returns ranked chunks with file paths and line numbers. `mode`: `keyword` (default), `semantic`, or `hybrid`.
161
+
162
+ **`memory_get(project, path)`** — Retrieve the complete contents of a specific file from a project's memory index.
163
+
164
+ **`project_info(identifier)`** — Returns metadata for a project. Accepts a slug, numeric ID, or alias.
165
+
166
+ **`project_list(status?)`** — Lists all projects in the registry. Filter by `active`, `archived`, or `all`.
167
+
168
+ **`session_list(project?, limit?)`** — Lists session notes sorted by date descending.
169
+
170
+ **`registry_search(query)`** — Full-text search over project metadata — names, paths, tags.
171
+
172
+ **`project_detect(path?)`** — Given a filesystem path (defaults to CWD), returns the matching project.
173
+
174
+ ### Installation
175
+
176
+ ```bash
177
+ pai mcp install # Install MCP shim only
178
+ pai daemon install # Install daemon + MCP together (recommended)
179
+ ```
180
+
181
+ Restart Claude Code after installation for the tools to appear.
182
+
183
+ ---
184
+
185
+ ## Search Modes
186
+
187
+ Three modes, selectable via the `--mode` flag on the CLI or the `mode` parameter in MCP tool calls.
188
+
189
+ ### Keyword (default)
190
+
191
+ PostgreSQL full-text search using `ts_rank`. No machine learning required. Performs well for exact terms, file names, session numbers, and known identifiers.
192
+
193
+ ```bash
194
+ pai memory search "session 0087 obsidian bridge"
195
+ ```
196
+
197
+ FTS query builders use OR operators rather than AND. `ts_rank` scores multi-match chunks higher naturally, so recall is maximized while precision comes from ranking.
198
+
199
+ ### Semantic
200
+
201
+ Vector similarity search using pgvector cosine distance on 768-dimensional Snowflake Arctic embeddings. Matches concepts across paraphrasing, synonyms, and language boundaries.
202
+
203
+ ```bash
204
+ pai memory search --mode semantic "how do I reconnect the messenger daemon"
205
+ ```
206
+
207
+ Embeddings are generated asynchronously by the daemon scheduler or on demand via `pai memory embed`.
208
+
209
+ ### Hybrid
210
+
211
+ Runs both keyword and semantic pipelines, normalizes each result set to a 0–1 score range, then blends them with a configurable weight. Delivers the best overall result quality.
212
+
213
+ ```bash
214
+ pai memory search --mode hybrid "rate limiting patterns"
215
+ ```
216
+
217
+ ### Mode Comparison
218
+
219
+ | Mode | Speed | Requires Embeddings | Best For |
220
+ |------|-------|---------------------|----------|
221
+ | keyword | Fast | No | Exact terms, IDs, session numbers |
222
+ | semantic | Medium | Yes | Concepts, paraphrases, cross-language |
223
+ | hybrid | Medium | Yes | General-purpose, best quality |
224
+
225
+ ---
226
+
227
+ ## CLI Reference
228
+
229
+ ### Project Management
230
+
231
+ | Subcommand | Description |
232
+ |------------|-------------|
233
+ | `project add <path>` | Register a new project |
234
+ | `project list` | List all registered projects |
235
+ | `project info <slug>` | Show project details and metadata |
236
+ | `project archive <slug>` | Archive a project |
237
+ | `project unarchive <slug>` | Restore an archived project |
238
+ | `project move <slug> <path>` | Update a project's root path |
239
+ | `project tag <slug> <tag>` | Add a tag to a project |
240
+ | `project alias <slug> <alias>` | Add an alias for quick lookup |
241
+ | `project cd <slug>` | Print project path for shell navigation |
242
+ | `project detect` | Auto-detect project from CWD |
243
+ | `project health` | Audit all registered paths |
244
+ | `project consolidate <slug>` | Merge scattered Notes directories |
245
+ | `project promote` | Promote a session note into a project |
246
+
247
+ ```bash
248
+ pai project list
249
+ pai project info my-app
250
+ cd $(pai project cd my-app)
251
+ pai project health
252
+ pai project promote --from-session ~/.pai/sessions/0012 --to ~/projects/new-project
253
+ ```
254
+
255
+ ### Session Management
256
+
257
+ | Subcommand | Description |
258
+ |------------|-------------|
259
+ | `session list` | List sessions, optionally by project |
260
+ | `session info <slug> <number>` | Show session details |
261
+ | `session rename <slug> <number> <name>` | Rename a session note |
262
+ | `session tag <slug> <number> <tag>` | Tag a session |
263
+ | `session route <slug> <number> <target>` | Cross-reference to another project |
264
+ | `session cleanup` | Auto-name, organize into YYYY/MM folders |
265
+
266
+ ```bash
267
+ pai session list --project my-app
268
+ pai session cleanup
269
+ ```
270
+
271
+ ### Memory Engine
272
+
273
+ | Subcommand | Description |
274
+ |------------|-------------|
275
+ | `memory index` | Re-index files for keyword search |
276
+ | `memory embed` | Generate vector embeddings |
277
+ | `memory search <query>` | Search indexed content |
278
+ | `memory status` | Show index statistics |
279
+
280
+ ```bash
281
+ pai memory search "chrome browser"
282
+ pai memory search --mode semantic "how does authentication work"
283
+ pai memory search --mode hybrid "indexer exclusion patterns"
284
+ pai memory status
285
+ ```
286
+
287
+ ### Daemon Management
288
+
289
+ | Subcommand | Description |
290
+ |------------|-------------|
291
+ | `daemon serve` | Start daemon in foreground |
292
+ | `daemon status` | Check daemon health |
293
+ | `daemon restart` | Restart the running daemon |
294
+ | `daemon install` | Install as launchd service |
295
+ | `daemon uninstall` | Remove launchd service |
296
+ | `daemon logs` | View daemon logs |
297
+ | `daemon migrate` | Migrate SQLite → PostgreSQL |
298
+
299
+ ```bash
300
+ pai daemon status
301
+ pai daemon logs -f
302
+ pai daemon restart
303
+ ```
304
+
305
+ Socket: `/tmp/pai.sock` · Log: `/tmp/pai-daemon.log`
306
+
307
+ ### Registry Maintenance
308
+
309
+ | Subcommand | Description |
310
+ |------------|-------------|
311
+ | `registry scan` | Discover new projects |
312
+ | `registry migrate` | Apply schema migrations |
313
+ | `registry stats` | Show registry statistics |
314
+ | `registry rebuild` | Rebuild from scratch |
315
+ | `registry lookup <path>` | Resolve encoded path |
316
+
317
+ ```bash
318
+ pai registry scan
319
+ pai registry stats
320
+ ```
321
+
322
+ ### Obsidian Vault
323
+
324
+ | Subcommand | Description |
325
+ |------------|-------------|
326
+ | `obsidian sync` | Sync notes into vault as symlinks |
327
+ | `obsidian status` | Show vault health |
328
+ | `obsidian open` | Launch Obsidian |
329
+
330
+ ```bash
331
+ pai obsidian sync
332
+ pai obsidian status
333
+ ```
334
+
335
+ ### Other Commands
336
+
337
+ ```bash
338
+ pai backup # Backup registry, config, and Postgres
339
+ pai restore <path> # Restore from backup (--no-postgres to skip DB)
340
+ pai setup # Interactive 7-step setup wizard
341
+ pai search "query" # Quick full-text search shortcut
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Daemon
347
+
348
+ The PAI daemon is a persistent background service that handles indexing, embedding generation, and MCP request proxying.
349
+
350
+ ### What It Does
351
+
352
+ - Listens on Unix socket `/tmp/pai.sock` using NDJSON protocol
353
+ - Proxies all MCP tool calls from the shim to PostgreSQL
354
+ - Re-indexes all active projects on a configurable interval (default: every 5 minutes)
355
+ - Generates text embeddings asynchronously using Snowflake Arctic Embed (768-dim)
356
+
357
+ ### Configuration
358
+
359
+ ```json
360
+ {
361
+ "storageBackend": "postgres",
362
+ "socketPath": "/tmp/pai.sock",
363
+ "indexIntervalSecs": 300,
364
+ "postgres": {
365
+ "host": "127.0.0.1",
366
+ "port": 5432,
367
+ "database": "pai",
368
+ "user": "pai",
369
+ "password": "pai"
370
+ }
371
+ }
372
+ ```
373
+
374
+ | Key | Default | Description |
375
+ |-----|---------|-------------|
376
+ | `storageBackend` | `"postgres"` | Storage engine: `"postgres"` or `"sqlite"` |
377
+ | `socketPath` | `"/tmp/pai.sock"` | Unix socket path for daemon IPC |
378
+ | `indexIntervalSecs` | `300` | Seconds between full re-index runs |
379
+
380
+ ### Launchd Service
381
+
382
+ The daemon runs under the label `com.pai.pai-daemon`. The plist is installed to `~/Library/LaunchAgents/` by `pai daemon install`. launchd restarts the daemon automatically if it exits.
383
+
384
+ ---
385
+
386
+ ## Obsidian Bridge
387
+
388
+ PAI can expose your project memory as an Obsidian vault. The vault contains no actual files — only symlinks into each project's `Notes/` directory, so edits in Obsidian are immediately visible to PAI and vice versa.
389
+
390
+ ### Vault Layout
391
+
392
+ ```
393
+ ~/.pai/obsidian-vault/
394
+ ├── _index.md # Auto-generated landing page
395
+ ├── topics/
396
+ │ ├── active-projects.md # Links to all active project folders
397
+ │ └── recent-sessions.md # Latest sessions across all projects
398
+ ├── pai-knowledge-os -> ~/projects/PAI/Notes/
399
+ ├── my-app -> ~/projects/my-app/Notes/
400
+ └── api-service -> ~/projects/api-service/Notes/
401
+ ```
402
+
403
+ ### Vault Health
404
+
405
+ `pai obsidian status` reports three categories:
406
+
407
+ | Status | Meaning |
408
+ |--------|---------|
409
+ | Healthy | Symlink exists and target directory is present |
410
+ | Broken | Symlink exists but target has moved or been deleted |
411
+ | Orphaned | Target directory exists but symlink is missing |
412
+
413
+ ---
414
+
415
+ ## Templates
416
+
417
+ PAI ships three templates used during setup and customizable for your workflow.
418
+
419
+ ### `templates/claude-md.template.md`
420
+
421
+ A publishable CLAUDE.md template containing generic agent orchestration patterns: swarm mode, parallel execution, model selection matrix (haiku/sonnet/opus), mandatory spotchecks, and directory restrictions.
422
+
423
+ `pai setup` generates your `~/.claude/CLAUDE.md` from this template, substituting `${HOME}` with your home directory.
424
+
425
+ ### `templates/agent-prefs.example.md`
426
+
427
+ Personal preferences template covering identity, project mappings, notifications, voice, and git rules. Copy to `~/.config/pai/agent-prefs.md` and customize.
428
+
429
+ ### `templates/voices.example.json`
430
+
431
+ Voice configuration for TTS integration. Supports Kokoro (local, no API key) and ElevenLabs:
432
+
433
+ ```json
434
+ {
435
+ "backend": "kokoro",
436
+ "default_voice": "af_heart",
437
+ "agents": {
438
+ "main": "af_heart",
439
+ "researcher": "bm_george"
440
+ }
441
+ }
442
+ ```
443
+
444
+ Copy to `~/.config/pai/voices.json` and configure your preferred backend.
445
+
446
+ ---
447
+
448
+ ## Database Schema
449
+
450
+ ### Registry (`~/.pai/registry.db` — SQLite)
451
+
452
+ | Table | Key Columns |
453
+ |-------|-------------|
454
+ | `projects` | id, slug, root_path, claude_notes_dir, status, tags, aliases, created_at |
455
+ | `sessions` | id, project_id, number, date, slug, file_path, tags |
456
+ | `links` | source_session_id, target_project_id, link_type |
457
+
458
+ ### Federation (`pai` PostgreSQL + pgvector)
459
+
460
+ **`pai_chunks`** — Indexed content chunks with embeddings:
461
+
462
+ | Column | Type | Description |
463
+ |--------|------|-------------|
464
+ | `id` | TEXT | SHA-256 chunk identifier |
465
+ | `project_id` | INTEGER | Owning project |
466
+ | `source` | TEXT | `memory`, `notes`, or `content` |
467
+ | `tier` | TEXT | `evergreen`, `topic`, or `session` |
468
+ | `path` | TEXT | Relative path within project |
469
+ | `start_line` / `end_line` | INTEGER | Line range in source file |
470
+ | `hash` | TEXT | SHA-256 of chunk text |
471
+ | `text` | TEXT | Raw chunk content |
472
+ | `embedding` | vector(768) | Snowflake Arctic embedding (nullable) |
473
+ | `updated_at` | BIGINT | Last index timestamp |
474
+
475
+ **`pai_files`** — File metadata for change detection:
476
+
477
+ | Column | Type | Description |
478
+ |--------|------|-------------|
479
+ | `project_id` | INTEGER | Owning project |
480
+ | `path` | TEXT | Relative path |
481
+ | `hash` | TEXT | SHA-256 of full file |
482
+ | `mtime` | BIGINT | Modification time |
483
+ | `size` | BIGINT | File size in bytes |
484
+
485
+ **Indexes:** HNSW on embedding (cosine), GIN on text (tsvector), B-tree on project_id/path.
486
+
487
+ **Content Tiers:**
488
+
489
+ | Tier | Description | Example |
490
+ |------|-------------|---------|
491
+ | `evergreen` | Permanent, high-signal memory | `MEMORY.md` |
492
+ | `topic` | Structured content files | Documentation, topic pages |
493
+ | `session` | Session notes | `Notes/0087 - 2026-02-20 - Obsidian Bridge.md` |
494
+
495
+ ---
496
+
497
+ ## Backup and Restore
498
+
499
+ ### Creating a Backup
500
+
501
+ ```bash
502
+ pai backup
503
+ ```
504
+
505
+ Creates a timestamped directory under `~/.pai/backups/` containing: `registry.db`, `config.json`, `federation.db` (if SQLite fallback active), and a `pg_dump` of the PostgreSQL database.
506
+
507
+ ### Restoring
508
+
509
+ ```bash
510
+ pai restore ~/.pai/backups/2026-02-25T14-30-00
511
+ pai restore ~/.pai/backups/2026-02-25T14-30-00 --no-postgres
512
+ ```
513
+
514
+ The `--no-postgres` flag skips PostgreSQL restore — useful when restoring to a fresh instance you intend to re-index.
515
+
516
+ ---
517
+
518
+ ## Development
519
+
520
+ ### Build
521
+
522
+ ```bash
523
+ bun install
524
+ bun run build # Uses tsdown (NOT tsup)
525
+ bun run dev # Watch mode
526
+ bun run test # vitest
527
+ bun run lint # tsc --noEmit
528
+ ```
529
+
530
+ ### Build Outputs
531
+
532
+ | Output | Purpose |
533
+ |--------|---------|
534
+ | `dist/cli/index.mjs` | `pai` CLI |
535
+ | `dist/mcp/index.mjs` | Direct MCP server (legacy) |
536
+ | `dist/daemon/index.mjs` | Daemon server |
537
+ | `dist/daemon-mcp/index.mjs` | MCP shim (stdio → daemon socket) |
538
+
539
+ ### Source Structure
540
+
541
+ ```
542
+ src/
543
+ ├── cli/commands/ # CLI command implementations
544
+ ├── daemon/ # Daemon server and index scheduler
545
+ ├── daemon-mcp/ # MCP shim (stdio → daemon socket)
546
+ ├── federation/ # Federation schema definitions
547
+ ├── hooks/ # Lifecycle hooks (pre-compact, session-stop)
548
+ ├── mcp/ # Direct MCP server (legacy)
549
+ ├── memory/ # Indexer, chunker, embeddings, search
550
+ ├── obsidian/ # Obsidian vault bridge
551
+ ├── registry/ # Registry migrations and queries
552
+ ├── session/ # Session slug generator
553
+ └── storage/ # Storage backend interface (SQLite/Postgres)
554
+ ```
555
+
556
+ ### Important Notes
557
+
558
+ - **better-sqlite3 is not supported in Bun.** Migration scripts use `npx tsx` to run under Node.js.
559
+ - **Do not substitute tsup for tsdown.** The build configuration depends on tsdown-specific behavior.
560
+ - The daemon and MCP shim communicate exclusively over the Unix socket. The shim holds no state.
561
+ - Embedding generation is always asynchronous. Text indexing is immediate; embeddings are processed in the background.
562
+
563
+ ---
564
+
565
+ ## License
566
+
567
+ MIT
package/FEATURE.md ADDED
@@ -0,0 +1,108 @@
1
+ # PAI Feature Comparison
2
+
3
+ ## Credit
4
+
5
+ This project is inspired by Daniel Miessler's work. He coined the "PAI" concept (Personal AI
6
+ Infrastructure) and built [Fabric](https://github.com/danielmiessler/fabric), a Python CLI for
7
+ augmenting human capabilities with reusable AI prompt patterns. If you haven't seen Fabric,
8
+ go look at it — it's excellent and solves a different problem extremely well.
9
+
10
+ This repository, PAI Knowledge OS, starts from the same name and philosophy but takes a
11
+ different direction: persistent memory, session continuity, and deep Claude Code integration.
12
+
13
+ ---
14
+
15
+ ## Feature Comparison
16
+
17
+ | Feature | Fabric (Miessler) | PAI Knowledge OS (this) |
18
+ |---|---|---|
19
+ | **Language** | Python | TypeScript (Bun) |
20
+ | **Primary interface** | CLI pipe (`echo "..." \| fabric -p pattern`) | MCP server + CLI (`pai`) |
21
+ | **Prompt templates** | Yes — 200+ community "patterns" | No (out of scope) |
22
+ | **YouTube transcript extraction** | Yes (built-in) | No |
23
+ | **LLM pipe-through workflow** | Yes — core feature | No |
24
+ | **Persistent session memory** | No | Yes — auto-indexed, 449K+ chunks |
25
+ | **Session registry** | No | Yes — SQLite, tracks 77+ projects |
26
+ | **Background daemon** | No | Yes — launchd, IPC via Unix socket |
27
+ | **MCP server** | No | Yes — 7+ tools exposed to Claude Code |
28
+ | **Keyword search (BM25)** | No | Yes — GIN full-text index, PostgreSQL |
29
+ | **Semantic search (vector)** | No | Yes — pgvector HNSW, Snowflake Arctic 768-dim |
30
+ | **Multi-backend storage** | No | Yes — SQLite (simple) or PostgreSQL (full) |
31
+ | **Obsidian vault bridge** | No | Yes — symlinks + auto-generated topic pages |
32
+ | **Project lifecycle** | No | Yes — promote, archive, move, detect from cwd |
33
+ | **Setup wizard** | No | Yes — idempotent 7-step interactive wizard |
34
+ | **Hook system** | No | Yes — pre-compact, session-stop, auto-cleanup |
35
+ | **Backup / restore** | No | Yes — timestamped pg_dump + registry export |
36
+ | **Multi-session concurrency** | n/a | Yes — daemon multiplexes Claude sessions |
37
+ | **Local / private** | Yes | Yes — no cloud, no external API for core |
38
+ | **Docker required** | No | Only for full mode (PostgreSQL); SQLite mode needs none |
39
+ | **macOS / Linux** | Yes | Yes |
40
+
41
+ ---
42
+
43
+ ## What's New in PAI Knowledge OS
44
+
45
+ These are capabilities that don't exist in Fabric and address a specific problem:
46
+ Claude Code starts every session cold, with no memory of past work.
47
+
48
+ ### Persistent Memory Engine
49
+
50
+ A background daemon indexes your Claude Code session notes and project files every five
51
+ minutes. Chunks are hashed for change detection, stored in PostgreSQL, and made available
52
+ for both keyword search (BM25/GIN) and semantic search (pgvector HNSW). When you ask
53
+ "what were we doing with the authentication system last month?" — it finds it.
54
+
55
+ ### Session Registry
56
+
57
+ Every Claude Code project and session is tracked in a lightweight SQLite registry. Projects
58
+ are detected automatically from the current working directory. Sessions get unique numbers,
59
+ tags, aliases, and cross-references. You can query across all of them from any Claude session.
60
+
61
+ ### MCP Server + Daemon Architecture
62
+
63
+ The MCP server exposes memory and registry tools directly inside Claude Code. The daemon
64
+ handles the indexing lifecycle and accepts connections over a Unix socket, so multiple Claude
65
+ Code instances can share one daemon without contention. The MCP shim is a thin connector;
66
+ all state lives in the daemon.
67
+
68
+ ### Obsidian Vault Bridge
69
+
70
+ PAI can sync your session notes and project memory into an Obsidian vault as a live knowledge
71
+ graph. Symlinks connect the vault to your actual note files. Topic pages are auto-generated
72
+ from project metadata. The vault updates on demand via `pai obsidian sync`.
73
+
74
+ ### Two Storage Modes
75
+
76
+ Simple mode requires nothing beyond Bun — SQLite only, keyword search only. Full mode adds
77
+ Docker, PostgreSQL, pgvector, and Snowflake Arctic embeddings for semantic search. The setup
78
+ wizard asks which you want and configures everything.
79
+
80
+ ### Idempotent Setup Wizard
81
+
82
+ `pai setup` walks through configuration interactively and is safe to re-run. It handles
83
+ PostgreSQL connection, embedding model selection, indexing interval, CLAUDE.md template
84
+ installation, MCP server registration, and Obsidian configuration — and detects what's
85
+ already configured so re-runs only change what you choose.
86
+
87
+ ---
88
+
89
+ ## What Fabric Does That This Doesn't
90
+
91
+ To be clear about scope:
92
+
93
+ - **Prompt pattern library** — Fabric ships 200+ community-maintained prompt templates. PAI
94
+ Knowledge OS has no pattern system.
95
+ - **Pipe-through LLM workflows** — Fabric's `echo "..." | fabric -p pattern` idiom is elegant
96
+ for processing text at the command line. PAI doesn't replicate this.
97
+ - **YouTube / web extraction** — Fabric can pull transcripts and content from URLs as input to
98
+ patterns. PAI doesn't.
99
+
100
+ If you want prompt patterns and CLI pipe-through workflows, use Fabric. If you want Claude
101
+ Code to remember everything across sessions, use this.
102
+
103
+ ---
104
+
105
+ ## Using Both
106
+
107
+ They're not mutually exclusive. Fabric handles one-shot prompt workflows. PAI Knowledge OS
108
+ handles persistent memory for Claude Code. Many people will want both.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Matthias Nott
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.