Slice 3: activity feed and active project (SSE + MCP tools)

Add internal/activity (thread-safe active project + bounded event feed with subscriber fan-out). Service exposes active-project/activity methods and takes the feed. New MCP tools get_active_project/set_active_project/get_activity and HTTP endpoints GET/POST /api/active-project, /api/activity, and /events (SSE). New <activity-feed> component updates live via EventSource; <repo-list> sets the active project on selection. Verified end-to-end in the running app: user actions push live events and set the active project (actor=user), all readable by Claude over MCP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 08:16:42 -04:00
parent d3abd4416e
commit 65daedc902
12 changed files with 579 additions and 11 deletions
+9
View File
@@ -53,6 +53,15 @@
most recent commits.
</p>
<h2>Active project &amp; activity</h2>
<p>
Clicking a repository also makes it your <strong>active project</strong>
the one you're currently focused on — shown in the activity panel at the
bottom. That panel also lists recent actions by both you and Claude, updating
live. When GitManager is connected to Claude, Claude can see your active
project and this activity, so you stay on the same page.
</p>
<h2>Background refresh</h2>
<p>
The dashboard refreshes on its own. By default it does <em>not</em> reach
+9 -5
View File
@@ -9,6 +9,7 @@
(AGENT.md §1.1). Each fetches its own data on connect. -->
<script type="module" src="/components/repo-list/repo-list.js"></script>
<script type="module" src="/components/repo-detail/repo-detail.js"></script>
<script type="module" src="/components/activity-feed/activity-feed.js"></script>
<style>
header {
display: flex;
@@ -22,14 +23,14 @@
header nav { margin-left: auto; }
/* Repo list docks LEFT, detail panel docks RIGHT by default (AGENT.md §4).
A real dockable layout is layered on later; this is the static default. */
main {
main { padding: 20px; display: flex; flex-direction: column; gap: 16px; }
.cols {
display: grid;
grid-template-columns: minmax(280px, 360px) 1fr;
gap: 16px;
padding: 20px;
align-items: start;
}
@media (max-width: 720px) { main { grid-template-columns: 1fr; } }
@media (max-width: 720px) { .cols { grid-template-columns: 1fr; } }
</style>
</head>
<body>
@@ -39,8 +40,11 @@
<nav><a href="/help">Help</a></nav>
</header>
<main>
<repo-list></repo-list>
<repo-detail></repo-detail>
<div class="cols">
<repo-list></repo-list>
<repo-detail></repo-detail>
</div>
<activity-feed></activity-feed>
</main>
</body>
</html>