# Development Guide

## Features

The XOOM Designer codebase mainly contains the implementation of the following features:&#x20;

* `XOOM Designer`: the visual model designer itself that, besides the project generation, provides a rapid configuration for VLINGO XOOM components.
* `XOOM CLI`: provides shortcuts for initializing XOOM Designer and interacting with Docker, Gloo Gateway API, and Kubernetes;

Although sharing the same codebase, these two features are not strongly dependent, so it's meant to be kept semantically and structurally separate. In that sense, the Designer and CLI implementations are respectively placed under the package `io.vlingo.xoom.designer` and `io.vlingo.xoom.cli`.&#x20;

Next, the practical sections show how to maintain and expand both features.

## Introduction to CLI

Once the XOOM Designer is correctly [installed](https://github.com/vlingo/xoom-designer/blob/8fee869be2bb257ae98b4a5a328826a95d757f04/src/main/java/io/vlingo/xoom/cli/CommandLineInterfaceInitializer.java#L33), the CLI is accessed from the terminal by calling the executable bash script (ex. `./xoom docker package`). Internally, this script runs the `Designer` jar and passes the command, i.e. `docker package`, to the [CommandLineInterfaceInitializer ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/cli/CommandLineInterfaceInitializer.java#L33)class:

```java
public class CommandLineInterfaceInitializer { 

  public static void main(final String[] args) {  
      ...
      
      final Task task = Task.triggeredBy(resolveCommand(args));      
      
      runTask(task, Arrays.asList(args));  
  }
 
  ...
}
```

The code snippet above shows that an implementation of `io.vlingo.xoom.cli.task.Task` is triggered by the user command, implying that there is one `Task` subclass for each supported task. Next, the task [implementation ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/cli/task/designer/DesignerTask.java)responsible for initializing the Designer service is demonstrated:

```java
public class DesignerTask extends Task {  
    
    private final DesignerInitializer initializer;  
    
    ...
    
    @Override  
    public void run(final List<String> args) {    
        this.initializer.start(OptionValue.mapValues(options, args));  
    }

}
```

The  `OptionValue` class helps tasks to support execution *options*, which are passed along with the bash command. For instance, the designer server port can be customized as follows:&#x20;

```bash
$ ./xoom designer --port 8081
```

The concluding step of a `Task` implementation is to edit the [ComponentRegistration ](https://github.com/vlingo/xoom-designer/blob/939c320735b1f7f3676fd9fbdc397cea42aa0da8/src/main/java/io/vlingo/xoom/cli/ComponentsRegistration.java)class mapping the task as an element of the `cliTasks` list. That makes XOOM CLI able to run the task when the corresponding command is executed:

```java

public class ComponentsRegistration {

  public static void registerWith(final Logger logger,
                                  final CommandExecutionProcess commandExecutionProcess,
                                  final XoomTurboProperties properties) {
    ComponentRegistry.register("cliTasks", Arrays.asList(new DesignerTask(commandExecutionProcess),  new DockerPackageTask(commandExecutionProcess) ...);
}
```

## Introduction to Designer

The following diagram gives us an overview of how the Designer components interact for generating a project:

![XOOM Designer components](/files/XADsYFZ5bK6dQfHm2cDa)

The Designer-embedded user interface illustrated above is built with [Svelte](https://svelte.dev/). It consumes a Rest API submitting the model details to the server-side. Once successfully processed, XOOM Designer uses [Apache FreeMarker](https://freemarker.apache.org/) for generating classes, configuration, and deployment files. That said, let's see how to add templates at the code level.

{% hint style="info" %}
For any development on XOOM Designer you must set an environment variable named `VLINGO_XOOM_STARTER_HOME`. Although you have likely already set this property in order to use the XOOM Designer, that was as an enduser, which has a different value. As a developer working on the Designer, you must set this to the absolute path of a directory relative to where the `vlingo-xoom-starter` repository has been cloned.

Using a \*nix shell, such as `bash`, set like this:

```
$ VLINGO_XOOM_DESIGNER_HOME=[git-clone-path]/dist/designer
$ export VLINGO_XOOM_DESIGNER_HOME
```

On Windows you can use the *System Properties > Advanced > Environment Variables...* to set the property permanently. For a one-time setting before running the design tool you can use the command line:

```
C:\> set VLINGO_XOOM_DESIGNER_HOME=[git-clone-path]\dist\designer
```

After making changes, from the root project directory, build and run the Designer. On \*nix run these commands:

```
$ mvn clean package -P frontend
...
$ java -jar target/xoom-designer-1.6.1-SNAPSHOT.jar gui
```

This works on Windows:

```
C:\[git-clone-path]> mvn clean package -P frontend
...
C:\[git-clone-path]> java -jar target\xoom-designer-1.6.1-SNAPSHOT.jar gui
```

For more details see `README.md` in the `xoom-designer` repository.
{% endhint %}

## Model Processing Steps

While the previous section provides a quick introduction to the Designer components, this section focuses on explaining each step involved in the Designer Model processing, going through the layers, from the external to the inner,   API to the full project generation.&#x20;

First, let's consider how the web-based UI interacts with the Rest API when the project generation is requested:

![Project Generation - UI and Rest API communication](/files/SXNkBxkeXJTCdJbleZFY)

The figure above shows the two requests submitted when the user finishes the Designer model and clicks [the *generate* button](https://docs.vlingo.io/~/files/v0/b/gitbook-28427.appspot.com/o/assets%2F-LLB-V2sJmANuWISDmBf%2F-M_3Au8_e8T8pab_PbuH%2F-M_3F4qjS-fN2APY2tk6%2FXOOM-Designer-Step-06b.png?alt=media\&token=986c44b9-1461-4067-a3fe-b25860829b51). The first request checks if the generation path is valid by creating the full directory tree where the generated project is going to be installed. If it succeeds, the project generation is subsequently requested. The handler methods responsible for processing these requests are presented below:&#x20;

```java
package io.vlingo.xoom.designer.infrastructure.restapi;

public class ModelProcessingResource extends DynamicResourceHandler {

  private final ModelProcessingManager modelProcessingManager;
  
  ...

  public Completes<Response> startGeneration(final DesignerModel model) {
    return modelProcessingManager.generate(model, modelProcessingInformation, logger).andThenTo(scene -> {
              final Response.Status responseStatus = scene.isFailed() ? InternalServerError : Ok;
              return Completes.withSuccess(Response.of(responseStatus, serialized(scene.report)));
            });
  }
  
  public Completes<Response> makeGenerationPath(final GenerationPath path) {
    try {
      modelProcessingManager.createGenerationPath(new File(path.path));
      return Completes.withSuccess(Response.of(Created, headers(of(Location, path.path)), path.serialized()));
    } catch (final GenerationPathAlreadyExistsException e) {
      return Completes.withSuccess(Response.of(Conflict, path.serialized()));
    } catch (final GenerationPathCreationException e) {
      return Completes.withSuccess(Response.of(Forbidden, path.serialized()));
    }
  }
  
  ...
}
```

[ModelProcessingResource ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/infrastructure/restapi/ModelProcessingResource.java)depends on [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)for making the generation path and generating the project. Let's get deeper into the code and see how [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)implements the project generation.

```java
public class ModelProcessingManager {

  private final List<CodeGenerationStep> codeGenerationSteps = new ArrayList<>();

  public ModelProcessingManager(final List<CodeGenerationStep> codeGenerationSteps) {
    this.codeGenerationSteps.addAll(codeGenerationSteps);
  }

  public Completes<ModelProcessingScene> generate(final DesignerModel model,
                                                  final ModelProcessingInformation information,
                                                  final Logger logger) {
    return validate(model, information)
            .andThenTo(scene -> mapContext(scene, logger))
            .andThen(scene -> processSteps(scene));
  }
  
  private Completes<ModelProcessingScene> validate(final DesignerModel model,
                                                   final ModelProcessingInformation information) {
    final ModelProcessingScene scene = ModelProcessingScene.with(model, information);
    final String validationErrors = String.join(", ", model.validate());
    if(validationErrors.isEmpty()) {
      return Completes.withSuccess(scene);
    }
    return Completes.withFailure(scene.onValidationFail(validationErrors));
  }

  private Completes<ModelProcessingScene> mapContext(final ModelProcessingScene scene,
                                                     final Logger logger) {
    try {
      final CodeGenerationContext codeGenerationContext =
              CodeGenerationContextMapper.map(scene.designerModel,
                      scene.information.generationTarget, logger);

      return Completes.withSuccess(scene.addCodeGenerationContext(codeGenerationContext));
    } catch (final Exception exception) {
      exception.printStackTrace();
      return Completes.withFailure(scene.onContextMappingFail(exception));
    }
  }

  private ModelProcessingScene processSteps(final ModelProcessingScene scene) {
    try {
      codeGenerationSteps.stream()
              .filter(step -> step.shouldProcess(scene.codeGenerationContext))
              .forEach(step -> step.process(scene.codeGenerationContext));

      return scene.onCodeGenerationSucceed();
    } catch (final Exception exception) {
      ...
    }
  }
```

Reading the [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)code from the top, it's clear that its constructor receives a [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) list. The details of this [ModelProcessingManager ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/ModelProcessingManager.java)dependency are explained later, but, for now, just keep in mind that the list elements are every step responsible for creating or customizing a piece of the generated project such as configuration files, source code, and other resources.

The `ModelProcessingManager.generate` is the high-level method for the project generation. It uses some auxiliary methods in order to keep the code more organized and readable. Here are the competencies of each one of these auxiliary methods:

* `ModelProcessingManager.validate` - checks if the submitted [DesignerModel ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/infrastructure/restapi/data/DesignerModel.java)is valid. Otherwise, the project generation fails.
* `ModelProcessingManager.mapContext` - maps a [DesignerModel ](https://github.com/vlingo/xoom-designer/blob/master/src/main/java/io/vlingo/xoom/designer/infrastructure/restapi/data/DesignerModel.java)to [CodeGenerationContext](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationContext.java) that gathers all the information required for the [CodeGenerationSteps](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java)
* `ModelProcessing.processSteps` - iterates through the [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) list and processes the steps when the `CodeGenerationStep.shouldProcess` returns true.

That said, let's have a look at the elements of the [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) list declared in `io.vlingo.xoom.designer.Configuration`:

```java
public class Configuration {
  
  ...
  
  private static List<CodeGenerationStep> codeGenerationSteps() {
    return Arrays.asList(
            //Preliminary
            new CodeGenerationParameterValidationStep(),
            new MainClassResolverStep(),
            new StagingFolderCleanUpStep(Phase.PRE_GENERATION),
            new TemporaryTaskFolderCreationStep(),
            //Java
            new ReadmeFileGenerationStep(),
            new ApplicationSettingsGenerationStep(),
            new ValueObjectGenerationStep(),
            new ModelGenerationStep(),
            new DataObjectGenerationStep(),
            new ProjectionGenerationStep(),
            new StorageGenerationStep(),
            new RestResourceGenerationStep(),
            new AutoDispatchMappingGenerationStep(),
            new ExchangeGenerationStep(),
            new SchemataGenerationStep(),
            new BootstrapGenerationStep(),
            new EntityUnitTestGenerationStep(),
            new QueriesUnitTestGenerationStep(),
            new ProjectionUnitTestGenerationStep(),
            new RestResourceAbstractUnitTestGenerationStep(),
            new RestResourceUnitTestGenerationStep(),
            new ClusterSettingsGenerationStep(),
            new DesignerModelGenerationStep(),
            new DockerfileGenerationStep(),
            new KubernetesManifestFileGenerationStep(),
            //React
            new StaticFilesGenerationStep(),
            new LayoutGenerationStep(),
            new AggregateManagementGenerationStep(),
            //Concluding
            new ContentCreationStep(),
            new MavenWrapperInstallationStep(),
            new SchemaPushStep(...),
            new SchemaPullStep(...),
            new StagingFolderCleanUpStep(Phase.POST_GENERATION)
    );
  }

}
```

The steps are grouped either by the generation phase or the programming language/technology on which a specific project part is generated. The preliminary steps are responsible for preparing the internal Designer resources for a new project generation and also defining [TemplateParameter ](https://github.com/vlingo/xoom-codegen/blob/dc5337d527a7540d0316d3b820ac610cce69fed4/src/main/java/io/vlingo/xoom/codegen/template/TemplateParameters.java#L23)values to be used in the later steps.

The core steps, declared between the preliminary and concluding steps, extend [TemplateProcessingStep](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java) which is a subclass of [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java). This extension allows these steps to easily process Freemarker templates based on Java/React technologies.&#x20;

At last, the concluding steps, like the preliminary steps, are simple [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) extensions that respectively perform the following tasks:

* Physically create the template output processed in the core steps;
* Copy necessary resources to the generated project;
* Executes Maven-based Schemata goals;
* Clear leftovers of the generated project from Designer internals;

The next section discusses how to implement a [CodeGenerationStep](https://github.com/vlingo/xoom-codegen/blob/master/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java) and create/update code templates.

## Create / Update Code Templates

The main constituent parts for every auto-generated class / project resouce are:

* A Freemarker template file
* A [io.vlingo.xoom.codegen.template.TemplateData](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateData.java#L18) implementation
* A [io.vlingo.xoom.codegen.template.TemplateProcessingStep](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java#L16) implementation&#x20;

Considering those parts, let's take `AggregateProtocol` class generation as an example and go through the implementation details, starting from the template file:

```java
package ${packageName};

<#if imports?has_content>
<#list imports as import>
import ${import.qualifiedClassName};
</#list>
</#if>

public interface ${aggregateProtocolName} {
  <#if !useCQRS>

  /*
   * Returns my current state.
   *
   * @return {@code Completes<${stateName}>}
   */
  Completes<${stateName}> currentState();
  </#if>

}
```

The [Aggregate Protocol template file](https://github.com/vlingo/xoom-designer/blob/ce6c5466b1f1f5532f69dff28fb962455d04a860/src/main/resources/codegen/java/AggregateProtocol.ftl#L1-L23) requires some parameter values to generate an `Aggregate Protocol` class. The parameters handling and mapping are addressed by [AggregateProtocolTemplateData ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/aggregate/AggregateProtocolTemplateData.java#L24)as follows:

```java
public class AggregateProtocolTemplateData extends TemplateData {

  private final String protocolName;
  private final TemplateParameters parameters;

  public AggregateProtocolTemplateData(final String packageName,
                                       final CodeGenerationParameter aggregate,
                                       final List<Content> contents,
                                       final Boolean useCQRS) {
    this.protocolName = aggregate.value;
    this.parameters = TemplateParameters.with(TemplateParameter.PACKAGE_NAME, packageName)
            .addImports(resolveImports(aggregate, contents))
            .and(TemplateParameter.AGGREGATE_PROTOCOL_NAME, aggregate.value)
            .and(TemplateParameter.STATE_NAME, JavaTemplateStandard.AGGREGATE_STATE.resolveClassname(aggregate.value))
            .and(TemplateParameter.USE_CQRS, useCQRS);
  }

  private Set<String> resolveImports(final CodeGenerationParameter aggregate, final List<Content> contents) {
    return ValueObjectDetail.resolveImports(contents, aggregate.retrieveAllRelated(Label.STATE_FIELD));
  }

  @Override
  public String filename() {
    return standard().resolveFilename(protocolName, parameters);
  }

  @Override
  public TemplateParameters parameters() {
    return parameters;
  }

  @Override
  public TemplateStandard standard() {
    return JavaTemplateStandard.AGGREGATE_PROTOCOL;
  }

}
```

The full package name and the `AggregateProtocol` class name are mapped to the template parameters in `loadParameters`. Additionally, [TemplateData](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateData.java#L18) requires the [filename method ](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateData.java#L40)implementation, which commonly uses the filename resolution logic in the corresponding [TemplateStandard](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateStandard.java).

```java
public class ModelGenerationStep extends TemplateProcessingStep {

  @Override
  protected List<TemplateData> buildTemplatesData(final CodeGenerationContext context) {
    return ModelTemplateDataFactory.from(context);
  }

  @Override
  public boolean shouldProcess(final CodeGenerationContext context) {
    return context.hasParameter(Label.AGGREGATE);
  }

}
```

[ModelGenerationStep ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/ModelGenerationStep.java#L17)implements the `buildTemplateData` method that passes parameter values, coming from the Web-based UI, to RestResourceTemplateData. In this particular scenario, [ModelTemplateDataFactory ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/ModelTemplateDataFactory.java#L29)is an additional and optional class that helps building [AggregateProtocolTemplateData](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/model/aggregate/AggregateProtocolTemplateData.java#L24). The [shouldProcess method ](https://github.com/vlingo/xoom-codegen/blob/0103c2664201b58f08f5100893a8a3efeaf53f2d/src/main/java/io/vlingo/xoom/codegen/CodeGenerationStep.java#L14)is also optional and useful when a [TemplateProcessingStep](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java#L16) subclass needs to be conditionally skipped.

Finally, [TemplateProcessingSteps](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessingStep.java#L16) has to be added to the [Configuration ](https://github.com/vlingo/xoom-designer/blob/22c1fb3c3116e22ea7f12580a9af3a228140ff54/src/main/java/io/vlingo/xoom/designer/Configuration.java#L75)steps list:

```java

private static List<CodeGenerationStep> codeGenerationSteps() {
    return Arrays.asList(
                    ...
            //Java
            new ReadmeFileGenerationStep(),
            new ApplicationSettingsGenerationStep(),
            new ValueObjectGenerationStep(),
            new ModelGenerationStep(),
            new DataObjectGenerationStep()
            
            ....
    );

```

Eventually, some peripheral points in the code are also involved. The following list is mainly related when a new template file is added:

**1.** Create an enum value in [Template ](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/Template.java#L10)passing the template filename (without extension) in the constructor. Example:

```java

    public enum Template {

        //Other template filenames

        AGGREGATE_PROTOCOL("AggregateProtocol")

        //Enum attributes
    }

```

**2.**  Map the new standard file to an existing [TemplateStandard](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateStandard.java) or create one. Sometimes there are multiple files for the same standard. For instance, there is one `Aggregate` template file for each `Storage` (Journal, State Store, Object Store). That means [TemplateStandard](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateStandard.java) is responsible for grouping template files by standard and helps the[ ](https://github.com/vlingo/vlingo-xoom/blob/50568b630d92e7dd9b3389496ebf5602d8a84755/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessor.java)[TemplateProcessor ](https://github.com/vlingo/xoom-codegen/blob/a5df99e39685683d6265b3546f7461e0507b8025/src/main/java/io/vlingo/xoom/codegen/template/TemplateProcessor.java#L12)to find the proper file based on [TemplateParameters ](https://github.com/vlingo/xoom-codegen/blob/dc5337d527a7540d0316d3b820ac610cce69fed4/src/main/java/io/vlingo/xoom/codegen/template/TemplateParameters.java#L23)such as [StorageType](https://github.com/vlingo/xoom-designer/blob/f3f227f4eb50a76f5043f81cba6dcd04d6822936/src/main/java/io/vlingo/xoom/designer/codegen/java/storage/StorageType.java). The examples below demonstrate the `Aggregate Protocol` and `Value Object` standards.

```java
public enum JavaTemplateStandard {
    
    AGGREGATE_PROTOCOL(parameters -> Template.AGGREGATE_PROTOCOL.filename),
    VALUE_OBJECT(parameters -> Template.VALUE_OBJECT.filename),

    //Other standards
}

```

**3.** In case it doesn't already exist, create an enum value in [TemplateParameter ](https://github.com/vlingo/xoom-codegen/blob/dc5337d527a7540d0316d3b820ac610cce69fed4/src/main/java/io/vlingo/xoom/codegen/template/TemplateParameters.java#L23)for each template parameter.

To sum up, those are the common steps regarding `code template files` on `xoom-designer`. Our team is available to discuss and provide more information on [Gitter](https://gitter.im/vlingo-platform-java/community/) and our [public Slack workspace](https://join.slack.com/t/vlingoplatfor-i6o3730/shared_invite/zt-bv6chhpw-u7s4kqb1qvVvVMUUH3wqng).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vlingo.io/xoom-designer/development-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
