Skip to main content

Terminal-first notes CLI with SQLite storage and git sync.

Project description

Terminotes Version Downloads

Terminotes is a terminal-first note taking CLI, 99% vibecoded with Codex CLI and GPT-5 under my tight supervision 😉.

It focuses on fast capture from a shell, durable storage in SQLite, and simple Git synchronization so you can keep your notes database in a repo and carry it between machines.

Features

  • Fast capture via editor (tn edit) and direct log entries (tn log -- ...).
  • SQLite storage with simple schema and safe parameterized queries.
  • Git-backed portability: store the DB in a repo and sync on demand.
  • Practical commands: list, search, delete, info, sync, and export.
  • Link capture with tn link, including optional comments, auto-applied link tags, and Wayback fallbacks.

Requirements

  • Python 3.13+
  • uv for environment and workflow.
  • Git installed and a reachable remote for your notes repo.

Installation

Install Terminotes globally via uv:

uv tool install terminotes

This places the tn console script on your PATH, so you can invoke Terminotes from any shell without activating a virtual environment. Use tn --help to explore the CLI. If you prefer a local development checkout, follow the contributing instructions later in this document.

Quick Start

  1. Create or edit your configuration file:
tn config

This bootstraps a TOML file (default ~/.config/terminotes/config.toml). Update it to point to your notes repo and editor. Minimal example:

git_remote_url = "git@github.com:you/terminotes-notes.git"
terminotes_dir = "notes-repo"  # absolute or relative to the config dir
editor = "vim"

Important: git_remote_url is required. Terminotes ensures a local clone exists under terminotes_dir and stores the SQLite DB there.

  1. Capture a first note:
tn edit
  1. List your notes:
tn ls --limit 10
  1. Sync with the remote when ready:
tn sync

Usage

Below are the primary subcommands. Use tn --help and tn <cmd> --help for details.

  • config — Create/open the config file in your editor.

    • Example: tn config
  • edit — Create a new note or edit an existing one.

    • New note: tn edit
    • Edit by id: tn edit --id 42
    • Edit last updated: tn edit --last
  • log — Quick log entry without opening an editor.

    • Example: tn log --tag work --tag focus -- This is a log entry
    • Title is derived from the first sentence or line, truncated when long.
    • Repeat --tag to associate tags; tag names are normalized to lowercase.
  • link — Save a URL with optional comment and Wayback fallback metadata.

    • Example: tn link https://example.com "Great article" --tag reading
    • Multi-word comments become the first paragraph of the note body, followed by the Markdown link (and Wayback fallback when present).
    • Automatically adds the link tag alongside any additional --tag arguments and stores the latest archived snapshot (when available) under the note's extra data.
    • Fetches the page title and appends the hostname when possible; otherwise the raw URL becomes the note title. A warning is shown if no Wayback snapshot is available.
  • ls — List most recent notes (by last edit time).

    • Example: tn ls --limit 10 --tag work
    • Options: --limit/-n, --reverse, --tag/--tag (filter by tag; repeatable)
  • search — Simple case-insensitive substring search across title/body/description.

    • Example: tn search python --tag personal
    • Options: --limit/-n, --reverse, --tag/--tag
  • delete — Delete a note by id.

    • Example: tn delete --yes 42
    • Uses a confirmation prompt unless --yes is provided.
  • prune — Remove unused tags and stale tag associations.

    • Example: tn prune
  • sync — Fetch, detect divergence, and push with the selected strategy.

    • Requires a clean working tree; commit or stash changes first.
    • Divergence prompt choices: local-wins, remote-wins, or abort.
  • export — Render notes to a static site or Markdown files.

    • HTML: tn export --format html --dest ./site --site-title "My Notes"
    • Markdown: tn export --format markdown --dest ./markdown
    • Outputs go into the destination directory, which is created if missing.
  • info — Show current repo path, totals, and last edited note.

Configuration

The config file is TOML and lives by default at ~/.config/terminotes/config.toml. Keys:

  • git_remote_url (string, required): your notes repo remote URL.
  • terminotes_dir (string, optional): where the local repo lives; absolute or relative path. Default: notes-repo under the config directory.
  • editor (string, optional): command to launch when editing notes via tn edit.

You can start from config/config.sample.toml.

Data Model

Notes are stored in an SQLite file named terminotes.sqlite3 under terminotes_dir. Schema (simplified):

  • id (INTEGER PRIMARY KEY)
  • title (TEXT)
  • body (TEXT)
  • description (TEXT)
  • created_at (TEXT, ISO 8601)
  • updated_at (TEXT, ISO 8601)
  • can_publish (INTEGER as boolean)
  • extra_data (TEXT as JSON) for structured metadata, e.g. link source and Wayback fallback URLs captured by tn link.
  • Tags are stored in a normalized (lowercase) many-to-many table; each note can belong to multiple tags and vice versa.

Timestamps are stored in UTC.

Git Sync

Terminotes uses your local clone of the notes repository and commits SQLite changes locally during edit/log/delete/prune. Network interaction only happens during tn sync:

  • fetch --prune then divergence detection.
  • If remote-ahead or diverged, you can pick:
    • remote-wins: hard reset to origin/<branch> (replaces local DB with remote).
    • local-wins: force-push with lease.
    • abort: do nothing.
  • If no upstream exists, tn sync pushes and sets upstream.

In non-interactive sessions, prompts are disabled and an error message is shown with guidance. A clean working tree is required.

Development

Use uv and the provided Justfile tasks:

just bootstrap    # uv sync + pre-commit install
just fmt          # ruff format
just lint         # ruff check
just test         # pytest
just precommit    # run all pre-commit tasks

Contributing

Pull requests are welcome. Before submitting:

  • Follow Conventional Commits (e.g., feat(cli): add search subcommand).
  • Run just precommit.
  • Include a summary, test output, and linked issues in your PR.

See AGENTS.md for repository conventions and tips.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

terminotes-0.6.2.tar.gz (53.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

terminotes-0.6.2-py3-none-any.whl (33.6 kB view details)

Uploaded Python 3

File details

Details for the file terminotes-0.6.2.tar.gz.

File metadata

  • Download URL: terminotes-0.6.2.tar.gz
  • Upload date:
  • Size: 53.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.19

File hashes

Hashes for terminotes-0.6.2.tar.gz
Algorithm Hash digest
SHA256 5ff82d7678bc2ecc40afa28383f50d8a504dd3865053ade9311b344e679ef639
MD5 518a979bfaa65c97f7f7c02eddf3c69c
BLAKE2b-256 b4a78445e4dbfc34a87466787d89d572bb9dcc8faf5dee0487f055fc71c49972

See more details on using hashes here.

File details

Details for the file terminotes-0.6.2-py3-none-any.whl.

File metadata

  • Download URL: terminotes-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 33.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.19

File hashes

Hashes for terminotes-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 dc89754dcb8fe7540334212c8dc4e42dfdfeb43b4e52cf6053299e423cd56d5c
MD5 cd8dd24930c242b10cd4b9c995a8cf08
BLAKE2b-256 526c1ce08e078c73b30871ef71cfc541fbff7f9c6cf5333506fb5da204d0d37e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page