@profullstack/qryptchat 0.11.0 → 0.12.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/README.md +1 -0
- package/dist/{chunk-ywyhy3sp.js → chunk-hmyhm26d.js} +40 -2
- package/dist/{chunk-wkjs9anq.js → chunk-ycvwj8wy.js} +1 -1
- package/dist/{chunk-nsn86c8y.js → chunk-zh85gmtq.js} +1 -1
- package/dist/commands.js +1 -1
- package/dist/mcp.js +1 -1
- package/dist/tui.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,6 +55,7 @@ qc mentions ops @al # who @al completes to: @alice, @alina
|
|
|
55
55
|
echo "deploy done" | qc send ops -
|
|
56
56
|
qc listen --json # new messages as NDJSON, until you stop it
|
|
57
57
|
qc whoami
|
|
58
|
+
qc keys # are this terminal's keys your account's? (qc keys publish puts them back)
|
|
58
59
|
```
|
|
59
60
|
|
|
60
61
|
`<chat>` is a chat id or any unique part of its name. Add `--json` for machine output.
|
|
@@ -736,6 +736,13 @@ class QcClient {
|
|
|
736
736
|
return "unknown";
|
|
737
737
|
}
|
|
738
738
|
}
|
|
739
|
+
async publishKey() {
|
|
740
|
+
const mine = this.session.keys?.keys1024?.publicKey;
|
|
741
|
+
if (!mine)
|
|
742
|
+
throw new QcError("This terminal holds no keys. Run qc login.");
|
|
743
|
+
await this.request("/api/crypto/public-keys", { method: "PUT", body: { public_key: mine, key_type: "ML-KEM-1024" } });
|
|
744
|
+
return this.keyCheck();
|
|
745
|
+
}
|
|
739
746
|
async profile() {
|
|
740
747
|
const { user } = await this.request(`/api/users/by-username/${encodeURIComponent(this.me?.username ?? "")}`);
|
|
741
748
|
return user;
|
|
@@ -1262,6 +1269,8 @@ Usage:
|
|
|
1262
1269
|
qc logout forget this terminal's session and keys
|
|
1263
1270
|
qc update [--check] update qc to the latest release (--check only says whether there is one)
|
|
1264
1271
|
qc whoami who this terminal is signed in as
|
|
1272
|
+
qc keys [publish] whether this terminal's keys are your account's; publish makes them the
|
|
1273
|
+
account's again (when another device published keys qc does not hold)
|
|
1265
1274
|
qc profile [--emoji \uD83D\uDD2D] [--pronouns she/her] [--website URL] [--bio TEXT]
|
|
1266
1275
|
show or set your public profile (an empty value clears it);
|
|
1267
1276
|
--openprofile prints it as OpenProfile.md
|
|
@@ -1379,7 +1388,7 @@ async function main2(argv, { version = "0.0.0" } = {}) {
|
|
|
1379
1388
|
}
|
|
1380
1389
|
case "agent": {
|
|
1381
1390
|
if (rest[0] === "call") {
|
|
1382
|
-
const { runVoiceAgent } = await import("./chunk-
|
|
1391
|
+
const { runVoiceAgent } = await import("./chunk-ycvwj8wy.js");
|
|
1383
1392
|
return runVoiceAgent(await client(flags), {
|
|
1384
1393
|
brain: typeof flags.brain === "string" ? flags.brain : undefined,
|
|
1385
1394
|
voice: typeof flags.voice === "string" ? flags.voice : undefined,
|
|
@@ -1442,6 +1451,35 @@ ${ok("Installed OpenEmoji. Restart the terminal, then run: qc fonts status")}`);
|
|
|
1442
1451
|
}
|
|
1443
1452
|
return;
|
|
1444
1453
|
}
|
|
1454
|
+
case "keys": {
|
|
1455
|
+
const c = await client(flags);
|
|
1456
|
+
const status = await c.keyCheck();
|
|
1457
|
+
if (rest[0] !== "publish") {
|
|
1458
|
+
if (flags.json)
|
|
1459
|
+
return json({ keys: status });
|
|
1460
|
+
if (status === "ok")
|
|
1461
|
+
return out(ok("This terminal's keys are your account's keys."));
|
|
1462
|
+
if (status === "mismatch")
|
|
1463
|
+
return out(warn("Your account publishes a different key, so messages sent to you since then won't decrypt here. If older messages read fine in qc read, run qc keys publish."));
|
|
1464
|
+
return out(info("Could not compare keys (no key on file, or the check failed)."));
|
|
1465
|
+
}
|
|
1466
|
+
if (status === "ok")
|
|
1467
|
+
return out(ok("Already published: nothing to do."));
|
|
1468
|
+
if (!flags.yes) {
|
|
1469
|
+
if (!process.stdin.isTTY)
|
|
1470
|
+
throw new Error("qc keys publish replaces the key everyone encrypts to. Add --yes to confirm.");
|
|
1471
|
+
const { createInterface } = await import("node:readline/promises");
|
|
1472
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1473
|
+
const answer = await rl.question("Publish this terminal's key? Devices holding the other key will stop decrypting new messages until they restore your keys. [y/N] ");
|
|
1474
|
+
rl.close();
|
|
1475
|
+
if (!/^y(es)?$/i.test(answer.trim()))
|
|
1476
|
+
return out(info("Left the published key alone."));
|
|
1477
|
+
}
|
|
1478
|
+
const after = await c.publishKey();
|
|
1479
|
+
if (flags.json)
|
|
1480
|
+
return json({ published: true, keys: after });
|
|
1481
|
+
return out(ok("Published. New messages are encrypted to this terminal's key again; other devices on the other key should restore from Settings > Keys."));
|
|
1482
|
+
}
|
|
1445
1483
|
case "logout":
|
|
1446
1484
|
clearSession();
|
|
1447
1485
|
return out(ok("Signed out. This terminal no longer holds your keys."));
|
|
@@ -1514,7 +1552,7 @@ ${info("Set: qc profile --emoji :telescope: --pronouns she/her --website https:/
|
|
|
1514
1552
|
throw new Error('Usage: qc call <number> (e.g. qc call "(415) 555-1234" or qc call +442079460958)');
|
|
1515
1553
|
const c = await client(flags);
|
|
1516
1554
|
const url = `${c.base}/phone?to=${encodeURIComponent(rest.join(" "))}`;
|
|
1517
|
-
const { openBrowser } = await import("./chunk-
|
|
1555
|
+
const { openBrowser } = await import("./chunk-zh85gmtq.js");
|
|
1518
1556
|
const opened = openBrowser(url);
|
|
1519
1557
|
return out(`${mark("send")}${opened === false ? "Open" : "Opened"} ${url}
|
|
1520
1558
|
Calls to phones need your browser for the audio; tap Call there.`);
|
package/dist/commands.js
CHANGED
package/dist/mcp.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -262,7 +262,7 @@ function saveRecent(list) {
|
|
|
262
262
|
writeFileSync(recentFile(), JSON.stringify(list), { mode: 384 });
|
|
263
263
|
} catch {}
|
|
264
264
|
}
|
|
265
|
-
var KEY_MISMATCH = "Keys don't match your account, so messages can't decrypt.
|
|
265
|
+
var KEY_MISMATCH = "Keys don't match your account, so new messages can't decrypt. If your history reads here, run qc keys publish; else qc login from a browser that reads your chats.";
|
|
266
266
|
async function runTui(client, { initialChat } = {}) {
|
|
267
267
|
const state = initialState(client.me);
|
|
268
268
|
state.recent = loadRecent();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profullstack/qryptchat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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": {
|