i18n

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: MIT Imports: 6 Imported by: 0

README

kite-mcp-i18n

Go Reference

Locale-aware string lookups for the algo2go ecosystem. Embeds JSON translation tables for English (en) and Hindi (hi); supports Accept-Language header parsing, context-bound locale propagation, and fallback to en for missing keys.

Used by Sundeepg98/kite-mcp-server for landing-page rendering, riskguard rejection messages, and OAuth flow strings.

Why a separate module?

Internationalization is an orthogonal cross-cutting primitive — usable by any algo2go project (broker dashboards, payment flows, monitoring UIs, future broker adapters) independent of kite-mcp-server. Hosting it in its own module:

  • Keeps translation contributions centralized (one repo to PR Hindi, Marathi, Tamil, etc.) instead of fragmenting per consumer
  • Lets the Locale type and Translate API version independently of the server
  • Reduces the dep-graph weight for consumers that only need locale resolution

Stability promise

v0.x — unstable. Method signatures may break between minor versions. Pin v0.1.0 deliberately. v1.0 ships only after the public API (Locale, T, TFromContext, WithLocale, LocaleFromContext, ParseAcceptLanguage, IsSupported, SupportedLocales) is reviewed for stability and at least one external consumer ships against it.

Install

go get github.com/algo2go/kite-mcp-i18n@v0.1.0

Public API (i18n.go)

  • type Locale string — newtype for IETF BCP 47 language tags (en, hi, ...)
  • T(loc Locale, key string) string — pure lookup, falls back to en
  • TFromContext(ctx, key) string — context-aware lookup
  • WithLocale(ctx, loc) context.Context / LocaleFromContext(ctx) Locale
  • ParseAcceptLanguage(header) Locale — best-match from HTTP header
  • IsSupported(loc) bool, SupportedLocales() []Locale
  • LocaleEN, LocaleHI constants

Translations

JSON files in locales/:

  • en.json — English (canonical)
  • hi.json — Hindi (Devanagari)

Keys are dot-namespaced (error.action.home, landing.cta.signin, ...). PRs welcome for additional Indian-subcontinent locales (Marathi, Tamil, Telugu, Bengali, etc.).

Reference consumer

Sundeepg98/kite-mcp-server — used by:

  • app/http.go for landing-page locale resolution + Accept-Language
  • kc/riskguard/middleware.go for localized rejection messages
  • OAuth + dashboard flows (via context propagation)

License

MIT — see LICENSE.

Authors

Original design + en/hi translations: Sundeepg98 (Zerodha Tech). Multi-module promotion (2026-05-09): algo2go contributors.

Documentation

Overview

Package i18n provides minimal locale-keyed string lookup for the Kite MCP user-facing surfaces (landing page, briefing templates, RiskGuard rejection messages, OAuth login screen).

Design constraints (per the internal-100 sprint Item 2 brief):

  • Leaf package — zero internal repo deps, so any package can import.
  • JSON-file translation source under locales/ — version-controlled, auditable, no external CMS dependency.
  • English fallback for missing keys (T(LocaleHI, k) returns en[k] when hi[k] is absent). Keeps the UI from rendering blank when a translator hasn't covered a string yet.
  • Unknown-key passthrough — T(loc, k) returns the literal key when neither locale has it, surfacing missing translations during dev and not crashing in prod.

Locale resolution at runtime:

  1. Explicit query / cookie / user-pref (set via WithLocale on ctx)
  2. Accept-Language header (ParseAcceptLanguage)
  3. Default LocaleEN

Initial Hindi coverage: 30 strings across landing/briefing/RiskGuard/ OAuth — the most-visible surfaces for an Indian retail trader.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsSupported

func IsSupported(loc Locale) bool

IsSupported reports whether the given locale string maps to a shipping translation set. Used by ParseAcceptLanguage and any cookie/ query-parameter validation.

func LoadError

func LoadError() error

LoadError returns any error encountered while loading translation files at init. Callers (test helpers, startup health checks) should treat a non-nil return as a hard failure.

func T

func T(loc Locale, key string) string

T returns the translated string for the given (locale, key) pair. Resolution order:

  1. translations[loc][key] if present and non-empty
  2. translations[en][key] (English fallback) if present and non-empty
  3. key itself (passthrough) so missing translations are visible

Args support is intentionally minimal: callers wanting interpolation should use the {placeholder} convention in the JSON value and strings.Replace at the call site, e.g.:

msg := i18n.T(loc, "briefing.morning.alerts_active")
msg = strings.Replace(msg, "{n}", strconv.Itoa(count), 1)

Avoiding fmt-style format-string interpolation here prevents the classic CWE-134 footgun and keeps translator-side templates free of Go-specific verbs.

func TFromContext

func TFromContext(ctx context.Context, key string) string

TFromContext is sugar for T(LocaleFromContext(ctx), key).

func WithLocale

func WithLocale(ctx context.Context, loc Locale) context.Context

WithLocale returns a child ctx carrying the given locale. Read by LocaleFromContext during T() lookups in handlers.

Types

type Locale

type Locale string

Locale identifies a translation set. The string value must match the JSON filename under locales/ and the standard IETF BCP-47 language tag for client header / cookie negotiation.

const (
	LocaleEN Locale = "en"
	LocaleHI Locale = "hi"
)

func LocaleFromContext

func LocaleFromContext(ctx context.Context) Locale

LocaleFromContext extracts the request-scoped locale, defaulting to LocaleEN when ctx has no locale value (e.g., default Go context, non-HTTP code paths).

func ParseAcceptLanguage

func ParseAcceptLanguage(header string) Locale

ParseAcceptLanguage extracts the highest-q-value supported locale from a browser-style Accept-Language header. Returns LocaleEN for an empty header or a header containing only unsupported locales.

Spec compliance is partial — we honor q-values and exact / language tag matches but skip the long tail of fallback chains. For our 2-locale ship-set this is sufficient; expand later if we add a 3rd / 4th locale.

Examples:

"hi-IN,hi;q=0.9,en;q=0.8"  -> hi  (hi has higher implicit q=1)
"en-US,en;q=0.9"           -> en
"fr-FR,fr;q=0.9"           -> en  (no fr translation; en fallback)
"en-IN,hi;q=0.5"           -> en  (en has higher q)
""                         -> en  (empty header; default)

func SupportedLocales

func SupportedLocales() []Locale

SupportedLocales returns a copy of the supported-locale list. Callers (Accept-Language parser, Locale picker UI) should iterate this rather than hard-coding the set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL