# Changelog Append-only running history of all changes (AGENT.md §9.1). Newest last. ## 2026-09-19 — Project scaffold - **What:** Initial runnable skeleton for the GitManager multi-repo dashboard. Added the Go backend (`cmd/server/main.go` + `internal/{config,logging,git,repos,render}`), the Echo HTTP server with `/`, `/help`, `/healthz`, and `/api/repos`, a read-only repo scanner that discovers repositories under `GIT_REPO_ROOTS` and keeps an in-memory index, the `` web component, shared design tokens (`web/static/app.css`), page shells (`web/templates/{index,help}.html`), and the dev tooling: `Dockerfile` (build/dev/runtime stages), `docker-compose.yml`, `.air.toml`, `.env.example`, `.gitignore`, `go.mod`. - **Why:** Stand up the architecture defined in AGENT.md so feature work can begin. - **Affects:** whole repo (foundation); `components/repo-list`. ## 2026-09-19 — Repo detail panel - **What:** Added the `` component (right dock) that listens for `repo:select` and shows a repo's remotes, local branches (current + upstream), and 20 most recent commits. Backed by a new `GET /api/repo?path=` endpoint (restricted to indexed repos) and new read-only git readers (`LocalBranches`, `RecentCommits`, `RemoteDetails`) plus `repos.BuildDetail` and `Index.Get`. `` now highlights the selected repo; `index.html` lays the two panels out left/right; help page documents the detail view. - **Why:** Make the dashboard drill into a single repository (the detail half of the list+detail default in AGENT.md §4). - **Affects:** `components/repo-detail`, `components/repo-list`, `internal/git`, `internal/repos`, `cmd/server`, `web/templates`. ### Notes to confirm (from AGENT.md §11) - **Go module path** is the placeholder `gitmanager`; change it if this gets a canonical import path (e.g. a GitHub URL). - All items in AGENT.md §11 (discovery strategy, background fetch, forge providers, listen address, container credentials) remain open. ## 2026-09-19 — Redefine the app as a two-way Claude companion (contract only) - **What:** Updated AGENT.md to make the Claude integration the defining pillar, no code yet. §0 now states the two-way purpose (Claude↔app) and the non-expert, GUI-first goal; added law §1.7 (one service layer behind both the GUI and the MCP server); stack table gained MCP server (Go SDK over Streamable HTTP at `/mcp`), SSE (app→browser), and flipped forge to Gitea-first read+write; layout added `internal/{service,mcp,activity}`; §6 added the right-click plain-language command vocabulary; **§8 rewritten** into "Claude integration" (8.1 MCP server, 8.2 activity feed + active project, 8.3 graceful project handoff, 8.4 forge read+write with "Merge & clean up"); §10 step 4 and §11 updated (three decisions resolved, new open items). `.env.example` now documents `GITEA_TOKEN` (read+write scope). - **Why:** Thomas described the real vision — the app should act as an extension of Claude: usable like an MCP by Claude, notifying Claude of in-app actions to stay in sync, cooperative project handoff when he's interrupted, plain-language right-click commands for non-experts, and one-click "merge & clean up" so PRs stop cluttering repos. Decisions locked: cooperative pull-first handoff; Gitea writes enabled (confirmed per §1.4); MCP over HTTP `/mcp`. - **Affects:** `AGENT.md`, `.env.example` (architecture/contract only — no code). ## 2026-09-19 — Service layer + MCP server (Claude integration, read tools) - **What:** Slice 1 — extracted `internal/service`, the one capability layer both the HTTP API and the MCP server call (§1.7); the `/api/repos` and `/api/repo` handlers now route through it. Slice 2 — added `internal/mcp`: an MCP server (`github.com/modelcontextprotocol/go-sdk` v1.8.0) served over Streamable HTTP at `/mcp`, with read tools `list_repos` and `get_repo` as thin adapters over the service. Added a round-trip test (`internal/mcp/mcp_test.go`) using a real temp git repo + the in-memory MCP transport. Verified the HTTP `/mcp` handshake locally and in Docker. - **Why:** First step of the two-way Claude integration (AGENT.md §8.1) — prove Claude can connect to the app over MCP before building deeper features on it. - **Affects:** `internal/service` (new), `internal/mcp` (new), `cmd/server/main.go`, `go.mod`/`go.sum`, `.air.toml`. - **Gotcha:** Docker-on-Windows bind mounts do NOT deliver filesystem events, so air's watch-based reload silently never fired. Fixed by enabling air polling (`poll = true`, `poll_interval = 500` in `.air.toml`). ## 2026-09-20 — HTTPS for the MCP connector (local TLS via mkcert) - **What:** Added an optional HTTPS listener alongside HTTP. New config `HTTPS_ADDR`, `TLS_CERT_FILE`, `TLS_KEY_FILE`; when set, `cmd/server` starts `e.StartTLS` on the same Echo app (best-effort — a missing cert logs a warning and stays HTTP-only). docker-compose publishes `127.0.0.1:8443` and points the TLS vars at `certs/localhost.pem` (mounted via the existing source mount). `.gitignore` ignores `/certs/`; `.env.example` documents the mkcert steps. - **Why:** Claude Desktop's custom MCP connector only accepts `https://` URLs. Local TLS with an mkcert-trusted cert lets `https://localhost:8443/mcp` work without exposing the unauthenticated app via a public tunnel (AGENT.md §8.1). - **Affects:** `internal/config`, `cmd/server/main.go`, `docker-compose.yml`, `.gitignore`, `.env.example`, `AGENT.md` (§8.1, §11). - **Host setup (user-run):** the local CA install (`mkcert -install`) is a security-settings change performed by the user, not the app. ## 2026-09-20 — Connect Claude Desktop via local stdio bridge (mcp-remote) - **What:** Corrected the Claude Desktop connection method in AGENT.md (§8.1, §11). The GUI "Add custom connector" flow can NOT reach a localhost server — it probes and calls tools from Anthropic's cloud, so `https://127.0.0.1:8443/mcp` fails "couldn't reach the server" even though a local browser reaches it. The working path is a local stdio bridge in `claude_desktop_config.json`: `mcpServers.gitmanager = cmd /c npx -y mcp-remote http://127.0.0.1:8080/mcp`. Added that entry to the user's Claude Desktop config (backup saved alongside). - **Why:** Keep the app localhost-only + unauthenticated (§0) while still letting Claude Desktop drive it. `mcp-remote` runs locally, so it reaches the local endpoint directly — no public exposure, no HTTPS needed for this path. - **Affects:** `AGENT.md` (§8.1, §11); user's `claude_desktop_config.json` (outside the repo). HTTPS/`:8443` from the prior entry stays available but is now optional. ## 2026-09-20 — Slice 3: activity feed + active project (§8.2) - **What:** Added `internal/activity` (thread-safe active project + bounded event feed with subscriber fan-out, mirrored to logs, no datastore). Service gained `ActiveProject`/`SetActiveProject`/`RecordActivity`/`Activity`/`SubscribeActivity` (and `service.New` now takes the feed). New MCP tools `get_active_project`, `set_active_project`, `get_activity` (object-wrapped outputs). New HTTP: `GET/POST /api/active-project`, `GET /api/activity`, and `GET /events` (SSE). New `` component (live via EventSource); `` now sets the active project on selection (a user action). Extended the MCP test to cover the new tools; help page documents the feature. - **Why:** The coordination foundation for the graceful project handoff (§8.3): the app and Claude share one active-project + activity view. User actions are recorded as `actor:user`, Claude's as `actor:claude`, so each side can see what the other did. - **Affects:** `internal/activity` (new), `internal/service`, `internal/mcp` (+test), `cmd/server/main.go`, `components/activity-feed` (new), `components/repo-list`, `web/templates/{index,help}.html`. ## 2026-09-20 — Slice 4: graceful project handoff (§8.3) - **What:** `internal/activity` gained a pending-switch model (`RequestSwitch`/`PendingSwitch`/`AckSwitch`/`CancelSwitch`); `AckSwitch` atomically sets the active project to the requested target and records a `switch-completed` event with Claude's summary. Service methods added. New MCP tools `get_pending_switch` and `ack_switch` (request is user-only — no MCP tool raises it). HTTP: `GET/POST/DELETE /api/switch`. New `` component: "Ask Claude to switch to ", the "waiting for a good stopping point" state with Cancel, and the completion notice; `` also updates the active project on `switch-completed`. Extended the MCP test to cover the full request→ack→clear flow. Help page + AGENT.md §8.3 updated. - **Why:** The headline feature — the user asks Claude to switch projects; Claude finishes to a safe stopping point, then `ack_switch` completes it and the app notifies the user over SSE. The switch is Claude-completed at a checkpoint, never app-forced (§1.4-class rule). - **Affects:** `internal/activity`, `internal/service`, `internal/mcp` (+test), `cmd/server/main.go`, `components/handoff-bar` (new), `components/activity-feed`, `web/templates/{index,help}.html`, `AGENT.md` (§8.3). - **Verified live:** request → "waiting" → cancel, all over SSE with activity logging. The ack/completion path is covered by the test; its live ✅ notice needs the two new MCP tools, which appear after the next Claude Desktop restart.