@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.
- package/ARCHITECTURE.md +567 -0
- package/FEATURE.md +108 -0
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/auto-route-D7W6RE06.mjs +86 -0
- package/dist/auto-route-D7W6RE06.mjs.map +1 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +5927 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/config-DBh1bYM2.mjs +151 -0
- package/dist/config-DBh1bYM2.mjs.map +1 -0
- package/dist/daemon/index.d.mts +1 -0
- package/dist/daemon/index.mjs +56 -0
- package/dist/daemon/index.mjs.map +1 -0
- package/dist/daemon-mcp/index.d.mts +1 -0
- package/dist/daemon-mcp/index.mjs +185 -0
- package/dist/daemon-mcp/index.mjs.map +1 -0
- package/dist/daemon-v5O897D4.mjs +773 -0
- package/dist/daemon-v5O897D4.mjs.map +1 -0
- package/dist/db-4lSqLFb8.mjs +199 -0
- package/dist/db-4lSqLFb8.mjs.map +1 -0
- package/dist/db-BcDxXVBu.mjs +110 -0
- package/dist/db-BcDxXVBu.mjs.map +1 -0
- package/dist/detect-BHqYcjJ1.mjs +86 -0
- package/dist/detect-BHqYcjJ1.mjs.map +1 -0
- package/dist/detector-DKA83aTZ.mjs +74 -0
- package/dist/detector-DKA83aTZ.mjs.map +1 -0
- package/dist/embeddings-mfqv-jFu.mjs +91 -0
- package/dist/embeddings-mfqv-jFu.mjs.map +1 -0
- package/dist/factory-BDAiKtYR.mjs +42 -0
- package/dist/factory-BDAiKtYR.mjs.map +1 -0
- package/dist/index.d.mts +307 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +11 -0
- package/dist/indexer-B20bPHL-.mjs +677 -0
- package/dist/indexer-B20bPHL-.mjs.map +1 -0
- package/dist/indexer-backend-BXaocO5r.mjs +360 -0
- package/dist/indexer-backend-BXaocO5r.mjs.map +1 -0
- package/dist/ipc-client-DPy7s3iu.mjs +156 -0
- package/dist/ipc-client-DPy7s3iu.mjs.map +1 -0
- package/dist/mcp/index.d.mts +1 -0
- package/dist/mcp/index.mjs +373 -0
- package/dist/mcp/index.mjs.map +1 -0
- package/dist/migrate-Bwj7qPaE.mjs +241 -0
- package/dist/migrate-Bwj7qPaE.mjs.map +1 -0
- package/dist/pai-marker-DX_mFLum.mjs +186 -0
- package/dist/pai-marker-DX_mFLum.mjs.map +1 -0
- package/dist/postgres-Ccvpc6fC.mjs +335 -0
- package/dist/postgres-Ccvpc6fC.mjs.map +1 -0
- package/dist/rolldown-runtime-95iHPtFO.mjs +18 -0
- package/dist/schemas-DjdwzIQ8.mjs +3405 -0
- package/dist/schemas-DjdwzIQ8.mjs.map +1 -0
- package/dist/search-PjftDxxs.mjs +282 -0
- package/dist/search-PjftDxxs.mjs.map +1 -0
- package/dist/sqlite-CHUrNtbI.mjs +90 -0
- package/dist/sqlite-CHUrNtbI.mjs.map +1 -0
- package/dist/tools-CLK4080-.mjs +805 -0
- package/dist/tools-CLK4080-.mjs.map +1 -0
- package/dist/utils-DEWdIFQ0.mjs +160 -0
- package/dist/utils-DEWdIFQ0.mjs.map +1 -0
- package/package.json +72 -0
- package/templates/README.md +181 -0
- package/templates/agent-prefs.example.md +362 -0
- package/templates/claude-md.template.md +733 -0
- package/templates/pai-project.template.md +13 -0
- package/templates/voices.example.json +251 -0
package/ARCHITECTURE.md
ADDED
|
@@ -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.
|