@gi4nks/ph 1.4.0 → 1.6.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/CHANGELOG.md +7 -0
- package/README.md +147 -58
- package/dist/cli.js +2292 -1021
- package/dist/cli.js.map +1 -1
- package/docs/evals/context-retrieval-golden.json +26 -0
- package/docs/evals/context-retrieval.md +27 -0
- package/docs/hooks.md +13 -7
- package/docs/ph-analysis.html +145 -0
- package/docs/ph-manual.md +352 -231
- package/docs/specs/SPEC-001-architecture-cli.md +82 -0
- package/docs/specs/SPEC-002-database-layer.md +105 -0
- package/docs/specs/SPEC-003-capture-modes.md +110 -0
- package/docs/specs/SPEC-004-filter-metadata.md +82 -0
- package/docs/specs/SPEC-005-search.md +102 -0
- package/docs/specs/SPEC-006-analysis-pipeline.md +98 -0
- package/docs/specs/SPEC-007-memory-summaries.md +96 -0
- package/docs/specs/SPEC-008-embeddings.md +90 -0
- package/docs/specs/SPEC-009-retention-archive.md +91 -0
- package/docs/specs/SPEC-010-remote-sync.md +106 -0
- package/docs/specs/SPEC-011-mcp-server.md +94 -0
- package/docs/specs/SPEC-012-tui-browser.md +98 -0
- package/docs/specs/SPEC-013-importers.md +109 -0
- package/docs/specs/SPEC-014-analytics-commands.md +109 -0
- package/docs/specs/SPEC-015-config-env.md +85 -0
- package/docs/specs/SPEC-INDEX.md +35 -0
- package/docs/specs/SPEC-ISSUES.md +122 -0
- package/docs/specs/_TEMPLATE.md +65 -0
- package/docs/superpowers/plans/2026-06-12-ph-evolution-phase1.md +466 -0
- package/docs/superpowers/plans/2026-06-12-ph-evolution-phase2.md +351 -0
- package/docs/superpowers/specs/2026-06-12-ph-evolution-design.md +173 -0
- package/hooks/codex/README.md +54 -0
- package/hooks/codex/ph-hook.sh +14 -0
- package/hooks/opencode/ph-plugin.ts +60 -57
- package/package.json +13 -12
package/docs/ph-manual.md
CHANGED
|
@@ -1,358 +1,479 @@
|
|
|
1
|
-
# ph — Prompt History
|
|
1
|
+
# ph — Prompt History and Project Memory
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Zero-friction capture, semantic search, project memory, and MCP-based knowledge retrieval for AI CLI tools.**
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## 1. Overview
|
|
8
8
|
|
|
9
|
-
ph is a transparent
|
|
9
|
+
ph is a transparent observability and knowledge layer for AI CLI tools (Claude Code, Codex CLI, Gemini CLI, OpenCode, etc.). It automatically records every prompt+response into a local SQLite database with full-text search, semantic vector search, LLM-based analysis, Git context snapshots, session grouping, and an interactive TUI browser.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Core principle:** ph captures conversations without changing the normal tool workflow. Optional analysis turns captured history into project summaries and memories that can be searched locally or requested by an MCP client. Capture and full-text search work without an LLM provider; analysis, embeddings, and semantic search require the configured provider.
|
|
12
12
|
|
|
13
13
|
### Key Features
|
|
14
14
|
|
|
15
|
-
- **Automatic
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
15
|
+
- **Automatic capture** via hooks (Claude Code, Codex CLI, Gemini CLI, OpenCode plugin) or wrapper mode
|
|
16
|
+
- **Full-text search** (FTS5) and **semantic vector search** (Ollama embeddings, 768-dim via sqlite-vec)
|
|
17
|
+
- **LLM analysis** — role/tag/relevance classification, summary extraction, key insights, technical decisions
|
|
18
|
+
- **Project memory** — per-project accumulated knowledge with deduped insights and decisions
|
|
19
|
+
- **MCP server** — tools for agents to search memories, check project knowledge, get context
|
|
20
|
+
- **Interactive TUI** — browse, filter, edit, star, re-run, export prompts
|
|
21
|
+
- **Session grouping** — automatic conversation grouping with cohesion scoring
|
|
22
|
+
- **Git context** — records branch, modified files, and diff at capture time
|
|
23
|
+
- **Background analysis** — async LLM processing after each capture (optional)
|
|
24
|
+
- **Retention & archiving** — configurable auto-archive of old/low-relevance prompts
|
|
25
|
+
- **Remote sync** — push/pull prompt history across machines via HTTP server
|
|
26
|
+
- **Local-first storage** — the database stays on the configured machine unless optional remote sync is enabled; no telemetry is sent
|
|
21
27
|
|
|
22
28
|
---
|
|
23
29
|
|
|
24
|
-
## 2.
|
|
30
|
+
## 2. Installation
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
```bash
|
|
33
|
+
# Via npm
|
|
34
|
+
npm install -g @gi4nks/ph
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
# From source
|
|
37
|
+
git clone git@github.com:gi4nks/ph.git
|
|
38
|
+
cd ph
|
|
39
|
+
npm install
|
|
40
|
+
npm run build
|
|
41
|
+
npm link
|
|
42
|
+
```
|
|
29
43
|
|
|
30
|
-
|
|
31
|
-
|------|-------------|-------------|
|
|
32
|
-
| Database | `~/.prompt_history.db` | SQLite with FTS5 + vector embeddings |
|
|
33
|
-
| Config | `~/.ph_config.json` | JSON config file (0o600 permissions) |
|
|
44
|
+
### Quick config
|
|
34
45
|
|
|
35
|
-
|
|
46
|
+
```bash
|
|
47
|
+
ph config set background-analysis true # auto-analyze after each capture
|
|
48
|
+
ph config set analyze-provider ollama # ollama (default) or gemini
|
|
49
|
+
ph config set ollama-model llama3.1:latest
|
|
50
|
+
```
|
|
36
51
|
|
|
37
52
|
---
|
|
38
53
|
|
|
39
|
-
## 3.
|
|
54
|
+
## 3. Capture Modes
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
### 3a. Hook mode (recommended)
|
|
42
57
|
|
|
43
|
-
|
|
58
|
+
AI CLI tools invoke `ph log` automatically after each interaction.
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
**Claude Code** — `hooks/claude/ph-hook.sh`:
|
|
61
|
+
```bash
|
|
62
|
+
ln -sf $(pwd)/hooks/claude/ph-hook.sh ~/.claude/ph-hook.sh
|
|
63
|
+
# Add to ~/.claude/settings.json:
|
|
64
|
+
# "hooks": { "Stop": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "~/.claude/ph-hook.sh", "async": true }] }] }
|
|
65
|
+
```
|
|
46
66
|
|
|
47
|
-
|
|
67
|
+
**Gemini CLI** — `hooks/gemini/ph-hook.sh`:
|
|
68
|
+
```bash
|
|
69
|
+
ln -sf $(pwd)/hooks/gemini/ph-hook.sh ~/.gemini/ph-hook.sh
|
|
70
|
+
# Add to ~/.gemini/settings.json:
|
|
71
|
+
# "hooks": { "AfterAgent": [{ "hooks": [{ "type": "command", "command": "~/.gemini/ph-hook.sh" }] }] }
|
|
72
|
+
```
|
|
48
73
|
|
|
49
|
-
|
|
50
|
-
|
|
74
|
+
**OpenCode** — plugin at `hooks/opencode/ph-plugin.ts`:
|
|
75
|
+
```bash
|
|
76
|
+
./hooks/opencode/install.sh # global install
|
|
77
|
+
```
|
|
51
78
|
|
|
52
|
-
|
|
79
|
+
**Codex CLI** — see [the Codex hook setup](../hooks/codex/README.md). The Stop
|
|
80
|
+
hook imports the active rollout transcript. To import existing sessions, run
|
|
81
|
+
`ph import codex --dry-run` and then `ph import codex`.
|
|
53
82
|
|
|
54
|
-
|
|
83
|
+
### 3b. Wrapper mode
|
|
55
84
|
|
|
56
|
-
|
|
85
|
+
```bash
|
|
86
|
+
ph claude "explain goroutines"
|
|
87
|
+
ph codex exec "explain goroutines"
|
|
88
|
+
ph gemini "refactor this code"
|
|
89
|
+
ph --ph-role debug --ph-tag auth claude "fix JWT expiration"
|
|
90
|
+
```
|
|
57
91
|
|
|
58
|
-
###
|
|
92
|
+
### 3c. Direct log
|
|
59
93
|
|
|
60
|
-
|
|
94
|
+
```bash
|
|
95
|
+
ph log --tool claude --prompt "your prompt" --response "response text"
|
|
96
|
+
echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
97
|
+
```
|
|
61
98
|
|
|
62
|
-
|
|
99
|
+
---
|
|
63
100
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
101
|
+
## 4. CLI Commands
|
|
102
|
+
|
|
103
|
+
| Command | Description |
|
|
104
|
+
|---------|-------------|
|
|
105
|
+
| `ph` (no args) | Open interactive TUI browser |
|
|
106
|
+
| `ph <tool> [args...]` | Wrapper mode — run tool + capture |
|
|
107
|
+
| `ph search [query]` | Full-text search prompts |
|
|
108
|
+
| `ph search --semantic <query>` | Semantic (vector) search |
|
|
109
|
+
| `ph search --archive` | Search archived prompts |
|
|
110
|
+
| `ph search -i <query>` | Open results in interactive TUI |
|
|
111
|
+
| `ph last [n]` | Show last N prompts |
|
|
112
|
+
| `ph context [query]` | Get RAG context for current project |
|
|
113
|
+
| `ph sessions` | Group prompts into work sessions |
|
|
114
|
+
| `ph timeline <project>` | Full chronological project history |
|
|
115
|
+
| `ph stats` | History statistics |
|
|
116
|
+
| `ph cluster -k 5` | K-means clustering on embeddings |
|
|
117
|
+
| `ph analyze` | LLM analysis of untagged prompts |
|
|
118
|
+
| `ph analyze-reusability` | Reusability scoring |
|
|
119
|
+
| `ph cleanup` | Remove useless prompts (length/duplicates) |
|
|
120
|
+
| `ph cleanup --retention` | Archive old/unqualified prompts per retention policy |
|
|
121
|
+
| `ph cleanup-reusability` | Cleanup by reusability score |
|
|
122
|
+
| `ph star <id>` | Toggle bookmark |
|
|
123
|
+
| `ph export <id>` | Export prompt (txt/json/md) |
|
|
124
|
+
| `ph import gemini|claude|opencode|codex` | Import from AI CLI history |
|
|
125
|
+
| `ph log --tool <name> ...` | Direct log (hook target) |
|
|
126
|
+
| `ph embed-all` | Generate embeddings for all prompts |
|
|
127
|
+
| `ph config get|set <key> <value>` | View/edit config |
|
|
128
|
+
| `ph vacuum` | Compact SQLite database |
|
|
129
|
+
| `ph memory-migrate` | Merge existing memories into project_summaries |
|
|
130
|
+
| `ph mcp` | Start MCP stdio server |
|
|
131
|
+
| `ph server --port 3001` | Start HTTP REST server |
|
|
132
|
+
| `ph remote push|pull|status` | Sync with remote ph server |
|
|
133
|
+
| `ph chat <tool> <prompt>` | Run tool with project context injected |
|
|
134
|
+
| `ph ollama-models` | List available Ollama models |
|
|
135
|
+
|
|
136
|
+
### Search options
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
-i / --interactive Open in TUI browser
|
|
140
|
+
--tool <name> Filter by tool
|
|
141
|
+
--project <name> Filter by project
|
|
142
|
+
--language <lang> Filter by language
|
|
143
|
+
--role <role> Filter by role
|
|
144
|
+
--tag <tag> Filter by tag
|
|
145
|
+
--starred Show only starred
|
|
146
|
+
--semantic Use semantic (vector) search
|
|
147
|
+
--archive Search archived prompts
|
|
148
|
+
--since YYYY-MM-DD Start date
|
|
149
|
+
--until YYYY-MM-DD End date
|
|
150
|
+
--limit <n> Max results (default 50)
|
|
151
|
+
--top Quality >= 8
|
|
152
|
+
--min-quality <n> Min quality (0-10)
|
|
153
|
+
--min-relevance <n> Min relevance (0-10)
|
|
154
|
+
--full Show full prompt text
|
|
69
155
|
```
|
|
70
156
|
|
|
71
|
-
|
|
157
|
+
### Context options
|
|
72
158
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
159
|
+
```
|
|
160
|
+
--project <name> Project name (default: auto-detect)
|
|
161
|
+
--limit <n> Max results (default 5)
|
|
162
|
+
--prompts-only Skip project knowledge, show only prompts
|
|
163
|
+
--memories-only Skip prompts, show only project knowledge
|
|
164
|
+
--verbose Include full prompt text
|
|
165
|
+
```
|
|
78
166
|
|
|
79
|
-
|
|
167
|
+
### Sessions options
|
|
80
168
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
8. Exits `0` unconditionally — Claude Code is never blocked
|
|
169
|
+
```
|
|
170
|
+
--gap-hours <n> Hours gap to split sessions (default 2)
|
|
171
|
+
--limit <n> Max sessions (default 20)
|
|
172
|
+
--min-size <n> Min prompts per session (default 1)
|
|
173
|
+
--no-cohesion Skip semantic cohesion computation
|
|
174
|
+
--export <n> Export session N as markdown
|
|
175
|
+
```
|
|
89
176
|
|
|
90
|
-
|
|
177
|
+
### Cluster options
|
|
91
178
|
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# Step 2: register in ~/.claude/settings.json
|
|
97
|
-
{
|
|
98
|
-
"hooks": {
|
|
99
|
-
"Stop": [
|
|
100
|
-
{
|
|
101
|
-
"matcher": ".*",
|
|
102
|
-
"hooks": [
|
|
103
|
-
{
|
|
104
|
-
"type": "command",
|
|
105
|
-
"command": "~/.claude/ph-hook.sh",
|
|
106
|
-
"async": true
|
|
107
|
-
}
|
|
108
|
-
]
|
|
109
|
-
}
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
}
|
|
179
|
+
```
|
|
180
|
+
-k <number> Number of clusters (default 5)
|
|
181
|
+
--limit <n> Max prompts per cluster to show (default 3)
|
|
113
182
|
```
|
|
114
183
|
|
|
115
184
|
---
|
|
116
185
|
|
|
117
|
-
|
|
186
|
+
## 5. TUI Keybindings
|
|
118
187
|
|
|
119
|
-
|
|
188
|
+
| Key | Action |
|
|
189
|
+
|-----|--------|
|
|
190
|
+
| `Up` / `Down`, `Page Up` / `Page Down` | Navigate list |
|
|
191
|
+
| `Tab` | Switch pane (wide mode) |
|
|
192
|
+
| `1`, `2`, `3` | Switch prompt/response/memory tab |
|
|
193
|
+
| `y` | Copy to clipboard |
|
|
194
|
+
| `s` | Toggle star |
|
|
195
|
+
| `e` | Edit metadata |
|
|
196
|
+
| `r` | Rerun prompt (edit before launch) |
|
|
197
|
+
| `Shift+C` | Chat mode: launch tool with project context |
|
|
198
|
+
| `x` | Delete entry |
|
|
199
|
+
| `/` | Search |
|
|
200
|
+
| `o` | Settings panel (toggle auto-analysis, view config) |
|
|
201
|
+
| `f` | Filter panel (flat list, Enter toggle, letter jump) |
|
|
202
|
+
| `c` | Clear all filters |
|
|
203
|
+
| `q` / `Escape` | Quit / back |
|
|
204
|
+
|
|
205
|
+
### TUI components
|
|
206
|
+
|
|
207
|
+
- **SearchBar** — always visible spotlight bar at top
|
|
208
|
+
- **FilterPanel** — flat scrollable list of filter options with counts `[N]`, toggle with Enter, jump by letter
|
|
209
|
+
- **SettingsView** — config viewer/editor (auto-analysis toggle, ollama URL/model, filters)
|
|
210
|
+
- **PreviewPane** — three tabs (prompt/response/memory). Memory tab shows project-level knowledge
|
|
211
|
+
- **ListEntry** — role marker, analysis status, star, Q/R badges, optional summary line
|
|
212
|
+
- **Footer** — context-sensitive hints (shows `C:chat` only when entry has project)
|
|
120
213
|
|
|
121
|
-
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 6. Project Memory System
|
|
217
|
+
|
|
218
|
+
ph maintains two levels of per-project knowledge:
|
|
219
|
+
|
|
220
|
+
### 6a. `project_summaries` (curated, 1 row per project)
|
|
221
|
+
|
|
222
|
+
Accumulated knowledge with deduped insights and decisions. Updated on every analysis. Primary source for MCP tools.
|
|
122
223
|
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"timestamp": "...",
|
|
130
|
-
"prompt": "the user's prompt text",
|
|
131
|
-
"prompt_response": "the assistant's full response text"
|
|
132
|
-
}
|
|
224
|
+
```bash
|
|
225
|
+
# View accumulated project knowledge
|
|
226
|
+
ph context --project myproject
|
|
227
|
+
|
|
228
|
+
# Via MCP (for AI agents)
|
|
229
|
+
# get_project_summary(project: "myproject")
|
|
133
230
|
```
|
|
134
231
|
|
|
135
|
-
|
|
232
|
+
### 6b. `memories` (append-only timeline)
|
|
136
233
|
|
|
137
|
-
|
|
138
|
-
2. Extracts `prompt`, `prompt_response`, and `cwd` directly via `jq`
|
|
139
|
-
3. Builds a JSON payload with `tool`, `prompt`, `response`, and `workdir` fields
|
|
140
|
-
4. Pipes to `ph log` in the background
|
|
141
|
-
5. Exits `0` unconditionally
|
|
234
|
+
Full chronological history of every analysis run. Preserved for detailed audit.
|
|
142
235
|
|
|
143
|
-
|
|
236
|
+
### Memory migration
|
|
237
|
+
|
|
238
|
+
If you have existing data from before the evolution phases:
|
|
144
239
|
|
|
145
240
|
```bash
|
|
146
|
-
#
|
|
147
|
-
ln -sf /path/to/ph/hooks/gemini/ph-hook.sh ~/.gemini/ph-hook.sh
|
|
148
|
-
|
|
149
|
-
# Step 2: register in ~/.gemini/settings.json
|
|
150
|
-
{
|
|
151
|
-
"hooks": {
|
|
152
|
-
"AfterAgent": [
|
|
153
|
-
{
|
|
154
|
-
"hooks": [
|
|
155
|
-
{
|
|
156
|
-
"type": "command",
|
|
157
|
-
"command": "~/.gemini/ph-hook.sh"
|
|
158
|
-
}
|
|
159
|
-
]
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
|
-
}
|
|
163
|
-
}
|
|
241
|
+
ph memory-migrate # one-time: merge all memories into project_summaries
|
|
164
242
|
```
|
|
165
243
|
|
|
166
244
|
---
|
|
167
245
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
OpenCode uses a JavaScript/TypeScript **plugin** system (rather than shell scripts). The `ph` integration is a plugin that hooks into OpenCode's message lifecycle to capture prompts and responses.
|
|
246
|
+
## 7. Retention & Archiving
|
|
171
247
|
|
|
172
|
-
|
|
248
|
+
Configurable auto-archiving to keep the database lean:
|
|
173
249
|
|
|
174
|
-
|
|
250
|
+
```bash
|
|
251
|
+
# Configure
|
|
252
|
+
ph config set retentionDays 90 # archive prompts older than 90 days
|
|
253
|
+
ph config set retentionMinRelevance 3 # prompts below this relevance archived first
|
|
254
|
+
ph config set retentionMinStarred true # starred prompts never archived
|
|
255
|
+
ph config set retentionMinAnalyzed true # analyzed prompts never archived
|
|
175
256
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
| `experimental.text.complete` | Fires after streaming completes. Replaces the snapshot with the full, final response text. |
|
|
257
|
+
# Run retention cleanup
|
|
258
|
+
ph cleanup --retention # archive matching prompts
|
|
259
|
+
ph cleanup --retention --dry-run # preview only
|
|
180
260
|
|
|
181
|
-
|
|
261
|
+
# Search archived prompts
|
|
262
|
+
ph search --archive
|
|
182
263
|
|
|
183
|
-
|
|
184
|
-
User types prompt
|
|
185
|
-
→ chat.message fires (role: user)
|
|
186
|
-
→ plugin stores the prompt text + metadata (agent, model, workdir)
|
|
187
|
-
|
|
188
|
-
Assistant streams response
|
|
189
|
-
→ experimental.text.complete fires for each text part
|
|
190
|
-
→ plugin accumulates the complete response text
|
|
191
|
-
|
|
192
|
-
Next user message or session end
|
|
193
|
-
→ plugin pairs prompt + accumulated response
|
|
194
|
-
→ pipes {"tool":"opencode","prompt":"...","response":"..."} to ph log
|
|
195
|
-
→ runs in background — never blocks OpenCode
|
|
264
|
+
# Auto-purge: entries older than 2x retentionDays are deleted during cleanup
|
|
196
265
|
```
|
|
197
266
|
|
|
198
|
-
|
|
267
|
+
---
|
|
199
268
|
|
|
200
|
-
|
|
201
|
-
- `~/.config/opencode/plugins/` — global (all projects)
|
|
202
|
-
- `.opencode/plugins/` — per-project
|
|
269
|
+
## 8. Background Analysis
|
|
203
270
|
|
|
204
|
-
|
|
271
|
+
When enabled, every `ph log` automatically spawns a detached child process that analyzes the new entry (role, tags, relevance, summary, key insights, technical decisions).
|
|
205
272
|
|
|
206
273
|
```bash
|
|
207
|
-
|
|
208
|
-
mkdir -p ~/.config/opencode/plugins
|
|
209
|
-
ln -sf /path/to/ph/hooks/opencode/ph-plugin.ts ~/.config/opencode/plugins/ph-plugin.ts
|
|
274
|
+
ph config set background-analysis true
|
|
210
275
|
```
|
|
211
276
|
|
|
212
|
-
|
|
277
|
+
Analysis uses Ollama by default (requires `ollama serve` running). Configure:
|
|
213
278
|
|
|
214
279
|
```bash
|
|
215
|
-
|
|
216
|
-
|
|
280
|
+
ph config set analyze-provider gemini # use Gemini instead
|
|
281
|
+
ph config set gemini-api-key "YOUR_KEY"
|
|
282
|
+
ph config set ollama-model llama3.1:latest
|
|
283
|
+
ph config set ollama-embed-model nomic-embed-text-v2-moe
|
|
217
284
|
```
|
|
218
285
|
|
|
219
|
-
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## 9. MCP Server
|
|
289
|
+
|
|
290
|
+
ph exposes an MCP (Model Context Protocol) server over stdio for AI agents:
|
|
220
291
|
|
|
221
292
|
```bash
|
|
222
|
-
|
|
293
|
+
ph mcp
|
|
223
294
|
```
|
|
224
295
|
|
|
225
|
-
|
|
296
|
+
### Available tools
|
|
297
|
+
|
|
298
|
+
| Tool | Description |
|
|
299
|
+
|------|-------------|
|
|
300
|
+
| `search_project_memory` | Semantic search + fallback to project_summaries |
|
|
301
|
+
| `get_project_context` | Merged summary + recent memories + recent prompts |
|
|
302
|
+
| `get_project_summary` | Accumulated key insights and technical decisions |
|
|
303
|
+
| `check_project_knowledge` | Before implementing: checks memories + prompts for existing work |
|
|
304
|
+
| `save_decision` | Persist an architectural decision to memory + summaries |
|
|
305
|
+
| `search_prompts` | Full-text search over prompt history |
|
|
306
|
+
| `get_prompt` | Full details by ID |
|
|
307
|
+
| `search_prompts_semantic` | Vector search over prompts |
|
|
308
|
+
| `get_project_timeline` | Full chronological project history |
|
|
309
|
+
| `get_project_diff` | Compare project state between dates |
|
|
310
|
+
| `list_prompts` | Paginated prompt listing |
|
|
226
311
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
```bash
|
|
230
|
-
# Start OpenCode — the plugin loads silently
|
|
231
|
-
opencode
|
|
312
|
+
---
|
|
232
313
|
|
|
233
|
-
|
|
234
|
-
ph search --tool opencode --limit 3
|
|
235
|
-
```
|
|
314
|
+
## 10. HTTP Server & Remote Sync
|
|
236
315
|
|
|
237
|
-
|
|
316
|
+
Share prompt history across machines:
|
|
238
317
|
|
|
239
318
|
```bash
|
|
240
|
-
|
|
319
|
+
# Start server
|
|
320
|
+
ph server --port 3001 --host 0.0.0.0
|
|
321
|
+
|
|
322
|
+
# From another machine
|
|
323
|
+
ph config set remote-url http://server-ip:3001
|
|
324
|
+
ph remote push # send local unsynced prompts
|
|
325
|
+
ph remote pull # fetch remote prompts
|
|
326
|
+
ph remote status # show sync state
|
|
241
327
|
```
|
|
242
328
|
|
|
329
|
+
Every `ph log` auto-pushes to remote if configured (fire-and-forget, never blocks).
|
|
330
|
+
|
|
243
331
|
---
|
|
244
332
|
|
|
245
|
-
|
|
333
|
+
## 11. Database
|
|
246
334
|
|
|
247
|
-
|
|
248
|
-
|--------|------------|------------|----------|
|
|
249
|
-
| Hook mechanism | `Stop` shell script | `AfterAgent` shell script | JS/TS plugin |
|
|
250
|
-
| Data delivery | `transcript_path` (JSONL) | Direct JSON on stdin | Event hooks (`chat.message`, `experimental.text.complete`) |
|
|
251
|
-
| Prompt extraction | Parse JSONL with `jq` slurp | `jq .prompt` | `message.role === 'user'` parts |
|
|
252
|
-
| Response extraction | Last assistant text block | `jq .prompt_response` | `experimental.text.complete` accumulation |
|
|
253
|
-
| Async support | Yes (`async: true`) | Yes (`& + disown`) | Yes (Promise fire-and-forget) |
|
|
254
|
-
| Blocks AI exit? | Never | Never | Never |
|
|
255
|
-
| Install method | Symlink + settings.json | Symlink + settings.json | Copy plugin file to `plugins/` dir |
|
|
335
|
+
**Location:** `~/.prompt_history.db` (configurable via `ph config set db-path`)
|
|
256
336
|
|
|
257
|
-
|
|
337
|
+
**Tables:**
|
|
258
338
|
|
|
259
|
-
|
|
339
|
+
| Table | Purpose |
|
|
340
|
+
|-------|---------|
|
|
341
|
+
| `prompts` | Main prompt+response storage with FTS5 index |
|
|
342
|
+
| `prompts_archive` | Archived (retention-aged) prompts |
|
|
343
|
+
| `memories` | Append-only per-project analysis timeline |
|
|
344
|
+
| `project_summaries` | Single curated row per project with merged knowledge |
|
|
345
|
+
| `vec_embeddings` | Vector embeddings (768-dim float, sqlite-vec) |
|
|
346
|
+
| `embeddings` | Legacy BLOB embeddings (migrated on connect) |
|
|
260
347
|
|
|
261
|
-
|
|
348
|
+
**Maintenance:**
|
|
262
349
|
|
|
263
350
|
```bash
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
make install # installs the global 'ph' symlink
|
|
351
|
+
ph vacuum # compact DB
|
|
352
|
+
ph cleanup # remove short/trivial/duplicate prompts
|
|
353
|
+
ph cleanup --retention # archive per retention policy
|
|
354
|
+
ph embed-all # (re)generate all embeddings
|
|
269
355
|
```
|
|
270
356
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
# Install globally:
|
|
275
|
-
npm install -g @gi4nks/ph
|
|
276
|
-
```
|
|
357
|
+
---
|
|
277
358
|
|
|
278
|
-
|
|
359
|
+
## 12. Filter Pipeline
|
|
279
360
|
|
|
280
|
-
|
|
281
|
-
# Set your Gemini API key (optional — Ollama works without it)
|
|
282
|
-
ph config set gemini-api-key "YOUR_KEY"
|
|
361
|
+
Before saving, ph filters out:
|
|
283
362
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
363
|
+
- Prompts shorter than `filterMinLength` (default 15 chars)
|
|
364
|
+
- Non-printable content
|
|
365
|
+
- Trivial patterns (single chars, common noise)
|
|
366
|
+
- Exact duplicates (within last 7 days)
|
|
367
|
+
- Low-relevance prompts (when `--min-relevance` is set)
|
|
287
368
|
|
|
288
|
-
|
|
289
|
-
ph config set background-analysis true
|
|
369
|
+
Configure:
|
|
290
370
|
|
|
291
|
-
|
|
292
|
-
ph config set
|
|
371
|
+
```bash
|
|
372
|
+
ph config set filter-min-length 20
|
|
373
|
+
ph config set filter-min-relevance 3
|
|
293
374
|
```
|
|
294
375
|
|
|
295
376
|
---
|
|
296
377
|
|
|
297
|
-
##
|
|
378
|
+
## 13. Configuration (`~/.ph_config.json`)
|
|
379
|
+
|
|
380
|
+
| Key | Default | Description |
|
|
381
|
+
|-----|---------|-------------|
|
|
382
|
+
| `dbPath` | `~/.prompt_history.db` | SQLite database path |
|
|
383
|
+
| `analyzeProvider` | `ollama` | LLM provider: `ollama` or `gemini` |
|
|
384
|
+
| `ollamaUrl` | `http://localhost:11434` | Ollama server URL |
|
|
385
|
+
| `ollamaModel` | `llama3.1:latest` | Analysis model |
|
|
386
|
+
| `ollamaEmbedModel` | `nomic-embed-text-v2-moe` | Embedding model |
|
|
387
|
+
| `geminiApiKey` | — | Gemini API key |
|
|
388
|
+
| `backgroundAnalysis` | `false` | Auto-analyze after each capture |
|
|
389
|
+
| `filterMinLength` | `15` | Min prompt length to keep |
|
|
390
|
+
| `filterMinRelevance` | `3` | Min relevance to keep (0=disable) |
|
|
391
|
+
| `retentionDays` | `90` | Auto-archive after N days |
|
|
392
|
+
| `retentionMinStarred` | `true` | Keep starred prompts |
|
|
393
|
+
| `retentionMinAnalyzed` | `true` | Keep analyzed prompts |
|
|
394
|
+
| `retentionMinRelevance` | `3` | Archive prompts below this relevance |
|
|
395
|
+
| `remoteUrl` | — | Remote ph server URL (or `PH_REMOTE_URL` env) |
|
|
396
|
+
| `remoteApiKey` | — | Remote server API key |
|
|
397
|
+
| `remoteLastPush` | — | Timestamp of last successful push |
|
|
398
|
+
| `remoteLastPull` | — | Timestamp of last successful pull |
|
|
298
399
|
|
|
299
|
-
|
|
400
|
+
---
|
|
300
401
|
|
|
301
|
-
|
|
302
|
-
# Full-text search
|
|
303
|
-
ph search "how to refactor"
|
|
402
|
+
## 14. Architecture
|
|
304
403
|
|
|
305
|
-
|
|
306
|
-
ph
|
|
404
|
+
```
|
|
405
|
+
Hook/Import → ph log → prompts table (FTS5 indexed)
|
|
406
|
+
↓
|
|
407
|
+
Background analysis (optional)
|
|
408
|
+
↓
|
|
409
|
+
┌────────────────┴────────────────┐
|
|
410
|
+
↓ ↓
|
|
411
|
+
memories (append-only, project_summaries
|
|
412
|
+
with TTL) (1 row per project,
|
|
413
|
+
merged + deduped)
|
|
414
|
+
↓ ↓
|
|
415
|
+
ph cleanup --retention MCP tools read
|
|
416
|
+
→ prompts_archive from here
|
|
307
417
|
```
|
|
308
418
|
|
|
309
|
-
###
|
|
419
|
+
### File layout
|
|
310
420
|
|
|
311
|
-
```
|
|
312
|
-
|
|
421
|
+
```
|
|
422
|
+
src/
|
|
423
|
+
cli.ts # Entry point (~80 lines), switch dispatch
|
|
424
|
+
types.ts # Core types (PromptEntry, MemoryEntry, ProjectSummary, etc.)
|
|
425
|
+
db/index.ts # PhDB public SQLite adapter
|
|
426
|
+
db/semantic-index.ts # Vector encoding, storage, and nearest-neighbor search
|
|
427
|
+
context/index.ts # Shared project-context retrieval and rendering
|
|
428
|
+
capture/index.ts # Shared capture-record normalization
|
|
429
|
+
commands/ # One module per CLI command
|
|
430
|
+
analyzer/ # LLM analysis (role/tag/relevance/summary/insights)
|
|
431
|
+
embedding/ # Ollama embedding generation
|
|
432
|
+
filter/ # Capture-time filter pipeline
|
|
433
|
+
mcp/server.ts # MCP stdio server
|
|
434
|
+
server/index.ts # HTTP REST server (zero deps)
|
|
435
|
+
ui/ # React/Ink TUI, including extracted filter policy and panel
|
|
436
|
+
importer/ # Gemini/Claude/OpenCode/Codex history importers
|
|
437
|
+
hooks/ # Shell scripts and plugins for AI tools
|
|
313
438
|
```
|
|
314
439
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
| Key | Action |
|
|
318
|
-
|-----|--------|
|
|
319
|
-
| `f` | Open filters panel |
|
|
320
|
-
| `e` | Edit prompt metadata (tags, notes) |
|
|
321
|
-
| `r` | Re-run selected prompt in your AI tool |
|
|
322
|
-
| `y` | Copy prompt to clipboard |
|
|
323
|
-
| `x` | Delete prompt from history |
|
|
440
|
+
---
|
|
324
441
|
|
|
325
|
-
|
|
442
|
+
## 15. Importing Existing History
|
|
326
443
|
|
|
327
444
|
```bash
|
|
328
|
-
#
|
|
329
|
-
ph
|
|
330
|
-
```
|
|
445
|
+
# Import from Claude Code
|
|
446
|
+
ph import claude --analyze
|
|
331
447
|
|
|
332
|
-
|
|
448
|
+
# Import from Gemini CLI
|
|
449
|
+
ph import gemini --filter
|
|
333
450
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
ph cleanup --min-length 20 --days 30
|
|
451
|
+
# Import from OpenCode
|
|
452
|
+
ph import opencode
|
|
337
453
|
|
|
338
|
-
#
|
|
339
|
-
ph
|
|
454
|
+
# Import from Codex CLI
|
|
455
|
+
ph import codex --dry-run
|
|
456
|
+
ph import codex
|
|
340
457
|
|
|
341
|
-
#
|
|
342
|
-
|
|
458
|
+
# Options:
|
|
459
|
+
# --analyze run LLM analysis on imported prompts
|
|
460
|
+
# --filter apply capture-time filters
|
|
461
|
+
# --dry-run preview without importing
|
|
343
462
|
```
|
|
344
463
|
|
|
345
464
|
---
|
|
346
465
|
|
|
347
|
-
##
|
|
348
|
-
|
|
349
|
-
Every interaction with an AI tool is a unit of intellectual work. A well-crafted prompt encodes context, intent, and engineering decisions that took time to develop. Without capture, that work is lost the moment the session closes.
|
|
350
|
-
|
|
351
|
-
ph treats your prompt history as a first-class artifact: searchable, annotated, versioned with Git context, and available for re-use. Over time, your history becomes a personal knowledge base of how you think and work with AI tools.
|
|
466
|
+
## 16. Versioning and Releases
|
|
352
467
|
|
|
353
|
-
|
|
468
|
+
Use Conventional Commits to describe changes: `feat:` requests a minor release,
|
|
469
|
+
`fix:` requests a patch release, and `BREAKING CHANGE:` requests a major release.
|
|
470
|
+
The GitHub Actions workflow runs `semantic-release` on pushes to `main`, updates
|
|
471
|
+
release metadata, publishes to npm, and creates a GitHub release.
|
|
354
472
|
|
|
355
|
-
|
|
473
|
+
The Make targets `make release-patch`, `make release-minor`, and
|
|
474
|
+
`make release-major` increment `package.json` and `package-lock.json` locally.
|
|
475
|
+
They do not commit, tag, or publish. The automated release workflow determines
|
|
476
|
+
the actual published version from commits since its most recent release tag.
|
|
356
477
|
|
|
357
478
|
---
|
|
358
479
|
|