There actually is a way to work around this (and to be clear: it is hacky and kinda works by accident. it will probably work until the path work mentioned by Laurenz is done, but no guarantees.)
Here it is:
// /somewhere/else/lib.typ
#let parse-xyz(..args) = {
let data = read(..args)
…
}
// main.typ
#let values = parse-xyz("my/path.xyz");
args
is an arguments
value, and such a value apparently remembers where it was constructed. So when read()
gets all the arguments that parse-xyz()
receives, these arguments are still relative to main.typ
. Whether the loss in readability due to the arcaneness of this behavior is worth it for you is for you to decide