@profullstack/qryptchat 0.6.3 → 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.
- package/bin/qc.js +3 -3
- package/dist/{chunk-1htbyjhe.js → chunk-bdg6cmfy.js} +58 -1
- package/dist/commands.js +3 -1
- package/dist/mcp.js +1 -1
- package/package.json +1 -1
package/bin/qc.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// qc: qrypt.chat in the terminal. `qc` opens the chat client; `qc --help` lists the rest.
|
|
3
3
|
import { readFileSync } from 'node:fs';
|
|
4
|
-
import { errorLine, main } from '../dist/commands.js';
|
|
4
|
+
import { errorLine, exitWhenFlushed, main } from '../dist/commands.js';
|
|
5
5
|
|
|
6
6
|
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
7
7
|
|
|
8
8
|
main(process.argv.slice(2), { version: pkg.version }).then(
|
|
9
|
-
() =>
|
|
9
|
+
() => exitWhenFlushed(0),
|
|
10
10
|
(err) => {
|
|
11
11
|
process.stderr.write(`${errorLine(err)}\n`);
|
|
12
|
-
|
|
12
|
+
exitWhenFlushed(1);
|
|
13
13
|
},
|
|
14
14
|
);
|
|
@@ -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) => {
|
|
@@ -1157,6 +1181,12 @@ function who(user, { agent = false } = {}) {
|
|
|
1157
1181
|
return `${face}${name}${handle}${pronouns}`;
|
|
1158
1182
|
}
|
|
1159
1183
|
|
|
1184
|
+
// src/cli/exit.js
|
|
1185
|
+
function exitWhenFlushed2(code, { timeoutMs = 30000 } = {}) {
|
|
1186
|
+
setTimeout(() => process.exit(code), timeoutMs);
|
|
1187
|
+
process.stdout.end(() => process.stderr.end(() => process.exit(code)));
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1160
1190
|
// src/cli/commands.js
|
|
1161
1191
|
var errorLine2 = (err) => `qc: ${fail(err?.message ?? String(err))}`;
|
|
1162
1192
|
var HELP2 = `qc: qrypt.chat in your terminal (end-to-end encrypted, ML-KEM-1024)
|
|
@@ -1178,6 +1208,8 @@ Usage:
|
|
|
1178
1208
|
qc react <chat> <message-id> <emoji> [--remove] react to a message
|
|
1179
1209
|
qc listen print new messages as they arrive (NDJSON with --json; --notify alerts with it)
|
|
1180
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]
|
|
1181
1213
|
|
|
1182
1214
|
<chat> is a chat id or part of its name. Options: --json, --url <server> (or QC_URL).
|
|
1183
1215
|
Keys and tokens are sealed (ChaCha20-Poly1305) in ${"$"}QC_HOME or ~/.config/qc; the key is in your
|
|
@@ -1379,6 +1411,31 @@ ${info("Set: qc profile --emoji :telescope: --pronouns she/her --website https:/
|
|
|
1379
1411
|
}
|
|
1380
1412
|
return;
|
|
1381
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
|
+
}
|
|
1382
1439
|
case "react": {
|
|
1383
1440
|
const [chatQuery, messageId, emoji] = rest;
|
|
1384
1441
|
if (!chatQuery || !messageId || !emoji)
|
|
@@ -1451,4 +1508,4 @@ ${HELP2}`);
|
|
|
1451
1508
|
}
|
|
1452
1509
|
}
|
|
1453
1510
|
|
|
1454
|
-
export { errorLine2, HELP2, parseArgs2, findChat2, main2 };
|
|
1511
|
+
export { exitWhenFlushed2, errorLine2, HELP2, parseArgs2, findChat2, main2 };
|
package/dist/commands.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
exitWhenFlushed2,
|
|
2
3
|
errorLine2,
|
|
3
4
|
HELP2,
|
|
4
5
|
parseArgs2,
|
|
5
6
|
findChat2,
|
|
6
7
|
main2
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-bdg6cmfy.js";
|
|
8
9
|
import"./chunk-g9xn5036.js";
|
|
9
10
|
export {
|
|
10
11
|
HELP2 as HELP,
|
|
11
12
|
errorLine2 as errorLine,
|
|
13
|
+
exitWhenFlushed2 as exitWhenFlushed,
|
|
12
14
|
findChat2 as findChat,
|
|
13
15
|
main2 as main,
|
|
14
16
|
parseArgs2 as parseArgs
|
package/dist/mcp.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profullstack/qryptchat",
|
|
3
|
-
"version": "0.
|
|
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": {
|