mirror of
https://github.com/davidkaya/aryx.git
synced 2026-07-24 21:48:36 +02:00
docs: remove old plans
This commit is contained in:
-204
@@ -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<WorkspaceState>;
|
||||
```
|
||||
|
||||
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
|
||||
@@ -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<string, unknown>;
|
||||
};
|
||||
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`
|
||||
Reference in New Issue
Block a user