From a8262a59a4eb8d6ebf366cf30eeb95bcfe97123c Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Tue, 6 Oct 2026 06:50:54 +0000 Subject: [PATCH] companions: qc (qrypt.chat terminal client) Adds @profullstack/qryptchat as an npm companion, so install.sh and cli-tools link/update put `qc` on PATH: a full-screen end-to-end encrypted chat client, a CLI for scripts and an MCP server. Co-Authored-By: Claude Opus 5.5 --- README.md | 3 ++- src/companions.ts | 12 ++++++++++++ test/companions.test.ts | 9 ++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4035484..79bfc2e 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,7 @@ implement, because they are distributed in their own right: | `devdb` | [terrablue/devdb](https://github.com/terrablue/devdb) — spin up a throwaway local database for development or testing | | `kali` | [`@profullstack/kali`](https://github.com/profullstack/kali) — install a Kali-style web pentesting toolbelt on Debian/Ubuntu | | `telnyx` | [`@telnyx/api-cli`](https://github.com/team-telnyx/telnyx-api-cli) — buy and wire phone numbers, send messages and drive calls | +| `qc` | [`@profullstack/qryptchat`](https://qrypt.chat) — qrypt.chat in the terminal: end-to-end encrypted (ML-KEM-1024) chat client, CLI and MCP server | And one group that is installed only when you ask for it, with `cli-tools companions --install mobile`: @@ -203,7 +204,7 @@ under any agentic CLI, from a Dockerfile, on a box that has never heard of this repository. Vendoring them to make one list tidier would cost them all of that. So `cli-tools` is their front door, not their implementation. -Seven come from npm. `bw` was the first companion that is nobody's but its +Eight come from npm. `bw` was the first companion that is nobody's but its vendor's — `adb`, `expo`, `eas` and `telnyx` are the others — and it earns the place on the same terms as the rest: published, self-installing, useful on a box with no checkout. It covers the secrets `cli-tools` deliberately does not — the `vault` helpers read a logicsrc diff --git a/src/companions.ts b/src/companions.ts index c2f4d5c..dd053a9 100644 --- a/src/companions.ts +++ b/src/companions.ts @@ -178,6 +178,18 @@ export const COMPANIONS: readonly Companion[] = [ summary: 'Buy and wire phone numbers, send messages and drive calls on Telnyx', home: 'https://github.com/team-telnyx/telnyx-api-cli', }, + { + name: 'qc', + // qrypt.chat in the terminal: bare `qc` is a full-screen hqtui chat client, + // `qc chats|read|send|listen` are for scripts and `qc mcp` is an MCP server. + // Messages are encrypted (ML-KEM-1024) on the machine running qc, so the + // keys live in ~/.config/qc after `qc login`, a browser handoff -- a front + // door like `myna`: nothing about the account lives here. The package is + // `@profullstack/qryptchat`; the binary is `qc`. + install: { kind: 'npm', package: '@profullstack/qryptchat' }, + summary: 'qrypt.chat in the terminal: end-to-end encrypted chat client, CLI and MCP server', + home: 'https://qrypt.chat', + }, { name: 'adb', // The Android Debug Bridge, and `fastboot` out of the same archive: one diff --git a/test/companions.test.ts b/test/companions.test.ts index 773bd1f..3a563f4 100644 --- a/test/companions.test.ts +++ b/test/companions.test.ts @@ -33,6 +33,7 @@ describe('the companion list', () => { 'devdb', 'kali', 'telnyx', + 'qc', 'adb', 'expo', 'eas', @@ -169,6 +170,7 @@ describe('statuses', () => { ['devdb', 'missing'], ['kali', 'missing'], ['telnyx', 'missing'], + ['qc', 'missing'], ['adb', 'missing'], ['expo', 'missing'], ['eas', 'missing'], @@ -184,7 +186,7 @@ describe('ensure', () => { // Reinstalling over it is the surprise `link` refuses for symlinks. const calls: string[] = []; const results = ensure({ - onPath: present('timer', 'billing', 'bw', 'diskpush', 'myna', 'devdb', 'kali', 'telnyx'), + onPath: present('timer', 'billing', 'bw', 'diskpush', 'myna', 'devdb', 'kali', 'telnyx', 'qc'), run: ({ display }) => { calls.push(display); return { status: 0 }; @@ -196,7 +198,7 @@ describe('ensure', () => { it('installs only what is missing', () => { const calls: string[] = []; - const installed = new Set(['timer', 'bw', 'diskpush', 'myna', 'devdb', 'kali', 'telnyx']); + const installed = new Set(['timer', 'bw', 'diskpush', 'myna', 'devdb', 'kali', 'telnyx', 'qc']); ensure({ onPath: (name) => (installed.has(name) ? `/usr/local/bin/${name}` : null), run: ({ display }) => { @@ -211,7 +213,7 @@ describe('ensure', () => { it('reinstalls everything at @latest when asked', () => { const calls: string[] = []; ensure({ - onPath: present('timer', 'billing', 'bw', 'diskpush', 'myna', 'devdb', 'kali', 'telnyx'), + onPath: present('timer', 'billing', 'bw', 'diskpush', 'myna', 'devdb', 'kali', 'telnyx', 'qc'), run: ({ display }) => { calls.push(display); return { status: 0 }; @@ -229,6 +231,7 @@ describe('ensure', () => { 'go install github.com/terrablue/devdb@latest', 'npm install -g @profullstack/kali@latest', 'npm install -g @telnyx/api-cli@latest', + 'npm install -g @profullstack/qryptchat@latest', ]); });