How to run the full OVOS Localize pipeline locally without deploying to GitHub.
uv pip install -e ".[dev]"Zero external dependencies — everything uses Python stdlib.
python scripts/generate_data.pyThis clones every repo in skills.txt into repos/ (shallow clone), scans locale directories, runs AST analysis and validation, then writes JSON to data/.
First run takes several minutes (cloning ~60 repos). Subsequent runs are faster (git pull only).
To test with fewer skills, create a temporary skills.txt:
# Back up the full list
cp skills.txt skills.txt.bak
# Test with just 2 skills
cat > skills.txt << 'EOF'
OpenVoiceOS/ovos-skill-hello-world
OpenVoiceOS/ovos-skill-weather
EOF
python scripts/generate_data.py
# Restore
mv skills.txt.bak skills.txtAfter running, data/ contains:
data/
├── repos.json # Skill index (all skills)
├── coverage.json # Language × skill coverage matrix
├── validation.json # Aggregated validation results
└── skills/
├── ovos-skill-hello-world.json
├── ovos-skill-weather.json
└── ...
python -m http.server 8000Open http://localhost:8000 in a browser.
| URL | What you see |
|---|---|
http://localhost:8000/#/ |
Dashboard — coverage heatmap, 53 skills × 40 languages |
http://localhost:8000/#/skill/ovos-skill-weather |
Skill detail — file list with per-language validation badges |
http://localhost:8000/#/skill/ovos-skill-weather/weather.intent/de-de |
Translation editor — source panel, editable textarea, context card |
The editor view has a "Submit as PR" button. The workflow:
- Click Sign in in the header
- Paste a GitHub Personal Access Token with
public_reposcope - Navigate to a file and language (e.g.
#/skill/ovos-skill-weather/weather.intent/de-de) - Edit the translation in the center textarea
- Click Submit as PR
What happens behind the scenes:
- Forks the skill repo to your GitHub account (idempotent)
- Creates a
translate/{lang}/{file}branch on your fork - Commits the edited file
- Opens a PR from your fork to the upstream
devbranch - Opens the PR in a new tab
The token is stored in localStorage only — never sent anywhere except the GitHub API.
Dashboard shows nothing / fetch errors in console:
- Verify
data/repos.jsonexists and is valid JSON:python -m json.tool data/repos.json > /dev/null - The server must run from the repo root (where
index.htmlanddata/both live)
"Submit as PR" fails with 404:
- Your token may lack
public_reposcope — regenerate it - The fork may not be ready yet — wait a few seconds and retry
"Edit on GitHub" links point to wrong branch:
generate_data.pydefaults todevbranch. TheRepoScanner.clone_or_pull()also defaults todev.
No data generation needed — the CLI works standalone:
# Text output
ovos-localize-cli --repo /path/to/ovos-skill-weather
# GitHub Actions annotation format (for CI)
ovos-localize-cli --repo /path/to/ovos-skill-weather --report-format github
# JSON output
ovos-localize-cli --repo /path/to/ovos-skill-weather --report-format jsonExit code: 0 = no errors, 1 = validation errors found.
uv run pytest test/ -vWith coverage:
uv run pytest test/ -v --cov=ovos_localize --cov-report=term-missingfrom ovos_localize.sync.github import RepoScanner
from ovos_localize.analyzers.context_builder import build_context_card
scanner = RepoScanner("./repos")
scan = scanner.full_sync("OpenVoiceOS", "ovos-skill-weather")
print(f"Skill: {scan.skill_class_name}")
print(f"Languages: {scan.languages}")
print(f"Files: {len(scan.locale_files)}")
for f in scan.locale_files:
if f.lang == "en-us":
card = build_context_card(f, scan.skill_analysis, scan.locale_files)
print(f"\n{f.base_name}.{f.file_type.value}: {card.file_type_label}")
if card.handler_method:
print(f" Handler: {card.handler_method}() at :{card.handler_line}")
if card.tips:
print(f" Tips: {card.tips[0]}")