@profullstack/qryptchat 0.6.2 → 0.6.3

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.
@@ -0,0 +1,71 @@
1
+ // src/cli/update.js
2
+ import { spawn } from "node:child_process";
3
+ import { realpathSync } from "node:fs";
4
+ var PACKAGE = "@profullstack/qryptchat";
5
+ function compareVersions(a, b) {
6
+ const parse = (v) => {
7
+ const [core, pre = ""] = String(v).replace(/^v/, "").split("-");
8
+ return { nums: core.split(".").map((n) => Number.parseInt(n, 10) || 0), pre };
9
+ };
10
+ const x = parse(a);
11
+ const y = parse(b);
12
+ for (let i = 0;i < 3; i++) {
13
+ const d = (x.nums[i] ?? 0) - (y.nums[i] ?? 0);
14
+ if (d)
15
+ return Math.sign(d);
16
+ }
17
+ if (x.pre === y.pre)
18
+ return 0;
19
+ if (!x.pre)
20
+ return 1;
21
+ if (!y.pre)
22
+ return -1;
23
+ return x.pre < y.pre ? -1 : 1;
24
+ }
25
+ function installCommand(binPath = "") {
26
+ const p = binPath.replaceAll("\\", "/");
27
+ const spec = `${PACKAGE}@latest`;
28
+ if (p.includes("/_npx/"))
29
+ return { npx: true };
30
+ if (p.includes("/.bun/"))
31
+ return { cmd: "bun", args: ["add", "-g", spec] };
32
+ if (p.includes("/pnpm/"))
33
+ return { cmd: "pnpm", args: ["add", "-g", spec] };
34
+ return { cmd: "npm", args: ["install", "-g", spec] };
35
+ }
36
+ async function latestVersion(fetchImpl = fetch) {
37
+ const res = await fetchImpl(`https://registry.npmjs.org/${PACKAGE}/latest`, { headers: { accept: "application/json" } });
38
+ if (!res.ok)
39
+ throw new Error(`Could not reach the npm registry (HTTP ${res.status}).`);
40
+ const { version } = await res.json();
41
+ if (!version)
42
+ throw new Error("The npm registry did not say which version is latest.");
43
+ return version;
44
+ }
45
+ function run(cmd, args) {
46
+ return new Promise((resolve, reject) => {
47
+ const child = spawn(cmd, args, { stdio: "inherit", shell: process.platform === "win32" });
48
+ child.on("error", (err) => reject(new Error(`Could not run ${cmd}: ${err.message}`)));
49
+ child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`${cmd} ${args.join(" ")} exited with ${code}.`)));
50
+ });
51
+ }
52
+ async function update({ current, check = false, binPath = process.argv[1], fetchImpl = fetch, runImpl = run }) {
53
+ const latest = await latestVersion(fetchImpl);
54
+ if (compareVersions(latest, current) <= 0)
55
+ return { updated: false, line: `qc ${current} is the latest.` };
56
+ let real = binPath || "";
57
+ try {
58
+ real = realpathSync(real);
59
+ } catch {}
60
+ const how = installCommand(real);
61
+ if (how.npx)
62
+ return { updated: false, line: `qc ${latest} is out (you have ${current}). Run: npx ${PACKAGE}@latest` };
63
+ const command = `${how.cmd} ${how.args.join(" ")}`;
64
+ if (check)
65
+ return { updated: false, line: `qc ${latest} is out (you have ${current}). Update with: qc update (runs ${command})` };
66
+ await runImpl(how.cmd, how.args);
67
+ return { updated: true, line: `qc ${current} -> ${latest}.` };
68
+ }
69
+ export {
70
+ update
71
+ };
@@ -1167,6 +1167,7 @@ Usage:
1167
1167
  qc agent join <link> join as an AI agent from an invite (makes its own keys) [--name --username]
1168
1168
  qc login [--oob] sign in through your browser; --oob to paste a code (SSH)
1169
1169
  qc logout forget this terminal's session and keys
1170
+ qc update [--check] update qc to the latest release (--check only says whether there is one)
1170
1171
  qc whoami who this terminal is signed in as
1171
1172
  qc profile [--emoji \uD83D\uDD2D] [--pronouns she/her] [--website URL] [--bio TEXT]
1172
1173
  show or set your public profile (an empty value clears it);
@@ -1433,6 +1434,12 @@ ${info("Set: qc profile --emoji :telescope: --pronouns she/her --website https:/
1433
1434
  `) });
1434
1435
  return;
1435
1436
  }
1437
+ case "update":
1438
+ case "upgrade": {
1439
+ const { update } = await import("./chunk-1499e56f.js");
1440
+ const r = await update({ current: version, check: Boolean(flags.check) });
1441
+ return out(r.updated ? ok(r.line) : info(r.line));
1442
+ }
1436
1443
  case "mcp": {
1437
1444
  const { serveMcp } = await import("./mcp.js");
1438
1445
  return serveMcp(await client(flags), { version });
package/dist/commands.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  parseArgs2,
5
5
  findChat2,
6
6
  main2
7
- } from "./chunk-s0qccr26.js";
7
+ } from "./chunk-1htbyjhe.js";
8
8
  import"./chunk-g9xn5036.js";
9
9
  export {
10
10
  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-s0qccr26.js";
4
+ } from "./chunk-1htbyjhe.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.2",
3
+ "version": "0.6.3",
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": {