3.4 KiB
3.4 KiB
Noise — Agent Instructions
What this is
Noise is a Signal Messenger client for Emacs, written in Elisp. It communicates with a local signal-cli instance via JSON-RPC over HTTP (default: localhost:9128). Conversations are stored in SQLite via emacs-sqlite3-api.
Technology & Architecture
| Layer | Technology |
|---|---|
| Language | Emacs Lisp (Elisp) |
| Message backend | signal-cli JSON-RPC (signal-cli daemon) |
| Local storage | SQLite (emacs-sqlite3-api) |
| Runtime | GNU Emacs |
- All Signal protocol work is delegated to
signal-cli. Noise is a client — it does not implement Signal crypto. - The JSON-RPC interface is called over HTTP (not piped subprocess stdio), so requests are
POST http://localhost:9128/api/v1/rpcwith JSON-RPC 2.0 payloads. - SQLite is the single source of truth for local state: contacts, conversations, messages, read/unread markers.
- The address is configurable via the
noise-signal-cli-addressdefcustom.
User Experience Principles
These come directly from the UI mockup (signal-emacs-ui.html) and README:
- Every action has a keybinding. There are no mouse targets, no toolbars, no sidebars.
- Conversation switching is minibuffer completion (fuzzy narrowing, vertico-style). Press
C-x bfrom anywhere to switch chats. - Compose inline at the prompt in a conversation buffer.
RETsends;M-RETinserts a newline. - Chat list is an ibuffer-style root buffer (
*signal*).n/pto move,RETto open a conversation. - Discoverability via which-key. The keymap is the menu —
C-c sshows available bindings. - Evil compatibility out of the box. When evil is active, provide modal bindings for searching, creating conversations, sending, etc.
- End-to-end encryption indicator (
⌁ E2E) is always visible in the modeline.
File Naming & Conventions
- Emacs Lisp source files live in the project root or a package directory and end in
.el. - Package prefix is
noise-for all symbols, functions, and variables. - Follow Emacs Lisp conventions:
defcustomfor user options,defvarfor internal state,defunfor commands. - Use
;;;as the comment starter for top-level headings,;;for inline comments.
Key Dependencies
signal-cli— external program, must be installed and running (signal-cli daemon --receive-mode=manual)emacs-sqlite3-api— Elisp package for SQLite (used for read/write on conversations, contacts, messages)
UI Screens (from mockup)
- Chat list (
*signal*) — root buffer showing all conversations, unread counts, last message preview, timestamps - Conversation buffer (
*signal:<name>*) — full message history with inline compose prompt, day separators, delivery receipts - Minibuffer switcher — fuzzy narrowing completion over all conversations, showing name, type (direct/group), unread count, last activity
- Which-key panel — discoverable keybindings menu triggered by prefix keys
Development Approach
- Build iteratively — get the JSON-RPC bridge working first, then the SQLite schema, then the buffers.
- Test with a real
signal-clidaemon running locally. Verify registration/account linking before anything else. - Elisp files should be byte-compilable with
emacs -batch -f batch-byte-compile. - Follow Emacs buffer-naming conventions and major-mode patterns.
- Always respect
noise-signal-cli-addressas the configurable JSON-RPC endpoint.