langPeanut

A multi-agent platform that finds hardcoded strings in real codebases, localizes them without breaking the code, keeps the result healthy over time, and optimizes it for local search — running on Gemini and Google Cloud.

The problem

Retrofitting localization onto an existing codebase is a chore nobody wants: hunt down hardcoded strings scattered across thousands of lines, hand-write locale catalogs (.arb, .json, .xcstrings, strings.xml), and rewrite source to call the right i18n API — without breaking JSX/widget trees, ICU plurals, or comments. Naive tools make it worse. Regex extractors and single-prompt LLMs routinely corrupt the code they're supposed to fix: deleted comments, mangled component trees, mistranslated {placeholders}. And once a codebase is localized, keeping it that way — catching drift, cleaning stale keys, making the translated copy actually rank in local search — is normally three separate tools nobody has time to run.

What it does

langPeanut treats localization as an AST boundary problem, not a translation problem, and builds outward from there into three cooperating agentic systems sharing one Go core and one on-disk project state — so anything one system does is immediately visible to the other two.

System A — the Localization Engine (8 agents)

A Supervisor Orchestrator runs an execution DAG with resumable session state and automatic pre-run snapshots:

  1. AST Scout Extractor — real tree-sitter grammars per platform (TSX/JSX, Dart, Swift, Kotlin) isolate UI string literals and auto-skip non-translatable code (console.log, routes, URLs, hex colors, regexes) using the actual syntax tree, not text patterns.
  2. Semantic Context & Disambiguation Agent — reads surrounding component hierarchy and sibling strings to disambiguate polysemous words (e.g. "Book" in a travel app → reserveFlightBtn, not readBookBtn).
  3. Deterministic AST Range Patch Engine — computes exact byte offsets to refactor source without rewriting untouched code; validates the in-memory AST before anything hits disk.
  4. Specialized Cultural Translator — translation-memory reuse across runs, strict ICU/plural/placeholder preservation, parallel per-language workers.
  5. 4-Tier Verification Critic — checks AST syntax, ICU variable parity, character-expansion/clipping risk, and cross-locale key parity; feeds structured diagnostics back for automatic self-correction before anything reaches a human.
  6. Autonomous Code Repair Agent — diffs post-refactor compiler diagnostics against a pre-flight baseline (so it only ever "blames" regressions it introduced), fixes deterministically where possible, escalates to a bounded LLM repair loop otherwise, and flags for human review rather than silently failing.
  7. Directive Agent — executes free-form instructions after localization (e.g. "add a language switcher to the navbar") via an outline-and-window strategy so it can safely operate on 10,000+ line files without reading them whole.
  8. Three standalone maintenance agents treat localization as ongoing upkeep, not a one-shot run: Doctor (0–100 project health score, --fix to bootstrap missing setup), Pruner (AST-scans real usage to safely delete dead translation keys), Persona Scout (zero-config brand-voice discovery from README/docs to keep tone and a do-not-translate glossary consistent).

The engine runs autonomously end to end — langPeanut run <repo> scans, filters, refactors, translates, verifies, and repairs on its own, landing at a human checkpoint or an opened PR, never a chat loop waiting on the next prompt. It also speaks TMX 1.4b / XLIFF 1.2, so translations round-trip with Crowdin, Phrase, or Lokalise instead of being locked in.

System B — the Central AI Copilot (19 tools)

langPeanut chat is a genuine agentic control plane, not a bolt-on chatbot. An LLM-driven planning step decides which of 19 registered tools to call — spanning localization (scan_repository, execute_localization, verify_translations...), SEO (seo_analyze_competitor, seo_weave_copy...), platform operations (manage_checkpoints, diagnose_system, prune_dead_keys...), and the cloud job queue (trigger_job, query_jobs) — with a deterministic keyword-based fallback so it still routes correctly with zero network access. Every tool delegates to the same already-verified deterministic agents the CLI calls directly — the LLM picks which tool runs, it never gets to invent a file mutation itself. Results render as structured cards (diffs, critic reports, cost breakdowns, checkpoint lists) in both the terminal and the web Studio.

System C — the SEO & Growth Studio (5 agents)

langPeanut seo is a second, fully independent pipeline that picks up where translation stops — a perfectly translated app is still invisible if the copy isn't optimized for how people actually search in that locale: SERP Scout (competitor discovery) → Keyword Intelligence (volume/intent scoring) → Semantic Copy Weaver (rewrites copy to weave in keywords while preserving every ICU variable) → SERP Simulator (mock search-result preview) → Growth Predictor Critic (projects CTR/traffic uplift). It reads and writes the exact same locale files System A produces — no export/import step between them. No commercial localization tool (Lokalise, Crowdin, Phrase) does this.

One platform, four surfaces

CLI, an interactive TUI, a zero-build web Studio (single Go binary, no Node/npm, ~40 REST endpoints, SSE-streamed chat), and — in the sibling langpeanut-cloud repo — a hosted GitHub App that clones repos into sandboxed, ephemeral Docker containers, runs the same pipeline, and opens a PR with a deterministically templated title/body (zero LLM spend on PR prose). Repair-agent failures become a needs-manual-review label and comment, never a blocked PR.

Zero-cost, zero-signup demo path: every read-only/refactor step runs on pure tree-sitter analysis with no network calls at all. Translation, chat, and SEO can use a frontier model, but without one configured they transparently fall back to a bundled 4-bit GGUF of Meta's NLLB-200 running locally via llama.cpp, or a local Ollama daemon — the entire platform is demoable offline, at $0.00, with no accounts.

Built on Gemini + Google Cloud

  • Geminigemini-3.7-flash, called through the official Google GenAI SDK (google.golang.org/genai), used narrowly for disambiguation and translation judgment calls — never to regenerate a whole file. That restraint is deliberate: linters and AST matchers reliably beat prompt engineering at catching things like leaked ICU placeholders, so the LLM is scoped to exactly the judgment calls a deterministic tool can't make.
  • Google Cloud Pub/Sub — durable, at-least-once delivery for inbound GitHub webhooks in the hosted bot: a topic/subscription pair decouples webhook receipt from job processing, so events survive deploys, restarts, and worker downtime instead of being dropped by a synchronous handler.
  • Deployed and exercised against a real production repository (pingroute-web, a Next.js 15/TypeScript codebase) on Google Cloud infrastructure — live dashboard and installable GitHub App available for judges to test against it directly.

Track

Taskmaster — this is a complete, autonomous workflow, not a chatbot. Given a messy, multi-step chore (finding, translating, and safely patching hardcoded strings across a real codebase, then keeping it healthy and search-optimized), the agent handles the details end to end with little to no hand-holding: scans, disambiguates, translates, patches, verifies, repairs, and proves the result compiles — then either checkpoints for human review or opens the PR itself.

Measured results

A 10-case adversarial benchmark (real JSX nesting, ICU plurals, ambiguous strings, comment-adjacent code) compares three approaches head-to-head: naive regex, a zero-shot LLM baseline, and the full pipeline. The pipeline reaches 100% AST compilation pass rate and 0% formatting drift; both baselines regress the code on multiple cases. Fully offline, reproducible in seconds with one command, at $0.00 — ./langPeanut benchmark.

Engineering judgment under real constraints

Beyond the benchmark, the build log documents real failure modes hit against production codebases and root-caused: apostrophes in JSX breaking naive syntax validators, Flutter ARB files misidentified as Dart source, translation-memory cache pollution, first-launch latency from a blocking network call. The recurring lesson across all three systems: never let an LLM regenerate a whole file — use it only for the narrow judgment call, and delegate every mutation to a deterministic, verifiable tool. That principle holds from the AST patch engine down to PR-body generation.

What's next

Provide optimization and support for other platforms.

for more in-depth demo - https://youtu.be/UzvCsmLUBIM Setup AI key before use

Built With

Share this project:

Updates