This briefs an AI assistant working on the lazysite codebase itself - the processor, CGI scripts, and tools. For content, view, and configuration work, see the other briefings:
lazysite/
lazysite-processor.pl # main processor (CGI)
lazysite-auth.pl # built-in auth wrapper
plugins/form-handler.pl # form submission dispatch
plugins/form-smtp.pl # SMTP helper
lazysite-manager-api.pl # manager JSON API
plugins/payment-demo.pl # x402 payment demo helper
plugins/log.pl # shared log helper (optional)
install.sh # signpost to the `lazysite` verbs; installs nothing
tools/
lazysite-server.pl # dev server
lazysite-users.pl # user management CLI
lazysite-audit.pl # link audit
build-static.sh # static site build
starter/ # template files copied to docroot
lazysite.conf.example
lazysite/
manager/ # manager UI template + CSS (D013; internal)
layouts/ # operator-installed layouts + themes (D013)
forms/ # form config examples
templates/registries/ # sitemap, feeds and llms.txt templates
manager/ # manager UI pages
docs/ # documentation (this site)
[demo pages]
test-site/ # scratch docroot for manual testing
.md files must keep their entire tag
definition (opening < through closing >) on one line. The
markdown parser treats line breaks inside a tag as block
boundaries and can strip attributes, break nesting, or produce
HTML whose id/name attributes never reach the DOM. Same
rule for <div>, <input>, <form>, etc. TT template files
(.tt) are not affected - multi-line tags there pass through
untouched.
lazysite-processor.pl.md or .url file,
parses front matter, resolves TT variables, renders the view,
caches the HTML, and returns it.
lazysite-auth.plX-Remote-* headers, and hands off to the processor.
plugins/form-handler.plLazysite::Handlers - the same delivery the schedule calls.
plugins/form-smtp.pllazysite-manager-api.plplugins/payment-demo.pltools/lazysite-server.pltools/lazysite-users.plplugins/audit.plCGI scripts and tools that want to appear in the manager Plugins page
must support --describe. When invoked with that flag, they print a
JSON object to stdout and exit 0.
Required fields: id, name, description, version.
Optional fields: config_file, config_keys, config_schema,
handler_types, actions.
Schema example:
{
"id": "form-smtp",
"name": "Form SMTP",
"description": "SMTP connection settings for form email delivery",
"version": "1.1",
"config_file": "lazysite/forms/smtp.conf",
"config_schema": [
{ "key": "method", "label": "Send method", "type": "select",
"options": ["sendmail", "smtp"], "default": "sendmail" },
{ "key": "host", "label": "SMTP host", "type": "text",
"show_when": { "key": "method", "value": ["smtp"] } }
],
"actions": []
}
Types: text, email, number, select, boolean, path. Use
show_when to conditionally display a field based on another field's
value.
Every script declares:
my $LOG_COMPONENT = 'audit'; # or 'form-smtp', 'auth', etc.
And calls log_event:
log_event( $level, $context, $message, %extra );
$level: DEBUG, INFO, WARN, ERROR$context: request URI or other stable identifier, or -$message: short human-readable description%extra: key-value pairs for structured loggingLog level is read from LAZYSITE_LOG_LEVEL (env) or log_level in
lazysite.conf. Format is LAZYSITE_LOG_FORMAT (text or json) or
log_format. Output goes to lazysite/logs/LOG_COMPONENT.log when
writable, otherwise stderr.
Pages are cached as .html files alongside their source .md files.
/about serves about.html if newer than about.md..html is missing or stale, the processor regenerates it.index.md compiles to index.html. On the plain Hestia lazysite
template that file is served directly by Apache via DirectoryIndex;
the other shipped templates leave it out of the index list, so /
reaches the processor..html file.Pages with auth: or payment: are never cached to disk and always
set Cache-Control: no-store, private.
Start the dev server for local testing:
perl tools/lazysite-server.pl --docroot /path/to/docroot --port 8080
Flags:
--docroot PATH - site docroot--port N - listen port--log-level LEVEL - override log levelThe dev server auto-detects built-in auth when lazysite/auth/users
exists.
Standard rsync command for local dev to a deployed site, preserving runtime state on the destination:
rsync -av --delete \
--exclude='.git' \
--exclude='test-site' \
--exclude='starter/lazysite/auth/' \
--exclude='starter/lazysite/forms/contact.conf' \
--exclude='starter/lazysite/forms/handlers.conf' \
--exclude='starter/lazysite/forms/smtp.conf' \
--exclude='starter/lazysite/lazysite.conf' \
--exclude='starter/lazysite/nav.conf' \
--exclude='starter/lazysite/cache/' \
--exclude='starter/lazysite/logs/' \
/home/user/lazysite/ /srv/projects/lazysite/
test-site/ is a scratch docroot for manual testing. It is git-ignored
and can be rebuilt freely:
cp -r starter/* test-site/
perl tools/lazysite-server.pl --docroot $(pwd)/test-site --port 8080