From 375bb12d47c816abcee56f5b1227d85fef27508e Mon Sep 17 00:00:00 2001 From: perrozzi Date: Mon, 8 Sep 2025 13:32:10 +0200 Subject: [PATCH 1/2] OpenAPI (#47) * Add OpenAPI compatibility documentation - Add OpenAPI compatibility section explaining UTCP as agent-focused extension - Include minimal OpenAPI ingestion example in Quick Start - Position information early in documentation for better user understanding * Clarify OpenAPI conversion is optional - Change 'are automatically converted' to 'can be automatically converted' - More accurate description of optional conversion process * Emphasize zero infrastructure requirement - Add 'or additional infrastructure' to OpenAPI compatibility section - Reinforces UTCP's core value proposition of no wrapper tax * Update index.md --------- Co-authored-by: Razvan Radulescu <43811028+h3xxit@users.noreply.github.com> --- docs/index.md | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index 2355a3e..9f0da6a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,6 +28,10 @@ UTCP acts as a **"manual"** that tells agents how to call your tools directly: *"If a human can call your API, an AI agent should be able to call it too - with the same security and no additional infrastructure."* ::: +## OpenAPI Compatibility + +UTCP extends OpenAPI for AI agents while maintaining full backward compatibility. Where OpenAPI describes APIs for human developers, UTCP adds agent-focused enhancements: `tags` for categorization, `average_response_size` for resource planning, multi-protocol support (CLI, gRPC, WebSocket), and direct execution instructions. Existing OpenAPI specs can be automatically converted to UTCP manuals without requiring API changes or additional infrastructure. + ## Quick Start (5 Minutes) ### 1. Install UTCP @@ -44,7 +48,12 @@ npm install @utcp/core @utcp/http ### 2. Expose Your First Tool -Add a discovery endpoint to your existing API: +**Option A: Discovery via existing OpenAPI spec** + +**Generate OpenAPI endpoint**: `GET http://api.github.com/openapi.json` + + +**Option B: Add a discovery endpoint to your existing API** **Add endpoint**: `GET /utcp` **Return your UTCP manual**: @@ -72,25 +81,50 @@ Add a discovery endpoint to your existing API: "var_name": "appid", "location": "query" } - } - }] } ``` ### 3. Call Your Tool -**Configure UTCP client**: +**Option A: Configure UTCP client**: ```json { "manual_call_templates": [{ "name": "weather_api", "call_template_type": "http", - "url": "http://localhost:8000/utcp", + "url": "http://localhost:8000/utcp", // Or http://api.github.com/openapi.json, the openapi spec gets converted automatically "http_method": "GET" }] } ``` +**Option B: Convert OpenAPI spec to UTCP manual manually** + +```python +async def convert_api(): + async with aiohttp.ClientSession() as session: + async with session.get("https://api.github.com/openapi.json") as response: + openapi_spec = await response.json() + + converter = OpenApiConverter(openapi_spec) + manual = converter.convert() + + print(f"Generated {len(manual.tools)} tools from GitHub API!") + return manual +``` + +Then save that to a text file and load it with the text configuration: +```json +{ + "manual_call_templates": [{ + "name": "github_manual", + "call_template_type": "text", + "file_path": "./github_manual.json", + }] +} +``` + + **Call the tool**: 1. Initialize UTCP client with configuration 2. Discover tools from weather API From dcb497bf08db51e924db80ac6b6a7e860c03b690 Mon Sep 17 00:00:00 2001 From: Razvan Radulescu <43811028+h3xxit@users.noreply.github.com> Date: Tue, 9 Sep 2025 13:55:20 +0200 Subject: [PATCH 2/2] Fix a lot of issues --- docs/for-tool-providers.md | 17 +- docs/implementation.md | 1 - docs/index.md | 8 +- docs/migration-v0.1-to-v1.0.md | 3 +- docs/protocols/http.md | 227 +++-- docs/protocols/index.md | 6 +- docs/protocols/mcp.md | 308 +++++-- docs/protocols/sse.md | 272 +++--- docs/protocols/streamable-http.md | 222 ++++- docs/protocols/text.md | 426 +++------ docs/protocols/websocket.md | 355 -------- docs/security.md | 25 - docusaurus.config.ts | 4 + package-lock.json | 1403 ++++++++++++++++++++++++++++- package.json | 1 + 15 files changed, 2236 insertions(+), 1042 deletions(-) delete mode 100644 docs/protocols/websocket.md diff --git a/docs/for-tool-providers.md b/docs/for-tool-providers.md index 87ff739..34457a1 100644 --- a/docs/for-tool-providers.md +++ b/docs/for-tool-providers.md @@ -45,7 +45,7 @@ As a tool provider, you'll create a **UTCP Manual** - a standardized description }, "tool_call_template": { "call_template_type": "http", - "url": "https://api.example.com/users/${user_id}", + "url": "https://api.example.com/users/{user_id}", "http_method": "GET" } } @@ -236,11 +236,7 @@ Use `${VARIABLE_NAME}` syntax for dynamic values: ```json { - "url": "https://api.example.com/users/${user_id}", - "body": { - "name": "${name}", - "email": "${email}" - } + "url": "https://api.example.com/users/{user_id}" } ``` @@ -270,8 +266,7 @@ Use `${VARIABLE_NAME}` syntax for dynamic values: "name": "get_data", "tool_call_template": { "call_template_type": "http", - "url": "${base_url}/data", - "timeout": "${timeout}" + "url": "${base_url}/data" } } ] @@ -327,7 +322,7 @@ The UTCP manual describes how to call your existing endpoints: }, "tool_call_template": { "call_template_type": "http", - "url": "https://api.example.com/users/${user_id}", + "url": "https://api.example.com/users/{user_id}", "http_method": "GET", "auth": { "auth_type": "api_key", @@ -550,9 +545,7 @@ Test your manual with UTCP clients: "call_template_type": "http", "url": "https://api.example.com/batch", "http_method": "POST", - "body": { - "items": "${items}" - } + "body_field": "items" } } ``` diff --git a/docs/implementation.md b/docs/implementation.md index c1aee3a..0eec31b 100644 --- a/docs/implementation.md +++ b/docs/implementation.md @@ -146,7 +146,6 @@ Call templates define how to invoke tools using specific protocols: } Tool arguments not used in the URL path or headers will be sent as query parameters for GET requests, or in the request body for POST/PUT/PATCH requests. The `body_field` specifies which tool argument contains the data for the request body. -} ``` #### CLI Call Template diff --git a/docs/index.md b/docs/index.md index 9f0da6a..c9c4137 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ UTCP acts as a **"manual"** that tells agents how to call your tools directly: ## OpenAPI Compatibility -UTCP extends OpenAPI for AI agents while maintaining full backward compatibility. Where OpenAPI describes APIs for human developers, UTCP adds agent-focused enhancements: `tags` for categorization, `average_response_size` for resource planning, multi-protocol support (CLI, gRPC, WebSocket), and direct execution instructions. Existing OpenAPI specs can be automatically converted to UTCP manuals without requiring API changes or additional infrastructure. +UTCP extends OpenAPI for AI agents while maintaining full backward compatibility. Where OpenAPI describes APIs for human developers, UTCP adds agent-focused enhancements: `tags` for categorization, `average_response_size` for resource planning, multi-protocol support (HTTP, CLI, gRPC, MCP), and direct execution instructions. Existing OpenAPI specs can be automatically converted to UTCP manuals without requiring API changes or additional infrastructure. ## Quick Start (5 Minutes) @@ -130,7 +130,6 @@ Then save that to a text file and load it with the text configuration: 2. Discover tools from weather API 3. Call `get_weather` tool with location parameter 4. Receive weather data response -``` **That's it!** Your tool is now discoverable and callable by any UTCP client. @@ -140,7 +139,7 @@ Then save that to a text file and load it with the text configuration: |---------|-------------| | **🚀 Zero Latency Overhead** | Direct tool calls, no proxy servers | | **🔒 Native Security** | Use your existing authentication and authorization | -| **🌐 Protocol Flexibility** | HTTP, WebSocket, CLI, GraphQL, and more | +| **🌐 Protocol Flexibility** | HTTP, MCP, CLI, GraphQL, and more | | **⚡ Easy Integration** | Add one endpoint, no infrastructure changes | | **📈 Scalable** | Leverage your existing scaling and monitoring | @@ -166,7 +165,6 @@ UTCP supports multiple communication protocols through plugins: | Protocol | Use Case | Plugin | Status | |----------|----------|--------|--------| | **[HTTP](./protocols/http.md)** | REST APIs, webhooks | `utcp-http` | ✅ Stable | -| **[WebSocket](./protocols/websocket.md)** | Real-time communication | `utcp-websocket` | ✅ Stable | | **[CLI](./protocols/cli.md)** | Command-line tools | `utcp-cli` | ✅ Stable | | **[Server-Sent Events](./protocols/streamable-http.md)** | Streaming data | `utcp-http` | ✅ Stable | | **[Text Files](./protocols/text.md)** | File reading | `utcp-text` | ✅ Stable | @@ -185,7 +183,7 @@ UTCP v1.0 features a modular, plugin-based architecture: - **[UTCP Client](./api/core/utcp/utcp_client.md)**: Tool discovery and execution engine ### Plugin System -- **Protocol Plugins**: HTTP, WebSocket, CLI, etc. +- **Protocol Plugins**: HTTP, MCP, CLI, etc. - **Custom Protocols**: Extend with your own communication methods - **Tool Repositories**: Pluggable storage for tool definitions - **Search Strategies**: Customizable tool discovery algorithms diff --git a/docs/migration-v0.1-to-v1.0.md b/docs/migration-v0.1-to-v1.0.md index eb50de7..38eb651 100644 --- a/docs/migration-v0.1-to-v1.0.md +++ b/docs/migration-v0.1-to-v1.0.md @@ -139,7 +139,7 @@ load_variables_from: ```json { "manual_version": "1.0.0", - "utcp_version": "1.0.1", + "utcp_version": "0.2.0", "info": { "title": "Weather API", "version": "1.0.0", @@ -174,7 +174,6 @@ load_variables_from: "var_name": "appid", "location": "query" } - } } ] } diff --git a/docs/protocols/http.md b/docs/protocols/http.md index 6340aeb..2c19f69 100644 --- a/docs/protocols/http.md +++ b/docs/protocols/http.md @@ -13,31 +13,29 @@ The HTTP protocol plugin enables UTCP to call tools via HTTP/HTTPS requests. Thi ```json { "call_template_type": "http", - "url": "https://api.example.com/endpoint", + "url": "https://api.example.com/users/{user_id}", "http_method": "GET|POST|PUT|DELETE|PATCH", + "content_type": "application/json", "headers": { - "Content-Type": "application/json", - "User-Agent": "UTCP-Client/1.0" + "X-Custom-Header": "static_value" }, - "query_params": { - "param1": "${variable1}", - "param2": "static_value" - }, - "body": { - "data": "${input_data}", - "timestamp": "${current_time}" - }, - "timeout": 30, - "verify_ssl": true, + "body_field": "body", + "header_fields": ["user_agent", "request_id"], "auth": { "auth_type": "api_key|basic|oauth2", "api_key": "${API_KEY}", - "var_name": "Authorization", - "location": "header" + "var_name": "Authorization", + "location": "header|query|cookie" } } ``` +### Field Descriptions + +For detailed field descriptions, examples, and implementation details, see: +- **[HttpCallTemplate API Reference](../api/plugins/communication_protocols/http/src/utcp_http/http_call_template.md)** - Complete field documentation with examples +- **[HttpCommunicationProtocol API Reference](../api/plugins/communication_protocols/http/src/utcp_http/http_communication_protocol.md)** - Implementation details and method documentation + ## Supported HTTP Methods | Method | Use Case | Body Support | @@ -57,11 +55,16 @@ The HTTP protocol plugin enables UTCP to call tools via HTTP/HTTPS requests. Thi "auth_type": "api_key", "api_key": "${API_KEY}", "var_name": "X-API-Key", - "location": "header" + "location": "header|query|cookie" } } ``` +Supported locations: +- `"header"`: API key sent as HTTP header +- `"query"`: API key sent as query parameter +- `"cookie"`: API key sent as HTTP cookie + ### Basic Authentication ```json { @@ -86,37 +89,81 @@ The HTTP protocol plugin enables UTCP to call tools via HTTP/HTTPS requests. Thi } ``` -## Variable Substitution +## Parameter Handling + +The HTTP protocol handles tool arguments in a hierarchical manner: + +1. **URL Path Parameters**: Arguments matching `{param_name}` in the URL are substituted directly +2. **Body Field**: If `body_field` is specified, that argument becomes the request body +3. **Header Fields**: Arguments listed in `header_fields` become request headers +4. **Query Parameters**: All remaining arguments become query parameters -Variables in call templates are substituted with values from: -- Tool call arguments: `${argument_name}` -- Environment variables: `${ENV_VAR}` -- Configuration variables: `${config.variable}` +### URL Path Parameters +URL templates can include path parameters using `{parameter_name}` syntax: -Example: ```json { - "url": "https://api.example.com/users/${user_id}", - "headers": { - "Authorization": "Bearer ${ACCESS_TOKEN}" - }, - "query_params": { - "format": "${output_format}", - "limit": "${max_results}" + "url": "https://api.example.com/users/{user_id}/posts/{post_id}" +} +``` + +When calling a tool with arguments `{"user_id": "123", "post_id": "456", "limit": "10"}`, the URL becomes: +`https://api.example.com/users/123/posts/456?limit=10` + +### Body Field Mapping +Specify which tool argument should be sent as the request body: + +```json +{ + "body_field": "data", + "content_type": "application/json" +} +``` + +### Header Field Mapping +Map specific tool arguments to HTTP headers: + +```json +{ + "header_fields": ["user_agent", "request_id"] +} +``` + +Tool arguments `user_agent` and `request_id` will be sent as HTTP headers. + +### Variable Substitution in Authentication +Authentication fields support environment variable substitution: + +```json +{ + "auth": { + "auth_type": "api_key", + "api_key": "Bearer ${API_KEY}", + "var_name": "Authorization", + "location": "header" } } ``` ## OpenAPI Integration -The HTTP protocol plugin can automatically generate UTCP manuals from OpenAPI/Swagger specifications: +The HTTP communication protocol automatically detects and converts OpenAPI/Swagger specifications to UTCP manuals: -1. **Automatic Discovery**: Point to an OpenAPI spec URL -2. **Schema Conversion**: Converts OpenAPI paths to UTCP tools -3. **Authentication Mapping**: Maps OpenAPI security schemes to UTCP auth -4. **Parameter Mapping**: Converts OpenAPI parameters to UTCP inputs +### Automatic Detection +When registering an HTTP provider, the protocol: +1. Fetches content from the specified URL +2. Checks if the response contains `utcp_version` and `tools` fields (UTCP manual) +3. If not, assumes it's an OpenAPI specification and converts it automatically -Example OpenAPI to UTCP conversion: +### Conversion Process +The `OpenApiConverter` handles: +- **Path Mapping**: OpenAPI paths become UTCP tool URLs with path parameters +- **Method Mapping**: HTTP methods are preserved +- **Parameter Mapping**: Path, query, header, and body parameters are mapped appropriately +- **Authentication**: OpenAPI security schemes are converted to UTCP auth configurations +- **Schema Validation**: OpenAPI schemas become UTCP input/output schemas + +### Example Conversion ```yaml # OpenAPI Specification paths: @@ -130,13 +177,13 @@ paths: type: string ``` -Becomes: +Becomes a UTCP tool: ```json { "name": "get_user", "tool_call_template": { "call_template_type": "http", - "url": "https://api.example.com/users/${id}", + "url": "https://api.example.com/users/{id}", "http_method": "GET" }, "inputs": { @@ -152,21 +199,31 @@ Becomes: ## Response Handling HTTP responses are processed based on: -- **Status Codes**: 2xx considered success, others as errors -- **Content-Type**: JSON, XML, text, and binary content support -- **Headers**: Response headers available in tool output -- **Error Mapping**: HTTP errors mapped to UTCP exceptions - -## Configuration Options - -| Option | Type | Default | Description | -|--------|------|---------|-------------| -| `timeout` | number | 30 | Request timeout in seconds | -| `verify_ssl` | boolean | true | Verify SSL certificates | -| `follow_redirects` | boolean | true | Follow HTTP redirects | -| `max_redirects` | number | 5 | Maximum redirect hops | -| `retry_count` | number | 0 | Number of retry attempts | -| `retry_delay` | number | 1 | Delay between retries (seconds) | +- **Status Codes**: 2xx considered success, 4xx/5xx raise exceptions +- **Content-Type**: + - `application/json`: Parsed as JSON object + - Other types: Returned as text string +- **Error Handling**: HTTP client errors are logged and re-raised +- **Timeouts**: 10 seconds for tool discovery, 30 seconds for tool execution + +## Security Features + +### HTTPS Enforcement +The HTTP protocol enforces secure connections by only allowing: +- HTTPS URLs (`https://`) +- Localhost URLs (`http://localhost` or `http://127.0.0.1`) + +Any other HTTP URLs will be rejected with a security error to prevent man-in-the-middle attacks. + +### OAuth2 Token Caching +OAuth2 tokens are automatically cached by `client_id` to avoid repeated authentication requests. The protocol supports both: +- **Body credentials**: Client ID/secret in request body +- **Header credentials**: Client ID/secret as Basic Auth header + +### Request Security +- URL path parameters are properly URL-encoded to prevent path injection +- All authentication credentials support environment variable substitution +- Cookies are supported for API key authentication when required ## Security Considerations @@ -188,10 +245,10 @@ HTTP responses are processed based on: - Implement rate limiting on the tool provider side ### Network Security -- Use HTTPS for all production communications -- Implement proper firewall rules -- Consider using VPNs or private networks for sensitive tools -- Monitor and log all HTTP requests for security analysis +- HTTPS is enforced by the protocol (except for localhost development) +- All credentials should use environment variable substitution (e.g., `${API_KEY}`) +- Path parameters are automatically URL-encoded to prevent injection attacks +- OAuth2 tokens are cached securely and not logged ## Error Handling @@ -210,10 +267,10 @@ Common HTTP errors and their meanings: ## Best Practices ### Performance -- Use connection pooling for multiple requests -- Implement appropriate timeouts -- Consider request/response compression -- Cache responses when appropriate +- Each request uses a fresh aiohttp ClientSession +- Tool discovery timeout: 10 seconds +- Tool execution timeout: 30 seconds +- OAuth2 tokens are cached to reduce authentication overhead ### Reliability - Implement retry logic with exponential backoff @@ -227,10 +284,58 @@ Common HTTP errors and their meanings: - Provide usage examples - Version your APIs and update call templates accordingly +## Complete Examples + +### Basic GET Request +```json +{ + "name": "get_user", + "call_template_type": "http", + "url": "https://api.example.com/users/{user_id}", + "http_method": "GET" +} +``` + +### POST with Authentication and Body +```json +{ + "name": "create_user", + "call_template_type": "http", + "url": "https://api.example.com/users", + "http_method": "POST", + "content_type": "application/json", + "body_field": "user_data", + "header_fields": ["request_id"], + "auth": { + "auth_type": "api_key", + "api_key": "Bearer ${API_KEY}", + "var_name": "Authorization", + "location": "header" + } +} +``` + +### OAuth2 Authentication +```json +{ + "name": "oauth_api", + "call_template_type": "http", + "url": "https://api.example.com/data", + "http_method": "GET", + "auth": { + "auth_type": "oauth2", + "client_id": "${CLIENT_ID}", + "client_secret": "${CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "read write" + } +} +``` + ## Language-Specific Implementation For implementation details and examples in your programming language: -- **Multi-language**: [UTCP HTTP Protocol Examples](https://github.com/universal-tool-calling-protocol) - HTTP protocol examples across multiple languages +- **Python**: See `python-utcp/plugins/communication_protocols/http/` - **TypeScript**: [TypeScript HTTP Protocol Documentation](https://github.com/universal-tool-calling-protocol/typescript-utcp/blob/main/docs/protocols/http.md) - **Other languages**: Check respective repositories in the [UTCP GitHub organization](https://github.com/universal-tool-calling-protocol) diff --git a/docs/protocols/index.md b/docs/protocols/index.md index 9a4f701..a6dfdc8 100644 --- a/docs/protocols/index.md +++ b/docs/protocols/index.md @@ -13,7 +13,6 @@ UTCP v1.0 features a modular, plugin-based architecture where different communic | Protocol | Plugin Package | Call Template | Use Cases | |----------|----------------|---------------|-----------| | **[HTTP](./http.md)** | `utcp-http` | `HttpCallTemplate` | REST APIs, webhooks, web services | -| **[WebSocket](./websocket.md)** | `utcp-websocket` | `WebSocketCallTemplate` | Real-time communication, streaming | | **[CLI](./cli.md)** | `utcp-cli` | `CliCallTemplate` | Command-line tools, scripts | | **[Server-Sent Events](./sse.md)** | `utcp-http` | `SseCallTemplate` | Event streaming, live updates | | **[Text Files](./text.md)** | `utcp-text` | `TextCallTemplate` | File reading, static content | @@ -43,10 +42,10 @@ Protocol plugins are available for different programming languages: ```bash # Example installation (Python) -pip install utcp-http utcp-cli utcp-websocket utcp-text utcp-mcp +pip install utcp-http utcp-cli utcp-text utcp-mcp # Example installation (Node.js) -npm install @utcp/http @utcp/cli @utcp/websocket @utcp/text @utcp/mcp +npm install @utcp/http @utcp/cli @utcp/text @utcp/mcp ``` For other languages, check the [UTCP GitHub organization](https://github.com/universal-tool-calling-protocol) @@ -76,7 +75,6 @@ Example call template structure: Choose the right protocol plugin based on your needs: - **HTTP**: Most common for REST APIs and web services -- **WebSocket**: Real-time bidirectional communication - **CLI**: Wrapping existing command-line tools - **SSE**: Server-sent events for streaming data - **Text**: Reading configuration files or static content diff --git a/docs/protocols/mcp.md b/docs/protocols/mcp.md index 13da0f6..54f3d73 100644 --- a/docs/protocols/mcp.md +++ b/docs/protocols/mcp.md @@ -13,33 +13,61 @@ The MCP (Model Context Protocol) plugin provides interoperability between UTCP a ```json { "call_template_type": "mcp", - "server_config": { - "command": "node", - "args": ["mcp-server.js"], - "working_directory": "/app/mcp", - "env": { - "NODE_ENV": "production", - "LOG_LEVEL": "info" - }, - "timeout": 30 + "config": { + "mcpServers": { + "filesystem": { + "command": "node", + "args": ["mcp-server.js"], + "cwd": "/app/mcp", + "env": { + "NODE_ENV": "production", + "LOG_LEVEL": "info" + } + } + } }, - "connection_timeout": 10, - "request_timeout": 30 + "auth": { + "auth_type": "oauth2", + "client_id": "${CLIENT_ID}", + "client_secret": "${CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "read:tools" + }, + "register_resources_as_tools": false } ``` +## Field Descriptions + +For detailed field specifications, examples, and validation rules, see: +- **[McpCallTemplate API Reference](../api/plugins/communication_protocols/mcp/src/utcp_mcp/mcp_call_template.md)** - Complete field documentation with examples +- **[McpCommunicationProtocol API Reference](../api/plugins/communication_protocols/mcp/src/utcp_mcp/mcp_communication_protocol.md)** - Implementation details and method documentation + +### Key Fields + +| Field | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `call_template_type` | string | Yes | - | Always "mcp" for MCP providers | +| `config` | object | Yes | - | Configuration object containing MCP server definitions | +| `auth` | object | No | null | Optional OAuth2 authentication for HTTP-based MCP servers | +| `register_resources_as_tools` | boolean | No | false | Whether to register MCP resources as callable tools | + ## Server Configuration -### Command-based Servers +### Command-based (stdio) Servers ```json { - "server_config": { - "command": "python", - "args": ["-m", "mcp_server", "--config", "config.json"], - "working_directory": "/app", - "env": { - "PYTHONPATH": "/app/lib", - "API_KEY": "${MCP_API_KEY}" + "config": { + "mcpServers": { + "my_server": { + "command": "python", + "args": ["-m", "mcp_server", "--config", "config.json"], + "cwd": "/app", + "env": { + "PYTHONPATH": "/app/lib", + "API_KEY": "${MCP_API_KEY}" + } + } } } } @@ -48,11 +76,41 @@ The MCP (Model Context Protocol) plugin provides interoperability between UTCP a ### HTTP-based Servers ```json { - "server_config": { - "transport": "http", - "url": "http://localhost:8080/mcp", - "headers": { - "Authorization": "Bearer ${MCP_TOKEN}" + "config": { + "mcpServers": { + "remote_server": { + "transport": "http", + "url": "https://mcp.example.com/api" + } + } + }, + "auth": { + "auth_type": "oauth2", + "client_id": "${CLIENT_ID}", + "client_secret": "${CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "mcp:access" + } +} +``` + +### Multiple Servers +```json +{ + "config": { + "mcpServers": { + "filesystem": { + "command": "node", + "args": ["filesystem-server.js"] + }, + "database": { + "command": "python", + "args": ["-m", "db_server"] + }, + "remote_api": { + "transport": "http", + "url": "https://api.example.com/mcp" + } } } } @@ -79,12 +137,13 @@ The MCP protocol plugin enables a gradual migration path from MCP to native UTCP ## Tool Discovery -MCP servers expose tools through the standard MCP protocol. The UTCP MCP plugin: +The MCP protocol implementation automatically discovers and maps tools: -1. **Connects** to the MCP server using stdio or HTTP transport -2. **Discovers** available tools via MCP's `tools/list` method -3. **Maps** MCP tool definitions to UTCP tool format -4. **Registers** tools in the UTCP client +1. **Session Management**: Creates persistent sessions with MCP servers using MCPClient +2. **Tool Discovery**: Lists available tools via MCP's `list_tools` method +3. **Tool Prefixing**: Adds server name prefix (e.g., `filesystem.read_file`) to ensure uniqueness +4. **Resource Support**: Optionally registers MCP resources as callable tools when `register_resources_as_tools` is true +5. **Tool Mapping**: Converts MCP tool schema to UTCP tool format automatically ## Request/Response Mapping @@ -105,9 +164,9 @@ MCP servers expose tools through the standard MCP protocol. The UTCP MCP plugin: // UTCP Tool (after mapping) { - "name": "read_file", + "name": "filesystem.read_file", "description": "Read contents of a file", - "inputs": { + "input_schema": { "type": "object", "properties": { "path": {"type": "string"} @@ -116,37 +175,65 @@ MCP servers expose tools through the standard MCP protocol. The UTCP MCP plugin: }, "tool_call_template": { "call_template_type": "mcp", - "server_config": {...} + "config": { + "mcpServers": {...} + } } } ``` ### Request Flow -1. UTCP client receives tool call -2. MCP plugin formats request as MCP `tools/call` -3. Request sent to MCP server -4. MCP server processes and responds -5. Response mapped back to UTCP format - -## Authentication and Security +1. UTCP client receives tool call with server-prefixed name (e.g., `filesystem.read_file`) +2. MCP plugin extracts server name and tool name +3. Gets or creates session with target MCP server +4. Calls MCP server's `call_tool` method +5. Processes response content (text, JSON, structured output) +6. Returns mapped result to UTCP client + +### Response Processing +The implementation intelligently processes MCP responses: +- **Structured output**: Returns `result.structured_output` if available +- **Text content**: Attempts JSON parsing, number parsing, or returns as string +- **List content**: Processes each item and returns as list or single item +- **Error handling**: Session-level errors trigger session restart + +## Authentication + +### OAuth2 Authentication (HTTP Servers) +```json +{ + "auth": { + "auth_type": "oauth2", + "client_id": "${CLIENT_ID}", + "client_secret": "${CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "mcp:read mcp:write" + } +} +``` -### Server Authentication +### Environment-based Authentication (stdio Servers) ```json { - "server_config": { - "command": "secure-mcp-server", - "env": { - "MCP_AUTH_TOKEN": "${MCP_SERVER_TOKEN}", - "MCP_CLIENT_ID": "${MCP_CLIENT_ID}" + "config": { + "mcpServers": { + "secure_server": { + "command": "secure-mcp-server", + "env": { + "MCP_AUTH_TOKEN": "${MCP_SERVER_TOKEN}", + "MCP_CLIENT_ID": "${MCP_CLIENT_ID}" + } + } } } } ``` -### Transport Security -- **stdio**: Inherits process security model -- **HTTP**: Use HTTPS and proper authentication headers -- **WebSocket**: Use WSS and authentication tokens +### Security Features +- **OAuth2 token caching**: Tokens cached by client_id to avoid repeated requests +- **Session management**: Persistent sessions with automatic error recovery +- **Environment variables**: Use `${VAR_NAME}` syntax for sensitive credentials +- **Transport security**: stdio inherits process security, HTTP supports OAuth2 ## Error Handling @@ -184,53 +271,70 @@ MCP errors are mapped to UTCP exceptions: ## Limitations -### MCP Feature Support -Not all MCP features are supported through UTCP: -- **Resources**: Not directly mapped to UTCP tools +### Current Limitations - **Prompts**: Not supported in UTCP model - **Sampling**: Not applicable to tool calling +- **Streaming**: MCP streaming calls return single result (no streaming support) -### Protocol Differences -- MCP's bidirectional communication vs UTCP's request/response -- MCP's resource model vs UTCP's tool-only model -- Different authentication mechanisms +### MCP Feature Support +Full support for core MCP features: +- **Tools**: Complete tool discovery and execution support +- **Resources**: Optional support via `register_resources_as_tools` flag +- **Authentication**: OAuth2 support for HTTP-based servers +- **Session management**: Persistent sessions with automatic recovery +- **Multiple servers**: Single provider can manage multiple MCP servers + +### Protocol Mapping +- **Tool naming**: Server-prefixed names ensure uniqueness across multiple servers +- **Response processing**: Intelligent parsing of MCP response formats +- **Error handling**: Session-level vs protocol-level error distinction +- **Resource tools**: Resources exposed as callable tools when enabled ## Configuration Examples ### Development Setup ```json { - "manual_call_templates": [{ - "name": "dev_mcp", - "call_template_type": "mcp", - "server_config": { - "command": "node", - "args": ["dev-server.js"], - "env": {"NODE_ENV": "development"} - }, - "connection_timeout": 5, - "request_timeout": 10 - }] + "name": "dev_mcp", + "call_template_type": "mcp", + "config": { + "mcpServers": { + "filesystem": { + "command": "node", + "args": ["dev-server.js"], + "env": {"NODE_ENV": "development"} + }, + "database": { + "command": "python", + "args": ["-m", "db_server", "--dev"] + } + } + }, + "register_resources_as_tools": true } ``` ### Production Setup ```json { - "manual_call_templates": [{ - "name": "prod_mcp", - "call_template_type": "mcp", - "server_config": { - "transport": "http", - "url": "https://mcp.example.com/api", - "headers": { - "Authorization": "Bearer ${MCP_PROD_TOKEN}", - "X-Client-Version": "1.0.0" + "name": "prod_mcp", + "call_template_type": "mcp", + "config": { + "mcpServers": { + "api_server": { + "transport": "http", + "url": "https://mcp.example.com/api" } - }, - "connection_timeout": 30, - "request_timeout": 60 - }] + } + }, + "auth": { + "auth_type": "oauth2", + "client_id": "${MCP_CLIENT_ID}", + "client_secret": "${MCP_CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "mcp:access" + }, + "register_resources_as_tools": false } ``` @@ -257,10 +361,44 @@ Not all MCP features are supported through UTCP: - Monitor for suspicious activity - Keep MCP servers updated -## Language-Specific Implementation +## Implementation Notes + +The MCP protocol implementation provides: + +- **Session persistence**: Reuses MCP sessions for better performance +- **Automatic recovery**: Handles session failures with automatic retry +- **Multi-server support**: Single provider manages multiple MCP servers +- **Resource integration**: Optional resource-to-tool mapping +- **OAuth2 support**: Full OAuth2 authentication for HTTP servers +- **Intelligent response processing**: Handles various MCP response formats + +### Usage Example +```python +import asyncio +from utcp_client import UtcpClient + +async def main(): + client = UtcpClient() + + # Register MCP provider with multiple servers + await client.register_tool_provider(mcp_manual) + + # Call tools with server-prefixed names + result = await client.call_tool("filesystem.read_file", {"path": "/data/file.txt"}) + + # Access resources as tools (if enabled) + resource_data = await client.call_tool("filesystem.resource_config", {}) + + await client.close() + +if __name__ == "__main__": + asyncio.run(main()) +``` + +## Related Protocols -For implementation details and examples in your programming language: +- **[HTTP](./http.md)** - For native HTTP-based tool implementations +- **[Server-Sent Events (SSE)](./sse.md)** - For real-time streaming tools +- **TCP/UDP** - For custom protocol implementations -- **Multi-language**: [UTCP MCP Protocol Examples](https://github.com/universal-tool-calling-protocol) - MCP protocol examples across multiple languages -- **TypeScript**: [TypeScript MCP Protocol Documentation](https://github.com/universal-tool-calling-protocol/typescript-utcp/blob/main/docs/protocols/mcp.md) -- **Other languages**: Check respective repositories in the [UTCP GitHub organization](https://github.com/universal-tool-calling-protocol) +For complete implementation details, see the [MCP Communication Protocol API Reference](../api/plugins/communication_protocols/mcp/src/utcp_mcp/mcp_communication_protocol.md). diff --git a/docs/protocols/sse.md b/docs/protocols/sse.md index 93618e9..4567605 100644 --- a/docs/protocols/sse.md +++ b/docs/protocols/sse.md @@ -25,56 +25,85 @@ npm install @utcp/http ```json { "call_template_type": "sse", - "url": "https://api.example.com/events", + "url": "https://api.example.com/events/{stream_id}", + "event_type": "data_update", + "reconnect": true, + "retry_timeout": 30000, "headers": { - "Authorization": "Bearer ${API_TOKEN}", - "Accept": "text/event-stream" + "X-Custom-Header": "static_value" }, - "timeout": 60, - "max_events": 10, - "event_filter": { - "type": "data_update" + "body_field": "payload", + "header_fields": ["user_id", "session_token"], + "auth": { + "auth_type": "api_key", + "api_key": "Bearer ${API_TOKEN}", + "var_name": "Authorization", + "location": "header" } } ``` -## Configuration Options +## Field Descriptions -The Server-Sent Events (SSE) call template enables real-time streaming data from HTTP endpoints. For complete field specifications and validation rules, see the [SSE Call Template API Reference](../api/plugins/communication_protocols/http/src/utcp_http/sse_call_template.md). -| `reconnect` | boolean | Auto-reconnect on connection loss (default: true) | -| `reconnect_delay` | number | Delay between reconnection attempts (default: 3) | +For detailed field specifications, examples, and validation rules, see: +- **[SseCallTemplate API Reference](../api/plugins/communication_protocols/http/src/utcp_http/sse_call_template.md)** - Complete field documentation with examples +- **[SseCommunicationProtocol API Reference](../api/plugins/communication_protocols/http/src/utcp_http/sse_communication_protocol.md)** - Implementation details and method documentation -## Authentication +### Key Fields -SSE uses standard HTTP authentication methods: +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `call_template_type` | string | Yes | Always "sse" for SSE providers | +| `url` | string | Yes | SSE endpoint URL with optional path parameters like `{stream_id}` | +| `event_type` | string | No | Filter for specific event types (default: all events) | +| `reconnect` | boolean | No | Auto-reconnect on connection loss (default: true) | +| `retry_timeout` | number | No | Retry timeout in milliseconds (default: 30000) | +| `headers` | object | No | Static headers for the initial connection | +| `body_field` | string | No | Tool argument name to map to request body | +| `header_fields` | array | No | Tool argument names to map to request headers | +| `auth` | object | No | Authentication configuration | + +## Authentication -### Bearer Token +SSE supports the same authentication methods as HTTP: +### API Key Authentication ```json { - "headers": { - "Authorization": "Bearer ${ACCESS_TOKEN}" + "auth": { + "auth_type": "api_key", + "api_key": "Bearer ${ACCESS_TOKEN}", + "var_name": "Authorization", + "location": "header" } } ``` -### API Key +Supported locations: +- `"header"`: API key sent as HTTP header +- `"query"`: API key sent as query parameter +- `"cookie"`: API key sent as HTTP cookie +### Basic Authentication ```json { - "headers": { - "X-API-Key": "${API_KEY}" + "auth": { + "auth_type": "basic", + "username": "${USERNAME}", + "password": "${PASSWORD}" } } ``` -### Query Parameter Auth - +### OAuth2 Authentication ```json { - "query_params": { - "token": "${API_TOKEN}", - "user_id": "${USER_ID}" + "auth": { + "auth_type": "oauth2", + "client_id": "${CLIENT_ID}", + "client_secret": "${CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "read write" } } ``` @@ -96,14 +125,16 @@ SSE uses standard HTTP authentication methods: }, "tool_call_template": { "call_template_type": "sse", - "url": "https://api.example.com/notifications/stream", - "query_params": { - "user_id": "${user_id}" - }, - "headers": { - "Authorization": "Bearer ${ACCESS_TOKEN}" - }, - "timeout": 300 + "url": "https://api.example.com/notifications/stream/{user_id}", + "event_type": "notification", + "reconnect": true, + "retry_timeout": 30000, + "auth": { + "auth_type": "api_key", + "api_key": "Bearer ${ACCESS_TOKEN}", + "var_name": "Authorization", + "location": "header" + } } } ``` @@ -114,11 +145,9 @@ SSE uses standard HTTP authentication methods: { "call_template_type": "sse", "url": "https://api.example.com/events", - "event_filter": { - "type": "order_update", - "status": ["completed", "cancelled"] - }, - "max_events": 5 + "event_type": "order_update", + "reconnect": true, + "retry_timeout": 15000 } ``` @@ -133,27 +162,21 @@ SSE uses standard HTTP authentication methods: "inputs": { "type": "object", "properties": { - "symbols": { - "type": "array", - "items": {"type": "string"} - }, - "duration": {"type": "number", "default": 60} + "symbol": {"type": "string"} }, - "required": ["symbols"] + "required": ["symbol"] }, "tool_call_template": { "call_template_type": "sse", - "url": "https://api.stocks.com/stream", - "query_params": { - "symbols": "${symbols}", - "format": "json" - }, - "headers": { - "Authorization": "Bearer ${STOCK_API_KEY}" - }, - "timeout": "${duration}", - "event_filter": { - "type": "price_update" + "url": "https://api.stocks.com/stream/{symbol}", + "event_type": "price_update", + "reconnect": true, + "retry_timeout": 30000, + "auth": { + "auth_type": "api_key", + "api_key": "${STOCK_API_KEY}", + "var_name": "Authorization", + "location": "header" } } } @@ -169,22 +192,24 @@ SSE uses standard HTTP authentication methods: "type": "object", "properties": { "service": {"type": "string"}, - "level": {"type": "string", "enum": ["error", "warn", "info", "debug"]} + "level": {"type": "string"} }, "required": ["service"] }, "tool_call_template": { "call_template_type": "sse", - "url": "https://logs.example.com/stream", - "query_params": { - "service": "${service}", - "level": "${level}" - }, - "headers": { - "X-API-Key": "${LOG_API_KEY}" - }, - "timeout": 600, - "max_events": 100 + "url": "https://logs.example.com/stream/{service}", + "event_type": "log_entry", + "reconnect": true, + "retry_timeout": 45000, + "body_field": "filter_config", + "header_fields": ["level"], + "auth": { + "auth_type": "api_key", + "api_key": "${LOG_API_KEY}", + "var_name": "X-API-Key", + "location": "header" + } } } ``` @@ -198,27 +223,25 @@ SSE uses standard HTTP authentication methods: "inputs": { "type": "object", "properties": { - "metrics": { - "type": "array", - "items": {"type": "string"} - }, - "interval": {"type": "number", "default": 5} + "server_id": {"type": "string"}, + "metrics_config": {"type": "object"} }, - "required": ["metrics"] + "required": ["server_id"] }, "tool_call_template": { "call_template_type": "sse", - "url": "https://monitoring.example.com/metrics/stream", - "query_params": { - "metrics": "${metrics}", - "interval": "${interval}" - }, - "headers": { - "Authorization": "Bearer ${MONITORING_TOKEN}" - }, - "timeout": 300, + "url": "https://monitoring.example.com/metrics/stream/{server_id}", + "event_type": "metric_update", "reconnect": true, - "reconnect_delay": 5 + "retry_timeout": 20000, + "body_field": "metrics_config", + "auth": { + "auth_type": "oauth2", + "client_id": "${MONITORING_CLIENT_ID}", + "client_secret": "${MONITORING_CLIENT_SECRET}", + "token_url": "https://auth.monitoring.com/token", + "scope": "metrics:read" + } } } ``` @@ -318,47 +341,86 @@ data: {"message": "Simple data without event type"} ## Advanced Features -### Custom Event Parsing +### Dynamic Parameter Substitution +- **URL path parameters**: Use `{parameter_name}` syntax in URLs +- **Body field mapping**: Map tool arguments to request body via `body_field` +- **Header field mapping**: Map tool arguments to headers via `header_fields` ```json { "call_template_type": "sse", - "url": "https://api.example.com/events", - "event_parser": { - "format": "json", - "extract_fields": ["timestamp", "level", "message"] - } + "url": "https://api.example.com/events/{stream_id}", + "event_type": "data_update", + "body_field": "filter_config", + "header_fields": ["user_context", "session_id"] } ``` -### Event Aggregation +### OAuth2 Token Management +- **Automatic token caching**: Tokens cached by client_id +- **Token refresh**: Automatic token refresh on expiration +- **Client credentials flow**: Supports OAuth2 client credentials grant ```json { - "call_template_type": "sse", - "url": "https://api.example.com/metrics", - "aggregation": { - "window": 10, - "function": "average", - "field": "value" + "auth": { + "auth_type": "oauth2", + "client_id": "${OAUTH_CLIENT_ID}", + "client_secret": "${OAUTH_CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "stream:read" } } ``` -### Conditional Termination +### Multiple Authentication Locations +- **Header**: Standard Authorization header or custom headers +- **Query**: API key as URL query parameter +- **Cookie**: API key sent as HTTP cookie ```json { - "call_template_type": "sse", - "url": "https://api.example.com/events", - "termination_condition": { - "event_type": "complete", - "data_field": "status", - "value": "finished" + "auth": { + "auth_type": "api_key", + "api_key": "${API_TOKEN}", + "var_name": "access_token", + "location": "cookie" } } ``` +## Implementation Notes + +The SSE protocol implementation provides: + +- **Async streaming**: Real-time event processing with async generators +- **Automatic reconnection**: Configurable via `reconnect` and `retry_timeout` fields +- **Event filtering**: Client-side filtering by `event_type` +- **Authentication caching**: OAuth2 tokens cached by client_id +- **Security enforcement**: HTTPS or localhost connections only +- **Error handling**: Graceful handling of connection failures and retries + +### Usage Example +```python +import asyncio +from utcp_client import UtcpClient + +async def main(): + client = UtcpClient() + + # Register SSE provider + await client.register_tool_provider(sse_manual) + + # Stream events with automatic filtering and reconnection + async for event in client.call_tool_streaming("stream_notifications", {"user_id": "123"}): + print(f"Event: {event}") + + await client.close() + +if __name__ == "__main__": + asyncio.run(main()) +``` + ## Common Use Cases - **Real-time Dashboards**: Live metrics, status updates @@ -381,6 +443,8 @@ data: {"message": "Simple data without event type"} ## Related Protocols -- [HTTP](./http.md) - For request/response patterns -- [WebSocket](./websocket.md) - For bidirectional communication -- [Streamable HTTP](./streamable-http.md) - For chunked HTTP responses +- **[HTTP](./http.md)** - For standard request/response patterns +- **WebSocket** - For bidirectional real-time communication +- **TCP/UDP** - For custom protocol implementations + +For complete implementation details, see the [SSE Communication Protocol API Reference](../api/plugins/communication_protocols/http/src/utcp_http/sse_communication_protocol.md). diff --git a/docs/protocols/streamable-http.md b/docs/protocols/streamable-http.md index 3ed9e6e..1a2341d 100644 --- a/docs/protocols/streamable-http.md +++ b/docs/protocols/streamable-http.md @@ -13,8 +13,11 @@ The Streamable HTTP protocol plugin (`utcp-http`) enables UTCP to handle large H ```json { "call_template_type": "streamable_http", - "url": "https://api.example.com/download/large-file", + "url": "https://api.example.com/download/{file_id}", "http_method": "GET", + "content_type": "application/octet-stream", + "chunk_size": 4096, + "timeout": 60000, "headers": { "Accept": "application/octet-stream" }, @@ -24,28 +27,31 @@ The Streamable HTTP protocol plugin (`utcp-http`) enables UTCP to handle large H "var_name": "Authorization", "location": "header" }, - "chunk_size": 8192, - "timeout": 300000, "body_field": "request_data", "header_fields": ["custom_header_arg"] } ``` -## Configuration Options +## Field Descriptions -The Streamable HTTP call template provides a way to configure streaming from HTTP endpoints. +For detailed field specifications, examples, and validation rules, see: +- **[StreamableHttpCallTemplate API Reference](../api/plugins/communication_protocols/http/src/utcp_http/streamable_http_call_template.md)** - Complete field documentation with examples +- **[StreamableHttpCommunicationProtocol API Reference](../api/plugins/communication_protocols/http/src/utcp_http/streamable_http_communication_protocol.md)** - Implementation details and method documentation -| Option | Type | Default | Description | -|---|---|---|---| -| `url` | string | **Required** | The streaming HTTP endpoint URL. Supports path parameters like `/users/{user_id}`. | -| `http_method` | string | `GET` | The HTTP method to use. Supported methods are `GET` and `POST`. | -| `content_type` | string | `application/octet-stream` | The `Content-Type` header to set for the request, especially when `body_field` is used. | -| `chunk_size` | integer | `4096` | The size of each data chunk in bytes to read from the stream. | -| `timeout` | integer | `60000` | Request timeout in milliseconds. | -| `headers` | object | `null` | Optional static headers to include in every request. | -| `auth` | object | `null` | Optional authentication configuration. See [HTTP Authentication](./http.md#authentication-methods). | -| `body_field` | string | `null` | The name of a single tool argument to be sent as the HTTP request body. | -| `header_fields` | array | `null` | A list of tool argument names to be sent as request headers. | +### Key Fields + +| Field | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `call_template_type` | string | Yes | - | Always "streamable_http" for streaming HTTP providers | +| `url` | string | Yes | - | HTTP endpoint URL with optional path parameters like `{file_id}` | +| `http_method` | string | No | "GET" | HTTP method to use ("GET" or "POST") | +| `content_type` | string | No | "application/octet-stream" | Content-Type header for requests | +| `chunk_size` | number | No | 4096 | Size of each data chunk in bytes | +| `timeout` | number | No | 60000 | Request timeout in milliseconds | +| `headers` | object | No | null | Static headers to include in requests | +| `auth` | object | No | null | Authentication configuration | +| `body_field` | string | No | null | Tool argument name to map to request body | +| `header_fields` | array | No | null | Tool argument names to map to request headers | ## Response Handling @@ -58,32 +64,90 @@ The protocol processes the incoming stream based on the `Content-Type` header of ## Authentication -Streamable HTTP supports the same authentication methods as the standard HTTP protocol, including API Key, Basic Auth, and OAuth2. The configuration is identical. +Streamable HTTP supports the same authentication methods as HTTP: + +### API Key Authentication +```json +{ + "auth": { + "auth_type": "api_key", + "api_key": "Bearer ${ACCESS_TOKEN}", + "var_name": "Authorization", + "location": "header" + } +} +``` + +Supported locations: +- `"header"`: API key sent as HTTP header +- `"query"`: API key sent as query parameter +- `"cookie"`: API key sent as HTTP cookie + +### Basic Authentication +```json +{ + "auth": { + "auth_type": "basic", + "username": "${USERNAME}", + "password": "${PASSWORD}" + } +} +``` + +### OAuth2 Authentication +```json +{ + "auth": { + "auth_type": "oauth2", + "client_id": "${CLIENT_ID}", + "client_secret": "${CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "read write" + } +} +``` + +## Parameter Handling -For more details, see the [HTTP Authentication Methods](./http.md#authentication-methods) documentation. +Streamable HTTP processes tool arguments through a hierarchy: -## Variable Substitution +1. **URL path parameters**: Substituted using `{parameter_name}` syntax +2. **Body field**: Single argument mapped to request body via `body_field` +3. **Header fields**: Arguments mapped to headers via `header_fields` +4. **Query parameters**: Remaining arguments sent as query parameters -Path parameters, query parameters, headers, and authentication fields all support variable substitution from tool arguments and environment variables, following the same syntax as the standard HTTP protocol. +### URL Path Parameters +Parameters in URLs are substituted from tool arguments: +```json +{ + "url": "https://api.example.com/files/{file_id}/download/{format}" +} +``` +Tool arguments `file_id` and `format` are substituted into the URL path. -Example: +### Variable Substitution +Authentication and header values support environment variable substitution: ```json { - "url": "https://api.example.com/files/{file_id}/download", "headers": { "Authorization": "Bearer ${ACCESS_TOKEN}" } } ``` -Here, `{file_id}` is substituted from a tool argument, and `${ACCESS_TOKEN}` is substituted from an environment or configuration variable. - -For more details, see the [HTTP Variable Substitution](./http.md#variable-substitution) documentation. ## Security Considerations -- **SSL/TLS**: It is strongly recommended to use `https://` endpoints to protect data in transit. The implementation enforces HTTPS or localhost connections by default. -- **Authentication**: Never hardcode credentials. Use variable substitution to inject secrets from a secure source (e.g., environment variables). -- **Input Sanitization**: Ensure that any arguments used in URL path parameters or query strings are properly validated and sanitized to prevent injection attacks. +### Connection Security +- **HTTPS enforcement**: Only HTTPS URLs or localhost connections are allowed +- **Certificate validation**: SSL certificates are validated by default +- **Secure token handling**: OAuth2 tokens are cached securely + +### Authentication Security +- **Environment variables**: Use `${VAR_NAME}` syntax for sensitive credentials +- **Token caching**: OAuth2 tokens are cached by client_id to avoid repeated requests +- **Authentication methods**: Support for API key, Basic auth, and OAuth2 +- **Location flexibility**: API keys can be sent in headers, query params, or cookies +- **URL encoding**: Path parameters are properly URL-encoded to prevent injection ## Error Handling @@ -99,7 +163,105 @@ Errors are handled similarly to the standard HTTP protocol: Connection errors, timeouts, and other network issues will also be raised as exceptions. +## Usage Examples + +### Large File Download +```json +{ + "name": "download_dataset", + "description": "Download large dataset files", + "inputs": { + "type": "object", + "properties": { + "dataset_id": {"type": "string"}, + "format": {"type": "string", "enum": ["csv", "json", "parquet"]} + }, + "required": ["dataset_id"] + }, + "tool_call_template": { + "call_template_type": "streamable_http", + "url": "https://data.example.com/datasets/{dataset_id}/download", + "http_method": "GET", + "chunk_size": 8192, + "timeout": 300000, + "header_fields": ["format"], + "auth": { + "auth_type": "api_key", + "api_key": "${DATA_API_KEY}", + "var_name": "X-API-Key", + "location": "header" + } + } +} +``` + +### Streaming JSON Data +```json +{ + "name": "export_records", + "description": "Export large record sets as streaming NDJSON", + "inputs": { + "type": "object", + "properties": { + "table_name": {"type": "string"}, + "filters": {"type": "object"} + }, + "required": ["table_name"] + }, + "tool_call_template": { + "call_template_type": "streamable_http", + "url": "https://api.example.com/export/{table_name}", + "http_method": "POST", + "content_type": "application/json", + "chunk_size": 4096, + "body_field": "filters", + "auth": { + "auth_type": "oauth2", + "client_id": "${OAUTH_CLIENT_ID}", + "client_secret": "${OAUTH_CLIENT_SECRET}", + "token_url": "https://auth.example.com/token", + "scope": "data:export" + } + } +} +``` + +## Implementation Notes + +The Streamable HTTP protocol implementation provides: + +- **Chunked streaming**: Processes responses in configurable chunk sizes +- **Content-type awareness**: Different handling for JSON, NDJSON, and binary content +- **Authentication caching**: OAuth2 tokens cached by client_id +- **Security enforcement**: HTTPS or localhost connections only +- **Error handling**: Graceful handling of connection failures and timeouts +- **Resource management**: Proper cleanup of HTTP connections and sessions + +### Usage Example +```python +import asyncio +from utcp_client import UtcpClient + +async def main(): + client = UtcpClient() + + # Register streamable HTTP provider + await client.register_tool_provider(streamable_http_manual) + + # Stream large dataset + async for chunk in client.call_tool_streaming("download_dataset", {"dataset_id": "large_dataset_123"}): + process_chunk(chunk) # Process each chunk as it arrives + + await client.close() + +if __name__ == "__main__": + asyncio.run(main()) +``` + ## Related Protocols -- [HTTP](./http.md) - For standard request/response interactions. -- [Server-Sent Events (SSE)](./sse.md) - For unidirectional, real-time event streams from server to client. \ No newline at end of file +- **[HTTP](./http.md)** - For standard request/response interactions +- **[Server-Sent Events (SSE)](./sse.md)** - For real-time event streams from server to client +- **TCP/UDP** - For custom protocol implementations + +For complete implementation details, see the [Streamable HTTP Communication Protocol API Reference](../api/plugins/communication_protocols/http/src/utcp_http/streamable_http_communication_protocol.md). \ No newline at end of file diff --git a/docs/protocols/text.md b/docs/protocols/text.md index dcca388..885777b 100644 --- a/docs/protocols/text.md +++ b/docs/protocols/text.md @@ -6,16 +6,13 @@ sidebar_position: 5 # Text Protocol -The Text protocol plugin (`utcp-text`) enables UTCP to read and process text files from local filesystem or remote URLs. This is useful for tools that need to access documentation, configuration files, logs, or any text-based data. +The Text protocol plugin (`utcp-text`) enables UTCP to read UTCP manuals and tool definitions from local JSON/YAML files. This protocol is designed for static tool configurations or environments where manuals are distributed as files. ## Installation ```bash -# Example installation (Python) +# Python installation pip install utcp-text - -# Example installation (Node.js) -npm install @utcp/text ``` ## Call Template Structure @@ -23,415 +20,202 @@ npm install @utcp/text ```json { "call_template_type": "text", - "file_path": "/path/to/file.txt", - "encoding": "utf-8", - "max_size": 1048576, - "line_range": { - "start": 1, - "end": 100 - } + "file_path": "/path/to/manual.json" } ``` ## Configuration Options -The Text call template enables reading and processing text files from local filesystem or URLs. For complete field specifications and validation rules, see the [Text Call Template API Reference](../api/plugins/communication_protocols/text/src/utcp_text/text_call_template.md). +The Text call template has a simple structure for reading UTCP manuals from files. For complete field specifications and validation rules, see the [Text Call Template API Reference](../api/plugins/communication_protocols/text/src/utcp_text/text_call_template.md). -## File Sources +### Required Fields -### Local Files +- **`call_template_type`**: Must be "text" +- **`file_path`**: Path to the file containing UTCP manual or tool definitions +- **`auth`**: Always `None` (text call templates don't support authentication) -```json -{ - "call_template_type": "text", - "file_path": "/var/log/application.log", - "encoding": "utf-8" -} -``` +## Supported File Types -### Remote URLs +### UTCP Manual Files ```json { "call_template_type": "text", - "file_path": "https://example.com/config.txt", - "max_size": 512000 + "file_path": "/path/to/utcp_manual.json" } ``` -### Variable Substitution +### OpenAPI Specifications + +The protocol automatically detects and converts OpenAPI specs to UTCP manuals: ```json { "call_template_type": "text", - "file_path": "/data/${filename}", - "encoding": "${file_encoding}" + "file_path": "/path/to/openapi.yaml" } ``` -## Examples +### Path Resolution -### Read Configuration File +Relative paths are resolved against the UTCP client's root directory: ```json { - "name": "read_config", - "description": "Read application configuration file", - "inputs": { - "type": "object", - "properties": { - "config_name": {"type": "string"} - }, - "required": ["config_name"] - }, - "tool_call_template": { - "call_template_type": "text", - "file_path": "/etc/app/${config_name}.conf", - "encoding": "utf-8", - "max_size": 65536 - } + "call_template_type": "text", + "file_path": "manuals/my_tools.json" // Resolved against client root_dir } ``` -### Read Log File with Line Range +## Usage Examples + +### Manual Registration + +#### UTCP Manual File ```json { - "name": "read_recent_logs", - "description": "Read recent log entries", - "inputs": { - "type": "object", - "properties": { - "log_file": {"type": "string"}, - "lines": {"type": "number", "default": 100} - }, - "required": ["log_file"] - }, - "tool_call_template": { + "name": "local_tools_manual", + "call_template": { "call_template_type": "text", - "file_path": "/var/log/${log_file}", - "line_range": { - "start": -${lines}, - "end": -1 - } + "file_path": "/path/to/my_tools.json" } } ``` -### Read Remote Documentation +#### OpenAPI Specification ```json { - "name": "fetch_documentation", - "description": "Fetch documentation from remote URL", - "inputs": { - "type": "object", - "properties": { - "doc_url": {"type": "string"}, - "section": {"type": "string"} - }, - "required": ["doc_url"] - }, - "tool_call_template": { + "name": "api_tools_manual", + "call_template": { "call_template_type": "text", - "file_path": "${doc_url}", - "pattern": "(?s)## ${section}.*?(?=## |$)", - "max_size": 2097152 + "file_path": "/path/to/openapi.yaml" } } ``` -### Search in File +### Tool Execution + +When tools are called, the Text protocol returns the content of the configured file: ```json { - "name": "search_in_file", - "description": "Search for pattern in text file", + "name": "read_file", + "description": "Read content from a file", "inputs": { "type": "object", - "properties": { - "file_path": {"type": "string"}, - "search_pattern": {"type": "string"} - }, - "required": ["file_path", "search_pattern"] + "properties": {}, + "required": [] }, "tool_call_template": { "call_template_type": "text", - "file_path": "${file_path}", - "pattern": "${search_pattern}", - "transform": "strip" - } -} -``` - -## Line Range Options - -### Absolute Line Numbers - -```json -{ - "line_range": { - "start": 10, - "end": 50 - } -} -``` - -### Relative to End (Tail) - -```json -{ - "line_range": { - "start": -100, - "end": -1 + "file_path": "/path/to/data.txt" } } ``` -### From Start (Head) - -```json -{ - "line_range": { - "start": 1, - "end": 100 - } -} -``` +## Protocol Behavior -## Pattern Matching - -### Simple Text Search - -```json -{ - "pattern": "ERROR" -} -``` - -### Regex Pattern - -```json -{ - "pattern": "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} ERROR.*" -} -``` +### Manual Registration -### Multi-line Pattern +When registering a manual with `register_manual()`, the protocol: -```json -{ - "pattern": "(?s)START.*?END" -} -``` +1. **Reads the file** from the specified `file_path` +2. **Detects file format** (JSON/YAML) +3. **Identifies content type**: + - UTCP Manual: Validates and returns directly + - OpenAPI Spec: Converts to UTCP manual using OpenApiConverter +4. **Returns result** with loaded tools -## Content Transformations +### Tool Execution -### Case Transformations +When calling a tool with `call_tool()`, the protocol: -```json -{ - "transform": "upper" // Convert to uppercase -} -``` +1. **Reads file content** from the `file_path` in the tool's call template +2. **Returns raw content** as a string -```json -{ - "transform": "lower" // Convert to lowercase -} -``` +### Streaming Support -### Whitespace Handling +The `call_tool_streaming()` method yields the entire file content as a single chunk. -```json -{ - "transform": "strip" // Remove leading/trailing whitespace -} -``` +## File Format Support -### Custom Transformations +### JSON Files ```json +// /path/to/manual.json { - "transform": "normalize_whitespace" // Normalize all whitespace + "version": "0.2.0", + "tools": [ + { + "name": "example_tool", + "description": "An example tool", + "inputs": {"type": "object", "properties": {}} + } + ] } ``` -## Response Format - -### Successful Read +### YAML Files -```json -{ - "content": "File content here...", - "metadata": { - "file_path": "/path/to/file.txt", - "size": 1024, - "lines": 25, - "encoding": "utf-8", - "last_modified": "2024-01-15T10:30:00Z" - } -} -``` - -### Filtered Content - -```json -{ - "content": "Matching lines...", - "metadata": { - "file_path": "/path/to/file.txt", - "total_lines": 1000, - "matched_lines": 5, - "pattern": "ERROR", - "line_range": {"start": 1, "end": 100} - } -} +```yaml +# /path/to/manual.yaml +version: "0.2.0" +tools: + - name: example_tool + description: An example tool + inputs: + type: object + properties: {} ``` ## Error Handling -| Error Type | Description | Handling | -|------------|-------------|----------| -| File Not Found | File doesn't exist | Raise `FileNotFoundError` | -| Permission Denied | No read permission | Raise `PermissionError` | -| File Too Large | Exceeds max_size limit | Raise `FileSizeError` | -| Encoding Error | Invalid file encoding | Raise `EncodingError` | -| Network Error | URL fetch failed | Raise `NetworkError` | - -## Security Considerations +The Text protocol handles various error conditions: -### Path Traversal Prevention - -```json -{ - "call_template_type": "text", - "file_path": "/safe/directory/${filename}", - "allowed_paths": ["/safe/directory/"] -} -``` +| Error Type | Condition | Behavior | +|------------|-----------|----------| +| File Not Found | File doesn't exist | Returns `RegisterManualResult` with `success: false` | +| Parse Error | Invalid JSON/YAML | Returns error result with exception details | +| Validation Error | Invalid UTCP manual | Returns error result with validation details | +| Generic Error | Unexpected exceptions | Returns error result with traceback | -### File Size Limits +### Error Response Format ```json { - "max_size": 1048576 // 1MB limit + "manual_call_template": { /* original template */ }, + "manual": { "tools": [] }, + "success": false, + "errors": ["Error details here..."] } ``` -### URL Restrictions +## Security Considerations -```json -{ - "allowed_domains": ["example.com", "docs.company.com"] -} -``` +- **Path Resolution**: Relative paths are resolved against the client's `root_dir` +- **Local Files Only**: Protocol only supports local file system access +- **No Authentication**: Text call templates don't support auth (always `None`) ## Best Practices -1. **Set Size Limits**: Always set appropriate max_size limits -2. **Validate Paths**: Validate file paths to prevent directory traversal -3. **Handle Encoding**: Specify encoding explicitly for non-UTF-8 files -4. **Use Line Ranges**: Use line ranges for large files to improve performance -5. **Pattern Efficiency**: Use efficient regex patterns for content filtering -6. **Cache Results**: Cache frequently accessed files -7. **Monitor Access**: Log file access for security auditing - -## Advanced Features - -### Conditional Reading - -```json -{ - "call_template_type": "text", - "file_path": "/var/log/app.log", - "condition": { - "modified_since": "2024-01-15T00:00:00Z" - } -} -``` - -### Multi-file Reading - -```json -{ - "call_template_type": "text", - "file_paths": [ - "/etc/app/config1.txt", - "/etc/app/config2.txt" - ], - "merge_strategy": "concatenate" -} -``` - -### Streaming Large Files - -```json -{ - "call_template_type": "text", - "file_path": "/var/log/huge.log", - "streaming": true, - "chunk_size": 8192 -} -``` +1. **Use Absolute Paths**: When possible, use absolute file paths for clarity +2. **Validate Files**: Ensure UTCP manual files are valid before registration +3. **Handle Errors**: Check `RegisterManualResult.success` before using tools +4. **Organize Manuals**: Keep manual files in a dedicated directory structure +5. **Version Control**: Include manual files in version control for consistency ## Common Use Cases -- **Configuration Management**: Reading config files, environment files -- **Log Analysis**: Processing application logs, system logs -- **Documentation**: Accessing README files, API docs, manuals -- **Data Processing**: Reading CSV, JSON, XML text files -- **Template Processing**: Reading template files for generation -- **Code Analysis**: Reading source code files for analysis -- **Monitoring**: Reading status files, health check files - -## Performance Considerations - -| File Size | Recommended Approach | -|-----------|---------------------| -| < 1MB | Read entire file | -| 1MB - 10MB | Use line ranges | -| 10MB - 100MB | Use streaming | -| > 100MB | Use external tools | +- **Static Tool Definitions**: Distributing tool configurations as files +- **Local Development**: Testing UTCP tools without external dependencies +- **Offline Environments**: Using tools in environments without network access +- **Configuration Management**: Reading tool definitions from config files +- **OpenAPI Integration**: Converting existing OpenAPI specs to UTCP tools -## Integration Examples +## API Reference -### With HTTP Protocol - -```json -{ - "name": "process_uploaded_file", - "description": "Process uploaded text file", - "inputs": { - "type": "object", - "properties": { - "file_url": {"type": "string"} - } - }, - "tool_call_template": { - "call_template_type": "text", - "file_path": "${file_url}", - "max_size": 5242880 - } -} -``` - -### With CLI Protocol - -```json -{ - "name": "analyze_log_file", - "description": "Analyze log file with external tool", - "inputs": { - "type": "object", - "properties": { - "log_path": {"type": "string"} - } - }, - "tool_call_template": { - "call_template_type": "cli", - "command": "log-analyzer", - "args": ["--file", "${log_path}", "--format", "json"] - } -} -``` +For detailed information about the implementation, see: +- [Text Call Template API](../api/plugins/communication_protocols/text/src/utcp_text/text_call_template.md) +- [Text Communication Protocol API](../api/plugins/communication_protocols/text/src/utcp_text/text_communication_protocol.md) diff --git a/docs/protocols/websocket.md b/docs/protocols/websocket.md deleted file mode 100644 index 5ce7789..0000000 --- a/docs/protocols/websocket.md +++ /dev/null @@ -1,355 +0,0 @@ ---- -id: websocket -title: WebSocket Protocol -sidebar_position: 2 ---- - -# WebSocket Protocol - -The WebSocket protocol plugin (`utcp-websocket`) enables UTCP to communicate with WebSocket servers for real-time, bidirectional communication. This is ideal for tools that require persistent connections or real-time updates. - -## Installation - -```bash -# Example installation (Python) -pip install utcp-websocket - -# Example installation (Node.js) -npm install @utcp/websocket -``` - -## Call Template Structure - -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "message": { - "type": "request", - "action": "${action}", - "data": "${data}" - }, - "connection_timeout": 10, - "response_timeout": 30, - "auth": { - "auth_type": "api_key", - "api_key": "${WS_API_KEY}", - "location": "query" - } -} -``` - -## Configuration Options - -The WebSocket call template enables real-time communication with WebSocket servers. For complete field specifications and validation rules, see the WebSocket Call Template API Reference (WIP). -| `expected_responses` | number | Number of expected response messages (default: 1) | -| `ping_interval` | number | Ping interval in seconds (default: 30) | - -## Authentication - -WebSocket authentication can be handled in several ways: - -### Query Parameter Authentication - -```json -{ - "auth": { - "auth_type": "api_key", - "api_key": "${API_KEY}", - "var_name": "token", - "location": "query" - } -} -``` - -### Header Authentication - -```json -{ - "auth": { - "auth_type": "api_key", - "api_key": "${API_KEY}", - "var_name": "Authorization", - "location": "header" - } -} -``` - -### Message-based Authentication - -```json -{ - "message": { - "type": "auth", - "token": "${API_KEY}" - } -} -``` - -## Message Formats - -### JSON Messages - -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "message": { - "id": "{{uuid}}", - "method": "getData", - "params": { - "query": "${query}", - "limit": 10 - } - } -} -``` - -### Text Messages - -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "message": "GET_DATA:${query}" -} -``` - -### Binary Messages - -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "message": { - "type": "binary", - "data": "${base64_data}" - } -} -``` - -## Examples - -### Real-time Data Subscription - -```json -{ - "name": "subscribe_stock_price", - "description": "Subscribe to real-time stock price updates", - "inputs": { - "type": "object", - "properties": { - "symbol": {"type": "string"}, - "duration": {"type": "number", "default": 60} - }, - "required": ["symbol"] - }, - "tool_call_template": { - "call_template_type": "websocket", - "url": "wss://api.stocks.com/ws", - "message": { - "action": "subscribe", - "symbol": "${symbol}", - "type": "price" - }, - "response_timeout": "${duration}", - "expected_responses": -1, - "close_after_response": false - } -} -``` - -### Chat Bot Integration - -```json -{ - "name": "send_chat_message", - "description": "Send a message to the chat bot", - "inputs": { - "type": "object", - "properties": { - "message": {"type": "string"}, - "user_id": {"type": "string"} - }, - "required": ["message", "user_id"] - }, - "tool_call_template": { - "call_template_type": "websocket", - "url": "wss://chat.example.com/ws", - "message": { - "type": "message", - "user_id": "${user_id}", - "content": "${message}", - "timestamp": "{{now}}" - }, - "headers": { - "Authorization": "Bearer ${CHAT_TOKEN}" - } - } -} -``` - -### IoT Device Control - -```json -{ - "name": "control_device", - "description": "Send control commands to IoT device", - "inputs": { - "type": "object", - "properties": { - "device_id": {"type": "string"}, - "command": {"type": "string"}, - "value": {"type": "number"} - }, - "required": ["device_id", "command"] - }, - "tool_call_template": { - "call_template_type": "websocket", - "url": "wss://iot.example.com/device/${device_id}", - "message": { - "command": "${command}", - "value": "${value}", - "timestamp": "{{now}}" - }, - "connection_timeout": 5, - "response_timeout": 10 - } -} -``` - -## Connection Management - -### Persistent Connections - -For tools that need to maintain persistent connections: - -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "message": {"action": "ping"}, - "close_after_response": false, - "ping_interval": 30 -} -``` - -### Connection Pooling - -The WebSocket protocol automatically manages connection pooling for efficiency: - -- Reuses connections to the same endpoint -- Handles connection lifecycle automatically -- Implements reconnection logic for dropped connections - -## Response Handling - -### Single Response - -```json -{ - "expected_responses": 1, - "close_after_response": true -} -``` - -### Multiple Responses - -```json -{ - "expected_responses": 5, - "response_timeout": 60 -} -``` - -### Streaming Responses - -```json -{ - "expected_responses": -1, - "response_timeout": 300, - "close_after_response": false -} -``` - -## Error Handling - -| Error Type | Description | Handling | -|------------|-------------|----------| -| Connection Failed | Cannot establish WebSocket connection | Raise `WebSocketConnectionError` | -| Authentication Failed | WebSocket handshake authentication failed | Raise `WebSocketAuthError` | -| Timeout | No response within timeout period | Raise `WebSocketTimeoutError` | -| Protocol Error | Invalid WebSocket protocol usage | Raise `WebSocketProtocolError` | -| Connection Closed | Server closed connection unexpectedly | Raise `WebSocketClosedError` | - -## Best Practices - -1. **Use Secure WebSockets**: Always use `wss://` for production -2. **Handle Reconnections**: Implement retry logic for connection failures -3. **Set Appropriate Timeouts**: Configure timeouts based on expected response times -4. **Validate Messages**: Validate both outgoing and incoming messages -5. **Monitor Connections**: Track connection health and performance -6. **Implement Heartbeats**: Use ping/pong for connection health checks -7. **Handle Backpressure**: Manage message queuing for high-throughput scenarios - -## Advanced Features - -### Message Filtering - -Filter incoming messages based on criteria: - -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "message": {"subscribe": "all"}, - "message_filter": { - "type": "stock_price", - "symbol": "${symbol}" - } -} -``` - -### Custom Headers - -Include custom headers in the WebSocket handshake: - -```json -{ - "headers": { - "User-Agent": "UTCP-Client/1.0", - "X-Client-ID": "${CLIENT_ID}", - "Authorization": "Bearer ${TOKEN}" - } -} -``` - -### Compression - -Enable WebSocket compression: - -```json -{ - "compression": "deflate", - "compression_threshold": 1024 -} -``` - -## Common Use Cases - -- **Real-time Data**: Stock prices, sensor data, live metrics -- **Chat Applications**: Messaging, notifications, presence -- **Gaming**: Real-time game state, multiplayer coordination -- **IoT Control**: Device commands, status updates -- **Live Updates**: News feeds, social media streams -- **Collaborative Tools**: Document editing, shared whiteboards - -## Protocol Comparison - -| Feature | WebSocket | HTTP | SSE | -|---------|-----------|------|-----| -| Bidirectional | ✅ | ❌ | ❌ | -| Real-time | ✅ | ❌ | ✅ | -| Persistent | ✅ | ❌ | ✅ | -| Overhead | Low | High | Medium | -| Complexity | Medium | Low | Low | diff --git a/docs/security.md b/docs/security.md index fbf10f6..14fa21f 100644 --- a/docs/security.md +++ b/docs/security.md @@ -118,29 +118,6 @@ Secure your UTCP manual endpoints: - ✅ Include request tracking headers - ✅ Implement retry limits -### WebSocket Security - -**Secure WebSocket configuration:** -```json -{ - "call_template_type": "websocket", - "url": "wss://api.example.com/ws", - "headers": { - "Authorization": "Bearer ${WS_TOKEN}", - "Origin": "https://trusted-domain.com" - }, - "ping_interval": 30, - "connection_timeout": 10 -} -``` - -**Security measures:** -- ✅ Use WSS (secure WebSocket) only -- ✅ Validate Origin headers -- ✅ Implement connection timeouts -- ✅ Use heartbeat/ping for connection health -- ✅ Limit concurrent connections per client - ### CLI Security :::danger High Risk Protocol @@ -427,7 +404,6 @@ Implement automated security validation: ### Protocol-Specific Security - [ ] **HTTP**: HTTPS only, certificate validation -- [ ] **WebSocket**: WSS only, origin validation - [ ] **CLI**: Sandboxed execution, input sanitization - [ ] **SSE**: Authenticated connections, event limits - [ ] **Text**: Path validation, size limits @@ -437,7 +413,6 @@ By following these security guidelines, you can safely implement UTCP while main For protocol-specific security details, see: - [HTTP Security](./protocols/http.md#security-considerations) -- [WebSocket Security](./protocols/websocket.md#security-considerations) - [CLI Security](./protocols/cli.md#security-considerations) - [SSE Security](./protocols/sse.md#security-considerations) - [Text Security](./protocols/text.md#security-considerations) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index ad26c8f..b7c38b1 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -37,6 +37,10 @@ const config: Config = { locales: ['en'], }, + markdown: { + mermaid: true, + }, + themes: ['@docusaurus/theme-mermaid'], presets: [ [ 'classic', diff --git a/package-lock.json b/package-lock.json index df98a8f..7e269e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@docusaurus/core": "3.8.1", "@docusaurus/plugin-client-redirects": "^3.8.1", "@docusaurus/preset-classic": "3.8.1", + "@docusaurus/theme-mermaid": "^3.8.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -288,6 +289,28 @@ "node": ">=6.0.0" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-9.2.0.tgz", + "integrity": "sha512-Oq1d9BGZakE/FyoEtcNeSwM7MpDO2vUBi11RWBZXf75zPsbUVWmUs03EqkRFrcgbXyKTas0BdZWC1wcuSoqSAw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -1988,6 +2011,51 @@ "node": ">=6.9.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", + "integrity": "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==", + "license": "MIT" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "license": "Apache-2.0" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3746,6 +3814,28 @@ "react-dom": "^18.0.0 || ^19.0.0" } }, + "node_modules/@docusaurus/theme-mermaid": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.8.1.tgz", + "integrity": "sha512-IWYqjyTPjkNnHsFFu9+4YkeXS7PD1xI3Bn2shOhBq+f95mgDfWInkpfBN4aYvx4fTT67Am6cPtohRdwh4Tidtg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.8.1", + "@docusaurus/module-type-aliases": "3.8.1", + "@docusaurus/theme-common": "3.8.1", + "@docusaurus/types": "3.8.1", + "@docusaurus/utils-validation": "3.8.1", + "mermaid": ">=11.6.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, "node_modules/@docusaurus/theme-search-algolia": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.1.tgz", @@ -3911,6 +4001,28 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.0.1.tgz", + "integrity": "sha512-A78CUEnFGX8I/WlILxJCuIJXloL0j/OJ9PSchPAfCargEIKmUBWvvEMmKWB5oONwiUqlNt+5eRufdkLxeHIWYw==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@antfu/utils": "^9.2.0", + "@iconify/types": "^2.0.0", + "debug": "^4.4.1", + "globals": "^15.15.0", + "kolorist": "^1.8.0", + "local-pkg": "^1.1.1", + "mlly": "^1.7.4" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -4044,6 +4156,15 @@ "react": ">=16" } }, + "node_modules/@mermaid-js/parser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.2.tgz", + "integrity": "sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ==", + "license": "MIT", + "dependencies": { + "langium": "3.3.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4492,6 +4613,259 @@ "@types/node": "*" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -4572,6 +4946,12 @@ "@types/send": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/gtag.js": { "version": "0.0.12", "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", @@ -4808,6 +5188,13 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -5894,6 +6281,32 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -6185,6 +6598,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "license": "MIT" + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -6397,6 +6816,15 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -6825,61 +7253,587 @@ "postcss-unique-selectors": "^6.0.4" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/cytoscape": { + "version": "3.33.1", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", + "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" }, - "peerDependencies": { - "postcss": "^8.4.31" + "engines": { + "node": ">=12" } }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "license": "MIT", + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" }, - "peerDependencies": { - "postcss": "^8.4.31" + "engines": { + "node": ">=12" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { - "css-tree": "~2.2.0" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" + "node_modules/dagre-d3-es": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "node_modules/dayjs": { + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", "license": "MIT" }, "node_modules/debounce": { @@ -7027,6 +7981,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -7165,6 +8128,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", + "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", @@ -7759,6 +8731,12 @@ "node": ">= 0.6" } }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "license": "MIT" + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -8287,6 +9265,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -8414,6 +9404,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -9119,6 +10115,15 @@ "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", "license": "MIT" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -9569,6 +10574,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/katex": { + "version": "0.16.22", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", + "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -9578,6 +10608,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9596,6 +10631,28 @@ "node": ">=6" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "license": "MIT" + }, + "node_modules/langium": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", + "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", + "license": "MIT", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/latest-version": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", @@ -9621,6 +10678,12 @@ "shell-quote": "^1.8.3" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -9671,6 +10734,23 @@ "node": ">=8.9.0" } }, + "node_modules/local-pkg": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz", + "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", @@ -9692,6 +10772,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -9784,6 +10870,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -10246,6 +11344,47 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.11.0.tgz", + "integrity": "sha512-9lb/VNkZqWTRjVgCV+l1N+t4kyi94y+l5xrmBmbbxZYkfRl5hEDaTPMOcaWKCl1McG8nBEaMlWwkcAEEgjhBgg==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.0.4", + "@iconify/utils": "^3.0.1", + "@mermaid-js/parser": "^0.6.2", + "@types/d3": "^7.4.3", + "cytoscape": "^3.29.3", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.13", + "dompurify": "^3.2.5", + "katex": "^0.16.22", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^15.0.7", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0" + } + }, + "node_modules/mermaid/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -12153,6 +13292,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -12632,6 +13800,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", + "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "license": "MIT" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -12759,6 +13933,12 @@ "tslib": "^2.0.3" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -12816,6 +13996,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -12849,6 +14035,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -14453,6 +15666,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -15283,6 +16512,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -15324,6 +16571,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -16148,6 +17401,12 @@ "postcss": "^8.4.31" } }, + "node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -16326,6 +17585,12 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", "license": "MIT" }, + "node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "license": "MIT" + }, "node_modules/tinypool": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", @@ -16385,6 +17650,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -16460,6 +17734,12 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", @@ -16954,6 +18234,55 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "license": "MIT" + }, "node_modules/watchpack": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", diff --git a/package.json b/package.json index 0829088..bf07cbd 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@docusaurus/core": "3.8.1", "@docusaurus/plugin-client-redirects": "^3.8.1", "@docusaurus/preset-classic": "3.8.1", + "@docusaurus/theme-mermaid": "^3.8.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0",