docs(agent-mode): add issue-creation skill, migration playbook, refresh TODOs (#2514)

- Add `.claude/skills/create-agent-issue/SKILL.md`: project-level skill that
  codifies the standard for one well-formed GitHub issue (title shape, body
  sections, label palette, draft artifact format, reviewer rubric, three-stage
  workflow: draft / review-and-push / all).
- Add `designdocs/todo/AGENT_TODOS_TO_ISSUES_PLAYBOOK.md`: orchestrator
  playbook for migrating `AGENT_MODE_TODOS.md` into GitHub issues with a
  two-subagent (author + reviewer) flow, autonomous triage, parallelism,
  idempotency, and verbatim subagent prompt templates.
- Revamp `designdocs/todo/AGENT_MODE_TODOS.md`: richer per-item context,
  "design needed" markers, reorganized MCP and Codex auth items, current
  pending count is 33 top-level items (P0=7, P1=17, P2=7, P3=2).
- Drop `designdocs/todo/MCP_EXTERNALLY_MANAGED_SERVERS.md` (stale).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Zero Liu 2026-05-28 00:42:27 -07:00 committed by GitHub
parent e7477385ae
commit 3aea987832
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 651 additions and 92 deletions

View file

@ -0,0 +1,300 @@
---
name: create-agent-issue
description: |
Create a single high-quality GitHub issue in
logancyang/obsidian-copilot-preview from a TODO item, design-doc punch list
entry, or ad-hoc feature/bug request. Each invocation is exactly one issue
end-to-end: investigate the surface in src/, draft against the standard,
ensure labels exist, push via gh, and (if a source file + line were given)
edit that line to point at the new issue. Use when asked to "file an issue
for X", "open a ticket", or "convert this TODO to an issue".
allowed-tools:
- Bash
- Read
- Edit
- Grep
- Glob
---
# `/create-agent-issue` — produce one high-quality GitHub issue
This skill creates **one** GitHub issue at a time in
`logancyang/obsidian-copilot-preview`. It is designed to be invoked either by
a human (one-shot, end-to-end) or by two cooperating subagents (one drafts,
one reviews and pushes).
The skill is deliberately scoped to a single issue. It does not loop, batch,
or reason about other items.
## Inputs
The caller passes (free-form for ad-hoc use, structured for subagent use):
- **TODO text** — the line(s) describing the work.
- **Priority**`P0` / `P1` / `P2` / `P3`.
- **Folded sub-items** *(optional)* — secondary bullets that should appear as a
checklist in the issue body.
- **Source file + line range** *(optional)* — file path and 1-based line range
whose lines should be replaced with a link to the new issue after the push.
- **`chunk-id`** *(optional)* — string used to name the draft artifact file.
Required when `stage=draft` or when running under a reviewer flow.
- **`stage`** — one of:
- `stage=draft` — investigate + write draft to
`.context/issues/<chunk-id>.md`. No GitHub call. No source-file edit.
- `stage=review-and-push` — load the draft, independently verify, revise if
needed, push via `gh`, edit the source file (or return the replacement
line).
- `stage=all` *(default for ad-hoc use)* — do both back-to-back in the same
context. Used when no reviewer step is required.
- **`source-edit`** *(optional, only with `review-and-push` / `all`)*
`apply` (default; skill edits the file) or `return-only` (skill reports the
proposed replacement line and does not touch the file).
## Investigation (mandatory for `stage=draft` and `stage=all`; the reviewer in `stage=review-and-push` repeats it independently)
Before drafting:
1. **Locate the relevant surface in `src/`.** Grep for keywords from the TODO.
Common entry points for Agent Mode work:
- `src/LLMProviders/`
- `src/agentMode/` (if present)
- `src/components/Chat/`
- `src/tools/`
- `src/mcp/`
- `src/skills/`
2. **Read any design doc referenced by the TODO line.** Examples currently
present in `designdocs/todo/`:
- `MCP_EXTERNALLY_MANAGED_SERVERS.md`
- `AGENT_PLANNING_REFLECTION_V0.md`
- `AGENT_REASONING_BLOCK.md`
- `ACP_DESIGN.md`
If the TODO references a doc that does not exist
(e.g. `designdocs/SKILLS_DISCOVERY_REDESIGN.md` is referenced today but
not yet written), flag this in the issue's Open questions section and
proceed with the TODO text alone.
3. **Note the current behavior in one or two sentences.** This anchors the
`## Context` section. The sentence must reference at least one real file
path or symbol the investigator just read.
4. **Identify the observable changes the user would see when resolved.** This
anchors `## Proposed behavior` and `## Success criteria`.
5. **Look for "design needed" markers** in the TODO sub-bullets. When
present, the issue body should call this out in `## Open questions /
Risks` and `## Proposed behavior` should remain intentionally open-ended
("design a UI that …" rather than prescribing pixels).
## Title standard
Imperative sentence. No trailing period. ≤80 characters. No area prefix.
Good examples:
- "Validate Agent Mode end-to-end on Windows"
- "Upgrade pinned opencode binary to latest version"
- "Pass Copilot system prompt to opencode, Claude Code, and Codex"
- "Verify agents cannot edit files outside the user vault (sandbox mode)"
- "Render AskUserQuestion prompts inline in chat"
Bad examples:
- "Agent mode: validate end-to-end behavior on Windows" (area prefix)
- "Make the chat better." (vague, trailing period)
- "I think we should probably do something about Windows" (not imperative)
## Body template
Exact section order. Markdown. No other top-level sections.
```markdown
## Context
<13 sentences anchored in the current code/behavior the investigator just
verified. Name the user pain or the gap. Link to a design doc in
`designdocs/todo/` if one is directly relevant. Do not link back to any
source TODO file.>
## Proposed behavior
<Bullet list of observable end-user behaviors after this issue is resolved.
Not implementation details. If sub-tasks were folded in, include them as a
checklist:>
- [ ] Sub-behavior 1
- [ ] Sub-behavior 2
## Success criteria
<Bulleted, verifiable list. Each item must be testable by a reviewer without
re-asking the author. Mix automated and manual where appropriate. At least
one bullet must reference a real test or command.>
- Behavior X is visible in the chat card before approval.
- `npm run test` passes including new unit tests for <module>.
- Manual: run `npm run test:vault`, exercise <flow>, observe <outcome>.
## Open questions / Risks
<Bullets. OK to be short. "None known." is acceptable when truly N/A.
If the source TODO is marked "design needed", lead this section with
`Design needed:` and list the specific design questions surfaced during
investigation.>
```
## Labels
Apply:
- **`agent-mode`** — always for Agent Mode work.
- **One priority label** — exactly one of `P0` / `P1` / `P2` / `P3`,
matching the TODO prefix.
- **Type label**`enhancement` or `bug` when obvious; skip otherwise.
Before applying, run
`gh label list --repo logancyang/obsidian-copilot-preview` and create any
missing label via `gh label create --repo logancyang/obsidian-copilot-preview
<name> --color <hex>`. Palette:
| Label | Color |
|--------------|-----------|
| `agent-mode` | `#5319e7` |
| `P0` | `#b60205` |
| `P1` | `#d93f0b` |
| `P2` | `#fbca04` |
| `P3` | `#0e8a16` |
`enhancement` and `bug` already exist in the repo with their default colors.
## Draft artifact format (`stage=draft` output)
Write to `.context/issues/<chunk-id>.md` with this exact shape so the reviewer
can parse deterministically:
```md
---
chunk-id: <id>
title: <issue title>
labels: [agent-mode, P1, enhancement]
priority: P1
source-file: <path or null>
source-lines: <start-end or null>
investigated:
- src/agentMode/binaryDetection.ts
- src/LLMProviders/opencode/launch.ts
---
## Context
...
## Proposed behavior
...
## Success criteria
...
## Open questions / Risks
...
```
The `investigated` field lists every file the author actually read. The
reviewer uses this to spot-check: re-grep, re-read at least one cited file,
and confirm the Context section's claims hold.
If the author could not locate the relevant surface in `src/`, set
`investigated: []` and explain in the issue's Open questions section that
the surface was not identified during investigation.
## Reviewer rubric (`stage=review-and-push`)
Before pushing, the reviewer applies this checklist to the draft. Each line
must pass; if any fail, the reviewer revises the draft in place and re-checks.
**Hard cap: 2 revision passes.** If still failing after the second revision,
abort and report the specific failures so the caller can re-spawn a fresh
author with the reviewer's feedback.
- **Title**: imperative, ≤80 chars, no trailing period, no area prefix.
- **Context**: anchored in real code or real current behavior. The reviewer
**must** re-grep at least one symbol or path from the `investigated:` list
and confirm it exists and behaves as the Context section claims. Generic
prose ("the current implementation doesn't handle X well") without a file
reference fails.
- **Proposed behavior**: observable end-user behaviors, not implementation
details. Multi-part proposals use `- [ ]` checklists.
- **Success criteria**: every bullet is verifiable by a reviewer without
re-asking the author. At least one bullet references a real test or
command (e.g. `npm run test`, `npm run test:vault`, a specific manual
flow). "Works correctly" is not a success criterion.
- **Open questions / Risks**: present and non-empty unless truly N/A. If the
source TODO is marked "design needed", this section leads with
`Design needed:` and enumerates the specific open design questions.
- **Labels**: includes `agent-mode` + exactly one priority label
(`P0`/`P1`/`P2`/`P3`) + optional `enhancement` or `bug`.
- **No leakage**: body contains no references to any source TODO file, no
scaffolding chatter ("as requested by user"), no internal coordination
comments.
## Push step (reviewer-owned in `stage=review-and-push` and `stage=all`)
After all rubric items pass:
1. Run `gh label list --repo logancyang/obsidian-copilot-preview` and create
any missing labels from the palette above.
2. Write the issue body to a temporary file (e.g.
`/tmp/create-agent-issue-<chunk-id>.md`) — passing a body file is more
robust than `--body` for multi-line markdown.
3. `gh issue create --repo logancyang/obsidian-copilot-preview --title "<title>"
--label "<comma-separated labels>" --body-file <tmpfile>`. Capture the
returned URL.
4. Parse the issue number from the URL.
## Source-file backfill (reviewer-owned, only in `stage=review-and-push` and `stage=all`, only when invoked with a source file + line range)
Replace the given source line(s) with a link to the new issue.
For a single line like:
```md
- [ ] P1: Improve binary detection
```
transform to:
```md
- [ ] P1: [Improve binary detection](https://github.com/logancyang/obsidian-copilot-preview/issues/123)
```
The checkbox stays unchecked. (Closing the checkbox happens later, when the
GitHub issue itself closes — that sweep is not part of this skill.)
If the issue folded in sub-items, the caller is expected to pass the full
line range to replace; the skill does what it's told and does not infer.
**`source-edit=return-only` mode.** If the caller passes `source-edit=return-only`,
compute the proposed replacement line(s) and return them in the report
without touching the file. Used when a caller wants to serialize file writes
itself.
If no source file is passed, skip this step entirely.
## Report back
Return a structured summary the caller can parse:
- `Created #<N>: <title> → <url>`
- `Source edit: <path>:<lines>` *or* `Source edit: returned <line>` *or*
`Source edit: none`
- `Revision passes: <N>` *(only in `stage=review-and-push` / `stage=all`)*
- `Rubric: pass` *or* `Rubric: abort — <reason>` *(only in
`stage=review-and-push` / `stage=all`)*
If `Rubric: abort`, no issue was created and no source edit was made.
## What this skill does not do
- Process multiple items in one invocation. One issue per call.
- Decide whether sub-items should be folded vs. split. The caller decides
and passes the result in.
- Reason about other items, sequencing, batching, or any external workflow.
- Close issues, assign users, set milestones, or sync GitHub state back into
any source file.
- Create pull requests.

View file

@ -5,41 +5,58 @@
- [x] Save chat history to notes
- [x] P0: Thoroughly assess whether migrating to Anthropic agent SDK is worth it.
- [ ] P0: Test Windows devices
- [ ] P0: Make sure bash command shows what command it runs (visibility)
- [ ] P0: Provide copilot specific system prompt
- [ ] Allow users to share system prompt
- [ ] Do a quick spike on the concrete behavior
- [ ] Investigate opencode provider specific prompt
- Anything path or subprocess related should be checked (skills management, opencode installation)
- [x] P0: Make sure bash command shows what command it runs (visibility)
- [ ] P0: Upgrade pinned opencode to latest version
- [ ] P0: Pass copilot built-in system prompt / user provided system prompt to agents
- making sure opencode, claude code, and codex all work well.
- [ ] P0: Test sandbox mode
- we need to make sure the agents won't accidentally edit files outside of user vault folders. Investigate sandbox mode in each agent integration and make those edit programmatically blocked.
- [x] P0: Skills
- [x] Check out cc-switch to understand how to make skills compatible cross other agents https://github.com/farion1231/cc-switch
- [x] P0: Permission management
- [x] Permission UI improvement
- [ ] P0: How to design the settings to configure the provider?
- [x] P0: How to design the settings to configure the provider?
- [x] Redesign the model settings - discussed on May 7 group meeting
- [x] support self host model
- [x] remove built-in models
- [x] migrate existing models to the new format
- [ ] P0: Test opencode works well with local models
- [ ] P0: Fix broken legacy agent mode
- [ ] Can we only support basic chat - not now but eventually yes
- configure local models in ollama and lm studio to make sure they can be enrolled in BYOK and enabled on opencode, and can work well in opencode.
- [ ] P0: Test migration (skill, model) to make sure no unrecoverable migration is introduced in pre-release
- the new agent mode introduces schema changes to data.json. We need to introduce migration scripts and versioning. Making sure before pre-release launch, all the schema changes are settled to avoid adding new migrations, as they can be fragile.
- [ ] P0: 非migrate的skill最好能直接引用,同名的skill如果内容一样migrate可以做得更好
- Check designdocs/SKILLS_DISCOVERY_REDESIGN.md
- [x] P0: Auto-save chat history controls
- [x] P0: Support image context
- [ ] P1: Support claude code authentication
- when user hasn't signed into claude code, the chat will respond with no message and no error.
- we need to prompt user to sign in. Best to pop claude oauth page and let them finish sign in directly within copilot.
- [ ] P1: Better binary detection
- In discord team channel, a few folks shared that the system failed to auto detect their binaries. It's due to lacking environment variable PATH in the runtime (e.g. nvm). We need to do researches to figure out whether we have to expand the PATH or there is a better way to import user system PATH.
- [ ] P1: MCP management
- We need to manage MCP in the same way as SKILLs. They should be portable agent to agent. This work involves introducing a new settings view and create a central way to manage MCP configs across all agents.
- design needed
- [ ] P1: Support oauth for MCP servers (the one example that I tested in ACP agents didn't work)
- [ ] P1: Support setting MCP by copy pasting JSON blobs (quality of life changes)
- [ ] P1: Fix broken legacy agent mode
- legacy agent mode currently failed to work. we need to keep them working to support existing user workflows
- [x] P1: [BUG] Check active note path. Sometimes the agent will start from a path that does not exist
- [x] P1: [Performance] Updating skills settings is laggy
- [ ] P1: Make askuserquestion tool show questions inline in the chat.
- [ ] P1: Improve binary detection
- [ ] P1: MCP
- Basic functionality is ready
- [ ] P1: Surface externally-managed MCP servers (claude.ai remote, plugin-provided) — see [MCP_EXTERNALLY_MANAGED_SERVERS.md](./MCP_EXTERNALLY_MANAGED_SERVERS.md)
- [ ] P1: Support oauth for MCP servers (the one example that I tested didn't work)
- [ ] P1: Support setting MCP by copy pasting JSON blobs
- [ ] P1: Content type support (image, audio) - https://agentclientprotocol.com/protocol/content
- [ ] P1: Make AskUserQuestion tool show questions inline in the chat like permission instead of in a dialog.
- design needed
- [ ] P1: Citation
- Introduce a tool to let agent call to generate citation on the researched sources
- design needed for citation
- [ ] P1: Edit diff UI - https://agentclientprotocol.com/protocol/tool-calls#diffs
- Generate clear diffs and let user approve before an edit can be make. This can be part of the edit permission check.
- Onces the agent makes the edit, we should still allow user to click on the edit tool message and check what was changed.
- The edit diff should be based on well rendered markdown, not raw markdown file. For example, table is impossible to understand the diff with the raw format
- [ ] P1: Thoroughly test opencode, codex, and claude code with different test cases
- [ ] Create sample vaults for test cases.
- design needed
- [ ] P1: Fix session title for claude code agent
- It currently doesn't generate session title like other ACP based agents.
- [ ] P1: Agent upgrade detection and helper UI in settings
- The installed ACP and opencode binary can upgrade. We need to provide users hint to upgrade them to ensure proper functionalities.
- [ ] P1: Forward web-source context to the agent
- The agent should be able to access the content of the rendered tab
- Right-click "Add to Copilot context" excerpts from web tabs and the
@ -48,10 +65,9 @@
`<copilot-context>` envelope (e.g. a `Web excerpts:` section with
`title (url): content`) so the agent can actually read them.
- [ ] P1: Move PDF parsing into an agent tool
- Inline PDF parsing during send can take too long and blocks the user
before the agent starts. Keep PDF attachments as vault paths for the
built-in Read tool for now, then expose Copilot PDF parsing as an
explicit tool the agent can call when it needs extracted PDF text.
- Copilot provide a premium PDF parsing service. For paid user, we should expose Copilot PDF parsing as an
explicit skill or mcp when it needs extracted PDF text.
- design needed
- [ ] P1: Token counter
- To know how many context is left in the current session
- Nice-to-have: Cost estimate
@ -62,17 +78,21 @@
- challenge - agentic search often is better than RAG, how does the agent know when to trigger it
- we don't need index-free search
- [ ] web search (paid feature only)
- [ ] ~~edit~~
- [ ] deprecate "edit" and "composer"
- [ ] youtube transcription (paid feature only)
- [ ] obsidian CLI
- [ ] P1: Opencode plan mode fine-tuning
- [ ] P1: compaction
- [ ] manual trigger
- [ ] P1: support compaction
- [ ] design how to manual trigger a compaction
- [ ] configure when to auto compact
- [ ] P1: Allow comment in plan mode
- inspired by claude code vscode extension interaction
- [ ] P1: Project mode
- [ ] P2: Inherit model effort from previous model when selecting a new model in the picker
- It's quite tedious today that sometimes the effort will drop to low.
- create a new project mode that work with the agent mode.
- [ ] P1: Move relevant notes to its own view
- [ ] P1: Settings page revamp
- deprecate unused settings
- [ ] P2: Support subscriptions that work with opencode (kimi code)
- today we ask user to configure their subscriptions directly in opencode. This will allow them to configure subscription directly in obsidian copilot.
- [ ] P2: Claude vscode plugin add comment to plan capability
- It makes iterating on plan a lot easier
- [x] P2: [UX] Make mode more obvious
@ -82,14 +102,18 @@
"Editing draft.md" / "Edited draft.md", "Fetching url" / "Fetched url",
etc.) so in-flight calls no longer render with past-tense verbs.
- [ ] P2: Edit previous user message
- [ ] P2: Support batch editing skills
- [ ] P2: New agent command (/new, /usage)
- [ ] P2: Claude code / Codex authentication
- [ ] P2: Agent command (/new)
- /new to create a new chat session
- /usage to show how much quota is left
- [ ] P2: Steering conversation (instead of queue)
- [ ] P2: Rollback everything to the state of previous message
- If a user wants to go back to a previous conversation (like claude code double ESC), we should allow users to and revert the state to when that message is triggered.
- [ ] P2: In-product QA agent to debug for users
- Users may have questions about copilot features and we can create a skill to answer user questions directly in copilot.
- [ ] P3: Rerun agent response
- [ ] P3: Agent todo list
- [ ] make sure in case it renders, it won't be buggy
- click "rerun" button to regenerate agent response
- [ ] P3: Copy agent message
- copy the agent generated message with a button under the message like what the chat mode allows today
- [x] P1: Queue messages
- [x] P1: Only include the provided models
- hide openrouter models behind a modal selector

View file

@ -0,0 +1,294 @@
# Playbook: migrate `AGENT_MODE_TODOS.md` to GitHub issues
This playbook tells an orchestrator agent how to convert every pending
top-level item in `designdocs/todo/AGENT_MODE_TODOS.md` into a GitHub issue
in `logancyang/obsidian-copilot-preview`, replacing each migrated TODO line
with a link to its issue.
The orchestrator does **not** write issues itself. It triages, then spawns a
pair of subagents per chunk — an *author* that drafts, and a *reviewer* that
re-verifies, revises, and pushes. The orchestrator owns the source-file
write to avoid races.
## Goal
For every pending top-level `- [ ]` item in `AGENT_MODE_TODOS.md`:
1. Open a GitHub issue in `logancyang/obsidian-copilot-preview` using the
`/create-agent-issue` skill standard.
2. Replace the TODO line with a markdown link to the new issue (checkbox
stays unchecked).
As of 2026-05-28 the file has **33 pending top-level items**:
P0 = 7, P1 = 17, P2 = 7, P3 = 2.
## Prerequisites
- `gh` CLI authenticated with WRITE access on
`logancyang/obsidian-copilot-preview`. Verify with
`gh repo view logancyang/obsidian-copilot-preview --json viewerPermission`.
- `.claude/skills/create-agent-issue/SKILL.md` present (this is the
single-issue standard the subagents follow).
- `.context/issues/` directory exists. The orchestrator creates it on first
run: `mkdir -p .context/issues`.
There is **no human approval gate** in this playbook. The orchestrator
proceeds autonomously once invoked.
## Why two subagents per chunk
The user does not review issues by hand. To maintain quality without a human
gate, every chunk goes through two passes:
- **Author subagent** investigates the relevant `src/` surface and writes a
draft to `.context/issues/<chunk-id>.md` (`stage=draft`). Does not touch
GitHub.
- **Reviewer subagent** loads the draft, **independently** re-investigates
the same surface (does not trust the author's `investigated:` frontmatter
blindly — uses it as a starting point and verifies), applies the rubric
defined in the skill, revises the draft in place (up to 2 passes), and
only then pushes via `gh` (`stage=review-and-push`).
Each subagent runs in its own context, so each has a full token budget for
code reading. Doing 33 chunks in a single context blurs detail and produces
lookalike issues.
## Step 1 — Triage (orchestrator decides autonomously)
Walk every pending top-level `- [ ]` in `AGENT_MODE_TODOS.md`. For each, build
a chunk record.
**Sub-bullet rules:**
- **Non-checkbox** sub-bullets (plain `-`) are always elaboration of the
parent. Fold them into the parent issue's `## Context` or
`## Proposed behavior`. Never split.
- **Checkbox** sub-bullets (`- [ ]`) are decided per case:
- **Fold** when sub-items are refinements of one behavior. Example:
"support compaction" → manual trigger + auto-compact toggles fit in one
issue with a `- [ ]` checklist in `## Proposed behavior`.
- **Split** when each sub-item is independently shippable with its own
surface and success criteria. Example: "Integrate copilot plus tool
calls" → the 5 children (vault search, web search, deprecate
edit/composer, YouTube transcription, Obsidian CLI) each get their own
issue.
**Record the triage** in `.context/issue-migration-plan.md` as a table:
```md
| chunk-id | parent line | priority | folded sub-lines | split-out sub-lines | source-line-range |
|----------|-------------|----------|------------------|---------------------|-------------------|
| windows-test | 7 | P0 | 8 | — | 7-8 |
| ...
```
- `chunk-id` is a short kebab-case slug (e.g. `windows-test`, `mcp-oauth`,
`compaction`). It is used to name the draft file at
`.context/issues/<chunk-id>.md`.
- `source-line-range` is the exact 1-based range in `AGENT_MODE_TODOS.md`
whose lines should be replaced by a link to the new issue. For folded
cases this includes the sub-lines; for split cases each split chunk gets
its own one-line range.
The triage runs once at the start. No user approval gate — the orchestrator
proceeds.
## Step 2 — Per-chunk flow
For each chunk record:
### 2.1 Spawn the author
Use the `Agent` tool with `subagent_type: "general-purpose"` and the
**author prompt template** (see Step 4 below). The author:
1. Loads `.claude/skills/create-agent-issue/SKILL.md`.
2. Runs the investigation step.
3. Runs `stage=draft`, writing the draft to
`.context/issues/<chunk-id>.md`.
4. Returns the draft file path in its summary.
### 2.2 Spawn the reviewer
Once the author returns, use `Agent` with `subagent_type: "general-purpose"`
and the **reviewer prompt template** (see Step 4 below). The reviewer:
1. Loads the skill.
2. Loads the draft at `.context/issues/<chunk-id>.md`.
3. Independently re-investigates the same surface (does not blindly trust
the author's `investigated:` list).
4. Applies the rubric. Revises the draft in place up to 2 times.
5. On rubric pass: runs `stage=review-and-push` with
`source-edit=return-only`, pushing the issue via `gh` and returning the
issue URL plus the proposed replacement line.
6. On rubric abort: returns the specific rubric failures.
### 2.3 Orchestrator writes the source file
On reviewer success, the orchestrator (not the subagent) edits
`designdocs/todo/AGENT_MODE_TODOS.md` to replace the chunk's
`source-line-range` with the replacement line returned by the reviewer.
This centralized write is what makes parallelism safe — multiple subagents
can run concurrently because none of them touch the source file. The
orchestrator serializes its own writes.
### 2.4 On abort — one re-spawn
If the reviewer aborts, re-spawn a fresh author for that chunk with the
reviewer's feedback embedded in the prompt. **Max 1 re-spawn per chunk.** If
the re-spawn also aborts, append the chunk-id and reviewer feedback to
`.context/failed-chunks.md` and move on. Do not block other chunks on a
single failure.
## Step 3 — Parallelism
Run **up to 3 chunks in parallel** as independent author → reviewer
pipelines. Each pipeline is internally serial (the reviewer needs the
author's draft). The orchestrator's writes to `AGENT_MODE_TODOS.md` are
already serialized (Step 2.3), so parallel chunks do not race on the source
file.
Three is the recommended starting concurrency. Adjust downward if you
observe rate-limit pressure from `gh` or token-budget issues.
## Step 4 — Subagent prompt templates
Copy-paste these into the `Agent` tool's `prompt` field. Replace
`{placeholders}` with the chunk's actual values.
### Author prompt template
```
You are processing one TODO item from designdocs/todo/AGENT_MODE_TODOS.md and
producing a draft GitHub issue.
Chunk ID: {chunk_id}
Priority: {priority}
Source file: designdocs/todo/AGENT_MODE_TODOS.md
Source line range: {source_line_range}
TODO text (verbatim from the source file):
---
{parent_todo_text}
{folded_sub_lines}
---
Your steps:
1. Read `.claude/skills/create-agent-issue/SKILL.md` and follow its standard.
2. Run a real investigation pass against `src/`. Grep for keywords from the
TODO text. Read at least one file from the relevant surface end-to-end so
the issue's Context section can cite real code. Read any design doc the
TODO references (look under `designdocs/todo/`).
3. Run the skill's `stage=draft` workflow. Write the draft to
`.context/issues/{chunk_id}.md` following the exact frontmatter format in
the skill. The `investigated:` frontmatter field must list every file you
actually read during this investigation.
4. Do NOT run `gh issue create`. Do NOT edit the source TODO file.
Return:
- The full path to the draft file you wrote.
- A one-paragraph summary of what you found during investigation, including
any open questions you surfaced.
If you cannot locate the relevant surface in `src/`, set `investigated: []`
in the draft frontmatter and call this out explicitly in the draft's Open
questions section. Do not invent file paths.
```
### Reviewer prompt template
```
You are reviewing a draft GitHub issue produced by another subagent. You may
revise it in place. You will be the one who pushes it to GitHub once you are
satisfied.
Chunk ID: {chunk_id}
Draft path: .context/issues/{chunk_id}.md
Source file: designdocs/todo/AGENT_MODE_TODOS.md
Source line range: {source_line_range}
Your steps:
1. Read `.claude/skills/create-agent-issue/SKILL.md` to load the standard
and the reviewer rubric.
2. Read the draft at the path above.
3. Re-investigate INDEPENDENTLY. Do not trust the draft's `investigated:`
frontmatter blindly. Pick at least one symbol or file path the draft
cites in its Context section, grep for it, and confirm it exists and
behaves as the draft claims. If the draft cites no concrete paths, that
itself is a rubric failure.
4. Apply the rubric in the skill. For each failing item, edit the draft in
place to fix it.
5. Hard cap: 2 revision passes. After the second revision, re-apply the
rubric. If any item still fails, do NOT push — abort and return the
specific rubric failures.
6. If the rubric passes, run the skill's `stage=review-and-push` workflow
with `source-edit=return-only`. This will:
- Ensure all required labels exist (create via `gh label create` if not).
- Push the issue via `gh issue create`.
- Compute (but not apply) the proposed replacement line for the source
file.
Return (on push success):
- The GitHub issue URL and number.
- The proposed replacement line for `AGENT_MODE_TODOS.md` lines
{source_line_range}. The orchestrator will apply the edit, not you.
- The number of revision passes you made.
Return (on rubric abort):
- The rubric items that failed, with specific examples from the draft.
- Any concrete suggestions for the next author run.
```
## Step 5 — Idempotency / resume
Before processing a chunk, the orchestrator checks two things:
- **Source line.** If `AGENT_MODE_TODOS.md` line(s) in the chunk's
`source-line-range` already contain `https://github.com/.../issues/`, the
chunk is already done — skip it.
- **Existing draft.** If `.context/issues/<chunk-id>.md` already exists,
skip the author phase and feed the existing draft directly to a reviewer.
Useful for resuming a partial run after an interruption.
## Step 6 — Final verification
Once all chunks are processed:
1. Confirm GitHub state:
```
gh issue list --repo logancyang/obsidian-copilot-preview \
--label agent-mode --state open --limit 100 | wc -l
```
should be ≥ the number of chunks processed successfully (some chunks may
have aborted and been logged to `.context/failed-chunks.md`).
2. Confirm source-file state:
```
git diff designdocs/todo/AGENT_MODE_TODOS.md
```
Every pending top-level `- [ ]` line should now contain a
`github.com/.../issues/` link, except chunks listed in
`.context/failed-chunks.md`.
3. Print a summary table to the user:
```
| chunk-id | issue # | url | revision passes |
```
Plus a list of any failed chunks with their abort reasons.
## Out of scope
- Closing GitHub issues. (Issues are created open and stay open until
resolved in the repo's normal flow.)
- Syncing TODO checkboxes back to checked state when the GitHub issue
closes. (Separate future sweep.)
- Migrating other TODO files in `designdocs/todo/` (`TECHDEBT.md`,
`TODO-composer-tool-redesign.md`, `TOKEN_BUDGET_ENFORCEMENT.md`,
`UI_RENDERING_PERFORMANCE.md`). This playbook targets only
`AGENT_MODE_TODOS.md`.
- Creating pull requests, assigning users, or setting milestones.
- Any human-in-the-loop gate. The orchestrator runs end-to-end.

View file

@ -1,59 +0,0 @@
# MCP servers managed outside the local config
## Problem
When the Claude Code backend is active, the running `claude` binary connects to MCP servers from at least three sources we do not control through `~/.claude.json` or `.mcp.json`:
1. **claude.ai-provisioned remote MCPs** — Gmail, Google Calendar, Google Drive, Slack, etc. Provisioned server-side per claude.ai account; the binary connects to them at startup over HTTPS.
2. **Plugin-provided MCPs** — e.g. `plugin:context7:context7`. Bundled by Claude Code plugins, not declared in any user-editable file.
3. **(Already covered by the main sync plan)** Local config MCPs in `~/.claude.json` and `.mcp.json`.
`claude mcp list` enumerates all three at runtime. `~/.claude.json` only contains category 3. The only local hint of category 1 is a `claudeAiMcpEverConnected: string[]` field, which is informational ("ever connected", not "currently active") and does not include category 2 at all.
### Why this is bad
If the obsidian-copilot MCP panel only shows local-config entries, a user who already has `claude.ai Gmail` connected may add their own `gmail` MCP through the panel. Both register tools under similar/overlapping namespaces; the agent calls become ambiguous, and the user has no signal that the conflict exists.
We've already locked down "extra registration via ACP" by passing `mcpServers: []` when the backend owns runtime registration (see `MCP_BACKEND_SYNC` plan). That stops obsidian-copilot from causing duplicates itself, but it does not prevent the user from creating a duplicate **inside** the local config that collides with a remote claude.ai MCP.
## What we cannot do
- **Disable claude.ai MCPs locally.** No CLI flag, no env var, no config key. Only off-switch is at claude.ai/settings → Connectors (web) or signing the connector out.
- **Disable plugin MCPs without disabling the plugin.** No per-MCP toggle.
- **Get a structured (JSON) list from `claude mcp list`.** Output is human-formatted; parsing is brittle and version-coupled.
Treating these as user-editable is therefore not on the table. The only available shape is **read-only awareness**.
## Options
| Option | Effect | Cost |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **A. Surface via `claude mcp list`** | Shell out, parse output, render claude.ai/_ and plugin/_ entries as read-only "Managed externally" rows alongside editable local ones. Solves "I don't see it". | Brittle parsing; spawns `claude` (~500ms1s) on panel mount. Output format may change between Claude Code versions. |
| **B. Static informational note** | Show "Claude Code may connect to remote claude.ai MCPs (Gmail, Calendar, etc.) that aren't editable here. Manage them at claude.ai/settings → Connectors." Just text, no enumeration. | Cheap. Doesn't tell the user _which_ servers, so they can still duplicate by name. |
| **C. Hybrid: warn on name conflict** | Pre-fill known claude.ai MCP names (gmail, calendar, slack, drive — small static list) and warn if user adds a server matching a known remote. | Heuristic; misses unknown remote MCPs and any future additions. |
| **D. Do nothing** | Status quo. User experiences conflict, debugs, learns. | Bad UX. |
### Recommendation
**A + B combined.** Shell out to `claude mcp list` once when the panel mounts, render claude.ai/_ and plugin/_ entries as read-only rows tagged "Managed by claude.ai" / "Managed by plugin", with a static note pointing to claude.ai/settings → Connectors. This is exactly what the user already sees in the terminal, lifted into Obsidian. Cache the result for the lifetime of the panel mount; add a manual "Refresh" button to reread.
Risks to mitigate before implementation:
- Parser must tolerate format changes — fail closed (omit external rows + log warning), never crash the panel.
- The shell-out must be debounced and cancellable; don't block initial render.
- If `claude` is not on PATH at panel mount (binary configured via custom path only), fall back to invoking via the configured `binaryPath` if the same binary supports `mcp list` (it does — same binary).
## Open questions
1. **Render claude.ai/plugin entries inline, or behind a "show external MCPs" disclosure toggle?** Inline is more discoverable; toggle keeps the panel uncluttered for users who never touch external MCPs.
2. **Refresh cadence:** mount-only + manual button, or also re-fetch on `subscribe()` callback from the local-config file watch (since external state can change without local file changes)?
3. **Backend coverage:** does the same problem exist for OpenCode / future Codex backend? If so, the read-only surface should live on `McpStorageAdapter` (`listExternal()` method) rather than be Claude-Code specific.
## Out of scope
- Any attempt to disable, mute, or hide claude.ai MCPs at runtime. The user must do that through claude.ai web settings; we can only point them there.
- Forking or patching `claude-agent-acp`.
## Related
- Main sync plan: see [`AGENT_MODE_TODOS.md`](./AGENT_MODE_TODOS.md) — _P1: Syncing and managing MCP registered in the backends_. This doc covers the externally-managed sub-case that the main sync plan deliberately does not address.