Repository navigation
Admin Guide
Everything below is in /admin.php. The panel is disabled entirely with ADMIN_ENABLED = false, and
every action is rate limited (ADMIN_RATE_LIMIT, default 10 attempts per 15 minutes per IP).
Until a password exists, only setup is offered. From localhost the new password alone is enough;
remotely you also type the one-time code from storage/logs/setup.log (0600). Passwords must be at
least 10 characters and are stored as ADMIN_PASSWORD_HASH. The plaintext ADMIN_PASSWORD key is
cleared on the next request.
- Full tree of the content root with a filter box, sizes and timestamps.
- New document / New folder — paths may include new folders, validated segment by segment.
-
New from template — five skeletons: blank, architecture decision (ADR), meeting notes,
how-to guide, reference page. Give a title, get
<dir>/<slug>.mdwith today's date filled in; an existing document of the same name is refused with409, and the new file opens in the editor. -
Upload .md — multi-file, drag & drop, target folder selectable. Admin uploads bypass the
reader-side
DISABLE_UPLOADgate and are audited. -
Upload image — png/jpg/gif/webp/avif, content-sniffed with
getimagesize; SVG is refused by design; collisions get safe names. - Rename/move — validated targets, refuses overwrites.
-
Delete — soft: files move to
storage/backups/trash/and can be restored.
Split-pane live preview that runs the real rendering engine, so the preview cannot disagree with
the published page. The toolbar inserts bold, italic, inline code, link, wikilink, bullet list, alert
block and table at the cursor (Ctrl/⌘+B and +I are wired too). Saves carry a sha256 and a
mismatch returns 409 instead of overwriting someone else's work. Word and reading-time counters,
image upload at the cursor, and a deep link per document (?page=editor&file=…).
Every save through the editor stores a revision (newest REVISIONS_MAX, default 20; identical
content is deduplicated by sha256). A restore writes through the normal save path and first stores a
(pre-restore) revision, so a restore is itself undoable. Disable with REVISIONS_ENABLED = false.
-
backup.createsnapshots the content root plus.md.ini, listed and downloadable in Backups & trash. - Restores need
ALLOW_RESTORE = trueand always write a…-pre-restoresnapshot first. - Trash entries and backups can be deleted permanently — that one is irreversible.
export.static writes a self-contained HTML bundle to storage/exports/: one file per document plus
all-documents.html, with a single embedded stylesheet and no JavaScript. The listing doubles as
index.html only when no document owns that name.
admin.php?action=health.run returns {ok, version, checks[]}: PHP version, extensions, storage
writability, config sanity, manifest state and more. The panel shows the same list on Security &
health. Also available: index stats and rebuild, link check (broken links, broken media, orphans),
log tail, audit trail of settings and content changes.
The panel edits .md.ini through settings.set with validation — an unknown key or a bad type is
reported per key instead of being written. settings.regenerate-key rotates API_KEY (the previous
key stops working immediately).
MD.Scribe 3.5.0 "Loom" · PHP 8.5 (verified on 8.5.12) · MIT · repository · releases