···11+# xdge - XDG Base Directory Specification for Eio
22+33+This library implements the [XDG Base Directory
44+Specification](https://specifications.freedesktop.org/basedir-spec/latest/) for
55+OCaml applications using the [Eio](https://github.com/ocaml-multicore/eio)
66+effects-based I/O library.
77+88+## What is XDG?
99+1010+The XDG Base Directory Specification defines standard locations for user-specific files on Unix-like systems, keeping home directories clean and organized:
1111+1212+- Config (`~/.config/app`): User preferences and settings
1313+- Data (`~/.local/share/app`): Persistent application data
1414+- Cache (`~/.cache/app`): Non-essential cached data (safe to delete)
1515+- State (`~/.local/state/app`): Logs, history, and runtime state
1616+- Runtime (`$XDG_RUNTIME_DIR/app`): Sockets, pipes, and session-bound files
1717+1818+The specification also defines system-wide search paths (`/etc/xdg`,
1919+`/usr/share`) and a precedence system using environment variables
2020+(`XDG_CONFIG_HOME`, `XDG_DATA_HOME`, and so on).
2121+2222+## Why Eio?
2323+2424+Eio uses a **capability-based** approach to I/O where filesystem access must be
2525+explicitly passed to functions. This design aligns naturally with XDG directory
2626+management. For example:
2727+2828+```ocaml
2929+(* Filesystem access is an explicit capability *)
3030+let xdg = Xdge.create env#fs "myapp"
3131+```
3232+3333+The capability model provides the benefit that code that needs filesystem
3434+access must receive the `fs` capability, with no hidden global state or ambient
3535+authority. The `Eio.Path.t` type returned by xdge encapsulates both the
3636+filesystem capability and the path, preventing path traversal outside the
3737+granted capability. Applications can restrict filesystem access by passing a
3838+sandboxed `fs` capability, and xdge respects those boundaries.
3939+4040+## Usage
4141+4242+```ocaml
4343+Eio_main.run @@ fun env ->
4444+ let xdg = Xdge.create env#fs "myapp" in
4545+4646+ (* Access XDG directories as Eio paths *)
4747+ let config = Xdge.config_dir xdg in
4848+ let data = Xdge.data_dir xdg in
4949+5050+ (* Search for files following XDG precedence *)
5151+ match Xdge.find_config_file xdg "settings.json" with
5252+ | Some path -> (* use path *)
5353+ | None -> (* use defaults *)
5454+```
5555+5656+For CLI applications, xdge provides Cmdliner terms that handle environment
5757+variable precedence and command-line overrides:
5858+5959+```ocaml
6060+let () =
6161+ Eio_main.run @@ fun env ->
6262+ let term = Xdge.Cmd.term "myapp" env#fs () in
6363+ (* Generates --config-dir, --data-dir, etc. flags *)
6464+ (* Respects MYAPP_CONFIG_DIR > XDG_CONFIG_HOME > default *)
6565+```
6666+6767+## Installation
6868+6969+```
7070+opam install xdge
7171+```
7272+7373+## License
7474+7575+ISC