Files
hermes-agent/website/docs/reference
alt-glitch c2b13dc3d8 feat(desktop): every desktop chat can install catalog plugins; tools gated by session platform
Toolsets that exist only for one kind of session now say so on their spec:
`platforms=frozenset({"desktop"})`. `TOOLSET_SESSION_PLATFORMS` is derived
from the specs that carry the key, `all` / `*` / no selection skip those
toolsets, and `toolsets.agent_tool_drops(agent)` removes their tools from any
agent whose own session platform is not listed. `agent_init._load_tools` and
`tools/mcp_tool_agent.py` (MCP refresh and prefix restore) call that one
helper. `tool_search._DIRECT_SURFACE_TOOLSETS` is derived from
`CLIENT_SURFACE_TOOLSETS` and `TOOLSET_SESSION_PLATFORMS`.

This replaces the profile-role gate: `profile_role_toolsets`, the role code in
`_with_session_toolsets` and the explicit-pin branch, the strip step in
`_select_tool_names`, and main's `setup` toolset (whose only tool moves out)
are deleted. `manage_catalog` moves into a new `catalog` toolset, which the
desktop client folds into every desktop chat like `project` and `desktop_ui`.
It is deferred behind tool_search by default (`config_defaults` defer list).
The shared-metrics schemas' toolset enum follows (`setup` out, `catalog` in).

The install card works outside the setup chat (#129650, with review fixes):
- Parallel installs: `_set_plugin_enabled` holds a per-home lock around the
  read-then-admit section, so rows enabled at once no longer refuse each other.
- A catalog plugin already on disk and not enabled is enabled in place, so Try
  again after a refused enable can finish.
- A failed catalog row counts as resolved (`contract.resolves`), so it no longer
  holds the turn to the 300 s deadline. The snapshot carries `resolved`, and the
  card reads it instead of a hand copy of the backend's rule.
- Each card draws its own operation by op id, because models reuse call ids.
- The row carries the approved non-secret choices (`approved`: force, enable,
  ref) and the chosen profile, so Try again after the card settled repeats them.
- Install phases are ids (`InstallPhase`, wire `CatalogInstallPhase`) and the
  installed-row notes are fields (`enabled`, `missing_env`, `server_errors`,
  `already_installed`, `requires_hermes`); the card words them in English
  strings (translations follow later). Failure reasons stay raw text, and
  `detail` keeps the English notes for the model.
- Installs and search target the calling chat's own home, carried as a path;
  the row's profile name is only a label, with no `'default'` fallback in
  Python or TypeScript.
- `dashboard_install_plugin` is split into `_resolve_source`, `_place_tree` and
  `_enable_placed`.

Desktop English strings for the card move to `en_catalog_install.ts` /
`types_catalog_install.ts`, which offsets the growth of `en.ts` and `types.ts`.
2026-10-07 01:01:14 +05:30
..
…