Repository navigation
feat: skills, cross-platform scripts, tests, and landing page - #4
Merged
Merged
Conversation
Skills for browser bookmarks, Downloads, Desktop, and Obsidian vaults. Each targets a category rather than an app and looks paths up in references/app-data-locations.md, so the bookmarks skill covers eight browsers across three storage formats. Shared safe-mutation rules cover the backup-first workflow, the content-is-data rule, root confinement, and the denylist. Skills cite them rather than restating them. Two stdlib-only scripts do the deterministic bulk work: bookmarks.py reads Chromium JSON, Safari plists, and Firefox SQLite, detecting format by content rather than filename; scan_tree.py inventories a directory and rejects plans that escape the root. Both refuse to write without a real backup. Replaces the README with a public-facing version and adds a contributor guide and fixtures.
Single self-contained HTML file, no build step, so it can be opened directly or served from GitHub Pages later. Technical-minimal language for a developer audience: system type stack, one blue accent, restrained scroll-reveal. Light and dark themes via prefers-color-scheme, both verified. The hero visual is real monospace text rather than a simulated product screenshot, since a terminal transcript is the actual medium. Reveal animation degrades safely: content is only hidden once JS confirms it is running, an IntersectionObserver drives the reveal, and a timeout reveals anything still hidden so content cannot be stranded in snapshot, print, or crawler contexts. Grid children are constrained with min-width:0 and the wide bento cell uses a class rather than an inline span, so the layout collapses to one column on mobile without horizontal overflow. All 15 text and background pairs pass WCAG AA in both themes.
Nothing in the design was macOS-specific. The skills are markdown, the scripts are standard-library Python, and the storage formats are identical across platforms: Chrome keeps the same Bookmarks JSON everywhere. Only three things actually differ, and they now live in one module. platforms.py resolves app data locations across macOS, Linux, and Windows path conventions, enumerates browser profiles, detects whether an app is running via pgrep or tasklist, and trashes files to ~/.Trash, the FreeDesktop trash, or the Recycle Bin through the shell API. The Windows path uses SHFileOperationW rather than moving files into $Recycle.Bin by hand, which would produce entries Explorer cannot restore. A permission denial is now a normal return value carrying platform specific remediation, rather than an unhandled PermissionError. On macOS that denial is the most common first-run outcome and it deserves a sentence, not a traceback. Skills no longer hardcode paths or pgrep invocations; they ask the resolver, so they work on every platform without being rewritten. Platform support is stated honestly: macOS is verified, Linux and Windows are implemented but not yet run end to end by anyone.
…mits
Four defects, all surfaced by the new test suite.
canon() normalised schemes with a plain string replace, so "https"
became "httpss" and no https URL ever matched its http twin. Duplicate
detection was quietly weaker than intended for most real bookmarks.
detect() recognised only binary plists. XML plists fell through to a
filename check and were reported as unrecognised. Empty files produced
the same confusing message rather than saying they were empty.
scan_tree counted the root as depth 0, so every --max-depth was one
level too generous. Depth 1 now means the root's own files, which is
what the flag reads as.
platforms.py listed Opera among the Chromium browsers but not in
PROCESS_NAMES, so running("opera") returned None. A skill could not tell
that Opera was open and would have let it clobber the write on quit.
101 tests, standard library only, no dependencies. Scripts are covered where behaviour is checkable: URL canonicalization, format sniffing by content, the refusal to write without a backup on disk, path-escape and denylist confinement, symlink handling, and trash semantics on all three platforms. Platform code is tested by forcing the platform, so Linux and Windows logic runs on any machine. Skills are covered structurally: frontmatter validity, names matching directories, safety rules cited rather than restated, no hardcoded paths, no raw rm, and referenced scripts actually existing. A triggering test asserts each skill's description matches the phrases a real person would type and does not collide with its siblings, since a skill nobody triggers is dead weight. Skill judgment stays with human review. Only structure is gated. CI runs the suite on Linux, macOS, and Windows across Python 3.10 and 3.13, which is what keeps the cross-platform claim honest.
A checklist the skill runs in the seconds before it writes, distinct from the reviewer checklist that humans use on a pull request. It restates the conditions that must hold right then: the path came from the resolver, a backup exists on disk, the user approved in a later turn than the one that asked, every path resolves inside the declared root, and the undo command is known before anything starts. Every skill now cites it. The pattern is borrowed from the design-taste-frontend skill, where it guards visual quality. Here it guards the user's data.
Makes the repository its own marketplace, so installing is adding the marketplace and then the plugin, with no intermediate hosting. Installing the plugin rather than copying a skill folder matters here: skills read the shared safety rules from the plugin root, and a lone SKILL.md dropped into ~/.claude/skills loses them silently.
The pull request template carries the reviewer checklist inline, since skill judgment is gated by humans rather than CI and the checklist is only useful if reviewers see it. A platform report template collects what is actually needed to promote Linux and Windows beyond CI: path resolution, running detection, and whether trashed files restore from the user's own file manager.
Glass needs something behind it to refract, so the ambient gradient field moved to the root element. It was previously a z-index:-1 child that the body's own opaque background painted over, which is why the effect barely read. Surfaces get a translucent fill, a saturating backdrop blur, a 1px border and an inset highlight for the edge, rather than blur alone. Translucency tints what sits behind text, so contrast was recomputed against the composited backgrounds at the densest point of the ambient field. Small accent labels failed there, blue on blue-tinted glass, and now use a separate accent-text token with more headroom. All pairs pass WCAG AA in both themes. prefers-reduced-transparency drops every blur and restores opaque fills.
Exact commands for adding the marketplace and installing the plugin, the macOS Full Disk Access step, and a warning against copying a bare skill folder, which silently loses the shared safety rules. States platform support precisely: macOS verified by use, Linux and Windows exercised by CI but not yet driven through a full cleanup by anyone, with a link to the report template. Adds a tests section naming what is covered and what cannot be, since whether a skill's judgment is any good is not something a test can say.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds out the repo from an empty scaffold into a working plugin.
Supersedes #3, which GitHub auto-closed when the branch history was rewritten to strip the design spec.
What's here
Four skills, each targeting a category rather than an app, so one file covers everything sharing a storage format:
organizing-bookmarkssorting-downloadsclearing-desktoporganizing-obsidian-vaultShared layer.
references/app-data-locations.mdholds every path;references/safe-mutation-rules.mdholds the backup-first workflow and the standing rules. Skills cite them rather than restating them, so nothing hardcodes a path and copies cannot drift.Three scripts, standard library only.
bookmarks.pyreads Chromium JSON, Safari plists, and Firefox SQLite.scan_tree.pyinventories directories and rejects plans that escape their root.platforms.pyresolves paths, detects running apps, and trashes files across macOS, Linux, and Windows.Cross-platform
Only paths, process lookup, and trash actually differ, and they now live in one module. Windows trash goes through
SHFileOperationWrather than moving files into$Recycle.Bin, which would produce entries Explorer cannot restore.macOS is verified by use. Linux and Windows are exercised by CI, but nobody has driven a full cleanup on them, and the README says exactly that.
Tests
101 tests, no dependencies, green on all three operating systems across Python 3.10 and 3.13.
They found four real bugs, fixed in
fix(scripts):canon()produced"httpss"from a naive string replace, so no https URL matched its http twin. Duplicate detection, the core of this project, was quietly broken for most real bookmarks.--max-depthwas off by one, scanning a level deeper than asked.PROCESS_NAMES, so a skill could not tell Opera was open and would have let it clobber the write on quit.Structure is gated; judgment is not. A triggering test asserts each skill's description fires on phrases real people type, since a skill nobody triggers is dead weight.
Safety
Adds a pre-flight check the skill runs immediately before writing, distinct from the reviewer checklist humans use on a PR. Pattern borrowed from the
design-taste-frontendskill, where it guards visual quality; here it guards user data.Site
Self-contained landing page, no build step, with a layered glass treatment. Contrast was recomputed against composited backgrounds, since translucency tints what sits behind text. Small accent labels failed there and now use a separate token. All pairs pass WCAG AA in both themes.