EasyMod VS Code Extension
VS Code sidebar chat extension for EasyMod backend gateway APIs.
What It Does
- Adds an
EasyMod Activity Bar view with a webview chat panel.
- Sends chat requests through backend
POST /api/vscode/send (including streaming).
- Supports extension sign-in with auth code exchange + refresh token flow.
- Supports organization-aware requests (
org_id) and model loading.
- Chat model dropdown includes an Auto option (sends
model: "auto"; backend performs
routing selection) alongside concrete models; a small resolved-model badge is shown on
assistant messages that were answered by an Auto turn. Auto is currently withheld for the
Grok provider — a Grok Auto turn loses the patch card, so pick a concrete Grok model for
edit requests until the gateway fix lands.
- Provider dropdown is dynamic: it lists every provider the backend's model list actually
returns (e.g. OpenAI, Anthropic, DeepSeek, Gemini, Grok), with an Auto option always
first — no provider needs a code change to show up once the backend serves its models.
- Includes local workspace tool loop (
rg, file read, file list) for retrieval-style workflows.
In a multi-root workspace, a bare rg search (no path argument) now searches EVERY open
workspace root, not just the first — matches from a non-primary root come back prefixed with
that root's folder name.
- Adds persistent workspace memory index (
.easymod/workspace-memory.json) for cross-language symbol/impact recall between turns. Remembered file content is validated against disk each time it's
reused: a changed file is re-read and refreshed automatically, and a removed file is dropped
from memory, so the assistant no longer quotes a file's pre-edit content back at you. Reused
session context snippets (the per-conversation context ledger) are validated the same way and
are dropped when the file no longer matches. In a multi-root workspace, a file read from any
open folder is remembered under THAT folder's own memory snapshot (not always the primary
root). Later turns rank remembered chunks across every open root under one global six-chunk /
token budget, then validate only the globally selected files against their owning roots. Once
per session each root's snapshot is also swept to drop entries that can no longer be resolved.
- Supports assistant patch preview/apply from unified diff output with workspace safety checks,
replay protection, and preservation of existing CRLF/LF line endings.
- Supports multiple local chat sessions (new/switch/rename/delete/clear).
- Keeps in-flight assistant streaming alive across Activity Bar/sidebar switches by retaining and rehydrating the chat webview state.
Requirements
- VS Code
^1.90.0
- Node/npm for build and test
- EasyMod backend reachable from
easymod.apiUrl
Setup
npm install
npm run compile
For development:
npm run watch
Run extension in Extension Development Host with F5.
Test
npm test
This rebuilds out/ and runs Node tests from compiled output (out/test/**/*.test.js) if present.
npm run compile runs the TypeScript strict compile check.
npm run watch keeps TypeScript compiling during extension development.
npm test runs the repository safety gates (check-db-safety, check-test-suite), rebuilds out/, and then runs the compiled Node test suite.
Commands
EasyMod: Open Chat Panel
EasyMod: Focus Chat View
EasyMod: Sign In
EasyMod: Sign Out
EasyMod: Switch Organization
EasyMod: Set Manual JWT Session
EasyMod: Toggle Full File Access
Settings (easymod.*)
Core connection/auth:
apiUrl (default: https://backend.easymodularity.com)
model (default: empty; uses the EasyMod default chat model)
defaultOrgId (default: empty)
extensionAuthBridgeUrl (default: https://easymodularity.com/extension-auth/bridge/start; set empty to use <apiUrl>/extension-auth/bridge/start)
extensionId (default: empty)
mcpJson (default: empty JSON string field)
Context and prompt assembly:
includeSelection (default: true)
includeWholeFile (default: false)
contextMode (focused | fullActiveFile, default: focused)
maxContextChars (default: 32000)
maxPromptChars (default: 52000)
reservedResponseChars (default: 12000)
maxPromptTokens (default: 32000)
maxContextTokens (default: 12000)
reservedResponseTokens (default: 4000)
historyMaxTokens (default: 3000)
memorySummaryMaxTokens (default: 800)
Retrieval and memory behavior:
contextLedgerEnabled (default: true)
contextLedgerMaxEntries (default: 24)
minRelevanceScore (default: 24)
retrievalChunkLines (default: 80)
retrievalChunkOverlapLines (default: 8)
retrievalMaxFiles (default: 80)
retrievalMaxSnippets (default: 3)
retrievalPerFileCharLimit (default: 120000)
maxToolResultChars (default: 30000)
Patch and tooling behavior:
autoApplyPatchWithConfirmation (default: true, legacy/unused)
enableWorkspaceToolLoop (default: true)
commandLoopEnabled (default: true)
commandLoopMaxRetries (default: 2)
commandExecTimeoutMs (default: 120000)
alwaysAutoRunCommands (default: false)
autoRunProjectStartup (default: false)
fullFileAccess (default: false)
enableDeveloperDebugPage (default: false)
apiKey is legacy/unused in JWT backend mode.
Patch flow notes:
fullFileAccess: true means new assistant patches auto-apply, and it also turns on trusted command auto-run plus startup auto-run.
fullFileAccess: false means new assistant patches stay in preview mode until manually applied from the latest patch card.
- Replaying an already-satisfied patch is reported as already applied without rewriting the
file; a structurally new diff can still intentionally repeat content. Existing CRLF/LF files
keep their line-ending convention through patch writes.
- When a prompt explicitly names a target workspace root (e.g.
in easymod-api workspace, … or in easymod-api, create …) and that name matches no existing root, auto-apply is blocked before any patch is applied; the extension surfaces the available roots and asks you to re-send.
alwaysAutoRunCommands: true skips the manual confirmation dialog only for trusted command runs that pass the extension policy.
autoRunProjectStartup: true lets EasyMod auto-start exactly one trusted startup command after prompts like "serve this project", "run this app", or natural variants such as "help me serve it". Auto-run is now allowlist-based: only common local startup commands such as npm run dev, npm start, npx serve, npx http-server, python -m http.server, php artisan serve, vite, and similar dev-server patterns qualify. Before launching a long-running startup command in the terminal, EasyMod now performs a short startup probe. If the command fails immediately, the captured stderr/stdout is fed into the command repair loop instead of being lost in terminal-only output. It still skips auto-run when there are multiple commands, the command is not startup-like, the command is outside the trusted auto-run allowlist, or a patch is still waiting for manual apply. The terminal working directory is anchored at the workspace root whose basename matches the command's leading cd <target> prefix, and the redundant root-name segment is stripped from the cd before the command is sent to the terminal (e.g. cd easymod-api/calculator && npm run dev spawns in the easymod-api root and sends cd calculator && npm run dev; bare-root cd easymod-api && npm run dev drops the cd entirely and sends npm run dev). Commands with no cd prefix or an unrecognized first segment fall back to the active-editor folder or the first workspace folder, and are sent verbatim.
Local Dev Tip
For local development against a local backend/frontend, use workspace overrides in .vscode/settings.json instead of changing defaults in package.json.
Example:
{
"easymod.apiUrl": "http://127.0.0.1:8010",
"easymod.extensionAuthBridgeUrl": "https://easymodularity.com/extension-auth/bridge/start",
"easymod.autoRunProjectStartup": true,
"easymod.fullFileAccess": false,
"easymod.enableDeveloperDebugPage": true
}
Notes
- Backend remains source of truth for auth, org access, and request handling.
- Extension-side tool loop and context assembly are configurable and can be disabled.
- Patch writes are guarded by workspace boundary checks and optional confirmation.
- In-flight assistant streams continue in the extension host even if the EasyMod sidebar is temporarily hidden; reopening the view rehydrates the current streamed text instead of starting from a blank panel.
Stream Log Semantics
chat stream chunk means raw bytes/chunks were read from backend SSE/stream transport.
assistant delta received means user-visible assistant text delta was emitted into the extension turn pipeline.
ui first flush is tied to the first assistant delta received, not the first chat stream chunk.
- In tool-loop or multi-turn synthesis flows,
chat stream chunk can appear long before first UI flush.
Example A (small-talk, fast path):
chat stream chunk at ~5ms
assistant delta received at ~600ms
ui first flush immediately after first delta
Example B (tool-loop heavy prompt):
- early
chat stream chunk events appear quickly (transport is active)
- multiple loop/follow-up turns happen
- first
assistant delta received may appear much later (for example 50s+)
ui first flush then occurs right after that first assistant delta
| |