优化 GET /api/roles/users 用户列表的排序:
- 主排序:按角色等级 皇帝 → 公爵 → 骑士 → 平民(无角色用户排最后)
- 次排序:用户名长度(短者优先)
- 末排序:用户名字母序(大小写不敏感)
- 查询由 db.query.users.findMany(relational)改为显式 select + leftJoin,
以支持基于角色名的 CASE 排序
Sort the user list returned by GET /api/roles/users:
- Primary: by role rank Emperor -> Duke -> Knight -> Civilian (users
without a role sort last)
- Secondary: username length (shorter first)
- Tertiary: username alphabetical order (case-insensitive)
- Switch the query from db.query.users.findMany (relational) to an explicit
select + leftJoin to enable CASE-based ordering on role name
Add ability for Emperor to delete users from the role management panel:
- New POST /api/roles/delete endpoint with PROMOTE_USER permission guard,
blocks deleting self or other emperors, cascades user data cleanup
- Trash button on each non-emperor row with confirmation dialog
- Auto-navigate to previous page when deleting the last user on a page
- i18n strings added for all 5 locales
Redesign the Emperor's Role Management panel from a single-user
search-and-assign form into a full user management dashboard with
browsable user list and inline role editing.
Mirror publish-cli.yml for @moemail/mcp: trigger on mcp-v* tags or manual
dispatch, install + bun build, then npm publish --access public using
secrets.NPM_TOKEN.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI publishes with `pnpm install` per package; commit pnpm-lock.yaml for
core and mcp (previously missing) and refresh cli's after the @moemail/core
dependency was added, so installs are reproducible.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the HTTP client and config into a new @moemail/core package shared
by the CLI and a new @moemail/mcp server, so both frontends talk to the same
MoeMail API through one code path.
- core: api client (now throws typed ConfigError/AuthError/PermissionError/
QuotaError instead of process.exit), config, msToIso, and a transport-
agnostic pollForNewMessage helper.
- cli: consume @moemail/core; route command errors through a shared fail()
that preserves exit codes (config/auth = 2, else = 1). Bump to 1.0.0.
- mcp: new stdio MCP server exposing 8 tools (create/list/read/wait/send/
delete); wait_for_email is bounded and returns a timeout status to retry.
Configured via MOEMAIL_API_KEY / MOEMAIL_API_URL env. Release 1.0.0.
Docs:
- Fix packages/cli/README.md (config set, send --content not --body, full
flag table).
- Add MCP section to both root READMEs; complete the CLI command list
(send, list, message-level delete).
- SKILL.md: --json works before or after the subcommand.
- Ignore bun.lock in package gitignores.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Anonymous callers to the shared mailbox API got 401 because the
middleware matcher's broad page pattern catches /api paths but the
inner allowlist only carved out /api/auth. SSR rendered the mailbox
listing, but every client-side fetch (message detail, polling,
pagination) was rejected, so opening a shared mailbox showed the list
without being able to read any message body.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The tsconfig include pattern `**/*.ts` was picking up CLI package sources
during Next.js build, causing missing `commander` module errors in CI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The CLI package is not part of a pnpm workspace, so its dependencies
need to be installed from within packages/cli/ directly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>