langctl 0.1.1 β†’ 0.1.2

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