Feature: expand one custom harness definition into per-profile catalog entries
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
Research direction
Start at the existing load_custom_harnesses and save_custom_harness_to_dir seams, then review the 12 Rust unit tests and the browser spec mentioned in the issue. Check the existing branch implementation against generated read-only entries and the omitted model picker; done means those tests and browser assertions pass and the follow-up PR is ready.
Written by the indexing model from the issue text.
Description
Summary
A custom harness definition (<app-data>/custom_harnesses/<id>.json) describes exactly one runtime entry. When a runtime has a profile-per-directory layout (one command, several isolated homes), the only way to offer each home as a pickable runtime today is one hand-written definition file per profile, kept in sync by hand: add or rename a profile and the runtime dropdown is stale until someone regenerates those files.
This proposes letting one definition declare a variants block, so Buzz derives one catalog entry per detected profile directory from it.
Proposed shape
{
"id": "hermes-profiles",
"label": "Hermes Agent",
"command": "hermes-acp",
"modelSelection": "harness",
"variants": {
"dir": "~/.hermes/profiles",
"marker": "profile.yaml",
"idTemplate": "{id}-{slug}",
"labelTemplate": "{label} [{meta}] ({name})",
"labelFrom": { "file": "profile.yaml", "key": "ui_meta.hermes-bots.title" },
"env": { "HERMES_HOME": "{dir}" }
}
}
dir+marker: which directories count, by marker file, so a directory that is not a profile of that runtime is skipped.idTemplate/labelTemplate:{id},{label},{name}(directory name),{slug}(id-safe directory name), and{meta}fromlabelFrom.labelFrom: read one dotted key out of a file in the profile directory (a persona title, for example), so the entry can readHermes Agent [Generalist] (generalist)rather than just the folder name.args/envplaceholders:{name},{slug},{dir}(the profile directory),{root}(the scanned directory), so the spawned process is pointed at its own profile.- Expansion is capped, and a definition with no
variantsreturns exactly itself as one entry, so nothing changes for existing definitions.
Two things go with it:
- Generated entries are read-only. They carry
generated+generated_from, render without an edit affordance, and name the definition file the user should edit instead. Editing a derived entry would otherwise be silently overwritten by the next scan. modelSelection: "harness". Optional, on any definition. When a runtime owns model choice, the agent config renderer omits the model field with the named reasonownedByHarnessSelectioninstead of showing a picker whose value the harness ignores.
The primitive is deliberately not tied to any one runtime. It covers a profile root, a per-project agent config dir, or any future profile-per-directory layout, and needs no runtime-specific code in the desktop shell.
Related existing reports
Searched open and closed PRs and issues for "harness profile", "custom harness variants", "harness definition profiles", "definitionVariants", "generated_from harness", "variants block harness": no existing work on this primitive.
Closest adjacent reports:
- #5813 Edit Agent dialog: Harness field is not editable (that is the case where an entry is meant to be edited; this is the neighbouring case where an entry should not be, because it is derived).
- #5155 managed-agents.json corruption, duplicate entries, and empty model dropdown when using custom ACP harnesses (custom harness entries meeting the model field).
- #7466 fix(desktop): make starter profiles optional and removable (catalog entry lifecycle).
Status
Implementation is written, tested, and on a branch, with 12 Rust unit tests driven through the existing load_custom_harnesses / save_custom_harness_to_dir seam, a browser spec that asserts the read-only row and the omitted model picker, and two proof frames. PR to follow and cross-link here.
- Dominant language
- Rust
- Stars
- 33.7k
- Forks
- 4.4k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 239
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from block/buzz
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
-
workflow_sink's mention parser never masks code regions — @name inside a code span wakes the agent Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 Half a day Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100