From e6ac35160d28a3b53aa3bf60464b4f652f512436 Mon Sep 17 00:00:00 2001 From: ru-sh Date: Tue, 22 Sep 2026 01:46:52 +0400 Subject: [PATCH] Add Claude Code project instructions --- .claude/settings.json | 17 ++++++++ .claude/skills/e2e/SKILL.md | 63 ++++++++++++++++++++++++++++ .claude/skills/vscode-patch/SKILL.md | 52 +++++++++++++++++++++++ CLAUDE.md | 43 +++++++++++++++++++ 4 files changed, 175 insertions(+) create mode 100644 .claude/settings.json create mode 100644 .claude/skills/e2e/SKILL.md create mode 100644 .claude/skills/vscode-patch/SKILL.md create mode 100644 CLAUDE.md diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000000..b60d08ae46ce --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,17 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "jq -r '.tool_input.file_path // .tool_response.filePath // empty' | { read -r f; [ -n \"$f\" ] && [ -f \"$f\" ] && \"${CLAUDE_PROJECT_DIR:-.}/node_modules/.bin/prettier\" --write --ignore-unknown --log-level=warn \"$f\"; } 2>/dev/null || true", + "timeout": 30, + "statusMessage": "prettier" + } + ] + } + ] + } +} diff --git a/.claude/skills/e2e/SKILL.md b/.claude/skills/e2e/SKILL.md new file mode 100644 index 000000000000..7bd5d4cf80c4 --- /dev/null +++ b/.claude/skills/e2e/SKILL.md @@ -0,0 +1,63 @@ +--- +name: e2e +description: Build and run code-server's Playwright e2e tests. Use when e2e verification is explicitly requested — the suite needs built artifacts first and is slow, so it is never the default verification (prefer npm run test:unit). +--- + +# E2E tests (Playwright) + +E2E runs against a **build**, not raw source. Only **Chromium** is enabled (Firefox/WebKit projects are disabled in `test/playwright.config.ts` due to known bugs). + +## One-time setup + +```bash +cd test && npm install && cd .. # also done by root postinstall +./test/node_modules/.bin/playwright install --with-deps chromium +``` + +## Build requirements + +`test-e2e.sh` sanity-checks for `out/` (TS build) and `lib/vscode/out` (VS Code build) and exits with help text if either is missing: + +```bash +git submodule update --init # if lib/vscode is empty +quilt push -a # if patches not yet applied +npm install +npm run build # TS -> out/ (fast) +VERSION=0.0.0 npm run build:vscode # very slow +``` + +## Run + +Unset `CODE_SERVER_TEST_ENTRY` tests the repo root build — the normal local loop: + +```bash +npm run test:e2e +``` + +To test a packaged release instead (what CI does): + +```bash +KEEP_MODULES=1 VERSION=0.0.0 npm run release +CODE_SERVER_TEST_ENTRY=./release npm run test:e2e +``` + +Useful variations (args pass through to Playwright): + +```bash +npm run test:e2e -- --grep login +npm run test:e2e -- --workers 1 +PWDEBUG=1 npm run test:e2e # Playwright inspector +``` + +## Iteration cheatsheet + +- Server-only change (`src/**`): re-run `npm run build` (fast), rerun tests — no VS Code rebuild needed. With `CODE_SERVER_TEST_ENTRY=./release` you must re-run `release` instead, so prefer the unset form while iterating. +- Patch / `lib/vscode` change: full `build:vscode` again. +- Test-extension changes: `test/e2e/extensions/test-extension` is rebuilt automatically by the runner. + +## Notes + +- Global setup (`test/utils/globalE2eSetup.ts`) pre-authenticates and creates temp `CODE_WORKSPACE_DIR` / `CODE_FOLDER_DIR`; reuse the page-object models in `test/e2e/models/` instead of raw selectors. +- CI runs with 60s timeout, 2 retries, video retained on failure, against `./release`. +- `npm run test:e2e:proxy` runs the suite behind Caddy (`ci/Caddyfile`) with `USE_PROXY=1`. +- New patches to VS Code require an accompanying e2e test (see `/vscode-patch`). diff --git a/.claude/skills/vscode-patch/SKILL.md b/.claude/skills/vscode-patch/SKILL.md new file mode 100644 index 000000000000..64c9ea22c60a --- /dev/null +++ b/.claude/skills/vscode-patch/SKILL.md @@ -0,0 +1,52 @@ +--- +name: vscode-patch +description: Create or modify code-server's quilt patches against the lib/vscode submodule. Use when changing VS Code behavior (marketplace, auth, telemetry, CSP, webviews...) or when a task would edit files under lib/vscode. +--- + +# Patching VS Code (quilt stack) + +All customizations to VS Code live in `patches/*.diff`, applied to the `lib/vscode` submodule with quilt. Never edit files under `lib/vscode` directly — untracked edits there are lost and can't be shared. + +## Before you start + +- The submodule must be initialized (`git submodule update --init`) and the stack applied (`quilt push -a`). +- Check the current stack state with `quilt top` / `quilt series` — quilt applies patches in `patches/series` order and only the top patch can absorb new edits. +- Reuse an existing patch when extending its concern (e.g. marketplace.diff for Open VSX changes); create a new one only for a new concern. + +## Workflow + +1. Push the stack to the patch you're extending, or create a new one at the top: + ``` + quilt push -a # apply everything first + quilt new {name}.diff # new patch (name matches its concern) + ``` +2. **Register every file before editing it** — quilt will not track edits to unregistered files: + ``` + quilt add [-P {patch}] lib/vscode/path/to/file.ts + quilt edit lib/vscode/path/to/file.ts # optional shorthand for add+edit + ``` +3. Make the changes in `lib/vscode/...`. +4. Capture/refresh the diff: + ``` + quilt refresh + ``` +5. Add a comment at the top of the `.diff` explaining **why the patch exists and how to reproduce the behavior it fixes or adds**. Look at existing patches in `patches/` for the expected format. +6. Every patch needs an e2e test (see the `/e2e` skill for how to build and run them). + +## Rules + +- Patches may depend on lower patches, but **every intermediate state of the stack must produce a working code-server** — no broken in-between states. +- The patch stack ordering in `patches/series` matters; don't reorder casually. +- Verify the stack still applies cleanly from scratch: `quilt pop -a && quilt push -a`. + +## After pulling changes that touch patches + +If a patch no longer applies (e.g. after a VS Code version bump): + +1. Apply as many as possible: `quilt push -a` +2. On a conflict: `quilt push -f`, manually restore the rejected hunks in the file, then `quilt refresh` +3. Repeat until the full stack applies. + +## After changing a patch + +Rebuild to verify: patches affect the VS Code build, so a full `VERSION=0.0.0 npm run build:vscode` (very slow) plus release build is needed for e2e. Unit tests (`npm run test:unit`) don't cover VS Code internals — server-side behavior changes in `src/` are what unit tests catch. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000000..37b316140609 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,43 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +code-server runs VS Code on a remote server, accessed in the browser. TypeScript Node server lives in `src/` (`node/` server, `browser/` static login/error assets, `common/` shared). VS Code itself is a git submodule at `lib/vscode`, customized by a quilt-managed patch stack in `patches/` (`patches/series` is the stack order). + +This is a downstream fork: PRs target `MotusLabs/code-server` (not coder/code-server) and are squashed into `main`. Commit messages are plain imperative summaries. Claude's commits stay unsigned — the user signs before pushing. + +## Setup (order matters) + +1. `git submodule update --init` — `lib/vscode` must exist before `npm install` (postinstall installs its deps; `SKIP_SUBMODULE_DEPS=1` skips that slow step) +2. `quilt push -a` — applies the patch stack +3. `npm install` +4. `npm run watch` — dev server at http://localhost:8080 + +"Forbidden access" in the browser means patches didn't apply: `quilt pop -a && quilt push -a`. + +npm only — `preinstall` throws under yarn. Node 24 (`.node-version`; the flake.nix `nodejs_22` pin is stale). + +## Commands + +- `npm run build` — compiles TS to `out/` +- `npm run test:unit` — jest; the default verification for changes. Single file: `npm run test:unit -- test/unit/node/cli.test.ts` (add `--coverage=false` to skip the 60% coverage gate). `npm run test` is intentionally not a script. +- e2e requires a full release build first and is slow — run only when explicitly asked (`/e2e` skill) +- `npm run lint:ts` — eslint `--max-warnings=0` over tracked ts/js, excluding `lib/vscode` +- `npm run lint:scripts` — shellcheck over tracked shell scripts +- `npm run prettier` — format; CI enforces `npx prettier --check .` +- `npm run fmt` — prettier + doctoc (regenerates docs TOCs; CI fails if they drift) +- `npm run build:vscode` / `npm run release` — require the `VERSION` env var (e.g. `VERSION=0.0.0 npm run build:vscode`); VS Code builds take a very long time + +## Style + +- Prettier (enforced): printWidth 120, **no semicolons**, trailing commas everywhere, double quotes. +- ESLint: `eqeqeq` required; `import/order` alphabetized. `no-explicit-any`, `no-non-null-assertion` etc. are off. +- Never edit files under `lib/vscode` directly — changes there go through quilt patches (`/vscode-patch` skill). + +## Patches (patches/*.diff) + +`quilt new {name}.diff` → `quilt add {file}` (mandatory before editing) → edit → `quilt refresh`. Each patch needs a comment explaining the reason and reproduction, plus an e2e test. Patches may depend on each other, but every intermediate state of the stack must yield a working code-server. User-facing changes should update CHANGELOG.md under `## Unreleased` (Keep-a-Changelog format). + +i18n/display languages only work in full builds, not `npm run watch` dev mode.