hermes-proton/skills/proton-drive/SKILL.md
exe.dev user f103d5f44f
feat: Proton Drive Hermes skill — rclone-backed file operations
Build the proton-drive Hermes skill following the Phase 4 spec
from ARCHITECTURE.md (§5). Primary path: rclone protondrive backend
with Drive SDK as a fallback option.

Skill components:
  - skills/proton-drive/SKILL.md — YAML frontmatter + full docs for
    all 9 tools (list, read, download, upload, search, mkdir,
    delete, stat, sync) with usage, error handling, security notes
  - skills/proton-drive/__init__.py — package init with exports
  - skills/proton-drive/tools.py — Python subprocess wrappers for
    each tool, plus rclone availability/remote checks
  - tests/test_drive.py — 25 unit tests (all pass) with mocked
    subprocess.run

All 9 Proton Drive tools implemented:
  proton_drive_list, proton_drive_read, proton_drive_download,
  proton_drive_upload, proton_drive_search, proton_drive_mkdir,
  proton_drive_delete, proton_drive_stat, proton_drive_sync

Signed-off-by: Bee <bee@trentuna.com>
2026-06-08 18:30:26 +02:00

8.2 KiB

name description version author license platforms metadata
proton-drive Hermes skill for Proton Drive — list, read, upload, download, search, and manage files using the rclone protondrive backend. 1.0.0 Trentuna / Bee MIT
linux
macos
windows
hermes
tags related_skills required_environment_variables optional_environment_variables
proton
drive
cloud-storage
rclone
file-management
proton-mail
proton-pass
proton-vpn
PROTON_RCLONE_REMOTE
PROTON_RCLONE_PATH
PROTON_DRIVE_USE_SDK

Proton Drive Skill

Agents can read, write, search, and manage files on Proton Drive through the battle-tested rclone protondrive backend.

Prerequisites

1. Install rclone

# Linux (official script)
curl https://rclone.org/install.sh | sudo bash

# macOS
brew install rclone

# Verify
rclone version

2. Configure the protondrive remote

rclone config create protondrive protondrive \
  username=your@proton.me \
  password=your_password \
  --non-interactive

Or interactively:

rclone config
# → Choose "n" (new remote)
# → Name: protondrive
# → Type: protondrive
# → Follow prompts for username, password, 2FA

3. Set environment variables (optional)

export PROTON_RCLONE_REMOTE=protondrive   # default: protondrive
export PROTON_RCLONE_PATH=/path/to/rclone # default: auto-detect from PATH

On first run, rclone will prompt for the mailbox password (your Proton login password). After authentication, tokens are cached locally by rclone's own credential store — no additional auth management needed for subsequent calls.

Tools

The skill provides 9 tools for interacting with Proton Drive. Each tool shells out to rclone with the configured protondrive remote.

proton_drive_list

List files and folders in a path on Proton Drive.

Usage: rclone lsf --json <remote>:<path>
Args:
  path (string, default: "/") — Path to list (e.g. "Documents" or "/")
  recursive (bool, default: false) — List recursively
  dirs_only (bool, default: false) — Show directories only
  files_only (bool, default: false) — Show files only
Returns: JSON array of {Name, Path, Size, ModTime, IsDir} items

proton_drive_read

Read a file's content from Proton Drive.

Usage: rclone cat <remote>:<path>
Args:
  path (string, required) — Path to the file (e.g. "Documents/notes.txt")
  head (int, optional) — Only read first N lines
  tail (int, optional) — Only read last N lines
Returns: File content as text string (up to 10MB; larger files use download instead)

Large files (>10MB) should be downloaded rather than read inline. The tool will return an error suggesting proton_drive_download for files exceeding the size threshold.

proton_drive_download

Download a file from Proton Drive to a local path.

Usage: rclone copy <remote>:<path> <local_path>
Args:
  remote_path (string, required) — Source path on Drive (e.g. "Documents/report.pdf")
  local_path (string, required) — Destination local path (absolute or ~/expanded)
  progress (bool, default: false) — Show transfer progress
Returns: JSON with {status, local_path, size_bytes}

The local path must be writable. If the path ends with /, the file is downloaded into that directory preserving its filename.

proton_drive_upload

Upload a local file or directory to Proton Drive.

Usage: rclone copy <local_path> <remote>:<path>
Args:
  local_path (string, required) — Source path on local filesystem
  remote_path (string, required) — Destination path on Drive (e.g. "Documents/")
  create_parents (bool, default: true) — Create parent dirs if they don't exist
  progress (bool, default: false) — Show transfer progress
Returns: JSON with {status, remote_path, size_bytes}

Supports both individual files and entire directories.

Search for files by name across Proton Drive.

Usage: rclone lsf -R --files-only <remote>: | grep -i <query>
  OR (for structured results): rclone lsf -R --json <remote>: | jq <filter>
Args:
  query (string, required) — Search term or regex pattern
  path (string, default: "/") — Root path to search under
  regex (bool, default: false) — Treat query as regex instead of substring
  max_results (int, default: 50) — Max results to return
Returns: JSON array of matching {Name, Path, Size, ModTime}

proton_drive_mkdir

Create a folder on Proton Drive.

Usage: rclone mkdir <remote>:<path>
Args:
  path (string, required) — Path of folder to create (e.g. "Documents/NewFolder")
Returns: JSON with {status: "created", path}

Creates all parent directories if they don't exist (like mkdir -p).

proton_drive_delete

Delete a file or empty folder from Proton Drive.

Usage: rclone delete <remote>:<path>
Args:
  path (string, required) — Path to the file/folder to delete
  recursive (bool, default: false) — Recursively delete folder contents
Returns: JSON with {status: "deleted", path}

Non-recursive deletion of non-empty folders will fail. rclone's purge command is used for recursive deletes.

proton_drive_stat

Get detailed metadata for a file or folder.

Usage: rclone lsl <remote>:<path>
  OR (detailed): rclone lsf --json <remote>:<path>
Args:
  path (string, required) — Path to the file or folder
Returns: JSON with {Name, Path, Size, ModTime, IsDir, Hash, MimeType}

proton_drive_sync

Synchronize a local directory with Proton Drive (or vice versa).

Usage: rclone sync <source> <destination> [flags]
Args:
  source (string, required) — Source path (local: or remote:)
  dest (string, required) — Destination (local: or remote:)
  direction (enum, default: "upload") — "upload" (local→Drive), "download" (Drive→local), "bidirectional"
  dry_run (bool, default: true) — If true, show what would change without syncing
  delete_excluded (bool, default: false) — Delete files at dest not present at source
Returns: JSON with {status, changed, added, deleted, errors}

IMPORTANT: Defaults to dry_run=true for safety. The agent MUST confirm with the user before running a live sync, especially when delete_excluded=true — this can cause data loss.

Implementation

All tools are implemented as Python subprocess wrappers in the tools/ subdirectory. The primary backend is rclone; the TypeScript Drive SDK is available as a fallback via PROTON_DRIVE_USE_SDK=true.

Tool Handler Pattern

def handle_proton_drive_list(args: dict, **kwargs) -> dict:
    path = args.get("path", "/")
    recursive = args.get("recursive", False)
    cmd = _build_rclone_command("lsf", "--json", path, recursive=recursive)
    result = _run_rclone(cmd, timeout=30)
    if result.returncode != 0:
        return {"error": result.stderr.strip()}
    items = [json.loads(line) for line in result.stdout.strip().split("\n") if line]
    return {"items": items}

Rclone Configuration Check

Before any tool execution, verify the rclone remote exists:

def _check_rclone_remote(remote: str) -> bool:
    result = subprocess.run(
        ["rclone", "listremotes"],
        capture_output=True, text=True, timeout=5
    )
    return f"{remote}:" in result.stdout

If the remote is not configured, return a clear error with setup instructions referencing the README.

Error Handling

Error Cause Resolution
remote not found protondrive remote not configured Run rclone config or refer to README
authentication required Token expired or invalid Run rclone config reconnect <remote>
file not found Path doesn't exist Check path with proton_drive_list
file too large Read attempt on >10MB file Use proton_drive_download instead
rate limited Too many API calls Retry with backoff (rclone does this auto)

Security Notes

  • Files read by proton_drive_read enter the agent's context. For sensitive documents, prefer proton_drive_download and specify a local path.
  • proton_drive_sync with delete_excluded=true is destructive. Always default to dry_run=true and require confirmation.
  • rclone stores tokens in its config file (~/.config/rclone/rclone.conf). Ensure this file has appropriate file permissions (chmod 600).