Bring the in-app help you already have into HelpCCMS
Your tooltips, field help and error messages are already written. They are spread across files, and nobody has ever seen them as one list.
Importing is that list, made once.
Where the collecting happens
In your codebase, by your own tooling. HelpCCMS reads a JSON file; it does not read your repository, and nothing in the import is generated or rewritten. Your entries become topics, unchanged.
your codebase → a script or a coding agent → JSON → HelpCCMSMost of the work is in the middle step, and a coding agent is good at it: walk the source, find the tooltips, field help and error messages, and write out one entry each.
The shape
The file is a JSON array, and each help entry is an object in it:
[
{
"help_key": "settings.api-keys",
"title": "API keys",
"text": "An API key lets a script talk to Acme on your behalf. Create one key per script, so you can withdraw a single key without breaking everything else.",
"where": "Settings screen, next to the API key field",
"external_ref": "SettingsKeys.tsx"
}
]help_key is the address your product will ask for later, and title is what the topic
is called. text is the words as they read today.
where says where the question mark sits, in your own words. Write it while you have the
source open, because that is the only moment anyone knows it for free. You get it back at
the other end of the chain: it becomes a column on the delivery sheet, in front of whoever
wires the key into the code.
external_ref is a different thing and both can be present. It points back at where the
text came from, a source file or a ticket; where says where it goes.
Three more fields are optional. short_desc for a one-line summary, topic_type for what
kind of answer it is, and body_v2 when you have structure worth keeping instead of a
single paragraph.
A UI element is a different kind of entry, and it becomes a role instead of a topic:
{
"kind": "ui-control",
"name": "Save",
"role": "uicontrol",
"tooltip": "Writes your changes.",
"help_key": "ui.save",
"where": "Editor toolbar"
}Both kinds sit in the same array. Buttons, shortcuts and field names travel as ui-control
entries, everything explanatory travels as help entries. where works on both.
What the import forgives
The import does not insist on the exact spelling of the spec.
Most fields accept two names. key works where help_key does, current_text where
text does, type where topic_type does, where_used where where does. An unrecognised role falls back to uicontrol
instead of rejecting the file.
The wrapper is forgiving too. A bare array is what the examples above show, and
{ "items": [ ... ] } is accepted as well.
The limits
Up to 3,000 entries and about 3 MB. A product with two hundred screens, each with a handful of explanations, plus its error messages, lands somewhere near two thousand entries.
A file over the limit is refused. You never get half of it in.
Before anything changes
The first pass writes nothing. You see how many topics it would create, how many roles, and the first entries as they would land. Read that, then decide.
What you have afterwards
Everything in one place.
Scattered through source, a difference in wording is invisible. In one list it is obvious: the same button called three things, the same concept explained twice in different words, six sentences that all start with "Simply".
You do not have to fix any of it during the import. The important change is that you can now see it together and edit it together.