@profullstack/qryptchat 0.4.7 → 0.5.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.
@@ -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)
@@ -1107,7 +1126,7 @@ function parseArgs2(argv) {
1107
1126
  const [k, v] = a.slice(2).split("=", 2);
1108
1127
  if (v !== undefined)
1109
1128
  args.flags[k] = v;
1110
- else if (["url", "n", "limit", "reply"].includes(k) && argv[i + 1] !== undefined)
1129
+ else if (["url", "n", "limit", "reply", "emoji", "pronouns", "website", "bio"].includes(k) && argv[i + 1] !== undefined && !argv[i + 1].startsWith("--"))
1111
1130
  args.flags[k] = argv[++i];
1112
1131
  else
1113
1132
  args.flags[k] = true;
@@ -1193,6 +1212,27 @@ async function main2(argv, { version = "0.0.0" } = {}) {
1193
1212
  throw new Error("Not signed in. Run qc login.");
1194
1213
  return flags.json ? json({ user: session.user, base: session.base }) : out(`@${session.user?.username} (${session.user?.display_name ?? ""}) on ${session.base}`);
1195
1214
  }
1215
+ case "profile": {
1216
+ const c = await client(flags);
1217
+ if (flags.openprofile)
1218
+ return out((await c.openProfile()).trimEnd());
1219
+ const fields = {};
1220
+ for (const k of ["emoji", "pronouns", "website", "bio"])
1221
+ if (flags[k] !== undefined)
1222
+ fields[k] = flags[k] === true ? "" : String(flags[k]);
1223
+ const p = Object.keys(fields).length ? await c.updateProfile(fields) : await c.profile();
1224
+ if (flags.json)
1225
+ return json({ username: p.username, emoji: p.emoji ?? null, pronouns: p.pronouns ?? null, website: p.website ?? null, bio: p.bio ?? null });
1226
+ out(`${p.emoji ? `${p.emoji} ` : ""}${p.displayName ?? p.display_name ?? p.username} @${p.username}${p.pronouns ? ` (${p.pronouns})` : ""}`);
1227
+ if (p.website)
1228
+ out(p.website);
1229
+ if (p.bio)
1230
+ out(p.bio);
1231
+ if (!Object.keys(fields).length)
1232
+ out(`
1233
+ Set: qc profile --emoji \uD83D\uDD2D --pronouns she/her --website https://you.example (an empty value clears)`);
1234
+ return;
1235
+ }
1196
1236
  case "chats":
1197
1237
  case "ls": {
1198
1238
  const chats = await (await client(flags)).conversations();
package/dist/commands.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  parseArgs2,
4
4
  findChat2,
5
5
  main2
6
- } from "./chunk-8rzydycp.js";
6
+ } from "./chunk-74kad4wd.js";
7
7
  import"./chunk-vfahhydf.js";
8
8
  export {
9
9
  HELP2 as HELP,
package/dist/mcp.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import"./chunk-vfahhydf.js";
2
2
  import {
3
3
  findChat2
4
- } from "./chunk-8rzydycp.js";
4
+ } from "./chunk-74kad4wd.js";
5
5
 
6
6
  // src/cli/mcp.js
7
7
  import { createInterface } from "node:readline";
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, fg: m.mine ? theme.primary : nameColor(theme, m.senderId || m.sender), bold: true },
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.4.7",
3
+ "version": "0.5.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": {