diff --git a/src/api/json/catalog.json b/src/api/json/catalog.json index 9a1c3494871..f173ae05d4f 100644 --- a/src/api/json/catalog.json +++ b/src/api/json/catalog.json @@ -5036,11 +5036,29 @@ "fileMatch": ["*.ai-kit.step.yaml"], "url": "https://raw.githubusercontent.com/em-al-wi/proactions-schema/main/schema/partial-step.schema.json" }, + { + "name": "Problem package format", + "description": "Problem package metadata for programming tasks in the Kattis/CLICS problem package format", + "fileMatch": ["problem.yml", "problem.yaml"], + "url": "https://raw.githubusercontent.com/RagnarGrootKoerkamp/BAPCtools/refs/heads/main/bapctools/resources/support/schemas/problem_yaml_schema.json" + }, { "name": "Problem package generators", "description": "Generators for programming tasks in the Kattis/CLICS problem package format", "fileMatch": ["generators.yml", "generators.yaml"], - "url": "https://raw.githubusercontent.com/RagnarGrootKoerkamp/BAPCtools/refs/heads/master/support/schemas/generators_yaml_schema.json" + "url": "https://raw.githubusercontent.com/RagnarGrootKoerkamp/BAPCtools/refs/heads/main/bapctools/resources/support/schemas/generators_yaml_schema.json" + }, + { + "name": "Problem package submissions", + "description": "Submissions metadata for programming tasks in the Kattis/CLICS problem package format", + "fileMatch": ["submissions.yml", "submissions.yaml"], + "url": "https://raw.githubusercontent.com/RagnarGrootKoerkamp/BAPCtools/refs/heads/main/bapctools/resources/support/schemas/submissions_yaml_schema.json" + }, + { + "name": "Problem package test group metadata", + "description": "Test group metadata for programming tasks in the Kattis/CLICS problem package format", + "fileMatch": ["test_group.yml", "test_group.yaml"], + "url": "https://raw.githubusercontent.com/RagnarGrootKoerkamp/BAPCtools/refs/heads/main/bapctools/resources/support/schemas/test_group_yaml_schema.json" }, { "name": "project.json", @@ -8584,6 +8602,19 @@ ], "url": "https://raw.githubusercontent.com/wiremock/wiremock/refs/heads/master/schemas/wiremock-stub-mapping-or-mappings.json" }, + { + "name": "WireMock message stub mapping", + "description": "WireMock single or multiple async message stub mapping JSON. See https://wiremock.org/docs/messaging/stubbing/", + "fileMatch": [ + "wiremock-message-stub-mapping.yml", + "wiremock-message-stub-mapping.yaml", + "message-stubs.json", + "message-stub-mappings.json", + "message-stubs.yaml", + "message-stub-mappings.yaml" + ], + "url": "https://raw.githubusercontent.com/wiremock/wiremock/refs/heads/master/schemas/wiremock-message-stub-mapping-or-mappings.json" + }, { "name": "WireMock CLI local service configuration", "description": "WireMock CLI and Runner local service config file format", @@ -9166,6 +9197,15 @@ "**/models/**/*.vespertide.yml" ], "url": "https://www.schemastore.org/vespertide-model.json" + }, + { + "name": "openHAB", + "description": "Configuration files for openHAB", + "fileMatch": ["**/conf/yaml/**/*.yml", "**/conf/yaml/**/*.yaml"], + "url": "https://www.schemastore.org/openhab-5.1.json", + "versions": { + "5.1": "https://www.schemastore.org/openhab-5.1.json" + } } ] } diff --git a/src/negative_test/openhab-5.1/001_missing_version.yml b/src/negative_test/openhab-5.1/001_missing_version.yml new file mode 100644 index 00000000000..de377101e94 --- /dev/null +++ b/src/negative_test/openhab-5.1/001_missing_version.yml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +items: + MyItem: + type: String diff --git a/src/negative_test/openhab-5.1/002_dimension_invalid_item.yml b/src/negative_test/openhab-5.1/002_dimension_invalid_item.yml new file mode 100644 index 00000000000..de0ed613d97 --- /dev/null +++ b/src/negative_test/openhab-5.1/002_dimension_invalid_item.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +items: + # This item has a dimension set even though it's not a Number + MyWrongNumberItem: + type: Switch + dimension: 'W' diff --git a/src/negative_test/openhab-5.1/003_dimension_invalid_group.yml b/src/negative_test/openhab-5.1/003_dimension_invalid_group.yml new file mode 100644 index 00000000000..fe16a80e05f --- /dev/null +++ b/src/negative_test/openhab-5.1/003_dimension_invalid_group.yml @@ -0,0 +1,11 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +items: + # This group has a dimension set even though it's not a Number + MyWrongGroupItem: + type: Group + group: + type: Switch + dimension: 'W' diff --git a/src/negative_test/openhab-5.1/004_thing_channel_dimension.yml b/src/negative_test/openhab-5.1/004_thing_channel_dimension.yml new file mode 100644 index 00000000000..5a160d95952 --- /dev/null +++ b/src/negative_test/openhab-5.1/004_thing_channel_dimension.yml @@ -0,0 +1,11 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +things: + # If type is set itemType can not be set + my:thing:uuid: + channels: + channel_1: + itemType: Switch + itemDimension: W diff --git a/src/negative_test/openhab-5.1/005_thing_channel_type_invalid1.yml b/src/negative_test/openhab-5.1/005_thing_channel_type_invalid1.yml new file mode 100644 index 00000000000..cd099317ce4 --- /dev/null +++ b/src/negative_test/openhab-5.1/005_thing_channel_type_invalid1.yml @@ -0,0 +1,11 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +things: + # If type is set kind can not be set + my:thing:uuid: + channels: + channel_1: + type: switch + kind: state diff --git a/src/negative_test/openhab-5.1/006_thing_channel_type_invalid2.yml b/src/negative_test/openhab-5.1/006_thing_channel_type_invalid2.yml new file mode 100644 index 00000000000..ad8b72b6e57 --- /dev/null +++ b/src/negative_test/openhab-5.1/006_thing_channel_type_invalid2.yml @@ -0,0 +1,11 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +things: + # If type is set itemType can not be set + my:thing:uuid: + channels: + channel_1: + type: switch + itemType: String diff --git a/src/negative_test/openhab-5.1/007_thing_channel_type_invalid3.yml b/src/negative_test/openhab-5.1/007_thing_channel_type_invalid3.yml new file mode 100644 index 00000000000..698d88659a9 --- /dev/null +++ b/src/negative_test/openhab-5.1/007_thing_channel_type_invalid3.yml @@ -0,0 +1,11 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +things: + # If type is set itemType can not be set + my:thing:uuid: + channels: + channel_1: + type: switch + itemDimension: String diff --git a/src/schema-validation.jsonc b/src/schema-validation.jsonc index 9a10f93baac..25913856d83 100644 --- a/src/schema-validation.jsonc +++ b/src/schema-validation.jsonc @@ -251,6 +251,7 @@ "lsdlschema-4.1.json", "lsdlschema.json", "nodemon.json", + "openhab-5.1.json", "partial-pyright.json", "pep-723.json", "pyproject.json", @@ -298,6 +299,7 @@ "license-report-config.json", "openweather.current.json", "openweather.roadrisk.json", + "openhab-5.1.json", "specif-1.1.json", "ctfd.json", "zarf.json", diff --git a/src/schemas/json/github-workflow.json b/src/schemas/json/github-workflow.json index 74467f564ee..cc7e59a88b3 100644 --- a/src/schemas/json/github-workflow.json +++ b/src/schemas/json/github-workflow.json @@ -963,7 +963,6 @@ } } ], - "required": ["description"], "additionalProperties": false } }, diff --git a/src/schemas/json/host.json b/src/schemas/json/host.json index 7c201eb2290..2f5ad86a544 100644 --- a/src/schemas/json/host.json +++ b/src/schemas/json/host.json @@ -450,6 +450,54 @@ }, "additionalProperties": false }, + "mcp-extension": { + "type": "object", + "description": "Configuration settings for 'mcp' triggers.", + "properties": { + "instructions": { + "description": "Describes to clients how to access the remote MCP server.", + "type": "string" + }, + "serverName": { + "description": "A friendly name for the remote MCP server.", + "type": "string" + }, + "serverVersion": { + "description": "Current version of the remote MCP server.", + "type": "string" + }, + "encryptClientState": { + "description": "Determines if client state is encrypted. Defaults to true. Setting to false may be useful for debugging and test scenarios but isn't recommended for production.", + "type": "boolean", + "default": true + }, + "messageOptions": { + "description": "COptions object for the message endpoint in the SSE transport.", + "type": "object", + "properties": { + "useAbsoluteUriForEndpoint": { + "description": "If set to false, the message endpoint is provided as a relative URI during initial connections over the SSE transport. If set to true, the message endpoint is returned as an absolute URI. Using a relative URI isn't recommended unless you have a specific reason to do so.", + "type": "boolean", + "default": false + } + }, + "additionalProperties": false + }, + "system": { + "description": "COptions object for the message endpoint in the SSE transport.", + "type": "object", + "properties": { + "webhookAuthorizationLevel": { + "description": "Defines the authorization level required for the webhook endpoint. Defaults to \"System\". Allowed values are \"System\" and \"Anonymous\". When you set the value to \"Anonymous\", an access key is no longer required for requests.", + "enum": ["System", "Anonymous"], + "default": "System" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, "version-1": { "type": "object", "properties": { @@ -1480,6 +1528,9 @@ } }, "additionalProperties": false + }, + "mcp": { + "$ref": "#/definitions/mcp-extension" } }, "additionalProperties": false diff --git a/src/schemas/json/openhab-5.1.json b/src/schemas/json/openhab-5.1.json new file mode 100644 index 00000000000..7bcf8119392 --- /dev/null +++ b/src/schemas/json/openhab-5.1.json @@ -0,0 +1,261 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json.schemastore.org/openhab-5.1.json", + "$defs": { + "bool_value_type": { "enum": [true, false] }, + "thing_uid": { + "type": "string", + "pattern": "^[A-Za-z0-9]([\\w-]+:)+[\\w-]+$" + }, + "item_type_enum": { + "type": "string", + "enum": [ + "Call", + "Color", + "Contact", + "DateTime", + "Dimmer", + "Group", + "Image", + "Location", + "Number", + "Player", + "Rollershutter", + "String", + "Switch" + ] + }, + "item_dimension_type": { "type": "string" }, + "config_value_type": { + "oneOf": [ + { "$ref": "#/$defs/bool_value_type" }, + { "type": "number" }, + { "type": "string" } + ] + }, + + "key_value_config_type": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[A-Za-z]\\w*$": { "$ref": "#/$defs/config_value_type" } + } + }, + "key_array_value_config_type": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[A-Za-z]\\w*$": { + "oneOf": [ + { "$ref": "#/$defs/config_value_type" }, + { + "type": "array", + "items": { "$ref": "#/$defs/config_value_type" } + } + ] + } + } + } + }, + "title": "openHAB 5.1", + "description": "Schema for openHAB configuration files. Implements version 5.1", + "type": "object", + "additionalProperties": false, + "required": ["version"], + "properties": { + "version": { "type": "integer", "const": 1 }, + "things": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[A-Za-z0-9]([\\w-]+:)+[\\w-]+$": { + "type": "object", + "properties": { + "isBridge": { "$ref": "#/$defs/bool_value_type" }, + "bridge": { "$ref": "#/$defs/thing_uid" }, + "location": { "type": "string" }, + "config": { "$ref": "#/$defs/key_value_config_type" }, + "channels": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^.+$": { + "type": "object", + "properties": { + "type": { "type": "string" }, + "kind": { "enum": ["state", "trigger"] }, + "itemType": { "$ref": "#/$defs/item_type_enum" }, + "itemDimension": { "$ref": "#/$defs/item_dimension_type" }, + "label": { "type": "string" }, + "description": { "type": "string" }, + "config": { "$ref": "#/$defs/key_array_value_config_type" } + }, + "allOf": [ + { + "if": { "required": ["type"] }, + "then": { + "not": { + "anyOf": [ + { "required": ["kind"] }, + { "required": ["itemType"] } + ] + } + } + }, + { + "if": { "type": "object", "required": ["itemDimension"] }, + "then": { + "properties": { "itemType": { "const": "Number" } } + } + }, + { + "if": { + "type": "object", + "properties": { + "itemType": { "not": { "const": "Number" } } + } + }, + "then": { "not": { "required": ["itemDimension"] } } + } + ] + } + } + } + } + } + } + }, + "items": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^[a-zA-Z_][a-zA-Z0-9_]*$": { + "type": "object", + "properties": { + "type": { "$ref": "#/$defs/item_type_enum" }, + "dimension": { "type": "string" }, + "group": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { "$ref": "#/$defs/item_type_enum" }, + "dimension": { "type": "string" }, + "function": { + "type": "string", + "enum": [ + "EQUALITY", + "AND", + "OR", + "NAND", + "NOR", + "XOR", + "SUM", + "AVG", + "MEDIAN", + "MIN", + "MAX", + "COUNT", + "LATEST", + "EARLIEST" + ] + }, + "parameters": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "allOf": [ + { + "if": { "type": "object", "required": ["dimension"] }, + "then": { "properties": { "type": { "const": "Number" } } } + }, + { + "if": { + "type": "object", + "properties": { "type": { "not": { "const": "Number" } } } + }, + "then": { "not": { "required": ["dimension"] } } + } + ] + }, + "label": { "type": "string" }, + "icon": { "type": "string" }, + "groups": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$" + } + }, + "tags": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-zA-Z_][a-zA-Z0-9_-]*$" + } + }, + "format": { "type": "string" }, + "unit": { "type": "string" }, + "autoupdate": { "$ref": "#/$defs/bool_value_type" }, + "channel": { "type": "string" }, + "channels": { + "type": "object", + "patternProperties": { + "^.*$": { "$ref": "#/$defs/key_array_value_config_type" } + } + }, + "metadata": { + "type": "object", + "patternProperties": { + "^.*$": { + "type": "object", + "properties": { + "value": { "$ref": "#/$defs/config_value_type" }, + "config": { "$ref": "#/$defs/key_value_config_type" } + } + } + } + } + }, + "allOf": [ + { + "if": { "type": "object", "required": ["dimension"] }, + "then": { "properties": { "type": { "const": "Number" } } } + }, + { + "if": { + "type": "object", + "properties": { "type": { "not": { "const": "Number" } } } + }, + "then": { "not": { "required": ["dimension"] } } + }, + { + "not": { + "required": ["channel", "channels"] + } + } + ] + } + } + }, + "tags": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^(Location|Equipment|Point|Property)_([A-Z][A-Za-z0-9_]+)*[A-Z][A-Za-z0-9_]*$": { + "type": "object", + "properties": { + "label": { "type": "string" }, + "description": { "type": "string" }, + "synonyms": { + "type": "array", + "items": { "type": "string" } + } + } + } + } + } + } +} diff --git a/src/schemas/json/partial-mypy.json b/src/schemas/json/partial-mypy.json index 9dfe928f1a4..e8872f4944f 100644 --- a/src/schemas/json/partial-mypy.json +++ b/src/schemas/json/partial-mypy.json @@ -259,6 +259,11 @@ "default": false, "type": "boolean" }, + "allow_untyped_decorators": { + "description": "Allow decorating typed functions with untyped decorators.", + "default": false, + "type": "boolean" + }, "disallow_untyped_decorators": { "description": "Reports an error whenever a function with type annotations is decorated with a decorator without annotations.", "default": false, @@ -717,6 +722,9 @@ "check_untyped_defs": { "$ref": "#/properties/check_untyped_defs" }, + "allow_untyped_decorators": { + "$ref": "#/properties/allow_untyped_decorators" + }, "disallow_untyped_decorators": { "$ref": "#/properties/disallow_untyped_decorators" }, diff --git a/src/schemas/json/partial-pytest.json b/src/schemas/json/partial-pytest.json index 617521eafe5..a947bf634ae 100644 --- a/src/schemas/json/partial-pytest.json +++ b/src/schemas/json/partial-pytest.json @@ -997,9 +997,9 @@ "x-tombi-array-values-order": "ascending" }, "tmp_path_retention_count": { - "type": "integer", + "type": "string", "description": "How many sessions should we keep the tmp_path directories, according to tmp_path_retention_policy.", - "default": 3 + "default": "3" }, "tmp_path_retention_policy": { "type": "string", diff --git a/src/schemas/json/ruff.json b/src/schemas/json/ruff.json index 00e8580821c..f2d0f1b2e8d 100644 --- a/src/schemas/json/ruff.json +++ b/src/schemas/json/ruff.json @@ -1516,6 +1516,38 @@ "sections": { "description": "A list of mappings from section names to modules.\n\nBy default, imports are categorized according to their type (e.g., `future`, `third-party`,\nand so on). This setting allows you to group modules into custom sections, to augment or\noverride the built-in sections.\n\nFor example, to group all testing utilities, you could create a `testing` section:\n```toml\ntesting = [\"pytest\", \"hypothesis\"]\n```\n\nThe values in the list are treated as glob patterns. For example, to match all packages in\nthe LangChain ecosystem (`langchain-core`, `langchain-openai`, etc.):\n```toml\nlangchain = [\"langchain-*\"]\n```\n\nCustom sections should typically be inserted into the [`section-order`](#lint_isort_section-order) list to ensure that\nthey're displayed as a standalone group and in the intended order, as in:\n```toml\nsection-order = [\n \"future\",\n \"standard-library\",\n \"third-party\",\n \"first-party\",\n \"local-folder\",\n \"testing\"\n]\n```\n\nIf a custom section is omitted from [`section-order`](#lint_isort_section-order), imports in that section will be\nassigned to the [`default-section`](#lint_isort_default-section) (which defaults to `third-party`).", "type": ["object", "null"], + "properties": { + "first-party": { + "type": "array", + "items": { + "type": "string" + } + }, + "future": { + "type": "array", + "items": { + "type": "string" + } + }, + "local-folder": { + "type": "array", + "items": { + "type": "string" + } + }, + "standard-library": { + "type": "array", + "items": { + "type": "string" + } + }, + "third-party": { + "type": "array", + "items": { + "type": "string" + } + } + }, "additionalProperties": { "type": "array", "items": { @@ -2325,7 +2357,8 @@ "py311", "py312", "py313", - "py314" + "py314", + "py315" ] }, "Quote": { @@ -2386,6 +2419,10 @@ "parenthesize-tuple-in-subscript": { "description": "Whether to prefer accessing items keyed by tuples with\nparentheses around the tuple (see `RUF031`).", "type": ["boolean", "null"] + }, + "strictly-empty-init-modules": { + "description": "Whether to require `__init__.py` files to contain no code at all, including imports and\ndocstrings (see `RUF067`).", + "type": ["boolean", "null"] } }, "additionalProperties": false @@ -2411,6 +2448,7 @@ "AIR30", "AIR301", "AIR302", + "AIR303", "AIR31", "AIR311", "AIR312", @@ -3506,11 +3544,14 @@ "RUF064", "RUF065", "RUF066", + "RUF067", "RUF1", "RUF10", "RUF100", "RUF101", "RUF102", + "RUF103", + "RUF104", "RUF2", "RUF20", "RUF200", diff --git a/src/test/host/host.v2.json b/src/test/host/host.v2.json index bc0af25d80c..d594781b7c9 100644 --- a/src/test/host/host.v2.json +++ b/src/test/host/host.v2.json @@ -91,6 +91,18 @@ "maxOutstandingRequests": 200, "routePrefix": "api" }, + "mcp": { + "encryptClientState": true, + "instructions": "Some test instructions on how to use the server", + "messageOptions": { + "useAbsoluteUriForEndpoint": false + }, + "serverName": "TestServer", + "serverVersion": "2.0.0", + "system": { + "webhookAuthorizationLevel": "System" + } + }, "queues": { "batchSize": 16, "maxDequeueCount": 5, diff --git a/src/test/openhab-5.1/documentation_tests.yml b/src/test/openhab-5.1/documentation_tests.yml new file mode 100644 index 00000000000..e9dbe3c9f1d --- /dev/null +++ b/src/test/openhab-5.1/documentation_tests.yml @@ -0,0 +1,158 @@ +# yaml-language-server: $schema=../../schemas/json/openhab-5.1.json + +version: 1 + +tags: + Property_Minimum: {} + + Equipment_OnlyLabel: + label: OnlyLabel + + Location_Intermediate1_Intermediate2_TagName1: + label: My Label + description: The description + synonyms: + - My Synonym1 + - My Synonym2 + +things: + # Minimum Bridge + mqtt:broker:mosquitto: + isBridge: true + config: + lwtMessage: offline + lwtQos: 1 + enableDiscovery: false + + # Thing for bridge with multiple channels + mqtt:topic:some-switch: + bridge: mqtt:broker:mosquitto + label: Some Switch + config: + availabilityTopic: some-switch/status + payloadAvailable: online + payloadNotAvailable: offline + channels: + switch1: + type: switch + config: + stateTopic: some-switch/switch/switch1/state + commandTopic: some-switch/switch/switch1/command + button1: + type: string + config: + stateTopic: some-switch/button1 + postCommand: true + statusled: + type: switch + config: + stateTopic: some-switch/light/status_led/state + commandTopic: some-switch/light/status_led/command + transformationPattern: + - JSONPATH:$.state + formatBeforePublish: '{"state": "%s"}' + + # Example to configure a built-in channel + astro:sun:home: + config: + geolocation: 52.518771,13.375420 + interval: 60 + channels: + rise#event: + type: rangeEvent + config: + offset: -30 + + # Checks for kind and itemType in channel definitions + thing:with:channel:configs: + channels: + channel1: + kind: state + itemType: Number + itemDimension: W + channel2: + kind: trigger + itemType: String + +items: + MinimumItem: + type: Dimmer + + FullItem: + type: Switch + label: MyLabel + icon: my_icon + autoupdate: false + format: '%d' + groups: + - GroupFuncWithParameters + tags: + - Location_Indoor_Room_MyRoom + channel: binding:thing:some_uid:name + metadata: + expire: + value: 3s + + NumberItemWithoutDimension: + type: Number + + NumberItemWithDimension: + type: Number + dimension: '°C' + + ItemChannelsLongFormNoConfig: + type: String + channels: + mqtt:topic:some-switch:button1: {} + + Item2ChannelsNoConfig: + type: Contact + channels: + mqtt:topic:some-switch:button1: {} + mqtt:topic:some-switch:button2: {} + + ItemChannelProfile: + type: Contact + channels: + mqtt:topic:some-switch:statusled: + profile: transform:MAP + function: '|open=ON;closed=OFF' + + ItemMetadataNoValue: + type: Rollershutter + metadata: + expire: + config: + duration: 3s + state: 0 + + ItemFullMetadata: + type: Location + metadata: + expire: + value: 'MyValue' + config: + key: value + + MinimumGroup: + type: Group + + GroupWithType: + type: Group + group: + type: Number + + GroupTypeWithDimension: + type: Group + group: + type: Number + dimension: '°C' + + GroupFuncWithParameters: + type: Group + group: + type: Switch + function: AND + parameters: + - ON + - OFF