From cf8c82b7794cd3f04894f13cf96089d09aae0ea0 Mon Sep 17 00:00:00 2001 From: David Kaya Date: Mon, 23 Mar 2026 23:54:44 +0100 Subject: [PATCH] docs: remove old plans --- HANDOVER.md | 204 ----------- MCP-LSP-IMPLEMENTATION-PLAN.md | 628 --------------------------------- 2 files changed, 832 deletions(-) delete mode 100644 HANDOVER.md delete mode 100644 MCP-LSP-IMPLEMENTATION-PLAN.md diff --git a/HANDOVER.md b/HANDOVER.md deleted file mode 100644 index 41154c8..0000000 --- a/HANDOVER.md +++ /dev/null @@ -1,204 +0,0 @@ -# Git-aware context UX handover - -This document covers the frontend/UX work that can now be built on top of the newly implemented backend/shared git-context support. - -## What was implemented in backend/shared - -The app now persists and refreshes per-project git context on `ProjectRecord`. - -### New shared project shape - -File: `src/shared/domain/project.ts` - -`ProjectRecord` now has: - -```ts -git?: ProjectGitContext; -``` - -`ProjectGitContext` shape: - -```ts -type ProjectGitContextStatus = 'ready' | 'not-repository' | 'git-missing' | 'error'; - -interface ProjectGitContext { - status: ProjectGitContextStatus; - scannedAt: string; - repoRoot?: string; - branch?: string; - upstream?: string; - ahead?: number; - behind?: number; - isDirty?: boolean; - changedFileCount?: number; - changes?: { - staged: number; - unstaged: number; - untracked: number; - conflicted: number; - }; - head?: { - hash: string; - shortHash: string; - subject: string; - committedAt: string; - }; - errorMessage?: string; -} -``` - -### New backend behavior - -Files: - -- `src/main/git/gitService.ts` -- `src/main/EryxAppService.ts` - -Behavior: - -- when a project is added, git context is fetched immediately -- when the workspace loads, the main process schedules an initial git-context refresh for all projects -- scratchpad projects intentionally do not carry git context -- non-repo folders are represented explicitly with `status: 'not-repository'` -- missing system git is represented explicitly with `status: 'git-missing'` -- unexpected git failures are represented with `status: 'error'` plus `errorMessage` - -### New Electron API - -Files: - -- `src/shared/contracts/channels.ts` -- `src/shared/contracts/ipc.ts` -- `src/main/ipc/registerIpcHandlers.ts` -- `src/preload/index.ts` - -New API: - -```ts -refreshProjectGitContext(projectId?: string): Promise; -``` - -Notes: - -- call with a `projectId` to refresh a single project -- call with no argument to refresh all projects -- the renderer also receives refreshed data through the existing `onWorkspaceUpdated(...)` subscription - -## Important UX constraints and current backend semantics - -These are important so the frontend does not guess incorrectly: - -- `project.git` is optional overall because scratchpad has no git context and older persisted workspaces may not have been refreshed yet -- `status: 'ready'` is the only state where branch/dirty/commit details should be assumed to exist -- `branch` may still be missing even when `status === 'ready'` (for example detached HEAD) -- `head` may be missing even when `status === 'ready'` (for example a repo with no commits yet) -- `upstream`, `ahead`, and `behind` are optional and should only be shown when present -- `changedFileCount` is a file-entry count, while `changes` breaks it down into staged / unstaged / untracked / conflicted -- this phase does **not** inject git context into sidecar run-turn payloads yet; this is app/backend UI support, not orchestration/runtime support - -## Recommended UX surfaces - -### 1. Sidebar project rows - -Primary file: `src/renderer/components/Sidebar.tsx` - -Current `ProjectGroup` already renders: - -- project icon -- project name -- running session count -- session count - -Recommended additions for non-scratchpad projects: - -- branch badge next to the project name when `project.git?.status === 'ready'` -- subtle dirty indicator when `isDirty === true` -- changed file count badge when `changedFileCount > 0` -- small warning/error badge for: - - `not-repository` - - `git-missing` - - `error` -- refresh action for the selected or hovered project that calls `api.refreshProjectGitContext(project.id)` - -Suggested behavior: - -- keep the row compact; do not turn it into a full card -- prefer one-line metadata in the collapsed header and more detail in an expanded/hover area if needed -- scratchpad should remain visually distinct and should not show git affordances - -### 2. Chat header / selected session context - -Primary file: `src/renderer/components/ChatPane.tsx` - -Current header already shows: - -- project name -- pattern name -- pattern mode - -Recommended additions for real projects: - -- branch name beside the project title -- dirty state chip when the repo has pending changes -- optional compact summary like: - - `3 changed` - - `2 ahead` - - `1 behind` -- optional recent commit summary tooltip/popover using `project.git.head` - -This is likely the best place to make git context feel relevant to the active conversation without overcrowding the sidebar. - -### 3. Empty/welcome state - -Primary file: `src/renderer/components/WelcomePane.tsx` - -Optional but useful: - -- update copy so project-backed sessions clearly imply branch/diff awareness -- if you add a project-management callout, mention that git state appears automatically for repositories - -### 4. App-level wiring - -Primary file: `src/renderer/App.tsx` - -The frontend agent will likely need to thread a refresh callback into whichever component gets the refresh UI, for example: - -```ts -() => void api.refreshProjectGitContext(projectId) -``` - -No extra state container is required because the workspace subscription already updates the renderer. - -## Suggested UX implementation order - -1. Add a small git metadata presentation in `Sidebar.tsx` -2. Add selected-project git context in `ChatPane.tsx` -3. Wire refresh actions from `App.tsx` -4. Add polish for non-ready states (`not-repository`, `git-missing`, `error`) - -## Edge cases the UX should handle - -- scratchpad: no git UI at all -- project added outside a git repo: show a neutral non-repo state, not a scary error -- git missing on the machine: show a helpful message, not a broken state -- detached HEAD: do not assume `branch` exists; fall back to commit short hash if useful -- brand-new repo with no commits: `head` may be absent even though the repo is valid -- upstream not configured: do not show ahead/behind placeholders -- refresh while viewing the project: avoid layout jumps; optimistic spinners are fine - -## Files most likely to change in the UX pass - -- `src/renderer/App.tsx` -- `src/renderer/components/Sidebar.tsx` -- `src/renderer/components/ChatPane.tsx` -- `src/renderer/components/WelcomePane.tsx` - -## Out of scope for this handover - -These are intentionally **not** implemented yet in backend/runtime: - -- passing git context into sidecar agent instructions -- git diff viewers or file-by-file change inspection -- branch switching or commit actions -- git-aware working sets / file pinning -- project summary generation beyond git metadata diff --git a/MCP-LSP-IMPLEMENTATION-PLAN.md b/MCP-LSP-IMPLEMENTATION-PLAN.md deleted file mode 100644 index a3b9311..0000000 --- a/MCP-LSP-IMPLEMENTATION-PLAN.md +++ /dev/null @@ -1,628 +0,0 @@ -# MCP / LSP Support Implementation Plan - -Status: implemented v1 architecture reference - -Intended execution order: - -1. Backend agent executes backend phases first. -2. Frontend agent executes frontend phases second. -3. Frontend work should begin only after the backend contracts, persistence, and diagnostics are stable. - -## Objective - -Add first-class support for MCP servers and LSP-backed project intelligence in Eryx without fighting the existing architecture. The design should preserve Eryx's current strengths: - -- Electron main as the desktop control plane -- preload + typed IPC as the renderer boundary -- shared TS contracts mirrored into the .NET sidecar -- .NET sidecar as the agent runtime -- OS keychain storage for secrets - -This plan is intentionally backend-first and split into backend/frontend task groups so different agents can execute them in order. - -The clarified product direction for v1 is: - -- users add MCPs and LSPs globally in app settings -- users enable or disable those global MCPs/LSPs per session in the right-side panel that is currently used for activity -- enabled tooling becomes available to the agent for that session - -## Current state analysis - -### Application architecture today - -- `src/main/EryxAppService.ts` - - central orchestration layer for workspace persistence, project/session lifecycle, sidecar calls, git refresh, and event emission -- `src/main/ipc/registerIpcHandlers.ts` - - single place where Electron IPC methods are registered -- `src/preload/index.ts` - - exposes the typed `eryxApi` bridge to the renderer -- `src/renderer/App.tsx` - - loads workspace + sidecar capabilities and wires subscriptions into the UI -- `src/shared/contracts/ipc.ts` - - typed renderer/main API contract -- `src/shared/contracts/sidecar.ts` - - typed main/sidecar protocol contract -- `sidecar/src/Eryx.AgentHost/Contracts/ProtocolModels.cs` - - C# mirror of the sidecar DTOs -- `sidecar/src/Eryx.AgentHost/Services/SidecarProtocolHost.cs` - - sidecar command dispatcher and capability provider -- `sidecar/src/Eryx.AgentHost/Services/CopilotWorkflowRunner.cs` - - actual agent runtime construction and activity emission - -### Signals that matter for MCP - -- `CopilotWorkflowRunner.cs` already loads `McpServerToolCallContent` via reflection and reports MCP tool names through `TryGetToolName(...)`. -- `CopilotWorkflowRunner.cs` builds a `SessionConfig` for each agent and already owns `AvailableTools`, `WorkingDirectory`, and `OnPermissionRequest`. -- Scratchpad explicitly clears `AvailableTools`, so scratchpad is currently a "no tools" product surface. - -### Signals that matter for LSP - -- `package.json` includes `typescript-language-server` and an `lsp:typescript` script, which is a good TypeScript-first bootstrap hint. -- For v1, the implemented design starts LSP processes inside the sidecar as turn-scoped tool sessions so they can surface directly as agent tools without inventing a second bridge layer. -- The current session's project root remains the source of truth for LSP initialization. - -### Persistence and secrets today - -- `src/main/persistence/workspaceRepository.ts` persists a single additive `workspace.json`. -- `src/shared/domain/workspace.ts` defines the root persisted shape. -- `src/shared/domain/session.ts` already carries session-scoped overrides such as `scratchpadConfig`, which makes it the natural place for per-session MCP/LSP enablement. -- `src/main/secrets/secretStore.ts` already wraps `keytar`, so secrets should stay in the OS keychain and never be stored in `workspace.json`. - -### Activity and diagnostics today - -- `src/shared/domain/event.ts` only exposes coarse activity today: `thinking`, `tool-calling`, `handoff`, `completed`. -- `src/renderer/components/ActivityPanel.tsx` can already show per-agent activity but not rich MCP/LSP traces. -- `src/renderer/components/CopilotStatusCard.tsx` and `SettingsPanel.tsx` already establish a diagnostics-first UX pattern worth reusing for MCP/LSP health surfaces. - -## Recommended design decisions - -### 1. Put global tooling definitions in workspace settings - -Additive, non-secret config should live in `WorkspaceState`, for example through a new `settings.tooling` section. - -Illustrative shape: - -```ts -interface WorkspaceState { - projects: ProjectRecord[]; - patterns: PatternDefinition[]; - sessions: SessionRecord[]; - selectedProjectId?: string; - selectedPatternId?: string; - selectedSessionId?: string; - lastUpdatedAt: string; - settings?: WorkspaceSettings; -} - -interface WorkspaceSettings { - tooling?: { - mcpServers?: McpServerDefinition[]; - lspProfiles?: LspProfileDefinition[]; - }; -} -``` - -Why this fits: - -- it follows the current single-workspace persistence model -- in the current architecture, that single local workspace file already behaves like the app-wide store on this computer -- it remains backward compatible because the new fields are optional -- it keeps MCP/LSP definitions reusable across future sessions - -### 2. Put enable/disable state on `SessionRecord` - -The user wants MCP/LSP enablement to be controlled per session from the right-side panel. That means the durable selection should live on `SessionRecord`, not on `ProjectRecord`. - -Illustrative shape: - -```ts -interface SessionRecord { - id: string; - projectId: string; - patternId: string; - title: string; - titleSource?: SessionTitleSource; - createdAt: string; - updatedAt: string; - status: SessionStatus; - isPinned?: boolean; - isArchived?: boolean; - messages: ChatMessageRecord[]; - lastError?: string; - scratchpadConfig?: ScratchpadSessionConfig; - tooling?: { - enabledMcpServerIds?: string[]; - enabledLspProfileIds?: string[]; - }; -} -``` - -How this should behave: - -- the settings screen owns the global registry of MCP and LSP definitions -- the session panel owns which global definitions are enabled for the current session -- the session's `projectId` provides the project root for LSP initialization when the session is project-backed -- scratchpad sessions should remain tool-free unless explicitly expanded later - -### 3. Keep secrets out of persisted JSON - -Use `src/main/secrets/secretStore.ts` for secret material. Persist only references in workspace config. - -Recommended rule set: - -- `workspace.json` stores server/profile definitions and secret references -- `keytar` stores secret values -- runtime logs, process IDs, and raw diagnostics stay out of `workspace.json` - -### 4. MCP belongs in the .NET sidecar runtime - -The sidecar already owns agent session creation, tool attachment, permission callbacks, and tool-call activity detection. MCP should build on that instead of inventing a second runtime stack in Electron or the renderer. - -Recommended flow: - -1. Electron main resolves session-enabled MCP definitions. -2. `EryxAppService.sendSessionMessage()` enriches the `run-turn` payload with runtime-ready MCP config. -3. The sidecar attaches MCP tools during `SessionConfig` creation. -4. The sidecar emits richer activity and error events back through the existing streaming channel. - -### 5. LSP process ownership should start in the sidecar for v1 - -Implemented v1 LSP ownership: - -- Electron main persists global definitions and resolves per-session selections. -- The sidecar starts the selected LSP server processes for a run, initializes them with the active project root, and exposes a focused tool surface through `AIFunction`s. -- The renderer only consumes typed config and per-session enablement state. - -Why this shipped path fits v1: - -- it keeps LSP capabilities closest to the agent tool runtime -- it avoids building a second transport bridge between Electron main and the sidecar before the tool surface is proven -- it preserves the user-facing model of "enable a tool for this session and let the agent use it" - -### 6. Prefer one user-facing tooling model - -The long-term product should not feel like "MCP over here, raw LSP over there" from a UX perspective. - -Recommended path: - -- implement direct MCP runtime support first -- implement LSP as a backend capability service second -- where feasible, expose LSP-backed actions to agents through MCP-like or tool-like abstractions instead of teaching the system two unrelated tool invocation models - -## Proposed data models - -The exact names can change, but the structure should follow these boundaries. - -### MCP definitions - -```ts -interface McpServerDefinition { - id: string; - name: string; - transport: 'stdio' | 'sse' | 'streamable-http'; - command?: string; - args?: string[]; - url?: string; - env?: McpEnvironmentBinding[]; - cwdStrategy?: 'project-root' | 'custom'; - customCwd?: string; - enabled?: boolean; -} - -interface McpEnvironmentBinding { - key: string; - valueSource: 'literal' | 'secret-ref'; - value?: string; - secretRef?: string; -} -``` - -### LSP profiles - -```ts -interface LspProfileDefinition { - id: string; - name: string; - languageIds: string[]; - transport: 'stdio'; - command: string; - args?: string[]; - initialization?: { - rootStrategy: 'project-root' | 'workspace-roots'; - initializationOptions?: Record; - }; - enabled?: boolean; -} -``` - -### Runtime diagnostics - -```ts -interface ToolingHealthSummary { - status: 'ready' | 'warning' | 'error' | 'disabled'; - summary: string; - detail?: string; - checkedAt: string; -} -``` - -Use separate summaries for: - -- workspace MCP health -- current session MCP enablement health -- LSP profile health -- current session LSP enablement health - -## Backend execution plan - -Backend must be executed first. - -### B0. Domain and persistence foundation - -Primary files: - -- `src/shared/domain/workspace.ts` -- `src/shared/domain/session.ts` -- `src/main/persistence/workspaceRepository.ts` -- `tests/shared/workspace.test.ts` -- `tests/shared/session.test.ts` - -Tasks: - -- add optional workspace-level tooling settings -- add optional session-level tooling enablement -- keep persisted migration additive and backward compatible -- ensure legacy workspaces load without mutation errors -- do not persist any secret values - -Acceptance: - -- old workspaces still load -- new fields round-trip through persistence -- tests cover legacy and new shapes - -### B1. Main-process tooling services and IPC - -Primary files: - -- `src/main/EryxAppService.ts` -- `src/shared/contracts/ipc.ts` -- `src/shared/contracts/channels.ts` -- `src/main/ipc/registerIpcHandlers.ts` -- `src/preload/index.ts` - -Recommended additions: - -- CRUD for MCP server definitions -- CRUD for LSP profiles -- session enable/disable methods for both systems -- diagnostics/status methods -- secret-reference save/delete flows that route through `SecretStore` - -Acceptance: - -- renderer gets a typed, renderer-safe API -- all config changes persist through `WorkspaceRepository` -- diagnostics can be queried without starting a session -- session enablement can be updated without mutating global definitions - -### B2. Sidecar protocol expansion for MCP - -Primary files: - -- `src/shared/contracts/sidecar.ts` -- `sidecar/src/Eryx.AgentHost/Contracts/ProtocolModels.cs` -- `sidecar/src/Eryx.AgentHost/Services/SidecarProtocolHost.cs` -- `src/main/sidecar/sidecarProcess.ts` -- `sidecar/tests/Eryx.AgentHost.Tests/SidecarProtocolHostTests.cs` - -Tasks: - -- extend capabilities with MCP availability/diagnostics -- extend `run-turn` with selected MCP runtime bindings -- optionally add dedicated MCP health validation commands if needed -- keep the protocol additive to avoid breaking existing clients - -Acceptance: - -- TS and C# contracts remain in sync -- protocol tests cover the new shapes -- existing capabilities and run-turn behavior still work without MCP config - -### B3. MCP runtime attachment in the sidecar - -Primary files: - -- `sidecar/src/Eryx.AgentHost/Services/CopilotWorkflowRunner.cs` -- new helper services under `sidecar/src/Eryx.AgentHost/Services/` -- `sidecar/tests/Eryx.AgentHost.Tests/CopilotWorkflowRunnerTests.cs` - -Tasks: - -- translate main-process MCP definitions into runtime-attached tools -- attach tools during `SessionConfig` creation -- handle startup failures and unsupported transports cleanly -- emit richer activity when tool/server identity matters -- revisit the current blanket `ApprovePermissionAsync(...)` behavior before enabling arbitrary external tools - -Acceptance: - -- project-backed runs can invoke enabled MCP tools -- tool failures surface clearly to the app -- scratchpad behavior remains intentionally restricted unless product scope changes - -### B4. LSP tool sessions in the sidecar - -Primary files: - -- `sidecar/src/Eryx.AgentHost/Services/LspToolSession.cs` -- `sidecar/src/Eryx.AgentHost/Services/SessionToolingBundle.cs` -- `package.json` -- `sidecar/tests/Eryx.AgentHost.Tests/*` - -Tasks: - -- start selected LSP server processes inside the sidecar for the active run -- initialize them against the current session project root -- expose a focused read-oriented tool surface to agents -- keep lifecycle cleanup bound to the run/session bundle -- start with TypeScript-first support - -Acceptance: - -- a project-backed session can initialize at least one supported LSP profile -- agents can call the exposed LSP tools without any renderer-managed process lifecycle -- no raw LSP JSON-RPC is exposed to the renderer - -### B5. LSP bridge into agent runtime - -Primary files: - -- `src/main/EryxAppService.ts` -- `src/shared/contracts/sidecar.ts` -- `sidecar/src/Eryx.AgentHost/Contracts/ProtocolModels.cs` -- `sidecar/src/Eryx.AgentHost/Services/SessionToolingBundle.cs` -- `sidecar/src/Eryx.AgentHost/Services/LspToolSession.cs` - -Tasks: - -- compose selected LSP profiles into the `run-turn` payload from Electron main -- translate those profiles into sidecar-local tool sessions -- expose a stable subset of LSP-backed operations to agents -- avoid turning the renderer into a second IDE protocol stack - -Recommended direction: - -- use sidecar-local `AIFunction` tools for agent consumption -- keep the exposed operations narrow and project-oriented - -Acceptance: - -- agents can request useful LSP-backed project intelligence during project runs -- the contract is observable and testable from the app side - -### B6. Backend hardening and validation - -Primary files: - -- impacted TS and C# tests -- `package.json` - -Validation commands: - -- `bun test` -- `bun run sidecar:test` -- `bun run build` - -Hardening checklist: - -- additive migration coverage -- bad configuration/error reporting coverage -- environment sanitization review for spawned tools/servers -- sidecar protocol regression coverage - -## Frontend execution plan - -Frontend should start only after backend APIs and diagnostics are stable. - -### F1. Read-only diagnostics surfaces - -Primary files: - -- `src/renderer/App.tsx` -- `src/renderer/components/SettingsPanel.tsx` -- `src/renderer/components/CopilotStatusCard.tsx` - -Tasks: - -- add MCP and LSP sections in settings -- surface backend-reported health, readiness, and counts -- reuse the current diagnostics-card style before introducing complex editors - -Acceptance: - -- users can see whether MCP/LSP are configured and healthy -- failures are understandable without opening logs - -### F2. Global configuration editors - -Primary files: - -- `src/renderer/components/SettingsPanel.tsx` -- new renderer components for MCP/LSP editors -- `src/renderer/App.tsx` - -Tasks: - -- create/edit/delete MCP server definitions -- create/edit/delete LSP profiles -- manage secret references safely -- do not mix global definition editing with per-session toggles -- allow secret references without ever echoing raw secrets back into the renderer state - -Acceptance: - -- all backend CRUD flows are reachable through the UI -- global definitions are understandable and recoverable - -### F3. Session tooling panel controls - -Primary files: - -- `src/renderer/components/ActivityPanel.tsx` -- `src/renderer/App.tsx` -- supporting renderer state/helpers - -Tasks: - -- extend the current right-side activity panel with MCP/LSP enable/disable controls for the selected session -- show which global tools are available vs enabled for the session -- disable LSP/MCP controls when the selected session cannot use them, such as scratchpad if that restriction remains -- surface lightweight health/state next to each toggle - -Acceptance: - -- users can enable or disable global MCPs/LSPs per session from the right-side panel -- session toggles are persisted on the session record and survive app reloads - -### F4. Runtime visibility in chat/activity surfaces - -Primary files: - -- `src/renderer/components/ActivityPanel.tsx` -- `src/renderer/lib/sessionActivity.ts` -- `src/shared/domain/event.ts` -- possibly `src/renderer/components/ChatPane.tsx` - -Tasks: - -- show tool server name + tool name clearly -- distinguish MCP activity from LSP-backed activity if both appear -- show meaningful failure summaries -- leave room for a future richer timeline without blocking this phase - -Acceptance: - -- users can tell what tool/server was used during a run -- failures do not collapse into generic "tool-calling" noise - -### F5. Session-level polish and troubleshooting UX - -Primary files: - -- `src/renderer/components/ActivityPanel.tsx` -- `src/renderer/components/ChatPane.tsx` -- any supporting session detail surfaces - -Tasks: - -- show current session tooling status clearly -- add "why unavailable?" and "fix configuration" entry points -- optionally add compact badges or chips for active MCP/LSP selections - -Acceptance: - -- session-scoped tooling is visible without leaving the main workflow -- troubleshooting paths are discoverable - -## Handoff between backend and frontend agents - -### Backend agent handoff deliverables - -The backend pass should hand off: - -- finalized shared domain shapes -- finalized IPC contract -- finalized sidecar contract changes -- clear diagnostics payloads -- scratchpad/tool policy behavior -- finalized session enablement state shape -- test coverage for persistence, protocol, and runtime behavior - -### Frontend agent prerequisites - -The frontend agent should not start until it has: - -- stable backend CRUD endpoints -- stable health/diagnostic payloads -- stable activity event shapes -- at least one working MCP path and one working LSP profile path to design against -- stable session enable/disable semantics for the right-side panel - -## Risks and decisions to settle early - -### A. Define what "LSP support" means in v1 - -This is the biggest scope decision. Options include: - -- agent-facing project intelligence only -- agent-facing intelligence plus light read-only diagnostics in the UI -- a much larger editor-like in-app LSP experience - -Recommended default: - -- agent-facing project intelligence first -- diagnostics UI second -- editor-like UX later - -### B. Decide the scratchpad policy - -Current behavior is strongly tool-free. Keep that default unless product scope explicitly changes. - -### C. Decide the default session behavior - -Need to decide whether new sessions start with: - -- no MCPs/LSPs enabled by default -- a safe recommended subset enabled by default -- the same enablement as the previously selected session - -Recommended default: - -- start disabled by default until a session explicitly enables a tool - -### D. Decide provisioning and trust - -Need explicit decisions for: - -- bundled vs user-installed MCP/LSP servers -- which transports are allowed in v1 -- whether arbitrary commands are allowed -- whether write-capable tools need approval -- whether LSP starts TypeScript-only first - -### E. Decide the approval/safety model - -`ApprovePermissionAsync(...)` currently auto-approves. That is not a sufficient trust model for arbitrary MCP tooling. A v1 safety story is needed before enabling broad external tool execution. - -### F. Decide observability depth - -Current activity events are coarse. MCP/LSP may require richer activity or trace events to stay understandable. - -## Recommended sequencing summary - -1. B0: persisted vocabulary and migration-safe shapes -2. B1: main-process API and diagnostics -3. B2: sidecar protocol expansion -4. B3: MCP runtime support -5. B4: Electron-main LSP service -6. B5: LSP bridge into agent runtime -7. F1-F5: frontend diagnostics, global editors, session toggles, visibility, and polish - -## Out of scope for the first implementation pass - -- a full IDE/editor inside Eryx -- raw LSP transport in the renderer -- persisted secret values in workspace files -- broad packaging/install automation for every possible LSP/MCP ecosystem on day one - -## Suggested validation gate before frontend begins - -Before handing to the frontend agent, the backend agent should be able to demonstrate: - -- additive workspace persistence for MCP/LSP config -- at least one working MCP-backed agent flow in a project session -- one initialized, health-reporting LSP profile in Electron main -- per-session enable/disable persistence for selected MCPs/LSPs -- stable diagnostics payloads exposed to the renderer -- passing `bun test`, `bun run sidecar:test`, and `bun run build`