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

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), strict mode.
  • Runtime: VSCode extension host (Node.js), VSCode ^1.74.0.
  • Primary Dependencies: vscode-languageclient (LSP client), @vscode-adblock-syntax/shared (shared types), valibot (validation), vscode API (provided by the host).
  • Storage: None — in-memory maps of clients and per-folder status.
  • Testing: Vitest, with a mocked vscode module.
  • Build: Rspack, output to out/ (root package.json main points 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 --noEmit for type errors.
    • pnpm --filter @vscode-adblock-syntax/client lint:code (add --fix to auto-fix) for ESLint.
    • pnpm --filter @vscode-adblock-syntax/client lint:md for Markdown.
  • Update or add Vitest unit tests for any changed code.
  • Run pnpm --filter @vscode-adblock-syntax/client test and 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 Concernsextension.ts orchestrates lifecycle; workspace-folders.ts handles 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 from server.
  • 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/status notifications → 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:

LayerResponsibilityExample
Activation/lifecycleCreate, start, dispose clientssrc/extension.ts
Workspace logicOutermost folder, file containmentsrc/workspace-folders.ts
Pure utilitiesLog level, status parsingsrc/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 vscode module.
  • 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).