langctl 0.1.1 → 0.2.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/README.md CHANGED
@@ -1,8 +1,34 @@
1
- # Langctl CLI
1
+ <div align="center">
2
2
 
3
- > CLI-first translation management for developers
3
+ # Langctl
4
4
 
5
- Langctl is a command-line tool that lets you manage translations directly from your terminal. Pull translations in multiple formats, sync with your projects, and integrate seamlessly into your CI/CD pipeline.
5
+ **CLI-first translation management for developers**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/langctl.svg)](https://www.npmjs.com/package/langctl)
8
+ [![license](https://img.shields.io/npm/l/langctl.svg)](https://github.com/siddharthsaxena0/langctl/blob/main/LICENSE)
9
+ [![npm downloads](https://img.shields.io/npm/dm/langctl.svg)](https://www.npmjs.com/package/langctl)
10
+
11
+ **[Website](https://langctl.com)** · **[Documentation](https://langctl.com/docs)** · **[Get Started](https://app.langctl.com/signup)**
12
+
13
+ <!-- Add a demo GIF here: -->
14
+ <!-- ![langctl demo](assets/demo.gif) -->
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ Langctl is a powerful command-line tool that lets you manage translations directly from your terminal. Create projects, manage translation keys, invite team members, export in multiple formats, and integrate seamlessly into your CI/CD pipeline.
21
+
22
+ ## Features
23
+
24
+ - 🚀 **Complete Project Management** - Create, update, and manage translation projects
25
+ - 🔑 **Translation Key CRUD** - Full control over translation keys and values
26
+ - 👥 **Team Management** - Invite members, manage roles, and handle invitations
27
+ - 📊 **Organization Insights** - View stats, plan limits, and usage metrics
28
+ - 📦 **Multi-Format Export** - Support for JSON, iOS, Android, Flutter, and i18n
29
+ - 🔄 **Import Translations** - Bulk import from JSON files
30
+ - 🤖 **CI/CD Ready** - Perfect for automated workflows
31
+ - 🌍 **Multi-Language Support** - Manage unlimited languages per project
6
32
 
7
33
  ## Installation
8
34
 
@@ -10,7 +36,7 @@ Langctl is a command-line tool that lets you manage translations directly from y
10
36
  npm install -g langctl
11
37
  ```
12
38
 
13
- Or use with npx:
39
+ Or use with npx (no installation required):
14
40
 
15
41
  ```bash
16
42
  npx langctl --help
@@ -18,178 +44,788 @@ npx langctl --help
18
44
 
19
45
  ## Quick Start
20
46
 
47
+ > **📌 First time here?** Check out our [Getting Started Guide](https://langctl.com/docs/getting-started/introduction) on the website for a complete walkthrough!
48
+
21
49
  ### 1. Get Your API Key
22
50
 
23
- Generate an API key from your Langctl dashboard:
24
- 1. Go to **Settings → API Keys**
25
- 2. Click **"Generate New Key"**
26
- 3. Copy the key (shown only once)
51
+ 1. Visit **[app.langctl.com](https://app.langctl.com/signup)** and create a free account
52
+ 2. Go to **Settings → API Keys**
53
+ 3. Click **"Generate New Key"**
54
+ 4. Copy the key (it's only shown once!)
55
+
56
+ > **💡 Tip:** Learn more about API keys and authentication at [langctl.com/docs/cli/authentication](https://langctl.com/docs/cli/authentication)
27
57
 
28
58
  ### 2. Authenticate
29
59
 
30
60
  ```bash
61
+ # Interactive setup
31
62
  langctl init
63
+
64
+ # Or authenticate directly
65
+ langctl auth lc_your_api_key_here
32
66
  ```
33
67
 
34
- This interactive wizard will:
35
- - Authenticate with your API key
36
- - Set your default language preference
68
+ ### 3. Explore Your Organization
37
69
 
38
- ### 3. List Your Projects
70
+ ```bash
71
+ # View organization info
72
+ langctl org info
39
73
 
40
- View all projects you have access to:
74
+ # Check statistics
75
+ langctl org stats
41
76
 
42
- ```bash
77
+ # List your projects
43
78
  langctl projects list
44
79
  ```
45
80
 
46
- ### 4. Pull Translations
47
-
48
- Download translations for a project:
81
+ ### 4. Start Working with Translations
49
82
 
50
83
  ```bash
51
- langctl pull <project-id> --language en --format json
84
+ # List translation keys
85
+ langctl keys list my-project
86
+
87
+ # Export translations
88
+ langctl export my-project --language en --format json
89
+
90
+ # Create a new key
91
+ langctl keys create my-project home.welcome \
92
+ --value-en "Welcome!" \
93
+ --value-es "¡Bienvenido!"
52
94
  ```
53
95
 
54
96
  ---
55
97
 
56
- ## Commands
98
+ ## Commands Overview
99
+
100
+ ### Authentication
101
+ - `langctl init` - Interactive setup wizard
102
+ - `langctl auth <api-key>` - Authenticate with API key
103
+ - `langctl logout` - Clear credentials
104
+ - `langctl config` - View current configuration
105
+
106
+ ### Organization
107
+ - `langctl org info` - View organization details
108
+ - `langctl org stats` - View organization statistics
109
+ - `langctl org plan` - View subscription plan and limits
110
+
111
+ ### Projects
112
+ - `langctl projects list` - List all projects
113
+ - `langctl projects create <name>` - Create new project
114
+ - `langctl projects get <slug>` - Get project details
115
+ - `langctl projects update <slug>` - Update project
116
+ - `langctl projects delete <slug>` - Delete project
117
+ - `langctl projects add-language <slug> <language>` - Add language
118
+ - `langctl projects remove-language <slug> <language>` - Remove language
119
+ - `langctl projects stats <slug>` - View project statistics
120
+
121
+ ### Translation Keys
122
+ - `langctl keys list <project>` - List translation keys
123
+ - `langctl keys get <project> <key>` - Get key details
124
+ - `langctl keys create <project> <key>` - Create new key
125
+ - `langctl keys delete <project> <key>` - Delete key
126
+ - `langctl keys translate <project> <key>` - Update translation
127
+ - `langctl keys publish <project> <keys...>` - Publish/unpublish keys
128
+
129
+ ### Team
130
+ - `langctl team list` - List team members
131
+ - `langctl team get <email>` - Get member details
132
+ - `langctl team invite <email>` - Invite team member
133
+ - `langctl team remove <email>` - Remove team member
134
+ - `langctl team update-role <email> <role>` - Update member role
135
+ - `langctl team invitations` - List invitations
136
+ - `langctl team revoke-invitation <email>` - Revoke invitation
137
+
138
+ ### Import/Export
139
+ - `langctl export <project>` - Export translations
140
+ - `langctl import <project> <file>` - Import translations
57
141
 
58
- ### `langctl init`
142
+ ---
143
+
144
+ ## Detailed Command Reference
145
+
146
+ ### Authentication Commands
59
147
 
60
- Interactive setup wizard to configure the CLI.
148
+ #### `langctl init`
149
+
150
+ Interactive setup wizard that guides you through authentication and configuration.
61
151
 
62
152
  ```bash
63
153
  langctl init
64
154
  ```
65
155
 
66
- ### `langctl auth <api-key>`
156
+ #### `langctl auth <api-key>`
67
157
 
68
- Authenticate with an API key from the dashboard.
158
+ Authenticate with an API key from your dashboard.
69
159
 
70
160
  ```bash
71
161
  langctl auth lc_abc123...
72
162
  ```
73
163
 
74
- ### `langctl logout`
164
+ #### `langctl logout`
75
165
 
76
- Clear authentication credentials.
166
+ Clear stored authentication credentials.
77
167
 
78
168
  ```bash
79
169
  langctl logout
80
170
  ```
81
171
 
82
- ### `langctl config`
172
+ #### `langctl config`
83
173
 
84
- View current configuration.
174
+ Display current configuration (API key, organization, etc.).
85
175
 
86
176
  ```bash
87
177
  langctl config
88
178
  ```
89
179
 
90
- ### `langctl projects list`
180
+ ---
181
+
182
+ ### Organization Commands
183
+
184
+ #### `langctl org info`
185
+
186
+ View your organization details.
187
+
188
+ ```bash
189
+ langctl org info
190
+ ```
191
+
192
+ **Output:**
193
+ - Organization name and ID
194
+ - Slug
195
+ - Subscription plan
196
+ - Creation date
197
+
198
+ #### `langctl org stats`
199
+
200
+ View comprehensive organization statistics.
201
+
202
+ ```bash
203
+ langctl org stats
204
+ ```
205
+
206
+ **Output:**
207
+ - Total team members
208
+ - Number of projects
209
+ - Translation key counts (total, published, unpublished)
210
+ - Languages used across projects
211
+ - API keys and webhooks
212
+
213
+ #### `langctl org plan`
214
+
215
+ View subscription plan details and resource limits.
216
+
217
+ ```bash
218
+ langctl org plan
219
+ ```
220
+
221
+ **Output:**
222
+ - Current plan (Free, Pro, Team, Enterprise)
223
+ - Max members allowed
224
+ - Max projects allowed
225
+ - Max keys per project
226
+ - Max API keys allowed
227
+
228
+ ---
229
+
230
+ ### Project Management Commands
91
231
 
92
- Show all accessible projects.
232
+ #### `langctl projects list`
233
+
234
+ List all projects you have access to.
93
235
 
94
236
  ```bash
95
237
  langctl projects list
96
238
  ```
97
239
 
98
- ### `langctl pull <project-id>`
240
+ **Output:**
241
+ - Project name and slug
242
+ - Description
243
+ - Supported languages
244
+ - Default language
245
+ - Available modules
246
+
247
+ #### `langctl projects create <name>`
248
+
249
+ Create a new translation project.
250
+
251
+ ```bash
252
+ langctl projects create "Mobile App" \
253
+ --description "iOS and Android translations" \
254
+ --languages en,es,fr,de \
255
+ --default-language en
256
+ ```
257
+
258
+ **Options:**
259
+ - `-d, --description <text>` - Project description
260
+ - `-l, --languages <langs>` - Comma-separated language codes (default: `en`)
261
+ - `--default-language <code>` - Default language (default: first language)
262
+
263
+ **Examples:**
264
+
265
+ ```bash
266
+ # Simple project with English only
267
+ langctl projects create "My App"
268
+
269
+ # Multi-language project
270
+ langctl projects create "Global App" \
271
+ -l en,es,fr,de,ja \
272
+ --default-language en
273
+
274
+ # With description
275
+ langctl projects create "Mobile App" \
276
+ -d "Translation keys for mobile application" \
277
+ -l en,es
278
+ ```
279
+
280
+ #### `langctl projects get <slug>`
281
+
282
+ Get detailed information about a specific project.
283
+
284
+ ```bash
285
+ langctl projects get my-app
286
+ ```
287
+
288
+ **Output:**
289
+ - Project name, ID, and slug
290
+ - Description
291
+ - All supported languages
292
+ - Default language
293
+ - List of modules
294
+
295
+ #### `langctl projects update <slug>`
296
+
297
+ Update project details.
298
+
299
+ ```bash
300
+ langctl projects update my-app \
301
+ --name "New Name" \
302
+ --description "Updated description" \
303
+ --languages en,es,fr,de,ja \
304
+ --default-language en
305
+ ```
306
+
307
+ **Options:**
308
+ - `-n, --name <name>` - Update project name
309
+ - `-d, --description <text>` - Update description
310
+ - `-l, --languages <langs>` - Update supported languages
311
+ - `--default-language <code>` - Update default language
312
+
313
+ **Examples:**
314
+
315
+ ```bash
316
+ # Change project name
317
+ langctl projects update my-app --name "Better Name"
318
+
319
+ # Add more languages
320
+ langctl projects update my-app -l en,es,fr,de,ja,zh
321
+
322
+ # Update description only
323
+ langctl projects update my-app -d "New project description"
324
+ ```
325
+
326
+ #### `langctl projects delete <slug>`
327
+
328
+ Delete a project (soft delete - can be recovered).
329
+
330
+ ```bash
331
+ langctl projects delete my-app
332
+ ```
333
+
334
+ **Warning:** This will mark the project as deleted. Contact support to recover deleted projects.
335
+
336
+ #### `langctl projects add-language <slug> <language>`
337
+
338
+ Add a new language to an existing project.
339
+
340
+ ```bash
341
+ langctl projects add-language my-app de
342
+ ```
343
+
344
+ **Examples:**
345
+
346
+ ```bash
347
+ # Add German
348
+ langctl projects add-language my-app de
349
+
350
+ # Add Japanese
351
+ langctl projects add-language my-app ja
352
+
353
+ # Add Chinese
354
+ langctl projects add-language my-app zh
355
+ ```
356
+
357
+ #### `langctl projects remove-language <slug> <language>`
358
+
359
+ Remove a language from a project.
360
+
361
+ ```bash
362
+ langctl projects remove-language my-app de
363
+ ```
364
+
365
+ **Note:** Cannot remove the default language. Change default language first if needed.
366
+
367
+ #### `langctl projects stats <slug>`
368
+
369
+ View project statistics.
370
+
371
+ ```bash
372
+ langctl projects stats my-app
373
+ ```
374
+
375
+ **Output:**
376
+ - Total translation keys
377
+ - Published vs unpublished counts
378
+ - Number of modules
379
+ - List of module names
380
+
381
+ ---
382
+
383
+ ### Translation Key Commands
384
+
385
+ #### `langctl keys list <project>`
386
+
387
+ List translation keys for a project.
388
+
389
+ ```bash
390
+ langctl keys list my-app
391
+ ```
392
+
393
+ **Options:**
394
+ - `-m, --module <name>` - Filter by module
395
+ - `-p, --published` - Show only published keys
396
+ - `-s, --search <term>` - Search in key names
397
+ - `--limit <number>` - Limit results (default: 100)
398
+ - `--offset <number>` - Offset for pagination (default: 0)
399
+
400
+ **Examples:**
401
+
402
+ ```bash
403
+ # List all keys
404
+ langctl keys list my-app
405
+
406
+ # Filter by module
407
+ langctl keys list my-app --module auth
408
+
409
+ # Show only published keys
410
+ langctl keys list my-app --published
411
+
412
+ # Search for specific keys
413
+ langctl keys list my-app --search "welcome"
414
+
415
+ # Pagination
416
+ langctl keys list my-app --limit 50 --offset 0
417
+ langctl keys list my-app --limit 50 --offset 50
418
+ ```
419
+
420
+ #### `langctl keys get <project> <key>`
421
+
422
+ Get detailed information about a specific translation key.
423
+
424
+ ```bash
425
+ langctl keys get my-app home.welcome
426
+ ```
427
+
428
+ **Output:**
429
+ - Key name and ID
430
+ - Description
431
+ - Module
432
+ - Published status
433
+ - All translations for all languages
434
+
435
+ #### `langctl keys create <project> <key>`
436
+
437
+ Create a new translation key with values for multiple languages.
438
+
439
+ ```bash
440
+ langctl keys create my-app home.welcome \
441
+ --description "Welcome message on homepage" \
442
+ --module home \
443
+ --value-en "Welcome to our app!" \
444
+ --value-es "¡Bienvenido a nuestra aplicación!" \
445
+ --value-fr "Bienvenue dans notre application!" \
446
+ --value-de "Willkommen in unserer App!"
447
+ ```
448
+
449
+ **Options:**
450
+ - `-d, --description <text>` - Key description
451
+ - `-m, --module <name>` - Module/namespace for organization
452
+ - `--value-en <value>` - English translation
453
+ - `--value-es <value>` - Spanish translation
454
+ - `--value-fr <value>` - French translation
455
+ - `--value-de <value>` - German translation
456
+ - `--tags <tags>` - Comma-separated tags
457
+
458
+ **Supported language options:**
459
+ You can use `--value-{language}` for any language code in your project.
460
+
461
+ **Examples:**
462
+
463
+ ```bash
464
+ # Simple key with one language
465
+ langctl keys create my-app button.submit --value-en "Submit"
466
+
467
+ # Multi-language key
468
+ langctl keys create my-app home.title \
469
+ --module home \
470
+ --value-en "Home" \
471
+ --value-es "Inicio" \
472
+ --value-fr "Accueil"
473
+
474
+ # With description and tags
475
+ langctl keys create my-app error.network \
476
+ --description "Network connection error" \
477
+ --module errors \
478
+ --value-en "Network error occurred" \
479
+ --tags error,network
480
+ ```
481
+
482
+ #### `langctl keys delete <project> <key>`
483
+
484
+ Delete a translation key.
485
+
486
+ ```bash
487
+ langctl keys delete my-app home.welcome
488
+ ```
489
+
490
+ #### `langctl keys translate <project> <key>`
491
+
492
+ Update the translation value for a specific language.
493
+
494
+ ```bash
495
+ langctl keys translate my-app home.welcome \
496
+ --language es \
497
+ --value "¡Bienvenido!"
498
+ ```
499
+
500
+ **Options:**
501
+ - `-l, --language <code>` - Language code (required)
502
+ - `-v, --value <text>` - Translation value (required)
503
+
504
+ **Examples:**
505
+
506
+ ```bash
507
+ # Update Spanish translation
508
+ langctl keys translate my-app home.title -l es -v "Inicio"
509
+
510
+ # Update French translation
511
+ langctl keys translate my-app button.submit -l fr -v "Soumettre"
512
+
513
+ # Add translation for new language
514
+ langctl keys translate my-app home.welcome -l de -v "Willkommen"
515
+ ```
516
+
517
+ #### `langctl keys publish <project> <keys...>`
518
+
519
+ Publish or unpublish translation keys.
520
+
521
+ ```bash
522
+ # Publish keys
523
+ langctl keys publish my-app home.welcome home.title button.submit
524
+
525
+ # Unpublish keys
526
+ langctl keys publish my-app home.welcome --unpublish
527
+ ```
528
+
529
+ **Options:**
530
+ - `--unpublish` - Unpublish instead of publish
531
+
532
+ **Examples:**
533
+
534
+ ```bash
535
+ # Publish single key
536
+ langctl keys publish my-app home.welcome
537
+
538
+ # Publish multiple keys
539
+ langctl keys publish my-app home.welcome home.title home.subtitle
540
+
541
+ # Unpublish keys
542
+ langctl keys publish my-app test.key --unpublish
543
+ ```
544
+
545
+ ---
546
+
547
+ ### Team Management Commands
548
+
549
+ #### `langctl team list`
550
+
551
+ List all team members in your organization.
552
+
553
+ ```bash
554
+ langctl team list
555
+ ```
556
+
557
+ **Output:**
558
+ - Member email
559
+ - Role (viewer, member, admin, owner)
560
+ - Join date
561
+
562
+ #### `langctl team get <email>`
99
563
 
100
- Pull translations from a project.
564
+ Get details about a specific team member.
101
565
 
102
566
  ```bash
103
- langctl pull <project-id> [options]
567
+ langctl team get user@example.com
568
+ ```
569
+
570
+ #### `langctl team invite <email>`
571
+
572
+ Invite a new team member.
573
+
574
+ ```bash
575
+ langctl team invite user@example.com --role member
104
576
  ```
105
577
 
106
578
  **Options:**
579
+ - `-r, --role <role>` - Member role (default: `member`)
580
+ - `viewer` - Read-only access
581
+ - `member` - Can manage translations
582
+ - `admin` - Full project and team management
583
+
584
+ **Examples:**
585
+
586
+ ```bash
587
+ # Invite as member (default)
588
+ langctl team invite user@example.com
589
+
590
+ # Invite as admin
591
+ langctl team invite admin@example.com --role admin
592
+
593
+ # Invite as viewer
594
+ langctl team invite viewer@example.com --role viewer
595
+ ```
596
+
597
+ #### `langctl team remove <email>`
598
+
599
+ Remove a team member from your organization.
600
+
601
+ ```bash
602
+ langctl team remove user@example.com
603
+ ```
604
+
605
+ **Note:** Cannot remove the organization owner. Cannot remove yourself (use appropriate UI for that).
606
+
607
+ #### `langctl team update-role <email> <role>`
107
608
 
108
- - `-l, --language <code>` - Language code to pull (default: `en`)
109
- - `-f, --format <type>` - Export format (default: `json`)
110
- - `json` - Flat JSON (key-value pairs)
111
- - `json-nested` - Nested JSON (organized by key structure)
112
- - `ios` - iOS .strings format
113
- - `android` - Android XML format
114
- - `flutter` - Flutter ARB format
115
- - `-o, --output <path>` - Output file path (default: `./translations/`)
116
- - `--no-published-only` - Include unpublished translations
609
+ Update a team member's role.
610
+
611
+ ```bash
612
+ langctl team update-role user@example.com admin
613
+ ```
614
+
615
+ **Valid roles:** `viewer`, `member`, `admin`
117
616
 
118
617
  **Examples:**
119
618
 
120
619
  ```bash
121
- # Pull English translations as JSON
122
- langctl pull abc-123 --language en --format json
620
+ # Promote to admin
621
+ langctl team update-role user@example.com admin
622
+
623
+ # Demote to viewer
624
+ langctl team update-role user@example.com viewer
625
+ ```
626
+
627
+ #### `langctl team invitations`
628
+
629
+ List all invitations (pending, accepted, or cancelled).
630
+
631
+ ```bash
632
+ # List all invitations
633
+ langctl team invitations
634
+
635
+ # List only pending invitations
636
+ langctl team invitations --pending
637
+ ```
638
+
639
+ **Options:**
640
+ - `-p, --pending` - Show only pending invitations
123
641
 
124
- # Pull Spanish translations as iOS strings
125
- langctl pull abc-123 --language es --format ios
642
+ #### `langctl team revoke-invitation <email>`
126
643
 
127
- # Pull all translations (including unpublished)
128
- langctl pull abc-123 --language en --no-published-only
644
+ Revoke a pending invitation.
129
645
 
130
- # Custom output path
131
- langctl pull abc-123 --language en --output ./locales/en.json
646
+ ```bash
647
+ langctl team revoke-invitation user@example.com
132
648
  ```
133
649
 
134
650
  ---
135
651
 
136
- ## Export Formats
652
+ ### Export/Import Commands
653
+
654
+ #### `langctl export <project>`
655
+
656
+ Export translations in various formats.
657
+
658
+ ```bash
659
+ langctl export my-app --language en --format flat-json
660
+ ```
661
+
662
+ **Options:**
663
+ - `-l, --language <code>` - Language to export (default: exports all languages)
664
+ - `-f, --format <type>` - Export format (default: `flat-json`)
665
+ - `-o, --output <path>` - Output file path (optional)
666
+ - `-m, --module <name>` - Export only specific module
667
+ - `--include-unpublished` - Include unpublished keys (default: published only)
668
+
669
+ **Supported formats:**
670
+ - `flat-json` - Flat key-value JSON (default)
671
+ - `nested-json` - Nested JSON structure
672
+ - `i18n-json` - i18next compatible format
673
+ - `android-xml` - Android strings.xml format
674
+ - `ios-strings` - iOS Localizable.strings format
675
+ - `flutter-arb` - Flutter ARB format
676
+
677
+ **Examples:**
678
+
679
+ ```bash
680
+ # Export single language as JSON
681
+ langctl export my-app -l en -f flat-json
682
+
683
+ # Export all languages
684
+ langctl export my-app
685
+
686
+ # Export for iOS
687
+ langctl export my-app -l en -f ios-strings -o ./ios/en.lproj/Localizable.strings
688
+
689
+ # Export for Android
690
+ langctl export my-app -l es -f android-xml -o ./android/res/values-es/strings.xml
691
+
692
+ # Export for Flutter
693
+ langctl export my-app -l fr -f flutter-arb -o ./lib/l10n/app_fr.arb
694
+
695
+ # Export specific module
696
+ langctl export my-app -l en --module auth
697
+
698
+ # Include unpublished translations
699
+ langctl export my-app -l en --include-unpublished
700
+ ```
701
+
702
+ #### `langctl import <project> <file>`
703
+
704
+ Import translations from a JSON file.
705
+
706
+ ```bash
707
+ langctl import my-app translations.json --language en
708
+ ```
709
+
710
+ **Options:**
711
+ - `-l, --language <code>` - Target language (required)
712
+ - `--overwrite` - Overwrite existing translations
713
+ - `--publish` - Auto-publish imported keys
714
+
715
+ **Examples:**
716
+
717
+ ```bash
718
+ # Import English translations
719
+ langctl import my-app en.json -l en
720
+
721
+ # Import and overwrite existing
722
+ langctl import my-app en.json -l en --overwrite
723
+
724
+ # Import and auto-publish
725
+ langctl import my-app en.json -l en --publish
137
726
 
138
- ### JSON (Flat)
727
+ # Import multiple languages
728
+ langctl import my-app en.json -l en --publish
729
+ langctl import my-app es.json -l es --publish
730
+ langctl import my-app fr.json -l fr --publish
731
+ ```
139
732
 
140
- Simple key-value pairs with dot notation.
733
+ **Supported JSON formats:**
141
734
 
142
735
  ```json
736
+ // Flat format (recommended)
143
737
  {
144
738
  "home.welcome": "Welcome!",
145
- "home.subtitle": "Get started with {{appName}}"
739
+ "home.subtitle": "Get started",
740
+ "button.submit": "Submit"
741
+ }
742
+
743
+ // Nested format (auto-flattened)
744
+ {
745
+ "home": {
746
+ "welcome": "Welcome!",
747
+ "subtitle": "Get started"
748
+ },
749
+ "button": {
750
+ "submit": "Submit"
751
+ }
146
752
  }
147
753
  ```
148
754
 
149
- ### JSON (Nested)
755
+ ---
756
+
757
+ ## Export Format Examples
150
758
 
151
- Organized by key structure.
759
+ ### Flat JSON (Default)
760
+
761
+ ```json
762
+ {
763
+ "home.welcome": "Welcome!",
764
+ "home.subtitle": "Get started with {{appName}}",
765
+ "button.submit": "Submit"
766
+ }
767
+ ```
768
+
769
+ ### Nested JSON
152
770
 
153
771
  ```json
154
772
  {
155
773
  "home": {
156
774
  "welcome": "Welcome!",
157
775
  "subtitle": "Get started with {{appName}}"
776
+ },
777
+ "button": {
778
+ "submit": "Submit"
158
779
  }
159
780
  }
160
781
  ```
161
782
 
162
- ### iOS Strings
783
+ ### i18next JSON
784
+
785
+ ```json
786
+ {
787
+ "home": {
788
+ "welcome": "Welcome!",
789
+ "subtitle": "Get started with {{appName}}"
790
+ }
791
+ }
792
+ ```
163
793
 
164
- Standard iOS `.strings` format.
794
+ ### iOS Strings
165
795
 
166
796
  ```
797
+ /* Welcome message */
167
798
  "home.welcome" = "Welcome!";
168
- "home.subtitle" = "Get started with %1$@";
799
+
800
+ /* Homepage subtitle with app name placeholder */
801
+ "home.subtitle" = "Get started with %@";
169
802
  ```
170
803
 
171
804
  ### Android XML
172
805
 
173
- Android resources XML format.
174
-
175
806
  ```xml
176
807
  <?xml version="1.0" encoding="utf-8"?>
177
808
  <resources>
809
+ <!-- Welcome message -->
178
810
  <string name="home.welcome">Welcome!</string>
811
+
812
+ <!-- Homepage subtitle with app name placeholder -->
179
813
  <string name="home.subtitle">Get started with %1$s</string>
180
814
  </resources>
181
815
  ```
182
816
 
183
817
  ### Flutter ARB
184
818
 
185
- Application Resource Bundle format for Flutter.
186
-
187
819
  ```json
188
820
  {
189
821
  "@@locale": "en",
190
822
  "home.welcome": "Welcome!",
823
+ "@home.welcome": {
824
+ "description": "Welcome message"
825
+ },
191
826
  "home.subtitle": "Get started with {appName}",
192
827
  "@home.subtitle": {
828
+ "description": "Homepage subtitle",
193
829
  "placeholders": {
194
830
  "appName": {
195
831
  "type": "String"
@@ -201,11 +837,99 @@ Application Resource Bundle format for Flutter.
201
837
 
202
838
  ---
203
839
 
840
+ ## Real-World Workflows
841
+
842
+ ### Complete Project Setup
843
+
844
+ ```bash
845
+ # 1. Authenticate
846
+ langctl auth lc_your_api_key_here
847
+
848
+ # 2. Create project
849
+ langctl projects create "Mobile App" \
850
+ -l en,es,fr,de \
851
+ --default-language en \
852
+ -d "iOS and Android application"
853
+
854
+ # 3. Add translation keys
855
+ langctl keys create mobile-app home.welcome \
856
+ --module home \
857
+ --value-en "Welcome!" \
858
+ --value-es "¡Bienvenido!" \
859
+ --value-fr "Bienvenue!"
860
+
861
+ langctl keys create mobile-app button.submit \
862
+ --module common \
863
+ --value-en "Submit" \
864
+ --value-es "Enviar" \
865
+ --value-fr "Soumettre"
866
+
867
+ # 4. Publish keys
868
+ langctl keys publish mobile-app home.welcome button.submit
869
+
870
+ # 5. Export for platforms
871
+ langctl export mobile-app -l en -f ios-strings -o ./ios/en.lproj/
872
+ langctl export mobile-app -l en -f android-xml -o ./android/res/values/
873
+ ```
874
+
875
+ ### Bulk Import Workflow
876
+
877
+ ```bash
878
+ # 1. Prepare JSON files (en.json, es.json, fr.json)
879
+ # 2. Import all languages
880
+ langctl import my-app en.json -l en --publish
881
+ langctl import my-app es.json -l es --publish
882
+ langctl import my-app fr.json -l fr --publish
883
+
884
+ # 3. Verify imports
885
+ langctl keys list my-app --published
886
+ langctl projects stats my-app
887
+ ```
888
+
889
+ ### Team Collaboration
890
+
891
+ ```bash
892
+ # 1. Invite team members
893
+ langctl team invite developer@example.com --role member
894
+ langctl team invite manager@example.com --role admin
895
+
896
+ # 2. Check invitations
897
+ langctl team invitations --pending
898
+
899
+ # 3. Manage roles
900
+ langctl team update-role developer@example.com admin
901
+
902
+ # 4. View team
903
+ langctl team list
904
+ ```
905
+
906
+ ### Multi-Platform Export
907
+
908
+ ```bash
909
+ # Export for all platforms
910
+ PROJECT="my-app"
911
+ LANG="en"
912
+
913
+ # Web (i18next)
914
+ langctl export $PROJECT -l $LANG -f i18n-json -o ./src/locales/$LANG.json
915
+
916
+ # iOS
917
+ langctl export $PROJECT -l $LANG -f ios-strings -o ./ios/$LANG.lproj/Localizable.strings
918
+
919
+ # Android
920
+ langctl export $PROJECT -l $LANG -f android-xml -o ./android/res/values/strings.xml
921
+
922
+ # Flutter
923
+ langctl export $PROJECT -l $LANG -f flutter-arb -o ./lib/l10n/app_$LANG.arb
924
+ ```
925
+
926
+ ---
927
+
204
928
  ## CI/CD Integration
205
929
 
206
930
  ### GitHub Actions
207
931
 
208
- Example workflow for daily translation syncs:
932
+ Automated translation sync workflow:
209
933
 
210
934
  ```yaml
211
935
  name: Sync Translations
@@ -213,10 +937,10 @@ name: Sync Translations
213
937
  on:
214
938
  schedule:
215
939
  - cron: '0 0 * * *' # Daily at midnight
216
- workflow_dispatch:
940
+ workflow_dispatch: # Manual trigger
217
941
 
218
942
  jobs:
219
- sync:
943
+ sync-translations:
220
944
  runs-on: ubuntu-latest
221
945
  steps:
222
946
  - uses: actions/checkout@v3
@@ -234,87 +958,258 @@ jobs:
234
958
  LANGCTL_API_KEY: ${{ secrets.LANGCTL_API_KEY }}
235
959
  run: langctl auth $LANGCTL_API_KEY
236
960
 
237
- - name: Pull Translations
961
+ - name: Export Translations
238
962
  run: |
239
- langctl pull ${{ secrets.PROJECT_ID }} --language en --format json
240
- langctl pull ${{ secrets.PROJECT_ID }} --language es --format json
963
+ langctl export my-project -l en -f i18n-json -o ./locales/en.json
964
+ langctl export my-project -l es -f i18n-json -o ./locales/es.json
965
+ langctl export my-project -l fr -f i18n-json -o ./locales/fr.json
241
966
 
242
967
  - name: Commit Changes
243
968
  run: |
244
- git config --global user.name "Langctl Bot"
245
- git config --global user.email "bot@langctl.com"
246
- git add translations/
247
- git commit -m "chore: update translations" || echo "No changes"
969
+ git config user.name "Langctl Bot"
970
+ git config user.email "bot@langctl.com"
971
+ git add locales/
972
+ git diff --staged --quiet || git commit -m "chore: update translations [skip ci]"
248
973
  git push
249
974
  ```
250
975
 
251
- **Setup:**
252
- 1. Add `LANGCTL_API_KEY` to your repository secrets
253
- 2. Add `PROJECT_ID` to your repository secrets
254
- 3. Adjust languages and format as needed
976
+ ### GitLab CI
977
+
978
+ ```yaml
979
+ sync-translations:
980
+ image: node:18
981
+ script:
982
+ - npm install -g langctl
983
+ - langctl auth $LANGCTL_API_KEY
984
+ - langctl export my-project -l en -f json -o ./locales/en.json
985
+ - langctl export my-project -l es -f json -o ./locales/es.json
986
+ - git config user.name "Langctl Bot"
987
+ - git config user.email "bot@langctl.com"
988
+ - git add locales/
989
+ - git diff --staged --quiet || git commit -m "chore: update translations"
990
+ - git push origin $CI_COMMIT_BRANCH
991
+ only:
992
+ - schedules
993
+ ```
994
+
995
+ ### Docker
996
+
997
+ ```dockerfile
998
+ FROM node:18-alpine
999
+
1000
+ RUN npm install -g langctl
1001
+
1002
+ WORKDIR /app
1003
+
1004
+ COPY . .
1005
+
1006
+ # Set API key via environment variable
1007
+ ENV LANGCTL_API_KEY=""
1008
+
1009
+ # Example: Export translations on build
1010
+ RUN langctl auth $LANGCTL_API_KEY && \
1011
+ langctl export my-project -l en -f json -o ./public/locales/en.json
1012
+ ```
255
1013
 
256
1014
  ---
257
1015
 
258
- ## Troubleshooting
1016
+ ## Best Practices
1017
+
1018
+ ### Project Organization
1019
+
1020
+ 1. **Use modules** to organize keys by feature:
1021
+ ```bash
1022
+ langctl keys create app auth.login.title --module auth
1023
+ langctl keys create app home.hero.title --module home
1024
+ langctl keys create app settings.profile.name --module settings
1025
+ ```
1026
+
1027
+ 2. **Follow naming conventions**:
1028
+ ```
1029
+ module.screen.element
1030
+ auth.login.title
1031
+ home.hero.subtitle
1032
+ ```
1033
+
1034
+ 3. **Add descriptions** to keys:
1035
+ ```bash
1036
+ langctl keys create app button.submit \
1037
+ --description "Primary action button across the app" \
1038
+ --value-en "Submit"
1039
+ ```
1040
+
1041
+ ### Translation Workflow
1042
+
1043
+ 1. **Create keys unpublished** (draft mode)
1044
+ 2. **Add translations** for all languages
1045
+ 3. **Review and test** translations
1046
+ 4. **Publish** when ready:
1047
+ ```bash
1048
+ langctl keys publish my-app key1 key2 key3
1049
+ ```
1050
+
1051
+ 5. **Export** published translations only:
1052
+ ```bash
1053
+ langctl export my-app -l en
1054
+ ```
1055
+
1056
+ ### Team Management
1057
+
1058
+ 1. **Use appropriate roles**:
1059
+ - `viewer` - Stakeholders, reviewers (read-only)
1060
+ - `member` - Translators, content writers
1061
+ - `admin` - Project managers, team leads
1062
+
1063
+ 2. **Regular access reviews**:
1064
+ ```bash
1065
+ langctl team list
1066
+ langctl team invitations
1067
+ ```
1068
+
1069
+ ### Security
1070
+
1071
+ 1. **Never commit API keys** to version control
1072
+ 2. **Use environment variables**:
1073
+ ```bash
1074
+ export LANGCTL_API_KEY="lc_..."
1075
+ langctl auth $LANGCTL_API_KEY
1076
+ ```
1077
+
1078
+ 3. **Rotate keys periodically** from [app.langctl.com](https://app.langctl.com)
1079
+
1080
+ 4. **Use different keys** for different environments:
1081
+ - Development key for local work
1082
+ - CI/CD key for automated workflows
1083
+ - Production key for releases
259
1084
 
260
- ### "Not authenticated" error
1085
+ ---
261
1086
 
262
- **Solution:** Run `langctl init` or `langctl auth <api-key>` to authenticate.
1087
+ ## Troubleshooting
263
1088
 
264
- ### "Project not found" error
1089
+ ### Authentication Issues
265
1090
 
266
- **Possible causes:**
267
- - Invalid project ID - verify with `langctl projects list`
268
- - API key doesn't have access to the project
269
- - Project belongs to different organization
1091
+ **"Not authenticated" error:**
1092
+ ```bash
1093
+ # Solution: Authenticate with your API key
1094
+ langctl auth lc_your_api_key_here
1095
+ ```
270
1096
 
271
- ### Invalid API key format
1097
+ **"Invalid API key" error:**
1098
+ - Verify key format (starts with `lc_`, 67 characters total)
1099
+ - Check key hasn't been revoked at [app.langctl.com](https://app.langctl.com)
1100
+ - Generate a new key if needed
272
1101
 
273
- API keys must:
274
- - Start with `lc_`
275
- - Be 67 characters long (including `lc_` prefix)
276
- - Be generated from the Langctl dashboard at [langctl.com](https://langctl.com)
1102
+ ### Project Issues
277
1103
 
278
- ### Connection issues
1104
+ **"Project not found" error:**
1105
+ ```bash
1106
+ # Check project slug (not name)
1107
+ langctl projects list
279
1108
 
280
- If you experience connectivity problems:
281
- - Check your internet connection
282
- - Verify you're not behind a restrictive firewall
283
- - Try again in a few moments
1109
+ # Use the slug shown in the list
1110
+ langctl keys list correct-slug-here
1111
+ ```
1112
+
1113
+ **Cannot remove language:**
1114
+ - Cannot remove the default language
1115
+ - Change default language first:
1116
+ ```bash
1117
+ langctl projects update my-app --default-language en
1118
+ langctl projects remove-language my-app fr
1119
+ ```
1120
+
1121
+ ### Import/Export Issues
1122
+
1123
+ **Import fails with format error:**
1124
+ - Ensure JSON is valid
1125
+ - Use flat key-value format or nested objects
1126
+ - Check language code is valid
1127
+
1128
+ **Export shows no keys:**
1129
+ - Verify keys are published:
1130
+ ```bash
1131
+ langctl keys list my-app --published
1132
+ ```
1133
+ - Or include unpublished:
1134
+ ```bash
1135
+ langctl export my-app -l en --include-unpublished
1136
+ ```
1137
+
1138
+ ### Connection Issues
1139
+
1140
+ If experiencing connectivity problems:
1141
+ 1. Check your internet connection
1142
+ 2. Verify you're not behind a restrictive firewall
1143
+ 3. Try again in a few moments
1144
+ 4. Contact support if issue persists
284
1145
 
285
1146
  ---
286
1147
 
287
- ## API Keys
1148
+ ## FAQ
1149
+
1150
+ **Q: What's the difference between slug and name?**
1151
+ A: The slug is the URL-friendly identifier (e.g., `my-app`), while the name is the display name (e.g., "My App"). Use slugs in CLI commands.
1152
+
1153
+ **Q: Can I use the CLI without installing it?**
1154
+ A: Yes! Use `npx langctl` instead of `langctl` for any command.
1155
+
1156
+ **Q: How do I get my project slug?**
1157
+ A: Run `langctl projects list` to see all project slugs.
1158
+
1159
+ **Q: Can I export multiple languages at once?**
1160
+ A: Yes, run `langctl export my-app` without `-l` flag to export all languages.
288
1161
 
289
- API keys are **organization-scoped** and provide access to all projects within that organization.
1162
+ **Q: What happens to unpublished keys?**
1163
+ A: They're excluded from exports by default. Use `--include-unpublished` to include them.
290
1164
 
291
- **Security best practices:**
292
- - ✅ Store API keys in environment variables or secrets managers
293
- - ✅ Use different keys for development and production
294
- - ✅ Rotate keys periodically
295
- - ❌ Never commit API keys to version control
296
- - ❌ Never share API keys publicly
1165
+ **Q: Can I undo a delete operation?**
1166
+ A: Projects and keys use soft deletes. Contact support to recover deleted items.
297
1167
 
298
- **Revoke compromised keys immediately** from your dashboard.
1168
+ **Q: How do I change my default language?**
1169
+ A: Run: `langctl projects update my-app --default-language <new-language>`
1170
+
1171
+ **Q: Can I use the CLI in CI/CD?**
1172
+ A: Yes! Store your API key as a secret and use it in your workflow. See [CI/CD Integration](#cicd-integration).
299
1173
 
300
1174
  ---
301
1175
 
302
1176
  ## Platform Support
303
1177
 
304
1178
  - ✅ macOS (Apple Silicon & Intel)
305
- - ✅ Linux (x64, ARM)
306
- - ✅ Windows (x64)
307
- - ✅ Node.js 16.0.0+
1179
+ - ✅ Linux (x64, ARM64)
1180
+ - ✅ Windows (x64, ARM64)
1181
+ - ✅ Node.js 16.0.0 or higher
308
1182
 
309
1183
  ---
310
1184
 
311
- ## Links
1185
+ ## 🌟 Why Langctl?
1186
+
1187
+ Tired of expensive translation management tools? Langctl offers:
1188
+ - ✅ **Free to start** - No credit card required
1189
+ - ✅ **90% cheaper** than enterprise alternatives
1190
+ - ✅ **Developer-first** - Built for your workflow
1191
+ - ✅ **AI-powered** - Context-aware translations
1192
+ - ✅ **Open source CLI** - Inspect, fork, contribute
312
1193
 
313
- - **Dashboard:** [app.langctl.com](https://app.langctl.com)
314
- - **Documentation:** [langctl.com/docs](https://langctl.com/docs)
315
- - **GitHub:** [github.com/siddharthsaxena0/langctl](https://github.com/siddharthsaxena0/langctl)
316
- - **Issues:** [github.com/siddharthsaxena0/langctl/issues](https://github.com/siddharthsaxena0/langctl/issues)
317
- - **Email:** [hello@langctl.com](mailto:hello@langctl.com)
1194
+ **[See pricing and compare features →](https://langctl.com/pricing)**
1195
+
1196
+ ---
1197
+
1198
+ ## 📚 Resources & Support
1199
+
1200
+ - 🌐 **[Website](https://langctl.com)** - Features, pricing, and comparisons
1201
+ - 📖 **[Full Documentation](https://langctl.com/docs)** - Guides, tutorials, and best practices
1202
+ - 🎯 **[Quick Start Tutorial](https://langctl.com/docs/getting-started/quickstart)** - Step-by-step walkthrough
1203
+ - 💡 **[Integration Guides](https://langctl.com/docs/integrations/overview)** - React, Angular, Vue, iOS, Android, Flutter
1204
+ - 📊 **[Dashboard](https://app.langctl.com)** - Manage translations visually
1205
+ - 💬 **[Get Support](https://langctl.com/contact)** - Email us at [hello@langctl.com](mailto:hello@langctl.com)
1206
+ - 🐛 **[Report Issues](https://github.com/siddharthsaxena0/langctl/issues)** - Bug reports and feature requests
1207
+
1208
+ ---
1209
+
1210
+ ## Contributing
1211
+
1212
+ We welcome contributions! This is an open-source project and we'd love your help making it better.
318
1213
 
319
1214
  ---
320
1215
 
@@ -322,6 +1217,16 @@ API keys are **organization-scoped** and provide access to all projects within t
322
1217
 
323
1218
  MIT License - see [LICENSE](LICENSE) file for details.
324
1219
 
1220
+ Copyright © 2026 Litcode Private Limited. All rights reserved.
1221
+
325
1222
  ---
326
1223
 
327
- **Made with ❤️ by the Langctl team**
1224
+ <div align="center">
1225
+
1226
+ **Built with ❤️ by the Langctl team**
1227
+
1228
+ *Making translation management simple, fast, and developer-friendly.*
1229
+
1230
+ **[Get Started Free →](https://app.langctl.com/signup)**
1231
+
1232
+ </div>