Docs

Local connections

The other direction from webhooks: a program on the same computer asking Deixis for something. It is off until you switch it on, it never opens a network port, and each program appears by name with its own list of what you allow it to do. This page has the whole model — the key beside your settings, the five requests a program may send, what it can and cannot see, and the worked example in the repository that exercises every one of them.

Local connections

The other direction from integrations: a program on this computer asking Deixis for something, rather than Deixis posting to something you configured. Settings → Integrations & apps → Local connections.

Off by default, and off means there is nothing listening. No pipe, no socket, and no file telling anything where to connect. Ticking Allow local apps to connect creates the listener immediately — no restart — and unticking it disconnects everything on it straight away.

  • Local only, and there is nothing new leaving the machine. A named pipe on Windows, a unix socket on macOS — never a TCP port, which is also why no firewall ever asks you about this. The Windows pipe explicitly rejects remote clients, so it is not reachable over the network either.
  • A key, beside your settings. While the door is open, Deixis writes local-door.json next to config.toml holding the address and a random key. A program reads that file to connect; one that cannot read the file cannot get in. The key is minted fresh each time the door opens, so switching the box off and on again is the simplest way to invalidate every key you have handed out.
  • Per-program permissions. Each program that connects appears in the list under its own name — the moment it connects, so you do not have to reopen the window to see it — with a tick per capability: ask you a question, take a palette key, receive a dictation you route to it, ask you to click something, and type into a field. The last two are off for every program until you switch them on. The first three cannot do anything without a move from you: a question is one you dismiss, a palette key can only take a letter that did nothing before, and a dictation arrives only if you press that key and speak. A program left alone with all three does nothing at all. Asking you to click something puts a picker over your whole screen, and typing puts text in a field with no further press — so those two wait until you have looked at the program and decided.
  • What a connected program sees: whether Deixis is idle or recording, and the microphone level — enough to show you it is listening. What it does not see: what you dictate. A program gets your words only when you hand them over, one dictation at a time, by answering its question out loud or by pressing a palette key you let it claim for that. It never simply receives everything you say. Nor does it see your history, your notes, your recordings, your shared links, your team, or your account; it cannot start a recording, and it cannot enumerate the other programs in the list.
  • Remembered, not re-asked. A program you allowed keeps its permissions while it is not running, so starting it is not the same question every day — the list shows those rows as not running. Revoke disconnects it and forgets it, so it comes back as something you have never allowed.
  • A program cannot drive Deixis. Five requests are all it may send — plus taking one of them, the request to click something, back again. Everything the app itself does — changing settings, shutting the engine down, deleting a recording — is refused, by name, on the connection.
  • A picker a program asks for does not stand there for ever. If nobody clicks, Deixis takes it off the screen after a minute and tells the program nobody answered; it also comes down the moment that program closes, or you revoke it. The program can withdraw its own request too.

If something is refused you will see it in the Activity feed under Advanced → it says which program, which request, and which tick is missing.

Writing a program that connects

core/examples/client.rs is the worked example, and it is meant to be read as well as run. It connects the way any program would — reading the address and the key out of local-door.json, nothing privileged — and then drives all five requests in turn: it claims a palette key, posts a two-button question you can answer out loud, asks you to click an element, and types one line into the focused field. It prints every event it receives and says plainly what came back, including the refusals: run it before you have ticked ask you to click something and type into a field and it tells you which tick is missing rather than failing.

cd core
cargo run --example client --no-default-features --features tools

Pressing a key, clicking an element and speaking cannot be faked — Deixis ignores synthetic input on purpose — so the steps that need you are opt-in, through three environment variables (DEIXIS_GESTURE_WAIT, DEIXIS_CAPTURE_WAIT, DEIXIS_PICK_WAIT) that say how many seconds the example will stand and wait for you. Those three belong to the example and are no part of the way programs talk to Deixis — nothing in Deixis reads them, and a program you write has no reason to have them. Run it with none of them set and it still completes: it asks for an element pick and then withdraws the request, which needs nobody.

Two things arrive without being asked for, and the example shows both. Tick type into a field while it is running and it is told at once — it does not have to reconnect to find out. And if you switch Local connections off, or revoke it, while it is running, it is told which of those happened rather than simply losing the pipe.


Two keycaps, Ctrl and Win, held down and lit teal from underneath.

Hold a key. Speak. Keep working.

Deixis is free, needs no account, and runs on your own device.

v1.2.2 · 64‑bit Windows 10/11 · macOS 13 on Apple silicon · 51 MB · nothing else to install