MCPcopy Index your code
hub / github.com/casey/filepack

github.com/casey/filepack @0.0.9

Chat with this repo
repository ↗ · DeepWiki ↗ · release 0.0.9 ↗ · + Follow
537 symbols 2,043 edges 102 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Table of Contents↗️

filepack

crates.io version build status downloads

filepack is a command-line file hashing and verification utility written in Rust.

It is an alternative to .sfv files and tools like shasum. Files are hashed using BLAKE3, a fast, cryptographic hash function.

A manifest named filepack.json containing the hashes of files in a directory can be created with:

filepack create path/to/directory

Which will write the manifest to path/to/directory/filepack.json.

Files can later be verified with:

filepack verify path/to/directory

To protect against accidental or malicious corruption, as long as the manifest has not been tampered with.

If you run filepack a lot, you might want to alias fp=filepack.

filepack is currently unstable: the interface and file format may change at any time. Additionally, the code has not been extensively reviewed and should be considered experimental.

Installation

filepack is written in Rust and can be built from source and installed from a checked-out copy of this repo with:

cargo install --path .

Or from crates.io with:

cargo install filepack

See rustup.rs for installation instructions for Rust.

Pre-Built Binaries

Pre-built binaries for Linux, MacOS, and Windows can be found on the releases page.

You can use the following command on Linux, MacOS, or Windows to download the latest release, just replace DEST with the directory where you'd like to put filepack:

curl --proto '=https' --tlsv1.2 -sSf https://filepack.com/install.sh | bash -s -- --to DEST

For example, to install filepack to ~/bin:

# create ~/bin
mkdir -p ~/bin

# download and extract filepack to ~/bin/filepack
curl --proto '=https' --tlsv1.2 -sSf https://filepack.com/install.sh | bash -s -- --to ~/bin

# add `~/bin` to the paths that your shell searches for executables
# this line should be added to your shell's initialization file,
# e.g. `~/.bashrc` or `~/.zshrc`
export PATH="$PATH:$HOME/bin"

# filepack should now be executable
filepack --help

Note that install.sh may fail on GitHub Actions or in other environments where many machines share IP addresses. install.sh calls GitHub APIs in order to determine the latest version of filepack to install, and those API calls are rate-limited on a per-IP basis. To make install.sh more reliable in such circumstances, pass a specific tag to install with --tag.

Usage

Filepack supports a number of subcommands, including filepack create to create a manifest, and filepack verify to verify a manifest.

See filepack help for supported subcommands and filepack help SUBCOMMAND for information about a particular subcommand.

filepack create

Create a manifest.

Recommended lints can be enabled with:

filepack create --deny distribution

filepack verify

Verify the contents of a directory against a manifest.

To verify the contents of DIR against DIR/filepack.json:

filepack verify DIR

If the current directory contains filepack.json, DIR can be omitted:

filepack verify

filepack verify takes an optional --print flag, which prints the manifest to standard output if verification succeeds. This can be used in a pipeline to ensure that you the manifest has been verified before proceeding:

filepack verify --print | jq

Data Directory

Filepack stores local configuration in the filepack subdirectory of the platform data directory.

The location of the platform data directory is platform dependent, with the $XDG_DATA_DIR being respected on all platforms.

Platform Value
All $XDG_DATA_DIR
Linux $HOME/.local/share
macOS $HOME/Library/Application Support
Windows {FOLDERID_LocalAppData}

Filepack stores keys in the keychain subdirectory of the filepack data directory. So if the platform data directory is ~/.local/share, the keychain directory is ~/.local/share/filepack/keychain.

The location of the filepack data directory used by a command can be overridden with the --data-dir option.

Manifest

filepack manifests are conventionally named filepack.json and are placed alongside the files they reference.

Manifests are UTF-8-encoded JSON.

Manifests contain an object with two mandatory keys, files and notes.

files

The value of the mandatory files key is an object mapping path components to directory entries. Directory entries may be subdirectories or files. Files are objects with keys hash, the hex-encoded BLAKE3 hash of the file, and size, the length of the file in bytes.

As a consequence of the manifest being UTF-8, all path components must be valid Unicode.

Path components may not be . or .., contain the path separators / or \, contain NUL, be longer than 255 bytes, or begin with a Windows drive prefix, such as C:.

signatures

The value of the mandatory signatures key is an array of signatures. Signatures are bech32 strings that include an Ed25519 key, the package fingerprint the signature is made over, an optional timestamp, and the signature itself.

Public keys are Curve25519 points and signatures are Ed25519 signatures made over the root of a Merkle tree which commits to the content of files via the package fingerprint.

Example

An manifest over a directory containing the files README.md and src/main.c, signed by the public key public1a67dndhhmae7p6fsfnj0z37zf78cde6mwqgtms0y87h8ldlvvflyqcxnd63:

{
  "files": {
    "README.md": {
      "hash": "fc253b84551ce6b00e820a826ac18054dc7f63a318ce62f3175315f5c467a62a",
      "size": 11883
    },
    "src": {
      "main.rs": {
        "hash": "1fa48b95ed335369d45b91af8138bdccd1413364bcdbfa6e9034e8a2cfd6e17f",
        "size": 33
      }
    }
  },
  "signatures": ["…"]
}

The signature is elided for brevity. Signatures are bech32m-encoded strings containing both a public key and an Ed25519 signature.

Keys, Signatures, Fingerprints, and Hashes

Public keys, private keys, signatures, and package fingerprints are all bech32m-encoded strings beginning with public1…, private1…, signature1…, and package1… respectively.

BLAKE3 file hashes are 64-character lowercase hexadecimal.

Metadata

Filepack packages may contain a file named metadata.yaml describing the package and its content.

filepack create loads metadata.yaml if present and checks for validity and unknown fields.

filepack verify also loads metadata.yaml if present and checks for validity. Unknown fields, however, are not an error, so that future versions of filepack may define new metadata fields in a backwards-compatible fashion.

Filepack metadata is intended to a broadly useful machine and human readable description of the contents of a package, covering personal, distribution, and archival use-cases.

Metadata follows a fixed schema and is not user-extensible. Future versions of filepack may define new metadata fields, causing verification errors if those fields are present and invalid according to the new schema.

Please feel free to open an issue with ideas for new metadata fields.

Schema

Fields are given as NAME: TYPE.

Mandatory fields:

  • title: component: The content's human-readable title.

Optional fields:

  • artwork: component.png: The filename of an PNG file containing artwork for the content, for example, cover art for an album or key art for a movie.

  • creator: component: The person or group who created the content.

  • date: date: The date the content was created or released.

  • description: markdown: A description of the content.

  • homepage: url: Primary URL for the content. Should be the official homepage of the content, if any, and not, for example, a Wikipedia or media database link.

  • language: language: The primary language of the content.

  • package: object: The package metadata.

  • readme: component.md: The filename of the content readme.

Optional package field describing the package itself, as opposed its content:

  • creator: component: The person or group who created the package.

  • creator-tag: tag: The tag of the person or group who created the package.

  • date: date: The date the package was created.

  • description: markdown: A description of the package.

  • homepage: url: Primary URL for the package.

  • nfo: component.nfo: The filename of the package nfo file.

Types:

  • component: A string with the same restrictions as path components in the manifest files object, allowing them to be used as unix filesystem paths. Note that Windows imposes additional restrictions which are not enforced, so components may not be valid paths on Windows.

  • component.EXTENSION: A component that must end with .EXTENSION.

  • date: A string containing a date in one of several formats: as a year only, when the date and time is unknown, a date only, when the time is unknown, or a date and time with a mandatory time zone.

  • language: A string containing an ISO 639-1 two-character language code. See filepack languages for valid language codes.

  • markdown: A string containing CommonMark markdown.

  • tag: A string containing a tag, commonly an abbreviation of a release group name. Must match the regular expression [0-9A-Z]+(\.[0-9A-Z]+)*.

  • url: A string containing a URL.

Example dates:

1970
1970-01-01
1970-01-01T00:00:00Z
1970-01-01 00:00:00Z
1970-01-01T00:00:00+00:00
1970-01-01 00:00:00 +00:00

Example

title: Tobin's Spirit Guide
creator: John Horace Tobin
artwork: cover.png
date: 1929
description: A compilation of supernatural occurrences, entities, and facts.
homepage: https://tobin-society.org/spirit-guide
language: en
readme: README.md
package:
  creator: Egon Spengler
  creator-tag: ES
  date: 1984-07-08 19:32:00 -04:00
  description: >
    First edition on loan from NYPL Main Branch research stacks. Captured via
    Microtek MS-300A flatbed scanner.
  homepage: https://ghost-busters.net/~egon
  nfo: tobins.nfo

The homepage URLs are of course anachronistic, as the World Wide Web was created in 1989, some years after Egon first packaged Tobin's Spirit Guide.

Lints

filepack create supports optional lints that can be enabled by group:

filepack create --deny distribution

The distribution lint group checks for issues which can cause problems if the package is intended for distribution, such as non-portable paths that are illegal on Windows, paths which would conflict on case-insensitive file systems, and inclusion of junk files such as .DS_Store.

Lint group names and the lints they cover can be printed with:

filepack lints

Keys and Signatures

filepack supports the generation of Curve25519 public/private keypairs, and the creation and verification of EdDSA signatures over manifests.

Keypair Generation

Keypairs are generated with:

filepack keygen

Which creates master.public and master.private files in the keychain subdirectory of the filepack data directory.

Public Key Printing

Generated public keys can be printed with:

filepack key

Signing

Signatures are created with:

filepack sign

Which signs the manifest in the current directory with your master key and adds the signature to the manifest's signatures array. Signatures are made over a fingerprint hash, recursively calculated from the contents of the manifest.

Signature Verification

Signatures embedded in a manifest are verified whenever a manifest is verified. The presence of a signature by a particular public key can be asserted with:

filepack verify --key PUBLIC_KEY

Which will fail if a valid signature for PUBLIC_KEY over the manifest contents is not present.

Fingerprints

Filepack signatures are made over the package fingerprint, which is the root of a Merkle tree of the files and directories contained in the manifest.

Fingerprints are BLAKE3 hashes, constructed such that it is impossible to produce objects which are different, either in type or content, but which have the same fingerprint.

Fingerprints may be used as a globally unique identifier. If two packages have the same fingerprint, they have the same content.

For details on how fingerprints are calculated, see DESIGN.md.

Workflows

Detecting Accidental Corruption

Create a filepack manifest with:

filepack create <PACKAGE>

This will create <PACKAGE>/filepack.json

To later verify the package against the manifest:

filepack verify <PACKAGE>

Because the manifest contains cryptographic hashes, accidental corruption to the files or manifest will always be detected by filepack verify

Extension points exported contracts — how you extend this code

Utf8PathExt (Interface)
(no doc) [1 implementers]
src/utf8_path_ext.rs
OwoColorizeExt (Interface)
(no doc) [1 implementers]
src/owo_colorize_ext.rs
Extension (Interface)
(no doc)
src/filename.rs

Core symbols most depended-on inside this repo

new
called by 226
src/progress_bar.rs
case
called by 27
src/relative_path.rs
as_bytes
called by 17
src/hash.rs
invalid
called by 17
src/key_name.rs
case
called by 16
src/date_time.rs
as_ref
called by 12
src/relative_path.rs
field
called by 11
src/fingerprint_hasher.rs
read_to_string
called by 11
src/filesystem.rs

Shape

Function 265
Method 201
Class 49
Enum 19
Interface 3

Languages

Rust100%

Modules by API surface

tests/verify.rs42 symbols
tests/test.rs37 symbols
tests/create.rs25 symbols
src/relative_path.rs19 symbols
src/manifest.rs17 symbols
src/component.rs17 symbols
src/private_key.rs16 symbols
src/signature.rs15 symbols
src/public_key.rs14 symbols
tests/metadata.rs13 symbols
src/hash.rs13 symbols
src/bech32_decoder.rs13 symbols

For agents

$ claude mcp add filepack \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact