Three things live here: where the plugin keeps its files, how it renders a
slopo config, and how it finds, installs and invokes the binary.
The adapter is driven by behaviour observed against slopo 0.8.0 rather than by
its documentation:
* --config is a global option and must precede the subcommand
* every path is written absolute, because slopo resolves relative paths
against the process working directory, not against the config file
* unknown config keys are a hard error, so the renderer writes from a closed
allow-list
* the embedding API key is never written at all -- slopo reads
SLOPO_EMBEDDING_API_KEY from the environment ahead of the file, so the
secret stays out of every file this plugin touches. Enforced in pruneConfig
rather than at the call site, so no future caller can leak it by passing one.
explainFailure maps slopo's deliberately terse agent-facing messages onto a
message and a next step, and reads the log tail because stderr alone leaves the
agent with no move: on a real failure stderr said "Embedding failed." while the
log named the exact litellm parameter that was rejected.
installEnv redirects UV_TOOL_DIR, UV_TOOL_BIN_DIR and UV_PYTHON_INSTALL_DIR
into $DSH_HOME. Only two directories in this container are persistent mounts;
~/.local, where uv installs by default, is on the container's writable layer
and does not survive a recreation.
Every path the plugin owns is under $DSH_HOME. Only two directories in the
container this runs in are persistent volumes ($DSH_HOME and the workspace
root); $HOME/.local -- where 'uv tool install' puts slopo and its CPython by
default -- is on the container's writable layer and dies on recreation, not
merely on restart.
renderSlopoConfig writes from a closed allow-list because slopo treats an
unknown config key as a hard error, and quotes every scalar because a path
can contain a colon or a leading dash. Verified against slopo 0.8.0 itself:
it reads the generated file back with no complaint and round-trips all 19
keys. The embedding API key is deliberately absent -- slopo reads
SLOPO_EMBEDDING_API_KEY from the environment ahead of the YAML value, so the
secret never lands on disk.