@gi4nks/ph 1.6.0 → 1.8.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 +22 -1
- package/LICENSE +1 -1
- package/README.md +79 -19
- package/dist/cli.js +3593 -3677
- package/dist/cli.js.map +1 -1
- package/docs/evals/context-retrieval-golden.json +17 -1
- package/docs/ph-architecture-review.html +179 -0
- package/docs/ph-manual.md +129 -73
- package/docs/ph-operational-memory-analysis.html +104 -0
- package/docs/plans/2026-10-10-operational-memory.md +192 -0
- package/docs/specs/SPEC-001-architecture-cli.md +100 -72
- package/docs/specs/SPEC-002-database-layer.md +22 -3
- package/docs/specs/SPEC-003-capture-modes.md +22 -9
- package/docs/specs/SPEC-005-search.md +46 -11
- package/docs/specs/SPEC-006-analysis-pipeline.md +8 -6
- package/docs/specs/SPEC-007-memory-summaries.md +19 -19
- package/docs/specs/SPEC-008-embeddings.md +8 -2
- package/docs/specs/SPEC-009-retention-archive.md +2 -2
- package/docs/specs/SPEC-010-remote-sync.md +77 -103
- package/docs/specs/SPEC-011-mcp-server.md +7 -4
- package/docs/specs/SPEC-012-tui-browser.md +30 -96
- package/docs/specs/SPEC-015-config-env.md +4 -0
- package/docs/specs/SPEC-016-operational-memory.md +48 -0
- package/docs/specs/SPEC-017-architecture-consolidation.md +63 -0
- package/docs/specs/SPEC-018-interaction-inspection-and-recall-integrity.md +164 -0
- package/docs/specs/SPEC-019-network-capture-and-ranking-integrity.md +36 -0
- package/docs/specs/SPEC-INDEX.md +12 -7
- package/docs/specs/SPEC-ISSUES.md +104 -18
- package/hooks/claude/README.md +1 -1
- package/hooks/codex/README.md +1 -1
- package/hooks/codex/ph-hook.sh +2 -1
- package/hooks/gemini/README.md +1 -1
- package/package.json +6 -7
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
{ "id": "gemini-import", "project": "ph", "text": "Gemini history import reads session JSON, pairs human messages with the following model response, and supports dry run and duplicate filtering." },
|
|
11
11
|
{ "id": "remote-sync", "project": "ph", "text": "Remote sync pushes unsynced prompts and pulls newer records; sync hashes deduplicate matching prompt, response, tool, and arguments." },
|
|
12
12
|
{ "id": "analysis-memory", "project": "ph", "text": "Background analysis appends project memories and merges key insights and technical decisions into a single project summary." },
|
|
13
|
+
{ "id": "shared-context", "project": "ph", "text": "getProjectContext and formatProjectContext are shared by ph context, chat, and MCP; semantic retrieval must stay project scoped." },
|
|
14
|
+
{ "id": "wise-provider", "project": "ph", "text": "Wise provides OpenRouter and MLX-Serve providers in ph; provider and model configuration is shared across CLI and TUI." },
|
|
15
|
+
{ "id": "homo-provider-boundary", "project": "homo", "text": "HOMO uses the shared Wise library to configure multiple AI providers behind the application's AI integration." },
|
|
16
|
+
{ "id": "homo-genesis-context", "project": "homo", "text": "Chapter Genesis carries previous content fragments and book-level lore constraints into generated scenes." },
|
|
17
|
+
{ "id": "picot-sqlite-build", "project": "picot", "text": "PicoT uses SQLite and Next.js; builds should use a SQLite timeout and isolated build data to avoid SQLITE_BUSY races." },
|
|
18
|
+
{ "id": "picot-breadcrumb-context", "project": "picot", "text": "PicoT document preview preserves the originating library listing, search, and filters through breadcrumb navigation." },
|
|
19
|
+
{ "id": "lens-harness-goal", "project": "lens", "text": "Lens integrates the harness goal loop with verified predicates, progress, recovery, and a run_command tool." },
|
|
20
|
+
{ "id": "lens-wise-provider", "project": "lens", "text": "Lens WiseProvider supports OpenRouter and MLX-Serve using configured provider model IDs." },
|
|
13
21
|
{ "id": "unrelated-react", "project": "lens", "text": "React rendering uses reconciliation to compare virtual trees and update the browser DOM." },
|
|
14
22
|
{ "id": "unrelated-go", "project": "sonic", "text": "Go goroutines communicate using channels and are scheduled by the Go runtime." }
|
|
15
23
|
],
|
|
@@ -21,6 +29,14 @@
|
|
|
21
29
|
{ "query": "How are assistant replies and hidden reasoning handled in Claude imports?", "relevant": ["claude-import"] },
|
|
22
30
|
{ "query": "How does Gemini history import pair prompt and model output?", "relevant": ["gemini-import"] },
|
|
23
31
|
{ "query": "How does ph avoid duplicate records when synchronizing laptops?", "relevant": ["remote-sync"] },
|
|
24
|
-
{ "query": "How do prompt analyses update the long term project knowledge?", "relevant": ["analysis-memory"] }
|
|
32
|
+
{ "query": "How do prompt analyses update the long term project knowledge?", "relevant": ["analysis-memory"] },
|
|
33
|
+
{ "query": "Which shared retrieval API do CLI, chat, and MCP use?", "relevant": ["shared-context"] },
|
|
34
|
+
{ "query": "How are Wise models and providers configured in ph?", "relevant": ["wise-provider"] },
|
|
35
|
+
{ "query": "How does HOMO pass earlier chapter context and lore into generation?", "relevant": ["homo-genesis-context"] },
|
|
36
|
+
{ "query": "Which provider abstraction does HOMO use for AI backends?", "relevant": ["homo-provider-boundary"] },
|
|
37
|
+
{ "query": "How should PicoT builds avoid SQLite locking conflicts?", "relevant": ["picot-sqlite-build"] },
|
|
38
|
+
{ "query": "What state does PicoT preserve when navigating back from a document?", "relevant": ["picot-breadcrumb-context"] },
|
|
39
|
+
{ "query": "How does Lens verify and recover an agent goal?", "relevant": ["lens-harness-goal"] },
|
|
40
|
+
{ "query": "Which local and hosted AI providers are available to Lens?", "relevant": ["lens-wise-provider"] }
|
|
25
41
|
]
|
|
26
42
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>PH Architecture Review</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
|
|
9
|
+
<style>
|
|
10
|
+
:root { color-scheme: light; --ink:#17212b; --muted:#52616d; --line:#d9e1e5; --paper:#f5f7f6; --teal:#087f74; --amber:#a85c05; --rose:#bd3e4b; }
|
|
11
|
+
body { background:var(--paper); color:var(--ink); font-family:Inter,ui-sans-serif,system-ui,-apple-system,sans-serif; }
|
|
12
|
+
h1,h2,h3,h4,.serif { font-family:Georgia,Cambria,"Times New Roman",serif; }
|
|
13
|
+
.module-box { border:1px solid #a8b8bf; border-radius:1rem; padding:1rem; background:#fff; box-shadow:0 10px 30px #162a3010; }
|
|
14
|
+
.diagram-arrow { color:#73848c; font-size:1.35rem; line-height:1; }
|
|
15
|
+
.seam-line { border-top:2px dashed var(--teal); position:relative; }
|
|
16
|
+
.seam-line:after { content:"SEAM"; position:absolute; right:0; top:-.78rem; padding:0 .45rem; background:white; color:var(--teal); font-size:.65rem; font-weight:800; letter-spacing:.12em; }
|
|
17
|
+
.mermaid { overflow-x:auto; background:#fff; padding:1.25rem; border:1px solid var(--line); border-radius:1rem; }
|
|
18
|
+
.evidence { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.8rem; overflow-wrap:anywhere; }
|
|
19
|
+
.impact td,.impact th { padding:.55rem .65rem; border-bottom:1px solid var(--line); text-align:left; vertical-align:top; }
|
|
20
|
+
@media print { body { background:white; } .module-box,.mermaid { box-shadow:none; break-inside:avoid; } }
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<main class="max-w-6xl mx-auto px-5 sm:px-8 py-10 sm:py-16">
|
|
25
|
+
<header class="border-b border-slate-300 pb-10">
|
|
26
|
+
<div class="flex flex-wrap gap-3 items-center text-sm text-slate-600">
|
|
27
|
+
<span class="rounded-full bg-slate-200 px-3 py-1 font-semibold">PH · PROMPT HISTORY</span>
|
|
28
|
+
<span>Architecture review</span><span>22 October 2026</span>
|
|
29
|
+
<span class="rounded-full bg-amber-100 text-amber-900 px-3 py-1 font-semibold">Working tree dirty</span>
|
|
30
|
+
</div>
|
|
31
|
+
<h1 class="serif text-5xl sm:text-6xl mt-8 leading-tight">A useful core under too many surfaces</h1>
|
|
32
|
+
<p class="mt-7 text-xl sm:text-2xl font-bold max-w-4xl">Strength: local capture, SQLite storage, and project-scoped retrieval form a coherent foundation with useful seams.</p>
|
|
33
|
+
<p class="mt-3 text-xl sm:text-2xl font-bold text-rose-800 max-w-4xl">Flaw: PH keeps adding command, transport, and knowledge workflows faster than it proves which ones users need.</p>
|
|
34
|
+
<div class="flex flex-wrap gap-3 mt-8 text-sm">
|
|
35
|
+
<span class="rounded-lg bg-slate-800 text-white px-3 py-2">Module</span>
|
|
36
|
+
<span class="rounded-lg border-2 border-dashed border-teal-700 text-teal-900 px-3 py-2">Seam</span>
|
|
37
|
+
<span class="rounded-lg border-2 border-dashed border-rose-600 text-rose-800 px-3 py-2">Leakage / unwired</span>
|
|
38
|
+
<span class="rounded-lg bg-teal-800 text-white px-3 py-2">Deep Module</span>
|
|
39
|
+
</div>
|
|
40
|
+
<p class="mt-6 max-w-4xl text-slate-600">This review describes the current working tree, including uncommitted operational-memory changes. It does not treat documentation or a passing test suite as proof of adoption.</p>
|
|
41
|
+
</header>
|
|
42
|
+
|
|
43
|
+
<section class="py-12 border-b border-slate-300">
|
|
44
|
+
<h2 class="serif text-3xl">Current Posture</h2>
|
|
45
|
+
<p class="mt-4 max-w-4xl text-slate-700">PH has a strong local-first data path and a meaningful retrieval boundary. Prompt capture remains useful without an LLM; semantic retrieval is optional; user approval gates curated memory writes. In this pass the MCP composition root was reduced to protocol setup, while memory and archive SQL moved behind repositories. The remaining concern is scope: a broad command set still exceeds what the operational workflow has validated.</p>
|
|
46
|
+
<div class="grid md:grid-cols-3 gap-4 mt-7">
|
|
47
|
+
<div class="module-box"><div class="text-3xl font-bold">97</div><div class="text-sm text-slate-600 mt-1">TypeScript / TSX source files</div></div>
|
|
48
|
+
<div class="module-box"><div class="text-3xl font-bold">17</div><div class="text-sm text-slate-600 mt-1">Test files; 94 tests passed in this checkout</div></div>
|
|
49
|
+
<div class="module-box"><div class="text-3xl font-bold">482 · 50 · 521 · 964</div><div class="text-sm text-slate-600 mt-1">Lines in CLI, MCP composition root, PhDB facade, and BrowseApp respectively</div></div>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="mt-6 grid md:grid-cols-2 gap-5 text-sm">
|
|
52
|
+
<div class="rounded-xl border border-slate-300 bg-white p-5"><h3 class="font-bold text-teal-900">Rules the system respects</h3><ul class="list-disc pl-5 mt-3 space-y-1 text-slate-700"><li>SQLite is the source of truth; Ollama and generative providers are optional.</li><li>Project filters are applied inside semantic retrieval before limiting results.</li><li>Operational `prepare` is read-only; `close` asks for approval before promotion.</li><li>CLI and MCP share task-context retrieval and atomic memory promotion use cases.</li><li>Memory and archive repositories share the existing SQLite connection through the stable PhDB facade.</li></ul></div>
|
|
53
|
+
<div class="rounded-xl border border-rose-200 bg-rose-50 p-5"><h3 class="font-bold text-rose-900">Rules that are not yet proven</h3><ul class="list-disc pl-5 mt-3 space-y-1 text-slate-700"><li>The plan's three real tasks across different projects are not evidenced; it records one temporary-database usage check.</li><li>MCP-only tools still own some search and rendering decisions inside their grouped handler modules.</li><li>Feature breadth spans history capture, analysis, memory, TUI, MCP, import, archive, and remote sync.</li><li>Embedding-backed retrieval quality has not been evaluated in this pass.</li></ul></div>
|
|
54
|
+
</div>
|
|
55
|
+
<p class="mt-5 text-sm text-slate-600">Verification observed: <span class="font-semibold">npm test</span> passed (17 files, 94 tests), <span class="font-semibold">npm run lint</span>, <span class="font-semibold">npm run build</span>, and `npx tsc --noEmit` all passed. A separate embedding-backed retrieval evaluation was not run.</p>
|
|
56
|
+
</section>
|
|
57
|
+
|
|
58
|
+
<section class="py-12 border-b border-slate-300">
|
|
59
|
+
<h2 class="serif text-3xl">Runtime Map</h2>
|
|
60
|
+
<p class="mt-3 max-w-4xl text-slate-700">Solid teal marks high-leverage modules; dashed red marks broad adapters or duplicated routes where responsibilities leak across boundaries.</p>
|
|
61
|
+
<div class="mermaid mt-6">
|
|
62
|
+
flowchart LR
|
|
63
|
+
User[User / agent] --> CLI[CLI dispatch and commands]
|
|
64
|
+
Hooks[CLI hooks and importers] --> Capture[Capture normalization]
|
|
65
|
+
CLI --> Capture
|
|
66
|
+
Capture --> DB[(SQLite / PhDB)]
|
|
67
|
+
CLI --> Retrieval[Project context retrieval]
|
|
68
|
+
MCP[MCP protocol composition] --> MCPTools[Grouped prompt, project, timeline handlers]
|
|
69
|
+
MCPTools --> Retrieval
|
|
70
|
+
Retrieval --> DB
|
|
71
|
+
Retrieval --> Embed[Embedding endpoint]
|
|
72
|
+
Retrieval --> Render[Shared context formatter]
|
|
73
|
+
Render --> CLI
|
|
74
|
+
Render --> MCPTools
|
|
75
|
+
CLI --> Close[Close proposal and approval]
|
|
76
|
+
Close --> Provider[Analysis provider]
|
|
77
|
+
Close --> DB
|
|
78
|
+
MCPTools --> DB
|
|
79
|
+
DB --> Vec[Semantic index]
|
|
80
|
+
CLI --> TUI[Ink browser]
|
|
81
|
+
TUI --> DB
|
|
82
|
+
CLI --> Remote[HTTP sync client]
|
|
83
|
+
Remote --> Server[HTTP sync server]
|
|
84
|
+
Server --> DB
|
|
85
|
+
classDef deep fill:#075e57,stroke:#064e48,color:#fff,stroke-width:2px;
|
|
86
|
+
classDef module fill:#e6f4f1,stroke:#0c8276,color:#153b38,stroke-width:1.5px;
|
|
87
|
+
classDef leak fill:#fff0f1,stroke:#c2414c,color:#762631,stroke-width:2px,stroke-dasharray:6 4;
|
|
88
|
+
classDef external fill:#f1f5f9,stroke:#64748b,color:#1e293b;
|
|
89
|
+
class Capture,Retrieval,Render,Vec deep;
|
|
90
|
+
class CLI,Close,TUI,DB,MCP,MCPTools module;
|
|
91
|
+
class Remote,Server leak;
|
|
92
|
+
class User,Hooks,Embed,Provider external;
|
|
93
|
+
</div>
|
|
94
|
+
<div class="grid md:grid-cols-3 gap-4 mt-5 text-sm">
|
|
95
|
+
<div class="module-box"><b>Capture Seam</b><p class="mt-2 text-slate-600">`src/capture/index.ts` normalizes direct logging, wrappers, and importers before persistence.</p></div>
|
|
96
|
+
<div class="module-box"><b>Retrieval Seam</b><p class="mt-2 text-slate-600">`src/knowledge/task-context.ts` shares bounded task retrieval across prepare and MCP; `src/context/index.ts` serves context and chat formatting.</p></div>
|
|
97
|
+
<div class="module-box border-rose-300"><b>Persistence Leakage</b><p class="mt-2 text-slate-600">The stable `PhDB` facade still exposes a broad prompt API; repository interfaces remain internal and SQLite-specific.</p></div>
|
|
98
|
+
</div>
|
|
99
|
+
</section>
|
|
100
|
+
|
|
101
|
+
<section class="py-12 border-b border-slate-300">
|
|
102
|
+
<h2 class="serif text-3xl">Candidates / Opportunities for Deepening</h2>
|
|
103
|
+
<p class="mt-3 text-slate-700 max-w-4xl">These are targeted reductions in real Leakage. They are not a proposal to replace the stack or split every file.</p>
|
|
104
|
+
|
|
105
|
+
<article class="mt-8 rounded-2xl border border-rose-200 bg-white p-6 sm:p-8">
|
|
106
|
+
<div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">1. Contain product scope until real-use evidence exists</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented as a scope gate</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P0</span></div></div>
|
|
107
|
+
<p class="evidence mt-4 text-slate-600">Evidence: `src/cli.ts:46-155` advertises a wide command set; `src/commands/` has 26 handlers; `README.md` describes capture, imports, analysis, memories, TUI, MCP, archive, and remote sync; `ROADMAP.md` now gates new user-facing work on three real tasks across projects.</p>
|
|
108
|
+
<h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">PH now has several overlapping ways to retrieve project knowledge (`context`, `prepare`, chat injection, MCP knowledge checks) plus a separate curation flow. The tool's command count is growing while the core promise—capture useful history and find it again—has no adoption or success measure in the repo. This is product-scope Leakage: every surface needs help, docs, compatibility, and tests.</p>
|
|
109
|
+
<h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">Keep the current commands available, state their distinct jobs, and defer new commands, transports, or knowledge workflows until the `prepare → work → close → promote` loop is used on three real tasks in different projects. The gate is now recorded in `ROADMAP.md`; no existing capability was removed.</p>
|
|
110
|
+
<div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before · surface area</b><div class="mt-3 flex flex-wrap gap-2 text-xs"><span class="bg-rose-50 p-2 rounded">context</span><span class="bg-rose-50 p-2 rounded">prepare</span><span class="bg-rose-50 p-2 rounded">chat context</span><span class="bg-rose-50 p-2 rounded">MCP check</span><span class="bg-rose-50 p-2 rounded">close</span><span class="bg-rose-50 p-2 rounded">save decision</span></div></div><div class="module-box border-teal-700"><b>After · gated growth</b><div class="mt-3 flex items-center gap-2 text-xs"><span class="bg-teal-50 p-2 rounded">capture</span><span class="diagram-arrow">→</span><span class="bg-teal-50 p-2 rounded">retrieve evidence</span><span class="diagram-arrow">→</span><span class="bg-teal-50 p-2 rounded">curate if useful</span></div><p class="mt-2 text-xs text-teal-900">No new surface until real-use gate.</p></div></div>
|
|
111
|
+
<div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> a user-visible workflow contract that works through CLI and MCP without duplicating domain decisions. <b>Deep Module:</b> the smallest evidence-backed workflow PH can make dependable.</p>
|
|
112
|
+
<table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>Less maintenance per feature and clearer product promise.</td><td>Related user actions converge on fewer entry points.</td><td>Add outcome checks for retrieval usefulness and accepted promotions, not just command behavior.</td></tr></table>
|
|
113
|
+
</article>
|
|
114
|
+
|
|
115
|
+
<article class="mt-6 rounded-2xl border border-amber-200 bg-white p-6 sm:p-8">
|
|
116
|
+
<div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">2. Give knowledge promotion one atomic persistence operation</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P1</span></div></div>
|
|
117
|
+
<p class="evidence mt-4 text-slate-600">Evidence: the previous implementation issued two writes per proposal. `PhDB.promoteMemories()` now delegates to the memory repository (`src/db/index.ts:473`); the shared provenance and promotion use case is `src/knowledge/promotion.ts`, used by CLI (`src/commands/close.ts:101`) and MCP (`src/mcp/tools/projects.ts:8,21`). A rollback test covers the transaction in `src/db/__tests__/phdb.test.ts`.</p>
|
|
118
|
+
<h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">Before this review, staged approval did not guarantee atomic persistence. A failed summary update or later proposal could leave a partial result. The fix now places the approved batch in one SQLite transaction; this candidate is addressed in the current working tree.</p>
|
|
119
|
+
<h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">The shared promotion operation accepts the approved proposal batch and writes memories plus aggregate summaries atomically. CLI and MCP use the same operation. Provider generation and interactive review stay outside the transaction; the Seam is the approved proposal batch.</p>
|
|
120
|
+
<div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before</b><div class="mt-3 flex items-center gap-2 text-xs"><span>insert memory</span><span class="diagram-arrow">→</span><span>update summary</span><span class="diagram-arrow">→</span><span>repeat</span></div><p class="mt-2 text-xs text-rose-800">Failure can leave partial state.</p></div><div class="module-box border-teal-700"><b>After</b><div class="mt-3 rounded-lg bg-teal-50 p-3 text-xs">Approved batch <span class="diagram-arrow">→</span> single DB transaction <span class="diagram-arrow">→</span> consistent memories + summaries</div></div></div>
|
|
121
|
+
<div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> transport-independent promotion input. <b>Deep Module:</b> persistence owns consistency and exposes one operation with a simple result.</p>
|
|
122
|
+
<table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>Both CLI and MCP get the same all-or-nothing guarantee.</td><td>Memory and summary consistency live beside database writes.</td><td>Inject a failure midway and assert neither side changed.</td></tr></table>
|
|
123
|
+
</article>
|
|
124
|
+
|
|
125
|
+
<article class="mt-6 rounded-2xl border border-amber-200 bg-white p-6 sm:p-8">
|
|
126
|
+
<div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">3. Thin the MCP composition root and share cross-transport work</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented; handlers remain adapters</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P1</span></div></div>
|
|
127
|
+
<p class="evidence mt-4 text-slate-600">Evidence: `src/mcp/server.ts` is now 50 lines. Tool definitions live in `src/mcp/tools/definitions.ts`; prompt, project, and timeline handlers are grouped in `src/mcp/tools/`; formatting is isolated in `format.ts`. `src/knowledge/{task-context,promotion}.ts` centralize shared retrieval and persistence.</p>
|
|
128
|
+
<h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">The original server mixed protocol registration, all handlers, retrieval policy, writes, and formatting. The composition root is now small and tool code is local by domain. Some MCP-only search, timeline, and output behavior remains in adapter modules, so the transport boundary is improved but not fully domain-neutral.</p>
|
|
129
|
+
<h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">The composition root now owns MCP SDK registration, handler dispatch, and error envelopes. Shared task-context retrieval and memory promotion live under `src/knowledge/` and are called by CLI and MCP. Tool-specific protocols and renderers remain grouped under `src/mcp/tools/`; further extraction should wait for another consumer.</p>
|
|
130
|
+
<div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before</b><div class="mt-3 text-xs space-y-2"><div class="rounded bg-rose-50 p-2">MCP root owns tool declarations, queries, fallback, and formatting</div><div class="rounded bg-rose-50 p-2">MCP root validates sources and performs persistence</div></div></div><div class="module-box border-teal-700"><b>After</b><div class="mt-3 text-xs space-y-2"><div class="rounded bg-teal-50 p-2">MCP root → grouped tool handlers → shared task-context use case</div><div class="rounded bg-teal-50 p-2">CLI / MCP → shared promotion use case → PhDB facade</div></div></div></div>
|
|
131
|
+
<div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> transport-neutral application operations. <b>Deep Module:</b> reusable project knowledge behavior with a compact input/output contract.</p>
|
|
132
|
+
<table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>New transports reuse product behavior instead of cloning it.</td><td>Protocol concerns stop interleaving with retrieval and writes.</td><td>Use-case tests avoid MCP protocol setup; adapter tests focus on schemas and errors.</td></tr></table>
|
|
133
|
+
</article>
|
|
134
|
+
|
|
135
|
+
<article class="mt-6 rounded-2xl border border-amber-200 bg-white p-6 sm:p-8">
|
|
136
|
+
<div class="flex flex-wrap justify-between gap-3"><h3 class="serif text-2xl">4. Split cohesive persistence behind the PhDB facade</h3><div class="flex gap-2"><span class="rounded-full bg-teal-100 text-teal-900 px-3 py-1 text-sm font-bold">Implemented for memory and archive</span><span class="rounded-full bg-slate-800 text-white px-3 py-1 text-sm font-bold">P2</span></div></div>
|
|
137
|
+
<p class="evidence mt-4 text-slate-600">Evidence: `src/db/index.ts` is now a 521-line public facade with prompt CRUD, FTS, migrations, and query forwarding. Memory and summary persistence moved to `src/db/memory-repository.ts`; archive persistence moved to `src/db/archive-repository.ts`; vectors remain in `src/db/semantic-index.ts`.</p>
|
|
138
|
+
<h4 class="mt-5 font-bold">Problem</h4><p class="text-slate-700">PhDB previously owned SQL for prompt CRUD, FTS, archives, memories, and summaries in one implementation. Memory and archive SQL now live in cohesive repositories over the same connection. The facade deliberately retains source compatibility; prompt CRUD and FTS remain one group.</p>
|
|
139
|
+
<h4 class="mt-5 font-bold">Solution</h4><p class="text-slate-700">The extraction keeps prompt CRUD/FTS in the facade and moves memory/summary and archive SQL behind internal repositories. All repositories share one SQLite connection; `PhDB` method names and return values stay stable. Avoid widening the repository abstraction until a second adapter needs it.</p>
|
|
140
|
+
<div class="grid sm:grid-cols-2 gap-3 mt-5"><div class="module-box border-rose-300"><b>Before</b><div class="mt-3 flex flex-wrap gap-2 text-xs"><span class="bg-rose-50 rounded p-2">PhDB: prompt</span><span class="bg-rose-50 rounded p-2">memory</span><span class="bg-rose-50 rounded p-2">summary</span><span class="bg-rose-50 rounded p-2">archive</span><span class="bg-rose-50 rounded p-2">migrations</span></div></div><div class="module-box border-teal-700"><b>After</b><div class="mt-3 flex items-center gap-2 text-xs"><span class="bg-teal-50 rounded p-2">PhDB prompt facade</span><span class="diagram-arrow">→</span><span class="border-2 border-dashed border-teal-700 rounded p-2">MemoryRepository<br>ArchiveRepository</span><span class="diagram-arrow">→</span><span class="bg-teal-50 rounded p-2">shared SQLite</span></div></div></div>
|
|
141
|
+
<div class="seam-line mt-8"></div><p class="mt-4 text-sm text-slate-700"><b>Seam:</b> existing PhDB-to-SQLite boundary, narrowed around use cases. <b>Deep Module:</b> a repository operation that hides SQL and guarantees its domain invariant.</p>
|
|
142
|
+
<table class="impact w-full mt-4 text-sm"><tr><th>Leverage</th><th>Locality</th><th>Tests</th></tr><tr><td>Changes to archive or memory behavior affect fewer consumers.</td><td>Each persistence concern owns its schema/query details.</td><td>Test repository invariants against temporary SQLite; use-case tests use a small contract.</td></tr></table>
|
|
143
|
+
</article>
|
|
144
|
+
</section>
|
|
145
|
+
|
|
146
|
+
<section class="py-12 border-b border-slate-300">
|
|
147
|
+
<h2 class="serif text-3xl">Top Recommendation</h2>
|
|
148
|
+
<div class="mt-5 rounded-2xl bg-slate-900 text-white p-6 sm:p-8">
|
|
149
|
+
<p class="text-teal-200 text-sm uppercase tracking-widest font-bold">First move · validate the operational workflow</p>
|
|
150
|
+
<h3 class="serif text-3xl mt-3">Do not add another memory feature yet</h3>
|
|
151
|
+
<p class="mt-4 max-w-4xl text-slate-200">Three structural actions are now in place: a product-scope gate, transport-neutral task-context and promotion operations with grouped MCP modules, and internal memory/archive repositories behind the unchanged PhDB API. Keep `prepare` as a read-only experiment. The remaining product test is three real tasks on different projects; record whether the brief prevented repeated work before adding more features.</p>
|
|
152
|
+
<p class="mt-4 max-w-4xl text-slate-200">Why this comes first: the biggest risk is not that PH lacks another abstraction. It is that summaries, memories, and tool-specific retrieval behavior drift while product value remains unmeasured. A transaction seam protects data now; a usage gate protects the project from building maintenance around an unproven loop.</p>
|
|
153
|
+
</div>
|
|
154
|
+
</section>
|
|
155
|
+
|
|
156
|
+
<section class="py-12 border-b border-slate-300">
|
|
157
|
+
<h2 class="serif text-3xl">Usage Modes</h2>
|
|
158
|
+
<div class="grid md:grid-cols-2 gap-4 mt-6">
|
|
159
|
+
<div class="module-box"><h3 class="font-bold">Capture and import history</h3><p class="mt-2 text-sm text-slate-600">Direct logging, wrappers, hooks, and importers normalize into prompt records.</p><p class="evidence mt-3">`src/capture/index.ts`, `src/importer/`, `src/commands/log.ts`, `hooks/`</p></div>
|
|
160
|
+
<div class="module-box"><h3 class="font-bold">Search local prompt history</h3><p class="mt-2 text-sm text-slate-600">SQLite FTS supports text search; sqlite-vec adds optional semantic search.</p><p class="evidence mt-3">`src/commands/search.ts`, `src/db/index.ts:246-345`, `src/db/semantic-index.ts`</p></div>
|
|
161
|
+
<div class="module-box"><h3 class="font-bold">Browse and curate records</h3><p class="mt-2 text-sm text-slate-600">The Ink interface filters, previews, edits metadata, exports, and reruns prompts.</p><p class="evidence mt-3">`src/ui/BrowseApp.tsx`, `src/ui/FilterPanel.tsx`, `src/ui/PreviewPane.tsx`</p></div>
|
|
162
|
+
<div class="module-box"><h3 class="font-bold">Expose history and project context to agents</h3><p class="mt-2 text-sm text-slate-600">MCP serves prompt queries and project knowledge; project tools call shared task-context retrieval and promotion use cases.</p><p class="evidence mt-3">`src/mcp/server.ts`, `src/mcp/tools/`, `src/knowledge/`</p></div>
|
|
163
|
+
<div class="module-box"><h3 class="font-bold">Prepare and promote operational knowledge</h3><p class="mt-2 text-sm text-slate-600">`prepare` retrieves a bounded brief; `close` proposes curated memory after provider analysis and user approval. Implemented in the current dirty tree; three-project real-use validation remains outstanding.</p><p class="evidence mt-3">`src/commands/prepare.ts`, `src/commands/close.ts`, `docs/specs/SPEC-016-operational-memory.md`</p></div>
|
|
164
|
+
<div class="module-box"><h3 class="font-bold">Synchronize with a remote PH server</h3><p class="mt-2 text-sm text-slate-600">An optional HTTP service supports prompt push/pull and memory lookups. It adds a second deployment and security surface.</p><p class="evidence mt-3">`src/server/index.ts`, `src/commands/remote.ts`</p></div>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="mt-8 grid md:grid-cols-2 gap-4">
|
|
167
|
+
<div class="rounded-xl bg-teal-50 border border-teal-300 p-5"><h3 class="font-bold text-teal-950">Ready for...</h3><p class="mt-2 text-sm text-slate-700">Local prompt capture, search, browsing, and opt-in agent access to a user's own project history. The operational-memory commands are implemented and pass their current automated suite.</p></div>
|
|
168
|
+
<div class="rounded-xl bg-rose-50 border border-rose-300 p-5"><h3 class="font-bold text-rose-950">Still requires integration...</h3><p class="mt-2 text-sm text-slate-700">Evidence that the prepare/close loop improves real tasks; retrieval evaluation against the configured embedding model; and a coherent support boundary for the many transports and commands.</p></div>
|
|
169
|
+
</div>
|
|
170
|
+
</section>
|
|
171
|
+
|
|
172
|
+
<footer class="pt-8 text-sm text-slate-600 flex flex-wrap justify-between gap-3">
|
|
173
|
+
<span>PH Architecture Review · Based on the working tree at review time</span>
|
|
174
|
+
<span>Created: 2026-10-22 · Updated: 2026-10-22</span>
|
|
175
|
+
</footer>
|
|
176
|
+
</main>
|
|
177
|
+
<script>mermaid.initialize({startOnLoad:true,theme:'neutral',securityLevel:'strict'});</script>
|
|
178
|
+
</body>
|
|
179
|
+
</html>
|
package/docs/ph-manual.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# ph — Prompt History and Project Memory
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Capture AI CLI work, find it later, and retrieve project context when you need it.**
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## 1. Overview
|
|
8
8
|
|
|
9
|
-
ph is a
|
|
9
|
+
ph is a local history and project-context tool for AI CLI work. It records interactions through native hooks or by wrapping a tool, then helps you search history and retrieve project context from the terminal.
|
|
10
10
|
|
|
11
|
-
**Core principle:** ph captures conversations without changing the normal tool workflow. Optional analysis
|
|
11
|
+
**Core principle:** ph captures conversations without changing the normal tool workflow. Optional analysis enriches each captured interaction with searchable summary, insights, decisions, and classification. Analysis does not promote active project memories; `ph close` and MCP `save_decision` are the explicit promotion paths. 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
|
|
|
@@ -17,7 +17,7 @@ ph is a transparent observability and knowledge layer for AI CLI tools (Claude C
|
|
|
17
17
|
- **LLM analysis** — role/tag/relevance classification, summary extraction, key insights, technical decisions
|
|
18
18
|
- **Project memory** — per-project accumulated knowledge with deduped insights and decisions
|
|
19
19
|
- **MCP server** — tools for agents to search memories, check project knowledge, get context
|
|
20
|
-
- **
|
|
20
|
+
- **Plain-text CLI** — the everyday interface is a small set of terminal commands
|
|
21
21
|
- **Session grouping** — automatic conversation grouping with cohesion scoring
|
|
22
22
|
- **Git context** — records branch, modified files, and diff at capture time
|
|
23
23
|
- **Background analysis** — async LLM processing after each capture (optional)
|
|
@@ -45,7 +45,7 @@ npm link
|
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
ph config set background-analysis true # auto-analyze after each capture
|
|
48
|
-
ph config set analyze-provider ollama # ollama (default) or
|
|
48
|
+
ph config set analyze-provider ollama # ollama (default), gemini, openrouter, or mlx-serve
|
|
49
49
|
ph config set ollama-model llama3.1:latest
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -98,18 +98,41 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|
|
101
|
-
## 4.
|
|
101
|
+
## 4. Everyday Commands
|
|
102
102
|
|
|
103
103
|
| Command | Description |
|
|
104
104
|
|---------|-------------|
|
|
105
|
-
| `ph`
|
|
105
|
+
| `ph` | Print the short usage guide |
|
|
106
|
+
| `ph setup` | Connect installed Claude Code, Codex CLI, Gemini CLI, and OpenCode for automatic capture |
|
|
107
|
+
| `ph <tool> [args...]` | Run an AI CLI tool and capture the interaction |
|
|
108
|
+
| `ph search <query>` | Find earlier work in the current project (five matches by default) |
|
|
109
|
+
| `ph show <id>` | Inspect the complete prompt, response, capture metadata, and analysis |
|
|
110
|
+
| `ph show <id> --json` | Print the complete interaction as JSON |
|
|
111
|
+
| `ph context "task"` | Retrieve project knowledge and related prompts |
|
|
112
|
+
| `ph close` | Review the last three hours and approve useful project knowledge |
|
|
113
|
+
|
|
114
|
+
`ph setup` is the recommended first step for everyday use. It detects installed supported tools (Claude Code, Codex CLI, Gemini CLI, and OpenCode), installs their native capture integrations, preserves existing settings, and reports whether each integration was installed or already configured. Pass tool names to choose explicitly. After setup, keep using your AI CLI normally; `ph search "query"` is the main command for retrieving earlier work. `ph <tool>` remains as a wrapper alternative.
|
|
115
|
+
|
|
116
|
+
`ph search "query"` searches the project detected from the current directory and returns five matches by default, ordered by text relevance. Use `--limit <n>` to show more, or `--all` to search across every project. When no project can be detected, PH searches all saved work and labels that scope. Searches with no current-project matches explain how to broaden the search.
|
|
117
|
+
|
|
118
|
+
`ph prepare "task"` remains as a compatibility alias for task-aware `ph context`.
|
|
119
|
+
`ph browse` is a compatibility alias for a plain-text list of recent interactions.
|
|
120
|
+
Use `ph help --all` for maintenance and integration commands, including `ph status` for recent capture and background-work state.
|
|
121
|
+
|
|
122
|
+
## 4a. Advanced Command Reference
|
|
123
|
+
|
|
124
|
+
| Command | Description |
|
|
125
|
+
|---------|-------------|
|
|
126
|
+
| `ph` (no args) | Print the short everyday-use guide |
|
|
106
127
|
| `ph <tool> [args...]` | Wrapper mode — run tool + capture |
|
|
107
|
-
| `ph search [query]` | Full-text search
|
|
128
|
+
| `ph search [query]` | Full-text search (current project, five matches by default) |
|
|
108
129
|
| `ph search --semantic <query>` | Semantic (vector) search |
|
|
109
130
|
| `ph search --archive` | Search archived prompts |
|
|
110
|
-
| `ph search -i <query>` | Open results in interactive TUI |
|
|
111
131
|
| `ph last [n]` | Show last N prompts |
|
|
112
|
-
| `ph context [
|
|
132
|
+
| `ph context [task]` | Retrieve task-aware project context; works without semantic embeddings |
|
|
133
|
+
| `ph prepare "<task>"` | Compatibility alias for task-aware context retrieval |
|
|
134
|
+
| `ph browse` | Compatibility alias for recent text results |
|
|
135
|
+
| `ph close [--since 3h]` | Review recent work and propose knowledge for explicit approval |
|
|
113
136
|
| `ph sessions` | Group prompts into work sessions |
|
|
114
137
|
| `ph timeline <project>` | Full chronological project history |
|
|
115
138
|
| `ph stats` | History statistics |
|
|
@@ -120,10 +143,11 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
120
143
|
| `ph cleanup --retention` | Archive old/unqualified prompts per retention policy |
|
|
121
144
|
| `ph cleanup-reusability` | Cleanup by reusability score |
|
|
122
145
|
| `ph star <id>` | Toggle bookmark |
|
|
123
|
-
| `ph export <id
|
|
146
|
+
| `ph export <id> [--format txt|json|md] [--archive]` | Export a complete interaction |
|
|
147
|
+
| `ph status` | Show recent capture, analysis, and remote-push state without content |
|
|
124
148
|
| `ph import gemini|claude|opencode|codex` | Import from AI CLI history |
|
|
125
149
|
| `ph log --tool <name> ...` | Direct log (hook target) |
|
|
126
|
-
| `ph embed-all` | Generate embeddings for
|
|
150
|
+
| `ph embed-all` | Generate embeddings for prompts without vectors |
|
|
127
151
|
| `ph config get|set <key> <value>` | View/edit config |
|
|
128
152
|
| `ph vacuum` | Compact SQLite database |
|
|
129
153
|
| `ph memory-migrate` | Merge existing memories into project_summaries |
|
|
@@ -136,7 +160,6 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
136
160
|
### Search options
|
|
137
161
|
|
|
138
162
|
```
|
|
139
|
-
-i / --interactive Open in TUI browser
|
|
140
163
|
--tool <name> Filter by tool
|
|
141
164
|
--project <name> Filter by project
|
|
142
165
|
--language <lang> Filter by language
|
|
@@ -147,11 +170,12 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
147
170
|
--archive Search archived prompts
|
|
148
171
|
--since YYYY-MM-DD Start date
|
|
149
172
|
--until YYYY-MM-DD End date
|
|
150
|
-
--limit <n> Max results (default
|
|
173
|
+
--limit <n> Max results (default 5)
|
|
174
|
+
--all Search across all projects instead of the current project
|
|
151
175
|
--top Quality >= 8
|
|
152
176
|
--min-quality <n> Min quality (0-10)
|
|
153
177
|
--min-relevance <n> Min relevance (0-10)
|
|
154
|
-
--full Show full prompt text
|
|
178
|
+
--full Show full prompt and response text
|
|
155
179
|
```
|
|
156
180
|
|
|
157
181
|
### Context options
|
|
@@ -183,43 +207,13 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
183
207
|
|
|
184
208
|
---
|
|
185
209
|
|
|
186
|
-
## 5.
|
|
187
|
-
|
|
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)
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## 6. Project Memory System
|
|
210
|
+
## 5. Project Memory System
|
|
217
211
|
|
|
218
212
|
ph maintains two levels of per-project knowledge:
|
|
219
213
|
|
|
220
|
-
###
|
|
214
|
+
### 5a. `project_summaries` (curated, 1 row per project)
|
|
221
215
|
|
|
222
|
-
Accumulated knowledge with deduped insights and decisions. Updated
|
|
216
|
+
Accumulated, explicitly promoted knowledge with deduped insights and decisions. Updated by approved `close` proposals, MCP `save_decision`, and legacy migration; automatic analysis does not write here.
|
|
223
217
|
|
|
224
218
|
```bash
|
|
225
219
|
# View accumulated project knowledge
|
|
@@ -229,9 +223,29 @@ ph context --project myproject
|
|
|
229
223
|
# get_project_summary(project: "myproject")
|
|
230
224
|
```
|
|
231
225
|
|
|
232
|
-
###
|
|
226
|
+
### 5b. `memories` (append-only timeline)
|
|
227
|
+
|
|
228
|
+
Legacy append-only project knowledge records retained for detailed audit. New automatic analysis results stay on their source interaction instead of creating memory rows.
|
|
229
|
+
|
|
230
|
+
### Operational workflow: retrieve, work, review
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Read-only task context; project auto-detected from the current directory
|
|
234
|
+
ph context "add Wise provider" --limit 5 --budget 3500
|
|
235
|
+
|
|
236
|
+
# Inspect the selection without calling an LLM
|
|
237
|
+
ph close --dry-run --since 3h
|
|
238
|
+
|
|
239
|
+
# Generate knowledge proposals; approve, edit, skip, or quit each one
|
|
240
|
+
ph close --since 3h
|
|
241
|
+
ph close --from 1670 --to 1682 --project ph
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`context` uses the task as a semantic retrieval query and prints source-linked prompt and memory excerpts. If Ollama embeddings are unavailable, it labels the fallback to recent project context. Retrieval never writes to SQLite. `prepare` remains an alias for compatibility. The character budget limits retrieved content; when the source list itself is larger than the budget, source IDs take precedence and the output can exceed the requested budget.
|
|
233
245
|
|
|
234
|
-
|
|
246
|
+
`close` selects prompt/response pairs within one project, displays them before generation, and asks the configured analysis provider for durable proposals. It checks for a terminal before making that provider call. Each accepted proposal creates an append-only memory tied to its source prompt IDs; the approved batch and summary updates are committed in one SQLite transaction. A persistence failure rolls back the whole batch. Provider errors, malformed output, dry-run, skipping, and quitting do not promote unapproved knowledge.
|
|
247
|
+
|
|
248
|
+
MCP `check_project_knowledge` uses the same retrieval and rendering boundary. MCP `save_decision` accepts optional `promptIds` and rejects missing or cross-project sources.
|
|
235
249
|
|
|
236
250
|
### Memory migration
|
|
237
251
|
|
|
@@ -243,7 +257,7 @@ ph memory-migrate # one-time: merge all memories into project_summaries
|
|
|
243
257
|
|
|
244
258
|
---
|
|
245
259
|
|
|
246
|
-
##
|
|
260
|
+
## 6. Retention & Archiving
|
|
247
261
|
|
|
248
262
|
Configurable auto-archiving to keep the database lean:
|
|
249
263
|
|
|
@@ -266,9 +280,9 @@ ph search --archive
|
|
|
266
280
|
|
|
267
281
|
---
|
|
268
282
|
|
|
269
|
-
##
|
|
283
|
+
## 7. Background Analysis
|
|
270
284
|
|
|
271
|
-
When enabled, every `ph log`
|
|
285
|
+
When enabled, every `ph log` marks analysis pending and starts a detached child process that adds role, tags, relevance, summary, key insights, and technical decisions to the interaction. It does not create project memories or summaries. `ph status` shows pending, complete, or safe failure state. Remote push status is shown when configured.
|
|
272
286
|
|
|
273
287
|
```bash
|
|
274
288
|
ph config set background-analysis true
|
|
@@ -283,9 +297,40 @@ ph config set ollama-model llama3.1:latest
|
|
|
283
297
|
ph config set ollama-embed-model nomic-embed-text-v2-moe
|
|
284
298
|
```
|
|
285
299
|
|
|
300
|
+
OpenRouter and MLX-Serve generation use `@gi4nks/wise`:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# OpenRouter: credentials stay in the environment; model IDs keep provider/model.
|
|
304
|
+
export OPENROUTER_API_KEY="your_openrouter_api_key"
|
|
305
|
+
ph models openrouter
|
|
306
|
+
ph config set openrouter-api-key # hidden prompt; or keep using the environment
|
|
307
|
+
ph config set analyze-provider openrouter
|
|
308
|
+
ph config set openrouter-model "provider/model-id"
|
|
309
|
+
ph config show # provider settings with credentials redacted
|
|
310
|
+
ph analyze
|
|
311
|
+
|
|
312
|
+
# MLX-Serve on Parmenide: open this tunnel in a separate terminal.
|
|
313
|
+
ssh -N -L 11234:127.0.0.1:11234 parmenide
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# In the terminal where you run ph:
|
|
318
|
+
ph models mlx-serve
|
|
319
|
+
ph config set analyze-provider mlx-serve
|
|
320
|
+
ph config set mlx-serve-model "exact-model-id-from-server"
|
|
321
|
+
ph analyze
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
MLX-Serve defaults to `http://127.0.0.1:11234/v1`. Override it with
|
|
325
|
+
`MLX_SERVE_BASE_URL` or `ph config set mlx-serve-url <url>`. Set
|
|
326
|
+
`MLX_SERVE_API_KEY` if the server requires auth; `GLB_OMLX_API_KEY` is also
|
|
327
|
+
accepted for existing setups. Alternatively run `ph config set mlx-serve-api-key`
|
|
328
|
+
to enter it without echoing it in the terminal. `ph config show` redacts
|
|
329
|
+
credentials. `ph models mlx-serve` marks entries `[loaded]` or `[unloaded]`.
|
|
330
|
+
|
|
286
331
|
---
|
|
287
332
|
|
|
288
|
-
##
|
|
333
|
+
## 8. MCP Server
|
|
289
334
|
|
|
290
335
|
ph exposes an MCP (Model Context Protocol) server over stdio for AI agents:
|
|
291
336
|
|
|
@@ -311,26 +356,30 @@ ph mcp
|
|
|
311
356
|
|
|
312
357
|
---
|
|
313
358
|
|
|
314
|
-
##
|
|
359
|
+
## 9. HTTP Server & Remote Sync
|
|
315
360
|
|
|
316
361
|
Share prompt history across machines:
|
|
317
362
|
|
|
318
363
|
```bash
|
|
319
|
-
#
|
|
320
|
-
ph
|
|
321
|
-
|
|
322
|
-
|
|
364
|
+
# Configure the required server key, then start on loopback
|
|
365
|
+
ph config set remote-api-key "$PH_REMOTE_API_KEY"
|
|
366
|
+
ph server --port 3001
|
|
367
|
+
|
|
368
|
+
# On the server, expose the listener only on a protected interface and put TLS
|
|
369
|
+
# in front of it before using the endpoint across an untrusted network.
|
|
370
|
+
# On each client, set the server URL and the same key:
|
|
371
|
+
ph config set remote-api-key "$PH_REMOTE_API_KEY"
|
|
323
372
|
ph config set remote-url http://server-ip:3001
|
|
324
|
-
ph remote push #
|
|
325
|
-
ph remote pull #
|
|
373
|
+
ph remote push # resumable ID-based sync
|
|
374
|
+
ph remote pull # resumable ID-based sync
|
|
326
375
|
ph remote status # show sync state
|
|
327
376
|
```
|
|
328
377
|
|
|
329
|
-
|
|
378
|
+
The server requires a key before it starts, binds to `127.0.0.1` by default, and exposes only a status value at public `/health`. All data routes require Bearer authentication. Push and pull cursors are scoped to the remote target and the local database UUID. Push pages are split to stay below the 32 MiB request-body limit; interrupted pages can be retried safely. Bulk push waits at a live wrapper record and continues after the response is saved. `ph log` and both wrapper modes push after capture; requests time out after five seconds so an unavailable server cannot hang the command indefinitely. An invalid optional remote URL marks sync failed while the interaction remains saved locally and the wrapped CLI still runs. Current limitation: replacing the remote database behind the same URL is not detected, and last-push/pull status times are global across targets.
|
|
330
379
|
|
|
331
380
|
---
|
|
332
381
|
|
|
333
|
-
##
|
|
382
|
+
## 10. Database
|
|
334
383
|
|
|
335
384
|
**Location:** `~/.prompt_history.db` (configurable via `ph config set db-path`)
|
|
336
385
|
|
|
@@ -351,12 +400,12 @@ Every `ph log` auto-pushes to remote if configured (fire-and-forget, never block
|
|
|
351
400
|
ph vacuum # compact DB
|
|
352
401
|
ph cleanup # remove short/trivial/duplicate prompts
|
|
353
402
|
ph cleanup --retention # archive per retention policy
|
|
354
|
-
ph embed-all #
|
|
403
|
+
ph embed-all # generate vectors for prompts without embeddings
|
|
355
404
|
```
|
|
356
405
|
|
|
357
406
|
---
|
|
358
407
|
|
|
359
|
-
##
|
|
408
|
+
## 11. Filter Pipeline
|
|
360
409
|
|
|
361
410
|
Before saving, ph filters out:
|
|
362
411
|
|
|
@@ -375,16 +424,20 @@ ph config set filter-min-relevance 3
|
|
|
375
424
|
|
|
376
425
|
---
|
|
377
426
|
|
|
378
|
-
##
|
|
427
|
+
## 12. Configuration (`~/.ph_config.json`)
|
|
379
428
|
|
|
380
429
|
| Key | Default | Description |
|
|
381
430
|
|-----|---------|-------------|
|
|
382
431
|
| `dbPath` | `~/.prompt_history.db` | SQLite database path |
|
|
383
|
-
| `analyzeProvider` | `ollama` | LLM provider: `ollama` or `
|
|
432
|
+
| `analyzeProvider` | `ollama` | LLM provider: `ollama`, `gemini`, `openrouter`, or `mlx-serve` |
|
|
384
433
|
| `ollamaUrl` | `http://localhost:11434` | Ollama server URL |
|
|
385
434
|
| `ollamaModel` | `llama3.1:latest` | Analysis model |
|
|
386
435
|
| `ollamaEmbedModel` | `nomic-embed-text-v2-moe` | Embedding model |
|
|
387
436
|
| `geminiApiKey` | — | Gemini API key |
|
|
437
|
+
| `openrouterModel` | — | Exact OpenRouter model ID |
|
|
438
|
+
| `openrouterUrl` | `https://openrouter.ai/api/v1` | OpenRouter-compatible API root |
|
|
439
|
+
| `mlxServeModel` | — | Exact MLX-Serve model ID |
|
|
440
|
+
| `mlxServeUrl` | `http://127.0.0.1:11234/v1` | MLX-Serve API root (Parmenide SSH tunnel by default) |
|
|
388
441
|
| `backgroundAnalysis` | `false` | Auto-analyze after each capture |
|
|
389
442
|
| `filterMinLength` | `15` | Min prompt length to keep |
|
|
390
443
|
| `filterMinRelevance` | `3` | Min relevance to keep (0=disable) |
|
|
@@ -394,12 +447,16 @@ ph config set filter-min-relevance 3
|
|
|
394
447
|
| `retentionMinRelevance` | `3` | Archive prompts below this relevance |
|
|
395
448
|
| `remoteUrl` | — | Remote ph server URL (or `PH_REMOTE_URL` env) |
|
|
396
449
|
| `remoteApiKey` | — | Remote server API key |
|
|
397
|
-
| `remoteLastPush` | — |
|
|
398
|
-
| `remoteLastPull` | — |
|
|
450
|
+
| `remoteLastPush` | — | Global timestamp of last successful push |
|
|
451
|
+
| `remoteLastPull` | — | Global timestamp of last successful pull |
|
|
452
|
+
|
|
453
|
+
Provider API credentials are environment-only: `OPENROUTER_API_KEY` and
|
|
454
|
+
`MLX_SERVE_API_KEY` (`GLB_OMLX_API_KEY` is a fallback). They are not written to
|
|
455
|
+
`~/.ph_config.json`.
|
|
399
456
|
|
|
400
457
|
---
|
|
401
458
|
|
|
402
|
-
##
|
|
459
|
+
## 13. Architecture
|
|
403
460
|
|
|
404
461
|
```
|
|
405
462
|
Hook/Import → ph log → prompts table (FTS5 indexed)
|
|
@@ -432,14 +489,13 @@ src/
|
|
|
432
489
|
filter/ # Capture-time filter pipeline
|
|
433
490
|
mcp/server.ts # MCP stdio server
|
|
434
491
|
server/index.ts # HTTP REST server (zero deps)
|
|
435
|
-
ui/ # React/Ink TUI, including extracted filter policy and panel
|
|
436
492
|
importer/ # Gemini/Claude/OpenCode/Codex history importers
|
|
437
493
|
hooks/ # Shell scripts and plugins for AI tools
|
|
438
494
|
```
|
|
439
495
|
|
|
440
496
|
---
|
|
441
497
|
|
|
442
|
-
##
|
|
498
|
+
## 14. Importing Existing History
|
|
443
499
|
|
|
444
500
|
```bash
|
|
445
501
|
# Import from Claude Code
|
|
@@ -463,7 +519,7 @@ ph import codex
|
|
|
463
519
|
|
|
464
520
|
---
|
|
465
521
|
|
|
466
|
-
##
|
|
522
|
+
## 15. Versioning and Releases
|
|
467
523
|
|
|
468
524
|
Use Conventional Commits to describe changes: `feat:` requests a minor release,
|
|
469
525
|
`fix:` requests a patch release, and `BREAKING CHANGE:` requests a major release.
|