Skip to Content
Agentsi18nprune — project analysis (agent onboarding)

i18nprune — project analysis (agent onboarding)

This document gives coding agents a single map of the repository: what the product does, how code is layered, where to change behavior, and how work is sequenced. It is written as a stable onboarding guide; implementation details may evolve—verify with packages/cli/src/ and docs/commands/.


1. Product summary

i18nprune is a Node.js ≥ 18 CLI (TypeScript, ESM) that helps teams keep i18n JSON aligned with source code and translation workflows:

  • Correctness — Literal translation keys referenced in application source are checked against a source-of-truth locale JSON.
  • Shape alignment — Non-source locale files can be merged and pruned to match the source structure (with optional preserve rules).
  • Generation & fill — Machine translation for generate and fill via a pluggable translator (e.g. Google gtx client).
  • Quality & review — Reporting for parity, drift, and locale-vs-source comparisons.
  • SafetyCleanup of unused keys with optional ripgrep verification; confirmations for destructive operations where appropriate.
  • DX — Structured --json on supported commands, global verbosity (-q / -s), doctor diagnostics, languages catalog listing.

The CLI is published as @zamdevio/i18nprune; local development uses pnpm, tsx, and vitest.


2. Repository layout (high level)

PathRole
packages/cli/bin/cli.tsEntry point — Commander program, global flags, preAction (config resolution, RunOptions, banners), subcommand registration.
packages/cli/src/commands/<name>/Per-command orchestration — Thin layers calling core/ and utils/.
packages/cli/src/core/Domain logic — Context, JSON operations, extraction, languages, translator, progress, errors, dynamic keys.
packages/cli/src/config/Config loading — Resolve path, parse schema, defineConfig, init prompts.
packages/cli/src/types/TypeScript contracts — Config, context, commands, runtime, logger, etc.
packages/cli/src/utils/Shared utilities — Logger, ANSI/style, fs, rg, CLI helpers, report writer.
packages/cli/src/constants/CLI strings — Docs URLs, JSON-output allowlist, etc.
packages/cli/src/exports/Library entrypointsconfig, core for programmatic use.
docs/Nextra-source markdown — One README.md per topic; pnpm docs:sync copies to apps/docs/content/.
tests/Integration tests (e.g. CLI against fixture app).
tests/fixtures/sample-i18n-app/Sample project for manual and automated CLI checks.
apps/docs/Documentation site app — Next.js + Nextra (install deps inside apps/docs/ for dev).

Git hygiene: Maintainer phase ordering lives in docs/phases/README.md. docs/phases/ is tracked in git; apps/docs/scripts/sync-content.js skips copying it to the public Nextra site. Public direction stays in docs/roadmap/README.md.


3. Architecture (layers)

┌─────────────────────────────────────────────────────────┐ │ packages/cli/bin/cli.ts (Commander, global flags, preAction) │ └───────────────────────────┬───────────────────────────────┘ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ packages/cli/src/commands/* packages/cli/src/config/* packages/cli/src/argv/* │ │ │ └───────────┬───────┴───────────────────┘ packages/cli/src/core/context/ (resolveContext, paths, run, meta) ┌───────────────┼───────────────┐ ▼ ▼ ▼ packages/cli/src/core/json packages/cli/src/core/ packages/cli/src/core/ merge/prune extractor translator path scanner + progress packages/cli/src/utils/logger (policy: info / detail / primary / …)
  • Context bundles resolved config, absolute paths (sourceLocale, localesDir, srcRoot), run (json, quiet, silent), and meta (field provenance, warnings).
  • Commands stay thin: parse options → resolveContext() → domain calls → printCommandSummary / human summaries / finalizeReportFile when applicable.

4. CLI surface (commands)

InvocationPurpose
initCreate config file when missing.
configPrint resolved config and env snapshot (--json).
validateLiteral keys in src vs source JSON; dynamic key warnings.
syncMerge/prune locale JSON to source shape (--lang, --dry-run).
generateCreate/update target locale from source + MT.
fillRe-translate leaves still matching source (--lang including all / lists).
qualityParity / drift signals (policy-aware).
reviewLocale vs source reporting (--json).
cleanupRemove unused keys (rg safety, confirmations, --check-only).
languagesList catalog codes for generate / fill.
localeslist, edit, dynamic, delete subcommands.
reportHelp topic for global --report-file / --report-format.
doctorEnvironment diagnostics.
helpStyled help for any command.

Global flags (see packages/cli/bin/cli.ts): --config, --yes, --json, -q/-s, path overrides, --functions, --no-discovery, --report-file, --report-format.


5. Configuration

  • Format: i18nprune.config.ts / .mts / .jsnot raw JSON on disk for the main config (JSON example files may exist as stubs only).
  • Schema: Zod-validated (packages/cli/src/config/schema.ts) — source, localesDir, src, functions, optional sourceLocaleCode, policies, reportFormat.
  • Merging: defineConfig() in packages/cli/src/config/define.ts merges user partial with defaults.
  • Resolution: packages/cli/src/config/resolve/ discovers config path, handles duplicates, ensureConfig for init flows.

6. Core pipelines (by concern)

Validate

  • Scan srcRoot for translation calls (packages/cli/src/core/scanner), extract literal keys (packages/cli/src/core/extractor), compare to string leaves in source JSON (packages/cli/src/core/json/leaves).
  • Dynamic keys: packages/cli/src/core/extractor/dynamic/ (TS/JS provider, comment heuristics) + packages/cli/src/core/extractor/dynamic/orchestrate.ts — project scan, non-literal first arguments; reported separately from missing literals. See docs/dynamic/README.md.

Sync

  • mergeToTemplateShape / pruneToTemplateShape (packages/cli/src/core/json/) driven by source JSON as template.
  • parseSyncLangSelection (packages/cli/src/utils/cli/args.ts) — default all non-source locales, or explicit list / all.

Generate / fill

  • Translator from packages/cli/src/core/translator/init.ts; progress via packages/cli/src/core/progress/session.ts.
  • Fill loops locales when --lang is all or comma-separated; prompts use promptFillLanguageSelection for TTY.

Cleanup

  • Compute unused keys from source JSON vs usage in code; optional rg string checks; preserve policy; confirmation unless global --yes or non-interactive rules.

Reports

  • packages/cli/src/utils/report/index.tspushReportEntry, finalizeReportFile; formats json / text / csv; independent styling from interactive logger for file output.

7. Testing

  • Unit: Vitest beside modules (e.g. packages/cli/src/utils/cli/__tests__/args.test.ts, packages/cli/src/config/__tests__/).
  • Integration: tests/integration/cli.fixture.test.ts runs dist/cli.js against tests/fixtures/sample-i18n-app — requires pnpm run build first.
  • Policy: Run pnpm typecheck and pnpm test before large merges; agents should do the same (see docs/agents/rules.md).

8. Documentation & site

  • Authoritative prose lives under docs/; pnpm docs:sync mirrors into apps/docs/content/.
  • Per-command docs: docs/commands/<command>/README.md — should stay in lockstep with packages/cli/bin/cli.ts and packages/cli/src/commands/ (see docs/agents/git.md).
  • Behavior: docs/behavior/ — exit codes, JSON/long-run interaction.
  • Architecture: docs/architecture/ — ADRs, translator/progress, tree.

9. Extension points (planned or partial)

AreaIntent
Translator providersAdditional backends beside Google gtx; shared translateLeaf contract.
Dynamic scannerMore languages, comment stripping, per-file sites, locales dynamic richness.
PatchingOpt-in loader auto-patches (ADR 004); locales delete / locales edit hooks.
Report coverageExtend pushReportEntry / finalizeReportFile to all long-running commands.
Rich summariesAlign human footers (formatSectionTitle) across validate, review, quality, etc.

Treat these as roadmap-aligned work; confirm current code before implementing.


10. Conventions (short)

  • ESM — Imports use .js suffix in TypeScript paths aligned with tsconfig / tsup.
  • ErrorsI18nPruneError with codes; reportCliError sets exit code.
  • Logging — Never bypass canEmit gates; use logger with explicit RunOptions / ctx.run.
  • CLI — Non-interactive and --json must not prompt where commands declare machine output (packages/cli/src/constants/jsonoutput.ts).

11. First tasks for a new agent

  1. Read docs/agents/rules.md and docs/agents/git.md.
  2. Run pnpm install, pnpm typecheck, pnpm test, pnpm run build.
  3. Skim packages/cli/bin/cli.ts and one command (e.g. packages/cli/src/commands/validate/index.ts) end-to-end.
  4. Open docs/commands/README.md and the matching command doc.
  5. For feature work, follow the commit plan in docs/agents/git.md so history stays reviewable.