@profullstack/qryptchat 0.4.7 → 0.5.1
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/dist/{chunk-8rzydycp.js → chunk-byfvkvkr.js} +43 -2
- package/dist/commands.js +1 -1
- package/dist/mcp.js +1 -1
- package/dist/tui.js +2 -1
- package/package.json +2 -2
|
@@ -727,6 +727,20 @@ class QcClient {
|
|
|
727
727
|
return "unknown";
|
|
728
728
|
}
|
|
729
729
|
}
|
|
730
|
+
async profile() {
|
|
731
|
+
const { user } = await this.request(`/api/users/by-username/${encodeURIComponent(this.me?.username ?? "")}`);
|
|
732
|
+
return user;
|
|
733
|
+
}
|
|
734
|
+
async updateProfile(fields) {
|
|
735
|
+
const { user } = await this.request("/api/profile/update", { method: "POST", body: fields });
|
|
736
|
+
return user;
|
|
737
|
+
}
|
|
738
|
+
async openProfile() {
|
|
739
|
+
const res = await this.fetch(`${this.base}/u/${encodeURIComponent(this.me?.username ?? "")}/openprofile.md`);
|
|
740
|
+
if (!res.ok)
|
|
741
|
+
throw new QcError(`HTTP ${res.status}`, res.status);
|
|
742
|
+
return res.text();
|
|
743
|
+
}
|
|
730
744
|
async conversations() {
|
|
731
745
|
const { conversations = [] } = await this.request("/api/conversations/load", { method: "POST", body: {} });
|
|
732
746
|
return conversations.map((c) => ({ ...c, title: conversationTitle(c, this.me) }));
|
|
@@ -751,6 +765,8 @@ class QcClient {
|
|
|
751
765
|
conversationId: m.conversation_id,
|
|
752
766
|
senderId: m.sender_id,
|
|
753
767
|
sender: m.sender?.display_name || m.sender?.username || "unknown",
|
|
768
|
+
emoji: m.sender?.emoji || "",
|
|
769
|
+
pronouns: m.sender?.pronouns || "",
|
|
754
770
|
username: m.sender?.username || "",
|
|
755
771
|
mine: m.sender_id === this.me?.id,
|
|
756
772
|
text: m.content,
|
|
@@ -1082,6 +1098,9 @@ Usage:
|
|
|
1082
1098
|
qc login [--oob] sign in through your browser; --oob to paste a code (SSH)
|
|
1083
1099
|
qc logout forget this terminal's session and keys
|
|
1084
1100
|
qc whoami who this terminal is signed in as
|
|
1101
|
+
qc profile [--emoji \uD83D\uDD2D] [--pronouns she/her] [--website URL] [--bio TEXT]
|
|
1102
|
+
show or set your public profile (an empty value clears it);
|
|
1103
|
+
--openprofile prints it as OpenProfile.md
|
|
1085
1104
|
qc chats list your chats
|
|
1086
1105
|
qc read <chat> [-n 20] print the last messages of a chat
|
|
1087
1106
|
qc send <chat> <text> send a message (text "-" reads stdin; --reply <message-id> to reply)
|
|
@@ -1094,7 +1113,8 @@ Keys and tokens are sealed (ChaCha20-Poly1305) in ${"$"}QC_HOME or ~/.config/qc;
|
|
|
1094
1113
|
OS keychain, or comes from a passphrase (QC_PASSPHRASE for scripts and qc mcp).
|
|
1095
1114
|
HD: emoji and icons are drawn as our OpenEmoji/OpenIcon images in Kitty, Ghostty, WezTerm and iTerm2.
|
|
1096
1115
|
Over SSH or in tmux (set -g allow-passthrough on) say which: QC_HD=1 (Kitty/Ghostty) or
|
|
1097
|
-
QC_HD=wezterm (WezTerm/iTerm2). QC_HD=0 turns it off
|
|
1116
|
+
QC_HD=wezterm (WezTerm/iTerm2). QC_HD=0 turns it off. Mosh carries only text, so behind mosh
|
|
1117
|
+
emoji stay characters: for images use ssh or WezTerm's multiplexer (wezterm connect).`;
|
|
1098
1118
|
function parseArgs2(argv) {
|
|
1099
1119
|
const args = { _: [], flags: {} };
|
|
1100
1120
|
for (let i = 0;i < argv.length; i++) {
|
|
@@ -1107,7 +1127,7 @@ function parseArgs2(argv) {
|
|
|
1107
1127
|
const [k, v] = a.slice(2).split("=", 2);
|
|
1108
1128
|
if (v !== undefined)
|
|
1109
1129
|
args.flags[k] = v;
|
|
1110
|
-
else if (["url", "n", "limit", "reply"].includes(k) && argv[i + 1] !== undefined)
|
|
1130
|
+
else if (["url", "n", "limit", "reply", "emoji", "pronouns", "website", "bio"].includes(k) && argv[i + 1] !== undefined && !argv[i + 1].startsWith("--"))
|
|
1111
1131
|
args.flags[k] = argv[++i];
|
|
1112
1132
|
else
|
|
1113
1133
|
args.flags[k] = true;
|
|
@@ -1193,6 +1213,27 @@ async function main2(argv, { version = "0.0.0" } = {}) {
|
|
|
1193
1213
|
throw new Error("Not signed in. Run qc login.");
|
|
1194
1214
|
return flags.json ? json({ user: session.user, base: session.base }) : out(`@${session.user?.username} (${session.user?.display_name ?? ""}) on ${session.base}`);
|
|
1195
1215
|
}
|
|
1216
|
+
case "profile": {
|
|
1217
|
+
const c = await client(flags);
|
|
1218
|
+
if (flags.openprofile)
|
|
1219
|
+
return out((await c.openProfile()).trimEnd());
|
|
1220
|
+
const fields = {};
|
|
1221
|
+
for (const k of ["emoji", "pronouns", "website", "bio"])
|
|
1222
|
+
if (flags[k] !== undefined)
|
|
1223
|
+
fields[k] = flags[k] === true ? "" : String(flags[k]);
|
|
1224
|
+
const p = Object.keys(fields).length ? await c.updateProfile(fields) : await c.profile();
|
|
1225
|
+
if (flags.json)
|
|
1226
|
+
return json({ username: p.username, emoji: p.emoji ?? null, pronouns: p.pronouns ?? null, website: p.website ?? null, bio: p.bio ?? null });
|
|
1227
|
+
out(`${p.emoji ? `${p.emoji} ` : ""}${p.displayName ?? p.display_name ?? p.username} @${p.username}${p.pronouns ? ` (${p.pronouns})` : ""}`);
|
|
1228
|
+
if (p.website)
|
|
1229
|
+
out(p.website);
|
|
1230
|
+
if (p.bio)
|
|
1231
|
+
out(p.bio);
|
|
1232
|
+
if (!Object.keys(fields).length)
|
|
1233
|
+
out(`
|
|
1234
|
+
Set: qc profile --emoji \uD83D\uDD2D --pronouns she/her --website https://you.example (an empty value clears)`);
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1196
1237
|
case "chats":
|
|
1197
1238
|
case "ls": {
|
|
1198
1239
|
const chats = await (await client(flags)).conversations();
|
package/dist/commands.js
CHANGED
package/dist/mcp.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -56,7 +56,8 @@ function transcriptLines(messages, width, theme) {
|
|
|
56
56
|
if (!sameRun) {
|
|
57
57
|
lines.push({
|
|
58
58
|
spans: [
|
|
59
|
-
{ text: m.mine ? "you" : m.sender
|
|
59
|
+
{ text: `${m.emoji ? `${m.emoji} ` : ""}${m.mine ? "you" : m.sender}`, fg: m.mine ? theme.primary : nameColor(theme, m.senderId || m.sender), bold: true },
|
|
60
|
+
...m.pronouns && !m.mine ? [{ text: ` ${m.pronouns}`, fg: theme.muted }] : [],
|
|
60
61
|
{ text: ` ${timeOf(m.at)}`, fg: theme.muted }
|
|
61
62
|
]
|
|
62
63
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profullstack/qryptchat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
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": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@noble/ciphers": "^2.0.0",
|
|
20
20
|
"@profullstack/encrypt": "^0.1.0",
|
|
21
|
-
"@profullstack/hqtui": "^0.10.
|
|
21
|
+
"@profullstack/hqtui": "^0.10.2",
|
|
22
22
|
"mlkem": "^2.5.0"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|