Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 60 additions & 41 deletions .claude/skills/generate-changelog/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ description: Generate changelog entries from merged PRs since the last release.
Generate changelog entries by analyzing merged PRs since the last release.

Execute these phases in order:

1. **Data Gathering** — find last release, fetch PRs, classify, generate entries
2. **Changelog Update** — write entries into CHANGELOG.md
3. **Review & Approval** — present the actual diff to the user for review
Expand All @@ -20,11 +21,13 @@ Execute these phases in order:
### Step 1.1: Find the latest release tag

Run:

```bash
git tag --sort=-creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1
```

Record as `LAST_TAG`. Get the tag's date:

```bash
git log -1 --format=%aI $LAST_TAG
```
Expand All @@ -46,12 +49,13 @@ Use the date portion only from `TAG_DATE` (e.g. `2026-02-09`).
### Step 1.4: Filter PRs

**Skip rules** (in order):

1. PR has the `changelog` label → skip (already tracked in a previous changelog update)
2. Author login is `dependabot` or `dependabot[bot]` → skip
3. Title matches version bump patterns → skip:
- Starts with `Switch to` and contains `-next`
- Title is a bare version like `vX.Y.Z`
- Title starts with `Release v`
- Starts with `Switch to` and contains `-next`
- Title is a bare version like `vX.Y.Z`
- Title starts with `Release v`
4. Title contains `update changelog` (case insensitive) → skip
5. Title is purely CI/metadata (readme badges, workflow config) AND body does NOT contain `[x] This PR should be mentioned in the changelog` → skip

Expand All @@ -62,9 +66,9 @@ Use the date portion only from `TAG_DATE` (e.g. `2026-02-09`).
1. If body contains `[x] This PR introduces a breaking change` → **breaking**
2. If body contains `[ ] This PR introduces a breaking change` → **normal**
3. If no checkbox info, analyze title and body:
- Breaking keywords: "refactor", "rename", "remove", "replace", "migrate", "breaking", "deprecate"
- Clearly non-breaking (bug fix, docs, minor enhancement) → **normal**
- Uncertain → flag for user review
- Breaking keywords: "refactor", "rename", "remove", "replace", "migrate", "breaking", "deprecate"
- Clearly non-breaking (bug fix, docs, minor enhancement) → **normal**
- Uncertain → flag for user review

### Step 1.6: Assign category tags

Expand All @@ -75,57 +79,65 @@ Pick the most fitting tag from the vocabulary (Step 1.2) based on PR title and b
#### Entry Format

**Normal changes:**

```
- [tag] Description [#N](https://github.com/OWNER/REPO/pull/N)
```

**Breaking changes** with migration sub-items:

```
- [tag] Description [#N](https://github.com/OWNER/REPO/pull/N)
- Migration detail 1
- Migration detail 2
```

**Multiple PRs for the same change:**

```
- [tag] Description [#N](url) [#M](url)
```

#### Style Guide

**Formatting:**
- Entry prefix: `- ` (dash + exactly 3 spaces)
- Sub-item indent: 4 spaces + `- ` (4 spaces from parent dash)
- Sub-sub-item indent: 8 spaces + `- `
- Single space between `[tag]` and description text
- Single space before PR link at end of line
- PR links are mandatory, full URLs: `[#123](https://github.com/OWNER/REPO/pull/123)`

- Entry prefix: `- ` (dash + exactly 3 spaces)
- Sub-item indent: 4 spaces + `- ` (4 spaces from parent dash)
- Sub-sub-item indent: 8 spaces + `- `
- Single space between `[tag]` and description text
- Single space before PR link at end of line
- PR links are mandatory, full URLs: `[#123](https://github.com/OWNER/REPO/pull/123)`

**Wording:**
- Always start with a **present tense imperative verb** (not past tense)
- Common verbs: Fix, Improve, Add, Update, Extend, Ensure, Introduce, Remove, Refactor, Rename, Provide, Allow, Support
- **Bug fixes**: "Fix a bug that caused/prevented...", "Fix X behavior"
- **Features**: "Introduce...", "Add support for...", "Provide..."
- **Enhancements**: "Improve...", "Extend...", "Ensure that..."
- **Refactors**: "Refactor...", "Rework...", "Rename..."
- Be specific — never "Fix various issues"

- Always start with a **present tense imperative verb** (not past tense)
- Common verbs: Fix, Improve, Add, Update, Extend, Ensure, Introduce, Remove, Refactor, Rename, Provide, Allow, Support
- **Bug fixes**: "Fix a bug that caused/prevented...", "Fix X behavior"
- **Features**: "Introduce...", "Add support for...", "Provide..."
- **Enhancements**: "Improve...", "Extend...", "Ensure that..."
- **Refactors**: "Refactor...", "Rework...", "Rename..."
- Be specific — never "Fix various issues"

**Capitalization:**
- Tags are always lowercase: `[diagram]`, not `[Diagram]`
- Description starts lowercase after the tag (unless proper noun or code element)
- Section headers: Title Case (`### Potentially Breaking Changes`)

- Tags are always lowercase: `[diagram]`, not `[Diagram]`
- Description starts lowercase after the tag (unless proper noun or code element)
- Section headers: Title Case (`### Potentially Breaking Changes`)

**Description cleanup from PR title:**
- Remove issue tracker prefixes (e.g. `GLSP-1234:`, `GH-123:`, `ISSUE-456:`)
- Remove conventional commit prefixes: `fix:`, `feat:`, `chore:`
- Rephrase bug-report style to changelog style:
- BAD: "Edit label UI does not resize on graph zoom"
- GOOD: "Fix edit label UI not resizing on graph zoom"
- Keep concise — one line

- Remove issue tracker prefixes (e.g. `GLSP-1234:`, `GH-123:`, `ISSUE-456:`)
- Remove conventional commit prefixes: `fix:`, `feat:`, `chore:`
- Rephrase bug-report style to changelog style:
- BAD: "Edit label UI does not resize on graph zoom"
- GOOD: "Fix edit label UI not resizing on graph zoom"
- Keep concise — one line

**Breaking changes:**
- Describe what changed, why it's breaking, and how to migrate
- Extract migration sub-items from the PR body's "What it does" section

- Describe what changed, why it's breaking, and how to migrate
- Extract migration sub-items from the PR body's "What it does" section

---

Expand All @@ -136,13 +148,15 @@ Pick the most fitting tag from the vocabulary (Step 1.2) based on PR title and b
Read `CHANGELOG.md` in the repository root.

**Active section detection:**
- An active section has the `- active` suffix (e.g. `## v2.7.0 - active`)
- If an active section exists → merge new entries into it
- If the topmost section is a released version (no `- active` suffix) → create a new active section above it

- An active section has the `- active` suffix (e.g. `## v2.7.0 - active`)
- If an active section exists → merge new entries into it
- If the topmost section is a released version (no `- active` suffix) → create a new active section above it

**Creating a new section:**
- Bump the minor version of `LAST_TAG` (e.g. `v2.6.0` → `v2.7.0`)
- Insert after the title line, before the first `## ` heading:

- Bump the minor version of `LAST_TAG` (e.g. `v2.6.0` → `v2.7.0`)
- Insert after the title line, before the first `## ` heading:

```markdown
## v2.7.0 - active
Expand All @@ -160,9 +174,10 @@ Read `CHANGELOG.md` in the repository root.
Only include "Potentially Breaking Changes" if there are breaking entries.

**Merging into existing active section:**
- Check PR numbers against existing entries to avoid duplicates
- Append new entries to the appropriate subsection
- Create missing subsections as needed

- Check PR numbers against existing entries to avoid duplicates
- Append new entries to the appropriate subsection
- Create missing subsections as needed

### Step 2.2: Write the updated CHANGELOG.md

Expand All @@ -185,13 +200,14 @@ Present the diff to the user.
List any entries flagged as uncertain (category or breaking status) and ask the user to resolve them.

Even if nothing is uncertain, ask:

> "Does everything look correct, or would you like to adjust any entries?"

### Step 3.3: Collect user feedback

- **Approve as-is** → done (or proceed to Phase 4 if PR was requested)
- **Request edits** → apply changes, show updated diff, ask again
- **Resolve uncertain items** → apply, show updated diff
- **Approve as-is** → done (or proceed to Phase 4 if PR was requested)
- **Request edits** → apply changes, show updated diff, ask again
- **Resolve uncertain items** → apply, show updated diff

**Do NOT proceed to Phase 4 unless the user explicitly requests a PR.**

Expand All @@ -200,11 +216,13 @@ Even if nothing is uncertain, ask:
## Phase 4: PR Creation (Optional)

Only execute this phase if the user explicitly requests a PR (either in their initial prompt or after reviewing the changelog). If the user hasn't mentioned a PR, ask after approval:

> "Would you like me to create a PR for this changelog update, or are you done?"

### Step 4.1: Determine the branch name

Check if `changelog-update` exists on remote:

```bash
git ls-remote --heads origin changelog-update
```
Expand All @@ -229,6 +247,7 @@ Report the PR URL.
### Step 4.4: Label referenced PRs

Add the `changelog` label to every PR mentioned in the new entries:

```bash
gh pr edit PR_NUMBER --add-label "changelog"
```
Expand Down
5 changes: 5 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export default [
rules: {
'@typescript-eslint/no-shadow': 'off',
'@typescript-eslint/padding-line-between-statements': 'off',
// The MCP SDK uses `exports` subpath patterns with explicit `.js` suffixes (e.g.
// `@modelcontextprotocol/sdk/server/mcp.js`). The TypeScript import resolver does
// not match these against the `./*` wildcard, even though tsc and Node resolve
// them correctly at compile- and runtime.
'import-x/no-unresolved': ['error', { ignore: ['^@modelcontextprotocol/sdk/'] }],
'no-restricted-imports': [
'warn',
{
Expand Down
1 change: 1 addition & 0 deletions examples/workflow-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"dependencies": {
"@eclipse-glsp/layout-elk": "2.7.0-next",
"@eclipse-glsp/server": "2.7.0-next",
"@eclipse-glsp/server-mcp": "2.7.0-next",
"inversify": "^6.1.3"
},
"devDependencies": {
Expand Down
6 changes: 3 additions & 3 deletions examples/workflow-server/src/common/graph-extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2022-2023 STMicroelectronics and others.
* Copyright (c) 2022-2026 STMicroelectronics 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
Expand Down Expand Up @@ -86,7 +86,7 @@ export class TaskNodeBuilder<T extends TaskNode = TaskNode> extends GNodeBuilder
protected createCompartmentHeader(): GLabel {
return new GLabelBuilder(GLabel)
.type(ModelTypes.LABEL_HEADING)
.id(this.proxy.id + '_classname')
.id(this.proxy.id + '_label')
.text(this.proxy.name)
.build();
}
Expand Down Expand Up @@ -151,7 +151,7 @@ export class CategoryNodeBuilder<T extends Category = Category> extends Activity
protected createCompartmentHeader(): GLabel {
return new GLabelBuilder(GLabel)
.type(ModelTypes.LABEL_HEADING)
.id(this.proxy.id + '_classname')
.id(this.proxy.id + '_label')
.text(this.proxy.name)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2022-2024 STMicroelectronics and others.
* Copyright (c) 2022-2026 STMicroelectronics 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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2022-2024 STMicroelectronics and others.
* Copyright (c) 2022-2026 STMicroelectronics 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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/********************************************************************************
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { DefaultTypes } from '@eclipse-glsp/server';
import { ElementTypeEntry, ElementTypes, ElementTypesProvider } from '@eclipse-glsp/server-mcp';
import { injectable } from 'inversify';
import { ModelTypes } from '../util/model-types';

const NODE_TYPES: ElementTypeEntry[] = [
{ id: ModelTypes.AUTOMATED_TASK, label: 'Automated Task', description: 'Task without human input', acceptsText: true },
{ id: ModelTypes.MANUAL_TASK, label: 'Manual Task', description: 'Task done by a human', acceptsText: true },
{ id: ModelTypes.JOIN_NODE, label: 'Join Node', description: 'Gateway that merges parallel flows', acceptsText: false },
{ id: ModelTypes.FORK_NODE, label: 'Fork Node', description: 'Gateway that splits into parallel flows', acceptsText: false },
{ id: ModelTypes.MERGE_NODE, label: 'Merge Node', description: 'Gateway that merges alternative flows', acceptsText: false },
{ id: ModelTypes.DECISION_NODE, label: 'Decision Node', description: 'Gateway that splits into alternative flows', acceptsText: false },
{ id: ModelTypes.CATEGORY, label: 'Category', description: 'Container node that groups other elements', acceptsText: true }
];

const EDGE_TYPES: ElementTypeEntry[] = [
{ id: DefaultTypes.EDGE, label: 'Edge', description: 'Standard control flow edge', acceptsText: false },
{
id: ModelTypes.WEIGHTED_EDGE,
label: 'Weighted Edge',
description: 'Edge that indicates a weighted probability. Typically used with a Decision Node.',
acceptsText: false
}
];

/**
* Workflow-specific {@link ElementTypesProvider}. Returns the constant set of creatable types
* with richer LLM-facing fields (`description`, `acceptsText`) than the default registry-scrape
* impl can infer. Bound on the workflow MCP diagram module via `bindElementTypesProvider()`;
* the standard `element-types` tool handler exposes the full entries via `structuredContent`
* (with a short summary in the text content) — no handler rebind needed.
*/
@injectable()
export class WorkflowElementTypesProvider implements ElementTypesProvider {
get(): ElementTypes {
return { nodeTypes: NODE_TYPES, edgeTypes: EDGE_TYPES };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/********************************************************************************
* Copyright (c) 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
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { GLabel, GModelElement } from '@eclipse-glsp/server';
import { DefaultMcpLabelProvider } from '@eclipse-glsp/server-mcp';
import { injectable } from 'inversify';
import { ModelTypes } from '../util/model-types';

/**
* Workflow-specific {@link DefaultMcpLabelProvider}: category labels are nested inside a
* compartment-header child rather than directly under the category, so the default
* direct-child lookup misses them. Other workflow element types fall through to the
* inherited default.
*/
@injectable()
export class WorkflowMcpLabelProvider extends DefaultMcpLabelProvider {
override getLabel(element: GModelElement): GLabel | undefined {
if (element.type === ModelTypes.CATEGORY) {
const header = element.children.find(child => child.type === ModelTypes.COMP_HEADER);
return header?.children.find((child): child is GLabel => child instanceof GLabel);
}
return super.getLabel(element);
}
}
Loading
Loading