clod
Copyright(c) Fuzz Leonard 2025
LicenseMIT
Maintainercyborg@bionicfuzz.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Clod.FileSystem

Description

This module provides functionality for working with files and directories, including finding, reading, copying, and checking files.

The module handles various file system tasks:

  • Recursively finding files in a directory structure
  • Detecting modified files since a given timestamp
  • Identifying text vs. binary files
  • Processing files according to ignore patterns
  • Creating an optimized file structure for Claude AI integration

File Processing Pipeline

  1. Files are discovered recursively in the repository
  2. Each file is checked against .gitignore and .clodignore patterns
  3. Binary files are excluded
  4. Remaining files are copied to a staging directory with optimized names
  5. A path manifest is created to map optimized names back to original paths

Optimized Naming

Files are renamed for Claude's UI by:

  • Replacing directory separators with dashes
  • Flattening the directory structure
  • Special handling for hidden files (e.g., .gitignore becomes dot--gitignore)
  • Special handling for certain file types (e.g., .svg files become .xml)

This ensures that all files can be easily distinguished in Claude's UI while maintaining a mapping back to their original locations. Hidden files are transformed to be visible in file browsers while preserving their hidden status when written back to the filesystem.

Synopsis

Re-exports from FileSystem.Operations

findAllFiles :: FilePath -> [FilePath] -> ClodM [FilePath] Source #

Recursively find all files in a directory

This function takes a base path and a list of files/directories, and recursively finds all files within those directories. It returns paths relative to the base path.

-- Find all files in the "src" directory
files <- findAllFiles "pathto/repo" ["src"]

-- Find all files in multiple directories
files <- findAllFiles "pathto/repo" ["src", "docs", "tests"]

-- Find all files in the root directory (without "./" prefix)
files <- findAllFiles "pathto/repo" [""]

safeRemoveFile :: FilePath -> ClodM () Source #

Safely remove a file, ignoring errors if it doesn't exist

copyFile #

Arguments

:: FilePath

Source filename

-> FilePath

Destination filename

-> IO () 

Copy a file with its permissions. If the destination file already exists, it is replaced atomically. Neither path may refer to an existing directory. No exceptions are thrown if the permissions could not be copied.

safeReadFile :: FileReadCap -> FilePath -> ClodM ByteString Source #

Safe file reading that checks capabilities

safeWriteFile :: FileWriteCap -> FilePath -> ByteString -> ClodM () Source #

Safe file writing that checks capabilities

safeCopyFile :: FileReadCap -> FileWriteCap -> FilePath -> FilePath -> ClodM () Source #

Safe file copying that checks capabilities for both read and write

Re-exports from FileSystem.Detection

isModifiedSince :: FilePath -> UTCTime -> FilePath -> ClodM Bool Source #

Check if a file has been modified since the given time

isTextFile :: FilePath -> ClodM Bool Source #

Check if a file is a text file using libmagic with enhanced detection

isTextDescription :: String -> ClodM Bool Source #

Helper to determine if a file description indicates text content

needsTransformation :: FilePath -> Bool Source #

Special handling for files that need transformation

Detects files that need special handling and transformation based on their name or extension. Currently identifies:

  • Hidden files (dotfiles) - need to be transformed to be visible
  • SVG files - need to be transformed to XML for Claude compatibility
>>> needsTransformation ".gitignore"
True
>>> needsTransformation "logo.svg"
True
>>> needsTransformation "regular-file.txt"
False

safeFileExists :: FileReadCap -> FilePath -> ClodM Bool Source #

Safe file existence check that checks capabilities

safeIsTextFile :: FileReadCap -> FilePath -> ClodM Bool Source #

Safe file type check that checks capabilities

Re-exports from FileSystem.Processing

processFiles Source #

Arguments

:: ClodConfig

Configuration for the Clod program

-> FilePath

Path to the manifest file

-> [FilePath]

List of files to process

-> Bool

Whether to only include in manifest (no file copying)

-> ClodM (Int, Int)

(Processed count, Skipped count)

Process a list of files for Claude integration

This is the core function that processes files for Claude integration. It filters files based on ignore patterns, skips binary files, and either copies the files to the staging directory or just adds them to the manifest.

The function returns a tuple with:

  • The number of files successfully processed
  • The number of files skipped
-- Process all files in a list
(processed, skipped) <- processFiles config manifestPath allFiles False

-- Process files but only include in manifest (no copying)
(processed, skipped) <- processFiles config manifestPath allFiles True

data ManifestEntry Source #

A manifest entry consisting of an optimized name and original path

Each entry in the path manifest maps an optimized file name (as displayed in Claude) to its original file path in the repository.

ManifestEntry 
  { entryOptimizedName = OptimizedName "src-config-settings.js"
  , entryOriginalPath = OriginalPath "srcconfigsettings.js"
  }

Constructors

ManifestEntry 

Fields

Instances

Instances details
Show ManifestEntry Source # 
Instance details

Defined in Clod.FileSystem.Processing

Eq ManifestEntry Source # 
Instance details

Defined in Clod.FileSystem.Processing

createOptimizedName :: FilePath -> OptimizedName Source #

Create an optimized filename for Claude UI

writeManifestFile Source #

Arguments

:: FileWriteCap

Capability token with permissions to write to the staging directory

-> FilePath

Path to the manifest file (typically "_path_manifest.dhall")

-> [(OptimizedName, OriginalPath)]

List of optimized name to original path mappings

-> ClodM ()

Action that creates the manifest file

Write all entries to the manifest file at once

This creates the _path_manifest.dhall file that maps optimized filenames back to original paths. The manifest is a Dhall record with optimized names as keys and original paths as values.

>>> writeManifestFile writeCap "_path_manifest.dhall" [(OptimizedName "app-config.js", OriginalPath "app/config.js")]
-- Creates a file with content: { `app-config.js` = "app/config.js" }

The manifest file is crucial for Claude to know where to write files back to the filesystem.

Re-exports from FileSystem.Transformations

flattenPath :: FilePath -> FilePath Source #

Flatten a path by removing directory separators and replacing them This makes paths suitable for flat storage

sanitizeFilename :: FilePath -> FilePath Source #

Sanitize a filename by removing special characters This ensures filenames are valid across platforms

transformFileContent Source #

Arguments

:: FileReadCap 
-> FileWriteCap 
-> (ByteString -> Text)

Transformation function

-> FilePath 
-> FilePath 
-> ClodM () 

Transform file content for Claude compatibility This function is used for special file types that need transformation