Redefine contract: two-way Claude companion (MCP + handoff + forge writes)
AGENT.md now makes the Claude integration the defining pillar: law 1.7 (one service layer behind GUI + MCP), MCP server over Streamable HTTP at /mcp, SSE app->browser, Gitea-first read+write forge, right-click command vocabulary, and rewritten section 8 (MCP server, activity feed, graceful project handoff, merge & clean up). No code yet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+7
-2
@@ -44,7 +44,12 @@ APP_ENV=dev
|
|||||||
# Optional: also append structured logs to this file. Leave empty to disable.
|
# Optional: also append structured logs to this file. Leave empty to disable.
|
||||||
LOG_FILE=
|
LOG_FILE=
|
||||||
|
|
||||||
# --- Forge integration — OPTIONAL, read-only, token-gated (AGENT.md §8) -----
|
# --- Forge integration — token-gated, READ + WRITE (AGENT.md §8.4) ----------
|
||||||
# With no token the feature is simply absent; the rest of the app is unaffected.
|
# The primary host is a self-hosted Gitea/Forgejo (git.nilles.net). With no
|
||||||
|
# token the forge features are simply absent; the rest of the app is unaffected.
|
||||||
|
# Writes (merge PR + delete branch, for "Merge & clean up") are each confirmed
|
||||||
|
# per AGENT.md §1.4. The token needs repo read + PR write + branch delete scope.
|
||||||
|
GITEA_TOKEN=
|
||||||
|
# Later providers, behind the same interface (unused for now):
|
||||||
GITHUB_TOKEN=
|
GITHUB_TOKEN=
|
||||||
GITLAB_TOKEN=
|
GITLAB_TOKEN=
|
||||||
|
|||||||
@@ -22,6 +22,23 @@ dockable UI panels and is architected so that host/forge integrations
|
|||||||
(GitHub/GitLab pull‑ and merge‑requests) can be attached without touching the
|
(GitHub/GitLab pull‑ and merge‑requests) can be attached without touching the
|
||||||
core.
|
core.
|
||||||
|
|
||||||
|
**The larger purpose — a two‑way companion to Claude.** The dashboard is the
|
||||||
|
visible half. The app is also built to work *with* Claude (used from Claude
|
||||||
|
Desktop / Claude Code) in both directions:
|
||||||
|
- **Claude → app:** the app is an **MCP server** Claude can drive — list/switch
|
||||||
|
repos, run Git operations, and create/merge/clean‑up pull requests — so Claude
|
||||||
|
can manage repositories on the user's behalf.
|
||||||
|
- **App → Claude:** when the user does something in the app (switches project,
|
||||||
|
merges a PR), the app makes that known so Claude stays in sync. The headline
|
||||||
|
case is a **graceful project handoff**: the user switches project in the app,
|
||||||
|
Claude finishes to a safe stopping point, switches, and the user is notified
|
||||||
|
(Section 8).
|
||||||
|
|
||||||
|
The intended user is a developer who does **not** want to memorize Git commands:
|
||||||
|
the GUI offers plain‑language, right‑click commands (Section 6), and Claude can
|
||||||
|
run the same operations through the MCP surface. This is why the app exists — a
|
||||||
|
plain dashboard is only step one.
|
||||||
|
|
||||||
This is a **dev environment first**. It is expected to grow continuously via
|
This is a **dev environment first**. It is expected to grow continuously via
|
||||||
incremental requests ("add X functionality"). Every addition must keep the
|
incremental requests ("add X functionality"). Every addition must keep the
|
||||||
self‑documenting workflow in Section 9 intact.
|
self‑documenting workflow in Section 9 intact.
|
||||||
@@ -143,6 +160,18 @@ The app must be runnable by a new developer with: clone → copy `.env.example`
|
|||||||
`.env` → set the repo roots → `docker compose up`. Document any host‑side
|
`.env` → set the repo roots → `docker compose up`. Document any host‑side
|
||||||
prerequisites (SSH agent, credential helper) in `.env.example` and the help page.
|
prerequisites (SSH agent, credential helper) in `.env.example` and the help page.
|
||||||
|
|
||||||
|
### 1.7 One service layer behind both the GUI and the MCP server
|
||||||
|
|
||||||
|
The web UI and the MCP server (Section 8) are **two front doors to the same
|
||||||
|
capabilities** — never two implementations. Every operation (a Git action, a
|
||||||
|
forge action, switching the active project) lives once in an internal service
|
||||||
|
that goes through the `internal/git` and `internal/forge` boundaries; the Echo
|
||||||
|
HTTP handlers and the MCP tool handlers are **thin adapters** that call it. A
|
||||||
|
capability added for the GUI is therefore available to Claude, and vice versa,
|
||||||
|
and safety rules (§1.4) are enforced in the shared layer so neither front door
|
||||||
|
can bypass them. Do not implement a Git/forge operation directly in an HTTP or
|
||||||
|
MCP handler.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Technology stack (locked unless told otherwise)
|
## 2. Technology stack (locked unless told otherwise)
|
||||||
@@ -154,7 +183,9 @@ prerequisites (SSH agent, credential helper) in `.env.example` and the help page
|
|||||||
| Page rendering | Go server‑rendered HTML shell | Server emits the page + declares web components; components fetch their own data. Use `html/template`. |
|
| Page rendering | Go server‑rendered HTML shell | Server emits the page + declares web components; components fetch their own data. Use `html/template`. |
|
||||||
| Git access | **System `git` via `os/exec`**, wrapped behind an `internal/git` interface | The system binary is authoritative: it honors the user's credential helpers, SSH keys, hooks, and config exactly. Pure‑Go `go-git` may be proposed for cheap read‑only queries, but only behind the same interface and only with approval. |
|
| Git access | **System `git` via `os/exec`**, wrapped behind an `internal/git` interface | The system binary is authoritative: it honors the user's credential helpers, SSH keys, hooks, and config exactly. Pure‑Go `go-git` may be proposed for cheap read‑only queries, but only behind the same interface and only with approval. |
|
||||||
| Repo discovery / index | **In‑memory cache + `github.com/fsnotify/fsnotify`** (optional) | Scan roots for `.git`, hold an index, refresh on interval and/or on filesystem change. |
|
| Repo discovery / index | **In‑memory cache + `github.com/fsnotify/fsnotify`** (optional) | Scan roots for `.git`, hold an index, refresh on interval and/or on filesystem change. |
|
||||||
| Forge integration (PRs/MRs) | **Provider‑abstracted** (`internal/forge`) — GitHub via `github.com/google/go-github`, GitLab via `gitlab.com/gitlab-org/api/client-go` | Optional, read‑only by default, enabled per‑host when a token is configured. See Section 8. |
|
| Forge integration (PRs/MRs) | **Provider‑abstracted** (`internal/forge`) — **Gitea/Forgejo first** via `code.gitea.io/sdk/gitea`; GitHub (`github.com/google/go-github`) / GitLab later behind the same interface | **Read/write**, token‑gated per host. Writes (merge PR, delete branch) are confirmed per §1.4. See Section 8. The primary host is a self‑hosted Gitea (`git.nilles.net`). |
|
||||||
|
| MCP server | **`github.com/modelcontextprotocol/go-sdk`**, served over **Streamable HTTP** at `/mcp` | Claude Desktop connects as a custom connector. Tools are thin adapters over the shared service layer (§1.7). See Section 8. |
|
||||||
|
| Real‑time (app → browser) | **Server‑Sent Events** (`net/http`, stdlib) | Push activity + handoff notifications and live repo updates to the components; replaces list polling over time. |
|
||||||
| Diff rendering | Server produces unified diff from `git`; client renders it in a component | No heavy client diff lib without asking. |
|
| Diff rendering | Server produces unified diff from `git`; client renders it in a component | No heavy client diff lib without asking. |
|
||||||
| Config | **`.env`** via `github.com/joho/godotenv` + a typed config struct | Section 1.5. |
|
| Config | **`.env`** via `github.com/joho/godotenv` + a typed config struct | Section 1.5. |
|
||||||
| Logging | **`log/slog`** → stdout/stderr (structured), optional rotating file sink | See Section 7. No database sink (there is no database). |
|
| Logging | **`log/slog`** → stdout/stderr (structured), optional rotating file sink | See Section 7. No database sink (there is no database). |
|
||||||
@@ -183,7 +214,10 @@ Section 0).
|
|||||||
│ ├── config/ # .env loading, typed config struct
|
│ ├── config/ # .env loading, typed config struct
|
||||||
│ ├── git/ # THE Git boundary: interface + os/exec impl (all git ops)
|
│ ├── git/ # THE Git boundary: interface + os/exec impl (all git ops)
|
||||||
│ ├── repos/ # discovery, in-memory index/cache, refresh scanner worker
|
│ ├── repos/ # discovery, in-memory index/cache, refresh scanner worker
|
||||||
│ ├── forge/ # OPTIONAL seam: GitHub/GitLab PR/MR + remote metadata (provider-abstracted)
|
│ ├── service/ # the ONE service layer both the HTTP API and MCP call (§1.7)
|
||||||
|
│ ├── forge/ # provider-abstracted PR/MR read+write (Gitea first) — Section 8
|
||||||
|
│ ├── mcp/ # MCP server: tool handlers (thin adapters over service) — Section 8
|
||||||
|
│ ├── activity/ # active-project state, activity feed, pending-switch handoff — Section 8
|
||||||
│ ├── logging/ # slog handler → stdout/stderr (+ optional file)
|
│ ├── logging/ # slog handler → stdout/stderr (+ optional file)
|
||||||
│ └── render/ # html/template page shell rendering
|
│ └── render/ # html/template page shell rendering
|
||||||
├── components/ # ALL web components live here (Section 1.2)
|
├── components/ # ALL web components live here (Section 1.2)
|
||||||
@@ -266,6 +300,13 @@ self‑fetching, independent lifecycle, cleanup on disconnect). Expected surface
|
|||||||
- A **repo detail panel** for the selected repo: branches, remotes, recent commit
|
- A **repo detail panel** for the selected repo: branches, remotes, recent commit
|
||||||
log, stashes, tags.
|
log, stashes, tags.
|
||||||
- **Diff / commit views** rendered from server‑produced unified diffs.
|
- **Diff / commit views** rendered from server‑produced unified diffs.
|
||||||
|
- A **right‑click context menu** on any item (repo, branch, PR, stash) is the
|
||||||
|
primary way commands are run. This is the app's reason for being (Section 0):
|
||||||
|
commands read in **plain language** for people who don't memorize Git — e.g.
|
||||||
|
"Get latest" (pull), "Save my work" (commit), "Publish" (push), "Merge &
|
||||||
|
clean up" (merge PR + delete branch). Keep a friendly‑name → Git/forge‑op
|
||||||
|
vocabulary; the same operations are exposed to Claude as MCP tools (Section 8),
|
||||||
|
both calling the one service layer (§1.7).
|
||||||
- An **action surface** for Git operations. Safe operations (fetch, pull,
|
- An **action surface** for Git operations. Safe operations (fetch, pull,
|
||||||
checkout, create branch, stage, commit, push) can proceed on a normal click;
|
checkout, create branch, stage, commit, push) can proceed on a normal click;
|
||||||
**destructive operations follow Section 1.4** (explicit control + confirmation
|
**destructive operations follow Section 1.4** (explicit control + confirmation
|
||||||
@@ -274,8 +315,8 @@ self‑fetching, independent lifecycle, cleanup on disconnect). Expected surface
|
|||||||
`repo:select` event the detail panel listens for) — never shared globals.
|
`repo:select` event the detail panel listens for) — never shared globals.
|
||||||
|
|
||||||
Server endpoints return JSON for the components to self‑fetch; mutating endpoints
|
Server endpoints return JSON for the components to self‑fetch; mutating endpoints
|
||||||
route through `internal/git` and trigger an index refresh for the affected repo so
|
route through the service layer (§1.7) and trigger an index refresh for the
|
||||||
the UI reflects reality without a full rescan.
|
affected repo so the UI reflects reality without a full rescan.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -292,25 +333,84 @@ the UI reflects reality without a full rescan.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Forge integration — OPTIONAL seam (PRs / MRs)
|
## 8. Claude integration (MCP server · activity feed · graceful handoff · forge)
|
||||||
|
|
||||||
Viewing pull/merge requests requires talking to a hosting provider, which is
|
This is the app's defining pillar (Section 0): GitManager works *with* Claude in
|
||||||
**outside** the "Git is the store" core. Keep it isolated and optional.
|
both directions. Everything here goes through the one service layer (§1.7) and
|
||||||
|
obeys the safety rules (§1.4).
|
||||||
|
|
||||||
- Live in `internal/forge` behind a **provider interface** so GitHub, GitLab, and
|
### 8.1 MCP server — Claude drives the app (`internal/mcp`)
|
||||||
others can drop in without touching the dashboard or the Git boundary.
|
|
||||||
- **Read‑only by default**: list open PRs/MRs and their CI/check status for a repo
|
- The app serves an **MCP endpoint over Streamable HTTP at `/mcp`** using
|
||||||
whose remote points at a supported host. Any write action (comment, merge,
|
`github.com/modelcontextprotocol/go-sdk`. Claude Desktop connects to it as a
|
||||||
approve) is a **separate, explicitly‑requested** capability — do not build write
|
**custom connector**. Like the rest of the app it is **localhost‑bound and
|
||||||
paths without asking, and route them through Section 1.4 if destructive.
|
unauthenticated** (Section 0) — do not expose it off‑host without asking.
|
||||||
|
- MCP **tools are thin adapters** over the service layer — no Git/forge logic in
|
||||||
|
the tool handlers (§1.7). Expected tools (grow as features land):
|
||||||
|
- Read: `list_repos`, `get_repo`, `get_active_project`, `get_activity`,
|
||||||
|
`get_pending_switch`, `list_prs`.
|
||||||
|
- Act: `git_status/checkout/commit/push/pull/create_branch`,
|
||||||
|
`create_pr`, `merge_and_cleanup_pr`, `set_active_project`, `ack_switch`.
|
||||||
|
- **Destructive tools carry the §1.4 contract into MCP:** they describe exactly
|
||||||
|
what they will do and default to the safe variant. The confirmation is the
|
||||||
|
human's — surfaced through Claude and/or the app UI — not something the tool
|
||||||
|
silently assumes.
|
||||||
|
|
||||||
|
### 8.2 Activity feed & active project (`internal/activity`)
|
||||||
|
|
||||||
|
- The app keeps, in memory (and mirrored to the logs — no new datastore, §1.3):
|
||||||
|
- the **active project** (the single repo/task currently in focus), and
|
||||||
|
- an **activity feed** of what happened (user *and* Claude actions: repo
|
||||||
|
switched, committed, PR merged, …).
|
||||||
|
- Both are **queryable** (`get_active_project`, `get_activity`) so Claude can
|
||||||
|
**sync on any turn boundary** — the reliable, pull‑based foundation. The app
|
||||||
|
also **pushes** these to the browser over SSE for live UI. This pull‑first
|
||||||
|
design does not depend on the host letting a connector wake Claude.
|
||||||
|
|
||||||
|
### 8.3 Graceful project handoff (the headline flow)
|
||||||
|
|
||||||
|
When the user switches project/task in the app, it is a **request**, not an
|
||||||
|
instant yank. The cooperative protocol:
|
||||||
|
|
||||||
|
1. **User** picks a new project/task in the app → the app records a
|
||||||
|
**pending‑switch request** (target + optional note) and the UI shows
|
||||||
|
"waiting for Claude to reach a good stopping point."
|
||||||
|
2. **Claude** sees the pending request (it checks at its natural turn‑boundary
|
||||||
|
checkpoints via `get_pending_switch`). It **finishes to a safe stopping
|
||||||
|
point and preserves work** — never abandons uncommitted changes to switch;
|
||||||
|
it completes the in‑flight step and commits/stashes as appropriate — then
|
||||||
|
performs the switch (`set_active_project`, moving its working context to the
|
||||||
|
new repo) and calls **`ack_switch`** with a short summary of where it left
|
||||||
|
the previous project.
|
||||||
|
3. **App** marks the request fulfilled and **notifies the user** over SSE
|
||||||
|
("Claude switched to *ProjectB*; *ProjectA* left at: …"). The user proceeds.
|
||||||
|
|
||||||
|
**Rule:** the switch is Claude‑completed at a checkpoint, not app‑forced. Losing
|
||||||
|
or interrupting uncommitted work to satisfy a switch is a §1.4‑class violation.
|
||||||
|
|
||||||
|
> Fully autonomous "Claude starts working the instant you click, with no turn
|
||||||
|
> from you" is intentionally **not** assumed — it depends on host push support.
|
||||||
|
> Build 8.2–8.3 pull‑first; layer any auto‑wake on top only where the host allows.
|
||||||
|
|
||||||
|
### 8.4 Forge integration — read **and write** (`internal/forge`)
|
||||||
|
|
||||||
|
Talking to the hosting provider is isolated behind a **provider interface**
|
||||||
|
(**Gitea/Forgejo first** — the primary host is `git.nilles.net`; GitHub/GitLab
|
||||||
|
later behind the same interface).
|
||||||
|
|
||||||
|
- **Read:** list open PRs/MRs and their CI/check status for a repo whose remote
|
||||||
|
points at a supported host.
|
||||||
|
- **Write (enabled):** create a PR, **merge a PR, and delete the source branch**
|
||||||
|
— this powers "**Merge & clean up**", the feature that makes PRs usable for a
|
||||||
|
user who otherwise finds them clutter (Section 0). Every write is **confirmed
|
||||||
|
per §1.4**, names the PR/branch, and prefers the tidy default (squash‑merge +
|
||||||
|
delete branch). Note a merged PR remains in the host's history; "clean up"
|
||||||
|
means removing the **branch**, not falsifying history.
|
||||||
- **Enablement is per‑host and token‑gated.** Tokens come from `.env`
|
- **Enablement is per‑host and token‑gated.** Tokens come from `.env`
|
||||||
(e.g. `GITHUB_TOKEN`, `GITLAB_TOKEN`); with no token, the feature is simply
|
(e.g. `GITEA_TOKEN`); with no token the forge features are simply absent and
|
||||||
absent and the rest of the app works unchanged (**graceful degradation** — never
|
the rest of the app works unchanged (**graceful degradation**).
|
||||||
a hard dependency).
|
- The provider is inferred from a repo's remote URL. Never send repo data to a
|
||||||
- The provider is inferred from a repo's remote URL. Never send repo data to a host
|
host the user didn't configure.
|
||||||
the user didn't configure.
|
|
||||||
|
|
||||||
Design the interface cleanly now; implement providers incrementally as requested.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -373,9 +473,12 @@ component carries its own context.
|
|||||||
2. **Check the rules** in Section 1. If the request conflicts, **pause and ask.**
|
2. **Check the rules** in Section 1. If the request conflicts, **pause and ask.**
|
||||||
3. If the work is UI: it is a **web component** in `components/<name>/` with its
|
3. If the work is UI: it is a **web component** in `components/<name>/` with its
|
||||||
own `.md`. No exceptions without asking.
|
own `.md`. No exceptions without asking.
|
||||||
4. If it touches repositories: go through the **`internal/git` boundary**, respect
|
4. If it touches repositories or forges: put the logic in the **service layer**
|
||||||
**Git = system of record** (Section 1.3), and treat **destructive operations**
|
(§1.7) over the `internal/git` / `internal/forge` boundaries — never in an HTTP
|
||||||
per Section 1.4. Never add a datastore.
|
or MCP handler — so both the GUI and Claude get it. Respect **Git = system of
|
||||||
|
record** (§1.3), treat **destructive operations** per §1.4, and never add a
|
||||||
|
datastore. A new capability generally means: service method → HTTP handler →
|
||||||
|
MCP tool → UI control.
|
||||||
5. If it needs a **new dependency** or a **new top‑level folder**, propose it and
|
5. If it needs a **new dependency** or a **new top‑level folder**, propose it and
|
||||||
wait for approval.
|
wait for approval.
|
||||||
6. Implement, run it in the **docker‑compose dev environment**, verify hot reload
|
6. Implement, run it in the **docker‑compose dev environment**, verify hot reload
|
||||||
@@ -396,10 +499,27 @@ silently guess.)*
|
|||||||
it should be enabled, and the interval / rate limit, before turning it on.
|
it should be enabled, and the interval / rate limit, before turning it on.
|
||||||
- **Git access library:** system `git` via `os/exec` is the locked default
|
- **Git access library:** system `git` via `os/exec` is the locked default
|
||||||
(Section 2). Confirm before introducing `go-git` for any read path.
|
(Section 2). Confirm before introducing `go-git` for any read path.
|
||||||
- **Forge providers:** which to support first (GitHub? GitLab?), and whether any
|
- ✅ **RESOLVED 2026-09-19:** **Forge = Gitea/Forgejo first** (`git.nilles.net`),
|
||||||
**write** actions (merge/comment/approve) are ever in scope (default: read‑only).
|
**read + write** — merge PR + delete branch ("Merge & clean up"), each confirmed
|
||||||
- **Listen address / exposure:** localhost‑only by default. Confirm before binding
|
per §1.4 (Section 8.4). GitHub/GitLab later behind the same interface.
|
||||||
to a non‑local interface — there is no auth (Section 0).
|
- ✅ **RESOLVED 2026-09-19:** **MCP transport = Streamable HTTP at `/mcp`**, added
|
||||||
|
in Claude Desktop as a custom connector (Section 8.1).
|
||||||
|
- ✅ **RESOLVED 2026-09-19:** **Project handoff is cooperative** — user requests a
|
||||||
|
switch, Claude finishes to a safe checkpoint, switches, and the user is notified;
|
||||||
|
pull‑first, not autonomous (Section 8.3).
|
||||||
|
- **MCP connector setup:** confirm this Claude Desktop build supports adding a
|
||||||
|
local Streamable‑HTTP custom connector (`http://127.0.0.1:8080/mcp`); if not,
|
||||||
|
fall back to a stdio shim.
|
||||||
|
- **Idle‑trigger for handoff:** the pull model syncs at Claude's turn boundaries.
|
||||||
|
If Claude is idle when the user switches, decide the nudge (user's next message,
|
||||||
|
a heartbeat/poll, or a host push if available) — do not assume instant wake.
|
||||||
|
- **Coordination‑state lifetime:** active project / pending‑switch / activity feed
|
||||||
|
are in‑memory today (§1.3). Confirm if any must survive an app restart before
|
||||||
|
adding any persistence.
|
||||||
|
- **Gitea token scope:** which token scopes to require (repo read + PR write +
|
||||||
|
branch delete) and how it is provisioned; document in `.env.example`.
|
||||||
|
- **Listen address / exposure:** localhost‑only by default (covers `/mcp` too).
|
||||||
|
Confirm before binding to a non‑local interface — there is no auth (Section 0).
|
||||||
- **Credential path from the container:** SSH agent socket vs mounted keys vs
|
- **Credential path from the container:** SSH agent socket vs mounted keys vs
|
||||||
credential helper, for pushing/fetching from inside Docker.
|
credential helper, for pushing/fetching from inside Docker.
|
||||||
|
|
||||||
|
|||||||
@@ -32,3 +32,23 @@ Append-only running history of all changes (AGENT.md §9.1). Newest last.
|
|||||||
canonical import path (e.g. a GitHub URL).
|
canonical import path (e.g. a GitHub URL).
|
||||||
- All items in AGENT.md §11 (discovery strategy, background fetch, forge
|
- All items in AGENT.md §11 (discovery strategy, background fetch, forge
|
||||||
providers, listen address, container credentials) remain open.
|
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).
|
||||||
|
|||||||
Reference in New Issue
Block a user