Back to projects

Case study · Personal project

Slugger: From Filename Cleanup to a Mac App

How a repetitive designer handoff became Slugger, a native Mac app for batch filename cleanup, safe previews, and optional AI naming from content.

Role
Product direction, workflow design, and AI-assisted development
Timeline
October 10, 2026 · Version 1.0
  • Swift
  • AppKit
  • Python
  • Claude Code
  • Codex

Slugger began with a small, recurring frustration: files arrived from designers with inconsistent names, and preparing them for the web meant opening, inspecting, and renaming them one by one. I wanted that effort to become a batch I could review.

At a glance

  • One file or a whole handoff. A native Mac interface previews original names, proposed names, and readiness before applying changes.

  • Predictable formatting stays local. Lowercase slugs, hyphens, accent handling, and optional extension normalization work without AI.

  • AI helps with meaning. Optional Claude or Codex suggestions use document excerpts or image previews to propose descriptive names.

  • Review remains the release gate. Conflicts are blocked, renaming requires an explicit action, and the last batch can be undone while the app stays open.

The starting view gives one clear next step: drop files into the window or choose Add Files. AI starts off, and Rename and Undo stay disabled until there is work to act on.

The problem behind the app

At work, I receive assets from designers whose filenames reflect their production process: spaces, mixed capitalization, punctuation, revision labels, and names that do not tell me much about the content. Before those files reach a website, I usually rename them by hand.

I care about SEO, but the practical goal starts with clarity. I want filenames that are readable in a URL, consistent across a site, and useful when I return to an asset later. That creates two different tasks: formatting a name correctly and deciding what the name should describe.

A script could handle the formatting. The slower part was looking at each file and choosing a useful name. My idea was to let AI assist with that judgment, then let deterministic rules turn the result into a filename I could use on the web.

From an app review to a product

The conversation began as a review of my Mac applications and workflow. The useful question became more specific: what repeated task still required too much attention? Consistent naming already mattered to how I used Finder and Spotlight. A small renaming tool was a direct way to improve that habit.

I first asked for a utility called Slugify that could rename a single file or a group while preserving extensions. That established the core contract: add or drop files, preview the changes, check for conflicts, and rename only when ready.

The next requests came from the actual workflow. I wanted uppercase image extensions normalized, a cleaner interface, and optional AI suggestions based on file contents. Image naming then needed visual understanding, so a photograph with an opaque filename could receive a subject-based suggestion instead of simply a tidier version of its old name.

The app became Slugger and its version was reset to 1.0. The app review was the starting point; the result was a focused tool built around one recurring handoff.

My role and implementation choices

I defined the problem, directed the feature sequence, reviewed the interface and icon, and used Codex to implement and check the application. Each refinement came from a concrete use case: preserve extensions first, make normalization a preference, put previews first, and keep AI suggestions separate from the action that changes files.

A Python script would have been enough for basic filename cleanup. The delivered app uses Swift and AppKit for the native interface and rename logic; Python handles build and packaging. That gives the workflow a drop target, native file picker, keyboard shortcuts, and a visible preview without needing a terminal for each batch.

The repository keeps the implementation small: one Swift source file, icon and application metadata, a Python build script, and usage documentation. It has no third-party runtime libraries. The public MIT-licensed repository makes the source available to inspect, build, and adapt.

A small interface with a clear hierarchy

The first interface spent too much space explaining the tool. The revised layout gives the files the most room: a compact toolbar, extension preference, optional AI controls, and a table that puts the before and after side by side.

The primary rename action sits at the bottom right, alongside Undo. The empty state accepts dropped files, and keyboard shortcuts cover adding files, renaming, and undoing. A Settings menu that did not open a settings window was removed; the relevant preference is already visible in the main workflow.

Safety is part of that interface. Slugger blocks conflicting destinations instead of overwriting files or silently inventing numbered names. It does not rename folders or follow symbolic links. Undo covers the last successful batch while the application remains open, so it is a useful recovery action with a deliberately limited history.

Predictable rules before AI

Slugger lowercases the filename stem, removes accents, transliterates supported scripts to Latin, and replaces spaces and punctuation with hyphens. It preserves the final extension by default and keeps files in their original folders.

The main workflow makes a batch reviewable: original name, new name, and status share one row. These sample handoff filenames demonstrate local formatting; AI is off.

The saved Lowercase extensions preference lowercases extensions and normalizes JPEG variants to .jpg. That changes the name, not the image format or file contents. Undo restores the original extension as well as the stem.

Extension normalization is an explicit preference, and the preview updates before any files change. The same batch can preserve extensions or make them consistent with web publishing conventions.

Formatting alone cannot remove every weak name. homepage-hero-final-02.jpg is consistent, but still carries a revision label and says little about the image. That is where content-aware suggestions become useful.

AI proposes; I decide

AI is off by default. Choosing Claude or Codex and clicking Suggest Names uses the installed command-line tool and its active sign-in. Slugger does not extract or store the provider’s credentials.

For images, the app sends a resized visual preview with metadata removed. For supported text files and PDFs, it sends bounded excerpts, including text from the first three PDF pages. Requests support up to 25 files, with up to 8,000 characters per file; Office documents are not parsed.

For a concrete example, I gave Slugger a copy of its mascot artwork named Export 001.PNG. Ordinary formatting produced export-001.PNG. After inspecting the image, Codex suggested cartoon-slug-with-baseball-bat-and-blue-cap.PNG: a description of the visible subject, with the original extension preserved.

A real Codex suggestion from the mascot image: Export 001.PNG becomes cartoon-slug-with-baseball-bat-and-blue-cap.PNG in the preview. The file has not been renamed; the status asks me to review the suggestion first.

The suggestion supplies meaning that formatting alone cannot recover from an export number. It still needs review: a model can describe what is visible, but it may miss the asset’s purpose, campaign context, or the naming convention I want to use.

Suggestions return to the same preview and conflict checks as ordinary formatting. Reset restores the regular slugified names, Cancel stops an active request, and Rename remains a separate decision. Only choosing AI sends filenames and the supported content to the selected provider; ordinary renaming stays local.

The development checks recorded in the project conversation included both providers suggesting names from contents, visual naming of a test image, and applying and undoing a suggested rename. The app also includes local self-tests for formatting, collisions, content preservation, AI response validation, cancellation, and image metadata removal.

Giving Slugger an identity

The baseball slug makes the name memorable: a friendly mascot for a practical utility, with a strong silhouette that works at Dock size.

The name connects a web slug with a baseball slugger. The final icon is a smiling cream-colored slug wearing a blue cap and holding a golden bat, with glossy eyes at the ends of its antennae. A calmer violet background gives the mascot room to read.

The icon evolved through several rounds: a filename mark, a simple slug, then the baseball character. I reviewed the expression, eye placement, background intensity, and outer edge. The final artwork uses a full square canvas so macOS handles the outer shape, resolving the rough rim in the earlier masked version.

The result gives Slugger personality without making the working interface busier. The current app uses a static icon; a compiled layered icon remains a possible future improvement.

What version 1.0 delivers

Slugger turns repeated manual cleanup into a previewable batch, with optional help choosing more descriptive names. It brings formatting, content-based suggestions, conflict checks, and undo into one native workflow.

The intended benefit is fewer repetitive edits and less time inspecting assets one at a time. I have not measured time saved or changes in search performance. The demonstrated outcome is the working tool and its source; measuring a representative designer handoff against my previous process is the next step toward quantifying the benefit.

The GitHub repository includes build instructions and the MIT license. Building from source is distinct from distributing a finished download: a broadly distributed Mac release would need Developer ID signing and notarization.

Proposed roadmap

These are directions for future versions, not features shipped in 1.0. I would prioritize improvements that make reviewing a real handoff faster while preserving control over the final names.

  • Naming presets and project context. Saved conventions for client, campaign, locale, and asset purpose could guide both deterministic formatting and AI suggestions. A useful next step is letting me exclude revision words and set a preferred naming length.
  • A richer review step. Image thumbnails, editable suggestions, and per-file acceptance could make it easier to judge a name without opening another application. AI should help describe what is visible; I should supply context it cannot infer.
  • Finder integration. A Quick Action or share extension could open selected files directly in Slugger, shortening the path from designer delivery to a reviewed batch.
  • Durable recovery and rename records. A persistent batch history and exportable old-to-new mapping could support recovery after relaunch and help update references when assets already appear in a website.
  • Clearer AI setup and larger handoffs. Provider availability checks, progress feedback, and a queued workflow around the current request limit could make optional AI easier to use without hiding what will be sent.
  • A distributable release. Signed, notarized builds and a layered app icon could make Slugger easier to install and maintain beyond my own Mac.

The product lesson is simple: formatting and meaning need different tools. Deterministic rules take care of consistency, AI assists with description, and a clear preview keeps the publishing decision with me.