From 8aea9a6336a2f03b0cfa0f5ae7bce2f6f367bc68 Mon Sep 17 00:00:00 2001 From: fantonangeli Date: Mon, 31 Aug 2026 15:35:11 +0200 Subject: [PATCH 1/4] Language Service foundation Signed-off-by: fantonangeli --- .syncpackrc.json | 7 ++ packages/language-service/.oxfmtrc.json | 3 + packages/language-service/.oxlintrc.json | 22 +++++ packages/language-service/README.md | 51 ++++++++++++ packages/language-service/package.json | 50 +++++++++++ packages/language-service/src/index.ts | 17 ++++ packages/language-service/src/volar/index.ts | 24 ++++++ .../tests/languageService.test.ts | 24 ++++++ packages/language-service/tsconfig.json | 14 ++++ packages/language-service/vite.config.ts | 32 ++++++++ packages/language-service/vitest.config.ts | 27 ++++++ pnpm-lock.yaml | 82 +++++++++++++++++++ pnpm-workspace.yaml | 1 + 13 files changed, 354 insertions(+) create mode 100644 packages/language-service/.oxfmtrc.json create mode 100644 packages/language-service/.oxlintrc.json create mode 100644 packages/language-service/README.md create mode 100644 packages/language-service/package.json create mode 100644 packages/language-service/src/index.ts create mode 100644 packages/language-service/src/volar/index.ts create mode 100644 packages/language-service/tests/languageService.test.ts create mode 100644 packages/language-service/tsconfig.json create mode 100644 packages/language-service/vite.config.ts create mode 100644 packages/language-service/vitest.config.ts diff --git a/.syncpackrc.json b/.syncpackrc.json index 785a03e1..80a8a50d 100644 --- a/.syncpackrc.json +++ b/.syncpackrc.json @@ -7,6 +7,13 @@ } }, "versionGroups": [ + { + "label": "Only language-service may depend on Volar. See the Architecture section in packages/language-service/README.md.", + "dependencies": ["@volar/**", "volar-service-*"], + "packages": ["!@openworkflowspec/language-service"], + "dependencyTypes": ["prod", "dev", "peer"], + "isBanned": true + }, { "label": "Ignore root package version", "packages": ["open-workflow-editor"], diff --git a/packages/language-service/.oxfmtrc.json b/packages/language-service/.oxfmtrc.json new file mode 100644 index 00000000..0de643fc --- /dev/null +++ b/packages/language-service/.oxfmtrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["../../.oxfmtrc.json"] +} diff --git a/packages/language-service/.oxlintrc.json b/packages/language-service/.oxlintrc.json new file mode 100644 index 00000000..09d122c5 --- /dev/null +++ b/packages/language-service/.oxlintrc.json @@ -0,0 +1,22 @@ +{ + "extends": ["../../.oxlintrc.json"], + "overrides": [ + { + "files": ["src/**/*.{ts,tsx}"], + "excludeFiles": ["src/volar/**"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + { + "group": ["@volar/*", "volar-service-*"], + "message": "Volar dependencies may only be imported from src/volar. See the Architecture section in README.md." + } + ] + } + ] + } + } + ] +} diff --git a/packages/language-service/README.md b/packages/language-service/README.md new file mode 100644 index 00000000..611b27c2 --- /dev/null +++ b/packages/language-service/README.md @@ -0,0 +1,51 @@ + + +# @openworkflowspec/language-service + +Language service foundation for the Open Workflow Specification, built on [Volar](https://volarjs.dev/). + +The package provides the common infrastructure for Open Workflow language features. + +## Architecture + +Volar-specific code is isolated under `src/volar/`. Imports from `@volar/*` outside this directory are prevented by Oxlint. + +```text +src/ +├── index.ts +└── volar/ + └── index.ts +``` + +## Development + +```bash +# Run unit tests +pnpm test + +# Linting +pnpm lint + +# Build package (development) +pnpm run build:dev + +# Build package (production - includes linting and tests) +pnpm run build:prod + +# Build Storybook static site +pnpm run build:storybook +``` diff --git a/packages/language-service/package.json b/packages/language-service/package.json new file mode 100644 index 00000000..bfe35b1a --- /dev/null +++ b/packages/language-service/package.json @@ -0,0 +1,50 @@ +{ + "name": "@openworkflowspec/language-service", + "version": "1.1.0", + "private": true, + "description": "Open Workflow language service foundation", + "keywords": [], + "homepage": "https://github.com/open-workflow-specification/editor", + "bugs": { + "url": "https://github.com/open-workflow-specification/editor/issues" + }, + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/open-workflow-specification/editor.git" + }, + "files": [ + "dist", + "src" + ], + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "scripts": { + "clean": "rimraf ./dist", + "build:dev": "pnpm clean && tsc -p tsconfig.json && vite build", + "build:prod": "pnpm lint && pnpm run build:dev && pnpm test", + "lint": "oxlint --config .oxlintrc.json src/ tests/", + "format": "oxfmt --config .oxfmtrc.json", + "format:check": "oxfmt --config .oxfmtrc.json --check", + "test": "vitest run" + }, + "dependencies": { + "@volar/language-service": "catalog:" + }, + "devDependencies": { + "@types/node": "catalog:", + "oxfmt": "catalog:", + "oxlint": "catalog:", + "rimraf": "catalog:", + "typescript": "catalog:", + "vite": "catalog:", + "vitest": "catalog:" + } +} diff --git a/packages/language-service/src/index.ts b/packages/language-service/src/index.ts new file mode 100644 index 00000000..d57c5531 --- /dev/null +++ b/packages/language-service/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from "./volar/index"; diff --git a/packages/language-service/src/volar/index.ts b/packages/language-service/src/volar/index.ts new file mode 100644 index 00000000..55a55f19 --- /dev/null +++ b/packages/language-service/src/volar/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { createLanguageService } from "@volar/language-service"; + +export type { + LanguageService, + LanguageServiceEnvironment, + LanguageServicePlugin, + ProjectContext, +} from "@volar/language-service"; diff --git a/packages/language-service/tests/languageService.test.ts b/packages/language-service/tests/languageService.test.ts new file mode 100644 index 00000000..09db0934 --- /dev/null +++ b/packages/language-service/tests/languageService.test.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, it, expect } from "vitest"; +import { createLanguageService } from "../src/index"; + +describe("createLanguageService", () => { + it("re-exports createLanguageService from @volar/language-service", () => { + expect(typeof createLanguageService).toBe("function"); + }); +}); diff --git a/packages/language-service/tsconfig.json b/packages/language-service/tsconfig.json new file mode 100644 index 00000000..245215bd --- /dev/null +++ b/packages/language-service/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "sourceMap": false, + "emitDeclarationOnly": true, + "noEmitOnError": true, + "rootDir": "./src", + "outDir": "./dist" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/language-service/vite.config.ts b/packages/language-service/vite.config.ts new file mode 100644 index 00000000..03525de7 --- /dev/null +++ b/packages/language-service/vite.config.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineConfig } from "vite"; + +export default defineConfig({ + resolve: { + tsconfigPaths: true, + }, + build: { + emptyOutDir: false, + sourcemap: true, + lib: { + entry: "src/index.ts", + fileName: (format) => (format === "es" ? "index.js" : `index.${format}.js`), + formats: ["es"], + }, + }, +}); diff --git a/packages/language-service/vitest.config.ts b/packages/language-service/vitest.config.ts new file mode 100644 index 00000000..73dbad35 --- /dev/null +++ b/packages/language-service/vitest.config.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2021-Present The Open Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + resolve: { + tsconfigPaths: true, + }, + test: { + globals: true, + environment: "node", + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a28b2a1..9e364fca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,6 +75,9 @@ catalogs: '@vitest/ui': specifier: ^4.1.11 version: 4.1.11 + '@volar/language-service': + specifier: ^2.4.28 + version: 2.4.28 '@xyflow/react': specifier: ^12.11.3 version: 12.11.3 @@ -265,6 +268,34 @@ importers: specifier: 'catalog:' version: 4.1.11(@types/node@26.2.0)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@30.0.1)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(yaml@2.9.0)) + packages/language-service: + dependencies: + '@volar/language-service': + specifier: 'catalog:' + version: 2.4.28 + devDependencies: + '@types/node': + specifier: 'catalog:' + version: 26.2.0 + oxfmt: + specifier: 'catalog:' + version: 0.64.0 + oxlint: + specifier: 'catalog:' + version: 1.77.0 + rimraf: + specifier: 'catalog:' + version: 6.1.3 + typescript: + specifier: 'catalog:' + version: 7.0.2 + vite: + specifier: 'catalog:' + version: 8.2.2(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(yaml@2.9.0) + vitest: + specifier: 'catalog:' + version: 4.1.11(@types/node@26.2.0)(@vitest/browser-playwright@4.1.11)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@30.0.1)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.1)(jiti@2.7.0)(yaml@2.9.0)) + packages/open-workflow-diagram-editor: dependencies: '@base-ui/react': @@ -2692,6 +2723,15 @@ packages: '@vitest/utils@4.1.11': resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} + + '@volar/language-service@2.4.28': + resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==} + + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} + '@webcontainer/env@1.1.1': resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} @@ -3939,6 +3979,22 @@ packages: jsdom: optional: true + vscode-jsonrpc@9.0.2: + resolution: {integrity: sha512-SbQSV9yRemARxeXw6LU5sS6Zq0e9/DgCCX5yelH263ZQWukbTk8EF8fjTrr1dziasf4GwlJbvTwFnTrnQFWZXQ==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.18.3: + resolution: {integrity: sha512-DF49+WeV5py4zO5hhobp60jjsDSK0lAqA0OuKBLBvp423HPWQcCbhZz3JgyfIewsEz2f8U+X75xNIFHdiXZm2w==} + + vscode-languageserver-textdocument@1.0.14: + resolution: {integrity: sha512-EQyqJMi552E4ZTf46izQ4Fj6XquqxCySR3J5ZSD1SisMf6RfpeOWHxGBE8Gr6V0/3GHIGdAzDn8F8+1nTGCnoQ==} + + vscode-languageserver-types@3.18.3: + resolution: {integrity: sha512-XIlzJ7Qp/jzSI1ds7/FwPAWrPeTZA7pAtlW4hdJ1J6xXWJL6dR9QYnDhJOdLzdKhUQ5Mm6mvUMw+3DcOQQasPw==} + + vscode-uri@3.2.0: + resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==} + w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -6081,6 +6137,19 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 + '@volar/language-core@2.4.28': + dependencies: + '@volar/source-map': 2.4.28 + + '@volar/language-service@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + vscode-languageserver-protocol: 3.18.3 + vscode-languageserver-textdocument: 1.0.14 + vscode-uri: 3.2.0 + + '@volar/source-map@2.4.28': {} + '@webcontainer/env@1.1.1': {} '@xyflow/react@12.11.3(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': @@ -7258,6 +7327,19 @@ snapshots: transitivePeerDependencies: - msw + vscode-jsonrpc@9.0.2: {} + + vscode-languageserver-protocol@3.18.3: + dependencies: + vscode-jsonrpc: 9.0.2 + vscode-languageserver-types: 3.18.3 + + vscode-languageserver-textdocument@1.0.14: {} + + vscode-languageserver-types@3.18.3: {} + + vscode-uri@3.2.0: {} + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 06c4a81e..1f14f608 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - packages/* - examples/* catalog: + "@volar/language-service": ^2.4.28 "@changesets/changelog-github": ^1.0.0 "@changesets/cli": ^3.0.1 "@chromatic-com/storybook": ^5.3.0 From 16ca0c3f70f7b9c1f9238d4683cecf039aa9246f Mon Sep 17 00:00:00 2001 From: fantonangeli Date: Mon, 31 Aug 2026 16:05:55 +0200 Subject: [PATCH 2/4] Fixes comment: https://github.com/open-workflow-specification/editor/pull/376#discussion_r3895020067 Signed-off-by: fantonangeli --- packages/language-service/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/language-service/README.md b/packages/language-service/README.md index 611b27c2..0b421811 100644 --- a/packages/language-service/README.md +++ b/packages/language-service/README.md @@ -45,7 +45,4 @@ pnpm run build:dev # Build package (production - includes linting and tests) pnpm run build:prod - -# Build Storybook static site -pnpm run build:storybook ``` From 813f0f2f7efb27b9e5a50fa240a9f334a5fad18a Mon Sep 17 00:00:00 2001 From: fantonangeli Date: Mon, 31 Aug 2026 18:38:23 +0200 Subject: [PATCH 3/4] Add changeset file Signed-off-by: fantonangeli --- .changeset/create-language-service.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/create-language-service.md diff --git a/.changeset/create-language-service.md b/.changeset/create-language-service.md new file mode 100644 index 00000000..67fea359 --- /dev/null +++ b/.changeset/create-language-service.md @@ -0,0 +1,5 @@ +--- +"@openworkflowspec/language-service": minor +--- + +Create the language service package foundation From 98c1aa0bcd0117d330828e269d0a18d111e4c0c5 Mon Sep 17 00:00:00 2001 From: fantonangeli Date: Tue, 1 Sep 2026 11:37:47 +0200 Subject: [PATCH 4/4] Fixes comment: https://github.com/open-workflow-specification/editor/pull/376#discussion_r3902485959 Signed-off-by: fantonangeli --- packages/language-service/vite.config.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/language-service/vite.config.ts b/packages/language-service/vite.config.ts index 03525de7..5dbee9dd 100644 --- a/packages/language-service/vite.config.ts +++ b/packages/language-service/vite.config.ts @@ -28,5 +28,8 @@ export default defineConfig({ fileName: (format) => (format === "es" ? "index.js" : `index.${format}.js`), formats: ["es"], }, + rollupOptions: { + external: [/^@volar\//], + }, }, });