Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ one executable for macOS and Linux. Read README.md before changing its behavior.
- README.md is the primary English README; README_zh.md is the Chinese version.
Every README change must update both files in the same change, keeping behavior,
examples, and section coverage equivalent. Preserve their language-switch links.
- When adding, removing, or changing a CLI command, option, default, or user-visible
behavior, update `skills/filetrail/SKILL.md` in the same change so the installable
agent skill stays accurate. Keep it focused on FileTrail's purpose and usage.
- Use the exact toolchain in rust-toolchain.toml. Keep Cargo.lock checked in.
- Building requires a C compiler for vendored libgit2 and SQLite. The distributed executable
needs no separate Rust installation, and its built-in commands need no system Git.
Expand Down
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@ with `./install.sh zsh`. It installs with Cargo, then configures that shell's
completion. Open a new shell afterward. The installation root defaults to
`${CARGO_HOME:-$HOME/.cargo}`; set `CARGO_INSTALL_ROOT` to override it.

## Agent skill

The [FileTrail skill](skills/filetrail/SKILL.md) teaches an agent what FileTrail
does and how to use its commands, including restoration. To install it, simply
send Codex this message:

```text
Please install this Skill: https://github.com/RinChanNOWWW/FileTrail/tree/master/skills/filetrail
```

You can also run Codex's GitHub skill installer manually:

```sh
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/skill-installer/scripts/install-skill-from-github.py" \
--repo RinChanNOWWW/FileTrail --ref master --path skills/filetrail
```

If the skill is on another branch or tag, replace `master` with that ref.
The skill installs as `filetrail`; invoke it with `$filetrail` in a supporting
agent environment. It provides instructions only: the agent still needs access
to the FileTrail executable and the files on the machine being managed.

## Tab completion and shell integration

If you installed FileTrail with `cargo install`, enable completion with:
Expand Down Expand Up @@ -110,6 +132,47 @@ Relative source paths are resolved from your current directory; parent-directory
symlinks are resolved to their actual locations. Sources, destinations, and the
application data directory must not overlap.

## Restore files to this system

Select an existing FileTrail repository with `init` on a new machine, then restore:

```sh
filetrail init ~/dotfiles --subdir macos # Only for a profile not yet initialized
filetrail restore --dry-run
filetrail restore
filetrail restore macos/__HOME__/.zshrc macos/__HOME__/.config/nvim
filetrail restore --track macos/__HOME__/.zshrc
filetrail restore --overwrite macos/__HOME__/.zshrc
```

Paths are relative to the repository root, including the configured subdirectory.
Supply multiple files or directories; directories are copied recursively and overlapping
selections are copied once. With no paths, restore all files under the current
subdirectory's `__HOME__` and `__ROOT__`. Other subdirectories and repository files
such as READMEs are not restored. `__HOME__` maps to the current user's Home;
`__ROOT__` maps to `/` and requires write access at the original absolute locations.
The repository's current working files are used, including uncommitted files.

By default, this only copies files and leaves management unchanged. Identical files
are left alone; different local contents, file types, or permissions require
`--overwrite`. Local directories are never replaced by files or links. Files absent
from the repository are not deleted. File permissions and symlinks are preserved;
symlink targets are not copied or rewritten. Restore refuses symlink ancestors,
paths into the repository or application data directory, and `.git` paths.
Nested `.git` entries are skipped.

`--track` also adds each restored file or symlink to management with deletion disabled,
so extra local files in the same directory do not become managed. Compatible existing
mappings retain their settings; disabled or excluded mappings must be adjusted before
using `--track`. Files encoded under `__ROOT__` that now belong inside Home can be
copied, but must use the `__HOME__` layout to be tracked. Empty directories are created
but are not added as management entries. Afterward, ordinary synchronization flows
from this system back to the repository; restore does not start the daemon or commit.

`--dry-run` previews copying and optional management changes without applying them.
All selections and conflicts are checked before copying. An I/O error during execution
can leave some files restored; fix the error and rerun the command.

## Change the target or start over

To switch repositories while keeping your sources, exclusions, and deletion settings:
Expand Down
54 changes: 54 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ filetrail --help
它先通过 Cargo 安装,再配置所选 shell 的补全,完成后重新打开 shell 即可。
安装根目录默认为 `${CARGO_HOME:-$HOME/.cargo}`,可通过 `CARGO_INSTALL_ROOT` 覆盖。

## Agent skill

[FileTrail skill](skills/filetrail/SKILL.md) 向 agent 介绍 FileTrail 的用途和命令用法,
包括文件恢复。直接把下面这句话发给 Codex,即可让它安装:

```text
请安装这个 Skill:https://github.com/RinChanNOWWW/FileTrail/tree/master/skills/filetrail
```

也可以手动运行 Codex 的 GitHub skill 安装脚本:

```sh
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/skill-installer/scripts/install-skill-from-github.py" \
--repo RinChanNOWWW/FileTrail --ref master --path skills/filetrail
```

如果 skill 位于其他分支或标签,将 `master` 替换为对应 ref。
安装后的名称为 `filetrail`,可在支持 skill 的 agent 环境中通过 `$filetrail` 调用。
skill 只提供使用说明;agent 仍需要能访问被管理机器上的 FileTrail 可执行文件和相关文件。

## Tab 补全与 shell 集成

如果使用 `cargo install` 安装 FileTrail,执行以下命令启用补全:
Expand Down Expand Up @@ -100,6 +120,40 @@ filetrail add ~/notes --exclude '**/*.tmp'
目录默认递归监听,排除规则相对于来源根目录。相对来源路径以当前目录为基准,
父目录中的符号链接会解析为实际路径。来源、目标和应用数据目录不能相互重叠。

## 恢复文件到当前系统

在新机器上通过 `init` 选择已有的 FileTrail 仓库,然后恢复:

```sh
filetrail init ~/dotfiles --subdir macos # 仅用于尚未初始化的配置
filetrail restore --dry-run
filetrail restore
filetrail restore macos/__HOME__/.zshrc macos/__HOME__/.config/nvim
filetrail restore --track macos/__HOME__/.zshrc
filetrail restore --overwrite macos/__HOME__/.zshrc
```

路径相对于仓库根目录,需要包含已配置的子目录。可以一次指定多个文件或目录;
目录会递归拷贝,重叠选择只拷贝一次。不指定路径时,恢复当前子目录下
`__HOME__` 和 `__ROOT__` 中的所有文件。其他子目录及 README 等仓库文件不会恢复。
`__HOME__` 映射到当前用户的 Home,`__ROOT__` 映射到 `/`,需要对原始绝对位置
具有写入权限。恢复使用仓库当前工作区中的文件,包括尚未提交的文件。

默认仅拷贝文件,不改变管理状态。相同文件保持不变;本地内容、文件类型或权限
不同时,需要显式传入 `--overwrite`。不会用文件或链接替换本地目录,也不会删除
仓库中不存在的本地文件。文件权限和符号链接会保留,但不会拷贝或改写链接指向的目标。
恢复拒绝经过符号链接父目录、写入仓库或应用数据目录,以及显式选择 `.git` 路径;
递归扫描时跳过嵌套的 `.git` 项。

`--track` 会将恢复的每个文件或符号链接加入管理,默认关闭删除传播,同目录下
额外存在的本地文件不会因此纳入管理。兼容的已有管理项保留原设置;已禁用或被排除的
管理项需要先调整设置才能使用 `--track`。编码在 `__ROOT__` 下、但在当前系统中属于
Home 的文件可以拷贝,加入管理则需要使用 `__HOME__` 布局。空目录会创建,但不会作为
管理项加入。之后普通同步仍从当前系统同步到仓库;恢复不会启动后台任务或提交。

`--dry-run` 预览拷贝和可选的管理变更,不实际应用。所有选择和冲突都会在拷贝前检查。
执行期间发生 I/O 错误可能留下部分已恢复的文件;修复错误后可重新运行命令。

## 更换目标或重新初始化

切换仓库时保留监听项、排除规则和删除设置:
Expand Down
221 changes: 221 additions & 0 deletions skills/filetrail/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
---
name: filetrail
description: Use the FileTrail CLI on macOS or Linux to manage file and dotfile synchronization into a Git repository, restore files to the current system, review and commit managed changes, and operate its daemon and shell integration. Applies to using FileTrail, not developing its Rust implementation.
---

# FileTrail

FileTrail watches selected files and directories and copies changes into a local
Git repository. It provides explicit review and commit commands, and can restore
repository files onto the current system. Normal synchronization goes from local
sources to the repository; it is not automatic bidirectional synchronization.
The daemon never stages, commits, or pushes. One executable supports macOS and
Linux; built-in commands need neither a Rust installation nor system Git.
Only `filetrail git` requires Git on PATH.

## Discover the installed CLI and profile

Run `filetrail --version`, `filetrail --help`, and relevant subcommand help before
using unfamiliar options; the installed version may differ from this guide.
FileTrail must be installed and executable in the environment where the user's
files reside. Loading this skill does not install the executable or grant access
to another machine's files.

The default profile is `$HOME/.filetrail`. Use the same `--data-dir <directory>`
for every command when the user selects another profile:

```sh
filetrail --data-dir ~/filetrail-work status
filetrail --data-dir ~/filetrail-work list
```

Inspect `status` and `list` for an existing setup. Use an isolated temporary profile,
source, and repository for experiments; the data directory must be outside both
source and repository. Real setup examples below apply when configuration is part
of the user's request.

## Set up sources and understand paths

```sh
filetrail init ~/dotfiles --subdir macos
filetrail add ~/.zshrc
filetrail add ~/.config/nvim
filetrail add ~/notes --exclude '**/*.tmp'
```

Use `--subdir linux` for a Linux layout, or omit `--subdir` to put the reserved
roots directly in the repository. `init` creates the destination and initializes
Git if needed; an existing local repository can also be selected. It does not
clone or fetch a remote. `add` immediately synchronizes the source's existing
files. Directories are recursive; `--exclude` is a repeatable glob relative to
each source root.

| Local source | Repository path with `--subdir macos` |
| --- | --- |
| `~/.zshrc` | `macos/__HOME__/.zshrc` |
| `~/.config/nvim/init.lua` | `macos/__HOME__/.config/nvim/init.lua` |
| `/opt/scripts/build.sh` | `macos/__ROOT__/opt/scripts/build.sh` |

`__HOME__` represents the current user's Home; `__ROOT__` represents `/`.
Custom targets are unsupported, and neither reserved name can occur in `--subdir`.
Source arguments are local paths, relative to the current directory when not
absolute. Parent symlinks are resolved when adding sources. Paths for `restore`,
`diff`, `commit`, and `resolve` are repository-relative and include the subdirectory.
Sources, the target repository, and the application data directory must not overlap.

For batch addition, use `filetrail add --from ./files.txt`. Write one source per
line, quoting paths containing spaces; blank lines and `#` comments are allowed.
Relative paths are resolved from the list's directory. `~` expands to Home;
variables and commands are not expanded or executed. The entire list is validated
before adding entries. Editing the list later does not update existing entries.

```text
~/.zshrc
~/.config/nvim
"~/My Notes"
/opt/scripts
```

## Manage and synchronize

| Command | Effect |
| --- | --- |
| `filetrail list` | Show source mappings and IDs. |
| `filetrail disable <id>` | Disable synchronization for a mapping. |
| `filetrail enable <id>` | Enable a mapping. |
| `filetrail remove <id>` | Stop managing a mapping; keep its files. |
| `filetrail sync --dry-run` | Preview forward synchronization. |
| `filetrail sync` | Synchronize immediately, even while automatic sync is paused. |

Use IDs returned by `list`. Source deletion does not delete repository copies by
default. `add <source> --delete` opts into propagating deletion of previously
synchronized files. An unavailable source directory never triggers mass deletion.
Symlinks are copied as links; `.git` is excluded. Empty directories can be copied,
but Git does not track them. Git ignore rules apply when committing.

## Restore from the repository

On a new profile, first select the existing local repository with `init` and the
appropriate `--subdir`. Then use:

```sh
filetrail restore --dry-run
filetrail restore
filetrail restore macos/__HOME__/.zshrc macos/__HOME__/.config/nvim
filetrail restore --track macos/__HOME__/.zshrc
filetrail restore --overwrite macos/__HOME__/.zshrc
```

- Without paths, restore all files under the configured subdirectory's `__HOME__`
and `__ROOT__`; other platform directories and repository READMEs are not restored.
- Multiple files or directories can be selected. Directories are recursive;
overlapping selections are copied once. Current working files are used, including
uncommitted files. `__ROOT__` locations need normal system write permissions.
- Default behavior is copying only, leaving management unchanged. Identical files
are left alone. Different local contents, types, or permissions require
`--overwrite`; local directories are never replaced by files or links.
- `--track` adds restored files and symlinks individually, with deletion disabled.
Extra local files are not added. Compatible existing mappings retain their settings;
disabled or excluded mappings must be adjusted before tracking. Empty directories
are created but not tracked. A `__ROOT__` path that now belongs inside Home must
use the `__HOME__` layout to be tracked.
- `--dry-run` previews both copying and optional tracking. Restore does not delete
extra local files, start the daemon, commit, or run forward synchronization.
- Permissions and symlinks are preserved; link targets are not rewritten or followed.
Symlink ancestors and writes into the repository, application data directory, or
`.git` are refused. Nested `.git` entries are skipped.

Selections and conflicts are checked before copying. An I/O failure can leave
some files restored; fix the error and rerun. Subsequent normal synchronization
still goes from local sources to the repository.

## Review, commit, and resolve conflicts

```sh
filetrail status
filetrail diff
filetrail diff -- macos/__HOME__/.config/nvim
filetrail commit
filetrail commit -m 'Update shell configuration'
filetrail commit -- macos/__HOME__/.zshrc
```

`diff` includes untracked file contents. `commit` includes only managed changes
and refuses unrelated staged changes; preserve the user's staging. A Git name
and email must be configured before committing. Omit `-m` for an automatically
generated message describing the selected changes. Commits do not push.

For stable review while the daemon runs, `pause` automatic sync, inspect with
`status`/`diff`, then `resume` if this task paused it. Preserve a preexisting paused
state. `resume` catches up; explicit `sync` and `add` still synchronize while paused.

```sh
filetrail conflicts
filetrail resolve macos/__HOME__/.zshrc --use-source
```

A conflict means the repository copy differs on first sync or changed outside
FileTrail. `resolve --use-source` explicitly overwrites that copy with the local
source. To choose the repository copy instead, use `restore --overwrite --track`
for that path, subject to tracking compatibility. Another option is to make the
copies identical and synchronize. Finish Git merge/rebase operations and unresolved
Git conflicts before synchronizing or restoring.

Run commits, pushes, overwrites, deletion propagation, and service installation
only within the user's requested scope; do not use them just to clear diagnostics.
Existing authorization need not be requested again.

## Background operation and shell integration

| Command | Effect |
| --- | --- |
| `filetrail daemon start` | Start background synchronization. |
| `filetrail daemon start --poll` | Use periodic scans instead of filesystem events. |
| `filetrail daemon status` | Inspect the daemon. |
| `filetrail daemon restart` | Restart it; `--poll` is also supported. |
| `filetrail daemon stop` | Stop it. |
| `filetrail daemon run` | Run in the foreground; `--poll` is also supported. |
| `filetrail pause` / `filetrail resume` | Pause automatic sync / resume and catch up. |
| `filetrail service show` | Preview the platform's service definition. |
| `filetrail service install` | Install login startup using launchd on macOS or systemd on Linux. |
| `filetrail service uninstall` | Stop the installed service and prevent automatic restarts. |

Place the executable at a stable location before installing its service.

`filetrail completions --install` detects the shell from `$SHELL`; use
`filetrail completions bash --install`, `zsh --install`, or `fish --install` to
choose explicitly. It preserves existing shell configuration. Open a new shell
after installation. Omit `--install` to print a completion script.

With Bash, Zsh, or Fish integration loaded, `filetrail cd` jumps to the repository
root. `command filetrail cd` prints the path; `--print0` selects NUL termination.
For an agent shell without integration, use `cd "$(command filetrail cd)"` in
Bash/Zsh or use the printed path as the next command's working directory.

`filetrail git <args...>` runs system Git in the repository root and prevents
concurrent FileTrail synchronization for the duration. Put FileTrail options
before `git`, e.g. `filetrail --data-dir ~/filetrail-work git status`. All following
arguments, I/O, and exit codes belong to Git. This passthrough uses normal Git
staging, including unmanaged files, and adds no automatic sync or commit.

## Change the target, stop using a profile, or troubleshoot

```sh
filetrail retarget ~/new-dotfiles
filetrail retarget ~/new-dotfiles --subdir linux
filetrail retarget ~/dotfiles --subdir .
```

`retarget` keeps sources, exclusions, deletion settings, and paused/running status.
Omitting `--subdir` preserves its value; `--subdir .` selects the repository root.
It immediately syncs enabled sources. The old repository and history remain.
If initial sync reports conflicts, the target has still changed: review `conflicts`
and resolve against the new repository.

`filetrail deinit` stops the daemon, uninstalls its service, and forgets the profile.
It preserves source files, repositories, Git history, logs, and shell completion.
It is repeatable. To start over, run `init`, add or restore-and-track sources, and
start the daemon or install a service as requested.

Use `filetrail doctor` to validate the setup, `filetrail logs` to read the log,
`filetrail logs --follow` to follow it, and `filetrail <command> --help` for details.
3 changes: 3 additions & 0 deletions skills/filetrail/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface:
display_name: "FileTrail"
short_description: "Sync, restore, and version files with FileTrail"
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod daemon;
pub mod git;
pub mod lifecycle;
pub mod manifest;
pub mod restore;
pub mod service;
mod state;
pub mod sync;
Loading
Loading