langctl 0.1.0 β†’ 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
@@ -18,170 +29,784 @@ npx langctl --help
18
29
 
19
30
  ## Quick Start
20
31
 
21
- ### 1. Initialize Configuration
32
+ ### 1. Get Your API Key
33
+
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!)
22
38
 
23
- Run the interactive setup wizard to configure Langctl:
39
+ ### 2. Authenticate
24
40
 
25
41
  ```bash
42
+ # Interactive setup
26
43
  langctl init
44
+
45
+ # Or authenticate directly
46
+ langctl auth lc_your_api_key_here
27
47
  ```
28
48
 
29
- This will:
30
- - Configure Supabase connection (uses defaults)
31
- - Authenticate with your API key (get one from the dashboard)
32
- - Set your default language preference
49
+ ### 3. Explore Your Organization
33
50
 
34
- ### 2. List Your Projects
51
+ ```bash
52
+ # View organization info
53
+ langctl org info
35
54
 
36
- View all projects you have access to:
55
+ # Check statistics
56
+ langctl org stats
37
57
 
38
- ```bash
58
+ # List your projects
39
59
  langctl projects list
40
60
  ```
41
61
 
42
- ### 3. Pull Translations
43
-
44
- Download translations for a project:
62
+ ### 4. Start Working with Translations
45
63
 
46
64
  ```bash
47
- 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!"
48
75
  ```
49
76
 
50
- ## Commands
77
+ ---
78
+
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
51
91
 
52
- ### `langctl init`
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
53
101
 
54
- Interactive setup wizard to configure the CLI.
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
126
+
127
+ ### Authentication Commands
128
+
129
+ #### `langctl init`
130
+
131
+ Interactive setup wizard that guides you through authentication and configuration.
55
132
 
56
133
  ```bash
57
134
  langctl init
58
135
  ```
59
136
 
60
- ### `langctl auth <api-key>`
137
+ #### `langctl auth <api-key>`
61
138
 
62
- Authenticate with an API key from the dashboard.
139
+ Authenticate with an API key from your dashboard.
63
140
 
64
141
  ```bash
65
142
  langctl auth lc_abc123...
66
143
  ```
67
144
 
68
- ### `langctl logout`
145
+ #### `langctl logout`
69
146
 
70
- Clear authentication credentials.
147
+ Clear stored authentication credentials.
71
148
 
72
149
  ```bash
73
150
  langctl logout
74
151
  ```
75
152
 
76
- ### `langctl config`
153
+ #### `langctl config`
77
154
 
78
- View current configuration.
155
+ Display current configuration (API key, organization, etc.).
79
156
 
80
157
  ```bash
81
158
  langctl config
82
159
  ```
83
160
 
84
- ### `langctl projects list`
161
+ ---
162
+
163
+ ### Organization Commands
164
+
165
+ #### `langctl org info`
85
166
 
86
- Show all accessible projects.
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`
195
+
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.
87
216
 
88
217
  ```bash
89
218
  langctl projects list
90
219
  ```
91
220
 
92
- ### `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>`
93
349
 
94
- Pull translations from a project.
350
+ View project statistics.
95
351
 
96
352
  ```bash
97
- langctl pull <project-id> [options]
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
98
372
  ```
99
373
 
100
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
101
392
 
102
- - `-l, --language <code>` - Language code to pull (default: en)
103
- - `-f, --format <type>` - Export format (default: json)
104
- - `json` - Flat JSON (key-value pairs)
105
- - `json-nested` - Nested JSON (organized by key structure)
106
- - `ios` - iOS .strings format
107
- - `android` - Android XML format
108
- - `flutter` - Flutter ARB format
109
- - `-o, --output <path>` - Output file path (default: ./translations/<filename>)
110
- - `--no-published-only` - Include unpublished translations
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.
111
441
 
112
442
  **Examples:**
113
443
 
114
444
  ```bash
115
- # Pull English translations as JSON
116
- langctl pull abc-123 --language en --format json
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
+ ```
117
462
 
118
- # Pull Spanish translations as iOS strings
119
- langctl pull abc-123 --language es --format ios
463
+ #### `langctl keys delete <project> <key>`
120
464
 
121
- # Pull all translations (including unpublished)
122
- langctl pull abc-123 --language en --no-published-only
465
+ Delete a translation key.
123
466
 
124
- # Custom output path
125
- langctl pull abc-123 --language en --output ./locales/en.json
467
+ ```bash
468
+ langctl keys delete my-app home.welcome
126
469
  ```
127
470
 
128
- ## Export Formats
471
+ #### `langctl keys translate <project> <key>`
129
472
 
130
- ### JSON (Flat)
473
+ Update the translation value for a specific language.
131
474
 
132
- Simple key-value pairs with dot notation.
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
+ ---
527
+
528
+ ### Team Management Commands
529
+
530
+ #### `langctl team list`
531
+
532
+ List all team members in your organization.
533
+
534
+ ```bash
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
557
+ ```
558
+
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:**
566
+
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`
597
+
598
+ **Examples:**
599
+
600
+ ```bash
601
+ # Promote to admin
602
+ langctl team update-role user@example.com admin
603
+
604
+ # Demote to viewer
605
+ langctl team update-role user@example.com viewer
606
+ ```
607
+
608
+ #### `langctl team invitations`
609
+
610
+ List all invitations (pending, accepted, or cancelled).
611
+
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
629
+ ```
630
+
631
+ ---
632
+
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:**
133
715
 
134
716
  ```json
717
+ // Flat format (recommended)
135
718
  {
136
719
  "home.welcome": "Welcome!",
137
- "home.subtitle": "Get started with {{appName}}"
720
+ "home.subtitle": "Get started",
721
+ "button.submit": "Submit"
722
+ }
723
+
724
+ // Nested format (auto-flattened)
725
+ {
726
+ "home": {
727
+ "welcome": "Welcome!",
728
+ "subtitle": "Get started"
729
+ },
730
+ "button": {
731
+ "submit": "Submit"
732
+ }
138
733
  }
139
734
  ```
140
735
 
141
- ### JSON (Nested)
736
+ ---
142
737
 
143
- Organized by key structure.
738
+ ## Export Format Examples
739
+
740
+ ### Flat JSON (Default)
741
+
742
+ ```json
743
+ {
744
+ "home.welcome": "Welcome!",
745
+ "home.subtitle": "Get started with {{appName}}",
746
+ "button.submit": "Submit"
747
+ }
748
+ ```
749
+
750
+ ### Nested JSON
144
751
 
145
752
  ```json
146
753
  {
147
754
  "home": {
148
755
  "welcome": "Welcome!",
149
756
  "subtitle": "Get started with {{appName}}"
757
+ },
758
+ "button": {
759
+ "submit": "Submit"
150
760
  }
151
761
  }
152
762
  ```
153
763
 
154
- ### iOS Strings
764
+ ### i18next JSON
155
765
 
156
- Standard iOS .strings format.
766
+ ```json
767
+ {
768
+ "home": {
769
+ "welcome": "Welcome!",
770
+ "subtitle": "Get started with {{appName}}"
771
+ }
772
+ }
773
+ ```
774
+
775
+ ### iOS Strings
157
776
 
158
777
  ```
778
+ /* Welcome message */
159
779
  "home.welcome" = "Welcome!";
160
- "home.subtitle" = "Get started with %1$@";
780
+
781
+ /* Homepage subtitle with app name placeholder */
782
+ "home.subtitle" = "Get started with %@";
161
783
  ```
162
784
 
163
785
  ### Android XML
164
786
 
165
- Android resources XML format.
166
-
167
787
  ```xml
168
788
  <?xml version="1.0" encoding="utf-8"?>
169
789
  <resources>
790
+ <!-- Welcome message -->
170
791
  <string name="home.welcome">Welcome!</string>
792
+
793
+ <!-- Homepage subtitle with app name placeholder -->
171
794
  <string name="home.subtitle">Get started with %1$s</string>
172
795
  </resources>
173
796
  ```
174
797
 
175
798
  ### Flutter ARB
176
799
 
177
- Application Resource Bundle format for Flutter.
178
-
179
800
  ```json
180
801
  {
181
802
  "@@locale": "en",
182
803
  "home.welcome": "Welcome!",
804
+ "@home.welcome": {
805
+ "description": "Welcome message"
806
+ },
183
807
  "home.subtitle": "Get started with {appName}",
184
808
  "@home.subtitle": {
809
+ "description": "Homepage subtitle",
185
810
  "placeholders": {
186
811
  "appName": {
187
812
  "type": "String"
@@ -191,36 +816,101 @@ Application Resource Bundle format for Flutter.
191
816
  }
192
817
  ```
193
818
 
194
- ## Configuration
819
+ ---
195
820
 
196
- Configuration is stored in `~/.langctl/config.json`:
821
+ ## Real-World Workflows
197
822
 
198
- ```json
199
- {
200
- "supabaseUrl": "https://xxx.supabase.co",
201
- "supabaseAnonKey": "eyJ...",
202
- "apiKey": "lc_...",
203
- "organizationId": "uuid",
204
- "organizationName": "Company Name",
205
- "defaultProject": "uuid",
206
- "defaultLanguage": "en"
207
- }
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
208
885
  ```
209
886
 
210
- ## API Keys
887
+ ### Multi-Platform Export
211
888
 
212
- Generate API keys from the Langctl dashboard:
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
213
899
 
214
- 1. Go to Settings β†’ API Keys
215
- 2. Click "Generate New Key"
216
- 3. Copy the key (shown only once)
217
- 4. Use it with `langctl auth <key>` or `langctl init`
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
+ ```
218
906
 
219
- API keys are organization-scoped and provide access to all projects within that organization.
907
+ ---
220
908
 
221
909
  ## CI/CD Integration
222
910
 
223
- Example GitHub Actions workflow:
911
+ ### GitHub Actions
912
+
913
+ Automated translation sync workflow:
224
914
 
225
915
  ```yaml
226
916
  name: Sync Translations
@@ -228,10 +918,10 @@ name: Sync Translations
228
918
  on:
229
919
  schedule:
230
920
  - cron: '0 0 * * *' # Daily at midnight
231
- workflow_dispatch:
921
+ workflow_dispatch: # Manual trigger
232
922
 
233
923
  jobs:
234
- sync:
924
+ sync-translations:
235
925
  runs-on: ubuntu-latest
236
926
  steps:
237
927
  - uses: actions/checkout@v3
@@ -244,69 +934,258 @@ jobs:
244
934
  - name: Install Langctl
245
935
  run: npm install -g langctl
246
936
 
247
- - name: Configure Langctl
937
+ - name: Authenticate
248
938
  env:
249
939
  LANGCTL_API_KEY: ${{ secrets.LANGCTL_API_KEY }}
250
940
  run: langctl auth $LANGCTL_API_KEY
251
941
 
252
- - name: Pull Translations
942
+ - name: Export Translations
253
943
  run: |
254
- langctl pull ${{ secrets.PROJECT_ID }} --language en --format json
255
- 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
256
947
 
257
948
  - name: Commit Changes
258
949
  run: |
259
- git config --global user.name "Langctl Bot"
260
- git config --global user.email "bot@langctl.com"
261
- git add translations/
262
- 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]"
263
954
  git push
264
955
  ```
265
956
 
266
- ## Troubleshooting
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=""
267
989
 
268
- ### "Not authenticated" error
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
+ ```
994
+
995
+ ---
996
+
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
269
1038
 
270
- Run `langctl auth <api-key>` or `langctl init` to authenticate.
1039
+ 1. **Use appropriate roles**:
1040
+ - `viewer` - Stakeholders, reviewers (read-only)
1041
+ - `member` - Translators, content writers
1042
+ - `admin` - Project managers, team leads
271
1043
 
272
- ### "Supabase not configured" error
1044
+ 2. **Regular access reviews**:
1045
+ ```bash
1046
+ langctl team list
1047
+ langctl team invitations
1048
+ ```
273
1049
 
274
- Run `langctl init` to configure Supabase connection.
1050
+ ### Security
275
1051
 
276
- ### "Project not found" error
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
+ ```
277
1058
 
278
- - Verify the project ID with `langctl projects list`
279
- - Check that your API key has access to the organization
1059
+ 3. **Rotate keys periodically** from [app.langctl.com](https://app.langctl.com)
280
1060
 
281
- ### Invalid API key format
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
282
1065
 
283
- API keys should:
284
- - Start with `lc_`
285
- - Be 67 characters long
286
- - Be generated from the Langctl dashboard
1066
+ ---
287
1067
 
288
- ## Development
1068
+ ## Troubleshooting
1069
+
1070
+ ### Authentication Issues
289
1071
 
1072
+ **"Not authenticated" error:**
290
1073
  ```bash
291
- # Install dependencies
292
- npm install
1074
+ # Solution: Authenticate with your API key
1075
+ langctl auth lc_your_api_key_here
1076
+ ```
293
1077
 
294
- # Build TypeScript
295
- npm run build
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
296
1082
 
297
- # Run in development mode
298
- npm run dev
1083
+ ### Project Issues
1084
+
1085
+ **"Project not found" error:**
1086
+ ```bash
1087
+ # Check project slug (not name)
1088
+ langctl projects list
299
1089
 
300
- # Test CLI
301
- node dist/index.js --help
1090
+ # Use the slug shown in the list
1091
+ langctl keys list correct-slug-here
302
1092
  ```
303
1093
 
304
- ## Support
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
305
1126
 
1127
+ ---
1128
+
1129
+ ## FAQ
1130
+
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.
1133
+
1134
+ **Q: Can I use the CLI without installing it?**
1135
+ A: Yes! Use `npx langctl` instead of `langctl` for any command.
1136
+
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).
1154
+
1155
+ ---
1156
+
1157
+ ## Platform Support
1158
+
1159
+ - βœ… macOS (Apple Silicon & Intel)
1160
+ - βœ… Linux (x64, ARM64)
1161
+ - βœ… Windows (x64, ARM64)
1162
+ - βœ… Node.js 16.0.0 or higher
1163
+
1164
+ ---
1165
+
1166
+ ## Links
1167
+
1168
+ - **Website:** [langctl.com](https://langctl.com)
1169
+ - **Dashboard:** [app.langctl.com](https://app.langctl.com)
306
1170
  - **Documentation:** [langctl.com/docs](https://langctl.com/docs)
307
- - **Issues:** [github.com/siddharthsaxena0/langctl/issues](https://github.com/siddharthsaxena0/langctl/issues)
308
- - **Email:** hello@langctl.com
1171
+ - **GitHub:** [github.com/siddharthsaxena0/langctl](https://github.com/siddharthsaxena0/langctl)
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.
1180
+
1181
+ ---
309
1182
 
310
1183
  ## License
311
1184
 
312
- MIT Β© Siddharth Saxena
1185
+ MIT License - see [LICENSE](LICENSE) file for details.
1186
+
1187
+ ---
1188
+
1189
+ **Built with ❀️ by the Langctl team**
1190
+
1191
+ *Making translation management simple, fast, and developer-friendly.*