Files
gitmost/agent-roles-catalog
claude_code 20ad272c23 feat(ai-roles): add importable, multilingual agent roles catalog
Admins can browse a curated catalog of agent roles, import roles/bundles
into a workspace, and update an imported role when the catalog ships a
newer version.

Catalog: a set of JSON files (index.json manifest + bundles/<id>/<lang>.json)
served from a local folder (dev) or a remote http(s) base URL via
AI_AGENT_ROLES_CATALOG_URL. Seeded with the existing 7 RU roles (editorial +
research bundles) plus EN translations.

Server:
- migration: nullable jsonb `source` column on ai_agent_roles
  ({ slug, language, version }; null => manually created)
- catalog provider: remote fetch with timeout + streaming size cap, or local
  read; ^[a-z0-9-]+$ segment guard against path-traversal/SSRF
- admin endpoints: catalog, catalog/bundle, import, update-from-catalog
- import/update match by slug+language; update preserves `enabled`

Client:
- catalog modal with language selector and Import/Installed/Update states
- "Import from catalog" button + empty-state CTA in the roles settings panel
- en-US/ru-RU strings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 19:26:30 +03:00
..

Agent roles catalog

This directory is data, not application code. It holds the content of an "agent roles catalog": reusable agent role definitions (system prompts plus a little metadata), grouped into bundles and translated into one or more languages. A separate server reads these files and serves them; nothing here is executable application logic except the validation script.

File layout

agent-roles-catalog/
  index.json                  # the catalog manifest: bundles, languages, role versions
  bundles/
    <bundle-id>/
      <lang>.json             # one file per declared language (e.g. ru.json, en.json)
  scripts/
    check.mjs                 # validates the catalog (no dependencies)
  package.json                # defines the `check` script
  README.md

Currently shipped bundles:

  • editorial — the editorial suite (structural-editor, line-editor, copy-editor, fact-checker, proofreader, narrator), languages ru, en.
  • research — a single researcher role, languages ru, en.

index.json schema

{
  "schemaVersion": 1,
  "bundles": [
    {
      "id": "editorial",                       // unique bundle id; matches bundles/<id>/
      "name": { "ru": "...", "en": "..." },    // localized display name
      "description": { "ru": "...", "en": "..." },
      "languages": ["ru", "en"],               // which <lang>.json files must exist
      "roles": [
        { "slug": "structural-editor", "version": 1 }
        // ...
      ]
    }
  ]
}

version lives here, in index.json, per role. Bump it whenever a role's content (instructions, name, description, etc.) changes, so consumers can detect updates.

Bundle (<lang>.json) schema

{
  "schemaVersion": 1,
  "language": "ru",
  "roles": [
    {
      "slug": "structural-editor",   // REQUIRED, unique across the whole catalog
      "emoji": "🧱",
      "name": "...",                 // REQUIRED, localized
      "description": "...",          // localized
      "instructions": "...",         // REQUIRED, the system prompt, localized
      "autoStart": true,             // whether the role starts working immediately
      "launchMessage": "..."         // first message sent on launch (or null)
    }
  ]
}

Notes:

  • modelConfig is intentionally absent; the server treats an absent modelConfig as null.
  • A role's slug, emoji, and autoStart are identical across all language files of the same bundle. Only name, description, instructions, and launchMessage are translated.

Slug uniqueness

Every slug must be UNIQUE ACROSS THE WHOLE CATALOG, not just within a bundle. A slug appears once per language file of its bundle (same slug in ru.json and en.json), but no two different bundles may share a slug. scripts/check.mjs enforces this.

How to add things

Add a role to an existing bundle

  1. Add an entry to that bundle's roles[] in index.json with a new unique slug and version: 1.
  2. Add a role object with the same slug to every <lang>.json of the bundle, translating name, description, instructions, and launchMessage.
  3. Run the check (see below).

Add a bundle

  1. Add a bundle object to index.json (id, name, description, languages, roles).
  2. Create bundles/<id>/<lang>.json for each declared language, with one role object per roles[] entry.
  3. Run the check.

Add a language to a bundle

  1. Add the language code to that bundle's languages[] in index.json.
  2. Create bundles/<id>/<lang>.json containing every role of the bundle, translated.
  3. Run the check.

Change a role's content

Edit the role in the relevant <lang>.json file(s) and bump that role's version in index.json.

Validating

From this directory:

node scripts/check.mjs   # or: npm run check

It fails (exit code 1) if any slug is duplicated across the catalog, if a bundle's index roles[] don't match the slugs present in each language file, if a declared language file is missing, or if any role is missing a required field (slug, name, instructions). It prints OK on success.