id = "crowdin"
name = "Crowdin CLI"
homepage = "https://github.com/crowdin/crowdin-cli"
description = "A command-line client for the Crowdin API."
executables = ["crowdin"]
[dotfiles]
paths = ["~/.crowdin.yaml"]
exclude = []
secret = []
side_effect = false
[[dotfiles.secret_paths]]
file = "~/.crowdin.yaml"
match = { key_path = ["api_key"] }
[commands]
format = 1
label = "Sync localization files"
description = "Upload source files to, or download translations from, a Crowdin project. Credentials normally come from crowdin.yml or the identity file, so --token is left out; other subcommands are not covered."
quality = "ai-draft"
parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = false }
[[commands.subcommand]]
path = ["upload", "sources"]
label = "Upload source files"
[[commands.subcommand.source]]
id = "docs"
kind = "manual"
url = "https://crowdin.github.io/crowdin-cli/commands/crowdin-upload-sources"
revision = "2026-10-27"
evidence = """
crowdin upload sources [OPTIONS]
-b, --branch=…
--label=…
--delete-obsolete
--no-auto-update
--cache
--dryrun
-c, --config=…
-i, --project-id=…
"""
[[commands.subcommand.field]]
id = "branch"
label = "Branch"
type = "string"
option = ["--branch", "-b"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "label"
label = "Labels"
description = "Attach labels to strings."
type = "string"
option = ["--label"]
multiple = true
sources = ["docs"]
[[commands.subcommand.field]]
id = "config"
label = "Config file"
type = "path"
option = ["--config", "-c"]
path = { kind = "file", role = "input", must_exist = true }
sources = ["docs"]
[[commands.subcommand.field]]
id = "project_id"
label = "Project ID"
type = "integer"
option = ["--project-id", "-i"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "delete_obsolete"
label = "Delete obsolete files"
description = "Remove files and folders from the Crowdin project that no longer match the source configuration."
type = "boolean"
option = ["--delete-obsolete"]
effect = "delete"
sources = ["docs"]
[[commands.subcommand.field]]
id = "no_auto_update"
label = "Only upload new files"
type = "boolean"
option = ["--no-auto-update"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "cache"
label = "Skip unchanged files"
type = "boolean"
option = ["--cache"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "dryrun"
label = "Dry run"
type = "boolean"
option = ["--dryrun"]
sources = ["docs"]
[[commands.subcommand.task]]
id = "preview"
label = "Preview upload"
fields = ["branch", "config", "dryrun"]
required = []
set = { dryrun = [true] }
[[commands.subcommand.task]]
id = "upload"
label = "Upload sources"
fields = ["branch", "config", "cache", "label"]
required = []
[[commands.subcommand.group]]
id = "basic"
label = "Basic"
fields = ["branch", "config", "project_id", "dryrun"]
[[commands.subcommand.group]]
id = "advanced"
label = "Advanced"
fields = ["label", "delete_obsolete", "no_auto_update", "cache"]
[[commands.subcommand]]
path = ["download"]
label = "Download translations"
[[commands.subcommand.source]]
id = "docs"
kind = "manual"
url = "https://crowdin.github.io/crowdin-cli/commands/crowdin-download"
revision = "2026-10-27"
evidence = """
crowdin download [SUBCOMMAND] [OPTIONS]
-b, --branch=…
-l, --language=…
-e, --exclude-language=…
--pseudo
--skip-untranslated-strings
--skip-untranslated-files
--export-only-approved
--keep-archive
--dryrun
-c, --config=…
-i, --project-id=…
"""
[[commands.subcommand.field]]
id = "branch"
label = "Branch"
type = "string"
option = ["--branch", "-b"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "language"
label = "Languages"
description = "Download only these languages."
type = "string"
option = ["--language", "-l"]
multiple = true
sources = ["docs"]
[[commands.subcommand.field]]
id = "exclude_language"
label = "Skip languages"
type = "string"
option = ["--exclude-language", "-e"]
multiple = true
sources = ["docs"]
[[commands.subcommand.field]]
id = "config"
label = "Config file"
type = "path"
option = ["--config", "-c"]
path = { kind = "file", role = "input", must_exist = true }
sources = ["docs"]
[[commands.subcommand.field]]
id = "project_id"
label = "Project ID"
type = "integer"
option = ["--project-id", "-i"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "skip_untranslated_files"
label = "Skip files not fully translated"
type = "boolean"
option = ["--skip-untranslated-files"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "skip_untranslated_strings"
label = "Skip untranslated strings"
type = "boolean"
option = ["--skip-untranslated-strings"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "export_only_approved"
label = "Approved translations only"
type = "boolean"
option = ["--export-only-approved"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "pseudo"
label = "Pseudo-localized files"
type = "boolean"
option = ["--pseudo"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "keep_archive"
label = "Keep downloaded archive"
type = "boolean"
option = ["--keep-archive"]
sources = ["docs"]
[[commands.subcommand.field]]
id = "dryrun"
label = "Dry run"
type = "boolean"
option = ["--dryrun"]
sources = ["docs"]
[[commands.subcommand.task]]
id = "all"
label = "Download all translations"
fields = ["branch", "config"]
required = []
[[commands.subcommand.task]]
id = "approved"
label = "Approved only"
fields = ["branch", "language", "config", "export_only_approved", "skip_untranslated_files"]
required = []
set = { export_only_approved = [true] }
[[commands.subcommand.group]]
id = "basic"
label = "Basic"
fields = ["branch", "language", "exclude_language", "config", "project_id", "dryrun"]
[[commands.subcommand.group]]
id = "advanced"
label = "Advanced"
fields = ["skip_untranslated_files", "skip_untranslated_strings", "export_only_approved", "pseudo", "keep_archive"]