Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .agents/skills/translation-diff-export/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,20 @@ pwsh ./.agents/skills/translation-diff-export/scripts/export-translation-diff.ps
-BaseRef origin/main
```

Export only the active section above the legacy boundary marker:

```powershell
pwsh ./.agents/skills/translation-diff-export/scripts/export-translation-diff.ps1 \
-NeutralJson ./src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_en.json \
-TargetJson ./src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_fr.json \
-Language fr \
-ActiveOnly
```

Optional parameters:

- `-OutputDir` (default: `generated/translation-diff-export`)
- `-ActiveOnly` (limits `.source.json` and `.reference.json` to keys above `__LEGACY_TRANSLATION_KEYS_BELOW__`)
- `-KeepIntermediate`

Run the built-in smoke test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ param(

[string]$OutputDir = 'generated/translation-diff-export',

[switch]$ActiveOnly,

[switch]$KeepIntermediate
)

Expand Down Expand Up @@ -326,6 +328,34 @@ function Sync-TranslatedWorkingCopy {
Write-OrderedJsonMap -Path $TranslatedPatchPath -Map $syncedMap
}

function Get-FilteredPatchMap {
param(
[Parameter(Mandatory = $true)]
[System.Collections.IDictionary]$Map,

[Parameter(Mandatory = $true)]
[System.Collections.IDictionary]$NeutralMap,

[Parameter(Mandatory = $true)]
[switch]$ActiveOnly
)

if (-not $ActiveOnly.IsPresent) {
return $Map
}

$activeKeys = Split-TranslationMapAtBoundary -Map $NeutralMap
$filteredMap = New-OrderedStringMap
foreach ($entry in $activeKeys.ActiveMap.GetEnumerator()) {
$key = [string]$entry.Key
if ($Map.Contains($key)) {
$filteredMap[$key] = [string]$Map[$key]
}
}

return $filteredMap
}

Assert-Command -Name 'git'
Assert-Command -Name 'cirup'

Expand Down Expand Up @@ -431,6 +461,9 @@ foreach ($entry in $neutralMap.GetEnumerator()) {
}
}

$sourcePatchMap = Get-FilteredPatchMap -Map $sourcePatchMap -NeutralMap $neutralMap -ActiveOnly:$ActiveOnly
$referencePatchMap = Get-FilteredPatchMap -Map $referencePatchMap -NeutralMap $neutralMap -ActiveOnly:$ActiveOnly

if (Test-Path -Path $sourcePatchPath -PathType Leaf) {
$previousSourceMap = Read-OrderedJsonMap -Path $sourcePatchPath
}
Expand Down Expand Up @@ -460,6 +493,9 @@ Write-Output "Created source patch: $sourcePatchPath"
Write-Output "Refreshed translated working copy: $translatedPatchPath"
Write-Output "Created reference patch: $referencePatchPath"
Write-Output "Created translation handoff prompt: $promptPath"
if ($ActiveOnly.IsPresent) {
Write-Output 'Patch scope: active translation keys only'
}
if ($KeepIntermediate.IsPresent) {
Write-Output "Kept intermediate files under: $tmpRoot"
}
48 changes: 48 additions & 0 deletions .github/workflows/translation-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Translation Validation

on:
push:
branches: [ "main" ]
paths:
- 'scripts/translation/**'
- '.agents/skills/translation-*/scripts/**'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Languages/**'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Data/LanguagesReference.json'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Data/TranslatedPercentages.json'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Data/Translators.json'
- 'src/UniGetUI.Core.Data/Assets/Data/Contributors.list'
- '.github/workflows/translation-validation.yml'

pull_request:
branches: [ "main" ]
paths:
- 'scripts/translation/**'
- '.agents/skills/translation-*/scripts/**'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Languages/**'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Data/LanguagesReference.json'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Data/TranslatedPercentages.json'
- 'src/UniGetUI.Core.LanguageEngine/Assets/Data/Translators.json'
- 'src/UniGetUI.Core.Data/Assets/Data/Contributors.list'
- '.github/workflows/translation-validation.yml'

workflow_dispatch:

jobs:
validate-translations:
runs-on: windows-latest

steps:
- name: Checkout the repository
uses: actions/checkout@v6

- name: Validate translation file structure
shell: pwsh
run: pwsh ./scripts/translation/Verify-Translations.ps1

- name: Validate boundary alignment
shell: pwsh
run: pwsh ./scripts/translation/Set-TranslationBoundaryOrder.ps1 -CheckOnly

- name: Validate translation metadata drift
shell: pwsh
run: pwsh ./scripts/translation/Sync-TranslationMetadata.ps1 -AllLanguages -CheckOnly
87 changes: 15 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ With UniGetUI, you can discover, install, update, and uninstall software from mu
![image](https://github.com/user-attachments/assets/7cb447ca-ee8b-4bce-8561-b9332fb0139a)
View more screenshots [here](#screenshots)

Check out the [Supported Package Managers Table](#supported-package-managers) for more details!
Check out the [Package Managers](#package-managers) section for more details!

**Disclaimer:** UniGetUI is not affiliated with the package managers it integrates with. Packages are provided by third parties, so review sources and publishers before installation.

Expand All @@ -44,8 +44,8 @@ Read more in the [Devolutions announcement](https://devolutions.net/blog/2026/03
- [Update UniGetUI](#update-unigetui)
- [Project stewardship](#project-stewardship)
- [Features](#features)
- [Supported Package Managers](#supported-package-managers)
- [Translations](#translations)
- [Package Managers](#package-managers)
- [Translations](TRANSLATION.md)
- [Contributors](#contributors)
- [Screenshots](#screenshots)
- [Frequently Asked Questions](#frequently-asked-questions)
Expand Down Expand Up @@ -102,7 +102,7 @@ UniGetUI has a built-in autoupdater. However, it can also be updated like any ot
- Export custom lists of packages to then import them to another machine and install those packages with previously specified, custom installation parameters. Setting up machines or configuring a specific software setup has never been easier.
- Backup your packages to a local file to easily recover your setup in a matter of seconds when migrating to a new machine*

## Supported Package Managers
## Package Managers

**NOTE:** All package managers do support basic install, update, and uninstall processes, as well as checking for updates, finding new packages, and retrieving details from a package.

Expand All @@ -114,74 +114,11 @@ UniGetUI has a built-in autoupdater. However, it can also be updated like any ot
❌: Not supported by the Package Manager<br>
<br>

# Translations

UniGetUI translations are maintained directly in this repository. All supported languages are kept at 100% completion with AI instead of shipping partial translations. If you spot a mistake or want to improve a translation, please open a GitHub issue or submit a pull request.

- <img src='https://flagcdn.com/za.svg' width=20> [Afrikaans](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_af.json)
- <img src='https://flagcdn.com/al.svg' width=20> [Albanian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_sq.json)
- <img src='https://flagcdn.com/sa.svg' width=20> [Arabic](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ar.json)
- <img src='https://flagcdn.com/bd.svg' width=20> [Bangla](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_bn.json)
- <img src='https://flagcdn.com/by.svg' width=20> [Belarusian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_be.json)
- <img src='https://flagcdn.com/bg.svg' width=20> [Bulgarian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_bg.json)
- <img src='https://flagcdn.com/ad.svg' width=20> [Catalan](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ca.json)
- <img src='https://flagcdn.com/hr.svg' width=20> [Croatian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_hr.json)
- <img src='https://flagcdn.com/cz.svg' width=20> [Czech](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_cs.json)
- <img src='https://flagcdn.com/dk.svg' width=20> [Danish](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_da.json)
- <img src='https://flagcdn.com/nl.svg' width=20> [Dutch](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_nl.json)
- <img src='https://flagcdn.com/gb.svg' width=20> [English](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_en.json)
- <img src='https://flagcdn.com/ee.svg' width=20> [Estonian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_et.json)
- <img src='https://flagcdn.com/fil.svg' width=20> [Filipino](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_fil.json)
- <img src='https://flagcdn.com/fi.svg' width=20> [Finnish](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_fi.json)
- <img src='https://flagcdn.com/fr.svg' width=20> [French](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_fr.json)
- <img src='https://flagcdn.com/ka.svg' width=20> [Georgian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ka.json)
- <img src='https://flagcdn.com/de.svg' width=20> [German](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_de.json)
- <img src='https://flagcdn.com/gr.svg' width=20> [Greek](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_el.json)
- <img src='https://flagcdn.com/in.svg' width=20> [Gujarati](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_gu.json)
- <img src='https://flagcdn.com/il.svg' width=20> [Hebrew](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_he.json)
- <img src='https://flagcdn.com/in.svg' width=20> [Hindi](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_hi.json)
- <img src='https://flagcdn.com/hu.svg' width=20> [Hungarian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_hu.json)
- <img src='https://flagcdn.com/id.svg' width=20> [Indonesian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_id.json)
- <img src='https://flagcdn.com/it.svg' width=20> [Italian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_it.json)
- <img src='https://flagcdn.com/jp.svg' width=20> [Japanese](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ja.json)
- <img src='https://flagcdn.com/in.svg' width=20> [Kannada](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_kn.json)
- <img src='https://flagcdn.com/kr.svg' width=20> [Korean](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ko.json)
- <img src='https://flagcdn.com/lt.svg' width=20> [Lithuanian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_lt.json)
- <img src='https://flagcdn.com/mk.svg' width=20> [Macedonian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_mk.json)
- <img src='https://flagcdn.com/no.svg' width=20> [Norwegian (bokmal)](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_nb.json)
- <img src='https://flagcdn.com/no.svg' width=20> [Norwegian (nynorsk)](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_nn.json)
- <img src='https://flagcdn.com/ir.svg' width=20> [Persian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_fa.json)
- <img src='https://flagcdn.com/pl.svg' width=20> [Polish](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_pl.json)
- <img src='https://flagcdn.com/br.svg' width=20> [Portuguese (Brazil)](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_pt_BR.json)
- <img src='https://flagcdn.com/pt.svg' width=20> [Portuguese (Portugal)](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_pt_PT.json)
- <img src='https://flagcdn.com/ro.svg' width=20> [Romanian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ro.json)
- <img src='https://flagcdn.com/ru.svg' width=20> [Russian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ru.json)
- <img src='https://flagcdn.com/in.svg' width=20> [Sanskrit](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_sa.json)
- <img src='https://flagcdn.com/rs.svg' width=20> [Serbian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_sr.json)
- <img src='https://flagcdn.com/lk.svg' width=20> [Sinhala](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_si.json)
- <img src='https://flagcdn.com/cn.svg' width=20> [Simplified Chinese (China)](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_zh_CN.json)
- <img src='https://flagcdn.com/sk.svg' width=20> [Slovak](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_sk.json)
- <img src='https://flagcdn.com/si.svg' width=20> [Slovene](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_sl.json)
- <img src='https://flagcdn.com/es.svg' width=20> [Spanish](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_es.json)
- <img src='https://flagcdn.com/se.svg' width=20> [Swedish](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_sv.json)
- <img src='https://flagcdn.com/ph.svg' width=20> [Tagalog](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_tg.json)
- <img src='https://flagcdn.com/ta.svg' width=20> [Tamil](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ta.json)
- <img src='https://flagcdn.com/th.svg' width=20> [Thai](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_th.json)
- <img src='https://flagcdn.com/tw.svg' width=20> [Traditional Chinese (Taiwan)](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_zh_TW.json)
- <img src='https://flagcdn.com/tr.svg' width=20> [Turkish](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_tr.json)
- <img src='https://flagcdn.com/ua.svg' width=20> [Ukrainian](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ua.json)
- <img src='https://flagcdn.com/pk.svg' width=20> [Urdu](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_ur.json)
- <img src='https://flagcdn.com/vn.svg' width=20> [Vietnamese](src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_vi.json)


# Contributions
UniGetUI wouldn't have been possible without the help of our dear contributors. From the person who fixed a typo to the person who improved half of the code, UniGetUI wouldn't be possible without them! :smile:<br><br>

## Contributors:
[![My dear contributors](https://contrib.rocks/image?repo=Devolutions/UniGetUI)](https://github.com/Devolutions/UniGetUI/graphs/contributors)<br><br>

## Translations

UniGetUI translations are maintained directly in this repository. For the current language list, completion status, and per-language contributor attributions, see [TRANSLATION.md](TRANSLATION.md). If you spot a translation issue or want to improve a locale, please open an issue or submit a pull request.

# Screenshots
## Screenshots

![image](media/UniGetUI_1.png)

Expand All @@ -204,7 +141,13 @@ UniGetUI translations are maintained directly in this repository. All supported
![image](media/UniGetUI_10.png)


# Frequently asked questions
## Contributions
UniGetUI continues to grow thanks to its community of contributors. Devolutions is grateful to everyone who contributes code, translations, documentation, testing, and feedback to the project.<br><br>

[![Contributors](https://contrib.rocks/image?repo=Devolutions/UniGetUI)](https://github.com/Devolutions/UniGetUI/graphs/contributors)<br><br>


## Frequently asked questions

**Q: I am unable to install or upgrade a specific Winget package! What should I do?**<br>

Expand Down
Loading
Loading