diff --git a/pygittools/main.py b/pygittools/main.py
index e60299c..6bbcf3c 100644
--- a/pygittools/main.py
+++ b/pygittools/main.py
@@ -7,7 +7,8 @@ import sys
 from pathlib import Path
 
 import pygittools
-from pygittools.tags_sync import format_sync_result, sync_board_tags
+from pygittools.tags_sync import delete_task_remote, format_sync_result, sync_board_tags
+from pygittools.tasks import TASK_REF_PREFIX, delete_task_local
 from pygittools.tasks_query import open_repository, resolve_repo_location
 from pygittools.tui import run_tui
 
@@ -42,6 +43,16 @@ def build_parser() -> argparse.ArgumentParser:
 		default="Tasks",
 		help="Board name under refs/tags/boards/ (default: Tasks)",
 	)
+	delete_parser = tags_subparsers.add_parser("delete-task", help="Delete a task tag locally and on a remote")
+	delete_parser.add_argument(
+		"task",
+		help="Task ref or ID (for example refs/tags/tasks/alpha or alpha)",
+	)
+	delete_parser.add_argument(
+		"--remote",
+		default="origin",
+		help="Remote name to delete from (for example origin)",
+	)
 	return parser
 
 
@@ -57,6 +68,27 @@ def _run_tags_sync(repo_path: Path | None, remote: str, board: str) -> int:
 	return 0
 
 
+def _normalize_task_ref(task: str) -> str:
+	if task.startswith("refs/"):
+		return task
+	return f"{TASK_REF_PREFIX}{task}"
+
+
+def _run_task_delete(repo_path: Path | None, remote: str | None, task: str) -> int:
+	location = resolve_repo_location(repo_path=repo_path)
+	repo = open_repository(location)
+	task_ref = _normalize_task_ref(task)
+	delete_task_local(repo, task_ref)
+	if not remote:
+		return 0
+	try:
+		delete_task_remote(repo, remote, task_ref)
+	except (KeyError, RuntimeError, ValueError) as exc:
+		print(exc, file=sys.stderr)
+		return 1
+	return 0
+
+
 def main(argv: list[str] | None = None) -> int:
 	args_list = sys.argv[1:] if argv is None else argv
 	if not args_list:
@@ -67,6 +99,8 @@ def main(argv: list[str] | None = None) -> int:
 
 	if args.command == "tags" and args.tags_command == "sync":
 		return _run_tags_sync(args.repo, args.remote, args.board)
+	if args.command == "tags" and args.tags_command == "delete-task":
+		return _run_task_delete(args.repo, args.remote, args.task)
 
 	return run_tui(args.repo)
 
diff --git a/pygittools/tags_sync.py b/pygittools/tags_sync.py
index c5dd374..ada3ea6 100644
--- a/pygittools/tags_sync.py
+++ b/pygittools/tags_sync.py
@@ -325,6 +325,35 @@ def push_board_tags(
 	return tuple(pushed), True
 
 
+def delete_task_remote(
+	repo: Repository,
+	remote_name: str,
+	task_ref: str,
+	*,
+	git: str | None = None,
+) -> None:
+	if remote_name not in repo.remotes.names():
+		raise ValueError(f"remote {remote_name!r} not configured")
+
+	task_name = task_ref
+	if not task_name.startswith("refs/") and not task_name.startswith(TASK_REF_PREFIX):
+		task_name = f"{TASK_REF_PREFIX}{task_name}"
+
+	refspecs: list[str] = [f":{task_name}"]
+	task = get_task(repo, task_name)
+	if task is not None:
+		for oid_hex in getattr(task, "comments", []) or []:
+			try:
+				oid = Oid(hex=oid_hex) if isinstance(oid_hex, str) else oid_hex
+				comment = get_comment(repo, oid)
+			except (ValueError, KeyError, TypeError):
+				continue
+			refspecs.append(f":{comment.name}")
+
+	proc = _run_git(repo, "push", remote_name, *refspecs, git=git)
+	_require_git_ok(proc, f"delete {task_name}")
+
+
 def sync_board_tags(
 	repo: Repository,
 	remote_name: str,
diff --git a/pygittools/tasks.py b/pygittools/tasks.py
index 7d48256..ebbef5f 100644
--- a/pygittools/tasks.py
+++ b/pygittools/tasks.py
@@ -331,3 +331,53 @@ def get_board(repo: Repository, ref: str) -> Board | None:
 	b.created_at = _parse_dt(j.get("created_at")) or b.created_at
 	b.updated_at = _parse_dt(j.get("updated_at")) or b.updated_at
 	return b
+
+
+def delete_task_local(repo: Repository, task_ref: str) -> None:
+	try:
+		tag_obj = repo.revparse_single(task_ref)
+	except (KeyError, ValueError):
+		return
+	if not isinstance(tag_obj, Tag):
+		return
+	task = get_task(repo, task_ref)
+	task_name = tag_obj.name
+
+	for ref_name in list(repo.references):
+		if not ref_name.startswith(BOARD_REF_PREFIX):
+			continue
+		board = get_board(repo, ref_name)
+		if board is None:
+			continue
+		original = list(getattr(board, "tasks", []) or [])
+		filtered: list[Oid | str] = []
+		removed: list[str] = []
+		for entry in original:
+			try:
+				oid = Oid(hex=entry) if isinstance(entry, str) else entry
+				board_task = get_task_by_oid(repo, oid)
+			except (ValueError, KeyError, TypeError):
+				filtered.append(entry)
+				continue
+			if board_task is None or board_task.name != task_name:
+				filtered.append(entry)
+			else:
+				removed.append(str(oid))
+		if not removed:
+			continue
+		board.tasks = filtered
+		board.update_message()
+		board.write(repo)
+
+	if task is not None:
+		for oid_hex in getattr(task, "comments", []) or []:
+			try:
+				oid = Oid(hex=oid_hex) if isinstance(oid_hex, str) else oid_hex
+				comment = get_comment(repo, oid)
+			except (ValueError, KeyError, TypeError):
+				continue
+			if comment.name in repo.references:
+				repo.references.delete(comment.name)
+
+	if task_ref in repo.references:
+		repo.references.delete(task_ref)
diff --git a/pygittools/tasks_test.py b/pygittools/tasks_test.py
index bb88ddd..569c876 100644
--- a/pygittools/tasks_test.py
+++ b/pygittools/tasks_test.py
@@ -11,6 +11,7 @@ from pygittools.tasks import (
 	Board,
 	Comment,
 	Task,
+	delete_task_local,
 	get_board,
 	get_comment,
 	get_task,
@@ -201,3 +202,39 @@ def test_full_board_flow_survives_git_gc(repo: Repository, tmp_path: Path) -> No
 
 	contents = [get_comment(reopened, Oid(hex=str(c))).content for c in loaded_task.comments]
 	assert contents == ["first", "second"]
+
+
+def test_delete_task_local_removes_board_and_comment_refs(repo: Repository) -> None:
+	board = Board(_empty_tree(), BOARD_MAIN, TAGGER, description="Main")
+
+	task = Task(
+		_empty_tree(),
+		_task_ref("to-delete"),
+		TAGGER,
+		title="To Delete",
+		description="remove me",
+		status=Task.Status.TODO,
+	)
+	task_oid = task.write(repo)
+
+	comment = Comment(task_oid, "bob <bob@example.com>", content="bye")
+	comment_oid = comment.write(repo)
+
+	task.comments = [str(comment_oid)]
+	task.update_message()
+	task_oid = task.write(repo)
+
+	board.tasks = [str(task_oid)]
+	board.update_message()
+	board.write(repo)
+
+	comment_ref = get_comment(repo, comment_oid).name
+
+	delete_task_local(repo, _task_ref("to-delete"))
+
+	assert _task_ref("to-delete") not in repo.references
+	assert comment_ref not in repo.references
+
+	loaded_board = get_board(repo, BOARD_MAIN)
+	assert loaded_board is not None
+	assert loaded_board.tasks == []
diff --git a/pygittools/tui/input_context.py b/pygittools/tui/input_context.py
index eafa00f..59d9c99 100644
--- a/pygittools/tui/input_context.py
+++ b/pygittools/tui/input_context.py
@@ -61,6 +61,8 @@ class NavContext:
 		if host.header_focus == "repo":
 			return "Enter browse projects — j/k move — H/L switch tab"
 		if host.header_focus == "branch":
+			if host.active_tab == "tasks":
+				return "Enter sync tasks — j/k move — H/L switch tab"
 			return "Enter switch branch — j/k move — H/L switch tab"
 		if host.active_tab == "log":
 			return host.log.status_hint()
@@ -88,7 +90,12 @@ class NavContext:
 			elif key in (KEY_DOWN, ord("j"), ord("J")):
 				host.set_header_focus("changes")
 			elif key in (KEY_ENTER, 10, 13):
-				return ContextDispatch(page_result=PageResult(action=PageAction.PUSH, next_page=branch_picker_page()))
+				if host.active_tab == "tasks" and host.page_context is not None:
+					host.tasks.sync_with_default_remote(host.page_context.repo)
+					return ContextDispatch()
+				return ContextDispatch(
+					page_result=PageResult(action=PageAction.PUSH, next_page=branch_picker_page()),
+				)
 			return ContextDispatch()
 
 		if key in (KEY_UP, ord("k"), ord("K")) and _content_list_is_at_top(host):
diff --git a/pygittools/tui/pages/home.py b/pygittools/tui/pages/home.py
index d1018dd..e0534f3 100644
--- a/pygittools/tui/pages/home.py
+++ b/pygittools/tui/pages/home.py
@@ -110,7 +110,10 @@ class HomePage:
 			branch_attr = theme.branch
 			if self._header_focus == "branch":
 				branch_attr = focus_attr(branch_attr)
-			draw_line(_BRANCH_ROW, 0, f"Branch: {branch}", width, branch_attr)
+			branch_label = f"Branch: {branch}"
+			if self._active_tab == "tasks":
+				branch_label = f"{branch_label} — [Sync tasks]"
+			draw_line(_BRANCH_ROW, 0, branch_label, width, branch_attr)
 
 		list_height = max(0, height - _HEADER_ROWS)
 		if list_height > 0 and height > _HEADER_ROWS:
diff --git a/pygittools/tui/pages/task_editor.py b/pygittools/tui/pages/task_editor.py
index f1c3309..7c9d1b3 100644
--- a/pygittools/tui/pages/task_editor.py
+++ b/pygittools/tui/pages/task_editor.py
@@ -8,12 +8,22 @@ from typing import Literal
 
 from pygit2 import Oid
 
-from pygittools.tasks import BOARD_REF_PREFIX, EMPTY_TREE_OID_HEX, TASK_REF_PREFIX, Task, get_board, get_task
+from pygittools.tags_sync import delete_task_remote, push_board_tags
+from pygittools.tasks import (
+	BOARD_REF_PREFIX,
+	EMPTY_TREE_OID_HEX,
+	TASK_REF_PREFIX,
+	Task,
+	delete_task_local,
+	get_board,
+	get_task,
+)
 from pygittools.tasks_query import BOARD_STATUS_ORDER, get_task_view
 from pygittools.tui.draw import draw_line
 from pygittools.tui.git_colors import current_theme, focus_attr
 from pygittools.tui.types import PageAction, PageContext, PageResult
 from pygittools.tui.ucurses import (  # type: ignore[import-untyped]
+	A_BOLD,
 	KEY_BACKSPACE,
 	KEY_DOWN,
 	KEY_ENTER,
@@ -53,7 +63,7 @@ class TaskEditorPage:
 			due_date="",
 		)
 		self._field_index = 0
-		self._input_mode: Literal["nav", "input"] = "input"
+		self._input_mode: Literal["nav", "input"] = "nav"
 		self._error: str | None = None
 
 	def on_enter(self, ctx: PageContext) -> None:
@@ -73,7 +83,17 @@ class TaskEditorPage:
 	def status_text(self) -> str:
 		if self._error:
 			return self._error
-		return "Enter save — j/k move field — type to edit — Esc or q back"
+		if self._task_ref is not None:
+			if self._field_index == len(_FIELDS):
+				return "Enter remove task (local) — j/k move — q or Esc back"
+			if self._field_index == len(_FIELDS) + 1:
+				return "Enter remove task (remote & local) — j/k move — q or Esc back"
+		if self._input_mode == "input":
+			field = _FIELDS[self._field_index]
+			if field in ("status", "priority"):
+				return "j/k change value — Enter save — Esc stop editing — q back"
+			return "Type to edit — Enter save — Esc stop editing — q back"
+		return "Enter edit field — j/k move field — q or Esc back"
 
 	def draw(self, stdscr: int, height: int, width: int) -> None:
 		del stdscr
@@ -93,12 +113,17 @@ class TaskEditorPage:
 			f"Assignee: {self._state.assignee}",
 			f"Due date (ISO): {self._state.due_date}",
 		]
+		if self._task_ref is not None:
+			rows.append("Remove task")
+			rows.append("Remove task (REMOTE & LOCAL)")
 		for index, text in enumerate(rows):
 			if index + 1 >= height:
 				break
-			attr = theme.normal
+			attr = theme.unstaged if self._task_ref is not None and index >= len(_FIELDS) else theme.normal
 			if index == self._field_index:
 				attr = focus_attr(attr)
+				if self._input_mode == "input" and index < len(_FIELDS):
+					attr |= A_BOLD
 			draw_line(index + 1, 0, text[:width], width, attr)
 
 	def handle_key(self, key: int) -> PageResult:
@@ -114,13 +139,11 @@ class TaskEditorPage:
 		if self._error is not None:
 			self._error = None
 
-		field = _FIELDS[self._field_index]
+		field = _FIELDS[self._field_index] if self._field_index < len(_FIELDS) else "title"
 
-		# Input mode: edit text fields, cycle status/priority; j/k/h/l are text in text fields.
 		if self._input_mode == "input":
 			if field in ("title", "description", "assignee", "due_date"):
 				if key in (KEY_UP, KEY_DOWN):
-					# Move between fields with arrows even while in input mode.
 					if key == KEY_UP:
 						self._field_index = max(0, self._field_index - 1)
 					else:
@@ -130,22 +153,35 @@ class TaskEditorPage:
 					return self._save()
 				return self._edit_text_field(field, key)
 			if field == "status":
+				if key in (KEY_ENTER, 10, 13):
+					return self._save()
 				self._cycle_status(key)
 				return PageResult()
 			if field == "priority":
+				if key in (KEY_ENTER, 10, 13):
+					return self._save()
 				self._cycle_priority(key)
 				return PageResult()
 			return PageResult()
 
-		# Nav mode: j/k and arrows move between fields; Enter saves.
 		if key in (KEY_UP, ord("k"), ord("K")):
 			self._field_index = max(0, self._field_index - 1)
 			return PageResult()
 		if key in (KEY_DOWN, ord("j"), ord("J")):
-			self._field_index = min(len(_FIELDS) - 1, self._field_index + 1)
+			max_index = (len(_FIELDS) + 1) if self._task_ref is not None else len(_FIELDS) - 1
+			self._field_index = min(max_index, self._field_index + 1)
 			return PageResult()
 		if key in (KEY_ENTER, 10, 13):
-			return self._save()
+			if self._task_ref is not None:
+				if self._field_index == len(_FIELDS):
+					return self._delete_local()
+				if self._field_index == len(_FIELDS) + 1:
+					return self._delete_remote_local()
+			self._input_mode = "input"
+			return PageResult()
+		if key in (KEY_BACKSPACE, 127, 8) and field in ("title", "description", "assignee", "due_date"):
+			self._input_mode = "input"
+			return self._edit_text_field(field, key)
 		return PageResult()
 
 	def _edit_text_field(self, field: _FieldName, key: int) -> PageResult:
@@ -235,6 +271,32 @@ class TaskEditorPage:
 		task.write(ctx.repo)
 		return PageResult(action=PageAction.POP)
 
+	def _delete_local(self) -> PageResult:
+		ctx = self._ctx
+		if ctx is None or self._task_ref is None:
+			return PageResult(action=PageAction.POP)
+
+		delete_task_local(ctx.repo, self._task_ref)
+
+		return PageResult(action=PageAction.POP)
+
+	def _delete_remote_local(self) -> PageResult:
+		ctx = self._ctx
+		if ctx is None or self._task_ref is None:
+			return PageResult(action=PageAction.POP)
+
+		remote_name = _default_remote_name(ctx)
+
+		if remote_name is not None:
+			delete_task_remote(ctx.repo, remote_name, self._task_ref)
+
+		delete_task_local(ctx.repo, self._task_ref)
+
+		if remote_name is not None:
+			push_board_tags(ctx.repo, remote_name, self._board_name)
+
+		return PageResult(action=PageAction.POP)
+
 
 def _replace_state_field(state: _EditorState, field: _FieldName, value: str) -> _EditorState:
 	if field == "title":
@@ -319,3 +381,12 @@ def _create_task(ctx: PageContext, board_name: str, state: _EditorState, due_dt:
 	board.tasks = [*(getattr(board, "tasks", []) or []), str(task_oid)]
 	board.update_message()
 	board.write(ctx.repo)
+
+
+def _default_remote_name(ctx: PageContext) -> str | None:
+	names = list(ctx.repo.remotes.names())
+	if not names:
+		return None
+	if "origin" in names:
+		return "origin"
+	return names[0]
diff --git a/pygittools/tui/tasks_list.py b/pygittools/tui/tasks_list.py
index c6bac12..4facd8a 100644
--- a/pygittools/tui/tasks_list.py
+++ b/pygittools/tui/tasks_list.py
@@ -7,6 +7,7 @@ from typing import Literal
 
 from pygit2 import Repository
 
+from pygittools.tags_sync import format_sync_result, sync_board_tags
 from pygittools.tasks_query import BOARD_STATUS_ORDER, BoardView, get_board_tasks_grouped, list_boards
 from pygittools.tui.draw import draw_line
 from pygittools.tui.git_colors import current_theme, focus_attr
@@ -135,6 +136,20 @@ class TasksBoardList:
 			attr = _row_attr(row, focused=focused, highlight=highlight)
 			draw_line(screen_row, 0, row.label, width, attr)
 
+	def sync_with_default_remote(self, repo: Repository) -> None:
+		if not repo.remotes:
+			self._error = "No remotes configured for task sync"
+			return
+		remote_name = "origin" if "origin" in repo.remotes.names() else next(iter(repo.remotes.names()))
+		board_name = self._board_name or "Tasks"
+		try:
+			result = sync_board_tags(repo, remote_name, board_name)
+		except (KeyError, RuntimeError, ValueError) as exc:
+			self._error = str(exc)
+			return
+		self._error = format_sync_result(result)
+		self.refresh(repo)
+
 	def handle_nav_key(self, key: int, repo: Repository) -> PageResult | None:
 		if key == KEY_RESIZE:
 			return None
