Go bindings for libghostty-vt.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add discovering-upstream-apis skill

Add an agent skill for discovering new or missing C APIs in the
upstream libghostty-vt headers and creating Go bindings for them.
The skill guides the agent through diffing upstream headers against
existing bindings, presenting findings, and writing idiomatic Go
wrappers following project conventions.

Includes a helper script that compares the pinned GIT_TAG in
CMakeLists.txt against the latest upstream main branch commit,
reporting whether an update is available.

+156
+122
.agents/skills/discovering-upstream-apis/SKILL.md
··· 1 + --- 2 + name: discovering-upstream-apis 3 + description: >- 4 + Discovers new or requested C APIs in upstream libghostty-vt headers 5 + and adds Go bindings. Use when asked to add new APIs, add bindings, 6 + check for new upstream APIs, or bind a specific API like 'add the 7 + decode png api'. 8 + --- 9 + 10 + # Discovering Upstream APIs 11 + 12 + Finds new or requested C APIs in the upstream libghostty-vt headers 13 + and creates or updates Go bindings for them. 14 + 15 + ## Checking for upstream changes 16 + 17 + The pinned commit is in `CMakeLists.txt` under 18 + `FetchContent_Declare(ghostty ...)`. 19 + 20 + Run `scripts/latest-upstream-commit.sh` to compare the pinned commit 21 + against the latest upstream `main` branch. It prints the pinned SHA, 22 + the latest SHA, and whether an update is available. 23 + 24 + When an update is available: 25 + 26 + 1. Update the `GIT_TAG` in `CMakeLists.txt` to the latest commit. 27 + 2. Run `make clean && make build` to fetch the new source. 28 + 3. Run the discovery steps above. 29 + 4. Compare against the current Go bindings. 30 + 5. Present findings to the user. 31 + 32 + ## Workflow 33 + 34 + ### 1. Identify what to bind 35 + 36 + Determine the scope based on the user's request: 37 + 38 + - **Specific API** (e.g. "add the decode png api"): Search the 39 + upstream headers for matching functions/types. 40 + - **All new APIs** (e.g. "add the new apis"): Diff the upstream 41 + headers against existing Go bindings to find unbound APIs. 42 + 43 + ### 2. Locate upstream headers 44 + 45 + Headers live at: 46 + 47 + ``` 48 + build/_deps/ghostty-src/zig-out/include/ghostty/vt/ 49 + ``` 50 + 51 + The umbrella header is at 52 + `build/_deps/ghostty-src/zig-out/include/ghostty/vt.h` and includes 53 + all sub-headers. Individual headers are in the `vt/` subdirectory. 54 + 55 + If the build directory does not exist, run `make build` first. 56 + 57 + ### 3. Discover unbound APIs 58 + 59 + To find what's new or missing: 60 + 61 + 1. List all C functions in the upstream headers: 62 + 63 + ``` 64 + grep -rh '^[A-Za-z].*ghostty_' \ 65 + build/_deps/ghostty-src/zig-out/include/ghostty/vt/ \ 66 + | grep '(' 67 + ``` 68 + 69 + 2. List all C functions already referenced in Go files: 70 + 71 + ``` 72 + grep -rh 'C\.\(ghostty_[a-z_]*\)' *.go \ 73 + | grep -oE 'ghostty_[a-z_]+' | sort -u 74 + ``` 75 + 76 + 3. Cross-reference to find unbound functions. 77 + 4. Also check `TODO.md` for known missing items. 78 + 79 + For type/enum discovery: 80 + 81 + ``` 82 + grep -rh 'typedef\|^} Ghostty\|GHOSTTY_[A-Z_]*[, ]' \ 83 + build/_deps/ghostty-src/zig-out/include/ghostty/vt/*.h 84 + ``` 85 + 86 + ### 4. Confirm with the user 87 + 88 + Before writing code, present the list of new APIs found and ask 89 + which ones the user wants bound. Group them by header file. Include: 90 + 91 + - Function signatures 92 + - Related types/enums they depend on 93 + - Which header they come from 94 + 95 + ### 5. Write Go bindings 96 + 97 + Follow the conventions specified in AGENTS.md and patterns in 98 + existing code. Here are some examples: 99 + 100 + - **Simple getters** (`ghostty_terminal_get`): See 101 + `terminal_data.go` — call `ghostty_terminal_get` with the 102 + appropriate enum, cast result to Go type. 103 + - **New/Free lifecycle**: See `render_state.go` — `NewX()` returns 104 + `(*X, error)`, `Close()` frees. 105 + - **Effect callbacks**: See `terminal_effect.go` — use C trampolines 106 + with `//export` and `cgo.Handle` for userdata round-tripping. 107 + - **Tagged unions**: See `terminal.go` `ScrollViewport*` — set tag 108 + then poke the value union via `unsafe.Pointer`. 109 + - **Formatters/iterators**: See `formatter.go` — functional options 110 + pattern, alloc + copy + free for output buffers. 111 + 112 + ### 6. Write tests 113 + 114 + - Add tests in a `_test.go` file matching the source file name. 115 + - Follow existing test patterns (see `terminal_test.go`, 116 + `formatter_test.go`). 117 + - Run `make test` to verify. 118 + 119 + ### 7. Update TODO.md 120 + 121 + - Remove any items from `TODO.md` that have been bound. 122 + - Add any new partial items if applicable.
+34
.agents/skills/discovering-upstream-apis/scripts/latest-upstream-commit.sh
··· 1 + #!/usr/bin/env bash 2 + # Prints the latest commit SHA on the main branch of the upstream 3 + # ghostty repo. Compares it against the pinned commit in 4 + # CMakeLists.txt and reports whether an update is needed. 5 + 6 + set -euo pipefail 7 + 8 + REPO="ghostty-org/ghostty" 9 + BRANCH="main" 10 + CMAKE="CMakeLists.txt" 11 + 12 + # Get the currently pinned commit from CMakeLists.txt. 13 + pinned=$(grep -oP '(?<=GIT_TAG )[0-9a-f]+' "$CMAKE" 2>/dev/null || true) 14 + if [ -z "$pinned" ]; then 15 + echo "ERROR: could not find GIT_TAG in $CMAKE" >&2 16 + exit 1 17 + fi 18 + 19 + # Fetch the latest commit from GitHub. 20 + latest=$(git ls-remote "https://github.com/${REPO}.git" "refs/heads/${BRANCH}" \ 21 + | awk '{print $1}') 22 + if [ -z "$latest" ]; then 23 + echo "ERROR: could not fetch latest commit from ${REPO}" >&2 24 + exit 1 25 + fi 26 + 27 + echo "pinned: $pinned" 28 + echo "latest: $latest" 29 + 30 + if [ "$pinned" = "$latest" ]; then 31 + echo "status: up-to-date" 32 + else 33 + echo "status: update-available" 34 + fi