Remove bookmarks and tags pages and sidebar blocks
Assisted-by: Claude Sonnet 4.6 via Claude Code
change smqrzsrwuqwrpkqwwtxokovwurtqpykq
commit 09863fe821bd78595e4a784eee35e7618aed192d
author Alpha Chen <alpha@kejadlen.dev>
date
parent nopqqnmk
diff --git a/quire-server/src/quire/web/handlers/ci.rs b/quire-server/src/quire/web/handlers/ci.rs
index 5a5a419..33c7c23 100644
--- a/quire-server/src/quire/web/handlers/ci.rs
+++ b/quire-server/src/quire/web/handlers/ci.rs
@@ -9,7 +9,6 @@ use super::super::templates::{
     DetailJob, DetailRun, DetailShEvent, RunDetailTemplate, RunListRow, RunListTemplate,
     nav_sections,
 };
-use super::git::RepoView;
 use super::{render, render_error};
 use crate::Quire;
 use crate::quire::web::paths::{RunDetailPath, RunListPath};
@@ -17,18 +16,14 @@ use crate::quire::web::paths::{RunDetailPath, RunListPath};
 pub async fn run_list(RunListPath { repo }: RunListPath, State(quire): State<Quire>) -> Response {
     let repo_display = repo.trim_end_matches(".git").to_string();
     let repo_name = db::resolve_repo_name(&repo);
-    let git_repo = match quire.repo(&repo_name) {
-        Ok(r) if r.exists() => r,
+    match quire.repo(&repo_name) {
+        Ok(r) if r.exists() => {}
         _ => return StatusCode::NOT_FOUND.into_response(),
     };
 
     let q = quire.clone();
     let rn = repo_name.clone();
     let runs_handle = tokio::task::spawn_blocking(move || db::load_runs(&q, &rn));
-    let refs_handle = tokio::task::spawn_blocking(move || {
-        let r = RepoView::new(&git_repo);
-        (r.bookmarks(), r.tags())
-    });
 
     let runs = match runs_handle.await {
         Ok(Ok(r)) => r,
@@ -46,7 +41,6 @@ pub async fn run_list(RunListPath { repo }: RunListPath, State(quire): State<Qui
             return StatusCode::INTERNAL_SERVER_ERROR.into_response();
         }
     };
-    let (bookmarks, tags) = refs_handle.await.unwrap_or_default();
 
     let template_runs: Vec<RunListRow> = runs
         .into_iter()
@@ -66,8 +60,6 @@ pub async fn run_list(RunListPath { repo }: RunListPath, State(quire): State<Qui
         repo: repo_display,
         crumbs: None,
         runs: template_runs,
-        bookmarks,
-        tags,
     };
     render(&tmpl)
 }
@@ -78,19 +70,14 @@ pub async fn run_detail(
 ) -> Response {
     let repo_display = repo.trim_end_matches(".git").to_string();
     let repo_name = db::resolve_repo_name(&repo);
-    let git_repo = match quire.repo(&repo_name) {
-        Ok(r) if r.exists() => r,
+    match quire.repo(&repo_name) {
+        Ok(r) if r.exists() => {}
         _ => return StatusCode::NOT_FOUND.into_response(),
     };
     if !db::is_valid_run_id(&run_id) {
         return StatusCode::NOT_FOUND.into_response();
     }
 
-    let refs_handle = tokio::task::spawn_blocking(move || {
-        let r = RepoView::new(&git_repo);
-        (r.bookmarks(), r.tags())
-    });
-
     let q = quire.clone();
     let rn = repo_name.clone();
     let ri = run_id.clone();
@@ -205,7 +192,6 @@ pub async fn run_detail(
     }
 
     let quire_ci_log = quire_ci_log_handle.await.unwrap_or_default();
-    let (bookmarks, tags) = refs_handle.await.unwrap_or_default();
 
     let tmpl = RunDetailTemplate {
         sections: nav_sections(&repo_display, "ci", true),
@@ -214,8 +200,6 @@ pub async fn run_detail(
         run: detail_run,
         jobs: detail_jobs,
         quire_ci_log,
-        bookmarks,
-        tags,
     };
     render(&tmpl)
 }
diff --git a/quire-server/src/quire/web/handlers/git.rs b/quire-server/src/quire/web/handlers/git.rs
index bece1e1..ac298d2 100644
--- a/quire-server/src/quire/web/handlers/git.rs
+++ b/quire-server/src/quire/web/handlers/git.rs
@@ -1,15 +1,9 @@
 //! Shared git-reading helpers used by multiple handlers.
 
-use super::super::templates::{BookmarkRow, ChangeRow, HeadInfo, TagRow};
+use super::super::templates::{ChangeRow, HeadInfo};
 use crate::quire::Repo;
 
-pub(super) type GitData = (
-    Option<HeadInfo>,
-    Option<String>,
-    Vec<BookmarkRow>,
-    Vec<TagRow>,
-    Vec<ChangeRow>,
-);
+pub(super) type GitData = (Option<HeadInfo>, Option<String>, Vec<ChangeRow>);
 
 pub(super) struct RepoView<'a> {
     repo: &'a Repo,
@@ -34,13 +28,7 @@ impl<'a> RepoView<'a> {
 
     /// Read all summary data from the repo for the home page.
     pub(super) fn read_all(&self, repo: &str) -> GitData {
-        (
-            self.head_info(),
-            self.readme(),
-            self.bookmarks(),
-            self.tags(),
-            self.recent_changes(repo),
-        )
+        (self.head_info(), self.readme(), self.recent_changes(repo))
     }
 
     pub(super) fn head_info(&self) -> Option<HeadInfo> {
@@ -71,49 +59,6 @@ impl<'a> RepoView<'a> {
         None
     }
 
-    pub(super) fn bookmarks(&self) -> Vec<BookmarkRow> {
-        let out = self
-            .run(&[
-                "for-each-ref",
-                "--format=%(refname:short)|%(objectname:short)|%(committerdate:relative)",
-                "--sort=-committerdate",
-                "refs/heads/",
-            ])
-            .unwrap_or_default();
-
-        out.lines()
-            .filter_map(|line| {
-                let mut parts = line.splitn(3, '|');
-                Some(BookmarkRow {
-                    name: parts.next()?.to_string(),
-                    sha_short: parts.next()?.to_string(),
-                    age: parts.next().unwrap_or("").to_string(),
-                })
-            })
-            .collect()
-    }
-
-    pub(super) fn tags(&self) -> Vec<TagRow> {
-        let out = self
-            .run(&[
-                "for-each-ref",
-                "--format=%(refname:short)|%(committerdate:relative)",
-                "--sort=-creatordate",
-                "refs/tags/",
-            ])
-            .unwrap_or_default();
-
-        out.lines()
-            .filter_map(|line| {
-                let mut parts = line.splitn(2, '|');
-                Some(TagRow {
-                    name: parts.next()?.to_string(),
-                    age: parts.next().unwrap_or("").to_string(),
-                })
-            })
-            .collect()
-    }
-
     pub(super) fn recent_changes(&self, repo: &str) -> Vec<ChangeRow> {
         self.recent_changes_for(None, repo)
     }
diff --git a/quire-server/src/quire/web/handlers/mod.rs b/quire-server/src/quire/web/handlers/mod.rs
index 6a2c2d0..0484640 100644
--- a/quire-server/src/quire/web/handlers/mod.rs
+++ b/quire-server/src/quire/web/handlers/mod.rs
@@ -4,7 +4,6 @@ mod ci;
 mod commit;
 mod git;
 mod log_view;
-mod refs;
 mod repo;
 mod repo_list;
 mod tree;
@@ -12,7 +11,6 @@ mod tree;
 pub use ci::{run_detail, run_list};
 pub use commit::commit_view;
 pub use log_view::log_view;
-pub use refs::{bookmarks_view, tags_view};
 pub use repo::repo_home;
 pub use repo_list::repo_list;
 pub use tree::{tree_view, tree_view_path};
diff --git a/quire-server/src/quire/web/handlers/refs.rs b/quire-server/src/quire/web/handlers/refs.rs
deleted file mode 100644
index 7b26618..0000000
--- a/quire-server/src/quire/web/handlers/refs.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-//! Handlers for the bookmarks and tags listing pages.
-
-use axum::extract::State;
-use axum::http::StatusCode;
-use axum::response::IntoResponse;
-use axum::response::Response;
-
-use super::super::templates::{BookmarksTemplate, TagsTemplate, nav_sections};
-use super::git::RepoView;
-use super::render;
-use crate::Quire;
-use crate::quire::web::paths::{BookmarksPath, TagsPath};
-
-pub async fn bookmarks_view(
-    BookmarksPath { repo }: BookmarksPath,
-    State(quire): State<Quire>,
-    auth: super::super::auth::Auth,
-) -> Response {
-    let repo_display = repo.trim_end_matches(".git").to_string();
-    let repo_name = super::super::db::resolve_repo_name(&repo);
-    let git_repo = match quire.repo(&repo_name) {
-        Ok(r) if r.exists() => r,
-        _ => return StatusCode::NOT_FOUND.into_response(),
-    };
-
-    let (bookmarks, tags) = tokio::task::spawn_blocking(move || {
-        let reader = RepoView::new(&git_repo);
-        (reader.bookmarks(), reader.tags())
-    })
-    .await
-    .unwrap_or_default();
-
-    let tmpl = BookmarksTemplate {
-        sections: nav_sections(&repo_display, "bookmarks", auth.is_authenticated()),
-        repo: repo_display,
-        crumbs: None,
-        bookmarks,
-        tags,
-    };
-    render(&tmpl)
-}
-
-pub async fn tags_view(
-    TagsPath { repo }: TagsPath,
-    State(quire): State<Quire>,
-    auth: super::super::auth::Auth,
-) -> Response {
-    let repo_display = repo.trim_end_matches(".git").to_string();
-    let repo_name = super::super::db::resolve_repo_name(&repo);
-    let git_repo = match quire.repo(&repo_name) {
-        Ok(r) if r.exists() => r,
-        _ => return StatusCode::NOT_FOUND.into_response(),
-    };
-
-    let (bookmarks, tags) = tokio::task::spawn_blocking(move || {
-        let reader = RepoView::new(&git_repo);
-        (reader.bookmarks(), reader.tags())
-    })
-    .await
-    .unwrap_or_default();
-
-    let tmpl = TagsTemplate {
-        sections: nav_sections(&repo_display, "tags", auth.is_authenticated()),
-        repo: repo_display,
-        crumbs: None,
-        bookmarks,
-        tags,
-    };
-    render(&tmpl)
-}
diff --git a/quire-server/src/quire/web/handlers/repo.rs b/quire-server/src/quire/web/handlers/repo.rs
index 571747c..5142dda 100644
--- a/quire-server/src/quire/web/handlers/repo.rs
+++ b/quire-server/src/quire/web/handlers/repo.rs
@@ -53,7 +53,7 @@ pub async fn repo_home(
     };
 
     let rd = repo_display.clone();
-    let (head, readme_html, bookmarks, tags, recent_changes) =
+    let (head, readme_html, recent_changes) =
         tokio::task::spawn_blocking(move || RepoView::new(&git_repo).read_all(&rd))
             .await
             .unwrap_or_default();
@@ -64,8 +64,6 @@ pub async fn repo_home(
         crumbs: None,
         head,
         readme_html,
-        bookmarks,
-        tags,
         recent_runs,
         recent_changes,
     };
diff --git a/quire-server/src/quire/web/handlers/tree.rs b/quire-server/src/quire/web/handlers/tree.rs
index c478731..82be2d2 100644
--- a/quire-server/src/quire/web/handlers/tree.rs
+++ b/quire-server/src/quire/web/handlers/tree.rs
@@ -45,10 +45,8 @@ async fn tree_or_file_at_path(quire: Quire, repo: String, path: String, authed:
 
         // Try ls-tree first — if it succeeds, this is a directory.
         if let Some(tree_data) = read_tree_data(&reader, &path_clone) {
-            let bookmarks = reader.bookmarks();
-            let tags = reader.tags();
             let recent_changes = reader.recent_changes_for(Some(&path_clone), &repo_d);
-            Some(Ok((tree_data, bookmarks, tags, recent_changes)))
+            Some(Ok((tree_data, recent_changes)))
         } else {
             // ls-tree failed — try reading as a file blob.
             read_file_data(&reader, &path_clone).map(Err)
@@ -58,14 +56,12 @@ async fn tree_or_file_at_path(quire: Quire, repo: String, path: String, authed:
     .unwrap_or(None);
 
     match result {
-        Some(Ok((tree_data, bookmarks, tags, recent_changes))) => {
+        Some(Ok((tree_data, recent_changes))) => {
             let crumbs = build_tree_crumbs(&repo_display, &path);
             let tmpl = TreeTemplate {
                 sections: nav_sections(&repo_display, "tree", authed),
                 repo: repo_display,
                 crumbs: Some(crumbs),
-                bookmarks,
-                tags,
                 path,
                 bookmark: tree_data.bookmark,
                 sha_short: tree_data.sha_short,
diff --git a/quire-server/src/quire/web/mod.rs b/quire-server/src/quire/web/mod.rs
index 28919eb..b9ded14 100644
--- a/quire-server/src/quire/web/mod.rs
+++ b/quire-server/src/quire/web/mod.rs
@@ -19,14 +19,13 @@ use axum_extra::routing::RouterExt;
 use crate::{
     Quire,
     quire::web::handlers::{
-        bookmarks_view, commit_view, config, log_view, repo_home, repo_list, run_detail, run_list,
-        stylesheet, tags_view, tree_view, tree_view_path,
+        commit_view, config, log_view, repo_home, repo_list, run_detail, run_list, stylesheet,
+        tree_view, tree_view_path,
     },
 };
 
 pub use paths::{
-    BookmarksPath, CommitPath, LogPath, RepoPath, RunDetailPath, RunListPath, TagsPath, TreePath,
-    TreeRootPath,
+    CommitPath, LogPath, RepoPath, RunDetailPath, RunListPath, TreePath, TreeRootPath,
 };
 
 pub mod paths {
@@ -71,18 +70,6 @@ pub mod paths {
         pub repo: String,
     }
 
-    #[derive(TypedPath, Deserialize)]
-    #[typed_path("/{repo}/bookmarks")]
-    pub struct BookmarksPath {
-        pub repo: String,
-    }
-
-    #[derive(TypedPath, Deserialize)]
-    #[typed_path("/{repo}/tags")]
-    pub struct TagsPath {
-        pub repo: String,
-    }
-
     #[derive(TypedPath, Deserialize)]
     #[typed_path("/{repo}/commits/{sha}")]
     pub struct CommitPath {
@@ -109,8 +96,6 @@ pub fn public_router(quire: Quire) -> Router {
         .typed_get(tree_view)
         .typed_get(tree_view_path)
         .typed_get(log_view)
-        .typed_get(bookmarks_view)
-        .typed_get(tags_view)
         .typed_get(commit_view)
         .route("/config", get(config))
         .route("/", get(repo_list))
diff --git a/quire-server/src/quire/web/templates.rs b/quire-server/src/quire/web/templates.rs
index 48ee17e..d4e634e 100644
--- a/quire-server/src/quire/web/templates.rs
+++ b/quire-server/src/quire/web/templates.rs
@@ -80,8 +80,6 @@ pub struct RunListTemplate {
     pub repo: String,
     pub crumbs: Option<Vec<Crumb>>,
     pub runs: Vec<RunListRow>,
-    pub bookmarks: Vec<BookmarkRow>,
-    pub tags: Vec<TagRow>,
     pub sections: Vec<SectionLink>,
 }
 
@@ -141,8 +139,6 @@ pub struct RunDetailTemplate {
     pub run: DetailRun,
     pub jobs: Vec<DetailJob>,
     pub quire_ci_log: String,
-    pub bookmarks: Vec<BookmarkRow>,
-    pub tags: Vec<TagRow>,
     pub sections: Vec<SectionLink>,
 }
 
@@ -300,8 +296,6 @@ pub struct RepoHomeTemplate {
     pub crumbs: Option<Vec<Crumb>>,
     pub head: Option<HeadInfo>,
     pub readme_html: Option<String>,
-    pub bookmarks: Vec<BookmarkRow>,
-    pub tags: Vec<TagRow>,
     pub recent_runs: Vec<RunListRow>,
     pub recent_changes: Vec<ChangeRow>,
     pub sections: Vec<SectionLink>,
@@ -325,22 +319,6 @@ impl RepoHomeTemplate {
             .map(|r| r.state_class())
             .unwrap_or("")
     }
-
-    pub fn bookmarks_preview(&self) -> &[BookmarkRow] {
-        &self.bookmarks[..self.bookmarks.len().min(5)]
-    }
-
-    pub fn extra_bookmarks(&self) -> usize {
-        self.bookmarks.len().saturating_sub(5)
-    }
-
-    pub fn tags_preview(&self) -> &[TagRow] {
-        &self.tags[..self.tags.len().min(5)]
-    }
-
-    pub fn extra_tags(&self) -> usize {
-        self.tags.len().saturating_sub(5)
-    }
 }
 
 pub struct HeadInfo {
@@ -367,17 +345,6 @@ impl HeadInfo {
     }
 }
 
-pub struct BookmarkRow {
-    pub name: String,
-    pub sha_short: String,
-    pub age: String,
-}
-
-pub struct TagRow {
-    pub name: String,
-    pub age: String,
-}
-
 pub struct ChangeRow {
     pub sha: String,
     pub description: String,
@@ -430,8 +397,6 @@ impl ConfigTemplate {
 pub struct TreeTemplate {
     pub repo: String,
     pub crumbs: Option<Vec<Crumb>>,
-    pub bookmarks: Vec<BookmarkRow>,
-    pub tags: Vec<TagRow>,
     pub sections: Vec<SectionLink>,
     /// Current directory path relative to repo root ("" = root).
     pub path: String,
@@ -600,42 +565,6 @@ impl LogTemplate {
     }
 }
 
-// ── Bookmarks ────────────────────────────────────────────────────
-
-#[derive(Template)]
-#[template(path = "bookmarks.html")]
-pub struct BookmarksTemplate {
-    pub repo: String,
-    pub crumbs: Option<Vec<Crumb>>,
-    pub bookmarks: Vec<BookmarkRow>,
-    pub tags: Vec<TagRow>,
-    pub sections: Vec<SectionLink>,
-}
-
-impl BookmarksTemplate {
-    pub fn version(&self) -> &'static str {
-        pkg_version()
-    }
-}
-
-// ── Tags ─────────────────────────────────────────────────────────
-
-#[derive(Template)]
-#[template(path = "tags.html")]
-pub struct TagsTemplate {
-    pub repo: String,
-    pub crumbs: Option<Vec<Crumb>>,
-    pub bookmarks: Vec<BookmarkRow>,
-    pub tags: Vec<TagRow>,
-    pub sections: Vec<SectionLink>,
-}
-
-impl TagsTemplate {
-    pub fn version(&self) -> &'static str {
-        pkg_version()
-    }
-}
-
 // ── Error ──────────────────────────────────────────────────────────
 
 #[derive(Template)]
diff --git a/quire-server/templates/bookmarks.html b/quire-server/templates/bookmarks.html
deleted file mode 100644
index dec1f0b..0000000
--- a/quire-server/templates/bookmarks.html
+++ /dev/null
@@ -1,51 +0,0 @@
-{% extends "_base.html" %}
-
-{% block title %}bookmarks · {{ repo }}{% endblock %}
-
-{% block nav %}
-{% include "_nav.html" %}
-{% endblock %}
-
-{% block fullpage %}
-
-<nav class="repo-section-nav">
-  {% include "_repo_section_nav.html" %}
-</nav>
-
-<div class="repo-body">
-
-  <article class="ref-list">
-    {% for b in bookmarks %}
-    <div class="ref-row">
-      <span class="bookmark-kind {% if loop.first %}bookmark-kind--trunk{% endif %}">{% if loop.first %}trunk{% else %}local{% endif %}</span>
-      <a class="bookmark-link" href="/{{ repo }}/log">
-        <span class="bookmark-glyph-sm">※</span>{{ b.name }}
-      </a>
-      <span class="ref-sha">{{ b.sha_short }}</span>
-      <span class="ref-age">{{ b.age }}</span>
-    </div>
-    {% else %}
-    <p class="ref-empty">no bookmarks</p>
-    {% endfor %}
-  </article>
-
-  <aside class="repo-sidebar">
-    {% if !tags.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Tags</div>
-      <div class="bookmark-list">
-        {% for t in tags %}
-        <div class="bookmark-row">
-          <a class="bookmark-link" href="/{{ repo }}/tags">{{ t.name }}</a>
-          <span class="bookmark-age">{{ t.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-      <a class="side-more" href="/{{ repo }}/tags">all tags →</a>
-    </div>
-    {% endif %}
-  </aside>
-
-</div>
-
-{% endblock %}
diff --git a/quire-server/templates/ci/run_detail.html b/quire-server/templates/ci/run_detail.html
index 1be27c6..2183314 100644
--- a/quire-server/templates/ci/run_detail.html
+++ b/quire-server/templates/ci/run_detail.html
@@ -67,38 +67,6 @@
     {% endif %}
   </article>
 
-  <aside class="repo-sidebar">
-    {% if !bookmarks.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Bookmarks</div>
-      <div class="bookmark-list">
-        {% for b in bookmarks %}
-        <div class="bookmark-row">
-          <span class="bookmark-kind {% if loop.first %}bookmark-kind--trunk{% endif %}">{% if loop.first %}trunk{% else %}local{% endif %}</span>
-          <a class="bookmark-link" href="/{{ repo }}/log">
-            <span class="bookmark-glyph-sm">※</span>{{ b.name }}
-          </a>
-          <span class="bookmark-age">{{ b.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-    </div>
-    {% endif %}
-
-    {% if !tags.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Tags</div>
-      <div class="bookmark-list">
-        {% for t in tags %}
-        <div class="bookmark-row">
-          <a class="bookmark-link" href="/{{ repo }}/log">{{ t.name }}</a>
-          <span class="bookmark-age">{{ t.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-    </div>
-    {% endif %}
-  </aside>
 
 </div>
 
diff --git a/quire-server/templates/ci/run_list.html b/quire-server/templates/ci/run_list.html
index 4189018..fd92a52 100644
--- a/quire-server/templates/ci/run_list.html
+++ b/quire-server/templates/ci/run_list.html
@@ -28,38 +28,6 @@
     {% endfor %}
   </article>
 
-  <aside class="repo-sidebar">
-    {% if !bookmarks.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Bookmarks</div>
-      <div class="bookmark-list">
-        {% for b in bookmarks %}
-        <div class="bookmark-row">
-          <span class="bookmark-kind {% if loop.first %}bookmark-kind--trunk{% endif %}">{% if loop.first %}trunk{% else %}local{% endif %}</span>
-          <a class="bookmark-link" href="/{{ repo }}/log">
-            <span class="bookmark-glyph-sm">※</span>{{ b.name }}
-          </a>
-          <span class="bookmark-age">{{ b.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-    </div>
-    {% endif %}
-
-    {% if !tags.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Tags</div>
-      <div class="bookmark-list">
-        {% for t in tags %}
-        <div class="bookmark-row">
-          <a class="bookmark-link" href="/{{ repo }}/log">{{ t.name }}</a>
-          <span class="bookmark-age">{{ t.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-    </div>
-    {% endif %}
-  </aside>
 
 </div>
 
diff --git a/quire-server/templates/repo_home.html b/quire-server/templates/repo_home.html
index 9d948d6..a0bda89 100644
--- a/quire-server/templates/repo_home.html
+++ b/quire-server/templates/repo_home.html
@@ -53,43 +53,6 @@
       <div class="clone-url">https://quire.local/{{ repo }}.git</div>
     </div>
 
-    {% if !bookmarks.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Bookmarks</div>
-      <div class="bookmark-list">
-        {% for b in self.bookmarks_preview() %}
-        <div class="bookmark-row">
-          <span class="bookmark-kind {% if loop.first %}bookmark-kind--trunk{% endif %}">{% if loop.first %}trunk{% else %}local{% endif %}</span>
-          <a class="bookmark-link" href="/{{ repo }}/log">
-            <span class="bookmark-glyph-sm">※</span>{{ b.name }}
-          </a>
-          <span class="bookmark-age">{{ b.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-      {% if self.extra_bookmarks() > 0 %}
-      <a class="side-more" href="/{{ repo }}/bookmarks">all bookmarks →</a>
-      {% endif %}
-    </div>
-    {% endif %}
-
-    {% if !tags.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Tags</div>
-      <div class="bookmark-list">
-        {% for t in self.tags_preview() %}
-        <div class="bookmark-row">
-          <a class="bookmark-link" href="/{{ repo }}/log">{{ t.name }}</a>
-          <span class="bookmark-age">{{ t.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-      {% if self.extra_tags() > 0 %}
-      <a class="side-more" href="/{{ repo }}/tags">+ {{ self.extra_tags() }} more →</a>
-      {% endif %}
-    </div>
-    {% endif %}
-
     {% if !recent_runs.is_empty() %}
     <div class="side-block">
       <div class="side-block-title">CI</div>
diff --git a/quire-server/templates/tags.html b/quire-server/templates/tags.html
deleted file mode 100644
index b2680fc..0000000
--- a/quire-server/templates/tags.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% extends "_base.html" %}
-
-{% block title %}tags · {{ repo }}{% endblock %}
-
-{% block nav %}
-{% include "_nav.html" %}
-{% endblock %}
-
-{% block fullpage %}
-
-<nav class="repo-section-nav">
-  {% include "_repo_section_nav.html" %}
-</nav>
-
-<div class="repo-body">
-
-  <article class="ref-list">
-    {% for t in tags %}
-    <div class="ref-row">
-      <a class="bookmark-link" href="/{{ repo }}/log">{{ t.name }}</a>
-      <span class="ref-age">{{ t.age }}</span>
-    </div>
-    {% else %}
-    <p class="ref-empty">no tags</p>
-    {% endfor %}
-  </article>
-
-  <aside class="repo-sidebar">
-    {% if !bookmarks.is_empty() %}
-    <div class="side-block">
-      <div class="side-block-title">Bookmarks</div>
-      <div class="bookmark-list">
-        {% for b in bookmarks %}
-        <div class="bookmark-row">
-          <span class="bookmark-kind {% if loop.first %}bookmark-kind--trunk{% endif %}">{% if loop.first %}trunk{% else %}local{% endif %}</span>
-          <a class="bookmark-link" href="/{{ repo }}/bookmarks">
-            <span class="bookmark-glyph-sm">※</span>{{ b.name }}
-          </a>
-          <span class="bookmark-age">{{ b.age }}</span>
-        </div>
-        {% endfor %}
-      </div>
-      <a class="side-more" href="/{{ repo }}/bookmarks">all bookmarks →</a>
-    </div>
-    {% endif %}
-  </aside>
-
-</div>
-
-{% endblock %}