emdash-core 0.1.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. emdash_core/__init__.py +3 -0
  2. emdash_core/agent/__init__.py +37 -0
  3. emdash_core/agent/agents.py +225 -0
  4. emdash_core/agent/code_reviewer.py +476 -0
  5. emdash_core/agent/compaction.py +143 -0
  6. emdash_core/agent/context_manager.py +140 -0
  7. emdash_core/agent/events.py +338 -0
  8. emdash_core/agent/handlers.py +224 -0
  9. emdash_core/agent/inprocess_subagent.py +377 -0
  10. emdash_core/agent/mcp/__init__.py +50 -0
  11. emdash_core/agent/mcp/client.py +346 -0
  12. emdash_core/agent/mcp/config.py +302 -0
  13. emdash_core/agent/mcp/manager.py +496 -0
  14. emdash_core/agent/mcp/tool_factory.py +213 -0
  15. emdash_core/agent/prompts/__init__.py +38 -0
  16. emdash_core/agent/prompts/main_agent.py +104 -0
  17. emdash_core/agent/prompts/subagents.py +131 -0
  18. emdash_core/agent/prompts/workflow.py +136 -0
  19. emdash_core/agent/providers/__init__.py +34 -0
  20. emdash_core/agent/providers/base.py +143 -0
  21. emdash_core/agent/providers/factory.py +80 -0
  22. emdash_core/agent/providers/models.py +220 -0
  23. emdash_core/agent/providers/openai_provider.py +463 -0
  24. emdash_core/agent/providers/transformers_provider.py +217 -0
  25. emdash_core/agent/research/__init__.py +81 -0
  26. emdash_core/agent/research/agent.py +143 -0
  27. emdash_core/agent/research/controller.py +254 -0
  28. emdash_core/agent/research/critic.py +428 -0
  29. emdash_core/agent/research/macros.py +469 -0
  30. emdash_core/agent/research/planner.py +449 -0
  31. emdash_core/agent/research/researcher.py +436 -0
  32. emdash_core/agent/research/state.py +523 -0
  33. emdash_core/agent/research/synthesizer.py +594 -0
  34. emdash_core/agent/reviewer_profile.py +475 -0
  35. emdash_core/agent/rules.py +123 -0
  36. emdash_core/agent/runner.py +601 -0
  37. emdash_core/agent/session.py +262 -0
  38. emdash_core/agent/spec_schema.py +66 -0
  39. emdash_core/agent/specification.py +479 -0
  40. emdash_core/agent/subagent.py +397 -0
  41. emdash_core/agent/subagent_prompts.py +13 -0
  42. emdash_core/agent/toolkit.py +482 -0
  43. emdash_core/agent/toolkits/__init__.py +64 -0
  44. emdash_core/agent/toolkits/base.py +96 -0
  45. emdash_core/agent/toolkits/explore.py +47 -0
  46. emdash_core/agent/toolkits/plan.py +55 -0
  47. emdash_core/agent/tools/__init__.py +141 -0
  48. emdash_core/agent/tools/analytics.py +436 -0
  49. emdash_core/agent/tools/base.py +131 -0
  50. emdash_core/agent/tools/coding.py +484 -0
  51. emdash_core/agent/tools/github_mcp.py +592 -0
  52. emdash_core/agent/tools/history.py +13 -0
  53. emdash_core/agent/tools/modes.py +153 -0
  54. emdash_core/agent/tools/plan.py +206 -0
  55. emdash_core/agent/tools/plan_write.py +135 -0
  56. emdash_core/agent/tools/search.py +412 -0
  57. emdash_core/agent/tools/spec.py +341 -0
  58. emdash_core/agent/tools/task.py +262 -0
  59. emdash_core/agent/tools/task_output.py +204 -0
  60. emdash_core/agent/tools/tasks.py +454 -0
  61. emdash_core/agent/tools/traversal.py +588 -0
  62. emdash_core/agent/tools/web.py +179 -0
  63. emdash_core/analytics/__init__.py +5 -0
  64. emdash_core/analytics/engine.py +1286 -0
  65. emdash_core/api/__init__.py +5 -0
  66. emdash_core/api/agent.py +308 -0
  67. emdash_core/api/agents.py +154 -0
  68. emdash_core/api/analyze.py +264 -0
  69. emdash_core/api/auth.py +173 -0
  70. emdash_core/api/context.py +77 -0
  71. emdash_core/api/db.py +121 -0
  72. emdash_core/api/embed.py +131 -0
  73. emdash_core/api/feature.py +143 -0
  74. emdash_core/api/health.py +93 -0
  75. emdash_core/api/index.py +162 -0
  76. emdash_core/api/plan.py +110 -0
  77. emdash_core/api/projectmd.py +210 -0
  78. emdash_core/api/query.py +320 -0
  79. emdash_core/api/research.py +122 -0
  80. emdash_core/api/review.py +161 -0
  81. emdash_core/api/router.py +76 -0
  82. emdash_core/api/rules.py +116 -0
  83. emdash_core/api/search.py +119 -0
  84. emdash_core/api/spec.py +99 -0
  85. emdash_core/api/swarm.py +223 -0
  86. emdash_core/api/tasks.py +109 -0
  87. emdash_core/api/team.py +120 -0
  88. emdash_core/auth/__init__.py +17 -0
  89. emdash_core/auth/github.py +389 -0
  90. emdash_core/config.py +74 -0
  91. emdash_core/context/__init__.py +52 -0
  92. emdash_core/context/models.py +50 -0
  93. emdash_core/context/providers/__init__.py +11 -0
  94. emdash_core/context/providers/base.py +74 -0
  95. emdash_core/context/providers/explored_areas.py +183 -0
  96. emdash_core/context/providers/touched_areas.py +360 -0
  97. emdash_core/context/registry.py +73 -0
  98. emdash_core/context/reranker.py +199 -0
  99. emdash_core/context/service.py +260 -0
  100. emdash_core/context/session.py +352 -0
  101. emdash_core/core/__init__.py +104 -0
  102. emdash_core/core/config.py +454 -0
  103. emdash_core/core/exceptions.py +55 -0
  104. emdash_core/core/models.py +265 -0
  105. emdash_core/core/review_config.py +57 -0
  106. emdash_core/db/__init__.py +67 -0
  107. emdash_core/db/auth.py +134 -0
  108. emdash_core/db/models.py +91 -0
  109. emdash_core/db/provider.py +222 -0
  110. emdash_core/db/providers/__init__.py +5 -0
  111. emdash_core/db/providers/supabase.py +452 -0
  112. emdash_core/embeddings/__init__.py +24 -0
  113. emdash_core/embeddings/indexer.py +534 -0
  114. emdash_core/embeddings/models.py +192 -0
  115. emdash_core/embeddings/providers/__init__.py +7 -0
  116. emdash_core/embeddings/providers/base.py +112 -0
  117. emdash_core/embeddings/providers/fireworks.py +141 -0
  118. emdash_core/embeddings/providers/openai.py +104 -0
  119. emdash_core/embeddings/registry.py +146 -0
  120. emdash_core/embeddings/service.py +215 -0
  121. emdash_core/graph/__init__.py +26 -0
  122. emdash_core/graph/builder.py +134 -0
  123. emdash_core/graph/connection.py +692 -0
  124. emdash_core/graph/schema.py +416 -0
  125. emdash_core/graph/writer.py +667 -0
  126. emdash_core/ingestion/__init__.py +7 -0
  127. emdash_core/ingestion/change_detector.py +150 -0
  128. emdash_core/ingestion/git/__init__.py +5 -0
  129. emdash_core/ingestion/git/commit_analyzer.py +196 -0
  130. emdash_core/ingestion/github/__init__.py +6 -0
  131. emdash_core/ingestion/github/pr_fetcher.py +296 -0
  132. emdash_core/ingestion/github/task_extractor.py +100 -0
  133. emdash_core/ingestion/orchestrator.py +540 -0
  134. emdash_core/ingestion/parsers/__init__.py +10 -0
  135. emdash_core/ingestion/parsers/base_parser.py +66 -0
  136. emdash_core/ingestion/parsers/call_graph_builder.py +121 -0
  137. emdash_core/ingestion/parsers/class_extractor.py +154 -0
  138. emdash_core/ingestion/parsers/function_extractor.py +202 -0
  139. emdash_core/ingestion/parsers/import_analyzer.py +119 -0
  140. emdash_core/ingestion/parsers/python_parser.py +123 -0
  141. emdash_core/ingestion/parsers/registry.py +72 -0
  142. emdash_core/ingestion/parsers/ts_ast_parser.js +313 -0
  143. emdash_core/ingestion/parsers/typescript_parser.py +278 -0
  144. emdash_core/ingestion/repository.py +346 -0
  145. emdash_core/models/__init__.py +38 -0
  146. emdash_core/models/agent.py +68 -0
  147. emdash_core/models/index.py +77 -0
  148. emdash_core/models/query.py +113 -0
  149. emdash_core/planning/__init__.py +7 -0
  150. emdash_core/planning/agent_api.py +413 -0
  151. emdash_core/planning/context_builder.py +265 -0
  152. emdash_core/planning/feature_context.py +232 -0
  153. emdash_core/planning/feature_expander.py +646 -0
  154. emdash_core/planning/llm_explainer.py +198 -0
  155. emdash_core/planning/similarity.py +509 -0
  156. emdash_core/planning/team_focus.py +821 -0
  157. emdash_core/server.py +153 -0
  158. emdash_core/sse/__init__.py +5 -0
  159. emdash_core/sse/stream.py +196 -0
  160. emdash_core/swarm/__init__.py +17 -0
  161. emdash_core/swarm/merge_agent.py +383 -0
  162. emdash_core/swarm/session_manager.py +274 -0
  163. emdash_core/swarm/swarm_runner.py +226 -0
  164. emdash_core/swarm/task_definition.py +137 -0
  165. emdash_core/swarm/worker_spawner.py +319 -0
  166. emdash_core/swarm/worktree_manager.py +278 -0
  167. emdash_core/templates/__init__.py +10 -0
  168. emdash_core/templates/defaults/agent-builder.md.template +82 -0
  169. emdash_core/templates/defaults/focus.md.template +115 -0
  170. emdash_core/templates/defaults/pr-review-enhanced.md.template +309 -0
  171. emdash_core/templates/defaults/pr-review.md.template +80 -0
  172. emdash_core/templates/defaults/project.md.template +85 -0
  173. emdash_core/templates/defaults/research_critic.md.template +112 -0
  174. emdash_core/templates/defaults/research_planner.md.template +85 -0
  175. emdash_core/templates/defaults/research_synthesizer.md.template +128 -0
  176. emdash_core/templates/defaults/reviewer.md.template +81 -0
  177. emdash_core/templates/defaults/spec.md.template +41 -0
  178. emdash_core/templates/defaults/tasks.md.template +78 -0
  179. emdash_core/templates/loader.py +296 -0
  180. emdash_core/utils/__init__.py +45 -0
  181. emdash_core/utils/git.py +84 -0
  182. emdash_core/utils/image.py +502 -0
  183. emdash_core/utils/logger.py +51 -0
  184. emdash_core-0.1.7.dist-info/METADATA +35 -0
  185. emdash_core-0.1.7.dist-info/RECORD +187 -0
  186. emdash_core-0.1.7.dist-info/WHEEL +4 -0
  187. emdash_core-0.1.7.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,278 @@
1
+ """Git worktree management for parallel agent execution."""
2
+
3
+ import re
4
+ import shutil
5
+ import subprocess
6
+ from dataclasses import dataclass
7
+ from datetime import datetime
8
+ from pathlib import Path
9
+ from typing import Optional
10
+
11
+ from git import Repo
12
+
13
+ from ..utils.logger import log
14
+
15
+
16
+ @dataclass
17
+ class WorktreeInfo:
18
+ """Information about a created worktree."""
19
+ path: Path
20
+ branch: str
21
+ base_branch: str
22
+ task_slug: str
23
+ created_at: str
24
+ status: str # pending, active, completed, failed
25
+
26
+
27
+ class WorktreeError(Exception):
28
+ """Error during worktree operations."""
29
+ pass
30
+
31
+
32
+ class WorktreeManager:
33
+ """Manages Git worktrees for parallel agent execution.
34
+
35
+ Creates isolated worktrees under .emdash-worktrees/{task-slug}/
36
+ with unique branches for each parallel task.
37
+
38
+ Example:
39
+ manager = WorktreeManager(repo_root=Path("."))
40
+
41
+ # Create worktree for a task
42
+ info = manager.create_worktree("add-user-auth", base_branch="main")
43
+ # -> .emdash-worktrees/add-user-auth/
44
+ # -> branch: emdash/task-add-user-auth
45
+
46
+ # Clean up when done
47
+ manager.remove_worktree("add-user-auth")
48
+ """
49
+
50
+ WORKTREE_DIR = ".emdash-worktrees"
51
+ BRANCH_PREFIX = "emdash/task-"
52
+
53
+ def __init__(self, repo_root: Path):
54
+ """Initialize worktree manager.
55
+
56
+ Args:
57
+ repo_root: Root of the main git repository
58
+ """
59
+ self.repo_root = repo_root.resolve()
60
+ self.repo = Repo(self.repo_root)
61
+ self.worktrees_base = self.repo_root / self.WORKTREE_DIR
62
+
63
+ def slugify(self, text: str) -> str:
64
+ """Convert text to URL-safe slug."""
65
+ text = text.lower().strip()
66
+ text = re.sub(r"[^\w\s-]", "", text)
67
+ text = re.sub(r"[-\s]+", "-", text)
68
+ return text[:50]
69
+
70
+ def _get_default_branch(self) -> str:
71
+ """Get the default branch name for this repo.
72
+
73
+ Tries HEAD, then common names (main, master), then first available branch.
74
+ """
75
+ # Try current HEAD branch
76
+ try:
77
+ if not self.repo.head.is_detached:
78
+ return self.repo.active_branch.name
79
+ except Exception:
80
+ pass
81
+
82
+ # Try common branch names
83
+ branch_names = [h.name for h in self.repo.heads]
84
+ for name in ["main", "master", "develop"]:
85
+ if name in branch_names:
86
+ return name
87
+
88
+ # Use first available branch
89
+ if branch_names:
90
+ return branch_names[0]
91
+
92
+ # Fallback to HEAD
93
+ return "HEAD"
94
+
95
+ def create_worktree(
96
+ self,
97
+ task_name: str,
98
+ base_branch: str | None = None,
99
+ force: bool = False,
100
+ ) -> WorktreeInfo:
101
+ """Create a new worktree for a task.
102
+
103
+ Args:
104
+ task_name: Human-readable task name or slug
105
+ base_branch: Branch to base the worktree on (auto-detected if None)
106
+ force: If True, remove existing worktree first
107
+
108
+ Returns:
109
+ WorktreeInfo with worktree details
110
+
111
+ Raises:
112
+ WorktreeError: If worktree creation fails
113
+ """
114
+ slug = self.slugify(task_name)
115
+ worktree_path = self.worktrees_base / slug
116
+ branch_name = f"{self.BRANCH_PREFIX}{slug}"
117
+
118
+ # Auto-detect base branch if not provided
119
+ if base_branch is None:
120
+ base_branch = self._get_default_branch()
121
+ log.debug(f"Using base branch: {base_branch}")
122
+
123
+ # Handle existing worktree
124
+ if worktree_path.exists():
125
+ if force:
126
+ self.remove_worktree(slug)
127
+ else:
128
+ raise WorktreeError(f"Worktree already exists: {worktree_path}")
129
+
130
+ # Ensure base directory exists
131
+ self.worktrees_base.mkdir(parents=True, exist_ok=True)
132
+
133
+ # Fetch latest if remote exists
134
+ try:
135
+ if self.repo.remotes:
136
+ self.repo.remotes.origin.fetch()
137
+ except Exception:
138
+ pass # No remote or fetch failed, continue with local
139
+
140
+ # Delete branch if it exists (from previous run)
141
+ if branch_name in [h.name for h in self.repo.heads]:
142
+ self.repo.delete_head(branch_name, force=True)
143
+
144
+ # Create worktree with new branch using git command
145
+ cmd = [
146
+ "git", "worktree", "add",
147
+ "-b", branch_name,
148
+ str(worktree_path),
149
+ base_branch,
150
+ ]
151
+ result = subprocess.run(
152
+ cmd,
153
+ cwd=str(self.repo_root),
154
+ capture_output=True,
155
+ text=True,
156
+ )
157
+
158
+ if result.returncode != 0:
159
+ raise WorktreeError(f"Failed to create worktree: {result.stderr}")
160
+
161
+ log.info(f"Created worktree at {worktree_path} on branch {branch_name}")
162
+
163
+ return WorktreeInfo(
164
+ path=worktree_path,
165
+ branch=branch_name,
166
+ base_branch=base_branch,
167
+ task_slug=slug,
168
+ created_at=datetime.now().isoformat(),
169
+ status="pending",
170
+ )
171
+
172
+ def remove_worktree(self, slug_or_path: str | Path) -> bool:
173
+ """Remove a worktree and optionally its branch.
174
+
175
+ Args:
176
+ slug_or_path: Task slug or full worktree path
177
+
178
+ Returns:
179
+ True if removed successfully
180
+ """
181
+ if isinstance(slug_or_path, Path):
182
+ worktree_path = slug_or_path
183
+ slug = worktree_path.name
184
+ else:
185
+ slug = slug_or_path
186
+ worktree_path = self.worktrees_base / slug
187
+
188
+ branch_name = f"{self.BRANCH_PREFIX}{slug}"
189
+
190
+ # Remove worktree
191
+ if worktree_path.exists():
192
+ cmd = ["git", "worktree", "remove", str(worktree_path), "--force"]
193
+ subprocess.run(cmd, cwd=str(self.repo_root), capture_output=True)
194
+
195
+ # If git worktree remove fails, force delete
196
+ if worktree_path.exists():
197
+ shutil.rmtree(worktree_path)
198
+
199
+ # Prune worktree metadata
200
+ subprocess.run(
201
+ ["git", "worktree", "prune"],
202
+ cwd=str(self.repo_root),
203
+ capture_output=True,
204
+ )
205
+
206
+ # Delete the branch
207
+ try:
208
+ if branch_name in [h.name for h in self.repo.heads]:
209
+ self.repo.delete_head(branch_name, force=True)
210
+ except Exception:
211
+ pass # Branch may not exist
212
+
213
+ log.info(f"Removed worktree {slug}")
214
+ return True
215
+
216
+ def list_worktrees(self) -> list[WorktreeInfo]:
217
+ """List all active emdash worktrees."""
218
+ result = subprocess.run(
219
+ ["git", "worktree", "list", "--porcelain"],
220
+ cwd=str(self.repo_root),
221
+ capture_output=True,
222
+ text=True,
223
+ )
224
+
225
+ worktrees = []
226
+ current: dict = {}
227
+
228
+ for line in result.stdout.strip().split("\n"):
229
+ if line.startswith("worktree "):
230
+ current["path"] = Path(line[9:])
231
+ elif line.startswith("branch refs/heads/"):
232
+ current["branch"] = line[18:]
233
+ elif line == "":
234
+ path = current.get("path")
235
+ if path and str(self.worktrees_base) in str(path):
236
+ worktrees.append(WorktreeInfo(
237
+ path=path,
238
+ branch=current.get("branch", ""),
239
+ base_branch="main",
240
+ task_slug=path.name,
241
+ created_at="",
242
+ status="active",
243
+ ))
244
+ current = {}
245
+
246
+ return worktrees
247
+
248
+ def cleanup_all(self) -> int:
249
+ """Remove all emdash worktrees.
250
+
251
+ Returns:
252
+ Number of worktrees removed
253
+ """
254
+ worktrees = self.list_worktrees()
255
+ for wt in worktrees:
256
+ self.remove_worktree(wt.task_slug)
257
+
258
+ # Also clean up the base directory
259
+ if self.worktrees_base.exists():
260
+ shutil.rmtree(self.worktrees_base)
261
+
262
+ return len(worktrees)
263
+
264
+ def get_worktree(self, slug: str) -> Optional[WorktreeInfo]:
265
+ """Get info for a specific worktree by slug."""
266
+ worktree_path = self.worktrees_base / slug
267
+ if not worktree_path.exists():
268
+ return None
269
+
270
+ branch_name = f"{self.BRANCH_PREFIX}{slug}"
271
+ return WorktreeInfo(
272
+ path=worktree_path,
273
+ branch=branch_name,
274
+ base_branch="main",
275
+ task_slug=slug,
276
+ created_at="",
277
+ status="active",
278
+ )
@@ -0,0 +1,10 @@
1
+ """Template loading utilities for emdash."""
2
+
3
+ from .loader import (
4
+ load_template,
5
+ load_template_for_agent,
6
+ get_template_path,
7
+ list_templates,
8
+ )
9
+
10
+ __all__ = ["load_template", "load_template_for_agent", "get_template_path", "list_templates"]
@@ -0,0 +1,82 @@
1
+ # Agent Builder Rules
2
+
3
+ > How we create specialized AI agents for this codebase.
4
+
5
+ ## Purpose
6
+
7
+ The agent-builder creates custom AGENTS.md profiles by analyzing the codebase, PRs, and review patterns to capture institutional knowledge.
8
+
9
+ ## What to Gather
10
+
11
+ 1. **Related PRs** - Find PRs related to the agent's purpose using keyword search
12
+ 2. **Review Patterns** - What reviewers consistently care about (from APPROVED reviews)
13
+ 3. **Anti-Patterns** - Things from REQUEST_CHANGES reviews that should be avoided
14
+ 4. **Domain Experts** - Authors and reviewers with most activity in the area
15
+ 5. **Code Communities** - Clustered areas of related code in the graph
16
+ 6. **Entry Points** - Key files and functions relevant to the purpose
17
+
18
+ ## AGENTS.md Format
19
+
20
+ The output should be Claude Code CLAUDE.md compatible:
21
+
22
+ ```markdown
23
+ # <agent-name>
24
+
25
+ ## Purpose
26
+ Single paragraph defining what this agent does and specializes in.
27
+
28
+ ## Knowledge Context
29
+ ### Code Areas
30
+ - Community descriptions from graph analysis
31
+
32
+ ### Key Files
33
+ - List of relevant file paths
34
+
35
+ ## Hints
36
+ 1. Best practice from approved reviews
37
+ 2. Specific, actionable advice (not generic)
38
+ ...
39
+
40
+ ## Things to Avoid
41
+ - (PR #N, @reviewer) Feedback from CHANGES_REQUESTED reviews
42
+ ...
43
+
44
+ ## Related PRs
45
+ - **PR #N**: Title (by @author)
46
+ ...
47
+
48
+ ## Domain Experts
49
+ - @username (N PRs in this area)
50
+ ...
51
+
52
+ ## MCP Tools
53
+ Reference to mcp.json tools.
54
+ ```
55
+
56
+ ## Exploration Strategy
57
+
58
+ 1. Start with semantic search for the agent's purpose
59
+ 2. Use github_search_prs to find related PRs
60
+ 3. For top PRs, extract review comments with github_pr_details
61
+ 4. Find communities that contain the relevant code
62
+ 5. Identify top contributors from PR authors
63
+
64
+ ## Hint Quality Guidelines
65
+
66
+ Good hints are:
67
+ - Specific to this codebase (reference actual patterns)
68
+ - Actionable (tell the agent what TO DO)
69
+ - Derived from real review feedback
70
+ - Concise (1-2 sentences each)
71
+
72
+ Bad hints:
73
+ - Generic advice ("write good tests")
74
+ - Vague guidance ("follow best practices")
75
+ - Not backed by PR evidence
76
+
77
+ ## Things to Avoid
78
+
79
+ - Generic hints that apply to any project
80
+ - Listing every file touched (focus on patterns)
81
+ - Ignoring negative feedback (REQUEST_CHANGES are valuable)
82
+ - Creating duplicate entries
@@ -0,0 +1,115 @@
1
+ # Team Focus Analysis Template
2
+
3
+ > How we summarize team activity and work-in-progress for stakeholders.
4
+
5
+ ## Purpose
6
+
7
+ The Team Focus report gives engineering managers and leads a quick understanding of:
8
+ - What the team is actively building
9
+ - Where technical effort is concentrated
10
+ - Who is working on what
11
+ - Patterns and risks worth attention
12
+
13
+ ## Required Sections
14
+
15
+ ### 1. Executive Summary
16
+
17
+ 2-3 sentences capturing the main thrust of team activity. Should answer:
18
+ - What is the primary focus area?
19
+ - What secondary work is happening?
20
+ - What's the overall picture?
21
+
22
+ **Example:**
23
+ > The team is focused on **AI-driven code generation improvements**, with primary efforts in prompt engineering and content handling. Secondary work involves test infrastructure modernization and bug fixes.
24
+
25
+ ### 2. Work Streams
26
+
27
+ Group related work by theme. For each stream:
28
+ - **Name the stream** with activity percentage
29
+ - **List hot files** being modified
30
+ - **Explain what's being built** using function/class names
31
+ - **Why it matters** (business/technical impact)
32
+ - **How it fits together** (show call flow if available)
33
+
34
+ Use code blocks for call graphs:
35
+ ```
36
+ FunctionA()
37
+ → calls FunctionB()
38
+ → returns to FunctionC()
39
+ ```
40
+
41
+ ### 3. PR Analysis
42
+
43
+ A table showing recent PRs with technical context:
44
+
45
+ | PR | Author | Code Changes | What It Does |
46
+ |----|--------|--------------|--------------|
47
+ | [PR #123](link) | [@author](link) | `file.ts` | Description of change |
48
+
49
+ **Requirements:**
50
+ - PRs MUST be linked: `[PR #123](https://github.com/owner/repo/pull/123)`
51
+ - Authors MUST be linked: `[@username](https://github.com/username)`
52
+ - Describe WHAT the code does, not just which files changed
53
+
54
+ ### 4. Key Contributors
55
+
56
+ A table showing who is working on what:
57
+
58
+ | Contributor | Commits | Technical Focus | Key PRs |
59
+ |-------------|---------|-----------------|---------|
60
+ | [@name](link) | N | Description of focus area | #PR1, #PR2 |
61
+
62
+ **Requirements:**
63
+ - Contributors MUST be linked to their GitHub profile
64
+ - Describe their technical focus area, not just file paths
65
+
66
+ ### 5. Technical Insights
67
+
68
+ Split into positive patterns and areas of attention:
69
+
70
+ #### Positive Patterns
71
+ - What's working well?
72
+ - Good architectural decisions?
73
+ - Effective patterns emerging?
74
+
75
+ #### Areas of Attention
76
+ - Risks or concerns?
77
+ - Large changes with missing context?
78
+ - Churn or instability patterns?
79
+
80
+ #### Recommendations
81
+ - Specific, actionable suggestions
82
+ - Reference specific PRs or patterns
83
+
84
+ ## Link Formatting (REQUIRED)
85
+
86
+ **All PRs and contributors must be clickable links:**
87
+
88
+ - PRs: `[PR #123](https://github.com/owner/repo/pull/123)`
89
+ - Contributors: `[@username](https://github.com/username)`
90
+
91
+ The GitHub repository URL will be provided in the data. Use it to construct proper links.
92
+
93
+ ## Writing Style
94
+
95
+ - Be specific: name functions, classes, and files
96
+ - Explain WHAT is being built, not just WHERE files are changing
97
+ - Use docstrings and code context to understand purpose
98
+ - Write for an engineering manager audience
99
+ - No vague statements like "improvements to X directory"
100
+ - Use tables for structured data (PRs, contributors)
101
+ - Use code blocks for call graphs and technical flows
102
+
103
+ ## What to Avoid
104
+
105
+ - Generic descriptions ("working on the codebase")
106
+ - Directory-only references without file specifics
107
+ - Missing links for PRs and contributors
108
+ - Unexplained technical terms
109
+ - Skipping the insights section
110
+
111
+
112
+
113
+
114
+
115
+