Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure Qt Installer Framework for cross-platform installers with component management, online updates, and custom UI
.claude/skills/a5c-ai-qt-installer-framework-config/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 138% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 143% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 206% | 0% |
Configure Qt Installer Framework (IFW) for cross-platform installers. This skill generates installer configurations with component management, online updates, maintenance tool, and custom branding.
json{ "type": "object", "properties": { "projectPath": { "type": "string", "description": "Path to the project" }, "installerName": { "type": "string", "description": "Name of the installer" }, "appInfo": { "type": "object", "properties": { "name": { "type": "string" }, "version": { "type": "string" }, "publisher": { "type": "string" }, "url": { "type": "string" } }, "required": ["name", "version", "publisher"] }, "components": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "displayName": { "type": "string" }, "description": { "type": "string" }, "version": { "type": "string" }, "required": { "type": "boolean" }, "dependencies": { "type": "array" } } } }, "onlineRepository": { "type": "object", "properties": { "enabled": { "type": "boolean" }, "url": { "type": "string" } } }, "targetPlatforms": { "type": "array", "items": { "enum": ["windows", "macos", "linux"] } } }, "required": ["projectPath", "installerName", "appInfo"] }
json{ "type": "object", "properties": { "success": { "type": "boolean" }, "structure": { "type": "object", "properties": { "configDir": { "type": "string" }, "packagesDir": { "type": "string" } } }, "buildCommands": { "type": "object", "properties": { "offline": { "type": "string" }, "online": { "type": "string" }, "repository": { "type": "string" } } } }, "required": ["success"] }
installer/
├── config/
│ ├── config.xml
│ ├── controller.qs
│ └── style.qss
├── packages/
│ ├── com.company.app/
│ │ ├── meta/
│ │ │ ├── package.xml
│ │ │ ├── installscript.qs
│ │ │ └── license.txt
│ │ └── data/
│ │ └── [application files]
│ └── com.company.app.plugins/
│ ├── meta/
│ │ └── package.xml
│ └── data/
│ └── [plugin files]
└── build/
└── [generated installer]xml<?xml version="1.0" encoding="UTF-8"?> <Installer> <Name>My Application</Name> <Version>1.0.0</Version> <Title>My Application Installer</Title> <Publisher>My Company</Publisher> <StartMenuDir>My Application</StartMenuDir> <TargetDir>@HomeDir@/MyApplication</TargetDir> <!-- UI Customization --> <WizardStyle>Modern</WizardStyle> <StyleSheet>style.qss</StyleSheet> <TitleColor>#2196F3</TitleColor> <Logo>logo.png</Logo> <Watermark>watermark.png</Watermark> <Banner>banner.png</Banner> <!-- Behavior --> <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters> <AllowSpaceInPath>true</AllowSpaceInPath> <MaintenanceToolName>MaintenanceTool</MaintenanceToolName> <!-- Online Updates --> <RemoteRepositories> <Repository> <Url>https://updates.mycompany.com/repo</Url> <Enabled>1</Enabled> </Repository> </RemoteRepositories> <!-- Controller Script --> <ControlScript>controller.qs</ControlScript> </Installer>
xml<?xml version="1.0" encoding="UTF-8"?> <Package> <DisplayName>My Application</DisplayName> <Description>Main application component</Description> <Version>1.0.0</Version> <ReleaseDate>2024-01-15</ReleaseDate> <Name>com.company.app</Name> <Dependencies>com.company.app.runtime</Dependencies> <Default>true</Default> <Essential>true</Essential> <ForcedInstallation>true</ForcedInstallation> <!-- Platform-specific --> <Licenses> <License name="EULA" file="license.txt"/> </Licenses> <Script>installscript.qs</Script> </Package>
javascriptfunction Component() { // Constructor } Component.prototype.createOperations = function() { component.createOperations(); if (systemInfo.productType === "windows") { // Create Start Menu shortcut component.addOperation("CreateShortcut", "@TargetDir@/MyApp.exe", "@StartMenuDir@/My Application.lnk", "workingDirectory=@TargetDir@", "iconPath=@TargetDir@/MyApp.exe", "iconId=0", "description=Launch My Application"); // Create Desktop shortcut component.addOperation("CreateShortcut", "@TargetDir@/MyApp.exe", "@DesktopDir@/My Application.lnk"); // Register file association component.addOperation("RegisterFileType", "myapp", "@TargetDir@/MyApp.exe '%1'", "My Application File", "text/x-myapp", "@TargetDir@/MyApp.exe,0", "ProgId=MyCompany.MyApp"); } if (systemInfo.productType === "osx") { // macOS specific operations component.addOperation("Execute", "/bin/ln", "-s", "@TargetDir@/MyApp.app", "/Applications/MyApp.app"); } if (systemInfo.productType === "linux") { // Create .desktop file component.addOperation("CreateDesktopEntry", "@TargetDir@/myapp.desktop", "Type=Application\n" + "Name=My Application\n" + "Exec=@TargetDir@/MyApp\n" + "Icon=@TargetDir@/myapp.png\n" + "Categories=Utility;"); } }
javascriptfunction Controller() { installer.autoRejectMessageBoxes(); installer.installationFinished.connect(this, Controller.prototype.installationFinishedPageCallback); } Controller.prototype.IntroductionPageCallback = function() { // Skip intro page in unattended mode if (installer.isUnattended()) { gui.clickButton(buttons.NextButton); } } Controller.prototype.TargetDirectoryPageCallback = function() { // Set custom target directory var widget = gui.currentPageWidget(); widget.TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/MyApp"); } Controller.prototype.ComponentSelectionPageCallback = function() { // Pre-select components var widget = gui.currentPageWidget(); widget.selectAll(); } Controller.prototype.LicenseAgreementPageCallback = function() { gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); } Controller.prototype.installationFinishedPageCallback = function() { // Launch app after installation if (installer.isInstaller() && installer.status === QInstaller.Success) { var widget = gui.currentPageWidget(); if (widget.RunItCheckBox) { widget.RunItCheckBox.setChecked(true); } } }
bash# Build offline installer binarycreator -c config/config.xml -p packages MyAppInstaller # Build online installer (small, downloads components) binarycreator -c config/config.xml -p packages -n MyAppOnlineInstaller # Create/update repository repogen -p packages repository # Update existing repository repogen --update-new-components -p packages repository
bash# Initial repository creation repogen -p packages output/repository # Upload to server rsync -avz output/repository/ user@server:/var/www/updates/ # Update with new version repogen --update-new-components -p packages output/repository
qt-cmake-project-generator - Build system setupauto-update-system process - Update workflowwindows-authenticode-signer - Windows signingmacos-notarization-workflow - macOS notarizationqt-cpp-specialist - Qt expertiserelease-manager - Release workflow| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 13,212 | 9,239 | -30% | 1 | 1 | 0% | 3,317 | 4,909 | +48% | 0 | 0 | — |
case-02 | fail→pass | 7,928 | 9,104 | +15% | 1 | 1 | 0% | 2,059 | 4,903 | +138% | 0 | 0 | — |
case-03 | pass→pass | 7,454 | 11,925 | +60% | 1 | 1 | 0% | 1,543 | 4,720 | +206% | 0 | 0 | — |
case-04 | pass→pass | 5,665 | 6,195 | +9% | 1 | 1 | 0% | 1,203 | 3,920 | +226% | 0 | 0 | — |
case-05 | pass→pass | 11,934 | 8,618 | -28% | 1 | 1 | 0% | 2,693 | 3,955 | +47% | 0 | 0 | — |
case-06 | pass→pass | 4,624 | 4,017 | -13% | 1 | 1 | 0% | 924 | 3,176 | +244% | 0 | 0 | — |
case-07 | pass→pass | 5,775 | 3,948 | -32% | 1 | 1 | 0% | 1,163 | 3,124 | +169% | 0 | 0 | — |
case-08 | pass→pass | 7,663 | 4,324 | -44% | 1 | 1 | 0% | 1,521 | 3,036 | +100% | 0 | 0 | — |
case-09 | pass→pass | 9,577 | 7,221 | -25% | 1 | 1 | 0% | 1,906 | 3,743 | +96% | 0 | 0 | — |
case-10 | fail→pass | 6,676 | 4,733 | -29% | 1 | 1 | 0% | 1,361 | 3,304 | +143% | 0 | 0 | — |
case-11 | pass→pass | 6,471 | 5,223 | -19% | 1 | 1 | 0% | 1,259 | 3,367 | +167% | 0 | 0 | — |
case-12 | pass→pass | 6,152 | 3,541 | -42% | 1 | 1 | 0% | 1,201 | 2,810 | +134% | 0 | 0 | — |
case-13 | pass→pass | 2,741 | 2,625 | -4% | 1 | 1 | 0% | 494 | 2,922 | +491% | 0 | 0 | — |
case-14 | pass→pass | 8,321 | 4,109 | -51% | 1 | 1 | 0% | 1,544 | 3,124 | +102% | 0 | 0 | — |
case-15 | fail→pass | 11,719 | 2,750 | -77% | 1 | 1 | 0% | 1,890 | 2,802 | +48% | 0 | 0 | — |
case-16 | pass→pass | 4,701 | 4,625 | -2% | 1 | 1 | 0% | 715 | 3,194 | +347% | 0 | 0 | — |
case-17 | pass→pass | 6,192 | 4,730 | -24% | 1 | 1 | 0% | 1,187 | 3,301 | +178% | 0 | 0 | — |
case-18 | pass→pass | 4,149 | 2,476 | -40% | 1 | 1 | 0% | 739 | 2,767 | +274% | 0 | 0 | — |
case-19 | pass→pass | 4,647 | 2,876 | -38% | 1 | 1 | 0% | 982 | 2,933 | +199% | 0 | 0 | — |
case-20 | pass→pass | 6,271 | 4,830 | -23% | 1 | 1 | 0% | 1,287 | 3,090 | +140% | 0 | 0 | — |
case-21 | pass→pass | 10,892 | 6,624 | -39% | 1 | 1 | 0% | 1,765 | 3,567 | +102% | 0 | 0 | — |
case-22 | pass→pass | 6,212 | 5,604 | -10% | 1 | 1 | 0% | 1,184 | 3,462 | +192% | 0 | 0 | — |
case-23 | pass→pass | 5,173 | 10,560 | +104% | 1 | 1 | 0% | 851 | 2,906 | +241% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +17 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.