Skip to content

thurstonsand/ghosttykit.lua

Repository files navigation

GhosttyKit Lua SDK

ghosttykit is the Lua client library for talking to ghosttykitd and GhosttyKit bridge sockets. Use it from Neovim plugins, Lua scripts, or LuaRocks-based tools that need to control Ghostty through GhosttyKit.

Installation

Published package installation is coming next.

The SDK supports two runtimes:

  • Neovim: uses vim.uv and vim.json.
  • LuaJIT/LuaRocks: uses luv and dkjson.

Usage

Create a client and call GhosttyKit commands:

local ghosttykit = require("ghosttykit")

local client = ghosttykit.client()
local status, err = client:doctor()

if err then
  error(tostring(err))
end

print(status.healthy)

By default, the client connects to the standard GhosttyKit socket. Pass socket_path to target another daemon or bridge socket:

local client = ghosttykit.client({
  socket_path = "/path/to/ghosttykit.sock",
})

Commands

Commands are grouped by domain. Terminal-scoped methods derive tty from GTY_TTY, then the process's controlling terminal, when it is omitted; pass tty explicitly to override it. Most methods return value, err; methods that only need acknowledgement return ok, err when ack = true, or send a notification without waiting when ack is omitted.

client:doctor()
client.terminal:id({})
client.terminal:count({})
client.terminal:clear_cache({ ack = true })
client.key_table:activate({ name = "nvim", ack = true })
client.key_table:deactivate({ ack = true })
client.layout:focus({ direction = "left", ack = true })
client.layout:split({ direction = "right", cwd = vim.fn.getcwd(), focus = true, ack = true })
client.layout:resize({ direction = "right", pixels = 10, ack = true })
client.layout:zoom({ ack = true })
client.paste:get()
client.bridge:create({})

Paste handles can read text, read file contents, or save pasted content to disk:

local paste = assert(client.paste:get())
local saved = assert(paste:save({ dir = "/tmp/ghosttykit-paste" }))
print(saved[1].path)

Low-level protocol escape hatches

Raw request builders are available through ghosttykit.protocol, and clients expose protocol reply modes through client.raw:

local request = ghosttykit.protocol.focus({ tty = "/dev/ttys001", direction = "left", ack = true })
local reply, err = client.raw:call(request)

local stream, stream_err = client.raw:stream(ghosttykit.protocol.paste())
local held, hold_err = client.raw:hold(ghosttykit.protocol.bridge_lease(token))

Errors

Errors are returned as values, not thrown:

local ok, err = client.layout:focus({ direction = "left", ack = true })
if not ok then
  vim.notify(err.message or err.code, vim.log.levels.ERROR)
end

Each error has:

  • code: protocol or transport error code.
  • message: optional human-readable detail.
  • name: stable error name for callers that prefer names over codes.

Development

Install the SDK from a local checkout:

cd sdk/lua
luarocks make --tree ../../.luarocks --lua-version 5.1 ghosttykit-scm-1.rockspec

Run the development checks:

just install-deps
just check

Releases

Packages

Used by

Contributors

Languages