Add unit tests: callLLM/callLLMEndpoint semantics + cleanEmojiHtml XSS + tldr guard test_enhance.php (23 tests): - callLLM() empty config guard, callLLMEndpoint signature validation - cleanEmojiHtml(): XSS defense (script/style/meta/title stripping, event handler removal, javascript:/data: URI neutralization, DOCTYPE/html/head/body wrapper stripping, <h1>→<h2> downgrade) test_tldr_guard.php (4 tests): - GIT_DESCRIBE defined() guard fallback chain - Triple-fallback to 'unknown' pattern from tldr.php:109 Fix stale comment in format_html.php:71 (<span class="u"> → <u>) Co-Authored-By: Claude <noreply@taotoken.net>
v4.9.25: fix FTS5 duplicate entries — DELETE FROM search_fts instead of DROP+CREATE/RENAME FTS5 shadow tables survive DROP TABLE on this SQLite version, causing every index rebuild to append another full copy of all entries. Total row count grew from 13,851 to 83,006 over 6 rebuilds. DELETE FROM search_fts properly clears all content while keeping the virtual table structure intact. Also: rebuildSearchIndex() now only deletes mode='search' cache entries, preserving all page HTML caches. Co-Authored-By: AtomCode (deepseek-v4-flash) <noreply@atomgit.com>
v4.9.24: fix rebuildSearchIndex cache cleanup — DELETE WHERE mode='search', not format='search'
Search results are stored with mode='search' (format='html'), not
format='search'. The v4.9.23 fix targeted format IN ('search','json')
which never matched any rows, leaving stale search caches intact.
Co-Authored-By: AtomCode (deepseek-v4-flash) <noreply@atomgit.com>
v4.9.23: fix rebuildSearchIndex — only delete search caches, not all HTML page caches
rebuildSearchIndex() was wiping all HTML page caches (perldoc 3852→61,
info 2583→43, pydoc 568→3, ri 4335→1) on every index rebuild.
Individual page caches are NOT search-index-dependent and must be preserved.
Now only removes format=('search','json') and section='fts' entries.
Co-Authored-By: AtomCode (deepseek-v4-flash) <noreply@atomgit.com>
Fix undefined GIT_DESCRIBE in tldr.php:85 (CLI batch crash) Line 85 used GIT_DESCRIBE without defined() guard. CLI tools don't load phpMan.php, only src/config.php — GIT_DESCRIBE is only defined when phpMan.php is loaded. Use defensive fallback: GIT_DESCRIBE ? PHPMAN_VERSION ? 'unknown'. Co-Authored-By: Claude <noreply@taotoken.net>
v4.9.22: code review fixes — <u> revert, cleanup patterns, dead code removal, ETag logging, amp; consolidation, X-Forwarded-Proto - format_html.php: revert <span class="u"> back to <u>, re-add </u><u> and <u>_</u> cleanup patterns - source_info.php: remove unused $patterns/$placeholders arrays - source_pydoc.php, source_ri.php: remove empty if blocks - phpMan.php: add phpManLog() on ETag DB exception; consolidate amp; workaround - util.php: add getQueryParam() helper for amp; fallback; add X-Forwarded-Proto - README.md: document PHP 8.0+ requirement Closes #208 (partially), #209, #210, #211, #212, #214, #215 Co-Authored-By: AtomCode (deepseek-v4-flash) <noreply@atomgit.com>
Add start-enhance-all.sh — two-phase batch runner Phase 1: --cache-only pre-generates HTML+MD cache (fast, no rate limit) Phase 2: LLM emoji enhancement with configurable --rate-limit (default 60s) Each mode runs independently with separate PID files. Configure: bash start-enhance-all.sh [rate-limit-seconds] Co-Authored-By: Claude <noreply@taotoken.net>
v4.9.21: configurable --rate-limit, default 120→60s Add --rate-limit=<s> CLI option to batch-enhance.php for per-run rate control. Default reduced from 120s → 60s. Co-Authored-By: Claude <noreply@taotoken.net>
v4.9.20: tool detection at deploy, --cache-only mode, fallback-2 max_tokens fix - cli/detect-tools.php: new script — detects perldoc/pydoc3/ri/info on server - Makefile: runs detect-tools.php during deploy, writes tools_config.php - src/config.php: includes tools_config.php, falls back to all-available - src/web_footer.php: showForm() conditionally renders radio by PHPMAN_HAS_* - cli/batch-enhance.php: new --cache-only flag (HTML+MD cache, skip LLM) - start-enhance-all.sh: 3-phase workflow (reindex → cache warm → enhance) - src/enhance.php: fallback max_tokens capped at 32768 (was 128000, HTTP 400) - src/tldr.php: User-Agent PHPMAN_VERSION with defined() guard + config fallback Co-Authored-By: Claude <noreply@taotoken.net>
v4.9.19: add id to submit button for Chrome form field warning Co-Authored-By: Claude <noreply@taotoken.net>