diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..80fecdf
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,3 @@
+[*.py]
+indent_style = tab
+indent_size = 4
diff --git a/.envrc b/.envrc
index 30d6dbd..9134d80 100644
--- a/.envrc
+++ b/.envrc
@@ -6,3 +6,4 @@ fi
 
 watch_file uv.lock
 watch_file pyproject.toml
+source_env_if_exists .envrc.local
diff --git a/.gitignore b/.gitignore
index 82191d2..126da01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ __pycache__/
 *.egg-info/
 .pygitweb/
 build/
+.envrc.*
diff --git a/pygittools/tasks.py b/pygittools/tasks.py
index 4bd1b34..7d48256 100644
--- a/pygittools/tasks.py
+++ b/pygittools/tasks.py
@@ -75,16 +75,15 @@ def _read_tag_raw(repo: Repository, oid: Oid) -> tuple[Oid, str, str, str]:
 	return (obj.target, obj.name, tagger_str, obj.message)
 
 
-"""
-A Task is an annotated tag (a full tag object, although it will get a ref as well).
-The usual fields of a tag (target, name, tagger) are present, but the "message" is a JSON string.
-All the fields seen below are supported, but arbitrary JSON keys may be added. Text fields are usually Markdown.
-The "name" must be a fully-qualified Git ref name (usually "refs/tags/tasks/<task-id>").
-Because the ODB is immutable, the tag will always point to the latest version of the task.
-"""
-
-
 class Task:
+	"""
+	A Task is an annotated tag (a full tag object, although it will get a ref as well).
+	The usual fields of a tag (target, name, tagger) are present, but the "message" is a JSON string.
+	All the fields seen below are supported, but arbitrary JSON keys may be added. Text fields are usually Markdown.
+	The "name" must be a fully-qualified Git ref name (usually "refs/tags/tasks/<task-id>").
+	Because the ODB is immutable, the tag will always point to the latest version of the task.
+	"""
+
 	class Status(Enum):
 		TODO = "TODO"
 		IN_PROGRESS = "IN_PROGRESS"
@@ -135,13 +134,12 @@ class Task:
 			k: v for k, v in self.__dict__.items() if k not in ["target", "tagger", "name", "message"]
 		})
 
-	"""
-    Write the task to the repository.
-    @param repo: The repository to write to.
-    @return: The OID of the written task.
-    """
-
 	def write(self, repo: Repository) -> Oid:
+		"""
+		Write the task to the repository.
+		@param repo: The repository to write to.
+		@return: The OID of the written task.
+		"""
 		try:
 			obj = repo[self.target]
 			object_type = (getattr(obj, "type_str", None) or "commit").lower()
@@ -214,14 +212,13 @@ def get_task_by_oid(repo: Repository, oid: Oid) -> Task | None:
 	return t
 
 
-"""
-A Comment is an annotated tag (a full tag object) that also gets a ref under refs/tags/comments/.
-The tagger is the author of the comment and the target is the task or parent comment.
-The ref keeps the comment reachable so git gc will not prune it.
-"""
-
-
 class Comment:
+	"""
+	A Comment is an annotated tag (a full tag object) that also gets a ref under refs/tags/comments/.
+	The tagger is the author of the comment and the target is the task or parent comment.
+	The ref keeps the comment reachable so git gc will not prune it.
+	"""
+
 	def __init__(
 		self,
 		target: Oid,  # Task or parent comment OID
@@ -249,13 +246,12 @@ class Comment:
 			k: v for k, v in self.__dict__.items() if k not in ["target", "tagger", "name", "message"]
 		})
 
-	"""
-    Write the comment to the repository.
-    @param repo: The repository to write to.
-    @return: The OID of the written comment.
-    """
-
 	def write(self, repo: Repository) -> Oid:
+		"""
+		Write the comment to the repository.
+		@param repo: The repository to write to.
+		@return: The OID of the written comment.
+		"""
 		try:
 			obj = repo[self.target]
 			object_type = (getattr(obj, "type_str", None) or "commit").lower()
@@ -282,14 +278,13 @@ def get_comment(repo: Repository, oid: Oid) -> Comment:
 	return c
 
 
-"""
-A Board is an annotated tag (a full tag object, although it will get a ref as well).
-The only used field is "message" which is a JSON string.
-The "tasks" field is an array of task OIDs.
-"""
-
-
 class Board:
+	"""
+	A Board is an annotated tag (a full tag object, although it will get a ref as well).
+	The only used field is "message" which is a JSON string.
+	The "tasks" field is an array of task OIDs.
+	"""
+
 	def __init__(
 		self,
 		target: Oid | str,
