SkillAgentSearch skills...

Exocortex

Note taking/information storage + retrieval system inspired by https://roamresearch.com

Install / Use

/learn @neutralinsomniac/Exocortex
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

exocortex

A note-taking/todo/information-storage system. There are two clients:

  • exo — a terminal UI for desktop/laptop, written in Go with bubbletea
  • tdeck-exo — a firmware port for the LilyGo T-Deck Plus, a portable device with a 320×240 display and a physical QWERTY keyboard

Concepts

exocortex tries to be as friction-free as possible when it comes to capturing information without worrying about organization upfront.

On startup, exo reopens the last tag you were on, or the inbox tag if none exists yet.

Tags are the top-level organizational unit. They are created explicitly via the new tag command, or on-the-fly by referencing them in row text using [[double brackets]]. Tags are automatically deleted when they have no rows and no rows reference them.

Rows are bullets under a tag. When a row references another tag (e.g. [[todo]] take out the trash), exocortex links that row bidirectionally — viewing the todo tag will show a reference back to the originating tag with the full row text visible and editable.

Installation

go install github.com/neutralinsomniac/exocortex/cmd/exo@latest

Or with Nix:

nix run github:neutralinsomniac/exocortex

To install into a NixOS configuration flake, add it as an input and pass it through to your NixOS module:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
    exocortex.url = "github:neutralinsomniac/exocortex";
    exocortex.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { nixpkgs, exocortex, ... } @ inputs: {
    nixosConfigurations.myhostname = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [ ./configuration.nix ];
    };
  };
}

Then in configuration.nix:

{ pkgs, inputs, ... }:
{
  environment.systemPackages = [
    inputs.exocortex.packages.${pkgs.system}.exo
    inputs.exocortex.packages.${pkgs.system}.exo-server
  ];
}

Usage

Run exo from anywhere. All data is stored in a single SQLite database at $XDG_DATA_HOME/exocortex/exocortex.db (defaulting to ~/.local/share/exocortex/exocortex.db).

Press ? inside the app to open the help screen.

Keybindings

Tags

| Key | Action | |-----|--------| | i | Go to inbox tag | | n | New tag | | r | Rename current tag | | t | Tag selector (type to filter) | | / | Fuzzy search all rows | | \ | Toggle show/hide done rows | | ctrl-t | Go back in tag history | | 19 | Jump to numbered tag reference |

Rows

| Key | Action | |-----|--------| | g / G | Jump to first / last row | | j / k | Move cursor down / up | | enter | Follow tag link in selected row | | o / O | Add row below / above cursor | | e | Edit selected row | | N | Add/edit note on selected row | | d | Cut selected row (or all marked) | | D | Mark done / un-done (or all marked) | | y | Yank (copy) selected row | | p / P | Paste below / above cursor | | J / K | Move row down / up within its priority group | | space | Toggle row in/out of multi-selection | | ; | Clear multi-selection | | ! @ # $ % | Set priority 1–5 (repeat to clear) | | ) | Clear priority | | u / U | Undo / redo | | S | Sync with server | | ? | Help | | q | Quit |

T-Deck Plus firmware (tdeck-exo)

The tdeck-exo/ directory contains a PlatformIO project that builds firmware for the LilyGo T-Deck Plus. It shares the same sync protocol as exo, so a T-Deck and a desktop instance stay in sync through the same server.

Building

Open tdeck-exo/ in PlatformIO and flash the lilygo_tdeck_plus environment.

Configuration

Edit tdeck-exo/src/config.h before flashing:

| Setting | Description | |---------|-------------| | WIFI_SSID / WIFI_PASSWORD | Network to connect to for sync and NTP | | SYNC_URL | Server URL — https:// for TLS, http:// for AES-256-GCM payload encryption | | SYNC_TOKEN | Shared secret matching the server's -token flag | | TLS_INSECURE | Set false to verify the server's TLS certificate | | NTP_SERVER | NTP server for time sync (default: pool.ntp.org) | | TZ_OFFSET_HOURS | UTC offset for your timezone (e.g. -5 for EST) | | BOARD_BAT_ADC | GPIO pin for battery voltage ADC (default: 4) | | SLEEP_TIMEOUT_MS | Deep sleep after this many ms of inactivity (default: 30000; set to 0 to disable) | | STATIC_IP | (optional) Static IP address — bypasses DHCP, avoids repeated DHCP requests on each wake | | STATIC_GATEWAY | (optional) Gateway address (required if STATIC_IP is set) | | STATIC_SUBNET | (optional) Subnet mask (required if STATIC_IP is set) | | STATIC_DNS | (optional) DNS server (required if STATIC_IP is set) |

Keybindings

Tag list

| Key | Action | |-----|--------| | j / k or trackball | Move cursor | | Enter | Open tag | | i | Go to inbox | | n | New tag | | Type | Filter tags | | Backspace | Clear filter / return to row list |

Row list

| Key | Action | |-----|--------| | j / k or trackball | Move cursor | | o | New row | | e | Edit selected row | | d | Cut selected row (copied to clipboard) | | y | Yank (copy) selected row | | p / P | Paste clipboard row after / before cursor | | D | Toggle done | | 15 | Set priority (press same key again to clear) | | 0 | Clear priority | | J / K | Move row up / down within its priority group | | h | Toggle show/hide done rows | | Enter / l | Follow [[tag]] link in selected row | | b | Go back in tag history | | t | Tag list | | i | Go to inbox | | s | Sync with server | | Backspace | Sleep immediately |

Row edit

| Key | Action | |-----|--------| | Trackball left / right | Move cursor within text | | Enter | Save | | Escape | Cancel |

Sync

exo-server is a companion binary that lets you keep a hosted exocortex database and sync to it from multiple machines. Sync is bidirectional with last-write-wins conflict resolution per row.

Running the server

go install github.com/neutralinsomniac/exocortex/cmd/exo-server@latest
exo-server -db /path/to/exocortex.db -token <secret> -cert /path/to/cert.pem -key /path/to/key.pem

| Flag | Default | Description | |------|---------|-------------| | -db | (required) | Path to the SQLite database file | | -token | (required) | Shared secret used to authenticate clients | | -cert | | TLS certificate file (PEM). Must be paired with -key | | -key | | TLS private key file (PEM). Must be paired with -cert | | -addr | :8765 | Address to listen on |

Encryption modes

With -cert and -key (TLS): The server listens with HTTPS. All traffic is encrypted via TLS. The sync payload is transmitted as plain JSON over the encrypted connection. Configure the client with an https:// URL.

Without -cert and -key (symmetric encryption): The server listens with plain HTTP, but the sync payload itself is encrypted end-to-end using AES-256-GCM. The encryption key is derived from the shared -token via SHA-256. Both request and response bodies are opaque binary blobs (application/octet-stream). No Authorization header is sent — a successful decryption already proves knowledge of the token, so the token never appears in plaintext on the wire. Configure the client with an http:// URL.

The client automatically selects the encryption mode based on the sync_url setting: https:// URLs use TLS (no payload encryption), and http:// URLs use AES-256-GCM payload encryption.

Configuring the client

Set the server URL and token in the exocortex settings table using any SQLite client:

sqlite3 ~/.local/share/exocortex/exocortex.db \
  "INSERT OR REPLACE INTO settings VALUES ('sync_url', 'https://yourserver:8765');
   INSERT OR REPLACE INTO settings VALUES ('sync_token', 'yoursecret');"

Once configured, press S inside exo to sync. Status is shown in the bottom bar.

View on GitHub
GitHub Stars21
CategoryEducation
Updated3d ago
Forks1

Languages

Go

Security Score

90/100

Audited on Apr 3, 2026

No findings