Harness profiles¶
A profile is a TOML file that describes one harness or one local inference runtime. hlock's harness-aware commands read profiles instead of hard-coding each harness, so supporting a new harness, or fixing a path for an existing one, means editing a file.
What reads which fields
Profiles drive detection, versions and install sources, hlock harness show, targeting,
hlock pin (model, providers, mcp, skills, bundles, instructions,
files), hlock sync (install, files, skills.write, config-root), and
hlock launch (launch, mcp.write, mcp.shape, instructions, and run
for code harnesses), and hlock localize (open-source, local-models,
local-provider, and runtime catalogs).
Where profiles come from¶
Built-in profiles ship with hlock (source:
crates/harness-lock-core/profiles).
hlock then reads these directories, lowest precedence first:
~/.config/hlock/profiles/- each directory in
HLOCK_PROFILE_PATH(:-separated) ./.hlock/profiles/
Each directory holds harnesses/*.toml and runtimes/*.toml. A profile with the same id
as an earlier one replaces it, so you can override a built-in. hlock harness show <name>
prints where the active profile came from.
A harness profile¶
id = "my-agent"
name = "My Agent"
kind = "cli" # cli | framework | custom
aliases = ["myagent"]
binaries = ["my-agent"]
version = { args = ["--version"] }
active-env = ["MY_AGENT_SESSION"] # set by the harness in the processes it spawns
config-root = { env = "MY_AGENT_HOME", default = "~/.my-agent" }
instructions = ["AGENTS.md", "{root}/AGENTS.md"]
[[install]]
method = "npm" # npm | brew | brew-cask | pip | uv-tool | script | app | manual
package = "my-agent"
[[install]]
method = "script"
command = "curl -fsSL https://example.com/install.sh | bash"
path-hints = ["/.my-agent/bin/"] # identifies this method from the binary's real path
[files.settings]
path = "{root}/settings.json"
format = "json" # json | jsonc | toml | yaml
restore = "whole" # whole | pointers | record
[model]
default = ["env:MY_AGENT_MODEL", "settings#/model"]
provider = ["settings#/provider"]
[mcp]
sources = ["settings#/mcpServers"]
write = "settings#/mcpServers"
[skills]
dirs = ["{root}/skills", ".my-agent/skills"]
write = "{root}/skills"
[launch]
model-flag = "--model"
Paths¶
~ is your home directory and {root} is the config root. A relative path is relative to
the project (the current directory). config-root.env is the variable that relocates the
root; when it names a parent directory (like XDG_CONFIG_HOME), add
suffix = "<subdir>". A file that lives outside the root by default but inside it when the
root is relocated (Claude Code's ~/.claude.json) sets isolated = "{root}/…".
Sources¶
model, mcp and providers take ordered lists of sources, and the first one that has a
value wins:
env:VARreads an environment variable.<file>#<pointer>reads a value from a named file in[files], where<pointer>is a JSON pointer, applied to TOML and YAML files as if they were JSON.{cwd}inside a pointer is replaced with the escaped project path (Claude Code keeps per-project MCP servers under/projects/{cwd}/mcpServers).
Set model.format = "provider/model" when the model value carries its provider (OpenCode's
anthropic/claude-sonnet-4-5), or model.default-provider when the harness only talks to one.
Restore policies¶
restore says what a file contributes to a locked setup: whole (the whole file),
pointers (only the subtrees listed in pointers, for files that also hold unrelated state),
or record (a digest only, for project files that are already in git).
Field reference¶
| Field | Meaning |
|---|---|
id, name, aliases |
Identity; any alias works wherever a harness name does |
kind |
cli, framework, or custom (default: cli, or custom with run) |
support |
full or basic (default basic) |
vendor, homepage |
Informational |
binaries |
Names to look up on PATH, in order |
version.args |
Arguments that print the version; the first dotted number is used |
active-env |
Variables whose presence means hlock runs inside this harness |
config-root |
env, suffix, default |
install |
Install methods, most preferred first: method, package, command, path-hints |
files.<id> |
path, isolated, format, restore, pointers |
model |
default, small, provider, base-url sources; format; default-provider |
providers |
source, plus pointers into each provider for base-url and models |
mcp |
sources, write, shape (standard, opencode, codex, goose): how launch writes servers |
skills |
dirs, write, builtin-dirs, builtin-manifest |
bundles |
Plugins/packages: kind, extractor (claude-plugins, pi-packages, npm-list), source, lockfile |
instructions |
Instruction files the harness reads |
launch |
args, model-flag |
open-source, local-models |
Used by hlock localize to choose local-capable harnesses |
local-provider |
How localize points the harness at a local endpoint: a list of { file, set }, where set maps JSON pointers to values; {provider}, {model}, {base_url} and {host} are substituted |
packages |
Packages to pin for code harnesses, e.g. pypi:pydantic-ai |
framework |
For custom harnesses: a framework profile to inherit packages from |
run |
For code harnesses: entrypoint, command, python, env |
A runtime profile¶
id = "my-runtime"
name = "My Runtime"
binaries = ["myrt"]
version = { args = ["--version"] }
ports = [9000] # recognizes a provider base URL like http://localhost:9000/v1
provider-names = ["myrt"] # provider names harness configs use for it
pull = "myrt pull {model}"
serve = "myrt serve"
[models]
layout = "hf-cache" # ollama | publisher-repo | hf-cache
dirs = ["env:MYRT_MODELS", "~/.myrt/models"]
[[install]]
method = "brew"
package = "myrt"
[[catalog]] # models `hlock localize` may pick
id = "my-coder:30b"
params-b = 30
min-memory-gb = 24 # weights plus a working context
tier = 3 # 3 strong agentic coder, 2 capable, 1 small/fast
tools = true # reliable tool calling
roles = [] # e.g. ["small", "decision"]; empty means any
Project harnesses¶
Agents you write yourself don't need a profile file: declare them under
[harnesses.<id>] in harness.toml (see Harnesses).
They accept every harness-profile field, plus entrypoint, command, python and env at
the top level of the table.
If you write a profile for a harness others use, please contribute it.