steward a file index service for Linux applications

Build

For AI agents

A compact operating guide for agents that help someone use steward, or that write software on top of it. Facts first, then recipes, then the mistakes to avoid.

Every page of this site is also plain Markdown: replace .html with .md. llms.txt indexes them, and llms-full.txt has them all in one file. The API reference is the authority on methods and shapes.

Facts

Is steward here?

test -S "$XDG_RUNTIME_DIR/steward/content.socket" && echo running
steward status | jq '{roots: [.configured[].path], scanning, hashing: .hashing.path}'

If the socket is missing, steward isn’t running. steward service status says whether it is installed as a service; steward version shows the command’s and the daemon’s versions. Don’t start or install it without the user’s agreement.

Ground rules

  1. Read freely; change only when asked. Lookups are harmless. Adding or removing roots, editing settings.toml, forcing hashing of large folders, and exports are the user’s decisions. Ask first.
  2. steward reports; it doesn’t decide. A duplicate list says which files hold identical bytes, not which copy to delete. Never delete or move the user’s files because of something steward said, unless the user tells you exactly what to do.
  3. Check freshness when it matters. Before acting on a path steward returned, confirm it (stat it yourself, or use resolve --recheck). After changing files yourself, tell steward (steward inspect PATHS or steward invalidate DIR).
  4. Offline is not gone. A root or observation marked offline is on an unmounted volume. Its files still exist.
  5. Hashing costs a full read. inspect and cid on a few files are cheap. hash on a media folder can take hours. Don’t start one casually.

Recipes

the user wants do
to know what uses the space steward tree PATH -d 2 (text), or steward raw children '{"path":"/abs/path"}' (JSON)
the size of a folder steward stat PATH \| jq '{total_alloc, total_size, total_files}'
to find files by name steward locate 'pattern': substring, or glob with * ? [; -x exact, -g glob, -r regex, -t d directories only; names only, not contents. Results are confirmed on disk and stale folders rescanned (--check rescan, the default)
the content id of a file steward inspect PATH \| jq -r '.[0].id'
other copies of a file id=$(steward inspect PATH \| jq -r '.[0].id'); steward find "$id"
where some content is now steward resolve ID --recheck: check state and observations[].online
duplicates steward dups PATH (only hashed files count; content-summary shows coverage)
what’s in a git checkout that is ignored or built steward stat PATH \| jq .tags; tags like classify:build-output, classify:ignored
why steward seems behind or busy steward status \| jq '{activity, hashing, problems: .problems[:5]}'
steward to notice a change now steward inspect PATHS (files: rescan + id), or steward scan DIR
to index another folder with consent: steward put-root PATH (add --contentid FOLDER for ids)

Paths can be relative or use ~. The CLI makes them absolute. The raw API needs absolute paths.

Reading results

Writing software that uses steward

Read Building on steward, then the API reference. In short:

from steward_client import Client, ConnectionLost

try:
    with Client(timeout=30) as c:
        [f] = c.inspect(["/home/me/Downloads/file.iso"])
        copies = c.resolve([(f.id, f.size)], recheck=True)[0].online if f.id else []
except ConnectionLost:
    copies = []          # steward isn't available: carry on without it