Context
Following 2026-07-14 architectural simplification (docs/01-PRODUCT.md §2.12 + docs/05-PLAN.md §"Migration Plan"), LLM enhancement moves out of phpMan into a standalone repo. Must serve multiple content sources, not just phpMan:
- phpMan: SQLite cache → MD files → enhanced MD
- myblog: MySQL (Movable Type) → MD files → enhanced MD
- future: filesystem, HTTP API, etc.
Goal
llm_enhance repo with source-agnostic abstraction. Same LLM transforms + task manager serves all projects.
Key design (full spec docs/05-PLAN.md §1.2-1.5)
Three ABCs:
Source: yields Entry objects. Impls: MysqlExportSource (myblog), PhpmanCacheSource (phpMan), FilesystemSource, HttpApiSource.
Transform: Entry → enhanced Entry. Versioned (e.g. emoji@v2). Impls: EmojiTransform, OkfTransform, TranslationTransform.
Sink: persists results. Impls: FilesystemSink, SqliteSink (phpMan compat), HttpApiSink.
Plus:
TaskManager: SQLite-backed queue, resume, rate limiting, cost tracking
LLMClient: multi-provider (OpenAI-compat, Anthropic), retry, truncation detection
- Prompt loader: versioned prompts in
src/llm_enhance/prompts/
Migration source map (Phase B)
From phpMan.php → llm_enhance:
| From |
To |
enhanceManPage() |
transform/emoji.py:EmojiTransform.apply() |
callLLM() |
llm/client.py:LLMClient.call() |
cleanEmojiHtml() |
transform/emoji.py:post_process() |
cli/batch-enhance.php |
cli.py:run_command() |
| LLM config (5 keys) |
per-project YAML configs |
Deleted (only existed for LLM path):
formatMarkdownToHTML(), formatInlineMarkdown()
renderTocSidebar()
Steps (Phase A+B+C+D, ~3-4 weeks)
- W1: Create repo, pyproject.toml, src layout, ABCs + tests
- W2: Port
cli/batch-enhance.php → Python CLI (queue/resume/rate-limit)
- W2-3: Implement
MysqlExportSource for myblog MT 4.x/5.x schema
- W3: Implement
PhpmanCacheSource reading ~/.phpman/cache/db.sqlite
- Test:
llm_enhance run --config=myblog.yaml --limit=10 --dry-run and same for phpMan
Related
Context
Following 2026-07-14 architectural simplification (docs/01-PRODUCT.md §2.12 + docs/05-PLAN.md §"Migration Plan"), LLM enhancement moves out of phpMan into a standalone repo. Must serve multiple content sources, not just phpMan:
Goal
llm_enhancerepo with source-agnostic abstraction. Same LLM transforms + task manager serves all projects.Key design (full spec docs/05-PLAN.md §1.2-1.5)
Three ABCs:
Source: yieldsEntryobjects. Impls:MysqlExportSource(myblog),PhpmanCacheSource(phpMan),FilesystemSource,HttpApiSource.Transform: Entry → enhanced Entry. Versioned (e.g.emoji@v2). Impls:EmojiTransform,OkfTransform,TranslationTransform.Sink: persists results. Impls:FilesystemSink,SqliteSink(phpMan compat),HttpApiSink.Plus:
TaskManager: SQLite-backed queue, resume, rate limiting, cost trackingLLMClient: multi-provider (OpenAI-compat, Anthropic), retry, truncation detectionsrc/llm_enhance/prompts/Migration source map (Phase B)
From
phpMan.php→llm_enhance:enhanceManPage()transform/emoji.py:EmojiTransform.apply()callLLM()llm/client.py:LLMClient.call()cleanEmojiHtml()transform/emoji.py:post_process()cli/batch-enhance.phpcli.py:run_command()Deleted (only existed for LLM path):
formatMarkdownToHTML(),formatInlineMarkdown()renderTocSidebar()Steps (Phase A+B+C+D, ~3-4 weeks)
cli/batch-enhance.php→ Python CLI (queue/resume/rate-limit)MysqlExportSourcefor myblog MT 4.x/5.x schemaPhpmanCacheSourcereading~/.phpman/cache/db.sqlitellm_enhance run --config=myblog.yaml --limit=10 --dry-runand same for phpManRelated
docs/05-PLAN.md§1