@gi4nks/ph 1.7.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 +15 -1
- package/README.md +34 -18
- package/dist/cli.js +3383 -3700
- 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 +88 -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/codex/README.md +1 -1
- package/hooks/codex/ph-hook.sh +2 -1
- package/package.json +1 -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,16 +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
|
|
12
|
-
|
|
13
|
-
In the TUI, `p` runs the selected prompt through one of the configured Wise analysis providers (same provider/model/URL settings shown by `ph config show`) and saves the response to history. `r` reruns the prompt with its original CLI tool.
|
|
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.
|
|
14
12
|
|
|
15
13
|
### Key Features
|
|
16
14
|
|
|
@@ -19,7 +17,7 @@ In the TUI, `p` runs the selected prompt through one of the configured Wise anal
|
|
|
19
17
|
- **LLM analysis** — role/tag/relevance classification, summary extraction, key insights, technical decisions
|
|
20
18
|
- **Project memory** — per-project accumulated knowledge with deduped insights and decisions
|
|
21
19
|
- **MCP server** — tools for agents to search memories, check project knowledge, get context
|
|
22
|
-
- **
|
|
20
|
+
- **Plain-text CLI** — the everyday interface is a small set of terminal commands
|
|
23
21
|
- **Session grouping** — automatic conversation grouping with cohesion scoring
|
|
24
22
|
- **Git context** — records branch, modified files, and diff at capture time
|
|
25
23
|
- **Background analysis** — async LLM processing after each capture (optional)
|
|
@@ -100,18 +98,41 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
100
98
|
|
|
101
99
|
---
|
|
102
100
|
|
|
103
|
-
## 4.
|
|
101
|
+
## 4. Everyday Commands
|
|
104
102
|
|
|
105
103
|
| Command | Description |
|
|
106
104
|
|---------|-------------|
|
|
107
|
-
| `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 |
|
|
108
127
|
| `ph <tool> [args...]` | Wrapper mode — run tool + capture |
|
|
109
|
-
| `ph search [query]` | Full-text search
|
|
128
|
+
| `ph search [query]` | Full-text search (current project, five matches by default) |
|
|
110
129
|
| `ph search --semantic <query>` | Semantic (vector) search |
|
|
111
130
|
| `ph search --archive` | Search archived prompts |
|
|
112
|
-
| `ph search -i <query>` | Open results in interactive TUI |
|
|
113
131
|
| `ph last [n]` | Show last N prompts |
|
|
114
|
-
| `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 |
|
|
115
136
|
| `ph sessions` | Group prompts into work sessions |
|
|
116
137
|
| `ph timeline <project>` | Full chronological project history |
|
|
117
138
|
| `ph stats` | History statistics |
|
|
@@ -122,10 +143,11 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
122
143
|
| `ph cleanup --retention` | Archive old/unqualified prompts per retention policy |
|
|
123
144
|
| `ph cleanup-reusability` | Cleanup by reusability score |
|
|
124
145
|
| `ph star <id>` | Toggle bookmark |
|
|
125
|
-
| `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 |
|
|
126
148
|
| `ph import gemini|claude|opencode|codex` | Import from AI CLI history |
|
|
127
149
|
| `ph log --tool <name> ...` | Direct log (hook target) |
|
|
128
|
-
| `ph embed-all` | Generate embeddings for
|
|
150
|
+
| `ph embed-all` | Generate embeddings for prompts without vectors |
|
|
129
151
|
| `ph config get|set <key> <value>` | View/edit config |
|
|
130
152
|
| `ph vacuum` | Compact SQLite database |
|
|
131
153
|
| `ph memory-migrate` | Merge existing memories into project_summaries |
|
|
@@ -138,7 +160,6 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
138
160
|
### Search options
|
|
139
161
|
|
|
140
162
|
```
|
|
141
|
-
-i / --interactive Open in TUI browser
|
|
142
163
|
--tool <name> Filter by tool
|
|
143
164
|
--project <name> Filter by project
|
|
144
165
|
--language <lang> Filter by language
|
|
@@ -149,11 +170,12 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
149
170
|
--archive Search archived prompts
|
|
150
171
|
--since YYYY-MM-DD Start date
|
|
151
172
|
--until YYYY-MM-DD End date
|
|
152
|
-
--limit <n> Max results (default
|
|
173
|
+
--limit <n> Max results (default 5)
|
|
174
|
+
--all Search across all projects instead of the current project
|
|
153
175
|
--top Quality >= 8
|
|
154
176
|
--min-quality <n> Min quality (0-10)
|
|
155
177
|
--min-relevance <n> Min relevance (0-10)
|
|
156
|
-
--full Show full prompt text
|
|
178
|
+
--full Show full prompt and response text
|
|
157
179
|
```
|
|
158
180
|
|
|
159
181
|
### Context options
|
|
@@ -185,43 +207,13 @@ echo '{"tool":"claude","prompt":"hi","response":"hello"}' | ph log --stdin
|
|
|
185
207
|
|
|
186
208
|
---
|
|
187
209
|
|
|
188
|
-
## 5.
|
|
189
|
-
|
|
190
|
-
| Key | Action |
|
|
191
|
-
|-----|--------|
|
|
192
|
-
| `Up` / `Down`, `Page Up` / `Page Down` | Navigate list |
|
|
193
|
-
| `Tab` | Switch pane (wide mode) |
|
|
194
|
-
| `1`, `2`, `3` | Switch prompt/response/memory tab |
|
|
195
|
-
| `y` | Copy to clipboard |
|
|
196
|
-
| `s` | Toggle star |
|
|
197
|
-
| `e` | Edit metadata |
|
|
198
|
-
| `r` | Rerun prompt (edit before launch) |
|
|
199
|
-
| `Shift+C` | Chat mode: launch tool with project context |
|
|
200
|
-
| `x` | Delete entry |
|
|
201
|
-
| `/` | Search |
|
|
202
|
-
| `o` | Settings panel (toggle auto-analysis, view config) |
|
|
203
|
-
| `f` | Filter panel (flat list, Enter toggle, letter jump) |
|
|
204
|
-
| `c` | Clear all filters |
|
|
205
|
-
| `q` / `Escape` | Quit / back |
|
|
206
|
-
|
|
207
|
-
### TUI components
|
|
208
|
-
|
|
209
|
-
- **SearchBar** — always visible spotlight bar at top
|
|
210
|
-
- **FilterPanel** — flat scrollable list of filter options with counts `[N]`, toggle with Enter, jump by letter
|
|
211
|
-
- **SettingsView** — config viewer/editor (auto-analysis toggle, ollama URL/model, filters)
|
|
212
|
-
- **PreviewPane** — three tabs (prompt/response/memory). Memory tab shows project-level knowledge
|
|
213
|
-
- **ListEntry** — role marker, analysis status, star, Q/R badges, optional summary line
|
|
214
|
-
- **Footer** — context-sensitive hints (shows `C:chat` only when entry has project)
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
## 6. Project Memory System
|
|
210
|
+
## 5. Project Memory System
|
|
219
211
|
|
|
220
212
|
ph maintains two levels of per-project knowledge:
|
|
221
213
|
|
|
222
|
-
###
|
|
214
|
+
### 5a. `project_summaries` (curated, 1 row per project)
|
|
223
215
|
|
|
224
|
-
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.
|
|
225
217
|
|
|
226
218
|
```bash
|
|
227
219
|
# View accumulated project knowledge
|
|
@@ -231,9 +223,29 @@ ph context --project myproject
|
|
|
231
223
|
# get_project_summary(project: "myproject")
|
|
232
224
|
```
|
|
233
225
|
|
|
234
|
-
###
|
|
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
|
|
235
231
|
|
|
236
|
-
|
|
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.
|
|
245
|
+
|
|
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.
|
|
237
249
|
|
|
238
250
|
### Memory migration
|
|
239
251
|
|
|
@@ -245,7 +257,7 @@ ph memory-migrate # one-time: merge all memories into project_summaries
|
|
|
245
257
|
|
|
246
258
|
---
|
|
247
259
|
|
|
248
|
-
##
|
|
260
|
+
## 6. Retention & Archiving
|
|
249
261
|
|
|
250
262
|
Configurable auto-archiving to keep the database lean:
|
|
251
263
|
|
|
@@ -268,9 +280,9 @@ ph search --archive
|
|
|
268
280
|
|
|
269
281
|
---
|
|
270
282
|
|
|
271
|
-
##
|
|
283
|
+
## 7. Background Analysis
|
|
272
284
|
|
|
273
|
-
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.
|
|
274
286
|
|
|
275
287
|
```bash
|
|
276
288
|
ph config set background-analysis true
|
|
@@ -318,7 +330,7 @@ credentials. `ph models mlx-serve` marks entries `[loaded]` or `[unloaded]`.
|
|
|
318
330
|
|
|
319
331
|
---
|
|
320
332
|
|
|
321
|
-
##
|
|
333
|
+
## 8. MCP Server
|
|
322
334
|
|
|
323
335
|
ph exposes an MCP (Model Context Protocol) server over stdio for AI agents:
|
|
324
336
|
|
|
@@ -344,26 +356,30 @@ ph mcp
|
|
|
344
356
|
|
|
345
357
|
---
|
|
346
358
|
|
|
347
|
-
##
|
|
359
|
+
## 9. HTTP Server & Remote Sync
|
|
348
360
|
|
|
349
361
|
Share prompt history across machines:
|
|
350
362
|
|
|
351
363
|
```bash
|
|
352
|
-
#
|
|
353
|
-
ph
|
|
354
|
-
|
|
355
|
-
|
|
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"
|
|
356
372
|
ph config set remote-url http://server-ip:3001
|
|
357
|
-
ph remote push #
|
|
358
|
-
ph remote pull #
|
|
373
|
+
ph remote push # resumable ID-based sync
|
|
374
|
+
ph remote pull # resumable ID-based sync
|
|
359
375
|
ph remote status # show sync state
|
|
360
376
|
```
|
|
361
377
|
|
|
362
|
-
|
|
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.
|
|
363
379
|
|
|
364
380
|
---
|
|
365
381
|
|
|
366
|
-
##
|
|
382
|
+
## 10. Database
|
|
367
383
|
|
|
368
384
|
**Location:** `~/.prompt_history.db` (configurable via `ph config set db-path`)
|
|
369
385
|
|
|
@@ -384,12 +400,12 @@ Every `ph log` auto-pushes to remote if configured (fire-and-forget, never block
|
|
|
384
400
|
ph vacuum # compact DB
|
|
385
401
|
ph cleanup # remove short/trivial/duplicate prompts
|
|
386
402
|
ph cleanup --retention # archive per retention policy
|
|
387
|
-
ph embed-all #
|
|
403
|
+
ph embed-all # generate vectors for prompts without embeddings
|
|
388
404
|
```
|
|
389
405
|
|
|
390
406
|
---
|
|
391
407
|
|
|
392
|
-
##
|
|
408
|
+
## 11. Filter Pipeline
|
|
393
409
|
|
|
394
410
|
Before saving, ph filters out:
|
|
395
411
|
|
|
@@ -408,7 +424,7 @@ ph config set filter-min-relevance 3
|
|
|
408
424
|
|
|
409
425
|
---
|
|
410
426
|
|
|
411
|
-
##
|
|
427
|
+
## 12. Configuration (`~/.ph_config.json`)
|
|
412
428
|
|
|
413
429
|
| Key | Default | Description |
|
|
414
430
|
|-----|---------|-------------|
|
|
@@ -431,8 +447,8 @@ ph config set filter-min-relevance 3
|
|
|
431
447
|
| `retentionMinRelevance` | `3` | Archive prompts below this relevance |
|
|
432
448
|
| `remoteUrl` | — | Remote ph server URL (or `PH_REMOTE_URL` env) |
|
|
433
449
|
| `remoteApiKey` | — | Remote server API key |
|
|
434
|
-
| `remoteLastPush` | — |
|
|
435
|
-
| `remoteLastPull` | — |
|
|
450
|
+
| `remoteLastPush` | — | Global timestamp of last successful push |
|
|
451
|
+
| `remoteLastPull` | — | Global timestamp of last successful pull |
|
|
436
452
|
|
|
437
453
|
Provider API credentials are environment-only: `OPENROUTER_API_KEY` and
|
|
438
454
|
`MLX_SERVE_API_KEY` (`GLB_OMLX_API_KEY` is a fallback). They are not written to
|
|
@@ -440,7 +456,7 @@ Provider API credentials are environment-only: `OPENROUTER_API_KEY` and
|
|
|
440
456
|
|
|
441
457
|
---
|
|
442
458
|
|
|
443
|
-
##
|
|
459
|
+
## 13. Architecture
|
|
444
460
|
|
|
445
461
|
```
|
|
446
462
|
Hook/Import → ph log → prompts table (FTS5 indexed)
|
|
@@ -473,14 +489,13 @@ src/
|
|
|
473
489
|
filter/ # Capture-time filter pipeline
|
|
474
490
|
mcp/server.ts # MCP stdio server
|
|
475
491
|
server/index.ts # HTTP REST server (zero deps)
|
|
476
|
-
ui/ # React/Ink TUI, including extracted filter policy and panel
|
|
477
492
|
importer/ # Gemini/Claude/OpenCode/Codex history importers
|
|
478
493
|
hooks/ # Shell scripts and plugins for AI tools
|
|
479
494
|
```
|
|
480
495
|
|
|
481
496
|
---
|
|
482
497
|
|
|
483
|
-
##
|
|
498
|
+
## 14. Importing Existing History
|
|
484
499
|
|
|
485
500
|
```bash
|
|
486
501
|
# Import from Claude Code
|
|
@@ -504,7 +519,7 @@ ph import codex
|
|
|
504
519
|
|
|
505
520
|
---
|
|
506
521
|
|
|
507
|
-
##
|
|
522
|
+
## 15. Versioning and Releases
|
|
508
523
|
|
|
509
524
|
Use Conventional Commits to describe changes: `feat:` requests a minor release,
|
|
510
525
|
`fix:` requests a patch release, and `BREAKING CHANGE:` requests a major release.
|