@profullstack/qryptchat 0.6.4 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -778,6 +778,15 @@ class QcClient {
778
778
  }));
779
779
  return { messages: out, hasMore };
780
780
  }
781
+ async joinGroup(code) {
782
+ return this.request("/api/conversations/join", { method: "POST", body: { code } });
783
+ }
784
+ async groupInvite(conversationId, { reset = false, off = false } = {}) {
785
+ const path = `/api/chat/conversations/${encodeURIComponent(conversationId)}/invite`;
786
+ if (off)
787
+ return this.request(path, { method: "DELETE" });
788
+ return this.request(path, { method: "POST", body: { reset } });
789
+ }
781
790
  async react(conversationId, messageId, emoji, remove = false) {
782
791
  return this.send(conversationId, reactionEnvelope(messageId, emoji, remove), { messageType: REACTION_TYPE });
783
792
  }
@@ -1136,6 +1145,21 @@ async function joinAsAgent(invite, { name, username, env = process.env, fetchImp
1136
1145
  return { session, conversationId: body.conversation_id, operator: body.operator };
1137
1146
  }
1138
1147
 
1148
+ // src/lib/chat/group-invites.js
1149
+ var CODE_RE = /^[A-Za-z0-9_-]{16,64}$/;
1150
+ function parseInviteCode(input) {
1151
+ const text = String(input ?? "").trim();
1152
+ let code = text;
1153
+ if (/^https?:\/\//i.test(text)) {
1154
+ try {
1155
+ code = new URL(text).pathname.match(/\/join\/([^/]+)\/?$/)?.[1] ?? "";
1156
+ } catch {
1157
+ return null;
1158
+ }
1159
+ }
1160
+ return CODE_RE.test(code) ? code : null;
1161
+ }
1162
+
1139
1163
  // src/cli/style.js
1140
1164
  import { emojify, icon } from "@profullstack/hqtui";
1141
1165
  var mark = (name) => {
@@ -1184,6 +1208,8 @@ Usage:
1184
1208
  qc react <chat> <message-id> <emoji> [--remove] react to a message
1185
1209
  qc listen print new messages as they arrive (NDJSON with --json; --notify alerts with it)
1186
1210
  qc mcp run as an MCP server on stdio (list_chats, read_chat, send_message)
1211
+ qc join <link> join a group chat from its invite link (https://qrypt.chat/join/...)
1212
+ qc invite <chat> print a group's invite link (group admins) [--reset makes a new one, --off turns it off]
1187
1213
 
1188
1214
  <chat> is a chat id or part of its name. Options: --json, --url <server> (or QC_URL).
1189
1215
  Keys and tokens are sealed (ChaCha20-Poly1305) in ${"$"}QC_HOME or ~/.config/qc; the key is in your
@@ -1385,6 +1411,31 @@ ${info("Set: qc profile --emoji :telescope: --pronouns she/her --website https:/
1385
1411
  }
1386
1412
  return;
1387
1413
  }
1414
+ case "join": {
1415
+ if (!rest[0])
1416
+ throw new Error("Usage: qc join <invite link>");
1417
+ const code = parseInviteCode(rest[0]);
1418
+ if (!code)
1419
+ throw new Error("That is not a group invite link (https://qrypt.chat/join/...).");
1420
+ const c = await client(flags);
1421
+ const result = await c.joinGroup(code);
1422
+ const chat = (await c.conversations()).find((x) => x.id === result.conversation_id);
1423
+ if (flags.json)
1424
+ return json(result);
1425
+ return out(ok(`${result.joined ? "Joined" : "Already in"} ${chat?.title ?? "the group"}. Try: qc read "${chat?.title ?? result.conversation_id}"`));
1426
+ }
1427
+ case "invite": {
1428
+ if (!rest[0])
1429
+ throw new Error("Usage: qc invite <chat> [--reset | --off]");
1430
+ const c = await client(flags);
1431
+ const chat = findChat2(await c.conversations(), rest[0]);
1432
+ const result = await c.groupInvite(chat.id, { reset: !!flags.reset, off: !!flags.off });
1433
+ if (flags.json)
1434
+ return json(result);
1435
+ if (flags.off)
1436
+ return out(ok(`The invite link for ${chat.title} is off.`));
1437
+ return out(result.invite.url);
1438
+ }
1388
1439
  case "react": {
1389
1440
  const [chatQuery, messageId, emoji] = rest;
1390
1441
  if (!chatQuery || !messageId || !emoji)
package/dist/commands.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  parseArgs2,
6
6
  findChat2,
7
7
  main2
8
- } from "./chunk-7fw9y4pv.js";
8
+ } from "./chunk-bdg6cmfy.js";
9
9
  import"./chunk-g9xn5036.js";
10
10
  export {
11
11
  HELP2 as HELP,
package/dist/mcp.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import"./chunk-g9xn5036.js";
2
2
  import {
3
3
  findChat2
4
- } from "./chunk-7fw9y4pv.js";
4
+ } from "./chunk-bdg6cmfy.js";
5
5
 
6
6
  // src/cli/mcp.js
7
7
  import { createInterface } from "node:readline";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profullstack/qryptchat",
3
- "version": "0.6.4",
3
+ "version": "0.7.0",
4
4
  "description": "qc: qrypt.chat in your terminal. A full-screen end-to-end encrypted chat client (ML-KEM-1024), plus a scriptable CLI and an MCP server.",
5
5
  "type": "module",
6
6
  "bin": {