Work in a monorepo
Config discovery walks up from the directory you run gth in, so you don’t have to sit in the
repo root or pass a path. From any package subdirectory, gth finds the nearest .gsloth.config.*
above you — up to, and including, your repo root.
The main use case: one shared config at the repo root
Section titled “The main use case: one shared config at the repo root”Goal: keep a single .gsloth.config.json at the monorepo root and have every package use it,
whatever subdirectory you invoke gth from.
acme-platform/├── .git/├── .gsloth.config.json└── packages/ └── api/ └── src/server.tsRun gth from inside the package:
cd packages/apigth ask "summarise src/server.ts"Discovery walks up packages/api → packages → acme-platform, finds .gsloth.config.json at
the root, and uses it. The walk searches each directory from the current one upward and stops at
(and including) the first directory that contains .git, your home directory, or the filesystem
root — whichever comes first. So a config at or below the git root is found; one above it is
not. In a monorepo the .git sits at the root, which is exactly where the shared config lives, so
the walk lands there and no per-package setup is needed.
Two details that decide which file wins:
- Nearest directory wins — discovery returns the first match and stops; it does not merge
configs from several directories. Within one directory the format order is
.gsloth.config.json→.jsonc→.js→.mjs. - The root config may live either at
acme-platform/.gsloth.config.jsonor, for a tidier root, atacme-platform/.gsloth/.gsloth-settings/.gsloth.config.json; both are discovered by the same walk.
If a package is itself a git submodule (its own .git), the walk stops at that submodule’s root
and never reaches the monorepo root — put a config there, or pass one with -c.
When a package needs its own config
Section titled “When a package needs its own config”Drop a .gsloth.config.json into the package directory. Because the nearest match wins, runs
inside that package use it:
acme-platform/├── .gsloth.config.json # used everywhere else└── packages/ └── ml/ └── .gsloth.config.json # used for runs inside packages/mlThe package config replaces the root config for those runs — it is not merged with it — so it
must be complete on its own (at minimum a valid llm spec). The only layer that merges underneath
a discovered project config is the global ~/.gsloth config, so genuinely cross-cutting settings
belong there rather than being duplicated into each package.
Examples
Section titled “Examples”# From any package subdir — finds the repo-root .gsloth.config.json by walking upcd packages/api && gth ask "summarise src/server.ts"
# Skip discovery entirely and point gth at a specific config filegth -c ./.gsloth.config.json ask "who are you?"
# Package-local config: runs inside packages/ml use packages/ml/.gsloth.config.jsoncd packages/ml && gth ask "which model is configured here?"Related
Section titled “Related”- Config file formats, the
.gsloth/.gsloth-settings/directory, and the full load cascade (global → project → CLI flags): Configuration. - Give a team its own config block under
.gsloth/.gsloth-settings/<name>/: Identity profiles. - Settings shared across every repo go in the global config: Providers & global config.