diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000..bb83649
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,32 @@
+# Changelog
+
+## 0.2.0 (2026-07-12)
+
+### pygittools
+
+- Add `pgt`, a terminal user interface for browsing repos, staging changes, and committing.
+- Persist commit message drafts across sessions.
+- Add tab navigation on the main page, input context handling to avoid key conflicts, and a basic log page.
+- Add `pgt tags sync` to synchronize annotated task tags.
+- Add a task MCP server (`pygittools-mcp`) for agent integration.
+- Show task IDs on the task board.
+
+### pygitweb
+
+- Implement Git smart HTTP for clone and push over HTTP.
+- Add per-project read/write permissions, enabling private repositories.
+- Harden board creation and comment modification routes.
+- Restrict the `/_internal/notify` hook route to localhost connections only.
+- Add a shutdown option on the settings page.
+- Add tag and commit search in the task UI.
+- Fix merge request opener when not explicitly configured in project settings.
+
+### Tests and docs
+
+- Fix hook listing and OAuth callback tests; mock Git signatures in tests for fresh Git installs.
+- Add smart HTTP clone/push test coverage including WebSocket upgrade.
+
+## 0.1.0
+
+Initial PyPI release of pygitweb and pygittools.
+
diff --git a/pygittools/__meta__.py b/pygittools/__meta__.py
index 291c4a2..d7f9fa4 100644
--- a/pygittools/__meta__.py
+++ b/pygittools/__meta__.py
@@ -2,7 +2,7 @@
 Metadata for PyGitTools - this is the canonical source of all information below.
 """
 
-__version__ = "0.1.0"
+__version__ = "0.2.0"
 __author__ = "Will Bowers"
 __license__ = "MIT"
 __description__ = "Python hooks and metadata storage in Git"
diff --git a/pygittools/pyproject.toml b/pygittools/pyproject.toml
index ab2894a..bd9e696 100644
--- a/pygittools/pyproject.toml
+++ b/pygittools/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
 
 [project]
 name = "pygittools"
-version = "0.1.0"
+version = "0.2.0"
 description = "Hooks and task storage in Git"
 readme = "README.md"
 license = "MIT"
diff --git a/pygitweb/__meta__.py b/pygitweb/__meta__.py
index 6b53919..00e334d 100644
--- a/pygitweb/__meta__.py
+++ b/pygitweb/__meta__.py
@@ -2,7 +2,7 @@
 Metadata for PyGitWeb - this is the canonical source of all information below.
 """
 
-__version__ = "0.1.0"
+__version__ = "0.2.0"
 __author__ = "Will Bowers"
 __license__ = "MIT"
 __description__ = "FastAPI + Pygit2 Repo Browser"
diff --git a/pygitweb/pyproject.toml b/pygitweb/pyproject.toml
index 62e492c..15d5920 100644
--- a/pygitweb/pyproject.toml
+++ b/pygitweb/pyproject.toml
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
 
 [project]
 name = "pygitweb"
-version = "0.1.0"
+version = "0.2.0"
 description = "Gitweb reimplementation with FastAPI and Pygit2"
 readme = "README.md"
 license = "MIT"
 license-files = ["LICENSE"]
 requires-python = ">=3.11"
 dependencies = [
-    "pygittools>=0.1.0",
+    "pygittools>=0.2.0",
     "fastapi[standard-no-fastapi-cloud-cli]>=0.104.0",
     "uvicorn[standard]>=0.24.0",
     "python-multipart>=0.0.6",
diff --git a/uv.lock b/uv.lock
index 3d3503b..be395d0 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1068,7 +1068,7 @@ wheels = [
 
 [[package]]
 name = "pygittools"
-version = "0.1.0"
+version = "0.2.0"
 source = { editable = "pygittools" }
 dependencies = [
     { name = "mcp" },
@@ -1085,7 +1085,7 @@ requires-dist = [
 
 [[package]]
 name = "pygitweb"
-version = "0.1.0"
+version = "0.2.0"
 source = { editable = "pygitweb" }
 dependencies = [
     { name = "fastapi", extra = ["standard-no-fastapi-cloud-cli"] },
