diff --git a/changelog.md b/changelog.md index b52ba33..f4ea4eb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,23 @@ +# Enhanced Documentation Metadata + +Added structured metadata to technical documentation for better maintainability: +- Added YAML preamble to UI action handling documentation +- Included code references to track dependencies between docs and code +- Added RAG-optimized metadata for improved document retrieval +- Created maintenance triggers to identify when docs need updates +- Structured questions the document answers for better discoverability +- Improved documentation organization and searchability + +# UI Action Handling Documentation + +Added comprehensive documentation for the UI action handling system: +- Created detailed guide in ttmp/2025-02-22/04-sse-dynamic-form.md +- Documented client-side event handling and server-side processing +- Explained form data collection from multiple sources +- Provided component-specific event handling reference +- Included complete flow walkthrough for form submissions +- Added debugging and console logging documentation + # Enhanced UI Action Handling Improved the UI action system to focus on data-relevant events and provide better form submission data: @@ -1339,29 +1359,19 @@ Fixed an issue where form input values weren't being properly collected during f - Added additional logging for form submission data - Fixed email input value collection in subscription forms -# Enhanced UI Action Handling +# UI Update Command with YAML Support -Improved the UI action system to focus on data-relevant events and provide better form submission data: -- Enhanced form submission to include complete form data in the action payload -- Implemented smart logging that prioritizes data-relevant events (clicked, changed, submitted) -- Added detailed form data logging for form submissions -- Used INFO level for important events and DEBUG level for less important ones -- Improved checkbox handling in form data collection -- Maintained backward compatibility with existing event system - -# UI Component Action Endpoint +Added a new shell command for updating UI components dynamically using YAML input. This command allows users to: -Added a generic event handler system for UI components that sends events to a REST endpoint: -- Created new `/api/ui-action` endpoint to receive component actions -- Added JavaScript function to send component actions to the server -- Updated all UI components to use the new action system -- Actions include component ID, action type, and optional data -- Server logs all actions for monitoring and debugging -- Maintained backward compatibility with existing console logging +- Define UI components in YAML format +- Convert YAML to JSON before sending to the UI server +- Update UI components without modifying YAML files directly -# Added GitHub Pull Request Listing Command +The command supports multiple conversion methods (Python, yq, or basic sed) and provides detailed documentation on the UI DSL. -Added a new command to list pull requests from GitHub repositories: -- Created list-github-pull-requests command with support for filtering by state, assignee, author, labels, and base branch -- Added draft PR filtering support -- Included comprehensive JSON output options for PR-specific fields \ No newline at end of file +## Changes +- Created `examples/ui/update-ui.yaml` shell command +- Added YAML to JSON conversion logic +- Created example YAML form definition +- Added comprehensive documentation in README.md +- Created helper script for easy usage \ No newline at end of file diff --git a/examples/ui/README.md b/examples/ui/README.md new file mode 100644 index 0000000..5b12d5f --- /dev/null +++ b/examples/ui/README.md @@ -0,0 +1,283 @@ +# UI Update Command + +This directory contains a shell command for dynamically updating the UI components in the Go-Go-MCP UI server. + +## Update UI Command + +The `update-ui.yaml` command allows you to update UI components dynamically by sending a JSON payload to the UI server's update endpoint. The components are specified as a YAML string and will be converted to JSON before being sent to the server. + +### Usage + +```bash +go-go-mcp run-command examples/ui/update-ui.yaml \ + --components 'components: + - title: + content: "Hello World" + id: main-title' \ + --server_url "http://localhost:8080" \ + --verbose +``` + +### Parameters + +- `components` (required): YAML string containing UI components definition +- `server_url` (optional): URL of the UI server (default: "http://localhost:8080") +- `verbose` (optional): Show verbose output (default: false) + +### Using a YAML File + +You can also use a YAML file as input: + +```bash +# Read YAML from a file +YAML_CONTENT=$(cat example-form.yaml) + +# Pass the YAML content to the command +go-go-mcp run-command examples/ui/update-ui.yaml \ + --components "$YAML_CONTENT" \ + --verbose +``` + +Or use the provided script: + +```bash +./update-dino-form.sh +``` + +## UI DSL Reference + +The UI DSL (Domain Specific Language) is a YAML-based language for defining user interfaces declaratively. It allows you to create rich, interactive web interfaces without writing HTML directly. + +### Basic Structure + +Every UI definition consists of a list of components under the `components` key: + +```yaml +components: + - componentType: + property1: value1 + property2: value2 +``` + +### Common Properties + +All components support these common properties: + +- `id`: Unique identifier for the component (required) +- `disabled`: Boolean to disable the component (optional) +- `data`: Map of data attributes (optional) + +### Component Types + +#### Button +```yaml +- button: + text: "Click me" + type: primary # primary, secondary, danger, success + id: submit-btn + disabled: false +``` + +#### Title (H1 Heading) +```yaml +- title: + content: "Welcome to My App" + id: main-title +``` + +#### Text (Paragraph) +```yaml +- text: + content: "This is a paragraph of text." + id: description-text +``` + +#### Input Field +```yaml +- input: + type: text # text, email, password, number, tel + placeholder: "Enter your name" + value: "" + required: true + id: name-input +``` + +#### Textarea +```yaml +- textarea: + placeholder: "Enter description" + id: description-textarea + rows: 4 + cols: 50 + value: | + Default multiline + text content +``` + +#### Checkbox +```yaml +- checkbox: + label: "Accept terms" + checked: false + required: true + name: terms + id: terms-checkbox +``` + +#### List + +Lists can contain various types of nested components, supporting both ordered (ol) and unordered (ul) lists. + +```yaml +- list: + type: ul # ul or ol + title: "Shopping List" + items: + - text: + content: "Groceries to buy:" + - checkbox: + label: "Milk" + id: milk-checkbox + - checkbox: + label: "Bread" + id: bread-checkbox + - button: + text: "Add Item" + id: add-item-btn + type: secondary +``` + +#### Form +```yaml +- form: + id: signup-form + components: + - title: + content: "Sign Up" + - input: + type: email + placeholder: "Email address" + required: true + - button: + id: submit + text: "Submit" + type: primary +``` + +### Complete Example + +Here's a complete example of a todo list interface: + +```yaml +components: + - title: + content: What would you like to tackle next? + + - text: + content: I see you have several items that need attention. + + - list: + type: ul + items: + - Review Dependencies: + button: + id: review-deps-btn + text: Review Update (#316) + type: secondary + - Calendar Integration: + button: + id: review-calendar-btn + text: Review Calendar PR (#315) + type: primary + + - form: + id: task-input-form + components: + - title: + content: Add New Task + - input: + id: new-task-input + type: text + placeholder: What needs to be done? + required: true + - checkbox: + id: high-priority-check + label: High Priority + - button: + id: add-task-btn + text: Add Task + type: success +``` + +### Event Handling + +The UI components automatically handle various events: + +1. **clicked**: When a user clicks on a button or interactive element +2. **changed**: When an input, textarea, or checkbox value changes +3. **submitted**: When a form is submitted +4. **focused**: When an input receives focus (debug level only) +5. **blurred**: When an input loses focus (debug level only) + +### Form Data Collection + +When a form is submitted, the system collects data from: + +1. Standard form fields via FormData API +2. Checkbox states (including unchecked boxes) +3. All input values by ID (as a fallback) +4. The ID of the button that triggered the submission + +### Best Practices + +1. Always provide meaningful IDs for components that need to be referenced +2. Use semantic naming for form fields +3. Group related components inside forms +4. Use appropriate button types for different actions: + - `primary`: Main actions + - `secondary`: Alternative actions + - `danger`: Destructive actions + - `success`: Confirmation actions +5. Provide clear labels and placeholders for form inputs + +## Example YAML for update-ui Command + +Here's an example of a contact form in YAML format: + +```yaml +components: + - title: + content: Contact Form + id: contact-title + + - form: + id: contact-form + components: + - input: + type: text + placeholder: Your Name + required: true + id: name-input + + - input: + type: email + placeholder: Your Email + required: true + id: email-input + + - textarea: + placeholder: Your Message + rows: 4 + id: message-textarea + + - checkbox: + label: Subscribe to newsletter + id: newsletter-checkbox + + - button: + text: Send Message + type: primary + id: send-btn +``` + +This will create a contact form with name, email, message fields, a newsletter checkbox, and a submit button. \ No newline at end of file diff --git a/examples/ui/example-form.json b/examples/ui/example-form.json new file mode 100644 index 0000000..941fd5a --- /dev/null +++ b/examples/ui/example-form.json @@ -0,0 +1,92 @@ +{ + "components": [ + { + "title": { + "content": "Dinosaur Facts Subscription", + "id": "dino-title" + } + }, + { + "text": { + "content": "Subscribe to receive amazing dinosaur facts directly to your inbox!", + "id": "dino-description" + } + }, + { + "form": { + "id": "dino-subscription-form", + "components": [ + { + "input": { + "type": "text", + "placeholder": "Your Name", + "required": true, + "id": "name-input" + } + }, + { + "input": { + "type": "email", + "placeholder": "Your Email", + "required": true, + "id": "email-input" + } + }, + { + "list": { + "type": "ul", + "title": "Favorite Dinosaur Types", + "items": [ + { + "checkbox": { + "label": "Theropods (T-Rex, Velociraptor)", + "id": "theropod-checkbox" + } + }, + { + "checkbox": { + "label": "Sauropods (Brachiosaurus, Diplodocus)", + "id": "sauropod-checkbox" + } + }, + { + "checkbox": { + "label": "Ceratopsians (Triceratops)", + "id": "ceratopsian-checkbox" + } + }, + { + "checkbox": { + "label": "Stegosaurs (Stegosaurus)", + "id": "stegosaur-checkbox" + } + } + ] + } + }, + { + "textarea": { + "placeholder": "Tell us about your favorite dinosaur", + "rows": 3, + "id": "favorite-textarea" + } + }, + { + "checkbox": { + "label": "Subscribe to weekly newsletter", + "id": "newsletter-checkbox", + "checked": true + } + }, + { + "button": { + "text": "Subscribe Now", + "type": "success", + "id": "subscribe-btn" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/examples/ui/example-form.yaml b/examples/ui/example-form.yaml new file mode 100644 index 0000000..6199870 --- /dev/null +++ b/examples/ui/example-form.yaml @@ -0,0 +1,58 @@ +components: + - title: + content: Dinosaur Facts Subscription + id: dino-title + + - text: + content: Subscribe to receive amazing dinosaur facts directly to your inbox! + id: dino-description + + - form: + id: dino-subscription-form + components: + - input: + type: text + placeholder: Your Name + required: true + id: name-input + + - input: + type: email + placeholder: Your Email + required: true + id: email-input + + - list: + type: ul + title: Favorite Dinosaur Types + items: + - checkbox: + label: Theropods (T-Rex, Velociraptor) + id: theropod-checkbox + + - checkbox: + label: Sauropods (Brachiosaurus, Diplodocus) + id: sauropod-checkbox + + - checkbox: + label: Ceratopsians (Triceratops) + id: ceratopsian-checkbox + + - checkbox: + label: Stegosaurs (Stegosaurus) + id: stegosaur-checkbox + + - textarea: + placeholder: Tell us about your favorite dinosaur + rows: 3 + id: favorite-textarea + + - checkbox: + label: Subscribe to weekly newsletter + id: newsletter-checkbox + checked: true + + - button: + text: Subscribe Now + type: success + id: subscribe-btn \ No newline at end of file diff --git a/examples/ui/update-dino-form.sh b/examples/ui/update-dino-form.sh new file mode 100755 index 0000000..f3a03f8 --- /dev/null +++ b/examples/ui/update-dino-form.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail + +# Get the directory of this script +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Read the YAML file +YAML_CONTENT=$(cat "$SCRIPT_DIR/example-form.yaml") + +# Run the update-ui command with the YAML content +go-go-mcp run-command "$SCRIPT_DIR/update-ui.yaml" \ + --components "$YAML_CONTENT" \ + --verbose \ No newline at end of file diff --git a/examples/ui/update-ui.yaml b/examples/ui/update-ui.yaml new file mode 100644 index 0000000..2fcf0f3 --- /dev/null +++ b/examples/ui/update-ui.yaml @@ -0,0 +1,323 @@ +name: update-ui +short: Update UI components dynamically +long: | + This command allows you to update the UI components dynamically by sending + a JSON payload to the UI server's update endpoint. The components are specified + as a YAML string and will be converted to JSON before being sent to the server. + + This command is useful for testing UI changes without modifying YAML files directly. + + --- + Title: UI DSL Documentation + Slug: ui-dsl + Short: Learn how to create rich, interactive web interfaces using the YAML-based UI DSL + Topics: + - ui + - dsl + - yaml + - web + Commands: + - none + Flags: + - none + IsTopLevel: true + IsTemplate: false + ShowPerDefault: true + SectionType: GeneralTopic + --- + + # UI DSL Documentation + + The UI DSL (Domain Specific Language) is a YAML-based language for defining user interfaces declaratively. It allows you to create rich, interactive web interfaces without writing HTML directly. The DSL is designed to be both human-readable and machine-friendly, making it ideal for both manual creation and automated generation. + + ## Basic Structure + + Every UI definition consists of a list of components under the `components` key: + + ```yaml + components: + - componentType: + property1: value1 + property2: value2 + ``` + + ## Common Properties + + All components support these common properties: + + - `id`: Unique identifier for the component (required) + - `disabled`: Boolean to disable the component (optional) + - `data`: Map of data attributes (optional) + + ## Component Types + + ### Button + ```yaml + - button: + text: "Click me" + type: primary # primary, secondary, danger, success + id: submit-btn + disabled: false + ``` + + ### Title (H1 Heading) + ```yaml + - title: + content: "Welcome to My App" + id: main-title + ``` + + ### Text (Paragraph) + ```yaml + - text: + content: "This is a paragraph of text." + id: description-text + ``` + + ### Input Field + ```yaml + - input: + type: text # text, email, password, number, tel + placeholder: "Enter your name" + value: "" + required: true + id: name-input + ``` + + ### Textarea + ```yaml + - textarea: + placeholder: "Enter description" + id: description-textarea + rows: 4 + cols: 50 + value: | + Default multiline + text content + ``` + + ### Checkbox + ```yaml + - checkbox: + label: "Accept terms" + checked: false + required: true + name: terms + id: terms-checkbox + ``` + + ### List + + Lists are versatile components that can contain various types of nested components. They support both ordered (ol) and unordered (ul) lists, and can include an optional title. Each list item can be a simple text component or a more complex component like a checkbox, button, or even nested forms. + + The list component is particularly useful for: + - Displaying menu options or navigation items + - Creating interactive checklists + - Showing grouped related actions + - Presenting structured content hierarchically + + Basic Example: + ```yaml + - list: + type: ul # ul or ol + title: "Shopping List" + items: + - text: + content: "Groceries to buy:" + - checkbox: + label: "Milk" + id: milk-checkbox + - checkbox: + label: "Bread" + id: bread-checkbox + - button: + text: "Add Item" + id: add-item-btn + type: secondary + ``` + + Complex Example with Mixed Components: + ```yaml + - list: + type: ol + title: "Conference Schedule" + items: + - text: + content: "Morning Sessions:" + - text: + content: "9:00 - Keynote Speech" + - form: + id: session-1-form + components: + - checkbox: + label: "Attending Keynote" + id: keynote-attend + - textarea: + placeholder: "Your questions" + id: keynote-questions + rows: 2 + - text: + content: "10:30 - Workshop" + - button: + text: "Download Schedule" + id: schedule-btn + type: primary + ``` + + ### Form + ```yaml + - form: + id: signup-form + components: + - title: + content: "Sign Up" + - input: + type: email + placeholder: "Email address" + required: true + - button: + id: submit + text: "Submit" + type: primary + ``` + + ## Complete Example + + Here's a complete example of a todo list interface: + + ```yaml + components: + - title: + content: What would you like to tackle next? + + - text: + content: I see you have several items that need attention. + + - list: + type: ul + items: + - Review Dependencies: + button: + id: review-deps-btn + text: Review Update (#316) + type: secondary + - Calendar Integration: + button: + id: review-calendar-btn + text: Review Calendar PR (#315) + type: primary + + - form: + id: task-input-form + components: + - title: + content: Add New Task + - input: + id: new-task-input + type: text + placeholder: What needs to be done? + required: true + - checkbox: + id: high-priority-check + label: High Priority + - button: + id: add-task-btn + text: Add Task + type: success + ``` + + ## Best Practices + + 1. Always provide meaningful IDs for components that need to be referenced + 2. Use semantic naming for form fields + 3. Group related components inside forms + 4. Use appropriate button types for different actions: + - `primary`: Main actions + - `secondary`: Alternative actions + - `danger`: Destructive actions + - `success`: Confirmation actions + 5. Provide clear labels and placeholders for form inputs + + +flags: + - name: components + type: string + help: YAML string containing UI components definition + required: true + - name: server_url + type: string + help: URL of the UI server + default: "http://localhost:8080" + - name: verbose + type: bool + help: Show verbose output + default: false + +shell-script: | + #!/bin/bash + set -euo pipefail + + # Log the operation if verbose is enabled + if [[ "{{ .Args.verbose }}" == "true" ]]; then + echo "Updating UI components..." + echo "Server URL: {{ .Args.server_url }}" + fi + + # Create temporary files for the components + YAML_FILE=$(mktemp) + JSON_FILE=$(mktemp) + trap 'rm -f "$YAML_FILE" "$JSON_FILE"' EXIT + + # Write the YAML components to the temporary file + echo '{{ .Args.components }}' > "$YAML_FILE" + + # Check if python is available for YAML to JSON conversion + if command -v python3 &> /dev/null; then + if [[ "{{ .Args.verbose }}" == "true" ]]; then + echo "Converting YAML to JSON using Python..." + fi + python3 -c ' + import sys, yaml, json + try: + yaml_content = yaml.safe_load(open(sys.argv[1], "r")) + json.dump(yaml_content, open(sys.argv[2], "w")) + print("Conversion successful") + except Exception as e: + print(f"Error converting YAML to JSON: {e}", file=sys.stderr) + sys.exit(1) + ' "$YAML_FILE" "$JSON_FILE" + # Fallback to yq if available + elif command -v yq &> /dev/null; then + if [[ "{{ .Args.verbose }}" == "true" ]]; then + echo "Converting YAML to JSON using yq..." + fi + yq -o=json eval '.' "$YAML_FILE" > "$JSON_FILE" + # Fallback to simple sed-based conversion for basic YAML + else + if [[ "{{ .Args.verbose }}" == "true" ]]; then + echo "No YAML parser found. Attempting basic conversion..." + fi + # This is a very basic conversion and will only work for simple YAML + cat "$YAML_FILE" | sed 's/: /": "/g' | sed 's/$/"/g' | sed 's/^/"/g' > "$JSON_FILE" + echo "Warning: Using basic YAML to JSON conversion. Install python3 with PyYAML or yq for better results." + fi + + # Send the components to the UI server + if [[ "{{ .Args.verbose }}" == "true" ]]; then + echo "Sending components to server..." + curl -X POST \ + -H "Content-Type: application/json" \ + -d @"$JSON_FILE" \ + "{{ .Args.server_url }}/api/ui-update" \ + -v + else + curl -X POST \ + -H "Content-Type: application/json" \ + -d @"$JSON_FILE" \ + "{{ .Args.server_url }}/api/ui-update" \ + -s + fi + + if [[ "{{ .Args.verbose }}" == "true" ]]; then + echo "UI update complete." + fi \ No newline at end of file