LibrePortal/containers/matrix/tools/matrix.tools.json
librelad 5b6ed924d2 fix(chat tools): wire list_users into the WebUI user-list modal
The Tools tab has an interactive modal: when a list_users task completes it
parses the task log for EZ_USER lines and renders one row per account with
reset / promote / delete buttons. All four new apps failed its contract in every
respect, so running List Users produced log text and nothing else.

- The marker is EZ_USER, tab-separated as email, username, roles. Matrix and
  Stoat emitted LP_USER in a different field order; Mattermost and Rocket.Chat
  emitted no marker at all.
- Matrix and Stoat then consumed their own marker lines in the formatting loop
  and printed only the pretty version, so nothing reached the log to parse.
- The row buttons look up tools by id: reset_password, set_admin, delete_user.
  The deactivate tools were named deactivate_user / disable_user, so no delete
  button rendered.
- Prefill only fills a field named email or username. Rocket.Chat's and Stoat's
  identifier field was called user, so a row action would have opened with an
  empty box.
- '-' placeholders are truthy, so the modal's `email || username` fallback
  picked '-' over the real username for accounts without an email (rocket.cat).
  The EZ_USER line now carries an empty string; '-' stays in the readable line.

Mattermost's listing is rebuilt on `mmctl --json`, which carries roles and
delete_at. The text listing has neither, and there is no --system-admin filter
on user list, so every account was reported as a plain user. Two parsing notes
that cost time: mmctl prints status lines both before and after the JSON, so it
needs raw_decode rather than json.loads; and --per-page above 200 makes it emit
a warning line ahead of the payload.

The modal's delete button also stops asserting "Delete user" over whatever the
tool actually does — it takes its label and icon from the tool, because most of
these deactivate and Matrix cannot delete at all.

Verified by replaying the modal's own parser over real tool output: 2 rows for
Matrix, 4 for Mattermost, 3 for Rocket.Chat, with admin and deactivated states
resolving correctly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:23:12 +01:00

107 lines
2.7 KiB
JSON

{
"tools": [
{
"id": "create_account",
"category": "users",
"label": "Create User Account",
"description": "Add a Matrix account. The username becomes permanent — @name:server can never be renamed.",
"icon": "👤",
"fields": [
{
"name": "username",
"label": "Username",
"type": "text",
"placeholder": "alice (not the full @alice:server)",
"required": true
},
{
"name": "displayname",
"label": "Display name",
"type": "text",
"placeholder": "Leave blank to use the username"
},
{
"name": "password",
"label": "Password",
"type": "password",
"placeholder": "Leave blank to generate"
},
{
"name": "admin",
"label": "Make server admin",
"type": "checkbox",
"default": false
}
]
},
{
"id": "list_users",
"category": "users",
"label": "List Users",
"description": "Every account on this homeserver, including deactivated ones.",
"icon": "📋",
"fields": []
},
{
"id": "reset_password",
"category": "users",
"label": "Reset User Password",
"description": "Set a new password and sign the user out of every device.",
"icon": "🔑",
"fields": [
{
"name": "username",
"label": "Username",
"type": "text",
"placeholder": "alice",
"required": true
},
{
"name": "password",
"label": "New password",
"type": "password",
"placeholder": "Leave blank to generate"
}
]
},
{
"id": "set_admin",
"category": "users",
"label": "Set Admin Status",
"description": "Grant or revoke Synapse server-admin rights.",
"icon": "👑",
"fields": [
{
"name": "username",
"label": "Username",
"type": "text",
"required": true
},
{
"name": "admin",
"label": "Make server admin",
"type": "checkbox",
"default": false
}
]
},
{
"id": "delete_user",
"category": "users",
"label": "Deactivate User Account",
"description": "Matrix has no delete. This revokes access and erases the profile, and the user ID stays permanently taken.",
"icon": "🚫",
"destructive": true,
"confirm": "This cannot be undone, and the user ID can never be registered again.",
"fields": [
{
"name": "username",
"label": "Username",
"type": "text",
"required": true
}
]
}
]
}