Docs
Generator
hlpd_generator reads an app's source, drives its UI and builds a help bundle: topics, Show me and Guide me walkthroughs with narration, captioned videos and an on-device search index.
Set up
cd generator
uv venv -p 3.12 .venv && VIRTUAL_ENV=.venv uv pip install -r requirements.txtSettings come from the environment, .env or ~/:
| Variable | Purpose |
|---|---|
LLM_BASE_URL, LLM_API_KEY, LLM_MODEL | The language model gateway that writes topics and scripts |
OPENROUTER_API_KEY | Narration audio. Or set GEMINI_API_KEY with HLPD_TTS_PROVIDER=gemini |
HLPD_IOS_SIMULATOR | The simulator used to record iOS walkthroughs |
HLPD_EMBEDDING_MODEL | The search embedding model, minishlab/ by default |
HLPD_API_URL | The hlpd API used by publish, https:/ by default |
The other HLPD_* settings are in hlpd_generator/.
Generate
.venv/bin/python -m hlpd_generator generate ~/Code/drink_ios --platform ios --out /tmp/hlpd/drinkStages run in order, and each skips work whose outputs already exist:
| Stage | What it does |
|---|---|
analyze | Builds a product model of the app from its source |
outline | Plans categories and topics, and which topics can have an in-app walkthrough |
docs | Writes each topic in Markdown |
enrich | Gives each topic more ways to be found, and held-out queries that measure search |
scripts | Writes a step script for each topic with a feasible walkthrough |
translate | Localises the help into the app's own locales |
narrate | Speaks each step's narration and converts it to AAC |
walkthrough | Compiles the steps into bounded, declarative in-app walkthroughs |
record | Runs each script through the platform driver and records the screen |
review | Checks narration against the recorded screen and corrects it |
render | Turns recordings into captioned videos with poster frames |
bundle | Assembles the bundle and checks it |
--stage <name> --forceredoes one stage.--only id,...limits per-topic work to the listed topics.--languages es,froverrides the translated locales.--gaps queries.jsonassigns unanswered user queries to topics.
Recording uses the iOS simulator and the HlpdDriver UI-test runner from the iOS SDK. The finished bundle is in <out>/.
Edit and reindex
After editing topics by hand, rebuild search, embeddings, suggestion thresholds and the manifest's files inventory:
.venv/bin/python -m hlpd_generator reindex /tmp/hlpd/drink/bundlePublish
HLPD_EMAIL=me@example.com HLPD_PASSWORD=... \
.venv/bin/python -m hlpd_generator publish /tmp/hlpd/drink/bundle --project brp_...publish validates the bundle, uploads it as a gzipped tar to POST / and prints the result. It uses the owner session in HLPD_TOKEN, or opens one with HLPD_EMAIL and HLPD_PASSWORD and closes it afterwards. --api URL overrides HLPD_API_URL, and --draft uploads without making the bundle live.
Bundle layout
HlpdBundle/
manifest.json
topics/<topic-id>.md
walkthroughs/<topic-id>.json declarative in-app walkthrough
audio/<topic-id>/<step-id>.m4a pre-generated AAC narration
videos/<topic-id>.mp4 rendered walkthrough video
videos/<topic-id>.vtt captions, one cue per step
images/<topic-id>/1.png video poster frame
search.json precomputed inverted index
embeddings/ static embedding model and chunk vectorsmanifest.json describes the product, categories and topics, and ends with a files inventory holding the SHA-256 and size of every other file. Validation requires the inventory to match the directory exactly, and over-the-air updates use it to fetch only the changed files. An abridged manifest:
{
"schema": 1,
"bundleId": "drink-ios",
"version": "2026.10.12-1",
"product": { "name": "Drink", "platform": "ios", "appBundleId": "uk.ph1l.drink", "appVersion": "1.4.0" },
"categories": [{ "id": "getting-started", "title": "Getting started", "order": 1 }],
"topics": [{
"id": "log-a-drink",
"title": "Log a drink",
"summary": "Record a glass of water from the home screen.",
"category": "getting-started",
"doc": "topics/log-a-drink.md",
"walkthrough": "walkthroughs/log-a-drink.json"
}],
"files": { "topics/log-a-drink.md": { "sha256": "9f2c…", "bytes": 812 } }
}