shallok 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -2,72 +2,180 @@
2
2
 
3
3
  > AI-Powered, Versioned Localization Tool for Developers & AI Coding Agents.
4
4
 
5
- Shallok is a developer tool and AI agent skill system that enables developers and AI coding agents (Antigravity, Cursor, Claude Code, GitHub Copilot) to add, configure, extract, translate, and maintain localization across existing codebases.
5
+ [![npm version](https://img.shields.io/npm/v/shallok.svg)](https://www.npmjs.com/package/shallok)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ **Shallok** is a developer tool and AI agent skill system that enables developers and AI coding agents (Antigravity, Cursor, Claude Code, GitHub Copilot) to add, configure, extract, translate, and maintain localization across existing codebases with **AST-based transformations**, **deterministic per-key versioning**, and **agent-native incremental translations**.
9
+
10
+ ---
6
11
 
7
12
  ## Features
8
13
 
9
- - **AST-Based Extraction**: Deterministic AST parsing (Babel) safely extracts user-facing text and attributes into stable semantic keys.
10
14
  - **Agent-Native Translation**: **Zero external API keys required**. AI coding agents translate missing and stale keys directly with natural cultural fluency.
11
- - **AI-Enriched Semantic Context**: Context notes are enriched by AI agents and strictly preserved across extractions.
12
- - **Per-Key Versioning & Content Hashing**: SHA-256 content hashes detect source modifications and mark translations stale on a granular, per-key basis.
13
- - **Framework Adapters**:
15
+ - **AST-Based Code Transformations**: Parses TSX/JSX and TypeScript safely with Babel; replaces hardcoded strings with framework hook/function calls without fragile regexes.
16
+ - **Per-Key Versioning & SHA-256 Content Hashing**: Granular content hashing detects source modifications; changing one string increments only its version while preserving all other translations.
17
+ - **AI-Enriched Semantic Context**: Context notes are enriched by AI agents and developers, strictly preserved across extractions.
18
+ - **Framework Adapters**: First-class support for:
14
19
  - **React**: `react-i18next` with `src/i18n.ts`
15
- - **Next.js**: `next-intl` (App Router `routing.ts`, `request.ts`, `middleware.ts`)
20
+ - **Next.js**: `next-intl` (App Router `routing.ts`, `request.ts`, `middleware.ts` & Pages Router)
16
21
  - **Expo / React Native**: `expo-localization` + `i18next` with native device locale detection
17
- - **Astro**: `astro:i18n` with dynamic message compilation
22
+ - **Astro**: `astro:i18n` with dynamic message compilation and UI island support
23
+ - **Vue**: `vue-i18n` with Vue composition API setup
18
24
  - **Placeholder & Integrity Validation**: Validates 0 missing keys, 0 stale versions, and 0 corrupted placeholder tokens (`{count}`, `{name}`).
25
+ - **Interactive Ink Terminal UI**: Beautiful interactive console screens with automatic non-TTY and `--json` fallback for AI agent orchestration.
26
+ - **5 Pre-Packaged Agent Skills**: Tailored skills for general i18n, React, Next.js, Expo, and Astro.
19
27
 
20
28
  ---
21
29
 
22
- ## Quickstart
30
+ ## Two Ways to Use Shallok
31
+
32
+ ### 1. Developer CLI Quickstart (`npx shallok init`)
23
33
 
24
- ### 1. Developer CLI Quickstart
25
- Run in any React, Next.js, Expo, or Astro project:
34
+ Run in any React, Next.js, Expo, Astro, or Vue project:
26
35
  ```bash
27
36
  npx shallok init
28
37
  ```
29
38
  This command automatically:
30
39
  1. Analyzes project architecture, detected framework, and router.
31
- 2. Scaffolds `localization.json`, `localization_base/`, `messages/`, and framework files.
32
- 3. Installs `shallok` into `devDependencies` using your project's package manager.
33
- 4. Installs AI agent skills directly into `.agents/skills/` and `skills/`.
40
+ 2. Scaffolds `localization.json`, `localization_base/`, `messages/`, and framework runtime files.
41
+ 3. Installs `shallok` into `devDependencies` using your detected package manager (pnpm, npm, yarn, or bun).
42
+ 4. Installs AI agent skills directly into `.agents/skills/` and `skills/` so AI coding agents immediately recognize them.
34
43
 
35
44
  ### 2. Direct AI Agent Skill Usage
36
- Copy any of the skills from `skills/` into your AI agent's skills directory (e.g. `.agents/skills/`), then tell your agent:
45
+
46
+ Alternatively, install or copy any of the skills from `skills/` into your AI coding agent (e.g. `.agents/skills/` or Claude/Cursor/Copilot), then tell your agent:
37
47
  > *"Add localization to this application with Kannada and Hindi"*
38
48
 
39
- The agent automatically verifies `shallok` is present, installs it if needed, and executes the complete 6-phase localization workflow.
49
+ The AI agent will:
50
+ 1. Check if `shallok` CLI is present in the project.
51
+ 2. If not present, install `shallok` into `devDependencies` automatically.
52
+ 3. Execute the 6-phase staged workflow (**Analyze → Plan → Init → Extract & Enrich Context → Translate → Build & Validate**) with **0 external API keys required**.
40
53
 
41
54
  ---
42
55
 
43
- ## CLI Commands
56
+ ## CLI Commands Reference
57
+
58
+ > Run via your package runner (`npx shallok`, `pnpm shallok`) or global install (`npm i -g shallok`).
44
59
 
60
+ ### Project Setup & Analysis
45
61
  ```bash
46
- # Analyze project architecture
62
+ # Analyze repository architecture without modifying files
63
+ shallok analyze
47
64
  shallok analyze --json
48
65
 
49
66
  # Initialize configuration and framework files
67
+ shallok init
50
68
  shallok init --source en --locales kn,hi,fr --framework react --yes
69
+ ```
51
70
 
52
- # Extract strings and preview changes
71
+ ### Extraction & Code Transformation
72
+ ```bash
73
+ # Preview proposed keys and transformations without modifying files
53
74
  shallok extract --dry-run
75
+
76
+ # Reconcile canonical catalog without modifying source code
54
77
  shallok extract
55
78
 
56
- # Apply AST transformations to source code
79
+ # Apply AST transformations to source code (replaces hardcoded strings with t(...) calls)
57
80
  shallok extract --apply
81
+ ```
82
+
83
+ ### Translation & Context
84
+ ```bash
85
+ # Generate missing or stale translations
86
+ shallok translate
87
+ shallok translate --locale kn
88
+ shallok translate --force
58
89
 
59
- # Check localization status
90
+ # Update semantic context for a key in canonical catalog (preserved across future extractions)
91
+ shallok context set app.pay_now "Primary CTA button in checkout flow to trigger payment modal"
92
+
93
+ # Directly update a translated entry in a locale catalog
94
+ shallok entry set kn app.pay_now "ಈಗ ಪಾವತಿಸಿ"
95
+ ```
96
+
97
+ ### Health, Validation & Build
98
+ ```bash
99
+ # Check localization status & translation completeness
60
100
  shallok status
101
+ shallok status --json
61
102
 
62
- # Compile runtime message bundles
63
- shallok build
103
+ # Produce a full localization health report
104
+ shallok report
105
+ shallok report --json
64
106
 
65
- # Validate placeholder and catalog integrity
107
+ # Validate placeholder parity ({name}) and catalog integrity
66
108
  shallok validate
109
+
110
+ # Compile runtime-compatible message bundles
111
+ shallok build
112
+ shallok build --format nested
113
+ ```
114
+
115
+ ### Management & Automation
116
+ ```bash
117
+ # Add or remove target locales
118
+ shallok locale add de
119
+ shallok locale remove fr
120
+
121
+ # Rename a key across canonical catalog, locale catalogs, and source references
122
+ shallok key rename old.key auth.login
123
+
124
+ # Full end-to-end sync pipeline (extract, translate, build, and validate)
125
+ shallok sync --dry-run
126
+ shallok sync --yes
67
127
  ```
68
128
 
69
129
  ---
70
130
 
131
+ ## Manifest Schema: `localization.json`
132
+
133
+ Located at the root of the target project:
134
+ ```json
135
+ {
136
+ "schema_version": 1,
137
+ "localization_version": 1,
138
+ "source_locale": "en",
139
+ "supported_locales": ["en", "kn", "hi", "fr", "de"],
140
+ "framework": {
141
+ "name": "nextjs",
142
+ "router": "app",
143
+ "localization_library": "next-intl",
144
+ "library_version": null
145
+ },
146
+ "paths": {
147
+ "source_directories": ["src"],
148
+ "base_directory": "localization_base",
149
+ "translations_directory": "messages"
150
+ },
151
+ "key_strategy": "semantic",
152
+ "translation": {
153
+ "provider": "mock",
154
+ "model": null,
155
+ "batch_size": 25
156
+ },
157
+ "options": {
158
+ "include_accessibility_text": true,
159
+ "preserve_obsolete_keys": true,
160
+ "require_review_for_ambiguous_strings": true,
161
+ "require_review_for_stale_translations": true
162
+ }
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Agent Skills Included
169
+
170
+ Shallok ships with 5 tailored skills for AI coding agents:
171
+ - `skills/localization-and-translation-i18n/`: Framework-independent core workflow
172
+ - `skills/react-localization-and-translation-i18n/`: React (`react-i18next`)
173
+ - `skills/nextjs-localization-and-translation-i18n/`: Next.js (`next-intl`)
174
+ - `skills/expo-localization-and-translation-i18n/`: Expo & React Native (`expo-localization` + `i18next`)
175
+ - `skills/astro-localization-and-translation-i18n/`: Astro (`astro:i18n`)
176
+
177
+ ---
178
+
71
179
  ## License
72
180
 
73
- MIT © Shallok Contributors
181
+ MIT © [Shallok Contributors](https://github.com/Hypermona/Shallok)
package/dist/index.js CHANGED
@@ -51189,7 +51189,7 @@ async function extractCommand(options) {
51189
51189
  const storage = new CatalogStorage(cwd);
51190
51190
  const manifest = await storage.readManifest();
51191
51191
  if (!manifest) {
51192
- printer.error('No localization.json found. Run "localize init" first.');
51192
+ printer.error('No localization.json found. Run "shallok init" first.');
51193
51193
  process.exit(1);
51194
51194
  }
51195
51195
  const isDryRun = options.dryRun ?? false;
@@ -51647,7 +51647,7 @@ async function translateCommand(options) {
51647
51647
  const storage = new CatalogStorage(cwd);
51648
51648
  const manifest = await storage.readManifest();
51649
51649
  if (!manifest) {
51650
- printer.error('No localization.json found. Run "localize init" first.');
51650
+ printer.error('No localization.json found. Run "shallok init" first.');
51651
51651
  process.exit(1);
51652
51652
  }
51653
51653
  const canonical = await storage.readCanonicalCatalog(
@@ -51772,7 +51772,7 @@ async function statusCommand(options) {
51772
51772
  const storage = new CatalogStorage(cwd);
51773
51773
  const manifest = await storage.readManifest();
51774
51774
  if (!manifest) {
51775
- printer.error('No localization.json found. Run "localize init" first.');
51775
+ printer.error('No localization.json found. Run "shallok init" first.');
51776
51776
  process.exit(1);
51777
51777
  }
51778
51778
  const canonical = await storage.readCanonicalCatalog(
@@ -51816,7 +51816,7 @@ async function validateCommand(options) {
51816
51816
  const storage = new CatalogStorage(cwd);
51817
51817
  const manifest = await storage.readManifest();
51818
51818
  if (!manifest) {
51819
- printer.error('No localization.json found. Run "localize init" first.');
51819
+ printer.error('No localization.json found. Run "shallok init" first.');
51820
51820
  process.exit(1);
51821
51821
  }
51822
51822
  const canonical = await storage.readCanonicalCatalog(
@@ -51864,7 +51864,7 @@ async function buildCommand(options) {
51864
51864
  const storage = new CatalogStorage(cwd);
51865
51865
  const manifest = await storage.readManifest();
51866
51866
  if (!manifest) {
51867
- printer.error('No localization.json found. Run "localize init" first.');
51867
+ printer.error('No localization.json found. Run "shallok init" first.');
51868
51868
  process.exit(1);
51869
51869
  }
51870
51870
  const canonical = await storage.readCanonicalCatalog(
@@ -51908,7 +51908,7 @@ async function reportCommand(options) {
51908
51908
  const storage = new CatalogStorage(cwd);
51909
51909
  const manifest = await storage.readManifest();
51910
51910
  if (!manifest) {
51911
- printer.error('No localization.json found. Run "localize init" first.');
51911
+ printer.error('No localization.json found. Run "shallok init" first.');
51912
51912
  process.exit(1);
51913
51913
  }
51914
51914
  const canonical = await storage.readCanonicalCatalog(
@@ -51968,7 +51968,7 @@ async function localeAddCommand(locale, options) {
51968
51968
  const storage = new CatalogStorage(cwd);
51969
51969
  const manifest = await storage.readManifest();
51970
51970
  if (!manifest) {
51971
- printer.error('No localization.json found. Run "localize init" first.');
51971
+ printer.error('No localization.json found. Run "shallok init" first.');
51972
51972
  process.exit(1);
51973
51973
  }
51974
51974
  const cleanLocale = locale.trim().toLowerCase();
@@ -51997,7 +51997,7 @@ async function localeAddCommand(locale, options) {
51997
51997
  return;
51998
51998
  }
51999
51999
  printer.success(`Added locale "${cleanLocale}" to supported_locales.`);
52000
- printer.info(`Run "localize translate --locale ${cleanLocale}" to generate translations for this locale.`);
52000
+ printer.info(`Run "shallok translate --locale ${cleanLocale}" to generate translations for this locale.`);
52001
52001
  }
52002
52002
  async function localeRemoveCommand(locale, options) {
52003
52003
  const cwd = process.cwd();
@@ -52005,7 +52005,7 @@ async function localeRemoveCommand(locale, options) {
52005
52005
  const storage = new CatalogStorage(cwd);
52006
52006
  const manifest = await storage.readManifest();
52007
52007
  if (!manifest) {
52008
- printer.error('No localization.json found. Run "localize init" first.');
52008
+ printer.error('No localization.json found. Run "shallok init" first.');
52009
52009
  process.exit(1);
52010
52010
  }
52011
52011
  const cleanLocale = locale.trim().toLowerCase();
@@ -52060,7 +52060,7 @@ async function renameCommand(oldKey, newKey, options) {
52060
52060
  const storage = new CatalogStorage(cwd);
52061
52061
  const manifest = await storage.readManifest();
52062
52062
  if (!manifest) {
52063
- printer.error('No localization.json found. Run "localize init" first.');
52063
+ printer.error('No localization.json found. Run "shallok init" first.');
52064
52064
  process.exit(1);
52065
52065
  }
52066
52066
  const canonical = await storage.readCanonicalCatalog(
@@ -52120,7 +52120,7 @@ async function contextSetCommand(key, newContext, options) {
52120
52120
  const storage = new CatalogStorage(cwd);
52121
52121
  const manifest = await storage.readManifest();
52122
52122
  if (!manifest) {
52123
- printer.error('No localization.json found. Run "localize init" first.');
52123
+ printer.error('No localization.json found. Run "shallok init" first.');
52124
52124
  process.exit(1);
52125
52125
  }
52126
52126
  const canonical = await storage.readCanonicalCatalog(
@@ -52162,7 +52162,7 @@ async function entrySetCommand(locale, key, translatedValue, options) {
52162
52162
  const storage = new CatalogStorage(cwd);
52163
52163
  const manifest = await storage.readManifest();
52164
52164
  if (!manifest) {
52165
- printer.error('No localization.json found. Run "localize init" first.');
52165
+ printer.error('No localization.json found. Run "shallok init" first.');
52166
52166
  process.exit(1);
52167
52167
  }
52168
52168
  const cleanLocale = locale.trim().toLowerCase();
@@ -52208,7 +52208,7 @@ async function entrySetCommand(locale, key, translatedValue, options) {
52208
52208
 
52209
52209
  // src/index.ts
52210
52210
  var program = new Command();
52211
- program.name("shallok").description("Shallok: AI-Powered, Versioned Localization Tool").version("0.1.0").option("--json", "Output machine-readable JSON for AI agent orchestration");
52211
+ program.name("shallok").description("Shallok: AI-Powered, Versioned Localization Tool").version("0.1.3").option("--json", "Output machine-readable JSON for AI agent orchestration");
52212
52212
  program.command("analyze").description("Analyze the repository without modifying it").option("--json", "Output machine-readable JSON").action(async (options) => {
52213
52213
  const isJson = options.json || program.opts().json;
52214
52214
  await analyzeCommand({ json: isJson });