DocForge is a toolchain for maintaining a single source of truth for Background Geolocation SDK documentation across all platforms:
- Harvest JSDoc from the TypeScript API into a portable YAML docs database (
docs-db/*.yaml) - Translate code examples from TypeScript to Swift and Kotlin using Claude skills
- Verify translated examples compile against native SDKs
- Apply documentation to native source files (Swift, Kotlin)
- Python 3.13+ and uv
- Git (for the TypeScript source submodule)
# Clone with all submodules (TS types + native SDKs)
git clone --recurse-submodules <this-repo>
# Or if already cloned, initialize submodules
git submodule update --init --recursive
# Install Python dependencies
uv sync
# Install Claude skills
./install-skills.sh| Path | Repo | Purpose |
|---|---|---|
background-geolocation-types/ |
TypeScript API types | Source of JSDoc for harvesting |
native/location-manager-ios/ |
iOS SDK | Target for Swift doc application + verification |
native/location-manager-android/ |
Android SDK | Target for Kotlin doc application + verification |
harvest.py emits one YAML file per symbol, named after the doc id:
Foo.yamlFoo.bar.yaml
Each YAML entry looks like:
id: BackgroundGeolocation.onLocation
source_file: background-geolocation-types/src/core/api/BackgroundGeolocation.ts
signature: 'onLocation(cb: ...): Subscription;'
description: |-
Subscribe to location events.
@example example-1
examples:
example-1:
title: Example 1
code:
ts: |-
// ...
objc: |-
// ...Important conventions:
descriptionis markdown-ish and may contain example placeholders like@example example-1.examples.<key>.codeis a map of language → snippet (ts,objc,kotlin, …).- When applying, Docforge inserts the chosen language snippet at the placeholder location.
# Harvest from the default TypeScript root (background-geolocation-types/src)
uv run forge harvest --seed --out-dir docs-db
# Or harvest from a custom TypeScript root
uv run forge harvest --seed --source /path/to/your/types/src --out-dir docs-dbUseful options:
--source PATH— TypeScript source root to harvest (default:background-geolocation-types/src).--limit N— stop after writing N YAML files (debugging).--prune— delete YAML files in--out-dirthat were not generated in this run (keeps the db tidy).
To make it easy to reference symbols later, you can insert/update a doc-id marker at the top of each harvestable JSDoc block:
# Insert into the default TS root
uv run forge harvest --insert-doc-ids
# Or target a custom TS root
uv run forge harvest --insert-doc-ids --source /path/to/your/types/srcThis produces JSDoc blocks like:
/**
* <!-- doc-id: ActivityType -->
* iOS Activity Type used with {@link GeoConfig.activityType}.
*/
export const ActivityType = {
// ...
}Notes:
--insert-doc-idsskips blocks marked@internalor@hidden.- Some internal/hidden mixin-style interfaces may still have public member docs; Docforge can alias containers when harvesting (see code comments in
harvest.py).
# Dump normalized doc blocks from a file (paths are relative to --source)
uv run forge harvest --dump core/api/BackgroundGeolocation.ts --max-blocks 3
# Or with an explicit source root
uv run forge harvest --dump --source /path/to/your/types/src core/api/BackgroundGeolocation.ts --max-blocks 3
# Dump extracted description/examples summary
uv run forge harvest --dump-extracted core/api/BackgroundGeolocation.ts --max-blocks 3apply-docs.py walks a source tree, finds Objective‑C docblocks containing:
<!-- doc-id: Module.member -->…and replaces the surrounding /** ... */ block with the harvested description + examples.
Dry-run (no writes):
uv run forge apply --docs-db docs-db --root ../ios-sdk --ext .h --lang objc --dry-runWrite changes:
uv run forge apply --docs-db docs-db --root ../ios-sdk --ext .h --lang objc --writeExactly one of these behaviors is used:
--dry-run— compute changes and print a summary (no writes). (Default if no mode is specified.)--check— like--dry-run, but exits 1 if any changes would be made (useful for CI).--write— apply changes to disk.
--docs-db PATH(required): directory containing*.yamldocs.--root PATH(required): root of the source tree to scan.--ext .h(default:.h): comma-separated list of extensions to scan.--exclude-dirs a,b,c(optional): directory names to skip (defaults includePods,DerivedData,node_modules, etc.).--lang <key>(required): single example language to apply (eg.objc).--verbose: print per-file/per-id updates and full diffs.--strict: fail if a referenced doc-id is missing from the docs-db.
The YAML description can contain placeholders like:
@example example-1
When applying:
- The placeholder is replaced in-place with a rendered block:
@example <Title>- a fenced code block in your selected
--lang
If an example is referenced but missing:
// MISSING example example-1
// Filename: BackgroundGeolocation.onLocation.yamlIf the example exists, but not for the requested language:
// WARNING: No example block found for lang "objc" for example-1
// Filename: /absolute/path/to/docs-db/BackgroundGeolocation.onLocation.yamlapply-docs.py normalizes Objective‑C docblocks to the canonical style:
/**
* <!-- doc-id: BackgroundGeolocation.onLocation -->
* Subscribe to location events.
*
* @example Example 1
* ```objc
* // ...
* ```
*/This ensures consistent alignment and clean diffs, even if the original header used a compact /**\n* ... style.
uv run forge harvest --seed --out-dir docs-db --pruneThis extracts JSDoc from the TypeScript types submodule into docs-db/*.yaml with ts: code examples.
Using Claude skills (install with ./install-skills.sh):
/translate-docs-swift docs-db/*.yaml # adds swift: blocks
/translate-docs-kotlin docs-db/*.yaml # adds kotlin: blocks
After this step, each YAML file has ts:, swift:, and kotlin: code blocks.
/verify-docs-swift # compiles Swift examples against iOS SDK
/verify-docs-kotlin # compiles Kotlin examples against Android SDK
These skills generate test files and run the compiler, iteratively fixing any errors.
/apply-docs-swift docs-db/*.yaml # writes Swift doc comments to iOS source
/apply-docs-kotlin docs-db/*.yaml # writes KDoc comments to Android source
These skills read the YAML, find the matching symbol in native source code by name, and insert/replace doc comments.
Run standard doc generators in each native repo:
- iOS: DocC / Xcode documentation
- Android: Dokka
All skills live in skills/ and are symlinked to ~/.claude/skills/ via install-skills.sh.
| Skill | Purpose |
|---|---|
/translate-docs-swift |
Translate TS examples to Swift in YAML |
/translate-docs-kotlin |
Translate TS examples to Kotlin in YAML |
/verify-docs-swift |
Compile-check Swift examples against iOS SDK |
/verify-docs-kotlin |
Compile-check Kotlin examples against Android SDK |
/apply-docs-swift |
Apply YAML docs as /// comments in iOS Swift source |
/apply-docs-kotlin |
Apply YAML docs as /** */ KDoc in Android Kotlin source |
- Keep
docs-db/in version control — it’s the canonical single source of truth for all platforms. - Run
./install-skills.shafter cloning to set up Claude skills. - The YAML database accumulates all language examples in one place — no need to copy between repos.
MIT License
Copyright (c) 2026 Transistor Software
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.