Agent's Guide to Wiki
Agent Guide: Updating BookStack Wiki Pages
This guide outlines how AI agents can directly query, read, edit, and update pages in the self-hosted BookStack Wiki (https://wiki.drheck.dev/).
1. Golden Rules for Agents
🚨 MANDATORY RULE: READ LIVE CONTENT FIRST BEFORE EDITING
NEVER generate or overwrite page content from memory or scratch without first reading the current live page and its latest revisions. Humans frequently make live edits in the BookStack browser interface between agent turns. Overwriting a page without reading its latest
markdownandpage_revisionsdestroys user contributions, custom links, code blocks, and embedded images.Every page update MUST follow this sequence:
- Fetch live markdown to a file via
/home/luke/bin/read-bookstack-page <page_id> <output_file>.- Query attached images from the
imagestable.- Incorporate existing content, user edits, and image tags into the updated document.
- Deploy changes with
/home/luke/bin/update-bookstack-page <page_id> <file_path>.- Pull down the live rendered page and verify HTML and KaTeX formula output via
/home/luke/bin/verify-bookstack-page <page_id_or_slug>.
🚨 MANDATORY RULE: PULL DOWN & VERIFY THE RENDERED PAGE & FORMULAS AFTER EVERY EDIT
Mathematical formulas (
$$...$$and$...$), signal chains (\longrightarrow), matrices, and TeX output are desired and encouraged across the wiki—but once an edit is made, you MUST pull down the live rendered page and check the output.Never assume a formula rendered properly just because the Markdown source looks right or
LENGTH(html)is non-zero in MariaDB. BookStack's server-side CommonMark parser transforms backslash-punctuation sequences before client-side KaTeX runs, and unquoted shell expansions can corrupt either the page source or the globalapp-custom-headKaTeX loader.After every wiki edit, you MUST:
- Run
/home/luke/bin/verify-bookstack-page <page_id_or_slug>(also executed automatically byupdate-bookstack-pageandcreate-bookstack-page), which pulls down the live rendered page over HTTPS (https://wiki.drheck.dev/books/<book>/page/<slug>) and validates:
- Every inline
<script>and the globalapp-custom-headKaTeX auto-render loader in<head>(vm.Scriptsyntax check + intact$$and$delimiter verification).- Every
$$...$$display formula and$...$inline formula in the rendered.page-contentDOM using real KaTeX0.16.11(katex.renderToStringwiththrowOnError: true, strict: 'error').- Zero unrendered TeX macros (
\text{...},\longrightarrow,\frac{...},\begin{...}), stray$$delimiters, CommonMark-stripped matrix row breaks (\\), CommonMark-stripped percent signs (\%), or accidental$prose collisions.- Inspect the live rendered HTML of the edited section via
curl -skL https://wiki.drheck.dev/books/<book_slug>/page/<page_slug>to confirm clean rendering.
🚨 ABSTRACT DATABASE-INTERNAL IDS FROM USER-FACING TEXT
Never include internal database IDs or object identifiers in user-facing page bodies, changelogs, or documentation summaries. Database IDs are internal implementation details strictly for CLI helper execution (
read-bookstack-page <id>,update-bookstack-page <id>). Humans navigate the wiki by title and URL slug. Always use human-readable titles, book names, and standard markdown hyperlinks (e.g.[Setup Detail](https://wiki.drheck.dev/books/setup-detail)), never raw numeric IDs.
🚨 DUAL STORAGE RULE (
markdownvshtml)BookStack stores page source in the
entity_page_datatable:
markdown: Source text loaded by BookStack when a page is opened in the browser editor.html: Rendered HTML displayed to public visitors on the website.Never update
htmlalone! Updatinghtmlalone causes the editor to load the outdatedmarkdowncolumn and wipe out HTML changes upon saving. Agents must update themarkdownsource via the official helper scripts.
2. Environment & Database Access
- Service Host:
ul(ul.drheck.dev) - Rootless Podman Container (Database):
bookstack_db(MariaDB, running underdocker-data,UID 1100) - Rootless Podman Container (Web/App):
bookstack(runs PHP-FPM as userabc) - Env File:
/data/docker/bookstack/.env - Database Name:
bookstackapp
Note on Execution Context: The helper utilities interact directly with local rootless Podman containers under
docker-data(UID 1100) onul(executingartisanas container userabcwithHOME=/configso root-owned cache/log files are never created). If the agent is running on another workstation, execute helper commands over SSH toulusing single-quoted outer SSH blocks or heredocs (ssh ul << 'EOF') so$and$$in LaTeX formulas are never expanded by the local shell.
3. Recommended Workflow & Utilities
Official CLI utilities in /home/luke/bin/ on host ul eliminate shell quoting bugs, SQL newline escaping artifacts, and cache desync:
Step 1: Find Page ID or Book ID by Slug or Keyword
/home/luke/bin/find-bookstack-page <search_term>
Output:
id name slug type
31 System Change log system-change-log page
Step 2: Export Live Markdown to a File (MANDATORY)
Export the live markdown directly to a clean file using the base64-safe reader:
/home/luke/bin/read-bookstack-page <page_id> /tmp/page_<page_id>.md
(Do NOT use raw mariadb -e "SELECT markdown..." queries, as the MariaDB CLI client escapes newlines into literal \n strings).
Step 3: Check Attached Images & Revisions
Check image attachments:
(cd /tmp && sudo -u docker-data HOME=/home/docker-data XDG_RUNTIME_DIR=/run/user/1100 podman exec bookstack_db mariadb \
-ubookstack -p"$(sudo grep DB_PASSWORD /data/docker/bookstack/.env | cut -d= -f2)" \
bookstackapp -e "SELECT id, name, url FROM images WHERE uploaded_to=<page_id>;")
Step 4: Edit Content Locally in the File
Modify /tmp/page_<page_id>.md, ensuring that all existing user edits, links, and image references () are preserved.
Step 5: Update Existing Page or Create New Page
To update an existing page:
/home/luke/bin/update-bookstack-page <page_id> /tmp/page_<page_id>.md
To create a new page in a book:
/home/luke/bin/create-bookstack-page <book_id> "<page_title>" <file_path>
These helpers Base64-encode content, invoke BookStack's native PHP PageContent models inside Docker as user abc (artisan tinker), compile both markdown and html columns, update revision tracking, clear the application and view caches, and automatically run /home/luke/bin/verify-bookstack-page against the live rendered URL.
Remember to clean up your temporary file afterwards (rm -f /tmp/page_<page_id>.md).
4. Mandatory Rendered-Page & Formula Verification
After every page update or creation, verify the live rendered output over HTTPS using /home/luke/bin/verify-bookstack-page:
/home/luke/bin/verify-bookstack-page <page_id_or_slug_or_url>
Example Output:
Verified live rendered page: https://wiki.drheck.dev/books/system-setup/page/subocr-service
Title: subocr service | Math blocks verified: 2 display ($$...$$), 7 inline ($...$)
STATUS: PASS (0 script errors, 0 KaTeX errors, 0 unrendered TeX blocks)
Also inspect the rendered HTML of any modified formulas or sections directly from the live web server:
curl -skL https://wiki.drheck.dev/books/<book_slug>/page/<page_slug> | grep -C 3 "<search_term>"
Why Database Length Checks Are Insufficient: Checking only SELECT LENGTH(markdown), LENGTH(html) FROM entity_page_data does not detect CommonMark backslash stripping (such as \\ turned into \ or \% turned into a TeX comment %), Markdown <em> tags splitting a formula across DOM text nodes, or JavaScript syntax errors in app-custom-head. Always verify the live rendered page.
5. Advanced Features & Typography Standards for Agents
BookStack on ul is enhanced with rich typographical, mathematical, and layout capabilities. Agents are encouraged to leverage these features:
5.1 KaTeX TeX Mathematical Engine (Globally Enabled)
A client-side KaTeX (0.16.11) rendering engine is active across all wiki pages, paired with server-side KaTeX verification in /home/luke/bin/verify-bookstack-page.
- Display Equations (Block Math): Enclose in
$$ ... $$on their own lines with blank lines before and after:$$\text{FREQ} = \frac{433,920,000}{24,000,000} \times 2^{16} = 1,184,883 = \mathbf{0x121473}$$ - Inline Math: Enclose in single
$ ... $directly within sentences:$T_e = 291.27\text{ }\mu\text{s}$ - Signal Chains & Architecture Pipelines: Use
\longrightarrowwith\text{...}for hardware, DSP, and ML pipelines:$$\text{Video Frame } I(t) \longrightarrow \text{PP-OCRv5 (MIGraphX FP32)} \longrightarrow \text{Qwen2.5-32B (ROCm)} \longrightarrow \text{UniDic + JMdict/JLPT Study View}$$ - Matrix &
casesRow Breaks Require\\\\(Four Backslashes) or\crin Markdown: Because BookStack's server-side CommonMark parser unescapes\\into a single\before KaTeX runs, writing\\in Markdown produces\(a TeX space) in HTML and collapses multi-row matrices onto a single line. Always write\\\\(four backslashes) or\crin Markdown so the rendered HTML contains\\:$$\begin{pmatrix} y_1 \\\\ y_2 \end{pmatrix} = \begin{bmatrix} a_{11} & a_{12} \\\\ a_{21} & a_{22} \end{bmatrix} \begin{pmatrix} x_1 \\\\ x_2 \end{pmatrix}$$ - Percent Signs Inside Math Require
\\\%in Markdown: CommonMark unescapes\%into%in HTML. In TeX/KaTeX, an unescaped%is a comment character that swallows the%symbol and everything up to the closing$. Always write\\\%in Markdown (e.g.$\le 1\\%$) so the rendered HTML passes\%to KaTeX. - Subscript / Underscore Safety: Do not put multiple unescaped underscores on the same line in LaTeX (e.g.
\text{DRATE_M}...\text{DRATE_E}), as CommonMark will interpret them as Markdown italics (<em>...</em>) and split the DOM text node so KaTeX cannot match the closing$. Use hyphens (e.g.\text{DRATE-M}) or single subscripts (x_1). - No Backslash-Punctuation Spacing Macros (
\;,\,,\!): Never use backslash-punctuation spacing commands inside Markdown math blocks. CommonMark strips backslashes before ASCII punctuation characters prior to client-side KaTeX rendering, turning\;into a literal;and\,into a literal,. Always use alphabetic TeX spacing macros (\quad,\qquad,\text{ }) or rely on built-in relation spacing around\longrightarrow. - Wrap Shell/Nginx Variables & Multiple Currency Amounts Carefully: In prose outside code blocks, always wrap
$variablenames (e.g.`$host`,`$proxy_add_x_forwarded_for`) in backticks so KaTeX does not pair two$signs in the same paragraph as an inline math expression.
5.2 Native BookStack Callout Banners
Use BookStack's native HTML callout classes for colored, professional alert callouts:
<p class="callout info"><strong>Info Note:</strong> Background context and operational instructions.</p>
<p class="callout success"><strong>Success:</strong> Empirical tests verified with zero errors.</p>
<p class="callout warning"><strong>Warning:</strong> Ensure Word Clock is 75Ω terminated on the final device.</p>
<p class="callout danger"><strong>Danger / Critical:</strong> Never run recursive find commands on host ul.</p>
5.3 Japanese Typography & Furigana (Ruby Text)
HTML5 Ruby annotations are fully supported in page bodies:
- Whole-word Furigana:
<ruby>漢字<rt>かんじ</rt></ruby> - Per-character Furigana:
<ruby>振<rt>ふ</rt>り<rt></rt>仮<rt>が</rt>名<rt>な</rt></ruby> - Japanese in TeX Math:
$$\text{周波数 } f = 433.92\text{ MHz}$$
5.4 Collapsible Accordions (<details>)
Use collapsible details to tuck away long raw data logs, register dumps, or secondary tables:
<details>
<summary><strong>Click to expand technical registers</strong></summary>
<p>Detailed register addresses and bitfield descriptions go here.</p>
</details>
5.5 High-Resolution Gallery Images with Lightbox Links
To embed images stored in the BookStack gallery with centering, scaling, and lightbox popup support:
<p align="center">
<a href="https://wiki.drheck.dev/uploads/images/gallery/YYYY-MM/image-name.jpg" target="_blank">
<img src="https://wiki.drheck.dev/uploads/images/gallery/YYYY-MM/image-name.jpg" alt="Description" width="65%" style="border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); display: block; margin: 0 auto;">
</a>
<em style="display: block; text-align: center; margin-top: 6px; font-size: 0.9em; color: #666;">Figure 1: Descriptive caption.</em>
</p>
5.6 Comprehensive Capabilities Reference
For an exhaustive cheat sheet, math examples, and live test cases, refer to: 📖 Meta: Wiki Capabilities, TeX Math & Typography Reference
6. Critical Operational Gotchas for Agents
- Always Pull Down & Verify the Live Rendered Page: Run
/home/luke/bin/verify-bookstack-page <page_id_or_slug>after every edit to verify live HTTPS delivery,<script>syntax inapp-custom-head, and strict KaTeX compilation of every$$...$$and$...$formula. - Never Expose Internal Database IDs in Documentation: Do not write internal numeric book or page IDs in user-facing text, changelogs, or documentation summaries. Always use human-readable titles and standard hyperlinks.
- Never Parse SQL Output or Update
app-custom-headvia Double-Quoted Shell Strings: Double-quoted bash strings (ssh ul "..."ormariadb -e "...") strip single quotes and expand$$into the bash PID, which corrupts both LaTeX formulas and the globalapp-custom-headKaTeX loader. Always use/home/luke/bin/read-bookstack-page,/home/luke/bin/update-bookstack-page, or hex/base64-encoded payloads. - Strip Top-Level
# <Page Title>Headers: BookStack renders the page title as an<h1>header automatically. Strip# <Page Title>from markdown source to prevent duplicate headers. - Preserve Attached Images: Always check for image links before overwriting.
- Execute
artisanas Userabc(-u abc -e HOME=/config -w /app/www): Runningartisanasrootcreates root-owned cache/log files in/config/www/framework/cacheand/config/log/bookstack/laravel.log, causingphp-fpm(abc) to return HTTP 500 errors. - CommonMark Escaping Inside KaTeX: Use
\\\\(or\cr) for matrix/cases row breaks,\\\%for literal percent signs inside math, and\quad/\qquad/\text{ }instead of\;/\,/\!.