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 viacurl -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
(e.g.Book 92,Page 100,page_id=31,image_id=45)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) - Docker Container (Database):
bookstack_db(MariaDB) - Docker 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 Docker containers on
ul(executingartisanas container userabcwithHOME=/configso root-owned cache/log files are never created). If the agent is running on anothernode (e.g.pikvm-studioorbmo95),workstation, execute helper commands over SSH toulusing single-quoted outer SSH blocks or heredocs (e.g.ssh ul)/home/luke/bin/find-bookstack-page<<<term>'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:
sudo docker exec bookstack_db mariadb \
-ubookstack -p"$(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 clearrun /home/luke/bin/verify-bookstack-page against the viewlive cache.rendered URL.
Remember to clean up your temporary file afterwards (rm -f /tmp/page_<page_id>.md).
4. Mandatory Rendered-Page & Formula Verification
VerifyAfter thatevery bothpage update or creation, verify the live rendered output over HTTPS using markdown/home/luke/bin/verify-bookstack-page and html lengths and contents match::
sudo/home/luke/bin/verify-bookstack-page docker<page_id_or_slug_or_url>
exec
Example mariadbOutput:
Verified -ubookstacklive -p"$(greprendered DB_PASSWORDpage: https:/data/docker/bookstack/.env/wiki.drheck.dev/books/system-setup/page/subocr-service
Title: subocr service | cutMath 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 -d=skL https://wiki.drheck.dev/books/<book_slug>/page/<page_slug> | grep -f2)C 3 "<search_term>"
\
Why -eDatabase "Length Checks Are Insufficient: Checking only SELECT page_id, LENGTH(markdown), LENGTH(html), LEFT(markdown, 150), LEFT(html, 150) FROM entity_page_dataWHEREdoes page_id=<page_id>not detect CommonMark backslash stripping (such as \ turned into G"\\ 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.pages, paired with server-side KaTeX verification in /home/luke/bin/verify-bookstack-page.
- Display Equations (Block Math): Enclose in
$$ ... $$on their ownlines: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 &
MatricesArchitecture Pipelines: Usestandard LaTeX macros like\longrightarrow,with\for hardware, DSP, and ML pipelines:begin{pmatrix}text{...}$$\text{Video Frame } I(t) \longrightarrow \text{PP-OCRv5 (MIGraphX FP32)} \longrightarrow \text{Qwen2.5-32B (ROCm)} \longrightarrow \text{UniDic + JMdict/JLPT Study View}$$
cases Row Breaks Require \\\\ (Four Backslashes) or \cr in 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 \cr in Markdown so the rendered HTML contains \\:
Percent Signs Inside Math Require$$\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}$$,
\begin{cases}...\end{cases}\%\int%% in HTML. In TeX/KaTeX, an unescaped % is a comment character that swallows the % symbol and everything up to the closing $. Always write \sum\\%$\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 x_1).
No Backslash-Punctuation Spacing Macros (\;, \,, \!): Never use backslash-punctuation spacing commands inside Markdown math blocks. \; 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 $variable names (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.
Bookinternal 92Page 100page_id=31page 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-head via Double-Quoted Shell Strings: Double-quoted bash strings (ssh ul "..." or mariadb -e "...") strip single quotes and expand $$ into the bash PID, which corrupts both LaTeX formulas and the global app-custom-head KaTeX loader. Always use /home/luke/bin/read-bookstack-page/home/luke/bin/update-bookstack-pagemariadb\n, \t\# <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.
artisan abc (-u abc -e HOME=/config -w /app/www): -w /app/wwwartisan root /config/www/framework/cache and /config/log/bookstack/laravel.log, causing php-fpm (abc) to return HTTP 500 errors.
\\\\ (or \cr) for matrix/cases row breaks, \\\% for literal percent signs inside math, and \quad/\qquad/\text{ } instead of \;\,\!\<punctuation>\quad\qquad