Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dart-Code high level API #4589

Closed
quekyj opened this issue Jun 16, 2023 · 28 comments
Closed

Dart-Code high level API #4589

quekyj opened this issue Jun 16, 2023 · 28 comments

Comments

@quekyj
Copy link

quekyj commented Jun 16, 2023

Is your feature request related to a problem? Please describe.
I am wondering if Dart-Code exposes its API to others to build tools around it. I am trying to build a debugger for ROHD on-top of the Dart-Code. Is this achievable?

Describe the solution you'd like

  • If Dart-Code has the debugger High-level API exposed, then probably more developers can build tools on top of this Dart-Code extension.
  • Make this an NPM package?

Describe alternatives you've considered
Probably use dart-debug-protocol.

Additional context
Nope

@DanTup
Copy link
Member

DanTup commented Jun 16, 2023

I am wondering if Dart-Code exposes its API to others to build tools around it.

It doesn't expose anything particularly useful right now. It's difficult to know what to expose without concrete use cases though. There's a lot of things that could be exposed, but exposing everything would be quite a burden (because anything exposed really needs to remain stable and not change).

I am trying to build a debugger for ROHD on-top of the Dart-Code. Is this achievable?

It's hard to say without specifics. If it's using Dart, I would've thought you could debug it without needing any special API - but perhaps there's more to it. Can you give a detailed example of exactly what you'd like to do?

@DanTup DanTup added the awaiting info Requires more information from the customer to progress label Jun 16, 2023
@quekyj
Copy link
Author

quekyj commented Jun 16, 2023

Can you give a detailed example of exactly what you'd like to do?

Sure! I am trying to build a debugger that can filter variables from Dart debugger. The reason a custom debugger for ROHD is needed is because this debugger will have its features expanded in the future to suit Hardware design operations.

So, the initial plan is to start with creating a debugger that can get the variables from Dart-Code debugger. Then, the variables will undergo some filtering process to select only the related variables in the breakpoints.

@DanTup
Copy link
Member

DanTup commented Jun 16, 2023

because this debugger will have its features expanded in the future

Can you expand on the sort of features you have in mind?

The reason I ask, is that Dart-Code doesn't actually have much influence over the capabilities of the debugger. We just implement the Debug Adapter Protocol. We can't extend the debugger UI in VS Code in ways that aren't supported by DAP (and if there are things that are supported by DAP but are not implemented in Dart's implementation of DAP, they may be things we should implement).

I am trying to build a debugger that can filter variables from Dart debugger.

I think it would be difficult to expose a general API that would allow this sort of thing. Right now VS Code is communicating with the debug adapter directly using the DAP protocol. Although the legacy debug adapter lives here in typescript, the new ones all live inside the Dart SDK. Dart-Code tells VS Code how to start the debug adapter, and then is mostly not involved.

Depending on exactly what you're trying to do (what are you trying to filter and why?) it might be that a custom debug adapter would be the most sensible route. This is what we do in Flutter to provide a debug adapter that knows how to launch Flutter apps and do things like Hot Reload:

https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart

You can extend the Dart debug adapter in the same way that Flutter does. Although right now it's not possible to extend the Flutter one (because unlike the Dart one which is shipped in the DDS Pub package, the Flutter one lives directly in flutter_tools which is not on Pub).

@quekyj
Copy link
Author

quekyj commented Jun 19, 2023

Can you expand on the sort of features you have in mind?

We are planning to have the following features in the near future:

  • Open a schematic hardware design diagram viewer using the debug tools to identify which wire is causing the problem or responsible the error
  • Signal Tracing: Trace back the signals (some var) connections points, to identify which part is causing the problem

it might be that a custom debug adapter would be the most sensible route

I see. So, what you mean is to achieve the filtering process. We need to create a custom debug adapter (Let's name it ROHD_adapter) which extend from dds pub and write ROHD-Code (typescript) vscode extension which tells vscode how to start the ROHD_adapter?

Is the idea above being correct, the suitable reference for the vscode extension is https://github.com/Dart-Code/Flutter?

@DanTup
Copy link
Member

DanTup commented Jun 19, 2023

We need to create a custom debug adapter (Let's name it ROHD_adapter) which extend from dds pub and write ROHD-Code (typescript) vscode extension which tells vscode how to start the ROHD_adapter?

I think this would be the most flexible way. It would allow you to get the Dart debugger functionality (by extending the existing base Dart debug adapter) but also allow you to extend it (or replace parts of it) in ways that might not be general enough to warrant being built into the standard Dart debug adapters.

Whether it's the best way may depend on exactly how much you're likely to diverge from the base Dart debugging (something that's unclear to me right now).

Perhaps if you're able to answer some more questions it might help me better understand how things will work:

  • "filter variables from Dart debugger"
    Can you give an example of what kind of filters you have in mind? Are you just trying to modify what's in the "Variables" section (or add your own), or change which fields/properties show for all types in places like the Watch section?
  • "Open a schematic hardware design diagram viewer"
    Is this something that would be driven by the debugger, or something else in the editor (eg., are you expecting to have your own VS Code extension anyway for this viewer, or is it an external application? what is the trigger for opening the diagram?)
  • Do your programs run using "dart run foo.dart" and "dart test foo.test" or are there different commands to run them?
  • Are there going to be events coming from the runtime/debugger that you need to use inside a VS Code extension?
    For example Flutter's widget inspector can send events to VS Code to open files at the location where a widget was constructed. This is done by custom events being sent back from the debug adapter to VS Code. If you want to do something similar, your own debug adapter would allow you to make your own custom commands without them needing to fit within those Dart already supports (although, Dart does now have some fairly generic "ToolEvents" that could work).

Is the idea above being correct, the suitable reference for the vscode extension is https://github.com/Dart-Code/Flutter?

The Flutter extension code there doesn't actually contain any debugger logic, as both Dart and Flutter share a single debugger type ("type": "dart"), so this is all handled inside the Dart extension (around here).

For simple cases you might be able to avoid writing any TypeScript and just create an extension that describes the debugger in the package.json manifest (see program):

https://code.visualstudio.com/api/references/contribution-points#contributes.debuggers

This tells VS Code how to start the debugger for a given type (you would have something like "type": "rhod" instead of "type": "dart").

@mkorbel1
Copy link

"filter variables from Dart debugger"
Can you give an example of what kind of filters you have in mind? Are you just trying to modify what's in the "Variables" section (or add your own), or change which fields/properties show for all types in places like the Watch section?

ROHD is a hardware development framework, and hardware is structured in a hierarchy of "modules" with signals interconnecting them. A signal is an instance of a Logic class, and a module is an instance of a Module class. These classes have a lot of other utilities, variables, etc. within them that are great to see in the debugger when debugging the framework/software, but it's too much clutter for debugging the modelled hardware. For example, a hardware designer would like to see a view consisting of:

  • for a Logic
    • what other Logic is driving this one? (member variable srcConnection)
    • what other Logics are being driven by this one? (member variable dstConnections)
    • where is this signal? (parentModule)
  • for a Module
    • what are the inputs and outputs? (inputs and outputs)
    • where is this module? (parentModule)

There's more examples than these, but basically we want to create a UI view for debugging hardware instead of only the entire software model of the hardware.

"Open a schematic hardware design diagram viewer"
Is this something that would be driven by the debugger, or something else in the editor (eg., are you expecting to have your own VS Code extension anyway for this viewer, or is it an external application? what is the trigger for opening the diagram?)

This would probably need to be part of a new extension as far as I understand. It would create a window/view where you can see a schematic diagram. Yes, it would need to be connected to/driven by the debugger. For example, select a Module object from the debugger window and view a real-time schematic view of that object.

Do your programs run using "dart run foo.dart" and "dart test foo.test" or are there different commands to run them?

Yes, they run via dart run .... ROHD is just a Dart framework with standard pub dependencies, and developers using ROHD create their own Dart projects/packages that depend on and leverage the ROHD libraries.

Are there going to be events coming from the runtime/debugger that you need to use inside a VS Code extension?
For example Flutter's widget inspector can send events to VS Code to open files at the location where a widget was constructed. This is done by custom events being sent back from the debug adapter to VS Code. If you want to do something similar, your own debug adapter would allow you to make your own custom commands without them needing to fit within those Dart already supports (although, Dart does now have some fairly generic "ToolEvents" that could work).

"Flutter's widget inspector can send events to VS Code to open files at the location where a widget was constructed" -> this sounds like a very helpful feature for ROHD debugging which I wasn't even sure how to do. The hierarchy of modules constructed within each other could be thought of as somewhat similar to Flutter's hierarchy of widgets.

Thank you, by the way, for the help and discussion. This is already very enlightening.

@DanTup
Copy link
Member

DanTup commented Jun 22, 2023

Thanks for the extra info. I'm still a little unsure which direction will work out best, but some additional thoughts in case they're helpful.

Making your own debug adapter (extending the Dart one) would give the ultimately flexibility, and would allow you to interact with the VM Service directly. However because you'd have to ship this outside of the SDK, there could end up being some "version skew" between the SDK the user is using, and the version of the base debug adapter and DDS that was compiled into your debug adapter (for example the runtime might have new language features but your debug adapter was compiled with an older SDK that doesn't understand them). At best, it wouldn't be a problem. At worst, you might need to compile a new version of your debug adapter on each Dart SDK release (and may need to select the correct versioned debug adapter for the SDK the user is using).

Another possibility could be a kind of "middleware", where your VS Code extension starts the SDK-shipped debug adapter, but you insert yourself in the middle (a DebugAdapterTrackerFactory) and manipulate the DAP requests in and out. This is how we inject some additional fields to support formatting numbers as hex (although we only need to modify the outbound parts, as the server then handles the formatting): https://github.com/Dart-Code/Dart-Code/blob/master/src/extension/providers/debug_adapter_hex_view_factory.ts

Middleware would give some of the benefits of your own adapter (you could filter things out of variables requests, for example - as long as you can identify which requests are for the types you want to filter) and would avoid any version skew (because where you sit is the standard DAP protocol which doesn't change with Dart versions), but it would restrict you to things that you can do via inspecting/manipulating DAP traffic (although this also includes handling ToolEvents that you can send from your Dart package code via "dart:developer").

I'm not sure if it'll be capable of this though:

Yes, it would need to be connected to/driven by the debugger. For example, select a Module object from the debugger window and view a real-time schematic view of that object.

It's not clear to me if you would need more information than is returned in the variables request to be able to support this feature? Is all the data to draw this diagram coming via the debugger? Is it all information that is already available to the debugger?

BTW - I don't know if it may be useful to you, but there have been some discussions about making it easier to build/extend Dart/Flutter tooling in VS Code. There are some notes and a video at flutter/devtools#5921 about allowing a Flutter web app embedded inside VS Code access to some APIs via Dart-Code (for example the analysis server and debug sessions). None of those ideas help here (because you want to modify parts of the existing debug experience), but they might be of interest for other features in your extension (if you might build them in Dart/Flutter).

@quekyj
Copy link
Author

quekyj commented Jun 28, 2023

@DanTup Thanks for your reply! I have the direction now which is to start with creating a RohdDebugAdapter that extends from DartDebugAdapter. However, I now met the problem on setting up the environment on debug the Debug Adapter (pretty new in this case). I have gone through the VSCode Mock Debug tutorials but its seems that what MockDebug does is start the DebugAdapter as a Server and have the extension to connect to the port.

{
	"name": "Server",
	"type": "node",
	"request": "launch",
	"cwd": "${workspaceFolder}",
	"program": "${workspaceFolder}/src/debugAdapter.ts",
	"args": [
		"--server=4711"
	],
	"outFiles": [
		"${workspaceFolder}/out/**/*.js"
	],
	"preLaunchTask": "npm: compile"
},

But it seems to me that Dart is using other approaches in dealing with this. I was thinking that I should tried with simple class that allows me to have my environment setup. I am using this script:

import 'package:dds/dap.dart';
import 'package:vm_service/vm_service.dart' as vm;
import 'rohd_adapter_args.dart';

class ROHDDebugAdapter extends DartDebugAdapter<RohdLaunchRequestArguments,
    RohdAttachRequestArguments> {
  ROHDDebugAdapter(super.channel);

  @override
  Future<void> attachImpl() async {}

  @override
  Future<void> debuggerConnected(vm.VM vmInfo) async {
    // Usually we'd capture the pid from the VM here and record it for
    // terminating, however for Flutter apps it may be running on a remote
    // device so it's not valid to terminate a process with that pid locally.
    // For attach, pids should never be collected as terminateRequest() should
    // not terminate the debugee.
  }

  @override
  Future<void> disconnectImpl() async {
    print('disconnect implmentation here');

    return Future.value();
  }

  @override
  Future<void> launchImpl() {
    print('launch implmentation here');

    return Future.value();
  }

  @override
  Future<void> terminateImpl() {
    print('terminate implmentation here');

    return Future.value();
  }

  @override
  // TODO: implement parseAttachArgs
  RohdAttachRequestArguments Function(Map<String, Object?> p1)
      get parseAttachArgs => RohdAttachRequestArguments.fromJson;

  @override
  // TODO: implement parseLaunchArgs
  RohdLaunchRequestArguments Function(Map<String, Object?> p1)
      get parseLaunchArgs => RohdLaunchRequestArguments.fromJson;

  @override
  // TODO: implement terminateOnVmServiceClose
  bool get terminateOnVmServiceClose => true;
}

But I am not sure how to launch it? Do I need an entry points for this?

@DanTup
Copy link
Member

DanTup commented Jun 28, 2023

@quekyj the SDK debug adapters do not currently support "server mode" (which is a long-running server that creates an adapter per-debug-session as it gets connections). Currently they only support single-session mode (which is a new adapter process is spawned for each process). This might change in the future.

Although, for your adapter, you'll be in control of how it's spawned, so you could easily add server mode (note: for now, I would only recommend server mode for dev/debugging, because there may be some security implications of running this on a port on the machine, whereas single-session mode only uses stdin/stdout that no other processes can connect to).

I hacked together a quick example that might be useful as a template (note: this is not production-worth code, but it might give you a starting point):

https://github.com/DanTup/custom-dart-debug-adapter

There are three projects:

  • custom_adapter - a custom Dart debug adapter ("dart-custom")
  • test_project - a simple Dart project I used to debug for testing
  • vs_code_extension - A simple VS Code extension that wires up the custom debug adapter

If you open this folder in VS Code you'll find a "Extension + Adapter Server" launch configuration, which is a compoung config that both starts the extension (which spawns a new VS Code window called the "extension development host") and also the custom debug adapter in server mode. It'll also open "test_project" automatically. If you press F5 to start debugging, it should launch a debug session and you'll notice that it has some additional output in the Debug Console, and also shows a fake field in the variables panel.

Screenshot 2023-06-28 161257

These both come from the custom adapter here:

https://github.com/DanTup/custom-dart-debug-adapter/blob/0b4cab887f68a136af078a31e9fa6661e22693c0/custom_adapter/bin/custom_adapter.dart#L28

If you add breakpoints in that adapter in the original VS Code window, you should be able to hit them and debug.

Screenshot 2023-06-28 161412

Alternatively, you can use the "Run Extension (Use DAP Single-Session Mode)" launch configuration instead, which will not run the server mode and will instead run the debug adapter for each session. This should work the same, but debugging of the debug adapter won't be available.

All of the interesting code is in commit DanTup/custom-dart-debug-adapter@0b4cab8 (the previous commit is just the empty project boilerplate).

Note: I'm still not certain if this is the best route to take, but it might give you something to try out some ideas. If you wanted to ship it, the debug adapter should be compiled (with "dart compile") and run as a binary (otherwise you'd need to ship source and run "pub get" to get the DDS package, etc.).

@quekyj
Copy link
Author

quekyj commented Jul 4, 2023

@DanTup Thanks for your amazing template! Let us study your code and come back again while progressing on our side.

@github-actions
Copy link

This issue has been marked stale because it is tagged awaiting-info for 20 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days.

@github-actions github-actions bot added the stale Will be closed soon if no response. label Jul 25, 2023
@DanTup DanTup removed the stale Will be closed soon if no response. label Jul 25, 2023
@quekyj
Copy link
Author

quekyj commented Jul 26, 2023

Hi @DanTup, we faced one challenge here in identify Module in creating the debug filter. So, let's say we have this piece of code where a child class RippleCarryAdder extends parent Module.

class RippleCarryAdder extends Module {}

When we tap into the debug var, we can't seem to identify whether RippleCarryAdder is a children class of Module. This is what we captured:

image

As of Logic, things gone pretty well. For example:

  final b = Logic(width: 3);

we can identify the type by just tap into variables.value.classRef?.name.

image

After that, a simple filtering with .where() would then work:

const filteringClassRef = ['Logic'];
if (vars != null) {
  variables.addAll(
    await Future.wait(
      vars
          .where(
            (variables) => filteringClassRef
                .contains(variables.value.classRef?.name),
          )
          .mapIndexed(convert),
    ),
  );
  response.variables.addAll(variables);

Questions

  1. Do we need to construct a tree data structure that has all local scope variables with expanded child information? This approach would require all the data to be constructed by passing through variableRequest() with all variableReference. It seems to me this is better to be done in the frontend (vscode).

  2. Is the flow correct? Do we miss something?

Flow of how user going to interact with debugger (For reference)

  1. User set a breakpoint at module / logic
    image
  2. These variables then undergo filtering based on certain criteria.
  3. If the variable type is 'logic,' only the fields of srcConnection, dstConnections, and parentModule will be displayed, while other variables remain hidden.
  4. If the variable type is 'Module,' only the fields of inputs, outputs, and parentModule will be displayed.
  5. The filtered results are then tabulated and presented in VSCode's tree views.

Experimental work

  1. https://github.com/quekyj/custom-dart-debug-adapter/tree/main

@DanTup
Copy link
Member

DanTup commented Jul 26, 2023

When we tap into the debug var, we can't seem to identify whether RippleCarryAdder is a children class of Module.

One possibility here would be to walk up the superclasses using the ClassRef.superclass field. This is what we do to get the names for all getters for the hierarchy:

https://github.com/dart-lang/sdk/blob/dd712accf4cb04860dd1ab7a35679e94dc8d6cad/pkg/dds/lib/src/dap/protocol_converter.dart#L720

Hopefully you'd only need to do this for the single top-level variable in variablesRequest and not for all child fields though (as that could require a lot of round-trips to the VM).

Do we need to construct a tree data structure that has all local scope variables with expanded child information?

variablesRequest only returns a single level and uses child variablesReferences as a way for the client to request the child fields later (when the user expands them). I don't think you should ever need to walk down the tree in a single variablesRequest?

Is the flow correct? Do we miss something?

What's written above sounds reasonable to me. Is filtering out the fields the only thing you need to do, or do you expect other customizations?

I don't know if it's useful, but there's a spec for Extension Types in Dart that feels similar to what you're doing and I wonder whether it would be another option.

Do you expect users to interact with the fields that you're filtering out from the debugger in their code, or would they only use the same fields you're showing in the debugger? Extension Types allow you to alter the interface of a type without the overhead of wrapping it in another type.

I don't know exactly what this will look like in the debugger (because it's not been implemented yet), but since it feels similar to what you're doing it might be something to review.

@github-actions
Copy link

This issue has been marked stale because it is tagged awaiting-info for 20 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days.

@github-actions github-actions bot added the stale Will be closed soon if no response. label Aug 16, 2023
@DanTup DanTup removed the stale Will be closed soon if no response. label Aug 21, 2023
@quekyj
Copy link
Author

quekyj commented Sep 6, 2023

Hi @DanTup, it appears that devtools provide more flexibility in building the debugger? Its seems that we might need to build a UI to show the Hardware schematic and waveform signals in the future. Based on the observation, what is provided in the vscode
debugger shown up in the devtools as well (break points, debug), just that we need to run with the command:dart run --pause-isolates-on-start --observe example.dart.

So, I was thinking if we can bypass the UI development in the VS Code and extends from devtools.

@quekyj
Copy link
Author

quekyj commented Sep 6, 2023

"Flutter's widget inspector can send events to VS Code to open files at the location where a widget was constructed" -> this sounds like a very helpful feature for ROHD debugging which I wasn't even sure how to do. The hierarchy of modules constructed within each other could be thought of as somewhat similar to Flutter's hierarchy of widgets.

It seems like this feature in devtools is called widget tree. We want to build this to show the hierarchy of the modules.

Do you expect users to interact with the fields that you're filtering out from the debugger in their code, or would they only use the same fields you're showing in the debugger? Extension Types allow you to alter the interface of a type without the overhead of wrapping it in another type.

Nope as for now. But we will need this in future where we can click on the variable, and it will bring user to the respective position in the UI. Something like show the wire or the connection pin.

@DanTup
Copy link
Member

DanTup commented Sep 6, 2023

If you'll need to build a custom UI, I agree extending DevTools might be a good way to do that. @kenzieschmoll has been working on a framework for building extensions for DevTools, although I'm not sure if it's ready to build on yet.

Although, it's not clear to me if you're proposing to extend DevTools and not use the VS Code UI (eg. users can't use the variables/breakpoints functionality inside VS Code). There are currently some issues related to breakpoints and hot-reload/restarting when trying to use multiple debuggers (eg. VS Code + DevTools) so currently the recommendation is to only use a single debugger (if you launch DevTools for a debug session in VS Code, the DevTools debugger tab should be hidden).

@quekyj
Copy link
Author

quekyj commented Sep 6, 2023

@kenzieschmoll has been working on a framework for building extensions for DevTools, although I'm not sure if it's ready to build on yet.

Where can I track this ya?

@DanTup
Copy link
Member

DanTup commented Sep 6, 2023

@quekyj
Copy link
Author

quekyj commented Sep 6, 2023

Thanks! Do you have any suggestions that what we should prepare while waiting for the extension release?

@DanTup
Copy link
Member

DanTup commented Sep 7, 2023

@kenzieschmoll how stable are things currently? Is it likely @quekyj could start trying to build something (understanding it can't ship until after this support ships in a stable DevTools/SDK)?

The PR rrousselGit/provider#832 that migrates Provider out of DevTools to an extension might also be a useful reference (in addition to the docs and this readme / example).

@quekyj
Copy link
Author

quekyj commented Sep 11, 2023

@DanTup I found this package https://pub.dev/packages/devtools_extensions and wonder if this is the one we are looking for?

@DanTup
Copy link
Member

DanTup commented Sep 12, 2023

@quekyj yep, that's part of the work described above. I don't think the support has shipped in the SDK yet so although you can start building on it a) it might not be stable and may change before it does and b) the shipped version of DevTools in the SDKs won't load your extensions.

@quekyj
Copy link
Author

quekyj commented Sep 25, 2023

Hi @DanTup, I have wrote a proper proposal for this. Would you mind taking a look to see if it aligns with our goals for the devtool extension?

intel/rohd#418

@DanTup
Copy link
Member

DanTup commented Sep 26, 2023

@quekyj I'm not sure I understand the goals well enough to be certain if you can do everything you need, but on the surface it seems reasonable to me. In a DevTools extension you can in theory draw any sort of UI you want, and you can have access to the VM Service (and possibly even the debug-adapter-protocol via DDS) so should be able to do anything DevTools could do.

Some minor comments:

In another words, whatever can be achieved in VS Code extension can be achieved in dev tool.

I'm not sure this is entirely true - you won't be able to interact with VS Code APIs directly from a DevTools extension (except for those Dart-Code will make available to DevTools extensions), although I'm not sure if you have much need for these.

Users can use the debugger by running the debug in the interactive mode via passing the flag --pause-isolates-on-start --observe.

It doesn't seem like a great experience to make users run things from the terminal - but I think once DevTools extensions are all implemented, it should be possible to run via the VS Code debugger, then open DevTools and use your extensions that way - without needing to use the terminal (or sacrificing using the VS Code debugger).

@github-actions
Copy link

This issue has been marked stale because it is tagged awaiting-info for 20 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days.

@github-actions github-actions bot added the stale Will be closed soon if no response. label Oct 17, 2023
@DanTup
Copy link
Member

DanTup commented Oct 17, 2023

@quekyj since you're looking at developing using a DevTools extension now, should we close this or do you think there's still anything required from Dart-Code?

@quekyj
Copy link
Author

quekyj commented Oct 17, 2023

@DanTup We can close this. Thanks for you support up until now! Appreciate that! 😀

@quekyj quekyj closed this as completed Oct 17, 2023
@DanTup DanTup removed is enhancement awaiting info Requires more information from the customer to progress stale Will be closed soon if no response. labels Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants