AGENTS.md
July 9, 2026 · View on GitHub
Agent reference for the @vscode-adblock-syntax/client package: the VSCode
extension entry point and Language Server Protocol (LSP) client.
This is part of a monorepo. For repo-wide conventions (dependency management, Markdown formatting, versioning, contribution rules) see the root AGENTS.md. For environment setup see DEVELOPMENT.md.
Table of Contents
- Project Overview
- Technical Context
- Project Structure
- Contribution Instructions
- Code Guidelines
- Related Agents
Project Overview
The client is the VSCode-facing half of the extension. It activates the extension, spins up one language client (and a separate server process) per outermost workspace folder, manages their lifecycle, mirrors AGLint status in the status bar, and forwards document/configuration events to the server over LSP. It holds all direct VSCode API access; linting logic lives in the server.
Technical Context
- Language/Version: TypeScript targeting
ESNext(see tsconfig.base.json),strictmode. - Runtime: VSCode extension host (Node.js), VSCode
^1.74.0. - Primary Dependencies:
vscode-languageclient(LSP client),@vscode-adblock-syntax/shared(shared types),valibot(validation),vscodeAPI (provided by the host). - Storage: None — in-memory maps of clients and per-folder status.
- Testing: Vitest, with a mocked
vscodemodule. - Build: Rspack, output to
out/(rootpackage.jsonmainpoints to./client/out/extension). - Project Type: monorepo package (VSCode extension entry).
Project Structure
client/
├── package.json # Package manifest and scripts
├── rspack.config.ts # Bundler config (output to out/)
├── src/
│ ├── extension.ts # Entry point: activate/deactivate, LSP client lifecycle
│ ├── constants.ts # Client IDs, language ID, file extensions, status bar config
│ ├── workspace-folders.ts # Outermost-folder resolution, file-in-folder checks
│ └── utils/
│ ├── log-level.ts # Maps VSCode log level → AGLint debug flag
│ └── status-parser.ts # Parses aglint/status notification params
└── tests/
├── __mocks__/vscode.ts # Mock VSCode API for tests
├── workspace-folders.test.ts
└── utils/ # Unit tests mirroring src/utils
Contribution Instructions
After completing a task, you MUST do the following:
- Verify your changes with the linter and type checker:
pnpm --filter @vscode-adblock-syntax/client exec tsc --noEmitfor type errors.pnpm --filter @vscode-adblock-syntax/client lint:code(add--fixto auto-fix) for ESLint.pnpm --filter @vscode-adblock-syntax/client lint:mdfor Markdown.
- Update or add Vitest unit tests for any changed code.
- Run
pnpm --filter @vscode-adblock-syntax/client testand ensure all tests pass. - When you change this package's structure, update the Project Structure section above.
- If a prompt asks you to refactor or improve code, capture the lesson as a guideline under Code Guidelines.
- Verify new code follows these Code Guidelines and the root AGENTS.md.
Code Guidelines
System Design
Design for the VSCode extension host:
- Keep all VSCode API usage in this package; never duplicate it in the server.
- Communicate with the server only over LSP (requests, notifications, middleware). Do not share mutable state across the process boundary.
- Create one client/server pair per outermost workspace folder (use
getOuterMostWorkspaceFolder); a dedicated default client handles untitled documents. Dispose clients and their stored status when a folder is removed. - React to events (document open/change/save, active editor change, workspace folder change, log-level change) asynchronously; never block the extension host.
- Keep activation fast and the bundle small; defer heavy work to the server process.
Architecture
The client is a thin VSCode integration layer. Principles:
- Separation of Concerns —
extension.tsorchestrates lifecycle;workspace-folders.tshandles folder math;utils/handles pure transformations (log level, status parsing). - Single Responsibility — keep pure helpers (status parsing, log-level mapping) free of VSCode API calls so they stay unit-testable.
- Dependency Direction — depend only on
vscode,vscode-languageclient, and@vscode-adblock-syntax/shared; never import fromserver. - Explicit Boundaries — the only channel to the server is LSP; the only channel to the user is the VSCode API (status bar, output channels).
- Data Flow Clarity — document events → middleware filter (file-in-folder)
→ server;
aglint/statusnotifications → status bar. - Make Invalid States Impossible — validate notification payloads
(
parseStatusParams) before using them. - Observability Built-in — each client gets a VSCode
LogOutputChannel, making it visible under "Developer: Set Log Level".
Layers:
| Layer | Responsibility | Example |
|---|---|---|
| Activation/lifecycle | Create, start, dispose clients | src/extension.ts |
| Workspace logic | Outermost folder, file containment | src/workspace-folders.ts |
| Pure utilities | Log level, status parsing | src/utils/status-parser.ts |
Dependency flow:
flowchart LR
extension["extension.ts (VSCode API + LSP client)"] --> workspace["workspace-folders.ts (pure)"]
extension --> utils["utils/* (pure)"]
extension --> shared["@vscode-adblock-syntax/shared (FileScheme, types)"]
Code Quality
- Follow the root Code Quality rules: required JSDoc, 4-space indent, max line length 120, grouped/alphabetized imports, inline type imports.
- Keep VSCode API calls out of pure helpers so they can be tested with the
mocked
vscodemodule. - Swallow only expected errors (e.g. notifications sent before the server is ready) and document why.
Testing
- Vitest tests live in tests/ and mirror
src/. - The VSCode API is mocked in tests/__mocks__/vscode.ts; pure helpers are tested directly.
- Add tests for new folder-resolution logic, status parsing, and log-level mapping. All tests must pass before completing a task.
Dependency Management
Follow the root Dependency Management
rules. Add dependencies via the workspace catalog; keep the client bundle
small because its size affects extension activation time.
Configuration & Documentation
- The client reads VSCode settings indirectly: it passes initialization options
(workspace folder, debug flag) to the server, which fetches
adblock.*settings. Update src/constants.ts when IDs, watched file patterns, or supported extensions change. - When the client/server protocol or activation behavior changes, update this file and the root AGENTS.md.
Markdown Formatting
Follow the root Markdown Formatting rules (max line length 120, dash bullets, 4-space nested indent, asterisk emphasis, limited inline HTML).
Related Agents
- Root: AGENTS.md
- Server: server/AGENTS.md
- Shared: shared/AGENTS.md