diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e2e704d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.lua]
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..d09b490
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Git LFS tracking
+docs/*.gif filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..077a514
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+
+github: taigrr # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7f1acf3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+# Logs
+*.log
+
+# OS files
+.DS_Store
+Thumbs.db
+
+# Editor files
+*.swp
+*.swo
+*~
+.idea/
+.vscode/
+
+# Neovim
+.nvim.lua
+.nvimrc
+.exrc
+
+# Test artifacts
+.tests/
diff --git a/.luarc.json b/.luarc.json
new file mode 100644
index 0000000..1613acb
--- /dev/null
+++ b/.luarc.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
+ "runtime": {
+ "version": "LuaJIT"
+ },
+ "diagnostics": {
+ "globals": ["vim"]
+ },
+ "workspace": {
+ "library": [
+ "${3rd}/luv/library"
+ ],
+ "checkThirdParty": false
+ }
+}
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..48bb5d0
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,188 @@
+# AGENTS.md
+
+AI agent guide for working in glaze.nvim.
+
+## Project Overview
+
+**glaze.nvim** is a Neovim plugin that provides centralized management for Go binaries used by other Neovim plugins. Think "Mason for Go binaries" with a lazy.nvim-style UI.
+
+- **Language**: Lua (Neovim plugin)
+- **Requirements**: Neovim >= 0.9, Go installed
+- **Author**: Tai Groot (taigrr)
+
+## Directory Structure
+
+```
+lua/glaze/
+├── init.lua # Main module: setup, config, registration API, binary path utilities
+├── runner.lua # Task runner: parallel go install with concurrency control
+├── checker.lua # Update checker: version comparison, auto-check scheduling
+├── view.lua # UI: lazy.nvim-style floating window, keybinds, rendering
+├── float.lua # Float window abstraction: backdrop, keymaps, resize handling
+├── text.lua # Text rendering: buffered text with highlight segments
+├── colors.lua # Highlight definitions: doughnut-inspired pink/magenta theme
+├── health.lua # Health check: :checkhealth glaze
+doc/
+└── glaze.txt # Vim help documentation
+```
+
+## Key Concepts
+
+### Binary Registration
+
+Plugins register binaries via `require("glaze").register(name, url, opts)`. Registration stores metadata in `M._binaries` table. Auto-install triggers if enabled and binary is missing.
+
+### Task Runner
+
+`runner.lua` manages parallel `go install` jobs with configurable concurrency. Tasks have states: `pending → running → done|error`. The runner opens the UI automatically when tasks start.
+
+### Update Checking
+
+`checker.lua` compares installed versions (`go version -m`) against latest (`go list -m -json`). State persisted to `vim.fn.stdpath("data") .. "/glaze/state.json"`.
+
+### UI Architecture
+
+- `float.lua`: Generic floating window with backdrop (inspired by lazy.nvim)
+- `view.lua`: Glaze-specific rendering, keybinds, spinner animation
+- `text.lua`: Buffered text builder with highlight segments and extmarks
+
+## Commands
+
+| Command | Description |
+| ---------------------- | ---------------------------------- |
+| `:Glaze` | Open the UI |
+| `:GlazeUpdate [name]` | Update all or specific binary |
+| `:GlazeInstall [name]` | Install missing or specific binary |
+| `:GlazeCheck` | Manual update check |
+| `:checkhealth glaze` | Run health check |
+
+## Testing
+
+**No automated tests exist.** Manual testing workflow:
+
+```lua
+-- In Neovim:
+:luafile % -- Reload current file
+:Glaze -- Test UI
+:checkhealth glaze -- Verify setup
+```
+
+Test with actual binaries:
+
+```lua
+require("glaze").setup({})
+require("glaze").register("glow", "github.com/charmbracelet/glow")
+:GlazeInstall glow
+```
+
+## Code Conventions
+
+### Module Pattern
+
+All modules return a table `M` with public functions. Private functions prefixed with `_`:
+
+```lua
+local M = {}
+M._private_state = {}
+function M.public_fn() end
+function M._private_fn() end
+return M
+```
+
+### Type Annotations
+
+Uses LuaCATS (`---@class`, `---@param`, `---@return`) for type hints. LSP warnings about `vim` being undefined are expected (Neovim globals).
+
+### Async Patterns
+
+- `vim.fn.jobstart()` for external commands
+- `vim.schedule()` to defer to main loop
+- `vim.defer_fn()` for delayed execution
+
+### UI Updates
+
+- Runner notifies via `M._on_update` callback
+- View subscribes and re-renders on notification
+- Timer drives spinner animation (100ms interval)
+
+## Highlight Groups
+
+All highlights prefixed with `Glaze`. Key groups:
+
+- `GlazeH1`, `GlazeH2` - Headers
+- `GlazeBinary`, `GlazeUrl`, `GlazePlugin` - Content
+- `GlazeDone`, `GlazeError`, `GlazeRunning` - Status
+- `GlazeProgressDone`, `GlazeProgressTodo` - Progress bar
+
+Colors follow doughnut aesthetic (pink `#FF6AD5` as primary accent).
+
+## Configuration
+
+Default config in `init.lua:53-78`. Key options:
+
+- `concurrency`: Parallel jobs (default 4)
+- `auto_install.enabled`: Install on register
+- `auto_check.enabled/frequency`: Update checking
+- `auto_update.enabled`: Auto-apply updates
+
+## Common Tasks
+
+### Adding a New Config Option
+
+1. Add to `GlazeConfig` type definition in `init.lua`
+2. Add default value in `M.config`
+3. Document in `README.md` and `doc/glaze.txt`
+
+### Adding a New Command
+
+1. Create in `M.setup()` via `vim.api.nvim_create_user_command()`
+2. Document in README and help file
+
+### Modifying UI
+
+1. Edit `view.lua:render()` for content changes
+2. Edit `view.lua:open()` to add keybinds
+3. Edit `colors.lua` for new highlight groups
+
+### Adding Health Checks
+
+Add checks in `health.lua:check()` using `vim.health.ok/warn/error/info`.
+
+## Gotchas
+
+1. **vim global**: All `vim.*` calls show LSP warnings - this is normal for Neovim plugins without proper Lua LSP config.
+
+2. **Race conditions**: `runner.lua` rejects new tasks if already running. Check `runner.is_running()` first.
+
+3. **Timer cleanup**: `view.lua._timer` must be stopped on close, or spinner keeps running.
+
+4. **State file**: `checker.lua` persists to data dir. If corrupt, delete `~/.local/share/nvim/glaze/state.json`.
+
+5. **GOBIN detection**: Checks multiple locations: `$GOBIN`, `$GOPATH/bin`, `~/go/bin`. See `init.lua:is_installed()`.
+
+6. **goenv support**: Auto-detected in setup, changes `go_cmd` to `{ "goenv", "exec", "go" }`.
+
+## API Reference
+
+Main module (`require("glaze")`):
+
+- `setup(opts)` - Initialize with config
+- `register(name, url, opts)` - Register binary
+- `unregister(name)` - Remove binary
+- `binaries()` - Get all registered
+- `is_installed(name)` - Check if binary exists
+- `bin_path(name)` - Get full path
+- `status(name)` - Get "installed"/"missing"/"unknown"
+
+Runner (`require("glaze.runner")`):
+
+- `update(names)` / `update_all()` - Update binaries
+- `install(names)` / `install_missing()` - Install binaries
+- `abort()` - Stop all tasks
+- `is_running()` / `tasks()` / `stats()` - Query state
+
+Checker (`require("glaze.checker")`):
+
+- `check(opts)` - Check for updates
+- `auto_check()` - Check if interval passed
+- `get_update_info()` - Get cached version info
diff --git a/LICENSE b/LICENSE
index 7e96918..ccaee7e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,14 @@
-MIT License
+BSD Zero Clause License
-Copyright (c) 2026 Tai Groot
+Copyright (c) 2025 Tai Groot
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..03d9b8e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+.PHONY: demo clean
+
+PLUGIN_PATH := $(shell pwd)
+
+demo:
+ @echo "Recording demo.gif..."
+ PLUGIN_PATH=$(PLUGIN_PATH) vhs docs/demo.tape
+ @echo "Done! Output: docs/demo.gif"
+
+clean:
+ rm -rf /tmp/vhs-glaze-config /tmp/vhs-glaze-data /tmp/glaze-demo
diff --git a/README.md b/README.md
index d159dd2..92d1b70 100644
--- a/README.md
+++ b/README.md
@@ -1,123 +1,164 @@
-# 🍩 glaze.nvim
+
+
+
+
+
-> **Go + Lazy = Glaze** — A Mason/Lazy-style manager for Go binaries in Neovim.
-> Charmbracelet-inspired aesthetic. Zero duplication. One source of truth.
->
-> *Like a fresh doughnut glaze — smooth, sweet, and holds everything together.*
+