import "@johnlindquist/kit"
const applicationsPath = "/Applications"
const outputDir = await env("APP_ICONS_OUTPUT_DIR", async () => {
return await path({
hint: "Select a folder to save app icons",
onlyDirs: true,
startPath: home("Desktop")
})
})
await ensureDir(outputDir)
const apps = await readdir(applicationsPath)
const appFiles = apps.filter(file => file.endsWith('.app'))
if (appFiles.length === 0) {
await div(md("No applications found in /Applications"))
exit()
}
let processed = 0
let successful = 0
let failed = 0
await div({
html: md(`# Extracting App Icons\n\nProcessing ${appFiles.length} applications...`),
onInit: async () => {
for (const appFile of appFiles) {
const appPath = path.join(applicationsPath, appFile)
const appName = path.basename(appFile, '.app')
try {
const iconPath = path.join(outputDir, `${appName}.png`)
await exec(`sips -s format png "${appPath}/Contents/Resources/*.icns" --out "${iconPath}" 2>/dev/null || true`)
try {
await exec(`iconutil -c png -o "${iconPath}" "${appPath}/Contents/Resources"/*.icns 2>/dev/null || true`)
} catch (e) {
await copyPathAsImage(appPath)
const iconBuffer = await clipboard.readImage()
if (iconBuffer && iconBuffer.length > 0) {
await writeFile(iconPath, iconBuffer)
}
}
if (await pathExists(iconPath)) {
successful++
} else {
failed++
}
} catch (error) {
console.log(`Failed to extract icon for ${appName}: ${error.message}`)
failed++
}
processed++
setPanel(md(`
## Progress: ${processed}/${appFiles.length}
ā
**Successful:** ${successful}
ā **Failed:** ${failed}
š± **Current:** ${appName}
`))
}
submit("complete")
}
})
await div(md(`
# Icon Extraction Complete!
## Results:
- **Total Apps:** ${appFiles.length}
- **Successfully Extracted:** ${successful}
- **Failed:** ${failed}
- **Output Directory:** ${outputDir}
The app icons have been saved as PNG files in your selected folder.
`))
await revealFile(outputDir)