Expanding Tuist's Cache Infrastructure Beyond Build Systems

Yeah, we can rename it to inputs and outputs. Note that they are cumulative, so you can have multiple lines:

# Maybe not the best example for two lines, but you get the idea :)
#CACHE inputs ["Package.resolved"] hash=content
#CACHE inputs ["Package.swift"] hash=content

I placed it as an interface for developers to configure how they’d like to hash the files (e.g. mtime, size) for cases where developers prefer to trade reliability for speed, but we can start with content as the only supported/default, and only add a different method if we are xplicitly asked for.

That’s correct. We can default to tuist.toml as the source of truth for the configuration and give them the option to override at the script level:

#CACHE project "tuist/automation"

If we want to evolve this into a layer (e.g., like MCPs sit between LLMs/agents and the outside world), we might want to iterate on the concept of “project,” since it’s maybe too tied to Tuist. At the end of the day, the project is a piece of information to scope the data & artifacts on our side (we are the ones calling it a project), so we can come up with an interface that makes that concept more generic.

On the auth side, the good thing is that there’s OAuth2, so the authentication flow could be similar to the one that LLM clients follow (i.e. OAuth2 with dynamic client registration).

#FABRIK input files ["Package.resolved"]
#FABRIK input files ["src/**/*.ts"]

# From command output
#FABRIK input command "swift --version"
#FABRIK input command "tuist version"

# From the execution environment
#FABRIK input platform arch
#FABRIK input platform os
#FABRIK input platform os-version

I think what we are indeed generalizing in this RFC is not just our ability to store binaries and serve them with low latency, but also our ability to store key-value pairs. So it’d be more appropriate to extend the title to say that we are “expanding the selection beyond test selection and expanding caching beyond build system caching”.

With that in mind, we have two types of data “key-value pairs” and “key-large-binary pairs”. While we could persist the former in the latter’s storage, I think it makes sense to stick to our model of using ClickHouse for the former and volumes & object storage for the latter.

Nx does a full replacement and Turborepo merges files when globs like build/** are used. I suggest that we start with a full replacement and iterate from there.

The Cache Client Protocol (CCP) :laughing: