@tekmidian/pai 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +82 -14
- package/FEATURE.md +7 -2
- package/PLUGIN-ARCHITECTURE.md +31 -16
- package/README.md +94 -9
- package/dist/cli/index.mjs +1 -1
- package/dist/daemon/index.mjs +1 -1
- package/dist/{daemon-B8pkxhSc.mjs → daemon-Ds9dTptY.mjs} +2 -2
- package/dist/{daemon-B8pkxhSc.mjs.map → daemon-Ds9dTptY.mjs.map} +1 -1
- package/dist/hooks/whisper-rules.mjs +1 -5
- package/dist/hooks/whisper-rules.mjs.map +2 -2
- package/dist/skills/Whisper/SKILL.md +49 -0
- package/package.json +1 -1
- package/src/hooks/ts/user-prompt/whisper-rules.ts +5 -8
package/ARCHITECTURE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# PAI Knowledge OS — Architecture
|
|
1
|
+
# PAI Knowledge OS — Architecture (v0.8.0)
|
|
2
2
|
|
|
3
3
|
Technical reference for PAI's architecture, database schema, CLI commands, and development setup.
|
|
4
4
|
|
|
@@ -151,7 +151,7 @@ If both commands return healthy output, PAI is running. Open a new Claude Code s
|
|
|
151
151
|
|
|
152
152
|
## MCP Server
|
|
153
153
|
|
|
154
|
-
PAI exposes 9 tools,
|
|
154
|
+
PAI exposes 9 tools, 19 on-demand prompts (skills), and 11 reference resources 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.
|
|
155
155
|
|
|
156
156
|
```
|
|
157
157
|
Claude Code (stdio)
|
|
@@ -207,6 +207,7 @@ The MCP server registers 18 prompts that Claude can invoke as on-demand skills.
|
|
|
207
207
|
| `name` | Session and project naming conventions |
|
|
208
208
|
| `observability` | Observation system usage and querying |
|
|
209
209
|
| `plan` | Forward-looking planning from TODOs and recent activity |
|
|
210
|
+
| `reconstruct` | Retroactively create session notes from JSONL transcripts and git history |
|
|
210
211
|
| `research` | Structured research methodology |
|
|
211
212
|
| `review` | Retrospective review of work over a time period |
|
|
212
213
|
| `route` | Session note routing across projects |
|
|
@@ -467,6 +468,8 @@ The PAI daemon is a persistent background service that handles indexing, embeddi
|
|
|
467
468
|
- Proxies all MCP tool calls from the shim to PostgreSQL
|
|
468
469
|
- Re-indexes all active projects on a configurable interval (default: every 5 minutes)
|
|
469
470
|
- Generates text embeddings asynchronously using Snowflake Arctic Embed (768-dim)
|
|
471
|
+
- Processes the persistent work queue: session summaries, topic detection, note updates
|
|
472
|
+
- Spawns headless Claude CLI processes for AI-powered session summarization
|
|
470
473
|
|
|
471
474
|
### Configuration
|
|
472
475
|
|
|
@@ -497,6 +500,62 @@ The daemon runs under the label `com.pai.pai-daemon`. The plist is installed to
|
|
|
497
500
|
|
|
498
501
|
---
|
|
499
502
|
|
|
503
|
+
## Work Queue and Session Summary Pipeline
|
|
504
|
+
|
|
505
|
+
The daemon owns a persistent work queue (`~/.config/pai/work-queue.json`) that decouples hook triggers from actual work. Hooks push lightweight work items to the queue and exit immediately. The daemon processes items sequentially from a background worker loop.
|
|
506
|
+
|
|
507
|
+
### Work Item Types
|
|
508
|
+
|
|
509
|
+
| Type | Who enqueues | Who processes | Description |
|
|
510
|
+
|------|-------------|---------------|-------------|
|
|
511
|
+
| `session-summary` | PreCompact, Stop hooks | `session-summary-worker.ts` | AI-powered summarization of JSONL transcript + git history |
|
|
512
|
+
| `topic-detect` | PreCompact hook | `topic-detect-worker.ts` | BM25-based topic shift detection for note splitting |
|
|
513
|
+
| `session-end` | Stop hook | `work-queue-worker.ts` | General session cleanup coordination |
|
|
514
|
+
| `note-update` | Session summary worker | `work-queue-worker.ts` | Write or update a session note file |
|
|
515
|
+
| `todo-update` | Session summary worker | `work-queue-worker.ts` | Update TODO.md with session state |
|
|
516
|
+
|
|
517
|
+
Work items are retried with exponential backoff (default max 3 attempts). The queue is written atomically (write temp file, then rename) to prevent corruption on daemon restart.
|
|
518
|
+
|
|
519
|
+
### Session Summary Pipeline
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
Stop or PreCompact hook fires
|
|
523
|
+
│
|
|
524
|
+
├── Hook reads minimal data (session_id, transcript_path, cwd)
|
|
525
|
+
├── Hook pushes { type: "session-summary", payload: {...} } to work queue
|
|
526
|
+
└── Hook exits (sub-second)
|
|
527
|
+
|
|
528
|
+
⬇ Daemon worker loop picks up the item
|
|
529
|
+
|
|
530
|
+
session-summary-worker.ts
|
|
531
|
+
│
|
|
532
|
+
├── Reads JSONL transcript (500K limit for stop, 200K for compact)
|
|
533
|
+
├── Reads recent git log (last 20 commits)
|
|
534
|
+
├── Strips ANTHROPIC_API_KEY from environment
|
|
535
|
+
├── Spawns headless Claude CLI (Opus for stop, Sonnet for compact)
|
|
536
|
+
├── Prompt requests: TOPIC: line + Work Done / Key Decisions / Known Issues / Next Steps
|
|
537
|
+
├── Compares TOPIC: against existing note title (Jaccard similarity < 30% → new note)
|
|
538
|
+
└── Writes or updates session note in project's Notes directory
|
|
539
|
+
|
|
540
|
+
⬇ If topic-detect was also enqueued
|
|
541
|
+
|
|
542
|
+
topic-detect-worker.ts
|
|
543
|
+
│
|
|
544
|
+
├── Extracts recent user messages from JSONL
|
|
545
|
+
├── Runs BM25 topic shift detector against PAI memory DB
|
|
546
|
+
└── Records topic boundary marker (used by next session-summary run)
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Cooldown and Force Flags
|
|
550
|
+
|
|
551
|
+
A 30-minute cooldown prevents redundant summary updates during active sessions. The Stop hook sets a `force: true` flag to bypass the cooldown, ensuring the final session state is always written. The PreCompact hook respects the cooldown to avoid O(n) summarizations during rapid compaction cycles.
|
|
552
|
+
|
|
553
|
+
### Claude Binary Discovery
|
|
554
|
+
|
|
555
|
+
The daemon runs under launchd with a minimal PATH. The `findClaudeBinary()` function checks `~/.local/bin/claude` first, then falls back to standard PATH resolution. This handles the common case where Claude CLI is installed via the npm global prefix, which launchd does not include in its environment PATH.
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
500
559
|
## Obsidian Bridge
|
|
501
560
|
|
|
502
561
|
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.
|
|
@@ -583,21 +642,22 @@ Claude Code Event
|
|
|
583
642
|
| Hook | Event | Purpose |
|
|
584
643
|
|------|-------|---------|
|
|
585
644
|
| `load-core-context.mjs` | SessionStart | Loads PAI skill system and core configuration |
|
|
586
|
-
| `load-project-context.mjs` | SessionStart | Detects project, loads notes dir, TODO, session note |
|
|
645
|
+
| `load-project-context.mjs` | SessionStart | Detects project, loads notes dir, TODO, session note; auto-registers new projects from .git, package.json, pubspec.yaml, and other signals |
|
|
587
646
|
| `initialize-session.mjs` | SessionStart | Creates numbered session note, registers in PAI registry |
|
|
588
647
|
| `post-compact-inject.mjs` | SessionStart (compact) | Reads saved state and injects into post-compaction context |
|
|
589
648
|
| `security-validator.mjs` | PreToolUse (Bash) | Validates shell commands against security rules |
|
|
590
649
|
| `capture-all-events.mjs` | All events | Observability — logs every hook event to session timeline |
|
|
591
650
|
| `observe.mjs` | PostToolUse | Classifies tool calls into typed observations (decision/bugfix/feature/refactor/discovery/change) |
|
|
592
651
|
| `inject-observations.mjs` | SessionStart | Injects recent observation context (compact index + timeline) |
|
|
593
|
-
| `context-compression-hook.mjs` | PreCompact | Extracts session state, saves checkpoint,
|
|
652
|
+
| `context-compression-hook.mjs` | PreCompact | Extracts session state, saves checkpoint, pushes session-summary work item to daemon |
|
|
594
653
|
| `capture-tool-output.mjs` | PostToolUse | Records tool inputs/outputs for observability dashboard |
|
|
595
654
|
| `update-tab-on-action.mjs` | PostToolUse | Updates terminal tab title based on current activity |
|
|
596
655
|
| `sync-todo-to-md.mjs` | PostToolUse (TodoWrite) | Syncs Claude's internal TODO list to `Notes/TODO.md` |
|
|
597
656
|
| `cleanup-session-files.mjs` | UserPromptSubmit | Cleans up stale temp files between prompts |
|
|
598
657
|
| `update-tab-titles.mjs` | UserPromptSubmit | Sets terminal tab title from session context |
|
|
599
|
-
| `
|
|
600
|
-
| `
|
|
658
|
+
| `whisper-rules.mjs` | UserPromptSubmit | Injects critical operating rules on every prompt; rules survive compaction and /clear |
|
|
659
|
+
| `stop-hook.mjs` | Stop | Pushes session-summary work item to daemon queue, sends notification |
|
|
660
|
+
| `capture-session-summary.mjs` | SessionEnd | Pushes session-summary work item to daemon queue |
|
|
601
661
|
| `subagent-stop-hook.mjs` | SubagentStop | Captures sub-agent completion for observability |
|
|
602
662
|
|
|
603
663
|
### Context Preservation Relay
|
|
@@ -942,8 +1002,14 @@ src/
|
|
|
942
1002
|
│ ├── daemon/ # Daemon server internals
|
|
943
1003
|
│ │ ├── dispatcher.ts # Tool dispatch (zettel, observation, memory)
|
|
944
1004
|
│ │ ├── handler.ts # NDJSON request handler
|
|
945
|
-
│ │
|
|
946
|
-
│ ├──
|
|
1005
|
+
│ │ ├── scheduler.ts # Background index scheduler
|
|
1006
|
+
│ │ ├── server.ts # Socket server
|
|
1007
|
+
│ │ ├── state.ts # Shared daemon state
|
|
1008
|
+
│ │ └── types.ts # Shared type definitions
|
|
1009
|
+
│ ├── session-summary-worker.ts # AI-powered session summarization (Opus/Sonnet)
|
|
1010
|
+
│ ├── topic-detect-worker.ts # BM25-based topic shift detection
|
|
1011
|
+
│ ├── work-queue-worker.ts # Generic work item processor
|
|
1012
|
+
│ ├── work-queue.ts # Persistent file-backed work queue
|
|
947
1013
|
│ ├── config.ts # Runtime configuration
|
|
948
1014
|
│ └── index.ts # Daemon entry point
|
|
949
1015
|
├── daemon-mcp/
|
|
@@ -954,12 +1020,14 @@ src/
|
|
|
954
1020
|
│ └── index.ts # MCP shim entry point (stdio → socket)
|
|
955
1021
|
├── hooks/
|
|
956
1022
|
│ └── ts/ # TypeScript hook sources by event
|
|
957
|
-
│ ├──
|
|
958
|
-
│ ├──
|
|
959
|
-
│ ├──
|
|
960
|
-
│ ├──
|
|
961
|
-
│ ├──
|
|
962
|
-
│
|
|
1023
|
+
│ ├── pre-compact/ # context-compression-hook.ts
|
|
1024
|
+
│ ├── pre-tool-use/ # security-validator
|
|
1025
|
+
│ ├── post-tool-use/ # observe, capture-tool-output, sync-todo-to-md, update-tab-on-action
|
|
1026
|
+
│ ├── session-start/ # load-core-context, load-project-context, initialize-session, inject-observations, post-compact-inject
|
|
1027
|
+
│ ├── session-end/ # capture-session-summary
|
|
1028
|
+
│ ├── stop/ # stop-hook
|
|
1029
|
+
│ ├── subagent-stop/ # subagent-stop-hook
|
|
1030
|
+
│ └── user-prompt/ # cleanup-session-files, update-tab-titles, whisper-rules
|
|
963
1031
|
├── mcp/
|
|
964
1032
|
│ └── tools/ # Shared tool implementations
|
|
965
1033
|
│ ├── memory.ts
|
package/FEATURE.md
CHANGED
|
@@ -28,14 +28,19 @@ different direction: persistent memory, session continuity, and deep Claude Code
|
|
|
28
28
|
| **Persistent session memory** | No | Yes — auto-indexed, 449K+ chunks |
|
|
29
29
|
| **Session registry** | No | Yes — SQLite, tracks 77+ projects |
|
|
30
30
|
| **Background daemon** | No | Yes — launchd, IPC via Unix socket |
|
|
31
|
-
| **MCP server** | No | Yes — 9 tools,
|
|
31
|
+
| **MCP server** | No | Yes — 9 tools, 19 prompts, 11 resources exposed to Claude Code |
|
|
32
32
|
| **Keyword search (BM25)** | No | Yes — GIN full-text index, PostgreSQL |
|
|
33
33
|
| **Semantic search (vector)** | No | Yes — pgvector HNSW, Snowflake Arctic 768-dim |
|
|
34
34
|
| **Multi-backend storage** | No | Yes — SQLite (simple) or PostgreSQL (full) |
|
|
35
35
|
| **Obsidian vault bridge** | No | Yes — symlinks + auto-generated topic pages |
|
|
36
36
|
| **Project lifecycle** | No | Yes — promote, archive, move, detect from cwd |
|
|
37
|
+
| **Auto project registration** | No | Yes — detects .git, package.json, pubspec.yaml, etc. on session start |
|
|
37
38
|
| **Setup wizard** | No | Yes — idempotent 14-step interactive wizard |
|
|
38
|
-
| **Hook system** | No | Yes — pre-compact, session-stop, auto-cleanup |
|
|
39
|
+
| **Hook system** | No | Yes — pre-compact, session-stop, auto-cleanup, whisper rules |
|
|
40
|
+
| **Automatic session notes** | No | Yes — AI-generated via daemon worker (Opus/Sonnet), topic-based splitting |
|
|
41
|
+
| **Topic-based note splitting** | No | Yes — Jaccard similarity detects topic shifts, creates separate notes |
|
|
42
|
+
| **Whisper rules** | No | Yes — injects critical rules on every prompt, survives compaction and /clear |
|
|
43
|
+
| **Session note reconstruction** | No | Yes — /reconstruct skill retroactively creates notes from JSONL + git history |
|
|
39
44
|
| **Backup / restore** | No | Yes — timestamped pg_dump + registry export |
|
|
40
45
|
| **Multi-session concurrency** | n/a | Yes — daemon multiplexes Claude sessions |
|
|
41
46
|
| **Custom statusline** | No | Yes — model, MCPs, context meter, colors |
|
package/PLUGIN-ARCHITECTURE.md
CHANGED
|
@@ -6,7 +6,7 @@ Technical reference for PAI's modular plugin system, cross-platform support, use
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
PAI is structured as a modular plugin system with 8 named modules organized into 3 pricing tiers. The architecture supports Claude Code (full integration), Cursor (MCP only), and Gemini CLI (MCP only).
|
|
9
|
+
PAI is structured as a modular plugin system with 8 named modules organized into 3 pricing tiers. The architecture supports Claude Code (full integration), Cursor (MCP only), and Gemini CLI (MCP only). Current version: 0.8.0.
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
PAI Knowledge OS
|
|
@@ -54,24 +54,24 @@ Each module has a `plugins/<module>/plugin.json` that declares:
|
|
|
54
54
|
|
|
55
55
|
| Module | Tier | Hooks | Skills | Description |
|
|
56
56
|
|--------|------|-------|--------|-------------|
|
|
57
|
-
| `core` | free | 6 | 3 | Memory engine, sessions, projects, security |
|
|
58
|
-
| `productivity` | free | 2 |
|
|
59
|
-
| `ui` | free |
|
|
57
|
+
| `core` | free | 6 | 3 | Memory engine, sessions, projects, security, auto-registration |
|
|
58
|
+
| `productivity` | free | 2 | 7 | Plan, Review, Journal, Research, Share, Createskill, Reconstruct |
|
|
59
|
+
| `ui` | free | 3 | 0 | Tab titles, statusline, tab coloring, whisper rules |
|
|
60
60
|
| `context-preservation` | free | 3 | 0 | Context compression and relay |
|
|
61
61
|
| `semantic-search` | pro | 0 | 0 | pgvector, reranking, hybrid search |
|
|
62
|
-
| `observability` | pro | 13 | 2 | Event capture, classification, summaries |
|
|
62
|
+
| `observability` | pro | 13 | 2 | Event capture, classification, AI-powered session summaries, topic detection |
|
|
63
63
|
| `zettelkasten` | enterprise | 0 | 5 | Graph operations, vault intelligence |
|
|
64
64
|
| `creative` | enterprise | 0 | 2 | Art direction, story, voice/prosody |
|
|
65
65
|
|
|
66
66
|
### Hook Distribution
|
|
67
67
|
|
|
68
|
-
Total:
|
|
68
|
+
Total: 27 hook registrations across 6 modules.
|
|
69
69
|
|
|
70
|
-
**Core (6):** load-core-context, load-project-context, initialize-session, security-validator, stop-hook, pai-session-stop.sh
|
|
70
|
+
**Core (6):** load-core-context, load-project-context (with auto-registration), initialize-session, security-validator, stop-hook, pai-session-stop.sh
|
|
71
71
|
|
|
72
72
|
**Productivity (2):** sync-todo-to-md, cleanup-session-files
|
|
73
73
|
|
|
74
|
-
**UI (
|
|
74
|
+
**UI (3):** update-tab-titles, update-tab-on-action, whisper-rules
|
|
75
75
|
|
|
76
76
|
**Context Preservation (3):** context-compression-hook, pai-pre-compact.sh, post-compact-inject
|
|
77
77
|
|
|
@@ -79,11 +79,11 @@ Total: 26 hook registrations across 6 modules.
|
|
|
79
79
|
|
|
80
80
|
### Skill Distribution
|
|
81
81
|
|
|
82
|
-
Total:
|
|
82
|
+
Total: 19 skills across 5 modules.
|
|
83
83
|
|
|
84
84
|
**Core (3):** Sessions, Route, Name
|
|
85
85
|
|
|
86
|
-
**Productivity (
|
|
86
|
+
**Productivity (7):** Plan, Review, Journal, Research, Share, Createskill, Reconstruct
|
|
87
87
|
|
|
88
88
|
**Observability (2):** Observability, SearchHistory
|
|
89
89
|
|
|
@@ -162,9 +162,9 @@ Claude Code gets the complete PAI experience:
|
|
|
162
162
|
|------------|---------|
|
|
163
163
|
| MCP Tools (9) | Full |
|
|
164
164
|
| MCP Resources (11) | Full |
|
|
165
|
-
| MCP Prompts (
|
|
166
|
-
| Hooks (
|
|
167
|
-
| Skills (
|
|
165
|
+
| MCP Prompts (19) | Full |
|
|
166
|
+
| Hooks (27 registrations) | Full |
|
|
167
|
+
| Skills (19 SKILL.md stubs) | Full |
|
|
168
168
|
| Statusline | Full |
|
|
169
169
|
| Tab management | Full |
|
|
170
170
|
|
|
@@ -342,16 +342,31 @@ No migration needed. The plugin architecture is purely additive:
|
|
|
342
342
|
|
|
343
343
|
## Future Roadmap
|
|
344
344
|
|
|
345
|
-
### Phase 1 (v0.7.0 —
|
|
345
|
+
### Phase 1 (v0.7.0 — Implemented)
|
|
346
346
|
- Module manifest system
|
|
347
347
|
- Cross-platform manifests
|
|
348
348
|
- User extension points
|
|
349
349
|
- Tier annotations (no enforcement)
|
|
350
350
|
|
|
351
|
-
### Phase 2 (v0.8.0)
|
|
351
|
+
### Phase 2 (v0.8.0 — Implemented)
|
|
352
|
+
- AI-powered session notes via daemon work queue
|
|
353
|
+
- Topic-based note splitting (Jaccard similarity)
|
|
354
|
+
- Whisper rules hook (persistent rule injection)
|
|
355
|
+
- Reconstruct skill (retroactive session note creation)
|
|
356
|
+
- API key stripping for cost-safe headless Claude spawning
|
|
357
|
+
|
|
358
|
+
### Phase 3 (v0.9.0)
|
|
352
359
|
- `pai plugins list` — show installed modules and tiers
|
|
353
360
|
- `pai plugins enable/disable <module>` — selective module activation
|
|
354
|
-
-
|
|
361
|
+
- License validation system
|
|
362
|
+
- `pai license activate <key>` command
|
|
363
|
+
- Graceful tier gating with upgrade prompts
|
|
364
|
+
|
|
365
|
+
### Phase 4 (v1.0.0)
|
|
366
|
+
- Plugin marketplace integration
|
|
367
|
+
- Third-party plugin support
|
|
368
|
+
- Plugin dependency resolution
|
|
369
|
+
- Community plugin repository
|
|
355
370
|
|
|
356
371
|
### Phase 3 (v0.9.0)
|
|
357
372
|
- License validation system
|
package/README.md
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
|
-
# PAI Knowledge OS
|
|
1
|
+
# PAI Knowledge OS — v0.8.0
|
|
2
2
|
|
|
3
|
-
Claude Code has a memory problem. Every new session starts cold — no idea what you built yesterday, what decisions you made, or where you left off.
|
|
3
|
+
Claude Code has a memory problem. Every new session starts cold — no idea what you built yesterday, what decisions you made, or where you left off. PAI fixes this.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Automatic Session Notes — by Topic
|
|
6
|
+
|
|
7
|
+
PAI's headline feature: **every session is automatically documented.** No manual note-taking, no "pause session" commands, no forgetting to save what you did.
|
|
8
|
+
|
|
9
|
+
When you work, a background daemon watches your session **continuously**. Every time Claude's context compacts — which happens automatically as the conversation grows — the daemon reads the JSONL transcript, combines it with your git history, and spawns a headless Claude process to write a structured session note. Not just at session end. Midway through your work, while you're still coding. The notes build up in real time as you go — what was built, what decisions were made, what problems were hit, what's left to do.
|
|
10
|
+
|
|
11
|
+
**When you change topics mid-session, PAI creates a new note.** If you start the day debugging audio, then pivot to a Flutter rewrite, you get two notes — not one giant file mixing unrelated work:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
Notes/2026/03/
|
|
15
|
+
0001 - 2026-03-23 - Phase 1 Research and Architecture.md
|
|
16
|
+
0002 - 2026-03-24 - Background Audio and iOS Conflicts.md
|
|
17
|
+
0003 - 2026-03-24 - Flutter Rewrite with Whisper.md ← auto-split, same day
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Topic detection uses Jaccard word similarity between the new summary's topic and the existing note's title. Below 30% overlap = new note.
|
|
21
|
+
|
|
22
|
+
**Model tiering:** Opus for final session summaries (best quality, runs once). Sonnet for mid-session checkpoints (good quality, runs on compaction). All using your Max plan — no API charges.
|
|
23
|
+
|
|
24
|
+
This is not a template or a skeleton. These are real notes with build error chronologies, architectural decisions with rationale, code snippets, and "what was tried and failed" sections. The kind of notes you'd write yourself if you had time.
|
|
6
25
|
|
|
7
26
|
---
|
|
8
27
|
|
|
@@ -56,6 +75,7 @@ Install PAI and Claude remembers. Ask it what you were working on. Ask it to fin
|
|
|
56
75
|
- "Go" — reads your TODO.md continuation prompt and picks up exactly where the last session stopped
|
|
57
76
|
- "What was I working on?" — progressive context injection loads recent observations at session start
|
|
58
77
|
- "Continue the daemon refactor" — session summaries give Claude full context without re-explaining
|
|
78
|
+
- "/reconstruct" — retroactively creates session notes from JSONL transcripts and git history when automatic capture missed a session
|
|
59
79
|
|
|
60
80
|
### Keeping Things Safe
|
|
61
81
|
|
|
@@ -114,15 +134,59 @@ PAI runs hooks at every stage of a Claude Code session:
|
|
|
114
134
|
|
|
115
135
|
| Event | What PAI Does |
|
|
116
136
|
|-------|--------------|
|
|
117
|
-
| **Session Start** | Loads project context, detects which project you're in, creates a session note |
|
|
118
|
-
| **User Prompt** | Cleans up temp files, updates terminal tab titles |
|
|
119
|
-
| **Pre-Compact** | Saves session state checkpoint, sends notification |
|
|
137
|
+
| **Session Start** | Loads project context, detects which project you're in, auto-registers new projects, creates a session note |
|
|
138
|
+
| **User Prompt** | Cleans up temp files, updates terminal tab titles, injects whisper rules on every prompt |
|
|
139
|
+
| **Pre-Compact** | Saves session state checkpoint, pushes `session-summary` work item to daemon, sends notification |
|
|
120
140
|
| **Post-Compact** | Injects preserved state back into Claude's context |
|
|
121
141
|
| **Tool Use** | Classifies tool calls into structured observations (decision/bugfix/feature/refactor/discovery/change) |
|
|
122
|
-
| **Session End** |
|
|
123
|
-
| **Stop** |
|
|
142
|
+
| **Session End** | Pushes `session-summary` work item to daemon for AI-powered note generation |
|
|
143
|
+
| **Stop** | Pushes `session-summary` work item to daemon, sends notification |
|
|
144
|
+
|
|
145
|
+
All hooks are TypeScript compiled to `.mjs` modules. They run as separate processes and communicate via stdin (JSON input from Claude Code) and stdout (context injection back into the conversation). Hooks are thin relays — they capture minimal data and immediately push work items to the daemon queue, which handles all heavy processing asynchronously.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Automatic Session Notes
|
|
150
|
+
|
|
151
|
+
PAI automatically writes structured session notes after every session ends — no manual journaling required. The daemon spawns a headless Claude CLI process (using your Max plan, not the API) to summarize the JSONL conversation transcript combined with recent git history.
|
|
152
|
+
|
|
153
|
+
### What Gets Generated
|
|
154
|
+
|
|
155
|
+
Each session note contains:
|
|
156
|
+
|
|
157
|
+
- **Work Done** — concrete description of what was accomplished
|
|
158
|
+
- **Key Decisions** — choices made and their rationale
|
|
159
|
+
- **Known Issues** — bugs found, blockers, or open questions
|
|
160
|
+
- **Next Steps** — where to pick up in the next session
|
|
161
|
+
|
|
162
|
+
The summarizer uses tiered model selection based on the trigger:
|
|
163
|
+
|
|
164
|
+
| Trigger | Model | Timeout | JSONL Limit |
|
|
165
|
+
|---------|-------|---------|-------------|
|
|
166
|
+
| Session end (Stop hook) | Opus | 5 minutes | 500K bytes |
|
|
167
|
+
| Auto-compaction (PreCompact hook) | Sonnet | 2 minutes | 200K bytes |
|
|
168
|
+
|
|
169
|
+
### Topic-Based Note Splitting
|
|
124
170
|
|
|
125
|
-
|
|
171
|
+
When a session covers multiple distinct topics, PAI creates separate notes rather than one long note for the whole session. The summarizer outputs a `TOPIC:` line describing the subject of the current work. PAI compares this against the existing note title using Jaccard word similarity — when similarity falls below 30%, a new note is created automatically.
|
|
172
|
+
|
|
173
|
+
Notes within the same day are numbered sequentially: `0042 - 2026-03-24 - Session Name.md`, `0043 - 2026-03-24 - Different Topic.md`, and so on.
|
|
174
|
+
|
|
175
|
+
### One Note Per Session
|
|
176
|
+
|
|
177
|
+
Each compaction within a session updates the existing note rather than creating a new one. The 30-minute cooldown between summaries prevents redundant updates. Stop hook triggers bypass the cooldown with a force flag to ensure the final state is always captured.
|
|
178
|
+
|
|
179
|
+
### Garbage Title Filter
|
|
180
|
+
|
|
181
|
+
Session note titles are validated before creation. Over 20 patterns are rejected, including: task notification strings, `[object Object]`, hex hashes, bare numbers, and other non-descriptive artifacts that can appear in session transcripts. Titles must describe actual work done and are capped at 60 characters.
|
|
182
|
+
|
|
183
|
+
### Finding the Claude Binary
|
|
184
|
+
|
|
185
|
+
The daemon runs under launchd with a minimal PATH that does not include `~/.local/bin/`. PAI resolves the Claude CLI binary by checking `~/.local/bin/claude` first, then falling back to PATH lookup, before spawning headless summarization processes.
|
|
186
|
+
|
|
187
|
+
### Stripping the API Key
|
|
188
|
+
|
|
189
|
+
When spawning headless Claude CLI processes for summarization, the daemon strips `ANTHROPIC_API_KEY` from the subprocess environment. This forces the spawned process to authenticate via your Max plan (free) rather than using the API key (billable). Without this, every automatic session note would incur API charges.
|
|
126
190
|
|
|
127
191
|
---
|
|
128
192
|
|
|
@@ -187,6 +251,27 @@ When a session ends, PAI generates a structured summary capturing what was reque
|
|
|
187
251
|
|
|
188
252
|
---
|
|
189
253
|
|
|
254
|
+
## Whisper Rules
|
|
255
|
+
|
|
256
|
+
PAI provides a hook that injects user-defined rules into every prompt via `UserPromptSubmit`. Rules survive compaction, `/clear`, and session restarts — they fire on every single turn, making them the most reliable way to enforce behavioral constraints.
|
|
257
|
+
|
|
258
|
+
**PAI ships the mechanism. You provide the rules.** The file `~/.claude/whisper-rules.md` does not exist by default. Use the `/whisper` skill to manage your rules:
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
/whisper — show current rules
|
|
262
|
+
/whisper add "NEVER send emails" — add a rule
|
|
263
|
+
/whisper remove 3 — remove rule #3
|
|
264
|
+
/whisper list — list with line numbers
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Or edit `~/.claude/whisper-rules.md` directly — one rule per line, plain text.
|
|
268
|
+
|
|
269
|
+
**Keep rules focused.** Every rule is injected on every prompt. Too many rules dilute effectiveness and waste tokens. Reserve whisper rules for truly critical constraints that keep getting violated despite being in CLAUDE.md.
|
|
270
|
+
|
|
271
|
+
The pattern is inspired by [Letta's claude-subconscious](https://github.com/letta-ai/claude-subconscious) approach to persistent context injection.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
190
275
|
## Auto-Compact Context Window
|
|
191
276
|
|
|
192
277
|
Claude Code can automatically compact your context window when it fills up, preventing session interruptions mid-task. PAI's statusline shows you at a glance whether auto-compact is active.
|
package/dist/cli/index.mjs
CHANGED
|
@@ -3793,7 +3793,7 @@ function cmdLogs(opts) {
|
|
|
3793
3793
|
}
|
|
3794
3794
|
function registerDaemonCommands(daemonCmd) {
|
|
3795
3795
|
daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
|
|
3796
|
-
const { serve } = await import("../daemon-
|
|
3796
|
+
const { serve } = await import("../daemon-Ds9dTptY.mjs").then((n) => n.t);
|
|
3797
3797
|
const { loadConfig: lc, ensureConfigDir } = await import("../config-BuhHWyOK.mjs").then((n) => n.r);
|
|
3798
3798
|
ensureConfigDir();
|
|
3799
3799
|
await serve(lc());
|
package/dist/daemon/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import "../indexer-D53l5d1U.mjs";
|
|
|
8
8
|
import { t as PaiClient } from "../ipc-client-CoyUHPod.mjs";
|
|
9
9
|
import { i as ensureConfigDir, o as loadConfig } from "../config-BuhHWyOK.mjs";
|
|
10
10
|
import "../factory-Ygqe_bVZ.mjs";
|
|
11
|
-
import { n as serve } from "../daemon-
|
|
11
|
+
import { n as serve } from "../daemon-Ds9dTptY.mjs";
|
|
12
12
|
import "../state-C6_vqz7w.mjs";
|
|
13
13
|
import "../tools-DcaJlYDN.mjs";
|
|
14
14
|
import "../detector-jGBuYQJM.mjs";
|
|
@@ -1899,7 +1899,7 @@ function computeTopicOverlap(topicA, topicB) {
|
|
|
1899
1899
|
return union > 0 ? intersection / union : 0;
|
|
1900
1900
|
}
|
|
1901
1901
|
/** Threshold: below this overlap ratio, we consider topics different. */
|
|
1902
|
-
const TOPIC_OVERLAP_THRESHOLD = .
|
|
1902
|
+
const TOPIC_OVERLAP_THRESHOLD = .15;
|
|
1903
1903
|
/**
|
|
1904
1904
|
* Write (or update) the session note with the AI-generated summary.
|
|
1905
1905
|
*
|
|
@@ -3043,4 +3043,4 @@ var daemon_exports = /* @__PURE__ */ __exportAll({ serve: () => serve });
|
|
|
3043
3043
|
|
|
3044
3044
|
//#endregion
|
|
3045
3045
|
export { serve as n, daemon_exports as t };
|
|
3046
|
-
//# sourceMappingURL=daemon-
|
|
3046
|
+
//# sourceMappingURL=daemon-Ds9dTptY.mjs.map
|