60 lines
3.6 KiB
Markdown
60 lines
3.6 KiB
Markdown
# 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/rpc` with 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-address` defcustom.
|
|
- The Signal account is configurable via the `noise-account` defcustom (nil for a single-account daemon; required when signal-cli has multiple accounts registered). Account-scoped RPC calls go through `noise-rpc-call-for-account`.
|
|
|
|
## 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 b` from anywhere to switch chats.
|
|
- **Compose inline at the prompt** in a conversation buffer. `RET` sends; `M-RET` inserts a newline.
|
|
- **Chat list is an ibuffer-style root buffer** (`*signal*`). `n`/`p` to move, `RET` to open a conversation.
|
|
- **Discoverability via which-key.** The keymap is the menu — `C-c s` shows 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: `defcustom` for user options, `defvar` for internal state, `defun` for 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)
|
|
|
|
1. **Chat list** (`*signal*`) — root buffer showing all conversations, unread counts, last message preview, timestamps
|
|
2. **Conversation buffer** (`*signal:<name>*`) — full message history with inline compose prompt, day separators, delivery receipts
|
|
3. **Minibuffer switcher** — fuzzy narrowing completion over all conversations, showing name, type (direct/group), unread count, last activity
|
|
4. **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-cli` daemon 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-address` as the configurable JSON-RPC endpoint.
|