The create-report, get-reports and clear-reports commands now live in the
plugin's own module next to the functions they call, with their locale.
The permissions keep their exp_scenario.command names because the command
authority derives them from the command name.
The Discord report alert in exp_scenario is gone since exp_reports posts to
its own webhook. The shared add_player stub takes an options table with
connected and admin defaulting to true and false, replacing the copy in
the exp_reports test environment.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Building on the class annotations from the smoke test changes:
- The suite is generic over its environment: Framework.suite is
@generic T : Stubs with the extension returning T, and Suite<T> passes T to
every test function. A test file declares
`local Suite = ... --- @type Suite<ExpRoles.TestEnv>` and env autocompletes
from there.
- The stubs declare their recorded fields, add_player returns Stubs.Player,
and the server is one.
- ExpRoles.TestEnv : Stubs declares the extension fields, so env.R returns
ExpRoles.Role and env.Roles is the module.
The typing immediately paid for itself by flagging real drift in the tests,
now fixed: _script_data is package private so the env exposes script_data()
instead, the join event carries its name and tick, the assignment record type
admits is_deleted, admin_state is a file local rather than an undeclared
field, and the event assertions which indexed [1] without a nil check compare
the whole event list.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>