Re-lands the install.sh regression suite from #772 (reverted in #827) together
with the guard change that makes it pass, so CI goes green in one step.
Background. #825 made --path refuse more than one --tool, on #819's report that
several tools sharing one destination clobber each other. That was right in
spirit and over-broad in practice, and it was implemented without verifying
the premise. Measured by installing one agent with every tool into a sandbox
and comparing what landed:
<division>-<slug>.md (raw copy) claude-code, copilot
<slug>.md (converted) gemini-cli, opencode, qwen, zcode
agency-<slug>/SKILL.md antigravity, osaurus
Tools in the same group write identical filenames and silently overwrite each
other (qwen + gemini-cli lose a file while both print [OK]). Tools in different
groups coexist (claude-code + codex, claude-code + qwen). Every other tool's
output is distinct.
The guard now refuses --path only for a colliding pair, naming both tools and
the reason, and allows the rest. path_collision_group() holds the measured
table; re-measure if a converter's naming changes.
The suite's two-tool --path cases used claude-code + copilot, which collide:
the "installs exactly one agent" count of 1 was passing because copilot had
overwritten claude-code's identical file. They now use claude-code + codex and
assert that BOTH outputs survive, which a single count cannot show; a new case
asserts the colliding pair is refused. codex has no committed output, so those
cases convert (only the two raw-copiers work under --no-convert in a fresh
checkout).
Verified under bash 3.2 (the macOS CI leg): 29 passed, 0 failed, 1 xfail.
Guard spot-checked against all three measured groups plus a cross-group pair.
Suite, workflow and CONTRIBUTING note by @SergiorCode (#772). Refs #772#819#825#827.
Co-Authored-By: SergiorCode <SergiorCode@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test(install): add a regression suite for install.sh + CI on Linux and macOS
install.sh is the largest script in the repo and has no tests. Every install
bug so far has been a silent one — agents copied to the wrong directory, a
path with a space split in two, a filter that installed everything — and the
only signal was a user noticing later.
scripts/test-install.sh pins the installer's observable contract:
* destinations: default $HOME/.claude/agents, --path override, tool env var
override, and --path winning over the env var
* selection: --division, --agent, --agents-file (comments/blank lines)
* --dry-run writes nothing; unknown --tool exits non-zero
* --link produces symlinks; a second run installs the same set, not dupes
* a destination containing spaces stays one directory
Expected counts are derived from divisions.json + lib.sh at runtime, so the
suite doesn't need updating when agents are added. Every case runs with HOME
pointed at a throwaway sandbox, so a broken default path can never write into
the real config. bash 3.2 + BSD userland, no new dependencies.
Verified it fails on the regressions it claims to catch: unquoting install_file
fails only the spaces case, neutering slug_allowed fails the four selection
cases, un-short-circuiting --dry-run fails the dry-run case, and ignoring the
env var in resolve_dest fails the env-override case.
CI runs it on ubuntu-latest and macos-latest (macOS ships bash 3.2, Linux
ships bash 5) plus bash -n over every script in scripts/.
* test(install): pin the parallel worker argument regression (#755)
Review feedback: the existing "paths with spaces" case selects a single tool,
so it stays on the serial path and never reaches the worker spawn where #755's
bug lives. Adds a case that does.
--tool claude-code,copilot --parallel --jobs 1 --agents-file <spaced path>
--path "<home>/My [Agents]/dest dir"
with a serial control immediately before it (same two tools, same spaced and
globbed --path, no --parallel) so a failure is attributable to the worker
hand-off rather than to the selection filter.
Marked xfail rather than a hard assertion: it fails on main today and passes
with #755 applied, and encoding a known-broken case as a hard failure would
turn CI red for reasons unrelated to whatever PR is being reviewed. xfail
never fails the suite; when the case starts passing it prints a note to
promote it to assert_eq (one-word edit). Measured on macOS bash 3.2.57:
main -> 25 passed / 1 xfail, #755 applied -> 26 passed / 0 failed, both
deterministic over repeated runs.
Note on --jobs 1: workers are still spawned through the same xargs/sh
hand-off, so argument propagation is exercised in full. Serializing them
keeps a second, unrelated defect out of this case — with two workers running
concurrently against one shared --path, the parent exits non-zero on ~3 runs
in 5 once the workers actually copy anything (one worker's cp fails with
ENOENT on the shared destination). That race is invisible on main only
because the workers currently install nothing at all; --jobs 1 or per-tool
destinations are clean. Reported in the PR discussion.
Contributors keep reaching for the same fix when a description contains ": "
and breaks YAML frontmatter: double-quote the source scalar (#473 for
zk-steward, re-proposed in #548, and again in #810). #778 fixed the same
problem one layer down by having the converters emit quoted scalars. The two
compose badly: get_field returned a quoted source's quotes as content, so
yaml_quote wrapped them again and every generated file for an already-quoted
agent shipped as description: '"..."' with a literal quote leaking into the
parsed value. zk-steward and ai-data-remediation-engineer are affected on
main today.
get_field now treats one matching outer pair of double or single quotes as
delimiters: it strips them and unescapes (\" -> ", \\ -> \, '' -> '). Quoting a
source description is now safe and harmless, so #473/#548/#810's instinct and
#778's generator-side fix reconcile. Unquoted sources are unchanged.
Verified in a sandbox end-to-end (source -> convert.sh -> parsed YAML):
zk-steward and ai-data-remediation-engineer no longer leak a quote and keep
their internal apostrophes; developer-tooling-engineer (unquoted, contains
": ") is byte-identical to before; synthetic '...''...' and "...\"...\\" cases
unescape correctly. lib.sh is only ever sourced by bash (its shebang); note
`repeat()` at the top of the TUI section is a zsh reserved word, so sourcing
lib.sh from a zsh shell errors — pre-existing and unrelated.
Refs #473#548#810#778
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Four install/convert bugs reported by @sunilkumarvalmiki (#817-#820), each
verified in a sandbox before and after the change.
- convert.sh --tool all --parallel silently skipped kimi: the parallel batch
listed 11 tools and the sequential batch 2, so the 14th tool ran in neither
(kimi output: 0 files vs 273 for every other tool). Add kimi to the parallel
batch — it writes to its own integrations/kimi/<slug>/ dir so it is
parallel-safe. (#817)
- The sequential batch's progress counter was hardcoded idx=8, stale from an
older batch size, printing "aider (8/14)" instead of 12/14. Derive it from
the parallel list length so it can never drift again; now prints 13/14 and
14/14. Same root cause as #817. (#818)
- --path is a documented single-destination override; with several --tool
values every tool resolved to the same directory and clobbered each other.
Refuse --path with more than one tool. Deliberately NOT restricting the path
itself: the override is the supported way to redirect installs (e.g. to a
sandbox), and validating it against an expected dir would break that. (#819)
- clean_tool_output runs rm -rf on $OUT_DIR/$1. The tool name is validated
upstream so this is not reachable today, but a plain-slug guard on $1 makes a
future direct caller unable to steer it outside $OUT_DIR via "../" or "/".
A prefix check would not do: "$OUT_DIR/../x" still starts with the prefix. (#820)
Fixes#817Fixes#818Fixes#819Fixes#820
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* Add Research division with Research Synthesist agent
New division for literature review, source evaluation, and evidence
synthesis. Wired into divisions.json, convert.sh, lint-agents.sh,
install.sh, and the lint-agents CI workflow.
* chore(hermes): regenerate agent count 272 -> 273 for research division (#770)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Prashant Raj Bista <prashant.bista.18@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Vendor specialist for Huawei's GaussDB OLTP (enterprise relational DB) —
performance tuning, high availability, and migration. A niche enterprise/
China-market addition, distinct from the general database-optimizer.
Gate: lint 0/0, originality 4.7% (shared DB terminology with database-optimizer,
well under thresholds), 1 H1 + 5 sections + 7 code blocks. All guards green
(divisions/tools/runbooks/hermes); Hermes roster 262 -> 263.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: opswm <opswm@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Production RAG pipeline specialist: chunking strategy, retrieval quality,
hybrid search, re-ranking, and eval-driven iteration. Retrieval-first
debugging mindset ("the retrieval is the crime scene, I have the evals").
Chosen over the concurrent #686 (RAG Engineer) as the keeper: same concept,
but #601 is more complete (2x content, 7 code blocks) and was submitted first.
Gate: lint 0/0, originality 0.0%, 1 H1 + 9 sections + 7 code blocks, valid
division. All guards green (divisions/tools/runbooks/hermes); Hermes roster
261 -> 262.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: MaedehJJ <MaedehJJ@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Candidate-side resume optimization: JD-to-experience mapping, ATS keyword
alignment, role-requirement matching. Landed on a fresh branch (the original
#586 had a stale README conflict) with the roster row authored here.
Gate: lint 0/0, originality 0.0%, 1 H1 + 14 sections + 5 code blocks, valid
division. All guards green (divisions/tools/runbooks/hermes); Hermes roster
picks it up (260 -> 261).
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: rshivam973 <rshivam973@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Consolidates five gated PRs into one merge (each edited the README roster,
so landing individually would cascade conflicts):
- Security: AI-Generated Code Security Auditor, Secrets & Credential Hygiene
Engineer (#647, #648 — @Synvoya)
- Engineering: Database Reliability, Developer Tooling, IoT Fleet Engineer
(#705 — @Hotragn)
- Specialized: Codebase Archaeologist (#681 — @Axion-Web-dev)
All six cleared the full gate: lint 0/0, originality 0.0-0.1% (no dupes vs
roster or each other), proper structure, valid divisions. Roster rows added
to the Security/Engineering/Specialized tables (every link verified). Full
guard suite green — divisions, tools, runbooks, and the Hermes plugin guard —
and the Hermes roster picks up all six (254 -> 260 agents).
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Synvoya <Synvoya@users.noreply.github.com>
Co-authored-by: Hotragn <Hotragn@users.noreply.github.com>
Co-authored-by: Axion-Web-dev <Axion-Web-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat(tools): add ZCode (Z.ai GLM agent harness)
ZCode reads per-agent markdown from `.zcode/agents/{slug}.md` (project) and
`~/.config/zcode/agents/{slug}.md` (global), with `name` + `description` YAML
frontmatter and an optional `tools` list — the same plain-agent-markdown shape
as Qwen.
- tools.json: add the `zcode` entry (dual-scope, per-agent, format `zcode-md`).
- convert.sh: add `convert_zcode` (byte-identical to the qwen converter,
output to integrations/zcode/agents/) + register in the dispatch, valid_tools,
tools_to_run, and parallel_tools.
- install.sh: add `zcode` to ALL_TOOLS, `install_zcode`, `detect_zcode`, and the
resolve_dest / bin / is_detected / display / label dispatches.
Directories + file format verified against ZCode's published docs. Renderer
contract: `zcode-md` output is byte-identical to `qwen-md`, verified by
diffing `convert.sh --tool zcode` against `--tool qwen` (243/243 files match).
check-tools.sh passes (16 tools consistent across tools.json, install.sh, and
convert.sh); bash -n clean on both scripts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WdX6PvnCfRgYD11yVpXVor
* zcode: gitignore generated output + add integration README
Bring the ZCode integration in line with the other tools: the 243 generated
agent files (integrations/zcode/agents/*.md) are output of `convert.sh`, not
source — add a .gitignore rule so they can't be committed, and add
integrations/zcode/README.md documenting generate/install (matching the vibe
and qwen integration READMEs).
Verified: generated agents are now git-ignored, the README is tracked, and
check-tools.sh still passes at 16 tools.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
* zcode: fix user-scope install path to ~/.zcode/agents (per ZCode docs)
The user-scope dest was ~/.config/zcode/agents/, but the official ZCode docs
state subagents are read from ~/.zcode/agents/<name>.md — so user-scope
installs landed where ZCode never looks. (detect.agentsDir and project scope
were already correct at .zcode/agents, so this was an internal inconsistency.)
Point tools.json dest.user, install_zcode's default, the header comment, and
the list display at ~/.zcode/agents; drop the stale ~/.config/zcode detection
clause; update the integration README. Keep format `zcode-md` distinct — ZCode's
native format supports color/model/permissions, so it will diverge from gemini-md
as the converter matures rather than being a permanent alias.
Verified: a default user-scope install now writes to ~/.zcode/agents/<slug>.md
(not ~/.config/zcode); check-tools.sh passes at 16 tools; install.sh syntax and
tools.json JSON both valid.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
`grep -q` exits at its first match without draining stdin, killing the
piping `echo` with SIGPIPE. Under `set -o pipefail` that 141 becomes the
pipeline's status, which is indistinguishable from "no match" — so a
section that is present gets reported missing. The race only surfaces on
bodies large enough that `echo` is still writing when `grep` bails, which
made the warning set differ between identical runs (full repo: 106/87/90
warnings across three runs; now a stable 59).
Feed both checks from a herestring so there is no writer to signal.
Co-authored-by: Jaak Vaher <jaak.vaher@cyber.ee>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
convert.sh's OpenClaw conversion routes persona sections (Identity,
Communication, Critical Rules, Style, Learning & Memory) to SOUL.md and
everything else to AGENTS.md by matching `## ` header keywords. 15 agents
produced an empty SOUL.md because no header matched — the same class as the
#670 fix. Two distinct causes, two minimal fixes:
- 13 agents used a `##`-level persona section under a non-canonical name
("Role Definition" / "Core Expertise"). Renamed to "Identity & Role
Definition" / "Identity & Core Expertise" — header text only, zero content
change (each is a clean +1/-1 diff).
- 2 agents (french-consulting-market, salesforce-architect) had full persona
sections but at `#` (H1) with no title — the literal #670 bug. Shifted every
header one level deeper (fence-aware, so code-block content is untouched) and
added a `# <Name>` title. These now lint 0/0.
Verified: 0 "no section headers map to SOUL.md" warnings remain (was 15);
regenerated OpenClaw output confirms all 15 SOUL.md files are now populated
with the persona; AGENTS.md retains operations; no agent content changed;
guards green. Total lint warnings 87 -> 59 (remaining are advisory
"missing Core Mission/Critical Rules", intentionally not forced).
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Agent developed by Snark Health (github.com/snark-health).
Snark Health was founded by a practicing US physician with 25 years
of internal medicine and infectious disease experience and direct
leadership of a $2 billion risk-based Medicare bundled payment
contract with the US government, and a Kenyan engineer and operator
whose collaboration with the founding physician began in 1998 in
rural western Kenya. The frameworks in these files come from a team
that has delivered care in both US hospital systems and
resource-limited settings, managed actuarial risk under government
contract, and built health infrastructure across two continents
over 25 years.
AI Collective OS: snarkhealth.ai
Agent registry: snarkhealth.ai/registry
Consolidates ten agent PRs from @Hotragn into one merge (they each edited
the README roster, so landing them individually would cascade conflicts):
- Engineering: Search Relevance, Identity & Access, Realtime Collaboration,
Desktop App, Mobile Release, Video Streaming, FinOps, WebAssembly,
API Platform
- Academic: Statistician
All ten cleared the gate: lint 0/0, originality 0.0–0.1% (no dupes vs the
roster or each other), proper structure, valid divisions. Roster rows added
to the Engineering and Academic tables; every link verified.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Hotragn <Hotragn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The five gov-tech agents (#580–#584) merged as agent-only PRs without
roster rows. Add them to the README division tables:
- Engineering: Drupal Performance, WordPress Performance, Section 508
Accessibility Specialist, USWDS Developer
- Specialized: FedRAMP & RMF Compliance Engineer
Docs only; every link verified to resolve to a committed agent file.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat: add FedRAMP & RMF Compliance Engineer agent to Specialized Division
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: update FedRAMP agent for Rev5/20x dual-pathway, KSIs, and NIST 800-53 Rev 5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat: add Section 508 Accessibility Specialist agent to Engineering Division
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix: correct WCAG/508 legal baseline accuracy in Section 508 Specialist agent
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
XDC Network is an EVM-compatible L1 (XDPoS consensus) worth knowing
alongside Arbitrum/Optimism/Base/Polygon. It supports EIP-1559 on both
mainnet and the Apothem testnet, so it behaves as a standard EVM target
for gas estimation and tooling.
Two references in README.md still pointed at the old
`~/.gemini/antigravity/skills/` path. Per the current Antigravity spec
(verified against Google's July 2026 docs), the canonical global skills
path for all three flavors — Antigravity, AGY CLI, AGY IDE (incl. 2.0) —
is `~/.gemini/config/skills/`. #667 fixed integrations/README.md; this
fixes the two that remained in the top-level README, so every path
reference in the repo now agrees with tools.json/convert.sh/install.sh.
Verified: zero `gemini/antigravity/skills` references remain repo-wide.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
- Antigravity installs to ~/.gemini/config/skills/ per antigravity/README.md,
convert.sh, and install.sh — the index was the sole outlier still saying
~/.gemini/antigravity/skills/
- Mistral Vibe is first-class in convert.sh and install.sh and has its own
integrations/vibe/README.md, but was missing from the Supported Tools index
(The originality-gate fix originally in this PR was superseded by #659.)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Two marketing agents had malformed heading structure that broke the
OpenClaw conversion, which buckets sections by `^## `:
- ai-citation-strategist used H1 (`#`) for its section headers (Identity,
Communication, Rules, Mission, Deliverables, Workflow, Metrics,
Capabilities), so none matched `^## ` — SOUL.md came out nearly empty and
everything landed in AGENTS.md. Promote those section headers to `##`
(leaving template content inside code fences untouched) and add a proper
`# AI Citation Strategist` H1 title.
- agentic-search-optimizer was the only file in the division with no H1
title (body opened at `## Your Identity & Memory`). Add
`# Agentic Search Optimizer`.
Verified: lint-agents passes (0/0), and the regenerated OpenClaw output now
splits correctly — SOUL.md carries the persona sections (Identity,
Communication, Critical Rules) instead of an empty file.
Fixes#670
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The help text advertised `--tool <a,b>` (a comma list), but --tool took a
single value and validated it whole, so `--tool claude-code,cursor` failed
with "Unknown tool 'claude-code,cursor'". --division and --agent already
split on commas; --tool didn't (#671).
Split --tool on commas, trim each entry, and validate each against
ALL_TOOLS (mirrors --division), so a bad entry still errors clearly by
name. Single-tool use is unchanged.
Verified: --tool claude-code,cursor installs both; "claude-code, cursor"
(with spaces) works; --tool claude-code,nope errors on 'nope'; --tool
cursor still works.
Fixes#671
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
install.sh hardcoded the division set in two lists (AGENT_DIRS,
ALL_DIVISIONS), and both had gone stale — missing healthcare (#655). So
`--tool claude-code`/`copilot` skipped healthcare's 2 agents,
`--division healthcare` errored "Unknown division", the interactive team
list omitted it, and the agent count was low by 2 (#668).
Derive both lists from divisions.json (the single source of truth), using
the same no-jq awk/grep/sed parse as check-divisions.sh. ALL_DIVISIONS is
now exactly the divisions.json entries; AGENT_DIRS is that set plus
strategy/ (preserving the intentional scan of its frontmatter-less docs,
which is_agent_file filters out). This is the same fix pattern as #659
(check-agent-originality.sh) and #666 (build-hermes-plugin.py): a derived
list can't drift, so check-divisions.sh needn't be extended to cover it.
Verified: ALL_DIVISIONS resolves to 17 (healthcare in, strategy out),
strategy still scanned, and `--division healthcare --dry-run` now finds
2 agents instead of "Unknown division".
Fixes#668
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
install_hermes() resolved `dest` from HERMES_PLUGIN_DIR and ran `rm -rf
"$dest"`. The var name invites setting it to the plugins *parent*
(~/.hermes/plugins) rather than the full plugin path, in which case the
rm -rf wiped the entire plugins directory and every other plugin in it.
Always target the agency-agents-router subdir (append it when the resolved
path doesn't already end in it), and add a defensive guard that refuses to
remove any path whose basename isn't `agency-agents-router`. Verified: with
HERMES_PLUGIN_DIR set to the plugins parent, a sibling plugin's data now
survives the install.
Fixes#669
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Two correctness fixes to the Hermes plugin generator:
1. slug alias (#665): agency_agents_search returns results keyed by `slug`,
but load/inspect/delegate only accepted a param named `agent`, so the
natural chain search -> load(slug=...) failed with "agent not found".
Add `slug` as an optional alias across the READ/PROMPT/DELEGATE schemas
and resolve either key in the handlers (via _identifier), with a clear
"agent or slug is required" error when neither is passed. Backward
compatible; `required` relaxed to [] (task-only for delegate).
2. division drift: AGENT_DIRS was a hardcoded copy of the division list that
the bash check-divisions.sh guard can't see (it's a Python list), so it
silently dropped healthcare (#655) — the two healthcare agents were
missing from the Hermes roster. Derive the division dirs from
divisions.json instead (mirrors the #659 fix to check-agent-originality.sh),
so the roster stays in sync with the catalog by construction.
Verified on the regenerated plugin: roster is 235 agents (healthcare now
indexed); search "clinical evidence healthcare" -> inspect(slug=...) resolves
to Clinical Evidence Agent — exercising both fixes together. agent= still works.
Fixes#665
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
check-agent-originality.sh hardcoded its own copy of the division list
(AGENT_DIRS) in the Python heredoc — a 5th copy that check-divisions.sh's
bash-array parser never saw, so it drifted: it was missing `gis` and
`security` and still carried the retired `strategy`. The practical effect
was that every gis/ and security/ agent — including newly added ones —
skipped the duplicate-detection scan entirely.
Read divisions.json directly instead of hardcoding, so this check can
never drift from the catalog again. Now scans all 16 divisions; verified
green in full-audit mode.
Supersedes #649/#650, which patch the hardcoded constants rather than
removing them.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Two related drift traps, both from hand-typed numbers/lists that no guard
watches:
1. CONTRIBUTING had no "how to add a tool" checklist, and its wording
("all output is gitignored") implied gitignoring was automatic — so
tool contributors kept committing generated integrations/<tool>/ output.
2. The division set and agent/division counts were hardcoded in prose in
several places and had already gone stale (CONTRIBUTING said "16" and
omitted healthcare; EXECUTIVE-BRIEF said "9 divisions").
Changes:
- Add an "Adding a Tool Integration" checklist to CONTRIBUTING (discuss-first,
reuse an existing `format`, the ~5-file touch list incl. the required
.gitignore rule, run check-tools.sh). Harmonize the "committed build
output" policy line to point at it.
- De-hardcode the division list in CONTRIBUTING — defer to divisions.json.
- Stop scattering roster counts: strategy/EXECUTIVE-BRIEF ("9 divisions") and
check-agent-originality.sh ("184-agent library") drop the number entirely;
README keeps a showcase stat but softens "232 across 16" to "230+ across
every division" so it never becomes a lie as the roster grows.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The app can't reliably resolve runbook rosters from display names (catalog
slugs are inconsistently division-prefixed, and names drift). This adds a
machine-readable manifest so the app reads rosters as data and maps each
slug to a catalog agent for one-click team deploy.
- strategy/runbooks.json: the 4 NEXUS scenarios (startup-mvp,
enterprise-feature, marketing-campaign, incident-response), each with
mode, duration, summary, doc, and a grouped roster. Every agents[] entry
is a verified slug = the agent .md filename stem (the corpus id), resolved
against the live roster — not a slugified display name. (Notably
"Senior Project Manager" is project-manager-senior, NOT
project-management-senior-project-manager, which naive mapping assumes.)
- scripts/check-runbooks.sh + .github/workflows/check-runbooks.yml: guard
(mirrors check-divisions.sh) failing the build if any roster slug doesn't
resolve to a real agent file, a doc path is missing, or JSON is malformed —
so renaming/removing an agent can't silently break the app's deploy.
All 64 slug references verified; guard passes and fails correctly.
Claude-Session: https://claude.ai/code/session_01WKnDRWM4izsB8WAXKszhsq
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Add Mistral Vibe support for Agency agents
- Add Mistral Vibe entry to tools.json with proper configuration
(id, label, kebab, format, installKind, dest, detection, version)
- Implement convert_vibe() function in convert.sh for Mistral Vibe's format
- Generates TOML agent configuration files (~/.vibe/agents/<slug>.toml)
- Generates markdown prompt files (~/.vibe/prompts/<slug>.md)
- Each agent gets agent_type and system_prompt_id (no hardcoded active_model)
- Add install_vibe() function in install.sh with full feature support
- Copies both agent TOML and prompt MD files
- Supports division/agent filtering and environment variable overrides
- Uses VIBE_HOME environment variable for custom install paths
- Add Mistral Vibe detection and tool labeling
- Add Mistral Vibe to all necessary case statements and arrays
- Update README.md to document Mistral Vibe support
- All changes validated with scripts/check-tools.sh
Mistral Vibe uses a two-file approach per agent:
- ~/.vibe/agents/<slug>.toml for agent configuration
- ~/.vibe/prompts/<slug>.md for system prompts
Users can specify active_model in their agent TOML files or rely on their
Vibe configuration default model.
Usage: ./scripts/install.sh --tool vibe [--division X] [--agent Y]
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
* Address PR #658 review feedback: add .gitignore, README, and fix icon
- Add integrations/vibe/README.md documenting the Mistral Vibe integration
- Update .gitignore to ignore integrations/vibe/agents/ and prompts/
- Update convert.sh usage() to include vibe in the tool list
- Fix tools.json: change vibe icon from 'mistral' to null (no mistral.svg)
- Bonus: update vibe accent color from #FF69B4 to #FA520F (Mistral brand orange)
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
---------
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
Agents developed by Snark Health (github.com/snark-health).
Snark Health was founded by a practicing US physician with 25 years
of internal medicine and infectious disease experience and direct
leadership of a $2 billion risk-based Medicare bundled payment
contract with the US government, and a Kenyan engineer and operator
whose collaboration with the founding physician began in 1998 in
rural western Kenya. The frameworks in these files come from a team
that has delivered care in both US hospital systems and
resource-limited settings, managed actuarial risk under government
contract, and built health infrastructure across two continents
over 25 years.
AI Collective OS: snarkhealth.ai
Agent registry: snarkhealth.ai/registry