I am Tony Narlock

This is my professional website. I’ve been a software developer for over 17 years. If you’re not in the field, what I do might not make much sense to you.

I work at tech startups, building web-based applications. On the frontend, I use React, TypeScript, and Relay (GraphQL), and on the backend, Python and Amazon Web Services.

In my spare time, I plan, develop, and maintain a suite of developer tools. For instance, tmuxp, which constructs tmux sessions from a JSON or YAML file. A few years ago, I also wrote a book about tmux, titled “The Tao of tmux”. Another tool I’ve created is cihai, based on Unicode’s UNIHAN dataset, which supports Chinese, Japanese, and Korean languages.

I actively contribute to open-source software projects. You can find me on GitHub, GitLab, and OpenHub.

My CV documents everything I’ve ever done - professional work, my projects, and open-source contributions (I’m a polyglot; there’s even some C++ in there).

Hello, I’m Tony Narlock

This is my professional website. I’ve been a software developer for over 17 years, currently working from Texas.

I build web-based applications at tech startups. On the frontend, I work with React, TypeScript, and Relay (GraphQL); on the backend, Python and Amazon Web Services.

Outside of work, I maintain a collection of developer tools. tmuxp builds tmux sessions from JSON or YAML configuration. I’ve also written “The Tao of tmux”, a practical guide to the terminal multiplexer. cihai provides programmatic access to Unicode’s UNIHAN dataset for Chinese, Japanese, and Korean characters.

I contribute to open-source projects and you can find my work on GitHub, GitLab, and OpenHub.

My CV has the details — professional work, personal projects, and contributions across various languages and technologies.

What's going on in my life as a programmer

What am I busy with outside of work?

2026

May 2026

agentgrep

agentgrep is a new project for searching local AI agent prompts and history across Claude Code, Codex, Cursor, and Gemini CLI. It ships four consumption surfaces from one codebase:

  • CLIagentgrep grep (rg/ag-shaped content search), agentgrep find (fd-shaped file discovery), agentgrep fuzzy (fzf-shaped ranking). A Lucene-style query language threads through all subcommands with field predicates (agent:, mtime:, model:, role:), boolean operators, and date ranges. --json / --ndjson / --vimgrep for pipeline consumption.
  • TUI — Textual app with live-streaming results, vim-style navigation, and format-aware JSON/Markdown rendering. Accessible via bare agentgrep or --ui on any subcommand.
  • Libraryrun_search_query() and typed event-stream iterators for embedding in other tools.
  • MCP serveragentgrep-mcp exposes search, catalog, discovery, and validation tools plus agentgrep:// resources to any MCP client.

Backed by a Pydantic-modelled storage catalog mapping every known prompt and history store across agents. Seven alpha releases (a0–a6) shipped in May.

libtmux

libtmux shipped three feature releases in May:

v0.56.0 is the command-parity release — 50+ new Python methods covering tmux's full command surface:

v0.57.0 adds a typed client model and tmux-native filtering:

v0.58.0 fixes subprocess output decoding on non-UTF-8 locales, where the Unicode format separator was corrupted and list accessors silently returned empty results.

libtmux-mcp

libtmux-mcp shipped six alpha releases (v0.1.0a4 through v0.1.0a9) maturing the agent-facing terminal control surface:

  • Pane recovery: respawn_pane restarts a stuck pane in place, preserving pane_id and window layout
  • Layout-relative targeting: find_pane_by_position resolves window corners (top-left, bottom-right, etc.) to a typed pane — no more parsing tmux format variables
  • Typed geometry: Pane responses now carry window-relative coordinates and edge predicates so agents can reason about layout without extra queries
  • Agent discovery rework: Bare "pane", "window", "session" prompts now activate the server; registration slug standardized to tmux
  • Deterministic command completion: wait_for_text redesigned to match only new output, reframing wait_for_channel as the primary synchronization primitive
  • Polling correctness: Wrapped-line matching in search_panes, history-limit trim warnings, pane lifecycle detection in wait_for_content_change

April 2026

vcspull

v1.59.0 overhauls vcspull sync with timeout guards, live progress, and a per-invocation debug log:

  • Per-repo timeout: Each repo runs under a 10-second deadline; override with --timeout SECONDS. The end-of-run summary lists timed-out repos with copy-pasteable rerun commands.
  • Live status indicator: Terminal spinner shows the active repo name and elapsed time; piped output emits periodic heartbeat lines.
  • Streaming output trail: A 3-line panel above the spinner shows recent git output and collapses when each repo finishes; tunable with --panel-lines.
  • Per-invocation debug log: Drops debug logs under $TMPDIR/vcspull/ (npm/pnpm style), surfaced automatically on failure or timeout.
  • Ctrl-C aborts shell chains: Exits via signal so chained vcspull sync && ... stops on first interrupt.
  • Quieter default output: libvcs logs are silenced by default; pass -v/-vv for verbosity.

Built on libvcs v0.40.0, which adds a timeout= keyword to Git.run()/Hg.run()/Svn.run() and fixes a perf regression on ref-heavy repos (2400+ refs).

libtmux-mcp

libtmux-mcp — terminal control for AI agents, built on libtmux and FastMCP — landed its first public alphas: v0.1.0a1 (2026-04-13) through v0.1.0a3 (2026-04-19). It exposes 30+ MCP tools across the tmux hierarchy (server → session → window → pane):

gp-sphinx

gp-sphinx — an integrated autodoc design system for git-pull Sphinx projects — landed its first public alphas: v0.0.1a10 (2026-04-25) through v0.0.1a12 (2026-04-27). It bundles 12 Sphinx packages that replace ~300 lines of duplicated docs/conf.py with ~10 lines:

Already powering the docs for libtmux v0.55.1, libvcs v0.40.0, and vcspull v1.59.0.

March 2026

vcspull

v1.58.0 adds --sync and --prune flags to vcspull import for full bidirectional config reconciliation, a --prune-untracked flag, and a granular options.pin metadata field to protect specific entries from mutation:

  • --sync: Updates changed URLs and prunes stale entries, fully reconciling config with the remote
  • --prune: Standalone cleanup — removes stale entries without updating URLs
  • --prune-untracked: Extends --sync/--prune to also remove entries lacking import provenance
  • Provenance tracking: metadata.imported_from tags scope pruning — manually added repos are never removed
  • options.pin: Per-repo, per-operation mutation guard (pin: true, pin: {import: true}, allow_overwrite: false)
  • Bug fix: vcspull add, discover, and fmt no longer silently corrupt .json config files

Available on all six import providers. Pruning is config-only — cloned directories on disk are not deleted. Uses a consistent CRDT action model (classifier → enum → apply) across all five config-mutation operations.

See more

Publications

Language Projects

Unix-like Utilities

Web Projects

Featured content

Coding around the web

Porting (Linux-to-BSD)

#893

#136

#147

  • pyston - An open-source Python implementation using JIT techniques #1072, #1073,

#1085

  • libpypa - Python parser implemented in pure C++ #50

Scrapyard

Experimental code / patches that never made it upstream:

Project templates

Permissively licensed starter templates you can use to bootstrap your projects.

These are mostly outdated

Frontend
Cookiecutter

Presentations

Industry and Press

Code Exploration

Other

  • Leather - PSA on why leather is cool

Donate

Like my open source projects and learning resources? Your support is appreciated!

Emboldening virtue, the Junzi

  • To be a righteous person (君子 jūn zǐ), as opposed to (小人 xiăorén)

What makes a good gentleman-scholar in Confucius' eyes?

  • Be coherent: "How did we get here?", "How do these things connect?"
  • Tolerate ambiguity
  • Treat matters in proportion to the issue
  • Secure attachment