diff --git a/.claude/skills/fix/SKILL.md b/.claude/skills/fix/SKILL.md new file mode 100644 index 0000000..01f8b7f --- /dev/null +++ b/.claude/skills/fix/SKILL.md @@ -0,0 +1,14 @@ +--- +name: fix +description: Auto-fix all lint, formatting, and copyright header issues across the workspace. Use when validation (`/verify`) fails or when explicitly requested. +--- + +Run the full auto-fix suite for the GLSP dev-packages monorepo from the repository root: + +```bash +yarn fix:all +``` + +This runs `yarn lint:fix && yarn format && yarn headers:fix` in sequence. + +After fixing, report what changed. If any issues remain that couldn't be auto-fixed, list them and suggest manual fixes. diff --git a/.claude/skills/verify/SKILL.md b/.claude/skills/verify/SKILL.md new file mode 100644 index 0000000..91785ca --- /dev/null +++ b/.claude/skills/verify/SKILL.md @@ -0,0 +1,18 @@ +--- +name: verify +description: Run full project validation (lint, format, copyright headers) to catch issues before committing. IMPORTANT - Proactively invoke this skill after completing any code changes (new features, bug fixes, refactors) before reporting completion to the user. +--- + +Run the full validation suite for the GLSP dev-packages monorepo from the repository root: + +```bash +yarn check:all +``` + +This runs `yarn install && yarn lint && yarn format:check && yarn headers:check` in sequence. + + +On failure: +1. Report which check failed and the specific errors +2. Auto-fix by invoking the `/fix` skill +3. Re-run `yarn check:all` to confirm everything passes diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93251a6..5ffd43c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - node-version: 20.x + node-version: 22.x - name: Build run: yarn install - name: Check for uncommitted changes in yarn.lock @@ -36,7 +36,7 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - node-version: 20.x + node-version: 22.x - name: Install run: | yarn install diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 85bcbea..f5271ee 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -84,7 +84,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - node-version: 20 + node-version: 22 - name: Set up Java 21 if: >- diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 995937c..fdbefcc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -67,7 +67,7 @@ jobs: - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 if: steps.check_changes.outputs.should_publish == 'true' with: - node-version: 20.x + node-version: 22.x registry-url: 'https://registry.npmjs.org' - name: Build diff --git a/AGENTS.md b/AGENTS.md index 04356cc..e0fec5f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,51 +1,12 @@ -# Repository Guidelines +# AGENTS.md -## Project Structure & Module Organization +## Project Overview -This repository is a Yarn workspaces monorepo for shared GLSP development tooling. +Eclipse GLSP shared development tooling monorepo. Contains reusable dev packages (ESLint config, Prettier config, TypeScript config, CLI tools) published to npm under `@eclipse-glsp/*`. This is **not** the GLSP runtime — it provides build/lint/format configurations consumed by other GLSP repositories (glsp-client, glsp-server-node, glsp-theia-integration, etc.). -- `dev-packages/*`: publishable workspace packages (`cli`, `config`, `config-test`, `eslint-config`, `mocha-config`, `nyc-config`, `prettier-config`, `ts-config`, `dev`). -- `dev-packages/cli/src`: TypeScript sources for the `glsp` CLI (`commands/` and `util/`). -- `.github/workflows`: CI, release, and publishing workflows. -- `docker/` and `releng/`: container and release-engineering assets. -- Root configs: `eslint.config.mjs`, `tsconfig*.json`, `.prettierrc`, `lerna.json`. +## Build & Development -## Build, Test, and Development Commands - -Use Node `>=20` and Yarn classic (`>=1.7.0 <2`). - -- `yarn install`: install dependencies and build via `prepare`. -- `yarn build`: run `lerna run build` across workspaces. -- `yarn watch`: watch CLI bundle changes. -- `yarn lint` / `yarn lint:fix`: run ESLint (or auto-fix). -- `yarn format` / `yarn format:check`: apply/check Prettier formatting. -- `yarn check:headers`: verify copyright headers against git history. -- `yarn check:pr`: CI-style local gate (`install`, lint, format check, headers). - -## Coding Style & Naming Conventions - -- Language: TypeScript for source code. -- Formatting: Prettier (`.prettierrc`) with 4-space indentation, single quotes, no trailing commas, LF line endings. -- JSON/YAML formatting uses 2-space indentation. -- Linting: ESLint flat config (`eslint.config.mjs`) with GLSP shared rules. -- Naming: keep command implementations in `dev-packages/cli/src/commands/*.ts`; shared helpers in `dev-packages/cli/src/util/*.ts`. - -## Testing Guidelines - -There is currently no root `test` script in this repository. Validate contributions with: - -- `yarn build` -- `yarn lint` -- `yarn format:check` -- `yarn check:headers` - -For new testable packages, use GLSP shared test config (`@eclipse-glsp/config-test`) and Mocha/nyc conventions (`*.spec.ts`, coverage via `test:coverage`). - -## Commit & Pull Request Guidelines - -- Open an issue in `https://github.com/eclipse-glsp/glsp` before coding. -- Branch naming: `issues/` (example: `issues/123`). -- Commit messages: imperative subject; issue references are expected (examples in history include `GLSP-1594: ... (#1596)`). -- Include closing reference with absolute URL, e.g. `closes https://github.com/eclipse-glsp/glsp/issues/241`. -- PRs should include scope, linked issue, and pass CI; ensure `yarn.lock` has no unintended diff. -- Ensure Eclipse Contributor Agreement (ECA) requirements are satisfied. +- **Package manager**: Yarn 1.x (classic) — do not use Yarn 2+/Berry or npm +- **Build**: Run `yarn` from the repository root to build the entire project +- **CLI**: Run `yarn glsp` to start the CLI +- Refer to the scripts in the root `package.json` for available build, lint, and format commands diff --git a/CLAUDE.md b/CLAUDE.md index 43c994c..d2beef7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1 +1,19 @@ -@AGENTS.md +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Eclipse GLSP shared development tooling monorepo. Contains reusable dev packages (ESLint config, Prettier config, TypeScript config, CLI tools) published to npm under `@eclipse-glsp/*`. This is **not** the GLSP runtime — it provides build/lint/format configurations consumed by other GLSP repositories (glsp-client, glsp-server-node, glsp-theia-integration, etc.). + +## Build & Development + +- **Package manager**: Yarn 1.x (classic) — do not use Yarn 2+/Berry or npm +- **Build**: Run `yarn` from the repository root to build the entire project +- **CLI**: Run `yarn glsp` to start the CLI +- Refer to the scripts in the root `package.json` for available build, lint, and format commands + +## Validation + +- After completing any code changes, always run the `/verify` skill before reporting completion +- If verification fails, run the `/fix` skill to auto-fix issues, then re-run `/verify` diff --git a/README.md b/README.md index f1df605..02d92a2 100644 --- a/README.md +++ b/README.md @@ -116,11 +116,11 @@ All changes on the master branch are deployed automatically to the corresponding ### Client packages -We recommend node in version 20 or higher: +We recommend node in version 22 or higher: ```bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash -nvm install 18 +nvm install 22 ``` and Yarn diff --git a/dev-packages/cli/package.json b/dev-packages/cli/package.json index d0d81f6..dad82d7 100644 --- a/dev-packages/cli/package.json +++ b/dev-packages/cli/package.json @@ -41,13 +41,11 @@ "devDependencies": { "@eclipse-glsp/config": "2.7.0-next", "@types/glob": "^8.1.0", - "@types/readline-sync": "^1.4.8", "@types/semver": "^7.7.1", "commander": "^14.0.0", "esbuild": "~0.25.9", "glob": "^10.4.5", "globby": "^14.1.0", - "readline-sync": "^1.4.10", "semver": "^7.7.2" }, "publishConfig": { diff --git a/dev-packages/cli/src/commands/check-header.ts b/dev-packages/cli/src/commands/check-header.ts index f41f998..09b333d 100644 --- a/dev-packages/cli/src/commands/check-header.ts +++ b/dev-packages/cli/src/commands/check-header.ts @@ -17,8 +17,6 @@ import { Option } from 'commander'; import * as fs from 'fs'; import { glob } from 'glob'; import * as minimatch from 'minimatch'; -import * as readline from 'readline-sync'; - import * as path from 'path'; import { LOGGER, @@ -174,7 +172,9 @@ function validate(rootDir: string, files: string[], options: HeaderCheckOptions) results.sort((a, b) => a.file.localeCompare(b.file)); - process.stdout.clearLine(0); + if (process.stdout.isTTY) { + process.stdout.clearLine(0); + } return results; } @@ -191,13 +191,12 @@ function validateEndYear(result: DateValidationResult): void { } function printFileProgress(currentFileCount: number, maxFileCount: number, message: string, clear = true): void { - if (clear) { + if (clear && process.stdout.isTTY) { process.stdout.clearLine(0); process.stdout.cursorTo(0); - } - process.stdout.write(`[${currentFileCount} of ${maxFileCount}] ${message}`); - if (!clear) { - process.stdout.write('\n'); + process.stdout.write(`[${currentFileCount} of ${maxFileCount}] ${message}`); + } else { + process.stdout.write(`[${currentFileCount} of ${maxFileCount}] ${message}\n`); } } @@ -219,15 +218,16 @@ export function handleValidationResults(rootDir: string, results: ValidationResu fs.writeFileSync(path.join(rootDir, 'headerCheck.json'), JSON.stringify(results, undefined, 2)); } - if ( - violations.length > 0 && - (options.autoFix || readline.keyInYN('Do you want to automatically fix copyright year range violations?')) - ) { + if (violations.length > 0 && options.autoFix) { const toFix = violations.filter(violation => isDateValidationResult(violation)) as DateValidationResult[]; fixViolations(rootDir, toFix, options); } LOGGER.info('Check completed'); + + if (violations.length > 0 && !options.autoFix) { + process.exit(1); + } } function toPrintMessage(result: ValidationResult): string { @@ -264,7 +264,7 @@ function fixViolations(rootDir: string, violations: DateValidationResult[], opti replaceInFile(violation.file, RegExp('Copyright \\([cC]\\) ' + currentRange), `Copyright (c) ${fixedRange}`); }); LOGGER.newLine(); - if (options.commit && (options.autoFix || readline.keyInYN('Do you want to create a commit for the fixed files?'))) { + if (options.commit && options.autoFix) { LOGGER.newLine(); const files = violations.map(violation => violation.file).join(' '); exec(`git add ${files}`); diff --git a/dev-packages/cli/src/commands/releng/releng.ts b/dev-packages/cli/src/commands/releng/releng.ts index 5f4c1ab..cba5465 100644 --- a/dev-packages/cli/src/commands/releng/releng.ts +++ b/dev-packages/cli/src/commands/releng/releng.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2025 EclipseSource and others. + * Copyright (c) 2025-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at diff --git a/dev-packages/cli/src/commands/update-next.ts b/dev-packages/cli/src/commands/update-next.ts index 781deca..ba74b93 100644 --- a/dev-packages/cli/src/commands/update-next.ts +++ b/dev-packages/cli/src/commands/update-next.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024-2025 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at diff --git a/docker/README.md b/docker/README.md index 150b70b..a2681cb 100644 --- a/docker/README.md +++ b/docker/README.md @@ -15,7 +15,7 @@ They are mainly used for CI jobs that require the possibility to build client an Currently each image variant has at least the following components installed: - Git >=2.17.1 -- Node 20, yarn 1.22.4 and lerna +- Node 22, yarn 1.22.4 and lerna - OpenJDK 21 and Maven >=3.6.0 - Python and GCC libraries to enable [Theia](https://theia-ide.org/) builds diff --git a/docker/ci/README.md b/docker/ci/README.md index 58f0811..2b1d697 100644 --- a/docker/ci/README.md +++ b/docker/ci/README.md @@ -13,10 +13,10 @@ ## Supported tags and respective `Dockerfile` links -- [`latest`, `ubuntu`, `ubuntu-v6.0`](https://github.com/eclipse-glsp/glsp/blob/master/docker/ci/ubuntu/Dockerfile) -- [`uitest`,`uitest-v6.0`](https://github.com/eclipse-glsp/glsp/blob/master/docker/ci/uitest/Dockerfile) +- [`alpine`, `alpine-v8.0`, `alpine-v7.1`, `alpine-v7.0`](https://github.com/eclipse-glsp/glsp/blob/master/docker/ci/alpine/Dockerfile) -- [`alpine`, `alpine-v7.1`, `alpine-v7.0`](https://github.com/eclipse-glsp/glsp/blob/master/docker/ci/alpine/Dockerfile) +- ~~[`latest`, `ubuntu`, `ubuntu-v6.0`](https://github.com/eclipse-glsp/glsp/blob/master/docker/ci/ubuntu/Dockerfile)~~ (deprecated) +- ~~[`uitest`,`uitest-v6.0`](https://github.com/eclipse-glsp/glsp/blob/master/docker/ci/uitest/Dockerfile)~~ (deprecated) Note that these tags are fluent and not bound to a fixed image version. If you want to use a fixed version you can use the base tag with a version suffix e.g. `ubuntu-v1.0`. @@ -34,7 +34,7 @@ They are mainly used for CI jobs that require the possibility to build client an Currently each image variant has at least the following components installed: - Git >=2.17.1 -- Node 20, yarn 1.22.19 and lerna +- Node 22, yarn 1.22.19 and lerna - OpenJDK 21 and Maven >=3.6.0 - Python and GCC libraries to enable [Theia](https://theia-ide.org/) builds @@ -52,13 +52,12 @@ Alternatively, you can run the image in interactive mode and gain full access to The `ci` images come in different flavors, each designed for a specific use case. -### `ci:ubuntu<-suffix>` +### `ci:ubuntu<-suffix>` (deprecated) -This is the defacto base image. If you are unsure about what your needs are, you probably want to use this one. -It is designed to be used both as a throw-away container (mount your source code and start the container to start your app) and as the base to build other images from. +> **Deprecated:** This image variant is deprecated and no longer maintained. Please use the `alpine` variant instead. -As the name indicates this image is based on [Ubuntu](https://ubuntu.com/). -This makes it very easy to use and customize but also results in a larger image size compared to the `alpine` variant. +This image is based on [Ubuntu](https://ubuntu.com/). +It was previously the default image but has been superseded by the `alpine` variant. ### `ci:alpine<-suffix>` @@ -68,9 +67,11 @@ Alpine Linux is much smaller than most distribution base images (~5MB), and thus It only provides the essential libraries needed for building client and server components and is the recommended image for classical CI jobs like building branches or PRs on change, or deploying build artifacts. Due to its slim size, it cannot be used for more sophisticated jobs like end-to-end testing without further extension, because essential components, such as a display server or a browser are not included. -### `ci:uitest<-suffix>` +### `ci:uitest<-suffix>` (deprecated) -This is the recommend image for CI jobs that execute any sort of UI tests. +> **Deprecated:** This image variant is deprecated and no longer maintained. Please use the `alpine` variant instead. + +This image was the recommended image for CI jobs that execute UI tests. It uses the same base as the `ubuntu` image but has additional libraries installed (including Xvfb which enables headless UI testing). In addition, Google Chrome is installed which enables browser-based UI testing of client components. @@ -85,6 +86,7 @@ In addition, Google Chrome is installed which enables browser-based UI testing o - [v6.0](https://hub.docker.com/r/eclipseglsp/ci/tags?page=1&name=v6.0): Update to node 20 - [v7.0](https://hub.docker.com/r/eclipseglsp/ci/tags?page=1&name=v7.0): Update to Java 21 (alpine only) - [v7.1](https://hub.docker.com/r/eclipseglsp/ci/tags?page=1&name=v7.1): Additionally install Java 11 (alpine only) +- [v8.0](https://hub.docker.com/r/eclipseglsp/ci/tags?page=1&name=v8.0): Update to Node 22 (alpine only). Ubuntu and uitest variants are deprecated and no longer maintained. ## License diff --git a/docker/ci/alpine/Dockerfile b/docker/ci/alpine/Dockerfile index 9be955c..8b2db9e 100644 --- a/docker/ci/alpine/Dockerfile +++ b/docker/ci/alpine/Dockerfile @@ -1,6 +1,6 @@ # eclipseglsp/ci:alpine -# 7.1 -FROM node:20-alpine3.22 +# 8.0 +FROM node:22-alpine3.21 # Install Java, Maven, Git and dependecies for Theia ENV JAVA_HOME="/usr/lib/jvm/java-21-openjdk" diff --git a/docker/ci/ubuntu/Dockerfile b/docker/ci/ubuntu/Dockerfile index d78bacd..f91d881 100644 --- a/docker/ci/ubuntu/Dockerfile +++ b/docker/ci/ubuntu/Dockerfile @@ -1,5 +1,7 @@ # eclipseglsp/ci:ubuntu # 6.0 +# DEPRECATED: This image is deprecated and no longer maintained. +# Please use the alpine variant instead: eclipseglsp/ci:alpine FROM ubuntu:22.04 # Install node & other Theia related dependencies RUN apt-get update && \ diff --git a/docker/ci/uitest/Dockerfile b/docker/ci/uitest/Dockerfile index 1323be1..8d9538c 100644 --- a/docker/ci/uitest/Dockerfile +++ b/docker/ci/uitest/Dockerfile @@ -1,5 +1,7 @@ # eclipseglsp/ci:uitest # 6.0 +# DEPRECATED: This image is deprecated and no longer maintained. +# Please use the alpine variant instead: eclipseglsp/ci:alpine FROM ubuntu:22.04 # Install node & other Theia related dependencies RUN apt-get update && \ diff --git a/package.json b/package.json index 5b90cf2..c040b57 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ ], "scripts": { "build": "lerna run build", - "check:all": "yarn install && yarn lint && yarn prettier:check && yarn headers:check", + "check:all": "yarn install && yarn lint && yarn format:check && yarn headers:check", "clean": "lerna run clean", "cli": "yarn --cwd dev-packages/cli", "fix:all": "yarn lint:fix && yarn format && yarn headers:fix", @@ -31,7 +31,7 @@ "@tony.ganchev/eslint-plugin-header": "^3.1.1", "@types/chai": "^4.3.5", "@types/mocha": "^10.0.1", - "@types/node": "20.x", + "@types/node": "22.x", "@types/sinon": "^10.0.13", "chai": "^4.3.7", "eslint": "^9.0.0", @@ -55,7 +55,7 @@ "typescript-eslint": "^8.0.0" }, "engines": { - "node": ">=20", + "node": ">=22", "yarn": ">=1.7.0 <2" } } diff --git a/yarn.lock b/yarn.lock index 2e4d056..13bf278 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1489,10 +1489,10 @@ dependencies: undici-types "~5.26.4" -"@types/node@20.x": - version "20.19.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.14.tgz#70b1fe26387c5d755ee253801c89de5747f28c14" - integrity sha512-gqiKWld3YIkmtrrg9zDvg9jfksZCcPywXVN7IauUGhilwGV/yOyeUsvpR796m/Jye0zUzMXPKe8Ct1B79A7N5Q== +"@types/node@22.x": + version "22.19.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.15.tgz#6091d99fdf7c08cb57dc8b1345d407ba9a1df576" + integrity sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg== dependencies: undici-types "~6.21.0" @@ -1501,11 +1501,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== -"@types/readline-sync@^1.4.8": - version "1.4.8" - resolved "https://registry.yarnpkg.com/@types/readline-sync/-/readline-sync-1.4.8.tgz#dc9767a93fc83825d90331f2549a2e90fc3255f0" - integrity sha512-BL7xOf0yKLA6baAX6MMOnYkoflUyj/c7y3pqMRfU0va7XlwHAOTOIo4x55P/qLfMsuaYdJJKubToLqRVmRtRZA== - "@types/semver@^7.7.1": version "7.7.1" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528" @@ -5635,11 +5630,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -readline-sync@^1.4.10: - version "1.4.10" - resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b" - integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw== - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"