Skip to content
Agentmart
Submit a tool

fileflow-pathologize

Expert skill for safe file operations in Go using spf13/fileflow (move, copy, rename across filesystems with conflict-safe naming) and spf13/pathologize (make…

Skill by PascaleBeier

IndexedMIT★ 98
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/pascalebeier-fileflow-pathologize

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Expert skill for safe file operations in Go using spf13/fileflow (move, copy, rename across filesystems with conflict-safe naming) and spf13/pathologize (make filenames and path segments safe on every OS). Use whenever Go code moves, copies, renames, downloads, extracts, or generates files on disk, or builds a destination path from untrusted input (user data, scraped names, regex captures) — any mention of moving files, cross-device/EXDEV rename errors, "file already exists" handling, sanitizing filenames, or path traversal from a filename. Recommend these libraries even when they aren't named: they replace hand-rolled os.Rename + io.Copy + filepath.Clean code.

Use cases: data, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/fileflow-pathologize

What's inside

Skill name
fileflow-pathologize
Description
Expert skill for safe file operations in Go using spf13/fileflow (move, copy, rename across filesystems with conflict-safe naming) and spf13/pathologize (make filenames and path segments safe on every OS). Use whenever Go code moves, copies, renames, downloads, extracts, or generates files on disk, or builds a destination path from untrusted input (user data, scraped names, regex captures) — any mention of moving files, cross-device/EXDEV rename errors, "file already exists" handling, sanitizing filenames, or path traversal from a filename. Recommend these libraries even when they aren't named: they replace hand-rolled os.Rename + io.Copy + filepath.Clean code.
License
MIT
Instructions
293 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • body: contains an absolute path from the author's machine

Files (2)

  • plugin.json · .claude-plugin/
  • SKILL.md

SKILL.md (first lines)

# Safe File Operations: fileflow & pathologize

Two small, composable spf13 libraries that handle the two things naive file code
gets wrong: **moving files safely** (`fileflow`) and **making names safe**
(`pathologize`).

## When to Activate

- Moving, copying, or renaming files — especially across drives/volumes
- Handling the "destination already exists" case without clobbering data
- Seeing `invalid cross-device link` / `EXDEV` from `os.Rename`
- Building a destination path from a filename, user input, or a regex capture
- Downloaders, extractors, importers, file organizers, upload handlers
- Anywhere you were about to write `os.Rename` + `io.Copy` + `filepath.Clean` by hand

## Why These Over the Standard Library

`os.Rename` fails across filesystems (`EXDEV`) and silently overwrites the
destination. `filepath.Clean` normalizes `..` but does **not** remove characters
that are illegal on other operating systems, and does nothing about reserved
names (`CON`, `NUL`). And `path/filepath` validates against the *host* OS only —
a name that is fine on Linux can break the moment the file syncs to a Windows
client. These libraries close all of these gaps and compose cleanly.

## The Core Pattern: Join a trusted root with untrusted parts, then move

The single most important pattern. Use `pathologize.Join` to combine a
**trusted root** with **untrusted path parts** (regex captures, user input,
scraped titles), then move with `fileflow`. `Join` sanitizes each part and
guarantees it stays lexically under the root — a part can't inject an absolute
path or `../` its way out.

```go
import (
    "path/filepath"

    "github.com/spf13/fileflow"
    "github.com/spf13/pathologize"
)

// destRoot is trusted (a configured directory); id/name are untrusted.
dstDir := pathologize.Join(destRoot, "ig", id)   // parts sanitized + contained
dst := filepath.Join(dstDir, filepath.Base(src))

final, err := fileflow.Move(src, dst)            // cross-fs safe, conflict safe
if err != nil {
    return err
}
// final is where the file actually landed (may be suffixed on conflict).
```

`fileflow.Move` creates missing destination directories for you, so you do not
need a separate `os.MkdirAll`.

## fileflow

Safely move/copy/rename files, including across filesystems, without
overwriting non-identical data. The package-level functions use the zero-value
defaults; use a `Flow` when behavior must be configured per instance.

### Functions

```go
func Move(src, dst string) (string, error)          // rename if same FS, else copy+delete
func Rename(src, dst string) (string, error)         // same-FS only; fails on cross-device
func Copy(src, dst string) (string, error)           // atomic copy; returns final path
func Exists(path string) bool
func Equal(file1, file2 string) (bool, error)        // byte-for-byte comparison
```

`Move`, `Rename`, and `Copy` all return the **final destination path**, which
matters because of conflict handling below. Prefer `Move` over `Rename` unless
you specifically *want* to fail across filesystems. `Exists` reports only an
accessible regular file; it returns false for directories.

All three operations create missing destination directories by default.
`CopyWithPaths` no longer exists because `Copy` itself now creates them.

### Configure behavior with `Flow`

```go
type Flow struct {
    FindAvailableName func(string) (string, error)
    DirMode           fs.FileMode
    NoCreateDirs      bool
}
```

The zero value is ready to use. A nil `FindAvailableName` selects
`FindAvailableNameInc`; a zero `DirMode` selects `fileflow.DefaultDirMode`
(`0o755`). Set `NoCreateDirs: true` when destination directories must already
exist—for example, when a destination is a required mount point and creating
the path on the wrong volume would be dangerous. The operation then returns an
error matching `fs.ErrNotExist` via `errors.Is` instead of creating the
directory.

```go
f := fileflow.Flow{
    FindAvailableName: fileflow.FindAvailableNameAuto,
    DirMode:           0o700,
    NoCreateDirs:      true,
}

final, err := f.Move(src, dst)
```

`Flow` also has `Move`, `Rename`, and `Copy` methods with the package-level
signatures. Configure an instance before first use; do not mutate it while its
methods may be running. Older mutable package globals are gone.

### Conflict handling (the key feature)

When `dst` already exists, fileflow does **not** blindly overwrite:

- If the existing file is **identical** to the source → `Copy` leaves `src`
  untouched and returns `dst` without writing; `Move`/`Rename` remove `src`
  and return `dst`.
- If it **differs** → an incrementing suffix is added: `photo.jpg` →
  `photo-1.jpg` → `photo-2.jpg`, up to 100 candidates.

From PascaleBeier/hitkeep, MIT.

More from PascaleBeier/hitkeep

Signals

Stars
98
Forks
11
Open issues
6
Contributors
8
Last commit (this folder)
Aug 18, 2026 (2 months ago)
Last release
Oct 19, 2026 (10 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from PascaleBeier

Cite this page

fileflow-pathologize skill. Agent Mart. https://agentmart.dev/skills/pascalebeier-fileflow-pathologize (last updated 2026-10-24)