Skip to content

feat(qc): message anyone new from the TUI, CLI and MCP (0.17.0, qc 0.13.0) - #344

Merged
ralyodio merged 1 commit into
masterfrom
feat/qc-new-direct-chat
Oct 27, 2026
Merged

ralyodio merged 1 commit into
masterfrom
feat/qc-new-direct-chat

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

qc had no way to start a chat with someone you had never talked to.

  • Server: `/api/users/search` and `POST /api/chat/conversations` accept Bearer (they were cookie-only, so qc got 401). New chats are announced live to every member's devices.
  • TUI: `/msg @name [first message]` (also `/dm`, `/query`, `/new`); `n` in the chat list starts one; the empty screen explains it.
  • CLI: `qc dm <@user> [text]` (alias `qc msg`).
  • MCP: `start_direct_chat { user, text? }`.
  • An existing direct chat with that person is reused. An ambiguous name lists the candidates.

Tests: tests/cli (88 pass) incl. pickUser, startDirect over Bearer, /msg parsing, empty-state hint, MCP tool list.

🤖 Generated with Claude Code

…13.0)

Anthony: "qrypt.chat tui has no way to message a new user."

qc could only talk in chats that already existed. Both server routes a new
chat needs were cookie-only, so even a hand-rolled call from qc got 401:
- /api/users/search and POST /api/chat/conversations now authenticate with
  authenticateRequest (Bearer or cookie), like the rest of the API.
- A new chat is announced (announceJoined): every member's open devices put
  it in their list at once and join its live room.

qc:
- TUI: /msg @name [first message] (also /dm, /query, /new) finds the person,
  opens or reuses your direct chat with them and sends the text. `n` in the
  chat list types "/msg @" for you; the empty screen says how.
- CLI: qc dm <@user> [text] (qc msg is the same; "-" reads stdin).
- MCP: start_direct_chat { user, text? }.
- QcClient.searchUsers / startDirect; pickUser takes an exact @username,
  else the only match, else lists who it could be.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ThreatCrush Security Scan

17 finding(s)

MEDIUM: 13 | LOW: 4

Severity Rule Location
MEDIUM js-unescaped-html-sink src/app/blog/[slug]/page.jsx:38
MEDIUM js-unescaped-html-sink src/app/blog/[slug]/page.jsx:66
MEDIUM js-unescaped-html-sink src/app/faq/page.jsx:57
MEDIUM js-unescaped-html-sink src/app/layout.jsx:142
MEDIUM js-unescaped-html-sink src/app/layout.jsx:146
MEDIUM js-unescaped-html-sink src/app/page.jsx:50
MEDIUM js-open-redirect src/app/phone/page.jsx:70
MEDIUM redos-nested-quantifier src/lib/auth/dns-name.js:88
MEDIUM redos-nested-quantifier src/lib/chat/voice-mode.js:116
MEDIUM redos-nested-quantifier src/lib/chat/voice-mode.js:121
MEDIUM js-unescaped-html-sink src/lib/components/chat/MessageItem.jsx:85
MEDIUM js-unescaped-html-sink src/lib/components/chat/MessageItem.jsx:130
MEDIUM js-unescaped-html-sink src/lib/components/PitFooter.jsx:15
LOW secret-generic-credential src/app/api/auth/register-anon/route.test.js:32
LOW secret-jwt tests/debug-sms.js:10
LOW secret-generic-credential tests/private-key-import-export.test.js:252
LOW secret-generic-credential tests/private-key-import-export.test.js:264

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit ddb0377 into master Oct 27, 2026
11 checks passed
@ralyodio
ralyodio deleted the feat/qc-new-direct-chat branch October 27, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant