Skip to main content
A declared source names a kind — directory, or one you wrote. The configuration can only choose among kinds that exist; defining one is code, and this page is how that code is written.

The config names a kind and cannot define one

There is nowhere in vitruvio.toml to put a command line. That is deliberate, and it is the reason this feature has no trust-confirmation ceremony: vitruvio.toml is committed and shared, so a field holding an argv would mean that cloning a repository and running source pull executes a stranger’s command. A kind vitruvio does not ship is a Python class you install, either as a file under $XDG_CONFIG_HOME/vitruvio/sources/ or as a vitruvio.sources entry point. Importing a module you wrote from your own configuration directory is code execution at the same trust level as your shell profile. Executing an argv that arrived with a git clone is not, and no prompt makes it so.

Writing a source

Two methods: list() returns what is on offer without fetching any of it, and fetch(item) returns one item’s bytes. They are separate so that a duplicate can be skipped before it is downloaded. When a remote listing omits the real filename or MIME type, return FetchResult(data, media_type=..., title=...) instead of bare bytes. The metadata discovered from the downloaded file is then recorded on the canonical block; a declared media_type still wins. self.options contains the effective merge for this pull, not necessarily only the committed defaults. Reject unknown keys in the constructor so a typo on either source add or source pull fails before fetching anything. Use what BaseSource gives you rather than the bare equivalents. Each carries a bound the naked call does not, and every one of them fails as a hang with nothing on screen: The VITRUVIO_* stripping is not paranoia: a source that shells back into vitruvio while inheriting VITRUVIO_BRAIN writes into the brain that is pulling it. And contain refusing a FIFO is the one that has teeth — read_bytes() on a FIFO blocks forever, and a glob will hand you one without comment.

origin is the dedup key

Make it stable across runs, and strip anything incidental before returning it — a session token, a rotating query parameter. Only the source knows which parts of its own addresses are meaningful. vitruvio case-folds it, so two origins differing only in case collide; the worst case is a spurious skip.