- Test all:
eldev test - Test single file:
eldev test ekg-test.eloreldev test ekg-llm-test.el - Lint:
eldev lint - Compile:
eldev compile(check for warnings — docstring width, unused vars, etc.) - Run with debug:
eldev -p -dtT test(shows full output with debug traces)
- File format: Emacs Lisp with
lexical-binding: tin first line - Headers: Include standard copyright, GPL license, commentary section
- Imports: Use
requirefor dependencies,declare-functionfor external functions - Naming: Kebab-case with
ekg-prefix for public functions,ekg--for private - Functions: Use
cl-defunwith keyword args when appropriate, docstrings required - Variables: Use
defcustomfor user options with:typeand:group - Constants: Use
defconstwithekg-prefix - Tests: Use
ekg-deftestmacro (sets up temp DB), place in*-test.elfiles - Errors: Use
errorfor user-facing messages,warnfor recoverable issues - Formatting: Standard Emacs Lisp indentation, max ~80 chars per line
- Comments: Use
;;; Code:section headers,;;for inline comments
EKG is a notetaking application for Emacs, which stores everything in SQLite in a triples database (a dependency of this package).
All functionality is documented in the file //doc/ekg.org, which should be
consulted before changing anything.
- Notes are stored in SQLite via the
tripleslibrary (subject-predicate-object format) - Each note has: ID, text content, mode, tags, timestamps, and optional resources (URLs/files)
- Tags can have prefixes (e.g., "date/2024-01-01", "doc/filename", "person/username"), the prefixes can be meaningful on their own.
- Notes support different major modes (org-mode, markdown-mode, text-mode)
- Tag-centric design: Notes are primarily organized by tags rather than titles
- Metadata editing: Special metadata section at top of notes for editing tags and properties
- Resource notes: Notes can be attached to files or URLs
- Templates: Note creation can use templates based on tags
- Inline commands: Support for transclusion and other dynamic content
- Semantic search: Optional embedding-based search via LLM providers
All functionality is explained in depth in doc/ekg.org.. Read this to
understand how functionality is supposed to work before modifying it.
To modify documentation, just modify doc/ekg.org. This is then exported to
texinfo to generate the other formats in this directory.
- Tests use
ekg-deftestmacro which sets up temporary databases - Test utilities in
ekg-test-utils.elprovide database setup and teardown - Tests cover note lifecycle, tag management, embedding functionality, and integrations
Uses triples library for RDF-like storage in SQLite:
- Notes stored as triples with various predicates (text, tags, mode, etc.)
- Supports full-text search via
triples-fts - Backup and upgrade functionality via
triples-backupsandtriples-upgrade
- The agent loop is in
ekg-agent--iterate, which callsllm-chat-asyncand recurses on each tool result until an end tool is called. llm-chat-asyncreturns a request handle (curl process from plz) that can be cancelled viallm-cancel-request. This is stored inekg-agent--current-request.- Tool functions that spawn subprocesses should be
:async tand track their processes (orfuturobjects) inekg-agent--tool-processesfor force-cancellation support. ekg-agent--set-stoppedacts as a once-only guard — it returns non-nil only on the first running→stopped transition, preventing double-firing of status callbacks.- The request chain:
ekg-agent--iterate→llm-chat-async→llm-request-plz-async→plz-media-type-request→plz(curl process named "plz-request-curl"). futur-process-call(used byrun_elisp) creates a subprocess viafutur; callbacks are bounced to the main thread viarun-at-time.
- Shell scripts in
agent_tools/provide CLI access to ekg for external agents. - Scripts call
emacsclientso require a running Emacs withserver-start. agent_tools/skill.mddocuments the scripts for use as an agent skill.- To locate scripts programmatically, query Emacs:
emacsclient --eval '(file-name-directory (locate-library "ekg"))'
- Package requires Emacs 28.1+ and depends on
triplesandllmpackages - Uses Eldev for development workflow (testing, linting, dependency management)
- All code follows standard Emacs Lisp conventions with
lexical-binding: t - All code in this package is designed for distribution to other users, so nothing can depend on a specific emacs setup.