shallok 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +72 -2
- package/dist/index.js +52324 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -4
- package/skills/astro-localization-and-translation-i18n/SKILL.md +164 -0
- package/skills/astro-localization-and-translation-i18n/references/astro-i18n.md +40 -0
- package/skills/astro-localization-and-translation-i18n/references/extraction.md +29 -0
- package/skills/astro-localization-and-translation-i18n/references/translation.md +45 -0
- package/skills/astro-localization-and-translation-i18n/references/versioning.md +57 -0
- package/skills/expo-localization-and-translation-i18n/SKILL.md +169 -0
- package/skills/expo-localization-and-translation-i18n/references/expo-localization.md +46 -0
- package/skills/expo-localization-and-translation-i18n/references/extraction.md +29 -0
- package/skills/expo-localization-and-translation-i18n/references/translation.md +45 -0
- package/skills/expo-localization-and-translation-i18n/references/versioning.md +57 -0
- package/skills/localization-and-translation-i18n/SKILL.md +173 -0
- package/skills/localization-and-translation-i18n/references/extraction.md +29 -0
- package/skills/localization-and-translation-i18n/references/frameworks.md +40 -0
- package/skills/localization-and-translation-i18n/references/translation.md +45 -0
- package/skills/localization-and-translation-i18n/references/versioning.md +57 -0
- package/skills/localize-app/SKILL.md +80 -0
- package/skills/localize-app/references/extraction.md +29 -0
- package/skills/localize-app/references/frameworks.md +25 -0
- package/skills/localize-app/references/translation.md +45 -0
- package/skills/localize-app/references/versioning.md +57 -0
- package/skills/nextjs-localization-and-translation-i18n/SKILL.md +166 -0
- package/skills/nextjs-localization-and-translation-i18n/references/extraction.md +29 -0
- package/skills/nextjs-localization-and-translation-i18n/references/next-intl.md +63 -0
- package/skills/nextjs-localization-and-translation-i18n/references/translation.md +45 -0
- package/skills/nextjs-localization-and-translation-i18n/references/versioning.md +57 -0
- package/skills/react-localization-and-translation-i18n/SKILL.md +266 -0
- package/skills/react-localization-and-translation-i18n/references/extraction.md +29 -0
- package/skills/react-localization-and-translation-i18n/references/react-i18next.md +47 -0
- package/skills/react-localization-and-translation-i18n/references/translation.md +45 -0
- package/skills/react-localization-and-translation-i18n/references/versioning.md +57 -0
package/package.json
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shallok",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI-Powered, Versioned Localization Tool for AI Coding Agents",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"shallok": "./dist/index.js",
|
|
9
|
+
"localize": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"skills",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/Hypermona/Shallok.git"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"i18n",
|
|
24
|
+
"localization",
|
|
25
|
+
"internationalization",
|
|
26
|
+
"translation",
|
|
27
|
+
"ai-agent",
|
|
28
|
+
"nextjs",
|
|
29
|
+
"react",
|
|
30
|
+
"expo",
|
|
31
|
+
"astro",
|
|
32
|
+
"ast"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup && node scripts/copy-skills.js",
|
|
42
|
+
"typecheck": "tsc --noEmit"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@shallok/core": "workspace:*",
|
|
46
|
+
"@shallok/framework-adapters": "workspace:*",
|
|
47
|
+
"@shallok/translation-providers": "workspace:*",
|
|
48
|
+
"chalk": "^5.4.1",
|
|
49
|
+
"commander": "^13.1.0",
|
|
50
|
+
"dotenv": "^16.4.7",
|
|
51
|
+
"ink": "^5.1.0",
|
|
52
|
+
"ora": "^8.2.0",
|
|
53
|
+
"react": "^18.3.1",
|
|
54
|
+
"zod": "^3.24.2"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^22.13.8",
|
|
58
|
+
"@types/react": "^18.3.18",
|
|
59
|
+
"tsup": "^9.0.0",
|
|
60
|
+
"typescript": "^5.7.3"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: astro-localization-and-translation-i18n
|
|
3
|
+
description: Astro-specific localization and translation workflow using astro:i18n and Shallok CLI (shallok). Covers static routing with [locale], Astro frontmatter useTranslations, client UI islands (React/Vue/Svelte), context enrichment, direct agent translation without external API keys, and validation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Astro Localization & Translation Skill (`astro:i18n`)
|
|
7
|
+
|
|
8
|
+
Use this skill when asked to add, configure, update, or audit localization in **Astro websites and web applications** (Static SSG, Hybrid, or SSR).
|
|
9
|
+
|
|
10
|
+
## Two Ways Developers Use Shallok
|
|
11
|
+
|
|
12
|
+
1. **Via CLI (`npx shallok init`)**: The developer runs `npx shallok init` in their project. Shallok initializes the catalogs, installs `shallok` into `devDependencies`, and adds this skill directly into `.agents/skills/` and `skills/`.
|
|
13
|
+
2. **Direct Skill Installation**: The developer installs or links this skill into their AI coding agent and directly asks: *"Add localization to this application"* or *"Translate into Kannada and Hindi"*.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Agent Step 0: Verify & Install Shallok CLI
|
|
18
|
+
|
|
19
|
+
**Before executing any localization commands, you (the AI Agent) MUST verify that `shallok` is available:**
|
|
20
|
+
|
|
21
|
+
1. Check `package.json` for `"shallok"` in `devDependencies` or run:
|
|
22
|
+
```bash
|
|
23
|
+
npx shallok --version
|
|
24
|
+
```
|
|
25
|
+
2. **If `shallok` is NOT installed, install it immediately** using the project's package manager:
|
|
26
|
+
- If `pnpm-lock.yaml` exists: `pnpm add -D shallok`
|
|
27
|
+
- If `yarn.lock` exists: `yarn add -D shallok`
|
|
28
|
+
- If `bun.lockb` / `bun.lock` exists: `bun add -d shallok`
|
|
29
|
+
- Otherwise: `npm install -D shallok`
|
|
30
|
+
*(Alternatively, run commands directly via `npx shallok <command>`)*
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Architecture & Agent Role
|
|
35
|
+
|
|
36
|
+
Shallok pairs a deterministic AST CLI (`shallok`) with **the AI Agent as the semantic translator and context enricher**:
|
|
37
|
+
|
|
38
|
+
1. **The CLI (`shallok`)** handles deterministic tasks:
|
|
39
|
+
- Scaffolds `src/i18n/utils.ts` integrating with `astro:i18n`.
|
|
40
|
+
- AST parses Astro templates and UI islands (`shallok extract`).
|
|
41
|
+
- Replaces user-facing strings with `{t('key')}` (`shallok extract --apply`).
|
|
42
|
+
- Maintains per-key versioning and SHA-256 content hashes in `localization_base/`.
|
|
43
|
+
- Compiles runtime message bundles to `messages/runtime/<locale>.json` (`shallok build`).
|
|
44
|
+
- Validates 0 missing keys, 0 stale versions, and 0 broken placeholders (`shallok validate`).
|
|
45
|
+
|
|
46
|
+
2. **The AI Agent (You)** provides semantic intelligence:
|
|
47
|
+
- **No external API keys required**: You generate natural, culturally authentic translations directly into target languages (e.g. Kannada, Hindi, Spanish, French, German).
|
|
48
|
+
- **Context Enrichment**: You inspect Astro `.astro` pages, layouts, markdown collections, and interactive islands to provide rich, descriptive `context` in `localization_base/` for each key.
|
|
49
|
+
- **Integrity**: You preserve all interpolation tokens (`{userName}`, `{count}`, `{amount}`) exactly as they appear in the source text.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 6-Phase Agent Workflow for Astro
|
|
54
|
+
|
|
55
|
+
### Phase A: Analyze
|
|
56
|
+
Inspect repository architecture without modifying files:
|
|
57
|
+
```bash
|
|
58
|
+
shallok analyze --json
|
|
59
|
+
```
|
|
60
|
+
- Verify framework is detected as `astro`.
|
|
61
|
+
- Check `astro.config.mjs` (or `.ts`) for existing `i18n` block.
|
|
62
|
+
- Identify page routing structure (`src/pages/`, `src/pages/[locale]/`).
|
|
63
|
+
- Identify interactive islands (React, Vue, Svelte, Solid components).
|
|
64
|
+
- Note user-requested target locales (e.g. `kn`, `hi`, `fr`, `es`).
|
|
65
|
+
- **Never edit files during Phase A.**
|
|
66
|
+
|
|
67
|
+
### Phase B: Plan and Review
|
|
68
|
+
Present a concise plan to the developer:
|
|
69
|
+
1. **Framework & Approach**: Astro with built-in `astro:i18n` and Shallok runtime translation helper (`src/i18n/utils.ts`).
|
|
70
|
+
2. **Locales**: Source locale (e.g. `en`) and target locales (e.g. `kn` Kannada, `hi` Hindi).
|
|
71
|
+
3. **Planned Scaffolding**:
|
|
72
|
+
- `localization.json` (Project manifest)
|
|
73
|
+
- `src/i18n/utils.ts` (Translation helper and locale type definitions)
|
|
74
|
+
- `astro.config.mjs` i18n configuration
|
|
75
|
+
- `localization_base/<source_locale>.json` & `metadata.json` (Canonical catalog & versions)
|
|
76
|
+
- `messages/<locale>.json` (Authoritative target catalogs)
|
|
77
|
+
- `messages/runtime/<locale>.json` (Compiled runtime message bundles)
|
|
78
|
+
4. **Routing Structure**:
|
|
79
|
+
- Localized routes under `src/pages/[locale]/...`
|
|
80
|
+
- Default locale route under `src/pages/` or prefixed.
|
|
81
|
+
5. Confirm with user before proceeding (or proceed if `--yes` / requested).
|
|
82
|
+
|
|
83
|
+
### Phase C: Initialize
|
|
84
|
+
Initialize configuration and Astro scaffolding:
|
|
85
|
+
```bash
|
|
86
|
+
shallok init --source en --locales kn,hi --framework astro --yes
|
|
87
|
+
```
|
|
88
|
+
This automatically creates:
|
|
89
|
+
- `localization.json`
|
|
90
|
+
- `src/i18n/utils.ts`
|
|
91
|
+
- Initial catalogs in `localization_base/` and `messages/`
|
|
92
|
+
- Installs `shallok` in `devDependencies` and copies skills
|
|
93
|
+
|
|
94
|
+
Ensure `astro.config.mjs` specifies the locales:
|
|
95
|
+
```javascript
|
|
96
|
+
import { defineConfig } from 'astro/config';
|
|
97
|
+
|
|
98
|
+
export default defineConfig({
|
|
99
|
+
i18n: {
|
|
100
|
+
defaultLocale: 'en',
|
|
101
|
+
locales: ['en', 'kn', 'hi'],
|
|
102
|
+
routing: {
|
|
103
|
+
prefixDefaultLocale: false,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Phase D: Extract & Enrich Context (AI-Driven)
|
|
110
|
+
1. **Preview proposed extraction**:
|
|
111
|
+
```bash
|
|
112
|
+
shallok extract --dry-run --json
|
|
113
|
+
```
|
|
114
|
+
2. **Extract strings to canonical catalog**:
|
|
115
|
+
```bash
|
|
116
|
+
shallok extract
|
|
117
|
+
```
|
|
118
|
+
This extracts text and expressions into `localization_base/en.json`.
|
|
119
|
+
|
|
120
|
+
3. **Enrich Context (Performed by AI Agent)**:
|
|
121
|
+
- Review `localization_base/en.json`.
|
|
122
|
+
- Inspect the `.astro` page or component where each key originates.
|
|
123
|
+
- Enrich `context` with semantic clarity (e.g. *"Landing page hero subtitle describing product mission"*).
|
|
124
|
+
- Use the CLI:
|
|
125
|
+
```bash
|
|
126
|
+
shallok context set <key> "<semantic_description>"
|
|
127
|
+
```
|
|
128
|
+
Or edit `"context"` directly in `localization_base/en.json`.
|
|
129
|
+
- **Preservation Guarantee**: Shallok's reconciliation algorithm strictly preserves your enriched context across all future extractions.
|
|
130
|
+
|
|
131
|
+
### Phase E: Translate (AI-Driven)
|
|
132
|
+
**No external API keys or LLM provider subscriptions are required.**
|
|
133
|
+
You, as the AI coding agent, generate the translations directly:
|
|
134
|
+
|
|
135
|
+
1. **Check translation status**:
|
|
136
|
+
```bash
|
|
137
|
+
shallok status --json
|
|
138
|
+
```
|
|
139
|
+
Identify keys in `messages/<locale>.json` marked with `status: "missing"` or `status: "stale"`.
|
|
140
|
+
|
|
141
|
+
2. **Generate Natural Translations**:
|
|
142
|
+
- Translate each string into culturally authentic target language (e.g. Kannada, Hindi).
|
|
143
|
+
- Use the source `content` and your enriched `context` for accurate terminology.
|
|
144
|
+
- **Strict Rule**: Preserve all interpolation tokens (`{count}`, `{name}`, `{date}`) exactly as formatted in the source text.
|
|
145
|
+
|
|
146
|
+
3. **Update Target Locale Catalogs**:
|
|
147
|
+
Write directly into `messages/<locale>.json` or use:
|
|
148
|
+
```bash
|
|
149
|
+
shallok entry set <locale> <key> "<translated_text>"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Phase F: Apply, Build & Validate
|
|
153
|
+
1. **Transform Astro source pages & components**:
|
|
154
|
+
```bash
|
|
155
|
+
shallok extract --apply
|
|
156
|
+
```
|
|
157
|
+
2. **Compile runtime message bundles**:
|
|
158
|
+
```bash
|
|
159
|
+
shallok build
|
|
160
|
+
```
|
|
161
|
+
3. **Validate catalog integrity**:
|
|
162
|
+
```bash
|
|
163
|
+
shallok validate
|
|
164
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Astro & astro:i18n Technical Reference
|
|
2
|
+
|
|
3
|
+
## Configuration Pattern
|
|
4
|
+
|
|
5
|
+
### 1. `astro.config.mjs`
|
|
6
|
+
```javascript
|
|
7
|
+
import { defineConfig } from 'astro/config';
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
i18n: {
|
|
11
|
+
defaultLocale: 'en',
|
|
12
|
+
locales: ['en', 'kn', 'hi'],
|
|
13
|
+
routing: {
|
|
14
|
+
prefixDefaultLocale: false,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. `src/i18n/utils.ts`
|
|
21
|
+
```typescript
|
|
22
|
+
export const defaultLocale = 'en';
|
|
23
|
+
export const locales = ['en', 'kn', 'hi'] as const;
|
|
24
|
+
|
|
25
|
+
export type Locale = (typeof locales)[number];
|
|
26
|
+
|
|
27
|
+
export async function useTranslations(locale: Locale) {
|
|
28
|
+
const messages = (await import(`../../messages/runtime/${locale}.json`)).default;
|
|
29
|
+
|
|
30
|
+
return function t(key: string): string {
|
|
31
|
+
return (messages as Record<string, string>)[key] || key;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Routing Conventions
|
|
37
|
+
- Root / Default Locale: `src/pages/index.astro`
|
|
38
|
+
- Subpath / Translated Locales: `src/pages/[locale]/index.astro`
|
|
39
|
+
- Current Locale Access: `Astro.currentLocale`
|
|
40
|
+
- Preferred Locale Detection: `Astro.preferredLocale`
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# AST Extraction Reference
|
|
2
|
+
|
|
3
|
+
## Extraction Strategy
|
|
4
|
+
Shallok uses Babel AST parsing (`@babel/parser` and `@babel/traverse`) with full JSX and TypeScript support to safely inspect and transform source files without regular expressions.
|
|
5
|
+
|
|
6
|
+
## What is Extracted
|
|
7
|
+
1. **JSX Text Nodes**:
|
|
8
|
+
- `<h1>Welcome</h1>` → `{t('home.welcome')}`
|
|
9
|
+
- `<button>Pay now</button>` → `<button>{t('checkout.pay_now')}</button>`
|
|
10
|
+
2. **User-Facing Attributes**:
|
|
11
|
+
- `placeholder="Enter your email"`
|
|
12
|
+
- `aria-label="Submit login form"`
|
|
13
|
+
- `title="Cart summary"`
|
|
14
|
+
- `alt="Product thumbnail"`
|
|
15
|
+
- `label="Password"`
|
|
16
|
+
3. **Conditional UI Expressions**:
|
|
17
|
+
- `{isMember ? 'VIP Member' : 'Guest User'}`
|
|
18
|
+
4. **Template Literals with Variables**:
|
|
19
|
+
- `Hello, ${name}!` → `Hello, {name}!` with variable preservation.
|
|
20
|
+
|
|
21
|
+
## What is Explicitly Ignored
|
|
22
|
+
- Technical attributes: `className`, `id`, `name`, `key`, `ref`, `type`, `href`, `src`, `data-testid`, `role`.
|
|
23
|
+
- Console and logger calls: `console.log(...)`, `console.error(...)`, `logger.debug(...)`.
|
|
24
|
+
- URLs, file paths, hex colors, CSS units.
|
|
25
|
+
- Non-user-facing strings, code constants, and symbols.
|
|
26
|
+
- Already localized calls: `t(...)`, `i18n.t(...)`.
|
|
27
|
+
|
|
28
|
+
## Dry-Run Mode
|
|
29
|
+
Always use `localize extract --dry-run` to preview keys and occurrences before committing changes to source files.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Translation Engine & Agent-Native Translation Reference
|
|
2
|
+
|
|
3
|
+
## Agent-Native Translation (Primary Workflow)
|
|
4
|
+
When using Shallok via an AI coding agent (e.g., in Claude, Cursor, Copilot, Antigravity):
|
|
5
|
+
- **No external API keys or LLM provider subscriptions are needed.**
|
|
6
|
+
- The AI agent itself generates accurate, natural translations for each target locale.
|
|
7
|
+
- The AI agent inspects `messages/<locale>.json` or runs `localize status --json` to identify entries with `status: "missing"` or `status: "stale"`.
|
|
8
|
+
- The AI agent writes the translated strings into `messages/<locale>.json` (or uses `localize entry set <locale> <key> "<translated_text>"`).
|
|
9
|
+
|
|
10
|
+
### Translation Schema
|
|
11
|
+
Each entry in `messages/<locale>.json` maintains:
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"checkout.pay_now": {
|
|
15
|
+
"value": "ಈಗ ಪಾವತಿಸಿ",
|
|
16
|
+
"source_version": 1,
|
|
17
|
+
"translated_at": "2026-10-19T14:00:00.000Z",
|
|
18
|
+
"status": "translated"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Supported Statuses
|
|
24
|
+
- `missing`: Key exists in canonical catalog but has no translation.
|
|
25
|
+
- `stale`: Key source version was incremented; old translation preserved for reference.
|
|
26
|
+
- `translated`: Translated and matching the current canonical `source_version`.
|
|
27
|
+
- `review_required`: Flagged for human review.
|
|
28
|
+
- `approved`: Formally approved translation.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Placeholder Preservation Rules
|
|
33
|
+
The AI agent must strictly preserve all interpolation placeholders in target translations:
|
|
34
|
+
- Source: `"Welcome back, {userName}! You have {itemCount} items in your cart."`
|
|
35
|
+
- Kannada: `"ಮರಳಿ ಸ್ವಾಗತ, {userName}! ನಿಮ್ಮ ಕಾರ್ಟ್ನಲ್ಲಿ {itemCount} ಐಟಂಗಳು ಇವೆ."`
|
|
36
|
+
- Hindi: `"वापसी पर स्वागत है, {userName}! आपके कार्ट में {itemCount} आइटम हैं।"`
|
|
37
|
+
|
|
38
|
+
If a translation drops a placeholder or introduces an invalid placeholder, `localize validate` will fail with an error.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## CLI-Based Translation (Optional / Fallback)
|
|
43
|
+
For automated pipelines or scripts running outside an interactive AI agent:
|
|
44
|
+
1. **Mock Provider (`mock`)**: Default provider with built-in dictionary for local development and CI testing.
|
|
45
|
+
2. **LLM Provider (`llm`)**: Calls OpenAI, Gemini, or Anthropic HTTP APIs when `TRANSLATION_API_KEY` is provided.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Per-Key Versioning & Context Reference
|
|
2
|
+
|
|
3
|
+
## Canonical Source Catalog (`localization_base/`)
|
|
4
|
+
The canonical catalog is the single source of truth for all active and obsolete keys, including their cryptographic content hashes and version counters.
|
|
5
|
+
|
|
6
|
+
### Structure of a Canonical Entry
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"checkout.pay_now": {
|
|
10
|
+
"key": "checkout.pay_now",
|
|
11
|
+
"content": "Pay now",
|
|
12
|
+
"context": "Primary action button on checkout screen to trigger payment modal",
|
|
13
|
+
"relative_file_path": "src/components/checkout.tsx",
|
|
14
|
+
"occurrences": [
|
|
15
|
+
{
|
|
16
|
+
"relative_file_path": "src/components/checkout.tsx",
|
|
17
|
+
"line": 42,
|
|
18
|
+
"column": 12
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"last_updated_at": "2026-10-19T10:00:00.000Z",
|
|
22
|
+
"key_version": 1,
|
|
23
|
+
"content_hash": "sha256:...",
|
|
24
|
+
"status": "active"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Context Enrichment by AI Agents
|
|
30
|
+
1. When strings are extracted via `localize extract`, the CLI provides baseline AST context (e.g. `JSX text in <button> (in App <button>)`).
|
|
31
|
+
2. The AI Agent analyzes the source code, component hierarchy, and user flow, and enriches the `context` with semantic clarity:
|
|
32
|
+
- CLI method: `localize context set <key> "<semantic_description>"`
|
|
33
|
+
- Direct edit: Update `"context"` in `localization_base/<source_locale>.json`.
|
|
34
|
+
3. **Preservation Guarantee**:
|
|
35
|
+
Shallok's reconciliation algorithm (`reconcileCanonicalCatalog`) checks if a key already has an enriched context. Unless the source code introduces an explicit inline comment (`{/* context: ... */}`), the AI agent's enriched context is **strictly preserved** across all future extractions and will not be overwritten by generic AST node descriptions.
|
|
36
|
+
|
|
37
|
+
## Reconciliation & Versioning Rules
|
|
38
|
+
1. **New Key**: Initialized at `key_version = 1`, `status = "active"`.
|
|
39
|
+
2. **Unchanged Content & Context**: `key_version` and `last_updated_at` remain unchanged.
|
|
40
|
+
3. **Modified Source Content**: `key_version` increments by 1; `last_updated_at` is updated.
|
|
41
|
+
4. **File Move / Occurrence Change**: Path and occurrence lines are updated; `key_version` does NOT increment.
|
|
42
|
+
5. **Key Removed from Source**: Marked `status = "obsolete"`; preserved in catalog for historical retention.
|
|
43
|
+
6. **Key Reintroduced**: Reactivated as `"active"`.
|
|
44
|
+
|
|
45
|
+
## Stale Detection in Locale Catalogs
|
|
46
|
+
In `messages/<locale>.json`, each entry records:
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"checkout.pay_now": {
|
|
50
|
+
"value": "ಈಗ ಪಾವತಿಸಿ",
|
|
51
|
+
"source_version": 1,
|
|
52
|
+
"translated_at": "2026-10-19T10:05:00.000Z",
|
|
53
|
+
"status": "translated"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
A translation is **stale** when `entry.source_version < canonicalEntry.key_version`. Stale entries retain their existing translated value for reference until the AI agent updates them.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: expo-localization-and-translation-i18n
|
|
3
|
+
description: Expo and React Native localization and translation workflow using expo-localization, i18next, and Shallok CLI (shallok). Covers device language detection via getLocales(), mobile Text/TextInput transformations, Metro-bundled runtime messages, context enrichment, direct agent translation without external API keys, and validation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Expo & React Native Localization Skill (`expo-localization` + `react-i18next`)
|
|
7
|
+
|
|
8
|
+
Use this skill when asked to add, configure, update, or audit localization in **Expo and React Native mobile applications** (Expo Router, React Navigation, bare React Native).
|
|
9
|
+
|
|
10
|
+
## Two Ways Developers Use Shallok
|
|
11
|
+
|
|
12
|
+
1. **Via CLI (`npx shallok init`)**: The developer runs `npx shallok init` in their project. Shallok initializes the catalogs, installs `shallok` into `devDependencies`, and adds this skill directly into `.agents/skills/` and `skills/`.
|
|
13
|
+
2. **Direct Skill Installation**: The developer installs or links this skill into their AI coding agent and directly asks: *"Add localization to this application"* or *"Translate into Kannada and Hindi"*.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Agent Step 0: Verify & Install Shallok CLI
|
|
18
|
+
|
|
19
|
+
**Before executing any localization commands, you (the AI Agent) MUST verify that `shallok` is available:**
|
|
20
|
+
|
|
21
|
+
1. Check `package.json` for `"shallok"` in `devDependencies` or run:
|
|
22
|
+
```bash
|
|
23
|
+
npx shallok --version
|
|
24
|
+
```
|
|
25
|
+
2. **If `shallok` is NOT installed, install it immediately** using the project's package manager:
|
|
26
|
+
- If `pnpm-lock.yaml` exists: `pnpm add -D shallok`
|
|
27
|
+
- If `yarn.lock` exists: `yarn add -D shallok`
|
|
28
|
+
- If `bun.lockb` / `bun.lock` exists: `bun add -d shallok`
|
|
29
|
+
- Otherwise: `npm install -D shallok`
|
|
30
|
+
*(Alternatively, run commands directly via `npx shallok <command>`)*
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Architecture & Agent Role
|
|
35
|
+
|
|
36
|
+
Shallok pairs a deterministic AST CLI (`shallok`) with **the AI Agent as the semantic translator and context enricher**:
|
|
37
|
+
|
|
38
|
+
1. **The CLI (`shallok`)** handles deterministic tasks:
|
|
39
|
+
- Scaffolds `i18n.ts` configuring `expo-localization` and `i18next`.
|
|
40
|
+
- AST parses mobile React Native components (`shallok extract`).
|
|
41
|
+
- Replaces user-facing strings in `<Text>`, `<TextInput>`, and props with `{t('key')}` (`shallok extract --apply`).
|
|
42
|
+
- Maintains per-key versioning and SHA-256 content hashes in `localization_base/`.
|
|
43
|
+
- Compiles static runtime message bundles to `messages/runtime/<locale>.json` for Metro bundling (`shallok build`).
|
|
44
|
+
- Validates 0 missing keys, 0 stale versions, and 0 broken placeholders (`shallok validate`).
|
|
45
|
+
|
|
46
|
+
2. **The AI Agent (You)** provides semantic intelligence:
|
|
47
|
+
- **No external API keys required**: You generate natural, culturally authentic mobile translations directly into target languages (e.g. Kannada, Hindi, Spanish, French, German).
|
|
48
|
+
- **Context Enrichment**: You inspect mobile screens, modals, navigation stacks, and touch targets to provide rich, descriptive `context` in `localization_base/` for each key.
|
|
49
|
+
- **Integrity**: You preserve all interpolation tokens (`{userName}`, `{count}`, `{amount}`) exactly as they appear in the source text.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 6-Phase Agent Workflow for Expo
|
|
54
|
+
|
|
55
|
+
### Phase A: Analyze
|
|
56
|
+
Inspect repository architecture without modifying files:
|
|
57
|
+
```bash
|
|
58
|
+
shallok analyze --json
|
|
59
|
+
```
|
|
60
|
+
- Verify framework is detected as `expo` (or `react-native`).
|
|
61
|
+
- Inspect `package.json` for Expo SDK version and navigation library (Expo Router `expo-router` or `@react-navigation`).
|
|
62
|
+
- Identify mobile entry point (`App.tsx`, `index.js`, or `app/_layout.tsx`).
|
|
63
|
+
- Identify candidate screen and component files (`src/**/*.tsx`, `app/**/*.tsx`, `components/**/*.tsx`).
|
|
64
|
+
- Note user-requested target locales (e.g. `kn`, `hi`, `fr`, `es`).
|
|
65
|
+
- **Never edit files during Phase A.**
|
|
66
|
+
|
|
67
|
+
### Phase B: Plan and Review
|
|
68
|
+
Present a concise plan to the developer:
|
|
69
|
+
1. **Framework & Libraries**: Expo / React Native with `expo-localization`, `i18next`, and `react-i18next`.
|
|
70
|
+
2. **Locales**: Source locale (e.g. `en`) and target locales (e.g. `kn` Kannada, `hi` Hindi).
|
|
71
|
+
3. **Dependencies to Install**:
|
|
72
|
+
```bash
|
|
73
|
+
npx expo install expo-localization
|
|
74
|
+
pnpm add i18next react-i18next
|
|
75
|
+
```
|
|
76
|
+
4. **Planned Scaffolding**:
|
|
77
|
+
- `localization.json` (Project manifest)
|
|
78
|
+
- `i18n.ts` (Mobile i18n initialization at root)
|
|
79
|
+
- `localization_base/<source_locale>.json` & `metadata.json` (Canonical catalog & versions)
|
|
80
|
+
- `messages/<locale>.json` (Authoritative target catalogs)
|
|
81
|
+
- `messages/runtime/<locale>.json` (Static runtime bundles imported by Metro)
|
|
82
|
+
5. **Root Integration**: Adding `import './i18n';` in `App.tsx` or `app/_layout.tsx`.
|
|
83
|
+
6. Confirm with user before proceeding (or proceed if `--yes` / requested).
|
|
84
|
+
|
|
85
|
+
### Phase C: Initialize
|
|
86
|
+
Initialize configuration and Expo scaffolding:
|
|
87
|
+
```bash
|
|
88
|
+
shallok init --source en --locales kn,hi --framework expo --yes
|
|
89
|
+
```
|
|
90
|
+
This automatically creates:
|
|
91
|
+
- `localization.json`
|
|
92
|
+
- `i18n.ts` (with `getLocales()` device language detection)
|
|
93
|
+
- Initial catalogs in `localization_base/` and `messages/`
|
|
94
|
+
- Installs `shallok` in `devDependencies` and copies skills
|
|
95
|
+
|
|
96
|
+
Ensure mobile dependencies are installed:
|
|
97
|
+
```bash
|
|
98
|
+
npx expo install expo-localization
|
|
99
|
+
pnpm add i18next react-i18next
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Phase D: Extract & Enrich Context (AI-Driven)
|
|
103
|
+
1. **Preview proposed extraction**:
|
|
104
|
+
```bash
|
|
105
|
+
shallok extract --dry-run --json
|
|
106
|
+
```
|
|
107
|
+
2. **Extract strings to canonical catalog**:
|
|
108
|
+
```bash
|
|
109
|
+
shallok extract
|
|
110
|
+
```
|
|
111
|
+
This extracts text inside `<Text>`, `<Button title="...">`, and `<TextInput placeholder="...">` into `localization_base/en.json`.
|
|
112
|
+
|
|
113
|
+
3. **Enrich Context (Performed by AI Agent)**:
|
|
114
|
+
- Review `localization_base/en.json`.
|
|
115
|
+
- Inspect the mobile screen and component context.
|
|
116
|
+
- Enrich `context` with semantic clarity (e.g. *"Header label on Bluetooth pairing bottom sheet modal"*).
|
|
117
|
+
- Use the CLI:
|
|
118
|
+
```bash
|
|
119
|
+
shallok context set <key> "<semantic_description>"
|
|
120
|
+
```
|
|
121
|
+
Or edit `"context"` directly in `localization_base/en.json`.
|
|
122
|
+
- **Preservation Guarantee**: Shallok's reconciliation algorithm strictly preserves your enriched context across all future extractions.
|
|
123
|
+
|
|
124
|
+
### Phase E: Translate (AI-Driven)
|
|
125
|
+
**No external API keys or LLM provider subscriptions are required.**
|
|
126
|
+
You, as the AI coding agent, generate the translations directly:
|
|
127
|
+
|
|
128
|
+
1. **Check translation status**:
|
|
129
|
+
```bash
|
|
130
|
+
shallok status --json
|
|
131
|
+
```
|
|
132
|
+
Identify keys in `messages/<locale>.json` marked with `status: "missing"` or `status: "stale"`.
|
|
133
|
+
|
|
134
|
+
2. **Generate Natural Translations**:
|
|
135
|
+
- Translate each string into culturally authentic target language (e.g. Kannada, Hindi).
|
|
136
|
+
- Keep mobile screen space constraints in mind (e.g. concise button labels).
|
|
137
|
+
- Use the source `content` and your enriched `context` for accurate terminology.
|
|
138
|
+
- **Strict Rule**: Preserve all interpolation tokens (`{count}`, `{name}`, `{date}`) exactly as formatted in the source text.
|
|
139
|
+
|
|
140
|
+
3. **Update Target Locale Catalogs**:
|
|
141
|
+
Write directly into `messages/<locale>.json` or use:
|
|
142
|
+
```bash
|
|
143
|
+
shallok entry set <locale> <key> "<translated_text>"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Phase F: Apply, Build & Validate
|
|
147
|
+
1. **Transform React Native components**:
|
|
148
|
+
```bash
|
|
149
|
+
shallok extract --apply
|
|
150
|
+
```
|
|
151
|
+
This injects `const { t } = useTranslation();` and replaces hardcoded text with `{t('key')}`.
|
|
152
|
+
|
|
153
|
+
2. **Verify Root Entry Integration**:
|
|
154
|
+
Ensure `App.tsx` or `app/_layout.tsx` imports `i18n.ts`:
|
|
155
|
+
```tsx
|
|
156
|
+
import './i18n'; // <-- Must be at the top of the entry file
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
3. **Compile runtime message bundles**:
|
|
160
|
+
```bash
|
|
161
|
+
shallok build
|
|
162
|
+
```
|
|
163
|
+
Compiles static dictionaries into `messages/runtime/<locale>.json`.
|
|
164
|
+
|
|
165
|
+
4. **Validate catalog integrity**:
|
|
166
|
+
```bash
|
|
167
|
+
shallok validate
|
|
168
|
+
```
|
|
169
|
+
Verifies 0 missing translations, 0 stale versions, 0 dropped or mismatched placeholders.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Expo & React Native Technical Reference
|
|
2
|
+
|
|
3
|
+
## Configuration Pattern (`i18n.ts`)
|
|
4
|
+
React Native applications require static message loading because dynamic Node.js filesystem operations (`fs.readFile`) are not available in native runtimes.
|
|
5
|
+
|
|
6
|
+
```typescript
|
|
7
|
+
import i18n from 'i18next';
|
|
8
|
+
import { initReactI18next } from 'react-i18next';
|
|
9
|
+
import { getLocales } from 'expo-localization';
|
|
10
|
+
|
|
11
|
+
import enMessages from './messages/runtime/en.json';
|
|
12
|
+
import knMessages from './messages/runtime/kn.json';
|
|
13
|
+
import hiMessages from './messages/runtime/hi.json';
|
|
14
|
+
|
|
15
|
+
const resources = {
|
|
16
|
+
en: { translation: enMessages },
|
|
17
|
+
kn: { translation: knMessages },
|
|
18
|
+
hi: { translation: hiMessages },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const deviceLanguage = getLocales()[0]?.languageCode ?? 'en';
|
|
22
|
+
|
|
23
|
+
i18n
|
|
24
|
+
.use(initReactI18next)
|
|
25
|
+
.init({
|
|
26
|
+
resources,
|
|
27
|
+
lng: deviceLanguage,
|
|
28
|
+
fallbackLng: 'en',
|
|
29
|
+
interpolation: {
|
|
30
|
+
escapeValue: false,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export default i18n;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## React Native Component Rules
|
|
38
|
+
1. **Text Nodes**:
|
|
39
|
+
Raw strings cannot exist outside `<Text>` in React Native.
|
|
40
|
+
- Correct: `<Text>{t('auth.title')}</Text>`
|
|
41
|
+
- Incorrect: `<div>{t('auth.title')}</div>`
|
|
42
|
+
2. **Prop Localizations**:
|
|
43
|
+
- `<TextInput placeholder={t('form.email')} />`
|
|
44
|
+
- `<Button title={t('actions.submit')} />`
|
|
45
|
+
3. **Alerts & Modals**:
|
|
46
|
+
- `Alert.alert(t('common.confirm'), t('dialog.delete_body'))`
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# AST Extraction Reference
|
|
2
|
+
|
|
3
|
+
## Extraction Strategy
|
|
4
|
+
Shallok uses Babel AST parsing (`@babel/parser` and `@babel/traverse`) with full JSX and TypeScript support to safely inspect and transform source files without regular expressions.
|
|
5
|
+
|
|
6
|
+
## What is Extracted
|
|
7
|
+
1. **JSX Text Nodes**:
|
|
8
|
+
- `<h1>Welcome</h1>` → `{t('home.welcome')}`
|
|
9
|
+
- `<button>Pay now</button>` → `<button>{t('checkout.pay_now')}</button>`
|
|
10
|
+
2. **User-Facing Attributes**:
|
|
11
|
+
- `placeholder="Enter your email"`
|
|
12
|
+
- `aria-label="Submit login form"`
|
|
13
|
+
- `title="Cart summary"`
|
|
14
|
+
- `alt="Product thumbnail"`
|
|
15
|
+
- `label="Password"`
|
|
16
|
+
3. **Conditional UI Expressions**:
|
|
17
|
+
- `{isMember ? 'VIP Member' : 'Guest User'}`
|
|
18
|
+
4. **Template Literals with Variables**:
|
|
19
|
+
- `Hello, ${name}!` → `Hello, {name}!` with variable preservation.
|
|
20
|
+
|
|
21
|
+
## What is Explicitly Ignored
|
|
22
|
+
- Technical attributes: `className`, `id`, `name`, `key`, `ref`, `type`, `href`, `src`, `data-testid`, `role`.
|
|
23
|
+
- Console and logger calls: `console.log(...)`, `console.error(...)`, `logger.debug(...)`.
|
|
24
|
+
- URLs, file paths, hex colors, CSS units.
|
|
25
|
+
- Non-user-facing strings, code constants, and symbols.
|
|
26
|
+
- Already localized calls: `t(...)`, `i18n.t(...)`.
|
|
27
|
+
|
|
28
|
+
## Dry-Run Mode
|
|
29
|
+
Always use `localize extract --dry-run` to preview keys and occurrences before committing changes to source files.
|